Code

Adding the new/change label to the star toolbar
[inkscape.git] / src / widgets / desktop-widget.cpp
index acd631c6a41f54525af45c5b12cf28ac868c26a6..65afc4f2926cf7b293e9b9eff152e752e9b4104d 100644 (file)
@@ -8,7 +8,11 @@
  *   MenTaLguY <mental@rydia.net>
  *   bulia byak <buliabyak@users.sf.net>
  *   Ralf Stephan <ralf@ark.in-berlin.de>
+ *   John Bintz <jcoswell@coswellproductions.org>
+ *   Johan Engelen <j.b.c.engelen@ewi.utwente.nl>
  *
+ * Copyright (C) 2007 Johan Engelen
+ * Copyright (C) 2006 John Bintz
  * Copyright (C) 2004 MenTaLguY
  * Copyright (C) 1999-2002 Lauris Kaplinski
  * Copyright (C) 2000-2001 Ximian, Inc.
@@ -35,6 +39,7 @@
 #include "prefs-utils.h"
 #include "file.h"
 #include "display/canvas-arena.h"
+#include "display/nr-arena.h"
 #include <extension/db.h>
 #include "helper/units.h"
 #include "widgets/button.h"
 #include "dialogs/swatches.h"
 #include "conn-avoid-ref.h"
 
+#if defined (SOLARIS_2_8)
+#include "round.h"
+using Inkscape::round;
+#endif 
+
 #ifdef WITH_INKBOARD
 #endif
 
@@ -77,7 +87,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);
@@ -100,6 +110,13 @@ SPDesktopWidget::setMessage (Inkscape::MessageType type, const gchar *message)
 {
     GtkLabel *sb=GTK_LABEL(this->select_status);
     gtk_label_set_markup (sb, message ? message : "");
+
+    // make sure the important messages are displayed immediately!
+    if (type == Inkscape::IMMEDIATE_MESSAGE && GTK_WIDGET_DRAWABLE (GTK_WIDGET(sb))) {
+        gtk_widget_queue_draw(GTK_WIDGET(sb));
+        gdk_window_process_updates(GTK_WIDGET(sb)->window, TRUE);
+    }
+
     // FIXME: TODO: remove <b></b> before displaying as tooltip
     gtk_tooltips_set_tip (this->tt, this->select_status_eventbox, message ? message : "", NULL);
 }
@@ -158,18 +175,21 @@ sp_desktop_widget_init (SPDesktopWidget *dtw)
 {
     GtkWidget *widget;
     GtkWidget *tbl;
-    GtkWidget *w;
 
     GtkWidget *hbox;
     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 */
@@ -183,8 +203,8 @@ sp_desktop_widget_init (SPDesktopWidget *dtw)
     {
         using Inkscape::UI::Dialogs::SwatchesPanel;
 
-        SwatchesPanel* swatches = new SwatchesPanel();
-        swatches->Temp();
+        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 );
     }
@@ -235,7 +255,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 ( GTK_ICON_SIZE_MENU,
+    dtw->sticky_zoom = sp_button_new_from_data ( Inkscape::ICON_SIZE_DECORATION,
                                                  SP_BUTTON_TYPE_TOGGLE,
                                                  NULL,
                                                  "sticky_zoom",
@@ -249,8 +269,6 @@ sp_desktop_widget_init (SPDesktopWidget *dtw)
     gtk_table_attach (GTK_TABLE (tbl), dtw->vscrollbar_box, 2, 3, 0, 2, (GtkAttachOptions)(GTK_FILL), (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 0, 0);
 
     /* Canvas */
-    w = gtk_frame_new (NULL);
-    gtk_table_attach (GTK_TABLE (tbl), w, 1, 2, 1, 2, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 0, 0);
     dtw->canvas = SP_CANVAS (sp_canvas_new_aa ());
     GTK_WIDGET_SET_FLAGS (GTK_WIDGET (dtw->canvas), GTK_CAN_FOCUS);
     style = gtk_style_copy (GTK_WIDGET (dtw->canvas)->style);
@@ -258,7 +276,7 @@ sp_desktop_widget_init (SPDesktopWidget *dtw)
     gtk_widget_set_style (GTK_WIDGET (dtw->canvas), style);
     gtk_widget_set_extension_events(GTK_WIDGET (dtw->canvas) , GDK_EXTENSION_EVENTS_ALL);
     g_signal_connect (G_OBJECT (dtw->canvas), "event", G_CALLBACK (sp_desktop_widget_event), dtw);
-    gtk_container_add (GTK_CONTAINER (w), GTK_WIDGET (dtw->canvas));
+    gtk_table_attach (GTK_TABLE (tbl), GTK_WIDGET (dtw->canvas), 1, 2, 1, 2, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 0, 0);
 
     dtw->selected_style = new Inkscape::UI::Widget::SelectedStyle(true);
     GtkHBox *ss_ = dtw->selected_style->gobj();
@@ -345,14 +363,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);
     }
@@ -375,9 +402,17 @@ SPDesktopWidget::updateTitle(gchar const* uri)
                                : g_basename(uri) );
         GString *name = g_string_new ("");
         if (this->desktop->number > 1) {
-            g_string_printf (name, _("%s: %d - Inkscape"), fname, this->desktop->number);
+            if (this->desktop->getMode() == RENDERMODE_OUTLINE) {
+                g_string_printf (name, _("%s: %d (outline) - Inkscape"), fname, this->desktop->number);
+            } else {
+                g_string_printf (name, _("%s: %d - Inkscape"), fname, this->desktop->number);
+            }
         } else {
-            g_string_printf (name, _("%s - Inkscape"), fname);
+            if (this->desktop->getMode() == RENDERMODE_OUTLINE) {
+                g_string_printf (name, _("%s (outline) - Inkscape"), fname);
+            } else {
+                g_string_printf (name, _("%s - Inkscape"), fname);
+            }
         }
         gtk_window_set_title (window, name->str);
         g_string_free (name, TRUE);
@@ -452,7 +487,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()));
@@ -656,6 +694,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)
 {
@@ -710,12 +779,12 @@ SPDesktopWidget::setWindowSize (gint w, gint h)
 /**
  * \note transientizing does not work on windows; when you minimize a document 
  * and then open it back, only its transient emerges and you cannot access 
- * the document window.
+ * the document window. The document window must be restored by rightclicking
+ * the taskbar button and pressing "Restore"
  */
 void
 SPDesktopWidget::setWindowTransient (void *p, int transient_policy)
 {
-#ifndef WIN32
     GtkWindow *w =GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(this)));
     if (w)
     {
@@ -733,7 +802,6 @@ SPDesktopWidget::setWindowTransient (void *p, int transient_policy)
             // without this, a transient window not always emerges on top
             gtk_window_present (w); 
     }
-#endif
 }
 
 void
@@ -755,7 +823,7 @@ SPDesktopWidget::warnDialog (gchar* text)
                 GTK_DIALOG_DESTROY_WITH_PARENT,
                 GTK_MESSAGE_WARNING,
                 GTK_BUTTONS_YES_NO,
-                text);
+                "%s", text);
         gint response = gtk_dialog_run(GTK_DIALOG(dialog));
         gtk_widget_destroy(dialog);
         if (response == GTK_RESPONSE_YES)
@@ -825,30 +893,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) {
@@ -922,7 +968,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);
 
@@ -966,8 +1012,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;
@@ -1227,11 +1274,9 @@ sp_desktop_widget_update_scrollbars (SPDesktopWidget *dtw, double scale)
 
     /* The desktop region we always show unconditionally */
     SPDocument *doc = dtw->desktop->doc();
-    NR::Rect const r = sp_item_bbox_desktop(SP_ITEM(SP_DOCUMENT_ROOT(doc)));
-    NR::Rect darea(NR::Point(MIN(r.min()[NR::X], -sp_document_width(doc)),
-                             MIN(r.min()[NR::Y], -sp_document_height(doc))),
-                   NR::Point(MAX(r.max()[NR::X], 2 * sp_document_width(doc)),
-                             MAX(r.max()[NR::Y], 2 * sp_document_height(doc))));
+    NR::Rect darea(NR::Point(-sp_document_width(doc), -sp_document_height(doc)),
+                   NR::Point(2 * sp_document_width(doc), 2 * sp_document_height(doc)));
+    darea = NR::union_bounds(darea, sp_item_bbox_desktop(SP_ITEM(SP_DOCUMENT_ROOT(doc))));
 
     /* Canvas region we always show unconditionally */
     NR::Rect carea(NR::Point(darea.min()[NR::X] * scale - 64,
@@ -1242,7 +1287,7 @@ sp_desktop_widget_update_scrollbars (SPDesktopWidget *dtw, double scale)
     NR::Rect viewbox = dtw->canvas->getViewbox();
 
     /* Viewbox is always included into scrollable region */
-    carea = NR::Rect::union_bounds(carea, viewbox);
+    carea = NR::union_bounds(carea, viewbox);
 
     set_adjustment(dtw->hadj, carea.min()[NR::X], carea.max()[NR::X],
                    viewbox.dimensions()[NR::X],