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"
25 #include <hildon/hildon-color-button.h>
26 #include <hildon/hildon-file-chooser-dialog.h>
27 #include "irreco_webdb_client.h"
29 #define MAX_IMG_SIZE 1024*1000
33 * @addtogroup IrrecoThemeUploadDlg
36 * Allow user to set theme settings and upload it.
43 * Source file of @ref IrrecoThemeUploadDlg.
48 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
50 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
52 #define IRRECO_THEME_UPLOAD_PREVIEW_WIDHT (IRRECO_SCREEN_WIDTH / 6)
53 #define IRRECO_THEME_UPLOAD_PREVIEW_HEIGHT (IRRECO_SCREEN_HEIGHT / 6)
57 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
59 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
60 static gboolean
_texts_ok(IrrecoThemeUploadDlg
*self
);
61 static gboolean
_send_theme(IrrecoThemeUploadDlg
*self
);
62 static void _update_preview(IrrecoThemeUploadDlg
*self
);
63 static void _run_button_browser_dlg(GtkWidget
*widget
,
64 GdkEventButton
*event
,
65 IrrecoThemeUploadDlg
*self
);
66 static gboolean
_get_image_data_and_hash(gchar
* img_path
,
72 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
73 /* Construction & Destruction */
74 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
77 * @name Construction & Destruction
81 G_DEFINE_TYPE(IrrecoThemeUploadDlg
, irreco_theme_upload_dlg
,
82 IRRECO_TYPE_INTERNAL_DLG
)
84 static void irreco_theme_upload_dlg_constructed(GObject
*object
)
86 IrrecoThemeUploadDlg
*self
;
89 GtkWidget
*vbox_preview
;
90 GtkWidget
*label_name
;
91 GtkWidget
*label_comments
;
92 GtkWidget
*label_preview
;
93 GtkWidget
*scrolled_comments
;
95 GtkWidget
*frame_comments
;
96 GtkWidget
*frame_preview
;
100 G_OBJECT_CLASS(irreco_theme_upload_dlg_parent_class
)->constructed(object
);
101 self
= IRRECO_THEME_UPLOAD_DLG(object
);
103 self
->comments
= NULL
;
105 /* Construct dialog. */
106 gtk_window_set_title(GTK_WINDOW(self
), _("Upload theme"));
107 gtk_window_set_modal(GTK_WINDOW(self
), TRUE
);
108 gtk_window_set_destroy_with_parent(GTK_WINDOW(self
), TRUE
);
109 gtk_dialog_set_has_separator(GTK_DIALOG(self
), FALSE
);
110 gtk_dialog_add_buttons(GTK_DIALOG(self
),
111 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
112 GTK_STOCK_OK
, GTK_RESPONSE_OK
,
115 /* Create widgets. */
116 hbox_lr
= gtk_hbox_new(FALSE
, 10);
117 vbox_preview
= gtk_vbox_new(FALSE
, 0);
118 label_name
= gtk_label_new("Theme name:");
119 label_comments
= gtk_label_new("Comments:");
120 label_preview
= gtk_label_new("Select\npreview image:");
121 self
->entry_name
= gtk_entry_new();
122 self
->textview_comments
= gtk_text_view_new();
123 frame_comments
= gtk_frame_new(NULL
);
126 self
->preview_image
= gtk_image_new();
127 gtk_image_set_from_file(GTK_IMAGE(self
->preview_image
), NULL
);
128 frame_preview
= gtk_frame_new(NULL
);
129 self
->preview_event_box
= gtk_event_box_new();
130 gtk_container_add(GTK_CONTAINER(frame_preview
), self
->preview_image
);
131 gtk_container_add(GTK_CONTAINER(self
->preview_event_box
), frame_preview
);
132 gtk_widget_set_size_request(frame_preview
, 200,200);
135 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(self
->textview_comments
),
137 gtk_widget_set_size_request(self
->textview_comments
, 400, 150);
138 scrolled_comments
= gtk_scrolled_window_new(NULL
, NULL
);
139 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_comments
),
141 GTK_POLICY_AUTOMATIC
);
142 table
= gtk_table_new(4, 2, FALSE
);
145 gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(self
)->vbox
),
147 gtk_box_pack_start_defaults(GTK_BOX(hbox_lr
), table
);
148 gtk_box_pack_end_defaults(GTK_BOX(hbox_lr
), vbox_preview
);
149 gtk_box_pack_start_defaults(GTK_BOX(vbox_preview
), label_preview
);
150 gtk_box_pack_end_defaults(GTK_BOX(vbox_preview
), self
->preview_event_box
);
151 gtk_container_add(GTK_CONTAINER(scrolled_comments
), self
->textview_comments
);
152 gtk_container_add (GTK_CONTAINER (frame_comments
), scrolled_comments
);
153 gtk_table_attach_defaults(GTK_TABLE(table
), label_name
, 0, 1, 0, 1);
154 gtk_table_attach_defaults(GTK_TABLE(table
), self
->entry_name
, 1, 2, 0, 1);
155 gtk_table_attach_defaults(GTK_TABLE(table
), label_comments
, 0, 1, 1, 2);
156 gtk_table_attach_defaults(GTK_TABLE(table
), frame_comments
, 0, 2, 2, 3);
159 /* Connect preview eventbox and start dialog from there */
160 g_signal_connect(G_OBJECT(self
->preview_event_box
),
161 "button-release-event",
162 G_CALLBACK(_run_button_browser_dlg
),
163 IRRECO_THEME_UPLOAD_DLG(self
));
165 gtk_widget_show_all(GTK_WIDGET(self
));
169 static void irreco_theme_upload_dlg_init(IrrecoThemeUploadDlg
*self
)
172 /*self->theme_name = g_string_new(NULL);
173 self->author = g_string_new(NULL);
174 self->comments = g_string_new(NULL);*/
178 static void irreco_theme_upload_dlg_finalize(GObject
*object
)
180 IrrecoThemeUploadDlg
*self
;
183 self
= IRRECO_THEME_UPLOAD_DLG(object
);
184 /*g_string_free(self->theme_name, TRUE);
185 self->theme_name = NULL;
186 g_string_free(self->author, TRUE);
188 g_string_free(self->comments, TRUE);
189 self->comments = NULL;*/
191 G_OBJECT_CLASS(irreco_theme_upload_dlg_parent_class
)->finalize(object
);
195 static void irreco_theme_upload_dlg_class_init(IrrecoThemeUploadDlgClass
*klass
)
197 GObjectClass
* object_class
= G_OBJECT_CLASS (klass
);
198 /* IrrecoDlgClass* parent_class = IRRECO_DLG_CLASS (klass); */
200 object_class
->finalize
= irreco_theme_upload_dlg_finalize
;
201 object_class
->constructed
= irreco_theme_upload_dlg_constructed
;
204 GtkWidget
*irreco_theme_upload_dlg_new(IrrecoData
*irreco_data
,
205 GtkWindow
*parent_window
)
207 IrrecoThemeUploadDlg
*self
;
210 self
= g_object_new(IRRECO_TYPE_THEME_UPLOAD_DLG
,
211 "irreco-data", irreco_data
,
213 irreco_dlg_set_parent(IRRECO_DLG(self
), parent_window
);
214 IRRECO_RETURN_PTR(self
);
219 * @todo Replace calls to irreco_theme_upload_dlg_create() with
220 * irreco_theme_upload_dlg_new().
222 IrrecoThemeUploadDlg
*irreco_theme_upload_dlg_create(IrrecoData
*irreco_data
,
223 GtkWindow
*parent_window
)
226 IRRECO_RETURN_PTR(irreco_theme_upload_dlg_new(
227 irreco_data
, parent_window
));
232 * @todo Replace calls to irreco_theme_upload_dlg_destroy() with
233 * gtk_widget_destroy().
235 void irreco_theme_upload_dlg_destroy(IrrecoThemeUploadDlg
* self
)
238 gtk_widget_destroy(GTK_WIDGET(self
));
239 if(self
->comments
!= NULL
) {
240 g_free(self
->comments
);
241 self
->comments
= NULL
;
250 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
251 /* Private Functions */
252 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
254 * @name Private Functions
258 /* Check textfields, return TRUE if everythings fine */
259 static gboolean
_texts_ok(IrrecoThemeUploadDlg
*self
)
261 gboolean rvalue
= TRUE
;
262 GtkTextIter startiter
;
264 /*GtkTextBuffer *buffer_comments;*/
268 if (self
->comments
!= NULL
) g_free(self
->comments
);
270 self
->theme_name
= gtk_entry_get_text(GTK_ENTRY(self
->entry_name
));
271 IRRECO_DEBUG("Theme name len:%d\n",
272 (gint
)g_utf8_strlen(self
->theme_name
, -1));
273 if((gint
)g_utf8_strlen(self
->theme_name
, -1) == 0) {
275 irreco_error_dlg(GTK_WINDOW(self
),
276 "Too short theme name.\n"
277 "Name must be at least 1 character.");
280 gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(self
->buffer_comments
),
282 gtk_text_buffer_get_end_iter(GTK_TEXT_BUFFER(self
->buffer_comments
),
284 self
->comments
= gtk_text_buffer_get_text(
285 GTK_TEXT_BUFFER(self
->buffer_comments
),
289 IRRECO_DEBUG("theme comments: %s\n", self
->comments
);
290 IRRECO_DEBUG("theme name: %s\n", self
->theme_name
);
292 IRRECO_RETURN_BOOL(rvalue
);
295 /* Upload theme and all written stuff, return TRUE if everything went fine */
296 static gboolean
_send_theme(IrrecoThemeUploadDlg
*self
)
299 IrrecoWebdbClient
*client
;
304 /* Parse folder out from theme path */
305 parsedpath
= g_utf8_strrchr(self
->theme
->path
->str
, -1, G_DIR_SEPARATOR
);
306 parsedpath
= g_utf8_find_next_char(parsedpath
, NULL
);
307 IRRECO_DEBUG("parsed theme path:%s\n", parsedpath
);
309 client
= irreco_webdb_client_new();
311 IRRECO_DEBUG("\nthemename: %s\ncomm: %s\nprevname: %s\nthemepath: %s\nusr: %s\npassu: %s\n", self
->theme_name
, self
->comments
, self
->theme
->preview_button_name
->str
, parsedpath
, self
->user
, self
->password
);
313 themeindex
= irreco_webdb_client_create_theme(client
,
316 self
->theme
->preview_button_name
->str
,
321 if(themeindex
== 0) {
322 IRRECO_RETURN_BOOL(TRUE
);
325 IRRECO_STRING_TABLE_FOREACH_DATA(self
->theme
->buttons
,
329 gsize buffer_size
= MAX_IMG_SIZE
;
330 guchar
*img_up_data
= g_malloc0(buffer_size
); /* binary datas */
331 guchar
*img_down_data
= g_malloc0(buffer_size
);
332 gchar
*img_up_sha
; /* SHAs */
334 gchar
*img_up_name
; /* filenames */
335 gchar
*img_down_name
;
336 gint img_up_len
; /* img data lengths */
338 GString
*img_folder
= g_string_new(NULL
); /* folder of button */
341 IRRECO_DEBUG("Current button: %s\n", button
->name
->str
);
344 if(_get_image_data_and_hash(button
->image_up
->str
,
348 IRRECO_DEBUG("Up sha: %s\n", img_up_sha
);
350 /* Parse folder out from theme img */
351 img_up_name
= g_utf8_strrchr(button
->image_up
->str
,
354 img_up_name
= g_utf8_find_next_char(img_up_name
, NULL
);
355 IRRECO_DEBUG("Parsed img up name: %s\n", img_up_name
);
360 /* multifailtilanne, goto the end */
364 if(_get_image_data_and_hash(button
->image_down
->str
,
368 IRRECO_DEBUG("Down sha: %s\n", img_down_sha
);
370 /* Parse folder out from theme img */
371 img_down_name
= g_utf8_strrchr(button
->image_down
->str
,
374 img_down_name
= g_utf8_find_next_char(img_down_name
, NULL
);
375 IRRECO_DEBUG("Parsed img down name: %s\n", img_down_name
);
377 img_down_data
= NULL
;
379 img_down_name
= NULL
;
382 img_folder
= g_string_new(NULL
);
383 /* Copy whole path+button name */
384 g_string_printf(img_folder
, "%s", button
->image_down
->str
);
385 /* Remove everything past and including rightmost folder character */
386 img_folder
= g_string_erase(img_folder
,
387 strlen(button
->image_down
->str
) -
388 strlen(g_utf8_strrchr(
389 button
->image_down
->str
,
393 /* Remove everything prior rightmost folder character */
394 g_string_printf(img_folder
, "%s", g_utf8_strrchr(img_folder
->str
,
397 /* Remove starting folder character */
398 img_folder
= g_string_erase(img_folder
, 0, 1);
399 IRRECO_DEBUG("button folder: %s\n", img_folder
->str
);
402 button_index
= irreco_webdb_client_add_button_to_theme(
406 button
->text_format_up
->str
,
407 button
->text_format_down
->str
,
408 button
->text_padding
,
422 IRRECO_DEBUG("butt index: %d", button_index
);
424 /*gint irreco_webdb_client_add_button_to_theme(IrrecoWebdbClient *self,
427 const gchar *text_format_up,
428 const gchar *text_format_down,
430 const gchar *image_up_hash,
431 const gchar *image_up_name,
432 const guchar *image_up,
434 const gchar *image_down_hash,
435 const gchar *image_down_name,
436 const guchar *image_down,
441 const gchar *password)*/
443 /* TODO if err msg -> messuboxeittain urputusta */
447 g_free(img_down_data
);
448 img_down_data
= NULL
;
449 g_string_free(img_folder
, TRUE
);
452 IRRECO_STRING_TABLE_FOREACH_END
454 IRRECO_RETURN_BOOL(TRUE
);
457 static gboolean
_get_image_data_and_hash(gchar
*img_path
,
462 gsize buffer_size
= MAX_IMG_SIZE
; /* Max image size 1 Mt */
463 /*gint img_data_len;*/
464 gboolean rvalue
= TRUE
;
468 if(irreco_file_exists(img_path
)) {
469 if(irreco_read_binary_file(img_path
,
473 /*IRRECO_DEBUG("img_data_len: %d\n", img_data_len);*/
474 *img_sha
= sha_compute_checksum_for_data(
478 /*IRRECO_DEBUG("sha1: %s\n", *img_sha);*/
480 IRRECO_DEBUG("File read failed\n");
484 IRRECO_DEBUG("No such file\n");
488 IRRECO_RETURN_BOOL(rvalue
)
492 static void _update_preview(IrrecoThemeUploadDlg
*self
)
496 /* if theme contains preview image, use it, else get some button */
497 if(!self
->preview_name
) {
500 IRRECO_DEBUG("No preview set, get first button\n");
501 irreco_string_table_index(self
->theme
->buttons
,
503 (gpointer
*) &self
->preview_button
);
504 if(self
->preview_button
) {
505 self
->preview_name
= self
->preview_button
->image_up
->str
;
508 IRRECO_DEBUG("preview path: %s\n", self
->preview_name
);
510 gtk_image_set_from_file(GTK_IMAGE(self
->preview_image
),
513 gtk_widget_show_all(GTK_WIDGET(self
));
523 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
524 /* Public Functions */
525 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
528 * Show dialog, and ask user for input.
531 gboolean
irreco_theme_upload_dlg_run(GtkWindow
*parent_window
,
532 IrrecoData
*irreco_data
,
533 IrrecoTheme
* irreco_theme
)
535 IrrecoThemeUploadDlg
*self
;
537 gboolean loop
= TRUE
;
541 if(irreco_theme
== NULL
) { IRRECO_RETURN_BOOL(FALSE
); }
543 self
= irreco_theme_upload_dlg_create(irreco_data
, parent_window
);
545 self
->parent_window
= GTK_WINDOW(self
);
546 self
->irreco_data
= irreco_data
;
547 self
->theme
= irreco_theme
;
548 self
->preview_name
= NULL
;
550 /* set things to dialog, cause theme & data wasn't set @ _constructed */
551 gtk_entry_set_text(GTK_ENTRY(self
->entry_name
), self
->theme
->name
->str
);
552 self
->buffer_comments
= gtk_text_view_get_buffer(
553 GTK_TEXT_VIEW(self
->textview_comments
));
554 gtk_text_buffer_set_text(GTK_TEXT_BUFFER(self
->buffer_comments
),
555 self
->theme
->comment
->str
,
557 _update_preview(self
);
561 response
= gtk_dialog_run(GTK_DIALOG(self
));
564 case GTK_RESPONSE_OK
:
565 IRRECO_DEBUG("GTK_RESPONSE_OK\n");
567 /* Check themename length and get texts */
568 if(!_texts_ok(self
)) {
569 IRRECO_DEBUG("Input failure\n");
573 /* Show login/reg dialog */
574 if(!irreco_show_login_dlg(irreco_data
,
578 IRRECO_DEBUG("Failed login\n\n");
582 /* set new info to theme */
583 irreco_theme_set_author(self
->theme
, self
->user
);
584 /* TODO add setting theme name */
585 irreco_theme_set_comment(self
->theme
, self
->comments
);
586 irreco_theme_set_preview_button(self
->theme
,
587 self
->preview_button
->name
->str
);
589 /* TODO tear theme into pieces and toss 'em into func that shoves bits into soup */
590 if(!_send_theme(self
)) {
591 IRRECO_DEBUG("Failed uploading\n");
594 /* TODO joku success info dialogi */
595 IRRECO_DEBUG("Should show glove dialog\n");
596 IRRECO_DEBUG("Upping went like a glove\n");
600 case GTK_RESPONSE_CANCEL
:
601 IRRECO_DEBUG("GTK_RESPONSE_CANCEL\n");
606 IRRECO_DEBUG("Something went horribly wrong\n");
612 irreco_theme_upload_dlg_destroy(self
);
615 IRRECO_RETURN_BOOL(FALSE
);
622 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
623 /* Events and Callbacks */
624 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
627 * @name Events and Callbacks
631 static void _run_button_browser_dlg(GtkWidget
*widget
,
632 GdkEventButton
*event
,
633 IrrecoThemeUploadDlg
*self
)
635 IrrecoThemeButton
*preview_theme_button
= NULL
;
639 preview_theme_button
= irreco_button_browser_dlg_run(
640 GTK_WINDOW(IRRECO_THEME_UPLOAD_DLG(self
)->parent_window
),
644 if(preview_theme_button
) {
645 IRRECO_DEBUG("Set preview button to theme and self->\n");
646 /* TODO set preview to theme */
647 self
->preview_name
= preview_theme_button
->image_up
->str
;
648 self
->preview_button
= preview_theme_button
;
649 _update_preview(self
);