Added scrolled window
[irreco.git] / irreco / src / core / irreco_cmd_chain_manager.c
blobd1425ff0e4cb48e65d77e6e310487561f59fa3d6
1 /*
2 * irreco - Ir Remote Control
3 * Copyright (C) 2007 Arto Karppinen (arto.karppinen@iki.fi)
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program 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 General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "irreco_cmd_chain_manager.h"
21 #include "irreco_config.h"
23 /**
24 * @addtogroup IrrecoCmdChainManager
25 * @ingroup Irreco
27 * A class for storing IrrecoCmdChains assosiated with buttons and hardkeys.
29 * - Stores an array of IrrecoCmdChains
30 * - Can save command chains to file.
31 * - Can read command chains from file.
33 * @{
36 /**
37 * @file
38 * Source file of @ref IrrecoCmdChainManager.
43 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
44 /* Prototypes */
45 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
47 typedef struct _IrrecoChainFindData IrrecoChainFindData;
48 struct _IrrecoChainFindData {
49 gpointer value;
50 gpointer key;
53 static gboolean irreco_cmd_chain_manager_free_foreach(gpointer key,
54 gpointer value,
55 gpointer user_data);
56 static gboolean irreco_cmd_chain_manager_find_chain_foreach(gpointer key,
57 gpointer value,
58 gpointer user_data);
59 static void irreco_cmd_chain_manager_to_config_foreach(gpointer key,
60 gpointer value,
61 gpointer user_data);
65 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
66 /* Construction & Destruction */
67 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
69 /**
70 * @name Construction & Destruction
71 * @{
74 IrrecoCmdChainManager *irreco_cmd_chain_manager_new()
76 IrrecoCmdChainManager *self;
77 IRRECO_ENTER
79 self = g_slice_new0(IrrecoCmdChainManager);
80 self->table = g_hash_table_new(NULL, NULL);
81 IRRECO_RETURN_PTR(self);
84 void irreco_cmd_chain_manager_free(IrrecoCmdChainManager *self)
86 IRRECO_ENTER
87 if (g_hash_table_size(self->table)) {
88 IRRECO_DEBUG("Hashtable is not empty. Something does not "
89 "properly free IrrecoCmdChains.\n");
92 g_hash_table_foreach_remove(self->table,
93 irreco_cmd_chain_manager_free_foreach,
94 NULL);
95 g_hash_table_destroy(self->table);
96 g_slice_free(IrrecoCmdChainManager, self);
97 IRRECO_RETURN
99 static gboolean irreco_cmd_chain_manager_free_foreach(gpointer key,
100 gpointer value,
101 gpointer user_data)
103 IRRECO_PRINTF("Destroying command chain with id \"%i\".\n",
104 (IrrecoCmdChainId) key);
105 irreco_cmd_chain_destroy((IrrecoCmdChain *) value);
106 return TRUE;
109 /** @} */
113 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
114 /* Private Functions */
115 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
118 * @name Private Functions
119 * @{
122 static IrrecoCmdChainId
123 irreco_cmd_chain_manager_find_empty_index(IrrecoCmdChainManager *self)
125 IrrecoCmdChainId i = 1;
126 IRRECO_ENTER
128 while (g_hash_table_lookup(self->table, (gconstpointer) i)) i++;
129 IRRECO_RETURN_INT(i);
134 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
135 /* Public Functions */
136 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
139 * @name Public Functions
140 * @{
144 * Create a new IrrecoCmdChain and assign an id for it.
146 IrrecoCmdChainId irreco_cmd_chain_manager_new_chain(IrrecoCmdChainManager *self)
148 IrrecoCmdChainId id;
149 IrrecoCmdChain *chain;
150 IRRECO_ENTER
152 id = irreco_cmd_chain_manager_find_empty_index(self);
153 chain = irreco_cmd_chain_create();
154 irreco_cmd_chain_set_id(chain, id);
155 g_hash_table_insert(self->table, (gpointer) id, chain);
156 IRRECO_RETURN_INT(id);
160 * Create a new command chain and assosiate it with the given id, if it does
161 * not already exists.
163 * @return TRUE if created, FALSE if already exists.
165 gboolean irreco_cmd_chain_manager_new_chain_with_id(IrrecoCmdChainManager *self,
166 IrrecoCmdChainId id)
168 IrrecoCmdChain *chain;
169 IRRECO_ENTER
171 if (g_hash_table_lookup(self->table, (gpointer) id)) {
172 IRRECO_DEBUG("Comman chain with id \"%i\" "
173 "already exists.\n", id);
174 IRRECO_RETURN_BOOL(FALSE);
177 chain = irreco_cmd_chain_create();
178 irreco_cmd_chain_set_id(chain, id);
179 g_hash_table_insert(self->table, (gpointer) id, chain);
180 IRRECO_RETURN_BOOL(TRUE);
183 void irreco_cmd_chain_manager_free_chain(IrrecoCmdChainManager *self,
184 IrrecoCmdChainId id)
186 IRRECO_ENTER
187 g_hash_table_remove(self->table, (gpointer) id);
188 IRRECO_RETURN
192 * Get chain.
194 * Returns: IrrecoCmdChain pointer or NULL.
196 IrrecoCmdChain *irreco_cmd_chain_manager_get_chain(IrrecoCmdChainManager *self,
197 IrrecoCmdChainId id)
199 IRRECO_ENTER
200 IRRECO_RETURN_PTR(g_hash_table_lookup(self->table, (gpointer) id));
204 * Find IrrecoCmdChainId that corresponds to IrrecoCmdChain pointer.
206 IrrecoCmdChainId irreco_cmd_chain_manager_find_chain(IrrecoCmdChainManager *self,
207 IrrecoCmdChain *chain)
209 IrrecoChainFindData find_data;
210 IRRECO_ENTER
212 if (g_hash_table_find(self->table,
213 irreco_cmd_chain_manager_find_chain_foreach,
214 &find_data)) {
215 IRRECO_RETURN_INT((IrrecoCmdChainId) find_data.key);
217 IRRECO_RETURN_INT(0);
219 static gboolean irreco_cmd_chain_manager_find_chain_foreach(gpointer key,
220 gpointer value,
221 gpointer user_data)
223 IrrecoChainFindData *find_data = (IrrecoChainFindData *) user_data;
224 if (find_data->value != value) return FALSE;
225 find_data->key = key;
226 return TRUE;
230 * Save command chains to disk.
232 gboolean irreco_cmd_chain_manager_to_config(IrrecoCmdChainManager *self)
234 GKeyFile *keyfile;
235 gboolean success;
236 IRRECO_ENTER
238 keyfile = g_key_file_new();
239 g_hash_table_foreach(self->table,
240 irreco_cmd_chain_manager_to_config_foreach,
241 keyfile);
242 success = irreco_gkeyfile_write_to_config_file(
243 keyfile, "irreco", irreco_config_cmd_chain_file);
244 g_key_file_free(keyfile);
245 IRRECO_RETURN_BOOL(success);
247 static void irreco_cmd_chain_manager_to_config_foreach(gpointer key,
248 gpointer value,
249 gpointer user_data)
251 GKeyFile *keyfile = (GKeyFile *) user_data;
252 IrrecoCmdChain *chain = (IrrecoCmdChain *) value;
253 IrrecoCmdChainId id = (IrrecoCmdChainId) key;
254 IRRECO_ENTER
256 irreco_cmd_chain_set_id(chain, id);
257 irreco_cmd_chain_to_config(chain, keyfile);
258 IRRECO_RETURN
262 * Read command chains from disk.
264 gboolean irreco_cmd_chain_manager_from_config(IrrecoData *irreco_data)
266 IrrecoCmdChainManager *self = irreco_data->cmd_chain_manager;
267 guint i;
268 IrrecoKeyFile *keyfile = NULL;
269 gchar *config_dir = NULL;
270 gchar *config_file = NULL;
271 gchar** groups = NULL;
272 gsize group_count = 0;
273 IRRECO_ENTER
275 /* Read config file into IrrecoKeyFile. */
276 config_dir = irreco_get_config_dir("irreco");
277 config_file = irreco_get_config_file(
278 "irreco", irreco_config_cmd_chain_file);
279 keyfile = irreco_keyfile_create(config_dir, config_file, NULL);
280 if (config_dir == NULL || config_file == NULL || keyfile == NULL) {
281 g_free(config_dir);
282 g_free(config_file);
283 irreco_keyfile_destroy(keyfile);
284 IRRECO_RETURN_BOOL(FALSE);
287 /* Get list of groups from. */
288 IRRECO_PRINTF("Reading layout configuration file \"%s\"\n",
289 config_file);
290 groups = g_key_file_get_groups(keyfile->keyfile, &group_count);
292 /* Read layouts. */
293 for (i = 0; i < group_count; i++) {
294 const gchar *group = groups[i];
295 IrrecoCmdChain *chain = NULL;
296 IrrecoCmdChain *id_chain = NULL;
298 /* Read only command chain groups. */
299 if (!g_str_has_prefix(group, "chain-") ||
300 g_strrstr(group, ":") != NULL) continue;
302 /* Read command chain from keyfile. */
303 irreco_keyfile_set_group(keyfile, group);
304 chain = irreco_cmd_chain_new_from_config(keyfile, irreco_data);
307 * Copy chain into ID-mapped chain.
308 * @todo Rework this so that there is no need to copy chains.
310 irreco_cmd_chain_manager_new_chain_with_id(
311 self, irreco_cmd_chain_get_id(chain));
312 id_chain = irreco_cmd_chain_manager_get_chain(
313 self, irreco_cmd_chain_get_id(chain));
314 irreco_cmd_chain_copy(chain, id_chain);
315 irreco_cmd_chain_free(chain);
318 g_strfreev(groups);
319 irreco_keyfile_destroy(keyfile);
320 g_free(config_dir);
321 g_free(config_file);
322 IRRECO_RETURN_BOOL(TRUE);
325 /** @} */
327 /** @} */