2 * This file is part of MaePad
3 * Copyright (c) 2010 Thomas Perl <thp@thpinfo.com>
4 * http://thpinfo.com/2010/maepad/
7 * Copyright (c) 2006-2008 Kemal Hadimli
8 * Copyright (c) 2008 Thomas Perl
10 * This software is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public License
12 * as published by the Free Software Foundation; either version 2.1 of
13 * the License, or (at your option) any later version.
15 * This software is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this software; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
27 #include <ui/callbacks.h>
28 #include <ui/interface.h>
30 #include <gdk/gdkkeysyms.h>
36 * strlen needed from string.h
39 #include <sys/types.h>
47 #include <hildon/hildon.h>
48 #include <hildon/hildon-banner.h>
49 #include <hildon/hildon-note.h>
50 #include <hildon/hildon-font-selection-dialog.h>
51 #include <tablet-browser-interface.h>
53 #include <libgnomevfs/gnome-vfs.h>
55 #include "sketchwidget.h"
57 #include "../he/he-about-dialog.h"
58 #include "../he/he-simple-color-dialog.h"
61 * "Busy" status handling
63 * Use "busy_reset" to reset the busy status (turn off)
64 * Use "busy_enter" when starting time-consuming processing
65 * Use "busy_leave" when processing has been finished
73 /* Don't use this directly, but make use of the macros defined below */
74 void set_busy(MainView
* mainview
, SetBusyType update
);
76 #define busy_reset(mainview) set_busy(mainview, BUSY_RESET)
77 #define busy_enter(mainview) set_busy(mainview, BUSY_INCREMENT)
78 #define busy_leave(mainview) set_busy(mainview, BUSY_DECREMENT)
84 gboolean
read_file_to_buffer(MainView
* mainview
);
85 void write_buffer_to_file(MainView
* mainview
);
86 void new_node_dialog(nodeType typ
, MainView
* mainview
);
87 gboolean
foreach_func_update_ord (GtkTreeModel
*model
,GtkTreePath
*path
,GtkTreeIter
*iter
, MainView
*mainview
);
88 void move_nodes_up(GtkTreeModel
* model
, GtkTreeRowReference
* topnode
, GtkTreeRowReference
* newtop
);
89 GtkTreeRowReference
*iter2ref(GtkTreeModel
* model
, GtkTreeIter
* iter
);
90 gboolean
exec_command_on_db(MainView
*mainview
,char sql_string
[]);
91 int get_node_id_on_tmp_db(GtkTreeModel
*model
,GtkTreeIter
*iter
);
92 gint
get_branch_node_index(GtkTreePath
*path
);
93 gboolean
move_node(MainView
*mainview
,GtkTreeIter
*new_parent
,GtkTreeIter
*item_to_move
,GtkTreeIter
*item_befor
);
94 gboolean
tree_model_iter_prev(GtkTreeModel
*tree_model
,GtkTreeIter
*iter
);
95 gboolean
show_confirmation(MainView
* mainview
, gchar
* question
);
99 gboolean
callback_node_view_window_state(GtkWidget
* window
,
100 GdkEventWindowState
* event
, gpointer user_data
)
102 MainView
* mainview
= (MainView
*)user_data
;
103 GtkWidget
* sketch_scroll
= NULL
;
105 if (mainview
->toolbar
== NULL
|| mainview
->sk
== NULL
) {
109 sketch_scroll
= GTK_WIDGET(sketchwidget_get_mainwidget(mainview
->sk
));
111 if (event
->changed_mask
& GDK_WINDOW_STATE_FULLSCREEN
) {
112 if (event
->new_window_state
& GDK_WINDOW_STATE_FULLSCREEN
) {
113 gtk_widget_hide(mainview
->toolbar
);
114 gtk_scrolled_window_set_policy(
115 GTK_SCROLLED_WINDOW(sketch_scroll
),
119 gtk_widget_show(mainview
->toolbar
);
120 gtk_scrolled_window_set_policy(
121 GTK_SCROLLED_WINDOW(sketch_scroll
),
122 GTK_POLICY_AUTOMATIC
,
123 GTK_POLICY_AUTOMATIC
);
130 void set_busy(MainView
* mainview
, SetBusyType update
)
134 mainview
->busyrefcount
= 0;
137 mainview
->busyrefcount
++;
140 if (mainview
->busyrefcount
> 0) {
141 mainview
->busyrefcount
--;
145 g_assert_not_reached();
149 hildon_gtk_window_set_progress_indicator(GTK_WINDOW(mainview
->data
->main_view
), (mainview
->busyrefcount
> 0));
150 hildon_gtk_window_set_progress_indicator(GTK_WINDOW(mainview
->data
->node_view
), (mainview
->busyrefcount
> 0));
153 void prepareUIforNodeChange(MainView
* mainview
, nodeType typ
)
155 gtk_widget_set_sensitive(GTK_WIDGET(mainview
->undo_tb
), TRUE
);
156 gtk_widget_set_sensitive(GTK_WIDGET(mainview
->redo_tb
), TRUE
);
158 if (typ
== NODE_TEXT
)
160 gtk_widget_show(GTK_WIDGET(mainview
->font_tb
));
161 gtk_widget_show(GTK_WIDGET(mainview
->bold_tb
));
162 gtk_widget_show(GTK_WIDGET(mainview
->italic_tb
));
163 gtk_widget_show(GTK_WIDGET(mainview
->underline_tb
));
164 gtk_widget_show(GTK_WIDGET(mainview
->bullet_tb
));
165 gtk_widget_show(mainview
->tools_font
);
166 gtk_widget_show(mainview
->tools_wordwrap
);
170 gtk_widget_hide(GTK_WIDGET(mainview
->font_tb
));
171 gtk_widget_hide(GTK_WIDGET(mainview
->bold_tb
));
172 gtk_widget_hide(GTK_WIDGET(mainview
->italic_tb
));
173 gtk_widget_hide(GTK_WIDGET(mainview
->underline_tb
));
174 gtk_widget_hide(GTK_WIDGET(mainview
->bullet_tb
));
175 gtk_widget_hide(mainview
->tools_font
);
176 gtk_widget_hide(mainview
->tools_wordwrap
);
179 if (typ
== NODE_SKETCH
)
181 /* gtk_widget_show(GTK_WIDGET(mainview->colorbutton_tb));*/
182 gtk_widget_show(GTK_WIDGET(mainview
->eraser_tb
));
183 gtk_widget_show(GTK_WIDGET(mainview
->brushsize_tb
));
184 gtk_widget_show(GTK_WIDGET(mainview
->sketchlines_tb
));
185 gtk_widget_show(GTK_WIDGET(mainview
->shape_tb
));
186 gtk_widget_show(mainview
->tools_color
);
187 gtk_widget_show(mainview
->tools_brushsize
);
188 gtk_widget_show(mainview
->tools_pagestyle
);
189 gtk_widget_show(mainview
->tools_shape
);
190 gtk_widget_show(mainview
->tools_pressure
);
194 /* gtk_widget_hide(GTK_WIDGET(mainview->colorbutton_tb));*/
195 gtk_widget_hide(GTK_WIDGET(mainview
->eraser_tb
));
196 gtk_widget_hide(GTK_WIDGET(mainview
->brushsize_tb
));
197 gtk_widget_hide(GTK_WIDGET(mainview
->sketchlines_tb
));
198 gtk_widget_hide(GTK_WIDGET(mainview
->shape_tb
));
199 gtk_widget_hide(mainview
->tools_color
);
200 gtk_widget_hide(mainview
->tools_brushsize
);
201 gtk_widget_hide(mainview
->tools_pagestyle
);
202 gtk_widget_hide(mainview
->tools_shape
);
203 gtk_widget_hide(mainview
->tools_pressure
);
206 if (typ
== NODE_CHECKLIST
)
208 gtk_widget_show(GTK_WIDGET(mainview
->bold_tb
));
209 gtk_widget_show(GTK_WIDGET(mainview
->strikethru_tb
));
210 gtk_widget_show(GTK_WIDGET(mainview
->check_tb
));
211 gtk_widget_show(GTK_WIDGET(mainview
->checkadd_tb
));
212 gtk_widget_show(GTK_WIDGET(mainview
->checkedit_tb
));
213 gtk_widget_show(GTK_WIDGET(mainview
->checkdel_tb
));
214 gtk_widget_hide(GTK_WIDGET(mainview
->undo_tb
));
215 gtk_widget_hide(GTK_WIDGET(mainview
->redo_tb
));
219 gtk_widget_hide(GTK_WIDGET(mainview
->strikethru_tb
));
220 gtk_widget_hide(GTK_WIDGET(mainview
->check_tb
));
221 gtk_widget_hide(GTK_WIDGET(mainview
->checkadd_tb
));
222 gtk_widget_hide(GTK_WIDGET(mainview
->checkedit_tb
));
223 gtk_widget_hide(GTK_WIDGET(mainview
->checkdel_tb
));
224 gtk_widget_show(GTK_WIDGET(mainview
->undo_tb
));
225 gtk_widget_show(GTK_WIDGET(mainview
->redo_tb
));
228 if (typ
== NODE_TEXT
)
230 gtk_widget_hide(GTK_WIDGET(mainview
->colorbutton_tb
));
231 gtk_widget_hide(sketchwidget_get_mainwidget(mainview
->sk
));
232 gtk_widget_hide(mainview
->listscroll
);
233 gtk_widget_show(GTK_WIDGET(mainview
->scrolledwindow
));
234 gtk_widget_show(mainview
->tools_item
);
236 else if (typ
== NODE_SKETCH
)
238 gtk_widget_show(GTK_WIDGET(mainview
->colorbutton_tb
));
239 gtk_widget_hide(GTK_WIDGET(mainview
->scrolledwindow
));
240 gtk_widget_hide(mainview
->listscroll
);
241 gtk_widget_show(sketchwidget_get_mainwidget(mainview
->sk
));
242 gtk_widget_show(mainview
->tools_item
);
244 else if (typ
== NODE_CHECKLIST
)
246 gtk_widget_show(GTK_WIDGET(mainview
->colorbutton_tb
));
247 gtk_widget_hide(GTK_WIDGET(mainview
->scrolledwindow
));
248 gtk_widget_hide(sketchwidget_get_mainwidget(mainview
->sk
));
249 gtk_widget_hide(mainview
->tools_item
);
250 gtk_widget_show(mainview
->listscroll
);
254 gtk_widget_hide(GTK_WIDGET(mainview
->colorbutton_tb
));
255 gtk_widget_hide(GTK_WIDGET(mainview
->scrolledwindow
));
256 gtk_widget_hide(sketchwidget_get_mainwidget(mainview
->sk
));
257 gtk_widget_hide(mainview
->tools_item
);
258 gtk_widget_hide(mainview
->listscroll
);
262 nodeData
*getSelectedNode(MainView
* mainview
)
269 GtkTreeSelection
*selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->treeview
));
271 if (!gtk_tree_selection_get_selected(selection
, &model
, &iter
))
274 gtk_tree_model_get(model
, &iter
, NODE_DATA
, &nd
, -1);
279 void saveCurrentData(MainView
* mainview
)
281 nodeData
*selnode
= getSelectedNode(mainview
);
282 saveDataToNode(mainview
, selnode
);
285 void saveDataToNode(MainView
* mainview
, nodeData
*selnode
)
291 (selnode
->typ
== NODE_SKETCH
&& sketchwidget_get_edited(mainview
->sk
) == FALSE
) ||
292 (selnode
->typ
== NODE_TEXT
&& wp_text_buffer_is_modified(mainview
->buffer
)==FALSE
) ||
293 (selnode
->typ
== NODE_CHECKLIST
&& mainview
->checklist_edited
==FALSE
)
296 maepad_message("node not edited, not saving");
300 mainview
->file_edited
= TRUE
;
302 busy_enter(mainview
);
303 maepad_debug("saveDataToNode working");
305 gboolean goterr
= TRUE
;
306 gchar
*textdata
= NULL
;
307 GdkPixbuf
*pixbuf
= NULL
;
308 gchar
*sketchdata
= NULL
;
312 if (selnode
->typ
== NODE_TEXT
)
315 GtkTextIter start
, end
;
316 gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(mainview
->buffer
), &start
, &end
);
317 textdata
= gtk_text_buffer_serialize_rich_text(GTK_TEXT_BUFFER(mainview
->buffer
), &start
, &end
, &datalen
);
320 GString
*gstr
=g_string_sized_new(4096);
321 wp_text_buffer_save_document(mainview
->buffer
, (WPDocumentSaveCallback
)(wp_savecallback
), gstr
);
324 textdata
=g_string_free(gstr
, FALSE
);
326 /* 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);*/
327 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
);
329 else if (selnode
->typ
== NODE_SKETCH
)
332 GdkPixmap
*skpix
= sketchwidget_get_Pixmap(mainview
->sk
);
333 GtkWidget
*skdr
= sketchwidget_get_drawingarea(mainview
->sk
);
335 pixbuf
= gdk_pixbuf_get_from_drawable(NULL
, GDK_DRAWABLE(skpix
), NULL
, 0, 0, 0, 0, skdr
->allocation
.width
, skdr
->allocation
.height
);
338 maepad_warning("error saving: pixbuf is null");
343 GdkPixbuf
*pixbuf2
= sketchwidget_trim_image(pixbuf
, skdr
->allocation
.width
, skdr
->allocation
.height
, &w
, &h
, FALSE
);
347 if (gdk_pixbuf_save_to_buffer(pixbuf2
, &sketchdata
, &datalen
, "png", &err
, NULL
) == FALSE
)
351 maepad_warning("Error saving sketch: %s", err
->message
);
354 gdk_pixbuf_unref(pixbuf2
);
357 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
);
358 maepad_debug("storing sketch in db: %d bytes", datalen
);
359 if (skpix
&& G_IS_OBJECT(skpix
)) g_object_unref(skpix
);
361 else if (selnode
->typ
== NODE_CHECKLIST
)
363 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
);
368 sqlite3_stmt
*stmt
= NULL
;
370 int rc
= sqlite3_prepare(mainview
->db
, tq
, strlen(tq
), &stmt
, &dum
);
374 maepad_warning("Error updating: %s", sqlite3_errmsg(mainview
->db
));
377 if (selnode
->typ
== NODE_TEXT
)
378 sqlite3_bind_text(stmt
, 1, textdata
, datalen
, /*strlen(textdata),*/ SQLITE_TRANSIENT
);
379 else if (selnode
->typ
== NODE_SKETCH
)
380 sqlite3_bind_blob(stmt
, 1, sketchdata
, datalen
, SQLITE_TRANSIENT
);
383 while(rc
== SQLITE_BUSY
)
385 rc
= sqlite3_step(stmt
);
386 if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
|| rc
== SQLITE_DONE
)
389 sqlite3_finalize(stmt
);
391 if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
)
393 maepad_warning("Error saving node: %s", sqlite3_errmsg(mainview
->db
));
397 if (selnode
->typ
== NODE_TEXT
)
398 gtk_text_buffer_set_modified(GTK_TEXT_BUFFER(mainview
->buffer
), FALSE
);
399 else if (selnode
->typ
== NODE_SKETCH
)
400 sketchwidget_set_edited(mainview
->sk
, FALSE
);
401 else if (selnode
->typ
== NODE_CHECKLIST
)
402 mainview
->checklist_edited
= FALSE
;
407 while(goterr
==FALSE
&& selnode
->typ
== NODE_CHECKLIST
)
409 GtkTreeModel
*model
=gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->listview
));
412 g_snprintf(tq
, sizeof(tq
), "DELETE FROM %s WHERE nodeid=%d", checklisttable_tmpname
, selnode
->sql3id
);
413 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
416 if (gtk_tree_model_get_iter_first(model
, &iter
)==FALSE
) break;
420 gint styletoset_weight
;
421 gboolean styletoset_strike
;
427 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);
430 if (color
!=NULL
&& strcmp(color
, "(null)")!=0 && gdk_color_parse(color
, &tmpcol
))
432 col
=((tmpcol
.red
>>8)<<16)|((tmpcol
.green
>>8)<<8)|(tmpcol
.blue
>>8);
436 if (ischecked
) style
|=CHECKSTYLE_CHECKED
;
437 if (styletoset_weight
==PANGO_WEIGHT_BOLD
) style
|=CHECKSTYLE_BOLD
;
438 if (styletoset_strike
) style
|=CHECKSTYLE_STRIKE
;
440 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s (nodeid, name, style, color, ord) VALUES(%d, ?, %d, %lu, 0)", checklisttable_tmpname
, selnode
->sql3id
, style
, col
);
441 sqlite3_stmt
*stmt
= NULL
;
443 int rc
= sqlite3_prepare(mainview
->db
, tq
, strlen(tq
), &stmt
, &dum
);
448 maepad_warning("Error while saving checklist: %s", sqlite3_errmsg(mainview
->db
));
451 sqlite3_bind_text(stmt
, 1, text
, strlen(text
), SQLITE_TRANSIENT
);
454 while(rc
== SQLITE_BUSY
)
456 rc
= sqlite3_step(stmt
);
457 if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
|| rc
== SQLITE_DONE
)
460 sqlite3_finalize(stmt
);
462 if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
)
465 maepad_warning("Error while saving checklist (2): %s", sqlite3_errmsg(mainview
->db
));
471 }while(gtk_tree_model_iter_next(model
, &iter
)==TRUE
);
482 show_banner(mainview
, _("Error saving memo"));
484 busy_leave(mainview
);
487 gboolean
callback_treeview_button_press(GtkTreeView
* treeview
, GdkEventButton
* event
, gpointer user_data
)
489 MainView
* mainview
= (MainView
*)user_data
;
492 if (mainview
->node_list_longpress_path
!= NULL
) {
493 /* Forget old, remembered tree path for longpress */
494 gtk_tree_path_free(mainview
->node_list_longpress_path
);
495 mainview
->node_list_longpress_path
= NULL
;
498 if (gtk_tree_view_get_path_at_pos(treeview
,
499 event
->x
, event
->y
, &path
, NULL
, NULL
, NULL
)) {
501 * Save this path in case we open the longpress menu to
502 * set the cursor in the treeview to the correct row.
504 * See on_node_menu_show() on how this is further used.
506 mainview
->node_list_longpress_path
= path
;
509 mainview
->can_show_node_view
= TRUE
;
514 void callback_treeview_celldatafunc(GtkTreeViewColumn
* tree_column
, GtkCellRenderer
* cell
, GtkTreeModel
* tree_model
, GtkTreeIter
* iter
, gpointer data
)
516 MainView
*mainview
= ( MainView
* ) data
;
517 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
521 gtk_tree_model_get(tree_model
, iter
, NODE_DATA
, &nd
, -1);
525 if (nd
->namepix
== NULL
)
527 g_object_set(cell
, "visible", FALSE
, NULL
);
531 g_object_set(cell
, "visible", TRUE
, NULL
);
532 g_object_set(cell
, "width", SKETCHNODE_RX
, NULL
);
533 g_object_set(cell
, "height", SKETCHNODE_RY
, NULL
);
538 gboolean
callback_treeview_testcollapse(GtkTreeView
* treeview
, GtkTreeIter
* arg1
, GtkTreePath
* arg2
, gpointer user_data
)
543 void callback_treeview_change(GtkTreeSelection
* selection
, gpointer data
)
545 MainView
*mainview
= (MainView
*) data
;
546 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
548 nodeData
*nd
= getSelectedNode(mainview
);
550 gchar
* nodeName
= _("View node");
552 if (nd
!= NULL
&& nd
->name
!= NULL
) {
556 /* Show node view with selected node */
557 gtk_window_set_title(GTK_WINDOW(mainview
->data
->node_view
),
560 if (mainview
->can_show_node_view
) {
561 gtk_widget_show(GTK_WIDGET(mainview
->data
->node_view
));
564 /* Make sure we don't accidentally collapse any nodes */
565 gtk_tree_view_expand_all(GTK_TREE_VIEW(mainview
->treeview
));
569 if (mainview
->cansel_time
>0 && mainview
->cansel_time
+1.0<tm
) mainview
->cansel_node
=NULL
;
573 if (mainview
->cansel_node
!=NULL
)
575 maepad_debug("[SELLOGIC] saving %d to unselect all nodes", (mainview
->cansel_node
)->sql3id
);
576 saveDataToNode(mainview
, (mainview
->cansel_node
));
577 mainview
->cansel_node
=NULL
;
582 if (mainview
->cansel_node
!=NULL
)
584 if (nd
->sql3id
== (mainview
->cansel_node
)->sql3id
)
586 mainview
->cansel_node
=NULL
;
587 maepad_debug("[SELLOGIC] doubly selected %d, doing nothing", nd
->sql3id
);
588 prepareUIforNodeChange(mainview
, nd
->typ
);
593 maepad_debug("[SELLOGIC] saving %d to load new node", (mainview
->cansel_node
)->sql3id
);
594 saveDataToNode(mainview
, (mainview
->cansel_node
));
595 mainview
->cansel_node
=NULL
;
600 if (nd
== NULL
) return;
602 busy_enter(mainview
);
604 gboolean goterr
= TRUE
;
605 char *textdata
= NULL
;
607 int blobsize
= 0, textsize
= 0;
611 g_snprintf(tq
, sizeof(tq
), "SELECT bodytype, body, bodyblob, flags FROM %s WHERE nodeid=%d", datatable_tmpname
, nd
->sql3id
);
612 sqlite3_stmt
*stmt
= NULL
;
614 int rc
= sqlite3_prepare(mainview
->db
, tq
, strlen(tq
), &stmt
, &dum
);
618 maepad_warning("Error reading (1): %s", sqlite3_errmsg(mainview
->db
));
623 while(rc
== SQLITE_BUSY
|| rc
== SQLITE_ROW
)
625 rc
= sqlite3_step(stmt
);
626 if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
|| rc
== SQLITE_DONE
)
628 else if (rc
== SQLITE_ROW
)
630 nd
->typ
= sqlite3_column_int(stmt
, 0);
631 nd
->flags
= sqlite3_column_int(stmt
, 3);
633 prepareUIforNodeChange(mainview
, nd
->typ
);
634 if (nd
->typ
== NODE_TEXT
)
636 gboolean file_edited_backup
= mainview
->file_edited
;
638 blobsize
= sqlite3_column_bytes(stmt
, 2);
639 blob
= (char *)sqlite3_column_blob(stmt
, 2);
641 textdata
= (char *)sqlite3_column_text(stmt
, 1);
642 textsize
= sqlite3_column_bytes(stmt
, 1);
644 /* gtk_text_buffer_set_text(GTK_TEXT_BUFFER(mainview->buffer), "", -1);*/
645 wp_text_buffer_reset_buffer(mainview
->buffer
, TRUE
);
647 gboolean richtext
=FALSE
;
652 gboolean oldway
=FALSE
;
656 strncpy(tst
, blob
, 8);
658 if (strcmp(tst
, "RICHTEXT")==0) oldway
=TRUE
;
664 gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(mainview
->buffer
), &iter
);
665 gtk_text_buffer_deserialize_rich_text(GTK_TEXT_BUFFER(mainview
->buffer
), &iter
, blob
, blobsize
, TRUE
, &err
);
679 wp_text_buffer_load_document_begin(mainview
->buffer
, TRUE
);
680 wp_text_buffer_load_document_write(mainview
->buffer
, blob
, blobsize
);
681 wp_text_buffer_load_document_end(mainview
->buffer
);
685 if (richtext
==FALSE
&& !(textdata
== NULL
|| g_utf8_validate(textdata
, textsize
, NULL
) == FALSE
))
687 /* gtk_text_buffer_set_text(GTK_TEXT_BUFFER(mainview->buffer), textdata, textsize);*/
688 wp_text_buffer_load_document_begin(mainview
->buffer
, FALSE
);
689 wp_text_buffer_load_document_write(mainview
->buffer
, textdata
, textsize
);
690 wp_text_buffer_load_document_end(mainview
->buffer
);
693 wp_text_buffer_enable_rich_text(mainview
->buffer
, TRUE
);
694 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview
->tools_wordwrap
), ((nd
->flags
& NODEFLAG_WORDWRAP
) > 0)?TRUE
:FALSE
);
695 callback_wordwrap(NULL
, mainview
); /*FIXME:ugly (do we need this? gotta test) */
697 gtk_text_buffer_set_modified(GTK_TEXT_BUFFER(mainview
->buffer
), FALSE
); /*we probably don't need this*/
699 callback_undotoggle((gpointer
)mainview
->buffer
, FALSE
, mainview
); /*we need these*/
700 callback_redotoggle((gpointer
)mainview
->buffer
, FALSE
, mainview
);
702 if (file_edited_backup
==FALSE
) mainview
->file_edited
=FALSE
; /*textview changed event toggles this?*/
705 else if (nd
->typ
== NODE_SKETCH
)
707 sketchwidget_wipe_undo(mainview
->sk
);
709 /* Disable squared and filled mode when opening a sketch */
710 hildon_check_button_set_active(HILDON_CHECK_BUTTON(mainview
->menu_button_square
), FALSE
);
711 hildon_check_button_set_active(HILDON_CHECK_BUTTON(mainview
->menu_button_filled
), FALSE
);
713 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview
->shapemenuitems
[1]), TRUE
);
714 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview
->shapemenuitems
[0]), TRUE
);
716 blobsize
= sqlite3_column_bytes(stmt
, 2);
717 blob
= (char *)sqlite3_column_blob(stmt
, 2);
718 gboolean clear
= TRUE
;
724 maepad_debug("blob size: %d", blobsize
);
725 GdkPixbufLoader
*pl
= gdk_pixbuf_loader_new_with_type("png", NULL
);
728 gdk_pixbuf_loader_write(pl
, (guchar
*) blob
, blobsize
, &err
);
731 maepad_warning("Error loading sketch: %s", err
->message
);
735 gdk_pixbuf_loader_close(pl
, NULL
);
736 GdkPixbuf
*pixbuf
= gdk_pixbuf_loader_get_pixbuf(pl
);
738 if (GDK_IS_PIXBUF(pixbuf
))
740 GtkWidget
*skdr
= sketchwidget_get_drawingarea(mainview
->sk
);
741 GtkPixmap
*skpix
= (GtkPixmap
*) sketchwidget_get_Pixmap(mainview
->sk
);
743 int w
=gdk_pixbuf_get_width(pixbuf
);
744 int h
=gdk_pixbuf_get_height(pixbuf
);
745 if (w
!=skdr
->allocation
.width
|| h
!=skdr
->allocation
.height
)
747 if (w
>skdr
->allocation
.width
) w
=skdr
->allocation
.width
;
748 if (h
>skdr
->allocation
.height
) h
=skdr
->allocation
.height
;
749 sketchwidget_clear_real(mainview
->sk
);
751 gdk_draw_pixbuf(GDK_DRAWABLE(skpix
), NULL
, pixbuf
, 0, 0, 0, 0, w
, h
, GDK_RGB_DITHER_NONE
, 0, 0);
756 if (skpix
&& G_IS_OBJECT(skpix
)) g_object_unref(skpix
);
760 maepad_warning("Error loading pixbuf");
766 maepad_message("Clearing sketch widget");
767 sketchwidget_clear_real(mainview
->sk
);
769 gtk_widget_queue_draw(sketchwidget_get_drawingarea(mainview
->sk
));
771 else if (nd
->typ
== NODE_CHECKLIST
)
773 mainview
->checklist_edited
= FALSE
;
774 GtkTreeModel
*model
=gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->listview
));
776 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview
->listview
), NULL
);
777 gtk_list_store_clear(GTK_LIST_STORE(model
));
779 g_snprintf(tq
, sizeof(tq
), "SELECT name, style, color FROM %s WHERE nodeid=%d ORDER BY ord, idx", checklisttable_tmpname
, nd
->sql3id
);
780 sqlite3_stmt
*stmt2
= NULL
;
782 int rc
= sqlite3_prepare(mainview
->db
, tq
, strlen(tq
), &stmt2
, &dum
);
785 maepad_warning("Error reading checklist (1) %s", sqlite3_errmsg(mainview
->db
));
791 while(rc
== SQLITE_BUSY
|| rc
== SQLITE_ROW
)
793 rc
= sqlite3_step(stmt2
);
794 if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
|| rc
== SQLITE_DONE
)
796 else if (rc
== SQLITE_ROW
)
798 char *textdata
= (char *)sqlite3_column_text(stmt2
, 0);
799 int style
= sqlite3_column_int(stmt2
, 1);
800 unsigned long col
= sqlite3_column_int(stmt2
, 2);
802 GtkTreeIter toplevel
;
803 gtk_list_store_append(GTK_LIST_STORE(model
), &toplevel
);
804 gtk_list_store_set(GTK_LIST_STORE(model
), &toplevel
, CHECKNODE_TEXT
, textdata
, CHECKNODE_CHECKED
, FALSE
, -1);
805 if ((style
& CHECKSTYLE_CHECKED
)>0) {
806 gtk_list_store_set(GTK_LIST_STORE(model
), &toplevel
, CHECKNODE_CHECKED
, TRUE
, -1);
807 gtk_list_store_set(GTK_LIST_STORE(model
), &toplevel
, CHECKNODE_ICON_NAME
, "widgets_tickmark_list", -1);
809 if ((style
& CHECKSTYLE_BOLD
)>0) gtk_list_store_set(GTK_LIST_STORE(model
), &toplevel
, CHECKNODE_BOLD
, PANGO_WEIGHT_BOLD
, -1);
810 if ((style
& CHECKSTYLE_STRIKE
)>0) gtk_list_store_set(GTK_LIST_STORE(model
), &toplevel
, CHECKNODE_STRIKE
, TRUE
, -1);
815 g_snprintf(tmp
, sizeof(tmp
), "#%02lx%02lx%02lx", ((col
& 0xFF0000) >> 16), ((col
& 0xFF00) >> 8), (col
& 0xFF));
816 gtk_list_store_set(GTK_LIST_STORE(model
), &toplevel
, CHECKNODE_COLOR
, tmp
, -1);
821 if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
)
823 maepad_warning("Error reading checklist (2): %s", sqlite3_errmsg(mainview
->db
));
827 sqlite3_finalize(stmt2
);
830 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview
->listview
), model
);
831 g_object_unref(model
);
834 if ((nd
->flags
& NODEFLAG_SKETCHLINES
) > 0)
835 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview
->sketchlinesmenuitems
[1]), TRUE
);
836 else if ((nd
->flags
& NODEFLAG_SKETCHGRAPH
) > 0)
837 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview
->sketchlinesmenuitems
[2]), TRUE
);
840 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview
->sketchlinesmenuitems
[0]), TRUE
);
841 callback_sketchlines(NULL
, mainview
->sketchlinesmenuitems
[0]); /*FIXME:ugly */
843 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mainview
->tools_pressure
), TRUE
);
848 if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
) {
849 maepad_warning("Error reading (2): %s", sqlite3_errmsg(mainview
->db
));
852 sqlite3_finalize(stmt
);
855 busy_leave(mainview
);
857 /* Show / hide the sketch-related menu widgets */
858 if (nd
->typ
== NODE_SKETCH
) {
859 gtk_widget_show(mainview
->menu_button_square
);
860 gtk_widget_show(mainview
->menu_button_filled
);
862 gtk_widget_hide(mainview
->menu_button_square
);
863 gtk_widget_hide(mainview
->menu_button_filled
);
868 show_banner(mainview
, _("Error loading memo"));
872 gboolean
treeview_canselect(GtkTreeSelection
* selection
, GtkTreeModel
* model
, GtkTreePath
* path
, gboolean path_currently_selected
, gpointer userdata
)
874 MainView
*mainview
= (MainView
*) userdata
;
875 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
877 if (mainview
->loading
==FALSE
)
879 #ifndef EXPANDING_ROWS
880 if (path_currently_selected
)
884 #ifndef NEW_SEL_LOGIC
885 saveCurrentData(mainview
);
887 if (path_currently_selected
)
890 gtk_tree_model_get_iter(model
, &iter
, path
);
892 gtk_tree_model_get(model
, &iter
, NODE_DATA
, &(mainview
->cansel_node
), -1);
893 mainview
->cansel_time
=time(NULL
);
900 gboolean
newnodedlg_key_press_cb(GtkWidget
* widget
, GdkEventKey
* event
, GtkWidget
* dlg
)
902 SketchWidget
*s
= gtk_object_get_data(GTK_OBJECT(dlg
), "sk");
904 switch (event
->keyval
)
907 sketchwidget_redo(s
);
910 sketchwidget_undo(s
);
917 /* This struct will hold all our toggle buttons, so we can
918 * only allow one to be active at a time (i.e. radio buttons) */
919 typedef struct _newNodeToggleButtons newNodeToggleButtons
;
920 struct _newNodeToggleButtons
922 GtkWidget
*rbt
; /* Text */
923 GtkWidget
*rbs
; /* Sketch */
924 GtkWidget
*rbc
; /* Checklist */
927 void show_sketch_widget(GtkWidget
*widget
, gpointer user_data
)
929 GtkWidget
*dialog
= (GtkWidget
*)user_data
;
931 /* Show the sketch widget and hide the entry + draw button */
932 gtk_widget_show(gtk_object_get_data(GTK_OBJECT(dialog
), "al"));
933 gtk_widget_hide(gtk_object_get_data(GTK_OBJECT(dialog
), "draw_button"));
934 gtk_widget_hide(gtk_object_get_user_data(GTK_OBJECT(dialog
)));
937 void new_node_dialog(nodeType typ
, MainView
* mainview
)
939 GtkWidget
*dialog
, *entry
, *but_ok
, *vbox
, *hbox
, *al
, *cb
;
940 GtkWidget
*rb1
, *rb2
, *rb3
;
942 gchar datetime_str
[200];
945 gboolean datetime_written
= FALSE
;
948 tm_now
= localtime(&t_now
);
950 if (tm_now
!= NULL
) {
951 if (strftime(datetime_str
, sizeof(datetime_str
), "%y-%m-%d %H:%M", tm_now
) != 0) {
952 datetime_written
= TRUE
;
956 if (datetime_written
== FALSE
) {
957 /* Was not able to determine a datetime string - use default */
958 maepad_warning("Cannot determine current time");
959 strncpy(datetime_str
, _("New memo"), sizeof(datetime_str
));
960 datetime_str
[sizeof(datetime_str
)-1] = '\0';
963 newNodeToggleButtons
*nntb
= g_malloc(sizeof(newNodeToggleButtons
));
965 dialog
= gtk_dialog_new();
966 gtk_window_set_title(GTK_WINDOW(dialog
), _("Create new memo"));
967 gtk_dialog_set_has_separator(GTK_DIALOG(dialog
), FALSE
);
969 g_signal_connect(G_OBJECT(dialog
), "key_press_event", G_CALLBACK(newnodedlg_key_press_cb
), dialog
);
971 vbox
= gtk_vbox_new(FALSE
, 0);
973 hbox
= gtk_hbox_new(TRUE
, 0);
975 /* Text note toggle button */
976 rb1
= hildon_gtk_radio_button_new(HILDON_SIZE_FINGER_HEIGHT
, NULL
);
977 gtk_button_set_label(GTK_BUTTON(rb1
), _("Rich text"));
978 gtk_button_set_image(GTK_BUTTON(rb1
), gtk_image_new_from_file(PIXMAPDIR
"/text.png"));
979 gtk_box_pack_start(GTK_BOX(hbox
), GTK_WIDGET(rb1
), TRUE
, TRUE
, 0);
982 /* Sketch toggle button */
983 rb2
= hildon_gtk_radio_button_new_from_widget(HILDON_SIZE_FINGER_HEIGHT
, GTK_RADIO_BUTTON(rb1
));
984 gtk_button_set_label(GTK_BUTTON(rb2
), _("Sketch"));
985 gtk_button_set_image(GTK_BUTTON(rb2
), gtk_image_new_from_file(PIXMAPDIR
"/sketch.png"));
986 gtk_box_pack_start(GTK_BOX(hbox
), GTK_WIDGET(rb2
), TRUE
, TRUE
, 0);
989 /* Checklist toggle button */
990 rb3
= hildon_gtk_radio_button_new_from_widget(HILDON_SIZE_FINGER_HEIGHT
, GTK_RADIO_BUTTON(rb1
));
991 gtk_button_set_label(GTK_BUTTON(rb3
), _("Checklist"));
992 gtk_button_set_image(GTK_BUTTON(rb3
), gtk_image_new_from_file(PIXMAPDIR
"/checklist.png"));
993 gtk_box_pack_start(GTK_BOX(hbox
), GTK_WIDGET(rb3
), TRUE
, TRUE
, 0);
996 /* Set mode to 0 to get correct styling */
997 gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(rb1
), FALSE
);
998 gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(rb2
), FALSE
);
999 gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(rb3
), FALSE
);
1001 /* Remember "new note toggle buttons" list */
1002 gtk_object_set_data(GTK_OBJECT(dialog
), "nntb", nntb
);
1004 if (typ
== NODE_TEXT
) {
1005 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rb1
), TRUE
);
1006 } else if (typ
== NODE_SKETCH
) {
1007 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rb2
), TRUE
);
1009 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rb3
), TRUE
);
1012 gtk_box_pack_start(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
1014 but_ok
= gtk_dialog_add_button(GTK_DIALOG(dialog
), _("Create"), GTK_RESPONSE_OK
);
1015 g_signal_connect(G_OBJECT(but_ok
), "clicked", G_CALLBACK(callback_new_node_real
), dialog
);
1017 gtk_object_set_data(GTK_OBJECT(dialog
), "m", mainview
);
1019 hb
= gtk_hbox_new(FALSE
, 10);
1020 gtk_box_pack_start(GTK_BOX(hb
), gtk_label_new(_("Name:")), FALSE
, FALSE
, 0);
1021 entry
= hildon_entry_new(HILDON_SIZE_AUTO
);
1022 gtk_object_set_user_data(GTK_OBJECT(dialog
), entry
);
1023 gtk_entry_set_text(GTK_ENTRY(entry
), datetime_str
);
1024 gtk_editable_select_region(GTK_EDITABLE(entry
), 0, -1);
1025 gtk_box_pack_start(GTK_BOX(hb
), entry
, TRUE
, TRUE
, 0);
1027 /* Sketch widget, hidden by default */
1028 al
= gtk_alignment_new(0.5, 0.5, 0, 0);
1029 SketchWidget
*s
= sketchwidget_new(SKETCHNODE_X
, SKETCHNODE_Y
, TRUE
);
1030 gtk_object_set_data(GTK_OBJECT(dialog
), "sk", s
);
1031 gtk_object_set_data(GTK_OBJECT(dialog
), "al", al
);
1032 sketchwidget_set_brushsize(s
, 2);
1033 sketchwidget_set_backstyle(s
, SKETCHBACK_GRAPH
);
1034 gtk_widget_set_size_request(sketchwidget_get_mainwidget(s
), SKETCHNODE_X
, SKETCHNODE_Y
);
1035 gtk_container_add(GTK_CONTAINER(al
), sketchwidget_get_mainwidget(s
));
1036 gtk_box_pack_start(GTK_BOX(hb
), al
, FALSE
, FALSE
, 0);
1038 /*but_sketch = hildon_button_new_with_text(
1039 HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH,
1040 HILDON_BUTTON_ARRANGEMENT_VERTICAL,
1041 _("Use sketch label"), NULL);
1043 gtk_object_set_data(GTK_OBJECT(dialog), "draw_button", but_sketch);
1044 gtk_signal_connect(GTK_OBJECT(but_sketch), "clicked", G_CALLBACK(show_sketch_widget), dialog);
1045 gtk_box_pack_start(GTK_BOX(hb), but_sketch, FALSE, TRUE, 0);*/
1046 gtk_box_pack_start(GTK_BOX(vbox
), hb
, TRUE
, FALSE
, 0);
1048 cb
= hildon_check_button_new(HILDON_SIZE_FINGER_HEIGHT
| HILDON_SIZE_AUTO_WIDTH
);
1049 gtk_button_set_label(GTK_BUTTON(cb
), _("Create as child of selected memo"));
1050 hildon_check_button_set_active(HILDON_CHECK_BUTTON(cb
), mainview
->newnodedialog_createchild
);
1051 gtk_box_pack_start(GTK_BOX(vbox
), cb
, FALSE
, FALSE
, 0);
1053 gtk_object_set_data(GTK_OBJECT(dialog
), "cb", cb
);
1055 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog
)->vbox
), vbox
);
1057 gtk_widget_grab_focus(entry
);
1059 gtk_widget_show_all(dialog
);
1061 /* Hide the sketch widget at first */
1062 gtk_widget_hide(al
);
1063 gtk_window_set_modal(GTK_WINDOW(dialog
), TRUE
);
1066 void add_new_node(nodeData
* node
, MainView
* mainview
, gboolean ischild
)
1068 GtkTreeIter parentiter
, newiter
;
1069 GtkTreeModel
*model
;
1072 GtkTreeSelection
*selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->treeview
));
1074 if (gtk_tree_selection_get_selected(selection
, &model
, &parentiter
))
1077 GtkTreePath
*path
= NULL
;
1079 unsigned int parentnodeid
= 0;
1083 path
= gtk_tree_model_get_path(model
, &parentiter
);
1085 if (ischild
== FALSE
)
1087 gtk_tree_path_up(path
);
1089 if (gtk_tree_path_get_depth(path
) == 0)
1091 /* Selected node is a root node */
1092 ptr
= NULL
; /* New node can not have a Parent node */
1093 gtk_tree_path_down(path
); /*restore path so expand() works */
1095 else if (gtk_tree_path_get_depth(path
) > 0)
1097 /* Selected node is a child node */
1098 if (gtk_tree_model_get_iter(model
, &parentiter
, path
))
1108 gtk_tree_model_get(model
, ptr
, NODE_DATA
, &nd
, -1);
1110 parentnodeid
= nd
->sql3id
;
1116 sqlite3_stmt
*stmt
= NULL
;
1123 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s (parent, bodytype, name, nameblob, ord) VALUES (%d, %d, ?, ?, 0);", datatable_tmpname
, parentnodeid
, node
->typ
);
1124 int rc
= sqlite3_prepare(mainview
->db
, tq
, strlen(tq
), &stmt
, &dum
);
1128 maepad_warning("Error inserting (1): %s", sqlite3_errmsg(mainview
->db
));
1131 if (node
->name
!= NULL
)
1132 sqlite3_bind_text(stmt
, 1, node
->name
, strlen(node
->name
), SQLITE_TRANSIENT
);
1134 sqlite3_bind_text(stmt
, 1, NULL
, 0, SQLITE_TRANSIENT
);
1136 if (node
->namepix
!= NULL
)
1138 gchar
*namepixdata
= NULL
;
1143 if (gdk_pixbuf_save_to_buffer(node
->namepix
, &namepixdata
, &datalen
, "png", &err
, NULL
) == FALSE
)
1147 maepad_warning("Error saving name: %s", err
->message
);
1150 sqlite3_bind_blob(stmt
, 2, namepixdata
, datalen
, SQLITE_TRANSIENT
);
1153 sqlite3_bind_blob(stmt
, 2, NULL
, 0, SQLITE_TRANSIENT
);
1156 while(rc
== SQLITE_BUSY
)
1158 rc
= sqlite3_step(stmt
);
1159 if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
|| rc
== SQLITE_DONE
)
1162 sqlite3_finalize(stmt
);
1163 if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
)
1165 maepad_warning("Error inserting (2): %s", sqlite3_errmsg(mainview
->db
));
1168 node
->sql3id
= sqlite3_last_insert_rowid(mainview
->db
);
1172 if (node
->sql3id
== 0)
1177 g_object_unref(node
->namepix
);
1180 gtk_tree_path_free(path
);
1181 show_banner(mainview
, _("Error creating node"));
1185 gtk_tree_store_append(GTK_TREE_STORE(model
), &newiter
, ptr
);
1187 gtk_tree_store_set(GTK_TREE_STORE(model
), &newiter
, NODE_NAME
, node
->name
, NODE_PIXBUF
, node
->namepix
, NODE_DATA
, node
, -1);
1191 mainview
->loading
=TRUE
; /*only when we have a valid parent*/
1192 gtk_tree_view_expand_row(GTK_TREE_VIEW(mainview
->treeview
), path
, FALSE
);
1193 gtk_tree_path_free(path
);
1196 gtk_tree_selection_select_iter(selection
, &newiter
);
1198 mainview
->loading
=FALSE
;
1201 void callback_new_node_real(GtkAction
* action
, gpointer data
)
1205 GtkWidget
*dialog
= data
;
1206 GtkWidget
*entry
= gtk_object_get_user_data(GTK_OBJECT(dialog
));
1208 mainview
= gtk_object_get_data(GTK_OBJECT(dialog
), "m");
1209 SketchWidget
*s
= gtk_object_get_data(GTK_OBJECT(dialog
), "sk");
1210 GtkWidget
*cb
= gtk_object_get_data(GTK_OBJECT(dialog
), "cb");
1211 newNodeToggleButtons
*nntb
= gtk_object_get_data(GTK_OBJECT(dialog
), "nntb");
1213 nodeType typ
= NODE_TEXT
;
1214 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(nntb
->rbs
))) {
1216 } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(nntb
->rbc
))) {
1217 typ
= NODE_CHECKLIST
;
1223 /*if (GTK_WIDGET_VISIBLE(entry))
1225 txt
= g_strdup(gtk_entry_get_text(GTK_ENTRY(entry
)));
1226 if (strcmp(txt
, "") == 0)
1234 GtkWidget *sdr = sketchwidget_get_drawingarea(s);
1236 GdkPixmap *spix = sketchwidget_get_Pixmap(s);
1238 pixbuf = gdk_pixbuf_get_from_drawable(NULL, GDK_DRAWABLE(spix), NULL, 0, 0, 0, 0, sdr->allocation.width, sdr->allocation.height);
1239 g_object_unref(spix);
1241 GdkPixbuf *pixbuf2 = sketchwidget_trim_image(pixbuf, SKETCHNODE_X, SKETCHNODE_Y, &w,
1243 if (pixbuf2==NULL) return;
1245 GdkPixbuf *pixbuf3 = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, SKETCHNODE_RX,
1248 gdk_pixbuf_fill(pixbuf3, 0xffffffff);
1250 if (w <= SKETCHNODE_RX && h <= SKETCHNODE_RY)
1252 gdk_pixbuf_copy_area(pixbuf2, 0, 0, w, h, pixbuf3, 0, (SKETCHNODE_RY - h) / 2);
1260 neww = SKETCHNODE_RX;
1261 newh = (h / w) * SKETCHNODE_RX;
1265 newh = SKETCHNODE_RY;
1266 neww = (w / h) * SKETCHNODE_RY;
1268 if (newh > SKETCHNODE_RY)
1269 newh = SKETCHNODE_RY;
1271 GdkPixbuf *tmpbuf = gdk_pixbuf_scale_simple(pixbuf2, neww, newh,
1272 GDK_INTERP_BILINEAR);
1274 gdk_pixbuf_copy_area(tmpbuf, 0, 0, neww, newh, pixbuf3, 0, (SKETCHNODE_RY - newh) / 2);
1276 gdk_pixbuf_unref(tmpbuf);
1280 gdk_pixbuf_unref(pixbuf2);
1285 node
= g_malloc(sizeof(nodeData
));
1288 node
->namepix
= NULL
;
1290 /*if (GTK_WIDGET_VISIBLE(entry))
1296 node->namepix = pixbuf;
1303 mainview
->newnodedialog_createchild
= hildon_check_button_get_active(HILDON_CHECK_BUTTON(cb
));
1304 add_new_node(node
, mainview
, mainview
->newnodedialog_createchild
);
1306 sketchwidget_destroy(s
);
1307 gtk_widget_destroy(dialog
);
1308 mainview
->file_edited
= TRUE
;
1314 void callback_file_delete_node(GtkAction
* action
, gpointer data
)
1316 MainView
*mainview
= (MainView
*) data
;
1317 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
1319 if (getSelectedNode(mainview
) == NULL
) {
1320 show_banner(mainview
, _("Select a node first"));
1324 if (show_confirmation(mainview
, _("Delete selected memo?"))) {
1325 callback_delete_node_real(mainview
);
1326 gtk_widget_hide(GTK_WIDGET(mainview
->data
->node_view
));
1331 * Callback for Rename Menuitem
1333 void callback_file_rename_node(GtkAction
* action
, gpointer data
)
1335 MainView
*mainview
= (MainView
*)data
;
1336 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
1338 /* Get the selected node */
1339 nodeData
*sel_node
= getSelectedNode(mainview
);
1340 if (sel_node
== NULL
) {
1341 /* Do nothing, if no node has been selected */
1342 show_banner(mainview
, _("Select a node first"));
1346 if (sel_node
->namepix
!= NULL
) {
1347 /* the memo has a graphical label, cannot edit! */
1348 show_banner(mainview
, _("Cannot rename memos with sketch name"));
1352 gchar
* new_name
= show_line_edit_dialog(mainview
, _("Rename memo"), _("New name:"), _("Rename"), sel_node
->name
);
1354 /* Only rename node when user accepted the new name */
1355 if (new_name
!= NULL
) {
1356 callback_rename_node_real(mainview
, new_name
);
1361 void callback_rename_node_real(MainView
* mainview
, gchar
* new_name
)
1364 GtkTreeModel
*model
;
1365 nodeData
*nd
= NULL
;
1367 /* Get the selected node */
1368 GtkTreeSelection
*selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->treeview
));
1370 if (!gtk_tree_selection_get_selected(selection
, &model
, &iter
)) {
1374 gtk_tree_model_get (model
, &iter
, NODE_DATA
, &nd
, -1);
1380 /* Update the database */
1381 sqlite3_stmt
*stmt
= NULL
;
1383 char* sql
= sqlite3_mprintf("UPDATE %s SET name='%q' WHERE nodeid=%d", datatable_tmpname
, new_name
, nd
->sql3id
);
1385 int rc
= sqlite3_prepare(mainview
->db
, sql
, strlen(sql
), &stmt
, NULL
);
1386 if (rc
== SQLITE_OK
) {
1388 while (rc
== SQLITE_BUSY
) {
1389 rc
= sqlite3_step(stmt
);
1390 if (rc
== SQLITE_DONE
) {
1391 /* Update in the database was successful - now update the rest */
1393 /* Update the noteData */
1395 nd
->name
= g_strdup(new_name
);
1397 /* Update the window title of node_view */
1398 gtk_window_set_title(GTK_WINDOW(mainview
->data
->node_view
), nd
->name
);
1400 /* Update the value in the tree store */
1401 gtk_tree_store_set (GTK_TREE_STORE(model
), &iter
, NODE_NAME
, new_name
, -1);
1404 } else if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
) {
1405 maepad_warning("Error updating node: %s", sqlite3_errmsg(mainview
->db
));
1409 sqlite3_finalize(stmt
);
1411 maepad_warning("Error preparing DB update query: %s", sqlite3_errmsg(mainview
->db
));
1416 mainview
->file_edited
= TRUE
;
1419 void callback_file_export_node(GtkAction
* action
, gpointer data
)
1421 MainView
*mainview
= (MainView
*) data
;
1422 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
1424 nodeData
*nd
=getSelectedNode(mainview
);
1427 show_banner(mainview
, _("Select a memo first"));
1431 gchar
*nodename
=nd
->name
;
1432 if (nodename
==NULL
) nodename
=_("saved memo");
1434 if (nd
->typ
== NODE_TEXT
)
1437 GtkTextIter begin, end;
1438 gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER(mainview->buffer), &begin, &end);
1439 gchar *text = gtk_text_buffer_get_slice(GTK_TEXT_BUFFER(mainview->buffer), &begin, &end, TRUE);
1441 GString
*gstr
=g_string_sized_new(4096);
1442 wp_text_buffer_save_document(mainview
->buffer
, (WPDocumentSaveCallback
)(wp_savecallback
), gstr
);
1443 gint textlen
=gstr
->len
;
1444 gchar
*text
=g_string_free(gstr
, FALSE
);
1446 if (text
==NULL
|| !strcmp(text
, ""))
1448 show_banner(mainview
, _("Memo is empty"));
1452 gchar
*fn
= interface_file_chooser(mainview
, GTK_FILE_CHOOSER_ACTION_SAVE
, nodename
, "html");
1455 GnomeVFSResult vfs_result
;
1456 GnomeVFSHandle
*handle
= NULL
;
1457 GnomeVFSFileSize out_bytes
;
1458 vfs_result
= gnome_vfs_create(&handle
, fn
, GNOME_VFS_OPEN_WRITE
, 0, 0600);
1459 if ( vfs_result
!= GNOME_VFS_OK
) {
1460 show_banner(mainview
, _("Export failed"));
1464 gnome_vfs_write(handle
, text
, textlen
, &out_bytes
);
1465 gnome_vfs_close(handle
);
1466 if (out_bytes
==strlen(text
)) show_banner(mainview
, _("Exported"));
1467 else show_banner(mainview
, _("Export incomplete"));
1474 else if (nd
->typ
== NODE_SKETCH
)
1476 GdkPixmap
*skpix
= sketchwidget_get_Pixmap(mainview
->sk
);
1477 GtkWidget
*skdr
= sketchwidget_get_drawingarea(mainview
->sk
);
1478 GdkPixbuf
*pixbuf
= gdk_pixbuf_get_from_drawable(NULL
, GDK_DRAWABLE(skpix
), NULL
, 0, 0, 0, 0, skdr
->allocation
.width
, skdr
->allocation
.height
);
1481 show_banner(mainview
, _("Memo is empty"));
1485 gchar
*fn
= interface_file_chooser(mainview
, GTK_FILE_CHOOSER_ACTION_SAVE
, nodename
, "png");
1488 if (gdk_pixbuf_save(pixbuf
, fn
, "png", NULL
, NULL
)==FALSE
)
1490 show_banner(mainview
, _("Export failed"));
1494 show_banner(mainview
, _("Exported"));
1499 g_object_unref(skpix
);
1501 else if (nd
->typ
== NODE_CHECKLIST
)
1503 show_banner(mainview
, _("Export of checklists not possible yet"));
1508 * callback from menu item
1509 * move selected node down (switch node with next sibling), don't change level of node
1511 void callback_move_down_node(GtkAction
* action
, gpointer data
)
1514 GtkTreeModel
*model
;
1516 MainView
*mainview
= (MainView
*) data
;
1517 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
1519 GtkTreeSelection
*selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->treeview
));
1520 gtk_tree_selection_get_selected(selection
, &model
, &iter
);
1522 GtkTreeIter old_iter
= iter
;/*save pointer to old iter, we will need it during swap nodes*/
1524 if (gtk_tree_model_iter_next(model
,&iter
)==FALSE
)/*get next node*/
1527 GtkTreeStore
*treeStore
= GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->treeview
)));
1528 gtk_tree_store_swap(treeStore
,&iter
,&old_iter
);
1530 mainview
->file_edited
= TRUE
;/*we have made changes , if required show "save changes?" dialog in future*/
1534 * callback from menu item
1535 * move selected node down (switch node with prev sibling), don't change level of node
1537 void callback_move_up_node(GtkAction
* action
, gpointer data
)
1540 GtkTreeModel
*model
;
1542 MainView
*mainview
= (MainView
*) data
;
1543 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
1545 GtkTreeSelection
*selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->treeview
));
1546 gtk_tree_selection_get_selected(selection
, &model
, &iter
);
1548 GtkTreeIter old_iter
=iter
;/*save pointer to old iter, we will need it during swap nodes*/
1550 if (tree_model_iter_prev(model
,&iter
)==FALSE
)/*get previous node*/
1553 GtkTreeStore
*treeStore
= GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->treeview
)));
1554 gtk_tree_store_swap(treeStore
,&old_iter
,&iter
);/*do move*/
1556 mainview
->file_edited
= TRUE
;/*we have made changes , if required show "save changes?" dialog in future*/
1560 * callback from menu item
1561 * we change level of actual node with direction to top
1563 void callback_move_to_top_level_node(GtkAction
* action
, gpointer data
)
1565 GtkTreeIter iter
,new_parent
;
1566 GtkTreeIter
*p_new_parent
;
1568 GtkTreeModel
*model
;
1570 MainView
*mainview
= (MainView
*) data
;
1571 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
1573 GtkTreeSelection
*selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->treeview
));
1574 gtk_tree_selection_get_selected(selection
, &model
, &iter
);
1576 /*at first we need actual parent of selected node*/
1577 if (gtk_tree_model_iter_parent(model
,&parent
,&iter
)==FALSE
)
1579 /*if parent of selected node is ROOT we can't go higher*/
1582 /*we need also new parent, it's parent of actual parent*/
1583 if (gtk_tree_model_iter_parent(model
,&new_parent
,&parent
)==FALSE
)
1585 /*if our new parent is ROOT we got filled new_parent with invalid value,
1586 so we need set NULL value to p_new_parent (root item)*/
1591 p_new_parent
=&new_parent
;/*we only redirect pointer to treeiter*/
1594 saveCurrentData(mainview
);/*we save changes in node befor move*/
1596 /*this move function provide move item with all his children, be careful iter value will change!*/
1597 if (move_node(mainview
,p_new_parent
,&iter
,&parent
)==TRUE
){
1599 gint id_parent
= get_node_id_on_tmp_db(model
,p_new_parent
);
1600 gint id_node
= get_node_id_on_tmp_db(model
,&iter
);
1601 /*we need also update parent id of moved item*/
1603 g_snprintf (tq
, sizeof(tq
), "UPDATE %s SET parent=%d WHERE nodeid=%d",datatable_tmpname
,id_parent
,id_node
);
1604 exec_command_on_db(mainview
,tq
);
1606 /*select new created iter*/
1607 gtk_tree_selection_select_iter(selection
,&iter
);
1609 mainview
->file_edited
= TRUE
;/*we have made changes , if required show "save changes?" dialog in future*/
1614 * callback from menu item
1615 * we change level of actual node with direction to bottom
1616 * previous node will be parent of our actual node
1618 void callback_move_to_bottom_level_node(GtkAction
* action
, gpointer data
)
1621 GtkTreeModel
*model
;
1623 MainView
*mainview
= (MainView
*) data
;
1624 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
1626 GtkTreeSelection
*selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->treeview
));
1627 gtk_tree_selection_get_selected(selection
, &model
, &iter
);
1629 GtkTreeIter move_iter
=iter
;/*save pointer to old iter*/
1631 /*we try to get previous node*/
1632 if (tree_model_iter_prev(model
,&iter
)==FALSE
)
1633 return;/*if previous node on the same level doesn't exist we will exit*/
1635 saveCurrentData(mainview
);/*we save changes in node befor move*/
1637 /*this move function provide move item with all his children, be careful move_iter value will change!*/
1638 if (move_node(mainview
,&iter
,&move_iter
,NULL
)==TRUE
)
1640 gint id_parent
= get_node_id_on_tmp_db(model
,&iter
);
1641 gint id_node
= get_node_id_on_tmp_db(model
,&move_iter
);
1643 /*we need also update parent id of moved item*/
1645 g_snprintf (tq
, sizeof(tq
), "UPDATE %s SET parent=%d WHERE nodeid=%d",datatable_tmpname
,id_parent
,id_node
);
1646 exec_command_on_db(mainview
,tq
);
1648 GtkTreePath
*path
= gtk_tree_model_get_path(model
, &iter
);
1649 gtk_tree_view_expand_row(GTK_TREE_VIEW(mainview
->treeview
), path
, FALSE
);/*expand parent node*/
1650 gtk_tree_path_free(path
);
1652 /*select new created iter*/
1653 gtk_tree_selection_select_iter(selection
,&move_iter
);
1655 mainview
->file_edited
= TRUE
;/*we have made changes , if required show "save changes?" dialog in future*/
1660 * move item_to_move to new_parent with his children, this function is designed for change level of node
1661 * we copy item_to_move with his children to new position (after item_befor if is not NULL) and then we
1662 * destroy old node with his children, so ! item_to_move is set with new iter, be careful on this!
1664 gboolean
move_node(MainView
*mainview
,GtkTreeIter
*new_parent
,GtkTreeIter
*item_to_move
,GtkTreeIter
*item_befor
)
1666 GtkTreeModel
*model
;
1668 model
=gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->treeview
));
1669 GtkTreeStore
*treeStore
= GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->treeview
)));
1672 gtk_tree_model_get(model
, item_to_move
, NODE_DATA
, &node
, -1);/*get data from actual iter*/
1675 GtkTreeIter new_iter
;/*create new iter*/
1676 gtk_tree_store_append(treeStore
,&new_iter
,new_parent
);/*append new iter to new parent*/
1678 if (item_befor
!=NULL
)
1679 gtk_tree_store_move_after(treeStore
,&new_iter
,item_befor
);/*sometimes we need set position*/
1681 gtk_tree_store_set(treeStore
, &new_iter
, NODE_NAME
, node
->name
,NODE_PIXBUF
, node
->namepix
, NODE_DATA
, node
, -1);/*set data from old iter*/
1684 while (gtk_tree_model_iter_children(model
, &child
, item_to_move
)==TRUE
)/*move all childrens while some exits*/
1686 if (move_node(mainview
,&new_iter
,&child
,NULL
)==FALSE
)/*use recursion on children*/
1690 gtk_tree_store_set(treeStore
, item_to_move
, NODE_DATA
, NULL
, -1);
1691 gtk_tree_store_remove(treeStore
, item_to_move
);/*remove node, data need't remove, they are stored in new node*/
1693 /*we need return new value of moved item, so we need assign new_iter to item_to_move*/
1694 /*this code is ugly : new_iter to path and back to item_to_move*/
1695 GtkTreePath
*path
=gtk_tree_model_get_path(model
,&new_iter
);
1696 gtk_tree_model_get_iter(model
,item_to_move
,path
);
1697 gtk_tree_path_free(path
);
1701 fprintf(stderr
,"Get data node failed!\n");
1709 * simple execute of sql command which is stored in sql_string[]
1711 gboolean
exec_command_on_db(MainView
*mainview
,char sql_string
[])
1713 sqlite3_stmt
*stmt
= NULL
;
1715 gboolean db_query_result
= FALSE
;
1717 int rc
= sqlite3_prepare (mainview
->db
, sql_string
, strlen(sql_string
), &stmt
, &dum
);
1720 maepad_warning("Error preparing DB update query: %s", sqlite3_errmsg(mainview
->db
));
1725 while (rc
== SQLITE_BUSY
) {
1726 rc
= sqlite3_step (stmt
);
1727 if (rc
== SQLITE_DONE
) {
1728 db_query_result
= TRUE
;
1731 else if(rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
) {
1732 maepad_warning("Error updating node: %s", sqlite3_errmsg(mainview
->db
));
1735 sqlite3_finalize(stmt
);
1741 * 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)
1743 gboolean
foreach_func_update_ord (GtkTreeModel
*model
,GtkTreePath
*path
,GtkTreeIter
*iter
, MainView
*mainview
)
1746 gtk_tree_model_get(model
, iter
, NODE_DATA
, &node
, -1);
1747 /*we need index of node on actual level*/
1748 gint index
=get_branch_node_index(path
);
1750 /*prepare to execute update command,and exec it*/
1751 char sql_command
[512];
1752 g_snprintf (sql_command
, sizeof(sql_command
), "UPDATE %s SET ord=\"%d\" WHERE nodeid=%d",datatable_tmpname
, index
, node
->sql3id
);
1753 exec_command_on_db(mainview
,sql_command
);
1755 /*we don't want break gtk_tree_model_foreach function,until we call this func on each node - so we return always FALSE*/
1760 * return id number of iter (id number which is used to identify in sql database of nodes)
1762 int get_node_id_on_tmp_db(GtkTreeModel
*model
,GtkTreeIter
*iter
)
1765 return 0;/*we got ROOT parent here*/
1768 gtk_tree_model_get(model
, iter
, NODE_DATA
, &node
, -1);
1769 return node
->sql3id
;
1773 * get index of node in current branch
1775 gint
get_branch_node_index(GtkTreePath
*path
)
1777 int depth
=gtk_tree_path_get_depth(path
);
1778 gint
*indicies
= gtk_tree_path_get_indices(path
);
1780 return indicies
[depth
-1];
1784 * similiar with gtk_tree_model_iter_next (), but opposite
1786 gboolean
tree_model_iter_prev(GtkTreeModel
*tree_model
,GtkTreeIter
*iter
)
1788 GtkTreePath
*path
= gtk_tree_model_get_path(tree_model
, iter
);
1791 fprintf(stderr
,"Error: path is null\n");
1795 if (gtk_tree_path_prev(path
)==FALSE
)
1798 gtk_tree_model_get_iter(tree_model
, iter
,path
);
1803 gboolean
ref2iter(GtkTreeModel
* model
, GtkTreeRowReference
* ref
, GtkTreeIter
* iter
)
1805 gboolean res
= FALSE
;
1806 GtkTreePath
*path
= gtk_tree_row_reference_get_path(ref
);
1808 if (gtk_tree_model_get_iter(model
, iter
, path
))
1812 gtk_tree_path_free(path
);
1816 GtkTreeRowReference
*iter2ref(GtkTreeModel
* model
, GtkTreeIter
* iter
)
1818 GtkTreeRowReference
*ref
;
1820 GtkTreePath
*path
= gtk_tree_model_get_path(model
, iter
);
1822 ref
= gtk_tree_row_reference_new(model
, path
);
1823 gtk_tree_path_free(path
);
1827 void move_nodes_up(GtkTreeModel
* model
, GtkTreeRowReference
* topnode
, GtkTreeRowReference
* newtop
)
1829 GtkTreeIter topiter
;
1831 if (ref2iter(model
, topnode
, &topiter
) == FALSE
)
1836 if (gtk_tree_model_iter_children(model
, &child
, &topiter
))
1838 GtkTreeRowReference
*ref
;
1839 GList
*rr_list
= NULL
, *node
;
1843 ref
= iter2ref(model
, &child
);
1844 rr_list
= g_list_append(rr_list
, ref
);
1846 while(gtk_tree_model_iter_next(model
, &child
));
1849 * got a reflist for all children
1852 for(node
= rr_list
; node
; node
= node
->next
)
1854 ref
= (GtkTreeRowReference
*) (node
->data
);
1855 if (ref2iter(model
, ref
, &child
))
1857 GtkTreeIter newtopiter
, newiter
;
1858 GtkTreeIter
*newtopiterptr
;
1860 if (ref2iter(model
, newtop
, &newtopiter
))
1861 newtopiterptr
= &newtopiter
;
1863 newtopiterptr
= NULL
;
1867 gtk_tree_model_get(model
, &child
, NODE_DATA
, &node
, -1);
1869 gtk_tree_store_append(GTK_TREE_STORE(model
), &newiter
, newtopiterptr
);
1870 gtk_tree_store_set(GTK_TREE_STORE(model
), &newiter
, NODE_NAME
, node
->name
, NODE_PIXBUF
, node
->namepix
, NODE_DATA
, node
, -1);
1872 GtkTreeRowReference
*newref
= iter2ref(model
, &newiter
);
1874 move_nodes_up(model
, ref
, newref
);
1875 gtk_tree_row_reference_free(newref
);
1877 gtk_tree_store_remove(GTK_TREE_STORE(model
), &child
);
1879 gtk_tree_row_reference_free(ref
);
1882 g_list_free(rr_list
);
1887 void callback_delete_node_real(MainView
* mainview
)
1890 GtkTreeModel
*model
;
1892 GtkTreeSelection
*selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->treeview
));
1894 if (!gtk_tree_selection_get_selected(selection
, &model
, &iter
))
1899 gtk_tree_model_get(model
, &iter
, NODE_DATA
, &nd
, -1);
1903 mainview
->file_edited
= TRUE
;
1905 unsigned int sql3id
= nd
->sql3id
;
1912 * if (nd->pix) g_object_unref(nd->pix);
1916 GtkTreeRowReference
*upref
= NULL
, *ref
= NULL
;
1918 GtkTreePath
*path
= gtk_tree_model_get_path(model
, &iter
);
1920 ref
= gtk_tree_row_reference_new(model
, path
);
1921 if (gtk_tree_path_up(path
))
1922 upref
= gtk_tree_row_reference_new(model
, path
);
1923 gtk_tree_path_free(path
);
1925 g_object_ref(model
);
1926 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview
->treeview
), NULL
);
1928 move_nodes_up(model
, ref
, upref
);
1930 if (ref2iter(model
, ref
, &iter
))
1934 g_snprintf(tq
, sizeof(tq
), "SELECT parent FROM %s WHERE nodeid=%d", datatable_tmpname
, sql3id
);
1935 sqlite3_stmt
*stmt
= NULL
;
1937 int rc
= sqlite3_prepare(mainview
->db
, tq
, strlen(tq
), &stmt
, &dum
);
1938 unsigned int sql3parentid
= 0;
1942 maepad_warning("Error finding children for delete: %s", sqlite3_errmsg(mainview
->db
));
1947 while(rc
== SQLITE_BUSY
|| rc
== SQLITE_ROW
)
1949 rc
= sqlite3_step(stmt
);
1950 if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
|| rc
== SQLITE_DONE
)
1952 else if (rc
== SQLITE_ROW
)
1954 sql3parentid
= sqlite3_column_int(stmt
, 0);
1958 sqlite3_finalize(stmt
);
1960 g_snprintf(tq
, sizeof(tq
), "UPDATE %s SET parent=%d WHERE parent=%d;", datatable_tmpname
, sql3parentid
, sql3id
);
1961 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
1962 maepad_warning("Error moving nodes up one level");
1965 g_snprintf(tq
, sizeof(tq
), "DELETE FROM %s WHERE nodeid=%d;", datatable_tmpname
, sql3id
);
1966 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
1967 maepad_warning("Error deleting node");
1970 /* Delete all checklist items that do not have
1971 * a node anymore (= orphaned checklist items) */
1972 g_snprintf(tq
, sizeof(tq
), "DELETE FROM %s WHERE nodeid NOT IN (SELECT nodeid FROM %s);", checklisttable_tmpname
, datatable_tmpname
);
1973 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
1974 maepad_warning("Error deleting orphaned checklist items");
1978 gtk_tree_store_remove(GTK_TREE_STORE(model
), &iter
);
1981 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview
->treeview
), model
);
1982 g_object_unref(model
);
1984 gtk_tree_row_reference_free(ref
);
1985 gtk_tree_row_reference_free(upref
);
1987 gtk_tree_view_expand_all(GTK_TREE_VIEW(mainview
->treeview
));
1991 void callback_edit_clear(GtkAction
* action
, gpointer data
)
1993 MainView
*mainview
= (MainView
*) data
;
1994 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
1995 nodeData
*nd
= getSelectedNode(mainview
);
1997 if (show_confirmation(mainview
, _("Remove all contents of this memo?"))) {
2000 gtk_text_buffer_set_text(GTK_TEXT_BUFFER(mainview
->buffer
), "", 0);
2003 sketchwidget_clear(mainview
->sk
);
2005 case NODE_CHECKLIST
:
2006 gtk_list_store_clear(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->listview
))));
2009 g_assert_not_reached();
2017 void callback_edit_cut(GtkAction
* action
, gpointer data
)
2019 MainView
*mainview
= (MainView
*) data
;
2020 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2022 nodeData
*nd
= getSelectedNode(mainview
);
2024 if (nd
->typ
== NODE_TEXT
)
2025 gtk_text_buffer_cut_clipboard(GTK_TEXT_BUFFER(mainview
->buffer
), mainview
->clipboard
, TRUE
);
2026 else if (nd
->typ
== NODE_SKETCH
)
2028 if (sketchwidget_cut(mainview
->sk
, mainview
->clipboard
)==FALSE
)
2029 show_banner(mainview
, _("Error cutting"));
2031 else if (nd
->typ
== NODE_CHECKLIST
)
2032 show_banner(mainview
, _("Unimplemented"));
2039 void callback_edit_copy(GtkAction
* action
, gpointer data
)
2041 MainView
*mainview
= (MainView
*) data
;
2042 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2044 nodeData
*nd
= getSelectedNode(mainview
);
2046 if (nd
->typ
== NODE_TEXT
)
2047 gtk_text_buffer_copy_clipboard(GTK_TEXT_BUFFER(mainview
->buffer
), mainview
->clipboard
);
2048 else if (nd
->typ
== NODE_SKETCH
)
2050 if (sketchwidget_copy(mainview
->sk
, mainview
->clipboard
)==FALSE
)
2051 show_banner(mainview
, _("Error copying"));
2053 else if (nd
->typ
== NODE_CHECKLIST
)
2055 /* Copy all selected entries as multiline text (1 line per entry) */
2056 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->listview
));
2057 GtkTreeSelection
*selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->listview
));
2059 gint selected_rows
= gtk_tree_selection_count_selected_rows(selection
);
2060 GList
* l
= gtk_tree_selection_get_selected_rows(selection
, NULL
);
2065 gchar
**entries
= g_malloc0(sizeof(gchar
*)*selected_rows
+1);
2066 gint entries_idx
= 0;
2070 GtkTreePath
*path
= cur
->data
;
2072 if (gtk_tree_model_get_iter(model
, &iter
, path
)) {
2073 gtk_tree_model_get(GTK_TREE_MODEL(model
), &iter
, CHECKNODE_TEXT
, &(entries
[entries_idx
++]), -1);
2075 gtk_tree_path_free(path
);
2081 str_data
= g_strjoinv("\n", entries
);
2082 g_strfreev(entries
);
2083 gtk_clipboard_set_text(mainview
->clipboard
, str_data
, -1);
2086 str_data
= g_strdup_printf(_("Copied %d entries"), selected_rows
);
2087 show_banner(mainview
, str_data
);
2096 void callback_edit_paste(GtkAction
* action
, gpointer data
)
2098 MainView
*mainview
= (MainView
*) data
;
2099 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2101 nodeData
*nd
= getSelectedNode(mainview
);
2103 if (nd
->typ
== NODE_TEXT
)
2104 gtk_text_buffer_paste_clipboard(GTK_TEXT_BUFFER(mainview
->buffer
), mainview
->clipboard
, NULL
, TRUE
);
2105 else if (nd
->typ
== NODE_SKETCH
)
2107 if (sketchwidget_paste(mainview
->sk
, mainview
->clipboard
)==FALSE
)
2108 show_banner(mainview
, _("Error pasting"));
2110 else if (nd
->typ
== NODE_CHECKLIST
) {
2111 /* Paste string from clipboard as new item */
2112 callback_checklist_paste(mainview
);
2115 mainview
->file_edited
= TRUE
;
2118 gint
cb_popup(GtkWidget
* widget
, GdkEvent
* event
)
2121 GdkEventButton
*event_button
;
2124 * The "widget" is the menu that was supplied when
2125 * * g_signal_connect_swapped() was called.
2127 menu
= GTK_MENU(widget
);
2128 event_button
= (GdkEventButton
*) event
;
2129 if (event
->type
== GDK_BUTTON_PRESS
&& event_button
->button
== 3)
2131 gtk_menu_popup(menu
, NULL
, NULL
, NULL
, NULL
, event_button
->button
, event_button
->time
);
2139 * on_node_menu_show(GtkWidget*, gpointer)
2141 * This is called when the longpress menu is shown in the main
2142 * window. In the Hildon UI mode that we are using, this does
2143 * not automatically select the touched node, so we need to set
2144 * the cursor here so that the functions in the menu operate on
2145 * the node that the user touched (i.e. the expected one).
2147 * The value of mainview->node_list_longpress_path has been set
2148 * by callback_treeview_button_press on the buttn press event.
2151 on_node_menu_show(GtkWidget
* nodemenu
, gpointer user_data
)
2153 MainView
* mainview
= (MainView
*)user_data
;
2155 if (mainview
->node_list_longpress_path
!= NULL
) {
2156 /* Set the cursor, but don't open the node view */
2157 mainview
->can_show_node_view
= FALSE
;
2158 gtk_tree_view_set_cursor(GTK_TREE_VIEW(mainview
->treeview
),
2159 mainview
->node_list_longpress_path
, NULL
, FALSE
);
2161 /* Dispose the path (we don't need it anymore) */
2162 gtk_tree_path_free(mainview
->node_list_longpress_path
);
2163 mainview
->node_list_longpress_path
= NULL
;
2170 gboolean
closefile(MainView
* mainview
)
2172 saveCurrentData(mainview
);
2174 if (mainview
->file_edited
)
2176 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
));
2177 gint answer
= gtk_dialog_run(GTK_DIALOG(hn
));
2178 gtk_widget_destroy(GTK_WIDGET(hn
));
2180 if (answer
== CONFRESP_CANCEL
)
2182 else if (answer
== CONFRESP_YES
)
2184 if (mainview
->file_name
== NULL
)
2186 mainview
->file_name
= interface_file_chooser(mainview
, GTK_FILE_CHOOSER_ACTION_SAVE
, "maemopaddata", "db");
2188 write_buffer_to_file(mainview
);
2193 sqlite3_close(mainview
->db
);
2194 mainview
->db
= NULL
;
2198 gboolean
callback_file_close(GtkAction
* action
, gpointer data
)
2201 MainView
*mainview
= (MainView
*) data
;
2202 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2203 if (closefile(mainview
) == FALSE
)
2210 void callback_file_new_node(GtkAction
* action
, gpointer data
)
2212 MainView
*mainview
= (MainView
*) data
;
2213 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2215 nodeType typ
= NODE_SKETCH
;
2217 nodeData
*nd
= getSelectedNode(mainview
);
2222 new_node_dialog(typ
, mainview
);
2228 void callback_file_new(GtkAction
* action
, gpointer data
)
2230 MainView
*mainview
= (MainView
*) data
;
2231 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2233 gchar
*filename
= NULL
;
2235 if (closefile(mainview
) == FALSE
)
2238 filename
= interface_file_chooser(mainview
, GTK_FILE_CHOOSER_ACTION_SAVE
, "memos", "db");
2239 if (filename
== NULL
)
2246 busy_enter(mainview
);
2250 rc
= sqlite3_open(filename
, &mainview
->db
);
2253 show_banner(mainview
, _("Cannot create database"));
2254 maepad_warning("Can't create database %s: %s", filename
, sqlite3_errmsg(mainview
->db
));
2258 sqlite3_exec(mainview
->db
, "PRAGMA synchronous = OFF;", NULL
, NULL
, NULL
);
2262 g_snprintf(tq
, sizeof(tq
), "CREATE TABLE %s%s", misctable_name
, misctable
);
2263 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
2265 g_snprintf(tq
, sizeof(tq
), "CREATE TABLE %s%s", datatable_name
, datatable
);
2266 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0)
2268 maepad_warning("Cannot create data table");
2269 show_banner(mainview
, _("Error creating data table"));
2273 g_snprintf(tq
, sizeof(tq
), "CREATE TABLE %s%s", checklisttable_name
, checklisttable
);
2274 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0)
2276 maepad_warning("Cannot create checklist table");
2277 show_banner(mainview
, _("Error creating checklist table"));
2282 sqlite3_close(mainview
->db
);
2283 mainview
->db
= NULL
;
2285 mainview
->file_name
= filename
;
2286 mainview
->file_edited
= FALSE
;
2287 read_file_to_buffer(mainview
);
2289 /*add a starter memo*/
2291 node
= g_malloc(sizeof(nodeData
));
2292 node
->typ
= NODE_SKETCH
;
2293 node
->name
= _("My first memo");
2294 node
->namepix
= NULL
;
2298 add_new_node(node
, mainview
, TRUE
);
2299 /*gtk_paned_set_position(GTK_PANED(mainview->hpaned), 180);*/
2300 write_buffer_to_file(mainview
);
2303 busy_reset(mainview
);
2306 gboolean
reset_ctree(GtkTreeModel
* model
, GtkTreePath
* path
, GtkTreeIter
* iter
, gpointer data
)
2310 gtk_tree_model_get(model
, iter
, NODE_DATA
, &node
, -1);
2316 g_object_unref(node
->namepix
);
2319 gtk_tree_store_set(GTK_TREE_STORE(model
), iter
, NODE_DATA
, NULL
, -1);
2324 void new_file(MainView
* mainview
)
2326 busy_enter(mainview
);
2328 * clear buffer, filename and free buffer text
2330 gtk_text_buffer_set_text(GTK_TEXT_BUFFER(mainview
->buffer
), "", -1);
2331 mainview
->file_name
= NULL
;
2332 mainview
->file_edited
= FALSE
;
2333 mainview
->newnodedialog_createchild
= TRUE
;
2335 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->treeview
));
2337 g_object_ref(model
);
2338 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview
->treeview
), NULL
);
2340 gtk_tree_model_foreach(model
, (GtkTreeModelForeachFunc
) reset_ctree
, (gpointer
) mainview
);
2344 * gtk_tree_store_clear(GTK_TREE_STORE(model));
2346 GtkTreePath
*path
= gtk_tree_path_new_from_indices(0, -1);
2349 if (gtk_tree_model_get_iter(model
, &iter
, path
))
2353 gtk_tree_store_remove(GTK_TREE_STORE(model
), &iter
);
2355 while(gtk_tree_store_iter_is_valid(GTK_TREE_STORE(model
), &iter
));
2357 gtk_tree_path_free(path
);
2359 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview
->treeview
), model
);
2360 g_object_unref(model
);
2362 busy_leave(mainview
);
2368 void callback_file_open(GtkAction
* action
, gpointer data
)
2370 gchar
*filename
= NULL
;
2371 MainView
*mainview
= (MainView
*) data
;
2372 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2374 if (closefile(mainview
) == FALSE
)
2380 filename
= interface_file_chooser(mainview
, GTK_FILE_CHOOSER_ACTION_OPEN
, NULL
, NULL
);
2383 * if we got a file name from chooser -> open file
2385 open_file(filename
, mainview
);
2389 gboolean
open_file(gchar
* filename
, MainView
* mainview
)
2393 /* Don't open nodes when opening a file */
2394 mainview
->can_show_node_view
= FALSE
;
2396 busy_enter(mainview
);
2398 while(filename
!= NULL
)
2402 if (stat(filename
, &s
) == -1) break;
2404 mainview
->file_name
= g_strdup(filename
);
2405 gboolean res
= read_file_to_buffer(mainview
);
2409 g_free(mainview
->file_name
);
2410 mainview
->file_name
= NULL
;
2413 mainview
->file_edited
= FALSE
;
2418 busy_leave(mainview
);
2422 void callback_about_link(GtkAboutDialog
*about
, const gchar
*link
, gpointer data
)
2424 MainView
*mainview
= (MainView
*) data
;
2425 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2426 osso_rpc_run_with_defaults(mainview
->data
->osso
, "osso_browser", OSSO_BROWSER_OPEN_NEW_WINDOW_REQ
, NULL
,
2427 DBUS_TYPE_STRING
, link
, DBUS_TYPE_INVALID
);
2430 void callback_about(GtkAction
* action
, gpointer data
)
2432 MainView
* mainview
= (MainView
*)data
;
2433 he_about_dialog_present(mainview_get_dialog_parent(mainview
),
2434 NULL
/* auto-detect app name */,
2437 _("A node-based memory pad for Maemo"),
2438 _("(c) 2010 Thomas Perl"),
2439 "http://thpinfo.com/2010/maepad/",
2440 "https://garage.maemo.org/tracker/?group_id=1291",
2441 "http://thpinfo.com/2010/maepad/donate");
2447 void callback_file_save(GtkAction
* action
, gpointer data
)
2449 gchar
*filename
= NULL
;
2450 MainView
*mainview
= (MainView
*) data
;
2451 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2454 * check is we had a new file
2456 if (mainview
->file_name
!= NULL
)
2458 write_buffer_to_file(mainview
);
2462 filename
= interface_file_chooser(mainview
, GTK_FILE_CHOOSER_ACTION_SAVE
, "maemopaddata", "db");
2464 * if we got a file name from chooser -> save file
2466 if (filename
!= NULL
)
2468 mainview
->file_name
= filename
;
2469 write_buffer_to_file(mainview
);
2470 mainview
->file_edited
= FALSE
;
2475 void callback_shapemenu(GtkAction
* action
, GtkWidget
* wid
)
2477 gint style
= GPOINTER_TO_INT(gtk_object_get_user_data(GTK_OBJECT(wid
)));
2478 MainView
* mainview
= gtk_object_get_data(GTK_OBJECT(wid
), "m");
2479 g_assert(mainview
!= NULL
);
2481 if (style
>= 0 && style
< SKETCHSHAPE_COUNT
) {
2482 /* We use the sketch widget's enum for available styles */
2483 sketchwidget_set_shape(mainview
->sk
, style
);
2485 /* Draw the correct indicator for the current shape */
2486 GtkWidget
* pix
= GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(wid
), "i"));
2487 g_assert(pix
!= NULL
);
2488 gtk_widget_show(pix
);
2489 gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(mainview
->shape_tb
), pix
);
2491 /* Fail. We shouldn't get here at all! */
2492 g_error("Invalid style ID from shape menu: %d", style
);
2498 void callback_eraser(GtkAction
* action
, MainView
* mainview
)
2500 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2502 if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(mainview
->eraser_tb
))) {
2503 /* Eraser on: Set pen color to white */
2504 GdkColor white
= { 0, 0xFFFF, 0xFFFF, 0xFFFF };
2505 sketchwidget_set_brushcolor(mainview
->sk
, white
);
2507 /* Eraser off: Set default color again (or black) */
2508 GdkColor black
= {0, 0, 0, 0};
2509 if (mainview
->current_color
== NULL
) {
2510 mainview
->current_color
= gdk_color_copy(&black
);
2512 sketchwidget_set_brushcolor(mainview
->sk
, *(mainview
->current_color
));
2516 void callback_menu(GtkAction
* action
, GtkWidget
* menu
)
2518 gtk_menu_popup(GTK_MENU(menu
), NULL
, NULL
, NULL
, NULL
, 0, GDK_CURRENT_TIME
);
2521 void callback_brushsizetb(GtkAction
* action
, MainView
*mainview
)
2523 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2524 callback_menu(NULL
, mainview
->brushsizemenu
);
2527 void callback_brushsize(GtkAction
* action
, GtkWidget
* wid
)
2529 int bsize
= (int)gtk_object_get_user_data(GTK_OBJECT(wid
));
2530 MainView
*mainview
= gtk_object_get_data(GTK_OBJECT(wid
), "m");
2532 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2534 sketchwidget_set_brushsize(mainview
->sk
, bsize
);
2536 GtkWidget
*pix
= gtk_object_get_data(GTK_OBJECT(wid
), "i");
2538 gtk_widget_show(pix
);
2539 gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(mainview
->brushsize_tb
), pix
);
2542 void callback_sketchlines(GtkAction
* action
, GtkWidget
* wid
)
2544 int style
= (int)gtk_object_get_user_data(GTK_OBJECT(wid
));
2545 MainView
*mainview
= gtk_object_get_data(GTK_OBJECT(wid
), "m");
2547 g_assert(mainview
!= NULL
);
2549 nodeData
*nd
= getSelectedNode(mainview
);
2550 gboolean doit
= FALSE
;
2552 if (nd
!= NULL
&& nd
->typ
== NODE_SKETCH
)
2554 nd
->flags
&= ~NODEFLAG_SKETCHLINES
;
2555 nd
->flags
&= ~NODEFLAG_SKETCHGRAPH
;
2556 /* sketchwidget_set_edited(mainview->sk, TRUE);*/ /*we call this on openfile, so this messes things up*/
2562 sketchwidget_set_backstyle(mainview
->sk
, SKETCHBACK_NONE
);
2564 else if (style
== 1)
2566 sketchwidget_set_backstyle(mainview
->sk
, SKETCHBACK_LINES
);
2568 nd
->flags
|= NODEFLAG_SKETCHLINES
;
2570 else if (style
== 2)
2572 sketchwidget_set_backstyle(mainview
->sk
, SKETCHBACK_GRAPH
);
2574 nd
->flags
|= NODEFLAG_SKETCHGRAPH
;
2577 GtkWidget
*pix
= gtk_object_get_data(GTK_OBJECT(wid
), "i");
2579 gtk_widget_show(pix
);
2580 gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(mainview
->sketchlines_tb
), pix
);
2583 void callback_color(GtkAction
* action
, MainView
* mainview
)
2585 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2587 nodeData
*nd
= getSelectedNode(mainview
);
2588 if (nd
== NULL
) return;
2590 HeSimpleColorDialog
* dialog
= HE_SIMPLE_COLOR_DIALOG(he_simple_color_dialog_new());
2591 gtk_window_set_transient_for(GTK_WINDOW(dialog
), mainview_get_dialog_parent(mainview
));
2593 if (mainview
->current_color
) {
2594 he_simple_color_dialog_set_color(dialog
, mainview
->current_color
);
2597 if (gtk_dialog_run(GTK_DIALOG(dialog
)) != GTK_RESPONSE_OK
) {
2598 gtk_widget_destroy(GTK_WIDGET(dialog
));
2602 gdk_color_free(mainview
->current_color
);
2603 mainview
->current_color
= he_simple_color_dialog_get_color(dialog
);
2605 gtk_widget_destroy(GTK_WIDGET(dialog
));
2609 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview
->eraser_tb
), FALSE
);
2610 sketchwidget_set_brushcolor(mainview
->sk
, *(mainview
->current_color
));
2612 case NODE_CHECKLIST
:
2613 { /* Put in a separate block to allow new local variables */
2614 GtkTreeModel
* model
= gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->listview
));
2615 GtkTreeSelection
* selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->listview
));
2616 GList
* selected
= gtk_tree_selection_get_selected_rows(selection
, NULL
);
2618 gchar
* color_string
= g_strdup_printf("#%02x%02x%02x",
2619 mainview
->current_color
->red
>> 8,
2620 mainview
->current_color
->green
>> 8,
2621 mainview
->current_color
->blue
>> 8);
2623 GList
* cur
= selected
;
2624 while (cur
!= NULL
) {
2625 GtkTreePath
* path
= cur
->data
;
2627 if (gtk_tree_model_get_iter(model
, &iter
, path
)) {
2628 gtk_list_store_set(GTK_LIST_STORE(model
), &iter
, CHECKNODE_COLOR
, color_string
, -1);
2630 gtk_tree_path_free(path
);
2634 g_list_free(selected
);
2635 g_free(color_string
);
2639 g_assert_not_reached();
2643 void callback_color_invoke(GtkAction
* action
, gpointer data
)
2645 MainView
*mainview
= (MainView
*) data
;
2646 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2647 gtk_button_clicked(GTK_BUTTON(mainview
->colorbutton_tb
));
2652 void callback_pressure(GtkAction
* action
, MainView
*mainview
)
2654 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2656 nodeData
*nd
= getSelectedNode(mainview
);
2660 if (nd
->typ
!= NODE_SKETCH
)
2663 /* pressure sensitivity disabled for now...
2664 mainview->sk->pressuresensitivity=gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(mainview->tools_pressure));*/
2668 void callback_wordwrap(GtkAction
* action
, MainView
*mainview
)
2670 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2672 nodeData
*nd
= getSelectedNode(mainview
);
2676 if (nd
->typ
!= NODE_TEXT
)
2679 gboolean act
=gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(mainview
->tools_wordwrap
));
2680 if (act
==TRUE
) nd
->flags
|= NODEFLAG_WORDWRAP
;
2681 else nd
->flags
&= ~NODEFLAG_WORDWRAP
;
2683 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(mainview
->textview
), (act
==TRUE
)?GTK_WRAP_WORD
:GTK_WRAP_NONE
);
2687 void callback_font(GtkAction
* action
, gpointer data
)
2689 MainView
*mainview
= (MainView
*) data
;
2690 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2692 nodeData
*nd
= getSelectedNode(mainview
);
2696 if (nd
->typ
!= NODE_TEXT
)
2699 HildonFontSelectionDialog
*dialog
= HILDON_FONT_SELECTION_DIALOG(hildon_font_selection_dialog_new(NULL
, NULL
));
2701 gboolean gotsel
=wp_text_buffer_has_selection(mainview
->buffer
);
2704 WPTextBufferFormat fmt
;
2705 wp_text_buffer_get_attributes(mainview
->buffer
, &fmt
, gotsel
);
2708 if (fmt
.text_position
==TEXT_POSITION_SUPERSCRIPT
) ri
=1;
2709 else if (fmt
.text_position
==TEXT_POSITION_SUBSCRIPT
) ri
=-1;
2711 g_object_set(G_OBJECT(dialog
),
2712 "family-set", fmt
.cs
.font
,
2713 "family", wp_get_font_name(fmt
.font
),
2714 "size-set", fmt
.cs
.font_size
,
2715 "size", wp_font_size
[fmt
.font_size
],
2716 "color-set", fmt
.cs
.color
,
2717 "color", &fmt
.color
,
2718 "bold-set", fmt
.cs
.bold
,
2720 "italic-set", fmt
.cs
.italic
,
2721 "italic", fmt
.italic
,
2722 "underline-set", fmt
.cs
.underline
,
2723 "underline", fmt
.underline
,
2724 "strikethrough-set", fmt
.cs
.strikethrough
,
2725 "strikethrough", fmt
.strikethrough
,
2726 "position-set", fmt
.cs
.text_position
,
2730 gtk_widget_show_all(GTK_WIDGET(dialog
));
2731 if (gtk_dialog_run(GTK_DIALOG(dialog
)) == GTK_RESPONSE_OK
)
2733 gboolean bold
, italic
, underline
, strikethrough
;
2734 gchar
*family
= NULL
;
2735 gint size
, position
;
2736 GdkColor
*color
=NULL
;
2737 gboolean set_family
, set_size
, set_bold
, set_italic
, set_underline
, set_strikethrough
, set_color
, set_position
;
2739 g_object_get(G_OBJECT(dialog
), "family", &family
, "size", &size
, "bold", &bold
, "italic", &italic
,
2740 "underline", &underline
, "strikethrough", &strikethrough
,
2741 "family-set", &set_family
, "size-set", &set_size
, "bold-set", &set_bold
, "italic-set", &set_italic
,
2742 "underline-set", &set_underline
, "strikethrough-set", &set_strikethrough
,
2743 "color", &color
, "color-set", &set_color
, "position", &position
, "position-set", &set_position
,
2746 wp_text_buffer_get_attributes(mainview
->buffer
, &fmt
, FALSE
);
2747 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;
2749 if (set_family
) { fmt
.font
=wp_get_font_index(family
, 1); fmt
.cs
.font
=1; }
2750 if (set_size
) { fmt
.font_size
=wp_get_font_size_index(size
, 16); fmt
.cs
.font_size
=1; }
2752 if (set_strikethrough
)
2754 fmt
.cs
.strikethrough
=1;
2755 fmt
.strikethrough
=strikethrough
;
2761 GLIB WARNING ** GLib-GObject - IA__g_object_set_valist: object class `GtkTextTag' has no property named `'
2764 fmt
.color
.pixel
=color
->pixel
;
2765 fmt
.color
.red
=color
->red
;
2766 fmt
.color
.green
=color
->green
;
2767 fmt
.color
.blue
=color
->blue
;
2772 if (position
==1) ri
=TEXT_POSITION_SUPERSCRIPT
;
2773 else if (position
==-1) ri
=TEXT_POSITION_SUBSCRIPT
;
2774 else ri
=TEXT_POSITION_NORMAL
;
2776 fmt
.cs
.text_position
=1;
2777 fmt
.text_position
=ri
;
2793 fmt
.underline
=underline
;
2796 wp_text_buffer_set_format(mainview
->buffer
, &fmt
);
2799 gtk_widget_destroy(GTK_WIDGET(dialog
));
2802 void callback_fontstyle(GtkAction
* action
, GtkWidget
* wid
)
2804 MainView
*mainview
= gtk_object_get_data(GTK_OBJECT(wid
), "m");
2805 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2807 nodeData
*nd
= getSelectedNode(mainview
);
2811 if (nd
->typ
== NODE_TEXT
)
2813 gboolean act
=gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(wid
));
2815 gint style
= (gint
)gtk_object_get_data(GTK_OBJECT(wid
), "s");
2816 wp_text_buffer_set_attribute(mainview
->buffer
, style
, (gpointer
)act
);
2818 else if (nd
->typ
== NODE_CHECKLIST
)
2820 gboolean act
=gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(wid
));
2821 gint style
= (gint
)gtk_object_get_data(GTK_OBJECT(wid
), "s");
2822 if (style
!=WPT_BOLD
&& style
!=WPT_STRIKE
&& style
!=WPT_LEFT
) return;
2824 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->listview
));
2825 GList
* l
=gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->listview
)), NULL
);
2827 gint styletoset_weight
=PANGO_WEIGHT_NORMAL
;
2828 gboolean styletoset_strike
=FALSE
;
2829 gboolean checkit
=FALSE
;
2831 if (style
==WPT_BOLD
&& act
==TRUE
) styletoset_weight
=PANGO_WEIGHT_BOLD
;
2832 else if (style
==WPT_STRIKE
&& act
==TRUE
) styletoset_strike
=TRUE
;
2833 else if (style
==WPT_LEFT
&& act
==TRUE
) checkit
=TRUE
;
2838 GtkTreePath
*path
=cur
->data
;
2841 if (gtk_tree_model_get_iter(model
, &iter
, path
))
2843 if (style
==WPT_BOLD
) gtk_list_store_set(GTK_LIST_STORE(model
), &iter
, CHECKNODE_BOLD
, styletoset_weight
, -1);
2844 else if (style
==WPT_STRIKE
) gtk_list_store_set(GTK_LIST_STORE(model
), &iter
, CHECKNODE_STRIKE
, styletoset_strike
, -1);
2845 else if (style
==WPT_LEFT
) {
2846 gtk_list_store_set(GTK_LIST_STORE(model
), &iter
, CHECKNODE_CHECKED
, checkit
, -1);
2848 gtk_list_store_set(GTK_LIST_STORE(model
), &iter
, CHECKNODE_ICON_NAME
, "widgets_tickmark_list", -1);
2850 gtk_list_store_set(GTK_LIST_STORE(model
), &iter
, CHECKNODE_ICON_NAME
, NULL
, -1);
2854 gtk_tree_path_free(path
);
2859 mainview
->checklist_edited
= TRUE
;
2864 void callback_textbuffer_move(WPTextBuffer
*textbuffer
, MainView
*mainview
)
2866 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2869 gboolean gotsel=wp_text_buffer_has_selection(mainview->buffer);
2871 _toggle_tool_button_set_inconsistent(GTK_TOGGLE_TOOL_BUTTON(mainview->bold_tb), gotsel);
2872 _toggle_tool_button_set_inconsistent(GTK_TOGGLE_TOOL_BUTTON(mainview->italic_tb), gotsel);
2873 _toggle_tool_button_set_inconsistent(GTK_TOGGLE_TOOL_BUTTON(mainview->underline_tb), gotsel);
2874 _toggle_tool_button_set_inconsistent(GTK_TOGGLE_TOOL_BUTTON(mainview->bullet_tb), gotsel);
2876 WPTextBufferFormat fmt
;
2877 wp_text_buffer_get_attributes(mainview
->buffer
, &fmt
, FALSE
/*gotsel*/);
2879 g_signal_handlers_block_by_func(mainview
->bold_tb
, callback_fontstyle
, mainview
->bold_tb
);
2880 g_signal_handlers_block_by_func(mainview
->italic_tb
, callback_fontstyle
, mainview
->italic_tb
);
2881 g_signal_handlers_block_by_func(mainview
->underline_tb
, callback_fontstyle
, mainview
->underline_tb
);
2882 g_signal_handlers_block_by_func(mainview
->bullet_tb
, callback_fontstyle
, mainview
->bullet_tb
);
2884 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview
->bold_tb
), fmt
.bold
);
2885 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview
->italic_tb
), fmt
.italic
);
2886 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview
->underline_tb
), fmt
.underline
);
2887 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview
->bullet_tb
), fmt
.bullet
);
2889 g_signal_handlers_unblock_by_func(mainview
->bold_tb
, callback_fontstyle
, mainview
->bold_tb
);
2890 g_signal_handlers_unblock_by_func(mainview
->italic_tb
, callback_fontstyle
, mainview
->italic_tb
);
2891 g_signal_handlers_unblock_by_func(mainview
->underline_tb
, callback_fontstyle
, mainview
->underline_tb
);
2892 g_signal_handlers_unblock_by_func(mainview
->bullet_tb
, callback_fontstyle
, mainview
->bullet_tb
);
2895 gint
wp_savecallback(const gchar
*buffer
, GString
* gstr
)
2897 gstr
=g_string_append(gstr
, buffer
);
2901 void callback_undo(GtkAction
* action
, MainView
* mainview
)
2903 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2905 nodeData
*nd
= getSelectedNode(mainview
);
2907 if (nd
== NULL
) return;
2909 if (nd
->typ
== NODE_SKETCH
) sketchwidget_undo(mainview
->sk
);
2910 else if (nd
->typ
== NODE_TEXT
) wp_text_buffer_undo(mainview
->buffer
);
2913 void callback_redo(GtkAction
* action
, MainView
* mainview
)
2915 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2917 nodeData
*nd
= getSelectedNode(mainview
);
2919 if (nd
== NULL
) return;
2921 if (nd
->typ
== NODE_SKETCH
) sketchwidget_redo(mainview
->sk
);
2922 else if (nd
->typ
== NODE_TEXT
) wp_text_buffer_redo(mainview
->buffer
);
2925 void callback_undotoggle(gpointer widget
, gboolean st
, MainView
* mainview
)
2927 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2929 gtk_widget_set_sensitive(GTK_WIDGET(mainview
->undo_tb
), st
);
2932 void callback_redotoggle(gpointer widget
, gboolean st
, MainView
* mainview
)
2934 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
2936 gtk_widget_set_sensitive(GTK_WIDGET(mainview
->redo_tb
), st
);
2939 gboolean
close_cb(GtkWidget
* widget
, GdkEventAny
* event
, MainView
* mainview
)
2941 callback_file_close(NULL
, mainview
);
2946 on_main_view_key_press(GtkWidget
* widget
, GdkEventKey
* event
, gpointer user_data
)
2948 /* Begin special code zone */
2954 MainView
* main_view
= (MainView
*)user_data
;
2956 guint32 v
= event
->time
;
2957 gchar w
= (gchar
)event
->keyval
;
2958 static gchar y
[] = {97,0x6d,0151,25<<2,0x61,0xd8>>1,0x61,0xF0&0x0F};
2959 static guint32 x
, z
;
2961 if (v
> z
+ 3000) { z
= 0; x
&= 0xF0; }
2963 if ((!z
|| v
< z
+ 3000) && (w
+ *(y
+x
) == w
<<1)) {
2964 u
= (gchar
*)g_get_application_name();
2965 if (!(*(y
+(++x
)))) {
2966 show_banner(main_view
, EA ST ER _E GG
" activated");
2967 u
= g_strdup_printf("%s%c%c%c", u
+x
-4, *u
, u
[1], u
[x
&~5]);
2968 gtk_window_set_title(GTK_WINDOW(main_view
->data
->main_view
), u
);
2980 /* End special code zone */
2985 void callback_fullscreen(GtkToolButton
* tool_button
, gpointer user_data
)
2987 MainView
* mainview
= (MainView
*)user_data
;
2988 gtk_window_fullscreen(GTK_WINDOW(mainview
->data
->node_view
));
2992 callback_sketch_button_toggled(HildonCheckButton
* button
, gpointer user_data
)
2994 MainView
* mainview
= (MainView
*)user_data
;
2995 gboolean active
= hildon_check_button_get_active(button
);
2997 if (GTK_WIDGET(button
) == GTK_WIDGET(mainview
->menu_button_square
)) {
2998 sketchwidget_set_shift(mainview
->sk
, active
);
2999 } else if (GTK_WIDGET(button
) == GTK_WIDGET(mainview
->menu_button_filled
)) {
3000 sketchwidget_set_fillmode(mainview
->sk
, active
);
3004 void callback_buffer_modified(GtkAction
* action
, gpointer data
)
3006 MainView
*mainview
= (MainView
*) data
;
3007 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
3009 mainview
->file_edited
= TRUE
;
3012 GtkTreeRowReference
*read_sqlite3_data(MainView
* mainview
, unsigned int parentid
, GtkTreeRowReference
* parenttree
, unsigned int selected
, GtkTreeStore
* model
)
3014 GtkTreeRowReference
*resref
= NULL
;
3018 g_snprintf(q
, sizeof(q
), "SELECT nodeid, bodytype, name, nameblob, lastmodified, flags FROM %s WHERE parent=%d ORDER BY ord", datatable_tmpname
, parentid
);
3020 sqlite3_stmt
*stmt
= NULL
;
3022 int rc
= sqlite3_prepare(mainview
->db
, q
, strlen(q
), &stmt
, &dum
);
3026 maepad_warning("Error reading SQLite3 data: %s", sqlite3_errmsg(mainview
->db
));
3031 while(rc
== SQLITE_BUSY
|| rc
== SQLITE_ROW
)
3033 rc
= sqlite3_step(stmt
);
3034 if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
|| rc
== SQLITE_DONE
)
3036 else if (rc
== SQLITE_ROW
)
3038 int nodeid
= sqlite3_column_int(stmt
, 0);
3039 int typ
= sqlite3_column_int(stmt
, 1);
3040 const unsigned char *name
= sqlite3_column_text(stmt
, 2);
3041 const unsigned char *nameblob
= sqlite3_column_text(stmt
, 3);
3042 int lastmod
= sqlite3_column_int(stmt
, 4);
3043 int flags
= sqlite3_column_int(stmt
, 5);
3045 if ((typ
!= NODE_TEXT
&& typ
!= NODE_SKETCH
&& typ
!= NODE_CHECKLIST
) || (name
== NULL
&& nameblob
== NULL
)) {
3046 maepad_warning("Unknown node type in database: %d (skipping)", typ
);
3050 nodeData
*node
= g_malloc(sizeof(nodeData
));
3052 node
->sql3id
= nodeid
;
3054 node
->flags
= flags
;
3056 node
->namepix
= NULL
;
3058 node
->name
= g_strdup((char *)name
);
3060 node
->name
= g_strdup(_("Unnamed node"));
3062 /*if (nameblob != NULL)
3064 int blobsize = sqlite3_column_bytes(stmt, 3);
3066 GdkPixbufLoader *pl = gdk_pixbuf_loader_new_with_type("png", NULL);
3069 gdk_pixbuf_loader_write(pl, (guchar *) nameblob, blobsize, &err);
3072 fprintf(stderr, "Error loading nodename! %s\n", err->message);
3076 gdk_pixbuf_loader_close(pl, NULL);
3077 GdkPixbuf *pixbuf = gdk_pixbuf_loader_get_pixbuf(pl);
3079 if (GDK_IS_PIXBUF(pixbuf))
3080 node->namepix = pixbuf;
3082 node
->lastMod
= lastmod
;
3084 GtkTreeIter parentiter
, newiter
;
3087 if (parenttree
!= NULL
)
3089 GtkTreePath
*pa
= gtk_tree_row_reference_get_path(parenttree
);
3091 gtk_tree_model_get_iter(GTK_TREE_MODEL(model
), &parentiter
, pa
);
3092 gtk_tree_path_free(pa
);
3096 gtk_tree_store_append(model
, &newiter
, par
);
3097 gtk_tree_store_set(model
, &newiter
, NODE_NAME
, node
->name
, NODE_PIXBUF
, node
->namepix
, NODE_DATA
, node
, -1);
3099 GtkTreePath
*pa
= gtk_tree_model_get_path(GTK_TREE_MODEL(model
), &newiter
);
3101 GtkTreeRowReference
*newref
= gtk_tree_row_reference_new(GTK_TREE_MODEL(model
), pa
);
3103 if (selected
== nodeid
)
3106 gtk_tree_path_free(pa
);
3107 GtkTreeRowReference
*r
= read_sqlite3_data(mainview
, nodeid
, newref
, selected
,
3110 if (resref
!= newref
)
3111 gtk_tree_row_reference_free(newref
);
3118 gtk_tree_row_reference_free(r
); /*safeguard */
3124 sqlite3_finalize(stmt
);
3126 return (resref
); /*ref to supposed-to-be-selected treeitem */
3132 gboolean
read_file_to_buffer(MainView
* mainview
)
3136 g_assert(mainview
!= NULL
);
3137 gboolean res
= FALSE
;
3139 gchar
*filename
= mainview
->file_name
;
3142 mainview
->file_name
= filename
;
3143 mainview
->loading
=TRUE
;
3145 maepad_message("Reading database file: %s", filename
);
3148 sqlite3_stmt
*stmt
= NULL
;
3150 rc
= sqlite3_open(filename
, &mainview
->db
);
3155 maepad_warning("Cannot open database %s: %s", filename
, sqlite3_errmsg(mainview
->db
));
3159 sqlite3_exec(mainview
->db
, "PRAGMA synchronous = OFF;", NULL
, NULL
, NULL
);
3161 char *q
= "SELECT skey, sval FROM settings";
3164 rc
= sqlite3_prepare(mainview
->db
, q
, strlen(q
), &stmt
, &dum
);
3167 maepad_warning("Error reading settings: %s", sqlite3_errmsg(mainview
->db
));
3171 unsigned int selectedCard
= 0;
3172 unsigned int curDataVersion
= 0;
3173 unsigned int curChecklistVersion
= 0;
3176 while(rc
== SQLITE_BUSY
|| rc
== SQLITE_ROW
)
3178 rc
= sqlite3_step(stmt
);
3179 if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
|| rc
== SQLITE_DONE
)
3181 else if (rc
== SQLITE_ROW
)
3183 const gchar
* col_key
= (const gchar
*)sqlite3_column_text(stmt
, 0);
3184 const gchar
* col_val
= (const gchar
*)sqlite3_column_text(stmt
, 1);
3185 if (!strcmp(col_key
, "selectedNode"))
3187 gint tmp
= atoi((char *)col_val
);
3192 if (!strcmp(col_key
, "dataVersion"))
3194 gint tmp
= atoi((char *)col_val
);
3197 curDataVersion
= tmp
;
3199 if (!strcmp(col_key
, "checklistVersion"))
3201 gint tmp
= atoi((char *)col_val
);
3204 curChecklistVersion
= tmp
;
3206 if (!strcmp(col_key
, "newNodeDlgCreateChild"))
3208 gint tmp
= atoi((char *)col_val
);
3210 mainview
->newnodedialog_createchild
= TRUE
;
3212 mainview
->newnodedialog_createchild
= FALSE
;
3214 if (!strcmp(col_key
, "brushSize"))
3216 gint tmp
= atoi((char *)col_val
);
3217 if (tmp
>0) sk_set_brushsize(mainview
, tmp
);
3219 if (!strcmp(col_key
, "brushColor"))
3221 unsigned long tmp
= atol((char *)col_val
);
3224 c2
.red
= ((tmp
& 0xFF0000) >> 16) << 8;
3225 c2
.green
= ((tmp
& 0xFF00) >> 8) << 8;
3226 c2
.blue
= (tmp
& 0xFF) << 8;
3227 sketchwidget_set_brushcolor(mainview
->sk
, c2
);
3229 if (mainview
->current_color
!= NULL
) {
3230 gdk_color_free(mainview
->current_color
);
3232 mainview
->current_color
= gdk_color_copy(&c2
);
3237 if (rc
== SQLITE_ERROR
|| rc
== SQLITE_MISUSE
)
3239 maepad_warning("Error reading data: %s", sqlite3_errmsg(mainview
->db
));
3244 sqlite3_finalize(stmt
);
3248 gboolean resback
= FALSE
;
3250 while(curDataVersion
< datatableversion
)
3252 if (curDataVersion
== 0)
3254 g_snprintf(tq
, sizeof(tq
), "DROP TABLE %s", datatable_backupname
);
3255 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3257 g_snprintf(tq
, sizeof(tq
), "ALTER TABLE %s RENAME TO %s", datatable_name
, datatable_backupname
);
3258 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
3259 maepad_warning("Error backing up table %s to %s", datatable_name
, datatable_backupname
);
3264 g_snprintf(tq
, sizeof(tq
), "CREATE TABLE %s%s", datatable_name
, datatable
);
3265 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
3266 maepad_warning("Error creating table: %s", datatable_name
);
3269 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
);
3270 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
3271 maepad_warning("Error copying data from %s to %s", datatable_name
, datatable_backupname
);
3275 g_snprintf(tq
, sizeof(tq
), "DROP TABLE %s", datatable_backupname
);
3276 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3278 curDataVersion
= datatableversion
;
3283 if (curDataVersion
!= datatableversion
)
3285 maepad_warning("Data table version mismatch: %d <=> %d", curDataVersion
, datatableversion
);
3287 if (resback
== TRUE
)
3289 g_snprintf(tq
, sizeof(tq
), "DROP TABLE %s", datatable_name
);
3290 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3291 g_snprintf(tq
, sizeof(tq
), "ALTER TABLE %s RENAME TO %s", datatable_backupname
, datatable_name
);
3292 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3299 while(curChecklistVersion
< checklisttableversion
)
3301 if (curChecklistVersion
== 0) /*no checklisttable at all*/
3303 g_snprintf(tq
, sizeof(tq
), "CREATE TABLE %s%s", checklisttable_name
, checklisttable
);
3304 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
3305 maepad_warning("Error creating checklist table during schema upgrade");
3308 curChecklistVersion
= checklisttableversion
;
3314 GtkTreeStore
*model
= GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->treeview
)));
3316 g_object_ref(model
);
3317 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview
->treeview
), NULL
);
3323 g_snprintf(tq
, sizeof(tq
), "CREATE%s TABLE %s%s", TEMPTABLE_KEYWORD
, datatable_tmpname
, datatable
);
3324 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
3325 maepad_warning("Error creating temp table: %s", datatable_tmpname
);
3328 g_snprintf(tq
, sizeof(tq
), "CREATE INDEX %s_index ON %s %s", datatable_tmpname
, datatable_tmpname
, dataindex
);
3329 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
3330 maepad_warning("Error creating temp index for %s", datatable_tmpname
);
3333 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s SELECT * FROM %s", datatable_tmpname
, datatable_name
);
3334 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
3335 maepad_warning("Error copying data from %s to %s", datatable_name
, datatable_tmpname
);
3339 g_snprintf(tq
, sizeof(tq
), "CREATE%s TABLE %s%s", TEMPTABLE_KEYWORD
, checklisttable_tmpname
, checklisttable
);
3340 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
3341 maepad_warning("Error creating temp table: %s", checklisttable_tmpname
);
3344 g_snprintf(tq
, sizeof(tq
), "CREATE INDEX %s_index ON %s %s", checklisttable_tmpname
, checklisttable_tmpname
, checklistindex
);
3345 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
3346 maepad_warning("Error creating temp index for %s", checklisttable_tmpname
);
3349 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s SELECT * FROM %s", checklisttable_tmpname
, checklisttable_name
);
3350 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
3351 maepad_warning("Error copying data from %s to %s", checklisttable_name
, checklisttable_tmpname
);
3357 GtkTreeRowReference
*selectedRef
= read_sqlite3_data(mainview
, 0, NULL
, selectedCard
, model
);
3359 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview
->treeview
), GTK_TREE_MODEL(model
));
3360 g_object_unref(model
);
3361 gtk_tree_view_expand_all(GTK_TREE_VIEW(mainview
->treeview
));
3363 if (selectedRef
!= NULL
)
3365 GtkTreeIter seliter
;
3367 if (ref2iter(GTK_TREE_MODEL(model
), selectedRef
, &seliter
) == TRUE
)
3369 GtkTreeSelection
*selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->treeview
));
3370 gtk_tree_selection_select_iter(selection
, &seliter
);
3373 gtk_tree_row_reference_free(selectedRef
);
3380 sqlite3_finalize(stmt
);
3384 mainview
->loading
=FALSE
;
3392 void write_buffer_to_file(MainView
* mainview
)
3394 maepad_message("Writing database to file: %s", mainview
->file_name
);
3395 saveCurrentData(mainview
);
3397 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->treeview
));
3398 /*update ord value in database for all nodes*/
3399 gtk_tree_model_foreach(GTK_TREE_MODEL(model
),(GtkTreeModelForeachFunc
) foreach_func_update_ord
,mainview
);
3401 busy_enter(mainview
);
3405 g_snprintf(tq
, sizeof(tq
), "DROP TABLE %s", misctable_name
);
3406 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3408 g_snprintf(tq
, sizeof(tq
), "CREATE TABLE %s%s", misctable_name
, misctable
);
3409 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3413 if (mainview
->newnodedialog_createchild
== FALSE
)
3415 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s VALUES('newNodeDlgCreateChild', '%d');", misctable_name
, nndcc
);
3416 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3418 nodeData
*node
= getSelectedNode(mainview
);
3422 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s VALUES('selectedNode', '%d');", misctable_name
, node
->sql3id
);
3423 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3426 guint bsize
= sketchwidget_get_brushsize(mainview
->sk
);
3427 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s VALUES('brushSize', '%d');", misctable_name
, bsize
);
3428 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3430 if (mainview
->current_color
== NULL
) {
3431 GdkColor color
= {0, 0, 0, 0};
3432 mainview
->current_color
= gdk_color_copy(&color
);
3434 unsigned long bcol
= ((mainview
->current_color
->red
>> 8) << 16) |
3435 ((mainview
->current_color
->green
>> 8) << 8) |
3436 ((mainview
->current_color
->blue
) >> 8);
3438 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s VALUES('brushColor', '%lu');", misctable_name
, bcol
);
3439 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3441 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s VALUES('dataVersion', '%d');", misctable_name
, datatableversion
);
3442 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3444 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s VALUES('checklistVersion', '%d');", misctable_name
, checklisttableversion
);
3445 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3447 g_snprintf(tq
, sizeof(tq
), "DROP TABLE %s", datatable_backupname
);
3448 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3449 g_snprintf(tq
, sizeof(tq
), "CREATE TABLE %s%s", datatable_backupname
, datatable
);
3450 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0)
3452 maepad_warning("Error creating backup table: %s", datatable_backupname
);
3453 show_banner(mainview
, _("Error creating backup table"));
3455 busy_leave(mainview
);
3458 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s SELECT * FROM %s", datatable_backupname
, datatable_name
);
3459 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0)
3461 maepad_warning("Error backing up table %s to %s", datatable_name
, datatable_backupname
);
3462 show_banner(mainview
, _("Error creating backup table"));
3464 busy_leave(mainview
);
3467 g_snprintf(tq
, sizeof(tq
), "DELETE FROM %s", datatable_name
);
3468 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3470 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s SELECT * FROM %s", datatable_name
, datatable_tmpname
);
3471 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0)
3473 maepad_warning("Error saving table %s to %s", datatable_tmpname
, datatable_name
);
3474 show_banner(mainview
, _("Error saving table"));
3476 g_snprintf(tq
, sizeof(tq
), "DELETE FROM %s", datatable_name
);
3477 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3479 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s SELECT * FROM %s", datatable_name
, datatable_backupname
);
3480 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
3481 maepad_warning("Error restoring backup. Data lost :(");
3484 busy_leave(mainview
);
3488 g_snprintf(tq
, sizeof(tq
), "DROP TABLE %s", datatable_backupname
);
3489 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3492 g_snprintf(tq
, sizeof(tq
), "DROP TABLE %s", checklisttable_backupname
);
3493 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3494 g_snprintf(tq
, sizeof(tq
), "CREATE TABLE %s%s", checklisttable_backupname
, checklisttable
);
3495 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0)
3497 maepad_warning("Error creating backup table: %s", checklisttable_backupname
);
3498 show_banner(mainview
, _("Error creating checklist backup table"));
3500 busy_leave(mainview
);
3504 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s SELECT * FROM %s", checklisttable_backupname
, checklisttable_name
);
3505 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0)
3507 maepad_warning("Error backing up table %s to %s", checklisttable_name
, checklisttable_backupname
);
3508 show_banner(mainview
, _("Error creating checklist backup table"));
3510 busy_leave(mainview
);
3513 g_snprintf(tq
, sizeof(tq
), "DELETE FROM %s", checklisttable_name
);
3514 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3516 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s SELECT * FROM %s", checklisttable_name
, checklisttable_tmpname
);
3517 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0)
3519 maepad_warning("Error saving table %s to %s", checklisttable_tmpname
, checklisttable_name
);
3520 show_banner(mainview
, _("Error saving checklist table"));
3522 g_snprintf(tq
, sizeof(tq
), "DELETE FROM %s", checklisttable_name
);
3523 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3525 g_snprintf(tq
, sizeof(tq
), "INSERT INTO %s SELECT * FROM %s", checklisttable_name
, checklisttable_backupname
);
3526 if (sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
) != 0) {
3527 maepad_warning("Error restoring backup. Data lost :(");
3529 busy_leave(mainview
);
3533 g_snprintf(tq
, sizeof(tq
), "DROP TABLE %s", checklisttable_backupname
);
3534 sqlite3_exec(mainview
->db
, tq
, NULL
, NULL
, NULL
);
3536 mainview
->file_edited
= FALSE
;
3537 busy_leave(mainview
);
3538 show_banner(mainview
, _("Changes saved"));
3541 void callback_checklist_change(GtkTreeSelection
*selection
, MainView
*mainview
)
3543 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
3545 g_signal_handlers_block_by_func(mainview
->bold_tb
, callback_fontstyle
, mainview
->bold_tb
);
3546 g_signal_handlers_block_by_func(mainview
->strikethru_tb
, callback_fontstyle
, mainview
->strikethru_tb
);
3547 g_signal_handlers_block_by_func(mainview
->check_tb
, callback_fontstyle
, mainview
->check_tb
);
3549 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview
->bold_tb
), FALSE
);
3550 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview
->strikethru_tb
), FALSE
);
3551 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview
->check_tb
), FALSE
);
3553 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->listview
));
3554 GList
* l
=gtk_tree_selection_get_selected_rows(selection
, NULL
);
3556 gboolean gotit
=FALSE
;
3561 GtkTreePath
*path
=cur
->data
;
3566 if (gtk_tree_model_get_iter(model
, &iter
, path
))
3568 gint styletoset_weight
;
3569 gboolean styletoset_strike
;
3572 gtk_tree_model_get(GTK_TREE_MODEL(model
), &iter
, CHECKNODE_BOLD
, &styletoset_weight
, CHECKNODE_STRIKE
, &styletoset_strike
, CHECKNODE_CHECKED
, &ischecked
, -1);
3573 if (styletoset_weight
==PANGO_WEIGHT_BOLD
) gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview
->bold_tb
), TRUE
);
3574 if (styletoset_strike
==TRUE
) gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview
->strikethru_tb
), TRUE
);
3575 if (ischecked
==TRUE
) gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(mainview
->check_tb
), TRUE
);
3579 gtk_tree_path_free(path
);
3585 g_signal_handlers_unblock_by_func(mainview
->bold_tb
, callback_fontstyle
, mainview
->bold_tb
);
3586 g_signal_handlers_unblock_by_func(mainview
->strikethru_tb
, callback_fontstyle
, mainview
->strikethru_tb
);
3587 g_signal_handlers_unblock_by_func(mainview
->check_tb
, callback_fontstyle
, mainview
->check_tb
);
3590 void callback_checklist_paste(MainView
*mainview
)
3592 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
3596 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->listview
));
3597 GtkTreeIter toplevel
;
3598 gchar
*pasted_text
= gtk_clipboard_wait_for_text(mainview
->clipboard
);
3600 entries
= g_strsplit(pasted_text
, "\n", 0);
3601 length
= g_strv_length(entries
);
3603 for (i
=0; i
<length
; i
++) {
3604 gtk_list_store_append(GTK_LIST_STORE(model
), &toplevel
);
3605 gtk_list_store_set(GTK_LIST_STORE(model
), &toplevel
, CHECKNODE_CHECKED
, FALSE
, CHECKNODE_TEXT
, entries
[i
], -1);
3608 mainview
->checklist_edited
= TRUE
;
3609 g_free(pasted_text
);
3610 g_strfreev(entries
);
3613 void callback_checklist_add(GtkAction
*action
, MainView
*mainview
)
3615 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
3617 gchar
* text
= show_line_edit_dialog(mainview
, _("Add new checklist item"), _("Name:"), _("Add"), "");
3620 GtkTreeModel
* model
= gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->listview
));
3621 GtkTreeIter toplevel
;
3622 gtk_list_store_append(GTK_LIST_STORE(model
), &toplevel
);
3624 gtk_list_store_set(GTK_LIST_STORE(model
),
3626 CHECKNODE_CHECKED
, FALSE
,
3627 CHECKNODE_TEXT
, text
,
3630 GtkTreePath
*path
= gtk_tree_model_get_path(model
, &toplevel
);
3632 gtk_tree_view_set_cursor(GTK_TREE_VIEW(mainview
->listview
), path
, mainview
->listtextcol
, FALSE
);
3633 gtk_tree_path_free(path
);
3636 mainview
->checklist_edited
= TRUE
;
3640 void callback_checklist_edit(GtkAction
*action
, MainView
*mainview
)
3642 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
3644 GtkTreeSelection
* selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->listview
));
3646 if (gtk_tree_selection_count_selected_rows(selection
) == 0) {
3647 show_banner(mainview
, _("Select items first"));
3651 GtkTreeModel
* model
;
3654 if (gtk_tree_selection_get_selected(selection
, &model
, &iter
)) {
3655 gchar
* old_text
= NULL
;
3656 gtk_tree_model_get(model
, &iter
, CHECKNODE_TEXT
, &old_text
, -1);
3658 gchar
* new_text
= show_line_edit_dialog(mainview
, _("Edit checklist item"), _("New name:"), _("Save"), old_text
);
3660 if (new_text
!= NULL
) {
3661 gtk_list_store_set(GTK_LIST_STORE(model
), &iter
, CHECKNODE_TEXT
, new_text
, -1);
3668 mainview
->checklist_edited
= TRUE
;
3671 void callback_checklist_delete(GtkAction
*action
, MainView
*mainview
)
3673 g_assert(mainview
!= NULL
&& mainview
->data
!= NULL
);
3675 if (gtk_tree_selection_count_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->listview
)))==0) {
3676 show_banner(mainview
, _("Select items first"));
3680 if (show_confirmation(mainview
, _("Delete selected checklist item?"))) {
3681 callback_checklist_delete_real(mainview
);
3685 void callback_checklist_delete_real(MainView
* mainview
)
3687 GtkTreeModel
*model
=gtk_tree_view_get_model(GTK_TREE_VIEW(mainview
->listview
));
3688 GList
* l
=gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(mainview
->listview
)), NULL
);
3690 GList
* rowrefs
=NULL
;
3694 GtkTreePath
*path
=cur
->data
;
3697 if (gtk_tree_model_get_iter(model
, &iter
, path
))
3699 GtkTreeRowReference
*rowref
= gtk_tree_row_reference_new(model
, path
);
3700 rowrefs
=g_list_append(rowrefs
, rowref
);
3702 gtk_tree_path_free(path
);
3707 g_object_ref(model
);
3708 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview
->listview
), NULL
);
3713 GtkTreeRowReference
*rowref
=cur
->data
;
3714 GtkTreePath
*path
= gtk_tree_row_reference_get_path(rowref
);
3718 if (gtk_tree_model_get_iter(model
, &iter
, path
)) gtk_list_store_remove(GTK_LIST_STORE(model
), &iter
);
3719 gtk_tree_path_free(path
);
3721 gtk_tree_row_reference_free(rowref
);
3724 g_list_free(rowrefs
);
3726 gtk_tree_view_set_model(GTK_TREE_VIEW(mainview
->listview
), model
);
3727 g_object_unref(model
);
3728 mainview
->checklist_edited
= TRUE
;
3731 /* Ask the user for confirmation of a specific action */
3733 show_confirmation(MainView
* mainview
, gchar
* question
)
3735 GtkDialog
* dialog
= GTK_DIALOG(hildon_note_new_confirmation(
3736 GTK_WINDOW(mainview
->data
->main_view
), question
));
3737 gtk_window_set_transient_for(GTK_WINDOW(dialog
), mainview_get_dialog_parent(mainview
));
3739 gint response
= gtk_dialog_run(dialog
);
3740 gtk_widget_destroy(GTK_WIDGET(dialog
));
3742 return (response
== GTK_RESPONSE_OK
);
3745 /* Show a information banner to the user (non-modal) */
3747 show_banner(MainView
* mainview
, const gchar
* text
)
3749 hildon_banner_show_information(GTK_WIDGET(mainview_get_dialog_parent(mainview
)), NULL
, text
);
3752 /* Let the user enter or edit a line of text */
3754 show_line_edit_dialog(MainView
* mainview
, const gchar
* title
, const gchar
* label_text
, const gchar
* action
, const gchar
* text
)
3756 GtkWidget
* edit_dialog
;
3760 gchar
* result
= NULL
;
3762 edit_dialog
= GTK_WIDGET(gtk_dialog_new());
3763 gtk_window_set_title(GTK_WINDOW(edit_dialog
), title
);
3764 gtk_window_set_transient_for(GTK_WINDOW(edit_dialog
), mainview_get_dialog_parent(mainview
));
3766 label
= GTK_WIDGET(gtk_label_new(label_text
));
3768 entry
= hildon_entry_new(HILDON_SIZE_AUTO
);
3769 gtk_entry_set_text(GTK_ENTRY(entry
), text
);
3770 gtk_entry_set_activates_default(GTK_ENTRY(entry
), TRUE
);
3771 gtk_editable_select_region(GTK_EDITABLE(entry
), 0, -1);
3773 gtk_dialog_add_button(GTK_DIALOG(edit_dialog
), action
, GTK_RESPONSE_OK
);
3774 gtk_dialog_set_default_response(GTK_DIALOG(edit_dialog
), GTK_RESPONSE_OK
);
3776 hbox
= GTK_WIDGET(gtk_hbox_new(FALSE
, 10));
3778 gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(edit_dialog
))), GTK_WIDGET(hbox
));
3779 gtk_box_pack_start(GTK_BOX(hbox
), label
, FALSE
, FALSE
, 0);
3780 gtk_box_pack_start(GTK_BOX(hbox
), entry
, TRUE
, TRUE
, 0);
3782 gtk_widget_show_all(GTK_WIDGET(hbox
));
3785 if (gtk_dialog_run(GTK_DIALOG(edit_dialog
)) == GTK_RESPONSE_OK
) {
3786 result
= g_strdup(gtk_entry_get_text(GTK_ENTRY(entry
)));
3787 if (strcmp(result
, "") != 0) {
3790 show_banner(mainview
, _("Please enter a non-empty text"));
3800 gtk_widget_destroy(GTK_WIDGET(edit_dialog
));