Code

init matrix variable, removes compiler warnings
[inkscape.git] / src / widgets / toolbox.cpp
index 0a4065e805f865ef6d4ee538220ee75131f42494..146853c2258d10716a08fbe89703cc75757a9db4 100644 (file)
@@ -69,6 +69,7 @@
 #include "document-private.h"
 #include "desktop-style.h"
 #include "../libnrtype/font-lister.h"
+#include "../connection-pool.h"
 
 #include "mod360.h"
 
@@ -89,7 +90,8 @@ static GtkWidget *sp_calligraphy_toolbox_new(SPDesktop *desktop);
 static GtkWidget *sp_dropper_toolbox_new(SPDesktop *desktop);
 static GtkWidget *sp_empty_toolbox_new(SPDesktop *desktop);
 static GtkWidget *sp_connector_toolbox_new(SPDesktop *desktop);
-static GtkWidget *sp_text_toolbox_new (SPDesktop *desktop);
+
+namespace { GtkWidget *sp_text_toolbox_new (SPDesktop *desktop); }
 
 
 static struct {
@@ -2783,143 +2785,245 @@ sp_text_letter_rotation_changed(GtkAdjustment *adj, GtkWidget *tbl)
     //Call back for letter rotation spinbutton
 }*/
 
-static void
-sp_text_toolbox_selection_changed (Inkscape::Selection *selection, GObject *tbl)
-{
-    GtkWidget *cbox = GTK_WIDGET(g_object_get_data (G_OBJECT(tbl), "combo-box-family"));
-    Inkscape::XML::Node *repr = 0;
-//  Inkscape::XML::Node *oldrepr = 0;
-    SPStyle *style = 0; 
-    bool multiple = false;
-    const GSList *items = selection->itemList();
+namespace {
 
-    for ( ; items ; items = items->next)
+    void
+    sp_text_toolbox_selection_changed (Inkscape::Selection *selection, GObject *tbl)
     {
-        if (SP_IS_TEXT((SPItem *) items->data))
+        GtkComboBox *cbox = 0;
+    
+        SPStyle *query =
+            sp_style_new ();
+
+        int result_family =
+            sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); 
+
+        int result_style =
+            sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE); 
+
+        int result_numbers =
+            sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); 
+
+        // If querying returned nothing, read the style from the text tool prefs (default style for new texts)
+        if (result_family == QUERY_STYLE_NOTHING || result_style == QUERY_STYLE_NOTHING || result_numbers == QUERY_STYLE_NOTHING)
         {
-            if (!style)
+            Inkscape::XML::Node *repr = inkscape_get_repr (INKSCAPE, "tools.text");
+
+            if (repr)
             {
-                repr = SP_OBJECT_REPR((SPItem *) items->data);
-                style = sp_style_new ();
-                sp_style_read_from_repr (style, repr); 
+                sp_style_read_from_repr (query, repr);
             }
             else
             {
-                multiple = true;
+                return;
             }
         }
-    }
-    
-    if (!style) return;
-    if (multiple)
-    {
-        g_object_set_data (G_OBJECT (cbox), "block", GINT_TO_POINTER(1));
-        gtk_combo_box_set_active (GTK_COMBO_BOX (cbox), -1); 
-        g_object_set_data (G_OBJECT (cbox), "block", GINT_TO_POINTER(0));
-        return;
-    }
 
-    Gtk::TreePath path = Inkscape::FontLister::get_instance()->get_row_for_font (style->text->font_family.value);
+        if (result_numbers == QUERY_STYLE_MULTIPLE_DIFFERENT)
+        {
+            static char* cboxes[] = { "combo-box-family", "combo-box-style" };
+        
+            for (unsigned n = 0 ; n < G_N_ELEMENTS(cboxes); ++n)
+            {
+                cbox = GTK_COMBO_BOX(g_object_get_data (G_OBJECT(tbl), cboxes[n]));
+                g_object_set_data (G_OBJECT (cbox), "block", GINT_TO_POINTER(1));
+                gtk_combo_box_set_active (GTK_COMBO_BOX (cbox), -1); 
+                g_object_set_data (G_OBJECT (cbox), "block", GINT_TO_POINTER(0));
+            }
+            gtk_widget_hide (GTK_WIDGET (g_object_get_data (G_OBJECT(tbl), "warning-image")));        
+            return;
+        }
 
-    g_object_set_data (G_OBJECT (cbox), "block", GINT_TO_POINTER(1));
+        if (query->text)
+        {
+            if (query->text->font_family.value) 
+            {
+                Gtk::TreePath path;
+                try {
+                    path = Inkscape::FontLister::get_instance()->get_row_for_font (query->text->font_family.value);
+                } catch (...) {
+                    return;
+                }
+
+                cbox = GTK_COMBO_BOX(g_object_get_data (G_OBJECT(tbl), "combo-box-family"));
+                g_object_set_data (G_OBJECT (cbox), "block", GINT_TO_POINTER(1));
+                gtk_combo_box_set_active (GTK_COMBO_BOX (cbox), gtk_tree_path_get_indices (path.gobj())[0]);
+                g_object_set_data (G_OBJECT (cbox), "block", GINT_TO_POINTER(0));
+            }
 
-    gtk_combo_box_set_active (GTK_COMBO_BOX (cbox), gtk_tree_path_get_indices (path.gobj())[0]);
+            //Style
+            cbox = GTK_COMBO_BOX(g_object_get_data (G_OBJECT(tbl), "combo-box-style"));
+            g_object_set_data (G_OBJECT (cbox), "block", GINT_TO_POINTER(1));
+            gtk_combo_box_set_active (GTK_COMBO_BOX (cbox), gint(query->font_style.value));
+            g_object_set_data (G_OBJECT (cbox), "block", GINT_TO_POINTER(0));
 
-    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
-    SPCSSAttr *css = sp_repr_css_attr_new (); 
-    items = sp_desktop_selection(desktop)->itemList();
+            gtk_widget_hide (GTK_WIDGET (g_object_get_data (G_OBJECT(tbl), "warning-image")));        
+        }
+    }
 
-    sp_repr_css_set_property (css, "font-family", gtk_combo_box_get_active_text (GTK_COMBO_BOX(cbox)));
-    sp_desktop_set_style (desktop, css, true);
+    void
+    sp_text_toolbox_selection_modified (Inkscape::Selection *selection, guint flags, GObject *tbl) 
+    {
+        sp_text_toolbox_selection_changed (selection, tbl); 
+    }
 
-    for (; items != NULL; items = items->next)
+    void
+    sp_text_toolbox_subselection_changed (gpointer dragger, GObject *tbl)
     {
-        // apply style to the reprs of all text objects in the selection
-        if (SP_IS_TEXT (items->data))
-        {
-            // backwards compatibility:
-            SP_OBJECT_REPR(items->data)->setAttribute("sodipodi:linespacing", sp_repr_css_property (css, "line-height", NULL));
-        }
+        sp_text_toolbox_selection_changed (NULL, tbl); 
     }
 
-    // complete the transaction
-    sp_document_done (sp_desktop_document (SP_ACTIVE_DESKTOP));
-    sp_repr_css_attr_unref (css);
+    void
+    sp_text_toolbox_family_changed (GtkComboBox *cbox,
+                                    GtkWidget   *tbl) 
+    {
+        SPDesktop *desktop = SP_ACTIVE_DESKTOP;
 
-    g_object_set_data (G_OBJECT (cbox), "block", GINT_TO_POINTER(0));
-}
+        if (GPOINTER_TO_INT(g_object_get_data (G_OBJECT (cbox), "block")) != 0) return;
 
-static void
-sp_text_toolbox_family_changed (GtkComboBox *cbox,
-                                GtkWidget   *tbl) 
-{
-    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
-    unsigned items = 0;
-    const GSList *item_list = sp_desktop_selection(desktop)->itemList();
-    SPCSSAttr *css = sp_repr_css_attr_new (); 
+        if (gtk_combo_box_get_active (cbox) < 0) return;
 
-    if (GPOINTER_TO_INT(g_object_get_data (G_OBJECT (cbox), "block")) != 0) return;
+        SPCSSAttr *css = sp_repr_css_attr_new (); 
+        sp_repr_css_set_property (css, "font-family", gtk_combo_box_get_active_text (cbox));
+        sp_desktop_set_style (desktop, css, true, true);
+        sp_document_done (sp_desktop_document (SP_ACTIVE_DESKTOP));
+        sp_repr_css_attr_unref (css);
 
-    sp_repr_css_set_property (css, "font-family", gtk_combo_box_get_active_text (cbox));
-    sp_desktop_set_style(desktop, css, true);
+        gtk_widget_hide (GTK_WIDGET (g_object_get_data (G_OBJECT(tbl), "warning-image")));        
+    }
+
+    void
+    sp_text_toolbox_family_entry_activate (GtkEntry     *entry,
+                                           GtkWidget    *tbl) 
+    {
+        const char* family = gtk_entry_get_text (entry);
+
+        try {    
+            Gtk::TreePath path = Inkscape::FontLister::get_instance()->get_row_for_font (family);
+            GtkComboBox *cbox = GTK_COMBO_BOX(g_object_get_data (G_OBJECT(tbl), "combo-box-family"));
+            gtk_combo_box_set_active (cbox, gtk_tree_path_get_indices (path.gobj())[0]);
+            gtk_widget_hide (GTK_WIDGET (g_object_get_data (G_OBJECT(tbl), "warning-image")));        
+        } catch (...) {
+            //XXX: Accept it anyway and show the warning
+            if (family && strlen (family)) gtk_widget_show_all (GTK_WIDGET (g_object_get_data (G_OBJECT(tbl), "warning-image")));        
+        }
+    }
 
-    for (; item_list != NULL; item_list = item_list->next) {
-        // apply style to the reprs of all text objects in the selection
-        if (SP_IS_TEXT (item_list->data)) {
+    void
+    sp_text_toolbox_style_changed (GtkComboBox *cbox,
+                                   GtkWidget   *tbl) 
+    {
+        SPDesktop *desktop = SP_ACTIVE_DESKTOP;
 
-            // backwards compatibility:
-            SP_OBJECT_REPR(item_list->data)->setAttribute("sodipodi:linespacing",
-sp_repr_css_property (css, "line-height", NULL));
+        if (GPOINTER_TO_INT(g_object_get_data (G_OBJECT (cbox), "block")) != 0) return;
+    
+        static char* styles[] = { "normal", "italic" , "oblique" };
 
-            ++items;
-        }
-        else if (SP_IS_FLOWTEXT (item_list->data))
-            // no need to set sodipodi:linespacing, because Inkscape never supported it on flowtext
-            ++items;
+        SPCSSAttr *css = sp_repr_css_attr_new (); 
+        sp_repr_css_set_property (css, "font-style", styles[gtk_combo_box_get_active (cbox)]);
+        sp_desktop_set_style (desktop, css, true, true);
+        sp_document_done (sp_desktop_document (SP_ACTIVE_DESKTOP));
+        sp_repr_css_attr_unref (css);
     }
 
-    sp_repr_css_change (inkscape_get_repr (INKSCAPE, "tools.text"), css, "style");
+}//<unnamed> namespace
 
-    // complete the transaction
-    sp_document_done (sp_desktop_document (SP_ACTIVE_DESKTOP));
-    sp_repr_css_attr_unref (css);
+#if 0
+static void  cell_data_func  (GtkCellLayout     *cell_layout,
+                              GtkCellRenderer   *cell,
+                              GtkTreeModel      *tree_model,
+                              GtkTreeIter       *iter,
+                              gpointer           data)
+{
+    char *text; 
+    gtk_tree_model_get (tree_model, iter, 0, &text, -1); 
+    g_object_set (G_OBJECT (cell), "family", text, NULL);
 }
+#endif
 
-static GtkWidget*
-sp_text_toolbox_new (SPDesktop *desktop)
+namespace
 {
-    GtkWidget   *tbl = gtk_hbox_new (FALSE, 0);
+    GtkWidget*
+    sp_text_toolbox_new (SPDesktop *desktop)
+    {
+        GtkWidget   *tbl = gtk_hbox_new (FALSE, 0);
 
 #if 0
-    GtkWidget   *us = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(tbl), "units");
+    GtkWidget   *us = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(tbl), "units"));
     GtkTooltips *tt = gtk_tooltips_new();
     GtkWidget   *group;
 #endif
 
-    //Font Family
-    {
-            GtkWidget *cbox = gtk_combo_box_entry_new_text ();
-            Glib::RefPtr<Gtk::ListStore> store = Inkscape::FontLister::get_instance()->get_font_list();
-            gtk_combo_box_set_model (GTK_COMBO_BOX (cbox), GTK_TREE_MODEL (Glib::unwrap(store)));
-            gtk_widget_set_size_request (cbox, 250, -1);
-            aux_toolbox_space (tbl, 1);
-            gtk_box_pack_start (GTK_BOX (tbl), cbox, FALSE, FALSE, 0);
-            g_object_set_data (G_OBJECT (tbl), "combo-box-family", cbox);
-            g_signal_connect (G_OBJECT (cbox), "changed", G_CALLBACK (sp_text_toolbox_family_changed), tbl);
-    }
+        //Font Family
+        GtkWidget *cbox = gtk_combo_box_entry_new_text ();
+        Glib::RefPtr<Gtk::ListStore> store = Inkscape::FontLister::get_instance()->get_font_list();
+        gtk_cell_layout_clear (GTK_CELL_LAYOUT (cbox));
+        GtkCellRenderer *cell = gtk_cell_renderer_text_new ();
+        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (cbox), cell, FALSE);
+        gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (cbox), cell, "text", 0, NULL);
+        GtkEntryCompletion *completion = gtk_entry_completion_new ();
+        gtk_entry_completion_set_model (completion, GTK_TREE_MODEL (Glib::unwrap(store)));
+        gtk_entry_completion_set_text_column (completion, 0);
+        gtk_entry_completion_set_minimum_key_length (completion, 3); //3 characters minimum sounds reasonable
+        g_object_set (G_OBJECT(completion), "inline-completion", TRUE, "popup-completion", TRUE, NULL);
 
-    //Font Style
-    {
-            GtkWidget *cbox = gtk_combo_box_new_text ();
-            gtk_widget_set_size_request (cbox, 144, -1);
-            aux_toolbox_space (tbl, 1);
-            gtk_box_pack_start (GTK_BOX (tbl), cbox, FALSE, FALSE, 0);
-            g_object_set_data (G_OBJECT (tbl), "combo-box-style", cbox);
-    }
+#if 0
+        gtk_cell_layout_set_cell_data_func
+            (GTK_CELL_LAYOUT (cbox),
+             cell, 
+             GtkCellLayoutDataFunc (cell_data_func),
+             tbl, 
+             NULL); 
+#endif
 
-    sigc::connection *connection =
-    new sigc::connection(sp_desktop_selection(desktop)->connectChanged (sigc::bind (sigc::ptr_fun (sp_text_toolbox_selection_changed), (GObject*)tbl)));
-    g_signal_connect(G_OBJECT(tbl), "destroy", G_CALLBACK(delete_connection), connection);
+        gtk_combo_box_set_model (GTK_COMBO_BOX (cbox), GTK_TREE_MODEL (Glib::unwrap(store)));
+        gtk_widget_set_size_request (cbox, 250, -1);
+        aux_toolbox_space (tbl, 1);
+        gtk_box_pack_start (GTK_BOX (tbl), cbox, FALSE, FALSE, 0);
+        g_object_set_data (G_OBJECT (tbl), "combo-box-family", cbox);
+        g_signal_connect (G_OBJECT (cbox), "changed", G_CALLBACK (sp_text_toolbox_family_changed), tbl);
+        g_signal_connect (G_OBJECT (GTK_BIN(cbox)->child), "activate", G_CALLBACK (sp_text_toolbox_family_entry_activate), tbl);
+        gtk_entry_set_completion (GTK_ENTRY(GTK_BIN(cbox)->child), completion);
+
+        GtkWidget *image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_SMALL_TOOLBAR);
+        aux_toolbox_space (tbl, 1);
+        GtkWidget *box = gtk_event_box_new ();
+        gtk_container_add (GTK_CONTAINER (box), image);
+        gtk_box_pack_start (GTK_BOX (tbl), box, FALSE, FALSE, 4);
+        g_object_set_data (G_OBJECT (tbl), "warning-image", box);
+        GtkTooltips *tooltips = gtk_tooltips_new ();
+        gtk_tooltips_set_tip (tooltips, box, _("This font is currently not installed on your system. Inkscape will use the default font instead."), "");
+        gtk_widget_hide (GTK_WIDGET (box));
+
+        //Font Style
+        cbox = gtk_combo_box_new_text ();
+        gtk_combo_box_append_text (GTK_COMBO_BOX (cbox), _("Normal"));
+        gtk_combo_box_append_text (GTK_COMBO_BOX (cbox), _("Italic"));
+        gtk_combo_box_append_text (GTK_COMBO_BOX (cbox), _("Oblique"));
+        gtk_widget_set_size_request (cbox, 144, -1);
+        aux_toolbox_space (tbl, 1);
+        gtk_box_pack_start (GTK_BOX (tbl), cbox, FALSE, FALSE, 0);
+        g_object_set_data (G_OBJECT (tbl), "combo-box-style", cbox);
+        g_signal_connect (G_OBJECT (cbox), "changed", G_CALLBACK (sp_text_toolbox_style_changed), tbl);
+
+        Inkscape::ConnectionPool* pool = Inkscape::ConnectionPool::new_connection_pool ("ISTextToolbox");
+
+        sigc::connection *c_selection_changed =
+            new sigc::connection (sp_desktop_selection (desktop)->connectChanged 
+                                (sigc::bind (sigc::ptr_fun (sp_text_toolbox_selection_changed), (GObject*)tbl)));
+        pool->add_connection ("selection-changed", c_selection_changed);
+
+        sigc::connection *c_selection_modified =
+            new sigc::connection (sp_desktop_selection (desktop)->connectModified 
+                                (sigc::bind (sigc::ptr_fun (sp_text_toolbox_selection_modified), (GObject*)tbl)));
+        pool->add_connection ("selection-modified", c_selection_modified);
+
+        sigc::connection *c_subselection_changed =
+            new sigc::connection (desktop->connectToolSubselectionChanged
+                                (sigc::bind (sigc::ptr_fun (sp_text_toolbox_subselection_changed), (GObject*)tbl)));
+        pool->add_connection ("tool-subselection-changed", c_subselection_changed);
+
+        Inkscape::ConnectionPool::connect_destroy (G_OBJECT (tbl), pool);
 
 #if 0
     //Font Size
@@ -2933,9 +3037,9 @@ sp_text_toolbox_new (SPDesktop *desktop)
             gtk_box_pack_start (GTK_BOX (tbl), c, FALSE, FALSE, 0);
     }
 
-        aux_toolbox_space(tbl, AUX_BETWEEN_BUTTON_GROUPS);
-        //Bold
-        {
+    aux_toolbox_space(tbl, AUX_BETWEEN_BUTTON_GROUPS);
+    //Bold
+    {
             GtkWidget *px = gtk_image_new_from_stock(GTK_STOCK_BOLD, Inkscape::ICON_SIZE_SMALL_TOOLBAR);
             GtkWidget *button = gtk_toggle_button_new ();
             gtk_container_add (GTK_CONTAINER (button), px);
@@ -2944,7 +3048,7 @@ sp_text_toolbox_new (SPDesktop *desktop)
             gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
             gtk_widget_set_sensitive(button, TRUE);
             gtk_box_pack_start (GTK_BOX (tbl), button, FALSE, FALSE, 0);
-        }
+    }
 
 
         //Italic
@@ -3181,19 +3285,17 @@ sp_text_toolbox_new (SPDesktop *desktop)
         }
 #endif
 
-#if 0
-    Inkscape::UI::Widget::StyleSwatch *swatch = new Inkscape::UI::Widget::StyleSwatch(NULL);
-    swatch->setWatchedTool ("tools.text", true);
-    GtkWidget *swatch_ = GTK_WIDGET(swatch->gobj());
-    gtk_box_pack_end(GTK_BOX(tbl), swatch_, FALSE, FALSE, 0);
+        Inkscape::UI::Widget::StyleSwatch *swatch = new Inkscape::UI::Widget::StyleSwatch(NULL);
+        swatch->setWatchedTool ("tools.text", true);
+        GtkWidget *swatch_ = GTK_WIDGET(swatch->gobj());
+        gtk_box_pack_end (GTK_BOX(tbl), swatch_, FALSE, FALSE, 0);
+        gtk_widget_show_all (tbl);
 
-    sp_set_font_size_smaller (tbl);
-#endif
+        return tbl;
 
-    gtk_widget_show_all (tbl);
-    return tbl;
+    } // end of sp_text_toolbox_new()
 
-} // end of sp_text_toolbox_new()
+}//<unnamed> namespace
 
 
 //#########################