Mostly minor fixes up until version 0.8.10.
[irreco.git] / irreco / src / core / irreco_theme_upload_dlg.c
blobc02faac7576db73ad489a3c211c211539a583825
1 /*
2 * irreco - Ir Remote Control
3 * Copyright (C) 2007 Arto Karppinen (arto.karppinen@iki.fi)
4 * 2008 Joni Kokko (t5kojo01@students.oamk.fi)
5 * 2008 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_theme_upload_dlg.h"
23 #include "irreco_button_browser_dlg.h"
24 #include <hildon/hildon-banner.h>
27 /**
28 * @addtogroup IrrecoThemeUploadDlg
29 * @ingroup Irreco
31 * Allow user to set theme settings and upload it.
33 * @{
36 /**
37 * @file
38 * Source file of @ref IrrecoThemeUploadDlg.
43 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
44 /* Datatypes */
45 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
47 #define IRRECO_THEME_UPLOAD_PREVIEW_WIDHT (IRRECO_SCREEN_WIDTH / 6)
48 #define IRRECO_THEME_UPLOAD_PREVIEW_HEIGHT (IRRECO_SCREEN_HEIGHT / 6)
50 /** Loader states. */
51 enum
53 LOADER_STATE_INIT,
54 LOADER_STATE_THEME,
55 LOADER_STATE_BUTTONS,
56 LOADER_STATE_BACKGROUNDS,
57 LOADER_STATE_END
60 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
61 /* Prototypes */
62 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
63 static gboolean _texts_ok(IrrecoThemeUploadDlg *self);
64 static gboolean _send_theme(IrrecoThemeUploadDlg *self);
65 static void _update_preview(IrrecoThemeUploadDlg *self);
66 static void _run_button_browser_dlg(GtkWidget *widget,
67 GdkEventButton *event,
68 IrrecoThemeUploadDlg *self);
69 static gboolean _get_image_data_and_hash(gchar* img_path,
70 guchar **img_data,
71 gchar **img_sha,
72 gint *img_data_len,
73 gsize buffer_size,
74 gchar **error_msg);
75 static void _hide_banner(IrrecoThemeUploadDlg *self);
76 static void _set_banner(IrrecoThemeUploadDlg *self,
77 const gchar *text,
78 gdouble fraction);
79 static void _loader_start(IrrecoThemeUploadDlg *self);
80 static void _loader_stop(IrrecoThemeUploadDlg *self);
82 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
83 /* Construction & Destruction */
84 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
86 /**
87 * @name Construction & Destruction
88 * @{
91 G_DEFINE_TYPE(IrrecoThemeUploadDlg, irreco_theme_upload_dlg,
92 IRRECO_TYPE_INTERNAL_DLG)
94 static void irreco_theme_upload_dlg_constructed(GObject *object)
96 IrrecoThemeUploadDlg *self;
98 GtkWidget *hbox_lr;
99 GtkWidget *vbox_preview;
100 GtkWidget *label_name;
101 GtkWidget *label_comments;
102 GtkWidget *label_preview;
103 GtkWidget *scrolled_comments;
104 GtkWidget *scrolled_window;
105 GtkWidget *table;
106 GtkWidget *frame_comments;
107 GtkWidget *frame_preview;
109 IRRECO_ENTER
111 G_OBJECT_CLASS(irreco_theme_upload_dlg_parent_class)->constructed(object);
112 self = IRRECO_THEME_UPLOAD_DLG(object);
114 self->comments = NULL;
116 /* Construct dialog. */
117 gtk_window_set_title(GTK_WINDOW(self), _("Upload theme"));
118 gtk_window_set_modal(GTK_WINDOW(self), TRUE);
119 gtk_window_set_destroy_with_parent(GTK_WINDOW(self), TRUE);
120 gtk_dialog_set_has_separator(GTK_DIALOG(self), FALSE);
121 gtk_dialog_add_buttons(GTK_DIALOG(self),
122 _("Upload"), GTK_RESPONSE_OK,
123 NULL);
125 /* Create widgets. */
126 hbox_lr = gtk_hbox_new(FALSE, 10);
127 vbox_preview = gtk_vbox_new(FALSE, 0);
128 label_name = gtk_label_new("Theme name:");
129 label_comments = gtk_label_new("Comments: ");
130 label_preview = gtk_label_new("Select\npreview image:");
131 self->entry_name = gtk_entry_new();
132 gtk_editable_set_editable(GTK_EDITABLE(self->entry_name), FALSE);
133 self->textview_comments = gtk_text_view_new();
134 frame_comments = gtk_frame_new(NULL);
136 /* preview */
137 self->preview_image = gtk_image_new();
138 gtk_image_set_from_file(GTK_IMAGE(self->preview_image), NULL);
139 frame_preview = gtk_frame_new(NULL);
140 self->preview_event_box = gtk_event_box_new();
141 gtk_container_add(GTK_CONTAINER(frame_preview), self->preview_image);
142 gtk_container_add(GTK_CONTAINER(self->preview_event_box), frame_preview);
143 gtk_widget_set_size_request(frame_preview, 200,200);
146 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(self->textview_comments),
147 GTK_WRAP_WORD_CHAR);
148 gtk_widget_set_size_request(self->textview_comments, 400, 150);
149 scrolled_comments = gtk_scrolled_window_new(NULL, NULL);
150 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_comments),
151 GTK_POLICY_NEVER,
152 GTK_POLICY_AUTOMATIC);
153 table = gtk_table_new(4, 2, FALSE);
155 /* Window scrolling */
156 scrolled_window = gtk_scrolled_window_new(NULL, NULL);
157 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
158 GTK_POLICY_NEVER,
159 GTK_POLICY_AUTOMATIC);
161 /* Build dialog. */
162 /*gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(self)->vbox),
163 hbox_lr);*/
164 /* TODO hbox_lr to scrolled and scrolled to self->vbox */
165 gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(self)->vbox),
166 scrolled_window);
167 gtk_scrolled_window_add_with_viewport(
168 GTK_SCROLLED_WINDOW(scrolled_window),
169 hbox_lr);
170 /*gtk_widget_set_size_request(GTK_WIDGET(hbox_lr), 600, 470);*/
171 gtk_window_set_default_size(GTK_WINDOW(self), 600, 340);
173 gtk_box_pack_start_defaults(GTK_BOX(hbox_lr), table);
174 gtk_box_pack_end_defaults(GTK_BOX(hbox_lr), vbox_preview);
175 gtk_box_pack_start_defaults(GTK_BOX(vbox_preview), label_preview);
176 gtk_box_pack_end_defaults(GTK_BOX(vbox_preview),
177 self->preview_event_box);
178 gtk_container_add(GTK_CONTAINER(scrolled_comments),
179 self->textview_comments);
180 gtk_container_add(GTK_CONTAINER (frame_comments),
181 scrolled_comments);
182 gtk_table_attach_defaults(GTK_TABLE(table),
183 label_name, 0, 1, 0, 1);
184 gtk_table_attach_defaults(GTK_TABLE(table),
185 self->entry_name, 1, 2, 0, 1);
186 gtk_table_attach_defaults(GTK_TABLE(table),
187 label_comments, 0, 1, 1, 2);
188 /*gtk_table_attach_defaults(GTK_TABLE(table),
189 frame_comments, 0, 2, 2, 3);*/
190 gtk_table_attach(GTK_TABLE(table),
191 frame_comments,
192 0, 2, 2, 3,
193 GTK_EXPAND, GTK_EXPAND,
194 5, 0);
195 gtk_container_set_border_width (GTK_CONTAINER (self), 5);
197 /* Connect preview eventbox and start dialog from there */
198 g_signal_connect(G_OBJECT(self->preview_event_box),
199 "button-release-event",
200 G_CALLBACK(_run_button_browser_dlg),
201 IRRECO_THEME_UPLOAD_DLG(self));
203 gtk_widget_show_all(GTK_WIDGET(self));
204 IRRECO_RETURN
207 static void irreco_theme_upload_dlg_init(IrrecoThemeUploadDlg *self)
209 IRRECO_ENTER
210 IRRECO_RETURN
213 static void irreco_theme_upload_dlg_finalize(GObject *object)
215 IrrecoThemeUploadDlg *self;
216 IRRECO_ENTER
218 self = IRRECO_THEME_UPLOAD_DLG(object);
220 G_OBJECT_CLASS(irreco_theme_upload_dlg_parent_class)->finalize(object);
221 IRRECO_RETURN
224 static void irreco_theme_upload_dlg_class_init(IrrecoThemeUploadDlgClass *klass)
226 GObjectClass* object_class = G_OBJECT_CLASS (klass);
227 /* IrrecoDlgClass* parent_class = IRRECO_DLG_CLASS (klass); */
229 object_class->finalize = irreco_theme_upload_dlg_finalize;
230 object_class->constructed = irreco_theme_upload_dlg_constructed;
233 GtkWidget *irreco_theme_upload_dlg_new(IrrecoData *irreco_data,
234 GtkWindow *parent_window)
236 IrrecoThemeUploadDlg *self;
237 IRRECO_ENTER
239 self = g_object_new(IRRECO_TYPE_THEME_UPLOAD_DLG,
240 "irreco-data", irreco_data,
241 NULL);
242 irreco_dlg_set_parent(IRRECO_DLG(self), parent_window);
243 IRRECO_RETURN_PTR(self);
246 /** @} */
249 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
250 /* Private Functions */
251 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
253 * @name Private Functions
254 * @{
258 * Show hildon progressbar banner.
260 * This function will create a new banner if one has not been created yet,
261 * if banner already exists, it's properties will be changed.
263 * @param text Text to show.
264 * @param fraction Value of progress.
266 static void _set_banner(IrrecoThemeUploadDlg *self,
267 const gchar *text,
268 gdouble fraction)
270 IRRECO_ENTER
272 if (self->banner == NULL) {
273 self->banner = hildon_banner_show_progress(
274 GTK_WIDGET(self), NULL, "");
277 hildon_banner_set_text(HILDON_BANNER(self->banner), text);
278 hildon_banner_set_fraction(HILDON_BANNER(self->banner), fraction);
280 IRRECO_RETURN
284 * Destroy banner, if it exists.
286 static void _hide_banner(IrrecoThemeUploadDlg *self)
288 IRRECO_ENTER
290 if (self->banner) {
291 gtk_widget_destroy(self->banner);
292 self->banner = NULL;
295 IRRECO_RETURN
299 * Start a loader state machine if one is not running already.
301 static void _loader_start(IrrecoThemeUploadDlg *self)
303 IRRECO_ENTER
305 if (self->loader_func_id == 0) {
306 self->loader_func_id = g_idle_add((GSourceFunc)_send_theme, self);
309 IRRECO_RETURN
313 * Stop and cleanup loader if a loader is running.
315 static void _loader_stop(IrrecoThemeUploadDlg *self)
317 IRRECO_ENTER
318 _hide_banner(self);
319 if (self->loader_func_id != 0) {
320 g_source_remove(self->loader_func_id);
321 self->loader_func_id = 0;
322 self->loader_state = 0;
324 IRRECO_RETURN
328 * Check textfields, return TRUE if everythings fine
330 static gboolean _texts_ok(IrrecoThemeUploadDlg *self)
332 gboolean rvalue = TRUE;
333 GtkTextIter startiter;
334 GtkTextIter enditer;
336 IRRECO_ENTER
338 if (self->comments != NULL) g_free(self->comments);
340 gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(self->buffer_comments),
341 &startiter);
342 gtk_text_buffer_get_end_iter(GTK_TEXT_BUFFER(self->buffer_comments),
343 &enditer);
344 self->comments = gtk_text_buffer_get_text(
345 GTK_TEXT_BUFFER(self->buffer_comments),
346 &startiter,
347 &enditer,
348 FALSE);
349 /* a Superb hack */
350 if(strlen(self->comments) == 0) {
351 self->comments = " ";
352 IRRECO_DEBUG("No comment given, "
353 "using space to prevent DB failing\n");
356 IRRECO_DEBUG("theme comments: %s\n", self->comments);
358 IRRECO_RETURN_BOOL(rvalue);
362 * Upload theme confs and images, return TRUE if everything went fine
364 static gboolean _send_theme(IrrecoThemeUploadDlg *self)
366 IrrecoWebdbTheme *theme;
368 IRRECO_ENTER
370 switch (self->loader_state) {
372 case LOADER_STATE_INIT:
374 IRRECO_DEBUG("Loader state init\n");
376 self->uploading_errors = FALSE;
378 self->cache = self->irreco_data->webdb_cache;
380 self->buffer_size =
381 irreco_webdb_cache_get_max_image_size(self->cache);
382 self->banner_max = irreco_string_table_lenght(
383 self->theme->buttons);
384 self->banner_max += irreco_string_table_lenght(
385 self->theme->backgrounds);
386 self->strtablesize = irreco_string_table_lenght(
387 self->theme->buttons);
388 self->strtableindex = 0;
389 _set_banner(self, _("Uploading theme..."), 0);
390 self->loader_state = LOADER_STATE_THEME;
392 IRRECO_RETURN_BOOL(TRUE);
394 case LOADER_STATE_THEME: {
396 gchar *parsedpath;
398 IRRECO_DEBUG("Loader state theme\n");
400 /* Parse folder out from theme path */
401 parsedpath = g_utf8_strrchr(self->theme->path->str,
403 G_DIR_SEPARATOR);
404 parsedpath = g_utf8_find_next_char(parsedpath, NULL);
406 /* Create new theme */
407 self->themeindex = irreco_webdb_cache_create_theme(
408 self->cache,
409 /*self->theme_name,*/
410 self->theme->name->str,
411 self->comments,
412 self->theme->preview_button_name->str,
413 parsedpath,
414 self->user,
415 self->password);
417 /* Theme creation failed for unknown reasons */
418 if(self->themeindex == 0) {
419 irreco_error_dlg(GTK_WINDOW(self),
420 "Theme creation failed");
421 self->uploading_errors = TRUE;
422 _loader_stop(self);
423 self->uploading_started = FALSE;
424 IRRECO_RETURN_BOOL(FALSE);
427 /* Theme creation prevented for mismatching username & password pair */
428 if(self->themeindex == -1) {
429 irreco_error_dlg(GTK_WINDOW(self),
430 "Username and password mismatch");
431 self->uploading_errors = TRUE;
432 _loader_stop(self);
433 self->uploading_started = FALSE;
434 IRRECO_RETURN_BOOL(FALSE);
437 /* Theme creation prevented for "wrong" user */
438 if(self->themeindex == -2) {
439 irreco_error_dlg(GTK_WINDOW(self),
440 "Theme name already taken");
441 self->uploading_errors = TRUE;
442 _loader_stop(self);
443 self->uploading_started = FALSE;
444 IRRECO_RETURN_BOOL(FALSE);
447 self->loader_state = LOADER_STATE_BUTTONS;
449 IRRECO_RETURN_BOOL(TRUE);
452 case LOADER_STATE_BUTTONS: {
454 guchar *img_up_data = g_malloc0(self->buffer_size);
455 guchar *img_down_data = g_malloc0(self->buffer_size);
456 gchar *img_up_sha; /* SHAs */
457 gchar *img_down_sha;
458 gchar *img_up_name; /* filenames */
459 gchar *img_down_name;
460 gint img_up_len; /* img data lengths */
461 gint img_down_len;
462 GString *img_folder = g_string_new(NULL); /* folder of button */
463 gint button_index;
464 gchar *error_msg = NULL;
465 const gchar *key;
466 IrrecoThemeButton *button = NULL;
467 gfloat banner;
469 IRRECO_DEBUG("Loader state buttons\n");
471 irreco_string_table_index(self->theme->buttons,
472 self->strtableindex, &key,
473 (gpointer *) &button);
475 if(button == NULL) {
476 IRRECO_DEBUG("No buttons\n");
477 goto cleanup_button;
480 banner = (gfloat) self->strtableindex/(gfloat) self->banner_max;
482 self->strtableindex++;
484 _set_banner(self,
485 "Uploading buttons...",
486 banner);
488 IRRECO_DEBUG("Current button: %s\n", button->name->str);
490 /* button up sizecheck */
491 if(irreco_file_length(button->image_up->str) >=
492 self->buffer_size) {
493 img_up_data = NULL;
494 img_up_sha = NULL;
495 img_up_name = NULL;
496 irreco_error_dlg(GTK_WINDOW(self),
497 g_strdup_printf(
498 "Button %s image too large\n"
499 "Max allowed size: %d KiB",
500 button->name->str,
501 self->buffer_size/1024));
502 self->uploading_errors = TRUE;
503 goto cleanup_button;
506 /* button up */
507 if(_get_image_data_and_hash(button->image_up->str,
508 &img_up_data,
509 &img_up_sha,
510 &img_up_len,
511 self->buffer_size,
512 &error_msg)) {
514 /* Parse folder out from theme img */
515 img_up_name = g_utf8_strrchr(button->image_up->str,
517 G_DIR_SEPARATOR);
518 img_up_name = g_utf8_find_next_char(img_up_name, NULL);
519 } else {
520 img_up_data = NULL;
521 img_up_sha = NULL;
522 img_up_name = NULL;
523 irreco_error_dlg(GTK_WINDOW(self), error_msg);
524 self->uploading_errors = TRUE;
525 goto cleanup_button;
528 /* button down sizecheck */
529 if(irreco_file_length(button->image_down->str) >=
530 self->buffer_size) {
531 img_down_data = NULL;
532 img_down_sha = NULL;
533 img_down_name = NULL;
534 irreco_error_dlg(GTK_WINDOW(self),
535 g_strdup_printf(
536 "Button %s image too large\n"
537 "Max allowed size: %d KiB",
538 button->name->str,
539 self->buffer_size/1024));
540 self->uploading_errors = TRUE;
541 goto cleanup_button;
544 /* button down */
545 if(_get_image_data_and_hash(button->image_down->str,
546 &img_down_data,
547 &img_down_sha,
548 &img_down_len,
549 self->buffer_size,
550 &error_msg)) {
551 /* Parse folder out from theme img */
552 img_down_name = g_utf8_strrchr(button->image_down->str,
554 G_DIR_SEPARATOR);
555 img_down_name = g_utf8_find_next_char(img_down_name,
556 NULL);
557 } else {
558 img_down_data = NULL;
559 img_down_sha = NULL;
560 img_down_name = NULL;
561 IRRECO_DEBUG("No optional down button\n");
564 /* Copy whole path+button name */
565 g_string_printf(img_folder, "%s", button->image_down->str);
566 /* Remove everything past and including rightmost folder char */
567 img_folder = g_string_erase(img_folder,
568 strlen(button->image_down->str) -
569 strlen(g_utf8_strrchr(
570 button->image_down->str,
572 G_DIR_SEPARATOR)),
573 -1);
574 /* Remove everything prior rightmost folder character */
575 g_string_printf(img_folder, "%s", g_utf8_strrchr(img_folder->str,
577 G_DIR_SEPARATOR));
578 /* Remove starting folder character */
579 img_folder = g_string_erase(img_folder, 0, 1);
581 /* Upload button */
582 button_index = irreco_webdb_cache_add_button_to_theme(
583 self->cache,
584 button->name->str,
585 button->allow_text,
586 button->text_format_up->str,
587 button->text_format_down->str,
588 button->text_padding,
589 button->text_h_align,
590 button->text_v_align,
591 img_up_sha,
592 img_up_name,
593 img_up_data,
594 img_up_len,
595 img_down_sha,
596 img_down_name,
597 img_down_data,
598 img_down_len,
599 img_folder->str,
600 self->themeindex,
601 self->user,
602 self->password);
604 if(button_index == 0) {
605 irreco_error_dlg(GTK_WINDOW(self),
606 g_strdup_printf(
607 "Button %s uploading failed",
608 button->name->str));
609 self->uploading_errors = TRUE;
612 cleanup_button:
613 /* Free resources */
614 g_free(img_up_data);
615 img_up_data = NULL;
616 g_free(img_down_data);
617 img_down_data = NULL;
618 g_string_free(img_folder, TRUE);
619 img_folder = NULL;
621 if(self->strtablesize == self->strtableindex ||
622 self->strtablesize == 0) {
623 self->strtablesize = irreco_string_table_lenght(
624 self->theme->backgrounds);
625 self->strtableindex = 0;
626 self->loader_state = LOADER_STATE_BACKGROUNDS;
627 IRRECO_DEBUG("Next loader state backgrounds\n");
630 IRRECO_RETURN_BOOL(TRUE);
633 case LOADER_STATE_BACKGROUNDS: {
634 GString *img_folder = g_string_new(NULL);
635 guchar *img_data = g_malloc0(self->buffer_size);
636 gchar *img_sha;
637 gchar *img_name;
638 gint img_len;
639 gint bg_index;
640 gchar *error_msg;
641 const gchar *key;
642 IrrecoThemeBg *bg = NULL;
643 gfloat banner;
645 irreco_string_table_index(self->theme->backgrounds,
646 self->strtableindex, &key,
647 (gpointer *) &bg);
649 if(bg == NULL) {
650 IRRECO_DEBUG("No backgrounds\n");
651 goto cleanup_bg;
654 banner = (gfloat) (self->banner_max -
655 self->strtablesize + self->strtableindex) /
656 (gfloat) self->banner_max;
658 self->strtableindex++;
660 _set_banner(self, "Uploading backgrounds...", banner);
662 IRRECO_DEBUG("Current bg: %s\n", bg->image_name->str);
664 /* backgrounds image sizecheck */
665 if(irreco_file_length(bg->image_path->str) >=
666 self->buffer_size) {
667 img_data = NULL;
668 img_sha = NULL;
669 img_name = NULL;
670 irreco_error_dlg(GTK_WINDOW(self),
671 g_strdup_printf(
672 "Background %s image too large\n"
673 "Max allowed size: %d KiB",
674 bg->image_name->str,
675 self->buffer_size/1024));
676 self->uploading_errors = TRUE;
677 goto cleanup_bg;
679 if(_get_image_data_and_hash(bg->image_path->str,
680 &img_data,
681 &img_sha,
682 &img_len,
683 self->buffer_size,
684 &error_msg)) {
686 /* Parse folder out from bg img path */
687 img_name = g_utf8_strrchr(bg->image_path->str,
689 G_DIR_SEPARATOR);
690 img_name = g_utf8_find_next_char(img_name, NULL);
691 } else {
692 img_data = NULL;
693 img_sha = NULL;
694 img_name = NULL;
695 irreco_error_dlg(GTK_WINDOW(self), error_msg);
696 self->uploading_errors = TRUE;
697 goto cleanup_bg;
700 /* Copy whole path+bg name */
701 g_string_printf(img_folder, "%s", bg->image_path->str);
702 /* Remove everything past and including rightmost folder char */
703 img_folder = g_string_erase(img_folder,
704 strlen(bg->image_path->str) -
705 strlen(g_utf8_strrchr(
706 bg->image_path->str,
708 G_DIR_SEPARATOR)),
709 -1);
710 /* Remove everything prior rightmost folder character */
711 g_string_printf(img_folder, "%s", g_utf8_strrchr(img_folder->str,
713 G_DIR_SEPARATOR));
714 /* Remove starting folder character */
715 img_folder = g_string_erase(img_folder, 0, 1);
717 if(img_len >= self->buffer_size) {
718 irreco_error_dlg(GTK_WINDOW(self),
719 g_strdup_printf(
720 "Bg %s image too large",
721 bg->image_name->str));
722 self->uploading_errors = TRUE;
723 goto cleanup_bg;
726 bg_index = irreco_webdb_cache_add_bg_to_theme(
727 self->cache,
728 bg->image_name->str,
729 img_sha,
730 img_name,
731 img_data,
732 img_len,
733 img_folder->str,
734 self->themeindex,
735 self->user,
736 self->password);
737 if(bg_index == 0) {
738 irreco_error_dlg(GTK_WINDOW(self),
739 g_strdup_printf(
740 "Bg %s uploading failed",
741 bg->image_name->str));
742 self->uploading_errors = TRUE;
745 cleanup_bg:
746 g_free(img_data);
747 img_data = NULL;
748 g_string_free(img_folder, TRUE);
749 img_folder = NULL;
751 if(self->strtablesize == self->strtableindex ||
752 self->strtablesize == 0) {
753 self->loader_state = LOADER_STATE_END;
754 IRRECO_DEBUG("Next loader state end\n");
757 IRRECO_RETURN_BOOL(TRUE);
760 case LOADER_STATE_END:
762 _hide_banner(self);
764 if(!self->uploading_errors) {
765 if(!irreco_webdb_cache_set_theme_downloadable(
766 self->cache,
767 self->themeindex,
768 TRUE,
769 self->user,
770 self->password)) {
771 irreco_error_dlg(GTK_WINDOW(self),
772 "Failed to make theme downloadable.\n"
773 "Theme won't show at database.");
774 self->uploading_errors = TRUE;
775 } else {
776 irreco_info_dlg(GTK_WINDOW(self),
777 "Theme uploaded successfully");
780 /* Get latest theme version to just uploaded theme */
781 if(!irreco_webdb_cache_get_theme_by_id(self->cache,
782 self->themeindex,
783 &theme)) {
784 /*irreco_error_dlg(GTK_WINDOW(self),
785 "Failed to get theme version");
786 self->uploading_errors = TRUE;*/
787 IRRECO_DEBUG("Failed to get theme version\n");
788 IRRECO_DEBUG("Not fatal bug, continuing\n");
790 } else {
791 g_string_printf(self->theme->version,
792 "%s",
793 theme->uploaded->str);
794 irreco_theme_update_keyfile(self->theme);
797 } else {
798 irreco_error_dlg(GTK_WINDOW(self),
799 "Some error(s) occured during upload.\n"
800 "Please try again.");
801 _loader_stop(self);
802 self->uploading_started = FALSE;
803 IRRECO_RETURN_BOOL(FALSE);
805 self->uploading_started = FALSE;
806 gtk_dialog_response(GTK_DIALOG(self), GTK_RESPONSE_CLOSE);
807 IRRECO_RETURN_BOOL(FALSE);
810 IRRECO_DEBUG("Oh no, shouldn't ever be here\n");
811 IRRECO_RETURN_BOOL(FALSE);
815 * Retrieves image data and hash of given file
817 * @param img_path Path to file containing binary data
818 * @param img_data Set to contain read binary data
819 * @param img_sha Set to contain sha1 of data
820 * @param img_data_len Set to contain length of data
821 * @param buffer_size Max length of data to read
822 * @param error_msg Set to contain error message, if error occurs
823 * @return True upon success, false otherwise
825 static gboolean _get_image_data_and_hash(gchar *img_path,
826 guchar **img_data,
827 gchar **img_sha,
828 gint *img_data_len,
829 gsize buffer_size,
830 gchar **error_msg)
832 gboolean rvalue = TRUE;
834 IRRECO_ENTER
836 if(irreco_file_exists(img_path)) {
837 if(irreco_read_binary_file(img_path,
838 *img_data,
839 buffer_size,
840 img_data_len)) {
841 *img_sha = g_compute_checksum_for_data(
842 G_CHECKSUM_SHA1,
843 *img_data,
844 *img_data_len);
845 } else {
846 IRRECO_DEBUG("File read failed\n");
847 *error_msg = "File read failed\n";
848 rvalue = FALSE;
850 } else {
851 IRRECO_DEBUG("No such file\n");
852 *error_msg = "No such file\n";
853 rvalue = FALSE;
856 IRRECO_RETURN_BOOL(rvalue)
861 * Update shown preview image
863 static void _update_preview(IrrecoThemeUploadDlg *self)
865 IRRECO_ENTER
867 /* if theme contains preview image, use it, else get first button */
868 if(self->preview_name) {
869 IRRECO_DEBUG("Preview set in dlg, using it\n");
870 } else if(strlen(self->theme->preview_button_name->str) != 0) {
871 gchar *strtblkey;
872 IRRECO_DEBUG("Preview set to theme, using it\n");
873 strtblkey = g_strdup_printf("%s/%s", self->theme->name->str,
874 self->theme->preview_button_name->str);
875 /*IRRECO_DEBUG("key: %s\n", strtblkey);*/
876 if(irreco_string_table_get(self->theme->buttons,
877 strtblkey,
878 (gpointer *) &self->preview_button)) {
879 self->preview_name = self->preview_button->image_up->str;
880 } else {
881 IRRECO_DEBUG("Theme preview set wrong\n");
883 } else {
884 const gchar *key;
885 IRRECO_DEBUG("No preview set, using first button of theme\n");
886 irreco_string_table_index(self->theme->buttons,
887 0, &key,
888 (gpointer *) &self->preview_button);
889 if(self->preview_button) {
890 self->preview_name = self->preview_button->image_up->str;
894 gtk_image_set_from_file(GTK_IMAGE(self->preview_image),
895 self->preview_name);
897 gtk_widget_show_all(GTK_WIDGET(self));
899 IRRECO_RETURN
902 /** @} */
905 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
906 /* Public Functions */
907 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
910 * Show dialog, and ask user for input.
911 * @param irreco_data Irreco data
912 * @param irreco_theme IrrecoTheme to be uploaded
914 gboolean irreco_theme_upload_dlg_run(GtkWindow *parent_window,
915 IrrecoData *irreco_data,
916 IrrecoTheme *irreco_theme,
917 gchar *user,
918 gchar *password)
920 IrrecoThemeUploadDlg *self;
921 gint response;
922 gboolean loop = TRUE;
923 gboolean rvalue = FALSE;
925 IRRECO_ENTER
927 if(irreco_theme == NULL) { IRRECO_RETURN_BOOL(FALSE); }
929 self = (IrrecoThemeUploadDlg*)irreco_theme_upload_dlg_new(irreco_data,
930 parent_window);
932 self->parent_window = GTK_WINDOW(self);
933 self->irreco_data = irreco_data;
934 self->theme = irreco_theme;
935 self->preview_name = NULL;
936 self->uploading_started = FALSE;
937 self->loader_func_id = 0;
938 self->user = user;
939 self->password = password;
941 /* set things to dialog, cause theme & data wasn't set @ _constructed */
942 gtk_entry_set_text(GTK_ENTRY(self->entry_name), self->theme->name->str);
943 self->buffer_comments = gtk_text_view_get_buffer(
944 GTK_TEXT_VIEW(self->textview_comments));
945 gtk_text_buffer_set_text(GTK_TEXT_BUFFER(self->buffer_comments),
946 self->theme->comment->str,
947 -1);
948 _update_preview(self);
950 do {
951 response = gtk_dialog_run(GTK_DIALOG(self));
952 switch (response) {
953 case GTK_RESPONSE_OK:
954 IRRECO_DEBUG("GTK_RESPONSE_OK\n");
956 if(self->uploading_started) {
957 IRRECO_DEBUG("Already uploading theme\n");
958 break;
961 /* Check themename length and get texts */
962 if(!_texts_ok(self)) {
963 IRRECO_DEBUG("Input failure\n");
964 break;
967 /* Show login/reg dialog */
968 if(self->user == NULL || self->password == NULL)
969 if(!irreco_show_login_dlg(irreco_data,
970 parent_window,
971 &self->user,
972 &self->password)) {
973 IRRECO_DEBUG("Failed login\n");
974 break;
977 /* set new info to theme */
978 irreco_theme_set_author(self->theme, self->user);
979 irreco_theme_set_comment(self->theme, self->comments);
980 if(!self->preview_button) {
981 irreco_error_dlg(GTK_WINDOW(self),
982 "Please select preview image first");
983 break;
985 irreco_theme_set_preview_button(self->theme,
986 self->preview_button->name->str);
987 self->uploading_started = TRUE;
988 self->loader_state = LOADER_STATE_INIT;
989 IRRECO_DEBUG("Start loader\n");
990 _loader_start(self);
992 break;
994 case GTK_RESPONSE_DELETE_EVENT:
995 IRRECO_DEBUG("GTK_RESPONSE_DELETE_EVENT\n");
996 _loader_stop(self);
997 if(self->uploading_started) {
998 irreco_info_dlg(GTK_WINDOW(self),
999 "Theme uploading aborted");
1001 loop = FALSE;
1002 break;
1004 case GTK_RESPONSE_CLOSE:
1005 IRRECO_DEBUG("GTK_RESPONSE_CLOSE\n");
1006 _loader_stop(self);
1007 loop = FALSE;
1008 rvalue = TRUE;
1009 break;
1011 default:
1012 IRRECO_DEBUG("Something went horribly wrong\n");
1013 break;
1016 } while (loop);
1018 gtk_widget_destroy(GTK_WIDGET(self));
1020 IRRECO_RETURN_BOOL(rvalue);
1023 /** @} */
1027 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
1028 /* Events and Callbacks */
1029 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
1032 * @name Events and Callbacks
1033 * @{
1037 * Run button browser where one button can be selected
1038 * Stores selected buttons name and buttonstructure
1040 static void _run_button_browser_dlg(GtkWidget *widget,
1041 GdkEventButton *event,
1042 IrrecoThemeUploadDlg *self)
1044 IrrecoThemeButton *preview_theme_button = NULL;
1046 IRRECO_ENTER
1048 preview_theme_button = irreco_button_browser_dlg_run(
1049 GTK_WINDOW(self),
1050 self->irreco_data,
1051 self->theme);
1053 if(preview_theme_button) {
1054 IRRECO_DEBUG("Set preview button to theme and self->\n");
1055 self->preview_name = preview_theme_button->image_up->str;
1056 self->preview_button = preview_theme_button;
1057 _update_preview(self);
1060 IRRECO_RETURN
1063 /** @} */
1067 /** @} */