Merge lp:~aauzi/midori/fix-1179624 into lp:midori

Proposed by André Auzi
Status: Superseded
Proposed branch: lp:~aauzi/midori/fix-1179624
Merge into: lp:midori
Diff against target: 624 lines (+454/-19)
5 files modified
katze/katze-item.c (+9/-3)
midori/midori-array.c (+150/-0)
midori/midori-array.h (+7/-0)
midori/midori-browser.c (+35/-7)
panels/midori-bookmarks.c (+253/-9)
To merge this branch: bzr merge lp:~aauzi/midori/fix-1179624
Reviewer Review Type Date Requested Status
Paweł Forysiuk Needs Fixing
Cris Dywan Needs Fixing
Review via email: mp+166606@code.launchpad.net

This proposal supersedes a proposal from 2013-05-21.

This proposal has been superseded by a proposal from 2013-05-31.

To post a comment you must log in.
Revision history for this message
Cris Dywan (kalikiana) wrote : Posted in a previous version of this proposal

385 + else if (!child_bookmarks_count && child_folders_count)
386 + text = g_strdup_printf(
387 + _("%s : folder, %d subfolders and no bookmark"),
388 + name, child_folders_count);

This should be done using ngettext, leaving gettext to figure out plural forms (there may be a dual form or other grammatical implications the code can't handle).

Is it necessary to implement midori_array_count_recursive using midori_array_query_recursive rather than asking SQlite to count rows? This seems a bit wasteful.

review: Needs Fixing
Revision history for this message
André Auzi (aauzi) wrote : Posted in a previous version of this proposal

> 385 + else if (!child_bookmarks_count && child_folders_count)
> 386 + text = g_strdup_printf(
> 387 + _("%s : folder, %d subfolders and no bookmark"),
> 388 + name, child_folders_count);
>
> This should be done using ngettext, leaving gettext to figure out plural forms
> (there may be a dual form or other grammatical implications the code can't
> handle).

Interesting. I was not aware of ngettext existence. I will give it a try.

> Is it necessary to implement midori_array_count_recursive using
> midori_array_query_recursive rather than asking SQlite to count rows? This
> seems a bit wasteful.

Well, the count within a folder is done using a COUNT(*) sql statement but SQLite does not implement recursive queries therefore I had to implement recursion within the code.

I nevertheless agree, midori_array_query_recursive was the easy path and this has to be changed.
Especially if we consider the fact that I not only retrieve the sub folder id but also its *uri* (!!!goof!!!)

This being noticed I still have doubts about the feature, initially I thought we could need to implement fancy stuff like giving the counts for the whole tree depth if the user press the 'alt' or 'ctrl' modifiers but the feedback I get with one child level actually suits my needs, I wonder if the need of such feature would come up one day.

If nobody needs it, it's the whole idea of recursion that's wasteful and we could just get rid of it and stick to one child level count which is achieved with a single SQL statement.

I wonder if it was the meaning of the remark?

Revision history for this message
Cris Dywan (kalikiana) wrote :

Thanks a lot for the updates! I think personally it's fine to do the counting this way, as usual I'd like Paweł's opinion on any bookmark UI changes.

Meanwhile "Open as Web A_pplication" was dropped as a pseudo-bookmark feature, please drop it here as well. Generel agreement is to leave this functionality to the web app extension.

There's also a merge conflict, you'll want to 'bzr merge lp:midori' to resolve it (see also the wiki).

Btw you can use "--fixes=lp:1179624" as an argument to "bzr commit" instead of in the message which makes a clickable link in the log and ensures closing of the bug once it's merged.

review: Needs Fixing
Revision history for this message
Paweł Forysiuk (tuxator) wrote :

Looks promising.

Please resolve conflicts and drop webapp code, it should slim the patch a bit
making it easier to read.

47 + text = g_strdup_printf(
448 + _("%s : folder, %s and %s"),
449 + name,
450 + child_bookmarks_str,
451 + child_folders_str);

Can you maybe "pack" such statements? I don't think this style is used in midori code and it
balloons the patch as well. I see it a couple of places.

+ text = g_strdup_printf(_("%s : folder, %s and %s"),
+ name, child_bookmarks_str, child_folders_str);

Something like this is still readable i think.

As for translatable strings it would be wise to add comments for translators there
/* i18n: some explanation */ Should help those reading the code as well.
Otherwise code looks good. Let's see again after update.

review: Needs Fixing
lp:~aauzi/midori/fix-1179624 updated
6172. By André Auzi

Take into account review remarks

6173. By André Auzi

Merge with lp:midori.

1 conflict solved:
 * remove of Open link as web application in link popup context menu

Revision history for this message
André Auzi (aauzi) wrote :

Thanks for the remarks.

Concerning the "web application" removal it was not clear to me if the status bar text and GTK_STOCK_EXECUTE icon use was to be removed as well. I just left them in the proposal so far.

In my opinion they should stay because it's the only remaining visual hint of the special behaviour of a click on such bookmarks.

Nevertheless it's your design decision, just let me know if I have to cleanup this part as well.

If not, a nice improvement, that's unfortunately not yet in my skills abilities, would be to use a combined icon made of the site's favicon and a "web application marker" (maybe a star or something like that...)

lp:~aauzi/midori/fix-1179624 updated
6174. By André Auzi

Fix potential memory leak in:

489 +static KatzeItem*
490 +midori_bookmarks_get_item_at_pos (GtkTreeView *treeview,
491 + gint x, gint y)
492 +{
493 + GtkTreeModel* model = gtk_tree_view_get_model (treeview);
494 + GtkTreePath* path;
495 + GtkTreeIter iter;
496 + KatzeItem* item;
497 +
498 + gtk_tree_view_get_path_at_pos (treeview, x, y,
499 + &path, NULL, NULL, NULL);
500 +
501 + if (!path)
502 + return NULL;
503 +
504 + if (!gtk_tree_model_get_iter (model, &iter, path))
505 + return NULL;
506 +
507 + gtk_tree_model_get (model, &iter, 0, &item, -1);
508 +
509 + gtk_tree_path_free (path); <= can leak if gtk_tree_model_get_iter returned FALSE
510 +
511 + return item;
512 +}

6175. By André Auzi

Complete remove of "app" related code

Take pfor's comments into account: texts simplifications and redundancy
reduced

6176. By André Auzi

Merge lp:midori

6177. By André Auzi

Remove change in midori_browser_bookmark_open_activate_cb

6178. By André Auzi

Change code style

6179. By André Auzi

merge lp:midori

6180. By André Auzi

Take into account review comments + merge lp:midori

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'katze/katze-item.c'
2--- katze/katze-item.c 2013-02-21 21:36:30 +0000
3+++ katze/katze-item.c 2013-05-31 18:42:28 +0000
4@@ -445,8 +445,13 @@
5
6 g_return_val_if_fail (KATZE_IS_ITEM (item), NULL);
7
8- if (widget && KATZE_ITEM_IS_FOLDER (item))
9- return gtk_widget_render_icon (widget, GTK_STOCK_DIRECTORY, GTK_ICON_SIZE_MENU, NULL);
10+ if (widget)
11+ {
12+ if (KATZE_ITEM_IS_FOLDER (item))
13+ return gtk_widget_render_icon (widget, GTK_STOCK_DIRECTORY, GTK_ICON_SIZE_MENU, NULL);
14+ if (KATZE_ITEM_IS_BOOKMARK (item) && katze_item_get_meta_boolean (item, "app"))
15+ return gtk_widget_render_icon (widget, GTK_STOCK_EXECUTE, GTK_ICON_SIZE_MENU, NULL);
16+ }
17 if ((pixbuf = midori_paths_get_icon (katze_item_get_icon (item), NULL)))
18 return pixbuf;
19 if ((pixbuf = midori_paths_get_icon (item->uri, widget)))
20@@ -526,7 +531,8 @@
21 gtk_widget_show (image);
22 if (pixbuf != NULL)
23 g_object_unref (pixbuf);
24- if (KATZE_ITEM_IS_FOLDER (item))
25+ if (KATZE_ITEM_IS_FOLDER (item)
26+ || (KATZE_ITEM_IS_BOOKMARK (item) && katze_item_get_meta_boolean (item, "app")))
27 return image;
28 g_object_set_data (G_OBJECT (image), "KatzeItem", g_object_ref (item));
29 g_signal_connect (image, "destroy",
30
31=== modified file 'midori/midori-array.c'
32--- midori/midori-array.c 2013-04-16 23:16:24 +0000
33+++ midori/midori-array.c 2013-05-31 18:42:28 +0000
34@@ -1194,3 +1194,153 @@
35 return midori_array_query_recursive (bookmarks, fields, condition, value, FALSE);
36 }
37
38+static gint64
39+count_from_sqlite (sqlite3* db,
40+ const gchar* sqlcmd)
41+{
42+ gint64 count = -1;
43+ sqlite3_stmt* stmt;
44+ gint result;
45+
46+ result = sqlite3_prepare_v2 (db, sqlcmd, -1, &stmt, NULL);
47+ if (result != SQLITE_OK)
48+ return -1;
49+
50+ g_assert (sqlite3_column_count (stmt) == 1);
51+
52+ if ((result = sqlite3_step (stmt)) == SQLITE_ROW)
53+ count = sqlite3_column_int64(stmt, 0);
54+
55+ sqlite3_clear_bindings (stmt);
56+ sqlite3_reset (stmt);
57+
58+ return count;
59+}
60+
61+static gint64
62+midori_array_count_recursive_by_id (KatzeArray* bookmarks,
63+ const gchar* condition,
64+ const gchar* value,
65+ gint64 id,
66+ gboolean recursive)
67+{
68+ gint64 count = -1;
69+ sqlite3* db;
70+ gchar* sqlcmd;
71+ char* sqlcmd_value;
72+ sqlite3_stmt* stmt;
73+ gint result;
74+ GList* ids;
75+ GList* iter_ids;
76+
77+ g_return_val_if_fail (condition, -1);
78+ g_return_val_if_fail (KATZE_IS_ARRAY (bookmarks), -1);
79+ db = g_object_get_data (G_OBJECT (bookmarks), "db");
80+ g_return_val_if_fail (db != NULL, -1);
81+
82+ g_assert(!strstr("parentid", condition));
83+
84+ if (id > 0)
85+ sqlcmd = g_strdup_printf ("SELECT COUNT(*) FROM bookmarks "
86+ "WHERE parentid = %" G_GINT64_FORMAT " AND %s",
87+ id,
88+ condition);
89+ else
90+ sqlcmd = g_strdup_printf ("SELECT COUNT(*) FROM bookmarks "
91+ "WHERE parentid IS NULL AND %s ",
92+ condition);
93+
94+ if (strstr (condition, "%q"))
95+ {
96+ sqlcmd_value = sqlite3_mprintf (sqlcmd, value ? value : "");
97+ count = count_from_sqlite (db, sqlcmd_value);
98+ sqlite3_free (sqlcmd_value);
99+ }
100+ else
101+ count = count_from_sqlite (db, sqlcmd);
102+
103+ g_free (sqlcmd);
104+
105+ if (!recursive || (count < 0))
106+ return count;
107+
108+ ids = NULL;
109+
110+ if (id > 0)
111+ sqlcmd_value = sqlite3_mprintf (
112+ "SELECT id FROM bookmarks "
113+ "WHERE parentid = %" G_GINT64_FORMAT " AND uri = ''", id);
114+ else
115+ sqlcmd_value = sqlite3_mprintf (
116+ "SELECT id FROM bookmarks "
117+ "WHERE parentid IS NULL AND uri = ''");
118+
119+ if (sqlite3_prepare_v2 (db, sqlcmd_value, -1, &stmt, NULL) == SQLITE_OK)
120+ {
121+ g_assert (sqlite3_column_count (stmt) == 1);
122+
123+ if ((result = sqlite3_step (stmt)) == SQLITE_ROW)
124+ {
125+ gint64* pid = g_new (gint64, 1);
126+
127+ *pid = sqlite3_column_int64(stmt, 0);
128+ ids = g_list_append (ids, pid);
129+ }
130+
131+ sqlite3_clear_bindings (stmt);
132+ sqlite3_reset (stmt);
133+ }
134+
135+ sqlite3_free (sqlcmd_value);
136+
137+ iter_ids = ids;
138+ while (iter_ids)
139+ {
140+ gint64 sub_count = midori_array_count_recursive_by_id (bookmarks,
141+ condition,
142+ value,
143+ *(gint64*)(iter_ids->data),
144+ recursive);
145+
146+ if (sub_count < 0)
147+ {
148+ g_list_free_full (ids, g_free);
149+ return -1;
150+ }
151+
152+ count += sub_count;
153+ iter_ids = g_list_next (iter_ids);
154+ }
155+
156+ g_list_free_full (ids, g_free);
157+ return count;
158+}
159+
160+/**
161+ * midori_array_count_recursive:
162+ * @array: the main bookmark array
163+ * @condition: condition, like "folder = '%q'"
164+ * @value: a value to be inserted if @condition contains %q
165+ * @recursive: if %TRUE include children
166+ *
167+ * Return value: the number of elements on success, -1 otherwise
168+ *
169+ * Since: 0.5.2
170+ **/
171+gint64
172+midori_array_count_recursive (KatzeArray* bookmarks,
173+ const gchar* condition,
174+ const gchar* value,
175+ KatzeItem* folder,
176+ gboolean recursive)
177+{
178+ gint64 id = -1;
179+
180+ g_return_val_if_fail (!folder || KATZE_ITEM_IS_FOLDER (folder), -1);
181+
182+ id = folder ? katze_item_get_meta_integer (folder, "id") : 0;
183+
184+ return midori_array_count_recursive_by_id (bookmarks, condition,
185+ value, id,
186+ recursive);
187+}
188
189=== modified file 'midori/midori-array.h'
190--- midori/midori-array.h 2012-01-03 20:15:19 +0000
191+++ midori/midori-array.h 2013-05-31 18:42:28 +0000
192@@ -47,4 +47,11 @@
193 katze_array_from_sqlite (sqlite3* db,
194 const gchar* sqlcmd);
195
196+gint64
197+midori_array_count_recursive (KatzeArray* bookmarks,
198+ const gchar* condition,
199+ const gchar* value,
200+ KatzeItem* folder,
201+ gboolean recursive);
202+
203 #endif /* !__MIDORI_ARRAY_H__ */
204
205=== modified file 'midori/midori-browser.c'
206--- midori/midori-browser.c 2013-05-31 03:40:27 +0000
207+++ midori/midori-browser.c 2013-05-31 18:42:28 +0000
208@@ -4147,7 +4147,10 @@
209 else if (!KATZE_IS_ARRAY (item) && strcmp (stock_id, GTK_STOCK_DELETE))
210 gtk_widget_set_sensitive (menuitem, uri != NULL);
211 g_object_set_data (G_OBJECT (menuitem), "KatzeItem", item);
212- g_signal_connect (menuitem, "activate", G_CALLBACK (callback), userdata);
213+ if (callback)
214+ g_signal_connect (menuitem, "activate", G_CALLBACK (callback), userdata);
215+ else
216+ gtk_widget_set_sensitive (menuitem, FALSE);
217 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
218 gtk_widget_show (menuitem);
219 }
220@@ -4156,8 +4159,22 @@
221 midori_browser_bookmark_open_activate_cb (GtkWidget* menuitem,
222 MidoriBrowser* browser)
223 {
224- KatzeItem* item = (KatzeItem*)g_object_get_data (G_OBJECT (menuitem), "KatzeItem");
225- midori_browser_open_bookmark (browser, item);
226+ KatzeItem* item;
227+ const gchar* uri;
228+
229+ item = (KatzeItem*)g_object_get_data (G_OBJECT (menuitem), "KatzeItem");
230+
231+ if ((uri = katze_item_get_uri (item)) && *uri)
232+ {
233+ gchar* uri_fixed = sokoke_magic_uri (uri, TRUE, FALSE);
234+ if (!uri_fixed)
235+ uri_fixed = g_strdup (uri);
236+
237+ midori_browser_set_current_uri (browser, uri_fixed);
238+ gtk_widget_grab_focus (midori_browser_get_current_tab (browser));
239+
240+ g_free (uri_fixed);
241+ }
242 }
243
244 static void
245@@ -4237,10 +4254,19 @@
246 GtkWidget* menuitem;
247
248 menu = gtk_menu_new ();
249- if (!katze_item_get_uri (item))
250- midori_browser_bookmark_popup_item (menu,
251- STOCK_TAB_NEW, _("Open all in _Tabs"),
252- item, midori_browser_bookmark_open_in_tab_activate_cb, browser);
253+ if (KATZE_ITEM_IS_FOLDER (item))
254+ {
255+ gint child_bookmarks_count = midori_array_count_recursive (browser->bookmarks,
256+ "uri <> ''", NULL, item, FALSE);
257+
258+ if (!child_bookmarks_count)
259+ midori_browser_bookmark_popup_item (menu,
260+ STOCK_TAB_NEW, _("Open all in _Tabs"), item, NULL, browser);
261+ else
262+ midori_browser_bookmark_popup_item (menu,
263+ STOCK_TAB_NEW, _("Open all in _Tabs"),
264+ item, midori_browser_bookmark_open_in_tab_activate_cb, browser);
265+ }
266 else
267 {
268 midori_browser_bookmark_popup_item (menu, GTK_STOCK_OPEN, NULL,
269@@ -4252,9 +4278,11 @@
270 STOCK_WINDOW_NEW, _("Open in New _Window"),
271 item, midori_browser_bookmark_open_in_window_activate_cb, browser);
272 }
273+
274 menuitem = gtk_separator_menu_item_new ();
275 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
276 gtk_widget_show (menuitem);
277+
278 midori_browser_bookmark_popup_item (menu, GTK_STOCK_EDIT, NULL,
279 item, midori_browser_bookmark_edit_activate_cb, widget);
280 midori_browser_bookmark_popup_item (menu, GTK_STOCK_DELETE, NULL,
281
282=== modified file 'panels/midori-bookmarks.c'
283--- panels/midori-bookmarks.c 2013-02-11 21:49:41 +0000
284+++ panels/midori-bookmarks.c 2013-05-31 18:42:28 +0000
285@@ -39,7 +39,6 @@
286 struct _MidoriBookmarks
287 {
288 GtkVBox parent_instance;
289-
290 GtkWidget* toolbar;
291 GtkWidget* edit;
292 GtkWidget* delete;
293@@ -49,6 +48,8 @@
294
295 gint filter_timeout;
296 gchar* filter;
297+
298+ KatzeItem* hovering_item;
299 };
300
301 struct _MidoriBookmarksClass
302@@ -86,6 +87,9 @@
303 GParamSpec* pspec);
304
305 static void
306+midori_bookmarks_statusbar_update (MidoriBookmarks *bookmarks);
307+
308+static void
309 midori_bookmarks_class_init (MidoriBookmarksClass* class)
310 {
311 GObjectClass* gobject_class;
312@@ -441,6 +445,121 @@
313 gtk_widget_set_sensitive (GTK_WIDGET (bookmarks->edit), selected);
314 }
315
316+static gchar*
317+midori_bookmarks_statusbar_bookmarks_str (gint count)
318+{
319+ if (!count)
320+ return NULL;
321+
322+ /* i18n: [n] bookmark(s) */
323+ return g_strdup_printf (ngettext ("%d bookmark", "%d bookmarks", count), count);
324+}
325+
326+static gchar*
327+midori_bookmarks_statusbar_subfolder_str (gint count)
328+{
329+ if (!count)
330+ return NULL;
331+
332+ /* i18n: [n] subfolder(s) */
333+ return g_strdup_printf (ngettext ("%d subfolder", "%d subfolders", count), count);
334+}
335+
336+static void
337+midori_bookmarks_statusbar_update (MidoriBookmarks *bookmarks)
338+{
339+ gchar* text = NULL;
340+ GtkTreeModel* model;
341+ GtkTreeIter iter;
342+ gboolean selected;
343+
344+ if (bookmarks->hovering_item)
345+ {
346+ KatzeItem* item = bookmarks->hovering_item;
347+ const gchar* name;
348+
349+ g_assert (!KATZE_ITEM_IS_SEPARATOR (item));
350+
351+ name = katze_item_get_name (item);
352+
353+ if (KATZE_ITEM_IS_FOLDER (item))
354+ {
355+ gint child_folders_count = midori_array_count_recursive (bookmarks->array,
356+ "uri = ''", NULL, item, FALSE);
357+ gint child_bookmarks_count = midori_array_count_recursive (bookmarks->array,
358+ "uri <> ''", NULL, item, FALSE);
359+ gchar* child_folders_str = midori_bookmarks_statusbar_subfolder_str (child_folders_count);
360+ gchar* child_bookmarks_str = midori_bookmarks_statusbar_bookmarks_str (child_bookmarks_count);
361+
362+ if (!child_bookmarks_count && !child_folders_count)
363+ /* i18n: [folder name] : empty folder */
364+ text = g_strdup_printf(_("%s : empty folder"), name);
365+ else if (!child_bookmarks_count && (child_folders_count >= 1))
366+ /* i18n: [folder name] : folder, [[n] folder(s)] and no bookmark */
367+ text = g_strdup_printf(_("%s : folder, %s and no bookmark"),
368+ name, child_folders_str);
369+ else if ((child_bookmarks_count >= 1) && !child_folders_count)
370+ /* i18n: [folder name] : folder, [[n] bookmark(s)] */
371+ text = g_strdup_printf(_("%s : folder, %s"),
372+ name, child_bookmarks_str);
373+ else if ((child_bookmarks_count >= 1) && (child_folders_count >= 1))
374+ /* i18n: [folder name] : folder, [[n] bookmark(s)] and [[n] folder(s)] */
375+ text = g_strdup_printf(_("%s : folder, %s and %s"),
376+ name, child_bookmarks_str, child_folders_str);
377+
378+ g_free (child_folders_str);
379+ g_free (child_bookmarks_str);
380+ }
381+ else if (KATZE_ITEM_IS_BOOKMARK (item))
382+ {
383+ const gchar* uri = katze_item_get_uri (item);
384+
385+ if (katze_item_get_meta_boolean (item, "app"))
386+ /* i18n: [bookmark name] : web application bookmark to : [bookmark uri] */
387+ text = g_strdup_printf (_("%s : web application bookmark to : %s"), name, uri);
388+ else
389+ /* i18n: [bookmark name] : bookmark to : [bookmark uri] */
390+ text = g_strdup_printf (_("%s : bookmark to : %s"), name, uri);
391+ }
392+ }
393+ else
394+ {
395+ gint child_folders_count = midori_array_count_recursive (bookmarks->array,
396+ "uri = ''", NULL, NULL, FALSE);
397+ gint child_bookmarks_count = midori_array_count_recursive (bookmarks->array,
398+ "uri <> ''", NULL, NULL, FALSE);
399+ gchar* child_folders_str = midori_bookmarks_statusbar_subfolder_str (child_folders_count);
400+ gchar* child_bookmarks_str = midori_bookmarks_statusbar_bookmarks_str (child_bookmarks_count);
401+
402+ if (!child_bookmarks_count && !child_folders_count)
403+ text = g_strdup_printf(_("Bookmarks : empty"));
404+ else if (!child_bookmarks_count && (child_folders_count >= 1))
405+ /* i18n: Bookmarks : [[n] folder(s)] and no bookmark */
406+ text = g_strdup_printf(_("Bookmarks : %s and no bookmark"),
407+ child_folders_str);
408+ else if ((child_bookmarks_count >= 1) && !child_folders_count)
409+ /* i18n: Bookmarks : [[n] bookmark(s)] */
410+ text = g_strdup_printf(_("Bookmarks : %s"),
411+ child_bookmarks_str);
412+ else if ((child_bookmarks_count >= 1) && (child_folders_count >= 1))
413+ /* i18n: Bookmarks : [[n] bookmark(s)] and [[n] folder(s)] */
414+ text = g_strdup_printf(_("Bookmarks : %s and %s"),
415+ child_bookmarks_str, child_folders_str);
416+
417+ g_free (child_folders_str);
418+ g_free (child_bookmarks_str);
419+ }
420+
421+ if (text)
422+ {
423+ MidoriBrowser* browser = midori_browser_get_for_widget (bookmarks->treeview);
424+
425+ g_object_set (browser, "statusbar-text", text, NULL);
426+
427+ g_free(text);
428+ }
429+}
430+
431 gboolean
432 midori_bookmarks_update_item_db (sqlite3* db,
433 KatzeItem* item)
434@@ -547,6 +666,7 @@
435 gtk_widget_show (GTK_WIDGET (toolitem));
436 bookmarks->delete = GTK_WIDGET (toolitem);
437 midori_bookmarks_toolbar_update (bookmarks);
438+ midori_bookmarks_statusbar_update (bookmarks);
439 toolitem = gtk_separator_tool_item_new ();
440 gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (toolitem), FALSE);
441 gtk_tool_item_set_expand (toolitem, TRUE);
442@@ -745,7 +865,10 @@
443 else if (!KATZE_ITEM_IS_FOLDER (item) && strcmp (stock_id, GTK_STOCK_DELETE))
444 gtk_widget_set_sensitive (menuitem, uri != NULL);
445 g_object_set_data (G_OBJECT (menuitem), "KatzeItem", item);
446- g_signal_connect (menuitem, "activate", G_CALLBACK (callback), bookmarks);
447+ if (callback)
448+ g_signal_connect (menuitem, "activate", G_CALLBACK (callback), bookmarks);
449+ else
450+ gtk_widget_set_sensitive (menuitem, FALSE);
451 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
452 gtk_widget_show (menuitem);
453 }
454@@ -831,14 +954,24 @@
455
456 menu = gtk_menu_new ();
457 if (KATZE_ITEM_IS_FOLDER (item))
458- midori_bookmarks_popup_item (menu,
459- STOCK_TAB_NEW, _("Open all in _Tabs"),
460- item, midori_bookmarks_open_in_tab_activate_cb, bookmarks);
461+ {
462+ gint child_bookmarks_count = midori_array_count_recursive (bookmarks->array,
463+ "uri <> ''", NULL, item, FALSE);
464+
465+ if (!child_bookmarks_count)
466+ midori_bookmarks_popup_item (menu,
467+ STOCK_TAB_NEW, _("Open all in _Tabs"),
468+ item, NULL, bookmarks);
469+ else
470+ midori_bookmarks_popup_item (menu,
471+ STOCK_TAB_NEW, _("Open all in _Tabs"),
472+ item, midori_bookmarks_open_in_tab_activate_cb, bookmarks);
473+ }
474 else
475 {
476- midori_bookmarks_popup_item (menu, GTK_STOCK_OPEN, NULL,
477- item, midori_bookmarks_open_activate_cb, bookmarks);
478- midori_bookmarks_popup_item (menu, STOCK_TAB_NEW, _("Open in New _Tab"),
479+ midori_bookmarks_popup_item (menu, GTK_STOCK_OPEN, NULL,
480+ item, midori_bookmarks_open_activate_cb, bookmarks);
481+ midori_bookmarks_popup_item (menu, STOCK_TAB_NEW, _("Open in New _Tab"),
482 item, midori_bookmarks_open_in_tab_activate_cb, bookmarks);
483 midori_bookmarks_popup_item (menu, STOCK_WINDOW_NEW, _("Open in New _Window"),
484 item, midori_bookmarks_open_in_window_activate_cb, bookmarks);
485@@ -960,6 +1093,105 @@
486 midori_bookmarks_toolbar_update (bookmarks);
487 }
488
489+static KatzeItem*
490+midori_bookmarks_get_item_at_pos (GtkTreeView *treeview,
491+ gint x, gint y)
492+{
493+ GtkTreeModel* model = gtk_tree_view_get_model (treeview);
494+ GtkTreePath* path;
495+ GtkTreeIter iter;
496+ KatzeItem* item;
497+
498+ gtk_tree_view_get_path_at_pos (treeview, x, y,
499+ &path, NULL, NULL, NULL);
500+
501+ if (!path)
502+ return NULL;
503+
504+ if (!gtk_tree_model_get_iter (model, &iter, path))
505+ return NULL;
506+
507+ gtk_tree_model_get (model, &iter, 0, &item, -1);
508+
509+ gtk_tree_path_free (path);
510+
511+ return item;
512+}
513+
514+static gboolean
515+midori_bookmarks_enter_notify_event_cb (GtkTreeView *treeview,
516+ GdkEventCrossing *event,
517+ MidoriBookmarks *bookmarks)
518+{
519+ KatzeItem* item = midori_bookmarks_get_item_at_pos (treeview, event->x, event->y);
520+
521+ if (bookmarks->hovering_item)
522+ g_object_unref (bookmarks->hovering_item);
523+
524+ bookmarks->hovering_item = item;
525+
526+ midori_bookmarks_statusbar_update (bookmarks);
527+
528+ return FALSE;
529+}
530+
531+static gboolean
532+midori_bookmarks_motion_notify_event_cb (GtkTreeView *treeview,
533+ GdkEventMotion *event,
534+ MidoriBookmarks *bookmarks)
535+{
536+ gboolean item_changed;
537+ KatzeItem* item;
538+ gint x;
539+ gint y;
540+
541+ if (event->is_hint)
542+ gtk_widget_get_pointer (GTK_WIDGET (treeview), &x, &y);
543+ else
544+ {
545+ x = event->x;
546+ y = event->y;
547+ }
548+
549+ item = midori_bookmarks_get_item_at_pos (treeview, x, y);
550+
551+ item_changed = (bookmarks->hovering_item != item) ? TRUE : FALSE;
552+
553+ if (!item_changed)
554+ {
555+ if (item)
556+ g_object_unref (item);
557+ }
558+ else
559+ {
560+ if (bookmarks->hovering_item)
561+ g_object_unref (bookmarks->hovering_item);
562+
563+ bookmarks->hovering_item = item;
564+
565+ midori_bookmarks_statusbar_update (bookmarks);
566+ }
567+
568+ return FALSE;
569+}
570+
571+static gboolean
572+midori_bookmarks_leave_notify_event_cb (GtkTreeView *treeview,
573+ GdkEventCrossing *event,
574+ MidoriBookmarks *bookmarks)
575+{
576+ MidoriBrowser* browser = midori_browser_get_for_widget (bookmarks->treeview);
577+
578+ if (bookmarks->hovering_item)
579+ g_object_unref (bookmarks->hovering_item);
580+
581+ bookmarks->hovering_item = NULL;
582+
583+ g_object_set (browser, "statusbar-text", "", NULL);
584+
585+ return FALSE;
586+}
587+
588 static gboolean
589 midori_bookmarks_filter_timeout_cb (gpointer data)
590 {
591@@ -1047,7 +1279,17 @@
592 midori_bookmarks_row_expanded_cb, bookmarks,
593 "signal::row-collapsed",
594 midori_bookmarks_row_collapsed_cb, bookmarks,
595+ "signal::enter-notify-event",
596+ midori_bookmarks_enter_notify_event_cb, bookmarks,
597+ "signal::motion-notify-event",
598+ midori_bookmarks_motion_notify_event_cb, bookmarks,
599+ "signal::leave-notify-event",
600+ midori_bookmarks_leave_notify_event_cb, bookmarks,
601 NULL);
602+ gtk_widget_add_events (GTK_WIDGET (treeview),
603+ GDK_POINTER_MOTION_MASK
604+ | GDK_POINTER_MOTION_HINT_MASK);
605+
606 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
607 g_signal_connect_after (selection, "changed",
608 G_CALLBACK (midori_bookmarks_selection_changed_cb),
609@@ -1055,6 +1297,7 @@
610 gtk_widget_show (treeview);
611 gtk_box_pack_start (GTK_BOX (bookmarks), treeview, TRUE, TRUE, 0);
612 bookmarks->treeview = treeview;
613+ bookmarks->hovering_item = NULL;
614 }
615
616 static void
617@@ -1064,5 +1307,6 @@
618
619 if (bookmarks->app)
620 g_object_unref (bookmarks->app);
621+ if (bookmarks->hovering_item)
622+ g_object_unref (bookmarks->hovering_item);
623 }
624-

Subscribers

People subscribed via source and target branches

to all changes: