tagged 0.25
[maemopadplus.git] / src / ui / callbacks.c
blob2c5b84ebad5dafc48daff4f4ea2cd7f8b6f4cd50
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 <hildon-widgets/hildon-banner.h>
37 #include <hildon-widgets/hildon-note.h>
38 #include <libgnomevfs/gnome-vfs.h>
39 #include <osso-browser-interface.h>
41 #include <config.h>
44 * Privates:
46 gboolean read_file_to_buffer(MainView * mainview);
47 void write_buffer_to_file(MainView * mainview);
48 void new_node_dialog(nodeType typ, MainView * mainview);
51 st==0: turn off/zero refcount
52 st==1: turn on/increase ref
53 st==2: decrease refcount and turn off if necessary
55 void setBusy(MainView *mainview, gchar st)
57 if (st==0) mainview->busyrefcount=0;
58 else if (st==1) mainview->busyrefcount++;
59 else if (st==2 && mainview->busyrefcount>0) mainview->busyrefcount--;
60 gdk_window_set_cursor(GTK_WIDGET(mainview->data->main_view)->window, (mainview->busyrefcount>0)?mainview->cursorBusy:NULL);
63 gboolean isBusy(MainView *mainview)
65 if (mainview->busyrefcount>0) return(TRUE);
66 return(FALSE);
69 void prepareUIforNodeChange(MainView * mainview, nodeType typ)
71 if (typ == NODE_TEXT)
73 gtk_widget_show(GTK_WIDGET(mainview->font_tb));
74 gtk_widget_show(mainview->tools_font);
76 else
78 gtk_widget_hide(GTK_WIDGET(mainview->font_tb));
79 gtk_widget_hide(mainview->tools_font);
82 if (typ == NODE_SKETCH)
84 gtk_widget_show(GTK_WIDGET(mainview->colorbutton_tb));
85 gtk_widget_show(GTK_WIDGET(mainview->eraser_tb));
86 gtk_widget_show(GTK_WIDGET(mainview->brushsize_tb));
87 gtk_widget_show(GTK_WIDGET(mainview->sketchlines_tb));
88 gtk_widget_show(GTK_WIDGET(mainview->shape_tb));
89 gtk_widget_show(GTK_WIDGET(mainview->undo_tb));
90 gtk_widget_show(GTK_WIDGET(mainview->redo_tb));
91 gtk_widget_show(mainview->tools_color);
92 gtk_widget_show(mainview->tools_brushsize);
93 gtk_widget_show(mainview->tools_pagestyle);
94 gtk_widget_show(mainview->tools_shape);
96 else
98 gtk_widget_hide(GTK_WIDGET(mainview->colorbutton_tb));
99 gtk_widget_hide(GTK_WIDGET(mainview->eraser_tb));
100 gtk_widget_hide(GTK_WIDGET(mainview->brushsize_tb));
101 gtk_widget_hide(GTK_WIDGET(mainview->sketchlines_tb));
102 gtk_widget_hide(GTK_WIDGET(mainview->shape_tb));
103 gtk_widget_hide(GTK_WIDGET(mainview->undo_tb));
104 gtk_widget_hide(GTK_WIDGET(mainview->redo_tb));
105 gtk_widget_hide(mainview->tools_color);
106 gtk_widget_hide(mainview->tools_brushsize);
107 gtk_widget_hide(mainview->tools_pagestyle);
108 gtk_widget_hide(mainview->tools_shape);
111 if (typ == NODE_TEXT)
113 gtk_widget_hide(sketchwidget_get_mainwidget(mainview->sk));
114 gtk_widget_show(GTK_WIDGET(mainview->scrolledwindow));
115 gtk_widget_show(mainview->tools_item);
117 else if (typ == NODE_SKETCH)
119 gtk_widget_hide(GTK_WIDGET(mainview->scrolledwindow));
120 gtk_widget_show(sketchwidget_get_mainwidget(mainview->sk));
121 gtk_widget_show(mainview->tools_item);
123 else
125 gtk_widget_hide(GTK_WIDGET(mainview->scrolledwindow));
126 gtk_widget_hide(sketchwidget_get_mainwidget(mainview->sk));
127 gtk_widget_hide(mainview->tools_item);
131 nodeData *getSelectedNode(MainView * mainview)
133 GtkTreeIter iter;
134 GtkTreeModel *model;
136 nodeData *nd;
138 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
140 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
141 return (NULL);
143 gtk_tree_model_get(model, &iter, NODE_DATA, &nd, -1);
145 return (nd);
148 void saveCurrentData(MainView * mainview)
150 nodeData *selnode = getSelectedNode(mainview);
151 saveDataToNode(mainview, selnode);
154 void saveDataToNode(MainView * mainview, nodeData *selnode)
156 if (selnode == NULL)
157 return;
159 if ((selnode->typ == NODE_SKETCH && sketchwidget_get_edited(mainview->sk) == FALSE) || (selnode->typ == NODE_TEXT && gtk_text_buffer_get_modified(GTK_TEXT_BUFFER(mainview->buffer)) == FALSE))
161 fprintf(stderr, "node not edited, not saving\n");
162 return;
165 mainview->file_edited = TRUE;
167 setBusy(mainview, 1);
168 fprintf(stderr, "savecurrentdata!\n");
170 gboolean goterr = TRUE;
171 gchar *textdata = NULL;
172 GdkPixbuf *pixbuf = NULL;
173 gchar *sketchdata = NULL;
174 gsize datalen = 0;
175 char tq[512];
177 if (selnode->typ == NODE_TEXT)
179 GtkTextIter start, end;
181 gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(mainview->buffer), &start, &end);
182 textdata = gtk_text_buffer_get_slice(GTK_TEXT_BUFFER(mainview->buffer), &start, &end, TRUE);
184 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);
186 else if (selnode->typ == NODE_SKETCH)
188 GError *err = NULL;
189 GdkPixmap *skpix = sketchwidget_get_Pixmap(mainview->sk);
190 GtkWidget *skdr = sketchwidget_get_drawingarea(mainview->sk);
192 pixbuf = gdk_pixbuf_get_from_drawable(NULL, GDK_DRAWABLE(skpix), NULL, 0, 0, 0, 0, skdr->allocation.width, skdr->allocation.height);
193 if (pixbuf == NULL)
195 fprintf(stderr, "Error saving: pixbuf is null\n");
197 else
199 double w, h;
200 GdkPixbuf *pixbuf2 = sketchwidget_trim_image(pixbuf, skdr->allocation.width, skdr->allocation.height, &w, &h, FALSE);
202 if (pixbuf2!=NULL)
204 if (gdk_pixbuf_save_to_buffer(pixbuf2, &sketchdata, &datalen, "png", &err, NULL) == FALSE)
206 sketchdata = NULL;
207 datalen = 0;
208 fprintf(stderr, "Error saving sketch! %s\n", err->message);
209 g_error_free(err);
211 gdk_pixbuf_unref(pixbuf2);
214 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);
215 fprintf(stderr, "datalen:%d\n", datalen);
216 if (skpix && G_IS_OBJECT(skpix)) g_object_unref(skpix);
220 * fprintf(stderr, "query is *%s*\n", tq);
225 sqlite3_stmt *stmt = NULL;
226 const char *dum;
227 int rc = sqlite3_prepare(mainview->db, tq, strlen(tq), &stmt, &dum);
229 if (rc)
231 fprintf(stderr, "Error updating: %s\n", sqlite3_errmsg(mainview->db));
232 break;
234 if (selnode->typ == NODE_TEXT)
235 sqlite3_bind_text(stmt, 1, textdata, strlen(textdata), SQLITE_TRANSIENT);
236 else if (selnode->typ == NODE_SKETCH)
237 sqlite3_bind_blob(stmt, 1, sketchdata, datalen, SQLITE_TRANSIENT);
239 rc = SQLITE_BUSY;
240 while(rc == SQLITE_BUSY)
242 rc = sqlite3_step(stmt);
243 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE || rc == SQLITE_DONE)
244 break;
246 sqlite3_finalize(stmt);
247 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE)
249 fprintf(stderr, "Error saving node: %s\n", sqlite3_errmsg(mainview->db));
251 else
253 if (selnode->typ == NODE_TEXT)
254 gtk_text_buffer_set_modified(GTK_TEXT_BUFFER(mainview->buffer), FALSE);
255 else if (selnode->typ == NODE_SKETCH)
256 sketchwidget_set_edited(mainview->sk, FALSE);
257 goterr = FALSE;
260 while(FALSE);
262 if (textdata)
263 g_free(textdata);
264 if (sketchdata)
265 g_free(sketchdata);
266 if (goterr == TRUE)
268 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Error saving memo"));
270 setBusy(mainview, 2);
273 void callback_treeview_celldatafunc(GtkTreeViewColumn * tree_column, GtkCellRenderer * cell, GtkTreeModel * tree_model, GtkTreeIter * iter, gpointer data)
275 MainView *mainview = NULL;
276 mainview = ( MainView * ) data;
277 g_assert(mainview != NULL && mainview->data != NULL );
279 nodeData *nd;
281 gtk_tree_model_get(tree_model, iter, NODE_DATA, &nd, -1);
282 if (nd == NULL)
283 return;
285 if (nd->namepix == NULL)
287 g_object_set(cell, "visible", FALSE, NULL);
289 else
291 g_object_set(cell, "visible", TRUE, NULL);
292 g_object_set(cell, "width", SKETCHNODE_RX, NULL);
293 g_object_set(cell, "height", SKETCHNODE_RY, NULL);
297 gboolean callback_treeview_testcollapse(GtkTreeView * treeview, GtkTreeIter * arg1, GtkTreePath * arg2, gpointer user_data)
299 return (TRUE);
302 void callback_treeview_change(GtkTreeSelection * selection, gpointer data)
304 MainView *mainview = NULL;
306 mainview = (MainView *) data;
307 g_assert(mainview != NULL && mainview->data != NULL);
309 nodeData *nd = getSelectedNode(mainview);
312 if (nd==NULL)
313 fprintf(stderr, "changed called but no selectednode\n");
314 else
315 fprintf(stderr, "changed called, selectednode is %d\n", nd->sql3id);
317 #ifdef NEW_SEL_LOGIC
318 guint tm=time(NULL);
319 if (mainview->cansel_time>0 && mainview->cansel_time+1.0<tm) mainview->cansel_node=NULL;
321 if (nd==NULL)
323 if (mainview->cansel_node!=NULL)
325 fprintf(stderr, "[SELLOGIC] saving %d to unselect all nodes\n", (mainview->cansel_node)->sql3id);
326 saveDataToNode(mainview, (mainview->cansel_node));
327 mainview->cansel_node=NULL;
329 return;
332 if (mainview->cansel_node!=NULL)
334 if (nd->sql3id == (mainview->cansel_node)->sql3id)
336 mainview->cansel_node=NULL;
337 fprintf(stderr, "[SELLOGIC] doubly selected %d, doing nothing\n", nd->sql3id);
338 return;
340 else
342 fprintf(stderr, "[SELLOGIC] saving %d to load new node\n", (mainview->cansel_node)->sql3id);
343 saveDataToNode(mainview, (mainview->cansel_node));
344 mainview->cansel_node=NULL;
347 #endif
349 if (nd == NULL) return;
351 setBusy(mainview, 1);
353 gboolean goterr = TRUE;
354 char *textdata = NULL;
355 char *blob = NULL;
356 int blobsize = 0;
358 char tq[512];
360 snprintf(tq, sizeof(tq), "SELECT bodytype, body, bodyblob, flags FROM %s WHERE nodeid=%d", datatable_tmpname, nd->sql3id);
361 sqlite3_stmt *stmt = NULL;
362 const char *dum;
363 int rc = sqlite3_prepare(mainview->db, tq, strlen(tq), &stmt, &dum);
365 if (rc)
367 fprintf(stderr, "Error reading (1) %s\n", sqlite3_errmsg(mainview->db));
369 else
371 rc = SQLITE_BUSY;
372 while(rc == SQLITE_BUSY || rc == SQLITE_ROW)
374 rc = sqlite3_step(stmt);
375 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE || rc == SQLITE_DONE)
376 break;
377 else if (rc == SQLITE_ROW)
379 nd->typ = sqlite3_column_int(stmt, 0);
380 nd->flags = sqlite3_column_int(stmt, 3);
382 prepareUIforNodeChange(mainview, nd->typ);
383 if (nd->typ == NODE_TEXT)
385 gboolean file_edited_backup = mainview->file_edited;
387 textdata = (char *)sqlite3_column_text(stmt, 1);
388 blobsize = sqlite3_column_bytes(stmt, 1);
390 if (textdata == NULL || g_utf8_validate(textdata, blobsize, NULL) == FALSE)
391 gtk_text_buffer_set_text(GTK_TEXT_BUFFER(mainview->buffer), "", -1);
392 else
394 gtk_text_buffer_set_text(GTK_TEXT_BUFFER(mainview->buffer), textdata, blobsize);
397 gtk_text_buffer_set_modified(GTK_TEXT_BUFFER(mainview->buffer), FALSE);
399 if (file_edited_backup==FALSE) mainview->file_edited=FALSE; /*textview changed event toggles this*/
400 goterr = FALSE;
402 else if (nd->typ == NODE_SKETCH)
404 sketchwidget_wipe_undo(mainview->sk);
405 sketchwidget_set_fillmode(mainview->sk, FALSE);
406 sketchwidget_set_shift(mainview->sk, FALSE);
407 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->shapemenuitems[1]), TRUE);
408 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->shapemenuitems[0]), TRUE);
410 blobsize = sqlite3_column_bytes(stmt, 2);
411 blob = (char *)sqlite3_column_blob(stmt, 2);
412 gboolean clear = TRUE;
414 if (blob == NULL)
415 goterr = FALSE;
416 if (blob != NULL)
418 fprintf(stderr, "blobsize:%d\n", blobsize);
419 GdkPixbufLoader *pl = gdk_pixbuf_loader_new_with_type("png", NULL);
420 GError *err = NULL;
422 gdk_pixbuf_loader_write(pl, (guchar *) blob, blobsize, &err);
423 if (err != NULL)
425 fprintf(stderr, "Error loading sketch! %s\n", err->message);
426 g_error_free(err);
427 err = NULL;
429 gdk_pixbuf_loader_close(pl, NULL);
430 GdkPixbuf *pixbuf = gdk_pixbuf_loader_get_pixbuf(pl);
432 if (GDK_IS_PIXBUF(pixbuf))
434 GtkWidget *skdr = sketchwidget_get_drawingarea(mainview->sk);
435 GtkPixmap *skpix = (GtkPixmap *) sketchwidget_get_Pixmap(mainview->sk);
437 int w=gdk_pixbuf_get_width(pixbuf);
438 int h=gdk_pixbuf_get_height(pixbuf);
439 if (w!=skdr->allocation.width || h!=skdr->allocation.height)
441 if (w>skdr->allocation.width) w=skdr->allocation.width;
442 if (h>skdr->allocation.height) h=skdr->allocation.height;
443 sketchwidget_clear_real(mainview->sk);
445 gdk_draw_pixbuf(GDK_DRAWABLE(skpix), NULL, pixbuf, 0, 0, 0, 0, w, h, GDK_RGB_DITHER_NONE, 0, 0);
447 clear = FALSE;
448 goterr = FALSE;
450 if (skpix && G_IS_OBJECT(skpix)) g_object_unref(skpix);
452 else
454 fprintf(stderr, "error loading pixbuf\n");
456 g_object_unref(pl);
458 if (clear == TRUE)
460 fprintf(stderr, "clearing pix area\n");
461 sketchwidget_clear_real(mainview->sk);
463 gtk_widget_queue_draw(sketchwidget_get_drawingarea(mainview->sk));
466 if ((nd->flags & NODEFLAG_SKETCHLINES) > 0)
467 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->sketchlinesmenuitems[1]), TRUE);
468 else if ((nd->flags & NODEFLAG_SKETCHGRAPH) > 0)
469 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->sketchlinesmenuitems[2]), TRUE);
470 else
472 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->sketchlinesmenuitems[0]), TRUE);
473 callback_sketchlines(NULL, mainview->sketchlinesmenuitems[0]); /*FIXME:ugly */
476 break;
479 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE)
480 fprintf(stderr, "Error reading (2) %s\n", sqlite3_errmsg(mainview->db));
482 sqlite3_finalize(stmt);
485 setBusy(mainview, 2);
487 if (goterr == TRUE)
489 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Error loading memo"));
493 gboolean treeview_canselect(GtkTreeSelection * selection, GtkTreeModel * model, GtkTreePath * path, gboolean path_currently_selected, gpointer userdata)
495 MainView *mainview = NULL;
497 mainview = (MainView *) userdata;
498 g_assert(mainview != NULL && mainview->data != NULL);
500 if (mainview->loading==FALSE)
502 #ifndef EXPANDING_ROWS
503 if (path_currently_selected)
504 return (FALSE);
505 #endif
507 #ifndef NEW_SEL_LOGIC
508 saveCurrentData(mainview);
509 #else
510 if (path_currently_selected)
512 GtkTreeIter iter;
513 gtk_tree_model_get_iter(model, &iter, path);
515 gtk_tree_model_get(model, &iter, NODE_DATA, &(mainview->cansel_node), -1);
516 mainview->cansel_time=time(NULL);
517 /* fprintf(stderr, "[SELLOGIC] canselect called for node %d\n", nd->sql3id);*/
519 #endif
521 return (TRUE);
524 gboolean newnodedlg_key_press_cb(GtkWidget * widget, GdkEventKey * event, GtkWidget * dlg)
526 SketchWidget *s = gtk_object_get_data(GTK_OBJECT(dlg), "sk");
528 switch (event->keyval)
530 case GDK_F7:
531 sketchwidget_redo(s);
532 return TRUE;
533 case GDK_F8:
534 sketchwidget_undo(s);
535 return TRUE;
536 return TRUE;
538 return FALSE;
541 void new_node_dialog(nodeType typ, MainView * mainview)
543 GtkWidget *dialog, *label, *entry, *but_ok, *but_cancel, *vbox, *hbox, *al, *cb, *rb1, *rb2;
545 dialog = gtk_dialog_new();
547 g_signal_connect(G_OBJECT(dialog), "key_press_event", G_CALLBACK(newnodedlg_key_press_cb), dialog);
549 GtkWidget *notebook = gtk_notebook_new();
551 vbox = gtk_vbox_new(FALSE, 0);
552 gtk_container_border_width(GTK_CONTAINER(vbox), 15);
554 hbox = gtk_hbox_new(FALSE, 0);
556 rb1=gtk_radio_button_new_with_label(NULL, _("Text memo"));
557 gtk_box_pack_start(GTK_BOX(hbox), rb1, FALSE, FALSE, 0);
558 gtk_object_set_data(GTK_OBJECT(dialog), "rbt", rb1);
560 rb2=gtk_radio_button_new_with_label(gtk_radio_button_get_group(GTK_RADIO_BUTTON(rb1)), _("Sketch memo"));
561 gtk_box_pack_start(GTK_BOX(hbox), rb2, FALSE, FALSE, 0);
562 gtk_object_set_data(GTK_OBJECT(dialog), "rbs", rb2);
564 if (typ==NODE_TEXT) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rb1), TRUE);
565 else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rb2), TRUE);
567 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
569 label = gtk_label_new(_("Text name"));
570 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, label);
571 label = gtk_label_new(_("Please name the memo:"));
572 entry = gtk_entry_new_with_max_length(64);
573 gtk_entry_set_text(GTK_ENTRY(entry), _("New memo"));
574 gtk_editable_select_region(GTK_EDITABLE(entry), 0, -1);
576 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
577 gtk_box_pack_start(GTK_BOX(vbox), entry, FALSE, FALSE, 0);
579 vbox = gtk_vbox_new(FALSE, 0);
580 gtk_container_border_width(GTK_CONTAINER(vbox), 15);
581 label = gtk_label_new(_("Sketch name"));
582 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, label);
584 label = gtk_label_new(_("Please name the memo:"));
586 al = gtk_alignment_new(0.5, 0.5, 0, 0);
588 SketchWidget *s = sketchwidget_new(SKETCHNODE_X, SKETCHNODE_Y, TRUE);
590 sketchwidget_set_brushsize(s, 2);
591 sketchwidget_set_backstyle(s, SKETCHBACK_GRAPH);
593 gtk_widget_set_size_request(sketchwidget_get_mainwidget(s), SKETCHNODE_X, SKETCHNODE_Y);
594 gtk_container_add(GTK_CONTAINER(al), sketchwidget_get_mainwidget(s));
596 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
597 gtk_box_pack_start(GTK_BOX(vbox), al, FALSE, FALSE, 0);
599 but_ok = gtk_button_new_with_label(_("Create"));
600 but_cancel = gtk_button_new_with_label(_("Cancel"));
601 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area), but_ok);
602 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area), but_cancel);
604 gtk_object_set_user_data(GTK_OBJECT(dialog), entry);
605 gtk_object_set_data(GTK_OBJECT(dialog), "mainview", mainview);
606 gtk_object_set_data(GTK_OBJECT(dialog), "sk", s);
607 gtk_object_set_data(GTK_OBJECT(dialog), "n", notebook);
609 nodeType *tmp = g_malloc(sizeof(nodeType)); /*FIXME memleak:not freed on widget_destroy */
610 *tmp = typ;
611 gtk_object_set_data(GTK_OBJECT(dialog), "t", tmp);
613 gtk_signal_connect_object(GTK_OBJECT(but_cancel), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), dialog);
614 g_signal_connect(G_OBJECT(but_ok), "clicked", G_CALLBACK(callback_new_node_real), dialog);
616 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), notebook);
618 cb = gtk_check_button_new_with_label("Create as childnode");
619 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cb), mainview->newnodedialog_createchild);
620 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), cb);
621 gtk_object_set_data(GTK_OBJECT(dialog), "cb", cb);
623 gtk_widget_grab_focus(entry);
625 gtk_widget_show_all(dialog);
626 gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
629 void add_new_node(nodeData * node, MainView * mainview, gboolean ischild)
631 GtkTreeIter parentiter, newiter;
632 GtkTreeModel *model;
633 void *ptr = NULL;
635 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
637 if (gtk_tree_selection_get_selected(selection, &model, &parentiter))
638 ptr = &parentiter;
640 GtkTreePath *path = NULL;
642 unsigned int parentnodeid = 0;
644 if (ptr != NULL)
646 path = gtk_tree_model_get_path(model, &parentiter);
648 if (ischild == FALSE)
650 gboolean tmp = gtk_tree_path_up(path);
652 if (gtk_tree_path_get_depth(path) > 0)
654 if (gtk_tree_model_get_iter(model, &parentiter, path))
655 ptr = &parentiter;
657 else if (tmp == TRUE)
659 gtk_tree_path_down(path); /*restore path so expand() works */
664 if (ptr != NULL)
666 nodeData *nd;
668 gtk_tree_model_get(model, ptr, NODE_DATA, &nd, -1);
669 if (nd)
670 parentnodeid = nd->sql3id;
673 node->sql3id = 0;
676 sqlite3_stmt *stmt = NULL;
677 const char *dum;
678 char tq[512];
681 * FIXME: ord
683 snprintf(tq, sizeof(tq), "INSERT INTO %s (parent, bodytype, name, nameblob, ord) VALUES (%d, %d, ?, ?, 0);", datatable_tmpname, parentnodeid, node->typ);
684 int rc = sqlite3_prepare(mainview->db, tq, strlen(tq), &stmt, &dum);
686 if (rc)
688 fprintf(stderr, "Error inserting(1): %s\n", sqlite3_errmsg(mainview->db));
689 break;
691 if (node->name != NULL)
692 sqlite3_bind_text(stmt, 1, node->name, strlen(node->name), SQLITE_TRANSIENT);
693 else
694 sqlite3_bind_text(stmt, 1, NULL, 0, SQLITE_TRANSIENT);
696 if (node->namepix != NULL)
698 gchar *namepixdata = NULL;
699 gsize datalen = 0;
701 GError *err = NULL;
703 if (gdk_pixbuf_save_to_buffer(node->namepix, &namepixdata, &datalen, "png", &err, NULL) == FALSE)
705 namepixdata = NULL;
706 datalen = 0;
707 fprintf(stderr, "Error saving name! %s\n", err->message);
708 g_error_free(err);
710 sqlite3_bind_blob(stmt, 2, namepixdata, datalen, SQLITE_TRANSIENT);
712 else
713 sqlite3_bind_blob(stmt, 2, NULL, 0, SQLITE_TRANSIENT);
715 rc = SQLITE_BUSY;
716 while(rc == SQLITE_BUSY)
718 rc = sqlite3_step(stmt);
719 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE || rc == SQLITE_DONE)
720 break;
722 sqlite3_finalize(stmt);
723 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE)
725 fprintf(stderr, "Error inserting(2): %s\n", sqlite3_errmsg(mainview->db));
726 break;
728 node->sql3id = sqlite3_last_insert_rowid(mainview->db);
730 while(FALSE);
732 if (node->sql3id == 0)
734 if (node->name)
735 g_free(node->name);
736 if (node->namepix)
737 g_object_unref(node->namepix);
738 g_free(node);
739 if (path)
740 gtk_tree_path_free(path);
741 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, "Error creating node");
742 return;
745 fprintf(stderr, "new node id is %d\n", node->sql3id);
748 gtk_tree_store_append(GTK_TREE_STORE(model), &newiter, ptr);
750 gtk_tree_store_set(GTK_TREE_STORE(model), &newiter, NODE_NAME, node->name, NODE_PIXBUF, node->namepix, NODE_DATA, node, -1);
752 if (path)
754 mainview->loading=TRUE; /*only when we have a valid parent*/
755 gtk_tree_view_expand_row(GTK_TREE_VIEW(mainview->treeview), path, FALSE);
756 gtk_tree_path_free(path);
759 gtk_tree_selection_select_iter(selection, &newiter);
761 mainview->loading=FALSE;
764 void callback_new_node_real(GtkAction * action, gpointer data)
766 MainView *mainview;
768 GtkWidget *dialog = data;
769 GtkWidget *entry = gtk_object_get_user_data(GTK_OBJECT(dialog));
771 mainview = gtk_object_get_data(GTK_OBJECT(dialog), "mainview");
772 SketchWidget *s = gtk_object_get_data(GTK_OBJECT(dialog), "sk");
773 GtkWidget *notebook = gtk_object_get_data(GTK_OBJECT(dialog), "n");
774 GtkWidget *cb = gtk_object_get_data(GTK_OBJECT(dialog), "cb");
775 /* nodeType *typ = gtk_object_get_data(GTK_OBJECT(dialog), "t");*/
777 nodeType typ = NODE_TEXT;
779 /* GtkWidget *rbt = gtk_object_get_data(GTK_OBJECT(dialog), "rbt");*/
780 GtkWidget *rbs = gtk_object_get_data(GTK_OBJECT(dialog), "rbs");
781 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rbs))) typ=NODE_SKETCH;
784 gint t = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
786 gchar *txt = NULL;
787 GdkPixbuf *pixbuf = NULL;
789 if (t == 0)
791 txt = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
792 if (strcmp(txt, "") == 0)
794 g_free(txt);
795 return;
798 else
800 GtkWidget *sdr = sketchwidget_get_drawingarea(s);
802 GdkPixmap *spix = sketchwidget_get_Pixmap(s);
804 pixbuf = gdk_pixbuf_get_from_drawable(NULL, GDK_DRAWABLE(spix), NULL, 0, 0, 0, 0, sdr->allocation.width, sdr->allocation.height);
805 g_object_unref(spix);
806 double w, h;
807 GdkPixbuf *pixbuf2 = sketchwidget_trim_image(pixbuf, SKETCHNODE_X, SKETCHNODE_Y, &w,
808 &h, TRUE);
809 if (pixbuf2==NULL) return;
811 GdkPixbuf *pixbuf3 = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, SKETCHNODE_RX,
812 SKETCHNODE_RY);
814 gdk_pixbuf_fill(pixbuf3, 0xffffffff);
816 if (w <= SKETCHNODE_RX && h <= SKETCHNODE_RY)
818 gdk_pixbuf_copy_area(pixbuf2, 0, 0, w, h, pixbuf3, 0, (SKETCHNODE_RY - h) / 2);
820 else
822 double neww, newh;
824 if (w > h)
826 neww = SKETCHNODE_RX;
827 newh = (h / w) * SKETCHNODE_RX;
829 else
831 newh = SKETCHNODE_RY;
832 neww = (w / h) * SKETCHNODE_RY;
834 if (newh > SKETCHNODE_RY)
835 newh = SKETCHNODE_RY; /*FIXME: newh exceeds SKETCHNODE_RY sometimes */
837 GdkPixbuf *tmpbuf = gdk_pixbuf_scale_simple(pixbuf2, neww, newh,
838 GDK_INTERP_BILINEAR);
840 gdk_pixbuf_copy_area(tmpbuf, 0, 0, neww, newh, pixbuf3, 0, (SKETCHNODE_RY - newh) / 2);
842 gdk_pixbuf_unref(tmpbuf);
845 pixbuf = pixbuf3;
846 gdk_pixbuf_unref(pixbuf2);
849 nodeData *node;
851 node = g_malloc(sizeof(nodeData));
852 node->typ = typ;
853 /* node->typ = *typ;
854 g_free(typ);*/
855 node->name = NULL;
856 node->namepix = NULL;
858 if (t == 0)
860 node->name = txt;
862 else if (t == 1)
864 node->namepix = pixbuf;
867 node->lastMod = 0;
868 node->flags = 0;
869 node->sql3id = 0;
871 mainview->newnodedialog_createchild = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cb));
872 add_new_node(node, mainview, mainview->newnodedialog_createchild);
874 sketchwidget_destroy(s);
875 gtk_widget_destroy(dialog);
876 mainview->file_edited = TRUE;
880 * delete node
882 void callback_file_delete_node(GtkAction * action, gpointer data)
884 MainView *mainview = NULL;
886 mainview = (MainView *) data;
887 g_assert(mainview != NULL && mainview->data != NULL);
889 if (getSelectedNode(mainview) == NULL)
891 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Select a node first"));
892 return;
895 GtkWidget *dialog, *label, *but_ok, *but_cancel;
897 dialog = gtk_dialog_new();
899 label = gtk_label_new(_("Are you sure?"));
901 but_ok = gtk_button_new_with_label(_("Yes, Delete"));
902 but_cancel = gtk_button_new_with_label(_("Cancel"));
904 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area), but_ok);
905 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area), but_cancel);
907 gtk_object_set_user_data(GTK_OBJECT(dialog), mainview);
909 gtk_signal_connect_object(GTK_OBJECT(but_cancel), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), dialog);
910 g_signal_connect(G_OBJECT(but_ok), "clicked", G_CALLBACK(callback_delete_node_real), dialog);
912 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
914 gtk_widget_show_all(dialog);
915 gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
918 void callback_file_expand_collapse_node(GtkAction * action, gpointer data)
920 MainView *mainview = NULL;
922 mainview = (MainView *) data;
923 g_assert(mainview != NULL && mainview->data != NULL);
925 GtkTreeIter iter;
926 GtkTreeModel *model;
928 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
930 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
932 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Select a node first"));
933 return;
936 GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
937 if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(mainview->treeview), path)==FALSE)
939 gtk_tree_view_expand_row(GTK_TREE_VIEW(mainview->treeview), path, FALSE);
941 else
943 gtk_tree_view_collapse_row(GTK_TREE_VIEW(mainview->treeview), path);
946 gtk_tree_path_free(path);
949 void callback_file_export_node(GtkAction * action, gpointer data)
951 MainView *mainview = NULL;
953 mainview = (MainView *) data;
954 g_assert(mainview != NULL && mainview->data != NULL);
956 nodeData *nd=getSelectedNode(mainview);
957 if (nd == NULL)
959 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Select a node first"));
960 return;
963 gchar *nodename=nd->name;
964 if (nodename==NULL) nodename="saved node";
966 if (nd->typ == NODE_TEXT)
968 GtkTextIter begin, end;
969 gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER(mainview->buffer), &begin, &end);
970 gchar *text = gtk_text_buffer_get_slice(GTK_TEXT_BUFFER(mainview->buffer), &begin, &end, TRUE);
971 if (text==NULL || !strcmp(text, ""))
973 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Node is empty"));
975 else
977 gchar *fn = interface_file_chooser(mainview, GTK_FILE_CHOOSER_ACTION_SAVE, nodename, "txt");
978 if (fn!=NULL)
980 GnomeVFSResult vfs_result;
981 GnomeVFSHandle *handle = NULL;
982 GnomeVFSFileSize out_bytes;
983 vfs_result = gnome_vfs_create(&handle, fn, GNOME_VFS_OPEN_WRITE, 0, 0600);
984 if ( vfs_result != GNOME_VFS_OK ) {
985 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Export failed"));
987 else
989 gnome_vfs_write(handle, text, strlen(text), &out_bytes);
990 gnome_vfs_close(handle);
991 if (out_bytes==strlen(text)) hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Exported"));
992 else hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Export incomplete"));
994 g_free(fn);
997 g_free(text);
999 else if (nd->typ == NODE_SKETCH)
1001 GdkPixmap *skpix = sketchwidget_get_Pixmap(mainview->sk);
1002 GtkWidget *skdr = sketchwidget_get_drawingarea(mainview->sk);
1003 GdkPixbuf *pixbuf = gdk_pixbuf_get_from_drawable(NULL, GDK_DRAWABLE(skpix), NULL, 0, 0, 0, 0, skdr->allocation.width, skdr->allocation.height);
1004 if (pixbuf==NULL)
1006 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Node is empty"));
1008 else
1010 gchar *fn = interface_file_chooser(mainview, GTK_FILE_CHOOSER_ACTION_SAVE, nodename, "png");
1011 if (fn!=NULL)
1013 if (gdk_pixbuf_save(pixbuf, fn, "png", NULL, NULL)==FALSE)
1015 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Export failed"));
1017 else
1019 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Exported"));
1021 g_free(fn);
1024 g_object_unref(skpix);
1028 gboolean ref2iter(GtkTreeModel * model, GtkTreeRowReference * ref, GtkTreeIter * iter)
1030 gboolean res = FALSE;
1031 GtkTreePath *path = gtk_tree_row_reference_get_path(ref);
1033 if (gtk_tree_model_get_iter(model, iter, path))
1035 res = TRUE;
1037 gtk_tree_path_free(path);
1038 return (res);
1041 GtkTreeRowReference *iter2ref(GtkTreeModel * model, GtkTreeIter * iter)
1043 GtkTreeRowReference *ref;
1045 GtkTreePath *path = gtk_tree_model_get_path(model, iter);
1047 ref = gtk_tree_row_reference_new(model, path);
1048 gtk_tree_path_free(path);
1049 return (ref);
1052 void move_nodes_up(GtkTreeModel * model, GtkTreeRowReference * topnode, GtkTreeRowReference * newtop)
1054 GtkTreeIter topiter;
1056 fprintf(stderr, "here2\n");
1058 if (ref2iter(model, topnode, &topiter) == FALSE)
1059 return;
1061 fprintf(stderr, "here3\n");
1063 GtkTreeIter child;
1065 if (gtk_tree_model_iter_children(model, &child, &topiter))
1067 fprintf(stderr, "here4\n");
1068 GtkTreeRowReference *ref;
1069 GList *rr_list = NULL, *node;
1073 ref = iter2ref(model, &child);
1074 rr_list = g_list_append(rr_list, ref);
1076 while(gtk_tree_model_iter_next(model, &child));
1079 * got a reflist for all children
1082 fprintf(stderr, "here5\n");
1083 for(node = rr_list; node; node = node->next)
1085 ref = (GtkTreeRowReference *) (node->data);
1086 if (ref2iter(model, ref, &child))
1088 GtkTreeIter newtopiter, newiter;
1089 GtkTreeIter *newtopiterptr;
1091 if (ref2iter(model, newtop, &newtopiter))
1092 newtopiterptr = &newtopiter;
1093 else
1094 newtopiterptr = NULL;
1096 nodeData *node;
1098 gtk_tree_model_get(model, &child, NODE_DATA, &node, -1);
1100 gtk_tree_store_append(GTK_TREE_STORE(model), &newiter, newtopiterptr);
1101 gtk_tree_store_set(GTK_TREE_STORE(model), &newiter, NODE_NAME, node->name, NODE_PIXBUF, node->namepix, NODE_DATA, node, -1);
1103 GtkTreeRowReference *newref = iter2ref(model, &newiter);
1105 move_nodes_up(model, ref, newref);
1106 gtk_tree_row_reference_free(newref);
1108 gtk_tree_store_remove(GTK_TREE_STORE(model), &child);
1110 gtk_tree_row_reference_free(ref);
1112 fprintf(stderr, "here6\n");
1114 g_list_free(rr_list);
1117 fprintf(stderr, "here7\n");
1121 void callback_delete_node_real(GtkAction * action, gpointer data)
1123 MainView *mainview;
1125 GtkWidget *dialog = data;
1127 mainview = gtk_object_get_user_data(GTK_OBJECT(dialog));
1129 GtkTreeIter iter;
1130 GtkTreeModel *model;
1132 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
1134 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
1135 return;
1137 nodeData *nd;
1139 gtk_tree_model_get(model, &iter, NODE_DATA, &nd, -1);
1140 if (!nd)
1141 return;
1143 mainview->file_edited = TRUE;
1145 unsigned int sql3id = nd->sql3id;
1147 if (nd->name)
1148 g_free(nd->name);
1151 * g_free(nd->data);
1152 * if (nd->pix) g_object_unref(nd->pix);
1154 g_free(nd);
1156 fprintf(stderr, "here1\n");
1157 GtkTreeRowReference *upref = NULL, *ref = NULL;
1159 GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
1161 ref = gtk_tree_row_reference_new(model, path);
1162 if (gtk_tree_path_up(path))
1163 upref = gtk_tree_row_reference_new(model, path);
1164 gtk_tree_path_free(path);
1166 g_object_ref(model);
1167 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->treeview), NULL);
1169 fprintf(stderr, "here! 1\n");
1170 move_nodes_up(model, ref, upref);
1172 fprintf(stderr, "here! 2\n");
1173 if (ref2iter(model, ref, &iter))
1175 char tq[512];
1177 snprintf(tq, sizeof(tq), "SELECT parent FROM %s WHERE nodeid=%d", datatable_tmpname, sql3id);
1178 sqlite3_stmt *stmt = NULL;
1179 const char *dum;
1180 int rc = sqlite3_prepare(mainview->db, tq, strlen(tq), &stmt, &dum);
1181 unsigned int sql3parentid = 0;
1183 if (rc)
1185 fprintf(stderr, "Error %s\n", sqlite3_errmsg(mainview->db));
1187 else
1189 rc = SQLITE_BUSY;
1190 while(rc == SQLITE_BUSY || rc == SQLITE_ROW)
1192 rc = sqlite3_step(stmt);
1193 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE || rc == SQLITE_DONE)
1194 break;
1195 else if (rc == SQLITE_ROW)
1197 sql3parentid = sqlite3_column_int(stmt, 0);
1198 break;
1201 sqlite3_finalize(stmt);
1203 snprintf(tq, sizeof(tq), "UPDATE %s SET parent=%d WHERE parent=%d;", datatable_tmpname, sql3parentid, sql3id);
1204 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
1205 fprintf(stderr, "ERROR moving nodes up!\n");
1206 else
1208 snprintf(tq, sizeof(tq), "DELETE FROM %s WHERE nodeid=%d;", datatable_tmpname, sql3id);
1209 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
1210 fprintf(stderr, "ERROR deleting node!\n");
1213 gtk_tree_store_remove(GTK_TREE_STORE(model), &iter);
1216 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->treeview), model);
1217 g_object_unref(model);
1219 fprintf(stderr, "here! 3\n");
1220 gtk_tree_row_reference_free(ref);
1221 gtk_tree_row_reference_free(upref);
1223 gtk_tree_view_expand_all(GTK_TREE_VIEW(mainview->treeview));
1225 fprintf(stderr, "here10\n");
1226 gtk_widget_destroy(dialog);
1229 void callback_edit_clear(GtkAction * action, gpointer data)
1231 MainView *mainview = NULL;
1233 mainview = (MainView *) data;
1234 g_assert(mainview != NULL && mainview->data != NULL);
1236 nodeData *nd = getSelectedNode(mainview);
1238 if (nd->typ == NODE_TEXT) gtk_text_buffer_set_text(GTK_TEXT_BUFFER(mainview->buffer), "", 0);
1239 else if (nd->typ == NODE_SKETCH) sketchwidget_clear(mainview->sk);
1243 * cut
1245 void callback_edit_cut(GtkAction * action, gpointer data)
1247 MainView *mainview = NULL;
1249 mainview = (MainView *) data;
1250 g_assert(mainview != NULL && mainview->data != NULL);
1252 nodeData *nd = getSelectedNode(mainview);
1254 if (nd->typ == NODE_TEXT)
1255 gtk_text_buffer_cut_clipboard(GTK_TEXT_BUFFER(mainview->buffer), mainview->clipboard, TRUE);
1256 else if (nd->typ == NODE_SKETCH)
1257 if (sketchwidget_cut(mainview->sk, mainview->clipboard)==FALSE)
1258 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Error cutting"));
1262 * copy
1264 void callback_edit_copy(GtkAction * action, gpointer data)
1267 * connect pointer to our MainView struct
1269 MainView *mainview = NULL;
1271 mainview = (MainView *) data;
1272 g_assert(mainview != NULL && mainview->data != NULL);
1274 nodeData *nd = getSelectedNode(mainview);
1276 if (nd->typ == NODE_TEXT)
1277 gtk_text_buffer_copy_clipboard(GTK_TEXT_BUFFER(mainview->buffer), mainview->clipboard);
1278 else if (nd->typ == NODE_SKETCH)
1279 if (sketchwidget_copy(mainview->sk, mainview->clipboard)==FALSE)
1280 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Error copying"));
1284 * paste
1286 void callback_edit_paste(GtkAction * action, gpointer data)
1289 * connect pointer to our MainView struct
1291 MainView *mainview = NULL;
1293 mainview = (MainView *) data;
1294 g_assert(mainview != NULL && mainview->data != NULL);
1296 nodeData *nd = getSelectedNode(mainview);
1298 if (nd->typ == NODE_TEXT)
1299 gtk_text_buffer_paste_clipboard(GTK_TEXT_BUFFER(mainview->buffer), mainview->clipboard, NULL, TRUE);
1300 else if (nd->typ == NODE_SKETCH)
1301 if (sketchwidget_paste(mainview->sk, mainview->clipboard)==FALSE)
1302 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Error pasting"));
1304 mainview->file_edited = TRUE;
1307 gint cb_popup(GtkWidget * widget, GdkEvent * event)
1309 GtkMenu *menu;
1310 GdkEventButton *event_button;
1313 * The "widget" is the menu that was supplied when
1314 * * g_signal_connect_swapped() was called.
1316 menu = GTK_MENU(widget);
1317 event_button = (GdkEventButton *) event;
1318 if (event->type == GDK_BUTTON_PRESS && event_button->button == 3)
1320 gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event_button->button, event_button->time);
1321 return TRUE;
1323 return FALSE;
1327 * close
1329 gboolean closefile(MainView * mainview)
1331 saveCurrentData(mainview);
1333 if (mainview->file_edited)
1335 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));
1336 gint answer = gtk_dialog_run(GTK_DIALOG(hn));
1337 gtk_widget_destroy(GTK_WIDGET(hn));
1339 if (answer == CONFRESP_CANCEL)
1340 return (FALSE);
1341 else if (answer == CONFRESP_YES)
1343 if (mainview->file_name == NULL)
1345 mainview->file_name = interface_file_chooser(mainview, GTK_FILE_CHOOSER_ACTION_SAVE, "maemopaddata", "db");
1347 write_buffer_to_file(mainview);
1351 if (mainview->db)
1352 sqlite3_close(mainview->db);
1353 mainview->db = NULL;
1354 return (TRUE);
1357 gboolean callback_file_close(GtkAction * action, gpointer data)
1360 MainView *mainview = NULL;
1362 mainview = (MainView *) data;
1363 g_assert(mainview != NULL && mainview->data != NULL);
1364 if (closefile(mainview) == FALSE)
1365 return(FALSE);
1367 gtk_main_quit();
1368 return(TRUE);
1371 void callback_file_new_node(GtkAction * action, gpointer data)
1373 MainView *mainview = NULL;
1375 mainview = (MainView *) data;
1376 g_assert(mainview != NULL && mainview->data != NULL);
1378 nodeType typ = NODE_SKETCH;
1380 nodeData *nd = getSelectedNode(mainview);
1382 if (nd != NULL)
1383 typ = nd->typ;
1385 new_node_dialog(typ, mainview);
1389 * new
1391 void callback_file_new(GtkAction * action, gpointer data)
1393 MainView *mainview = NULL;
1395 mainview = (MainView *) data;
1396 g_assert(mainview != NULL && mainview->data != NULL);
1398 gchar *filename = NULL;
1400 if (closefile(mainview) == FALSE)
1401 return;
1403 filename = interface_file_chooser(mainview, GTK_FILE_CHOOSER_ACTION_SAVE, "memos", "db");
1404 if (filename == NULL)
1405 return;
1407 new_file(mainview);
1411 setBusy(mainview, 1);
1413 int rc;
1415 rc = sqlite3_open(filename, &mainview->db);
1416 if (rc)
1418 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Error 1"));
1419 fprintf(stderr, "Can't create database %s: %s\n", filename, sqlite3_errmsg(mainview->db));
1420 break;
1422 char tq[512];
1424 snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", misctable_name, misctable);
1425 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
1427 snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", datatable_name, datatable);
1428 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
1430 fprintf(stderr, "ERROR creating data table\n");
1431 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Error 2"));
1432 break;
1435 if (mainview->db)
1436 sqlite3_close(mainview->db);
1437 mainview->db = NULL;
1439 mainview->file_name = filename;
1440 mainview->file_edited = FALSE;
1441 read_file_to_buffer(mainview);
1443 /*add a starter memo*/
1444 nodeData *node;
1445 node = g_malloc(sizeof(nodeData));
1446 node->typ = NODE_SKETCH;
1447 node->name = _("My first memo");
1448 node->namepix = NULL;
1449 node->lastMod = 0;
1450 node->flags = 0;
1451 node->sql3id = 0;
1452 add_new_node(node, mainview, TRUE);
1453 gtk_paned_set_position(GTK_PANED(mainview->hpaned), 180);
1454 mainview->viewflags = 3;
1455 callback_setview(mainview, 1);
1456 write_buffer_to_file(mainview);
1458 }while(FALSE);
1459 setBusy(mainview, 0);
1462 gboolean reset_ctree(GtkTreeModel * model, GtkTreePath * path, GtkTreeIter * iter, gpointer data)
1464 nodeData *node;
1466 gtk_tree_model_get(model, iter, NODE_DATA, &node, -1);
1467 if (node)
1469 if (node->name)
1470 g_free(node->name);
1471 if (node->namepix)
1472 g_object_unref(node->namepix);
1473 g_free(node);
1475 gtk_tree_store_set(GTK_TREE_STORE(model), iter, NODE_DATA, NULL, -1);
1477 return (FALSE);
1480 void new_file(MainView * mainview)
1482 setBusy(mainview, 1);
1484 * clear buffer, filename and free buffer text
1486 gtk_text_buffer_set_text(GTK_TEXT_BUFFER(mainview->buffer), "", -1);
1487 mainview->file_name = NULL;
1488 mainview->file_edited = FALSE;
1489 mainview->newnodedialog_createchild = TRUE;
1491 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->treeview));
1493 g_object_ref(model);
1494 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->treeview), NULL);
1496 gtk_tree_model_foreach(model, (GtkTreeModelForeachFunc) reset_ctree, (gpointer) mainview);
1499 * crashing bastard
1500 * gtk_tree_store_clear(GTK_TREE_STORE(model));
1502 GtkTreePath *path = gtk_tree_path_new_from_indices(0, -1);
1503 GtkTreeIter iter;
1505 if (gtk_tree_model_get_iter(model, &iter, path))
1509 gtk_tree_store_remove(GTK_TREE_STORE(model), &iter);
1511 while(gtk_tree_store_iter_is_valid(GTK_TREE_STORE(model), &iter));
1513 gtk_tree_path_free(path);
1515 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->treeview), model);
1516 g_object_unref(model);
1518 prepareUIforNodeChange(mainview, NODE_UNKNOWN);
1519 setBusy(mainview, 2);
1523 * open
1525 void callback_file_open(GtkAction * action, gpointer data)
1527 gchar *filename = NULL;
1528 MainView *mainview = NULL;
1530 mainview = (MainView *) data;
1531 g_assert(mainview != NULL && mainview->data != NULL);
1533 if (closefile(mainview) == FALSE)
1534 return;
1537 * open new file
1539 filename = interface_file_chooser(mainview, GTK_FILE_CHOOSER_ACTION_OPEN, NULL, NULL);
1542 * if we got a file name from chooser -> open file
1544 open_file(filename, mainview);
1545 g_free(filename);
1548 gboolean open_file(gchar * filename, MainView * mainview)
1550 gboolean ret=FALSE;
1552 setBusy(mainview, 1);
1554 while(filename != NULL)
1556 struct stat s;
1558 if (stat(filename, &s) == -1) break;
1560 mainview->file_name = g_strdup(filename);
1561 gboolean res = read_file_to_buffer(mainview);
1563 if (res == FALSE)
1565 g_free(mainview->file_name);
1566 mainview->file_name = NULL;
1567 break;
1569 mainview->file_edited = FALSE;
1570 ret=TRUE;
1571 break;
1574 setBusy(mainview, 2);
1575 return(ret);
1578 void callback_about_link(GtkAction * action, gpointer data)
1580 MainView *mainview = NULL;
1582 mainview = (MainView *) data;
1583 g_assert(mainview != NULL && mainview->data != NULL);
1585 osso_rpc_run_with_defaults(mainview->data->osso, "osso_browser", OSSO_BROWSER_OPEN_NEW_WINDOW_REQ, NULL,
1586 DBUS_TYPE_STRING, "http://garage.maemo.org/projects/maemopadplus/", DBUS_TYPE_INVALID);
1589 void callback_about(GtkAction * action, gpointer data)
1591 #if 1
1592 MainView *mainview = NULL;
1593 mainview = (MainView *) data;
1595 GtkWidget *w, *d;
1597 d = gtk_dialog_new();
1598 gtk_container_border_width(GTK_CONTAINER(d), 15);
1600 char tmp[32];
1602 snprintf(tmp, sizeof(tmp), "Maemopad+ %s", VERSION);
1603 w = gtk_button_new_with_label(tmp);
1604 g_object_set(w, "relief", GTK_RELIEF_NONE, NULL);
1605 g_object_set(w, "focus-on-click", FALSE, NULL);
1606 g_signal_connect(G_OBJECT(w), "clicked", G_CALLBACK(callback_about_link), mainview);
1607 gtk_container_add (GTK_CONTAINER(GTK_DIALOG(d)->vbox), w);
1609 w = gtk_label_new("\nLicense: LGPL\nAuthor: Kemal 'disq' Hadimli <disqkk@gmail.com>\n");
1610 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(d)->vbox), w);
1612 w = gtk_button_new_with_label(_("Close"));
1613 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(d)->action_area), w);
1614 gtk_signal_connect_object(GTK_OBJECT(w), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), d);
1616 gtk_widget_show_all(d);
1617 gtk_window_set_modal(GTK_WINDOW(d), TRUE);
1619 #else
1621 MainView *mainview=(MainView *)data;
1622 const char *authors[]={"Kemal 'disq' Hadimli <disqkk@gmail.com>", NULL};
1623 gtk_show_about_dialog(GTK_WINDOW(mainview->data->main_view), "name", "Maemopad+", "authors", authors, "copyright", "\xc2\xa9 2006 Kemal 'disq' Hadimli <disqkk@gmail.com>", "license", "GPL", "version", VERSION, "website", "http://garage.maemo.org/projects/maemopadplus/", "comments", "Based on Nokia's MaemoPad", NULL);
1625 #endif
1629 * save
1631 void callback_file_save(GtkAction * action, gpointer data)
1633 gchar *filename = NULL;
1634 MainView *mainview = NULL;
1636 mainview = (MainView *) data;
1637 g_assert(mainview != NULL && mainview->data != NULL);
1640 * check is we had a new file
1642 if (mainview->file_name != NULL)
1644 write_buffer_to_file(mainview);
1646 else
1648 filename = interface_file_chooser(mainview, GTK_FILE_CHOOSER_ACTION_SAVE, "maemopaddata", "db");
1650 * if we got a file name from chooser -> save file
1652 if (filename != NULL)
1654 mainview->file_name = filename;
1655 write_buffer_to_file(mainview);
1656 mainview->file_edited = FALSE;
1661 void callback_shapemenu(GtkAction * action, GtkWidget * wid)
1663 int style = (int)gtk_object_get_user_data(GTK_OBJECT(wid));
1664 MainView *mainview = gtk_object_get_data(GTK_OBJECT(wid), "mainview");
1666 g_assert(mainview != NULL);
1668 if (style==0) sketchwidget_set_shape(mainview->sk, SKETCHSHAPE_FREEHAND);
1669 else if (style==1) sketchwidget_set_shape(mainview->sk, SKETCHSHAPE_LINE);
1670 else if (style==2) sketchwidget_set_shape(mainview->sk, SKETCHSHAPE_RECT);
1671 else if (style==3) sketchwidget_set_shape(mainview->sk, SKETCHSHAPE_ELLIPSE);
1676 void callback_eraser(GtkAction * action, MainView * mainview)
1678 g_assert(mainview != NULL && mainview->data != NULL);
1680 if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(mainview->eraser_tb)) == TRUE)
1682 GdkColor c2;
1684 c2.red = 65535;
1685 c2.green = 65535;
1686 c2.blue = 65535;
1688 sketchwidget_set_brushcolor(mainview->sk, c2);
1689 mainview->brushsize_backup = sketchwidget_get_brushsize(mainview->sk);
1690 guint ers=(mainview->brushsize_backup*4)+4;
1691 sk_set_brushsize(mainview, ers);
1692 sketchwidget_set_brushsize(mainview->sk, ers); /*fixme:to override max brush size, not pretty*/
1694 else
1696 GdkColor *col = hildon_color_button_get_color(HILDON_COLOR_BUTTON(mainview->colorbutton));
1698 GdkColor c2;
1700 c2.red = col->red;
1701 c2.green = col->green;
1702 c2.blue = col->blue;
1704 sketchwidget_set_brushcolor(mainview->sk, c2);
1705 sk_set_brushsize(mainview, mainview->brushsize_backup);
1709 void callback_toggletree(GtkAction * action, MainView * mainview)
1711 g_assert(mainview != NULL && mainview->data != NULL);
1713 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)));
1715 if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(mainview->toggletree_tb))==TRUE)
1716 mainview->viewflags |= 1;
1717 else
1718 mainview->viewflags &= ~1;
1720 callback_setview(mainview, 0);
1723 void callback_menu(GtkAction * action, GtkWidget * menu)
1725 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0, GDK_CURRENT_TIME);
1728 void callback_brushsizetb(GtkAction * action, MainView *mainview)
1730 g_assert(mainview != NULL && mainview->data != NULL);
1732 if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(mainview->eraser_tb)) == TRUE)
1734 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->eraser_tb), FALSE);
1736 else
1738 callback_menu(NULL, mainview->brushsizemenu);
1742 void callback_brushsize(GtkAction * action, GtkWidget * wid)
1744 int bsize = (int)gtk_object_get_user_data(GTK_OBJECT(wid));
1745 MainView *mainview = gtk_object_get_data(GTK_OBJECT(wid), "mainview");
1747 g_assert(mainview != NULL && mainview->data != NULL);
1749 sketchwidget_set_brushsize(mainview->sk, bsize);
1751 GtkWidget *pix = gtk_object_get_data(GTK_OBJECT(wid), "icon");
1753 gtk_widget_show(pix);
1754 gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(mainview->brushsize_tb), pix);
1757 void callback_sketchlines(GtkAction * action, GtkWidget * wid)
1759 int style = (int)gtk_object_get_user_data(GTK_OBJECT(wid));
1760 MainView *mainview = gtk_object_get_data(GTK_OBJECT(wid), "mainview");
1762 g_assert(mainview != NULL);
1764 nodeData *nd = getSelectedNode(mainview);
1765 gboolean doit = FALSE;
1767 if (nd != NULL && nd->typ == NODE_SKETCH)
1769 nd->flags &= ~NODEFLAG_SKETCHLINES;
1770 nd->flags &= ~NODEFLAG_SKETCHGRAPH;
1771 /* sketchwidget_set_edited(mainview->sk, TRUE);*/ /*we call this on openfile, so this messes things up*/
1772 doit = TRUE;
1775 if (style == 0)
1777 sketchwidget_set_backstyle(mainview->sk, SKETCHBACK_NONE);
1779 else if (style == 1)
1781 sketchwidget_set_backstyle(mainview->sk, SKETCHBACK_LINES);
1782 if (doit == TRUE)
1783 nd->flags |= NODEFLAG_SKETCHLINES;
1785 else if (style == 2)
1787 sketchwidget_set_backstyle(mainview->sk, SKETCHBACK_GRAPH);
1788 if (doit == TRUE)
1789 nd->flags |= NODEFLAG_SKETCHGRAPH;
1792 GtkWidget *pix = gtk_object_get_data(GTK_OBJECT(wid), "icon");
1794 gtk_widget_show(pix);
1795 gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(mainview->sketchlines_tb), pix);
1798 void callback_color(HildonColorButton * colorButton, MainView * mainview)
1800 g_assert(mainview != NULL && mainview->data != NULL);
1802 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->eraser_tb), FALSE);
1804 GdkColor *col = hildon_color_button_get_color(colorButton);
1806 GdkColor c2;
1808 c2.red = col->red;
1809 c2.green = col->green;
1810 c2.blue = col->blue;
1812 sketchwidget_set_brushcolor(mainview->sk, c2);
1815 void callback_color_invoke(GtkAction * action, gpointer data)
1817 MainView *mainview = NULL;
1819 mainview = (MainView *) data;
1820 g_assert(mainview != NULL && mainview->data != NULL);
1822 HildonColorButton *hc = HILDON_COLOR_BUTTON(mainview->colorbutton);
1824 gtk_button_clicked(GTK_BUTTON(&hc->button));
1828 * font
1830 void callback_font(GtkAction * action, gpointer data)
1832 PangoFontDescription *new_font = NULL;
1833 MainView *mainview = NULL;
1835 mainview = (MainView *) data;
1836 g_assert(mainview != NULL && mainview->data != NULL);
1838 nodeData *nd = getSelectedNode(mainview);
1840 if (nd == NULL)
1841 return;
1842 if (nd->typ == NODE_SKETCH)
1843 return;
1845 new_font = interface_font_chooser(mainview);
1848 * if we got a new font from chooser -> change font
1850 if (new_font != NULL)
1852 mainview->font_desc = new_font;
1853 gtk_widget_modify_font(mainview->textview, mainview->font_desc);
1857 void callback_undo(GtkAction * action, MainView * mainview)
1859 g_assert(mainview != NULL && mainview->data != NULL);
1861 nodeData *nd = getSelectedNode(mainview);
1863 if (nd == NULL || nd->typ != NODE_SKETCH)
1864 return;
1866 sketchwidget_undo(mainview->sk);
1869 void callback_redo(GtkAction * action, MainView * mainview)
1871 g_assert(mainview != NULL && mainview->data != NULL);
1873 nodeData *nd = getSelectedNode(mainview);
1875 if (nd == NULL || nd->typ != NODE_SKETCH)
1876 return;
1878 sketchwidget_redo(mainview->sk);
1881 void callback_undotoggle(SketchWidget * sk, gboolean st, MainView * mainview)
1883 g_assert(mainview != NULL && mainview->data != NULL);
1885 gtk_widget_set_sensitive(GTK_WIDGET(mainview->undo_tb), st);
1888 void callback_redotoggle(SketchWidget * sk, gboolean st, MainView * mainview)
1890 g_assert(mainview != NULL && mainview->data != NULL);
1892 gtk_widget_set_sensitive(GTK_WIDGET(mainview->redo_tb), st);
1895 gboolean close_cb(GtkWidget * widget, GdkEventAny * event, MainView * mainview)
1897 callback_file_close(NULL, mainview);
1898 return (TRUE);
1901 gboolean key_press_cb(GtkWidget * widget, GdkEventKey * event, MainView * mainview)
1903 switch (event->keyval)
1907 * case GDK_Up:
1908 * gtk_infoprint(GTK_WINDOW(app), "Navigation Key Up");
1909 * return TRUE;
1911 * case GDK_Down:
1912 * gtk_infoprint(GTK_WINDOW(app), "Navigation Key Down");
1913 * return TRUE;
1915 * case GDK_Left:
1916 * gtk_infoprint(GTK_WINDOW(app), "Navigation Key Left");
1917 * return TRUE;
1919 * case GDK_Right:
1920 * gtk_infoprint(GTK_WINDOW(app), "Navigation Key Right");
1921 * return TRUE;
1923 * case GDK_Return:
1924 * gtk_infoprint(GTK_WINDOW(app), "Navigation Key select");
1925 * return TRUE;
1927 /*code below messes up when you have a textview*/
1929 case GDK_Left:
1930 case GDK_Right:
1932 gtk_widget_child_focus(widget, event->keyval==GDK_Left?GTK_DIR_TAB_BACKWARD:GTK_DIR_TAB_FORWARD);
1933 return TRUE;
1936 case GDK_Left:
1938 nodeData *selnode = getSelectedNode(mainview);
1939 if (selnode!=NULL && selnode->typ==NODE_SKETCH)
1941 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Squared shapes ON"));
1942 sketchwidget_set_shift(mainview->sk, TRUE);
1943 return TRUE;
1945 return FALSE;
1947 case GDK_Right:
1949 nodeData *selnode = getSelectedNode(mainview);
1950 if (selnode!=NULL && selnode->typ==NODE_SKETCH)
1952 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Squared shapes OFF"));
1953 sketchwidget_set_shift(mainview->sk, FALSE);
1954 return TRUE;
1956 return FALSE;
1958 case GDK_Down:
1960 nodeData *selnode = getSelectedNode(mainview);
1961 if (selnode!=NULL && selnode->typ==NODE_SKETCH)
1963 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Filled shapes OFF"));
1964 sketchwidget_set_fillmode(mainview->sk, FALSE);
1965 return TRUE;
1967 return FALSE;
1969 case GDK_Up:
1971 nodeData *selnode = getSelectedNode(mainview);
1972 if (selnode!=NULL && selnode->typ==NODE_SKETCH)
1974 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, _("Filled shapes ON"));
1975 sketchwidget_set_fillmode(mainview->sk, TRUE);
1976 return TRUE;
1978 return FALSE;
1980 case GDK_F6:
1981 if ((mainview->viewflags & 4) == 0) mainview->viewflags |= 4;
1982 else mainview->viewflags &= ~4;
1983 callback_setview(mainview, 1);
1984 return TRUE;
1985 case GDK_F7:
1987 nodeData *selnode = getSelectedNode(mainview);
1988 if (selnode!=NULL && selnode->typ==NODE_SKETCH)
1990 callback_redo(NULL, mainview);
1991 return TRUE;
1993 return FALSE;
1995 case GDK_F8:
1997 nodeData *selnode = getSelectedNode(mainview);
1998 if (selnode!=NULL && selnode->typ==NODE_SKETCH)
2000 callback_undo(NULL, mainview);
2001 return TRUE;
2003 return FALSE;
2005 case GDK_Escape:
2006 if ((mainview->viewflags & 1) == 0) mainview->viewflags |= 1;
2007 else mainview->viewflags &= ~1;
2008 callback_setview(mainview, 1);
2010 return TRUE;
2013 return FALSE;
2016 void callback_viewmenu(GtkAction * action, GtkWidget * wid)
2018 int flag = (int)gtk_object_get_user_data(GTK_OBJECT(wid));
2019 MainView *mainview = gtk_object_get_data(GTK_OBJECT(wid), "mainview");
2021 g_assert(mainview != NULL);
2023 if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(wid))) mainview->viewflags |= flag;
2024 else mainview->viewflags &= ~flag;
2026 if (flag==1)
2028 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->toggletree_tb), gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(wid)));
2029 return;
2032 callback_setview(mainview, 0);
2036 void callback_setview(MainView *mainview, int setmenu)
2038 if (setmenu>0)
2040 if ((mainview->viewflags&4)>0)
2041 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->viewmenuitems[2]), TRUE);
2042 else
2043 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->viewmenuitems[2]), FALSE);
2045 if ((mainview->viewflags&2)>0)
2046 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->viewmenuitems[1]), TRUE);
2047 else
2048 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->viewmenuitems[1]), FALSE);
2050 if ((mainview->viewflags&1)>0)
2052 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->viewmenuitems[0]), TRUE);
2053 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->toggletree_tb), TRUE);
2055 else
2057 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview->viewmenuitems[0]), FALSE);
2058 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview->toggletree_tb), FALSE);
2061 return;
2064 setBusy(mainview, 1);
2066 if ((mainview->viewflags&4)>0)
2067 gtk_window_fullscreen(GTK_WINDOW(mainview->data->main_view));
2068 else
2069 gtk_window_unfullscreen(GTK_WINDOW(mainview->data->main_view));
2071 if ((mainview->viewflags&2)>0)
2072 gtk_widget_show(mainview->toolbar);
2073 else
2074 gtk_widget_hide(mainview->toolbar);
2076 if ((mainview->viewflags&1)>0)
2077 gtk_widget_show(mainview->scrolledtree);
2078 else
2079 gtk_widget_hide(mainview->scrolledtree);
2081 if (mainview->viewflags==4)
2082 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sketchwidget_get_mainwidget(mainview->sk)), GTK_POLICY_NEVER, GTK_POLICY_NEVER);
2083 else
2084 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sketchwidget_get_mainwidget(mainview->sk)), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
2086 setBusy(mainview, 2);
2090 * buffer edited
2092 void callback_buffer_modified(GtkAction * action, gpointer data)
2095 * connect pointer to our MainView struct
2097 MainView *mainview = NULL;
2099 mainview = (MainView *) data;
2100 g_assert(mainview != NULL && mainview->data != NULL);
2103 * change state
2105 mainview->file_edited = TRUE;
2109 * Callback for exit D-BUS event
2111 void exit_event_handler(gboolean die_now, gpointer data)
2113 MainView *mainview = NULL;
2115 mainview = (MainView *) data;
2116 g_assert(mainview != NULL && mainview->data != NULL);
2118 if (!die_now)
2120 if (callback_file_close(NULL, mainview)==FALSE) gtk_main_quit(); /*make sure we call gtk_main_quit*/
2122 else
2124 gtk_main_quit();
2127 * application_exit(mainview->data);
2132 * Callback for hardware D-BUS events
2134 void hw_event_handler(osso_hw_state_t * state, gpointer data)
2136 MainView *mainview = NULL;
2138 mainview = (MainView *) data;
2139 g_assert(mainview != NULL && mainview->data != NULL);
2142 * if (state->shutdown_ind)
2144 * gtk_infoprint(GTK_WINDOW(mainview->data->app),
2145 * "Shutdown event!");
2147 * if (state->memory_low_ind)
2149 * gtk_infoprint(GTK_WINDOW(mainview->data->app),
2150 * "Memory low event!");
2153 if (state->save_unsaved_data_ind)
2155 fprintf(stderr, "Saving unsaved data!\n");
2156 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, "Saving unsaved data!");
2157 callback_file_save(NULL, mainview);
2161 * if (state->system_inactivity_ind)
2163 * gtk_infoprint(GTK_WINDOW(mainview->data->app),
2164 * "Minimize application inactivity event!");
2169 GtkTreeRowReference *read_sqlite3_data(MainView * mainview, unsigned int parentid, GtkTreeRowReference * parenttree, unsigned int selected, GtkTreeStore * model)
2171 GtkTreeRowReference *resref = NULL;
2173 char q[256];
2175 snprintf(q, sizeof(q), "SELECT nodeid, bodytype, name, nameblob, lastmodified, flags FROM %s WHERE parent=%d ORDER BY ord", datatable_tmpname, parentid);
2177 sqlite3_stmt *stmt = NULL;
2178 const char *dum;
2179 int rc = sqlite3_prepare(mainview->db, q, strlen(q), &stmt, &dum);
2181 if (rc)
2183 fprintf(stderr, "Error %s\n", sqlite3_errmsg(mainview->db));
2184 return (NULL);
2187 rc = SQLITE_BUSY;
2188 while(rc == SQLITE_BUSY || rc == SQLITE_ROW)
2190 rc = sqlite3_step(stmt);
2191 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE || rc == SQLITE_DONE)
2192 break;
2193 else if (rc == SQLITE_ROW)
2195 int nodeid = sqlite3_column_int(stmt, 0);
2196 int typ = sqlite3_column_int(stmt, 1);
2197 const unsigned char *name = sqlite3_column_text(stmt, 2);
2198 const unsigned char *nameblob = sqlite3_column_text(stmt, 3);
2199 int lastmod = sqlite3_column_int(stmt, 4);
2200 int flags = sqlite3_column_int(stmt, 5);
2203 * fprintf(stderr, "CARD=%s TYPE=%d\n", name, typ);
2205 if ((typ != NODE_TEXT && typ != NODE_SKETCH) || (name == NULL && nameblob == NULL))
2209 * fprintf(stderr, "invalid card, skipping\n");
2211 continue;
2214 nodeData *node = g_malloc(sizeof(nodeData));
2216 node->sql3id = nodeid;
2217 node->typ = typ;
2218 node->flags = flags;
2219 node->name = NULL;
2220 node->namepix = NULL;
2221 if (name != NULL)
2222 node->name = g_strdup((char *)name);
2223 if (nameblob != NULL)
2225 int blobsize = sqlite3_column_bytes(stmt, 3);
2227 GdkPixbufLoader *pl = gdk_pixbuf_loader_new_with_type("png", NULL);
2228 GError *err = NULL;
2230 gdk_pixbuf_loader_write(pl, (guchar *) nameblob, blobsize, &err);
2231 if (err != NULL)
2233 fprintf(stderr, "Error loading nodename! %s\n", err->message);
2234 g_error_free(err);
2235 err = NULL;
2237 gdk_pixbuf_loader_close(pl, NULL);
2238 GdkPixbuf *pixbuf = gdk_pixbuf_loader_get_pixbuf(pl);
2240 if (GDK_IS_PIXBUF(pixbuf))
2241 node->namepix = pixbuf;
2243 node->lastMod = lastmod;
2245 GtkTreeIter parentiter, newiter;
2246 void *par = NULL;
2248 if (parenttree != NULL)
2250 GtkTreePath *pa = gtk_tree_row_reference_get_path(parenttree);
2252 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &parentiter, pa);
2253 gtk_tree_path_free(pa);
2254 par = &parentiter;
2257 gtk_tree_store_append(model, &newiter, par);
2258 gtk_tree_store_set(model, &newiter, NODE_NAME, node->name, NODE_PIXBUF, node->namepix, NODE_DATA, node, -1);
2260 GtkTreePath *pa = gtk_tree_model_get_path(GTK_TREE_MODEL(model), &newiter);
2262 GtkTreeRowReference *newref = gtk_tree_row_reference_new(GTK_TREE_MODEL(model), pa);
2264 if (selected == nodeid)
2265 resref = newref;
2267 gtk_tree_path_free(pa);
2268 GtkTreeRowReference *r = read_sqlite3_data(mainview, nodeid, newref, selected,
2269 model);
2271 if (resref != newref)
2272 gtk_tree_row_reference_free(newref);
2274 if (r != NULL)
2276 if (resref == NULL)
2277 resref = r;
2278 else
2279 gtk_tree_row_reference_free(r); /*safeguard */
2284 if (stmt)
2285 sqlite3_finalize(stmt);
2287 return (resref); /*ref to supposed-to-be-selected treeitem */
2291 * read file
2293 gboolean read_file_to_buffer(MainView * mainview)
2295 char tq[512];
2297 g_assert(mainview != NULL);
2298 gboolean res = FALSE;
2300 gchar *filename = mainview->file_name;
2302 new_file(mainview);
2303 mainview->file_name = filename;
2304 mainview->loading=TRUE;
2306 fprintf(stderr, "read:*%s*\n", filename);
2308 int rc;
2309 sqlite3_stmt *stmt = NULL;
2311 rc = sqlite3_open(filename, &mainview->db);
2314 if (rc)
2316 fprintf(stderr, "Can't open database %s: %s\n", filename, sqlite3_errmsg(mainview->db));
2317 break;
2320 char *q = "SELECT skey, sval FROM settings";
2321 const char *dum;
2323 rc = sqlite3_prepare(mainview->db, q, strlen(q), &stmt, &dum);
2324 if (rc)
2326 fprintf(stderr, "Error %s\n", sqlite3_errmsg(mainview->db));
2327 break;
2330 unsigned int selectedCard = 0;
2333 * fprintf(stderr, "start config\n");
2335 unsigned int curDataVersion = 0;
2337 rc = SQLITE_BUSY;
2338 while(rc == SQLITE_BUSY || rc == SQLITE_ROW)
2340 rc = sqlite3_step(stmt);
2341 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE || rc == SQLITE_DONE)
2342 break;
2343 else if (rc == SQLITE_ROW)
2345 const unsigned char *col_key = sqlite3_column_text(stmt, 0);
2346 const unsigned char *col_val = sqlite3_column_text(stmt, 1);
2349 * fprintf(stderr, "%s=%s\n", col_key, col_val);
2351 if (!strcmp(col_key, "leftPanedPos"))
2353 gint panedPos = atoi((char *)col_val);
2355 if (panedPos > 0)
2356 gtk_paned_set_position(GTK_PANED(mainview->hpaned), panedPos);
2358 if (!strcmp(col_key, "selectedNode"))
2360 gint tmp = atoi((char *)col_val);
2362 if (tmp > 0)
2363 selectedCard = tmp;
2365 if (!strcmp(col_key, "dataVersion"))
2367 gint tmp = atoi((char *)col_val);
2369 if (tmp > 0)
2370 curDataVersion = tmp;
2372 if (!strcmp(col_key, "newNodeDlgCreateChild"))
2374 gint tmp = atoi((char *)col_val);
2376 mainview->newnodedialog_createchild = TRUE;
2377 if (tmp == 0)
2378 mainview->newnodedialog_createchild = FALSE;
2380 if (!strcmp(col_key, "fullScreen"))
2382 gint tmp = atoi((char *)col_val);
2383 if (tmp<0 || tmp>4) tmp=0;
2384 if (tmp==0) tmp=4;
2385 else tmp--;
2386 if (tmp==0) tmp=3;
2387 else if (tmp==1) tmp=2;
2388 else if (tmp==2) tmp=7;
2389 else if (tmp==3) tmp=6;
2390 else if (tmp==4) tmp=4;
2391 mainview->viewflags=tmp;
2392 callback_setview(mainview, TRUE);
2394 if (!strcmp(col_key, "viewFlags"))
2396 gint tmp = atoi((char *)col_val);
2397 if (tmp<0) tmp=3;
2398 mainview->viewflags=tmp;
2399 callback_setview(mainview, TRUE);
2401 if (!strcmp(col_key, "brushSize"))
2403 gint tmp = atoi((char *)col_val);
2404 if (tmp>0) sk_set_brushsize(mainview, tmp);
2406 if (!strcmp(col_key, "brushColor"))
2408 unsigned long tmp = atol((char *)col_val);
2409 GdkColor c2;
2411 c2.red = ((tmp & 0xFF0000) >> 16) << 8;
2412 c2.green = ((tmp & 0xFF00) >> 8) << 8;
2413 c2.blue = (tmp & 0xFF) << 8;
2414 /* fprintf(stderr, "READ BRUSHCOLOR is %ul (%d,%d,%d)\n", tmp, c2.red, c2.green, c2.blue);*/
2416 sketchwidget_set_brushcolor(mainview->sk, c2);
2417 hildon_color_button_set_color(HILDON_COLOR_BUTTON(mainview->colorbutton), &c2);
2422 if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE)
2424 fprintf(stderr, "Error2 %s\n", sqlite3_errmsg(mainview->db));
2425 break;
2429 * fprintf(stderr, "end config\n");
2431 if (stmt)
2432 sqlite3_finalize(stmt);
2434 gboolean resback = FALSE;
2436 while(curDataVersion < datatableversion)
2438 if (curDataVersion == 0)
2440 snprintf(tq, sizeof(tq), "DROP TABLE %s", datatable_backupname);
2441 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
2443 snprintf(tq, sizeof(tq), "ALTER TABLE %s RENAME TO %s", datatable_name, datatable_backupname);
2444 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
2446 fprintf(stderr, "ERROR backing up table!\n");
2447 break;
2449 resback = TRUE;
2451 snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", datatable_name, datatable);
2452 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
2454 fprintf(stderr, "ERROR creating table!\n");
2455 break;
2457 snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT nodeid, parent, bodytype, name, body, nameblob, bodyblob, lastmodified, ord, 0 FROM %s", datatable_name, datatable_backupname);
2458 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
2460 fprintf(stderr, "ERROR copying data!\n");
2461 break;
2464 snprintf(tq, sizeof(tq), "DROP TABLE %s", datatable_backupname);
2465 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
2467 curDataVersion = datatableversion;
2470 if (curDataVersion != datatableversion)
2472 fprintf(stderr, "Data version mismatch\n");
2474 if (resback == TRUE)
2476 snprintf(tq, sizeof(tq), "DROP TABLE %s", datatable_name);
2477 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
2478 snprintf(tq, sizeof(tq), "ALTER TABLE %s RENAME TO %s", datatable_backupname, datatable_name);
2479 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
2482 break;
2485 GtkTreeStore *model = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(mainview->treeview)));
2487 g_object_ref(model);
2488 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->treeview), NULL);
2492 char tq[512];
2494 snprintf(tq, sizeof(tq), "CREATE%s TABLE %s%s", TEMPTABLE_KEYWORD, datatable_tmpname, datatable);
2495 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
2497 fprintf(stderr, "ERROR creating temp table!\n");
2498 break;
2500 snprintf(tq, sizeof(tq), "CREATE INDEX %s_index ON %s %s", datatable_tmpname, datatable_tmpname, dataindex);
2501 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
2503 fprintf(stderr, "ERROR creating temp index!\n");
2504 break;
2506 snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT * FROM %s", datatable_tmpname, datatable_name);
2507 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
2509 fprintf(stderr, "ERROR copying data to temp table!\n");
2510 break;
2513 while(FALSE);
2515 GtkTreeRowReference *selectedRef = read_sqlite3_data(mainview, 0, NULL, selectedCard, model);
2517 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->treeview), GTK_TREE_MODEL(model));
2518 g_object_unref(model);
2519 gtk_tree_view_expand_all(GTK_TREE_VIEW(mainview->treeview));
2521 if (selectedRef != NULL)
2523 GtkTreeIter seliter;
2525 if (ref2iter(GTK_TREE_MODEL(model), selectedRef, &seliter) == TRUE)
2527 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview->treeview));
2528 gtk_tree_selection_select_iter(selection, &seliter);
2531 gtk_tree_row_reference_free(selectedRef);
2533 res = TRUE;
2535 while(FALSE);
2537 if (stmt)
2538 sqlite3_finalize(stmt);
2541 mainview->loading=FALSE;
2543 return (res);
2547 * write to file
2549 void write_buffer_to_file(MainView * mainview)
2551 fprintf(stderr, "write:*%s*\n", mainview->file_name);
2552 saveCurrentData(mainview);
2554 setBusy(mainview, 1);
2556 char tq[512];
2558 snprintf(tq, sizeof(tq), "DROP TABLE %s", misctable_name);
2559 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
2561 snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", misctable_name, misctable);
2562 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
2564 gint panedPos = gtk_paned_get_position(GTK_PANED(mainview->hpaned));
2566 snprintf(tq, sizeof(tq), "INSERT INTO %s VALUES('leftPanedPos', '%d');", misctable_name, panedPos);
2567 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
2569 gint nndcc = 1;
2571 if (mainview->newnodedialog_createchild == FALSE)
2572 nndcc = 0;
2573 snprintf(tq, sizeof(tq), "INSERT INTO %s VALUES('newNodeDlgCreateChild', '%d');", misctable_name, nndcc);
2574 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
2576 snprintf(tq, sizeof(tq), "INSERT INTO %s VALUES('viewFlags', '%d');", misctable_name, mainview->viewflags);
2577 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
2579 nodeData *node = getSelectedNode(mainview);
2581 if (node)
2583 snprintf(tq, sizeof(tq), "INSERT INTO %s VALUES('selectedNode', '%d');", misctable_name, node->sql3id);
2584 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
2587 guint bsize;
2588 if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(mainview->eraser_tb)) == TRUE)
2590 bsize=mainview->brushsize_backup;
2592 else
2594 bsize=sketchwidget_get_brushsize(mainview->sk);
2596 snprintf(tq, sizeof(tq), "INSERT INTO %s VALUES('brushSize', '%d');", misctable_name, bsize);
2597 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
2599 GdkColor *col = hildon_color_button_get_color(HILDON_COLOR_BUTTON(mainview->colorbutton));
2600 unsigned long bcol=((col->red >> 8) << 16) | ((col->green >> 8) << 8) | (col->blue >> 8);
2601 /* fprintf(stderr, "BRUSHCOLOR is %d (%d,%d,%d)\n", bcol, col->red, col->green, col->blue);*/
2602 snprintf(tq, sizeof(tq), "INSERT INTO %s VALUES('brushColor', '%lu');", misctable_name, bcol);
2603 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
2605 snprintf(tq, sizeof(tq), "INSERT INTO %s VALUES('dataVersion', '%d');", misctable_name, datatableversion);
2606 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
2608 snprintf(tq, sizeof(tq), "DROP TABLE %s", datatable_backupname);
2609 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
2610 snprintf(tq, sizeof(tq), "CREATE TABLE %s%s", datatable_backupname, datatable);
2611 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
2613 fprintf(stderr, "ERROR creating backup table!\n");
2614 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, "Error 1");
2615 return;
2617 snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT * FROM %s", datatable_backupname, datatable_name);
2618 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
2620 fprintf(stderr, "ERROR backing up table!\n");
2621 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, "Error 2");
2622 return;
2624 snprintf(tq, sizeof(tq), "DELETE FROM %s", datatable_name);
2625 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
2627 snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT * FROM %s", datatable_name, datatable_tmpname);
2628 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
2630 fprintf(stderr, "ERROR saving table!\n");
2631 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), NULL, "Error 3");
2633 snprintf(tq, sizeof(tq), "DELETE FROM %s", datatable_name);
2634 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
2636 snprintf(tq, sizeof(tq), "INSERT INTO %s SELECT * FROM %s", datatable_name, datatable_backupname);
2637 if (sqlite3_exec(mainview->db, tq, NULL, NULL, NULL) != 0)
2639 fprintf(stderr, "ERROR restoring backup! data lost!\n");
2641 setBusy(mainview, 2);
2642 return;
2645 snprintf(tq, sizeof(tq), "DROP TABLE %s", datatable_backupname);
2646 sqlite3_exec(mainview->db, tq, NULL, NULL, NULL);
2648 mainview->file_edited = FALSE;
2649 setBusy(mainview, 2);
2650 hildon_banner_show_information(GTK_WIDGET(mainview->data->main_view), GTK_STOCK_SAVE, _("Saved"));