Vertical scroll bar follows cursor position.
[irreco.git] / irreco / src / core / irreco_remote_upload_dlg.c
blob66ab393ad68f0f9a37b116235d3752194998b608
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_client.h"
25 /** Loader states. */
26 enum
28 LOADER_STATE_INIT,
29 LOADER_STATE_CONFIGURATIONS,
30 LOADER_STATE_THEMES,
31 LOADER_STATE_END
35 /**
36 * @addtogroup IrrecoRemoteUploadDlg
37 * @ingroup Irreco
39 * @todo PURPOCE OF CLASS.
41 * @{
44 /**
45 * @file
46 * Source file of @ref IrrecoRemoteUploadDlg.
50 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
51 /* Prototypes */
52 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
54 void irreco_remote_upload_dlg_comment_size_request(GtkWidget *widget,
55 GtkRequisition *requisition,
56 IrrecoRemoteUploadDlg *self);
58 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
59 /* Construction & Destruction */
60 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
62 /**
63 * @name Construction & Destruction
64 * @{
67 G_DEFINE_TYPE(IrrecoRemoteUploadDlg, irreco_remote_upload_dlg, IRRECO_TYPE_DLG)
69 static void irreco_remote_upload_dlg_dispose(GObject *object)
71 G_OBJECT_CLASS(irreco_remote_upload_dlg_parent_class)->dispose(object);
74 static void irreco_remote_upload_dlg_finalize(GObject *object)
76 G_OBJECT_CLASS(irreco_remote_upload_dlg_parent_class)->finalize(object);
79 static void irreco_remote_upload_dlg_class_init(
80 IrrecoRemoteUploadDlgClass *klass)
82 GObjectClass *object_class = G_OBJECT_CLASS (klass);
85 object_class->dispose = irreco_remote_upload_dlg_dispose;
86 object_class->finalize = irreco_remote_upload_dlg_finalize;
89 static void irreco_remote_upload_dlg_init(IrrecoRemoteUploadDlg *self)
91 GtkWidget *table;
92 GtkWidget *label_category;
93 GtkWidget *label_manufacturer;
94 GtkWidget *label_model;
95 GtkWidget *label_comment;
96 GtkWidget *align;
97 GtkWidget *comment_frame;
98 IRRECO_ENTER
100 /* Build the dialog */
101 gtk_window_set_title(GTK_WINDOW(self), _("Upload Remote"));
102 gtk_window_set_modal(GTK_WINDOW(self), TRUE);
103 gtk_window_set_destroy_with_parent(GTK_WINDOW(self), TRUE);
104 gtk_dialog_set_has_separator(GTK_DIALOG(self), FALSE);
105 gtk_dialog_add_buttons(GTK_DIALOG(self),
106 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
107 GTK_STOCK_OK, GTK_RESPONSE_OK,
108 NULL);
110 /* labels */
112 label_category = gtk_label_new("Category: ");
113 label_manufacturer = gtk_label_new("Manufacturer: ");
114 label_model = gtk_label_new("Model: ");
115 label_comment = gtk_label_new("Comment: ");
117 gtk_misc_set_alignment(GTK_MISC(label_category), 0, 0.5);
118 gtk_misc_set_alignment(GTK_MISC(label_manufacturer), 0, 0.5);
119 gtk_misc_set_alignment(GTK_MISC(label_model), 0, 0.5);
120 gtk_misc_set_alignment(GTK_MISC(label_comment), 0, 0.5);
122 /* entries */
124 self->category = gtk_combo_box_entry_new_text();
125 self->manufacturer = gtk_combo_box_entry_new_text();
126 self->model = gtk_entry_new();
128 /* comment textview */
130 self->comment = gtk_text_view_new();
131 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(self->comment),
132 GTK_WRAP_WORD_CHAR);
134 comment_frame = gtk_frame_new(NULL);
135 gtk_container_add(GTK_CONTAINER(comment_frame), self->comment);
137 /* table */
139 table = gtk_table_new(5, 2, FALSE);
141 gtk_table_attach(GTK_TABLE(table), label_category, 0, 1, 0, 1,
142 GTK_FILL, GTK_FILL, 0, 2);
143 gtk_table_attach(GTK_TABLE(table), label_manufacturer, 0, 1, 1, 2,
144 GTK_FILL, GTK_FILL, 0, 2);
145 gtk_table_attach(GTK_TABLE(table), label_model, 0, 1, 2, 3,
146 GTK_FILL, GTK_FILL, 0, 2);
147 gtk_table_attach(GTK_TABLE(table), label_comment, 0, 1, 3, 4,
148 GTK_FILL, GTK_FILL, 0, 2);
149 gtk_table_attach(GTK_TABLE(table), self->category, 1, 2, 0, 1,
150 GTK_FILL, GTK_FILL, 0, 2);
151 gtk_table_attach(GTK_TABLE(table), self->manufacturer, 1, 2, 1, 2,
152 GTK_FILL, GTK_FILL, 0, 2);
153 gtk_table_attach(GTK_TABLE(table), self->model, 1, 2, 2, 3,
154 GTK_FILL, GTK_FILL, 0, 0);
155 gtk_table_attach(GTK_TABLE(table), comment_frame, 0, 2, 4, 5,
156 GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0);
158 /* scroll */
160 self->scroll = gtk_scrolled_window_new(NULL, NULL);
161 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(self->scroll),
162 GTK_POLICY_NEVER,
163 GTK_POLICY_AUTOMATIC);
164 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(self->scroll),
165 table);
167 /* alignment */
169 align = gtk_alignment_new(0.5, 0.5, 1, 1);
170 gtk_alignment_set_padding(GTK_ALIGNMENT(align), 12, 12, 12, 12);
172 gtk_container_add(GTK_CONTAINER(align), self->scroll);
173 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(self)->vbox),
174 GTK_WIDGET(align));
176 /* Signals */
177 g_signal_connect(G_OBJECT(self->comment), "size-request", G_CALLBACK(
178 irreco_remote_upload_dlg_comment_size_request), self);
180 gtk_widget_set_size_request(GTK_WIDGET(self), -1, 280);
182 gtk_widget_show_all(GTK_WIDGET(self));
184 IRRECO_RETURN
187 IrrecoRemoteUploadDlg* irreco_remote_upload_dlg_new(IrrecoData *irreco_data,
188 GtkWindow *parent)
190 IrrecoRemoteUploadDlg *self;
191 IRRECO_ENTER
193 self = g_object_new(IRRECO_TYPE_REMOTE_UPLOAD_DLG, NULL);
194 irreco_dlg_set_parent(IRRECO_DLG(self), parent);
195 self->irreco_data = irreco_data;
196 IRRECO_RETURN_PTR(self);
200 /** @} */
204 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
205 /* Private Functions */
206 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
209 * @name Private Functions
210 * @{
213 gboolean irreco_remote_upload_dlg_populate_category(IrrecoRemoteUploadDlg *self)
215 IrrecoStringTable *categories = NULL;
216 IrrecoWebdbCache *webdb_cache;
217 IRRECO_ENTER
219 webdb_cache = irreco_data_get_webdb_cache(self->irreco_data, FALSE);
221 /* Get categories */
222 if(irreco_webdb_cache_get_all_categories(webdb_cache, &categories)) {
223 IRRECO_STRING_TABLE_FOREACH_KEY(categories, key)
225 gtk_combo_box_append_text(
226 GTK_COMBO_BOX(self->category), key);
228 IRRECO_STRING_TABLE_FOREACH_END
229 } else {
230 irreco_error_dlg(GTK_WINDOW(self),
231 irreco_webdb_cache_get_error(webdb_cache));
232 IRRECO_RETURN_BOOL(FALSE);
235 if (categories != NULL) irreco_string_table_free(categories);
237 IRRECO_RETURN_BOOL(TRUE);
240 gboolean irreco_remote_upload_dlg_populate_manufacturer(
241 IrrecoRemoteUploadDlg *self)
243 IrrecoStringTable *manufacturers = NULL;
244 IrrecoWebdbCache *webdb_cache;
245 IRRECO_ENTER
247 webdb_cache = irreco_data_get_webdb_cache(self->irreco_data, FALSE);
249 /* Get manufacturers */
250 if(irreco_webdb_cache_get_all_manufacturers(webdb_cache,
251 &manufacturers)) {
252 IRRECO_STRING_TABLE_FOREACH_KEY(manufacturers, key)
254 gtk_combo_box_append_text(
255 GTK_COMBO_BOX(self->manufacturer), key);
257 IRRECO_STRING_TABLE_FOREACH_END
258 } else {
259 irreco_error_dlg(GTK_WINDOW(self),
260 irreco_webdb_cache_get_error(webdb_cache));
261 IRRECO_RETURN_BOOL(FALSE);
264 if (manufacturers != NULL) irreco_string_table_free(manufacturers);
265 IRRECO_RETURN_BOOL(TRUE);
268 gboolean irreco_remote_upload_dlg_send(IrrecoRemoteUploadDlg *self)
270 IrrecoWebdbCache *webdb_cache;
271 IrrecoButtonLayout *layout;
272 gboolean rvalue = FALSE;
273 IRRECO_ENTER
274 webdb_cache = irreco_data_get_webdb_cache(self->irreco_data, FALSE);
275 layout = self->irreco_data->window_manager->current_layout;
277 switch (self->loader_state) {
279 case LOADER_STATE_INIT: {
280 gchar *category = NULL;
281 gchar *manufacturer = NULL;
282 const gchar *model;
283 gchar *comment = NULL;
284 GtkTextIter start;
285 GtkTextIter end;
286 GtkTextBuffer *buffer;
287 GString *path = g_string_new(irreco_get_config_dir("irreco"));
288 gchar *file_data = NULL;
289 gint file_length;
290 IRRECO_DEBUG("LOADER_STATE_INIT");
292 category = gtk_combo_box_get_active_text(
293 GTK_COMBO_BOX(self->category));
295 manufacturer = gtk_combo_box_get_active_text(
296 GTK_COMBO_BOX(self->manufacturer));
298 model = gtk_entry_get_text(GTK_ENTRY(self->model));
300 /* comment */
302 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(self->comment));
303 gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(buffer), &start);
304 gtk_text_buffer_get_end_iter(GTK_TEXT_BUFFER(buffer), &end);
305 comment = gtk_text_buffer_get_text(GTK_TEXT_BUFFER(buffer),
306 &start, &end, FALSE);
308 /* data */
310 g_string_append_printf(path,"/%s",layout->filename->str);
311 file_length = irreco_file_length(path->str);
312 file_data = g_malloc0(file_length);
314 /* check errors */
316 if (!irreco_read_text_file(path->str, file_data, file_length)) {
317 irreco_error_dlg(GTK_WINDOW(self),
318 "Can't open layout file.");
319 goto end_init;
322 if (strlen(category) == 0) {
323 irreco_error_dlg(GTK_WINDOW(self),
324 "Empty category field.");
325 goto end_init;
328 if (strlen(manufacturer) == 0) {
329 irreco_error_dlg(GTK_WINDOW(self),
330 "Empty manufacturer field.");
331 goto end_init;
334 if (strlen(model) == 0) {
335 irreco_error_dlg(GTK_WINDOW(self),
336 "Empty model field.");
337 goto end_init;
340 if (strlen(comment) == 0) {
341 irreco_error_dlg(GTK_WINDOW(self),
342 "Empty comment field.");
345 /* Show login dialog */
347 if (!irreco_show_login_dlg(self->irreco_data, GTK_WINDOW(self),
348 &self->user_name, &self->password)) {
349 IRRECO_DEBUG("Failed login\n");
350 goto end_init;
353 /* create remote to db */
355 self->remote_id = irreco_webdb_client_create_new_remote(
356 webdb_cache->private, layout->name->str,
357 comment, category, manufacturer, model,
358 layout->filename->str, file_data,
359 self->user_name, self->password);
361 if (self->remote_id != 0) {
362 rvalue = TRUE;
364 end_init:
365 if (category != NULL) g_free(category);
366 if (manufacturer != NULL) g_free(manufacturer);
367 if (comment != NULL) g_free(comment);
368 if (file_data != NULL) g_free(file_data);
369 g_string_free(path, FALSE);
371 if (rvalue == TRUE) {
372 self->loader_state = LOADER_STATE_CONFIGURATIONS;
373 } else {
374 self->loader_state = LOADER_STATE_END;
377 IRRECO_RETURN_BOOL(TRUE);
379 case LOADER_STATE_CONFIGURATIONS:
380 IRRECO_DEBUG("LOADER_STATE_CONFIGURATIONS\n");
381 self->loader_state = LOADER_STATE_THEMES;
382 IRRECO_RETURN_BOOL(TRUE);
383 case LOADER_STATE_THEMES: {
384 gboolean rvalue = TRUE;
385 IrrecoStringTable *themes = NULL;
386 IRRECO_DEBUG("LOADER_STATE_THEMES\n");
388 if (!irreco_layout_get_themes(self->irreco_data,
389 layout->name->str, &themes)) {
390 goto end_themes;
393 IRRECO_STRING_TABLE_FOREACH(themes, name, gchar *, date) {
394 gint id;
395 id = irreco_webdb_client_get_theme_id_by_name_and_date(
396 webdb_cache->private, name, date);
398 if (id == 0) {
400 /* Get theme */
402 IrrecoTheme *theme;
403 irreco_string_table_get(
404 self->irreco_data->theme_manager->themes,
405 name, (gpointer*) &theme);
407 /* Upload theme to database */
409 if (!irreco_theme_upload_dlg_run(GTK_WINDOW(self),
410 self->irreco_data,
411 theme)) {
412 rvalue = FALSE;
415 id = irreco_webdb_client_get_theme_id_by_name_and_date(
416 webdb_cache->private, theme->name->str,
417 theme->version->str);
420 /* Append theme to remote */
422 if (id != 0) {
423 irreco_webdb_client_add_theme_to_remote(
424 webdb_cache->private, self->remote_id,
425 id, self->user_name, self->password);
428 IRRECO_STRING_TABLE_FOREACH_END
430 /* Set remote downloadable according to the rvalue */
432 irreco_webdb_client_set_remote_downloadable(
433 webdb_cache->private, self->remote_id,
434 rvalue, self->user_name, self->password);
435 end_themes:
436 if (themes != NULL) irreco_string_table_free(themes);
438 self->loader_state = LOADER_STATE_END;
439 IRRECO_RETURN_BOOL(TRUE);
441 case LOADER_STATE_END:
442 IRRECO_DEBUG("LOADER_STATE_END\n");
443 g_source_remove(self->loader_func_id);
446 IRRECO_RETURN_BOOL(FALSE);
449 /** @} */
453 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
454 /* Public Functions */
455 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
458 * @name Public Functions
459 * @{
462 void irreco_show_remote_upload_dlg(IrrecoData *irreco_data, GtkWindow *parent)
464 IrrecoRemoteUploadDlg *self;
465 gboolean loop = TRUE;
466 IRRECO_ENTER
468 self = irreco_remote_upload_dlg_new(irreco_data, parent);
470 irreco_remote_upload_dlg_populate_category(self);
471 irreco_remote_upload_dlg_populate_manufacturer(self);
473 do {
474 gint response = gtk_dialog_run(GTK_DIALOG(self));
475 switch (response) {
476 case GTK_RESPONSE_CANCEL:
477 IRRECO_DEBUG("GTK_RESPONSE_CANCEL\n");
478 loop = FALSE;
479 break;
481 case GTK_RESPONSE_OK:
482 IRRECO_DEBUG("GTK_RESPONSE_OK\n");
483 self->loader_state = LOADER_STATE_INIT;
484 self->loader_func_id = g_idle_add((GSourceFunc)
485 irreco_remote_upload_dlg_send, self);
486 break;
489 } while (loop);
491 gtk_widget_destroy(GTK_WIDGET(self));
492 IRRECO_RETURN
495 /** @} */
499 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
500 /* Events and Callbacks */
501 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
504 * @name Events and Callbacks
505 * @{
508 void irreco_remote_upload_dlg_comment_size_request(GtkWidget *widget,
509 GtkRequisition *requisition,
510 IrrecoRemoteUploadDlg *self)
512 GtkAdjustment* vadjustment = gtk_scrolled_window_get_vadjustment(
513 GTK_SCROLLED_WINDOW(self->scroll));
514 IRRECO_ENTER
516 if (requisition->height > self->cursor_position) {
517 vadjustment->value += 27;
518 } else if (requisition->height < self->cursor_position) {
519 vadjustment->value -= 27;
521 self->cursor_position = requisition->height;
523 IRRECO_RETURN
526 /** @} */
528 /** @} */