summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: b1d3300)
raw | patch | inline | side by side (parent: b1d3300)
author | Jon A. Cruz <jon@joncruz.org> | |
Thu, 7 Jan 2010 09:19:48 +0000 (01:19 -0800) | ||
committer | Jon A. Cruz <jon@joncruz.org> | |
Thu, 7 Jan 2010 09:19:48 +0000 (01:19 -0800) |
src/ui/Makefile_insert | patch | blob | history | |
src/ui/uxmanager.cpp | [new file with mode: 0644] | patch | blob |
src/ui/uxmanager.h | [new file with mode: 0644] | patch | blob |
src/util/Makefile_insert | patch | blob | history | |
src/util/ege-tags.cpp | [new file with mode: 0644] | patch | blob |
src/util/ege-tags.h | [new file with mode: 0644] | patch | blob |
src/widgets/desktop-widget.cpp | patch | blob | history | |
src/widgets/toolbox.cpp | patch | blob | history | |
src/widgets/toolbox.h | patch | blob | history |
diff --git a/src/ui/Makefile_insert b/src/ui/Makefile_insert
index 3eb6c6b13c93cb29745fd91d297687ccdfc38454..eb8966d11634b6fdfe93ec9025b682ab36418b03 100644 (file)
--- a/src/ui/Makefile_insert
+++ b/src/ui/Makefile_insert
ui/previewable.h \
ui/previewfillable.h \
ui/previewholder.cpp \
- ui/previewholder.h
+ ui/previewholder.h \
+ ui/uxmanager.cpp \
+ ui/uxmanager.h
diff --git a/src/ui/uxmanager.cpp b/src/ui/uxmanager.cpp
--- /dev/null
+++ b/src/ui/uxmanager.cpp
@@ -0,0 +1,68 @@
+/** \file
+ * Desktop widget implementation
+ */
+/* Authors:
+ * Jon A. Cruz <jon@joncruz.org>
+ *
+ * Copyright (C) 2010 Jon A. Cruz
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "uxmanager.h"
+#include "util/ege-tags.h"
+#include "widgets/toolbox.h"
+
+namespace Inkscape {
+namespace UI {
+
+UXManager* instance = 0;
+
+UXManager* UXManager::getInstance()
+{
+ if (!instance) {
+ instance = new UXManager();
+ }
+ return instance;
+}
+
+
+UXManager::UXManager()
+{
+ ege::TagSet tags;
+ tags.setLang("en");
+
+ tags.addTag(ege::Tag("General"));
+ tags.addTag(ege::Tag("Icons"));
+}
+
+UXManager::~UXManager()
+{
+}
+
+
+void UXManager::connectToDesktop( std::vector<GtkWidget *> const & toolboxes, SPDesktop *desktop )
+{
+ for (std::vector<GtkWidget*>::const_iterator it = toolboxes.begin(); it != toolboxes.end(); ++it ) {
+ sp_toolbox_set_desktop( *it, desktop );
+ }
+}
+
+
+} // namespace UI
+} // namespace Inkscape
+
+/*
+ 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 :
diff --git a/src/ui/uxmanager.h b/src/ui/uxmanager.h
--- /dev/null
+++ b/src/ui/uxmanager.h
@@ -0,0 +1,47 @@
+#ifndef SEEN_UI_UXMANAGER_H
+#define SEEN_UI_UXMANAGER_H
+/*
+ * A simple interface for previewing representations.
+ *
+ * Authors:
+ * Jon A. Cruz <jon@joncruz.org>
+ *
+ * Copyright (C) 2010 Jon A. Cruz
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <vector>
+
+typedef struct _GtkWidget GtkWidget;
+class SPDesktop;
+
+namespace Inkscape {
+namespace UI {
+
+class UXManager
+{
+public:
+ static UXManager* getInstance();
+ virtual ~UXManager();
+
+ void connectToDesktop( std::vector<GtkWidget *> const & toolboxes, SPDesktop *desktop );
+
+private:
+ UXManager();
+};
+
+} // namespace UI
+} // namespace Inkscape
+
+#endif // SEEN_UI_UXMANAGER_H
+/*
+ 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 :
index b76a4dcdb49787f87af028268899e0918ba30371..87a974768a9162a16f4e712d0d4c9edbd46081ff 100644 (file)
--- a/src/util/Makefile_insert
+++ b/src/util/Makefile_insert
util/compose.hpp \
util/ucompose.hpp \
util/enums.h \
+ util/ege-tags.h \
+ util/ege-tags.cpp \
util/filter-list.h \
util/fixed_point.h \
util/format.h \
diff --git a/src/util/ege-tags.cpp b/src/util/ege-tags.cpp
--- /dev/null
+++ b/src/util/ege-tags.cpp
@@ -0,0 +1,178 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is EGE Tagging Support.
+ *
+ * The Initial Developer of the Original Code is
+ * Jon A. Cruz.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif // HAVE_CONFIG_H
+
+#if HAVE_LIBINTL_H
+#include <libintl.h>
+#endif // HAVE_LIBINTL_H
+
+#if !defined(_)
+#define _(s) gettext(s)
+#endif // !defined(_)
+
+#include <set>
+#include <algorithm>
+#include <functional>
+
+#include "ege-tags.h"
+
+#include <glib.h>
+
+namespace ege
+{
+
+Label::Label(std::string const& lang, std::string const& value) :
+ lang(lang),
+ value(value)
+{
+}
+
+Label::~Label()
+{
+}
+
+// =========================================================================
+
+Tag::~Tag()
+{
+}
+
+Tag::Tag(std::string const& key) :
+ key(key)
+{
+}
+
+// =========================================================================
+
+TagSet::TagSet() :
+ lang(),
+ tags(),
+ counts()
+{
+}
+
+TagSet::~TagSet()
+{
+}
+
+void TagSet::setLang(std::string const& lang)
+{
+ if (lang != this->lang) {
+ this->lang = lang;
+ }
+}
+
+
+struct sameLang : public std::binary_function<Label, Label, bool> {
+ bool operator()(Label const& x, Label const& y) const { return (x.lang == y.lang); }
+};
+
+
+bool TagSet::addTag(Tag const& tag)
+{
+ bool present = false;
+
+ for ( std::vector<Tag>::iterator it = tags.begin(); (it != tags.end()) && !present; ++it ) {
+ if (tag.key == it->key) {
+ present = true;
+
+ for ( std::vector<Label>::const_iterator it2 = tag.labels.begin(); it2 != tag.labels.end(); ++it2 ) {
+ std::vector<Label>::iterator itOld = std::find_if( it->labels.begin(), it->labels.end(), std::bind2nd(sameLang(), *it2) );
+ if (itOld != it->labels.end()) {
+ itOld->value = it2->value;
+ } else {
+ it->labels.push_back(*it2);
+ }
+ }
+ }
+ }
+
+ if (!present) {
+ tags.push_back(tag);
+ counts[tag.key] = 0;
+ }
+
+ return present;
+}
+
+
+std::vector<Tag> const& TagSet::getTags()
+{
+ return tags;
+}
+
+int TagSet::getCount( std::string const& key )
+{
+ int count = 0;
+ if ( counts.find(key) != counts.end() ) {
+ count = counts[key];
+ }
+ return count;
+}
+
+void TagSet::increment( std::string const& key )
+{
+ if ( counts.find(key) != counts.end() ) {
+ counts[key]++;
+ } else {
+ Tag tag(key);
+ tags.push_back(tag);
+ counts[key] = 1;
+ }
+}
+
+void TagSet::decrement( std::string const& key )
+{
+ if ( counts.find(key) != counts.end() ) {
+ counts[key]--;
+ }
+}
+
+} // namespace ege
+
+/*
+ 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:encoding=utf-8:textwidth=99 :
diff --git a/src/util/ege-tags.h b/src/util/ege-tags.h
--- /dev/null
+++ b/src/util/ege-tags.h
@@ -0,0 +1,121 @@
+#ifndef SEEN_EGE_TAGS_H
+#define SEEN_EGE_TAGS_H
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is EGE Tagging Support.
+ *
+ * The Initial Developer of the Original Code is
+ * Jon A. Cruz.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <string>
+#include <vector>
+#include <map>
+
+/*
+ * Implements base tagging of http://create.freedesktop.org/wiki/ResourceTagging .
+ */
+
+// Note that this API is preliminary and subject to frequent change:
+
+namespace ege
+{
+
+class Label
+{
+public:
+ Label();
+ Label(std::string const& lang, std::string const& value);
+ ~Label();
+
+ std::string lang;
+ std::string value;
+};
+
+class Tag
+{
+public:
+ Tag();
+ Tag(std::string const& key);
+ ~Tag();
+
+ std::string key;
+ std::vector<Label> labels;
+};
+
+
+/**
+ * Contains a set of tags with unique keys, and with locale support.
+ *
+ */
+class TagSet
+{
+public:
+ TagSet();
+ ~TagSet();
+
+ std::string const & getLang() const;
+ void setLang(std::string const& lang);
+
+ /**
+ * Adds or updates a tag.
+ *
+ * @return true if a tag was updated, false if it was added.
+ */
+ bool addTag(Tag const& tag);
+ std::vector<Tag> const& getTags();
+
+ int getCount( std::string const& key );
+ void increment( std::string const& key );
+ void decrement( std::string const& key );
+
+private:
+
+ std::string lang;
+ std::vector<Tag> tags;
+ std::map<std::string, int> counts;
+};
+
+} // namespace ege
+
+
+#endif // SEEN_EGE_TAGS_H
+/*
+ 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:encoding=utf-8:textwidth=99 :
index b63992afe9a8ff22d0528533ffc0326f20646251..6c330b5f3d7a99d4b545ddb0cb18b1875652b1a2 100644 (file)
#include "ui/widget/dock.h"
#include "ui/widget/layer-selector.h"
#include "ui/widget/selected-style.h"
+#include "ui/uxmanager.h"
#include "widgets/button.h"
#include "widgets/ruler.h"
#include "widgets/spinbutton-events.h"
using Inkscape::round;
#endif
+
+using Inkscape::UI::UXManager;
+
+
#ifdef WITH_INKBOARD
#endif
sp_desktop_widget_layout (dtw);
- sp_tool_toolbox_set_desktop (dtw->tool_toolbox, dtw->desktop);
- sp_aux_toolbox_set_desktop (dtw->aux_toolbox, dtw->desktop);
- sp_commands_toolbox_set_desktop (dtw->commands_toolbox, dtw->desktop);
- sp_snap_toolbox_set_desktop (dtw->snap_toolbox, dtw->desktop);
+ std::vector<GtkWidget *> toolboxes;
+ toolboxes.push_back(dtw->tool_toolbox);
+ toolboxes.push_back(dtw->aux_toolbox);
+ toolboxes.push_back(dtw->commands_toolbox);
+ toolboxes.push_back(dtw->snap_toolbox);
+ UXManager::getInstance()->connectToDesktop( toolboxes, dtw->desktop );
dtw->panels->setDesktop( dtw->desktop );
index 49cbbe0104366ab731e62b2ad3793504cc1fba71..185e8bd2d033843b6381be051c68393ecf1212c6 100644 (file)
--- a/src/widgets/toolbox.cpp
+++ b/src/widgets/toolbox.cpp
typedef void (*SetupFunction)(GtkWidget *toolbox, SPDesktop *desktop);
typedef void (*UpdateFunction)(SPDesktop *desktop, SPEventContext *eventcontext, GtkWidget *toolbox);
+enum BarId {
+ BAR_TOOL = 0,
+ BAR_AUX,
+ BAR_COMMANDS,
+ BAR_SNAP,
+};
+
+#define BAR_ID_KEY "BarIdValue"
+
+
static void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
static void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
static void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
static Glib::RefPtr<Gtk::ActionGroup> create_or_fetch_actions( SPDesktop* desktop );
-static void toolbox_set_desktop (GtkWidget *toolbox, SPDesktop *desktop, SetupFunction setup_func, UpdateFunction update_func);
-
static void setup_tool_toolbox (GtkWidget *toolbox, SPDesktop *desktop);
static void update_tool_toolbox (SPDesktop *desktop, SPEventContext *eventcontext, GtkWidget *toolbox);
@@ -833,9 +841,7 @@ void handlebox_attached(GtkHandleBox* /*handlebox*/, GtkWidget* widget, gpointer
gtk_widget_set_size_request( widget, -1, -1 );
}
-
-
-static GtkWidget* toolboxNewCommon( GtkWidget* tb, GtkPositionType handlePos )
+static GtkWidget* toolboxNewCommon( GtkWidget* tb, BarId id, GtkPositionType handlePos )
{
g_object_set_data(G_OBJECT(tb), "desktop", NULL);
g_signal_connect(G_OBJECT(hb), "child_detached", G_CALLBACK(handlebox_detached), static_cast<gpointer>(0));
g_signal_connect(G_OBJECT(hb), "child_attached", G_CALLBACK(handlebox_attached), static_cast<gpointer>(0));
+ gpointer val = GINT_TO_POINTER(id);
+ g_object_set_data(G_OBJECT(hb), BAR_ID_KEY, val);
+
return hb;
}
gtk_toolbar_set_orientation(GTK_TOOLBAR(toolBar), GTK_ORIENTATION_VERTICAL);
gtk_toolbar_set_show_arrow(GTK_TOOLBAR(toolBar), TRUE);
- return toolboxNewCommon( toolBar, GTK_POS_TOP );
+ return toolboxNewCommon( toolBar, BAR_TOOL, GTK_POS_TOP );
}
GtkWidget *sp_aux_toolbox_new()
{
GtkWidget *tb = gtk_vbox_new(FALSE, 0);
- g_object_set_data(G_OBJECT(tb), "MarkForChild", const_cast<gchar *>("MarkForChild"));
-
- return toolboxNewCommon( tb, GTK_POS_LEFT );
+ return toolboxNewCommon( tb, BAR_AUX, GTK_POS_LEFT );
}
//####################################
{
GtkWidget *tb = gtk_toolbar_new();
- return toolboxNewCommon( tb, GTK_POS_LEFT );
+ return toolboxNewCommon( tb, BAR_COMMANDS, GTK_POS_LEFT );
}
GtkWidget *sp_snap_toolbox_new()
{
GtkWidget *tb = gtk_vbox_new(FALSE, 0);
- return toolboxNewCommon( tb, GTK_POS_LEFT );
+ return toolboxNewCommon( tb, BAR_SNAP, GTK_POS_LEFT );
}
static EgeAdjustmentAction * create_adjustment_action( gchar const *name,
@@ -1509,55 +1516,41 @@ static void sp_zoom_toolbox_prep(SPDesktop */*desktop*/, GtkActionGroup* /*mainA
// no custom GtkAction setup needed
} // end of sp_zoom_toolbox_prep()
-void
-sp_tool_toolbox_set_desktop(GtkWidget *toolbox, SPDesktop *desktop)
+void sp_toolbox_set_desktop(GtkWidget *toolbox, SPDesktop *desktop)
{
- toolbox_set_desktop(toolbox,
- desktop,
- setup_tool_toolbox,
- update_tool_toolbox);
-}
+ sigc::connection *conn = static_cast<sigc::connection*>(g_object_get_data(G_OBJECT(toolbox),
+ "event_context_connection"));
+ BarId id = static_cast<BarId>( GPOINTER_TO_INT(g_object_get_data(G_OBJECT(toolbox), BAR_ID_KEY)) );
-void
-sp_aux_toolbox_set_desktop(GtkWidget *toolbox, SPDesktop *desktop)
-{
- toolbox_set_desktop(toolbox,
- desktop,
- setup_aux_toolbox,
- update_aux_toolbox);
-}
+ SetupFunction setup_func = 0;
+ UpdateFunction update_func = 0;
-void
-sp_commands_toolbox_set_desktop(GtkWidget *toolbox, SPDesktop *desktop)
-{
- toolbox_set_desktop(toolbox,
- desktop,
- setup_commands_toolbox,
- update_commands_toolbox);
-}
+ switch (id) {
+ case BAR_TOOL:
+ setup_func = setup_tool_toolbox;
+ update_func = update_tool_toolbox;
+ break;
-void
-sp_snap_toolbox_set_desktop(GtkWidget *toolbox, SPDesktop *desktop)
-{
- toolbox_set_desktop(toolbox,
- desktop,
- setup_snap_toolbox,
- update_snap_toolbox);
-}
+ case BAR_AUX:
+ toolbox = gtk_bin_get_child(GTK_BIN(toolbox));
+ setup_func = setup_aux_toolbox;
+ update_func = update_aux_toolbox;
+ break;
+ case BAR_COMMANDS:
+ setup_func = setup_commands_toolbox;
+ update_func = update_commands_toolbox;
+ break;
-static void
-toolbox_set_desktop(GtkWidget *toolbox, SPDesktop *desktop, SetupFunction setup_func, UpdateFunction update_func)
-{
- sigc::connection *conn = static_cast<sigc::connection*>(g_object_get_data(G_OBJECT(toolbox),
- "event_context_connection"));
- {
- GtkWidget* child = gtk_bin_get_child(GTK_BIN(toolbox));
- if (g_object_get_data(G_OBJECT(child), "MarkForChild")) {
- toolbox = child;
- }
+ case BAR_SNAP:
+ setup_func = setup_snap_toolbox;
+ update_func = update_snap_toolbox;
+ break;
+ default:
+ g_warning("Unexpected toolbox id encountered.");
}
+
gpointer ptr = g_object_get_data(G_OBJECT(toolbox), "desktop");
SPDesktop *old_desktop = static_cast<SPDesktop*>(ptr);
@@ -1573,17 +1566,16 @@ toolbox_set_desktop(GtkWidget *toolbox, SPDesktop *desktop, SetupFunction setup_
g_object_set_data(G_OBJECT(toolbox), "desktop", (gpointer)desktop);
- if (desktop) {
+ if (desktop && setup_func && update_func) {
gtk_widget_set_sensitive(toolbox, TRUE);
setup_func(toolbox, desktop);
update_func(desktop, desktop->event_context, toolbox);
- *conn = desktop->connectEventContextChanged
- (sigc::bind (sigc::ptr_fun(update_func), toolbox));
+ *conn = desktop->connectEventContextChanged(sigc::bind (sigc::ptr_fun(update_func), toolbox));
} else {
gtk_widget_set_sensitive(toolbox, FALSE);
}
-} // end of toolbox_set_desktop()
+} // end of sp_toolbox_set_desktop()
static void setupToolboxCommon( GtkWidget *toolbox,
diff --git a/src/widgets/toolbox.h b/src/widgets/toolbox.h
index 4bc417e8f6d4ddb7a43064e441511d14f64f6b4a..a07a8cb2a3872e4e34547af56f54420e0360c81c 100644 (file)
--- a/src/widgets/toolbox.h
+++ b/src/widgets/toolbox.h
#include <gtk/gtkstyle.h>
#include <gtk/gtktooltips.h>
+#include <glibmm/ustring.h>
#include "forward.h"
#include "icon-size.h"
GtkWidget *sp_tool_toolbox_new ();
-void sp_tool_toolbox_set_desktop(GtkWidget *toolbox, SPDesktop *desktop);
-
GtkWidget *sp_aux_toolbox_new ();
-void sp_aux_toolbox_set_desktop(GtkWidget *toolbox, SPDesktop *desktop);
-
GtkWidget *sp_commands_toolbox_new ();
-void sp_commands_toolbox_set_desktop(GtkWidget *toolbox, SPDesktop *desktop);
-
GtkWidget *sp_snap_toolbox_new ();
-void sp_snap_toolbox_set_desktop(GtkWidget *toolbox, SPDesktop *desktop);
+
+void sp_toolbox_set_desktop(GtkWidget *toolbox, SPDesktop *desktop);
+
void update_snap_toolbox(SPDesktop *desktop, SPEventContext *eventcontext, GtkWidget *toolbox);
void setup_snap_toolbox (GtkWidget *toolbox, SPDesktop *desktop);