~ubuntu-branches/debian/experimental/inkscape/experimental

« back to all changes in this revision

Viewing changes to src/widgets/toolbox.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Viehmann
  • Date: 2008-09-09 23:29:02 UTC
  • mfrom: (1.1.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20080909232902-c50iujhk1w79u8e7
Tags: 0.46-2.1
* Non-maintainer upload.
* Add upstream patch fixing a crash in the open dialog
  in the zh_CN.utf8 locale. Closes: #487623.
  Thanks to Luca Bruno for the patch.

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