]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkfontbutton.c
GtkEntry: Sanity check the end_pos value in _get_display_text()
[~andy/gtk] / gtk / gtkfontbutton.c
index 800551f344c3a43fc26e2e4e06bc0f2d53adad66..f65b905b2d45a8e1fda13b49f8ba9a40ecf87374 100644 (file)
@@ -16,8 +16,7 @@
  * Library General Public License for more details.
  *
  * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  */
 /*
  * Modified by the GTK+ Team and others 2003.  See the AUTHORS
@@ -130,6 +129,27 @@ static void gtk_font_button_update_font_info        (GtkFontButton     *gfs);
 
 static guint font_button_signals[LAST_SIGNAL] = { 0 };
 
+static void
+clear_font_data (GtkFontButton *font_button)
+{
+  GtkFontButtonPrivate *priv = font_button->priv;
+
+  if (priv->font_family)
+    g_object_unref (priv->font_family);
+  priv->font_family = NULL;
+
+  if (priv->font_face)
+    g_object_unref (priv->font_face);
+  priv->font_face = NULL;
+
+  if (priv->font_desc)
+    pango_font_description_free (priv->font_desc);
+  priv->font_desc = NULL;
+
+  g_free (priv->fontname);
+  priv->fontname = NULL;
+}
+
 static void
 clear_font_filter_data (GtkFontButton *font_button)
 {
@@ -142,6 +162,71 @@ clear_font_filter_data (GtkFontButton *font_button)
   priv->font_filter_data_destroy = NULL;
 }
 
+static gboolean
+font_description_style_equal (const PangoFontDescription *a,
+                              const PangoFontDescription *b)
+{
+  return (pango_font_description_get_weight (a) == pango_font_description_get_weight (b) &&
+          pango_font_description_get_style (a) == pango_font_description_get_style (b) &&
+          pango_font_description_get_stretch (a) == pango_font_description_get_stretch (b) &&
+          pango_font_description_get_variant (a) == pango_font_description_get_variant (b));
+}
+
+static void
+gtk_font_button_update_font_data (GtkFontButton *font_button)
+{
+  GtkFontButtonPrivate *priv = font_button->priv;
+  PangoFontFamily **families;
+  PangoFontFace **faces;
+  gint n_families, n_faces, i;
+  const gchar *family;
+
+  g_assert (priv->font_desc != NULL);
+
+  priv->fontname = pango_font_description_to_string (priv->font_desc);
+
+  family = pango_font_description_get_family (priv->font_desc);
+  if (family == NULL)
+    return;
+
+  n_families = 0;
+  families = NULL;
+  pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (font_button)),
+                               &families, &n_families);
+  n_faces = 0;
+  faces = NULL;
+  for (i = 0; i < n_families; i++)
+    {
+      const gchar *name = pango_font_family_get_name (families[i]);
+
+      if (!g_ascii_strcasecmp (name, family))
+        {
+          priv->font_family = g_object_ref (families[i]);
+
+          pango_font_family_list_faces (families[i], &faces, &n_faces);
+          break;
+        }
+    }
+  g_free (families);
+
+  for (i = 0; i < n_faces; i++)
+    {
+      PangoFontDescription *tmp_desc = pango_font_face_describe (faces[i]);
+
+      if (font_description_style_equal (tmp_desc, priv->font_desc))
+        {
+          priv->font_face = g_object_ref (faces[i]);
+
+          pango_font_description_free (tmp_desc);
+          break;
+        }
+      else
+        pango_font_description_free (tmp_desc);
+    }
+
+  g_free (faces);
+}
+
 static gchar *
 gtk_font_button_get_preview_text (GtkFontButton *font_button)
 {
@@ -189,9 +274,9 @@ gtk_font_button_set_show_preview_entry (GtkFontButton *font_button,
   GtkFontButtonPrivate *priv = font_button->priv;
 
   if (priv->font_dialog)
-    return gtk_font_chooser_set_show_preview_entry (GTK_FONT_CHOOSER (priv->font_dialog), show);
-
-  priv->show_preview_entry = show != FALSE;
+    gtk_font_chooser_set_show_preview_entry (GTK_FONT_CHOOSER (priv->font_dialog), show);
+  else
+    priv->show_preview_entry = show != FALSE;
 }
 
 static PangoFontFamily *
@@ -261,16 +346,19 @@ gtk_font_button_take_font_desc (GtkFontButton        *font_button,
 
   g_object_freeze_notify (object);
 
-  if (priv->font_desc)
-    pango_font_description_free (priv->font_desc);
+  clear_font_data (font_button);
+
   if (font_desc)
     priv->font_desc = font_desc; /* adopted */
   else
     priv->font_desc = pango_font_description_from_string (_("Sans 12"));
 
-  g_free (priv->fontname);
-  priv->fontname = pango_font_description_to_string (priv->font_desc);
+  if (pango_font_description_get_size_is_absolute (priv->font_desc))
+    priv->font_size = pango_font_description_get_size (priv->font_desc);
+  else 
+    priv->font_size = pango_font_description_get_size (priv->font_desc) / PANGO_SCALE;
 
+  gtk_font_button_update_font_data (font_button);
   gtk_font_button_update_font_info (font_button);
 
   if (priv->font_dialog)
@@ -489,29 +577,15 @@ gtk_font_button_finalize (GObject *object)
     gtk_widget_destroy (font_button->priv->font_dialog);
   font_button->priv->font_dialog = NULL;
 
-  g_free (font_button->priv->fontname);
-  font_button->priv->fontname = NULL;
-
   g_free (font_button->priv->title);
   font_button->priv->title = NULL;
 
+  clear_font_data (font_button);
   clear_font_filter_data (font_button);
 
   g_free (font_button->priv->preview_text);
   font_button->priv->preview_text = NULL;
 
-  if (font_button->priv->font_family)
-    g_object_unref (font_button->priv->font_family);
-  font_button->priv->font_family = NULL;
-
-  if (font_button->priv->font_face)
-    g_object_unref (font_button->priv->font_face);
-  font_button->priv->font_face = NULL;
-
-  if (font_button->priv->font_desc)
-    pango_font_description_free (font_button->priv->font_desc);
-  font_button->priv->font_desc = NULL;
-
   G_OBJECT_CLASS (gtk_font_button_parent_class)->finalize (object);
 }
 
@@ -719,12 +793,9 @@ gtk_font_button_set_use_font (GtkFontButton *font_button,
     {
       font_button->priv->use_font = use_font;
 
-      if (use_font)
-        gtk_font_button_label_use_font (font_button);
-      else
-       gtk_widget_set_style (font_button->priv->font_label, NULL);
+      gtk_font_button_label_use_font (font_button);
  
-     g_object_notify (G_OBJECT (font_button), "use-font");
+      g_object_notify (G_OBJECT (font_button), "use-font");
     }
 } 
 
@@ -767,8 +838,7 @@ gtk_font_button_set_use_size (GtkFontButton *font_button,
     {
       font_button->priv->use_size = use_size;
 
-      if (font_button->priv->use_font)
-        gtk_font_button_label_use_font (font_button);
+      gtk_font_button_label_use_font (font_button);
 
       g_object_notify (G_OBJECT (font_button), "use-size");
     }
@@ -1003,25 +1073,17 @@ response_cb (GtkDialog *dialog,
 
   g_object_freeze_notify (object);
 
-  if (priv->font_desc)
-    pango_font_description_free (priv->font_desc);
-  priv->font_desc = gtk_font_chooser_get_font_desc (font_chooser);
-
-  g_free (priv->fontname);
-  priv->fontname = pango_font_description_to_string (priv->font_desc);
+  clear_font_data (font_button);
 
-  if (priv->font_family)
-    g_object_unref (priv->font_family);
+  priv->font_desc = gtk_font_chooser_get_font_desc (font_chooser);
+  if (priv->font_desc)
+    priv->fontname = pango_font_description_to_string (priv->font_desc);
   priv->font_family = gtk_font_chooser_get_font_family (font_chooser);
   if (priv->font_family)
     g_object_ref (priv->font_family);
-
-  if (priv->font_face)
-    g_object_unref (priv->font_face);
   priv->font_face = gtk_font_chooser_get_font_face (font_chooser);
   if (priv->font_face)
     g_object_ref (priv->font_face);
-
   priv->font_size = gtk_font_chooser_get_font_size (font_chooser);
 
   /* Set label font */
@@ -1080,106 +1142,50 @@ gtk_font_button_label_use_font (GtkFontButton *font_button)
 {
   PangoFontDescription *desc;
 
-  if (!font_button->priv->use_font)
-    return;
-
-  desc = pango_font_description_copy (font_button->priv->font_desc);
-
-  if (!font_button->priv->use_size)
-    pango_font_description_unset_fields (desc, PANGO_FONT_MASK_SIZE);
+  if (font_button->priv->use_font)
+    {
+      desc = pango_font_description_copy (font_button->priv->font_desc);
 
-  gtk_widget_modify_font (font_button->priv->font_label, desc);
+      if (!font_button->priv->use_size)
+        pango_font_description_unset_fields (desc, PANGO_FONT_MASK_SIZE);
+    }
+  else
+    desc = NULL;
 
-  pango_font_description_free (desc);
-}
+  gtk_widget_override_font (font_button->priv->font_label, desc);
 
-static gboolean
-font_description_style_equal (const PangoFontDescription *a,
-                              const PangoFontDescription *b)
-{
-  return (pango_font_description_get_weight (a) == pango_font_description_get_weight (b) &&
-          pango_font_description_get_style (a) == pango_font_description_get_style (b) &&
-          pango_font_description_get_stretch (a) == pango_font_description_get_stretch (b) &&
-          pango_font_description_get_variant (a) == pango_font_description_get_variant (b));
+  if (desc)
+    pango_font_description_free (desc);
 }
 
 static void
 gtk_font_button_update_font_info (GtkFontButton *font_button)
 {
-  const PangoFontDescription *desc;
-  const gchar *family;
-  gchar *style;
+  GtkFontButtonPrivate *priv = font_button->priv;
   gchar *family_style;
 
-  desc = font_button->priv->font_desc;
-  g_assert (desc != NULL);
+  g_assert (priv->font_desc != NULL);
 
-  family = pango_font_description_get_family (desc);
-  
-#if 0
-  /* This gives the wrong names, e.g. Italic when the font chooser
-   * dialog displayed Oblique.
-   */
-  pango_font_description_unset_fields (desc, PANGO_FONT_MASK_FAMILY | PANGO_FONT_MASK_SIZE);
-  style = pango_font_description_to_string (desc);
-  gtk_label_set_text (GTK_LABEL (font_button->priv->style_label), style);      
-#endif
-
-  style = NULL;
-  if (font_button->priv->show_style && family) 
+  if (priv->show_style)
     {
-      PangoFontFamily **families;
-      PangoFontFace **faces;
-      gint n_families, n_faces, i;
-
-      n_families = 0;
-      families = NULL;
-      pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (font_button)),
-                                   &families, &n_families);
-      n_faces = 0;
-      faces = NULL;
-      for (i = 0; i < n_families; i++) 
-        {
-          const gchar *name = pango_font_family_get_name (families[i]);
-          
-          if (!g_ascii_strcasecmp (name, family)) 
-            {
-              pango_font_family_list_faces (families[i], &faces, &n_faces);
-              break;
-            }
-        }
-      g_free (families);
-      
-      for (i = 0; i < n_faces; i++) 
-        {
-          PangoFontDescription *tmp_desc = pango_font_face_describe (faces[i]);
-          
-          if (font_description_style_equal (tmp_desc, desc)) 
-            {
-              style = g_strdup (pango_font_face_get_face_name (faces[i]));
-              pango_font_description_free (tmp_desc);
-              break;
-            }
-          else
-            pango_font_description_free (tmp_desc);
-        }
-      g_free (faces);
-    }
+      PangoFontDescription *desc = pango_font_description_copy_static (priv->font_desc);
 
-  if (style == NULL || !g_ascii_strcasecmp (style, "Regular"))
-    family_style = g_strdup (family);
+      pango_font_description_unset_fields (desc, PANGO_FONT_MASK_SIZE);
+      family_style = pango_font_description_to_string (desc);
+      pango_font_description_free (desc);
+    }
   else
-    family_style = g_strdup_printf ("%s %s", family, style);
-  
+    family_style = g_strdup (pango_font_description_get_family (priv->font_desc));
+
   gtk_label_set_text (GTK_LABEL (font_button->priv->font_label), family_style);
-  
-  g_free (style);
   g_free (family_style);
 
   if (font_button->priv->show_size) 
     {
-      gchar *size = g_strdup_printf ("%g",
-                                     pango_font_description_get_size (desc) / (double)PANGO_SCALE);
+      /* mirror Pango, which doesn't translate this either */
+      gchar *size = g_strdup_printf ("%g%s",
+                                     pango_font_description_get_size (priv->font_desc) / (double)PANGO_SCALE,
+                                     pango_font_description_get_size_is_absolute (priv->font_desc) ? "px" : "");
       
       gtk_label_set_text (GTK_LABEL (font_button->priv->size_label), size);