Status: | Work in progress | ||||||||
---|---|---|---|---|---|---|---|---|---|
Proposed branch: | lp:~aauzi/midori/fix-894143 | ||||||||
Merge into: | lp:midori | ||||||||
Diff against target: |
3396 lines (+2255/-309) 10 files modified
katze/katze-array.c (+53/-2) katze/katze-arrayaction.c (+10/-0) katze/katze-utils.c (+90/-3) katze/katze-utils.h (+5/-0) midori/midori-array.c (+7/-0) midori/midori-bookmarks-db.c (+107/-15) midori/midori-bookmarks-db.h (+11/-9) midori/midori-browser.c (+11/-19) panels/midori-bookmarks.c (+1960/-260) tests/bookmarks.c (+1/-1) |
||||||||
To merge this branch: | bzr merge lp:~aauzi/midori/fix-894143 | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Midori Devs | Pending | ||
Review via email: mp+165249@code.launchpad.net |
Commit message
Description of the change
(For review: fix-1179200 is a prerequisite to fix-894143)
To post a comment you must log in.
lp:~aauzi/midori/fix-894143
updated
- 6340. By André Auzi
-
merge lp:midori after merge of fix-1179200-8
Unmerged revisions
- 6340. By André Auzi
-
merge lp:midori after merge of fix-1179200-8
- 6339. By André Auzi
-
Fix race condition in timestamp comparison
- 6338. By André Auzi
-
merge lp:midori
- 6337. By André Auzi
-
Fix Test #9 regression error
- 6336. By André Auzi
- 6335. By André Auzi
-
merge fix-xbel-
import- regression - 6334. By André Auzi
-
merge lp:midori
- 6333. By André Auzi
-
manage sort order in bookmarks test
- 6332. By André Auzi
-
merge lp:midori after insert of fix-1179200-4
- 6331. By André Auzi
-
Derivation of GtkTreeStore for DND drop destination control.
Inserts are delayed to handle move operations where move is actually an insert at destination, followed by a delete at the source and finally a row change callback.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'katze/katze-array.c' | |||
2 | --- katze/katze-array.c 2013-11-04 20:57:37 +0000 | |||
3 | +++ katze/katze-array.c 2014-01-30 21:24:26 +0000 | |||
4 | @@ -33,6 +33,15 @@ | |||
5 | 33 | GList* items; | 33 | GList* items; |
6 | 34 | }; | 34 | }; |
7 | 35 | 35 | ||
8 | 36 | enum | ||
9 | 37 | { | ||
10 | 38 | PROP_0, | ||
11 | 39 | |||
12 | 40 | PROP_TYPE, | ||
13 | 41 | |||
14 | 42 | N_PROPERTIES | ||
15 | 43 | }; | ||
16 | 44 | |||
17 | 36 | enum { | 45 | enum { |
18 | 37 | ADD_ITEM, | 46 | ADD_ITEM, |
19 | 38 | REMOVE_ITEM, | 47 | REMOVE_ITEM, |
20 | @@ -55,6 +64,17 @@ | |||
21 | 55 | { | 64 | { |
22 | 56 | g_object_set_data (G_OBJECT (array), "last-update", | 65 | g_object_set_data (G_OBJECT (array), "last-update", |
23 | 57 | GINT_TO_POINTER (time (NULL))); | 66 | GINT_TO_POINTER (time (NULL))); |
24 | 67 | /* #define DEBUG_UPDATE */ | ||
25 | 68 | #ifdef DEBUG_UPDATE | ||
26 | 69 | if (KATZE_IS_ITEM (array)) | ||
27 | 70 | { | ||
28 | 71 | const gchar *name = katze_item_get_name (KATZE_ITEM (array)); | ||
29 | 72 | if (name && *name) | ||
30 | 73 | { | ||
31 | 74 | g_print ("_katze_array_update: %s\n", name); | ||
32 | 75 | } | ||
33 | 76 | } | ||
34 | 77 | #endif | ||
35 | 58 | } | 78 | } |
36 | 59 | 79 | ||
37 | 60 | static void | 80 | static void |
38 | @@ -105,6 +125,27 @@ | |||
39 | 105 | } | 125 | } |
40 | 106 | 126 | ||
41 | 107 | static void | 127 | static void |
42 | 128 | _katze_array_set_property (GObject *object, | ||
43 | 129 | guint property_id, | ||
44 | 130 | const GValue *value, | ||
45 | 131 | GParamSpec *pspec) | ||
46 | 132 | { | ||
47 | 133 | KatzeArray *array = KATZE_ARRAY (object); | ||
48 | 134 | |||
49 | 135 | switch (property_id) | ||
50 | 136 | { | ||
51 | 137 | case PROP_TYPE: | ||
52 | 138 | array->priv->type = g_value_get_gtype (value); | ||
53 | 139 | break; | ||
54 | 140 | |||
55 | 141 | default: | ||
56 | 142 | /* We don't have any other property... */ | ||
57 | 143 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); | ||
58 | 144 | break; | ||
59 | 145 | } | ||
60 | 146 | } | ||
61 | 147 | |||
62 | 148 | static void | ||
63 | 108 | katze_array_class_init (KatzeArrayClass* class) | 149 | katze_array_class_init (KatzeArrayClass* class) |
64 | 109 | { | 150 | { |
65 | 110 | GObjectClass* gobject_class; | 151 | GObjectClass* gobject_class; |
66 | @@ -187,6 +228,7 @@ | |||
67 | 187 | 228 | ||
68 | 188 | gobject_class = G_OBJECT_CLASS (class); | 229 | gobject_class = G_OBJECT_CLASS (class); |
69 | 189 | gobject_class->finalize = katze_array_finalize; | 230 | gobject_class->finalize = katze_array_finalize; |
70 | 231 | gobject_class->set_property = _katze_array_set_property; | ||
71 | 190 | 232 | ||
72 | 191 | class->add_item = _katze_array_add_item; | 233 | class->add_item = _katze_array_add_item; |
73 | 192 | class->remove_item = _katze_array_remove_item; | 234 | class->remove_item = _katze_array_remove_item; |
74 | @@ -194,6 +236,16 @@ | |||
75 | 194 | class->clear = _katze_array_clear; | 236 | class->clear = _katze_array_clear; |
76 | 195 | class->update = _katze_array_update; | 237 | class->update = _katze_array_update; |
77 | 196 | 238 | ||
78 | 239 | |||
79 | 240 | g_object_class_install_property (gobject_class, | ||
80 | 241 | PROP_TYPE, | ||
81 | 242 | g_param_spec_gtype ( | ||
82 | 243 | "type", | ||
83 | 244 | "Type", | ||
84 | 245 | "The array item type", | ||
85 | 246 | G_TYPE_NONE, | ||
86 | 247 | G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY)); | ||
87 | 248 | |||
88 | 197 | g_type_class_add_private (class, sizeof (KatzeArrayPrivate)); | 249 | g_type_class_add_private (class, sizeof (KatzeArrayPrivate)); |
89 | 198 | } | 250 | } |
90 | 199 | 251 | ||
91 | @@ -238,8 +290,7 @@ | |||
92 | 238 | 290 | ||
93 | 239 | g_return_val_if_fail (g_type_is_a (type, G_TYPE_OBJECT), NULL); | 291 | g_return_val_if_fail (g_type_is_a (type, G_TYPE_OBJECT), NULL); |
94 | 240 | 292 | ||
97 | 241 | array = g_object_new (KATZE_TYPE_ARRAY, NULL); | 293 | array = g_object_new (KATZE_TYPE_ARRAY, "type", type, NULL); |
96 | 242 | array->priv->type = type; | ||
98 | 243 | 294 | ||
99 | 244 | return array; | 295 | return array; |
100 | 245 | } | 296 | } |
101 | 246 | 297 | ||
102 | === modified file 'katze/katze-arrayaction.c' | |||
103 | --- katze/katze-arrayaction.c 2012-12-16 18:40:00 +0000 | |||
104 | +++ katze/katze-arrayaction.c 2014-01-30 21:24:26 +0000 | |||
105 | @@ -767,12 +767,14 @@ | |||
106 | 767 | KatzeArray* array) | 767 | KatzeArray* array) |
107 | 768 | { | 768 | { |
108 | 769 | GSList* proxies; | 769 | GSList* proxies; |
109 | 770 | KatzeArray *old_array = NULL; | ||
110 | 770 | 771 | ||
111 | 771 | g_return_if_fail (KATZE_IS_ARRAY_ACTION (array_action)); | 772 | g_return_if_fail (KATZE_IS_ARRAY_ACTION (array_action)); |
112 | 772 | g_return_if_fail (!array || katze_array_is_a (array, KATZE_TYPE_ITEM)); | 773 | g_return_if_fail (!array || katze_array_is_a (array, KATZE_TYPE_ITEM)); |
113 | 773 | 774 | ||
114 | 774 | /* FIXME: Disconnect old array */ | 775 | /* FIXME: Disconnect old array */ |
115 | 775 | 776 | ||
116 | 777 | old_array = array_action->array; | ||
117 | 776 | if (array) | 778 | if (array) |
118 | 777 | g_object_ref (array); | 779 | g_object_ref (array); |
119 | 778 | katze_object_assign (array_action->array, array); | 780 | katze_object_assign (array_action->array, array); |
120 | @@ -793,7 +795,15 @@ | |||
121 | 793 | 795 | ||
122 | 794 | do | 796 | do |
123 | 795 | { | 797 | { |
124 | 798 | KatzeArray* item = g_object_get_data (G_OBJECT (proxies->data), "KatzeItem"); | ||
125 | 799 | |||
126 | 800 | if (item && (item == old_array)) | ||
127 | 801 | g_object_set_data (G_OBJECT (proxies->data), "KatzeItem", array); | ||
128 | 802 | |||
129 | 796 | gtk_widget_set_sensitive (proxies->data, array != NULL); | 803 | gtk_widget_set_sensitive (proxies->data, array != NULL); |
130 | 797 | } | 804 | } |
131 | 798 | while ((proxies = g_slist_next (proxies))); | 805 | while ((proxies = g_slist_next (proxies))); |
132 | 806 | |||
133 | 807 | if (array) | ||
134 | 808 | katze_array_update (KATZE_ARRAY (array)); | ||
135 | 799 | } | 809 | } |
136 | 800 | 810 | ||
137 | === modified file 'katze/katze-utils.c' | |||
138 | --- katze/katze-utils.c 2013-11-05 21:51:18 +0000 | |||
139 | +++ katze/katze-utils.c 2014-01-30 21:24:26 +0000 | |||
140 | @@ -1002,12 +1002,99 @@ | |||
141 | 1002 | 1002 | ||
142 | 1003 | g_return_val_if_fail (GTK_IS_TREE_VIEW (treeview), FALSE); | 1003 | g_return_val_if_fail (GTK_IS_TREE_VIEW (treeview), FALSE); |
143 | 1004 | 1004 | ||
147 | 1005 | if ((selection = gtk_tree_view_get_selection (treeview))) | 1005 | selection = gtk_tree_view_get_selection(treeview); |
148 | 1006 | if (gtk_tree_selection_get_selected (selection, model, iter)) | 1006 | |
149 | 1007 | return TRUE; | 1007 | switch (gtk_tree_selection_get_mode (selection)) |
150 | 1008 | { | ||
151 | 1009 | default: | ||
152 | 1010 | break; | ||
153 | 1011 | |||
154 | 1012 | case GTK_SELECTION_SINGLE: | ||
155 | 1013 | case GTK_SELECTION_BROWSE: | ||
156 | 1014 | if (gtk_tree_selection_get_selected (selection, model, iter)) | ||
157 | 1015 | return TRUE; | ||
158 | 1016 | break; | ||
159 | 1017 | |||
160 | 1018 | case GTK_SELECTION_MULTIPLE: | ||
161 | 1019 | if (gtk_tree_selection_count_selected_rows (selection) == 1) | ||
162 | 1020 | { | ||
163 | 1021 | GtkTreeModel *stock_model; | ||
164 | 1022 | GList *list = gtk_tree_selection_get_selected_rows (selection, &stock_model); | ||
165 | 1023 | |||
166 | 1024 | if (model) | ||
167 | 1025 | *model = stock_model; | ||
168 | 1026 | |||
169 | 1027 | if (list) | ||
170 | 1028 | { | ||
171 | 1029 | GtkTreePath *path = (GtkTreePath *)g_list_nth_data (list, 0); | ||
172 | 1030 | |||
173 | 1031 | if (path && (!iter || gtk_tree_model_get_iter (stock_model, iter, path))) | ||
174 | 1032 | { | ||
175 | 1033 | g_list_free_full(list, (GDestroyNotify) gtk_tree_path_free); | ||
176 | 1034 | return TRUE; | ||
177 | 1035 | } | ||
178 | 1036 | |||
179 | 1037 | g_list_free_full(list, (GDestroyNotify) gtk_tree_path_free); | ||
180 | 1038 | } | ||
181 | 1039 | } | ||
182 | 1040 | } | ||
183 | 1041 | |||
184 | 1008 | return FALSE; | 1042 | return FALSE; |
185 | 1009 | } | 1043 | } |
186 | 1010 | 1044 | ||
187 | 1045 | /** | ||
188 | 1046 | * katze_tree_view_get_selected_rows: | ||
189 | 1047 | * @treeview: a #GtkTreeView | ||
190 | 1048 | * @model: a pointer to store the #GtkTreeModel, or %NULL | ||
191 | 1049 | * @rows: a pointer to store the #GList of #GtkTreePath, or %NULL | ||
192 | 1050 | * | ||
193 | 1051 | * Determines whether there is a selection in @treeview | ||
194 | 1052 | * and sets the @rows to the current selection. | ||
195 | 1053 | * | ||
196 | 1054 | * If there is a selection and @model is not %NULL, it is | ||
197 | 1055 | * set to the model. If @model is %NULL, the @rows will be | ||
198 | 1056 | * set to %NULL. | ||
199 | 1057 | * | ||
200 | 1058 | * Either @model or @rows or both can be %NULL in which case | ||
201 | 1059 | * no value will be assigned in any case. | ||
202 | 1060 | * | ||
203 | 1061 | * When @rows is not %NULL it must be freed using: | ||
204 | 1062 | * g_list_free_full (list, (GDestroyNotify) gtk_tree_path_free); | ||
205 | 1063 | * | ||
206 | 1064 | * Return value: the count of selected rows | ||
207 | 1065 | * | ||
208 | 1066 | * Since: 0.4.7.aau.1 | ||
209 | 1067 | **/ | ||
210 | 1068 | |||
211 | 1069 | gint | ||
212 | 1070 | katze_tree_view_get_selected_rows (GtkTreeView* treeview, | ||
213 | 1071 | GtkTreeModel** model, | ||
214 | 1072 | GList** rows) | ||
215 | 1073 | { | ||
216 | 1074 | gint count; | ||
217 | 1075 | GtkTreeSelection* selection; | ||
218 | 1076 | |||
219 | 1077 | if (model) | ||
220 | 1078 | *model = NULL; | ||
221 | 1079 | if (rows) | ||
222 | 1080 | *rows = NULL; | ||
223 | 1081 | |||
224 | 1082 | g_return_val_if_fail (GTK_IS_TREE_VIEW (treeview), 0); | ||
225 | 1083 | |||
226 | 1084 | selection = gtk_tree_view_get_selection(treeview); | ||
227 | 1085 | |||
228 | 1086 | count = gtk_tree_selection_count_selected_rows (selection); | ||
229 | 1087 | if (count > 0) | ||
230 | 1088 | { | ||
231 | 1089 | if (model && rows) | ||
232 | 1090 | { | ||
233 | 1091 | *rows = gtk_tree_selection_get_selected_rows (selection, model); | ||
234 | 1092 | } | ||
235 | 1093 | } | ||
236 | 1094 | |||
237 | 1095 | return count; | ||
238 | 1096 | } | ||
239 | 1097 | |||
240 | 1011 | void | 1098 | void |
241 | 1012 | katze_bookmark_populate_tree_view (KatzeArray* array, | 1099 | katze_bookmark_populate_tree_view (KatzeArray* array, |
242 | 1013 | GtkTreeStore* model, | 1100 | GtkTreeStore* model, |
243 | 1014 | 1101 | ||
244 | === modified file 'katze/katze-utils.h' | |||
245 | --- katze/katze-utils.h 2013-04-16 22:10:56 +0000 | |||
246 | +++ katze/katze-utils.h 2014-01-30 21:24:26 +0000 | |||
247 | @@ -88,6 +88,11 @@ | |||
248 | 88 | GtkTreeModel** model, | 88 | GtkTreeModel** model, |
249 | 89 | GtkTreeIter* iter); | 89 | GtkTreeIter* iter); |
250 | 90 | 90 | ||
251 | 91 | gint | ||
252 | 92 | katze_tree_view_get_selected_rows (GtkTreeView* treeview, | ||
253 | 93 | GtkTreeModel** model, | ||
254 | 94 | GList** rows); | ||
255 | 95 | |||
256 | 91 | void | 96 | void |
257 | 92 | katze_bookmark_populate_tree_view (KatzeArray* array, | 97 | katze_bookmark_populate_tree_view (KatzeArray* array, |
258 | 93 | GtkTreeStore* model, | 98 | GtkTreeStore* model, |
259 | 94 | 99 | ||
260 | === modified file 'midori/midori-array.c' | |||
261 | --- midori/midori-array.c 2013-08-05 19:52:52 +0000 | |||
262 | +++ midori/midori-array.c 2014-01-30 21:24:26 +0000 | |||
263 | @@ -1031,9 +1031,16 @@ | |||
264 | 1031 | || g_str_equal (name, "last_visit") || g_str_equal (name, "visit_count") | 1031 | || g_str_equal (name, "last_visit") || g_str_equal (name, "visit_count") |
265 | 1032 | || g_str_equal (name, "pos_panel") || g_str_equal (name, "pos_bar")) | 1032 | || g_str_equal (name, "pos_panel") || g_str_equal (name, "pos_bar")) |
266 | 1033 | { | 1033 | { |
267 | 1034 | #if 0 | ||
268 | 1034 | gint value; | 1035 | gint value; |
269 | 1035 | value = sqlite3_column_int64 (stmt, column); | 1036 | value = sqlite3_column_int64 (stmt, column); |
270 | 1036 | katze_item_set_meta_integer (item, name, value); | 1037 | katze_item_set_meta_integer (item, name, value); |
271 | 1038 | #else | ||
272 | 1039 | /* use text to properly handle NULL values */ | ||
273 | 1040 | const unsigned char* text; | ||
274 | 1041 | text = sqlite3_column_text (stmt, column); | ||
275 | 1042 | katze_item_set_meta_string (item, name, (gchar*)text); | ||
276 | 1043 | #endif | ||
277 | 1037 | } | 1044 | } |
278 | 1038 | else if (g_str_equal (name, "desc")) | 1045 | else if (g_str_equal (name, "desc")) |
279 | 1039 | { | 1046 | { |
280 | 1040 | 1047 | ||
281 | === modified file 'midori/midori-bookmarks-db.c' | |||
282 | --- midori/midori-bookmarks-db.c 2014-01-24 23:04:05 +0000 | |||
283 | +++ midori/midori-bookmarks-db.c 2014-01-30 21:24:26 +0000 | |||
284 | @@ -181,14 +181,29 @@ | |||
285 | 181 | midori_bookmarks_db_get_item_parent (MidoriBookmarksDb* bookmarks, | 181 | midori_bookmarks_db_get_item_parent (MidoriBookmarksDb* bookmarks, |
286 | 182 | gpointer item) | 182 | gpointer item) |
287 | 183 | { | 183 | { |
288 | 184 | gint64 parentid = katze_item_get_meta_integer (KATZE_ITEM (item), "parentid"); | ||
289 | 185 | KatzeItem *search = katze_item_new (); | ||
290 | 184 | KatzeArray* parent; | 186 | KatzeArray* parent; |
297 | 185 | gint64 parentid; | 187 | |
298 | 186 | 188 | if (!parentid) | |
299 | 187 | parentid = katze_item_get_meta_integer (KATZE_ITEM (item), "parentid"); | 189 | { |
300 | 188 | 190 | parentid = katze_item_get_meta_integer (KATZE_ITEM (bookmarks), "id"); | |
301 | 189 | if (parentid == 0) | 191 | katze_item_set_meta_integer (KATZE_ITEM (item), "parentid", parentid); |
302 | 190 | { | 192 | } |
303 | 193 | |||
304 | 194 | katze_item_set_meta_integer(search, "id", parentid); | ||
305 | 195 | |||
306 | 196 | parent = KATZE_ARRAY (g_hash_table_lookup (bookmarks->all_items, search)); | ||
307 | 197 | |||
308 | 198 | g_object_unref (search); | ||
309 | 199 | |||
310 | 200 | if (!parent) | ||
311 | 201 | { | ||
312 | 202 | g_warning ("item parent not found\n"); | ||
313 | 203 | |||
314 | 191 | parent = KATZE_ARRAY (bookmarks); | 204 | parent = KATZE_ARRAY (bookmarks); |
315 | 205 | katze_item_set_meta_integer (KATZE_ITEM (item), "parentid", | ||
316 | 206 | katze_item_get_meta_integer (KATZE_ITEM (bookmarks), "id")); | ||
317 | 192 | } | 207 | } |
318 | 193 | else | 208 | else |
319 | 194 | { | 209 | { |
320 | @@ -267,7 +282,10 @@ | |||
321 | 267 | 282 | ||
322 | 268 | g_return_if_fail (parent); | 283 | g_return_if_fail (parent); |
323 | 269 | 284 | ||
325 | 270 | katze_array_update (parent); | 285 | if (IS_MIDORI_BOOKMARKS_DB (parent)) |
326 | 286 | KATZE_ARRAY_CLASS (midori_bookmarks_db_parent_class)->update (parent); | ||
327 | 287 | else | ||
328 | 288 | katze_array_update (parent); | ||
329 | 271 | } | 289 | } |
330 | 272 | 290 | ||
331 | 273 | /** | 291 | /** |
332 | @@ -479,7 +497,7 @@ | |||
333 | 479 | else if (old_parent && katze_item_get_meta_integer (old_parent, "id") > 0) | 497 | else if (old_parent && katze_item_get_meta_integer (old_parent, "id") > 0) |
334 | 480 | new_parentid = g_strdup_printf ("%" G_GINT64_FORMAT, katze_item_get_meta_integer (old_parent, "id")); | 498 | new_parentid = g_strdup_printf ("%" G_GINT64_FORMAT, katze_item_get_meta_integer (old_parent, "id")); |
335 | 481 | else | 499 | else |
337 | 482 | new_parentid = g_strdup_printf ("NULL"); | 500 | new_parentid = g_strdup ("NULL"); |
338 | 483 | 501 | ||
339 | 484 | sqlcmd = sqlite3_mprintf ( | 502 | sqlcmd = sqlite3_mprintf ( |
340 | 485 | "INSERT INTO bookmarks (id, parentid, title, uri, desc, toolbar, app) " | 503 | "INSERT INTO bookmarks (id, parentid, title, uri, desc, toolbar, app) " |
341 | @@ -557,7 +575,8 @@ | |||
342 | 557 | 575 | ||
343 | 558 | sqlcmd = sqlite3_mprintf ( | 576 | sqlcmd = sqlite3_mprintf ( |
344 | 559 | "UPDATE bookmarks SET " | 577 | "UPDATE bookmarks SET " |
346 | 560 | "parentid=%q, title='%q', uri='%q', desc='%q', toolbar=%d, app=%d " | 578 | "parentid=%q, title='%q', uri='%q', desc='%q', toolbar=%d, app=%d, " |
347 | 579 | "pos_bar=%d, pos_panel=%d " | ||
348 | 561 | "WHERE id = %q ;", | 580 | "WHERE id = %q ;", |
349 | 562 | parentid, | 581 | parentid, |
350 | 563 | katze_item_get_name (item), | 582 | katze_item_get_name (item), |
351 | @@ -565,6 +584,8 @@ | |||
352 | 565 | katze_str_non_null (katze_item_get_meta_string (item, "desc")), | 584 | katze_str_non_null (katze_item_get_meta_string (item, "desc")), |
353 | 566 | katze_item_get_meta_boolean (item, "toolbar"), | 585 | katze_item_get_meta_boolean (item, "toolbar"), |
354 | 567 | katze_item_get_meta_boolean (item, "app"), | 586 | katze_item_get_meta_boolean (item, "app"), |
355 | 587 | (gint)katze_item_get_meta_integer (item, "pos_bar"), | ||
356 | 588 | (gint)katze_item_get_meta_integer (item, "pos_panel"), | ||
357 | 568 | id); | 589 | id); |
358 | 569 | 590 | ||
359 | 570 | updated = TRUE; | 591 | updated = TRUE; |
360 | @@ -579,6 +600,14 @@ | |||
361 | 579 | g_free (parentid); | 600 | g_free (parentid); |
362 | 580 | g_free (id); | 601 | g_free (id); |
363 | 581 | 602 | ||
364 | 603 | #ifdef DEBUG_DB_UPDATE | ||
365 | 604 | g_print ("update:%s - parentid: %s, pos_bar:%d, pos_panel:%d\n", | ||
366 | 605 | katze_item_get_name (item), | ||
367 | 606 | parentid, | ||
368 | 607 | (gint)katze_item_get_meta_integer (item, "pos_bar"), | ||
369 | 608 | (gint)katze_item_get_meta_integer (item, "pos_panel")); | ||
370 | 609 | #endif | ||
371 | 610 | |||
372 | 582 | return updated; | 611 | return updated; |
373 | 583 | } | 612 | } |
374 | 584 | 613 | ||
375 | @@ -710,10 +739,10 @@ | |||
376 | 710 | g_return_val_if_fail (errmsg != NULL, NULL); | 739 | g_return_val_if_fail (errmsg != NULL, NULL); |
377 | 711 | 740 | ||
378 | 712 | database = midori_bookmarks_database_new (&error); | 741 | database = midori_bookmarks_database_new (&error); |
380 | 713 | 742 | ||
381 | 714 | if (error != NULL) | 743 | if (error != NULL) |
382 | 715 | { | 744 | { |
384 | 716 | *errmsg = g_strdup (error->message); | 745 | *errmsg = g_strdup (error->message); |
385 | 717 | g_error_free (error); | 746 | g_error_free (error); |
386 | 718 | return NULL; | 747 | return NULL; |
387 | 719 | } | 748 | } |
388 | @@ -724,7 +753,10 @@ | |||
389 | 724 | if (midori_debug ("bookmarks")) | 753 | if (midori_debug ("bookmarks")) |
390 | 725 | sqlite3_trace (db, midori_bookmarks_db_dbtracer, NULL); | 754 | sqlite3_trace (db, midori_bookmarks_db_dbtracer, NULL); |
391 | 726 | 755 | ||
393 | 727 | bookmarks = MIDORI_BOOKMARKS_DB (g_object_new (TYPE_MIDORI_BOOKMARKS_DB, NULL)); | 756 | bookmarks = MIDORI_BOOKMARKS_DB (g_object_new (TYPE_MIDORI_BOOKMARKS_DB, |
394 | 757 | "type", KATZE_TYPE_ITEM, | ||
395 | 758 | NULL)); | ||
396 | 759 | |||
397 | 728 | bookmarks->db = db; | 760 | bookmarks->db = db; |
398 | 729 | 761 | ||
399 | 730 | g_object_set_data (G_OBJECT (bookmarks), "db", db); | 762 | g_object_set_data (G_OBJECT (bookmarks), "db", db); |
400 | @@ -776,6 +808,7 @@ | |||
401 | 776 | katze_item_set_meta_integer (item, "parentid", parentid); | 808 | katze_item_set_meta_integer (item, "parentid", parentid); |
402 | 777 | midori_bookmarks_db_add_item (bookmarks, item); | 809 | midori_bookmarks_db_add_item (bookmarks, item); |
403 | 778 | } | 810 | } |
404 | 811 | |||
405 | 779 | g_list_free (list); | 812 | g_list_free (list); |
406 | 780 | } | 813 | } |
407 | 781 | 814 | ||
408 | @@ -859,7 +892,7 @@ | |||
409 | 859 | * @array: the main bookmark array | 892 | * @array: the main bookmark array |
410 | 860 | * @sqlcmd: the sqlcmd to execute | 893 | * @sqlcmd: the sqlcmd to execute |
411 | 861 | * | 894 | * |
413 | 862 | * Internal function that process the requested @sqlcmd. | 895 | * Internal function that processes the requested @sqlcmd. |
414 | 863 | * | 896 | * |
415 | 864 | * Return value: a #KatzeArray on success, %NULL otherwise | 897 | * Return value: a #KatzeArray on success, %NULL otherwise |
416 | 865 | **/ | 898 | **/ |
417 | @@ -885,6 +918,12 @@ | |||
418 | 885 | * @fields: comma separated list of fields | 918 | * @fields: comma separated list of fields |
419 | 886 | * @condition: condition, like "folder = '%q'" | 919 | * @condition: condition, like "folder = '%q'" |
420 | 887 | * @value: a value to be inserted if @condition contains %q | 920 | * @value: a value to be inserted if @condition contains %q |
421 | 921 | * @order: a value to be inserted in "ORDER BY" | ||
422 | 922 | * default order is : | ||
423 | 923 | * (uri='') ASC, title DESC | ||
424 | 924 | * @order is inserted before title. | ||
425 | 925 | * order then becomes : | ||
426 | 926 | * (uri='') ASC, @order title DESC | ||
427 | 888 | * @recursive: if %TRUE include children | 927 | * @recursive: if %TRUE include children |
428 | 889 | * | 928 | * |
429 | 890 | * Stores the result in a #KatzeArray. | 929 | * Stores the result in a #KatzeArray. |
430 | @@ -898,6 +937,7 @@ | |||
431 | 898 | const gchar* fields, | 937 | const gchar* fields, |
432 | 899 | const gchar* condition, | 938 | const gchar* condition, |
433 | 900 | const gchar* value, | 939 | const gchar* value, |
434 | 940 | const gchar* order, | ||
435 | 901 | gboolean recursive) | 941 | gboolean recursive) |
436 | 902 | { | 942 | { |
437 | 903 | gchar* sqlcmd; | 943 | gchar* sqlcmd; |
438 | @@ -911,7 +951,7 @@ | |||
439 | 911 | g_return_val_if_fail (condition, NULL); | 951 | g_return_val_if_fail (condition, NULL); |
440 | 912 | 952 | ||
441 | 913 | sqlcmd = g_strdup_printf ("SELECT %s FROM bookmarks WHERE %s " | 953 | sqlcmd = g_strdup_printf ("SELECT %s FROM bookmarks WHERE %s " |
443 | 914 | "ORDER BY (uri='') ASC, title DESC", fields, condition); | 954 | "ORDER BY (uri='') ASC, %s title DESC", fields, condition, order ? order : ""); |
444 | 915 | if (strstr (condition, "%q")) | 955 | if (strstr (condition, "%q")) |
445 | 916 | { | 956 | { |
446 | 917 | sqlcmd_value = sqlite3_mprintf (sqlcmd, value ? value : ""); | 957 | sqlcmd_value = sqlite3_mprintf (sqlcmd, value ? value : ""); |
447 | @@ -932,7 +972,7 @@ | |||
448 | 932 | gchar* parentid = g_strdup_printf ("%" G_GINT64_FORMAT, | 972 | gchar* parentid = g_strdup_printf ("%" G_GINT64_FORMAT, |
449 | 933 | katze_item_get_meta_integer (item, "id")); | 973 | katze_item_get_meta_integer (item, "id")); |
450 | 934 | KatzeArray* subarray = midori_bookmarks_db_query_recursive (bookmarks, | 974 | KatzeArray* subarray = midori_bookmarks_db_query_recursive (bookmarks, |
452 | 935 | fields, "parentid=%q", parentid, TRUE); | 975 | fields, "parentid=%q", parentid, order, TRUE); |
453 | 936 | KatzeItem* subitem; | 976 | KatzeItem* subitem; |
454 | 937 | GList* sublist; | 977 | GList* sublist; |
455 | 938 | 978 | ||
456 | @@ -1097,3 +1137,55 @@ | |||
457 | 1097 | value, id, | 1137 | value, id, |
458 | 1098 | recursive); | 1138 | recursive); |
459 | 1099 | } | 1139 | } |
460 | 1140 | |||
461 | 1141 | /** | ||
462 | 1142 | * midori_bookmarks_db_populate_folder: | ||
463 | 1143 | **/ | ||
464 | 1144 | |||
465 | 1145 | void | ||
466 | 1146 | midori_bookmarks_db_populate_folder (MidoriBookmarksDb* bookmarks, | ||
467 | 1147 | KatzeArray *folder) | ||
468 | 1148 | { | ||
469 | 1149 | const gchar* id = katze_item_get_meta_string (KATZE_ITEM (folder), "id"); | ||
470 | 1150 | const gchar *condition; | ||
471 | 1151 | KatzeArray* array; | ||
472 | 1152 | KatzeItem* item; | ||
473 | 1153 | GList* list; | ||
474 | 1154 | |||
475 | 1155 | if (id == NULL) | ||
476 | 1156 | { | ||
477 | 1157 | condition = "parentid is NULL"; | ||
478 | 1158 | } | ||
479 | 1159 | else | ||
480 | 1160 | { | ||
481 | 1161 | condition = "parentid = %q"; | ||
482 | 1162 | } | ||
483 | 1163 | |||
484 | 1164 | array = midori_bookmarks_db_query_recursive (bookmarks, | ||
485 | 1165 | "id, title, parentid, uri, app, pos_panel, pos_bar", condition, id, "pos_panel ASC,", FALSE); | ||
486 | 1166 | |||
487 | 1167 | if (IS_MIDORI_BOOKMARKS_DB (folder)) | ||
488 | 1168 | { | ||
489 | 1169 | KATZE_ARRAY_FOREACH_ITEM_L (item, folder, list) | ||
490 | 1170 | { | ||
491 | 1171 | KATZE_ARRAY_CLASS (midori_bookmarks_db_parent_class)->remove_item (folder, item); | ||
492 | 1172 | } | ||
493 | 1173 | |||
494 | 1174 | KATZE_ARRAY_FOREACH_ITEM_L (item, array, list) | ||
495 | 1175 | { | ||
496 | 1176 | KATZE_ARRAY_CLASS (midori_bookmarks_db_parent_class)->add_item (folder, item); | ||
497 | 1177 | } | ||
498 | 1178 | } | ||
499 | 1179 | else | ||
500 | 1180 | { | ||
501 | 1181 | katze_array_clear(folder); | ||
502 | 1182 | |||
503 | 1183 | KATZE_ARRAY_FOREACH_ITEM_L (item, array, list) | ||
504 | 1184 | { | ||
505 | 1185 | katze_array_add_item (folder, item); | ||
506 | 1186 | } | ||
507 | 1187 | } | ||
508 | 1188 | |||
509 | 1189 | g_object_unref (array); | ||
510 | 1190 | } | ||
511 | 1191 | |||
512 | 1100 | 1192 | ||
513 | === modified file 'midori/midori-bookmarks-db.h' | |||
514 | --- midori/midori-bookmarks-db.h 2013-09-17 19:34:23 +0000 | |||
515 | +++ midori/midori-bookmarks-db.h 2014-01-30 21:24:26 +0000 | |||
516 | @@ -62,19 +62,21 @@ | |||
517 | 62 | const gchar* fields, | 62 | const gchar* fields, |
518 | 63 | const gchar* condition, | 63 | const gchar* condition, |
519 | 64 | const gchar* value, | 64 | const gchar* value, |
520 | 65 | const gchar* order, | ||
521 | 65 | gboolean recursive); | 66 | gboolean recursive); |
522 | 66 | 67 | ||
523 | 67 | gint64 | 68 | gint64 |
524 | 68 | midori_bookmarks_db_count_recursive (MidoriBookmarksDb* bookmarks, | 69 | midori_bookmarks_db_count_recursive (MidoriBookmarksDb* bookmarks, |
526 | 69 | const gchar* condition, | 70 | const gchar* condition, |
527 | 70 | const gchar* value, | 71 | const gchar* value, |
535 | 71 | KatzeItem* folder, | 72 | KatzeItem* folder, |
536 | 72 | gboolean recursive); | 73 | gboolean recursive); |
537 | 73 | 74 | ||
538 | 74 | gint64 | 75 | void |
539 | 75 | midori_bookmarks_insert_item_db (sqlite3* db, | 76 | midori_bookmarks_db_on_quit (MidoriBookmarksDb* array); |
540 | 76 | KatzeItem* item, | 77 | |
541 | 77 | gint64 parentid); | 78 | void |
542 | 79 | midori_bookmarks_db_populate_folder (MidoriBookmarksDb* bookmarks, | ||
543 | 80 | KatzeArray *folder); | ||
544 | 78 | 81 | ||
545 | 79 | #endif /* !__MIDORI_BOOKMARKS_DB_H__ */ | 82 | #endif /* !__MIDORI_BOOKMARKS_DB_H__ */ |
546 | 80 | |||
547 | 81 | 83 | ||
548 | === modified file 'midori/midori-browser.c' | |||
549 | --- midori/midori-browser.c 2014-01-06 23:05:10 +0000 | |||
550 | +++ midori/midori-browser.c 2014-01-30 21:24:26 +0000 | |||
551 | @@ -1025,7 +1025,7 @@ | |||
552 | 1025 | static gint64 | 1025 | static gint64 |
553 | 1026 | midori_bookmark_folder_button_get_active (GtkWidget* combo) | 1026 | midori_bookmark_folder_button_get_active (GtkWidget* combo) |
554 | 1027 | { | 1027 | { |
556 | 1028 | gint64 id = 0; | 1028 | gint64 id = -1; |
557 | 1029 | GtkTreeIter iter; | 1029 | GtkTreeIter iter; |
558 | 1030 | 1030 | ||
559 | 1031 | g_return_val_if_fail (GTK_IS_COMBO_BOX (combo), 0); | 1031 | g_return_val_if_fail (GTK_IS_COMBO_BOX (combo), 0); |
560 | @@ -3107,29 +3107,17 @@ | |||
561 | 3107 | KatzeArray* folder, | 3107 | KatzeArray* folder, |
562 | 3108 | MidoriBrowser* browser) | 3108 | MidoriBrowser* browser) |
563 | 3109 | { | 3109 | { |
564 | 3110 | KatzeArray* bookmarks; | ||
565 | 3111 | const gchar* id = katze_item_get_meta_string (KATZE_ITEM (folder), "id"); | ||
566 | 3112 | gchar* condition; | ||
567 | 3113 | |||
568 | 3114 | if (browser->bookmarks == NULL) | 3110 | if (browser->bookmarks == NULL) |
569 | 3115 | return FALSE; | 3111 | return FALSE; |
570 | 3116 | 3112 | ||
580 | 3117 | if (id == NULL) | 3113 | midori_bookmarks_db_populate_folder (browser->bookmarks, folder); |
572 | 3118 | condition = "parentid is NULL"; | ||
573 | 3119 | else | ||
574 | 3120 | condition = "parentid = %q"; | ||
575 | 3121 | |||
576 | 3122 | bookmarks = midori_bookmarks_db_query_recursive (browser->bookmarks, | ||
577 | 3123 | "id, title, parentid, uri, app, pos_panel, pos_bar", condition, id, FALSE); | ||
578 | 3124 | if (!bookmarks) | ||
579 | 3125 | return FALSE; | ||
581 | 3126 | 3114 | ||
582 | 3127 | /* Clear items from dummy array here */ | 3115 | /* Clear items from dummy array here */ |
583 | 3128 | gtk_container_foreach (GTK_CONTAINER (menu), | 3116 | gtk_container_foreach (GTK_CONTAINER (menu), |
584 | 3129 | (GtkCallback)(gtk_widget_destroy), NULL); | 3117 | (GtkCallback)(gtk_widget_destroy), NULL); |
585 | 3130 | 3118 | ||
586 | 3131 | /* "Import Bookmarks" and "Export Bookmarks" at the top */ | 3119 | /* "Import Bookmarks" and "Export Bookmarks" at the top */ |
588 | 3132 | if (id == NULL) | 3120 | if (folder == KATZE_ARRAY (browser->bookmarks)) |
589 | 3133 | { | 3121 | { |
590 | 3134 | GtkWidget* menuitem; | 3122 | GtkWidget* menuitem; |
591 | 3135 | menuitem = gtk_action_create_menu_item (_action_by_name (browser, "BookmarksImport")); | 3123 | menuitem = gtk_action_create_menu_item (_action_by_name (browser, "BookmarksImport")); |
592 | @@ -3143,7 +3131,7 @@ | |||
593 | 3143 | gtk_widget_show (menuitem); | 3131 | gtk_widget_show (menuitem); |
594 | 3144 | } | 3132 | } |
595 | 3145 | 3133 | ||
597 | 3146 | if (katze_array_is_empty (bookmarks)) | 3134 | if (katze_array_is_empty (folder)) |
598 | 3147 | { | 3135 | { |
599 | 3148 | GtkWidget* menuitem = gtk_image_menu_item_new_with_label (_("Empty")); | 3136 | GtkWidget* menuitem = gtk_image_menu_item_new_with_label (_("Empty")); |
600 | 3149 | gtk_widget_set_sensitive (menuitem, FALSE); | 3137 | gtk_widget_set_sensitive (menuitem, FALSE); |
601 | @@ -3152,7 +3140,7 @@ | |||
602 | 3152 | return TRUE; | 3140 | return TRUE; |
603 | 3153 | } | 3141 | } |
604 | 3154 | 3142 | ||
606 | 3155 | katze_array_action_generate_menu (KATZE_ARRAY_ACTION (action), bookmarks, | 3143 | katze_array_action_generate_menu (KATZE_ARRAY_ACTION (action), folder, |
607 | 3156 | menu, GTK_WIDGET (browser)); | 3144 | menu, GTK_WIDGET (browser)); |
608 | 3157 | return TRUE; | 3145 | return TRUE; |
609 | 3158 | } | 3146 | } |
610 | @@ -4502,7 +4490,7 @@ | |||
611 | 4502 | 4490 | ||
612 | 4503 | error = NULL; | 4491 | error = NULL; |
613 | 4504 | bookmarks = midori_bookmarks_db_query_recursive (browser->bookmarks, | 4492 | bookmarks = midori_bookmarks_db_query_recursive (browser->bookmarks, |
615 | 4505 | "*", "parentid IS NULL", NULL, TRUE); | 4493 | "*", "parentid IS NULL", NULL, NULL, TRUE); |
616 | 4506 | if (!midori_array_to_file (bookmarks, path, format, &error)) | 4494 | if (!midori_array_to_file (bookmarks, path, format, &error)) |
617 | 4507 | { | 4495 | { |
618 | 4508 | sokoke_message_dialog (GTK_MESSAGE_ERROR, | 4496 | sokoke_message_dialog (GTK_MESSAGE_ERROR, |
619 | @@ -6702,7 +6690,7 @@ | |||
620 | 6702 | gtk_separator_tool_item_new (), -1); | 6690 | gtk_separator_tool_item_new (), -1); |
621 | 6703 | 6691 | ||
622 | 6704 | array = midori_bookmarks_db_query_recursive (browser->bookmarks, | 6692 | array = midori_bookmarks_db_query_recursive (browser->bookmarks, |
624 | 6705 | "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "toolbar = 1", NULL, FALSE); | 6693 | "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "toolbar = 1", NULL, "pos_bar ASC,", FALSE); |
625 | 6706 | if (!array) | 6694 | if (!array) |
626 | 6707 | { | 6695 | { |
627 | 6708 | _action_set_sensitive (browser, "BookmarkAdd", FALSE); | 6696 | _action_set_sensitive (browser, "BookmarkAdd", FALSE); |
628 | @@ -6756,6 +6744,10 @@ | |||
629 | 6756 | midori_bookmarkbar_remove_item_cb, browser); | 6744 | midori_bookmarkbar_remove_item_cb, browser); |
630 | 6757 | } | 6745 | } |
631 | 6758 | 6746 | ||
632 | 6747 | g_object_set (G_OBJECT (_action_by_name (browser, "Bookmarks")), | ||
633 | 6748 | "array", KATZE_ARRAY (bookmarks), | ||
634 | 6749 | NULL); | ||
635 | 6750 | |||
636 | 6759 | settings = midori_browser_get_settings (browser); | 6751 | settings = midori_browser_get_settings (browser); |
637 | 6760 | g_signal_handlers_disconnect_by_func (settings, | 6752 | g_signal_handlers_disconnect_by_func (settings, |
638 | 6761 | midori_browser_show_bookmarkbar_notify_value_cb, browser); | 6753 | midori_browser_show_bookmarkbar_notify_value_cb, browser); |
639 | 6762 | 6754 | ||
640 | === modified file 'panels/midori-bookmarks.c' | |||
641 | --- panels/midori-bookmarks.c 2014-01-24 23:04:05 +0000 | |||
642 | +++ panels/midori-bookmarks.c 2014-01-30 21:24:26 +0000 | |||
643 | @@ -26,6 +26,151 @@ | |||
644 | 26 | 26 | ||
645 | 27 | #define COMPLETION_DELAY 200 | 27 | #define COMPLETION_DELAY 200 |
646 | 28 | 28 | ||
647 | 29 | #define MIDORI_BOOKMARKS_TREE_MODEL_TARGET "GTK_TREE_MODEL_ROW" | ||
648 | 30 | |||
649 | 31 | G_BEGIN_DECLS | ||
650 | 32 | |||
651 | 33 | #define MIDORI_BOOKMARKS_TREE_STORE_TYPE \ | ||
652 | 34 | (midori_bookmarks_tree_store_get_type ()) | ||
653 | 35 | #define MIDORI_BOOKMARKS_TREE_STORE(obj) \ | ||
654 | 36 | (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_BOOKMARKS_TREE_STORE_TYPE, MidoriBookmarksTreeStore)) | ||
655 | 37 | #define MIDORI_BOOKMARKS_TREE_STORE_CLASS(klass) \ | ||
656 | 38 | (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_BOOKMARKS_TREE_STORE_TYPE, MidoriBookmarksTreeStoreClass)) | ||
657 | 39 | |||
658 | 40 | static gboolean | ||
659 | 41 | midori_bookmarks_tree_store_drag_data_get (GtkTreeDragSource* drag_source, | ||
660 | 42 | GtkTreePath* source_path, | ||
661 | 43 | GtkSelectionData* selection_data); | ||
662 | 44 | static gboolean | ||
663 | 45 | midori_bookmarks_tree_store_drag_data_delete (GtkTreeDragSource* drag_source, | ||
664 | 46 | GtkTreePath* source_path); | ||
665 | 47 | static gboolean | ||
666 | 48 | midori_bookmarks_tree_store_row_drop_possible (GtkTreeDragDest *drag_dest, | ||
667 | 49 | GtkTreePath *dest_path, | ||
668 | 50 | GtkSelectionData *selection_data); | ||
669 | 51 | static gboolean | ||
670 | 52 | midori_bookmarks_tree_store_drag_data_received (GtkTreeDragDest *drag_dest, | ||
671 | 53 | GtkTreePath *dest_path, | ||
672 | 54 | GtkSelectionData *selection_data); | ||
673 | 55 | |||
674 | 56 | typedef struct _MidoriBookmarksTreeStore MidoriBookmarksTreeStore; | ||
675 | 57 | typedef struct _MidoriBookmarksTreeStoreClass MidoriBookmarksTreeStoreClass; | ||
676 | 58 | typedef struct _TreeRowData TreeRowData; | ||
677 | 59 | |||
678 | 60 | struct _MidoriBookmarksTreeStore | ||
679 | 61 | { | ||
680 | 62 | GtkTreeStore parent_instance; | ||
681 | 63 | |||
682 | 64 | GList* stock_got_rows; | ||
683 | 65 | GtkTreeView *_view; | ||
684 | 66 | }; | ||
685 | 67 | |||
686 | 68 | struct _MidoriBookmarksTreeStoreClass | ||
687 | 69 | { | ||
688 | 70 | GtkTreeStoreClass parent_class; | ||
689 | 71 | }; | ||
690 | 72 | |||
691 | 73 | struct _TreeRowData | ||
692 | 74 | { | ||
693 | 75 | GtkTreeModel *model; | ||
694 | 76 | gchar path[4]; | ||
695 | 77 | }; | ||
696 | 78 | |||
697 | 79 | static GtkTreeDragSourceIface * | ||
698 | 80 | gtk_tree_store_gtk_tree_drag_source_iface = NULL; | ||
699 | 81 | static GtkTreeDragDestIface * | ||
700 | 82 | gtk_tree_store_gtk_tree_drag_dest_iface = NULL; | ||
701 | 83 | |||
702 | 84 | static void | ||
703 | 85 | midori_bookmarks_tree_store_drag_source_init (GtkTreeDragSourceIface *iface) | ||
704 | 86 | { | ||
705 | 87 | gtk_tree_store_gtk_tree_drag_source_iface = g_type_interface_peek_parent (iface); | ||
706 | 88 | |||
707 | 89 | iface->drag_data_get = midori_bookmarks_tree_store_drag_data_get; | ||
708 | 90 | iface->drag_data_delete = midori_bookmarks_tree_store_drag_data_delete; | ||
709 | 91 | } | ||
710 | 92 | |||
711 | 93 | static void | ||
712 | 94 | midori_bookmarks_tree_store_drag_dest_init (GtkTreeDragDestIface *iface) | ||
713 | 95 | { | ||
714 | 96 | gtk_tree_store_gtk_tree_drag_dest_iface = g_type_interface_peek_parent (iface); | ||
715 | 97 | |||
716 | 98 | iface->row_drop_possible = midori_bookmarks_tree_store_row_drop_possible; | ||
717 | 99 | iface->drag_data_received = midori_bookmarks_tree_store_drag_data_received; | ||
718 | 100 | } | ||
719 | 101 | |||
720 | 102 | static void | ||
721 | 103 | midori_bookmarks_tree_store_init (MidoriBookmarksTreeStore* item) | ||
722 | 104 | { | ||
723 | 105 | item->stock_got_rows = NULL; | ||
724 | 106 | item->_view = NULL; | ||
725 | 107 | } | ||
726 | 108 | |||
727 | 109 | static void | ||
728 | 110 | midori_bookmarks_tree_store_class_init (MidoriBookmarksTreeStoreClass *class) | ||
729 | 111 | { | ||
730 | 112 | } | ||
731 | 113 | |||
732 | 114 | G_DEFINE_TYPE_WITH_CODE (MidoriBookmarksTreeStore, | ||
733 | 115 | midori_bookmarks_tree_store, | ||
734 | 116 | GTK_TYPE_TREE_STORE, | ||
735 | 117 | G_IMPLEMENT_INTERFACE ( | ||
736 | 118 | GTK_TYPE_TREE_DRAG_SOURCE, | ||
737 | 119 | midori_bookmarks_tree_store_drag_source_init) | ||
738 | 120 | G_IMPLEMENT_INTERFACE ( | ||
739 | 121 | GTK_TYPE_TREE_DRAG_DEST, | ||
740 | 122 | midori_bookmarks_tree_store_drag_dest_init)); | ||
741 | 123 | |||
742 | 124 | |||
743 | 125 | GtkTreeStore* | ||
744 | 126 | midori_bookmarks_tree_store_new (gint n_columns, ...) | ||
745 | 127 | { | ||
746 | 128 | GtkTreeStore* tree_store = GTK_TREE_STORE (g_object_new (MIDORI_BOOKMARKS_TREE_STORE_TYPE, NULL)); | ||
747 | 129 | va_list ap; | ||
748 | 130 | GType* types; | ||
749 | 131 | gint n; | ||
750 | 132 | |||
751 | 133 | if (!tree_store) | ||
752 | 134 | return NULL; | ||
753 | 135 | |||
754 | 136 | types = g_new (GType, n_columns); | ||
755 | 137 | |||
756 | 138 | if (!types) | ||
757 | 139 | { | ||
758 | 140 | g_object_unref(tree_store); | ||
759 | 141 | return NULL; | ||
760 | 142 | } | ||
761 | 143 | |||
762 | 144 | va_start(ap, n_columns); | ||
763 | 145 | for (n = 0; n < n_columns; n++) | ||
764 | 146 | { | ||
765 | 147 | types[n] = va_arg(ap, GType); | ||
766 | 148 | } | ||
767 | 149 | va_end(ap); | ||
768 | 150 | |||
769 | 151 | gtk_tree_store_set_column_types (tree_store, | ||
770 | 152 | n_columns, | ||
771 | 153 | types); | ||
772 | 154 | |||
773 | 155 | g_free (types); | ||
774 | 156 | return tree_store; | ||
775 | 157 | } | ||
776 | 158 | |||
777 | 159 | GtkTreeStore* | ||
778 | 160 | midori_bookmarks_tree_store_newv (gint n_columns, GType *types) | ||
779 | 161 | { | ||
780 | 162 | GtkTreeStore* tree_store = GTK_TREE_STORE (g_object_new (MIDORI_BOOKMARKS_TREE_STORE_TYPE, NULL)); | ||
781 | 163 | |||
782 | 164 | if (!tree_store) | ||
783 | 165 | return NULL; | ||
784 | 166 | |||
785 | 167 | gtk_tree_store_set_column_types (tree_store, | ||
786 | 168 | n_columns, | ||
787 | 169 | types); | ||
788 | 170 | |||
789 | 171 | return tree_store; | ||
790 | 172 | } | ||
791 | 173 | |||
792 | 29 | gboolean | 174 | gboolean |
793 | 30 | midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser, | 175 | midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser, |
794 | 31 | KatzeItem* bookmark_or_parent, | 176 | KatzeItem* bookmark_or_parent, |
795 | @@ -37,6 +182,12 @@ | |||
796 | 37 | midori_browser_open_bookmark (MidoriBrowser* browser, | 182 | midori_browser_open_bookmark (MidoriBrowser* browser, |
797 | 38 | KatzeItem* item); | 183 | KatzeItem* item); |
798 | 39 | 184 | ||
799 | 185 | static void | ||
800 | 186 | midori_bookmarks_row_changed_cb (GtkTreeModel* model, | ||
801 | 187 | GtkTreePath* path, | ||
802 | 188 | GtkTreeIter* iter, | ||
803 | 189 | MidoriBookmarks* bookmarks); | ||
804 | 190 | |||
805 | 40 | struct _MidoriBookmarks | 191 | struct _MidoriBookmarks |
806 | 41 | { | 192 | { |
807 | 42 | GtkVBox parent_instance; | 193 | GtkVBox parent_instance; |
808 | @@ -50,7 +201,19 @@ | |||
809 | 50 | gint filter_timeout; | 201 | gint filter_timeout; |
810 | 51 | gchar* filter; | 202 | gchar* filter; |
811 | 52 | 203 | ||
812 | 204 | GList* pending_inserts; | ||
813 | 53 | KatzeItem* hovering_item; | 205 | KatzeItem* hovering_item; |
814 | 206 | |||
815 | 207 | struct _stock_pending_event | ||
816 | 208 | { | ||
817 | 209 | gint x; | ||
818 | 210 | gint y; | ||
819 | 211 | } *pending_event, | ||
820 | 212 | stock_pending_event; | ||
821 | 213 | |||
822 | 214 | GHashTable* updated_items; | ||
823 | 215 | GList* added_paths; | ||
824 | 216 | GList* reordered_paths; | ||
825 | 54 | }; | 217 | }; |
826 | 55 | 218 | ||
827 | 56 | struct _MidoriBookmarksClass | 219 | struct _MidoriBookmarksClass |
828 | @@ -88,36 +251,47 @@ | |||
829 | 88 | GParamSpec* pspec); | 251 | GParamSpec* pspec); |
830 | 89 | 252 | ||
831 | 90 | static void | 253 | static void |
837 | 91 | midori_bookmarks_row_changed_cb (GtkTreeModel* model, | 254 | midori_bookmarks_update_cb (KatzeArray* array, |
838 | 92 | GtkTreePath* path, | 255 | MidoriBookmarks* bookmarks); |
834 | 93 | GtkTreeIter* iter, | ||
835 | 94 | MidoriBookmarks* bookmarks); | ||
836 | 95 | |||
839 | 96 | static void | 256 | static void |
840 | 97 | midori_bookmarks_add_item_cb (KatzeArray* array, | 257 | midori_bookmarks_add_item_cb (KatzeArray* array, |
841 | 98 | KatzeItem* item, | 258 | KatzeItem* item, |
842 | 99 | MidoriBookmarks* bookmarks); | 259 | MidoriBookmarks* bookmarks); |
843 | 100 | |||
844 | 101 | static void | 260 | static void |
845 | 102 | midori_bookmarks_update_item_cb (KatzeArray* array, | 261 | midori_bookmarks_update_item_cb (KatzeArray* array, |
849 | 103 | KatzeItem* item, | 262 | KatzeItem* item, |
850 | 104 | MidoriBookmarks* bookmarks); | 263 | MidoriBookmarks* bookmarks); |
848 | 105 | |||
851 | 106 | static void | 264 | static void |
852 | 107 | midori_bookmarks_remove_item_cb (KatzeArray* array, | 265 | midori_bookmarks_remove_item_cb (KatzeArray* array, |
853 | 108 | KatzeItem* item, | 266 | KatzeItem* item, |
854 | 109 | MidoriBookmarks* bookmarks); | 267 | MidoriBookmarks* bookmarks); |
855 | 110 | 268 | ||
856 | 111 | static void | 269 | static void |
859 | 112 | midori_bookmarks_update_cb (KatzeArray* array, | 270 | midori_bookmarks_row_inserted_cb (GtkTreeModel* model, |
860 | 113 | MidoriBookmarks* bookmarks); | 271 | GtkTreePath* path, |
861 | 272 | GtkTreeIter* iter, | ||
862 | 273 | MidoriBookmarks* bookmarks); | ||
863 | 274 | static void | ||
864 | 275 | midori_bookmarks_row_changed_cb (GtkTreeModel* model, | ||
865 | 276 | GtkTreePath* path, | ||
866 | 277 | GtkTreeIter* iter, | ||
867 | 278 | MidoriBookmarks* bookmarks); | ||
868 | 279 | static void | ||
869 | 280 | midori_bookmarks_row_deleted_cb (GtkTreeModel* model, | ||
870 | 281 | GtkTreePath* path, | ||
871 | 282 | MidoriBookmarks* bookmarks); | ||
872 | 283 | |||
873 | 284 | static void | ||
874 | 285 | midori_bookmarks_update_item (MidoriBookmarks* bookmarks, KatzeItem *item); | ||
875 | 114 | 286 | ||
876 | 115 | static void | 287 | static void |
877 | 116 | midori_bookmarks_statusbar_update (MidoriBookmarks *bookmarks); | 288 | midori_bookmarks_statusbar_update (MidoriBookmarks *bookmarks); |
878 | 117 | 289 | ||
879 | 118 | static void | 290 | static void |
882 | 119 | midori_bookmarks_add_item (KatzeItem* item, | 291 | midori_bookmarks_idle_remove_item (MidoriBookmarks* bookmarks, KatzeItem *item); |
883 | 120 | MidoriBookmarks* bookmarks); | 292 | |
884 | 293 | static gboolean | ||
885 | 294 | midori_bookmarks_idle_func (gpointer data); | ||
886 | 121 | 295 | ||
887 | 122 | static void | 296 | static void |
888 | 123 | midori_bookmarks_class_init (MidoriBookmarksClass* class) | 297 | midori_bookmarks_class_init (MidoriBookmarksClass* class) |
889 | @@ -133,13 +307,13 @@ | |||
890 | 133 | flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT; | 307 | flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT; |
891 | 134 | 308 | ||
892 | 135 | g_object_class_install_property (gobject_class, | 309 | g_object_class_install_property (gobject_class, |
900 | 136 | PROP_APP, | 310 | PROP_APP, |
901 | 137 | g_param_spec_object ( | 311 | g_param_spec_object ( |
902 | 138 | "app", | 312 | "app", |
903 | 139 | "App", | 313 | "App", |
904 | 140 | "The app", | 314 | "The app", |
905 | 141 | MIDORI_TYPE_APP, | 315 | MIDORI_TYPE_APP, |
906 | 142 | flags)); | 316 | flags)); |
907 | 143 | } | 317 | } |
908 | 144 | 318 | ||
909 | 145 | static const gchar* | 319 | static const gchar* |
910 | @@ -168,7 +342,7 @@ | |||
911 | 168 | gchar* parent_id; | 342 | gchar* parent_id; |
912 | 169 | 343 | ||
913 | 170 | parent_id = g_strdup_printf ("%" G_GINT64_FORMAT, parentid); | 344 | parent_id = g_strdup_printf ("%" G_GINT64_FORMAT, parentid); |
915 | 171 | if (!(root_array = midori_bookmarks_db_query_recursive (array, "*", "parentid = %q", parent_id, FALSE))) | 345 | if (!(root_array = midori_bookmarks_db_query_recursive (array, "*", "parentid = %q", parent_id, "pos_panel DESC,", FALSE))) |
916 | 172 | { | 346 | { |
917 | 173 | g_free (parent_id); | 347 | g_free (parent_id); |
918 | 174 | return; | 348 | return; |
919 | @@ -180,7 +354,7 @@ | |||
920 | 180 | subarray = katze_array_new (KATZE_TYPE_ARRAY); | 354 | subarray = katze_array_new (KATZE_TYPE_ARRAY); |
921 | 181 | katze_item_set_name (KATZE_ITEM (subarray), katze_item_get_name (item)); | 355 | katze_item_set_name (KATZE_ITEM (subarray), katze_item_get_name (item)); |
922 | 182 | midori_bookmarks_export_array_db (db, subarray, | 356 | midori_bookmarks_export_array_db (db, subarray, |
924 | 183 | katze_item_get_meta_integer (item, "parentid")); | 357 | katze_item_get_meta_integer (item, "parentid")); |
925 | 184 | katze_array_add_item (array, subarray); | 358 | katze_array_add_item (array, subarray); |
926 | 185 | } | 359 | } |
927 | 186 | else | 360 | else |
928 | @@ -201,20 +375,20 @@ | |||
929 | 201 | 375 | ||
930 | 202 | if (keyword && *keyword) | 376 | if (keyword && *keyword) |
931 | 203 | array = midori_bookmarks_db_query_recursive (bookmarks->bookmarks_db, | 377 | array = midori_bookmarks_db_query_recursive (bookmarks->bookmarks_db, |
933 | 204 | "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "title LIKE '%%%q%%'", keyword, FALSE); | 378 | "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "title LIKE '%%%q%%'", keyword, NULL, FALSE); |
934 | 205 | else | 379 | else |
935 | 206 | { | 380 | { |
936 | 207 | if (parentid > 0) | 381 | if (parentid > 0) |
937 | 208 | { | 382 | { |
938 | 209 | gchar* parent_id = g_strdup_printf ("%" G_GINT64_FORMAT, parentid); | 383 | gchar* parent_id = g_strdup_printf ("%" G_GINT64_FORMAT, parentid); |
939 | 210 | array = midori_bookmarks_db_query_recursive (bookmarks->bookmarks_db, | 384 | array = midori_bookmarks_db_query_recursive (bookmarks->bookmarks_db, |
941 | 211 | "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "parentid = %q", parent_id, FALSE); | 385 | "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "parentid = %q", parent_id, "pos_panel DESC, ", FALSE); |
942 | 212 | 386 | ||
943 | 213 | g_free (parent_id); | 387 | g_free (parent_id); |
944 | 214 | } | 388 | } |
945 | 215 | else | 389 | else |
946 | 216 | array = midori_bookmarks_db_query_recursive (bookmarks->bookmarks_db, | 390 | array = midori_bookmarks_db_query_recursive (bookmarks->bookmarks_db, |
948 | 217 | "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "parentid IS NULL", NULL, FALSE); | 391 | "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "parentid IS NULL", NULL, "pos_panel DESC, ", FALSE); |
949 | 218 | } | 392 | } |
950 | 219 | return array ? array : katze_array_new (KATZE_TYPE_ITEM); | 393 | return array ? array : katze_array_new (KATZE_TYPE_ITEM); |
951 | 220 | } | 394 | } |
952 | @@ -231,24 +405,52 @@ | |||
953 | 231 | KatzeItem* item; | 405 | KatzeItem* item; |
954 | 232 | GtkTreeIter child; | 406 | GtkTreeIter child; |
955 | 233 | 407 | ||
956 | 408 | g_signal_handlers_block_by_func (model, | ||
957 | 409 | midori_bookmarks_row_changed_cb, | ||
958 | 410 | bookmarks); | ||
959 | 411 | |||
960 | 234 | array = midori_bookmarks_read_from_db (bookmarks, parentid, keyword); | 412 | array = midori_bookmarks_read_from_db (bookmarks, parentid, keyword); |
961 | 235 | katze_bookmark_populate_tree_view (array, model, parent); | 413 | katze_bookmark_populate_tree_view (array, model, parent); |
962 | 414 | |||
963 | 415 | g_signal_handlers_unblock_by_func (model, | ||
964 | 416 | midori_bookmarks_row_changed_cb, | ||
965 | 417 | bookmarks); | ||
966 | 418 | |||
967 | 236 | /* Remove invisible dummy row */ | 419 | /* Remove invisible dummy row */ |
968 | 237 | last = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (model), parent); | 420 | last = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (model), parent); |
969 | 238 | if (!last) | 421 | if (!last) |
970 | 239 | return; | 422 | return; |
971 | 423 | |||
972 | 424 | g_signal_handlers_block_by_func (model, | ||
973 | 425 | midori_bookmarks_row_deleted_cb, | ||
974 | 426 | bookmarks); | ||
975 | 427 | |||
976 | 240 | gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (model), &child, parent, last - 1); | 428 | gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (model), &child, parent, last - 1); |
977 | 241 | gtk_tree_model_get (GTK_TREE_MODEL (model), &child, 0, &item, -1); | 429 | gtk_tree_model_get (GTK_TREE_MODEL (model), &child, 0, &item, -1); |
978 | 242 | if (KATZE_ITEM_IS_SEPARATOR (item)) | 430 | if (KATZE_ITEM_IS_SEPARATOR (item)) |
979 | 243 | gtk_tree_store_remove (model, &child); | 431 | gtk_tree_store_remove (model, &child); |
980 | 244 | else | 432 | else |
981 | 245 | g_object_unref (item); | 433 | g_object_unref (item); |
982 | 434 | |||
983 | 435 | g_signal_handlers_unblock_by_func (model, | ||
984 | 436 | midori_bookmarks_row_deleted_cb, | ||
985 | 437 | bookmarks); | ||
986 | 438 | |||
987 | 246 | } | 439 | } |
988 | 247 | 440 | ||
989 | 441 | static void | ||
990 | 442 | midori_bookmarks_add_item (KatzeItem* item, | ||
991 | 443 | MidoriBookmarks* bookmarks); | ||
992 | 444 | |||
993 | 445 | static void | ||
994 | 446 | add_parent_to_reorder (GtkTreeModel* model, | ||
995 | 447 | GtkTreePath* path, | ||
996 | 448 | MidoriBookmarks* bookmarks); | ||
997 | 449 | |||
998 | 248 | static gboolean | 450 | static gboolean |
999 | 249 | midori_bookmarks_reach_item_recurse (GtkTreeModel* model, | 451 | midori_bookmarks_reach_item_recurse (GtkTreeModel* model, |
1002 | 250 | GtkTreeIter* iter, | 452 | GtkTreeIter* iter, |
1003 | 251 | gint64 id) | 453 | gint64 id) |
1004 | 252 | { | 454 | { |
1005 | 253 | do | 455 | do |
1006 | 254 | { | 456 | { |
1007 | @@ -258,7 +460,7 @@ | |||
1008 | 258 | 460 | ||
1009 | 259 | gtk_tree_model_get (model, iter, 0, &item, -1); | 461 | gtk_tree_model_get (model, iter, 0, &item, -1); |
1010 | 260 | 462 | ||
1012 | 261 | if (!KATZE_ITEM_IS_SEPARATOR(item)) | 463 | if (item) |
1013 | 262 | { | 464 | { |
1014 | 263 | itemid = katze_item_get_meta_integer (item, "id"); | 465 | itemid = katze_item_get_meta_integer (item, "id"); |
1015 | 264 | g_object_unref (item); | 466 | g_object_unref (item); |
1016 | @@ -267,13 +469,11 @@ | |||
1017 | 267 | if (id == itemid) | 469 | if (id == itemid) |
1018 | 268 | return TRUE; | 470 | return TRUE; |
1019 | 269 | 471 | ||
1021 | 270 | if (gtk_tree_model_iter_children (model, &child, iter)) | 472 | if (gtk_tree_model_iter_children (model, &child, iter) |
1022 | 473 | && midori_bookmarks_reach_item_recurse (model, &child, id)) | ||
1023 | 271 | { | 474 | { |
1029 | 272 | if (midori_bookmarks_reach_item_recurse (model, &child, id)) | 475 | *iter = child; |
1030 | 273 | { | 476 | return TRUE; |
1026 | 274 | *iter = child; | ||
1027 | 275 | return TRUE; | ||
1028 | 276 | } | ||
1031 | 277 | } | 477 | } |
1032 | 278 | } | 478 | } |
1033 | 279 | while (gtk_tree_model_iter_next(model, iter)); | 479 | while (gtk_tree_model_iter_next(model, iter)); |
1034 | @@ -283,8 +483,8 @@ | |||
1035 | 283 | 483 | ||
1036 | 284 | static gboolean | 484 | static gboolean |
1037 | 285 | midori_bookmarks_reach_item (GtkTreeModel* model, | 485 | midori_bookmarks_reach_item (GtkTreeModel* model, |
1040 | 286 | GtkTreeIter* iter, | 486 | GtkTreeIter* iter, |
1041 | 287 | gint64 id) | 487 | gint64 id) |
1042 | 288 | { | 488 | { |
1043 | 289 | if (!gtk_tree_model_get_iter_first(model, iter)) | 489 | if (!gtk_tree_model_get_iter_first(model, iter)) |
1044 | 290 | return FALSE; | 490 | return FALSE; |
1045 | @@ -293,38 +493,73 @@ | |||
1046 | 293 | } | 493 | } |
1047 | 294 | 494 | ||
1048 | 295 | static void | 495 | static void |
1052 | 296 | midori_bookmarks_add_item_to_model(GtkTreeStore* model, | 496 | midori_bookmarks_add_item_to_model(MidoriBookmarks* bookmarks, |
1053 | 297 | GtkTreeIter* parent, | 497 | GtkTreeModel* model, |
1054 | 298 | KatzeItem* item) | 498 | GtkTreeIter* parent, |
1055 | 499 | KatzeItem* item) | ||
1056 | 299 | { | 500 | { |
1057 | 501 | GtkTreeStore* tree_store = GTK_TREE_STORE (model); | ||
1058 | 502 | gint last; | ||
1059 | 503 | GtkTreeIter child; | ||
1060 | 504 | |||
1061 | 300 | if (KATZE_ITEM_IS_BOOKMARK (item)) | 505 | if (KATZE_ITEM_IS_BOOKMARK (item)) |
1062 | 301 | { | 506 | { |
1063 | 507 | gint position = 0; | ||
1064 | 508 | |||
1065 | 509 | /* skip the folders to be consistent with the db query order */ | ||
1066 | 510 | if (gtk_tree_model_iter_children (model, &child, parent)) | ||
1067 | 511 | while (gtk_tree_model_iter_has_child (model, &child)) | ||
1068 | 512 | { | ||
1069 | 513 | position++; | ||
1070 | 514 | if (!gtk_tree_model_iter_next (model, &child)) | ||
1071 | 515 | break; | ||
1072 | 516 | } | ||
1073 | 517 | |||
1074 | 302 | gchar* tooltip = g_markup_escape_text (katze_item_get_uri (item), -1); | 518 | gchar* tooltip = g_markup_escape_text (katze_item_get_uri (item), -1); |
1075 | 303 | 519 | ||
1078 | 304 | gtk_tree_store_insert_with_values (model, NULL, parent, | 520 | gtk_tree_store_insert_with_values (tree_store, NULL, parent, |
1079 | 305 | 0, | 521 | position, |
1080 | 306 | 0, item, 1, tooltip, -1); | 522 | 0, item, 1, tooltip, -1); |
1081 | 307 | g_free (tooltip); | 523 | g_free (tooltip); |
1082 | 308 | } | 524 | } |
1084 | 309 | else | 525 | else if (KATZE_ITEM_IS_FOLDER (item)) |
1085 | 310 | { | 526 | { |
1086 | 311 | GtkTreeIter root_iter; | 527 | GtkTreeIter root_iter; |
1087 | 312 | 528 | ||
1089 | 313 | gtk_tree_store_insert_with_values (model, &root_iter, parent, | 529 | gtk_tree_store_insert_with_values (tree_store, &root_iter, parent, |
1090 | 314 | 0, 0, item, -1); | 530 | 0, 0, item, -1); |
1091 | 315 | 531 | ||
1092 | 316 | /* That's an invisible dummy, so we always have an expander */ | 532 | /* That's an invisible dummy, so we always have an expander */ |
1096 | 317 | gtk_tree_store_insert_with_values (model, NULL, &root_iter, | 533 | gtk_tree_store_insert_with_values (tree_store, NULL, &root_iter, |
1097 | 318 | 0, | 534 | 0, 0, NULL, -1); |
1095 | 319 | 0, NULL, -1); | ||
1098 | 320 | } | 535 | } |
1099 | 536 | |||
1100 | 537 | /* Remove invisible dummy row */ | ||
1101 | 538 | last = gtk_tree_model_iter_n_children (model, parent); | ||
1102 | 539 | if (!last) | ||
1103 | 540 | return; | ||
1104 | 541 | |||
1105 | 542 | g_signal_handlers_block_by_func (model, | ||
1106 | 543 | midori_bookmarks_row_deleted_cb, | ||
1107 | 544 | bookmarks); | ||
1108 | 545 | |||
1109 | 546 | gtk_tree_model_iter_nth_child (model, &child, parent, last - 1); | ||
1110 | 547 | gtk_tree_model_get (model, &child, 0, &item, -1); | ||
1111 | 548 | if (KATZE_ITEM_IS_SEPARATOR (item)) | ||
1112 | 549 | gtk_tree_store_remove (tree_store, &child); | ||
1113 | 550 | else | ||
1114 | 551 | g_object_unref (item); | ||
1115 | 552 | |||
1116 | 553 | g_signal_handlers_unblock_by_func (model, | ||
1117 | 554 | midori_bookmarks_row_deleted_cb, | ||
1118 | 555 | bookmarks); | ||
1119 | 321 | } | 556 | } |
1120 | 322 | 557 | ||
1121 | 323 | static void | 558 | static void |
1122 | 324 | midori_bookmarks_update_item_in_model(MidoriBookmarks* bookmarks, | 559 | midori_bookmarks_update_item_in_model(MidoriBookmarks* bookmarks, |
1126 | 325 | GtkTreeStore* model, | 560 | GtkTreeStore* model, |
1127 | 326 | GtkTreeIter* iter, | 561 | GtkTreeIter* iter, |
1128 | 327 | KatzeItem* item) | 562 | KatzeItem* item) |
1129 | 328 | { | 563 | { |
1130 | 329 | g_signal_handlers_block_by_func (model, | 564 | g_signal_handlers_block_by_func (model, |
1131 | 330 | midori_bookmarks_row_changed_cb, | 565 | midori_bookmarks_row_changed_cb, |
1132 | @@ -350,18 +585,48 @@ | |||
1133 | 350 | bookmarks); | 585 | bookmarks); |
1134 | 351 | } | 586 | } |
1135 | 352 | 587 | ||
1136 | 588 | static gboolean | ||
1137 | 589 | midori_bookmarks_idle_pending (MidoriBookmarks* bookmarks) | ||
1138 | 590 | { | ||
1139 | 591 | if (bookmarks->pending_inserts | ||
1140 | 592 | || bookmarks->added_paths | ||
1141 | 593 | || bookmarks->reordered_paths | ||
1142 | 594 | || g_hash_table_size (bookmarks->updated_items)) | ||
1143 | 595 | return TRUE; | ||
1144 | 596 | return FALSE; | ||
1145 | 597 | } | ||
1146 | 598 | |||
1147 | 599 | /** | ||
1148 | 600 | * midori_bookmarks_idle_start: | ||
1149 | 601 | * @bookmarks: the bookmarks panel | ||
1150 | 602 | * | ||
1151 | 603 | * Internal function that checks whether idle processing is pending, | ||
1152 | 604 | * if not, add a new one. | ||
1153 | 605 | **/ | ||
1154 | 606 | static void | ||
1155 | 607 | midori_bookmarks_idle_start (MidoriBookmarks* bookmarks) | ||
1156 | 608 | { | ||
1157 | 609 | if (midori_bookmarks_idle_pending (bookmarks)) | ||
1158 | 610 | return; | ||
1159 | 611 | |||
1160 | 612 | g_idle_add (midori_bookmarks_idle_func, bookmarks); | ||
1161 | 613 | } | ||
1162 | 614 | |||
1163 | 353 | static void | 615 | static void |
1164 | 354 | midori_bookmarks_add_item (KatzeItem* item, | 616 | midori_bookmarks_add_item (KatzeItem* item, |
1165 | 355 | MidoriBookmarks* bookmarks); | 617 | MidoriBookmarks* bookmarks); |
1166 | 618 | |||
1167 | 356 | static void | 619 | static void |
1168 | 357 | midori_bookmarks_add_item_cb (KatzeArray* array, | 620 | midori_bookmarks_add_item_cb (KatzeArray* array, |
1169 | 358 | KatzeItem* item, | 621 | KatzeItem* item, |
1170 | 359 | MidoriBookmarks* bookmarks) | 622 | MidoriBookmarks* bookmarks) |
1171 | 360 | { | 623 | { |
1173 | 361 | midori_bookmarks_add_item (item, bookmarks); | 624 | midori_bookmarks_idle_start (bookmarks); |
1174 | 625 | |||
1175 | 626 | g_object_ref (item); | ||
1176 | 627 | bookmarks->pending_inserts = g_list_append (bookmarks->pending_inserts, item); | ||
1177 | 362 | } | 628 | } |
1178 | 363 | 629 | ||
1179 | 364 | |||
1180 | 365 | static void | 630 | static void |
1181 | 366 | midori_bookmarks_add_item (KatzeItem* item, | 631 | midori_bookmarks_add_item (KatzeItem* item, |
1182 | 367 | MidoriBookmarks* bookmarks) | 632 | MidoriBookmarks* bookmarks) |
1183 | @@ -370,18 +635,16 @@ | |||
1184 | 370 | GtkTreeModel* model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview)); | 635 | GtkTreeModel* model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview)); |
1185 | 371 | GtkTreeIter iter; | 636 | GtkTreeIter iter; |
1186 | 372 | 637 | ||
1191 | 373 | if (!parentid) | 638 | if (parentid == katze_item_get_meta_integer (KATZE_ITEM (bookmarks->bookmarks_db), "id")) |
1192 | 374 | { | 639 | midori_bookmarks_add_item_to_model (bookmarks, model, NULL, item); |
1189 | 375 | midori_bookmarks_add_item_to_model (GTK_TREE_STORE (model), NULL, item); | ||
1190 | 376 | } | ||
1193 | 377 | else if (midori_bookmarks_reach_item (model, &iter, parentid)) | 640 | else if (midori_bookmarks_reach_item (model, &iter, parentid)) |
1194 | 378 | { | 641 | { |
1195 | 379 | GtkTreePath* path = gtk_tree_model_get_path(model, &iter); | 642 | GtkTreePath* path = gtk_tree_model_get_path(model, &iter); |
1196 | 643 | gint n_children = gtk_tree_model_iter_n_children (model, &iter); | ||
1197 | 380 | 644 | ||
1202 | 381 | if (gtk_tree_view_row_expanded (GTK_TREE_VIEW (bookmarks->treeview), path)) | 645 | if (gtk_tree_view_row_expanded (GTK_TREE_VIEW (bookmarks->treeview), path) |
1203 | 382 | { | 646 | || !n_children) |
1204 | 383 | midori_bookmarks_add_item_to_model (GTK_TREE_STORE (model), &iter, item); | 647 | midori_bookmarks_add_item_to_model (bookmarks, model, &iter, item); |
1201 | 384 | } | ||
1205 | 385 | 648 | ||
1206 | 386 | gtk_tree_path_free (path); | 649 | gtk_tree_path_free (path); |
1207 | 387 | } | 650 | } |
1208 | @@ -389,8 +652,8 @@ | |||
1209 | 389 | 652 | ||
1210 | 390 | static void | 653 | static void |
1211 | 391 | midori_bookmarks_update_item_cb (KatzeArray* array, | 654 | midori_bookmarks_update_item_cb (KatzeArray* array, |
1214 | 392 | KatzeItem* item, | 655 | KatzeItem* item, |
1215 | 393 | MidoriBookmarks* bookmarks) | 656 | MidoriBookmarks* bookmarks) |
1216 | 394 | { | 657 | { |
1217 | 395 | gint64 id = katze_item_get_meta_integer (item, "id"); | 658 | gint64 id = katze_item_get_meta_integer (item, "id"); |
1218 | 396 | gint64 parentid = katze_item_get_meta_integer (item, "parentid"); | 659 | gint64 parentid = katze_item_get_meta_integer (item, "parentid"); |
1219 | @@ -433,7 +696,7 @@ | |||
1220 | 433 | midori_bookmarks_add_item (item, bookmarks); | 696 | midori_bookmarks_add_item (item, bookmarks); |
1221 | 434 | } | 697 | } |
1222 | 435 | } | 698 | } |
1224 | 436 | else if (parentid == 0) | 699 | else if (parentid == katze_item_get_meta_integer (KATZE_ITEM (bookmarks->bookmarks_db), "id")) |
1225 | 437 | { | 700 | { |
1226 | 438 | midori_bookmarks_update_item_in_model (bookmarks, GTK_TREE_STORE (model), &iter, item); | 701 | midori_bookmarks_update_item_in_model (bookmarks, GTK_TREE_STORE (model), &iter, item); |
1227 | 439 | } | 702 | } |
1228 | @@ -457,6 +720,10 @@ | |||
1229 | 457 | GtkTreeModel* model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview)); | 720 | GtkTreeModel* model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview)); |
1230 | 458 | GtkTreeIter iter; | 721 | GtkTreeIter iter; |
1231 | 459 | 722 | ||
1232 | 723 | g_assert (KATZE_IS_ITEM (item)); | ||
1233 | 724 | |||
1234 | 725 | midori_bookmarks_idle_remove_item (bookmarks, item); | ||
1235 | 726 | |||
1236 | 460 | if (midori_bookmarks_reach_item (model, &iter, id)) | 727 | if (midori_bookmarks_reach_item (model, &iter, id)) |
1237 | 461 | { | 728 | { |
1238 | 462 | GtkTreeIter parent; | 729 | GtkTreeIter parent; |
1239 | @@ -486,12 +753,869 @@ | |||
1240 | 486 | midori_bookmarks_update_cb (KatzeArray* array, | 753 | midori_bookmarks_update_cb (KatzeArray* array, |
1241 | 487 | MidoriBookmarks* bookmarks) | 754 | MidoriBookmarks* bookmarks) |
1242 | 488 | { | 755 | { |
1243 | 756 | #if 1 | ||
1244 | 757 | g_print ("midori_bookmarks_update_cb: ignored ********\n"); | ||
1245 | 758 | #else | ||
1246 | 489 | GtkTreeModel* model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview)); | 759 | GtkTreeModel* model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview)); |
1247 | 760 | |||
1248 | 490 | gtk_tree_store_clear (GTK_TREE_STORE (model)); | 761 | gtk_tree_store_clear (GTK_TREE_STORE (model)); |
1249 | 491 | midori_bookmarks_read_from_db_to_model (bookmarks, | 762 | midori_bookmarks_read_from_db_to_model (bookmarks, |
1250 | 492 | GTK_TREE_STORE (model), NULL, 0, bookmarks->filter); | 763 | GTK_TREE_STORE (model), NULL, 0, bookmarks->filter); |
1253 | 493 | } | 764 | #endif |
1254 | 494 | 765 | } | |
1255 | 766 | |||
1256 | 767 | gboolean | ||
1257 | 768 | midori_bookmarks_tree_set_row_drag_data (GtkSelectionData *selection_data, | ||
1258 | 769 | GtkTreeModel *tree_model, | ||
1259 | 770 | GList* rows) | ||
1260 | 771 | { | ||
1261 | 772 | TreeRowData *trd; | ||
1262 | 773 | gint len; | ||
1263 | 774 | gint struct_size; | ||
1264 | 775 | gint length; | ||
1265 | 776 | gint i; | ||
1266 | 777 | GString *data; | ||
1267 | 778 | |||
1268 | 779 | g_return_val_if_fail (selection_data != NULL, FALSE); | ||
1269 | 780 | g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE); | ||
1270 | 781 | g_return_val_if_fail (rows != NULL, FALSE); | ||
1271 | 782 | |||
1272 | 783 | data = g_string_new(""); | ||
1273 | 784 | |||
1274 | 785 | length = g_list_length (rows); | ||
1275 | 786 | for (i = 0; i < length; i++) | ||
1276 | 787 | { | ||
1277 | 788 | GtkTreePath *path = (GtkTreePath *)g_list_nth_data (rows, i); | ||
1278 | 789 | gchar *path_str = gtk_tree_path_to_string (path); | ||
1279 | 790 | |||
1280 | 791 | g_string_append (data, path_str); | ||
1281 | 792 | if (i < length-1) | ||
1282 | 793 | g_string_append_c (data, '\n'); | ||
1283 | 794 | } | ||
1284 | 795 | |||
1285 | 796 | len = data->len; | ||
1286 | 797 | |||
1287 | 798 | /* the old allocate-end-of-struct-to-hold-string trick */ | ||
1288 | 799 | struct_size = sizeof (TreeRowData) + len + 1 - | ||
1289 | 800 | (sizeof (TreeRowData) - G_STRUCT_OFFSET (TreeRowData, path)); | ||
1290 | 801 | |||
1291 | 802 | trd = g_malloc (struct_size); | ||
1292 | 803 | |||
1293 | 804 | strcpy (trd->path, data->str); | ||
1294 | 805 | |||
1295 | 806 | g_string_free (data, TRUE); | ||
1296 | 807 | |||
1297 | 808 | trd->model = tree_model; | ||
1298 | 809 | |||
1299 | 810 | gtk_selection_data_set (selection_data, | ||
1300 | 811 | gdk_atom_intern_static_string (MIDORI_BOOKMARKS_TREE_MODEL_TARGET), | ||
1301 | 812 | 8, /* bytes */ | ||
1302 | 813 | (void*)trd, | ||
1303 | 814 | struct_size); | ||
1304 | 815 | |||
1305 | 816 | g_free (trd); | ||
1306 | 817 | |||
1307 | 818 | return TRUE; | ||
1308 | 819 | } | ||
1309 | 820 | |||
1310 | 821 | static gboolean | ||
1311 | 822 | midori_bookmarks_tree_store_drag_data_get (GtkTreeDragSource* drag_source, | ||
1312 | 823 | GtkTreePath* source_path, | ||
1313 | 824 | GtkSelectionData* selection_data) | ||
1314 | 825 | { | ||
1315 | 826 | MidoriBookmarksTreeStore *tree_store; | ||
1316 | 827 | gboolean status = FALSE; | ||
1317 | 828 | |||
1318 | 829 | g_return_val_if_fail (selection_data != NULL, FALSE); | ||
1319 | 830 | g_return_val_if_fail (GTK_IS_TREE_MODEL (drag_source), FALSE); | ||
1320 | 831 | g_return_val_if_fail (source_path != NULL, FALSE); | ||
1321 | 832 | |||
1322 | 833 | tree_store = MIDORI_BOOKMARKS_TREE_STORE(drag_source); | ||
1323 | 834 | |||
1324 | 835 | if (tree_store->stock_got_rows) | ||
1325 | 836 | { | ||
1326 | 837 | g_list_free_full (tree_store->stock_got_rows, (GDestroyNotify) gtk_tree_path_free); | ||
1327 | 838 | tree_store->stock_got_rows = NULL; | ||
1328 | 839 | } | ||
1329 | 840 | |||
1330 | 841 | if (gtk_selection_data_get_target (selection_data) == | ||
1331 | 842 | gdk_atom_intern_static_string (MIDORI_BOOKMARKS_TREE_MODEL_TARGET)) | ||
1332 | 843 | { | ||
1333 | 844 | GtkTreeModel *model; | ||
1334 | 845 | GList* rows; | ||
1335 | 846 | if (katze_tree_view_get_selected_rows ( | ||
1336 | 847 | tree_store->_view, &model, &rows)) | ||
1337 | 848 | { | ||
1338 | 849 | status = midori_bookmarks_tree_set_row_drag_data (selection_data, model, rows); | ||
1339 | 850 | |||
1340 | 851 | tree_store->stock_got_rows = rows; | ||
1341 | 852 | } | ||
1342 | 853 | } | ||
1343 | 854 | |||
1344 | 855 | return status; | ||
1345 | 856 | } | ||
1346 | 857 | |||
1347 | 858 | static void | ||
1348 | 859 | update_path_list_for_insert (GList * rows, GtkTreePath* path) | ||
1349 | 860 | { | ||
1350 | 861 | gint length = g_list_length (rows); | ||
1351 | 862 | gint i; | ||
1352 | 863 | |||
1353 | 864 | for (i = 0; i < length; i++ ) | ||
1354 | 865 | { | ||
1355 | 866 | GtkTreePath *src_path_r = (GtkTreePath *)g_list_nth_data (rows, i); | ||
1356 | 867 | gint la = gtk_tree_path_get_depth (path); | ||
1357 | 868 | gint lb = gtk_tree_path_get_depth (src_path_r); | ||
1358 | 869 | gint *ia = gtk_tree_path_get_indices (path); | ||
1359 | 870 | gint *ib = gtk_tree_path_get_indices (src_path_r); | ||
1360 | 871 | gint j; | ||
1361 | 872 | |||
1362 | 873 | if (la > lb) /* insert was donne in a deeper branch than source */ | ||
1363 | 874 | continue; | ||
1364 | 875 | |||
1365 | 876 | if (ia[la-1] > ib[la-1]) /* insert was donne after source */ | ||
1366 | 877 | continue; | ||
1367 | 878 | |||
1368 | 879 | for (j = 0; j < la; j++) | ||
1369 | 880 | { | ||
1370 | 881 | if (ia[j] != ib[j]) break; | ||
1371 | 882 | } | ||
1372 | 883 | |||
1373 | 884 | if (j < la-1) /* insert and source are not in the same branch */ | ||
1374 | 885 | continue; | ||
1375 | 886 | |||
1376 | 887 | /* source at depth level of insert must be incremented due to the insert */ | ||
1377 | 888 | ib[la-1] += 1; | ||
1378 | 889 | } | ||
1379 | 890 | } | ||
1380 | 891 | |||
1381 | 892 | static gint | ||
1382 | 893 | midori_tree_path_compare (const GtkTreePath *a, | ||
1383 | 894 | const GtkTreePath *b) | ||
1384 | 895 | { | ||
1385 | 896 | if (!gtk_tree_path_get_depth ((GtkTreePath *)a)) | ||
1386 | 897 | { | ||
1387 | 898 | if (!gtk_tree_path_get_depth ((GtkTreePath *)b)) | ||
1388 | 899 | return 0; | ||
1389 | 900 | |||
1390 | 901 | return -1; | ||
1391 | 902 | } | ||
1392 | 903 | |||
1393 | 904 | if (!gtk_tree_path_get_depth ((GtkTreePath *)b)) | ||
1394 | 905 | return 1; | ||
1395 | 906 | |||
1396 | 907 | return gtk_tree_path_compare (a, b); | ||
1397 | 908 | } | ||
1398 | 909 | |||
1399 | 910 | static GList* | ||
1400 | 911 | update_path_list_for_delete (GList* rows, GtkTreePath* removed_path) | ||
1401 | 912 | { | ||
1402 | 913 | GList* new_rows = rows; | ||
1403 | 914 | |||
1404 | 915 | while (rows) | ||
1405 | 916 | { | ||
1406 | 917 | GtkTreePath *source_path = (GtkTreePath *)rows->data; | ||
1407 | 918 | gint la = gtk_tree_path_get_depth (removed_path); | ||
1408 | 919 | gint lb = gtk_tree_path_get_depth (source_path); | ||
1409 | 920 | gint *ia = gtk_tree_path_get_indices (removed_path); | ||
1410 | 921 | gint *ib = gtk_tree_path_get_indices (source_path); | ||
1411 | 922 | gint cmp = midori_tree_path_compare (removed_path, source_path); | ||
1412 | 923 | gint j; | ||
1413 | 924 | |||
1414 | 925 | if (cmp == 1) /* removal was done after source => kip source as it is */ | ||
1415 | 926 | goto keep_source; | ||
1416 | 927 | |||
1417 | 928 | if (cmp == 0) /* source is removed => remove source */ | ||
1418 | 929 | goto remove_source; | ||
1419 | 930 | |||
1420 | 931 | /* if removal is an ancestor of the source => remove source */ | ||
1421 | 932 | if (gtk_tree_path_is_ancestor (removed_path, source_path)) | ||
1422 | 933 | goto remove_source; | ||
1423 | 934 | |||
1424 | 935 | if (la > lb) /* removal was donne in a deeper branch than source */ | ||
1425 | 936 | goto keep_source; | ||
1426 | 937 | |||
1427 | 938 | for (j = 0; j < la; j++) | ||
1428 | 939 | { | ||
1429 | 940 | if (ia[j] != ib[j]) break; | ||
1430 | 941 | } | ||
1431 | 942 | |||
1432 | 943 | if (j < la-1) /* removal and source are not in the same branch */ | ||
1433 | 944 | goto keep_source; | ||
1434 | 945 | |||
1435 | 946 | /* source at depth level of removal must be decremented due to the removal */ | ||
1436 | 947 | ib[la-1] -= 1; | ||
1437 | 948 | |||
1438 | 949 | if (ib[la-1] >= 0) | ||
1439 | 950 | goto keep_source; | ||
1440 | 951 | |||
1441 | 952 | remove_source: | ||
1442 | 953 | /* remove source entry */ | ||
1443 | 954 | gtk_tree_path_free (source_path); | ||
1444 | 955 | { | ||
1445 | 956 | GList *next_rows = g_list_next (rows); | ||
1446 | 957 | new_rows = g_list_delete_link (new_rows, rows); | ||
1447 | 958 | rows = next_rows; | ||
1448 | 959 | } | ||
1449 | 960 | continue; | ||
1450 | 961 | |||
1451 | 962 | keep_source: | ||
1452 | 963 | rows = g_list_next (rows); | ||
1453 | 964 | } | ||
1454 | 965 | |||
1455 | 966 | return new_rows; | ||
1456 | 967 | } | ||
1457 | 968 | |||
1458 | 969 | static gboolean | ||
1459 | 970 | midori_bookmarks_tree_store_drag_data_delete (GtkTreeDragSource* drag_source, | ||
1460 | 971 | GtkTreePath* source_path) | ||
1461 | 972 | { | ||
1462 | 973 | gboolean status = TRUE; | ||
1463 | 974 | MidoriBookmarksTreeStore *tree_store = MIDORI_BOOKMARKS_TREE_STORE(drag_source); | ||
1464 | 975 | GtkTreeModel* model = GTK_TREE_MODEL(drag_source); | ||
1465 | 976 | |||
1466 | 977 | if (!tree_store->stock_got_rows) | ||
1467 | 978 | return TRUE; | ||
1468 | 979 | |||
1469 | 980 | while (tree_store->stock_got_rows) | ||
1470 | 981 | { | ||
1471 | 982 | GtkTreePath *prev = (GtkTreePath *)tree_store->stock_got_rows->data; | ||
1472 | 983 | GtkTreeIter iter; | ||
1473 | 984 | |||
1474 | 985 | tree_store->stock_got_rows = g_list_delete_link (tree_store->stock_got_rows, | ||
1475 | 986 | tree_store->stock_got_rows); | ||
1476 | 987 | |||
1477 | 988 | if (gtk_tree_model_get_iter (model, &iter, prev)) | ||
1478 | 989 | { | ||
1479 | 990 | /* remove item updating source paths */ | ||
1480 | 991 | gtk_tree_store_remove (GTK_TREE_STORE (drag_source), &iter); | ||
1481 | 992 | |||
1482 | 993 | tree_store->stock_got_rows = update_path_list_for_delete (tree_store->stock_got_rows, prev); | ||
1483 | 994 | } | ||
1484 | 995 | else | ||
1485 | 996 | status = FALSE; | ||
1486 | 997 | |||
1487 | 998 | gtk_tree_path_free (prev); | ||
1488 | 999 | } | ||
1489 | 1000 | |||
1490 | 1001 | return status; | ||
1491 | 1002 | } | ||
1492 | 1003 | |||
1493 | 1004 | static gboolean | ||
1494 | 1005 | midori_bookmarks_tree_store_get_rows_drag_data (GtkSelectionData *selection_data, | ||
1495 | 1006 | GtkTreeModel **tree_model, | ||
1496 | 1007 | GList **rows) | ||
1497 | 1008 | { | ||
1498 | 1009 | TreeRowData *trd; | ||
1499 | 1010 | |||
1500 | 1011 | g_return_val_if_fail (selection_data != NULL, FALSE); | ||
1501 | 1012 | |||
1502 | 1013 | if (tree_model) | ||
1503 | 1014 | *tree_model = NULL; | ||
1504 | 1015 | |||
1505 | 1016 | if (rows) | ||
1506 | 1017 | *rows = NULL; | ||
1507 | 1018 | |||
1508 | 1019 | if (gtk_selection_data_get_target (selection_data) != | ||
1509 | 1020 | gdk_atom_intern_static_string (MIDORI_BOOKMARKS_TREE_MODEL_TARGET)) | ||
1510 | 1021 | return FALSE; | ||
1511 | 1022 | |||
1512 | 1023 | if (gtk_selection_data_get_length (selection_data) < 0) | ||
1513 | 1024 | return FALSE; | ||
1514 | 1025 | |||
1515 | 1026 | trd = (void*) gtk_selection_data_get_data (selection_data); | ||
1516 | 1027 | |||
1517 | 1028 | if (tree_model) | ||
1518 | 1029 | *tree_model = trd->model; | ||
1519 | 1030 | |||
1520 | 1031 | if (rows) | ||
1521 | 1032 | { | ||
1522 | 1033 | GList *list = NULL; | ||
1523 | 1034 | gchar *trd_path = g_strdup (trd->path); | ||
1524 | 1035 | gchar *path_str; | ||
1525 | 1036 | |||
1526 | 1037 | path_str = strtok(trd_path, "\n"); | ||
1527 | 1038 | while (path_str && *path_str) | ||
1528 | 1039 | { | ||
1529 | 1040 | list = g_list_append (list, gtk_tree_path_new_from_string (path_str)); | ||
1530 | 1041 | path_str = strtok (NULL, "\n"); | ||
1531 | 1042 | } | ||
1532 | 1043 | |||
1533 | 1044 | *rows = list; | ||
1534 | 1045 | g_free (trd_path); | ||
1535 | 1046 | } | ||
1536 | 1047 | |||
1537 | 1048 | return TRUE; | ||
1538 | 1049 | } | ||
1539 | 1050 | |||
1540 | 1051 | #if !GTK_CHECK_VERSION (3,0,0) | ||
1541 | 1052 | gboolean | ||
1542 | 1053 | gtk_tree_model_iter_previous (GtkTreeModel *tree_model, | ||
1543 | 1054 | GtkTreeIter *iter) | ||
1544 | 1055 | { | ||
1545 | 1056 | GtkTreePath* path = gtk_tree_model_get_path (tree_model, iter); | ||
1546 | 1057 | gboolean result = gtk_tree_path_prev (path); | ||
1547 | 1058 | |||
1548 | 1059 | if (result) | ||
1549 | 1060 | result = gtk_tree_model_get_iter (tree_model, iter, path); | ||
1550 | 1061 | else | ||
1551 | 1062 | { | ||
1552 | 1063 | GtkTreeIter invalid = {0}; | ||
1553 | 1064 | *iter = invalid; | ||
1554 | 1065 | } | ||
1555 | 1066 | |||
1556 | 1067 | gtk_tree_path_free (path); | ||
1557 | 1068 | return result; | ||
1558 | 1069 | } | ||
1559 | 1070 | #endif | ||
1560 | 1071 | |||
1561 | 1072 | static gboolean | ||
1562 | 1073 | midori_bookmarks_tree_store_row_drop_possible (GtkTreeDragDest* drag_dest, | ||
1563 | 1074 | GtkTreePath* dest_path, | ||
1564 | 1075 | GtkSelectionData* selection_data) | ||
1565 | 1076 | { | ||
1566 | 1077 | GtkTreeModel* dest_model = GTK_TREE_MODEL(drag_dest); | ||
1567 | 1078 | GtkTreePath *parent; | ||
1568 | 1079 | GtkTreeIter dest_parent; | ||
1569 | 1080 | GtkTreeIter *dest_parent_p = NULL; | ||
1570 | 1081 | gboolean row_drop_possible = TRUE; | ||
1571 | 1082 | GtkTreeViewDropPosition drop_position; | ||
1572 | 1083 | |||
1573 | 1084 | gtk_tree_view_get_drag_dest_row (MIDORI_BOOKMARKS_TREE_STORE (dest_model)->_view, | ||
1574 | 1085 | NULL, &drop_position); | ||
1575 | 1086 | |||
1576 | 1087 | parent = gtk_tree_path_copy (dest_path); | ||
1577 | 1088 | if ((gtk_tree_path_get_depth (parent) > 1) | ||
1578 | 1089 | && gtk_tree_path_up (parent) | ||
1579 | 1090 | && gtk_tree_model_get_iter (dest_model, &dest_parent, parent)) | ||
1580 | 1091 | dest_parent_p = &dest_parent; | ||
1581 | 1092 | |||
1582 | 1093 | gtk_tree_path_free (parent); | ||
1583 | 1094 | |||
1584 | 1095 | if (dest_parent_p) | ||
1585 | 1096 | { | ||
1586 | 1097 | KatzeItem* item; | ||
1587 | 1098 | |||
1588 | 1099 | gtk_tree_model_get (dest_model, dest_parent_p, 0, &item, -1); | ||
1589 | 1100 | |||
1590 | 1101 | if (!KATZE_ITEM_IS_FOLDER (item)) | ||
1591 | 1102 | { | ||
1592 | 1103 | #ifdef DEBUG_DROP | ||
1593 | 1104 | gchar *dest_path_str = gtk_tree_path_to_string (dest_path); | ||
1594 | 1105 | |||
1595 | 1106 | g_print ("%s: can only drop into folders\n", dest_path_str); | ||
1596 | 1107 | g_free (dest_path_str); | ||
1597 | 1108 | #endif /* DEBUG_DROP */ | ||
1598 | 1109 | row_drop_possible = FALSE; | ||
1599 | 1110 | } | ||
1600 | 1111 | |||
1601 | 1112 | if (item) | ||
1602 | 1113 | g_object_unref (item); | ||
1603 | 1114 | } | ||
1604 | 1115 | |||
1605 | 1116 | if (row_drop_possible | ||
1606 | 1117 | && (gtk_selection_data_get_target (selection_data) == | ||
1607 | 1118 | gdk_atom_intern_static_string (MIDORI_BOOKMARKS_TREE_MODEL_TARGET))) | ||
1608 | 1119 | { | ||
1609 | 1120 | GtkTreeModel *src_model; | ||
1610 | 1121 | GList* rows; | ||
1611 | 1122 | |||
1612 | 1123 | if (midori_bookmarks_tree_store_get_rows_drag_data (selection_data, | ||
1613 | 1124 | &src_model, &rows)) | ||
1614 | 1125 | { | ||
1615 | 1126 | GtkTreeIter dest_iter; | ||
1616 | 1127 | GList* src_row; | ||
1617 | 1128 | gboolean dest_is_folder = FALSE; | ||
1618 | 1129 | /* gboolean dest_is_bookmark = FALSE; */ | ||
1619 | 1130 | gboolean src_has_folders = FALSE; | ||
1620 | 1131 | gboolean src_has_bookmarks = FALSE; | ||
1621 | 1132 | |||
1622 | 1133 | if (gtk_tree_model_get_iter (dest_model, &dest_iter, dest_path)) | ||
1623 | 1134 | { | ||
1624 | 1135 | if (gtk_tree_model_iter_has_child (dest_model, &dest_iter)) | ||
1625 | 1136 | dest_is_folder = TRUE; | ||
1626 | 1137 | /* | ||
1627 | 1138 | else | ||
1628 | 1139 | { | ||
1629 | 1140 | KatzeItem* item; | ||
1630 | 1141 | gtk_tree_model_get (dest_model, &dest_iter, 0, &item, -1); | ||
1631 | 1142 | if (item) | ||
1632 | 1143 | { | ||
1633 | 1144 | dest_is_bookmark = TRUE; | ||
1634 | 1145 | g_object_unref (item); | ||
1635 | 1146 | } | ||
1636 | 1147 | } | ||
1637 | 1148 | */ | ||
1638 | 1149 | } | ||
1639 | 1150 | |||
1640 | 1151 | for (src_row = rows ; src_row ; src_row = g_list_next (src_row)) | ||
1641 | 1152 | { | ||
1642 | 1153 | GtkTreePath* src_path = (GtkTreePath*)src_row->data; | ||
1643 | 1154 | GtkTreeIter src_iter; | ||
1644 | 1155 | KatzeItem* item; | ||
1645 | 1156 | |||
1646 | 1157 | if (!gtk_tree_model_get_iter (src_model, &src_iter, src_path)) | ||
1647 | 1158 | continue; | ||
1648 | 1159 | |||
1649 | 1160 | gtk_tree_model_get (src_model, &src_iter, 0, &item, -1); | ||
1650 | 1161 | if (item) | ||
1651 | 1162 | { | ||
1652 | 1163 | if (!src_has_folders && KATZE_ITEM_IS_FOLDER (item)) | ||
1653 | 1164 | src_has_folders = TRUE; | ||
1654 | 1165 | else if (!src_has_bookmarks && KATZE_ITEM_IS_BOOKMARK (item)) | ||
1655 | 1166 | src_has_bookmarks = TRUE; | ||
1656 | 1167 | |||
1657 | 1168 | g_object_unref (item); | ||
1658 | 1169 | } | ||
1659 | 1170 | if (src_has_bookmarks && src_has_folders) | ||
1660 | 1171 | break; | ||
1661 | 1172 | } | ||
1662 | 1173 | |||
1663 | 1174 | if (src_has_bookmarks) | ||
1664 | 1175 | { | ||
1665 | 1176 | switch (drop_position) | ||
1666 | 1177 | { | ||
1667 | 1178 | case GTK_TREE_VIEW_DROP_BEFORE: | ||
1668 | 1179 | case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: | ||
1669 | 1180 | if (dest_is_folder) | ||
1670 | 1181 | { | ||
1671 | 1182 | #ifdef DEBUG_DROP | ||
1672 | 1183 | gchar *dest_path_str = gtk_tree_path_to_string (dest_path); | ||
1673 | 1184 | |||
1674 | 1185 | g_print ("%s: cannot drop bookmarks in folders group\n", dest_path_str); | ||
1675 | 1186 | g_free (dest_path_str); | ||
1676 | 1187 | #endif /* DEBUG_DROP */ | ||
1677 | 1188 | row_drop_possible = FALSE; | ||
1678 | 1189 | goto done; | ||
1679 | 1190 | } | ||
1680 | 1191 | break; | ||
1681 | 1192 | case GTK_TREE_VIEW_DROP_AFTER: | ||
1682 | 1193 | case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: | ||
1683 | 1194 | if (dest_is_folder) | ||
1684 | 1195 | { | ||
1685 | 1196 | gboolean next_dest_is_folder = FALSE; | ||
1686 | 1197 | |||
1687 | 1198 | if (gtk_tree_model_iter_next (dest_model, &dest_iter)) | ||
1688 | 1199 | if (gtk_tree_model_iter_has_child (dest_model, &dest_iter)) | ||
1689 | 1200 | next_dest_is_folder = TRUE; | ||
1690 | 1201 | |||
1691 | 1202 | if (next_dest_is_folder) | ||
1692 | 1203 | { | ||
1693 | 1204 | #ifdef DEBUG_DROP | ||
1694 | 1205 | gchar *dest_path_str = gtk_tree_path_to_string (dest_path); | ||
1695 | 1206 | |||
1696 | 1207 | g_print ("%s: cannot drop bookmarks in folders group\n", dest_path_str); | ||
1697 | 1208 | g_free (dest_path_str); | ||
1698 | 1209 | #endif /* DEBUG_DROP */ | ||
1699 | 1210 | row_drop_possible = FALSE; | ||
1700 | 1211 | goto done; | ||
1701 | 1212 | } | ||
1702 | 1213 | } | ||
1703 | 1214 | break; | ||
1704 | 1215 | default: | ||
1705 | 1216 | break; | ||
1706 | 1217 | } | ||
1707 | 1218 | } | ||
1708 | 1219 | else if (src_has_folders) | ||
1709 | 1220 | { | ||
1710 | 1221 | gboolean prev_dest_is_folder = TRUE; | ||
1711 | 1222 | |||
1712 | 1223 | if (gtk_tree_model_iter_previous (dest_model, &dest_iter)) | ||
1713 | 1224 | if (!gtk_tree_model_iter_has_child (dest_model, &dest_iter)) | ||
1714 | 1225 | prev_dest_is_folder = FALSE; | ||
1715 | 1226 | |||
1716 | 1227 | if (!prev_dest_is_folder) | ||
1717 | 1228 | { | ||
1718 | 1229 | #ifdef DEBUG_DROP | ||
1719 | 1230 | gchar *dest_path_str = gtk_tree_path_to_string (dest_path); | ||
1720 | 1231 | |||
1721 | 1232 | g_print ("%s: cannot drop folders in bookmarks group\n", dest_path_str); | ||
1722 | 1233 | g_free (dest_path_str); | ||
1723 | 1234 | #endif /* DEBUG_DROP */ | ||
1724 | 1235 | row_drop_possible = FALSE; | ||
1725 | 1236 | goto done; | ||
1726 | 1237 | } | ||
1727 | 1238 | } | ||
1728 | 1239 | |||
1729 | 1240 | if (src_model == dest_model) | ||
1730 | 1241 | { | ||
1731 | 1242 | for (src_row = rows ; src_row ; src_row = g_list_next (src_row)) | ||
1732 | 1243 | { | ||
1733 | 1244 | GtkTreePath* src_path = (GtkTreePath*)src_row->data; | ||
1734 | 1245 | |||
1735 | 1246 | /* Can't drop into ourself. */ | ||
1736 | 1247 | if (gtk_tree_path_is_ancestor (src_path, dest_path)) | ||
1737 | 1248 | { | ||
1738 | 1249 | #ifdef DEBUG_DROP | ||
1739 | 1250 | g_print ("cannot drop into source folders\n"); | ||
1740 | 1251 | #endif /* DEBUG_DROP */ | ||
1741 | 1252 | row_drop_possible = FALSE; | ||
1742 | 1253 | goto done; | ||
1743 | 1254 | } | ||
1744 | 1255 | update_path_list_for_insert (rows, dest_path); | ||
1745 | 1256 | } | ||
1746 | 1257 | } | ||
1747 | 1258 | done: | ||
1748 | 1259 | g_list_free_full (rows, (GDestroyNotify) gtk_tree_path_free); | ||
1749 | 1260 | } | ||
1750 | 1261 | else | ||
1751 | 1262 | row_drop_possible = FALSE; | ||
1752 | 1263 | } | ||
1753 | 1264 | else | ||
1754 | 1265 | row_drop_possible = FALSE; | ||
1755 | 1266 | |||
1756 | 1267 | #ifdef DEBUG_DROP | ||
1757 | 1268 | if (row_drop_possible) | ||
1758 | 1269 | { | ||
1759 | 1270 | gchar *dest_path_str = gtk_tree_path_to_string (dest_path); | ||
1760 | 1271 | gchar *drop_position_str = "unknown"; | ||
1761 | 1272 | switch (drop_position) | ||
1762 | 1273 | { | ||
1763 | 1274 | case GTK_TREE_VIEW_DROP_BEFORE: | ||
1764 | 1275 | drop_position_str = "before"; | ||
1765 | 1276 | break; | ||
1766 | 1277 | case GTK_TREE_VIEW_DROP_AFTER: | ||
1767 | 1278 | drop_position_str = "after"; | ||
1768 | 1279 | break; | ||
1769 | 1280 | case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: | ||
1770 | 1281 | drop_position_str = "into or before"; | ||
1771 | 1282 | break; | ||
1772 | 1283 | case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: | ||
1773 | 1284 | drop_position_str = "into or after"; | ||
1774 | 1285 | break; | ||
1775 | 1286 | } | ||
1776 | 1287 | |||
1777 | 1288 | g_print ("%s: row drop possible (%s)\n", dest_path_str, drop_position_str); | ||
1778 | 1289 | g_free (dest_path_str); | ||
1779 | 1290 | } | ||
1780 | 1291 | #endif /* DEBUG_DROP */ | ||
1781 | 1292 | |||
1782 | 1293 | return row_drop_possible; | ||
1783 | 1294 | } | ||
1784 | 1295 | |||
1785 | 1296 | static void | ||
1786 | 1297 | copy_node_data (GtkTreeStore *src_store, | ||
1787 | 1298 | GtkTreeIter *src_iter, | ||
1788 | 1299 | GtkTreeStore *dest_store, | ||
1789 | 1300 | GtkTreeIter *dest_iter) | ||
1790 | 1301 | { | ||
1791 | 1302 | gint i; | ||
1792 | 1303 | gint n_columns; | ||
1793 | 1304 | GtkTreeModel* src_model = GTK_TREE_MODEL (src_store); | ||
1794 | 1305 | |||
1795 | 1306 | n_columns = gtk_tree_model_get_n_columns (src_model); | ||
1796 | 1307 | |||
1797 | 1308 | for (i = 0; i < n_columns; i++) | ||
1798 | 1309 | { | ||
1799 | 1310 | void *item; | ||
1800 | 1311 | |||
1801 | 1312 | gtk_tree_model_get (src_model, src_iter, i, &item, -1); | ||
1802 | 1313 | gtk_tree_store_set (dest_store, dest_iter, i, item, -1); | ||
1803 | 1314 | } | ||
1804 | 1315 | } | ||
1805 | 1316 | |||
1806 | 1317 | static void | ||
1807 | 1318 | recursive_node_copy (GtkTreeStore *src_store, | ||
1808 | 1319 | GtkTreeIter *src_iter, | ||
1809 | 1320 | GtkTreeStore *dest_store, | ||
1810 | 1321 | GtkTreeIter *dest_iter) | ||
1811 | 1322 | { | ||
1812 | 1323 | GtkTreeIter child; | ||
1813 | 1324 | GtkTreeModel *src_model = GTK_TREE_MODEL (src_store); | ||
1814 | 1325 | |||
1815 | 1326 | copy_node_data (src_store, src_iter, dest_store, dest_iter); | ||
1816 | 1327 | |||
1817 | 1328 | if (gtk_tree_model_iter_children (src_model, &child, src_iter)) | ||
1818 | 1329 | { | ||
1819 | 1330 | /* Need to create children and recurse. Note our | ||
1820 | 1331 | * dependence on persistent iterators here. | ||
1821 | 1332 | */ | ||
1822 | 1333 | do | ||
1823 | 1334 | { | ||
1824 | 1335 | GtkTreeIter copy; | ||
1825 | 1336 | |||
1826 | 1337 | /* Gee, a really slow algorithm... ;-) FIXME */ | ||
1827 | 1338 | gtk_tree_store_append (dest_store, | ||
1828 | 1339 | ©, | ||
1829 | 1340 | dest_iter); | ||
1830 | 1341 | |||
1831 | 1342 | recursive_node_copy (src_store, &child, dest_store, ©); | ||
1832 | 1343 | } | ||
1833 | 1344 | while (gtk_tree_model_iter_next (src_model, &child)); | ||
1834 | 1345 | } | ||
1835 | 1346 | } | ||
1836 | 1347 | |||
1837 | 1348 | static gboolean | ||
1838 | 1349 | midori_bookmarks_tree_store_drag_data_received (GtkTreeDragDest *drag_dest, | ||
1839 | 1350 | GtkTreePath *dest_path, | ||
1840 | 1351 | GtkSelectionData *selection_data) | ||
1841 | 1352 | { | ||
1842 | 1353 | gboolean status = TRUE; | ||
1843 | 1354 | |||
1844 | 1355 | g_return_val_if_fail (selection_data != NULL, FALSE); | ||
1845 | 1356 | g_return_val_if_fail (GTK_IS_TREE_MODEL (drag_dest), FALSE); | ||
1846 | 1357 | g_return_val_if_fail (dest_path != NULL, FALSE); | ||
1847 | 1358 | |||
1848 | 1359 | if (gtk_selection_data_get_target (selection_data) == | ||
1849 | 1360 | gdk_atom_intern_static_string (MIDORI_BOOKMARKS_TREE_MODEL_TARGET)) | ||
1850 | 1361 | { | ||
1851 | 1362 | GtkTreeStore *dest_store = GTK_TREE_STORE (drag_dest); | ||
1852 | 1363 | GtkTreeModel *dest_model = GTK_TREE_MODEL (drag_dest); | ||
1853 | 1364 | GtkTreeModel *src_model; | ||
1854 | 1365 | GList* rows; | ||
1855 | 1366 | |||
1856 | 1367 | if (midori_bookmarks_tree_store_get_rows_drag_data (selection_data, | ||
1857 | 1368 | &src_model, &rows)) | ||
1858 | 1369 | { | ||
1859 | 1370 | GtkTreeStore *src_store = GTK_TREE_STORE (src_model); | ||
1860 | 1371 | GtkTreePath *prev = gtk_tree_path_copy (dest_path); | ||
1861 | 1372 | |||
1862 | 1373 | gint count = 0; | ||
1863 | 1374 | gint length = g_list_length (rows); | ||
1864 | 1375 | gint i; | ||
1865 | 1376 | |||
1866 | 1377 | for (i = 0; i < length; i++) | ||
1867 | 1378 | { | ||
1868 | 1379 | GtkTreeIter dest_iter; | ||
1869 | 1380 | GtkTreeIter src_iter; | ||
1870 | 1381 | GtkTreePath *src_path = (GtkTreePath *)g_list_nth_data (rows, i); | ||
1871 | 1382 | |||
1872 | 1383 | if (!gtk_tree_model_get_iter (src_model, &src_iter, src_path)) | ||
1873 | 1384 | continue; | ||
1874 | 1385 | |||
1875 | 1386 | /* Get the path to insert _after_ (dest is the path to insert _before_) */ | ||
1876 | 1387 | if (i == 0) | ||
1877 | 1388 | { | ||
1878 | 1389 | if (!gtk_tree_path_prev (prev)) | ||
1879 | 1390 | { /* Get the parent, NULL if parent is the root */ | ||
1880 | 1391 | GtkTreeIter dest_parent; | ||
1881 | 1392 | GtkTreePath *parent = gtk_tree_path_copy (dest_path); | ||
1882 | 1393 | GtkTreeIter *dest_parent_p = NULL; | ||
1883 | 1394 | |||
1884 | 1395 | if (gtk_tree_path_up (parent) && | ||
1885 | 1396 | gtk_tree_path_get_depth (parent) > 0) | ||
1886 | 1397 | { | ||
1887 | 1398 | gtk_tree_model_get_iter (dest_model, | ||
1888 | 1399 | &dest_parent, parent); | ||
1889 | 1400 | dest_parent_p = &dest_parent; | ||
1890 | 1401 | } | ||
1891 | 1402 | gtk_tree_path_free (parent); | ||
1892 | 1403 | |||
1893 | 1404 | gtk_tree_store_prepend (dest_store, &dest_iter, dest_parent_p); | ||
1894 | 1405 | } | ||
1895 | 1406 | else if (gtk_tree_model_get_iter (dest_model, &dest_iter, prev)) | ||
1896 | 1407 | { | ||
1897 | 1408 | GtkTreeIter tmp_iter = dest_iter; | ||
1898 | 1409 | |||
1899 | 1410 | gtk_tree_store_insert_after (dest_store, &dest_iter, NULL, | ||
1900 | 1411 | &tmp_iter); | ||
1901 | 1412 | } | ||
1902 | 1413 | } | ||
1903 | 1414 | else if (gtk_tree_model_get_iter (dest_model, &dest_iter, prev)) | ||
1904 | 1415 | { | ||
1905 | 1416 | GtkTreeIter tmp_iter = dest_iter; | ||
1906 | 1417 | |||
1907 | 1418 | gtk_tree_store_insert_after (dest_store, &dest_iter, NULL, | ||
1908 | 1419 | &tmp_iter); | ||
1909 | 1420 | } | ||
1910 | 1421 | |||
1911 | 1422 | gtk_tree_path_free (prev); | ||
1912 | 1423 | |||
1913 | 1424 | recursive_node_copy (src_store, &src_iter, dest_store, &dest_iter); | ||
1914 | 1425 | count++; | ||
1915 | 1426 | |||
1916 | 1427 | prev = gtk_tree_model_get_path (dest_model, &dest_iter); | ||
1917 | 1428 | |||
1918 | 1429 | if (src_store != dest_store) | ||
1919 | 1430 | continue; | ||
1920 | 1431 | |||
1921 | 1432 | update_path_list_for_insert (rows, prev); | ||
1922 | 1433 | } | ||
1923 | 1434 | |||
1924 | 1435 | gtk_tree_path_free (prev); | ||
1925 | 1436 | |||
1926 | 1437 | g_assert (count == length); | ||
1927 | 1438 | |||
1928 | 1439 | if (src_store == dest_store) | ||
1929 | 1440 | { | ||
1930 | 1441 | MidoriBookmarksTreeStore *tree_store = MIDORI_BOOKMARKS_TREE_STORE(src_store); | ||
1931 | 1442 | |||
1932 | 1443 | g_list_free_full (tree_store->stock_got_rows, (GDestroyNotify) gtk_tree_path_free); | ||
1933 | 1444 | tree_store->stock_got_rows = rows; | ||
1934 | 1445 | } | ||
1935 | 1446 | else | ||
1936 | 1447 | g_list_free_full (rows, (GDestroyNotify) gtk_tree_path_free); | ||
1937 | 1448 | } | ||
1938 | 1449 | } | ||
1939 | 1450 | |||
1940 | 1451 | return status; | ||
1941 | 1452 | } | ||
1942 | 1453 | |||
1943 | 1454 | static void | ||
1944 | 1455 | midori_bookmarks_set_item_positon (GtkTreeModel* model, | ||
1945 | 1456 | GtkTreeIter* iter, | ||
1946 | 1457 | gint64 parentid, | ||
1947 | 1458 | MidoriBookmarks* bookmarks) | ||
1948 | 1459 | { | ||
1949 | 1460 | KatzeItem* item; | ||
1950 | 1461 | gint position = 0; | ||
1951 | 1462 | GtkTreeIter next = *iter; | ||
1952 | 1463 | |||
1953 | 1464 | do { | ||
1954 | 1465 | gboolean update = FALSE; | ||
1955 | 1466 | gtk_tree_model_get (model, &next, 0, &item, -1); | ||
1956 | 1467 | |||
1957 | 1468 | if (!KATZE_IS_ITEM (item)) | ||
1958 | 1469 | continue; | ||
1959 | 1470 | |||
1960 | 1471 | if (position != katze_item_get_meta_integer (item, "pos_panel")) | ||
1961 | 1472 | { | ||
1962 | 1473 | katze_item_set_meta_integer (item, "pos_panel", position); | ||
1963 | 1474 | update = TRUE; | ||
1964 | 1475 | } | ||
1965 | 1476 | if (parentid != katze_item_get_meta_integer (item, "parentid")) | ||
1966 | 1477 | { | ||
1967 | 1478 | katze_item_set_meta_integer (item, "parentid", parentid); | ||
1968 | 1479 | update = TRUE; | ||
1969 | 1480 | } | ||
1970 | 1481 | |||
1971 | 1482 | if (update) | ||
1972 | 1483 | midori_bookmarks_update_item (bookmarks, item); | ||
1973 | 1484 | |||
1974 | 1485 | position++; | ||
1975 | 1486 | |||
1976 | 1487 | g_object_unref (item); | ||
1977 | 1488 | } | ||
1978 | 1489 | while (gtk_tree_model_iter_next (model, &next)); | ||
1979 | 1490 | } | ||
1980 | 1491 | |||
1981 | 1492 | static void | ||
1982 | 1493 | assert_reorder_are_folders (GtkTreeModel* model, | ||
1983 | 1494 | MidoriBookmarks* bookmarks) | ||
1984 | 1495 | { | ||
1985 | 1496 | GList* iter; | ||
1986 | 1497 | for (iter = bookmarks->reordered_paths; iter ; iter = g_list_next (iter)) | ||
1987 | 1498 | { | ||
1988 | 1499 | GtkTreePath* path = (GtkTreePath*)iter->data; | ||
1989 | 1500 | GtkTreeIter tree_iter; | ||
1990 | 1501 | |||
1991 | 1502 | if (!gtk_tree_path_get_depth (path)) | ||
1992 | 1503 | continue; | ||
1993 | 1504 | |||
1994 | 1505 | if (gtk_tree_model_get_iter (model, &tree_iter, path)) | ||
1995 | 1506 | { | ||
1996 | 1507 | KatzeItem *item; | ||
1997 | 1508 | |||
1998 | 1509 | gtk_tree_model_get (model, &tree_iter, 0, &item, -1); | ||
1999 | 1510 | |||
2000 | 1511 | g_assert (KATZE_ITEM_IS_FOLDER (item)); | ||
2001 | 1512 | } | ||
2002 | 1513 | } | ||
2003 | 1514 | } | ||
2004 | 1515 | |||
2005 | 1516 | static void | ||
2006 | 1517 | add_parent_to_reorder (GtkTreeModel* model, | ||
2007 | 1518 | GtkTreePath* path, | ||
2008 | 1519 | MidoriBookmarks* bookmarks) | ||
2009 | 1520 | { | ||
2010 | 1521 | GtkTreePath* path_copy = gtk_tree_path_copy (path); | ||
2011 | 1522 | GList* found; | ||
2012 | 1523 | |||
2013 | 1524 | midori_bookmarks_idle_start (bookmarks); | ||
2014 | 1525 | |||
2015 | 1526 | if (gtk_tree_path_get_depth (path_copy) > 1 | ||
2016 | 1527 | && gtk_tree_path_up (path_copy)) | ||
2017 | 1528 | { | ||
2018 | 1529 | GtkTreeIter iter; | ||
2019 | 1530 | if (gtk_tree_model_get_iter (model, &iter, path_copy)) | ||
2020 | 1531 | { | ||
2021 | 1532 | KatzeItem* item; | ||
2022 | 1533 | gtk_tree_model_get (model, &iter, 0, &item, -1); | ||
2023 | 1534 | if (item) | ||
2024 | 1535 | { | ||
2025 | 1536 | g_assert (KATZE_ITEM_IS_FOLDER (item)); | ||
2026 | 1537 | g_object_unref (item); | ||
2027 | 1538 | } | ||
2028 | 1539 | else | ||
2029 | 1540 | g_assert_not_reached (); | ||
2030 | 1541 | } | ||
2031 | 1542 | else | ||
2032 | 1543 | g_assert_not_reached (); | ||
2033 | 1544 | } | ||
2034 | 1545 | else | ||
2035 | 1546 | { | ||
2036 | 1547 | gtk_tree_path_free (path_copy); | ||
2037 | 1548 | path_copy = gtk_tree_path_new (); | ||
2038 | 1549 | } | ||
2039 | 1550 | |||
2040 | 1551 | if ((found = g_list_find_custom (bookmarks->reordered_paths, | ||
2041 | 1552 | path_copy, (GCompareFunc)midori_tree_path_compare)) != NULL) | ||
2042 | 1553 | { | ||
2043 | 1554 | gtk_tree_path_free (path_copy); | ||
2044 | 1555 | return; | ||
2045 | 1556 | } | ||
2046 | 1557 | |||
2047 | 1558 | bookmarks->reordered_paths = g_list_append (bookmarks->reordered_paths, path_copy); | ||
2048 | 1559 | } | ||
2049 | 1560 | |||
2050 | 1561 | static void | ||
2051 | 1562 | midori_bookmarks_row_inserted_cb (GtkTreeModel* model, | ||
2052 | 1563 | GtkTreePath* path, | ||
2053 | 1564 | GtkTreeIter* iter, | ||
2054 | 1565 | MidoriBookmarks* bookmarks) | ||
2055 | 1566 | { | ||
2056 | 1567 | midori_bookmarks_idle_start (bookmarks); | ||
2057 | 1568 | |||
2058 | 1569 | update_path_list_for_insert (bookmarks->added_paths, path); | ||
2059 | 1570 | update_path_list_for_insert (bookmarks->reordered_paths, path); | ||
2060 | 1571 | assert_reorder_are_folders (model, bookmarks); | ||
2061 | 1572 | |||
2062 | 1573 | if (g_list_find_custom (bookmarks->added_paths, | ||
2063 | 1574 | path, (GCompareFunc)midori_tree_path_compare)) | ||
2064 | 1575 | return; | ||
2065 | 1576 | |||
2066 | 1577 | bookmarks->added_paths = g_list_append (bookmarks->added_paths, gtk_tree_path_copy (path)); | ||
2067 | 1578 | } | ||
2068 | 1579 | |||
2069 | 1580 | #ifdef DEBUG_LIST | ||
2070 | 1581 | static void | ||
2071 | 1582 | print_path_list (GList* iter) | ||
2072 | 1583 | { | ||
2073 | 1584 | for ( ; iter ; iter = g_list_next (iter)) | ||
2074 | 1585 | { | ||
2075 | 1586 | gchar* str = gtk_tree_path_to_string ((GtkTreePath*)iter->data); | ||
2076 | 1587 | g_print ("%s ", str); | ||
2077 | 1588 | g_free (str); | ||
2078 | 1589 | } | ||
2079 | 1590 | g_print ("\n"); | ||
2080 | 1591 | } | ||
2081 | 1592 | #endif /* DEBUG_LIST */ | ||
2082 | 1593 | |||
2083 | 1594 | static void | ||
2084 | 1595 | midori_bookmarks_row_deleted_cb (GtkTreeModel* model, | ||
2085 | 1596 | GtkTreePath* path, | ||
2086 | 1597 | MidoriBookmarks* bookmarks) | ||
2087 | 1598 | { | ||
2088 | 1599 | #ifdef DEBUG_LIST | ||
2089 | 1600 | gchar* str = gtk_tree_path_to_string (path); | ||
2090 | 1601 | g_print ("midori_bookmarks_row_deleted_cb: path: %s\n", str); | ||
2091 | 1602 | g_free (str); | ||
2092 | 1603 | #endif /* DEBUG_LIST */ | ||
2093 | 1604 | |||
2094 | 1605 | midori_bookmarks_idle_start (bookmarks); | ||
2095 | 1606 | |||
2096 | 1607 | bookmarks->added_paths = update_path_list_for_delete (bookmarks->added_paths, path); | ||
2097 | 1608 | #ifdef DEBUG_LIST | ||
2098 | 1609 | print_path_list (bookmarks->reordered_paths); | ||
2099 | 1610 | #endif /* DEBUG_LIST */ | ||
2100 | 1611 | bookmarks->reordered_paths = update_path_list_for_delete (bookmarks->reordered_paths, path); | ||
2101 | 1612 | #ifdef DEBUG_LIST | ||
2102 | 1613 | print_path_list (bookmarks->reordered_paths); | ||
2103 | 1614 | #endif /* DEBUG_LIST */ | ||
2104 | 1615 | assert_reorder_are_folders (model, bookmarks); | ||
2105 | 1616 | add_parent_to_reorder (model, path, bookmarks); | ||
2106 | 1617 | assert_reorder_are_folders (model, bookmarks); | ||
2107 | 1618 | } | ||
2108 | 495 | 1619 | ||
2109 | 496 | static void | 1620 | static void |
2110 | 497 | midori_bookmarks_row_changed_cb (GtkTreeModel* model, | 1621 | midori_bookmarks_row_changed_cb (GtkTreeModel* model, |
2111 | @@ -499,41 +1623,8 @@ | |||
2112 | 499 | GtkTreeIter* iter, | 1623 | GtkTreeIter* iter, |
2113 | 500 | MidoriBookmarks* bookmarks) | 1624 | MidoriBookmarks* bookmarks) |
2114 | 501 | { | 1625 | { |
2150 | 502 | KatzeItem* item; | 1626 | add_parent_to_reorder (model, path, bookmarks); |
2151 | 503 | GtkTreeIter parent; | 1627 | assert_reorder_are_folders (model, bookmarks); |
2117 | 504 | KatzeItem* new_parent = NULL; | ||
2118 | 505 | gint64 parentid; | ||
2119 | 506 | |||
2120 | 507 | gtk_tree_model_get (model, iter, 0, &item, -1); | ||
2121 | 508 | |||
2122 | 509 | if (gtk_tree_model_iter_parent (model, &parent, iter)) | ||
2123 | 510 | { | ||
2124 | 511 | gtk_tree_model_get (model, &parent, 0, &new_parent, -1); | ||
2125 | 512 | |||
2126 | 513 | /* Bookmarks must not be moved into non-folder items */ | ||
2127 | 514 | if (!KATZE_ITEM_IS_FOLDER (new_parent)) | ||
2128 | 515 | parentid = 0; | ||
2129 | 516 | else | ||
2130 | 517 | parentid = katze_item_get_meta_integer (new_parent, "id"); | ||
2131 | 518 | } | ||
2132 | 519 | else | ||
2133 | 520 | parentid = 0; | ||
2134 | 521 | |||
2135 | 522 | katze_item_set_meta_integer (item, "parentid", parentid); | ||
2136 | 523 | |||
2137 | 524 | g_signal_handlers_block_by_func (bookmarks->bookmarks_db, | ||
2138 | 525 | midori_bookmarks_update_item_cb, | ||
2139 | 526 | bookmarks); | ||
2140 | 527 | |||
2141 | 528 | midori_bookmarks_db_update_item (bookmarks->bookmarks_db, item); | ||
2142 | 529 | |||
2143 | 530 | g_signal_handlers_unblock_by_func (bookmarks->bookmarks_db, | ||
2144 | 531 | midori_bookmarks_update_item_cb, | ||
2145 | 532 | bookmarks); | ||
2146 | 533 | |||
2147 | 534 | g_object_unref (item); | ||
2148 | 535 | if (new_parent) | ||
2149 | 536 | g_object_unref (new_parent); | ||
2152 | 537 | } | 1628 | } |
2153 | 538 | 1629 | ||
2154 | 539 | static void | 1630 | static void |
2155 | @@ -596,7 +1687,7 @@ | |||
2156 | 596 | GtkTreeIter iter; | 1687 | GtkTreeIter iter; |
2157 | 597 | 1688 | ||
2158 | 598 | if (katze_tree_view_get_selected_iter (GTK_TREE_VIEW (bookmarks->treeview), | 1689 | if (katze_tree_view_get_selected_iter (GTK_TREE_VIEW (bookmarks->treeview), |
2160 | 599 | &model, &iter)) | 1690 | &model, &iter)) |
2161 | 600 | { | 1691 | { |
2162 | 601 | KatzeItem* item; | 1692 | KatzeItem* item; |
2163 | 602 | MidoriBrowser* browser; | 1693 | MidoriBrowser* browser; |
2164 | @@ -616,15 +1707,17 @@ | |||
2165 | 616 | static void | 1707 | static void |
2166 | 617 | midori_bookmarks_toolbar_update (MidoriBookmarks *bookmarks) | 1708 | midori_bookmarks_toolbar_update (MidoriBookmarks *bookmarks) |
2167 | 618 | { | 1709 | { |
2169 | 619 | gboolean selected; | 1710 | gint selected; |
2170 | 620 | 1711 | ||
2172 | 621 | selected = katze_tree_view_get_selected_iter ( | 1712 | selected = katze_tree_view_get_selected_rows ( |
2173 | 622 | GTK_TREE_VIEW (bookmarks->treeview), NULL, NULL); | 1713 | GTK_TREE_VIEW (bookmarks->treeview), NULL, NULL); |
2176 | 623 | gtk_widget_set_sensitive (GTK_WIDGET (bookmarks->delete), selected); | 1714 | gtk_widget_set_sensitive ( |
2177 | 624 | gtk_widget_set_sensitive (GTK_WIDGET (bookmarks->edit), selected); | 1715 | GTK_WIDGET (bookmarks->delete), (selected > 0 ? TRUE : FALSE)); |
2178 | 1716 | gtk_widget_set_sensitive ( | ||
2179 | 1717 | GTK_WIDGET (bookmarks->edit), (selected == 1 ? TRUE : FALSE)); | ||
2180 | 625 | } | 1718 | } |
2181 | 626 | 1719 | ||
2183 | 627 | static gchar* | 1720 | static gchar* |
2184 | 628 | midori_bookmarks_statusbar_bookmarks_str (gint count) | 1721 | midori_bookmarks_statusbar_bookmarks_str (gint count) |
2185 | 629 | { | 1722 | { |
2186 | 630 | if (!count) | 1723 | if (!count) |
2187 | @@ -634,7 +1727,7 @@ | |||
2188 | 634 | return g_strdup_printf (ngettext ("%d bookmark", "%d bookmarks", count), count); | 1727 | return g_strdup_printf (ngettext ("%d bookmark", "%d bookmarks", count), count); |
2189 | 635 | } | 1728 | } |
2190 | 636 | 1729 | ||
2192 | 637 | static gchar* | 1730 | static gchar* |
2193 | 638 | midori_bookmarks_statusbar_subfolders_str (gint count) | 1731 | midori_bookmarks_statusbar_subfolders_str (gint count) |
2194 | 639 | { | 1732 | { |
2195 | 640 | if (!count) | 1733 | if (!count) |
2196 | @@ -648,78 +1741,141 @@ | |||
2197 | 648 | midori_bookmarks_statusbar_update (MidoriBookmarks *bookmarks) | 1741 | midori_bookmarks_statusbar_update (MidoriBookmarks *bookmarks) |
2198 | 649 | { | 1742 | { |
2199 | 650 | gchar* text = NULL; | 1743 | gchar* text = NULL; |
2208 | 651 | 1744 | GtkTreeModel* model; | |
2209 | 652 | if (bookmarks->hovering_item) | 1745 | GList *rows; |
2210 | 653 | { | 1746 | gint selected; |
2211 | 654 | KatzeItem* item = bookmarks->hovering_item; | 1747 | |
2212 | 655 | 1748 | selected = katze_tree_view_get_selected_rows ( | |
2213 | 656 | g_assert (!KATZE_ITEM_IS_SEPARATOR (item)); | 1749 | GTK_TREE_VIEW (bookmarks->treeview), &model, &rows); |
2214 | 657 | 1750 | ||
2215 | 658 | if (KATZE_ITEM_IS_FOLDER (item)) | 1751 | if (selected > 1) |
2216 | 1752 | { | ||
2217 | 1753 | gint i; | ||
2218 | 1754 | gint selected_folders_count = 0; | ||
2219 | 1755 | gint selected_bookmarks_count = 0; | ||
2220 | 1756 | gchar* selected_folders_str = midori_bookmarks_statusbar_subfolders_str (selected_folders_count); | ||
2221 | 1757 | gchar* selected_bookmarks_str = midori_bookmarks_statusbar_bookmarks_str (selected_bookmarks_count); | ||
2222 | 1758 | |||
2223 | 1759 | for (i = 0 ; i < selected ; i++) | ||
2224 | 1760 | { | ||
2225 | 1761 | GtkTreeIter iter; | ||
2226 | 1762 | KatzeItem* item; | ||
2227 | 1763 | |||
2228 | 1764 | if (!gtk_tree_model_get_iter ( | ||
2229 | 1765 | model, &iter, (GtkTreePath *)g_list_nth_data (rows, i))) | ||
2230 | 1766 | continue; | ||
2231 | 1767 | |||
2232 | 1768 | gtk_tree_model_get (model, &iter, 0, &item, -1); | ||
2233 | 1769 | |||
2234 | 1770 | g_assert (!KATZE_ITEM_IS_SEPARATOR (item)); | ||
2235 | 1771 | |||
2236 | 1772 | if (KATZE_ITEM_IS_FOLDER (item)) | ||
2237 | 1773 | { | ||
2238 | 1774 | selected_folders_count++; | ||
2239 | 1775 | } | ||
2240 | 1776 | else | ||
2241 | 1777 | { | ||
2242 | 1778 | selected_bookmarks_count++; | ||
2243 | 1779 | } | ||
2244 | 1780 | } | ||
2245 | 1781 | |||
2246 | 1782 | selected_folders_str = midori_bookmarks_statusbar_subfolders_str (selected_folders_count); | ||
2247 | 1783 | selected_bookmarks_str = midori_bookmarks_statusbar_bookmarks_str (selected_bookmarks_count); | ||
2248 | 1784 | |||
2249 | 1785 | if (!selected_bookmarks_count && !selected_folders_count) | ||
2250 | 1786 | g_assert_not_reached (); | ||
2251 | 1787 | else if (!selected_bookmarks_count && (selected_folders_count >= 1)) | ||
2252 | 1788 | /* i18n: Selection containing [[n] folder(s)] and no bookmark */ | ||
2253 | 1789 | text = g_strdup_printf (_("Selection containing %s and no bookmark"), | ||
2254 | 1790 | selected_folders_str); | ||
2255 | 1791 | else if ((selected_bookmarks_count >= 1) && !selected_folders_count) | ||
2256 | 1792 | /* i18n: Selection containing [[n] bookmark(s)] */ | ||
2257 | 1793 | text = g_strdup_printf (_("Selection containing %s"), selected_bookmarks_str); | ||
2258 | 1794 | else if ((selected_bookmarks_count >= 1) && (selected_folders_count >= 1)) | ||
2259 | 1795 | /* i18n: Selection containing [[n] bookmark(s)] and [[n] folder(s)] */ | ||
2260 | 1796 | text = g_strdup_printf (_("Selection containing %s and %s"), | ||
2261 | 1797 | selected_bookmarks_str, selected_folders_str); | ||
2262 | 1798 | |||
2263 | 1799 | g_free (selected_folders_str); | ||
2264 | 1800 | g_free (selected_bookmarks_str); | ||
2265 | 1801 | |||
2266 | 1802 | g_list_free_full (rows, (GDestroyNotify) gtk_tree_path_free); | ||
2267 | 1803 | } | ||
2268 | 1804 | else | ||
2269 | 1805 | { | ||
2270 | 1806 | if (selected) | ||
2271 | 1807 | g_list_free_full (rows, (GDestroyNotify) gtk_tree_path_free); | ||
2272 | 1808 | |||
2273 | 1809 | if (bookmarks->hovering_item) | ||
2274 | 1810 | { | ||
2275 | 1811 | KatzeItem* item = bookmarks->hovering_item; | ||
2276 | 1812 | |||
2277 | 1813 | if (KATZE_ITEM_IS_FOLDER (item)) | ||
2278 | 1814 | { | ||
2279 | 1815 | gint child_folders_count = midori_bookmarks_db_count_recursive (bookmarks->bookmarks_db, | ||
2280 | 1816 | "uri = ''", NULL, item, FALSE); | ||
2281 | 1817 | gint child_bookmarks_count = midori_bookmarks_db_count_recursive (bookmarks->bookmarks_db, | ||
2282 | 1818 | "uri <> ''", NULL, item, FALSE); | ||
2283 | 1819 | gchar* child_folders_str = midori_bookmarks_statusbar_subfolders_str (child_folders_count); | ||
2284 | 1820 | gchar* child_bookmarks_str = midori_bookmarks_statusbar_bookmarks_str (child_bookmarks_count); | ||
2285 | 1821 | |||
2286 | 1822 | if (!child_bookmarks_count && !child_folders_count) | ||
2287 | 1823 | /* i18n: Empty folder */ | ||
2288 | 1824 | text = g_strdup_printf (_("Empty folder")); | ||
2289 | 1825 | else if (!child_bookmarks_count && (child_folders_count >= 1)) | ||
2290 | 1826 | /* i18n: Folder containing [[n] folder(s)] and no bookmark */ | ||
2291 | 1827 | text = g_strdup_printf (_("Folder containing %s and no bookmark"), | ||
2292 | 1828 | child_folders_str); | ||
2293 | 1829 | else if ((child_bookmarks_count >= 1) && !child_folders_count) | ||
2294 | 1830 | /* i18n: Folder containing [[n] bookmark(s)] */ | ||
2295 | 1831 | text = g_strdup_printf (_("Folder containing %s"), child_bookmarks_str); | ||
2296 | 1832 | else if ((child_bookmarks_count >= 1) && (child_folders_count >= 1)) | ||
2297 | 1833 | /* i18n: Folder containing [[n] bookmark(s)] and [[n] folder(s)] */ | ||
2298 | 1834 | text = g_strdup_printf (_("Folder containing %s and %s"), | ||
2299 | 1835 | child_bookmarks_str, child_folders_str); | ||
2300 | 1836 | |||
2301 | 1837 | g_free (child_folders_str); | ||
2302 | 1838 | g_free (child_bookmarks_str); | ||
2303 | 1839 | } | ||
2304 | 1840 | else if (KATZE_ITEM_IS_BOOKMARK (item)) | ||
2305 | 1841 | { | ||
2306 | 1842 | const gchar* uri = katze_item_get_uri (item); | ||
2307 | 1843 | |||
2308 | 1844 | /* i18n: Bookmark leading to: [bookmark uri] */ | ||
2309 | 1845 | text = g_strdup_printf (_("Bookmark leading to: %s"), uri); | ||
2310 | 1846 | } | ||
2311 | 1847 | } | ||
2312 | 1848 | else | ||
2313 | 659 | { | 1849 | { |
2314 | 660 | gint child_folders_count = midori_bookmarks_db_count_recursive (bookmarks->bookmarks_db, | 1850 | gint child_folders_count = midori_bookmarks_db_count_recursive (bookmarks->bookmarks_db, |
2316 | 661 | "uri = ''", NULL, item, FALSE); | 1851 | "uri = ''", NULL, NULL, FALSE); |
2317 | 662 | gint child_bookmarks_count = midori_bookmarks_db_count_recursive (bookmarks->bookmarks_db, | 1852 | gint child_bookmarks_count = midori_bookmarks_db_count_recursive (bookmarks->bookmarks_db, |
2319 | 663 | "uri <> ''", NULL, item, FALSE); | 1853 | "uri <> ''", NULL, NULL, FALSE); |
2320 | 664 | gchar* child_folders_str = midori_bookmarks_statusbar_subfolders_str (child_folders_count); | 1854 | gchar* child_folders_str = midori_bookmarks_statusbar_subfolders_str (child_folders_count); |
2321 | 665 | gchar* child_bookmarks_str = midori_bookmarks_statusbar_bookmarks_str (child_bookmarks_count); | 1855 | gchar* child_bookmarks_str = midori_bookmarks_statusbar_bookmarks_str (child_bookmarks_count); |
2322 | 666 | 1856 | ||
2329 | 667 | if (!child_bookmarks_count && !child_folders_count) | 1857 | if (!child_bookmarks_count && (child_folders_count >= 1)) |
2330 | 668 | /* i18n: Empty folder */ | 1858 | /* i18n: [[n] folder(s)] and no bookmark */ |
2331 | 669 | text = g_strdup_printf (_("Empty folder")); | 1859 | text = g_strdup_printf (_("%s and no bookmark"), |
2326 | 670 | else if (!child_bookmarks_count && (child_folders_count >= 1)) | ||
2327 | 671 | /* i18n: Folder containing [[n] folder(s)] and no bookmark */ | ||
2328 | 672 | text = g_strdup_printf (_("Folder containing %s and no bookmark"), | ||
2332 | 673 | child_folders_str); | 1860 | child_folders_str); |
2333 | 674 | else if ((child_bookmarks_count >= 1) && !child_folders_count) | 1861 | else if ((child_bookmarks_count >= 1) && !child_folders_count) |
2336 | 675 | /* i18n: Folder containing [[n] bookmark(s)] */ | 1862 | text = g_strdup (child_bookmarks_str); |
2335 | 676 | text = g_strdup_printf (_("Folder containing %s"), child_bookmarks_str); | ||
2337 | 677 | else if ((child_bookmarks_count >= 1) && (child_folders_count >= 1)) | 1863 | else if ((child_bookmarks_count >= 1) && (child_folders_count >= 1)) |
2340 | 678 | /* i18n: Folder containing [[n] bookmark(s)] and [[n] folder(s)] */ | 1864 | /* i18n: [[n] bookmark(s)] and [[n] folder(s)] */ |
2341 | 679 | text = g_strdup_printf (_("Folder containing %s and %s"), | 1865 | text = g_strdup_printf (_("%s and %s"), |
2342 | 680 | child_bookmarks_str, child_folders_str); | 1866 | child_bookmarks_str, child_folders_str); |
2343 | 681 | 1867 | ||
2344 | 682 | g_free (child_folders_str); | 1868 | g_free (child_folders_str); |
2345 | 683 | g_free (child_bookmarks_str); | 1869 | g_free (child_bookmarks_str); |
2346 | 684 | } | 1870 | } |
2347 | 685 | else if (KATZE_ITEM_IS_BOOKMARK (item)) | ||
2348 | 686 | { | ||
2349 | 687 | const gchar* uri = katze_item_get_uri (item); | ||
2350 | 688 | |||
2351 | 689 | /* i18n: Bookmark leading to: [bookmark uri] */ | ||
2352 | 690 | text = g_strdup_printf (_("Bookmark leading to: %s"), uri); | ||
2353 | 691 | } | ||
2354 | 692 | } | ||
2355 | 693 | else | ||
2356 | 694 | { | ||
2357 | 695 | gint child_folders_count = midori_bookmarks_db_count_recursive (bookmarks->bookmarks_db, | ||
2358 | 696 | "uri = ''", NULL, NULL, FALSE); | ||
2359 | 697 | gint child_bookmarks_count = midori_bookmarks_db_count_recursive (bookmarks->bookmarks_db, | ||
2360 | 698 | "uri <> ''", NULL, NULL, FALSE); | ||
2361 | 699 | gchar* child_folders_str = midori_bookmarks_statusbar_subfolders_str (child_folders_count); | ||
2362 | 700 | gchar* child_bookmarks_str = midori_bookmarks_statusbar_bookmarks_str (child_bookmarks_count); | ||
2363 | 701 | |||
2364 | 702 | if (!child_bookmarks_count && (child_folders_count >= 1)) | ||
2365 | 703 | /* i18n: [[n] folder(s)] and no bookmark */ | ||
2366 | 704 | text = g_strdup_printf (_("%s and no bookmark"), | ||
2367 | 705 | child_folders_str); | ||
2368 | 706 | else if ((child_bookmarks_count >= 1) && !child_folders_count) | ||
2369 | 707 | text = g_strdup (child_bookmarks_str); | ||
2370 | 708 | else if ((child_bookmarks_count >= 1) && (child_folders_count >= 1)) | ||
2371 | 709 | /* i18n: [[n] bookmark(s)] and [[n] folder(s)] */ | ||
2372 | 710 | text = g_strdup_printf (_("%s and %s"), | ||
2373 | 711 | child_bookmarks_str, child_folders_str); | ||
2374 | 712 | |||
2375 | 713 | g_free (child_folders_str); | ||
2376 | 714 | g_free (child_bookmarks_str); | ||
2377 | 715 | } | 1871 | } |
2378 | 716 | 1872 | ||
2379 | 717 | if (text) | 1873 | if (text) |
2380 | 718 | { | 1874 | { |
2381 | 719 | MidoriBrowser* browser = midori_browser_get_for_widget (bookmarks->treeview); | 1875 | MidoriBrowser* browser = midori_browser_get_for_widget (bookmarks->treeview); |
2383 | 720 | 1876 | ||
2384 | 721 | g_object_set (browser, "statusbar-text", text, NULL); | 1877 | g_object_set (browser, "statusbar-text", text, NULL); |
2386 | 722 | 1878 | ||
2387 | 723 | g_free(text); | 1879 | g_free(text); |
2388 | 724 | } | 1880 | } |
2389 | 725 | } | 1881 | } |
2390 | @@ -729,19 +1885,33 @@ | |||
2391 | 729 | MidoriBookmarks* bookmarks) | 1885 | MidoriBookmarks* bookmarks) |
2392 | 730 | { | 1886 | { |
2393 | 731 | GtkTreeModel* model; | 1887 | GtkTreeModel* model; |
2398 | 732 | GtkTreeIter iter; | 1888 | GList* rows; |
2399 | 733 | 1889 | GList* iter_row; | |
2400 | 734 | if (katze_tree_view_get_selected_iter (GTK_TREE_VIEW (bookmarks->treeview), | 1890 | |
2401 | 735 | &model, &iter)) | 1891 | if (!katze_tree_view_get_selected_rows(GTK_TREE_VIEW (bookmarks->treeview), |
2402 | 1892 | &model, &rows)) | ||
2403 | 1893 | return; | ||
2404 | 1894 | |||
2405 | 1895 | for (iter_row = rows ; iter_row ; iter_row = g_list_next (iter_row)) | ||
2406 | 736 | { | 1896 | { |
2414 | 737 | KatzeItem* item; | 1897 | GtkTreeIter iter; |
2415 | 738 | 1898 | ||
2416 | 739 | gtk_tree_model_get (model, &iter, 0, &item, -1); | 1899 | if (gtk_tree_model_get_iter (model, &iter, (GtkTreePath *)iter_row->data)) |
2417 | 740 | 1900 | { | |
2418 | 741 | midori_bookmarks_db_remove_item (bookmarks->bookmarks_db, item); | 1901 | KatzeItem* item; |
2419 | 742 | 1902 | ||
2420 | 743 | g_object_unref (item); | 1903 | gtk_tree_model_get (model, &iter, 0, &item, -1); |
2421 | 1904 | |||
2422 | 1905 | if (item) | ||
2423 | 1906 | { | ||
2424 | 1907 | midori_bookmarks_db_remove_item (bookmarks->bookmarks_db, item); | ||
2425 | 1908 | |||
2426 | 1909 | g_object_unref (item); | ||
2427 | 1910 | } | ||
2428 | 1911 | } | ||
2429 | 744 | } | 1912 | } |
2430 | 1913 | |||
2431 | 1914 | g_list_free_full (rows, (GDestroyNotify) gtk_tree_path_free); | ||
2432 | 745 | } | 1915 | } |
2433 | 746 | 1916 | ||
2434 | 747 | static GtkWidget* | 1917 | static GtkWidget* |
2435 | @@ -759,7 +1929,7 @@ | |||
2436 | 759 | toolitem = gtk_tool_button_new_from_stock (STOCK_BOOKMARK_ADD); | 1929 | toolitem = gtk_tool_button_new_from_stock (STOCK_BOOKMARK_ADD); |
2437 | 760 | gtk_widget_set_name (GTK_WIDGET (toolitem), "BookmarkAdd"); | 1930 | gtk_widget_set_name (GTK_WIDGET (toolitem), "BookmarkAdd"); |
2438 | 761 | gtk_widget_set_tooltip_text (GTK_WIDGET (toolitem), | 1931 | gtk_widget_set_tooltip_text (GTK_WIDGET (toolitem), |
2440 | 762 | _("Add a new bookmark")); | 1932 | _("Add a new bookmark")); |
2441 | 763 | gtk_tool_item_set_is_important (toolitem, TRUE); | 1933 | gtk_tool_item_set_is_important (toolitem, TRUE); |
2442 | 764 | g_signal_connect (toolitem, "clicked", | 1934 | g_signal_connect (toolitem, "clicked", |
2443 | 765 | G_CALLBACK (midori_bookmarks_add_clicked_cb), bookmarks); | 1935 | G_CALLBACK (midori_bookmarks_add_clicked_cb), bookmarks); |
2444 | @@ -767,7 +1937,7 @@ | |||
2445 | 767 | gtk_widget_show (GTK_WIDGET (toolitem)); | 1937 | gtk_widget_show (GTK_WIDGET (toolitem)); |
2446 | 768 | toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_EDIT); | 1938 | toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_EDIT); |
2447 | 769 | gtk_widget_set_tooltip_text (GTK_WIDGET (toolitem), | 1939 | gtk_widget_set_tooltip_text (GTK_WIDGET (toolitem), |
2449 | 770 | _("Edit the selected bookmark")); | 1940 | _("Edit the selected bookmark")); |
2450 | 771 | g_signal_connect (toolitem, "clicked", | 1941 | g_signal_connect (toolitem, "clicked", |
2451 | 772 | G_CALLBACK (midori_bookmarks_edit_clicked_cb), bookmarks); | 1942 | G_CALLBACK (midori_bookmarks_edit_clicked_cb), bookmarks); |
2452 | 773 | gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1); | 1943 | gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1); |
2453 | @@ -775,7 +1945,7 @@ | |||
2454 | 775 | bookmarks->edit = GTK_WIDGET (toolitem); | 1945 | bookmarks->edit = GTK_WIDGET (toolitem); |
2455 | 776 | toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_DELETE); | 1946 | toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_DELETE); |
2456 | 777 | gtk_widget_set_tooltip_text (GTK_WIDGET (toolitem), | 1947 | gtk_widget_set_tooltip_text (GTK_WIDGET (toolitem), |
2458 | 778 | _("Delete the selected bookmark")); | 1948 | _("Delete the selected bookmark")); |
2459 | 779 | g_signal_connect (toolitem, "clicked", | 1949 | g_signal_connect (toolitem, "clicked", |
2460 | 780 | G_CALLBACK (midori_bookmarks_delete_clicked_cb), bookmarks); | 1950 | G_CALLBACK (midori_bookmarks_delete_clicked_cb), bookmarks); |
2461 | 781 | gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1); | 1951 | gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1); |
2462 | @@ -791,7 +1961,7 @@ | |||
2463 | 791 | toolitem = gtk_tool_button_new_from_stock (STOCK_FOLDER_NEW); | 1961 | toolitem = gtk_tool_button_new_from_stock (STOCK_FOLDER_NEW); |
2464 | 792 | gtk_widget_set_name (GTK_WIDGET (toolitem), "BookmarkFolderAdd"); | 1962 | gtk_widget_set_name (GTK_WIDGET (toolitem), "BookmarkFolderAdd"); |
2465 | 793 | gtk_widget_set_tooltip_text (GTK_WIDGET (toolitem), | 1963 | gtk_widget_set_tooltip_text (GTK_WIDGET (toolitem), |
2467 | 794 | _("Add a new folder")); | 1964 | _("Add a new folder")); |
2468 | 795 | g_signal_connect (toolitem, "clicked", | 1965 | g_signal_connect (toolitem, "clicked", |
2469 | 796 | G_CALLBACK (midori_bookmarks_add_clicked_cb), bookmarks); | 1966 | G_CALLBACK (midori_bookmarks_add_clicked_cb), bookmarks); |
2470 | 797 | gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1); | 1967 | gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1); |
2471 | @@ -841,6 +2011,12 @@ | |||
2472 | 841 | G_CALLBACK (midori_bookmarks_remove_item_cb), bookmarks); | 2011 | G_CALLBACK (midori_bookmarks_remove_item_cb), bookmarks); |
2473 | 842 | g_signal_connect (bookmarks->bookmarks_db, "update", | 2012 | g_signal_connect (bookmarks->bookmarks_db, "update", |
2474 | 843 | G_CALLBACK (midori_bookmarks_update_cb), bookmarks); | 2013 | G_CALLBACK (midori_bookmarks_update_cb), bookmarks); |
2475 | 2014 | g_signal_connect_after (model, "row-inserted", | ||
2476 | 2015 | G_CALLBACK (midori_bookmarks_row_inserted_cb), | ||
2477 | 2016 | bookmarks); | ||
2478 | 2017 | g_signal_connect_after (model, "row-deleted", | ||
2479 | 2018 | G_CALLBACK (midori_bookmarks_row_deleted_cb), | ||
2480 | 2019 | bookmarks); | ||
2481 | 844 | g_signal_connect_after (model, "row-changed", | 2020 | g_signal_connect_after (model, "row-changed", |
2482 | 845 | G_CALLBACK (midori_bookmarks_row_changed_cb), | 2021 | G_CALLBACK (midori_bookmarks_row_changed_cb), |
2483 | 846 | bookmarks); | 2022 | bookmarks); |
2484 | @@ -856,12 +2032,12 @@ | |||
2485 | 856 | 2032 | ||
2486 | 857 | switch (prop_id) | 2033 | switch (prop_id) |
2487 | 858 | { | 2034 | { |
2494 | 859 | case PROP_APP: | 2035 | case PROP_APP: |
2495 | 860 | midori_bookmarks_set_app (bookmarks, g_value_get_object (value)); | 2036 | midori_bookmarks_set_app (bookmarks, g_value_get_object (value)); |
2496 | 861 | break; | 2037 | break; |
2497 | 862 | default: | 2038 | default: |
2498 | 863 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | 2039 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
2499 | 864 | break; | 2040 | break; |
2500 | 865 | } | 2041 | } |
2501 | 866 | } | 2042 | } |
2502 | 867 | 2043 | ||
2503 | @@ -875,12 +2051,12 @@ | |||
2504 | 875 | 2051 | ||
2505 | 876 | switch (prop_id) | 2052 | switch (prop_id) |
2506 | 877 | { | 2053 | { |
2513 | 878 | case PROP_APP: | 2054 | case PROP_APP: |
2514 | 879 | g_value_set_object (value, bookmarks->app); | 2055 | g_value_set_object (value, bookmarks->app); |
2515 | 880 | break; | 2056 | break; |
2516 | 881 | default: | 2057 | default: |
2517 | 882 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | 2058 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
2518 | 883 | break; | 2059 | break; |
2519 | 884 | } | 2060 | } |
2520 | 885 | } | 2061 | } |
2521 | 886 | 2062 | ||
2522 | @@ -918,8 +2094,8 @@ | |||
2523 | 918 | if (item && katze_item_get_name (item)) | 2094 | if (item && katze_item_get_name (item)) |
2524 | 919 | { | 2095 | { |
2525 | 920 | g_object_set (renderer, "markup", NULL, | 2096 | g_object_set (renderer, "markup", NULL, |
2528 | 921 | "ellipsize", PANGO_ELLIPSIZE_END, | 2097 | "ellipsize", PANGO_ELLIPSIZE_END, |
2529 | 922 | "text", katze_item_get_name (item), NULL); | 2098 | "text", katze_item_get_name (item), NULL); |
2530 | 923 | } | 2099 | } |
2531 | 924 | else | 2100 | else |
2532 | 925 | g_object_set (renderer, "markup", _("<i>Separator</i>"), NULL); | 2101 | g_object_set (renderer, "markup", _("<i>Separator</i>"), NULL); |
2533 | @@ -976,7 +2152,7 @@ | |||
2534 | 976 | menuitem = gtk_image_menu_item_new_from_stock (stock_id, NULL); | 2152 | menuitem = gtk_image_menu_item_new_from_stock (stock_id, NULL); |
2535 | 977 | if (label) | 2153 | if (label) |
2536 | 978 | gtk_label_set_text_with_mnemonic (GTK_LABEL (gtk_bin_get_child ( | 2154 | gtk_label_set_text_with_mnemonic (GTK_LABEL (gtk_bin_get_child ( |
2538 | 979 | GTK_BIN (menuitem))), label); | 2155 | GTK_BIN (menuitem))), label); |
2539 | 980 | if (!strcmp (stock_id, GTK_STOCK_EDIT)) | 2156 | if (!strcmp (stock_id, GTK_STOCK_EDIT)) |
2540 | 981 | gtk_widget_set_sensitive (menuitem, | 2157 | gtk_widget_set_sensitive (menuitem, |
2541 | 982 | !KATZE_ITEM_IS_SEPARATOR (item)); | 2158 | !KATZE_ITEM_IS_SEPARATOR (item)); |
2542 | @@ -1007,39 +2183,103 @@ | |||
2543 | 1007 | } | 2183 | } |
2544 | 1008 | } | 2184 | } |
2545 | 1009 | 2185 | ||
2555 | 1010 | static void | 2186 | static GtkWidget* |
2556 | 1011 | midori_bookmarks_open_in_tab_activate_cb (GtkWidget* menuitem, | 2187 | midori_bookmarks_open_bookmark_in_tab (KatzeItem *item, |
2557 | 1012 | MidoriBookmarks* bookmarks) | 2188 | MidoriBrowser* browser) |
2558 | 1013 | { | 2189 | { |
2559 | 1014 | KatzeItem* item; | 2190 | const gchar* uri = katze_item_get_uri (item); |
2560 | 1015 | const gchar* uri; | 2191 | |
2561 | 1016 | 2192 | if (!uri || !*uri) | |
2562 | 1017 | item = (KatzeItem*)g_object_get_data (G_OBJECT (menuitem), "KatzeItem"); | 2193 | return NULL; |
2563 | 1018 | if (KATZE_ITEM_IS_FOLDER (item)) | 2194 | |
2564 | 2195 | return midori_browser_add_item (browser, item); | ||
2565 | 2196 | } | ||
2566 | 2197 | |||
2567 | 2198 | static GtkWidget* | ||
2568 | 2199 | midori_bookmarks_open_folder_in_tab (gint64 parentid, | ||
2569 | 2200 | MidoriBookmarks* bookmarks, | ||
2570 | 2201 | MidoriBrowser* browser) | ||
2571 | 2202 | { | ||
2572 | 2203 | GtkWidget* last_view = NULL; | ||
2573 | 2204 | KatzeArray* array; | ||
2574 | 2205 | |||
2575 | 2206 | array = midori_bookmarks_read_from_db (bookmarks, parentid, NULL); | ||
2576 | 2207 | |||
2577 | 2208 | if (KATZE_IS_ARRAY (array)) | ||
2578 | 1019 | { | 2209 | { |
2579 | 1020 | KatzeItem* child; | 2210 | KatzeItem* child; |
2586 | 1021 | KatzeArray* array; | 2211 | |
2581 | 1022 | |||
2582 | 1023 | array = midori_bookmarks_read_from_db (bookmarks, | ||
2583 | 1024 | katze_item_get_meta_integer (item, "parentid"), NULL); | ||
2584 | 1025 | |||
2585 | 1026 | g_return_if_fail (KATZE_IS_ARRAY (array)); | ||
2587 | 1027 | KATZE_ARRAY_FOREACH_ITEM (child, array) | 2212 | KATZE_ARRAY_FOREACH_ITEM (child, array) |
2588 | 1028 | { | 2213 | { |
2590 | 1029 | if ((uri = katze_item_get_uri (child)) && *uri) | 2214 | GtkWidget* view = midori_bookmarks_open_bookmark_in_tab (child, browser); |
2591 | 2215 | if (view) | ||
2592 | 2216 | last_view = view; | ||
2593 | 2217 | } | ||
2594 | 2218 | } | ||
2595 | 2219 | |||
2596 | 2220 | return last_view; | ||
2597 | 2221 | } | ||
2598 | 2222 | |||
2599 | 2223 | static void | ||
2600 | 2224 | midori_bookmarks_open_in_tab_activate_cb (GtkWidget* menuitem, | ||
2601 | 2225 | MidoriBookmarks* bookmarks) | ||
2602 | 2226 | { | ||
2603 | 2227 | GtkWidget* last_view = NULL; | ||
2604 | 2228 | MidoriBrowser* browser = midori_browser_get_for_widget (GTK_WIDGET (bookmarks)); | ||
2605 | 2229 | GtkTreeModel* model; | ||
2606 | 2230 | GList* rows; | ||
2607 | 2231 | gint length; | ||
2608 | 2232 | |||
2609 | 2233 | length = katze_tree_view_get_selected_rows (GTK_TREE_VIEW (bookmarks->treeview), | ||
2610 | 2234 | &model, &rows); | ||
2611 | 2235 | |||
2612 | 2236 | if (!length) | ||
2613 | 2237 | { | ||
2614 | 2238 | KatzeItem* root = KATZE_ITEM (bookmarks->bookmarks_db); | ||
2615 | 2239 | KatzeItem* item = KATZE_ITEM (g_object_get_data (G_OBJECT (menuitem), "KatzeItem")); | ||
2616 | 2240 | |||
2617 | 2241 | if (item != root) | ||
2618 | 2242 | return; | ||
2619 | 2243 | |||
2620 | 2244 | last_view = midori_bookmarks_open_folder_in_tab (0, bookmarks, browser); | ||
2621 | 2245 | } | ||
2622 | 2246 | else | ||
2623 | 2247 | { | ||
2624 | 2248 | gint i; | ||
2625 | 2249 | |||
2626 | 2250 | for (i = 0 ; i < length; i++) | ||
2627 | 2251 | { | ||
2628 | 2252 | GtkTreeIter iter; | ||
2629 | 2253 | |||
2630 | 2254 | if (gtk_tree_model_get_iter ( | ||
2631 | 2255 | model, &iter, (GtkTreePath *)g_list_nth_data (rows, i))) | ||
2632 | 1030 | { | 2256 | { |
2636 | 1031 | MidoriBrowser* browser = midori_browser_get_for_widget (GTK_WIDGET (bookmarks)); | 2257 | GtkWidget* view = NULL; |
2637 | 1032 | GtkWidget* view = midori_browser_add_item (browser, child); | 2258 | KatzeItem* item; |
2638 | 1033 | midori_browser_set_current_tab_smartly (browser, view); | 2259 | |
2639 | 2260 | gtk_tree_model_get (model, &iter, 0, &item, -1); | ||
2640 | 2261 | |||
2641 | 2262 | if (KATZE_ITEM_IS_SEPARATOR(item)) | ||
2642 | 2263 | continue; | ||
2643 | 2264 | |||
2644 | 2265 | if (KATZE_ITEM_IS_FOLDER (item)) | ||
2645 | 2266 | view = midori_bookmarks_open_folder_in_tab ( | ||
2646 | 2267 | katze_item_get_meta_integer (item, "id"), bookmarks, browser); | ||
2647 | 2268 | else | ||
2648 | 2269 | view = midori_bookmarks_open_bookmark_in_tab (item, browser); | ||
2649 | 2270 | |||
2650 | 2271 | g_object_unref (item); | ||
2651 | 2272 | |||
2652 | 2273 | if (view) | ||
2653 | 2274 | last_view = view; | ||
2654 | 1034 | } | 2275 | } |
2655 | 1035 | } | 2276 | } |
2663 | 1036 | } | 2277 | |
2664 | 1037 | else if ((uri = katze_item_get_uri (item)) && *uri) | 2278 | g_list_free_full (rows, (GDestroyNotify) gtk_tree_path_free); |
2665 | 1038 | { | 2279 | } |
2666 | 1039 | MidoriBrowser* browser = midori_browser_get_for_widget (GTK_WIDGET (bookmarks)); | 2280 | |
2667 | 1040 | GtkWidget* view = midori_browser_add_item (browser, item); | 2281 | if (last_view) |
2668 | 1041 | midori_browser_set_current_tab_smartly (browser, view); | 2282 | midori_browser_set_current_tab_smartly (browser, last_view); |
2662 | 1042 | } | ||
2669 | 1043 | } | 2283 | } |
2670 | 1044 | 2284 | ||
2671 | 1045 | static void | 2285 | static void |
2672 | @@ -1067,18 +2307,20 @@ | |||
2673 | 1067 | KatzeItem* item, | 2307 | KatzeItem* item, |
2674 | 1068 | MidoriBookmarks* bookmarks) | 2308 | MidoriBookmarks* bookmarks) |
2675 | 1069 | { | 2309 | { |
2676 | 2310 | KatzeItem* root = KATZE_ITEM (bookmarks->bookmarks_db); | ||
2677 | 1070 | GtkWidget* menu; | 2311 | GtkWidget* menu; |
2678 | 1071 | GtkWidget* menuitem; | 2312 | GtkWidget* menuitem; |
2679 | 1072 | 2313 | ||
2680 | 1073 | menu = gtk_menu_new (); | 2314 | menu = gtk_menu_new (); |
2682 | 1074 | if (KATZE_ITEM_IS_FOLDER (item)) | 2315 | if ((item == root) |
2683 | 2316 | || KATZE_ITEM_IS_FOLDER (item)) | ||
2684 | 1075 | { | 2317 | { |
2685 | 1076 | gint child_bookmarks_count = midori_bookmarks_db_count_recursive (bookmarks->bookmarks_db, | 2318 | gint child_bookmarks_count = midori_bookmarks_db_count_recursive (bookmarks->bookmarks_db, |
2686 | 1077 | "uri <> ''", NULL, item, FALSE); | 2319 | "uri <> ''", NULL, item, FALSE); |
2687 | 1078 | 2320 | ||
2688 | 1079 | midori_bookmarks_popup_item (menu, | 2321 | midori_bookmarks_popup_item (menu, |
2691 | 1080 | STOCK_TAB_NEW, _("Open all in _Tabs"), item, | 2322 | STOCK_TAB_NEW, _("Open all in _Tabs"), item, |
2692 | 1081 | (!child_bookmarks_count ? NULL : midori_bookmarks_open_in_tab_activate_cb), | 2323 | (!child_bookmarks_count ? NULL : midori_bookmarks_open_in_tab_activate_cb), |
2693 | 1082 | bookmarks); | 2324 | bookmarks); |
2694 | 1083 | } | 2325 | } |
2695 | 1084 | else | 2326 | else |
2696 | @@ -1094,11 +2336,59 @@ | |||
2697 | 1094 | gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); | 2336 | gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); |
2698 | 1095 | gtk_widget_show (menuitem); | 2337 | gtk_widget_show (menuitem); |
2699 | 1096 | midori_bookmarks_popup_item (menu, GTK_STOCK_EDIT, NULL, | 2338 | midori_bookmarks_popup_item (menu, GTK_STOCK_EDIT, NULL, |
2705 | 1097 | item, midori_bookmarks_edit_clicked_cb, bookmarks); | 2339 | item, (item == root) ? NULL : midori_bookmarks_edit_clicked_cb, bookmarks); |
2706 | 1098 | midori_bookmarks_popup_item (menu, GTK_STOCK_DELETE, NULL, | 2340 | midori_bookmarks_popup_item (menu, GTK_STOCK_DELETE, NULL, |
2707 | 1099 | item, midori_bookmarks_delete_clicked_cb, bookmarks); | 2341 | item, (item == root) ? NULL : midori_bookmarks_delete_clicked_cb, bookmarks); |
2708 | 1100 | 2342 | ||
2709 | 1101 | katze_widget_popup (widget, GTK_MENU (menu), event, KATZE_MENU_POSITION_CURSOR); | 2343 | katze_widget_popup (widget, GTK_MENU (menu), event, KATZE_MENU_POSITION_CURSOR); |
2710 | 2344 | } | ||
2711 | 2345 | |||
2712 | 2346 | static void | ||
2713 | 2347 | midori_bookmarks_multi_popup (GtkWidget* widget, | ||
2714 | 2348 | GdkEventButton* event, | ||
2715 | 2349 | MidoriBookmarks* bookmarks, | ||
2716 | 2350 | GtkTreeModel* model, | ||
2717 | 2351 | gint count, | ||
2718 | 2352 | GList* rows) | ||
2719 | 2353 | { | ||
2720 | 2354 | GtkWidget* menu; | ||
2721 | 2355 | GtkWidget* menuitem; | ||
2722 | 2356 | |||
2723 | 2357 | menu = gtk_menu_new (); | ||
2724 | 2358 | |||
2725 | 2359 | midori_bookmarks_popup_item (menu, | ||
2726 | 2360 | STOCK_TAB_NEW, _("Open all in _Tabs"), | ||
2727 | 2361 | KATZE_ITEM(bookmarks->bookmarks_db), midori_bookmarks_open_in_tab_activate_cb, bookmarks); | ||
2728 | 2362 | menuitem = gtk_separator_menu_item_new (); | ||
2729 | 2363 | gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); | ||
2730 | 2364 | gtk_widget_show (menuitem); | ||
2731 | 2365 | |||
2732 | 2366 | midori_bookmarks_popup_item (menu, GTK_STOCK_EDIT, NULL, | ||
2733 | 2367 | NULL, NULL, bookmarks); | ||
2734 | 2368 | midori_bookmarks_popup_item (menu, GTK_STOCK_DELETE, NULL, | ||
2735 | 2369 | KATZE_ITEM(bookmarks->bookmarks_db), midori_bookmarks_delete_clicked_cb, bookmarks); | ||
2736 | 2370 | |||
2737 | 2371 | katze_widget_popup (widget, GTK_MENU (menu), event, KATZE_MENU_POSITION_CURSOR); | ||
2738 | 2372 | } | ||
2739 | 2373 | |||
2740 | 2374 | static gboolean | ||
2741 | 2375 | midori_bookmarks_do_block_selection (GtkTreeSelection *selection, | ||
2742 | 2376 | GtkTreeModel *model, | ||
2743 | 2377 | GtkTreePath *path, | ||
2744 | 2378 | gboolean path_currently_selected, | ||
2745 | 2379 | gpointer data) | ||
2746 | 2380 | { | ||
2747 | 2381 | return FALSE; | ||
2748 | 2382 | } | ||
2749 | 2383 | |||
2750 | 2384 | static gboolean | ||
2751 | 2385 | midori_bookmarks_do_not_block_selection (GtkTreeSelection *selection, | ||
2752 | 2386 | GtkTreeModel *model, | ||
2753 | 2387 | GtkTreePath *path, | ||
2754 | 2388 | gboolean path_currently_selected, | ||
2755 | 2389 | gpointer data) | ||
2756 | 2390 | { | ||
2757 | 2391 | return TRUE; | ||
2758 | 1102 | } | 2392 | } |
2759 | 1103 | 2393 | ||
2760 | 1104 | static gboolean | 2394 | static gboolean |
2761 | @@ -1109,32 +2399,194 @@ | |||
2762 | 1109 | GtkTreeModel* model; | 2399 | GtkTreeModel* model; |
2763 | 1110 | GtkTreeIter iter; | 2400 | GtkTreeIter iter; |
2764 | 1111 | 2401 | ||
2766 | 1112 | if (event->button != 2 && event->button != 3) | 2402 | if (bookmarks->pending_event) |
2767 | 2403 | { | ||
2768 | 2404 | GtkTreeView* treeview = GTK_TREE_VIEW(widget); | ||
2769 | 2405 | GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview); | ||
2770 | 2406 | gint x = bookmarks->stock_pending_event.x; | ||
2771 | 2407 | gint y = bookmarks->stock_pending_event.y; | ||
2772 | 2408 | |||
2773 | 2409 | bookmarks->pending_event = NULL; | ||
2774 | 2410 | gtk_tree_selection_set_select_function ( | ||
2775 | 2411 | selection, midori_bookmarks_do_not_block_selection, NULL, NULL); | ||
2776 | 2412 | |||
2777 | 2413 | if (x != event->x || y != event->y) | ||
2778 | 2414 | return FALSE; | ||
2779 | 2415 | } | ||
2780 | 2416 | |||
2781 | 2417 | if (event->button == 3) | ||
2782 | 2418 | return TRUE; | ||
2783 | 2419 | |||
2784 | 2420 | if (event->button != 2) | ||
2785 | 1113 | return FALSE; | 2421 | return FALSE; |
2786 | 1114 | 2422 | ||
2787 | 1115 | if (katze_tree_view_get_selected_iter (GTK_TREE_VIEW (widget), &model, &iter)) | 2423 | if (katze_tree_view_get_selected_iter (GTK_TREE_VIEW (widget), &model, &iter)) |
2788 | 1116 | { | 2424 | { |
2789 | 2425 | gboolean done = FALSE; | ||
2790 | 1117 | KatzeItem* item; | 2426 | KatzeItem* item; |
2791 | 1118 | 2427 | ||
2792 | 1119 | gtk_tree_model_get (model, &iter, 0, &item, -1); | 2428 | gtk_tree_model_get (model, &iter, 0, &item, -1); |
2793 | 1120 | 2429 | ||
2795 | 1121 | if (event->button == 2) | 2430 | if (KATZE_ITEM_IS_BOOKMARK (item)) |
2796 | 1122 | { | 2431 | { |
2799 | 1123 | const gchar* uri; | 2432 | MidoriBrowser* browser = midori_browser_get_for_widget (widget); |
2800 | 1124 | if (KATZE_ITEM_IS_BOOKMARK (item) && (uri = katze_item_get_uri (item)) && *uri) | 2433 | GtkWidget* view = midori_bookmarks_open_bookmark_in_tab ( |
2801 | 2434 | item, browser); | ||
2802 | 2435 | |||
2803 | 2436 | if (widget) | ||
2804 | 1125 | { | 2437 | { |
2808 | 1126 | MidoriBrowser* browser = midori_browser_get_for_widget (widget); | 2438 | midori_browser_set_current_tab_smartly (browser, view); |
2809 | 1127 | GtkWidget* view = midori_browser_add_uri (browser, uri); | 2439 | done = TRUE; |
2807 | 1128 | midori_browser_set_current_tab (browser, view); | ||
2810 | 1129 | } | 2440 | } |
2811 | 1130 | } | 2441 | } |
2819 | 1131 | else | 2442 | |
2820 | 1132 | midori_bookmarks_popup (widget, event, item, bookmarks); | 2443 | g_object_unref (item); |
2821 | 1133 | 2444 | ||
2822 | 1134 | if (item != NULL) | 2445 | return done; |
2823 | 1135 | g_object_unref (item); | 2446 | } |
2824 | 1136 | return TRUE; | 2447 | |
2825 | 1137 | } | 2448 | return FALSE; |
2826 | 2449 | } | ||
2827 | 2450 | |||
2828 | 2451 | static gboolean | ||
2829 | 2452 | midori_bookmarks_block_selection(GtkWidget* widget, | ||
2830 | 2453 | GdkEventButton* event, | ||
2831 | 2454 | MidoriBookmarks* bookmarks) | ||
2832 | 2455 | { | ||
2833 | 2456 | GtkTreeView* treeview = GTK_TREE_VIEW(widget); | ||
2834 | 2457 | GtkTreePath* path; | ||
2835 | 2458 | GtkTreeSelection* selection; | ||
2836 | 2459 | gint cell_x; | ||
2837 | 2460 | gint cell_y; | ||
2838 | 2461 | |||
2839 | 2462 | if (!gtk_tree_view_get_path_at_pos ( | ||
2840 | 2463 | treeview, event->x, event->y, | ||
2841 | 2464 | &path, NULL, &cell_x, &cell_y)) | ||
2842 | 2465 | return FALSE; | ||
2843 | 2466 | |||
2844 | 2467 | gtk_widget_grab_focus (widget); | ||
2845 | 2468 | |||
2846 | 2469 | selection = gtk_tree_view_get_selection (treeview); | ||
2847 | 2470 | |||
2848 | 2471 | if (gtk_tree_selection_path_is_selected (selection, path) | ||
2849 | 2472 | && !(event->state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK))) | ||
2850 | 2473 | { | ||
2851 | 2474 | bookmarks->pending_event = &bookmarks->stock_pending_event; | ||
2852 | 2475 | bookmarks->stock_pending_event.x = event->x; | ||
2853 | 2476 | bookmarks->stock_pending_event.y = event->y; | ||
2854 | 2477 | gtk_tree_selection_set_select_function ( | ||
2855 | 2478 | selection, midori_bookmarks_do_block_selection, NULL, NULL); | ||
2856 | 2479 | } | ||
2857 | 2480 | else | ||
2858 | 2481 | { | ||
2859 | 2482 | bookmarks->pending_event = NULL; | ||
2860 | 2483 | gtk_tree_selection_set_select_function ( | ||
2861 | 2484 | selection, midori_bookmarks_do_not_block_selection, NULL, NULL); | ||
2862 | 2485 | } | ||
2863 | 2486 | |||
2864 | 2487 | return FALSE; | ||
2865 | 2488 | } | ||
2866 | 2489 | |||
2867 | 2490 | static gboolean | ||
2868 | 2491 | midori_bookmarks_button_press_event_cb (GtkWidget* widget, | ||
2869 | 2492 | GdkEventButton* event, | ||
2870 | 2493 | MidoriBookmarks* bookmarks) | ||
2871 | 2494 | { | ||
2872 | 2495 | GtkTreeView* treeview = GTK_TREE_VIEW(widget); | ||
2873 | 2496 | GtkTreePath* path; | ||
2874 | 2497 | GtkTreeSelection* selection; | ||
2875 | 2498 | GtkTreeModel* model; | ||
2876 | 2499 | gint selected; | ||
2877 | 2500 | GList* rows; | ||
2878 | 2501 | gint cell_x; | ||
2879 | 2502 | gint cell_y; | ||
2880 | 2503 | |||
2881 | 2504 | if (event->button == 1) | ||
2882 | 2505 | return midori_bookmarks_block_selection (widget, event, bookmarks); | ||
2883 | 2506 | |||
2884 | 2507 | if (event->button != 3) | ||
2885 | 2508 | return FALSE; | ||
2886 | 2509 | |||
2887 | 2510 | selection = gtk_tree_view_get_selection (treeview); | ||
2888 | 2511 | |||
2889 | 2512 | if (!gtk_tree_view_get_path_at_pos ( | ||
2890 | 2513 | treeview, event->x, event->y, | ||
2891 | 2514 | &path, NULL, &cell_x, &cell_y)) | ||
2892 | 2515 | { | ||
2893 | 2516 | /* FIXME: popup opening below treeview | ||
2894 | 2517 | * Rationale: the user is actually in ROOT folder | ||
2895 | 2518 | * we may need to have a non editable, non deletable, ROOT folder popup | ||
2896 | 2519 | * Open all in Tabs | ||
2897 | 2520 | * Separator | ||
2898 | 2521 | * Edit [inactive] | ||
2899 | 2522 | * Delete [inactive] | ||
2900 | 2523 | * Here we just mimic the Files behaviour: | ||
2901 | 2524 | * 1- unselect all | ||
2902 | 2525 | * 2- let popup based on selection process | ||
2903 | 2526 | */ | ||
2904 | 2527 | |||
2905 | 2528 | gtk_tree_selection_unselect_all (selection); | ||
2906 | 2529 | } | ||
2907 | 2530 | else if (!gtk_tree_selection_path_is_selected (selection, path)) | ||
2908 | 2531 | { | ||
2909 | 2532 | /* Use case: popup opening on item not in selection | ||
2910 | 2533 | * Rationale: the user is addressing a single item not in selection | ||
2911 | 2534 | * we may need a single item popup with callbacks working on the item, | ||
2912 | 2535 | * not the selection. | ||
2913 | 2536 | * Here we just mimic the Files behaviour: | ||
2914 | 2537 | * 1- change the selection to the item the popup is opened on | ||
2915 | 2538 | * 2- let popup based on selection process | ||
2916 | 2539 | */ | ||
2917 | 2540 | |||
2918 | 2541 | gtk_tree_selection_unselect_all (selection); | ||
2919 | 2542 | gtk_tree_selection_select_path (selection, path); | ||
2920 | 2543 | } | ||
2921 | 2544 | |||
2922 | 2545 | selected = katze_tree_view_get_selected_rows(GTK_TREE_VIEW (widget), &model, &rows); | ||
2923 | 2546 | |||
2924 | 2547 | if (!selected) | ||
2925 | 2548 | { | ||
2926 | 2549 | KatzeItem* root = KATZE_ITEM (bookmarks->bookmarks_db); | ||
2927 | 2550 | |||
2928 | 2551 | midori_bookmarks_popup (widget, event, root, bookmarks); | ||
2929 | 2552 | |||
2930 | 2553 | return TRUE; | ||
2931 | 2554 | } | ||
2932 | 2555 | |||
2933 | 2556 | if (selected == 1) | ||
2934 | 2557 | { | ||
2935 | 2558 | GtkTreeIter iter; | ||
2936 | 2559 | KatzeItem* item; | ||
2937 | 2560 | |||
2938 | 2561 | if (!gtk_tree_model_get_iter ( | ||
2939 | 2562 | model, &iter, (GtkTreePath *)g_list_nth_data (rows, 0))) | ||
2940 | 2563 | { | ||
2941 | 2564 | g_list_free_full (rows, (GDestroyNotify) gtk_tree_path_free); | ||
2942 | 2565 | |||
2943 | 2566 | return FALSE; | ||
2944 | 2567 | } | ||
2945 | 2568 | |||
2946 | 2569 | gtk_tree_model_get (model, &iter, 0, &item, -1); | ||
2947 | 2570 | |||
2948 | 2571 | midori_bookmarks_popup (widget, event, item, bookmarks); | ||
2949 | 2572 | |||
2950 | 2573 | g_object_unref (item); | ||
2951 | 2574 | |||
2952 | 2575 | g_list_free_full (rows, (GDestroyNotify) gtk_tree_path_free); | ||
2953 | 2576 | |||
2954 | 2577 | return TRUE; | ||
2955 | 2578 | } | ||
2956 | 2579 | |||
2957 | 2580 | if (selected > 1) | ||
2958 | 2581 | { | ||
2959 | 2582 | midori_bookmarks_multi_popup (widget, event, bookmarks, | ||
2960 | 2583 | model, selected, rows); | ||
2961 | 2584 | |||
2962 | 2585 | g_list_free_full (rows, (GDestroyNotify) gtk_tree_path_free); | ||
2963 | 2586 | |||
2964 | 2587 | return TRUE; | ||
2965 | 2588 | } | ||
2966 | 2589 | |||
2967 | 1138 | return FALSE; | 2590 | return FALSE; |
2968 | 1139 | } | 2591 | } |
2969 | 1140 | 2592 | ||
2970 | @@ -1165,39 +2617,74 @@ | |||
2971 | 1165 | } | 2617 | } |
2972 | 1166 | } | 2618 | } |
2973 | 1167 | 2619 | ||
2979 | 1168 | static void | 2620 | static gboolean |
2980 | 1169 | midori_bookmarks_row_expanded_cb (GtkTreeView* treeview, | 2621 | midori_bookmarks_test_expand_row_cb (GtkTreeView* treeview, |
2981 | 1170 | GtkTreeIter* iter, | 2622 | GtkTreeIter* iter, |
2982 | 1171 | GtkTreePath* path, | 2623 | GtkTreePath* path, |
2983 | 1172 | MidoriBookmarks* bookmarks) | 2624 | MidoriBookmarks* bookmarks) |
2984 | 1173 | { | 2625 | { |
2985 | 1174 | GtkTreeModel* model; | 2626 | GtkTreeModel* model; |
2986 | 2627 | GtkTreeIter child; | ||
2987 | 1175 | KatzeItem* item; | 2628 | KatzeItem* item; |
2988 | 2629 | gint64 id; | ||
2989 | 1176 | 2630 | ||
2990 | 1177 | model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview)); | 2631 | model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview)); |
2991 | 2632 | |||
2992 | 1178 | gtk_tree_model_get (model, iter, 0, &item, -1); | 2633 | gtk_tree_model_get (model, iter, 0, &item, -1); |
2993 | 2634 | |||
2994 | 2635 | g_return_val_if_fail (KATZE_IS_ITEM(item), TRUE); | ||
2995 | 2636 | |||
2996 | 2637 | g_signal_handlers_block_by_func (model, | ||
2997 | 2638 | midori_bookmarks_row_deleted_cb, | ||
2998 | 2639 | bookmarks); | ||
2999 | 2640 | |||
3000 | 2641 | id = katze_item_get_meta_integer (item, "id"); | ||
3001 | 2642 | |||
3002 | 2643 | g_object_unref (item); | ||
3003 | 2644 | |||
3004 | 2645 | while (gtk_tree_model_iter_children (model, &child, iter)) | ||
3005 | 2646 | gtk_tree_store_remove (GTK_TREE_STORE (model), &child); | ||
3006 | 2647 | /* That's an invisible dummy, so we always have an expander */ | ||
3007 | 2648 | gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &child, iter, | ||
3008 | 2649 | 0, 0, NULL, -1); | ||
3009 | 2650 | |||
3010 | 2651 | g_signal_handlers_unblock_by_func (model, | ||
3011 | 2652 | midori_bookmarks_row_deleted_cb, | ||
3012 | 2653 | bookmarks); | ||
3013 | 2654 | |||
3014 | 1179 | midori_bookmarks_read_from_db_to_model (bookmarks, GTK_TREE_STORE (model), | 2655 | midori_bookmarks_read_from_db_to_model (bookmarks, GTK_TREE_STORE (model), |
3017 | 1180 | iter, katze_item_get_meta_integer (item, "id"), NULL); | 2656 | iter, id, NULL); |
3018 | 1181 | g_object_unref (item); | 2657 | |
3019 | 2658 | return FALSE; | ||
3020 | 1182 | } | 2659 | } |
3021 | 1183 | 2660 | ||
3022 | 1184 | static void | 2661 | static void |
3023 | 1185 | midori_bookmarks_row_collapsed_cb (GtkTreeView *treeview, | 2662 | midori_bookmarks_row_collapsed_cb (GtkTreeView *treeview, |
3024 | 1186 | GtkTreeIter *parent, | 2663 | GtkTreeIter *parent, |
3025 | 1187 | GtkTreePath *path, | 2664 | GtkTreePath *path, |
3027 | 1188 | gpointer user_data) | 2665 | MidoriBookmarks* bookmarks) |
3028 | 1189 | { | 2666 | { |
3029 | 1190 | GtkTreeModel* model; | 2667 | GtkTreeModel* model; |
3030 | 1191 | GtkTreeStore* treestore; | 2668 | GtkTreeStore* treestore; |
3031 | 1192 | GtkTreeIter child; | 2669 | GtkTreeIter child; |
3032 | 1193 | 2670 | ||
3033 | 1194 | model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview)); | 2671 | model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview)); |
3034 | 2672 | |||
3035 | 2673 | g_signal_handlers_block_by_func (model, | ||
3036 | 2674 | midori_bookmarks_row_deleted_cb, | ||
3037 | 2675 | bookmarks); | ||
3038 | 2676 | |||
3039 | 1195 | treestore = GTK_TREE_STORE (model); | 2677 | treestore = GTK_TREE_STORE (model); |
3040 | 1196 | while (gtk_tree_model_iter_nth_child (model, &child, parent, 0)) | 2678 | while (gtk_tree_model_iter_nth_child (model, &child, parent, 0)) |
3041 | 1197 | gtk_tree_store_remove (treestore, &child); | 2679 | gtk_tree_store_remove (treestore, &child); |
3042 | 1198 | /* That's an invisible dummy, so we always have an expander */ | 2680 | /* That's an invisible dummy, so we always have an expander */ |
3043 | 1199 | gtk_tree_store_insert_with_values (treestore, &child, parent, | 2681 | gtk_tree_store_insert_with_values (treestore, &child, parent, |
3044 | 1200 | 0, 0, NULL, -1); | 2682 | 0, 0, NULL, -1); |
3045 | 2683 | |||
3046 | 2684 | g_signal_handlers_block_by_func (model, | ||
3047 | 2685 | midori_bookmarks_row_deleted_cb, | ||
3048 | 2686 | bookmarks); | ||
3049 | 2687 | |||
3050 | 1201 | } | 2688 | } |
3051 | 1202 | 2689 | ||
3052 | 1203 | static void | 2690 | static void |
3053 | @@ -1205,26 +2692,27 @@ | |||
3054 | 1205 | MidoriBookmarks *bookmarks) | 2692 | MidoriBookmarks *bookmarks) |
3055 | 1206 | { | 2693 | { |
3056 | 1207 | midori_bookmarks_toolbar_update (bookmarks); | 2694 | midori_bookmarks_toolbar_update (bookmarks); |
3057 | 2695 | midori_bookmarks_statusbar_update (bookmarks); | ||
3058 | 1208 | } | 2696 | } |
3059 | 1209 | 2697 | ||
3060 | 1210 | static KatzeItem* | 2698 | static KatzeItem* |
3061 | 1211 | midori_bookmarks_get_item_at_pos (GtkTreeView *treeview, | 2699 | midori_bookmarks_get_item_at_pos (GtkTreeView *treeview, |
3062 | 1212 | gint x, gint y) | 2700 | gint x, gint y) |
3064 | 1213 | { | 2701 | { |
3065 | 1214 | GtkTreeModel* model = gtk_tree_view_get_model (treeview); | 2702 | GtkTreeModel* model = gtk_tree_view_get_model (treeview); |
3066 | 1215 | GtkTreePath* path; | 2703 | GtkTreePath* path; |
3067 | 1216 | GtkTreeIter iter; | 2704 | GtkTreeIter iter; |
3068 | 1217 | KatzeItem* item = NULL; | 2705 | KatzeItem* item = NULL; |
3069 | 1218 | 2706 | ||
3070 | 1219 | gtk_tree_view_get_path_at_pos (treeview, x, y, | 2707 | gtk_tree_view_get_path_at_pos (treeview, x, y, |
3073 | 1220 | &path, NULL, NULL, NULL); | 2708 | &path, NULL, NULL, NULL); |
3074 | 1221 | 2709 | ||
3075 | 1222 | if (!path) | 2710 | if (!path) |
3076 | 1223 | return NULL; | 2711 | return NULL; |
3078 | 1224 | 2712 | ||
3079 | 1225 | if (gtk_tree_model_get_iter (model, &iter, path)) | 2713 | if (gtk_tree_model_get_iter (model, &iter, path)) |
3080 | 1226 | gtk_tree_model_get (model, &iter, 0, &item, -1); | 2714 | gtk_tree_model_get (model, &iter, 0, &item, -1); |
3082 | 1227 | 2715 | ||
3083 | 1228 | gtk_tree_path_free (path); | 2716 | gtk_tree_path_free (path); |
3084 | 1229 | 2717 | ||
3085 | 1230 | return item; | 2718 | return item; |
3086 | @@ -1296,7 +2784,7 @@ | |||
3087 | 1296 | 2784 | ||
3088 | 1297 | if (bookmarks->hovering_item) | 2785 | if (bookmarks->hovering_item) |
3089 | 1298 | g_object_unref (bookmarks->hovering_item); | 2786 | g_object_unref (bookmarks->hovering_item); |
3091 | 1299 | 2787 | ||
3092 | 1300 | bookmarks->hovering_item = NULL; | 2788 | bookmarks->hovering_item = NULL; |
3093 | 1301 | 2789 | ||
3094 | 1302 | g_object_set (browser, "statusbar-text", "", NULL); | 2790 | g_object_set (browser, "statusbar-text", "", NULL); |
3095 | @@ -1337,6 +2825,183 @@ | |||
3096 | 1337 | midori_bookmarks_filter_timeout_cb, bookmarks, NULL); | 2825 | midori_bookmarks_filter_timeout_cb, bookmarks, NULL); |
3097 | 1338 | } | 2826 | } |
3098 | 1339 | 2827 | ||
3099 | 2828 | static GtkTargetEntry midori_bookmarks_dnd_target_entries[]= | ||
3100 | 2829 | { | ||
3101 | 2830 | {MIDORI_BOOKMARKS_TREE_MODEL_TARGET, GTK_TARGET_SAME_WIDGET, 0}, | ||
3102 | 2831 | }; | ||
3103 | 2832 | |||
3104 | 2833 | #define MIDORI_BOOKMARKS_DND_NB_TARGET_ENTRIES \ | ||
3105 | 2834 | G_N_ELEMENTS (midori_bookmarks_dnd_target_entries) | ||
3106 | 2835 | |||
3107 | 2836 | static guint | ||
3108 | 2837 | item_hash (gconstpointer item) | ||
3109 | 2838 | { | ||
3110 | 2839 | gint64 id = katze_item_get_meta_integer (KATZE_ITEM (item), "id"); | ||
3111 | 2840 | return g_int64_hash (&id); | ||
3112 | 2841 | } | ||
3113 | 2842 | |||
3114 | 2843 | static gboolean | ||
3115 | 2844 | item_equal (gconstpointer item_a, gconstpointer item_b) | ||
3116 | 2845 | { | ||
3117 | 2846 | gint64 id_a = katze_item_get_meta_integer (KATZE_ITEM (item_a), "id"); | ||
3118 | 2847 | gint64 id_b = katze_item_get_meta_integer (KATZE_ITEM (item_b), "id"); | ||
3119 | 2848 | return (id_a == id_b)? TRUE : FALSE; | ||
3120 | 2849 | } | ||
3121 | 2850 | |||
3122 | 2851 | static gboolean | ||
3123 | 2852 | midori_bookmarks_idle_func (gpointer data) | ||
3124 | 2853 | { | ||
3125 | 2854 | MidoriBookmarks* bookmarks = MIDORI_BOOKMARKS (data); | ||
3126 | 2855 | GtkTreeModel* model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview)); | ||
3127 | 2856 | GHashTableIter hash_iter; | ||
3128 | 2857 | gpointer key, value; | ||
3129 | 2858 | GList* list_iter; | ||
3130 | 2859 | |||
3131 | 2860 | /* update remaining additions */ | ||
3132 | 2861 | assert_reorder_are_folders (model, bookmarks); | ||
3133 | 2862 | for (list_iter = bookmarks->added_paths; list_iter ; list_iter = g_list_next (list_iter)) | ||
3134 | 2863 | { | ||
3135 | 2864 | GtkTreePath* path = (GtkTreePath*)list_iter->data; | ||
3136 | 2865 | |||
3137 | 2866 | add_parent_to_reorder (model, path, bookmarks); | ||
3138 | 2867 | assert_reorder_are_folders (model, bookmarks); | ||
3139 | 2868 | } | ||
3140 | 2869 | |||
3141 | 2870 | g_list_free_full (bookmarks->added_paths, (GDestroyNotify) gtk_tree_path_free); | ||
3142 | 2871 | bookmarks->added_paths = NULL; | ||
3143 | 2872 | |||
3144 | 2873 | /* do actual reordering */ | ||
3145 | 2874 | for (list_iter = bookmarks->reordered_paths; list_iter ; list_iter = g_list_next (list_iter)) | ||
3146 | 2875 | { | ||
3147 | 2876 | GtkTreeIter local_iter; | ||
3148 | 2877 | GtkTreePath* path = (GtkTreePath*)list_iter->data; | ||
3149 | 2878 | |||
3150 | 2879 | if (gtk_tree_path_get_depth (path)) | ||
3151 | 2880 | { | ||
3152 | 2881 | GtkTreeIter parent; | ||
3153 | 2882 | |||
3154 | 2883 | if (gtk_tree_model_get_iter (model, &parent, path)) | ||
3155 | 2884 | { | ||
3156 | 2885 | KatzeItem *item; | ||
3157 | 2886 | gint64 id; | ||
3158 | 2887 | |||
3159 | 2888 | gtk_tree_model_get (model, &parent, 0, &item, -1); | ||
3160 | 2889 | |||
3161 | 2890 | g_assert (KATZE_ITEM_IS_FOLDER (item)); | ||
3162 | 2891 | |||
3163 | 2892 | id = katze_item_get_meta_integer (item, "id"); | ||
3164 | 2893 | |||
3165 | 2894 | if (gtk_tree_model_iter_children (model, &local_iter, &parent)) | ||
3166 | 2895 | midori_bookmarks_set_item_positon(model, &local_iter, id, bookmarks); | ||
3167 | 2896 | |||
3168 | 2897 | /* update folder array for menu update */ | ||
3169 | 2898 | katze_array_update (KATZE_ARRAY (item)); | ||
3170 | 2899 | |||
3171 | 2900 | g_object_unref (item); | ||
3172 | 2901 | } | ||
3173 | 2902 | } | ||
3174 | 2903 | else | ||
3175 | 2904 | { | ||
3176 | 2905 | if (gtk_tree_model_get_iter_first (model, &local_iter)) | ||
3177 | 2906 | midori_bookmarks_set_item_positon(model, &local_iter, | ||
3178 | 2907 | katze_item_get_meta_integer (KATZE_ITEM (bookmarks->bookmarks_db), "id"), | ||
3179 | 2908 | bookmarks); | ||
3180 | 2909 | |||
3181 | 2910 | g_signal_handlers_block_by_func (bookmarks->bookmarks_db, | ||
3182 | 2911 | midori_bookmarks_update_cb, | ||
3183 | 2912 | bookmarks); | ||
3184 | 2913 | |||
3185 | 2914 | /* update folder array for menu update */ | ||
3186 | 2915 | katze_array_update (KATZE_ARRAY (bookmarks->bookmarks_db)); | ||
3187 | 2916 | |||
3188 | 2917 | g_signal_handlers_unblock_by_func (bookmarks->bookmarks_db, | ||
3189 | 2918 | midori_bookmarks_update_cb, | ||
3190 | 2919 | bookmarks); | ||
3191 | 2920 | } | ||
3192 | 2921 | } | ||
3193 | 2922 | |||
3194 | 2923 | g_list_free_full (bookmarks->reordered_paths, (GDestroyNotify) gtk_tree_path_free); | ||
3195 | 2924 | bookmarks->reordered_paths = NULL; | ||
3196 | 2925 | |||
3197 | 2926 | /* then finalize updates */ | ||
3198 | 2927 | g_signal_handlers_block_by_func (bookmarks->bookmarks_db, | ||
3199 | 2928 | midori_bookmarks_update_item_cb, | ||
3200 | 2929 | bookmarks); | ||
3201 | 2930 | |||
3202 | 2931 | g_hash_table_iter_init (&hash_iter, bookmarks->updated_items); | ||
3203 | 2932 | |||
3204 | 2933 | while (g_hash_table_iter_next (&hash_iter, &key, &value)) | ||
3205 | 2934 | { | ||
3206 | 2935 | midori_bookmarks_db_update_item (bookmarks->bookmarks_db, KATZE_ITEM (value)); | ||
3207 | 2936 | g_object_unref (value); | ||
3208 | 2937 | } | ||
3209 | 2938 | |||
3210 | 2939 | g_signal_handlers_unblock_by_func (bookmarks->bookmarks_db, | ||
3211 | 2940 | midori_bookmarks_update_item_cb, | ||
3212 | 2941 | bookmarks); | ||
3213 | 2942 | |||
3214 | 2943 | g_hash_table_remove_all (bookmarks->updated_items); | ||
3215 | 2944 | |||
3216 | 2945 | /* process pending additions of inserted bookmarks */ | ||
3217 | 2946 | for (list_iter = bookmarks->pending_inserts; list_iter; list_iter = g_list_next (list_iter)) | ||
3218 | 2947 | { | ||
3219 | 2948 | KatzeItem *item = KATZE_ITEM (list_iter->data); | ||
3220 | 2949 | |||
3221 | 2950 | midori_bookmarks_add_item (item, bookmarks); | ||
3222 | 2951 | |||
3223 | 2952 | g_object_unref (item); | ||
3224 | 2953 | } | ||
3225 | 2954 | |||
3226 | 2955 | g_list_free (bookmarks->pending_inserts); | ||
3227 | 2956 | bookmarks->pending_inserts = NULL; | ||
3228 | 2957 | return midori_bookmarks_idle_pending (bookmarks); | ||
3229 | 2958 | } | ||
3230 | 2959 | |||
3231 | 2960 | static void | ||
3232 | 2961 | midori_bookmarks_update_item (MidoriBookmarks* bookmarks, KatzeItem *item) | ||
3233 | 2962 | { | ||
3234 | 2963 | midori_bookmarks_idle_start (bookmarks); | ||
3235 | 2964 | |||
3236 | 2965 | if (g_hash_table_lookup (bookmarks->updated_items, item)) | ||
3237 | 2966 | return; | ||
3238 | 2967 | |||
3239 | 2968 | g_object_ref (item); | ||
3240 | 2969 | g_hash_table_insert (bookmarks->updated_items, item, item); | ||
3241 | 2970 | } | ||
3242 | 2971 | |||
3243 | 2972 | static void | ||
3244 | 2973 | midori_bookmarks_idle_remove_item (MidoriBookmarks* bookmarks, KatzeItem *item) | ||
3245 | 2974 | { | ||
3246 | 2975 | gpointer found; | ||
3247 | 2976 | |||
3248 | 2977 | if (KATZE_ITEM_IS_FOLDER (item)) | ||
3249 | 2978 | { | ||
3250 | 2979 | gint64 id = katze_item_get_meta_integer (item, "id"); | ||
3251 | 2980 | GHashTableIter iter; | ||
3252 | 2981 | gpointer key, value; | ||
3253 | 2982 | |||
3254 | 2983 | g_hash_table_iter_init (&iter, bookmarks->updated_items); | ||
3255 | 2984 | |||
3256 | 2985 | while (g_hash_table_iter_next (&iter, &key, &value)) | ||
3257 | 2986 | { | ||
3258 | 2987 | KatzeItem *hash_item = KATZE_ITEM(key); | ||
3259 | 2988 | |||
3260 | 2989 | gint64 parentid = katze_item_get_meta_integer (hash_item, "parentid"); | ||
3261 | 2990 | if (parentid == id) | ||
3262 | 2991 | { | ||
3263 | 2992 | g_hash_table_iter_remove (&iter); | ||
3264 | 2993 | g_object_unref (hash_item); | ||
3265 | 2994 | } | ||
3266 | 2995 | } | ||
3267 | 2996 | } | ||
3268 | 2997 | |||
3269 | 2998 | if ((found = g_hash_table_lookup (bookmarks->updated_items, item)) != NULL) | ||
3270 | 2999 | { | ||
3271 | 3000 | g_hash_table_remove (bookmarks->updated_items, found); | ||
3272 | 3001 | g_object_unref (found); | ||
3273 | 3002 | } | ||
3274 | 3003 | } | ||
3275 | 3004 | |||
3276 | 1340 | static void | 3005 | static void |
3277 | 1341 | midori_bookmarks_init (MidoriBookmarks* bookmarks) | 3006 | midori_bookmarks_init (MidoriBookmarks* bookmarks) |
3278 | 1342 | { | 3007 | { |
3279 | @@ -1349,6 +3014,8 @@ | |||
3280 | 1349 | GtkCellRenderer* renderer_text; | 3014 | GtkCellRenderer* renderer_text; |
3281 | 1350 | GtkTreeSelection* selection; | 3015 | GtkTreeSelection* selection; |
3282 | 1351 | 3016 | ||
3283 | 3017 | bookmarks->pending_event = NULL; | ||
3284 | 3018 | |||
3285 | 1352 | /* Create the filter entry */ | 3019 | /* Create the filter entry */ |
3286 | 1353 | entry = sokoke_search_entry_new (_("Search Bookmarks")); | 3020 | entry = sokoke_search_entry_new (_("Search Bookmarks")); |
3287 | 1354 | g_signal_connect_after (entry, "changed", | 3021 | g_signal_connect_after (entry, "changed", |
3288 | @@ -1359,7 +3026,7 @@ | |||
3289 | 1359 | gtk_box_pack_start (GTK_BOX (bookmarks), box, FALSE, FALSE, 5); | 3026 | gtk_box_pack_start (GTK_BOX (bookmarks), box, FALSE, FALSE, 5); |
3290 | 1360 | 3027 | ||
3291 | 1361 | /* Create the treeview */ | 3028 | /* Create the treeview */ |
3293 | 1362 | model = gtk_tree_store_new (2, KATZE_TYPE_ITEM, G_TYPE_STRING); | 3029 | model = midori_bookmarks_tree_store_new (2, KATZE_TYPE_ITEM, G_TYPE_STRING); |
3294 | 1363 | treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model)); | 3030 | treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model)); |
3295 | 1364 | gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE); | 3031 | gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE); |
3296 | 1365 | gtk_tree_view_set_tooltip_column (GTK_TREE_VIEW (treeview), 1); | 3032 | gtk_tree_view_set_tooltip_column (GTK_TREE_VIEW (treeview), 1); |
3297 | @@ -1376,19 +3043,32 @@ | |||
3298 | 1376 | (GtkTreeCellDataFunc)midori_bookmarks_treeview_render_text_cb, | 3043 | (GtkTreeCellDataFunc)midori_bookmarks_treeview_render_text_cb, |
3299 | 1377 | treeview, NULL); | 3044 | treeview, NULL); |
3300 | 1378 | gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); | 3045 | gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); |
3302 | 1379 | gtk_tree_view_set_reorderable (GTK_TREE_VIEW (treeview), TRUE); | 3046 | gtk_tree_view_set_reorderable (GTK_TREE_VIEW (treeview), FALSE); |
3303 | 3047 | gtk_tree_view_enable_model_drag_source ( | ||
3304 | 3048 | GTK_TREE_VIEW (treeview), | ||
3305 | 3049 | GDK_BUTTON1_MASK, | ||
3306 | 3050 | midori_bookmarks_dnd_target_entries, | ||
3307 | 3051 | MIDORI_BOOKMARKS_DND_NB_TARGET_ENTRIES, | ||
3308 | 3052 | GDK_ACTION_MOVE|GDK_ACTION_LINK); | ||
3309 | 3053 | gtk_tree_view_enable_model_drag_dest ( | ||
3310 | 3054 | GTK_TREE_VIEW (treeview), | ||
3311 | 3055 | midori_bookmarks_dnd_target_entries, | ||
3312 | 3056 | MIDORI_BOOKMARKS_DND_NB_TARGET_ENTRIES, | ||
3313 | 3057 | GDK_ACTION_MOVE|GDK_ACTION_LINK); | ||
3314 | 1380 | g_object_unref (model); | 3058 | g_object_unref (model); |
3315 | 1381 | g_object_connect (treeview, | 3059 | g_object_connect (treeview, |
3316 | 1382 | "signal::row-activated", | 3060 | "signal::row-activated", |
3317 | 1383 | midori_bookmarks_row_activated_cb, bookmarks, | 3061 | midori_bookmarks_row_activated_cb, bookmarks, |
3318 | 3062 | "signal::button-press-event", | ||
3319 | 3063 | midori_bookmarks_button_press_event_cb, bookmarks, | ||
3320 | 1384 | "signal::button-release-event", | 3064 | "signal::button-release-event", |
3321 | 1385 | midori_bookmarks_button_release_event_cb, bookmarks, | 3065 | midori_bookmarks_button_release_event_cb, bookmarks, |
3322 | 1386 | "signal::key-release-event", | 3066 | "signal::key-release-event", |
3323 | 1387 | midori_bookmarks_key_release_event_cb, bookmarks, | 3067 | midori_bookmarks_key_release_event_cb, bookmarks, |
3324 | 1388 | "signal::popup-menu", | 3068 | "signal::popup-menu", |
3325 | 1389 | midori_bookmarks_popup_menu_cb, bookmarks, | 3069 | midori_bookmarks_popup_menu_cb, bookmarks, |
3328 | 1390 | "signal::row-expanded", | 3070 | "signal::test-expand-row", |
3329 | 1391 | midori_bookmarks_row_expanded_cb, bookmarks, | 3071 | midori_bookmarks_test_expand_row_cb, bookmarks, |
3330 | 1392 | "signal::row-collapsed", | 3072 | "signal::row-collapsed", |
3331 | 1393 | midori_bookmarks_row_collapsed_cb, bookmarks, | 3073 | midori_bookmarks_row_collapsed_cb, bookmarks, |
3332 | 1394 | "signal::enter-notify-event", | 3074 | "signal::enter-notify-event", |
3333 | @@ -1398,18 +3078,27 @@ | |||
3334 | 1398 | "signal::leave-notify-event", | 3078 | "signal::leave-notify-event", |
3335 | 1399 | midori_bookmarks_leave_notify_event_cb, bookmarks, | 3079 | midori_bookmarks_leave_notify_event_cb, bookmarks, |
3336 | 1400 | NULL); | 3080 | NULL); |
3340 | 1401 | gtk_widget_add_events (GTK_WIDGET (treeview), | 3081 | |
3341 | 1402 | GDK_POINTER_MOTION_MASK | 3082 | MIDORI_BOOKMARKS_TREE_STORE (model)->_view = GTK_TREE_VIEW (treeview); |
3342 | 1403 | | GDK_POINTER_MOTION_HINT_MASK); | 3083 | |
3343 | 3084 | gtk_widget_add_events (GTK_WIDGET (treeview), | ||
3344 | 3085 | GDK_POINTER_MOTION_MASK | ||
3345 | 3086 | | GDK_POINTER_MOTION_HINT_MASK); | ||
3346 | 1404 | 3087 | ||
3347 | 1405 | selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); | 3088 | selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); |
3348 | 3089 | gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); | ||
3349 | 1406 | g_signal_connect_after (selection, "changed", | 3090 | g_signal_connect_after (selection, "changed", |
3352 | 1407 | G_CALLBACK (midori_bookmarks_selection_changed_cb), | 3091 | G_CALLBACK (midori_bookmarks_selection_changed_cb), |
3353 | 1408 | bookmarks); | 3092 | bookmarks); |
3354 | 1409 | gtk_widget_show (treeview); | 3093 | gtk_widget_show (treeview); |
3355 | 1410 | gtk_box_pack_start (GTK_BOX (bookmarks), treeview, TRUE, TRUE, 0); | 3094 | gtk_box_pack_start (GTK_BOX (bookmarks), treeview, TRUE, TRUE, 0); |
3356 | 1411 | bookmarks->treeview = treeview; | 3095 | bookmarks->treeview = treeview; |
3357 | 3096 | bookmarks->pending_inserts = NULL; | ||
3358 | 1412 | bookmarks->hovering_item = NULL; | 3097 | bookmarks->hovering_item = NULL; |
3359 | 3098 | bookmarks->pending_inserts = NULL; | ||
3360 | 3099 | bookmarks->updated_items = g_hash_table_new (item_hash, item_equal); | ||
3361 | 3100 | bookmarks->added_paths = NULL; | ||
3362 | 3101 | bookmarks->reordered_paths = NULL; | ||
3363 | 1413 | } | 3102 | } |
3364 | 1414 | 3103 | ||
3365 | 1415 | static void | 3104 | static void |
3366 | @@ -1420,5 +3109,16 @@ | |||
3367 | 1420 | if (bookmarks->app) | 3109 | if (bookmarks->app) |
3368 | 1421 | g_object_unref (bookmarks->app); | 3110 | g_object_unref (bookmarks->app); |
3369 | 1422 | if (bookmarks->hovering_item) | 3111 | if (bookmarks->hovering_item) |
3371 | 1423 | g_object_unref (bookmarks->hovering_item); | 3112 | g_object_unref (bookmarks->hovering_item); |
3372 | 3113 | |||
3373 | 3114 | if (g_idle_remove_by_data (bookmarks)) | ||
3374 | 3115 | { | ||
3375 | 3116 | g_list_free_full (bookmarks->pending_inserts, (GDestroyNotify) g_object_unref); | ||
3376 | 3117 | bookmarks->pending_inserts = NULL; | ||
3377 | 3118 | g_hash_table_unref (bookmarks->updated_items); | ||
3378 | 3119 | g_list_free_full (bookmarks->added_paths, (GDestroyNotify) gtk_tree_path_free); | ||
3379 | 3120 | bookmarks->added_paths = NULL; | ||
3380 | 3121 | g_list_free_full (bookmarks->reordered_paths, (GDestroyNotify) gtk_tree_path_free); | ||
3381 | 3122 | bookmarks->reordered_paths = NULL; | ||
3382 | 3123 | } | ||
3383 | 1424 | } | 3124 | } |
3384 | 1425 | 3125 | ||
3385 | === modified file 'tests/bookmarks.c' | |||
3386 | --- tests/bookmarks.c 2013-08-05 19:52:52 +0000 | |||
3387 | +++ tests/bookmarks.c 2014-01-30 21:24:26 +0000 | |||
3388 | @@ -128,7 +128,7 @@ | |||
3389 | 128 | } | 128 | } |
3390 | 129 | 129 | ||
3391 | 130 | db_items = midori_bookmarks_db_query_recursive (db_bookmarks, | 130 | db_items = midori_bookmarks_db_query_recursive (db_bookmarks, |
3393 | 131 | "*", "title='%q'", katze_item_get_name (test_item), FALSE); | 131 | "*", "title='%q'", katze_item_get_name (test_item), NULL, FALSE); |
3394 | 132 | 132 | ||
3395 | 133 | /* FIXME g_assert_cmpint (katze_array_get_length (db_items), ==, 1); */ | 133 | /* FIXME g_assert_cmpint (katze_array_get_length (db_items), ==, 1); */ |
3396 | 134 | db_item = katze_array_get_nth_item (db_items, 0); | 134 | db_item = katze_array_get_nth_item (db_items, 0); |
Updated with merge in of lp:~aauzi/midori/fix-1179200-9 and lp:midori.
Bookmark item positions are now properly managed in both menus and panel.
Multiple bookmark selection and drag-n-drop in the bookmark panel allow bookmark ordering.