Code

add document to action events
[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         SPDocument *document = action->view->doc();
135         if (document) {
136             _addProperty(share_static_string("document"), document->serial());
137         }
138         _addProperty(share_static_string("verb"), action->id);
139     }
140 };
144 /**
145         \return   None
146         \brief    Executes an action
147         \param    action   The action to be executed
148         \param    data     Data that is passed into the action.  This depends
149                            on the situation that the action is used in.
151         This function implements the 'action' in SPActions.  It first validates
152         its parameters, making sure it got an action passed in.  Then it
153         turns that action into its parent class of NRActiveObject.  The
154         NRActiveObject allows for listeners to be attached to it.  This
155         function goes through those listeners and calls them with the
156         vector that was attached to the listener.
157 */
158 void
159 sp_action_perform (SPAction *action, void * data)
161         NRActiveObject *aobject;
163         nr_return_if_fail (action != NULL);
164         nr_return_if_fail (SP_IS_ACTION (action));
166         Inkscape::Debug::EventTracker<ActionEvent> tracker(action);
168         aobject = NR_ACTIVE_OBJECT(action);
169         if (aobject->callbacks) {
170                 unsigned int i;
171                 for (i = 0; i < aobject->callbacks->length; i++) {
172                         NRObjectListener *listener;
173                         SPActionEventVector *avector;
175                         listener = &aobject->callbacks->listeners[i];
176                         avector = (SPActionEventVector *) listener->vector;
178                         if ((listener->size >= sizeof (SPActionEventVector)) && avector != NULL && avector->perform != NULL) {
179                                 avector->perform (action, listener->data, data);
180                         }
181                 }
182         }
185 /**
186  * Change activation in all actions that can be taken with the action.
187  */
188 void
189 sp_action_set_active (SPAction *action, unsigned int active)
191         nr_return_if_fail (action != NULL);
192         nr_return_if_fail (SP_IS_ACTION (action));
194         if (active != action->active) {
195                 NRActiveObject *aobject;
196                 action->active = active;
197                 aobject = (NRActiveObject *) action;
198                 if (aobject->callbacks) {
199                         unsigned int i;
200                         for (i = 0; i < aobject->callbacks->length; i++) {
201                                 NRObjectListener *listener;
202                                 SPActionEventVector *avector;
203                                 listener = aobject->callbacks->listeners + i;
204                                 avector = (SPActionEventVector *) listener->vector;
205                                 if ((listener->size >= sizeof (SPActionEventVector)) && avector->set_active) {
206                                         avector->set_active (action, active, listener->data);
207                                 }
208                         }
209                 }
210         }
213 /**
214  * Change sensitivity in all actions that can be taken with the action.
215  */
216 void
217 sp_action_set_sensitive (SPAction *action, unsigned int sensitive)
219         nr_return_if_fail (action != NULL);
220         nr_return_if_fail (SP_IS_ACTION (action));
222         if (sensitive != action->sensitive) {
223                 NRActiveObject *aobject;
224                 action->sensitive = sensitive;
225                 aobject = (NRActiveObject *) action;
226                 if (aobject->callbacks) {
227                         unsigned int i;
228                         for (i = 0; i < aobject->callbacks->length; i++) {
229                                 NRObjectListener *listener;
230                                 SPActionEventVector *avector;
231                                 listener = aobject->callbacks->listeners + i;
232                                 avector = (SPActionEventVector *) listener->vector;
233                                 if ((listener->size >= sizeof (SPActionEventVector)) && avector->set_sensitive) {
234                                         avector->set_sensitive (action, sensitive, listener->data);
235                                 }
236                         }
237                 }
238         }
242 /**
243  * Change name for all actions that can be taken with the action.
244  */
245 void
246 sp_action_set_name (SPAction *action, Glib::ustring name)
248         nr_return_if_fail (action != NULL);
249         nr_return_if_fail (SP_IS_ACTION (action));
251         NRActiveObject *aobject;
252         g_free(action->name);
253         action->name = g_strdup(name.c_str());
254         aobject = (NRActiveObject *) action;
255         if (aobject->callbacks) {
256             unsigned int i;
257             for (i = 0; i < aobject->callbacks->length; i++) {
258                 NRObjectListener *listener;
259                 SPActionEventVector *avector;
260                 listener = aobject->callbacks->listeners + i;
261                 avector = (SPActionEventVector *) listener->vector;
262                 if ((listener->size >= sizeof (SPActionEventVector)) && avector->set_name) {
263                     avector->set_name (action, name, listener->data);
264                 }
265             }
266         }
272 /**
273  * Return View associated with the action.
274  */
275 Inkscape::UI::View::View *
276 sp_action_get_view (SPAction *action)
278         g_return_val_if_fail (SP_IS_ACTION (action), NULL);
279         return action->view;
282 /*
283   Local Variables:
284   mode:c++
285   c-file-style:"stroustrup"
286   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
287   indent-tabs-mode:nil
288   fill-column:99
289   End:
290 */
291 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :