Fix compiler warnings for callbacks.c
[maepad.git] / src / ui / callbacks.c
blob927cb1a828b4fe26693b79eb4cd1f2ed32870022
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 && gtk_object_get_data(GTK_OBJECT(mainview->listview), "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 gtk_object_set_data(GTK_OBJECT(mainview->listview), "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 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("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 gtk_object_set_data(GTK_OBJECT(mainview->listview), "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 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("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 nntb_toggled(GtkToggleButton *togglebutton, gpointer user_data)
903 newNodeToggleButtons *nntb = (newNodeToggleButtons*)user_data;
904 static gboolean toggle_in_progress = FALSE;
906 /* The toggle_in_progress flag is needed, because the toggled
907 * signal is emitted when setting the active property of the
908 * GtkToggleButtons below - this would result in an endless
909 * recursion - so we don't allow recursive toggle signals. */
911 if (toggle_in_progress) return;
913 toggle_in_progress = TRUE;
914 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(nntb->rbt), FALSE);
915 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(nntb->rbs), FALSE);
916 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(nntb->rbc), FALSE);
917 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(togglebutton), TRUE);
918 toggle_in_progress = FALSE;
921 void show_sketch_widget(GtkWidget *widget, gpointer user_data)
923 GtkWidget *dialog = (GtkWidget*)user_data;
925 /* Show the sketch widget and hide the entry + draw button */
926 gtk_widget_show(gtk_object_get_data(GTK_OBJECT(dialog), "al"));
927 gtk_widget_hide(gtk_object_get_data(GTK_OBJECT(dialog), "draw_button"));
928 gtk_widget_hide(gtk_object_get_user_data(GTK_OBJECT(dialog)));
931 void new_node_dialog(nodeType typ, MainView * mainview)
933 GtkWidget *dialog, *entry, *but_ok, *vbox, *hbox, *al, *cb;
934 GtkWidget *rb1, *rb2, *rb3;
935 GtkWidget *hb;
936 gchar datetime_str[200];
937 time_t t_now;
938 struct tm *tm_now;
939 gboolean datetime_written = FALSE;
941 t_now = time(NULL);
942 tm_now = localtime(&t_now);
944 if (tm_now != NULL) {
945 if (strftime(datetime_str, sizeof(datetime_str), "%y-%m-%d %H:%M", tm_now) != 0) {
946 datetime_written = TRUE;
950 if (datetime_written == FALSE) {
951 /* Was not able to determine a datetime string - use default */
952 fprintf(stderr, "Warning: cannot resolve time!\n");
953 strncpy(datetime_str, _("New memo"), sizeof(datetime_str));
954 datetime_str[sizeof(datetime_str)-1] = '\0';
957 newNodeToggleButtons *nntb = g_malloc(sizeof(newNodeToggleButtons));
959 dialog = gtk_dialog_new();
960 gtk_window_set_title(GTK_WINDOW(dialog), _("Create new memo"));
961 gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
963 g_signal_connect(G_OBJECT(dialog), "key_press_event", G_CALLBACK(newnodedlg_key_press_cb), dialog);
965 vbox = gtk_vbox_new(FALSE, 0);
967 hbox = gtk_hbox_new(TRUE, 0);
969 /* Text note toggle button */
970 rb1 = hildon_gtk_radio_button_new(HILDON_SIZE_FINGER_HEIGHT, NULL);
971 gtk_button_set_label(GTK_BUTTON(rb1), _("Rich text"));
972 gtk_button_set_image(GTK_BUTTON(rb1), gtk_image_new_from_file(PIXMAPDIR "/text.png"));
973 gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(rb1), TRUE, TRUE, 0);
974 g_signal_connect(G_OBJECT(rb1), "toggled", G_CALLBACK(nntb_toggled), nntb);
975 nntb->rbt = rb1;
977 /* Sketch toggle button */
978 rb2 = hildon_gtk_radio_button_new_from_widget(HILDON_SIZE_FINGER_HEIGHT, GTK_RADIO_BUTTON(rb1));
979 gtk_button_set_label(GTK_BUTTON(rb2), _("Sketch"));
980 gtk_button_set_image(GTK_BUTTON(rb2), gtk_image_new_from_file(PIXMAPDIR "/sketch.png"));
981 gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(rb2), TRUE, TRUE, 0);
982 g_signal_connect(G_OBJECT(rb2), "toggled", G_CALLBACK(nntb_toggled), nntb);
983 nntb->rbs = rb2;
985 /* Checklist toggle button */
986 rb3 = hildon_gtk_radio_button_new_from_widget(HILDON_SIZE_FINGER_HEIGHT, GTK_RADIO_BUTTON(rb1));
987 gtk_button_set_label(GTK_BUTTON(rb3), _("Checklist"));
988 gtk_button_set_image(GTK_BUTTON(rb3), gtk_image_new_from_file(PIXMAPDIR "/checklist.png"));
989 gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(rb3), TRUE, TRUE, 0);
990 g_signal_connect(G_OBJECT(rb3), "toggled", G_CALLBACK(nntb_toggled), nntb);
991 nntb->rbc = rb3;
993 /* Set mode to 0 to get correct styling */
994 gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(rb1), FALSE);
995 gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(rb2), FALSE);
996 gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(rb3), FALSE);
998 /* Remember "new note toggle buttons" list */
999 gtk_object_set_data(GTK_OBJECT(dialog), "nntb", nntb);
1001 if (typ == NODE_TEXT) {
1002 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rb1), TRUE);
1003 } else if (typ == NODE_SKETCH) {
1004 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rb2), TRUE);
1005 } else {
1006 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rb3), TRUE);
1009 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
1011 but_ok = gtk_dialog_add_button(GTK_DIALOG(dialog), _("Create"), GTK_RESPONSE_OK);
1012 g_signal_connect(G_OBJECT(but_ok), "clicked", G_CALLBACK(callback_new_node_real), dialog);
1014 gtk_object_set_data(GTK_OBJECT(dialog), "m", mainview);
1016 hb = gtk_hbox_new(FALSE, 10);
1017 gtk_box_pack_start(GTK_BOX(hb), gtk_label_new(_("Name:")), FALSE, FALSE, 0);
1018 entry = hildon_entry_new(HILDON_SIZE_AUTO);
1019 gtk_object_set_user_data(GTK_OBJECT(dialog), entry);
1020 gtk_entry_set_text(GTK_ENTRY(entry), datetime_str);
1021 gtk_editable_select_region(GTK_EDITABLE(entry), 0, -1);
1022 gtk_box_pack_start(GTK_BOX(hb), entry, TRUE, TRUE, 0);
1024 /* Sketch widget, hidden by default */
1025 al = gtk_alignment_new(0.5, 0.5, 0, 0);
1026 SketchWidget *s = sketchwidget_new(SKETCHNODE_X, SKETCHNODE_Y, TRUE);
1027 gtk_object_set_data(GTK_OBJECT(dialog), "sk", s);
1028 gtk_object_set_data(GTK_OBJECT(dialog), "al", al);
1029 sketchwidget_set_brushsize(s, 2);
1030 sketchwidget_set_backstyle(s, SKETCHBACK_GRAPH);
1031 gtk_widget_set_size_request(sketchwidget_get_mainwidget(s), SKETCHNODE_X, SKETCHNODE_Y);
1032 gtk_container_add(GTK_CONTAINER(al), sketchwidget_get_mainwidget(s));
1033 gtk_box_pack_start(GTK_BOX(hb), al, FALSE, FALSE, 0);
1035 /*but_sketch = hildon_button_new_with_text(
1036 HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH,
1037 HILDON_BUTTON_ARRANGEMENT_VERTICAL,
1038 _("Use sketch label"), NULL);
1040 gtk_object_set_data(GTK_OBJECT(dialog), "draw_button", but_sketch);
1041 gtk_signal_connect(GTK_OBJECT(but_sketch), "clicked", G_CALLBACK(show_sketch_widget), dialog);
1042 gtk_box_pack_start(GTK_BOX(hb), but_sketch, FALSE, TRUE, 0);*/
1043 gtk_box_pack_start(GTK_BOX(vbox), hb, TRUE, FALSE, 0);
1045 cb = hildon_check_button_new(HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
1046 gtk_button_set_label(GTK_BUTTON(cb), _("Create as child of selected memo"));
1047 hildon_check_button_set_active(HILDON_CHECK_BUTTON(cb), mainview->newnodedialog_createchild);
1048 gtk_box_pack_start(GTK_BOX(vbox), cb, FALSE, FALSE, 0);
1050 gtk_object_set_data(GTK_OBJECT(dialog), "cb", cb);
1052 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), vbox);
1054 gtk_widget_grab_focus(entry);
1056 gtk_widget_show_all(dialog);
1058 /* Hide the sketch widget at first */
1059 gtk_widget_hide(al);
1060 gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
1063 void add_new_node(nodeData * node, MainView * mainview, gboolean ischild)
1065 GtkTreeIter parentiter, newiter;
1066 GtkTreeModel *model;
1067 void *ptr = NULL;
1069 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
1071 if (gtk_tree_selection_get_selected(selection, &model, &parentiter))
1072 ptr = &parentiter;
1074 GtkTreePath *path = NULL;
1076 unsigned int parentnodeid = 0;
1078 if (ptr != NULL)
1080 path = gtk_tree_model_get_path(model, &parentiter);
1082 if (ischild == FALSE)
1084 gtk_tree_path_up(path);
1086 if (gtk_tree_path_get_depth(path) == 0)
1088 /* Selected node is a root node */
1089 ptr = NULL; /* New node can not have a Parent node */
1090 gtk_tree_path_down(path); /*restore path so expand() works */
1092 else if (gtk_tree_path_get_depth(path) > 0)
1094 /* Selected node is a child node */
1095 if (gtk_tree_model_get_iter(model, &parentiter, path))
1096 ptr = &parentiter;
1101 if (ptr != NULL)
1103 nodeData *nd;
1105 gtk_tree_model_get(model, ptr, NODE_DATA, &nd, -1);
1106 if (nd)
1107 parentnodeid = nd->sql3id;
1110 node->sql3id = 0;
1113 sqlite3_stmt *stmt = NULL;
1114 const char *dum;
1115 char tq[512];
1118 * FIXME: ord
1120 g_snprintf(tq, sizeof(tq), "INSERT INTO %s (parent, bodytype, name, nameblob, ord) VALUES (%d, %d, ?, ?, 0);", datatable_tmpname, parentnodeid, node->typ);
1121 int rc = sqlite3_prepare(mainview->db, tq, strlen(tq), &stmt, &dum);
1123 if (rc)
1125 fprintf(stderr, "Error inserting(1): %s\n", sqlite3_errmsg(mainview->db));
1126 break;
1128 if (node->name != NULL)
1129 sqlite3_bind_text(stmt, 1, node->name, strlen(node->name), SQLITE_TRANSIENT);
1130 else
1131 sqlite3_bind_text(stmt, 1, NULL, 0, SQLITE_TRANSIENT);
1133 if (node->namepix != NULL)
1135 gchar *namepixdata = NULL;
1136 gsize datalen = 0;
1138 GError *err = NULL;
1140 if (gdk_pixbuf_save_to_buffer(node->namepix, &namepixdata, &datalen, "png", &err, NULL) == FALSE)
1142 namepixdata = NULL;
1143 datalen = 0;
1144 fprintf(stderr, "Error saving name! %s\n", err->message);
1145 g_error_free(err);
1147 sqlite3_bind_blob(stmt, 2, namepixdata, datalen, SQLITE_TRANSIENT);
1149 else
1150 sqlite3_bind_blob(stmt, 2, NULL, 0, SQLITE_TRANSIENT);
1152 rc = SQLITE_BUSY;
1153 while(rc == SQLITE_BUSY)
1155 rc = sqlite3_step(stmt);
1156 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE || rc == SQLITE_DONE)
1157 break;
1159 sqlite3_finalize(stmt);
1160 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE)
1162 fprintf(stderr, "Error inserting(2): %s\n", sqlite3_errmsg(mainview->db));
1163 break;
1165 node->sql3id = sqlite3_last_insert_rowid(mainview->db);
1167 while(FALSE);
1169 if (node->sql3id == 0)
1171 if (node->name)
1172 g_free(node->name);
1173 if (node->namepix)
1174 g_object_unref(node->namepix);
1175 g_free(node);
1176 if (path)
1177 gtk_tree_path_free(path);
1178 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, "Error creating node");
1179 return;
1182 gtk_tree_store_append(GTK_TREE_STORE(model), &newiter, ptr);
1184 gtk_tree_store_set(GTK_TREE_STORE(model), &newiter, NODE_NAME, node->name, NODE_PIXBUF, node->namepix, NODE_DATA, node, -1);
1186 if (path)
1188 mainview->loading=TRUE; /*only when we have a valid parent*/
1189 gtk_tree_view_expand_row(GTK_TREE_VIEW(mainview->treeview), path, FALSE);
1190 gtk_tree_path_free(path);
1193 gtk_tree_selection_select_iter(selection, &newiter);
1195 mainview->loading=FALSE;
1198 void callback_new_node_real(GtkAction * action, gpointer data)
1200 MainView *mainview;
1202 GtkWidget *dialog = data;
1203 GtkWidget *entry = gtk_object_get_user_data(GTK_OBJECT(dialog));
1205 mainview = gtk_object_get_data(GTK_OBJECT(dialog), "m");
1206 SketchWidget *s = gtk_object_get_data(GTK_OBJECT(dialog), "sk");
1207 GtkWidget *cb = gtk_object_get_data(GTK_OBJECT(dialog), "cb");
1208 newNodeToggleButtons *nntb = gtk_object_get_data(GTK_OBJECT(dialog), "nntb");
1210 nodeType typ = NODE_TEXT;
1211 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(nntb->rbs))) {
1212 typ = NODE_SKETCH;
1213 } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(nntb->rbc))) {
1214 typ = NODE_CHECKLIST;
1216 g_free(nntb);
1218 gchar *txt = NULL;
1220 /*if (GTK_WIDGET_VISIBLE(entry))
1222 txt = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
1223 if (strcmp(txt, "") == 0)
1225 g_free(txt);
1226 return;
1229 else
1231 GtkWidget *sdr = sketchwidget_get_drawingarea(s);
1233 GdkPixmap *spix = sketchwidget_get_Pixmap(s);
1235 pixbuf = gdk_pixbuf_get_from_drawable(NULL, GDK_DRAWABLE(spix), NULL, 0, 0, 0, 0, sdr->allocation.width, sdr->allocation.height);
1236 g_object_unref(spix);
1237 double w, h;
1238 GdkPixbuf *pixbuf2 = sketchwidget_trim_image(pixbuf, SKETCHNODE_X, SKETCHNODE_Y, &w,
1239 &h, TRUE);
1240 if (pixbuf2==NULL) return;
1242 GdkPixbuf *pixbuf3 = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, SKETCHNODE_RX,
1243 SKETCHNODE_RY);
1245 gdk_pixbuf_fill(pixbuf3, 0xffffffff);
1247 if (w <= SKETCHNODE_RX && h <= SKETCHNODE_RY)
1249 gdk_pixbuf_copy_area(pixbuf2, 0, 0, w, h, pixbuf3, 0, (SKETCHNODE_RY - h) / 2);
1251 else
1253 double neww, newh;
1255 if (w > h)
1257 neww = SKETCHNODE_RX;
1258 newh = (h / w) * SKETCHNODE_RX;
1260 else
1262 newh = SKETCHNODE_RY;
1263 neww = (w / h) * SKETCHNODE_RY;
1265 if (newh > SKETCHNODE_RY)
1266 newh = SKETCHNODE_RY;
1268 GdkPixbuf *tmpbuf = gdk_pixbuf_scale_simple(pixbuf2, neww, newh,
1269 GDK_INTERP_BILINEAR);
1271 gdk_pixbuf_copy_area(tmpbuf, 0, 0, neww, newh, pixbuf3, 0, (SKETCHNODE_RY - newh) / 2);
1273 gdk_pixbuf_unref(tmpbuf);
1276 pixbuf = pixbuf3;
1277 gdk_pixbuf_unref(pixbuf2);
1280 nodeData *node;
1282 node = g_malloc(sizeof(nodeData));
1283 node->typ = typ;
1284 node->name = txt;
1285 node->namepix = NULL;
1287 /*if (GTK_WIDGET_VISIBLE(entry))
1289 node->name = txt;
1291 else
1293 node->namepix = pixbuf;
1296 node->lastMod = 0;
1297 node->flags = 0;
1298 node->sql3id = 0;
1300 mainview->newnodedialog_createchild = hildon_check_button_get_active(HILDON_CHECK_BUTTON(cb));
1301 add_new_node(node, mainview, mainview->newnodedialog_createchild);
1303 sketchwidget_destroy(s);
1304 gtk_widget_destroy(dialog);
1305 mainview->file_edited = TRUE;
1309 * delete node
1311 void callback_file_delete_node(GtkAction * action, gpointer data)
1313 MainView *mainview = (MainView *) data;
1314 g_assert(mainview != NULL && mainview->data != NULL);
1316 if (getSelectedNode(mainview) == NULL) {
1317 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Select a node first"));
1318 return;
1321 if (show_confirmation(mainview, _("Delete selected memo?"))) {
1322 callback_delete_node_real(mainview);
1323 gtk_widget_hide(GTK_WIDGET(mainview->data->node_view));
1328 * Callback for Rename Menuitem
1330 void callback_file_rename_node(GtkAction * action, gpointer data)
1332 MainView *mainview = (MainView *) data;
1333 g_assert(mainview != NULL && mainview->data != NULL);
1335 /* Get the selected node */
1336 nodeData *sel_node = getSelectedNode(mainview);
1337 if (!sel_node)
1339 /* Do nothing, if no node has been selected */
1340 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Select a node first"));
1341 return;
1344 if (sel_node->namepix != NULL)
1346 /* the memo has a graphical label, cannot edit! */
1347 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Cannot rename memos with sketch name"));
1348 return;
1351 /* Create dialog box */
1352 GtkWidget *dialog, *label, *entry, *but_ok, *hbox;
1354 dialog = gtk_dialog_new();
1355 gtk_window_set_title(GTK_WINDOW(dialog), _("Rename memo"));
1357 label = gtk_label_new(_("New name:"));
1359 entry = hildon_entry_new(HILDON_SIZE_AUTO);
1360 gtk_entry_set_text (GTK_ENTRY(entry), sel_node->name);
1361 gtk_editable_select_region (GTK_EDITABLE(entry), 0, -1);
1363 but_ok = gtk_dialog_add_button(GTK_DIALOG(dialog), _("Rename"), GTK_RESPONSE_OK);
1365 g_object_set_data(G_OBJECT(dialog), "m", mainview);
1366 g_object_set_data(G_OBJECT(dialog), "e", entry);
1368 g_signal_connect(G_OBJECT(but_ok), "clicked", G_CALLBACK(callback_rename_node_real), dialog);
1370 hbox = GTK_WIDGET(gtk_hbox_new(FALSE, 10));
1372 gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), GTK_WIDGET(hbox));
1373 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1374 gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
1376 gtk_widget_show_all(dialog);
1377 gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
1381 * Callback for Rename Dialog
1383 void callback_rename_node_real (GtkAction *action, gpointer data)
1385 MainView *mainview;
1386 GtkWidget *entry;
1387 GtkTreeIter iter;
1388 GtkTreeModel *model;
1389 nodeData *nd = NULL;
1391 GtkWidget *dialog = data;
1393 mainview = g_object_get_data (G_OBJECT(dialog), "m");
1394 entry = g_object_get_data (G_OBJECT(dialog), "e");
1396 /* Checking whether the entry is empty */
1397 const gchar *new_node_name = gtk_entry_get_text (GTK_ENTRY(entry));
1398 if (strcmp (new_node_name, "") == 0) {
1399 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Name can not be empty"));
1400 return;
1403 /* Get the selected node */
1404 GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(mainview->treeview));
1406 if (!gtk_tree_selection_get_selected (selection, &model, &iter))
1407 return;
1409 gtk_tree_model_get (model, &iter, NODE_DATA, &nd, -1);
1410 if (!nd)
1411 return;
1413 /* If we reach here, all checkings are done */
1414 /* Update the database */
1415 char tq[512];
1416 unsigned int sql3id = nd->sql3id;
1417 sqlite3_stmt *stmt = NULL;
1418 const char* dum;
1419 gboolean db_query_result = FALSE;
1421 /* Update the noteData */
1422 if (nd->name) {
1423 g_free(nd->name);
1425 nd->name = g_strdup(new_node_name);
1427 /* Update the window title of node_view */
1428 gtk_window_set_title(GTK_WINDOW(mainview->data->node_view), nd->name);
1430 do {
1431 g_snprintf (tq, sizeof(tq), "UPDATE %s SET name=\"%s\" WHERE nodeid=%d",
1432 datatable_tmpname, new_node_name, sql3id);
1433 int rc = sqlite3_prepare (mainview->db, tq, strlen(tq), &stmt, &dum);
1435 if (rc) {
1436 fprintf (stderr, "Error preparing db update query: %s\n", sqlite3_errmsg(mainview->db));
1437 break;
1439 rc = SQLITE_BUSY;
1440 while (rc == SQLITE_BUSY) {
1441 rc = sqlite3_step (stmt);
1442 if (rc == SQLITE_DONE) {
1443 db_query_result = TRUE;
1444 break;
1446 else if(rc == SQLITE_ERROR || rc== SQLITE_MISUSE) {
1447 fprintf (stderr, "Error updating node: %s\n", sqlite3_errmsg(mainview->db));
1448 break;
1450 sqlite3_finalize(stmt);
1452 } while (FALSE);
1454 /* Update the tree */
1455 if (db_query_result)
1456 gtk_tree_store_set (GTK_TREE_STORE(model), &iter, NODE_NAME, new_node_name, -1);
1458 mainview->file_edited = TRUE;
1460 /* Destroy the dialog */
1461 gtk_widget_destroy (dialog);
1464 void callback_file_export_node(GtkAction * action, gpointer data)
1466 MainView *mainview = (MainView *) data;
1467 g_assert(mainview != NULL && mainview->data != NULL);
1469 nodeData *nd=getSelectedNode(mainview);
1470 if (nd == NULL)
1472 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Select a memo first"));
1473 return;
1476 gchar *nodename=nd->name;
1477 if (nodename==NULL) nodename=_("saved memo");
1479 if (nd->typ == NODE_TEXT)
1482 GtkTextIter begin, end;
1483 gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER(mainview->buffer), &begin, &end);
1484 gchar *text = gtk_text_buffer_get_slice(GTK_TEXT_BUFFER(mainview->buffer), &begin, &end, TRUE);
1486 GString *gstr=g_string_sized_new(4096);
1487 wp_text_buffer_save_document(mainview->buffer, (WPDocumentSaveCallback)(wp_savecallback), gstr);
1488 gint textlen=gstr->len;
1489 gchar *text=g_string_free(gstr, FALSE);
1491 if (text==NULL || !strcmp(text, ""))
1493 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Memo is empty"));
1495 else
1497 gchar *fn = interface_file_chooser(mainview, GTK_FILE_CHOOSER_ACTION_SAVE, nodename, "html");
1498 if (fn!=NULL)
1500 GnomeVFSResult vfs_result;
1501 GnomeVFSHandle *handle = NULL;
1502 GnomeVFSFileSize out_bytes;
1503 vfs_result = gnome_vfs_create(&handle, fn, GNOME_VFS_OPEN_WRITE, 0, 0600);
1504 if ( vfs_result != GNOME_VFS_OK ) {
1505 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Export failed"));
1507 else
1509 gnome_vfs_write(handle, text, textlen, &out_bytes);
1510 gnome_vfs_close(handle);
1511 if (out_bytes==strlen(text)) hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Exported"));
1512 else hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Export incomplete"));
1514 g_free(fn);
1517 g_free(text);
1519 else if (nd->typ == NODE_SKETCH)
1521 GdkPixmap *skpix = sketchwidget_get_Pixmap(mainview->sk);
1522 GtkWidget *skdr = sketchwidget_get_drawingarea(mainview->sk);
1523 GdkPixbuf *pixbuf = gdk_pixbuf_get_from_drawable(NULL, GDK_DRAWABLE(skpix), NULL, 0, 0, 0, 0, skdr->allocation.width, skdr->allocation.height);
1524 if (pixbuf==NULL)
1526 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Memo is empty"));
1528 else
1530 gchar *fn = interface_file_chooser(mainview, GTK_FILE_CHOOSER_ACTION_SAVE, nodename, "png");
1531 if (fn!=NULL)
1533 if (gdk_pixbuf_save(pixbuf, fn, "png", NULL, NULL)==FALSE)
1535 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Export failed"));
1537 else
1539 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Exported"));
1541 g_free(fn);
1544 g_object_unref(skpix);
1546 else if (nd->typ == NODE_CHECKLIST)
1548 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Unimplemented"));
1553 * callback from menu item
1554 * move selected node down (switch node with next sibling), don't change level of node
1556 void callback_move_down_node(GtkAction * action, gpointer data)
1558 GtkTreeIter iter;
1559 GtkTreeModel *model;
1561 MainView *mainview = (MainView *) data;
1562 g_assert(mainview != NULL && mainview->data != NULL);
1564 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
1565 gtk_tree_selection_get_selected(selection, &model, &iter);
1567 GtkTreeIter old_iter = iter;/*save pointer to old iter, we will need it during swap nodes*/
1569 if (gtk_tree_model_iter_next(model,&iter)==FALSE)/*get next node*/
1570 return;
1572 GtkTreeStore *treeStore = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->treeview)));
1573 gtk_tree_store_swap(treeStore,&iter,&old_iter);
1575 mainview->file_edited = TRUE;/*we have made changes , if required show "save changes?" dialog in future*/
1579 * callback from menu item
1580 * move selected node down (switch node with prev sibling), don't change level of node
1582 void callback_move_up_node(GtkAction * action, gpointer data)
1584 GtkTreeIter iter;
1585 GtkTreeModel *model;
1587 MainView *mainview = (MainView *) data;
1588 g_assert(mainview != NULL && mainview->data != NULL);
1590 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
1591 gtk_tree_selection_get_selected(selection, &model, &iter);
1593 GtkTreeIter old_iter=iter;/*save pointer to old iter, we will need it during swap nodes*/
1595 if (tree_model_iter_prev(model,&iter)==FALSE)/*get previous node*/
1596 return;
1598 GtkTreeStore *treeStore = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->treeview)));
1599 gtk_tree_store_swap(treeStore,&old_iter,&iter);/*do move*/
1601 mainview->file_edited = TRUE;/*we have made changes , if required show "save changes?" dialog in future*/
1605 * callback from menu item
1606 * we change level of actual node with direction to top
1608 void callback_move_to_top_level_node(GtkAction * action, gpointer data)
1610 GtkTreeIter iter,new_parent;
1611 GtkTreeIter *p_new_parent;
1612 GtkTreeIter parent;
1613 GtkTreeModel *model;
1615 MainView *mainview = (MainView *) data;
1616 g_assert(mainview != NULL && mainview->data != NULL);
1618 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
1619 gtk_tree_selection_get_selected(selection, &model, &iter);
1621 /*at first we need actual parent of selected node*/
1622 if (gtk_tree_model_iter_parent(model,&parent,&iter)==FALSE)
1624 /*if parent of selected node is ROOT we can't go higher*/
1625 return;
1627 /*we need also new parent, it's parent of actual parent*/
1628 if (gtk_tree_model_iter_parent(model,&new_parent,&parent)==FALSE)
1630 /*if our new parent is ROOT we got filled new_parent with invalid value,
1631 so we need set NULL value to p_new_parent (root item)*/
1632 p_new_parent=NULL;
1634 else
1636 p_new_parent=&new_parent;/*we only redirect pointer to treeiter*/
1639 saveCurrentData(mainview);/*we save changes in node befor move*/
1641 /*this move function provide move item with all his children, be careful iter value will change!*/
1642 if (move_node(mainview,p_new_parent,&iter,&parent)==TRUE){
1644 gint id_parent = get_node_id_on_tmp_db(model,p_new_parent);
1645 gint id_node = get_node_id_on_tmp_db(model,&iter);
1646 /*we need also update parent id of moved item*/
1647 char tq[512];
1648 g_snprintf (tq, sizeof(tq), "UPDATE %s SET parent=%d WHERE nodeid=%d",datatable_tmpname,id_parent ,id_node);
1649 exec_command_on_db(mainview,tq);
1651 /*select new created iter*/
1652 gtk_tree_selection_select_iter(selection,&iter);
1654 mainview->file_edited = TRUE;/*we have made changes , if required show "save changes?" dialog in future*/
1659 * callback from menu item
1660 * we change level of actual node with direction to bottom
1661 * previous node will be parent of our actual node
1663 void callback_move_to_bottom_level_node(GtkAction * action, gpointer data)
1665 GtkTreeIter iter;
1666 GtkTreeModel *model;
1668 MainView *mainview = (MainView *) data;
1669 g_assert(mainview != NULL && mainview->data != NULL);
1671 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
1672 gtk_tree_selection_get_selected(selection, &model, &iter);
1674 GtkTreeIter move_iter=iter;/*save pointer to old iter*/
1676 /*we try to get previous node*/
1677 if (tree_model_iter_prev(model,&iter)==FALSE)
1678 return;/*if previous node on the same level doesn't exist we will exit*/
1680 saveCurrentData(mainview);/*we save changes in node befor move*/
1682 /*this move function provide move item with all his children, be careful move_iter value will change!*/
1683 if (move_node(mainview,&iter,&move_iter,NULL)==TRUE)
1685 gint id_parent = get_node_id_on_tmp_db(model,&iter);
1686 gint id_node = get_node_id_on_tmp_db(model,&move_iter);
1688 /*we need also update parent id of moved item*/
1689 char tq[512];
1690 g_snprintf (tq, sizeof(tq), "UPDATE %s SET parent=%d WHERE nodeid=%d",datatable_tmpname,id_parent ,id_node);
1691 exec_command_on_db(mainview,tq);
1693 GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
1694 gtk_tree_view_expand_row(GTK_TREE_VIEW(mainview->treeview), path, FALSE);/*expand parent node*/
1695 gtk_tree_path_free(path);
1697 /*select new created iter*/
1698 gtk_tree_selection_select_iter(selection,&move_iter);
1700 mainview->file_edited = TRUE;/*we have made changes , if required show "save changes?" dialog in future*/
1705 * move item_to_move to new_parent with his children, this function is designed for change level of node
1706 * we copy item_to_move with his children to new position (after item_befor if is not NULL) and then we
1707 * destroy old node with his children, so ! item_to_move is set with new iter, be careful on this!
1709 gboolean move_node(MainView *mainview,GtkTreeIter *new_parent,GtkTreeIter *item_to_move,GtkTreeIter *item_befor)
1711 GtkTreeModel *model;
1713 model=gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->treeview));
1714 GtkTreeStore *treeStore = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->treeview)));
1716 nodeData *node;
1717 gtk_tree_model_get(model, item_to_move, NODE_DATA, &node, -1);/*get data from actual iter*/
1718 if (node)
1720 GtkTreeIter new_iter;/*create new iter*/
1721 gtk_tree_store_append(treeStore,&new_iter,new_parent);/*append new iter to new parent*/
1723 if (item_befor!=NULL)
1724 gtk_tree_store_move_after(treeStore,&new_iter,item_befor);/*sometimes we need set position*/
1726 gtk_tree_store_set(treeStore, &new_iter, NODE_NAME, node->name,NODE_PIXBUF, node->namepix, NODE_DATA, node, -1);/*set data from old iter*/
1728 GtkTreeIter child;
1729 while (gtk_tree_model_iter_children(model, &child, item_to_move)==TRUE)/*move all childrens while some exits*/
1731 if (move_node(mainview,&new_iter,&child,NULL)==FALSE)/*use recursion on children*/
1732 return FALSE;
1735 gtk_tree_store_set(treeStore, item_to_move, NODE_DATA, NULL, -1);
1736 gtk_tree_store_remove(treeStore, item_to_move);/*remove node, data need't remove, they are stored in new node*/
1738 /*we need return new value of moved item, so we need assign new_iter to item_to_move*/
1739 /*this code is ugly : new_iter to path and back to item_to_move*/
1740 GtkTreePath *path=gtk_tree_model_get_path(model,&new_iter);
1741 gtk_tree_model_get_iter(model,item_to_move,path);
1742 gtk_tree_path_free(path);
1744 else
1746 fprintf(stderr,"Get data node failed!\n");
1747 return FALSE;
1750 return TRUE;
1754 * simple execute of sql command which is stored in sql_string[]
1756 gboolean exec_command_on_db(MainView *mainview,char sql_string[])
1758 sqlite3_stmt *stmt = NULL;
1759 const char* dum;
1760 gboolean db_query_result = FALSE;
1762 int rc = sqlite3_prepare (mainview->db, sql_string, strlen(sql_string), &stmt, &dum);
1764 if (rc) {
1765 fprintf (stderr, "Error preparing db update query: %s\n", sqlite3_errmsg(mainview->db));
1766 return FALSE;
1769 rc = SQLITE_BUSY;
1770 while (rc == SQLITE_BUSY) {
1771 rc = sqlite3_step (stmt);
1772 if (rc == SQLITE_DONE) {
1773 db_query_result = TRUE;
1774 break;
1776 else if(rc == SQLITE_ERROR || rc== SQLITE_MISUSE) {
1777 fprintf (stderr, "Error updating node: %s\n", sqlite3_errmsg(mainview->db));
1778 break;
1780 sqlite3_finalize(stmt);
1782 return TRUE;
1786 * 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)
1788 gboolean foreach_func_update_ord (GtkTreeModel *model,GtkTreePath *path,GtkTreeIter *iter, MainView *mainview)
1790 nodeData *node;
1791 gtk_tree_model_get(model, iter, NODE_DATA, &node, -1);
1792 /*we need index of node on actual level*/
1793 gint index=get_branch_node_index(path);
1795 /*prepare to execute update command,and exec it*/
1796 char sql_command[512];
1797 g_snprintf (sql_command, sizeof(sql_command), "UPDATE %s SET ord=\"%d\" WHERE nodeid=%d",datatable_tmpname, index, node->sql3id);
1798 exec_command_on_db(mainview,sql_command);
1800 /*we don't want break gtk_tree_model_foreach function,until we call this func on each node - so we return always FALSE*/
1801 return FALSE;
1805 * return id number of iter (id number which is used to identify in sql database of nodes)
1807 int get_node_id_on_tmp_db(GtkTreeModel *model,GtkTreeIter *iter)
1809 if (iter==NULL)
1810 return 0;/*we got ROOT parent here*/
1812 nodeData *node;
1813 gtk_tree_model_get(model, iter, NODE_DATA, &node, -1);
1814 return node->sql3id;
1818 * get index of node in current branch
1820 gint get_branch_node_index(GtkTreePath *path)
1822 int depth=gtk_tree_path_get_depth(path);
1823 gint *indicies = gtk_tree_path_get_indices(path);
1825 return indicies[depth-1];
1829 * similiar with gtk_tree_model_iter_next (), but opposite
1831 gboolean tree_model_iter_prev(GtkTreeModel *tree_model,GtkTreeIter *iter)
1833 GtkTreePath *path = gtk_tree_model_get_path(tree_model, iter);
1835 if (path==NULL){
1836 fprintf(stderr,"Error: path is null\n");
1837 return FALSE;
1840 if (gtk_tree_path_prev(path)==FALSE)
1841 return FALSE;
1843 gtk_tree_model_get_iter(tree_model, iter,path);
1845 return TRUE;
1848 gboolean ref2iter(GtkTreeModel * model, GtkTreeRowReference * ref, GtkTreeIter * iter)
1850 gboolean res = FALSE;
1851 GtkTreePath *path = gtk_tree_row_reference_get_path(ref);
1853 if (gtk_tree_model_get_iter(model, iter, path))
1855 res = TRUE;
1857 gtk_tree_path_free(path);
1858 return (res);
1861 GtkTreeRowReference *iter2ref(GtkTreeModel * model, GtkTreeIter * iter)
1863 GtkTreeRowReference *ref;
1865 GtkTreePath *path = gtk_tree_model_get_path(model, iter);
1867 ref = gtk_tree_row_reference_new(model, path);
1868 gtk_tree_path_free(path);
1869 return (ref);
1872 void move_nodes_up(GtkTreeModel * model, GtkTreeRowReference * topnode, GtkTreeRowReference * newtop)
1874 GtkTreeIter topiter;
1876 fprintf(stderr, "here2\n");
1878 if (ref2iter(model, topnode, &topiter) == FALSE)
1879 return;
1881 fprintf(stderr, "here3\n");
1883 GtkTreeIter child;
1885 if (gtk_tree_model_iter_children(model, &child, &topiter))
1887 fprintf(stderr, "here4\n");
1888 GtkTreeRowReference *ref;
1889 GList *rr_list = NULL, *node;
1893 ref = iter2ref(model, &child);
1894 rr_list = g_list_append(rr_list, ref);
1896 while(gtk_tree_model_iter_next(model, &child));
1899 * got a reflist for all children
1902 fprintf(stderr, "here5\n");
1903 for(node = rr_list; node; node = node->next)
1905 ref = (GtkTreeRowReference *) (node->data);
1906 if (ref2iter(model, ref, &child))
1908 GtkTreeIter newtopiter, newiter;
1909 GtkTreeIter *newtopiterptr;
1911 if (ref2iter(model, newtop, &newtopiter))
1912 newtopiterptr = &newtopiter;
1913 else
1914 newtopiterptr = NULL;
1916 nodeData *node;
1918 gtk_tree_model_get(model, &child, NODE_DATA, &node, -1);
1920 gtk_tree_store_append(GTK_TREE_STORE(model), &newiter, newtopiterptr);
1921 gtk_tree_store_set(GTK_TREE_STORE(model), &newiter, NODE_NAME, node->name, NODE_PIXBUF, node->namepix, NODE_DATA, node, -1);
1923 GtkTreeRowReference *newref = iter2ref(model, &newiter);
1925 move_nodes_up(model, ref, newref);
1926 gtk_tree_row_reference_free(newref);
1928 gtk_tree_store_remove(GTK_TREE_STORE(model), &child);
1930 gtk_tree_row_reference_free(ref);
1932 fprintf(stderr, "here6\n");
1934 g_list_free(rr_list);
1937 fprintf(stderr, "here7\n");
1941 void callback_delete_node_real(MainView* mainview)
1943 GtkTreeIter iter;
1944 GtkTreeModel *model;
1946 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
1948 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
1949 return;
1951 nodeData *nd;
1953 gtk_tree_model_get(model, &iter, NODE_DATA, &nd, -1);
1954 if (!nd)
1955 return;
1957 mainview->file_edited = TRUE;
1959 unsigned int sql3id = nd->sql3id;
1961 if (nd->name)
1962 g_free(nd->name);
1965 * g_free(nd->data);
1966 * if (nd->pix) g_object_unref(nd->pix);
1968 g_free(nd);
1970 fprintf(stderr, "here1\n");
1971 GtkTreeRowReference *upref = NULL, *ref = NULL;
1973 GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
1975 ref = gtk_tree_row_reference_new(model, path);
1976 if (gtk_tree_path_up(path))
1977 upref = gtk_tree_row_reference_new(model, path);
1978 gtk_tree_path_free(path);
1980 g_object_ref(model);
1981 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->treeview), NULL);
1983 fprintf(stderr, "here! 1\n");
1984 move_nodes_up(model, ref, upref);
1986 fprintf(stderr, "here! 2\n");
1987 if (ref2iter(model, ref, &iter))
1989 char tq[512];
1991 g_snprintf(tq, sizeof(tq), "SELECT parent FROM %s WHERE nodeid=%d", datatable_tmpname, sql3id);
1992 sqlite3_stmt *stmt = NULL;
1993 const char *dum;
1994 int rc = sqlite3_prepare(mainview->db, tq, strlen(tq), &stmt, &dum);
1995 unsigned int sql3parentid = 0;
1997 if (rc)
1999 fprintf(stderr, "Error %s\n", sqlite3_errmsg(mainview->db));
2001 else
2003 rc = SQLITE_BUSY;
2004 while(rc == SQLITE_BUSY || rc == SQLITE_ROW)
2006 rc = sqlite3_step(stmt);
2007 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE || rc == SQLITE_DONE)
2008 break;
2009 else if (rc == SQLITE_ROW)
2011 sql3parentid = sqlite3_column_int(stmt, 0);
2012 break;
2015 sqlite3_finalize(stmt);
2017 g_snprintf(tq, sizeof(tq), "UPDATE %s SET parent=%d WHERE parent=%d;", datatable_tmpname, sql3parentid, sql3id);
2018 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
2019 fprintf(stderr, "ERROR moving nodes up!\n");
2020 else
2022 g_snprintf(tq, sizeof(tq), "DELETE FROM %s WHERE nodeid=%d;", datatable_tmpname, sql3id);
2023 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
2024 fprintf(stderr, "ERROR deleting node!\n");
2026 /* Delete all checklist items that do not have
2027 * a node anymore (= orphaned checklist items) */
2028 g_snprintf(tq, sizeof(tq), "DELETE FROM %s WHERE nodeid NOT IN (SELECT nodeid FROM %s);", checklisttable_tmpname, datatable_tmpname);
2029 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
2030 fprintf(stderr, "ERROR deleting orphaned checklist items!\n");
2033 gtk_tree_store_remove(GTK_TREE_STORE(model), &iter);
2036 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->treeview), model);
2037 g_object_unref(model);
2039 fprintf(stderr, "here! 3\n");
2040 gtk_tree_row_reference_free(ref);
2041 gtk_tree_row_reference_free(upref);
2043 gtk_tree_view_expand_all(GTK_TREE_VIEW(mainview->treeview));
2045 fprintf(stderr, "here10\n");
2048 void callback_edit_clear(GtkAction * action, gpointer data)
2050 MainView *mainview = (MainView *) data;
2051 g_assert(mainview != NULL && mainview->data != NULL);
2052 nodeData *nd = getSelectedNode(mainview);
2054 if (show_confirmation(mainview, _("Remove all contents of this memo?"))) {
2055 switch (nd->typ) {
2056 case NODE_TEXT:
2057 gtk_text_buffer_set_text(GTK_TEXT_BUFFER(mainview->buffer), "", 0);
2058 break;
2059 case NODE_SKETCH:
2060 sketchwidget_clear(mainview->sk);
2061 break;
2062 case NODE_CHECKLIST:
2063 gtk_list_store_clear(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->listview))));
2064 break;
2065 default:
2066 /* Unknown node type */
2067 g_assert(FALSE);
2073 * cut
2075 void callback_edit_cut(GtkAction * action, gpointer data)
2077 MainView *mainview = (MainView *) data;
2078 g_assert(mainview != NULL && mainview->data != NULL);
2080 nodeData *nd = getSelectedNode(mainview);
2082 if (nd->typ == NODE_TEXT)
2083 gtk_text_buffer_cut_clipboard(GTK_TEXT_BUFFER(mainview->buffer), mainview->clipboard, TRUE);
2084 else if (nd->typ == NODE_SKETCH)
2086 if (sketchwidget_cut(mainview->sk, mainview->clipboard)==FALSE)
2087 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Error cutting"));
2089 else if (nd->typ == NODE_CHECKLIST)
2090 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Unimplemented"));
2095 * copy
2097 void callback_edit_copy(GtkAction * action, gpointer data)
2099 MainView *mainview = (MainView *) data;
2100 g_assert(mainview != NULL && mainview->data != NULL);
2102 nodeData *nd = getSelectedNode(mainview);
2104 if (nd->typ == NODE_TEXT)
2105 gtk_text_buffer_copy_clipboard(GTK_TEXT_BUFFER(mainview->buffer), mainview->clipboard);
2106 else if (nd->typ == NODE_SKETCH)
2108 if (sketchwidget_copy(mainview->sk, mainview->clipboard)==FALSE)
2109 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Error copying"));
2111 else if (nd->typ == NODE_CHECKLIST)
2113 /* Copy all selected entries as multiline text (1 line per entry) */
2114 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->listview));
2115 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->listview));
2117 gint selected_rows = gtk_tree_selection_count_selected_rows(selection);
2118 GList* l = gtk_tree_selection_get_selected_rows(selection, NULL);
2120 GtkTreeIter iter;
2121 gchar *str_data;
2123 gchar **entries = g_malloc0(sizeof(gchar*)*selected_rows+1);
2124 gint entries_idx = 0;
2126 GList* cur = l;
2127 while(cur) {
2128 GtkTreePath *path = cur->data;
2130 if (gtk_tree_model_get_iter(model, &iter, path)) {
2131 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHECKNODE_TEXT, &(entries[entries_idx++]), -1);
2133 gtk_tree_path_free(path);
2135 cur = cur->next;
2138 g_list_free(l);
2139 str_data = g_strjoinv("\n", entries);
2140 g_strfreev(entries);
2141 gtk_clipboard_set_text(mainview->clipboard, str_data, -1);
2142 g_free(str_data);
2144 str_data = g_strdup_printf(_("Copied %d entries"), selected_rows);
2145 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, str_data);
2146 g_free(str_data);
2152 * paste
2154 void callback_edit_paste(GtkAction * action, gpointer data)
2156 MainView *mainview = (MainView *) data;
2157 g_assert(mainview != NULL && mainview->data != NULL);
2159 nodeData *nd = getSelectedNode(mainview);
2161 if (nd->typ == NODE_TEXT)
2162 gtk_text_buffer_paste_clipboard(GTK_TEXT_BUFFER(mainview->buffer), mainview->clipboard, NULL, TRUE);
2163 else if (nd->typ == NODE_SKETCH)
2165 if (sketchwidget_paste(mainview->sk, mainview->clipboard)==FALSE)
2166 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Error pasting"));
2168 else if (nd->typ == NODE_CHECKLIST) {
2169 /* Paste string from clipboard as new item */
2170 callback_checklist_paste(mainview);
2173 mainview->file_edited = TRUE;
2176 gint cb_popup(GtkWidget * widget, GdkEvent * event)
2178 GtkMenu *menu;
2179 GdkEventButton *event_button;
2182 * The "widget" is the menu that was supplied when
2183 * * g_signal_connect_swapped() was called.
2185 menu = GTK_MENU(widget);
2186 event_button = (GdkEventButton *) event;
2187 if (event->type == GDK_BUTTON_PRESS && event_button->button == 3)
2189 gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event_button->button, event_button->time);
2190 return TRUE;
2192 return FALSE;
2196 * close
2198 gboolean closefile(MainView * mainview)
2200 saveCurrentData(mainview);
2202 if (mainview->file_edited)
2204 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));
2205 gint answer = gtk_dialog_run(GTK_DIALOG(hn));
2206 gtk_widget_destroy(GTK_WIDGET(hn));
2208 if (answer == CONFRESP_CANCEL)
2209 return (FALSE);
2210 else if (answer == CONFRESP_YES)
2212 if (mainview->file_name == NULL)
2214 mainview->file_name = interface_file_chooser(mainview, GTK_FILE_CHOOSER_ACTION_SAVE, "maemopaddata", "db");
2216 write_buffer_to_file(mainview);
2220 if (mainview->db)
2221 sqlite3_close(mainview->db);
2222 mainview->db = NULL;
2223 return (TRUE);
2226 gboolean callback_file_close(GtkAction * action, gpointer data)
2229 MainView *mainview = (MainView *) data;
2230 g_assert(mainview != NULL && mainview->data != NULL);
2231 if (closefile(mainview) == FALSE)
2232 return(FALSE);
2234 gtk_main_quit();
2235 return(TRUE);
2238 void callback_file_new_node(GtkAction * action, gpointer data)
2240 MainView *mainview = (MainView *) data;
2241 g_assert(mainview != NULL && mainview->data != NULL);
2243 nodeType typ = NODE_SKETCH;
2245 nodeData *nd = getSelectedNode(mainview);
2247 if (nd != NULL)
2248 typ = nd->typ;
2250 new_node_dialog(typ, mainview);
2254 * new
2256 void callback_file_new(GtkAction * action, gpointer data)
2258 MainView *mainview = (MainView *) data;
2259 g_assert(mainview != NULL && mainview->data != NULL);
2261 gchar *filename = NULL;
2263 if (closefile(mainview) == FALSE)
2264 return;
2266 filename = interface_file_chooser(mainview, GTK_FILE_CHOOSER_ACTION_SAVE, "memos", "db");
2267 if (filename == NULL)
2268 return;
2270 new_file(mainview);
2274 busy_enter(mainview);
2276 int rc;
2278 rc = sqlite3_open(filename, &mainview->db);
2279 if (rc)
2281 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Error 1"));
2282 fprintf(stderr, "Can't create database %s: %s\n", filename, sqlite3_errmsg(mainview->db));
2283 break;
2286 sqlite3_exec(mainview->db, "PRAGMA synchronous = OFF;", NULL, NULL, NULL);
2288 char tq[512];
2290 g_snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", misctable_name, misctable);
2291 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
2293 g_snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", datatable_name, datatable);
2294 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
2296 fprintf(stderr, "ERROR creating data table\n");
2297 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Error 2"));
2298 break;
2301 g_snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", checklisttable_name, checklisttable);
2302 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
2304 fprintf(stderr, "ERROR creating checklist table\n");
2305 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Error 3"));
2306 break;
2309 if (mainview->db)
2310 sqlite3_close(mainview->db);
2311 mainview->db = NULL;
2313 mainview->file_name = filename;
2314 mainview->file_edited = FALSE;
2315 read_file_to_buffer(mainview);
2317 /*add a starter memo*/
2318 nodeData *node;
2319 node = g_malloc(sizeof(nodeData));
2320 node->typ = NODE_SKETCH;
2321 node->name = _("My first memo");
2322 node->namepix = NULL;
2323 node->lastMod = 0;
2324 node->flags = 0;
2325 node->sql3id = 0;
2326 add_new_node(node, mainview, TRUE);
2327 /*gtk_paned_set_position(GTK_PANED(mainview->hpaned), 180);*/
2328 mainview->viewflags = 3;
2329 callback_setview(mainview, 1);
2330 write_buffer_to_file(mainview);
2332 }while(FALSE);
2333 busy_reset(mainview);
2336 gboolean reset_ctree(GtkTreeModel * model, GtkTreePath * path, GtkTreeIter * iter, gpointer data)
2338 nodeData *node;
2340 gtk_tree_model_get(model, iter, NODE_DATA, &node, -1);
2341 if (node)
2343 if (node->name)
2344 g_free(node->name);
2345 if (node->namepix)
2346 g_object_unref(node->namepix);
2347 g_free(node);
2349 gtk_tree_store_set(GTK_TREE_STORE(model), iter, NODE_DATA, NULL, -1);
2351 return (FALSE);
2354 void new_file(MainView * mainview)
2356 busy_enter(mainview);
2358 * clear buffer, filename and free buffer text
2360 gtk_text_buffer_set_text(GTK_TEXT_BUFFER(mainview->buffer), "", -1);
2361 mainview->file_name = NULL;
2362 mainview->file_edited = FALSE;
2363 mainview->newnodedialog_createchild = TRUE;
2365 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->treeview));
2367 g_object_ref(model);
2368 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->treeview), NULL);
2370 gtk_tree_model_foreach(model, (GtkTreeModelForeachFunc) reset_ctree, (gpointer) mainview);
2373 * crashing bastard
2374 * gtk_tree_store_clear(GTK_TREE_STORE(model));
2376 GtkTreePath *path = gtk_tree_path_new_from_indices(0, -1);
2377 GtkTreeIter iter;
2379 if (gtk_tree_model_get_iter(model, &iter, path))
2383 gtk_tree_store_remove(GTK_TREE_STORE(model), &iter);
2385 while(gtk_tree_store_iter_is_valid(GTK_TREE_STORE(model), &iter));
2387 gtk_tree_path_free(path);
2389 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->treeview), model);
2390 g_object_unref(model);
2392 prepareUIforNodeChange(mainview, NODE_UNKNOWN);
2393 busy_leave(mainview);
2397 * open
2399 void callback_file_open(GtkAction * action, gpointer data)
2401 gchar *filename = NULL;
2402 MainView *mainview = (MainView *) data;
2403 g_assert(mainview != NULL && mainview->data != NULL);
2405 if (closefile(mainview) == FALSE)
2406 return;
2409 * open new file
2411 filename = interface_file_chooser(mainview, GTK_FILE_CHOOSER_ACTION_OPEN, NULL, NULL);
2414 * if we got a file name from chooser -> open file
2416 open_file(filename, mainview);
2417 g_free(filename);
2420 gboolean open_file(gchar * filename, MainView * mainview)
2422 gboolean ret=FALSE;
2424 busy_enter(mainview);
2426 while(filename != NULL)
2428 struct stat s;
2430 if (stat(filename, &s) == -1) break;
2432 mainview->file_name = g_strdup(filename);
2433 gboolean res = read_file_to_buffer(mainview);
2435 if (res == FALSE)
2437 g_free(mainview->file_name);
2438 mainview->file_name = NULL;
2439 break;
2441 mainview->file_edited = FALSE;
2442 ret=TRUE;
2443 break;
2446 busy_leave(mainview);
2447 return(ret);
2450 void callback_about_link(GtkAboutDialog *about, const gchar *link, gpointer data)
2452 MainView *mainview = (MainView *) data;
2453 g_assert(mainview != NULL && mainview->data != NULL);
2454 osso_rpc_run_with_defaults(mainview->data->osso, "osso_browser", OSSO_BROWSER_OPEN_NEW_WINDOW_REQ, NULL,
2455 DBUS_TYPE_STRING, link, DBUS_TYPE_INVALID);
2458 void callback_about(GtkAction * action, gpointer data)
2460 /*MainView *mainview=(MainView *)data;*/
2461 he_about_dialog_present(NULL /* auto-detect app name */,
2462 "maepad",
2463 VERSION,
2464 _("A node-based memory pad for Maemo"),
2465 _("(c) 2008-2010 Thomas Perl, (c) 2006-2008 Kemal Hadimli"),
2466 "http://thpinfo.com/2010/maepad/",
2467 NULL /* TODO: Add bug tracker URL */,
2468 "http://thpinfo.com/2010/maepad/donate");
2472 * save
2474 void callback_file_save(GtkAction * action, gpointer data)
2476 gchar *filename = NULL;
2477 MainView *mainview = (MainView *) data;
2478 g_assert(mainview != NULL && mainview->data != NULL);
2481 * check is we had a new file
2483 if (mainview->file_name != NULL)
2485 write_buffer_to_file(mainview);
2487 else
2489 filename = interface_file_chooser(mainview, GTK_FILE_CHOOSER_ACTION_SAVE, "maemopaddata", "db");
2491 * if we got a file name from chooser -> save file
2493 if (filename != NULL)
2495 mainview->file_name = filename;
2496 write_buffer_to_file(mainview);
2497 mainview->file_edited = FALSE;
2502 void callback_shapemenu(GtkAction * action, GtkWidget * wid)
2504 int style = (int)gtk_object_get_user_data(GTK_OBJECT(wid));
2505 MainView *mainview = gtk_object_get_data(GTK_OBJECT(wid), "m");
2507 g_assert(mainview != NULL);
2509 if (style==0) sketchwidget_set_shape(mainview->sk, SKETCHSHAPE_FREEHAND);
2510 else if (style==1) sketchwidget_set_shape(mainview->sk, SKETCHSHAPE_LINE);
2511 else if (style==2) sketchwidget_set_shape(mainview->sk, SKETCHSHAPE_RECT);
2512 else if (style==3) sketchwidget_set_shape(mainview->sk, SKETCHSHAPE_ELLIPSE);
2517 void callback_eraser(GtkAction * action, MainView * mainview)
2519 g_assert(mainview != NULL && mainview->data != NULL);
2521 if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(mainview->eraser_tb)) == TRUE)
2523 GdkColor c2;
2525 c2.red = 65535;
2526 c2.green = 65535;
2527 c2.blue = 65535;
2529 mainview->sk->pressuresensitivity=FALSE;
2531 sketchwidget_set_brushcolor(mainview->sk, c2);
2532 mainview->brushsize_backup = sketchwidget_get_brushsize(mainview->sk);
2533 guint ers=(mainview->brushsize_backup*4)+4;
2534 sk_set_brushsize(mainview, ers);
2535 sketchwidget_set_brushsize(mainview->sk, ers); /*fixme:to override max brush size, not pretty*/
2537 else
2539 if (mainview->current_color == NULL) {
2540 GdkColor color = {0, 0, 0, 0};
2541 mainview->current_color = gdk_color_copy(&color);
2543 /* pressure sensitivity disabled for now...
2544 mainview->sk->pressuresensitivity=gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(mainview->tools_pressure));*/
2546 sketchwidget_set_brushcolor(mainview->sk, *(mainview->current_color));
2547 sk_set_brushsize(mainview, mainview->brushsize_backup);
2551 void callback_menu(GtkAction * action, GtkWidget * menu)
2553 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0, GDK_CURRENT_TIME);
2556 void callback_brushsizetb(GtkAction * action, MainView *mainview)
2558 g_assert(mainview != NULL && mainview->data != NULL);
2560 if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(mainview->eraser_tb)) == TRUE)
2562 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->eraser_tb), FALSE);
2564 else
2566 callback_menu(NULL, mainview->brushsizemenu);
2570 void callback_brushsize(GtkAction * action, GtkWidget * wid)
2572 int bsize = (int)gtk_object_get_user_data(GTK_OBJECT(wid));
2573 MainView *mainview = gtk_object_get_data(GTK_OBJECT(wid), "m");
2575 g_assert(mainview != NULL && mainview->data != NULL);
2577 sketchwidget_set_brushsize(mainview->sk, bsize);
2579 GtkWidget *pix = gtk_object_get_data(GTK_OBJECT(wid), "i");
2581 gtk_widget_show(pix);
2582 gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(mainview->brushsize_tb), pix);
2585 void callback_sketchlines(GtkAction * action, GtkWidget * wid)
2587 int style = (int)gtk_object_get_user_data(GTK_OBJECT(wid));
2588 MainView *mainview = gtk_object_get_data(GTK_OBJECT(wid), "m");
2590 g_assert(mainview != NULL);
2592 nodeData *nd = getSelectedNode(mainview);
2593 gboolean doit = FALSE;
2595 if (nd != NULL && nd->typ == NODE_SKETCH)
2597 nd->flags &= ~NODEFLAG_SKETCHLINES;
2598 nd->flags &= ~NODEFLAG_SKETCHGRAPH;
2599 /* sketchwidget_set_edited(mainview->sk, TRUE);*/ /*we call this on openfile, so this messes things up*/
2600 doit = TRUE;
2603 if (style == 0)
2605 sketchwidget_set_backstyle(mainview->sk, SKETCHBACK_NONE);
2607 else if (style == 1)
2609 sketchwidget_set_backstyle(mainview->sk, SKETCHBACK_LINES);
2610 if (doit == TRUE)
2611 nd->flags |= NODEFLAG_SKETCHLINES;
2613 else if (style == 2)
2615 sketchwidget_set_backstyle(mainview->sk, SKETCHBACK_GRAPH);
2616 if (doit == TRUE)
2617 nd->flags |= NODEFLAG_SKETCHGRAPH;
2620 GtkWidget *pix = gtk_object_get_data(GTK_OBJECT(wid), "i");
2622 gtk_widget_show(pix);
2623 gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(mainview->sketchlines_tb), pix);
2626 void callback_color(GtkAction* action, MainView* mainview)
2628 g_assert(mainview != NULL && mainview->data != NULL);
2630 nodeData *nd = getSelectedNode(mainview);
2631 if (nd == NULL) return;
2633 HeSimpleColorDialog* dialog = HE_SIMPLE_COLOR_DIALOG(he_simple_color_dialog_new());
2635 if (mainview->current_color) {
2636 he_simple_color_dialog_set_color(dialog, mainview->current_color);
2639 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
2640 gtk_widget_destroy(GTK_WIDGET(dialog));
2641 return;
2644 gdk_color_free(mainview->current_color);
2645 mainview->current_color = he_simple_color_dialog_get_color(dialog);
2647 gtk_widget_destroy(GTK_WIDGET(dialog));
2649 switch (nd->typ) {
2650 case NODE_SKETCH:
2651 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->eraser_tb), FALSE);
2652 sketchwidget_set_brushcolor(mainview->sk, *(mainview->current_color));
2653 break;
2654 case NODE_CHECKLIST:
2655 { /* Put in a separate block to allow new local variables */
2656 GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->listview));
2657 GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->listview));
2658 GList* selected = gtk_tree_selection_get_selected_rows(selection, NULL);
2660 gchar* color_string = g_strdup_printf("#%02x%02x%02x",
2661 mainview->current_color->red >> 8,
2662 mainview->current_color->green >> 8,
2663 mainview->current_color->blue >> 8);
2665 GList* cur = selected;
2666 while (cur != NULL) {
2667 GtkTreePath* path = cur->data;
2668 GtkTreeIter iter;
2669 if (gtk_tree_model_get_iter(model, &iter, path)) {
2670 gtk_list_store_set(GTK_LIST_STORE(model), &iter, CHECKNODE_COLOR, color_string, -1);
2672 gtk_tree_path_free(path);
2673 cur = cur->next;
2676 g_list_free(selected);
2677 g_free(color_string);
2679 break;
2680 default:
2681 g_error("Wrong node type for color selection");
2682 return;
2686 void callback_color_invoke(GtkAction * action, gpointer data)
2688 MainView *mainview = (MainView *) data;
2689 g_assert(mainview != NULL && mainview->data != NULL);
2690 gtk_button_clicked(GTK_BUTTON(mainview->colorbutton_tb));
2695 void callback_pressure(GtkAction * action, MainView *mainview)
2697 g_assert(mainview != NULL && mainview->data != NULL);
2699 nodeData *nd = getSelectedNode(mainview);
2701 if (nd == NULL)
2702 return;
2703 if (nd->typ != NODE_SKETCH)
2704 return;
2706 /* pressure sensitivity disabled for now...
2707 mainview->sk->pressuresensitivity=gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(mainview->tools_pressure));*/
2711 void callback_wordwrap(GtkAction * action, MainView *mainview)
2713 g_assert(mainview != NULL && mainview->data != NULL);
2715 nodeData *nd = getSelectedNode(mainview);
2717 if (nd == NULL)
2718 return;
2719 if (nd->typ != NODE_TEXT)
2720 return;
2722 gboolean act=gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(mainview->tools_wordwrap));
2723 if (act==TRUE) nd->flags |= NODEFLAG_WORDWRAP;
2724 else nd->flags &= ~NODEFLAG_WORDWRAP;
2726 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(mainview->textview), (act==TRUE)?GTK_WRAP_WORD:GTK_WRAP_NONE);
2730 void callback_font(GtkAction * action, gpointer data)
2732 MainView *mainview = (MainView *) data;
2733 g_assert(mainview != NULL && mainview->data != NULL);
2735 nodeData *nd = getSelectedNode(mainview);
2737 if (nd == NULL)
2738 return;
2739 if (nd->typ != NODE_TEXT)
2740 return;
2742 HildonFontSelectionDialog *dialog = HILDON_FONT_SELECTION_DIALOG(hildon_font_selection_dialog_new(NULL, NULL));
2744 gboolean gotsel=wp_text_buffer_has_selection(mainview->buffer);
2745 /*gotsel=FALSE;*/
2747 WPTextBufferFormat fmt;
2748 wp_text_buffer_get_attributes(mainview->buffer, &fmt, gotsel);
2750 gint ri=0;
2751 if (fmt.text_position==TEXT_POSITION_SUPERSCRIPT) ri=1;
2752 else if (fmt.text_position==TEXT_POSITION_SUBSCRIPT) ri=-1;
2754 g_object_set(G_OBJECT(dialog),
2755 "family-set", fmt.cs.font,
2756 "family", wp_get_font_name(fmt.font),
2757 "size-set", fmt.cs.font_size,
2758 "size", wp_font_size[fmt.font_size],
2759 "color-set", fmt.cs.color,
2760 "color", &fmt.color,
2761 "bold-set", fmt.cs.bold,
2762 "bold", fmt.bold,
2763 "italic-set", fmt.cs.italic,
2764 "italic", fmt.italic,
2765 "underline-set", fmt.cs.underline,
2766 "underline", fmt.underline,
2767 "strikethrough-set", fmt.cs.strikethrough,
2768 "strikethrough", fmt.strikethrough,
2769 "position-set", fmt.cs.text_position,
2770 "position", ri,
2771 NULL);
2773 gtk_widget_show_all(GTK_WIDGET(dialog));
2774 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
2776 gboolean bold, italic, underline, strikethrough;
2777 gchar *family = NULL;
2778 gint size, position;
2779 GdkColor *color=NULL;
2780 gboolean set_family, set_size, set_bold, set_italic, set_underline, set_strikethrough, set_color, set_position;
2782 g_object_get(G_OBJECT(dialog), "family", &family, "size", &size, "bold", &bold, "italic", &italic,
2783 "underline", &underline, "strikethrough", &strikethrough,
2784 "family-set", &set_family, "size-set", &set_size, "bold-set", &set_bold, "italic-set", &set_italic,
2785 "underline-set", &set_underline, "strikethrough-set", &set_strikethrough,
2786 "color", &color, "color-set", &set_color, "position", &position, "position-set", &set_position,
2787 NULL);
2789 wp_text_buffer_get_attributes(mainview->buffer, &fmt, FALSE);
2790 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;
2792 if (set_family) { fmt.font=wp_get_font_index(family, 1); fmt.cs.font=1; }
2793 if (set_size) { fmt.font_size=wp_get_font_size_index(size, 16); fmt.cs.font_size=1; }
2795 if (set_strikethrough)
2797 fmt.cs.strikethrough=1;
2798 fmt.strikethrough=strikethrough;
2801 if (set_color)
2804 GLIB WARNING ** GLib-GObject - IA__g_object_set_valist: object class `GtkTextTag' has no property named `'
2806 fmt.cs.color=1;
2807 fmt.color.pixel=color->pixel;
2808 fmt.color.red=color->red;
2809 fmt.color.green=color->green;
2810 fmt.color.blue=color->blue;
2813 if (set_position)
2815 if (position==1) ri=TEXT_POSITION_SUPERSCRIPT;
2816 else if (position==-1) ri=TEXT_POSITION_SUBSCRIPT;
2817 else ri=TEXT_POSITION_NORMAL;
2819 fmt.cs.text_position=1;
2820 fmt.text_position=ri;
2823 if (set_bold)
2825 fmt.cs.bold=1;
2826 fmt.bold=bold;
2828 if (set_italic)
2830 fmt.cs.italic=1;
2831 fmt.italic=italic;
2833 if (set_underline)
2835 fmt.cs.underline=1;
2836 fmt.underline=underline;
2839 wp_text_buffer_set_format(mainview->buffer, &fmt);
2842 gtk_widget_destroy(GTK_WIDGET(dialog));
2845 void callback_fontstyle(GtkAction * action, GtkWidget * wid)
2847 MainView *mainview = gtk_object_get_data(GTK_OBJECT(wid), "m");
2848 g_assert(mainview != NULL && mainview->data != NULL);
2850 nodeData *nd = getSelectedNode(mainview);
2852 if (nd == NULL)
2853 return;
2854 if (nd->typ == NODE_TEXT)
2856 gboolean act=gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(wid));
2858 gint style = (gint)gtk_object_get_data(GTK_OBJECT(wid), "s");
2859 wp_text_buffer_set_attribute(mainview->buffer, style, (gpointer)act);
2861 else if (nd->typ == NODE_CHECKLIST)
2863 gboolean act=gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(wid));
2864 gint style = (gint)gtk_object_get_data(GTK_OBJECT(wid), "s");
2865 if (style!=WPT_BOLD && style!=WPT_STRIKE && style!=WPT_LEFT) return;
2867 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->listview));
2868 GList* l=gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->listview)), NULL);
2870 gint styletoset_weight=PANGO_WEIGHT_NORMAL;
2871 gboolean styletoset_strike=FALSE;
2872 gboolean checkit=FALSE;
2874 if (style==WPT_BOLD && act==TRUE) styletoset_weight=PANGO_WEIGHT_BOLD;
2875 else if (style==WPT_STRIKE && act==TRUE) styletoset_strike=TRUE;
2876 else if (style==WPT_LEFT && act==TRUE) checkit=TRUE;
2878 GList* cur=l;
2879 while(cur)
2881 GtkTreePath *path=cur->data;
2883 GtkTreeIter iter;
2884 if (gtk_tree_model_get_iter(model, &iter, path))
2886 if (style==WPT_BOLD) gtk_list_store_set(GTK_LIST_STORE(model), &iter, CHECKNODE_BOLD, styletoset_weight, -1);
2887 else if (style==WPT_STRIKE) gtk_list_store_set(GTK_LIST_STORE(model), &iter, CHECKNODE_STRIKE, styletoset_strike, -1);
2888 else if (style==WPT_LEFT) {
2889 gtk_list_store_set(GTK_LIST_STORE(model), &iter, CHECKNODE_CHECKED, checkit, -1);
2890 if (checkit) {
2891 gtk_list_store_set(GTK_LIST_STORE(model), &iter, CHECKNODE_ICON_NAME, "widgets_tickmark_list", -1);
2892 } else {
2893 gtk_list_store_set(GTK_LIST_STORE(model), &iter, CHECKNODE_ICON_NAME, "", -1);
2897 gtk_tree_path_free(path);
2898 cur=cur->next;
2901 g_list_free(l);
2902 gtk_object_set_data(GTK_OBJECT(mainview->listview), "edited", GINT_TO_POINTER(TRUE));
2907 void callback_textbuffer_move(WPTextBuffer *textbuffer, MainView *mainview)
2909 g_assert(mainview != NULL && mainview->data != NULL);
2912 gboolean gotsel=wp_text_buffer_has_selection(mainview->buffer);
2914 _toggle_tool_button_set_inconsistent(GTK_TOGGLE_TOOL_BUTTON(mainview->bold_tb), gotsel);
2915 _toggle_tool_button_set_inconsistent(GTK_TOGGLE_TOOL_BUTTON(mainview->italic_tb), gotsel);
2916 _toggle_tool_button_set_inconsistent(GTK_TOGGLE_TOOL_BUTTON(mainview->underline_tb), gotsel);
2917 _toggle_tool_button_set_inconsistent(GTK_TOGGLE_TOOL_BUTTON(mainview->bullet_tb), gotsel);
2919 WPTextBufferFormat fmt;
2920 wp_text_buffer_get_attributes(mainview->buffer, &fmt, FALSE/*gotsel*/);
2922 g_signal_handlers_block_by_func(mainview->bold_tb, callback_fontstyle, mainview->bold_tb);
2923 g_signal_handlers_block_by_func(mainview->italic_tb, callback_fontstyle, mainview->italic_tb);
2924 g_signal_handlers_block_by_func(mainview->underline_tb, callback_fontstyle, mainview->underline_tb);
2925 g_signal_handlers_block_by_func(mainview->bullet_tb, callback_fontstyle, mainview->bullet_tb);
2927 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->bold_tb), fmt.bold);
2928 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->italic_tb), fmt.italic);
2929 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->underline_tb), fmt.underline);
2930 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->bullet_tb), fmt.bullet);
2932 g_signal_handlers_unblock_by_func(mainview->bold_tb, callback_fontstyle, mainview->bold_tb);
2933 g_signal_handlers_unblock_by_func(mainview->italic_tb, callback_fontstyle, mainview->italic_tb);
2934 g_signal_handlers_unblock_by_func(mainview->underline_tb, callback_fontstyle, mainview->underline_tb);
2935 g_signal_handlers_unblock_by_func(mainview->bullet_tb, callback_fontstyle, mainview->bullet_tb);
2938 gint wp_savecallback(const gchar *buffer, GString * gstr)
2940 gstr=g_string_append(gstr, buffer);
2941 return(0);
2944 void callback_undo(GtkAction * action, MainView * mainview)
2946 g_assert(mainview != NULL && mainview->data != NULL);
2948 nodeData *nd = getSelectedNode(mainview);
2950 if (nd == NULL) return;
2952 if (nd->typ == NODE_SKETCH) sketchwidget_undo(mainview->sk);
2953 else if (nd->typ == NODE_TEXT) wp_text_buffer_undo(mainview->buffer);
2956 void callback_redo(GtkAction * action, MainView * mainview)
2958 g_assert(mainview != NULL && mainview->data != NULL);
2960 nodeData *nd = getSelectedNode(mainview);
2962 if (nd == NULL) return;
2964 if (nd->typ == NODE_SKETCH) sketchwidget_redo(mainview->sk);
2965 else if (nd->typ == NODE_TEXT) wp_text_buffer_redo(mainview->buffer);
2968 void callback_undotoggle(gpointer widget, gboolean st, MainView * mainview)
2970 g_assert(mainview != NULL && mainview->data != NULL);
2972 gtk_widget_set_sensitive(GTK_WIDGET(mainview->undo_tb), st);
2975 void callback_redotoggle(gpointer widget, gboolean st, MainView * mainview)
2977 g_assert(mainview != NULL && mainview->data != NULL);
2979 gtk_widget_set_sensitive(GTK_WIDGET(mainview->redo_tb), st);
2982 void callback_finger(SketchWidget * sk, gint x, gint y, gdouble pressure, MainView * mainview)
2984 g_assert(mainview != NULL && mainview->data != NULL);
2986 if ((mainview->viewflags & 2) == 0) mainview->viewflags |= 2;
2987 else mainview->viewflags &= ~2;
2988 callback_setview(mainview, 1);
2991 gboolean close_cb(GtkWidget * widget, GdkEventAny * event, MainView * mainview)
2993 callback_file_close(NULL, mainview);
2994 return (TRUE);
2997 gboolean key_press_cb(GtkWidget * widget, GdkEventKey * event, MainView * mainview)
2999 switch (event->keyval)
3003 * case GDK_Up:
3004 * gtk_infoprint(GTK_WINDOW(app), "Navigation Key Up");
3005 * return TRUE;
3007 * case GDK_Down:
3008 * gtk_infoprint(GTK_WINDOW(app), "Navigation Key Down");
3009 * return TRUE;
3011 * case GDK_Left:
3012 * gtk_infoprint(GTK_WINDOW(app), "Navigation Key Left");
3013 * return TRUE;
3015 * case GDK_Right:
3016 * gtk_infoprint(GTK_WINDOW(app), "Navigation Key Right");
3017 * return TRUE;
3019 * case GDK_Return:
3020 * gtk_infoprint(GTK_WINDOW(app), "Navigation Key select");
3021 * return TRUE;
3023 /*code below messes up when you have a textview*/
3025 case GDK_Left:
3026 case GDK_Right:
3028 gtk_widget_child_focus(widget, event->keyval==GDK_Left?GTK_DIR_TAB_BACKWARD:GTK_DIR_TAB_FORWARD);
3029 return TRUE;
3032 case GDK_Left:
3034 nodeData *selnode = getSelectedNode(mainview);
3035 if (selnode!=NULL && selnode->typ==NODE_SKETCH)
3037 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Squared shapes ON"));
3038 sketchwidget_set_shift(mainview->sk, TRUE);
3039 return TRUE;
3041 return FALSE;
3043 case GDK_Right:
3045 nodeData *selnode = getSelectedNode(mainview);
3046 if (selnode!=NULL && selnode->typ==NODE_SKETCH)
3048 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Squared shapes OFF"));
3049 sketchwidget_set_shift(mainview->sk, FALSE);
3050 return TRUE;
3052 return FALSE;
3054 case GDK_Down:
3056 nodeData *selnode = getSelectedNode(mainview);
3057 if (selnode!=NULL && selnode->typ==NODE_SKETCH)
3059 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Filled shapes OFF"));
3060 sketchwidget_set_fillmode(mainview->sk, FALSE);
3061 return TRUE;
3063 return FALSE;
3065 case GDK_Up:
3067 nodeData *selnode = getSelectedNode(mainview);
3068 if (selnode!=NULL && selnode->typ==NODE_SKETCH)
3070 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Filled shapes ON"));
3071 sketchwidget_set_fillmode(mainview->sk, TRUE);
3072 return TRUE;
3074 return FALSE;
3076 case GDK_F6:
3078 if ((mainview->viewflags & 4) == 0) mainview->viewflags |= 4;
3079 else mainview->viewflags &= ~4;
3080 callback_setview(mainview, 1);
3081 return TRUE;
3083 case GDK_F7:
3085 callback_redo(NULL, mainview);
3086 return TRUE;
3088 case GDK_F8:
3090 callback_undo(NULL, mainview);
3091 return TRUE;
3093 case GDK_Escape:
3095 if ((mainview->viewflags & 1) == 0) mainview->viewflags |= 1;
3096 else mainview->viewflags &= ~1;
3097 callback_setview(mainview, 1);
3099 return TRUE;
3102 case GDK_Return:
3104 if ((mainview->viewflags & 2) == 0) mainview->viewflags |= 2;
3105 else mainview->viewflags &= ~2;
3106 callback_setview(mainview, 1);
3107 return TRUE;
3112 return FALSE;
3115 void callback_viewmenu(GtkAction * action, GtkWidget * wid)
3117 int flag = (int)gtk_object_get_user_data(GTK_OBJECT(wid));
3118 MainView *mainview = gtk_object_get_data(GTK_OBJECT(wid), "m");
3120 g_assert(mainview != NULL);
3122 if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(wid))) mainview->viewflags |= flag;
3123 else mainview->viewflags &= ~flag;
3125 if (flag==1)
3127 return;
3130 callback_setview(mainview, 0);
3134 void callback_setview(MainView *mainview, int setmenu)
3136 if (setmenu>0)
3138 if ((mainview->viewflags&4)>0)
3139 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->viewmenuitems[2]), TRUE);
3140 else
3141 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->viewmenuitems[2]), FALSE);
3143 if ((mainview->viewflags&2)>0)
3144 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->viewmenuitems[1]), TRUE);
3145 else
3146 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->viewmenuitems[1]), FALSE);
3148 if ((mainview->viewflags&1)>0)
3150 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->viewmenuitems[0]), TRUE);
3152 else
3154 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->viewmenuitems[0]), FALSE);
3157 return;
3160 busy_enter(mainview);
3162 if ((mainview->viewflags&4)>0)
3163 gtk_window_fullscreen(GTK_WINDOW(mainview->data->main_view));
3164 else
3165 gtk_window_unfullscreen(GTK_WINDOW(mainview->data->main_view));
3167 if ((mainview->viewflags&2)>0)
3168 gtk_widget_show(mainview->toolbar);
3169 else
3170 gtk_widget_hide(mainview->toolbar);
3172 if ((mainview->viewflags&1)>0)
3173 gtk_widget_show(mainview->scrolledtree);
3174 else
3175 gtk_widget_hide(mainview->scrolledtree);
3177 if (mainview->viewflags==4)
3178 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sketchwidget_get_mainwidget(mainview->sk)), GTK_POLICY_NEVER, GTK_POLICY_NEVER);
3179 else
3180 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sketchwidget_get_mainwidget(mainview->sk)), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
3182 busy_leave(mainview);
3185 void callback_fullscreen(GtkToolButton* tool_button, gpointer user_data)
3187 MainView* mainview = (MainView*)user_data;
3188 gtk_window_fullscreen(GTK_WINDOW(mainview->data->node_view));
3191 void callback_buffer_modified(GtkAction * action, gpointer data)
3193 MainView *mainview = (MainView *) data;
3194 g_assert(mainview != NULL && mainview->data != NULL);
3196 mainview->file_edited = TRUE;
3200 * Callback for exit D-BUS event
3202 void exit_event_handler(gboolean die_now, gpointer data)
3204 MainView *mainview = (MainView *) data;
3205 g_assert(mainview != NULL && mainview->data != NULL);
3207 if (!die_now)
3209 if (callback_file_close(NULL, mainview)==FALSE) gtk_main_quit(); /*make sure we call gtk_main_quit*/
3211 else
3213 gtk_main_quit();
3216 * application_exit(mainview->data);
3221 * Callback for hardware D-BUS events
3223 void hw_event_handler(osso_hw_state_t * state, gpointer data)
3225 MainView *mainview = (MainView *) data;
3226 g_assert(mainview != NULL && mainview->data != NULL);
3229 * if (state->shutdown_ind)
3231 * gtk_infoprint(GTK_WINDOW(mainview->data->app),
3232 * "Shutdown event!");
3234 * if (state->memory_low_ind)
3236 * gtk_infoprint(GTK_WINDOW(mainview->data->app),
3237 * "Memory low event!");
3240 if (state->save_unsaved_data_ind)
3242 fprintf(stderr, "Saving unsaved data!\n");
3243 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, "Saving unsaved data!");
3244 callback_file_save(NULL, mainview);
3248 * if (state->system_inactivity_ind)
3250 * gtk_infoprint(GTK_WINDOW(mainview->data->app),
3251 * "Minimize application inactivity event!");
3256 GtkTreeRowReference *read_sqlite3_data(MainView * mainview, unsigned int parentid, GtkTreeRowReference * parenttree, unsigned int selected, GtkTreeStore * model)
3258 GtkTreeRowReference *resref = NULL;
3260 char q[256];
3262 g_snprintf(q, sizeof(q), "SELECT nodeid, bodytype, name, nameblob, lastmodified, flags FROM %s WHERE parent=%d ORDER BY ord", datatable_tmpname, parentid);
3264 sqlite3_stmt *stmt = NULL;
3265 const char *dum;
3266 int rc = sqlite3_prepare(mainview->db, q, strlen(q), &stmt, &dum);
3268 if (rc)
3270 fprintf(stderr, "Error %s\n", sqlite3_errmsg(mainview->db));
3271 return (NULL);
3274 rc = SQLITE_BUSY;
3275 while(rc == SQLITE_BUSY || rc == SQLITE_ROW)
3277 rc = sqlite3_step(stmt);
3278 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE || rc == SQLITE_DONE)
3279 break;
3280 else if (rc == SQLITE_ROW)
3282 int nodeid = sqlite3_column_int(stmt, 0);
3283 int typ = sqlite3_column_int(stmt, 1);
3284 const unsigned char *name = sqlite3_column_text(stmt, 2);
3285 const unsigned char *nameblob = sqlite3_column_text(stmt, 3);
3286 int lastmod = sqlite3_column_int(stmt, 4);
3287 int flags = sqlite3_column_int(stmt, 5);
3290 * fprintf(stderr, "CARD=%s TYPE=%d\n", name, typ);
3292 if ((typ != NODE_TEXT && typ != NODE_SKETCH && typ != NODE_CHECKLIST) || (name == NULL && nameblob == NULL))
3296 * fprintf(stderr, "invalid card, skipping\n");
3298 continue;
3301 nodeData *node = g_malloc(sizeof(nodeData));
3303 node->sql3id = nodeid;
3304 node->typ = typ;
3305 node->flags = flags;
3306 node->name = NULL;
3307 node->namepix = NULL;
3308 if (name != NULL) {
3309 node->name = g_strdup((char *)name);
3310 } else {
3311 node->name = g_strdup(_("Unnamed node"));
3313 /*if (nameblob != NULL)
3315 int blobsize = sqlite3_column_bytes(stmt, 3);
3317 GdkPixbufLoader *pl = gdk_pixbuf_loader_new_with_type("png", NULL);
3318 GError *err = NULL;
3320 gdk_pixbuf_loader_write(pl, (guchar *) nameblob, blobsize, &err);
3321 if (err != NULL)
3323 fprintf(stderr, "Error loading nodename! %s\n", err->message);
3324 g_error_free(err);
3325 err = NULL;
3327 gdk_pixbuf_loader_close(pl, NULL);
3328 GdkPixbuf *pixbuf = gdk_pixbuf_loader_get_pixbuf(pl);
3330 if (GDK_IS_PIXBUF(pixbuf))
3331 node->namepix = pixbuf;
3333 node->lastMod = lastmod;
3335 GtkTreeIter parentiter, newiter;
3336 void *par = NULL;
3338 if (parenttree != NULL)
3340 GtkTreePath *pa = gtk_tree_row_reference_get_path(parenttree);
3342 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &parentiter, pa);
3343 gtk_tree_path_free(pa);
3344 par = &parentiter;
3347 gtk_tree_store_append(model, &newiter, par);
3348 gtk_tree_store_set(model, &newiter, NODE_NAME, node->name, NODE_PIXBUF, node->namepix, NODE_DATA, node, -1);
3350 GtkTreePath *pa = gtk_tree_model_get_path(GTK_TREE_MODEL(model), &newiter);
3352 GtkTreeRowReference *newref = gtk_tree_row_reference_new(GTK_TREE_MODEL(model), pa);
3354 if (selected == nodeid)
3355 resref = newref;
3357 gtk_tree_path_free(pa);
3358 GtkTreeRowReference *r = read_sqlite3_data(mainview, nodeid, newref, selected,
3359 model);
3361 if (resref != newref)
3362 gtk_tree_row_reference_free(newref);
3364 if (r != NULL)
3366 if (resref == NULL)
3367 resref = r;
3368 else
3369 gtk_tree_row_reference_free(r); /*safeguard */
3374 if (stmt)
3375 sqlite3_finalize(stmt);
3377 return (resref); /*ref to supposed-to-be-selected treeitem */
3381 * read file
3383 gboolean read_file_to_buffer(MainView * mainview)
3385 char tq[512];
3387 g_assert(mainview != NULL);
3388 gboolean res = FALSE;
3390 gchar *filename = mainview->file_name;
3392 new_file(mainview);
3393 mainview->file_name = filename;
3394 mainview->loading=TRUE;
3396 fprintf(stderr, "read:*%s*\n", filename);
3398 int rc;
3399 sqlite3_stmt *stmt = NULL;
3401 rc = sqlite3_open(filename, &mainview->db);
3404 if (rc)
3406 fprintf(stderr, "Can't open database %s: %s\n", filename, sqlite3_errmsg(mainview->db));
3407 break;
3410 sqlite3_exec(mainview->db, "PRAGMA synchronous = OFF;", NULL, NULL, NULL);
3412 char *q = "SELECT skey, sval FROM settings";
3413 const char *dum;
3415 rc = sqlite3_prepare(mainview->db, q, strlen(q), &stmt, &dum);
3416 if (rc)
3418 fprintf(stderr, "Error %s\n", sqlite3_errmsg(mainview->db));
3419 break;
3422 unsigned int selectedCard = 0;
3425 * fprintf(stderr, "start config\n");
3427 unsigned int curDataVersion = 0;
3428 unsigned int curChecklistVersion = 0;
3430 rc = SQLITE_BUSY;
3431 while(rc == SQLITE_BUSY || rc == SQLITE_ROW)
3433 rc = sqlite3_step(stmt);
3434 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE || rc == SQLITE_DONE)
3435 break;
3436 else if (rc == SQLITE_ROW)
3438 const gchar* col_key = (const gchar*)sqlite3_column_text(stmt, 0);
3439 const gchar* col_val = (const gchar*)sqlite3_column_text(stmt, 1);
3442 * fprintf(stderr, "%s=%s\n", col_key, col_val);
3444 if (!strcmp(col_key, "selectedNode"))
3446 gint tmp = atoi((char *)col_val);
3448 if (tmp > 0)
3449 selectedCard = tmp;
3451 if (!strcmp(col_key, "dataVersion"))
3453 gint tmp = atoi((char *)col_val);
3455 if (tmp > 0)
3456 curDataVersion = tmp;
3458 if (!strcmp(col_key, "checklistVersion"))
3460 gint tmp = atoi((char *)col_val);
3462 if (tmp > 0)
3463 curChecklistVersion = tmp;
3465 if (!strcmp(col_key, "newNodeDlgCreateChild"))
3467 gint tmp = atoi((char *)col_val);
3469 mainview->newnodedialog_createchild = TRUE;
3470 if (tmp == 0)
3471 mainview->newnodedialog_createchild = FALSE;
3473 if (!strcmp(col_key, "fullScreen"))
3475 gint tmp = atoi((char *)col_val);
3476 if (tmp<0 || tmp>4) tmp=0;
3477 if (tmp==0) tmp=4;
3478 else tmp--;
3479 if (tmp==0) tmp=3;
3480 else if (tmp==1) tmp=2;
3481 else if (tmp==2) tmp=7;
3482 else if (tmp==3) tmp=6;
3483 else if (tmp==4) tmp=4;
3484 mainview->viewflags=tmp;
3485 callback_setview(mainview, TRUE);
3487 if (!strcmp(col_key, "viewFlags"))
3489 gint tmp = atoi((char *)col_val);
3490 if (tmp<0) tmp=3;
3491 mainview->viewflags=tmp;
3492 callback_setview(mainview, TRUE);
3494 if (!strcmp(col_key, "brushSize"))
3496 gint tmp = atoi((char *)col_val);
3497 if (tmp>0) sk_set_brushsize(mainview, tmp);
3499 if (!strcmp(col_key, "brushColor"))
3501 unsigned long tmp = atol((char *)col_val);
3502 GdkColor c2;
3504 c2.red = ((tmp & 0xFF0000) >> 16) << 8;
3505 c2.green = ((tmp & 0xFF00) >> 8) << 8;
3506 c2.blue = (tmp & 0xFF) << 8;
3507 /* fprintf(stderr, "READ BRUSHCOLOR is %ul (%d,%d,%d)\n", tmp, c2.red, c2.green, c2.blue);*/
3509 sketchwidget_set_brushcolor(mainview->sk, c2);
3511 if (mainview->current_color != NULL) {
3512 gdk_color_free(mainview->current_color);
3514 mainview->current_color = gdk_color_copy(&c2);
3519 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE)
3521 fprintf(stderr, "Error2 %s\n", sqlite3_errmsg(mainview->db));
3522 break;
3526 * fprintf(stderr, "end config\n");
3528 if (stmt) {
3529 sqlite3_finalize(stmt);
3530 stmt = NULL;
3533 gboolean resback = FALSE;
3535 while(curDataVersion < datatableversion)
3537 if (curDataVersion == 0)
3539 g_snprintf(tq, sizeof(tq), "DROP TABLE %s", datatable_backupname);
3540 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3542 g_snprintf(tq, sizeof(tq), "ALTER TABLE %s RENAME TO %s", datatable_name, datatable_backupname);
3543 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3545 fprintf(stderr, "ERROR backing up table!\n");
3546 break;
3548 resback = TRUE;
3550 g_snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", datatable_name, datatable);
3551 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3553 fprintf(stderr, "ERROR creating table!\n");
3554 break;
3556 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);
3557 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3559 fprintf(stderr, "ERROR copying data!\n");
3560 break;
3563 g_snprintf(tq, sizeof(tq), "DROP TABLE %s", datatable_backupname);
3564 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3566 curDataVersion = datatableversion;
3568 break;
3571 if (curDataVersion != datatableversion)
3573 fprintf(stderr, "Data version mismatch\n");
3575 if (resback == TRUE)
3577 g_snprintf(tq, sizeof(tq), "DROP TABLE %s", datatable_name);
3578 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3579 g_snprintf(tq, sizeof(tq), "ALTER TABLE %s RENAME TO %s", datatable_backupname, datatable_name);
3580 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3583 break;
3587 while(curChecklistVersion < checklisttableversion)
3589 if (curChecklistVersion == 0) /*no checklisttable at all*/
3591 g_snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", checklisttable_name, checklisttable);
3592 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3594 fprintf(stderr, "ERROR creating checklist table!\n");
3595 break;
3597 curChecklistVersion = checklisttableversion;
3599 break;
3603 GtkTreeStore *model = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->treeview)));
3605 g_object_ref(model);
3606 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->treeview), NULL);
3610 char tq[512];
3612 g_snprintf(tq, sizeof(tq), "CREATE%s TABLE %s%s", TEMPTABLE_KEYWORD, datatable_tmpname, datatable);
3613 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3615 fprintf(stderr, "ERROR creating temp table!\n");
3616 break;
3618 g_snprintf(tq, sizeof(tq), "CREATE INDEX %s_index ON %s %s", datatable_tmpname, datatable_tmpname, dataindex);
3619 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3621 fprintf(stderr, "ERROR creating temp index!\n");
3622 break;
3624 g_snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT * FROM %s", datatable_tmpname, datatable_name);
3625 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3627 fprintf(stderr, "ERROR copying data to temp table!\n");
3628 break;
3631 g_snprintf(tq, sizeof(tq), "CREATE%s TABLE %s%s", TEMPTABLE_KEYWORD, checklisttable_tmpname, checklisttable);
3632 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3634 fprintf(stderr, "ERROR creating temp table! (checklist)\n");
3635 break;
3637 g_snprintf(tq, sizeof(tq), "CREATE INDEX %s_index ON %s %s", checklisttable_tmpname, checklisttable_tmpname, checklistindex);
3638 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3640 fprintf(stderr, "ERROR creating temp index! (checklist)\n");
3641 break;
3643 g_snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT * FROM %s", checklisttable_tmpname, checklisttable_name);
3644 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3646 fprintf(stderr, "ERROR copying data to temp table! (checklist)\n");
3647 break;
3650 while(FALSE);
3652 GtkTreeRowReference *selectedRef = read_sqlite3_data(mainview, 0, NULL, selectedCard, model);
3654 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->treeview), GTK_TREE_MODEL(model));
3655 g_object_unref(model);
3656 gtk_tree_view_expand_all(GTK_TREE_VIEW(mainview->treeview));
3658 if (selectedRef != NULL)
3660 GtkTreeIter seliter;
3662 if (ref2iter(GTK_TREE_MODEL(model), selectedRef, &seliter) == TRUE)
3664 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
3665 gtk_tree_selection_select_iter(selection, &seliter);
3668 gtk_tree_row_reference_free(selectedRef);
3670 res = TRUE;
3672 while(FALSE);
3674 if (stmt) {
3675 sqlite3_finalize(stmt);
3679 mainview->loading=FALSE;
3681 return (res);
3685 * write to file
3687 void write_buffer_to_file(MainView * mainview)
3689 fprintf(stderr, "write:*%s*\n", mainview->file_name);
3690 saveCurrentData(mainview);
3692 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->treeview));
3693 /*update ord value in database for all nodes*/
3694 gtk_tree_model_foreach(GTK_TREE_MODEL(model),(GtkTreeModelForeachFunc) foreach_func_update_ord,mainview);
3696 busy_enter(mainview);
3698 char tq[512];
3700 g_snprintf(tq, sizeof(tq), "DROP TABLE %s", misctable_name);
3701 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3703 g_snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", misctable_name, misctable);
3704 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3706 gint nndcc = 1;
3708 if (mainview->newnodedialog_createchild == FALSE)
3709 nndcc = 0;
3710 g_snprintf(tq, sizeof(tq), "INSERT INTO %s VALUES('newNodeDlgCreateChild', '%d');", misctable_name, nndcc);
3711 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3713 g_snprintf(tq, sizeof(tq), "INSERT INTO %s VALUES('viewFlags', '%d');", misctable_name, mainview->viewflags);
3714 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3716 nodeData *node = getSelectedNode(mainview);
3718 if (node)
3720 g_snprintf(tq, sizeof(tq), "INSERT INTO %s VALUES('selectedNode', '%d');", misctable_name, node->sql3id);
3721 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3724 guint bsize;
3725 if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(mainview->eraser_tb)) == TRUE)
3727 bsize=mainview->brushsize_backup;
3729 else
3731 bsize=sketchwidget_get_brushsize(mainview->sk);
3733 g_snprintf(tq, sizeof(tq), "INSERT INTO %s VALUES('brushSize', '%d');", misctable_name, bsize);
3734 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3736 if (mainview->current_color == NULL) {
3737 GdkColor color = {0, 0, 0, 0};
3738 mainview->current_color = gdk_color_copy(&color);
3740 unsigned long bcol = ((mainview->current_color->red >> 8) << 16) |
3741 ((mainview->current_color->green >> 8) << 8) |
3742 ((mainview->current_color->blue) >> 8);
3744 /* fprintf(stderr, "BRUSHCOLOR is %d (%d,%d,%d)\n", bcol, col->red, col->green, col->blue);*/
3745 g_snprintf(tq, sizeof(tq), "INSERT INTO %s VALUES('brushColor', '%lu');", misctable_name, bcol);
3746 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3748 g_snprintf(tq, sizeof(tq), "INSERT INTO %s VALUES('dataVersion', '%d');", misctable_name, datatableversion);
3749 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3751 g_snprintf(tq, sizeof(tq), "INSERT INTO %s VALUES('checklistVersion', '%d');", misctable_name, checklisttableversion);
3752 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3754 g_snprintf(tq, sizeof(tq), "DROP TABLE %s", datatable_backupname);
3755 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3756 g_snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", datatable_backupname, datatable);
3757 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3759 fprintf(stderr, "ERROR creating backup table!\n");
3760 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, "Error 1");
3762 busy_leave(mainview);
3763 return;
3765 g_snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT * FROM %s", datatable_backupname, datatable_name);
3766 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3768 fprintf(stderr, "ERROR backing up table!\n");
3769 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, "Error 2");
3771 busy_leave(mainview);
3772 return;
3774 g_snprintf(tq, sizeof(tq), "DELETE FROM %s", datatable_name);
3775 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3777 g_snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT * FROM %s", datatable_name, datatable_tmpname);
3778 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3780 fprintf(stderr, "ERROR saving table!\n");
3781 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, "Error 3");
3783 g_snprintf(tq, sizeof(tq), "DELETE FROM %s", datatable_name);
3784 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3786 g_snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT * FROM %s", datatable_name, datatable_backupname);
3787 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3789 fprintf(stderr, "ERROR restoring backup! data lost!\n");
3792 busy_leave(mainview);
3793 return;
3796 g_snprintf(tq, sizeof(tq), "DROP TABLE %s", datatable_backupname);
3797 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3799 /*checklist*/
3800 g_snprintf(tq, sizeof(tq), "DROP TABLE %s", checklisttable_backupname);
3801 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3802 g_snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", checklisttable_backupname, checklisttable);
3803 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3805 fprintf(stderr, "ERROR creating backup table! (checklist)\n");
3806 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, "Error 4");
3808 busy_leave(mainview);
3809 return;
3812 g_snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT * FROM %s", checklisttable_backupname, checklisttable_name);
3813 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3815 fprintf(stderr, "ERROR backing up table! (checklist)\n");
3816 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, "Error 5");
3818 busy_leave(mainview);
3819 return;
3821 g_snprintf(tq, sizeof(tq), "DELETE FROM %s", checklisttable_name);
3822 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3824 g_snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT * FROM %s", checklisttable_name, checklisttable_tmpname);
3825 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3827 fprintf(stderr, "ERROR saving table! (checklist)\n");
3828 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, "Error 6");
3830 g_snprintf(tq, sizeof(tq), "DELETE FROM %s", checklisttable_name);
3831 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3833 g_snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT * FROM %s", checklisttable_name, checklisttable_backupname);
3834 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3836 fprintf(stderr, "ERROR restoring backup! data lost! (checklist)\n");
3838 busy_leave(mainview);
3839 return;
3842 g_snprintf(tq, sizeof(tq), "DROP TABLE %s", checklisttable_backupname);
3843 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3845 mainview->file_edited = FALSE;
3846 busy_leave(mainview);
3847 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), GTK_STOCK_SAVE, _("Changes saved"));
3851 void callback_checklist_toggled(GtkCellRendererToggle *cell_renderer, gchar *path, GtkWidget *source)
3853 gtk_object_set_data(GTK_OBJECT(source), "edited", GINT_TO_POINTER(TRUE));
3855 GtkTreeIter iter;
3856 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(source));
3857 GtkTreePath *treepath = gtk_tree_path_new_from_string(path);
3858 if(gtk_tree_model_get_iter(model, &iter, treepath)) {
3859 gboolean val;
3860 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHECKNODE_CHECKED, &val, -1);
3861 gtk_list_store_set(GTK_LIST_STORE(model), &iter, CHECKNODE_CHECKED, !val, -1);
3862 if (!val) {
3863 gtk_list_store_set(GTK_LIST_STORE(model), &iter, CHECKNODE_ICON_NAME, "widgets_tickmark_list", -1);
3864 } else {
3865 gtk_list_store_set(GTK_LIST_STORE(model), &iter, CHECKNODE_ICON_NAME, "", -1);
3868 gtk_tree_path_free(treepath);
3871 void callback_checklist_edited(GtkCellRendererToggle *cell_renderer, gchar *arg1, gchar *arg2, GtkWidget *source)
3873 gtk_object_set_data(GTK_OBJECT(source), "edited", GINT_TO_POINTER(TRUE));
3875 GtkTreeIter iter;
3876 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(source));
3877 GtkTreePath *treepath = gtk_tree_path_new_from_string(arg1);
3878 if(gtk_tree_model_get_iter(model, &iter, treepath))
3880 gtk_list_store_set(GTK_LIST_STORE(model), &iter, CHECKNODE_TEXT, arg2, -1);
3882 gtk_tree_path_free(treepath);
3885 void callback_checklist_change(GtkTreeSelection *selection, MainView *mainview)
3887 g_assert(mainview != NULL && mainview->data != NULL);
3889 g_signal_handlers_block_by_func(mainview->bold_tb, callback_fontstyle, mainview->bold_tb);
3890 g_signal_handlers_block_by_func(mainview->strikethru_tb, callback_fontstyle, mainview->strikethru_tb);
3891 g_signal_handlers_block_by_func(mainview->check_tb, callback_fontstyle, mainview->check_tb);
3893 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->bold_tb), FALSE);
3894 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->strikethru_tb), FALSE);
3895 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->check_tb), FALSE);
3897 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->listview));
3898 GList* l=gtk_tree_selection_get_selected_rows(selection, NULL);
3900 gboolean gotit=FALSE;
3902 GList* cur=l;
3903 while(cur)
3905 GtkTreePath *path=cur->data;
3907 if (!gotit)
3909 GtkTreeIter iter;
3910 if (gtk_tree_model_get_iter(model, &iter, path))
3912 gint styletoset_weight;
3913 gboolean styletoset_strike;
3914 gboolean ischecked;
3916 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHECKNODE_BOLD, &styletoset_weight, CHECKNODE_STRIKE, &styletoset_strike, CHECKNODE_CHECKED, &ischecked, -1);
3917 if (styletoset_weight==PANGO_WEIGHT_BOLD) gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->bold_tb), TRUE);
3918 if (styletoset_strike==TRUE) gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->strikethru_tb), TRUE);
3919 if (ischecked==TRUE) gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->check_tb), TRUE);
3920 gotit=TRUE;
3923 gtk_tree_path_free(path);
3924 cur=cur->next;
3927 g_list_free(l);
3929 g_signal_handlers_unblock_by_func(mainview->bold_tb, callback_fontstyle, mainview->bold_tb);
3930 g_signal_handlers_unblock_by_func(mainview->strikethru_tb, callback_fontstyle, mainview->strikethru_tb);
3931 g_signal_handlers_unblock_by_func(mainview->check_tb, callback_fontstyle, mainview->check_tb);
3934 void callback_checklist_paste(MainView *mainview)
3936 g_assert(mainview != NULL && mainview->data != NULL);
3937 gchar **entries;
3938 gint length, i;
3940 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->listview));
3941 GtkTreeIter toplevel;
3942 gchar *pasted_text = gtk_clipboard_wait_for_text(mainview->clipboard);
3944 entries = g_strsplit(pasted_text, "\n", 0);
3945 length = g_strv_length(entries);
3947 for (i=0; i<length; i++) {
3948 gtk_list_store_append(GTK_LIST_STORE(model), &toplevel);
3949 gtk_list_store_set(GTK_LIST_STORE(model), &toplevel, CHECKNODE_CHECKED, FALSE, CHECKNODE_TEXT, entries[i], -1);
3952 gtk_object_set_data(GTK_OBJECT(mainview->listview), "edited", GINT_TO_POINTER(TRUE));
3953 g_free(pasted_text);
3954 g_strfreev(entries);
3957 void callback_checklist_add(GtkAction *action, MainView *mainview)
3959 g_assert(mainview != NULL && mainview->data != NULL);
3961 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->listview));
3962 GtkTreeIter toplevel;
3963 gtk_list_store_append(GTK_LIST_STORE(model), &toplevel);
3965 gtk_list_store_set(GTK_LIST_STORE(model), &toplevel, CHECKNODE_CHECKED, FALSE, CHECKNODE_TEXT, "", -1);
3966 GtkTreePath *path = gtk_tree_model_get_path(model, &toplevel);
3967 if (path)
3969 gtk_tree_view_set_cursor(GTK_TREE_VIEW(mainview->listview), path, mainview->listtextcol, TRUE);
3970 gtk_tree_path_free(path);
3973 gtk_object_set_data(GTK_OBJECT(mainview->listview), "edited", GINT_TO_POINTER(TRUE));
3976 void callback_checklist_delete(GtkAction *action, MainView *mainview)
3978 g_assert(mainview != NULL && mainview->data != NULL);
3980 if (gtk_tree_selection_count_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->listview)))==0) {
3981 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Select items first"));
3982 return;
3985 if (show_confirmation(mainview, _("Delete selected checklist item?"))) {
3986 callback_checklist_delete_real(mainview);
3990 void callback_checklist_delete_real(MainView* mainview)
3992 GtkTreeModel *model=gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->listview));
3993 GList* l=gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->listview)), NULL);
3995 GList* rowrefs=NULL;
3996 GList* cur=l;
3997 while(cur)
3999 GtkTreePath *path=cur->data;
4001 GtkTreeIter iter;
4002 if (gtk_tree_model_get_iter(model, &iter, path))
4004 GtkTreeRowReference *rowref = gtk_tree_row_reference_new(model, path);
4005 rowrefs=g_list_append(rowrefs, rowref);
4007 gtk_tree_path_free(path);
4008 cur=cur->next;
4010 g_list_free(l);
4012 g_object_ref(model);
4013 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->listview), NULL);
4015 cur=rowrefs;
4016 while(cur)
4018 GtkTreeRowReference *rowref=cur->data;
4019 GtkTreePath *path= gtk_tree_row_reference_get_path(rowref);
4020 if (path)
4022 GtkTreeIter iter;
4023 if (gtk_tree_model_get_iter(model, &iter, path)) gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
4024 gtk_tree_path_free(path);
4026 gtk_tree_row_reference_free(rowref);
4027 cur=cur->next;
4029 g_list_free(rowrefs);
4031 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->listview), model);
4032 g_object_unref(model);
4033 gtk_object_set_data(GTK_OBJECT(mainview->listview), "edited", GINT_TO_POINTER(TRUE));
4036 /* Ask the user for confirmation of a specific action */
4037 gboolean show_confirmation(MainView* mainview, gchar* question)
4039 GtkDialog* dialog = GTK_DIALOG(hildon_note_new_confirmation(
4040 GTK_WINDOW(mainview->data->main_view), question));
4042 gint response = gtk_dialog_run(dialog);
4043 gtk_widget_destroy(GTK_WIDGET(dialog));
4045 return (response == GTK_RESPONSE_OK);