Created system which uploads all configurations of remote to database
[irreco.git] / irreco / src / core / irreco_remote_upload_dlg.c
blob02c8ed90c1d80c1bc1094f05dced537687d3396c
1 /*
2 * irreco - Ir Remote Control
3 * Copyright (C) 2008 Joni Kokko (t5kojo01@students.oamk.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_remote_upload_dlg.h"
21 #include "irreco_login_dlg.h"
22 #include "irreco_theme_upload_dlg.h"
23 #include "irreco_webdb_upload_dlg.h"
24 #include "irreco_webdb_cache.h"
26 /** Loader states. */
27 enum
29 LOADER_STATE_INIT,
30 LOADER_STATE_CONFIGURATIONS,
31 LOADER_STATE_THEMES,
32 LOADER_STATE_END
36 /**
37 * @addtogroup IrrecoRemoteUploadDlg
38 * @ingroup Irreco
40 * @todo PURPOCE OF CLASS.
42 * @{
45 /**
46 * @file
47 * Source file of @ref IrrecoRemoteUploadDlg.
51 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
52 /* Prototypes */
53 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
55 void irreco_remote_upload_dlg_comment_size_request(GtkWidget *widget,
56 GtkRequisition *requisition,
57 IrrecoRemoteUploadDlg *self);
59 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
60 /* Construction & Destruction */
61 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
63 /**
64 * @name Construction & Destruction
65 * @{
68 G_DEFINE_TYPE(IrrecoRemoteUploadDlg, irreco_remote_upload_dlg, IRRECO_TYPE_DLG)
70 static void irreco_remote_upload_dlg_dispose(GObject *object)
72 G_OBJECT_CLASS(irreco_remote_upload_dlg_parent_class)->dispose(object);
75 static void irreco_remote_upload_dlg_finalize(GObject *object)
77 G_OBJECT_CLASS(irreco_remote_upload_dlg_parent_class)->finalize(object);
80 static void irreco_remote_upload_dlg_class_init(
81 IrrecoRemoteUploadDlgClass *klass)
83 GObjectClass *object_class = G_OBJECT_CLASS (klass);
86 object_class->dispose = irreco_remote_upload_dlg_dispose;
87 object_class->finalize = irreco_remote_upload_dlg_finalize;
90 static void irreco_remote_upload_dlg_init(IrrecoRemoteUploadDlg *self)
92 GtkWidget *table;
93 GtkWidget *label_category;
94 GtkWidget *label_manufacturer;
95 GtkWidget *label_model;
96 GtkWidget *label_comment;
97 GtkWidget *align;
98 GtkWidget *comment_frame;
99 IRRECO_ENTER
101 self->remote_uploaded = FALSE;
103 /* Build the dialog */
104 gtk_window_set_title(GTK_WINDOW(self), _("Upload Remote"));
105 gtk_window_set_modal(GTK_WINDOW(self), TRUE);
106 gtk_window_set_destroy_with_parent(GTK_WINDOW(self), TRUE);
107 gtk_dialog_set_has_separator(GTK_DIALOG(self), FALSE);
108 gtk_dialog_add_buttons(GTK_DIALOG(self),
109 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
110 GTK_STOCK_OK, GTK_RESPONSE_OK,
111 NULL);
113 /* labels */
115 label_category = gtk_label_new("Category: ");
116 label_manufacturer = gtk_label_new("Manufacturer: ");
117 label_model = gtk_label_new("Model: ");
118 label_comment = gtk_label_new("Comment: ");
120 gtk_misc_set_alignment(GTK_MISC(label_category), 0, 0.5);
121 gtk_misc_set_alignment(GTK_MISC(label_manufacturer), 0, 0.5);
122 gtk_misc_set_alignment(GTK_MISC(label_model), 0, 0.5);
123 gtk_misc_set_alignment(GTK_MISC(label_comment), 0, 0.5);
125 /* entries */
127 self->category = gtk_combo_box_entry_new_text();
128 self->manufacturer = gtk_combo_box_entry_new_text();
129 self->model = gtk_entry_new();
131 /* comment textview */
133 self->comment = gtk_text_view_new();
134 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(self->comment),
135 GTK_WRAP_WORD_CHAR);
137 comment_frame = gtk_frame_new(NULL);
138 gtk_container_add(GTK_CONTAINER(comment_frame), self->comment);
140 /* table */
142 table = gtk_table_new(5, 2, FALSE);
144 gtk_table_attach(GTK_TABLE(table), label_category, 0, 1, 0, 1,
145 GTK_FILL, GTK_FILL, 0, 2);
146 gtk_table_attach(GTK_TABLE(table), label_manufacturer, 0, 1, 1, 2,
147 GTK_FILL, GTK_FILL, 0, 2);
148 gtk_table_attach(GTK_TABLE(table), label_model, 0, 1, 2, 3,
149 GTK_FILL, GTK_FILL, 0, 2);
150 gtk_table_attach(GTK_TABLE(table), label_comment, 0, 1, 3, 4,
151 GTK_FILL, GTK_FILL, 0, 2);
152 gtk_table_attach(GTK_TABLE(table), self->category, 1, 2, 0, 1,
153 GTK_FILL, GTK_FILL, 0, 2);
154 gtk_table_attach(GTK_TABLE(table), self->manufacturer, 1, 2, 1, 2,
155 GTK_FILL, GTK_FILL, 0, 2);
156 gtk_table_attach(GTK_TABLE(table), self->model, 1, 2, 2, 3,
157 GTK_FILL, GTK_FILL, 0, 0);
158 gtk_table_attach(GTK_TABLE(table), comment_frame, 0, 2, 4, 5,
159 GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0);
161 /* scroll */
163 self->scroll = gtk_scrolled_window_new(NULL, NULL);
164 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(self->scroll),
165 GTK_POLICY_NEVER,
166 GTK_POLICY_AUTOMATIC);
167 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(self->scroll),
168 table);
170 /* alignment */
172 align = gtk_alignment_new(0.5, 0.5, 1, 1);
173 gtk_alignment_set_padding(GTK_ALIGNMENT(align), 12, 12, 12, 12);
175 gtk_container_add(GTK_CONTAINER(align), self->scroll);
176 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(self)->vbox),
177 GTK_WIDGET(align));
179 /* Signals */
180 g_signal_connect(G_OBJECT(self->comment), "size-request", G_CALLBACK(
181 irreco_remote_upload_dlg_comment_size_request), self);
183 gtk_widget_set_size_request(GTK_WIDGET(self), -1, 280);
185 gtk_widget_show_all(GTK_WIDGET(self));
187 IRRECO_RETURN
190 IrrecoRemoteUploadDlg* irreco_remote_upload_dlg_new(IrrecoData *irreco_data,
191 GtkWindow *parent)
193 IrrecoRemoteUploadDlg *self;
194 IRRECO_ENTER
196 self = g_object_new(IRRECO_TYPE_REMOTE_UPLOAD_DLG, NULL);
197 irreco_dlg_set_parent(IRRECO_DLG(self), parent);
198 self->irreco_data = irreco_data;
199 IRRECO_RETURN_PTR(self);
203 /** @} */
207 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
208 /* Private Functions */
209 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
212 * @name Private Functions
213 * @{
216 gboolean irreco_remote_upload_dlg_populate_category(IrrecoRemoteUploadDlg *self)
218 IrrecoStringTable *categories = NULL;
219 IrrecoWebdbCache *webdb_cache;
220 IRRECO_ENTER
222 webdb_cache = irreco_data_get_webdb_cache(self->irreco_data, FALSE);
224 /* Get categories */
225 if(irreco_webdb_cache_get_all_categories(webdb_cache, &categories)) {
226 IRRECO_STRING_TABLE_FOREACH_KEY(categories, key)
228 gtk_combo_box_append_text(
229 GTK_COMBO_BOX(self->category), key);
231 IRRECO_STRING_TABLE_FOREACH_END
232 } else {
233 irreco_error_dlg(GTK_WINDOW(self),
234 irreco_webdb_cache_get_error(webdb_cache));
235 IRRECO_RETURN_BOOL(FALSE);
238 if (categories != NULL) irreco_string_table_free(categories);
240 IRRECO_RETURN_BOOL(TRUE);
243 gboolean irreco_remote_upload_dlg_populate_manufacturer(
244 IrrecoRemoteUploadDlg *self)
246 IrrecoStringTable *manufacturers = NULL;
247 IrrecoWebdbCache *webdb_cache;
248 IRRECO_ENTER
250 webdb_cache = irreco_data_get_webdb_cache(self->irreco_data, FALSE);
252 /* Get manufacturers */
253 if(irreco_webdb_cache_get_all_manufacturers(webdb_cache,
254 &manufacturers)) {
255 IRRECO_STRING_TABLE_FOREACH_KEY(manufacturers, key)
257 gtk_combo_box_append_text(
258 GTK_COMBO_BOX(self->manufacturer), key);
260 IRRECO_STRING_TABLE_FOREACH_END
261 } else {
262 irreco_error_dlg(GTK_WINDOW(self),
263 irreco_webdb_cache_get_error(webdb_cache));
264 IRRECO_RETURN_BOOL(FALSE);
267 if (manufacturers != NULL) irreco_string_table_free(manufacturers);
268 IRRECO_RETURN_BOOL(TRUE);
271 gboolean irreco_remote_upload_dlg_send(IrrecoRemoteUploadDlg *self)
273 IrrecoWebdbCache *webdb_cache;
274 IrrecoButtonLayout *layout;
275 gboolean rvalue = FALSE;
276 IRRECO_ENTER
277 webdb_cache = irreco_data_get_webdb_cache(self->irreco_data, FALSE);
278 layout = self->irreco_data->window_manager->current_layout;
280 switch (self->loader_state) {
282 case LOADER_STATE_INIT: {
283 gchar *category = NULL;
284 gchar *manufacturer = NULL;
285 const gchar *model;
286 gchar *comment = NULL;
287 GtkTextIter start;
288 GtkTextIter end;
289 GtkTextBuffer *buffer;
290 GString *path = g_string_new(irreco_get_config_dir("irreco"));
291 gchar *file_data = NULL;
292 gint file_length;
293 IRRECO_DEBUG("LOADER_STATE_INIT");
295 category = gtk_combo_box_get_active_text(
296 GTK_COMBO_BOX(self->category));
298 manufacturer = gtk_combo_box_get_active_text(
299 GTK_COMBO_BOX(self->manufacturer));
301 model = gtk_entry_get_text(GTK_ENTRY(self->model));
303 /* Set new name */
304 if (irreco_string_table_exists(
305 self->irreco_data->irreco_layout_array, model) &&
306 !g_str_equal(layout->name->str, model)) {
307 irreco_error_dlg(GTK_WINDOW(self),
308 _(IRRECO_LAYOUT_NAME_COLLISION));
309 goto end_init;
312 if (!irreco_string_table_change_key(
313 self->irreco_data->irreco_layout_array, layout->name->str,
314 model)) {
315 irreco_error_dlg(GTK_WINDOW(self),
316 "Incompatible model");
317 goto end_init;
320 irreco_config_save_layouts(self->irreco_data);
322 /* comment */
324 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(self->comment));
325 gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(buffer), &start);
326 gtk_text_buffer_get_end_iter(GTK_TEXT_BUFFER(buffer), &end);
327 comment = gtk_text_buffer_get_text(GTK_TEXT_BUFFER(buffer),
328 &start, &end, FALSE);
330 /* data */
332 g_string_append_printf(path,"/%s",layout->filename->str);
333 file_length = irreco_file_length(path->str);
334 file_data = g_malloc0(file_length);
336 /* check errors */
338 if (!irreco_read_text_file(path->str, file_data, file_length)) {
339 irreco_error_dlg(GTK_WINDOW(self),
340 "Can't open layout file.");
341 goto end_init;
344 if (strlen(category) == 0) {
345 irreco_error_dlg(GTK_WINDOW(self),
346 "Empty category field.");
347 goto end_init;
350 if (strlen(manufacturer) == 0) {
351 irreco_error_dlg(GTK_WINDOW(self),
352 "Empty manufacturer field.");
353 goto end_init;
356 if (strlen(model) == 0) {
357 irreco_error_dlg(GTK_WINDOW(self),
358 "Empty model field.");
359 goto end_init;
362 if (strlen(comment) == 0) {
363 irreco_error_dlg(GTK_WINDOW(self),
364 "Empty comment field.");
367 /* Show login dialog */
369 if (!irreco_show_login_dlg(self->irreco_data, GTK_WINDOW(self),
370 &self->user_name, &self->password)) {
371 IRRECO_DEBUG("Failed login\n");
372 goto end_init;
375 /* create remote to db */
377 self->remote_id = irreco_webdb_cache_create_new_remote(
378 webdb_cache->private, comment, category,
379 manufacturer, model, layout->filename->str,
380 file_data, self->user_name, self->password);
383 if (self->remote_id != 0) {
384 rvalue = TRUE;
386 end_init:
387 if (category != NULL) g_free(category);
388 if (manufacturer != NULL) g_free(manufacturer);
389 if (comment != NULL) g_free(comment);
390 if (file_data != NULL) g_free(file_data);
391 g_string_free(path, FALSE);
393 if (rvalue == TRUE) {
394 self->loader_state = LOADER_STATE_CONFIGURATIONS;
395 } else {
396 self->loader_state = LOADER_STATE_END;
399 IRRECO_RETURN_BOOL(TRUE);
401 case LOADER_STATE_CONFIGURATIONS: {
402 IrrecoStringTable *devices = NULL;
403 IRRECO_DEBUG("LOADER_STATE_CONFIGURATIONS\n");
405 if (!irreco_layout_get_backends(self->irreco_data,
406 layout->name->str,
407 &devices)) {
408 goto end_configurations;
410 IRRECO_STRING_TABLE_FOREACH(devices, name,
411 IrrecoBackendInstance *, instance) {
412 IrrecoBackendFileContainer *file = NULL;
413 gint id;
414 if (!irreco_backend_instance_export_conf(instance, name,
415 &file)) {
416 self->loader_state = LOADER_STATE_END;
417 IRRECO_DEBUG("exporting error");
418 goto end_configurations;
420 id = irreco_webdb_cache_get_config_id(webdb_cache,
421 file->hash->str,
422 file->name->str);
424 if (id == 0) {
425 irreco_show_webdb_upload_dlg(self->irreco_data,
426 GTK_WINDOW(self),
427 file, name);
429 id = irreco_webdb_cache_get_config_id(
430 webdb_cache,
431 file->hash->str,
432 file->name->str);
436 /* Append configuration to remote */
438 if (id != 0) {
439 irreco_webdb_cache_add_configuration_to_remote(
440 webdb_cache, self->remote_id, id,
441 self->user_name, self->password);
444 if (file != NULL) {
445 irreco_backend_file_container_free(file);
446 file = NULL;
449 IRRECO_STRING_TABLE_FOREACH_END
451 self->loader_state = LOADER_STATE_THEMES;
453 end_configurations:
454 if (devices != NULL) irreco_string_table_free(devices);
455 IRRECO_RETURN_BOOL(TRUE);
457 case LOADER_STATE_THEMES: {
458 IrrecoStringTable *themes = NULL;
459 IRRECO_DEBUG("LOADER_STATE_THEMES\n");
461 if (!irreco_layout_get_themes(self->irreco_data,
462 layout->name->str, &themes)) {
463 goto end_themes;
466 IRRECO_STRING_TABLE_FOREACH(themes, name, gchar *, date) {
467 gint id;
468 id = irreco_webdb_cache_get_theme_id_by_name_and_date(
469 webdb_cache, name, date);
471 if (id == 0) {
473 /* Get theme */
475 IrrecoTheme *theme;
476 irreco_string_table_get(
477 self->irreco_data->theme_manager->themes,
478 name, (gpointer*) &theme);
480 /* Upload theme to database */
482 if (!irreco_theme_upload_dlg_run(GTK_WINDOW(self),
483 self->irreco_data,
484 theme)) {
485 goto end_themes;
488 id = irreco_webdb_cache_get_theme_id_by_name_and_date(
489 webdb_cache, theme->name->str,
490 theme->version->str);
493 /* Append theme to remote */
495 if (id != 0) {
496 irreco_webdb_cache_add_theme_to_remote(webdb_cache,
497 self->remote_id,
499 self->user_name,
500 self->password);
503 IRRECO_STRING_TABLE_FOREACH_END
505 /* Set remote downloadable to TRUE */
507 irreco_webdb_cache_set_remote_downloadable(webdb_cache,
508 self->remote_id,
509 TRUE,
510 self->user_name,
511 self->password);
513 irreco_info_dlg(GTK_WINDOW(self),
514 "Remote uploaded successfully!");
515 self->remote_uploaded = TRUE;
517 /* Clean cache */
518 if (webdb_cache->remote_id_hash != NULL) {
519 g_hash_table_remove_all(webdb_cache->remote_id_hash);
521 if (webdb_cache->remote_categories != NULL) {
522 irreco_string_table_free(
523 webdb_cache->remote_categories);
524 webdb_cache->remote_categories = NULL;
527 end_themes:
528 if (themes != NULL) irreco_string_table_free(themes);
530 self->loader_state = LOADER_STATE_END;
531 IRRECO_RETURN_BOOL(TRUE);
533 case LOADER_STATE_END:
534 IRRECO_DEBUG("LOADER_STATE_END\n");
535 g_source_remove(self->loader_func_id);
537 if (self->remote_uploaded == TRUE) {
538 gtk_dialog_response(GTK_DIALOG(self),
539 GTK_RESPONSE_CANCEL);
543 IRRECO_RETURN_BOOL(FALSE);
546 /** @} */
550 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
551 /* Public Functions */
552 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
555 * @name Public Functions
556 * @{
559 void irreco_show_remote_upload_dlg(IrrecoData *irreco_data, GtkWindow *parent)
561 IrrecoRemoteUploadDlg *self;
562 gboolean loop = TRUE;
563 IrrecoButtonLayout *layout =
564 irreco_data->window_manager->current_layout;
565 IrrecoStringTable *themes;
566 gboolean deb_theme_in_layout = FALSE;
567 IRRECO_ENTER
569 self = irreco_remote_upload_dlg_new(irreco_data, parent);
571 irreco_remote_upload_dlg_populate_category(self);
572 irreco_remote_upload_dlg_populate_manufacturer(self);
573 gtk_entry_set_text(GTK_ENTRY(self->model),
574 irreco_button_layout_get_name(layout));
576 irreco_layout_get_themes(irreco_data, layout->name->str, &themes);
577 IRRECO_STRING_TABLE_FOREACH_KEY(themes, theme_name)
578 IrrecoTheme *theme;
579 irreco_string_table_get(irreco_data->theme_manager->themes,
580 theme_name, (gpointer *) &theme);
581 if (g_str_equal(theme->source->str, "deb")) {
582 deb_theme_in_layout = TRUE;
584 IRRECO_STRING_TABLE_FOREACH_END
586 if (deb_theme_in_layout) {
587 irreco_error_dlg(GTK_WINDOW(self),
588 "You can't upload remotes with Build In themes ");
589 goto end;
592 do {
593 gint response = gtk_dialog_run(GTK_DIALOG(self));
594 switch (response) {
595 case GTK_RESPONSE_CANCEL:
596 IRRECO_DEBUG("GTK_RESPONSE_CANCEL\n");
597 loop = FALSE;
598 break;
600 case GTK_RESPONSE_OK:
601 IRRECO_DEBUG("GTK_RESPONSE_OK\n");
602 self->loader_state = LOADER_STATE_INIT;
603 self->loader_func_id = g_idle_add((GSourceFunc)
604 irreco_remote_upload_dlg_send, self);
605 break;
608 } while (loop);
610 end:
611 irreco_string_table_free(themes);
612 gtk_widget_destroy(GTK_WIDGET(self));
613 IRRECO_RETURN
616 /** @} */
620 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
621 /* Events and Callbacks */
622 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
625 * @name Events and Callbacks
626 * @{
629 void irreco_remote_upload_dlg_comment_size_request(GtkWidget *widget,
630 GtkRequisition *requisition,
631 IrrecoRemoteUploadDlg *self)
633 GtkAdjustment* vadjustment = gtk_scrolled_window_get_vadjustment(
634 GTK_SCROLLED_WINDOW(self->scroll));
635 IRRECO_ENTER
637 if (requisition->height > self->cursor_position) {
638 vadjustment->value += 27;
639 } else if (requisition->height < self->cursor_position) {
640 vadjustment->value -= 27;
642 self->cursor_position = requisition->height;
644 IRRECO_RETURN
647 /** @} */
649 /** @} */