summaryrefslogtreecommitdiffstats
path: root/src/widgets
diff options
context:
space:
mode:
authorLiam P. White <inkscapebrony@gmail.com>2014-10-29 22:40:05 +0000
committerLiam P. White <inkscapebrony@gmail.com>2014-10-29 22:40:05 +0000
commite9943b70c7bf507b9639ecb0a421bcee7ce93e33 (patch)
tree2d2fe7ee7a566e1ef1a5dcde18296d9f21188f35 /src/widgets
parenti18n. Fixing untranslated strings. (diff)
parentMerge with trunk r13640 (diff)
downloadinkscape-e9943b70c7bf507b9639ecb0a421bcee7ce93e33.tar.gz
inkscape-e9943b70c7bf507b9639ecb0a421bcee7ce93e33.zip
Merge experimental
(bzr r13641)
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/CMakeLists.txt10
-rw-r--r--src/widgets/Makefile_insert10
-rw-r--r--src/widgets/arc-toolbar.cpp28
-rw-r--r--src/widgets/box3d-toolbar.cpp24
-rw-r--r--src/widgets/button.cpp381
-rw-r--r--src/widgets/button.h31
-rw-r--r--src/widgets/calligraphy-toolbar.cpp6
-rw-r--r--src/widgets/connector-toolbar.cpp4
-rw-r--r--src/widgets/dash-selector.cpp2
-rw-r--r--src/widgets/desktop-widget.cpp6
-rw-r--r--src/widgets/dropper-toolbar.cpp4
-rw-r--r--src/widgets/eek-preview.h1
-rw-r--r--src/widgets/ege-adjustment-action.cpp1113
-rw-r--r--src/widgets/ege-adjustment-action.h192
-rw-r--r--src/widgets/ege-output-action.cpp245
-rw-r--r--src/widgets/ege-output-action.h120
-rw-r--r--src/widgets/ege-select-one-action.cpp1153
-rw-r--r--src/widgets/ege-select-one-action.h245
-rw-r--r--src/widgets/eraser-toolbar.cpp6
-rw-r--r--src/widgets/font-selector.cpp48
-rw-r--r--src/widgets/font-selector.h4
-rw-r--r--src/widgets/gradient-image.cpp56
-rw-r--r--src/widgets/gradient-image.h30
-rw-r--r--src/widgets/gradient-selector.cpp54
-rw-r--r--src/widgets/gradient-selector.h31
-rw-r--r--src/widgets/gradient-toolbar.cpp6
-rw-r--r--src/widgets/gradient-vector.cpp72
-rw-r--r--src/widgets/gradient-vector.h16
-rw-r--r--src/widgets/icon.cpp5
-rw-r--r--src/widgets/icon.h8
-rw-r--r--src/widgets/ink-action.cpp638
-rw-r--r--src/widgets/ink-action.h159
-rw-r--r--src/widgets/ink-comboboxentry-action.cpp958
-rw-r--r--src/widgets/ink-comboboxentry-action.h106
-rw-r--r--src/widgets/lpe-toolbar.cpp41
-rw-r--r--src/widgets/mappings.xml1
-rw-r--r--src/widgets/measure-toolbar.cpp4
-rw-r--r--src/widgets/mesh-toolbar.cpp88
-rw-r--r--src/widgets/node-toolbar.cpp51
-rw-r--r--src/widgets/paint-selector.cpp101
-rw-r--r--src/widgets/paint-selector.h18
-rw-r--r--src/widgets/paintbucket-toolbar.cpp6
-rw-r--r--src/widgets/pencil-toolbar.cpp16
-rw-r--r--src/widgets/rect-toolbar.cpp28
-rw-r--r--src/widgets/select-toolbar.cpp6
-rw-r--r--src/widgets/sp-color-icc-selector.cpp45
-rw-r--r--src/widgets/sp-color-icc-selector.h2
-rw-r--r--src/widgets/sp-color-notebook.cpp50
-rw-r--r--src/widgets/sp-color-notebook.h4
-rw-r--r--src/widgets/sp-color-scales.cpp54
-rw-r--r--src/widgets/sp-color-scales.h5
-rw-r--r--src/widgets/sp-color-selector.cpp42
-rw-r--r--src/widgets/sp-color-selector.h12
-rw-r--r--src/widgets/sp-color-slider.cpp30
-rw-r--r--src/widgets/sp-color-slider.h7
-rw-r--r--src/widgets/sp-color-wheel-selector.cpp54
-rw-r--r--src/widgets/sp-color-wheel-selector.h5
-rw-r--r--src/widgets/sp-widget.cpp79
-rw-r--r--src/widgets/sp-widget.h18
-rw-r--r--src/widgets/sp-xmlview-attr-list.cpp34
-rw-r--r--src/widgets/sp-xmlview-attr-list.h3
-rw-r--r--src/widgets/sp-xmlview-content.cpp34
-rw-r--r--src/widgets/sp-xmlview-content.h3
-rw-r--r--src/widgets/sp-xmlview-tree.cpp42
-rw-r--r--src/widgets/sp-xmlview-tree.h17
-rw-r--r--src/widgets/spinbutton-events.h4
-rw-r--r--src/widgets/spiral-toolbar.cpp6
-rw-r--r--src/widgets/spray-toolbar.cpp6
-rw-r--r--src/widgets/spw-utilities.cpp11
-rw-r--r--src/widgets/star-toolbar.cpp31
-rw-r--r--src/widgets/stroke-marker-selector.cpp4
-rw-r--r--src/widgets/stroke-style.cpp2
-rw-r--r--src/widgets/stroke-style.h6
-rw-r--r--src/widgets/text-toolbar.cpp10
-rw-r--r--src/widgets/toolbox.cpp14
-rw-r--r--src/widgets/toolbox.h6
-rw-r--r--src/widgets/tweak-toolbar.cpp8
77 files changed, 5770 insertions, 1010 deletions
diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt
index fe4433153..072b905a2 100644
--- a/src/widgets/CMakeLists.txt
+++ b/src/widgets/CMakeLists.txt
@@ -24,6 +24,9 @@ set(widgets_SRC
desktop-widget.cpp
eek-preview.cpp
ege-paint-def.cpp
+ ege-adjustment-action.cpp
+ ege-output-action.cpp
+ ege-select-one-action.cpp
fill-style.cpp
font-selector.cpp
gradient-image.cpp
@@ -31,6 +34,8 @@ set(widgets_SRC
gradient-toolbar.cpp
gradient-vector.cpp
icon.cpp
+ ink-action.cpp
+ ink-comboboxentry-action.cpp
paint-selector.cpp
ruler.cpp
select-toolbar.cpp
@@ -80,6 +85,9 @@ set(widgets_SRC
desktop-widget.h
eek-preview.h
ege-paint-def.h
+ ege-adjustment-action.h
+ ege-output-action.h
+ ege-select-one-action.h
fill-n-stroke-factory.h
fill-style.h
font-selector.h
@@ -88,6 +96,8 @@ set(widgets_SRC
gradient-toolbar.h
gradient-vector.h
icon.h
+ ink-action.h
+ ink-comboboxentry-action.h
paint-selector.h
ruler.h
select-toolbar.h
diff --git a/src/widgets/Makefile_insert b/src/widgets/Makefile_insert
index 97713cbee..dc4c12967 100644
--- a/src/widgets/Makefile_insert
+++ b/src/widgets/Makefile_insert
@@ -19,8 +19,14 @@ ink_common_sources += \
widgets/dropper-toolbar.h \
widgets/eek-preview.cpp \
widgets/eek-preview.h \
+ widgets/ege-adjustment-action.cpp \
+ widgets/ege-adjustment-action.h \
widgets/ege-paint-def.cpp \
widgets/ege-paint-def.h \
+ widgets/ege-output-action.cpp \
+ widgets/ege-output-action.h \
+ widgets/ege-select-one-action.cpp \
+ widgets/ege-select-one-action.h \
widgets/eraser-toolbar.cpp \
widgets/eraser-toolbar.h \
widgets/fill-style.cpp \
@@ -38,6 +44,10 @@ ink_common_sources += \
widgets/gradient-vector.h \
widgets/icon.cpp \
widgets/icon.h \
+ widgets/ink-action.cpp \
+ widgets/ink-action.h \
+ widgets/ink-comboboxentry-action.cpp \
+ widgets/ink-comboboxentry-action.h \
widgets/lpe-toolbar.cpp \
widgets/lpe-toolbar.h \
widgets/measure-toolbar.cpp \
diff --git a/src/widgets/arc-toolbar.cpp b/src/widgets/arc-toolbar.cpp
index ca6810c81..ca582924b 100644
--- a/src/widgets/arc-toolbar.cpp
+++ b/src/widgets/arc-toolbar.cpp
@@ -34,10 +34,10 @@
#include "desktop-handles.h"
#include "desktop.h"
#include "document-undo.h"
-#include "ege-adjustment-action.h"
-#include "ege-output-action.h"
-#include "ege-select-one-action.h"
-#include "ink-action.h"
+#include "widgets/ege-adjustment-action.h"
+#include "widgets/ege-output-action.h"
+#include "widgets/ege-select-one-action.h"
+#include "widgets/ink-action.h"
#include "mod360.h"
#include "preferences.h"
#include "selection.h"
@@ -45,6 +45,7 @@
#include "toolbox.h"
#include "ui/icon-names.h"
#include "ui/uxmanager.h"
+#include "ui/tools/arc-tool.h"
#include "verbs.h"
#include "widgets/spinbutton-events.h"
#include "xml/node-event-vector.h"
@@ -304,6 +305,7 @@ static void sp_arc_toolbox_selection_changed(Inkscape::Selection *selection, GOb
}
}
+static void arc_toolbox_check_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder);
void sp_arc_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
{
@@ -402,14 +404,22 @@ void sp_arc_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObjec
sp_arctb_sensitivize( holder, gtk_adjustment_get_value(adj1), gtk_adjustment_get_value(adj2) );
}
-
- sigc::connection *connection = new sigc::connection(
- sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_arc_toolbox_selection_changed), G_OBJECT(holder)))
- );
- g_signal_connect( holder, "destroy", G_CALLBACK(delete_connection), connection );
+ desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(arc_toolbox_check_ec), holder));
g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder );
}
+static void arc_toolbox_check_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder)
+{
+ static sigc::connection changed;
+
+ if (SP_IS_ARC_CONTEXT(ec)) {
+ changed = sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_arc_toolbox_selection_changed), holder));
+ sp_arc_toolbox_selection_changed(sp_desktop_selection(desktop), holder);
+ } else {
+ if (changed)
+ changed.disconnect();
+ }
+}
/*
Local Variables:
diff --git a/src/widgets/box3d-toolbar.cpp b/src/widgets/box3d-toolbar.cpp
index 3b13cd2cf..02d102a11 100644
--- a/src/widgets/box3d-toolbar.cpp
+++ b/src/widgets/box3d-toolbar.cpp
@@ -36,13 +36,14 @@
#include "desktop.h"
#include "document-undo.h"
#include "document.h"
-#include "ege-adjustment-action.h"
-#include "ink-action.h"
+#include "widgets/ege-adjustment-action.h"
+#include "widgets/ink-action.h"
#include "inkscape.h"
#include "persp3d.h"
#include "selection.h"
#include "toolbox.h"
#include "ui/icon-names.h"
+#include "ui/tools/box3d-tool.h"
#include "ui/uxmanager.h"
#include "verbs.h"
#include "xml/node-event-vector.h"
@@ -280,6 +281,8 @@ static void box3d_vp_z_state_changed( GtkToggleAction *act, GtkAction *box3d_ang
box3d_vp_state_changed(act, box3d_angle, Proj::Z);
}
+static void box3d_toolbox_check_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder);
+
void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
{
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
@@ -409,13 +412,22 @@ void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject
gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/shapes/3dbox/vp_z_state", true) );
}
- sigc::connection *connection = new sigc::connection(
- sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(box3d_toolbox_selection_changed), G_OBJECT(holder)))
- );
- g_signal_connect(holder, "destroy", G_CALLBACK(delete_connection), connection);
+ desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(box3d_toolbox_check_ec), holder));
g_signal_connect(holder, "destroy", G_CALLBACK(purge_repr_listener), holder);
}
+static void box3d_toolbox_check_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder)
+{
+ static sigc::connection changed;
+ if (SP_IS_BOX3D_CONTEXT(ec)) {
+ changed = sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(box3d_toolbox_selection_changed), holder));
+ box3d_toolbox_selection_changed(sp_desktop_selection(desktop), holder);
+ } else {
+ if (changed)
+ changed.disconnect();
+ }
+}
+
/*
Local Variables:
mode:c++
diff --git a/src/widgets/button.cpp b/src/widgets/button.cpp
index a1bd9b792..1776e28c4 100644
--- a/src/widgets/button.cpp
+++ b/src/widgets/button.cpp
@@ -1,6 +1,4 @@
-#define __SP_BUTTON_C__
-
-/*
+/**
* Generic button widget
*
* Authors:
@@ -13,282 +11,257 @@
* This code is in public domain
*/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
+#include <glibmm.h>
#include "icon.h"
-#include "shortcuts.h"
-#include "interface.h"
+
+#include "button.h"
#include "helper/action-context.h"
+#include "ui/interface.h"
+#include "shortcuts.h"
+#include "helper/action.h"
#include <gdk/gdkkeysyms.h>
-#include "button.h"
-
static void sp_button_dispose(GObject *object);
-#if GTK_CHECK_VERSION(3,0,0)
-static void sp_button_get_preferred_width(GtkWidget *widget,
- gint *minimal_width,
- gint *natural_width);
+#if GTK_CHECK_VERSION(3, 0, 0)
+static void sp_button_get_preferred_width(GtkWidget *widget, gint *minimal_width, gint *natural_width);
-static void sp_button_get_preferred_height(GtkWidget *widget,
- gint *minimal_height,
- gint *natural_height);
+static void sp_button_get_preferred_height(GtkWidget *widget, gint *minimal_height, gint *natural_height);
#else
-static void sp_button_size_request (GtkWidget *widget, GtkRequisition *requisition);
+static void sp_button_size_request(GtkWidget *widget, GtkRequisition *requisition);
#endif
-static void sp_button_clicked (GtkButton *button);
-static void sp_button_perform_action (SPButton *button, gpointer data);
-static gint sp_button_process_event (SPButton *button, GdkEvent *event);
+static void sp_button_clicked(GtkButton *button);
+static void sp_button_perform_action(SPButton *button, gpointer data);
+static gint sp_button_process_event(SPButton *button, GdkEvent *event);
-static void sp_button_set_action (SPButton *button, SPAction *action);
-static void sp_button_set_doubleclick_action (SPButton *button, SPAction *action);
-static void sp_button_action_set_active (SPButton *button, bool active);
-static void sp_button_set_composed_tooltip (GtkWidget *widget, SPAction *action);
+static void sp_button_set_action(SPButton *button, SPAction *action);
+static void sp_button_set_doubleclick_action(SPButton *button, SPAction *action);
+static void sp_button_action_set_active(SPButton *button, bool active);
+static void sp_button_set_composed_tooltip(GtkWidget *widget, SPAction *action);
G_DEFINE_TYPE(SPButton, sp_button, GTK_TYPE_TOGGLE_BUTTON);
-static void
-sp_button_class_init (SPButtonClass *klass)
+static void sp_button_class_init(SPButtonClass *klass)
{
- GObjectClass *object_class=G_OBJECT_CLASS(klass);
- GtkWidgetClass *widget_class=GTK_WIDGET_CLASS(klass);
- GtkButtonClass *button_class=GTK_BUTTON_CLASS(klass);
-
- object_class->dispose = sp_button_dispose;
-#if GTK_CHECK_VERSION(3,0,0)
- widget_class->get_preferred_width = sp_button_get_preferred_width;
- widget_class->get_preferred_height = sp_button_get_preferred_height;
+ GObjectClass *object_class = G_OBJECT_CLASS(klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+ GtkButtonClass *button_class = GTK_BUTTON_CLASS(klass);
+
+ object_class->dispose = sp_button_dispose;
+#if GTK_CHECK_VERSION(3, 0, 0)
+ widget_class->get_preferred_width = sp_button_get_preferred_width;
+ widget_class->get_preferred_height = sp_button_get_preferred_height;
#else
- widget_class->size_request = sp_button_size_request;
+ widget_class->size_request = sp_button_size_request;
#endif
- button_class->clicked = sp_button_clicked;
+ button_class->clicked = sp_button_clicked;
}
-static void
-sp_button_init (SPButton *button)
+static void sp_button_init(SPButton *button)
{
- button->action = NULL;
- button->doubleclick_action = NULL;
- new (&button->c_set_active) sigc::connection();
- new (&button->c_set_sensitive) sigc::connection();
+ button->action = NULL;
+ button->doubleclick_action = NULL;
+ new (&button->c_set_active) sigc::connection();
+ new (&button->c_set_sensitive) sigc::connection();
- gtk_container_set_border_width (GTK_CONTAINER (button), 0);
+ gtk_container_set_border_width(GTK_CONTAINER(button), 0);
- gtk_widget_set_can_focus (GTK_WIDGET (button), FALSE);
- gtk_widget_set_can_default (GTK_WIDGET (button), FALSE);
+ gtk_widget_set_can_focus(GTK_WIDGET(button), FALSE);
+ gtk_widget_set_can_default(GTK_WIDGET(button), FALSE);
- g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (sp_button_perform_action), NULL);
- g_signal_connect_after (G_OBJECT (button), "event", G_CALLBACK (sp_button_process_event), NULL);
+ g_signal_connect_after(G_OBJECT(button), "clicked", G_CALLBACK(sp_button_perform_action), NULL);
+ g_signal_connect_after(G_OBJECT(button), "event", G_CALLBACK(sp_button_process_event), NULL);
}
static void sp_button_dispose(GObject *object)
{
- SPButton *button = SP_BUTTON (object);
+ SPButton *button = SP_BUTTON(object);
- if (button->action) {
- sp_button_set_action (button, NULL);
- }
- if (button->doubleclick_action) {
- sp_button_set_doubleclick_action (button, NULL);
- }
+ if (button->action) {
+ sp_button_set_action(button, NULL);
+ }
+ if (button->doubleclick_action) {
+ sp_button_set_doubleclick_action(button, NULL);
+ }
- button->c_set_active.~connection();
- button->c_set_sensitive.~connection();
+ button->c_set_active.~connection();
+ button->c_set_sensitive.~connection();
- (G_OBJECT_CLASS(sp_button_parent_class))->dispose(object);
+ (G_OBJECT_CLASS(sp_button_parent_class))->dispose(object);
}
-
-
-#if GTK_CHECK_VERSION(3,0,0)
+#if GTK_CHECK_VERSION(3, 0, 0)
static void sp_button_get_preferred_width(GtkWidget *widget, gint *minimal_width, gint *natural_width)
{
- GtkWidget *child = gtk_bin_get_child(GTK_BIN (widget));
- GtkStyle *style = gtk_widget_get_style(widget);
-
- if (child) {
- gtk_widget_get_preferred_width(GTK_WIDGET(child), minimal_width, natural_width);
- } else {
- *minimal_width = 0;
- *natural_width = 0;
- }
-
- *minimal_width += 2 + 2 * MAX(2, style->xthickness);
- *natural_width += 2 + 2 * MAX(2, style->xthickness);
+ GtkWidget *child = gtk_bin_get_child(GTK_BIN(widget));
+ GtkStyle *style = gtk_widget_get_style(widget);
+
+ if (child) {
+ gtk_widget_get_preferred_width(GTK_WIDGET(child), minimal_width, natural_width);
+ } else {
+ *minimal_width = 0;
+ *natural_width = 0;
+ }
+
+ *minimal_width += 2 + 2 * MAX(2, style->xthickness);
+ *natural_width += 2 + 2 * MAX(2, style->xthickness);
}
static void sp_button_get_preferred_height(GtkWidget *widget, gint *minimal_height, gint *natural_height)
{
- GtkWidget *child = gtk_bin_get_child(GTK_BIN (widget));
- GtkStyle *style = gtk_widget_get_style(widget);
-
- if (child) {
- gtk_widget_get_preferred_height(GTK_WIDGET(child), minimal_height, natural_height);
- } else {
- *minimal_height = 0;
- *natural_height = 0;
- }
+ GtkWidget *child = gtk_bin_get_child(GTK_BIN(widget));
+ GtkStyle *style = gtk_widget_get_style(widget);
- *minimal_height += 2 + 2 * MAX(2, style->ythickness);
- *natural_height += 2 + 2 * MAX(2, style->ythickness);
+ if (child) {
+ gtk_widget_get_preferred_height(GTK_WIDGET(child), minimal_height, natural_height);
+ } else {
+ *minimal_height = 0;
+ *natural_height = 0;
+ }
+ *minimal_height += 2 + 2 * MAX(2, style->ythickness);
+ *natural_height += 2 + 2 * MAX(2, style->ythickness);
}
#else
static void sp_button_size_request(GtkWidget *widget, GtkRequisition *requisition)
{
- GtkWidget *child = gtk_bin_get_child (GTK_BIN (widget));
- GtkStyle *style = gtk_widget_get_style (widget);
-
- if (child) {
- gtk_widget_size_request (GTK_WIDGET (child), requisition);
- } else {
- requisition->width = 0;
- requisition->height = 0;
- }
-
- requisition->width += 2 + 2 * MAX (2, style->xthickness);
- requisition->height += 2 + 2 * MAX (2, style->ythickness);
+ GtkWidget *child = gtk_bin_get_child(GTK_BIN(widget));
+ GtkStyle *style = gtk_widget_get_style(widget);
+
+ if (child) {
+ gtk_widget_size_request(GTK_WIDGET(child), requisition);
+ } else {
+ requisition->width = 0;
+ requisition->height = 0;
+ }
+
+ requisition->width += 2 + 2 * MAX(2, style->xthickness);
+ requisition->height += 2 + 2 * MAX(2, style->ythickness);
}
#endif
-static void
-sp_button_clicked (GtkButton *button)
+static void sp_button_clicked(GtkButton *button)
{
- SPButton *sp_button=SP_BUTTON (button);
+ SPButton *sp_button = SP_BUTTON(button);
- if (sp_button->type == SP_BUTTON_TYPE_TOGGLE) {
- (GTK_BUTTON_CLASS(sp_button_parent_class))->clicked (button);
- }
+ if (sp_button->type == SP_BUTTON_TYPE_TOGGLE) {
+ (GTK_BUTTON_CLASS(sp_button_parent_class))->clicked(button);
+ }
}
-static gint
-sp_button_process_event (SPButton *button, GdkEvent *event)
+static gint sp_button_process_event(SPButton *button, GdkEvent *event)
{
- switch (event->type) {
- case GDK_2BUTTON_PRESS:
- if (button->doubleclick_action) {
- sp_action_perform (button->doubleclick_action, NULL);
- }
- return TRUE;
- break;
- default:
- break;
- }
-
- return FALSE;
+ switch (event->type) {
+ case GDK_2BUTTON_PRESS:
+ if (button->doubleclick_action) {
+ sp_action_perform(button->doubleclick_action, NULL);
+ }
+ return TRUE;
+ break;
+ default:
+ break;
+ }
+
+ return FALSE;
}
-static void
-sp_button_perform_action (SPButton *button, gpointer /*data*/)
+static void sp_button_perform_action(SPButton *button, gpointer /*data*/)
{
- if (button->action) {
- sp_action_perform (button->action, NULL);
- }
+ if (button->action) {
+ sp_action_perform(button->action, NULL);
+ }
}
-
-GtkWidget *
-sp_button_new( Inkscape::IconSize size, SPButtonType type, SPAction *action, SPAction *doubleclick_action )
+GtkWidget *sp_button_new(Inkscape::IconSize size, SPButtonType type, SPAction *action, SPAction *doubleclick_action)
{
- SPButton *button = SP_BUTTON(g_object_new(SP_TYPE_BUTTON, NULL));
+ SPButton *button = SP_BUTTON(g_object_new(SP_TYPE_BUTTON, NULL));
- button->type = type;
- button->lsize = CLAMP( size, Inkscape::ICON_SIZE_MENU, Inkscape::ICON_SIZE_DECORATION );
+ button->type = type;
+ button->lsize = CLAMP(size, Inkscape::ICON_SIZE_MENU, Inkscape::ICON_SIZE_DECORATION);
- sp_button_set_action (button, action);
- if (doubleclick_action)
- sp_button_set_doubleclick_action (button, doubleclick_action);
+ sp_button_set_action(button, action);
+ if (doubleclick_action)
+ sp_button_set_doubleclick_action(button, doubleclick_action);
- // The Inkscape style is no-relief buttons
- gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
+ // The Inkscape style is no-relief buttons
+ gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
- return GTK_WIDGET(button);
+ return GTK_WIDGET(button);
}
-void
-sp_button_toggle_set_down (SPButton *button, gboolean down)
+void sp_button_toggle_set_down(SPButton *button, gboolean down)
{
- g_return_if_fail (button->type == SP_BUTTON_TYPE_TOGGLE);
- g_signal_handlers_block_by_func (G_OBJECT (button), (gpointer)G_CALLBACK (sp_button_perform_action), NULL);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), (unsigned int)down);
- g_signal_handlers_unblock_by_func (G_OBJECT (button), (gpointer)G_CALLBACK (sp_button_perform_action), NULL);
+ g_return_if_fail(button->type == SP_BUTTON_TYPE_TOGGLE);
+ g_signal_handlers_block_by_func(G_OBJECT(button), (gpointer)G_CALLBACK(sp_button_perform_action), NULL);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), (unsigned int)down);
+ g_signal_handlers_unblock_by_func(G_OBJECT(button), (gpointer)G_CALLBACK(sp_button_perform_action), NULL);
}
-static void
-sp_button_set_doubleclick_action (SPButton *button, SPAction *action)
+static void sp_button_set_doubleclick_action(SPButton *button, SPAction *action)
{
- if (button->doubleclick_action) {
- g_object_unref (button->doubleclick_action);
- }
- button->doubleclick_action = action;
- if (action) {
- g_object_ref(action);
- }
-
+ if (button->doubleclick_action) {
+ g_object_unref(button->doubleclick_action);
+ }
+ button->doubleclick_action = action;
+ if (action) {
+ g_object_ref(action);
+ }
}
-static void
-sp_button_set_action (SPButton *button, SPAction *action)
+static void sp_button_set_action(SPButton *button, SPAction *action)
{
- GtkWidget *child;
-
- if (button->action) {
- button->c_set_active.disconnect();
- button->c_set_sensitive.disconnect();
- child = gtk_bin_get_child (GTK_BIN (button));
- if (child) {
- gtk_container_remove (GTK_CONTAINER (button), child);
- }
- g_object_unref(button->action);
- }
- button->action = action;
- if (action) {
- g_object_ref(action);
- button->c_set_active = action->signal_set_active.connect(
- sigc::bind<0>(
- sigc::ptr_fun(&sp_button_action_set_active),
- SP_BUTTON(button)));
- button->c_set_sensitive = action->signal_set_sensitive.connect(
- sigc::bind<0>(
- sigc::ptr_fun(&gtk_widget_set_sensitive),
- GTK_WIDGET(button)));
- if (action->image) {
- child = sp_icon_new (button->lsize, action->image);
- gtk_widget_show (child);
- gtk_container_add (GTK_CONTAINER (button), child);
- }
- }
-
- sp_button_set_composed_tooltip(GTK_WIDGET(button), action);
+ GtkWidget *child;
+
+ if (button->action) {
+ button->c_set_active.disconnect();
+ button->c_set_sensitive.disconnect();
+ child = gtk_bin_get_child(GTK_BIN(button));
+ if (child) {
+ gtk_container_remove(GTK_CONTAINER(button), child);
+ }
+ g_object_unref(button->action);
+ }
+ button->action = action;
+ if (action) {
+ g_object_ref(action);
+ button->c_set_active = action->signal_set_active.connect(
+ sigc::bind<0>(sigc::ptr_fun(&sp_button_action_set_active), SP_BUTTON(button)));
+ button->c_set_sensitive = action->signal_set_sensitive.connect(
+ sigc::bind<0>(sigc::ptr_fun(&gtk_widget_set_sensitive), GTK_WIDGET(button)));
+ if (action->image) {
+ child = sp_icon_new(button->lsize, action->image);
+ gtk_widget_show(child);
+ gtk_container_add(GTK_CONTAINER(button), child);
+ }
+ }
+
+ sp_button_set_composed_tooltip(GTK_WIDGET(button), action);
}
-static void
-sp_button_action_set_active (SPButton *button, bool active)
+static void sp_button_action_set_active(SPButton *button, bool active)
{
- if (button->type != SP_BUTTON_TYPE_TOGGLE) {
- return;
- }
-
- /* temporarily lobotomized until SPActions are per-view */
- if (0 && !active != !SP_BUTTON_IS_DOWN (button)) {
- sp_button_toggle_set_down (button, active);
- }
+ if (button->type != SP_BUTTON_TYPE_TOGGLE) {
+ return;
+ }
+
+ /* temporarily lobotomized until SPActions are per-view */
+ if (0 && !active != !SP_BUTTON_IS_DOWN(button)) {
+ sp_button_toggle_set_down(button, active);
+ }
}
static void sp_button_set_composed_tooltip(GtkWidget *widget, SPAction *action)
{
if (action) {
- unsigned int shortcut = sp_shortcut_get_primary (action->verb);
+ unsigned int shortcut = sp_shortcut_get_primary(action->verb);
if (shortcut != GDK_KEY_VoidSymbol) {
// there's both action and shortcut
gchar *key = sp_shortcut_get_label(shortcut);
- gchar *tip = g_strdup_printf ("%s (%s)", action->tip, key);
+ gchar *tip = g_strdup_printf("%s (%s)", action->tip, key);
gtk_widget_set_tooltip_text(widget, tip);
g_free(tip);
g_free(key);
@@ -302,18 +275,14 @@ static void sp_button_set_composed_tooltip(GtkWidget *widget, SPAction *action)
}
}
-GtkWidget *
-sp_button_new_from_data( Inkscape::IconSize size,
- SPButtonType type,
- Inkscape::UI::View::View *view,
- const gchar *name,
- const gchar *tip )
+GtkWidget *sp_button_new_from_data(Inkscape::IconSize size, SPButtonType type, Inkscape::UI::View::View *view,
+ const gchar *name, const gchar *tip)
{
- GtkWidget *button;
- SPAction *action=sp_action_new(Inkscape::ActionContext(view), name, name, tip, name, 0);
- button = sp_button_new (size, type, action, NULL);
- g_object_unref(action);
- return button;
+ GtkWidget *button;
+ SPAction *action = sp_action_new(Inkscape::ActionContext(view), name, name, tip, name, 0);
+ button = sp_button_new(size, type, action, NULL);
+ g_object_unref(action);
+ return button;
}
/*
@@ -325,4 +294,4 @@ sp_button_new_from_data( Inkscape::IconSize size,
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 :
diff --git a/src/widgets/button.h b/src/widgets/button.h
index 41863357d..2bceb5e97 100644
--- a/src/widgets/button.h
+++ b/src/widgets/button.h
@@ -1,7 +1,7 @@
-#ifndef __SP_BUTTON_H__
-#define __SP_BUTTON_H__
+#ifndef SEEN_SP_BUTTON_H
+#define SEEN_SP_BUTTON_H
-/*
+/**
* Generic button widget
*
* Author:
@@ -17,10 +17,18 @@
#define SP_IS_BUTTON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_BUTTON))
#include <gtk/gtk.h>
-#include <sigc++/sigc++.h>
-#include "helper/action.h"
+#include <sigc++/connection.h>
#include "icon-size.h"
+struct SPAction;
+
+namespace Inkscape {
+namespace UI {
+namespace View {
+class View;
+}
+}
+}
typedef enum {
SP_BUTTON_TYPE_NORMAL,
@@ -61,6 +69,15 @@ GtkWidget *sp_button_new_from_data (Inkscape::IconSize size,
const gchar *name,
const gchar *tip);
+#endif // !SEEN_SP_BUTTON_H
-
-#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 :
diff --git a/src/widgets/calligraphy-toolbar.cpp b/src/widgets/calligraphy-toolbar.cpp
index 9c0393cd9..4ae6427ad 100644
--- a/src/widgets/calligraphy-toolbar.cpp
+++ b/src/widgets/calligraphy-toolbar.cpp
@@ -34,9 +34,9 @@
#include "desktop.h"
#include "document-undo.h"
-#include "ege-adjustment-action.h"
-#include "ege-select-one-action.h"
-#include "ink-action.h"
+#include "widgets/ege-adjustment-action.h"
+#include "widgets/ege-select-one-action.h"
+#include "widgets/ink-action.h"
#include "preferences.h"
#include "toolbox.h"
#include "ui/icon-names.h"
diff --git a/src/widgets/connector-toolbar.cpp b/src/widgets/connector-toolbar.cpp
index 9bbc1bbb4..6ce926dc1 100644
--- a/src/widgets/connector-toolbar.cpp
+++ b/src/widgets/connector-toolbar.cpp
@@ -35,10 +35,10 @@
#include "desktop-handles.h"
#include "desktop.h"
#include "document-undo.h"
-#include "ege-adjustment-action.h"
+#include "widgets/ege-adjustment-action.h"
#include "enums.h"
#include "graphlayout.h"
-#include "ink-action.h"
+#include "widgets/ink-action.h"
#include "inkscape.h"
#include "preferences.h"
#include "selection.h"
diff --git a/src/widgets/dash-selector.cpp b/src/widgets/dash-selector.cpp
index fce7a9d9f..479895022 100644
--- a/src/widgets/dash-selector.cpp
+++ b/src/widgets/dash-selector.cpp
@@ -25,7 +25,7 @@
#include <2geom/coord.h>
#include "style.h"
-#include "dialogs/dialog-events.h"
+#include "ui/dialog-events.h"
#include "preferences.h"
#include "ui/widget/spinbutton.h"
#include "display/cairo-utils.h"
diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp
index 1b4648286..9c8dac7dc 100644
--- a/src/widgets/desktop-widget.cpp
+++ b/src/widgets/desktop-widget.cpp
@@ -38,7 +38,7 @@
#include "display/canvas-arena.h"
#include "document.h"
#include "ege-color-prof-tracker.h"
-#include "ege-select-one-action.h"
+#include "widgets/ege-select-one-action.h"
#include <extension/db.h>
#include "file.h"
#include "helper/action.h"
@@ -46,7 +46,7 @@
#include "util/units.h"
#include "ui/widget/unit-tracker.h"
#include "inkscape-private.h"
-#include "interface.h"
+#include "ui/interface.h"
#include "macros.h"
#include "preferences.h"
#include "sp-image.h"
@@ -358,7 +358,7 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw )
{
using Inkscape::UI::Dialogs::SwatchesPanel;
- dtw->panels = new SwatchesPanel("/embedded/swatches");
+ dtw->panels = new SwatchesPanel("/embedded/swatches" /*false*/);
dtw->panels->setOrientation(SP_ANCHOR_SOUTH);
#if GTK_CHECK_VERSION(3,0,0)
diff --git a/src/widgets/dropper-toolbar.cpp b/src/widgets/dropper-toolbar.cpp
index 478d0c1a4..45ed9ead4 100644
--- a/src/widgets/dropper-toolbar.cpp
+++ b/src/widgets/dropper-toolbar.cpp
@@ -32,8 +32,8 @@
#include "dropper-toolbar.h"
#include "document-undo.h"
-#include "ege-output-action.h"
-#include "ink-action.h"
+#include "widgets/ege-output-action.h"
+#include "widgets/ink-action.h"
#include "preferences.h"
#include "widgets/spinbutton-events.h"
diff --git a/src/widgets/eek-preview.h b/src/widgets/eek-preview.h
index e4c724cc5..883ce713e 100644
--- a/src/widgets/eek-preview.h
+++ b/src/widgets/eek-preview.h
@@ -37,7 +37,6 @@
#ifndef SEEN_EEK_PREVIEW_H
#define SEEN_EEK_PREVIEW_H
-#include <gdk/gdk.h>
#include <gtk/gtk.h>
/**
diff --git a/src/widgets/ege-adjustment-action.cpp b/src/widgets/ege-adjustment-action.cpp
new file mode 100644
index 000000000..d89a6e3f1
--- /dev/null
+++ b/src/widgets/ege-adjustment-action.cpp
@@ -0,0 +1,1113 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ */
+/* ***** 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 Adjustment Action.
+ *
+ * The Initial Developer of the Original Code is
+ * Jon A. Cruz.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * 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 ***** */
+
+/* Note: this file should be kept compilable as both .cpp and .c */
+
+#include <cmath>
+#include <string.h>
+
+#include "widgets/icon.h"
+#include <gdk/gdkkeysyms.h>
+
+#include "icon-size.h"
+#include "widgets/ege-adjustment-action.h"
+#include "ui/widget/gimpspinscale.h"
+#include "ui/icon-names.h"
+
+
+static void ege_adjustment_action_finalize( GObject* object );
+static void ege_adjustment_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec );
+static void ege_adjustment_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec );
+
+static GtkWidget* create_menu_item( GtkAction* action );
+static GtkWidget* create_tool_item( GtkAction* action );
+static void connect_proxy( GtkAction *action, GtkWidget *proxy );
+static void disconnect_proxy( GtkAction *action, GtkWidget *proxy );
+
+static gboolean focus_in_cb( GtkWidget *widget, GdkEventKey *event, gpointer data );
+static gboolean focus_out_cb( GtkWidget *widget, GdkEventKey *event, gpointer data );
+static gboolean keypress_cb( GtkWidget *widget, GdkEventKey *event, gpointer data );
+
+static void ege_adjustment_action_defocus( EgeAdjustmentAction* action );
+
+static void egeAct_free_description( gpointer data, gpointer user_data );
+static void egeAct_free_all_descriptions( EgeAdjustmentAction* action );
+
+static EgeCreateAdjWidgetCB gFactoryCb = 0;
+static GQuark gDataName = 0;
+
+enum {
+ APPEARANCE_UNKNOWN = -1,
+ APPEARANCE_NONE = 0,
+ APPEARANCE_FULL, /* label, then all choices represented by separate buttons */
+ APPEARANCE_COMPACT, /* label, then choices in a drop-down menu */
+ APPEARANCE_MINIMAL, /* no label, just choices in a drop-down menu */
+};
+
+/* TODO need to have appropriate icons setup for these: */
+static const gchar *floogles[] = {
+ INKSCAPE_ICON("list-remove"),
+ INKSCAPE_ICON("list-add"),
+ INKSCAPE_ICON("go-down"),
+ INKSCAPE_ICON("help-about"),
+ INKSCAPE_ICON("go-up"),
+ 0};
+
+typedef struct _EgeAdjustmentDescr EgeAdjustmentDescr;
+
+struct _EgeAdjustmentDescr
+{
+ gchar* descr;
+ gdouble value;
+};
+
+struct _EgeAdjustmentActionPrivate
+{
+ GtkAdjustment* adj;
+ GtkWidget* focusWidget;
+ gdouble climbRate;
+ guint digits;
+ gdouble epsilon;
+ gchar* format;
+ gchar* selfId;
+ EgeWidgetFixup toolPost;
+ gdouble lastVal;
+ gdouble step;
+ gdouble page;
+ gint appearanceMode;
+ gboolean transferFocus;
+ GList* descriptions;
+ gchar* appearance;
+ gchar* iconId;
+ Inkscape::IconSize iconSize;
+ Inkscape::UI::Widget::UnitTracker *unitTracker;
+};
+
+#define EGE_ADJUSTMENT_ACTION_GET_PRIVATE( o ) ( G_TYPE_INSTANCE_GET_PRIVATE( (o), EGE_ADJUSTMENT_ACTION_TYPE, EgeAdjustmentActionPrivate ) )
+
+enum {
+ PROP_ADJUSTMENT = 1,
+ PROP_FOCUS_WIDGET,
+ PROP_CLIMB_RATE,
+ PROP_DIGITS,
+ PROP_SELFID,
+ PROP_TOOL_POST,
+ PROP_APPEARANCE,
+ PROP_ICON_ID,
+ PROP_ICON_SIZE,
+ PROP_UNIT_TRACKER
+};
+
+enum {
+ BUMP_TOP = 0,
+ BUMP_PAGE_UP,
+ BUMP_UP,
+ BUMP_NONE,
+ BUMP_DOWN,
+ BUMP_PAGE_DOWN,
+ BUMP_BOTTOM,
+ BUMP_CUSTOM = 100
+};
+
+G_DEFINE_TYPE(EgeAdjustmentAction, ege_adjustment_action, GTK_TYPE_ACTION);
+
+static void ege_adjustment_action_class_init( EgeAdjustmentActionClass* klass )
+{
+ if ( klass ) {
+ GObjectClass * objClass = G_OBJECT_CLASS( klass );
+
+ gDataName = g_quark_from_string("ege-adj-action");
+
+
+ objClass->finalize = ege_adjustment_action_finalize;
+
+ objClass->get_property = ege_adjustment_action_get_property;
+ objClass->set_property = ege_adjustment_action_set_property;
+
+ klass->parent_class.create_menu_item = create_menu_item;
+ klass->parent_class.create_tool_item = create_tool_item;
+ klass->parent_class.connect_proxy = connect_proxy;
+ klass->parent_class.disconnect_proxy = disconnect_proxy;
+
+ g_object_class_install_property( objClass,
+ PROP_ADJUSTMENT,
+ g_param_spec_object( "adjustment",
+ "Adjustment",
+ "The adjustment to change",
+ GTK_TYPE_ADJUSTMENT,
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ g_object_class_install_property( objClass,
+ PROP_FOCUS_WIDGET,
+ g_param_spec_pointer( "focus-widget",
+ "Focus Widget",
+ "The widget to return focus to",
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ g_object_class_install_property( objClass,
+ PROP_CLIMB_RATE,
+ g_param_spec_double( "climb-rate",
+ "Climb Rate",
+ "The acelleraton rate",
+ 0.0, G_MAXDOUBLE, 0.0,
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ g_object_class_install_property( objClass,
+ PROP_DIGITS,
+ g_param_spec_uint( "digits",
+ "Digits",
+ "The number of digits to show",
+ 0, 20, 0,
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ g_object_class_install_property( objClass,
+ PROP_SELFID,
+ g_param_spec_string( "self-id",
+ "Self ID",
+ "Marker for self pointer",
+ 0,
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ g_object_class_install_property( objClass,
+ PROP_TOOL_POST,
+ g_param_spec_pointer( "tool-post",
+ "Tool Widget post process",
+ "Function for final adjustments",
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ g_object_class_install_property( objClass,
+ PROP_APPEARANCE,
+ g_param_spec_string( "appearance",
+ "Appearance hint",
+ "A hint for how to display",
+ "",
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ g_object_class_install_property( objClass,
+ PROP_ICON_ID,
+ g_param_spec_string( "iconId",
+ "Icon ID",
+ "The id for the icon",
+ "",
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ g_object_class_install_property( objClass,
+ PROP_ICON_SIZE,
+ g_param_spec_int( "iconSize",
+ "Icon Size",
+ "The size the icon",
+ (int)Inkscape::ICON_SIZE_MENU,
+ (int)Inkscape::ICON_SIZE_DECORATION,
+ (int)Inkscape::ICON_SIZE_SMALL_TOOLBAR,
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ g_object_class_install_property( objClass,
+ PROP_UNIT_TRACKER,
+ g_param_spec_pointer( "unit_tracker",
+ "Unit Tracker",
+ "The widget that keeps track of the unit",
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ g_type_class_add_private( klass, sizeof(EgeAdjustmentActionClass) );
+ }
+}
+
+void ege_adjustment_action_set_compact_tool_factory( EgeCreateAdjWidgetCB factoryCb )
+{
+ gFactoryCb = factoryCb;
+}
+
+static void ege_adjustment_action_init( EgeAdjustmentAction* action )
+{
+ action->private_data = EGE_ADJUSTMENT_ACTION_GET_PRIVATE( action );
+ action->private_data->adj = 0;
+ action->private_data->focusWidget = 0;
+ action->private_data->climbRate = 0.0;
+ action->private_data->digits = 2;
+ action->private_data->epsilon = 0.009;
+ action->private_data->format = g_strdup_printf("%%0.%df%%s%%s", action->private_data->digits);
+ action->private_data->selfId = 0;
+ action->private_data->toolPost = 0;
+ action->private_data->lastVal = 0.0;
+ action->private_data->step = 0.0;
+ action->private_data->page = 0.0;
+ action->private_data->appearanceMode = APPEARANCE_NONE;
+ action->private_data->transferFocus = FALSE;
+ action->private_data->descriptions = 0;
+ action->private_data->appearance = 0;
+ action->private_data->iconId = 0;
+ action->private_data->iconSize = Inkscape::ICON_SIZE_SMALL_TOOLBAR;
+ action->private_data->unitTracker = NULL;
+}
+
+static void ege_adjustment_action_finalize( GObject* object )
+{
+ EgeAdjustmentAction* action = 0;
+ g_return_if_fail( object != NULL );
+ g_return_if_fail( IS_EGE_ADJUSTMENT_ACTION(object) );
+
+ action = EGE_ADJUSTMENT_ACTION( object );
+
+ // g_free(NULL) does nothing
+ g_free( action->private_data->format );
+ g_free( action->private_data->selfId );
+ g_free( action->private_data->appearance );
+ g_free( action->private_data->iconId );
+
+ egeAct_free_all_descriptions( action );
+
+ if ( G_OBJECT_CLASS(ege_adjustment_action_parent_class)->finalize ) {
+ (*G_OBJECT_CLASS(ege_adjustment_action_parent_class)->finalize)(object);
+ }
+}
+
+EgeAdjustmentAction* ege_adjustment_action_new( GtkAdjustment* adjustment,
+ const gchar *name,
+ const gchar *label,
+ const gchar *tooltip,
+ const gchar *stock_id,
+ gdouble climb_rate,
+ guint digits,
+ Inkscape::UI::Widget::UnitTracker *unit_tracker )
+{
+ GObject* obj = (GObject*)g_object_new( EGE_ADJUSTMENT_ACTION_TYPE,
+ "name", name,
+ "label", label,
+ "tooltip", tooltip,
+ "stock_id", stock_id,
+ "adjustment", adjustment,
+ "climb-rate", climb_rate,
+ "digits", digits,
+ "unit_tracker", unit_tracker,
+ NULL );
+
+ EgeAdjustmentAction* action = EGE_ADJUSTMENT_ACTION( obj );
+
+ return action;
+}
+
+static void ege_adjustment_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec )
+{
+ EgeAdjustmentAction* action = EGE_ADJUSTMENT_ACTION( obj );
+ switch ( propId ) {
+ case PROP_ADJUSTMENT:
+ g_value_set_object( value, action->private_data->adj );
+ break;
+
+ case PROP_FOCUS_WIDGET:
+ g_value_set_pointer( value, action->private_data->focusWidget );
+ break;
+
+ case PROP_CLIMB_RATE:
+ g_value_set_double( value, action->private_data->climbRate );
+ break;
+
+ case PROP_DIGITS:
+ g_value_set_uint( value, action->private_data->digits );
+ break;
+
+ case PROP_SELFID:
+ g_value_set_string( value, action->private_data->selfId );
+ break;
+
+ case PROP_TOOL_POST:
+ g_value_set_pointer( value, (void*)action->private_data->toolPost );
+ break;
+
+ case PROP_APPEARANCE:
+ g_value_set_string( value, action->private_data->appearance );
+ break;
+
+ case PROP_ICON_ID:
+ g_value_set_string( value, action->private_data->iconId );
+ break;
+
+ case PROP_ICON_SIZE:
+ g_value_set_int( value, action->private_data->iconSize );
+ break;
+
+ case PROP_UNIT_TRACKER:
+ g_value_set_pointer( value, action->private_data->unitTracker );
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
+ }
+}
+
+void ege_adjustment_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec )
+{
+ EgeAdjustmentAction* action = EGE_ADJUSTMENT_ACTION( obj );
+ switch ( propId ) {
+ case PROP_ADJUSTMENT:
+ {
+ action->private_data->adj = GTK_ADJUSTMENT( g_value_get_object( value ) );
+ g_object_get( G_OBJECT(action->private_data->adj),
+ "step-increment", &action->private_data->step,
+ "page-increment", &action->private_data->page,
+ NULL );
+ }
+ break;
+
+ case PROP_FOCUS_WIDGET:
+ {
+ /* TODO unhook prior */
+ action->private_data->focusWidget = (GtkWidget*)g_value_get_pointer( value );
+ }
+ break;
+
+ case PROP_CLIMB_RATE:
+ {
+ /* TODO pass on */
+ action->private_data->climbRate = g_value_get_double( value );
+ }
+ break;
+
+ case PROP_DIGITS:
+ {
+ /* TODO pass on */
+ action->private_data->digits = g_value_get_uint( value );
+ switch ( action->private_data->digits ) {
+ case 0: action->private_data->epsilon = 0.9; break;
+ case 1: action->private_data->epsilon = 0.09; break;
+ case 2: action->private_data->epsilon = 0.009; break;
+ case 3: action->private_data->epsilon = 0.0009; break;
+ case 4: action->private_data->epsilon = 0.00009; break;
+ }
+ if ( action->private_data->format ) {
+ g_free( action->private_data->format );
+ }
+ action->private_data->format = g_strdup_printf("%%0.%df%%s%%s", action->private_data->digits);
+ }
+ break;
+
+ case PROP_SELFID:
+ {
+ /* TODO pass on */
+ gchar* prior = action->private_data->selfId;
+ action->private_data->selfId = g_value_dup_string( value );
+ g_free( prior );
+ }
+ break;
+
+ case PROP_TOOL_POST:
+ {
+ action->private_data->toolPost = (EgeWidgetFixup)g_value_get_pointer( value );
+ }
+ break;
+
+ case PROP_APPEARANCE:
+ {
+ gchar* tmp = action->private_data->appearance;
+ gchar* newVal = g_value_dup_string( value );
+ action->private_data->appearance = newVal;
+ g_free( tmp );
+
+ if ( !action->private_data->appearance || (strcmp("", newVal) == 0) ) {
+ action->private_data->appearanceMode = APPEARANCE_NONE;
+ } else if ( strcmp("full", newVal) == 0 ) {
+ action->private_data->appearanceMode = APPEARANCE_FULL;
+ } else if ( strcmp("compact", newVal) == 0 ) {
+ action->private_data->appearanceMode = APPEARANCE_COMPACT;
+ } else if ( strcmp("minimal", newVal) == 0 ) {
+ action->private_data->appearanceMode = APPEARANCE_MINIMAL;
+ } else {
+ action->private_data->appearanceMode = APPEARANCE_UNKNOWN;
+ }
+ }
+ break;
+
+ case PROP_ICON_ID:
+ {
+ gchar* tmp = action->private_data->iconId;
+ action->private_data->iconId = g_value_dup_string( value );
+ g_free( tmp );
+ }
+ break;
+
+ case PROP_ICON_SIZE:
+ {
+ action->private_data->iconSize = (Inkscape::IconSize)g_value_get_int( value );
+ }
+ break;
+
+ case PROP_UNIT_TRACKER:
+ {
+ action->private_data->unitTracker = (Inkscape::UI::Widget::UnitTracker*)g_value_get_pointer( value );
+ }
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
+ }
+}
+
+GtkAdjustment* ege_adjustment_action_get_adjustment( EgeAdjustmentAction* action )
+{
+ g_return_val_if_fail( IS_EGE_ADJUSTMENT_ACTION(action), NULL );
+
+ return action->private_data->adj;
+}
+
+void ege_adjustment_action_set_focuswidget( EgeAdjustmentAction* action, GtkWidget* widget )
+{
+ g_return_if_fail( IS_EGE_ADJUSTMENT_ACTION(action) );
+
+ /* TODO unhook prior */
+
+ action->private_data->focusWidget = widget;
+}
+
+GtkWidget* ege_adjustment_action_get_focuswidget( EgeAdjustmentAction* action )
+{
+ g_return_val_if_fail( IS_EGE_ADJUSTMENT_ACTION(action), NULL );
+
+ return action->private_data->focusWidget;
+}
+
+static void egeAct_free_description( gpointer data, gpointer user_data ) {
+ (void)user_data;
+ if ( data ) {
+ EgeAdjustmentDescr* descr = (EgeAdjustmentDescr*)data;
+ if ( descr->descr ) {
+ g_free( descr->descr );
+ descr->descr = 0;
+ }
+ g_free( descr );
+ }
+}
+
+static void egeAct_free_all_descriptions( EgeAdjustmentAction* action )
+{
+ if ( action->private_data->descriptions ) {
+ g_list_foreach( action->private_data->descriptions, egeAct_free_description, 0 );
+ g_list_free( action->private_data->descriptions );
+ action->private_data->descriptions = 0;
+ }
+}
+
+static gint egeAct_compare_descriptions( gconstpointer a, gconstpointer b )
+{
+ gint val = 0;
+
+ EgeAdjustmentDescr const * aa = (EgeAdjustmentDescr const *)a;
+ EgeAdjustmentDescr const * bb = (EgeAdjustmentDescr const *)b;
+
+ if ( aa && bb ) {
+ if ( aa->value < bb->value ) {
+ val = -1;
+ } else if ( aa->value > bb->value ) {
+ val = 1;
+ }
+ }
+
+ return val;
+}
+
+void ege_adjustment_action_set_descriptions( EgeAdjustmentAction* action, gchar const** descriptions, gdouble const* values, guint count )
+{
+ g_return_if_fail( IS_EGE_ADJUSTMENT_ACTION(action) );
+
+ egeAct_free_all_descriptions( action );
+
+ if ( count && descriptions && values ) {
+ guint i = 0;
+ for ( i = 0; i < count; i++ ) {
+ EgeAdjustmentDescr* descr = g_new0( EgeAdjustmentDescr, 1 );
+ descr->descr = descriptions[i] ? g_strdup( descriptions[i] ) : 0;
+ descr->value = values[i];
+ action->private_data->descriptions = g_list_insert_sorted( action->private_data->descriptions, (gpointer)descr, egeAct_compare_descriptions );
+ }
+ }
+}
+
+void ege_adjustment_action_set_appearance( EgeAdjustmentAction* action, gchar const* val )
+{
+ g_object_set( G_OBJECT(action), "appearance", val, NULL );
+}
+
+static void process_menu_action( GtkWidget* obj, gpointer data )
+{
+ GtkCheckMenuItem* item = GTK_CHECK_MENU_ITEM(obj);
+ if ( gtk_check_menu_item_get_active (item)) {
+ EgeAdjustmentAction* act = (EgeAdjustmentAction*)g_object_get_qdata( G_OBJECT(obj), gDataName );
+ gint what = GPOINTER_TO_INT(data);
+
+
+ gdouble base = gtk_adjustment_get_value( act->private_data->adj );
+ gdouble lower = 0.0;
+ gdouble upper = 0.0;
+ gdouble step = 0.0;
+ gdouble page = 0.0;
+ g_object_get( G_OBJECT(act->private_data->adj),
+ "lower", &lower,
+ "upper", &upper,
+ "step-increment", &step,
+ "page-increment", &page,
+ NULL );
+
+ switch ( what ) {
+ case BUMP_TOP:
+ gtk_adjustment_set_value( act->private_data->adj, upper );
+ break;
+
+ case BUMP_PAGE_UP:
+ gtk_adjustment_set_value( act->private_data->adj, base + page );
+ break;
+
+ case BUMP_UP:
+ gtk_adjustment_set_value( act->private_data->adj, base + step );
+ break;
+
+ case BUMP_DOWN:
+ gtk_adjustment_set_value( act->private_data->adj, base - step );
+ break;
+
+ case BUMP_PAGE_DOWN:
+ gtk_adjustment_set_value( act->private_data->adj, base - page );
+ break;
+
+ case BUMP_BOTTOM:
+ gtk_adjustment_set_value( act->private_data->adj, lower );
+ break;
+
+ default:
+ if ( what >= BUMP_CUSTOM ) {
+ guint index = what - BUMP_CUSTOM;
+ if ( index < g_list_length( act->private_data->descriptions ) ) {
+ EgeAdjustmentDescr* descr = (EgeAdjustmentDescr*)g_list_nth_data( act->private_data->descriptions, index );
+ if ( descr ) {
+ gtk_adjustment_set_value( act->private_data->adj, descr->value );
+ }
+ }
+ }
+ }
+ }
+}
+
+static void create_single_menu_item( GCallback toggleCb, int val, GtkWidget* menu, EgeAdjustmentAction* act, GtkWidget** dst, GSList** group, gdouble num, gboolean active )
+{
+ char* str = 0;
+ EgeAdjustmentDescr* marker = 0;
+ GList* cur = act->private_data->descriptions;
+
+ while ( cur ) {
+ EgeAdjustmentDescr* descr = (EgeAdjustmentDescr*)cur->data;
+ gdouble delta = num - descr->value;
+ if ( delta < 0.0 ) {
+ delta = -delta;
+ }
+ if ( delta < act->private_data->epsilon ) {
+ marker = descr;
+ break;
+ }
+ cur = g_list_next( cur );
+ }
+
+ str = g_strdup_printf( act->private_data->format, num,
+ ((marker && marker->descr) ? ": " : ""),
+ ((marker && marker->descr) ? marker->descr : ""));
+
+ *dst = gtk_radio_menu_item_new_with_label( *group, str );
+ if ( !*group) {
+ *group = gtk_radio_menu_item_get_group( GTK_RADIO_MENU_ITEM(*dst) );
+ }
+ if ( active ) {
+ gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(*dst), TRUE );
+ }
+ gtk_menu_shell_append( GTK_MENU_SHELL(menu), *dst );
+ g_object_set_qdata( G_OBJECT(*dst), gDataName, act );
+
+ g_signal_connect( G_OBJECT(*dst), "toggled", toggleCb, GINT_TO_POINTER(val) );
+
+ g_free(str);
+}
+
+static GList* flush_explicit_items( GList* descriptions,
+ GCallback toggleCb,
+ int val,
+ GtkWidget* menu,
+ EgeAdjustmentAction* act,
+ GtkWidget** dst,
+ GSList** group,
+ gdouble num )
+{
+ GList* cur = descriptions;
+
+ if ( cur ) {
+ gdouble valUpper = num + act->private_data->epsilon;
+ gdouble valLower = num - act->private_data->epsilon;
+
+ EgeAdjustmentDescr* descr = (EgeAdjustmentDescr*)cur->data;
+
+ while ( cur && descr && (descr->value >= valLower) ) {
+ if ( descr->value > valUpper ) {
+ create_single_menu_item( toggleCb, val + g_list_position(act->private_data->descriptions, cur), menu, act, dst, group, descr->value, FALSE );
+ }
+
+ cur = g_list_previous( cur );
+ descr = cur ? (EgeAdjustmentDescr*)cur->data : 0;
+ }
+ }
+
+ return cur;
+}
+
+static GtkWidget* create_popup_number_menu( EgeAdjustmentAction* act )
+{
+ GtkWidget* menu = gtk_menu_new();
+
+ GSList* group = 0;
+ GtkWidget* single = 0;
+
+ GList* addOns = g_list_last( act->private_data->descriptions );
+
+ gdouble base = gtk_adjustment_get_value( act->private_data->adj );
+ gdouble lower = 0.0;
+ gdouble upper = 0.0;
+ gdouble step = 0.0;
+ gdouble page = 0.0;
+ g_object_get( G_OBJECT(act->private_data->adj),
+ "lower", &lower,
+ "upper", &upper,
+ "step-increment", &step,
+ "page-increment", &page,
+ NULL );
+
+
+ if ( base < upper ) {
+ addOns = flush_explicit_items( addOns, G_CALLBACK(process_menu_action), BUMP_CUSTOM, menu, act, &single, &group, upper );
+ create_single_menu_item( G_CALLBACK(process_menu_action), BUMP_TOP, menu, act, &single, &group, upper, FALSE );
+ if ( (base + page) < upper ) {
+ addOns = flush_explicit_items( addOns, G_CALLBACK(process_menu_action), BUMP_CUSTOM, menu, act, &single, &group, base + page );
+ create_single_menu_item( G_CALLBACK(process_menu_action), BUMP_PAGE_UP, menu, act, &single, &group, base + page, FALSE );
+ }
+ if ( (base + step) < upper ) {
+ addOns = flush_explicit_items( addOns, G_CALLBACK(process_menu_action), BUMP_CUSTOM, menu, act, &single, &group, base + step );
+ create_single_menu_item( G_CALLBACK(process_menu_action), BUMP_UP, menu, act, &single, &group, base + step, FALSE );
+ }
+ }
+
+ addOns = flush_explicit_items( addOns, G_CALLBACK(process_menu_action), BUMP_CUSTOM, menu, act, &single, &group, base );
+ create_single_menu_item( G_CALLBACK(process_menu_action), BUMP_NONE, menu, act, &single, &group, base, TRUE );
+
+ if ( base > lower ) {
+ if ( (base - step) > lower ) {
+ addOns = flush_explicit_items( addOns, G_CALLBACK(process_menu_action), BUMP_CUSTOM, menu, act, &single, &group, base - step );
+ create_single_menu_item( G_CALLBACK(process_menu_action), BUMP_DOWN, menu, act, &single, &group, base - step, FALSE );
+ }
+ if ( (base - page) > lower ) {
+ addOns = flush_explicit_items( addOns, G_CALLBACK(process_menu_action), BUMP_CUSTOM, menu, act, &single, &group, base - page );
+ create_single_menu_item( G_CALLBACK(process_menu_action), BUMP_PAGE_DOWN, menu, act, &single, &group, base - page, FALSE );
+ }
+ addOns = flush_explicit_items( addOns, G_CALLBACK(process_menu_action), BUMP_CUSTOM, menu, act, &single, &group, lower );
+ create_single_menu_item( G_CALLBACK(process_menu_action), BUMP_BOTTOM, menu, act, &single, &group, lower, FALSE );
+ }
+
+ if ( act->private_data->descriptions ) {
+ gdouble value = ((EgeAdjustmentDescr*)act->private_data->descriptions->data)->value;
+ addOns = flush_explicit_items( addOns, G_CALLBACK(process_menu_action), BUMP_CUSTOM, menu, act, &single, &group, value );
+ }
+
+ return menu;
+}
+
+static GtkWidget* create_menu_item( GtkAction* action )
+{
+ GtkWidget* item = 0;
+
+ if ( IS_EGE_ADJUSTMENT_ACTION(action) ) {
+ EgeAdjustmentAction* act = EGE_ADJUSTMENT_ACTION( action );
+ GValue value;
+ GtkWidget* subby = 0;
+
+ memset( &value, 0, sizeof(value) );
+ g_value_init( &value, G_TYPE_STRING );
+ g_object_get_property( G_OBJECT(action), "label", &value );
+
+ item = gtk_menu_item_new_with_label( g_value_get_string( &value ) );
+
+ subby = create_popup_number_menu( act );
+ gtk_menu_item_set_submenu( GTK_MENU_ITEM(item), subby );
+ gtk_widget_show_all( subby );
+ g_value_unset( &value );
+ } else {
+ item = GTK_ACTION_CLASS(ege_adjustment_action_parent_class)->create_menu_item( action );
+ }
+
+ return item;
+}
+
+static void value_changed_cb( GtkSpinButton* spin, EgeAdjustmentAction* act )
+{
+ if ( gtk_widget_has_focus( GTK_WIDGET(spin) ) ) {
+ gint start = 0, end = 0;
+ if (GTK_IS_EDITABLE(spin) && gtk_editable_get_selection_bounds (GTK_EDITABLE(spin), &start, &end)
+ && start != end) {
+ // #167846, #363000 If the spin button has a selection, its probably
+ // because we got here from a Tab key from another spin, if so dont defocus
+ return;
+ }
+ ege_adjustment_action_defocus( act );
+ }
+}
+
+static gboolean event_cb( EgeAdjustmentAction* act, GdkEvent* evt )
+{
+ gboolean handled = FALSE;
+ if ( evt->type == GDK_BUTTON_PRESS ) {
+ if ( evt->button.button == 3 ) {
+ if ( IS_EGE_ADJUSTMENT_ACTION(act) ) {
+ GdkEventButton* btnevt = (GdkEventButton*)evt;
+ GtkWidget* menu = create_popup_number_menu(act);
+ gtk_widget_show_all( menu );
+ gtk_menu_popup( GTK_MENU(menu), NULL, NULL, NULL, NULL, btnevt->button, btnevt->time );
+ }
+ handled = TRUE;
+ }
+ }
+
+ return handled;
+}
+
+static GtkWidget* create_tool_item( GtkAction* action )
+{
+ GtkWidget* item = 0;
+
+ if ( IS_EGE_ADJUSTMENT_ACTION(action) ) {
+ EgeAdjustmentAction* act = EGE_ADJUSTMENT_ACTION( action );
+ GtkWidget* spinbutton = 0;
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkWidget* hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
+ gtk_box_set_homogeneous(GTK_BOX(hb), FALSE);
+#else
+ GtkWidget* hb = gtk_hbox_new( FALSE, 5 );
+#endif
+ GValue value;
+ memset( &value, 0, sizeof(value) );
+ g_value_init( &value, G_TYPE_STRING );
+ g_object_get_property( G_OBJECT(action), "short_label", &value );
+
+ if ( act->private_data->appearanceMode == APPEARANCE_FULL ) {
+ /* Slider */
+ spinbutton = gimp_spin_scale_new (act->private_data->adj, g_value_get_string( &value ), 0);
+ gtk_widget_set_size_request(spinbutton, 100, -1);
+
+ } else if ( act->private_data->appearanceMode == APPEARANCE_MINIMAL ) {
+ spinbutton = gtk_scale_button_new( GTK_ICON_SIZE_MENU, 0, 100, 2, 0 );
+ gtk_scale_button_set_adjustment( GTK_SCALE_BUTTON(spinbutton), act->private_data->adj );
+ gtk_scale_button_set_icons( GTK_SCALE_BUTTON(spinbutton), floogles );
+ } else {
+ if ( gFactoryCb ) {
+ spinbutton = gFactoryCb( act->private_data->adj, act->private_data->climbRate, act->private_data->digits, act->private_data->unitTracker );
+ } else {
+ spinbutton = gtk_spin_button_new( act->private_data->adj, act->private_data->climbRate, act->private_data->digits );
+ }
+ }
+
+ item = GTK_WIDGET( gtk_tool_item_new() );
+
+ {
+ GValue tooltip;
+ memset( &tooltip, 0, sizeof(tooltip) );
+ g_value_init( &tooltip, G_TYPE_STRING );
+ g_object_get_property( G_OBJECT(action), "tooltip", &tooltip );
+ const gchar* tipstr = g_value_get_string( &tooltip );
+ if ( tipstr && *tipstr ) {
+ gtk_widget_set_tooltip_text( spinbutton, tipstr );
+ }
+ g_value_unset( &tooltip );
+ }
+
+ if ( act->private_data->appearanceMode != APPEARANCE_FULL ) {
+ GtkWidget* filler1 = gtk_label_new(" ");
+ gtk_box_pack_start( GTK_BOX(hb), filler1, FALSE, FALSE, 0 );
+
+ /* Use an icon if available or use short-label */
+ if ( act->private_data->iconId && strcmp( act->private_data->iconId, "" ) != 0 ) {
+ GtkWidget* icon = sp_icon_new( act->private_data->iconSize, act->private_data->iconId );
+ gtk_box_pack_start( GTK_BOX(hb), icon, FALSE, FALSE, 0 );
+ } else {
+ GtkWidget* lbl = gtk_label_new( g_value_get_string( &value ) ? g_value_get_string( &value ) : "wwww" );
+ gtk_misc_set_alignment( GTK_MISC(lbl), 1.0, 0.5 );
+ gtk_box_pack_start( GTK_BOX(hb), lbl, FALSE, FALSE, 0 );
+ }
+ }
+
+ if ( act->private_data->appearanceMode == APPEARANCE_FULL ) {
+ gtk_box_pack_start( GTK_BOX(hb), spinbutton, TRUE, TRUE, 0 );
+ } else {
+ gtk_box_pack_start( GTK_BOX(hb), spinbutton, FALSE, FALSE, 0 );
+ }
+
+ gtk_container_add( GTK_CONTAINER(item), hb );
+
+ if ( act->private_data->selfId ) {
+ g_object_set_data( G_OBJECT(spinbutton), act->private_data->selfId, spinbutton );
+ }
+
+ g_signal_connect( G_OBJECT(spinbutton), "focus-in-event", G_CALLBACK(focus_in_cb), action );
+ g_signal_connect( G_OBJECT(spinbutton), "focus-out-event", G_CALLBACK(focus_out_cb), action );
+ g_signal_connect( G_OBJECT(spinbutton), "key-press-event", G_CALLBACK(keypress_cb), action );
+
+ g_signal_connect( G_OBJECT(spinbutton), "value-changed", G_CALLBACK(value_changed_cb), action );
+
+ g_signal_connect_swapped( G_OBJECT(spinbutton), "event", G_CALLBACK(event_cb), action );
+ if ( act->private_data->appearanceMode == APPEARANCE_FULL ) {
+ /* */
+ } else if ( act->private_data->appearanceMode == APPEARANCE_MINIMAL ) {
+ /* */
+ } else {
+ gtk_entry_set_width_chars( GTK_ENTRY(spinbutton), act->private_data->digits + 3 );
+ }
+
+ gtk_widget_show_all( item );
+
+ /* Shrink or whatnot after shown */
+ if ( act->private_data->toolPost ) {
+ act->private_data->toolPost( item );
+ }
+
+ g_value_unset( &value );
+ } else {
+ item = GTK_ACTION_CLASS(ege_adjustment_action_parent_class)->create_tool_item( action );
+ }
+
+ return item;
+}
+
+static void connect_proxy( GtkAction *action, GtkWidget *proxy )
+{
+ GTK_ACTION_CLASS(ege_adjustment_action_parent_class)->connect_proxy( action, proxy );
+}
+
+static void disconnect_proxy( GtkAction *action, GtkWidget *proxy )
+{
+ GTK_ACTION_CLASS(ege_adjustment_action_parent_class)->disconnect_proxy( action, proxy );
+}
+
+void ege_adjustment_action_defocus( EgeAdjustmentAction* action )
+{
+ if ( action->private_data->transferFocus ) {
+ if ( action->private_data->focusWidget ) {
+ gtk_widget_grab_focus( action->private_data->focusWidget );
+ }
+ }
+}
+
+gboolean focus_in_cb( GtkWidget *widget, GdkEventKey *event, gpointer data )
+{
+ (void)event;
+ if ( IS_EGE_ADJUSTMENT_ACTION(data) ) {
+ EgeAdjustmentAction* action = EGE_ADJUSTMENT_ACTION( data );
+ if ( GTK_IS_SPIN_BUTTON(widget) ) {
+ action->private_data->lastVal = gtk_spin_button_get_value( GTK_SPIN_BUTTON(widget) );
+ } else if ( GTK_IS_SCALE_BUTTON(widget) ) {
+ action->private_data->lastVal = gtk_scale_button_get_value( GTK_SCALE_BUTTON(widget) );
+ } else if (GTK_IS_RANGE(widget) ) {
+ action->private_data->lastVal = gtk_range_get_value( GTK_RANGE(widget) );
+ }
+ action->private_data->transferFocus = TRUE;
+ }
+
+ return FALSE; /* report event not consumed */
+}
+
+static gboolean focus_out_cb( GtkWidget *widget, GdkEventKey *event, gpointer data )
+{
+ (void)widget;
+ (void)event;
+ if ( IS_EGE_ADJUSTMENT_ACTION(data) ) {
+ EgeAdjustmentAction* action = EGE_ADJUSTMENT_ACTION( data );
+ action->private_data->transferFocus = FALSE;
+ }
+
+ return FALSE; /* report event not consumed */
+}
+
+
+static gboolean process_tab( GtkWidget* widget, int direction )
+{
+ gboolean handled = FALSE;
+ GtkWidget* parent = gtk_widget_get_parent(widget);
+ GtkWidget* gp = parent ? gtk_widget_get_parent(parent) : 0;
+ GtkWidget* ggp = gp ? gtk_widget_get_parent(gp) : 0;
+
+ if ( ggp && GTK_IS_TOOLBAR(ggp) ) {
+ GList* kids = gtk_container_get_children( GTK_CONTAINER(ggp) );
+ if ( kids ) {
+ GtkWidget* curr = widget;
+ while ( curr && (gtk_widget_get_parent(curr) != ggp) ) {
+ curr = gtk_widget_get_parent( curr );
+ }
+ if ( curr ) {
+ GList* mid = g_list_find( kids, curr );
+ while ( mid ) {
+ mid = ( direction < 0 ) ? g_list_previous(mid) : g_list_next(mid);
+ if ( mid && GTK_IS_TOOL_ITEM(mid->data) ) {
+ /* potential target */
+ GtkWidget* child = gtk_bin_get_child( GTK_BIN(mid->data) );
+ if ( child && GTK_IS_BOX(child) ) { /* could be ours */
+ GList* subChildren = gtk_container_get_children( GTK_CONTAINER(child) );
+ if ( subChildren ) {
+ GList* last = g_list_last(subChildren);
+ if ( last && GTK_IS_SPIN_BUTTON(last->data) && gtk_widget_is_sensitive( GTK_WIDGET(last->data) ) ) {
+ gtk_widget_grab_focus( GTK_WIDGET(last->data) );
+ handled = TRUE;
+ mid = 0; /* to stop loop */
+ }
+
+ g_list_free(subChildren);
+ }
+ }
+ }
+ }
+ }
+ g_list_free( kids );
+ }
+ }
+
+ return handled;
+}
+
+gboolean keypress_cb( GtkWidget *widget, GdkEventKey *event, gpointer data )
+{
+ gboolean wasConsumed = FALSE; /* default to report event not consumed */
+ EgeAdjustmentAction* action = EGE_ADJUSTMENT_ACTION(data);
+ guint key = 0;
+ gdk_keymap_translate_keyboard_state( gdk_keymap_get_for_display( gdk_display_get_default() ),
+ event->hardware_keycode, (GdkModifierType)event->state,
+ 0, &key, 0, 0, 0 );
+
+ switch ( key ) {
+ case GDK_KEY_Escape:
+ {
+ action->private_data->transferFocus = TRUE;
+ gtk_spin_button_set_value( GTK_SPIN_BUTTON(widget), action->private_data->lastVal );
+ ege_adjustment_action_defocus( action );
+ wasConsumed = TRUE;
+ }
+ break;
+
+ case GDK_KEY_Return:
+ case GDK_KEY_KP_Enter:
+ {
+ action->private_data->transferFocus = TRUE;
+ ege_adjustment_action_defocus( action );
+ wasConsumed = TRUE;
+ }
+ break;
+
+ case GDK_KEY_Tab:
+ {
+ action->private_data->transferFocus = FALSE;
+ wasConsumed = process_tab( widget, 1 );
+ }
+ break;
+
+ case GDK_KEY_ISO_Left_Tab:
+ {
+ action->private_data->transferFocus = FALSE;
+ wasConsumed = process_tab( widget, -1 );
+ }
+ break;
+
+ case GDK_KEY_Up:
+ case GDK_KEY_KP_Up:
+ {
+ action->private_data->transferFocus = FALSE;
+ gdouble val = gtk_spin_button_get_value( GTK_SPIN_BUTTON(widget) );
+ gtk_spin_button_set_value( GTK_SPIN_BUTTON(widget), val + action->private_data->step );
+ wasConsumed = TRUE;
+ }
+ break;
+
+ case GDK_KEY_Down:
+ case GDK_KEY_KP_Down:
+ {
+ action->private_data->transferFocus = FALSE;
+ gdouble val = gtk_spin_button_get_value( GTK_SPIN_BUTTON(widget) );
+ gtk_spin_button_set_value( GTK_SPIN_BUTTON(widget), val - action->private_data->step );
+ wasConsumed = TRUE;
+ }
+ break;
+
+ case GDK_KEY_Page_Up:
+ case GDK_KEY_KP_Page_Up:
+ {
+ action->private_data->transferFocus = FALSE;
+ gdouble val = gtk_spin_button_get_value( GTK_SPIN_BUTTON(widget) );
+ gtk_spin_button_set_value( GTK_SPIN_BUTTON(widget), val + action->private_data->page );
+ wasConsumed = TRUE;
+ }
+ break;
+
+ case GDK_KEY_Page_Down:
+ case GDK_KEY_KP_Page_Down:
+ {
+ action->private_data->transferFocus = FALSE;
+ gdouble val = gtk_spin_button_get_value( GTK_SPIN_BUTTON(widget) );
+ gtk_spin_button_set_value( GTK_SPIN_BUTTON(widget), val - action->private_data->page );
+ wasConsumed = TRUE;
+ }
+ break;
+
+ case GDK_KEY_z:
+ case GDK_KEY_Z:
+ {
+ action->private_data->transferFocus = FALSE;
+ gtk_spin_button_set_value( GTK_SPIN_BUTTON(widget), action->private_data->lastVal );
+ wasConsumed = TRUE;
+ }
+ break;
+
+ }
+
+ return wasConsumed;
+}
+/*
+ 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/widgets/ege-adjustment-action.h b/src/widgets/ege-adjustment-action.h
new file mode 100644
index 000000000..8cfaa3e52
--- /dev/null
+++ b/src/widgets/ege-adjustment-action.h
@@ -0,0 +1,192 @@
+#ifndef SEEN_EGE_ADJUSTMENT_ACTION
+#define SEEN_EGE_ADJUSTMENT_ACTION
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ */
+/* ***** 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 Adjustment Action.
+ *
+ * The Initial Developer of the Original Code is
+ * Jon A. Cruz.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * 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 ***** */
+
+/** \file
+ * GtkAction subclass that represents a GtkAdjustment value.
+ */
+
+/* Note: this file should be kept compilable as both .cpp and .c */
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+
+#define EGE_ADJUSTMENT_ACTION_TYPE ( ege_adjustment_action_get_type() )
+#define EGE_ADJUSTMENT_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_CAST( (obj), EGE_ADJUSTMENT_ACTION_TYPE, EgeAdjustmentAction) )
+#define EGE_ADJUSTMENT_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( (klass), EGE_ADJUSTMENT_ACTION_TYPE, EgeAdjustmentActionClass) )
+#define IS_EGE_ADJUSTMENT_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_TYPE( (obj), EGE_ADJUSTMENT_ACTION_TYPE) )
+#define IS_EGE_ADJUSTMENT_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE( (klass), EGE_ADJUSTMENT_ACTION_TYPE) )
+#define EGE_ADJUSTMENT_ACTION_GET_CLASS( obj ) ( G_TYPE_INSTANCE_GET_CLASS( (obj), EGE_ADJUSTMENT_ACTION_TYPE, EgeAdjustmentActionClass) )
+
+typedef struct _EgeAdjustmentAction EgeAdjustmentAction;
+typedef struct _EgeAdjustmentActionClass EgeAdjustmentActionClass;
+typedef struct _EgeAdjustmentActionPrivate EgeAdjustmentActionPrivate;
+
+namespace Inkscape {
+ namespace UI {
+ namespace Widget {
+ class UnitTracker;
+ }
+ }
+}
+
+/**
+ * Instance structure of EgeAdjustmentAction.
+ */
+struct _EgeAdjustmentAction
+{
+ /** Parent instance structure. */
+ GtkAction action;
+
+ /** Pointer to private instance data. */
+ EgeAdjustmentActionPrivate *private_data;
+};
+
+/**
+ * Class structure of EgeAdjustmentAction.
+ */
+struct _EgeAdjustmentActionClass
+{
+ /** Parent class structure. */
+ GtkActionClass parent_class;
+};
+
+/** Standard Gtk type function */
+GType ege_adjustment_action_get_type( void );
+
+
+/*
+ * Note: This normally could be implemented via a GType property for the class to construct,
+ * but gtkmm classes implemented in C++ only will often not funciton properly.
+ *
+ */
+
+/** Callback type for widgets creation factory */
+typedef GtkWidget* (*EgeCreateAdjWidgetCB)( GtkAdjustment *adjustment, gdouble climb_rate, guint digits, Inkscape::UI::Widget::UnitTracker *unit_tracker );
+
+/**
+ * Sets a factory callback to be used to create the specific widget.
+ *
+ * @param factoryCb the callback to use to create custom widgets, NULL to use the default.
+ */
+void ege_adjustment_action_set_compact_tool_factory( EgeCreateAdjWidgetCB factoryCb );
+
+
+/**
+ * Creates a new EgeAdjustmentAction instance.
+ * This is a GtkAction subclass that manages a value stored in a
+ * GtkAdjustment.
+ *
+ * @param adjustment The GtkAdjustment to manage.
+ * @param name Functional name for the action.
+ * @param label Display label for the action.
+ * @param tooltip Tooltip for the action.
+ * @param stock_id Icon id to use.
+ * @param climb_rate Used for created widgets.
+ * @param digits Used for created widgets.
+ * @param unit_tracker Used to store unit.
+ */
+EgeAdjustmentAction* ege_adjustment_action_new( GtkAdjustment* adjustment,
+ const gchar *name,
+ const gchar *label,
+ const gchar *tooltip,
+ const gchar *stock_id,
+ gdouble climb_rate,
+ guint digits,
+ Inkscape::UI::Widget::UnitTracker *unit_tracker
+ );
+/**
+ * Returns a pointer to the GtkAdjustment represented by the given
+ * EgeAdjustmentAction.
+ *
+ * @param action The action to fetch the GtkAdjustment for.
+ */
+GtkAdjustment* ege_adjustment_action_get_adjustment( EgeAdjustmentAction* action );
+
+/**
+ * Sets the GtkWidget to return focus to.
+ * This is used to be able to transfer focus back out of a toolbar.
+ *
+ * @param action The action to set the widget for.
+ * @param widget The widget to return focus to after editing.
+ * @see ege_adjustment_action_get_focuswidget
+ */
+void ege_adjustment_action_set_focuswidget( EgeAdjustmentAction* action, GtkWidget* widget );
+
+/**
+ * Returns a pointer to the GtkWidget to return focus to after changing
+ * the value.
+ *
+ * @param action The action to fetch the focus widget for.
+ * @returns A pointer to the widget to return focus to, NULL if none set.
+ * @see ege_adjustment_action_set_focuswidget
+ */
+GtkWidget* ege_adjustment_action_get_focuswidget( EgeAdjustmentAction* action );
+
+/**
+ * Set a list of values with labels to explicitly include in menus.
+ *
+ * @param action The action to set explicit entries for.
+ * @param descriptions Array of descriptions to include.
+ * Descriptions will be matched one-for-one with numbers in the 'values' array.
+ * @param values Array of values to include.
+ * Values will be matched one-for-one with numbers in the 'descriptions' array.
+ * @param count Number of items in the 'descriptions' and 'values' arrays.
+ */
+void ege_adjustment_action_set_descriptions( EgeAdjustmentAction* action, gchar const** descriptions, gdouble const* values, guint count );
+
+/**
+ * Sets a hint to be used in determining the display form.
+ * This is the XForms style 'appearance' hint: "full", "compact", "minimal".
+ *
+ * @param action The action to set the tooltip column for.
+ * @param val The value of the appearance hint.
+ */
+void ege_adjustment_action_set_appearance( EgeAdjustmentAction* action, gchar const* val );
+
+/** Callback type for post-creation 'fixup' pass on generated widgets */
+typedef void (*EgeWidgetFixup)(GtkWidget *widget);
+
+
+G_END_DECLS
+
+#endif /* SEEN_EGE_ADJUSTMENT_ACTION */
diff --git a/src/widgets/ege-output-action.cpp b/src/widgets/ege-output-action.cpp
new file mode 100644
index 000000000..5dece8e91
--- /dev/null
+++ b/src/widgets/ege-output-action.cpp
@@ -0,0 +1,245 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ */
+/* ***** 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 Output Action.
+ *
+ * The Initial Developer of the Original Code is
+ * Jon A. Cruz.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * 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 ***** */
+
+/* Note: this file should be kept compilable as both .cpp and .c */
+
+#include <string.h>
+
+#include <gtk/gtk.h>
+
+#include "widgets/ege-output-action.h"
+
+
+static void ege_output_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec );
+static void ege_output_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec );
+static void fixup_labels( GObject *gobject, GParamSpec *arg1, gpointer user_data );
+
+/* static GtkWidget* create_menu_item( GtkAction* action ); */
+static GtkWidget* create_tool_item( GtkAction* action );
+
+struct _EgeOutputActionPrivate
+{
+ gboolean useMarkup;
+};
+
+#define EGE_OUTPUT_ACTION_GET_PRIVATE( o ) ( G_TYPE_INSTANCE_GET_PRIVATE( (o), EGE_OUTPUT_ACTION_TYPE, EgeOutputActionPrivate ) )
+
+enum {
+ PROP_USE_MARKUP = 1,
+};
+
+G_DEFINE_TYPE(EgeOutputAction, ege_output_action, GTK_TYPE_ACTION);
+
+void ege_output_action_class_init( EgeOutputActionClass* klass )
+{
+ if ( klass ) {
+ GObjectClass* objClass = G_OBJECT_CLASS( klass );
+
+ objClass->get_property = ege_output_action_get_property;
+ objClass->set_property = ege_output_action_set_property;
+
+/* klass->parent_class.create_menu_item = create_menu_item; */
+ klass->parent_class.create_tool_item = create_tool_item;
+
+ g_object_class_install_property( objClass,
+ PROP_USE_MARKUP,
+ g_param_spec_boolean( "use-markup",
+ "UseMarkup",
+ "If markup should be used",
+ FALSE,
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ g_type_class_add_private( klass, sizeof(EgeOutputActionClass) );
+ }
+}
+
+
+void ege_output_action_init( EgeOutputAction* action )
+{
+ action->private_data = EGE_OUTPUT_ACTION_GET_PRIVATE( action );
+ action->private_data->useMarkup = FALSE;
+
+ g_signal_connect( action, "notify", G_CALLBACK( fixup_labels ), NULL );
+}
+
+EgeOutputAction* ege_output_action_new( const gchar *name,
+ const gchar *label,
+ const gchar *tooltip,
+ const gchar *stock_id )
+{
+ GObject* obj = (GObject*)g_object_new( EGE_OUTPUT_ACTION_TYPE,
+ "name", name,
+ "label", label,
+ "tooltip", tooltip,
+ "stock_id", stock_id,
+ "use-markup", FALSE,
+ NULL );
+
+ EgeOutputAction* action = EGE_OUTPUT_ACTION( obj );
+
+ return action;
+}
+
+gboolean ege_output_action_get_use_markup( EgeOutputAction* action )
+{
+ g_return_val_if_fail( IS_EGE_OUTPUT_ACTION(action), FALSE );
+
+ return action->private_data->useMarkup;
+}
+
+void ege_output_action_set_use_markup( EgeOutputAction* action, gboolean setting )
+{
+ g_object_set( G_OBJECT(action), "use-markup", setting, NULL );
+}
+
+void ege_output_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec )
+{
+ EgeOutputAction* action = EGE_OUTPUT_ACTION( obj );
+ switch ( propId ) {
+ case PROP_USE_MARKUP:
+ g_value_set_boolean( value, action->private_data->useMarkup );
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
+ }
+}
+
+void ege_output_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec )
+{
+ EgeOutputAction* action = EGE_OUTPUT_ACTION( obj );
+ switch ( propId ) {
+ case PROP_USE_MARKUP:
+ {
+ action->private_data->useMarkup = g_value_get_boolean( value );
+ }
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
+ }
+}
+
+
+/* static GtkWidget* create_menu_item( GtkAction* action ) */
+
+GtkWidget* create_tool_item( GtkAction* action )
+{
+ GtkWidget* item = 0;
+
+ if ( IS_EGE_OUTPUT_ACTION(action) )
+ {
+ GValue value;
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkWidget* hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
+ gtk_box_set_homogeneous(GTK_BOX(hb), FALSE);
+#else
+ GtkWidget* hb = gtk_hbox_new( FALSE, 5 );
+#endif
+ GtkWidget* lbl = 0;
+ memset( &value, 0, sizeof(value) );
+
+ g_value_init( &value, G_TYPE_STRING );
+ g_object_get_property( G_OBJECT(action), "short_label", &value );
+ const gchar* sss = g_value_get_string( &value );
+
+ item = GTK_WIDGET( gtk_tool_item_new() );
+
+ lbl = gtk_label_new( " " );
+ gtk_container_add( GTK_CONTAINER(hb), lbl );
+
+ if ( EGE_OUTPUT_ACTION(action)->private_data->useMarkup ) {
+ lbl = gtk_label_new(NULL);
+ gtk_label_set_markup( GTK_LABEL(lbl), sss ? sss : " " );
+ } else {
+ lbl = gtk_label_new( sss ? sss : " " );
+ }
+ gtk_container_add( GTK_CONTAINER(hb), lbl );
+
+ lbl = gtk_label_new( " " );
+ gtk_container_add( GTK_CONTAINER(hb), lbl );
+
+ gtk_container_add( GTK_CONTAINER(item), hb );
+
+ gtk_widget_show_all( item );
+
+ g_value_unset( &value );
+ } else {
+ item = GTK_ACTION_CLASS(ege_output_action_parent_class)->create_tool_item( action );
+ }
+
+ return item;
+}
+
+void fixup_labels( GObject *gobject, GParamSpec *arg1, gpointer user_data )
+{
+ /* TODO: handle 'use-markup' getting changed also */
+
+ if ( arg1 && arg1->name && (strcmp("label", arg1->name) == 0) ) {
+ GSList* proxies = gtk_action_get_proxies( GTK_ACTION(gobject) );
+ gchar* str = 0;
+ g_object_get( gobject, "label", &str, NULL );
+ (void)user_data;
+ while ( proxies ) {
+ if ( GTK_IS_TOOL_ITEM(proxies->data) ) {
+ /* Search for the things we built up in create_tool_item() */
+ GList* children = gtk_container_get_children( GTK_CONTAINER(proxies->data) );
+ if ( children && children->data ) {
+ if ( GTK_IS_BOX(children->data) ) {
+ children = gtk_container_get_children( GTK_CONTAINER(children->data) );
+ if ( children && g_list_next(children) ) {
+ GtkWidget* child = GTK_WIDGET( g_list_next(children)->data );
+ if ( GTK_IS_LABEL(child) ) {
+ GtkLabel* lbl = GTK_LABEL(child);
+ if ( EGE_OUTPUT_ACTION(gobject)->private_data->useMarkup ) {
+ gtk_label_set_markup( lbl, str );
+ } else {
+ gtk_label_set_text( lbl, str );
+ }
+ }
+ }
+ }
+ }
+ }
+ proxies = g_slist_next( proxies );
+ }
+ g_free( str );
+ }
+}
+
diff --git a/src/widgets/ege-output-action.h b/src/widgets/ege-output-action.h
new file mode 100644
index 000000000..0f4e21805
--- /dev/null
+++ b/src/widgets/ege-output-action.h
@@ -0,0 +1,120 @@
+#ifndef SEEN_EGE_OUTPUT_ACTION
+#define SEEN_EGE_OUTPUT_ACTION
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ */
+/* ***** 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 Output Action.
+ *
+ * The Initial Developer of the Original Code is
+ * Jon A. Cruz.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * 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 ***** */
+
+/** \file
+ * GtkAction subclass that represents a string for output.
+ */
+
+/* Note: this file should be kept compilable as both .cpp and .c */
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+
+#define EGE_OUTPUT_ACTION_TYPE ( ege_output_action_get_type() )
+#define EGE_OUTPUT_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_CAST( (obj), EGE_OUTPUT_ACTION_TYPE, EgeOutputAction) )
+#define EGE_OUTPUT_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( (klass), EGE_OUTPUT_ACTION_TYPE, EgeOutputActionClass) )
+#define IS_EGE_OUTPUT_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_TYPE( (obj), EGE_OUTPUT_ACTION_TYPE) )
+#define IS_EGE_OUTPUT_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE( (klass), EGE_OUTPUT_ACTION_TYPE) )
+#define EGE_OUTPUT_ACTION_GET_CLASS( obj ) ( G_TYPE_INSTANCE_GET_CLASS( (obj), EGE_OUTPUT_ACTION_TYPE, EgeOutputActionClass) )
+
+typedef struct _EgeOutputAction EgeOutputAction;
+typedef struct _EgeOutputActionClass EgeOutputActionClass;
+typedef struct _EgeOutputActionPrivate EgeOutputActionPrivate;
+
+/**
+ * Instance structure of EgeOutputAction.
+ */
+struct _EgeOutputAction
+{
+ /** Parent instance structure. */
+ GtkAction action;
+
+ /** Pointer to private instance data. */
+ EgeOutputActionPrivate *private_data;
+};
+
+/**
+ * Class structure of EgeOutputAction.
+ */
+struct _EgeOutputActionClass
+{
+ /** Parent class structure. */
+ GtkActionClass parent_class;
+};
+
+/** Standard Gtk type function */
+GType ege_output_action_get_type( void );
+
+/**
+ * Creates a new EgeOutputAction instance.
+ * This is a GtkAction subclass that displays a string.
+ *
+ * @param name Functional name for the action.
+ * @param label Display label for the action.
+ * @param tooltip Tooltip for the action.
+ * @param stock_id Icon id to use.
+ */
+EgeOutputAction* ege_output_action_new( const gchar *name,
+ const gchar *label,
+ const gchar *tooltip,
+ const gchar *stock_id );
+
+/**
+ * Return whether or not the displayed text is interpreted as markup.
+ *
+ * @param action The action to fetch the markup state for.
+ * @return True if the text is to be interpreted as markup, false otherwise.
+ */
+gboolean ege_output_action_get_use_markup( EgeOutputAction* action );
+
+/**
+ * Sets whether or not the displayed text is interpreted as markup.
+ *
+ * @param action The action to set the markup state for.
+ * @param setting True if the text is to be interpreted as markup, false otherwise.
+ */
+void ege_output_action_set_use_markup( EgeOutputAction* action, gboolean setting );
+
+G_END_DECLS
+
+#endif /* SEEN_EGE_OUTPUT_ACTION */
diff --git a/src/widgets/ege-select-one-action.cpp b/src/widgets/ege-select-one-action.cpp
new file mode 100644
index 000000000..ab86c49f8
--- /dev/null
+++ b/src/widgets/ege-select-one-action.cpp
@@ -0,0 +1,1153 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ */
+/* ***** 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 Select One Action.
+ *
+ * The Initial Developer of the Original Code is
+ * Jon A. Cruz.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * 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 ***** */
+
+/* Note: this file should be kept compilable as both .cpp and .c */
+
+#include <string.h>
+
+#include <gtk/gtk.h>
+
+#include "widgets/ege-select-one-action.h"
+
+enum {
+ CHANGED = 0,
+ LAST_SIGNAL};
+
+static void ege_select_one_action_finalize( GObject* action );
+static void ege_select_one_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec );
+static void ege_select_one_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec );
+
+static gint find_text_index(EgeSelectOneAction *act, gchar const* text);
+static void commit_pending_change(EgeSelectOneAction *act);
+static void resync_active( EgeSelectOneAction* act, gint active, gboolean override );
+static void resync_sensitive( EgeSelectOneAction* act );
+static void combo_entry_changed_cb( GtkEntry* widget, gpointer user_data );
+static gboolean combo_entry_focus_lost_cb( GtkWidget *widget, GdkEventFocus *event, gpointer data );
+static void combo_changed_cb( GtkComboBox* widget, gpointer user_data );
+static void menu_toggled_cb( GtkWidget* obj, gpointer data );
+static void proxy_action_chagned_cb( GtkRadioAction* action, GtkRadioAction* current, gpointer user_data );
+
+static GtkWidget* create_menu_item( GtkAction* action );
+static GtkWidget* create_tool_item( GtkAction* action );
+static void connect_proxy( GtkAction *action, GtkWidget *proxy );
+static void disconnect_proxy( GtkAction *action, GtkWidget *proxy );
+
+static int scan_max_width( GtkTreeModel *model, gint labelColumn );
+
+static guint signals[LAST_SIGNAL] = {0};
+static GQuark gDataName = 0;
+
+
+enum {
+ APPEARANCE_UNKNOWN = -1,
+ APPEARANCE_NONE = 0,
+ APPEARANCE_FULL, /* label, then all choices represented by separate buttons */
+ APPEARANCE_COMPACT, /* label, then choices in a drop-down menu */
+ APPEARANCE_MINIMAL, /* no label, just choices in a drop-down menu */
+};
+
+enum {
+ SELECTION_UNKNOWN = -1,
+ SELECTION_CLOSED = 0,
+ SELECTION_OPEN,
+};
+
+struct _EgeSelectOneActionPrivate
+{
+ gint active;
+ gint labelColumn;
+ gint iconColumn;
+ gint tooltipColumn;
+ gint sensitiveColumn;
+ gint appearanceMode;
+ gint selectionMode;
+ gint iconSize;
+ GType radioActionType;
+ GtkTreeModel* model;
+ gchar *iconProperty;
+ gchar *appearance;
+ gchar *selection;
+ gchar *activeText;
+ gchar *pendingText;
+};
+
+#define EGE_SELECT_ONE_ACTION_GET_PRIVATE( o ) ( G_TYPE_INSTANCE_GET_PRIVATE( (o), EGE_SELECT_ONE_ACTION_TYPE, EgeSelectOneActionPrivate ) )
+
+enum {
+ PROP_MODEL = 1,
+ PROP_ACTIVE,
+ PROP_LABEL_COLUMN,
+ PROP_ICON_COLUMN,
+ PROP_TOOLTIP_COLUMN,
+ PROP_SENSITIVE_COLUMN,
+ PROP_ICON_PROP,
+ PROP_ICON_SIZE,
+ PROP_APPEARANCE,
+ PROP_SELECTION
+};
+
+G_DEFINE_TYPE(EgeSelectOneAction, ege_select_one_action, GTK_TYPE_ACTION);
+
+GtkTreeModel *ege_select_one_action_get_model(EgeSelectOneAction* action ){
+ return GTK_TREE_MODEL(action->private_data->model);
+}
+void ege_select_one_action_class_init( EgeSelectOneActionClass* klass )
+{
+ if ( klass ) {
+ GObjectClass* objClass = G_OBJECT_CLASS( klass );
+
+ gDataName = g_quark_from_string("ege-select1-action");
+
+ objClass->finalize = ege_select_one_action_finalize;
+ objClass->get_property = ege_select_one_action_get_property;
+ objClass->set_property = ege_select_one_action_set_property;
+
+ klass->parent_class.create_menu_item = create_menu_item;
+ klass->parent_class.create_tool_item = create_tool_item;
+ klass->parent_class.connect_proxy = connect_proxy;
+ klass->parent_class.disconnect_proxy = disconnect_proxy;
+
+ g_object_class_install_property( objClass,
+ PROP_MODEL,
+ g_param_spec_object( "model",
+ "Tree Model",
+ "Tree model of possible items",
+ GTK_TYPE_TREE_MODEL,
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ g_object_class_install_property( objClass,
+ PROP_ACTIVE,
+ g_param_spec_int( "active",
+ "Active Selection",
+ "The index of the selected item",
+ -1, G_MAXINT, 0,
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ g_object_class_install_property( objClass,
+ PROP_LABEL_COLUMN,
+ g_param_spec_int( "label-column",
+ "Display Column",
+ "The column of the model that holds display strings",
+ 0, G_MAXINT, 0,
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ g_object_class_install_property( objClass,
+ PROP_ICON_COLUMN,
+ g_param_spec_int( "icon-column",
+ "Icon Column",
+ "The column of the model that holds display icon name",
+ -1, G_MAXINT, -1,
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ g_object_class_install_property( objClass,
+ PROP_TOOLTIP_COLUMN,
+ g_param_spec_int( "tooltip-column",
+ "Tooltip Column",
+ "The column of the model that holds tooltip strings",
+ -1, G_MAXINT, -1,
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ g_object_class_install_property( objClass,
+ PROP_SENSITIVE_COLUMN,
+ g_param_spec_int( "sensitive-column",
+ "Sensitive Column",
+ "The column of the model that holds sensitive state",
+ -1, G_MAXINT, -1,
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ g_object_class_install_property( objClass,
+ PROP_ICON_PROP,
+ g_param_spec_string( "icon-property",
+ "Icon Property",
+ "Target icon property",
+ "",
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ g_object_class_install_property( objClass,
+ PROP_ICON_SIZE,
+ g_param_spec_int( "icon-size",
+ "Icon Size",
+ "Target icon size",
+ -1, G_MAXINT, -1,
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ g_object_class_install_property( objClass,
+ PROP_APPEARANCE,
+ g_param_spec_string( "appearance",
+ "Appearance hint",
+ "A hint for how to display",
+ "",
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ g_object_class_install_property( objClass,
+ PROP_SELECTION,
+ g_param_spec_string( "selection",
+ "Selection set open or closed",
+ "'open' to allow edits/additions, 'closed' to disallow.",
+ "",
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ signals[CHANGED] = g_signal_new( "changed",
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(EgeSelectOneActionClass, changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ g_type_class_add_private( klass, sizeof(EgeSelectOneActionClass) );
+ }
+}
+
+
+void ege_select_one_action_init( EgeSelectOneAction* action )
+{
+ action->private_data = EGE_SELECT_ONE_ACTION_GET_PRIVATE( action );
+ action->private_data->active = 0;
+ action->private_data->labelColumn = 0;
+ action->private_data->iconColumn = -1;
+ action->private_data->tooltipColumn = -1;
+ action->private_data->sensitiveColumn = -1;
+ action->private_data->appearanceMode = APPEARANCE_NONE;
+ action->private_data->selectionMode = SELECTION_CLOSED;
+ action->private_data->radioActionType = 0;
+ action->private_data->model = 0;
+ action->private_data->iconProperty = g_strdup("stock-id");
+ action->private_data->iconSize = -1;
+ action->private_data->appearance = 0;
+ action->private_data->selection = 0;
+ action->private_data->activeText = 0;
+ action->private_data->pendingText = 0;
+
+/* g_signal_connect( action, "notify", G_CALLBACK( fixup_labels ), NULL ); */
+}
+
+void ege_select_one_action_finalize( GObject* object )
+{
+ EgeSelectOneAction *action = EGE_SELECT_ONE_ACTION( object );
+
+ g_free( action->private_data->iconProperty );
+ g_free( action->private_data->appearance );
+ g_free( action->private_data->selection );
+
+ if ( G_OBJECT_CLASS(ege_select_one_action_parent_class)->finalize ) {
+ (*G_OBJECT_CLASS(ege_select_one_action_parent_class)->finalize)(object);
+ }
+}
+
+EgeSelectOneAction* ege_select_one_action_new( const gchar *name,
+ const gchar *label,
+ const gchar *tooltip,
+ const gchar *stock_id,
+ GtkTreeModel* model )
+{
+ GObject* obj = (GObject*)g_object_new( EGE_SELECT_ONE_ACTION_TYPE,
+ "name", name,
+ "label", label,
+ "tooltip", tooltip,
+ "stock_id", stock_id,
+ "model", model,
+ "active", 0,
+ "icon-property", "stock-id",
+ NULL );
+
+ EgeSelectOneAction* action = EGE_SELECT_ONE_ACTION( obj );
+
+ return action;
+}
+
+
+gint ege_select_one_action_get_active( EgeSelectOneAction* action )
+{
+ g_return_val_if_fail( IS_EGE_SELECT_ONE_ACTION(action), 0 );
+ return action->private_data->active;
+}
+
+gchar *ege_select_one_action_get_active_text( EgeSelectOneAction* action )
+{
+ GtkTreeIter iter;
+ gchar *str = 0;
+ g_return_val_if_fail( IS_EGE_SELECT_ONE_ACTION(action), 0 );
+
+ if ( action->private_data->active >= 0) {
+ if ( gtk_tree_model_iter_nth_child( action->private_data->model, &iter, NULL, action->private_data->active ) ) {
+ gtk_tree_model_get( action->private_data->model, &iter,
+ action->private_data->labelColumn, &str,
+ -1 );
+ }
+ } else if ( (action->private_data->active == -1) && action->private_data->activeText ) {
+ str = g_strdup(action->private_data->activeText);
+ }
+
+ return str;
+}
+
+void ege_select_one_action_set_active_text( EgeSelectOneAction* action, gchar const *text )
+{
+ g_return_if_fail( IS_EGE_SELECT_ONE_ACTION(action) );
+
+ if (action->private_data->activeText) {
+ g_free( action->private_data->activeText );
+ }
+ action->private_data->activeText = g_strdup(text);
+
+ if (action->private_data->active != -1) {
+ g_object_set( G_OBJECT(action), "active", -1, NULL );
+ } else {
+ resync_active( action, -1, TRUE );
+ }
+}
+
+void ege_select_one_action_set_active( EgeSelectOneAction* action, gint val )
+{
+ g_object_set( G_OBJECT(action), "active", val, NULL );
+}
+
+void ege_select_one_action_update_sensitive( EgeSelectOneAction* action )
+{
+ if( action->private_data->sensitiveColumn < 0 ) {
+ g_warning( "ege_select_one_action: Attempt to update sensitivity of item without sensitive column\n" );
+ return;
+ }
+ resync_sensitive( action );
+}
+
+gint ege_select_one_action_get_label_column( EgeSelectOneAction* action )
+{
+ g_return_val_if_fail( IS_EGE_SELECT_ONE_ACTION(action), 0 );
+ return action->private_data->labelColumn;
+}
+
+void ege_select_one_action_set_label_column( EgeSelectOneAction* action, gint col )
+{
+ g_object_set( G_OBJECT(action), "label-column", col, NULL );
+}
+
+gint ege_select_one_action_get_icon_column( EgeSelectOneAction* action )
+{
+ g_return_val_if_fail( IS_EGE_SELECT_ONE_ACTION(action), 0 );
+ return action->private_data->iconColumn;
+}
+
+void ege_select_one_action_set_icon_column( EgeSelectOneAction* action, gint col )
+{
+ g_object_set( G_OBJECT(action), "icon-column", col, NULL );
+}
+
+gint ege_select_one_action_get_icon_size( EgeSelectOneAction* action )
+{
+ g_return_val_if_fail( IS_EGE_SELECT_ONE_ACTION(action), 0 );
+ return action->private_data->iconSize;
+}
+
+void ege_select_one_action_set_icon_size( EgeSelectOneAction* action, gint size )
+{
+ g_object_set( G_OBJECT(action), "icon-size", size, NULL );
+}
+
+gint ege_select_one_action_get_tooltip_column( EgeSelectOneAction* action )
+{
+ g_return_val_if_fail( IS_EGE_SELECT_ONE_ACTION(action), 0 );
+ return action->private_data->tooltipColumn;
+}
+
+void ege_select_one_action_set_tooltip_column( EgeSelectOneAction* action, gint col )
+{
+ g_object_set( G_OBJECT(action), "tooltip-column", col, NULL );
+}
+
+gint ege_select_one_action_get_sensitive_column( EgeSelectOneAction* action )
+{
+ g_return_val_if_fail( IS_EGE_SELECT_ONE_ACTION(action), 0 );
+ return action->private_data->sensitiveColumn;
+}
+
+void ege_select_one_action_set_sensitive_column( EgeSelectOneAction* action, gint col )
+{
+ g_object_set( G_OBJECT(action), "sensitive-column", col, NULL );
+}
+
+void ege_select_one_action_set_appearance( EgeSelectOneAction* action, gchar const* val )
+{
+ g_object_set( G_OBJECT(action), "appearance", val, NULL );
+}
+
+void ege_select_one_action_set_selection( EgeSelectOneAction* action, gchar const* val )
+{
+ g_object_set( G_OBJECT(action), "selection", val, NULL );
+}
+
+void ege_select_one_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec )
+{
+ EgeSelectOneAction* action = EGE_SELECT_ONE_ACTION( obj );
+ switch ( propId ) {
+ case PROP_MODEL:
+ g_value_set_object( value, action->private_data->model );
+ break;
+
+ case PROP_ACTIVE:
+ g_value_set_int( value, action->private_data->active );
+ break;
+
+ case PROP_LABEL_COLUMN:
+ g_value_set_int( value, action->private_data->labelColumn );
+ break;
+
+ case PROP_ICON_COLUMN:
+ g_value_set_int( value, action->private_data->iconColumn );
+ break;
+
+ case PROP_TOOLTIP_COLUMN:
+ g_value_set_int( value, action->private_data->tooltipColumn );
+ break;
+
+ case PROP_SENSITIVE_COLUMN:
+ g_value_set_int( value, action->private_data->sensitiveColumn );
+ break;
+
+ case PROP_ICON_PROP:
+ g_value_set_string( value, action->private_data->iconProperty );
+ break;
+
+ case PROP_ICON_SIZE:
+ g_value_set_int( value, action->private_data->iconSize );
+ break;
+
+ case PROP_APPEARANCE:
+ g_value_set_string( value, action->private_data->appearance );
+ break;
+
+ case PROP_SELECTION:
+ g_value_set_string( value, action->private_data->selection );
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
+ }
+}
+
+void ege_select_one_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec )
+{
+ EgeSelectOneAction* action = EGE_SELECT_ONE_ACTION( obj );
+ switch ( propId ) {
+ case PROP_MODEL:
+ {
+ action->private_data->model = GTK_TREE_MODEL( g_value_get_object( value ) );
+ }
+ break;
+
+ case PROP_ACTIVE:
+ {
+ resync_active( action, g_value_get_int( value ), FALSE );
+ }
+ break;
+
+ case PROP_LABEL_COLUMN:
+ {
+ action->private_data->labelColumn = g_value_get_int( value );
+ }
+ break;
+
+ case PROP_ICON_COLUMN:
+ {
+ action->private_data->iconColumn = g_value_get_int( value );
+ }
+ break;
+
+ case PROP_TOOLTIP_COLUMN:
+ {
+ action->private_data->tooltipColumn = g_value_get_int( value );
+ }
+ break;
+
+ case PROP_SENSITIVE_COLUMN:
+ {
+ action->private_data->sensitiveColumn = g_value_get_int( value );
+ }
+ break;
+
+ case PROP_ICON_PROP:
+ {
+ gchar* tmp = action->private_data->iconProperty;
+ gchar* newVal = g_value_dup_string( value );
+ action->private_data->iconProperty = newVal;
+ g_free( tmp );
+ }
+ break;
+
+ case PROP_ICON_SIZE:
+ {
+ action->private_data->iconSize = g_value_get_int( value );
+ }
+ break;
+
+ case PROP_APPEARANCE:
+ {
+ gchar* tmp = action->private_data->appearance;
+ gchar* newVal = g_value_dup_string( value );
+ action->private_data->appearance = newVal;
+ g_free( tmp );
+
+ if ( !action->private_data->appearance || (strcmp("", newVal) == 0) ) {
+ action->private_data->appearanceMode = APPEARANCE_NONE;
+ } else if ( strcmp("full", newVal) == 0 ) {
+ action->private_data->appearanceMode = APPEARANCE_FULL;
+ } else if ( strcmp("compact", newVal) == 0 ) {
+ action->private_data->appearanceMode = APPEARANCE_COMPACT;
+ } else if ( strcmp("minimal", newVal) == 0 ) {
+ action->private_data->appearanceMode = APPEARANCE_MINIMAL;
+ } else {
+ action->private_data->appearanceMode = APPEARANCE_UNKNOWN;
+ }
+ }
+ break;
+
+ case PROP_SELECTION:
+ {
+ gchar* tmp = action->private_data->selection;
+ gchar* newVal = g_value_dup_string( value );
+ action->private_data->selection = newVal;
+ g_free( tmp );
+
+ if ( !action->private_data->selection || (strcmp("closed", newVal) == 0) ) {
+ action->private_data->selectionMode = SELECTION_CLOSED;
+ } else if ( strcmp("open", newVal) == 0 ) {
+ action->private_data->selectionMode = SELECTION_OPEN;
+ } else {
+ action->private_data->selectionMode = SELECTION_UNKNOWN;
+ }
+ }
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
+ }
+}
+
+GtkWidget* create_menu_item( GtkAction* action )
+{
+ GtkWidget* item = 0;
+
+ if ( IS_EGE_SELECT_ONE_ACTION(action) ) {
+ EgeSelectOneAction* act = EGE_SELECT_ONE_ACTION( action );
+ gchar* sss = 0;
+ gint index = 0;
+ GtkTreeIter iter;
+ GSList* group = 0;
+ GtkWidget* subby = gtk_menu_new();
+
+ g_object_get( G_OBJECT(action), "label", &sss, NULL );
+
+ item = gtk_menu_item_new_with_label( sss );
+
+ gboolean valid = gtk_tree_model_get_iter_first( act->private_data->model, &iter );
+ while ( valid ) {
+ gchar* str = 0;
+ gtk_tree_model_get( act->private_data->model, &iter,
+ act->private_data->labelColumn, &str,
+ -1 );
+
+ GtkWidget *item = gtk_radio_menu_item_new_with_label( group, str );
+ group = gtk_radio_menu_item_get_group( GTK_RADIO_MENU_ITEM(item) );
+ gtk_menu_shell_append( GTK_MENU_SHELL(subby), item );
+ g_object_set_qdata( G_OBJECT(item), gDataName, act );
+
+ gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(item), index == act->private_data->active );
+
+ g_free(str);
+ str = 0;
+
+ g_signal_connect( G_OBJECT(item), "toggled", G_CALLBACK(menu_toggled_cb), GINT_TO_POINTER(index) );
+
+ index++;
+ valid = gtk_tree_model_iter_next( act->private_data->model, &iter );
+ }
+
+ gtk_menu_item_set_submenu( GTK_MENU_ITEM(item), subby );
+ gtk_widget_show_all( subby );
+
+ g_free(sss);
+ } else {
+ item = GTK_ACTION_CLASS(ege_select_one_action_parent_class)->create_menu_item( action );
+ }
+
+ return item;
+}
+
+
+void ege_select_one_action_set_radio_action_type( EgeSelectOneAction* action, GType radioActionType )
+{
+ (void)action;
+
+ if ( g_type_is_a( radioActionType, GTK_TYPE_RADIO_ACTION ) ) {
+ action->private_data->radioActionType = radioActionType;
+ } else {
+ g_warning("Passed in type '%s' is not derived from '%s'", g_type_name(radioActionType), g_type_name(GTK_TYPE_RADIO_ACTION) );
+ }
+}
+
+GtkWidget* create_tool_item( GtkAction* action )
+{
+ GtkWidget* item = 0;
+
+ if ( IS_EGE_SELECT_ONE_ACTION(action) && EGE_SELECT_ONE_ACTION(action)->private_data->model )
+ {
+ EgeSelectOneAction* act = EGE_SELECT_ONE_ACTION(action);
+ item = GTK_WIDGET( gtk_tool_item_new() );
+
+ if ( act->private_data->appearanceMode == APPEARANCE_FULL ) {
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkWidget* holder = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_box_set_homogeneous(GTK_BOX(holder), FALSE);
+#else
+ GtkWidget* holder = gtk_hbox_new( FALSE, 0 );
+#endif
+
+ GtkRadioAction* ract = 0;
+ GSList* group = 0;
+ GtkTreeIter iter;
+ gboolean valid = FALSE;
+ gint index = 0;
+
+ {
+ gchar* sss = 0;
+ g_object_get( G_OBJECT(action), "short_label", &sss, NULL );
+ // If short_label not defined, g_object_get will return label.
+ // This hack allows a label to be used with a drop-down menu when
+ // no label is used with a set of icons that are self-explanatory.
+ if (sss && strcmp( sss, "NotUsed" ) != 0 ) {
+ GtkWidget* lbl = gtk_label_new(sss);
+ gtk_box_pack_start( GTK_BOX(holder), lbl, FALSE, FALSE, 4 );
+ }
+ g_free( sss );
+ sss = 0;
+ }
+
+ valid = gtk_tree_model_get_iter_first( act->private_data->model, &iter );
+ while ( valid ) {
+ gchar* str = 0;
+ gchar* tip = 0;
+ gchar* iconId = 0;
+ gboolean sens = true;
+ /*
+ gint size = 0;
+ */
+ gtk_tree_model_get( act->private_data->model, &iter,
+ act->private_data->labelColumn, &str,
+ -1 );
+ if ( act->private_data->iconColumn >= 0 ) {
+ gtk_tree_model_get( act->private_data->model, &iter,
+ act->private_data->iconColumn, &iconId,
+ -1 );
+ }
+ if ( act->private_data->tooltipColumn >= 0 ) {
+ gtk_tree_model_get( act->private_data->model, &iter,
+ act->private_data->tooltipColumn, &tip,
+ -1 );
+ }
+ if ( act->private_data->sensitiveColumn >= 0 ) {
+ gtk_tree_model_get( act->private_data->model, &iter,
+ act->private_data->sensitiveColumn, &sens,
+ -1 );
+ }
+
+ if ( act->private_data->radioActionType ) {
+ void* obj = g_object_new( act->private_data->radioActionType,
+ "name", "Name 1",
+ "label", str,
+ "tooltip", tip,
+ "value", index,
+ /*
+ "iconId", iconId,
+ "iconSize", size,
+ */
+ NULL );
+ if ( iconId ) {
+ g_object_set( G_OBJECT(obj), act->private_data->iconProperty, iconId, NULL );
+ }
+
+ if ( act->private_data->iconProperty ) {
+ /* TODO get this string to be set instead of hardcoded */
+ if ( act->private_data->iconSize >= 0 ) {
+ g_object_set( G_OBJECT(obj), "iconSize", act->private_data->iconSize, NULL );
+ }
+ }
+
+ ract = GTK_RADIO_ACTION(obj);
+ } else {
+ ract = gtk_radio_action_new( "Name 1", str, tip, iconId, index );
+ }
+
+ if ( act->private_data->sensitiveColumn >= 0 ) {
+ gtk_action_set_sensitive( GTK_ACTION(ract), sens );
+ }
+
+ gtk_radio_action_set_group( ract, group );
+ group = gtk_radio_action_get_group( ract );
+
+ if ( index == act->private_data->active ) {
+ gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(ract), TRUE );
+ }
+ g_signal_connect( G_OBJECT(ract), "changed", G_CALLBACK( proxy_action_chagned_cb ), act );
+
+ GtkWidget* sub = gtk_action_create_tool_item( GTK_ACTION(ract) );
+ gtk_activatable_set_related_action( GTK_ACTIVATABLE (sub), GTK_ACTION(ract) );
+ gtk_tool_item_set_tooltip_text( GTK_TOOL_ITEM(sub), tip );
+
+ gtk_box_pack_start( GTK_BOX(holder), sub, FALSE, FALSE, 0 );
+
+ g_free( str );
+ g_free( tip );
+ g_free( iconId );
+
+ index++;
+ valid = gtk_tree_model_iter_next( act->private_data->model, &iter );
+ }
+
+ g_object_set_data( G_OBJECT(holder), "ege-proxy_action-group", group );
+
+ gtk_container_add( GTK_CONTAINER(item), holder );
+ } else {
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkWidget* holder = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4);
+ gtk_box_set_homogeneous(GTK_BOX(holder), FALSE);
+#else
+ GtkWidget *holder = gtk_hbox_new( FALSE, 4 );
+#endif
+
+ GtkEntry *entry = 0;
+ GtkWidget *normal;
+
+ if (act->private_data->selectionMode == SELECTION_OPEN) {
+ normal = gtk_combo_box_new_with_model_and_entry (act->private_data->model);
+ gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX (normal), act->private_data->labelColumn);
+
+ GtkWidget *child = gtk_bin_get_child( GTK_BIN(normal) );
+ if (GTK_IS_ENTRY(child)) {
+ int maxUsed = scan_max_width( act->private_data->model, act->private_data->labelColumn );
+ GtkEntryCompletion *complete = 0;
+ entry = GTK_ENTRY(child);
+ gtk_entry_set_width_chars(entry, maxUsed); /* replace with property */
+
+ complete = gtk_entry_completion_new();
+ gtk_entry_completion_set_model( complete, act->private_data->model );
+ gtk_entry_completion_set_text_column( complete, act->private_data->labelColumn );
+ gtk_entry_completion_set_inline_completion( complete, FALSE );
+ gtk_entry_completion_set_inline_selection( complete, FALSE );
+ gtk_entry_completion_set_popup_completion( complete, TRUE );
+ gtk_entry_completion_set_popup_set_width( complete, FALSE );
+ gtk_entry_set_completion( entry, complete );
+
+ g_signal_connect( G_OBJECT(child), "activate", G_CALLBACK(combo_entry_changed_cb), act );
+ g_signal_connect( G_OBJECT(child), "focus-out-event", G_CALLBACK(combo_entry_focus_lost_cb), act );
+ }
+ }
+ else {
+ GtkCellRenderer * renderer = NULL;
+ normal = gtk_combo_box_new_with_model( act->private_data->model );
+ if ( act->private_data->iconColumn >= 0 ) {
+ renderer = gtk_cell_renderer_pixbuf_new();
+ gtk_cell_layout_pack_start( GTK_CELL_LAYOUT(normal), renderer, TRUE );
+
+ /* "icon-name" */
+ gtk_cell_layout_add_attribute( GTK_CELL_LAYOUT(normal), renderer, "stock-id", act->private_data->iconColumn );
+ }
+
+ renderer = gtk_cell_renderer_text_new();
+ gtk_cell_layout_pack_start( GTK_CELL_LAYOUT(normal), renderer, TRUE );
+ gtk_cell_layout_add_attribute( GTK_CELL_LAYOUT(normal), renderer, "text", act->private_data->labelColumn );
+ }
+
+ gtk_combo_box_set_active( GTK_COMBO_BOX(normal), act->private_data->active );
+ if ( entry && (act->private_data->active == -1) ) {
+ gtk_entry_set_text( entry, act->private_data->activeText );
+ }
+
+ g_signal_connect( G_OBJECT(normal), "changed", G_CALLBACK(combo_changed_cb), action );
+
+ g_object_set_data( G_OBJECT(holder), "ege-combo-box", normal );
+ g_object_set_data( G_OBJECT(act), "ege-combo-box", normal );
+
+ if (act->private_data->appearanceMode == APPEARANCE_COMPACT) {
+ gchar* sss = 0;
+ g_object_get( G_OBJECT(action), "short_label", &sss, NULL );
+ if (sss) {
+ GtkWidget* lbl = gtk_label_new(sss);
+ gtk_box_pack_start( GTK_BOX(holder), lbl, FALSE, FALSE, 4 );
+ g_free( sss );
+ sss = 0;
+ }
+ }
+
+ gtk_box_pack_start( GTK_BOX(holder), normal, FALSE, FALSE, 0 );
+
+ {
+ GtkWidget *align = gtk_alignment_new(0, 0.5, 0, 0);
+ gtk_container_add( GTK_CONTAINER(align), holder);
+ gtk_container_add( GTK_CONTAINER(item), align );
+ }
+ }
+
+ gtk_widget_show_all( item );
+ } else {
+ item = GTK_ACTION_CLASS(ege_select_one_action_parent_class)->create_tool_item( action );
+ }
+
+ return item;
+}
+
+
+void connect_proxy( GtkAction *action, GtkWidget *proxy )
+{
+ GTK_ACTION_CLASS(ege_select_one_action_parent_class)->connect_proxy( action, proxy );
+}
+
+void disconnect_proxy( GtkAction *action, GtkWidget *proxy )
+{
+ GTK_ACTION_CLASS(ege_select_one_action_parent_class)->disconnect_proxy( action, proxy );
+}
+
+
+void resync_active( EgeSelectOneAction* act, gint active, gboolean override )
+{
+ if ( override || (act->private_data->active != active) ) {
+ act->private_data->active = active;
+ GSList* proxies = gtk_action_get_proxies( GTK_ACTION(act) );
+ while ( proxies ) {
+ if ( GTK_IS_TOOL_ITEM(proxies->data) ) {
+ /* Search for the things we built up in create_tool_item() */
+ GList* children = gtk_container_get_children( GTK_CONTAINER(proxies->data) );
+ if ( children && children->data ) {
+ gpointer combodata = g_object_get_data( G_OBJECT(children->data), "ege-combo-box" );
+ if (!combodata && GTK_IS_ALIGNMENT(children->data)) {
+ GList *other = gtk_container_get_children( GTK_CONTAINER(children->data) );
+ combodata = g_object_get_data( G_OBJECT(other->data), "ege-combo-box" );
+ }
+ if ( GTK_IS_COMBO_BOX(combodata) ) {
+ GtkComboBox* combo = GTK_COMBO_BOX(combodata);
+ if ((active == -1) && (gtk_combo_box_get_has_entry(combo))) {
+ gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(combo))), act->private_data->activeText);
+ } else if ( gtk_combo_box_get_active(combo) != active ) {
+ gtk_combo_box_set_active( combo, active );
+ }
+ } else if ( GTK_IS_BOX(children->data) ) {
+ gpointer data = g_object_get_data( G_OBJECT(children->data), "ege-proxy_action-group" );
+ if ( data ) {
+ GSList* group = (GSList*)data;
+ GtkRadioAction* oneAction = GTK_RADIO_ACTION(group->data);
+ gint hot = gtk_radio_action_get_current_value( oneAction );
+ if ( hot != active ) {
+ /*gtk_radio_action_set_current_value( oneAction, active );*/
+ gint value = 0;
+ while ( group ) {
+ GtkRadioAction* possible = GTK_RADIO_ACTION(group->data);
+ g_object_get( G_OBJECT(possible), "value", &value, NULL );
+ if ( value == active ) {
+ /* Found the group member to set active */
+ gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(possible), TRUE );
+ break;
+ }
+
+ group = g_slist_next(group);
+ }
+ }
+ }
+ }
+ }
+ } else if ( GTK_IS_MENU_ITEM(proxies->data) ) {
+ GtkWidget* subMenu = gtk_menu_item_get_submenu( GTK_MENU_ITEM(proxies->data) );
+ GList* children = gtk_container_get_children( GTK_CONTAINER(subMenu) );
+ if ( children && (g_list_length(children) > (guint)active) ) {
+ gpointer data = g_list_nth_data( children, active );
+ gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(data), TRUE );
+ }
+ }
+
+ proxies = g_slist_next( proxies );
+ }
+
+ g_signal_emit( G_OBJECT(act), signals[CHANGED], 0);
+ }
+}
+
+void resync_sensitive( EgeSelectOneAction* act )
+{
+ GSList* proxies = gtk_action_get_proxies( GTK_ACTION(act) );
+ while ( proxies ) {
+ if ( GTK_IS_TOOL_ITEM(proxies->data) ) {
+ /* Search for the things we built up in create_tool_item() */
+ GList* children = gtk_container_get_children( GTK_CONTAINER(proxies->data) );
+ if ( children && children->data ) {
+ gpointer combodata = g_object_get_data( G_OBJECT(children->data), "ege-combo-box" );
+ if (!combodata && GTK_IS_ALIGNMENT(children->data)) {
+ GList *other = gtk_container_get_children( GTK_CONTAINER(children->data) );
+ combodata = g_object_get_data( G_OBJECT(other->data), "ege-combo-box" );
+ }
+ if ( GTK_IS_COMBO_BOX(combodata) ) {
+ /* Not implemented */
+ } else if ( GTK_IS_BOX(children->data) ) {
+ gpointer data = g_object_get_data( G_OBJECT(children->data), "ege-proxy_action-group" );
+ if ( data ) {
+ GSList* group = (GSList*)data;
+ // List is backwards in group as compared to GtkTreeModel, we better do matching.
+ while ( group ) {
+ GtkRadioAction* ract = GTK_RADIO_ACTION(group->data);
+ const gchar* label = gtk_action_get_label( GTK_ACTION( ract ) );
+
+ // Search for matching GtkTreeModel entry
+ GtkTreeIter iter;
+ gboolean valid;
+ valid = gtk_tree_model_get_iter_first( act->private_data->model, &iter );
+ gboolean sens = true;
+
+ while( valid ) {
+
+ gchar* str = 0;
+ gtk_tree_model_get( act->private_data->model, &iter,
+ act->private_data->labelColumn, &str,
+ -1 );
+
+ if( strcmp( label, str ) == 0 ) {
+ gtk_tree_model_get( act->private_data->model, &iter,
+ act->private_data->sensitiveColumn, &sens,
+ -1 );
+ break;
+ }
+ g_free( str );
+
+ valid = gtk_tree_model_iter_next( act->private_data->model, &iter );
+ }
+
+ gtk_action_set_sensitive( GTK_ACTION(ract), sens );
+ group = g_slist_next(group);
+ }
+ }
+ }
+ }
+ } else if ( GTK_IS_MENU_ITEM(proxies->data) ) {
+ /* Not implemented */
+ }
+
+ proxies = g_slist_next( proxies );
+ }
+
+ g_signal_emit( G_OBJECT(act), signals[CHANGED], 0);
+}
+
+void combo_changed_cb( GtkComboBox* widget, gpointer user_data )
+{
+ EgeSelectOneAction *act = EGE_SELECT_ONE_ACTION(user_data);
+ gchar *text = 0;
+ GtkComboBox *cb = GTK_COMBO_BOX (widget);
+ gint newActive = gtk_combo_box_get_active(widget);
+
+ if (gtk_combo_box_get_has_entry (cb)) {
+ GtkBin *bin = GTK_BIN (cb);
+ GtkEntry *entry = GTK_ENTRY (gtk_bin_get_child (bin));
+
+ text = g_strdup (gtk_entry_get_text (entry));
+ }
+ else {
+ GtkTreeIter iter;
+
+ if (gtk_combo_box_get_active_iter (cb, &iter)) {
+ GtkTreeModel *model = gtk_combo_box_get_model (cb);
+
+ gtk_tree_model_get (model, &iter, 0, &text, -1);
+ }
+ }
+
+ if (!text) {
+ /* User probably deleted the data in the model */
+ return;
+ }
+
+ if (newActive == -1) {
+ /* indicates the user is entering text for a custom aka "open" value */
+ if (act->private_data->pendingText && text && (strcmp(act->private_data->pendingText, text) == 0) ) {
+ /* The currently entered data matches the last seen */
+ } else {
+ if (act->private_data->pendingText) {
+ g_free(act->private_data->pendingText);
+ }
+ act->private_data->pendingText = text;
+ text = 0;
+ }
+ } else if (newActive != act->private_data->active) {
+ if (act->private_data->pendingText) {
+ g_free(act->private_data->pendingText);
+ act->private_data->pendingText = 0;
+ }
+ g_object_set( G_OBJECT(act), "active", newActive, NULL );
+ }
+
+ if (text) {
+ g_free(text);
+ text = 0;
+ }
+}
+
+gboolean combo_entry_focus_lost_cb( GtkWidget *widget, GdkEventFocus *event, gpointer data )
+{
+ EgeSelectOneAction* act = EGE_SELECT_ONE_ACTION(data);
+ (void)widget;
+ (void)event;
+
+ commit_pending_change(act);
+
+ return FALSE;
+}
+
+void combo_entry_changed_cb( GtkEntry* widget, gpointer user_data )
+{
+ EgeSelectOneAction* act = EGE_SELECT_ONE_ACTION(user_data);
+ (void)widget;
+ commit_pending_change(act);
+}
+
+void commit_pending_change(EgeSelectOneAction *act)
+{
+ if (act->private_data->pendingText) {
+ if (act->private_data->activeText && (strcmp(act->private_data->pendingText, act->private_data->activeText) == 0)) {
+ /* Was the same value */
+ g_free(act->private_data->pendingText);
+ act->private_data->pendingText = 0;
+ } else {
+ gint matching = find_text_index(act, act->private_data->pendingText);
+
+ if (act->private_data->activeText) {
+ g_free(act->private_data->activeText);
+ }
+ act->private_data->activeText = act->private_data->pendingText;
+ act->private_data->pendingText = 0;
+
+ if (matching >= 0) {
+ g_free(act->private_data->activeText);
+ act->private_data->activeText = 0;
+ g_object_set( G_OBJECT(act), "active", matching, NULL );
+ } else if (act->private_data->active != -1) {
+ g_object_set( G_OBJECT(act), "active", -1, NULL );
+ } else {
+ resync_active( act, -1, TRUE );
+ }
+ }
+ }
+}
+
+gint find_text_index(EgeSelectOneAction *act, gchar const* text)
+{
+ gint index = -1;
+
+ if (text) {
+ GtkTreeIter iter;
+ gboolean valid = gtk_tree_model_get_iter_first( act->private_data->model, &iter );
+ gint curr = 0;
+ while ( valid && (index < 0) ) {
+ gchar* str = 0;
+ gtk_tree_model_get( act->private_data->model, &iter,
+ act->private_data->labelColumn, &str,
+ -1 );
+
+ if (str && (strcmp(text, str) == 0)) {
+ index = curr;
+ }
+
+ g_free(str);
+ str = 0;
+
+ curr++;
+ valid = gtk_tree_model_iter_next( act->private_data->model, &iter );
+ }
+ }
+
+ return index;
+}
+
+void menu_toggled_cb( GtkWidget* obj, gpointer data )
+{
+ GtkCheckMenuItem* item = GTK_CHECK_MENU_ITEM(obj);
+ EgeSelectOneAction* act = (EgeSelectOneAction*)g_object_get_qdata( G_OBJECT(obj), gDataName );
+ gint newActive = GPOINTER_TO_INT(data);
+ if ( gtk_check_menu_item_get_active(item) && (newActive != act->private_data->active) ) {
+ g_object_set( G_OBJECT(act), "active", newActive, NULL );
+ }
+}
+
+void proxy_action_chagned_cb( GtkRadioAction* action, GtkRadioAction* current, gpointer user_data )
+{
+ (void)current;
+ if ( gtk_toggle_action_get_active( GTK_TOGGLE_ACTION(action) ) ) {
+ EgeSelectOneAction* act = EGE_SELECT_ONE_ACTION(user_data);
+ gint newActive = gtk_radio_action_get_current_value( action );
+ if ( newActive != act->private_data->active ) {
+ g_object_set( G_OBJECT(act), "active", newActive, NULL );
+ }
+ }
+}
+
+int scan_max_width( GtkTreeModel *model, gint labelColumn )
+{
+ int maxUsed = 0;
+ GtkTreeIter iter;
+ gboolean valid = gtk_tree_model_get_iter_first( model, &iter );
+ while ( valid ) {
+ gchar* str = NULL;
+ gtk_tree_model_get( model, &iter, labelColumn, &str, -1 );
+ if (str != NULL){
+ int count = strlen(str);
+ if (count > maxUsed) {
+ maxUsed = count;
+ }
+ g_free(str);
+ }
+ valid = gtk_tree_model_iter_next( model, &iter );
+ }
+ return maxUsed;
+}
+
+/*
+ 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/widgets/ege-select-one-action.h b/src/widgets/ege-select-one-action.h
new file mode 100644
index 000000000..0c5cecaa3
--- /dev/null
+++ b/src/widgets/ege-select-one-action.h
@@ -0,0 +1,245 @@
+#ifndef SEEN_EGE_SELECT_ONE_ACTION
+#define SEEN_EGE_SELECT_ONE_ACTION
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ */
+/* ***** 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 Select One Action.
+ *
+ * The Initial Developer of the Original Code is
+ * Jon A. Cruz.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * 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 ***** */
+
+/** \file
+ * GtkAction subclass that represents a set of values the user may select
+ * one from at a given time.
+ * This can manifest as a popup menu, a ComboBox, a set of toggle buttons,
+ * etc.
+ */
+
+/* Note: this file should be kept compilable as both .cpp and .c */
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+
+#define EGE_SELECT_ONE_ACTION_TYPE ( ege_select_one_action_get_type() )
+#define EGE_SELECT_ONE_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_CAST( (obj), EGE_SELECT_ONE_ACTION_TYPE, EgeSelectOneAction) )
+#define EGE_SELECT_ONE_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( (klass), EGE_SELECT_ONE_ACTION_TYPE, EgeSelectOneActionClass) )
+#define IS_EGE_SELECT_ONE_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_TYPE( (obj), EGE_SELECT_ONE_ACTION_TYPE) )
+#define IS_EGE_SELECT_ONE_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE( (klass), EGE_SELECT_ONE_ACTION_TYPE) )
+#define EGE_SELECT_ONE_ACTION_GET_CLASS( obj ) ( G_TYPE_INSTANCE_GET_CLASS( (obj), EGE_SELECT_ONE_ACTION_TYPE, EgeSelectOneActionClass) )
+
+typedef struct _EgeSelectOneAction EgeSelectOneAction;
+typedef struct _EgeSelectOneActionClass EgeSelectOneActionClass;
+typedef struct _EgeSelectOneActionPrivate EgeSelectOneActionPrivate;
+
+/**
+ * Instance structure of EgeSelectOneAction.
+ */
+struct _EgeSelectOneAction
+{
+ /** Parent instance structure. */
+ GtkAction action;
+
+ /** Pointer to private instance data. */
+ EgeSelectOneActionPrivate *private_data;
+};
+
+/**
+ * Class structure of EgeSelectOneAction.
+ */
+struct _EgeSelectOneActionClass
+{
+ /** Parent class structure. */
+ GtkActionClass parent_class;
+
+ void (*changed) (EgeSelectOneAction* action);
+};
+
+/** Standard Gtk type function */
+GType ege_select_one_action_get_type( void );
+
+/**
+ * Creates a new EgeSelectOneAction instance.
+ * This is a GtkAction subclass that represents a set of values the user
+ * may select one from at a given time.
+ * This can manifest as a popup menu, a ComboBox, a set of toggle buttons,
+ * etc.
+ *
+ * @param name Functional name for the action.
+ * @param label Display label for the action.
+ * @param tooltip Tooltip for the action.
+ * @param stock_id Icon id to use.
+ * @param model the source of choices to present.
+ */
+EgeSelectOneAction* ege_select_one_action_new( const gchar *name,
+ const gchar *label,
+ const gchar *tooltip,
+ const gchar *stock_id,
+ GtkTreeModel* model );
+
+GtkTreeModel *ege_select_one_action_get_model(EgeSelectOneAction* action );
+
+/**
+ * Returns the index of the currently selected item.
+ *
+ * @param action The action to fetch the selected index for.
+ */
+gint ege_select_one_action_get_active( EgeSelectOneAction* action );
+
+/**
+ * Returns the text of the currently selected item.
+ *
+ * @param action The action to fetch the text for.
+ * @return the selected text. The caller is responsible to call g_free() on it when done.
+ */
+gchar *ege_select_one_action_get_active_text( EgeSelectOneAction* action );
+
+/**
+ * Sets the text of the currently selected item.
+ *
+ * @param action The action to fetch the text for.
+ * @param text the text to set.
+ */
+void ege_select_one_action_set_active_text( EgeSelectOneAction* action, gchar const *text );
+
+/**
+ * Sets the currently selected item.
+ *
+ * @param action The action to fetch the selected index for.
+ * @param val index of the item to make selected.
+ */
+void ege_select_one_action_set_active( EgeSelectOneAction* action, gint val );
+
+//void ege_select_one_action_set_sensitive( EgeSelectOneAction *action, gint val, gboolean sensitive );
+
+/**
+ * Update sensitive parameters.
+ * @param action The action to update.
+ */
+void ege_select_one_action_update_sensitive( EgeSelectOneAction *action );
+
+/**
+ * Returns the column used for the display label.
+ *
+ * @param action The action to fetch the label column for.
+ */
+gint ege_select_one_action_get_label_column( EgeSelectOneAction* action );
+
+/**
+ * Sets the column used for the display label.
+ *
+ * @param action The action to set the label column for.
+ * @param col column to use.
+ */
+void ege_select_one_action_set_label_column( EgeSelectOneAction* action, gint col );
+
+
+/**
+ * Returns the column used for the display icon.
+ *
+ * @param action The action to fetch the icon column for.
+ */
+gint ege_select_one_action_get_icon_column( EgeSelectOneAction* action );
+
+/**
+ * Sets the column used for the display icon.
+ *
+ * @param action The action to set the icon column for.
+ * @param col column to use.
+ */
+void ege_select_one_action_set_icon_column( EgeSelectOneAction* action, gint col );
+
+gint ege_select_one_action_get_icon_size( EgeSelectOneAction* action );
+
+void ege_select_one_action_set_icon_size( EgeSelectOneAction* action, gint size );
+
+
+/**
+ * Returns the column used for the tooltip.
+ *
+ * @param action The action to fetch the tooltip column for.
+ */
+gint ege_select_one_action_get_tooltip_column( EgeSelectOneAction* action );
+
+/**
+ * Sets the column used for the tooltip.
+ *
+ * @param action The action to set the tooltip column for.
+ * @param col column to use.
+ */
+void ege_select_one_action_set_tooltip_column( EgeSelectOneAction* action, gint col );
+
+
+/**
+ * Returns the column used for tracking sensitivity.
+ *
+ * @param action The action to fetch the sensitive column for.
+ */
+gint ege_select_one_action_get_sensitive_column( EgeSelectOneAction* action );
+
+/**
+ * Sets the column used for sensitivity (if any).
+ *
+ * @param action The action to set the sensitive column for.
+ * @param col column to use.
+ */
+void ege_select_one_action_set_sensitive_column( EgeSelectOneAction* action, gint col );
+
+
+/**
+ * Sets a hint to be used in determining the display form.
+ * This is the XForms style 'appearance' hint: "full", "compact", "minimal".
+ *
+ * @param action The action to set the tooltip column for.
+ * @param val The value of the appearance hint.
+ */
+void ege_select_one_action_set_appearance( EgeSelectOneAction* action, gchar const* val );
+
+/**
+ * Sets to allow or disallow free entry additions to the list.
+ * The default is "closed" selections that do not allow additions/edits.
+ * This is the XForms functional 'selection' attribute: "open", "closed".
+ *
+ * @param action The action to set the tooltip column for.
+ * @param val The value of the selection attribute.
+ */
+void ege_select_one_action_set_selection( EgeSelectOneAction *action, gchar const* val );
+
+/* bit of a work-around */
+void ege_select_one_action_set_radio_action_type( EgeSelectOneAction* action, GType radioActionType );
+
+G_END_DECLS
+
+#endif /* SEEN_EGE_SELECT_ONE_ACTION */
diff --git a/src/widgets/eraser-toolbar.cpp b/src/widgets/eraser-toolbar.cpp
index 14e7cbf4e..f547cbd8b 100644
--- a/src/widgets/eraser-toolbar.cpp
+++ b/src/widgets/eraser-toolbar.cpp
@@ -35,9 +35,9 @@
#include "desktop-handles.h"
#include "desktop.h"
#include "document-undo.h"
-#include "ege-adjustment-action.h"
-#include "ege-select-one-action.h"
-#include "ink-action.h"
+#include "widgets/ege-adjustment-action.h"
+#include "widgets/ege-select-one-action.h"
+#include "widgets/ink-action.h"
#include "preferences.h"
#include "toolbox.h"
#include "ui/icon-names.h"
diff --git a/src/widgets/font-selector.cpp b/src/widgets/font-selector.cpp
index 327349844..943434868 100644
--- a/src/widgets/font-selector.cpp
+++ b/src/widgets/font-selector.cpp
@@ -1,6 +1,4 @@
-#define __SP_FONT_SELECTOR_C__
-
-/*
+/**
* Font selection widgets
*
* Authors:
@@ -38,7 +36,11 @@
struct SPFontSelector
{
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkBox hbox;
+#else
GtkHBox hbox;
+#endif
unsigned int block_emit : 1;
@@ -59,7 +61,11 @@ struct SPFontSelector
struct SPFontSelectorClass
{
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkBoxClass parent_class;
+#else
GtkHBoxClass parent_class;
+#endif
void (* font_set) (SPFontSelector *fsel, gchar *fontspec);
};
@@ -69,8 +75,6 @@ enum {
LAST_SIGNAL
};
-static void sp_font_selector_class_init (SPFontSelectorClass *c);
-static void sp_font_selector_init (SPFontSelector *fsel);
static void sp_font_selector_dispose (GObject *object);
static void sp_font_selector_family_select_row (GtkTreeSelection *selection,
@@ -85,36 +89,18 @@ static void sp_font_selector_size_changed (GtkComboBox *combobo
static void sp_font_selector_emit_set (SPFontSelector *fsel);
static void sp_font_selector_set_sizes( SPFontSelector *fsel );
-static GtkHBoxClass *fs_parent_class = NULL;
static guint fs_signals[LAST_SIGNAL] = { 0 };
-GType sp_font_selector_get_type()
-{
- static GType type = 0;
- if (!type) {
- GTypeInfo info = {
- sizeof(SPFontSelectorClass),
- 0, // base_init
- 0, // base_finalize
- (GClassInitFunc)sp_font_selector_class_init,
- 0, // class_finalize
- 0, // class_data
- sizeof(SPFontSelector),
- 0, // n_preallocs
- (GInstanceInitFunc)sp_font_selector_init,
- 0 // value_table
- };
- type = g_type_register_static(GTK_TYPE_HBOX, "SPFontSelector", &info, static_cast<GTypeFlags>(0));
- }
- return type;
-}
+#if GTK_CHECK_VERSION(3,0,0)
+G_DEFINE_TYPE(SPFontSelector, sp_font_selector, GTK_TYPE_BOX);
+#else
+G_DEFINE_TYPE(SPFontSelector, sp_font_selector, GTK_TYPE_HBOX);
+#endif
static void sp_font_selector_class_init(SPFontSelectorClass *c)
{
GObjectClass *object_class = G_OBJECT_CLASS(c);
- fs_parent_class = (GtkHBoxClass* )g_type_class_peek_parent (c);
-
fs_signals[FONT_SET] = g_signal_new ("font_set",
G_TYPE_FROM_CLASS(object_class),
(GSignalFlags)G_SIGNAL_RUN_FIRST,
@@ -285,8 +271,8 @@ static void sp_font_selector_dispose(GObject *object)
fsel->styles.length = 0;
}
- if (G_OBJECT_CLASS(fs_parent_class)->dispose) {
- G_OBJECT_CLASS(fs_parent_class)->dispose(object);
+ if (G_OBJECT_CLASS(sp_font_selector_parent_class)->dispose) {
+ G_OBJECT_CLASS(sp_font_selector_parent_class)->dispose(object);
}
}
@@ -554,4 +540,4 @@ double sp_font_selector_get_size(SPFontSelector *fsel)
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 :
diff --git a/src/widgets/font-selector.h b/src/widgets/font-selector.h
index 66715f048..ff5472d2d 100644
--- a/src/widgets/font-selector.h
+++ b/src/widgets/font-selector.h
@@ -54,7 +54,7 @@ Glib::ustring sp_font_selector_get_fontspec (SPFontSelector *fsel);
double sp_font_selector_get_size (SPFontSelector *fsel);
-#endif // SP_FONT_SELECTOR_H
+#endif // !SP_FONT_SELECTOR_H
/*
Local Variables:
@@ -65,4 +65,4 @@ double sp_font_selector_get_size (SPFontSelector *fsel);
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 :
diff --git a/src/widgets/gradient-image.cpp b/src/widgets/gradient-image.cpp
index 64b058f62..6901b8549 100644
--- a/src/widgets/gradient-image.cpp
+++ b/src/widgets/gradient-image.cpp
@@ -1,6 +1,4 @@
-#define __SP_GRADIENT_IMAGE_C__
-
-/*
+/**
* A simple gradient preview
*
* Author:
@@ -12,18 +10,15 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
-#include "macros.h"
+#include <sigc++/sigc++.h>
+
#include "display/cairo-utils.h"
#include "gradient-image.h"
+#include "macros.h"
#include "sp-gradient.h"
-#include <sigc++/functors/ptr_fun.h>
-#include <sigc++/adaptors/bind.h>
-
#define VBLOCK 16
-static void sp_gradient_image_class_init (SPGradientImageClass *klass);
-static void sp_gradient_image_init (SPGradientImage *image);
static void sp_gradient_image_size_request (GtkWidget *widget, GtkRequisition *requisition);
#if GTK_CHECK_VERSION(3,0,0)
@@ -45,35 +40,13 @@ static void sp_gradient_image_gradient_release (SPObject *, SPGradientImage *im)
static void sp_gradient_image_gradient_modified (SPObject *, guint flags, SPGradientImage *im);
static void sp_gradient_image_update (SPGradientImage *img);
-static GtkWidgetClass *parent_class;
-
-GType sp_gradient_image_get_type(void)
-{
- static GType type = 0;
- if (!type) {
- GTypeInfo info = {
- sizeof (SPGradientImageClass),
- NULL, NULL,
- (GClassInitFunc) sp_gradient_image_class_init,
- NULL, NULL,
- sizeof (SPGradientImage),
- 0,
- (GInstanceInitFunc) sp_gradient_image_init,
- NULL
- };
- type = g_type_register_static (GTK_TYPE_WIDGET, "SPGradientImage", &info, (GTypeFlags)0);
- }
- return type;
-}
+G_DEFINE_TYPE(SPGradientImage, sp_gradient_image, GTK_TYPE_WIDGET);
static void sp_gradient_image_class_init(SPGradientImageClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
- parent_class = GTK_WIDGET_CLASS(g_type_class_peek_parent (klass));
#if GTK_CHECK_VERSION(3,0,0)
-// GObjectClass *object_class = G_OBJECT_CLASS(klass);
-
widget_class->get_preferred_width = sp_gradient_image_get_preferred_width;
widget_class->get_preferred_height = sp_gradient_image_get_preferred_height;
widget_class->draw = sp_gradient_image_draw;
@@ -116,11 +89,11 @@ static void sp_gradient_image_destroy(GtkObject *object)
image->modified_connection.~connection();
#if GTK_CHECK_VERSION(3,0,0)
- if (parent_class->destroy)
- (* (parent_class)->destroy) (object);
+ if (GTK_WIDGET_CLASS(sp_gradient_image_parent_class)->destroy)
+ GTK_WIDGET_CLASS(sp_gradient_image_parent_class)->destroy(object);
#else
- if ((GTK_OBJECT_CLASS(parent_class))->destroy)
- (* (GTK_OBJECT_CLASS(parent_class))->destroy) (object);
+ if (GTK_OBJECT_CLASS(sp_gradient_image_parent_class)->destroy)
+ GTK_OBJECT_CLASS(sp_gradient_image_parent_class)->destroy(object);
#endif
}
@@ -269,3 +242,14 @@ sp_gradient_image_update (SPGradientImage *image)
gtk_widget_queue_draw (GTK_WIDGET (image));
}
}
+
+/*
+ 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 :
diff --git a/src/widgets/gradient-image.h b/src/widgets/gradient-image.h
index 904ce4cac..0d3833441 100644
--- a/src/widgets/gradient-image.h
+++ b/src/widgets/gradient-image.h
@@ -1,7 +1,7 @@
-#ifndef __SP_GRADIENT_IMAGE_H__
-#define __SP_GRADIENT_IMAGE_H__
+#ifndef SEEN_SP_GRADIENT_IMAGE_H
+#define SEEN_SP_GRADIENT_IMAGE_H
-/*
+/**
* A simple gradient preview
*
* Author:
@@ -17,9 +17,6 @@
class SPGradient;
-#include <glib.h>
-
-#include <stddef.h>
#include <sigc++/connection.h>
#define SP_TYPE_GRADIENT_IMAGE (sp_gradient_image_get_type ())
@@ -29,15 +26,15 @@ class SPGradient;
#define SP_IS_GRADIENT_IMAGE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SP_TYPE_GRADIENT_IMAGE))
struct SPGradientImage {
- GtkWidget widget;
- SPGradient *gradient;
+ GtkWidget widget;
+ SPGradient *gradient;
- sigc::connection release_connection;
- sigc::connection modified_connection;
+ sigc::connection release_connection;
+ sigc::connection modified_connection;
};
struct SPGradientImageClass {
- GtkWidgetClass parent_class;
+ GtkWidgetClass parent_class;
};
GType sp_gradient_image_get_type (void);
@@ -47,3 +44,14 @@ GdkPixbuf *sp_gradient_to_pixbuf (SPGradient *gr, int width, int height);
void sp_gradient_image_set_gradient (SPGradientImage *gi, SPGradient *gr);
#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 :
diff --git a/src/widgets/gradient-selector.cpp b/src/widgets/gradient-selector.cpp
index 871d1ee4c..a5e16aed2 100644
--- a/src/widgets/gradient-selector.cpp
+++ b/src/widgets/gradient-selector.cpp
@@ -16,13 +16,15 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
+
+#include <gtkmm/treeview.h>
+
#include "gradient-vector.h"
-#include <gtk/gtk.h>
#include "document.h"
-#include "../document-undo.h"
-#include "../document-private.h"
-#include "../gradient-chemistry.h"
+#include "document-undo.h"
+#include "document-private.h"
+#include "gradient-chemistry.h"
#include "inkscape.h"
#include "verbs.h"
#include "helper/action.h"
@@ -47,8 +49,6 @@ enum {
};
-static void sp_gradient_selector_class_init (SPGradientSelectorClass *klass);
-static void sp_gradient_selector_init (SPGradientSelector *selector);
static void sp_gradient_selector_dispose(GObject *object);
/* Signal handlers */
@@ -57,41 +57,18 @@ static void sp_gradient_selector_edit_vector_clicked (GtkWidget *w, SPGradientSe
static void sp_gradient_selector_add_vector_clicked (GtkWidget *w, SPGradientSelector *sel);
static void sp_gradient_selector_delete_vector_clicked (GtkWidget *w, SPGradientSelector *sel);
-
-static GtkVBoxClass *parent_class;
static guint signals[LAST_SIGNAL] = {0};
-GType sp_gradient_selector_get_type(void)
-{
- static GType type = 0;
- if (!type) {
- static const GTypeInfo info = {
- sizeof(SPGradientSelectorClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) sp_gradient_selector_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(SPGradientSelector),
- 0, /* n_preallocs */
- (GInstanceInitFunc) sp_gradient_selector_init,
- 0, /* value_table */
- };
-
- type = g_type_register_static( GTK_TYPE_VBOX,
- "SPGradientSelector",
- &info,
- static_cast< GTypeFlags > (0) );
- }
- return type;
-}
+#if GTK_CHECK_VERSION(3,0,0)
+G_DEFINE_TYPE(SPGradientSelector, sp_gradient_selector, GTK_TYPE_BOX);
+#else
+G_DEFINE_TYPE(SPGradientSelector, sp_gradient_selector, GTK_TYPE_VBOX);
+#endif
static void sp_gradient_selector_class_init(SPGradientSelectorClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS(klass);
- parent_class = GTK_VBOX_CLASS(g_type_class_peek_parent (klass));
-
signals[GRABBED] = g_signal_new ("grabbed",
G_TYPE_FROM_CLASS(object_class),
(GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE),
@@ -128,6 +105,11 @@ static void sp_gradient_selector_init(SPGradientSelector *sel)
{
sel->safelyInit = true;
sel->blocked = false;
+
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_orientable_set_orientation(GTK_ORIENTABLE(sel), GTK_ORIENTATION_VERTICAL);
+#endif
+
new (&sel->nonsolid) std::vector<GtkWidget*>();
new (&sel->swatch_widgets) std::vector<GtkWidget*>();
@@ -269,8 +251,8 @@ static void sp_gradient_selector_dispose(GObject *object)
sel->text_renderer = NULL;
}
- if ((G_OBJECT_CLASS(parent_class))->dispose) {
- (* (G_OBJECT_CLASS(parent_class))->dispose) (object);
+ if ((G_OBJECT_CLASS(sp_gradient_selector_parent_class))->dispose) {
+ (G_OBJECT_CLASS(sp_gradient_selector_parent_class))->dispose(object);
}
}
diff --git a/src/widgets/gradient-selector.h b/src/widgets/gradient-selector.h
index 1f58de2e4..e090d7cbd 100644
--- a/src/widgets/gradient-selector.h
+++ b/src/widgets/gradient-selector.h
@@ -19,27 +19,23 @@
# include <config.h>
#endif
-#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
-#include <glibmm/threads.h>
-#endif
-
-#include <glib.h>
-#include <gtk/gtk.h>
-
-#include <gtkmm/entry.h>
-#include <gtkmm/label.h>
-#include <gtkmm/table.h>
#include <gtkmm/liststore.h>
-#include <gtkmm/treeview.h>
#include <gtkmm/scrolledwindow.h>
#include <vector>
-#include "sp-gradient.h"
#include "sp-gradient-spread.h"
#include "sp-gradient-units.h"
+class SPDocument;
class SPGradient;
+namespace Gtk {
+class CellRendererPixbuf;
+class CellRendererText;
+class ScrolledWindow;
+class TreeView;
+}
+
#define SP_TYPE_GRADIENT_SELECTOR (sp_gradient_selector_get_type ())
#define SP_GRADIENT_SELECTOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_GRADIENT_SELECTOR, SPGradientSelector))
#define SP_GRADIENT_SELECTOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), SP_TYPE_GRADIENT_SELECTOR, SPGradientSelectorClass))
@@ -49,11 +45,18 @@ class SPGradient;
struct SPGradientSelector {
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkBox vbox;
+#else
GtkVBox vbox;
+#endif
enum SelectorMode {
MODE_LINEAR,
MODE_RADIAL,
+#ifdef WITH_MESH
+ MODE_MESH,
+#endif
MODE_SWATCH
};
@@ -128,7 +131,11 @@ struct SPGradientSelector {
};
struct SPGradientSelectorClass {
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkBoxClass parent_class;
+#else
GtkVBoxClass parent_class;
+#endif
void (* grabbed) (SPGradientSelector *sel);
void (* dragged) (SPGradientSelector *sel);
diff --git a/src/widgets/gradient-toolbar.cpp b/src/widgets/gradient-toolbar.cpp
index 9cd742fb4..b6378b251 100644
--- a/src/widgets/gradient-toolbar.cpp
+++ b/src/widgets/gradient-toolbar.cpp
@@ -22,12 +22,12 @@
#include "desktop.h"
#include "document-undo.h"
#include "document.h"
-#include "ege-adjustment-action.h"
-#include "ege-select-one-action.h"
+#include "widgets/ege-adjustment-action.h"
+#include "widgets/ege-select-one-action.h"
#include "gradient-chemistry.h"
#include "gradient-drag.h"
#include "gradient-toolbar.h"
-#include "ink-action.h"
+#include "widgets/ink-action.h"
#include "macros.h"
#include "preferences.h"
#include "selection.h"
diff --git a/src/widgets/gradient-vector.cpp b/src/widgets/gradient-vector.cpp
index 17ac887c4..6607c90d2 100644
--- a/src/widgets/gradient-vector.cpp
+++ b/src/widgets/gradient-vector.cpp
@@ -23,6 +23,7 @@
# include "config.h"
#endif
+#include <glibmm.h>
#include "gradient-vector.h"
#include "ui/widget/color-preview.h"
#include "verbs.h"
@@ -30,17 +31,17 @@
#include "macros.h"
#include <glibmm/i18n.h>
#include <set>
-#include "../widgets/gradient-image.h"
-#include "../inkscape.h"
-#include "../document-private.h"
-#include "../gradient-chemistry.h"
-#include "../helper/window.h"
+#include "widgets/gradient-image.h"
+#include "inkscape.h"
+#include "document-private.h"
+#include "gradient-chemistry.h"
+#include "helper/window.h"
#include "io/resource.h"
#include "xml/repr.h"
-#include "../dialogs/dialog-events.h"
-#include "../preferences.h"
+#include "ui/dialog-events.h"
+#include "preferences.h"
#include "svg/css-ostringstream.h"
#include "sp-stop.h"
#include "selection-chemistry.h"
@@ -50,8 +51,7 @@
#include "desktop.h"
#include "layer-manager.h"
-#include <sigc++/functors/ptr_fun.h>
-#include <sigc++/adaptors/bind.h>
+#include <sigc++/sigc++.h>
#include "document-undo.h"
using Inkscape::DocumentUndo;
@@ -61,9 +61,6 @@ enum {
LAST_SIGNAL
};
-static void sp_gradient_vector_selector_class_init(SPGradientVectorSelectorClass *klass);
-static void sp_gradient_vector_selector_init(SPGradientVectorSelector *gvs);
-
#if GTK_CHECK_VERSION(3,0,0)
static void sp_gradient_vector_selector_destroy(GtkWidget *object);
#else
@@ -79,7 +76,6 @@ static SPStop *get_selected_stop( GtkWidget *vb);
void gr_get_usage_counts(SPDocument *doc, std::map<SPGradient *, gint> *mapUsageCount );
unsigned long sp_gradient_to_hhssll(SPGradient *gr);
-static GtkVBoxClass *parent_class;
static guint signals[LAST_SIGNAL] = {0};
// TODO FIXME kill these globals!!!
@@ -88,35 +84,15 @@ static win_data wd;
static gint x = -1000, y = -1000, w = 0, h = 0; // impossible original values to make sure they are read from prefs
static Glib::ustring const prefs_path = "/dialogs/gradienteditor/";
-GType sp_gradient_vector_selector_get_type(void)
-{
- static GType type = 0;
- if (!type) {
- static const GTypeInfo info = {
- sizeof(SPGradientVectorSelectorClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- reinterpret_cast<GClassInitFunc>(sp_gradient_vector_selector_class_init),
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(SPGradientVectorSelector),
- 0, /* n_preallocs */
- reinterpret_cast<GInstanceInitFunc>(sp_gradient_vector_selector_init),
- 0, /* value_table */
- };
-
- type = g_type_register_static( GTK_TYPE_VBOX,
- "SPGradientVectorSelector",
- &info,
- static_cast< GTypeFlags >(0) );
- }
- return type;
-}
+#if GTK_CHECK_VERSION(3,0,0)
+G_DEFINE_TYPE(SPGradientVectorSelector, sp_gradient_vector_selector, GTK_TYPE_BOX);
+#else
+G_DEFINE_TYPE(SPGradientVectorSelector, sp_gradient_vector_selector, GTK_TYPE_VBOX);
+#endif
static void sp_gradient_vector_selector_class_init(SPGradientVectorSelectorClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
- parent_class = static_cast<GtkVBoxClass*>(g_type_class_peek_parent(klass));
signals[VECTOR_SET] = g_signal_new( "vector_set",
G_TYPE_FROM_CLASS(gobject_class),
@@ -138,6 +114,10 @@ static void sp_gradient_vector_selector_class_init(SPGradientVectorSelectorClass
static void sp_gradient_vector_selector_init(SPGradientVectorSelector *gvs)
{
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_orientable_set_orientation(GTK_ORIENTABLE(gvs), GTK_ORIENTATION_VERTICAL);
+#endif
+
gvs->idlabel = TRUE;
gvs->swatched = false;
@@ -181,12 +161,12 @@ static void sp_gradient_vector_selector_destroy(GtkObject *object)
gvs->tree_select_connection.~connection();
#if GTK_CHECK_VERSION(3,0,0)
- if ((reinterpret_cast<GtkWidgetClass *>(parent_class))->destroy) {
- (* (reinterpret_cast<GtkWidgetClass *>(parent_class))->destroy) (object);
+ if ((GTK_WIDGET_CLASS(sp_gradient_vector_selector_parent_class))->destroy) {
+ (GTK_WIDGET_CLASS(sp_gradient_vector_selector_parent_class))->destroy(object);
}
#else
- if ((reinterpret_cast<GtkObjectClass *>(parent_class))->destroy) {
- (* (reinterpret_cast<GtkObjectClass *>(parent_class))->destroy) (object);
+ if ((GTK_OBJECT_CLASS(sp_gradient_vector_selector_parent_class))->destroy) {
+ (GTK_OBJECT_CLASS(sp_gradient_vector_selector_parent_class))->destroy(object);
}
#endif
}
@@ -488,10 +468,10 @@ void SPGradientVectorSelector::setSwatched()
### Vector Editing Widget
##################################################################*/
-#include "../widgets/sp-color-notebook.h"
-#include "../widgets/widget-sizes.h"
-#include "../xml/node-event-vector.h"
-#include "../svg/svg-color.h"
+#include "widgets/sp-color-notebook.h"
+#include "widgets/widget-sizes.h"
+#include "xml/node-event-vector.h"
+#include "svg/svg-color.h"
#define PAD 4
diff --git a/src/widgets/gradient-vector.h b/src/widgets/gradient-vector.h
index b63120a6e..5ae90b28f 100644
--- a/src/widgets/gradient-vector.h
+++ b/src/widgets/gradient-vector.h
@@ -19,16 +19,8 @@
# include "config.h"
#endif
-#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
-#include <glibmm/threads.h>
-#endif
-
#include <gtkmm/liststore.h>
-
-#include <stddef.h>
#include <sigc++/connection.h>
-
-#include <gtk/gtk.h>
#include "gradient-selector.h"
#define SP_TYPE_GRADIENT_VECTOR_SELECTOR (sp_gradient_vector_selector_get_type ())
@@ -43,7 +35,11 @@ class SPGradient;
class SPStop;
struct SPGradientVectorSelector {
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkBox vbox;
+#else
GtkVBox vbox;
+#endif
guint idlabel : 1;
@@ -65,7 +61,11 @@ struct SPGradientVectorSelector {
};
struct SPGradientVectorSelectorClass {
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkBoxClass parent_class;
+#else
GtkVBoxClass parent_class;
+#endif
void (* vector_set) (SPGradientVectorSelector *gvs, SPGradient *gr);
};
diff --git a/src/widgets/icon.cpp b/src/widgets/icon.cpp
index eb16cfece..a6e53d638 100644
--- a/src/widgets/icon.cpp
+++ b/src/widgets/icon.cpp
@@ -247,7 +247,11 @@ gboolean IconImpl::draw(GtkWidget *widget, cairo_t* cr)
bool unref_image = false;
/* copied from the expose function of GtkImage */
+#if GTK_CHECK_VERSION(3,0,0)
+ if (gtk_widget_get_state_flags (GTK_WIDGET(icon)) != GTK_STATE_FLAG_NORMAL && image) {
+#else
if (gtk_widget_get_state (GTK_WIDGET(icon)) != GTK_STATE_NORMAL && image) {
+#endif
GtkIconSource *source = gtk_icon_source_new();
gtk_icon_source_set_pixbuf(source, icon->pb);
gtk_icon_source_set_size(source, GTK_ICON_SIZE_SMALL_TOOLBAR); // note: this is boilerplate and not used
@@ -685,6 +689,7 @@ void IconImpl::setupLegacyNaming() {
legacyNames["draw-star"] ="star_angled";
legacyNames["path-mode-bezier"] ="bezier_mode";
legacyNames["path-mode-spiro"] ="spiro_splines_mode";
+ legacyNames["path-mode-bspline"] ="bspline_mode";
legacyNames["path-mode-polyline"] ="polylines_mode";
legacyNames["path-mode-polyline-paraxial"] ="paraxial_lines_mode";
legacyNames["draw-use-tilt"] ="guse_tilt";
diff --git a/src/widgets/icon.h b/src/widgets/icon.h
index e1dae0d6a..5838d8de4 100644
--- a/src/widgets/icon.h
+++ b/src/widgets/icon.h
@@ -14,14 +14,6 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
-#include <glibmm/threads.h>
-#endif
-
#include <gtkmm/widget.h>
#include "icon-size.h"
diff --git a/src/widgets/ink-action.cpp b/src/widgets/ink-action.cpp
new file mode 100644
index 000000000..5941c31e4
--- /dev/null
+++ b/src/widgets/ink-action.cpp
@@ -0,0 +1,638 @@
+#include "widgets/icon.h"
+#include "icon-size.h"
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include "widgets/ink-action.h"
+
+#include "widgets/button.h"
+
+static void ink_action_finalize( GObject* obj );
+static void ink_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec );
+static void ink_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec );
+
+static GtkWidget* ink_action_create_menu_item( GtkAction* action );
+static GtkWidget* ink_action_create_tool_item( GtkAction* action );
+
+struct _InkActionPrivate
+{
+ gchar* iconId;
+ Inkscape::IconSize iconSize;
+};
+
+#define INK_ACTION_GET_PRIVATE( o ) ( G_TYPE_INSTANCE_GET_PRIVATE( (o), INK_ACTION_TYPE, InkActionPrivate ) )
+
+G_DEFINE_TYPE(InkAction, ink_action, GTK_TYPE_ACTION);
+
+enum {
+ PROP_INK_ID = 1,
+ PROP_INK_SIZE
+};
+
+static void ink_action_class_init( InkActionClass* klass )
+{
+ if ( klass ) {
+ GObjectClass * objClass = G_OBJECT_CLASS( klass );
+
+ objClass->finalize = ink_action_finalize;
+ objClass->get_property = ink_action_get_property;
+ objClass->set_property = ink_action_set_property;
+
+ klass->parent_class.create_menu_item = ink_action_create_menu_item;
+ klass->parent_class.create_tool_item = ink_action_create_tool_item;
+ /*klass->parent_class.connect_proxy = connect_proxy;*/
+ /*klass->parent_class.disconnect_proxy = disconnect_proxy;*/
+
+ g_object_class_install_property( objClass,
+ PROP_INK_ID,
+ g_param_spec_string( "iconId",
+ "Icon ID",
+ "The id for the icon",
+ "",
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ g_object_class_install_property( objClass,
+ PROP_INK_SIZE,
+ g_param_spec_int( "iconSize",
+ "Icon Size",
+ "The size the icon",
+ (int)Inkscape::ICON_SIZE_MENU,
+ (int)Inkscape::ICON_SIZE_DECORATION,
+ (int)Inkscape::ICON_SIZE_SMALL_TOOLBAR,
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ g_type_class_add_private( klass, sizeof(InkActionClass) );
+ }
+}
+
+static void ink_action_init( InkAction* action )
+{
+ action->private_data = INK_ACTION_GET_PRIVATE( action );
+ action->private_data->iconId = 0;
+ action->private_data->iconSize = Inkscape::ICON_SIZE_SMALL_TOOLBAR;
+}
+
+static void ink_action_finalize( GObject* obj )
+{
+ InkAction* action = INK_ACTION( obj );
+
+ g_free( action->private_data->iconId );
+ g_free( action->private_data );
+
+}
+
+//Any strings passed in should already be localised
+InkAction* ink_action_new( const gchar *name,
+ const gchar *label,
+ const gchar *tooltip,
+ const gchar *inkId,
+ Inkscape::IconSize size )
+{
+ GObject* obj = (GObject*)g_object_new( INK_ACTION_TYPE,
+ "name", name,
+ "label", label,
+ "tooltip", tooltip,
+ "iconId", inkId,
+ "iconSize", size,
+ NULL );
+
+ InkAction* action = INK_ACTION( obj );
+
+ return action;
+}
+
+static void ink_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec )
+{
+ InkAction* action = INK_ACTION( obj );
+ (void)action;
+ switch ( propId ) {
+ case PROP_INK_ID:
+ {
+ g_value_set_string( value, action->private_data->iconId );
+ }
+ break;
+
+ case PROP_INK_SIZE:
+ {
+ g_value_set_int( value, action->private_data->iconSize );
+ }
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
+ }
+}
+
+void ink_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec )
+{
+ InkAction* action = INK_ACTION( obj );
+ (void)action;
+ switch ( propId ) {
+ case PROP_INK_ID:
+ {
+ gchar* tmp = action->private_data->iconId;
+ action->private_data->iconId = g_value_dup_string( value );
+ g_free( tmp );
+ }
+ break;
+
+ case PROP_INK_SIZE:
+ {
+ action->private_data->iconSize = (Inkscape::IconSize)g_value_get_int( value );
+ }
+ break;
+
+ default:
+ {
+ G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
+ }
+ }
+}
+
+static GtkWidget* ink_action_create_menu_item( GtkAction* action )
+{
+ InkAction* act = INK_ACTION( action );
+ GtkWidget* item = 0;
+
+ if ( act->private_data->iconId ) {
+ gchar* label = 0;
+ g_object_get( G_OBJECT(act), "label", &label, NULL );
+
+ item = gtk_image_menu_item_new_with_mnemonic( label );
+ GtkWidget* child = sp_icon_new( Inkscape::ICON_SIZE_MENU, act->private_data->iconId );
+ // TODO this work-around is until SPIcon will live properly inside of a popup menu
+ if ( SP_IS_ICON(child) ) {
+ SPIcon* icon = SP_ICON(child);
+ sp_icon_fetch_pixbuf( icon );
+ GdkPixbuf* target = icon->pb;
+ if ( target ) {
+ child = gtk_image_new_from_pixbuf( target );
+ gtk_widget_set_sensitive(child, gtk_action_is_sensitive(action));
+ gtk_widget_destroy( GTK_WIDGET(icon) );
+ }
+ }
+ gtk_widget_show_all( child );
+ gtk_image_menu_item_set_image( GTK_IMAGE_MENU_ITEM(item), child );
+
+ g_free( label );
+ label = 0;
+ } else {
+ item = GTK_ACTION_CLASS(ink_action_parent_class)->create_menu_item( action );
+ }
+
+ return item;
+}
+
+static GtkWidget* ink_action_create_tool_item( GtkAction* action )
+{
+ InkAction* act = INK_ACTION( action );
+ GtkWidget* item = GTK_ACTION_CLASS(ink_action_parent_class)->create_tool_item(action);
+
+ if ( act->private_data->iconId ) {
+ if ( GTK_IS_TOOL_BUTTON(item) ) {
+ GtkToolButton* button = GTK_TOOL_BUTTON(item);
+
+ GtkWidget* child = sp_icon_new( act->private_data->iconSize, act->private_data->iconId );
+ gtk_tool_button_set_icon_widget( button, child );
+ } else {
+ // For now trigger a warning but don't do anything else
+ GtkToolButton* button = GTK_TOOL_BUTTON(item);
+ (void)button;
+ }
+ }
+
+ // TODO investigate if needed
+ gtk_widget_show_all( item );
+
+ return item;
+}
+
+
+
+/* --------------------------------------------------------------- */
+/* --------------------------------------------------------------- */
+/* --------------------------------------------------------------- */
+/* --------------------------------------------------------------- */
+
+
+static void ink_toggle_action_finalize( GObject* obj );
+static void ink_toggle_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec );
+static void ink_toggle_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec );
+
+static GtkWidget* ink_toggle_action_create_menu_item( GtkAction* action );
+static GtkWidget* ink_toggle_action_create_tool_item( GtkAction* action );
+
+static void ink_toggle_action_update_icon( InkToggleAction* action );
+
+struct _InkToggleActionPrivate
+{
+ gchar* iconId;
+ Inkscape::IconSize iconSize;
+};
+
+#define INK_TOGGLE_ACTION_GET_PRIVATE( o ) ( G_TYPE_INSTANCE_GET_PRIVATE( (o), INK_TOGGLE_ACTION_TYPE, InkToggleActionPrivate ) )
+
+G_DEFINE_TYPE(InkToggleAction, ink_toggle_action, GTK_TYPE_TOGGLE_ACTION);
+
+static void ink_toggle_action_class_init( InkToggleActionClass* klass )
+{
+ if ( klass ) {
+ GObjectClass * objClass = G_OBJECT_CLASS( klass );
+
+ objClass->finalize = ink_toggle_action_finalize;
+ objClass->get_property = ink_toggle_action_get_property;
+ objClass->set_property = ink_toggle_action_set_property;
+
+ klass->parent_class.parent_class.create_menu_item = ink_toggle_action_create_menu_item;
+ klass->parent_class.parent_class.create_tool_item = ink_toggle_action_create_tool_item;
+ /*klass->parent_class.connect_proxy = connect_proxy;*/
+ /*klass->parent_class.disconnect_proxy = disconnect_proxy;*/
+
+ g_object_class_install_property( objClass,
+ PROP_INK_ID,
+ g_param_spec_string( "iconId",
+ "Icon ID",
+ "The id for the icon",
+ "",
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ g_object_class_install_property( objClass,
+ PROP_INK_SIZE,
+ g_param_spec_int( "iconSize",
+ "Icon Size",
+ "The size the icon",
+ (int)Inkscape::ICON_SIZE_MENU,
+ (int)99,
+ (int)Inkscape::ICON_SIZE_SMALL_TOOLBAR,
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ g_type_class_add_private( klass, sizeof(InkToggleActionClass) );
+ }
+}
+
+static void ink_toggle_action_init( InkToggleAction* action )
+{
+ action->private_data = INK_TOGGLE_ACTION_GET_PRIVATE( action );
+ action->private_data->iconId = 0;
+ action->private_data->iconSize = Inkscape::ICON_SIZE_SMALL_TOOLBAR;
+}
+
+static void ink_toggle_action_finalize( GObject* obj )
+{
+ InkToggleAction* action = INK_TOGGLE_ACTION( obj );
+
+ g_free( action->private_data->iconId );
+ g_free( action->private_data );
+
+}
+
+InkToggleAction* ink_toggle_action_new( const gchar *name,
+ const gchar *label,
+ const gchar *tooltip,
+ const gchar *inkId,
+ Inkscape::IconSize size,
+ SPAttributeEnum attr)
+{
+ GObject* obj = (GObject*)g_object_new( INK_TOGGLE_ACTION_TYPE,
+ "name", name,
+ "label", label,
+ "tooltip", tooltip,
+ "iconId", inkId,
+ "iconSize", Inkscape::getRegisteredIconSize(size),
+ //"SP_ATTR_INKSCAPE", attr, // Why doesn't this work and do I need to use g_object_set_data below?
+ NULL );
+
+ g_object_set_data(obj, "SP_ATTR_INKSCAPE", GINT_TO_POINTER(attr));
+ InkToggleAction* action = INK_TOGGLE_ACTION( obj );
+
+ return action;
+}
+
+static void ink_toggle_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec )
+{
+ InkToggleAction* action = INK_TOGGLE_ACTION( obj );
+ (void)action;
+ switch ( propId ) {
+ case PROP_INK_ID:
+ {
+ g_value_set_string( value, action->private_data->iconId );
+ }
+ break;
+
+ case PROP_INK_SIZE:
+ {
+ g_value_set_int( value, action->private_data->iconSize );
+ }
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
+ }
+}
+
+void ink_toggle_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec )
+{
+ InkToggleAction* action = INK_TOGGLE_ACTION( obj );
+ (void)action;
+ switch ( propId ) {
+ case PROP_INK_ID:
+ {
+ gchar* tmp = action->private_data->iconId;
+ action->private_data->iconId = g_value_dup_string( value );
+ g_free( tmp );
+
+ ink_toggle_action_update_icon( action );
+ }
+ break;
+
+ case PROP_INK_SIZE:
+ {
+ action->private_data->iconSize = (Inkscape::IconSize)g_value_get_int( value );
+ }
+ break;
+
+ default:
+ {
+ G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
+ }
+ }
+}
+
+static GtkWidget* ink_toggle_action_create_menu_item( GtkAction* action )
+{
+ GtkWidget* item = GTK_TOGGLE_ACTION_CLASS(ink_toggle_action_parent_class)->parent_class.create_menu_item(action);
+
+ return item;
+}
+
+static GtkWidget* ink_toggle_action_create_tool_item( GtkAction* action )
+{
+ InkToggleAction* act = INK_TOGGLE_ACTION( action );
+
+ GtkWidget* item = GTK_TOGGLE_ACTION_CLASS(ink_toggle_action_parent_class)->parent_class.create_tool_item(action);
+ if ( GTK_IS_TOOL_BUTTON(item) ) {
+ GtkToolButton* button = GTK_TOOL_BUTTON(item);
+ if ( act->private_data->iconId ) {
+ GtkWidget* child = sp_icon_new( act->private_data->iconSize, act->private_data->iconId );
+ GtkWidget* align = gtk_alignment_new( 0.5, 0.5, 0.0, 0.0 );
+ gtk_container_add( GTK_CONTAINER(align), child );
+ gtk_tool_button_set_icon_widget( button, align );
+ } else {
+ gchar *label = 0;
+ g_object_get( G_OBJECT(action), "short_label", &label, NULL );
+ gtk_tool_button_set_label( button, label );
+ g_free( label );
+ label = 0;
+ }
+ } else {
+ // For now trigger a warning but don't do anything else
+ GtkToolButton* button = GTK_TOOL_BUTTON(item);
+ (void)button;
+ }
+ gtk_widget_show_all( item );
+
+ return item;
+}
+
+
+static void ink_toggle_action_update_icon( InkToggleAction* action )
+{
+ if ( action ) {
+ GSList* proxies = gtk_action_get_proxies( GTK_ACTION(action) );
+ while ( proxies ) {
+ if ( GTK_IS_TOOL_ITEM(proxies->data) ) {
+ if ( GTK_IS_TOOL_BUTTON(proxies->data) ) {
+ GtkToolButton* button = GTK_TOOL_BUTTON(proxies->data);
+
+ GtkWidget* child = sp_icon_new( action->private_data->iconSize, action->private_data->iconId );
+ GtkWidget* align = gtk_alignment_new( 0.5, 0.5, 0.0, 0.0 );
+ gtk_container_add( GTK_CONTAINER(align), child );
+ gtk_widget_show_all( align );
+ gtk_tool_button_set_icon_widget( button, align );
+ }
+ }
+
+ proxies = g_slist_next( proxies );
+ }
+ }
+}
+
+
+/* --------------------------------------------------------------- */
+/* --------------------------------------------------------------- */
+/* --------------------------------------------------------------- */
+/* --------------------------------------------------------------- */
+
+
+static void ink_radio_action_finalize( GObject* obj );
+static void ink_radio_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec );
+static void ink_radio_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec );
+
+static GtkWidget* ink_radio_action_create_menu_item( GtkAction* action );
+static GtkWidget* ink_radio_action_create_tool_item( GtkAction* action );
+
+struct _InkRadioActionPrivate
+{
+ gchar* iconId;
+ Inkscape::IconSize iconSize;
+};
+
+#define INK_RADIO_ACTION_GET_PRIVATE( o ) ( G_TYPE_INSTANCE_GET_PRIVATE( (o), INK_RADIO_ACTION_TYPE, InkRadioActionPrivate ) )
+
+G_DEFINE_TYPE(InkRadioAction, ink_radio_action, GTK_TYPE_RADIO_ACTION);
+
+static void ink_radio_action_class_init( InkRadioActionClass* klass )
+{
+ if ( klass ) {
+ GObjectClass * objClass = G_OBJECT_CLASS( klass );
+
+ objClass->finalize = ink_radio_action_finalize;
+ objClass->get_property = ink_radio_action_get_property;
+ objClass->set_property = ink_radio_action_set_property;
+
+ klass->parent_class.parent_class.parent_class.create_menu_item = ink_radio_action_create_menu_item;
+ klass->parent_class.parent_class.parent_class.create_tool_item = ink_radio_action_create_tool_item;
+ /*klass->parent_class.connect_proxy = connect_proxy;*/
+ /*klass->parent_class.disconnect_proxy = disconnect_proxy;*/
+
+ g_object_class_install_property( objClass,
+ PROP_INK_ID,
+ g_param_spec_string( "iconId",
+ "Icon ID",
+ "The id for the icon",
+ "",
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ g_object_class_install_property( objClass,
+ PROP_INK_SIZE,
+ g_param_spec_int( "iconSize",
+ "Icon Size",
+ "The size the icon",
+ (int)Inkscape::ICON_SIZE_MENU,
+ (int)Inkscape::ICON_SIZE_DECORATION,
+ (int)Inkscape::ICON_SIZE_SMALL_TOOLBAR,
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ g_type_class_add_private( klass, sizeof(InkRadioActionClass) );
+ }
+}
+
+static void ink_radio_action_init( InkRadioAction* action )
+{
+ action->private_data = INK_RADIO_ACTION_GET_PRIVATE( action );
+ action->private_data->iconId = 0;
+ action->private_data->iconSize = Inkscape::ICON_SIZE_SMALL_TOOLBAR;
+}
+
+static void ink_radio_action_finalize( GObject* obj )
+{
+ InkRadioAction* action = INK_RADIO_ACTION( obj );
+
+ g_free( action->private_data->iconId );
+ g_free( action->private_data );
+
+}
+
+InkRadioAction* ink_radio_action_new( const gchar *name,
+ const gchar *label,
+ const gchar *tooltip,
+ const gchar *inkId,
+ Inkscape::IconSize size )
+{
+ GObject* obj = (GObject*)g_object_new( INK_RADIO_ACTION_TYPE,
+ "name", name,
+ "label", label,
+ "tooltip", tooltip,
+ "iconId", inkId,
+ "iconSize", Inkscape::getRegisteredIconSize(size),
+ NULL );
+
+ InkRadioAction* action = INK_RADIO_ACTION( obj );
+
+ return action;
+}
+
+static void ink_radio_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec )
+{
+ InkRadioAction* action = INK_RADIO_ACTION( obj );
+ (void)action;
+ switch ( propId ) {
+ case PROP_INK_ID:
+ {
+ g_value_set_string( value, action->private_data->iconId );
+ }
+ break;
+
+ case PROP_INK_SIZE:
+ {
+ g_value_set_int( value, action->private_data->iconSize );
+ }
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
+ }
+}
+
+void ink_radio_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec )
+{
+ InkRadioAction* action = INK_RADIO_ACTION( obj );
+ (void)action;
+ switch ( propId ) {
+ case PROP_INK_ID:
+ {
+ gchar* tmp = action->private_data->iconId;
+ action->private_data->iconId = g_value_dup_string( value );
+ g_free( tmp );
+ }
+ break;
+
+ case PROP_INK_SIZE:
+ {
+ action->private_data->iconSize = (Inkscape::IconSize)g_value_get_int( value );
+ }
+ break;
+
+ default:
+ {
+ G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
+ }
+ }
+}
+
+static GtkWidget* ink_radio_action_create_menu_item( GtkAction* action )
+{
+ GtkWidget* item = GTK_RADIO_ACTION_CLASS(ink_radio_action_parent_class)->parent_class.parent_class.create_menu_item(action);
+
+ return item;
+}
+
+static GtkWidget* ink_radio_action_create_tool_item( GtkAction* action )
+{
+ InkRadioAction* act = INK_RADIO_ACTION( action );
+ GtkWidget* item = GTK_RADIO_ACTION_CLASS(ink_radio_action_parent_class)->parent_class.parent_class.create_tool_item(action);
+
+ if ( act->private_data->iconId ) {
+ if ( GTK_IS_TOOL_BUTTON(item) ) {
+ GtkToolButton* button = GTK_TOOL_BUTTON(item);
+
+ GtkWidget* child = sp_icon_new( act->private_data->iconSize, act->private_data->iconId );
+ GtkWidget* align = gtk_alignment_new( 0.5, 0.5, 0.0, 0.0 );
+ gtk_container_add( GTK_CONTAINER(align), child );
+ gtk_tool_button_set_icon_widget( button, align );
+ } else {
+ // For now trigger a warning but don't do anything else
+ GtkToolButton* button = GTK_TOOL_BUTTON(item);
+ (void)button;
+ }
+ }
+
+ // TODO investigate if needed
+ gtk_widget_show_all( item );
+
+ return item;
+}
+
+
+/* --------------------------------------------------------------- */
+/* --------------------------------------------------------------- */
+/* --------------------------------------------------------------- */
+/* --------------------------------------------------------------- */
+
+// ToolMenu Action is happily derived from http://www.gtkforums.com/viewtopic.php?t=4215
+
+G_DEFINE_TYPE(InkToolMenuAction, ink_tool_menu_action, INK_ACTION_TYPE);
+
+static void
+ink_tool_menu_action_class_init (InkToolMenuActionClass *klass)
+{
+ GtkActionClass *action_class = GTK_ACTION_CLASS (klass);
+ action_class->toolbar_item_type = GTK_TYPE_MENU_TOOL_BUTTON;
+}
+
+static void
+ink_tool_menu_action_init (InkToolMenuAction* /*tma*/)
+{
+}
+
+InkToolMenuAction *
+ink_tool_menu_action_new (const gchar *name,
+ const gchar *label,
+ const gchar *tooltip,
+ const gchar *inkId,
+ Inkscape::IconSize size )
+{
+ g_return_val_if_fail (name != NULL, NULL);
+
+ GObject* obj = (GObject*)g_object_new( INK_TOOL_MENU_ACTION_TYPE,
+ "name", name,
+ "label", label,
+ "tooltip", tooltip,
+ "iconId", inkId,
+ "iconSize", size,
+ NULL );
+
+ InkToolMenuAction* action = INK_TOOL_MENU_ACTION( obj );
+
+ return action;
+}
diff --git a/src/widgets/ink-action.h b/src/widgets/ink-action.h
new file mode 100644
index 000000000..ac5cb9873
--- /dev/null
+++ b/src/widgets/ink-action.h
@@ -0,0 +1,159 @@
+#ifndef SEEN_INK_ACTION
+#define SEEN_INK_ACTION
+
+
+#include <gtk/gtk.h>
+#include "icon-size.h"
+#include "attributes.h"
+
+/* Equivalent to GTK Actions of the same type, but can support Inkscape SVG icons */
+
+G_BEGIN_DECLS
+
+#define INK_ACTION_TYPE ( ink_action_get_type() )
+#define INK_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_CAST( (obj), INK_ACTION_TYPE, InkAction) )
+#define INK_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( (klass), INK_ACTION_TYPE, InkActionClass) )
+#define IS_INK_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_TYPE( (obj), INK_ACTION_TYPE) )
+#define IS_INK_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE( (klass), INK_ACTION_TYPE) )
+#define INK_ACTION_GET_CLASS( obj ) ( G_TYPE_INSTANCE_GET_CLASS( (obj), INK_ACTION_TYPE, InkActionClass) )
+
+typedef struct _InkAction InkAction;
+typedef struct _InkActionClass InkActionClass;
+typedef struct _InkActionPrivate InkActionPrivate;
+
+struct _InkAction
+{
+ GtkAction action;
+ InkActionPrivate *private_data;
+};
+
+struct _InkActionClass
+{
+ GtkActionClass parent_class;
+};
+
+GType ink_action_get_type( void );
+
+InkAction* ink_action_new( const gchar *name,
+ const gchar *label,
+ const gchar *tooltip,
+ const gchar *inkId,
+ Inkscape::IconSize size );
+
+
+/* --------------------------------------------------------------- */
+/* --------------------------------------------------------------- */
+/* --------------------------------------------------------------- */
+/* --------------------------------------------------------------- */
+
+
+#define INK_TOGGLE_ACTION_TYPE ( ink_toggle_action_get_type() )
+#define INK_TOGGLE_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_CAST( (obj), INK_TOGGLE_ACTION_TYPE, InkToggleAction) )
+#define INK_TOGGLE_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( (klass), INK_TOGGLE_ACTION_TYPE, InkToggleActionClass) )
+#define IS_INK_TOGGLE_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_TYPE( (obj), INK_TOGGLE_ACTION_TYPE) )
+#define IS_INK_TOGGLE_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE( (klass), INK_TOGGLE_ACTION_TYPE) )
+#define INK_TOGGLE_ACTION_GET_CLASS( obj ) ( G_TYPE_INSTANCE_GET_CLASS( (obj), INK_TOGGLE_ACTION_TYPE, InkToggleActionClass) )
+
+typedef struct _InkToggleAction InkToggleAction;
+typedef struct _InkToggleActionClass InkToggleActionClass;
+typedef struct _InkToggleActionPrivate InkToggleActionPrivate;
+
+struct _InkToggleAction
+{
+ GtkToggleAction action;
+ InkToggleActionPrivate *private_data;
+};
+
+struct _InkToggleActionClass
+{
+ GtkToggleActionClass parent_class;
+};
+
+GType ink_toggle_action_get_type( void );
+
+InkToggleAction* ink_toggle_action_new( const gchar *name,
+ const gchar *label,
+ const gchar *tooltip,
+ const gchar *inkId,
+ Inkscape::IconSize size,
+ SPAttributeEnum attr = SP_ATTR_INVALID);
+
+
+/* --------------------------------------------------------------- */
+/* --------------------------------------------------------------- */
+/* --------------------------------------------------------------- */
+/* --------------------------------------------------------------- */
+
+
+#define INK_RADIO_ACTION_TYPE ( ink_radio_action_get_type() )
+#define INK_RADIO_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_CAST( (obj), INK_RADIO_ACTION_TYPE, InkRadioAction) )
+#define INK_RADIO_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( (klass), INK_RADIO_ACTION_TYPE, InkRadioActionClass) )
+#define IS_INK_RADIO_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_TYPE( (obj), INK_RADIO_ACTION_TYPE) )
+#define IS_INK_RADIO_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE( (klass), INK_RADIO_ACTION_TYPE) )
+#define INK_RADIO_ACTION_GET_CLASS( obj ) ( G_TYPE_INSTANCE_GET_CLASS( (obj), INK_RADIO_ACTION_TYPE, InkRadioActionClass) )
+
+typedef struct _InkRadioAction InkRadioAction;
+typedef struct _InkRadioActionClass InkRadioActionClass;
+typedef struct _InkRadioActionPrivate InkRadioActionPrivate;
+
+struct _InkRadioAction
+{
+ GtkRadioAction action;
+ InkRadioActionPrivate *private_data;
+};
+
+struct _InkRadioActionClass
+{
+ GtkRadioActionClass parent_class;
+};
+
+GType ink_radio_action_get_type( void );
+
+InkRadioAction* ink_radio_action_new( const gchar *name,
+ const gchar *label,
+ const gchar *tooltip,
+ const gchar *inkId,
+ Inkscape::IconSize size );
+
+
+/* --------------------------------------------------------------- */
+/* --------------------------------------------------------------- */
+/* --------------------------------------------------------------- */
+/* --------------------------------------------------------------- */
+
+// ToolMenu Action is happily derived from http://www.gtkforums.com/viewtopic.php?t=4215
+
+#define INK_TOOL_MENU_ACTION_TYPE ( ink_tool_menu_action_get_type() )
+#define INK_TOOL_MENU_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_CAST( (obj), INK_TOOL_MENU_ACTION_TYPE, InkToolMenuAction) )
+#define INK_TOOL_MENU_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( (klass), INK_TOOL_MENU_ACTION_TYPE, InkToolMenuActionClass) )
+#define IS_INK_TOOL_MENU_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_TYPE( (obj), INK_TOOL_MENU_ACTION_TYPE) )
+#define IS_INK_TOOL_MENU_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE( (klass), INK_TOOL_MENU_ACTION_TYPE) )
+#define INK_TOOL_MENU_ACTION_GET_CLASS( obj ) ( G_TYPE_INSTANCE_GET_CLASS( (obj), INK_TOOL_MENU_ACTION_TYPE, InkToolMenuActionClass) )
+
+typedef struct _InkToolMenuAction InkToolMenuAction;
+typedef struct _InkToolMenuActionClass InkToolMenuActionClass;
+typedef struct _InkToolMenuActionPrivate InkToolMenuActionPrivate;
+
+struct _InkToolMenuAction
+{
+ InkAction action;
+};
+
+struct _InkToolMenuActionClass
+{
+ InkActionClass parent_class;
+};
+
+GType ink_tool_menu_action_get_type( void );
+
+InkToolMenuAction* ink_tool_menu_action_new( const gchar *name,
+ const gchar *label,
+ const gchar *tooltip,
+ const gchar *inkId,
+ Inkscape::IconSize size );
+
+
+
+G_END_DECLS
+
+#endif /* SEEN_INK_ACTION */
diff --git a/src/widgets/ink-comboboxentry-action.cpp b/src/widgets/ink-comboboxentry-action.cpp
new file mode 100644
index 000000000..1114d2cdb
--- /dev/null
+++ b/src/widgets/ink-comboboxentry-action.cpp
@@ -0,0 +1,958 @@
+/*
+ * A subclass of GtkAction that wraps a GtkComboBoxEntry.
+ * Features:
+ * Setting GtkEntryBox width in characters.
+ * Passing a function for formatting cells.
+ * Displaying a warning if entry text isn't in list.
+ * Check comma separated values in text against list. (Useful for font-family fallbacks.)
+ * Setting names for GtkComboBoxEntry and GtkEntry (actionName_combobox, actionName_entry)
+ * to allow setting resources.
+ *
+ * Author(s):
+ * Tavmjong Bah
+ * Jon A. Cruz <jon@joncruz.org>
+ *
+ * Copyright (C) 2010 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+/*
+ * We must provide for both a toolbar item and a menu item.
+ * As we don't know which widgets are used (or even constructed),
+ * we must keep track of things like active entry ourselves.
+ */
+
+#include <iostream>
+#include <string.h>
+#include <glibmm/ustring.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "widgets/ink-comboboxentry-action.h"
+#include "ui/icon-names.h"
+
+// Must handle both tool and menu items!
+static GtkWidget* create_tool_item( GtkAction* action );
+static GtkWidget* create_menu_item( GtkAction* action );
+
+// Internal
+static gint get_active_row_from_text( Ink_ComboBoxEntry_Action* action, const gchar* target_text, gboolean exclude = false, gboolean ignore_case = false );
+static Glib::ustring check_comma_separated_text( Ink_ComboBoxEntry_Action* action );
+
+// Callbacks
+static void combo_box_changed_cb( GtkComboBox* widget, gpointer data );
+static void entry_activate_cb( GtkEntry* widget, gpointer data );
+static gboolean match_selected_cb( GtkEntryCompletion* widget, GtkTreeModel* model, GtkTreeIter* iter, gpointer data );
+static gboolean keypress_cb( GtkWidget *widget, GdkEventKey *event, gpointer data );
+
+enum {
+ PROP_MODEL = 1,
+ PROP_COMBOBOX,
+ PROP_ENTRY,
+ PROP_ENTRY_WIDTH,
+ PROP_EXTRA_WIDTH,
+ PROP_CELL_DATA_FUNC,
+ PROP_SEPARATOR_FUNC,
+ PROP_POPUP,
+ PROP_FOCUS_WIDGET
+};
+
+enum {
+ CHANGED = 0,
+ ACTIVATED,
+ N_SIGNALS
+};
+static guint signals[N_SIGNALS] = {0};
+
+static GQuark gDataName = 0;
+
+static void ink_comboboxentry_action_init (Ink_ComboBoxEntry_Action *action);
+static void ink_comboboxentry_action_class_init (Ink_ComboBoxEntry_ActionClass *klass);
+
+G_DEFINE_TYPE(Ink_ComboBoxEntry_Action, ink_comboboxentry_action, GTK_TYPE_ACTION);
+
+static void ink_comboboxentry_action_finalize (GObject *object)
+{
+ // Free any allocated resources.
+
+ G_OBJECT_CLASS (ink_comboboxentry_action_parent_class)->finalize (object);
+}
+
+
+static void ink_comboboxentry_action_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+ Ink_ComboBoxEntry_Action *action = INK_COMBOBOXENTRY_ACTION (object);
+
+ switch(property_id) {
+
+ case PROP_MODEL:
+ action->model = GTK_TREE_MODEL( g_value_get_object( value ));
+ break;
+
+ case PROP_COMBOBOX:
+ action->combobox = GTK_COMBO_BOX (g_value_get_object (value));
+ break;
+
+ case PROP_ENTRY:
+ action->entry = GTK_ENTRY( g_value_get_object( value ));
+ break;
+
+ case PROP_ENTRY_WIDTH:
+ action->entry_width = g_value_get_int( value );
+ break;
+
+ case PROP_EXTRA_WIDTH:
+ action->extra_width = g_value_get_int( value );
+ break;
+
+ case PROP_CELL_DATA_FUNC:
+ action->cell_data_func = g_value_get_pointer( value );
+ break;
+
+ case PROP_SEPARATOR_FUNC:
+ action->separator_func = g_value_get_pointer( value );
+ break;
+
+ case PROP_POPUP:
+ action->popup = g_value_get_boolean( value );
+ break;
+
+ case PROP_FOCUS_WIDGET:
+ action->focusWidget = (GtkWidget*)g_value_get_pointer( value );
+ break;
+
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+
+static void ink_comboboxentry_action_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+ Ink_ComboBoxEntry_Action *action = INK_COMBOBOXENTRY_ACTION (object);
+
+ switch(property_id) {
+
+ case PROP_MODEL:
+ g_value_set_object (value, action->model);
+ break;
+
+ case PROP_COMBOBOX:
+ g_value_set_object (value, action->combobox);
+ break;
+
+ case PROP_ENTRY:
+ g_value_set_object (value, action->entry);
+ break;
+
+ case PROP_ENTRY_WIDTH:
+ g_value_set_int (value, action->entry_width);
+ break;
+
+ case PROP_EXTRA_WIDTH:
+ g_value_set_int (value, action->extra_width);
+ break;
+
+ case PROP_CELL_DATA_FUNC:
+ g_value_set_pointer (value, action->cell_data_func);
+ break;
+
+ case PROP_SEPARATOR_FUNC:
+ g_value_set_pointer (value, action->separator_func);
+ break;
+
+ case PROP_POPUP:
+ g_value_set_boolean (value, action->popup);
+ break;
+
+ case PROP_FOCUS_WIDGET:
+ g_value_set_pointer (value, action->focusWidget);
+ break;
+
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+ink_comboboxentry_action_connect_proxy (GtkAction *action,
+ GtkWidget *proxy)
+{
+ /* Override any proxy properties. */
+ // if (GTK_IS_MENU_ITEM (proxy)) {
+ // }
+
+ GTK_ACTION_CLASS (ink_comboboxentry_action_parent_class)->connect_proxy (action, proxy);
+}
+
+static void
+ink_comboboxentry_action_class_init (Ink_ComboBoxEntry_ActionClass *klass)
+{
+
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GtkActionClass *gtkaction_class = GTK_ACTION_CLASS (klass);
+
+ gtkaction_class->connect_proxy = ink_comboboxentry_action_connect_proxy;
+
+ gobject_class->finalize = ink_comboboxentry_action_finalize;
+ gobject_class->set_property = ink_comboboxentry_action_set_property;
+ gobject_class->get_property = ink_comboboxentry_action_get_property;
+
+ gDataName = g_quark_from_string("ink_comboboxentry-action");
+
+ klass->parent_class.create_tool_item = create_tool_item;
+ klass->parent_class.create_menu_item = create_menu_item;
+
+ g_object_class_install_property (
+ gobject_class,
+ PROP_MODEL,
+ g_param_spec_object ("model",
+ "Tree Model",
+ "Tree Model",
+ GTK_TYPE_TREE_MODEL,
+ (GParamFlags)G_PARAM_READWRITE));
+ g_object_class_install_property (
+ gobject_class,
+ PROP_COMBOBOX,
+ g_param_spec_object ("combobox",
+ "GtkComboBoxEntry",
+ "GtkComboBoxEntry",
+ GTK_TYPE_WIDGET,
+ (GParamFlags)G_PARAM_READABLE));
+ g_object_class_install_property (
+ gobject_class,
+ PROP_ENTRY,
+ g_param_spec_object ("entry",
+ "GtkEntry",
+ "GtkEntry",
+ GTK_TYPE_WIDGET,
+ (GParamFlags)G_PARAM_READABLE));
+ g_object_class_install_property (
+ gobject_class,
+ PROP_ENTRY_WIDTH,
+ g_param_spec_int ("entry_width",
+ "EntryBox width",
+ "EntryBox width (characters)",
+ -1.0, 100, -1.0,
+ (GParamFlags)G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ gobject_class,
+ PROP_EXTRA_WIDTH,
+ g_param_spec_int ("extra_width",
+ "Extra width",
+ "Extra width (px)",
+ -1.0, 500, -1.0,
+ (GParamFlags)G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ gobject_class,
+ PROP_CELL_DATA_FUNC,
+ g_param_spec_pointer ("cell_data_func",
+ "Cell Data Func",
+ "Cell Deta Function",
+ (GParamFlags)G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ gobject_class,
+ PROP_SEPARATOR_FUNC,
+ g_param_spec_pointer ("separator_func",
+ "Separator Func",
+ "Separator Function",
+ (GParamFlags)G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ gobject_class,
+ PROP_POPUP,
+ g_param_spec_boolean ("popup",
+ "Entry Popup",
+ "Entry Popup",
+ false,
+ (GParamFlags)G_PARAM_READWRITE));
+
+ g_object_class_install_property( gobject_class,
+ PROP_FOCUS_WIDGET,
+ g_param_spec_pointer( "focus-widget",
+ "Focus Widget",
+ "The widget to return focus to",
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ // We need to know when GtkComboBoxEvent or Menu ready for reading
+ signals[CHANGED] = g_signal_new( "changed",
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(Ink_ComboBoxEntry_ActionClass, changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ // Probably not needed... originally to keep track of key-presses.
+ signals[ACTIVATED] = g_signal_new( "activated",
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(Ink_ComboBoxEntry_ActionClass, activated),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+}
+
+static void ink_comboboxentry_action_init (Ink_ComboBoxEntry_Action *action)
+{
+ action->active = -1;
+ action->text = strdup("");
+ action->entry_completion = NULL;
+ action->indicator = NULL;
+ action->popup = false;
+ action->info = NULL;
+ action->info_cb = NULL;
+ action->info_cb_id = 0;
+ action->info_cb_blocked = false;
+ action->warning = NULL;
+ action->warning_cb = NULL;
+ action->warning_cb_id = 0;
+ action->warning_cb_blocked = false;
+ action->altx_name = NULL;
+ action->focusWidget = NULL;
+}
+
+Ink_ComboBoxEntry_Action *ink_comboboxentry_action_new (const gchar *name,
+ const gchar *label,
+ const gchar *tooltip,
+ const gchar *stock_id,
+ GtkTreeModel *model,
+ gint entry_width,
+ gint extra_width,
+ void *cell_data_func,
+ void *separator_func,
+ GtkWidget *focusWidget)
+{
+ g_return_val_if_fail (name != NULL, NULL);
+
+ return (Ink_ComboBoxEntry_Action*)g_object_new (INK_COMBOBOXENTRY_TYPE_ACTION,
+ "name", name,
+ "label", label,
+ "tooltip", tooltip,
+ "stock-id", stock_id,
+ "model", model,
+ "entry_width", entry_width,
+ "extra_width", extra_width,
+ "cell_data_func", cell_data_func,
+ "separator_func", separator_func,
+ "focus-widget", focusWidget,
+ NULL);
+}
+
+// Create a widget for a toolbar.
+GtkWidget* create_tool_item( GtkAction* action )
+{
+ GtkWidget* item = 0;
+
+ if ( INK_COMBOBOXENTRY_IS_ACTION( action ) && INK_COMBOBOXENTRY_ACTION(action)->model ) {
+
+ Ink_ComboBoxEntry_Action* ink_comboboxentry_action = INK_COMBOBOXENTRY_ACTION( action );
+
+ gchar *action_name = g_strdup( gtk_action_get_name( action ) );
+ gchar *combobox_name = g_strjoin( NULL, action_name, "_combobox", NULL );
+ gchar *entry_name = g_strjoin( NULL, action_name, "_entry", NULL );
+ g_free( action_name );
+
+ item = GTK_WIDGET( gtk_tool_item_new() );
+
+ GtkWidget* comboBoxEntry = gtk_combo_box_new_with_model_and_entry (ink_comboboxentry_action->model);
+ gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX (comboBoxEntry), 0);
+
+ // Name it so we can muck with it using an RC file
+ gtk_widget_set_name( comboBoxEntry, combobox_name );
+ g_free( combobox_name );
+
+ {
+ GtkWidget *align = gtk_alignment_new(0, 0.5, 0, 0);
+ gtk_container_add( GTK_CONTAINER(align), comboBoxEntry );
+ gtk_container_add( GTK_CONTAINER(item), align );
+ }
+
+ ink_comboboxentry_action->combobox = GTK_COMBO_BOX (comboBoxEntry);
+
+ //gtk_combo_box_set_active( GTK_COMBO_BOX( comboBoxEntry ), ink_comboboxentry_action->active );
+ gtk_combo_box_set_active( GTK_COMBO_BOX( comboBoxEntry ), 0 );
+
+ g_signal_connect( G_OBJECT(comboBoxEntry), "changed", G_CALLBACK(combo_box_changed_cb), action );
+
+ // Optionally add separator function...
+ if( ink_comboboxentry_action->separator_func != NULL ) {
+ gtk_combo_box_set_row_separator_func( ink_comboboxentry_action->combobox,
+ GtkTreeViewRowSeparatorFunc (ink_comboboxentry_action->separator_func),
+ NULL, NULL );
+ }
+
+ // FIXME: once gtk3 migration is done this can be removed
+ // https://bugzilla.gnome.org/show_bug.cgi?id=734915
+ gtk_widget_show_all (comboBoxEntry);
+
+ // Optionally add formatting...
+ if( ink_comboboxentry_action->cell_data_func != NULL ) {
+ GtkCellRenderer *cell = gtk_cell_renderer_text_new();
+ gtk_cell_layout_clear( GTK_CELL_LAYOUT( comboBoxEntry ) );
+ gtk_cell_layout_pack_start( GTK_CELL_LAYOUT( comboBoxEntry ), cell, true );
+ gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT( comboBoxEntry ), cell,
+ GtkCellLayoutDataFunc (ink_comboboxentry_action->cell_data_func),
+ NULL, NULL );
+ }
+
+ // Optionally widen the combobox width... which widens the drop-down list in list mode.
+ if( ink_comboboxentry_action->extra_width > 0 ) {
+ GtkRequisition req;
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_widget_get_preferred_size(GTK_WIDGET(ink_comboboxentry_action->combobox), &req, NULL);
+#else
+ gtk_widget_size_request( GTK_WIDGET( ink_comboboxentry_action->combobox ), &req );
+#endif
+ gtk_widget_set_size_request( GTK_WIDGET( ink_comboboxentry_action->combobox ),
+ req.width + ink_comboboxentry_action->extra_width, -1 );
+ }
+
+ // Get reference to GtkEntry and fiddle a bit with it.
+ GtkWidget *child = gtk_bin_get_child( GTK_BIN(comboBoxEntry) );
+
+ // Name it so we can muck with it using an RC file
+ gtk_widget_set_name( child, entry_name );
+ g_free( entry_name );
+
+ if( child && GTK_IS_ENTRY( child ) ) {
+
+ ink_comboboxentry_action->entry = GTK_ENTRY(child);
+
+ // Change width
+ if( ink_comboboxentry_action->entry_width > 0 ) {
+ gtk_entry_set_width_chars (GTK_ENTRY (child), ink_comboboxentry_action->entry_width );
+ }
+
+ // Add pop-up entry completion if required
+ if( ink_comboboxentry_action->popup ) {
+ ink_comboboxentry_action_popup_enable( ink_comboboxentry_action );
+ }
+
+ // Add altx_name if required
+ if( ink_comboboxentry_action->altx_name ) {
+ g_object_set_data( G_OBJECT( child ), ink_comboboxentry_action->altx_name, ink_comboboxentry_action->entry );
+ }
+
+ // Add signal for GtkEntry to check if finished typing.
+ g_signal_connect( G_OBJECT(child), "activate", G_CALLBACK(entry_activate_cb), action );
+ g_signal_connect( G_OBJECT(child), "key-press-event", G_CALLBACK(keypress_cb), action );
+ }
+
+ gtk_activatable_set_related_action( GTK_ACTIVATABLE (item), GTK_ACTION( action ) );
+ gtk_widget_show_all( item );
+
+ } else {
+
+ item = GTK_ACTION_CLASS(ink_comboboxentry_action_parent_class)->create_tool_item( action );
+
+ }
+
+ return item;
+}
+
+// Create a drop-down menu.
+GtkWidget* create_menu_item( GtkAction* action )
+{
+ GtkWidget* item = 0;
+
+ item = GTK_ACTION_CLASS(ink_comboboxentry_action_parent_class)->create_menu_item( action );
+ g_warning( "ink_comboboxentry_action: create_menu_item not implemented" );
+ // One can easily modify ege-select-one-action routine to implement this.
+ return item;
+}
+
+// Setters/Getters ---------------------------------------------------
+
+GtkTreeModel *ink_comboboxentry_action_get_model( Ink_ComboBoxEntry_Action* action ) {
+
+ return action->model;
+}
+
+GtkComboBox *ink_comboboxentry_action_get_comboboxentry( Ink_ComboBoxEntry_Action* action ) {
+
+ return action->combobox;
+}
+
+gchar* ink_comboboxentry_action_get_active_text( Ink_ComboBoxEntry_Action* action ) {
+
+ gchar* text = g_strdup( action->text );
+ return text;
+}
+
+/*
+ * For the font-family list we need to handle two cases:
+ * Text is in list store:
+ * In this case we use row number as the font-family list can have duplicate
+ * entries, one in the document font part and one in the system font part. In
+ * order that scrolling through the list works properly we must distinguish
+ * between the two.
+ * Text is not in the list store (i.e. default font-family is not on system):
+ * In this case we have a row number of -1, and the text must be set by hand.
+ */
+gboolean ink_comboboxentry_action_set_active_text( Ink_ComboBoxEntry_Action* action, const gchar* text, int row ) {
+
+ if( strcmp( action->text, text ) != 0 ) {
+ g_free( action->text );
+ action->text = g_strdup( text );
+ }
+
+ // Get active row or -1 if none
+ if( row < 0 ) {
+ row = get_active_row_from_text( action, action->text );
+ }
+ action->active = row;
+
+ // Set active row, check that combobox has been created.
+ if( action->combobox ) {
+ gtk_combo_box_set_active( GTK_COMBO_BOX( action->combobox ), action->active );
+ }
+
+ // Fiddle with entry
+ if( action->entry ) {
+
+ // Explicitly set text in GtkEntry box (won't be set if text not in list).
+ gtk_entry_set_text( action->entry, text );
+
+ // Show or hide warning -- this might be better moved to text-toolbox.cpp
+ if( action->info_cb_id != 0 &&
+ !action->info_cb_blocked ) {
+ g_signal_handler_block (G_OBJECT(action->entry),
+ action->info_cb_id );
+ action->info_cb_blocked = true;
+ }
+ if( action->warning_cb_id != 0 &&
+ !action->warning_cb_blocked ) {
+ g_signal_handler_block (G_OBJECT(action->entry),
+ action->warning_cb_id );
+ action->warning_cb_blocked = true;
+ }
+
+ bool set = false;
+ if( action->warning != NULL ) {
+ Glib::ustring missing = check_comma_separated_text( action );
+ if( !missing.empty() ) {
+ gtk_entry_set_icon_from_icon_name( action->entry,
+ GTK_ENTRY_ICON_SECONDARY,
+ INKSCAPE_ICON("dialog-warning") );
+ // Can't add tooltip until icon set
+ Glib::ustring warning = action->warning;
+ warning += ": ";
+ warning += missing;
+ gtk_entry_set_icon_tooltip_text( action->entry,
+ GTK_ENTRY_ICON_SECONDARY,
+ warning.c_str() );
+
+ if( action->warning_cb ) {
+
+ // Add callback if we haven't already
+ if( action->warning_cb_id == 0 ) {
+ action->warning_cb_id =
+ g_signal_connect( G_OBJECT(action->entry),
+ "icon-press",
+ G_CALLBACK(action->warning_cb),
+ action);
+ }
+ // Unblock signal
+ if( action->warning_cb_blocked ) {
+ g_signal_handler_unblock (G_OBJECT(action->entry),
+ action->warning_cb_id );
+ action->warning_cb_blocked = false;
+ }
+ }
+ set = true;
+ }
+ }
+
+ if( !set && action->info != NULL ) {
+ gtk_entry_set_icon_from_icon_name( GTK_ENTRY(action->entry),
+ GTK_ENTRY_ICON_SECONDARY,
+ INKSCAPE_ICON("edit-select-all") );
+ gtk_entry_set_icon_tooltip_text( action->entry,
+ GTK_ENTRY_ICON_SECONDARY,
+ action->info );
+
+ if( action->info_cb ) {
+ // Add callback if we haven't already
+ if( action->info_cb_id == 0 ) {
+ action->info_cb_id =
+ g_signal_connect( G_OBJECT(action->entry),
+ "icon-press",
+ G_CALLBACK(action->info_cb),
+ action);
+ }
+ // Unblock signal
+ if( action->info_cb_blocked ) {
+ g_signal_handler_unblock (G_OBJECT(action->entry),
+ action->info_cb_id );
+ action->info_cb_blocked = false;
+ }
+ }
+ set = true;
+ }
+
+ if( !set ) {
+ gtk_entry_set_icon_from_icon_name( GTK_ENTRY(action->entry),
+ GTK_ENTRY_ICON_SECONDARY,
+ NULL );
+ }
+ }
+
+ // Return if active text in list
+ gboolean found = ( action->active != -1 );
+ return found;
+}
+
+void ink_comboboxentry_action_set_entry_width( Ink_ComboBoxEntry_Action* action, gint entry_width ) {
+
+ action->entry_width = entry_width;
+
+ // Widget may not have been created....
+ if( action->entry ) {
+ gtk_entry_set_width_chars( GTK_ENTRY(action->entry), entry_width );
+ }
+}
+
+void ink_comboboxentry_action_set_extra_width( Ink_ComboBoxEntry_Action* action, gint extra_width ) {
+
+ action->extra_width = extra_width;
+
+ // Widget may not have been created....
+ if( action->combobox ) {
+ GtkRequisition req;
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_widget_get_preferred_size(GTK_WIDGET(action->combobox), &req, NULL);
+#else
+ gtk_widget_size_request( GTK_WIDGET( action->combobox ), &req );
+#endif
+ gtk_widget_set_size_request( GTK_WIDGET( action->combobox ), req.width + action->extra_width, -1 );
+ }
+}
+
+void ink_comboboxentry_action_popup_enable( Ink_ComboBoxEntry_Action* action ) {
+
+ action->popup = true;
+
+ // Widget may not have been created....
+ if( action->entry ) {
+
+ // Check we don't already have a GtkEntryCompletion
+ if( action->entry_completion ) return;
+
+ action->entry_completion = gtk_entry_completion_new();
+
+ gtk_entry_set_completion( action->entry, action->entry_completion );
+ gtk_entry_completion_set_model( action->entry_completion, action->model );
+ gtk_entry_completion_set_text_column( action->entry_completion, 0 );
+ gtk_entry_completion_set_popup_completion( action->entry_completion, true );
+ gtk_entry_completion_set_inline_completion( action->entry_completion, false );
+ gtk_entry_completion_set_inline_selection( action->entry_completion, true );
+
+ g_signal_connect (G_OBJECT (action->entry_completion), "match-selected", G_CALLBACK (match_selected_cb), action );
+
+
+ }
+}
+
+void ink_comboboxentry_action_popup_disable( Ink_ComboBoxEntry_Action* action ) {
+
+ action->popup = false;
+
+ if( action->entry_completion ) {
+ gtk_widget_destroy(GTK_WIDGET(action->entry_completion));
+ action->entry_completion = 0;
+ }
+}
+void ink_comboboxentry_action_set_tooltip( Ink_ComboBoxEntry_Action* action, const gchar* tooltip ) {
+
+ // Widget may not have been created....
+ if( action->entry ) {
+ gtk_widget_set_tooltip_text ( GTK_WIDGET(action->entry), tooltip);
+ }
+ if( action->combobox ) {
+ gtk_widget_set_tooltip_text ( GTK_WIDGET(action->combobox), tooltip);
+ }
+
+}
+
+void ink_comboboxentry_action_set_info( Ink_ComboBoxEntry_Action* action, const gchar* info ) {
+
+ g_free( action->info );
+ action->info = g_strdup( info );
+
+ // Widget may not have been created....
+ if( action->entry ) {
+ gtk_entry_set_icon_tooltip_text( GTK_ENTRY(action->entry),
+ GTK_ENTRY_ICON_SECONDARY,
+ action->info );
+ }
+}
+
+void ink_comboboxentry_action_set_info_cb( Ink_ComboBoxEntry_Action* action, gpointer info_cb ) {
+
+ action->info_cb = info_cb;
+}
+
+void ink_comboboxentry_action_set_warning( Ink_ComboBoxEntry_Action* action, const gchar* warning ) {
+
+ g_free( action->warning );
+ action->warning = g_strdup( warning );
+
+ // Widget may not have been created....
+ if( action->entry ) {
+ gtk_entry_set_icon_tooltip_text( GTK_ENTRY(action->entry),
+ GTK_ENTRY_ICON_SECONDARY,
+ action->warning );
+ }
+}
+
+void ink_comboboxentry_action_set_warning_cb( Ink_ComboBoxEntry_Action* action, gpointer warning_cb ) {
+
+ action->warning_cb = warning_cb;
+}
+
+void ink_comboboxentry_action_set_altx_name( Ink_ComboBoxEntry_Action* action, const gchar* altx_name ) {
+
+ g_free( action->altx_name );
+ action->altx_name = g_strdup( altx_name );
+
+ // Widget may not have been created....
+ if( action->entry ) {
+ g_object_set_data( G_OBJECT(action->entry), action->altx_name, action->entry );
+ }
+}
+
+// Internal ---------------------------------------------------
+
+// Return row of active text or -1 if not found. If exclude is true,
+// use 3d colunm if available to exclude row from checking (useful to
+// skip rows added for font-families included in doc and not on
+// system)
+gint get_active_row_from_text( Ink_ComboBoxEntry_Action* action, const gchar* target_text,
+ gboolean exclude, gboolean ignore_case ) {
+
+ // Check if text in list
+ gint row = 0;
+ gboolean found = false;
+ GtkTreeIter iter;
+ gboolean valid = gtk_tree_model_get_iter_first( action->model, &iter );
+ while ( valid ) {
+
+ // See if we should exclude a row
+ gboolean check = true; // If true, font-family is on system.
+ if( exclude && gtk_tree_model_get_n_columns( action->model ) > 2 ) {
+ gtk_tree_model_get( action->model, &iter, 2, &check, -1 );
+ }
+
+ if( check ) {
+ // Get text from list entry
+ gchar* text = 0;
+ gtk_tree_model_get( action->model, &iter, 0, &text, -1 ); // Column 0
+
+ if( !ignore_case ) {
+ // Case sensitive compare
+ if( strcmp( target_text, text ) == 0 ){
+ found = true;
+ break;
+ }
+ } else {
+ // Case insensitive compare
+ gchar* target_text_casefolded = g_utf8_casefold( target_text, -1 );
+ gchar* text_casefolded = g_utf8_casefold( text, -1 );
+ gboolean equal = (strcmp( target_text_casefolded, text_casefolded ) == 0 );
+ g_free( text_casefolded );
+ g_free( target_text_casefolded );
+ if( equal ) {
+ found = true;
+ break;
+ }
+ }
+ }
+
+ ++row;
+ valid = gtk_tree_model_iter_next( action->model, &iter );
+ }
+
+ if( !found ) row = -1;
+
+ return row;
+
+}
+
+// Checks if all comma separated text fragments are in the list and
+// returns a ustring with a list of missing fragments.
+// This is useful for checking if all fonts in a font-family fallback
+// list are available on the system.
+//
+// This routine could also create a Pango Markup string to show which
+// fragments are invalid in the entry box itself. See:
+// http://developer.gnome.org/pango/stable/PangoMarkupFormat.html
+// However... it appears that while one can retrieve the PangoLayout
+// for a GtkEntry box, it is only a copy and changing it has no effect.
+// PangoLayout * pl = gtk_entry_get_layout( entry );
+// pango_layout_set_markup( pl, "NEW STRING", -1 ); // DOESN'T WORK
+static Glib::ustring check_comma_separated_text( Ink_ComboBoxEntry_Action* action ) {
+
+ Glib::ustring missing;
+
+ // Parse fallback_list using a comma as deliminator
+ gchar** tokens = g_strsplit( action->text, ",", 0 );
+
+ gint i = 0;
+ while( tokens[i] != NULL ) {
+
+ // Remove any surrounding white space.
+ g_strstrip( tokens[i] );
+
+ if( get_active_row_from_text( action, tokens[i], true, true ) == -1 ) {
+ missing += tokens[i];
+ missing += ", ";
+ }
+ ++i;
+ }
+ g_strfreev( tokens );
+
+ // Remove extra comma and space from end.
+ if( missing.size() >= 2 ) {
+ missing.resize( missing.size()-2 );
+ }
+ return missing;
+}
+
+// Callbacks ---------------------------------------------------
+
+static void combo_box_changed_cb( GtkComboBox* widget, gpointer data ) {
+
+ // Two things can happen to get here:
+ // An item is selected in the drop-down menu.
+ // Text is typed.
+ // We only react here if an item is selected.
+
+ // Get action
+ Ink_ComboBoxEntry_Action *action = INK_COMBOBOXENTRY_ACTION( data );
+
+ // Check if item selected:
+ gint newActive = gtk_combo_box_get_active(widget);
+ if( newActive >= 0 && newActive != action->active ) {
+
+ action->active = newActive;
+
+ GtkTreeIter iter;
+ if( gtk_combo_box_get_active_iter( GTK_COMBO_BOX( action->combobox ), &iter ) ) {
+
+ gchar* text = 0;
+ gtk_tree_model_get( action->model, &iter, 0, &text, -1 );
+ gtk_entry_set_text( action->entry, text );
+
+ g_free( action->text );
+ action->text = text;
+ }
+
+ // Now let the world know
+ g_signal_emit( G_OBJECT(action), signals[CHANGED], 0 );
+ }
+}
+
+static void entry_activate_cb( GtkEntry* widget, gpointer data ) {
+
+ // Get text from entry box.. check if it matches a menu entry.
+
+ // Get action
+ Ink_ComboBoxEntry_Action *action = INK_COMBOBOXENTRY_ACTION( data );
+
+ // Get text
+ g_free( action->text );
+ action->text = g_strdup( gtk_entry_get_text( widget ) );
+
+ // Get row
+ action->active =
+ get_active_row_from_text( action, action->text );
+
+ // Set active row
+ gtk_combo_box_set_active( GTK_COMBO_BOX( action->combobox), action->active );
+
+ // Now let the world know
+ g_signal_emit( G_OBJECT(action), signals[CHANGED], 0 );
+
+}
+
+static gboolean match_selected_cb( GtkEntryCompletion* /*widget*/, GtkTreeModel* model, GtkTreeIter* iter, gpointer data )
+{
+ // Get action
+ Ink_ComboBoxEntry_Action *action = INK_COMBOBOXENTRY_ACTION( data );
+ GtkEntry *entry = action->entry;
+
+ if( entry) {
+ gchar *family = 0;
+ gtk_tree_model_get(model, iter, 0, &family, -1);
+
+ // Set text in GtkEntry
+ gtk_entry_set_text (GTK_ENTRY (entry), family );
+
+ // Set text in GtkAction
+ g_free( action->text );
+ action->text = family;
+
+ // Get row
+ action->active =
+ get_active_row_from_text( action, action->text );
+
+ // Set active row
+ gtk_combo_box_set_active( GTK_COMBO_BOX( action->combobox), action->active );
+
+ // Now let the world know
+ g_signal_emit( G_OBJECT(action), signals[CHANGED], 0 );
+
+ return true;
+ }
+ return false;
+}
+
+static void ink_comboboxentry_action_defocus( Ink_ComboBoxEntry_Action* action )
+{
+ if ( action->focusWidget ) {
+ gtk_widget_grab_focus( action->focusWidget );
+ }
+}
+
+gboolean keypress_cb( GtkWidget * /*widget*/, GdkEventKey *event, gpointer data )
+{
+ gboolean wasConsumed = FALSE; /* default to report event not consumed */
+ guint key = 0;
+ Ink_ComboBoxEntry_Action* action = INK_COMBOBOXENTRY_ACTION( data );
+ gdk_keymap_translate_keyboard_state( gdk_keymap_get_for_display( gdk_display_get_default() ),
+ event->hardware_keycode, (GdkModifierType)event->state,
+ 0, &key, 0, 0, 0 );
+
+ switch ( key ) {
+
+ // TODO Add bindings for Tab/LeftTab
+ case GDK_KEY_Escape:
+ {
+ //gtk_spin_button_set_value( GTK_SPIN_BUTTON(widget), action->private_data->lastVal );
+ ink_comboboxentry_action_defocus( action );
+ wasConsumed = TRUE;
+ }
+ break;
+
+ case GDK_KEY_Return:
+ case GDK_KEY_KP_Enter:
+ {
+ ink_comboboxentry_action_defocus( action );
+ //wasConsumed = TRUE;
+ }
+ break;
+
+
+ }
+
+ return wasConsumed;
+}
diff --git a/src/widgets/ink-comboboxentry-action.h b/src/widgets/ink-comboboxentry-action.h
new file mode 100644
index 000000000..04b66e8fe
--- /dev/null
+++ b/src/widgets/ink-comboboxentry-action.h
@@ -0,0 +1,106 @@
+/*
+ * A subclass of GtkAction that wraps a GtkComboBoxEntry.
+ * Features:
+ * Setting GtkEntryBox width in characters.
+ * Passing a function for formatting cells.
+ * Displaying a warning if text isn't in list.
+ * Setting names for GtkComboBoxEntry and GtkEntry (actionName_combobox, actionName_entry)
+ * to allow setting resources.
+ *
+ * Author(s):
+ * Tavmjong Bah
+ * Jon A. Cruz <jon@joncruz.org>
+ *
+ * Copyright (C) 2010 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef SEEN_INK_COMBOBOXENTRY_ACTION
+#define SEEN_INK_COMBOBOXENTRY_ACTION
+
+#include <gtk/gtk.h>
+
+#define INK_COMBOBOXENTRY_TYPE_ACTION (ink_comboboxentry_action_get_type())
+#define INK_COMBOBOXENTRY_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INK_COMBOBOXENTRY_TYPE_ACTION, Ink_ComboBoxEntry_Action))
+#define INK_COMBOBOXENTRY_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), INK_COMBOBOXENTRY_TYPE_ACTION, Ink_ComboBoxEntry_ActionClass))
+#define INK_COMBOBOXENTRY_IS_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INK_COMBOBOXENTRY_TYPE_ACTION))
+#define INK_COMBOBOXENTRY_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INK_COMBOBOXENTRY_TYPE_ACTION, Ink_ComboBoxEntry_ActionClass))
+
+typedef struct _Ink_ComboBoxEntry_ActionClass Ink_ComboBoxEntry_ActionClass;
+typedef struct _Ink_ComboBoxEntry_Action Ink_ComboBoxEntry_Action;
+
+struct _Ink_ComboBoxEntry_ActionClass {
+ GtkActionClass parent_class;
+
+ void (*changed) (Ink_ComboBoxEntry_Action* action);
+ void (*activated) (Ink_ComboBoxEntry_Action* action);
+};
+
+struct _Ink_ComboBoxEntry_Action {
+ GtkAction parent_instance;
+
+ GtkTreeModel *model;
+ GtkComboBox *combobox;
+ GtkEntry *entry;
+ GtkEntryCompletion *entry_completion;
+ GtkWidget *indicator;
+
+ gpointer cell_data_func; // drop-down menu format
+ gpointer separator_func;
+
+ gint active; // Index of active menu item (-1 if not in list).
+ gchar *text; // Text of active menu item or entry box.
+ gint entry_width;// Width of GtkEntry in characters.
+ gint extra_width;// Extra Width of GtkComboBox.. to widen drop-down list in list mode.
+ gboolean popup; // Do we pop-up an entry-completion dialog?
+ gchar *info; // Text for tooltip info about entry.
+ gpointer info_cb; // Callback for clicking info icon.
+ gint info_cb_id;
+ gboolean info_cb_blocked;
+ gchar *warning; // Text for tooltip warning that entry isn't in list.
+ gpointer warning_cb; // Callback for clicking warning icon.
+ gint warning_cb_id;
+ gboolean warning_cb_blocked;
+ gchar *altx_name; // Target for Alt-X keyboard shortcut.
+ GtkWidget *focusWidget;
+};
+
+
+GType ink_comboboxentry_action_get_type (void);
+
+/**
+ * Creates a GtkAction subclass that wraps a GtkComboBoxEntry object.
+ */
+Ink_ComboBoxEntry_Action *ink_comboboxentry_action_new ( const gchar *name,
+ const gchar *label,
+ const gchar *tooltip,
+ const gchar *stock_id,
+ GtkTreeModel *model,
+ gint entry_width = -1,
+ gint extra_width = -1,
+ gpointer cell_data_func = NULL,
+ gpointer separator_func = NULL,
+ GtkWidget* focusWidget = NULL);
+
+GtkTreeModel *ink_comboboxentry_action_get_model( Ink_ComboBoxEntry_Action* action );
+GtkComboBox *ink_comboboxentry_action_get_comboboxentry( Ink_ComboBoxEntry_Action* action );
+
+gchar* ink_comboboxentry_action_get_active_text( Ink_ComboBoxEntry_Action* action );
+gboolean ink_comboboxentry_action_set_active_text( Ink_ComboBoxEntry_Action* action, const gchar* text, int row=-1 );
+
+void ink_comboboxentry_action_set_entry_width( Ink_ComboBoxEntry_Action* action, gint entry_width );
+void ink_comboboxentry_action_set_extra_width( Ink_ComboBoxEntry_Action* action, gint extra_width );
+
+void ink_comboboxentry_action_popup_enable( Ink_ComboBoxEntry_Action* action );
+void ink_comboboxentry_action_popup_disable( Ink_ComboBoxEntry_Action* action );
+
+void ink_comboboxentry_action_set_info( Ink_ComboBoxEntry_Action* action, const gchar* info );
+void ink_comboboxentry_action_set_info_cb( Ink_ComboBoxEntry_Action* action, gpointer info_cb );
+void ink_comboboxentry_action_set_warning( Ink_ComboBoxEntry_Action* action, const gchar* warning_cb );
+void ink_comboboxentry_action_set_warning_cb(Ink_ComboBoxEntry_Action* action, gpointer warning );
+void ink_comboboxentry_action_set_tooltip( Ink_ComboBoxEntry_Action* action, const gchar* tooltip );
+
+void ink_comboboxentry_action_set_altx_name( Ink_ComboBoxEntry_Action* action, const gchar* altx_name );
+
+#endif /* SEEN_INK_COMBOBOXENTRY_ACTION */
diff --git a/src/widgets/lpe-toolbar.cpp b/src/widgets/lpe-toolbar.cpp
index e9e5af912..a85f3ae78 100644
--- a/src/widgets/lpe-toolbar.cpp
+++ b/src/widgets/lpe-toolbar.cpp
@@ -30,19 +30,18 @@
#include "live_effects/lpe-line_segment.h"
#include "lpe-toolbar.h"
-#include "connection-pool.h"
#include "desktop-handles.h"
#include "desktop.h"
#include "document-undo.h"
-#include "ege-select-one-action.h"
+#include "widgets/ege-select-one-action.h"
#include "helper/action-context.h"
#include "helper/action.h"
-#include "ink-action.h"
+#include "widgets/ink-action.h"
#include "live_effects/effect.h"
#include "preferences.h"
#include "selection.h"
#include "sp-namedview.h"
-#include "tools-switch.h"
+#include "ui/tools-switch.h"
#include "ui/tools/lpe-tool.h"
#include "ui/widget/unit-tracker.h"
#include "util/units.h"
@@ -180,6 +179,7 @@ static void lpetool_unit_changed(GtkAction* /*act*/, GObject* tbl)
{
UnitTracker* tracker = reinterpret_cast<UnitTracker*>(g_object_get_data(tbl, "tracker"));
Unit const *unit = tracker->getActiveUnit();
+ g_return_if_fail(unit != NULL);
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
prefs->setString("/tools/lpetool/unit", unit->abbr);
@@ -275,12 +275,15 @@ static void lpetool_open_lpe_dialog(GtkToggleAction *act, gpointer data)
gtk_toggle_action_set_active(act, false);
}
+static void lpetool_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder);
+
void sp_lpetool_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
{
UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR);
tracker->setActiveUnit(sp_desktop_namedview(desktop)->doc_units);
g_object_set_data(holder, "tracker", tracker);
Unit const *unit = tracker->getActiveUnit();
+ g_return_if_fail(unit != NULL);
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
prefs->setString("/tools/lpetool/unit", unit->abbr);
@@ -400,21 +403,27 @@ void sp_lpetool_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GO
gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), FALSE );
}
- //watch selection
- Inkscape::ConnectionPool* pool = Inkscape::ConnectionPool::new_connection_pool ("ISNodeToolbox");
+ desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(lpetool_toolbox_watch_ec), holder));
+}
- sigc::connection *c_selection_modified =
- new sigc::connection (sp_desktop_selection (desktop)->connectModified
- (sigc::bind (sigc::ptr_fun (sp_lpetool_toolbox_sel_modified), holder)));
- pool->add_connection ("selection-modified", c_selection_modified);
+static void lpetool_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder)
+{
+ static sigc::connection c_selection_modified;
+ static sigc::connection c_selection_changed;
- sigc::connection *c_selection_changed =
- new sigc::connection (sp_desktop_selection (desktop)->connectChanged
- (sigc::bind (sigc::ptr_fun(sp_lpetool_toolbox_sel_changed), holder)));
- pool->add_connection ("selection-changed", c_selection_changed);
+ if (SP_IS_LPETOOL_CONTEXT(ec)) {
+ // Watch selection
+ c_selection_modified = sp_desktop_selection(desktop)->connectModified(sigc::bind(sigc::ptr_fun(sp_lpetool_toolbox_sel_modified), holder));
+ c_selection_changed = sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_lpetool_toolbox_sel_changed), holder));
+ sp_lpetool_toolbox_sel_changed(sp_desktop_selection(desktop), holder);
+ } else {
+ if (c_selection_modified)
+ c_selection_modified.disconnect();
+ if (c_selection_changed)
+ c_selection_changed.disconnect();
+ }
}
-
/*
Local Variables:
mode:c++
@@ -424,4 +433,4 @@ void sp_lpetool_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GO
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 :
diff --git a/src/widgets/mappings.xml b/src/widgets/mappings.xml
index 2de3ff545..089bf76ea 100644
--- a/src/widgets/mappings.xml
+++ b/src/widgets/mappings.xml
@@ -197,6 +197,7 @@
<!-- bezier toolbar -->
<remap id='bezier_mode' newid='path-mode-bezier'/>
<remap id='spiro_splines_mode' newid='path-mode-spiro'/>
+ <remap id='bspline_mode' newid='path-mode-bspline'/>
<remap id='polylines_mode' newid='path-mode-polyline'/>
<remap id='paraxial_lines_mode' newid='path-mode-polyline-paraxial'/>
diff --git a/src/widgets/measure-toolbar.cpp b/src/widgets/measure-toolbar.cpp
index 46d3bd4e0..1a4678332 100644
--- a/src/widgets/measure-toolbar.cpp
+++ b/src/widgets/measure-toolbar.cpp
@@ -34,8 +34,8 @@
#include "desktop-handles.h"
#include "desktop.h"
#include "document-undo.h"
-#include "ege-adjustment-action.h"
-#include "ege-output-action.h"
+#include "widgets/ege-adjustment-action.h"
+#include "widgets/ege-output-action.h"
#include "preferences.h"
#include "toolbox.h"
#include "ui/widget/unit-tracker.h"
diff --git a/src/widgets/mesh-toolbar.cpp b/src/widgets/mesh-toolbar.cpp
index 15dda94f0..897d84278 100644
--- a/src/widgets/mesh-toolbar.cpp
+++ b/src/widgets/mesh-toolbar.cpp
@@ -42,6 +42,7 @@
#include <glibmm/i18n.h>
#include "ui/tools/gradient-tool.h"
+#include "ui/tools/mesh-tool.h"
#include "gradient-drag.h"
#include "sp-mesh-gradient.h"
#include "gradient-chemistry.h"
@@ -49,17 +50,16 @@
#include "selection.h"
#include "ui/icon-names.h"
-#include "../ege-adjustment-action.h"
-#include "../ege-output-action.h"
-#include "../ege-select-one-action.h"
-#include "../ink-action.h"
-#include "../ink-comboboxentry-action.h"
+#include "widgets/ege-adjustment-action.h"
+#include "widgets/ege-output-action.h"
+#include "widgets/ege-select-one-action.h"
+#include "widgets/ink-action.h"
+#include "widgets/ink-comboboxentry-action.h"
#include "sp-stop.h"
#include "svg/css-ostringstream.h"
#include "svg/svg-color.h"
#include "desktop-style.h"
-#include "ui/tools/gradient-tool.h"
#include "toolbox.h"
@@ -67,7 +67,7 @@ using Inkscape::DocumentUndo;
using Inkscape::UI::ToolboxFactory;
using Inkscape::UI::PrefPusher;
-static gboolean blocked = FALSE;
+static bool blocked = false;
//########################
//## Mesh ##
@@ -116,22 +116,16 @@ static void ms_drag_selection_changed(gpointer /*dragger*/, gpointer data)
}
-static void ms_defs_release(SPObject * /*defs*/, GtkWidget *widget)
+static void ms_defs_release(SPObject * /*defs*/, GObject *widget)
{
ms_tb_selection_changed(NULL, widget);
}
-static void ms_defs_modified(SPObject * /*defs*/, guint /*flags*/, GtkWidget *widget)
+static void ms_defs_modified(SPObject * /*defs*/, guint /*flags*/, GObject *widget)
{
- ms_tb_selection_changed(NULL, (gpointer) widget);
-}
-
-static void ms_disconnect_sigc(GObject * /*obj*/, sigc::connection *connection) {
- connection->disconnect();
- delete connection;
+ ms_tb_selection_changed(NULL, widget);
}
-
/*
* Callback functions for user actions
*/
@@ -184,6 +178,8 @@ static void ms_col_changed(GtkAdjustment *adj, GObject * /*tbl*/ )
blocked = FALSE;
}
+static void mesh_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder);
+
/**
* Mesh auxiliary toolbar construction and setup.
*
@@ -323,35 +319,43 @@ void sp_mesh_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObj
g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher);
}
-
- Inkscape::Selection *selection = sp_desktop_selection (desktop);
- SPDocument *document = sp_desktop_document (desktop);
-
g_object_set_data(holder, "desktop", desktop);
- // connect to selection modified and changed signals
- sigc::connection *conn1 = new sigc::connection(
- selection->connectChanged(sigc::bind(sigc::ptr_fun(&ms_tb_selection_changed), (gpointer) holder)));
- sigc::connection *conn2 = new sigc::connection(
- selection->connectModified(sigc::bind(sigc::ptr_fun(&ms_tb_selection_modified), (gpointer) holder)));
- sigc::connection *conn3 = new sigc::connection(
- desktop->connectToolSubselectionChanged( sigc::bind(sigc::ptr_fun(&ms_drag_selection_changed), (gpointer) holder)));
-
- // when holder is destroyed, disconnect
- g_signal_connect(G_OBJECT(holder), "destroy", G_CALLBACK(ms_disconnect_sigc), conn1);
- g_signal_connect(G_OBJECT(holder), "destroy", G_CALLBACK(ms_disconnect_sigc), conn2);
- g_signal_connect(G_OBJECT(holder), "destroy", G_CALLBACK(ms_disconnect_sigc), conn3);
-
- // connect to release and modified signals of the defs (i.e. when someone changes mesh)
- sigc::connection *release_connection = new sigc::connection();
- *release_connection = document->getDefs()->connectRelease(sigc::bind<1>(sigc::ptr_fun(&ms_defs_release), GTK_WIDGET(holder)));
- sigc::connection *modified_connection = new sigc::connection();
- *modified_connection = document->getDefs()->connectModified(sigc::bind<2>(sigc::ptr_fun(&ms_defs_modified), GTK_WIDGET(holder)));
-
- // when holder is destroyed, disconnect
- g_signal_connect(G_OBJECT(holder), "destroy", G_CALLBACK(ms_disconnect_sigc), release_connection);
- g_signal_connect(G_OBJECT(holder), "destroy", G_CALLBACK(ms_disconnect_sigc), modified_connection);
+ desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(mesh_toolbox_watch_ec), holder));
+}
+static void mesh_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder)
+{
+ static sigc::connection c_selection_changed;
+ static sigc::connection c_selection_modified;
+ static sigc::connection c_subselection_changed;
+ static sigc::connection c_defs_release;
+ static sigc::connection c_defs_modified;
+
+ if (SP_IS_MESH_CONTEXT(ec)) {
+ // connect to selection modified and changed signals
+ Inkscape::Selection *selection = sp_desktop_selection (desktop);
+ SPDocument *document = sp_desktop_document (desktop);
+
+ c_selection_changed = selection->connectChanged(sigc::bind(sigc::ptr_fun(&ms_tb_selection_changed), holder));
+ c_selection_modified = selection->connectModified(sigc::bind(sigc::ptr_fun(&ms_tb_selection_modified), holder));
+ c_subselection_changed = desktop->connectToolSubselectionChanged(sigc::bind(sigc::ptr_fun(&ms_drag_selection_changed), holder));
+
+ c_defs_release = document->getDefs()->connectRelease(sigc::bind<1>(sigc::ptr_fun(&ms_defs_release), holder));
+ c_defs_modified = document->getDefs()->connectModified(sigc::bind<2>(sigc::ptr_fun(&ms_defs_modified), holder));
+ ms_tb_selection_changed(selection, holder);
+ } else {
+ if (c_selection_changed)
+ c_selection_changed.disconnect();
+ if (c_selection_modified)
+ c_selection_modified.disconnect();
+ if (c_subselection_changed)
+ c_subselection_changed.disconnect();
+ if (c_defs_release)
+ c_defs_release.disconnect();
+ if (c_defs_modified)
+ c_defs_modified.disconnect();
+ }
}
/*
diff --git a/src/widgets/node-toolbar.cpp b/src/widgets/node-toolbar.cpp
index 39e0a9be0..467325d08 100644
--- a/src/widgets/node-toolbar.cpp
+++ b/src/widgets/node-toolbar.cpp
@@ -31,12 +31,11 @@
#include "ui/tool/multi-path-manipulator.h"
#include <glibmm/i18n.h>
#include "node-toolbar.h"
-#include "connection-pool.h"
#include "desktop-handles.h"
#include "desktop.h"
#include "document-undo.h"
-#include "ege-adjustment-action.h"
-#include "ink-action.h"
+#include "widgets/ege-adjustment-action.h"
+#include "widgets/ink-action.h"
#include "inkscape.h"
#include "preferences.h"
#include "selection-chemistry.h"
@@ -229,6 +228,7 @@ static void sp_node_toolbox_coord_changed(gpointer /*shape_editor*/, GObject *tb
return;
}
Unit const *unit = tracker->getActiveUnit();
+ g_return_if_fail(unit != NULL);
NodeTool *nt = get_node_tool();
if (!nt || !(nt->_selected_nodes) ||nt->_selected_nodes->empty()) {
@@ -321,7 +321,7 @@ static void sp_node_toolbox_sel_modified(Inkscape::Selection *selection, guint /
sp_node_toolbox_sel_changed (selection, tbl);
}
-
+static void node_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder);
//################################
//## Node Editing Toolbox ##
@@ -614,32 +614,33 @@ void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje
gtk_action_group_add_action( mainActions, act );
}
-
sp_node_toolbox_sel_changed(sp_desktop_selection(desktop), holder);
+ desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(node_toolbox_watch_ec), holder));
- //watch selection
- Inkscape::ConnectionPool* pool = Inkscape::ConnectionPool::new_connection_pool ("ISNodeToolbox");
-
- sigc::connection *c_selection_changed =
- new sigc::connection (sp_desktop_selection (desktop)->connectChanged
- (sigc::bind (sigc::ptr_fun (sp_node_toolbox_sel_changed), holder)));
- pool->add_connection ("selection-changed", c_selection_changed);
-
- sigc::connection *c_selection_modified =
- new sigc::connection (sp_desktop_selection (desktop)->connectModified
- (sigc::bind (sigc::ptr_fun (sp_node_toolbox_sel_modified), holder)));
- pool->add_connection ("selection-modified", c_selection_modified);
-
- sigc::connection *c_subselection_changed =
- new sigc::connection (desktop->connectToolSubselectionChanged
- (sigc::bind (sigc::ptr_fun (sp_node_toolbox_coord_changed), holder)));
- pool->add_connection ("tool-subselection-changed", c_subselection_changed);
+} // end of sp_node_toolbox_prep()
- Inkscape::ConnectionPool::connect_destroy (G_OBJECT (holder), pool);
+static void node_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder)
+{
+ static sigc::connection c_selection_changed;
+ static sigc::connection c_selection_modified;
+ static sigc::connection c_subselection_changed;
- g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder );
-} // end of sp_node_toolbox_prep()
+ if (INK_IS_NODE_TOOL(ec)) {
+ // watch selection
+ c_selection_changed = sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_node_toolbox_sel_changed), holder));
+ c_selection_modified = sp_desktop_selection(desktop)->connectModified(sigc::bind(sigc::ptr_fun(sp_node_toolbox_sel_modified), holder));
+ c_subselection_changed = desktop->connectToolSubselectionChanged(sigc::bind(sigc::ptr_fun(sp_node_toolbox_coord_changed), holder));
+ sp_node_toolbox_sel_changed(sp_desktop_selection(desktop), holder);
+ } else {
+ if (c_selection_changed)
+ c_selection_changed.disconnect();
+ if (c_selection_modified)
+ c_selection_modified.disconnect();
+ if (c_subselection_changed)
+ c_subselection_changed.disconnect();
+ }
+}
/*
diff --git a/src/widgets/paint-selector.cpp b/src/widgets/paint-selector.cpp
index 9466c875e..6ef910f61 100644
--- a/src/widgets/paint-selector.cpp
+++ b/src/widgets/paint-selector.cpp
@@ -29,14 +29,15 @@
#endif
#include "widgets/swatch-selector.h"
-#include "../sp-pattern.h"
+#include "sp-pattern.h"
#include <glibmm/i18n.h>
-#include "../widgets/icon.h"
+#include "widgets/icon.h"
#include "widgets/widget-sizes.h"
#include "xml/repr.h"
#include "sp-color-notebook.h"
#include "sp-linear-gradient.h"
+#include "sp-mesh-gradient.h"
#include "sp-radial-gradient.h"
/* fixme: Move it from dialogs to here */
#include "gradient-selector.h"
@@ -71,8 +72,6 @@ enum {
LAST_SIGNAL
};
-static void sp_paint_selector_class_init(SPPaintSelectorClass *klass);
-static void sp_paint_selector_init(SPPaintSelector *slider);
static void sp_paint_selector_dispose(GObject *object);
static GtkWidget *sp_paint_selector_style_button_add(SPPaintSelector *psel, gchar const *px, SPPaintSelector::Mode mode, gchar const *tip);
@@ -91,7 +90,6 @@ static void sp_paint_selector_set_mode_unset(SPPaintSelector *psel);
static void sp_paint_selector_set_style_buttons(SPPaintSelector *psel, GtkWidget *active);
-static GtkVBoxClass *parent_class;
static guint psel_signals[LAST_SIGNAL] = {0};
#ifdef SP_PS_VERBOSE
@@ -113,10 +111,13 @@ static gchar const* modeStrings[] = {
#endif
-static bool isPaintModeGradient( SPPaintSelector::Mode mode )
+static bool isPaintModeGradient(SPPaintSelector::Mode mode)
{
bool isGrad = (mode == SPPaintSelector::MODE_GRADIENT_LINEAR) ||
(mode == SPPaintSelector::MODE_GRADIENT_RADIAL) ||
+#ifdef WITH_MESH
+ (mode == SPPaintSelector::MODE_GRADIENT_MESH) ||
+#endif
(mode == SPPaintSelector::MODE_SWATCH);
return isGrad;
@@ -136,34 +137,17 @@ static SPGradientSelector *getGradientFromData(SPPaintSelector const *psel)
return grad;
}
-GType sp_paint_selector_get_type(void)
-{
- static GType type = 0;
- if (!type) {
- GTypeInfo info = {
- sizeof(SPPaintSelectorClass),
- 0, // base_init
- 0, // base_finalize
- (GClassInitFunc)sp_paint_selector_class_init,
- 0, // class_finalize
- 0, // class_data
- sizeof(SPPaintSelector),
- 0, // n_preallocs
- (GInstanceInitFunc)sp_paint_selector_init,
- 0 // value_table
- };
- type = g_type_register_static(GTK_TYPE_VBOX, "SPPaintSelector", &info, static_cast<GTypeFlags>(0));
- }
- return type;
-}
+#if GTK_CHECK_VERSION(3,0,0)
+G_DEFINE_TYPE(SPPaintSelector, sp_paint_selector, GTK_TYPE_BOX);
+#else
+G_DEFINE_TYPE(SPPaintSelector, sp_paint_selector, GTK_TYPE_VBOX);
+#endif
static void
sp_paint_selector_class_init(SPPaintSelectorClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS(klass);
- parent_class = GTK_VBOX_CLASS(g_type_class_peek_parent(klass));
-
psel_signals[MODE_CHANGED] = g_signal_new("mode_changed",
G_TYPE_FROM_CLASS(object_class),
(GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE),
@@ -216,6 +200,10 @@ sp_paint_selector_class_init(SPPaintSelectorClass *klass)
static void
sp_paint_selector_init(SPPaintSelector *psel)
{
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_orientable_set_orientation(GTK_ORIENTABLE(psel), GTK_ORIENTATION_VERTICAL);
+#endif
+
psel->mode = static_cast<SPPaintSelector::Mode>(-1); // huh? do you mean 0xff? -- I think this means "not in the enum"
/* Paint style button box */
@@ -238,6 +226,10 @@ sp_paint_selector_init(SPPaintSelector *psel)
SPPaintSelector::MODE_GRADIENT_LINEAR, _("Linear gradient"));
psel->radial = sp_paint_selector_style_button_add(psel, INKSCAPE_ICON("paint-gradient-radial"),
SPPaintSelector::MODE_GRADIENT_RADIAL, _("Radial gradient"));
+#ifdef WITH_MESH
+ psel->mesh = sp_paint_selector_style_button_add(psel, INKSCAPE_ICON("paint-gradient-mesh"),
+ SPPaintSelector::MODE_GRADIENT_MESH, _("Mesh gradient"));
+#endif
psel->pattern = sp_paint_selector_style_button_add(psel, INKSCAPE_ICON("paint-pattern"),
SPPaintSelector::MODE_PATTERN, _("Pattern"));
psel->swatch = sp_paint_selector_style_button_add(psel, INKSCAPE_ICON("paint-swatch"),
@@ -314,8 +306,8 @@ static void sp_paint_selector_dispose(GObject *object)
// clean up our long-living pattern menu
g_object_set_data(G_OBJECT(psel),"patternmenu",NULL);
- if ((G_OBJECT_CLASS(parent_class))->dispose)
- (* (G_OBJECT_CLASS(parent_class))->dispose)(object);
+ if ((G_OBJECT_CLASS(sp_paint_selector_parent_class))->dispose)
+ (G_OBJECT_CLASS(sp_paint_selector_parent_class))->dispose(object);
}
static GtkWidget *sp_paint_selector_style_button_add(SPPaintSelector *psel,
@@ -413,6 +405,9 @@ void SPPaintSelector::setMode(Mode mode)
break;
case MODE_GRADIENT_LINEAR:
case MODE_GRADIENT_RADIAL:
+#ifdef WITH_MESH
+ case MODE_GRADIENT_MESH:
+#endif
sp_paint_selector_set_mode_gradient(this, mode);
break;
case MODE_PATTERN:
@@ -511,6 +506,21 @@ void SPPaintSelector::setGradientRadial(SPGradient *vector)
gsel->setVector((vector) ? vector->document : 0, vector);
}
+#ifdef WITH_MESH
+void SPPaintSelector::setGradientMesh(SPGradient *vector)
+{
+#ifdef SP_PS_VERBOSE
+ g_print("PaintSelector set GRADIENT MESH\n");
+#endif
+ setMode(MODE_GRADIENT_RADIAL);
+
+ SPGradientSelector *gsel = getGradientFromData(this);
+
+ gsel->setMode(SPGradientSelector::MODE_MESH);
+ gsel->setVector((vector) ? vector->document : 0, vector);
+}
+#endif
+
void SPPaintSelector::setGradientProperties( SPGradientUnits units, SPGradientSpread spread )
{
g_return_if_fail(isPaintModeGradient(mode));
@@ -665,8 +675,8 @@ static void sp_paint_selector_set_mode_color(SPPaintSelector *psel, SPPaintSelec
/* Create new color selector */
/* Create vbox */
#if GTK_CHECK_VERSION(3,0,0)
- GtkWidget *vb = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4);
- gtk_box_set_homogeneous(GTK_BOX(vb), FALSE);
+ GtkWidget *vb = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4);
+ gtk_box_set_homogeneous(GTK_BOX(vb), FALSE);
#else
GtkWidget *vb = gtk_vbox_new(FALSE, 4);
#endif
@@ -728,9 +738,14 @@ static void sp_paint_selector_set_mode_gradient(SPPaintSelector *psel, SPPaintSe
if (mode == SPPaintSelector::MODE_GRADIENT_LINEAR) {
sp_paint_selector_set_style_buttons(psel, psel->gradient);
- } else {
+ } else if (mode == SPPaintSelector::MODE_GRADIENT_RADIAL) {
sp_paint_selector_set_style_buttons(psel, psel->radial);
}
+#ifdef WITH_MESH
+ else {
+ sp_paint_selector_set_style_buttons(psel, psel->mesh);
+ }
+#endif
gtk_widget_set_sensitive(psel->style, TRUE);
if ((psel->mode == SPPaintSelector::MODE_GRADIENT_LINEAR) || (psel->mode == SPPaintSelector::MODE_GRADIENT_RADIAL)) {
@@ -756,10 +771,17 @@ static void sp_paint_selector_set_mode_gradient(SPPaintSelector *psel, SPPaintSe
SP_GRADIENT_SELECTOR(gsel)->setMode(SPGradientSelector::MODE_LINEAR);
//sp_gradient_selector_set_mode(SP_GRADIENT_SELECTOR(gsel), SP_GRADIENT_SELECTOR_MODE_LINEAR);
gtk_label_set_markup(GTK_LABEL(psel->label), _("<b>Linear gradient</b>"));
- } else {
+ } else if (mode == SPPaintSelector::MODE_GRADIENT_LINEAR) {
SP_GRADIENT_SELECTOR(gsel)->setMode(SPGradientSelector::MODE_RADIAL);
gtk_label_set_markup(GTK_LABEL(psel->label), _("<b>Radial gradient</b>"));
}
+#ifdef WITH_MESH
+ else {
+ SP_GRADIENT_SELECTOR(gsel)->setMode(SPGradientSelector::MODE_RADIAL);
+ gtk_label_set_markup(GTK_LABEL(psel->label), _("<b>Mesh gradient</b>"));
+ }
+#endif
+
#ifdef SP_PS_VERBOSE
g_print("Gradient req\n");
#endif
@@ -772,6 +794,9 @@ sp_paint_selector_set_style_buttons(SPPaintSelector *psel, GtkWidget *active)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(psel->solid), (active == psel->solid));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(psel->gradient), (active == psel->gradient));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(psel->radial), (active == psel->radial));
+#ifdef WITH_MESH
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(psel->mesh), (active == psel->mesh));
+#endif
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(psel->pattern), (active == psel->pattern));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(psel->swatch), (active == psel->swatch));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(psel->unset), (active == psel->unset));
@@ -1004,8 +1029,8 @@ static void sp_paint_selector_set_mode_pattern(SPPaintSelector *psel, SPPaintSel
/* Create vbox */
#if GTK_CHECK_VERSION(3,0,0)
- tbl = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4);
- gtk_box_set_homogeneous(GTK_BOX(tbl), FALSE);
+ tbl = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4);
+ gtk_box_set_homogeneous(GTK_BOX(tbl), FALSE);
#else
tbl = gtk_vbox_new(FALSE, 4);
#endif
@@ -1218,6 +1243,10 @@ SPPaintSelector::Mode SPPaintSelector::getModeForStyle(SPStyle const & style, Fi
mode = MODE_GRADIENT_LINEAR;
} else if (SP_IS_RADIALGRADIENT(server)) {
mode = MODE_GRADIENT_RADIAL;
+#ifdef WITH_MESH
+ } else if (SP_IS_MESHGRADIENT(server)) {
+ mode = MODE_GRADIENT_MESH;
+#endif
} else if (SP_IS_PATTERN(server)) {
mode = MODE_PATTERN;
} else {
diff --git a/src/widgets/paint-selector.h b/src/widgets/paint-selector.h
index d6ad3f50c..788aa673e 100644
--- a/src/widgets/paint-selector.h
+++ b/src/widgets/paint-selector.h
@@ -12,7 +12,6 @@
*
*/
-#include <glib.h>
#include <gtk/gtk.h>
#include "color.h"
@@ -35,7 +34,11 @@ class SPStyle;
* Generic paint selector widget.
*/
struct SPPaintSelector {
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkBox vbox;
+#else
GtkVBox vbox;
+#endif
enum Mode {
MODE_EMPTY,
@@ -45,6 +48,9 @@ struct SPPaintSelector {
MODE_COLOR_CMYK,
MODE_GRADIENT_LINEAR,
MODE_GRADIENT_RADIAL,
+#ifdef WITH_MESH
+ MODE_GRADIENT_MESH,
+#endif
MODE_PATTERN,
MODE_SWATCH,
MODE_UNSET
@@ -64,6 +70,9 @@ struct SPPaintSelector {
GtkWidget *solid;
GtkWidget *gradient;
GtkWidget *radial;
+#ifdef WITH_MESH
+ GtkWidget *mesh;
+#endif
GtkWidget *pattern;
GtkWidget *swatch;
GtkWidget *unset;
@@ -88,6 +97,9 @@ struct SPPaintSelector {
void setGradientLinear( SPGradient *vector );
void setGradientRadial( SPGradient *vector );
+#ifdef WITH_MESH
+ void setGradientMesh(SPGradient *vector);
+#endif
void setSwatch( SPGradient *vector );
void setGradientProperties( SPGradientUnits units, SPGradientSpread spread );
@@ -109,7 +121,11 @@ enum {COMBO_COL_LABEL=0, COMBO_COL_STOCK=1, COMBO_COL_PATTERN=2, COMBO_COL_SEP=3
/// The SPPaintSelector vtable
struct SPPaintSelectorClass {
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkBoxClass parent_class;
+#else
GtkVBoxClass parent_class;
+#endif
void (* mode_changed) (SPPaintSelector *psel, SPPaintSelector::Mode mode);
diff --git a/src/widgets/paintbucket-toolbar.cpp b/src/widgets/paintbucket-toolbar.cpp
index e20811de8..d8edeb9f6 100644
--- a/src/widgets/paintbucket-toolbar.cpp
+++ b/src/widgets/paintbucket-toolbar.cpp
@@ -33,8 +33,8 @@
#include "paintbucket-toolbar.h"
#include "desktop.h"
#include "document-undo.h"
-#include "ege-adjustment-action.h"
-#include "ege-select-one-action.h"
+#include "widgets/ege-adjustment-action.h"
+#include "widgets/ege-select-one-action.h"
#include "preferences.h"
#include "toolbox.h"
#include "ui/icon-names.h"
@@ -83,6 +83,8 @@ static void paintbucket_offset_changed(GtkAdjustment *adj, GObject *tbl)
// Don't adjust the offset value because we're saving the
// unit and it'll be correctly handled on load.
prefs->setDouble("/tools/paintbucket/offset", (gdouble)gtk_adjustment_get_value(adj));
+
+ g_return_if_fail(unit != NULL);
prefs->setString("/tools/paintbucket/offsetunits", unit->abbr);
}
diff --git a/src/widgets/pencil-toolbar.cpp b/src/widgets/pencil-toolbar.cpp
index 45a552889..1214a378a 100644
--- a/src/widgets/pencil-toolbar.cpp
+++ b/src/widgets/pencil-toolbar.cpp
@@ -33,12 +33,12 @@
#include "pencil-toolbar.h"
#include "desktop.h"
#include "document-undo.h"
-#include "ege-adjustment-action.h"
-#include "ege-select-one-action.h"
-#include "ink-action.h"
+#include "widgets/ege-adjustment-action.h"
+#include "widgets/ege-select-one-action.h"
+#include "widgets/ink-action.h"
#include "preferences.h"
#include "toolbox.h"
-#include "tools-switch.h"
+#include "ui/tools-switch.h"
#include "ui/icon-names.h"
#include "ui/tools/pen-tool.h"
#include "ui/uxmanager.h"
@@ -104,7 +104,12 @@ static void sp_add_freehand_mode_toggle(GtkActionGroup* mainActions, GObject* ho
1, _("Create Spiro path"),
2, INKSCAPE_ICON("path-mode-spiro"),
-1 );
-
+ gtk_list_store_append( model, &iter );
+ gtk_list_store_set( model, &iter,
+ 0, _("BSpline"),
+ 1, _("Create BSpline path"),
+ 2, INKSCAPE_ICON("path-mode-bspline"),
+ -1 );
if (!tool_is_pencil) {
gtk_list_store_append( model, &iter );
gtk_list_store_set( model, &iter,
@@ -157,6 +162,7 @@ static GList * freehand_shape_dropdown_items_list() {
glist = g_list_append (glist, _("Triangle out"));
glist = g_list_append (glist, _("Ellipse"));
glist = g_list_append (glist, _("From clipboard"));
+ glist = g_list_append (glist, _("Last applied"));
return glist;
}
diff --git a/src/widgets/rect-toolbar.cpp b/src/widgets/rect-toolbar.cpp
index 908e6cc78..e1ce01eaf 100644
--- a/src/widgets/rect-toolbar.cpp
+++ b/src/widgets/rect-toolbar.cpp
@@ -34,9 +34,9 @@
#include "desktop-handles.h"
#include "desktop.h"
#include "document-undo.h"
-#include "ege-adjustment-action.h"
-#include "ege-output-action.h"
-#include "ink-action.h"
+#include "widgets/ege-adjustment-action.h"
+#include "widgets/ege-output-action.h"
+#include "widgets/ink-action.h"
#include "inkscape.h"
#include "preferences.h"
#include "selection.h"
@@ -44,6 +44,7 @@
#include "sp-rect.h"
#include "toolbox.h"
#include "ui/icon-names.h"
+#include "ui/tools/rect-tool.h"
#include "ui/uxmanager.h"
#include "ui/widget/unit-tracker.h"
#include "util/units.h"
@@ -87,6 +88,7 @@ static void sp_rtb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *
UnitTracker* tracker = reinterpret_cast<UnitTracker*>(g_object_get_data( tbl, "tracker" ));
Unit const *unit = tracker->getActiveUnit();
+ g_return_if_fail(unit != NULL);
if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) {
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
@@ -180,6 +182,7 @@ static void rect_tb_event_attr_changed(Inkscape::XML::Node * /*repr*/, gchar con
UnitTracker* tracker = reinterpret_cast<UnitTracker*>( g_object_get_data( tbl, "tracker" ) );
Unit const *unit = tracker->getActiveUnit();
Unit const *doc_unit = sp_desktop_namedview(SP_ACTIVE_DESKTOP)->doc_units;
+ g_return_if_fail(unit != NULL);
gpointer item = g_object_get_data( tbl, "item" );
if (item && SP_IS_RECT(item)) {
@@ -286,6 +289,7 @@ static void sp_rect_toolbox_selection_changed(Inkscape::Selection *selection, GO
}
}
+static void rect_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder);
void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
{
@@ -392,13 +396,21 @@ void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje
g_object_set_data( holder, "single", GINT_TO_POINTER(TRUE) );
sp_rtb_sensitivize( holder );
- sigc::connection *connection = new sigc::connection(
- sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_rect_toolbox_selection_changed), holder))
- );
- g_signal_connect( holder, "destroy", G_CALLBACK(delete_connection), connection );
+ desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(rect_toolbox_watch_ec), holder));
g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder );
}
+static void rect_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder)
+{
+ static sigc::connection changed;
+
+ if (SP_IS_RECT_CONTEXT(ec)) {
+ changed = sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_rect_toolbox_selection_changed), holder));
+ } else {
+ if (changed)
+ changed.disconnect();
+ }
+}
/*
Local Variables:
@@ -409,4 +421,4 @@ void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 :
diff --git a/src/widgets/select-toolbar.cpp b/src/widgets/select-toolbar.cpp
index 284e436bf..08a46354e 100644
--- a/src/widgets/select-toolbar.cpp
+++ b/src/widgets/select-toolbar.cpp
@@ -26,10 +26,10 @@
#include "display/sp-canvas.h"
#include "document-undo.h"
#include "document.h"
-#include "ege-adjustment-action.h"
+#include "widgets/ege-adjustment-action.h"
#include "helper/action-context.h"
#include "helper/action.h"
-#include "ink-action.h"
+#include "widgets/ink-action.h"
#include "inkscape.h"
#include "message-stack.h"
#include "preferences.h"
@@ -73,6 +73,7 @@ sp_selection_layout_widget_update(SPWidget *spw, Inkscape::Selection *sel)
if ( bbox ) {
UnitTracker *tracker = reinterpret_cast<UnitTracker*>(g_object_get_data(G_OBJECT(spw), "tracker"));
Unit const *unit = tracker->getActiveUnit();
+ g_return_if_fail(unit != NULL);
struct { char const *key; double val; } const keyval[] = {
{ "X", bbox->min()[X] },
@@ -178,6 +179,7 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw)
gdouble xrel = 0;
gdouble yrel = 0;
Unit const *unit = tracker->getActiveUnit();
+ g_return_if_fail(unit != NULL);
GtkAdjustment* a_x = GTK_ADJUSTMENT( g_object_get_data( G_OBJECT(spw), "X" ) );
GtkAdjustment* a_y = GTK_ADJUSTMENT( g_object_get_data( G_OBJECT(spw), "Y" ) );
diff --git a/src/widgets/sp-color-icc-selector.cpp b/src/widgets/sp-color-icc-selector.cpp
index 53e73dd57..6e910c582 100644
--- a/src/widgets/sp-color-icc-selector.cpp
+++ b/src/widgets/sp-color-icc-selector.cpp
@@ -10,7 +10,7 @@
#include <set>
#include <vector>
-#include "../dialogs/dialog-events.h"
+#include "ui/dialog-events.h"
#include "sp-color-icc-selector.h"
#include "sp-color-scales.h"
#include "sp-color-slider.h"
@@ -67,10 +67,7 @@ extern guint update_in_progress;
G_BEGIN_DECLS
-static void sp_color_icc_selector_class_init (SPColorICCSelectorClass *klass);
-static void sp_color_icc_selector_init (SPColorICCSelector *cs);
static void sp_color_icc_selector_dispose(GObject *object);
-
static void sp_color_icc_selector_show_all (GtkWidget *widget);
static void sp_color_icc_selector_hide(GtkWidget *widget);
@@ -161,9 +158,6 @@ public:
#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
};
-
-static SPColorSelectorClass *parent_class;
-
#define XPAD 4
#define YPAD 1
@@ -205,8 +199,14 @@ void attachToGridOrTable(GtkWidget *parent,
guint ypadding = YPAD)
{
#if GTK_CHECK_VERSION(3,0,0)
+ #if GTK_CHECK_VERSION(3,12,0)
+ gtk_widget_set_margin_start( child, xpadding );
+ gtk_widget_set_margin_end( child, xpadding );
+ #else
gtk_widget_set_margin_left( child, xpadding );
gtk_widget_set_margin_right( child, xpadding );
+ #endif
+
gtk_widget_set_margin_top( child, ypadding );
gtk_widget_set_margin_bottom( child, ypadding );
if (hexpand) {
@@ -227,30 +227,7 @@ void attachToGridOrTable(GtkWidget *parent,
} // namespace
-GType sp_color_icc_selector_get_type(void)
-{
- static GType type = 0;
- if (!type) {
- static const GTypeInfo info = {
- sizeof (SPColorICCSelectorClass),
- NULL, // base_init
- NULL, // base_finalize
- (GClassInitFunc) sp_color_icc_selector_class_init,
- NULL, // class_finalize
- NULL, // class_data
- sizeof (SPColorICCSelector),
- 0, // n_preallocs
- (GInstanceInitFunc) sp_color_icc_selector_init,
- 0, // value_table
- };
-
- type = g_type_register_static (SP_TYPE_COLOR_SELECTOR,
- "SPColorICCSelector",
- &info,
- static_cast< GTypeFlags > (0) );
- }
- return type;
-}
+G_DEFINE_TYPE(SPColorICCSelector, sp_color_icc_selector, SP_TYPE_COLOR_SELECTOR);
static void sp_color_icc_selector_class_init(SPColorICCSelectorClass *klass)
{
@@ -259,8 +236,6 @@ static void sp_color_icc_selector_class_init(SPColorICCSelectorClass *klass)
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
SPColorSelectorClass *selector_class = SP_COLOR_SELECTOR_CLASS (klass);
- parent_class = SP_COLOR_SELECTOR_CLASS (g_type_class_peek_parent (klass));
-
selector_class->name = nameset;
selector_class->submode_count = 1;
@@ -599,8 +574,8 @@ void ColorICCSelector::init()
static void sp_color_icc_selector_dispose(GObject *object)
{
- if ((G_OBJECT_CLASS(parent_class))->dispose) {
- (* (G_OBJECT_CLASS(parent_class))->dispose)(object);
+ if (G_OBJECT_CLASS(sp_color_icc_selector_parent_class)->dispose) {
+ G_OBJECT_CLASS(sp_color_icc_selector_parent_class)->dispose(object);
}
}
diff --git a/src/widgets/sp-color-icc-selector.h b/src/widgets/sp-color-icc-selector.h
index f63ab0853..6cdaff639 100644
--- a/src/widgets/sp-color-icc-selector.h
+++ b/src/widgets/sp-color-icc-selector.h
@@ -2,8 +2,6 @@
#define SEEN_SP_COLOR_ICC_SELECTOR_H
#include <glib.h>
-#include <gtk/gtk.h>
-
#include "sp-color-selector.h"
namespace Inkscape {
diff --git a/src/widgets/sp-color-notebook.cpp b/src/widgets/sp-color-notebook.cpp
index e081f98e0..c7fa96efd 100644
--- a/src/widgets/sp-color-notebook.cpp
+++ b/src/widgets/sp-color-notebook.cpp
@@ -25,7 +25,7 @@
#include <gtk/gtk.h>
#include <glibmm/i18n.h>
-#include "../dialogs/dialog-events.h"
+#include "ui/dialog-events.h"
#include "../preferences.h"
#include "sp-color-notebook.h"
#include "spw-utilities.h"
@@ -38,7 +38,7 @@
#include "../profile-manager.h"
#include "color-profile.h"
#include "cms-system.h"
-#include "tools-switch.h"
+#include "ui/tools-switch.h"
#include "ui/tools/tool-base.h"
using Inkscape::CMSSystem;
@@ -53,46 +53,21 @@ struct SPColorNotebookTracker {
SPColorNotebook *backPointer;
};
-static void sp_color_notebook_class_init (SPColorNotebookClass *klass);
-static void sp_color_notebook_init (SPColorNotebook *colorbook);
static void sp_color_notebook_dispose(GObject *object);
static void sp_color_notebook_show_all (GtkWidget *widget);
static void sp_color_notebook_hide(GtkWidget *widget);
-static SPColorSelectorClass *parent_class;
-
#define XPAD 4
#define YPAD 1
-GType sp_color_notebook_get_type(void)
-{
- static GType type = 0;
- if (!type) {
- GTypeInfo info = {
- sizeof(SPColorNotebookClass),
- 0, // base_init
- 0, // base_finalize
- (GClassInitFunc)sp_color_notebook_class_init,
- 0, // class_finalize
- 0, // class_data
- sizeof(SPColorNotebook),
- 0, // n_preallocs
- (GInstanceInitFunc)sp_color_notebook_init,
- 0 // value_table
- };
- type = g_type_register_static(SP_TYPE_COLOR_SELECTOR, "SPColorNotebook", &info, static_cast<GTypeFlags>(0));
- }
- return type;
-}
+G_DEFINE_TYPE(SPColorNotebook, sp_color_notebook, SP_TYPE_COLOR_SELECTOR);
static void sp_color_notebook_class_init(SPColorNotebookClass *klass)
{
GObjectClass *object_class = reinterpret_cast<GObjectClass *>(klass);
GtkWidgetClass *widget_class = reinterpret_cast<GtkWidgetClass *>(klass);
- parent_class = SP_COLOR_SELECTOR_CLASS(g_type_class_peek_parent(klass));
-
object_class->dispose = sp_color_notebook_dispose;
widget_class->show_all = sp_color_notebook_show_all;
@@ -289,8 +264,13 @@ void ColorNotebook::init()
sp_set_font_size_smaller (_buttonbox);
#if GTK_CHECK_VERSION(3,0,0)
+ #if GTK_CHECK_VERSION(3,12,0)
+ gtk_widget_set_margin_start(_buttonbox, XPAD);
+ gtk_widget_set_margin_end(_buttonbox, XPAD);
+ #else
gtk_widget_set_margin_left(_buttonbox, XPAD);
gtk_widget_set_margin_right(_buttonbox, XPAD);
+ #endif
gtk_widget_set_margin_top(_buttonbox, YPAD);
gtk_widget_set_margin_bottom(_buttonbox, YPAD);
gtk_widget_set_hexpand(_buttonbox, TRUE);
@@ -306,8 +286,13 @@ void ColorNotebook::init()
row++;
#if GTK_CHECK_VERSION(3,0,0)
+ #if GTK_CHECK_VERSION(3,12,0)
+ gtk_widget_set_margin_start(_book, XPAD*2);
+ gtk_widget_set_margin_end(_book, XPAD*2);
+ #else
gtk_widget_set_margin_left(_book, XPAD*2);
gtk_widget_set_margin_right(_book, XPAD*2);
+ #endif
gtk_widget_set_margin_top(_book, YPAD);
gtk_widget_set_margin_bottom(_book, YPAD);
gtk_widget_set_hexpand(_book, TRUE);
@@ -434,8 +419,13 @@ void ColorNotebook::init()
#endif //defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
#if GTK_CHECK_VERSION(3,0,0)
+ #if GTK_CHECK_VERSION(3,12,0)
+ gtk_widget_set_margin_start(rgbabox, XPAD);
+ gtk_widget_set_margin_end(rgbabox, XPAD);
+ #else
gtk_widget_set_margin_left(rgbabox, XPAD);
gtk_widget_set_margin_right(rgbabox, XPAD);
+ #endif
gtk_widget_set_margin_top(rgbabox, YPAD);
gtk_widget_set_margin_bottom(rgbabox, YPAD);
gtk_grid_attach(GTK_GRID(table), rgbabox, 0, row, 2, 1);
@@ -457,8 +447,8 @@ void ColorNotebook::init()
static void sp_color_notebook_dispose(GObject *object)
{
- if (((GObjectClass *) (parent_class))->dispose)
- (* ((GObjectClass *) (parent_class))->dispose) (object);
+ if (G_OBJECT_CLASS(sp_color_notebook_parent_class)->dispose)
+ G_OBJECT_CLASS(sp_color_notebook_parent_class)->dispose(object);
}
ColorNotebook::~ColorNotebook()
diff --git a/src/widgets/sp-color-notebook.h b/src/widgets/sp-color-notebook.h
index 6e5111132..469bb56e8 100644
--- a/src/widgets/sp-color-notebook.h
+++ b/src/widgets/sp-color-notebook.h
@@ -12,14 +12,10 @@
* This code is in public domain
*/
-#include <gtk/gtk.h>
-#include "../color.h"
#include "sp-color-selector.h"
#include <glib.h>
-
-
struct SPColorNotebook;
class ColorNotebook: public ColorSelector
diff --git a/src/widgets/sp-color-scales.cpp b/src/widgets/sp-color-scales.cpp
index c3f9d511c..60ba62ec5 100644
--- a/src/widgets/sp-color-scales.cpp
+++ b/src/widgets/sp-color-scales.cpp
@@ -8,8 +8,9 @@
#include <math.h>
#include <gtk/gtk.h>
#include <glibmm/i18n.h>
-#include "../dialogs/dialog-events.h"
+#include "ui/dialog-events.h"
#include "sp-color-scales.h"
+#include "sp-color-slider.h"
#include "svg/svg-icc-color.h"
#define CSC_CHANNEL_R (1 << 0)
@@ -30,8 +31,6 @@
G_BEGIN_DECLS
-static void sp_color_scales_class_init (SPColorScalesClass *klass);
-static void sp_color_scales_init (SPColorScales *cs);
static void sp_color_scales_dispose(GObject *object);
static void sp_color_scales_show_all (GtkWidget *widget);
@@ -41,38 +40,12 @@ static const gchar *sp_color_scales_hue_map (void);
G_END_DECLS
-static SPColorSelectorClass *parent_class;
-
#define XPAD 4
#define YPAD 1
#define noDUMP_CHANGE_INFO 1
-GType
-sp_color_scales_get_type (void)
-{
- static GType type = 0;
- if (!type) {
- static const GTypeInfo info = {
- sizeof (SPColorScalesClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) sp_color_scales_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (SPColorScales),
- 0, /* n_preallocs */
- (GInstanceInitFunc) sp_color_scales_init,
- NULL
- };
-
- type = g_type_register_static (SP_TYPE_COLOR_SELECTOR,
- "SPColorScales",
- &info,
- static_cast< GTypeFlags > (0) );
- }
- return type;
-}
+G_DEFINE_TYPE(SPColorScales, sp_color_scales, SP_TYPE_COLOR_SELECTOR);
static void
sp_color_scales_class_init (SPColorScalesClass *klass)
@@ -82,8 +55,6 @@ sp_color_scales_class_init (SPColorScalesClass *klass)
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
SPColorSelectorClass *selector_class = SP_COLOR_SELECTOR_CLASS (klass);
- parent_class = SP_COLOR_SELECTOR_CLASS (g_type_class_peek_parent (klass));
-
selector_class->name = nameset;
selector_class->submode_count = 3;
@@ -151,8 +122,13 @@ void ColorScales::init()
gtk_widget_show (_l[i]);
#if GTK_CHECK_VERSION(3,0,0)
+ #if GTK_CHECK_VERSION(3,12,0)
+ gtk_widget_set_margin_start(_l[i], XPAD);
+ gtk_widget_set_margin_end(_l[i], XPAD);
+ #else
gtk_widget_set_margin_left(_l[i], XPAD);
gtk_widget_set_margin_right(_l[i], XPAD);
+ #endif
gtk_widget_set_margin_top(_l[i], YPAD);
gtk_widget_set_margin_bottom(_l[i], YPAD);
gtk_grid_attach(GTK_GRID(t), _l[i], 0, i, 1, 1);
@@ -167,8 +143,13 @@ void ColorScales::init()
gtk_widget_show (_s[i]);
#if GTK_CHECK_VERSION(3,0,0)
+ #if GTK_CHECK_VERSION(3,12,0)
+ gtk_widget_set_margin_start(_s[i], XPAD);
+ gtk_widget_set_margin_end(_s[i], XPAD);
+ #else
gtk_widget_set_margin_left(_s[i], XPAD);
gtk_widget_set_margin_right(_s[i], XPAD);
+ #endif
gtk_widget_set_margin_top(_s[i], YPAD);
gtk_widget_set_margin_bottom(_s[i], YPAD);
gtk_widget_set_hexpand(_s[i], TRUE);
@@ -184,8 +165,13 @@ void ColorScales::init()
gtk_widget_show (_b[i]);
#if GTK_CHECK_VERSION(3,0,0)
+ #if GTK_CHECK_VERSION(3,12,0)
+ gtk_widget_set_margin_start(_b[i], XPAD);
+ gtk_widget_set_margin_end(_b[i], XPAD);
+ #else
gtk_widget_set_margin_left(_b[i], XPAD);
gtk_widget_set_margin_right(_b[i], XPAD);
+ #endif
gtk_widget_set_margin_top(_b[i], YPAD);
gtk_widget_set_margin_bottom(_b[i], YPAD);
gtk_widget_set_halign(_b[i], GTK_ALIGN_CENTER);
@@ -214,8 +200,8 @@ void ColorScales::init()
static void sp_color_scales_dispose(GObject *object)
{
- if ((G_OBJECT_CLASS(parent_class))->dispose)
- (* (G_OBJECT_CLASS(parent_class))->dispose) (object);
+ if (G_OBJECT_CLASS(sp_color_scales_parent_class)->dispose)
+ G_OBJECT_CLASS(sp_color_scales_parent_class)->dispose(object);
}
static void
diff --git a/src/widgets/sp-color-scales.h b/src/widgets/sp-color-scales.h
index 3b11bc05e..72cbafa2f 100644
--- a/src/widgets/sp-color-scales.h
+++ b/src/widgets/sp-color-scales.h
@@ -2,15 +2,12 @@
#define SEEN_SP_COLOR_SCALES_H
#include <glib.h>
-#include <gtk/gtk.h>
-#include <color.h>
-#include <widgets/sp-color-slider.h>
#include <widgets/sp-color-selector.h>
-
struct SPColorScales;
struct SPColorScalesClass;
+struct SPColorSlider;
typedef enum {
SP_COLOR_SCALES_MODE_NONE = 0,
diff --git a/src/widgets/sp-color-selector.cpp b/src/widgets/sp-color-selector.cpp
index 6d62acecd..e97c36431 100644
--- a/src/widgets/sp-color-selector.cpp
+++ b/src/widgets/sp-color-selector.cpp
@@ -22,42 +22,20 @@ enum {
#define noDUMP_CHANGE_INFO
#define FOO_NAME(x) g_type_name( G_TYPE_FROM_INSTANCE(x) )
-static void sp_color_selector_class_init( SPColorSelectorClass *klass );
-static void sp_color_selector_init( SPColorSelector *csel );
static void sp_color_selector_dispose(GObject *object);
static void sp_color_selector_show_all( GtkWidget *widget );
static void sp_color_selector_hide( GtkWidget *widget );
-static GtkVBoxClass *parent_class;
static guint csel_signals[LAST_SIGNAL] = {0};
double ColorSelector::_epsilon = 1e-4;
-GType sp_color_selector_get_type( void )
-{
- static GType type = 0;
- if (!type) {
- static const GTypeInfo info = {
- sizeof(SPColorSelectorClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) sp_color_selector_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(SPColorSelector),
- 0, /* n_preallocs */
- (GInstanceInitFunc) sp_color_selector_init,
- NULL
- };
-
- type = g_type_register_static( GTK_TYPE_VBOX,
- "SPColorSelector",
- &info,
- static_cast<GTypeFlags>(0) );
- }
- return type;
-}
+#if GTK_CHECK_VERSION(3,0,0)
+G_DEFINE_TYPE(SPColorSelector, sp_color_selector, GTK_TYPE_BOX);
+#else
+G_DEFINE_TYPE(SPColorSelector, sp_color_selector, GTK_TYPE_VBOX);
+#endif
void sp_color_selector_class_init( SPColorSelectorClass *klass )
{
@@ -66,8 +44,6 @@ void sp_color_selector_class_init( SPColorSelectorClass *klass )
GtkWidgetClass *widget_class;
widget_class = GTK_WIDGET_CLASS(klass);
- parent_class = GTK_VBOX_CLASS( g_type_class_peek_parent(klass) );
-
csel_signals[GRABBED] = g_signal_new( "grabbed",
G_TYPE_FROM_CLASS(object_class),
(GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE),
@@ -109,6 +85,10 @@ void sp_color_selector_class_init( SPColorSelectorClass *klass )
void sp_color_selector_init( SPColorSelector *csel )
{
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_orientable_set_orientation(GTK_ORIENTABLE(csel), GTK_ORIENTATION_VERTICAL);
+#endif
+
if ( csel->base )
{
csel->base->init();
@@ -125,8 +105,8 @@ void sp_color_selector_dispose(GObject *object)
csel->base = 0;
}
- if ( (G_OBJECT_CLASS(parent_class))->dispose ) {
- (* (G_OBJECT_CLASS(parent_class))->dispose)(object);
+ if ((G_OBJECT_CLASS(sp_color_selector_parent_class))->dispose ) {
+ (G_OBJECT_CLASS(sp_color_selector_parent_class))->dispose(object);
}
}
diff --git a/src/widgets/sp-color-selector.h b/src/widgets/sp-color-selector.h
index 616d5a9e7..30061774a 100644
--- a/src/widgets/sp-color-selector.h
+++ b/src/widgets/sp-color-selector.h
@@ -2,9 +2,7 @@
#define SEEN_SP_COLOR_SELECTOR_H
#include <gtk/gtk.h>
-#include "../color.h"
-
-#include <glib.h>
+#include "color.h"
struct SPColorSelector;
@@ -62,13 +60,21 @@ private:
#define SP_COLOR_SELECTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SP_TYPE_COLOR_SELECTOR, SPColorSelectorClass))
struct SPColorSelector {
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkBox vbox;
+#else
GtkVBox vbox;
+#endif
ColorSelector* base;
};
struct SPColorSelectorClass {
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkBoxClass parent_class;
+#else
GtkVBoxClass parent_class;
+#endif
const gchar **name;
guint submode_count;
diff --git a/src/widgets/sp-color-slider.cpp b/src/widgets/sp-color-slider.cpp
index 9b13ba1c5..ab7e2cd84 100644
--- a/src/widgets/sp-color-slider.cpp
+++ b/src/widgets/sp-color-slider.cpp
@@ -12,6 +12,7 @@
#include <gtk/gtk.h>
#include "sp-color-scales.h"
+#include "sp-color-slider.h"
#include "preferences.h"
#define SLIDER_WIDTH 96
@@ -26,8 +27,6 @@ enum {
LAST_SIGNAL
};
-static void sp_color_slider_class_init (SPColorSliderClass *klass);
-static void sp_color_slider_init (SPColorSlider *slider);
static void sp_color_slider_dispose(GObject *object);
static void sp_color_slider_realize (GtkWidget *widget);
@@ -61,36 +60,15 @@ static const guchar *sp_color_slider_render_gradient (gint x0, gint y0, gint wid
static const guchar *sp_color_slider_render_map (gint x0, gint y0, gint width, gint height,
guchar *map, gint start, gint step, guint b0, guint b1, guint mask);
-static GtkWidgetClass *parent_class;
static guint slider_signals[LAST_SIGNAL] = {0};
-GType
-sp_color_slider_get_type (void)
-{
- static GType type = 0;
- if (!type) {
- GTypeInfo info = {
- sizeof (SPColorSliderClass),
- NULL, NULL,
- (GClassInitFunc) sp_color_slider_class_init,
- NULL, NULL,
- sizeof (SPColorSlider),
- 0,
- (GInstanceInitFunc) sp_color_slider_init,
- NULL
- };
- type = g_type_register_static (GTK_TYPE_WIDGET, "SPColorSlider", &info, (GTypeFlags)0);
- }
- return type;
-}
+G_DEFINE_TYPE(SPColorSlider, sp_color_slider, GTK_TYPE_WIDGET);
static void sp_color_slider_class_init(SPColorSliderClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS(klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
- parent_class = GTK_WIDGET_CLASS(g_type_class_peek_parent(klass));
-
slider_signals[GRABBED] = g_signal_new ("grabbed",
G_TYPE_FROM_CLASS(object_class),
(GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE),
@@ -183,8 +161,8 @@ static void sp_color_slider_dispose(GObject *object)
slider->adjustment = NULL;
}
- if ((G_OBJECT_CLASS(parent_class))->dispose)
- (* (G_OBJECT_CLASS(parent_class))->dispose) (object);
+ if (G_OBJECT_CLASS(sp_color_slider_parent_class)->dispose)
+ G_OBJECT_CLASS(sp_color_slider_parent_class)->dispose (object);
}
static void
diff --git a/src/widgets/sp-color-slider.h b/src/widgets/sp-color-slider.h
index 591d8368a..b81d62e41 100644
--- a/src/widgets/sp-color-slider.h
+++ b/src/widgets/sp-color-slider.h
@@ -14,13 +14,6 @@
#include <gtk/gtk.h>
-#include <glib.h>
-
-
-
-struct SPColorSlider;
-struct SPColorSliderClass;
-
#define SP_TYPE_COLOR_SLIDER (sp_color_slider_get_type ())
#define SP_COLOR_SLIDER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_COLOR_SLIDER, SPColorSlider))
#define SP_COLOR_SLIDER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), SP_TYPE_COLOR_SLIDER, SPColorSliderClass))
diff --git a/src/widgets/sp-color-wheel-selector.cpp b/src/widgets/sp-color-wheel-selector.cpp
index 7c8bb1df7..6cfa7c14d 100644
--- a/src/widgets/sp-color-wheel-selector.cpp
+++ b/src/widgets/sp-color-wheel-selector.cpp
@@ -4,17 +4,16 @@
#include <math.h>
#include <gtk/gtk.h>
#include <glibmm/i18n.h>
-#include "../dialogs/dialog-events.h"
+#include "ui/dialog-events.h"
#include "sp-color-wheel-selector.h"
#include "sp-color-scales.h"
+#include "sp-color-slider.h"
#include "sp-color-icc-selector.h"
#include "../svg/svg-icc-color.h"
#include "ui/widget/gimpcolorwheel.h"
G_BEGIN_DECLS
-static void sp_color_wheel_selector_class_init (SPColorWheelSelectorClass *klass);
-static void sp_color_wheel_selector_init (SPColorWheelSelector *cs);
static void sp_color_wheel_selector_dispose(GObject *object);
static void sp_color_wheel_selector_show_all (GtkWidget *widget);
@@ -23,36 +22,10 @@ static void sp_color_wheel_selector_hide(GtkWidget *widget);
G_END_DECLS
-static SPColorSelectorClass *parent_class;
-
#define XPAD 4
#define YPAD 1
-GType
-sp_color_wheel_selector_get_type (void)
-{
- static GType type = 0;
- if (!type) {
- static const GTypeInfo info = {
- sizeof (SPColorWheelSelectorClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) sp_color_wheel_selector_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (SPColorWheelSelector),
- 0, /* n_preallocs */
- (GInstanceInitFunc) sp_color_wheel_selector_init,
- 0, /* value_table */
- };
-
- type = g_type_register_static (SP_TYPE_COLOR_SELECTOR,
- "SPColorWheelSelector",
- &info,
- static_cast< GTypeFlags > (0) );
- }
- return type;
-}
+G_DEFINE_TYPE(SPColorWheelSelector, sp_color_wheel_selector, SP_TYPE_COLOR_SELECTOR);
static void sp_color_wheel_selector_class_init(SPColorWheelSelectorClass *klass)
{
@@ -61,8 +34,6 @@ static void sp_color_wheel_selector_class_init(SPColorWheelSelectorClass *klass)
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
SPColorSelectorClass *selector_class = SP_COLOR_SELECTOR_CLASS (klass);
- parent_class = SP_COLOR_SELECTOR_CLASS (g_type_class_peek_parent (klass));
-
selector_class->name = nameset;
selector_class->submode_count = 1;
@@ -142,8 +113,13 @@ void ColorWheelSelector::init()
gtk_widget_show (_label);
#if GTK_CHECK_VERSION(3,0,0)
+ #if GTK_CHECK_VERSION(3,12,0)
+ gtk_widget_set_margin_start(_label, XPAD);
+ gtk_widget_set_margin_end(_label, XPAD);
+ #else
gtk_widget_set_margin_left(_label, XPAD);
gtk_widget_set_margin_right(_label, XPAD);
+ #endif
gtk_widget_set_margin_top(_label, YPAD);
gtk_widget_set_margin_bottom(_label, YPAD);
gtk_widget_set_halign(_label, GTK_ALIGN_FILL);
@@ -162,8 +138,13 @@ void ColorWheelSelector::init()
gtk_widget_show (_slider);
#if GTK_CHECK_VERSION(3,0,0)
+ #if GTK_CHECK_VERSION(3,12,0)
+ gtk_widget_set_margin_start(_slider, XPAD);
+ gtk_widget_set_margin_end(_slider, XPAD);
+ #else
gtk_widget_set_margin_left(_slider, XPAD);
gtk_widget_set_margin_right(_slider, XPAD);
+ #endif
gtk_widget_set_margin_top(_slider, YPAD);
gtk_widget_set_margin_bottom(_slider, YPAD);
gtk_widget_set_hexpand(_slider, TRUE);
@@ -188,8 +169,13 @@ void ColorWheelSelector::init()
gtk_widget_show (_sbtn);
#if GTK_CHECK_VERSION(3,0,0)
+ #if GTK_CHECK_VERSION(3,12,0)
+ gtk_widget_set_margin_start(_sbtn, XPAD);
+ gtk_widget_set_margin_end(_sbtn, XPAD);
+ #else
gtk_widget_set_margin_left(_sbtn, XPAD);
gtk_widget_set_margin_right(_sbtn, XPAD);
+ #endif
gtk_widget_set_margin_top(_sbtn, YPAD);
gtk_widget_set_margin_bottom(_sbtn, YPAD);
gtk_widget_set_halign(_sbtn, GTK_ALIGN_CENTER);
@@ -216,8 +202,8 @@ void ColorWheelSelector::init()
static void sp_color_wheel_selector_dispose(GObject *object)
{
- if ((G_OBJECT_CLASS(parent_class))->dispose)
- (* (G_OBJECT_CLASS(parent_class))->dispose) (object);
+ if (G_OBJECT_CLASS(sp_color_wheel_selector_parent_class)->dispose)
+ G_OBJECT_CLASS(sp_color_wheel_selector_parent_class)->dispose(object);
}
static void
diff --git a/src/widgets/sp-color-wheel-selector.h b/src/widgets/sp-color-wheel-selector.h
index bbd377422..12b060dbe 100644
--- a/src/widgets/sp-color-wheel-selector.h
+++ b/src/widgets/sp-color-wheel-selector.h
@@ -1,15 +1,12 @@
#ifndef SEEN_SP_COLOR_WHEEL_SELECTOR_H
#define SEEN_SP_COLOR_WHEEL_SELECTOR_H
-#include <glib.h>
#include <gtk/gtk.h>
-#include "sp-color-slider.h"
#include "sp-color-selector.h"
-
-
typedef struct _GimpColorWheel GimpColorWheel;
+struct SPColorSlider;
struct SPColorWheelSelector;
struct SPColorWheelSelectorClass;
diff --git a/src/widgets/sp-widget.cpp b/src/widgets/sp-widget.cpp
index 0e2295e36..fdf5ec500 100644
--- a/src/widgets/sp-widget.cpp
+++ b/src/widgets/sp-widget.cpp
@@ -36,8 +36,6 @@ public:
SPWidgetImpl(SPWidget &target);
~SPWidgetImpl();
- static void classInit(SPWidgetClass *klass);
- static void init(SPWidget *widget);
static void dispose(GObject *object);
static void show(GtkWidget *widget);
static void hide(GtkWidget *widget);
@@ -61,64 +59,27 @@ public:
static void changeSelectionCB(Application *inkscape, Selection *selection, SPWidget *spw);
static void setSelectionCB(Application *inkscape, Selection *selection, SPWidget *spw);
- static GtkWidget *constructGlobal(SPWidget *spw, Inkscape::Application *inkscape);
+ static GtkWidget *constructGlobal(SPWidget *spw, InkscapeApplication *inkscape);
void modifySelection(Application *inkscape, Selection *selection, guint flags);
void changeSelection(Application *inkscape, Selection *selection);
void setSelection(Application *inkscape, Selection *selection);
private:
- static GtkBinClass *parentClass;
- static guint signals[LAST_SIGNAL];
-
SPWidget &_target;
};
-
-GtkBinClass *SPWidgetImpl::parentClass = 0;
-guint SPWidgetImpl::signals[LAST_SIGNAL] = {0};
-
} // namespace Inkscape
-GType SPWidget::getType()
-{
- static GType type = 0;
- if (!type) {
- static GTypeInfo const info = {
- sizeof(SPWidgetClass),
- NULL, NULL,
- reinterpret_cast<GClassInitFunc>(SPWidgetImpl::classInit),
- NULL, NULL,
- sizeof(SPWidget),
- 0,
- reinterpret_cast<GInstanceInitFunc>(SPWidgetImpl::init),
- NULL
- };
- type = g_type_register_static(GTK_TYPE_BIN,
- "SPWidget",
- &info,
- static_cast<GTypeFlags>(0));
- }
- return type;
-}
+G_DEFINE_TYPE(SPWidget, sp_widget, GTK_TYPE_BIN);
-namespace Inkscape {
+static guint signals[LAST_SIGNAL] = {0};
-SPWidgetImpl::SPWidgetImpl(SPWidget &target) :
- _target(target)
-{
-}
-
-SPWidgetImpl::~SPWidgetImpl()
-{
-}
-
-void SPWidgetImpl::classInit(SPWidgetClass *klass)
+static void
+sp_widget_class_init(SPWidgetClass *klass)
{
GObjectClass *object_class = reinterpret_cast<GObjectClass *>(klass);
GtkWidgetClass *widget_class = reinterpret_cast<GtkWidgetClass *>(klass);
- parentClass = reinterpret_cast<GtkBinClass *>(g_type_class_peek_parent(klass));
-
object_class->dispose = SPWidgetImpl::dispose;
signals[CONSTRUCT] = g_signal_new ("construct",
@@ -169,13 +130,23 @@ void SPWidgetImpl::classInit(SPWidgetClass *klass)
widget_class->size_allocate = SPWidgetImpl::sizeAllocate;
}
-void SPWidgetImpl::init(SPWidget *spw)
+static void sp_widget_init(SPWidget *spw)
{
spw->inkscape = NULL;
-
spw->_impl = new SPWidgetImpl(*spw); // ctor invoked after all other init
}
+namespace Inkscape {
+
+SPWidgetImpl::SPWidgetImpl(SPWidget &target) :
+ _target(target)
+{
+}
+
+SPWidgetImpl::~SPWidgetImpl()
+{
+}
+
void SPWidgetImpl::dispose(GObject *object)
{
SPWidget *spw = reinterpret_cast<SPWidget *>(object);
@@ -194,8 +165,8 @@ void SPWidgetImpl::dispose(GObject *object)
delete spw->_impl;
spw->_impl = 0;
- if (reinterpret_cast<GObjectClass *>(parentClass)->dispose) {
- (*reinterpret_cast<GObjectClass *>(parentClass)->dispose)(object);
+ if (G_OBJECT_CLASS(sp_widget_parent_class)->dispose) {
+ G_OBJECT_CLASS(sp_widget_parent_class)->dispose(object);
}
}
@@ -210,8 +181,8 @@ void SPWidgetImpl::show(GtkWidget *widget)
g_signal_connect(spw->inkscape, "set_selection", G_CALLBACK(SPWidgetImpl::setSelectionCB), spw);
}
- if (reinterpret_cast<GtkWidgetClass *>(parentClass)->show) {
- (*reinterpret_cast<GtkWidgetClass *>(parentClass)->show)(widget);
+ if (GTK_WIDGET_CLASS(sp_widget_parent_class)->show) {
+ GTK_WIDGET_CLASS(sp_widget_parent_class)->show(widget);
}
}
@@ -224,8 +195,8 @@ void SPWidgetImpl::hide(GtkWidget *widget)
sp_signal_disconnect_by_data(spw->inkscape, spw);
}
- if (reinterpret_cast<GtkWidgetClass *>(parentClass)->hide) {
- (*reinterpret_cast<GtkWidgetClass *>(parentClass)->hide)(widget);
+ if (GTK_WIDGET_CLASS(sp_widget_parent_class)->hide) {
+ GTK_WIDGET_CLASS(sp_widget_parent_class)->hide(widget);
}
}
@@ -293,7 +264,7 @@ void SPWidgetImpl::sizeAllocate(GtkWidget *widget, GtkAllocation *allocation)
}
}
-GtkWidget *SPWidgetImpl::constructGlobal(SPWidget *spw, Inkscape::Application *inkscape)
+GtkWidget *SPWidgetImpl::constructGlobal(SPWidget *spw, InkscapeApplication *inkscape)
{
g_return_val_if_fail(!spw->inkscape, NULL);
@@ -345,7 +316,7 @@ void SPWidgetImpl::setSelection(Application * /*inkscape*/, Selection *selection
// Methods
-GtkWidget *sp_widget_new_global(Inkscape::Application *inkscape)
+GtkWidget *sp_widget_new_global(InkscapeApplication *inkscape)
{
SPWidget *spw = reinterpret_cast<SPWidget*>(g_object_new(SP_TYPE_WIDGET, NULL));
diff --git a/src/widgets/sp-widget.h b/src/widgets/sp-widget.h
index 3a23a92c5..6227c3a72 100644
--- a/src/widgets/sp-widget.h
+++ b/src/widgets/sp-widget.h
@@ -15,35 +15,27 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
-#include <glib.h>
#include <gtk/gtk.h>
-#define SP_TYPE_WIDGET (SPWidget::getType())
+#define SP_TYPE_WIDGET (sp_widget_get_type())
#define SP_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_WIDGET, SPWidget))
#define SP_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_WIDGET, SPWidgetClass))
#define SP_IS_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_WIDGET))
#define SP_IS_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_WIDGET))
+struct InkscapeApplication;
namespace Inkscape {
-
-struct Application;
class Selection;
class SPWidgetImpl;
-
}
struct SPWidget {
friend class Inkscape::SPWidgetImpl;
- static GType getType();
-
- //
-
GtkBin bin;
- Inkscape::Application *inkscape;
+ InkscapeApplication *inkscape;
-private:
Inkscape::SPWidgetImpl *_impl;
};
@@ -58,10 +50,10 @@ struct SPWidgetClass {
void (* set_selection) (SPWidget *spw, Inkscape::Selection *selection);
};
-/* fixme: Think (Lauris) */
+GType sp_widget_get_type();
/** Generic constructor for global widget. */
-GtkWidget *sp_widget_new_global(Inkscape::Application *inkscape);
+GtkWidget *sp_widget_new_global(InkscapeApplication *inkscape);
#endif // SEEN_SP_WIDGET_H
/*
diff --git a/src/widgets/sp-xmlview-attr-list.cpp b/src/widgets/sp-xmlview-attr-list.cpp
index 47b0ebb9d..dd763aea5 100644
--- a/src/widgets/sp-xmlview-attr-list.cpp
+++ b/src/widgets/sp-xmlview-attr-list.cpp
@@ -20,9 +20,6 @@
#include "../xml/node-event-vector.h"
#include "sp-xmlview-attr-list.h"
-static void sp_xmlview_attr_list_class_init (SPXMLViewAttrListClass * klass);
-static void sp_xmlview_attr_list_init (SPXMLViewAttrList * list);
-
#if GTK_CHECK_VERSION(3,0,0)
static void sp_xmlview_attr_list_destroy(GtkWidget * object);
#else
@@ -31,8 +28,6 @@ static void sp_xmlview_attr_list_destroy(GtkObject * object);
static void event_attr_changed (Inkscape::XML::Node * repr, const gchar * name, const gchar * old_value, const gchar * new_value, bool is_interactive, gpointer data);
-static GtkTreeViewClass * parent_class = NULL;
-
static Inkscape::XML::NodeEventVector repr_events = {
NULL, /* child_added */
NULL, /* child_removed */
@@ -88,28 +83,7 @@ sp_xmlview_attr_list_set_repr (SPXMLViewAttrList * list, Inkscape::XML::Node * r
}
}
-GType sp_xmlview_attr_list_get_type(void)
-{
- static GType type = 0;
-
- if (!type) {
- GTypeInfo info = {
- sizeof(SPXMLViewAttrListClass),
- 0, // base_init
- 0, // base_finalize
- (GClassInitFunc)sp_xmlview_attr_list_class_init,
- 0, // class_finalize
- 0, // class_data
- sizeof(SPXMLViewAttrList),
- 0, // n_preallocs
- (GInstanceInitFunc)sp_xmlview_attr_list_init,
- 0 // value_table
- };
- type = g_type_register_static(GTK_TYPE_TREE_VIEW, "SPXMLViewAttrList", &info, static_cast<GTypeFlags>(0));
- }
-
- return type;
-}
+G_DEFINE_TYPE(SPXMLViewAttrList, sp_xmlview_attr_list, GTK_TYPE_TREE_VIEW);
void sp_xmlview_attr_list_class_init (SPXMLViewAttrListClass * klass)
{
@@ -121,8 +95,6 @@ void sp_xmlview_attr_list_class_init (SPXMLViewAttrListClass * klass)
object_class->destroy = sp_xmlview_attr_list_destroy;
#endif
- parent_class = GTK_TREE_VIEW_CLASS(g_type_class_peek_parent (klass));
-
g_signal_new("row-value-changed",
G_TYPE_FROM_CLASS(klass),
G_SIGNAL_RUN_FIRST,
@@ -154,9 +126,9 @@ void sp_xmlview_attr_list_destroy(GtkObject * object)
sp_xmlview_attr_list_set_repr (list, NULL);
#if GTK_CHECK_VERSION(3,0,0)
- GTK_WIDGET_CLASS(parent_class)->destroy (object);
+ GTK_WIDGET_CLASS(sp_xmlview_attr_list_parent_class)->destroy (object);
#else
- GTK_OBJECT_CLASS(parent_class)->destroy (object);
+ GTK_OBJECT_CLASS(sp_xmlview_attr_list_parent_class)->destroy (object);
#endif
}
diff --git a/src/widgets/sp-xmlview-attr-list.h b/src/widgets/sp-xmlview-attr-list.h
index 367ef1a12..08b115bfa 100644
--- a/src/widgets/sp-xmlview-attr-list.h
+++ b/src/widgets/sp-xmlview-attr-list.h
@@ -12,10 +12,8 @@
* Released under the GNU GPL; see COPYING for details
*/
-#include <stdio.h>
#include <gtk/gtk.h>
-
#define SP_TYPE_XMLVIEW_ATTR_LIST (sp_xmlview_attr_list_get_type ())
#define SP_XMLVIEW_ATTR_LIST(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_XMLVIEW_ATTR_LIST, SPXMLViewAttrList))
#define SP_IS_XMLVIEW_ATTR_LIST(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_XMLVIEW_ATTR_LIST))
@@ -23,7 +21,6 @@
struct SPXMLViewAttrList
{
-
GtkTreeView list;
GtkListStore *store;
diff --git a/src/widgets/sp-xmlview-content.cpp b/src/widgets/sp-xmlview-content.cpp
index ac64dabdb..9243760bd 100644
--- a/src/widgets/sp-xmlview-content.cpp
+++ b/src/widgets/sp-xmlview-content.cpp
@@ -23,9 +23,6 @@
using Inkscape::DocumentUndo;
-static void sp_xmlview_content_class_init (SPXMLViewContentClass * klass);
-static void sp_xmlview_content_init (SPXMLViewContent * text);
-
#if GTK_CHECK_VERSION(3,0,0)
static void sp_xmlview_content_destroy(GtkWidget * object);
#else
@@ -36,8 +33,6 @@ void sp_xmlview_content_changed (GtkTextBuffer *tb, SPXMLViewContent *text);
static void event_content_changed (Inkscape::XML::Node * repr, const gchar * old_content, const gchar * new_content, gpointer data);
-static GtkTextViewClass * parent_class = NULL;
-
static Inkscape::XML::NodeEventVector repr_events = {
NULL, /* child_added */
NULL, /* child_removed */
@@ -81,28 +76,7 @@ sp_xmlview_content_set_repr (SPXMLViewContent * text, Inkscape::XML::Node * repr
}
}
-GType sp_xmlview_content_get_type(void)
-{
- static GType type = 0;
-
- if (!type) {
- GTypeInfo info = {
- sizeof(SPXMLViewContentClass),
- 0, // base_init
- 0, // base_finalize
- (GClassInitFunc)sp_xmlview_content_class_init,
- 0, // class_finalize
- 0, // class_data
- sizeof(SPXMLViewContent),
- 0, // n_preallocs
- (GInstanceInitFunc)sp_xmlview_content_init,
- 0 // value_table
- };
- type = g_type_register_static(GTK_TYPE_TEXT_VIEW, "SPXMLViewContent", &info, static_cast<GTypeFlags>(0));
- }
-
- return type;
-}
+G_DEFINE_TYPE(SPXMLViewContent, sp_xmlview_content, GTK_TYPE_TEXT_VIEW);
void sp_xmlview_content_class_init(SPXMLViewContentClass * klass)
{
@@ -113,8 +87,6 @@ void sp_xmlview_content_class_init(SPXMLViewContentClass * klass)
GtkObjectClass * object_class = GTK_OBJECT_CLASS(klass);
object_class->destroy = sp_xmlview_content_destroy;
#endif
-
- parent_class = GTK_TEXT_VIEW_CLASS(g_type_class_peek_parent (klass));
}
void
@@ -135,9 +107,9 @@ void sp_xmlview_content_destroy(GtkObject * object)
sp_xmlview_content_set_repr (text, NULL);
#if GTK_CHECK_VERSION(3,0,0)
- GTK_WIDGET_CLASS (parent_class)->destroy (object);
+ GTK_WIDGET_CLASS (sp_xmlview_content_parent_class)->destroy (object);
#else
- GTK_OBJECT_CLASS (parent_class)->destroy (object);
+ GTK_OBJECT_CLASS (sp_xmlview_content_parent_class)->destroy (object);
#endif
}
diff --git a/src/widgets/sp-xmlview-content.h b/src/widgets/sp-xmlview-content.h
index 8b1342c5e..140eacf46 100644
--- a/src/widgets/sp-xmlview-content.h
+++ b/src/widgets/sp-xmlview-content.h
@@ -13,10 +13,7 @@
*/
#include <config.h>
-#include <stdio.h>
#include <gtk/gtk.h>
-#include <glib.h>
-
#define SP_TYPE_XMLVIEW_CONTENT (sp_xmlview_content_get_type ())
#define SP_XMLVIEW_CONTENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_XMLVIEW_CONTENT, SPXMLViewContent))
diff --git a/src/widgets/sp-xmlview-tree.cpp b/src/widgets/sp-xmlview-tree.cpp
index 43b7dc289..5dff9adf3 100644
--- a/src/widgets/sp-xmlview-tree.cpp
+++ b/src/widgets/sp-xmlview-tree.cpp
@@ -1,6 +1,4 @@
-#define __SP_XMLVIEW_TREE_C__
-
-/*
+/**
* Specialization of GtkTreeView for the XML tree view
*
* Authors:
@@ -14,7 +12,7 @@
#include <cstring>
#include <string>
-#include "../xml/node-event-vector.h"
+#include "xml/node-event-vector.h"
#include "sp-xmlview-tree.h"
struct NodeData {
@@ -25,9 +23,6 @@ struct NodeData {
enum { STORE_TEXT_COL = 0, STORE_DATA_COL, STORE_REPR_COL, STORE_N_COLS };
-static void sp_xmlview_tree_class_init (SPXMLViewTreeClass * klass);
-static void sp_xmlview_tree_init (SPXMLViewTree * tree);
-
#if GTK_CHECK_VERSION(3,0,0)
static void sp_xmlview_tree_destroy(GtkWidget * object);
#else
@@ -92,8 +87,6 @@ static const Inkscape::XML::NodeEventVector pi_repr_events = {
NULL /* order_changed */
};
-static GtkTreeViewClass * parent_class = NULL;
-
GtkWidget *sp_xmlview_tree_new(Inkscape::XML::Node * repr, void * /*factory*/, void * /*data*/)
{
SPXMLViewTree *tree = SP_XMLVIEW_TREE(g_object_new (SP_TYPE_XMLVIEW_TREE, NULL));
@@ -124,28 +117,7 @@ GtkWidget *sp_xmlview_tree_new(Inkscape::XML::Node * repr, void * /*factory*/, v
return GTK_WIDGET(tree);
}
-GType
-sp_xmlview_tree_get_type (void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof (SPXMLViewTreeClass),
- NULL, NULL,
- (GClassInitFunc) sp_xmlview_tree_class_init,
- NULL, NULL,
- sizeof (SPXMLViewTree),
- 0,
- (GInstanceInitFunc) sp_xmlview_tree_init,
- NULL
- };
- type = g_type_register_static (GTK_TYPE_TREE_VIEW, "SPXMLViewTree", &info, (GTypeFlags)0);
- }
-
-
- return type;
-}
+G_DEFINE_TYPE(SPXMLViewTree, sp_xmlview_tree, GTK_TYPE_TREE_VIEW);
void sp_xmlview_tree_class_init(SPXMLViewTreeClass * klass)
{
@@ -157,8 +129,6 @@ void sp_xmlview_tree_class_init(SPXMLViewTreeClass * klass)
object_class->destroy = sp_xmlview_tree_destroy;
#endif
- parent_class = GTK_TREE_VIEW_CLASS(g_type_class_peek_parent (klass));
-
// Signal for when a tree drag and drop has completed
g_signal_new ( "tree_move",
G_TYPE_FROM_CLASS(klass),
@@ -190,9 +160,9 @@ void sp_xmlview_tree_destroy(GtkObject * object)
sp_xmlview_tree_set_repr (tree, NULL);
#if GTK_CHECK_VERSION(3,0,0)
- GTK_WIDGET_CLASS(parent_class)->destroy (object);
+ GTK_WIDGET_CLASS(sp_xmlview_tree_parent_class)->destroy (object);
#else
- GTK_OBJECT_CLASS(parent_class)->destroy (object);
+ GTK_OBJECT_CLASS(sp_xmlview_tree_parent_class)->destroy (object);
#endif
}
@@ -734,4 +704,4 @@ gboolean search_equal_func(GtkTreeModel *model, gint /*column*/, const gchar *ke
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 :
diff --git a/src/widgets/sp-xmlview-tree.h b/src/widgets/sp-xmlview-tree.h
index 69228fa88..7ecbcb471 100644
--- a/src/widgets/sp-xmlview-tree.h
+++ b/src/widgets/sp-xmlview-tree.h
@@ -1,9 +1,4 @@
-#ifndef __SP_XMLVIEW_TREE_H__
-#define __SP_XMLVIEW_TREE_H__
-
-/*
- * Specialization of GtkTreeView for the XML editor
- *
+/**
* Authors:
* MenTaLguY <mental@rydia.net>
*
@@ -12,9 +7,15 @@
* Released under the GNU GPL; see COPYING for details
*/
+#ifndef SEEN_SP_XMLVIEW_TREE_H
+#define SEEN_SP_XMLVIEW_TREE_H
+
#include <gtk/gtk.h>
#include <glib.h>
+/**
+ * Specialization of GtkTreeView for the XML editor
+ */
#define SP_TYPE_XMLVIEW_TREE (sp_xmlview_tree_get_type ())
#define SP_XMLVIEW_TREE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_XMLVIEW_TREE, SPXMLViewTree))
@@ -49,7 +50,7 @@ Inkscape::XML::Node * sp_xmlview_tree_node_get_repr (GtkTreeModel *model, GtkTre
gboolean sp_xmlview_tree_get_repr_node (SPXMLViewTree * tree, Inkscape::XML::Node * repr, GtkTreeIter *node);
-#endif
+#endif // !SEEN_SP_XMLVIEW_TREE_H
/*
Local Variables:
@@ -60,4 +61,4 @@ gboolean sp_xmlview_tree_get_repr_node (SPXMLViewTree * tree, Inkscape::XML::Nod
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 :
diff --git a/src/widgets/spinbutton-events.h b/src/widgets/spinbutton-events.h
index c1df88c8a..9bf50d87c 100644
--- a/src/widgets/spinbutton-events.h
+++ b/src/widgets/spinbutton-events.h
@@ -10,7 +10,9 @@
*/
#include <glib.h>
-#include <gtk/gtk.h> /* GtkWidget */
+
+typedef struct _GdkEventKey GdkEventKey;
+typedef struct _GtkWidget GtkWidget;
gboolean spinbutton_focus_in (GtkWidget *w, GdkEventKey *event, gpointer data);
void spinbutton_undo (GtkWidget *w);
diff --git a/src/widgets/spiral-toolbar.cpp b/src/widgets/spiral-toolbar.cpp
index 710be9440..e85b024ed 100644
--- a/src/widgets/spiral-toolbar.cpp
+++ b/src/widgets/spiral-toolbar.cpp
@@ -34,9 +34,9 @@
#include "desktop-handles.h"
#include "desktop.h"
#include "document-undo.h"
-#include "ege-adjustment-action.h"
-#include "ege-output-action.h"
-#include "ink-action.h"
+#include "widgets/ege-adjustment-action.h"
+#include "widgets/ege-output-action.h"
+#include "widgets/ink-action.h"
#include "preferences.h"
#include "selection.h"
#include "sp-spiral.h"
diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp
index 788ce6475..183814b7e 100644
--- a/src/widgets/spray-toolbar.cpp
+++ b/src/widgets/spray-toolbar.cpp
@@ -33,9 +33,9 @@
#include "spray-toolbar.h"
#include "desktop.h"
#include "document-undo.h"
-#include "ege-adjustment-action.h"
-#include "ege-select-one-action.h"
-#include "ink-action.h"
+#include "widgets/ege-adjustment-action.h"
+#include "widgets/ege-select-one-action.h"
+#include "widgets/ink-action.h"
#include "preferences.h"
#include "toolbox.h"
#include "ui/icon-names.h"
diff --git a/src/widgets/spw-utilities.cpp b/src/widgets/spw-utilities.cpp
index 9c0c8d7c6..f87889bb1 100644
--- a/src/widgets/spw-utilities.cpp
+++ b/src/widgets/spw-utilities.cpp
@@ -64,8 +64,15 @@ Gtk::Label * spw_label(Gtk::Table *table, const gchar *label_text, int col, int
label_widget->set_hexpand();
label_widget->set_halign(Gtk::ALIGN_FILL);
label_widget->set_valign(Gtk::ALIGN_CENTER);
+
+ #if GTK_CHECK_VERSION(3,12,0)
+ label_widget->set_margin_start(4);
+ label_widget->set_margin_end(4);
+ #else
label_widget->set_margin_left(4);
label_widget->set_margin_right(4);
+ #endif
+
table->attach(*label_widget, col, row, 1, 1);
#else
table->attach(*label_widget, col, col+1, row, row+1, (Gtk::EXPAND | Gtk::FILL), static_cast<Gtk::AttachOptions>(0), 4, 0);
@@ -238,7 +245,11 @@ sp_set_font_size_recursive (GtkWidget *w, gpointer font)
PangoFontDescription* pan = pango_font_description_new ();
pango_font_description_set_size (pan, size);
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_widget_override_font (w, pan);
+#else
gtk_widget_modify_font (w, pan);
+#endif
if (GTK_IS_CONTAINER(w)) {
gtk_container_foreach (GTK_CONTAINER(w), (GtkCallback) sp_set_font_size_recursive, font);
diff --git a/src/widgets/star-toolbar.cpp b/src/widgets/star-toolbar.cpp
index 7a7d0dc71..6213263fc 100644
--- a/src/widgets/star-toolbar.cpp
+++ b/src/widgets/star-toolbar.cpp
@@ -34,14 +34,15 @@
#include "desktop-handles.h"
#include "desktop.h"
#include "document-undo.h"
-#include "ege-adjustment-action.h"
-#include "ege-output-action.h"
-#include "ege-select-one-action.h"
-#include "ink-action.h"
+#include "widgets/ege-adjustment-action.h"
+#include "widgets/ege-output-action.h"
+#include "widgets/ege-select-one-action.h"
+#include "widgets/ink-action.h"
#include "selection.h"
#include "sp-star.h"
#include "toolbox.h"
#include "ui/icon-names.h"
+#include "ui/tools/star-tool.h"
#include "ui/uxmanager.h"
#include "verbs.h"
#include "widgets/../preferences.h"
@@ -435,6 +436,7 @@ static void sp_stb_defaults( GtkWidget * /*widget*/, GObject *dataKludge )
gtk_adjustment_value_changed(adj);
}
+static void star_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder);
void sp_star_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
{
@@ -571,15 +573,22 @@ void sp_star_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje
}
}
- sigc::connection *connection = new sigc::connection(
- sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_star_toolbox_selection_changed), holder))
- );
- g_signal_connect( holder, "destroy", G_CALLBACK(delete_connection), connection );
- g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder );
+ desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(star_toolbox_watch_ec), holder));
+ g_signal_connect(holder, "destroy", G_CALLBACK(purge_repr_listener), holder);
}
+static void star_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder)
+{
+ static sigc::connection changed;
-
+ if (dynamic_cast<Inkscape::UI::Tools::StarTool const*>(ec) != NULL) {
+ changed = sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_star_toolbox_selection_changed), holder));
+ sp_star_toolbox_selection_changed(sp_desktop_selection(desktop), holder);
+ } else {
+ if (changed)
+ changed.disconnect();
+ }
+}
/*
Local Variables:
@@ -590,4 +599,4 @@ void sp_star_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 :
diff --git a/src/widgets/stroke-marker-selector.cpp b/src/widgets/stroke-marker-selector.cpp
index a0121b799..23da54e94 100644
--- a/src/widgets/stroke-marker-selector.cpp
+++ b/src/widgets/stroke-marker-selector.cpp
@@ -25,13 +25,13 @@
#include "style.h"
-#include "dialogs/dialog-events.h"
+#include "ui/dialog-events.h"
#include "desktop-handles.h"
#include "desktop-style.h"
#include "preferences.h"
#include "path-prefix.h"
#include "io/sys.h"
-#include "marker.h"
+#include "sp-marker.h"
#include "sp-defs.h"
#include "sp-root.h"
#include "ui/cache/svg_preview_cache.h"
diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp
index 7477e07ca..02dd5df6e 100644
--- a/src/widgets/stroke-style.cpp
+++ b/src/widgets/stroke-style.cpp
@@ -18,7 +18,7 @@
#define noSP_SS_VERBOSE
#include "stroke-style.h"
-#include "../gradient-chemistry.h"
+#include "gradient-chemistry.h"
#include "sp-gradient.h"
#include "sp-stop.h"
#include "svg/svg-color.h"
diff --git a/src/widgets/stroke-style.h b/src/widgets/stroke-style.h
index 6f0fe583b..15e394097 100644
--- a/src/widgets/stroke-style.h
+++ b/src/widgets/stroke-style.h
@@ -12,6 +12,8 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
+// WHOA! talk about header bloat!
+
#ifndef SEEN_DIALOGS_STROKE_STYLE_H
#define SEEN_DIALOGS_STROKE_STYLE_H
@@ -33,7 +35,7 @@
#include "desktop.h"
#include "desktop-handles.h"
#include "desktop-style.h"
-#include "dialogs/dialog-events.h"
+#include "ui/dialog-events.h"
#include "display/canvas-bpath.h" // for SP_STROKE_LINEJOIN_*
#include "display/drawing.h"
#include "document-private.h"
@@ -42,7 +44,7 @@
#include "helper/stock-items.h"
#include "inkscape.h"
#include "io/sys.h"
-#include "marker.h"
+#include "sp-marker.h"
#include "preferences.h"
#include "path-prefix.h"
#include "selection.h"
diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp
index 2697beb8a..d62bb8027 100644
--- a/src/widgets/text-toolbar.cpp
+++ b/src/widgets/text-toolbar.cpp
@@ -36,10 +36,10 @@
#include "desktop.h"
#include "document-undo.h"
#include "document.h"
-#include "ege-adjustment-action.h"
-#include "ege-select-one-action.h"
-#include "ink-action.h"
-#include "ink-comboboxentry-action.h"
+#include "widgets/ege-adjustment-action.h"
+#include "widgets/ege-select-one-action.h"
+#include "widgets/ink-action.h"
+#include "widgets/ink-comboboxentry-action.h"
#include "inkscape.h"
#include "preferences.h"
#include "selection-chemistry.h"
@@ -1663,4 +1663,4 @@ static void text_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolB
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 :
diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp
index 939546f78..9e55d1cf6 100644
--- a/src/widgets/toolbox.cpp
+++ b/src/widgets/toolbox.cpp
@@ -43,20 +43,20 @@
#include "../desktop-handles.h"
#include "../desktop-style.h"
#include "document-undo.h"
-#include "../ege-adjustment-action.h"
-#include "../ege-output-action.h"
-#include "../ege-select-one-action.h"
+#include "widgets/ege-adjustment-action.h"
+#include "widgets/ege-output-action.h"
+#include "widgets/ege-select-one-action.h"
#include "../graphlayout.h"
#include "../helper/action.h"
#include "../helper/action-context.h"
#include "icon.h"
-#include "../ink-action.h"
-#include "../ink-comboboxentry-action.h"
+#include "ink-action.h"
+#include "ink-comboboxentry-action.h"
#include "../inkscape.h"
-#include "../interface.h"
+#include "ui/interface.h"
#include "../shortcuts.h"
#include "../sp-namedview.h"
-#include "../tools-switch.h"
+#include "ui/tools-switch.h"
#include "../ui/icon-names.h"
#include "../ui/widget/style-swatch.h"
#include "../verbs.h"
diff --git a/src/widgets/toolbox.h b/src/widgets/toolbox.h
index fb749bfb5..db9130034 100644
--- a/src/widgets/toolbox.h
+++ b/src/widgets/toolbox.h
@@ -13,15 +13,15 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
-#include <gtk/gtk.h>
#include <glibmm/ustring.h>
#include "icon-size.h"
-#include "../ege-adjustment-action.h"
-#include "../preferences.h"
+#include "preferences.h"
#define TOOLBAR_SLIDER_HINT "full"
+typedef struct _EgeAdjustmentAction EgeAdjustmentAction;
+
class SPDesktop;
namespace Inkscape {
diff --git a/src/widgets/tweak-toolbar.cpp b/src/widgets/tweak-toolbar.cpp
index 050d7fb5e..a5d90fc3d 100644
--- a/src/widgets/tweak-toolbar.cpp
+++ b/src/widgets/tweak-toolbar.cpp
@@ -33,10 +33,10 @@
#include "tweak-toolbar.h"
#include "desktop.h"
#include "document-undo.h"
-#include "ege-adjustment-action.h"
-#include "ege-output-action.h"
-#include "ege-select-one-action.h"
-#include "ink-action.h"
+#include "widgets/ege-adjustment-action.h"
+#include "widgets/ege-output-action.h"
+#include "widgets/ege-select-one-action.h"
+#include "widgets/ink-action.h"
#include "preferences.h"
#include "toolbox.h"
#include "ui/icon-names.h"