Code

Fixed const/non-const mismatch loop.
[inkscape.git] / src / ink-action.cpp
4 #include <glib/gi18n.h>
5 #include <gtk/gtkalignment.h>
6 #include <gtk/gtktooltips.h>
7 #include <gtk/gtktoolitem.h>
8 #include <gtk/gtktoggletoolbutton.h>
9 #include <gtk/gtkcheckmenuitem.h>
10 #include <gtk/gtkimagemenuitem.h>
12 #include "icon-size.h"
13 #include "ink-action.h"
15 #include "widgets/button.h"
16 #include "widgets/icon.h"
18 static void ink_action_class_init( InkActionClass* klass );
19 static void ink_action_init( InkAction* action );
20 static void ink_action_finalize( GObject* obj );
21 static void ink_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec );
22 static void ink_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec );
24 static GtkWidget* ink_action_create_menu_item( GtkAction* action );
25 static GtkWidget* ink_action_create_tool_item( GtkAction* action );
27 static GtkActionClass* gInkActionParentClass = 0;
29 struct _InkActionPrivate
30 {
31     gchar* iconId;
32     Inkscape::IconSize iconSize;
33 };
35 #define INK_ACTION_GET_PRIVATE( o ) ( G_TYPE_INSTANCE_GET_PRIVATE( (o), INK_ACTION_TYPE, InkActionPrivate ) )
37 GType ink_action_get_type( void )
38 {
39     static GType myType = 0;
40     if ( !myType ) {
41         static const GTypeInfo myInfo = {
42             sizeof( InkActionClass ),
43             NULL, /* base_init */
44             NULL, /* base_finalize */
45             (GClassInitFunc)ink_action_class_init,
46             NULL, /* class_finalize */
47             NULL, /* class_data */
48             sizeof( InkAction ),
49             0, /* n_preallocs */
50             (GInstanceInitFunc)ink_action_init,
51             NULL
52         };
54         myType = g_type_register_static( GTK_TYPE_ACTION, "InkAction", &myInfo, (GTypeFlags)0 );
55     }
57     return myType;
58 }
60 enum {
61     PROP_INK_ID = 1,
62     PROP_INK_SIZE
63 };
65 static void ink_action_class_init( InkActionClass* klass )
66 {
67     if ( klass ) {
68         gInkActionParentClass = GTK_ACTION_CLASS( g_type_class_peek_parent( klass ) );
69         GObjectClass * objClass = G_OBJECT_CLASS( klass );
71         objClass->finalize = ink_action_finalize;
72         objClass->get_property = ink_action_get_property;
73         objClass->set_property = ink_action_set_property;
75         klass->parent_class.create_menu_item = ink_action_create_menu_item;
76         klass->parent_class.create_tool_item = ink_action_create_tool_item;
77         /*klass->parent_class.connect_proxy = connect_proxy;*/
78         /*klass->parent_class.disconnect_proxy = disconnect_proxy;*/
80         g_object_class_install_property( objClass,
81                                          PROP_INK_ID,
82                                          g_param_spec_string( "iconId",
83                                                               "Icon ID",
84                                                               "The id for the icon",
85                                                               "",
86                                                               (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
88         g_object_class_install_property( objClass,
89                                          PROP_INK_SIZE,
90                                          g_param_spec_int( "iconSize",
91                                                            "Icon Size",
92                                                            "The size the icon",
93                                                            (int)Inkscape::ICON_SIZE_MENU,
94                                                            (int)Inkscape::ICON_SIZE_DECORATION,
95                                                            (int)Inkscape::ICON_SIZE_SMALL_TOOLBAR,
96                                                            (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
98         g_type_class_add_private( klass, sizeof(InkActionClass) );
99     }
102 static void ink_action_init( InkAction* action )
104     action->private_data = INK_ACTION_GET_PRIVATE( action );
105     action->private_data->iconId = 0;
106     action->private_data->iconSize = Inkscape::ICON_SIZE_SMALL_TOOLBAR;
109 static void ink_action_finalize( GObject* obj )
111     InkAction* action = INK_ACTION( obj );
113     g_free( action->private_data->iconId );
114     g_free( action->private_data );
118 //Any strings passed in should already be localised
119 InkAction* ink_action_new( const gchar *name,
120                            const gchar *label,
121                            const gchar *tooltip,
122                            const gchar *inkId,
123                            Inkscape::IconSize size )
125     GObject* obj = (GObject*)g_object_new( INK_ACTION_TYPE,
126                                            "name", name,
127                                            "label", label,
128                                            "tooltip", tooltip,
129                                            "iconId", inkId,
130                                            "iconSize", size,
131                                            NULL );
133     InkAction* action = INK_ACTION( obj );
135     return action;
138 static void ink_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec )
140     InkAction* action = INK_ACTION( obj );
141     (void)action;
142     switch ( propId ) {
143         case PROP_INK_ID:
144         {
145             g_value_set_string( value, action->private_data->iconId );
146         }
147         break;
149         case PROP_INK_SIZE:
150         {
151             g_value_set_int( value, action->private_data->iconSize );
152         }
153         break;
155         default:
156             G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
157     }
160 void ink_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec )
162     InkAction* action = INK_ACTION( obj );
163     (void)action;
164     switch ( propId ) {
165         case PROP_INK_ID:
166         {
167             gchar* tmp = action->private_data->iconId;
168             action->private_data->iconId = g_value_dup_string( value );
169             g_free( tmp );
170         }
171         break;
173         case PROP_INK_SIZE:
174         {
175             action->private_data->iconSize = (Inkscape::IconSize)g_value_get_int( value );
176         }
177         break;
179         default:
180         {
181             G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
182         }
183     }
186 #include <gtk/gtkstock.h>
188 static GtkWidget* ink_action_create_menu_item( GtkAction* action )
190     InkAction* act = INK_ACTION( action );
191     GtkWidget* item = 0;
193     if ( act->private_data->iconId ) {
194         gchar* label = 0;
195         g_object_get( G_OBJECT(act), "label", &label, NULL );
197         item = gtk_image_menu_item_new_with_mnemonic( label );
198         GtkWidget* child = sp_icon_new( Inkscape::ICON_SIZE_MENU, act->private_data->iconId );
199         // TODO this work-around is until SPIcon will live properly inside of a popup menu
200         if ( SP_IS_ICON(child) ) {
201             SPIcon* icon = SP_ICON(child);
202             sp_icon_fetch_pixbuf( icon );
203             GdkPixbuf* target = icon->pb;
204             if ( target ) {
205                 child = gtk_image_new_from_pixbuf( target );
206                 gtk_widget_set_sensitive(child, gtk_action_is_sensitive(action));
207                 gtk_widget_destroy( GTK_WIDGET(icon) );
208             }
209         }
210         gtk_widget_show_all( child );
211         gtk_image_menu_item_set_image( GTK_IMAGE_MENU_ITEM(item), child );
213         g_free( label );
214         label = 0;
215     } else {
216         item = gInkActionParentClass->create_menu_item( action );
217     }
219     return item;
222 static GtkWidget* ink_action_create_tool_item( GtkAction* action )
224     InkAction* act = INK_ACTION( action );
225     GtkWidget* item = gInkActionParentClass->create_tool_item(action);
227     if ( act->private_data->iconId ) {
228         if ( GTK_IS_TOOL_BUTTON(item) ) {
229             GtkToolButton* button = GTK_TOOL_BUTTON(item);
231             GtkWidget* child = sp_icon_new( act->private_data->iconSize, act->private_data->iconId );
232             gtk_tool_button_set_icon_widget( button, child );
233         } else {
234             // For now trigger a warning but don't do anything else
235             GtkToolButton* button = GTK_TOOL_BUTTON(item);
236             (void)button;
237         }
238     }
240     // TODO investigate if needed
241     gtk_widget_show_all( item );
243     return item;
248 /* --------------------------------------------------------------- */
249 /* --------------------------------------------------------------- */
250 /* --------------------------------------------------------------- */
251 /* --------------------------------------------------------------- */
254 static void ink_toggle_action_class_init( InkToggleActionClass* klass );
255 static void ink_toggle_action_init( InkToggleAction* action );
256 static void ink_toggle_action_finalize( GObject* obj );
257 static void ink_toggle_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec );
258 static void ink_toggle_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec );
260 static GtkWidget* ink_toggle_action_create_menu_item( GtkAction* action );
261 static GtkWidget* ink_toggle_action_create_tool_item( GtkAction* action );
263 static void ink_toggle_action_update_icon( InkToggleAction* action );
265 static GtkToggleActionClass* gInkToggleActionParentClass = 0;
267 struct _InkToggleActionPrivate
269     gchar* iconId;
270     Inkscape::IconSize iconSize;
271 };
273 #define INK_TOGGLE_ACTION_GET_PRIVATE( o ) ( G_TYPE_INSTANCE_GET_PRIVATE( (o), INK_TOGGLE_ACTION_TYPE, InkToggleActionPrivate ) )
275 GType ink_toggle_action_get_type( void )
277     static GType myType = 0;
278     if ( !myType ) {
279         static const GTypeInfo myInfo = {
280             sizeof( InkToggleActionClass ),
281             NULL, /* base_init */
282             NULL, /* base_finalize */
283             (GClassInitFunc)ink_toggle_action_class_init,
284             NULL, /* class_finalize */
285             NULL, /* class_data */
286             sizeof( InkToggleAction ),
287             0, /* n_preallocs */
288             (GInstanceInitFunc)ink_toggle_action_init,
289             NULL
290         };
292         myType = g_type_register_static( GTK_TYPE_TOGGLE_ACTION, "InkToggleAction", &myInfo, (GTypeFlags)0 );
293     }
295     return myType;
299 static void ink_toggle_action_class_init( InkToggleActionClass* klass )
301     if ( klass ) {
302         gInkToggleActionParentClass = GTK_TOGGLE_ACTION_CLASS( g_type_class_peek_parent( klass ) );
303         GObjectClass * objClass = G_OBJECT_CLASS( klass );
305         objClass->finalize = ink_toggle_action_finalize;
306         objClass->get_property = ink_toggle_action_get_property;
307         objClass->set_property = ink_toggle_action_set_property;
309         klass->parent_class.parent_class.create_menu_item = ink_toggle_action_create_menu_item;
310         klass->parent_class.parent_class.create_tool_item = ink_toggle_action_create_tool_item;
311         /*klass->parent_class.connect_proxy = connect_proxy;*/
312         /*klass->parent_class.disconnect_proxy = disconnect_proxy;*/
314         g_object_class_install_property( objClass,
315                                          PROP_INK_ID,
316                                          g_param_spec_string( "iconId",
317                                                               "Icon ID",
318                                                               "The id for the icon",
319                                                               "",
320                                                               (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
322         g_object_class_install_property( objClass,
323                                          PROP_INK_SIZE,
324                                          g_param_spec_int( "iconSize",
325                                                            "Icon Size",
326                                                            "The size the icon",
327                                                            (int)Inkscape::ICON_SIZE_MENU,
328                                                            (int)99,
329                                                            (int)Inkscape::ICON_SIZE_SMALL_TOOLBAR,
330                                                            (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
332         g_type_class_add_private( klass, sizeof(InkToggleActionClass) );
333     }
336 static void ink_toggle_action_init( InkToggleAction* action )
338     action->private_data = INK_TOGGLE_ACTION_GET_PRIVATE( action );
339     action->private_data->iconId = 0;
340     action->private_data->iconSize = Inkscape::ICON_SIZE_SMALL_TOOLBAR;
343 static void ink_toggle_action_finalize( GObject* obj )
345     InkToggleAction* action = INK_TOGGLE_ACTION( obj );
347     g_free( action->private_data->iconId );
348     g_free( action->private_data );
352 InkToggleAction* ink_toggle_action_new( const gchar *name,
353                            const gchar *label,
354                            const gchar *tooltip,
355                            const gchar *inkId,
356                            Inkscape::IconSize size,
357                            SPAttributeEnum attr)
359     GObject* obj = (GObject*)g_object_new( INK_TOGGLE_ACTION_TYPE,
360                                            "name", name,
361                                            "label", label,
362                                            "tooltip", tooltip,
363                                            "iconId", inkId,
364                                            "iconSize", Inkscape::getRegisteredIconSize(size),
365                                            //"SP_ATTR_INKSCAPE", attr, // Why doesn't this work and do I need to use g_object_set_data below?
366                                            NULL );
368     g_object_set_data(obj, "SP_ATTR_INKSCAPE", GINT_TO_POINTER(attr));
369     InkToggleAction* action = INK_TOGGLE_ACTION( obj );
371     return action;
374 static void ink_toggle_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec )
376     InkToggleAction* action = INK_TOGGLE_ACTION( obj );
377     (void)action;
378     switch ( propId ) {
379         case PROP_INK_ID:
380         {
381             g_value_set_string( value, action->private_data->iconId );
382         }
383         break;
385         case PROP_INK_SIZE:
386         {
387             g_value_set_int( value, action->private_data->iconSize );
388         }
389         break;
391         default:
392             G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
393     }
396 void ink_toggle_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec )
398     InkToggleAction* action = INK_TOGGLE_ACTION( obj );
399     (void)action;
400     switch ( propId ) {
401         case PROP_INK_ID:
402         {
403             gchar* tmp = action->private_data->iconId;
404             action->private_data->iconId = g_value_dup_string( value );
405             g_free( tmp );
407             ink_toggle_action_update_icon( action );
408         }
409         break;
411         case PROP_INK_SIZE:
412         {
413             action->private_data->iconSize = (Inkscape::IconSize)g_value_get_int( value );
414         }
415         break;
417         default:
418         {
419             G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
420         }
421     }
424 static GtkWidget* ink_toggle_action_create_menu_item( GtkAction* action )
426     GtkWidget* item = gInkToggleActionParentClass->parent_class.create_menu_item(action);
428     return item;
431 static GtkWidget* ink_toggle_action_create_tool_item( GtkAction* action )
433     InkToggleAction* act = INK_TOGGLE_ACTION( action );
435     GtkWidget* item = gInkToggleActionParentClass->parent_class.create_tool_item(action);
436     if ( GTK_IS_TOOL_BUTTON(item) ) {
437         GtkToolButton* button = GTK_TOOL_BUTTON(item);
438         if ( act->private_data->iconId ) {
439             GtkWidget* child = sp_icon_new( act->private_data->iconSize, act->private_data->iconId );
440             GtkWidget* align = gtk_alignment_new( 0.5, 0.5, 0.0, 0.0 );
441             gtk_container_add( GTK_CONTAINER(align), child );
442             gtk_tool_button_set_icon_widget( button, align );
443         } else {
444             gchar *label;
445             g_object_get (G_OBJECT(action), "short_label", &label, NULL);
446             gtk_tool_button_set_label( button, label );
447         }
448     } else {
449         // For now trigger a warning but don't do anything else
450         GtkToolButton* button = GTK_TOOL_BUTTON(item);
451         (void)button;
452     }
453     gtk_widget_show_all( item );
455     return item;
459 static void ink_toggle_action_update_icon( InkToggleAction* action )
461     if ( action ) {
462         GSList* proxies = gtk_action_get_proxies( GTK_ACTION(action) );
463         while ( proxies ) {
464             if ( GTK_IS_TOOL_ITEM(proxies->data) ) {
465                 if ( GTK_IS_TOOL_BUTTON(proxies->data) ) {
466                     GtkToolButton* button = GTK_TOOL_BUTTON(proxies->data);
468                     GtkWidget* child = sp_icon_new( action->private_data->iconSize, action->private_data->iconId );
469                     gtk_widget_show_all( child );
470                     gtk_tool_button_set_icon_widget( button, child );
471                 }
472             }
474             proxies = g_slist_next( proxies );
475         }
476     }
480 /* --------------------------------------------------------------- */
481 /* --------------------------------------------------------------- */
482 /* --------------------------------------------------------------- */
483 /* --------------------------------------------------------------- */
486 static void ink_radio_action_class_init( InkRadioActionClass* klass );
487 static void ink_radio_action_init( InkRadioAction* action );
488 static void ink_radio_action_finalize( GObject* obj );
489 static void ink_radio_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec );
490 static void ink_radio_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec );
492 static GtkWidget* ink_radio_action_create_menu_item( GtkAction* action );
493 static GtkWidget* ink_radio_action_create_tool_item( GtkAction* action );
495 static GtkRadioActionClass* gInkRadioActionParentClass = 0;
497 struct _InkRadioActionPrivate
499     gchar* iconId;
500     Inkscape::IconSize iconSize;
501 };
503 #define INK_RADIO_ACTION_GET_PRIVATE( o ) ( G_TYPE_INSTANCE_GET_PRIVATE( (o), INK_RADIO_ACTION_TYPE, InkRadioActionPrivate ) )
505 GType ink_radio_action_get_type( void )
507     static GType myType = 0;
508     if ( !myType ) {
509         static const GTypeInfo myInfo = {
510             sizeof( InkRadioActionClass ),
511             NULL, /* base_init */
512             NULL, /* base_finalize */
513             (GClassInitFunc)ink_radio_action_class_init,
514             NULL, /* class_finalize */
515             NULL, /* class_data */
516             sizeof( InkRadioAction ),
517             0, /* n_preallocs */
518             (GInstanceInitFunc)ink_radio_action_init,
519             NULL
520         };
522         myType = g_type_register_static( GTK_TYPE_RADIO_ACTION, "InkRadioAction", &myInfo, (GTypeFlags)0 );
523     }
525     return myType;
529 static void ink_radio_action_class_init( InkRadioActionClass* klass )
531     if ( klass ) {
532         gInkRadioActionParentClass = GTK_RADIO_ACTION_CLASS( g_type_class_peek_parent( klass ) );
533         GObjectClass * objClass = G_OBJECT_CLASS( klass );
535         objClass->finalize = ink_radio_action_finalize;
536         objClass->get_property = ink_radio_action_get_property;
537         objClass->set_property = ink_radio_action_set_property;
539         klass->parent_class.parent_class.parent_class.create_menu_item = ink_radio_action_create_menu_item;
540         klass->parent_class.parent_class.parent_class.create_tool_item = ink_radio_action_create_tool_item;
541         /*klass->parent_class.connect_proxy = connect_proxy;*/
542         /*klass->parent_class.disconnect_proxy = disconnect_proxy;*/
544         g_object_class_install_property( objClass,
545                                          PROP_INK_ID,
546                                          g_param_spec_string( "iconId",
547                                                               "Icon ID",
548                                                               "The id for the icon",
549                                                               "",
550                                                               (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
552         g_object_class_install_property( objClass,
553                                          PROP_INK_SIZE,
554                                          g_param_spec_int( "iconSize",
555                                                            "Icon Size",
556                                                            "The size the icon",
557                                                            (int)Inkscape::ICON_SIZE_MENU,
558                                                            (int)Inkscape::ICON_SIZE_DECORATION,
559                                                            (int)Inkscape::ICON_SIZE_SMALL_TOOLBAR,
560                                                            (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
562         g_type_class_add_private( klass, sizeof(InkRadioActionClass) );
563     }
566 static void ink_radio_action_init( InkRadioAction* action )
568     action->private_data = INK_RADIO_ACTION_GET_PRIVATE( action );
569     action->private_data->iconId = 0;
570     action->private_data->iconSize = Inkscape::ICON_SIZE_SMALL_TOOLBAR;
573 static void ink_radio_action_finalize( GObject* obj )
575     InkRadioAction* action = INK_RADIO_ACTION( obj );
577     g_free( action->private_data->iconId );
578     g_free( action->private_data );
582 InkRadioAction* ink_radio_action_new( const gchar *name,
583                            const gchar *label,
584                            const gchar *tooltip,
585                            const gchar *inkId,
586                            Inkscape::IconSize size )
588     GObject* obj = (GObject*)g_object_new( INK_RADIO_ACTION_TYPE,
589                                            "name", name,
590                                            "label", label,
591                                            "tooltip", tooltip,
592                                            "iconId", inkId,
593                                            "iconSize", Inkscape::getRegisteredIconSize(size),
594                                            NULL );
596     InkRadioAction* action = INK_RADIO_ACTION( obj );
598     return action;
601 static void ink_radio_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec )
603     InkRadioAction* action = INK_RADIO_ACTION( obj );
604     (void)action;
605     switch ( propId ) {
606         case PROP_INK_ID:
607         {
608             g_value_set_string( value, action->private_data->iconId );
609         }
610         break;
612         case PROP_INK_SIZE:
613         {
614             g_value_set_int( value, action->private_data->iconSize );
615         }
616         break;
618         default:
619             G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
620     }
623 void ink_radio_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec )
625     InkRadioAction* action = INK_RADIO_ACTION( obj );
626     (void)action;
627     switch ( propId ) {
628         case PROP_INK_ID:
629         {
630             gchar* tmp = action->private_data->iconId;
631             action->private_data->iconId = g_value_dup_string( value );
632             g_free( tmp );
633         }
634         break;
636         case PROP_INK_SIZE:
637         {
638             action->private_data->iconSize = (Inkscape::IconSize)g_value_get_int( value );
639         }
640         break;
642         default:
643         {
644             G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
645         }
646     }
649 static GtkWidget* ink_radio_action_create_menu_item( GtkAction* action )
651     GtkWidget* item = gInkRadioActionParentClass->parent_class.parent_class.create_menu_item(action);
653     return item;
656 static GtkWidget* ink_radio_action_create_tool_item( GtkAction* action )
658     InkRadioAction* act = INK_RADIO_ACTION( action );
659     GtkWidget* item = gInkRadioActionParentClass->parent_class.parent_class.create_tool_item(action);
661     if ( act->private_data->iconId ) {
662         if ( GTK_IS_TOOL_BUTTON(item) ) {
663             GtkToolButton* button = GTK_TOOL_BUTTON(item);
665             GtkWidget* child = sp_icon_new( act->private_data->iconSize, act->private_data->iconId );
666             GtkWidget* align = gtk_alignment_new( 0.5, 0.5, 0.0, 0.0 );
667             gtk_container_add( GTK_CONTAINER(align), child );
668             gtk_tool_button_set_icon_widget( button, align );
669         } else {
670             // For now trigger a warning but don't do anything else
671             GtkToolButton* button = GTK_TOOL_BUTTON(item);
672             (void)button;
673         }
674     }
676     // TODO investigate if needed
677     gtk_widget_show_all( item );
679     return item;