Code

disconnect signals on destroying
[inkscape.git] / src / widgets / desktop-widget.cpp
index 7c70b01fa2f2e65ffbe4ec0c41e0e86c94a8a7c1..6b15bb370a0b081576b18f5f8e2eeb38e8caa0f5 100644 (file)
@@ -8,7 +8,9 @@
  *   MenTaLguY <mental@rydia.net>
  *   bulia byak <buliabyak@users.sf.net>
  *   Ralf Stephan <ralf@ark.in-berlin.de>
+ *   John Bintz <jcoswell@coswellproductions.org>
  *
+ * Copyright (C) 2006 John Bintz
  * Copyright (C) 2004 MenTaLguY
  * Copyright (C) 1999-2002 Lauris Kaplinski
  * Copyright (C) 2000-2001 Ximian, Inc.
@@ -77,7 +79,7 @@ static gint sp_desktop_widget_event (GtkWidget *widget, GdkEvent *event, SPDeskt
 
 
 static void sp_desktop_widget_adjustment_value_changed (GtkAdjustment *adj, SPDesktopWidget *dtw);
-static void sp_desktop_widget_namedview_modified (SPNamedView *nv, guint flags, SPDesktopWidget *dtw);
+static void sp_desktop_widget_namedview_modified (SPObject *obj, guint flags, SPDesktopWidget *dtw);
 
 static gdouble sp_dtw_zoom_value_to_display (gdouble value);
 static gdouble sp_dtw_zoom_display_to_value (gdouble value);
@@ -163,12 +165,16 @@ sp_desktop_widget_init (SPDesktopWidget *dtw)
     GtkWidget *eventbox;
     GtkStyle *style;
 
+    new (&dtw->modified_connection) sigc::connection();
+
     widget = GTK_WIDGET (dtw);
 
     dtw->window = 0;
     
     dtw->desktop = NULL;
 
+    dtw->_interaction_disabled_counter = 0;
+    
     dtw->tt = gtk_tooltips_new ();
 
     /* Main table */
@@ -182,7 +188,7 @@ sp_desktop_widget_init (SPDesktopWidget *dtw)
     {
         using Inkscape::UI::Dialogs::SwatchesPanel;
 
-        SwatchesPanel* swatches = new SwatchesPanel();
+        SwatchesPanel* swatches = new SwatchesPanel("embedded.swatches");
         swatches->setOrientation( Gtk::ANCHOR_SOUTH );
         dtw->panels = GTK_WIDGET(swatches->gobj());
         gtk_box_pack_end( GTK_BOX( dtw->vbox ), dtw->panels, FALSE, TRUE, 0 );
@@ -234,7 +240,7 @@ sp_desktop_widget_init (SPDesktopWidget *dtw)
     gtk_table_attach (GTK_TABLE (tbl), dtw->hscrollbar, 1, 2, 2, 3, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)(GTK_FILL), 0, 0);
     /* Vertical scrollbar and the sticky zoom button */
     dtw->vscrollbar_box = gtk_vbox_new (FALSE, 0);
-    dtw->sticky_zoom = sp_button_new_from_data ( Inkscape::ICON_SIZE_MENU,
+    dtw->sticky_zoom = sp_button_new_from_data ( Inkscape::ICON_SIZE_DECORATION,
                                                  SP_BUTTON_TYPE_TOGGLE,
                                                  NULL,
                                                  "sticky_zoom",
@@ -342,14 +348,23 @@ sp_desktop_widget_destroy (GtkObject *object)
     SPDesktopWidget *dtw = SP_DESKTOP_WIDGET (object);
 
     if (dtw->desktop) {
+        g_signal_handlers_disconnect_by_func(G_OBJECT (dtw->zoom_status), (gpointer) G_CALLBACK(sp_dtw_zoom_input), dtw);
+        g_signal_handlers_disconnect_by_func(G_OBJECT (dtw->zoom_status), (gpointer) G_CALLBACK(sp_dtw_zoom_output), dtw);
+        gtk_signal_disconnect_by_data (GTK_OBJECT (dtw->zoom_status), dtw->zoom_status);
+        g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->zoom_status), (gpointer) G_CALLBACK (sp_dtw_zoom_value_changed), dtw);
+        g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->zoom_status), (gpointer) G_CALLBACK (sp_dtw_zoom_populate_popup), dtw);
+        g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->canvas), (gpointer) G_CALLBACK (sp_desktop_widget_event), dtw);
+
         dtw->layer_selector->unreference();
         inkscape_remove_desktop (dtw->desktop); // clears selection too
-        sp_signal_disconnect_by_data (G_OBJECT (dtw->desktop->namedview), dtw);
+        dtw->modified_connection.disconnect();
         dtw->desktop->destroy();
         Inkscape::GC::release (dtw->desktop);
         dtw->desktop = NULL;
     }
 
+    dtw->modified_connection.~connection();
+
     if (GTK_OBJECT_CLASS (dtw_parent_class)->destroy) {
         (* GTK_OBJECT_CLASS (dtw_parent_class)->destroy) (object);
     }
@@ -449,7 +464,10 @@ sp_desktop_widget_realize (GtkWidget *widget)
     dtw->desktop->set_display_area (d.x0, d.y0, d.x1, d.y1, 10);
 
     /* Listen on namedview modification */
-    g_signal_connect (G_OBJECT (dtw->desktop->namedview), "modified", G_CALLBACK (sp_desktop_widget_namedview_modified), dtw);
+    // originally (prior to the sigc++ conversion) the signal was simply
+    // connected twice rather than disconnecting the first connection
+    dtw->modified_connection.disconnect();
+    dtw->modified_connection = dtw->desktop->namedview->connectModified(sigc::bind<2>(sigc::ptr_fun(&sp_desktop_widget_namedview_modified), dtw));
     sp_desktop_widget_namedview_modified (dtw->desktop->namedview, SP_OBJECT_MODIFIED_FLAG, dtw);
 
     dtw->updateTitle(SP_DOCUMENT_NAME (dtw->desktop->doc()));
@@ -653,6 +671,37 @@ SPDesktopWidget::requestCanvasUpdate() {
     gtk_widget_queue_draw (GTK_WIDGET (SP_CANVAS_ITEM (this->desktop->main)->canvas));
 }
 
+void 
+SPDesktopWidget::requestCanvasUpdateAndWait() {
+    requestCanvasUpdate();
+    
+    while (gtk_events_pending()) 
+      gtk_main_iteration_do(FALSE);
+
+}
+
+void
+SPDesktopWidget::enableInteraction()
+{
+  g_return_if_fail(_interaction_disabled_counter > 0);
+  
+  _interaction_disabled_counter--;
+  
+  if (_interaction_disabled_counter == 0) {
+    gtk_widget_set_sensitive(GTK_WIDGET(this), TRUE);
+  }
+}
+
+void
+SPDesktopWidget::disableInteraction()
+{
+  if (_interaction_disabled_counter == 0) {
+    gtk_widget_set_sensitive(GTK_WIDGET(this), FALSE);
+  }
+  
+  _interaction_disabled_counter++;
+}
+
 void 
 SPDesktopWidget::setCoordinateStatus(NR::Point p)
 {
@@ -822,30 +871,8 @@ sp_desktop_widget_layout (SPDesktopWidget *dtw)
 
     if (prefs_get_int_attribute (fullscreen ? "fullscreen.panels" : "window.panels", "state", 1) == 0) {
         gtk_widget_hide_all( dtw->panels );
-        GList* kids = gtk_container_get_children( GTK_CONTAINER( dtw->statusbar ) );
-        if ( kids )
-        {
-            GList* last = g_list_last( kids );
-            if ( last )
-            {
-                GtkStatusbar* tail = GTK_STATUSBAR( last->data );
-                gtk_statusbar_set_has_resize_grip( tail, TRUE );
-            }
-            g_list_free( kids );
-        }
     } else {
         gtk_widget_show_all( dtw->panels );
-        GList* kids = gtk_container_get_children( GTK_CONTAINER( dtw->statusbar ) );
-        if ( kids )
-        {
-            GList* last = g_list_last( kids );
-            if ( last )
-            {
-                GtkStatusbar* tail = GTK_STATUSBAR( last->data );
-                gtk_statusbar_set_has_resize_grip( tail, FALSE );
-            }
-            g_list_free( kids );
-        }
     }
 
     if (prefs_get_int_attribute (fullscreen ? "fullscreen.scrollbars" : "window.scrollbars", "state", 1) == 0) {
@@ -919,7 +946,7 @@ sp_desktop_widget_new (SPNamedView *namedview)
     sp_view_widget_set_view (SP_VIEW_WIDGET (dtw), dtw->desktop);
 
     /* Listen on namedview modification */
-    g_signal_connect (G_OBJECT (namedview), "modified", G_CALLBACK (sp_desktop_widget_namedview_modified), dtw);
+    dtw->modified_connection = namedview->connectModified(sigc::bind<2>(sigc::ptr_fun(&sp_desktop_widget_namedview_modified), dtw));
 
     dtw->layer_selector->setDesktop(dtw->desktop);
 
@@ -963,8 +990,9 @@ sp_desktop_widget_update_rulers (SPDesktopWidget *dtw)
 
 
 static void
-sp_desktop_widget_namedview_modified (SPNamedView *nv, guint flags, SPDesktopWidget *dtw)
+sp_desktop_widget_namedview_modified (SPObject *obj, guint flags, SPDesktopWidget *dtw)
 {
+    SPNamedView *nv=SP_NAMEDVIEW(obj);
     if (flags & SP_OBJECT_MODIFIED_FLAG) {
         dtw->dt2r = 1.0 / nv->doc_units->unittobase;
         dtw->ruler_origin = nv->gridorigin;