Switch to first memo after a memo has been deleted to update view
[maemopadplus.git] / src / ui / callbacks.c
blobbfbb07d7af43ff07f2e683073f66edcc5f658c67
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>
29 * strlen needed from string.h
31 #include <string.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <unistd.h>
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include <config.h>
38 #include <time.h>
40 #include <hildon/hildon-banner.h>
41 #include <hildon/hildon-note.h>
42 #include <hildon/hildon-font-selection-dialog.h>
43 #include <tablet-browser-interface.h>
45 #include <libgnomevfs/gnome-vfs.h>
49 * Privates:
51 gboolean read_file_to_buffer(MainView * mainview);
52 void write_buffer_to_file(MainView * mainview);
53 void new_node_dialog(nodeType typ, MainView * mainview);
54 gboolean foreach_func_update_ord (GtkTreeModel *model,GtkTreePath *path,GtkTreeIter *iter, MainView *mainview);
55 void move_nodes_up(GtkTreeModel * model, GtkTreeRowReference * topnode, GtkTreeRowReference * newtop);
56 GtkTreeRowReference *iter2ref(GtkTreeModel * model, GtkTreeIter * iter);
57 gboolean exec_command_on_db(MainView *mainview,char sql_string[]);
58 int get_node_id_on_tmp_db(GtkTreeModel *model,GtkTreeIter *iter);
59 gint get_branch_node_index(GtkTreePath *path);
60 gboolean move_node(MainView *mainview,GtkTreeIter *new_parent,GtkTreeIter *item_to_move,GtkTreeIter *item_befor);
61 gboolean tree_model_iter_prev(GtkTreeModel *tree_model,GtkTreeIter *iter);
64 st==0: turn off/zero refcount
65 st==1: turn on/increase ref
66 st==2: decrease refcount and turn off if necessary
68 void setBusy(MainView *mainview, gchar st)
70 if (st==0) mainview->busyrefcount=0;
71 else if (st==1) mainview->busyrefcount++;
72 else if (st==2 && mainview->busyrefcount>0) mainview->busyrefcount--;
73 gdk_window_set_cursor(GTK_WIDGET(mainview->data->main_view)->window, (mainview->busyrefcount>0)?mainview->cursorBusy:NULL);
76 gboolean isBusy(MainView *mainview)
78 if (mainview->busyrefcount>0) return(TRUE);
79 return(FALSE);
82 void prepareUIforNodeChange(MainView * mainview, nodeType typ)
84 gtk_widget_set_sensitive(GTK_WIDGET(mainview->undo_tb), TRUE);
85 gtk_widget_set_sensitive(GTK_WIDGET(mainview->redo_tb), TRUE);
87 if (typ == NODE_TEXT)
89 gtk_widget_show(GTK_WIDGET(mainview->font_tb));
90 gtk_widget_show(GTK_WIDGET(mainview->bold_tb));
91 gtk_widget_show(GTK_WIDGET(mainview->italic_tb));
92 gtk_widget_show(GTK_WIDGET(mainview->underline_tb));
93 gtk_widget_show(GTK_WIDGET(mainview->bullet_tb));
94 gtk_widget_show(mainview->tools_font);
95 gtk_widget_show(mainview->tools_wordwrap);
97 else
99 gtk_widget_hide(GTK_WIDGET(mainview->font_tb));
100 gtk_widget_hide(GTK_WIDGET(mainview->bold_tb));
101 gtk_widget_hide(GTK_WIDGET(mainview->italic_tb));
102 gtk_widget_hide(GTK_WIDGET(mainview->underline_tb));
103 gtk_widget_hide(GTK_WIDGET(mainview->bullet_tb));
104 gtk_widget_hide(mainview->tools_font);
105 gtk_widget_hide(mainview->tools_wordwrap);
108 if (typ == NODE_SKETCH)
110 /* gtk_widget_show(GTK_WIDGET(mainview->colorbutton_tb));*/
111 gtk_widget_show(GTK_WIDGET(mainview->eraser_tb));
112 gtk_widget_show(GTK_WIDGET(mainview->brushsize_tb));
113 gtk_widget_show(GTK_WIDGET(mainview->sketchlines_tb));
114 gtk_widget_show(GTK_WIDGET(mainview->shape_tb));
115 gtk_widget_show(mainview->tools_color);
116 gtk_widget_show(mainview->tools_brushsize);
117 gtk_widget_show(mainview->tools_pagestyle);
118 gtk_widget_show(mainview->tools_shape);
119 gtk_widget_show(mainview->tools_pressure);
121 else
123 /* gtk_widget_hide(GTK_WIDGET(mainview->colorbutton_tb));*/
124 gtk_widget_hide(GTK_WIDGET(mainview->eraser_tb));
125 gtk_widget_hide(GTK_WIDGET(mainview->brushsize_tb));
126 gtk_widget_hide(GTK_WIDGET(mainview->sketchlines_tb));
127 gtk_widget_hide(GTK_WIDGET(mainview->shape_tb));
128 gtk_widget_hide(mainview->tools_color);
129 gtk_widget_hide(mainview->tools_brushsize);
130 gtk_widget_hide(mainview->tools_pagestyle);
131 gtk_widget_hide(mainview->tools_shape);
132 gtk_widget_hide(mainview->tools_pressure);
135 if (typ == NODE_CHECKLIST)
137 gtk_widget_show(GTK_WIDGET(mainview->bold_tb));
138 gtk_widget_show(GTK_WIDGET(mainview->strikethru_tb));
139 gtk_widget_show(GTK_WIDGET(mainview->check_tb));
140 gtk_widget_show(GTK_WIDGET(mainview->checkadd_tb));
141 gtk_widget_show(GTK_WIDGET(mainview->checkdel_tb));
142 gtk_widget_hide(GTK_WIDGET(mainview->undo_tb));
143 gtk_widget_hide(GTK_WIDGET(mainview->redo_tb));
145 else
147 gtk_widget_hide(GTK_WIDGET(mainview->strikethru_tb));
148 gtk_widget_hide(GTK_WIDGET(mainview->check_tb));
149 gtk_widget_hide(GTK_WIDGET(mainview->checkadd_tb));
150 gtk_widget_hide(GTK_WIDGET(mainview->checkdel_tb));
151 gtk_widget_show(GTK_WIDGET(mainview->undo_tb));
152 gtk_widget_show(GTK_WIDGET(mainview->redo_tb));
155 if (typ == NODE_TEXT)
157 gtk_widget_hide(GTK_WIDGET(mainview->colorbutton_tb));
158 gtk_widget_hide(sketchwidget_get_mainwidget(mainview->sk));
159 gtk_widget_hide(mainview->listscroll);
160 gtk_widget_show(GTK_WIDGET(mainview->scrolledwindow));
161 gtk_widget_show(mainview->tools_item);
163 else if (typ == NODE_SKETCH)
165 gtk_widget_show(GTK_WIDGET(mainview->colorbutton_tb));
166 gtk_widget_hide(GTK_WIDGET(mainview->scrolledwindow));
167 gtk_widget_hide(mainview->listscroll);
168 gtk_widget_show(sketchwidget_get_mainwidget(mainview->sk));
169 gtk_widget_show(mainview->tools_item);
171 else if (typ == NODE_CHECKLIST)
173 gtk_widget_show(GTK_WIDGET(mainview->colorbutton_tb));
174 gtk_widget_hide(GTK_WIDGET(mainview->scrolledwindow));
175 gtk_widget_hide(sketchwidget_get_mainwidget(mainview->sk));
176 gtk_widget_hide(mainview->tools_item);
177 gtk_widget_show(mainview->listscroll);
179 else
181 gtk_widget_hide(GTK_WIDGET(mainview->colorbutton_tb));
182 gtk_widget_hide(GTK_WIDGET(mainview->scrolledwindow));
183 gtk_widget_hide(sketchwidget_get_mainwidget(mainview->sk));
184 gtk_widget_hide(mainview->tools_item);
185 gtk_widget_hide(mainview->listscroll);
189 nodeData *getSelectedNode(MainView * mainview)
191 GtkTreeIter iter;
192 GtkTreeModel *model;
194 nodeData *nd;
196 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
198 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
199 return (NULL);
201 gtk_tree_model_get(model, &iter, NODE_DATA, &nd, -1);
203 return (nd);
206 void saveCurrentData(MainView * mainview)
208 nodeData *selnode = getSelectedNode(mainview);
209 saveDataToNode(mainview, selnode);
212 void saveDataToNode(MainView * mainview, nodeData *selnode)
214 if (selnode == NULL)
215 return;
217 if (
218 (selnode->typ == NODE_SKETCH && sketchwidget_get_edited(mainview->sk) == FALSE) ||
219 (selnode->typ == NODE_TEXT && wp_text_buffer_is_modified(mainview->buffer)==FALSE) ||
220 (selnode->typ == NODE_CHECKLIST && gtk_object_get_data(GTK_OBJECT(mainview->listview), "edited")==FALSE)
223 fprintf(stderr, "node not edited, not saving\n");
224 return;
227 mainview->file_edited = TRUE;
229 setBusy(mainview, 1);
230 fprintf(stderr, "savecurrentdata!\n");
232 gboolean goterr = TRUE;
233 gchar *textdata = NULL;
234 GdkPixbuf *pixbuf = NULL;
235 gchar *sketchdata = NULL;
236 gsize datalen = 0;
237 char tq[512];
239 if (selnode->typ == NODE_TEXT)
241 #if 0
242 GtkTextIter start, end;
243 gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(mainview->buffer), &start, &end);
244 textdata = gtk_text_buffer_serialize_rich_text(GTK_TEXT_BUFFER(mainview->buffer), &start, &end, &datalen);
245 #endif
247 GString *gstr=g_string_sized_new(4096);
248 wp_text_buffer_save_document(mainview->buffer, (WPDocumentSaveCallback)(wp_savecallback), gstr);
250 datalen=gstr->len;
251 textdata=g_string_free(gstr, FALSE);
252 /*fprintf(stderr, "*%s*\n", textdata);*/
254 /* 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);*/
255 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);
257 else if (selnode->typ == NODE_SKETCH)
259 GError *err = NULL;
260 GdkPixmap *skpix = sketchwidget_get_Pixmap(mainview->sk);
261 GtkWidget *skdr = sketchwidget_get_drawingarea(mainview->sk);
263 pixbuf = gdk_pixbuf_get_from_drawable(NULL, GDK_DRAWABLE(skpix), NULL, 0, 0, 0, 0, skdr->allocation.width, skdr->allocation.height);
264 if (pixbuf == NULL)
266 fprintf(stderr, "Error saving: pixbuf is null\n");
268 else
270 double w, h;
271 GdkPixbuf *pixbuf2 = sketchwidget_trim_image(pixbuf, skdr->allocation.width, skdr->allocation.height, &w, &h, FALSE);
273 if (pixbuf2!=NULL)
275 if (gdk_pixbuf_save_to_buffer(pixbuf2, &sketchdata, &datalen, "png", &err, NULL) == FALSE)
277 sketchdata = NULL;
278 datalen = 0;
279 fprintf(stderr, "Error saving sketch! %s\n", err->message);
280 g_error_free(err);
282 gdk_pixbuf_unref(pixbuf2);
285 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);
286 fprintf(stderr, "datalen:%d\n", datalen);
287 if (skpix && G_IS_OBJECT(skpix)) g_object_unref(skpix);
289 else if (selnode->typ == NODE_CHECKLIST)
291 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);
294 /*fprintf(stderr, "query is *%s*\n", tq); */
298 sqlite3_stmt *stmt = NULL;
299 const char *dum;
300 int rc = sqlite3_prepare(mainview->db, tq, strlen(tq), &stmt, &dum);
302 if (rc)
304 fprintf(stderr, "Error updating: %s\n", sqlite3_errmsg(mainview->db));
305 break;
307 if (selnode->typ == NODE_TEXT)
308 sqlite3_bind_text(stmt, 1, textdata, datalen, /*strlen(textdata),*/ SQLITE_TRANSIENT);
309 else if (selnode->typ == NODE_SKETCH)
310 sqlite3_bind_blob(stmt, 1, sketchdata, datalen, SQLITE_TRANSIENT);
312 rc = SQLITE_BUSY;
313 while(rc == SQLITE_BUSY)
315 rc = sqlite3_step(stmt);
316 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE || rc == SQLITE_DONE)
317 break;
319 sqlite3_finalize(stmt);
321 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE)
323 fprintf(stderr, "Error saving node: %s\n", sqlite3_errmsg(mainview->db));
325 else
327 if (selnode->typ == NODE_TEXT)
328 gtk_text_buffer_set_modified(GTK_TEXT_BUFFER(mainview->buffer), FALSE);
329 else if (selnode->typ == NODE_SKETCH)
330 sketchwidget_set_edited(mainview->sk, FALSE);
331 else if (selnode->typ == NODE_CHECKLIST)
332 gtk_object_set_data(GTK_OBJECT(mainview->listview), "edited", FALSE);
333 goterr = FALSE;
335 }while(FALSE);
337 while(goterr==FALSE && selnode->typ == NODE_CHECKLIST)
339 GtkTreeModel *model=gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->listview));
341 char tq[512];
342 snprintf(tq, sizeof(tq), "DELETE FROM %s WHERE nodeid=%d", checklisttable_tmpname, selnode->sql3id);
343 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
345 GtkTreeIter iter;
346 if (gtk_tree_model_get_iter_first(model, &iter)==FALSE) break;
350 gint styletoset_weight;
351 gboolean styletoset_strike;
352 gboolean ischecked;
353 gchar *text;
354 gchar *color;
355 unsigned long col=0;
357 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);
359 GdkColor tmpcol;
360 if (color!=NULL && strcmp(color, "(null)")!=0 && gdk_color_parse(color, &tmpcol))
362 col=((tmpcol.red>>8)<<16)|((tmpcol.green>>8)<<8)|(tmpcol.blue>>8);
363 /* fprintf(stderr, "calculated color for node is *%lu*\n", col);*/
366 gint style=0;
367 if (ischecked) style|=CHECKSTYLE_CHECKED;
368 if (styletoset_weight==PANGO_WEIGHT_BOLD) style|=CHECKSTYLE_BOLD;
369 if (styletoset_strike) style|=CHECKSTYLE_STRIKE;
371 snprintf(tq, sizeof(tq), "INSERT INTO %s (nodeid, name, style, color, ord) VALUES(%d, ?, %d, %lu, 0)", checklisttable_tmpname, selnode->sql3id, style, col);
372 sqlite3_stmt *stmt = NULL;
373 const char *dum;
374 int rc = sqlite3_prepare(mainview->db, tq, strlen(tq), &stmt, &dum);
376 if (rc)
378 goterr=TRUE;
379 fprintf(stderr, "Error while saving checklist: %s\n", sqlite3_errmsg(mainview->db));
380 break;
382 sqlite3_bind_text(stmt, 1, text, strlen(text), SQLITE_TRANSIENT);
384 rc = SQLITE_BUSY;
385 while(rc == SQLITE_BUSY)
387 rc = sqlite3_step(stmt);
388 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE || rc == SQLITE_DONE)
389 break;
391 sqlite3_finalize(stmt);
393 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE)
395 goterr=TRUE;
396 fprintf(stderr, "Error while saving checklist (2): %s\n", sqlite3_errmsg(mainview->db));
399 g_free(color);
400 g_free(text);
402 }while(gtk_tree_model_iter_next(model, &iter)==TRUE);
404 break;
407 if (textdata)
408 g_free(textdata);
409 if (sketchdata)
410 g_free(sketchdata);
411 if (goterr == TRUE)
413 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Error saving memo"));
415 setBusy(mainview, 2);
418 void callback_treeview_celldatafunc(GtkTreeViewColumn * tree_column, GtkCellRenderer * cell, GtkTreeModel * tree_model, GtkTreeIter * iter, gpointer data)
420 MainView *mainview = ( MainView * ) data;
421 g_assert(mainview != NULL && mainview->data != NULL );
423 nodeData *nd;
425 gtk_tree_model_get(tree_model, iter, NODE_DATA, &nd, -1);
426 if (nd == NULL)
427 return;
429 if (nd->namepix == NULL)
431 g_object_set(cell, "visible", FALSE, NULL);
433 else
435 g_object_set(cell, "visible", TRUE, NULL);
436 g_object_set(cell, "width", SKETCHNODE_RX, NULL);
437 g_object_set(cell, "height", SKETCHNODE_RY, NULL);
442 gboolean callback_treeview_testcollapse(GtkTreeView * treeview, GtkTreeIter * arg1, GtkTreePath * arg2, gpointer user_data)
444 return (TRUE);
447 void callback_treeview_change(GtkTreeSelection * selection, gpointer data)
449 MainView *mainview = (MainView *) data;
450 g_assert(mainview != NULL && mainview->data != NULL);
452 nodeData *nd = getSelectedNode(mainview);
455 if (nd==NULL)
456 fprintf(stderr, "changed called but no selectednode\n");
457 else
458 fprintf(stderr, "changed called, selectednode is %d\n", nd->sql3id);
460 #ifdef NEW_SEL_LOGIC
461 guint tm=time(NULL);
462 if (mainview->cansel_time>0 && mainview->cansel_time+1.0<tm) mainview->cansel_node=NULL;
464 if (nd==NULL)
466 if (mainview->cansel_node!=NULL)
468 fprintf(stderr, "[SELLOGIC] saving %d to unselect all nodes\n", (mainview->cansel_node)->sql3id);
469 saveDataToNode(mainview, (mainview->cansel_node));
470 mainview->cansel_node=NULL;
472 return;
475 if (mainview->cansel_node!=NULL)
477 if (nd->sql3id == (mainview->cansel_node)->sql3id)
479 mainview->cansel_node=NULL;
480 fprintf(stderr, "[SELLOGIC] doubly selected %d, doing nothing\n", nd->sql3id);
481 return;
483 else
485 fprintf(stderr, "[SELLOGIC] saving %d to load new node\n", (mainview->cansel_node)->sql3id);
486 saveDataToNode(mainview, (mainview->cansel_node));
487 mainview->cansel_node=NULL;
490 #endif
492 if (nd == NULL) return;
494 setBusy(mainview, 1);
496 gboolean goterr = TRUE;
497 char *textdata = NULL;
498 char *blob = NULL;
499 int blobsize = 0, textsize = 0;
501 char tq[512];
503 snprintf(tq, sizeof(tq), "SELECT bodytype, body, bodyblob, flags FROM %s WHERE nodeid=%d", datatable_tmpname, nd->sql3id);
504 sqlite3_stmt *stmt = NULL;
505 const char *dum;
506 int rc = sqlite3_prepare(mainview->db, tq, strlen(tq), &stmt, &dum);
508 if (rc)
510 fprintf(stderr, "Error reading (1) %s\n", sqlite3_errmsg(mainview->db));
512 else
514 rc = SQLITE_BUSY;
515 while(rc == SQLITE_BUSY || rc == SQLITE_ROW)
517 rc = sqlite3_step(stmt);
518 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE || rc == SQLITE_DONE)
519 break;
520 else if (rc == SQLITE_ROW)
522 nd->typ = sqlite3_column_int(stmt, 0);
523 nd->flags = sqlite3_column_int(stmt, 3);
525 prepareUIforNodeChange(mainview, nd->typ);
526 if (nd->typ == NODE_TEXT)
528 gboolean file_edited_backup = mainview->file_edited;
530 blobsize = sqlite3_column_bytes(stmt, 2);
531 blob = (char *)sqlite3_column_blob(stmt, 2);
533 textdata = (char *)sqlite3_column_text(stmt, 1);
534 textsize = sqlite3_column_bytes(stmt, 1);
536 /* gtk_text_buffer_set_text(GTK_TEXT_BUFFER(mainview->buffer), "", -1);*/
537 wp_text_buffer_reset_buffer(mainview->buffer, TRUE);
539 gboolean richtext=FALSE;
541 if (blob != NULL)
543 #if 0
544 gboolean oldway=FALSE;
545 if (blobsize>8)
547 char tst[8];
548 strncpy(tst, blob, 8);
549 tst[8]=0;
550 if (strcmp(tst, "RICHTEXT")==0) oldway=TRUE;
552 if (oldway)
554 GError *err = NULL;
555 GtkTextIter iter;
556 gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(mainview->buffer), &iter);
557 gtk_text_buffer_deserialize_rich_text(GTK_TEXT_BUFFER(mainview->buffer), &iter, blob, blobsize, TRUE, &err);
558 if (err != NULL)
560 fprintf(stderr, "Error loading text memo with richtext parser! %s\n", err->message);
561 g_error_free(err);
563 else
565 richtext=TRUE;
568 #endif
570 if (richtext==FALSE)
572 wp_text_buffer_load_document_begin(mainview->buffer, TRUE);
573 wp_text_buffer_load_document_write(mainview->buffer, blob, blobsize);
574 wp_text_buffer_load_document_end(mainview->buffer);
575 richtext=TRUE;
578 if (richtext==FALSE && !(textdata == NULL || g_utf8_validate(textdata, textsize, NULL) == FALSE))
580 /* gtk_text_buffer_set_text(GTK_TEXT_BUFFER(mainview->buffer), textdata, textsize);*/
581 wp_text_buffer_load_document_begin(mainview->buffer, FALSE);
582 wp_text_buffer_load_document_write(mainview->buffer, textdata, textsize);
583 wp_text_buffer_load_document_end(mainview->buffer);
586 wp_text_buffer_enable_rich_text(mainview->buffer, TRUE);
587 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->tools_wordwrap), ((nd->flags & NODEFLAG_WORDWRAP) > 0)?TRUE:FALSE);
588 callback_wordwrap(NULL, mainview); /*FIXME:ugly (do we need this? gotta test) */
590 gtk_text_buffer_set_modified(GTK_TEXT_BUFFER(mainview->buffer), FALSE); /*we probably don't need this*/
592 callback_undotoggle((gpointer)mainview->buffer, FALSE, mainview); /*we need these*/
593 callback_redotoggle((gpointer)mainview->buffer, FALSE, mainview);
595 if (file_edited_backup==FALSE) mainview->file_edited=FALSE; /*textview changed event toggles this?*/
596 goterr = FALSE;
598 else if (nd->typ == NODE_SKETCH)
600 sketchwidget_wipe_undo(mainview->sk);
601 sketchwidget_set_fillmode(mainview->sk, FALSE);
602 sketchwidget_set_shift(mainview->sk, FALSE);
603 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->shapemenuitems[1]), TRUE);
604 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->shapemenuitems[0]), TRUE);
606 blobsize = sqlite3_column_bytes(stmt, 2);
607 blob = (char *)sqlite3_column_blob(stmt, 2);
608 gboolean clear = TRUE;
610 if (blob == NULL)
611 goterr = FALSE;
612 if (blob != NULL)
614 fprintf(stderr, "blobsize:%d\n", blobsize);
615 GdkPixbufLoader *pl = gdk_pixbuf_loader_new_with_type("png", NULL);
616 GError *err = NULL;
618 gdk_pixbuf_loader_write(pl, (guchar *) blob, blobsize, &err);
619 if (err != NULL)
621 fprintf(stderr, "Error loading sketch! %s\n", err->message);
622 g_error_free(err);
623 err = NULL;
625 gdk_pixbuf_loader_close(pl, NULL);
626 GdkPixbuf *pixbuf = gdk_pixbuf_loader_get_pixbuf(pl);
628 if (GDK_IS_PIXBUF(pixbuf))
630 GtkWidget *skdr = sketchwidget_get_drawingarea(mainview->sk);
631 GtkPixmap *skpix = (GtkPixmap *) sketchwidget_get_Pixmap(mainview->sk);
633 int w=gdk_pixbuf_get_width(pixbuf);
634 int h=gdk_pixbuf_get_height(pixbuf);
635 if (w!=skdr->allocation.width || h!=skdr->allocation.height)
637 if (w>skdr->allocation.width) w=skdr->allocation.width;
638 if (h>skdr->allocation.height) h=skdr->allocation.height;
639 sketchwidget_clear_real(mainview->sk);
641 gdk_draw_pixbuf(GDK_DRAWABLE(skpix), NULL, pixbuf, 0, 0, 0, 0, w, h, GDK_RGB_DITHER_NONE, 0, 0);
643 clear = FALSE;
644 goterr = FALSE;
646 if (skpix && G_IS_OBJECT(skpix)) g_object_unref(skpix);
648 else
650 fprintf(stderr, "error loading pixbuf\n");
652 g_object_unref(pl);
654 if (clear == TRUE)
656 fprintf(stderr, "clearing pix area\n");
657 sketchwidget_clear_real(mainview->sk);
659 gtk_widget_queue_draw(sketchwidget_get_drawingarea(mainview->sk));
661 else if (nd->typ == NODE_CHECKLIST)
663 gtk_object_set_data(GTK_OBJECT(mainview->listview), "edited", FALSE);
664 GtkTreeModel *model=gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->listview));
665 g_object_ref(model);
666 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->listview), NULL);
667 gtk_list_store_clear(GTK_LIST_STORE(model));
669 snprintf(tq, sizeof(tq), "SELECT name, style, color FROM %s WHERE nodeid=%d ORDER BY ord, idx", checklisttable_tmpname, nd->sql3id);
670 sqlite3_stmt *stmt2 = NULL;
671 const char *dum;
672 int rc = sqlite3_prepare(mainview->db, tq, strlen(tq), &stmt2, &dum);
673 if (rc)
675 fprintf(stderr, "Error reading checklist (1) %s\n", sqlite3_errmsg(mainview->db));
677 else
679 goterr=FALSE;
680 rc = SQLITE_BUSY;
681 while(rc == SQLITE_BUSY || rc == SQLITE_ROW)
683 rc = sqlite3_step(stmt2);
684 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE || rc == SQLITE_DONE)
685 break;
686 else if (rc == SQLITE_ROW)
688 char *textdata = (char *)sqlite3_column_text(stmt2, 0);
689 int style = sqlite3_column_int(stmt2, 1);
690 unsigned long col = sqlite3_column_int(stmt2, 2);
692 GtkTreeIter toplevel;
693 gtk_list_store_append(GTK_LIST_STORE(model), &toplevel);
694 gtk_list_store_set(GTK_LIST_STORE(model), &toplevel, CHECKNODE_TEXT, textdata, CHECKNODE_CHECKED, FALSE, -1);
695 if ((style & CHECKSTYLE_CHECKED)>0) gtk_list_store_set(GTK_LIST_STORE(model), &toplevel, CHECKNODE_CHECKED, TRUE, -1);
696 if ((style & CHECKSTYLE_BOLD)>0) gtk_list_store_set(GTK_LIST_STORE(model), &toplevel, CHECKNODE_BOLD, PANGO_WEIGHT_BOLD, -1);
697 if ((style & CHECKSTYLE_STRIKE)>0) gtk_list_store_set(GTK_LIST_STORE(model), &toplevel, CHECKNODE_STRIKE, TRUE, -1);
699 if (col>0)
701 char tmp[10];
702 snprintf(tmp, sizeof(tmp), "#%02x%02x%02x", ((col & 0xFF0000) >> 16), ((col & 0xFF00) >> 8), (col & 0xFF));
703 /* fprintf(stderr, "read color for node is *%s*\n", tmp);*/
704 gtk_list_store_set(GTK_LIST_STORE(model), &toplevel, CHECKNODE_COLOR, tmp, -1);
709 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE)
711 fprintf(stderr, "Error reading checklist (2) %s\n", sqlite3_errmsg(mainview->db));
712 goterr=TRUE;
715 sqlite3_finalize(stmt2);
718 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->listview), model);
719 g_object_unref(model);
722 if ((nd->flags & NODEFLAG_SKETCHLINES) > 0)
723 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->sketchlinesmenuitems[1]), TRUE);
724 else if ((nd->flags & NODEFLAG_SKETCHGRAPH) > 0)
725 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->sketchlinesmenuitems[2]), TRUE);
726 else
728 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->sketchlinesmenuitems[0]), TRUE);
729 callback_sketchlines(NULL, mainview->sketchlinesmenuitems[0]); /*FIXME:ugly */
731 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->tools_pressure), TRUE);
733 break;
736 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE)
737 fprintf(stderr, "Error reading (2) %s\n", sqlite3_errmsg(mainview->db));
739 sqlite3_finalize(stmt);
742 setBusy(mainview, 2);
744 if (goterr == TRUE)
746 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Error loading memo"));
750 gboolean treeview_canselect(GtkTreeSelection * selection, GtkTreeModel * model, GtkTreePath * path, gboolean path_currently_selected, gpointer userdata)
752 MainView *mainview = (MainView *) userdata;
753 g_assert(mainview != NULL && mainview->data != NULL);
755 if (mainview->loading==FALSE)
757 #ifndef EXPANDING_ROWS
758 if (path_currently_selected)
759 return (FALSE);
760 #endif
762 #ifndef NEW_SEL_LOGIC
763 saveCurrentData(mainview);
764 #else
765 if (path_currently_selected)
767 GtkTreeIter iter;
768 gtk_tree_model_get_iter(model, &iter, path);
770 gtk_tree_model_get(model, &iter, NODE_DATA, &(mainview->cansel_node), -1);
771 mainview->cansel_time=time(NULL);
772 /* fprintf(stderr, "[SELLOGIC] canselect called for node %d\n", nd->sql3id);*/
774 #endif
776 return (TRUE);
779 gboolean newnodedlg_key_press_cb(GtkWidget * widget, GdkEventKey * event, GtkWidget * dlg)
781 SketchWidget *s = gtk_object_get_data(GTK_OBJECT(dlg), "sk");
783 switch (event->keyval)
785 case GDK_F7:
786 sketchwidget_redo(s);
787 return TRUE;
788 case GDK_F8:
789 sketchwidget_undo(s);
790 return TRUE;
792 return FALSE;
796 /* This struct will hold all our toggle buttons, so we can
797 * only allow one to be active at a time (i.e. radio buttons) */
798 typedef struct _newNodeToggleButtons newNodeToggleButtons;
799 struct _newNodeToggleButtons
801 GtkWidget *rbt; /* Text */
802 GtkWidget *rbs; /* Sketch */
803 GtkWidget *rbc; /* Checklist */
806 void nntb_toggled(GtkToggleButton *togglebutton, gpointer user_data)
808 newNodeToggleButtons *nntb = (newNodeToggleButtons*)user_data;
809 static gboolean toggle_in_progress = FALSE;
811 /* The toggle_in_progress flag is needed, because the toggled
812 * signal is emitted when setting the active property of the
813 * GtkToggleButtons below - this would result in an endless
814 * recursion - so we don't allow recursive toggle signals. */
816 if (toggle_in_progress) return;
818 toggle_in_progress = TRUE;
819 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(nntb->rbt), FALSE);
820 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(nntb->rbs), FALSE);
821 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(nntb->rbc), FALSE);
822 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(togglebutton), TRUE);
823 toggle_in_progress = FALSE;
826 void show_sketch_widget(GtkWidget *widget, gpointer user_data)
828 GtkWidget *dialog = (GtkWidget*)user_data;
830 /* Show the sketch widget and hide the entry + draw button */
831 gtk_widget_show(gtk_object_get_data(GTK_OBJECT(dialog), "al"));
832 gtk_widget_hide(gtk_object_get_data(GTK_OBJECT(dialog), "draw_button"));
833 gtk_widget_hide(gtk_object_get_user_data(GTK_OBJECT(dialog)));
836 void new_node_dialog(nodeType typ, MainView * mainview)
838 GtkWidget *dialog, *label, *entry, *but_ok, *but_cancel, *vbox, *hbox, *al, *cb;
839 GtkWidget *rb1, *rb2, *rb3;
840 GtkWidget *bb, *im, *lb, *but_sketch, *hb;
841 gchar* tmp_str;
842 gchar datetime_str[200];
843 time_t t_now;
844 struct tm *tm_now;
845 gboolean datetime_written = FALSE;
847 t_now = time(NULL);
848 tm_now = localtime(&t_now);
850 if (tm_now != NULL) {
851 if (strftime(datetime_str, sizeof(datetime_str), "%y-%m-%d %H:%M", tm_now) != 0) {
852 datetime_written = TRUE;
856 if (datetime_written == FALSE) {
857 /* Was not able to determine a datetime string - use default */
858 fprintf(stderr, "Warning: cannot resolve time!\n");
859 strncpy(datetime_str, _("New memo"), sizeof(datetime_str));
860 datetime_str[sizeof(datetime_str)-1] = '\0';
863 newNodeToggleButtons *nntb = g_malloc(sizeof(newNodeToggleButtons));
865 dialog = gtk_dialog_new();
866 gtk_window_set_title(GTK_WINDOW(dialog), _("Create new node"));
867 gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
869 g_signal_connect(G_OBJECT(dialog), "key_press_event", G_CALLBACK(newnodedlg_key_press_cb), dialog);
871 vbox = gtk_vbox_new(FALSE, 5);
873 hbox = gtk_hbox_new(TRUE, 10);
875 /* Text note toggle button */
876 rb1 = gtk_toggle_button_new();
877 bb = gtk_hbox_new(FALSE, 5);
878 gtk_container_set_border_width(GTK_CONTAINER(bb), 10);
879 gtk_container_add(GTK_CONTAINER(rb1), bb);
880 im = gtk_image_new_from_file(PIXMAPDIR "/text.png");
881 lb = gtk_label_new(NULL);
882 tmp_str = g_strdup_printf("<b>%s</b>", _("Rich text"));
883 gtk_label_set_markup(GTK_LABEL(lb), tmp_str);
884 g_free(tmp_str);
885 gtk_box_pack_start(GTK_BOX(bb), im, FALSE, FALSE, 0);
886 gtk_box_pack_start(GTK_BOX(bb), lb, FALSE, FALSE, 0);
887 gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(rb1), FALSE, FALSE, 0);
888 g_signal_connect(G_OBJECT(rb1), "toggled", G_CALLBACK(nntb_toggled), nntb);
889 nntb->rbt = rb1;
891 /* Sketch toggle button */
892 rb2 = gtk_toggle_button_new();
893 bb = gtk_hbox_new(FALSE, 5);
894 gtk_container_set_border_width(GTK_CONTAINER(bb), 10);
895 gtk_container_add(GTK_CONTAINER(rb2), bb);
896 im = gtk_image_new_from_file(PIXMAPDIR "/sketch.png");
897 lb = gtk_label_new(NULL);
898 tmp_str = g_strdup_printf("<b>%s</b>", _("Sketch"));
899 gtk_label_set_markup(GTK_LABEL(lb), tmp_str);
900 g_free(tmp_str);
901 gtk_box_pack_start(GTK_BOX(bb), im, FALSE, FALSE, 0);
902 gtk_box_pack_start(GTK_BOX(bb), lb, FALSE, FALSE, 0);
903 gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(rb2), FALSE, FALSE, 0);
904 g_signal_connect(G_OBJECT(rb2), "toggled", G_CALLBACK(nntb_toggled), nntb);
905 nntb->rbs = rb2;
907 /* Checklist toggle button */
908 rb3 = gtk_toggle_button_new();
909 bb = gtk_hbox_new(FALSE, 5);
910 gtk_container_set_border_width(GTK_CONTAINER(bb), 10);
911 gtk_container_add(GTK_CONTAINER(rb3), bb);
912 im = gtk_image_new_from_file(PIXMAPDIR "/checklist.png");
913 lb = gtk_label_new(NULL);
914 tmp_str = g_strdup_printf("<b>%s</b>", _("Checklist"));
915 gtk_label_set_markup(GTK_LABEL(lb), tmp_str);
916 g_free(tmp_str);
917 gtk_box_pack_start(GTK_BOX(bb), im, FALSE, FALSE, 0);
918 gtk_box_pack_start(GTK_BOX(bb), lb, FALSE, FALSE, 0);
919 gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(rb3), FALSE, FALSE, 0);
920 g_signal_connect(G_OBJECT(rb3), "toggled", G_CALLBACK(nntb_toggled), nntb);
921 nntb->rbc = rb3;
923 /* Add padding around our toggle buttons */
924 gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
926 /* Remember "new note toggle buttons" list */
927 gtk_object_set_data(GTK_OBJECT(dialog), "nntb", nntb);
929 if (typ == NODE_TEXT) {
930 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rb1), TRUE);
931 } else if (typ == NODE_SKETCH) {
932 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rb2), TRUE);
933 } else {
934 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rb3), TRUE);
937 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
939 but_ok = gtk_button_new_with_label(_("Create node"));
940 but_cancel = gtk_button_new_with_label(_("Cancel"));
941 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area), but_ok);
942 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area), but_cancel);
944 gtk_object_set_data(GTK_OBJECT(dialog), "m", mainview);
946 gtk_signal_connect_object(GTK_OBJECT(but_cancel), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), dialog);
947 g_signal_connect(G_OBJECT(but_ok), "clicked", G_CALLBACK(callback_new_node_real), dialog);
949 hb = gtk_hbox_new(FALSE, 10);
950 gtk_box_pack_start(GTK_BOX(hb), gtk_label_new(_("Label:")), FALSE, FALSE, 0);
951 entry = gtk_entry_new_with_max_length(64);
952 gtk_object_set_user_data(GTK_OBJECT(dialog), entry);
953 gtk_entry_set_text(GTK_ENTRY(entry), datetime_str);
954 gtk_editable_select_region(GTK_EDITABLE(entry), 0, -1);
955 gtk_box_pack_start(GTK_BOX(hb), entry, TRUE, TRUE, 0);
957 /* Sketch widget, hidden by default */
958 al = gtk_alignment_new(0.5, 0.5, 0, 0);
959 SketchWidget *s = sketchwidget_new(SKETCHNODE_X, SKETCHNODE_Y, TRUE);
960 gtk_object_set_data(GTK_OBJECT(dialog), "sk", s);
961 gtk_object_set_data(GTK_OBJECT(dialog), "al", al);
962 sketchwidget_set_brushsize(s, 2);
963 sketchwidget_set_backstyle(s, SKETCHBACK_GRAPH);
964 gtk_widget_set_size_request(sketchwidget_get_mainwidget(s), SKETCHNODE_X, SKETCHNODE_Y);
965 gtk_container_add(GTK_CONTAINER(al), sketchwidget_get_mainwidget(s));
966 gtk_box_pack_start(GTK_BOX(hb), al, FALSE, FALSE, 0);
968 but_sketch = gtk_button_new_with_label(_("Draw..."));
969 gtk_object_set_data(GTK_OBJECT(dialog), "draw_button", but_sketch);
970 gtk_signal_connect(GTK_OBJECT(but_sketch), "clicked", G_CALLBACK(show_sketch_widget), dialog);
972 gtk_box_pack_start(GTK_BOX(hb), but_sketch, FALSE, TRUE, 0);
973 gtk_box_pack_start(GTK_BOX(vbox), hb, TRUE, FALSE, 0);
975 cb = gtk_check_button_new_with_label(_("Create as child node of current node"));
976 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cb), mainview->newnodedialog_createchild);
977 gtk_container_add(GTK_CONTAINER(vbox), cb);
978 gtk_object_set_data(GTK_OBJECT(dialog), "cb", cb);
980 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), vbox);
982 gtk_widget_grab_focus(entry);
984 gtk_widget_show_all(dialog);
986 /* Hide the sketch widget at first */
987 gtk_widget_hide(al);
988 gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
991 void add_new_node(nodeData * node, MainView * mainview, gboolean ischild)
993 GtkTreeIter parentiter, newiter;
994 GtkTreeModel *model;
995 void *ptr = NULL;
997 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
999 if (gtk_tree_selection_get_selected(selection, &model, &parentiter))
1000 ptr = &parentiter;
1002 GtkTreePath *path = NULL;
1004 unsigned int parentnodeid = 0;
1006 if (ptr != NULL)
1008 path = gtk_tree_model_get_path(model, &parentiter);
1010 if (ischild == FALSE)
1012 gtk_tree_path_up(path);
1014 if (gtk_tree_path_get_depth(path) == 0)
1016 /* Selected node is a root node */
1017 ptr = NULL; /* New node can not have a Parent node */
1018 gtk_tree_path_down(path); /*restore path so expand() works */
1020 else if (gtk_tree_path_get_depth(path) > 0)
1022 /* Selected node is a child node */
1023 if (gtk_tree_model_get_iter(model, &parentiter, path))
1024 ptr = &parentiter;
1029 if (ptr != NULL)
1031 nodeData *nd;
1033 gtk_tree_model_get(model, ptr, NODE_DATA, &nd, -1);
1034 if (nd)
1035 parentnodeid = nd->sql3id;
1038 node->sql3id = 0;
1041 sqlite3_stmt *stmt = NULL;
1042 const char *dum;
1043 char tq[512];
1046 * FIXME: ord
1048 snprintf(tq, sizeof(tq), "INSERT INTO %s (parent, bodytype, name, nameblob, ord) VALUES (%d, %d, ?, ?, 0);", datatable_tmpname, parentnodeid, node->typ);
1049 int rc = sqlite3_prepare(mainview->db, tq, strlen(tq), &stmt, &dum);
1051 if (rc)
1053 fprintf(stderr, "Error inserting(1): %s\n", sqlite3_errmsg(mainview->db));
1054 break;
1056 if (node->name != NULL)
1057 sqlite3_bind_text(stmt, 1, node->name, strlen(node->name), SQLITE_TRANSIENT);
1058 else
1059 sqlite3_bind_text(stmt, 1, NULL, 0, SQLITE_TRANSIENT);
1061 if (node->namepix != NULL)
1063 gchar *namepixdata = NULL;
1064 gsize datalen = 0;
1066 GError *err = NULL;
1068 if (gdk_pixbuf_save_to_buffer(node->namepix, &namepixdata, &datalen, "png", &err, NULL) == FALSE)
1070 namepixdata = NULL;
1071 datalen = 0;
1072 fprintf(stderr, "Error saving name! %s\n", err->message);
1073 g_error_free(err);
1075 sqlite3_bind_blob(stmt, 2, namepixdata, datalen, SQLITE_TRANSIENT);
1077 else
1078 sqlite3_bind_blob(stmt, 2, NULL, 0, SQLITE_TRANSIENT);
1080 rc = SQLITE_BUSY;
1081 while(rc == SQLITE_BUSY)
1083 rc = sqlite3_step(stmt);
1084 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE || rc == SQLITE_DONE)
1085 break;
1087 sqlite3_finalize(stmt);
1088 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE)
1090 fprintf(stderr, "Error inserting(2): %s\n", sqlite3_errmsg(mainview->db));
1091 break;
1093 node->sql3id = sqlite3_last_insert_rowid(mainview->db);
1095 while(FALSE);
1097 if (node->sql3id == 0)
1099 if (node->name)
1100 g_free(node->name);
1101 if (node->namepix)
1102 g_object_unref(node->namepix);
1103 g_free(node);
1104 if (path)
1105 gtk_tree_path_free(path);
1106 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, "Error creating node");
1107 return;
1110 gtk_tree_store_append(GTK_TREE_STORE(model), &newiter, ptr);
1112 gtk_tree_store_set(GTK_TREE_STORE(model), &newiter, NODE_NAME, node->name, NODE_PIXBUF, node->namepix, NODE_DATA, node, -1);
1114 if (path)
1116 mainview->loading=TRUE; /*only when we have a valid parent*/
1117 gtk_tree_view_expand_row(GTK_TREE_VIEW(mainview->treeview), path, FALSE);
1118 gtk_tree_path_free(path);
1121 gtk_tree_selection_select_iter(selection, &newiter);
1123 mainview->loading=FALSE;
1126 void callback_new_node_real(GtkAction * action, gpointer data)
1128 MainView *mainview;
1130 GtkWidget *dialog = data;
1131 GtkWidget *entry = gtk_object_get_user_data(GTK_OBJECT(dialog));
1133 mainview = gtk_object_get_data(GTK_OBJECT(dialog), "m");
1134 SketchWidget *s = gtk_object_get_data(GTK_OBJECT(dialog), "sk");
1135 GtkWidget *cb = gtk_object_get_data(GTK_OBJECT(dialog), "cb");
1136 newNodeToggleButtons *nntb = gtk_object_get_data(GTK_OBJECT(dialog), "nntb");
1138 nodeType typ = NODE_TEXT;
1139 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(nntb->rbs))) {
1140 typ = NODE_SKETCH;
1141 } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(nntb->rbc))) {
1142 typ = NODE_CHECKLIST;
1144 g_free(nntb);
1146 gchar *txt = NULL;
1147 GdkPixbuf *pixbuf = NULL;
1149 if (GTK_WIDGET_VISIBLE(entry))
1151 txt = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
1152 if (strcmp(txt, "") == 0)
1154 g_free(txt);
1155 return;
1158 else
1160 GtkWidget *sdr = sketchwidget_get_drawingarea(s);
1162 GdkPixmap *spix = sketchwidget_get_Pixmap(s);
1164 pixbuf = gdk_pixbuf_get_from_drawable(NULL, GDK_DRAWABLE(spix), NULL, 0, 0, 0, 0, sdr->allocation.width, sdr->allocation.height);
1165 g_object_unref(spix);
1166 double w, h;
1167 GdkPixbuf *pixbuf2 = sketchwidget_trim_image(pixbuf, SKETCHNODE_X, SKETCHNODE_Y, &w,
1168 &h, TRUE);
1169 if (pixbuf2==NULL) return;
1171 GdkPixbuf *pixbuf3 = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, SKETCHNODE_RX,
1172 SKETCHNODE_RY);
1174 gdk_pixbuf_fill(pixbuf3, 0xffffffff);
1176 if (w <= SKETCHNODE_RX && h <= SKETCHNODE_RY)
1178 gdk_pixbuf_copy_area(pixbuf2, 0, 0, w, h, pixbuf3, 0, (SKETCHNODE_RY - h) / 2);
1180 else
1182 double neww, newh;
1184 if (w > h)
1186 neww = SKETCHNODE_RX;
1187 newh = (h / w) * SKETCHNODE_RX;
1189 else
1191 newh = SKETCHNODE_RY;
1192 neww = (w / h) * SKETCHNODE_RY;
1194 if (newh > SKETCHNODE_RY)
1195 newh = SKETCHNODE_RY;
1197 GdkPixbuf *tmpbuf = gdk_pixbuf_scale_simple(pixbuf2, neww, newh,
1198 GDK_INTERP_BILINEAR);
1200 gdk_pixbuf_copy_area(tmpbuf, 0, 0, neww, newh, pixbuf3, 0, (SKETCHNODE_RY - newh) / 2);
1202 gdk_pixbuf_unref(tmpbuf);
1205 pixbuf = pixbuf3;
1206 gdk_pixbuf_unref(pixbuf2);
1209 nodeData *node;
1211 node = g_malloc(sizeof(nodeData));
1212 node->typ = typ;
1213 node->name = NULL;
1214 node->namepix = NULL;
1216 if (GTK_WIDGET_VISIBLE(entry))
1218 node->name = txt;
1220 else
1222 node->namepix = pixbuf;
1225 node->lastMod = 0;
1226 node->flags = 0;
1227 node->sql3id = 0;
1229 mainview->newnodedialog_createchild = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cb));
1230 add_new_node(node, mainview, mainview->newnodedialog_createchild);
1232 sketchwidget_destroy(s);
1233 gtk_widget_destroy(dialog);
1234 mainview->file_edited = TRUE;
1238 * delete node
1240 void callback_file_delete_node(GtkAction * action, gpointer data)
1242 MainView *mainview = (MainView *) data;
1243 g_assert(mainview != NULL && mainview->data != NULL);
1245 if (getSelectedNode(mainview) == NULL)
1247 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Select a node first"));
1248 return;
1251 GtkWidget *dialog, *label, *but_ok, *but_cancel;
1253 dialog = gtk_dialog_new();
1255 label = gtk_label_new(_("Delete current memo?"));
1257 but_ok = gtk_button_new_with_label(_("Yes, Delete"));
1258 but_cancel = gtk_button_new_with_label(_("Cancel"));
1260 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area), but_ok);
1261 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area), but_cancel);
1263 gtk_object_set_user_data(GTK_OBJECT(dialog), mainview);
1265 gtk_signal_connect_object(GTK_OBJECT(but_cancel), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), dialog);
1266 g_signal_connect(G_OBJECT(but_ok), "clicked", G_CALLBACK(callback_delete_node_real), dialog);
1268 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
1270 gtk_widget_show_all(dialog);
1271 gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
1275 * Callback for Rename Menuitem
1277 void callback_file_rename_node(GtkAction * action, gpointer data)
1279 MainView *mainview = (MainView *) data;
1280 g_assert(mainview != NULL && mainview->data != NULL);
1282 /* Get the selected node */
1283 nodeData *sel_node = getSelectedNode(mainview);
1284 if (!sel_node)
1286 /* Do nothing, if no node has been selected */
1287 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Select a node first"));
1288 return;
1291 if (sel_node->namepix != NULL)
1293 /* the memo has a graphical label, cannot edit! */
1294 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Cannot rename memos with sketch name"));
1295 return;
1298 /* Create dialog box */
1299 GtkWidget *dialog, *label, *entry, *but_ok, *but_cancel;
1301 dialog = gtk_dialog_new();
1303 label = gtk_label_new(_("New Memo name:"));
1305 entry = gtk_entry_new_with_max_length(64);
1306 gtk_entry_set_text (GTK_ENTRY(entry), sel_node->name);
1307 gtk_editable_select_region (GTK_EDITABLE(entry), 0, -1);
1309 but_ok = gtk_button_new_with_label(_("OK"));
1310 but_cancel = gtk_button_new_with_label(_("Cancel"));
1312 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area), but_ok);
1313 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area), but_cancel);
1315 g_object_set_data(G_OBJECT(dialog), "m", mainview);
1316 g_object_set_data(G_OBJECT(dialog), "e", entry);
1318 gtk_signal_connect_object(GTK_OBJECT(but_cancel), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), dialog);
1319 g_signal_connect(G_OBJECT(but_ok), "clicked", G_CALLBACK(callback_rename_node_real), dialog);
1321 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
1322 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), entry);
1324 gtk_box_set_spacing (GTK_DIALOG(dialog)->vbox, 10);
1326 gtk_widget_show_all(dialog);
1327 gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
1331 * Callback for Rename Dialog
1333 void callback_rename_node_real (GtkAction *action, gpointer data)
1335 MainView *mainview;
1336 GtkWidget *entry;
1337 GtkTreeIter iter;
1338 GtkTreeModel *model;
1339 nodeData *nd = NULL;
1341 GtkWidget *dialog = data;
1343 mainview = g_object_get_data (G_OBJECT(dialog), "m");
1344 entry = g_object_get_data (G_OBJECT(dialog), "e");
1346 /* Checking whether the entry is empty */
1347 gchar *new_node_name = gtk_entry_get_text (GTK_ENTRY(entry));
1348 if (strcmp (new_node_name, "") == 0) {
1349 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Name can not be empty"));
1350 return;
1353 /* Get the selected node */
1354 GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(mainview->treeview));
1356 if (!gtk_tree_selection_get_selected (selection, &model, &iter))
1357 return;
1359 gtk_tree_model_get (model, &iter, NODE_DATA, &nd, -1);
1360 if (!nd)
1361 return;
1363 /* If we reach here, all checkings are done */
1364 /* Update the database */
1365 char tq[512];
1366 unsigned int sql3id = nd->sql3id;
1367 sqlite3_stmt *stmt = NULL;
1368 const char* dum;
1369 gboolean db_query_result = FALSE;
1371 /* Update the noteData */
1372 if (nd->name) {
1373 g_free(nd->name);
1375 nd->name = g_strdup(new_node_name);
1377 do {
1378 snprintf (tq, sizeof(tq), "UPDATE %s SET name=\"%s\" WHERE nodeid=%d",
1379 datatable_tmpname, new_node_name, sql3id);
1380 int rc = sqlite3_prepare (mainview->db, tq, strlen(tq), &stmt, &dum);
1382 if (rc) {
1383 fprintf (stderr, "Error preparing db update query: %s\n", sqlite3_errmsg(mainview->db));
1384 break;
1386 rc = SQLITE_BUSY;
1387 while (rc == SQLITE_BUSY) {
1388 rc = sqlite3_step (stmt);
1389 if (rc == SQLITE_DONE) {
1390 db_query_result = TRUE;
1391 break;
1393 else if(rc == SQLITE_ERROR || rc== SQLITE_MISUSE) {
1394 fprintf (stderr, "Error updating node: %s\n", sqlite3_errmsg(mainview->db));
1395 break;
1397 sqlite3_finalize(stmt);
1399 } while (FALSE);
1401 /* Update the tree */
1402 if (db_query_result)
1403 gtk_tree_store_set (GTK_TREE_STORE(model), &iter, NODE_NAME, new_node_name, -1);
1405 mainview->file_edited = TRUE;
1407 /* Destroy the dialog */
1408 gtk_widget_destroy (dialog);
1411 void callback_file_expand_collapse_node(GtkAction * action, gpointer data)
1413 MainView *mainview = (MainView *) data;
1414 g_assert(mainview != NULL && mainview->data != NULL);
1416 GtkTreeIter iter;
1417 GtkTreeModel *model;
1419 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
1421 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
1423 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Select a node first"));
1424 return;
1427 GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
1428 if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(mainview->treeview), path)==FALSE)
1430 gtk_tree_view_expand_row(GTK_TREE_VIEW(mainview->treeview), path, FALSE);
1432 else
1434 gtk_tree_view_collapse_row(GTK_TREE_VIEW(mainview->treeview), path);
1437 gtk_tree_path_free(path);
1440 void callback_file_export_node(GtkAction * action, gpointer data)
1442 MainView *mainview = (MainView *) data;
1443 g_assert(mainview != NULL && mainview->data != NULL);
1445 nodeData *nd=getSelectedNode(mainview);
1446 if (nd == NULL)
1448 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Select a memo first"));
1449 return;
1452 gchar *nodename=nd->name;
1453 if (nodename==NULL) nodename=_("saved memo");
1455 if (nd->typ == NODE_TEXT)
1458 GtkTextIter begin, end;
1459 gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER(mainview->buffer), &begin, &end);
1460 gchar *text = gtk_text_buffer_get_slice(GTK_TEXT_BUFFER(mainview->buffer), &begin, &end, TRUE);
1462 GString *gstr=g_string_sized_new(4096);
1463 wp_text_buffer_save_document(mainview->buffer, (WPDocumentSaveCallback)(wp_savecallback), gstr);
1464 gint textlen=gstr->len;
1465 gchar *text=g_string_free(gstr, FALSE);
1467 if (text==NULL || !strcmp(text, ""))
1469 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Memo is empty"));
1471 else
1473 gchar *fn = interface_file_chooser(mainview, GTK_FILE_CHOOSER_ACTION_SAVE, nodename, "html");
1474 if (fn!=NULL)
1476 GnomeVFSResult vfs_result;
1477 GnomeVFSHandle *handle = NULL;
1478 GnomeVFSFileSize out_bytes;
1479 vfs_result = gnome_vfs_create(&handle, fn, GNOME_VFS_OPEN_WRITE, 0, 0600);
1480 if ( vfs_result != GNOME_VFS_OK ) {
1481 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Export failed"));
1483 else
1485 gnome_vfs_write(handle, text, textlen, &out_bytes);
1486 gnome_vfs_close(handle);
1487 if (out_bytes==strlen(text)) hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Exported"));
1488 else hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Export incomplete"));
1490 g_free(fn);
1493 g_free(text);
1495 else if (nd->typ == NODE_SKETCH)
1497 GdkPixmap *skpix = sketchwidget_get_Pixmap(mainview->sk);
1498 GtkWidget *skdr = sketchwidget_get_drawingarea(mainview->sk);
1499 GdkPixbuf *pixbuf = gdk_pixbuf_get_from_drawable(NULL, GDK_DRAWABLE(skpix), NULL, 0, 0, 0, 0, skdr->allocation.width, skdr->allocation.height);
1500 if (pixbuf==NULL)
1502 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Memo is empty"));
1504 else
1506 gchar *fn = interface_file_chooser(mainview, GTK_FILE_CHOOSER_ACTION_SAVE, nodename, "png");
1507 if (fn!=NULL)
1509 if (gdk_pixbuf_save(pixbuf, fn, "png", NULL, NULL)==FALSE)
1511 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Export failed"));
1513 else
1515 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Exported"));
1517 g_free(fn);
1520 g_object_unref(skpix);
1522 else if (nd->typ == NODE_CHECKLIST)
1524 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Unimplemented"));
1529 * callback from menu item
1530 * move selected node down (switch node with next sibling), don't change level of node
1532 void callback_move_down_node(GtkAction * action, gpointer data)
1534 GtkTreeIter iter;
1535 GtkTreeModel *model;
1537 MainView *mainview = (MainView *) data;
1538 g_assert(mainview != NULL && mainview->data != NULL);
1540 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
1541 gtk_tree_selection_get_selected(selection, &model, &iter);
1543 GtkTreeIter old_iter = iter;/*save pointer to old iter, we will need it during swap nodes*/
1545 if (gtk_tree_model_iter_next(model,&iter)==FALSE)/*get next node*/
1546 return;
1548 GtkTreeStore *treeStore = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->treeview)));
1549 gtk_tree_store_swap(treeStore,&iter,&old_iter);
1551 mainview->file_edited = TRUE;/*we have made changes , if required show "save changes?" dialog in future*/
1555 * callback from menu item
1556 * move selected node down (switch node with prev sibling), don't change level of node
1558 void callback_move_up_node(GtkAction * action, gpointer data)
1560 GtkTreeIter iter;
1561 GtkTreeModel *model;
1563 MainView *mainview = (MainView *) data;
1564 g_assert(mainview != NULL && mainview->data != NULL);
1566 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
1567 gtk_tree_selection_get_selected(selection, &model, &iter);
1569 GtkTreeIter old_iter=iter;/*save pointer to old iter, we will need it during swap nodes*/
1571 if (tree_model_iter_prev(model,&iter)==FALSE)/*get previous node*/
1572 return;
1574 GtkTreeStore *treeStore = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->treeview)));
1575 gtk_tree_store_swap(treeStore,&old_iter,&iter);/*do move*/
1577 mainview->file_edited = TRUE;/*we have made changes , if required show "save changes?" dialog in future*/
1581 * callback from menu item
1582 * we change level of actual node with direction to top
1584 void callback_move_to_top_level_node(GtkAction * action, gpointer data)
1586 GtkTreeIter iter,new_parent;
1587 GtkTreeIter *p_new_parent;
1588 GtkTreeIter parent;
1589 GtkTreeModel *model;
1591 MainView *mainview = (MainView *) data;
1592 g_assert(mainview != NULL && mainview->data != NULL);
1594 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
1595 gtk_tree_selection_get_selected(selection, &model, &iter);
1597 /*at first we need actual parent of selected node*/
1598 if (gtk_tree_model_iter_parent(model,&parent,&iter)==FALSE)
1600 /*if parent of selected node is ROOT we can't go higher*/
1601 return;
1603 /*we need also new parent, it's parent of actual parent*/
1604 if (gtk_tree_model_iter_parent(model,&new_parent,&parent)==FALSE)
1606 /*if our new parent is ROOT we got filled new_parent with invalid value,
1607 so we need set NULL value to p_new_parent (root item)*/
1608 p_new_parent=NULL;
1610 else
1612 p_new_parent=&new_parent;/*we only redirect pointer to treeiter*/
1615 saveCurrentData(mainview);/*we save changes in node befor move*/
1617 /*this move function provide move item with all his children, be careful iter value will change!*/
1618 if (move_node(mainview,p_new_parent,&iter,&parent)==TRUE){
1620 gint id_parent = get_node_id_on_tmp_db(model,p_new_parent);
1621 gint id_node = get_node_id_on_tmp_db(model,&iter);
1622 /*we need also update parent id of moved item*/
1623 char tq[512];
1624 snprintf (tq, sizeof(tq), "UPDATE %s SET parent=%d WHERE nodeid=%d",datatable_tmpname,id_parent ,id_node);
1625 exec_command_on_db(mainview,tq);
1627 /*select new created iter*/
1628 gtk_tree_selection_select_iter(selection,&iter);
1630 mainview->file_edited = TRUE;/*we have made changes , if required show "save changes?" dialog in future*/
1635 * callback from menu item
1636 * we change level of actual node with direction to bottom
1637 * previous node will be parent of our actual node
1639 void callback_move_to_bottom_level_node(GtkAction * action, gpointer data)
1641 GtkTreeIter iter;
1642 GtkTreeModel *model;
1644 MainView *mainview = (MainView *) data;
1645 g_assert(mainview != NULL && mainview->data != NULL);
1647 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
1648 gtk_tree_selection_get_selected(selection, &model, &iter);
1650 GtkTreeIter move_iter=iter;/*save pointer to old iter*/
1652 /*we try to get previous node*/
1653 if (tree_model_iter_prev(model,&iter)==FALSE)
1654 return;/*if previous node on the same level doesn't exist we will exit*/
1656 saveCurrentData(mainview);/*we save changes in node befor move*/
1658 /*this move function provide move item with all his children, be careful move_iter value will change!*/
1659 if (move_node(mainview,&iter,&move_iter,NULL)==TRUE)
1661 gint id_parent = get_node_id_on_tmp_db(model,&iter);
1662 gint id_node = get_node_id_on_tmp_db(model,&move_iter);
1664 /*we need also update parent id of moved item*/
1665 char tq[512];
1666 snprintf (tq, sizeof(tq), "UPDATE %s SET parent=%d WHERE nodeid=%d",datatable_tmpname,id_parent ,id_node);
1667 exec_command_on_db(mainview,tq);
1669 GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
1670 gtk_tree_view_expand_row(GTK_TREE_VIEW(mainview->treeview), path, FALSE);/*expand parent node*/
1671 gtk_tree_path_free(path);
1673 /*select new created iter*/
1674 gtk_tree_selection_select_iter(selection,&move_iter);
1676 mainview->file_edited = TRUE;/*we have made changes , if required show "save changes?" dialog in future*/
1681 * move item_to_move to new_parent with his children, this function is designed for change level of node
1682 * we copy item_to_move with his children to new position (after item_befor if is not NULL) and then we
1683 * destroy old node with his children, so ! item_to_move is set with new iter, be careful on this!
1685 gboolean move_node(MainView *mainview,GtkTreeIter *new_parent,GtkTreeIter *item_to_move,GtkTreeIter *item_befor)
1687 GtkTreeModel *model;
1689 model=gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->treeview));
1690 GtkTreeStore *treeStore = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->treeview)));
1692 nodeData *node;
1693 gtk_tree_model_get(model, item_to_move, NODE_DATA, &node, -1);/*get data from actual iter*/
1694 if (node)
1696 GtkTreeIter new_iter;/*create new iter*/
1697 gtk_tree_store_append(treeStore,&new_iter,new_parent);/*append new iter to new parent*/
1699 if (item_befor!=NULL)
1700 gtk_tree_store_move_after(treeStore,&new_iter,item_befor);/*sometimes we need set position*/
1702 gtk_tree_store_set(treeStore, &new_iter, NODE_NAME, node->name,NODE_PIXBUF, node->namepix, NODE_DATA, node, -1);/*set data from old iter*/
1704 GtkTreeIter child;
1705 while (gtk_tree_model_iter_children(model, &child, item_to_move)==TRUE)/*move all childrens while some exits*/
1707 if (move_node(mainview,&new_iter,&child,NULL)==FALSE)/*use recursion on children*/
1708 return FALSE;
1711 gtk_tree_store_set(treeStore, item_to_move, NODE_DATA, NULL, -1);
1712 gtk_tree_store_remove(treeStore, item_to_move);/*remove node, data need't remove, they are stored in new node*/
1714 /*we need return new value of moved item, so we need assign new_iter to item_to_move*/
1715 /*this code is ugly : new_iter to path and back to item_to_move*/
1716 GtkTreePath *path=gtk_tree_model_get_path(model,&new_iter);
1717 gtk_tree_model_get_iter(model,item_to_move,path);
1718 gtk_tree_path_free(path);
1720 else
1722 fprintf(stderr,"Get data node failed!\n");
1723 return FALSE;
1726 return TRUE;
1730 * simple execute of sql command which is stored in sql_string[]
1732 gboolean exec_command_on_db(MainView *mainview,char sql_string[])
1734 sqlite3_stmt *stmt = NULL;
1735 const char* dum;
1736 gboolean db_query_result = FALSE;
1738 int rc = sqlite3_prepare (mainview->db, sql_string, strlen(sql_string), &stmt, &dum);
1740 if (rc) {
1741 fprintf (stderr, "Error preparing db update query: %s\n", sqlite3_errmsg(mainview->db));
1742 return FALSE;
1745 rc = SQLITE_BUSY;
1746 while (rc == SQLITE_BUSY) {
1747 rc = sqlite3_step (stmt);
1748 if (rc == SQLITE_DONE) {
1749 db_query_result = TRUE;
1750 break;
1752 else if(rc == SQLITE_ERROR || rc== SQLITE_MISUSE) {
1753 fprintf (stderr, "Error updating node: %s\n", sqlite3_errmsg(mainview->db));
1754 break;
1756 sqlite3_finalize(stmt);
1758 return TRUE;
1762 * 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)
1764 gboolean foreach_func_update_ord (GtkTreeModel *model,GtkTreePath *path,GtkTreeIter *iter, MainView *mainview)
1766 nodeData *node;
1767 gtk_tree_model_get(model, iter, NODE_DATA, &node, -1);
1768 /*we need index of node on actual level*/
1769 gint index=get_branch_node_index(path);
1771 /*prepare to execute update command,and exec it*/
1772 char sql_command[512];
1773 snprintf (sql_command, sizeof(sql_command), "UPDATE %s SET ord=\"%d\" WHERE nodeid=%d",datatable_tmpname, index, node->sql3id);
1774 exec_command_on_db(mainview,sql_command);
1776 /*we don't want break gtk_tree_model_foreach function,until we call this func on each node - so we return always FALSE*/
1777 return FALSE;
1781 * return id number of iter (id number which is used to identify in sql database of nodes)
1783 int get_node_id_on_tmp_db(GtkTreeModel *model,GtkTreeIter *iter)
1785 if (iter==NULL)
1786 return 0;/*we got ROOT parent here*/
1788 nodeData *node;
1789 gtk_tree_model_get(model, iter, NODE_DATA, &node, -1);
1790 return node->sql3id;
1794 * get index of node in current branch
1796 gint get_branch_node_index(GtkTreePath *path)
1798 int depth=gtk_tree_path_get_depth(path);
1799 gint *indicies = gtk_tree_path_get_indices(path);
1801 return indicies[depth-1];
1805 * similiar with gtk_tree_model_iter_next (), but opposite
1807 gboolean tree_model_iter_prev(GtkTreeModel *tree_model,GtkTreeIter *iter)
1809 GtkTreePath *path = gtk_tree_model_get_path(tree_model, iter);
1811 if (path==NULL){
1812 fprintf(stderr,"Error: path is null\n");
1813 return FALSE;
1816 if (gtk_tree_path_prev(path)==FALSE)
1817 return FALSE;
1819 gtk_tree_model_get_iter(tree_model, iter,path);
1821 return TRUE;
1824 gboolean ref2iter(GtkTreeModel * model, GtkTreeRowReference * ref, GtkTreeIter * iter)
1826 gboolean res = FALSE;
1827 GtkTreePath *path = gtk_tree_row_reference_get_path(ref);
1829 if (gtk_tree_model_get_iter(model, iter, path))
1831 res = TRUE;
1833 gtk_tree_path_free(path);
1834 return (res);
1837 GtkTreeRowReference *iter2ref(GtkTreeModel * model, GtkTreeIter * iter)
1839 GtkTreeRowReference *ref;
1841 GtkTreePath *path = gtk_tree_model_get_path(model, iter);
1843 ref = gtk_tree_row_reference_new(model, path);
1844 gtk_tree_path_free(path);
1845 return (ref);
1848 void move_nodes_up(GtkTreeModel * model, GtkTreeRowReference * topnode, GtkTreeRowReference * newtop)
1850 GtkTreeIter topiter;
1852 fprintf(stderr, "here2\n");
1854 if (ref2iter(model, topnode, &topiter) == FALSE)
1855 return;
1857 fprintf(stderr, "here3\n");
1859 GtkTreeIter child;
1861 if (gtk_tree_model_iter_children(model, &child, &topiter))
1863 fprintf(stderr, "here4\n");
1864 GtkTreeRowReference *ref;
1865 GList *rr_list = NULL, *node;
1869 ref = iter2ref(model, &child);
1870 rr_list = g_list_append(rr_list, ref);
1872 while(gtk_tree_model_iter_next(model, &child));
1875 * got a reflist for all children
1878 fprintf(stderr, "here5\n");
1879 for(node = rr_list; node; node = node->next)
1881 ref = (GtkTreeRowReference *) (node->data);
1882 if (ref2iter(model, ref, &child))
1884 GtkTreeIter newtopiter, newiter;
1885 GtkTreeIter *newtopiterptr;
1887 if (ref2iter(model, newtop, &newtopiter))
1888 newtopiterptr = &newtopiter;
1889 else
1890 newtopiterptr = NULL;
1892 nodeData *node;
1894 gtk_tree_model_get(model, &child, NODE_DATA, &node, -1);
1896 gtk_tree_store_append(GTK_TREE_STORE(model), &newiter, newtopiterptr);
1897 gtk_tree_store_set(GTK_TREE_STORE(model), &newiter, NODE_NAME, node->name, NODE_PIXBUF, node->namepix, NODE_DATA, node, -1);
1899 GtkTreeRowReference *newref = iter2ref(model, &newiter);
1901 move_nodes_up(model, ref, newref);
1902 gtk_tree_row_reference_free(newref);
1904 gtk_tree_store_remove(GTK_TREE_STORE(model), &child);
1906 gtk_tree_row_reference_free(ref);
1908 fprintf(stderr, "here6\n");
1910 g_list_free(rr_list);
1913 fprintf(stderr, "here7\n");
1917 void callback_delete_node_real(GtkAction * action, gpointer data)
1919 MainView *mainview;
1921 GtkWidget *dialog = data;
1923 mainview = gtk_object_get_user_data(GTK_OBJECT(dialog));
1925 GtkTreeIter iter;
1926 GtkTreeModel *model;
1928 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
1930 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
1931 return;
1933 nodeData *nd;
1935 gtk_tree_model_get(model, &iter, NODE_DATA, &nd, -1);
1936 if (!nd)
1937 return;
1939 mainview->file_edited = TRUE;
1941 unsigned int sql3id = nd->sql3id;
1943 if (nd->name)
1944 g_free(nd->name);
1947 * g_free(nd->data);
1948 * if (nd->pix) g_object_unref(nd->pix);
1950 g_free(nd);
1952 fprintf(stderr, "here1\n");
1953 GtkTreeRowReference *upref = NULL, *ref = NULL;
1955 GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
1957 ref = gtk_tree_row_reference_new(model, path);
1958 if (gtk_tree_path_up(path))
1959 upref = gtk_tree_row_reference_new(model, path);
1960 gtk_tree_path_free(path);
1962 g_object_ref(model);
1963 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->treeview), NULL);
1965 fprintf(stderr, "here! 1\n");
1966 move_nodes_up(model, ref, upref);
1968 fprintf(stderr, "here! 2\n");
1969 if (ref2iter(model, ref, &iter))
1971 char tq[512];
1973 snprintf(tq, sizeof(tq), "SELECT parent FROM %s WHERE nodeid=%d", datatable_tmpname, sql3id);
1974 sqlite3_stmt *stmt = NULL;
1975 const char *dum;
1976 int rc = sqlite3_prepare(mainview->db, tq, strlen(tq), &stmt, &dum);
1977 unsigned int sql3parentid = 0;
1979 if (rc)
1981 fprintf(stderr, "Error %s\n", sqlite3_errmsg(mainview->db));
1983 else
1985 rc = SQLITE_BUSY;
1986 while(rc == SQLITE_BUSY || rc == SQLITE_ROW)
1988 rc = sqlite3_step(stmt);
1989 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE || rc == SQLITE_DONE)
1990 break;
1991 else if (rc == SQLITE_ROW)
1993 sql3parentid = sqlite3_column_int(stmt, 0);
1994 break;
1997 sqlite3_finalize(stmt);
1999 snprintf(tq, sizeof(tq), "UPDATE %s SET parent=%d WHERE parent=%d;", datatable_tmpname, sql3parentid, sql3id);
2000 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
2001 fprintf(stderr, "ERROR moving nodes up!\n");
2002 else
2004 snprintf(tq, sizeof(tq), "DELETE FROM %s WHERE nodeid=%d;", datatable_tmpname, sql3id);
2005 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
2006 fprintf(stderr, "ERROR deleting node!\n");
2008 /* Delete all checklist items that do not have
2009 * a node anymore (= orphaned checklist items) */
2010 snprintf(tq, sizeof(tq), "DELETE FROM %s WHERE nodeid NOT IN (SELECT nodeid FROM %s);", checklisttable_tmpname, datatable_tmpname);
2011 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
2012 fprintf(stderr, "ERROR deleting orphaned checklist items!\n");
2015 gtk_tree_store_remove(GTK_TREE_STORE(model), &iter);
2018 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->treeview), model);
2020 if (gtk_tree_model_get_iter_first(model, &iter)) {
2021 /* Select the first item, so the view is updated */
2022 gtk_tree_selection_select_iter(selection, &iter);
2023 } else {
2024 /* TODO: Handle case when the last memo is deleted */
2027 g_object_unref(model);
2029 fprintf(stderr, "here! 3\n");
2030 gtk_tree_row_reference_free(ref);
2031 gtk_tree_row_reference_free(upref);
2033 gtk_tree_view_expand_all(GTK_TREE_VIEW(mainview->treeview));
2035 fprintf(stderr, "here10\n");
2036 gtk_widget_destroy(dialog);
2039 void callback_edit_clear(GtkAction * action, gpointer data)
2041 MainView *mainview = (MainView *) data;
2042 g_assert(mainview != NULL && mainview->data != NULL);
2044 nodeData *nd = getSelectedNode(mainview);
2046 if (nd->typ == NODE_TEXT) gtk_text_buffer_set_text(GTK_TEXT_BUFFER(mainview->buffer), "", 0);
2047 else if (nd->typ == NODE_SKETCH) sketchwidget_clear(mainview->sk);
2048 else if (nd->typ == NODE_CHECKLIST) gtk_list_store_clear(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->listview))));
2052 * cut
2054 void callback_edit_cut(GtkAction * action, gpointer data)
2056 MainView *mainview = (MainView *) data;
2057 g_assert(mainview != NULL && mainview->data != NULL);
2059 nodeData *nd = getSelectedNode(mainview);
2061 if (nd->typ == NODE_TEXT)
2062 gtk_text_buffer_cut_clipboard(GTK_TEXT_BUFFER(mainview->buffer), mainview->clipboard, TRUE);
2063 else if (nd->typ == NODE_SKETCH)
2065 if (sketchwidget_cut(mainview->sk, mainview->clipboard)==FALSE)
2066 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Error cutting"));
2068 else if (nd->typ == NODE_CHECKLIST)
2069 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Unimplemented"));
2074 * copy
2076 void callback_edit_copy(GtkAction * action, gpointer data)
2078 MainView *mainview = (MainView *) data;
2079 g_assert(mainview != NULL && mainview->data != NULL);
2081 nodeData *nd = getSelectedNode(mainview);
2083 if (nd->typ == NODE_TEXT)
2084 gtk_text_buffer_copy_clipboard(GTK_TEXT_BUFFER(mainview->buffer), mainview->clipboard);
2085 else if (nd->typ == NODE_SKETCH)
2087 if (sketchwidget_copy(mainview->sk, mainview->clipboard)==FALSE)
2088 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Error copying"));
2090 else if (nd->typ == NODE_CHECKLIST)
2092 /* Copy all selected entries as multiline text (1 line per entry) */
2093 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->listview));
2094 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->listview));
2096 gint selected_rows = gtk_tree_selection_count_selected_rows(selection);
2097 GList* l = gtk_tree_selection_get_selected_rows(selection, NULL);
2099 GtkTreeIter iter;
2100 gchar *str_data;
2102 gchar **entries = g_malloc0(sizeof(gchar*)*selected_rows+1);
2103 gint entries_idx = 0;
2105 GList* cur = l;
2106 while(cur) {
2107 GtkTreePath *path = cur->data;
2109 if (gtk_tree_model_get_iter(model, &iter, path)) {
2110 gtk_tree_model_get(GTK_LIST_STORE(model), &iter, CHECKNODE_TEXT, &(entries[entries_idx++]), -1);
2112 gtk_tree_path_free(path);
2114 cur = cur->next;
2117 g_list_free(l);
2118 str_data = g_strjoinv("\n", entries);
2119 g_strfreev(entries);
2120 gtk_clipboard_set_text(mainview->clipboard, str_data, -1);
2121 g_free(str_data);
2123 str_data = g_strdup_printf(_("Copied %d entries"), selected_rows);
2124 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, str_data);
2125 g_free(str_data);
2131 * paste
2133 void callback_edit_paste(GtkAction * action, gpointer data)
2135 MainView *mainview = (MainView *) data;
2136 g_assert(mainview != NULL && mainview->data != NULL);
2138 nodeData *nd = getSelectedNode(mainview);
2140 if (nd->typ == NODE_TEXT)
2141 gtk_text_buffer_paste_clipboard(GTK_TEXT_BUFFER(mainview->buffer), mainview->clipboard, NULL, TRUE);
2142 else if (nd->typ == NODE_SKETCH)
2144 if (sketchwidget_paste(mainview->sk, mainview->clipboard)==FALSE)
2145 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Error pasting"));
2147 else if (nd->typ == NODE_CHECKLIST) {
2148 /* Paste string from clipboard as new item */
2149 callback_checklist_paste(mainview);
2152 mainview->file_edited = TRUE;
2155 gint cb_popup(GtkWidget * widget, GdkEvent * event)
2157 GtkMenu *menu;
2158 GdkEventButton *event_button;
2161 * The "widget" is the menu that was supplied when
2162 * * g_signal_connect_swapped() was called.
2164 menu = GTK_MENU(widget);
2165 event_button = (GdkEventButton *) event;
2166 if (event->type == GDK_BUTTON_PRESS && event_button->button == 3)
2168 gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event_button->button, event_button->time);
2169 return TRUE;
2171 return FALSE;
2175 * close
2177 gboolean closefile(MainView * mainview)
2179 saveCurrentData(mainview);
2181 if (mainview->file_edited)
2183 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));
2184 gint answer = gtk_dialog_run(GTK_DIALOG(hn));
2185 gtk_widget_destroy(GTK_WIDGET(hn));
2187 if (answer == CONFRESP_CANCEL)
2188 return (FALSE);
2189 else if (answer == CONFRESP_YES)
2191 if (mainview->file_name == NULL)
2193 mainview->file_name = interface_file_chooser(mainview, GTK_FILE_CHOOSER_ACTION_SAVE, "maemopaddata", "db");
2195 write_buffer_to_file(mainview);
2199 if (mainview->db)
2200 sqlite3_close(mainview->db);
2201 mainview->db = NULL;
2202 return (TRUE);
2205 gboolean callback_file_close(GtkAction * action, gpointer data)
2208 MainView *mainview = (MainView *) data;
2209 g_assert(mainview != NULL && mainview->data != NULL);
2210 if (closefile(mainview) == FALSE)
2211 return(FALSE);
2213 gtk_main_quit();
2214 return(TRUE);
2217 void callback_file_new_node(GtkAction * action, gpointer data)
2219 MainView *mainview = (MainView *) data;
2220 g_assert(mainview != NULL && mainview->data != NULL);
2222 nodeType typ = NODE_SKETCH;
2224 nodeData *nd = getSelectedNode(mainview);
2226 if (nd != NULL)
2227 typ = nd->typ;
2229 new_node_dialog(typ, mainview);
2233 * new
2235 void callback_file_new(GtkAction * action, gpointer data)
2237 MainView *mainview = (MainView *) data;
2238 g_assert(mainview != NULL && mainview->data != NULL);
2240 gchar *filename = NULL;
2242 if (closefile(mainview) == FALSE)
2243 return;
2245 filename = interface_file_chooser(mainview, GTK_FILE_CHOOSER_ACTION_SAVE, "memos", "db");
2246 if (filename == NULL)
2247 return;
2249 new_file(mainview);
2253 setBusy(mainview, 1);
2255 int rc;
2257 rc = sqlite3_open(filename, &mainview->db);
2258 if (rc)
2260 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Error 1"));
2261 fprintf(stderr, "Can't create database %s: %s\n", filename, sqlite3_errmsg(mainview->db));
2262 break;
2265 sqlite3_exec(mainview->db, "PRAGMA synchronous = OFF;", NULL, NULL, NULL);
2267 char tq[512];
2269 snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", misctable_name, misctable);
2270 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
2272 snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", datatable_name, datatable);
2273 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
2275 fprintf(stderr, "ERROR creating data table\n");
2276 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Error 2"));
2277 break;
2280 snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", checklisttable_name, checklisttable);
2281 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
2283 fprintf(stderr, "ERROR creating checklist table\n");
2284 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Error 3"));
2285 break;
2288 if (mainview->db)
2289 sqlite3_close(mainview->db);
2290 mainview->db = NULL;
2292 mainview->file_name = filename;
2293 mainview->file_edited = FALSE;
2294 read_file_to_buffer(mainview);
2296 /*add a starter memo*/
2297 nodeData *node;
2298 node = g_malloc(sizeof(nodeData));
2299 node->typ = NODE_SKETCH;
2300 node->name = _("My first memo");
2301 node->namepix = NULL;
2302 node->lastMod = 0;
2303 node->flags = 0;
2304 node->sql3id = 0;
2305 add_new_node(node, mainview, TRUE);
2306 gtk_paned_set_position(GTK_PANED(mainview->hpaned), 180);
2307 mainview->viewflags = 3;
2308 callback_setview(mainview, 1);
2309 write_buffer_to_file(mainview);
2311 }while(FALSE);
2312 setBusy(mainview, 0);
2315 gboolean reset_ctree(GtkTreeModel * model, GtkTreePath * path, GtkTreeIter * iter, gpointer data)
2317 nodeData *node;
2319 gtk_tree_model_get(model, iter, NODE_DATA, &node, -1);
2320 if (node)
2322 if (node->name)
2323 g_free(node->name);
2324 if (node->namepix)
2325 g_object_unref(node->namepix);
2326 g_free(node);
2328 gtk_tree_store_set(GTK_TREE_STORE(model), iter, NODE_DATA, NULL, -1);
2330 return (FALSE);
2333 void new_file(MainView * mainview)
2335 setBusy(mainview, 1);
2337 * clear buffer, filename and free buffer text
2339 gtk_text_buffer_set_text(GTK_TEXT_BUFFER(mainview->buffer), "", -1);
2340 mainview->file_name = NULL;
2341 mainview->file_edited = FALSE;
2342 mainview->newnodedialog_createchild = TRUE;
2344 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->treeview));
2346 g_object_ref(model);
2347 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->treeview), NULL);
2349 gtk_tree_model_foreach(model, (GtkTreeModelForeachFunc) reset_ctree, (gpointer) mainview);
2352 * crashing bastard
2353 * gtk_tree_store_clear(GTK_TREE_STORE(model));
2355 GtkTreePath *path = gtk_tree_path_new_from_indices(0, -1);
2356 GtkTreeIter iter;
2358 if (gtk_tree_model_get_iter(model, &iter, path))
2362 gtk_tree_store_remove(GTK_TREE_STORE(model), &iter);
2364 while(gtk_tree_store_iter_is_valid(GTK_TREE_STORE(model), &iter));
2366 gtk_tree_path_free(path);
2368 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->treeview), model);
2369 g_object_unref(model);
2371 prepareUIforNodeChange(mainview, NODE_UNKNOWN);
2372 setBusy(mainview, 2);
2376 * open
2378 void callback_file_open(GtkAction * action, gpointer data)
2380 gchar *filename = NULL;
2381 MainView *mainview = (MainView *) data;
2382 g_assert(mainview != NULL && mainview->data != NULL);
2384 if (closefile(mainview) == FALSE)
2385 return;
2388 * open new file
2390 filename = interface_file_chooser(mainview, GTK_FILE_CHOOSER_ACTION_OPEN, NULL, NULL);
2393 * if we got a file name from chooser -> open file
2395 open_file(filename, mainview);
2396 g_free(filename);
2399 gboolean open_file(gchar * filename, MainView * mainview)
2401 gboolean ret=FALSE;
2403 setBusy(mainview, 1);
2405 while(filename != NULL)
2407 struct stat s;
2409 if (stat(filename, &s) == -1) break;
2411 mainview->file_name = g_strdup(filename);
2412 gboolean res = read_file_to_buffer(mainview);
2414 if (res == FALSE)
2416 g_free(mainview->file_name);
2417 mainview->file_name = NULL;
2418 break;
2420 mainview->file_edited = FALSE;
2421 ret=TRUE;
2422 break;
2425 setBusy(mainview, 2);
2426 return(ret);
2429 void callback_about_link(GtkAboutDialog *about, const gchar *link, gpointer data)
2431 MainView *mainview = (MainView *) data;
2432 g_assert(mainview != NULL && mainview->data != NULL);
2433 osso_rpc_run_with_defaults(mainview->data->osso, "osso_browser", OSSO_BROWSER_OPEN_NEW_WINDOW_REQ, NULL,
2434 DBUS_TYPE_STRING, link, DBUS_TYPE_INVALID);
2437 void callback_about(GtkAction * action, gpointer data)
2439 MainView *mainview=(MainView *)data;
2441 const char *authors[] = {
2442 "Kemal Hadimli",
2443 "Thomas Perl",
2444 "Anil Kumar",
2445 "Michal Seben",
2446 "Marko Vertainen",
2447 NULL
2450 gtk_about_dialog_set_url_hook(callback_about_link, mainview, NULL);
2452 gtk_show_about_dialog(GTK_WINDOW(mainview->data->main_view),
2453 "name", "Maemopad+",
2454 "authors", authors,
2455 "copyright", "(c) 2006-2008 Kemal Hadimli\n(c) 2008 Thomas Perl",
2456 "license", "GNU LGPL version 2.1 or later\n\nSee http://www.gnu.org/licenses/lgpl.html",
2457 "version", VERSION,
2458 "website", "http://maemopadplus.garage.maemo.org/",
2459 NULL);
2464 * save
2466 void callback_file_save(GtkAction * action, gpointer data)
2468 gchar *filename = NULL;
2469 MainView *mainview = (MainView *) data;
2470 g_assert(mainview != NULL && mainview->data != NULL);
2473 * check is we had a new file
2475 if (mainview->file_name != NULL)
2477 write_buffer_to_file(mainview);
2479 else
2481 filename = interface_file_chooser(mainview, GTK_FILE_CHOOSER_ACTION_SAVE, "maemopaddata", "db");
2483 * if we got a file name from chooser -> save file
2485 if (filename != NULL)
2487 mainview->file_name = filename;
2488 write_buffer_to_file(mainview);
2489 mainview->file_edited = FALSE;
2494 void callback_shapemenu(GtkAction * action, GtkWidget * wid)
2496 int style = (int)gtk_object_get_user_data(GTK_OBJECT(wid));
2497 MainView *mainview = gtk_object_get_data(GTK_OBJECT(wid), "m");
2499 g_assert(mainview != NULL);
2501 if (style==0) sketchwidget_set_shape(mainview->sk, SKETCHSHAPE_FREEHAND);
2502 else if (style==1) sketchwidget_set_shape(mainview->sk, SKETCHSHAPE_LINE);
2503 else if (style==2) sketchwidget_set_shape(mainview->sk, SKETCHSHAPE_RECT);
2504 else if (style==3) sketchwidget_set_shape(mainview->sk, SKETCHSHAPE_ELLIPSE);
2509 void callback_eraser(GtkAction * action, MainView * mainview)
2511 g_assert(mainview != NULL && mainview->data != NULL);
2513 if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(mainview->eraser_tb)) == TRUE)
2515 GdkColor c2;
2517 c2.red = 65535;
2518 c2.green = 65535;
2519 c2.blue = 65535;
2521 mainview->sk->pressuresensitivity=FALSE;
2523 sketchwidget_set_brushcolor(mainview->sk, c2);
2524 mainview->brushsize_backup = sketchwidget_get_brushsize(mainview->sk);
2525 guint ers=(mainview->brushsize_backup*4)+4;
2526 sk_set_brushsize(mainview, ers);
2527 sketchwidget_set_brushsize(mainview->sk, ers); /*fixme:to override max brush size, not pretty*/
2529 else
2531 GdkColor c2;
2533 hildon_color_button_get_color(HILDON_COLOR_BUTTON(mainview->colorbutton), &c2);
2535 mainview->sk->pressuresensitivity=gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(mainview->tools_pressure));
2537 sketchwidget_set_brushcolor(mainview->sk, c2);
2538 sk_set_brushsize(mainview, mainview->brushsize_backup);
2542 void callback_toggletree(GtkAction * action, MainView * mainview)
2544 g_assert(mainview != NULL && mainview->data != NULL);
2546 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->viewmenuitems[0]), gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(mainview->toggletree_tb)));
2548 if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(mainview->toggletree_tb))==TRUE)
2549 mainview->viewflags |= 1;
2550 else
2551 mainview->viewflags &= ~1;
2553 callback_setview(mainview, 0);
2556 void callback_menu(GtkAction * action, GtkWidget * menu)
2558 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0, GDK_CURRENT_TIME);
2561 void callback_brushsizetb(GtkAction * action, MainView *mainview)
2563 g_assert(mainview != NULL && mainview->data != NULL);
2565 if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(mainview->eraser_tb)) == TRUE)
2567 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->eraser_tb), FALSE);
2569 else
2571 callback_menu(NULL, mainview->brushsizemenu);
2575 void callback_brushsize(GtkAction * action, GtkWidget * wid)
2577 int bsize = (int)gtk_object_get_user_data(GTK_OBJECT(wid));
2578 MainView *mainview = gtk_object_get_data(GTK_OBJECT(wid), "m");
2580 g_assert(mainview != NULL && mainview->data != NULL);
2582 sketchwidget_set_brushsize(mainview->sk, bsize);
2584 GtkWidget *pix = gtk_object_get_data(GTK_OBJECT(wid), "i");
2586 gtk_widget_show(pix);
2587 gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(mainview->brushsize_tb), pix);
2590 void callback_sketchlines(GtkAction * action, GtkWidget * wid)
2592 int style = (int)gtk_object_get_user_data(GTK_OBJECT(wid));
2593 MainView *mainview = gtk_object_get_data(GTK_OBJECT(wid), "m");
2595 g_assert(mainview != NULL);
2597 nodeData *nd = getSelectedNode(mainview);
2598 gboolean doit = FALSE;
2600 if (nd != NULL && nd->typ == NODE_SKETCH)
2602 nd->flags &= ~NODEFLAG_SKETCHLINES;
2603 nd->flags &= ~NODEFLAG_SKETCHGRAPH;
2604 /* sketchwidget_set_edited(mainview->sk, TRUE);*/ /*we call this on openfile, so this messes things up*/
2605 doit = TRUE;
2608 if (style == 0)
2610 sketchwidget_set_backstyle(mainview->sk, SKETCHBACK_NONE);
2612 else if (style == 1)
2614 sketchwidget_set_backstyle(mainview->sk, SKETCHBACK_LINES);
2615 if (doit == TRUE)
2616 nd->flags |= NODEFLAG_SKETCHLINES;
2618 else if (style == 2)
2620 sketchwidget_set_backstyle(mainview->sk, SKETCHBACK_GRAPH);
2621 if (doit == TRUE)
2622 nd->flags |= NODEFLAG_SKETCHGRAPH;
2625 GtkWidget *pix = gtk_object_get_data(GTK_OBJECT(wid), "i");
2627 gtk_widget_show(pix);
2628 gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(mainview->sketchlines_tb), pix);
2631 void callback_color(HildonColorButton * colorButton, MainView * mainview)
2633 g_assert(mainview != NULL && mainview->data != NULL);
2635 nodeData *nd = getSelectedNode(mainview);
2636 if (nd == NULL) return;
2638 GdkColor c2;
2639 hildon_color_button_get_color(colorButton, &c2);
2641 if (nd->typ == NODE_SKETCH)
2643 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->eraser_tb), FALSE);
2644 sketchwidget_set_brushcolor(mainview->sk, c2);
2646 else if (nd->typ == NODE_CHECKLIST)
2648 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->listview));
2649 GList* l=gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->listview)), NULL);
2651 char tmp[10];
2652 snprintf(tmp, sizeof(tmp), "#%02x%02x%02x", c2.red>>8, c2.green>>8, c2.blue>>8);
2654 GList* cur=l;
2655 while(cur)
2657 GtkTreePath *path=cur->data;
2659 GtkTreeIter iter;
2660 if (gtk_tree_model_get_iter(model, &iter, path))
2662 gtk_list_store_set(GTK_LIST_STORE(model), &iter, CHECKNODE_COLOR, tmp, -1);
2664 gtk_tree_path_free(path);
2665 cur=cur->next;
2667 g_list_free(l);
2671 void callback_color_invoke(GtkAction * action, gpointer data)
2673 MainView *mainview = (MainView *) data;
2674 g_assert(mainview != NULL && mainview->data != NULL);
2676 gtk_button_clicked(GTK_BUTTON(mainview->colorbutton));
2681 void callback_pressure(GtkAction * action, MainView *mainview)
2683 g_assert(mainview != NULL && mainview->data != NULL);
2685 nodeData *nd = getSelectedNode(mainview);
2687 if (nd == NULL)
2688 return;
2689 if (nd->typ != NODE_SKETCH)
2690 return;
2692 mainview->sk->pressuresensitivity=gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(mainview->tools_pressure));
2696 void callback_wordwrap(GtkAction * action, MainView *mainview)
2698 g_assert(mainview != NULL && mainview->data != NULL);
2700 nodeData *nd = getSelectedNode(mainview);
2702 if (nd == NULL)
2703 return;
2704 if (nd->typ != NODE_TEXT)
2705 return;
2707 gboolean act=gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(mainview->tools_wordwrap));
2708 if (act==TRUE) nd->flags |= NODEFLAG_WORDWRAP;
2709 else nd->flags &= ~NODEFLAG_WORDWRAP;
2711 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(mainview->textview), (act==TRUE)?GTK_WRAP_WORD:GTK_WRAP_NONE);
2715 void callback_font(GtkAction * action, gpointer data)
2717 MainView *mainview = (MainView *) data;
2718 g_assert(mainview != NULL && mainview->data != NULL);
2720 nodeData *nd = getSelectedNode(mainview);
2722 if (nd == NULL)
2723 return;
2724 if (nd->typ != NODE_TEXT)
2725 return;
2727 HildonFontSelectionDialog *dialog = HILDON_FONT_SELECTION_DIALOG(hildon_font_selection_dialog_new(NULL, NULL));
2729 gboolean gotsel=wp_text_buffer_has_selection(mainview->buffer);
2730 /*gotsel=FALSE;*/
2732 WPTextBufferFormat fmt;
2733 wp_text_buffer_get_attributes(mainview->buffer, &fmt, gotsel);
2735 gint ri=0;
2736 if (fmt.text_position==TEXT_POSITION_SUPERSCRIPT) ri=1;
2737 else if (fmt.text_position==TEXT_POSITION_SUBSCRIPT) ri=-1;
2739 g_object_set(G_OBJECT(dialog),
2740 "family-set", fmt.cs.font,
2741 "family", wp_get_font_name(fmt.font),
2742 "size-set", fmt.cs.font_size,
2743 "size", wp_font_size[fmt.font_size],
2744 "color-set", fmt.cs.color,
2745 "color", &fmt.color,
2746 "bold-set", fmt.cs.bold,
2747 "bold", fmt.bold,
2748 "italic-set", fmt.cs.italic,
2749 "italic", fmt.italic,
2750 "underline-set", fmt.cs.underline,
2751 "underline", fmt.underline,
2752 "strikethrough-set", fmt.cs.strikethrough,
2753 "strikethrough", fmt.strikethrough,
2754 "position-set", fmt.cs.text_position,
2755 "position", ri,
2756 NULL);
2758 gtk_widget_show_all(GTK_WIDGET(dialog));
2759 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
2761 gboolean bold, italic, underline, strikethrough;
2762 gchar *family = NULL;
2763 gint size, position;
2764 GdkColor *color=NULL;
2765 gboolean set_family, set_size, set_bold, set_italic, set_underline, set_strikethrough, set_color, set_position;
2767 g_object_get(G_OBJECT(dialog), "family", &family, "size", &size, "bold", &bold, "italic", &italic,
2768 "underline", &underline, "strikethrough", &strikethrough,
2769 "family-set", &set_family, "size-set", &set_size, "bold-set", &set_bold, "italic-set", &set_italic,
2770 "underline-set", &set_underline, "strikethrough-set", &set_strikethrough,
2771 "color", &color, "color-set", &set_color, "position", &position, "position-set", &set_position,
2772 NULL);
2774 wp_text_buffer_get_attributes(mainview->buffer, &fmt, FALSE);
2775 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;
2777 if (set_family) { fmt.font=wp_get_font_index(family, 1); fmt.cs.font=1; }
2778 if (set_size) { fmt.font_size=wp_get_font_size_index(size, 16); fmt.cs.font_size=1; }
2780 if (set_strikethrough)
2782 fmt.cs.strikethrough=1;
2783 fmt.strikethrough=strikethrough;
2786 if (set_color)
2789 GLIB WARNING ** GLib-GObject - IA__g_object_set_valist: object class `GtkTextTag' has no property named `'
2791 fmt.cs.color=1;
2792 fmt.color.pixel=color->pixel;
2793 fmt.color.red=color->red;
2794 fmt.color.green=color->green;
2795 fmt.color.blue=color->blue;
2798 if (set_position)
2800 if (position==1) ri=TEXT_POSITION_SUPERSCRIPT;
2801 else if (position==-1) ri=TEXT_POSITION_SUBSCRIPT;
2802 else ri=TEXT_POSITION_NORMAL;
2804 fmt.cs.text_position=1;
2805 fmt.text_position=ri;
2808 if (set_bold)
2810 fmt.cs.bold=1;
2811 fmt.bold=bold;
2813 if (set_italic)
2815 fmt.cs.italic=1;
2816 fmt.italic=italic;
2818 if (set_underline)
2820 fmt.cs.underline=1;
2821 fmt.underline=underline;
2824 wp_text_buffer_set_format(mainview->buffer, &fmt);
2827 gtk_widget_destroy(GTK_WIDGET(dialog));
2830 void callback_fontstyle(GtkAction * action, GtkWidget * wid)
2832 MainView *mainview = gtk_object_get_data(GTK_OBJECT(wid), "m");
2833 g_assert(mainview != NULL && mainview->data != NULL);
2835 nodeData *nd = getSelectedNode(mainview);
2837 if (nd == NULL)
2838 return;
2839 if (nd->typ == NODE_TEXT)
2841 gboolean act=gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(wid));
2843 gint style = (gint)gtk_object_get_data(GTK_OBJECT(wid), "s");
2844 wp_text_buffer_set_attribute(mainview->buffer, style, (gpointer)act);
2846 else if (nd->typ == NODE_CHECKLIST)
2848 gboolean act=gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(wid));
2849 gint style = (gint)gtk_object_get_data(GTK_OBJECT(wid), "s");
2850 if (style!=WPT_BOLD && style!=WPT_STRIKE && style!=WPT_LEFT) return;
2852 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->listview));
2853 GList* l=gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->listview)), NULL);
2855 gint styletoset_weight=PANGO_WEIGHT_NORMAL;
2856 gboolean styletoset_strike=FALSE;
2857 gboolean checkit=FALSE;
2859 if (style==WPT_BOLD && act==TRUE) styletoset_weight=PANGO_WEIGHT_BOLD;
2860 else if (style==WPT_STRIKE && act==TRUE) styletoset_strike=TRUE;
2861 else if (style==WPT_LEFT && act==TRUE) checkit=TRUE;
2863 GList* cur=l;
2864 while(cur)
2866 GtkTreePath *path=cur->data;
2868 GtkTreeIter iter;
2869 if (gtk_tree_model_get_iter(model, &iter, path))
2871 if (style==WPT_BOLD) gtk_list_store_set(GTK_LIST_STORE(model), &iter, CHECKNODE_BOLD, styletoset_weight, -1);
2872 else if (style==WPT_STRIKE) gtk_list_store_set(GTK_LIST_STORE(model), &iter, CHECKNODE_STRIKE, styletoset_strike, -1);
2873 else if (style==WPT_LEFT) gtk_list_store_set(GTK_LIST_STORE(model), &iter, CHECKNODE_CHECKED, checkit, -1);
2875 gtk_tree_path_free(path);
2876 cur=cur->next;
2879 g_list_free(l);
2880 gtk_object_set_data(GTK_OBJECT(mainview->listview), "edited", TRUE);
2885 void callback_textbuffer_move(WPTextBuffer *textbuffer, MainView *mainview)
2887 g_assert(mainview != NULL && mainview->data != NULL);
2890 gboolean gotsel=wp_text_buffer_has_selection(mainview->buffer);
2892 _toggle_tool_button_set_inconsistent(GTK_TOGGLE_TOOL_BUTTON(mainview->bold_tb), gotsel);
2893 _toggle_tool_button_set_inconsistent(GTK_TOGGLE_TOOL_BUTTON(mainview->italic_tb), gotsel);
2894 _toggle_tool_button_set_inconsistent(GTK_TOGGLE_TOOL_BUTTON(mainview->underline_tb), gotsel);
2895 _toggle_tool_button_set_inconsistent(GTK_TOGGLE_TOOL_BUTTON(mainview->bullet_tb), gotsel);
2897 WPTextBufferFormat fmt;
2898 wp_text_buffer_get_attributes(mainview->buffer, &fmt, FALSE/*gotsel*/);
2900 g_signal_handlers_block_by_func(mainview->bold_tb, callback_fontstyle, mainview->bold_tb);
2901 g_signal_handlers_block_by_func(mainview->italic_tb, callback_fontstyle, mainview->italic_tb);
2902 g_signal_handlers_block_by_func(mainview->underline_tb, callback_fontstyle, mainview->underline_tb);
2903 g_signal_handlers_block_by_func(mainview->bullet_tb, callback_fontstyle, mainview->bullet_tb);
2905 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->bold_tb), fmt.bold);
2906 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->italic_tb), fmt.italic);
2907 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->underline_tb), fmt.underline);
2908 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->bullet_tb), fmt.bullet);
2910 g_signal_handlers_unblock_by_func(mainview->bold_tb, callback_fontstyle, mainview->bold_tb);
2911 g_signal_handlers_unblock_by_func(mainview->italic_tb, callback_fontstyle, mainview->italic_tb);
2912 g_signal_handlers_unblock_by_func(mainview->underline_tb, callback_fontstyle, mainview->underline_tb);
2913 g_signal_handlers_unblock_by_func(mainview->bullet_tb, callback_fontstyle, mainview->bullet_tb);
2916 gint wp_savecallback(const gchar *buffer, GString * gstr)
2918 gstr=g_string_append(gstr, buffer);
2919 return(0);
2922 void callback_undo(GtkAction * action, MainView * mainview)
2924 g_assert(mainview != NULL && mainview->data != NULL);
2926 nodeData *nd = getSelectedNode(mainview);
2928 if (nd == NULL) return;
2930 if (nd->typ == NODE_SKETCH) sketchwidget_undo(mainview->sk);
2931 else if (nd->typ == NODE_TEXT) wp_text_buffer_undo(mainview->buffer);
2934 void callback_redo(GtkAction * action, MainView * mainview)
2936 g_assert(mainview != NULL && mainview->data != NULL);
2938 nodeData *nd = getSelectedNode(mainview);
2940 if (nd == NULL) return;
2942 if (nd->typ == NODE_SKETCH) sketchwidget_redo(mainview->sk);
2943 else if (nd->typ == NODE_TEXT) wp_text_buffer_redo(mainview->buffer);
2946 void callback_undotoggle(gpointer widget, gboolean st, MainView * mainview)
2948 g_assert(mainview != NULL && mainview->data != NULL);
2950 gtk_widget_set_sensitive(GTK_WIDGET(mainview->undo_tb), st);
2953 void callback_redotoggle(gpointer widget, gboolean st, MainView * mainview)
2955 g_assert(mainview != NULL && mainview->data != NULL);
2957 gtk_widget_set_sensitive(GTK_WIDGET(mainview->redo_tb), st);
2960 void callback_finger(SketchWidget * sk, gint x, gint y, gdouble pressure, MainView * mainview)
2962 g_assert(mainview != NULL && mainview->data != NULL);
2964 if ((mainview->viewflags & 2) == 0) mainview->viewflags |= 2;
2965 else mainview->viewflags &= ~2;
2966 callback_setview(mainview, 1);
2969 gboolean close_cb(GtkWidget * widget, GdkEventAny * event, MainView * mainview)
2971 callback_file_close(NULL, mainview);
2972 return (TRUE);
2975 gboolean key_press_cb(GtkWidget * widget, GdkEventKey * event, MainView * mainview)
2977 switch (event->keyval)
2981 * case GDK_Up:
2982 * gtk_infoprint(GTK_WINDOW(app), "Navigation Key Up");
2983 * return TRUE;
2985 * case GDK_Down:
2986 * gtk_infoprint(GTK_WINDOW(app), "Navigation Key Down");
2987 * return TRUE;
2989 * case GDK_Left:
2990 * gtk_infoprint(GTK_WINDOW(app), "Navigation Key Left");
2991 * return TRUE;
2993 * case GDK_Right:
2994 * gtk_infoprint(GTK_WINDOW(app), "Navigation Key Right");
2995 * return TRUE;
2997 * case GDK_Return:
2998 * gtk_infoprint(GTK_WINDOW(app), "Navigation Key select");
2999 * return TRUE;
3001 /*code below messes up when you have a textview*/
3003 case GDK_Left:
3004 case GDK_Right:
3006 gtk_widget_child_focus(widget, event->keyval==GDK_Left?GTK_DIR_TAB_BACKWARD:GTK_DIR_TAB_FORWARD);
3007 return TRUE;
3010 case GDK_Left:
3012 nodeData *selnode = getSelectedNode(mainview);
3013 if (selnode!=NULL && selnode->typ==NODE_SKETCH)
3015 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Squared shapes ON"));
3016 sketchwidget_set_shift(mainview->sk, TRUE);
3017 return TRUE;
3019 return FALSE;
3021 case GDK_Right:
3023 nodeData *selnode = getSelectedNode(mainview);
3024 if (selnode!=NULL && selnode->typ==NODE_SKETCH)
3026 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Squared shapes OFF"));
3027 sketchwidget_set_shift(mainview->sk, FALSE);
3028 return TRUE;
3030 return FALSE;
3032 case GDK_Down:
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, _("Filled shapes OFF"));
3038 sketchwidget_set_fillmode(mainview->sk, FALSE);
3039 return TRUE;
3041 return FALSE;
3043 case GDK_Up:
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, _("Filled shapes ON"));
3049 sketchwidget_set_fillmode(mainview->sk, TRUE);
3050 return TRUE;
3052 return FALSE;
3054 case GDK_F6:
3056 if ((mainview->viewflags & 4) == 0) mainview->viewflags |= 4;
3057 else mainview->viewflags &= ~4;
3058 callback_setview(mainview, 1);
3059 return TRUE;
3061 case GDK_F7:
3063 callback_redo(NULL, mainview);
3064 return TRUE;
3066 case GDK_F8:
3068 callback_undo(NULL, mainview);
3069 return TRUE;
3071 case GDK_Escape:
3073 if ((mainview->viewflags & 1) == 0) mainview->viewflags |= 1;
3074 else mainview->viewflags &= ~1;
3075 callback_setview(mainview, 1);
3077 return TRUE;
3080 case GDK_Return:
3082 if ((mainview->viewflags & 2) == 0) mainview->viewflags |= 2;
3083 else mainview->viewflags &= ~2;
3084 callback_setview(mainview, 1);
3085 return TRUE;
3090 return FALSE;
3093 void callback_viewmenu(GtkAction * action, GtkWidget * wid)
3095 int flag = (int)gtk_object_get_user_data(GTK_OBJECT(wid));
3096 MainView *mainview = gtk_object_get_data(GTK_OBJECT(wid), "m");
3098 g_assert(mainview != NULL);
3100 if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(wid))) mainview->viewflags |= flag;
3101 else mainview->viewflags &= ~flag;
3103 if (flag==1)
3105 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->toggletree_tb), gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(wid)));
3106 return;
3109 callback_setview(mainview, 0);
3113 void callback_setview(MainView *mainview, int setmenu)
3115 if (setmenu>0)
3117 if ((mainview->viewflags&4)>0)
3118 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->viewmenuitems[2]), TRUE);
3119 else
3120 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->viewmenuitems[2]), FALSE);
3122 if ((mainview->viewflags&2)>0)
3123 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->viewmenuitems[1]), TRUE);
3124 else
3125 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->viewmenuitems[1]), FALSE);
3127 if ((mainview->viewflags&1)>0)
3129 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->viewmenuitems[0]), TRUE);
3130 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->toggletree_tb), TRUE);
3132 else
3134 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->viewmenuitems[0]), FALSE);
3135 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->toggletree_tb), FALSE);
3138 return;
3141 setBusy(mainview, 1);
3143 if ((mainview->viewflags&4)>0)
3144 gtk_window_fullscreen(GTK_WINDOW(mainview->data->main_view));
3145 else
3146 gtk_window_unfullscreen(GTK_WINDOW(mainview->data->main_view));
3148 if ((mainview->viewflags&2)>0)
3149 gtk_widget_show(mainview->toolbar);
3150 else
3151 gtk_widget_hide(mainview->toolbar);
3153 if ((mainview->viewflags&1)>0)
3154 gtk_widget_show(mainview->scrolledtree);
3155 else
3156 gtk_widget_hide(mainview->scrolledtree);
3158 if (mainview->viewflags==4)
3159 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sketchwidget_get_mainwidget(mainview->sk)), GTK_POLICY_NEVER, GTK_POLICY_NEVER);
3160 else
3161 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sketchwidget_get_mainwidget(mainview->sk)), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
3163 setBusy(mainview, 2);
3167 void callback_buffer_modified(GtkAction * action, gpointer data)
3169 MainView *mainview = (MainView *) data;
3170 g_assert(mainview != NULL && mainview->data != NULL);
3172 mainview->file_edited = TRUE;
3176 * Callback for exit D-BUS event
3178 void exit_event_handler(gboolean die_now, gpointer data)
3180 MainView *mainview = (MainView *) data;
3181 g_assert(mainview != NULL && mainview->data != NULL);
3183 if (!die_now)
3185 if (callback_file_close(NULL, mainview)==FALSE) gtk_main_quit(); /*make sure we call gtk_main_quit*/
3187 else
3189 gtk_main_quit();
3192 * application_exit(mainview->data);
3197 * Callback for hardware D-BUS events
3199 void hw_event_handler(osso_hw_state_t * state, gpointer data)
3201 MainView *mainview = (MainView *) data;
3202 g_assert(mainview != NULL && mainview->data != NULL);
3205 * if (state->shutdown_ind)
3207 * gtk_infoprint(GTK_WINDOW(mainview->data->app),
3208 * "Shutdown event!");
3210 * if (state->memory_low_ind)
3212 * gtk_infoprint(GTK_WINDOW(mainview->data->app),
3213 * "Memory low event!");
3216 if (state->save_unsaved_data_ind)
3218 fprintf(stderr, "Saving unsaved data!\n");
3219 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, "Saving unsaved data!");
3220 callback_file_save(NULL, mainview);
3224 * if (state->system_inactivity_ind)
3226 * gtk_infoprint(GTK_WINDOW(mainview->data->app),
3227 * "Minimize application inactivity event!");
3232 GtkTreeRowReference *read_sqlite3_data(MainView * mainview, unsigned int parentid, GtkTreeRowReference * parenttree, unsigned int selected, GtkTreeStore * model)
3234 GtkTreeRowReference *resref = NULL;
3236 char q[256];
3238 snprintf(q, sizeof(q), "SELECT nodeid, bodytype, name, nameblob, lastmodified, flags FROM %s WHERE parent=%d ORDER BY ord", datatable_tmpname, parentid);
3240 sqlite3_stmt *stmt = NULL;
3241 const char *dum;
3242 int rc = sqlite3_prepare(mainview->db, q, strlen(q), &stmt, &dum);
3244 if (rc)
3246 fprintf(stderr, "Error %s\n", sqlite3_errmsg(mainview->db));
3247 return (NULL);
3250 rc = SQLITE_BUSY;
3251 while(rc == SQLITE_BUSY || rc == SQLITE_ROW)
3253 rc = sqlite3_step(stmt);
3254 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE || rc == SQLITE_DONE)
3255 break;
3256 else if (rc == SQLITE_ROW)
3258 int nodeid = sqlite3_column_int(stmt, 0);
3259 int typ = sqlite3_column_int(stmt, 1);
3260 const unsigned char *name = sqlite3_column_text(stmt, 2);
3261 const unsigned char *nameblob = sqlite3_column_text(stmt, 3);
3262 int lastmod = sqlite3_column_int(stmt, 4);
3263 int flags = sqlite3_column_int(stmt, 5);
3266 * fprintf(stderr, "CARD=%s TYPE=%d\n", name, typ);
3268 if ((typ != NODE_TEXT && typ != NODE_SKETCH && typ != NODE_CHECKLIST) || (name == NULL && nameblob == NULL))
3272 * fprintf(stderr, "invalid card, skipping\n");
3274 continue;
3277 nodeData *node = g_malloc(sizeof(nodeData));
3279 node->sql3id = nodeid;
3280 node->typ = typ;
3281 node->flags = flags;
3282 node->name = NULL;
3283 node->namepix = NULL;
3284 if (name != NULL)
3285 node->name = g_strdup((char *)name);
3286 if (nameblob != NULL)
3288 int blobsize = sqlite3_column_bytes(stmt, 3);
3290 GdkPixbufLoader *pl = gdk_pixbuf_loader_new_with_type("png", NULL);
3291 GError *err = NULL;
3293 gdk_pixbuf_loader_write(pl, (guchar *) nameblob, blobsize, &err);
3294 if (err != NULL)
3296 fprintf(stderr, "Error loading nodename! %s\n", err->message);
3297 g_error_free(err);
3298 err = NULL;
3300 gdk_pixbuf_loader_close(pl, NULL);
3301 GdkPixbuf *pixbuf = gdk_pixbuf_loader_get_pixbuf(pl);
3303 if (GDK_IS_PIXBUF(pixbuf))
3304 node->namepix = pixbuf;
3306 node->lastMod = lastmod;
3308 GtkTreeIter parentiter, newiter;
3309 void *par = NULL;
3311 if (parenttree != NULL)
3313 GtkTreePath *pa = gtk_tree_row_reference_get_path(parenttree);
3315 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &parentiter, pa);
3316 gtk_tree_path_free(pa);
3317 par = &parentiter;
3320 gtk_tree_store_append(model, &newiter, par);
3321 gtk_tree_store_set(model, &newiter, NODE_NAME, node->name, NODE_PIXBUF, node->namepix, NODE_DATA, node, -1);
3323 GtkTreePath *pa = gtk_tree_model_get_path(GTK_TREE_MODEL(model), &newiter);
3325 GtkTreeRowReference *newref = gtk_tree_row_reference_new(GTK_TREE_MODEL(model), pa);
3327 if (selected == nodeid)
3328 resref = newref;
3330 gtk_tree_path_free(pa);
3331 GtkTreeRowReference *r = read_sqlite3_data(mainview, nodeid, newref, selected,
3332 model);
3334 if (resref != newref)
3335 gtk_tree_row_reference_free(newref);
3337 if (r != NULL)
3339 if (resref == NULL)
3340 resref = r;
3341 else
3342 gtk_tree_row_reference_free(r); /*safeguard */
3347 if (stmt)
3348 sqlite3_finalize(stmt);
3350 return (resref); /*ref to supposed-to-be-selected treeitem */
3354 * read file
3356 gboolean read_file_to_buffer(MainView * mainview)
3358 char tq[512];
3360 g_assert(mainview != NULL);
3361 gboolean res = FALSE;
3363 gchar *filename = mainview->file_name;
3365 new_file(mainview);
3366 mainview->file_name = filename;
3367 mainview->loading=TRUE;
3369 fprintf(stderr, "read:*%s*\n", filename);
3371 int rc;
3372 sqlite3_stmt *stmt = NULL;
3374 rc = sqlite3_open(filename, &mainview->db);
3377 if (rc)
3379 fprintf(stderr, "Can't open database %s: %s\n", filename, sqlite3_errmsg(mainview->db));
3380 break;
3383 sqlite3_exec(mainview->db, "PRAGMA synchronous = OFF;", NULL, NULL, NULL);
3385 char *q = "SELECT skey, sval FROM settings";
3386 const char *dum;
3388 rc = sqlite3_prepare(mainview->db, q, strlen(q), &stmt, &dum);
3389 if (rc)
3391 fprintf(stderr, "Error %s\n", sqlite3_errmsg(mainview->db));
3392 break;
3395 unsigned int selectedCard = 0;
3398 * fprintf(stderr, "start config\n");
3400 unsigned int curDataVersion = 0;
3401 unsigned int curChecklistVersion = 0;
3403 rc = SQLITE_BUSY;
3404 while(rc == SQLITE_BUSY || rc == SQLITE_ROW)
3406 rc = sqlite3_step(stmt);
3407 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE || rc == SQLITE_DONE)
3408 break;
3409 else if (rc == SQLITE_ROW)
3411 const unsigned char *col_key = sqlite3_column_text(stmt, 0);
3412 const unsigned char *col_val = sqlite3_column_text(stmt, 1);
3415 * fprintf(stderr, "%s=%s\n", col_key, col_val);
3417 if (!strcmp(col_key, "leftPanedPos"))
3419 gint panedPos = atoi((char *)col_val);
3421 if (panedPos > 0)
3422 gtk_paned_set_position(GTK_PANED(mainview->hpaned), panedPos);
3424 if (!strcmp(col_key, "selectedNode"))
3426 gint tmp = atoi((char *)col_val);
3428 if (tmp > 0)
3429 selectedCard = tmp;
3431 if (!strcmp(col_key, "dataVersion"))
3433 gint tmp = atoi((char *)col_val);
3435 if (tmp > 0)
3436 curDataVersion = tmp;
3438 if (!strcmp(col_key, "checklistVersion"))
3440 gint tmp = atoi((char *)col_val);
3442 if (tmp > 0)
3443 curChecklistVersion = tmp;
3445 if (!strcmp(col_key, "newNodeDlgCreateChild"))
3447 gint tmp = atoi((char *)col_val);
3449 mainview->newnodedialog_createchild = TRUE;
3450 if (tmp == 0)
3451 mainview->newnodedialog_createchild = FALSE;
3453 if (!strcmp(col_key, "fullScreen"))
3455 gint tmp = atoi((char *)col_val);
3456 if (tmp<0 || tmp>4) tmp=0;
3457 if (tmp==0) tmp=4;
3458 else tmp--;
3459 if (tmp==0) tmp=3;
3460 else if (tmp==1) tmp=2;
3461 else if (tmp==2) tmp=7;
3462 else if (tmp==3) tmp=6;
3463 else if (tmp==4) tmp=4;
3464 mainview->viewflags=tmp;
3465 callback_setview(mainview, TRUE);
3467 if (!strcmp(col_key, "viewFlags"))
3469 gint tmp = atoi((char *)col_val);
3470 if (tmp<0) tmp=3;
3471 mainview->viewflags=tmp;
3472 callback_setview(mainview, TRUE);
3474 if (!strcmp(col_key, "brushSize"))
3476 gint tmp = atoi((char *)col_val);
3477 if (tmp>0) sk_set_brushsize(mainview, tmp);
3479 if (!strcmp(col_key, "brushColor"))
3481 unsigned long tmp = atol((char *)col_val);
3482 GdkColor c2;
3484 c2.red = ((tmp & 0xFF0000) >> 16) << 8;
3485 c2.green = ((tmp & 0xFF00) >> 8) << 8;
3486 c2.blue = (tmp & 0xFF) << 8;
3487 /* fprintf(stderr, "READ BRUSHCOLOR is %ul (%d,%d,%d)\n", tmp, c2.red, c2.green, c2.blue);*/
3489 sketchwidget_set_brushcolor(mainview->sk, c2);
3490 hildon_color_button_set_color(HILDON_COLOR_BUTTON(mainview->colorbutton), &c2);
3495 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE)
3497 fprintf(stderr, "Error2 %s\n", sqlite3_errmsg(mainview->db));
3498 break;
3502 * fprintf(stderr, "end config\n");
3504 if (stmt)
3505 sqlite3_finalize(stmt);
3507 gboolean resback = FALSE;
3509 while(curDataVersion < datatableversion)
3511 if (curDataVersion == 0)
3513 snprintf(tq, sizeof(tq), "DROP TABLE %s", datatable_backupname);
3514 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3516 snprintf(tq, sizeof(tq), "ALTER TABLE %s RENAME TO %s", datatable_name, datatable_backupname);
3517 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3519 fprintf(stderr, "ERROR backing up table!\n");
3520 break;
3522 resback = TRUE;
3524 snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", datatable_name, datatable);
3525 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3527 fprintf(stderr, "ERROR creating table!\n");
3528 break;
3530 snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT nodeid, parent, bodytype, name, body, nameblob, bodyblob, lastmodified, ord, 0 FROM %s", datatable_name, datatable_backupname);
3531 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3533 fprintf(stderr, "ERROR copying data!\n");
3534 break;
3537 snprintf(tq, sizeof(tq), "DROP TABLE %s", datatable_backupname);
3538 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3540 curDataVersion = datatableversion;
3542 break;
3545 if (curDataVersion != datatableversion)
3547 fprintf(stderr, "Data version mismatch\n");
3549 if (resback == TRUE)
3551 snprintf(tq, sizeof(tq), "DROP TABLE %s", datatable_name);
3552 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3553 snprintf(tq, sizeof(tq), "ALTER TABLE %s RENAME TO %s", datatable_backupname, datatable_name);
3554 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3557 break;
3561 while(curChecklistVersion < checklisttableversion)
3563 if (curChecklistVersion == 0) /*no checklisttable at all*/
3565 snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", checklisttable_name, checklisttable);
3566 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3568 fprintf(stderr, "ERROR creating checklist table!\n");
3569 break;
3571 curChecklistVersion = checklisttableversion;
3573 break;
3577 GtkTreeStore *model = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->treeview)));
3579 g_object_ref(model);
3580 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->treeview), NULL);
3584 char tq[512];
3586 snprintf(tq, sizeof(tq), "CREATE%s TABLE %s%s", TEMPTABLE_KEYWORD, datatable_tmpname, datatable);
3587 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3589 fprintf(stderr, "ERROR creating temp table!\n");
3590 break;
3592 snprintf(tq, sizeof(tq), "CREATE INDEX %s_index ON %s %s", datatable_tmpname, datatable_tmpname, dataindex);
3593 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3595 fprintf(stderr, "ERROR creating temp index!\n");
3596 break;
3598 snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT * FROM %s", datatable_tmpname, datatable_name);
3599 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3601 fprintf(stderr, "ERROR copying data to temp table!\n");
3602 break;
3605 snprintf(tq, sizeof(tq), "CREATE%s TABLE %s%s", TEMPTABLE_KEYWORD, checklisttable_tmpname, checklisttable);
3606 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3608 fprintf(stderr, "ERROR creating temp table! (checklist)\n");
3609 break;
3611 snprintf(tq, sizeof(tq), "CREATE INDEX %s_index ON %s %s", checklisttable_tmpname, checklisttable_tmpname, checklistindex);
3612 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3614 fprintf(stderr, "ERROR creating temp index! (checklist)\n");
3615 break;
3617 snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT * FROM %s", checklisttable_tmpname, checklisttable_name);
3618 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3620 fprintf(stderr, "ERROR copying data to temp table! (checklist)\n");
3621 break;
3624 while(FALSE);
3626 GtkTreeRowReference *selectedRef = read_sqlite3_data(mainview, 0, NULL, selectedCard, model);
3628 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->treeview), GTK_TREE_MODEL(model));
3629 g_object_unref(model);
3630 gtk_tree_view_expand_all(GTK_TREE_VIEW(mainview->treeview));
3632 if (selectedRef != NULL)
3634 GtkTreeIter seliter;
3636 if (ref2iter(GTK_TREE_MODEL(model), selectedRef, &seliter) == TRUE)
3638 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
3639 gtk_tree_selection_select_iter(selection, &seliter);
3642 gtk_tree_row_reference_free(selectedRef);
3644 res = TRUE;
3646 while(FALSE);
3648 if (stmt)
3649 sqlite3_finalize(stmt);
3652 mainview->loading=FALSE;
3654 return (res);
3658 * write to file
3660 void write_buffer_to_file(MainView * mainview)
3662 fprintf(stderr, "write:*%s*\n", mainview->file_name);
3663 saveCurrentData(mainview);
3665 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->treeview));
3666 /*update ord value in database for all nodes*/
3667 gtk_tree_model_foreach(GTK_TREE_MODEL(model),(GtkTreeModelForeachFunc) foreach_func_update_ord,mainview);
3669 setBusy(mainview, 1);
3671 char tq[512];
3673 snprintf(tq, sizeof(tq), "DROP TABLE %s", misctable_name);
3674 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3676 snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", misctable_name, misctable);
3677 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3679 gint panedPos = gtk_paned_get_position(GTK_PANED(mainview->hpaned));
3681 snprintf(tq, sizeof(tq), "INSERT INTO %s VALUES('leftPanedPos', '%d');", misctable_name, panedPos);
3682 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3684 gint nndcc = 1;
3686 if (mainview->newnodedialog_createchild == FALSE)
3687 nndcc = 0;
3688 snprintf(tq, sizeof(tq), "INSERT INTO %s VALUES('newNodeDlgCreateChild', '%d');", misctable_name, nndcc);
3689 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3691 snprintf(tq, sizeof(tq), "INSERT INTO %s VALUES('viewFlags', '%d');", misctable_name, mainview->viewflags);
3692 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3694 nodeData *node = getSelectedNode(mainview);
3696 if (node)
3698 snprintf(tq, sizeof(tq), "INSERT INTO %s VALUES('selectedNode', '%d');", misctable_name, node->sql3id);
3699 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3702 guint bsize;
3703 if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(mainview->eraser_tb)) == TRUE)
3705 bsize=mainview->brushsize_backup;
3707 else
3709 bsize=sketchwidget_get_brushsize(mainview->sk);
3711 snprintf(tq, sizeof(tq), "INSERT INTO %s VALUES('brushSize', '%d');", misctable_name, bsize);
3712 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3714 GdkColor col;
3715 hildon_color_button_get_color(HILDON_COLOR_BUTTON(mainview->colorbutton), &col);
3716 unsigned long bcol=((col.red >> 8) << 16) | ((col.green >> 8) << 8) | (col.blue >> 8);
3718 /* fprintf(stderr, "BRUSHCOLOR is %d (%d,%d,%d)\n", bcol, col->red, col->green, col->blue);*/
3719 snprintf(tq, sizeof(tq), "INSERT INTO %s VALUES('brushColor', '%lu');", misctable_name, bcol);
3720 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3722 snprintf(tq, sizeof(tq), "INSERT INTO %s VALUES('dataVersion', '%d');", misctable_name, datatableversion);
3723 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3725 snprintf(tq, sizeof(tq), "INSERT INTO %s VALUES('checklistVersion', '%d');", misctable_name, checklisttableversion);
3726 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3728 snprintf(tq, sizeof(tq), "DROP TABLE %s", datatable_backupname);
3729 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3730 snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", datatable_backupname, datatable);
3731 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3733 fprintf(stderr, "ERROR creating backup table!\n");
3734 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, "Error 1");
3736 setBusy(mainview, 2);
3737 return;
3739 snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT * FROM %s", datatable_backupname, datatable_name);
3740 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3742 fprintf(stderr, "ERROR backing up table!\n");
3743 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, "Error 2");
3745 setBusy(mainview, 2);
3746 return;
3748 snprintf(tq, sizeof(tq), "DELETE FROM %s", datatable_name);
3749 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3751 snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT * FROM %s", datatable_name, datatable_tmpname);
3752 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3754 fprintf(stderr, "ERROR saving table!\n");
3755 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, "Error 3");
3757 snprintf(tq, sizeof(tq), "DELETE FROM %s", datatable_name);
3758 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3760 snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT * FROM %s", datatable_name, datatable_backupname);
3761 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3763 fprintf(stderr, "ERROR restoring backup! data lost!\n");
3766 setBusy(mainview, 2);
3767 return;
3770 snprintf(tq, sizeof(tq), "DROP TABLE %s", datatable_backupname);
3771 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3773 /*checklist*/
3774 snprintf(tq, sizeof(tq), "DROP TABLE %s", checklisttable_backupname);
3775 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3776 snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", checklisttable_backupname, checklisttable);
3777 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3779 fprintf(stderr, "ERROR creating backup table! (checklist)\n");
3780 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, "Error 4");
3782 setBusy(mainview, 2);
3783 return;
3786 snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT * FROM %s", checklisttable_backupname, checklisttable_name);
3787 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3789 fprintf(stderr, "ERROR backing up table! (checklist)\n");
3790 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, "Error 5");
3792 setBusy(mainview, 2);
3793 return;
3795 snprintf(tq, sizeof(tq), "DELETE FROM %s", checklisttable_name);
3796 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3798 snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT * FROM %s", checklisttable_name, checklisttable_tmpname);
3799 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3801 fprintf(stderr, "ERROR saving table! (checklist)\n");
3802 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, "Error 6");
3804 snprintf(tq, sizeof(tq), "DELETE FROM %s", checklisttable_name);
3805 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3807 snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT * FROM %s", checklisttable_name, checklisttable_backupname);
3808 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
3810 fprintf(stderr, "ERROR restoring backup! data lost! (checklist)\n");
3812 setBusy(mainview, 2);
3813 return;
3816 snprintf(tq, sizeof(tq), "DROP TABLE %s", checklisttable_backupname);
3817 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
3819 mainview->file_edited = FALSE;
3820 setBusy(mainview, 2);
3821 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), GTK_STOCK_SAVE, _("Saved"));
3825 void callback_checklist_toggled(GtkCellRendererToggle *cell_renderer, gchar *path, GtkWidget *source)
3827 gtk_object_set_data(GTK_OBJECT(source), "edited", TRUE);
3829 GtkTreeIter iter;
3830 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(source));
3831 GtkTreePath *treepath = gtk_tree_path_new_from_string(path);
3832 if(gtk_tree_model_get_iter(model, &iter, treepath))
3834 gboolean val;
3835 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHECKNODE_CHECKED, &val, -1);
3836 gtk_list_store_set(GTK_LIST_STORE(model), &iter, CHECKNODE_CHECKED, !val, -1);
3838 gtk_tree_path_free(treepath);
3841 void callback_checklist_edited(GtkCellRendererToggle *cell_renderer, gchar *arg1, gchar *arg2, GtkWidget *source)
3843 gtk_object_set_data(GTK_OBJECT(source), "edited", TRUE);
3845 GtkTreeIter iter;
3846 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(source));
3847 GtkTreePath *treepath = gtk_tree_path_new_from_string(arg1);
3848 if(gtk_tree_model_get_iter(model, &iter, treepath))
3850 gtk_list_store_set(GTK_LIST_STORE(model), &iter, CHECKNODE_TEXT, arg2, -1);
3852 gtk_tree_path_free(treepath);
3855 void callback_checklist_change(GtkTreeSelection *selection, MainView *mainview)
3857 g_assert(mainview != NULL && mainview->data != NULL);
3859 g_signal_handlers_block_by_func(mainview->bold_tb, callback_fontstyle, mainview->bold_tb);
3860 g_signal_handlers_block_by_func(mainview->strikethru_tb, callback_fontstyle, mainview->strikethru_tb);
3861 g_signal_handlers_block_by_func(mainview->check_tb, callback_fontstyle, mainview->check_tb);
3863 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->bold_tb), FALSE);
3864 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->strikethru_tb), FALSE);
3865 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->check_tb), FALSE);
3867 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->listview));
3868 GList* l=gtk_tree_selection_get_selected_rows(selection, NULL);
3870 gboolean gotit=FALSE;
3872 GList* cur=l;
3873 while(cur)
3875 GtkTreePath *path=cur->data;
3877 if (!gotit)
3879 GtkTreeIter iter;
3880 if (gtk_tree_model_get_iter(model, &iter, path))
3882 gint styletoset_weight;
3883 gboolean styletoset_strike;
3884 gboolean ischecked;
3886 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHECKNODE_BOLD, &styletoset_weight, CHECKNODE_STRIKE, &styletoset_strike, CHECKNODE_CHECKED, &ischecked, -1);
3887 if (styletoset_weight==PANGO_WEIGHT_BOLD) gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->bold_tb), TRUE);
3888 if (styletoset_strike==TRUE) gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->strikethru_tb), TRUE);
3889 if (ischecked==TRUE) gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->check_tb), TRUE);
3890 gotit=TRUE;
3893 gtk_tree_path_free(path);
3894 cur=cur->next;
3897 g_list_free(l);
3899 g_signal_handlers_unblock_by_func(mainview->bold_tb, callback_fontstyle, mainview->bold_tb);
3900 g_signal_handlers_unblock_by_func(mainview->strikethru_tb, callback_fontstyle, mainview->strikethru_tb);
3901 g_signal_handlers_unblock_by_func(mainview->check_tb, callback_fontstyle, mainview->check_tb);
3904 void callback_checklist_paste(MainView *mainview)
3906 g_assert(mainview != NULL && mainview->data != NULL);
3907 gchar **entries;
3908 gint length, i;
3910 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->listview));
3911 GtkTreeIter toplevel;
3912 gchar *pasted_text = gtk_clipboard_wait_for_text(mainview->clipboard);
3914 entries = g_strsplit(pasted_text, "\n", 0);
3915 length = g_strv_length(entries);
3917 for (i=0; i<length; i++) {
3918 gtk_list_store_append(GTK_LIST_STORE(model), &toplevel);
3919 gtk_list_store_set(GTK_LIST_STORE(model), &toplevel, CHECKNODE_CHECKED, FALSE, CHECKNODE_TEXT, entries[i], -1);
3922 gtk_object_set_data(GTK_OBJECT(mainview->listview), "edited", TRUE);
3923 g_free(pasted_text);
3924 g_strfreev(entries);
3927 void callback_checklist_add(GtkAction *action, MainView *mainview)
3929 g_assert(mainview != NULL && mainview->data != NULL);
3931 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->listview));
3932 GtkTreeIter toplevel;
3933 gtk_list_store_append(GTK_LIST_STORE(model), &toplevel);
3935 gtk_list_store_set(GTK_LIST_STORE(model), &toplevel, CHECKNODE_CHECKED, FALSE, CHECKNODE_TEXT, "", -1);
3936 GtkTreePath *path = gtk_tree_model_get_path(model, &toplevel);
3937 if (path)
3939 gtk_tree_view_set_cursor(GTK_TREE_VIEW(mainview->listview), path, mainview->listtextcol, TRUE);
3940 gtk_tree_path_free(path);
3943 gtk_object_set_data(GTK_OBJECT(mainview->listview), "edited", TRUE);
3946 void callback_checklist_delete(GtkAction *action, MainView *mainview)
3948 g_assert(mainview != NULL && mainview->data != NULL);
3950 if (gtk_tree_selection_count_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->listview)))==0)
3952 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Select items first"));
3953 return;
3956 GtkWidget *dialog, *label, *but_ok, *but_cancel;
3958 dialog = gtk_dialog_new();
3960 label = gtk_label_new(_("Delete selected items?"));
3962 but_ok = gtk_button_new_with_label(_("Yes, Delete"));
3963 but_cancel = gtk_button_new_with_label(_("Cancel"));
3965 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area), but_ok);
3966 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area), but_cancel);
3968 gtk_object_set_user_data(GTK_OBJECT(dialog), mainview);
3970 gtk_signal_connect_object(GTK_OBJECT(but_cancel), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), dialog);
3971 g_signal_connect(G_OBJECT(but_ok), "clicked", G_CALLBACK(callback_checklist_delete_real), dialog);
3973 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
3975 gtk_widget_show_all(dialog);
3976 gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
3979 void callback_checklist_delete_real(GtkAction *action, gpointer data)
3981 GtkWidget *dialog = data;
3982 MainView *mainview = gtk_object_get_user_data(GTK_OBJECT(dialog));
3983 gtk_widget_destroy(dialog);
3985 GtkTreeModel *model=gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->listview));
3986 GList* l=gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->listview)), NULL);
3988 GList* rowrefs=NULL;
3989 GList* cur=l;
3990 while(cur)
3992 GtkTreePath *path=cur->data;
3994 GtkTreeIter iter;
3995 if (gtk_tree_model_get_iter(model, &iter, path))
3997 GtkTreeRowReference *rowref = gtk_tree_row_reference_new(model, path);
3998 rowrefs=g_list_append(rowrefs, rowref);
4000 gtk_tree_path_free(path);
4001 cur=cur->next;
4003 g_list_free(l);
4005 g_object_ref(model);
4006 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->listview), NULL);
4008 cur=rowrefs;
4009 while(cur)
4011 GtkTreeRowReference *rowref=cur->data;
4012 GtkTreePath *path= gtk_tree_row_reference_get_path(rowref);
4013 if (path)
4015 GtkTreeIter iter;
4016 if (gtk_tree_model_get_iter(model, &iter, path)) gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
4017 gtk_tree_path_free(path);
4019 gtk_tree_row_reference_free(rowref);
4020 cur=cur->next;
4022 g_list_free(rowrefs);
4024 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->listview), model);
4025 g_object_unref(model);
4026 gtk_object_set_data(GTK_OBJECT(mainview->listview), "edited", TRUE);