update copyright year
[claws.git] / src / plugins / notification / gtkhotkey / gtk-hotkey-registry.c
1 /*
2  * This file is part of GtkHotkey.
3  * Copyright Mikkel Kamstrup Erlandsen, March, 2008
4  *
5  *   GtkHotkey is free software: you can redistribute it and/or modify
6  *   it under the terms of the GNU Lesser General Public License as published by
7  *   the Free Software Foundation, either version 3 of the License, or
8  *   (at your option) any later version.
9  *
10  *   GtkHotkey is distributed in the hope that it will be useful,
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *   GNU Lesser General Public License for more details.
14  *
15  *   You should have received a copy of the GNU Lesser General Public License
16  *   along with GtkHotkey.  If not, see <http://www.gnu.org/licenses/>.
17  */
18  
19 #include "config.h"
20
21 #include "gtk-hotkey-registry.h"
22 #include "gtk-hotkey-key-file-registry.h"
23
24 enum  {
25         GTK_HOTKEY_REGISTRY_DUMMY_PROPERTY
26 };
27
28 enum {
29         HOTKEY_STORED,
30         HOTKEY_DELETED,
31         
32         LAST_SIGNAL
33 };
34
35 static gpointer         gtk_hotkey_registry_parent_class = NULL;
36
37 static GType            default_registry_type = G_TYPE_INVALID;
38
39 static GtkHotkeyRegistry
40                                         *default_registry = NULL;
41
42 #define DEFAULT_REGISTRY_TYPE GTK_HOTKEY_TYPE_KEY_FILE_REGISTRY
43
44 guint                           storage_signals[LAST_SIGNAL] = { 0 };
45
46 /**
47  * SECTION:gtk-hotkey-registry
48  * @short_description: Abstract base class for services storing and loading hotkeys
49  * @see_also: #GtkHotkeyKeyFileRegistry
50  *
51  * #GtkHotkeyRegistry is an abstract base class for implementing a platform
52  * specific service for storing and loading hotkey configurations.
53  *
54  * The actual binding of the hotkey into the environment is done by a
55  * #GtkHotkeyListener. This class is only meant to do the management part of the
56  * hotkey handling.
57  *
58  * The reasong why applications should use a #GtkHotkeyRegistry and not just a
59  * flat text file with the hotkey signature is to make sure we don't overwrite
60  * or interfere with the hotkeys of other applications. And possibly providing
61  * a unified user interface for managing the hotkeys of all applications.
62  *
63  * To obtain a #GtkHotkeyRegistry matching your desktop environment use
64  * the factory method gtk_hotkey_registry_get_default().
65  *
66  **/    
67
68 /**
69  * gtk_hotkey_registry_get_default
70  * @returns: A reference to a #GtkHotkeyRegistry matching your platform
71  *
72  * Currently the only implementation of this class is #GtkHotkeyKeyFileRegistry.
73  */
74 GtkHotkeyRegistry*
75 gtk_hotkey_registry_get_default (void)
76 {       
77         if (G_UNLIKELY(default_registry == NULL)) {
78                 
79                 /* Set the default type of registry to create */
80                 if (default_registry_type == G_TYPE_INVALID)
81                         default_registry_type = DEFAULT_REGISTRY_TYPE;
82                 
83                 default_registry = GTK_HOTKEY_REGISTRY (g_object_new (GTK_HOTKEY_TYPE_KEY_FILE_REGISTRY,
84                                                                                                                         NULL));
85                 g_return_val_if_fail (GTK_HOTKEY_IS_REGISTRY(default_registry), NULL);
86                 /* We always keep a ref to the registry here */
87         }
88         return g_object_ref(default_registry);
89 }
90
91 /**
92  * gtk_hotkey_registry_get_hotkey
93  * @self: The registry to search in
94  * @app_id: The name under which the application has registered it self
95  *          when it created the #GtkHotkeyInfo in the first place.
96  * @key_id: The id assignedd to the actual hotkey on the moment of its creation
97  * @error: Place to store a #GError in case of errors, or %NULL to ignore
98  * @returns: The #GtkHotkeyInfo for the requested parameters or %NULL is none
99  *           where found. In the case %NULL is returned @error will be set
100  *           accordingly. Free the hotkey with g_object_unref() when you are done
101  *           using it.
102  *
103  * Look up a hotkey given its id and application id.
104  */
105 GtkHotkeyInfo*
106 gtk_hotkey_registry_get_hotkey (GtkHotkeyRegistry        *self,
107                                                            const char           *app_id,
108                                                            const char           *key_id,
109                                                            GError                       **error)
110 {
111         g_return_val_if_fail (GTK_HOTKEY_IS_REGISTRY(self), NULL);
112         return GTK_HOTKEY_REGISTRY_GET_CLASS (self)->get_hotkey (self, app_id, key_id,
113                                                                                                                         error);
114 }
115
116 /**
117  * gtk_hotkey_registry_get_application_hotkeys
118  * @self: The #GtkHotkeyRegistry to look hotkeys up in
119  * @app_id: Unique application id
120  * @error: Place to return a #GError or %NULL
121  * @returns: A list of #GtkHotkeyInfo objects. The list should be with freed with
122  *           g_list_free() and the hotkey objects should be freed with
123  *           g_object_unref().
124  * 
125  * Look up all hotkeys registered by a given application.
126  */
127 GList*
128 gtk_hotkey_registry_get_application_hotkeys (GtkHotkeyRegistry  *self,
129                                                                                         const char                      *app_id,
130                                                                                         GError                          **error)
131 {
132         g_return_val_if_fail (GTK_HOTKEY_IS_REGISTRY(self), NULL);
133         return GTK_HOTKEY_REGISTRY_GET_CLASS (self)->get_application_hotkeys (self, app_id, error);
134 }
135
136 /**
137  * gtk_hotkey_registry_get_all_hotkeys
138  * @self: The #GtkHotkeyRegistry to look hotkeys up in
139  * @returns: A list of all valid #GtkHotkeyInfo<!-- -->s stored in the registry. 
140  *           The list should be with freed with g_list_free() and the hotkey 
141  *           objects should be freed with g_object_unref().
142  * 
143  * Look up all hotkeys registered by a given application.
144  */
145 GList*
146 gtk_hotkey_registry_get_all_hotkeys (GtkHotkeyRegistry  *self)
147 {
148         g_return_val_if_fail (GTK_HOTKEY_IS_REGISTRY(self), NULL);
149         return GTK_HOTKEY_REGISTRY_GET_CLASS (self)->get_all_hotkeys (self);
150 }
151
152 /**
153  * gtk_hotkey_registry_store_hotkey
154  * @self: The #GtkHotkeyRegistry in which to store the hotkey
155  * @info: The #GtkHotkeyInfo to store
156  * @error: Place to return a #GError or %NULL to ignore
157  * @returns: %TRUE on success and %FALS otherwise. In case of errors @error
158  *           will be set accordingly.
159  *           
160  * Store a hotkey in the registry for later usage. In case of success the
161  * #GtkHotkeyRegistry::hotkey-stored signal will be emitted.
162  */
163 gboolean
164 gtk_hotkey_registry_store_hotkey (GtkHotkeyRegistry   *self,
165                                                                  GtkHotkeyInfo          *info,
166                                                                  GError                         **error)
167 {
168         g_return_val_if_fail (GTK_HOTKEY_IS_REGISTRY(self), FALSE);
169         return GTK_HOTKEY_REGISTRY_GET_CLASS (self)->store_hotkey (self, info, error);
170 }
171
172 /**
173  * gtk_hotkey_registry_delete_hotkey
174  * @self: The #GtkHotkeyRegistry from which to delete the hotkey
175  * @app_id: The value of the #GtkHotkeyInfo:application-id property of the stored
176  *          hotkey
177  * @key_id: The value of the #GtkHotkeyInfo:key-id property of the stored hotkey
178  * @error: Place to return a #GError or %NULL to ignore
179  * @returns: %TRUE on success and %FALS otherwise. In case of errors @error
180  *           will be set accordingly.
181  *           
182  * Delete a hotkey from the registry. In case of success the
183  * #GtkHotkeyRegistry::hotkey-deleted signal will be emitted.
184  */
185 gboolean
186 gtk_hotkey_registry_delete_hotkey (GtkHotkeyRegistry    *self,
187                                                                   const gchar           *app_id,
188                                                                   const gchar           *key_id,
189                                                                   GError                        **error)
190 {
191         g_return_val_if_fail (GTK_HOTKEY_IS_REGISTRY(self), FALSE);
192         return GTK_HOTKEY_REGISTRY_GET_CLASS (self)->delete_hotkey (self, app_id,
193                                                                                                                            key_id, error);
194 }
195
196 /**
197  * gtk_hotkey_registry_has_hotkey
198  * @self: The #GtkHotkeyRegistry to look hotkeys up in
199  * @app_id: The value of the #GtkHotkeyInfo:application-id property of the stored
200  *          hotkey
201  * @key_id: The value of the #GtkHotkeyInfo:key-id property of the stored hotkey
202  * @returns: %TRUE if the registry has stored a hotkey with with application id
203  *           @app_id and hotkey id @key_id.
204  * 
205  * Look up all hotkeys registered by a given application.
206  */
207 gboolean
208 gtk_hotkey_registry_has_hotkey (GtkHotkeyRegistry               *self,
209                                                            const gchar                  *app_id,
210                                                            const gchar                  *key_id)
211 {
212         g_return_val_if_fail (GTK_HOTKEY_IS_REGISTRY(self), FALSE);
213         return GTK_HOTKEY_REGISTRY_GET_CLASS (self)->has_hotkey (self, app_id, key_id);
214 }
215
216 /**
217  * gtk_hotkey_registry_hotkey_stored
218  * @self: The #GtkHotkeyRegistry to emit the signal on
219  * @info: The #GtkHotkeyInfo that was stored
220  * 
221  * Emit the #GtkHotkeyRegistry::hotkey-stored signal on @self. This method should
222  * only be used by child classes of #GtkHotkeyRegistry.
223  */
224 void
225 gtk_hotkey_registry_hotkey_stored (GtkHotkeyRegistry    *self,
226                                                                  GtkHotkeyInfo          *info)
227 {
228         g_return_if_fail (GTK_HOTKEY_IS_REGISTRY(self));
229         g_return_if_fail (GTK_HOTKEY_IS_INFO(info));
230         
231         GTK_HOTKEY_REGISTRY_GET_CLASS (self)->hotkey_stored (self, info);
232 }
233
234 /**
235  * gtk_hotkey_registry_hotkey_deleted
236  * @self: The #GtkHotkeyRegistry to emit the signal on
237  * @info: The #GtkHotkeyInfo that was deleted
238  * 
239  * Emit the #GtkHotkeyRegistry::hotkey-deleted signal on @self. This method should
240  * only be used by child classes of #GtkHotkeyRegistry.
241  */
242 void
243 gtk_hotkey_registry_hotkey_deleted (GtkHotkeyRegistry           *self,
244                                                                    GtkHotkeyInfo                *info)
245 {
246         g_return_if_fail (GTK_HOTKEY_IS_REGISTRY(self));
247         GTK_HOTKEY_REGISTRY_GET_CLASS (self)->hotkey_deleted (self, info);
248 }
249
250 static void
251 gtk_hotkey_registry_hotkey_stored_real (GtkHotkeyRegistry       *self,
252                                                                            GtkHotkeyInfo        *info)
253 {
254         g_return_if_fail (GTK_HOTKEY_IS_INFO(info));
255         g_return_if_fail (GTK_HOTKEY_IS_REGISTRY(self));
256         
257         g_signal_emit (self, storage_signals[HOTKEY_STORED], 0, info);
258 }
259
260 static void
261 gtk_hotkey_registry_hotkey_deleted_real (GtkHotkeyRegistry      *self,
262                                                                                 GtkHotkeyInfo           *info)
263 {
264         g_return_if_fail (GTK_HOTKEY_IS_INFO(info));
265         g_return_if_fail (GTK_HOTKEY_IS_REGISTRY(self));
266         
267         g_signal_emit (self, storage_signals[HOTKEY_DELETED], 0, info);
268 }
269
270 static void
271 gtk_hotkey_registry_class_init (GtkHotkeyRegistryClass *klass)
272 {
273         gtk_hotkey_registry_parent_class = g_type_class_peek_parent (klass);
274         
275         klass->hotkey_stored = gtk_hotkey_registry_hotkey_stored_real;
276         klass->hotkey_deleted = gtk_hotkey_registry_hotkey_deleted_real;
277         
278         /**
279          * GtkHotkeyRegistry::hotkey-stored
280          * @hotkey:The hotkey that was stored
281          *
282          * Emitted when a hotkey has been stored in the registry
283          */
284         storage_signals[HOTKEY_STORED] = \
285         g_signal_new ("hotkey_stored",
286                                   GTK_HOTKEY_TYPE_STORAGE,
287                                   G_SIGNAL_RUN_LAST,
288                                   0, NULL, NULL,
289                                   g_cclosure_marshal_VOID__OBJECT,
290                                   G_TYPE_NONE, 1,
291                                   G_TYPE_OBJECT);
292         
293         /**
294          * GtkHotkeyRegistry::hotkey-deleted
295          * @hotkey:The hotkey that was deleted
296          *
297          * Emitted when a hotkey has been deleted from the registry
298          */
299         storage_signals[HOTKEY_DELETED] = \
300         g_signal_new ("hotkey_deleted",
301                                   GTK_HOTKEY_TYPE_STORAGE,
302                                   G_SIGNAL_RUN_LAST,
303                                   0, NULL, NULL,
304                                   g_cclosure_marshal_VOID__OBJECT,
305                                   G_TYPE_NONE, 1,
306                                   G_TYPE_OBJECT);
307 }
308
309
310 static void
311 gtk_hotkey_registry_init (GtkHotkeyRegistry * self)
312 {
313         
314 }
315
316 static void
317 gtk_hotkey_registry_finalize (GtkHotkeyRegistry * self)
318 {
319         
320 }
321
322 GType
323 gtk_hotkey_registry_get_type (void)
324 {
325         static GType gtk_hotkey_registry_type_id = 0;
326         
327         if (G_UNLIKELY (gtk_hotkey_registry_type_id == 0)) {
328                 static const GTypeInfo g_define_type_info = {
329                         sizeof (GtkHotkeyRegistryClass),
330                         (GBaseInitFunc) gtk_hotkey_registry_init,
331                         (GBaseFinalizeFunc) gtk_hotkey_registry_finalize,
332                         (GClassInitFunc) gtk_hotkey_registry_class_init,
333                         (GClassFinalizeFunc) NULL,
334                         NULL,
335                         sizeof (GtkHotkeyRegistry),
336                         0,
337                         (GInstanceInitFunc) gtk_hotkey_registry_init,
338                         (const GTypeValueTable *) NULL  /* value table */
339                 };
340                 
341                 gtk_hotkey_registry_type_id = g_type_register_static (G_TYPE_OBJECT, "GtkHotkeyRegistry", &g_define_type_info, G_TYPE_FLAG_ABSTRACT);
342         }
343         return gtk_hotkey_registry_type_id;
344 }