Code

Prevent localized doubles from being written into filter matrices
[inkscape.git] / src / helper / action.cpp
1 #define __SP_ACTION_C__
3 /** \file
4  * SPAction implementation
5  *
6  * Author:
7  *   Lauris Kaplinski <lauris@kaplinski.com>
8  *
9  * Copyright (C) 2003 Lauris Kaplinski
10  *
11  * This code is in public domain
12  */
14 #include <string.h>
16 #include "debug/logger.h"
17 #include "debug/timestamp.h"
18 #include "debug/simple-event.h"
19 #include "debug/event-tracker.h"
20 #include "ui/view/view.h"
21 #include "document.h"
22 #include "helper/action.h"
24 static void sp_action_class_init (SPActionClass *klass);
25 static void sp_action_init (SPAction *action);
26 static void sp_action_finalize (NRObject *object);
28 static NRActiveObjectClass *parent_class;
30 /**
31  * Register SPAction class and return its type.
32  */
33 NRType
34 sp_action_get_type (void)
35 {
36         static unsigned int type = 0;
37         if (!type) {
38                 type = nr_object_register_type (NR_TYPE_ACTIVE_OBJECT,
39                                                 "SPAction",
40                                                 sizeof (SPActionClass),
41                                                 sizeof (SPAction),
42                                                 (void (*) (NRObjectClass *)) sp_action_class_init,
43                                                 (void (*) (NRObject *)) sp_action_init);
44         }
45         return type;
46 }
48 /**
49  * SPAction vtable initialization.
50  */
51 static void
52 sp_action_class_init (SPActionClass *klass)
53 {
54         NRObjectClass * object_class;
56         object_class = (NRObjectClass *) klass;
58         parent_class = (NRActiveObjectClass *) (((NRObjectClass *) klass)->parent);
60         object_class->finalize = sp_action_finalize;
61         object_class->cpp_ctor = NRObject::invoke_ctor<SPAction>;
62 }
64 /**
65  * Callback for SPAction object initialization.
66  */
67 static void
68 sp_action_init (SPAction *action)
69 {
70         action->sensitive = 0;
71         action->active = 0;
72         action->view = NULL;
73         action->id = action->name = action->tip = NULL;
74         action->image = NULL;
75 }
77 /**
78  * Called before SPAction object destruction.
79  */
80 static void
81 sp_action_finalize (NRObject *object)
82 {
83         SPAction *action;
85         action = (SPAction *) object;
87         if (action->image) free (action->image);
88         if (action->tip) free (action->tip);
89         if (action->name) free (action->name);
90         if (action->id) free (action->id);
92         ((NRObjectClass *) (parent_class))->finalize (object);
93 }
95 /**
96  * Create new SPAction object and set its properties.
97  */
98 SPAction *
99 sp_action_new(Inkscape::UI::View::View *view,
100               const gchar *id,
101               const gchar *name,
102               const gchar *tip,
103               const gchar *image,
104               Inkscape::Verb * verb)
106         SPAction *action = (SPAction *)nr_object_new(SP_TYPE_ACTION);
108         action->view = view;
109         action->sensitive = TRUE;
110         if (id) action->id = strdup (id);
111         if (name) action->name = strdup (name);
112         if (tip) action->tip = strdup (tip);
113         if (image) action->image = strdup (image);
114         action->verb = verb;
116         return action;
119 namespace {
121 using Inkscape::Debug::SimpleEvent;
122 using Inkscape::Debug::Event;
123 using Inkscape::Util::share_static_string;
124 using Inkscape::Debug::timestamp;
126 typedef SimpleEvent<Event::INTERACTION> ActionEventBase;
128 class ActionEvent : public ActionEventBase {
129 public:
130     ActionEvent(SPAction const *action)
131     : ActionEventBase(share_static_string("action"))
132     {
133         _addProperty(share_static_string("timestamp"), timestamp());
134         if (action->view) {
135             SPDocument *document = action->view->doc();
136             if (document) {
137                 _addProperty(share_static_string("document"), document->serial());
138             }
139         }
140         _addProperty(share_static_string("verb"), action->id);
141     }
142 };
146 /**
147         \return   None
148         \brief    Executes an action
149         \param    action   The action to be executed
150         \param    data     Data that is passed into the action.  This depends
151                            on the situation that the action is used in.
153         This function implements the 'action' in SPActions.  It first validates
154         its parameters, making sure it got an action passed in.  Then it
155         turns that action into its parent class of NRActiveObject.  The
156         NRActiveObject allows for listeners to be attached to it.  This
157         function goes through those listeners and calls them with the
158         vector that was attached to the listener.
159 */
160 void
161 sp_action_perform (SPAction *action, void * data)
163         NRActiveObject *aobject;
165         nr_return_if_fail (action != NULL);
166         nr_return_if_fail (SP_IS_ACTION (action));
168         Inkscape::Debug::EventTracker<ActionEvent> tracker(action);
170         aobject = NR_ACTIVE_OBJECT(action);
171         if (aobject->callbacks) {
172                 unsigned int i;
173                 for (i = 0; i < aobject->callbacks->length; i++) {
174                         NRObjectListener *listener;
175                         SPActionEventVector *avector;
177                         listener = &aobject->callbacks->listeners[i];
178                         avector = (SPActionEventVector *) listener->vector;
180                         if ((listener->size >= sizeof (SPActionEventVector)) && avector != NULL && avector->perform != NULL) {
181                                 avector->perform (action, listener->data, data);
182                         }
183                 }
184         }
187 /**
188  * Change activation in all actions that can be taken with the action.
189  */
190 void
191 sp_action_set_active (SPAction *action, unsigned int active)
193         nr_return_if_fail (action != NULL);
194         nr_return_if_fail (SP_IS_ACTION (action));
196         if (active != action->active) {
197                 NRActiveObject *aobject;
198                 action->active = active;
199                 aobject = (NRActiveObject *) action;
200                 if (aobject->callbacks) {
201                         unsigned int i;
202                         for (i = 0; i < aobject->callbacks->length; i++) {
203                                 NRObjectListener *listener;
204                                 SPActionEventVector *avector;
205                                 listener = aobject->callbacks->listeners + i;
206                                 avector = (SPActionEventVector *) listener->vector;
207                                 if ((listener->size >= sizeof (SPActionEventVector)) && avector->set_active) {
208                                         avector->set_active (action, active, listener->data);
209                                 }
210                         }
211                 }
212         }
215 /**
216  * Change sensitivity in all actions that can be taken with the action.
217  */
218 void
219 sp_action_set_sensitive (SPAction *action, unsigned int sensitive)
221         nr_return_if_fail (action != NULL);
222         nr_return_if_fail (SP_IS_ACTION (action));
224         if (sensitive != action->sensitive) {
225                 NRActiveObject *aobject;
226                 action->sensitive = sensitive;
227                 aobject = (NRActiveObject *) action;
228                 if (aobject->callbacks) {
229                         unsigned int i;
230                         for (i = 0; i < aobject->callbacks->length; i++) {
231                                 NRObjectListener *listener;
232                                 SPActionEventVector *avector;
233                                 listener = aobject->callbacks->listeners + i;
234                                 avector = (SPActionEventVector *) listener->vector;
235                                 if ((listener->size >= sizeof (SPActionEventVector)) && avector->set_sensitive) {
236                                         avector->set_sensitive (action, sensitive, listener->data);
237                                 }
238                         }
239                 }
240         }
244 /**
245  * Change name for all actions that can be taken with the action.
246  */
247 void
248 sp_action_set_name (SPAction *action, Glib::ustring name)
250         nr_return_if_fail (action != NULL);
251         nr_return_if_fail (SP_IS_ACTION (action));
253         NRActiveObject *aobject;
254         g_free(action->name);
255         action->name = g_strdup(name.c_str());
256         aobject = (NRActiveObject *) action;
257         if (aobject->callbacks) {
258             unsigned int i;
259             for (i = 0; i < aobject->callbacks->length; i++) {
260                 NRObjectListener *listener;
261                 SPActionEventVector *avector;
262                 listener = aobject->callbacks->listeners + i;
263                 avector = (SPActionEventVector *) listener->vector;
264                 if ((listener->size >= sizeof (SPActionEventVector)) && avector->set_name) {
265                     avector->set_name (action, name, listener->data);
266                 }
267             }
268         }
274 /**
275  * Return View associated with the action.
276  */
277 Inkscape::UI::View::View *
278 sp_action_get_view (SPAction *action)
280         g_return_val_if_fail (SP_IS_ACTION (action), NULL);
281         return action->view;
284 /*
285   Local Variables:
286   mode:c++
287   c-file-style:"stroustrup"
288   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
289   indent-tabs-mode:nil
290   fill-column:99
291   End:
292 */
293 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :