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 "helper/action.h"
18 static void sp_action_class_init (SPActionClass *klass);
19 static void sp_action_init (SPAction *action);
20 static void sp_action_finalize (NRObject *object);
22 static NRActiveObjectClass *parent_class;
24 /**
25 * Register SPAction class and return its type.
26 */
27 NRType
28 sp_action_get_type (void)
29 {
30 static unsigned int type = 0;
31 if (!type) {
32 type = nr_object_register_type (NR_TYPE_ACTIVE_OBJECT,
33 "SPAction",
34 sizeof (SPActionClass),
35 sizeof (SPAction),
36 (void (*) (NRObjectClass *)) sp_action_class_init,
37 (void (*) (NRObject *)) sp_action_init);
38 }
39 return type;
40 }
42 /**
43 * SPAction vtable initialization.
44 */
45 static void
46 sp_action_class_init (SPActionClass *klass)
47 {
48 NRObjectClass * object_class;
50 object_class = (NRObjectClass *) klass;
52 parent_class = (NRActiveObjectClass *) (((NRObjectClass *) klass)->parent);
54 object_class->finalize = sp_action_finalize;
55 object_class->cpp_ctor = NRObject::invoke_ctor<SPAction>;
56 }
58 /**
59 * Callback for SPAction object initialization.
60 */
61 static void
62 sp_action_init (SPAction *action)
63 {
64 action->sensitive = 0;
65 action->active = 0;
66 action->view = NULL;
67 action->id = action->name = action->tip = NULL;
68 action->image = NULL;
69 }
71 /**
72 * Called before SPAction object destruction.
73 */
74 static void
75 sp_action_finalize (NRObject *object)
76 {
77 SPAction *action;
79 action = (SPAction *) object;
81 if (action->image) free (action->image);
82 if (action->tip) free (action->tip);
83 if (action->name) free (action->name);
84 if (action->id) free (action->id);
86 ((NRObjectClass *) (parent_class))->finalize (object);
87 }
89 /**
90 * Create new SPAction object and set its properties.
91 */
92 SPAction *
93 sp_action_new(Inkscape::UI::View::View *view,
94 const gchar *id,
95 const gchar *name,
96 const gchar *tip,
97 const gchar *image,
98 Inkscape::Verb * verb)
99 {
100 SPAction *action = (SPAction *)nr_object_new(SP_TYPE_ACTION);
102 action->view = view;
103 action->sensitive = TRUE;
104 if (id) action->id = strdup (id);
105 if (name) action->name = strdup (name);
106 if (tip) action->tip = strdup (tip);
107 if (image) action->image = strdup (image);
108 action->verb = verb;
110 return action;
111 }
113 /**
114 \return None
115 \brief Executes an action
116 \param action The action to be executed
117 \param data Data that is passed into the action. This depends
118 on the situation that the action is used in.
120 This function implements the 'action' in SPActions. It first validates
121 its parameters, making sure it got an action passed in. Then it
122 turns that action into its parent class of NRActiveObject. The
123 NRActiveObject allows for listeners to be attached to it. This
124 function goes through those listeners and calls them with the
125 vector that was attached to the listener.
126 */
127 void
128 sp_action_perform (SPAction *action, void * data)
129 {
130 NRActiveObject *aobject;
132 nr_return_if_fail (action != NULL);
133 nr_return_if_fail (SP_IS_ACTION (action));
135 aobject = NR_ACTIVE_OBJECT(action);
136 if (aobject->callbacks) {
137 unsigned int i;
138 for (i = 0; i < aobject->callbacks->length; i++) {
139 NRObjectListener *listener;
140 SPActionEventVector *avector;
142 listener = &aobject->callbacks->listeners[i];
143 avector = (SPActionEventVector *) listener->vector;
145 if ((listener->size >= sizeof (SPActionEventVector)) && avector != NULL && avector->perform != NULL) {
146 avector->perform (action, listener->data, data);
147 }
148 }
149 }
150 }
152 /**
153 * Change activation in all actions that can be taken with the action.
154 */
155 void
156 sp_action_set_active (SPAction *action, unsigned int active)
157 {
158 nr_return_if_fail (action != NULL);
159 nr_return_if_fail (SP_IS_ACTION (action));
161 if (active != action->active) {
162 NRActiveObject *aobject;
163 action->active = active;
164 aobject = (NRActiveObject *) action;
165 if (aobject->callbacks) {
166 unsigned int i;
167 for (i = 0; i < aobject->callbacks->length; i++) {
168 NRObjectListener *listener;
169 SPActionEventVector *avector;
170 listener = aobject->callbacks->listeners + i;
171 avector = (SPActionEventVector *) listener->vector;
172 if ((listener->size >= sizeof (SPActionEventVector)) && avector->set_active) {
173 avector->set_active (action, active, listener->data);
174 }
175 }
176 }
177 }
178 }
180 /**
181 * Change sensitivity in all actions that can be taken with the action.
182 */
183 void
184 sp_action_set_sensitive (SPAction *action, unsigned int sensitive)
185 {
186 nr_return_if_fail (action != NULL);
187 nr_return_if_fail (SP_IS_ACTION (action));
189 if (sensitive != action->sensitive) {
190 NRActiveObject *aobject;
191 action->sensitive = sensitive;
192 aobject = (NRActiveObject *) action;
193 if (aobject->callbacks) {
194 unsigned int i;
195 for (i = 0; i < aobject->callbacks->length; i++) {
196 NRObjectListener *listener;
197 SPActionEventVector *avector;
198 listener = aobject->callbacks->listeners + i;
199 avector = (SPActionEventVector *) listener->vector;
200 if ((listener->size >= sizeof (SPActionEventVector)) && avector->set_sensitive) {
201 avector->set_sensitive (action, sensitive, listener->data);
202 }
203 }
204 }
205 }
206 }
209 /**
210 * Change name for all actions that can be taken with the action.
211 */
212 void
213 sp_action_set_name (SPAction *action, Glib::ustring name)
214 {
215 nr_return_if_fail (action != NULL);
216 nr_return_if_fail (SP_IS_ACTION (action));
218 NRActiveObject *aobject;
219 g_free(action->name);
220 action->name = g_strdup(name.c_str());
221 aobject = (NRActiveObject *) action;
222 if (aobject->callbacks) {
223 unsigned int i;
224 for (i = 0; i < aobject->callbacks->length; i++) {
225 NRObjectListener *listener;
226 SPActionEventVector *avector;
227 listener = aobject->callbacks->listeners + i;
228 avector = (SPActionEventVector *) listener->vector;
229 if ((listener->size >= sizeof (SPActionEventVector)) && avector->set_name) {
230 avector->set_name (action, name, listener->data);
231 }
232 }
233 }
234 }
239 /**
240 * Return View associated with the action.
241 */
242 Inkscape::UI::View::View *
243 sp_action_get_view (SPAction *action)
244 {
245 g_return_val_if_fail (SP_IS_ACTION (action), NULL);
246 return action->view;
247 }
249 /*
250 Local Variables:
251 mode:c++
252 c-file-style:"stroustrup"
253 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
254 indent-tabs-mode:nil
255 fill-column:99
256 End:
257 */
258 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :