Code

Disable the page selector when there's only one page
[inkscape.git] / src / widgets / gradient-vector.cpp
index ccb36a3ec6bc0798787de7dc020249e5f9727fb8..f1c4e3500437665d8ccc1013367ee5997119fe61 100644 (file)
@@ -6,11 +6,13 @@
  * Authors:
  *   Lauris Kaplinski <lauris@kaplinski.com>
  *   bulia byak <buliabyak@users.sf.net>
+ *   MenTaLguY <mental@rydia.net>
  *
  * Copyright (C) 2001-2002 Lauris Kaplinski
  * Copyright (C) 2001 Ximian, Inc.
  * Copyright (C) 2004 Monash University
  * Copyright (C) 2004 David Turner
+ * Copyright (C) 2006 MenTaLguY
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
  *
@@ -38,6 +40,9 @@
 #include "svg/css-ostringstream.h"
 #include "sp-stop.h"
 
+#include <sigc++/functors/ptr_fun.h>
+#include <sigc++/adaptors/bind.h>
+
 enum {
        VECTOR_SET,
        LAST_SIGNAL
@@ -47,7 +52,7 @@ static void sp_gradient_vector_selector_class_init (SPGradientVectorSelectorClas
 static void sp_gradient_vector_selector_init (SPGradientVectorSelector *gvs);
 static void sp_gradient_vector_selector_destroy (GtkObject *object);
 
-static void sp_gvs_gradient_release (SPGradient *gr, SPGradientVectorSelector *gvs);
+static void sp_gvs_gradient_release (SPObject *obj, SPGradientVectorSelector *gvs);
 static void sp_gvs_defs_release (SPObject *defs, SPGradientVectorSelector *gvs);
 static void sp_gvs_defs_modified (SPObject *defs, guint flags, SPGradientVectorSelector *gvs);
 
@@ -108,6 +113,10 @@ sp_gradient_vector_selector_init (SPGradientVectorSelector *gvs)
        gvs->doc = NULL;
        gvs->gr = NULL;
 
+       new (&gvs->gradient_release_connection) sigc::connection();
+       new (&gvs->defs_release_connection) sigc::connection();
+       new (&gvs->defs_modified_connection) sigc::connection();
+
        gvs->menu = gtk_option_menu_new ();
        gtk_widget_show (gvs->menu);
        gtk_box_pack_start (GTK_BOX (gvs), gvs->menu, TRUE, TRUE, 0);
@@ -121,15 +130,20 @@ sp_gradient_vector_selector_destroy (GtkObject *object)
        gvs = SP_GRADIENT_VECTOR_SELECTOR (object);
 
        if (gvs->gr) {
-               sp_signal_disconnect_by_data (gvs->gr, gvs);
+               gvs->gradient_release_connection.disconnect();
                gvs->gr = NULL;
        }
 
        if (gvs->doc) {
-               sp_signal_disconnect_by_data (SP_DOCUMENT_DEFS (gvs->doc), gvs);
+               gvs->defs_release_connection.disconnect();
+               gvs->defs_modified_connection.disconnect();
                gvs->doc = NULL;
        }
 
+       gvs->gradient_release_connection.~connection();
+       gvs->defs_release_connection.~connection();
+       gvs->defs_modified_connection.~connection();
+
        if (((GtkObjectClass *) (parent_class))->destroy)
                (* ((GtkObjectClass *) (parent_class))->destroy) (object);
 }
@@ -168,21 +182,21 @@ sp_gradient_vector_selector_set_gradient (SPGradientVectorSelector *gvs, SPDocum
        if (doc != gvs->doc) {
                /* Disconnect signals */
                if (gvs->gr) {
-                       sp_signal_disconnect_by_data (gvs->gr, gvs);
-                       g_signal_handlers_disconnect_matched (G_OBJECT(gvs->gr), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, gvs);
+                       gvs->gradient_release_connection.disconnect();
                        gvs->gr = NULL;
                }
                if (gvs->doc) {
-                       sp_signal_disconnect_by_data (SP_DOCUMENT_DEFS (gvs->doc), gvs);
+                       gvs->defs_release_connection.disconnect();
+                       gvs->defs_modified_connection.disconnect();
                        gvs->doc = NULL;
                }
                /* Connect signals */
                if (doc) {
-                       g_signal_connect (G_OBJECT (SP_DOCUMENT_DEFS (doc)), "release", G_CALLBACK (sp_gvs_defs_release), gvs);
-                       g_signal_connect (G_OBJECT (SP_DOCUMENT_DEFS (doc)), "modified", G_CALLBACK (sp_gvs_defs_modified), gvs);
+                       gvs->defs_release_connection = SP_DOCUMENT_DEFS(doc)->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_gvs_defs_release), gvs));
+                       gvs->defs_modified_connection = SP_DOCUMENT_DEFS(doc)->connectModified(sigc::bind<2>(sigc::ptr_fun(&sp_gvs_defs_modified), gvs));
                }
                if (gr) {
-                       g_signal_connect (G_OBJECT (gr), "release", G_CALLBACK (sp_gvs_gradient_release), gvs);
+                       gvs->gradient_release_connection = gr->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_gvs_gradient_release), gvs));
                }
                gvs->doc = doc;
                gvs->gr = gr;
@@ -330,14 +344,12 @@ sp_gvs_gradient_activate (GtkMenuItem *mi, SPGradientVectorSelector *gvs)
        /* fixme: Really we would want to use _set_vector */
        /* Detach old */
        if (gvs->gr) {
-               sp_signal_disconnect_by_data (gvs->gr, gvs);
+               gvs->gradient_release_connection.disconnect();
                gvs->gr = NULL;
        }
        /* Attach new */
        if (norm) {
-               g_signal_connect (G_OBJECT (norm), "release", G_CALLBACK (sp_gvs_gradient_release), gvs);
-               /* fixme: Connect 'modified'? (Lauris) */
-               /* fixme: I think we do not need it (Lauris) */
+               gvs->gradient_release_connection = norm->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_gvs_gradient_release), gvs));
                gvs->gr = norm;
        }
 
@@ -346,16 +358,18 @@ sp_gvs_gradient_activate (GtkMenuItem *mi, SPGradientVectorSelector *gvs)
        if (norm != gr) {
                /* We do extra undo push here */
                /* If handler has already done it, it is just NOP */
-               sp_document_done (SP_OBJECT_DOCUMENT (norm));
+               // FIXME: looks like this is never a valid undo step, consider removing this
+           sp_document_done (SP_OBJECT_DOCUMENT (norm), SP_VERB_CONTEXT_GRADIENT,
+                             /* TODO: annotate */ "gradient-vector.cpp:350");
        }
 }
 
 static void
-sp_gvs_gradient_release (SPGradient *gr, SPGradientVectorSelector *gvs)
+sp_gvs_gradient_release (SPObject *obj, SPGradientVectorSelector *gvs)
 {
        /* Disconnect gradient */
        if (gvs->gr) {
-               sp_signal_disconnect_by_data (gvs->gr, gvs);
+               gvs->gradient_release_connection.disconnect();
                gvs->gr = NULL;
        }
 
@@ -367,9 +381,13 @@ static void
 sp_gvs_defs_release (SPObject *defs, SPGradientVectorSelector *gvs)
 {
        gvs->doc = NULL;
+
+       gvs->defs_release_connection.disconnect();
+       gvs->defs_modified_connection.disconnect();
+
        /* Disconnect gradient as well */
        if (gvs->gr) {
-               sp_signal_disconnect_by_data (gvs->gr, gvs);
+               gvs->gradient_release_connection.disconnect();
                gvs->gr = NULL;
        }
 
@@ -393,7 +411,7 @@ sp_gvs_defs_modified (SPObject *defs, guint flags, SPGradientVectorSelector *gvs
 #include "../widgets/sp-color-preview.h"
 #include "../widgets/widget-sizes.h"
 #include "../xml/node-event-vector.h"
-#include "../svg/svg.h"
+#include "../svg/svg-color.h"
 
 
 #define PAD 4
@@ -405,8 +423,8 @@ static gint sp_gradient_vector_dialog_delete (GtkWidget *widget, GdkEvent *event
 static void sp_gradient_vector_dialog_destroy (GtkObject *object, gpointer data);
 
 static void sp_gradient_vector_widget_destroy (GtkObject *object, gpointer data);
-static void sp_gradient_vector_gradient_release (SPGradient *gradient, GtkWidget *widget);
-static void sp_gradient_vector_gradient_modified (SPGradient *gradient, guint flags, GtkWidget *widget);
+static void sp_gradient_vector_gradient_release (SPObject *obj, GtkWidget *widget);
+static void sp_gradient_vector_gradient_modified (SPObject *obj, guint flags, GtkWidget *widget);
 static void sp_gradient_vector_color_dragged (SPColorSelector *csel, GtkObject *object);
 static void sp_gradient_vector_color_changed (SPColorSelector *csel, GtkObject *object);
 static void update_stop_list( GtkWidget *mnu, SPGradient *gradient, SPStop *new_stop);
@@ -446,6 +464,9 @@ verify_grad(SPGradient *gradient)
                }
        }
 
+        Inkscape::XML::Document *xml_doc;
+        xml_doc = SP_OBJECT_REPR(gradient)->document();
+
        if (i < 1) {
                gchar c[64];
                sp_svg_write_color (c, 64, 0x00000000);
@@ -455,19 +476,19 @@ verify_grad(SPGradient *gradient)
 
                Inkscape::XML::Node *child;
 
-               child = sp_repr_new ("svg:stop");
+               child = xml_doc->createElement("svg:stop");
                sp_repr_set_css_double(child, "offset", 0.0);
                child->setAttribute("style", os.str().c_str());
                SP_OBJECT_REPR (gradient)->addChild(child, NULL);
 
-               child = sp_repr_new ("svg:stop");
+               child = xml_doc->createElement("svg:stop");
                sp_repr_set_css_double(child, "offset", 1.0);
                child->setAttribute("style", os.str().c_str());
                SP_OBJECT_REPR (gradient)->addChild(child, NULL);
        }
        if (i < 2) {
                sp_repr_set_css_double(SP_OBJECT_REPR(stop), "offset", 0.0);
-               Inkscape::XML::Node *child = SP_OBJECT_REPR(stop)->duplicate();
+               Inkscape::XML::Node *child = SP_OBJECT_REPR(stop)->duplicate(SP_OBJECT_REPR(gradient)->document());
                sp_repr_set_css_double(child, "offset", 1.0);
                SP_OBJECT_REPR(gradient)->addChild(child, SP_OBJECT_REPR (stop));
        }
@@ -637,7 +658,8 @@ offadjustmentChanged( GtkAdjustment *adjustment, GtkWidget *vb)
     stop->offset = adjustment->value;
     sp_repr_set_css_double(SP_OBJECT_REPR(stop), "offset", stop->offset);
 
-    sp_document_done (SP_OBJECT_DOCUMENT (stop));
+    sp_document_done (SP_OBJECT_DOCUMENT (stop), SP_VERB_CONTEXT_GRADIENT,
+                                                       _("Change gradient stop offset"));
 
        blocked = FALSE;
 }
@@ -679,11 +701,11 @@ sp_grd_ed_add_stop (GtkWidget *widget,  GtkWidget *vb)
        }
 
        if (next != NULL) {
-               new_stop_repr = SP_OBJECT_REPR(stop)->duplicate();
+               new_stop_repr = SP_OBJECT_REPR(stop)->duplicate(SP_OBJECT_REPR(gradient)->document());
                SP_OBJECT_REPR(gradient)->addChild(new_stop_repr, SP_OBJECT_REPR(stop));
        } else {
                next = stop;
-               new_stop_repr = SP_OBJECT_REPR(sp_prev_stop(stop, gradient))->duplicate();
+               new_stop_repr = SP_OBJECT_REPR(sp_prev_stop(stop, gradient))->duplicate(SP_OBJECT_REPR(gradient)->document());
                SP_OBJECT_REPR(gradient)->addChild(new_stop_repr, SP_OBJECT_REPR(sp_prev_stop(stop, gradient)));
        }
 
@@ -701,6 +723,7 @@ sp_grd_ed_add_stop (GtkWidget *widget,  GtkWidget *vb)
        gdouble opacity = (gdouble) SP_RGBA32_A_F (cnew);
        os << "stop-color:" << c << ";stop-opacity:" << opacity <<";";
        SP_OBJECT_REPR (newstop)->setAttribute("style", os.str().c_str());
+    sp_repr_set_css_double( SP_OBJECT_REPR(newstop), "offset", (double)newstop->offset);
 
        sp_gradient_vector_widget_load_gradient (vb, gradient);
        Inkscape::GC::release(new_stop_repr);
@@ -709,7 +732,8 @@ sp_grd_ed_add_stop (GtkWidget *widget,  GtkWidget *vb)
        GtkWidget *offslide =GTK_WIDGET (g_object_get_data (G_OBJECT (vb), "offslide"));
        gtk_widget_set_sensitive (offslide, TRUE);
        gtk_widget_set_sensitive (GTK_WIDGET (offspin), TRUE);
-       sp_document_done (SP_OBJECT_DOCUMENT (gradient));
+       sp_document_done (SP_OBJECT_DOCUMENT (gradient), SP_VERB_CONTEXT_GRADIENT, 
+                         _("Add gradient stop"));
 }
 
 static void
@@ -740,7 +764,8 @@ sp_grd_ed_del_stop (GtkWidget *widget,  GtkWidget *vb)
                SP_OBJECT_REPR(gradient)->removeChild(SP_OBJECT_REPR(stop));
                sp_gradient_vector_widget_load_gradient (vb, gradient);
                update_stop_list(GTK_WIDGET(mnu), gradient, NULL);
-               sp_document_done (SP_OBJECT_DOCUMENT (gradient));
+               sp_document_done (SP_OBJECT_DOCUMENT (gradient), SP_VERB_CONTEXT_GRADIENT, 
+                                 _("Delete gradient stop"));
        }
 
 }
@@ -832,8 +857,8 @@ sp_gradient_vector_widget_new (SPGradient *gradient, SPStop *select_stop)
 
 
        /* Signals */
-       gtk_signal_connect (GTK_OBJECT (Offset_adj), "value_changed",
-                                                                                       GTK_SIGNAL_FUNC (offadjustmentChanged), vb);
+       gtk_signal_connect (GTK_OBJECT (Offset_adj), "value_changed", 
+                           GTK_SIGNAL_FUNC (offadjustmentChanged), vb);
 
        // gtk_signal_connect (GTK_OBJECT (slider), "changed",  GTK_SIGNAL_FUNC (offsliderChanged), vb);
        gtk_widget_show (hb);
@@ -878,6 +903,10 @@ sp_gradient_vector_editor_new (SPGradient *gradient, SPStop *stop)
                        w = prefs_get_int_attribute (prefs_path, "w", 0);
                        h = prefs_get_int_attribute (prefs_path, "h", 0);
                }
+
+                if (x<0) x=0;
+                if (y<0) y=0;
+
                if (x != 0 || y != 0)
                        gtk_window_move ((GtkWindow *) dlg, x, y);
                else
@@ -932,14 +961,44 @@ sp_gradient_vector_widget_load_gradient (GtkWidget *widget, SPGradient *gradient
        SPGradient *old;
 
        old = (SPGradient*)g_object_get_data (G_OBJECT (widget), "gradient");
+
        if (old != gradient) {
+               sigc::connection *release_connection;
+               sigc::connection *modified_connection;
+
+               release_connection = (sigc::connection *)g_object_get_data(G_OBJECT(widget), "gradient_release_connection");
+               modified_connection = (sigc::connection *)g_object_get_data(G_OBJECT(widget), "gradient_modified_connection");
+
                if (old) {
+                       g_assert( release_connection != NULL );
+                       g_assert( modified_connection != NULL );
+                       release_connection->disconnect();
+                       modified_connection->disconnect();
                        sp_signal_disconnect_by_data (old, widget);
                }
+
                if (gradient) {
-                       g_signal_connect (G_OBJECT (gradient), "release", G_CALLBACK (sp_gradient_vector_gradient_release), widget);
-                       g_signal_connect (G_OBJECT (gradient), "modified", G_CALLBACK (sp_gradient_vector_gradient_modified), widget);
+                       if (!release_connection) {
+                               release_connection = new sigc::connection();
+                       }
+                       if (!modified_connection) {
+                               modified_connection = new sigc::connection();
+                       }
+                       *release_connection = gradient->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_gradient_vector_gradient_release), widget));
+                       *modified_connection = gradient->connectModified(sigc::bind<2>(sigc::ptr_fun(&sp_gradient_vector_gradient_modified), widget));
+               } else {
+                       if (release_connection) {
+                               delete release_connection;
+                               release_connection = NULL;
+                       }
+                       if (modified_connection) {
+                               delete modified_connection;
+                               modified_connection = NULL;
+                       }
                }
+
+               g_object_set_data(G_OBJECT(widget), "gradient_release_connection", release_connection);
+               g_object_set_data(G_OBJECT(widget), "gradient_modified_connection", modified_connection);
        }
 
        g_object_set_data (G_OBJECT (widget), "gradient", gradient);
@@ -971,8 +1030,8 @@ sp_gradient_vector_widget_load_gradient (GtkWidget *widget, SPGradient *gradient
        // Once the user edits a gradient, it stops being auto-collectable
        if (SP_OBJECT_REPR(gradient)->attribute("inkscape:collect")) {
                SPDocument *document = SP_OBJECT_DOCUMENT (gradient);
-               gboolean saved = sp_document_get_undo_sensitive(document);
-               sp_document_set_undo_sensitive (document, FALSE);
+               bool saved = sp_document_get_undo_sensitive(document);
+               sp_document_set_undo_sensitive (document, false);
                SP_OBJECT_REPR(gradient)->setAttribute("inkscape:collect", NULL);
                sp_document_set_undo_sensitive (document, saved);
        }
@@ -994,6 +1053,9 @@ sp_gradient_vector_dialog_delete (GtkWidget *widget, GdkEvent *event, GtkWidget
        gtk_window_get_position ((GtkWindow *) dlg, &x, &y);
        gtk_window_get_size ((GtkWindow *) dlg, &w, &h);
 
+    if (x<0) x=0;
+    if (y<0) y=0;
+
        prefs_set_int_attribute (prefs_path, "x", x);
        prefs_set_int_attribute (prefs_path, "y", y);
        prefs_set_int_attribute (prefs_path, "w", w);
@@ -1020,14 +1082,15 @@ sp_gradient_vector_widget_destroy (GtkObject *object, gpointer data)
 }
 
 static void
-sp_gradient_vector_gradient_release (SPGradient *gradient, GtkWidget *widget)
+sp_gradient_vector_gradient_release (SPObject *object, GtkWidget *widget)
 {
        sp_gradient_vector_widget_load_gradient (widget, NULL);
 }
 
 static void
-sp_gradient_vector_gradient_modified (SPGradient *gradient, guint flags, GtkWidget *widget)
+sp_gradient_vector_gradient_modified (SPObject *object, guint flags, GtkWidget *widget)
 {
+       SPGradient *gradient=SP_GRADIENT(object);
        if (!blocked) {
                blocked = TRUE;
                sp_gradient_vector_widget_load_gradient (widget, gradient);
@@ -1061,10 +1124,7 @@ static void sp_gradient_vector_color_dragged(SPColorSelector *csel, GtkObject *o
     csel->base->getColorAlpha(stop->specified_color, &stop->opacity);
     stop->currentColor = false;
 
-       blocked = FALSE;
-    SPColorPreview *cpv = (SPColorPreview *)g_object_get_data (G_OBJECT(gtk_menu_get_active (GTK_MENU(gtk_option_menu_get_menu (mnu)))), "preview");
-    sp_color_preview_set_rgba32(cpv, sp_stop_get_rgba32(stop));
-
+    blocked = FALSE;
 }
 
 static void
@@ -1109,7 +1169,22 @@ sp_gradient_vector_color_changed (SPColorSelector *csel, GtkObject *object)
                //      g_snprintf (c, 256, "stop-color:#%06x;stop-opacity:%g;", rgb >> 8, (gdouble) alpha);
                //SP_OBJECT_REPR (stop)->setAttribute("style", c);
 
-       sp_document_done (SP_OBJECT_DOCUMENT (ngr));
+       sp_document_done (SP_OBJECT_DOCUMENT (ngr), SP_VERB_CONTEXT_GRADIENT,
+                         _("Change gradient stop color"));
 
        blocked = FALSE;
+
+       SPColorPreview *cpv = (SPColorPreview *)g_object_get_data (G_OBJECT(gtk_menu_get_active (GTK_MENU(gtk_option_menu_get_menu (mnu)))), "preview");
+       sp_color_preview_set_rgba32(cpv, sp_stop_get_rgba32(stop));
 }
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :