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
22 #include <ui/callbacks.h>
23 #include <ui/interface.h>
25 #include <gdk/gdkkeysyms.h>
31 * strlen needed from string.h
34 #include <sys/types.h>
42 #include <hildon/hildon.h>
43 #include <hildon/hildon-banner.h>
44 #include <hildon/hildon-note.h>
45 #include <hildon/hildon-font-selection-dialog.h>
46 #include <tablet-browser-interface.h>
48 #include <libgnomevfs/gnome-vfs.h>
50 #include "sketchwidget.h"
52 #include "../he/he-about-dialog.h"
53 #include "../he/he-simple-color-dialog.h"
56 * "Busy" status handling
58 * Use "busy_reset" to reset the busy status (turn off)
59 * Use "busy_enter" when starting time-consuming processing
60 * Use "busy_leave" when processing has been finished
68 /* Don't use this directly, but make use of the macros defined below */
69 void set_busy(MainView
* mainview
, SetBusyType update
);
71 #define busy_reset(mainview) set_busy(mainview, BUSY_RESET)
72 #define busy_enter(mainview) set_busy(mainview, BUSY_INCREMENT)
73 #define busy_leave(mainview) set_busy(mainview, BUSY_DECREMENT)
79 gboolean
read_file_to_buffer(MainView
* mainview
);
80 void write_buffer_to_file(MainView
* mainview
);
81 void new_node_dialog(nodeType typ
, MainView
* mainview
);
82 gboolean
foreach_func_update_ord (GtkTreeModel
*model
,GtkTreePath
*path
,GtkTreeIter
*iter
, MainView
*mainview
);
83 void move_nodes_up(GtkTreeModel
* model
, GtkTreeRowReference
* topnode
, GtkTreeRowReference
* newtop
);
84 GtkTreeRowReference
*iter2ref(GtkTreeModel
* model
, GtkTreeIter
* iter
);
85 gboolean
exec_command_on_db(MainView
*mainview
,char sql_string
[]);
86 int get_node_id_on_tmp_db(GtkTreeModel
*model
,GtkTreeIter
*iter
);
87 gint
get_branch_node_index(GtkTreePath
*path
);
88 gboolean
move_node(MainView
*mainview
,GtkTreeIter
*new_parent
,GtkTreeIter
*item_to_move
,GtkTreeIter
*item_befor
);
89 gboolean
tree_model_iter_prev(GtkTreeModel
*tree_model
,GtkTreeIter
*iter
);
90 gboolean
show_confirmation(MainView
* mainview
, gchar
* question
);
94 gboolean
callback_node_view_window_state(GtkWidget
* window
,
95 GdkEventWindowState
* event
, gpointer user_data
)
97 MainView
* mainview
= (MainView
*)user_data
;
98 GtkWidget
* sketch_scroll
= NULL
;
100 if (mainview
->toolbar
== NULL
|| mainview
->sk
== NULL
) {
104 sketch_scroll
= GTK_WIDGET(sketchwidget_get_mainwidget(mainview
->sk
));
106 if (event
->changed_mask
& GDK_WINDOW_STATE_FULLSCREEN
) {
107 if (event
->new_window_state
& GDK_WINDOW_STATE_FULLSCREEN
) {
108 gtk_widget_hide(mainview
->toolbar
);
109 gtk_scrolled_window_set_policy(
110 GTK_SCROLLED_WINDOW(sketch_scroll
),
114 gtk_widget_show(mainview
->toolbar
);
115 gtk_scrolled_window_set_policy(
116 GTK_SCROLLED_WINDOW(sketch_scroll
),
117 GTK_POLICY_AUTOMATIC
,
118 GTK_POLICY_AUTOMATIC
);
125 void set_busy(MainView
* mainview
, SetBusyType update
)
129 mainview
->busyrefcount
= 0;
132 mainview
->busyrefcount
++;
135 if (mainview
->busyrefcount
> 0) {
136 mainview
->busyrefcount
--;
140 g_error("Wrong type in set_busy: %d", update
);
144 hildon_gtk_window_set_progress_indicator(GTK_WINDOW(mainview
->data
->main_view
), (mainview
->busyrefcount
> 0));
145 hildon_gtk_window_set_progress_indicator(GTK_WINDOW(mainview
->data
->node_view
), (mainview
->busyrefcount
> 0));
148 void prepareUIforNodeChange(MainView
* mainview
, nodeType typ
)
150 gtk_widget_set_sensitive(GTK_WIDGET(mainview
->undo_tb
), TRUE
);
151 gtk_widget_set_sensitive(GTK_WIDGET(mainview
->redo_tb
), TRUE
);
153 if (typ
== NODE_TEXT
)
155 gtk_widget_show(GTK_WIDGET(mainview
->font_tb
));
156 gtk_widget_show(GTK_WIDGET(mainview
->bold_tb
));
157 gtk_widget_show(GTK_WIDGET(mainview
->italic_tb
));
158 gtk_widget_show(GTK_WIDGET(mainview
->underline_tb
));
159 gtk_widget_show(GTK_WIDGET(mainview
->bullet_tb
));
160 gtk_widget_show(mainview
->tools_font
);
161 gtk_widget_show(mainview
->tools_wordwrap
);
165 gtk_widget_hide(GTK_WIDGET(mainview
->font_tb
));
166 gtk_widget_hide(GTK_WIDGET(mainview
->bold_tb
));
167 gtk_widget_hide(GTK_WIDGET(mainview
->italic_tb
));
168 gtk_widget_hide(GTK_WIDGET(mainview
->underline_tb
));
169 gtk_widget_hide(GTK_WIDGET(mainview
->bullet_tb
));
170 gtk_widget_hide(mainview
->tools_font
);
171 gtk_widget_hide(mainview
->tools_wordwrap
);
174 if (typ
== NODE_SKETCH
)
176 /* gtk_widget_show(GTK_WIDGET(mainview->colorbutton_tb));*/
177 gtk_widget_show(GTK_WIDGET(mainview
->eraser_tb
));
178 gtk_widget_show(GTK_WIDGET(mainview
->brushsize_tb
));
179 gtk_widget_show(GTK_WIDGET(mainview
->sketchlines_tb
));
180 gtk_widget_show(GTK_WIDGET(mainview
->shape_tb
));
181 gtk_widget_show(mainview
->tools_color
);
182 gtk_widget_show(mainview
->tools_brushsize
);
183 gtk_widget_show(mainview
->tools_pagestyle
);
184 gtk_widget_show(mainview
->tools_shape
);
185 gtk_widget_show(mainview
->tools_pressure
);
189 /* gtk_widget_hide(GTK_WIDGET(mainview->colorbutton_tb));*/
190 gtk_widget_hide(GTK_WIDGET(mainview
->eraser_tb
));
191 gtk_widget_hide(GTK_WIDGET(mainview
->brushsize_tb
));
192 gtk_widget_hide(GTK_WIDGET(mainview
->sketchlines_tb
));
193 gtk_widget_hide(GTK_WIDGET(mainview
->shape_tb
));
194 gtk_widget_hide(mainview
->tools_color
);
195 gtk_widget_hide(mainview
->tools_brushsize
);
196 gtk_widget_hide(mainview
->tools_pagestyle
);
197 gtk_widget_hide(mainview
->tools_shape
);
198 gtk_widget_hide(mainview
->tools_pressure
);
201 if (typ
== NODE_CHECKLIST
)
203 gtk_widget_show(GTK_WIDGET(mainview
->bold_tb
));
204 gtk_widget_show(GTK_WIDGET(mainview
->strikethru_tb
));
205 gtk_widget_show(GTK_WIDGET(mainview
->check_tb
));
206 gtk_widget_show(GTK_WIDGET(mainview
->checkadd_tb
));
207 gtk_widget_show(GTK_WIDGET(mainview
->checkdel_tb
));
208 gtk_widget_hide(GTK_WIDGET(mainview
->undo_tb
));
209 gtk_widget_hide(GTK_WIDGET(mainview
->redo_tb
));
213 gtk_widget_hide(GTK_WIDGET(mainview
->strikethru_tb
));
214 gtk_widget_hide(GTK_WIDGET(mainview
->check_tb
));
215 gtk_widget_hide(GTK_WIDGET(mainview
->checkadd_tb
));
216 gtk_widget_hide(GTK_WIDGET(mainview
->checkdel_tb
));
217 gtk_widget_show(GTK_WIDGET(mainview
->undo_tb
));
218 gtk_widget_show(GTK_WIDGET(mainview
->redo_tb
));
221 if (typ
== NODE_TEXT
)
223 gtk_widget_hide(GTK_WIDGET(mainview
->colorbutton_tb
));
224 gtk_widget_hide(sketchwidget_get_mainwidget(mainview
->sk
));
225 gtk_widget_hide(mainview
->listscroll
);
226 gtk_widget_show(GTK_WIDGET(mainview
->scrolledwindow
));
227 gtk_widget_show(mainview
->tools_item
);
229 else if (typ
== NODE_SKETCH
)
231 gtk_widget_show(GTK_WIDGET(mainview
->colorbutton_tb
));
232 gtk_widget_hide(GTK_WIDGET(mainview
->scrolledwindow
));
233 gtk_widget_hide(mainview
->listscroll
);
234 gtk_widget_show(sketchwidget_get_mainwidget(mainview
->sk
));
235 gtk_widget_show(mainview
->tools_item
);
237 else if (typ
== NODE_CHECKLIST
)
239 gtk_widget_show(GTK_WIDGET(mainview
->colorbutton_tb
));
240 gtk_widget_hide(GTK_WIDGET(mainview
->scrolledwindow
));
241 gtk_widget_hide(sketchwidget_get_mainwidget(mainview
->sk
));
242 gtk_widget_hide(mainview
->tools_item
);
243 gtk_widget_show(mainview
->listscroll
);
247 gtk_widget_hide(GTK_WIDGET(mainview
->colorbutton_tb
));
248 gtk_widget_hide(GTK_WIDGET(mainview
->scrolledwindow
));
249 gtk_widget_hide(sketchwidget_get_mainwidget(mainview
->sk
));
250 gtk_widget_hide(mainview
->tools_item
);
251 gtk_widget_hide(mainview
->listscroll
);
255 nodeData
*getSelectedNode(MainView
* mainview
)
262 GtkTreeSelection
*selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->treeview
));
264 if (!gtk_tree_selection_get_selected(selection
, &model
, &iter
))
267 gtk_tree_model_get(model
, &iter
, NODE_DATA
, &nd
, -1);
272 void saveCurrentData(MainView
* mainview
)
274 nodeData
*selnode
= getSelectedNode(mainview
);
275 saveDataToNode(mainview
, selnode
);
278 void saveDataToNode(MainView
* mainview
, nodeData
*selnode
)
284 (selnode
->typ
== NODE_SKETCH
&& sketchwidget_get_edited(mainview
->sk
) == FALSE
) ||
285 (selnode
->typ
== NODE_TEXT
&& wp_text_buffer_is_modified(mainview
->buffer
)==FALSE
) ||
286 (selnode
->typ
== NODE_CHECKLIST
&& mainview
->checklist_edited
==FALSE
)
289 maepad_message("node not edited, not saving");
293 mainview
->file_edited
= TRUE
;
295 busy_enter(mainview
);
296 maepad_debug("saveDataToNode working");
298 gboolean goterr
= TRUE
;
299 gchar
*textdata
= NULL
;
300 GdkPixbuf
*pixbuf
= NULL
;
301 gchar
*sketchdata
= NULL
;
305 if (selnode
->typ
== NODE_TEXT
)
308 GtkTextIter start
, end
;
309 gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(mainview
->buffer
), &start
, &end
);
310 textdata
= gtk_text_buffer_serialize_rich_text(GTK_TEXT_BUFFER(mainview
->buffer
), &start
, &end
, &datalen
);
313 GString
*gstr
=g_string_sized_new(4096);
314 wp_text_buffer_save_document(mainview
->buffer
, (WPDocumentSaveCallback
)(wp_savecallback
), gstr
);
317 textdata
=g_string_free(gstr
, FALSE
);
319 /* g_snprintf(tq, sizeof(tq), "UPDATE %s SET bodytype=%d, bodyblob=NULL, body=?, flags=%d WHERE nodeid=%d", datatable_tmpname, selnode->typ, selnode->flags, selnode->sql3id);*/
320 g_snprintf(tq
, sizeof(tq
), "UPDATE %s SET bodytype=%d, bodyblob=?, body=NULL, flags=%d WHERE nodeid=%d", datatable_tmpname
, selnode
->typ
, selnode
->flags
, selnode
->sql3id
);
322 else if (selnode
->typ
== NODE_SKETCH
)
325 GdkPixmap
*skpix
= sketchwidget_get_Pixmap(mainview
->sk
);
326 GtkWidget
*skdr
= sketchwidget_get_drawingarea(mainview
->sk
);
328 pixbuf
= gdk_pixbuf_get_from_drawable(NULL
, GDK_DRAWABLE(skpix
), NULL
, 0, 0, 0, 0, skdr
->allocation
.width
, skdr
->allocation
.height
);
331 maepad_warning("error saving: pixbuf is null");
336 GdkPixbuf
*pixbuf2
= sketchwidget_trim_image(pixbuf
, skdr
->allocation
.width
, skdr
->allocation
.height
, &w
, &h
, FALSE
);
340 if (gdk_pixbuf_save_to_buffer(pixbuf2
, &sketchdata
, &datalen
, "png", &err
, NULL
) == FALSE
)
344 maepad_warning("Error saving sketch: %s", err
->message
);
347 gdk_pixbuf_unref(pixbuf2
);
350 g_snprintf(tq
, sizeof(tq
), "UPDATE %s SET bodytype=%d, body=NULL, bodyblob=?, flags=%d WHERE nodeid=%d", datatable_tmpname
, selnode
->typ
, selnode
->flags
, selnode
->sql3id
);
351 maepad_debug("storing sketch in db: %d bytes", datalen
);
352 if (skpix
&& G_IS_OBJECT(skpix
)) g_object_unref(skpix
);
354 else if (selnode
->typ
== NODE_CHECKLIST
)
356 g_snprintf(tq
, sizeof(tq
), "UPDATE %s SET bodytype=%d, body=NULL, bodyblob=NULL, flags=%d WHERE nodeid=%d", datatable_tmpname
, selnode
->typ
, selnode
->flags
, selnode
->sql3id
);
361 sqlite3_stmt
*stmt
= NULL
;
363 int rc
= sqlite3_prepare(mainview
->db
, tq
, strlen(tq
), &stmt
, &dum
);
367 maepad_warning("Error updating: %s", sqlite3_errmsg(mainview
->db
));
370 if (selnode
->typ
== NODE_TEXT
)
371 sqlite3_bind_text(stmt
, 1, textdata
, datalen
, /*strlen(textdata),*/ SQLITE_TRANSIENT
);
372 else if (selnode
->typ
== NODE_SKETCH
)
373 sqlite3_bind_blob(stmt
, 1, sketchdata
, datalen
, SQLITE_TRANSIENT
);
376 while(rc
== SQLITE_BUSY
)
378 rc
= sqlite3_step(stmt
);
379 if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
|| rc
== SQLITE_DONE
)
382 sqlite3_finalize(stmt
);
384 if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
)
386 maepad_warning("Error saving node: %s", sqlite3_errmsg(mainview
->db
));
390 if (selnode
->typ
== NODE_TEXT
)
391 gtk_text_buffer_set_modified(GTK_TEXT_BUFFER(mainview
->buffer
), FALSE
);
392 else if (selnode
->typ
== NODE_SKETCH
)
393 sketchwidget_set_edited(mainview
->sk
, FALSE
);
394 else if (selnode
->typ
== NODE_CHECKLIST
)
395 mainview
->checklist_edited
= FALSE
;
400 while(goterr
==FALSE
&& selnode
->typ
== NODE_CHECKLIST
)
402 GtkTreeModel
*model
=gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->listview
));
405 g_snprintf(tq
, sizeof(tq
), "DELETE FROM %s WHERE nodeid=%d", checklisttable_tmpname
, selnode
->sql3id
);
406 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
409 if (gtk_tree_model_get_iter_first(model
, &iter
)==FALSE
) break;
413 gint styletoset_weight
;
414 gboolean styletoset_strike
;
420 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);
423 if (color
!=NULL
&& strcmp(color
, "(null)")!=0 && gdk_color_parse(color
, &tmpcol
))
425 col
=((tmpcol
.red
>>8)<<16)|((tmpcol
.green
>>8)<<8)|(tmpcol
.blue
>>8);
429 if (ischecked
) style
|=CHECKSTYLE_CHECKED
;
430 if (styletoset_weight
==PANGO_WEIGHT_BOLD
) style
|=CHECKSTYLE_BOLD
;
431 if (styletoset_strike
) style
|=CHECKSTYLE_STRIKE
;
433 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s (nodeid, name, style, color, ord) VALUES(%d, ?, %d, %lu, 0)", checklisttable_tmpname
, selnode
->sql3id
, style
, col
);
434 sqlite3_stmt
*stmt
= NULL
;
436 int rc
= sqlite3_prepare(mainview
->db
, tq
, strlen(tq
), &stmt
, &dum
);
441 maepad_warning("Error while saving checklist: %s", sqlite3_errmsg(mainview
->db
));
444 sqlite3_bind_text(stmt
, 1, text
, strlen(text
), SQLITE_TRANSIENT
);
447 while(rc
== SQLITE_BUSY
)
449 rc
= sqlite3_step(stmt
);
450 if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
|| rc
== SQLITE_DONE
)
453 sqlite3_finalize(stmt
);
455 if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
)
458 maepad_warning("Error while saving checklist (2): %s", sqlite3_errmsg(mainview
->db
));
464 }while(gtk_tree_model_iter_next(model
, &iter
)==TRUE
);
475 show_banner(mainview
, _("Error saving memo"));
477 busy_leave(mainview
);
480 gboolean
callback_treeview_button_press(GtkTreeView
* treeview
, GdkEventButton
* event
, gpointer user_data
)
482 MainView
* mainview
= (MainView
*)user_data
;
484 mainview
->can_show_node_view
= TRUE
;
489 void callback_treeview_celldatafunc(GtkTreeViewColumn
* tree_column
, GtkCellRenderer
* cell
, GtkTreeModel
* tree_model
, GtkTreeIter
* iter
, gpointer data
)
491 MainView
*mainview
= ( MainView
* ) data
;
492 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
496 gtk_tree_model_get(tree_model
, iter
, NODE_DATA
, &nd
, -1);
500 if (nd
->namepix
== NULL
)
502 g_object_set(cell
, "visible", FALSE
, NULL
);
506 g_object_set(cell
, "visible", TRUE
, NULL
);
507 g_object_set(cell
, "width", SKETCHNODE_RX
, NULL
);
508 g_object_set(cell
, "height", SKETCHNODE_RY
, NULL
);
513 gboolean
callback_treeview_testcollapse(GtkTreeView
* treeview
, GtkTreeIter
* arg1
, GtkTreePath
* arg2
, gpointer user_data
)
518 void callback_treeview_change(GtkTreeSelection
* selection
, gpointer data
)
520 MainView
*mainview
= (MainView
*) data
;
521 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
523 nodeData
*nd
= getSelectedNode(mainview
);
525 gchar
* nodeName
= _("View node");
527 if (nd
!= NULL
&& nd
->name
!= NULL
) {
531 /* Show node view with selected node */
532 gtk_window_set_title(GTK_WINDOW(mainview
->data
->node_view
),
535 if (mainview
->can_show_node_view
) {
536 gtk_widget_show(GTK_WIDGET(mainview
->data
->node_view
));
539 /* Make sure we don't accidentally collapse any nodes */
540 gtk_tree_view_expand_all(GTK_TREE_VIEW(mainview
->treeview
));
544 if (mainview
->cansel_time
>0 && mainview
->cansel_time
+1.0<tm
) mainview
->cansel_node
=NULL
;
548 if (mainview
->cansel_node
!=NULL
)
550 maepad_debug("[SELLOGIC] saving %d to unselect all nodes", (mainview
->cansel_node
)->sql3id
);
551 saveDataToNode(mainview
, (mainview
->cansel_node
));
552 mainview
->cansel_node
=NULL
;
557 if (mainview
->cansel_node
!=NULL
)
559 if (nd
->sql3id
== (mainview
->cansel_node
)->sql3id
)
561 mainview
->cansel_node
=NULL
;
562 maepad_debug("[SELLOGIC] doubly selected %d, doing nothing", nd
->sql3id
);
567 maepad_debug("[SELLOGIC] saving %d to load new node", (mainview
->cansel_node
)->sql3id
);
568 saveDataToNode(mainview
, (mainview
->cansel_node
));
569 mainview
->cansel_node
=NULL
;
574 if (nd
== NULL
) return;
576 busy_enter(mainview
);
578 gboolean goterr
= TRUE
;
579 char *textdata
= NULL
;
581 int blobsize
= 0, textsize
= 0;
585 g_snprintf(tq
, sizeof(tq
), "SELECT bodytype, body, bodyblob, flags FROM %s WHERE nodeid=%d", datatable_tmpname
, nd
->sql3id
);
586 sqlite3_stmt
*stmt
= NULL
;
588 int rc
= sqlite3_prepare(mainview
->db
, tq
, strlen(tq
), &stmt
, &dum
);
592 maepad_warning("Error reading (1): %s", sqlite3_errmsg(mainview
->db
));
597 while(rc
== SQLITE_BUSY
|| rc
== SQLITE_ROW
)
599 rc
= sqlite3_step(stmt
);
600 if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
|| rc
== SQLITE_DONE
)
602 else if (rc
== SQLITE_ROW
)
604 nd
->typ
= sqlite3_column_int(stmt
, 0);
605 nd
->flags
= sqlite3_column_int(stmt
, 3);
607 prepareUIforNodeChange(mainview
, nd
->typ
);
608 if (nd
->typ
== NODE_TEXT
)
610 gboolean file_edited_backup
= mainview
->file_edited
;
612 blobsize
= sqlite3_column_bytes(stmt
, 2);
613 blob
= (char *)sqlite3_column_blob(stmt
, 2);
615 textdata
= (char *)sqlite3_column_text(stmt
, 1);
616 textsize
= sqlite3_column_bytes(stmt
, 1);
618 /* gtk_text_buffer_set_text(GTK_TEXT_BUFFER(mainview->buffer), "", -1);*/
619 wp_text_buffer_reset_buffer(mainview
->buffer
, TRUE
);
621 gboolean richtext
=FALSE
;
626 gboolean oldway
=FALSE
;
630 strncpy(tst
, blob
, 8);
632 if (strcmp(tst
, "RICHTEXT")==0) oldway
=TRUE
;
638 gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(mainview
->buffer
), &iter
);
639 gtk_text_buffer_deserialize_rich_text(GTK_TEXT_BUFFER(mainview
->buffer
), &iter
, blob
, blobsize
, TRUE
, &err
);
653 wp_text_buffer_load_document_begin(mainview
->buffer
, TRUE
);
654 wp_text_buffer_load_document_write(mainview
->buffer
, blob
, blobsize
);
655 wp_text_buffer_load_document_end(mainview
->buffer
);
659 if (richtext
==FALSE
&& !(textdata
== NULL
|| g_utf8_validate(textdata
, textsize
, NULL
) == FALSE
))
661 /* gtk_text_buffer_set_text(GTK_TEXT_BUFFER(mainview->buffer), textdata, textsize);*/
662 wp_text_buffer_load_document_begin(mainview
->buffer
, FALSE
);
663 wp_text_buffer_load_document_write(mainview
->buffer
, textdata
, textsize
);
664 wp_text_buffer_load_document_end(mainview
->buffer
);
667 wp_text_buffer_enable_rich_text(mainview
->buffer
, TRUE
);
668 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview
->tools_wordwrap
), ((nd
->flags
& NODEFLAG_WORDWRAP
) > 0)?TRUE
:FALSE
);
669 callback_wordwrap(NULL
, mainview
); /*FIXME:ugly (do we need this? gotta test) */
671 gtk_text_buffer_set_modified(GTK_TEXT_BUFFER(mainview
->buffer
), FALSE
); /*we probably don't need this*/
673 callback_undotoggle((gpointer
)mainview
->buffer
, FALSE
, mainview
); /*we need these*/
674 callback_redotoggle((gpointer
)mainview
->buffer
, FALSE
, mainview
);
676 if (file_edited_backup
==FALSE
) mainview
->file_edited
=FALSE
; /*textview changed event toggles this?*/
679 else if (nd
->typ
== NODE_SKETCH
)
681 sketchwidget_wipe_undo(mainview
->sk
);
682 sketchwidget_set_fillmode(mainview
->sk
, FALSE
);
683 sketchwidget_set_shift(mainview
->sk
, FALSE
);
684 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview
->shapemenuitems
[1]), TRUE
);
685 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview
->shapemenuitems
[0]), TRUE
);
687 blobsize
= sqlite3_column_bytes(stmt
, 2);
688 blob
= (char *)sqlite3_column_blob(stmt
, 2);
689 gboolean clear
= TRUE
;
695 maepad_debug("blob size: %d", blobsize
);
696 GdkPixbufLoader
*pl
= gdk_pixbuf_loader_new_with_type("png", NULL
);
699 gdk_pixbuf_loader_write(pl
, (guchar
*) blob
, blobsize
, &err
);
702 maepad_warning("Error loading sketch: %s", err
->message
);
706 gdk_pixbuf_loader_close(pl
, NULL
);
707 GdkPixbuf
*pixbuf
= gdk_pixbuf_loader_get_pixbuf(pl
);
709 if (GDK_IS_PIXBUF(pixbuf
))
711 GtkWidget
*skdr
= sketchwidget_get_drawingarea(mainview
->sk
);
712 GtkPixmap
*skpix
= (GtkPixmap
*) sketchwidget_get_Pixmap(mainview
->sk
);
714 int w
=gdk_pixbuf_get_width(pixbuf
);
715 int h
=gdk_pixbuf_get_height(pixbuf
);
716 if (w
!=skdr
->allocation
.width
|| h
!=skdr
->allocation
.height
)
718 if (w
>skdr
->allocation
.width
) w
=skdr
->allocation
.width
;
719 if (h
>skdr
->allocation
.height
) h
=skdr
->allocation
.height
;
720 sketchwidget_clear_real(mainview
->sk
);
722 gdk_draw_pixbuf(GDK_DRAWABLE(skpix
), NULL
, pixbuf
, 0, 0, 0, 0, w
, h
, GDK_RGB_DITHER_NONE
, 0, 0);
727 if (skpix
&& G_IS_OBJECT(skpix
)) g_object_unref(skpix
);
731 maepad_warning("Error loading pixbuf");
737 maepad_message("Clearing sketch widget");
738 sketchwidget_clear_real(mainview
->sk
);
740 gtk_widget_queue_draw(sketchwidget_get_drawingarea(mainview
->sk
));
742 else if (nd
->typ
== NODE_CHECKLIST
)
744 mainview
->checklist_edited
= FALSE
;
745 GtkTreeModel
*model
=gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->listview
));
747 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview
->listview
), NULL
);
748 gtk_list_store_clear(GTK_LIST_STORE(model
));
750 g_snprintf(tq
, sizeof(tq
), "SELECT name, style, color FROM %s WHERE nodeid=%d ORDER BY ord, idx", checklisttable_tmpname
, nd
->sql3id
);
751 sqlite3_stmt
*stmt2
= NULL
;
753 int rc
= sqlite3_prepare(mainview
->db
, tq
, strlen(tq
), &stmt2
, &dum
);
756 maepad_warning("Error reading checklist (1) %s", sqlite3_errmsg(mainview
->db
));
762 while(rc
== SQLITE_BUSY
|| rc
== SQLITE_ROW
)
764 rc
= sqlite3_step(stmt2
);
765 if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
|| rc
== SQLITE_DONE
)
767 else if (rc
== SQLITE_ROW
)
769 char *textdata
= (char *)sqlite3_column_text(stmt2
, 0);
770 int style
= sqlite3_column_int(stmt2
, 1);
771 unsigned long col
= sqlite3_column_int(stmt2
, 2);
773 GtkTreeIter toplevel
;
774 gtk_list_store_append(GTK_LIST_STORE(model
), &toplevel
);
775 gtk_list_store_set(GTK_LIST_STORE(model
), &toplevel
, CHECKNODE_TEXT
, textdata
, CHECKNODE_CHECKED
, FALSE
, -1);
776 if ((style
& CHECKSTYLE_CHECKED
)>0) {
777 gtk_list_store_set(GTK_LIST_STORE(model
), &toplevel
, CHECKNODE_CHECKED
, TRUE
, -1);
778 gtk_list_store_set(GTK_LIST_STORE(model
), &toplevel
, CHECKNODE_ICON_NAME
, "widgets_tickmark_list", -1);
780 if ((style
& CHECKSTYLE_BOLD
)>0) gtk_list_store_set(GTK_LIST_STORE(model
), &toplevel
, CHECKNODE_BOLD
, PANGO_WEIGHT_BOLD
, -1);
781 if ((style
& CHECKSTYLE_STRIKE
)>0) gtk_list_store_set(GTK_LIST_STORE(model
), &toplevel
, CHECKNODE_STRIKE
, TRUE
, -1);
786 g_snprintf(tmp
, sizeof(tmp
), "#%02lx%02lx%02lx", ((col
& 0xFF0000) >> 16), ((col
& 0xFF00) >> 8), (col
& 0xFF));
787 gtk_list_store_set(GTK_LIST_STORE(model
), &toplevel
, CHECKNODE_COLOR
, tmp
, -1);
792 if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
)
794 maepad_warning("Error reading checklist (2): %s", sqlite3_errmsg(mainview
->db
));
798 sqlite3_finalize(stmt2
);
801 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview
->listview
), model
);
802 g_object_unref(model
);
805 if ((nd
->flags
& NODEFLAG_SKETCHLINES
) > 0)
806 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview
->sketchlinesmenuitems
[1]), TRUE
);
807 else if ((nd
->flags
& NODEFLAG_SKETCHGRAPH
) > 0)
808 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview
->sketchlinesmenuitems
[2]), TRUE
);
811 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview
->sketchlinesmenuitems
[0]), TRUE
);
812 callback_sketchlines(NULL
, mainview
->sketchlinesmenuitems
[0]); /*FIXME:ugly */
814 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview
->tools_pressure
), TRUE
);
819 if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
) {
820 maepad_warning("Error reading (2): %s", sqlite3_errmsg(mainview
->db
));
823 sqlite3_finalize(stmt
);
826 busy_leave(mainview
);
830 show_banner(mainview
, _("Error loading memo"));
834 gboolean
treeview_canselect(GtkTreeSelection
* selection
, GtkTreeModel
* model
, GtkTreePath
* path
, gboolean path_currently_selected
, gpointer userdata
)
836 MainView
*mainview
= (MainView
*) userdata
;
837 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
839 if (mainview
->loading
==FALSE
)
841 #ifndef EXPANDING_ROWS
842 if (path_currently_selected
)
846 #ifndef NEW_SEL_LOGIC
847 saveCurrentData(mainview
);
849 if (path_currently_selected
)
852 gtk_tree_model_get_iter(model
, &iter
, path
);
854 gtk_tree_model_get(model
, &iter
, NODE_DATA
, &(mainview
->cansel_node
), -1);
855 mainview
->cansel_time
=time(NULL
);
862 gboolean
newnodedlg_key_press_cb(GtkWidget
* widget
, GdkEventKey
* event
, GtkWidget
* dlg
)
864 SketchWidget
*s
= gtk_object_get_data(GTK_OBJECT(dlg
), "sk");
866 switch (event
->keyval
)
869 sketchwidget_redo(s
);
872 sketchwidget_undo(s
);
879 /* This struct will hold all our toggle buttons, so we can
880 * only allow one to be active at a time (i.e. radio buttons) */
881 typedef struct _newNodeToggleButtons newNodeToggleButtons
;
882 struct _newNodeToggleButtons
884 GtkWidget
*rbt
; /* Text */
885 GtkWidget
*rbs
; /* Sketch */
886 GtkWidget
*rbc
; /* Checklist */
889 void show_sketch_widget(GtkWidget
*widget
, gpointer user_data
)
891 GtkWidget
*dialog
= (GtkWidget
*)user_data
;
893 /* Show the sketch widget and hide the entry + draw button */
894 gtk_widget_show(gtk_object_get_data(GTK_OBJECT(dialog
), "al"));
895 gtk_widget_hide(gtk_object_get_data(GTK_OBJECT(dialog
), "draw_button"));
896 gtk_widget_hide(gtk_object_get_user_data(GTK_OBJECT(dialog
)));
899 void new_node_dialog(nodeType typ
, MainView
* mainview
)
901 GtkWidget
*dialog
, *entry
, *but_ok
, *vbox
, *hbox
, *al
, *cb
;
902 GtkWidget
*rb1
, *rb2
, *rb3
;
904 gchar datetime_str
[200];
907 gboolean datetime_written
= FALSE
;
910 tm_now
= localtime(&t_now
);
912 if (tm_now
!= NULL
) {
913 if (strftime(datetime_str
, sizeof(datetime_str
), "%y-%m-%d %H:%M", tm_now
) != 0) {
914 datetime_written
= TRUE
;
918 if (datetime_written
== FALSE
) {
919 /* Was not able to determine a datetime string - use default */
920 maepad_warning("Cannot determine current time");
921 strncpy(datetime_str
, _("New memo"), sizeof(datetime_str
));
922 datetime_str
[sizeof(datetime_str
)-1] = '\0';
925 newNodeToggleButtons
*nntb
= g_malloc(sizeof(newNodeToggleButtons
));
927 dialog
= gtk_dialog_new();
928 gtk_window_set_title(GTK_WINDOW(dialog
), _("Create new memo"));
929 gtk_dialog_set_has_separator(GTK_DIALOG(dialog
), FALSE
);
931 g_signal_connect(G_OBJECT(dialog
), "key_press_event", G_CALLBACK(newnodedlg_key_press_cb
), dialog
);
933 vbox
= gtk_vbox_new(FALSE
, 0);
935 hbox
= gtk_hbox_new(TRUE
, 0);
937 /* Text note toggle button */
938 rb1
= hildon_gtk_radio_button_new(HILDON_SIZE_FINGER_HEIGHT
, NULL
);
939 gtk_button_set_label(GTK_BUTTON(rb1
), _("Rich text"));
940 gtk_button_set_image(GTK_BUTTON(rb1
), gtk_image_new_from_file(PIXMAPDIR
"/text.png"));
941 gtk_box_pack_start(GTK_BOX(hbox
), GTK_WIDGET(rb1
), TRUE
, TRUE
, 0);
944 /* Sketch toggle button */
945 rb2
= hildon_gtk_radio_button_new_from_widget(HILDON_SIZE_FINGER_HEIGHT
, GTK_RADIO_BUTTON(rb1
));
946 gtk_button_set_label(GTK_BUTTON(rb2
), _("Sketch"));
947 gtk_button_set_image(GTK_BUTTON(rb2
), gtk_image_new_from_file(PIXMAPDIR
"/sketch.png"));
948 gtk_box_pack_start(GTK_BOX(hbox
), GTK_WIDGET(rb2
), TRUE
, TRUE
, 0);
951 /* Checklist toggle button */
952 rb3
= hildon_gtk_radio_button_new_from_widget(HILDON_SIZE_FINGER_HEIGHT
, GTK_RADIO_BUTTON(rb1
));
953 gtk_button_set_label(GTK_BUTTON(rb3
), _("Checklist"));
954 gtk_button_set_image(GTK_BUTTON(rb3
), gtk_image_new_from_file(PIXMAPDIR
"/checklist.png"));
955 gtk_box_pack_start(GTK_BOX(hbox
), GTK_WIDGET(rb3
), TRUE
, TRUE
, 0);
958 /* Set mode to 0 to get correct styling */
959 gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(rb1
), FALSE
);
960 gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(rb2
), FALSE
);
961 gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(rb3
), FALSE
);
963 /* Remember "new note toggle buttons" list */
964 gtk_object_set_data(GTK_OBJECT(dialog
), "nntb", nntb
);
966 if (typ
== NODE_TEXT
) {
967 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rb1
), TRUE
);
968 } else if (typ
== NODE_SKETCH
) {
969 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rb2
), TRUE
);
971 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rb3
), TRUE
);
974 gtk_box_pack_start(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
976 but_ok
= gtk_dialog_add_button(GTK_DIALOG(dialog
), _("Create"), GTK_RESPONSE_OK
);
977 g_signal_connect(G_OBJECT(but_ok
), "clicked", G_CALLBACK(callback_new_node_real
), dialog
);
979 gtk_object_set_data(GTK_OBJECT(dialog
), "m", mainview
);
981 hb
= gtk_hbox_new(FALSE
, 10);
982 gtk_box_pack_start(GTK_BOX(hb
), gtk_label_new(_("Name:")), FALSE
, FALSE
, 0);
983 entry
= hildon_entry_new(HILDON_SIZE_AUTO
);
984 gtk_object_set_user_data(GTK_OBJECT(dialog
), entry
);
985 gtk_entry_set_text(GTK_ENTRY(entry
), datetime_str
);
986 gtk_editable_select_region(GTK_EDITABLE(entry
), 0, -1);
987 gtk_box_pack_start(GTK_BOX(hb
), entry
, TRUE
, TRUE
, 0);
989 /* Sketch widget, hidden by default */
990 al
= gtk_alignment_new(0.5, 0.5, 0, 0);
991 SketchWidget
*s
= sketchwidget_new(SKETCHNODE_X
, SKETCHNODE_Y
, TRUE
);
992 gtk_object_set_data(GTK_OBJECT(dialog
), "sk", s
);
993 gtk_object_set_data(GTK_OBJECT(dialog
), "al", al
);
994 sketchwidget_set_brushsize(s
, 2);
995 sketchwidget_set_backstyle(s
, SKETCHBACK_GRAPH
);
996 gtk_widget_set_size_request(sketchwidget_get_mainwidget(s
), SKETCHNODE_X
, SKETCHNODE_Y
);
997 gtk_container_add(GTK_CONTAINER(al
), sketchwidget_get_mainwidget(s
));
998 gtk_box_pack_start(GTK_BOX(hb
), al
, FALSE
, FALSE
, 0);
1000 /*but_sketch = hildon_button_new_with_text(
1001 HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH,
1002 HILDON_BUTTON_ARRANGEMENT_VERTICAL,
1003 _("Use sketch label"), NULL);
1005 gtk_object_set_data(GTK_OBJECT(dialog), "draw_button", but_sketch);
1006 gtk_signal_connect(GTK_OBJECT(but_sketch), "clicked", G_CALLBACK(show_sketch_widget), dialog);
1007 gtk_box_pack_start(GTK_BOX(hb), but_sketch, FALSE, TRUE, 0);*/
1008 gtk_box_pack_start(GTK_BOX(vbox
), hb
, TRUE
, FALSE
, 0);
1010 cb
= hildon_check_button_new(HILDON_SIZE_FINGER_HEIGHT
| HILDON_SIZE_AUTO_WIDTH
);
1011 gtk_button_set_label(GTK_BUTTON(cb
), _("Create as child of selected memo"));
1012 hildon_check_button_set_active(HILDON_CHECK_BUTTON(cb
), mainview
->newnodedialog_createchild
);
1013 gtk_box_pack_start(GTK_BOX(vbox
), cb
, FALSE
, FALSE
, 0);
1015 gtk_object_set_data(GTK_OBJECT(dialog
), "cb", cb
);
1017 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog
)->vbox
), vbox
);
1019 gtk_widget_grab_focus(entry
);
1021 gtk_widget_show_all(dialog
);
1023 /* Hide the sketch widget at first */
1024 gtk_widget_hide(al
);
1025 gtk_window_set_modal(GTK_WINDOW(dialog
), TRUE
);
1028 void add_new_node(nodeData
* node
, MainView
* mainview
, gboolean ischild
)
1030 GtkTreeIter parentiter
, newiter
;
1031 GtkTreeModel
*model
;
1034 GtkTreeSelection
*selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->treeview
));
1036 if (gtk_tree_selection_get_selected(selection
, &model
, &parentiter
))
1039 GtkTreePath
*path
= NULL
;
1041 unsigned int parentnodeid
= 0;
1045 path
= gtk_tree_model_get_path(model
, &parentiter
);
1047 if (ischild
== FALSE
)
1049 gtk_tree_path_up(path
);
1051 if (gtk_tree_path_get_depth(path
) == 0)
1053 /* Selected node is a root node */
1054 ptr
= NULL
; /* New node can not have a Parent node */
1055 gtk_tree_path_down(path
); /*restore path so expand() works */
1057 else if (gtk_tree_path_get_depth(path
) > 0)
1059 /* Selected node is a child node */
1060 if (gtk_tree_model_get_iter(model
, &parentiter
, path
))
1070 gtk_tree_model_get(model
, ptr
, NODE_DATA
, &nd
, -1);
1072 parentnodeid
= nd
->sql3id
;
1078 sqlite3_stmt
*stmt
= NULL
;
1085 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s (parent, bodytype, name, nameblob, ord) VALUES (%d, %d, ?, ?, 0);", datatable_tmpname
, parentnodeid
, node
->typ
);
1086 int rc
= sqlite3_prepare(mainview
->db
, tq
, strlen(tq
), &stmt
, &dum
);
1090 maepad_warning("Error inserting (1): %s", sqlite3_errmsg(mainview
->db
));
1093 if (node
->name
!= NULL
)
1094 sqlite3_bind_text(stmt
, 1, node
->name
, strlen(node
->name
), SQLITE_TRANSIENT
);
1096 sqlite3_bind_text(stmt
, 1, NULL
, 0, SQLITE_TRANSIENT
);
1098 if (node
->namepix
!= NULL
)
1100 gchar
*namepixdata
= NULL
;
1105 if (gdk_pixbuf_save_to_buffer(node
->namepix
, &namepixdata
, &datalen
, "png", &err
, NULL
) == FALSE
)
1109 maepad_warning("Error saving name: %s", err
->message
);
1112 sqlite3_bind_blob(stmt
, 2, namepixdata
, datalen
, SQLITE_TRANSIENT
);
1115 sqlite3_bind_blob(stmt
, 2, NULL
, 0, SQLITE_TRANSIENT
);
1118 while(rc
== SQLITE_BUSY
)
1120 rc
= sqlite3_step(stmt
);
1121 if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
|| rc
== SQLITE_DONE
)
1124 sqlite3_finalize(stmt
);
1125 if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
)
1127 maepad_warning("Error inserting (2): %s", sqlite3_errmsg(mainview
->db
));
1130 node
->sql3id
= sqlite3_last_insert_rowid(mainview
->db
);
1134 if (node
->sql3id
== 0)
1139 g_object_unref(node
->namepix
);
1142 gtk_tree_path_free(path
);
1143 show_banner(mainview
, _("Error creating node"));
1147 gtk_tree_store_append(GTK_TREE_STORE(model
), &newiter
, ptr
);
1149 gtk_tree_store_set(GTK_TREE_STORE(model
), &newiter
, NODE_NAME
, node
->name
, NODE_PIXBUF
, node
->namepix
, NODE_DATA
, node
, -1);
1153 mainview
->loading
=TRUE
; /*only when we have a valid parent*/
1154 gtk_tree_view_expand_row(GTK_TREE_VIEW(mainview
->treeview
), path
, FALSE
);
1155 gtk_tree_path_free(path
);
1158 gtk_tree_selection_select_iter(selection
, &newiter
);
1160 mainview
->loading
=FALSE
;
1163 void callback_new_node_real(GtkAction
* action
, gpointer data
)
1167 GtkWidget
*dialog
= data
;
1168 GtkWidget
*entry
= gtk_object_get_user_data(GTK_OBJECT(dialog
));
1170 mainview
= gtk_object_get_data(GTK_OBJECT(dialog
), "m");
1171 SketchWidget
*s
= gtk_object_get_data(GTK_OBJECT(dialog
), "sk");
1172 GtkWidget
*cb
= gtk_object_get_data(GTK_OBJECT(dialog
), "cb");
1173 newNodeToggleButtons
*nntb
= gtk_object_get_data(GTK_OBJECT(dialog
), "nntb");
1175 nodeType typ
= NODE_TEXT
;
1176 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(nntb
->rbs
))) {
1178 } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(nntb
->rbc
))) {
1179 typ
= NODE_CHECKLIST
;
1185 /*if (GTK_WIDGET_VISIBLE(entry))
1187 txt
= g_strdup(gtk_entry_get_text(GTK_ENTRY(entry
)));
1188 if (strcmp(txt
, "") == 0)
1196 GtkWidget *sdr = sketchwidget_get_drawingarea(s);
1198 GdkPixmap *spix = sketchwidget_get_Pixmap(s);
1200 pixbuf = gdk_pixbuf_get_from_drawable(NULL, GDK_DRAWABLE(spix), NULL, 0, 0, 0, 0, sdr->allocation.width, sdr->allocation.height);
1201 g_object_unref(spix);
1203 GdkPixbuf *pixbuf2 = sketchwidget_trim_image(pixbuf, SKETCHNODE_X, SKETCHNODE_Y, &w,
1205 if (pixbuf2==NULL) return;
1207 GdkPixbuf *pixbuf3 = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, SKETCHNODE_RX,
1210 gdk_pixbuf_fill(pixbuf3, 0xffffffff);
1212 if (w <= SKETCHNODE_RX && h <= SKETCHNODE_RY)
1214 gdk_pixbuf_copy_area(pixbuf2, 0, 0, w, h, pixbuf3, 0, (SKETCHNODE_RY - h) / 2);
1222 neww = SKETCHNODE_RX;
1223 newh = (h / w) * SKETCHNODE_RX;
1227 newh = SKETCHNODE_RY;
1228 neww = (w / h) * SKETCHNODE_RY;
1230 if (newh > SKETCHNODE_RY)
1231 newh = SKETCHNODE_RY;
1233 GdkPixbuf *tmpbuf = gdk_pixbuf_scale_simple(pixbuf2, neww, newh,
1234 GDK_INTERP_BILINEAR);
1236 gdk_pixbuf_copy_area(tmpbuf, 0, 0, neww, newh, pixbuf3, 0, (SKETCHNODE_RY - newh) / 2);
1238 gdk_pixbuf_unref(tmpbuf);
1242 gdk_pixbuf_unref(pixbuf2);
1247 node
= g_malloc(sizeof(nodeData
));
1250 node
->namepix
= NULL
;
1252 /*if (GTK_WIDGET_VISIBLE(entry))
1258 node->namepix = pixbuf;
1265 mainview
->newnodedialog_createchild
= hildon_check_button_get_active(HILDON_CHECK_BUTTON(cb
));
1266 add_new_node(node
, mainview
, mainview
->newnodedialog_createchild
);
1268 sketchwidget_destroy(s
);
1269 gtk_widget_destroy(dialog
);
1270 mainview
->file_edited
= TRUE
;
1276 void callback_file_delete_node(GtkAction
* action
, gpointer data
)
1278 MainView
*mainview
= (MainView
*) data
;
1279 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
1281 if (getSelectedNode(mainview
) == NULL
) {
1282 show_banner(mainview
, _("Select a node first"));
1286 if (show_confirmation(mainview
, _("Delete selected memo?"))) {
1287 callback_delete_node_real(mainview
);
1288 gtk_widget_hide(GTK_WIDGET(mainview
->data
->node_view
));
1293 * Callback for Rename Menuitem
1295 void callback_file_rename_node(GtkAction
* action
, gpointer data
)
1297 MainView
*mainview
= (MainView
*)data
;
1298 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
1300 /* Get the selected node */
1301 nodeData
*sel_node
= getSelectedNode(mainview
);
1302 if (sel_node
== NULL
) {
1303 /* Do nothing, if no node has been selected */
1304 show_banner(mainview
, _("Select a node first"));
1308 if (sel_node
->namepix
!= NULL
) {
1309 /* the memo has a graphical label, cannot edit! */
1310 show_banner(mainview
, _("Cannot rename memos with sketch name"));
1314 gchar
* new_name
= show_line_edit_dialog(mainview
, _("Rename memo"), _("New name:"), _("Rename"), sel_node
->name
);
1316 /* Only rename node when user accepted the new name */
1317 if (new_name
!= NULL
) {
1318 callback_rename_node_real(mainview
, new_name
);
1323 void callback_rename_node_real(MainView
* mainview
, gchar
* new_name
)
1326 GtkTreeModel
*model
;
1327 nodeData
*nd
= NULL
;
1329 /* Get the selected node */
1330 GtkTreeSelection
*selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->treeview
));
1332 if (!gtk_tree_selection_get_selected(selection
, &model
, &iter
)) {
1336 gtk_tree_model_get (model
, &iter
, NODE_DATA
, &nd
, -1);
1342 /* Update the database */
1343 sqlite3_stmt
*stmt
= NULL
;
1345 char* sql
= sqlite3_mprintf("UPDATE %s SET name='%q' WHERE nodeid=%d", datatable_tmpname
, new_name
, nd
->sql3id
);
1347 int rc
= sqlite3_prepare(mainview
->db
, sql
, strlen(sql
), &stmt
, NULL
);
1348 if (rc
== SQLITE_OK
) {
1350 while (rc
== SQLITE_BUSY
) {
1351 rc
= sqlite3_step(stmt
);
1352 if (rc
== SQLITE_DONE
) {
1353 /* Update in the database was successful - now update the rest */
1355 /* Update the noteData */
1357 nd
->name
= g_strdup(new_name
);
1359 /* Update the window title of node_view */
1360 gtk_window_set_title(GTK_WINDOW(mainview
->data
->node_view
), nd
->name
);
1362 /* Update the value in the tree store */
1363 gtk_tree_store_set (GTK_TREE_STORE(model
), &iter
, NODE_NAME
, new_name
, -1);
1366 } else if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
) {
1367 maepad_warning("Error updating node: %s", sqlite3_errmsg(mainview
->db
));
1371 sqlite3_finalize(stmt
);
1373 maepad_warning("Error preparing DB update query: %s", sqlite3_errmsg(mainview
->db
));
1378 mainview
->file_edited
= TRUE
;
1381 void callback_file_export_node(GtkAction
* action
, gpointer data
)
1383 MainView
*mainview
= (MainView
*) data
;
1384 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
1386 nodeData
*nd
=getSelectedNode(mainview
);
1389 show_banner(mainview
, _("Select a memo first"));
1393 gchar
*nodename
=nd
->name
;
1394 if (nodename
==NULL
) nodename
=_("saved memo");
1396 if (nd
->typ
== NODE_TEXT
)
1399 GtkTextIter begin, end;
1400 gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER(mainview->buffer), &begin, &end);
1401 gchar *text = gtk_text_buffer_get_slice(GTK_TEXT_BUFFER(mainview->buffer), &begin, &end, TRUE);
1403 GString
*gstr
=g_string_sized_new(4096);
1404 wp_text_buffer_save_document(mainview
->buffer
, (WPDocumentSaveCallback
)(wp_savecallback
), gstr
);
1405 gint textlen
=gstr
->len
;
1406 gchar
*text
=g_string_free(gstr
, FALSE
);
1408 if (text
==NULL
|| !strcmp(text
, ""))
1410 show_banner(mainview
, _("Memo is empty"));
1414 gchar
*fn
= interface_file_chooser(mainview
, GTK_FILE_CHOOSER_ACTION_SAVE
, nodename
, "html");
1417 GnomeVFSResult vfs_result
;
1418 GnomeVFSHandle
*handle
= NULL
;
1419 GnomeVFSFileSize out_bytes
;
1420 vfs_result
= gnome_vfs_create(&handle
, fn
, GNOME_VFS_OPEN_WRITE
, 0, 0600);
1421 if ( vfs_result
!= GNOME_VFS_OK
) {
1422 show_banner(mainview
, _("Export failed"));
1426 gnome_vfs_write(handle
, text
, textlen
, &out_bytes
);
1427 gnome_vfs_close(handle
);
1428 if (out_bytes
==strlen(text
)) show_banner(mainview
, _("Exported"));
1429 else show_banner(mainview
, _("Export incomplete"));
1436 else if (nd
->typ
== NODE_SKETCH
)
1438 GdkPixmap
*skpix
= sketchwidget_get_Pixmap(mainview
->sk
);
1439 GtkWidget
*skdr
= sketchwidget_get_drawingarea(mainview
->sk
);
1440 GdkPixbuf
*pixbuf
= gdk_pixbuf_get_from_drawable(NULL
, GDK_DRAWABLE(skpix
), NULL
, 0, 0, 0, 0, skdr
->allocation
.width
, skdr
->allocation
.height
);
1443 show_banner(mainview
, _("Memo is empty"));
1447 gchar
*fn
= interface_file_chooser(mainview
, GTK_FILE_CHOOSER_ACTION_SAVE
, nodename
, "png");
1450 if (gdk_pixbuf_save(pixbuf
, fn
, "png", NULL
, NULL
)==FALSE
)
1452 show_banner(mainview
, _("Export failed"));
1456 show_banner(mainview
, _("Exported"));
1461 g_object_unref(skpix
);
1463 else if (nd
->typ
== NODE_CHECKLIST
)
1465 show_banner(mainview
, _("Export of checklists not possible yet"));
1470 * callback from menu item
1471 * move selected node down (switch node with next sibling), don't change level of node
1473 void callback_move_down_node(GtkAction
* action
, gpointer data
)
1476 GtkTreeModel
*model
;
1478 MainView
*mainview
= (MainView
*) data
;
1479 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
1481 GtkTreeSelection
*selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->treeview
));
1482 gtk_tree_selection_get_selected(selection
, &model
, &iter
);
1484 GtkTreeIter old_iter
= iter
;/*save pointer to old iter, we will need it during swap nodes*/
1486 if (gtk_tree_model_iter_next(model
,&iter
)==FALSE
)/*get next node*/
1489 GtkTreeStore
*treeStore
= GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->treeview
)));
1490 gtk_tree_store_swap(treeStore
,&iter
,&old_iter
);
1492 mainview
->file_edited
= TRUE
;/*we have made changes , if required show "save changes?" dialog in future*/
1496 * callback from menu item
1497 * move selected node down (switch node with prev sibling), don't change level of node
1499 void callback_move_up_node(GtkAction
* action
, gpointer data
)
1502 GtkTreeModel
*model
;
1504 MainView
*mainview
= (MainView
*) data
;
1505 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
1507 GtkTreeSelection
*selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->treeview
));
1508 gtk_tree_selection_get_selected(selection
, &model
, &iter
);
1510 GtkTreeIter old_iter
=iter
;/*save pointer to old iter, we will need it during swap nodes*/
1512 if (tree_model_iter_prev(model
,&iter
)==FALSE
)/*get previous node*/
1515 GtkTreeStore
*treeStore
= GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->treeview
)));
1516 gtk_tree_store_swap(treeStore
,&old_iter
,&iter
);/*do move*/
1518 mainview
->file_edited
= TRUE
;/*we have made changes , if required show "save changes?" dialog in future*/
1522 * callback from menu item
1523 * we change level of actual node with direction to top
1525 void callback_move_to_top_level_node(GtkAction
* action
, gpointer data
)
1527 GtkTreeIter iter
,new_parent
;
1528 GtkTreeIter
*p_new_parent
;
1530 GtkTreeModel
*model
;
1532 MainView
*mainview
= (MainView
*) data
;
1533 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
1535 GtkTreeSelection
*selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->treeview
));
1536 gtk_tree_selection_get_selected(selection
, &model
, &iter
);
1538 /*at first we need actual parent of selected node*/
1539 if (gtk_tree_model_iter_parent(model
,&parent
,&iter
)==FALSE
)
1541 /*if parent of selected node is ROOT we can't go higher*/
1544 /*we need also new parent, it's parent of actual parent*/
1545 if (gtk_tree_model_iter_parent(model
,&new_parent
,&parent
)==FALSE
)
1547 /*if our new parent is ROOT we got filled new_parent with invalid value,
1548 so we need set NULL value to p_new_parent (root item)*/
1553 p_new_parent
=&new_parent
;/*we only redirect pointer to treeiter*/
1556 saveCurrentData(mainview
);/*we save changes in node befor move*/
1558 /*this move function provide move item with all his children, be careful iter value will change!*/
1559 if (move_node(mainview
,p_new_parent
,&iter
,&parent
)==TRUE
){
1561 gint id_parent
= get_node_id_on_tmp_db(model
,p_new_parent
);
1562 gint id_node
= get_node_id_on_tmp_db(model
,&iter
);
1563 /*we need also update parent id of moved item*/
1565 g_snprintf (tq
, sizeof(tq
), "UPDATE %s SET parent=%d WHERE nodeid=%d",datatable_tmpname
,id_parent
,id_node
);
1566 exec_command_on_db(mainview
,tq
);
1568 /*select new created iter*/
1569 gtk_tree_selection_select_iter(selection
,&iter
);
1571 mainview
->file_edited
= TRUE
;/*we have made changes , if required show "save changes?" dialog in future*/
1576 * callback from menu item
1577 * we change level of actual node with direction to bottom
1578 * previous node will be parent of our actual node
1580 void callback_move_to_bottom_level_node(GtkAction
* action
, gpointer data
)
1583 GtkTreeModel
*model
;
1585 MainView
*mainview
= (MainView
*) data
;
1586 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
1588 GtkTreeSelection
*selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->treeview
));
1589 gtk_tree_selection_get_selected(selection
, &model
, &iter
);
1591 GtkTreeIter move_iter
=iter
;/*save pointer to old iter*/
1593 /*we try to get previous node*/
1594 if (tree_model_iter_prev(model
,&iter
)==FALSE
)
1595 return;/*if previous node on the same level doesn't exist we will exit*/
1597 saveCurrentData(mainview
);/*we save changes in node befor move*/
1599 /*this move function provide move item with all his children, be careful move_iter value will change!*/
1600 if (move_node(mainview
,&iter
,&move_iter
,NULL
)==TRUE
)
1602 gint id_parent
= get_node_id_on_tmp_db(model
,&iter
);
1603 gint id_node
= get_node_id_on_tmp_db(model
,&move_iter
);
1605 /*we need also update parent id of moved item*/
1607 g_snprintf (tq
, sizeof(tq
), "UPDATE %s SET parent=%d WHERE nodeid=%d",datatable_tmpname
,id_parent
,id_node
);
1608 exec_command_on_db(mainview
,tq
);
1610 GtkTreePath
*path
= gtk_tree_model_get_path(model
, &iter
);
1611 gtk_tree_view_expand_row(GTK_TREE_VIEW(mainview
->treeview
), path
, FALSE
);/*expand parent node*/
1612 gtk_tree_path_free(path
);
1614 /*select new created iter*/
1615 gtk_tree_selection_select_iter(selection
,&move_iter
);
1617 mainview
->file_edited
= TRUE
;/*we have made changes , if required show "save changes?" dialog in future*/
1622 * move item_to_move to new_parent with his children, this function is designed for change level of node
1623 * we copy item_to_move with his children to new position (after item_befor if is not NULL) and then we
1624 * destroy old node with his children, so ! item_to_move is set with new iter, be careful on this!
1626 gboolean
move_node(MainView
*mainview
,GtkTreeIter
*new_parent
,GtkTreeIter
*item_to_move
,GtkTreeIter
*item_befor
)
1628 GtkTreeModel
*model
;
1630 model
=gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->treeview
));
1631 GtkTreeStore
*treeStore
= GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->treeview
)));
1634 gtk_tree_model_get(model
, item_to_move
, NODE_DATA
, &node
, -1);/*get data from actual iter*/
1637 GtkTreeIter new_iter
;/*create new iter*/
1638 gtk_tree_store_append(treeStore
,&new_iter
,new_parent
);/*append new iter to new parent*/
1640 if (item_befor
!=NULL
)
1641 gtk_tree_store_move_after(treeStore
,&new_iter
,item_befor
);/*sometimes we need set position*/
1643 gtk_tree_store_set(treeStore
, &new_iter
, NODE_NAME
, node
->name
,NODE_PIXBUF
, node
->namepix
, NODE_DATA
, node
, -1);/*set data from old iter*/
1646 while (gtk_tree_model_iter_children(model
, &child
, item_to_move
)==TRUE
)/*move all childrens while some exits*/
1648 if (move_node(mainview
,&new_iter
,&child
,NULL
)==FALSE
)/*use recursion on children*/
1652 gtk_tree_store_set(treeStore
, item_to_move
, NODE_DATA
, NULL
, -1);
1653 gtk_tree_store_remove(treeStore
, item_to_move
);/*remove node, data need't remove, they are stored in new node*/
1655 /*we need return new value of moved item, so we need assign new_iter to item_to_move*/
1656 /*this code is ugly : new_iter to path and back to item_to_move*/
1657 GtkTreePath
*path
=gtk_tree_model_get_path(model
,&new_iter
);
1658 gtk_tree_model_get_iter(model
,item_to_move
,path
);
1659 gtk_tree_path_free(path
);
1663 fprintf(stderr
,"Get data node failed!\n");
1671 * simple execute of sql command which is stored in sql_string[]
1673 gboolean
exec_command_on_db(MainView
*mainview
,char sql_string
[])
1675 sqlite3_stmt
*stmt
= NULL
;
1677 gboolean db_query_result
= FALSE
;
1679 int rc
= sqlite3_prepare (mainview
->db
, sql_string
, strlen(sql_string
), &stmt
, &dum
);
1682 maepad_warning("Error preparing DB update query: %s", sqlite3_errmsg(mainview
->db
));
1687 while (rc
== SQLITE_BUSY
) {
1688 rc
= sqlite3_step (stmt
);
1689 if (rc
== SQLITE_DONE
) {
1690 db_query_result
= TRUE
;
1693 else if(rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
) {
1694 maepad_warning("Error updating node: %s", sqlite3_errmsg(mainview
->db
));
1697 sqlite3_finalize(stmt
);
1703 * 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)
1705 gboolean
foreach_func_update_ord (GtkTreeModel
*model
,GtkTreePath
*path
,GtkTreeIter
*iter
, MainView
*mainview
)
1708 gtk_tree_model_get(model
, iter
, NODE_DATA
, &node
, -1);
1709 /*we need index of node on actual level*/
1710 gint index
=get_branch_node_index(path
);
1712 /*prepare to execute update command,and exec it*/
1713 char sql_command
[512];
1714 g_snprintf (sql_command
, sizeof(sql_command
), "UPDATE %s SET ord=\"%d\" WHERE nodeid=%d",datatable_tmpname
, index
, node
->sql3id
);
1715 exec_command_on_db(mainview
,sql_command
);
1717 /*we don't want break gtk_tree_model_foreach function,until we call this func on each node - so we return always FALSE*/
1722 * return id number of iter (id number which is used to identify in sql database of nodes)
1724 int get_node_id_on_tmp_db(GtkTreeModel
*model
,GtkTreeIter
*iter
)
1727 return 0;/*we got ROOT parent here*/
1730 gtk_tree_model_get(model
, iter
, NODE_DATA
, &node
, -1);
1731 return node
->sql3id
;
1735 * get index of node in current branch
1737 gint
get_branch_node_index(GtkTreePath
*path
)
1739 int depth
=gtk_tree_path_get_depth(path
);
1740 gint
*indicies
= gtk_tree_path_get_indices(path
);
1742 return indicies
[depth
-1];
1746 * similiar with gtk_tree_model_iter_next (), but opposite
1748 gboolean
tree_model_iter_prev(GtkTreeModel
*tree_model
,GtkTreeIter
*iter
)
1750 GtkTreePath
*path
= gtk_tree_model_get_path(tree_model
, iter
);
1753 fprintf(stderr
,"Error: path is null\n");
1757 if (gtk_tree_path_prev(path
)==FALSE
)
1760 gtk_tree_model_get_iter(tree_model
, iter
,path
);
1765 gboolean
ref2iter(GtkTreeModel
* model
, GtkTreeRowReference
* ref
, GtkTreeIter
* iter
)
1767 gboolean res
= FALSE
;
1768 GtkTreePath
*path
= gtk_tree_row_reference_get_path(ref
);
1770 if (gtk_tree_model_get_iter(model
, iter
, path
))
1774 gtk_tree_path_free(path
);
1778 GtkTreeRowReference
*iter2ref(GtkTreeModel
* model
, GtkTreeIter
* iter
)
1780 GtkTreeRowReference
*ref
;
1782 GtkTreePath
*path
= gtk_tree_model_get_path(model
, iter
);
1784 ref
= gtk_tree_row_reference_new(model
, path
);
1785 gtk_tree_path_free(path
);
1789 void move_nodes_up(GtkTreeModel
* model
, GtkTreeRowReference
* topnode
, GtkTreeRowReference
* newtop
)
1791 GtkTreeIter topiter
;
1793 if (ref2iter(model
, topnode
, &topiter
) == FALSE
)
1798 if (gtk_tree_model_iter_children(model
, &child
, &topiter
))
1800 GtkTreeRowReference
*ref
;
1801 GList
*rr_list
= NULL
, *node
;
1805 ref
= iter2ref(model
, &child
);
1806 rr_list
= g_list_append(rr_list
, ref
);
1808 while(gtk_tree_model_iter_next(model
, &child
));
1811 * got a reflist for all children
1814 for(node
= rr_list
; node
; node
= node
->next
)
1816 ref
= (GtkTreeRowReference
*) (node
->data
);
1817 if (ref2iter(model
, ref
, &child
))
1819 GtkTreeIter newtopiter
, newiter
;
1820 GtkTreeIter
*newtopiterptr
;
1822 if (ref2iter(model
, newtop
, &newtopiter
))
1823 newtopiterptr
= &newtopiter
;
1825 newtopiterptr
= NULL
;
1829 gtk_tree_model_get(model
, &child
, NODE_DATA
, &node
, -1);
1831 gtk_tree_store_append(GTK_TREE_STORE(model
), &newiter
, newtopiterptr
);
1832 gtk_tree_store_set(GTK_TREE_STORE(model
), &newiter
, NODE_NAME
, node
->name
, NODE_PIXBUF
, node
->namepix
, NODE_DATA
, node
, -1);
1834 GtkTreeRowReference
*newref
= iter2ref(model
, &newiter
);
1836 move_nodes_up(model
, ref
, newref
);
1837 gtk_tree_row_reference_free(newref
);
1839 gtk_tree_store_remove(GTK_TREE_STORE(model
), &child
);
1841 gtk_tree_row_reference_free(ref
);
1844 g_list_free(rr_list
);
1849 void callback_delete_node_real(MainView
* mainview
)
1852 GtkTreeModel
*model
;
1854 GtkTreeSelection
*selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->treeview
));
1856 if (!gtk_tree_selection_get_selected(selection
, &model
, &iter
))
1861 gtk_tree_model_get(model
, &iter
, NODE_DATA
, &nd
, -1);
1865 mainview
->file_edited
= TRUE
;
1867 unsigned int sql3id
= nd
->sql3id
;
1874 * if (nd->pix) g_object_unref(nd->pix);
1878 GtkTreeRowReference
*upref
= NULL
, *ref
= NULL
;
1880 GtkTreePath
*path
= gtk_tree_model_get_path(model
, &iter
);
1882 ref
= gtk_tree_row_reference_new(model
, path
);
1883 if (gtk_tree_path_up(path
))
1884 upref
= gtk_tree_row_reference_new(model
, path
);
1885 gtk_tree_path_free(path
);
1887 g_object_ref(model
);
1888 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview
->treeview
), NULL
);
1890 move_nodes_up(model
, ref
, upref
);
1892 if (ref2iter(model
, ref
, &iter
))
1896 g_snprintf(tq
, sizeof(tq
), "SELECT parent FROM %s WHERE nodeid=%d", datatable_tmpname
, sql3id
);
1897 sqlite3_stmt
*stmt
= NULL
;
1899 int rc
= sqlite3_prepare(mainview
->db
, tq
, strlen(tq
), &stmt
, &dum
);
1900 unsigned int sql3parentid
= 0;
1904 maepad_warning("Error finding children for delete: %s", sqlite3_errmsg(mainview
->db
));
1909 while(rc
== SQLITE_BUSY
|| rc
== SQLITE_ROW
)
1911 rc
= sqlite3_step(stmt
);
1912 if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
|| rc
== SQLITE_DONE
)
1914 else if (rc
== SQLITE_ROW
)
1916 sql3parentid
= sqlite3_column_int(stmt
, 0);
1920 sqlite3_finalize(stmt
);
1922 g_snprintf(tq
, sizeof(tq
), "UPDATE %s SET parent=%d WHERE parent=%d;", datatable_tmpname
, sql3parentid
, sql3id
);
1923 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
1924 maepad_warning("Error moving nodes up one level");
1927 g_snprintf(tq
, sizeof(tq
), "DELETE FROM %s WHERE nodeid=%d;", datatable_tmpname
, sql3id
);
1928 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
1929 maepad_warning("Error deleting node");
1932 /* Delete all checklist items that do not have
1933 * a node anymore (= orphaned checklist items) */
1934 g_snprintf(tq
, sizeof(tq
), "DELETE FROM %s WHERE nodeid NOT IN (SELECT nodeid FROM %s);", checklisttable_tmpname
, datatable_tmpname
);
1935 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
1936 maepad_warning("Error deleting orphaned checklist items");
1940 gtk_tree_store_remove(GTK_TREE_STORE(model
), &iter
);
1943 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview
->treeview
), model
);
1944 g_object_unref(model
);
1946 gtk_tree_row_reference_free(ref
);
1947 gtk_tree_row_reference_free(upref
);
1949 gtk_tree_view_expand_all(GTK_TREE_VIEW(mainview
->treeview
));
1953 void callback_edit_clear(GtkAction
* action
, gpointer data
)
1955 MainView
*mainview
= (MainView
*) data
;
1956 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
1957 nodeData
*nd
= getSelectedNode(mainview
);
1959 if (show_confirmation(mainview
, _("Remove all contents of this memo?"))) {
1962 gtk_text_buffer_set_text(GTK_TEXT_BUFFER(mainview
->buffer
), "", 0);
1965 sketchwidget_clear(mainview
->sk
);
1967 case NODE_CHECKLIST
:
1968 gtk_list_store_clear(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->listview
))));
1971 /* Unknown node type */
1980 void callback_edit_cut(GtkAction
* action
, gpointer data
)
1982 MainView
*mainview
= (MainView
*) data
;
1983 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
1985 nodeData
*nd
= getSelectedNode(mainview
);
1987 if (nd
->typ
== NODE_TEXT
)
1988 gtk_text_buffer_cut_clipboard(GTK_TEXT_BUFFER(mainview
->buffer
), mainview
->clipboard
, TRUE
);
1989 else if (nd
->typ
== NODE_SKETCH
)
1991 if (sketchwidget_cut(mainview
->sk
, mainview
->clipboard
)==FALSE
)
1992 show_banner(mainview
, _("Error cutting"));
1994 else if (nd
->typ
== NODE_CHECKLIST
)
1995 show_banner(mainview
, _("Unimplemented"));
2002 void callback_edit_copy(GtkAction
* action
, gpointer data
)
2004 MainView
*mainview
= (MainView
*) data
;
2005 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2007 nodeData
*nd
= getSelectedNode(mainview
);
2009 if (nd
->typ
== NODE_TEXT
)
2010 gtk_text_buffer_copy_clipboard(GTK_TEXT_BUFFER(mainview
->buffer
), mainview
->clipboard
);
2011 else if (nd
->typ
== NODE_SKETCH
)
2013 if (sketchwidget_copy(mainview
->sk
, mainview
->clipboard
)==FALSE
)
2014 show_banner(mainview
, _("Error copying"));
2016 else if (nd
->typ
== NODE_CHECKLIST
)
2018 /* Copy all selected entries as multiline text (1 line per entry) */
2019 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->listview
));
2020 GtkTreeSelection
*selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->listview
));
2022 gint selected_rows
= gtk_tree_selection_count_selected_rows(selection
);
2023 GList
* l
= gtk_tree_selection_get_selected_rows(selection
, NULL
);
2028 gchar
**entries
= g_malloc0(sizeof(gchar
*)*selected_rows
+1);
2029 gint entries_idx
= 0;
2033 GtkTreePath
*path
= cur
->data
;
2035 if (gtk_tree_model_get_iter(model
, &iter
, path
)) {
2036 gtk_tree_model_get(GTK_TREE_MODEL(model
), &iter
, CHECKNODE_TEXT
, &(entries
[entries_idx
++]), -1);
2038 gtk_tree_path_free(path
);
2044 str_data
= g_strjoinv("\n", entries
);
2045 g_strfreev(entries
);
2046 gtk_clipboard_set_text(mainview
->clipboard
, str_data
, -1);
2049 str_data
= g_strdup_printf(_("Copied %d entries"), selected_rows
);
2050 show_banner(mainview
, str_data
);
2059 void callback_edit_paste(GtkAction
* action
, gpointer data
)
2061 MainView
*mainview
= (MainView
*) data
;
2062 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2064 nodeData
*nd
= getSelectedNode(mainview
);
2066 if (nd
->typ
== NODE_TEXT
)
2067 gtk_text_buffer_paste_clipboard(GTK_TEXT_BUFFER(mainview
->buffer
), mainview
->clipboard
, NULL
, TRUE
);
2068 else if (nd
->typ
== NODE_SKETCH
)
2070 if (sketchwidget_paste(mainview
->sk
, mainview
->clipboard
)==FALSE
)
2071 show_banner(mainview
, _("Error pasting"));
2073 else if (nd
->typ
== NODE_CHECKLIST
) {
2074 /* Paste string from clipboard as new item */
2075 callback_checklist_paste(mainview
);
2078 mainview
->file_edited
= TRUE
;
2081 gint
cb_popup(GtkWidget
* widget
, GdkEvent
* event
)
2084 GdkEventButton
*event_button
;
2087 * The "widget" is the menu that was supplied when
2088 * * g_signal_connect_swapped() was called.
2090 menu
= GTK_MENU(widget
);
2091 event_button
= (GdkEventButton
*) event
;
2092 if (event
->type
== GDK_BUTTON_PRESS
&& event_button
->button
== 3)
2094 gtk_menu_popup(menu
, NULL
, NULL
, NULL
, NULL
, event_button
->button
, event_button
->time
);
2103 gboolean
closefile(MainView
* mainview
)
2105 saveCurrentData(mainview
);
2107 if (mainview
->file_edited
)
2109 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
));
2110 gint answer
= gtk_dialog_run(GTK_DIALOG(hn
));
2111 gtk_widget_destroy(GTK_WIDGET(hn
));
2113 if (answer
== CONFRESP_CANCEL
)
2115 else if (answer
== CONFRESP_YES
)
2117 if (mainview
->file_name
== NULL
)
2119 mainview
->file_name
= interface_file_chooser(mainview
, GTK_FILE_CHOOSER_ACTION_SAVE
, "maemopaddata", "db");
2121 write_buffer_to_file(mainview
);
2126 sqlite3_close(mainview
->db
);
2127 mainview
->db
= NULL
;
2131 gboolean
callback_file_close(GtkAction
* action
, gpointer data
)
2134 MainView
*mainview
= (MainView
*) data
;
2135 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2136 if (closefile(mainview
) == FALSE
)
2143 void callback_file_new_node(GtkAction
* action
, gpointer data
)
2145 MainView
*mainview
= (MainView
*) data
;
2146 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2148 nodeType typ
= NODE_SKETCH
;
2150 nodeData
*nd
= getSelectedNode(mainview
);
2155 new_node_dialog(typ
, mainview
);
2161 void callback_file_new(GtkAction
* action
, gpointer data
)
2163 MainView
*mainview
= (MainView
*) data
;
2164 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2166 gchar
*filename
= NULL
;
2168 if (closefile(mainview
) == FALSE
)
2171 filename
= interface_file_chooser(mainview
, GTK_FILE_CHOOSER_ACTION_SAVE
, "memos", "db");
2172 if (filename
== NULL
)
2179 busy_enter(mainview
);
2183 rc
= sqlite3_open(filename
, &mainview
->db
);
2186 show_banner(mainview
, _("Cannot create database"));
2187 maepad_warning("Can't create database %s: %s", filename
, sqlite3_errmsg(mainview
->db
));
2191 sqlite3_exec(mainview
->db
, "PRAGMA synchronous = OFF;", NULL
, NULL
, NULL
);
2195 g_snprintf(tq
, sizeof(tq
), "CREATE TABLE %s%s", misctable_name
, misctable
);
2196 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
2198 g_snprintf(tq
, sizeof(tq
), "CREATE TABLE %s%s", datatable_name
, datatable
);
2199 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0)
2201 maepad_warning("Cannot create data table");
2202 show_banner(mainview
, _("Error creating data table"));
2206 g_snprintf(tq
, sizeof(tq
), "CREATE TABLE %s%s", checklisttable_name
, checklisttable
);
2207 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0)
2209 maepad_warning("Cannot create checklist table");
2210 show_banner(mainview
, _("Error creating checklist table"));
2215 sqlite3_close(mainview
->db
);
2216 mainview
->db
= NULL
;
2218 mainview
->file_name
= filename
;
2219 mainview
->file_edited
= FALSE
;
2220 read_file_to_buffer(mainview
);
2222 /*add a starter memo*/
2224 node
= g_malloc(sizeof(nodeData
));
2225 node
->typ
= NODE_SKETCH
;
2226 node
->name
= _("My first memo");
2227 node
->namepix
= NULL
;
2231 add_new_node(node
, mainview
, TRUE
);
2232 /*gtk_paned_set_position(GTK_PANED(mainview->hpaned), 180);*/
2233 write_buffer_to_file(mainview
);
2236 busy_reset(mainview
);
2239 gboolean
reset_ctree(GtkTreeModel
* model
, GtkTreePath
* path
, GtkTreeIter
* iter
, gpointer data
)
2243 gtk_tree_model_get(model
, iter
, NODE_DATA
, &node
, -1);
2249 g_object_unref(node
->namepix
);
2252 gtk_tree_store_set(GTK_TREE_STORE(model
), iter
, NODE_DATA
, NULL
, -1);
2257 void new_file(MainView
* mainview
)
2259 busy_enter(mainview
);
2261 * clear buffer, filename and free buffer text
2263 gtk_text_buffer_set_text(GTK_TEXT_BUFFER(mainview
->buffer
), "", -1);
2264 mainview
->file_name
= NULL
;
2265 mainview
->file_edited
= FALSE
;
2266 mainview
->newnodedialog_createchild
= TRUE
;
2268 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->treeview
));
2270 g_object_ref(model
);
2271 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview
->treeview
), NULL
);
2273 gtk_tree_model_foreach(model
, (GtkTreeModelForeachFunc
) reset_ctree
, (gpointer
) mainview
);
2277 * gtk_tree_store_clear(GTK_TREE_STORE(model));
2279 GtkTreePath
*path
= gtk_tree_path_new_from_indices(0, -1);
2282 if (gtk_tree_model_get_iter(model
, &iter
, path
))
2286 gtk_tree_store_remove(GTK_TREE_STORE(model
), &iter
);
2288 while(gtk_tree_store_iter_is_valid(GTK_TREE_STORE(model
), &iter
));
2290 gtk_tree_path_free(path
);
2292 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview
->treeview
), model
);
2293 g_object_unref(model
);
2295 prepareUIforNodeChange(mainview
, NODE_UNKNOWN
);
2296 busy_leave(mainview
);
2302 void callback_file_open(GtkAction
* action
, gpointer data
)
2304 gchar
*filename
= NULL
;
2305 MainView
*mainview
= (MainView
*) data
;
2306 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2308 if (closefile(mainview
) == FALSE
)
2314 filename
= interface_file_chooser(mainview
, GTK_FILE_CHOOSER_ACTION_OPEN
, NULL
, NULL
);
2317 * if we got a file name from chooser -> open file
2319 open_file(filename
, mainview
);
2323 gboolean
open_file(gchar
* filename
, MainView
* mainview
)
2327 busy_enter(mainview
);
2329 while(filename
!= NULL
)
2333 if (stat(filename
, &s
) == -1) break;
2335 mainview
->file_name
= g_strdup(filename
);
2336 gboolean res
= read_file_to_buffer(mainview
);
2340 g_free(mainview
->file_name
);
2341 mainview
->file_name
= NULL
;
2344 mainview
->file_edited
= FALSE
;
2349 busy_leave(mainview
);
2353 void callback_about_link(GtkAboutDialog
*about
, const gchar
*link
, gpointer data
)
2355 MainView
*mainview
= (MainView
*) data
;
2356 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2357 osso_rpc_run_with_defaults(mainview
->data
->osso
, "osso_browser", OSSO_BROWSER_OPEN_NEW_WINDOW_REQ
, NULL
,
2358 DBUS_TYPE_STRING
, link
, DBUS_TYPE_INVALID
);
2361 void callback_about(GtkAction
* action
, gpointer data
)
2363 MainView
* mainview
= (MainView
*)data
;
2364 he_about_dialog_present(mainview_get_dialog_parent(mainview
),
2365 NULL
/* auto-detect app name */,
2368 _("A node-based memory pad for Maemo"),
2369 _("(c) 2008-2010 Thomas Perl, (c) 2006-2008 Kemal Hadimli"),
2370 "http://thpinfo.com/2010/maepad/",
2371 NULL
/* TODO: Add bug tracker URL */,
2372 "http://thpinfo.com/2010/maepad/donate");
2378 void callback_file_save(GtkAction
* action
, gpointer data
)
2380 gchar
*filename
= NULL
;
2381 MainView
*mainview
= (MainView
*) data
;
2382 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2385 * check is we had a new file
2387 if (mainview
->file_name
!= NULL
)
2389 write_buffer_to_file(mainview
);
2393 filename
= interface_file_chooser(mainview
, GTK_FILE_CHOOSER_ACTION_SAVE
, "maemopaddata", "db");
2395 * if we got a file name from chooser -> save file
2397 if (filename
!= NULL
)
2399 mainview
->file_name
= filename
;
2400 write_buffer_to_file(mainview
);
2401 mainview
->file_edited
= FALSE
;
2406 void callback_shapemenu(GtkAction
* action
, GtkWidget
* wid
)
2408 int style
= (int)gtk_object_get_user_data(GTK_OBJECT(wid
));
2409 MainView
*mainview
= gtk_object_get_data(GTK_OBJECT(wid
), "m");
2411 g_assert(mainview
!= NULL
);
2413 if (style
==0) sketchwidget_set_shape(mainview
->sk
, SKETCHSHAPE_FREEHAND
);
2414 else if (style
==1) sketchwidget_set_shape(mainview
->sk
, SKETCHSHAPE_LINE
);
2415 else if (style
==2) sketchwidget_set_shape(mainview
->sk
, SKETCHSHAPE_RECT
);
2416 else if (style
==3) sketchwidget_set_shape(mainview
->sk
, SKETCHSHAPE_ELLIPSE
);
2421 void callback_eraser(GtkAction
* action
, MainView
* mainview
)
2423 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2425 if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(mainview
->eraser_tb
)) == TRUE
)
2433 mainview
->sk
->pressuresensitivity
=FALSE
;
2435 sketchwidget_set_brushcolor(mainview
->sk
, c2
);
2436 mainview
->brushsize_backup
= sketchwidget_get_brushsize(mainview
->sk
);
2437 guint ers
=(mainview
->brushsize_backup
*4)+4;
2438 sk_set_brushsize(mainview
, ers
);
2439 sketchwidget_set_brushsize(mainview
->sk
, ers
); /*fixme:to override max brush size, not pretty*/
2443 if (mainview
->current_color
== NULL
) {
2444 GdkColor color
= {0, 0, 0, 0};
2445 mainview
->current_color
= gdk_color_copy(&color
);
2447 /* pressure sensitivity disabled for now...
2448 mainview->sk->pressuresensitivity=gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(mainview->tools_pressure));*/
2450 sketchwidget_set_brushcolor(mainview
->sk
, *(mainview
->current_color
));
2451 sk_set_brushsize(mainview
, mainview
->brushsize_backup
);
2455 void callback_menu(GtkAction
* action
, GtkWidget
* menu
)
2457 gtk_menu_popup(GTK_MENU(menu
), NULL
, NULL
, NULL
, NULL
, 0, GDK_CURRENT_TIME
);
2460 void callback_brushsizetb(GtkAction
* action
, MainView
*mainview
)
2462 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2464 if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(mainview
->eraser_tb
)) == TRUE
)
2466 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview
->eraser_tb
), FALSE
);
2470 callback_menu(NULL
, mainview
->brushsizemenu
);
2474 void callback_brushsize(GtkAction
* action
, GtkWidget
* wid
)
2476 int bsize
= (int)gtk_object_get_user_data(GTK_OBJECT(wid
));
2477 MainView
*mainview
= gtk_object_get_data(GTK_OBJECT(wid
), "m");
2479 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2481 sketchwidget_set_brushsize(mainview
->sk
, bsize
);
2483 GtkWidget
*pix
= gtk_object_get_data(GTK_OBJECT(wid
), "i");
2485 gtk_widget_show(pix
);
2486 gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(mainview
->brushsize_tb
), pix
);
2489 void callback_sketchlines(GtkAction
* action
, GtkWidget
* wid
)
2491 int style
= (int)gtk_object_get_user_data(GTK_OBJECT(wid
));
2492 MainView
*mainview
= gtk_object_get_data(GTK_OBJECT(wid
), "m");
2494 g_assert(mainview
!= NULL
);
2496 nodeData
*nd
= getSelectedNode(mainview
);
2497 gboolean doit
= FALSE
;
2499 if (nd
!= NULL
&& nd
->typ
== NODE_SKETCH
)
2501 nd
->flags
&= ~NODEFLAG_SKETCHLINES
;
2502 nd
->flags
&= ~NODEFLAG_SKETCHGRAPH
;
2503 /* sketchwidget_set_edited(mainview->sk, TRUE);*/ /*we call this on openfile, so this messes things up*/
2509 sketchwidget_set_backstyle(mainview
->sk
, SKETCHBACK_NONE
);
2511 else if (style
== 1)
2513 sketchwidget_set_backstyle(mainview
->sk
, SKETCHBACK_LINES
);
2515 nd
->flags
|= NODEFLAG_SKETCHLINES
;
2517 else if (style
== 2)
2519 sketchwidget_set_backstyle(mainview
->sk
, SKETCHBACK_GRAPH
);
2521 nd
->flags
|= NODEFLAG_SKETCHGRAPH
;
2524 GtkWidget
*pix
= gtk_object_get_data(GTK_OBJECT(wid
), "i");
2526 gtk_widget_show(pix
);
2527 gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(mainview
->sketchlines_tb
), pix
);
2530 void callback_color(GtkAction
* action
, MainView
* mainview
)
2532 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2534 nodeData
*nd
= getSelectedNode(mainview
);
2535 if (nd
== NULL
) return;
2537 HeSimpleColorDialog
* dialog
= HE_SIMPLE_COLOR_DIALOG(he_simple_color_dialog_new());
2538 gtk_window_set_transient_for(GTK_WINDOW(dialog
), mainview_get_dialog_parent(mainview
));
2540 if (mainview
->current_color
) {
2541 he_simple_color_dialog_set_color(dialog
, mainview
->current_color
);
2544 if (gtk_dialog_run(GTK_DIALOG(dialog
)) != GTK_RESPONSE_OK
) {
2545 gtk_widget_destroy(GTK_WIDGET(dialog
));
2549 gdk_color_free(mainview
->current_color
);
2550 mainview
->current_color
= he_simple_color_dialog_get_color(dialog
);
2552 gtk_widget_destroy(GTK_WIDGET(dialog
));
2556 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview
->eraser_tb
), FALSE
);
2557 sketchwidget_set_brushcolor(mainview
->sk
, *(mainview
->current_color
));
2559 case NODE_CHECKLIST
:
2560 { /* Put in a separate block to allow new local variables */
2561 GtkTreeModel
* model
= gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->listview
));
2562 GtkTreeSelection
* selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->listview
));
2563 GList
* selected
= gtk_tree_selection_get_selected_rows(selection
, NULL
);
2565 gchar
* color_string
= g_strdup_printf("#%02x%02x%02x",
2566 mainview
->current_color
->red
>> 8,
2567 mainview
->current_color
->green
>> 8,
2568 mainview
->current_color
->blue
>> 8);
2570 GList
* cur
= selected
;
2571 while (cur
!= NULL
) {
2572 GtkTreePath
* path
= cur
->data
;
2574 if (gtk_tree_model_get_iter(model
, &iter
, path
)) {
2575 gtk_list_store_set(GTK_LIST_STORE(model
), &iter
, CHECKNODE_COLOR
, color_string
, -1);
2577 gtk_tree_path_free(path
);
2581 g_list_free(selected
);
2582 g_free(color_string
);
2586 g_error("Wrong node type for color selection");
2591 void callback_color_invoke(GtkAction
* action
, gpointer data
)
2593 MainView
*mainview
= (MainView
*) data
;
2594 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2595 gtk_button_clicked(GTK_BUTTON(mainview
->colorbutton_tb
));
2600 void callback_pressure(GtkAction
* action
, MainView
*mainview
)
2602 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2604 nodeData
*nd
= getSelectedNode(mainview
);
2608 if (nd
->typ
!= NODE_SKETCH
)
2611 /* pressure sensitivity disabled for now...
2612 mainview->sk->pressuresensitivity=gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(mainview->tools_pressure));*/
2616 void callback_wordwrap(GtkAction
* action
, MainView
*mainview
)
2618 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2620 nodeData
*nd
= getSelectedNode(mainview
);
2624 if (nd
->typ
!= NODE_TEXT
)
2627 gboolean act
=gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(mainview
->tools_wordwrap
));
2628 if (act
==TRUE
) nd
->flags
|= NODEFLAG_WORDWRAP
;
2629 else nd
->flags
&= ~NODEFLAG_WORDWRAP
;
2631 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(mainview
->textview
), (act
==TRUE
)?GTK_WRAP_WORD
:GTK_WRAP_NONE
);
2635 void callback_font(GtkAction
* action
, gpointer data
)
2637 MainView
*mainview
= (MainView
*) data
;
2638 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2640 nodeData
*nd
= getSelectedNode(mainview
);
2644 if (nd
->typ
!= NODE_TEXT
)
2647 HildonFontSelectionDialog
*dialog
= HILDON_FONT_SELECTION_DIALOG(hildon_font_selection_dialog_new(NULL
, NULL
));
2649 gboolean gotsel
=wp_text_buffer_has_selection(mainview
->buffer
);
2652 WPTextBufferFormat fmt
;
2653 wp_text_buffer_get_attributes(mainview
->buffer
, &fmt
, gotsel
);
2656 if (fmt
.text_position
==TEXT_POSITION_SUPERSCRIPT
) ri
=1;
2657 else if (fmt
.text_position
==TEXT_POSITION_SUBSCRIPT
) ri
=-1;
2659 g_object_set(G_OBJECT(dialog
),
2660 "family-set", fmt
.cs
.font
,
2661 "family", wp_get_font_name(fmt
.font
),
2662 "size-set", fmt
.cs
.font_size
,
2663 "size", wp_font_size
[fmt
.font_size
],
2664 "color-set", fmt
.cs
.color
,
2665 "color", &fmt
.color
,
2666 "bold-set", fmt
.cs
.bold
,
2668 "italic-set", fmt
.cs
.italic
,
2669 "italic", fmt
.italic
,
2670 "underline-set", fmt
.cs
.underline
,
2671 "underline", fmt
.underline
,
2672 "strikethrough-set", fmt
.cs
.strikethrough
,
2673 "strikethrough", fmt
.strikethrough
,
2674 "position-set", fmt
.cs
.text_position
,
2678 gtk_widget_show_all(GTK_WIDGET(dialog
));
2679 if (gtk_dialog_run(GTK_DIALOG(dialog
)) == GTK_RESPONSE_OK
)
2681 gboolean bold
, italic
, underline
, strikethrough
;
2682 gchar
*family
= NULL
;
2683 gint size
, position
;
2684 GdkColor
*color
=NULL
;
2685 gboolean set_family
, set_size
, set_bold
, set_italic
, set_underline
, set_strikethrough
, set_color
, set_position
;
2687 g_object_get(G_OBJECT(dialog
), "family", &family
, "size", &size
, "bold", &bold
, "italic", &italic
,
2688 "underline", &underline
, "strikethrough", &strikethrough
,
2689 "family-set", &set_family
, "size-set", &set_size
, "bold-set", &set_bold
, "italic-set", &set_italic
,
2690 "underline-set", &set_underline
, "strikethrough-set", &set_strikethrough
,
2691 "color", &color
, "color-set", &set_color
, "position", &position
, "position-set", &set_position
,
2694 wp_text_buffer_get_attributes(mainview
->buffer
, &fmt
, FALSE
);
2695 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;
2697 if (set_family
) { fmt
.font
=wp_get_font_index(family
, 1); fmt
.cs
.font
=1; }
2698 if (set_size
) { fmt
.font_size
=wp_get_font_size_index(size
, 16); fmt
.cs
.font_size
=1; }
2700 if (set_strikethrough
)
2702 fmt
.cs
.strikethrough
=1;
2703 fmt
.strikethrough
=strikethrough
;
2709 GLIB WARNING ** GLib-GObject - IA__g_object_set_valist: object class `GtkTextTag' has no property named `'
2712 fmt
.color
.pixel
=color
->pixel
;
2713 fmt
.color
.red
=color
->red
;
2714 fmt
.color
.green
=color
->green
;
2715 fmt
.color
.blue
=color
->blue
;
2720 if (position
==1) ri
=TEXT_POSITION_SUPERSCRIPT
;
2721 else if (position
==-1) ri
=TEXT_POSITION_SUBSCRIPT
;
2722 else ri
=TEXT_POSITION_NORMAL
;
2724 fmt
.cs
.text_position
=1;
2725 fmt
.text_position
=ri
;
2741 fmt
.underline
=underline
;
2744 wp_text_buffer_set_format(mainview
->buffer
, &fmt
);
2747 gtk_widget_destroy(GTK_WIDGET(dialog
));
2750 void callback_fontstyle(GtkAction
* action
, GtkWidget
* wid
)
2752 MainView
*mainview
= gtk_object_get_data(GTK_OBJECT(wid
), "m");
2753 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2755 nodeData
*nd
= getSelectedNode(mainview
);
2759 if (nd
->typ
== NODE_TEXT
)
2761 gboolean act
=gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(wid
));
2763 gint style
= (gint
)gtk_object_get_data(GTK_OBJECT(wid
), "s");
2764 wp_text_buffer_set_attribute(mainview
->buffer
, style
, (gpointer
)act
);
2766 else if (nd
->typ
== NODE_CHECKLIST
)
2768 gboolean act
=gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(wid
));
2769 gint style
= (gint
)gtk_object_get_data(GTK_OBJECT(wid
), "s");
2770 if (style
!=WPT_BOLD
&& style
!=WPT_STRIKE
&& style
!=WPT_LEFT
) return;
2772 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->listview
));
2773 GList
* l
=gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->listview
)), NULL
);
2775 gint styletoset_weight
=PANGO_WEIGHT_NORMAL
;
2776 gboolean styletoset_strike
=FALSE
;
2777 gboolean checkit
=FALSE
;
2779 if (style
==WPT_BOLD
&& act
==TRUE
) styletoset_weight
=PANGO_WEIGHT_BOLD
;
2780 else if (style
==WPT_STRIKE
&& act
==TRUE
) styletoset_strike
=TRUE
;
2781 else if (style
==WPT_LEFT
&& act
==TRUE
) checkit
=TRUE
;
2786 GtkTreePath
*path
=cur
->data
;
2789 if (gtk_tree_model_get_iter(model
, &iter
, path
))
2791 if (style
==WPT_BOLD
) gtk_list_store_set(GTK_LIST_STORE(model
), &iter
, CHECKNODE_BOLD
, styletoset_weight
, -1);
2792 else if (style
==WPT_STRIKE
) gtk_list_store_set(GTK_LIST_STORE(model
), &iter
, CHECKNODE_STRIKE
, styletoset_strike
, -1);
2793 else if (style
==WPT_LEFT
) {
2794 gtk_list_store_set(GTK_LIST_STORE(model
), &iter
, CHECKNODE_CHECKED
, checkit
, -1);
2796 gtk_list_store_set(GTK_LIST_STORE(model
), &iter
, CHECKNODE_ICON_NAME
, "widgets_tickmark_list", -1);
2798 gtk_list_store_set(GTK_LIST_STORE(model
), &iter
, CHECKNODE_ICON_NAME
, NULL
, -1);
2802 gtk_tree_path_free(path
);
2807 mainview
->checklist_edited
= TRUE
;
2812 void callback_textbuffer_move(WPTextBuffer
*textbuffer
, MainView
*mainview
)
2814 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2817 gboolean gotsel=wp_text_buffer_has_selection(mainview->buffer);
2819 _toggle_tool_button_set_inconsistent(GTK_TOGGLE_TOOL_BUTTON(mainview->bold_tb), gotsel);
2820 _toggle_tool_button_set_inconsistent(GTK_TOGGLE_TOOL_BUTTON(mainview->italic_tb), gotsel);
2821 _toggle_tool_button_set_inconsistent(GTK_TOGGLE_TOOL_BUTTON(mainview->underline_tb), gotsel);
2822 _toggle_tool_button_set_inconsistent(GTK_TOGGLE_TOOL_BUTTON(mainview->bullet_tb), gotsel);
2824 WPTextBufferFormat fmt
;
2825 wp_text_buffer_get_attributes(mainview
->buffer
, &fmt
, FALSE
/*gotsel*/);
2827 g_signal_handlers_block_by_func(mainview
->bold_tb
, callback_fontstyle
, mainview
->bold_tb
);
2828 g_signal_handlers_block_by_func(mainview
->italic_tb
, callback_fontstyle
, mainview
->italic_tb
);
2829 g_signal_handlers_block_by_func(mainview
->underline_tb
, callback_fontstyle
, mainview
->underline_tb
);
2830 g_signal_handlers_block_by_func(mainview
->bullet_tb
, callback_fontstyle
, mainview
->bullet_tb
);
2832 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview
->bold_tb
), fmt
.bold
);
2833 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview
->italic_tb
), fmt
.italic
);
2834 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview
->underline_tb
), fmt
.underline
);
2835 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview
->bullet_tb
), fmt
.bullet
);
2837 g_signal_handlers_unblock_by_func(mainview
->bold_tb
, callback_fontstyle
, mainview
->bold_tb
);
2838 g_signal_handlers_unblock_by_func(mainview
->italic_tb
, callback_fontstyle
, mainview
->italic_tb
);
2839 g_signal_handlers_unblock_by_func(mainview
->underline_tb
, callback_fontstyle
, mainview
->underline_tb
);
2840 g_signal_handlers_unblock_by_func(mainview
->bullet_tb
, callback_fontstyle
, mainview
->bullet_tb
);
2843 gint
wp_savecallback(const gchar
*buffer
, GString
* gstr
)
2845 gstr
=g_string_append(gstr
, buffer
);
2849 void callback_undo(GtkAction
* action
, MainView
* mainview
)
2851 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2853 nodeData
*nd
= getSelectedNode(mainview
);
2855 if (nd
== NULL
) return;
2857 if (nd
->typ
== NODE_SKETCH
) sketchwidget_undo(mainview
->sk
);
2858 else if (nd
->typ
== NODE_TEXT
) wp_text_buffer_undo(mainview
->buffer
);
2861 void callback_redo(GtkAction
* action
, MainView
* mainview
)
2863 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2865 nodeData
*nd
= getSelectedNode(mainview
);
2867 if (nd
== NULL
) return;
2869 if (nd
->typ
== NODE_SKETCH
) sketchwidget_redo(mainview
->sk
);
2870 else if (nd
->typ
== NODE_TEXT
) wp_text_buffer_redo(mainview
->buffer
);
2873 void callback_undotoggle(gpointer widget
, gboolean st
, MainView
* mainview
)
2875 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2877 gtk_widget_set_sensitive(GTK_WIDGET(mainview
->undo_tb
), st
);
2880 void callback_redotoggle(gpointer widget
, gboolean st
, MainView
* mainview
)
2882 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2884 gtk_widget_set_sensitive(GTK_WIDGET(mainview
->redo_tb
), st
);
2887 gboolean
close_cb(GtkWidget
* widget
, GdkEventAny
* event
, MainView
* mainview
)
2889 callback_file_close(NULL
, mainview
);
2893 gboolean
key_press_cb(GtkWidget
* widget
, GdkEventKey
* event
, MainView
* mainview
)
2895 switch (event
->keyval
)
2900 * gtk_infoprint(GTK_WINDOW(app), "Navigation Key Up");
2904 * gtk_infoprint(GTK_WINDOW(app), "Navigation Key Down");
2908 * gtk_infoprint(GTK_WINDOW(app), "Navigation Key Left");
2912 * gtk_infoprint(GTK_WINDOW(app), "Navigation Key Right");
2916 * gtk_infoprint(GTK_WINDOW(app), "Navigation Key select");
2919 /*code below messes up when you have a textview*/
2924 gtk_widget_child_focus(widget, event->keyval==GDK_Left?GTK_DIR_TAB_BACKWARD:GTK_DIR_TAB_FORWARD);
2930 nodeData
*selnode
= getSelectedNode(mainview
);
2931 if (selnode
!=NULL
&& selnode
->typ
==NODE_SKETCH
)
2933 show_banner(mainview
, _("Squared shapes ON"));
2934 sketchwidget_set_shift(mainview
->sk
, TRUE
);
2941 nodeData
*selnode
= getSelectedNode(mainview
);
2942 if (selnode
!=NULL
&& selnode
->typ
==NODE_SKETCH
)
2944 show_banner(mainview
, _("Squared shapes OFF"));
2945 sketchwidget_set_shift(mainview
->sk
, FALSE
);
2952 nodeData
*selnode
= getSelectedNode(mainview
);
2953 if (selnode
!=NULL
&& selnode
->typ
==NODE_SKETCH
)
2955 show_banner(mainview
, _("Filled shapes OFF"));
2956 sketchwidget_set_fillmode(mainview
->sk
, FALSE
);
2963 nodeData
*selnode
= getSelectedNode(mainview
);
2964 if (selnode
!=NULL
&& selnode
->typ
==NODE_SKETCH
)
2966 show_banner(mainview
, _("Filled shapes ON"));
2967 sketchwidget_set_fillmode(mainview
->sk
, TRUE
);
2974 callback_redo(NULL
, mainview
);
2979 callback_undo(NULL
, mainview
);
2987 void callback_fullscreen(GtkToolButton
* tool_button
, gpointer user_data
)
2989 MainView
* mainview
= (MainView
*)user_data
;
2990 gtk_window_fullscreen(GTK_WINDOW(mainview
->data
->node_view
));
2993 void callback_buffer_modified(GtkAction
* action
, gpointer data
)
2995 MainView
*mainview
= (MainView
*) data
;
2996 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2998 mainview
->file_edited
= TRUE
;
3001 GtkTreeRowReference
*read_sqlite3_data(MainView
* mainview
, unsigned int parentid
, GtkTreeRowReference
* parenttree
, unsigned int selected
, GtkTreeStore
* model
)
3003 GtkTreeRowReference
*resref
= NULL
;
3007 g_snprintf(q
, sizeof(q
), "SELECT nodeid, bodytype, name, nameblob, lastmodified, flags FROM %s WHERE parent=%d ORDER BY ord", datatable_tmpname
, parentid
);
3009 sqlite3_stmt
*stmt
= NULL
;
3011 int rc
= sqlite3_prepare(mainview
->db
, q
, strlen(q
), &stmt
, &dum
);
3015 maepad_warning("Error reading SQLite3 data: %s", sqlite3_errmsg(mainview
->db
));
3020 while(rc
== SQLITE_BUSY
|| rc
== SQLITE_ROW
)
3022 rc
= sqlite3_step(stmt
);
3023 if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
|| rc
== SQLITE_DONE
)
3025 else if (rc
== SQLITE_ROW
)
3027 int nodeid
= sqlite3_column_int(stmt
, 0);
3028 int typ
= sqlite3_column_int(stmt
, 1);
3029 const unsigned char *name
= sqlite3_column_text(stmt
, 2);
3030 const unsigned char *nameblob
= sqlite3_column_text(stmt
, 3);
3031 int lastmod
= sqlite3_column_int(stmt
, 4);
3032 int flags
= sqlite3_column_int(stmt
, 5);
3034 if ((typ
!= NODE_TEXT
&& typ
!= NODE_SKETCH
&& typ
!= NODE_CHECKLIST
) || (name
== NULL
&& nameblob
== NULL
)) {
3035 maepad_warning("Unknown node type in database: %d (skipping)", typ
);
3039 nodeData
*node
= g_malloc(sizeof(nodeData
));
3041 node
->sql3id
= nodeid
;
3043 node
->flags
= flags
;
3045 node
->namepix
= NULL
;
3047 node
->name
= g_strdup((char *)name
);
3049 node
->name
= g_strdup(_("Unnamed node"));
3051 /*if (nameblob != NULL)
3053 int blobsize = sqlite3_column_bytes(stmt, 3);
3055 GdkPixbufLoader *pl = gdk_pixbuf_loader_new_with_type("png", NULL);
3058 gdk_pixbuf_loader_write(pl, (guchar *) nameblob, blobsize, &err);
3061 fprintf(stderr, "Error loading nodename! %s\n", err->message);
3065 gdk_pixbuf_loader_close(pl, NULL);
3066 GdkPixbuf *pixbuf = gdk_pixbuf_loader_get_pixbuf(pl);
3068 if (GDK_IS_PIXBUF(pixbuf))
3069 node->namepix = pixbuf;
3071 node
->lastMod
= lastmod
;
3073 GtkTreeIter parentiter
, newiter
;
3076 if (parenttree
!= NULL
)
3078 GtkTreePath
*pa
= gtk_tree_row_reference_get_path(parenttree
);
3080 gtk_tree_model_get_iter(GTK_TREE_MODEL(model
), &parentiter
, pa
);
3081 gtk_tree_path_free(pa
);
3085 gtk_tree_store_append(model
, &newiter
, par
);
3086 gtk_tree_store_set(model
, &newiter
, NODE_NAME
, node
->name
, NODE_PIXBUF
, node
->namepix
, NODE_DATA
, node
, -1);
3088 GtkTreePath
*pa
= gtk_tree_model_get_path(GTK_TREE_MODEL(model
), &newiter
);
3090 GtkTreeRowReference
*newref
= gtk_tree_row_reference_new(GTK_TREE_MODEL(model
), pa
);
3092 if (selected
== nodeid
)
3095 gtk_tree_path_free(pa
);
3096 GtkTreeRowReference
*r
= read_sqlite3_data(mainview
, nodeid
, newref
, selected
,
3099 if (resref
!= newref
)
3100 gtk_tree_row_reference_free(newref
);
3107 gtk_tree_row_reference_free(r
); /*safeguard */
3113 sqlite3_finalize(stmt
);
3115 return (resref
); /*ref to supposed-to-be-selected treeitem */
3121 gboolean
read_file_to_buffer(MainView
* mainview
)
3125 g_assert(mainview
!= NULL
);
3126 gboolean res
= FALSE
;
3128 gchar
*filename
= mainview
->file_name
;
3131 mainview
->file_name
= filename
;
3132 mainview
->loading
=TRUE
;
3134 maepad_message("Reading database file: %s", filename
);
3137 sqlite3_stmt
*stmt
= NULL
;
3139 rc
= sqlite3_open(filename
, &mainview
->db
);
3144 maepad_warning("Cannot open database %s: %s", filename
, sqlite3_errmsg(mainview
->db
));
3148 sqlite3_exec(mainview
->db
, "PRAGMA synchronous = OFF;", NULL
, NULL
, NULL
);
3150 char *q
= "SELECT skey, sval FROM settings";
3153 rc
= sqlite3_prepare(mainview
->db
, q
, strlen(q
), &stmt
, &dum
);
3156 maepad_warning("Error reading settings: %s", sqlite3_errmsg(mainview
->db
));
3160 unsigned int selectedCard
= 0;
3161 unsigned int curDataVersion
= 0;
3162 unsigned int curChecklistVersion
= 0;
3165 while(rc
== SQLITE_BUSY
|| rc
== SQLITE_ROW
)
3167 rc
= sqlite3_step(stmt
);
3168 if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
|| rc
== SQLITE_DONE
)
3170 else if (rc
== SQLITE_ROW
)
3172 const gchar
* col_key
= (const gchar
*)sqlite3_column_text(stmt
, 0);
3173 const gchar
* col_val
= (const gchar
*)sqlite3_column_text(stmt
, 1);
3174 if (!strcmp(col_key
, "selectedNode"))
3176 gint tmp
= atoi((char *)col_val
);
3181 if (!strcmp(col_key
, "dataVersion"))
3183 gint tmp
= atoi((char *)col_val
);
3186 curDataVersion
= tmp
;
3188 if (!strcmp(col_key
, "checklistVersion"))
3190 gint tmp
= atoi((char *)col_val
);
3193 curChecklistVersion
= tmp
;
3195 if (!strcmp(col_key
, "newNodeDlgCreateChild"))
3197 gint tmp
= atoi((char *)col_val
);
3199 mainview
->newnodedialog_createchild
= TRUE
;
3201 mainview
->newnodedialog_createchild
= FALSE
;
3203 if (!strcmp(col_key
, "brushSize"))
3205 gint tmp
= atoi((char *)col_val
);
3206 if (tmp
>0) sk_set_brushsize(mainview
, tmp
);
3208 if (!strcmp(col_key
, "brushColor"))
3210 unsigned long tmp
= atol((char *)col_val
);
3213 c2
.red
= ((tmp
& 0xFF0000) >> 16) << 8;
3214 c2
.green
= ((tmp
& 0xFF00) >> 8) << 8;
3215 c2
.blue
= (tmp
& 0xFF) << 8;
3216 sketchwidget_set_brushcolor(mainview
->sk
, c2
);
3218 if (mainview
->current_color
!= NULL
) {
3219 gdk_color_free(mainview
->current_color
);
3221 mainview
->current_color
= gdk_color_copy(&c2
);
3226 if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
)
3228 maepad_warning("Error reading data: %s", sqlite3_errmsg(mainview
->db
));
3233 sqlite3_finalize(stmt
);
3237 gboolean resback
= FALSE
;
3239 while(curDataVersion
< datatableversion
)
3241 if (curDataVersion
== 0)
3243 g_snprintf(tq
, sizeof(tq
), "DROP TABLE %s", datatable_backupname
);
3244 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3246 g_snprintf(tq
, sizeof(tq
), "ALTER TABLE %s RENAME TO %s", datatable_name
, datatable_backupname
);
3247 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
3248 maepad_warning("Error backing up table %s to %s", datatable_name
, datatable_backupname
);
3253 g_snprintf(tq
, sizeof(tq
), "CREATE TABLE %s%s", datatable_name
, datatable
);
3254 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
3255 maepad_warning("Error creating table: %s", datatable_name
);
3258 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s SELECT nodeid, parent, bodytype, name, body, nameblob, bodyblob, lastmodified, ord, 0 FROM %s", datatable_name
, datatable_backupname
);
3259 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
3260 maepad_warning("Error copying data from %s to %s", datatable_name
, datatable_backupname
);
3264 g_snprintf(tq
, sizeof(tq
), "DROP TABLE %s", datatable_backupname
);
3265 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3267 curDataVersion
= datatableversion
;
3272 if (curDataVersion
!= datatableversion
)
3274 maepad_warning("Data table version mismatch: %d <=> %d", curDataVersion
, datatableversion
);
3276 if (resback
== TRUE
)
3278 g_snprintf(tq
, sizeof(tq
), "DROP TABLE %s", datatable_name
);
3279 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3280 g_snprintf(tq
, sizeof(tq
), "ALTER TABLE %s RENAME TO %s", datatable_backupname
, datatable_name
);
3281 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3288 while(curChecklistVersion
< checklisttableversion
)
3290 if (curChecklistVersion
== 0) /*no checklisttable at all*/
3292 g_snprintf(tq
, sizeof(tq
), "CREATE TABLE %s%s", checklisttable_name
, checklisttable
);
3293 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
3294 maepad_warning("Error creating checklist table during schema upgrade");
3297 curChecklistVersion
= checklisttableversion
;
3303 GtkTreeStore
*model
= GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->treeview
)));
3305 g_object_ref(model
);
3306 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview
->treeview
), NULL
);
3312 g_snprintf(tq
, sizeof(tq
), "CREATE%s TABLE %s%s", TEMPTABLE_KEYWORD
, datatable_tmpname
, datatable
);
3313 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
3314 maepad_warning("Error creating temp table: %s", datatable_tmpname
);
3317 g_snprintf(tq
, sizeof(tq
), "CREATE INDEX %s_index ON %s %s", datatable_tmpname
, datatable_tmpname
, dataindex
);
3318 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
3319 maepad_warning("Error creating temp index for %s", datatable_tmpname
);
3322 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s SELECT * FROM %s", datatable_tmpname
, datatable_name
);
3323 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
3324 maepad_warning("Error copying data from %s to %s", datatable_name
, datatable_tmpname
);
3328 g_snprintf(tq
, sizeof(tq
), "CREATE%s TABLE %s%s", TEMPTABLE_KEYWORD
, checklisttable_tmpname
, checklisttable
);
3329 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
3330 maepad_warning("Error creating temp table: %s", checklisttable_tmpname
);
3333 g_snprintf(tq
, sizeof(tq
), "CREATE INDEX %s_index ON %s %s", checklisttable_tmpname
, checklisttable_tmpname
, checklistindex
);
3334 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
3335 maepad_warning("Error creating temp index for %s", checklisttable_tmpname
);
3338 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s SELECT * FROM %s", checklisttable_tmpname
, checklisttable_name
);
3339 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
3340 maepad_warning("Error copying data from %s to %s", checklisttable_name
, checklisttable_tmpname
);
3346 GtkTreeRowReference
*selectedRef
= read_sqlite3_data(mainview
, 0, NULL
, selectedCard
, model
);
3348 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview
->treeview
), GTK_TREE_MODEL(model
));
3349 g_object_unref(model
);
3350 gtk_tree_view_expand_all(GTK_TREE_VIEW(mainview
->treeview
));
3352 if (selectedRef
!= NULL
)
3354 GtkTreeIter seliter
;
3356 if (ref2iter(GTK_TREE_MODEL(model
), selectedRef
, &seliter
) == TRUE
)
3358 GtkTreeSelection
*selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->treeview
));
3359 gtk_tree_selection_select_iter(selection
, &seliter
);
3362 gtk_tree_row_reference_free(selectedRef
);
3369 sqlite3_finalize(stmt
);
3373 mainview
->loading
=FALSE
;
3381 void write_buffer_to_file(MainView
* mainview
)
3383 maepad_message("Writing database to file: %s", mainview
->file_name
);
3384 saveCurrentData(mainview
);
3386 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->treeview
));
3387 /*update ord value in database for all nodes*/
3388 gtk_tree_model_foreach(GTK_TREE_MODEL(model
),(GtkTreeModelForeachFunc
) foreach_func_update_ord
,mainview
);
3390 busy_enter(mainview
);
3394 g_snprintf(tq
, sizeof(tq
), "DROP TABLE %s", misctable_name
);
3395 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3397 g_snprintf(tq
, sizeof(tq
), "CREATE TABLE %s%s", misctable_name
, misctable
);
3398 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3402 if (mainview
->newnodedialog_createchild
== FALSE
)
3404 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s VALUES('newNodeDlgCreateChild', '%d');", misctable_name
, nndcc
);
3405 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3407 nodeData
*node
= getSelectedNode(mainview
);
3411 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s VALUES('selectedNode', '%d');", misctable_name
, node
->sql3id
);
3412 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3416 if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(mainview
->eraser_tb
)) == TRUE
)
3418 bsize
=mainview
->brushsize_backup
;
3422 bsize
=sketchwidget_get_brushsize(mainview
->sk
);
3424 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s VALUES('brushSize', '%d');", misctable_name
, bsize
);
3425 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3427 if (mainview
->current_color
== NULL
) {
3428 GdkColor color
= {0, 0, 0, 0};
3429 mainview
->current_color
= gdk_color_copy(&color
);
3431 unsigned long bcol
= ((mainview
->current_color
->red
>> 8) << 16) |
3432 ((mainview
->current_color
->green
>> 8) << 8) |
3433 ((mainview
->current_color
->blue
) >> 8);
3435 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s VALUES('brushColor', '%lu');", misctable_name
, bcol
);
3436 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3438 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s VALUES('dataVersion', '%d');", misctable_name
, datatableversion
);
3439 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3441 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s VALUES('checklistVersion', '%d');", misctable_name
, checklisttableversion
);
3442 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3444 g_snprintf(tq
, sizeof(tq
), "DROP TABLE %s", datatable_backupname
);
3445 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3446 g_snprintf(tq
, sizeof(tq
), "CREATE TABLE %s%s", datatable_backupname
, datatable
);
3447 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0)
3449 maepad_warning("Error creating backup table: %s", datatable_backupname
);
3450 show_banner(mainview
, _("Error creating backup table"));
3452 busy_leave(mainview
);
3455 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s SELECT * FROM %s", datatable_backupname
, datatable_name
);
3456 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0)
3458 maepad_warning("Error backing up table %s to %s", datatable_name
, datatable_backupname
);
3459 show_banner(mainview
, _("Error creating backup table"));
3461 busy_leave(mainview
);
3464 g_snprintf(tq
, sizeof(tq
), "DELETE FROM %s", datatable_name
);
3465 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3467 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s SELECT * FROM %s", datatable_name
, datatable_tmpname
);
3468 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0)
3470 maepad_warning("Error saving table %s to %s", datatable_tmpname
, datatable_name
);
3471 show_banner(mainview
, _("Error saving table"));
3473 g_snprintf(tq
, sizeof(tq
), "DELETE FROM %s", datatable_name
);
3474 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3476 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s SELECT * FROM %s", datatable_name
, datatable_backupname
);
3477 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
3478 maepad_warning("Error restoring backup. Data lost :(");
3481 busy_leave(mainview
);
3485 g_snprintf(tq
, sizeof(tq
), "DROP TABLE %s", datatable_backupname
);
3486 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3489 g_snprintf(tq
, sizeof(tq
), "DROP TABLE %s", checklisttable_backupname
);
3490 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3491 g_snprintf(tq
, sizeof(tq
), "CREATE TABLE %s%s", checklisttable_backupname
, checklisttable
);
3492 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0)
3494 maepad_warning("Error creating backup table: %s", checklisttable_backupname
);
3495 show_banner(mainview
, _("Error creating checklist backup table"));
3497 busy_leave(mainview
);
3501 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s SELECT * FROM %s", checklisttable_backupname
, checklisttable_name
);
3502 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0)
3504 maepad_warning("Error backing up table %s to %s", checklisttable_name
, checklisttable_backupname
);
3505 show_banner(mainview
, _("Error creating checklist backup table"));
3507 busy_leave(mainview
);
3510 g_snprintf(tq
, sizeof(tq
), "DELETE FROM %s", checklisttable_name
);
3511 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3513 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s SELECT * FROM %s", checklisttable_name
, checklisttable_tmpname
);
3514 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0)
3516 maepad_warning("Error saving table %s to %s", checklisttable_tmpname
, checklisttable_name
);
3517 show_banner(mainview
, _("Error saving checklist table"));
3519 g_snprintf(tq
, sizeof(tq
), "DELETE FROM %s", checklisttable_name
);
3520 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3522 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s SELECT * FROM %s", checklisttable_name
, checklisttable_backupname
);
3523 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
3524 maepad_warning("Error restoring backup. Data lost :(");
3526 busy_leave(mainview
);
3530 g_snprintf(tq
, sizeof(tq
), "DROP TABLE %s", checklisttable_backupname
);
3531 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3533 mainview
->file_edited
= FALSE
;
3534 busy_leave(mainview
);
3535 show_banner(mainview
, _("Changes saved"));
3538 void callback_checklist_change(GtkTreeSelection
*selection
, MainView
*mainview
)
3540 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
3542 g_signal_handlers_block_by_func(mainview
->bold_tb
, callback_fontstyle
, mainview
->bold_tb
);
3543 g_signal_handlers_block_by_func(mainview
->strikethru_tb
, callback_fontstyle
, mainview
->strikethru_tb
);
3544 g_signal_handlers_block_by_func(mainview
->check_tb
, callback_fontstyle
, mainview
->check_tb
);
3546 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview
->bold_tb
), FALSE
);
3547 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview
->strikethru_tb
), FALSE
);
3548 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview
->check_tb
), FALSE
);
3550 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->listview
));
3551 GList
* l
=gtk_tree_selection_get_selected_rows(selection
, NULL
);
3553 gboolean gotit
=FALSE
;
3558 GtkTreePath
*path
=cur
->data
;
3563 if (gtk_tree_model_get_iter(model
, &iter
, path
))
3565 gint styletoset_weight
;
3566 gboolean styletoset_strike
;
3569 gtk_tree_model_get(GTK_TREE_MODEL(model
), &iter
, CHECKNODE_BOLD
, &styletoset_weight
, CHECKNODE_STRIKE
, &styletoset_strike
, CHECKNODE_CHECKED
, &ischecked
, -1);
3570 if (styletoset_weight
==PANGO_WEIGHT_BOLD
) gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview
->bold_tb
), TRUE
);
3571 if (styletoset_strike
==TRUE
) gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview
->strikethru_tb
), TRUE
);
3572 if (ischecked
==TRUE
) gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview
->check_tb
), TRUE
);
3576 gtk_tree_path_free(path
);
3582 g_signal_handlers_unblock_by_func(mainview
->bold_tb
, callback_fontstyle
, mainview
->bold_tb
);
3583 g_signal_handlers_unblock_by_func(mainview
->strikethru_tb
, callback_fontstyle
, mainview
->strikethru_tb
);
3584 g_signal_handlers_unblock_by_func(mainview
->check_tb
, callback_fontstyle
, mainview
->check_tb
);
3587 void callback_checklist_paste(MainView
*mainview
)
3589 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
3593 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->listview
));
3594 GtkTreeIter toplevel
;
3595 gchar
*pasted_text
= gtk_clipboard_wait_for_text(mainview
->clipboard
);
3597 entries
= g_strsplit(pasted_text
, "\n", 0);
3598 length
= g_strv_length(entries
);
3600 for (i
=0; i
<length
; i
++) {
3601 gtk_list_store_append(GTK_LIST_STORE(model
), &toplevel
);
3602 gtk_list_store_set(GTK_LIST_STORE(model
), &toplevel
, CHECKNODE_CHECKED
, FALSE
, CHECKNODE_TEXT
, entries
[i
], -1);
3605 mainview
->checklist_edited
= TRUE
;
3606 g_free(pasted_text
);
3607 g_strfreev(entries
);
3610 void callback_checklist_add(GtkAction
*action
, MainView
*mainview
)
3612 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
3614 gchar
* text
= show_line_edit_dialog(mainview
, _("Add new checklist item"), _("Name:"), _("Add"), "");
3617 GtkTreeModel
* model
= gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->listview
));
3618 GtkTreeIter toplevel
;
3619 gtk_list_store_append(GTK_LIST_STORE(model
), &toplevel
);
3621 gtk_list_store_set(GTK_LIST_STORE(model
),
3623 CHECKNODE_CHECKED
, FALSE
,
3624 CHECKNODE_TEXT
, text
,
3627 GtkTreePath
*path
= gtk_tree_model_get_path(model
, &toplevel
);
3629 gtk_tree_view_set_cursor(GTK_TREE_VIEW(mainview
->listview
), path
, mainview
->listtextcol
, FALSE
);
3630 gtk_tree_path_free(path
);
3633 mainview
->checklist_edited
= TRUE
;
3637 void callback_checklist_edit(GtkAction
*action
, MainView
*mainview
)
3639 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
3641 GtkTreeSelection
* selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->listview
));
3643 if (gtk_tree_selection_count_selected_rows(selection
) == 0) {
3644 show_banner(mainview
, _("Select items first"));
3648 GtkTreeModel
* model
;
3651 if (gtk_tree_selection_get_selected(selection
, &model
, &iter
)) {
3652 gchar
* old_text
= NULL
;
3653 gtk_tree_model_get(model
, &iter
, CHECKNODE_TEXT
, &old_text
, -1);
3655 gchar
* new_text
= show_line_edit_dialog(mainview
, _("Edit checklist item"), _("New name:"), _("Save"), old_text
);
3657 if (new_text
!= NULL
) {
3658 gtk_list_store_set(GTK_LIST_STORE(model
), &iter
, CHECKNODE_TEXT
, new_text
, -1);
3665 mainview
->checklist_edited
= TRUE
;
3668 void callback_checklist_delete(GtkAction
*action
, MainView
*mainview
)
3670 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
3672 if (gtk_tree_selection_count_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->listview
)))==0) {
3673 show_banner(mainview
, _("Select items first"));
3677 if (show_confirmation(mainview
, _("Delete selected checklist item?"))) {
3678 callback_checklist_delete_real(mainview
);
3682 void callback_checklist_delete_real(MainView
* mainview
)
3684 GtkTreeModel
*model
=gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->listview
));
3685 GList
* l
=gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->listview
)), NULL
);
3687 GList
* rowrefs
=NULL
;
3691 GtkTreePath
*path
=cur
->data
;
3694 if (gtk_tree_model_get_iter(model
, &iter
, path
))
3696 GtkTreeRowReference
*rowref
= gtk_tree_row_reference_new(model
, path
);
3697 rowrefs
=g_list_append(rowrefs
, rowref
);
3699 gtk_tree_path_free(path
);
3704 g_object_ref(model
);
3705 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview
->listview
), NULL
);
3710 GtkTreeRowReference
*rowref
=cur
->data
;
3711 GtkTreePath
*path
= gtk_tree_row_reference_get_path(rowref
);
3715 if (gtk_tree_model_get_iter(model
, &iter
, path
)) gtk_list_store_remove(GTK_LIST_STORE(model
), &iter
);
3716 gtk_tree_path_free(path
);
3718 gtk_tree_row_reference_free(rowref
);
3721 g_list_free(rowrefs
);
3723 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview
->listview
), model
);
3724 g_object_unref(model
);
3725 mainview
->checklist_edited
= TRUE
;
3728 /* Ask the user for confirmation of a specific action */
3730 show_confirmation(MainView
* mainview
, gchar
* question
)
3732 GtkDialog
* dialog
= GTK_DIALOG(hildon_note_new_confirmation(
3733 GTK_WINDOW(mainview
->data
->main_view
), question
));
3734 gtk_window_set_transient_for(GTK_WINDOW(dialog
), mainview_get_dialog_parent(mainview
));
3736 gint response
= gtk_dialog_run(dialog
);
3737 gtk_widget_destroy(GTK_WIDGET(dialog
));
3739 return (response
== GTK_RESPONSE_OK
);
3742 /* Show a information banner to the user (non-modal) */
3744 show_banner(MainView
* mainview
, const gchar
* text
)
3746 hildon_banner_show_information(GTK_WIDGET(mainview_get_dialog_parent(mainview
)), NULL
, text
);
3749 /* Let the user enter or edit a line of text */
3751 show_line_edit_dialog(MainView
* mainview
, const gchar
* title
, const gchar
* label_text
, const gchar
* action
, const gchar
* text
)
3753 GtkWidget
* edit_dialog
;
3757 gchar
* result
= NULL
;
3759 edit_dialog
= GTK_WIDGET(gtk_dialog_new());
3760 gtk_window_set_title(GTK_WINDOW(edit_dialog
), title
);
3761 gtk_window_set_transient_for(GTK_WINDOW(edit_dialog
), mainview_get_dialog_parent(mainview
));
3763 label
= GTK_WIDGET(gtk_label_new(label_text
));
3765 entry
= hildon_entry_new(HILDON_SIZE_AUTO
);
3766 gtk_entry_set_text(GTK_ENTRY(entry
), text
);
3767 gtk_entry_set_activates_default(GTK_ENTRY(entry
), TRUE
);
3768 gtk_editable_select_region(GTK_EDITABLE(entry
), 0, -1);
3770 gtk_dialog_add_button(GTK_DIALOG(edit_dialog
), action
, GTK_RESPONSE_OK
);
3771 gtk_dialog_set_default_response(GTK_DIALOG(edit_dialog
), GTK_RESPONSE_OK
);
3773 hbox
= GTK_WIDGET(gtk_hbox_new(FALSE
, 10));
3775 gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(edit_dialog
))), GTK_WIDGET(hbox
));
3776 gtk_box_pack_start(GTK_BOX(hbox
), label
, FALSE
, FALSE
, 0);
3777 gtk_box_pack_start(GTK_BOX(hbox
), entry
, TRUE
, TRUE
, 0);
3779 gtk_widget_show_all(GTK_WIDGET(hbox
));
3782 if (gtk_dialog_run(GTK_DIALOG(edit_dialog
)) == GTK_RESPONSE_OK
) {
3783 result
= g_strdup(gtk_entry_get_text(GTK_ENTRY(entry
)));
3784 if (strcmp(result
, "") != 0) {
3787 show_banner(mainview
, _("Please enter a non-empty text"));
3797 gtk_widget_destroy(GTK_WIDGET(edit_dialog
));