Code

First (very limited) version of the 3D box tool; allows for drawing of new boxes...
[inkscape.git] / src / verbs.cpp
index 476170e994e4c94926db73c7dc56e67f37b86f13..04a49f37c4bd3a58d9ad03275d5e548d96a5f974 100644 (file)
 #include "sp-flowtext.h"
 #include "layer-fns.h"
 #include "node-context.h"
+#include "select-context.h"
+#include "seltrans.h"
 #include "gradient-context.h"
+#include "shape-editor.h"
+#include "draw-context.h"
 
 
 /**
@@ -128,12 +132,13 @@ static void show_panel( Inkscape::UI::Widget::Panel &panel, char const *prefs_pa
         Gtk::VBox *mainVBox = dia->get_vbox();
         mainVBox->pack_start(panel);
         dia->show_all_children();
-        dia->present();
         dia->read_geometry();
+        dia->present();
     } else {
-        Gtk::Dialog *dia = dynamic_cast<Gtk::Dialog*>(container);
+        PanelDialog *dia = dynamic_cast<PanelDialog*>(container);
         if ( dia ) {
             //g_message("Found an existing dialog");
+            dia->read_geometry();
             dia->present();
         } else {
             g_message("Failed to find an existing dialog");
@@ -915,28 +920,28 @@ EditVerb::perform(SPAction *action, void *data, void *pdata)
             break;
         case SP_VERB_EDIT_SELECT_ALL:
             if (tools_isactive(dt, TOOLS_NODES)) {
-                sp_nodepath_select_all_from_subpath(SP_NODE_CONTEXT(ec)->nodepath, false);
+                SP_NODE_CONTEXT(ec)->shape_editor->select_all_from_subpath(false);
             } else {
                 sp_edit_select_all();
             }
             break;
         case SP_VERB_EDIT_INVERT:
             if (tools_isactive(dt, TOOLS_NODES)) {
-                sp_nodepath_select_all_from_subpath(SP_NODE_CONTEXT(ec)->nodepath, true);
+                SP_NODE_CONTEXT(ec)->shape_editor->select_all_from_subpath(true);
             } else {
                 sp_edit_invert();
             }
             break;
         case SP_VERB_EDIT_SELECT_ALL_IN_ALL_LAYERS:
             if (tools_isactive(dt, TOOLS_NODES)) {
-                sp_nodepath_select_all(SP_NODE_CONTEXT(ec)->nodepath, false);
+                SP_NODE_CONTEXT(ec)->shape_editor->select_all(false);
             } else {
                 sp_edit_select_all_in_all_layers();
             }
             break;
         case SP_VERB_EDIT_INVERT_IN_ALL_LAYERS:
             if (tools_isactive(dt, TOOLS_NODES)) {
-                sp_nodepath_select_all(SP_NODE_CONTEXT(ec)->nodepath, true);
+                SP_NODE_CONTEXT(ec)->shape_editor->select_all(true);
             } else {
                 sp_edit_invert_in_all_layers();
             }
@@ -944,7 +949,7 @@ EditVerb::perform(SPAction *action, void *data, void *pdata)
 
         case SP_VERB_EDIT_SELECT_NEXT: 
             if (tools_isactive(dt, TOOLS_NODES)) {
-                sp_nodepath_select_next(SP_NODE_CONTEXT(ec)->nodepath);
+                SP_NODE_CONTEXT(ec)->shape_editor->select_next();
             } else if (tools_isactive(dt, TOOLS_GRADIENT)) {
                 sp_gradient_context_select_next (ec);
             } else {
@@ -953,7 +958,7 @@ EditVerb::perform(SPAction *action, void *data, void *pdata)
             break;
         case SP_VERB_EDIT_SELECT_PREV: 
             if (tools_isactive(dt, TOOLS_NODES)) {
-                sp_nodepath_select_prev(SP_NODE_CONTEXT(ec)->nodepath);
+                SP_NODE_CONTEXT(ec)->shape_editor->select_prev();
             } else if (tools_isactive(dt, TOOLS_GRADIENT)) {
                 sp_gradient_context_select_prev (ec);
             } else {
@@ -963,7 +968,7 @@ EditVerb::perform(SPAction *action, void *data, void *pdata)
 
         case SP_VERB_EDIT_DESELECT:
             if (tools_isactive(dt, TOOLS_NODES)) {
-                sp_nodepath_deselect(SP_NODE_CONTEXT(ec)->nodepath);
+                SP_NODE_CONTEXT(ec)->shape_editor->deselect();
             } else {
                 sp_desktop_selection(dt)->clear();
             }
@@ -1053,9 +1058,11 @@ SelectionVerb::perform(SPAction *action, void *data, void *pdata)
             break;
         case SP_VERB_SELECTION_DYNAMIC_OFFSET:
             sp_selected_path_create_offset_object_zero();
+            tools_switch_current(TOOLS_NODES);
             break;
         case SP_VERB_SELECTION_LINKED_OFFSET:
             sp_selected_path_create_updating_offset_object_zero();
+            tools_switch_current(TOOLS_NODES);
             break;
 
         case SP_VERB_SELECTION_OUTLINE:
@@ -1254,7 +1261,17 @@ ObjectVerb::perform( SPAction *action, void *data, void *pdata )
     if (sel->isEmpty())
         return;
 
-    NR::Point const center(sel->bounds().midpoint());
+    NR::Maybe<NR::Rect> bbox = sel->bounds();
+    if (!bbox) {
+        return;
+    }
+    // If the rotation center of the selection is visible, choose it as reference point
+    // for horizontal and vertical flips. Otherwise, take the center of the bounding box.
+    NR::Point center;
+    if (tools_isactive(dt, TOOLS_SELECT) && sel->center() && SP_SELECT_CONTEXT(ec)->_seltrans->centerIsVisible())
+        center = *sel->center();
+    else
+        center = bbox->midpoint();
 
     switch (reinterpret_cast<std::size_t>(data)) {
         case SP_VERB_OBJECT_ROTATE_90_CW:
@@ -1279,8 +1296,23 @@ ObjectVerb::perform( SPAction *action, void *data, void *pdata )
             flowtext_to_text();
             break;
         case SP_VERB_OBJECT_FLIP_HORIZONTAL:
+            // When working with the node tool ...
             if (tools_isactive(dt, TOOLS_NODES)) {
-                sp_nodepath_flip(SP_NODE_CONTEXT(ec)->nodepath, NR::X);
+                Inkscape::NodePath::Node *active_node = Inkscape::NodePath::Path::active_node;
+
+                // ... and one of the nodes is currently mouseovered ...
+                if (active_node) {
+
+                    // ... flip the selected nodes about that node
+                    SP_NODE_CONTEXT(ec)->shape_editor->flip(NR::X, active_node->pos);
+               } else {
+
+                    // ... or else about the center of their bounding box.
+                    SP_NODE_CONTEXT(ec)->shape_editor->flip(NR::X);
+                }
+
+            // When working with the selector tool, flip the selection about its rotation center 
+            // (if it is visible) or about the center of the bounding box.
             } else {
                 sp_selection_scale_relative(sel, center, NR::scale(-1.0, 1.0));
             }
@@ -1288,8 +1320,14 @@ ObjectVerb::perform( SPAction *action, void *data, void *pdata )
                              _("Flip horizontally"));
             break;
         case SP_VERB_OBJECT_FLIP_VERTICAL:
+            // The behaviour is analogous to flipping horizontally
             if (tools_isactive(dt, TOOLS_NODES)) {
-                sp_nodepath_flip(SP_NODE_CONTEXT(ec)->nodepath, NR::Y);
+                Inkscape::NodePath::Node *active_node = Inkscape::NodePath::Path::active_node;
+                if (active_node) {
+                    SP_NODE_CONTEXT(ec)->shape_editor->flip(NR::Y, active_node->pos);
+                } else {
+                    SP_NODE_CONTEXT(ec)->shape_editor->flip(NR::Y);
+                }
             } else {
                 sp_selection_scale_relative(sel, center, NR::scale(1.0, -1.0));
             }
@@ -1332,7 +1370,7 @@ ContextVerb::perform(SPAction *action, void *data, void *pdata)
     /** \todo !!! hopefully this can go away soon and actions can look after
      * themselves
      */
-    for (vidx = SP_VERB_CONTEXT_SELECT; vidx <= SP_VERB_CONTEXT_DROPPER_PREFS; vidx++)
+    for (vidx = SP_VERB_CONTEXT_SELECT; vidx <= SP_VERB_CONTEXT_PAINTBUCKET_PREFS; vidx++)
     {
         SPAction *tool_action= get((sp_verb_t)vidx)->get_action(dt);
         if (tool_action) {
@@ -1350,6 +1388,9 @@ ContextVerb::perform(SPAction *action, void *data, void *pdata)
         case SP_VERB_CONTEXT_RECT:
             tools_switch_current(TOOLS_SHAPES_RECT);
             break;
+        case SP_VERB_CONTEXT_3DBOX:
+            tools_switch_current(TOOLS_SHAPES_3DBOX);
+            break;
         case SP_VERB_CONTEXT_ARC:
             tools_switch_current(TOOLS_SHAPES_ARC);
             break;
@@ -1383,6 +1424,9 @@ ContextVerb::perform(SPAction *action, void *data, void *pdata)
         case SP_VERB_CONTEXT_CONNECTOR:
             tools_switch_current (TOOLS_CONNECTOR);
             break;
+        case SP_VERB_CONTEXT_PAINTBUCKET:
+            tools_switch_current(TOOLS_PAINTBUCKET);
+            break;
 
         case SP_VERB_CONTEXT_SELECT_PREFS:
             prefs_set_int_attribute("dialogs.preferences", "page", PREFS_PAGE_TOOLS_SELECTOR);
@@ -1396,6 +1440,10 @@ ContextVerb::perform(SPAction *action, void *data, void *pdata)
             prefs_set_int_attribute("dialogs.preferences", "page", PREFS_PAGE_TOOLS_SHAPES_RECT);
             dt->_dlg_mgr->showDialog("InkscapePreferences");
             break;
+        case SP_VERB_CONTEXT_3DBOX_PREFS:
+            prefs_set_int_attribute("dialogs.preferences", "page", PREFS_PAGE_TOOLS_SHAPES_3DBOX);
+            dt->_dlg_mgr->showDialog("InkscapePreferences");
+            break;
         case SP_VERB_CONTEXT_ARC_PREFS:
             prefs_set_int_attribute("dialogs.preferences", "page", PREFS_PAGE_TOOLS_SHAPES_ELLIPSE);
             dt->_dlg_mgr->showDialog("InkscapePreferences");
@@ -1440,6 +1488,10 @@ ContextVerb::perform(SPAction *action, void *data, void *pdata)
             prefs_set_int_attribute ("dialogs.preferences", "page", PREFS_PAGE_TOOLS_CONNECTOR);
             dt->_dlg_mgr->showDialog("InkscapePreferences");
             break;
+        case SP_VERB_CONTEXT_PAINTBUCKET_PREFS:
+            prefs_set_int_attribute ("dialogs.preferences", "page", PREFS_PAGE_TOOLS_PAINTBUCKET);
+            dt->_dlg_mgr->showDialog("InkscapePreferences");
+            break;
 
         default:
             break;
@@ -1468,6 +1520,7 @@ ZoomVerb::perform(SPAction *action, void *data, void *pdata)
     SPDesktop *dt = static_cast<SPDesktop*>(sp_action_get_view(action));
     if (!dt)
         return;
+    SPEventContext *ec = dt->event_context;
 
     SPDocument *doc = sp_desktop_document(dt);
 
@@ -1480,12 +1533,32 @@ ZoomVerb::perform(SPAction *action, void *data, void *pdata)
     switch (GPOINTER_TO_INT(data)) {
         case SP_VERB_ZOOM_IN:
         {
+            // While drawing with the pen/pencil tool, zoom towards the end of the unfinished path
+            if (tools_isactive(dt, TOOLS_FREEHAND_PENCIL) || tools_isactive(dt, TOOLS_FREEHAND_PEN)) {
+                SPCurve *rc = SP_DRAW_CONTEXT(ec)->red_curve;
+                if (sp_curve_last_bpath(rc)) {
+                    NR::Point const zoom_to (sp_curve_last_point(rc));
+                    dt->zoom_relative_keep_point(zoom_to, zoom_inc);
+                    break;
+                }
+            }
+
             NR::Rect const d = dt->get_display_area();
             dt->zoom_relative( d.midpoint()[NR::X], d.midpoint()[NR::Y], zoom_inc);
             break;
         }
         case SP_VERB_ZOOM_OUT:
         {
+            // While drawing with the pen/pencil tool, zoom away from the end of the unfinished path
+            if (tools_isactive(dt, TOOLS_FREEHAND_PENCIL) || tools_isactive(dt, TOOLS_FREEHAND_PEN)) {
+                SPCurve *rc = SP_DRAW_CONTEXT(ec)->red_curve;
+                if (sp_curve_last_bpath(rc)) {
+                    NR::Point const zoom_to (sp_curve_last_point(rc));
+                    dt->zoom_relative_keep_point(zoom_to, 1 / zoom_inc);
+                    break;
+                }
+            }
+
             NR::Rect const d = dt->get_display_area();
             dt->zoom_relative( d.midpoint()[NR::X], d.midpoint()[NR::Y], 1 / zoom_inc );
             break;
@@ -1536,7 +1609,7 @@ ZoomVerb::perform(SPAction *action, void *data, void *pdata)
             sp_namedview_toggle_guides(doc, repr);
             break;
         case SP_VERB_TOGGLE_GRID:
-            sp_namedview_toggle_grid(doc, repr);
+            dt->toggleGrid();
             break;
 #ifdef HAVE_GTK_WINDOW_FULLSCREEN
         case SP_VERB_FULLSCREEN:
@@ -1596,6 +1669,7 @@ DialogVerb::perform(SPAction *action, void *data, void *pdata)
             break;
         case SP_VERB_DIALOG_FILL_STROKE:
             sp_object_properties_dialog();
+            // dt->_dlg_mgr->showDialog("FillAndStroke");
             break;
         case SP_VERB_DIALOG_SWATCHES:
             show_panel( Inkscape::UI::Dialogs::SwatchesPanel::getInstance(), "dialogs.swatches", SP_VERB_DIALOG_SWATCHES);
@@ -1952,8 +2026,80 @@ FitCanvasVerb::perform(SPAction *action, void *data, void *pdata)
 /* *********** End Fit Canvas ********** */
 
 
+/* *********** Lock'N'Hide ********** */
+
+/** \brief A class to represent the object unlocking and unhiding verbs */
+class LockAndHideVerb : public Verb {
+private:
+    static void perform(SPAction *action, void *mydata, void *otherdata);
+    static SPActionEventVector vector;
+protected:
+    virtual SPAction *make_action(Inkscape::UI::View::View *view);
+public:
+    /** \brief Use the Verb initializer with the same parameters. */
+    LockAndHideVerb(unsigned int const code,
+                   gchar const *id,
+                   gchar const *name,
+                   gchar const *tip,
+                   gchar const *image) :
+        Verb(code, id, name, tip, image)
+    {
+        set_default_sensitive(true);
+    }
+}; /* LockAndHideVerb class */
+
+/**
+ * The vector to attach in the lock'n'hide verb.
+ */
+SPActionEventVector LockAndHideVerb::vector =
+            {{NULL},LockAndHideVerb::perform, NULL, NULL, NULL, NULL};
+
+/** \brief  Create an action for a \c LockAndHideVerb
+    \param  view  Which view the action should be created for
+    \return The built action.
 
+    Calls \c make_action_helper with the \c vector.
+*/
+SPAction *
+LockAndHideVerb::make_action(Inkscape::UI::View::View *view)
+{
+    SPAction *action = make_action_helper(view, &vector);
+    return action;
+}
 
+/** \brief  Decode the verb code and take appropriate action */
+void
+LockAndHideVerb::perform(SPAction *action, void *data, void *pdata)
+{
+    SPDesktop *dt = static_cast<SPDesktop*>(sp_action_get_view(action));
+    if (!dt) return;
+    SPDocument *doc = sp_desktop_document(dt);
+    if (!doc) return;
+    
+    switch ((long) data) {
+        case SP_VERB_UNLOCK_ALL:
+            unlock_all(dt);
+            sp_document_done(doc, SP_VERB_UNLOCK_ALL, _("Unlock all objects in the current layer"));
+            break;
+        case SP_VERB_UNLOCK_ALL_IN_ALL_LAYERS:
+            unlock_all_in_all_layers(dt);
+            sp_document_done(doc, SP_VERB_UNLOCK_ALL_IN_ALL_LAYERS, _("Unlock all objects in all layers"));
+            break;
+        case SP_VERB_UNHIDE_ALL:
+            unhide_all(dt);
+            sp_document_done(doc, SP_VERB_UNHIDE_ALL, _("Unhide all objects in the current layer"));
+            break;
+        case SP_VERB_UNHIDE_ALL_IN_ALL_LAYERS:
+            unhide_all_in_all_layers(dt);
+            sp_document_done(doc, SP_VERB_UNHIDE_ALL_IN_ALL_LAYERS, _("Unhide all objects in all layers"));
+            break;
+        default:
+            return;
+    }
+
+    return;
+}
+/* *********** End Lock'N'Hide ********** */
 
 
 /* these must be in the same order as the SP_VERB_* enum in "verbs.h" */
@@ -2166,9 +2312,13 @@ Verb *Verb::_base_verbs[] = {
 
     /* Object */
     new ObjectVerb(SP_VERB_OBJECT_ROTATE_90_CW, "ObjectRotate90", N_("Rotate _90&#176; CW"),
-                   N_("Rotate selection 90&#176; clockwise"), "object_rotate_90_CW"),
+                   // This is shared between tooltips and statusbar, so they
+                   // must use UTF-8, not HTML entities for special characters.
+                   N_("Rotate selection 90\xc2\xb0 clockwise"), "object_rotate_90_CW"),
     new ObjectVerb(SP_VERB_OBJECT_ROTATE_90_CCW, "ObjectRotate90CCW", N_("Rotate 9_0&#176; CCW"),
-                   N_("Rotate selection 90&#176; counter-clockwise"), "object_rotate_90_CCW"),
+                   // This is shared between tooltips and statusbar, so they
+                   // must use UTF-8, not HTML entities for special characters.
+                   N_("Rotate selection 90\xc2\xb0 counter-clockwise"), "object_rotate_90_CCW"),
     new ObjectVerb(SP_VERB_OBJECT_FLATTEN, "ObjectRemoveTransform", N_("Remove _Transformations"),
                    N_("Remove transformations from object"), "object_reset"),
     new ObjectVerb(SP_VERB_OBJECT_TO_CURVE, "ObjectToPath", N_("_Object to Path"),
@@ -2201,6 +2351,8 @@ Verb *Verb::_base_verbs[] = {
                     N_("Edit path nodes or control handles"), "draw_node"),
     new ContextVerb(SP_VERB_CONTEXT_RECT, "ToolRect", N_("Rectangle"),
                     N_("Create rectangles and squares"), "draw_rect"),
+    new ContextVerb(SP_VERB_CONTEXT_3DBOX, "Tool3DBox", N_("3D Box"),
+                    N_("Create 3D boxes"), "draw_3dbox"),
     new ContextVerb(SP_VERB_CONTEXT_ARC, "ToolArc", N_("Ellipse"),
                     N_("Create circles, ellipses, and arcs"), "draw_arc"),
     new ContextVerb(SP_VERB_CONTEXT_STAR, "ToolStar", N_("Star"),
@@ -2211,7 +2363,7 @@ Verb *Verb::_base_verbs[] = {
                     N_("Draw freehand lines"), "draw_freehand"),
     new ContextVerb(SP_VERB_CONTEXT_PEN, "ToolPen", N_("Pen"),
                     N_("Draw Bezier curves and straight lines"), "draw_pen"),
-    new ContextVerb(SP_VERB_CONTEXT_CALLIGRAPHIC, "ToolCalligrphic", N_("Calligraphy"),
+    new ContextVerb(SP_VERB_CONTEXT_CALLIGRAPHIC, "ToolCalligraphic", N_("Calligraphy"),
                     N_("Draw calligraphic lines"), "draw_calligraphic"),
     new ContextVerb(SP_VERB_CONTEXT_TEXT, "ToolText", N_("Text"),
                     N_("Create and edit text objects"), "draw_text"),
@@ -2220,9 +2372,11 @@ Verb *Verb::_base_verbs[] = {
     new ContextVerb(SP_VERB_CONTEXT_ZOOM, "ToolZoom", N_("Zoom"),
                     N_("Zoom in or out"), "draw_zoom"),
     new ContextVerb(SP_VERB_CONTEXT_DROPPER, "ToolDropper", N_("Dropper"),
-                    N_("Pick averaged colors from image"), "draw_dropper"),
+                    N_("Pick colors from image"), "draw_dropper"),
     new ContextVerb(SP_VERB_CONTEXT_CONNECTOR, "ToolConnector", N_("Connector"),
                     N_("Create connectors"), "draw_connector"),
+    new ContextVerb(SP_VERB_CONTEXT_PAINTBUCKET, "ToolPaintBucket", N_("Paint Bucket"),
+                    N_("Fill bounded areas"), "draw_paintbucket"),
 
     /* Tool prefs */
     new ContextVerb(SP_VERB_CONTEXT_SELECT_PREFS, "SelectPrefs", N_("Selector Preferences"),
@@ -2231,6 +2385,8 @@ Verb *Verb::_base_verbs[] = {
                     N_("Open Preferences for the Node tool"), NULL),
     new ContextVerb(SP_VERB_CONTEXT_RECT_PREFS, "RectPrefs", N_("Rectangle Preferences"),
                     N_("Open Preferences for the Rectangle tool"), NULL),
+    new ContextVerb(SP_VERB_CONTEXT_3DBOX_PREFS, "3DBoxPrefs", N_("3D Box Preferences"),
+                    N_("Open Preferences for the 3D Box tool"), NULL),
     new ContextVerb(SP_VERB_CONTEXT_ARC_PREFS, "ArcPrefs", N_("Ellipse Preferences"),
                     N_("Open Preferences for the Ellipse tool"), NULL),
     new ContextVerb(SP_VERB_CONTEXT_STAR_PREFS, "StarPrefs", N_("Star Preferences"),
@@ -2253,6 +2409,8 @@ Verb *Verb::_base_verbs[] = {
                     N_("Open Preferences for the Dropper tool"), NULL),
     new ContextVerb(SP_VERB_CONTEXT_CONNECTOR_PREFS, "ConnectorPrefs", N_("Connector Preferences"),
                     N_("Open Preferences for the Connector tool"), NULL),
+    new ContextVerb(SP_VERB_CONTEXT_PAINTBUCKET_PREFS, "PaintBucketPrefs", N_("Paint Bucket Preferences"),
+                    N_("Open Preferences for the Paint Bucket tool"), NULL),
 
     /* Zoom/View */
     new ZoomVerb(SP_VERB_ZOOM_IN, "ZoomIn", N_("Zoom In"), N_("Zoom in"), "zoom_in"),
@@ -2306,7 +2464,7 @@ Verb *Verb::_base_verbs[] = {
     new DialogVerb(SP_VERB_DIALOG_METADATA, "DialogMetadata", N_("Document _Metadata..."),
                    N_("Edit document metadata (to be saved with the document)"), "document_metadata" ),
     new DialogVerb(SP_VERB_DIALOG_FILL_STROKE, "DialogFillStroke", N_("_Fill and Stroke..."),
-                   N_("Edit objects' style, such as color or stroke width"), "fill_and_stroke"),
+                   N_("Edit objects' colors, gradients, stroke width, arrowheads, dash patterns..."), "fill_and_stroke"),
     // TRANSLATORS: "Swatches" means: color samples
     new DialogVerb(SP_VERB_DIALOG_SWATCHES, "DialogSwatches", N_("S_watches..."),
                    N_("Select colors from a swatches palette"), GTK_STOCK_SELECT_COLOR),
@@ -2385,11 +2543,37 @@ Verb *Verb::_base_verbs[] = {
                        N_("Fit the page to the drawing"), NULL),
     new FitCanvasVerb(SP_VERB_FIT_CANVAS_TO_SELECTION_OR_DRAWING, "FitCanvasToSelectionOrDrawing", N_("Fit Page to Selection or Drawing"),
                        N_("Fit the page to the current selection or the drawing if there is no selection"), NULL),
+    /* LockAndHide */
+    new LockAndHideVerb(SP_VERB_UNLOCK_ALL, "UnlockAll", N_("Unlock All"),
+                       N_("Unlock all objects in the current layer"), NULL),
+    new LockAndHideVerb(SP_VERB_UNLOCK_ALL_IN_ALL_LAYERS, "UnlockAllInAllLayers", N_("Unlock All in All Layers"),
+                       N_("Unlock all objects in all layers"), NULL),
+    new LockAndHideVerb(SP_VERB_UNHIDE_ALL, "UnhideAll", N_("Unhide All"),
+                       N_("Unhide all objects in the current layer"), NULL),
+    new LockAndHideVerb(SP_VERB_UNHIDE_ALL_IN_ALL_LAYERS, "UnhideAllInAllLayers", N_("Unhide All in All Layers"),
+                       N_("Unhide all objects in all layers"), NULL),
     /* Footer */
     new Verb(SP_VERB_LAST, " '\"invalid id", NULL, NULL, NULL)
 };
 
 
+void
+Verb::list (void) {
+    // Go through the dynamic verb table
+    for (VerbTable::iterator iter = _verbs.begin(); iter != _verbs.end(); iter++) {
+        Verb * verb = iter->second;
+        if (verb->get_code() == SP_VERB_INVALID ||
+                verb->get_code() == SP_VERB_NONE ||
+                verb->get_code() == SP_VERB_LAST) {
+            continue;
+        }
+
+        printf("%s: %s\n", verb->get_id(), verb->get_tip()? verb->get_tip() : verb->get_name());
+    }
+
+    return;
+};
+
 }  /* namespace Inkscape */
 
 /*