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
=== modified file 'midori/midori-array.c'
--- midori/midori-array.c 2013-04-16 23:16:24 +0000
+++ midori/midori-array.c 2013-06-02 13:38:27 +0000
@@ -1194,3 +1194,153 @@
1194 return midori_array_query_recursive (bookmarks, fields, condition, value, FALSE);1194 return midori_array_query_recursive (bookmarks, fields, condition, value, FALSE);
1195}1195}
11961196
1197static gint64
1198count_from_sqlite (sqlite3* db,
1199 const gchar* sqlcmd)
1200{
1201 gint64 count = -1;
1202 sqlite3_stmt* stmt;
1203 gint result;
1204
1205 result = sqlite3_prepare_v2 (db, sqlcmd, -1, &stmt, NULL);
1206 if (result != SQLITE_OK)
1207 return -1;
1208
1209 g_assert (sqlite3_column_count (stmt) == 1);
1210
1211 if ((result = sqlite3_step (stmt)) == SQLITE_ROW)
1212 count = sqlite3_column_int64(stmt, 0);
1213
1214 sqlite3_clear_bindings (stmt);
1215 sqlite3_reset (stmt);
1216
1217 return count;
1218}
1219
1220static gint64
1221midori_array_count_recursive_by_id (KatzeArray* bookmarks,
1222 const gchar* condition,
1223 const gchar* value,
1224 gint64 id,
1225 gboolean recursive)
1226{
1227 gint64 count = -1;
1228 sqlite3* db;
1229 gchar* sqlcmd;
1230 char* sqlcmd_value;
1231 sqlite3_stmt* stmt;
1232 gint result;
1233 GList* ids;
1234 GList* iter_ids;
1235
1236 g_return_val_if_fail (condition, -1);
1237 g_return_val_if_fail (KATZE_IS_ARRAY (bookmarks), -1);
1238 db = g_object_get_data (G_OBJECT (bookmarks), "db");
1239 g_return_val_if_fail (db != NULL, -1);
1240
1241 g_assert(!strstr("parentid", condition));
1242
1243 if (id > 0)
1244 sqlcmd = g_strdup_printf ("SELECT COUNT(*) FROM bookmarks "
1245 "WHERE parentid = %" G_GINT64_FORMAT " AND %s",
1246 id,
1247 condition);
1248 else
1249 sqlcmd = g_strdup_printf ("SELECT COUNT(*) FROM bookmarks "
1250 "WHERE parentid IS NULL AND %s ",
1251 condition);
1252
1253 if (strstr (condition, "%q"))
1254 {
1255 sqlcmd_value = sqlite3_mprintf (sqlcmd, value ? value : "");
1256 count = count_from_sqlite (db, sqlcmd_value);
1257 sqlite3_free (sqlcmd_value);
1258 }
1259 else
1260 count = count_from_sqlite (db, sqlcmd);
1261
1262 g_free (sqlcmd);
1263
1264 if (!recursive || (count < 0))
1265 return count;
1266
1267 ids = NULL;
1268
1269 if (id > 0)
1270 sqlcmd_value = sqlite3_mprintf (
1271 "SELECT id FROM bookmarks "
1272 "WHERE parentid = %" G_GINT64_FORMAT " AND uri = ''", id);
1273 else
1274 sqlcmd_value = sqlite3_mprintf (
1275 "SELECT id FROM bookmarks "
1276 "WHERE parentid IS NULL AND uri = ''");
1277
1278 if (sqlite3_prepare_v2 (db, sqlcmd_value, -1, &stmt, NULL) == SQLITE_OK)
1279 {
1280 g_assert (sqlite3_column_count (stmt) == 1);
1281
1282 if ((result = sqlite3_step (stmt)) == SQLITE_ROW)
1283 {
1284 gint64* pid = g_new (gint64, 1);
1285
1286 *pid = sqlite3_column_int64(stmt, 0);
1287 ids = g_list_append (ids, pid);
1288 }
1289
1290 sqlite3_clear_bindings (stmt);
1291 sqlite3_reset (stmt);
1292 }
1293
1294 sqlite3_free (sqlcmd_value);
1295
1296 iter_ids = ids;
1297 while (iter_ids)
1298 {
1299 gint64 sub_count = midori_array_count_recursive_by_id (bookmarks,
1300 condition,
1301 value,
1302 *(gint64*)(iter_ids->data),
1303 recursive);
1304
1305 if (sub_count < 0)
1306 {
1307 g_list_free_full (ids, g_free);
1308 return -1;
1309 }
1310
1311 count += sub_count;
1312 iter_ids = g_list_next (iter_ids);
1313 }
1314
1315 g_list_free_full (ids, g_free);
1316 return count;
1317}
1318
1319/**
1320 * midori_array_count_recursive:
1321 * @array: the main bookmark array
1322 * @condition: condition, like "folder = '%q'"
1323 * @value: a value to be inserted if @condition contains %q
1324 * @recursive: if %TRUE include children
1325 *
1326 * Return value: the number of elements on success, -1 otherwise
1327 *
1328 * Since: 0.5.2
1329 **/
1330gint64
1331midori_array_count_recursive (KatzeArray* bookmarks,
1332 const gchar* condition,
1333 const gchar* value,
1334 KatzeItem* folder,
1335 gboolean recursive)
1336{
1337 gint64 id = -1;
1338
1339 g_return_val_if_fail (!folder || KATZE_ITEM_IS_FOLDER (folder), -1);
1340
1341 id = folder ? katze_item_get_meta_integer (folder, "id") : 0;
1342
1343 return midori_array_count_recursive_by_id (bookmarks, condition,
1344 value, id,
1345 recursive);
1346}
11971347
=== modified file 'midori/midori-array.h'
--- midori/midori-array.h 2012-01-03 20:15:19 +0000
+++ midori/midori-array.h 2013-06-02 13:38:27 +0000
@@ -47,4 +47,11 @@
47katze_array_from_sqlite (sqlite3* db,47katze_array_from_sqlite (sqlite3* db,
48 const gchar* sqlcmd);48 const gchar* sqlcmd);
4949
50gint64
51midori_array_count_recursive (KatzeArray* bookmarks,
52 const gchar* condition,
53 const gchar* value,
54 KatzeItem* folder,
55 gboolean recursive);
56
50#endif /* !__MIDORI_ARRAY_H__ */57#endif /* !__MIDORI_ARRAY_H__ */
5158
=== modified file 'midori/midori-browser.c'
--- midori/midori-browser.c 2013-05-31 03:40:27 +0000
+++ midori/midori-browser.c 2013-06-02 13:38:27 +0000
@@ -4147,7 +4147,10 @@
4147 else if (!KATZE_IS_ARRAY (item) && strcmp (stock_id, GTK_STOCK_DELETE))4147 else if (!KATZE_IS_ARRAY (item) && strcmp (stock_id, GTK_STOCK_DELETE))
4148 gtk_widget_set_sensitive (menuitem, uri != NULL);4148 gtk_widget_set_sensitive (menuitem, uri != NULL);
4149 g_object_set_data (G_OBJECT (menuitem), "KatzeItem", item);4149 g_object_set_data (G_OBJECT (menuitem), "KatzeItem", item);
4150 g_signal_connect (menuitem, "activate", G_CALLBACK (callback), userdata);4150 if (callback)
4151 g_signal_connect (menuitem, "activate", G_CALLBACK (callback), userdata);
4152 else
4153 gtk_widget_set_sensitive (menuitem, FALSE);
4151 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);4154 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
4152 gtk_widget_show (menuitem);4155 gtk_widget_show (menuitem);
4153}4156}
@@ -4237,10 +4240,16 @@
4237 GtkWidget* menuitem;4240 GtkWidget* menuitem;
42384241
4239 menu = gtk_menu_new ();4242 menu = gtk_menu_new ();
4240 if (!katze_item_get_uri (item))4243 if (KATZE_ITEM_IS_FOLDER (item))
4244 {
4245 gint child_bookmarks_count = midori_array_count_recursive (browser->bookmarks,
4246 "uri <> ''", NULL, item, FALSE);
4247
4241 midori_browser_bookmark_popup_item (menu,4248 midori_browser_bookmark_popup_item (menu,
4242 STOCK_TAB_NEW, _("Open all in _Tabs"),4249 STOCK_TAB_NEW, _("Open all in _Tabs"), item,
4243 item, midori_browser_bookmark_open_in_tab_activate_cb, browser);4250 (!child_bookmarks_count ? NULL : midori_browser_bookmark_open_in_tab_activate_cb),
4251 browser);
4252 }
4244 else4253 else
4245 {4254 {
4246 midori_browser_bookmark_popup_item (menu, GTK_STOCK_OPEN, NULL,4255 midori_browser_bookmark_popup_item (menu, GTK_STOCK_OPEN, NULL,
@@ -4252,9 +4261,11 @@
4252 STOCK_WINDOW_NEW, _("Open in New _Window"),4261 STOCK_WINDOW_NEW, _("Open in New _Window"),
4253 item, midori_browser_bookmark_open_in_window_activate_cb, browser);4262 item, midori_browser_bookmark_open_in_window_activate_cb, browser);
4254 }4263 }
4264
4255 menuitem = gtk_separator_menu_item_new ();4265 menuitem = gtk_separator_menu_item_new ();
4256 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);4266 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
4257 gtk_widget_show (menuitem);4267 gtk_widget_show (menuitem);
4268
4258 midori_browser_bookmark_popup_item (menu, GTK_STOCK_EDIT, NULL,4269 midori_browser_bookmark_popup_item (menu, GTK_STOCK_EDIT, NULL,
4259 item, midori_browser_bookmark_edit_activate_cb, widget);4270 item, midori_browser_bookmark_edit_activate_cb, widget);
4260 midori_browser_bookmark_popup_item (menu, GTK_STOCK_DELETE, NULL,4271 midori_browser_bookmark_popup_item (menu, GTK_STOCK_DELETE, NULL,
42614272
=== modified file 'panels/midori-bookmarks.c'
--- panels/midori-bookmarks.c 2013-02-11 21:49:41 +0000
+++ panels/midori-bookmarks.c 2013-06-02 13:38:27 +0000
@@ -39,7 +39,6 @@
39struct _MidoriBookmarks39struct _MidoriBookmarks
40{40{
41 GtkVBox parent_instance;41 GtkVBox parent_instance;
42
43 GtkWidget* toolbar;42 GtkWidget* toolbar;
44 GtkWidget* edit;43 GtkWidget* edit;
45 GtkWidget* delete;44 GtkWidget* delete;
@@ -49,6 +48,8 @@
4948
50 gint filter_timeout;49 gint filter_timeout;
51 gchar* filter;50 gchar* filter;
51
52 KatzeItem* hovering_item;
52};53};
5354
54struct _MidoriBookmarksClass55struct _MidoriBookmarksClass
@@ -86,6 +87,9 @@
86 GParamSpec* pspec);87 GParamSpec* pspec);
8788
88static void89static void
90midori_bookmarks_statusbar_update (MidoriBookmarks *bookmarks);
91
92static void
89midori_bookmarks_class_init (MidoriBookmarksClass* class)93midori_bookmarks_class_init (MidoriBookmarksClass* class)
90{94{
91 GObjectClass* gobject_class;95 GObjectClass* gobject_class;
@@ -441,6 +445,109 @@
441 gtk_widget_set_sensitive (GTK_WIDGET (bookmarks->edit), selected);445 gtk_widget_set_sensitive (GTK_WIDGET (bookmarks->edit), selected);
442}446}
443447
448static gchar*
449midori_bookmarks_statusbar_bookmarks_str (gint count)
450{
451 if (!count)
452 return NULL;
453
454 /* i18n: [n] bookmark(s) */
455 return g_strdup_printf (ngettext ("%d bookmark", "%d bookmarks", count), count);
456}
457
458static gchar*
459midori_bookmarks_statusbar_subfolders_str (gint count)
460{
461 if (!count)
462 return NULL;
463
464 /* i18n: [n] subfolder(s) */
465 return g_strdup_printf (ngettext ("%d subfolder", "%d subfolders", count), count);
466}
467
468static void
469midori_bookmarks_statusbar_update (MidoriBookmarks *bookmarks)
470{
471 gchar* text = NULL;
472 GtkTreeModel* model;
473 GtkTreeIter iter;
474 gboolean selected;
475
476 if (bookmarks->hovering_item)
477 {
478 KatzeItem* item = bookmarks->hovering_item;
479
480 g_assert (!KATZE_ITEM_IS_SEPARATOR (item));
481
482 if (KATZE_ITEM_IS_FOLDER (item))
483 {
484 gint child_folders_count = midori_array_count_recursive (bookmarks->array,
485 "uri = ''", NULL, item, FALSE);
486 gint child_bookmarks_count = midori_array_count_recursive (bookmarks->array,
487 "uri <> ''", NULL, item, FALSE);
488 gchar* child_folders_str = midori_bookmarks_statusbar_subfolders_str (child_folders_count);
489 gchar* child_bookmarks_str = midori_bookmarks_statusbar_bookmarks_str (child_bookmarks_count);
490
491 if (!child_bookmarks_count && !child_folders_count)
492 /* i18n: empty folder */
493 text = g_strdup_printf (_("empty folder"));
494 else if (!child_bookmarks_count && (child_folders_count >= 1))
495 /* i18n: folder containing [[n] folder(s)] and no bookmark */
496 text = g_strdup_printf (_("folder containing %s and no bookmark"),
497 child_folders_str);
498 else if ((child_bookmarks_count >= 1) && !child_folders_count)
499 /* i18n: folder containing [[n] bookmark(s)] */
500 text = g_strdup_printf (_("folder containing %s"), child_bookmarks_str);
501 else if ((child_bookmarks_count >= 1) && (child_folders_count >= 1))
502 /* i18n: folder containing [[n] bookmark(s)] and [[n] folder(s)] */
503 text = g_strdup_printf (_("folder containing %s and %s"),
504 child_bookmarks_str, child_folders_str);
505
506 g_free (child_folders_str);
507 g_free (child_bookmarks_str);
508 }
509 else if (KATZE_ITEM_IS_BOOKMARK (item))
510 {
511 const gchar* uri = katze_item_get_uri (item);
512
513 /* i18n: bookmark leading to : [bookmark uri] */
514 text = g_strdup_printf (_("bookmark leading to : %s"), uri);
515 }
516 }
517 else
518 {
519 gint child_folders_count = midori_array_count_recursive (bookmarks->array,
520 "uri = ''", NULL, NULL, FALSE);
521 gint child_bookmarks_count = midori_array_count_recursive (bookmarks->array,
522 "uri <> ''", NULL, NULL, FALSE);
523 gchar* child_folders_str = midori_bookmarks_statusbar_subfolders_str (child_folders_count);
524 gchar* child_bookmarks_str = midori_bookmarks_statusbar_bookmarks_str (child_bookmarks_count);
525
526 if (!child_bookmarks_count && (child_folders_count >= 1))
527 /* i18n: [[n] folder(s)] and no bookmark */
528 text = g_strdup_printf (_("%s and no bookmark"),
529 child_folders_str);
530 else if ((child_bookmarks_count >= 1) && !child_folders_count)
531 text = g_strdup (child_bookmarks_str);
532 else if ((child_bookmarks_count >= 1) && (child_folders_count >= 1))
533 /* i18n: [[n] bookmark(s)] and [[n] folder(s)] */
534 text = g_strdup_printf (_("%s and %s"),
535 child_bookmarks_str, child_folders_str);
536
537 g_free (child_folders_str);
538 g_free (child_bookmarks_str);
539 }
540
541 if (text)
542 {
543 MidoriBrowser* browser = midori_browser_get_for_widget (bookmarks->treeview);
544
545 g_object_set (browser, "statusbar-text", text, NULL);
546
547 g_free(text);
548 }
549}
550
444gboolean551gboolean
445midori_bookmarks_update_item_db (sqlite3* db,552midori_bookmarks_update_item_db (sqlite3* db,
446 KatzeItem* item)553 KatzeItem* item)
@@ -547,6 +654,7 @@
547 gtk_widget_show (GTK_WIDGET (toolitem));654 gtk_widget_show (GTK_WIDGET (toolitem));
548 bookmarks->delete = GTK_WIDGET (toolitem);655 bookmarks->delete = GTK_WIDGET (toolitem);
549 midori_bookmarks_toolbar_update (bookmarks);656 midori_bookmarks_toolbar_update (bookmarks);
657 midori_bookmarks_statusbar_update (bookmarks);
550 toolitem = gtk_separator_tool_item_new ();658 toolitem = gtk_separator_tool_item_new ();
551 gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (toolitem), FALSE);659 gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (toolitem), FALSE);
552 gtk_tool_item_set_expand (toolitem, TRUE);660 gtk_tool_item_set_expand (toolitem, TRUE);
@@ -745,7 +853,10 @@
745 else if (!KATZE_ITEM_IS_FOLDER (item) && strcmp (stock_id, GTK_STOCK_DELETE))853 else if (!KATZE_ITEM_IS_FOLDER (item) && strcmp (stock_id, GTK_STOCK_DELETE))
746 gtk_widget_set_sensitive (menuitem, uri != NULL);854 gtk_widget_set_sensitive (menuitem, uri != NULL);
747 g_object_set_data (G_OBJECT (menuitem), "KatzeItem", item);855 g_object_set_data (G_OBJECT (menuitem), "KatzeItem", item);
748 g_signal_connect (menuitem, "activate", G_CALLBACK (callback), bookmarks);856 if (callback)
857 g_signal_connect (menuitem, "activate", G_CALLBACK (callback), bookmarks);
858 else
859 gtk_widget_set_sensitive (menuitem, FALSE);
749 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);860 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
750 gtk_widget_show (menuitem);861 gtk_widget_show (menuitem);
751}862}
@@ -831,9 +942,15 @@
831942
832 menu = gtk_menu_new ();943 menu = gtk_menu_new ();
833 if (KATZE_ITEM_IS_FOLDER (item))944 if (KATZE_ITEM_IS_FOLDER (item))
945 {
946 gint child_bookmarks_count = midori_array_count_recursive (bookmarks->array,
947 "uri <> ''", NULL, item, FALSE);
948
834 midori_bookmarks_popup_item (menu,949 midori_bookmarks_popup_item (menu,
835 STOCK_TAB_NEW, _("Open all in _Tabs"),950 STOCK_TAB_NEW, _("Open all in _Tabs"), item,
836 item, midori_bookmarks_open_in_tab_activate_cb, bookmarks);951 (!child_bookmarks_count ? NULL : midori_bookmarks_open_in_tab_activate_cb),
952 bookmarks);
953 }
837 else954 else
838 {955 {
839 midori_bookmarks_popup_item (menu, GTK_STOCK_OPEN, NULL,956 midori_bookmarks_popup_item (menu, GTK_STOCK_OPEN, NULL,
@@ -960,6 +1077,103 @@
960 midori_bookmarks_toolbar_update (bookmarks);1077 midori_bookmarks_toolbar_update (bookmarks);
961}1078}
9621079
1080static KatzeItem*
1081midori_bookmarks_get_item_at_pos (GtkTreeView *treeview,
1082 gint x, gint y)
1083{
1084 GtkTreeModel* model = gtk_tree_view_get_model (treeview);
1085 GtkTreePath* path;
1086 GtkTreeIter iter;
1087 KatzeItem* item;
1088
1089 gtk_tree_view_get_path_at_pos (treeview, x, y,
1090 &path, NULL, NULL, NULL);
1091
1092 if (!path)
1093 return NULL;
1094
1095 if (gtk_tree_model_get_iter (model, &iter, path))
1096 gtk_tree_model_get (model, &iter, 0, &item, -1);
1097
1098 gtk_tree_path_free (path);
1099
1100 return item;
1101}
1102
1103static gboolean
1104midori_bookmarks_enter_notify_event_cb (GtkTreeView *treeview,
1105 GdkEventCrossing *event,
1106 MidoriBookmarks *bookmarks)
1107{
1108 KatzeItem* item = midori_bookmarks_get_item_at_pos (treeview, event->x, event->y);
1109
1110 if (bookmarks->hovering_item)
1111 g_object_unref (bookmarks->hovering_item);
1112
1113 bookmarks->hovering_item = item;
1114
1115 midori_bookmarks_statusbar_update (bookmarks);
1116
1117 return FALSE;
1118}
1119
1120static gboolean
1121midori_bookmarks_motion_notify_event_cb (GtkTreeView *treeview,
1122 GdkEventMotion *event,
1123 MidoriBookmarks *bookmarks)
1124{
1125 gboolean item_changed;
1126 KatzeItem* item;
1127 gint x;
1128 gint y;
1129
1130 if (event->is_hint)
1131 gtk_widget_get_pointer (GTK_WIDGET (treeview), &x, &y);
1132 else
1133 {
1134 x = event->x;
1135 y = event->y;
1136 }
1137
1138 item = midori_bookmarks_get_item_at_pos (treeview, x, y);
1139
1140 item_changed = (bookmarks->hovering_item != item) ? TRUE : FALSE;
1141
1142 if (!item_changed)
1143 {
1144 if (item)
1145 g_object_unref (item);
1146 }
1147 else
1148 {
1149 if (bookmarks->hovering_item)
1150 g_object_unref (bookmarks->hovering_item);
1151
1152 bookmarks->hovering_item = item;
1153
1154 midori_bookmarks_statusbar_update (bookmarks);
1155 }
1156
1157 return FALSE;
1158}
1159
1160static gboolean
1161midori_bookmarks_leave_notify_event_cb (GtkTreeView *treeview,
1162 GdkEventCrossing *event,
1163 MidoriBookmarks *bookmarks)
1164{
1165 MidoriBrowser* browser = midori_browser_get_for_widget (bookmarks->treeview);
1166
1167 if (bookmarks->hovering_item)
1168 g_object_unref (bookmarks->hovering_item);
1169
1170 bookmarks->hovering_item = NULL;
1171
1172 g_object_set (browser, "statusbar-text", "", NULL);
1173
1174 return FALSE;
1175}
1176
963static gboolean1177static gboolean
964midori_bookmarks_filter_timeout_cb (gpointer data)1178midori_bookmarks_filter_timeout_cb (gpointer data)
965{1179{
@@ -1047,7 +1261,17 @@
1047 midori_bookmarks_row_expanded_cb, bookmarks,1261 midori_bookmarks_row_expanded_cb, bookmarks,
1048 "signal::row-collapsed",1262 "signal::row-collapsed",
1049 midori_bookmarks_row_collapsed_cb, bookmarks,1263 midori_bookmarks_row_collapsed_cb, bookmarks,
1264 "signal::enter-notify-event",
1265 midori_bookmarks_enter_notify_event_cb, bookmarks,
1266 "signal::motion-notify-event",
1267 midori_bookmarks_motion_notify_event_cb, bookmarks,
1268 "signal::leave-notify-event",
1269 midori_bookmarks_leave_notify_event_cb, bookmarks,
1050 NULL);1270 NULL);
1271 gtk_widget_add_events (GTK_WIDGET (treeview),
1272 GDK_POINTER_MOTION_MASK
1273 | GDK_POINTER_MOTION_HINT_MASK);
1274
1051 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));1275 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
1052 g_signal_connect_after (selection, "changed",1276 g_signal_connect_after (selection, "changed",
1053 G_CALLBACK (midori_bookmarks_selection_changed_cb),1277 G_CALLBACK (midori_bookmarks_selection_changed_cb),
@@ -1055,6 +1279,7 @@
1055 gtk_widget_show (treeview);1279 gtk_widget_show (treeview);
1056 gtk_box_pack_start (GTK_BOX (bookmarks), treeview, TRUE, TRUE, 0);1280 gtk_box_pack_start (GTK_BOX (bookmarks), treeview, TRUE, TRUE, 0);
1057 bookmarks->treeview = treeview;1281 bookmarks->treeview = treeview;
1282 bookmarks->hovering_item = NULL;
1058}1283}
10591284
1060static void1285static void
@@ -1064,5 +1289,6 @@
10641289
1065 if (bookmarks->app)1290 if (bookmarks->app)
1066 g_object_unref (bookmarks->app);1291 g_object_unref (bookmarks->app);
1292 if (bookmarks->hovering_item)
1293 g_object_unref (bookmarks->hovering_item);
1067}1294}
1068

Subscribers

People subscribed via source and target branches

to all changes: