~valavanisalex/ubuntu/oneiric/inkscape/inkscape_0.48.1-2ubuntu4

« back to all changes in this revision

Viewing changes to src/widgets/toolbox.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook, Kees Cook, Ted Gould
  • Date: 2008-02-10 14:20:16 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20080210142016-vcnb2zqyhszu0xvb
Tags: 0.46~pre1-0ubuntu1
[ Kees Cook ]
* debian/control:
  - add libgtkspell-dev build-dep to gain GtkSpell features (LP: #183547).
  - update Standards version (no changes needed).
  - add Vcs and Homepage fields.
  - switch to new python-lxml dep.
* debian/{control,rules}: switch from dpatch to quilt for more sanity.
* debian/patches/20_fix_glib_and_gxx43_ftbfs.patch:
  - merged against upstream fixes.
  - added additional fixes for newly written code.
* debian/rules: enable parallel building.

[ Ted Gould ]
* Updating POTFILES.in to make it so things build correctly.
* debian/control:
  - add ImageMagick++ and libboost-dev to build-deps

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#define __SP_MAINTOOLBOX_C__
2
 
 
3
1
/** \file
4
 
 * Controls bars for some of Inkscape's tools 
 
2
 * Controls bars for some of Inkscape's tools
5
3
 * (for some tools, they are in their own files)
6
4
 */
7
5
 
29
27
# include "config.h"
30
28
#endif
31
29
 
 
30
#include <cstring>
 
31
#include <string>
 
32
 
32
33
#include <gtkmm.h>
33
34
#include <gtk/gtk.h>
34
35
#include <iostream>
47
48
#include "sp-namedview.h"
48
49
#include "desktop.h"
49
50
#include "desktop-handles.h"
50
 
#include "nodepath.h"
51
51
#include "xml/repr.h"
52
52
#include "xml/node-event-vector.h"
53
53
#include <glibmm/i18n.h>
62
62
#include "gradient-toolbar.h"
63
63
 
64
64
#include "connector-context.h"
 
65
#include "node-context.h"
 
66
#include "shape-editor.h"
 
67
#include "tweak-context.h"
65
68
#include "sp-rect.h"
 
69
#include "box3d.h"
 
70
#include "box3d-context.h"
66
71
#include "sp-star.h"
67
72
#include "sp-spiral.h"
68
73
#include "sp-ellipse.h"
70
75
#include "sp-flowtext.h"
71
76
#include "style.h"
72
77
#include "selection.h"
 
78
#include "selection-chemistry.h"
73
79
#include "document-private.h"
74
80
#include "desktop-style.h"
75
81
#include "../libnrtype/font-lister.h"
 
82
#include "../libnrtype/font-instance.h"
76
83
#include "../connection-pool.h"
77
84
#include "../prefs-utils.h"
78
85
#include "../inkscape-stock.h"
83
90
 
84
91
#include "toolbox.h"
85
92
 
 
93
#include "flood-context.h"
 
94
 
86
95
#include "ink-action.h"
87
96
#include "ege-adjustment-action.h"
 
97
#include "ege-output-action.h"
 
98
#include "ege-select-one-action.h"
 
99
#include "helper/unit-tracker.h"
 
100
 
 
101
#include "svg/css-ostringstream.h"
 
102
 
 
103
using Inkscape::UnitTracker;
88
104
 
89
105
typedef void (*SetupFunction)(GtkWidget *toolbox, SPDesktop *desktop);
90
106
typedef void (*UpdateFunction)(SPDesktop *desktop, SPEventContext *eventcontext, GtkWidget *toolbox);
91
107
 
92
 
static GtkWidget *sp_node_toolbox_new(SPDesktop *desktop);
93
 
static GtkWidget *sp_zoom_toolbox_new(SPDesktop *desktop);
94
 
static GtkWidget *sp_star_toolbox_new(SPDesktop *desktop);
95
 
static GtkWidget *sp_arc_toolbox_new(SPDesktop *desktop);
96
 
static GtkWidget *sp_rect_toolbox_new(SPDesktop *desktop);
97
 
static GtkWidget *sp_spiral_toolbox_new(SPDesktop *desktop);
98
 
static GtkWidget *sp_pencil_toolbox_new(SPDesktop *desktop);
99
 
static GtkWidget *sp_pen_toolbox_new(SPDesktop *desktop);
100
 
static GtkWidget *sp_calligraphy_toolbox_new(SPDesktop *desktop);
101
 
static GtkWidget *sp_dropper_toolbox_new(SPDesktop *desktop);
 
108
static void       sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
 
109
static void       sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
 
110
static void       sp_zoom_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
 
111
static void       sp_star_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
 
112
static void       sp_arc_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
 
113
static void       sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
 
114
static void       box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
 
115
static void       sp_spiral_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
 
116
static void       sp_pencil_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
 
117
static void       sp_pen_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
 
118
static void       sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
 
119
static void       sp_dropper_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
102
120
static GtkWidget *sp_empty_toolbox_new(SPDesktop *desktop);
103
 
static GtkWidget *sp_connector_toolbox_new(SPDesktop *desktop);
 
121
static void       sp_connector_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
 
122
static void       sp_paintbucket_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
104
123
 
105
124
namespace { GtkWidget *sp_text_toolbox_new (SPDesktop *desktop); }
106
125
 
113
132
} const tools[] = {
114
133
    { "SPSelectContext",   "select_tool",    SP_VERB_CONTEXT_SELECT,  SP_VERB_CONTEXT_SELECT_PREFS},
115
134
    { "SPNodeContext",     "node_tool",      SP_VERB_CONTEXT_NODE, SP_VERB_CONTEXT_NODE_PREFS },
 
135
    { "SPTweakContext",    "tweak_tool",     SP_VERB_CONTEXT_TWEAK, SP_VERB_CONTEXT_TWEAK_PREFS },
116
136
    { "SPZoomContext",     "zoom_tool",      SP_VERB_CONTEXT_ZOOM, SP_VERB_CONTEXT_ZOOM_PREFS },
117
137
    { "SPRectContext",     "rect_tool",      SP_VERB_CONTEXT_RECT, SP_VERB_CONTEXT_RECT_PREFS },
 
138
    { "Box3DContext",      "3dbox_tool",     SP_VERB_CONTEXT_3DBOX, SP_VERB_CONTEXT_3DBOX_PREFS },
118
139
    { "SPArcContext",      "arc_tool",       SP_VERB_CONTEXT_ARC, SP_VERB_CONTEXT_ARC_PREFS },
119
140
    { "SPStarContext",     "star_tool",      SP_VERB_CONTEXT_STAR, SP_VERB_CONTEXT_STAR_PREFS },
120
141
    { "SPSpiralContext",   "spiral_tool",    SP_VERB_CONTEXT_SPIRAL, SP_VERB_CONTEXT_SPIRAL_PREFS },
121
142
    { "SPPencilContext",   "pencil_tool",    SP_VERB_CONTEXT_PENCIL, SP_VERB_CONTEXT_PENCIL_PREFS },
122
143
    { "SPPenContext",      "pen_tool",       SP_VERB_CONTEXT_PEN, SP_VERB_CONTEXT_PEN_PREFS },
123
144
    { "SPDynaDrawContext", "dyna_draw_tool", SP_VERB_CONTEXT_CALLIGRAPHIC, SP_VERB_CONTEXT_CALLIGRAPHIC_PREFS },
 
145
    { "SPFloodContext",    "paintbucket_tool",     SP_VERB_CONTEXT_PAINTBUCKET, SP_VERB_CONTEXT_PAINTBUCKET_PREFS },
124
146
    { "SPTextContext",     "text_tool",      SP_VERB_CONTEXT_TEXT, SP_VERB_CONTEXT_TEXT_PREFS },
125
147
    { "SPConnectorContext","connector_tool", SP_VERB_CONTEXT_CONNECTOR, SP_VERB_CONTEXT_CONNECTOR_PREFS },
126
148
    { "SPGradientContext", "gradient_tool",  SP_VERB_CONTEXT_GRADIENT, SP_VERB_CONTEXT_GRADIENT_PREFS },
132
154
    gchar const *type_name;
133
155
    gchar const *data_name;
134
156
    GtkWidget *(*create_func)(SPDesktop *desktop);
 
157
    void (*prep_func)(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
 
158
    gchar const *ui_name;
 
159
    gint swatch_verb_id;
 
160
    gchar const *swatch_tool;
 
161
    gchar const *swatch_tip;
135
162
} const aux_toolboxes[] = {
136
 
    { "SPSelectContext", "select_toolbox", sp_select_toolbox_new },
137
 
    { "SPNodeContext",   "node_toolbox",   sp_node_toolbox_new },
138
 
    { "SPZoomContext",   "zoom_toolbox",   sp_zoom_toolbox_new },
139
 
    { "SPStarContext",   "star_toolbox",   sp_star_toolbox_new },
140
 
    { "SPRectContext",   "rect_toolbox",   sp_rect_toolbox_new },
141
 
    { "SPArcContext",    "arc_toolbox",    sp_arc_toolbox_new },
142
 
    { "SPSpiralContext", "spiral_toolbox", sp_spiral_toolbox_new },
143
 
    { "SPPencilContext", "pencil_toolbox", sp_pencil_toolbox_new },
144
 
    { "SPPenContext", "pen_toolbox", sp_pen_toolbox_new },
145
 
    { "SPDynaDrawContext", "calligraphy_toolbox", sp_calligraphy_toolbox_new },
146
 
    { "SPTextContext",   "text_toolbox",   sp_text_toolbox_new },
147
 
    { "SPDropperContext", "dropper_toolbox", sp_dropper_toolbox_new },
148
 
    { "SPGradientContext", "gradient_toolbox", sp_gradient_toolbox_new },
149
 
    { "SPConnectorContext", "connector_toolbox", sp_connector_toolbox_new },
150
 
    { NULL, NULL, NULL }
 
163
    { "SPSelectContext", "select_toolbox", 0, sp_select_toolbox_prep,            "SelectToolbar",
 
164
      SP_VERB_INVALID, 0, 0},
 
165
    { "SPNodeContext",   "node_toolbox",   0, sp_node_toolbox_prep,              "NodeToolbar",
 
166
      SP_VERB_INVALID, 0, 0},
 
167
    { "SPTweakContext",   "tweak_toolbox",   0, sp_tweak_toolbox_prep,              "TweakToolbar",
 
168
      SP_VERB_CONTEXT_TWEAK_PREFS, "tools.tweak", _("Color/opacity used for color tweaking")},
 
169
    { "SPZoomContext",   "zoom_toolbox",   0, sp_zoom_toolbox_prep,              "ZoomToolbar",
 
170
      SP_VERB_INVALID, 0, 0},
 
171
    { "SPStarContext",   "star_toolbox",   0, sp_star_toolbox_prep,              "StarToolbar",
 
172
      SP_VERB_CONTEXT_STAR_PREFS,   "tools.shapes.star",     _("Style of new stars")},
 
173
    { "SPRectContext",   "rect_toolbox",   0, sp_rect_toolbox_prep,              "RectToolbar",
 
174
      SP_VERB_CONTEXT_RECT_PREFS,   "tools.shapes.rect",     _("Style of new rectangles")},
 
175
    { "Box3DContext",  "3dbox_toolbox",  0, box3d_toolbox_prep,             "3DBoxToolbar",
 
176
      SP_VERB_CONTEXT_3DBOX_PREFS,  "tools.shapes.3dbox",    _("Style of new 3D boxes")},
 
177
    { "SPArcContext",    "arc_toolbox",    0, sp_arc_toolbox_prep,               "ArcToolbar",
 
178
      SP_VERB_CONTEXT_ARC_PREFS,    "tools.shapes.arc",      _("Style of new ellipses")},
 
179
    { "SPSpiralContext", "spiral_toolbox", 0, sp_spiral_toolbox_prep,            "SpiralToolbar",
 
180
      SP_VERB_CONTEXT_SPIRAL_PREFS, "tools.shapes.spiral",   _("Style of new spirals")},
 
181
    { "SPPencilContext", "pencil_toolbox", 0, sp_pencil_toolbox_prep,            "PencilToolbar",
 
182
      SP_VERB_CONTEXT_PENCIL_PREFS, "tools.freehand.pencil", _("Style of new paths created by Pencil")},
 
183
    { "SPPenContext", "pen_toolbox", 0, sp_pen_toolbox_prep,                     "PenToolbar",
 
184
      SP_VERB_CONTEXT_PEN_PREFS,    "tools.freehand.pen",    _("Style of new paths created by Pen")},
 
185
    { "SPDynaDrawContext", "calligraphy_toolbox", 0, sp_calligraphy_toolbox_prep,"CalligraphyToolbar",
 
186
      SP_VERB_CONTEXT_CALLIGRAPHIC_PREFS, "tools.calligraphic", _("Style of new calligraphic strokes")},
 
187
    { "SPTextContext",   "text_toolbox",   sp_text_toolbox_new, 0,               0,
 
188
      SP_VERB_INVALID, 0, 0},
 
189
    { "SPDropperContext", "dropper_toolbox", 0, sp_dropper_toolbox_prep,         "DropperToolbar",
 
190
      SP_VERB_INVALID, 0, 0},
 
191
    { "SPGradientContext", "gradient_toolbox", sp_gradient_toolbox_new, 0,       0,
 
192
      SP_VERB_INVALID, 0, 0},
 
193
    { "SPConnectorContext", "connector_toolbox", 0, sp_connector_toolbox_prep,   "ConnectorToolbar",
 
194
      SP_VERB_INVALID, 0, 0},
 
195
    { "SPFloodContext",  "paintbucket_toolbox",  0, sp_paintbucket_toolbox_prep, "PaintbucketToolbar",
 
196
      SP_VERB_CONTEXT_PAINTBUCKET_PREFS, "tools.paintbucket", _("Style of Paint Bucket fill objects")},
 
197
    { NULL, NULL, NULL, NULL, NULL, SP_VERB_INVALID, NULL, NULL }
151
198
};
152
199
 
 
200
 
 
201
static gchar const * ui_descr =
 
202
        "<ui>"
 
203
        "  <toolbar name='SelectToolbar'>"
 
204
        "    <toolitem action='EditSelectAll' />"
 
205
        "    <toolitem action='EditSelectAllInAllLayers' />"
 
206
        "    <toolitem action='EditDeselect' />"
 
207
        "    <separator />"
 
208
        "    <toolitem action='ObjectRotate90CCW' />"
 
209
        "    <toolitem action='ObjectRotate90' />"
 
210
        "    <toolitem action='ObjectFlipHorizontally' />"
 
211
        "    <toolitem action='ObjectFlipVertically' />"
 
212
        "    <separator />"
 
213
        "    <toolitem action='SelectionToBack' />"
 
214
        "    <toolitem action='SelectionLower' />"
 
215
        "    <toolitem action='SelectionRaise' />"
 
216
        "    <toolitem action='SelectionToFront' />"
 
217
        "    <separator />"
 
218
        "    <toolitem action='XAction' />"
 
219
        "    <toolitem action='YAction' />"
 
220
        "    <toolitem action='WidthAction' />"
 
221
        "    <toolitem action='LockAction' />"
 
222
        "    <toolitem action='HeightAction' />"
 
223
        "    <toolitem action='UnitsAction' />"
 
224
        "    <separator />"
 
225
        "    <toolitem action='transform_affect_label' />"
 
226
        "    <toolitem action='transform_stroke' />"
 
227
        "    <toolitem action='transform_corners' />"
 
228
        "    <toolitem action='transform_gradient' />"
 
229
        "    <toolitem action='transform_pattern' />"
 
230
        "  </toolbar>"
 
231
 
 
232
        "  <toolbar name='NodeToolbar'>"
 
233
        "    <toolitem action='NodeInsertAction' />"
 
234
        "    <toolitem action='NodeDeleteAction' />"
 
235
        "    <separator />"
 
236
        "    <toolitem action='NodeJoinAction' />"
 
237
        "    <toolitem action='NodeJoinSegmentAction' />"
 
238
        "    <toolitem action='NodeDeleteSegmentAction' />"
 
239
        "    <toolitem action='NodeBreakAction' />"
 
240
        "    <separator />"
 
241
        "    <toolitem action='NodeCuspAction' />"
 
242
        "    <toolitem action='NodeSmoothAction' />"
 
243
        "    <toolitem action='NodeSymmetricAction' />"
 
244
        "    <separator />"
 
245
        "    <toolitem action='NodeLineAction' />"
 
246
        "    <toolitem action='NodeCurveAction' />"
 
247
        "    <separator />"
 
248
        "    <toolitem action='ObjectToPath' />"
 
249
        "    <toolitem action='StrokeToPath' />"
 
250
        "    <separator />"
 
251
        "    <toolitem action='NodesShowHandlesAction' />"
 
252
        "    <separator />"
 
253
        "    <toolitem action='EditNextLPEParameterAction' />"
 
254
        "    <separator />"
 
255
        "    <toolitem action='NodeXAction' />"
 
256
        "    <toolitem action='NodeYAction' />"
 
257
        "    <toolitem action='NodeUnitsAction' />"
 
258
        "  </toolbar>"
 
259
 
 
260
        "  <toolbar name='TweakToolbar'>"
 
261
        "    <toolitem action='TweakWidthAction' />"
 
262
        "    <separator />"
 
263
        "    <toolitem action='TweakForceAction' />"
 
264
        "    <toolitem action='TweakPressureAction' />"
 
265
        "    <separator />"
 
266
        "    <toolitem action='TweakModeAction' />"
 
267
        "    <separator />"
 
268
        "    <toolitem action='TweakFidelityAction' />"
 
269
        "    <separator />"
 
270
        "    <toolitem action='TweakChannelsLabel' />"
 
271
        "    <toolitem action='TweakDoH' />"
 
272
        "    <toolitem action='TweakDoS' />"
 
273
        "    <toolitem action='TweakDoL' />"
 
274
        "    <toolitem action='TweakDoO' />"
 
275
        "  </toolbar>"
 
276
 
 
277
        "  <toolbar name='ZoomToolbar'>"
 
278
        "    <toolitem action='ZoomIn' />"
 
279
        "    <toolitem action='ZoomOut' />"
 
280
        "    <separator />"
 
281
        "    <toolitem action='Zoom1:0' />"
 
282
        "    <toolitem action='Zoom1:2' />"
 
283
        "    <toolitem action='Zoom2:1' />"
 
284
        "    <separator />"
 
285
        "    <toolitem action='ZoomSelection' />"
 
286
        "    <toolitem action='ZoomDrawing' />"
 
287
        "    <toolitem action='ZoomPage' />"
 
288
        "    <toolitem action='ZoomPageWidth' />"
 
289
        "    <separator />"
 
290
        "    <toolitem action='ZoomPrev' />"
 
291
        "    <toolitem action='ZoomNext' />"
 
292
        "  </toolbar>"
 
293
 
 
294
        "  <toolbar name='StarToolbar'>"
 
295
        "    <separator />"
 
296
        "    <toolitem action='StarStateAction' />"
 
297
        "    <separator />"
 
298
        "    <toolitem action='FlatAction' />"
 
299
        "    <separator />"
 
300
        "    <toolitem action='MagnitudeAction' />"
 
301
        "    <toolitem action='SpokeAction' />"
 
302
        "    <toolitem action='RoundednessAction' />"
 
303
        "    <toolitem action='RandomizationAction' />"
 
304
        "    <separator />"
 
305
        "    <toolitem action='StarResetAction' />"
 
306
        "  </toolbar>"
 
307
 
 
308
        "  <toolbar name='RectToolbar'>"
 
309
        "    <toolitem action='RectStateAction' />"
 
310
        "    <toolitem action='RectWidthAction' />"
 
311
        "    <toolitem action='RectHeightAction' />"
 
312
        "    <toolitem action='RadiusXAction' />"
 
313
        "    <toolitem action='RadiusYAction' />"
 
314
        "    <toolitem action='RectUnitsAction' />"
 
315
        "    <separator />"
 
316
        "    <toolitem action='RectResetAction' />"
 
317
        "  </toolbar>"
 
318
 
 
319
        "  <toolbar name='3DBoxToolbar'>"
 
320
        "    <toolitem action='3DBoxAngleXAction' />"
 
321
        "    <toolitem action='3DBoxVPXStateAction' />"
 
322
        "    <separator />"
 
323
        "    <toolitem action='3DBoxAngleYAction' />"
 
324
        "    <toolitem action='3DBoxVPYStateAction' />"
 
325
        "    <separator />"
 
326
        "    <toolitem action='3DBoxAngleZAction' />"
 
327
        "    <toolitem action='3DBoxVPZStateAction' />"
 
328
        "  </toolbar>"
 
329
 
 
330
        "  <toolbar name='SpiralToolbar'>"
 
331
        "    <toolitem action='SpiralStateAction' />"
 
332
        "    <toolitem action='SpiralRevolutionAction' />"
 
333
        "    <toolitem action='SpiralExpansionAction' />"
 
334
        "    <toolitem action='SpiralT0Action' />"
 
335
        "    <separator />"
 
336
        "    <toolitem action='SpiralResetAction' />"
 
337
        "  </toolbar>"
 
338
 
 
339
        "  <toolbar name='PenToolbar'>"
 
340
        "  </toolbar>"
 
341
 
 
342
        "  <toolbar name='PencilToolbar'>"
 
343
        "  </toolbar>"
 
344
 
 
345
        "  <toolbar name='CalligraphyToolbar'>"
 
346
        "    <separator />"
 
347
        "    <toolitem action='CalligraphyWidthAction' />"
 
348
        "    <toolitem action='PressureAction' />"
 
349
        "    <toolitem action='TraceAction' />"
 
350
        "    <toolitem action='ThinningAction' />"
 
351
        "    <separator />"
 
352
        "    <toolitem action='AngleAction' />"
 
353
        "    <toolitem action='TiltAction' />"
 
354
        "    <toolitem action='FixationAction' />"
 
355
        "    <separator />"
 
356
        "    <toolitem action='CapRoundingAction' />"
 
357
        "    <separator />"
 
358
        "    <toolitem action='TremorAction' />"
 
359
        "    <toolitem action='WiggleAction' />"
 
360
        "    <toolitem action='MassAction' />"
 
361
        "    <separator />"
 
362
        "    <toolitem action='CalligraphyResetAction' />"
 
363
        "  </toolbar>"
 
364
 
 
365
        "  <toolbar name='ArcToolbar'>"
 
366
        "    <toolitem action='ArcStateAction' />"
 
367
        "    <separator />"
 
368
        "    <toolitem action='ArcStartAction' />"
 
369
        "    <toolitem action='ArcEndAction' />"
 
370
        "    <separator />"
 
371
        "    <toolitem action='ArcOpenAction' />"
 
372
        "    <separator />"
 
373
        "    <toolitem action='ArcResetAction' />"
 
374
        "    <separator />"
 
375
        "  </toolbar>"
 
376
 
 
377
        "  <toolbar name='PaintbucketToolbar'>"
 
378
        "    <toolitem action='ChannelsAction' />"
 
379
        "    <separator />"
 
380
        "    <toolitem action='ThresholdAction' />"
 
381
        "    <separator />"
 
382
        "    <toolitem action='OffsetAction' />"
 
383
        "    <toolitem action='PaintbucketUnitsAction' />"
 
384
        "    <separator />"
 
385
        "    <toolitem action='AutoGapAction' />"
 
386
        "    <separator />"
 
387
        "    <toolitem action='PaintbucketResetAction' />"
 
388
        "  </toolbar>"
 
389
 
 
390
        "  <toolbar name='DropperToolbar'>"
 
391
        "    <toolitem action='DropperPickAlphaAction' />"
 
392
        "    <toolitem action='DropperSetAlphaAction' />"
 
393
        "  </toolbar>"
 
394
 
 
395
        "  <toolbar name='ConnectorToolbar'>"
 
396
        "    <toolitem action='ConnectorAvoidAction' />"
 
397
        "    <toolitem action='ConnectorIgnoreAction' />"
 
398
        "    <toolitem action='ConnectorSpacingAction' />"
 
399
        "    <toolitem action='ConnectorGraphAction' />"
 
400
        "    <toolitem action='ConnectorLengthAction' />"
 
401
        "    <toolitem action='ConnectorDirectedAction' />"
 
402
        "    <toolitem action='ConnectorOverlapAction' />"
 
403
        "  </toolbar>"
 
404
 
 
405
        "</ui>"
 
406
;
 
407
 
 
408
static GtkActionGroup* create_or_fetch_actions( SPDesktop* desktop );
 
409
 
153
410
static void toolbox_set_desktop (GtkWidget *toolbox, SPDesktop *desktop, SetupFunction setup_func, UpdateFunction update_func, sigc::connection*);
154
411
 
155
412
static void setup_tool_toolbox (GtkWidget *toolbox, SPDesktop *desktop);
162
419
static void update_commands_toolbox (SPDesktop *desktop, SPEventContext *eventcontext, GtkWidget *toolbox);
163
420
 
164
421
/* Global text entry widgets necessary for update */
165
 
/* GtkWidget *dropper_rgb_entry, 
 
422
/* GtkWidget *dropper_rgb_entry,
166
423
          *dropper_opacity_entry ; */
167
424
// should be made a private member once this is converted to class
168
425
 
169
 
static void delete_connection(GObject *obj, sigc::connection *connection) {
 
426
static void delete_connection(GObject */*obj*/, sigc::connection *connection) {
170
427
    connection->disconnect();
171
428
    delete connection;
172
429
}
173
430
 
174
 
static GtkWidget *
175
 
sp_toolbox_button_new(GtkWidget *t, Inkscape::IconSize size, gchar const *pxname, GtkSignalFunc handler,
176
 
                      GtkTooltips *tt, gchar const *tip)
 
431
static void purge_repr_listener( GObject* obj, GObject* tbl )
177
432
{
178
 
    GtkWidget *b = sp_button_new_from_data(size, SP_BUTTON_TYPE_NORMAL, NULL, pxname, tip, tt);
179
 
    gtk_widget_show(b);
180
 
    if (handler) gtk_signal_connect(GTK_OBJECT(b), "clicked", handler, NULL);
181
 
    gtk_box_pack_start(GTK_BOX(t), b, FALSE, FALSE, 0);
182
 
 
183
 
    return b;
 
433
    (void)obj;
 
434
    Inkscape::XML::Node* oldrepr = reinterpret_cast<Inkscape::XML::Node *>( g_object_get_data( tbl, "repr" ) );
 
435
    if (oldrepr) { // remove old listener
 
436
        sp_repr_remove_listener_by_data(oldrepr, tbl);
 
437
        Inkscape::GC::release(oldrepr);
 
438
        oldrepr = 0;
 
439
        g_object_set_data( tbl, "repr", NULL );
 
440
    }
184
441
}
185
442
 
186
443
GtkWidget *
218
475
    return sp_toolbox_button_new_from_verb(t, size, SP_BUTTON_TYPE_NORMAL, verb, view, tt);
219
476
}
220
477
 
 
478
 
 
479
static void trigger_sp_action( GtkAction* /*act*/, gpointer user_data )
 
480
{
 
481
    SPAction* targetAction = SP_ACTION(user_data);
 
482
    if ( targetAction ) {
 
483
        sp_action_perform( targetAction, NULL );
 
484
    }
 
485
}
 
486
 
 
487
static void sp_action_action_set_sensitive (SPAction */*action*/, unsigned int sensitive, void *data)
 
488
{
 
489
    if ( data ) {
 
490
        GtkAction* act = GTK_ACTION(data);
 
491
        gtk_action_set_sensitive( act, sensitive );
 
492
    }
 
493
}
 
494
 
 
495
static SPActionEventVector action_event_vector = {
 
496
    {NULL},
 
497
    NULL,
 
498
    NULL,
 
499
    sp_action_action_set_sensitive,
 
500
    NULL,
 
501
    NULL
 
502
};
 
503
 
 
504
static GtkAction* create_action_for_verb( Inkscape::Verb* verb, Inkscape::UI::View::View* view, Inkscape::IconSize size )
 
505
{
 
506
    GtkAction* act = 0;
 
507
 
 
508
    SPAction* targetAction = verb->get_action(view);
 
509
    InkAction* inky = ink_action_new( verb->get_id(), verb->get_name(), verb->get_tip(), verb->get_image(), size  );
 
510
    act = GTK_ACTION(inky);
 
511
    gtk_action_set_sensitive( act, targetAction->sensitive );
 
512
 
 
513
    g_signal_connect( G_OBJECT(inky), "activate", GTK_SIGNAL_FUNC(trigger_sp_action), targetAction );
 
514
 
 
515
    SPAction*rebound = dynamic_cast<SPAction *>( nr_object_ref( dynamic_cast<NRObject *>(targetAction) ) );
 
516
    nr_active_object_add_listener( (NRActiveObject *)rebound, (NRObjectEventVector *)&action_event_vector, sizeof(SPActionEventVector), inky );
 
517
 
 
518
    return act;
 
519
}
 
520
 
 
521
GtkActionGroup* create_or_fetch_actions( SPDesktop* desktop )
 
522
{
 
523
    Inkscape::UI::View::View *view = desktop;
 
524
    gint verbsToUse[] = {
 
525
        // disabled until we have icons for them:
 
526
        //find
 
527
        //SP_VERB_EDIT_TILE,
 
528
        //SP_VERB_EDIT_UNTILE,
 
529
        SP_VERB_DIALOG_ALIGN_DISTRIBUTE,
 
530
        SP_VERB_DIALOG_DISPLAY,
 
531
        SP_VERB_DIALOG_FILL_STROKE,
 
532
        SP_VERB_DIALOG_NAMEDVIEW,
 
533
        SP_VERB_DIALOG_TEXT,
 
534
        SP_VERB_DIALOG_XML_EDITOR,
 
535
        SP_VERB_EDIT_CLONE,
 
536
        SP_VERB_EDIT_COPY,
 
537
        SP_VERB_EDIT_CUT,
 
538
        SP_VERB_EDIT_DUPLICATE,
 
539
        SP_VERB_EDIT_PASTE,
 
540
        SP_VERB_EDIT_REDO,
 
541
        SP_VERB_EDIT_UNDO,
 
542
        SP_VERB_EDIT_UNLINK_CLONE,
 
543
        SP_VERB_FILE_EXPORT,
 
544
        SP_VERB_FILE_IMPORT,
 
545
        SP_VERB_FILE_NEW,
 
546
        SP_VERB_FILE_OPEN,
 
547
        SP_VERB_FILE_PRINT,
 
548
        SP_VERB_FILE_SAVE,
 
549
        SP_VERB_OBJECT_TO_CURVE,
 
550
        SP_VERB_SELECTION_GROUP,
 
551
        SP_VERB_SELECTION_OUTLINE,
 
552
        SP_VERB_SELECTION_UNGROUP,
 
553
        SP_VERB_ZOOM_1_1,
 
554
        SP_VERB_ZOOM_1_2,
 
555
        SP_VERB_ZOOM_2_1,
 
556
        SP_VERB_ZOOM_DRAWING,
 
557
        SP_VERB_ZOOM_IN,
 
558
        SP_VERB_ZOOM_NEXT,
 
559
        SP_VERB_ZOOM_OUT,
 
560
        SP_VERB_ZOOM_PAGE,
 
561
        SP_VERB_ZOOM_PAGE_WIDTH,
 
562
        SP_VERB_ZOOM_PREV,
 
563
        SP_VERB_ZOOM_SELECTION,
 
564
    };
 
565
 
 
566
    gint shrinkTop = prefs_get_int_attribute_limited( "toolbox", "small", 1, 0, 1 );
 
567
    Inkscape::IconSize toolboxSize = shrinkTop ? Inkscape::ICON_SIZE_SMALL_TOOLBAR : Inkscape::ICON_SIZE_LARGE_TOOLBAR;
 
568
 
 
569
    static std::map<SPDesktop*, GtkActionGroup*> groups;
 
570
    GtkActionGroup* mainActions = 0;
 
571
    if ( groups.find(desktop) != groups.end() ) {
 
572
        mainActions = groups[desktop];
 
573
    }
 
574
 
 
575
    if ( !mainActions ) {
 
576
        mainActions = gtk_action_group_new("main");
 
577
        groups[desktop] = mainActions;
 
578
    }
 
579
 
 
580
    for ( guint i = 0; i < G_N_ELEMENTS(verbsToUse); i++ ) {
 
581
        Inkscape::Verb* verb = Inkscape::Verb::get(verbsToUse[i]);
 
582
        if ( verb ) {
 
583
            if ( !gtk_action_group_get_action( mainActions, verb->get_id() ) ) {
 
584
                GtkAction* act = create_action_for_verb( verb, view, toolboxSize );
 
585
                gtk_action_group_add_action( mainActions, act );
 
586
            }
 
587
        }
 
588
    }
 
589
 
 
590
    return mainActions;
 
591
}
 
592
 
 
593
 
221
594
GtkWidget *
222
595
sp_tool_toolbox_new()
223
596
{
244
617
}
245
618
 
246
619
static void
247
 
aux_toolbox_attached(GtkHandleBox *toolbox, GtkWidget *child)
 
620
aux_toolbox_attached(GtkHandleBox */*toolbox*/, GtkWidget *child)
248
621
{
249
622
    g_object_set_data(G_OBJECT(child), "is_detached", GINT_TO_POINTER(FALSE));
250
623
    gtk_widget_queue_resize(child);
251
624
}
252
625
 
253
626
static void
254
 
aux_toolbox_detached(GtkHandleBox *toolbox, GtkWidget *child)
 
627
aux_toolbox_detached(GtkHandleBox */*toolbox*/, GtkWidget *child)
255
628
{
256
629
    g_object_set_data(G_OBJECT(child), "is_detached", GINT_TO_POINTER(TRUE));
257
630
    gtk_widget_queue_resize(child);
262
635
{
263
636
    GtkWidget *tb = gtk_vbox_new(FALSE, 0);
264
637
 
265
 
    GtkWidget *tb_s = gtk_vbox_new(FALSE, 0);
266
 
    GtkWidget *tb_e = gtk_vbox_new(FALSE, 0);
267
638
    gtk_box_set_spacing(GTK_BOX(tb), AUX_SPACING);
268
 
    gtk_box_pack_start(GTK_BOX(tb), GTK_WIDGET(tb_s), FALSE, FALSE, 0);
269
 
    gtk_box_pack_end(GTK_BOX(tb), GTK_WIDGET(tb_e), FALSE, FALSE, 0);
270
639
 
271
640
    g_object_set_data(G_OBJECT(tb), "desktop", NULL);
272
 
    g_object_set_data(G_OBJECT(tb), "top_spacer", tb_s);
273
641
 
274
642
    gtk_widget_set_sensitive(tb, FALSE);
275
643
 
299
667
{
300
668
    GtkWidget *tb = gtk_vbox_new(FALSE, 0);
301
669
 
302
 
    GtkWidget *tb_s = gtk_vbox_new(FALSE, 0);
303
 
    GtkWidget *tb_e = gtk_vbox_new(FALSE, 0);
304
670
    gtk_box_set_spacing(GTK_BOX(tb), AUX_SPACING);
305
 
    gtk_box_pack_start(GTK_BOX(tb), GTK_WIDGET(tb_s), FALSE, FALSE, 0);
306
 
    gtk_box_pack_end(GTK_BOX(tb), GTK_WIDGET(tb_e), FALSE, FALSE, 0);
307
671
 
308
672
    g_object_set_data(G_OBJECT(tb), "desktop", NULL);
309
673
    gtk_widget_set_sensitive(tb, FALSE);
325
689
    return hb;
326
690
}
327
691
 
 
692
static EgeAdjustmentAction * create_adjustment_action( gchar const *name,
 
693
                                                       gchar const *label, gchar const *shortLabel, gchar const *tooltip,
 
694
                                                       gchar const *path, gchar const *data, gdouble def,
 
695
                                                       GtkWidget *focusTarget,
 
696
                                                       GtkWidget *us,
 
697
                                                       GObject *dataKludge,
 
698
                                                       gboolean altx, gchar const *altx_mark,
 
699
                                                       gdouble lower, gdouble upper, gdouble step, gdouble page,
 
700
                                                       gchar const** descrLabels, gdouble const* descrValues, guint descrCount,
 
701
                                                       void (*callback)(GtkAdjustment *, GObject *),
 
702
                                                       gdouble climb = 0.1, guint digits = 3, double factor = 1.0 )
 
703
{
 
704
    GtkAdjustment* adj = GTK_ADJUSTMENT( gtk_adjustment_new( prefs_get_double_attribute(path, data, def) * factor,
 
705
                                                             lower, upper, step, page, page ) );
 
706
    if (us) {
 
707
        sp_unit_selector_add_adjustment( SP_UNIT_SELECTOR(us), adj );
 
708
    }
 
709
 
 
710
    gtk_signal_connect( GTK_OBJECT(adj), "value-changed", GTK_SIGNAL_FUNC(callback), dataKludge );
 
711
 
 
712
    EgeAdjustmentAction* act = ege_adjustment_action_new( adj, name, label, tooltip, 0, climb, digits );
 
713
    if ( shortLabel ) {
 
714
        g_object_set( act, "short_label", shortLabel, NULL );
 
715
    }
 
716
 
 
717
    if ( (descrCount > 0) && descrLabels && descrValues ) {
 
718
        ege_adjustment_action_set_descriptions( act, descrLabels, descrValues, descrCount );
 
719
    }
 
720
 
 
721
    if ( focusTarget ) {
 
722
        ege_adjustment_action_set_focuswidget( act, focusTarget );
 
723
    }
 
724
 
 
725
    if ( altx && altx_mark ) {
 
726
        g_object_set( G_OBJECT(act), "self-id", altx_mark, NULL );
 
727
    }
 
728
 
 
729
    if ( dataKludge ) {
 
730
        g_object_set_data( dataKludge, data, adj );
 
731
    }
 
732
 
 
733
    // Using a cast just to make sure we pass in the right kind of function pointer
 
734
    g_object_set( G_OBJECT(act), "tool-post", static_cast<EgeWidgetFixup>(sp_set_font_size_smaller), NULL );
 
735
 
 
736
    return act;
 
737
}
 
738
 
328
739
 
329
740
//####################################
330
741
//# node editing callbacks
331
742
//####################################
332
743
 
 
744
/**
 
745
 * FIXME: Returns current shape_editor in context. // later eliminate this function at all!
 
746
 */
 
747
static ShapeEditor *get_current_shape_editor()
 
748
{
 
749
    if (!SP_ACTIVE_DESKTOP) {
 
750
        return NULL;
 
751
    }
 
752
 
 
753
    SPEventContext *event_context = (SP_ACTIVE_DESKTOP)->event_context;
 
754
 
 
755
    if (!SP_IS_NODE_CONTEXT(event_context)) {
 
756
        return NULL;
 
757
    }
 
758
 
 
759
    return SP_NODE_CONTEXT(event_context)->shape_editor;
 
760
}
 
761
 
 
762
 
333
763
void
334
764
sp_node_path_edit_add(void)
335
765
{
336
 
    sp_node_selected_add_node();
 
766
    ShapeEditor *shape_editor = get_current_shape_editor();
 
767
    if (shape_editor) shape_editor->add_node();
337
768
}
338
769
 
339
770
void
340
771
sp_node_path_edit_delete(void)
341
772
{
342
 
    sp_node_selected_delete();
 
773
    ShapeEditor *shape_editor = get_current_shape_editor();
 
774
    if (shape_editor) shape_editor->delete_nodes();
343
775
}
344
776
 
345
777
void
346
778
sp_node_path_edit_delete_segment(void)
347
779
{
348
 
    sp_node_selected_delete_segment();
 
780
    ShapeEditor *shape_editor = get_current_shape_editor();
 
781
    if (shape_editor) shape_editor->delete_segment();
349
782
}
350
783
 
351
784
void
352
785
sp_node_path_edit_break(void)
353
786
{
354
 
    sp_node_selected_break();
 
787
    ShapeEditor *shape_editor = get_current_shape_editor();
 
788
    if (shape_editor) shape_editor->break_at_nodes();
355
789
}
356
790
 
357
791
void
358
792
sp_node_path_edit_join(void)
359
793
{
360
 
    sp_node_selected_join();
 
794
    ShapeEditor *shape_editor = get_current_shape_editor();
 
795
    if (shape_editor) shape_editor->join_nodes();
361
796
}
362
797
 
363
798
void
364
799
sp_node_path_edit_join_segment(void)
365
800
{
366
 
    sp_node_selected_join_segment();
 
801
    ShapeEditor *shape_editor = get_current_shape_editor();
 
802
    if (shape_editor) shape_editor->join_segments();
367
803
}
368
804
 
369
805
void
370
806
sp_node_path_edit_toline(void)
371
807
{
372
 
    sp_node_selected_set_line_type(NR_LINETO);
 
808
    ShapeEditor *shape_editor = get_current_shape_editor();
 
809
    if (shape_editor) shape_editor->set_type_of_segments(NR_LINETO);
373
810
}
374
811
 
375
812
void
376
813
sp_node_path_edit_tocurve(void)
377
814
{
378
 
    sp_node_selected_set_line_type(NR_CURVETO);
 
815
    ShapeEditor *shape_editor = get_current_shape_editor();
 
816
    if (shape_editor) shape_editor->set_type_of_segments(NR_CURVETO);
379
817
}
380
818
 
381
819
void
382
820
sp_node_path_edit_cusp(void)
383
821
{
384
 
    sp_node_selected_set_type(Inkscape::NodePath::NODE_CUSP);
 
822
    ShapeEditor *shape_editor = get_current_shape_editor();
 
823
    if (shape_editor) shape_editor->set_node_type(Inkscape::NodePath::NODE_CUSP);
385
824
}
386
825
 
387
826
void
388
827
sp_node_path_edit_smooth(void)
389
828
{
390
 
    sp_node_selected_set_type(Inkscape::NodePath::NODE_SMOOTH);
 
829
    ShapeEditor *shape_editor = get_current_shape_editor();
 
830
    if (shape_editor) shape_editor->set_node_type(Inkscape::NodePath::NODE_SMOOTH);
391
831
}
392
832
 
393
833
void
394
834
sp_node_path_edit_symmetrical(void)
395
835
{
396
 
    sp_node_selected_set_type(Inkscape::NodePath::NODE_SYMM);
 
836
    ShapeEditor *shape_editor = get_current_shape_editor();
 
837
    if (shape_editor) shape_editor->set_node_type(Inkscape::NodePath::NODE_SYMM);
397
838
}
398
839
 
399
 
static void toggle_show_handles (GtkWidget *button, gpointer data) {
400
 
    bool show = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
 
840
static void toggle_show_handles (GtkToggleAction *act, gpointer /*data*/) {
 
841
    bool show = gtk_toggle_action_get_active( act );
401
842
    prefs_set_int_attribute ("tools.nodes", "show_handles",  show ? 1 : 0);
402
 
    sp_nodepath_show_handles(show);
 
843
    ShapeEditor *shape_editor = get_current_shape_editor();
 
844
    if (shape_editor) shape_editor->show_handles(show);
 
845
}
 
846
 
 
847
void sp_node_path_edit_nextLPEparam (GtkAction */*act*/, gpointer data) {
 
848
    sp_selection_next_patheffect_param( reinterpret_cast<SPDesktop*>(data) );
 
849
}
 
850
 
 
851
/* is called when the node selection is modified */
 
852
static void
 
853
sp_node_toolbox_coord_changed(gpointer /*shape_editor*/, GObject *tbl)
 
854
{
 
855
    GtkAction* xact = GTK_ACTION( g_object_get_data( tbl, "nodes_x_action" ) );
 
856
    GtkAction* yact = GTK_ACTION( g_object_get_data( tbl, "nodes_y_action" ) );
 
857
    GtkAdjustment *xadj = ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION(xact));
 
858
    GtkAdjustment *yadj = ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION(yact));
 
859
 
 
860
    // quit if run by the attr_changed listener
 
861
    if (g_object_get_data( tbl, "freeze" )) {
 
862
        return;
 
863
    }
 
864
 
 
865
    // in turn, prevent listener from responding
 
866
    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE));
 
867
 
 
868
    UnitTracker* tracker = reinterpret_cast<UnitTracker*>( g_object_get_data( tbl, "tracker" ) );
 
869
    SPUnit const *unit = tracker->getActiveUnit();
 
870
 
 
871
    ShapeEditor *shape_editor = get_current_shape_editor();
 
872
    if (shape_editor && shape_editor->has_nodepath()) {
 
873
        Inkscape::NodePath::Path *nodepath = shape_editor->get_nodepath();
 
874
        int n_selected = 0;
 
875
        if (nodepath) {
 
876
            n_selected = nodepath->numSelected();
 
877
        }
 
878
 
 
879
        if (n_selected == 0) {
 
880
            gtk_action_set_sensitive(xact, FALSE);
 
881
            gtk_action_set_sensitive(yact, FALSE);
 
882
        } else {
 
883
            gtk_action_set_sensitive(xact, TRUE);
 
884
            gtk_action_set_sensitive(yact, TRUE);
 
885
            NR::Coord oldx = sp_units_get_pixels(gtk_adjustment_get_value(xadj), *unit);
 
886
            NR::Coord oldy = sp_units_get_pixels(gtk_adjustment_get_value(xadj), *unit);
 
887
 
 
888
            if (n_selected == 1) {
 
889
                NR::Point sel_node = nodepath->singleSelectedCoords();
 
890
                if (oldx != sel_node[NR::X] || oldy != sel_node[NR::Y]) {
 
891
                    gtk_adjustment_set_value(xadj, sp_pixels_get_units(sel_node[NR::X], *unit));
 
892
                    gtk_adjustment_set_value(yadj, sp_pixels_get_units(sel_node[NR::Y], *unit));
 
893
                }
 
894
            } else {
 
895
                NR::Maybe<NR::Coord> x = sp_node_selected_common_coord(nodepath, NR::X);
 
896
                NR::Maybe<NR::Coord> y = sp_node_selected_common_coord(nodepath, NR::Y);
 
897
                if ((x && ((*x) != oldx)) || (y && ((*y) != oldy))) {
 
898
                    /* Note: Currently x and y will always have a value, even if the coordinates of the
 
899
                       selected nodes don't coincide (in this case we use the coordinates of the center
 
900
                       of the bounding box). So the entries are never set to zero. */
 
901
                    // FIXME: Maybe we should clear the entry if several nodes are selected
 
902
                    //        instead of providing a kind of average value
 
903
                    gtk_adjustment_set_value(xadj, sp_pixels_get_units(x ? (*x) : 0.0, *unit));
 
904
                    gtk_adjustment_set_value(yadj, sp_pixels_get_units(y ? (*y) : 0.0, *unit));
 
905
                }
 
906
            }
 
907
        }
 
908
    } else {
 
909
        // no shape-editor or nodepath yet (when we just switched to the tool); coord entries must be inactive
 
910
        gtk_action_set_sensitive(xact, FALSE);
 
911
        gtk_action_set_sensitive(yact, FALSE);
 
912
    }
 
913
 
 
914
    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
 
915
}
 
916
 
 
917
static void
 
918
sp_node_path_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *value_name)
 
919
{
 
920
    SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" );
 
921
 
 
922
    UnitTracker* tracker = reinterpret_cast<UnitTracker*>(g_object_get_data( tbl, "tracker" ));
 
923
    SPUnit const *unit = tracker->getActiveUnit();
 
924
 
 
925
    if (sp_document_get_undo_sensitive(sp_desktop_document(desktop))) {
 
926
        prefs_set_double_attribute("tools.nodes", value_name, sp_units_get_pixels(adj->value, *unit));
 
927
    }
 
928
 
 
929
    // quit if run by the attr_changed listener
 
930
    if (g_object_get_data( tbl, "freeze" )) {
 
931
        return;
 
932
    }
 
933
 
 
934
    // in turn, prevent listener from responding
 
935
    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE));
 
936
 
 
937
    ShapeEditor *shape_editor = get_current_shape_editor();
 
938
    if (shape_editor && shape_editor->has_nodepath()) {
 
939
        double val = sp_units_get_pixels(gtk_adjustment_get_value(adj), *unit);
 
940
        if (!strcmp(value_name, "x")) {
 
941
            sp_node_selected_move_absolute(shape_editor->get_nodepath(), val, NR::X);
 
942
        }
 
943
        if (!strcmp(value_name, "y")) {
 
944
            sp_node_selected_move_absolute(shape_editor->get_nodepath(), val, NR::Y);
 
945
        }
 
946
    }
 
947
 
 
948
    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
 
949
}
 
950
 
 
951
static void
 
952
sp_node_path_x_value_changed(GtkAdjustment *adj, GObject *tbl)
 
953
{
 
954
    sp_node_path_value_changed(adj, tbl, "x");
 
955
}
 
956
 
 
957
static void
 
958
sp_node_path_y_value_changed(GtkAdjustment *adj, GObject *tbl)
 
959
{
 
960
    sp_node_path_value_changed(adj, tbl, "y");
403
961
}
404
962
 
405
963
//################################
406
964
//##    Node Editing Toolbox    ##
407
965
//################################
408
966
 
409
 
static GtkWidget *
410
 
sp_node_toolbox_new(SPDesktop *desktop)
 
967
static void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
411
968
{
412
 
    Inkscape::UI::View::View *view = desktop;
413
 
 
414
 
    GtkTooltips *tt = gtk_tooltips_new();
415
 
    GtkWidget *tb = gtk_hbox_new(FALSE, 0);
416
 
 
417
 
    gtk_box_pack_start(GTK_BOX(tb), gtk_hbox_new(FALSE, 0), FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
418
 
 
419
 
    sp_toolbox_button_new(tb, Inkscape::ICON_SIZE_SMALL_TOOLBAR, "node_insert",
420
 
        GTK_SIGNAL_FUNC(sp_node_path_edit_add), tt, _("Insert new nodes into selected segments"));
421
 
    sp_toolbox_button_new(tb, Inkscape::ICON_SIZE_SMALL_TOOLBAR, "node_delete",
422
 
        GTK_SIGNAL_FUNC(sp_node_path_edit_delete), tt, _("Delete selected nodes"));
423
 
 
424
 
    gtk_box_pack_start(GTK_BOX(tb), gtk_hbox_new(FALSE, 0), FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
425
 
 
426
 
    sp_toolbox_button_new(tb, Inkscape::ICON_SIZE_SMALL_TOOLBAR, "node_join",
427
 
        GTK_SIGNAL_FUNC(sp_node_path_edit_join), tt, _("Join selected endnodes"));
428
 
    sp_toolbox_button_new(tb, Inkscape::ICON_SIZE_SMALL_TOOLBAR, "node_join_segment",
429
 
        GTK_SIGNAL_FUNC(sp_node_path_edit_join_segment), tt, _("Join selected endnodes with a new segment"));
430
 
 
431
 
    sp_toolbox_button_new(tb, Inkscape::ICON_SIZE_SMALL_TOOLBAR, "node_delete_segment",
432
 
        GTK_SIGNAL_FUNC(sp_node_path_edit_delete_segment), tt, _("Split path between two non-endpoint nodes"));
433
 
 
434
 
    sp_toolbox_button_new(tb, Inkscape::ICON_SIZE_SMALL_TOOLBAR, "node_break",
435
 
        GTK_SIGNAL_FUNC(sp_node_path_edit_break), tt, _("Break path at selected nodes"));
436
 
 
437
 
    gtk_box_pack_start(GTK_BOX(tb), gtk_hbox_new(FALSE, 0), FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
438
 
 
439
 
    sp_toolbox_button_new(tb, Inkscape::ICON_SIZE_SMALL_TOOLBAR, "node_cusp",
440
 
        GTK_SIGNAL_FUNC(sp_node_path_edit_cusp), tt, _("Make selected nodes corner"));
441
 
 
442
 
    sp_toolbox_button_new(tb, Inkscape::ICON_SIZE_SMALL_TOOLBAR, "node_smooth",
443
 
        GTK_SIGNAL_FUNC(sp_node_path_edit_smooth), tt, _("Make selected nodes smooth"));
444
 
 
445
 
    sp_toolbox_button_new(tb, Inkscape::ICON_SIZE_SMALL_TOOLBAR, "node_symmetric",
446
 
        GTK_SIGNAL_FUNC(sp_node_path_edit_symmetrical), tt, _("Make selected nodes symmetric"));
447
 
 
448
 
    gtk_box_pack_start(GTK_BOX(tb), gtk_hbox_new(FALSE, 0), FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
449
 
 
450
 
    sp_toolbox_button_new(tb, Inkscape::ICON_SIZE_SMALL_TOOLBAR, "node_line",
451
 
        GTK_SIGNAL_FUNC(sp_node_path_edit_toline), tt, _("Make selected segments lines"));
452
 
 
453
 
    sp_toolbox_button_new(tb, Inkscape::ICON_SIZE_SMALL_TOOLBAR, "node_curve",
454
 
        GTK_SIGNAL_FUNC(sp_node_path_edit_tocurve), tt, _("Make selected segments curves"));
455
 
 
456
 
    gtk_box_pack_start(GTK_BOX(tb), gtk_hbox_new(FALSE, 0), FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
457
 
 
458
 
    sp_toolbox_button_normal_new_from_verb(tb, Inkscape::ICON_SIZE_SMALL_TOOLBAR, Inkscape::Verb::get(SP_VERB_OBJECT_TO_CURVE), view, tt);
459
 
 
460
 
    sp_toolbox_button_normal_new_from_verb(tb, Inkscape::ICON_SIZE_SMALL_TOOLBAR, Inkscape::Verb::get(SP_VERB_SELECTION_OUTLINE), view, tt);
461
 
 
462
 
    aux_toolbox_space(tb, AUX_BETWEEN_BUTTON_GROUPS);
463
 
 
464
 
    GtkWidget *cvbox = gtk_vbox_new (FALSE, 0);
465
 
    GtkWidget *cbox = gtk_hbox_new (FALSE, 0);
466
 
 
467
 
    {
468
 
    GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
469
 
                                              SP_BUTTON_TYPE_TOGGLE,
470
 
                                              NULL,
471
 
                                              "nodes_show_handles",
472
 
                                              _("Show the Bezier handles of selected nodes"),
473
 
                                              tt);
474
 
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), prefs_get_int_attribute ("tools.nodes", "show_handles", 1));
475
 
    g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (toggle_show_handles), desktop);
476
 
    gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
477
 
    }
478
 
 
479
 
    gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, FALSE, 0);
480
 
    gtk_box_pack_start(GTK_BOX(tb), cvbox, FALSE, FALSE, 0);
481
 
 
482
 
    gtk_widget_show_all(tb);
483
 
 
484
 
    return tb;
485
 
 
486
 
} // end of sp_node_toolbox_new()
 
969
    UnitTracker* tracker = new UnitTracker( SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE );
 
970
    tracker->setActiveUnit( sp_desktop_namedview(desktop)->doc_units );
 
971
    g_object_set_data( holder, "tracker", tracker );
 
972
 
 
973
    {
 
974
        InkAction* inky = ink_action_new( "NodeInsertAction",
 
975
                                          _("Insert node"),
 
976
                                          _("Insert new nodes into selected segments"),
 
977
                                          "node_insert",
 
978
                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
 
979
        g_object_set( inky, "short_label", _("Insert"), NULL );
 
980
        g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_add), 0 );
 
981
        gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
 
982
    }
 
983
 
 
984
    {
 
985
        InkAction* inky = ink_action_new( "NodeDeleteAction",
 
986
                                          _("Delete node"),
 
987
                                          _("Delete selected nodes"),
 
988
                                          "node_delete",
 
989
                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
 
990
        g_object_set( inky, "short_label", _("Delete"), NULL );
 
991
        g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_delete), 0 );
 
992
        gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
 
993
    }
 
994
 
 
995
    {
 
996
        InkAction* inky = ink_action_new( "NodeJoinAction",
 
997
                                          _("Join endnodes"),
 
998
                                          _("Join selected endnodes"),
 
999
                                          "node_join",
 
1000
                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
 
1001
        g_object_set( inky, "short_label", _("Join"), NULL );
 
1002
        g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_join), 0 );
 
1003
        gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
 
1004
    }
 
1005
 
 
1006
    {
 
1007
        InkAction* inky = ink_action_new( "NodeJoinSegmentAction",
 
1008
                                          _("Join Segment"),
 
1009
                                          _("Join selected endnodes with a new segment"),
 
1010
                                          "node_join_segment",
 
1011
                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
 
1012
        g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_join_segment), 0 );
 
1013
        gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
 
1014
    }
 
1015
 
 
1016
    {
 
1017
        InkAction* inky = ink_action_new( "NodeDeleteSegmentAction",
 
1018
                                          _("Delete Segment"),
 
1019
                                          _("Split path between two non-endpoint nodes"),
 
1020
                                          "node_delete_segment",
 
1021
                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
 
1022
        g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_delete_segment), 0 );
 
1023
        gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
 
1024
    }
 
1025
 
 
1026
    {
 
1027
        InkAction* inky = ink_action_new( "NodeBreakAction",
 
1028
                                          _("Node Break"),
 
1029
                                          _("Break path at selected nodes"),
 
1030
                                          "node_break",
 
1031
                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
 
1032
        g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_break), 0 );
 
1033
        gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
 
1034
    }
 
1035
 
 
1036
    {
 
1037
        InkAction* inky = ink_action_new( "NodeCuspAction",
 
1038
                                          _("Node Cusp"),
 
1039
                                          _("Make selected nodes corner"),
 
1040
                                          "node_cusp",
 
1041
                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
 
1042
        g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_cusp), 0 );
 
1043
        gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
 
1044
    }
 
1045
 
 
1046
    {
 
1047
        InkAction* inky = ink_action_new( "NodeSmoothAction",
 
1048
                                          _("Node Smooth"),
 
1049
                                          _("Make selected nodes smooth"),
 
1050
                                          "node_smooth",
 
1051
                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
 
1052
        g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_smooth), 0 );
 
1053
        gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
 
1054
    }
 
1055
 
 
1056
    {
 
1057
        InkAction* inky = ink_action_new( "NodeSymmetricAction",
 
1058
                                          _("Node Symmetric"),
 
1059
                                          _("Make selected nodes symmetric"),
 
1060
                                          "node_symmetric",
 
1061
                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
 
1062
        g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_symmetrical), 0 );
 
1063
        gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
 
1064
    }
 
1065
 
 
1066
    {
 
1067
        InkAction* inky = ink_action_new( "NodeLineAction",
 
1068
                                          _("Node Line"),
 
1069
                                          _("Make selected segments lines"),
 
1070
                                          "node_line",
 
1071
                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
 
1072
        g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_toline), 0 );
 
1073
        gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
 
1074
    }
 
1075
 
 
1076
    {
 
1077
        InkAction* inky = ink_action_new( "NodeCurveAction",
 
1078
                                          _("Node Curve"),
 
1079
                                          _("Make selected segments curves"),
 
1080
                                          "node_curve",
 
1081
                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
 
1082
        g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_tocurve), 0 );
 
1083
        gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
 
1084
    }
 
1085
 
 
1086
    {
 
1087
        InkToggleAction* act = ink_toggle_action_new( "NodesShowHandlesAction",
 
1088
                                                      _("Show Handles"),
 
1089
                                                      _("Show the Bezier handles of selected nodes"),
 
1090
                                                      "nodes_show_handles",
 
1091
                                                      Inkscape::ICON_SIZE_DECORATION );
 
1092
        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
 
1093
        g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_show_handles), desktop );
 
1094
        gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.nodes", "show_handles", 1 ) );
 
1095
    }
 
1096
 
 
1097
    {
 
1098
        InkAction* inky = ink_action_new( "EditNextLPEParameterAction",
 
1099
                                          _("Next Path Effect Parameter"),
 
1100
                                          _("Show next Path Effect parameter for editing"),
 
1101
                                          "edit_next_parameter",
 
1102
                                          Inkscape::ICON_SIZE_DECORATION );
 
1103
        g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_nextLPEparam), desktop );
 
1104
        gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
 
1105
    }
 
1106
 
 
1107
    /* X coord of selected node(s) */
 
1108
    {
 
1109
        EgeAdjustmentAction* eact = 0;
 
1110
        gchar const* labels[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 
1111
        gdouble values[] = {1, 2, 3, 5, 10, 20, 50, 100, 200, 500};
 
1112
        eact = create_adjustment_action( "NodeXAction",
 
1113
                                         _("X coordinate:"), _("X:"), _("X coordinate of selected node(s)"),
 
1114
                                         "tools.nodes", "Xcoord", 0,
 
1115
                                         GTK_WIDGET(desktop->canvas), NULL/*us*/, holder, TRUE, "altx-nodes",
 
1116
                                         -1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP,
 
1117
                                         labels, values, G_N_ELEMENTS(labels),
 
1118
                                         sp_node_path_x_value_changed );
 
1119
        tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) );
 
1120
        g_object_set_data( holder, "nodes_x_action", eact );
 
1121
        gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
 
1122
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
 
1123
    }
 
1124
 
 
1125
    /* Y coord of selected node(s) */
 
1126
    {
 
1127
        EgeAdjustmentAction* eact = 0;
 
1128
        gchar const* labels[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 
1129
        gdouble values[] = {1, 2, 3, 5, 10, 20, 50, 100, 200, 500};
 
1130
        eact = create_adjustment_action( "NodeYAction",
 
1131
                                         _("Y coordinate:"), _("Y:"), _("Y coordinate of selected node(s)"),
 
1132
                                         "tools.nodes", "Ycoord", 0,
 
1133
                                         GTK_WIDGET(desktop->canvas), NULL/*us*/, holder, FALSE, NULL,
 
1134
                                         -1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP,
 
1135
                                         labels, values, G_N_ELEMENTS(labels),
 
1136
                                         sp_node_path_y_value_changed );
 
1137
        tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) );
 
1138
        g_object_set_data( holder, "nodes_y_action", eact );
 
1139
        gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
 
1140
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
 
1141
    }
 
1142
 
 
1143
    // add the units menu
 
1144
    {
 
1145
        GtkAction* act = tracker->createAction( "NodeUnitsAction", _("Units"), ("") );
 
1146
        gtk_action_group_add_action( mainActions, act );
 
1147
    }
 
1148
 
 
1149
    sigc::connection *connection = new sigc::connection (
 
1150
        desktop->connectToolSubselectionChanged(sigc::bind (sigc::ptr_fun(sp_node_toolbox_coord_changed), (GObject *)holder))
 
1151
        );
 
1152
 
 
1153
    g_signal_connect( holder, "destroy", G_CALLBACK(delete_connection), connection );
 
1154
    g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder );
 
1155
} // end of sp_node_toolbox_prep()
487
1156
 
488
1157
 
489
1158
//########################
490
1159
//##    Zoom Toolbox    ##
491
1160
//########################
492
1161
 
493
 
static GtkWidget *
494
 
sp_zoom_toolbox_new(SPDesktop *desktop)
 
1162
static void sp_zoom_toolbox_prep(SPDesktop */*desktop*/, GtkActionGroup* /*mainActions*/, GObject* /*holder*/)
495
1163
{
496
 
    Inkscape::UI::View::View *view=desktop;
497
 
 
498
 
    GtkTooltips *tt = gtk_tooltips_new();
499
 
    GtkWidget *tb = gtk_hbox_new(FALSE, 0);
500
 
 
501
 
    gtk_box_pack_start(GTK_BOX(tb), gtk_hbox_new(FALSE, 0),
502
 
                       FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
503
 
 
504
 
    sp_toolbox_button_new_from_verb(tb, Inkscape::ICON_SIZE_SMALL_TOOLBAR, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_ZOOM_IN), view, tt);
505
 
 
506
 
    sp_toolbox_button_new_from_verb(tb, Inkscape::ICON_SIZE_SMALL_TOOLBAR, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_ZOOM_OUT), view, tt);
507
 
 
508
 
    gtk_box_pack_start(GTK_BOX(tb), gtk_hbox_new(FALSE, 0), FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
509
 
 
510
 
    sp_toolbox_button_new_from_verb(tb, Inkscape::ICON_SIZE_SMALL_TOOLBAR, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_ZOOM_SELECTION), view, tt);
511
 
 
512
 
    sp_toolbox_button_new_from_verb(tb, Inkscape::ICON_SIZE_SMALL_TOOLBAR, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_ZOOM_DRAWING), view, tt);
513
 
 
514
 
    sp_toolbox_button_new_from_verb(tb, Inkscape::ICON_SIZE_SMALL_TOOLBAR, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_ZOOM_PAGE), view, tt);
515
 
 
516
 
    sp_toolbox_button_new_from_verb(tb, Inkscape::ICON_SIZE_SMALL_TOOLBAR, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_ZOOM_PAGE_WIDTH), view, tt);
517
 
 
518
 
    gtk_box_pack_start(GTK_BOX(tb), gtk_hbox_new(FALSE, 0), FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
519
 
 
520
 
    sp_toolbox_button_new_from_verb(tb, Inkscape::ICON_SIZE_SMALL_TOOLBAR, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_ZOOM_PREV), view, tt);
521
 
 
522
 
    sp_toolbox_button_new_from_verb(tb, Inkscape::ICON_SIZE_SMALL_TOOLBAR, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_ZOOM_NEXT), view, tt);
523
 
 
524
 
    gtk_box_pack_start(GTK_BOX(tb), gtk_hbox_new(FALSE, 0), FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
525
 
 
526
 
    sp_toolbox_button_new_from_verb(tb, Inkscape::ICON_SIZE_SMALL_TOOLBAR, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_ZOOM_1_1), view, tt);
527
 
 
528
 
    sp_toolbox_button_new_from_verb(tb, Inkscape::ICON_SIZE_SMALL_TOOLBAR, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_ZOOM_1_2), view, tt);
529
 
 
530
 
    sp_toolbox_button_new_from_verb(tb, Inkscape::ICON_SIZE_SMALL_TOOLBAR, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_ZOOM_2_1), view, tt);
531
 
 
532
 
    gtk_widget_show_all(tb);
533
 
 
534
 
    return tb;
535
 
 
536
 
} // end of sp_zoom_toolbox_new()
 
1164
    // no custom GtkAction setup needed
 
1165
} // end of sp_zoom_toolbox_prep()
537
1166
 
538
1167
void
539
1168
sp_tool_toolbox_set_desktop(GtkWidget *toolbox, SPDesktop *desktop)
576
1205
        gtk_widget_set_sensitive(toolbox, TRUE);
577
1206
        setup_func(toolbox, desktop);
578
1207
        update_func(desktop, desktop->event_context, toolbox);
579
 
        *conn = desktop->connectEventContextChanged 
 
1208
        *conn = desktop->connectEventContextChanged
580
1209
            (sigc::bind (sigc::ptr_fun(update_func), toolbox));
581
1210
    } else {
582
1211
        gtk_widget_set_sensitive(toolbox, FALSE);
589
1218
setup_tool_toolbox(GtkWidget *toolbox, SPDesktop *desktop)
590
1219
{
591
1220
    GtkTooltips *tooltips=GTK_TOOLTIPS(g_object_get_data(G_OBJECT(toolbox), "tooltips"));
592
 
    gint shrinkLeft = prefs_get_int_attribute_limited( "toolbox.left", "small", 0, 0, 1 );
 
1221
    gint shrinkLeft = prefs_get_int_attribute_limited( "toolbox.tools", "small", 0, 0, 1 );
 
1222
    if ( (shrinkLeft == 0) && (prefs_get_int_attribute_limited( "toolbox.tools", "small", 1, 0, 1 ) == 1) ) {
 
1223
        // "toolbox.tools" was not set. Fallback to older value
 
1224
        shrinkLeft = prefs_get_int_attribute_limited( "toolbox.left", "small", 0, 0, 1 );
 
1225
 
 
1226
        // Copy the setting forwards
 
1227
        prefs_set_int_attribute( "toolbox.tools", "small", shrinkLeft );
 
1228
    }
593
1229
    Inkscape::IconSize toolboxSize = shrinkLeft ? Inkscape::ICON_SIZE_SMALL_TOOLBAR : Inkscape::ICON_SIZE_LARGE_TOOLBAR;
594
1230
 
595
1231
    for (int i = 0 ; tools[i].type_name ; i++ ) {
608
1244
 
609
1245
 
610
1246
static void
611
 
update_tool_toolbox( SPDesktop *desktop, SPEventContext *eventcontext, GtkWidget *toolbox )
 
1247
update_tool_toolbox( SPDesktop */*desktop*/, SPEventContext *eventcontext, GtkWidget *toolbox )
612
1248
{
613
1249
    gchar const *const tname = ( eventcontext
614
1250
                                 ? gtk_type_name(GTK_OBJECT_TYPE(eventcontext))
623
1259
setup_aux_toolbox(GtkWidget *toolbox, SPDesktop *desktop)
624
1260
{
625
1261
    GtkSizeGroup* grouper = gtk_size_group_new( GTK_SIZE_GROUP_BOTH );
626
 
 
627
 
    for (int i = 0 ; aux_toolboxes[i].type_name ; i++ ) {
628
 
        GtkWidget *sub_toolbox;
629
 
        if (aux_toolboxes[i].create_func == NULL)
630
 
            sub_toolbox = sp_empty_toolbox_new(desktop);
631
 
        else
632
 
            sub_toolbox = aux_toolboxes[i].create_func(desktop);
633
 
 
634
 
        gtk_size_group_add_widget( grouper, sub_toolbox );
635
 
 
636
 
        gtk_container_add(GTK_CONTAINER(toolbox), sub_toolbox);
637
 
        g_object_set_data(G_OBJECT(toolbox), aux_toolboxes[i].data_name, sub_toolbox);
638
 
    }
 
1262
    GtkActionGroup* mainActions = create_or_fetch_actions( desktop );
 
1263
    GtkUIManager* mgr = gtk_ui_manager_new();
 
1264
    GError* errVal = 0;
 
1265
    gtk_ui_manager_insert_action_group( mgr, mainActions, 0 );
 
1266
    gtk_ui_manager_add_ui_from_string( mgr, ui_descr, -1, &errVal );
 
1267
 
 
1268
    std::map<std::string, GtkWidget*> dataHolders;
 
1269
 
 
1270
    for (int i = 0 ; aux_toolboxes[i].type_name ; i++ ) {
 
1271
        if ( aux_toolboxes[i].prep_func ) {
 
1272
            // converted to GtkActions and UIManager
 
1273
 
 
1274
            GtkWidget* kludge = gtk_hbox_new( FALSE, 0 );
 
1275
            g_object_set_data( G_OBJECT(kludge), "dtw", desktop->canvas);
 
1276
            g_object_set_data( G_OBJECT(kludge), "desktop", desktop);
 
1277
            dataHolders[aux_toolboxes[i].type_name] = kludge;
 
1278
            aux_toolboxes[i].prep_func( desktop, mainActions, G_OBJECT(kludge) );
 
1279
        } else {
 
1280
 
 
1281
            GtkWidget *sub_toolbox = 0;
 
1282
            if (aux_toolboxes[i].create_func == NULL)
 
1283
                sub_toolbox = sp_empty_toolbox_new(desktop);
 
1284
            else {
 
1285
                sub_toolbox = aux_toolboxes[i].create_func(desktop);
 
1286
            }
 
1287
 
 
1288
            gtk_size_group_add_widget( grouper, sub_toolbox );
 
1289
 
 
1290
            gtk_container_add(GTK_CONTAINER(toolbox), sub_toolbox);
 
1291
            g_object_set_data(G_OBJECT(toolbox), aux_toolboxes[i].data_name, sub_toolbox);
 
1292
 
 
1293
        }
 
1294
    }
 
1295
 
 
1296
    // Second pass to create toolbars *after* all GtkActions are created
 
1297
    for (int i = 0 ; aux_toolboxes[i].type_name ; i++ ) {
 
1298
        if ( aux_toolboxes[i].prep_func ) {
 
1299
            // converted to GtkActions and UIManager
 
1300
 
 
1301
            GtkWidget* kludge = dataHolders[aux_toolboxes[i].type_name];
 
1302
 
 
1303
            GtkWidget* holder = gtk_table_new( 1, 3, FALSE );
 
1304
            gtk_table_attach( GTK_TABLE(holder), kludge, 2, 3, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0 );
 
1305
 
 
1306
            gchar* tmp = g_strdup_printf( "/ui/%s", aux_toolboxes[i].ui_name );
 
1307
            GtkWidget* toolBar = gtk_ui_manager_get_widget( mgr, tmp );
 
1308
            g_free( tmp );
 
1309
            tmp = 0;
 
1310
 
 
1311
            gint shrinkTop = prefs_get_int_attribute_limited( "toolbox", "small", 1, 0, 1 );
 
1312
            Inkscape::IconSize toolboxSize = shrinkTop ? Inkscape::ICON_SIZE_SMALL_TOOLBAR : Inkscape::ICON_SIZE_LARGE_TOOLBAR;
 
1313
            if ( prefs_get_int_attribute_limited( "toolbox", "icononly", 1, 0, 1 ) ) {
 
1314
                gtk_toolbar_set_style( GTK_TOOLBAR(toolBar), GTK_TOOLBAR_ICONS );
 
1315
            }
 
1316
            gtk_toolbar_set_icon_size( GTK_TOOLBAR(toolBar), static_cast<GtkIconSize>(toolboxSize) );
 
1317
 
 
1318
 
 
1319
            gtk_table_attach( GTK_TABLE(holder), toolBar, 0, 1, 0, 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 0, 0 );
 
1320
 
 
1321
            if ( aux_toolboxes[i].swatch_verb_id != SP_VERB_INVALID ) {
 
1322
                Inkscape::UI::Widget::StyleSwatch *swatch = new Inkscape::UI::Widget::StyleSwatch( NULL, aux_toolboxes[i].swatch_tip );
 
1323
                swatch->setDesktop( desktop );
 
1324
                swatch->setClickVerb( aux_toolboxes[i].swatch_verb_id );
 
1325
                swatch->setWatchedTool( aux_toolboxes[i].swatch_tool, true );
 
1326
                GtkWidget *swatch_ = GTK_WIDGET( swatch->gobj() );
 
1327
                gtk_table_attach( GTK_TABLE(holder), swatch_, 1, 2, 0, 1, (GtkAttachOptions)(GTK_SHRINK | GTK_FILL), (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), AUX_BETWEEN_BUTTON_GROUPS, 0 );
 
1328
            }
 
1329
 
 
1330
            gtk_widget_show_all( holder );
 
1331
            sp_set_font_size_smaller( holder );
 
1332
 
 
1333
            gtk_size_group_add_widget( grouper, holder );
 
1334
 
 
1335
            gtk_container_add( GTK_CONTAINER(toolbox), holder );
 
1336
            g_object_set_data( G_OBJECT(toolbox), aux_toolboxes[i].data_name, holder );
 
1337
        }
 
1338
    }
 
1339
 
639
1340
    g_object_unref( G_OBJECT(grouper) );
640
1341
}
641
1342
 
642
1343
static void
643
 
update_aux_toolbox(SPDesktop *desktop, SPEventContext *eventcontext, GtkWidget *toolbox)
 
1344
update_aux_toolbox(SPDesktop */*desktop*/, SPEventContext *eventcontext, GtkWidget *toolbox)
644
1345
{
645
1346
    gchar const *tname = ( eventcontext
646
1347
                           ? gtk_type_name(GTK_OBJECT_TYPE(eventcontext))
659
1360
static void
660
1361
setup_commands_toolbox(GtkWidget *toolbox, SPDesktop *desktop)
661
1362
{
662
 
    Inkscape::UI::View::View *view = desktop;
663
 
 
664
 
    GtkTooltips *tt = gtk_tooltips_new();
665
 
    GtkWidget *tb = gtk_hbox_new(FALSE, 0);
666
 
 
 
1363
    gchar const * descr =
 
1364
        "<ui>"
 
1365
        "  <toolbar name='CommandsToolbar'>"
 
1366
        "    <toolitem action='FileNew' />"
 
1367
        "    <toolitem action='FileOpen' />"
 
1368
        "    <toolitem action='FileSave' />"
 
1369
        "    <toolitem action='FilePrint' />"
 
1370
        "    <separator />"
 
1371
        "    <toolitem action='FileImport' />"
 
1372
        "    <toolitem action='FileExport' />"
 
1373
        "    <separator />"
 
1374
        "    <toolitem action='EditUndo' />"
 
1375
        "    <toolitem action='EditRedo' />"
 
1376
        "    <separator />"
 
1377
        "    <toolitem action='EditCopy' />"
 
1378
        "    <toolitem action='EditCut' />"
 
1379
        "    <toolitem action='EditPaste' />"
 
1380
        "    <separator />"
 
1381
        "    <toolitem action='ZoomSelection' />"
 
1382
        "    <toolitem action='ZoomDrawing' />"
 
1383
        "    <toolitem action='ZoomPage' />"
 
1384
        "    <separator />"
 
1385
        "    <toolitem action='EditDuplicate' />"
 
1386
        "    <toolitem action='EditClone' />"
 
1387
        "    <toolitem action='EditUnlinkClone' />"
 
1388
        "    <separator />"
 
1389
        "    <toolitem action='SelectionGroup' />"
 
1390
        "    <toolitem action='SelectionUnGroup' />"
 
1391
        "    <separator />"
 
1392
        "    <toolitem action='DialogFillStroke' />"
 
1393
        "    <toolitem action='DialogText' />"
 
1394
        "    <toolitem action='DialogXMLEditor' />"
 
1395
        "    <toolitem action='DialogAlignDistribute' />"
 
1396
        "    <separator />"
 
1397
        "    <toolitem action='DialogPreferences' />"
 
1398
        "    <toolitem action='DialogDocumentProperties' />"
 
1399
        "  </toolbar>"
 
1400
        "</ui>";
 
1401
    GtkActionGroup* mainActions = create_or_fetch_actions( desktop );
 
1402
 
 
1403
 
 
1404
    GtkUIManager* mgr = gtk_ui_manager_new();
 
1405
    GError* errVal = 0;
 
1406
 
 
1407
    gtk_ui_manager_insert_action_group( mgr, mainActions, 0 );
 
1408
    gtk_ui_manager_add_ui_from_string( mgr, descr, -1, &errVal );
 
1409
 
 
1410
    GtkWidget* toolBar = gtk_ui_manager_get_widget( mgr, "/ui/CommandsToolbar" );
 
1411
    if ( prefs_get_int_attribute_limited( "toolbox", "icononly", 1, 0, 1 ) ) {
 
1412
        gtk_toolbar_set_style( GTK_TOOLBAR(toolBar), GTK_TOOLBAR_ICONS );
 
1413
    }
667
1414
    gint shrinkTop = prefs_get_int_attribute_limited( "toolbox", "small", 1, 0, 1 );
668
1415
    Inkscape::IconSize toolboxSize = shrinkTop ? Inkscape::ICON_SIZE_SMALL_TOOLBAR : Inkscape::ICON_SIZE_LARGE_TOOLBAR;
669
 
 
670
 
    sp_toolbox_button_new_from_verb(tb, toolboxSize, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_FILE_NEW), view, tt);
671
 
    sp_toolbox_button_new_from_verb(tb, toolboxSize, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_FILE_OPEN), view, tt);
672
 
    sp_toolbox_button_new_from_verb(tb, toolboxSize, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_FILE_SAVE), view, tt);
673
 
    sp_toolbox_button_new_from_verb(tb, toolboxSize, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_FILE_PRINT), view, tt);
674
 
 
675
 
    aux_toolbox_space(tb, AUX_BETWEEN_BUTTON_GROUPS);
676
 
 
677
 
    sp_toolbox_button_new_from_verb(tb, toolboxSize, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_FILE_IMPORT), view, tt);
678
 
    sp_toolbox_button_new_from_verb(tb, toolboxSize, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_FILE_EXPORT), view, tt);
679
 
 
680
 
    aux_toolbox_space(tb, AUX_BETWEEN_BUTTON_GROUPS);
681
 
 
682
 
    sp_toolbox_button_new_from_verb(tb, toolboxSize, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_EDIT_UNDO), view, tt);
683
 
    sp_toolbox_button_new_from_verb(tb, toolboxSize, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_EDIT_REDO), view, tt);
684
 
 
685
 
    aux_toolbox_space(tb, AUX_BETWEEN_BUTTON_GROUPS);
686
 
 
687
 
    sp_toolbox_button_new_from_verb(tb, toolboxSize, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_EDIT_COPY), view, tt);
688
 
    sp_toolbox_button_new_from_verb(tb, toolboxSize, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_EDIT_CUT), view, tt);
689
 
    sp_toolbox_button_new_from_verb(tb, toolboxSize, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_EDIT_PASTE), view, tt);
690
 
 
691
 
    aux_toolbox_space(tb, AUX_BETWEEN_BUTTON_GROUPS);
692
 
 
693
 
    sp_toolbox_button_new_from_verb(tb, toolboxSize, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_ZOOM_SELECTION), view, tt);
694
 
    sp_toolbox_button_new_from_verb(tb, toolboxSize, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_ZOOM_DRAWING), view, tt);
695
 
    sp_toolbox_button_new_from_verb(tb, toolboxSize, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_ZOOM_PAGE), view, tt);
696
 
 
697
 
    aux_toolbox_space(tb, AUX_BETWEEN_BUTTON_GROUPS);
698
 
 
699
 
    sp_toolbox_button_new_from_verb(tb, toolboxSize, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_EDIT_DUPLICATE), view, tt);
700
 
    sp_toolbox_button_new_from_verb(tb, toolboxSize, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_EDIT_CLONE), view, tt);
701
 
    sp_toolbox_button_new_from_verb(tb, toolboxSize, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_EDIT_UNLINK_CLONE), view, tt);
702
 
 
703
 
    aux_toolbox_space(tb, AUX_BETWEEN_BUTTON_GROUPS);
704
 
 
705
 
    sp_toolbox_button_normal_new_from_verb(tb, toolboxSize, Inkscape::Verb::get(SP_VERB_SELECTION_GROUP), view, tt);
706
 
    sp_toolbox_button_normal_new_from_verb(tb, toolboxSize, Inkscape::Verb::get(SP_VERB_SELECTION_UNGROUP), view, tt);
707
 
 
708
 
    // disabled until we have icons for them:
709
 
 
710
 
    //find
711
 
 
712
 
    //sp_toolbox_button_new_from_verb(tb, toolboxSize, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_EDIT_TILE), view, tt);
713
 
    //sp_toolbox_button_new_from_verb(tb, toolboxSize, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_EDIT_UNTILE), view, tt);
714
 
 
715
 
    aux_toolbox_space(tb, AUX_BETWEEN_BUTTON_GROUPS);
716
 
 
717
 
    sp_toolbox_button_new_from_verb(tb, toolboxSize, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_DIALOG_FILL_STROKE), view, tt);
718
 
    sp_toolbox_button_new_from_verb(tb, toolboxSize, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_DIALOG_TEXT), view, tt);
719
 
    sp_toolbox_button_new_from_verb(tb, toolboxSize, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_DIALOG_XML_EDITOR), view, tt);
720
 
    sp_toolbox_button_new_from_verb(tb, toolboxSize, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_DIALOG_ALIGN_DISTRIBUTE), view, tt);
721
 
 
722
 
    aux_toolbox_space(tb, AUX_BETWEEN_BUTTON_GROUPS);
723
 
 
724
 
    sp_toolbox_button_new_from_verb(tb, toolboxSize, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_DIALOG_DISPLAY), view, tt);
725
 
    sp_toolbox_button_new_from_verb(tb, toolboxSize, SP_BUTTON_TYPE_NORMAL, Inkscape::Verb::get(SP_VERB_DIALOG_NAMEDVIEW), view, tt);
726
 
 
727
 
    gtk_widget_show_all(tb);
728
 
 
729
 
    gtk_container_add(GTK_CONTAINER(toolbox), tb);
 
1416
    gtk_toolbar_set_icon_size( GTK_TOOLBAR(toolBar), (GtkIconSize)toolboxSize );
 
1417
 
 
1418
 
 
1419
    gtk_container_add( GTK_CONTAINER(toolbox), toolBar );
730
1420
}
731
1421
 
732
1422
static void
733
 
update_commands_toolbox(SPDesktop *desktop, SPEventContext *eventcontext, GtkWidget *toolbox)
 
1423
update_commands_toolbox(SPDesktop */*desktop*/, SPEventContext */*eventcontext*/, GtkWidget */*toolbox*/)
734
1424
{
735
1425
}
736
1426
 
745
1435
    }
746
1436
    gtk_widget_show(toolbox);
747
1437
 
748
 
    // need to show the spacer, or the padding will be off
749
 
    GtkWidget *spacer = GTK_WIDGET(g_object_get_data(G_OBJECT(toolbox), "top_spacer"));
750
 
    gtk_widget_show(spacer);
751
 
 
752
1438
    gtk_widget_show_all(shown_toolbox);
753
1439
}
754
1440
 
803
1489
    gtk_tooltips_set_tip(tt, sb, tooltip, NULL);
804
1490
    if (altx)
805
1491
        gtk_object_set_data(GTK_OBJECT(sb), altx_mark, sb);
806
 
    gtk_widget_set_size_request(sb, 
 
1492
    gtk_widget_set_size_request(sb,
807
1493
                                (upper <= 1.0 || digits == 0)? AUX_SPINBUTTON_WIDTH_SMALL - 10: AUX_SPINBUTTON_WIDTH_SMALL,
808
1494
                                AUX_SPINBUTTON_HEIGHT);
809
1495
    gtk_widget_show(sb);
815
1501
    return hb;
816
1502
}
817
1503
 
818
 
static EgeAdjustmentAction * create_adjustment_action( gchar const *name,
819
 
                                                       gchar const *label, gchar const *tooltip,
820
 
                                                       gchar const *path, gchar const *data, gdouble def,
821
 
                                                       GtkWidget *focusTarget,
822
 
                                                       GtkWidget *us,
823
 
                                                       GtkWidget *dataKludge,
824
 
                                                       gboolean altx, gchar const *altx_mark,
825
 
                                                       gdouble lower, gdouble upper, gdouble step, gdouble page,
826
 
                                                       void (*callback)(GtkAdjustment *, GtkWidget *),
827
 
                                                       gdouble climb = 0.1, guint digits = 3, double factor = 1.0 )
828
 
{
829
 
    GtkAdjustment* adj = GTK_ADJUSTMENT( gtk_adjustment_new( prefs_get_double_attribute(path, data, def) * factor,
830
 
                                                             lower, upper, step, page, page ) );
831
 
    if (us) {
832
 
        sp_unit_selector_add_adjustment( SP_UNIT_SELECTOR(us), adj );
833
 
    }
834
 
 
835
 
    gtk_signal_connect( GTK_OBJECT(adj), "value-changed", GTK_SIGNAL_FUNC(callback), dataKludge );
836
 
 
837
 
    EgeAdjustmentAction* act = ege_adjustment_action_new( adj, name, label, tooltip, 0, climb, digits );
838
 
 
839
 
    if ( focusTarget ) {
840
 
        ege_adjustment_action_set_focuswidget( act, focusTarget );
841
 
    }
842
 
 
843
 
    if ( altx && altx_mark ) {
844
 
        g_object_set( G_OBJECT(act), "self-id", altx_mark, NULL );
845
 
    }
846
 
 
847
 
    if ( dataKludge ) {
848
 
        gtk_object_set_data( GTK_OBJECT(dataKludge), data, adj );
849
 
    }
850
 
 
851
 
    // Using a cast just to make sure we pass in the right kind of function pointer
852
 
    g_object_set( G_OBJECT(act), "tool-post", static_cast<EgeWidgetFixup>(sp_set_font_size_smaller), NULL );
853
 
 
854
 
    return act;
855
 
}
856
 
 
857
 
 
858
1504
#define MODE_LABEL_WIDTH 70
859
1505
 
860
1506
//########################
861
1507
//##       Star         ##
862
1508
//########################
863
1509
 
864
 
static void
865
 
sp_stb_magnitude_value_changed(GtkAdjustment *adj, GtkWidget *tbl)
 
1510
static void sp_stb_magnitude_value_changed( GtkAdjustment *adj, GObject *dataKludge )
866
1511
{
867
 
    SPDesktop *desktop = (SPDesktop *) gtk_object_get_data(GTK_OBJECT(tbl), "desktop");
 
1512
    SPDesktop *desktop = (SPDesktop *) g_object_get_data( dataKludge, "desktop" );
868
1513
 
869
1514
    if (sp_document_get_undo_sensitive(sp_desktop_document(desktop))) {
870
1515
        // do not remember prefs if this call is initiated by an undo change, because undoing object
873
1518
    }
874
1519
 
875
1520
    // quit if run by the attr_changed listener
876
 
    if (g_object_get_data(G_OBJECT(tbl), "freeze")) {
 
1521
    if (g_object_get_data( dataKludge, "freeze" )) {
877
1522
        return;
878
1523
    }
879
1524
 
880
1525
    // in turn, prevent listener from responding
881
 
    g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE));
 
1526
    g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(TRUE) );
882
1527
 
883
1528
    bool modmade = false;
884
1529
 
895
1540
            modmade = true;
896
1541
        }
897
1542
    }
898
 
    if (modmade)  sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR, 
 
1543
    if (modmade)  sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR,
899
1544
                                   _("Star: Change number of corners"));
900
1545
 
901
 
    g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(FALSE));
902
 
 
903
 
    spinbutton_defocus(GTK_OBJECT(tbl));
 
1546
    g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(FALSE) );
904
1547
}
905
1548
 
906
 
static void
907
 
sp_stb_proportion_value_changed(GtkAdjustment *adj, GtkWidget *tbl)
 
1549
static void sp_stb_proportion_value_changed( GtkAdjustment *adj, GObject *dataKludge )
908
1550
{
909
 
    SPDesktop *desktop = (SPDesktop *) gtk_object_get_data(GTK_OBJECT(tbl), "desktop");
 
1551
    SPDesktop *desktop = (SPDesktop *) g_object_get_data( dataKludge, "desktop" );
910
1552
 
911
1553
    if (sp_document_get_undo_sensitive(sp_desktop_document(desktop))) {
912
1554
        prefs_set_double_attribute("tools.shapes.star", "proportion", adj->value);
913
1555
    }
914
1556
 
915
1557
    // quit if run by the attr_changed listener
916
 
    if (g_object_get_data(G_OBJECT(tbl), "freeze")) {
 
1558
    if (g_object_get_data( dataKludge, "freeze" )) {
917
1559
        return;
918
1560
    }
919
1561
 
920
1562
    // in turn, prevent listener from responding
921
 
    g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE));
 
1563
    g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(TRUE) );
922
1564
 
923
1565
    bool modmade = false;
924
1566
    Inkscape::Selection *selection = sp_desktop_selection(desktop);
940
1582
        }
941
1583
    }
942
1584
 
943
 
    if (modmade) sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR, 
 
1585
    if (modmade) sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR,
944
1586
                                   _("Star: Change spoke ratio"));
945
1587
 
946
 
    g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(FALSE));
947
 
 
948
 
    spinbutton_defocus(GTK_OBJECT(tbl));
 
1588
    g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(FALSE) );
949
1589
}
950
1590
 
951
 
static void
952
 
sp_stb_sides_flat_state_changed(GtkWidget *widget, GtkObject *tbl)
 
1591
static void sp_stb_sides_flat_state_changed( EgeSelectOneAction *act, GObject *dataKludge )
953
1592
{
954
 
    SPDesktop *desktop = (SPDesktop *) gtk_object_get_data(GTK_OBJECT(tbl), "desktop");
 
1593
    SPDesktop *desktop = (SPDesktop *) g_object_get_data( dataKludge, "desktop" );
 
1594
    bool flat = ege_select_one_action_get_active( act ) == 0;
955
1595
 
956
1596
    if (sp_document_get_undo_sensitive(sp_desktop_document(desktop))) {
957
 
        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
958
 
            prefs_set_string_attribute("tools.shapes.star", "isflatsided", "true");
959
 
        } else {
960
 
            prefs_set_string_attribute("tools.shapes.star", "isflatsided", "false");
961
 
        }
 
1597
        prefs_set_string_attribute( "tools.shapes.star", "isflatsided",
 
1598
                                    flat ? "true" : "false" );
962
1599
    }
963
1600
 
964
1601
    // quit if run by the attr_changed listener
965
 
    if (g_object_get_data(G_OBJECT(tbl), "freeze")) {
 
1602
    if (g_object_get_data( dataKludge, "freeze" )) {
966
1603
        return;
967
1604
    }
968
1605
 
969
1606
    // in turn, prevent listener from responding
970
 
    g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE));
 
1607
    g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(TRUE) );
971
1608
 
972
1609
    Inkscape::Selection *selection = sp_desktop_selection(desktop);
973
1610
    GSList const *items = selection->itemList();
974
 
    GtkWidget *prop_widget = (GtkWidget*) g_object_get_data(G_OBJECT(tbl), "prop_widget");
 
1611
    GtkAction* prop_action = GTK_ACTION( g_object_get_data( dataKludge, "prop_action" ) );
975
1612
    bool modmade = false;
976
 
    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
977
 
        gtk_widget_set_sensitive(GTK_WIDGET(prop_widget), FALSE);
978
 
        for (; items != NULL; items = items->next) {
979
 
            if (SP_IS_STAR((SPItem *) items->data)) {
980
 
                Inkscape::XML::Node *repr = SP_OBJECT_REPR((SPItem *) items->data);
981
 
                repr->setAttribute("inkscape:flatsided", "true");
982
 
                SP_OBJECT((SPItem *) items->data)->updateRepr(repr, SP_OBJECT_WRITE_EXT);
983
 
                modmade = true;
984
 
            }
985
 
        }
986
 
    } else {
987
 
        gtk_widget_set_sensitive(GTK_WIDGET(prop_widget), TRUE);
988
 
        for (; items != NULL; items = items->next) {
989
 
            if (SP_IS_STAR((SPItem *) items->data)) {
990
 
                Inkscape::XML::Node *repr = SP_OBJECT_REPR((SPItem *) items->data);
991
 
                repr->setAttribute("inkscape:flatsided", "false");
992
 
                SP_OBJECT(items->data)->updateRepr(repr, SP_OBJECT_WRITE_EXT);
993
 
                modmade = true;
994
 
            }
995
 
        }
996
 
    }
997
 
    if (modmade) sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR, 
998
 
                                  gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))? _("Make polygon") : _("Make star"));
999
 
 
1000
 
    g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(FALSE));
1001
 
 
1002
 
    spinbutton_defocus(GTK_OBJECT(tbl));
 
1613
 
 
1614
    if ( prop_action ) {
 
1615
        gtk_action_set_sensitive( prop_action, !flat );
 
1616
    }
 
1617
 
 
1618
    for (; items != NULL; items = items->next) {
 
1619
        if (SP_IS_STAR((SPItem *) items->data)) {
 
1620
            Inkscape::XML::Node *repr = SP_OBJECT_REPR((SPItem *) items->data);
 
1621
            repr->setAttribute("inkscape:flatsided", flat ? "true" : "false" );
 
1622
            SP_OBJECT((SPItem *) items->data)->updateRepr(repr, SP_OBJECT_WRITE_EXT);
 
1623
            modmade = true;
 
1624
        }
 
1625
    }
 
1626
 
 
1627
    if (modmade) {
 
1628
        sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR,
 
1629
                         flat ? _("Make polygon") : _("Make star"));
 
1630
    }
 
1631
 
 
1632
    g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(FALSE) );
1003
1633
}
1004
1634
 
1005
 
static void
1006
 
sp_stb_rounded_value_changed(GtkAdjustment *adj, GtkWidget *tbl)
 
1635
static void sp_stb_rounded_value_changed( GtkAdjustment *adj, GObject *dataKludge )
1007
1636
{
1008
 
    SPDesktop *desktop = (SPDesktop *) gtk_object_get_data(GTK_OBJECT(tbl), "desktop");
 
1637
    SPDesktop *desktop = (SPDesktop *) g_object_get_data( dataKludge, "desktop" );
1009
1638
 
1010
1639
    if (sp_document_get_undo_sensitive(sp_desktop_document(desktop))) {
1011
1640
        prefs_set_double_attribute("tools.shapes.star", "rounded", (gdouble) adj->value);
1012
1641
    }
1013
1642
 
1014
1643
    // quit if run by the attr_changed listener
1015
 
    if (g_object_get_data(G_OBJECT(tbl), "freeze")) {
 
1644
    if (g_object_get_data( dataKludge, "freeze" )) {
1016
1645
        return;
1017
1646
    }
1018
1647
 
1019
1648
    // in turn, prevent listener from responding
1020
 
    g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE));
 
1649
    g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(TRUE) );
1021
1650
 
1022
1651
    bool modmade = false;
1023
1652
 
1031
1660
            modmade = true;
1032
1661
        }
1033
1662
    }
1034
 
    if (modmade)  sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR, 
 
1663
    if (modmade)  sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR,
1035
1664
                                   _("Star: Change rounding"));
1036
1665
 
1037
 
    g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(FALSE));
1038
 
 
1039
 
    spinbutton_defocus(GTK_OBJECT(tbl));
 
1666
    g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(FALSE) );
1040
1667
}
1041
1668
 
1042
 
 
1043
 
static void
1044
 
sp_stb_randomized_value_changed(GtkAdjustment *adj, GtkWidget *tbl)
 
1669
static void sp_stb_randomized_value_changed( GtkAdjustment *adj, GObject *dataKludge )
1045
1670
{
1046
 
    SPDesktop *desktop = (SPDesktop *) gtk_object_get_data(GTK_OBJECT(tbl), "desktop");
 
1671
    SPDesktop *desktop = (SPDesktop *) g_object_get_data( dataKludge, "desktop" );
1047
1672
 
1048
1673
    if (sp_document_get_undo_sensitive(sp_desktop_document(desktop))) {
1049
1674
        prefs_set_double_attribute("tools.shapes.star", "randomized", (gdouble) adj->value);
1050
1675
    }
1051
1676
 
1052
1677
    // quit if run by the attr_changed listener
1053
 
    if (g_object_get_data(G_OBJECT(tbl), "freeze")) {
 
1678
    if (g_object_get_data( dataKludge, "freeze" )) {
1054
1679
        return;
1055
1680
    }
1056
1681
 
1057
1682
    // in turn, prevent listener from responding
1058
 
    g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE));
 
1683
    g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(TRUE) );
1059
1684
 
1060
1685
    bool modmade = false;
1061
1686
 
1069
1694
            modmade = true;
1070
1695
        }
1071
1696
    }
1072
 
    if (modmade)  sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR, 
 
1697
    if (modmade)  sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR,
1073
1698
                                   _("Star: Change randomization"));
1074
1699
 
1075
 
    g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(FALSE));
1076
 
 
1077
 
    spinbutton_defocus(GTK_OBJECT(tbl));
 
1700
    g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(FALSE) );
1078
1701
}
1079
1702
 
1080
1703
 
1081
1704
static void star_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const *name,
1082
 
                                       gchar const *old_value, gchar const *new_value,
1083
 
                                       bool is_interactive, gpointer data)
 
1705
                                       gchar const */*old_value*/, gchar const */*new_value*/,
 
1706
                                       bool /*is_interactive*/, gpointer data)
1084
1707
{
1085
1708
    GtkWidget *tbl = GTK_WIDGET(data);
1086
1709
 
1092
1715
    // in turn, prevent callbacks from responding
1093
1716
    g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE));
1094
1717
 
1095
 
    GtkAdjustment *adj;
 
1718
    GtkAdjustment *adj = 0;
1096
1719
 
1097
1720
    if (!strcmp(name, "inkscape:randomized")) {
1098
 
        adj = (GtkAdjustment*)gtk_object_get_data(GTK_OBJECT(tbl), "randomized");
 
1721
        adj = GTK_ADJUSTMENT( gtk_object_get_data(GTK_OBJECT(tbl), "randomized") );
1099
1722
        gtk_adjustment_set_value(adj, sp_repr_get_double_attribute(repr, "inkscape:randomized", 0.0));
1100
1723
    } else if (!strcmp(name, "inkscape:rounded")) {
1101
 
        adj = (GtkAdjustment*)gtk_object_get_data(GTK_OBJECT(tbl), "rounded");
 
1724
        adj = GTK_ADJUSTMENT( gtk_object_get_data(GTK_OBJECT(tbl), "rounded") );
1102
1725
        gtk_adjustment_set_value(adj, sp_repr_get_double_attribute(repr, "inkscape:rounded", 0.0));
1103
1726
    } else if (!strcmp(name, "inkscape:flatsided")) {
1104
 
        GtkWidget *fscb = (GtkWidget*) g_object_get_data(G_OBJECT(tbl), "flat_checkbox");
1105
 
        GtkWidget *prop_widget = (GtkWidget*) g_object_get_data(G_OBJECT(tbl), "prop_widget");
 
1727
        GtkAction* prop_action = GTK_ACTION( g_object_get_data(G_OBJECT(tbl), "prop_action") );
1106
1728
        char const *flatsides = repr->attribute("inkscape:flatsided");
1107
 
        if (flatsides && !strcmp(flatsides,"false" )) {
1108
 
            gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(fscb),  FALSE);
1109
 
            gtk_widget_set_sensitive(GTK_WIDGET(prop_widget), TRUE);
 
1729
        EgeSelectOneAction* flat_action = EGE_SELECT_ONE_ACTION( g_object_get_data( G_OBJECT(tbl), "flat_action" ) );
 
1730
        if ( flatsides && !strcmp(flatsides,"false") ) {
 
1731
            ege_select_one_action_set_active( flat_action, 1 );
 
1732
            gtk_action_set_sensitive( prop_action, TRUE );
1110
1733
        } else {
1111
 
            gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(fscb),  TRUE);
1112
 
            gtk_widget_set_sensitive(GTK_WIDGET(prop_widget), FALSE);
 
1734
            ege_select_one_action_set_active( flat_action, 0 );
 
1735
            gtk_action_set_sensitive( prop_action, FALSE );
1113
1736
        }
1114
1737
    } else if (!strcmp(name, "sodipodi:r1") || !strcmp(name, "sodipodi:r2")) {
1115
1738
        adj = (GtkAdjustment*)gtk_object_get_data(GTK_OBJECT(tbl), "proportion");
1143
1766
 *  \param selection Should not be NULL.
1144
1767
 */
1145
1768
static void
1146
 
sp_star_toolbox_selection_changed(Inkscape::Selection *selection, GtkObject *tbl)
 
1769
sp_star_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl)
1147
1770
{
1148
1771
    int n_selected = 0;
1149
1772
    Inkscape::XML::Node *repr = NULL;
1150
 
    Inkscape::XML::Node *oldrepr = NULL;
 
1773
 
 
1774
    purge_repr_listener( tbl, tbl );
1151
1775
 
1152
1776
    for (GSList const *items = selection->itemList();
1153
1777
         items != NULL;
1159
1783
        }
1160
1784
    }
1161
1785
 
1162
 
    GtkWidget *l = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(tbl), "mode_label"));
 
1786
    EgeOutputAction* act = EGE_OUTPUT_ACTION( g_object_get_data( tbl, "mode_action" ) );
1163
1787
 
1164
1788
    if (n_selected == 0) {
1165
 
        gtk_label_set_markup(GTK_LABEL(l), _("<b>New:</b>"));
 
1789
        g_object_set( G_OBJECT(act), "label", _("<b>New:</b>"), NULL );
1166
1790
    } else if (n_selected == 1) {
1167
 
        gtk_label_set_markup(GTK_LABEL(l), _("<b>Change:</b>"));
1168
 
 
1169
 
        oldrepr = (Inkscape::XML::Node *) gtk_object_get_data(GTK_OBJECT(tbl), "repr");
1170
 
        if (oldrepr) { // remove old listener
1171
 
            sp_repr_remove_listener_by_data(oldrepr, tbl);
1172
 
            Inkscape::GC::release(oldrepr);
1173
 
            oldrepr = 0;
1174
 
            g_object_set_data(G_OBJECT(tbl), "repr", NULL);
1175
 
        }
 
1791
        g_object_set( G_OBJECT(act), "label", _("<b>Change:</b>"), NULL );
1176
1792
 
1177
1793
        if (repr) {
1178
 
            g_object_set_data(G_OBJECT(tbl), "repr", repr);
 
1794
            g_object_set_data( tbl, "repr", repr );
1179
1795
            Inkscape::GC::anchor(repr);
1180
1796
            sp_repr_add_listener(repr, &star_tb_repr_events, tbl);
1181
1797
            sp_repr_synthesize_events(repr, &star_tb_repr_events, tbl);
1183
1799
    } else {
1184
1800
        // FIXME: implement averaging of all parameters for multiple selected stars
1185
1801
        //gtk_label_set_markup(GTK_LABEL(l), _("<b>Average:</b>"));
1186
 
        gtk_label_set_markup(GTK_LABEL(l), _("<b>Change:</b>"));
 
1802
        //gtk_label_set_markup(GTK_LABEL(l), _("<b>Change:</b>"));
1187
1803
    }
1188
1804
}
1189
1805
 
1190
1806
 
1191
 
static void
1192
 
sp_stb_defaults(GtkWidget *widget, GtkWidget *tbl)
 
1807
static void sp_stb_defaults( GtkWidget */*widget*/, GObject *dataKludge )
1193
1808
{
1194
1809
    // FIXME: in this and all other _default functions, set some flag telling the value_changed
1195
1810
    // callbacks to lump all the changes for all selected objects in one undo step
1196
1811
 
1197
 
    GtkAdjustment *adj;
 
1812
    GtkAdjustment *adj = 0;
1198
1813
 
1199
1814
    // fixme: make settable in prefs!
1200
1815
    gint mag = 5;
1203
1818
    gdouble randomized = 0;
1204
1819
    gdouble rounded = 0;
1205
1820
 
1206
 
    GtkWidget *fscb = (GtkWidget*) g_object_get_data(G_OBJECT(tbl), "flat_checkbox");
1207
 
    gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(fscb),  flat);
1208
 
    GtkWidget *sb2 = (GtkWidget*) g_object_get_data(G_OBJECT(tbl), "prop_widget");
1209
 
    gtk_widget_set_sensitive(GTK_WIDGET(sb2), !flat);
1210
 
 
1211
 
    adj = (GtkAdjustment*)gtk_object_get_data(GTK_OBJECT(tbl), "magnitude");
 
1821
    EgeSelectOneAction* flat_action = EGE_SELECT_ONE_ACTION( g_object_get_data( dataKludge, "flat_action" ) );
 
1822
    ege_select_one_action_set_active( flat_action, flat ? 0 : 1 );
 
1823
 
 
1824
    GtkAction* sb2 = GTK_ACTION( g_object_get_data( dataKludge, "prop_action" ) );
 
1825
    gtk_action_set_sensitive( sb2, !flat );
 
1826
 
 
1827
    adj = GTK_ADJUSTMENT( g_object_get_data( dataKludge, "magnitude" ) );
1212
1828
    gtk_adjustment_set_value(adj, mag);
1213
1829
    gtk_adjustment_value_changed(adj);
1214
1830
 
1215
 
    adj = (GtkAdjustment*)gtk_object_get_data(GTK_OBJECT(tbl), "proportion");
 
1831
    adj = GTK_ADJUSTMENT( g_object_get_data( dataKludge, "proportion" ) );
1216
1832
    gtk_adjustment_set_value(adj, prop);
1217
1833
    gtk_adjustment_value_changed(adj);
1218
1834
 
1219
 
    adj = (GtkAdjustment*)gtk_object_get_data(GTK_OBJECT(tbl), "rounded");
 
1835
    adj = GTK_ADJUSTMENT( g_object_get_data( dataKludge, "rounded" ) );
1220
1836
    gtk_adjustment_set_value(adj, rounded);
1221
1837
    gtk_adjustment_value_changed(adj);
1222
1838
 
1223
 
    adj = (GtkAdjustment*)gtk_object_get_data(GTK_OBJECT(tbl), "randomized");
 
1839
    adj = GTK_ADJUSTMENT( g_object_get_data( dataKludge, "randomized" ) );
1224
1840
    gtk_adjustment_set_value(adj, randomized);
1225
1841
    gtk_adjustment_value_changed(adj);
1226
 
 
1227
 
    spinbutton_defocus(GTK_OBJECT(tbl));
1228
1842
}
1229
1843
 
1230
1844
 
1241
1855
}
1242
1856
 
1243
1857
 
1244
 
static GtkWidget *
1245
 
sp_star_toolbox_new(SPDesktop *desktop)
 
1858
static void sp_star_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
1246
1859
{
1247
 
    GtkWidget *tbl = gtk_hbox_new(FALSE, 0);
1248
 
 
1249
 
    gtk_object_set_data(GTK_OBJECT(tbl), "dtw", desktop->canvas);
1250
 
    gtk_object_set_data(GTK_OBJECT(tbl), "desktop", desktop);
1251
 
 
1252
 
    GtkTooltips *tt = gtk_tooltips_new();
1253
 
 
1254
 
    sp_toolbox_add_label(tbl, _("<b>New:</b>"));
1255
 
 
1256
 
    gchar const *flatsidedstr = NULL;
1257
 
 
1258
 
    /* Flatsided checkbox */
1259
1860
    {
1260
 
        GtkWidget *hb = gtk_hbox_new(FALSE, 1);
1261
 
        GtkWidget *fscb = gtk_check_button_new_with_label(_("Polygon"));
1262
 
        gtk_widget_set_sensitive(GTK_WIDGET(fscb), TRUE);
1263
 
        flatsidedstr = prefs_get_string_attribute("tools.shapes.star", "isflatsided");
1264
 
        if (!flatsidedstr || (flatsidedstr && !strcmp(flatsidedstr, "false")))
1265
 
            gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(fscb),  FALSE);
1266
 
        else
1267
 
            gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(fscb),  TRUE);
1268
 
        gtk_tooltips_set_tip(tt, fscb, _("Regular polygon (with one handle) instead of a star"), NULL);
1269
 
        gtk_widget_show(fscb);
1270
 
        gtk_object_set_data(GTK_OBJECT(tbl), "flat_checkbox", fscb);
1271
 
        gtk_container_add(GTK_CONTAINER(hb), fscb);
1272
 
        g_signal_connect(G_OBJECT(fscb), "toggled", GTK_SIGNAL_FUNC(sp_stb_sides_flat_state_changed ), tbl);
1273
 
        gtk_box_pack_start(GTK_BOX(tbl),hb, FALSE, FALSE, AUX_SPACING);
 
1861
        EgeOutputAction* act = ege_output_action_new( "StarStateAction", _("<b>New:</b>"), "", 0 );
 
1862
        ege_output_action_set_use_markup( act, TRUE );
 
1863
        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
 
1864
        g_object_set_data( holder, "mode_action", act );
1274
1865
    }
1275
1866
 
1276
 
    aux_toolbox_space(tbl, AUX_BETWEEN_BUTTON_GROUPS);
1277
 
 
1278
 
    /* Magnitude */
1279
1867
    {
1280
 
        GtkWidget *hb = sp_tb_spinbutton(_("Corners:"), _("Number of corners of a polygon or star"),
 
1868
        EgeAdjustmentAction* eact = 0;
 
1869
        gchar const *flatsidedstr = prefs_get_string_attribute( "tools.shapes.star", "isflatsided" );
 
1870
        bool isFlatSided = flatsidedstr ? (strcmp(flatsidedstr, "false") != 0) : true;
 
1871
 
 
1872
        /* Flatsided checkbox */
 
1873
        {
 
1874
            GtkListStore* model = gtk_list_store_new( 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING );
 
1875
 
 
1876
            GtkTreeIter iter;
 
1877
            gtk_list_store_append( model, &iter );
 
1878
            gtk_list_store_set( model, &iter,
 
1879
                                0, _("Polygon"),
 
1880
                                1, _("Regular polygon (with one handle) instead of a star"),
 
1881
                                2, "star_flat",
 
1882
                                -1 );
 
1883
 
 
1884
            gtk_list_store_append( model, &iter );
 
1885
            gtk_list_store_set( model, &iter,
 
1886
                                0, _("Star"),
 
1887
                                1, _("Star instead of a regular polygon (with one handle)"),
 
1888
                                2, "star_angled",
 
1889
                                -1 );
 
1890
 
 
1891
            EgeSelectOneAction* act = ege_select_one_action_new( "FlatAction", (""), (""), NULL, GTK_TREE_MODEL(model) );
 
1892
            gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
 
1893
            g_object_set_data( holder, "flat_action", act );
 
1894
 
 
1895
            ege_select_one_action_set_appearance( act, "full" );
 
1896
            ege_select_one_action_set_radio_action_type( act, INK_RADIO_ACTION_TYPE );
 
1897
            g_object_set( G_OBJECT(act), "icon-property", "iconId", NULL );
 
1898
            ege_select_one_action_set_icon_column( act, 2 );
 
1899
            ege_select_one_action_set_tooltip_column( act, 1  );
 
1900
 
 
1901
            ege_select_one_action_set_active( act, isFlatSided ? 0 : 1 );
 
1902
            g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_stb_sides_flat_state_changed), holder);
 
1903
        }
 
1904
 
 
1905
        /* Magnitude */
 
1906
        {
 
1907
        gchar const* labels[] = {_("triangle/tri-star"), _("square/quad-star"), _("pentagon/five-pointed star"), _("hexagon/six-pointed star"), 0, 0, 0, 0, 0};
 
1908
        gdouble values[] = {3, 4, 5, 6, 7, 8, 10, 12, 20};
 
1909
        eact = create_adjustment_action( "MagnitudeAction",
 
1910
                                         _("Corners"), _("Corners:"), _("Number of corners of a polygon or star"),
1281
1911
                                         "tools.shapes.star", "magnitude", 3,
1282
 
                                         NULL, tbl, TRUE, "altx-star",
1283
 
                                         3, 1024, 1, 1,
1284
 
                                         sp_stb_magnitude_value_changed, 1, 0);
1285
 
        gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, AUX_SPACING);
1286
 
    }
 
1912
                                         GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
 
1913
                                         3, 1024, 1, 5,
 
1914
                                         labels, values, G_N_ELEMENTS(labels),
 
1915
                                         sp_stb_magnitude_value_changed,
 
1916
                                         1.0, 0 );
 
1917
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
 
1918
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
 
1919
        }
1287
1920
 
1288
 
    /* Spoke ratio */
1289
 
    {
1290
 
        GtkWidget *hb = sp_tb_spinbutton(_("Spoke ratio:"),
 
1921
        /* Spoke ratio */
 
1922
        {
 
1923
        gchar const* labels[] = {_("thin-ray star"), 0, _("pentagram"), _("hexagram"), _("heptagram"), _("octagram"), _("regular polygon")};
 
1924
        gdouble values[] = {0.01, 0.2, 0.382, 0.577, 0.692, 0.765, 1};
 
1925
        eact = create_adjustment_action( "SpokeAction",
 
1926
                                         _("Spoke ratio"), _("Spoke ratio:"),
1291
1927
                                         // TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle.
1292
1928
                                         // Base radius is the same for the closest handle.
1293
1929
                                         _("Base radius to tip radius ratio"),
1294
1930
                                         "tools.shapes.star", "proportion", 0.5,
1295
 
                                         NULL, tbl, FALSE, NULL,
 
1931
                                         GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
1296
1932
                                         0.01, 1.0, 0.01, 0.1,
1297
 
                                         sp_stb_proportion_value_changed);
1298
 
        gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, AUX_SPACING);
1299
 
        g_object_set_data(G_OBJECT(tbl), "prop_widget", hb);
1300
 
        if (!flatsidedstr || (flatsidedstr && !strcmp(flatsidedstr, "false")))
1301
 
            gtk_widget_set_sensitive(GTK_WIDGET(hb), TRUE);
1302
 
        else
1303
 
            gtk_widget_set_sensitive(GTK_WIDGET(hb), FALSE);
1304
 
    }
1305
 
 
1306
 
    /* Roundedness */
1307
 
    {
1308
 
        GtkWidget *hb = sp_tb_spinbutton(_("Rounded:"), _("How much rounded are the corners (0 for sharp)"),
 
1933
                                         labels, values, G_N_ELEMENTS(labels),
 
1934
                                         sp_stb_proportion_value_changed );
 
1935
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
 
1936
        g_object_set_data( holder, "prop_action", eact );
 
1937
        }
 
1938
 
 
1939
        if ( !isFlatSided ) {
 
1940
            gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
 
1941
        } else {
 
1942
            gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
 
1943
        }
 
1944
 
 
1945
        /* Roundedness */
 
1946
        {
 
1947
        gchar const* labels[] = {_("stretched"), _("twisted"), _("slightly pinched"), _("NOT rounded"), _("slightly rounded"), _("visibly rounded"), _("well rounded"), _("amply rounded"), 0, _("stretched"), _("blown up")};
 
1948
        gdouble values[] = {-1, -0.2, -0.03, 0, 0.05, 0.1, 0.2, 0.3, 0.5, 1, 10};
 
1949
        eact = create_adjustment_action( "RoundednessAction",
 
1950
                                         _("Rounded"), _("Rounded:"), _("How much rounded are the corners (0 for sharp)"),
1309
1951
                                         "tools.shapes.star", "rounded", 0.0,
1310
 
                                         NULL, tbl, FALSE, NULL,
1311
 
                                         -100.0, 100.0, 0.01, 0.1,
1312
 
                                         sp_stb_rounded_value_changed);
1313
 
        gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, AUX_SPACING);
1314
 
    }
 
1952
                                         GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
 
1953
                                         -10.0, 10.0, 0.01, 0.1,
 
1954
                                         labels, values, G_N_ELEMENTS(labels),
 
1955
                                         sp_stb_rounded_value_changed );
 
1956
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
 
1957
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
 
1958
        }
1315
1959
 
1316
 
    /* Randomization */
1317
 
    {
1318
 
        GtkWidget *hb = sp_tb_spinbutton(_("Randomized:"), _("Scatter randomly the corners and angles"),
 
1960
        /* Randomization */
 
1961
        {
 
1962
        gchar const* labels[] = {_("NOT randomized"), _("slightly irregular"), _("visibly randomized"), _("strongly randomized"), _("blown up")};
 
1963
        gdouble values[] = {0, 0.01, 0.1, 0.5, 10};
 
1964
        eact = create_adjustment_action( "RandomizationAction",
 
1965
                                         _("Randomized"), _("Randomized:"), _("Scatter randomly the corners and angles"),
1319
1966
                                         "tools.shapes.star", "randomized", 0.0,
1320
 
                                         NULL, tbl, FALSE, NULL,
 
1967
                                         GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
1321
1968
                                         -10.0, 10.0, 0.001, 0.01,
1322
 
                                         sp_stb_randomized_value_changed, 0.1, 3);
1323
 
        gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, AUX_SPACING);
 
1969
                                         labels, values, G_N_ELEMENTS(labels),
 
1970
                                         sp_stb_randomized_value_changed, 0.1, 3 );
 
1971
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
 
1972
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
 
1973
        }
1324
1974
    }
1325
1975
 
1326
 
    aux_toolbox_space(tbl, AUX_SPACING);
1327
 
 
1328
 
    /* Reset */
1329
1976
    {
1330
 
        GtkWidget *hb = gtk_hbox_new(FALSE, 1);
1331
 
        GtkWidget *b = gtk_button_new_with_label(_("Defaults"));
1332
 
        gtk_tooltips_set_tip(tt, b, _("Reset shape parameters to defaults (use Inkscape Preferences > Tools to change defaults)"), NULL);
1333
 
        gtk_widget_show(b);
1334
 
        gtk_container_add(GTK_CONTAINER(hb), b);
1335
 
        gtk_signal_connect(GTK_OBJECT(b), "clicked", GTK_SIGNAL_FUNC(sp_stb_defaults), tbl);
1336
 
        gtk_box_pack_start(GTK_BOX(tbl),hb, FALSE, FALSE, AUX_SPACING);
 
1977
        /* Reset */
 
1978
        {
 
1979
            GtkAction* act = gtk_action_new( "StarResetAction",
 
1980
                                             _("Defaults"),
 
1981
                                             _("Reset shape parameters to defaults (use Inkscape Preferences > Tools to change defaults)"),
 
1982
                                             GTK_STOCK_CLEAR );
 
1983
            g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_stb_defaults), holder );
 
1984
            gtk_action_group_add_action( mainActions, act );
 
1985
            gtk_action_set_sensitive( act, TRUE );
 
1986
        }
1337
1987
    }
1338
1988
 
1339
 
    Inkscape::UI::Widget::StyleSwatch *swatch = new Inkscape::UI::Widget::StyleSwatch(NULL);
1340
 
    swatch->setWatchedTool ("tools.shapes.star", true);
1341
 
    GtkWidget *swatch_ = GTK_WIDGET(swatch->gobj());
1342
 
    gtk_box_pack_end(GTK_BOX(tbl), swatch_, FALSE, FALSE, 0);
1343
 
 
1344
 
    gtk_widget_show_all(tbl);
1345
 
    sp_set_font_size_smaller (tbl);
1346
 
 
1347
1989
    sigc::connection *connection = new sigc::connection(
1348
 
        sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_star_toolbox_selection_changed), (GtkObject *)tbl))
 
1990
        sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_star_toolbox_selection_changed), (GObject *)holder))
1349
1991
        );
1350
 
    g_signal_connect(G_OBJECT(tbl), "destroy", G_CALLBACK(delete_connection), connection);
1351
 
 
1352
 
    return tbl;
 
1992
    g_signal_connect( holder, "destroy", G_CALLBACK(delete_connection), connection );
 
1993
    g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder );
1353
1994
}
1354
1995
 
1355
1996
 
1357
1998
//##       Rect         ##
1358
1999
//########################
1359
2000
 
1360
 
static void 
1361
 
sp_rtb_sensitivize (GtkWidget *tbl)
 
2001
static void sp_rtb_sensitivize( GObject *tbl )
1362
2002
{
1363
 
    GtkAdjustment *adj1 = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(tbl), "rx"));
1364
 
    GtkAdjustment *adj2 = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(tbl), "ry"));
1365
 
    GtkWidget *not_rounded = (GtkWidget*) g_object_get_data(G_OBJECT(tbl), "not_rounded");
 
2003
    GtkAdjustment *adj1 = GTK_ADJUSTMENT( g_object_get_data(tbl, "rx") );
 
2004
    GtkAdjustment *adj2 = GTK_ADJUSTMENT( g_object_get_data(tbl, "ry") );
 
2005
    GtkAction* not_rounded = GTK_ACTION( g_object_get_data(tbl, "not_rounded") );
1366
2006
 
1367
 
    if (adj1->value == 0 && adj2->value == 0 && gtk_object_get_data(GTK_OBJECT(tbl), "single")) { // only for a single selected rect (for now)
1368
 
        gtk_widget_set_sensitive(GTK_WIDGET(not_rounded), FALSE);
 
2007
    if (adj1->value == 0 && adj2->value == 0 && g_object_get_data(tbl, "single")) { // only for a single selected rect (for now)
 
2008
        gtk_action_set_sensitive( not_rounded, FALSE );
1369
2009
    } else {
1370
 
        gtk_widget_set_sensitive(GTK_WIDGET(not_rounded), TRUE);
 
2010
        gtk_action_set_sensitive( not_rounded, TRUE );
1371
2011
    }
1372
2012
}
1373
2013
 
1374
2014
 
1375
2015
static void
1376
 
sp_rtb_value_changed(GtkAdjustment *adj, GtkWidget *tbl, gchar const *value_name,
 
2016
sp_rtb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *value_name,
1377
2017
                          void (*setter)(SPRect *, gdouble))
1378
2018
{
1379
 
    SPDesktop *desktop = (SPDesktop *) gtk_object_get_data(GTK_OBJECT(tbl), "desktop");
 
2019
    SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" );
1380
2020
 
1381
 
    GtkWidget *us = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(tbl), "units");
1382
 
    SPUnit const *unit = sp_unit_selector_get_unit(SP_UNIT_SELECTOR(us));
 
2021
    UnitTracker* tracker = reinterpret_cast<UnitTracker*>(g_object_get_data( tbl, "tracker" ));
 
2022
    SPUnit const *unit = tracker->getActiveUnit();
1383
2023
 
1384
2024
    if (sp_document_get_undo_sensitive(sp_desktop_document(desktop))) {
1385
2025
        prefs_set_double_attribute("tools.shapes.rect", value_name, sp_units_get_pixels(adj->value, *unit));
1386
2026
    }
1387
2027
 
1388
2028
    // quit if run by the attr_changed listener
1389
 
    if (g_object_get_data(G_OBJECT(tbl), "freeze")) {
 
2029
    if (g_object_get_data( tbl, "freeze" )) {
1390
2030
        return;
1391
2031
    }
1392
2032
 
1393
2033
    // in turn, prevent listener from responding
1394
 
    g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE));
 
2034
    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE));
1395
2035
 
1396
2036
    bool modmade = false;
1397
2037
    Inkscape::Selection *selection = sp_desktop_selection(desktop);
1406
2046
        }
1407
2047
    }
1408
2048
 
1409
 
    sp_rtb_sensitivize (tbl);
 
2049
    sp_rtb_sensitivize( tbl );
1410
2050
 
1411
2051
    if (modmade) {
1412
 
        sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_RECT, 
 
2052
        sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_RECT,
1413
2053
                                   _("Change rectangle"));
1414
2054
    }
1415
2055
 
1416
 
    g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(FALSE));
1417
 
 
1418
 
    // defocus spinbuttons by moving focus to the canvas, unless "stay" is on
1419
 
    spinbutton_defocus(GTK_OBJECT(tbl));
 
2056
    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
1420
2057
}
1421
2058
 
1422
2059
static void
1423
 
sp_rtb_rx_value_changed(GtkAdjustment *adj, GtkWidget *tbl)
 
2060
sp_rtb_rx_value_changed(GtkAdjustment *adj, GObject *tbl)
1424
2061
{
1425
2062
    sp_rtb_value_changed(adj, tbl, "rx", sp_rect_set_visible_rx);
1426
2063
}
1427
2064
 
1428
2065
static void
1429
 
sp_rtb_ry_value_changed(GtkAdjustment *adj, GtkWidget *tbl)
 
2066
sp_rtb_ry_value_changed(GtkAdjustment *adj, GObject *tbl)
1430
2067
{
1431
2068
    sp_rtb_value_changed(adj, tbl, "ry", sp_rect_set_visible_ry);
1432
2069
}
1433
2070
 
1434
2071
static void
1435
 
sp_rtb_width_value_changed(GtkAdjustment *adj, GtkWidget *tbl)
 
2072
sp_rtb_width_value_changed(GtkAdjustment *adj, GObject *tbl)
1436
2073
{
1437
2074
    sp_rtb_value_changed(adj, tbl, "width", sp_rect_set_visible_width);
1438
2075
}
1439
2076
 
1440
2077
static void
1441
 
sp_rtb_height_value_changed(GtkAdjustment *adj, GtkWidget *tbl)
 
2078
sp_rtb_height_value_changed(GtkAdjustment *adj, GObject *tbl)
1442
2079
{
1443
2080
    sp_rtb_value_changed(adj, tbl, "height", sp_rect_set_visible_height);
1444
2081
}
1446
2083
 
1447
2084
 
1448
2085
static void
1449
 
sp_rtb_defaults( GtkWidget *widget, GtkObject *obj)
 
2086
sp_rtb_defaults( GtkWidget */*widget*/, GObject *obj)
1450
2087
{
1451
 
    GtkWidget *tbl = GTK_WIDGET(obj);
1452
 
 
1453
 
    GtkAdjustment *adj;
1454
 
 
1455
 
    adj = (GtkAdjustment*)gtk_object_get_data(obj, "rx");
 
2088
    GtkAdjustment *adj = 0;
 
2089
 
 
2090
    adj = GTK_ADJUSTMENT( g_object_get_data(obj, "rx") );
1456
2091
    gtk_adjustment_set_value(adj, 0.0);
1457
2092
    // this is necessary if the previous value was 0, but we still need to run the callback to change all selected objects
1458
2093
    gtk_adjustment_value_changed(adj);
1459
2094
 
1460
 
    adj = (GtkAdjustment*)gtk_object_get_data(obj, "ry");
 
2095
    adj = GTK_ADJUSTMENT( g_object_get_data(obj, "ry") );
1461
2096
    gtk_adjustment_set_value(adj, 0.0);
1462
2097
    gtk_adjustment_value_changed(adj);
1463
2098
 
1464
 
    sp_rtb_sensitivize (tbl);
1465
 
 
1466
 
    spinbutton_defocus(GTK_OBJECT(tbl));
 
2099
    sp_rtb_sensitivize( obj );
1467
2100
}
1468
2101
 
1469
 
static void rect_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const *name,
1470
 
                                       gchar const *old_value, gchar const *new_value,
1471
 
                                       bool is_interactive, gpointer data)
 
2102
static void rect_tb_event_attr_changed(Inkscape::XML::Node */*repr*/, gchar const */*name*/,
 
2103
                                       gchar const */*old_value*/, gchar const */*new_value*/,
 
2104
                                       bool /*is_interactive*/, gpointer data)
1472
2105
{
1473
 
    GtkWidget *tbl = GTK_WIDGET(data);
 
2106
    GObject *tbl = G_OBJECT(data);
1474
2107
 
1475
2108
    // quit if run by the _changed callbacks
1476
 
    if (g_object_get_data(G_OBJECT(tbl), "freeze")) {
 
2109
    if (g_object_get_data( tbl, "freeze" )) {
1477
2110
        return;
1478
2111
    }
1479
2112
 
1480
2113
    // in turn, prevent callbacks from responding
1481
 
    g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE));
1482
 
 
1483
 
    GtkWidget *us = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(tbl), "units");
1484
 
    SPUnit const *unit = sp_unit_selector_get_unit(SP_UNIT_SELECTOR(us));
1485
 
 
1486
 
    SPItem *item = SP_ITEM(g_object_get_data(G_OBJECT(tbl), "item"));
1487
 
    if (SP_IS_RECT(item)) {
 
2114
    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) );
 
2115
 
 
2116
    UnitTracker* tracker = reinterpret_cast<UnitTracker*>( g_object_get_data( tbl, "tracker" ) );
 
2117
    SPUnit const *unit = tracker->getActiveUnit();
 
2118
 
 
2119
    gpointer item = g_object_get_data( tbl, "item" );
 
2120
    if (item && SP_IS_RECT(item)) {
1488
2121
        {
1489
 
            GtkAdjustment *adj = (GtkAdjustment*)gtk_object_get_data(GTK_OBJECT(tbl), "rx");
 
2122
            GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "rx" ) );
1490
2123
            gdouble rx = sp_rect_get_visible_rx(SP_RECT(item));
1491
2124
            gtk_adjustment_set_value(adj, sp_pixels_get_units(rx, *unit));
1492
2125
        }
1493
2126
 
1494
2127
        {
1495
 
            GtkAdjustment *adj = (GtkAdjustment*)gtk_object_get_data(GTK_OBJECT(tbl), "ry");
 
2128
            GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "ry" ) );
1496
2129
            gdouble ry = sp_rect_get_visible_ry(SP_RECT(item));
1497
2130
            gtk_adjustment_set_value(adj, sp_pixels_get_units(ry, *unit));
1498
2131
        }
1499
2132
 
1500
2133
        {
1501
 
            GtkAdjustment *adj = (GtkAdjustment*)gtk_object_get_data(GTK_OBJECT(tbl), "width");
 
2134
            GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "width" ) );
1502
2135
            gdouble width = sp_rect_get_visible_width (SP_RECT(item));
1503
2136
            gtk_adjustment_set_value(adj, sp_pixels_get_units(width, *unit));
1504
2137
        }
1505
2138
 
1506
2139
        {
1507
 
            GtkAdjustment *adj = (GtkAdjustment*)gtk_object_get_data(GTK_OBJECT(tbl), "height");
 
2140
            GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "height" ) );
1508
2141
            gdouble height = sp_rect_get_visible_height (SP_RECT(item));
1509
2142
            gtk_adjustment_set_value(adj, sp_pixels_get_units(height, *unit));
1510
2143
        }
1511
2144
    }
1512
2145
 
1513
 
    sp_rtb_sensitivize (tbl);
 
2146
    sp_rtb_sensitivize( tbl );
1514
2147
 
1515
 
    g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(FALSE));
 
2148
    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
1516
2149
}
1517
2150
 
1518
2151
 
1528
2161
 *  \param selection should not be NULL.
1529
2162
 */
1530
2163
static void
1531
 
sp_rect_toolbox_selection_changed(Inkscape::Selection *selection, GtkObject *tbl)
 
2164
sp_rect_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl)
1532
2165
{
1533
2166
    int n_selected = 0;
1534
2167
    Inkscape::XML::Node *repr = NULL;
1535
2168
    SPItem *item = NULL;
1536
 
    Inkscape::XML::Node *oldrepr = NULL;
 
2169
 
 
2170
    if ( g_object_get_data( tbl, "repr" ) ) {
 
2171
        g_object_set_data( tbl, "item", NULL );
 
2172
    }
 
2173
    purge_repr_listener( tbl, tbl );
1537
2174
 
1538
2175
    for (GSList const *items = selection->itemList();
1539
2176
         items != NULL;
1545
2182
        }
1546
2183
    }
1547
2184
 
1548
 
    GtkWidget *l = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(tbl), "mode_label"));
 
2185
    EgeOutputAction* act = EGE_OUTPUT_ACTION( g_object_get_data( tbl, "mode_action" ) );
1549
2186
 
1550
 
    g_object_set_data(G_OBJECT(tbl), "single", GINT_TO_POINTER(FALSE));
 
2187
    g_object_set_data( tbl, "single", GINT_TO_POINTER(FALSE) );
1551
2188
 
1552
2189
    if (n_selected == 0) {
1553
 
        gtk_label_set_markup(GTK_LABEL(l), _("<b>New:</b>"));
 
2190
        g_object_set( G_OBJECT(act), "label", _("<b>New:</b>"), NULL );
1554
2191
 
1555
 
        GtkWidget *w = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(tbl), "width_sb");
1556
 
        gtk_widget_set_sensitive(w, FALSE);
1557
 
        GtkWidget *h = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(tbl), "height_sb");
1558
 
        gtk_widget_set_sensitive(h, FALSE);
 
2192
        GtkAction* w = GTK_ACTION( g_object_get_data( tbl, "width_action" ) );
 
2193
        gtk_action_set_sensitive(w, FALSE);
 
2194
        GtkAction* h = GTK_ACTION( g_object_get_data( tbl, "height_action" ) );
 
2195
        gtk_action_set_sensitive(h, FALSE);
1559
2196
 
1560
2197
    } else if (n_selected == 1) {
1561
 
        gtk_label_set_markup(GTK_LABEL(l), _("<b>Change:</b>"));
1562
 
        g_object_set_data(G_OBJECT(tbl), "single", GINT_TO_POINTER(TRUE));
1563
 
 
1564
 
        GtkWidget *w = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(tbl), "width_sb");
1565
 
        gtk_widget_set_sensitive(w, TRUE);
1566
 
        GtkWidget *h = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(tbl), "height_sb");
1567
 
        gtk_widget_set_sensitive(h, TRUE);
1568
 
 
1569
 
        oldrepr = (Inkscape::XML::Node *) gtk_object_get_data(GTK_OBJECT(tbl), "repr");
1570
 
        if (oldrepr) { // remove old listener
1571
 
            sp_repr_remove_listener_by_data(oldrepr, tbl);
1572
 
            Inkscape::GC::release(oldrepr);
1573
 
            oldrepr = 0;
1574
 
            g_object_set_data(G_OBJECT(tbl), "repr", NULL);
1575
 
        }
 
2198
        g_object_set( G_OBJECT(act), "label", _("<b>Change:</b>"), NULL );
 
2199
        g_object_set_data( tbl, "single", GINT_TO_POINTER(TRUE) );
 
2200
 
 
2201
        GtkAction* w = GTK_ACTION( g_object_get_data( tbl, "width_action" ) );
 
2202
        gtk_action_set_sensitive(w, TRUE);
 
2203
        GtkAction* h = GTK_ACTION( g_object_get_data( tbl, "height_action" ) );
 
2204
        gtk_action_set_sensitive(h, TRUE);
 
2205
 
1576
2206
        if (repr) {
1577
 
            g_object_set_data(G_OBJECT(tbl), "repr", repr);
1578
 
            g_object_set_data(G_OBJECT(tbl), "item", item);
 
2207
            g_object_set_data( tbl, "repr", repr );
 
2208
            g_object_set_data( tbl, "item", item );
1579
2209
            Inkscape::GC::anchor(repr);
1580
2210
            sp_repr_add_listener(repr, &rect_tb_repr_events, tbl);
1581
2211
            sp_repr_synthesize_events(repr, &rect_tb_repr_events, tbl);
1583
2213
    } else {
1584
2214
        // FIXME: implement averaging of all parameters for multiple selected
1585
2215
        //gtk_label_set_markup(GTK_LABEL(l), _("<b>Average:</b>"));
1586
 
        gtk_label_set_markup(GTK_LABEL(l), _("<b>Change:</b>"));
1587
 
        sp_rtb_sensitivize (GTK_WIDGET(tbl));
 
2216
        g_object_set( G_OBJECT(act), "label", _("<b>Change:</b>"), NULL );
 
2217
        sp_rtb_sensitivize( tbl );
1588
2218
    }
1589
2219
}
1590
2220
 
1591
2221
 
1592
 
static GtkWidget *
1593
 
sp_rect_toolbox_new(SPDesktop *desktop)
 
2222
static void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
1594
2223
{
1595
 
    GtkWidget *tbl = gtk_hbox_new(FALSE, 0);
1596
 
 
1597
 
    gtk_object_set_data(GTK_OBJECT(tbl), "dtw", desktop->canvas);
1598
 
    gtk_object_set_data(GTK_OBJECT(tbl), "desktop", desktop);
1599
 
 
1600
 
    GtkTooltips *tt = gtk_tooltips_new();
1601
 
 
1602
 
    sp_toolbox_add_label(tbl, _("<b>New:</b>"));
 
2224
    EgeAdjustmentAction* eact = 0;
 
2225
 
 
2226
    {
 
2227
        EgeOutputAction* act = ege_output_action_new( "RectStateAction", _("<b>New:</b>"), "", 0 );
 
2228
        ege_output_action_set_use_markup( act, TRUE );
 
2229
        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
 
2230
        g_object_set_data( holder, "mode_action", act );
 
2231
    }
1603
2232
 
1604
2233
    // rx/ry units menu: create
1605
 
    GtkWidget *us = sp_unit_selector_new(SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE);
1606
 
    sp_unit_selector_setsize(us, AUX_OPTION_MENU_WIDTH, AUX_OPTION_MENU_HEIGHT);
1607
 
    sp_unit_selector_set_unit(SP_UNIT_SELECTOR(us), desktop->namedview->doc_units);
 
2234
    UnitTracker* tracker = new UnitTracker( SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE );
 
2235
    //tracker->addUnit( SP_UNIT_PERCENT, 0 );
1608
2236
    // fixme: add % meaning per cent of the width/height
 
2237
    tracker->setActiveUnit( sp_desktop_namedview(desktop)->doc_units );
 
2238
    g_object_set_data( holder, "tracker", tracker );
1609
2239
 
1610
2240
    /* W */
1611
2241
    {
1612
 
        GtkWidget *hb = sp_tb_spinbutton(_("W:"), _("Width of rectangle"),
 
2242
        gchar const* labels[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 
2243
        gdouble values[] = {1, 2, 3, 5, 10, 20, 50, 100, 200, 500};
 
2244
        eact = create_adjustment_action( "RectWidthAction",
 
2245
                                         _("Width"), _("W:"), _("Width of rectangle"),
1613
2246
                                         "tools.shapes.rect", "width", 0,
1614
 
                                         us, tbl, TRUE, "altx-rect",
 
2247
                                         GTK_WIDGET(desktop->canvas), NULL/*us*/, holder, TRUE, "altx-rect",
1615
2248
                                         0, 1e6, SPIN_STEP, SPIN_PAGE_STEP,
1616
 
                                         sp_rtb_width_value_changed);
1617
 
        gtk_object_set_data(GTK_OBJECT(tbl), "width_sb", hb);
1618
 
        gtk_widget_set_sensitive(hb, FALSE);
1619
 
        gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
 
2249
                                         labels, values, G_N_ELEMENTS(labels),
 
2250
                                         sp_rtb_width_value_changed );
 
2251
        tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) );
 
2252
        g_object_set_data( holder, "width_action", eact );
 
2253
        gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
 
2254
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
1620
2255
    }
1621
2256
 
1622
2257
    /* H */
1623
2258
    {
1624
 
        GtkWidget *hb = sp_tb_spinbutton(_("H:"), _("Height of rectangle"),
 
2259
        gchar const* labels[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 
2260
        gdouble values[] = {1, 2, 3, 5, 10, 20, 50, 100, 200, 500};
 
2261
        eact = create_adjustment_action( "RectHeightAction",
 
2262
                                         _("Height"), _("H:"), _("Height of rectangle"),
1625
2263
                                         "tools.shapes.rect", "height", 0,
1626
 
                                         us, tbl, FALSE, NULL,
 
2264
                                         GTK_WIDGET(desktop->canvas), NULL/*us*/, holder, FALSE, NULL,
1627
2265
                                         0, 1e6, SPIN_STEP, SPIN_PAGE_STEP,
1628
 
                                         sp_rtb_height_value_changed);
1629
 
        gtk_object_set_data(GTK_OBJECT(tbl), "height_sb", hb);
1630
 
        gtk_widget_set_sensitive(hb, FALSE);
1631
 
        gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
 
2266
                                         labels, values, G_N_ELEMENTS(labels),
 
2267
                                         sp_rtb_height_value_changed );
 
2268
        tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) );
 
2269
        g_object_set_data( holder, "height_action", eact );
 
2270
        gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
 
2271
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
1632
2272
    }
1633
2273
 
1634
2274
    /* rx */
1635
2275
    {
1636
 
        GtkWidget *hb = sp_tb_spinbutton(_("Rx:"), _("Horizontal radius of rounded corners"),
 
2276
        gchar const* labels[] = {_("not rounded"), 0, 0, 0, 0, 0, 0, 0, 0};
 
2277
        gdouble values[] = {0.5, 1, 2, 3, 5, 10, 20, 50, 100};
 
2278
        eact = create_adjustment_action( "RadiusXAction",
 
2279
                                         _("Horizontal radius"), _("Rx:"), _("Horizontal radius of rounded corners"),
1637
2280
                                         "tools.shapes.rect", "rx", 0,
1638
 
                                         us, tbl, FALSE, NULL,
 
2281
                                         GTK_WIDGET(desktop->canvas), NULL/*us*/, holder, FALSE, NULL,
1639
2282
                                         0, 1e6, SPIN_STEP, SPIN_PAGE_STEP,
 
2283
                                         labels, values, G_N_ELEMENTS(labels),
1640
2284
                                         sp_rtb_rx_value_changed);
1641
 
        gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
 
2285
        tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) );
 
2286
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
1642
2287
    }
1643
2288
 
1644
2289
    /* ry */
1645
2290
    {
1646
 
        GtkWidget *hb = sp_tb_spinbutton(_("Ry:"), _("Vertical radius of rounded corners"),
 
2291
        gchar const* labels[] = {_("not rounded"), 0, 0, 0, 0, 0, 0, 0, 0};
 
2292
        gdouble values[] = {0.5, 1, 2, 3, 5, 10, 20, 50, 100};
 
2293
        eact = create_adjustment_action( "RadiusYAction",
 
2294
                                         _("Vertical radius"), _("Ry:"), _("Vertical radius of rounded corners"),
1647
2295
                                         "tools.shapes.rect", "ry", 0,
1648
 
                                         us, tbl, FALSE, NULL,
 
2296
                                         GTK_WIDGET(desktop->canvas), NULL/*us*/, holder, FALSE, NULL,
1649
2297
                                         0, 1e6, SPIN_STEP, SPIN_PAGE_STEP,
 
2298
                                         labels, values, G_N_ELEMENTS(labels),
1650
2299
                                         sp_rtb_ry_value_changed);
1651
 
        gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
 
2300
        tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) );
 
2301
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
1652
2302
    }
1653
2303
 
1654
2304
    // add the units menu
1655
 
    gtk_widget_show(us);
1656
 
    gtk_box_pack_start(GTK_BOX(tbl), us, FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
1657
 
    gtk_object_set_data(GTK_OBJECT(tbl), "units", us);
 
2305
    {
 
2306
        GtkAction* act = tracker->createAction( "RectUnitsAction", _("Units"), ("") );
 
2307
        gtk_action_group_add_action( mainActions, act );
 
2308
    }
1658
2309
 
1659
2310
    /* Reset */
1660
2311
    {
1661
 
        GtkWidget *hb = gtk_hbox_new(FALSE, 1);
1662
 
        GtkWidget *b = gtk_button_new_with_label(_("Not rounded"));
1663
 
        gtk_object_set_data(GTK_OBJECT(tbl), "not_rounded", b);
1664
 
        gtk_tooltips_set_tip(tt, b, _("Make corners sharp"), NULL);
1665
 
        gtk_widget_show(b);
1666
 
        gtk_container_add(GTK_CONTAINER(hb), b);
1667
 
        gtk_signal_connect(GTK_OBJECT(b), "clicked", GTK_SIGNAL_FUNC(sp_rtb_defaults), tbl);
1668
 
        gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
 
2312
        InkAction* inky = ink_action_new( "RectResetAction",
 
2313
                                          _("Not rounded"),
 
2314
                                          _("Make corners sharp"),
 
2315
                                          "squared_corner",
 
2316
                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
 
2317
        g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_rtb_defaults), holder );
 
2318
        gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
 
2319
        gtk_action_set_sensitive( GTK_ACTION(inky), TRUE );
 
2320
        g_object_set_data( holder, "not_rounded", inky );
1669
2321
    }
1670
2322
 
1671
 
    Inkscape::UI::Widget::StyleSwatch *swatch = new Inkscape::UI::Widget::StyleSwatch(NULL);
1672
 
    swatch->setWatchedTool ("tools.shapes.rect", true);
1673
 
    GtkWidget *swatch_ = GTK_WIDGET(swatch->gobj());
1674
 
    gtk_box_pack_end(GTK_BOX(tbl), swatch_, FALSE, FALSE, 0);
1675
 
 
1676
 
    g_object_set_data(G_OBJECT(tbl), "single", GINT_TO_POINTER(TRUE));
1677
 
    sp_rtb_sensitivize (tbl);
1678
 
 
1679
 
    gtk_widget_show_all(tbl);
1680
 
    sp_set_font_size_smaller (tbl);
 
2323
    g_object_set_data( holder, "single", GINT_TO_POINTER(TRUE) );
 
2324
    sp_rtb_sensitivize( holder );
1681
2325
 
1682
2326
    sigc::connection *connection = new sigc::connection(
1683
 
        sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_rect_toolbox_selection_changed), (GtkObject *)tbl))
 
2327
        sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_rect_toolbox_selection_changed), (GObject *)holder))
1684
2328
        );
1685
 
    g_signal_connect(G_OBJECT(tbl), "destroy", G_CALLBACK(delete_connection), connection);
1686
 
 
1687
 
    return tbl;
 
2329
    g_signal_connect( holder, "destroy", G_CALLBACK(delete_connection), connection );
 
2330
    g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder );
 
2331
}
 
2332
 
 
2333
//########################
 
2334
//##       3D Box       ##
 
2335
//########################
 
2336
 
 
2337
// normalize angle so that it lies in the interval [0,360]
 
2338
static double box3d_normalize_angle (double a) {
 
2339
    double angle = a + ((int) (a/360.0))*360;
 
2340
    if (angle < 0) {
 
2341
        angle += 360.0;
 
2342
    }
 
2343
    return angle;
 
2344
}
 
2345
 
 
2346
static void
 
2347
box3d_set_button_and_adjustment(Persp3D *persp, Proj::Axis axis,
 
2348
                                GtkAdjustment *adj, GtkAction *act, GtkToggleAction *tact) {
 
2349
    // TODO: Take all selected perspectives into account but don't touch the state button if not all of them
 
2350
    //       have the same state (otherwise a call to box3d_vp_z_state_changed() is triggered and the states
 
2351
    //       are reset).
 
2352
    bool is_infinite = !persp3d_VP_is_finite(persp, axis);
 
2353
 
 
2354
    if (is_infinite) {
 
2355
        gtk_toggle_action_set_active(tact, TRUE);
 
2356
        gtk_action_set_sensitive(act, TRUE);
 
2357
 
 
2358
        double angle = persp3d_get_infinite_angle(persp, axis);
 
2359
        if (angle != NR_HUGE) { // FIXME: We should catch this error earlier (don't show the spinbutton at all)
 
2360
            gtk_adjustment_set_value(adj, box3d_normalize_angle(angle));
 
2361
        }
 
2362
    } else {
 
2363
        gtk_toggle_action_set_active(tact, FALSE);
 
2364
        gtk_action_set_sensitive(act, FALSE);
 
2365
    }
 
2366
}
 
2367
 
 
2368
static void
 
2369
box3d_resync_toolbar(Inkscape::XML::Node *persp_repr, GObject *data) {
 
2370
    if (!persp_repr) {
 
2371
        g_print ("No perspective given to box3d_resync_toolbar().\n");
 
2372
        return;
 
2373
    }
 
2374
 
 
2375
    GtkWidget *tbl = GTK_WIDGET(data);
 
2376
    GtkAdjustment *adj = 0;
 
2377
    GtkAction *act = 0;
 
2378
    GtkToggleAction *tact = 0;
 
2379
    Persp3D *persp = persp3d_get_from_repr(persp_repr);
 
2380
    {
 
2381
        adj = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(tbl), "box3d_angle_x"));
 
2382
        act = GTK_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_angle_x_action"));
 
2383
        tact = &INK_TOGGLE_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_vp_x_state_action"))->action;
 
2384
 
 
2385
        box3d_set_button_and_adjustment(persp, Proj::X, adj, act, tact);
 
2386
    }
 
2387
    {
 
2388
        adj = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(tbl), "box3d_angle_y"));
 
2389
        act = GTK_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_angle_y_action"));
 
2390
        tact = &INK_TOGGLE_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_vp_y_state_action"))->action;
 
2391
 
 
2392
        box3d_set_button_and_adjustment(persp, Proj::Y, adj, act, tact);
 
2393
    }
 
2394
    {
 
2395
        adj = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(tbl), "box3d_angle_z"));
 
2396
        act = GTK_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_angle_z_action"));
 
2397
        tact = &INK_TOGGLE_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_vp_z_state_action"))->action;
 
2398
 
 
2399
        box3d_set_button_and_adjustment(persp, Proj::Z, adj, act, tact);
 
2400
    }
 
2401
}
 
2402
 
 
2403
static void box3d_persp_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const *name,
 
2404
                                                  gchar const */*old_value*/, gchar const */*new_value*/,
 
2405
                                                  bool /*is_interactive*/, gpointer data)
 
2406
{
 
2407
    GtkWidget *tbl = GTK_WIDGET(data);
 
2408
 
 
2409
    // quit if run by the attr_changed listener
 
2410
    // note: it used to work without the differently called freeze_ attributes (here and in
 
2411
    //       box3d_angle_value_changed()) but I now it doesn't so I'm leaving them in for now
 
2412
    if (g_object_get_data(G_OBJECT(tbl), "freeze_angle")) {
 
2413
        return;
 
2414
    }
 
2415
 
 
2416
    // set freeze so that it can be caught in box3d_angle_z_value_changed() (to avoid calling
 
2417
    // sp_document_maybe_done() when the document is undo insensitive)
 
2418
    g_object_set_data(G_OBJECT(tbl), "freeze_attr", GINT_TO_POINTER(TRUE));
 
2419
 
 
2420
    // TODO: Only update the appropriate part of the toolbar
 
2421
//    if (!strcmp(name, "inkscape:vp_z")) {
 
2422
        box3d_resync_toolbar(repr, G_OBJECT(tbl));
 
2423
//    }
 
2424
 
 
2425
    Persp3D *persp = persp3d_get_from_repr(repr);
 
2426
    persp3d_update_box_reprs(persp);
 
2427
 
 
2428
    g_object_set_data(G_OBJECT(tbl), "freeze_attr", GINT_TO_POINTER(FALSE));
 
2429
}
 
2430
 
 
2431
static Inkscape::XML::NodeEventVector box3d_persp_tb_repr_events =
 
2432
{
 
2433
    NULL, /* child_added */
 
2434
    NULL, /* child_removed */
 
2435
    box3d_persp_tb_event_attr_changed,
 
2436
    NULL, /* content_changed */
 
2437
    NULL  /* order_changed */
 
2438
};
 
2439
 
 
2440
/**
 
2441
 *  \param selection Should not be NULL.
 
2442
 */
 
2443
// FIXME: This should rather be put into persp3d-reference.cpp or something similar so that it reacts upon each
 
2444
//        Change of the perspective, and not of the current selection (but how to refer to the toolbar then?)
 
2445
static void
 
2446
box3d_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl)
 
2447
{
 
2448
    // Here the following should be done: If all selected boxes have finite VPs in a certain direction,
 
2449
    // disable the angle entry fields for this direction (otherwise entering a value in them should only
 
2450
    // update the perspectives with infinite VPs and leave the other ones untouched).
 
2451
 
 
2452
    Inkscape::XML::Node *persp_repr = NULL;
 
2453
    purge_repr_listener(tbl, tbl);
 
2454
 
 
2455
    SPItem *item = selection->singleItem();
 
2456
    if (item && SP_IS_BOX3D(item)) {
 
2457
        // FIXME: Also deal with multiple selected boxes
 
2458
        SPBox3D *box = SP_BOX3D(item);
 
2459
        Persp3D *persp = box3d_get_perspective(box);
 
2460
        persp_repr = SP_OBJECT_REPR(persp);
 
2461
        if (persp_repr) {
 
2462
            g_object_set_data(tbl, "repr", persp_repr);
 
2463
            Inkscape::GC::anchor(persp_repr);
 
2464
            sp_repr_add_listener(persp_repr, &box3d_persp_tb_repr_events, tbl);
 
2465
            sp_repr_synthesize_events(persp_repr, &box3d_persp_tb_repr_events, tbl);
 
2466
        }
 
2467
 
 
2468
        inkscape_active_document()->current_persp3d = persp3d_get_from_repr(persp_repr);
 
2469
        prefs_set_string_attribute("tools.shapes.3dbox", "persp", persp_repr->attribute("id"));
 
2470
    
 
2471
        box3d_resync_toolbar(persp_repr, tbl);
 
2472
    }
 
2473
}
 
2474
 
 
2475
static void
 
2476
box3d_angle_value_changed(GtkAdjustment *adj, GObject *dataKludge, Proj::Axis axis)
 
2477
{
 
2478
    SPDesktop *desktop = (SPDesktop *) g_object_get_data( dataKludge, "desktop" );
 
2479
    SPDocument *document = sp_desktop_document(desktop);
 
2480
 
 
2481
    // quit if run by the attr_changed listener
 
2482
    // note: it used to work without the differently called freeze_ attributes (here and in
 
2483
    //       box3d_persp_tb_event_attr_changed()) but I now it doesn't so I'm leaving them in for now
 
2484
    if (g_object_get_data( dataKludge, "freeze_attr" )) {
 
2485
        return;
 
2486
    }
 
2487
 
 
2488
    // in turn, prevent listener from responding
 
2489
    g_object_set_data(dataKludge, "freeze_angle", GINT_TO_POINTER(TRUE));
 
2490
 
 
2491
    //Persp3D *persp = document->current_persp3d;
 
2492
    std::set<Persp3D *> sel_persps = persp3d_currently_selected_persps (inkscape_active_event_context());
 
2493
    if (sel_persps.empty()) {
 
2494
        // this can happen when the document is created; we silently ignore it
 
2495
        return;
 
2496
    }
 
2497
    Persp3D *persp = *(sel_persps.begin());
 
2498
 
 
2499
    persp->tmat.set_infinite_direction (axis, adj->value);
 
2500
    SP_OBJECT(persp)->updateRepr();
 
2501
 
 
2502
    // TODO: use the correct axis here, too
 
2503
    sp_document_maybe_done(document, "perspangle", SP_VERB_CONTEXT_3DBOX, _("3D Box: Change perspective (angle of infinite axis)"));
 
2504
 
 
2505
    g_object_set_data( dataKludge, "freeze_angle", GINT_TO_POINTER(FALSE) );
 
2506
}
 
2507
 
 
2508
 
 
2509
static void
 
2510
box3d_angle_x_value_changed(GtkAdjustment *adj, GObject *dataKludge)
 
2511
{
 
2512
    box3d_angle_value_changed(adj, dataKludge, Proj::X);
 
2513
}
 
2514
 
 
2515
static void
 
2516
box3d_angle_y_value_changed(GtkAdjustment *adj, GObject *dataKludge)
 
2517
{
 
2518
    box3d_angle_value_changed(adj, dataKludge, Proj::Y);
 
2519
}
 
2520
 
 
2521
static void
 
2522
box3d_angle_z_value_changed(GtkAdjustment *adj, GObject *dataKludge)
 
2523
{
 
2524
    box3d_angle_value_changed(adj, dataKludge, Proj::Z);
 
2525
}
 
2526
 
 
2527
 
 
2528
static void box3d_vp_state_changed( GtkToggleAction *act, GtkAction *box3d_angle, Proj::Axis axis )
 
2529
{
 
2530
    // TODO: Take all selected perspectives into account
 
2531
    std::set<Persp3D *> sel_persps = persp3d_currently_selected_persps (inkscape_active_event_context());
 
2532
    if (sel_persps.empty()) {
 
2533
        // this can happen when the document is created; we silently ignore it
 
2534
        return;
 
2535
    }
 
2536
    Persp3D *persp = *(sel_persps.begin());
 
2537
 
 
2538
    bool set_infinite = gtk_toggle_action_get_active(act);
 
2539
    persp3d_set_VP_state (persp, axis, set_infinite ? Proj::VP_INFINITE : Proj::VP_FINITE);
 
2540
}
 
2541
 
 
2542
static void box3d_vp_x_state_changed( GtkToggleAction *act, GtkAction *box3d_angle )
 
2543
{
 
2544
    box3d_vp_state_changed(act, box3d_angle, Proj::X);
 
2545
}
 
2546
 
 
2547
static void box3d_vp_y_state_changed( GtkToggleAction *act, GtkAction *box3d_angle )
 
2548
{
 
2549
    box3d_vp_state_changed(act, box3d_angle, Proj::Y);
 
2550
}
 
2551
 
 
2552
static void box3d_vp_z_state_changed( GtkToggleAction *act, GtkAction *box3d_angle )
 
2553
{
 
2554
    box3d_vp_state_changed(act, box3d_angle, Proj::Z);
 
2555
}
 
2556
 
 
2557
static void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
 
2558
{
 
2559
    EgeAdjustmentAction* eact = 0;
 
2560
    SPDocument *document = sp_desktop_document (desktop);
 
2561
    Persp3D *persp = document->current_persp3d;
 
2562
 
 
2563
    EgeAdjustmentAction* box3d_angle_x = 0;
 
2564
    EgeAdjustmentAction* box3d_angle_y = 0;
 
2565
    EgeAdjustmentAction* box3d_angle_z = 0;
 
2566
 
 
2567
    /* Angle X */
 
2568
    {
 
2569
        gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0 };
 
2570
        gdouble values[] = {-90, -60, -30, 0, 30, 60, 90};
 
2571
        eact = create_adjustment_action( "3DBoxAngleXAction",
 
2572
                                         _("Angle in X direction"), _("Angle X:"),
 
2573
                                         // Translators: PL is short for 'perspective line'
 
2574
                                         _("Angle of PLs in X direction"),
 
2575
                                         "tools.shapes.3dbox", "box3d_angle_x", 30,
 
2576
                                         GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "altx-box3d",
 
2577
                                         -360.0, 360.0, 1.0, 10.0,
 
2578
                                         labels, values, G_N_ELEMENTS(labels),
 
2579
                                         box3d_angle_x_value_changed );
 
2580
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
 
2581
        g_object_set_data( holder, "box3d_angle_x_action", eact );
 
2582
        box3d_angle_x = eact;
 
2583
    }
 
2584
 
 
2585
    if (!persp3d_VP_is_finite(persp, Proj::X)) {
 
2586
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
 
2587
    } else {
 
2588
        gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
 
2589
    }
 
2590
 
 
2591
 
 
2592
    /* VP X state */
 
2593
    {
 
2594
        InkToggleAction* act = ink_toggle_action_new( "3DBoxVPXStateAction",
 
2595
                                                      // Translators: VP is short for 'vanishing point'
 
2596
                                                      _("State of VP in X direction"),
 
2597
                                                      _("Toggle VP in X direction between 'finite' and 'infinite' (=parallel)"),
 
2598
                                                      "toggle_vp_x",
 
2599
                                                      Inkscape::ICON_SIZE_DECORATION );
 
2600
        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
 
2601
        g_object_set_data( holder, "box3d_vp_x_state_action", act );
 
2602
        g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(box3d_vp_x_state_changed), box3d_angle_x );
 
2603
        gtk_action_set_sensitive( GTK_ACTION(box3d_angle_x), !prefs_get_int_attribute( "tools.shapes.3dbox", "vp_x_state", 1 ) );
 
2604
        gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.shapes.3dbox", "vp_x_state", 1 ) );
 
2605
    }
 
2606
 
 
2607
    /* Angle Y */
 
2608
    {
 
2609
        gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0 };
 
2610
        gdouble values[] = {-90, -60, -30, 0, 30, 60, 90};
 
2611
        eact = create_adjustment_action( "3DBoxAngleYAction",
 
2612
                                         _("Angle in Y direction"), _("Angle Y:"),
 
2613
                                         // Translators: PL is short for 'perspective line'
 
2614
                                         _("Angle of PLs in Y direction"),
 
2615
                                         "tools.shapes.3dbox", "box3d_angle_y", 30,
 
2616
                                         GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
 
2617
                                         -360.0, 360.0, 1.0, 10.0,
 
2618
                                         labels, values, G_N_ELEMENTS(labels),
 
2619
                                         box3d_angle_y_value_changed );
 
2620
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
 
2621
        g_object_set_data( holder, "box3d_angle_y_action", eact );
 
2622
        box3d_angle_y = eact;
 
2623
    }
 
2624
 
 
2625
    if (!persp3d_VP_is_finite(persp, Proj::Y)) {
 
2626
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
 
2627
    } else {
 
2628
        gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
 
2629
    }
 
2630
 
 
2631
    /* VP Y state */
 
2632
    {
 
2633
        InkToggleAction* act = ink_toggle_action_new( "3DBoxVPYStateAction",
 
2634
                                                      // Translators: VP is short for 'vanishing point'
 
2635
                                                      _("State of VP in Y direction"),
 
2636
                                                      _("Toggle VP in Y direction between 'finite' and 'infinite' (=parallel)"),
 
2637
                                                      "toggle_vp_y",
 
2638
                                                      Inkscape::ICON_SIZE_DECORATION );
 
2639
        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
 
2640
        g_object_set_data( holder, "box3d_vp_y_state_action", act );
 
2641
        g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(box3d_vp_y_state_changed), box3d_angle_y );
 
2642
        gtk_action_set_sensitive( GTK_ACTION(box3d_angle_y), !prefs_get_int_attribute( "tools.shapes.3dbox", "vp_y_state", 1 ) );
 
2643
        gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.shapes.3dbox", "vp_y_state", 1 ) );
 
2644
    }
 
2645
 
 
2646
    /* Angle Z */
 
2647
    {
 
2648
        gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0 };
 
2649
        gdouble values[] = {-90, -60, -30, 0, 30, 60, 90};
 
2650
        eact = create_adjustment_action( "3DBoxAngleZAction",
 
2651
                                         _("Angle in Z direction"), _("Angle Z:"),
 
2652
                                         // Translators: PL is short for 'perspective line'
 
2653
                                         _("Angle of PLs in Z direction"),
 
2654
                                         "tools.shapes.3dbox", "box3d_angle_z", 30,
 
2655
                                         GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
 
2656
                                         -360.0, 360.0, 1.0, 10.0,
 
2657
                                         labels, values, G_N_ELEMENTS(labels),
 
2658
                                         box3d_angle_z_value_changed );
 
2659
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
 
2660
        g_object_set_data( holder, "box3d_angle_z_action", eact );
 
2661
        box3d_angle_z = eact;
 
2662
    }
 
2663
 
 
2664
    if (!persp3d_VP_is_finite(persp, Proj::Z)) {
 
2665
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
 
2666
    } else {
 
2667
        gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
 
2668
    }
 
2669
 
 
2670
    /* VP Z state */
 
2671
    {
 
2672
        InkToggleAction* act = ink_toggle_action_new( "3DBoxVPZStateAction",
 
2673
                                                      // Translators: VP is short for 'vanishing point'
 
2674
                                                      _("State of VP in Z direction"),
 
2675
                                                      _("Toggle VP in Z direction between 'finite' and 'infinite' (=parallel)"),
 
2676
                                                      "toggle_vp_z",
 
2677
                                                      Inkscape::ICON_SIZE_DECORATION );
 
2678
        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
 
2679
        g_object_set_data( holder, "box3d_vp_z_state_action", act );
 
2680
        g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(box3d_vp_z_state_changed), box3d_angle_z );
 
2681
        gtk_action_set_sensitive( GTK_ACTION(box3d_angle_z), !prefs_get_int_attribute( "tools.shapes.3dbox", "vp_z_state", 1 ) );
 
2682
        gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.shapes.3dbox", "vp_z_state", 1 ) );
 
2683
    }
 
2684
 
 
2685
    sigc::connection *connection = new sigc::connection(
 
2686
        sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(box3d_toolbox_selection_changed), (GObject *)holder))
 
2687
       );
 
2688
    g_signal_connect(holder, "destroy", G_CALLBACK(delete_connection), connection);
 
2689
    g_signal_connect(holder, "destroy", G_CALLBACK(purge_repr_listener), holder);
1688
2690
}
1689
2691
 
1690
2692
//########################
1692
2694
//########################
1693
2695
 
1694
2696
static void
1695
 
sp_spl_tb_value_changed(GtkAdjustment *adj, GtkWidget *tbl, gchar const *value_name)
 
2697
sp_spl_tb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *value_name)
1696
2698
{
1697
 
    SPDesktop *desktop = (SPDesktop *) gtk_object_get_data(GTK_OBJECT(tbl), "desktop");
 
2699
    SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" );
1698
2700
 
1699
2701
    if (sp_document_get_undo_sensitive(sp_desktop_document(desktop))) {
1700
2702
        prefs_set_double_attribute("tools.shapes.spiral", value_name, adj->value);
1701
2703
    }
1702
2704
 
1703
2705
    // quit if run by the attr_changed listener
1704
 
    if (g_object_get_data(G_OBJECT(tbl), "freeze")) {
 
2706
    if (g_object_get_data( tbl, "freeze" )) {
1705
2707
        return;
1706
2708
    }
1707
2709
 
1708
2710
    // in turn, prevent listener from responding
1709
 
    g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE));
 
2711
    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) );
1710
2712
 
1711
2713
    gchar* namespaced_name = g_strconcat("sodipodi:", value_name, NULL);
1712
2714
 
1726
2728
    g_free(namespaced_name);
1727
2729
 
1728
2730
    if (modmade) {
1729
 
        sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_SPIRAL, 
 
2731
        sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_SPIRAL,
1730
2732
                                   _("Change spiral"));
1731
2733
    }
1732
2734
 
1733
 
    g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(FALSE));
1734
 
 
1735
 
    spinbutton_defocus(GTK_OBJECT(tbl));
 
2735
    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
1736
2736
}
1737
2737
 
1738
2738
static void
1739
 
sp_spl_tb_revolution_value_changed(GtkAdjustment *adj, GtkWidget *tbl)
 
2739
sp_spl_tb_revolution_value_changed(GtkAdjustment *adj, GObject *tbl)
1740
2740
{
1741
2741
    sp_spl_tb_value_changed(adj, tbl, "revolution");
1742
2742
}
1743
2743
 
1744
2744
static void
1745
 
sp_spl_tb_expansion_value_changed(GtkAdjustment *adj, GtkWidget *tbl)
 
2745
sp_spl_tb_expansion_value_changed(GtkAdjustment *adj, GObject *tbl)
1746
2746
{
1747
2747
    sp_spl_tb_value_changed(adj, tbl, "expansion");
1748
2748
}
1749
2749
 
1750
2750
static void
1751
 
sp_spl_tb_t0_value_changed(GtkAdjustment *adj, GtkWidget *tbl)
 
2751
sp_spl_tb_t0_value_changed(GtkAdjustment *adj, GObject *tbl)
1752
2752
{
1753
2753
    sp_spl_tb_value_changed(adj, tbl, "t0");
1754
2754
}
1755
2755
 
1756
2756
static void
1757
 
sp_spl_tb_defaults(GtkWidget *widget, GtkObject *obj)
 
2757
sp_spl_tb_defaults(GtkWidget */*widget*/, GtkObject *obj)
1758
2758
{
1759
2759
    GtkWidget *tbl = GTK_WIDGET(obj);
1760
2760
 
1781
2781
}
1782
2782
 
1783
2783
 
1784
 
static void spiral_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const *name,
1785
 
                                         gchar const *old_value, gchar const *new_value,
1786
 
                                         bool is_interactive, gpointer data)
 
2784
static void spiral_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const */*name*/,
 
2785
                                         gchar const */*old_value*/, gchar const */*new_value*/,
 
2786
                                         bool /*is_interactive*/, gpointer data)
1787
2787
{
1788
2788
    GtkWidget *tbl = GTK_WIDGET(data);
1789
2789
 
1818
2818
};
1819
2819
 
1820
2820
static void
1821
 
sp_spiral_toolbox_selection_changed(Inkscape::Selection *selection, GtkObject *tbl)
 
2821
sp_spiral_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl)
1822
2822
{
1823
2823
    int n_selected = 0;
1824
2824
    Inkscape::XML::Node *repr = NULL;
1825
 
    Inkscape::XML::Node *oldrepr = NULL;
 
2825
 
 
2826
    purge_repr_listener( tbl, tbl );
1826
2827
 
1827
2828
    for (GSList const *items = selection->itemList();
1828
2829
         items != NULL;
1834
2835
        }
1835
2836
    }
1836
2837
 
1837
 
    GtkWidget *l = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(tbl), "mode_label"));
 
2838
    EgeOutputAction* act = EGE_OUTPUT_ACTION( g_object_get_data( tbl, "mode_action" ) );
1838
2839
 
1839
2840
    if (n_selected == 0) {
1840
 
        gtk_label_set_markup(GTK_LABEL(l), _("<b>New:</b>"));
 
2841
        g_object_set( G_OBJECT(act), "label", _("<b>New:</b>"), NULL );
1841
2842
    } else if (n_selected == 1) {
1842
 
        gtk_label_set_markup(GTK_LABEL(l), _("<b>Change:</b>"));
1843
 
 
1844
 
        oldrepr = (Inkscape::XML::Node *) gtk_object_get_data(GTK_OBJECT(tbl), "repr");
1845
 
        if (oldrepr) { // remove old listener
1846
 
            sp_repr_remove_listener_by_data(oldrepr, tbl);
1847
 
            Inkscape::GC::release(oldrepr);
1848
 
            oldrepr = 0;
1849
 
            g_object_set_data(G_OBJECT(tbl), "repr", NULL);
1850
 
        }
 
2843
        g_object_set( G_OBJECT(act), "label", _("<b>Change:</b>"), NULL );
1851
2844
 
1852
2845
        if (repr) {
1853
 
            g_object_set_data(G_OBJECT(tbl), "repr", repr);
 
2846
            g_object_set_data( tbl, "repr", repr );
1854
2847
            Inkscape::GC::anchor(repr);
1855
2848
            sp_repr_add_listener(repr, &spiral_tb_repr_events, tbl);
1856
2849
            sp_repr_synthesize_events(repr, &spiral_tb_repr_events, tbl);
1858
2851
    } else {
1859
2852
        // FIXME: implement averaging of all parameters for multiple selected
1860
2853
        //gtk_label_set_markup(GTK_LABEL(l), _("<b>Average:</b>"));
1861
 
        gtk_label_set_markup(GTK_LABEL(l), _("<b>Change:</b>"));
 
2854
        g_object_set( G_OBJECT(act), "label", _("<b>Change:</b>"), NULL );
1862
2855
    }
1863
2856
}
1864
2857
 
1865
2858
 
1866
 
static GtkWidget *
1867
 
sp_spiral_toolbox_new(SPDesktop *desktop)
 
2859
static void sp_spiral_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
1868
2860
{
1869
 
    GtkWidget *tbl = gtk_hbox_new(FALSE, 0);
1870
 
    gtk_object_set_data(GTK_OBJECT(tbl), "dtw", desktop->canvas);
1871
 
    gtk_object_set_data(GTK_OBJECT(tbl), "desktop", desktop);
1872
 
 
1873
 
    GtkTooltips *tt = gtk_tooltips_new();
1874
 
 
1875
 
    sp_toolbox_add_label(tbl, _("<b>New:</b>"));
 
2861
    EgeAdjustmentAction* eact = 0;
 
2862
 
 
2863
    {
 
2864
        EgeOutputAction* act = ege_output_action_new( "SpiralStateAction", _("<b>New:</b>"), "", 0 );
 
2865
        ege_output_action_set_use_markup( act, TRUE );
 
2866
        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
 
2867
        g_object_set_data( holder, "mode_action", act );
 
2868
    }
1876
2869
 
1877
2870
    /* Revolution */
1878
2871
    {
1879
 
        GtkWidget *hb = sp_tb_spinbutton(_("Turns:"), _("Number of revolutions"),
 
2872
        gchar const* labels[] = {_("just a curve"), 0, _("one full revolution"), 0, 0, 0, 0, 0, 0};
 
2873
        gdouble values[] = {0.01, 0.5, 1, 2, 3, 5, 10, 20, 50, 100};
 
2874
        eact = create_adjustment_action( "SpiralRevolutionAction",
 
2875
                                         _("Number of turns"), _("Turns:"), _("Number of revolutions"),
1880
2876
                                         "tools.shapes.spiral", "revolution", 3.0,
1881
 
                                         NULL, tbl, TRUE, "altx-spiral",
 
2877
                                         GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "altx-spiral",
1882
2878
                                         0.01, 1024.0, 0.1, 1.0,
 
2879
                                         labels, values, G_N_ELEMENTS(labels),
1883
2880
                                         sp_spl_tb_revolution_value_changed, 1, 2);
1884
 
        gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, AUX_SPACING);
 
2881
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
1885
2882
    }
1886
2883
 
1887
2884
    /* Expansion */
1888
2885
    {
1889
 
        GtkWidget *hb = sp_tb_spinbutton(_("Divergence:"), _("How much denser/sparser are outer revolutions; 1 = uniform"),
 
2886
        gchar const* labels[] = {_("circle"), _("edge is much denser"), _("edge is denser"), _("even"), _("center is denser"), _("center is much denser"), 0};
 
2887
        gdouble values[] = {0, 0.1, 0.5, 1, 1.5, 5, 20};
 
2888
        eact = create_adjustment_action( "SpiralExpansionAction",
 
2889
                                         _("Divergence"), _("Divergence:"), _("How much denser/sparser are outer revolutions; 1 = uniform"),
1890
2890
                                         "tools.shapes.spiral", "expansion", 1.0,
1891
 
                                         NULL, tbl, FALSE, NULL,
 
2891
                                         GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
1892
2892
                                         0.0, 1000.0, 0.01, 1.0,
 
2893
                                         labels, values, G_N_ELEMENTS(labels),
1893
2894
                                         sp_spl_tb_expansion_value_changed);
1894
 
        gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, AUX_SPACING);
 
2895
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
1895
2896
    }
1896
2897
 
1897
2898
    /* T0 */
1898
2899
    {
1899
 
        GtkWidget *hb = sp_tb_spinbutton(_("Inner radius:"), _("Radius of the innermost revolution (relative to the spiral size)"),
 
2900
        gchar const* labels[] = {_("starts from center"), _("starts mid-way"), _("starts near edge")};
 
2901
        gdouble values[] = {0, 0.5, 0.9};
 
2902
        eact = create_adjustment_action( "SpiralT0Action",
 
2903
                                         _("Inner radius"), _("Inner radius:"), _("Radius of the innermost revolution (relative to the spiral size)"),
1900
2904
                                         "tools.shapes.spiral", "t0", 0.0,
1901
 
                                         NULL, tbl, FALSE, NULL,
 
2905
                                         GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
1902
2906
                                         0.0, 0.999, 0.01, 1.0,
 
2907
                                         labels, values, G_N_ELEMENTS(labels),
1903
2908
                                         sp_spl_tb_t0_value_changed);
1904
 
        gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, AUX_SPACING);
 
2909
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
1905
2910
    }
1906
2911
 
1907
 
    aux_toolbox_space(tbl, AUX_SPACING);
1908
 
 
1909
2912
    /* Reset */
1910
2913
    {
1911
 
        GtkWidget *hb = gtk_hbox_new(FALSE, 1);
1912
 
        GtkWidget *b = gtk_button_new_with_label(_("Defaults"));
1913
 
        gtk_tooltips_set_tip(tt, b, _("Reset shape parameters to defaults (use Inkscape Preferences > Tools to change defaults)"), NULL);
1914
 
        gtk_widget_show(b);
1915
 
        gtk_container_add(GTK_CONTAINER(hb), b);
1916
 
        gtk_signal_connect(GTK_OBJECT(b), "clicked", GTK_SIGNAL_FUNC(sp_spl_tb_defaults), tbl);
1917
 
        gtk_box_pack_start(GTK_BOX(tbl),hb, FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
 
2914
        InkAction* inky = ink_action_new( "SpiralResetAction",
 
2915
                                          _("Defaults"),
 
2916
                                          _("Reset shape parameters to defaults (use Inkscape Preferences > Tools to change defaults)"),
 
2917
                                          GTK_STOCK_CLEAR,
 
2918
                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
 
2919
        g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_spl_tb_defaults), holder );
 
2920
        gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
1918
2921
    }
1919
2922
 
1920
 
    Inkscape::UI::Widget::StyleSwatch *swatch = new Inkscape::UI::Widget::StyleSwatch(NULL);
1921
 
    swatch->setWatchedTool ("tools.shapes.spiral", true);
1922
 
    GtkWidget *swatch_ = GTK_WIDGET(swatch->gobj());
1923
 
    gtk_box_pack_end(GTK_BOX(tbl), swatch_, FALSE, FALSE, 0);
1924
 
 
1925
 
    gtk_widget_show_all(tbl);
1926
 
    sp_set_font_size_smaller (tbl);
1927
2923
 
1928
2924
    sigc::connection *connection = new sigc::connection(
1929
 
        sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_spiral_toolbox_selection_changed), (GtkObject *)tbl))
 
2925
        sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_spiral_toolbox_selection_changed), (GObject *)holder))
1930
2926
        );
1931
 
    g_signal_connect(G_OBJECT(tbl), "destroy", G_CALLBACK(delete_connection), connection);
1932
 
 
1933
 
    return tbl;
 
2927
    g_signal_connect( holder, "destroy", G_CALLBACK(delete_connection), connection );
 
2928
    g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder );
1934
2929
}
1935
2930
 
1936
2931
//########################
1938
2933
//########################
1939
2934
 
1940
2935
 
1941
 
static GtkWidget *
1942
 
sp_pen_toolbox_new(SPDesktop *desktop)
1943
 
{
1944
 
    GtkWidget *tbl = gtk_hbox_new(FALSE, 0);
1945
 
    gtk_object_set_data(GTK_OBJECT(tbl), "dtw", desktop->canvas);
1946
 
    gtk_object_set_data(GTK_OBJECT(tbl), "desktop", desktop);
1947
 
 
1948
 
    Inkscape::UI::Widget::StyleSwatch *swatch = new Inkscape::UI::Widget::StyleSwatch(NULL);
1949
 
    swatch->setWatchedTool ("tools.freehand.pen", true);
1950
 
    GtkWidget *swatch_ = GTK_WIDGET(swatch->gobj());
1951
 
    gtk_box_pack_end(GTK_BOX(tbl), swatch_, FALSE, FALSE, 0);
1952
 
 
1953
 
    gtk_widget_show_all(tbl);
1954
 
    sp_set_font_size_smaller (tbl);
1955
 
 
1956
 
    return tbl;
1957
 
}
1958
 
 
1959
 
static GtkWidget *
1960
 
sp_pencil_toolbox_new(SPDesktop *desktop)
1961
 
{
1962
 
    GtkWidget *tbl = gtk_hbox_new(FALSE, 0);
1963
 
    gtk_object_set_data(GTK_OBJECT(tbl), "dtw", desktop->canvas);
1964
 
    gtk_object_set_data(GTK_OBJECT(tbl), "desktop", desktop);
1965
 
 
1966
 
    Inkscape::UI::Widget::StyleSwatch *swatch = new Inkscape::UI::Widget::StyleSwatch(NULL);
1967
 
    swatch->setWatchedTool ("tools.freehand.pencil", true);
1968
 
    GtkWidget *swatch_ = GTK_WIDGET(swatch->gobj());
1969
 
    gtk_box_pack_end(GTK_BOX(tbl), swatch_, FALSE, FALSE, 0);
1970
 
 
1971
 
    gtk_widget_show_all(tbl);
1972
 
    sp_set_font_size_smaller (tbl);
1973
 
 
1974
 
    return tbl;
 
2936
static void sp_pen_toolbox_prep(SPDesktop */*desktop*/, GtkActionGroup* /*mainActions*/, GObject* /*holder*/)
 
2937
{
 
2938
    // Put stuff here
 
2939
}
 
2940
 
 
2941
static void sp_pencil_toolbox_prep(SPDesktop */*desktop*/, GtkActionGroup* /*mainActions*/, GObject* /*holder*/)
 
2942
{
 
2943
    // Put stuff here
 
2944
}
 
2945
 
 
2946
//########################
 
2947
//##       Tweak        ##
 
2948
//########################
 
2949
 
 
2950
static void sp_tweak_width_value_changed( GtkAdjustment *adj, GObject */*tbl*/ )
 
2951
{
 
2952
    prefs_set_double_attribute( "tools.tweak", "width", adj->value * 0.01 );
 
2953
}
 
2954
 
 
2955
static void sp_tweak_force_value_changed( GtkAdjustment *adj, GObject */*tbl*/ )
 
2956
{
 
2957
    prefs_set_double_attribute( "tools.tweak", "force", adj->value * 0.01 );
 
2958
}
 
2959
 
 
2960
static void sp_tweak_pressure_state_changed( GtkToggleAction *act, gpointer /*data*/ )
 
2961
{
 
2962
    prefs_set_int_attribute( "tools.tweak", "usepressure", gtk_toggle_action_get_active( act ) ? 1 : 0);
 
2963
}
 
2964
 
 
2965
static void sp_tweak_mode_changed( EgeSelectOneAction *act, GObject *tbl )
 
2966
{
 
2967
    int mode = ege_select_one_action_get_active( act );
 
2968
    prefs_set_int_attribute("tools.tweak", "mode", mode);
 
2969
 
 
2970
    GtkAction *doh = GTK_ACTION(g_object_get_data( tbl, "tweak_doh"));
 
2971
    GtkAction *dos = GTK_ACTION(g_object_get_data( tbl, "tweak_dos"));
 
2972
    GtkAction *dol = GTK_ACTION(g_object_get_data( tbl, "tweak_dol"));
 
2973
    GtkAction *doo = GTK_ACTION(g_object_get_data( tbl, "tweak_doo"));
 
2974
    GtkAction *fid = GTK_ACTION(g_object_get_data( tbl, "tweak_fidelity"));
 
2975
    GtkAction *dolabel = GTK_ACTION(g_object_get_data( tbl, "tweak_channels_label"));
 
2976
    if (mode == TWEAK_MODE_COLORPAINT || mode == TWEAK_MODE_COLORJITTER) {
 
2977
        if (doh) gtk_action_set_sensitive (doh, TRUE);
 
2978
        if (dos) gtk_action_set_sensitive (dos, TRUE);
 
2979
        if (dol) gtk_action_set_sensitive (dol, TRUE);
 
2980
        if (doo) gtk_action_set_sensitive (doo, TRUE);
 
2981
        if (dolabel) gtk_action_set_sensitive (dolabel, TRUE);
 
2982
        if (fid) gtk_action_set_sensitive (fid, FALSE);
 
2983
    } else {
 
2984
        if (doh) gtk_action_set_sensitive (doh, FALSE);
 
2985
        if (dos) gtk_action_set_sensitive (dos, FALSE);
 
2986
        if (dol) gtk_action_set_sensitive (dol, FALSE);
 
2987
        if (doo) gtk_action_set_sensitive (doo, FALSE);
 
2988
        if (dolabel) gtk_action_set_sensitive (dolabel, FALSE);
 
2989
        if (fid) gtk_action_set_sensitive (fid, TRUE);
 
2990
    }
 
2991
}
 
2992
 
 
2993
static void sp_tweak_fidelity_value_changed( GtkAdjustment *adj, GObject */*tbl*/ )
 
2994
{
 
2995
    prefs_set_double_attribute( "tools.tweak", "fidelity", adj->value * 0.01 );
 
2996
}
 
2997
 
 
2998
static void tweak_toggle_doh (GtkToggleAction *act, gpointer /*data*/) {
 
2999
    bool show = gtk_toggle_action_get_active( act );
 
3000
    prefs_set_int_attribute ("tools.tweak", "doh",  show ? 1 : 0);
 
3001
}
 
3002
static void tweak_toggle_dos (GtkToggleAction *act, gpointer /*data*/) {
 
3003
    bool show = gtk_toggle_action_get_active( act );
 
3004
    prefs_set_int_attribute ("tools.tweak", "dos",  show ? 1 : 0);
 
3005
}
 
3006
static void tweak_toggle_dol (GtkToggleAction *act, gpointer /*data*/) {
 
3007
    bool show = gtk_toggle_action_get_active( act );
 
3008
    prefs_set_int_attribute ("tools.tweak", "dol",  show ? 1 : 0);
 
3009
}
 
3010
static void tweak_toggle_doo (GtkToggleAction *act, gpointer /*data*/) {
 
3011
    bool show = gtk_toggle_action_get_active( act );
 
3012
    prefs_set_int_attribute ("tools.tweak", "doo",  show ? 1 : 0);
 
3013
}
 
3014
 
 
3015
static void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
 
3016
{
 
3017
    {
 
3018
        /* Width */
 
3019
        gchar const* labels[] = {_("(pinch tweak)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad tweak)")};
 
3020
        gdouble values[] = {1, 3, 5, 10, 15, 20, 30, 50, 75, 100};
 
3021
        EgeAdjustmentAction *eact = create_adjustment_action( "TweakWidthAction",
 
3022
                                                              _("Width"), _("Width:"), _("The width of the tweak area (relative to the visible canvas area)"),
 
3023
                                                              "tools.tweak", "width", 15,
 
3024
                                                              GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "altx-tweak",
 
3025
                                                              1, 100, 1.0, 10.0,
 
3026
                                                              labels, values, G_N_ELEMENTS(labels),
 
3027
                                                              sp_tweak_width_value_changed,  0.01, 0, 100 );
 
3028
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
 
3029
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
 
3030
    }
 
3031
 
 
3032
 
 
3033
    {
 
3034
        /* Force */
 
3035
        gchar const* labels[] = {_("(minimum force)"), 0, 0, _("(default)"), 0, 0, 0, _("(maximum force)")};
 
3036
        gdouble values[] = {1, 5, 10, 20, 30, 50, 70, 100};
 
3037
        EgeAdjustmentAction *eact = create_adjustment_action( "TweakForceAction",
 
3038
                                                              _("Force"), _("Force:"), _("The force of the tweak action"),
 
3039
                                                              "tools.tweak", "force", 20,
 
3040
                                                              GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "tweak-force",
 
3041
                                                              1, 100, 1.0, 10.0,
 
3042
                                                              labels, values, G_N_ELEMENTS(labels),
 
3043
                                                              sp_tweak_force_value_changed,  0.01, 0, 100 );
 
3044
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
 
3045
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
 
3046
    }
 
3047
 
 
3048
    /* Mode */
 
3049
    {
 
3050
        GtkListStore* model = gtk_list_store_new( 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING );
 
3051
 
 
3052
        GtkTreeIter iter;
 
3053
        gtk_list_store_append( model, &iter );
 
3054
        gtk_list_store_set( model, &iter,
 
3055
                            0, _("Push mode"),
 
3056
                            1, _("Push parts of paths in any direction"),
 
3057
                            2, "tweak_push_mode",
 
3058
                            -1 );
 
3059
 
 
3060
        gtk_list_store_append( model, &iter );
 
3061
        gtk_list_store_set( model, &iter,
 
3062
                            0, _("Shrink mode"),
 
3063
                            1, _("Shrink (inset) parts of paths"),
 
3064
                            2, "tweak_shrink_mode",
 
3065
                            -1 );
 
3066
 
 
3067
        gtk_list_store_append( model, &iter );
 
3068
        gtk_list_store_set( model, &iter,
 
3069
                            0, _("Grow mode"),
 
3070
                            1, _("Grow (outset) parts of paths"),
 
3071
                            2, "tweak_grow_mode",
 
3072
                            -1 );
 
3073
 
 
3074
        gtk_list_store_append( model, &iter );
 
3075
        gtk_list_store_set( model, &iter,
 
3076
                            0, _("Attract mode"),
 
3077
                            1, _("Attract parts of paths towards cursor"),
 
3078
                            2, "tweak_attract_mode",
 
3079
                            -1 );
 
3080
 
 
3081
        gtk_list_store_append( model, &iter );
 
3082
        gtk_list_store_set( model, &iter,
 
3083
                            0, _("Repel mode"),
 
3084
                            1, _("Repel parts of paths from cursor"),
 
3085
                            2, "tweak_repel_mode",
 
3086
                            -1 );
 
3087
 
 
3088
        gtk_list_store_append( model, &iter );
 
3089
        gtk_list_store_set( model, &iter,
 
3090
                            0, _("Roughen mode"),
 
3091
                            1, _("Roughen parts of paths"),
 
3092
                            2, "tweak_roughen_mode",
 
3093
                            -1 );
 
3094
 
 
3095
        gtk_list_store_append( model, &iter );
 
3096
        gtk_list_store_set( model, &iter,
 
3097
                            0, _("Color paint mode"),
 
3098
                            1, _("Paint the tool's color upon selected objects"),
 
3099
                            2, "tweak_colorpaint_mode",
 
3100
                            -1 );
 
3101
 
 
3102
        gtk_list_store_append( model, &iter );
 
3103
        gtk_list_store_set( model, &iter,
 
3104
                            0, _("Color jitter mode"),
 
3105
                            1, _("Jitter the colors of selected objects"),
 
3106
                            2, "tweak_colorjitter_mode",
 
3107
                            -1 );
 
3108
 
 
3109
        EgeSelectOneAction* act = ege_select_one_action_new( "TweakModeAction", _("Mode"), (""), NULL, GTK_TREE_MODEL(model) );
 
3110
        g_object_set( act, "short_label", _("Mode:"), NULL );
 
3111
        gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
 
3112
        g_object_set_data( holder, "mode_action", act );
 
3113
 
 
3114
        ege_select_one_action_set_appearance( act, "full" );
 
3115
        ege_select_one_action_set_radio_action_type( act, INK_RADIO_ACTION_TYPE );
 
3116
        g_object_set( G_OBJECT(act), "icon-property", "iconId", NULL );
 
3117
        ege_select_one_action_set_icon_column( act, 2 );
 
3118
        ege_select_one_action_set_tooltip_column( act, 1  );
 
3119
 
 
3120
        gint mode = prefs_get_int_attribute("tools.tweak", "mode", 0);
 
3121
        ege_select_one_action_set_active( act, mode );
 
3122
        g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_tweak_mode_changed), holder );
 
3123
 
 
3124
        g_object_set_data( G_OBJECT(holder), "tweak_tool_mode", act);
 
3125
    }
 
3126
 
 
3127
    guint mode = prefs_get_int_attribute("tools.tweak", "mode", 0);
 
3128
 
 
3129
    {
 
3130
        EgeOutputAction* act = ege_output_action_new( "TweakChannelsLabel", _("Channels:"), "", 0 );
 
3131
        ege_output_action_set_use_markup( act, TRUE );
 
3132
        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
 
3133
        if (mode != TWEAK_MODE_COLORPAINT && mode != TWEAK_MODE_COLORJITTER)
 
3134
            gtk_action_set_sensitive (GTK_ACTION(act), FALSE);
 
3135
        g_object_set_data( holder, "tweak_channels_label", act);
 
3136
    }
 
3137
 
 
3138
    {
 
3139
        InkToggleAction* act = ink_toggle_action_new( "TweakDoH",
 
3140
                                                      _("Hue"),
 
3141
                                                      _("In color mode, act on objects' hue"),
 
3142
                                                      NULL,
 
3143
                                                      Inkscape::ICON_SIZE_DECORATION );
 
3144
        g_object_set( act, "short_label", _("H"), NULL );
 
3145
        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
 
3146
        g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_doh), desktop );
 
3147
        gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.tweak", "doh", 1 ) );
 
3148
        if (mode != TWEAK_MODE_COLORPAINT && mode != TWEAK_MODE_COLORJITTER)
 
3149
            gtk_action_set_sensitive (GTK_ACTION(act), FALSE);
 
3150
        g_object_set_data( holder, "tweak_doh", act);
 
3151
    }
 
3152
    {
 
3153
        InkToggleAction* act = ink_toggle_action_new( "TweakDoS",
 
3154
                                                      _("Saturation"),
 
3155
                                                      _("In color mode, act on objects' saturation"),
 
3156
                                                      NULL,
 
3157
                                                      Inkscape::ICON_SIZE_DECORATION );
 
3158
        g_object_set( act, "short_label", _("S"), NULL );
 
3159
        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
 
3160
        g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_dos), desktop );
 
3161
        gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.tweak", "dos", 1 ) );
 
3162
        if (mode != TWEAK_MODE_COLORPAINT && mode != TWEAK_MODE_COLORJITTER)
 
3163
            gtk_action_set_sensitive (GTK_ACTION(act), FALSE);
 
3164
        g_object_set_data( holder, "tweak_dos", act );
 
3165
    }
 
3166
    {
 
3167
        InkToggleAction* act = ink_toggle_action_new( "TweakDoL",
 
3168
                                                      _("Lightness"),
 
3169
                                                      _("In color mode, act on objects' lightness"),
 
3170
                                                      NULL,
 
3171
                                                      Inkscape::ICON_SIZE_DECORATION );
 
3172
        g_object_set( act, "short_label", _("L"), NULL );
 
3173
        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
 
3174
        g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_dol), desktop );
 
3175
        gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.tweak", "dol", 1 ) );
 
3176
        if (mode != TWEAK_MODE_COLORPAINT && mode != TWEAK_MODE_COLORJITTER)
 
3177
            gtk_action_set_sensitive (GTK_ACTION(act), FALSE);
 
3178
        g_object_set_data( holder, "tweak_dol", act );
 
3179
    }
 
3180
    {
 
3181
        InkToggleAction* act = ink_toggle_action_new( "TweakDoO",
 
3182
                                                      _("Opacity"),
 
3183
                                                      _("In color mode, act on objects' opacity"),
 
3184
                                                      NULL,
 
3185
                                                      Inkscape::ICON_SIZE_DECORATION );
 
3186
        g_object_set( act, "short_label", _("O"), NULL );
 
3187
        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
 
3188
        g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_doo), desktop );
 
3189
        gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.tweak", "doo", 1 ) );
 
3190
        if (mode != TWEAK_MODE_COLORPAINT && mode != TWEAK_MODE_COLORJITTER)
 
3191
            gtk_action_set_sensitive (GTK_ACTION(act), FALSE);
 
3192
        g_object_set_data( holder, "tweak_doo", act );
 
3193
    }
 
3194
 
 
3195
    {   /* Fidelity */
 
3196
        gchar const* labels[] = {_("(rough, simplified)"), 0, 0, _("(default)"), 0, 0, _("(fine, but many nodes)")};
 
3197
        gdouble values[] = {10, 25, 35, 50, 60, 80, 100};
 
3198
        EgeAdjustmentAction *eact = create_adjustment_action( "TweakFidelityAction",
 
3199
                                                              _("Fidelity"), _("Fidelity:"),
 
3200
                                                              _("Low fidelity simplifies paths; high fidelity preserves path features but may generate a lot of new nodes"),
 
3201
                                                              "tools.tweak", "fidelity", 50,
 
3202
                                                              GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "tweak-fidelity",
 
3203
                                                              1, 100, 1.0, 10.0,
 
3204
                                                              labels, values, G_N_ELEMENTS(labels),
 
3205
                                                              sp_tweak_fidelity_value_changed,  0.01, 0, 100 );
 
3206
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
 
3207
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
 
3208
        if (mode == TWEAK_MODE_COLORPAINT || mode == TWEAK_MODE_COLORJITTER)
 
3209
            gtk_action_set_sensitive (GTK_ACTION(eact), FALSE);
 
3210
        g_object_set_data( holder, "tweak_fidelity", eact );
 
3211
    }
 
3212
 
 
3213
 
 
3214
    /* Use Pressure button */
 
3215
    {
 
3216
        InkToggleAction* act = ink_toggle_action_new( "TweakPressureAction",
 
3217
                                                      _("Pressure"),
 
3218
                                                      _("Use the pressure of the input device to alter the force of tweak action"),
 
3219
                                                      "use_pressure",
 
3220
                                                      Inkscape::ICON_SIZE_DECORATION );
 
3221
        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
 
3222
        g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_tweak_pressure_state_changed), NULL);
 
3223
        gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.tweak", "usepressure", 1 ) );
 
3224
    }
 
3225
 
1975
3226
}
1976
3227
 
1977
3228
 
1979
3230
//##     Calligraphy    ##
1980
3231
//########################
1981
3232
 
1982
 
static void sp_ddc_mass_value_changed2( GtkAdjustment *adj, GtkWidget *tbl )
 
3233
static void sp_ddc_mass_value_changed( GtkAdjustment *adj, GObject* /*tbl*/ )
1983
3234
{
1984
3235
    prefs_set_double_attribute( "tools.calligraphic", "mass", adj->value );
1985
 
    //spinbutton_defocus(GTK_OBJECT(tbl));
1986
3236
}
1987
3237
 
1988
 
static void sp_ddc_wiggle_value_changed2( GtkAdjustment *adj, GtkWidget *tbl )
 
3238
static void sp_ddc_wiggle_value_changed( GtkAdjustment *adj, GObject* /*tbl*/ )
1989
3239
{
1990
3240
    prefs_set_double_attribute( "tools.calligraphic", "wiggle", adj->value );
1991
 
//    spinbutton_defocus(GTK_OBJECT(tbl));
1992
3241
}
1993
3242
 
1994
 
static void sp_ddc_angle_value_changed2( GtkAdjustment *adj, GtkWidget *tbl )
 
3243
static void sp_ddc_angle_value_changed( GtkAdjustment *adj, GObject* /*tbl*/ )
1995
3244
{
1996
3245
    prefs_set_double_attribute( "tools.calligraphic", "angle", adj->value );
1997
 
//    spinbutton_defocus(GTK_OBJECT(tbl));
1998
3246
}
1999
3247
 
2000
 
static void sp_ddc_width_value_changed2( GtkAdjustment *adj, GtkWidget *tbl )
 
3248
static void sp_ddc_width_value_changed( GtkAdjustment *adj, GObject */*tbl*/ )
2001
3249
{
2002
3250
    prefs_set_double_attribute( "tools.calligraphic", "width", adj->value * 0.01 );
2003
 
//    spinbutton_defocus(GTK_OBJECT(tbl));
2004
3251
}
2005
3252
 
2006
 
static void sp_ddc_velthin_value_changed2( GtkAdjustment *adj, GtkWidget *tbl )
 
3253
static void sp_ddc_velthin_value_changed( GtkAdjustment *adj, GObject* /*tbl*/ )
2007
3254
{
2008
3255
    prefs_set_double_attribute("tools.calligraphic", "thinning", adj->value);
2009
 
//    spinbutton_defocus(GTK_OBJECT(tbl));
2010
3256
}
2011
3257
 
2012
 
static void sp_ddc_flatness_value_changed2( GtkAdjustment *adj, GtkWidget *tbl )
 
3258
static void sp_ddc_flatness_value_changed( GtkAdjustment *adj, GObject* /*tbl*/ )
2013
3259
{
2014
3260
    prefs_set_double_attribute( "tools.calligraphic", "flatness", adj->value );
2015
 
//    spinbutton_defocus(GTK_OBJECT(tbl));
2016
3261
}
2017
3262
 
2018
 
static void sp_ddc_tremor_value_changed2( GtkAdjustment *adj, GtkWidget *tbl )
 
3263
static void sp_ddc_tremor_value_changed( GtkAdjustment *adj, GObject* /*tbl*/ )
2019
3264
{
2020
3265
    prefs_set_double_attribute( "tools.calligraphic", "tremor", adj->value );
2021
 
//    spinbutton_defocus(GTK_OBJECT(tbl));
2022
3266
}
2023
3267
 
2024
 
static void sp_ddc_cap_rounding_value_changed2( GtkAdjustment *adj, GtkWidget *tbl )
 
3268
static void sp_ddc_cap_rounding_value_changed( GtkAdjustment *adj, GObject* /*tbl*/ )
2025
3269
{
2026
3270
    prefs_set_double_attribute( "tools.calligraphic", "cap_rounding", adj->value );
2027
 
//    spinbutton_defocus(GTK_OBJECT(tbl));
2028
3271
}
2029
3272
 
2030
 
static void sp_ddc_pressure_state_changed2( GtkToggleAction *act, gpointer data )
 
3273
static void sp_ddc_pressure_state_changed( GtkToggleAction *act, gpointer /*data*/ )
2031
3274
{
2032
3275
    prefs_set_int_attribute( "tools.calligraphic", "usepressure", gtk_toggle_action_get_active( act ) ? 1 : 0);
2033
3276
}
2034
3277
 
2035
 
static void sp_ddc_tilt_state_changed2( GtkToggleAction *act, GtkAction *calligraphy_angle )
 
3278
static void sp_ddc_trace_background_changed( GtkToggleAction *act, gpointer /*data*/ )
 
3279
{
 
3280
    prefs_set_int_attribute( "tools.calligraphic", "tracebackground", gtk_toggle_action_get_active( act ) ? 1 : 0);
 
3281
}
 
3282
 
 
3283
static void sp_ddc_tilt_state_changed( GtkToggleAction *act, GtkAction *calligraphy_angle )
2036
3284
{
2037
3285
    prefs_set_int_attribute( "tools.calligraphic", "usetilt", gtk_toggle_action_get_active( act ) ? 1 : 0 );
2038
3286
 
2039
3287
    gtk_action_set_sensitive( calligraphy_angle, !gtk_toggle_action_get_active( act ) );
2040
3288
}
2041
3289
 
2042
 
static void sp_ddc_defaults2(GtkWidget *, GtkWidget *dataKludge)
 
3290
static void sp_ddc_defaults(GtkWidget *, GObject *dataKludge)
2043
3291
{
2044
3292
    // FIXME: make defaults settable via Inkscape Options
2045
3293
    struct KeyValue {
2058
3306
 
2059
3307
    for (unsigned i = 0; i < G_N_ELEMENTS(key_values); ++i) {
2060
3308
        KeyValue const &kv = key_values[i];
2061
 
        GtkAdjustment* adj = static_cast<GtkAdjustment *>(gtk_object_get_data(GTK_OBJECT(dataKludge), kv.key));
 
3309
        GtkAdjustment* adj = static_cast<GtkAdjustment *>(g_object_get_data(dataKludge, kv.key));
2062
3310
        if ( adj ) {
2063
3311
            gtk_adjustment_set_value(adj, kv.value);
2064
3312
        }
2065
3313
    }
2066
 
 
2067
 
//    spinbutton_defocus(GTK_OBJECT(tbl));
2068
 
}
2069
 
 
2070
 
static void
2071
 
sp_ddc_mass_value_changed(GtkAdjustment *adj, GtkWidget *tbl)
2072
 
{
2073
 
    prefs_set_double_attribute("tools.calligraphic", "mass", adj->value);
2074
 
    spinbutton_defocus(GTK_OBJECT(tbl));
2075
 
}
2076
 
 
2077
 
static void
2078
 
sp_ddc_wiggle_value_changed(GtkAdjustment *adj, GtkWidget *tbl)
2079
 
{
2080
 
    prefs_set_double_attribute("tools.calligraphic", "wiggle", adj->value);
2081
 
    spinbutton_defocus(GTK_OBJECT(tbl));
2082
 
}
2083
 
 
2084
 
static void
2085
 
sp_ddc_angle_value_changed(GtkAdjustment *adj, GtkWidget *tbl)
2086
 
{
2087
 
    prefs_set_double_attribute("tools.calligraphic", "angle", adj->value);
2088
 
    spinbutton_defocus(GTK_OBJECT(tbl));
2089
 
}
2090
 
 
2091
 
static void
2092
 
sp_ddc_width_value_changed(GtkAdjustment *adj, GtkWidget *tbl)
2093
 
{
2094
 
    prefs_set_double_attribute("tools.calligraphic", "width", adj->value * 0.01);
2095
 
    spinbutton_defocus(GTK_OBJECT(tbl));
2096
 
}
2097
 
 
2098
 
static void
2099
 
sp_ddc_velthin_value_changed(GtkAdjustment *adj, GtkWidget *tbl)
2100
 
{
2101
 
    prefs_set_double_attribute("tools.calligraphic", "thinning", adj->value);
2102
 
    spinbutton_defocus(GTK_OBJECT(tbl));
2103
 
}
2104
 
 
2105
 
static void
2106
 
sp_ddc_flatness_value_changed(GtkAdjustment *adj, GtkWidget *tbl)
2107
 
{
2108
 
    prefs_set_double_attribute("tools.calligraphic", "flatness", adj->value);
2109
 
    spinbutton_defocus(GTK_OBJECT(tbl));
2110
 
}
2111
 
 
2112
 
static void
2113
 
sp_ddc_tremor_value_changed(GtkAdjustment *adj, GtkWidget *tbl)
2114
 
{
2115
 
    prefs_set_double_attribute("tools.calligraphic", "tremor", adj->value);
2116
 
    spinbutton_defocus(GTK_OBJECT(tbl));
2117
 
}
2118
 
 
2119
 
static void
2120
 
sp_ddc_cap_rounding_value_changed(GtkAdjustment *adj, GtkWidget *tbl)
2121
 
{
2122
 
    prefs_set_double_attribute("tools.calligraphic", "cap_rounding", adj->value);
2123
 
    spinbutton_defocus(GTK_OBJECT(tbl));
2124
 
}
2125
 
 
2126
 
static void
2127
 
sp_ddc_pressure_state_changed(GtkWidget *button, gpointer data)
2128
 
{
2129
 
    prefs_set_int_attribute ("tools.calligraphic", "usepressure", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) ? 1 : 0);
2130
 
}
2131
 
 
2132
 
static void
2133
 
sp_ddc_tilt_state_changed(GtkWidget *button, GtkWidget *calligraphy_angle)
2134
 
{
2135
 
    prefs_set_int_attribute ("tools.calligraphic", "usetilt", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) ? 1 : 0);
2136
 
 
2137
 
    gtk_widget_set_sensitive(GTK_WIDGET(calligraphy_angle), !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)));
2138
 
}
2139
 
 
2140
 
static void sp_ddc_defaults(GtkWidget *, GtkWidget *tbl)
2141
 
{
2142
 
    // FIXME: make defaults settable via Inkscape Options
2143
 
    struct KeyValue {
2144
 
        char const *key;
2145
 
        double value;
2146
 
    } const key_values[] = {
2147
 
        {"mass", 0.02},
2148
 
        {"wiggle", 0.0},
2149
 
        {"angle", 30.0},
2150
 
        {"width", 15},
2151
 
        {"thinning", 0.1},
2152
 
        {"tremor", 0.0},
2153
 
        {"flatness", 0.9},
2154
 
        {"cap_rounding", 0.0}
2155
 
    };
2156
 
 
2157
 
    for (unsigned i = 0; i < G_N_ELEMENTS(key_values); ++i) {
2158
 
        KeyValue const &kv = key_values[i];
2159
 
        GtkAdjustment &adj = *static_cast<GtkAdjustment *>(gtk_object_get_data(GTK_OBJECT(tbl), kv.key));
2160
 
        gtk_adjustment_set_value(&adj, kv.value);
2161
 
    }
2162
 
 
2163
 
    spinbutton_defocus(GTK_OBJECT(tbl));
2164
 
}
2165
 
 
2166
 
 
2167
 
 
2168
 
 
2169
 
static GtkWidget *
2170
 
sp_calligraphy_toolbox_new(SPDesktop *desktop)
2171
 
{
2172
 
  if ( prefs_get_int_attribute_limited( "options.stocktoolbars", "value", 1, 0, 1 ) ) {
2173
 
    GtkWidget *toolBar = 0;
2174
 
    GtkWidget* holder = gtk_table_new( 1, 2, FALSE );
2175
 
 
2176
 
    gchar const * descr =
2177
 
        "<ui>"
2178
 
        "  <toolbar name='CalligraphyToolbar'>"
2179
 
        "    <separator />"
2180
 
        "    <toolitem name='Width' action='WidthAction' />"
2181
 
        "    <toolitem name='Thinning' action='ThinningAction' />"
2182
 
        "    <separator />"
2183
 
        "    <toolitem name='Angle' action='AngleAction' />"
2184
 
        "    <toolitem action='FixationAction' />"
2185
 
        "    <toolitem action='CapRoundingAction' />"
2186
 
        "    <separator />"
2187
 
        "    <toolitem action='TremorAction' />"
2188
 
        "    <toolitem action='WiggleAction' />"
2189
 
        "    <toolitem action='MassAction' />"
2190
 
        "    <separator />"
2191
 
        "    <toolitem action='PressureAction' />"
2192
 
        "    <toolitem action='TiltAction' />"
2193
 
        "    <toolitem action='ResetAction' />"
2194
 
        "  </toolbar>"
2195
 
        "</ui>";
2196
 
    GtkUIManager* mgr = gtk_ui_manager_new();
2197
 
    GError* errVal = 0;
2198
 
    GtkActionGroup* mainActions = gtk_action_group_new("main");
2199
 
 
 
3314
}
 
3315
 
 
3316
 
 
3317
static void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
 
3318
{
2200
3319
    {
2201
3320
        EgeAdjustmentAction* calligraphy_angle = 0;
2202
 
        EgeAdjustmentAction* eact = 0;
2203
3321
 
 
3322
        {
2204
3323
        /* Width */
2205
 
        eact = create_adjustment_action( "WidthAction",
2206
 
                                         _("Width:"), _("The width of the calligraphic pen (relative to the visible canvas area)"),
2207
 
                                         "tools.calligraphic", "width", 15,
2208
 
                                         GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "altx-calligraphy",
2209
 
                                         1, 100, 1.0, 10.0,
2210
 
                                         sp_ddc_width_value_changed2,  0.01, 0, 100 );
 
3324
        gchar const* labels[] = {_("(hairline)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad stroke)")};
 
3325
        gdouble values[] = {1, 3, 5, 10, 15, 20, 30, 50, 75, 100};
 
3326
        EgeAdjustmentAction *eact = create_adjustment_action( "CalligraphyWidthAction",
 
3327
                                                              _("Pen Width"), _("Width:"),
 
3328
                                                              _("The width of the calligraphic pen (relative to the visible canvas area)"),
 
3329
                                                              "tools.calligraphic", "width", 15,
 
3330
                                                              GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "altx-calligraphy",
 
3331
                                                              1, 100, 1.0, 10.0,
 
3332
                                                              labels, values, G_N_ELEMENTS(labels),
 
3333
                                                              sp_ddc_width_value_changed,  0.01, 0, 100 );
2211
3334
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
2212
3335
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
 
3336
        }
2213
3337
 
 
3338
        {
2214
3339
        /* Thinning */
2215
 
        eact = create_adjustment_action( "ThinningAction",
2216
 
                                         _("Thinning:"), _("How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 makes them broader, 0 makes width independent of velocity)"),
2217
 
                                         "tools.calligraphic", "thinning", 0.1,
2218
 
                                         GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
2219
 
                                         -1.0, 1.0, 0.01, 0.1,
2220
 
                                         sp_ddc_velthin_value_changed2, 0.01, 2);
 
3340
            gchar const* labels[] = {_("(speed blows up stroke)"), 0, 0, _("(slight widening)"), _("(constant width)"), _("(slight thinning, default)"), 0, 0, _("(speed deflates stroke)")};
 
3341
            gdouble values[] = {-1, -0.4, -0.2, -0.1, 0, 0.1, 0.2, 0.4, 1};
 
3342
        EgeAdjustmentAction* eact = create_adjustment_action( "ThinningAction",
 
3343
                                                              _("Stroke Thinning"), _("Thinning:"),
 
3344
                                                              _("How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 makes them broader, 0 makes width independent of velocity)"),
 
3345
                                                              "tools.calligraphic", "thinning", 0.1,
 
3346
                                                              GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
 
3347
                                                              -1.0, 1.0, 0.01, 0.1,
 
3348
                                                              labels, values, G_N_ELEMENTS(labels),
 
3349
                                                              sp_ddc_velthin_value_changed, 0.01, 2);
2221
3350
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
2222
3351
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
 
3352
        }
2223
3353
 
 
3354
        {
2224
3355
        /* Angle */
2225
 
        eact = create_adjustment_action( "AngleAction",
2226
 
                                         _("Angle:"), _("The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if fixation = 0)"),
2227
 
                                         "tools.calligraphic", "angle", 30,
2228
 
                                         GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "calligraphy-angle",
2229
 
                                         -90.0, 90.0, 1.0, 10.0,
2230
 
                                         sp_ddc_angle_value_changed2, 1, 0 );
 
3356
        gchar const* labels[] = {_("(left edge up)"), 0, 0, _("(horizontal)"), _("(default)"), 0, _("(right edge up)")};
 
3357
        gdouble values[] = {-90, -60, -30, 0, 30, 60, 90};
 
3358
        EgeAdjustmentAction* eact = create_adjustment_action( "AngleAction",
 
3359
                                                              _("Pen Angle"), _("Angle:"),
 
3360
                                                              _("The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if fixation = 0)"),
 
3361
                                                              "tools.calligraphic", "angle", 30,
 
3362
                                                              GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "calligraphy-angle",
 
3363
                                                              -90.0, 90.0, 1.0, 10.0,
 
3364
                                                              labels, values, G_N_ELEMENTS(labels),
 
3365
                                                              sp_ddc_angle_value_changed, 1, 0 );
2231
3366
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
2232
3367
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
2233
3368
        calligraphy_angle = eact;
 
3369
        }
2234
3370
 
 
3371
        {
2235
3372
        /* Fixation */
2236
 
        eact = create_adjustment_action( "FixationAction",
2237
 
                                         _("Fixation:"), _("Angle behavior (0 = nib always perpendicular to stroke direction, 1 = fixed angle)"),
2238
 
                                         "tools.calligraphic", "flatness", 0.9,
2239
 
                                         GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
2240
 
                                         0.0, 1.0, 0.01, 0.1,
2241
 
                                         sp_ddc_flatness_value_changed2, 0.01, 2 );
 
3373
            gchar const* labels[] = {_("(perpendicular to stroke, \"brush\")"), 0, 0, 0, _("(almost fixed, default)"), _("(fixed by Angle, \"pen\")")};
 
3374
        gdouble values[] = {0, 0.2, 0.4, 0.6, 0.9, 1.0};
 
3375
        EgeAdjustmentAction* eact = create_adjustment_action( "FixationAction",
 
3376
                                                              _("Fixation"), _("Fixation:"),
 
3377
                                                              _("Angle behavior (0 = nib always perpendicular to stroke direction, 1 = fixed angle)"),
 
3378
                                                              "tools.calligraphic", "flatness", 0.9,
 
3379
                                                              GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
 
3380
                                                              0.0, 1.0, 0.01, 0.1,
 
3381
                                                              labels, values, G_N_ELEMENTS(labels),
 
3382
                                                              sp_ddc_flatness_value_changed, 0.01, 2 );
2242
3383
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
2243
3384
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
 
3385
        }
2244
3386
 
 
3387
        {
2245
3388
        /* Cap Rounding */
 
3389
            gchar const* labels[] = {_("(blunt caps, default)"), _("(slightly bulging)"), 0, 0, _("(approximately round)"), _("(long protruding caps)")};
 
3390
        gdouble values[] = {0, 0.3, 0.5, 1.0, 1.4, 5.0};
2246
3391
        // TRANSLATORS: "cap" means "end" (both start and finish) here
2247
 
        eact = create_adjustment_action( "CapRoundingAction",
2248
 
                                         _("Caps:"), _("Increase to make caps at the ends of strokes protrude more (0 = no caps, 1 = round caps)"),
2249
 
                                         "tools.calligraphic", "cap_rounding", 0.0,
2250
 
                                         GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
2251
 
                                         0.0, 5.0, 0.01, 0.1,
2252
 
                                         sp_ddc_cap_rounding_value_changed2, 0.01, 2 );
 
3392
        EgeAdjustmentAction* eact = create_adjustment_action( "CapRoundingAction",
 
3393
                                                              _("Cap rounding"), _("Caps:"),
 
3394
                                                              _("Increase to make caps at the ends of strokes protrude more (0 = no caps, 1 = round caps)"),
 
3395
                                                              "tools.calligraphic", "cap_rounding", 0.0,
 
3396
                                                              GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
 
3397
                                                              0.0, 5.0, 0.01, 0.1,
 
3398
                                                              labels, values, G_N_ELEMENTS(labels),
 
3399
                                                              sp_ddc_cap_rounding_value_changed, 0.01, 2 );
2253
3400
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
2254
3401
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
 
3402
        }
2255
3403
 
 
3404
        {
2256
3405
        /* Tremor */
2257
 
        eact = create_adjustment_action( "TremorAction",
2258
 
                                         _("Tremor:"), _("Increase to make strokes rugged and trembling"),
2259
 
                                         "tools.calligraphic", "tremor", 0.0,
2260
 
                                         GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
2261
 
                                         0.0, 1.0, 0.01, 0.1,
2262
 
                                         sp_ddc_tremor_value_changed2, 0.01, 2 );
 
3406
            gchar const* labels[] = {_("(smooth line)"), _("(slight tremor)"), _("(noticeable tremor)"), 0, 0, _("(maximum tremor)")};
 
3407
        gdouble values[] = {0, 0.1, 0.2, 0.4, 0.6, 1.0};
 
3408
        EgeAdjustmentAction* eact = create_adjustment_action( "TremorAction",
 
3409
                                                              _("Stroke Tremor"), _("Tremor:"),
 
3410
                                                              _("Increase to make strokes rugged and trembling"),
 
3411
                                                              "tools.calligraphic", "tremor", 0.0,
 
3412
                                                              GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
 
3413
                                                              0.0, 1.0, 0.01, 0.1,
 
3414
                                                              labels, values, G_N_ELEMENTS(labels),
 
3415
                                                              sp_ddc_tremor_value_changed, 0.01, 2 );
2263
3416
 
2264
3417
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
2265
3418
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
 
3419
        }
2266
3420
 
 
3421
        {
2267
3422
        /* Wiggle */
2268
 
        eact = create_adjustment_action( "WiggleAction",
2269
 
                                         _("Wiggle:"), _("Increase to make the pen waver and wiggle"),
2270
 
                                         "tools.calligraphic", "wiggle", 0.0,
2271
 
                                         GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
2272
 
                                         0.0, 1.0, 0.01, 0.1,
2273
 
                                         sp_ddc_wiggle_value_changed2, 0.01, 2 );
 
3423
        gchar const* labels[] = {_("(no wiggle)"), _("(slight deviation)"), 0, 0, _("(wild waves and curls)")};
 
3424
        gdouble values[] = {0, 0.2, 0.4, 0.6, 1.0};
 
3425
        EgeAdjustmentAction* eact = create_adjustment_action( "WiggleAction",
 
3426
                                                              _("Pen Wiggle"), _("Wiggle:"),
 
3427
                                                              _("Increase to make the pen waver and wiggle"),
 
3428
                                                              "tools.calligraphic", "wiggle", 0.0,
 
3429
                                                              GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
 
3430
                                                              0.0, 1.0, 0.01, 0.1,
 
3431
                                                              labels, values, G_N_ELEMENTS(labels),
 
3432
                                                              sp_ddc_wiggle_value_changed, 0.01, 2 );
2274
3433
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
2275
3434
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
 
3435
        }
2276
3436
 
 
3437
        {
2277
3438
        /* Mass */
2278
 
        eact = create_adjustment_action( "MassAction",
2279
 
                                         _("Mass:"), _("Increase to make the pen drag behind, as if slowed by inertia"),
2280
 
                                         "tools.calligraphic", "mass", 0.02,
2281
 
                                         GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
2282
 
                                         0.0, 1.0, 0.01, 0.1,
2283
 
                                         sp_ddc_mass_value_changed2, 0.01, 2 );
 
3439
            gchar const* labels[] = {_("(no inertia)"), _("(slight smoothing, default)"), _("(noticeable lagging)"), 0, 0, _("(maximum inertia)")};
 
3440
        gdouble values[] = {0.0, 0.02, 0.1, 0.2, 0.5, 1.0};
 
3441
        EgeAdjustmentAction* eact = create_adjustment_action( "MassAction",
 
3442
                                                              _("Pen Mass"), _("Mass:"),
 
3443
                                                              _("Increase to make the pen drag behind, as if slowed by inertia"),
 
3444
                                                              "tools.calligraphic", "mass", 0.02,
 
3445
                                                              GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
 
3446
                                                              0.0, 1.0, 0.01, 0.1,
 
3447
                                                              labels, values, G_N_ELEMENTS(labels),
 
3448
                                                              sp_ddc_mass_value_changed, 0.01, 2 );
2284
3449
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
2285
3450
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
2286
 
 
 
3451
        }
 
3452
 
 
3453
 
 
3454
        /* Trace Background button */
 
3455
        {
 
3456
            InkToggleAction* act = ink_toggle_action_new( "TraceAction",
 
3457
                                                          _("Trace Background"),
 
3458
                                                          _("Trace the lightness of the background by the width of the pen (white - minimum width, black - maximum width)"),
 
3459
                                                          "trace_background",
 
3460
                                                          Inkscape::ICON_SIZE_DECORATION );
 
3461
            gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
 
3462
            g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_ddc_trace_background_changed), NULL);
 
3463
            gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.calligraphic", "tracebackground", 0 ) );
 
3464
        }
2287
3465
 
2288
3466
        /* Use Pressure button */
2289
3467
        {
2293
3471
                                                          "use_pressure",
2294
3472
                                                          Inkscape::ICON_SIZE_DECORATION );
2295
3473
            gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
2296
 
            g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_ddc_pressure_state_changed2), NULL);
 
3474
            g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_ddc_pressure_state_changed), NULL);
2297
3475
            gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.calligraphic", "usepressure", 1 ) );
2298
3476
        }
2299
3477
 
2305
3483
                                                          "use_tilt",
2306
3484
                                                          Inkscape::ICON_SIZE_DECORATION );
2307
3485
            gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
2308
 
            g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_ddc_tilt_state_changed2), calligraphy_angle );
 
3486
            g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_ddc_tilt_state_changed), calligraphy_angle );
2309
3487
            gtk_action_set_sensitive( GTK_ACTION(calligraphy_angle), !prefs_get_int_attribute( "tools.calligraphic", "usetilt", 1 ) );
2310
3488
            gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.calligraphic", "usetilt", 1 ) );
2311
3489
        }
2312
3490
 
2313
3491
        /* Reset */
2314
3492
        {
2315
 
            GtkAction* act = gtk_action_new( "ResetAction",
 
3493
            GtkAction* act = gtk_action_new( "CalligraphyResetAction",
2316
3494
                                             _("Defaults"),
2317
 
                                             _("Reset shape parameters to defaults (use Inkscape Preferences > Tools to change defaults)"),
 
3495
                                             _("Reset all parameters to defaults"),
2318
3496
                                             GTK_STOCK_CLEAR );
2319
 
            g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_ddc_defaults2), holder );
 
3497
            g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_ddc_defaults), holder );
2320
3498
            gtk_action_group_add_action( mainActions, act );
2321
3499
            gtk_action_set_sensitive( act, TRUE );
2322
3500
        }
2323
3501
    }
2324
 
 
2325
 
 
2326
 
    gtk_ui_manager_insert_action_group( mgr, mainActions, 0 );
2327
 
    gtk_ui_manager_add_ui_from_string( mgr, descr, -1, &errVal );
2328
 
 
2329
 
    toolBar = gtk_ui_manager_get_widget( mgr, "/ui/CalligraphyToolbar" );
2330
 
    gtk_toolbar_set_style( GTK_TOOLBAR(toolBar), GTK_TOOLBAR_ICONS );
2331
 
    gtk_toolbar_set_icon_size( GTK_TOOLBAR(toolBar), GTK_ICON_SIZE_SMALL_TOOLBAR );
2332
 
 
2333
 
 
2334
 
    gtk_table_attach( GTK_TABLE(holder), toolBar, 0, 1, 0, 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 0, 0 );
2335
 
 
2336
 
    Inkscape::UI::Widget::StyleSwatch *swatch = new Inkscape::UI::Widget::StyleSwatch(NULL);
2337
 
    swatch->setWatchedTool ("tools.calligraphic", true);
2338
 
    GtkWidget *swatch_ = GTK_WIDGET(swatch->gobj());
2339
 
    gtk_table_attach( GTK_TABLE(holder), swatch_, 1, 2, 0, 1, (GtkAttachOptions)(GTK_SHRINK | GTK_FILL), (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), AUX_BETWEEN_BUTTON_GROUPS, 0 );
2340
 
 
2341
 
    gtk_widget_show_all(holder);
2342
 
    //sp_set_font_size_smaller (tbl);
2343
 
 
2344
 
    return holder;
2345
 
  } else {
2346
 
    GtkWidget *tbl = gtk_hbox_new(FALSE, 0);
2347
 
    gtk_object_set_data(GTK_OBJECT(tbl), "dtw", desktop->canvas);
2348
 
    gtk_object_set_data(GTK_OBJECT(tbl), "desktop", desktop);
2349
 
 
2350
 
    GtkTooltips *tt = gtk_tooltips_new();
2351
 
    GtkWidget *calligraphy_angle;
2352
 
 
2353
 
    //  interval
2354
 
    gtk_box_pack_start(GTK_BOX(tbl), gtk_hbox_new(FALSE, 0), FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
2355
 
 
2356
 
    /* Width */
2357
 
    {
2358
 
        GtkWidget *hb = sp_tb_spinbutton(_("Width:"), _("The width of the calligraphic pen (relative to the visible canvas area)"),
2359
 
                                         "tools.calligraphic", "width", 15,
2360
 
                                         NULL, tbl, TRUE, "altx-calligraphy",
2361
 
                                         1, 100, 1.0, 10.0,
2362
 
                                         sp_ddc_width_value_changed,  0.01, 0, 100);
2363
 
        gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, AUX_SPACING);
2364
 
    }
2365
 
 
2366
 
    /* Thinning */
2367
 
    {
2368
 
        GtkWidget *hb = sp_tb_spinbutton(_("Thinning:"), _("How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 makes them broader, 0 makes width independent of velocity)"),
2369
 
                                         "tools.calligraphic", "thinning", 0.1,
2370
 
                                         NULL, tbl, FALSE, NULL,
2371
 
                                         -1.0, 1.0, 0.01, 0.1,
2372
 
                                         sp_ddc_velthin_value_changed, 0.01, 2);
2373
 
        gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, AUX_SPACING);
2374
 
    }
2375
 
 
2376
 
    //  interval
2377
 
    gtk_box_pack_start(GTK_BOX(tbl), gtk_hbox_new(FALSE, 0), FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
2378
 
 
2379
 
    /* Angle */
2380
 
    {
2381
 
        calligraphy_angle = sp_tb_spinbutton(_("Angle:"), _("The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if fixation = 0)"),
2382
 
                                             "tools.calligraphic", "angle", 30,
2383
 
                                             NULL, tbl, TRUE, "calligraphy-angle",
2384
 
                                             -90.0, 90.0, 1.0, 10.0,
2385
 
                                             sp_ddc_angle_value_changed, 1, 0);
2386
 
        gtk_box_pack_start(GTK_BOX(tbl), calligraphy_angle, FALSE, FALSE, AUX_SPACING);
2387
 
    }
2388
 
 
2389
 
    /* Fixation */
2390
 
    {
2391
 
        GtkWidget *hb = sp_tb_spinbutton(_("Fixation:"), _("Angle behavior (0 = nib always perpendicular to stroke direction, 1 = fixed angle)"),
2392
 
                                         "tools.calligraphic", "flatness", 0.9,
2393
 
                                         NULL, tbl, FALSE, NULL,
2394
 
                                         0.0, 1.0, 0.01, 0.1,
2395
 
                                         sp_ddc_flatness_value_changed, 0.01, 2);
2396
 
        gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, AUX_SPACING);
2397
 
    }
2398
 
 
2399
 
    /* Cap Rounding */
2400
 
    {
2401
 
        // TRANSLATORS: "cap" means "end" (both start and finish) here
2402
 
        GtkWidget *hb = sp_tb_spinbutton(_("Round:"), _("Increase to round the ends of strokes"),
2403
 
                                         "tools.calligraphic", "cap_rounding", 0.0,
2404
 
                                         NULL, tbl, FALSE, NULL,
2405
 
                                         0.0, 1.0, 0.01, 0.1,
2406
 
                                         sp_ddc_cap_rounding_value_changed, 0.01, 2);
2407
 
        gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, AUX_SPACING);
2408
 
    }
2409
 
 
2410
 
    //  interval
2411
 
    gtk_box_pack_start(GTK_BOX(tbl), gtk_hbox_new(FALSE, 0), FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
2412
 
 
2413
 
    /* Tremor */
2414
 
    {
2415
 
        GtkWidget *hb = sp_tb_spinbutton(_("Tremor:"), _("Increase to make strokes rugged and trembling"),
2416
 
                                         "tools.calligraphic", "tremor", 0.0,
2417
 
                                         NULL, tbl, FALSE, NULL,
2418
 
                                         0.0, 1.0, 0.01, 0.1,
2419
 
                                         sp_ddc_tremor_value_changed, 0.01, 2);
2420
 
        gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, AUX_SPACING);
2421
 
    }
2422
 
 
2423
 
    /* Wiggle */
2424
 
    {
2425
 
        GtkWidget *hb = sp_tb_spinbutton(_("Wiggle:"), _("Increase to make the pen waver and wiggle"),
2426
 
                                         "tools.calligraphic", "wiggle", 0.0,
2427
 
                                         NULL, tbl, FALSE, NULL,
2428
 
                                         0.0, 1.0, 0.01, 0.1,
2429
 
                                         sp_ddc_wiggle_value_changed, 0.01, 2);
2430
 
        gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, AUX_SPACING);
2431
 
    }
2432
 
 
2433
 
 
2434
 
    /* Mass */
2435
 
    {
2436
 
        GtkWidget *hb = sp_tb_spinbutton(_("Mass:"), _("Increase to make the pen drag behind, as if slowed by inertia"),
2437
 
                                         "tools.calligraphic", "mass", 0.02,
2438
 
                                         NULL, tbl, FALSE, NULL,
2439
 
                                         0.0, 1.0, 0.01, 0.1,
2440
 
                                         sp_ddc_mass_value_changed, 0.01, 2);
2441
 
        gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, AUX_SPACING);
2442
 
    }
2443
 
 
2444
 
    //  interval
2445
 
    gtk_box_pack_start(GTK_BOX(tbl), gtk_hbox_new(FALSE, 0), FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
2446
 
 
2447
 
    GtkWidget *cvbox = gtk_vbox_new (FALSE, 0);
2448
 
    GtkWidget *cbox = gtk_hbox_new (FALSE, 0);
2449
 
 
2450
 
    /* Use Pressure button */
2451
 
    {
2452
 
    GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
2453
 
                                                 SP_BUTTON_TYPE_TOGGLE,
2454
 
                                                 NULL,
2455
 
                                                 "use_pressure",
2456
 
                                                 _("Use the pressure of the input device to alter the width of the pen"),
2457
 
                                                 tt);
2458
 
    g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (sp_ddc_pressure_state_changed), NULL);
2459
 
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), prefs_get_int_attribute ("tools.calligraphic", "usepressure", 1));
2460
 
    gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
2461
 
    }
2462
 
 
2463
 
    /* Use Tilt button */
2464
 
    {
2465
 
    GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
2466
 
                                                 SP_BUTTON_TYPE_TOGGLE,
2467
 
                                                 NULL,
2468
 
                                                 "use_tilt",
2469
 
                                                 _("Use the tilt of the input device to alter the angle of the pen's nib"),
2470
 
                                                 tt);
2471
 
    g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (sp_ddc_tilt_state_changed), calligraphy_angle);
2472
 
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), prefs_get_int_attribute ("tools.calligraphic", "usetilt", 1));
2473
 
    gtk_widget_set_sensitive(GTK_WIDGET(calligraphy_angle), !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)));
2474
 
    gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
2475
 
    }
2476
 
 
2477
 
    gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, FALSE, 0);
2478
 
    gtk_box_pack_start(GTK_BOX(tbl), cvbox, FALSE, FALSE, 0);
2479
 
 
2480
 
    /* Reset */
2481
 
    {
2482
 
        GtkWidget *hb = gtk_hbox_new(FALSE, 1);
2483
 
        GtkWidget *b = gtk_button_new_with_label(_("Defaults"));
2484
 
        gtk_tooltips_set_tip(tt, b, _("Reset shape parameters to defaults (use Inkscape Preferences > Tools to change defaults)"), NULL);
2485
 
        gtk_widget_show(b);
2486
 
        gtk_container_add(GTK_CONTAINER(hb), b);
2487
 
        gtk_signal_connect(GTK_OBJECT(b), "clicked", GTK_SIGNAL_FUNC(sp_ddc_defaults), tbl);
2488
 
        gtk_box_pack_start(GTK_BOX(tbl),hb, FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
2489
 
    }
2490
 
 
2491
 
 
2492
 
    Inkscape::UI::Widget::StyleSwatch *swatch = new Inkscape::UI::Widget::StyleSwatch(NULL);
2493
 
    swatch->setWatchedTool ("tools.calligraphic", true);
2494
 
    GtkWidget *swatch_ = GTK_WIDGET(swatch->gobj());
2495
 
    gtk_box_pack_end(GTK_BOX(tbl), swatch_, FALSE, FALSE, 0);
2496
 
 
2497
 
    gtk_widget_show_all(tbl);
2498
 
    sp_set_font_size_smaller (tbl);
2499
 
 
2500
 
    return tbl;
2501
 
  }
2502
3502
}
2503
3503
 
2504
3504
 
2506
3506
//##    Circle / Arc    ##
2507
3507
//########################
2508
3508
 
2509
 
static void 
2510
 
sp_arctb_sensitivize (GtkWidget *tbl, double v1, double v2)
 
3509
static void sp_arctb_sensitivize( GObject *tbl, double v1, double v2 )
2511
3510
{
2512
 
    GtkWidget *ocb = (GtkWidget*) g_object_get_data(G_OBJECT(tbl), "open_checkbox");
2513
 
    GtkWidget *make_whole = (GtkWidget*) g_object_get_data(G_OBJECT(tbl), "make_whole");
 
3511
    GtkAction *ocb = GTK_ACTION( g_object_get_data( tbl, "open_action" ) );
 
3512
    GtkAction *make_whole = GTK_ACTION( g_object_get_data( tbl, "make_whole" ) );
2514
3513
 
2515
3514
    if (v1 == 0 && v2 == 0) {
2516
 
        if (gtk_object_get_data(GTK_OBJECT(tbl), "single")) { // only for a single selected ellipse (for now)
2517
 
            gtk_widget_set_sensitive(GTK_WIDGET(ocb), FALSE);
2518
 
            gtk_widget_set_sensitive(GTK_WIDGET(make_whole), FALSE);
 
3515
        if (g_object_get_data( tbl, "single" )) { // only for a single selected ellipse (for now)
 
3516
            gtk_action_set_sensitive( ocb, FALSE );
 
3517
            gtk_action_set_sensitive( make_whole, FALSE );
2519
3518
        }
2520
3519
    } else {
2521
 
        gtk_widget_set_sensitive(GTK_WIDGET(ocb), TRUE);
2522
 
        gtk_widget_set_sensitive(GTK_WIDGET(make_whole), TRUE);
 
3520
        gtk_action_set_sensitive( ocb, TRUE );
 
3521
        gtk_action_set_sensitive( make_whole, TRUE );
2523
3522
    }
2524
3523
}
2525
3524
 
2526
3525
static void
2527
 
sp_arctb_startend_value_changed(GtkAdjustment *adj, GtkWidget *tbl, gchar const *value_name, gchar const *other_name)
 
3526
sp_arctb_startend_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *value_name, gchar const *other_name)
2528
3527
{
2529
 
    SPDesktop *desktop = (SPDesktop *) gtk_object_get_data(GTK_OBJECT(tbl), "desktop");
 
3528
    SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" );
2530
3529
 
2531
3530
    if (sp_document_get_undo_sensitive(sp_desktop_document(desktop))) {
2532
3531
        prefs_set_double_attribute("tools.shapes.arc", value_name, (adj->value * M_PI)/ 180);
2533
3532
    }
2534
3533
 
2535
3534
    // quit if run by the attr_changed listener
2536
 
    if (g_object_get_data(G_OBJECT(tbl), "freeze")) {
 
3535
    if (g_object_get_data( tbl, "freeze" )) {
2537
3536
        return;
2538
3537
    }
2539
3538
 
2540
3539
    // in turn, prevent listener from responding
2541
 
    g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE));
 
3540
    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) );
2542
3541
 
2543
3542
    gchar* namespaced_name = g_strconcat("sodipodi:", value_name, NULL);
2544
3543
 
2569
3568
 
2570
3569
    g_free(namespaced_name);
2571
3570
 
2572
 
    GtkAdjustment *other = (GtkAdjustment *)gtk_object_get_data(GTK_OBJECT(tbl), other_name);
 
3571
    GtkAdjustment *other = GTK_ADJUSTMENT( g_object_get_data( tbl, other_name ) );
2573
3572
 
2574
 
    sp_arctb_sensitivize (tbl, adj->value, other->value);
 
3573
    sp_arctb_sensitivize( tbl, adj->value, other->value );
2575
3574
 
2576
3575
    if (modmade) {
2577
 
        sp_document_maybe_done(sp_desktop_document(desktop), value_name, SP_VERB_CONTEXT_ARC, 
 
3576
        sp_document_maybe_done(sp_desktop_document(desktop), value_name, SP_VERB_CONTEXT_ARC,
2578
3577
                                   _("Arc: Change start/end"));
2579
3578
    }
2580
3579
 
2581
 
    // defocus spinbuttons by moving focus to the canvas, unless "stay" is on
2582
 
    spinbutton_defocus(GTK_OBJECT(tbl));
2583
 
 
2584
 
    g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(FALSE));
 
3580
    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
2585
3581
}
2586
3582
 
2587
3583
 
2588
 
static void
2589
 
sp_arctb_start_value_changed(GtkAdjustment *adj,  GtkWidget *tbl)
 
3584
static void sp_arctb_start_value_changed(GtkAdjustment *adj,  GObject *tbl)
2590
3585
{
2591
3586
    sp_arctb_startend_value_changed(adj,  tbl, "start", "end");
2592
3587
}
2593
3588
 
2594
 
static void
2595
 
sp_arctb_end_value_changed(GtkAdjustment *adj, GtkWidget *tbl)
 
3589
static void sp_arctb_end_value_changed(GtkAdjustment *adj, GObject *tbl)
2596
3590
{
2597
3591
    sp_arctb_startend_value_changed(adj,  tbl, "end", "start");
2598
3592
}
2599
3593
 
2600
 
static void
2601
 
sp_arctb_open_state_changed(GtkWidget *widget, GtkObject *tbl)
 
3594
static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl )
2602
3595
{
2603
 
    SPDesktop *desktop = (SPDesktop *) gtk_object_get_data(GTK_OBJECT(tbl), "desktop");
2604
 
 
 
3596
    SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" );
2605
3597
    if (sp_document_get_undo_sensitive(sp_desktop_document(desktop))) {
2606
 
        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
 
3598
        if ( ege_select_one_action_get_active( act ) != 0 ) {
2607
3599
            prefs_set_string_attribute("tools.shapes.arc", "open", "true");
2608
3600
        } else {
2609
3601
            prefs_set_string_attribute("tools.shapes.arc", "open", NULL);
2611
3603
    }
2612
3604
 
2613
3605
    // quit if run by the attr_changed listener
2614
 
    if (g_object_get_data(G_OBJECT(tbl), "freeze")) {
 
3606
    if (g_object_get_data( tbl, "freeze" )) {
2615
3607
        return;
2616
3608
    }
2617
3609
 
2618
3610
    // in turn, prevent listener from responding
2619
 
    g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE));
 
3611
    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) );
2620
3612
 
2621
3613
    bool modmade = false;
2622
3614
 
2623
 
    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
 
3615
    if ( ege_select_one_action_get_active(act) != 0 ) {
2624
3616
        for (GSList const *items = sp_desktop_selection(desktop)->itemList();
2625
3617
             items != NULL;
2626
3618
             items = items->next)
2647
3639
    }
2648
3640
 
2649
3641
    if (modmade) {
2650
 
        sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_ARC, 
 
3642
        sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_ARC,
2651
3643
                                   _("Arc: Change open/closed"));
2652
3644
    }
2653
3645
 
2654
 
    g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(FALSE));
2655
 
 
2656
 
    spinbutton_defocus(GTK_OBJECT(tbl));
 
3646
    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
2657
3647
}
2658
3648
 
2659
 
static void sp_arctb_defaults(GtkWidget *, GtkObject *obj)
 
3649
static void sp_arctb_defaults(GtkWidget *, GObject *obj)
2660
3650
{
2661
 
    GtkWidget *tbl = GTK_WIDGET(obj);
2662
 
 
2663
3651
    GtkAdjustment *adj;
2664
 
    adj = (GtkAdjustment*)gtk_object_get_data(obj, "start");
2665
 
    gtk_adjustment_set_value(adj, 0.0);
2666
 
    gtk_adjustment_value_changed(adj);
2667
 
 
2668
 
    adj = (GtkAdjustment*)gtk_object_get_data(obj, "end");
2669
 
    gtk_adjustment_set_value(adj, 0.0);
2670
 
    gtk_adjustment_value_changed(adj);
2671
 
 
2672
 
    spinbutton_defocus(GTK_OBJECT(tbl));
 
3652
    adj = GTK_ADJUSTMENT( g_object_get_data(obj, "start") );
 
3653
    gtk_adjustment_set_value(adj, 0.0);
 
3654
    gtk_adjustment_value_changed(adj);
 
3655
 
 
3656
    adj = GTK_ADJUSTMENT( g_object_get_data(obj, "end") );
 
3657
    gtk_adjustment_set_value(adj, 0.0);
 
3658
    gtk_adjustment_value_changed(adj);
 
3659
 
 
3660
    spinbutton_defocus( GTK_OBJECT(obj) );
2673
3661
}
2674
3662
 
2675
 
static void arc_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const *name,
2676
 
                                      gchar const *old_value, gchar const *new_value,
2677
 
                                      bool is_interactive, gpointer data)
 
3663
static void arc_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const */*name*/,
 
3664
                                      gchar const */*old_value*/, gchar const */*new_value*/,
 
3665
                                      bool /*is_interactive*/, gpointer data)
2678
3666
{
2679
 
    GtkWidget *tbl = GTK_WIDGET(data);
 
3667
    GObject *tbl = G_OBJECT(data);
2680
3668
 
2681
3669
    // quit if run by the _changed callbacks
2682
 
    if (g_object_get_data(G_OBJECT(tbl), "freeze")) {
 
3670
    if (g_object_get_data( tbl, "freeze" )) {
2683
3671
        return;
2684
3672
    }
2685
3673
 
2686
3674
    // in turn, prevent callbacks from responding
2687
 
    g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE));
 
3675
    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) );
2688
3676
 
2689
3677
    gdouble start = sp_repr_get_double_attribute(repr, "sodipodi:start", 0.0);
2690
3678
    gdouble end = sp_repr_get_double_attribute(repr, "sodipodi:end", 0.0);
2691
3679
 
2692
3680
    GtkAdjustment *adj1,*adj2;
2693
 
    adj1 = (GtkAdjustment*)gtk_object_get_data(GTK_OBJECT(tbl), "start");
 
3681
    adj1 = GTK_ADJUSTMENT( g_object_get_data( tbl, "start" ) );
2694
3682
    gtk_adjustment_set_value(adj1, mod360((start * 180)/M_PI));
2695
 
    adj2 = (GtkAdjustment*)gtk_object_get_data(GTK_OBJECT(tbl), "end");
 
3683
    adj2 = GTK_ADJUSTMENT( g_object_get_data( tbl, "end" ) );
2696
3684
    gtk_adjustment_set_value(adj2, mod360((end * 180)/M_PI));
2697
3685
 
2698
 
    sp_arctb_sensitivize (tbl, adj1->value, adj2->value);
 
3686
    sp_arctb_sensitivize( tbl, adj1->value, adj2->value );
2699
3687
 
2700
3688
    char const *openstr = NULL;
2701
3689
    openstr = repr->attribute("sodipodi:open");
2702
 
    GtkWidget *ocb = (GtkWidget*) g_object_get_data(G_OBJECT(tbl), "open_checkbox");
 
3690
    EgeSelectOneAction *ocb = EGE_SELECT_ONE_ACTION( g_object_get_data( tbl, "open_action" ) );
2703
3691
 
2704
3692
    if (openstr) {
2705
 
        gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(ocb),  TRUE);
 
3693
        ege_select_one_action_set_active( ocb, 1 );
2706
3694
    } else {
2707
 
        gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(ocb),  FALSE);
 
3695
        ege_select_one_action_set_active( ocb, 0 );
2708
3696
    }
2709
3697
 
2710
 
    g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(FALSE));
 
3698
    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
2711
3699
}
2712
3700
 
2713
3701
static Inkscape::XML::NodeEventVector arc_tb_repr_events = {
2719
3707
};
2720
3708
 
2721
3709
 
2722
 
static void
2723
 
sp_arc_toolbox_selection_changed(Inkscape::Selection *selection, GtkObject *tbl)
 
3710
static void sp_arc_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl)
2724
3711
{
2725
3712
    int n_selected = 0;
2726
3713
    Inkscape::XML::Node *repr = NULL;
2727
 
    Inkscape::XML::Node *oldrepr = NULL;
 
3714
 
 
3715
    purge_repr_listener( tbl, tbl );
2728
3716
 
2729
3717
    for (GSList const *items = selection->itemList();
2730
3718
         items != NULL;
2736
3724
        }
2737
3725
    }
2738
3726
 
2739
 
    GtkWidget *l = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(tbl), "mode_label"));
 
3727
    EgeOutputAction* act = EGE_OUTPUT_ACTION( g_object_get_data( tbl, "mode_action" ) );
2740
3728
 
2741
 
    g_object_set_data(G_OBJECT(tbl), "single", GINT_TO_POINTER(FALSE));
 
3729
    g_object_set_data( tbl, "single", GINT_TO_POINTER(FALSE) );
2742
3730
    if (n_selected == 0) {
2743
 
        gtk_label_set_markup(GTK_LABEL(l), _("<b>New:</b>"));
 
3731
        g_object_set( G_OBJECT(act), "label", _("<b>New:</b>"), NULL );
2744
3732
    } else if (n_selected == 1) {
2745
 
        g_object_set_data(G_OBJECT(tbl), "single", GINT_TO_POINTER(TRUE));
2746
 
        gtk_label_set_markup(GTK_LABEL(l), _("<b>Change:</b>"));
2747
 
 
2748
 
        oldrepr = (Inkscape::XML::Node *) gtk_object_get_data(GTK_OBJECT(tbl), "repr");
2749
 
 
2750
 
        if (oldrepr) { // remove old listener
2751
 
            sp_repr_remove_listener_by_data(oldrepr, tbl);
2752
 
            Inkscape::GC::release(oldrepr);
2753
 
            oldrepr = 0;
2754
 
            g_object_set_data(G_OBJECT(tbl), "repr", NULL);
2755
 
        }
 
3733
        g_object_set_data( tbl, "single", GINT_TO_POINTER(TRUE) );
 
3734
        g_object_set( G_OBJECT(act), "label", _("<b>Change:</b>"), NULL );
2756
3735
 
2757
3736
        if (repr) {
2758
 
            g_object_set_data(G_OBJECT(tbl), "repr", repr);
 
3737
            g_object_set_data( tbl, "repr", repr );
2759
3738
            Inkscape::GC::anchor(repr);
2760
3739
            sp_repr_add_listener(repr, &arc_tb_repr_events, tbl);
2761
3740
            sp_repr_synthesize_events(repr, &arc_tb_repr_events, tbl);
2763
3742
    } else {
2764
3743
        // FIXME: implement averaging of all parameters for multiple selected
2765
3744
        //gtk_label_set_markup(GTK_LABEL(l), _("<b>Average:</b>"));
2766
 
        gtk_label_set_markup(GTK_LABEL(l), _("<b>Change:</b>"));
2767
 
        sp_arctb_sensitivize (GTK_WIDGET(tbl), 1, 0);
 
3745
        g_object_set( G_OBJECT(act), "label", _("<b>Change:</b>"), NULL );
 
3746
        sp_arctb_sensitivize( tbl, 1, 0 );
2768
3747
    }
2769
3748
}
2770
3749
 
2771
3750
 
2772
 
static GtkWidget *
2773
 
sp_arc_toolbox_new(SPDesktop *desktop)
 
3751
static void sp_arc_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
2774
3752
{
2775
 
    GtkWidget *tbl = gtk_hbox_new(FALSE, 0);
2776
 
 
2777
 
    gtk_object_set_data(GTK_OBJECT(tbl), "dtw", desktop->canvas);
2778
 
    gtk_object_set_data(GTK_OBJECT(tbl), "desktop", desktop);
2779
 
 
2780
 
    GtkTooltips *tt = gtk_tooltips_new();
2781
 
 
2782
 
    sp_toolbox_add_label(tbl, _("<b>New:</b>"));
 
3753
    EgeAdjustmentAction* eact = 0;
 
3754
 
 
3755
 
 
3756
    {
 
3757
        EgeOutputAction* act = ege_output_action_new( "ArcStateAction", _("<b>New:</b>"), "", 0 );
 
3758
        ege_output_action_set_use_markup( act, TRUE );
 
3759
        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
 
3760
        g_object_set_data( holder, "mode_action", act );
 
3761
    }
2783
3762
 
2784
3763
    /* Start */
2785
3764
    {
2786
 
        GtkWidget *hb = sp_tb_spinbutton(_("Start:"), _("The angle (in degrees) from the horizontal to the arc's start point"),
 
3765
        eact = create_adjustment_action( "ArcStartAction",
 
3766
                                         _("Start"), _("Start:"),
 
3767
                                         _("The angle (in degrees) from the horizontal to the arc's start point"),
2787
3768
                                         "tools.shapes.arc", "start", 0.0,
2788
 
                                         NULL, tbl, TRUE, "altx-arc",
 
3769
                                         GTK_WIDGET(desktop->canvas), NULL/*us*/, holder, TRUE, "altx-arc",
2789
3770
                                         -360.0, 360.0, 1.0, 10.0,
 
3771
                                         0, 0, 0,
2790
3772
                                         sp_arctb_start_value_changed);
2791
 
        gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
 
3773
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
2792
3774
    }
2793
3775
 
2794
3776
    /* End */
2795
3777
    {
2796
 
        GtkWidget *hb = sp_tb_spinbutton(_("End:"), _("The angle (in degrees) from the horizontal to the arc's end point"),
 
3778
        eact = create_adjustment_action( "ArcEndAction",
 
3779
                                         _("End"), _("End:"),
 
3780
                                         _("The angle (in degrees) from the horizontal to the arc's end point"),
2797
3781
                                         "tools.shapes.arc", "end", 0.0,
2798
 
                                         NULL, tbl, FALSE, NULL,
 
3782
                                         GTK_WIDGET(desktop->canvas), NULL/*us*/, holder, FALSE, NULL,
2799
3783
                                         -360.0, 360.0, 1.0, 10.0,
 
3784
                                         0, 0, 0,
2800
3785
                                         sp_arctb_end_value_changed);
2801
 
        gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
 
3786
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
2802
3787
    }
2803
3788
 
2804
3789
    /* Segments / Pie checkbox */
2805
3790
    {
2806
 
        GtkWidget *hb = gtk_hbox_new(FALSE, 1);
2807
 
        GtkWidget *fscb = gtk_check_button_new_with_label(_("Open arc"));
2808
 
        gtk_tooltips_set_tip(tt, fscb, _("Switch between arc (unclosed shape) and segment (closed shape with two radii)"), NULL);
2809
 
 
2810
 
        gchar const *openstr = NULL;
2811
 
        openstr = prefs_get_string_attribute("tools.shapes.arc", "open");
2812
 
        if (!openstr || (openstr && !strcmp(openstr, "false")))
2813
 
            gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(fscb),  FALSE);
2814
 
        else
2815
 
            gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(fscb),  TRUE);
2816
 
 
2817
 
        gtk_widget_show(fscb);
2818
 
        gtk_object_set_data(GTK_OBJECT(tbl), "open_checkbox", fscb);
2819
 
        gtk_container_add(GTK_CONTAINER(hb), fscb);
2820
 
        g_signal_connect(G_OBJECT(fscb), "toggled", GTK_SIGNAL_FUNC(sp_arctb_open_state_changed ), tbl);
2821
 
        gtk_box_pack_start(GTK_BOX(tbl),hb, FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
 
3791
        GtkListStore* model = gtk_list_store_new( 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING );
 
3792
 
 
3793
        GtkTreeIter iter;
 
3794
        gtk_list_store_append( model, &iter );
 
3795
        gtk_list_store_set( model, &iter,
 
3796
                            0, _("Closed arc"),
 
3797
                            1, _("Switch to segment (closed shape with two radii)"),
 
3798
                            2, "circle_closed_arc",
 
3799
                            -1 );
 
3800
 
 
3801
        gtk_list_store_append( model, &iter );
 
3802
        gtk_list_store_set( model, &iter,
 
3803
                            0, _("Open Arc"),
 
3804
                            1, _("Switch to arc (unclosed shape)"),
 
3805
                            2, "circle_open_arc",
 
3806
                            -1 );
 
3807
 
 
3808
        EgeSelectOneAction* act = ege_select_one_action_new( "ArcOpenAction", (""), (""), NULL, GTK_TREE_MODEL(model) );
 
3809
        gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
 
3810
        g_object_set_data( holder, "open_action", act );
 
3811
 
 
3812
        ege_select_one_action_set_appearance( act, "full" );
 
3813
        ege_select_one_action_set_radio_action_type( act, INK_RADIO_ACTION_TYPE );
 
3814
        g_object_set( G_OBJECT(act), "icon-property", "iconId", NULL );
 
3815
        ege_select_one_action_set_icon_column( act, 2 );
 
3816
        ege_select_one_action_set_tooltip_column( act, 1  );
 
3817
 
 
3818
        gchar const *openstr = prefs_get_string_attribute("tools.shapes.arc", "open");
 
3819
        bool isClosed = (!openstr || (openstr && !strcmp(openstr, "false")));
 
3820
        ege_select_one_action_set_active( act, isClosed ? 0 : 1 );
 
3821
        g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_arctb_open_state_changed), holder );
2822
3822
    }
2823
3823
 
2824
3824
    /* Make Whole */
2825
3825
    {
2826
 
        GtkWidget *hb = gtk_hbox_new(FALSE, 1);
2827
 
        GtkWidget *b = gtk_button_new_with_label(_("Make whole"));
2828
 
        gtk_object_set_data(GTK_OBJECT(tbl), "make_whole", b);
2829
 
        gtk_tooltips_set_tip(tt, b, _("Make the shape a whole ellipse, not arc or segment"), NULL);
2830
 
        gtk_widget_show(b);
2831
 
        gtk_container_add(GTK_CONTAINER(hb), b);
2832
 
        gtk_signal_connect(GTK_OBJECT(b), "clicked", GTK_SIGNAL_FUNC(sp_arctb_defaults), tbl);
2833
 
        gtk_box_pack_start(GTK_BOX(tbl),hb, FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
 
3826
        InkAction* inky = ink_action_new( "ArcResetAction",
 
3827
                                          _("Make whole"),
 
3828
                                          _("Make the shape a whole ellipse, not arc or segment"),
 
3829
                                          "reset_circle",
 
3830
                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
 
3831
        g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_arctb_defaults), holder );
 
3832
        gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
 
3833
        gtk_action_set_sensitive( GTK_ACTION(inky), TRUE );
 
3834
        g_object_set_data( holder, "make_whole", inky );
2834
3835
    }
2835
3836
 
2836
 
    g_object_set_data(G_OBJECT(tbl), "single", GINT_TO_POINTER(TRUE));
 
3837
    g_object_set_data( G_OBJECT(holder), "single", GINT_TO_POINTER(TRUE) );
2837
3838
    // sensitivize make whole and open checkbox
2838
3839
    {
2839
 
        GtkAdjustment *adj1 = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(tbl), "start"));
2840
 
        GtkAdjustment *adj2 = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(tbl), "end"));
2841
 
        sp_arctb_sensitivize (tbl, adj1->value, adj2->value);
 
3840
        GtkAdjustment *adj1 = GTK_ADJUSTMENT( g_object_get_data( holder, "start" ) );
 
3841
        GtkAdjustment *adj2 = GTK_ADJUSTMENT( g_object_get_data( holder, "end" ) );
 
3842
        sp_arctb_sensitivize( holder, adj1->value, adj2->value );
2842
3843
    }
2843
3844
 
 
3845
 
2844
3846
    sigc::connection *connection = new sigc::connection(
2845
 
        sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_arc_toolbox_selection_changed), (GtkObject *)tbl))
 
3847
        sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_arc_toolbox_selection_changed), (GObject *)holder))
2846
3848
        );
2847
 
    g_signal_connect(G_OBJECT(tbl), "destroy", G_CALLBACK(delete_connection), connection);
2848
 
 
2849
 
    Inkscape::UI::Widget::StyleSwatch *swatch = new Inkscape::UI::Widget::StyleSwatch(NULL);
2850
 
    swatch->setWatchedTool ("tools.shapes.arc", true);
2851
 
    GtkWidget *swatch_ = GTK_WIDGET(swatch->gobj());
2852
 
    gtk_box_pack_end(GTK_BOX(tbl), swatch_, FALSE, FALSE, 0);
2853
 
 
2854
 
    gtk_widget_show_all(tbl);
2855
 
    sp_set_font_size_smaller (tbl);
2856
 
 
2857
 
    return tbl;
 
3849
    g_signal_connect( holder, "destroy", G_CALLBACK(delete_connection), connection );
 
3850
    g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder );
2858
3851
}
2859
3852
 
2860
3853
 
2866
3859
//##      Dropper       ##
2867
3860
//########################
2868
3861
 
2869
 
static void toggle_dropper_pick_alpha (GtkWidget *button, gpointer tbl) {
2870
 
    prefs_set_int_attribute ("tools.dropper", "pick", 
2871
 
        gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)));
2872
 
    GtkWidget *set_checkbox = (GtkWidget*) g_object_get_data(G_OBJECT(tbl), "set_checkbox");
2873
 
    if (set_checkbox) {
2874
 
        if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) {
2875
 
            gtk_widget_set_sensitive (GTK_WIDGET (set_checkbox), TRUE);
 
3862
static void toggle_dropper_pick_alpha( GtkToggleAction* act, gpointer tbl ) {
 
3863
    prefs_set_int_attribute( "tools.dropper", "pick", gtk_toggle_action_get_active( act ) );
 
3864
    GtkAction* set_action = GTK_ACTION( g_object_get_data(G_OBJECT(tbl), "set_action") );
 
3865
    if ( set_action ) {
 
3866
        if ( gtk_toggle_action_get_active( act ) ) {
 
3867
            gtk_action_set_sensitive( set_action, TRUE );
2876
3868
        } else {
2877
 
            gtk_widget_set_sensitive (GTK_WIDGET (set_checkbox), FALSE);
 
3869
            gtk_action_set_sensitive( set_action, FALSE );
2878
3870
        }
2879
3871
    }
2880
 
    spinbutton_defocus(GTK_OBJECT(tbl));
2881
 
}
2882
 
 
2883
 
static void toggle_dropper_set_alpha (GtkWidget *button, gpointer tbl) {
2884
 
    prefs_set_int_attribute ("tools.dropper", "setalpha", 
2885
 
        gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) ? 1 : 0);
2886
 
    spinbutton_defocus(GTK_OBJECT(tbl));
2887
 
}
2888
 
 
2889
 
 
2890
 
/**
2891
 
 * Copy the current saved desktop color to the clipboard as full hex + alpha
2892
 
 * color representation. This is useful for passing values between various 
2893
 
 * input boxes, or directly to xml.
2894
 
 */
2895
 
/* static void
2896
 
sp_dropper_copy( GtkWidget *widget, GtkObject *obj)
2897
 
{
2898
 
    GtkWidget *tbl = GTK_WIDGET(obj);
2899
 
    
2900
 
    SPDesktop *desktop = 
2901
 
        (SPDesktop *) gtk_object_get_data(GTK_OBJECT(tbl), "desktop");
2902
 
 
2903
 
   
2904
 
    sp_dropper_c32_color_copy( sp_desktop_get_color(desktop, true) );
2905
 
}*/
2906
 
 
2907
 
 
2908
 
/**
2909
 
 * Copies currently saved desktop color to the clipboard as a hex value. This 
2910
 
 * is useful for editing webpages and needing a value quickly for web
2911
 
 * colors.
2912
 
 * 
2913
 
 * TODO: When the toggle of the dropper is set to not mix color against 
2914
 
 *       page background, this still just gets the color of the page and 
2915
 
 *       doesn't get the actual mixed against background which is needed 
2916
 
 *       for the hex value ppl. want for web pages, etc.
2917
 
 */
2918
 
 
2919
 
/* static void
2920
 
sp_dropper_copy_as_hex ( GtkWidget *widget, GtkObject *obj)
2921
 
{
2922
 
    GtkWidget *tbl = GTK_WIDGET(obj);
2923
 
    
2924
 
    SPDesktop *desktop = 
2925
 
        (SPDesktop *) gtk_object_get_data(GTK_OBJECT(tbl), "desktop");
2926
 
    
2927
 
    sp_dropper_c32_color_copy_hex( sp_desktop_get_color(desktop, true) );
2928
 
}*/
2929
 
 
2930
 
 
2931
 
/**
2932
 
 * Sets the input boxes with the changed color and opacity. This is used as a 
2933
 
 * callback for style changing.
2934
 
 */
2935
 
/* static bool
2936
 
sp_style_changed (const SPCSSAttr *css, gpointer data)
2937
 
{
2938
 
    // GrDrag *drag = (GrDrag *) data;
2939
 
    
2940
 
    // set fill of text entry box
2941
 
    if (css->attribute("fill"))
2942
 
        gtk_entry_set_text((GtkEntry *)dropper_rgb_entry, 
2943
 
            css->attribute("fill")); 
2944
 
 
2945
 
    // set opacity of text entry box
2946
 
    if (css->attribute("fill-opacity"))
2947
 
        gtk_entry_set_text((GtkEntry *)dropper_opacity_entry, 
2948
 
            css->attribute("fill-opacity")); 
2949
 
    
2950
 
    // set fill of text entry box
2951
 
    if (css->attribute("stroke"))
2952
 
        gtk_entry_set_text((GtkEntry *)dropper_rgb_entry, 
2953
 
            css->attribute("stroke")); 
2954
 
 
2955
 
    // set opacity of text entry box
2956
 
    if (css->attribute("stroke-opacity"))
2957
 
        gtk_entry_set_text((GtkEntry *)dropper_opacity_entry, 
2958
 
            css->attribute("stroke-opacity"));
2959
 
    return false;
2960
 
 
2961
 
}
2962
 
*/
 
3872
 
 
3873
    spinbutton_defocus(GTK_OBJECT(tbl));
 
3874
}
 
3875
 
 
3876
static void toggle_dropper_set_alpha( GtkToggleAction* act, gpointer tbl ) {
 
3877
    prefs_set_int_attribute( "tools.dropper", "setalpha", gtk_toggle_action_get_active( act ) ? 1 : 0 );
 
3878
    spinbutton_defocus(GTK_OBJECT(tbl));
 
3879
}
2963
3880
 
2964
3881
 
2965
3882
/**
2969
3886
 * TODO: Add queue of last 5 or so colors selected with new swatches so that
2970
3887
 *       can drag and drop places. Will provide a nice mixing palette.
2971
3888
 */
2972
 
static GtkWidget *
2973
 
sp_dropper_toolbox_new(SPDesktop *desktop)
 
3889
static void sp_dropper_toolbox_prep(SPDesktop */*desktop*/, GtkActionGroup* mainActions, GObject* holder)
2974
3890
{
2975
 
    GtkWidget *tbl = gtk_hbox_new(FALSE, 0);
2976
 
 
2977
 
    gtk_object_set_data(GTK_OBJECT(tbl), "dtw", desktop->canvas);
2978
 
    gtk_object_set_data(GTK_OBJECT(tbl), "desktop", desktop);
2979
 
 
2980
 
    GtkTooltips *tt = gtk_tooltips_new();
2981
 
 
2982
 
    
2983
 
    gtk_box_pack_start(GTK_BOX(tbl), gtk_hbox_new(FALSE, 0), FALSE, FALSE, 
2984
 
                       AUX_BETWEEN_BUTTON_GROUPS);
2985
 
    // sp_toolbox_add_label(tbl, _("<b>New:</b>"));
2986
 
 
2987
 
 
2988
 
    
2989
 
    /* RGB Input Field */
2990
 
 /*   {
2991
 
        GtkWidget *hb = gtk_hbox_new(FALSE, 1);
2992
 
        GtkWidget *dropper_rgba_label = gtk_label_new ("Color:");
2993
 
        gtk_widget_show (dropper_rgba_label);
2994
 
        gtk_container_add(GTK_CONTAINER(hb), dropper_rgba_label);
2995
 
        
2996
 
        dropper_rgb_entry = gtk_entry_new ();
2997
 
        sp_dialog_defocus_on_enter (dropper_rgb_entry);
2998
 
        gtk_entry_set_max_length (GTK_ENTRY (dropper_rgb_entry), 7);
2999
 
        gtk_entry_set_width_chars (GTK_ENTRY (dropper_rgb_entry), 7);
3000
 
        gtk_tooltips_set_tip(tt, dropper_rgb_entry, 
3001
 
                         _("Hexidecimal representation of last selected "
3002
 
                           "color"), 
3003
 
                         NULL);
3004
 
        gtk_widget_show (dropper_rgb_entry);
3005
 
        gtk_container_add(GTK_CONTAINER(hb), dropper_rgb_entry);
3006
 
        
3007
 
        gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, 
3008
 
                           AUX_BETWEEN_BUTTON_GROUPS);
3009
 
    } */
3010
 
    
3011
 
    /* Opacity Input Field */
3012
 
/*    {
3013
 
        GtkWidget *hb = gtk_hbox_new(FALSE, 1);
3014
 
        GtkWidget *dropper_opacity_label = gtk_label_new ( _("Opacity:") );
3015
 
        gtk_widget_show (dropper_opacity_label);
3016
 
        gtk_container_add(GTK_CONTAINER(hb), dropper_opacity_label);
3017
 
        
3018
 
        dropper_opacity_entry = gtk_entry_new ();
3019
 
        sp_dialog_defocus_on_enter (dropper_opacity_entry);
3020
 
        gtk_entry_set_max_length (GTK_ENTRY (dropper_opacity_entry), 11);
3021
 
        gtk_entry_set_width_chars (GTK_ENTRY (dropper_opacity_entry), 11);
3022
 
        gtk_tooltips_set_tip(tt, dropper_opacity_entry, 
3023
 
                         _("Opacity of last selected color"), 
3024
 
                         NULL);
3025
 
        gtk_widget_show (dropper_opacity_entry);
3026
 
        gtk_container_add(GTK_CONTAINER(hb), dropper_opacity_entry);
3027
 
        
3028
 
        gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, 
3029
 
                           AUX_BETWEEN_BUTTON_GROUPS);
3030
 
    } */
3031
 
    
3032
 
    
3033
 
    /* Copy to Clipboard */
3034
 
/*    {
3035
 
        GtkWidget *hb = gtk_hbox_new(FALSE, 1);
3036
 
        GtkWidget *b = gtk_button_new_with_label(_("Copy as RGBA"));
3037
 
        gtk_tooltips_set_tip(tt, b, _("Copy last saved color as hexidecimal "
3038
 
                                      "RGB + Alpha (RGBA) to "
3039
 
                                      "clipboard"), 
3040
 
                             NULL);
3041
 
        gtk_widget_show(b);
3042
 
        gtk_container_add(GTK_CONTAINER(hb), b);
3043
 
        gtk_signal_connect(GTK_OBJECT(b), "clicked", 
3044
 
            GTK_SIGNAL_FUNC(sp_dropper_copy), tbl);
3045
 
        gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, 
3046
 
                           AUX_BETWEEN_BUTTON_GROUPS);
3047
 
    } */
3048
 
 
3049
 
 
3050
 
    /* Copy to Clipboard as HEX */
3051
 
/*    {
3052
 
        GtkWidget *hb = gtk_hbox_new(FALSE, 1);
3053
 
        GtkWidget *b = gtk_button_new_with_label(_("Copy as HEX"));
3054
 
        gtk_tooltips_set_tip(tt, b, _("Copy last saved color as "
3055
 
                                      "hexidecimal RGB without alpha " 
3056
 
                                      "to clipboard"), NULL);
3057
 
        gtk_widget_show(b);
3058
 
        gtk_container_add(GTK_CONTAINER(hb), b);
3059
 
        gtk_signal_connect(GTK_OBJECT(b), "clicked", 
3060
 
            GTK_SIGNAL_FUNC(sp_dropper_copy_as_hex), tbl);
3061
 
        gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, 
3062
 
                           AUX_BETWEEN_BUTTON_GROUPS);
3063
 
    } */
3064
 
    
3065
 
    // aux_toolbox_space(tbl, AUX_BETWEEN_BUTTON_GROUPS);
3066
 
    
 
3891
    gint pickAlpha = prefs_get_int_attribute( "tools.dropper", "pick", 1 );
 
3892
 
3067
3893
    {
3068
 
        GtkWidget *hb = gtk_hbox_new(FALSE, 1);
3069
 
 
3070
 
        GtkWidget *button = gtk_check_button_new_with_label(_("Pick alpha"));
3071
 
        gtk_tooltips_set_tip(tt, button, _("Pick both the color and the alpha (transparency) under cursor; otherwise, pick only the visible color premultiplied by alpha"), NULL);
3072
 
        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), 
3073
 
                                      prefs_get_int_attribute ("tools.dropper", 
3074
 
                                                               "pick", 1));
3075
 
        gtk_widget_show(button);
3076
 
        gtk_container_add (GTK_CONTAINER (hb), button);
3077
 
        gtk_object_set_data(GTK_OBJECT(tbl), "pick_checkbox", button);
3078
 
        g_signal_connect (G_OBJECT (button), "toggled", G_CALLBACK (toggle_dropper_pick_alpha), tbl);
3079
 
        gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, 
3080
 
                   AUX_BETWEEN_BUTTON_GROUPS);
 
3894
        InkToggleAction* act = ink_toggle_action_new( "DropperPickAlphaAction",
 
3895
                                                      _("Pick alpha"),
 
3896
                                                      _("Pick both the color and the alpha (transparency) under cursor; otherwise, pick only the visible color premultiplied by alpha"),
 
3897
                                                      "color_alpha_get",
 
3898
                                                      Inkscape::ICON_SIZE_DECORATION );
 
3899
        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
 
3900
        g_object_set_data( holder, "pick_action", act );
 
3901
        gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), pickAlpha );
 
3902
        g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_dropper_pick_alpha), holder );
3081
3903
    }
3082
3904
 
3083
3905
    {
3084
 
        GtkWidget *hb = gtk_hbox_new(FALSE, 1);
3085
 
 
3086
 
        GtkWidget *button = gtk_check_button_new_with_label(_("Set alpha"));
3087
 
        gtk_tooltips_set_tip(tt, button, _("If alpha was picked, assign it to selection as fill or stroke transparency"), NULL);
3088
 
        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), 
3089
 
                                      prefs_get_int_attribute ("tools.dropper", 
3090
 
                                                               "setalpha", 1));
3091
 
        gtk_widget_show(button);
3092
 
        gtk_container_add (GTK_CONTAINER (hb), button);
3093
 
        gtk_object_set_data(GTK_OBJECT(tbl), "set_checkbox", button);
3094
 
        g_signal_connect (G_OBJECT (button), "toggled", G_CALLBACK (toggle_dropper_set_alpha), tbl);
3095
 
 
 
3906
        InkToggleAction* act = ink_toggle_action_new( "DropperSetAlphaAction",
 
3907
                                                      _("Set alpha"),
 
3908
                                                      _("If alpha was picked, assign it to selection as fill or stroke transparency"),
 
3909
                                                      "color_alpha_set",
 
3910
                                                      Inkscape::ICON_SIZE_DECORATION );
 
3911
        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
 
3912
        g_object_set_data( holder, "set_action", act );
 
3913
        gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.dropper", "setalpha", 1 ) );
3096
3914
        // make sure it's disabled if we're not picking alpha
3097
 
        GtkWidget *pick_checkbox = (GtkWidget*) g_object_get_data(G_OBJECT(tbl), "pick_checkbox");
3098
 
        if (pick_checkbox) {
3099
 
            if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (pick_checkbox))) {
3100
 
                gtk_widget_set_sensitive (GTK_WIDGET (button), TRUE);
3101
 
            } else {
3102
 
                gtk_widget_set_sensitive (GTK_WIDGET (button), FALSE);
3103
 
            }
3104
 
        }
3105
 
 
3106
 
        gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, 
3107
 
                   AUX_BETWEEN_BUTTON_GROUPS);
 
3915
        gtk_action_set_sensitive( GTK_ACTION(act), pickAlpha );
 
3916
        g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_dropper_set_alpha), holder );
3108
3917
    }
3109
 
   
3110
 
    aux_toolbox_space(tbl, AUX_BETWEEN_BUTTON_GROUPS);
3111
 
    
3112
 
 
3113
 
    // where new gtkmm stuff should go
3114
 
    
3115
 
    gtk_widget_show_all(tbl);
3116
 
    sp_set_font_size_smaller (tbl);
3117
 
 
3118
 
    /*
3119
 
    sigc::connection *connection = new sigc::connection(
3120
 
        desktop->connectSetStyle(
3121
 
            sigc::bind(sigc::ptr_fun(sp_style_changed), 
3122
 
                       desktop)) ); 
3123
 
    
3124
 
    g_signal_connect(G_OBJECT(tbl), "destroy", G_CALLBACK(delete_connection), 
3125
 
                     connection); */
3126
 
    
3127
 
    return tbl;
3128
3918
}
3129
3919
 
3130
3920
 
3167
3957
bool visible = false;
3168
3958
 
3169
3959
void
3170
 
sp_text_toolbox_selection_changed (Inkscape::Selection *selection, GObject *tbl)
 
3960
sp_text_toolbox_selection_changed (Inkscape::Selection */*selection*/, GObject *tbl)
3171
3961
{
3172
 
 
3173
3962
    SPStyle *query =
3174
 
        sp_style_new ();
 
3963
        sp_style_new (SP_ACTIVE_DOCUMENT);
 
3964
    
 
3965
    int result_fontspec =
 
3966
        sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION);
3175
3967
 
3176
3968
    int result_family =
3177
 
        sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); 
 
3969
        sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY);
3178
3970
 
3179
3971
    int result_style =
3180
 
        sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE); 
 
3972
        sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE);
3181
3973
 
3182
3974
    int result_numbers =
3183
 
        sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); 
 
3975
        sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS);
3184
3976
 
3185
 
    gtk_widget_hide (GTK_WIDGET (g_object_get_data (G_OBJECT(tbl), "warning-image")));        
 
3977
    gtk_widget_hide (GTK_WIDGET (g_object_get_data (G_OBJECT(tbl), "warning-image")));
3186
3978
 
3187
3979
    // If querying returned nothing, read the style from the text tool prefs (default style for new texts)
3188
3980
    if (result_family == QUERY_STYLE_NOTHING || result_style == QUERY_STYLE_NOTHING || result_numbers == QUERY_STYLE_NOTHING)
3205
3997
            GtkWidget *entry = GTK_WIDGET (g_object_get_data (G_OBJECT (tbl), "family-entry"));
3206
3998
            gtk_entry_set_text (GTK_ENTRY (entry), "");
3207
3999
 
3208
 
        } else if (query->text->font_family.value) {
 
4000
        } else if (query->text->font_specification.value || query->text->font_family.value) {
3209
4001
 
3210
4002
            GtkWidget *entry = GTK_WIDGET (g_object_get_data (G_OBJECT (tbl), "family-entry"));
3211
 
            gtk_entry_set_text (GTK_ENTRY (entry), query->text->font_family.value);
 
4003
            
 
4004
            // Get the font that corresponds 
 
4005
            Glib::ustring familyName;
 
4006
            
 
4007
            font_instance * font = font_factory::Default()->FaceFromStyle(query);
 
4008
            if (font) {
 
4009
                familyName = font_factory::Default()->GetUIFamilyString(font->descr);
 
4010
                font->Unref();
 
4011
                font = NULL;
 
4012
            }
 
4013
            
 
4014
            gtk_entry_set_text (GTK_ENTRY (entry), familyName.c_str());
3212
4015
 
3213
4016
            Gtk::TreePath path;
3214
4017
            try {
3215
 
                path = Inkscape::FontLister::get_instance()->get_row_for_font (query->text->font_family.value);
 
4018
                path = Inkscape::FontLister::get_instance()->get_row_for_font (familyName);
3216
4019
            } catch (...) {
 
4020
                g_warning("Family name %s does not have an entry in the font lister.", familyName.c_str());
3217
4021
                return;
3218
4022
            }
3219
4023
 
3220
4024
            GtkTreeSelection *tselection = GTK_TREE_SELECTION (g_object_get_data (G_OBJECT(tbl), "family-tree-selection"));
3221
4025
            GtkTreeView *treeview = GTK_TREE_VIEW (g_object_get_data (G_OBJECT(tbl), "family-tree-view"));
3222
4026
 
3223
 
            g_object_set_data (G_OBJECT (tselection), "block", gpointer(1)); 
 
4027
            g_object_set_data (G_OBJECT (tselection), "block", gpointer(1));
3224
4028
 
3225
4029
            gtk_tree_selection_select_path (tselection, path.gobj());
3226
4030
            gtk_tree_view_scroll_to_cell (treeview, path.gobj(), NULL, TRUE, 0.5, 0.0);
3227
4031
 
3228
 
            g_object_set_data (G_OBJECT (tselection), "block", gpointer(0)); 
 
4032
            g_object_set_data (G_OBJECT (tselection), "block", gpointer(0));
3229
4033
        }
3230
4034
 
3231
4035
        //Size
3232
4036
        GtkWidget *cbox = GTK_WIDGET (g_object_get_data (G_OBJECT (tbl), "combo-box-size"));
3233
4037
        char *str = g_strdup_printf ("%.5g", query->font_size.computed);
3234
 
        g_object_set_data (tbl, "size-block", gpointer(1)); 
 
4038
        g_object_set_data (tbl, "size-block", gpointer(1));
3235
4039
        gtk_entry_set_text (GTK_ENTRY(GTK_BIN (cbox)->child), str);
3236
 
        g_object_set_data (tbl, "size-block", gpointer(0)); 
 
4040
        g_object_set_data (tbl, "size-block", gpointer(0));
3237
4041
        free (str);
3238
4042
 
3239
4043
        //Anchor
3274
4078
            GtkToggleButton *button = GTK_TOGGLE_BUTTON (g_object_get_data (G_OBJECT (tbl), "style-bold"));
3275
4079
 
3276
4080
            gboolean active = gtk_toggle_button_get_active (button);
3277
 
            gboolean check  = (query->font_weight.computed >= SP_CSS_FONT_WEIGHT_700); 
 
4081
            gboolean check  = (query->font_weight.computed >= SP_CSS_FONT_WEIGHT_700);
3278
4082
 
3279
 
            if (active != check) 
 
4083
            if (active != check)
3280
4084
            {
3281
4085
                g_object_set_data (G_OBJECT (button), "block", gpointer(1));
3282
 
                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), check); 
 
4086
                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), check);
3283
4087
                g_object_set_data (G_OBJECT (button), "block", gpointer(0));
3284
4088
            }
3285
4089
        }
3288
4092
            GtkToggleButton *button = GTK_TOGGLE_BUTTON (g_object_get_data (G_OBJECT (tbl), "style-italic"));
3289
4093
 
3290
4094
            gboolean active = gtk_toggle_button_get_active (button);
3291
 
            gboolean check  = (query->font_style.computed != SP_CSS_FONT_STYLE_NORMAL); 
 
4095
            gboolean check  = (query->font_style.computed != SP_CSS_FONT_STYLE_NORMAL);
3292
4096
 
3293
4097
            if (active != check)
3294
4098
            {
3295
4099
                g_object_set_data (G_OBJECT (button), "block", gpointer(1));
3296
 
                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), check); 
 
4100
                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), check);
3297
4101
                g_object_set_data (G_OBJECT (button), "block", gpointer(0));
3298
4102
            }
3299
4103
        }
3302
4106
        //locking both buttons, changing one affect all group (both)
3303
4107
        GtkWidget *button = GTK_WIDGET (g_object_get_data (G_OBJECT (tbl), "orientation-horizontal"));
3304
4108
        g_object_set_data (G_OBJECT (button), "block", gpointer(1));
3305
 
        
 
4109
 
3306
4110
        GtkWidget *button1 = GTK_WIDGET (g_object_get_data (G_OBJECT (tbl), "orientation-vertical"));
3307
4111
        g_object_set_data (G_OBJECT (button1), "block", gpointer(1));
3308
 
        
 
4112
 
3309
4113
        if (query->writing_mode.computed == SP_CSS_WRITING_MODE_LR_TB)
3310
4114
        {
3311
4115
            gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
3317
4121
        g_object_set_data (G_OBJECT (button), "block", gpointer(0));
3318
4122
        g_object_set_data (G_OBJECT (button1), "block", gpointer(0));
3319
4123
    }
3320
 
}
3321
 
 
3322
 
void
3323
 
sp_text_toolbox_selection_modified (Inkscape::Selection *selection, guint flags, GObject *tbl) 
3324
 
{
3325
 
    sp_text_toolbox_selection_changed (selection, tbl); 
3326
 
}
3327
 
 
3328
 
void
3329
 
sp_text_toolbox_subselection_changed (gpointer dragger, GObject *tbl)
3330
 
{
3331
 
    sp_text_toolbox_selection_changed (NULL, tbl); 
 
4124
 
 
4125
    sp_style_unref(query);
 
4126
}
 
4127
 
 
4128
void
 
4129
sp_text_toolbox_selection_modified (Inkscape::Selection *selection, guint /*flags*/, GObject *tbl)
 
4130
{
 
4131
    sp_text_toolbox_selection_changed (selection, tbl);
 
4132
}
 
4133
 
 
4134
void
 
4135
sp_text_toolbox_subselection_changed (gpointer /*dragger*/, GObject *tbl)
 
4136
{
 
4137
    sp_text_toolbox_selection_changed (NULL, tbl);
3332
4138
}
3333
4139
 
3334
4140
void
3335
4141
sp_text_toolbox_family_changed (GtkTreeSelection    *selection,
3336
 
                                GObject             *tbl) 
 
4142
                                GObject             *tbl)
3337
4143
{
3338
4144
    SPDesktop    *desktop = SP_ACTIVE_DESKTOP;
3339
4145
    GtkTreeModel *model = 0;
3342
4148
    GtkTreeIter   iter;
3343
4149
    char         *family = 0;
3344
4150
 
 
4151
    (void)popdown;
 
4152
 
3345
4153
    gdk_pointer_ungrab (GDK_CURRENT_TIME);
3346
4154
    gdk_keyboard_ungrab (GDK_CURRENT_TIME);
3347
4155
 
3356
4164
        gtk_entry_set_text (GTK_ENTRY (entry), family);
3357
4165
        return;
3358
4166
    }
3359
 
        
3360
 
    gtk_widget_hide (popdown);
3361
 
    visible = false;
3362
4167
 
3363
4168
    gtk_entry_set_text (GTK_ENTRY (entry), family);
3364
4169
 
3365
4170
    SPStyle *query =
3366
 
        sp_style_new ();
3367
 
 
3368
 
    int result_numbers =
3369
 
        sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); 
3370
 
 
3371
 
    SPCSSAttr *css = sp_repr_css_attr_new (); 
3372
 
    sp_repr_css_set_property (css, "font-family", family); 
 
4171
        sp_style_new (SP_ACTIVE_DOCUMENT);
 
4172
 
 
4173
    int result_fontspec =
 
4174
        sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION);
 
4175
    
 
4176
    font_instance * fontFromStyle = font_factory::Default()->FaceFromStyle(query);
 
4177
    
 
4178
    SPCSSAttr *css = sp_repr_css_attr_new ();
 
4179
    
 
4180
    
 
4181
    // First try to get the font spec from the stored value
 
4182
    Glib::ustring fontSpec = query->text->font_specification.set ?  query->text->font_specification.value : "";
 
4183
    
 
4184
    if (fontSpec.empty()) {
 
4185
        // Construct a new font specification if it does not yet exist
 
4186
        font_instance * fontFromStyle = font_factory::Default()->FaceFromStyle(query);
 
4187
        fontSpec = font_factory::Default()->ConstructFontSpecification(fontFromStyle);
 
4188
        fontFromStyle->Unref();
 
4189
    }
 
4190
    
 
4191
    if (!fontSpec.empty()) {
 
4192
        Glib::ustring newFontSpec = font_factory::Default()->ReplaceFontSpecificationFamily(fontSpec, family);
 
4193
        if (!newFontSpec.empty() && fontSpec != newFontSpec) {
 
4194
            font_instance *font = font_factory::Default()->FaceFromFontSpecification(newFontSpec.c_str());
 
4195
            if (font) {
 
4196
                sp_repr_css_set_property (css, "-inkscape-font-specification", newFontSpec.c_str());
 
4197
                
 
4198
                // Set all the these just in case they were altered when finding the best
 
4199
                // match for the new family and old style...
 
4200
                
 
4201
                gchar c[256];
 
4202
                
 
4203
                font->Family(c, 256);
 
4204
                sp_repr_css_set_property (css, "font-family", c);
 
4205
                
 
4206
                font->Attribute( "weight", c, 256);
 
4207
                sp_repr_css_set_property (css, "font-weight", c);
 
4208
                
 
4209
                font->Attribute("style", c, 256);
 
4210
                sp_repr_css_set_property (css, "font-style", c);
 
4211
                
 
4212
                font->Attribute("stretch", c, 256);
 
4213
                sp_repr_css_set_property (css, "font-stretch", c);
 
4214
                
 
4215
                font->Attribute("variant", c, 256);
 
4216
                sp_repr_css_set_property (css, "font-variant", c);
 
4217
                
 
4218
                font->Unref();
 
4219
            }
 
4220
        }
 
4221
    }
3373
4222
 
3374
4223
    // If querying returned nothing, read the style from the text tool prefs (default style for new texts)
3375
 
    if (result_numbers == QUERY_STYLE_NOTHING)
 
4224
    if (result_fontspec == QUERY_STYLE_NOTHING)
3376
4225
    {
3377
4226
        sp_repr_css_change (inkscape_get_repr (INKSCAPE, "tools.text"), css, "style");
3378
4227
        sp_text_edit_dialog_default_set_insensitive (); //FIXME: Replace trough a verb
3382
4231
        sp_desktop_set_style (desktop, css, true, true);
3383
4232
    }
3384
4233
 
3385
 
    sp_document_done (sp_desktop_document (SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, 
 
4234
    sp_style_unref(query);
 
4235
 
 
4236
    sp_document_done (sp_desktop_document (SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT,
3386
4237
                                   _("Text: Change font family"));
3387
4238
    sp_repr_css_attr_unref (css);
3388
4239
    free (family);
3389
 
    gtk_widget_hide (GTK_WIDGET (g_object_get_data (G_OBJECT(tbl), "warning-image")));        
 
4240
    gtk_widget_hide (GTK_WIDGET (g_object_get_data (G_OBJECT(tbl), "warning-image")));
3390
4241
 
3391
4242
    gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
3392
4243
}
3393
4244
 
3394
4245
void
3395
4246
sp_text_toolbox_family_entry_activate (GtkEntry     *entry,
3396
 
                                       GObject      *tbl) 
 
4247
                                       GObject      *tbl)
3397
4248
{
3398
4249
    const char *family = gtk_entry_get_text (entry);
3399
4250
 
3400
 
    try {    
 
4251
    try {
3401
4252
        Gtk::TreePath path = Inkscape::FontLister::get_instance()->get_row_for_font (family);
3402
4253
        GtkTreeSelection *selection = GTK_TREE_SELECTION (g_object_get_data (G_OBJECT(tbl), "family-tree-selection"));
3403
4254
        GtkTreeView *treeview = GTK_TREE_VIEW (g_object_get_data (G_OBJECT(tbl), "family-tree-view"));
3404
4255
        gtk_tree_selection_select_path (selection, path.gobj());
3405
4256
        gtk_tree_view_scroll_to_cell (treeview, path.gobj(), NULL, TRUE, 0.5, 0.0);
3406
 
        gtk_widget_hide (GTK_WIDGET (g_object_get_data (G_OBJECT(tbl), "warning-image")));        
 
4257
        gtk_widget_hide (GTK_WIDGET (g_object_get_data (G_OBJECT(tbl), "warning-image")));
3407
4258
    } catch (...) {
3408
4259
        if (family && strlen (family))
3409
4260
        {
3418
4269
{
3419
4270
    if (g_object_get_data (G_OBJECT (button), "block")) return;
3420
4271
    if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) return;
3421
 
    int prop = GPOINTER_TO_INT(data); 
 
4272
    int prop = GPOINTER_TO_INT(data);
3422
4273
 
3423
4274
    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
3424
 
    SPCSSAttr *css = sp_repr_css_attr_new (); 
 
4275
    SPCSSAttr *css = sp_repr_css_attr_new ();
3425
4276
 
3426
4277
    switch (prop)
3427
4278
    {
3428
4279
        case 0:
3429
4280
        {
3430
 
            sp_repr_css_set_property (css, "text-anchor", "start"); 
3431
 
            sp_repr_css_set_property (css, "text-align", "start"); 
 
4281
            sp_repr_css_set_property (css, "text-anchor", "start");
 
4282
            sp_repr_css_set_property (css, "text-align", "start");
3432
4283
            break;
3433
4284
        }
3434
4285
        case 1:
3435
4286
        {
3436
 
            sp_repr_css_set_property (css, "text-anchor", "middle"); 
3437
 
            sp_repr_css_set_property (css, "text-align", "center"); 
 
4287
            sp_repr_css_set_property (css, "text-anchor", "middle");
 
4288
            sp_repr_css_set_property (css, "text-align", "center");
3438
4289
            break;
3439
4290
        }
3440
4291
 
3441
4292
        case 2:
3442
4293
        {
3443
 
            sp_repr_css_set_property (css, "text-anchor", "end"); 
3444
 
            sp_repr_css_set_property (css, "text-align", "end"); 
 
4294
            sp_repr_css_set_property (css, "text-anchor", "end");
 
4295
            sp_repr_css_set_property (css, "text-align", "end");
3445
4296
            break;
3446
4297
        }
3447
4298
 
3448
4299
        case 3:
3449
4300
        {
3450
 
            sp_repr_css_set_property (css, "text-anchor", "start"); 
3451
 
            sp_repr_css_set_property (css, "text-align", "justify"); 
 
4301
            sp_repr_css_set_property (css, "text-anchor", "start");
 
4302
            sp_repr_css_set_property (css, "text-align", "justify");
3452
4303
            break;
3453
4304
        }
3454
4305
    }
3455
4306
 
3456
4307
    SPStyle *query =
3457
 
        sp_style_new ();
 
4308
        sp_style_new (SP_ACTIVE_DOCUMENT);
3458
4309
    int result_numbers =
3459
 
        sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); 
 
4310
        sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS);
3460
4311
 
3461
4312
    // If querying returned nothing, read the style from the text tool prefs (default style for new texts)
3462
4313
    if (result_numbers == QUERY_STYLE_NOTHING)
3464
4315
        sp_repr_css_change (inkscape_get_repr (INKSCAPE, "tools.text"), css, "style");
3465
4316
    }
3466
4317
 
 
4318
    sp_style_unref(query);
 
4319
 
3467
4320
    sp_desktop_set_style (desktop, css, true, true);
3468
 
    sp_document_done (sp_desktop_document (SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, 
 
4321
    sp_document_done (sp_desktop_document (SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT,
3469
4322
                                   _("Text: Change alignment"));
3470
4323
    sp_repr_css_attr_unref (css);
3471
4324
 
3479
4332
    if (g_object_get_data (G_OBJECT (button), "block")) return;
3480
4333
 
3481
4334
    SPDesktop   *desktop    = SP_ACTIVE_DESKTOP;
3482
 
    SPCSSAttr   *css        = sp_repr_css_attr_new (); 
3483
 
    int          prop       = GPOINTER_TO_INT(data); 
 
4335
    SPCSSAttr   *css        = sp_repr_css_attr_new ();
 
4336
    int          prop       = GPOINTER_TO_INT(data);
3484
4337
    bool         active     = gtk_toggle_button_get_active (button);
3485
4338
 
3486
 
 
 
4339
    SPStyle *query =
 
4340
        sp_style_new (SP_ACTIVE_DOCUMENT);
 
4341
    
 
4342
    int result_fontspec =
 
4343
        sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION);
 
4344
 
 
4345
    int result_family =
 
4346
        sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY);
 
4347
 
 
4348
    int result_style =
 
4349
        sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE);
 
4350
 
 
4351
    int result_numbers =
 
4352
        sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS);
 
4353
    
 
4354
    Glib::ustring fontSpec = query->text->font_specification.set ?  query->text->font_specification.value : "";
 
4355
    Glib::ustring newFontSpec = "";
 
4356
    
 
4357
    if (fontSpec.empty()) {
 
4358
        // Construct a new font specification if it does not yet exist
 
4359
        font_instance * fontFromStyle = font_factory::Default()->FaceFromStyle(query);
 
4360
        fontSpec = font_factory::Default()->ConstructFontSpecification(fontFromStyle);
 
4361
        fontFromStyle->Unref();
 
4362
    }
 
4363
    
3487
4364
    switch (prop)
3488
4365
    {
3489
4366
        case 0:
3490
4367
        {
3491
 
            sp_repr_css_set_property (css, "font-weight", active ? "bold" : "normal" ); 
 
4368
            if (!fontSpec.empty()) {
 
4369
                newFontSpec = font_factory::Default()->FontSpecificationSetBold(fontSpec, active);
 
4370
            }
 
4371
            if (fontSpec != newFontSpec) {
 
4372
                // Don't even set the bold if the font didn't exist on the system
 
4373
                sp_repr_css_set_property (css, "font-weight", active ? "bold" : "normal" );
 
4374
            }
3492
4375
            break;
3493
4376
        }
3494
4377
 
3495
4378
        case 1:
3496
4379
        {
3497
 
            sp_repr_css_set_property (css, "font-style", active ? "italic" : "normal"); 
 
4380
            if (!fontSpec.empty()) {
 
4381
                newFontSpec = font_factory::Default()->FontSpecificationSetItalic(fontSpec, active);
 
4382
            }
 
4383
            if (fontSpec != newFontSpec) {
 
4384
                // Don't even set the italic if the font didn't exist on the system
 
4385
                sp_repr_css_set_property (css, "font-style", active ? "italic" : "normal");
 
4386
            }
3498
4387
            break;
3499
4388
        }
3500
4389
    }
3501
4390
 
3502
 
    SPStyle *query =
3503
 
        sp_style_new ();
3504
 
    int result_numbers =
3505
 
        sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); 
 
4391
    if (!newFontSpec.empty()) {
 
4392
        sp_repr_css_set_property (css, "-inkscape-font-specification", newFontSpec.c_str()); 
 
4393
    }
3506
4394
 
3507
4395
    // If querying returned nothing, read the style from the text tool prefs (default style for new texts)
3508
 
    if (result_numbers == QUERY_STYLE_NOTHING)
 
4396
    if (result_fontspec == QUERY_STYLE_NOTHING)
3509
4397
    {
3510
4398
        sp_repr_css_change (inkscape_get_repr (INKSCAPE, "tools.text"), css, "style");
3511
4399
    }
3512
4400
 
 
4401
    sp_style_unref(query);
 
4402
 
3513
4403
    sp_desktop_set_style (desktop, css, true, true);
3514
 
    sp_document_done (sp_desktop_document (SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, 
 
4404
    sp_document_done (sp_desktop_document (SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT,
3515
4405
                                   _("Text: Change font style"));
3516
4406
    sp_repr_css_attr_unref (css);
3517
4407
 
3526
4416
        g_object_set_data (G_OBJECT (button), "block", gpointer(0));
3527
4417
        return;
3528
4418
    }
3529
 
    
 
4419
 
3530
4420
    SPDesktop   *desktop    = SP_ACTIVE_DESKTOP;
3531
 
    SPCSSAttr   *css        = sp_repr_css_attr_new (); 
3532
 
    int          prop       = GPOINTER_TO_INT(data); 
 
4421
    SPCSSAttr   *css        = sp_repr_css_attr_new ();
 
4422
    int          prop       = GPOINTER_TO_INT(data);
3533
4423
 
3534
4424
    switch (prop)
3535
4425
    {
3541
4431
 
3542
4432
        case 1:
3543
4433
        {
3544
 
            sp_repr_css_set_property (css, "writing-mode", "tb"); 
 
4434
            sp_repr_css_set_property (css, "writing-mode", "tb");
3545
4435
            break;
3546
4436
        }
3547
4437
    }
3548
4438
 
3549
4439
    SPStyle *query =
3550
 
        sp_style_new ();
 
4440
        sp_style_new (SP_ACTIVE_DOCUMENT);
3551
4441
    int result_numbers =
3552
 
        sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); 
 
4442
        sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS);
3553
4443
 
3554
4444
    // If querying returned nothing, read the style from the text tool prefs (default style for new texts)
3555
4445
    if (result_numbers == QUERY_STYLE_NOTHING)
3558
4448
    }
3559
4449
 
3560
4450
    sp_desktop_set_style (desktop, css, true, true);
3561
 
    sp_document_done (sp_desktop_document (SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, 
 
4451
    sp_document_done (sp_desktop_document (SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT,
3562
4452
                                   _("Text: Change orientation"));
3563
4453
    sp_repr_css_attr_unref (css);
3564
4454
 
3566
4456
}
3567
4457
 
3568
4458
gboolean
3569
 
sp_text_toolbox_size_keypress (GtkWidget *w, GdkEventKey *event, gpointer data)
3570
 
{
3571
 
    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
3572
 
    if (!desktop) return FALSE;
3573
 
 
3574
 
    switch (get_group0_keyval (event)) {
3575
 
        case GDK_Escape: // defocus
3576
 
            gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
3577
 
            return TRUE; // I consumed the event
3578
 
            break;
3579
 
        case GDK_Return: // defocus
3580
 
        case GDK_KP_Enter:
3581
 
            gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
3582
 
            return TRUE; // I consumed the event
3583
 
            break;
3584
 
    }
3585
 
    return FALSE;
3586
 
}
3587
 
 
3588
 
gboolean
3589
 
sp_text_toolbox_family_keypress (GtkWidget *w, GdkEventKey *event, GObject *tbl)
 
4459
sp_text_toolbox_family_keypress (GtkWidget */*w*/, GdkEventKey *event, GObject *tbl)
3590
4460
{
3591
4461
    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
3592
4462
    if (!desktop) return FALSE;
3602
4472
}
3603
4473
 
3604
4474
gboolean
3605
 
sp_text_toolbox_family_list_keypress (GtkWidget *w, GdkEventKey *event, GObject *tbl)
 
4475
sp_text_toolbox_family_list_keypress (GtkWidget *w, GdkEventKey *event, GObject */*tbl*/)
3606
4476
{
3607
4477
    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
3608
4478
    if (!desktop) return FALSE;
3609
4479
 
3610
4480
    switch (get_group0_keyval (event)) {
 
4481
        case GDK_KP_Enter:
 
4482
        case GDK_Return:
3611
4483
        case GDK_Escape: // defocus
3612
4484
            gtk_widget_hide (w);
3613
4485
            visible = false;
3621
4493
 
3622
4494
void
3623
4495
sp_text_toolbox_size_changed  (GtkComboBox *cbox,
3624
 
                               GObject     *tbl) 
 
4496
                               GObject     *tbl)
3625
4497
{
3626
4498
    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
3627
4499
 
3628
4500
    if (g_object_get_data (tbl, "size-block")) return;
3629
4501
 
3630
 
#if GTK_CHECK_VERSION(2,6,0)
 
4502
    // If this is not from selecting a size in the list (in which case get_active will give the
 
4503
    // index of the selected item, otherwise -1) and not from user pressing Enter/Return, do not
 
4504
    // process this event. This fixes GTK's stupid insistence on sending an activate change every
 
4505
    // time any character gets typed or deleted, which made this control nearly unusable in 0.45.
 
4506
    if (gtk_combo_box_get_active (cbox) < 0 && !g_object_get_data (tbl, "enter-pressed"))
 
4507
        return;
 
4508
 
 
4509
    gchar *endptr;
 
4510
    gdouble value = -1;
3631
4511
    char *text = gtk_combo_box_get_active_text (cbox);
3632
 
#else // GTK_CHECK_VERSION(2,6,0)
3633
 
    GtkTreeModel *model = gtk_combo_box_get_model (cbox);
3634
 
    GtkTreeIter iter;
3635
 
    char *text = NULL;
3636
 
 
3637
 
    if (gtk_combo_box_get_active_iter (cbox, &iter) && model)
3638
 
        gtk_tree_model_get (model, &iter, 0, &text, -1);
3639
 
#endif // GTK_CHECK_VERSION(2,6,0)
3640
 
 
3641
 
    SPCSSAttr *css = sp_repr_css_attr_new (); 
3642
 
    sp_repr_css_set_property (css, "font-size", text); 
3643
 
    free (text);
 
4512
    if (text) {
 
4513
        value = g_strtod (text, &endptr);
 
4514
        if (endptr == text) // conversion failed, non-numeric input
 
4515
            value = -1;
 
4516
        free (text);
 
4517
    }
 
4518
    if (value <= 0) {
 
4519
        return; // could not parse value 
 
4520
    }
 
4521
 
 
4522
    SPCSSAttr *css = sp_repr_css_attr_new ();
 
4523
    Inkscape::CSSOStringStream osfs;
 
4524
    osfs << value;
 
4525
    sp_repr_css_set_property (css, "font-size", osfs.str().c_str());
3644
4526
 
3645
4527
    SPStyle *query =
3646
 
        sp_style_new ();
 
4528
        sp_style_new (SP_ACTIVE_DOCUMENT);
3647
4529
    int result_numbers =
3648
 
        sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); 
 
4530
        sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS);
3649
4531
 
3650
4532
    // If querying returned nothing, read the style from the text tool prefs (default style for new texts)
3651
4533
    if (result_numbers == QUERY_STYLE_NOTHING)
3653
4535
        sp_repr_css_change (inkscape_get_repr (INKSCAPE, "tools.text"), css, "style");
3654
4536
    }
3655
4537
 
 
4538
    sp_style_unref(query);
 
4539
 
3656
4540
    sp_desktop_set_style (desktop, css, true, true);
3657
 
    sp_document_maybe_done (sp_desktop_document (SP_ACTIVE_DESKTOP), "ttb:size", SP_VERB_NONE, 
 
4541
    sp_document_maybe_done (sp_desktop_document (SP_ACTIVE_DESKTOP), "ttb:size", SP_VERB_NONE,
3658
4542
                                   _("Text: Change font size"));
3659
4543
    sp_repr_css_attr_unref (css);
3660
4544
 
3661
 
 
3662
 
    if (gtk_combo_box_get_active (cbox) > 0) // if this was from drop-down (as opposed to type-in), defocus
3663
 
        gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
 
4545
    gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
 
4546
}
 
4547
 
 
4548
gboolean
 
4549
sp_text_toolbox_size_focusout (GtkWidget */*w*/, GdkEventFocus *event, GObject *tbl)
 
4550
{
 
4551
    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
 
4552
    if (!desktop) return FALSE;
 
4553
 
 
4554
    if (!g_object_get_data (tbl, "esc-pressed")) {
 
4555
        g_object_set_data (tbl, "enter-pressed", gpointer(1));
 
4556
        GtkComboBox *cbox = GTK_COMBO_BOX(g_object_get_data (G_OBJECT (tbl), "combo-box-size"));
 
4557
        sp_text_toolbox_size_changed (cbox, tbl);
 
4558
        g_object_set_data (tbl, "enter-pressed", gpointer(0));
 
4559
    }
 
4560
    return FALSE; // I consumed the event
 
4561
}
 
4562
 
 
4563
 
 
4564
gboolean
 
4565
sp_text_toolbox_size_keypress (GtkWidget */*w*/, GdkEventKey *event, GObject *tbl)
 
4566
{
 
4567
    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
 
4568
    if (!desktop) return FALSE;
 
4569
 
 
4570
    switch (get_group0_keyval (event)) {
 
4571
        case GDK_Escape: // defocus
 
4572
            g_object_set_data (tbl, "esc-pressed", gpointer(1));
 
4573
            gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
 
4574
            g_object_set_data (tbl, "esc-pressed", gpointer(0));
 
4575
            return TRUE; // I consumed the event
 
4576
            break;
 
4577
        case GDK_Return: // defocus
 
4578
        case GDK_KP_Enter:
 
4579
            g_object_set_data (tbl, "enter-pressed", gpointer(1));
 
4580
            GtkComboBox *cbox = GTK_COMBO_BOX(g_object_get_data (G_OBJECT (tbl), "combo-box-size"));
 
4581
            sp_text_toolbox_size_changed (cbox, tbl);
 
4582
            gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
 
4583
            g_object_set_data (tbl, "enter-pressed", gpointer(0));
 
4584
            return TRUE; // I consumed the event
 
4585
            break;
 
4586
    }
 
4587
    return FALSE;
3664
4588
}
3665
4589
 
3666
4590
void
3667
 
sp_text_toolbox_text_popdown_clicked    (GtkButton          *button,
 
4591
sp_text_toolbox_text_popdown_clicked    (GtkButton          */*button*/,
3668
4592
                                         GObject            *tbl)
3669
4593
{
3670
4594
    GtkWidget *popdown = GTK_WIDGET (g_object_get_data (tbl, "family-popdown-window"));
3674
4598
    if (!visible)
3675
4599
    {
3676
4600
        gdk_window_get_origin (widget->window, &x, &y);
3677
 
        gtk_window_move (GTK_WINDOW (popdown), x, y + widget->allocation.height + 2); //2px of grace space 
 
4601
        gtk_window_move (GTK_WINDOW (popdown), x, y + widget->allocation.height + 2); //2px of grace space
3678
4602
        gtk_widget_show_all (popdown);
3679
4603
 
3680
4604
        gdk_pointer_grab (widget->window, TRUE,
3698
4622
 
3699
4623
gboolean
3700
4624
sp_text_toolbox_entry_focus_in  (GtkWidget        *entry,
3701
 
                                 GdkEventFocus    *event,
3702
 
                                 GObject          *tbl)
 
4625
                                 GdkEventFocus    */*event*/,
 
4626
                                 GObject          */*tbl*/)
3703
4627
{
3704
4628
    gtk_entry_select_region (GTK_ENTRY (entry), 0, -1);
3705
4629
    return FALSE;
3707
4631
 
3708
4632
gboolean
3709
4633
sp_text_toolbox_popdown_focus_out (GtkWidget        *popdown,
3710
 
                                   GdkEventFocus    *event,
3711
 
                                   GObject          *tbl)
 
4634
                                   GdkEventFocus    */*event*/,
 
4635
                                   GObject          */*tbl*/)
3712
4636
{
3713
4637
    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
3714
4638
 
3719
4643
}
3720
4644
 
3721
4645
void
3722
 
cell_data_func  (GtkTreeViewColumn *column,
 
4646
cell_data_func  (GtkTreeViewColumn */*column*/,
3723
4647
                 GtkCellRenderer   *cell,
3724
4648
                 GtkTreeModel      *tree_model,
3725
4649
                 GtkTreeIter       *iter,
3726
 
                 gpointer           data)
 
4650
                 gpointer           /*data*/)
3727
4651
{
3728
4652
    char        *family,
3729
4653
        *family_escaped,
3735
4659
 
3736
4660
    family_escaped = g_markup_escape_text (family, -1);
3737
4661
    sample_escaped = g_markup_escape_text (sample, -1);
3738
 
    
3739
 
    std::stringstream markup; 
 
4662
 
 
4663
    std::stringstream markup;
3740
4664
    markup << family_escaped << "  <span foreground='darkgray' font_family='" << family_escaped << "'>" << sample_escaped << "</span>";
3741
4665
    g_object_set (G_OBJECT (cell), "markup", markup.str().c_str(), NULL);
3742
4666
 
3745
4669
    free (sample_escaped);
3746
4670
}
3747
4671
 
3748
 
static void delete_completion(GObject *obj, GtkWidget *entry) {
 
4672
static void delete_completion(GObject */*obj*/, GtkWidget *entry) {
3749
4673
    GObject *completion = (GObject *) gtk_object_get_data(GTK_OBJECT(entry), "completion");
3750
4674
    if (completion) {
3751
4675
        gtk_entry_set_completion (GTK_ENTRY(entry), NULL);
3775
4699
    GtkEntryCompletion  *completion = gtk_entry_completion_new ();
3776
4700
    gtk_entry_completion_set_model (completion, GTK_TREE_MODEL (Glib::unwrap(store)));
3777
4701
    gtk_entry_completion_set_text_column (completion, 0);
3778
 
    gtk_entry_completion_set_minimum_key_length (completion, 1); 
 
4702
    gtk_entry_completion_set_minimum_key_length (completion, 1);
3779
4703
    g_object_set (G_OBJECT(completion), "inline-completion", TRUE, "popup-completion", TRUE, NULL);
3780
4704
    gtk_entry_set_completion (GTK_ENTRY(entry), completion);
3781
4705
    gtk_object_set_data(GTK_OBJECT(entry), "completion", completion);
3782
4706
    aux_toolbox_space (tbl, 1);
3783
4707
    gtk_box_pack_start (GTK_BOX (tbl), entry, FALSE, FALSE, 0);
3784
4708
    g_signal_connect(G_OBJECT(tbl), "destroy", G_CALLBACK(delete_completion), entry);
3785
 
        
 
4709
 
3786
4710
    //Button
3787
4711
    GtkWidget   *button = gtk_button_new ();
3788
4712
    gtk_container_add       (GTK_CONTAINER (button), gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE));
3801
4725
 
3802
4726
    gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (Glib::unwrap(store)));
3803
4727
    gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
3804
 
#if GTK_CHECK_VERSION(2,6,0)
3805
4728
    gtk_tree_view_set_fixed_height_mode (GTK_TREE_VIEW (treeview), TRUE);
3806
 
#endif // GTK_CHECK_VERSION(2,6,0)
3807
4729
 
3808
4730
    //gtk_tree_view_set_enable_search (GTK_TREE_VIEW (treeview), TRUE);
3809
4731
 
3810
 
    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); 
 
4732
    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
3811
4733
    gtk_container_add (GTK_CONTAINER (sw), treeview);
3812
4734
 
3813
4735
    gtk_container_add (GTK_CONTAINER (window), sw);
3856
4778
    gtk_box_pack_start (GTK_BOX (tbl), cbox, FALSE, FALSE, 0);
3857
4779
    g_object_set_data (G_OBJECT (tbl), "combo-box-size", cbox);
3858
4780
    g_signal_connect (G_OBJECT (cbox), "changed", G_CALLBACK (sp_text_toolbox_size_changed), tbl);
3859
 
    gtk_signal_connect(GTK_OBJECT(cbox), "key-press-event", GTK_SIGNAL_FUNC(sp_text_toolbox_size_keypress), NULL);
 
4781
    gtk_signal_connect(GTK_OBJECT(gtk_bin_get_child(GTK_BIN(cbox))), "key-press-event", GTK_SIGNAL_FUNC(sp_text_toolbox_size_keypress), tbl);
 
4782
    gtk_signal_connect(GTK_OBJECT(gtk_bin_get_child(GTK_BIN(cbox))), "focus-out-event", GTK_SIGNAL_FUNC(sp_text_toolbox_size_focusout), tbl);
3860
4783
 
3861
4784
    //spacer
3862
4785
    aux_toolbox_space (tbl, 4);
3886
4809
 
3887
4810
    gtk_box_pack_start  (GTK_BOX  (row), rbutton, FALSE, FALSE, 0);
3888
4811
    g_object_set_data   (G_OBJECT (tbl), "text-middle", rbutton);
3889
 
    g_signal_connect    (G_OBJECT (rbutton), "toggled", G_CALLBACK (sp_text_toolbox_anchoring_toggled), gpointer (1)); 
 
4812
    g_signal_connect    (G_OBJECT (rbutton), "toggled", G_CALLBACK (sp_text_toolbox_anchoring_toggled), gpointer (1));
3890
4813
    gtk_tooltips_set_tip(tt, rbutton, _("Center"), NULL);
3891
4814
 
3892
4815
    // right
3920
4843
    ////////////Text style
3921
4844
    row = gtk_hbox_new (FALSE, 4);
3922
4845
 
3923
 
    // bold 
3924
 
    rbutton = gtk_toggle_button_new (); 
 
4846
    // bold
 
4847
    rbutton = gtk_toggle_button_new ();
3925
4848
    gtk_button_set_relief       (GTK_BUTTON (rbutton), GTK_RELIEF_NONE);
3926
4849
    gtk_container_add           (GTK_CONTAINER (rbutton), gtk_image_new_from_stock (GTK_STOCK_BOLD, GTK_ICON_SIZE_SMALL_TOOLBAR));
3927
4850
    gtk_toggle_button_set_mode  (GTK_TOGGLE_BUTTON (rbutton), FALSE);
3932
4855
    g_signal_connect    (G_OBJECT (rbutton), "toggled", G_CALLBACK (sp_text_toolbox_style_toggled), gpointer(0));
3933
4856
 
3934
4857
    // italic
3935
 
    rbutton = gtk_toggle_button_new (); 
 
4858
    rbutton = gtk_toggle_button_new ();
3936
4859
    gtk_button_set_relief       (GTK_BUTTON (rbutton), GTK_RELIEF_NONE);
3937
4860
    gtk_container_add           (GTK_CONTAINER (rbutton), gtk_image_new_from_stock (GTK_STOCK_ITALIC, GTK_ICON_SIZE_SMALL_TOOLBAR));
3938
4861
    gtk_toggle_button_set_mode  (GTK_TOGGLE_BUTTON (rbutton), FALSE);
3940
4863
 
3941
4864
    gtk_box_pack_start  (GTK_BOX  (row), rbutton, FALSE, FALSE, 0);
3942
4865
    g_object_set_data   (G_OBJECT (tbl), "style-italic", rbutton);
3943
 
    g_signal_connect    (G_OBJECT (rbutton), "toggled", G_CALLBACK (sp_text_toolbox_style_toggled), gpointer (1)); 
 
4866
    g_signal_connect    (G_OBJECT (rbutton), "toggled", G_CALLBACK (sp_text_toolbox_style_toggled), gpointer (1));
3944
4867
 
3945
4868
    aux_toolbox_space (tbl, 1);
3946
4869
    gtk_box_pack_start (GTK_BOX (tbl), row, FALSE, FALSE, 4);
3956
4879
    // horizontal
3957
4880
    rbutton = group;
3958
4881
    gtk_button_set_relief       (GTK_BUTTON (rbutton), GTK_RELIEF_NONE);
3959
 
    gtk_container_add           (GTK_CONTAINER (rbutton), sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_STOCK_WRITING_MODE_LR)); 
 
4882
    gtk_container_add           (GTK_CONTAINER (rbutton), sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_STOCK_WRITING_MODE_LR));
3960
4883
    gtk_toggle_button_set_mode  (GTK_TOGGLE_BUTTON (rbutton), FALSE);
3961
4884
    gtk_tooltips_set_tip(tt, rbutton, _("Horizontal text"), NULL);
3962
4885
 
3967
4890
    // vertical
3968
4891
    rbutton = gtk_radio_button_new (gtk_radio_button_group (GTK_RADIO_BUTTON (group)));
3969
4892
    gtk_button_set_relief       (GTK_BUTTON (rbutton), GTK_RELIEF_NONE);
3970
 
    gtk_container_add           (GTK_CONTAINER (rbutton), sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_STOCK_WRITING_MODE_TB)); 
 
4893
    gtk_container_add           (GTK_CONTAINER (rbutton), sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_STOCK_WRITING_MODE_TB));
3971
4894
    gtk_toggle_button_set_mode  (GTK_TOGGLE_BUTTON (rbutton), FALSE);
3972
4895
    gtk_tooltips_set_tip(tt, rbutton, _("Vertical text"), NULL);
3973
4896
 
3974
4897
    gtk_box_pack_start  (GTK_BOX  (row), rbutton, FALSE, FALSE, 0);
3975
4898
    g_object_set_data   (G_OBJECT (tbl), "orientation-vertical", rbutton);
3976
 
    g_signal_connect    (G_OBJECT (rbutton), "toggled", G_CALLBACK (sp_text_toolbox_orientation_toggled), gpointer (1)); 
 
4899
    g_signal_connect    (G_OBJECT (rbutton), "toggled", G_CALLBACK (sp_text_toolbox_orientation_toggled), gpointer (1));
3977
4900
    gtk_box_pack_start (GTK_BOX (tbl), row, FALSE, FALSE, 4);
3978
4901
 
3979
4902
 
3981
4904
    Inkscape::ConnectionPool* pool = Inkscape::ConnectionPool::new_connection_pool ("ISTextToolbox");
3982
4905
 
3983
4906
    sigc::connection *c_selection_changed =
3984
 
        new sigc::connection (sp_desktop_selection (desktop)->connectChanged 
 
4907
        new sigc::connection (sp_desktop_selection (desktop)->connectChanged
3985
4908
                              (sigc::bind (sigc::ptr_fun (sp_text_toolbox_selection_changed), (GObject*)tbl)));
3986
4909
    pool->add_connection ("selection-changed", c_selection_changed);
3987
4910
 
3988
4911
    sigc::connection *c_selection_modified =
3989
 
        new sigc::connection (sp_desktop_selection (desktop)->connectModified 
 
4912
        new sigc::connection (sp_desktop_selection (desktop)->connectModified
3990
4913
                              (sigc::bind (sigc::ptr_fun (sp_text_toolbox_selection_modified), (GObject*)tbl)));
3991
4914
    pool->add_connection ("selection-modified", c_selection_modified);
3992
4915
 
3998
4921
    Inkscape::ConnectionPool::connect_destroy (G_OBJECT (tbl), pool);
3999
4922
 
4000
4923
 
4001
 
#if 0
4002
 
    // horizontal
4003
 
    {
4004
 
        GtkWidget *px= sp_icon_new(Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_STOCK_WRITING_MODE_LR);
4005
 
        GtkWidget *b = group = gtk_radio_button_new (NULL);
4006
 
        gtk_container_add (GTK_CONTAINER (b), px);
4007
 
        gtk_tooltips_set_tip (tt, b, _("Horizontal text"), NULL);
4008
 
        gtk_button_set_relief (GTK_BUTTON (b), GTK_RELIEF_NONE);
4009
 
        gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (b), FALSE );
4010
 
        gtk_box_pack_start (GTK_BOX (tbl), b, FALSE, FALSE, 0);
4011
 
    }
4012
 
 
4013
 
    // vertical
4014
 
    {
4015
 
        GtkWidget *px = sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_STOCK_WRITING_MODE_TB);
4016
 
        GtkWidget *b = gtk_radio_button_new (gtk_radio_button_group (GTK_RADIO_BUTTON (group)));
4017
 
        gtk_container_add (GTK_CONTAINER (b), px);
4018
 
        gtk_tooltips_set_tip (tt, b, _("Vertical text"), NULL);
4019
 
        gtk_button_set_relief (GTK_BUTTON (b), GTK_RELIEF_NONE);
4020
 
        gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (b), FALSE );
4021
 
        gtk_box_pack_start (GTK_BOX (tbl), b, FALSE, FALSE, 0);
4022
 
    }
4023
 
 
4024
 
    aux_toolbox_space(tbl, AUX_BETWEEN_BUTTON_GROUPS);
4025
 
 
4026
 
    // letter spacing
4027
 
    {
4028
 
        {
4029
 
            GtkWidget *image = sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_STOCK_TEXT_LETTER_SPACING);
4030
 
            GtkWidget *hb = gtk_hbox_new(FALSE, 1);
4031
 
            gtk_container_add (GTK_CONTAINER (hb), image);
4032
 
            gtk_widget_show(image);
4033
 
            gtk_box_pack_start (GTK_BOX (tbl), hb, FALSE, FALSE, 0);
4034
 
        }
4035
 
    
4036
 
        {
4037
 
            GtkWidget *hb = sp_tb_spinbutton(_(""), _("Spacing between letters"),
4038
 
                                             "tools.text", "letter_spacing", 0.0,
4039
 
                                             us, tbl, FALSE, NULL,
4040
 
                                             -1000.0, 1000.0, 0.1, 0.1,
4041
 
                                             sp_text_letter_changed, 0.1, 1);
4042
 
            gtk_widget_set_size_request (hb, 45, 6);
4043
 
            gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, 6);
4044
 
        }
4045
 
    }
4046
 
 
4047
 
    // line spacing
4048
 
    {
4049
 
        {
4050
 
            GtkWidget *image = sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_STOCK_TEXT_LINE_SPACING);
4051
 
            GtkWidget *hb = gtk_hbox_new(FALSE, 1);
4052
 
            gtk_container_add (GTK_CONTAINER (hb), image);
4053
 
            gtk_widget_show(image);
4054
 
            gtk_box_pack_start (GTK_BOX (tbl), hb, FALSE, FALSE, 0);
4055
 
        }
4056
 
    
4057
 
        {
4058
 
            GtkWidget *hb = sp_tb_spinbutton(_(""), _("Spacing between lines"),
4059
 
                                             "tools.text", "line_spacing", 0,
4060
 
                                             us, tbl, FALSE, NULL,
4061
 
                                             -1000.0, 1000.0, 0.1, 0.1,
4062
 
                                             sp_text_line_changed, 0.1, 1);
4063
 
            gtk_widget_set_size_request (hb, 45, 0);
4064
 
            gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, 3);
4065
 
        }
4066
 
    }
4067
 
 
4068
 
    {
4069
 
        // horizontal kerning/vertical kerning units menu: create
4070
 
        GtkWidget *us = sp_unit_selector_new(SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE);
4071
 
        sp_unit_selector_setsize(us, AUX_OPTION_MENU_WIDTH, AUX_OPTION_MENU_HEIGHT);
4072
 
        sp_unit_selector_set_unit(SP_UNIT_SELECTOR(us), desktop->namedview->doc_units);
4073
 
 
4074
 
        aux_toolbox_space(tbl, AUX_BETWEEN_BUTTON_GROUPS);
4075
 
 
4076
 
        // horizontal kerning
4077
 
        {
4078
 
            {
4079
 
                GtkWidget *image = sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_STOCK_TEXT_HORZ_KERN);
4080
 
                GtkWidget *hb = gtk_hbox_new(FALSE, 1);
4081
 
                gtk_container_add (GTK_CONTAINER (hb), image);
4082
 
                gtk_widget_show(image);
4083
 
                gtk_box_pack_start (GTK_BOX (tbl), hb, FALSE, FALSE, 0);
4084
 
            }
4085
 
 
4086
 
            {
4087
 
                GtkWidget *hb = sp_tb_spinbutton(_(""), _("Horizontal kerning"),
4088
 
                                                 "tools.text", "horizontal_kerning", 0,
4089
 
                                                 us, tbl, FALSE, NULL,
4090
 
                                                 -100.00, 100.00, 0.01, 0.1,
4091
 
                                                 sp_text_horiz_kern_changed);
4092
 
                gtk_widget_set_size_request (hb, 45, 0);
4093
 
                gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, 6);
4094
 
            }
4095
 
        }
4096
 
 
4097
 
        // vertical kerning
4098
 
        {
4099
 
            {
4100
 
                GtkWidget *image = sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_STOCK_TEXT_VERT_KERN);
4101
 
                GtkWidget *hb = gtk_hbox_new(FALSE, 1);
4102
 
                gtk_container_add (GTK_CONTAINER (hb), image);
4103
 
                gtk_widget_show(image);
4104
 
                gtk_box_pack_start (GTK_BOX (tbl), hb, FALSE, FALSE, 0);
4105
 
            }
4106
 
    
4107
 
            {
4108
 
                GtkWidget *hb = sp_tb_spinbutton(_(""), _("Vertical kerning"),
4109
 
                                                 "tools.text", "vertical_kerning", 0,
4110
 
                                                 us, tbl, FALSE, NULL,
4111
 
                                                 -100.00, 100.00, 0.01, 0.1,
4112
 
                                                 sp_text_vert_kern_changed);
4113
 
                gtk_widget_set_size_request (hb, 45, 0);
4114
 
                gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, 5);
4115
 
            }
4116
 
        }
4117
 
 
4118
 
        // add the units menu
4119
 
        gtk_widget_show(us);
4120
 
        gtk_box_pack_start(GTK_BOX(tbl), us, FALSE, FALSE, 1);
4121
 
        gtk_object_set_data(GTK_OBJECT(tbl), "units", us);
4122
 
    }
4123
 
 
4124
 
    // letter rotation
4125
 
    aux_toolbox_space(tbl, AUX_BETWEEN_BUTTON_GROUPS);
4126
 
    {
4127
 
        {
4128
 
            GtkWidget *image = sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_STOCK_TEXT_ROTATION);
4129
 
            GtkWidget *hb = gtk_hbox_new(FALSE, 1);
4130
 
            gtk_container_add (GTK_CONTAINER (hb), image);
4131
 
            gtk_widget_show(image);
4132
 
            gtk_box_pack_start (GTK_BOX (tbl), hb, FALSE, FALSE, 0);
4133
 
        }
4134
 
        {
4135
 
            GtkWidget *hb = sp_tb_spinbutton(_(""), _("Letter rotation"),
4136
 
                                             "tools.text", "letter_rotation", 0,
4137
 
                                             us, tbl, FALSE, NULL,
4138
 
                                             -180.0, 180.0, 0.1, 0.1,
4139
 
                                             sp_text_letter_rotation_changed, 0.1, 1);
4140
 
            gtk_widget_set_size_request (hb, 45, 0);
4141
 
            gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, 6);
4142
 
        }
4143
 
        // rotation degree label
4144
 
        {
4145
 
            GtkWidget *label = gtk_widget_new (GTK_TYPE_LABEL, "label", "\302\260", "xalign", 0.0, NULL);
4146
 
            gtk_box_pack_start(GTK_BOX(tbl), label, FALSE, FALSE, 0);
4147
 
        }
4148
 
    }
4149
 
        
4150
 
    // Remove Manual Kerns
4151
 
    {
4152
 
        GtkWidget *px = sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_STOCK_TEXT_REMOVE_KERNS);
4153
 
        GtkWidget *button = gtk_button_new ();
4154
 
        gtk_container_add (GTK_CONTAINER (button), px);
4155
 
        gtk_widget_show(button);
4156
 
        gtk_tooltips_set_tip (tt, button, _("Remove manual kerns"), NULL);
4157
 
        gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
4158
 
        gtk_widget_set_sensitive(button, TRUE);
4159
 
        gtk_box_pack_start (GTK_BOX (tbl), button, FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
4160
 
    }
4161
 
#endif
4162
 
 
4163
4924
    gtk_widget_show_all (tbl);
4164
4925
    return tbl;
4165
4926
 
4169
4930
 
4170
4931
 
4171
4932
//#########################
4172
 
//##  Connector Toolbox  ##
 
4933
//##      Connector      ##
4173
4934
//#########################
4174
4935
 
4175
4936
static void sp_connector_path_set_avoid(void)
4185
4946
 
4186
4947
 
4187
4948
 
4188
 
static void connector_spacing_changed(GtkAdjustment *adj, GtkWidget *tbl)
 
4949
static void connector_spacing_changed(GtkAdjustment *adj, GObject* tbl)
4189
4950
{
4190
4951
    // quit if run by the _changed callbacks
4191
 
    if (g_object_get_data(G_OBJECT(tbl), "freeze")) {
 
4952
    if (g_object_get_data( tbl, "freeze" )) {
4192
4953
        return;
4193
4954
    }
4194
 
        
4195
 
    SPDesktop *desktop = (SPDesktop *) gtk_object_get_data(GTK_OBJECT(tbl),
4196
 
            "desktop");
 
4955
 
 
4956
    SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" );
4197
4957
    SPDocument *doc = sp_desktop_document(desktop);
4198
4958
 
4199
4959
    if (!sp_document_get_undo_sensitive(doc))
4201
4961
        return;
4202
4962
    }
4203
4963
 
 
4964
    Inkscape::XML::Node *repr = SP_OBJECT_REPR(desktop->namedview);
 
4965
 
 
4966
    if ( repr->attribute("inkscape:connector-spacing") ) {
 
4967
        gdouble priorValue = gtk_adjustment_get_value(adj);
 
4968
        sp_repr_get_double( repr, "inkscape:connector-spacing", &priorValue );
 
4969
        if ( priorValue == gtk_adjustment_get_value(adj) ) {
 
4970
            return;
 
4971
        }
 
4972
    } else if ( adj->value == defaultConnSpacing ) {
 
4973
        return;
 
4974
    }
 
4975
 
4204
4976
    // in turn, prevent callbacks from responding
4205
 
    g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE));
4206
 
    
4207
 
    Inkscape::XML::Node *repr = SP_OBJECT_REPR(desktop->namedview);
4208
 
    
 
4977
    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) );
 
4978
 
4209
4979
    sp_repr_set_css_double(repr, "inkscape:connector-spacing", adj->value);
4210
4980
    SP_OBJECT(desktop->namedview)->updateRepr();
4211
 
    
 
4981
 
4212
4982
    GSList *items = get_avoided_items(NULL, desktop->currentRoot(), desktop);
4213
4983
    for ( GSList const *iter = items ; iter != NULL ; iter = iter->next ) {
4214
4984
        SPItem *item = reinterpret_cast<SPItem *>(iter->data);
4219
4989
    if (items) {
4220
4990
        g_slist_free(items);
4221
4991
    }
4222
 
    
4223
 
    sp_document_done(doc, SP_VERB_CONTEXT_CONNECTOR, 
 
4992
 
 
4993
    sp_document_done(doc, SP_VERB_CONTEXT_CONNECTOR,
4224
4994
            _("Change connector spacing"));
4225
4995
 
4226
 
    g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(FALSE));
4227
 
    
 
4996
    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
 
4997
 
4228
4998
    spinbutton_defocus(GTK_OBJECT(tbl));
4229
4999
}
4230
5000
 
4243
5013
    sp_document_done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Arrange connector network"));
4244
5014
}
4245
5015
 
4246
 
static void
4247
 
sp_directed_graph_layout_toggled(GtkWidget *widget, GtkObject *tbl)
4248
 
{
4249
 
    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
4250
 
        prefs_set_string_attribute("tools.connector", "directedlayout", 
4251
 
                "true");
4252
 
    } else {
4253
 
        prefs_set_string_attribute("tools.connector", "directedlayout", 
4254
 
                "false");
4255
 
    }
4256
 
}
4257
 
static void
4258
 
sp_nooverlaps_graph_layout_toggled(GtkWidget *widget, GtkObject *tbl)
4259
 
{
4260
 
    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
4261
 
        prefs_set_string_attribute("tools.connector", "avoidoverlaplayout", 
4262
 
                "true");
4263
 
    } else {
4264
 
        prefs_set_string_attribute("tools.connector", "avoidoverlaplayout", 
4265
 
                "false");
4266
 
    }
4267
 
}
4268
 
 
4269
 
 
4270
 
static void connector_length_changed(GtkAdjustment *adj, GtkWidget *tbl)
 
5016
static void sp_directed_graph_layout_toggled( GtkToggleAction* act, GtkObject */*tbl*/ )
 
5017
{
 
5018
    if ( gtk_toggle_action_get_active( act ) ) {
 
5019
        prefs_set_string_attribute("tools.connector", "directedlayout",
 
5020
                "true");
 
5021
    } else {
 
5022
        prefs_set_string_attribute("tools.connector", "directedlayout",
 
5023
                "false");
 
5024
    }
 
5025
}
 
5026
 
 
5027
static void sp_nooverlaps_graph_layout_toggled( GtkToggleAction* act, GtkObject */*tbl*/ )
 
5028
{
 
5029
    if ( gtk_toggle_action_get_active( act ) ) {
 
5030
        prefs_set_string_attribute("tools.connector", "avoidoverlaplayout",
 
5031
                "true");
 
5032
    } else {
 
5033
        prefs_set_string_attribute("tools.connector", "avoidoverlaplayout",
 
5034
                "false");
 
5035
    }
 
5036
}
 
5037
 
 
5038
 
 
5039
static void connector_length_changed(GtkAdjustment *adj, GObject* tbl)
4271
5040
{
4272
5041
    prefs_set_double_attribute("tools.connector", "length", adj->value);
4273
5042
    spinbutton_defocus(GTK_OBJECT(tbl));
4274
5043
}
4275
5044
 
4276
5045
static void connector_tb_event_attr_changed(Inkscape::XML::Node *repr,
4277
 
        gchar const *name, gchar const *old_value, gchar const *new_value,
4278
 
        bool is_interactive, gpointer data)
 
5046
                                            gchar const *name, gchar const */*old_value*/, gchar const */*new_value*/,
 
5047
                                            bool /*is_interactive*/, gpointer data)
4279
5048
{
4280
5049
    GtkWidget *tbl = GTK_WIDGET(data);
4281
5050
 
4290
5059
            gtk_object_get_data(GTK_OBJECT(tbl), "spacing");
4291
5060
    gdouble spacing = defaultConnSpacing;
4292
5061
    sp_repr_get_double(repr, "inkscape:connector-spacing", &spacing);
4293
 
    
 
5062
 
4294
5063
    gtk_adjustment_set_value(adj, spacing);
4295
5064
}
4296
5065
 
4304
5073
};
4305
5074
 
4306
5075
 
4307
 
static GtkWidget *
4308
 
sp_connector_toolbox_new(SPDesktop *desktop)
 
5076
static void sp_connector_toolbox_prep( SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder )
4309
5077
{
4310
 
    GtkTooltips *tt = gtk_tooltips_new();
4311
 
    GtkWidget *tbl = gtk_hbox_new(FALSE, 0);
4312
 
    
4313
 
    gtk_object_set_data(GTK_OBJECT(tbl), "dtw", desktop->canvas);
4314
 
    gtk_object_set_data(GTK_OBJECT(tbl), "desktop", desktop);
4315
 
 
4316
 
    gtk_box_pack_start(GTK_BOX(tbl), gtk_hbox_new(FALSE, 0), FALSE, FALSE,
4317
 
            AUX_BETWEEN_BUTTON_GROUPS);
4318
 
 
4319
 
    sp_toolbox_button_new(tbl, Inkscape::ICON_SIZE_SMALL_TOOLBAR,
4320
 
            "connector_avoid", GTK_SIGNAL_FUNC(sp_connector_path_set_avoid),
4321
 
            tt, _("Make connectors avoid selected objects"));
4322
 
 
4323
 
    sp_toolbox_button_new(tbl, Inkscape::ICON_SIZE_SMALL_TOOLBAR,
4324
 
            "connector_ignore", GTK_SIGNAL_FUNC(sp_connector_path_set_ignore),
4325
 
            tt, _("Make connectors ignore selected objects"));
4326
 
 
4327
 
    //  interval
4328
 
    gtk_box_pack_start(GTK_BOX(tbl), gtk_hbox_new(FALSE, 0), FALSE, FALSE,
4329
 
            AUX_BETWEEN_BUTTON_GROUPS);
 
5078
    {
 
5079
        InkAction* inky = ink_action_new( "ConnectorAvoidAction",
 
5080
                                          _("Avoid"),
 
5081
                                          _("Make connectors avoid selected objects"),
 
5082
                                          "connector_avoid",
 
5083
                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
 
5084
        g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_path_set_avoid), holder );
 
5085
        gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
 
5086
    }
 
5087
 
 
5088
    {
 
5089
        InkAction* inky = ink_action_new( "ConnectorIgnoreAction",
 
5090
                                          _("Ignore"),
 
5091
                                          _("Make connectors ignore selected objects"),
 
5092
                                          "connector_ignore",
 
5093
                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
 
5094
        g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_path_set_ignore), holder );
 
5095
        gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
 
5096
    }
 
5097
 
 
5098
    EgeAdjustmentAction* eact = 0;
4330
5099
 
4331
5100
    // Spacing spinbox
4332
 
    {
4333
 
        GtkWidget *object_spacing = sp_tb_spinbutton(_("Spacing:"),
4334
 
                _("The amount of space left around objects by auto-routing connectors"),
4335
 
                "tools.connector", "spacing", 10, NULL, tbl, TRUE,
4336
 
                "inkscape:connector-spacing", 0, 100, 1.0, 10.0,
4337
 
                connector_spacing_changed, 1, 0);
 
5101
    eact = create_adjustment_action( "ConnectorSpacingAction",
 
5102
                                     _("Connector Spacing"), _("Spacing:"),
 
5103
                                     _("The amount of space left around objects by auto-routing connectors"),
 
5104
                                     "tools.connector", "spacing", defaultConnSpacing,
 
5105
                                     GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "inkscape:connector-spacing",
 
5106
                                     0, 100, 1.0, 10.0,
 
5107
                                     0, 0, 0,
 
5108
                                     connector_spacing_changed, 1, 0 );
 
5109
    gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
4338
5110
 
4339
 
        gtk_box_pack_start(GTK_BOX(tbl), object_spacing, FALSE, FALSE,
4340
 
                AUX_SPACING);
4341
 
    }
4342
5111
    // Graph (connector network) layout
4343
 
    sp_toolbox_button_new(tbl, Inkscape::ICON_SIZE_SMALL_TOOLBAR,
4344
 
            "graph_layout", GTK_SIGNAL_FUNC(sp_connector_graph_layout),
4345
 
            tt, _("Nicely arrange selected connector network"));
 
5112
    {
 
5113
        InkAction* inky = ink_action_new( "ConnectorGraphAction",
 
5114
                                          _("Graph"),
 
5115
                                          _("Nicely arrange selected connector network"),
 
5116
                                          "graph_layout",
 
5117
                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
 
5118
        g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_graph_layout), holder );
 
5119
        gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
 
5120
    }
 
5121
 
4346
5122
    // Default connector length spinbox
4347
 
    {
4348
 
        GtkWidget *connector_length = sp_tb_spinbutton(_("Length:"),
4349
 
                _("Ideal length for connectors when layout is applied"),
4350
 
                "tools.connector", "length", 100, NULL, tbl, TRUE,
4351
 
                "inkscape:connector-length", 10, 1000, 10.0, 100.0,
4352
 
                connector_length_changed, 1, 0);
4353
 
 
4354
 
        gtk_box_pack_start(GTK_BOX(tbl), connector_length, FALSE, FALSE,
4355
 
                AUX_SPACING);
4356
 
    }
4357
 
    gchar const *tbuttonstate;
 
5123
    eact = create_adjustment_action( "ConnectorLengthAction",
 
5124
                                     _("Connector Length"), _("Length:"),
 
5125
                                     _("Ideal length for connectors when layout is applied"),
 
5126
                                     "tools.connector", "length", 100,
 
5127
                                     GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "inkscape:connector-length",
 
5128
                                     10, 1000, 10.0, 100.0,
 
5129
                                     0, 0, 0,
 
5130
                                     connector_length_changed, 1, 0 );
 
5131
    gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
 
5132
 
 
5133
 
4358
5134
    // Directed edges toggle button
4359
5135
    {
4360
 
        GtkWidget *tbutton = gtk_toggle_button_new (); 
4361
 
        gtk_button_set_relief       (GTK_BUTTON (tbutton), GTK_RELIEF_NONE);
4362
 
        gtk_container_add           (GTK_CONTAINER (tbutton), sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, "directed_graph")); 
4363
 
        gtk_toggle_button_set_mode  (GTK_TOGGLE_BUTTON (tbutton), FALSE);
4364
 
        gtk_tooltips_set_tip(tt, tbutton, _("Make connectors with end-markers (arrows) point downwards"), NULL);
4365
 
 
4366
 
        gtk_box_pack_start  (GTK_BOX  (tbl), tbutton, FALSE, FALSE, 0);
4367
 
        g_signal_connect(G_OBJECT(tbutton), "toggled", GTK_SIGNAL_FUNC(sp_directed_graph_layout_toggled), tbl);
4368
 
        tbuttonstate = prefs_get_string_attribute("tools.connector", "directedlayout");
4369
 
        gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(tbutton), 
4370
 
                (tbuttonstate && !strcmp(tbuttonstate, "true"))?TRUE:FALSE );
 
5136
        InkToggleAction* act = ink_toggle_action_new( "ConnectorDirectedAction",
 
5137
                                                      _("Downwards"),
 
5138
                                                      _("Make connectors with end-markers (arrows) point downwards"),
 
5139
                                                      "directed_graph",
 
5140
                                                      Inkscape::ICON_SIZE_DECORATION );
 
5141
        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
 
5142
 
 
5143
        gchar const* tbuttonstate = prefs_get_string_attribute( "tools.connector", "directedlayout" );
 
5144
        gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act),
 
5145
                (tbuttonstate && !strcmp(tbuttonstate, "true")) ? TRUE:FALSE );
 
5146
 
 
5147
        g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_directed_graph_layout_toggled), holder );
4371
5148
    }
 
5149
 
4372
5150
    // Avoid overlaps toggle button
4373
5151
    {
4374
 
        GtkWidget *tbutton = gtk_toggle_button_new (); 
4375
 
        gtk_button_set_relief       (GTK_BUTTON (tbutton), GTK_RELIEF_NONE);
4376
 
        gtk_container_add           (GTK_CONTAINER (tbutton), sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, "remove_overlaps")); 
4377
 
        gtk_toggle_button_set_mode  (GTK_TOGGLE_BUTTON (tbutton), FALSE);
4378
 
        gtk_tooltips_set_tip(tt, tbutton, _("Do not allow overlapping shapes"), NULL);
4379
 
 
4380
 
        gtk_box_pack_start  (GTK_BOX  (tbl), tbutton, FALSE, FALSE, 0);
4381
 
        g_signal_connect(G_OBJECT(tbutton), "toggled", GTK_SIGNAL_FUNC(sp_nooverlaps_graph_layout_toggled), tbl);
4382
 
        tbuttonstate = prefs_get_string_attribute("tools.connector", "avoidoverlaplayout");
4383
 
        gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(tbutton), 
4384
 
                (tbuttonstate && !strcmp(tbuttonstate, "true"))?TRUE:FALSE );
 
5152
        InkToggleAction* act = ink_toggle_action_new( "ConnectorOverlapAction",
 
5153
                                                      _("Remove overlaps"),
 
5154
                                                      _("Do not allow overlapping shapes"),
 
5155
                                                      "remove_overlaps",
 
5156
                                                      Inkscape::ICON_SIZE_DECORATION );
 
5157
        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
 
5158
 
 
5159
        gchar const* tbuttonstate = prefs_get_string_attribute( "tools.connector", "avoidoverlaplayout" );
 
5160
        gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act),
 
5161
                (tbuttonstate && !strcmp(tbuttonstate, "true")) ? TRUE:FALSE );
 
5162
 
 
5163
        g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_nooverlaps_graph_layout_toggled), holder );
4385
5164
    }
4386
5165
 
4387
 
    gtk_widget_show_all(tbl);
4388
 
    sp_set_font_size_smaller (tbl);
4389
 
    
4390
5166
    // Code to watch for changes to the connector-spacing attribute in
4391
5167
    // the XML.
4392
5168
    Inkscape::XML::Node *repr = SP_OBJECT_REPR(desktop->namedview);
4393
5169
    g_assert(repr != NULL);
4394
 
        
4395
 
    Inkscape::XML::Node *oldrepr = (Inkscape::XML::Node *)
4396
 
            gtk_object_get_data(GTK_OBJECT(tbl), "repr");
4397
 
    
4398
 
    if (oldrepr) { // remove old listener
4399
 
        sp_repr_remove_listener_by_data(oldrepr, tbl);
4400
 
        Inkscape::GC::release(oldrepr);
4401
 
        oldrepr = NULL;
4402
 
        g_object_set_data(G_OBJECT(tbl), "repr", NULL);
4403
 
    }
 
5170
 
 
5171
    purge_repr_listener( holder, holder );
4404
5172
 
4405
5173
    if (repr) {
4406
 
        g_object_set_data(G_OBJECT(tbl), "repr", repr);
 
5174
        g_object_set_data( holder, "repr", repr );
4407
5175
        Inkscape::GC::anchor(repr);
4408
 
        sp_repr_add_listener(repr, &connector_tb_repr_events, tbl);
4409
 
        sp_repr_synthesize_events(repr, &connector_tb_repr_events, tbl);
4410
 
    }
4411
 
    
4412
 
    return tbl;
4413
 
 
4414
 
} // end of sp_connector_toolbox_new()
4415
 
 
 
5176
        sp_repr_add_listener( repr, &connector_tb_repr_events, holder );
 
5177
        sp_repr_synthesize_events( repr, &connector_tb_repr_events, holder );
 
5178
    }
 
5179
} // end of sp_connector_toolbox_prep()
 
5180
 
 
5181
 
 
5182
//#########################
 
5183
//##     Paintbucket     ##
 
5184
//#########################
 
5185
 
 
5186
static void paintbucket_channels_changed(EgeSelectOneAction* act, GObject* /*tbl*/)
 
5187
{
 
5188
    gint channels = ege_select_one_action_get_active( act );
 
5189
    flood_channels_set_channels( channels );
 
5190
}
 
5191
 
 
5192
static void paintbucket_threshold_changed(GtkAdjustment *adj, GObject */*tbl*/)
 
5193
{
 
5194
    prefs_set_int_attribute("tools.paintbucket", "threshold", (gint)adj->value);
 
5195
}
 
5196
 
 
5197
static void paintbucket_autogap_changed(EgeSelectOneAction* act, GObject */*tbl*/)
 
5198
{
 
5199
    prefs_set_int_attribute("tools.paintbucket", "autogap", ege_select_one_action_get_active( act ));
 
5200
}
 
5201
 
 
5202
static void paintbucket_offset_changed(GtkAdjustment *adj, GObject *tbl)
 
5203
{
 
5204
    UnitTracker* tracker = static_cast<UnitTracker*>(g_object_get_data( tbl, "tracker" ));
 
5205
    SPUnit const *unit = tracker->getActiveUnit();
 
5206
 
 
5207
    prefs_set_double_attribute("tools.paintbucket", "offset", (gdouble)sp_units_get_pixels(adj->value, *unit));
 
5208
 
 
5209
    prefs_set_string_attribute("tools.paintbucket", "offsetunits", sp_unit_get_abbreviation(unit));
 
5210
}
 
5211
 
 
5212
static void paintbucket_defaults(GtkWidget *, GObject *dataKludge)
 
5213
{
 
5214
    // FIXME: make defaults settable via Inkscape Options
 
5215
    struct KeyValue {
 
5216
        char const *key;
 
5217
        double value;
 
5218
    } const key_values[] = {
 
5219
        {"threshold", 15},
 
5220
        {"offset", 0.0}
 
5221
    };
 
5222
 
 
5223
    for (unsigned i = 0; i < G_N_ELEMENTS(key_values); ++i) {
 
5224
        KeyValue const &kv = key_values[i];
 
5225
        GtkAdjustment* adj = static_cast<GtkAdjustment *>(g_object_get_data(dataKludge, kv.key));
 
5226
        if ( adj ) {
 
5227
            gtk_adjustment_set_value(adj, kv.value);
 
5228
        }
 
5229
    }
 
5230
 
 
5231
    EgeSelectOneAction* channels_action = EGE_SELECT_ONE_ACTION( g_object_get_data( dataKludge, "channels_action" ) );
 
5232
    ege_select_one_action_set_active( channels_action, FLOOD_CHANNELS_RGB );
 
5233
    EgeSelectOneAction* autogap_action = EGE_SELECT_ONE_ACTION( g_object_get_data( dataKludge, "autogap_action" ) );
 
5234
    ege_select_one_action_set_active( autogap_action, 0 );
 
5235
}
 
5236
 
 
5237
static void sp_paintbucket_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
 
5238
{
 
5239
    EgeAdjustmentAction* eact = 0;
 
5240
 
 
5241
    {
 
5242
        GtkListStore* model = gtk_list_store_new( 2, G_TYPE_STRING, G_TYPE_INT );
 
5243
 
 
5244
        GList* items = 0;
 
5245
        gint count = 0;
 
5246
        for ( items = flood_channels_dropdown_items_list(); items ; items = g_list_next(items) )
 
5247
        {
 
5248
            GtkTreeIter iter;
 
5249
            gtk_list_store_append( model, &iter );
 
5250
            gtk_list_store_set( model, &iter, 0, reinterpret_cast<gchar*>(items->data), 1, count, -1 );
 
5251
            count++;
 
5252
        }
 
5253
        g_list_free( items );
 
5254
        items = 0;
 
5255
        EgeSelectOneAction* act1 = ege_select_one_action_new( "ChannelsAction", _("Fill by"), (""), NULL, GTK_TREE_MODEL(model) );
 
5256
        g_object_set( act1, "short_label", _("Fill by:"), NULL );
 
5257
        ege_select_one_action_set_appearance( act1, "compact" );
 
5258
        ege_select_one_action_set_active( act1, prefs_get_int_attribute("tools.paintbucket", "channels", 0) );
 
5259
        g_signal_connect( G_OBJECT(act1), "changed", G_CALLBACK(paintbucket_channels_changed), holder );
 
5260
        gtk_action_group_add_action( mainActions, GTK_ACTION(act1) );
 
5261
        g_object_set_data( holder, "channels_action", act1 );
 
5262
    }
 
5263
 
 
5264
    // Spacing spinbox
 
5265
    {
 
5266
        eact = create_adjustment_action(
 
5267
            "ThresholdAction",
 
5268
            _("Fill Threshold"), _("Threshold:"),
 
5269
            _("The maximum allowed difference between the clicked pixel and the neighboring pixels to be counted in the fill"),
 
5270
            "tools.paintbucket", "threshold", 5, GTK_WIDGET(desktop->canvas), NULL, holder, TRUE,
 
5271
            "inkscape:paintbucket-threshold", 0, 100.0, 1.0, 10.0,
 
5272
            0, 0, 0,
 
5273
            paintbucket_threshold_changed, 1, 0 );
 
5274
 
 
5275
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
 
5276
    }
 
5277
 
 
5278
    // Create the units menu.
 
5279
    UnitTracker* tracker = new UnitTracker( SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE );
 
5280
    tracker->setActiveUnit(sp_unit_get_by_abbreviation(prefs_get_string_attribute("tools.paintbucket", "offsetunits")));
 
5281
    g_object_set_data( holder, "tracker", tracker );
 
5282
    {
 
5283
        GtkAction* act = tracker->createAction( "PaintbucketUnitsAction", _("Units"), ("") );
 
5284
        gtk_action_group_add_action( mainActions, act );
 
5285
    }
 
5286
 
 
5287
    // Offset spinbox
 
5288
    {
 
5289
        eact = create_adjustment_action(
 
5290
            "OffsetAction",
 
5291
            _("Grow/shrink by"), _("Grow/shrink by:"),
 
5292
            _("The amount to grow (positive) or shrink (negative) the created fill path"),
 
5293
            "tools.paintbucket", "offset", 0, GTK_WIDGET(desktop->canvas), NULL/*us*/, holder, TRUE,
 
5294
            "inkscape:paintbucket-offset", -1e6, 1e6, 0.1, 0.5,
 
5295
            0, 0, 0,
 
5296
            paintbucket_offset_changed, 1, 2);
 
5297
        tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) );
 
5298
 
 
5299
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
 
5300
    }
 
5301
 
 
5302
    /* Auto Gap */
 
5303
    {
 
5304
        GtkListStore* model = gtk_list_store_new( 2, G_TYPE_STRING, G_TYPE_INT );
 
5305
 
 
5306
        GList* items = 0;
 
5307
        gint count = 0;
 
5308
        for ( items = flood_autogap_dropdown_items_list(); items ; items = g_list_next(items) )
 
5309
        {
 
5310
            GtkTreeIter iter;
 
5311
            gtk_list_store_append( model, &iter );
 
5312
            gtk_list_store_set( model, &iter, 0, reinterpret_cast<gchar*>(items->data), 1, count, -1 );
 
5313
            count++;
 
5314
        }
 
5315
        g_list_free( items );
 
5316
        items = 0;
 
5317
        EgeSelectOneAction* act2 = ege_select_one_action_new( "AutoGapAction", _("Close gaps"), (""), NULL, GTK_TREE_MODEL(model) );
 
5318
        g_object_set( act2, "short_label", _("Close gaps:"), NULL );
 
5319
        ege_select_one_action_set_appearance( act2, "compact" );
 
5320
        ege_select_one_action_set_active( act2, prefs_get_int_attribute("tools.paintbucket", "autogap", 0) );
 
5321
        g_signal_connect( G_OBJECT(act2), "changed", G_CALLBACK(paintbucket_autogap_changed), holder );
 
5322
        gtk_action_group_add_action( mainActions, GTK_ACTION(act2) );
 
5323
        g_object_set_data( holder, "autogap_action", act2 );
 
5324
    }
 
5325
 
 
5326
    /* Reset */
 
5327
    {
 
5328
        GtkAction* act = gtk_action_new( "PaintbucketResetAction",
 
5329
                                          _("Defaults"),
 
5330
                                          _("Reset paint bucket parameters to defaults (use Inkscape Preferences > Tools to change defaults)"),
 
5331
                                          GTK_STOCK_CLEAR );
 
5332
        g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(paintbucket_defaults), holder );
 
5333
        gtk_action_group_add_action( mainActions, act );
 
5334
        gtk_action_set_sensitive( act, TRUE );
 
5335
    }
 
5336
 
 
5337
}
4416
5338
 
4417
5339
/*
4418
5340
  Local Variables:
4425
5347
*/
4426
5348
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
4427
5349
 
 
5350
 
 
5351
 
 
5352