Fix and remove some obsolete OSSO/D-Bus stuff
[maepad.git] / src / ui / callbacks.c
blob5b039028f3c88eb4525e22fd2ad98c0be3a46c1c
1 /*
2 * This file is part of maemopad+
5 * This software is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public License
7 * as published by the Free Software Foundation; either version 2.1 of
8 * the License, or (at your option) any later version.
10 * This software is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this software; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
22 #include <ui/callbacks.h>
23 #include <ui/interface.h>
24 #include <gtk/gtk.h>
25 #include <gdk/gdkkeysyms.h>
26 #include <libintl.h>
28 #include <glib.h>
31 * strlen needed from string.h
33 #include <string.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <unistd.h>
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <config.h>
40 #include <time.h>
42 #include <hildon/hildon.h>
43 #include <hildon/hildon-banner.h>
44 #include <hildon/hildon-note.h>
45 #include <hildon/hildon-font-selection-dialog.h>
46 #include <tablet-browser-interface.h>
48 #include <libgnomevfs/gnome-vfs.h>
50 #include "sketchwidget.h"
52 #include "../he/he-about-dialog.h"
53 #include "../he/he-simple-color-dialog.h"
56 * "Busy" status handling
58 * Use "busy_reset" to reset the busy status (turn off)
59 * Use "busy_enter" when starting time-consuming processing
60 * Use "busy_leave" when processing has been finished
62 typedef enum {
63 BUSY_RESET = 0,
64 BUSY_INCREMENT,
65 BUSY_DECREMENT,
66 } SetBusyType;
68 /* Don't use this directly, but make use of the macros defined below */
69 void set_busy(MainView* mainview, SetBusyType update);
71 #define busy_reset(mainview) set_busy(mainview, BUSY_RESET)
72 #define busy_enter(mainview) set_busy(mainview, BUSY_INCREMENT)
73 #define busy_leave(mainview) set_busy(mainview, BUSY_DECREMENT)
77 * Privates:
79 gboolean read_file_to_buffer(MainView * mainview);
80 void write_buffer_to_file(MainView * mainview);
81 void new_node_dialog(nodeType typ, MainView * mainview);
82 gboolean foreach_func_update_ord (GtkTreeModel *model,GtkTreePath *path,GtkTreeIter *iter, MainView *mainview);
83 void move_nodes_up(GtkTreeModel * model, GtkTreeRowReference * topnode, GtkTreeRowReference * newtop);
84 GtkTreeRowReference *iter2ref(GtkTreeModel * model, GtkTreeIter * iter);
85 gboolean exec_command_on_db(MainView *mainview,char sql_string[]);
86 int get_node_id_on_tmp_db(GtkTreeModel *model,GtkTreeIter *iter);
87 gint get_branch_node_index(GtkTreePath *path);
88 gboolean move_node(MainView *mainview,GtkTreeIter *new_parent,GtkTreeIter *item_to_move,GtkTreeIter *item_befor);
89 gboolean tree_model_iter_prev(GtkTreeModel *tree_model,GtkTreeIter *iter);
90 gboolean show_confirmation(MainView* mainview, gchar* question);
94 gboolean callback_node_view_window_state(GtkWidget* window,
95 GdkEventWindowState* event, gpointer user_data)
97 MainView* mainview = (MainView*)user_data;
98 GtkWidget* sketch_scroll = NULL;
100 if (mainview->toolbar == NULL || mainview->sk == NULL) {
101 return FALSE;
104 sketch_scroll = GTK_WIDGET(sketchwidget_get_mainwidget(mainview->sk));
106 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
107 if (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) {
108 gtk_widget_hide(mainview->toolbar);
109 gtk_scrolled_window_set_policy(
110 GTK_SCROLLED_WINDOW(sketch_scroll),
111 GTK_POLICY_NEVER,
112 GTK_POLICY_NEVER);
113 } else {
114 gtk_widget_show(mainview->toolbar);
115 gtk_scrolled_window_set_policy(
116 GTK_SCROLLED_WINDOW(sketch_scroll),
117 GTK_POLICY_AUTOMATIC,
118 GTK_POLICY_AUTOMATIC);
122 return FALSE;
125 void set_busy(MainView* mainview, SetBusyType update)
127 switch (update) {
128 case BUSY_RESET:
129 mainview->busyrefcount = 0;
130 break;
131 case BUSY_INCREMENT:
132 mainview->busyrefcount++;
133 break;
134 case BUSY_DECREMENT:
135 if (mainview->busyrefcount > 0) {
136 mainview->busyrefcount--;
138 break;
139 default:
140 g_error("Wrong type in set_busy: %d", update);
141 break;
144 hildon_gtk_window_set_progress_indicator(GTK_WINDOW(mainview->data->main_view), (mainview->busyrefcount > 0));
145 hildon_gtk_window_set_progress_indicator(GTK_WINDOW(mainview->data->node_view), (mainview->busyrefcount > 0));
148 void prepareUIforNodeChange(MainView * mainview, nodeType typ)
150 gtk_widget_set_sensitive(GTK_WIDGET(mainview->undo_tb), TRUE);
151 gtk_widget_set_sensitive(GTK_WIDGET(mainview->redo_tb), TRUE);
153 if (typ == NODE_TEXT)
155 gtk_widget_show(GTK_WIDGET(mainview->font_tb));
156 gtk_widget_show(GTK_WIDGET(mainview->bold_tb));
157 gtk_widget_show(GTK_WIDGET(mainview->italic_tb));
158 gtk_widget_show(GTK_WIDGET(mainview->underline_tb));
159 gtk_widget_show(GTK_WIDGET(mainview->bullet_tb));
160 gtk_widget_show(mainview->tools_font);
161 gtk_widget_show(mainview->tools_wordwrap);
163 else
165 gtk_widget_hide(GTK_WIDGET(mainview->font_tb));
166 gtk_widget_hide(GTK_WIDGET(mainview->bold_tb));
167 gtk_widget_hide(GTK_WIDGET(mainview->italic_tb));
168 gtk_widget_hide(GTK_WIDGET(mainview->underline_tb));
169 gtk_widget_hide(GTK_WIDGET(mainview->bullet_tb));
170 gtk_widget_hide(mainview->tools_font);
171 gtk_widget_hide(mainview->tools_wordwrap);
174 if (typ == NODE_SKETCH)
176 /* gtk_widget_show(GTK_WIDGET(mainview->colorbutton_tb));*/
177 gtk_widget_show(GTK_WIDGET(mainview->eraser_tb));
178 gtk_widget_show(GTK_WIDGET(mainview->brushsize_tb));
179 gtk_widget_show(GTK_WIDGET(mainview->sketchlines_tb));
180 gtk_widget_show(GTK_WIDGET(mainview->shape_tb));
181 gtk_widget_show(mainview->tools_color);
182 gtk_widget_show(mainview->tools_brushsize);
183 gtk_widget_show(mainview->tools_pagestyle);
184 gtk_widget_show(mainview->tools_shape);
185 gtk_widget_show(mainview->tools_pressure);
187 else
189 /* gtk_widget_hide(GTK_WIDGET(mainview->colorbutton_tb));*/
190 gtk_widget_hide(GTK_WIDGET(mainview->eraser_tb));
191 gtk_widget_hide(GTK_WIDGET(mainview->brushsize_tb));
192 gtk_widget_hide(GTK_WIDGET(mainview->sketchlines_tb));
193 gtk_widget_hide(GTK_WIDGET(mainview->shape_tb));
194 gtk_widget_hide(mainview->tools_color);
195 gtk_widget_hide(mainview->tools_brushsize);
196 gtk_widget_hide(mainview->tools_pagestyle);
197 gtk_widget_hide(mainview->tools_shape);
198 gtk_widget_hide(mainview->tools_pressure);
201 if (typ == NODE_CHECKLIST)
203 gtk_widget_show(GTK_WIDGET(mainview->bold_tb));
204 gtk_widget_show(GTK_WIDGET(mainview->strikethru_tb));
205 gtk_widget_show(GTK_WIDGET(mainview->check_tb));
206 gtk_widget_show(GTK_WIDGET(mainview->checkadd_tb));
207 gtk_widget_show(GTK_WIDGET(mainview->checkdel_tb));
208 gtk_widget_hide(GTK_WIDGET(mainview->undo_tb));
209 gtk_widget_hide(GTK_WIDGET(mainview->redo_tb));
211 else
213 gtk_widget_hide(GTK_WIDGET(mainview->strikethru_tb));
214 gtk_widget_hide(GTK_WIDGET(mainview->check_tb));
215 gtk_widget_hide(GTK_WIDGET(mainview->checkadd_tb));
216 gtk_widget_hide(GTK_WIDGET(mainview->checkdel_tb));
217 gtk_widget_show(GTK_WIDGET(mainview->undo_tb));
218 gtk_widget_show(GTK_WIDGET(mainview->redo_tb));
221 if (typ == NODE_TEXT)
223 gtk_widget_hide(GTK_WIDGET(mainview->colorbutton_tb));
224 gtk_widget_hide(sketchwidget_get_mainwidget(mainview->sk));
225 gtk_widget_hide(mainview->listscroll);
226 gtk_widget_show(GTK_WIDGET(mainview->scrolledwindow));
227 gtk_widget_show(mainview->tools_item);
229 else if (typ == NODE_SKETCH)
231 gtk_widget_show(GTK_WIDGET(mainview->colorbutton_tb));
232 gtk_widget_hide(GTK_WIDGET(mainview->scrolledwindow));
233 gtk_widget_hide(mainview->listscroll);
234 gtk_widget_show(sketchwidget_get_mainwidget(mainview->sk));
235 gtk_widget_show(mainview->tools_item);
237 else if (typ == NODE_CHECKLIST)
239 gtk_widget_show(GTK_WIDGET(mainview->colorbutton_tb));
240 gtk_widget_hide(GTK_WIDGET(mainview->scrolledwindow));
241 gtk_widget_hide(sketchwidget_get_mainwidget(mainview->sk));
242 gtk_widget_hide(mainview->tools_item);
243 gtk_widget_show(mainview->listscroll);
245 else
247 gtk_widget_hide(GTK_WIDGET(mainview->colorbutton_tb));
248 gtk_widget_hide(GTK_WIDGET(mainview->scrolledwindow));
249 gtk_widget_hide(sketchwidget_get_mainwidget(mainview->sk));
250 gtk_widget_hide(mainview->tools_item);
251 gtk_widget_hide(mainview->listscroll);
255 nodeData *getSelectedNode(MainView * mainview)
257 GtkTreeIter iter;
258 GtkTreeModel *model;
260 nodeData *nd;
262 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
264 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
265 return (NULL);
267 gtk_tree_model_get(model, &iter, NODE_DATA, &nd, -1);
269 return (nd);
272 void saveCurrentData(MainView * mainview)
274 nodeData *selnode = getSelectedNode(mainview);
275 saveDataToNode(mainview, selnode);
278 void saveDataToNode(MainView * mainview, nodeData *selnode)
280 if (selnode == NULL)
281 return;
283 if (
284 (selnode->typ == NODE_SKETCH && sketchwidget_get_edited(mainview->sk) == FALSE) ||
285 (selnode->typ == NODE_TEXT && wp_text_buffer_is_modified(mainview->buffer)==FALSE) ||
286 (selnode->typ == NODE_CHECKLIST && mainview->checklist_edited==FALSE)
289 fprintf(stderr, "node not edited, not saving\n");
290 return;
293 mainview->file_edited = TRUE;
295 busy_enter(mainview);
296 fprintf(stderr, "savecurrentdata!\n");
298 gboolean goterr = TRUE;
299 gchar *textdata = NULL;
300 GdkPixbuf *pixbuf = NULL;
301 gchar *sketchdata = NULL;
302 gsize datalen = 0;
303 char tq[512];
305 if (selnode->typ == NODE_TEXT)
307 #if 0
308 GtkTextIter start, end;
309 gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(mainview->buffer), &start, &end);
310 textdata = gtk_text_buffer_serialize_rich_text(GTK_TEXT_BUFFER(mainview->buffer), &start, &end, &datalen);
311 #endif
313 GString *gstr=g_string_sized_new(4096);
314 wp_text_buffer_save_document(mainview->buffer, (WPDocumentSaveCallback)(wp_savecallback), gstr);
316 datalen=gstr->len;
317 textdata=g_string_free(gstr, FALSE);
318 /*fprintf(stderr, "*%s*\n", textdata);*/
320 /* g_snprintf(tq, sizeof(tq), "UPDATE %s SET bodytype=%d, bodyblob=NULL, body=?, flags=%d WHERE nodeid=%d", datatable_tmpname, selnode->typ, selnode->flags, selnode->sql3id);*/
321 g_snprintf(tq, sizeof(tq), "UPDATE %s SET bodytype=%d, bodyblob=?, body=NULL, flags=%d WHERE nodeid=%d", datatable_tmpname, selnode->typ, selnode->flags, selnode->sql3id);
323 else if (selnode->typ == NODE_SKETCH)
325 GError *err = NULL;
326 GdkPixmap *skpix = sketchwidget_get_Pixmap(mainview->sk);
327 GtkWidget *skdr = sketchwidget_get_drawingarea(mainview->sk);
329 pixbuf = gdk_pixbuf_get_from_drawable(NULL, GDK_DRAWABLE(skpix), NULL, 0, 0, 0, 0, skdr->allocation.width, skdr->allocation.height);
330 if (pixbuf == NULL)
332 fprintf(stderr, "Error saving: pixbuf is null\n");
334 else
336 double w, h;
337 GdkPixbuf *pixbuf2 = sketchwidget_trim_image(pixbuf, skdr->allocation.width, skdr->allocation.height, &w, &h, FALSE);
339 if (pixbuf2!=NULL)
341 if (gdk_pixbuf_save_to_buffer(pixbuf2, &sketchdata, &datalen, "png", &err, NULL) == FALSE)
343 sketchdata = NULL;
344 datalen = 0;
345 fprintf(stderr, "Error saving sketch! %s\n", err->message);
346 g_error_free(err);
348 gdk_pixbuf_unref(pixbuf2);
351 g_snprintf(tq, sizeof(tq), "UPDATE %s SET bodytype=%d, body=NULL, bodyblob=?, flags=%d WHERE nodeid=%d", datatable_tmpname, selnode->typ, selnode->flags, selnode->sql3id);
352 fprintf(stderr, "datalen:%d\n", datalen);
353 if (skpix && G_IS_OBJECT(skpix)) g_object_unref(skpix);
355 else if (selnode->typ == NODE_CHECKLIST)
357 g_snprintf(tq, sizeof(tq), "UPDATE %s SET bodytype=%d, body=NULL, bodyblob=NULL, flags=%d WHERE nodeid=%d", datatable_tmpname, selnode->typ, selnode->flags, selnode->sql3id);
360 /*fprintf(stderr, "query is *%s*\n", tq); */
364 sqlite3_stmt *stmt = NULL;
365 const char *dum;
366 int rc = sqlite3_prepare(mainview->db, tq, strlen(tq), &stmt, &dum);
368 if (rc)
370 fprintf(stderr, "Error updating: %s\n", sqlite3_errmsg(mainview->db));
371 break;
373 if (selnode->typ == NODE_TEXT)
374 sqlite3_bind_text(stmt, 1, textdata, datalen, /*strlen(textdata),*/ SQLITE_TRANSIENT);
375 else if (selnode->typ == NODE_SKETCH)
376 sqlite3_bind_blob(stmt, 1, sketchdata, datalen, SQLITE_TRANSIENT);
378 rc = SQLITE_BUSY;
379 while(rc == SQLITE_BUSY)
381 rc = sqlite3_step(stmt);
382 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE || rc == SQLITE_DONE)
383 break;
385 sqlite3_finalize(stmt);
387 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE)
389 fprintf(stderr, "Error saving node: %s\n", sqlite3_errmsg(mainview->db));
391 else
393 if (selnode->typ == NODE_TEXT)
394 gtk_text_buffer_set_modified(GTK_TEXT_BUFFER(mainview->buffer), FALSE);
395 else if (selnode->typ == NODE_SKETCH)
396 sketchwidget_set_edited(mainview->sk, FALSE);
397 else if (selnode->typ == NODE_CHECKLIST)
398 mainview->checklist_edited = FALSE;
399 goterr = FALSE;
401 }while(FALSE);
403 while(goterr==FALSE && selnode->typ == NODE_CHECKLIST)
405 GtkTreeModel *model=gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->listview));
407 char tq[512];
408 g_snprintf(tq, sizeof(tq), "DELETE FROM %s WHERE nodeid=%d", checklisttable_tmpname, selnode->sql3id);
409 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
411 GtkTreeIter iter;
412 if (gtk_tree_model_get_iter_first(model, &iter)==FALSE) break;
416 gint styletoset_weight;
417 gboolean styletoset_strike;
418 gboolean ischecked;
419 gchar *text;
420 gchar *color;
421 unsigned long col=0;
423 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHECKNODE_BOLD, &styletoset_weight, CHECKNODE_STRIKE, &styletoset_strike, CHECKNODE_CHECKED, &ischecked, CHECKNODE_TEXT, &text, CHECKNODE_COLOR, &color, -1);
425 GdkColor tmpcol;
426 if (color!=NULL && strcmp(color, "(null)")!=0 && gdk_color_parse(color, &tmpcol))
428 col=((tmpcol.red>>8)<<16)|((tmpcol.green>>8)<<8)|(tmpcol.blue>>8);
429 /* fprintf(stderr, "calculated color for node is *%lu*\n", col);*/
432 gint style=0;
433 if (ischecked) style|=CHECKSTYLE_CHECKED;
434 if (styletoset_weight==PANGO_WEIGHT_BOLD) style|=CHECKSTYLE_BOLD;
435 if (styletoset_strike) style|=CHECKSTYLE_STRIKE;
437 g_snprintf(tq, sizeof(tq), "INSERT INTO %s (nodeid, name, style, color, ord) VALUES(%d, ?, %d, %lu, 0)", checklisttable_tmpname, selnode->sql3id, style, col);
438 sqlite3_stmt *stmt = NULL;
439 const char *dum;
440 int rc = sqlite3_prepare(mainview->db, tq, strlen(tq), &stmt, &dum);
442 if (rc)
444 goterr=TRUE;
445 fprintf(stderr, "Error while saving checklist: %s\n", sqlite3_errmsg(mainview->db));
446 break;
448 sqlite3_bind_text(stmt, 1, text, strlen(text), SQLITE_TRANSIENT);
450 rc = SQLITE_BUSY;
451 while(rc == SQLITE_BUSY)
453 rc = sqlite3_step(stmt);
454 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE || rc == SQLITE_DONE)
455 break;
457 sqlite3_finalize(stmt);
459 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE)
461 goterr=TRUE;
462 fprintf(stderr, "Error while saving checklist (2): %s\n", sqlite3_errmsg(mainview->db));
465 g_free(color);
466 g_free(text);
468 }while(gtk_tree_model_iter_next(model, &iter)==TRUE);
470 break;
473 if (textdata)
474 g_free(textdata);
475 if (sketchdata)
476 g_free(sketchdata);
477 if (goterr == TRUE)
479 show_banner(mainview, _("Error saving memo"));
481 busy_leave(mainview);
484 gboolean callback_treeview_button_press(GtkTreeView* treeview, GdkEventButton* event, gpointer user_data)
486 MainView* mainview = (MainView*)user_data;
488 mainview->can_show_node_view = TRUE;
490 return FALSE;
493 void callback_treeview_celldatafunc(GtkTreeViewColumn * tree_column, GtkCellRenderer * cell, GtkTreeModel * tree_model, GtkTreeIter * iter, gpointer data)
495 MainView *mainview = ( MainView * ) data;
496 g_assert(mainview != NULL && mainview->data != NULL );
498 nodeData *nd;
500 gtk_tree_model_get(tree_model, iter, NODE_DATA, &nd, -1);
501 if (nd == NULL)
502 return;
504 if (nd->namepix == NULL)
506 g_object_set(cell, "visible", FALSE, NULL);
508 else
510 g_object_set(cell, "visible", TRUE, NULL);
511 g_object_set(cell, "width", SKETCHNODE_RX, NULL);
512 g_object_set(cell, "height", SKETCHNODE_RY, NULL);
517 gboolean callback_treeview_testcollapse(GtkTreeView * treeview, GtkTreeIter * arg1, GtkTreePath * arg2, gpointer user_data)
519 return (FALSE);
522 void callback_treeview_change(GtkTreeSelection * selection, gpointer data)
524 MainView *mainview = (MainView *) data;
525 g_assert(mainview != NULL && mainview->data != NULL);
527 nodeData *nd = getSelectedNode(mainview);
529 gchar* nodeName = _("View node");
531 if (nd != NULL && nd->name != NULL) {
532 nodeName = nd->name;
535 /* Show node view with selected node */
536 gtk_window_set_title(GTK_WINDOW(mainview->data->node_view),
537 nodeName);
539 if (mainview->can_show_node_view) {
540 gtk_widget_show(GTK_WIDGET(mainview->data->node_view));
543 /* Make sure we don't accidentally collapse any nodes */
544 gtk_tree_view_expand_all(GTK_TREE_VIEW(mainview->treeview));
547 if (nd==NULL)
548 fprintf(stderr, "changed called but no selectednode\n");
549 else
550 fprintf(stderr, "changed called, selectednode is %d\n", nd->sql3id);
552 #ifdef NEW_SEL_LOGIC
553 guint tm=time(NULL);
554 if (mainview->cansel_time>0 && mainview->cansel_time+1.0<tm) mainview->cansel_node=NULL;
556 if (nd==NULL)
558 if (mainview->cansel_node!=NULL)
560 fprintf(stderr, "[SELLOGIC] saving %d to unselect all nodes\n", (mainview->cansel_node)->sql3id);
561 saveDataToNode(mainview, (mainview->cansel_node));
562 mainview->cansel_node=NULL;
564 return;
567 if (mainview->cansel_node!=NULL)
569 if (nd->sql3id == (mainview->cansel_node)->sql3id)
571 mainview->cansel_node=NULL;
572 fprintf(stderr, "[SELLOGIC] doubly selected %d, doing nothing\n", nd->sql3id);
573 return;
575 else
577 fprintf(stderr, "[SELLOGIC] saving %d to load new node\n", (mainview->cansel_node)->sql3id);
578 saveDataToNode(mainview, (mainview->cansel_node));
579 mainview->cansel_node=NULL;
582 #endif
584 if (nd == NULL) return;
586 busy_enter(mainview);
588 gboolean goterr = TRUE;
589 char *textdata = NULL;
590 char *blob = NULL;
591 int blobsize = 0, textsize = 0;
593 char tq[512];
595 g_snprintf(tq, sizeof(tq), "SELECT bodytype, body, bodyblob, flags FROM %s WHERE nodeid=%d", datatable_tmpname, nd->sql3id);
596 sqlite3_stmt *stmt = NULL;
597 const char *dum;
598 int rc = sqlite3_prepare(mainview->db, tq, strlen(tq), &stmt, &dum);
600 if (rc)
602 fprintf(stderr, "Error reading (1) %s\n", sqlite3_errmsg(mainview->db));
604 else
606 rc = SQLITE_BUSY;
607 while(rc == SQLITE_BUSY || rc == SQLITE_ROW)
609 rc = sqlite3_step(stmt);
610 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE || rc == SQLITE_DONE)
611 break;
612 else if (rc == SQLITE_ROW)
614 nd->typ = sqlite3_column_int(stmt, 0);
615 nd->flags = sqlite3_column_int(stmt, 3);
617 prepareUIforNodeChange(mainview, nd->typ);
618 if (nd->typ == NODE_TEXT)
620 gboolean file_edited_backup = mainview->file_edited;
622 blobsize = sqlite3_column_bytes(stmt, 2);
623 blob = (char *)sqlite3_column_blob(stmt, 2);
625 textdata = (char *)sqlite3_column_text(stmt, 1);
626 textsize = sqlite3_column_bytes(stmt, 1);
628 /* gtk_text_buffer_set_text(GTK_TEXT_BUFFER(mainview->buffer), "", -1);*/
629 wp_text_buffer_reset_buffer(mainview->buffer, TRUE);
631 gboolean richtext=FALSE;
633 if (blob != NULL)
635 #if 0
636 gboolean oldway=FALSE;
637 if (blobsize>8)
639 char tst[8];
640 strncpy(tst, blob, 8);
641 tst[8]=0;
642 if (strcmp(tst, "RICHTEXT")==0) oldway=TRUE;
644 if (oldway)
646 GError *err = NULL;
647 GtkTextIter iter;
648 gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(mainview->buffer), &iter);
649 gtk_text_buffer_deserialize_rich_text(GTK_TEXT_BUFFER(mainview->buffer), &iter, blob, blobsize, TRUE, &err);
650 if (err != NULL)
652 fprintf(stderr, "Error loading text memo with richtext parser! %s\n", err->message);
653 g_error_free(err);
655 else
657 richtext=TRUE;
660 #endif
662 if (richtext==FALSE)
664 wp_text_buffer_load_document_begin(mainview->buffer, TRUE);
665 wp_text_buffer_load_document_write(mainview->buffer, blob, blobsize);
666 wp_text_buffer_load_document_end(mainview->buffer);
667 richtext=TRUE;
670 if (richtext==FALSE && !(textdata == NULL || g_utf8_validate(textdata, textsize, NULL) == FALSE))
672 /* gtk_text_buffer_set_text(GTK_TEXT_BUFFER(mainview->buffer), textdata, textsize);*/
673 wp_text_buffer_load_document_begin(mainview->buffer, FALSE);
674 wp_text_buffer_load_document_write(mainview->buffer, textdata, textsize);
675 wp_text_buffer_load_document_end(mainview->buffer);
678 wp_text_buffer_enable_rich_text(mainview->buffer, TRUE);
679 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->tools_wordwrap), ((nd->flags & NODEFLAG_WORDWRAP) > 0)?TRUE:FALSE);
680 callback_wordwrap(NULL, mainview); /*FIXME:ugly (do we need this? gotta test) */
682 gtk_text_buffer_set_modified(GTK_TEXT_BUFFER(mainview->buffer), FALSE); /*we probably don't need this*/
684 callback_undotoggle((gpointer)mainview->buffer, FALSE, mainview); /*we need these*/
685 callback_redotoggle((gpointer)mainview->buffer, FALSE, mainview);
687 if (file_edited_backup==FALSE) mainview->file_edited=FALSE; /*textview changed event toggles this?*/
688 goterr = FALSE;
690 else if (nd->typ == NODE_SKETCH)
692 sketchwidget_wipe_undo(mainview->sk);
693 sketchwidget_set_fillmode(mainview->sk, FALSE);
694 sketchwidget_set_shift(mainview->sk, FALSE);
695 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->shapemenuitems[1]), TRUE);
696 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->shapemenuitems[0]), TRUE);
698 blobsize = sqlite3_column_bytes(stmt, 2);
699 blob = (char *)sqlite3_column_blob(stmt, 2);
700 gboolean clear = TRUE;
702 if (blob == NULL)
703 goterr = FALSE;
704 if (blob != NULL)
706 fprintf(stderr, "blobsize:%d\n", blobsize);
707 GdkPixbufLoader *pl = gdk_pixbuf_loader_new_with_type("png", NULL);
708 GError *err = NULL;
710 gdk_pixbuf_loader_write(pl, (guchar *) blob, blobsize, &err);
711 if (err != NULL)
713 fprintf(stderr, "Error loading sketch! %s\n", err->message);
714 g_error_free(err);
715 err = NULL;
717 gdk_pixbuf_loader_close(pl, NULL);
718 GdkPixbuf *pixbuf = gdk_pixbuf_loader_get_pixbuf(pl);
720 if (GDK_IS_PIXBUF(pixbuf))
722 GtkWidget *skdr = sketchwidget_get_drawingarea(mainview->sk);
723 GtkPixmap *skpix = (GtkPixmap *) sketchwidget_get_Pixmap(mainview->sk);
725 int w=gdk_pixbuf_get_width(pixbuf);
726 int h=gdk_pixbuf_get_height(pixbuf);
727 if (w!=skdr->allocation.width || h!=skdr->allocation.height)
729 if (w>skdr->allocation.width) w=skdr->allocation.width;
730 if (h>skdr->allocation.height) h=skdr->allocation.height;
731 sketchwidget_clear_real(mainview->sk);
733 gdk_draw_pixbuf(GDK_DRAWABLE(skpix), NULL, pixbuf, 0, 0, 0, 0, w, h, GDK_RGB_DITHER_NONE, 0, 0);
735 clear = FALSE;
736 goterr = FALSE;
738 if (skpix && G_IS_OBJECT(skpix)) g_object_unref(skpix);
740 else
742 fprintf(stderr, "error loading pixbuf\n");
744 g_object_unref(pl);
746 if (clear == TRUE)
748 fprintf(stderr, "clearing pix area\n");
749 sketchwidget_clear_real(mainview->sk);
751 gtk_widget_queue_draw(sketchwidget_get_drawingarea(mainview->sk));
753 else if (nd->typ == NODE_CHECKLIST)
755 mainview->checklist_edited = FALSE;
756 GtkTreeModel *model=gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->listview));
757 g_object_ref(model);
758 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->listview), NULL);
759 gtk_list_store_clear(GTK_LIST_STORE(model));
761 g_snprintf(tq, sizeof(tq), "SELECT name, style, color FROM %s WHERE nodeid=%d ORDER BY ord, idx", checklisttable_tmpname, nd->sql3id);
762 sqlite3_stmt *stmt2 = NULL;
763 const char *dum;
764 int rc = sqlite3_prepare(mainview->db, tq, strlen(tq), &stmt2, &dum);
765 if (rc)
767 fprintf(stderr, "Error reading checklist (1) %s\n", sqlite3_errmsg(mainview->db));
769 else
771 goterr=FALSE;
772 rc = SQLITE_BUSY;
773 while(rc == SQLITE_BUSY || rc == SQLITE_ROW)
775 rc = sqlite3_step(stmt2);
776 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE || rc == SQLITE_DONE)
777 break;
778 else if (rc == SQLITE_ROW)
780 char *textdata = (char *)sqlite3_column_text(stmt2, 0);
781 int style = sqlite3_column_int(stmt2, 1);
782 unsigned long col = sqlite3_column_int(stmt2, 2);
784 GtkTreeIter toplevel;
785 gtk_list_store_append(GTK_LIST_STORE(model), &toplevel);
786 gtk_list_store_set(GTK_LIST_STORE(model), &toplevel, CHECKNODE_TEXT, textdata, CHECKNODE_CHECKED, FALSE, -1);
787 if ((style & CHECKSTYLE_CHECKED)>0) {
788 gtk_list_store_set(GTK_LIST_STORE(model), &toplevel, CHECKNODE_CHECKED, TRUE, -1);
789 gtk_list_store_set(GTK_LIST_STORE(model), &toplevel, CHECKNODE_ICON_NAME, "widgets_tickmark_list", -1);
791 if ((style & CHECKSTYLE_BOLD)>0) gtk_list_store_set(GTK_LIST_STORE(model), &toplevel, CHECKNODE_BOLD, PANGO_WEIGHT_BOLD, -1);
792 if ((style & CHECKSTYLE_STRIKE)>0) gtk_list_store_set(GTK_LIST_STORE(model), &toplevel, CHECKNODE_STRIKE, TRUE, -1);
794 if (col>0)
796 char tmp[10];
797 g_snprintf(tmp, sizeof(tmp), "#%02lx%02lx%02lx", ((col & 0xFF0000) >> 16), ((col & 0xFF00) >> 8), (col & 0xFF));
798 /* fprintf(stderr, "read color for node is *%s*\n", tmp);*/
799 gtk_list_store_set(GTK_LIST_STORE(model), &toplevel, CHECKNODE_COLOR, tmp, -1);
804 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE)
806 fprintf(stderr, "Error reading checklist (2) %s\n", sqlite3_errmsg(mainview->db));
807 goterr=TRUE;
810 sqlite3_finalize(stmt2);
813 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->listview), model);
814 g_object_unref(model);
817 if ((nd->flags & NODEFLAG_SKETCHLINES) > 0)
818 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->sketchlinesmenuitems[1]), TRUE);
819 else if ((nd->flags & NODEFLAG_SKETCHGRAPH) > 0)
820 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->sketchlinesmenuitems[2]), TRUE);
821 else
823 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->sketchlinesmenuitems[0]), TRUE);
824 callback_sketchlines(NULL, mainview->sketchlinesmenuitems[0]); /*FIXME:ugly */
826 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->tools_pressure), TRUE);
828 break;
831 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE)
832 fprintf(stderr, "Error reading (2) %s\n", sqlite3_errmsg(mainview->db));
834 sqlite3_finalize(stmt);
837 busy_leave(mainview);
839 if (goterr == TRUE)
841 show_banner(mainview, _("Error loading memo"));
845 gboolean treeview_canselect(GtkTreeSelection * selection, GtkTreeModel * model, GtkTreePath * path, gboolean path_currently_selected, gpointer userdata)
847 MainView *mainview = (MainView *) userdata;
848 g_assert(mainview != NULL && mainview->data != NULL);
850 if (mainview->loading==FALSE)
852 #ifndef EXPANDING_ROWS
853 if (path_currently_selected)
854 return (FALSE);
855 #endif
857 #ifndef NEW_SEL_LOGIC
858 saveCurrentData(mainview);
859 #else
860 if (path_currently_selected)
862 GtkTreeIter iter;
863 gtk_tree_model_get_iter(model, &iter, path);
865 gtk_tree_model_get(model, &iter, NODE_DATA, &(mainview->cansel_node), -1);
866 mainview->cansel_time=time(NULL);
867 /* fprintf(stderr, "[SELLOGIC] canselect called for node %d\n", nd->sql3id);*/
869 #endif
871 return (TRUE);
874 gboolean newnodedlg_key_press_cb(GtkWidget * widget, GdkEventKey * event, GtkWidget * dlg)
876 SketchWidget *s = gtk_object_get_data(GTK_OBJECT(dlg), "sk");
878 switch (event->keyval)
880 case GDK_F7:
881 sketchwidget_redo(s);
882 return TRUE;
883 case GDK_F8:
884 sketchwidget_undo(s);
885 return TRUE;
887 return FALSE;
891 /* This struct will hold all our toggle buttons, so we can
892 * only allow one to be active at a time (i.e. radio buttons) */
893 typedef struct _newNodeToggleButtons newNodeToggleButtons;
894 struct _newNodeToggleButtons
896 GtkWidget *rbt; /* Text */
897 GtkWidget *rbs; /* Sketch */
898 GtkWidget *rbc; /* Checklist */
901 void show_sketch_widget(GtkWidget *widget, gpointer user_data)
903 GtkWidget *dialog = (GtkWidget*)user_data;
905 /* Show the sketch widget and hide the entry + draw button */
906 gtk_widget_show(gtk_object_get_data(GTK_OBJECT(dialog), "al"));
907 gtk_widget_hide(gtk_object_get_data(GTK_OBJECT(dialog), "draw_button"));
908 gtk_widget_hide(gtk_object_get_user_data(GTK_OBJECT(dialog)));
911 void new_node_dialog(nodeType typ, MainView * mainview)
913 GtkWidget *dialog, *entry, *but_ok, *vbox, *hbox, *al, *cb;
914 GtkWidget *rb1, *rb2, *rb3;
915 GtkWidget *hb;
916 gchar datetime_str[200];
917 time_t t_now;
918 struct tm *tm_now;
919 gboolean datetime_written = FALSE;
921 t_now = time(NULL);
922 tm_now = localtime(&t_now);
924 if (tm_now != NULL) {
925 if (strftime(datetime_str, sizeof(datetime_str), "%y-%m-%d %H:%M", tm_now) != 0) {
926 datetime_written = TRUE;
930 if (datetime_written == FALSE) {
931 /* Was not able to determine a datetime string - use default */
932 fprintf(stderr, "Warning: cannot resolve time!\n");
933 strncpy(datetime_str, _("New memo"), sizeof(datetime_str));
934 datetime_str[sizeof(datetime_str)-1] = '\0';
937 newNodeToggleButtons *nntb = g_malloc(sizeof(newNodeToggleButtons));
939 dialog = gtk_dialog_new();
940 gtk_window_set_title(GTK_WINDOW(dialog), _("Create new memo"));
941 gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
943 g_signal_connect(G_OBJECT(dialog), "key_press_event", G_CALLBACK(newnodedlg_key_press_cb), dialog);
945 vbox = gtk_vbox_new(FALSE, 0);
947 hbox = gtk_hbox_new(TRUE, 0);
949 /* Text note toggle button */
950 rb1 = hildon_gtk_radio_button_new(HILDON_SIZE_FINGER_HEIGHT, NULL);
951 gtk_button_set_label(GTK_BUTTON(rb1), _("Rich text"));
952 gtk_button_set_image(GTK_BUTTON(rb1), gtk_image_new_from_file(PIXMAPDIR "/text.png"));
953 gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(rb1), TRUE, TRUE, 0);
954 nntb->rbt = rb1;
956 /* Sketch toggle button */
957 rb2 = hildon_gtk_radio_button_new_from_widget(HILDON_SIZE_FINGER_HEIGHT, GTK_RADIO_BUTTON(rb1));
958 gtk_button_set_label(GTK_BUTTON(rb2), _("Sketch"));
959 gtk_button_set_image(GTK_BUTTON(rb2), gtk_image_new_from_file(PIXMAPDIR "/sketch.png"));
960 gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(rb2), TRUE, TRUE, 0);
961 nntb->rbs = rb2;
963 /* Checklist toggle button */
964 rb3 = hildon_gtk_radio_button_new_from_widget(HILDON_SIZE_FINGER_HEIGHT, GTK_RADIO_BUTTON(rb1));
965 gtk_button_set_label(GTK_BUTTON(rb3), _("Checklist"));
966 gtk_button_set_image(GTK_BUTTON(rb3), gtk_image_new_from_file(PIXMAPDIR "/checklist.png"));
967 gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(rb3), TRUE, TRUE, 0);
968 nntb->rbc = rb3;
970 /* Set mode to 0 to get correct styling */
971 gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(rb1), FALSE);
972 gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(rb2), FALSE);
973 gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(rb3), FALSE);
975 /* Remember "new note toggle buttons" list */
976 gtk_object_set_data(GTK_OBJECT(dialog), "nntb", nntb);
978 if (typ == NODE_TEXT) {
979 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rb1), TRUE);
980 } else if (typ == NODE_SKETCH) {
981 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rb2), TRUE);
982 } else {
983 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rb3), TRUE);
986 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
988 but_ok = gtk_dialog_add_button(GTK_DIALOG(dialog), _("Create"), GTK_RESPONSE_OK);
989 g_signal_connect(G_OBJECT(but_ok), "clicked", G_CALLBACK(callback_new_node_real), dialog);
991 gtk_object_set_data(GTK_OBJECT(dialog), "m", mainview);
993 hb = gtk_hbox_new(FALSE, 10);
994 gtk_box_pack_start(GTK_BOX(hb), gtk_label_new(_("Name:")), FALSE, FALSE, 0);
995 entry = hildon_entry_new(HILDON_SIZE_AUTO);
996 gtk_object_set_user_data(GTK_OBJECT(dialog), entry);
997 gtk_entry_set_text(GTK_ENTRY(entry), datetime_str);
998 gtk_editable_select_region(GTK_EDITABLE(entry), 0, -1);
999 gtk_box_pack_start(GTK_BOX(hb), entry, TRUE, TRUE, 0);
1001 /* Sketch widget, hidden by default */
1002 al = gtk_alignment_new(0.5, 0.5, 0, 0);
1003 SketchWidget *s = sketchwidget_new(SKETCHNODE_X, SKETCHNODE_Y, TRUE);
1004 gtk_object_set_data(GTK_OBJECT(dialog), "sk", s);
1005 gtk_object_set_data(GTK_OBJECT(dialog), "al", al);
1006 sketchwidget_set_brushsize(s, 2);
1007 sketchwidget_set_backstyle(s, SKETCHBACK_GRAPH);
1008 gtk_widget_set_size_request(sketchwidget_get_mainwidget(s), SKETCHNODE_X, SKETCHNODE_Y);
1009 gtk_container_add(GTK_CONTAINER(al), sketchwidget_get_mainwidget(s));
1010 gtk_box_pack_start(GTK_BOX(hb), al, FALSE, FALSE, 0);
1012 /*but_sketch = hildon_button_new_with_text(
1013 HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH,
1014 HILDON_BUTTON_ARRANGEMENT_VERTICAL,
1015 _("Use sketch label"), NULL);
1017 gtk_object_set_data(GTK_OBJECT(dialog), "draw_button", but_sketch);
1018 gtk_signal_connect(GTK_OBJECT(but_sketch), "clicked", G_CALLBACK(show_sketch_widget), dialog);
1019 gtk_box_pack_start(GTK_BOX(hb), but_sketch, FALSE, TRUE, 0);*/
1020 gtk_box_pack_start(GTK_BOX(vbox), hb, TRUE, FALSE, 0);
1022 cb = hildon_check_button_new(HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
1023 gtk_button_set_label(GTK_BUTTON(cb), _("Create as child of selected memo"));
1024 hildon_check_button_set_active(HILDON_CHECK_BUTTON(cb), mainview->newnodedialog_createchild);
1025 gtk_box_pack_start(GTK_BOX(vbox), cb, FALSE, FALSE, 0);
1027 gtk_object_set_data(GTK_OBJECT(dialog), "cb", cb);
1029 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), vbox);
1031 gtk_widget_grab_focus(entry);
1033 gtk_widget_show_all(dialog);
1035 /* Hide the sketch widget at first */
1036 gtk_widget_hide(al);
1037 gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
1040 void add_new_node(nodeData * node, MainView * mainview, gboolean ischild)
1042 GtkTreeIter parentiter, newiter;
1043 GtkTreeModel *model;
1044 void *ptr = NULL;
1046 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
1048 if (gtk_tree_selection_get_selected(selection, &model, &parentiter))
1049 ptr = &parentiter;
1051 GtkTreePath *path = NULL;
1053 unsigned int parentnodeid = 0;
1055 if (ptr != NULL)
1057 path = gtk_tree_model_get_path(model, &parentiter);
1059 if (ischild == FALSE)
1061 gtk_tree_path_up(path);
1063 if (gtk_tree_path_get_depth(path) == 0)
1065 /* Selected node is a root node */
1066 ptr = NULL; /* New node can not have a Parent node */
1067 gtk_tree_path_down(path); /*restore path so expand() works */
1069 else if (gtk_tree_path_get_depth(path) > 0)
1071 /* Selected node is a child node */
1072 if (gtk_tree_model_get_iter(model, &parentiter, path))
1073 ptr = &parentiter;
1078 if (ptr != NULL)
1080 nodeData *nd;
1082 gtk_tree_model_get(model, ptr, NODE_DATA, &nd, -1);
1083 if (nd)
1084 parentnodeid = nd->sql3id;
1087 node->sql3id = 0;
1090 sqlite3_stmt *stmt = NULL;
1091 const char *dum;
1092 char tq[512];
1095 * FIXME: ord
1097 g_snprintf(tq, sizeof(tq), "INSERT INTO %s (parent, bodytype, name, nameblob, ord) VALUES (%d, %d, ?, ?, 0);", datatable_tmpname, parentnodeid, node->typ);
1098 int rc = sqlite3_prepare(mainview->db, tq, strlen(tq), &stmt, &dum);
1100 if (rc)
1102 fprintf(stderr, "Error inserting(1): %s\n", sqlite3_errmsg(mainview->db));
1103 break;
1105 if (node->name != NULL)
1106 sqlite3_bind_text(stmt, 1, node->name, strlen(node->name), SQLITE_TRANSIENT);
1107 else
1108 sqlite3_bind_text(stmt, 1, NULL, 0, SQLITE_TRANSIENT);
1110 if (node->namepix != NULL)
1112 gchar *namepixdata = NULL;
1113 gsize datalen = 0;
1115 GError *err = NULL;
1117 if (gdk_pixbuf_save_to_buffer(node->namepix, &namepixdata, &datalen, "png", &err, NULL) == FALSE)
1119 namepixdata = NULL;
1120 datalen = 0;
1121 fprintf(stderr, "Error saving name! %s\n", err->message);
1122 g_error_free(err);
1124 sqlite3_bind_blob(stmt, 2, namepixdata, datalen, SQLITE_TRANSIENT);
1126 else
1127 sqlite3_bind_blob(stmt, 2, NULL, 0, SQLITE_TRANSIENT);
1129 rc = SQLITE_BUSY;
1130 while(rc == SQLITE_BUSY)
1132 rc = sqlite3_step(stmt);
1133 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE || rc == SQLITE_DONE)
1134 break;
1136 sqlite3_finalize(stmt);
1137 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE)
1139 fprintf(stderr, "Error inserting(2): %s\n", sqlite3_errmsg(mainview->db));
1140 break;
1142 node->sql3id = sqlite3_last_insert_rowid(mainview->db);
1144 while(FALSE);
1146 if (node->sql3id == 0)
1148 if (node->name)
1149 g_free(node->name);
1150 if (node->namepix)
1151 g_object_unref(node->namepix);
1152 g_free(node);
1153 if (path)
1154 gtk_tree_path_free(path);
1155 show_banner(mainview, _("Error creating node"));
1156 return;
1159 gtk_tree_store_append(GTK_TREE_STORE(model), &newiter, ptr);
1161 gtk_tree_store_set(GTK_TREE_STORE(model), &newiter, NODE_NAME, node->name, NODE_PIXBUF, node->namepix, NODE_DATA, node, -1);
1163 if (path)
1165 mainview->loading=TRUE; /*only when we have a valid parent*/
1166 gtk_tree_view_expand_row(GTK_TREE_VIEW(mainview->treeview), path, FALSE);
1167 gtk_tree_path_free(path);
1170 gtk_tree_selection_select_iter(selection, &newiter);
1172 mainview->loading=FALSE;
1175 void callback_new_node_real(GtkAction * action, gpointer data)
1177 MainView *mainview;
1179 GtkWidget *dialog = data;
1180 GtkWidget *entry = gtk_object_get_user_data(GTK_OBJECT(dialog));
1182 mainview = gtk_object_get_data(GTK_OBJECT(dialog), "m");
1183 SketchWidget *s = gtk_object_get_data(GTK_OBJECT(dialog), "sk");
1184 GtkWidget *cb = gtk_object_get_data(GTK_OBJECT(dialog), "cb");
1185 newNodeToggleButtons *nntb = gtk_object_get_data(GTK_OBJECT(dialog), "nntb");
1187 nodeType typ = NODE_TEXT;
1188 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(nntb->rbs))) {
1189 typ = NODE_SKETCH;
1190 } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(nntb->rbc))) {
1191 typ = NODE_CHECKLIST;
1193 g_free(nntb);
1195 gchar *txt = NULL;
1197 /*if (GTK_WIDGET_VISIBLE(entry))
1199 txt = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
1200 if (strcmp(txt, "") == 0)
1202 g_free(txt);
1203 return;
1206 else
1208 GtkWidget *sdr = sketchwidget_get_drawingarea(s);
1210 GdkPixmap *spix = sketchwidget_get_Pixmap(s);
1212 pixbuf = gdk_pixbuf_get_from_drawable(NULL, GDK_DRAWABLE(spix), NULL, 0, 0, 0, 0, sdr->allocation.width, sdr->allocation.height);
1213 g_object_unref(spix);
1214 double w, h;
1215 GdkPixbuf *pixbuf2 = sketchwidget_trim_image(pixbuf, SKETCHNODE_X, SKETCHNODE_Y, &w,
1216 &h, TRUE);
1217 if (pixbuf2==NULL) return;
1219 GdkPixbuf *pixbuf3 = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, SKETCHNODE_RX,
1220 SKETCHNODE_RY);
1222 gdk_pixbuf_fill(pixbuf3, 0xffffffff);
1224 if (w <= SKETCHNODE_RX && h <= SKETCHNODE_RY)
1226 gdk_pixbuf_copy_area(pixbuf2, 0, 0, w, h, pixbuf3, 0, (SKETCHNODE_RY - h) / 2);
1228 else
1230 double neww, newh;
1232 if (w > h)
1234 neww = SKETCHNODE_RX;
1235 newh = (h / w) * SKETCHNODE_RX;
1237 else
1239 newh = SKETCHNODE_RY;
1240 neww = (w / h) * SKETCHNODE_RY;
1242 if (newh > SKETCHNODE_RY)
1243 newh = SKETCHNODE_RY;
1245 GdkPixbuf *tmpbuf = gdk_pixbuf_scale_simple(pixbuf2, neww, newh,
1246 GDK_INTERP_BILINEAR);
1248 gdk_pixbuf_copy_area(tmpbuf, 0, 0, neww, newh, pixbuf3, 0, (SKETCHNODE_RY - newh) / 2);
1250 gdk_pixbuf_unref(tmpbuf);
1253 pixbuf = pixbuf3;
1254 gdk_pixbuf_unref(pixbuf2);
1257 nodeData *node;
1259 node = g_malloc(sizeof(nodeData));
1260 node->typ = typ;
1261 node->name = txt;
1262 node->namepix = NULL;
1264 /*if (GTK_WIDGET_VISIBLE(entry))
1266 node->name = txt;
1268 else
1270 node->namepix = pixbuf;
1273 node->lastMod = 0;
1274 node->flags = 0;
1275 node->sql3id = 0;
1277 mainview->newnodedialog_createchild = hildon_check_button_get_active(HILDON_CHECK_BUTTON(cb));
1278 add_new_node(node, mainview, mainview->newnodedialog_createchild);
1280 sketchwidget_destroy(s);
1281 gtk_widget_destroy(dialog);
1282 mainview->file_edited = TRUE;
1286 * delete node
1288 void callback_file_delete_node(GtkAction * action, gpointer data)
1290 MainView *mainview = (MainView *) data;
1291 g_assert(mainview != NULL && mainview->data != NULL);
1293 if (getSelectedNode(mainview) == NULL) {
1294 show_banner(mainview, _("Select a node first"));
1295 return;
1298 if (show_confirmation(mainview, _("Delete selected memo?"))) {
1299 callback_delete_node_real(mainview);
1300 gtk_widget_hide(GTK_WIDGET(mainview->data->node_view));
1305 * Callback for Rename Menuitem
1307 void callback_file_rename_node(GtkAction * action, gpointer data)
1309 MainView *mainview = (MainView*)data;
1310 g_assert(mainview != NULL && mainview->data != NULL);
1312 /* Get the selected node */
1313 nodeData *sel_node = getSelectedNode(mainview);
1314 if (sel_node == NULL) {
1315 /* Do nothing, if no node has been selected */
1316 show_banner(mainview, _("Select a node first"));
1317 return;
1320 if (sel_node->namepix != NULL) {
1321 /* the memo has a graphical label, cannot edit! */
1322 show_banner(mainview, _("Cannot rename memos with sketch name"));
1323 return;
1326 gchar* new_name = show_line_edit_dialog(mainview, _("Rename memo"), _("New name:"), _("Rename"), sel_node->name);
1328 /* Only rename node when user accepted the new name */
1329 if (new_name != NULL) {
1330 callback_rename_node_real(mainview, new_name);
1331 g_free(new_name);
1335 void callback_rename_node_real(MainView* mainview, gchar* new_name)
1337 GtkTreeIter iter;
1338 GtkTreeModel *model;
1339 nodeData *nd = NULL;
1341 /* Get the selected node */
1342 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
1344 if (!gtk_tree_selection_get_selected(selection, &model, &iter)) {
1345 return;
1348 gtk_tree_model_get (model, &iter, NODE_DATA, &nd, -1);
1350 if (nd == NULL) {
1351 return;
1354 /* Update the database */
1355 sqlite3_stmt *stmt = NULL;
1357 char* sql = sqlite3_mprintf("UPDATE %s SET name='%q' WHERE nodeid=%d", datatable_tmpname, new_name, nd->sql3id);
1359 int rc = sqlite3_prepare(mainview->db, sql, strlen(sql), &stmt, NULL);
1360 if (rc == SQLITE_OK) {
1361 rc = SQLITE_BUSY;
1362 while (rc == SQLITE_BUSY) {
1363 rc = sqlite3_step(stmt);
1364 if (rc == SQLITE_DONE) {
1365 /* Update in the database was successful - now update the rest */
1367 /* Update the noteData */
1368 g_free(nd->name);
1369 nd->name = g_strdup(new_name);
1371 /* Update the window title of node_view */
1372 gtk_window_set_title(GTK_WINDOW(mainview->data->node_view), nd->name);
1374 /* Update the value in the tree store */
1375 gtk_tree_store_set (GTK_TREE_STORE(model), &iter, NODE_NAME, new_name, -1);
1377 break;
1378 } else if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE) {
1379 fprintf(stderr, "Error updating node: %s\n", sqlite3_errmsg(mainview->db));
1380 break;
1383 sqlite3_finalize(stmt);
1384 } else {
1385 fprintf (stderr, "Error preparing db update query: %s\n", sqlite3_errmsg(mainview->db));
1388 sqlite3_free(sql);
1390 mainview->file_edited = TRUE;
1393 void callback_file_export_node(GtkAction * action, gpointer data)
1395 MainView *mainview = (MainView *) data;
1396 g_assert(mainview != NULL && mainview->data != NULL);
1398 nodeData *nd=getSelectedNode(mainview);
1399 if (nd == NULL)
1401 show_banner(mainview, _("Select a memo first"));
1402 return;
1405 gchar *nodename=nd->name;
1406 if (nodename==NULL) nodename=_("saved memo");
1408 if (nd->typ == NODE_TEXT)
1411 GtkTextIter begin, end;
1412 gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER(mainview->buffer), &begin, &end);
1413 gchar *text = gtk_text_buffer_get_slice(GTK_TEXT_BUFFER(mainview->buffer), &begin, &end, TRUE);
1415 GString *gstr=g_string_sized_new(4096);
1416 wp_text_buffer_save_document(mainview->buffer, (WPDocumentSaveCallback)(wp_savecallback), gstr);
1417 gint textlen=gstr->len;
1418 gchar *text=g_string_free(gstr, FALSE);
1420 if (text==NULL || !strcmp(text, ""))
1422 show_banner(mainview, _("Memo is empty"));
1424 else
1426 gchar *fn = interface_file_chooser(mainview, GTK_FILE_CHOOSER_ACTION_SAVE, nodename, "html");
1427 if (fn!=NULL)
1429 GnomeVFSResult vfs_result;
1430 GnomeVFSHandle *handle = NULL;
1431 GnomeVFSFileSize out_bytes;
1432 vfs_result = gnome_vfs_create(&handle, fn, GNOME_VFS_OPEN_WRITE, 0, 0600);
1433 if ( vfs_result != GNOME_VFS_OK ) {
1434 show_banner(mainview, _("Export failed"));
1436 else
1438 gnome_vfs_write(handle, text, textlen, &out_bytes);
1439 gnome_vfs_close(handle);
1440 if (out_bytes==strlen(text)) show_banner(mainview, _("Exported"));
1441 else show_banner(mainview, _("Export incomplete"));
1443 g_free(fn);
1446 g_free(text);
1448 else if (nd->typ == NODE_SKETCH)
1450 GdkPixmap *skpix = sketchwidget_get_Pixmap(mainview->sk);
1451 GtkWidget *skdr = sketchwidget_get_drawingarea(mainview->sk);
1452 GdkPixbuf *pixbuf = gdk_pixbuf_get_from_drawable(NULL, GDK_DRAWABLE(skpix), NULL, 0, 0, 0, 0, skdr->allocation.width, skdr->allocation.height);
1453 if (pixbuf==NULL)
1455 show_banner(mainview, _("Memo is empty"));
1457 else
1459 gchar *fn = interface_file_chooser(mainview, GTK_FILE_CHOOSER_ACTION_SAVE, nodename, "png");
1460 if (fn!=NULL)
1462 if (gdk_pixbuf_save(pixbuf, fn, "png", NULL, NULL)==FALSE)
1464 show_banner(mainview, _("Export failed"));
1466 else
1468 show_banner(mainview, _("Exported"));
1470 g_free(fn);
1473 g_object_unref(skpix);
1475 else if (nd->typ == NODE_CHECKLIST)
1477 show_banner(mainview, _("Export of checklists not possible yet"));
1482 * callback from menu item
1483 * move selected node down (switch node with next sibling), don't change level of node
1485 void callback_move_down_node(GtkAction * action, gpointer data)
1487 GtkTreeIter iter;
1488 GtkTreeModel *model;
1490 MainView *mainview = (MainView *) data;
1491 g_assert(mainview != NULL && mainview->data != NULL);
1493 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
1494 gtk_tree_selection_get_selected(selection, &model, &iter);
1496 GtkTreeIter old_iter = iter;/*save pointer to old iter, we will need it during swap nodes*/
1498 if (gtk_tree_model_iter_next(model,&iter)==FALSE)/*get next node*/
1499 return;
1501 GtkTreeStore *treeStore = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->treeview)));
1502 gtk_tree_store_swap(treeStore,&iter,&old_iter);
1504 mainview->file_edited = TRUE;/*we have made changes , if required show "save changes?" dialog in future*/
1508 * callback from menu item
1509 * move selected node down (switch node with prev sibling), don't change level of node
1511 void callback_move_up_node(GtkAction * action, gpointer data)
1513 GtkTreeIter iter;
1514 GtkTreeModel *model;
1516 MainView *mainview = (MainView *) data;
1517 g_assert(mainview != NULL && mainview->data != NULL);
1519 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
1520 gtk_tree_selection_get_selected(selection, &model, &iter);
1522 GtkTreeIter old_iter=iter;/*save pointer to old iter, we will need it during swap nodes*/
1524 if (tree_model_iter_prev(model,&iter)==FALSE)/*get previous node*/
1525 return;
1527 GtkTreeStore *treeStore = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->treeview)));
1528 gtk_tree_store_swap(treeStore,&old_iter,&iter);/*do move*/
1530 mainview->file_edited = TRUE;/*we have made changes , if required show "save changes?" dialog in future*/
1534 * callback from menu item
1535 * we change level of actual node with direction to top
1537 void callback_move_to_top_level_node(GtkAction * action, gpointer data)
1539 GtkTreeIter iter,new_parent;
1540 GtkTreeIter *p_new_parent;
1541 GtkTreeIter parent;
1542 GtkTreeModel *model;
1544 MainView *mainview = (MainView *) data;
1545 g_assert(mainview != NULL && mainview->data != NULL);
1547 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
1548 gtk_tree_selection_get_selected(selection, &model, &iter);
1550 /*at first we need actual parent of selected node*/
1551 if (gtk_tree_model_iter_parent(model,&parent,&iter)==FALSE)
1553 /*if parent of selected node is ROOT we can't go higher*/
1554 return;
1556 /*we need also new parent, it's parent of actual parent*/
1557 if (gtk_tree_model_iter_parent(model,&new_parent,&parent)==FALSE)
1559 /*if our new parent is ROOT we got filled new_parent with invalid value,
1560 so we need set NULL value to p_new_parent (root item)*/
1561 p_new_parent=NULL;
1563 else
1565 p_new_parent=&new_parent;/*we only redirect pointer to treeiter*/
1568 saveCurrentData(mainview);/*we save changes in node befor move*/
1570 /*this move function provide move item with all his children, be careful iter value will change!*/
1571 if (move_node(mainview,p_new_parent,&iter,&parent)==TRUE){
1573 gint id_parent = get_node_id_on_tmp_db(model,p_new_parent);
1574 gint id_node = get_node_id_on_tmp_db(model,&iter);
1575 /*we need also update parent id of moved item*/
1576 char tq[512];
1577 g_snprintf (tq, sizeof(tq), "UPDATE %s SET parent=%d WHERE nodeid=%d",datatable_tmpname,id_parent ,id_node);
1578 exec_command_on_db(mainview,tq);
1580 /*select new created iter*/
1581 gtk_tree_selection_select_iter(selection,&iter);
1583 mainview->file_edited = TRUE;/*we have made changes , if required show "save changes?" dialog in future*/
1588 * callback from menu item
1589 * we change level of actual node with direction to bottom
1590 * previous node will be parent of our actual node
1592 void callback_move_to_bottom_level_node(GtkAction * action, gpointer data)
1594 GtkTreeIter iter;
1595 GtkTreeModel *model;
1597 MainView *mainview = (MainView *) data;
1598 g_assert(mainview != NULL && mainview->data != NULL);
1600 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
1601 gtk_tree_selection_get_selected(selection, &model, &iter);
1603 GtkTreeIter move_iter=iter;/*save pointer to old iter*/
1605 /*we try to get previous node*/
1606 if (tree_model_iter_prev(model,&iter)==FALSE)
1607 return;/*if previous node on the same level doesn't exist we will exit*/
1609 saveCurrentData(mainview);/*we save changes in node befor move*/
1611 /*this move function provide move item with all his children, be careful move_iter value will change!*/
1612 if (move_node(mainview,&iter,&move_iter,NULL)==TRUE)
1614 gint id_parent = get_node_id_on_tmp_db(model,&iter);
1615 gint id_node = get_node_id_on_tmp_db(model,&move_iter);
1617 /*we need also update parent id of moved item*/
1618 char tq[512];
1619 g_snprintf (tq, sizeof(tq), "UPDATE %s SET parent=%d WHERE nodeid=%d",datatable_tmpname,id_parent ,id_node);
1620 exec_command_on_db(mainview,tq);
1622 GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
1623 gtk_tree_view_expand_row(GTK_TREE_VIEW(mainview->treeview), path, FALSE);/*expand parent node*/
1624 gtk_tree_path_free(path);
1626 /*select new created iter*/
1627 gtk_tree_selection_select_iter(selection,&move_iter);
1629 mainview->file_edited = TRUE;/*we have made changes , if required show "save changes?" dialog in future*/
1634 * move item_to_move to new_parent with his children, this function is designed for change level of node
1635 * we copy item_to_move with his children to new position (after item_befor if is not NULL) and then we
1636 * destroy old node with his children, so ! item_to_move is set with new iter, be careful on this!
1638 gboolean move_node(MainView *mainview,GtkTreeIter *new_parent,GtkTreeIter *item_to_move,GtkTreeIter *item_befor)
1640 GtkTreeModel *model;
1642 model=gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->treeview));
1643 GtkTreeStore *treeStore = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->treeview)));
1645 nodeData *node;
1646 gtk_tree_model_get(model, item_to_move, NODE_DATA, &node, -1);/*get data from actual iter*/
1647 if (node)
1649 GtkTreeIter new_iter;/*create new iter*/
1650 gtk_tree_store_append(treeStore,&new_iter,new_parent);/*append new iter to new parent*/
1652 if (item_befor!=NULL)
1653 gtk_tree_store_move_after(treeStore,&new_iter,item_befor);/*sometimes we need set position*/
1655 gtk_tree_store_set(treeStore, &new_iter, NODE_NAME, node->name,NODE_PIXBUF, node->namepix, NODE_DATA, node, -1);/*set data from old iter*/
1657 GtkTreeIter child;
1658 while (gtk_tree_model_iter_children(model, &child, item_to_move)==TRUE)/*move all childrens while some exits*/
1660 if (move_node(mainview,&new_iter,&child,NULL)==FALSE)/*use recursion on children*/
1661 return FALSE;
1664 gtk_tree_store_set(treeStore, item_to_move, NODE_DATA, NULL, -1);
1665 gtk_tree_store_remove(treeStore, item_to_move);/*remove node, data need't remove, they are stored in new node*/
1667 /*we need return new value of moved item, so we need assign new_iter to item_to_move*/
1668 /*this code is ugly : new_iter to path and back to item_to_move*/
1669 GtkTreePath *path=gtk_tree_model_get_path(model,&new_iter);
1670 gtk_tree_model_get_iter(model,item_to_move,path);
1671 gtk_tree_path_free(path);
1673 else
1675 fprintf(stderr,"Get data node failed!\n");
1676 return FALSE;
1679 return TRUE;
1683 * simple execute of sql command which is stored in sql_string[]
1685 gboolean exec_command_on_db(MainView *mainview,char sql_string[])
1687 sqlite3_stmt *stmt = NULL;
1688 const char* dum;
1689 gboolean db_query_result = FALSE;
1691 int rc = sqlite3_prepare (mainview->db, sql_string, strlen(sql_string), &stmt, &dum);
1693 if (rc) {
1694 fprintf (stderr, "Error preparing db update query: %s\n", sqlite3_errmsg(mainview->db));
1695 return FALSE;
1698 rc = SQLITE_BUSY;
1699 while (rc == SQLITE_BUSY) {
1700 rc = sqlite3_step (stmt);
1701 if (rc == SQLITE_DONE) {
1702 db_query_result = TRUE;
1703 break;
1705 else if(rc == SQLITE_ERROR || rc== SQLITE_MISUSE) {
1706 fprintf (stderr, "Error updating node: %s\n", sqlite3_errmsg(mainview->db));
1707 break;
1709 sqlite3_finalize(stmt);
1711 return TRUE;
1715 * it is used in gtk_tree_model_foreach function to update ord value for all nodes (it's usefull for move up, move down node)
1717 gboolean foreach_func_update_ord (GtkTreeModel *model,GtkTreePath *path,GtkTreeIter *iter, MainView *mainview)
1719 nodeData *node;
1720 gtk_tree_model_get(model, iter, NODE_DATA, &node, -1);
1721 /*we need index of node on actual level*/
1722 gint index=get_branch_node_index(path);
1724 /*prepare to execute update command,and exec it*/
1725 char sql_command[512];
1726 g_snprintf (sql_command, sizeof(sql_command), "UPDATE %s SET ord=\"%d\" WHERE nodeid=%d",datatable_tmpname, index, node->sql3id);
1727 exec_command_on_db(mainview,sql_command);
1729 /*we don't want break gtk_tree_model_foreach function,until we call this func on each node - so we return always FALSE*/
1730 return FALSE;
1734 * return id number of iter (id number which is used to identify in sql database of nodes)
1736 int get_node_id_on_tmp_db(GtkTreeModel *model,GtkTreeIter *iter)
1738 if (iter==NULL)
1739 return 0;/*we got ROOT parent here*/
1741 nodeData *node;
1742 gtk_tree_model_get(model, iter, NODE_DATA, &node, -1);
1743 return node->sql3id;
1747 * get index of node in current branch
1749 gint get_branch_node_index(GtkTreePath *path)
1751 int depth=gtk_tree_path_get_depth(path);
1752 gint *indicies = gtk_tree_path_get_indices(path);
1754 return indicies[depth-1];
1758 * similiar with gtk_tree_model_iter_next (), but opposite
1760 gboolean tree_model_iter_prev(GtkTreeModel *tree_model,GtkTreeIter *iter)
1762 GtkTreePath *path = gtk_tree_model_get_path(tree_model, iter);
1764 if (path==NULL){
1765 fprintf(stderr,"Error: path is null\n");
1766 return FALSE;
1769 if (gtk_tree_path_prev(path)==FALSE)
1770 return FALSE;
1772 gtk_tree_model_get_iter(tree_model, iter,path);
1774 return TRUE;
1777 gboolean ref2iter(GtkTreeModel * model, GtkTreeRowReference * ref, GtkTreeIter * iter)
1779 gboolean res = FALSE;
1780 GtkTreePath *path = gtk_tree_row_reference_get_path(ref);
1782 if (gtk_tree_model_get_iter(model, iter, path))
1784 res = TRUE;
1786 gtk_tree_path_free(path);
1787 return (res);
1790 GtkTreeRowReference *iter2ref(GtkTreeModel * model, GtkTreeIter * iter)
1792 GtkTreeRowReference *ref;
1794 GtkTreePath *path = gtk_tree_model_get_path(model, iter);
1796 ref = gtk_tree_row_reference_new(model, path);
1797 gtk_tree_path_free(path);
1798 return (ref);
1801 void move_nodes_up(GtkTreeModel * model, GtkTreeRowReference * topnode, GtkTreeRowReference * newtop)
1803 GtkTreeIter topiter;
1805 fprintf(stderr, "here2\n");
1807 if (ref2iter(model, topnode, &topiter) == FALSE)
1808 return;
1810 fprintf(stderr, "here3\n");
1812 GtkTreeIter child;
1814 if (gtk_tree_model_iter_children(model, &child, &topiter))
1816 fprintf(stderr, "here4\n");
1817 GtkTreeRowReference *ref;
1818 GList *rr_list = NULL, *node;
1822 ref = iter2ref(model, &child);
1823 rr_list = g_list_append(rr_list, ref);
1825 while(gtk_tree_model_iter_next(model, &child));
1828 * got a reflist for all children
1831 fprintf(stderr, "here5\n");
1832 for(node = rr_list; node; node = node->next)
1834 ref = (GtkTreeRowReference *) (node->data);
1835 if (ref2iter(model, ref, &child))
1837 GtkTreeIter newtopiter, newiter;
1838 GtkTreeIter *newtopiterptr;
1840 if (ref2iter(model, newtop, &newtopiter))
1841 newtopiterptr = &newtopiter;
1842 else
1843 newtopiterptr = NULL;
1845 nodeData *node;
1847 gtk_tree_model_get(model, &child, NODE_DATA, &node, -1);
1849 gtk_tree_store_append(GTK_TREE_STORE(model), &newiter, newtopiterptr);
1850 gtk_tree_store_set(GTK_TREE_STORE(model), &newiter, NODE_NAME, node->name, NODE_PIXBUF, node->namepix, NODE_DATA, node, -1);
1852 GtkTreeRowReference *newref = iter2ref(model, &newiter);
1854 move_nodes_up(model, ref, newref);
1855 gtk_tree_row_reference_free(newref);
1857 gtk_tree_store_remove(GTK_TREE_STORE(model), &child);
1859 gtk_tree_row_reference_free(ref);
1861 fprintf(stderr, "here6\n");
1863 g_list_free(rr_list);
1866 fprintf(stderr, "here7\n");
1870 void callback_delete_node_real(MainView* mainview)
1872 GtkTreeIter iter;
1873 GtkTreeModel *model;
1875 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
1877 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
1878 return;
1880 nodeData *nd;
1882 gtk_tree_model_get(model, &iter, NODE_DATA, &nd, -1);
1883 if (!nd)
1884 return;
1886 mainview->file_edited = TRUE;
1888 unsigned int sql3id = nd->sql3id;
1890 if (nd->name)
1891 g_free(nd->name);
1894 * g_free(nd->data);
1895 * if (nd->pix) g_object_unref(nd->pix);
1897 g_free(nd);
1899 fprintf(stderr, "here1\n");
1900 GtkTreeRowReference *upref = NULL, *ref = NULL;
1902 GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
1904 ref = gtk_tree_row_reference_new(model, path);
1905 if (gtk_tree_path_up(path))
1906 upref = gtk_tree_row_reference_new(model, path);
1907 gtk_tree_path_free(path);
1909 g_object_ref(model);
1910 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->treeview), NULL);
1912 fprintf(stderr, "here! 1\n");
1913 move_nodes_up(model, ref, upref);
1915 fprintf(stderr, "here! 2\n");
1916 if (ref2iter(model, ref, &iter))
1918 char tq[512];
1920 g_snprintf(tq, sizeof(tq), "SELECT parent FROM %s WHERE nodeid=%d", datatable_tmpname, sql3id);
1921 sqlite3_stmt *stmt = NULL;
1922 const char *dum;
1923 int rc = sqlite3_prepare(mainview->db, tq, strlen(tq), &stmt, &dum);
1924 unsigned int sql3parentid = 0;
1926 if (rc)
1928 fprintf(stderr, "Error %s\n", sqlite3_errmsg(mainview->db));
1930 else
1932 rc = SQLITE_BUSY;
1933 while(rc == SQLITE_BUSY || rc == SQLITE_ROW)
1935 rc = sqlite3_step(stmt);
1936 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE || rc == SQLITE_DONE)
1937 break;
1938 else if (rc == SQLITE_ROW)
1940 sql3parentid = sqlite3_column_int(stmt, 0);
1941 break;
1944 sqlite3_finalize(stmt);
1946 g_snprintf(tq, sizeof(tq), "UPDATE %s SET parent=%d WHERE parent=%d;", datatable_tmpname, sql3parentid, sql3id);
1947 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
1948 fprintf(stderr, "ERROR moving nodes up!\n");
1949 else
1951 g_snprintf(tq, sizeof(tq), "DELETE FROM %s WHERE nodeid=%d;", datatable_tmpname, sql3id);
1952 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
1953 fprintf(stderr, "ERROR deleting node!\n");
1955 /* Delete all checklist items that do not have
1956 * a node anymore (= orphaned checklist items) */
1957 g_snprintf(tq, sizeof(tq), "DELETE FROM %s WHERE nodeid NOT IN (SELECT nodeid FROM %s);", checklisttable_tmpname, datatable_tmpname);
1958 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
1959 fprintf(stderr, "ERROR deleting orphaned checklist items!\n");
1962 gtk_tree_store_remove(GTK_TREE_STORE(model), &iter);
1965 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->treeview), model);
1966 g_object_unref(model);
1968 fprintf(stderr, "here! 3\n");
1969 gtk_tree_row_reference_free(ref);
1970 gtk_tree_row_reference_free(upref);
1972 gtk_tree_view_expand_all(GTK_TREE_VIEW(mainview->treeview));
1974 fprintf(stderr, "here10\n");
1977 void callback_edit_clear(GtkAction * action, gpointer data)
1979 MainView *mainview = (MainView *) data;
1980 g_assert(mainview != NULL && mainview->data != NULL);
1981 nodeData *nd = getSelectedNode(mainview);
1983 if (show_confirmation(mainview, _("Remove all contents of this memo?"))) {
1984 switch (nd->typ) {
1985 case NODE_TEXT:
1986 gtk_text_buffer_set_text(GTK_TEXT_BUFFER(mainview->buffer), "", 0);
1987 break;
1988 case NODE_SKETCH:
1989 sketchwidget_clear(mainview->sk);
1990 break;
1991 case NODE_CHECKLIST:
1992 gtk_list_store_clear(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->listview))));
1993 break;
1994 default:
1995 /* Unknown node type */
1996 g_assert(FALSE);
2002 * cut
2004 void callback_edit_cut(GtkAction * action, gpointer data)
2006 MainView *mainview = (MainView *) data;
2007 g_assert(mainview != NULL && mainview->data != NULL);
2009 nodeData *nd = getSelectedNode(mainview);
2011 if (nd->typ == NODE_TEXT)
2012 gtk_text_buffer_cut_clipboard(GTK_TEXT_BUFFER(mainview->buffer), mainview->clipboard, TRUE);
2013 else if (nd->typ == NODE_SKETCH)
2015 if (sketchwidget_cut(mainview->sk, mainview->clipboard)==FALSE)
2016 show_banner(mainview, _("Error cutting"));
2018 else if (nd->typ == NODE_CHECKLIST)
2019 show_banner(mainview, _("Unimplemented"));
2024 * copy
2026 void callback_edit_copy(GtkAction * action, gpointer data)
2028 MainView *mainview = (MainView *) data;
2029 g_assert(mainview != NULL && mainview->data != NULL);
2031 nodeData *nd = getSelectedNode(mainview);
2033 if (nd->typ == NODE_TEXT)
2034 gtk_text_buffer_copy_clipboard(GTK_TEXT_BUFFER(mainview->buffer), mainview->clipboard);
2035 else if (nd->typ == NODE_SKETCH)
2037 if (sketchwidget_copy(mainview->sk, mainview->clipboard)==FALSE)
2038 show_banner(mainview, _("Error copying"));
2040 else if (nd->typ == NODE_CHECKLIST)
2042 /* Copy all selected entries as multiline text (1 line per entry) */
2043 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->listview));
2044 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->listview));
2046 gint selected_rows = gtk_tree_selection_count_selected_rows(selection);
2047 GList* l = gtk_tree_selection_get_selected_rows(selection, NULL);
2049 GtkTreeIter iter;
2050 gchar *str_data;
2052 gchar **entries = g_malloc0(sizeof(gchar*)*selected_rows+1);
2053 gint entries_idx = 0;
2055 GList* cur = l;
2056 while(cur) {
2057 GtkTreePath *path = cur->data;
2059 if (gtk_tree_model_get_iter(model, &iter, path)) {
2060 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHECKNODE_TEXT, &(entries[entries_idx++]), -1);
2062 gtk_tree_path_free(path);
2064 cur = cur->next;
2067 g_list_free(l);
2068 str_data = g_strjoinv("\n", entries);
2069 g_strfreev(entries);
2070 gtk_clipboard_set_text(mainview->clipboard, str_data, -1);
2071 g_free(str_data);
2073 str_data = g_strdup_printf(_("Copied %d entries"), selected_rows);
2074 show_banner(mainview, str_data);
2075 g_free(str_data);
2081 * paste
2083 void callback_edit_paste(GtkAction * action, gpointer data)
2085 MainView *mainview = (MainView *) data;
2086 g_assert(mainview != NULL && mainview->data != NULL);
2088 nodeData *nd = getSelectedNode(mainview);
2090 if (nd->typ == NODE_TEXT)
2091 gtk_text_buffer_paste_clipboard(GTK_TEXT_BUFFER(mainview->buffer), mainview->clipboard, NULL, TRUE);
2092 else if (nd->typ == NODE_SKETCH)
2094 if (sketchwidget_paste(mainview->sk, mainview->clipboard)==FALSE)
2095 show_banner(mainview, _("Error pasting"));
2097 else if (nd->typ == NODE_CHECKLIST) {
2098 /* Paste string from clipboard as new item */
2099 callback_checklist_paste(mainview);
2102 mainview->file_edited = TRUE;
2105 gint cb_popup(GtkWidget * widget, GdkEvent * event)
2107 GtkMenu *menu;
2108 GdkEventButton *event_button;
2111 * The "widget" is the menu that was supplied when
2112 * * g_signal_connect_swapped() was called.
2114 menu = GTK_MENU(widget);
2115 event_button = (GdkEventButton *) event;
2116 if (event->type == GDK_BUTTON_PRESS && event_button->button == 3)
2118 gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event_button->button, event_button->time);
2119 return TRUE;
2121 return FALSE;
2125 * close
2127 gboolean closefile(MainView * mainview)
2129 saveCurrentData(mainview);
2131 if (mainview->file_edited)
2133 HildonNote *hn = HILDON_NOTE(hildon_note_new_confirmation_add_buttons(GTK_WINDOW(mainview->data->main_view), _("Save changes?"), _("Yes"), CONFRESP_YES, _("No"), CONFRESP_NO, _("Cancel"), CONFRESP_CANCEL, NULL, NULL));
2134 gint answer = gtk_dialog_run(GTK_DIALOG(hn));
2135 gtk_widget_destroy(GTK_WIDGET(hn));
2137 if (answer == CONFRESP_CANCEL)
2138 return (FALSE);
2139 else if (answer == CONFRESP_YES)
2141 if (mainview->file_name == NULL)
2143 mainview->file_name = interface_file_chooser(mainview, GTK_FILE_CHOOSER_ACTION_SAVE, "maemopaddata", "db");
2145 write_buffer_to_file(mainview);
2149 if (mainview->db)
2150 sqlite3_close(mainview->db);
2151 mainview->db = NULL;
2152 return (TRUE);
2155 gboolean callback_file_close(GtkAction * action, gpointer data)
2158 MainView *mainview = (MainView *) data;
2159 g_assert(mainview != NULL && mainview->data != NULL);
2160 if (closefile(mainview) == FALSE)
2161 return(FALSE);
2163 gtk_main_quit();
2164 return(TRUE);
2167 void callback_file_new_node(GtkAction * action, gpointer data)
2169 MainView *mainview = (MainView *) data;
2170 g_assert(mainview != NULL && mainview->data != NULL);
2172 nodeType typ = NODE_SKETCH;
2174 nodeData *nd = getSelectedNode(mainview);
2176 if (nd != NULL)
2177 typ = nd->typ;
2179 new_node_dialog(typ, mainview);
2183 * new
2185 void callback_file_new(GtkAction * action, gpointer data)
2187 MainView *mainview = (MainView *) data;
2188 g_assert(mainview != NULL && mainview->data != NULL);
2190 gchar *filename = NULL;
2192 if (closefile(mainview) == FALSE)
2193 return;
2195 filename = interface_file_chooser(mainview, GTK_FILE_CHOOSER_ACTION_SAVE, "memos", "db");
2196 if (filename == NULL)
2197 return;
2199 new_file(mainview);
2203 busy_enter(mainview);
2205 int rc;
2207 rc = sqlite3_open(filename, &mainview->db);
2208 if (rc)
2210 show_banner(mainview, _("Cannot create database"));
2211 fprintf(stderr, "Can't create database %s: %s\n", filename, sqlite3_errmsg(mainview->db));
2212 break;
2215 sqlite3_exec(mainview->db, "PRAGMA synchronous = OFF;", NULL, NULL, NULL);
2217 char tq[512];
2219 g_snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", misctable_name, misctable);
2220 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
2222 g_snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", datatable_name, datatable);
2223 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
2225 fprintf(stderr, "ERROR creating data table\n");
2226 show_banner(mainview, _("Error creating data table"));
2227 break;
2230 g_snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", checklisttable_name, checklisttable);
2231 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
2233 fprintf(stderr, "ERROR creating checklist table\n");
2234 show_banner(mainview, _("Error creating checklist table"));
2235 break;
2238 if (mainview->db)
2239 sqlite3_close(mainview->db);
2240 mainview->db = NULL;
2242 mainview->file_name = filename;
2243 mainview->file_edited = FALSE;
2244 read_file_to_buffer(mainview);
2246 /*add a starter memo*/
2247 nodeData *node;
2248 node = g_malloc(sizeof(nodeData));
2249 node->typ = NODE_SKETCH;
2250 node->name = _("My first memo");
2251 node->namepix = NULL;
2252 node->lastMod = 0;
2253 node->flags = 0;
2254 node->sql3id = 0;
2255 add_new_node(node, mainview, TRUE);
2256 /*gtk_paned_set_position(GTK_PANED(mainview->hpaned), 180);*/
2257 write_buffer_to_file(mainview);
2259 }while(FALSE);
2260 busy_reset(mainview);
2263 gboolean reset_ctree(GtkTreeModel * model, GtkTreePath * path, GtkTreeIter * iter, gpointer data)
2265 nodeData *node;
2267 gtk_tree_model_get(model, iter, NODE_DATA, &node, -1);
2268 if (node)
2270 if (node->name)
2271 g_free(node->name);
2272 if (node->namepix)
2273 g_object_unref(node->namepix);
2274 g_free(node);
2276 gtk_tree_store_set(GTK_TREE_STORE(model), iter, NODE_DATA, NULL, -1);
2278 return (FALSE);
2281 void new_file(MainView * mainview)
2283 busy_enter(mainview);
2285 * clear buffer, filename and free buffer text
2287 gtk_text_buffer_set_text(GTK_TEXT_BUFFER(mainview->buffer), "", -1);
2288 mainview->file_name = NULL;
2289 mainview->file_edited = FALSE;
2290 mainview->newnodedialog_createchild = TRUE;
2292 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->treeview));
2294 g_object_ref(model);
2295 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->treeview), NULL);
2297 gtk_tree_model_foreach(model, (GtkTreeModelForeachFunc) reset_ctree, (gpointer) mainview);
2300 * crashing bastard
2301 * gtk_tree_store_clear(GTK_TREE_STORE(model));
2303 GtkTreePath *path = gtk_tree_path_new_from_indices(0, -1);
2304 GtkTreeIter iter;
2306 if (gtk_tree_model_get_iter(model, &iter, path))
2310 gtk_tree_store_remove(GTK_TREE_STORE(model), &iter);
2312 while(gtk_tree_store_iter_is_valid(GTK_TREE_STORE(model), &iter));
2314 gtk_tree_path_free(path);
2316 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->treeview), model);
2317 g_object_unref(model);
2319 prepareUIforNodeChange(mainview, NODE_UNKNOWN);
2320 busy_leave(mainview);
2324 * open
2326 void callback_file_open(GtkAction * action, gpointer data)
2328 gchar *filename = NULL;
2329 MainView *mainview = (MainView *) data;
2330 g_assert(mainview != NULL && mainview->data != NULL);
2332 if (closefile(mainview) == FALSE)
2333 return;
2336 * open new file
2338 filename = interface_file_chooser(mainview, GTK_FILE_CHOOSER_ACTION_OPEN, NULL, NULL);
2341 * if we got a file name from chooser -> open file
2343 open_file(filename, mainview);
2344 g_free(filename);
2347 gboolean open_file(gchar * filename, MainView * mainview)
2349 gboolean ret=FALSE;
2351 busy_enter(mainview);
2353 while(filename != NULL)
2355 struct stat s;
2357 if (stat(filename, &s) == -1) break;
2359 mainview->file_name = g_strdup(filename);
2360 gboolean res = read_file_to_buffer(mainview);
2362 if (res == FALSE)
2364 g_free(mainview->file_name);
2365 mainview->file_name = NULL;
2366 break;
2368 mainview->file_edited = FALSE;
2369 ret=TRUE;
2370 break;
2373 busy_leave(mainview);
2374 return(ret);
2377 void callback_about_link(GtkAboutDialog *about, const gchar *link, gpointer data)
2379 MainView *mainview = (MainView *) data;
2380 g_assert(mainview != NULL && mainview->data != NULL);
2381 osso_rpc_run_with_defaults(mainview->data->osso, "osso_browser", OSSO_BROWSER_OPEN_NEW_WINDOW_REQ, NULL,
2382 DBUS_TYPE_STRING, link, DBUS_TYPE_INVALID);
2385 void callback_about(GtkAction * action, gpointer data)
2387 MainView* mainview = (MainView *)data;
2388 he_about_dialog_present(mainview_get_dialog_parent(mainview),
2389 NULL /* auto-detect app name */,
2390 "maepad",
2391 VERSION,
2392 _("A node-based memory pad for Maemo"),
2393 _("(c) 2008-2010 Thomas Perl, (c) 2006-2008 Kemal Hadimli"),
2394 "http://thpinfo.com/2010/maepad/",
2395 NULL /* TODO: Add bug tracker URL */,
2396 "http://thpinfo.com/2010/maepad/donate");
2400 * save
2402 void callback_file_save(GtkAction * action, gpointer data)
2404 gchar *filename = NULL;
2405 MainView *mainview = (MainView *) data;
2406 g_assert(mainview != NULL && mainview->data != NULL);
2409 * check is we had a new file
2411 if (mainview->file_name != NULL)
2413 write_buffer_to_file(mainview);
2415 else
2417 filename = interface_file_chooser(mainview, GTK_FILE_CHOOSER_ACTION_SAVE, "maemopaddata", "db");
2419 * if we got a file name from chooser -> save file
2421 if (filename != NULL)
2423 mainview->file_name = filename;
2424 write_buffer_to_file(mainview);
2425 mainview->file_edited = FALSE;
2430 void callback_shapemenu(GtkAction * action, GtkWidget * wid)
2432 int style = (int)gtk_object_get_user_data(GTK_OBJECT(wid));
2433 MainView *mainview = gtk_object_get_data(GTK_OBJECT(wid), "m");
2435 g_assert(mainview != NULL);
2437 if (style==0) sketchwidget_set_shape(mainview->sk, SKETCHSHAPE_FREEHAND);
2438 else if (style==1) sketchwidget_set_shape(mainview->sk, SKETCHSHAPE_LINE);
2439 else if (style==2) sketchwidget_set_shape(mainview->sk, SKETCHSHAPE_RECT);
2440 else if (style==3) sketchwidget_set_shape(mainview->sk, SKETCHSHAPE_ELLIPSE);
2445 void callback_eraser(GtkAction * action, MainView * mainview)
2447 g_assert(mainview != NULL && mainview->data != NULL);
2449 if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(mainview->eraser_tb)) == TRUE)
2451 GdkColor c2;
2453 c2.red = 65535;
2454 c2.green = 65535;
2455 c2.blue = 65535;
2457 mainview->sk->pressuresensitivity=FALSE;
2459 sketchwidget_set_brushcolor(mainview->sk, c2);
2460 mainview->brushsize_backup = sketchwidget_get_brushsize(mainview->sk);
2461 guint ers=(mainview->brushsize_backup*4)+4;
2462 sk_set_brushsize(mainview, ers);
2463 sketchwidget_set_brushsize(mainview->sk, ers); /*fixme:to override max brush size, not pretty*/
2465 else
2467 if (mainview->current_color == NULL) {
2468 GdkColor color = {0, 0, 0, 0};
2469 mainview->current_color = gdk_color_copy(&color);
2471 /* pressure sensitivity disabled for now...
2472 mainview->sk->pressuresensitivity=gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(mainview->tools_pressure));*/
2474 sketchwidget_set_brushcolor(mainview->sk, *(mainview->current_color));
2475 sk_set_brushsize(mainview, mainview->brushsize_backup);
2479 void callback_menu(GtkAction * action, GtkWidget * menu)
2481 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0, GDK_CURRENT_TIME);
2484 void callback_brushsizetb(GtkAction * action, MainView *mainview)
2486 g_assert(mainview != NULL && mainview->data != NULL);
2488 if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(mainview->eraser_tb)) == TRUE)
2490 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->eraser_tb), FALSE);
2492 else
2494 callback_menu(NULL, mainview->brushsizemenu);
2498 void callback_brushsize(GtkAction * action, GtkWidget * wid)
2500 int bsize = (int)gtk_object_get_user_data(GTK_OBJECT(wid));
2501 MainView *mainview = gtk_object_get_data(GTK_OBJECT(wid), "m");
2503 g_assert(mainview != NULL && mainview->data != NULL);
2505 sketchwidget_set_brushsize(mainview->sk, bsize);
2507 GtkWidget *pix = gtk_object_get_data(GTK_OBJECT(wid), "i");
2509 gtk_widget_show(pix);
2510 gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(mainview->brushsize_tb), pix);
2513 void callback_sketchlines(GtkAction * action, GtkWidget * wid)
2515 int style = (int)gtk_object_get_user_data(GTK_OBJECT(wid));
2516 MainView *mainview = gtk_object_get_data(GTK_OBJECT(wid), "m");
2518 g_assert(mainview != NULL);
2520 nodeData *nd = getSelectedNode(mainview);
2521 gboolean doit = FALSE;
2523 if (nd != NULL && nd->typ == NODE_SKETCH)
2525 nd->flags &= ~NODEFLAG_SKETCHLINES;
2526 nd->flags &= ~NODEFLAG_SKETCHGRAPH;
2527 /* sketchwidget_set_edited(mainview->sk, TRUE);*/ /*we call this on openfile, so this messes things up*/
2528 doit = TRUE;
2531 if (style == 0)
2533 sketchwidget_set_backstyle(mainview->sk, SKETCHBACK_NONE);
2535 else if (style == 1)
2537 sketchwidget_set_backstyle(mainview->sk, SKETCHBACK_LINES);
2538 if (doit == TRUE)
2539 nd->flags |= NODEFLAG_SKETCHLINES;
2541 else if (style == 2)
2543 sketchwidget_set_backstyle(mainview->sk, SKETCHBACK_GRAPH);
2544 if (doit == TRUE)
2545 nd->flags |= NODEFLAG_SKETCHGRAPH;
2548 GtkWidget *pix = gtk_object_get_data(GTK_OBJECT(wid), "i");
2550 gtk_widget_show(pix);
2551 gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(mainview->sketchlines_tb), pix);
2554 void callback_color(GtkAction* action, MainView* mainview)
2556 g_assert(mainview != NULL && mainview->data != NULL);
2558 nodeData *nd = getSelectedNode(mainview);
2559 if (nd == NULL) return;
2561 HeSimpleColorDialog* dialog = HE_SIMPLE_COLOR_DIALOG(he_simple_color_dialog_new());
2563 if (mainview->current_color) {
2564 he_simple_color_dialog_set_color(dialog, mainview->current_color);
2567 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
2568 gtk_widget_destroy(GTK_WIDGET(dialog));
2569 return;
2572 gdk_color_free(mainview->current_color);
2573 mainview->current_color = he_simple_color_dialog_get_color(dialog);
2575 gtk_widget_destroy(GTK_WIDGET(dialog));
2577 switch (nd->typ) {
2578 case NODE_SKETCH:
2579 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->eraser_tb), FALSE);
2580 sketchwidget_set_brushcolor(mainview->sk, *(mainview->current_color));
2581 break;
2582 case NODE_CHECKLIST:
2583 { /* Put in a separate block to allow new local variables */
2584 GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->listview));
2585 GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->listview));
2586 GList* selected = gtk_tree_selection_get_selected_rows(selection, NULL);
2588 gchar* color_string = g_strdup_printf("#%02x%02x%02x",
2589 mainview->current_color->red >> 8,
2590 mainview->current_color->green >> 8,
2591 mainview->current_color->blue >> 8);
2593 GList* cur = selected;
2594 while (cur != NULL) {
2595 GtkTreePath* path = cur->data;
2596 GtkTreeIter iter;
2597 if (gtk_tree_model_get_iter(model, &iter, path)) {
2598 gtk_list_store_set(GTK_LIST_STORE(model), &iter, CHECKNODE_COLOR, color_string, -1);
2600 gtk_tree_path_free(path);
2601 cur = cur->next;
2604 g_list_free(selected);
2605 g_free(color_string);
2607 break;
2608 default:
2609 g_error("Wrong node type for color selection");
2610 return;
2614 void callback_color_invoke(GtkAction * action, gpointer data)
2616 MainView *mainview = (MainView *) data;
2617 g_assert(mainview != NULL && mainview->data != NULL);
2618 gtk_button_clicked(GTK_BUTTON(mainview->colorbutton_tb));
2623 void callback_pressure(GtkAction * action, MainView *mainview)
2625 g_assert(mainview != NULL && mainview->data != NULL);
2627 nodeData *nd = getSelectedNode(mainview);
2629 if (nd == NULL)
2630 return;
2631 if (nd->typ != NODE_SKETCH)
2632 return;
2634 /* pressure sensitivity disabled for now...
2635 mainview->sk->pressuresensitivity=gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(mainview->tools_pressure));*/
2639 void callback_wordwrap(GtkAction * action, MainView *mainview)
2641 g_assert(mainview != NULL && mainview->data != NULL);
2643 nodeData *nd = getSelectedNode(mainview);
2645 if (nd == NULL)
2646 return;
2647 if (nd->typ != NODE_TEXT)
2648 return;
2650 gboolean act=gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(mainview->tools_wordwrap));
2651 if (act==TRUE) nd->flags |= NODEFLAG_WORDWRAP;
2652 else nd->flags &= ~NODEFLAG_WORDWRAP;
2654 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(mainview->textview), (act==TRUE)?GTK_WRAP_WORD:GTK_WRAP_NONE);
2658 void callback_font(GtkAction * action, gpointer data)
2660 MainView *mainview = (MainView *) data;
2661 g_assert(mainview != NULL && mainview->data != NULL);
2663 nodeData *nd = getSelectedNode(mainview);
2665 if (nd == NULL)
2666 return;
2667 if (nd->typ != NODE_TEXT)
2668 return;
2670 HildonFontSelectionDialog *dialog = HILDON_FONT_SELECTION_DIALOG(hildon_font_selection_dialog_new(NULL, NULL));
2672 gboolean gotsel=wp_text_buffer_has_selection(mainview->buffer);
2673 /*gotsel=FALSE;*/
2675 WPTextBufferFormat fmt;
2676 wp_text_buffer_get_attributes(mainview->buffer, &fmt, gotsel);
2678 gint ri=0;
2679 if (fmt.text_position==TEXT_POSITION_SUPERSCRIPT) ri=1;
2680 else if (fmt.text_position==TEXT_POSITION_SUBSCRIPT) ri=-1;
2682 g_object_set(G_OBJECT(dialog),
2683 "family-set", fmt.cs.font,
2684 "family", wp_get_font_name(fmt.font),
2685 "size-set", fmt.cs.font_size,
2686 "size", wp_font_size[fmt.font_size],
2687 "color-set", fmt.cs.color,
2688 "color", &fmt.color,
2689 "bold-set", fmt.cs.bold,
2690 "bold", fmt.bold,
2691 "italic-set", fmt.cs.italic,
2692 "italic", fmt.italic,
2693 "underline-set", fmt.cs.underline,
2694 "underline", fmt.underline,
2695 "strikethrough-set", fmt.cs.strikethrough,
2696 "strikethrough", fmt.strikethrough,
2697 "position-set", fmt.cs.text_position,
2698 "position", ri,
2699 NULL);
2701 gtk_widget_show_all(GTK_WIDGET(dialog));
2702 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
2704 gboolean bold, italic, underline, strikethrough;
2705 gchar *family = NULL;
2706 gint size, position;
2707 GdkColor *color=NULL;
2708 gboolean set_family, set_size, set_bold, set_italic, set_underline, set_strikethrough, set_color, set_position;
2710 g_object_get(G_OBJECT(dialog), "family", &family, "size", &size, "bold", &bold, "italic", &italic,
2711 "underline", &underline, "strikethrough", &strikethrough,
2712 "family-set", &set_family, "size-set", &set_size, "bold-set", &set_bold, "italic-set", &set_italic,
2713 "underline-set", &set_underline, "strikethrough-set", &set_strikethrough,
2714 "color", &color, "color-set", &set_color, "position", &position, "position-set", &set_position,
2715 NULL);
2717 wp_text_buffer_get_attributes(mainview->buffer, &fmt, FALSE);
2718 fmt.cs.font=fmt.cs.font_size=fmt.cs.strikethrough=fmt.cs.color=fmt.cs.bold=fmt.cs.italic=fmt.cs.underline=fmt.cs.text_position=0;
2720 if (set_family) { fmt.font=wp_get_font_index(family, 1); fmt.cs.font=1; }
2721 if (set_size) { fmt.font_size=wp_get_font_size_index(size, 16); fmt.cs.font_size=1; }
2723 if (set_strikethrough)
2725 fmt.cs.strikethrough=1;
2726 fmt.strikethrough=strikethrough;
2729 if (set_color)
2732 GLIB WARNING ** GLib-GObject - IA__g_object_set_valist: object class `GtkTextTag' has no property named `'
2734 fmt.cs.color=1;
2735 fmt.color.pixel=color->pixel;
2736 fmt.color.red=color->red;
2737 fmt.color.green=color->green;
2738 fmt.color.blue=color->blue;
2741 if (set_position)
2743 if (position==1) ri=TEXT_POSITION_SUPERSCRIPT;
2744 else if (position==-1) ri=TEXT_POSITION_SUBSCRIPT;
2745 else ri=TEXT_POSITION_NORMAL;
2747 fmt.cs.text_position=1;
2748 fmt.text_position=ri;
2751 if (set_bold)
2753 fmt.cs.bold=1;
2754 fmt.bold=bold;
2756 if (set_italic)
2758 fmt.cs.italic=1;
2759 fmt.italic=italic;
2761 if (set_underline)
2763 fmt.cs.underline=1;
2764 fmt.underline=underline;
2767 wp_text_buffer_set_format(mainview->buffer, &fmt);
2770 gtk_widget_destroy(GTK_WIDGET(dialog));
2773 void callback_fontstyle(GtkAction * action, GtkWidget * wid)
2775 MainView *mainview = gtk_object_get_data(GTK_OBJECT(wid), "m");
2776 g_assert(mainview != NULL && mainview->data != NULL);
2778 nodeData *nd = getSelectedNode(mainview);
2780 if (nd == NULL)
2781 return;
2782 if (nd->typ == NODE_TEXT)
2784 gboolean act=gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(wid));
2786 gint style = (gint)gtk_object_get_data(GTK_OBJECT(wid), "s");
2787 wp_text_buffer_set_attribute(mainview->buffer, style, (gpointer)act);
2789 else if (nd->typ == NODE_CHECKLIST)
2791 gboolean act=gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(wid));
2792 gint style = (gint)gtk_object_get_data(GTK_OBJECT(wid), "s");
2793 if (style!=WPT_BOLD && style!=WPT_STRIKE && style!=WPT_LEFT) return;
2795 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->listview));
2796 GList* l=gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->listview)), NULL);
2798 gint styletoset_weight=PANGO_WEIGHT_NORMAL;
2799 gboolean styletoset_strike=FALSE;
2800 gboolean checkit=FALSE;
2802 if (style==WPT_BOLD && act==TRUE) styletoset_weight=PANGO_WEIGHT_BOLD;
2803 else if (style==WPT_STRIKE && act==TRUE) styletoset_strike=TRUE;
2804 else if (style==WPT_LEFT && act==TRUE) checkit=TRUE;
2806 GList* cur=l;
2807 while(cur)
2809 GtkTreePath *path=cur->data;
2811 GtkTreeIter iter;
2812 if (gtk_tree_model_get_iter(model, &iter, path))
2814 if (style==WPT_BOLD) gtk_list_store_set(GTK_LIST_STORE(model), &iter, CHECKNODE_BOLD, styletoset_weight, -1);
2815 else if (style==WPT_STRIKE) gtk_list_store_set(GTK_LIST_STORE(model), &iter, CHECKNODE_STRIKE, styletoset_strike, -1);
2816 else if (style==WPT_LEFT) {
2817 gtk_list_store_set(GTK_LIST_STORE(model), &iter, CHECKNODE_CHECKED, checkit, -1);
2818 if (checkit) {
2819 gtk_list_store_set(GTK_LIST_STORE(model), &iter, CHECKNODE_ICON_NAME, "widgets_tickmark_list", -1);
2820 } else {
2821 gtk_list_store_set(GTK_LIST_STORE(model), &iter, CHECKNODE_ICON_NAME, "", -1);
2825 gtk_tree_path_free(path);
2826 cur=cur->next;
2829 g_list_free(l);
2830 mainview->checklist_edited = TRUE;
2835 void callback_textbuffer_move(WPTextBuffer *textbuffer, MainView *mainview)
2837 g_assert(mainview != NULL && mainview->data != NULL);
2840 gboolean gotsel=wp_text_buffer_has_selection(mainview->buffer);
2842 _toggle_tool_button_set_inconsistent(GTK_TOGGLE_TOOL_BUTTON(mainview->bold_tb), gotsel);
2843 _toggle_tool_button_set_inconsistent(GTK_TOGGLE_TOOL_BUTTON(mainview->italic_tb), gotsel);
2844 _toggle_tool_button_set_inconsistent(GTK_TOGGLE_TOOL_BUTTON(mainview->underline_tb), gotsel);
2845 _toggle_tool_button_set_inconsistent(GTK_TOGGLE_TOOL_BUTTON(mainview->bullet_tb), gotsel);
2847 WPTextBufferFormat fmt;
2848 wp_text_buffer_get_attributes(mainview->buffer, &fmt, FALSE/*gotsel*/);
2850 g_signal_handlers_block_by_func(mainview->bold_tb, callback_fontstyle, mainview->bold_tb);
2851 g_signal_handlers_block_by_func(mainview->italic_tb, callback_fontstyle, mainview->italic_tb);
2852 g_signal_handlers_block_by_func(mainview->underline_tb, callback_fontstyle, mainview->underline_tb);
2853 g_signal_handlers_block_by_func(mainview->bullet_tb, callback_fontstyle, mainview->bullet_tb);
2855 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->bold_tb), fmt.bold);
2856 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->italic_tb), fmt.italic);
2857 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->underline_tb), fmt.underline);
2858 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->bullet_tb), fmt.bullet);
2860 g_signal_handlers_unblock_by_func(mainview->bold_tb, callback_fontstyle, mainview->bold_tb);
2861 g_signal_handlers_unblock_by_func(mainview->italic_tb, callback_fontstyle, mainview->italic_tb);
2862 g_signal_handlers_unblock_by_func(mainview->underline_tb, callback_fontstyle, mainview->underline_tb);
2863 g_signal_handlers_unblock_by_func(mainview->bullet_tb, callback_fontstyle, mainview->bullet_tb);
2866 gint wp_savecallback(const gchar *buffer, GString * gstr)
2868 gstr=g_string_append(gstr, buffer);
2869 return(0);
2872 void callback_undo(GtkAction * action, MainView * mainview)
2874 g_assert(mainview != NULL && mainview->data != NULL);
2876 nodeData *nd = getSelectedNode(mainview);
2878 if (nd == NULL) return;
2880 if (nd->typ == NODE_SKETCH) sketchwidget_undo(mainview->sk);
2881 else if (nd->typ == NODE_TEXT) wp_text_buffer_undo(mainview->buffer);
2884 void callback_redo(GtkAction * action, MainView * mainview)
2886 g_assert(mainview != NULL && mainview->data != NULL);
2888 nodeData *nd = getSelectedNode(mainview);
2890 if (nd == NULL) return;
2892 if (nd->typ == NODE_SKETCH) sketchwidget_redo(mainview->sk);
2893 else if (nd->typ == NODE_TEXT) wp_text_buffer_redo(mainview->buffer);
2896 void callback_undotoggle(gpointer widget, gboolean st, MainView * mainview)
2898 g_assert(mainview != NULL && mainview->data != NULL);
2900 gtk_widget_set_sensitive(GTK_WIDGET(mainview->undo_tb), st);
2903 void callback_redotoggle(gpointer widget, gboolean st, MainView * mainview)
2905 g_assert(mainview != NULL && mainview->data != NULL);
2907 gtk_widget_set_sensitive(GTK_WIDGET(mainview->redo_tb), st);
2910 gboolean close_cb(GtkWidget * widget, GdkEventAny * event, MainView * mainview)
2912 callback_file_close(NULL, mainview);
2913 return (TRUE);
2916 gboolean key_press_cb(GtkWidget * widget, GdkEventKey * event, MainView * mainview)
2918 switch (event->keyval)
2922 * case GDK_Up:
2923 * gtk_infoprint(GTK_WINDOW(app), "Navigation Key Up");
2924 * return TRUE;
2926 * case GDK_Down:
2927 * gtk_infoprint(GTK_WINDOW(app), "Navigation Key Down");
2928 * return TRUE;
2930 * case GDK_Left:
2931 * gtk_infoprint(GTK_WINDOW(app), "Navigation Key Left");
2932 * return TRUE;
2934 * case GDK_Right:
2935 * gtk_infoprint(GTK_WINDOW(app), "Navigation Key Right");
2936 * return TRUE;
2938 * case GDK_Return:
2939 * gtk_infoprint(GTK_WINDOW(app), "Navigation Key select");
2940 * return TRUE;
2942 /*code below messes up when you have a textview*/
2944 case GDK_Left:
2945 case GDK_Right:
2947 gtk_widget_child_focus(widget, event->keyval==GDK_Left?GTK_DIR_TAB_BACKWARD:GTK_DIR_TAB_FORWARD);
2948 return TRUE;
2951 case GDK_Left:
2953 nodeData *selnode = getSelectedNode(mainview);
2954 if (selnode!=NULL && selnode->typ==NODE_SKETCH)
2956 show_banner(mainview, _("Squared shapes ON"));
2957 sketchwidget_set_shift(mainview->sk, TRUE);
2958 return TRUE;
2960 return FALSE;
2962 case GDK_Right:
2964 nodeData *selnode = getSelectedNode(mainview);
2965 if (selnode!=NULL && selnode->typ==NODE_SKETCH)
2967 show_banner(mainview, _("Squared shapes OFF"));
2968 sketchwidget_set_shift(mainview->sk, FALSE);
2969 return TRUE;
2971 return FALSE;
2973 case GDK_Down:
2975 nodeData *selnode = getSelectedNode(mainview);
2976 if (selnode!=NULL && selnode->typ==NODE_SKETCH)
2978 show_banner(mainview, _("Filled shapes OFF"));
2979 sketchwidget_set_fillmode(mainview->sk, FALSE);
2980 return TRUE;
2982 return FALSE;
2984 case GDK_Up:
2986 nodeData *selnode = getSelectedNode(mainview);
2987 if (selnode!=NULL && selnode->typ==NODE_SKETCH)
2989 show_banner(mainview, _("Filled shapes ON"));
2990 sketchwidget_set_fillmode(mainview->sk, TRUE);
2991 return TRUE;
2993 return FALSE;
2995 case GDK_F7:
2997 callback_redo(NULL, mainview);
2998 return TRUE;
3000 case GDK_F8:
3002 callback_undo(NULL, mainview);
3003 return TRUE;
3007 return FALSE;
3010 void callback_fullscreen(GtkToolButton* tool_button, gpointer user_data)
3012 MainView* mainview = (MainView*)user_data;
3013 gtk_window_fullscreen(GTK_WINDOW(mainview->data->node_view));
3016 void callback_buffer_modified(GtkAction * action, gpointer data)
3018 MainView *mainview = (MainView *) data;
3019 g_assert(mainview != NULL && mainview->data != NULL);
3021 mainview->file_edited = TRUE;
3024 GtkTreeRowReference *read_sqlite3_data(MainView * mainview, unsigned int parentid, GtkTreeRowReference * parenttree, unsigned int selected, GtkTreeStore * model)
3026 GtkTreeRowReference *resref = NULL;
3028 char q[256];
3030 g_snprintf(q, sizeof(q), "SELECT nodeid, bodytype, name, nameblob, lastmodified, flags FROM %s WHERE parent=%d ORDER BY ord", datatable_tmpname, parentid);
3032 sqlite3_stmt *stmt = NULL;
3033 const char *dum;
3034 int rc = sqlite3_prepare(mainview->db, q, strlen(q), &stmt, &dum);
3036 if (rc)
3038 fprintf(stderr, "Error %s\n", sqlite3_errmsg(mainview->db));
3039 return (NULL);
3042 rc = SQLITE_BUSY;
3043 while(rc == SQLITE_BUSY || rc == SQLITE_ROW)
3045 rc = sqlite3_step(stmt);
3046 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE || rc == SQLITE_DONE)
3047 break;
3048 else if (rc == SQLITE_ROW)
3050 int nodeid = sqlite3_column_int(stmt, 0);
3051 int typ = sqlite3_column_int(stmt, 1);
3052 const unsigned char *name = sqlite3_column_text(stmt, 2);
3053 const unsigned char *nameblob = sqlite3_column_text(stmt, 3);
3054 int lastmod = sqlite3_column_int(stmt, 4);
3055 int flags = sqlite3_column_int(stmt, 5);
3058 * fprintf(stderr, "CARD=%s TYPE=%d\n", name, typ);
3060 if ((typ != NODE_TEXT && typ != NODE_SKETCH && typ != NODE_CHECKLIST) || (name == NULL && nameblob == NULL))
3064 * fprintf(stderr, "invalid card, skipping\n");
3066 continue;
3069 nodeData *node = g_malloc(sizeof(nodeData));
3071 node->sql3id = nodeid;
3072 node->typ = typ;
3073 node->flags = flags;
3074 node->name = NULL;
3075 node->namepix = NULL;
3076 if (name != NULL) {
3077 node->name = g_strdup((char *)name);
3078 } else {
3079 node->name = g_strdup(_("Unnamed node"));
3081 /*if (nameblob != NULL)
3083 int blobsize = sqlite3_column_bytes(stmt, 3);
3085 GdkPixbufLoader *pl = gdk_pixbuf_loader_new_with_type("png", NULL);
3086 GError *err = NULL;
3088 gdk_pixbuf_loader_write(pl, (guchar *) nameblob, blobsize, &err);
3089 if (err != NULL)
3091 fprintf(stderr, "Error loading nodename! %s\n", err->message);
3092 g_error_free(err);
3093 err = NULL;
3095 gdk_pixbuf_loader_close(pl, NULL);
3096 GdkPixbuf *pixbuf = gdk_pixbuf_loader_get_pixbuf(pl);
3098 if (GDK_IS_PIXBUF(pixbuf))
3099 node->namepix = pixbuf;
3101 node->lastMod = lastmod;
3103 GtkTreeIter parentiter, newiter;
3104 void *par = NULL;
3106 if (parenttree != NULL)
3108 GtkTreePath *pa = gtk_tree_row_reference_get_path(parenttree);
3110 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &parentiter, pa);
3111 gtk_tree_path_free(pa);
3112 par = &parentiter;
3115 gtk_tree_store_append(model, &newiter, par);
3116 gtk_tree_store_set(model, &newiter, NODE_NAME, node->name, NODE_PIXBUF, node->namepix, NODE_DATA, node, -1);
3118 GtkTreePath *pa = gtk_tree_model_get_path(GTK_TREE_MODEL(model), &newiter);
3120 GtkTreeRowReference *newref = gtk_tree_row_reference_new(GTK_TREE_MODEL(model), pa);
3122 if (selected == nodeid)
3123 resref = newref;
3125 gtk_tree_path_free(pa);
3126 GtkTreeRowReference *r = read_sqlite3_data(mainview, nodeid, newref, selected,
3127 model);
3129 if (resref != newref)
3130 gtk_tree_row_reference_free(newref);
3132 if (r != NULL)
3134 if (resref == NULL)
3135 resref = r;
3136 else
3137 gtk_tree_row_reference_free(r); /*safeguard */
3142 if (stmt)
3143 sqlite3_finalize(stmt);
3145 return (resref); /*ref to supposed-to-be-selected treeitem */
3149 * read file
3151 gboolean read_file_to_buffer(MainView * mainview)
3153 char tq[512];
3155 g_assert(mainview != NULL);
3156 gboolean res = FALSE;
3158 gchar *filename = mainview->file_name;
3160 new_file(mainview);
3161 mainview->file_name = filename;
3162 mainview->loading=TRUE;
3164 fprintf(stderr, "read:*%s*\n", filename);
3166 int rc;
3167 sqlite3_stmt *stmt = NULL;
3169 rc = sqlite3_open(filename, &mainview->db);
3172 if (rc)
3174 fprintf(stderr, "Can't open database %s: %s\n", filename, sqlite3_errmsg(mainview->db));
3175 break;
3178 sqlite3_exec(mainview->db, "PRAGMA synchronous = OFF;", NULL, NULL, NULL);
3180 char *q = "SELECT skey, sval FROM settings";
3181 const char *dum;
3183 rc = sqlite3_prepare(mainview->db, q, strlen(q), &stmt, &dum);
3184 if (rc)
3186 fprintf(stderr, "Error %s\n", sqlite3_errmsg(mainview->db));
3187 break;
3190 unsigned int selectedCard = 0;
3193 * fprintf(stderr, "start config\n");
3195 unsigned int curDataVersion = 0;
3196 unsigned int curChecklistVersion = 0;
3198 rc = SQLITE_BUSY;
3199 while(rc == SQLITE_BUSY || rc == SQLITE_ROW)
3201 rc = sqlite3_step(stmt);
3202 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE || rc == SQLITE_DONE)
3203 break;
3204 else if (rc == SQLITE_ROW)
3206 const gchar* col_key = (const gchar*)sqlite3_column_text(stmt, 0);
3207 const gchar* col_val = (const gchar*)sqlite3_column_text(stmt, 1);
3210 * fprintf(stderr, "%s=%s\n", col_key, col_val);
3212 if (!strcmp(col_key, "selectedNode"))
3214 gint tmp = atoi((char *)col_val);
3216 if (tmp > 0)
3217 selectedCard = tmp;
3219 if (!strcmp(col_key, "dataVersion"))
3221 gint tmp = atoi((char *)col_val);
3223 if (tmp > 0)
3224 curDataVersion = tmp;
3226 if (!strcmp(col_key, "checklistVersion"))
3228 gint tmp = atoi((char *)col_val);
3230 if (tmp > 0)
3231 curChecklistVersion = tmp;
3233 if (!strcmp(col_key, "newNodeDlgCreateChild"))
3235 gint tmp = atoi((char *)col_val);
3237 mainview->newnodedialog_createchild = TRUE;
3238 if (tmp == 0)
3239 mainview->newnodedialog_createchild = FALSE;
3241 if (!strcmp(col_key, "brushSize"))
3243 gint tmp = atoi((char *)col_val);
3244 if (tmp>0) sk_set_brushsize(mainview, tmp);
3246 if (!strcmp(col_key, "brushColor"))
3248 unsigned long tmp = atol((char *)col_val);
3249 GdkColor c2;
3251 c2.red = ((tmp & 0xFF0000) >> 16) << 8;
3252 c2.green = ((tmp & 0xFF00) >> 8) << 8;
3253 c2.blue = (tmp & 0xFF) << 8;
3254 /* fprintf(stderr, "READ BRUSHCOLOR is %ul (%d,%d,%d)\n", tmp, c2.red, c2.green, c2.blue);*/
3256 sketchwidget_set_brushcolor(mainview->sk, c2);
3258 if (mainview->current_color != NULL) {
3259 gdk_color_free(mainview->current_color);
3261 mainview->current_color = gdk_color_copy(&c2);
3266 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE)
3268 fprintf(stderr, "Error2 %s\n", sqlite3_errmsg(mainview->db));
3269 break;
3273 * fprintf(stderr, "end config\n");
3275 if (stmt) {
3276 sqlite3_finalize(stmt);
3277 stmt = NULL;
3280 gboolean resback = FALSE;
3282 while(curDataVersion < datatableversion)
3284 if (curDataVersion == 0)
3286 g_snprintf(tq, sizeof(tq), "DROP TABLE %s", datatable_backupname);
3287 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3289 g_snprintf(tq, sizeof(tq), "ALTER TABLE %s RENAME TO %s", datatable_name, datatable_backupname);
3290 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3292 fprintf(stderr, "ERROR backing up table!\n");
3293 break;
3295 resback = TRUE;
3297 g_snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", datatable_name, datatable);
3298 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3300 fprintf(stderr, "ERROR creating table!\n");
3301 break;
3303 g_snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT nodeid, parent, bodytype, name, body, nameblob, bodyblob, lastmodified, ord, 0 FROM %s", datatable_name, datatable_backupname);
3304 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3306 fprintf(stderr, "ERROR copying data!\n");
3307 break;
3310 g_snprintf(tq, sizeof(tq), "DROP TABLE %s", datatable_backupname);
3311 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3313 curDataVersion = datatableversion;
3315 break;
3318 if (curDataVersion != datatableversion)
3320 fprintf(stderr, "Data version mismatch\n");
3322 if (resback == TRUE)
3324 g_snprintf(tq, sizeof(tq), "DROP TABLE %s", datatable_name);
3325 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3326 g_snprintf(tq, sizeof(tq), "ALTER TABLE %s RENAME TO %s", datatable_backupname, datatable_name);
3327 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3330 break;
3334 while(curChecklistVersion < checklisttableversion)
3336 if (curChecklistVersion == 0) /*no checklisttable at all*/
3338 g_snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", checklisttable_name, checklisttable);
3339 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3341 fprintf(stderr, "ERROR creating checklist table!\n");
3342 break;
3344 curChecklistVersion = checklisttableversion;
3346 break;
3350 GtkTreeStore *model = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->treeview)));
3352 g_object_ref(model);
3353 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->treeview), NULL);
3357 char tq[512];
3359 g_snprintf(tq, sizeof(tq), "CREATE%s TABLE %s%s", TEMPTABLE_KEYWORD, datatable_tmpname, datatable);
3360 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3362 fprintf(stderr, "ERROR creating temp table!\n");
3363 break;
3365 g_snprintf(tq, sizeof(tq), "CREATE INDEX %s_index ON %s %s", datatable_tmpname, datatable_tmpname, dataindex);
3366 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3368 fprintf(stderr, "ERROR creating temp index!\n");
3369 break;
3371 g_snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT * FROM %s", datatable_tmpname, datatable_name);
3372 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3374 fprintf(stderr, "ERROR copying data to temp table!\n");
3375 break;
3378 g_snprintf(tq, sizeof(tq), "CREATE%s TABLE %s%s", TEMPTABLE_KEYWORD, checklisttable_tmpname, checklisttable);
3379 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3381 fprintf(stderr, "ERROR creating temp table! (checklist)\n");
3382 break;
3384 g_snprintf(tq, sizeof(tq), "CREATE INDEX %s_index ON %s %s", checklisttable_tmpname, checklisttable_tmpname, checklistindex);
3385 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3387 fprintf(stderr, "ERROR creating temp index! (checklist)\n");
3388 break;
3390 g_snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT * FROM %s", checklisttable_tmpname, checklisttable_name);
3391 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3393 fprintf(stderr, "ERROR copying data to temp table! (checklist)\n");
3394 break;
3397 while(FALSE);
3399 GtkTreeRowReference *selectedRef = read_sqlite3_data(mainview, 0, NULL, selectedCard, model);
3401 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->treeview), GTK_TREE_MODEL(model));
3402 g_object_unref(model);
3403 gtk_tree_view_expand_all(GTK_TREE_VIEW(mainview->treeview));
3405 if (selectedRef != NULL)
3407 GtkTreeIter seliter;
3409 if (ref2iter(GTK_TREE_MODEL(model), selectedRef, &seliter) == TRUE)
3411 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
3412 gtk_tree_selection_select_iter(selection, &seliter);
3415 gtk_tree_row_reference_free(selectedRef);
3417 res = TRUE;
3419 while(FALSE);
3421 if (stmt) {
3422 sqlite3_finalize(stmt);
3426 mainview->loading=FALSE;
3428 return (res);
3432 * write to file
3434 void write_buffer_to_file(MainView * mainview)
3436 fprintf(stderr, "write:*%s*\n", mainview->file_name);
3437 saveCurrentData(mainview);
3439 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->treeview));
3440 /*update ord value in database for all nodes*/
3441 gtk_tree_model_foreach(GTK_TREE_MODEL(model),(GtkTreeModelForeachFunc) foreach_func_update_ord,mainview);
3443 busy_enter(mainview);
3445 char tq[512];
3447 g_snprintf(tq, sizeof(tq), "DROP TABLE %s", misctable_name);
3448 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3450 g_snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", misctable_name, misctable);
3451 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3453 gint nndcc = 1;
3455 if (mainview->newnodedialog_createchild == FALSE)
3456 nndcc = 0;
3457 g_snprintf(tq, sizeof(tq), "INSERT INTO %s VALUES('newNodeDlgCreateChild', '%d');", misctable_name, nndcc);
3458 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3460 nodeData *node = getSelectedNode(mainview);
3462 if (node)
3464 g_snprintf(tq, sizeof(tq), "INSERT INTO %s VALUES('selectedNode', '%d');", misctable_name, node->sql3id);
3465 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3468 guint bsize;
3469 if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(mainview->eraser_tb)) == TRUE)
3471 bsize=mainview->brushsize_backup;
3473 else
3475 bsize=sketchwidget_get_brushsize(mainview->sk);
3477 g_snprintf(tq, sizeof(tq), "INSERT INTO %s VALUES('brushSize', '%d');", misctable_name, bsize);
3478 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3480 if (mainview->current_color == NULL) {
3481 GdkColor color = {0, 0, 0, 0};
3482 mainview->current_color = gdk_color_copy(&color);
3484 unsigned long bcol = ((mainview->current_color->red >> 8) << 16) |
3485 ((mainview->current_color->green >> 8) << 8) |
3486 ((mainview->current_color->blue) >> 8);
3488 /* fprintf(stderr, "BRUSHCOLOR is %d (%d,%d,%d)\n", bcol, col->red, col->green, col->blue);*/
3489 g_snprintf(tq, sizeof(tq), "INSERT INTO %s VALUES('brushColor', '%lu');", misctable_name, bcol);
3490 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3492 g_snprintf(tq, sizeof(tq), "INSERT INTO %s VALUES('dataVersion', '%d');", misctable_name, datatableversion);
3493 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3495 g_snprintf(tq, sizeof(tq), "INSERT INTO %s VALUES('checklistVersion', '%d');", misctable_name, checklisttableversion);
3496 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3498 g_snprintf(tq, sizeof(tq), "DROP TABLE %s", datatable_backupname);
3499 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3500 g_snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", datatable_backupname, datatable);
3501 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3503 fprintf(stderr, "ERROR creating backup table!\n");
3504 show_banner(mainview, _("Error creating backup table"));
3506 busy_leave(mainview);
3507 return;
3509 g_snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT * FROM %s", datatable_backupname, datatable_name);
3510 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3512 fprintf(stderr, "ERROR backing up table!\n");
3513 show_banner(mainview, _("Error creating backup table"));
3515 busy_leave(mainview);
3516 return;
3518 g_snprintf(tq, sizeof(tq), "DELETE FROM %s", datatable_name);
3519 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3521 g_snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT * FROM %s", datatable_name, datatable_tmpname);
3522 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3524 fprintf(stderr, "ERROR saving table!\n");
3525 show_banner(mainview, _("Error saving table"));
3527 g_snprintf(tq, sizeof(tq), "DELETE FROM %s", datatable_name);
3528 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3530 g_snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT * FROM %s", datatable_name, datatable_backupname);
3531 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3533 fprintf(stderr, "ERROR restoring backup! data lost!\n");
3536 busy_leave(mainview);
3537 return;
3540 g_snprintf(tq, sizeof(tq), "DROP TABLE %s", datatable_backupname);
3541 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3543 /*checklist*/
3544 g_snprintf(tq, sizeof(tq), "DROP TABLE %s", checklisttable_backupname);
3545 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3546 g_snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", checklisttable_backupname, checklisttable);
3547 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3549 fprintf(stderr, "ERROR creating backup table! (checklist)\n");
3550 show_banner(mainview, _("Error creating checklist backup table"));
3552 busy_leave(mainview);
3553 return;
3556 g_snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT * FROM %s", checklisttable_backupname, checklisttable_name);
3557 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3559 fprintf(stderr, "ERROR backing up table! (checklist)\n");
3560 show_banner(mainview, _("Error creating checklist backup table"));
3562 busy_leave(mainview);
3563 return;
3565 g_snprintf(tq, sizeof(tq), "DELETE FROM %s", checklisttable_name);
3566 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3568 g_snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT * FROM %s", checklisttable_name, checklisttable_tmpname);
3569 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3571 fprintf(stderr, "ERROR saving table! (checklist)\n");
3572 show_banner(mainview, _("Error saving checklist table"));
3574 g_snprintf(tq, sizeof(tq), "DELETE FROM %s", checklisttable_name);
3575 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3577 g_snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT * FROM %s", checklisttable_name, checklisttable_backupname);
3578 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3580 fprintf(stderr, "ERROR restoring backup! data lost! (checklist)\n");
3582 busy_leave(mainview);
3583 return;
3586 g_snprintf(tq, sizeof(tq), "DROP TABLE %s", checklisttable_backupname);
3587 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3589 mainview->file_edited = FALSE;
3590 busy_leave(mainview);
3591 show_banner(mainview, _("Changes saved"));
3594 void callback_checklist_change(GtkTreeSelection *selection, MainView *mainview)
3596 g_assert(mainview != NULL && mainview->data != NULL);
3598 g_signal_handlers_block_by_func(mainview->bold_tb, callback_fontstyle, mainview->bold_tb);
3599 g_signal_handlers_block_by_func(mainview->strikethru_tb, callback_fontstyle, mainview->strikethru_tb);
3600 g_signal_handlers_block_by_func(mainview->check_tb, callback_fontstyle, mainview->check_tb);
3602 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->bold_tb), FALSE);
3603 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->strikethru_tb), FALSE);
3604 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->check_tb), FALSE);
3606 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->listview));
3607 GList* l=gtk_tree_selection_get_selected_rows(selection, NULL);
3609 gboolean gotit=FALSE;
3611 GList* cur=l;
3612 while(cur)
3614 GtkTreePath *path=cur->data;
3616 if (!gotit)
3618 GtkTreeIter iter;
3619 if (gtk_tree_model_get_iter(model, &iter, path))
3621 gint styletoset_weight;
3622 gboolean styletoset_strike;
3623 gboolean ischecked;
3625 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHECKNODE_BOLD, &styletoset_weight, CHECKNODE_STRIKE, &styletoset_strike, CHECKNODE_CHECKED, &ischecked, -1);
3626 if (styletoset_weight==PANGO_WEIGHT_BOLD) gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->bold_tb), TRUE);
3627 if (styletoset_strike==TRUE) gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->strikethru_tb), TRUE);
3628 if (ischecked==TRUE) gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->check_tb), TRUE);
3629 gotit=TRUE;
3632 gtk_tree_path_free(path);
3633 cur=cur->next;
3636 g_list_free(l);
3638 g_signal_handlers_unblock_by_func(mainview->bold_tb, callback_fontstyle, mainview->bold_tb);
3639 g_signal_handlers_unblock_by_func(mainview->strikethru_tb, callback_fontstyle, mainview->strikethru_tb);
3640 g_signal_handlers_unblock_by_func(mainview->check_tb, callback_fontstyle, mainview->check_tb);
3643 void callback_checklist_paste(MainView *mainview)
3645 g_assert(mainview != NULL && mainview->data != NULL);
3646 gchar **entries;
3647 gint length, i;
3649 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->listview));
3650 GtkTreeIter toplevel;
3651 gchar *pasted_text = gtk_clipboard_wait_for_text(mainview->clipboard);
3653 entries = g_strsplit(pasted_text, "\n", 0);
3654 length = g_strv_length(entries);
3656 for (i=0; i<length; i++) {
3657 gtk_list_store_append(GTK_LIST_STORE(model), &toplevel);
3658 gtk_list_store_set(GTK_LIST_STORE(model), &toplevel, CHECKNODE_CHECKED, FALSE, CHECKNODE_TEXT, entries[i], -1);
3661 mainview->checklist_edited = TRUE;
3662 g_free(pasted_text);
3663 g_strfreev(entries);
3666 void callback_checklist_add(GtkAction *action, MainView *mainview)
3668 g_assert(mainview != NULL && mainview->data != NULL);
3670 gchar* text = show_line_edit_dialog(mainview, _("Add new checklist item"), _("Name:"), _("Add"), "");
3672 if (text != NULL) {
3673 GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->listview));
3674 GtkTreeIter toplevel;
3675 gtk_list_store_append(GTK_LIST_STORE(model), &toplevel);
3677 gtk_list_store_set(GTK_LIST_STORE(model),
3678 &toplevel,
3679 CHECKNODE_CHECKED, FALSE,
3680 CHECKNODE_TEXT, text,
3681 -1);
3683 GtkTreePath *path = gtk_tree_model_get_path(model, &toplevel);
3684 if (path) {
3685 gtk_tree_view_set_cursor(GTK_TREE_VIEW(mainview->listview), path, mainview->listtextcol, FALSE);
3686 gtk_tree_path_free(path);
3689 mainview->checklist_edited = TRUE;
3693 void callback_checklist_edit(GtkAction *action, MainView *mainview)
3695 g_assert(mainview != NULL && mainview->data != NULL);
3697 GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->listview));
3699 if (gtk_tree_selection_count_selected_rows(selection) == 0) {
3700 show_banner(mainview, _("Select items first"));
3701 return;
3704 GtkTreeModel* model;
3705 GtkTreeIter iter;
3707 if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
3708 gchar* old_text = NULL;
3709 gtk_tree_model_get(model, &iter, CHECKNODE_TEXT, &old_text, -1);
3711 gchar* new_text = show_line_edit_dialog(mainview, _("Edit checklist item"), _("New name:"), _("Save"), old_text);
3713 if (new_text != NULL) {
3714 gtk_list_store_set(GTK_LIST_STORE(model), &iter, CHECKNODE_TEXT, new_text, -1);
3715 g_free(new_text);
3718 g_free(old_text);
3721 mainview->checklist_edited = TRUE;
3724 void callback_checklist_delete(GtkAction *action, MainView *mainview)
3726 g_assert(mainview != NULL && mainview->data != NULL);
3728 if (gtk_tree_selection_count_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->listview)))==0) {
3729 show_banner(mainview, _("Select items first"));
3730 return;
3733 if (show_confirmation(mainview, _("Delete selected checklist item?"))) {
3734 callback_checklist_delete_real(mainview);
3738 void callback_checklist_delete_real(MainView* mainview)
3740 GtkTreeModel *model=gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->listview));
3741 GList* l=gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->listview)), NULL);
3743 GList* rowrefs=NULL;
3744 GList* cur=l;
3745 while(cur)
3747 GtkTreePath *path=cur->data;
3749 GtkTreeIter iter;
3750 if (gtk_tree_model_get_iter(model, &iter, path))
3752 GtkTreeRowReference *rowref = gtk_tree_row_reference_new(model, path);
3753 rowrefs=g_list_append(rowrefs, rowref);
3755 gtk_tree_path_free(path);
3756 cur=cur->next;
3758 g_list_free(l);
3760 g_object_ref(model);
3761 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->listview), NULL);
3763 cur=rowrefs;
3764 while(cur)
3766 GtkTreeRowReference *rowref=cur->data;
3767 GtkTreePath *path= gtk_tree_row_reference_get_path(rowref);
3768 if (path)
3770 GtkTreeIter iter;
3771 if (gtk_tree_model_get_iter(model, &iter, path)) gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
3772 gtk_tree_path_free(path);
3774 gtk_tree_row_reference_free(rowref);
3775 cur=cur->next;
3777 g_list_free(rowrefs);
3779 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->listview), model);
3780 g_object_unref(model);
3781 mainview->checklist_edited = TRUE;
3784 /* Ask the user for confirmation of a specific action */
3785 gboolean
3786 show_confirmation(MainView* mainview, gchar* question)
3788 GtkDialog* dialog = GTK_DIALOG(hildon_note_new_confirmation(
3789 GTK_WINDOW(mainview->data->main_view), question));
3790 gtk_window_set_transient_for(GTK_WINDOW(dialog), mainview_get_dialog_parent(mainview));
3792 gint response = gtk_dialog_run(dialog);
3793 gtk_widget_destroy(GTK_WIDGET(dialog));
3795 return (response == GTK_RESPONSE_OK);
3798 /* Show a information banner to the user (non-modal) */
3799 void
3800 show_banner(MainView* mainview, const gchar* text)
3802 hildon_banner_show_information(GTK_WIDGET(mainview_get_dialog_parent(mainview)), NULL, text);
3805 /* Let the user enter or edit a line of text */
3806 gchar*
3807 show_line_edit_dialog(MainView* mainview, const gchar* title, const gchar* label_text, const gchar* action, const gchar* text)
3809 GtkWidget* edit_dialog;
3810 GtkWidget* label;
3811 GtkWidget* entry;
3812 GtkWidget* hbox;
3813 gchar* result = NULL;
3815 edit_dialog = GTK_WIDGET(gtk_dialog_new());
3816 gtk_window_set_title(GTK_WINDOW(edit_dialog), title);
3817 gtk_window_set_transient_for(GTK_WINDOW(edit_dialog), mainview_get_dialog_parent(mainview));
3819 label = GTK_WIDGET(gtk_label_new(label_text));
3821 entry = hildon_entry_new(HILDON_SIZE_AUTO);
3822 gtk_entry_set_text(GTK_ENTRY(entry), text);
3823 gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
3824 gtk_editable_select_region(GTK_EDITABLE(entry), 0, -1);
3826 gtk_dialog_add_button(GTK_DIALOG(edit_dialog), action, GTK_RESPONSE_OK);
3827 gtk_dialog_set_default_response(GTK_DIALOG(edit_dialog), GTK_RESPONSE_OK);
3829 hbox = GTK_WIDGET(gtk_hbox_new(FALSE, 10));
3831 gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(edit_dialog))), GTK_WIDGET(hbox));
3832 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
3833 gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
3835 gtk_widget_show_all(GTK_WIDGET(hbox));
3837 while (TRUE) {
3838 if (gtk_dialog_run(GTK_DIALOG(edit_dialog)) == GTK_RESPONSE_OK) {
3839 result = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
3840 if (strcmp(result, "") != 0) {
3841 break;
3842 } else {
3843 show_banner(mainview, _("Please enter a non-empty text"));
3844 g_free(result);
3845 result = NULL;
3847 } else {
3848 result = NULL;
3849 break;
3853 gtk_widget_destroy(GTK_WIDGET(edit_dialog));
3854 return result;