Code

From trunk
[inkscape.git] / src / ui / context-menu.cpp
index b701adc2b3183fd9ccd1a66167c0634880a506e1..98ad9dc7bf8110d02b97857b2b34127fd82e8744 100644 (file)
@@ -17,6 +17,9 @@
 #include "../xml/repr.h"
 #include "desktop.h"
 #include "document.h"
+#include "message-stack.h"
+#include "preferences.h"
+#include "ui/dialog/dialog-manager.h"
 
 static void sp_object_type_menu(GType type, SPObject *object, SPDesktop *desktop, GtkMenu *menu);
 
@@ -47,12 +50,13 @@ sp_object_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu)
 #include "document.h"
 #include "desktop-handles.h"
 #include "selection.h"
-
+#include "selection-chemistry.h"
 #include "dialogs/item-properties.h"
 #include "dialogs/object-attributes.h"
-#include "dialogs/object-properties.h"
 
 #include "sp-path.h"
+#include "sp-clippath.h"
+#include "sp-mask.h"
 
 
 static void sp_item_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu);
@@ -83,7 +87,10 @@ sp_object_type_menu(GType type, SPObject *object, SPDesktop *desktop, GtkMenu *m
 static void sp_item_properties(GtkMenuItem *menuitem, SPItem *item);
 static void sp_item_select_this(GtkMenuItem *menuitem, SPItem *item);
 static void sp_item_create_link(GtkMenuItem *menuitem, SPItem *item);
-
+static void sp_set_mask(GtkMenuItem *menuitem, SPItem *item);
+static void sp_release_mask(GtkMenuItem *menuitem, SPItem *item);
+static void sp_set_clip(GtkMenuItem *menuitem, SPItem *item);
+static void sp_release_clip(GtkMenuItem *menuitem, SPItem *item);
 /* Generate context menu item section */
 
 static void
@@ -121,6 +128,51 @@ sp_item_menu(SPObject *object, SPDesktop *desktop, GtkMenu *m)
     gtk_widget_set_sensitive(w, !SP_IS_ANCHOR(item));
     gtk_widget_show(w);
     gtk_menu_append(GTK_MENU(m), w);
+    /* Set mask */
+    w = gtk_menu_item_new_with_mnemonic(_("Set Mask"));
+    gtk_object_set_data(GTK_OBJECT(w), "desktop", desktop);
+    gtk_signal_connect(GTK_OBJECT(w), "activate", GTK_SIGNAL_FUNC(sp_set_mask), item);
+    if ((item && item->mask_ref && item->mask_ref->getObject()) || (item->clip_ref && item->clip_ref->getObject())) {
+        gtk_widget_set_sensitive(w, FALSE);
+    } else {
+        gtk_widget_set_sensitive(w, TRUE);
+    }
+    gtk_widget_show(w);
+    gtk_menu_append(GTK_MENU(m), w);
+    /* Release mask */
+    w = gtk_menu_item_new_with_mnemonic(_("Release Mask"));
+    gtk_object_set_data(GTK_OBJECT(w), "desktop", desktop);
+    gtk_signal_connect(GTK_OBJECT(w), "activate", GTK_SIGNAL_FUNC(sp_release_mask), item);
+    if (item && item->mask_ref && item->mask_ref->getObject()) {
+        gtk_widget_set_sensitive(w, TRUE);
+    } else {
+        gtk_widget_set_sensitive(w, FALSE);
+    }
+    gtk_widget_show(w);
+    gtk_menu_append(GTK_MENU(m), w);
+    /* Set Clip */
+    w = gtk_menu_item_new_with_mnemonic(_("Set Clip"));
+    gtk_object_set_data(GTK_OBJECT(w), "desktop", desktop);
+    gtk_signal_connect(GTK_OBJECT(w), "activate", GTK_SIGNAL_FUNC(sp_set_clip), item);
+    if ((item && item->mask_ref && item->mask_ref->getObject()) || (item->clip_ref && item->clip_ref->getObject())) {
+        gtk_widget_set_sensitive(w, FALSE);
+    } else {
+        gtk_widget_set_sensitive(w, TRUE);
+    }
+    gtk_widget_show(w);
+    gtk_menu_append(GTK_MENU(m), w);
+    /* Release Clip */
+    w = gtk_menu_item_new_with_mnemonic(_("Release Clip"));
+    gtk_object_set_data(GTK_OBJECT(w), "desktop", desktop);
+    gtk_signal_connect(GTK_OBJECT(w), "activate", GTK_SIGNAL_FUNC(sp_release_clip), item);
+    if (item && item->clip_ref && item->clip_ref->getObject()) {
+        gtk_widget_set_sensitive(w, TRUE);
+    } else {
+        gtk_widget_set_sensitive(w, FALSE);
+    }
+    gtk_widget_show(w);
+    gtk_menu_append(GTK_MENU(m), w);
+
 }
 
 static void
@@ -138,6 +190,63 @@ sp_item_properties(GtkMenuItem *menuitem, SPItem *item)
     sp_item_dialog();
 }
 
+
+static void
+sp_set_mask(GtkMenuItem *menuitem, SPItem *item)
+{
+    SPDesktop *desktop;
+
+    g_assert(SP_IS_ITEM(item));
+
+    desktop = (SPDesktop*)gtk_object_get_data(GTK_OBJECT(menuitem), "desktop");
+    g_return_if_fail(desktop != NULL);
+
+       sp_selection_set_mask(desktop, false, false);
+}
+
+
+static void
+sp_release_mask(GtkMenuItem *menuitem, SPItem *item)
+{
+    SPDesktop *desktop;
+
+    g_assert(SP_IS_ITEM(item));
+
+    desktop = (SPDesktop*)gtk_object_get_data(GTK_OBJECT(menuitem), "desktop");
+    g_return_if_fail(desktop != NULL);
+
+    sp_selection_unset_mask(desktop, false);
+}
+
+
+static void
+sp_set_clip(GtkMenuItem *menuitem, SPItem *item)
+{
+    SPDesktop *desktop;
+
+    g_assert(SP_IS_ITEM(item));
+
+    desktop = (SPDesktop*)gtk_object_get_data(GTK_OBJECT(menuitem), "desktop");
+    g_return_if_fail(desktop != NULL);
+
+       sp_selection_set_mask(desktop, true, false);
+}
+
+
+static void
+sp_release_clip(GtkMenuItem *menuitem, SPItem *item)
+{
+    SPDesktop *desktop;
+
+    g_assert(SP_IS_ITEM(item));
+
+    desktop = (SPDesktop*)gtk_object_get_data(GTK_OBJECT(menuitem), "desktop");
+    g_return_if_fail(desktop != NULL);
+
+    sp_selection_unset_mask(desktop, true);
+}
+
+
 static void
 sp_item_select_this(GtkMenuItem *menuitem, SPItem *item)
 {
@@ -167,11 +276,15 @@ sp_item_create_link(GtkMenuItem *menuitem, SPItem *item)
     g_return_if_fail(SP_IS_ANCHOR(object));
 
     const char *id = SP_OBJECT_REPR(item)->attribute("id");
-    Inkscape::XML::Node *child = SP_OBJECT_REPR(item)->duplicate();
+    Inkscape::XML::Node *child = SP_OBJECT_REPR(item)->duplicate(xml_doc);
     SP_OBJECT(item)->deleteObject(false);
     repr->addChild(child, NULL);
     child->setAttribute("id", id);
-    sp_document_done(SP_OBJECT_DOCUMENT(object), SP_VERB_NONE, 
+
+    Inkscape::GC::release(repr);
+    Inkscape::GC::release(child);
+
+    sp_document_done(SP_OBJECT_DOCUMENT(object), SP_VERB_NONE,
                      _("Create link"));
 
     sp_object_attributes_dialog(object, "SPAnchor");
@@ -235,10 +348,6 @@ sp_anchor_menu(SPObject *object, SPDesktop *desktop, GtkMenu *m)
     gtk_signal_connect(GTK_OBJECT(w), "activate", GTK_SIGNAL_FUNC(sp_anchor_link_properties), item);
     gtk_widget_show(w);
     gtk_menu_append(GTK_MENU(m), w);
-    /* Separator */
-    w = gtk_menu_item_new();
-    gtk_widget_show(w);
-    gtk_menu_append(GTK_MENU(m), w);
     /* Select item */
     w = gtk_menu_item_new_with_mnemonic(_("_Follow Link"));
     gtk_signal_connect(GTK_OBJECT(w), "activate", GTK_SIGNAL_FUNC(sp_anchor_link_follow), item);
@@ -253,13 +362,13 @@ sp_anchor_menu(SPObject *object, SPDesktop *desktop, GtkMenu *m)
 }
 
 static void
-sp_anchor_link_properties(GtkMenuItem *menuitem, SPAnchor *anchor)
+sp_anchor_link_properties(GtkMenuItem */*menuitem*/, SPAnchor *anchor)
 {
     sp_object_attributes_dialog(SP_OBJECT(anchor), "Link");
 }
 
 static void
-sp_anchor_link_follow(GtkMenuItem *menuitem, SPAnchor *anchor)
+sp_anchor_link_follow(GtkMenuItem */*menuitem*/, SPAnchor *anchor)
 {
     g_return_if_fail(anchor != NULL);
     g_return_if_fail(SP_IS_ANCHOR(anchor));
@@ -268,7 +377,7 @@ sp_anchor_link_follow(GtkMenuItem *menuitem, SPAnchor *anchor)
 }
 
 static void
-sp_anchor_link_remove(GtkMenuItem *menuitem, SPAnchor *anchor)
+sp_anchor_link_remove(GtkMenuItem */*menuitem*/, SPAnchor *anchor)
 {
     GSList *children;
 
@@ -284,29 +393,86 @@ sp_anchor_link_remove(GtkMenuItem *menuitem, SPAnchor *anchor)
 /* Image */
 
 static void sp_image_image_properties(GtkMenuItem *menuitem, SPAnchor *anchor);
+static void sp_image_image_edit(GtkMenuItem *menuitem, SPAnchor *anchor);
 
 static void
 sp_image_menu(SPObject *object, SPDesktop *desktop, GtkMenu *m)
 {
-    SPItem *item;
+    SPItem *item = SP_ITEM(object);
     GtkWidget *w;
 
-    item = (SPItem *) object;
-
     /* Link dialog */
     w = gtk_menu_item_new_with_mnemonic(_("Image _Properties"));
     gtk_object_set_data(GTK_OBJECT(w), "desktop", desktop);
     gtk_signal_connect(GTK_OBJECT(w), "activate", GTK_SIGNAL_FUNC(sp_image_image_properties), item);
     gtk_widget_show(w);
     gtk_menu_append(GTK_MENU(m), w);
+
+    w = gtk_menu_item_new_with_mnemonic(_("Edit Externally..."));
+    gtk_object_set_data(GTK_OBJECT(w), "desktop", desktop);
+    gtk_signal_connect(GTK_OBJECT(w), "activate", GTK_SIGNAL_FUNC(sp_image_image_edit), item);
+    gtk_widget_show(w);
+    gtk_menu_append(GTK_MENU(m), w);
+    Inkscape::XML::Node *ir = SP_OBJECT_REPR(object);
+    const gchar *href = ir->attribute("xlink:href");
+    if ( (!href) || ((strncmp(href, "data:", 5) == 0)) ) {
+        gtk_widget_set_sensitive( w, FALSE );
+    }
 }
 
 static void
-sp_image_image_properties(GtkMenuItem *menuitem, SPAnchor *anchor)
+sp_image_image_properties(GtkMenuItem */*menuitem*/, SPAnchor *anchor)
 {
     sp_object_attributes_dialog(SP_OBJECT(anchor), "Image");
 }
 
+static gchar* getImageEditorName() {
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+    gchar* value = 0;
+    Glib::ustring choices = prefs->getString("/options/bitmapeditor/choices");
+    if (!choices.empty()) {
+        gchar** splits = g_strsplit(choices.data(), ",", 0);
+        gint numIems = g_strv_length(splits);
+
+        int setting = prefs->getIntLimited("/options/bitmapeditor/value", 0, 0, numIems);
+        value = g_strdup(splits[setting]);
+
+        g_strfreev(splits);
+    }
+
+    if (!value) {
+        value = g_strdup("gimp");
+    }
+    return value;
+}
+
+static void sp_image_image_edit(GtkMenuItem *menuitem, SPAnchor *anchor)
+{
+    SPObject* obj = SP_OBJECT(anchor);
+    Inkscape::XML::Node *ir = SP_OBJECT_REPR(obj);
+    const gchar *href = ir->attribute("xlink:href");
+
+    GError* errThing = 0;
+    gchar* editorBin = getImageEditorName();
+    gchar const* args[] = {editorBin, href, 0};
+    g_spawn_async(0, // working dir
+                  const_cast<gchar **>(args),
+                  0, //envp
+                  G_SPAWN_SEARCH_PATH,
+                  0, // child_setup
+                  0, // user_data
+                  0, //GPid *child_pid
+                  &errThing);
+    if ( errThing ) {
+        g_warning("Problem launching editor (%d). %s", errThing->code, errThing->message);
+        SPDesktop *desktop = (SPDesktop*)gtk_object_get_data(GTK_OBJECT(menuitem), "desktop");
+        desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, errThing->message);
+        g_error_free(errThing);
+        errThing = 0;
+    }
+    g_free(editorBin);
+}
+
 /* SPShape */
 
 static void
@@ -323,7 +489,7 @@ sp_shape_fill_settings(GtkMenuItem *menuitem, SPItem *item)
         sp_desktop_selection(desktop)->set(item);
     }
 
-    sp_object_properties_dialog();
+    desktop->_dlg_mgr->showDialog("FillAndStroke");
 }
 
 static void