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: 538 lines (+403/-9)
4 files modified
midori/midori-array.c (+150/-0)
midori/midori-array.h (+7/-0)
midori/midori-browser.c (+15/-4)
panels/midori-bookmarks.c (+231/-5)
To merge this branch: bzr merge lp:~aauzi/midori/fix-1179624
Reviewer Review Type Date Requested Status
Paweł Forysiuk Needs Fixing
Cris Dywan Pending
Review via email: mp+166878@code.launchpad.net

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

This proposal has been superseded by a proposal from 2013-06-02.

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 : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

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
Revision history for this message
André Auzi (aauzi) wrote : Posted in a previous version of this proposal

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...)

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

André, to clarify. I brought up the app handling because your patch extends it further. The change moving away from it I referred to is https://code.launchpad.net/~kalikiana/midori/dialoglauncher/+merge/166327 . It might be easiest to not modify that handling in this patch and keep it separate instead.

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

Ok I think I've understood.

App handling is going to be something completely different and refering to metadata "app" would produce an integration issue.

I get rid of it.

Thanks for clarifying.

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

comments from:
pfor: displaying title and uri feels kinda redundant to be fair, you see the same information in the panel
pfor: and i guess it depends on the bookmark and your monitor size but sometimes it will obscure the info
pfor: i would just do something like that
pfor: bookmark leading to: ...
pfor: webapp launching: ....
pfor: folder containing: ....
pfor: in statusbar you can have enabled statusbar features that would take some space, with text as such all "critical" info should be still visible
pfor: i would leave the webapp code out for now

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

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

8 + if (KATZE_ITEM_IS_FOLDER (item))
199 + {
200 + gint child_bookmarks_count = midori_array_count_recursive (browser->bookmarks,
201 + "uri <> ''", NULL, item, FALSE);
202 +
203 + if (!child_bookmarks_count)
204 + midori_browser_bookmark_popup_item (menu,
205 + STOCK_TAB_NEW, _("Open all in _Tabs"), item, NULL, browser);
206 + else
207 + midori_browser_bookmark_popup_item (menu,
208 + STOCK_TAB_NEW, _("Open all in _Tabs"),
209 + item, midori_browser_bookmark_open_in_tab_activate_cb, browser);
210 + }

This part looks a bit strange.

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

> 8 + if (KATZE_ITEM_IS_FOLDER (item))
> 199 + {
> 200 + gint child_bookmarks_count = midori_array_count_recursive
> (browser->bookmarks,
> 201 + "uri <> ''", NULL, item, FALSE);
> 202 +
> 203 + if (!child_bookmarks_count)
> 204 + midori_browser_bookmark_popup_item (menu,
> 205 + STOCK_TAB_NEW, _("Open all in _Tabs"), item, NULL,
> browser);
> 206 + else
> 207 + midori_browser_bookmark_popup_item (menu,
> 208 + STOCK_TAB_NEW, _("Open all in _Tabs"),
> 209 + item,
> midori_browser_bookmark_open_in_tab_activate_cb, browser);
> 210 + }
>
> This part looks a bit strange.

hmm, I guess it's the coding style that looks unfamiliar.

Maybe I could rewrite it this way:

   if (KATZE_ITEM_IS_FOLDER (item))
   {
       gint child_bookmarks_count = midori_array_count_recursive (browser->bookmarks,
           "uri <> ''", NULL, item, FALSE);

       midori_browser_bookmark_popup_item (menu,
           STOCK_TAB_NEW, _("Open all in _Tabs"), item,
           (!child_bookmarks_count ? NULL : midori_browser_bookmark_open_in_tab_activate_cb),
           browser);
    }

The intent is to make the menu item insensitive when the folder does not contain bookmarks as suggested in : http://elementaryos.org/docs/widget-concepts.

It's related to the following change in midori_browser_bookmark_popup_item :
182 - g_signal_connect (menuitem, "activate", G_CALLBACK (callback), userdata);
183 + if (callback)
184 + g_signal_connect (menuitem, "activate", G_CALLBACK (callback), userdata);
185 + else
186 + gtk_widget_set_sensitive (menuitem, FALSE);

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

Subscribers

People subscribed via source and target branches

to all changes: