Merge lp:~midori/midori/clippyEditor into lp:midori

Proposed by Christian Dywan on 2017-11-27
Status: Needs review
Proposed branch: lp:~midori/midori/clippyEditor
Merge into: lp:midori
Prerequisite: lp:~midori/midori/clippyBookmarks
Diff against target: 1021 lines (+408/-453)
7 files modified
extensions/clippy.vala (+160/-1)
midori/midori-bookmarks-db.c (+215/-0)
midori/midori-bookmarks-db.h (+4/-0)
midori/midori-browser.c (+21/-450)
midori/midori.vapi (+6/-0)
panels/midori-bookmarks.c (+1/-1)
panels/midori-history.c (+1/-1)
To merge this branch: bzr merge lp:~midori/midori/clippyEditor
Reviewer Review Type Date Requested Status
Midori Devs 2017-11-27 Pending
Review via email: mp+334320@code.launchpad.net

Commit message

Move bookmark editor into clippy

Description of the change

This branch moves the bookmark editor into Clippy (and always uses a popover in all cases, no dialog, for consistency). The combo box created from the bookmarks database moves out of Browser into to BookmarksDb, which is where it should've been in the first place.

To post a comment you must log in.

Unmerged revisions

7175. By Christian Dywan on 2017-11-27

Move bookmark editor into clippy

7174. By Christian Dywan on 2017-11-26

Move bookmarkbar into clippy extension

7173. By Christian Dywan on 2017-11-26

Drop pass-through-console flag

7172. By Christian Dywan on 2017-11-25

Unconditionally include WebKit2 headers

7171. By Christian Dywan on 2017-11-07

Drop non-WebKit2 website saving code path

7170. By Christian Dywan on 2017-11-06

Non-conditional skipping of non-WebKit2 extensions

7169. By Christian Dywan on 2017-11-06

Drop non-WebKit2/ non-libnotify code paths

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'extensions/clippy.vala'
2--- extensions/clippy.vala 2017-11-27 17:24:49 +0000
3+++ extensions/clippy.vala 2017-11-27 17:24:49 +0000
4@@ -10,6 +10,129 @@
5 */
6
7 namespace Bookmarks {
8+ private class Editor : Gtk.Popover {
9+ Midori.Browser browser;
10+ bool new_bookmark;
11+ bool is_folder;
12+ Katze.Item bookmark;
13+ Gtk.Button accept;
14+ Gtk.Entry entry_title;
15+ Gtk.Entry entry_uri;
16+ Gtk.ComboBox combo_folder;
17+ Gtk.CheckButton check_toolbar;
18+
19+ public Editor (Midori.Browser browser, bool new_bookmark, bool is_folder, Katze.Item? bookmark_or_parent, Gtk.Widget? relative_to) {
20+ this.browser = browser;
21+ this.new_bookmark = new_bookmark;
22+ this.is_folder = is_folder;
23+
24+ this.relative_to = relative_to ?? browser.get_titlebar ();
25+ set_border_width (12);
26+ var content_area = new Gtk.Box (Gtk.Orientation.VERTICAL, 6);
27+ add (content_area);
28+ var actions = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6);
29+ content_area.pack_end (actions, true, true, 0);
30+ accept = new Gtk.Button.from_stock (new_bookmark ? Gtk.Stock.ADD : Gtk.Stock.SAVE);
31+ actions.pack_end (accept, false, false, 0);
32+ accept.clicked.connect (accepted);
33+ accept.set_can_default (true);
34+ set_default_widget (accept);
35+
36+ var description = new Gtk.Label (is_folder ?
37+ _("Type a name for this folder, and choose where to keep it.") :
38+ _("Type a name for this bookmark, and choose where to keep it."));
39+ var vbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 6);
40+ vbox.pack_start (description, false, false, 6);
41+ content_area.pack_start (vbox, false, false, 0);
42+
43+ if (new_bookmark) {
44+ var view = browser.tab as Midori.View;
45+ if (is_folder) {
46+ bookmark = new Katze.Array (typeof (Katze.Item));
47+ } else {
48+ bookmark = new Katze.Item ();
49+ bookmark.uri = view.get_display_uri ();
50+ }
51+ bookmark.name = view.get_display_title ();
52+ bookmark.set_meta_integer ("parentid", bookmark_or_parent != null
53+ ? bookmark_or_parent.get_meta_integer ("id") : 0);
54+ } else {
55+ bookmark = bookmark_or_parent;
56+ }
57+
58+ entry_title = new Gtk.Entry ();
59+ entry_title.activates_default = true;
60+ entry_title.text = bookmark.name != null ? bookmark.name : "";
61+ entry_title.changed.connect (title_changed);
62+ title_changed ();
63+ vbox.pack_start (entry_title, false, false, 0);
64+
65+ if (!is_folder) {
66+ entry_uri = new Gtk.Entry ();
67+ entry_uri.activates_default = true;
68+ entry_uri.text = bookmark.uri;
69+ vbox.pack_start (entry_uri, false, false, 0);
70+ }
71+
72+ var bookmarks = browser.bookmarks as Midori.BookmarksDb;
73+ combo_folder = bookmarks.folder_button_new (bookmark.get_meta_integer ("parentid"));
74+ vbox.pack_start (combo_folder, false, false, 0);
75+
76+ var hbox = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6);
77+ vbox.pack_start (hbox, false, false, 0);
78+ check_toolbar = new Gtk.CheckButton.with_mnemonic (_("Show in Bookmarks _Bar"));
79+ check_toolbar.active = bookmark.get_meta_boolean ("toolbar");
80+ hbox.pack_start (check_toolbar, false, false, 0);
81+
82+ if (new_bookmark && !is_folder) {
83+ var label = new Gtk.Button.with_mnemonic (_("Add to _Speed Dial"));
84+ label.clicked.connect (() => {
85+ var view = browser.tab as Midori.View;
86+ browser.speed_dial.add (view.get_display_uri (), view.get_display_title (), null);
87+ destroy ();
88+ });
89+ actions.pack_start (label, false, false, 0);
90+
91+ /* FIXME: There's no API for extending the bookmark dialog */
92+ var action_group = browser.get_action_group ();
93+ var action = action_group.get_action ("CreateLauncher");
94+ if (action != null) {
95+ label = new Gtk.Button.with_mnemonic (action.label);
96+ label.clicked.connect (() => {
97+ action.activate ();
98+ destroy ();
99+ });
100+ actions.pack_start (label, false, false, 0);
101+ }
102+ }
103+
104+ content_area.show_all ();
105+ show ();
106+ }
107+
108+ void title_changed () {
109+ accept.sensitive = entry_title.text != null && entry_title.text != "";
110+ }
111+
112+ void accepted () {
113+ bookmark.name = entry_title.text;
114+ bookmark.set_meta_integer ("toolbar", check_toolbar.active ? 1 : 0);
115+ if (!(bookmark is Katze.Array))
116+ bookmark.uri = entry_uri.text;
117+ Gtk.TreeIter iter;
118+ int64 parent_id = -1;
119+ if (combo_folder.get_active_iter (out iter))
120+ combo_folder.model.get (iter, 1, out parent_id);
121+ bookmark.set_meta_integer ("parentid", parent_id);
122+ var bookmarks = browser.bookmarks as Midori.BookmarksDb;
123+ if (new_bookmark)
124+ bookmarks.add_item (bookmark);
125+ else
126+ bookmarks.update_item (bookmark);
127+ destroy ();
128+ }
129+ }
130+
131 private class Toolbar : Gtk.Toolbar {
132 Midori.Browser browser;
133 bool populating;
134@@ -120,15 +243,51 @@
135 void browser_added (Midori.Browser browser) {
136 browser.notify["bookmarks"].connect (bookmarks_changed);
137 browser.notify_property ("bookmarks");
138+
139+ var action_group = browser.get_action_group ();
140+ action_group.get_action ("BookmarkAdd").activate.connect ((action) => {
141+ new Editor (browser, true, false, null,
142+ action.get_data<Gtk.Widget?> ("proxy") ?? get_proxy (action));
143+ });
144+ action_group.get_action ("BookmarkFolderAdd").activate.connect ((action) => {
145+ new Editor (browser, true, true, null,
146+ action.get_data<Gtk.Widget?> ("proxy") ?? get_proxy (action));
147+ });
148+ action_group.get_action ("BookmarkEdit").activate.connect ((action) => {
149+ new Editor (browser, false, false,
150+ action.get_data<Katze.Item> ("bookmark"),
151+ action.get_data<Gtk.Widget?> ("proxy"));
152+ });
153+ action_group.get_action ("BookmarkFolderEdit").activate.connect ((action) => {
154+ new Editor (browser, false, true,
155+ action.get_data<Katze.Item> ("bookmark"),
156+ action.get_data<Gtk.Widget?> ("proxy"));
157+ });
158+ }
159+
160+ Gtk.Widget? get_proxy (Gtk.Action action) {
161+ foreach (var proxy in action.get_proxies ()) {
162+ if (proxy is Gtk.ToolItem)
163+ return proxy;
164+ }
165+ return null;
166 }
167
168 void bookmarks_changed (GLib.Object object, GLib.ParamSpec pspec) {
169 var browser = object as Midori.Browser;
170 var action_group = browser.get_action_group ();
171- var action = action_group.get_action ("Bookmarkbar") as Gtk.ToggleAction;
172+ var action = action_group.get_action ("Bookmarkbar");
173 action.visible = browser.parent == null && browser.bookmarks != null;
174 if (action.visible)
175 browser.add_toolbar (new Toolbar (browser));
176+ action = action_group.get_action ("BookmarkAdd");
177+ action.visible = browser.bookmarks != null;
178+ action = action_group.get_action ("BookmarkFolderAdd");
179+ action.visible = browser.bookmarks != null;
180+ action = action_group.get_action ("BookmarkEdit");
181+ action.visible = browser.bookmarks != null;
182+ action = action_group.get_action ("BookmarkFolderEdit");
183+ action.visible = browser.bookmarks != null;
184 }
185
186 void activated (Midori.App app) {
187
188=== modified file 'midori/midori-bookmarks-db.c'
189--- midori/midori-bookmarks-db.c 2015-07-06 21:26:46 +0000
190+++ midori/midori-bookmarks-db.c 2017-11-27 17:24:49 +0000
191@@ -16,6 +16,7 @@
192 #include "midori-array.h"
193 #include "sokoke.h"
194 #include "midori-core.h"
195+#include "katze-cellrenderercomboboxtext.h"
196
197 #include <glib/gstdio.h>
198 #include <glib/gi18n.h>
199@@ -1149,3 +1150,217 @@
200
201 g_object_unref (array);
202 }
203+
204+typedef struct _FolderEntry
205+{
206+ const gchar *title;
207+ gint64 id;
208+ gint64 parentid;
209+} FolderEntry;
210+
211+static void
212+midori_bookmark_folder_free_folder_entry (FolderEntry* folder)
213+{
214+ g_free ((gpointer)folder->title);
215+}
216+
217+static gboolean
218+midori_bookmark_folder_button_reach_parent (GtkTreeModel* model, GtkTreeIter *iter, gint64 parentid)
219+{
220+ do
221+ {
222+ gint64 id;
223+
224+ gtk_tree_model_get (model, iter, 1, &id, -1);
225+
226+ if (parentid == id)
227+ return TRUE;
228+
229+ if (gtk_tree_model_iter_has_child (model, iter))
230+ {
231+ GtkTreeIter child;
232+ gtk_tree_model_iter_children (model, &child, iter);
233+ if (midori_bookmark_folder_button_reach_parent (model, &child, parentid))
234+ {
235+ *iter = child;
236+ return TRUE;
237+ }
238+ }
239+ }
240+ while (gtk_tree_model_iter_next (model, iter));
241+
242+ return FALSE;
243+}
244+
245+GtkWidget*
246+midori_bookmarks_db_folder_button_new (MidoriBookmarksDb* array,
247+ gint64 selected_parentid)
248+{
249+ GtkTreeStore* model;
250+ GtkWidget* combo;
251+ GtkCellRenderer* renderer;
252+ guint n;
253+ sqlite3* db;
254+ sqlite3_stmt* statement;
255+ gint result;
256+ const gchar* sqlcmd = "SELECT title, id, parentid FROM bookmarks WHERE uri='' ORDER BY parentid, title ASC";
257+ gint64 current_parentid;
258+ GtkTreeIter tree_iter;
259+ GtkTreeIter stock_parent_iter;
260+ GtkTreeIter* parent_iter;
261+ GList *folders = NULL;
262+
263+ db = g_object_get_data (G_OBJECT (array), "db");
264+ g_return_val_if_fail (db != NULL, NULL);
265+
266+ /* folder combo box model content:
267+ ** 0: title
268+ ** 1: id
269+ */
270+ model = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_INT64);
271+ combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (model));
272+
273+ /* setup combo layout
274+ ** 0: a folder icon
275+ ** 1: the folder name
276+ */
277+
278+ gtk_cell_layout_clear (GTK_CELL_LAYOUT (combo));
279+
280+ renderer = gtk_cell_renderer_pixbuf_new ();
281+ g_object_set (G_OBJECT (renderer),
282+ "stock-id", GTK_STOCK_DIRECTORY,
283+ "stock-size", GTK_ICON_SIZE_MENU,
284+ NULL);
285+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, FALSE);
286+
287+ renderer = katze_cell_renderer_combobox_text_new ();
288+ g_object_set (G_OBJECT (renderer),
289+ "width-chars", 40, /* FIXME: figure out a way to define an acceptable string length */
290+ "ellipsize", PANGO_ELLIPSIZE_END,
291+ "unfolded-text", _("Select [text]"),
292+ NULL);
293+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
294+ gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo), renderer, "text", 0);
295+
296+ /* read the folders list from the database */
297+ /* FIXME: this should be a service of midori/midori-bookmarks-db */
298+
299+ if ((result = sqlite3_prepare_v2 (db, sqlcmd, -1, &statement, NULL)) == SQLITE_OK)
300+ {
301+ while ((result = sqlite3_step (statement)) == SQLITE_ROW)
302+ {
303+ FolderEntry* folder = g_new (FolderEntry, 1);
304+
305+ folder->title = g_strdup ((const gchar*)sqlite3_column_text (statement, 0));
306+ folder->id = sqlite3_column_int64 (statement, 1);
307+ folder->parentid = sqlite3_column_int64 (statement, 2);
308+
309+ folders = g_list_append (folders, folder);
310+ }
311+
312+ sqlite3_clear_bindings (statement);
313+ sqlite3_reset (statement);
314+ }
315+
316+ /* populate the combo box */
317+ /* FIXME: here we should have the root bookmark array's name and id, not hard encoded values */
318+
319+ gtk_tree_store_insert_with_values (model, &tree_iter, NULL, G_MAXINT,
320+ 0, _("Bookmarks"), 1, (gint64)-1, -1);
321+ gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo), &tree_iter);
322+
323+ current_parentid = -1;
324+ parent_iter = NULL;
325+ n = 1;
326+ while (g_list_first (folders))
327+ {
328+ gboolean something_done = FALSE;
329+ GList* list_iter = g_list_first (folders);
330+
331+ do
332+ {
333+ FolderEntry* folder = list_iter->data;
334+ const gchar* title = folder->title;
335+ gint64 id = folder->id;
336+ gint64 parentid = folder->parentid;
337+
338+ if (parentid != current_parentid) /* optimize case of sub-folders of the same parent */
339+ {
340+ if (!parentid)
341+ {
342+ /* folder's parent is the stree store root */
343+
344+ current_parentid = -1;
345+ parent_iter = NULL;
346+ }
347+ else if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &tree_iter))
348+ {
349+ if (midori_bookmark_folder_button_reach_parent (
350+ GTK_TREE_MODEL (model), &tree_iter, parentid))
351+ {
352+ /* folder's parent found in the tree store */
353+
354+ current_parentid = parentid;
355+ stock_parent_iter = tree_iter;
356+ parent_iter = &stock_parent_iter;
357+ }
358+ else
359+ {
360+ /* folder's parent not found, skip it */
361+
362+ list_iter = g_list_next (list_iter);
363+ continue;
364+ }
365+ }
366+ else
367+ g_assert_not_reached ();
368+ }
369+
370+ /* insert folder in the tree store and remove it from the folders list */
371+
372+ gtk_tree_store_insert_with_values (model, &tree_iter, parent_iter, G_MAXINT,
373+ 0, title, 1, id, -1);
374+
375+ if (id == selected_parentid)
376+ gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo), &tree_iter);
377+
378+ n++;
379+
380+ something_done = TRUE;
381+
382+ g_free ((gpointer)title);
383+ folders = g_list_delete_link (folders, list_iter);
384+
385+ list_iter = g_list_first (folders);
386+ }
387+ while (list_iter);
388+
389+ if (!something_done) /* avoid infinite loop in case of orphan folders */
390+ break;
391+ }
392+
393+ if (g_list_first (folders))
394+ {
395+ GList* iter;
396+ g_printerr ("midori_bookmark_folder_button_new: orphan folder(s) detected in bookmarks db\n");
397+
398+ for (iter = g_list_first (folders) ; iter ; iter = g_list_next (iter))
399+ {
400+ FolderEntry* folder = iter->data;
401+ const gchar* title = folder->title;
402+ gint64 id = folder->id;
403+ gint64 parentid = folder->parentid;
404+
405+ g_printerr (" id=%" G_GINT64_FORMAT ", parentid=%" G_GINT64_FORMAT ", title=%s\n",
406+ id, parentid, title);
407+ }
408+
409+ g_list_free_full (folders, (GDestroyNotify)midori_bookmark_folder_free_folder_entry);
410+ }
411+
412+ if (n < 2)
413+ gtk_widget_set_sensitive (combo, FALSE);
414+
415+ return combo;
416+}
417
418=== modified file 'midori/midori-bookmarks-db.h'
419--- midori/midori-bookmarks-db.h 2015-07-06 21:26:46 +0000
420+++ midori/midori-bookmarks-db.h 2017-11-27 17:24:49 +0000
421@@ -75,5 +75,9 @@
422 midori_bookmarks_db_populate_folder (MidoriBookmarksDb* bookmarks,
423 KatzeArray *folder);
424
425+GtkWidget*
426+midori_bookmarks_db_folder_button_new (MidoriBookmarksDb* bookmarks,
427+ gint64 selected_parentid);
428+
429 #endif /* !__MIDORI_BOOKMARKS_DB_H__ */
430
431
432=== modified file 'midori/midori-browser.c'
433--- midori/midori-browser.c 2017-11-27 17:24:49 +0000
434+++ midori/midori-browser.c 2017-11-27 17:24:49 +0000
435@@ -289,8 +289,6 @@
436 midori_view_get_next_page (view) != NULL);
437
438 _action_set_sensitive (browser, "AddSpeedDial", !midori_view_is_blank (view));
439- _action_set_sensitive (browser, "BookmarkAdd", !midori_view_is_blank (view));
440- _action_set_sensitive (browser, "BookmarkFolderAdd", !midori_view_is_blank (view));
441 _action_set_sensitive (browser, "MailTo", !midori_view_is_blank (view));
442 _action_set_sensitive (browser, "SaveAs", midori_tab_can_save (MIDORI_TAB (view)));
443 _action_set_sensitive (browser, "ZoomIn", midori_view_can_zoom_in (view));
444@@ -818,220 +816,6 @@
445 }
446 }
447
448-static gboolean
449-midori_bookmark_folder_button_reach_parent (GtkTreeModel* model, GtkTreeIter *iter, gint64 parentid)
450-{
451- do
452- {
453- gint64 id;
454-
455- gtk_tree_model_get (model, iter, 1, &id, -1);
456-
457- if (parentid == id)
458- return TRUE;
459-
460- if (gtk_tree_model_iter_has_child (model, iter))
461- {
462- GtkTreeIter child;
463- gtk_tree_model_iter_children (model, &child, iter);
464- if (midori_bookmark_folder_button_reach_parent (model, &child, parentid))
465- {
466- *iter = child;
467- return TRUE;
468- }
469- }
470- }
471- while (gtk_tree_model_iter_next (model, iter));
472-
473- return FALSE;
474-}
475-
476-typedef struct _FolderEntry
477-{
478- const gchar *title;
479- gint64 id;
480- gint64 parentid;
481-} FolderEntry;
482-
483-static void
484-midori_bookmark_folder_free_folder_entry (FolderEntry* folder)
485-{
486- g_free ((gpointer)folder->title);
487-}
488-
489-static GtkWidget*
490-midori_bookmark_folder_button_new (MidoriBookmarksDb* array,
491- gint64 selected_parentid)
492-{
493- GtkTreeStore* model;
494- GtkWidget* combo;
495- GtkCellRenderer* renderer;
496- guint n;
497- sqlite3* db;
498- sqlite3_stmt* statement;
499- gint result;
500- const gchar* sqlcmd = "SELECT title, id, parentid FROM bookmarks WHERE uri='' ORDER BY parentid, title ASC";
501- gint64 current_parentid;
502- GtkTreeIter tree_iter;
503- GtkTreeIter stock_parent_iter;
504- GtkTreeIter* parent_iter;
505- GList *folders = NULL;
506-
507- db = g_object_get_data (G_OBJECT (array), "db");
508- g_return_val_if_fail (db != NULL, NULL);
509-
510- /* folder combo box model content:
511- ** 0: title
512- ** 1: id
513- */
514- model = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_INT64);
515- combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (model));
516-
517- /* setup combo layout
518- ** 0: a folder icon
519- ** 1: the folder name
520- */
521-
522- gtk_cell_layout_clear (GTK_CELL_LAYOUT (combo));
523-
524- renderer = gtk_cell_renderer_pixbuf_new ();
525- g_object_set (G_OBJECT (renderer),
526- "stock-id", GTK_STOCK_DIRECTORY,
527- "stock-size", GTK_ICON_SIZE_MENU,
528- NULL);
529- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, FALSE);
530-
531- renderer = katze_cell_renderer_combobox_text_new ();
532- g_object_set (G_OBJECT (renderer),
533- "width-chars", 40, /* FIXME: figure out a way to define an acceptable string length */
534- "ellipsize", PANGO_ELLIPSIZE_END,
535- "unfolded-text", _("Select [text]"),
536- NULL);
537- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
538- gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo), renderer, "text", 0);
539-
540- /* read the folders list from the database */
541- /* FIXME: this should be a service of midori/midori-bookmarks-db */
542-
543- if ((result = sqlite3_prepare_v2 (db, sqlcmd, -1, &statement, NULL)) == SQLITE_OK)
544- {
545- while ((result = sqlite3_step (statement)) == SQLITE_ROW)
546- {
547- FolderEntry* folder = g_new (FolderEntry, 1);
548-
549- folder->title = g_strdup ((const gchar*)sqlite3_column_text (statement, 0));
550- folder->id = sqlite3_column_int64 (statement, 1);
551- folder->parentid = sqlite3_column_int64 (statement, 2);
552-
553- folders = g_list_append (folders, folder);
554- }
555-
556- sqlite3_clear_bindings (statement);
557- sqlite3_reset (statement);
558- }
559-
560- /* populate the combo box */
561- /* FIXME: here we should have the root bookmark array's name and id, not hard encoded values */
562-
563- gtk_tree_store_insert_with_values (model, &tree_iter, NULL, G_MAXINT,
564- 0, _("Bookmarks"), 1, (gint64)-1, -1);
565- gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo), &tree_iter);
566-
567- current_parentid = -1;
568- parent_iter = NULL;
569- n = 1;
570- while (g_list_first (folders))
571- {
572- gboolean something_done = FALSE;
573- GList* list_iter = g_list_first (folders);
574-
575- do
576- {
577- FolderEntry* folder = list_iter->data;
578- const gchar* title = folder->title;
579- gint64 id = folder->id;
580- gint64 parentid = folder->parentid;
581-
582- if (parentid != current_parentid) /* optimize case of sub-folders of the same parent */
583- {
584- if (!parentid)
585- {
586- /* folder's parent is the stree store root */
587-
588- current_parentid = -1;
589- parent_iter = NULL;
590- }
591- else if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &tree_iter))
592- {
593- if (midori_bookmark_folder_button_reach_parent (
594- GTK_TREE_MODEL (model), &tree_iter, parentid))
595- {
596- /* folder's parent found in the tree store */
597-
598- current_parentid = parentid;
599- stock_parent_iter = tree_iter;
600- parent_iter = &stock_parent_iter;
601- }
602- else
603- {
604- /* folder's parent not found, skip it */
605-
606- list_iter = g_list_next (list_iter);
607- continue;
608- }
609- }
610- else
611- g_assert_not_reached ();
612- }
613-
614- /* insert folder in the tree store and remove it from the folders list */
615-
616- gtk_tree_store_insert_with_values (model, &tree_iter, parent_iter, G_MAXINT,
617- 0, title, 1, id, -1);
618-
619- if (id == selected_parentid)
620- gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo), &tree_iter);
621-
622- n++;
623-
624- something_done = TRUE;
625-
626- g_free ((gpointer)title);
627- folders = g_list_delete_link (folders, list_iter);
628-
629- list_iter = g_list_first (folders);
630- }
631- while (list_iter);
632-
633- if (!something_done) /* avoid infinite loop in case of orphan folders */
634- break;
635- }
636-
637- if (g_list_first (folders))
638- {
639- GList* iter;
640- g_printerr ("midori_bookmark_folder_button_new: orphan folder(s) detected in bookmarks db\n");
641-
642- for (iter = g_list_first (folders) ; iter ; iter = g_list_next (iter))
643- {
644- FolderEntry* folder = iter->data;
645- const gchar* title = folder->title;
646- gint64 id = folder->id;
647- gint64 parentid = folder->parentid;
648-
649- g_printerr (" id=%" G_GINT64_FORMAT ", parentid=%" G_GINT64_FORMAT ", title=%s\n",
650- id, parentid, title);
651- }
652-
653- g_list_free_full (folders, (GDestroyNotify)midori_bookmark_folder_free_folder_entry);
654- }
655-
656- if (n < 2)
657- gtk_widget_set_sensitive (combo, FALSE);
658-
659- return combo;
660-}
661-
662 static gint64
663 midori_bookmark_folder_button_get_active (GtkWidget* combo)
664 {
665@@ -1049,76 +833,6 @@
666 return id;
667 }
668
669-static void
670-midori_browser_edit_bookmark_title_changed_cb (GtkEntry* entry,
671- GtkWidget* button)
672-{
673- const gchar* title = gtk_entry_get_text (entry);
674- gtk_widget_set_sensitive (button,
675- title != NULL && title[0] != '\0');
676-}
677-
678-static void
679-midori_browser_edit_bookmark_response_cb (GtkWidget* dialog,
680- gint response,
681- MidoriBrowser* browser)
682-{
683- if (response == GTK_RESPONSE_ACCEPT)
684- {
685- KatzeItem* bookmark = g_object_get_data (G_OBJECT (dialog), "bookmark");
686- GtkWidget* entry_title = g_object_get_data (G_OBJECT (dialog), "entry-title");
687- katze_item_set_name (bookmark,
688- gtk_entry_get_text (GTK_ENTRY (entry_title)));
689- GtkWidget* check_toolbar = g_object_get_data (G_OBJECT (dialog), "check-toolbar");
690- katze_item_set_meta_integer (bookmark, "toolbar",
691- gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check_toolbar)));
692- GtkWidget* entry_uri = g_object_get_data (G_OBJECT (dialog), "entry-uri");
693- if (!KATZE_IS_ARRAY (bookmark))
694- katze_item_set_uri (bookmark,
695- gtk_entry_get_text (GTK_ENTRY (entry_uri)));
696-
697- GtkWidget* combo_folder = g_object_get_data (G_OBJECT (dialog), "combo-folder");
698- gint64 selected = midori_bookmark_folder_button_get_active (combo_folder);
699- katze_item_set_meta_integer (bookmark, "parentid", selected);
700-
701- gboolean new_bookmark = g_object_get_data (G_OBJECT (dialog), "new-bookmark") != NULL;
702- if (new_bookmark)
703- midori_bookmarks_db_add_item (browser->bookmarks, bookmark);
704- else
705- midori_bookmarks_db_update_item (browser->bookmarks, bookmark);
706- }
707- gtk_widget_destroy (dialog);
708-}
709-
710-static void
711-midori_browser_edit_bookmark_add_speed_dial_cb (GtkWidget* button,
712- KatzeItem* bookmark)
713-{
714- MidoriBrowser* browser = midori_browser_get_for_widget (button);
715- midori_browser_add_speed_dial (browser);
716- GtkWidget* dialog = gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER);
717- midori_browser_edit_bookmark_response_cb (dialog, GTK_RESPONSE_DELETE_EVENT, browser);
718-}
719-
720-static void
721-midori_browser_edit_bookmark_create_launcher_cb (GtkWidget* button,
722- KatzeItem* bookmark)
723-{
724- MidoriBrowser* browser = midori_browser_get_for_widget (button);
725- GtkAction* action = g_object_get_data (G_OBJECT (button), "midori-action");
726- gtk_action_activate (action);
727- GtkWidget* dialog = gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER);
728- midori_browser_edit_bookmark_response_cb (dialog, GTK_RESPONSE_DELETE_EVENT, browser);
729-}
730-
731-static void
732-midori_browser_edit_bookmark_button_cb (GtkWidget* button,
733- MidoriBrowser* browser)
734-{
735- GtkWidget* dialog = gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER);
736- midori_browser_edit_bookmark_response_cb (dialog, GTK_RESPONSE_ACCEPT, browser);
737-}
738-
739 /* Private function, used by MidoriBookmarks and MidoriHistory */
740 /* static */ gboolean
741 midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser,
742@@ -1127,144 +841,14 @@
743 gboolean is_folder,
744 GtkWidget* proxy)
745 {
746- KatzeItem* bookmark = bookmark_or_parent;
747- const gchar* title;
748- GtkWidget* dialog;
749- GtkWidget* accept;
750- GtkWidget* content_area;
751- GtkWidget* actions;
752- GtkWidget* view;
753- GtkWidget* vbox;
754- GtkWidget* hbox;
755- GtkWidget* label;
756- const gchar* value;
757- GtkWidget* entry_title;
758- GtkWidget* entry_uri;
759- GtkWidget* combo_folder;
760- GtkWidget* check_toolbar;
761- gboolean return_status = FALSE;
762-
763- if (is_folder)
764- title = new_bookmark ? _("New Folder") : _("Edit Folder");
765- else
766- title = new_bookmark ? _("New Bookmark") : _("Edit Bookmark");
767- if (proxy != NULL)
768- {
769- dialog = gtk_popover_new (proxy);
770- content_area = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
771- gtk_container_add (GTK_CONTAINER (dialog), content_area);
772- actions = gtk_hbox_new (FALSE, 6);
773- gtk_box_pack_end (GTK_BOX (content_area), actions, TRUE, TRUE, 0);
774- accept = gtk_button_new_from_stock (new_bookmark ? GTK_STOCK_ADD : GTK_STOCK_SAVE);
775- gtk_box_pack_end (GTK_BOX (actions), accept, FALSE, FALSE, 0);
776- g_signal_connect (accept, "clicked", G_CALLBACK (midori_browser_edit_bookmark_button_cb), browser);
777- }
778- else
779- {
780- dialog = gtk_dialog_new_with_buttons (title, GTK_WINDOW (browser),
781- GTK_DIALOG_DESTROY_WITH_PARENT, NULL, NULL);
782- content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
783- actions = gtk_hbox_new (FALSE, 0);
784- gtk_box_pack_end (GTK_BOX (content_area), actions, TRUE, TRUE, 0);
785- gtk_dialog_add_buttons (GTK_DIALOG (dialog),
786- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
787- new_bookmark ? GTK_STOCK_ADD : GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
788- gtk_window_set_icon_name (GTK_WINDOW (dialog),
789- new_bookmark ? GTK_STOCK_ADD : GTK_STOCK_REMOVE);
790- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
791- g_signal_connect (dialog, "response", G_CALLBACK (midori_browser_edit_bookmark_response_cb), browser);
792- accept = gtk_dialog_get_widget_for_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
793- }
794- gtk_container_set_border_width (GTK_CONTAINER (dialog), 12);
795-
796- if (!is_folder)
797- label = gtk_label_new (_("Type a name for this bookmark, and choose where to keep it."));
798- else
799- label = gtk_label_new (_("Type a name for this folder, and choose where to keep it."));
800-
801- vbox = gtk_vbox_new (FALSE, 6);
802- gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 6);
803- gtk_box_pack_start (GTK_BOX (content_area), vbox, FALSE, FALSE, 0);
804-
805- if (new_bookmark)
806- {
807- view = midori_browser_get_current_tab (browser);
808- if (is_folder)
809- {
810- bookmark = (KatzeItem*)katze_array_new (KATZE_TYPE_ARRAY);
811- katze_item_set_name (bookmark,
812- midori_view_get_display_title (MIDORI_VIEW (view)));
813- }
814- else
815- bookmark = g_object_new (KATZE_TYPE_ITEM,
816- "uri", midori_view_get_display_uri (MIDORI_VIEW (view)),
817- "name", midori_view_get_display_title (MIDORI_VIEW (view)), NULL);
818- katze_item_set_meta_integer (
819- bookmark, "parentid",
820- (!bookmark_or_parent
821- ? 0
822- : katze_item_get_meta_integer (bookmark_or_parent, "id")));
823- g_object_set_data (G_OBJECT (dialog), "new-bookmark", bookmark);
824- }
825- g_object_set_data_full (G_OBJECT (dialog), "bookmark", bookmark, (GDestroyNotify)g_object_unref);
826-
827- entry_title = gtk_entry_new ();
828- gtk_entry_set_activates_default (GTK_ENTRY (entry_title), TRUE);
829- value = katze_item_get_name (bookmark);
830- gtk_entry_set_text (GTK_ENTRY (entry_title), katze_str_non_null (value));
831- midori_browser_edit_bookmark_title_changed_cb (GTK_ENTRY (entry_title),
832- accept);
833- g_signal_connect (entry_title, "changed",
834- G_CALLBACK (midori_browser_edit_bookmark_title_changed_cb), accept);
835- gtk_box_pack_start (GTK_BOX (vbox), entry_title, FALSE, FALSE, 0);
836- g_object_set_data (G_OBJECT (dialog), "entry-title", entry_title);
837-
838- entry_uri = NULL;
839- if (!is_folder)
840- {
841- entry_uri = katze_uri_entry_new (accept);
842- gtk_entry_set_activates_default (GTK_ENTRY (entry_uri), TRUE);
843- gtk_entry_set_text (GTK_ENTRY (entry_uri), katze_item_get_uri (bookmark));
844- gtk_box_pack_start (GTK_BOX (vbox), entry_uri, FALSE, FALSE, 0);
845- g_object_set_data (G_OBJECT (dialog), "entry-uri", entry_uri);
846- }
847-
848- combo_folder = midori_bookmark_folder_button_new (browser->bookmarks,
849- katze_item_get_meta_integer (bookmark, "parentid"));
850- gtk_box_pack_start (GTK_BOX (vbox), combo_folder, FALSE, FALSE, 0);
851- g_object_set_data (G_OBJECT (dialog), "combo-folder", combo_folder);
852-
853- hbox = gtk_hbox_new (FALSE, 6);
854- gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
855- check_toolbar = gtk_check_button_new_with_mnemonic (_("Show in Bookmarks _Bar"));
856- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_toolbar),
857- katze_item_get_meta_boolean (bookmark, "toolbar"));
858- gtk_box_pack_start (GTK_BOX (hbox), check_toolbar, FALSE, FALSE, 0);
859- g_object_set_data (G_OBJECT (dialog), "check-toolbar", check_toolbar);
860-
861- if (new_bookmark && !is_folder)
862- {
863- label = gtk_button_new_with_mnemonic (_("Add to _Speed Dial"));
864- g_signal_connect (label, "clicked",
865- G_CALLBACK (midori_browser_edit_bookmark_add_speed_dial_cb), bookmark);
866- gtk_box_pack_start (GTK_BOX (actions), label, FALSE, FALSE, 0);
867-
868- /* FIXME: There's no API for extending the bookmark dialog */
869- GtkAction* action = _action_by_name (browser, "CreateLauncher");
870- if (action != NULL)
871- {
872- label = gtk_button_new_with_mnemonic (gtk_action_get_label (action));
873- g_object_set_data (G_OBJECT (label), "midori-action", action);
874- g_signal_connect (label, "clicked",
875- G_CALLBACK (midori_browser_edit_bookmark_create_launcher_cb), bookmark);
876- gtk_box_pack_start (GTK_BOX (actions), label, FALSE, FALSE, 0);
877- }
878- }
879-
880- gtk_widget_show_all (content_area);
881- gtk_widget_show (dialog);
882-
883- return return_status;
884+ GtkAction* action = _action_by_name (browser,
885+ new_bookmark ?
886+ (is_folder ? "BookmarkFolderAdd" : "BookmarkAdd") :
887+ (is_folder ? "BookmarkFolderEdit" : "BookmarkEdit"));
888+ g_object_set_data_full (G_OBJECT (action), "bookmark", bookmark_or_parent, (GDestroyNotify)g_object_unref);
889+ g_object_set_data (G_OBJECT (action), "proxy", proxy);
890+ gtk_action_activate (action);
891+ return FALSE;
892 }
893
894 static gboolean
895@@ -4276,25 +3860,6 @@
896 }
897
898 static void
899-_action_bookmark_add_activate (GtkAction* action,
900- MidoriBrowser* browser)
901-{
902- GtkWidget* proxy = NULL;
903- GSList* proxies = gtk_action_get_proxies (action);
904- for (; proxies != NULL; proxies = g_slist_next (proxies))
905- if (GTK_IS_TOOL_ITEM (proxies->data))
906- {
907- proxy = proxies->data;
908- break;
909- }
910-
911- if (g_str_equal (gtk_action_get_name (action), "BookmarkFolderAdd"))
912- midori_browser_edit_bookmark_dialog_new (browser, NULL, TRUE, TRUE, proxy);
913- else
914- midori_browser_edit_bookmark_dialog_new (browser, NULL, TRUE, FALSE, proxy);
915-}
916-
917-static void
918 _action_bookmarks_import_activate (GtkAction* action,
919 MidoriBrowser* browser)
920 {
921@@ -4423,7 +3988,7 @@
922 gtk_box_pack_start (GTK_BOX (hbox), combo, TRUE, TRUE, 0);
923 gtk_box_pack_start (GTK_BOX (content_area), hbox, FALSE, TRUE, 0);
924
925- combobox_folder = midori_bookmark_folder_button_new (browser->bookmarks, 0);
926+ combobox_folder = midori_bookmarks_db_folder_button_new (browser->bookmarks, 0);
927 gtk_box_pack_start (GTK_BOX (content_area), combobox_folder, FALSE, TRUE, 0);
928 gtk_widget_show_all (content_area);
929
930@@ -5198,10 +4763,16 @@
931
932 { "BookmarkAdd", STOCK_BOOKMARK_ADD,
933 NULL, "<Ctrl>d",
934- N_("Add a new bookmark"), G_CALLBACK (_action_bookmark_add_activate) },
935+ N_("Add a new bookmark"), NULL },
936 { "BookmarkFolderAdd", NULL,
937 N_("Add a new _folder"), "",
938- NULL, G_CALLBACK (_action_bookmark_add_activate) },
939+ NULL, NULL },
940+ { "BookmarkEdit", NULL,
941+ "Edit an existing bookmark", "",
942+ NULL, NULL },
943+ { "BookmarkFolderEdit", NULL,
944+ "Edit an existing folder", "",
945+ NULL, NULL },
946 { "BookmarksImport", NULL,
947 N_("_Import bookmarks…"), "",
948 NULL, G_CALLBACK (_action_bookmarks_import_activate) },
949@@ -5984,8 +5555,10 @@
950 _action_set_visible (browser, "LastSession", FALSE);
951
952 _action_set_visible (browser, "Bookmarks", browser->bookmarks != NULL);
953- _action_set_visible (browser, "BookmarkAdd", browser->bookmarks != NULL);
954- _action_set_visible (browser, "BookmarkFolderAdd", browser->bookmarks != NULL);
955+ _action_set_visible (browser, "BookmarkAdd", FALSE);
956+ _action_set_visible (browser, "BookmarkFolderAdd", FALSE);
957+ _action_set_visible (browser, "BookmarkEdit", FALSE);
958+ _action_set_visible (browser, "BookmarkFolderEdit", FALSE);
959 _action_set_visible (browser, "BookmarksImport", browser->bookmarks != NULL);
960 _action_set_visible (browser, "BookmarksExport", browser->bookmarks != NULL);
961 _action_set_visible (browser, "Bookmarkbar", FALSE);
962@@ -6427,8 +6000,6 @@
963 for (; proxies; proxies = g_slist_next (proxies))
964 gtk_widget_show (proxies->data);
965 }
966- _action_set_visible (browser, "BookmarkAdd", bookmarks != NULL);
967- _action_set_visible (browser, "BookmarkFolderAdd", bookmarks != NULL);
968 _action_set_visible (browser, "BookmarksImport", bookmarks != NULL);
969 _action_set_visible (browser, "BookmarksExport", bookmarks != NULL);
970
971
972=== modified file 'midori/midori.vapi'
973--- midori/midori.vapi 2017-11-27 17:24:49 +0000
974+++ midori/midori.vapi 2017-11-27 17:24:49 +0000
975@@ -24,7 +24,11 @@
976
977 [CCode (type_id = "TYPE_MIDORI_BOOKMARKS_DB", cheader_filename = "midori/midori-bookmarks-db.h")]
978 public class BookmarksDb : Katze.Array {
979+ public void add_item (Katze.Item item);
980+ public void update_item (Katze.Item item);
981+ public void remove_item (Katze.Item item);
982 public Katze.Array? query_recursive (string fields, string condition, string? value, bool recursive);
983+ public unowned Gtk.ComboBox folder_button_new (int64 parent_id);
984 }
985
986 [CCode (cheader_filename = "midori/midori-array.h")]
987@@ -109,6 +113,8 @@
988 public Katze.Array? history { owned get; set; }
989 [NoAccessorMethod]
990 public bool show_tabs { get; set; }
991+ [NoAccessorMethod]
992+ public Midori.SpeedDial? speed_dial { owned get; set; }
993
994 public signal Browser new_window (Browser? browser);
995 [HasEmitter]
996
997=== modified file 'panels/midori-bookmarks.c'
998--- panels/midori-bookmarks.c 2015-08-10 00:31:37 +0000
999+++ panels/midori-bookmarks.c 2017-11-27 17:24:49 +0000
1000@@ -605,7 +605,7 @@
1001
1002 browser = midori_browser_get_for_widget (bookmarks->treeview);
1003 midori_browser_edit_bookmark_dialog_new (
1004- browser, item, FALSE, KATZE_ITEM_IS_FOLDER (item), NULL);
1005+ browser, item, FALSE, KATZE_ITEM_IS_FOLDER (item), bookmarks->treeview);
1006
1007 g_object_unref (item);
1008 }
1009
1010=== modified file 'panels/midori-history.c'
1011--- panels/midori-history.c 2015-08-10 00:11:32 +0000
1012+++ panels/midori-history.c 2017-11-27 17:24:49 +0000
1013@@ -326,7 +326,7 @@
1014 GtkTreeIter iter;
1015 KatzeItem* item = NULL;
1016
1017- GtkWidget* proxy = GTK_IS_TOOL_ITEM (menuitem) ? menuitem : NULL;
1018+ GtkWidget* proxy = GTK_IS_TOOL_ITEM (menuitem) ? menuitem : history->treeview;
1019 MidoriBrowser* browser = midori_browser_get_for_widget (GTK_WIDGET (history));
1020 if (katze_tree_view_get_selected_iter (GTK_TREE_VIEW (history->treeview),
1021 &model, &iter))

Subscribers

People subscribed via source and target branches

to all changes: