diff options
| author | Kris De Gussem <kris.degussem@gmail.com> | 2012-04-05 20:14:44 +0000 |
|---|---|---|
| committer | Kris <Kris.De.Gussem@hotmail.com> | 2012-04-05 20:14:44 +0000 |
| commit | bcd804c6c383e2964b072257da282d9a91db7d16 (patch) | |
| tree | aa9617b1045a4dda778ac86c7fc5c4ef22eef535 /src | |
| parent | add test code for bug #967416 (diff) | |
| download | inkscape-bcd804c6c383e2964b072257da282d9a91db7d16.tar.gz inkscape-bcd804c6c383e2964b072257da282d9a91db7d16.zip | |
C++ify context menu:
- c++ified context-menu.cpp (and included in interface.cpp)
- removed dozens of pointer conversions (of which some were erroneous)
- fixed a memory leak
- added some null pointer checks to prevent crashes
(bzr r11160)
Diffstat (limited to 'src')
| -rw-r--r-- | src/doxygen-main.cpp | 2 | ||||
| -rw-r--r-- | src/event-context.cpp | 14 | ||||
| -rw-r--r-- | src/interface.cpp | 792 | ||||
| -rw-r--r-- | src/interface.h | 61 | ||||
| -rw-r--r-- | src/ui/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/ui/Makefile_insert | 2 | ||||
| -rw-r--r-- | src/ui/context-menu.cpp | 715 | ||||
| -rw-r--r-- | src/ui/context-menu.h | 36 |
8 files changed, 751 insertions, 873 deletions
diff --git a/src/doxygen-main.cpp b/src/doxygen-main.cpp index ea4d056ce..70c62b3a9 100644 --- a/src/doxygen-main.cpp +++ b/src/doxygen-main.cpp @@ -305,7 +305,7 @@ namespace XML {} * [\ref help.cpp] [\ref inkscape.cpp] [\ref inkscape-stock.cpp] * [\ref interface.cpp, \ref memeq.h] [\ref main.cpp, \ref winmain.cpp] * [\ref menus-skeleton.h, \ref preferences-skeleton.h] - * [\ref context-menu.cpp] [\ref select-toolbar.cpp] [\ref shortcuts.cpp] + * [\ref select-toolbar.cpp] [\ref shortcuts.cpp] * [\ref sp-cursor.cpp] [\ref text-edit.cpp] [\ref toolbox.cpp, \ref ui/widget/toolbox.cpp] * Inkscape::Verb [\ref verbs.h] * diff --git a/src/event-context.cpp b/src/event-context.cpp index 0cfa18f57..4ea4068fe 100644 --- a/src/event-context.cpp +++ b/src/event-context.cpp @@ -6,8 +6,9 @@ * Frank Felfe <innerspace@iname.com> * bulia byak <buliabyak@users.sf.net> * Jon A. Cruz <jon@joncruz.org> + * Kris De Gussem <Kris.DeGussem@gmail.com> * - * Copyright (C) 1999-2010 authors + * Copyright (C) 1999-2012 authors * Copyright (C) 2001-2002 Ximian, Inc. * * Released under GNU GPL, read the file 'COPYING' for more information @@ -1034,22 +1035,19 @@ static void set_event_location(SPDesktop *desktop, GdkEvent *event) { * Create popup menu and tell Gtk to show it. */ void sp_event_root_menu_popup(SPDesktop *desktop, SPItem *item, GdkEvent *event) { - GtkWidget *menu; - /* fixme: This is not what I want but works for now (Lauris) */ if (event->type == GDK_KEY_PRESS) { item = sp_desktop_selection(desktop)->singleItem(); } - menu = sp_ui_context_menu(desktop, item); - gtk_widget_show(menu); + ContextMenu* CM = new ContextMenu(desktop, item); + CM->show(); switch (event->type) { case GDK_BUTTON_PRESS: - gtk_menu_popup(GTK_MENU(menu), NULL, NULL, 0, NULL, - event->button.button, event->button.time); + CM->popup(event->button.button, event->button.time); break; case GDK_KEY_PRESS: - gtk_menu_popup(GTK_MENU(menu), NULL, NULL, 0, NULL, 0, event->key.time); + CM->popup(0, event->key.time); break; default: break; diff --git a/src/interface.cpp b/src/interface.cpp index 1e1324e32..77ef9a075 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -8,11 +8,13 @@ * bulia byak <buliabyak@users.sf.net> * Jon A. Cruz <jon@joncruz.org> * Abhishek Sharma + * Kris De Gussem <Kris.DeGussem@gmail.com> * + * Copyright (C) 2012 Kris De Gussem * Copyright (C) 2010 authors * Copyright (C) 1999-2005 authors - * Copyright (C) 2001-2002 Ximian, Inc. * Copyright (C) 2004 David Turner + * Copyright (C) 2001-2002 Ximian, Inc. * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -37,7 +39,6 @@ #include "desktop-handles.h" #include "interface.h" #include "desktop.h" -#include "ui/context-menu.h" #include "selection.h" #include "selection-chemistry.h" #include "svg-view-widget.h" @@ -66,6 +67,16 @@ #include "gradient-drag.h" #include "widgets/ege-paint-def.h" #include "document-undo.h" +#include "sp-anchor.h" +#include "sp-clippath.h" +#include "sp-image.h" +#include "sp-item.h" +#include "sp-mask.h" +// #include "verbs.h" +#include "message-stack.h" +// #include "inkscape.h" +#include "ui/dialog/dialog-manager.h" +// #include "../xml/repr.h" #include <gdk/gdkkeysyms.h> #include <gtk/gtk.h> @@ -296,9 +307,9 @@ void sp_ui_new_view_preview() void sp_ui_close_view(GtkWidget */*widget*/) { - SPDesktop *dt = SP_ACTIVE_DESKTOP; + SPDesktop *dt = SP_ACTIVE_DESKTOP; - if (dt == NULL) { + if (dt == NULL) { return; } @@ -329,14 +340,14 @@ sp_ui_close_all(void) /* Iterate through all the windows, destroying each in the order they become active */ while (SP_ACTIVE_DESKTOP) { - SPDesktop *dt = SP_ACTIVE_DESKTOP; - if (dt->shutdown()) { + SPDesktop *dt = SP_ACTIVE_DESKTOP; + if (dt->shutdown()) { /* The user canceled the operation, so end doing the close */ return FALSE; } - // Shutdown can proceed; use the stored reference to the desktop here instead of the current SP_ACTIVE_DESKTOP, - // because the user might have changed the focus in the meantime (see bug #381357 on Launchpad) - dt->destroyWidget(); + // Shutdown can proceed; use the stored reference to the desktop here instead of the current SP_ACTIVE_DESKTOP, + // because the user might have changed the focus in the meantime (see bug #381357 on Launchpad) + dt->destroyWidget(); } return TRUE; @@ -353,7 +364,7 @@ static void sp_ui_menu_activate(void */*object*/, SPAction *action) { if (!temporarily_block_actions) { - sp_action_perform(action, NULL); + sp_action_perform(action, NULL); } } @@ -481,8 +492,7 @@ sp_ui_dialog_title_string(Inkscape::Verb *verb, gchar *c) * */ -static GtkWidget * -sp_ui_menu_append_item_from_verb(GtkMenu *menu, Inkscape::Verb *verb, Inkscape::UI::View::View *view, bool radio = false, GSList *group = NULL) +static GtkWidget *sp_ui_menu_append_item_from_verb(GtkMenu *menu, Inkscape::Verb *verb, Inkscape::UI::View::View *view, bool radio, GSList *group) { SPAction *action; GtkWidget *item; @@ -503,18 +513,18 @@ sp_ui_menu_append_item_from_verb(GtkMenu *menu, Inkscape::Verb *verb, Inkscape:: GtkWidget *const hb = gtk_hbox_new(FALSE, 16); GtkWidget *const name_lbl = gtk_label_new(""); gtk_label_set_markup_with_mnemonic(GTK_LABEL(name_lbl), action->name); - gtk_misc_set_alignment((GtkMisc *) name_lbl, 0.0, 0.5); - gtk_box_pack_start((GtkBox *) hb, name_lbl, TRUE, TRUE, 0); + gtk_misc_set_alignment(reinterpret_cast<GtkMisc *>(name_lbl), 0.0, 0.5); + gtk_box_pack_start(reinterpret_cast<GtkBox *>(hb), name_lbl, TRUE, TRUE, 0); GtkWidget *const accel_lbl = gtk_label_new(c); - gtk_misc_set_alignment((GtkMisc *) accel_lbl, 1.0, 0.5); - gtk_box_pack_end((GtkBox *) hb, accel_lbl, FALSE, FALSE, 0); + gtk_misc_set_alignment(reinterpret_cast<GtkMisc *>(accel_lbl), 1.0, 0.5); + gtk_box_pack_end(reinterpret_cast<GtkBox *>(hb), accel_lbl, FALSE, FALSE, 0); gtk_widget_show_all(hb); if (radio) { item = gtk_radio_menu_item_new (group); } else { item = gtk_image_menu_item_new(); } - gtk_container_add((GtkContainer *) item, hb); + gtk_container_add(reinterpret_cast<GtkContainer *>(item), hb); g_free(c); } else { if (radio) { @@ -524,8 +534,8 @@ sp_ui_menu_append_item_from_verb(GtkMenu *menu, Inkscape::Verb *verb, Inkscape:: } GtkWidget *const name_lbl = gtk_label_new(""); gtk_label_set_markup_with_mnemonic(GTK_LABEL(name_lbl), action->name); - gtk_misc_set_alignment((GtkMisc *) name_lbl, 0.0, 0.5); - gtk_container_add((GtkContainer *) item, name_lbl); + gtk_misc_set_alignment(reinterpret_cast<GtkMisc *>(name_lbl), 0.0, 0.5); + gtk_container_add(reinterpret_cast<GtkContainer *>(item), name_lbl); } action->signal_set_sensitive.connect( @@ -929,8 +939,8 @@ void sp_ui_build_dyn_menus(Inkscape::XML::Node *menus, GtkWidget *menu, Inkscape gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE); } if (verb->get_code() != SP_VERB_NONE) { - SPAction *action = verb->get_action(view); - g_signal_connect( G_OBJECT(item), "expose_event", (GCallback) update_view_menu, (void *) action); + SPAction *action = verb->get_action(view); + g_signal_connect( G_OBJECT(item), "expose_event", (GCallback) update_view_menu, (void *) action); } } else { sp_ui_menu_append_item_from_verb(GTK_MENU(menu), verb, view); @@ -1016,87 +1026,6 @@ GtkWidget *sp_ui_main_menubar(Inkscape::UI::View::View *view) return mbar; } -static void leave_group(GtkMenuItem *, SPDesktop *desktop) { - desktop->setCurrentLayer(desktop->currentLayer()->parent); -} - -static void enter_group(GtkMenuItem *mi, SPDesktop *desktop) { - desktop->setCurrentLayer(reinterpret_cast<SPObject *>(g_object_get_data(G_OBJECT(mi), "group"))); - sp_desktop_selection(desktop)->clear(); -} - -GtkWidget * -sp_ui_context_menu(Inkscape::UI::View::View *view, SPItem *item) -{ - GtkWidget *m; - SPDesktop *dt; - - dt = static_cast<SPDesktop*>(view); - - m = gtk_menu_new(); - - /* Undo and Redo */ - sp_ui_menu_append_item_from_verb(GTK_MENU(m), Inkscape::Verb::get(SP_VERB_EDIT_UNDO), view); - sp_ui_menu_append_item_from_verb(GTK_MENU(m), Inkscape::Verb::get(SP_VERB_EDIT_REDO), view); - - /* Separator */ - sp_ui_menu_append_item(GTK_MENU(m), NULL, NULL, NULL, NULL, NULL, NULL); - - sp_ui_menu_append_item_from_verb(GTK_MENU(m), Inkscape::Verb::get(SP_VERB_EDIT_CUT), view); - sp_ui_menu_append_item_from_verb(GTK_MENU(m), Inkscape::Verb::get(SP_VERB_EDIT_COPY), view); - sp_ui_menu_append_item_from_verb(GTK_MENU(m), Inkscape::Verb::get(SP_VERB_EDIT_PASTE), view); - - /* Separator */ - sp_ui_menu_append_item(GTK_MENU(m), NULL, NULL, NULL, NULL, NULL, NULL); - - sp_ui_menu_append_item_from_verb(GTK_MENU(m), Inkscape::Verb::get(SP_VERB_EDIT_DUPLICATE), view); - sp_ui_menu_append_item_from_verb(GTK_MENU(m), Inkscape::Verb::get(SP_VERB_EDIT_DELETE), view); - - /* Item menu */ - if (item) { - sp_ui_menu_append_item(GTK_MENU(m), NULL, NULL, NULL, NULL, NULL, NULL); - sp_object_menu((SPObject *) item, dt, GTK_MENU(m)); - } - - /* layer menu */ - SPGroup *group=NULL; - if (item) { - if (SP_IS_GROUP(item)) { - group = SP_GROUP(item); - } else if ( item != dt->currentRoot() && SP_IS_GROUP(item->parent) ) { - group = SP_GROUP(item->parent); - } - } - - if (( group && group != dt->currentLayer() ) || - ( dt->currentLayer() != dt->currentRoot() && dt->currentLayer()->parent != dt->currentRoot() ) ) { - /* Separator */ - sp_ui_menu_append_item(GTK_MENU(m), NULL, NULL, NULL, NULL, NULL, NULL); - } - - if ( group && group != dt->currentLayer() ) { - /* TRANSLATORS: #%s is the id of the group e.g. <g id="#g7">, not a number. */ - gchar *label=g_strdup_printf(_("Enter group #%s"), group->getId()); - GtkWidget *w = gtk_menu_item_new_with_label(label); - g_free(label); - g_object_set_data(G_OBJECT(w), "group", group); - g_signal_connect(G_OBJECT(w), "activate", GCallback(enter_group), dt); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - } - - if ( dt->currentLayer() != dt->currentRoot() ) { - if ( dt->currentLayer()->parent != dt->currentRoot() ) { - GtkWidget *w = gtk_menu_item_new_with_label(_("Go to parent")); - g_signal_connect(G_OBJECT(w), "activate", GCallback(leave_group), dt); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - - } - } - - return m; -} /* Drag and Drop */ void @@ -1455,9 +1384,9 @@ sp_ui_drag_data_received(GtkWidget *widget, gchar *filename = g_build_filename( g_get_tmp_dir(), "inkscape-dnd-import", NULL ); g_file_set_contents(filename, - reinterpret_cast<gchar const *>(gtk_selection_data_get_data (data)), - gtk_selection_data_get_length (data), - NULL); + reinterpret_cast<gchar const *>(gtk_selection_data_get_data (data)), + gtk_selection_data_get_length (data), + NULL); file_import(doc, filename, ext); g_free(filename); @@ -1629,6 +1558,659 @@ void injectRenamedIcons() } +void ContextMenu::EnterGroup(Gtk::MenuItem* mi) +{ + _desktop->setCurrentLayer(reinterpret_cast<SPObject *>(mi->get_data("group"))); + _desktop->selection->clear(); +} + +void ContextMenu::LeaveGroup(void) +{ + _desktop->setCurrentLayer(_desktop->currentLayer()->parent); +} + +ContextMenu::ContextMenu(Inkscape::UI::View::View *view, SPItem *item) : + _item(item), + separators(), + MIGroup(), + MIParent(_("Go to parent")) +{ +// g_message("ContextMenu"); + _object = static_cast<SPObject *>(item); + _desktop = static_cast<SPDesktop*>(view); + + /* Undo and Redo */ + AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_UNDO), view); + AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_REDO), view); + + AddSeparator(); + + AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_CUT), view); + AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_COPY), view); + AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_PASTE), view); + + AddSeparator(); + + AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_DUPLICATE), view); + AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_DELETE), view); + + /* Item menu */ + if (item!=NULL) { + AddSeparator(); + MakeObjectMenu(); + } + + /* layer menu */ + SPGroup *group=NULL; + if (item) { + if (SP_IS_GROUP(item)) { + group = SP_GROUP(item); + } else if ( item != _desktop->currentRoot() && SP_IS_GROUP(item->parent) ) { + group = SP_GROUP(item->parent); + } + } + + if (( group && group != _desktop->currentLayer() ) || + ( _desktop->currentLayer() != _desktop->currentRoot() && _desktop->currentLayer()->parent != _desktop->currentRoot() ) ) { + AddSeparator(); + } + + if ( group && group != _desktop->currentLayer() ) { + /* TRANSLATORS: #%1 is the id of the group e.g. <g id="#g7">, not a number. */ + MIGroup.set_label (Glib::ustring::compose(_("Enter group #%1"), group->getId())); + MIGroup.set_data("group", group); + MIGroup.signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &ContextMenu::EnterGroup),&MIGroup)); + MIGroup.show(); + append(MIGroup); + } + + if ( _desktop->currentLayer() != _desktop->currentRoot() ) { + if ( _desktop->currentLayer()->parent != _desktop->currentRoot() ) { + MIParent.signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::LeaveGroup)); + MIParent.show(); + append(MIParent); + } + } +} + +ContextMenu::~ContextMenu(void) +{ +// g_message("~ContextMenu"); +} + +Gtk::SeparatorMenuItem* ContextMenu::AddSeparator(void) +{ + Gtk::SeparatorMenuItem* sep = new Gtk::SeparatorMenuItem(); + sep->show(); + append(*sep); + separators.push_back(sep); + return sep; +} + +void ContextMenu::AppendItemFromVerb(Inkscape::Verb *verb, Inkscape::UI::View::View *view)//, bool radio, GSList *group) +{ + SPAction *action; + + if (verb->get_code() == SP_VERB_NONE) { + Gtk::MenuItem *item = AddSeparator(); + item->show(); + append(*item); + } else { + action = verb->get_action(view); + if (!action) + { + return; + } + + Gtk::ImageMenuItem *item = NULL; + unsigned int shortcut = sp_shortcut_get_primary(verb); + if (shortcut!=GDK_VoidSymbol) { + gchar* c = sp_shortcut_get_label(shortcut); + Gtk::HBox *const hb = new Gtk::HBox (FALSE, 16); + Gtk::Label *const name_lbl = new Gtk::Label(action->name, true); + name_lbl->set_alignment(0.0, 0.5); + hb->pack_start(*name_lbl, TRUE, TRUE, 0); + Gtk::Label *const accel_lbl = new Gtk::Label(c); + accel_lbl->set_alignment(1.0, 0.5); + hb->pack_end(*accel_lbl, FALSE, FALSE, 0); + hb->show_all(); + // if (radio) { + // item = gtk_radio_menu_item_new (group); + // } else { + item = new Gtk::ImageMenuItem(); + // } + item->add(*hb); + g_free(c); + } else { + // if (radio) { + // item = gtk_radio_menu_item_new (group); + // } else { + item = new Gtk::ImageMenuItem(); + // } + Gtk::Label *const name_lbl = new Gtk::Label(action->name, true); + name_lbl->set_alignment(0.0, 0.5); + item->add(*name_lbl); + } + + action->signal_set_sensitive.connect(sigc::mem_fun(*this, &ContextMenu::set_sensitive)); + action->signal_set_name.connect(sigc::mem_fun(*item, &ContextMenu::set_name)); + + if (!action->sensitive) { + item->set_sensitive(FALSE); + } + + if (action->image) { + sp_ui_menuitem_add_icon((GtkWidget*)item->gobj(), action->image); + } + item->set_events(Gdk::KEY_PRESS_MASK); + item->set_data("view", (gpointer) view); + item->signal_activate().connect(sigc::bind(sigc::ptr_fun(sp_ui_menu_activate),item,action)); + item->signal_select().connect(sigc::bind(sigc::ptr_fun(sp_ui_menu_select_action),item,action)); + item->signal_deselect().connect(sigc::bind(sigc::ptr_fun(sp_ui_menu_deselect_action),item,action)); + item->show(); + append(*item); + } +} + +void ContextMenu::MakeObjectMenu(void) +{ + GObjectClass *klass = G_OBJECT_GET_CLASS(_object); //to deduce the object's type from its class + GType type = G_TYPE_FROM_CLASS(klass); + + if (type | SP_TYPE_ITEM) + { + MakeItemMenu (); + } + if (type == SP_TYPE_GROUP) + { + MakeGroupMenu(); + } + if (type == SP_TYPE_ANCHOR) + { + MakeAnchorMenu(); + } + if (type == SP_TYPE_IMAGE) + { + MakeImageMenu(); + } + if (type == SP_TYPE_SHAPE) + { + MakeShapeMenu(); + } + if (type == SP_TYPE_TEXT) + { + MakeTextMenu(); + } +} + +void ContextMenu::MakeItemMenu (void) +{ + Gtk::MenuItem* mi; + + /* Item dialog */ + mi = new Gtk::MenuItem(_("_Object Properties..."),1); + mi->set_data("desktop", _desktop); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ItemProperties)); + mi->show(); + append(*mi); + + AddSeparator(); + + /* Select item */ + mi = new Gtk::MenuItem(_("_Select This"),1); + if (_desktop->selection->includes(_item)) { + mi->set_sensitive(FALSE); + } else { + mi->set_data("desktop", _desktop); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ItemSelectThis)); + } + mi->show(); + append(*mi); + + /* Select same fill and stroke */ + mi = new Gtk::MenuItem(_("_Select Same Fill and Stroke"),1); + if (_desktop->selection->isEmpty()) { + mi->set_sensitive(FALSE); + } else { + mi->set_data("desktop", _desktop); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SelectSameFillStroke)); + } + mi->set_sensitive(!SP_IS_ANCHOR(_item)); + mi->show(); + append(*mi); + + /* Create link */ + mi = new Gtk::MenuItem(_("_Create Link"),1); + mi->set_data("desktop", _desktop); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ItemCreateLink)); + mi->set_sensitive(!SP_IS_ANCHOR(_item)); + mi->show(); + append(*mi); + + bool ClipRefOK=false; + bool MaskRefOK=false; + if (_item){ + if (_item->clip_ref){ + if (_item->clip_ref->getObject()){ + ClipRefOK=true; + } + } + } + if (_item){ + if (_item->mask_ref){ + if (_item->mask_ref->getObject()){ + MaskRefOK=true; + } + } + } + /* Set mask */ + mi = new Gtk::MenuItem(_("Set Mask"),1); + mi->set_data("desktop", _desktop); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SetMask)); + if (ClipRefOK || MaskRefOK) { + mi->set_sensitive(FALSE); + } else { + mi->set_sensitive(TRUE); + } + mi->show(); + append(*mi); + + /* Release mask */ + mi = new Gtk::MenuItem(_("Release Mask"),1); + mi->set_data("desktop", _desktop); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ReleaseMask)); + if (MaskRefOK) { + mi->set_sensitive(TRUE); + } else { + mi->set_sensitive(FALSE); + } + mi->show(); + append(*mi); + + /* Set Clip */ + mi = new Gtk::MenuItem(_("Set _Clip"),1); + mi->set_data("desktop", _desktop); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SetClip)); + if (ClipRefOK || MaskRefOK) { + mi->set_sensitive(FALSE); + } else { + mi->set_sensitive(TRUE); + } + mi->show(); + append(*mi); + + /* Release Clip */ + mi = new Gtk::MenuItem(_("Release C_lip"),1); + mi->set_data("desktop", _desktop); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ReleaseClip)); + if (ClipRefOK) { + mi->set_sensitive(TRUE); + } else { + mi->set_sensitive(FALSE); + } + mi->show(); + append(*mi); +} + +void ContextMenu::SelectSameFillStroke(void) +{ + sp_select_same_fill_stroke_style(_desktop, true, true, true); +} + +void ContextMenu::ItemProperties(void) +{ + _desktop->selection->set(_item); + _desktop->_dlg_mgr->showDialog("ObjectProperties"); +} + +void ContextMenu::ItemSelectThis(void) +{ + _desktop->selection->set(_item); +} + +void ContextMenu::ItemCreateLink(void) +{ + Inkscape::XML::Document *xml_doc = _desktop->doc()->getReprDoc(); + Inkscape::XML::Node *repr = xml_doc->createElement("svg:a"); + _item->parent->getRepr()->addChild(repr, _item->getRepr()); + SPObject *object = _item->document->getObjectByRepr(repr); + g_return_if_fail(SP_IS_ANCHOR(object)); + + const char *id = _item->getRepr()->attribute("id"); + Inkscape::XML::Node *child = _item->getRepr()->duplicate(xml_doc); + _item->deleteObject(false); + repr->addChild(child, NULL); + child->setAttribute("id", id); + + Inkscape::GC::release(repr); + Inkscape::GC::release(child); + + DocumentUndo::done(object->document, SP_VERB_NONE, _("Create link")); + + _desktop->selection->set(SP_ITEM(object)); + _desktop->_dlg_mgr->showDialog("ObjectAttributes"); +} + +void ContextMenu::SetMask(void) +{ + sp_selection_set_mask(_desktop, false, false); +} + +void ContextMenu::ReleaseMask(void) +{ + sp_selection_unset_mask(_desktop, false); +} + + +void ContextMenu::SetClip(void) +{ + sp_selection_set_mask(_desktop, true, false); +} + + +void ContextMenu::ReleaseClip(void) +{ + sp_selection_unset_mask(_desktop, true); +} + +void ContextMenu::MakeGroupMenu(void) +{ + /* "Ungroup" */ + Gtk::MenuItem* mi = new Gtk::MenuItem(_("_Ungroup"),1); + mi->set_data("desktop", _desktop); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ActivateUngroup)); + mi->show(); + append(*mi); +} + +void ContextMenu::ActivateUngroup(void) +{ + GSList *children = NULL; + + sp_item_group_ungroup(static_cast<SPGroup*>(_item), &children); + _desktop->selection->setList(children); + g_slist_free(children); +} + +void ContextMenu::MakeAnchorMenu(void) +{ + Gtk::MenuItem* mi; + + /* Link dialog */ + mi = new Gtk::MenuItem(_("Link _Properties..."),1); + mi->set_data("desktop", _desktop); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::AnchorLinkProperties)); + mi->show(); + append(*mi); + + /* Select item */ + mi = new Gtk::MenuItem(_("_Follow Link"),1); + mi->set_data("desktop", _desktop); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::AnchorLinkFollow)); + mi->show(); + append(*mi); + + /* Reset transformations */ + mi = new Gtk::MenuItem(_("_Remove Link"),1); + mi->set_data("desktop", _desktop); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::AnchorLinkRemove)); + mi->show(); + append(*mi); +} + +void ContextMenu::AnchorLinkProperties(void) +{ + _desktop->_dlg_mgr->showDialog("ObjectAttributes"); +} + +void ContextMenu::AnchorLinkFollow(void) +{ + /* shell out to an external browser here */ +} + +void ContextMenu::AnchorLinkRemove(void) +{ + GSList *children = NULL; + sp_item_group_ungroup(static_cast<SPAnchor*>(_item), &children); + g_slist_free(children); +} + +void ContextMenu::MakeImageMenu (void) +{ + Gtk::MenuItem* mi; + Inkscape::XML::Node *ir = _object->getRepr(); + const gchar *href = ir->attribute("xlink:href"); + + /* Image properties */ + mi = new Gtk::MenuItem(_("Image _Properties..."),1); + mi->set_data("desktop", _desktop); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ImageProperties)); + mi->show(); + append(*mi); + + /* Edit externally */ + mi = new Gtk::MenuItem(_("Edit Externally..."),1); + mi->set_data("desktop", _desktop); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ImageEdit)); + mi->show(); + append(*mi); + if ( (!href) || ((strncmp(href, "data:", 5) == 0)) ) { + mi->set_sensitive( FALSE ); + } + + /* Embed image */ + if (Inkscape::Verb::getbyid( "org.ekips.filter.embedselectedimages" )) { + mi = new Gtk::MenuItem(C_("Context menu", "Embed Image")); + mi->set_data("desktop", _desktop); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ImageEmbed)); + mi->show(); + append(*mi); + if ( (!href) || ((strncmp(href, "data:", 5) == 0)) ) { + mi->set_sensitive( FALSE ); + } + } + + /* Extract image */ + if (Inkscape::Verb::getbyid( "org.ekips.filter.extractimage" )) { + mi = new Gtk::MenuItem(C_("Context menu", "Extract Image...")); + mi->set_data("desktop", _desktop); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ImageExtract)); + mi->show(); + append(*mi); + if ( (!href) || ((strncmp(href, "data:", 5) == 0)) ) { + mi->set_sensitive( FALSE ); + } + } +} + +void ContextMenu::ImageProperties(void) +{ + _desktop->_dlg_mgr->showDialog("ObjectAttributes"); +} + +Glib::ustring ContextMenu::getImageEditorName() { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Glib::ustring value; + Glib::ustring choices = prefs->getString("/options/bitmapeditor/value"); + if (!choices.empty()) { + value = choices; + } + else { + value = "gimp"; + } + return value; +} + +/* Edit Externally entry */ +void ContextMenu::ImageEdit(void) +{ + if (_desktop->selection->isEmpty()) { + _desktop->selection->set(_item); + } + + GSList const *selected = _desktop->selection->itemList(); + + GError* errThing = 0; + Glib::ustring cmdline = getImageEditorName(); + Glib::ustring name; + Glib::ustring fullname; + +#ifdef WIN32 + // g_spawn_command_line_sync parsing is done according to Unix shell rules, + // not Windows command interpreter rules. Thus we need to enclose the + // executable path with single quotes. + int index = cmdline.find(".exe"); + if ( index < 0 ) index = cmdline.find(".bat"); + if ( index < 0 ) index = cmdline.find(".com"); + if ( index >= 0 ) { + Glib::ustring editorBin = cmdline.substr(0, index + 4).c_str(); + Glib::ustring args = cmdline.substr(index + 4, cmdline.length()).c_str(); + editorBin.insert(0, "'"); + editorBin.append("'"); + cmdline = editorBin; + cmdline.append(args); + } else { + // Enclose the whole command line if no executable path can be extracted. + cmdline.insert(0, "'"); + cmdline.append("'"); + } +#endif + + for (GSList const *iter = selected; iter != NULL; iter = iter->next) { + Inkscape::XML::Node *ir = SP_ITEM(iter->data)->getRepr(); + const gchar *href = ir->attribute("xlink:href"); + + if (strncmp (href,"file:",5) == 0) { + // URI to filename conversion + name = g_filename_from_uri(href, NULL, NULL); + } else { + name.append(href); + } + + if (Glib::path_is_absolute(name)) { + fullname = name; + } else if (SP_ACTIVE_DOCUMENT->getBase()) { + fullname = Glib::build_filename(SP_ACTIVE_DOCUMENT->getBase(), name); + } else { + fullname = Glib::build_filename(Glib::get_current_dir(), name); + } + + cmdline.append(" '"); + cmdline.append(fullname.c_str()); + cmdline.append("'"); + } + + //g_warning("##Command line: %s\n", cmdline.c_str()); + + g_spawn_command_line_async(cmdline.c_str(), &errThing); + + if ( errThing ) { + g_warning("Problem launching editor (%d). %s", errThing->code, errThing->message); + (_desktop->messageStack())->flash(Inkscape::ERROR_MESSAGE, errThing->message); + g_error_free(errThing); + errThing = 0; + } +} + +/* Embed Image entry */ +void ContextMenu::ImageEmbed(void) +{ + if (_desktop->selection->isEmpty()) { + _desktop->selection->set(_item); + } + + Inkscape::Verb *verb = Inkscape::Verb::getbyid( "org.ekips.filter.embedselectedimages" ); + if (verb) { + SPAction *action = verb->get_action(_desktop); + if (action) { + sp_action_perform(action, NULL); + } + } +} + +/* Extract Image entry */ +void ContextMenu::ImageExtract(void) +{ + if (_desktop->selection->isEmpty()) { + _desktop->selection->set(_item); + } + + Inkscape::Verb *verb = Inkscape::Verb::getbyid( "org.ekips.filter.extractimage" ); + if (verb) { + SPAction *action = verb->get_action(_desktop); + if (action) { + sp_action_perform(action, NULL); + } + } +} + +void ContextMenu::MakeShapeMenu (void) +{ + Gtk::MenuItem* mi; + + /* Item dialog */ + mi = new Gtk::MenuItem(_("_Fill and Stroke..."),1); + mi->set_data("desktop", _desktop); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::FillSettings)); + mi->show(); + append(*mi); +} + +void ContextMenu::FillSettings(void) +{ + if (_desktop->selection->isEmpty()) { + _desktop->selection->set(_item); + } + + _desktop->_dlg_mgr->showDialog("FillAndStroke"); +} + +void ContextMenu::MakeTextMenu (void) +{ + Gtk::MenuItem* mi; + + /* Fill and Stroke dialog */ + mi = new Gtk::MenuItem(_("_Fill and Stroke..."),1); + mi->set_data("desktop", _desktop); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::FillSettings)); + mi->show(); + append(*mi); + + /* Edit Text dialog */ + mi = new Gtk::MenuItem(_("_Text and Font..."),1); + mi->set_data("desktop", _desktop); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::TextSettings)); + mi->show(); + append(*mi); + + /* Spellcheck dialog */ + mi = new Gtk::MenuItem(_("Check Spellin_g..."),1); + mi->set_data("desktop", _desktop); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SpellcheckSettings)); + mi->show(); + append(*mi); +} + +/* Edit Text entry */ +void ContextMenu::TextSettings (void) +{ + if (_desktop->selection->isEmpty()) { + _desktop->selection->set(_item); + } + + _desktop->_dlg_mgr->showDialog("TextFont"); +} + +/* Spellcheck entry */ +void ContextMenu::SpellcheckSettings (void) +{ + if (_desktop->selection->isEmpty()) { + _desktop->selection->set(_item); + } + + _desktop->_dlg_mgr->showDialog("SpellCheck"); +} + /* Local Variables: mode:c++ diff --git a/src/interface.h b/src/interface.h index 2b01a20d7..db98c3ae3 100644 --- a/src/interface.h +++ b/src/interface.h @@ -8,7 +8,9 @@ * Lauris Kaplinski <lauris@kaplinski.com> * Frank Felfe <innerspace@iname.com> * Abhishek Sharma + * Kris De Gussem <Kris.DeGussem@gmail.com> * + * Copyright (C) 2012 Kris De Gussem * Copyright (C) 1999-2002 authors * Copyright (C) 2001-2002 Ximian, Inc. * @@ -16,6 +18,7 @@ */ #include <gtk/gtk.h> +#include <gtkmm/menu.h> #include "sp-item.h" @@ -58,10 +61,7 @@ unsigned int sp_ui_close_all (void); */ GtkWidget *sp_ui_main_menubar (Inkscape::UI::View::View *view); -/** - * - */ -GtkWidget *sp_ui_context_menu (Inkscape::UI::View::View *v, SPItem *item); +static GtkWidget *sp_ui_menu_append_item_from_verb(GtkMenu *menu, Inkscape::Verb *verb, Inkscape::UI::View::View *view, bool radio = false, GSList *group = NULL); /** @@ -82,6 +82,59 @@ void sp_ui_dialog_title_string (Inkscape::Verb * verb, gchar* c); void sp_ui_error_dialog (const gchar * message); bool sp_ui_overwrite_file (const gchar * filename); +class ContextMenu : public Gtk::Menu +{ + public: + ContextMenu(Inkscape::UI::View::View *view, SPItem *item); + ~ContextMenu(void); + private: + SPItem *_item; + SPObject *_object; + SPDesktop *_desktop; + + std::vector<Gtk::SeparatorMenuItem*> separators; + Gtk::MenuItem MIGroup; + Gtk::MenuItem MIParent; + + Gtk::SeparatorMenuItem* AddSeparator(void); + void AppendItemFromVerb(Inkscape::Verb *verb, Inkscape::UI::View::View *view); + void MakeObjectMenu (void); + void MakeItemMenu (void); + void MakeGroupMenu (void); + void MakeAnchorMenu (void); + void MakeImageMenu (void); + void MakeShapeMenu (void); + void MakeTextMenu (void); + + void EnterGroup(Gtk::MenuItem* mi); + void LeaveGroup(void); + void ItemProperties(void); + void ItemSelectThis(void); + void SelectSameFillStroke(void); + void ItemCreateLink(void); + void SetMask(void); + void ReleaseMask(void); + void SetClip(void); + void ReleaseClip(void); + + void ActivateUngroup(void); + + void AnchorLinkProperties(void); + void AnchorLinkFollow(void); + void AnchorLinkRemove(void); + + void ImageProperties(void); + void ImageEdit(void); + Glib::ustring getImageEditorName(); + void ImageEmbed(void); + void ImageExtract(void); + + void FillSettings(void); + + void TextSettings(void); + void SpellcheckSettings(void); +}; + #endif // SEEN_SP_INTERFACE_H /* diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 35840e0c4..85f0899a8 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -1,7 +1,6 @@ set(ui_SRC clipboard.cpp - context-menu.cpp previewholder.cpp uxmanager.cpp @@ -121,7 +120,6 @@ set(ui_SRC # ------- # Headers clipboard.h - context-menu.h icon-names.h previewable.h previewfillable.h diff --git a/src/ui/Makefile_insert b/src/ui/Makefile_insert index eb8966d11..19ecef0fc 100644 --- a/src/ui/Makefile_insert +++ b/src/ui/Makefile_insert @@ -1,8 +1,6 @@ ## Makefile.am fragment sourced by src/Makefile.am. ink_common_sources += \ - ui/context-menu.cpp \ - ui/context-menu.h \ ui/clipboard.cpp \ ui/clipboard.h \ ui/icon-names.h \ diff --git a/src/ui/context-menu.cpp b/src/ui/context-menu.cpp deleted file mode 100644 index ad47da68b..000000000 --- a/src/ui/context-menu.cpp +++ /dev/null @@ -1,715 +0,0 @@ -/* - * Unser-interface related object extension - * - * Authors: - * Lauris Kaplinski <lauris@kaplinski.com> - * Jon A. Cruz <jon@joncruz.org> - * Abhishek Sharma - * - * This code is in public domain - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "ui/dialog/dialog-manager.h" -#include "context-menu.h" -#include "../xml/repr.h" -#include "desktop.h" -#include "document.h" -#include "document-undo.h" -#include "helper/action.h" //sp_action_perform -#include "inkscape.h" -#include "message-stack.h" -#include "preferences.h" -#include "verbs.h" - -#include "selection-chemistry.h" - -using Inkscape::DocumentUndo; - -static void sp_object_type_menu(GType type, SPObject *object, SPDesktop *desktop, GtkMenu *menu); - -/* Append object-specific part to context menu */ - -void sp_object_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu) -{ - GObjectClass *klass; - klass = G_OBJECT_GET_CLASS(object); - while (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_OBJECT)) { - GType type; - type = G_TYPE_FROM_CLASS(klass); - sp_object_type_menu(type, object, desktop, menu); - klass = (GObjectClass*)g_type_class_peek_parent(klass); - } -} - -/* Implementation */ - -#include <gtk/gtk.h> -#include <glibmm/i18n.h> - -#include "selection.h" -#include "selection-chemistry.h" -#include "sp-anchor.h" -#include "sp-clippath.h" -#include "sp-image.h" -#include "sp-mask.h" -#include "sp-path.h" -#include "sp-text.h" -#include "desktop-handles.h" -#include "ui/dialog/object-attributes.h" -#include "ui/dialog/object-properties.h" -#include "ui/dialog/spellcheck.h" - - -static void sp_item_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu); -static void sp_group_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu); -static void sp_anchor_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu); -static void sp_image_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu); -static void sp_shape_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu); -static void sp_text_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu); - -static void sp_object_type_menu(GType type, SPObject *object, SPDesktop *desktop, GtkMenu *menu) -{ - static GHashTable *t2m = NULL; - void (* handler)(SPObject *object, SPDesktop *desktop, GtkMenu *menu); - if (!t2m) { - t2m = g_hash_table_new(NULL, NULL); - g_hash_table_insert(t2m, GUINT_TO_POINTER(SP_TYPE_ITEM), (void*)sp_item_menu); - g_hash_table_insert(t2m, GUINT_TO_POINTER(SP_TYPE_GROUP), (void*)sp_group_menu); - g_hash_table_insert(t2m, GUINT_TO_POINTER(SP_TYPE_ANCHOR), (void*)sp_anchor_menu); - g_hash_table_insert(t2m, GUINT_TO_POINTER(SP_TYPE_IMAGE), (void*)sp_image_menu); - g_hash_table_insert(t2m, GUINT_TO_POINTER(SP_TYPE_SHAPE), (void*)sp_shape_menu); - g_hash_table_insert(t2m, GUINT_TO_POINTER(SP_TYPE_TEXT), (void*)sp_text_menu); - } - handler = (void (*)(SPObject*, SPDesktop*, GtkMenu*))g_hash_table_lookup(t2m, GUINT_TO_POINTER(type)); - if (handler) handler(object, desktop, menu); -} - -/* SPItem */ - -static void sp_item_properties(GtkMenuItem *menuitem, SPItem *item); -static void sp_item_select_this(GtkMenuItem *menuitem, SPItem *item); -static void sp_item_select_same_fill_stroke(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 sp_item_menu(SPObject *object, SPDesktop *desktop, GtkMenu *m) -{ - SPItem *item; - GtkWidget *w; - - item = (SPItem *) object; - - /* Item dialog */ - w = gtk_menu_item_new_with_mnemonic(_("_Object Properties...")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_item_properties), item); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - /* Separator */ - w = gtk_menu_item_new(); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - /* Select item */ - w = gtk_menu_item_new_with_mnemonic(_("_Select This")); - if (sp_desktop_selection(desktop)->includes(item)) { - gtk_widget_set_sensitive(w, FALSE); - } else { - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_item_select_this), item); - } - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - /* Select same fill and stroke */ - w = gtk_menu_item_new_with_mnemonic(_("_Select Same Fill and Stroke")); - if (sp_desktop_selection(desktop)->isEmpty()) { - gtk_widget_set_sensitive(w, FALSE); - } else { - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_item_select_same_fill_stroke), item); - } - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - /* Create link */ - w = gtk_menu_item_new_with_mnemonic(_("_Create Link")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_item_create_link), item); - gtk_widget_set_sensitive(w, !SP_IS_ANCHOR(item)); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - /* Set mask */ - w = gtk_menu_item_new_with_mnemonic(_("Set Mask")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(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_shell_append(GTK_MENU_SHELL(m), w); - /* Release mask */ - w = gtk_menu_item_new_with_mnemonic(_("Release Mask")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(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_shell_append(GTK_MENU_SHELL(m), w); - /* Set Clip */ - w = gtk_menu_item_new_with_mnemonic(_("Set _Clip")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(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_shell_append(GTK_MENU_SHELL(m), w); - /* Release Clip */ - w = gtk_menu_item_new_with_mnemonic(_("Release C_lip")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(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_shell_append(GTK_MENU_SHELL(m), w); - -} - -static void sp_item_properties(GtkMenuItem *menuitem, SPItem *item) -{ - SPDesktop *desktop; - - g_assert(SP_IS_ITEM(item)); - - desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - g_return_if_fail(desktop != NULL); - - sp_desktop_selection(desktop)->set(item); - - // sp_item_dialog(); - desktop->_dlg_mgr->showDialog("ObjectProperties"); -} - - -static void sp_set_mask(GtkMenuItem *menuitem, SPItem *item) -{ - SPDesktop *desktop; - - g_assert(SP_IS_ITEM(item)); - - desktop = (SPDesktop*)g_object_get_data(G_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*)g_object_get_data(G_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*)g_object_get_data(G_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*)g_object_get_data(G_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) -{ - SPDesktop *desktop; - - g_assert(SP_IS_ITEM(item)); - - desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - g_return_if_fail(desktop != NULL); - - sp_desktop_selection(desktop)->set(item); -} - -static void sp_item_select_same_fill_stroke(GtkMenuItem *menuitem, SPItem * /*item*/) -{ - SPDesktop *desktop = static_cast<SPDesktop*>(g_object_get_data(G_OBJECT(menuitem), "desktop")); - g_return_if_fail(desktop != NULL); - - sp_select_same_fill_stroke_style(desktop, true, true, true); -} - - -static void sp_item_create_link(GtkMenuItem *menuitem, SPItem *item) -{ - g_assert(SP_IS_ITEM(item)); - g_assert(!SP_IS_ANCHOR(item)); - - SPDesktop *desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - g_return_if_fail(desktop != NULL); - - Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); - Inkscape::XML::Node *repr = xml_doc->createElement("svg:a"); - item->parent->getRepr()->addChild(repr, item->getRepr()); - SPObject *object = item->document->getObjectByRepr(repr); - g_return_if_fail(SP_IS_ANCHOR(object)); - - const char *id = item->getRepr()->attribute("id"); - Inkscape::XML::Node *child = item->getRepr()->duplicate(xml_doc); - item->deleteObject(false); - repr->addChild(child, NULL); - child->setAttribute("id", id); - - Inkscape::GC::release(repr); - Inkscape::GC::release(child); - - DocumentUndo::done(object->document, SP_VERB_NONE, - _("Create link")); - - sp_desktop_selection(desktop)->set(SP_ITEM(object)); - desktop->_dlg_mgr->showDialog("ObjectAttributes"); -} - -/* SPGroup */ - -static void sp_item_group_ungroup_activate(GtkMenuItem *menuitem, SPGroup *group); - -static void sp_group_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu) -{ - SPItem *item=SP_ITEM(object); - GtkWidget *w; - - /* "Ungroup" */ - w = gtk_menu_item_new_with_mnemonic(_("_Ungroup")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_item_group_ungroup_activate), item); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), w); -} - -static void sp_item_group_ungroup_activate(GtkMenuItem *menuitem, SPGroup *group) -{ - SPDesktop *desktop; - GSList *children; - - g_assert(SP_IS_GROUP(group)); - - desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - g_return_if_fail(desktop != NULL); - - children = NULL; - sp_item_group_ungroup(group, &children); - - sp_desktop_selection(desktop)->setList(children); - g_slist_free(children); -} - -/* SPAnchor */ - -static void sp_anchor_link_properties(GtkMenuItem *menuitem, SPAnchor *anchor); -static void sp_anchor_link_follow(GtkMenuItem *menuitem, SPAnchor *anchor); -static void sp_anchor_link_remove(GtkMenuItem *menuitem, SPAnchor *anchor); - -static void sp_anchor_menu(SPObject *object, SPDesktop *desktop, GtkMenu *m) -{ - SPItem *item; - GtkWidget *w; - - item = (SPItem *) object; - - /* Link dialog */ - w = gtk_menu_item_new_with_mnemonic(_("Link _Properties...")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_anchor_link_properties), item); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - /* Select item */ - w = gtk_menu_item_new_with_mnemonic(_("_Follow Link")); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_anchor_link_follow), item); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - /* Reset transformations */ - w = gtk_menu_item_new_with_mnemonic(_("_Remove Link")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_anchor_link_remove), item); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); -} - -static void sp_anchor_link_properties(GtkMenuItem *menuitem, SPAnchor */*anchor*/) -{ - SPDesktop *desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - g_return_if_fail(desktop != NULL); - desktop->_dlg_mgr->showDialog("ObjectAttributes"); -} - -static void sp_anchor_link_follow(GtkMenuItem */*menuitem*/, SPAnchor *anchor) -{ - g_return_if_fail(anchor != NULL); - g_return_if_fail(SP_IS_ANCHOR(anchor)); - - /* shell out to an external browser here */ -} - -static void sp_anchor_link_remove(GtkMenuItem */*menuitem*/, SPAnchor *anchor) -{ - GSList *children; - - g_return_if_fail(anchor != NULL); - g_return_if_fail(SP_IS_ANCHOR(anchor)); - - children = NULL; - sp_item_group_ungroup(SP_GROUP(anchor), &children); - - g_slist_free(children); -} - -/* Image */ - -static void sp_image_image_properties(GtkMenuItem *menuitem, SPAnchor *anchor); -static void sp_image_image_edit(GtkMenuItem *menuitem, SPItem *item); -static void sp_image_image_embed(GtkMenuItem *menuitem, SPItem *item); -static void sp_image_image_extract(GtkMenuItem *menuitem, SPItem *item); - -static void sp_image_menu(SPObject *object, SPDesktop *desktop, GtkMenu *m) -{ - SPItem *item = SP_ITEM(object); - GtkWidget *w; - Inkscape::XML::Node *ir = object->getRepr(); - const gchar *href = ir->attribute("xlink:href"); - - /* Image properties */ - w = gtk_menu_item_new_with_mnemonic(_("Image _Properties...")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_image_image_properties), item); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - - /* Edit externally */ - w = gtk_menu_item_new_with_mnemonic(_("Edit Externally...")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_image_image_edit), item); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - if ( (!href) || ((strncmp(href, "data:", 5) == 0)) ) { - gtk_widget_set_sensitive( w, FALSE ); - } - - /* Embed image */ - if (Inkscape::Verb::getbyid( "org.ekips.filter.embedselectedimages" )) { - w = gtk_menu_item_new_with_mnemonic(C_("Context menu", "Embed Image")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_image_image_embed), item); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - if ( (!href) || ((strncmp(href, "data:", 5) == 0)) ) { - gtk_widget_set_sensitive( w, FALSE ); - } - } - - /* Extract image */ - if (Inkscape::Verb::getbyid( "org.ekips.filter.extractimage" )) { - w = gtk_menu_item_new_with_mnemonic(C_("Context menu", "Extract Image...")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_image_image_extract), item); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - if ( (!href) || ((strncmp(href, "data:", 5) != 0)) ) { - gtk_widget_set_sensitive( w, FALSE ); - } - } -} - -/* Image Properties entry */ -static void sp_image_image_properties(GtkMenuItem *menuitem, SPAnchor */*anchor*/) -{ - SPDesktop *desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - g_return_if_fail(desktop != NULL); - desktop->_dlg_mgr->showDialog("ObjectAttributes"); -} - -static gchar* getImageEditorName() { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gchar* value = 0; - Glib::ustring choices = prefs->getString("/options/bitmapeditor/value"); - if (!choices.empty()) { - value = g_strdup(choices.c_str()); - } - if (!value) { - value = g_strdup("gimp"); - } - return value; -} - -/* Edit Externally entry */ -static void sp_image_image_edit(GtkMenuItem *menuitem, SPItem *item) -{ - SPDesktop *desktop = NULL; - - g_assert(SP_IS_ITEM(item)); - - desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - g_return_if_fail(desktop != NULL); - - if (sp_desktop_selection(desktop)->isEmpty()) { - sp_desktop_selection(desktop)->set(item); - } - - GSList const *selected = sp_desktop_selection(desktop)->itemList(); - - GError* errThing = 0; - Glib::ustring cmdline = getImageEditorName(); - Glib::ustring name; - Glib::ustring fullname; - -#ifdef WIN32 - // g_spawn_command_line_sync parsing is done according to Unix shell rules, - // not Windows command interpreter rules. Thus we need to enclose the - // executable path with sigle quotes. - int index = cmdline.find(".exe"); - if ( index < 0 ) index = cmdline.find(".bat"); - if ( index < 0 ) index = cmdline.find(".com"); - if ( index >= 0 ) { - Glib::ustring editorBin = cmdline.substr(0, index + 4).c_str(); - Glib::ustring args = cmdline.substr(index + 4, cmdline.length()).c_str(); - editorBin.insert(0, "'"); - editorBin.append("'"); - cmdline = editorBin; - cmdline.append(args); - } else { - // Enclose the whole command line if no executable path can be extracted. - cmdline.insert(0, "'"); - cmdline.append("'"); - } -#endif - - for (GSList const *iter = selected; iter != NULL; iter = iter->next) { - Inkscape::XML::Node *ir = SP_ITEM(iter->data)->getRepr(); - const gchar *href = ir->attribute("xlink:href"); - - if (strncmp (href,"file:",5) == 0) { - // URI to filename conversion - name = g_filename_from_uri(href, NULL, NULL); - } else { - name.append(href); - } - - if (Glib::path_is_absolute(name)) { - fullname = name; - } else if (SP_ACTIVE_DOCUMENT->getBase()) { - fullname = Glib::build_filename(SP_ACTIVE_DOCUMENT->getBase(), name); - } else { - fullname = Glib::build_filename(Glib::get_current_dir(), name); - } - - cmdline.append(" '"); - cmdline.append(fullname.c_str()); - cmdline.append("'"); - } - - //g_warning("##Command line: %s\n", cmdline.c_str()); - - g_spawn_command_line_async(cmdline.c_str(), - &errThing); - - if ( errThing ) { - g_warning("Problem launching editor (%d). %s", errThing->code, errThing->message); - SPDesktop *desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, errThing->message); - g_error_free(errThing); - errThing = 0; - } -} - -/* Embed Image entry */ -static void sp_image_image_embed(GtkMenuItem *menuitem, SPItem *item) -{ - SPDesktop *desktop; - - g_assert(SP_IS_ITEM(item)); - - desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - g_return_if_fail(desktop != NULL); - - if (sp_desktop_selection(desktop)->isEmpty()) { - sp_desktop_selection(desktop)->set(item); - } - - Inkscape::Verb *verb = Inkscape::Verb::getbyid( "org.ekips.filter.embedselectedimages" ); - if (verb) { - SPAction *action = verb->get_action(desktop); - if (action) { - sp_action_perform(action, NULL); - } - } -} - -/* Extract Image entry */ -static void sp_image_image_extract(GtkMenuItem *menuitem, SPItem *item) -{ - SPDesktop *desktop; - - g_assert(SP_IS_ITEM(item)); - - desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - g_return_if_fail(desktop != NULL); - - if (sp_desktop_selection(desktop)->isEmpty()) { - sp_desktop_selection(desktop)->set(item); - } - - Inkscape::Verb *verb = Inkscape::Verb::getbyid( "org.ekips.filter.extractimage" ); - if (verb) { - SPAction *action = verb->get_action(desktop); - if (action) { - sp_action_perform(action, NULL); - } - } -} - -/* Fill and Stroke entry */ -static void sp_fill_settings(GtkMenuItem *menuitem, SPItem *item) -{ - SPDesktop *desktop; - - g_assert(SP_IS_ITEM(item)); - - desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - g_return_if_fail(desktop != NULL); - - if (sp_desktop_selection(desktop)->isEmpty()) { - sp_desktop_selection(desktop)->set(item); - } - - desktop->_dlg_mgr->showDialog("FillAndStroke"); -} - -/* SPShape */ -static void sp_shape_menu(SPObject *object, SPDesktop *desktop, GtkMenu *m) -{ - SPItem *item; - GtkWidget *w; - - item = (SPItem *) object; - - /* Item dialog */ - w = gtk_menu_item_new_with_mnemonic(_("_Fill and Stroke...")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_fill_settings), item); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); -} - -/* Edit Text entry */ -static void sp_text_settings(GtkMenuItem *menuitem, SPItem *item) -{ - SPDesktop *desktop; - - g_assert(SP_IS_ITEM(item)); - - desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - g_return_if_fail(desktop != NULL); - - if (sp_desktop_selection(desktop)->isEmpty()) { - sp_desktop_selection(desktop)->set(item); - } - - desktop->_dlg_mgr->showDialog("TextFont"); -} - -/* Spellcheck entry */ -static void sp_spellcheck_settings(GtkMenuItem *menuitem, SPItem *item) -{ - SPDesktop *desktop; - - g_assert(SP_IS_ITEM(item)); - - desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - g_return_if_fail(desktop != NULL); - - if (sp_desktop_selection(desktop)->isEmpty()) { - sp_desktop_selection(desktop)->set(item); - } - - desktop->_dlg_mgr->showDialog("SpellCheck"); -} - -/* SPText */ -static void sp_text_menu(SPObject *object, SPDesktop *desktop, GtkMenu *m) -{ - SPItem *item; - GtkWidget *w; - - item = (SPItem *) object; - - /* Fill and Stroke dialog */ - w = gtk_menu_item_new_with_mnemonic(_("_Fill and Stroke...")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_fill_settings), item); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - - /* Edit Text dialog */ - w = gtk_menu_item_new_with_mnemonic(_("_Text and Font...")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_text_settings), item); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - - /* Spellcheck dialog */ - w = gtk_menu_item_new_with_mnemonic(_("Check Spellin_g...")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_spellcheck_settings), item); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); -} -/* - 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/context-menu.h b/src/ui/context-menu.h deleted file mode 100644 index 39753f93f..000000000 --- a/src/ui/context-menu.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef SEEN_CONTEXT_MENU_H -#define SEEN_CONTEXT_MENU_H - -/* - * Unser-interface related object extension - * - * Authors: - * Lauris Kaplinski <lauris@kaplinski.com> - * Abhishek Sharma - * - * This code is in public domain - */ - -#include <gtk/gtk.h> - -#include "sp-object.h" - -class SPDesktop; - -/** - * Append object-specific part to context menu. - */ -void sp_object_menu (SPObject *object, SPDesktop *desktop, GtkMenu *menu); - -#endif - -/* - 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:fileencoding=utf-8:textwidth=99 : |
