Clean code
[irreco.git] / irreco / src / core / irreco_webdb_dlg.c
blob0f0d05f8bba60cd1d626703fd3a96f6bb41494d5
1 /*
2 * irreco - Ir Remote Control
3 * Copyright (C) 2007,2008 Arto Karppinen (arto.karppinen@iki.fi),
4 * Joni Kokko (t5kojo01@students.oamk.fi),
5 * Harri Vattulainen (t5vaha01@students.oamk.fi)
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #include "irreco_webdb_dlg.h"
23 #include <hildon/hildon-banner.h>
24 #include "irreco_webdb_register_dlg.h"
25 #include "irreco_select_instance_dlg.h"
26 #include "irreco_config.h"
29 /**
30 * @addtogroup IrrecoWebdbDlg
31 * @ingroup Irreco
33 * @todo PURPOCE OF CLASS.
35 * @{
38 /**
39 * @file
40 * Source file of @ref IrrecoWebdbDlg.
44 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
45 /* Prototypes */
46 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
47 static void irreco_webdb_dlg_clean_details(IrrecoWebdbDlg *self);
48 static gboolean irreco_webdb_dlg_loader_categ(IrrecoWebdbDlg *self);
49 static gboolean irreco_webdb_dlg_loader_manuf(IrrecoWebdbDlg *self);
50 static gboolean irreco_webdb_dlg_loader_model(IrrecoWebdbDlg *self);
51 static gboolean irreco_webdb_dlg_loader_config(IrrecoWebdbDlg *self);
52 static gboolean irreco_webdb_dlg_display_config_detail(IrrecoWebdbDlg *self,
53 GtkTreeIter * iter);
54 static gboolean irreco_webdb_dlg_load_file(IrrecoWebdbDlg *self);
56 static gboolean irreco_show_webdb_dlg_map_event(IrrecoWebdbDlg *self,
57 GdkEvent *event,
58 gpointer user_data);
59 static void irreco_show_webdb_dlg_destroy_event(IrrecoWebdbDlg *self,
60 gpointer user_data);
61 static void irreco_show_webdb_dlg_row_activated_event(GtkTreeView *tree_view,
62 GtkTreePath *path,
63 GtkTreeViewColumn *column,
64 IrrecoWebdbDlg *self);
65 static void irreco_show_webdb_dlg_row_expanded_event(GtkTreeView *tree_view,
66 GtkTreeIter *iter,
67 GtkTreePath *path,
68 IrrecoWebdbDlg *self);
69 static void irreco_show_webdb_dlg_row_collapsed_event(GtkTreeView *tree_view,
70 GtkTreeIter *iter,
71 GtkTreePath *path,
72 IrrecoWebdbDlg *self);
73 static void irreco_show_webdb_dlg_row_selected_event(GtkTreeSelection *sel,
74 IrrecoWebdbDlg *self);
79 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
80 /* Datatypes */
81 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
83 /** Button responce codes. */
84 enum {
85 IRRECO_DEVICE_REFRESH
88 /** GtkTreeStore colums. */
89 enum
91 TEXT_COL,
92 FLAG_COL,
93 DATA_COL,
94 N_COLUMNS
97 /** Loader states. */
98 enum
100 LOADER_STATE_INIT,
101 LOADER_STATE_LOOP,
102 LOADER_STATE_END,
103 LOADER_STATE_CLEANUP
106 /** Row flags. */
107 enum
109 ROW_CHILDREN_LOADED = 1 << 1,
110 ROW_TYPE_CATEGORY = 1 << 2,
111 ROW_TYPE_MANUFACTURER = 1 << 3,
112 ROW_TYPE_MODEL = 1 << 4,
113 ROW_TYPE_CONFIG = 1 << 5,
114 ROW_TYPE_LOADING = 1 << 6
119 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
120 /* Construction & Destruction */
121 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
124 * @name Construction & Destruction
125 * @{
128 G_DEFINE_TYPE(IrrecoWebdbDlg, irreco_webdb_dlg, IRRECO_TYPE_DLG)
130 static void irreco_webdb_dlg_finalize(GObject *object)
132 if (G_OBJECT_CLASS(irreco_webdb_dlg_parent_class)->finalize)
133 G_OBJECT_CLASS(irreco_webdb_dlg_parent_class)->finalize(object);
136 static void irreco_webdb_dlg_class_init(IrrecoWebdbDlgClass *klass)
138 GObjectClass *object_class = G_OBJECT_CLASS(klass);
139 object_class->finalize = irreco_webdb_dlg_finalize;
142 static void irreco_webdb_dlg_init(IrrecoWebdbDlg *self)
144 GtkTreeViewColumn *column;
145 GtkCellRenderer *renderer;
146 GtkTreeSelection *select;
147 GtkWidget *label_user;
148 GtkWidget *label_backend;
149 GtkWidget *label_category;
150 GtkWidget *label_manuf;
151 GtkWidget *label_model;
152 GtkWidget *label_file_uploaded;
153 GtkWidget *label_file_download_count;
154 GtkWidget *config_info_alignment;
155 GtkWidget *config_info_frame;
156 GtkWidget *tree_view_frame;
157 GtkWidget *tree_view_hbox;
159 IRRECO_ENTER
161 /* Construct dialog. */
162 gtk_window_set_title(GTK_WINDOW(self),
163 _("Download device from Irreco Database"));
164 gtk_window_set_modal(GTK_WINDOW(self), TRUE);
165 gtk_window_set_destroy_with_parent(GTK_WINDOW(self), TRUE);
166 gtk_dialog_set_has_separator(GTK_DIALOG(self), FALSE);
167 gtk_dialog_add_buttons(GTK_DIALOG(self),
168 GTK_STOCK_REFRESH, IRRECO_DEVICE_REFRESH,
169 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
170 GTK_STOCK_OK, GTK_RESPONSE_OK,
171 NULL);
172 /* Create hbox */
173 self->hbox = g_object_new(GTK_TYPE_HBOX, NULL);
174 gtk_box_set_spacing(GTK_BOX(self->hbox), 8);
175 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(self)->vbox),
176 irreco_gtk_align(GTK_WIDGET(self->hbox),
177 0, 0, 1, 1, 8, 8, 8, 8));
178 /* Create tree_view_hbox */
179 tree_view_hbox = g_object_new(GTK_TYPE_HBOX, NULL);
181 /* Create Treeview */
182 self->tree_store = gtk_tree_store_new(
183 N_COLUMNS, G_TYPE_STRING, G_TYPE_INT, G_TYPE_POINTER);
184 self->tree_view = GTK_TREE_VIEW(gtk_tree_view_new_with_model(
185 GTK_TREE_MODEL(self->tree_store)));
187 renderer = gtk_cell_renderer_text_new();
188 column = gtk_tree_view_column_new_with_attributes(
189 NULL, renderer, "text", TEXT_COL, NULL);
190 gtk_tree_view_append_column(self->tree_view, column);
192 gtk_box_pack_start(GTK_BOX(tree_view_hbox), GTK_WIDGET(self->tree_view),
193 TRUE, TRUE, 0);
195 /* Create scrollbar for Treeview */
196 self->scrollbar = gtk_vscrollbar_new(gtk_tree_view_get_vadjustment(
197 GTK_TREE_VIEW(self->tree_view)));
198 gtk_box_pack_start(GTK_BOX(tree_view_hbox), GTK_WIDGET(self->scrollbar),
199 FALSE, TRUE, 0);
201 /* Create Frame for Treeview */
202 tree_view_frame = gtk_frame_new("");
203 gtk_frame_set_label_widget(GTK_FRAME(tree_view_frame),
204 irreco_gtk_label_bold("Devices", 0, 0, 0, 0, 0, 0));
206 gtk_container_add(GTK_CONTAINER(tree_view_frame),
207 GTK_WIDGET(tree_view_hbox));
209 gtk_box_pack_start(GTK_BOX(self->hbox), GTK_WIDGET(tree_view_frame),
210 TRUE, TRUE, 0);
212 /* Create config_info */
213 self->config_info = gtk_table_new(7, 2, FALSE);
214 gtk_table_set_row_spacings(GTK_TABLE(self->config_info), 4);
216 label_user = gtk_label_new("Creator: ");
217 gtk_misc_set_alignment(GTK_MISC(label_user), 0, 0.5);
218 gtk_table_attach_defaults(GTK_TABLE(self->config_info),
219 label_user, 0, 1, 0, 1);
221 label_backend = gtk_label_new("Backend: ");
222 gtk_misc_set_alignment(GTK_MISC(label_backend), 0, 0.5);
223 gtk_table_attach_defaults(GTK_TABLE(self->config_info),
224 label_backend, 0, 1, 1, 2);
226 label_category = gtk_label_new("Category: ");
227 gtk_misc_set_alignment(GTK_MISC(label_category), 0, 0.5);
228 gtk_table_attach_defaults(GTK_TABLE(self->config_info),
229 label_category, 0, 1, 2, 3);
231 label_manuf = gtk_label_new("Manufacturer: ");
232 gtk_misc_set_alignment(GTK_MISC(label_manuf), 0, 0.5);
233 gtk_table_attach_defaults(GTK_TABLE(self->config_info),
234 label_manuf, 0, 1, 3, 4);
236 label_model = gtk_label_new("Model: ");
237 gtk_misc_set_alignment(GTK_MISC(label_model), 0, 0.5);
238 gtk_table_attach_defaults(GTK_TABLE(self->config_info),
239 label_model, 0, 1, 4, 5);
241 label_file_uploaded = gtk_label_new("Created: ");
242 gtk_misc_set_alignment(GTK_MISC(label_file_uploaded), 0, 0.5);
243 gtk_table_attach_defaults(GTK_TABLE(self->config_info),
244 label_file_uploaded, 0, 1, 5, 6);
246 label_file_download_count = gtk_label_new("Downloaded: ");
247 gtk_misc_set_alignment(GTK_MISC(label_file_download_count), 0, 0.5);
248 gtk_table_attach_defaults(GTK_TABLE(self->config_info),
249 label_file_download_count, 0, 1, 6, 7);
251 self->config_user = gtk_label_new("-");
252 gtk_misc_set_alignment(GTK_MISC(self->config_user), 0, 0.5);
253 gtk_table_attach(GTK_TABLE(self->config_info), self->config_user,
254 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
256 self->config_backend = gtk_label_new("-");
257 gtk_misc_set_alignment(GTK_MISC(self->config_backend), 0, 0.5);
258 gtk_table_attach(GTK_TABLE(self->config_info), self->config_backend,
259 1, 2, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
261 self->config_category = gtk_label_new("-");
262 gtk_misc_set_alignment(GTK_MISC(self->config_category), 0, 0.5);
263 gtk_table_attach(GTK_TABLE(self->config_info), self->config_category,
264 1, 2, 2, 3, GTK_FILL, GTK_FILL, 0, 0);
266 self->config_manuf = gtk_label_new("-");
267 gtk_misc_set_alignment(GTK_MISC(self->config_manuf), 0, 0.5);
268 gtk_table_attach(GTK_TABLE(self->config_info), self->config_manuf,
269 1, 2, 3, 4, GTK_FILL, GTK_FILL, 0, 0);
271 self->config_model = gtk_label_new("-");
272 gtk_misc_set_alignment(GTK_MISC(self->config_model), 0, 0.5);
273 gtk_table_attach(GTK_TABLE(self->config_info), self->config_model,
274 1, 2, 4, 5, GTK_FILL, GTK_FILL, 0, 0);
276 self->config_uploaded = gtk_label_new("-");
277 gtk_misc_set_alignment(GTK_MISC(self->config_uploaded), 0, 0.5);
278 gtk_table_attach(GTK_TABLE(self->config_info),
279 self->config_uploaded,
280 1, 2, 5, 6, GTK_FILL, GTK_FILL, 0, 0);
282 self->config_download_count = gtk_label_new("-");
283 gtk_misc_set_alignment(GTK_MISC(self->config_download_count), 0, 0.5);
284 gtk_table_attach(GTK_TABLE(self->config_info),
285 self->config_download_count,
286 1, 2, 6, 7, GTK_FILL, GTK_FILL, 0, 0);
288 /* Create frame for config_info */
289 config_info_frame = gtk_frame_new("");
290 gtk_frame_set_label_widget(GTK_FRAME(config_info_frame),
291 irreco_gtk_label_bold("Details", 0, 0, 0, 0, 0, 0));
293 gtk_box_pack_start(GTK_BOX(self->hbox),
294 GTK_WIDGET(config_info_frame),
295 FALSE, TRUE, 0);
297 config_info_alignment = gtk_alignment_new(0, 0, 0, 0);
298 gtk_alignment_set_padding(GTK_ALIGNMENT(config_info_alignment),
299 0, 8, 8, 8);
300 gtk_container_add(GTK_CONTAINER(config_info_frame),
301 GTK_WIDGET(config_info_alignment));
303 gtk_container_add(GTK_CONTAINER(config_info_alignment),
304 GTK_WIDGET(self->config_info));
306 /* Setup the selection handler for TREE */
307 select = gtk_tree_view_get_selection(self->tree_view);
308 gtk_tree_selection_set_mode(select, GTK_SELECTION_SINGLE);
310 /* Signal handlers. */
311 g_signal_connect(G_OBJECT(self), "map-event",
312 G_CALLBACK(irreco_show_webdb_dlg_map_event), NULL);
313 g_signal_connect(G_OBJECT(self), "destroy",
314 G_CALLBACK(irreco_show_webdb_dlg_destroy_event), NULL);
315 g_signal_connect(G_OBJECT(self->tree_view), "row-activated",
316 G_CALLBACK(irreco_show_webdb_dlg_row_activated_event),
317 self);
318 g_signal_connect(G_OBJECT(self->tree_view), "row-expanded",
319 G_CALLBACK(irreco_show_webdb_dlg_row_expanded_event),
320 self);
321 g_signal_connect(G_OBJECT(self->tree_view), "row-collapsed",
322 G_CALLBACK(irreco_show_webdb_dlg_row_collapsed_event),
323 self);
324 g_signal_connect(G_OBJECT (select), "changed",
325 G_CALLBACK (irreco_show_webdb_dlg_row_selected_event),
326 self);
329 gtk_tree_view_set_enable_tree_lines(self->tree_view, TRUE);
330 g_object_set (G_OBJECT (self->tree_view), "show-expanders", TRUE, NULL);
331 g_object_set (G_OBJECT (self->tree_view), "level-indentation", 0, NULL);
332 gtk_tree_view_set_rubber_banding(self->tree_view, FALSE);
334 gtk_widget_set_size_request(GTK_WIDGET(self), 696, 396);
335 gtk_widget_show_all(GTK_WIDGET(self));
336 IRRECO_RETURN
339 GtkWidget *irreco_webdb_dlg_new(IrrecoData *irreco_data,
340 GtkWindow *parent)
342 IrrecoWebdbDlg *self;
343 IRRECO_ENTER
345 self = g_object_new(IRRECO_TYPE_WEBDB_DLG, NULL);
346 irreco_dlg_set_parent(IRRECO_DLG(self), parent);
347 irreco_webdb_dlg_set_irreco_data(self, irreco_data);
348 IRRECO_RETURN_PTR(self);
351 /** @} */
355 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
356 /* Private Functions */
357 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
360 * @name Private Functions
361 * @{
365 * Clean detail list
368 static void irreco_webdb_dlg_clean_details(IrrecoWebdbDlg *self)
370 IRRECO_ENTER
372 self->config = NULL;
373 gtk_label_set_text(
374 GTK_LABEL(self->config_user), "-");
375 gtk_label_set_text(
376 GTK_LABEL(self->config_backend), "-");
377 gtk_label_set_text(
378 GTK_LABEL(self->config_category), "-");
379 gtk_label_set_text(
380 GTK_LABEL(self->config_manuf), "-");
381 gtk_label_set_text(
382 GTK_LABEL(self->config_model), "-");
383 gtk_label_set_text(
384 GTK_LABEL(self->config_uploaded), "-");
385 gtk_label_set_text(
386 GTK_LABEL(self->config_download_count), "-");
388 IRRECO_RETURN
392 * Have the childern of this item been loaded.
394 * @return TRUE if children have been loade, FALSE otherwise.
396 static gboolean irreco_webdb_dlg_row_is_loaded(IrrecoWebdbDlg *self,
397 GtkTreeIter *iter)
399 gint i;
400 IRRECO_ENTER
402 gtk_tree_model_get(GTK_TREE_MODEL(self->tree_store),
403 iter, FLAG_COL, &i, -1);
404 if (i & ROW_CHILDREN_LOADED) IRRECO_RETURN_BOOL(TRUE);
405 IRRECO_RETURN_BOOL(FALSE);
409 * Enable / Disable ROW_CHILDREN_LOADED flag from a row.
411 * @param value If set, ROW_CHILDREN_LOADED will be enabled.
413 static void irreco_webdb_dlg_row_set_loaded(IrrecoWebdbDlg *self,
414 GtkTreeIter *iter,
415 gboolean value)
417 gint i;
418 IRRECO_ENTER
420 gtk_tree_model_get(GTK_TREE_MODEL(self->tree_store),
421 iter, FLAG_COL, &i, -1);
422 if (value) {
423 i = i | ROW_CHILDREN_LOADED;
424 } else {
425 i = i & ~ROW_CHILDREN_LOADED;
427 gtk_tree_store_set(self->tree_store, iter, FLAG_COL, i, -1);
429 IRRECO_RETURN
433 * Get type of row.
435 static gint irreco_webdb_dlg_row_get_type(IrrecoWebdbDlg *self,
436 GtkTreeIter *iter)
438 gint i;
439 IRRECO_ENTER
441 gtk_tree_model_get(GTK_TREE_MODEL(self->tree_store),
442 iter, FLAG_COL, &i, -1);
443 if (i & ROW_TYPE_CATEGORY)
444 IRRECO_RETURN_ENUM(ROW_TYPE_CATEGORY);
445 if (i & ROW_TYPE_MANUFACTURER)
446 IRRECO_RETURN_ENUM(ROW_TYPE_MANUFACTURER);
447 if (i & ROW_TYPE_MODEL)
448 IRRECO_RETURN_ENUM(ROW_TYPE_MODEL);
449 if (i & ROW_TYPE_CONFIG)
450 IRRECO_RETURN_ENUM(ROW_TYPE_CONFIG);
451 if (i & ROW_TYPE_LOADING)
452 IRRECO_RETURN_ENUM(ROW_TYPE_LOADING);
453 IRRECO_RETURN_INT(0);
457 * Show hildon progressbar banner.
459 * This function will create a new banner if one has not been created yet,
460 * if banner already exists, it's properties will be changed.
462 * @param text Text to show.
463 * @param fraction Value of progress.
465 static void irreco_webdb_dlg_set_banner(IrrecoWebdbDlg *self,
466 const gchar *text,
467 gdouble fraction)
469 IRRECO_ENTER
470 if (self->banner == NULL) {
471 self->banner = hildon_banner_show_progress(
472 GTK_WIDGET(self), NULL, "");
475 hildon_banner_set_text(HILDON_BANNER(self->banner), text);
476 hildon_banner_set_fraction(HILDON_BANNER(self->banner), fraction);
477 IRRECO_RETURN
481 * Destroy banner, if it exists.
483 static void irreco_webdb_dlg_hide_banner(IrrecoWebdbDlg *self)
485 IRRECO_ENTER
486 if (self->banner) {
487 gtk_widget_destroy(self->banner);
488 self->banner = NULL;
490 IRRECO_RETURN
494 * Start a loader state machine if one is not running already.
496 static void irreco_webdb_dlg_loader_start(IrrecoWebdbDlg *self,
497 GSourceFunc function,
498 GtkTreeIter *parent_iter)
500 IRRECO_ENTER
502 if (self->loader_func_id == 0) {
503 if (parent_iter) {
504 self->loader_parent_iter = gtk_tree_iter_copy(
505 parent_iter);
508 if (function) {
509 self->loader_func_id = g_idle_add(function, self);
510 } else {
511 IRRECO_ERROR("Loader function pointer not given.\n");
515 IRRECO_RETURN
519 * Stop and cleanup loader if a loader is running.
521 static void irreco_webdb_dlg_loader_stop(IrrecoWebdbDlg *self)
523 IRRECO_ENTER
524 if (self->loader_func_id != 0) {
525 g_source_remove(self->loader_func_id);
526 self->loader_func_id = 0;
527 self->loader_state = 0;
528 if (self->loader_parent_iter) {
529 gtk_tree_iter_free(self->loader_parent_iter);
531 self->loader_parent_iter = NULL;
533 IRRECO_RETURN
537 * Web Database Category loader.
539 * This loader will request a list of categories from the Web Database and
540 * update the TreeView accordingly. Every category row created by this loader
541 * will have row type ROW_TYPE_CATEGORY.
543 static gboolean irreco_webdb_dlg_loader_categ(IrrecoWebdbDlg *self)
545 IRRECO_ENTER
547 switch (self->loader_state) {
548 case LOADER_STATE_INIT:
549 irreco_webdb_dlg_set_banner(self, _("Loading ..."), 0);
550 self->loader_state = LOADER_STATE_LOOP;
551 irreco_webdb_dlg_clean_details(self);
552 IRRECO_RETURN_BOOL(TRUE);
554 case LOADER_STATE_LOOP: {
555 GtkTreeIter iter;
556 GtkTreeIter iter_loading;
557 IrrecoStringTable *categories = NULL;
558 IrrecoWebdbCache *webdb_cache = NULL;
560 webdb_cache = irreco_data_get_webdb_cache(self->irreco_data,
561 FALSE);
562 if(irreco_webdb_cache_get_categories(webdb_cache, &categories)){
563 IRRECO_STRING_TABLE_FOREACH_KEY(categories, key)
565 /* Append categogy. */
566 gtk_tree_store_append(self->tree_store,
567 &iter, NULL);
568 gtk_tree_store_set(self->tree_store,
569 &iter, TEXT_COL, key,
570 FLAG_COL, ROW_TYPE_CATEGORY,
571 DATA_COL, NULL, -1);
573 /* Add loading item into category. */
574 gtk_tree_store_append(self->tree_store,
575 &iter_loading, &iter);
576 gtk_tree_store_set(self->tree_store,
577 &iter_loading,
578 TEXT_COL, _("Loading ..."),
579 FLAG_COL, ROW_TYPE_LOADING,
580 DATA_COL, NULL, -1);
581 IRRECO_STRING_TABLE_FOREACH_END
582 } else {
583 irreco_error_dlg(GTK_WINDOW(self),
584 irreco_webdb_cache_get_error(
585 webdb_cache));
588 irreco_webdb_dlg_set_banner(self, _("Loading ..."), 1);
589 self->loader_state = LOADER_STATE_END;
590 IRRECO_RETURN_BOOL(TRUE);
593 case LOADER_STATE_END:
594 irreco_webdb_dlg_hide_banner(self);
595 irreco_webdb_dlg_loader_stop(self);
598 IRRECO_RETURN_BOOL(FALSE);
602 * Web Database Manufacturer loader.
604 * @todo
606 static gboolean irreco_webdb_dlg_loader_manuf(IrrecoWebdbDlg *self)
608 IRRECO_ENTER
610 switch (self->loader_state) {
611 case LOADER_STATE_INIT:
612 irreco_webdb_dlg_set_banner(self, _("Loading ..."), 0);
613 self->loader_state = LOADER_STATE_LOOP;
614 IRRECO_RETURN_BOOL(TRUE);
616 case LOADER_STATE_LOOP: {
617 GtkTreeIter iter;
618 GtkTreeIter iter_loading;
619 IrrecoStringTable *manufacturers = NULL;
620 IrrecoWebdbCache *webdb_cache = NULL;
621 gchar *category;
623 gtk_tree_model_get(GTK_TREE_MODEL(self->tree_store),
624 self->loader_parent_iter,
625 TEXT_COL, &category, -1);
627 webdb_cache = irreco_data_get_webdb_cache(self->irreco_data,
628 FALSE);
630 if(irreco_webdb_cache_get_manufacturers(webdb_cache,
631 category,
632 &manufacturers)){
634 IRRECO_STRING_TABLE_FOREACH_KEY(manufacturers, key)
636 /* Add manufacturer item into category. */
637 gtk_tree_store_append(self->tree_store,
638 &iter, self->loader_parent_iter);
639 gtk_tree_store_set(self->tree_store,
640 &iter,
641 TEXT_COL, key,
642 FLAG_COL, ROW_TYPE_MANUFACTURER,
643 DATA_COL, NULL, -1);
645 /* Add loading item into manufacturer. */
646 gtk_tree_store_append(self->tree_store,
647 &iter_loading, &iter);
648 gtk_tree_store_set(self->tree_store,
649 &iter_loading,
650 TEXT_COL, _("Loading ..."),
651 FLAG_COL, ROW_TYPE_LOADING,
652 DATA_COL, NULL, -1);
654 IRRECO_STRING_TABLE_FOREACH_END
655 } else {
656 irreco_error_dlg(GTK_WINDOW(self),
657 irreco_webdb_cache_get_error(
658 webdb_cache));
661 g_free (category);
663 /* Delete loading item from category. */
664 gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(self->tree_store),
665 &iter,self->loader_parent_iter,0);
666 if(irreco_webdb_dlg_row_get_type(self,
667 &iter) == ROW_TYPE_LOADING) {
668 gtk_tree_store_remove(self->tree_store,&iter);
670 irreco_webdb_dlg_set_banner(self, _("Loading ..."), 1);
671 self->loader_state = LOADER_STATE_END;
672 IRRECO_RETURN_BOOL(TRUE);
675 case LOADER_STATE_END:
676 irreco_webdb_dlg_row_set_loaded(self, self->loader_parent_iter,
677 TRUE);
678 irreco_webdb_dlg_hide_banner(self);
679 irreco_webdb_dlg_loader_stop(self);
682 IRRECO_RETURN_BOOL(FALSE);
686 * Web Database Model loader.
688 * @todo
690 static gboolean irreco_webdb_dlg_loader_model(IrrecoWebdbDlg *self)
692 IRRECO_ENTER
694 switch (self->loader_state) {
695 case LOADER_STATE_INIT:
696 irreco_webdb_dlg_set_banner(self, _("Loading ..."), 0);
697 self->loader_state = LOADER_STATE_LOOP;
698 IRRECO_RETURN_BOOL(TRUE);
700 case LOADER_STATE_LOOP: {
701 GtkTreeIter iter;
702 GtkTreeIter iter_loading;
703 GtkTreeIter category_iter;
704 IrrecoStringTable *models = NULL;
705 IrrecoWebdbCache *webdb_cache = NULL;
706 gchar *category;
707 gchar *manufacturer;
709 /*Get category and manufacturer*/
711 gtk_tree_model_get(GTK_TREE_MODEL(self->tree_store),
712 self->loader_parent_iter,
713 TEXT_COL, &manufacturer, -1);
715 gtk_tree_model_iter_parent(GTK_TREE_MODEL(self->tree_store),
716 &category_iter,
717 self->loader_parent_iter);
719 gtk_tree_model_get(GTK_TREE_MODEL(self->tree_store),
720 &category_iter,
721 TEXT_COL, &category, -1);
723 webdb_cache = irreco_data_get_webdb_cache(self->irreco_data,
724 FALSE);
726 if(irreco_webdb_cache_get_models(webdb_cache, category,
727 manufacturer, &models)){
729 IRRECO_STRING_TABLE_FOREACH_KEY(models, key)
731 /* Add model item into manufacturer. */
732 gtk_tree_store_append(self->tree_store,
733 &iter, self->loader_parent_iter);
734 gtk_tree_store_set(self->tree_store,
735 &iter,
736 TEXT_COL, key,
737 FLAG_COL, ROW_TYPE_MODEL,
738 DATA_COL, NULL, -1);
740 /* Add loading item into model. */
741 gtk_tree_store_append(self->tree_store,
742 &iter_loading, &iter);
743 gtk_tree_store_set(self->tree_store,
744 &iter_loading,
745 TEXT_COL, _("Loading ..."),
746 FLAG_COL, ROW_TYPE_LOADING,
747 DATA_COL, NULL, -1);
749 IRRECO_STRING_TABLE_FOREACH_END
750 } else {
751 irreco_error_dlg(GTK_WINDOW(self),
752 irreco_webdb_cache_get_error(
753 webdb_cache));
755 g_free (category);
756 g_free (manufacturer);
758 /* Delete loading item from manufacturer. */
759 gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(self->tree_store),
760 &iter, self->loader_parent_iter,
762 if(irreco_webdb_dlg_row_get_type(self,
763 &iter) == ROW_TYPE_LOADING) {
764 gtk_tree_store_remove(self->tree_store, &iter);
767 irreco_webdb_dlg_set_banner(self, _("Loading ..."), 1);
768 self->loader_state = LOADER_STATE_END;
770 IRRECO_RETURN_BOOL(TRUE);
772 case LOADER_STATE_END:
773 irreco_webdb_dlg_row_set_loaded(self, self->loader_parent_iter,
774 TRUE);
775 irreco_webdb_dlg_hide_banner(self);
776 irreco_webdb_dlg_loader_stop(self);
779 IRRECO_RETURN_BOOL(FALSE);
783 * Web Database Config loader.
785 * @todo
787 static gboolean irreco_webdb_dlg_loader_config(IrrecoWebdbDlg *self)
789 IRRECO_ENTER
791 switch (self->loader_state) {
792 case LOADER_STATE_INIT:
793 irreco_webdb_dlg_set_banner(self, _("Loading ..."), 0);
794 self->loader_state = LOADER_STATE_LOOP;
795 self->loader_pos = 0;
796 IRRECO_RETURN_BOOL(TRUE);
798 case LOADER_STATE_LOOP: {
799 GtkTreeIter iter;
800 GtkTreeIter manufacturer_iter;
801 GtkTreeIter category_iter;
802 IrrecoWebdbConf *config = NULL;
803 IrrecoStringTable *configs = NULL;
804 IrrecoWebdbCache *webdb_cache = NULL;
805 const gchar *config_id = NULL;
806 gpointer id_data;
807 gchar *category;
808 gchar *manufacturer;
809 gchar *model;
810 gint config_count;
811 gfloat banner;
813 /*Get manufacturer_iter and category_iter */
815 gtk_tree_model_iter_parent(GTK_TREE_MODEL(self->tree_store),
816 &manufacturer_iter,
817 self->loader_parent_iter);
819 gtk_tree_model_iter_parent(GTK_TREE_MODEL(self->tree_store),
820 &category_iter,
821 &manufacturer_iter);
823 /*Get category, manufacturer and model*/
825 gtk_tree_model_get(GTK_TREE_MODEL(self->tree_store),
826 &category_iter,
827 TEXT_COL, &category, -1);
829 gtk_tree_model_get(GTK_TREE_MODEL(self->tree_store),
830 &manufacturer_iter,
831 TEXT_COL, &manufacturer, -1);
833 gtk_tree_model_get(GTK_TREE_MODEL(self->tree_store),
834 self->loader_parent_iter,
835 TEXT_COL, &model, -1);
838 webdb_cache = irreco_data_get_webdb_cache(self->irreco_data,
839 FALSE);
841 if(irreco_webdb_cache_get_configs(webdb_cache,
842 category, manufacturer, model, &configs)){
843 gint id;
844 irreco_string_table_index(configs, self->loader_pos,
845 &config_id, &id_data);
846 id = atoi(config_id);
847 if(irreco_webdb_cache_get_configuration(webdb_cache,
848 id, &config)){
850 /* Add config item into model. */
851 gtk_tree_store_append(self->tree_store,
852 &iter, self->loader_parent_iter);
853 gtk_tree_store_set(self->tree_store,
854 &iter,
855 TEXT_COL, config->user->str,
856 FLAG_COL, ROW_TYPE_CONFIG,
857 DATA_COL, config_id, -1);
858 } else {
859 irreco_error_dlg(GTK_WINDOW(self),
860 irreco_webdb_cache_get_error(
861 webdb_cache));
864 } else {
865 irreco_error_dlg(GTK_WINDOW(self),
866 irreco_webdb_cache_get_error(
867 webdb_cache));
869 g_free (category);
870 g_free (manufacturer);
871 g_free (model);
874 /* Delete loading item from model. */
875 gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(self->tree_store),
876 &iter, self->loader_parent_iter,
878 if(irreco_webdb_dlg_row_get_type(self,
879 &iter) == ROW_TYPE_LOADING) {
880 gtk_tree_store_remove(self->tree_store, &iter);
883 config_count = irreco_string_table_lenght(configs);
885 banner = ((float) self->loader_pos + 1) / (float) config_count;
886 irreco_webdb_dlg_set_banner(self, _("Loading ..."), banner);
888 if (self->loader_pos + 1 >= config_count) {
889 self->loader_state = LOADER_STATE_END;
890 IRRECO_RETURN_BOOL(TRUE);
891 } else {
892 self->loader_pos++;
893 IRRECO_RETURN_BOOL(TRUE);
897 IRRECO_RETURN_BOOL(TRUE);
899 case LOADER_STATE_END:
900 irreco_webdb_dlg_row_set_loaded(self, self->loader_parent_iter,
901 TRUE);
902 irreco_webdb_dlg_hide_banner(self);
903 irreco_webdb_dlg_loader_stop(self);
906 IRRECO_RETURN_BOOL(FALSE);
910 * Web Database Configuration details loader.
912 * @todo
914 static gboolean irreco_webdb_dlg_display_config_detail(IrrecoWebdbDlg *self,
915 GtkTreeIter * iter)
917 IrrecoWebdbCache *webdb_cache = NULL;
918 const gchar *config_id = NULL;
919 GString *download_count = g_string_new("");
920 gint config_id_int;
921 IRRECO_ENTER
923 gtk_tree_model_get(GTK_TREE_MODEL(self->tree_store),
924 iter, DATA_COL, &config_id, -1);
926 config_id_int = atoi(config_id);
928 webdb_cache = irreco_data_get_webdb_cache(self->irreco_data,
929 FALSE);
931 irreco_webdb_cache_get_configuration(webdb_cache,
932 config_id_int, &self->config);
934 gtk_label_set_text(GTK_LABEL(self->config_user),
935 self->config->user->str);
936 gtk_label_set_text(GTK_LABEL(self->config_backend),
937 self->config->backend->str);
938 gtk_label_set_text(GTK_LABEL(self->config_category),
939 self->config->category->str);
940 gtk_label_set_text(GTK_LABEL(self->config_manuf),
941 self->config->manufacturer->str);
942 gtk_label_set_text(GTK_LABEL(self->config_model),
943 self->config->model->str);
944 gtk_label_set_text(GTK_LABEL(self->config_uploaded),
945 self->config->file_uploaded->str);
947 g_string_printf(download_count, "%s times",
948 self->config->file_download_count->str);
949 gtk_label_set_text(GTK_LABEL(self->config_download_count),
950 download_count->str);
951 g_string_free(download_count, TRUE);
953 IRRECO_RETURN_BOOL(TRUE);
958 * Web Database File loader.
960 * @todo
962 static gboolean irreco_webdb_dlg_load_file(IrrecoWebdbDlg *self)
964 IrrecoWebdbCache *webdb_cache = NULL;
965 IrrecoBackendInstance *inst = NULL;
966 GString *error_msg = g_string_new("");
967 IrrecoBackendManager *manager;
968 IrrecoBackendFileContainer *file_container;
969 GString *file_data;
970 gchar *sha1 = NULL;
971 gboolean success = TRUE;
972 gboolean new_instance = FALSE;
973 gint instances;
974 IRRECO_ENTER
976 if(self->config == NULL) {
977 g_string_printf(error_msg, "Select configuration first");
978 goto end;
981 /* Get file_data */
982 webdb_cache = irreco_data_get_webdb_cache(self->irreco_data, FALSE);
983 if (!irreco_webdb_cache_get_file(webdb_cache,
984 self->config->file_hash->str,
985 self->config->file_name->str,
986 &file_data)) {
987 g_string_printf(error_msg, irreco_webdb_cache_get_error(
988 webdb_cache));
989 goto end;
992 sha1 = sha_compute_checksum_for_string(G_CHECKSUM_SHA1,
993 file_data->str, -1);
995 if (g_utf8_collate(self->config->file_hash->str, sha1) != 0) {
996 g_string_printf(error_msg, "sha1 checksum failed.");
997 goto end;
1001 /* Search backend */
1002 manager = self->irreco_data->irreco_backend_manager;
1003 IRRECO_BACKEND_MANAGER_FOREACH_LIB(manager, lib)
1004 if (g_utf8_collate(lib->name, self->config->backend->str) != 0){
1005 continue;
1007 if (!(lib->api->flags & IRRECO_BACKEND_EDITABLE_DEVICES)) {
1008 g_string_printf(error_msg,
1009 "\"%s\" backend is not editable...",
1010 self->config->backend->str);
1011 goto end;
1013 else if (!(lib->api->flags &
1014 IRRECO_BACKEND_CONFIGURATION_EXPORT)) {
1015 g_string_printf(error_msg,
1016 "\"%s\" backend doesn't support "
1017 "exporting its configuration...",
1018 self->config->backend->str);
1019 goto end;
1021 /* Check if many instances */
1022 instances = 0;
1023 IRRECO_BACKEND_MANAGER_FOREACH_INSTANCE(manager, instance)
1024 irreco_backend_instance_get_description(instance);
1025 if (g_utf8_collate(instance->lib->name,
1026 self->config->backend->str) == 0) {
1027 instances++;
1029 /*if there is only one instance, then use it */
1030 inst = instance;
1032 IRRECO_STRING_TABLE_FOREACH_END
1033 IRRECO_DEBUG("INSTACES: %d\n",instances);
1035 /* Create new instance if it comes to the crunch */
1036 if (instances == 0 || lib->api->flags &
1037 IRRECO_BACKEND_NEW_INST_ON_CONF_IMPORT) {
1038 inst = irreco_backend_manager_create_instance(
1039 manager, lib, NULL, NULL);
1040 new_instance = TRUE;
1041 break;
1044 /* Select instace */
1045 if (instances > 1) {
1046 if (!irreco_show_select_instance_dlg(
1047 self->irreco_data, GTK_WINDOW(self),
1048 self->config->backend->str, &inst)) {
1049 g_string_printf(error_msg,
1050 "Operation aborted by user...");
1051 goto end;
1054 goto instance_ready;
1055 IRRECO_STRING_TABLE_FOREACH_END
1057 if (inst == NULL) {
1058 g_string_printf(error_msg, "\"%s\" backend is not installed...",
1059 self->config->backend->str);
1060 goto end;
1063 irreco_backend_instance_configure(inst, GTK_WINDOW(self));
1064 irreco_backend_instance_save_to_conf(inst);
1065 irreco_config_save_backends(manager);
1067 instance_ready:
1068 file_container = irreco_backend_file_container_new();
1069 irreco_backend_file_container_set(file_container,
1070 inst->lib->name,
1071 self->config->category->str,
1072 self->config->manufacturer->str,
1073 self->config->model->str,
1074 self->config->file_name->str,
1075 file_data->str);
1077 if (irreco_backend_instance_check_conf(inst, file_container)) {
1078 GString *question = g_string_new("");
1079 g_string_printf(question, "\"%s\" backend already contains\n"
1080 "device \"%s\".\n"
1081 "Do you want to overwrite?",
1082 inst->lib->name,self->config->model->str);
1083 success = irreco_yes_no_dlg(GTK_WINDOW(self), question->str);
1084 g_string_free(question, TRUE);
1086 if(success == FALSE) {
1087 goto end;
1091 /* Send file_data for backend */
1092 if(irreco_backend_instance_import_conf(inst, file_container)) {
1093 irreco_info_dlg(GTK_WINDOW(self),
1094 "Configuration downloaded successfully!");
1095 irreco_backend_manager_get_devcmd_lists(
1096 self->irreco_data->irreco_backend_manager);
1097 } else {
1098 g_string_printf(error_msg, "Backend error");
1100 if (new_instance) {
1101 irreco_backend_manager_destroy_instance(manager, inst);
1103 goto end;
1106 end:
1107 if(error_msg->len > 0) {
1108 irreco_error_dlg(GTK_WINDOW(self), error_msg->str);
1109 success = FALSE;
1111 g_string_free(error_msg, TRUE);
1112 if (sha1 != NULL) g_free(sha1);
1113 IRRECO_RETURN_BOOL(success);
1116 /** @} */
1120 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
1121 /* Functions */
1122 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
1125 * @name Public Functions
1126 * @{
1129 void irreco_webdb_dlg_set_irreco_data(IrrecoWebdbDlg *self,
1130 IrrecoData *irreco_data)
1132 IRRECO_ENTER
1133 self->irreco_data = irreco_data;
1134 IRRECO_RETURN
1137 void irreco_show_webdb_dlg(IrrecoData *irreco_data, GtkWindow *parent)
1139 IrrecoWebdbDlg *self;
1140 gint response;
1141 gboolean loop = TRUE;
1142 IRRECO_ENTER
1144 self = IRRECO_WEBDB_DLG(irreco_webdb_dlg_new(irreco_data, parent));
1146 do {
1147 response = gtk_dialog_run(GTK_DIALOG(self));
1148 switch (response) {
1149 case IRRECO_DEVICE_REFRESH:
1150 IRRECO_DEBUG("IRRECO_DEVICE_REFRESH\n");
1151 gtk_tree_store_clear(self->tree_store);
1152 irreco_data_get_webdb_cache(self->irreco_data, TRUE);
1153 irreco_webdb_dlg_loader_start(self,
1154 G_SOURCEFUNC(irreco_webdb_dlg_loader_categ),
1155 NULL);
1156 break;
1158 case GTK_RESPONSE_CANCEL:
1159 IRRECO_DEBUG("GTK_RESPONSE_CANCEL\n");
1160 loop = FALSE;
1161 break;
1163 case GTK_RESPONSE_OK:
1164 IRRECO_DEBUG("GTK_RESPONSE_OK\n");
1165 loop = !irreco_webdb_dlg_load_file(self);
1166 break;
1169 } while (loop);
1171 gtk_widget_destroy(GTK_WIDGET(self));
1172 IRRECO_RETURN
1175 /** @} */
1179 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
1180 /* Events and Callbacks */
1181 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
1184 * @name Events and Callbacks
1185 * @{
1188 static gboolean irreco_show_webdb_dlg_map_event(IrrecoWebdbDlg *self,
1189 GdkEvent *event,
1190 gpointer user_data)
1192 IRRECO_ENTER
1193 irreco_webdb_dlg_loader_start(
1194 self, G_SOURCEFUNC(irreco_webdb_dlg_loader_categ), NULL);
1195 IRRECO_RETURN_BOOL(FALSE);
1198 static void irreco_show_webdb_dlg_destroy_event(IrrecoWebdbDlg *self,
1199 gpointer user_data)
1201 IRRECO_ENTER
1202 irreco_webdb_dlg_loader_stop(self);
1203 IRRECO_RETURN
1206 static void irreco_show_webdb_dlg_row_activated_event(GtkTreeView *tree_view,
1207 GtkTreePath *path,
1208 GtkTreeViewColumn *column,
1209 IrrecoWebdbDlg *self)
1211 IRRECO_ENTER
1213 if (gtk_tree_view_row_expanded(tree_view, path)) {
1214 gtk_tree_view_expand_row(tree_view, path, FALSE);
1215 } else {
1216 gtk_tree_view_collapse_row(tree_view, path);
1218 IRRECO_RETURN
1221 static void irreco_show_webdb_dlg_row_expanded_event(GtkTreeView *tree_view,
1222 GtkTreeIter *iter,
1223 GtkTreePath *path,
1224 IrrecoWebdbDlg *self)
1226 IRRECO_ENTER
1228 irreco_webdb_dlg_clean_details(self);
1230 if (self->loader_func_id != 0) {
1231 gtk_tree_view_collapse_row(tree_view, path);
1234 if (!irreco_webdb_dlg_row_is_loaded(self, iter)) {
1235 switch (irreco_webdb_dlg_row_get_type(self, iter)) {
1236 case ROW_TYPE_CATEGORY:
1237 irreco_webdb_dlg_loader_start(self,
1238 G_SOURCEFUNC(irreco_webdb_dlg_loader_manuf),
1239 iter);
1240 break;
1242 case ROW_TYPE_MANUFACTURER:
1243 irreco_webdb_dlg_loader_start(self,
1244 G_SOURCEFUNC(irreco_webdb_dlg_loader_model),
1245 iter);
1246 break;
1248 case ROW_TYPE_MODEL:
1249 irreco_webdb_dlg_loader_start(self,
1250 G_SOURCEFUNC(irreco_webdb_dlg_loader_config),
1251 iter);
1252 break;
1256 IRRECO_RETURN
1259 static void irreco_show_webdb_dlg_row_collapsed_event(GtkTreeView *tree_view,
1260 GtkTreeIter *iter,
1261 GtkTreePath *path,
1262 IrrecoWebdbDlg *self)
1264 IRRECO_ENTER
1266 irreco_webdb_dlg_clean_details(self);
1268 IRRECO_RETURN
1271 static void irreco_show_webdb_dlg_row_selected_event(GtkTreeSelection *sel,
1272 IrrecoWebdbDlg *self)
1274 GtkTreeIter iter;
1275 GtkTreeModel *model;
1277 IRRECO_ENTER
1279 if (gtk_tree_selection_get_selected (sel, &model, &iter))
1281 switch (irreco_webdb_dlg_row_get_type(self, &iter)) {
1283 case ROW_TYPE_CONFIG:
1284 IRRECO_DEBUG("ROW_TYPE_CONFIG\n");
1285 irreco_webdb_dlg_display_config_detail(self, &iter);
1286 break;
1288 default:
1289 irreco_webdb_dlg_clean_details(self);
1290 break;
1294 IRRECO_RETURN
1297 /** @} */
1298 /** @} */