Merge lp:~aauzi/midori/fix-1179200 into lp:midori
- fix-1179200
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~aauzi/midori/fix-1179200 |
Merge into: | lp:midori |
Diff against target: |
2005 lines (+1212/-305) 9 files modified
katze/katze-array.c (+40/-0) katze/katze-array.h (+4/-0) katze/katze-item.c (+8/-2) midori/midori-array.c (+9/-7) midori/midori-bookmarks.c (+632/-45) midori/midori-bookmarks.h (+10/-12) midori/midori-browser.c (+77/-38) panels/midori-bookmarks.c (+432/-187) panels/midori-bookmarks.h (+0/-14) |
To merge this branch: | bzr merge lp:~aauzi/midori/fix-1179200 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
André Auzi | Needs Resubmitting | ||
Midori Devs | Pending | ||
Review via email:
|
This proposal has been superseded by a proposal from 2013-06-05.
Commit message
Description of the change
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Cris Dywan (kalikiana) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Cris Dywan (kalikiana) wrote : | # |
A side note on the comment "panels/
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
André Auzi (aauzi) wrote : | # |
> - if (item->parent)
> - katze_array_update ((KatzeArray*
> + if (item->parent && g_strcmp0(icon, picon))
> + katze_array_
>
> katze_array_
> that should be mentioned by marking the old one as Deprecated for clarity.
Not exactly... I kept the update for one purpose, the update of the whole data structure.
Basically here, the update in the bookmark panel, clears the whole tree and reloads it.
It thought this use case was still needed for features like bookmark imports, especially the way it is still designed.
Basically, the array_tree is a container. update is signal signaling an item and its containees, update_item only the item.
You probably have noticed that the update_item in the panel basically:
* finds the item in the tree
* unlinks it from where it is
* finds its new parent
* and relinks the item at its new position.
It doesn't do much if the item and its new parent is not visible.
So far, the bookmark bar does not implement such behaviour, it only refresh the whol bar on item change. This would probablye have to be changed for correct DND reordering of the bookmark bar.
> The checks like g_strcmp0(icon, picon) seem to avoid updating if nothing
> changed - in that case, why not do this for all values in each function?
Well, I didn't do it because it would most probably generate a lot of useless signal traffic.
The design I choose make midori/
I therefore just kept the automatic signal of the container on containee change where it was in place (I believe it's due to site title and favicon update after page load, isn't it?)
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
André Auzi (aauzi) wrote : | # |
> A side note on the comment "panels/
> historically the code is badly mixed, in an ideal world both the panel and the
> toolbar should be independent views. Much like the Transfers extension these
> days.
Yes, I've identified the Model-View-
* the data base is the Model
* the midori/
* and bookmarkbar and bookmarkpanel are Views of this model.
With this design pattern actions on the model should go through the controller and that's what I've implemented for delete and update.
I did not do it for insert for two reasons:
1. I didn't intend to change the whole design. I believe there are historical reasons to designs decision that may not be obvious on quick examination. The less I touch the better everybody is :)
2. I do not have a satisfying solution for the provision of the parentid on the insert of a child item I've seen in the file import. No solution => no change.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Cris Dywan (kalikiana) wrote : | # |
> > The checks like g_strcmp0(icon, picon) seem to avoid updating if nothing
> > changed - in that case, why not do this for all values in each function?
> Well, I didn't do it because it would most probably generate a lot of useless signal traffic.
> The design I choose make midori/
> I therefore just kept the automatic signal of the container on containee change where it was in place
> (I believe it's due to site title and favicon update after page load, isn't it?)
What I meant was to wrap the whole of the values that change, for example:
{
gchar* pname;
g_
pname = item->name;
if (item->parent && g_strcmp0(name, pname))
{
}
}
I also realize you're doing "pname = item->name" before g_return_if_fail - don't, it will crash if the assertion is hit. Do it as I do above to be on the safe side.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
André Auzi (aauzi) wrote : | # |
> What I meant was to wrap the whole of the values that change, for example:
>
> {
> gchar* pname;
> g_return_if_fail (KATZE_IS_ITEM (item));
> pname = item->name;
> if (item->parent && g_strcmp0(name, pname))
> {
> katze_assign (item->name, g_strdup (name));
> katze_array_
> g_object_notify (G_OBJECT (item), "name");
> }
> }
>
> I also realize you're doing "pname = item->name" before g_return_if_fail -
> don't, it will crash if the assertion is hit. Do it as I do above to be on the
> safe side.
OK, understood and agreed.
I will change that.
- 6171. By André Auzi
-
1. fix of change value protection in katze_item_set_name and katze_item_set_icon
2. replace remaining katze_array_update by katze_array_update_ item in katze_item_set_name
note: global update katze_array_update mechanism still in use for:
a- initial populate of bookmarks and extensions,
b- bookmarks imports
3. fix patch application regression
--- midori/midori- browser. c 2013-05-21 19:20:44 +0000
+++ midori/midori- browser. c 2013-05-28 18:58:04 +0000
@@ -6127,6 +6127,8 @@
"array", dummy_array /* updated, unique */,
NULL);
g_object_ connect (action,
+ "signal::populate- folder" ,
+ _action_bookmarks_ populate_ folder, browser,
"signal: :activate- item-alt" ,
midori_ bookmarkbar_ activate_ item_alt, browser,
NULL) ;
@@ -6143,8 +6145,6 @@
"array", dummy_array /* updated, unique */,
NULL);
g_object_ connect (action,
- "signal::populate- folder" ,
- _action_bookmarks_ populate_ folder, browser,
"signal: :populate- popup",
_action_ tools_populate_ popup, browser,
"signal: :activate- item-alt" ,
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
André Auzi (aauzi) wrote : | # |
> > A side note on the comment "panels/
> yes,
> > historically the code is badly mixed, in an ideal world both the panel and
> the
> > toolbar should be independent views. Much like the Transfers extension these
> > days.
>
> Yes, I've identified the Model-View-
> code is organised:
> * the data base is the Model
> * the midori/
> * and bookmarkbar and bookmarkpanel are Views of this model.
>
> With this design pattern actions on the model should go through the controller
> and that's what I've implemented for delete and update.
> I did not do it for insert for two reasons:
Let's do a little follow up on this topic.
Thanks to your remark in Bug #1185595 I felt encouraged to investigate the way bookmarks are retrieved from the database.
My investigations led me to two observations:
1- katze_array_
2- katze_array_
My conclusions are the following:
1- katze_array_
2- midori_
3- it should then parse the result rows for 'uri' value in order to determine if it can populate a katze_item or a katze_array of type KATZE_TYPE_ITEM
The connection with this bug fix proposal is the following.
The new function midori_
This would allow us to implement one additional steps forward in the direction of convergence of the bookmarks data and fix a concern pfor and I share, the triplication of data between bookmarks menu, bookmarkbar item and bookmarks side panel.
The hash table I used to implement packing of updates, or something similar, can also be used for items retrieval, before populating new items, midori_
Of course, the rows data should be inserted in an existing item, different client view may need different metadata.
To integrate well with the existing fix proposal, midori_
pfor, again, tipped me on how this flush could be sped up further: updates should be enclosed into SQLite transactions.
Finally, I was mentioning I did not have a solution for the insert, I think it is not the case anymore.
The katze_array_
This callback should change a folder implemented in katze_item into an empty katze_array of type
KATZE_ARRAY_ITEM before inserting it in the database
It should also go through a katze_array of type KATZE_ARRAY:
1- insert all child bookm...
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
André Auzi (aauzi) wrote : | # |
> The consequences on the client views are the following:
> 1- they should ignore add_item of katze_array which are not type
> KATZE_TYPE_ITEM
> 2- they should ignore add_item of katze_item of a folder
>
Additional note:
The consequence on client side may be totally removed if midori_bookmarks derives from katze_array and implements the preprocessing of folders (convert in katze_array of type KATZE_ARRAY_ITEM) and the population of the content of a katze_array is done in a specialization of katze_array_
By doing so we could ensure that *valid* items would be signaled to the client views.
- 6172. By André Auzi
-
merge lp:midori
- 6173. By André Auzi
-
merge lp:midori
- 6174. By André Auzi
-
prototype of bookmarks DB with transactions
+ minor fix in xbel import - 6175. By André Auzi
-
merge lp:midori + fix Bookmarks vs Tools menue issue
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
André Auzi (aauzi) wrote : | # |
Ok, I've prototyped the ideas shared in the previous comment.
Now, all the database operations are implemented in midori/
The result is impressive, my 883 bookmarks are now imported in #500ms where it was previously taking more than 6s.
The katze_array_
Well, this is not clean code yet (far from it) but I was so excited by the impressive improvement that I wanted to share it for maybe some stress test feedback.
I therefore resubmit it as it is and will implement suggested changes in a clean update.
- 6176. By André Auzi
-
cleanups and fix of remove and add item issue
- 6177. By André Auzi
-
merge lp:midori
- 6178. By André Auzi
-
more cleanups
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
André Auzi (aauzi) wrote : | # |
Well, this is now clean enough.
- 6179. By André Auzi
-
implement complete derivation from KatzeArray for proper database interaction.
midori/midori- bookmarks. [ch] -> midori/ midori- bookmarks- db.[ch]
class MidoriBookmarksDb created. - 6180. By André Auzi
-
merge lp:midori
move midori_array_count_ recursive into midori_ bookmarks_ db_count_ recursive - 6181. By André Auzi
-
fix relay method selection
- 6182. By André Auzi
-
revert changes in katze-item and katze-array,
localize them in midori-bookmarks-db - 6183. By André Auzi
-
merge lp:midori
- 6184. By André Auzi
-
insert change 6208 from lp:midori
- 6185. By André Auzi
-
cosmetics coding style
- 6186. By André Auzi
-
adapt bookmarks unit tests and fix add item issue
- 6187. By André Auzi
-
cleanup update_item implementation
- 6188. By André Auzi
-
merge lp:midori
- 6189. By André Auzi
-
merge lp:midori
- 6190. By André Auzi
-
fix potential memory leak
Unmerged revisions
- 6190. By André Auzi
-
fix potential memory leak
- 6189. By André Auzi
-
merge lp:midori
- 6188. By André Auzi
-
merge lp:midori
- 6187. By André Auzi
-
cleanup update_item implementation
- 6186. By André Auzi
-
adapt bookmarks unit tests and fix add item issue
- 6185. By André Auzi
-
cosmetics coding style
- 6184. By André Auzi
-
insert change 6208 from lp:midori
- 6183. By André Auzi
-
merge lp:midori
- 6182. By André Auzi
-
revert changes in katze-item and katze-array,
localize them in midori-bookmarks-db - 6181. By André Auzi
-
fix relay method selection
Preview Diff
1 | === modified file 'katze/katze-array.c' |
2 | --- katze/katze-array.c 2012-08-08 23:02:56 +0000 |
3 | +++ katze/katze-array.c 2013-06-05 17:59:27 +0000 |
4 | @@ -42,6 +42,9 @@ |
5 | (*add_item) (KatzeArray* array, |
6 | gpointer item); |
7 | void |
8 | + (*update_item) (KatzeArray* array, |
9 | + gpointer item); |
10 | + void |
11 | (*remove_item) (KatzeArray* array, |
12 | gpointer item); |
13 | void |
14 | @@ -59,6 +62,7 @@ |
15 | |
16 | enum { |
17 | ADD_ITEM, |
18 | + UPDATE_ITEM, |
19 | REMOVE_ITEM, |
20 | MOVE_ITEM, |
21 | CLEAR, |
22 | @@ -95,6 +99,13 @@ |
23 | } |
24 | |
25 | static void |
26 | +_katze_array_update_item (KatzeArray* array, |
27 | + gpointer item) |
28 | +{ |
29 | + _katze_array_update (array); |
30 | +} |
31 | + |
32 | +static void |
33 | _katze_array_remove_item (KatzeArray* array, |
34 | gpointer item) |
35 | { |
36 | @@ -147,6 +158,17 @@ |
37 | G_TYPE_NONE, 1, |
38 | G_TYPE_POINTER); |
39 | |
40 | + signals[UPDATE_ITEM] = g_signal_new ( |
41 | + "update-item", |
42 | + G_TYPE_FROM_CLASS (class), |
43 | + (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION), |
44 | + G_STRUCT_OFFSET (KatzeArrayClass, add_item), |
45 | + 0, |
46 | + NULL, |
47 | + g_cclosure_marshal_VOID__POINTER, |
48 | + G_TYPE_NONE, 1, |
49 | + G_TYPE_POINTER); |
50 | + |
51 | signals[REMOVE_ITEM] = g_signal_new ( |
52 | "remove-item", |
53 | G_TYPE_FROM_CLASS (class), |
54 | @@ -213,6 +235,7 @@ |
55 | gobject_class->finalize = katze_array_finalize; |
56 | |
57 | class->add_item = _katze_array_add_item; |
58 | + class->update_item = _katze_array_update_item; |
59 | class->remove_item = _katze_array_remove_item; |
60 | class->move_item = _katze_array_move_item; |
61 | class->clear = _katze_array_clear; |
62 | @@ -301,6 +324,23 @@ |
63 | } |
64 | |
65 | /** |
66 | + * katze_array_update_item: |
67 | + * @array: a #KatzeArray |
68 | + * @item: an item |
69 | + * |
70 | + * Notify an update of the item of the array. |
71 | + * |
72 | + **/ |
73 | +void |
74 | +katze_array_update_item (KatzeArray* array, |
75 | + gpointer item) |
76 | +{ |
77 | + g_return_if_fail (KATZE_IS_ARRAY (array)); |
78 | + |
79 | + g_signal_emit (array, signals[UPDATE_ITEM], 0, item); |
80 | +} |
81 | + |
82 | +/** |
83 | * katze_array_remove_item: |
84 | * @array: a #KatzeArray |
85 | * @item: an item |
86 | |
87 | === modified file 'katze/katze-array.h' |
88 | --- katze/katze-array.h 2011-01-19 20:58:26 +0000 |
89 | +++ katze/katze-array.h 2013-06-05 17:59:27 +0000 |
90 | @@ -47,6 +47,10 @@ |
91 | gpointer item); |
92 | |
93 | void |
94 | +katze_array_update_item (KatzeArray* array, |
95 | + gpointer item); |
96 | + |
97 | +void |
98 | katze_array_remove_item (KatzeArray* array, |
99 | gpointer item); |
100 | |
101 | |
102 | === modified file 'katze/katze-item.c' |
103 | --- katze/katze-item.c 2013-02-21 21:36:30 +0000 |
104 | +++ katze/katze-item.c 2013-06-05 17:59:27 +0000 |
105 | @@ -316,9 +316,12 @@ |
106 | { |
107 | g_return_if_fail (KATZE_IS_ITEM (item)); |
108 | |
109 | + if (!g_strcmp0 (item->name, name)) |
110 | + return; |
111 | + |
112 | katze_assign (item->name, g_strdup (name)); |
113 | if (item->parent) |
114 | - katze_array_update ((KatzeArray*)item->parent); |
115 | + katze_array_update_item ((KatzeArray*)item->parent, item); |
116 | g_object_notify (G_OBJECT (item), "name"); |
117 | } |
118 | |
119 | @@ -420,9 +423,12 @@ |
120 | { |
121 | g_return_if_fail (KATZE_IS_ITEM (item)); |
122 | |
123 | + if (!g_strcmp0 (katze_item_get_meta_string (item, "icon"), icon)) |
124 | + return; |
125 | + |
126 | katze_item_set_meta_string (item, "icon", icon); |
127 | if (item->parent) |
128 | - katze_array_update ((KatzeArray*)item->parent); |
129 | + katze_array_update_item ((KatzeArray*)item->parent, item); |
130 | g_object_notify (G_OBJECT (item), "icon"); |
131 | } |
132 | |
133 | |
134 | === modified file 'midori/midori-array.c' |
135 | --- midori/midori-array.c 2013-04-16 23:16:24 +0000 |
136 | +++ midori/midori-array.c 2013-06-05 17:59:27 +0000 |
137 | @@ -97,15 +97,15 @@ |
138 | if (katze_str_equal ((gchar*)cur->name, "title")) |
139 | { |
140 | gchar* value = g_strstrip ((gchar*)xmlNodeGetContent (cur)); |
141 | + katze_item_set_name (KATZE_ITEM (array), value); |
142 | + xmlFree (value); |
143 | + } |
144 | + else if (katze_str_equal ((gchar*)cur->name, "desc")) |
145 | + { |
146 | + gchar* value = g_strstrip ((gchar*)xmlNodeGetContent (cur)); |
147 | katze_item_set_text (KATZE_ITEM (array), value); |
148 | xmlFree (value); |
149 | } |
150 | - else if (katze_str_equal ((gchar*)cur->name, "desc")) |
151 | - { |
152 | - gchar* value = g_strstrip ((gchar*)xmlNodeGetContent (cur)); |
153 | - katze_item_set_name (KATZE_ITEM (array), value); |
154 | - xmlFree (value); |
155 | - } |
156 | else if (katze_str_equal ((gchar*)cur->name, "info")) |
157 | katze_xbel_parse_info ((KatzeItem*)array, cur); |
158 | else if (katze_str_equal ((gchar*)cur->name, "folder")) |
159 | @@ -986,7 +986,7 @@ |
160 | return FALSE; |
161 | } |
162 | |
163 | -static void |
164 | +/* static */ void |
165 | katze_item_set_value_from_column (sqlite3_stmt* stmt, |
166 | gint column, |
167 | KatzeItem* item) |
168 | @@ -1116,6 +1116,8 @@ |
169 | * Return value: a #KatzeArray on success, %NULL otherwise |
170 | * |
171 | * Since: 0.4.4 |
172 | + * |
173 | + * Deprecated: 0.5.2: Use midori_bookmarks_query_recursive() instead. |
174 | **/ |
175 | KatzeArray* |
176 | midori_array_query_recursive (KatzeArray* bookmarks, |
177 | |
178 | === modified file 'midori/midori-bookmarks.c' |
179 | --- midori/midori-bookmarks.c 2012-11-25 15:37:41 +0000 |
180 | +++ midori/midori-bookmarks.c 2013-06-05 17:59:27 +0000 |
181 | @@ -25,6 +25,30 @@ |
182 | #include <unistd.h> |
183 | #endif |
184 | |
185 | +#define MIDORI_BOOKMARKS_DB_CONTROL(a) ((MidoriBookmarksDBControl*)(a)) |
186 | +typedef struct _MidoriBookmarksDBControl MidoriBookmarksDBControl; |
187 | +struct _MidoriBookmarksDBControl |
188 | +{ |
189 | + sqlite3* db; |
190 | + GList* pending_inserts; |
191 | + GHashTable* pending_updates; |
192 | + GHashTable* pending_deletes; |
193 | + GHashTable* all_items; |
194 | +}; |
195 | + |
196 | +static gint64 |
197 | +midori_bookmarks_insert_item_db (sqlite3* db, |
198 | + KatzeItem* item, |
199 | + gint64 parentid); |
200 | + |
201 | +static gboolean |
202 | +midori_bookmarks_update_item_db (sqlite3* db, |
203 | + KatzeItem* item); |
204 | + |
205 | +static gboolean |
206 | +midori_bookmarks_remove_item_db (sqlite3* db, |
207 | + KatzeItem* item); |
208 | + |
209 | void |
210 | midori_bookmarks_dbtracer (void* dummy, |
211 | const char* query) |
212 | @@ -32,35 +56,415 @@ |
213 | g_printerr ("%s\n", query); |
214 | } |
215 | |
216 | -void |
217 | +static guint |
218 | +item_hash (gconstpointer item) |
219 | +{ |
220 | + gint64 id = katze_item_get_meta_integer (KATZE_ITEM (item), "id"); |
221 | + return g_int64_hash (&id); |
222 | +} |
223 | + |
224 | +static gboolean |
225 | +item_equal (gconstpointer item_a, gconstpointer item_b) |
226 | +{ |
227 | + gint64 id_a = katze_item_get_meta_integer (KATZE_ITEM (item_a), "id"); |
228 | + gint64 id_b = katze_item_get_meta_integer (KATZE_ITEM (item_b), "id"); |
229 | + return (id_a == id_b)? TRUE : FALSE; |
230 | +} |
231 | + |
232 | +static gboolean |
233 | +midori_bookmarks_begin_transaction (sqlite3* db) |
234 | +{ |
235 | + char* errmsg = NULL; |
236 | + |
237 | + if (sqlite3_exec (db, "BEGIN TRANSACTION;", NULL, NULL, &errmsg) != SQLITE_OK) |
238 | + { |
239 | + g_printerr (_("Failed to begin transaction: %s\n"), errmsg); |
240 | + sqlite3_free (errmsg); |
241 | + return FALSE; |
242 | + } |
243 | + |
244 | + return TRUE; |
245 | +} |
246 | + |
247 | +static gboolean |
248 | +midori_bookmarks_end_transaction (sqlite3* db, gboolean commit) |
249 | +{ |
250 | + char* errmsg = NULL; |
251 | + if (sqlite3_exec (db, (commit ? "COMMIT;" : "ROLLBACK;"), NULL, NULL, &errmsg) != SQLITE_OK) |
252 | + { |
253 | + if (commit) |
254 | + g_printerr (_("Failed to end transaction: %s\n"), errmsg); |
255 | + else |
256 | + g_printerr (_("Failed to cancel transaction: %s\n"), errmsg); |
257 | + sqlite3_free (errmsg); |
258 | + return FALSE; |
259 | + } |
260 | + |
261 | + return TRUE; |
262 | +} |
263 | + |
264 | +static gint |
265 | +midori_bookmarks_insert_item (MidoriBookmarksDBControl* control, |
266 | + KatzeItem* item) |
267 | +{ |
268 | + GList* list; |
269 | + KatzeArray* array; |
270 | + gint64 id = 0; |
271 | + gint count = 0; |
272 | + gint64 parentid = katze_item_get_meta_integer (item, "parentid"); |
273 | + |
274 | + id = midori_bookmarks_insert_item_db (control->db, item, parentid); |
275 | + count++; |
276 | + |
277 | + g_object_ref (item); |
278 | + g_hash_table_insert (control->all_items, item, item); |
279 | + |
280 | + if (!KATZE_IS_ARRAY (item)) |
281 | + return count; |
282 | + |
283 | + array = KATZE_ARRAY (item); |
284 | + |
285 | + KATZE_ARRAY_FOREACH_ITEM_L (item, array, list) |
286 | + { |
287 | + katze_item_set_meta_integer (item, "parentid", id); |
288 | + count += midori_bookmarks_insert_item (control, item); |
289 | + } |
290 | + |
291 | + g_list_free (list); |
292 | + return count; |
293 | +} |
294 | + |
295 | +static void |
296 | +midori_bookmarks_remove_item (KatzeItem* item, |
297 | + MidoriBookmarksDBControl* control) |
298 | +{ |
299 | + gint64 id = katze_item_get_meta_integer (item, "id"); |
300 | + GHashTableIter hash_iter; |
301 | + gpointer key, value; |
302 | + gpointer found; |
303 | + GList* childs = NULL; |
304 | + GList* list_iter; |
305 | + |
306 | + if (found = g_list_find (control->pending_inserts, item)) |
307 | + { |
308 | + g_object_unref (((GList*)found)->data); |
309 | + control->pending_inserts = g_list_delete_link (control->pending_inserts, |
310 | + ((GList*)found)); |
311 | + } |
312 | + |
313 | + if (found = g_hash_table_lookup (control->pending_updates, item)) |
314 | + { |
315 | + g_hash_table_remove (control->pending_updates, found); |
316 | + g_object_unref (found); |
317 | + } |
318 | + |
319 | + if (found = g_hash_table_lookup (control->all_items, item)) |
320 | + { |
321 | + g_hash_table_remove (control->all_items, found); |
322 | + g_object_unref (found); |
323 | + } |
324 | + |
325 | + if (!KATZE_ITEM_IS_FOLDER (item)) |
326 | + return; |
327 | + |
328 | + g_hash_table_iter_init (&hash_iter, control->all_items); |
329 | + |
330 | + while (g_hash_table_iter_next (&hash_iter, &key, &value)) |
331 | + { |
332 | + KatzeItem *hash_item = KATZE_ITEM (value); |
333 | + gint64 parentid = katze_item_get_meta_integer (hash_item, "parentid"); |
334 | + |
335 | + if (parentid != id) |
336 | + continue; |
337 | + |
338 | + childs = g_list_append (childs, hash_item); |
339 | + } |
340 | + |
341 | + for (list_iter = childs; list_iter; list_iter = g_list_next (list_iter)) |
342 | + { |
343 | + KatzeItem *list_item = KATZE_ITEM (list_iter->data); |
344 | + |
345 | + midori_bookmarks_remove_item (list_item, control); |
346 | + } |
347 | + |
348 | + g_list_free (childs); |
349 | +} |
350 | + |
351 | +static gboolean |
352 | +midori_bookmarks_idle_func (gpointer data) |
353 | +{ |
354 | + GTimer *timer = g_timer_new(); |
355 | + gint count = 0; |
356 | + gulong microseconds; |
357 | + gboolean with_transaction; |
358 | + KatzeArray* bookmarks = KATZE_ARRAY (data); |
359 | + MidoriBookmarksDBControl* control = g_object_get_data (G_OBJECT (bookmarks), "control"); |
360 | + GList* list_iter; |
361 | + GHashTableIter hash_iter; |
362 | + gpointer key, value; |
363 | + |
364 | + g_timer_start (timer); |
365 | + |
366 | + with_transaction = midori_bookmarks_begin_transaction (control->db); |
367 | + |
368 | + for (list_iter = control->pending_inserts; list_iter; list_iter = g_list_next (list_iter)) |
369 | + { |
370 | + KatzeItem *item = KATZE_ITEM (list_iter->data); |
371 | + |
372 | + count += midori_bookmarks_insert_item (control, item); |
373 | + |
374 | + g_object_unref (item); |
375 | + } |
376 | + |
377 | + g_hash_table_iter_init (&hash_iter, control->pending_updates); |
378 | + |
379 | + while (g_hash_table_iter_next (&hash_iter, &key, &value)) |
380 | + { |
381 | + KatzeItem *item = KATZE_ITEM (value); |
382 | + |
383 | + midori_bookmarks_update_item_db (control->db, item); |
384 | + g_object_unref (item); |
385 | + count++; |
386 | + } |
387 | + |
388 | + g_hash_table_iter_init (&hash_iter, control->pending_deletes); |
389 | + |
390 | + while (g_hash_table_iter_next (&hash_iter, &key, &value)) |
391 | + { |
392 | + KatzeItem *item = KATZE_ITEM (value); |
393 | + |
394 | + midori_bookmarks_remove_item_db (control->db, item); |
395 | + g_object_unref (item); |
396 | + count++; |
397 | + } |
398 | + |
399 | + if (with_transaction) |
400 | + midori_bookmarks_end_transaction (control->db, TRUE); |
401 | + |
402 | + g_timer_elapsed (timer, µseconds); |
403 | + g_print ("midori_bookmarks_idle: %d DB operation(s) in %lu micro-seconds\n", |
404 | + count, microseconds); |
405 | + |
406 | + g_timer_destroy (timer); |
407 | + |
408 | + g_hash_table_remove_all (control->pending_deletes); |
409 | + g_hash_table_remove_all (control->pending_updates); |
410 | + g_list_free (control->pending_inserts); |
411 | + control->pending_inserts = NULL; |
412 | + |
413 | + return FALSE; |
414 | +} |
415 | + |
416 | +static void |
417 | +midori_bookmarks_idle_start (KatzeArray* array, |
418 | + MidoriBookmarksDBControl* control) |
419 | +{ |
420 | + if (control->pending_inserts |
421 | + || g_hash_table_size (control->pending_updates) |
422 | + || g_hash_table_size (control->pending_deletes)) |
423 | + return; |
424 | + |
425 | + g_idle_add (midori_bookmarks_idle_func, array); |
426 | +} |
427 | + |
428 | +static void |
429 | midori_bookmarks_add_item_cb (KatzeArray* array, |
430 | KatzeItem* item, |
431 | - sqlite3* db) |
432 | -{ |
433 | - midori_bookmarks_insert_item_db (db, item, |
434 | - katze_item_get_meta_integer (item, "parentid")); |
435 | -} |
436 | - |
437 | -void |
438 | + MidoriBookmarksDBControl* control) |
439 | +{ |
440 | + gpointer found = g_list_find (control->pending_inserts, item); |
441 | + |
442 | + if (found) |
443 | + return; |
444 | + |
445 | + midori_bookmarks_idle_start (array, control); |
446 | + |
447 | + g_object_ref (item); |
448 | + control->pending_inserts = g_list_append (control->pending_inserts, item); |
449 | +} |
450 | + |
451 | +static void |
452 | +midori_bookmarks_update_item_cb (KatzeArray* array, |
453 | + KatzeItem* item, |
454 | + MidoriBookmarksDBControl* control) |
455 | +{ |
456 | + gpointer found = g_hash_table_lookup (control->pending_updates, item); |
457 | + |
458 | + if (found) |
459 | + return; |
460 | + |
461 | + midori_bookmarks_idle_start (array, control); |
462 | + |
463 | + g_object_ref (item); |
464 | + g_hash_table_insert (control->pending_updates, item, item); |
465 | +} |
466 | + |
467 | +static void |
468 | midori_bookmarks_remove_item_cb (KatzeArray* array, |
469 | KatzeItem* item, |
470 | - sqlite3* db) |
471 | -{ |
472 | - gchar* sqlcmd; |
473 | - char* errmsg = NULL; |
474 | - |
475 | - |
476 | - sqlcmd = sqlite3_mprintf ( |
477 | - "DELETE FROM bookmarks WHERE id = %" G_GINT64_FORMAT ";", |
478 | + MidoriBookmarksDBControl* control) |
479 | +{ |
480 | + gpointer found = g_hash_table_lookup (control->pending_deletes, item); |
481 | + |
482 | + if (found) |
483 | + return; |
484 | + |
485 | + midori_bookmarks_idle_start (array, control); |
486 | + |
487 | + midori_bookmarks_remove_item (item, control); |
488 | + |
489 | + g_object_ref (item); |
490 | + g_hash_table_insert (control->pending_deletes, item, item); |
491 | +} |
492 | + |
493 | +static gint64 |
494 | +midori_bookmarks_insert_item_db (sqlite3* db, |
495 | + KatzeItem* item, |
496 | + gint64 parentid) |
497 | +{ |
498 | + gchar* sqlcmd; |
499 | + char* errmsg = NULL; |
500 | + KatzeItem* old_parent; |
501 | + gchar* new_parentid; |
502 | + gchar* id = NULL; |
503 | + const gchar* uri = NULL; |
504 | + const gchar* desc = NULL; |
505 | + gint64 seq = 0; |
506 | + |
507 | + /* Bookmarks must have a name, import may produce invalid items */ |
508 | + g_return_val_if_fail (katze_item_get_name (item), seq); |
509 | + |
510 | + if (!db) |
511 | + return seq; |
512 | + |
513 | + if (katze_item_get_meta_integer (item, "id") > 0) |
514 | + id = g_strdup_printf ("%" G_GINT64_FORMAT, katze_item_get_meta_integer(item, "id")); |
515 | + else |
516 | + id = g_strdup_printf ("NULL"); |
517 | + |
518 | + if (KATZE_ITEM_IS_BOOKMARK (item)) |
519 | + uri = katze_item_get_uri (item); |
520 | + |
521 | + if (katze_item_get_text (item)) |
522 | + desc = katze_item_get_text (item); |
523 | + |
524 | + /* Use folder, otherwise fallback to parent folder */ |
525 | + old_parent = katze_item_get_parent (item); |
526 | + if (parentid > 0) |
527 | + new_parentid = g_strdup_printf ("%" G_GINT64_FORMAT, parentid); |
528 | + else if (old_parent && katze_item_get_meta_integer (old_parent, "id") > 0) |
529 | + new_parentid = g_strdup_printf ("%" G_GINT64_FORMAT, katze_item_get_meta_integer (old_parent, "id")); |
530 | + else |
531 | + new_parentid = g_strdup_printf ("NULL"); |
532 | + |
533 | + sqlcmd = sqlite3_mprintf ( |
534 | + "INSERT INTO bookmarks (id, parentid, title, uri, desc, toolbar, app) " |
535 | + "VALUES (%q, %q, '%q', '%q', '%q', %d, %d)", |
536 | + id, |
537 | + new_parentid, |
538 | + katze_item_get_name (item), |
539 | + katze_str_non_null (uri), |
540 | + katze_str_non_null (desc), |
541 | + katze_item_get_meta_boolean (item, "toolbar"), |
542 | + katze_item_get_meta_boolean (item, "app")); |
543 | + |
544 | + if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) == SQLITE_OK) |
545 | + { |
546 | + /* Get insert id */ |
547 | + if (g_str_equal (id, "NULL")) |
548 | + { |
549 | + KatzeArray* seq_array; |
550 | + |
551 | + sqlite3_free (sqlcmd); |
552 | + sqlcmd = sqlite3_mprintf ( |
553 | + "SELECT seq FROM sqlite_sequence WHERE name = 'bookmarks'"); |
554 | + |
555 | + seq_array = katze_array_from_sqlite (db, sqlcmd); |
556 | + if (katze_array_get_nth_item (seq_array, 0)) |
557 | + { |
558 | + KatzeItem* seq_item = katze_array_get_nth_item (seq_array, 0); |
559 | + |
560 | + seq = katze_item_get_meta_integer (seq_item, "seq"); |
561 | + katze_item_set_meta_integer (item, "id", seq); |
562 | + } |
563 | + g_object_unref (seq_array); |
564 | + } |
565 | + } |
566 | + else |
567 | + { |
568 | + g_printerr (_("Failed to add bookmark item: %s\n"), errmsg); |
569 | + sqlite3_free (errmsg); |
570 | + } |
571 | + |
572 | + sqlite3_free (sqlcmd); |
573 | + g_free (new_parentid); |
574 | + g_free (id); |
575 | + |
576 | + return seq; |
577 | +} |
578 | + |
579 | +static gboolean |
580 | +midori_bookmarks_update_item_db (sqlite3* db, |
581 | + KatzeItem* item) |
582 | +{ |
583 | + gchar* sqlcmd; |
584 | + char* errmsg = NULL; |
585 | + gchar* parentid; |
586 | + gboolean updated; |
587 | + |
588 | + if (katze_item_get_meta_integer (item, "parentid") > 0) |
589 | + parentid = g_strdup_printf ("%" G_GINT64_FORMAT, |
590 | + katze_item_get_meta_integer (item, "parentid")); |
591 | + else |
592 | + parentid = g_strdup_printf ("NULL"); |
593 | + |
594 | + sqlcmd = sqlite3_mprintf ( |
595 | + "UPDATE bookmarks SET " |
596 | + "parentid=%q, title='%q', uri='%q', desc='%q', toolbar=%d, app=%d " |
597 | + "WHERE id = %" G_GINT64_FORMAT ";", |
598 | + parentid, |
599 | + katze_item_get_name (item), |
600 | + katze_str_non_null (katze_item_get_uri (item)), |
601 | + katze_str_non_null (katze_item_get_meta_string (item, "desc")), |
602 | + katze_item_get_meta_boolean (item, "toolbar"), |
603 | + katze_item_get_meta_boolean (item, "app"), |
604 | katze_item_get_meta_integer (item, "id")); |
605 | |
606 | - if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK) |
607 | - { |
608 | - g_printerr (_("Failed to remove history item: %s\n"), errmsg); |
609 | - sqlite3_free (errmsg); |
610 | - } |
611 | - |
612 | - sqlite3_free (sqlcmd); |
613 | + updated = TRUE; |
614 | + if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK) |
615 | + { |
616 | + updated = FALSE; |
617 | + g_printerr (_("Failed to update bookmark : %s\n"), errmsg); |
618 | + sqlite3_free (errmsg); |
619 | + } |
620 | + |
621 | + sqlite3_free (sqlcmd); |
622 | + g_free (parentid); |
623 | + |
624 | + return updated; |
625 | +} |
626 | + |
627 | +static gboolean |
628 | +midori_bookmarks_remove_item_db (sqlite3* db, |
629 | + KatzeItem* item) |
630 | +{ |
631 | + char* errmsg = NULL; |
632 | + gchar* sqlcmd; |
633 | + gboolean removed = TRUE; |
634 | + |
635 | + sqlcmd = sqlite3_mprintf ( |
636 | + "DELETE FROM bookmarks WHERE id = %" G_GINT64_FORMAT ";", |
637 | + katze_item_get_meta_integer (item, "id")); |
638 | + |
639 | + if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK) |
640 | + { |
641 | + g_printerr (_("Failed to remove bookmark item: %s\n"), errmsg); |
642 | + sqlite3_free (errmsg); |
643 | + removed = FALSE; |
644 | + } |
645 | + |
646 | + sqlite3_free (sqlcmd); |
647 | + return removed; |
648 | } |
649 | |
650 | #define _APPEND_TO_SQL_ERRORMSG(custom_errmsg) \ |
651 | @@ -141,6 +545,7 @@ |
652 | gchar* sql_errmsg = NULL; |
653 | gchar* import_errmsg = NULL; |
654 | KatzeArray* array; |
655 | + MidoriBookmarksDBControl* control; |
656 | |
657 | g_return_val_if_fail (errmsg != NULL, NULL); |
658 | |
659 | @@ -279,12 +684,21 @@ |
660 | init_success: |
661 | g_free (newfile); |
662 | g_free (oldfile); |
663 | + control = MIDORI_BOOKMARKS_DB_CONTROL (g_malloc (sizeof (*control))); |
664 | + control->db = db; |
665 | + control->pending_inserts = NULL; |
666 | + control->pending_updates = g_hash_table_new (item_hash, item_equal); |
667 | + control->pending_deletes = g_hash_table_new (item_hash, item_equal); |
668 | + control->all_items = g_hash_table_new (item_hash, item_equal); |
669 | array = katze_array_new (KATZE_TYPE_ARRAY); |
670 | g_signal_connect (array, "add-item", |
671 | - G_CALLBACK (midori_bookmarks_add_item_cb), db); |
672 | + G_CALLBACK (midori_bookmarks_add_item_cb), control); |
673 | + g_signal_connect (array, "update-item", |
674 | + G_CALLBACK (midori_bookmarks_update_item_cb), control); |
675 | g_signal_connect (array, "remove-item", |
676 | - G_CALLBACK (midori_bookmarks_remove_item_cb), db); |
677 | + G_CALLBACK (midori_bookmarks_remove_item_cb), control); |
678 | g_object_set_data (G_OBJECT (array), "db", db); |
679 | + g_object_set_data (G_OBJECT (array), "control", control); |
680 | return array; |
681 | |
682 | init_failed: |
683 | @@ -298,24 +712,6 @@ |
684 | } |
685 | |
686 | void |
687 | -midori_bookmarks_import (const gchar* filename, |
688 | - sqlite3* db) |
689 | -{ |
690 | - KatzeArray* bookmarks; |
691 | - GError* error = NULL; |
692 | - |
693 | - bookmarks = katze_array_new (KATZE_TYPE_ARRAY); |
694 | - |
695 | - if (!midori_array_from_file (bookmarks, filename, "xbel", &error)) |
696 | - { |
697 | - g_warning (_("The bookmarks couldn't be saved. %s"), error->message); |
698 | - g_error_free (error); |
699 | - return; |
700 | - } |
701 | - midori_bookmarks_import_array_db (db, bookmarks, 0); |
702 | -} |
703 | - |
704 | -void |
705 | midori_bookmarks_on_quit (KatzeArray* array) |
706 | { |
707 | g_return_if_fail (KATZE_IS_ARRAY (array)); |
708 | @@ -323,5 +719,196 @@ |
709 | sqlite3* db = g_object_get_data (G_OBJECT (array), "db"); |
710 | g_return_if_fail (db != NULL); |
711 | sqlite3_close (db); |
712 | -} |
713 | - |
714 | + MidoriBookmarksDBControl* control = g_object_get_data (G_OBJECT (array), "control"); |
715 | + g_return_if_fail (control != NULL); |
716 | + g_idle_remove_by_data (array); |
717 | + g_list_free (control->pending_inserts); |
718 | + g_hash_table_unref (control->pending_updates); |
719 | + g_hash_table_unref (control->pending_deletes); |
720 | + g_hash_table_unref (control->all_items); |
721 | +} |
722 | + |
723 | +/** |
724 | + * midori_bookmarks_import_array: |
725 | + * @array: the main bookmark array |
726 | + * @array: #KatzeArray containing the items to import |
727 | + * @parentid: the id of folder |
728 | + * |
729 | + * Imports the items of @array as childs of the folder |
730 | + * identfied by @parentid. |
731 | + * |
732 | + * Since: 0.5.2 |
733 | + **/ |
734 | +void |
735 | +midori_bookmarks_import_array (KatzeArray* bookmarks, |
736 | + KatzeArray* array, |
737 | + gint64 parentid) |
738 | +{ |
739 | + GList* list; |
740 | + KatzeItem* item; |
741 | + |
742 | + KATZE_ARRAY_FOREACH_ITEM_L (item, array, list) |
743 | + { |
744 | + katze_item_set_meta_integer (item, "parentid", parentid); |
745 | + katze_array_add_item (bookmarks, item); |
746 | + } |
747 | + |
748 | + g_list_free (list); |
749 | +} |
750 | + |
751 | +static void |
752 | +midori_bookmarks_force_idle (KatzeArray* array, |
753 | + MidoriBookmarksDBControl* control) |
754 | +{ |
755 | + if (g_idle_remove_by_data (array)) |
756 | + midori_bookmarks_idle_func (array); |
757 | +} |
758 | + |
759 | +/* static */ void |
760 | +katze_item_set_value_from_column (sqlite3_stmt* stmt, |
761 | + gint column, |
762 | + KatzeItem* item); |
763 | + |
764 | +static KatzeArray* |
765 | +midori_bookmarks_array_from_statement (sqlite3_stmt* stmt, |
766 | + MidoriBookmarksDBControl* control) |
767 | +{ |
768 | + KatzeArray *array; |
769 | + gint result; |
770 | + gint cols; |
771 | + |
772 | + array = katze_array_new (KATZE_TYPE_ITEM); |
773 | + cols = sqlite3_column_count (stmt); |
774 | + |
775 | + while ((result = sqlite3_step (stmt)) == SQLITE_ROW) |
776 | + { |
777 | + gint i; |
778 | + KatzeItem* item; |
779 | + KatzeItem* found; |
780 | + |
781 | + item = katze_item_new (); |
782 | + for (i = 0; i < cols; i++) |
783 | + katze_item_set_value_from_column (stmt, i, item); |
784 | + |
785 | + if (found = g_hash_table_lookup (control->all_items, item)) |
786 | + { |
787 | + for (i = 0; i < cols; i++) |
788 | + katze_item_set_value_from_column (stmt, i, found); |
789 | + |
790 | + g_object_unref (item); |
791 | + |
792 | + item = found; |
793 | + } |
794 | + else if (KATZE_ITEM_IS_FOLDER (item)) |
795 | + { |
796 | + item = KATZE_ITEM (katze_array_new (KATZE_TYPE_ITEM)); |
797 | + |
798 | + for (i = 0; i < cols; i++) |
799 | + katze_item_set_value_from_column (stmt, i, item); |
800 | + |
801 | + g_object_ref (item); |
802 | + g_hash_table_insert (control->all_items, item, item); |
803 | + } |
804 | + else |
805 | + { |
806 | + g_object_ref (item); |
807 | + g_hash_table_insert (control->all_items, item, item); |
808 | + } |
809 | + |
810 | + katze_array_add_item (array, item); |
811 | + } |
812 | + |
813 | + sqlite3_clear_bindings (stmt); |
814 | + sqlite3_reset (stmt); |
815 | + return array; |
816 | +} |
817 | + |
818 | +static KatzeArray* |
819 | +midori_bookmarks_array_from_sqlite (KatzeArray* array, |
820 | + const gchar* sqlcmd) |
821 | +{ |
822 | + MidoriBookmarksDBControl* control; |
823 | + sqlite3_stmt* stmt; |
824 | + gint result; |
825 | + |
826 | + control = g_object_get_data (G_OBJECT (array), "control"); |
827 | + g_return_val_if_fail (control != NULL, NULL); |
828 | + |
829 | + midori_bookmarks_force_idle (array, control); |
830 | + |
831 | + result = sqlite3_prepare_v2 (control->db, sqlcmd, -1, &stmt, NULL); |
832 | + if (result != SQLITE_OK) |
833 | + return NULL; |
834 | + |
835 | + return midori_bookmarks_array_from_statement (stmt, control); |
836 | +} |
837 | + |
838 | +/** |
839 | + * midori_bookmarks_query_recursive: |
840 | + * @array: the main bookmark array |
841 | + * @fields: comma separated list of fields |
842 | + * @condition: condition, like "folder = '%q'" |
843 | + * @value: a value to be inserted if @condition contains %q |
844 | + * @recursive: if %TRUE include children |
845 | + * |
846 | + * Stores the result in a #KatzeArray. |
847 | + * |
848 | + * Return value: a #KatzeArray on success, %NULL otherwise |
849 | + * |
850 | + * Since: 0.5.2 |
851 | + **/ |
852 | +KatzeArray* |
853 | +midori_bookmarks_query_recursive (KatzeArray* bookmarks, |
854 | + const gchar* fields, |
855 | + const gchar* condition, |
856 | + const gchar* value, |
857 | + gboolean recursive) |
858 | +{ |
859 | + gchar* sqlcmd; |
860 | + char* sqlcmd_value; |
861 | + KatzeArray* array; |
862 | + KatzeItem* item; |
863 | + GList* list; |
864 | + |
865 | + g_return_val_if_fail (KATZE_IS_ARRAY (bookmarks), NULL); |
866 | + g_return_val_if_fail (fields, NULL); |
867 | + g_return_val_if_fail (condition, NULL); |
868 | + |
869 | + sqlcmd = g_strdup_printf ("SELECT %s FROM bookmarks WHERE %s " |
870 | + "ORDER BY (uri='') ASC, title DESC", fields, condition); |
871 | + if (strstr (condition, "%q")) |
872 | + { |
873 | + sqlcmd_value = sqlite3_mprintf (sqlcmd, value ? value : ""); |
874 | + array = midori_bookmarks_array_from_sqlite (bookmarks, sqlcmd_value); |
875 | + sqlite3_free (sqlcmd_value); |
876 | + } |
877 | + else |
878 | + array = midori_bookmarks_array_from_sqlite (bookmarks, sqlcmd); |
879 | + g_free (sqlcmd); |
880 | + |
881 | + if (!recursive) |
882 | + return array; |
883 | + |
884 | + KATZE_ARRAY_FOREACH_ITEM_L (item, array, list) |
885 | + { |
886 | + if (KATZE_ITEM_IS_FOLDER (item)) |
887 | + { |
888 | + gchar* parentid = g_strdup_printf ("%" G_GINT64_FORMAT, |
889 | + katze_item_get_meta_integer (item, "id")); |
890 | + KatzeArray* subarray = midori_bookmarks_query_recursive (bookmarks, |
891 | + fields, "parentid=%q", parentid, TRUE); |
892 | + KatzeItem* subitem; |
893 | + GList* sublist; |
894 | + |
895 | + KATZE_ARRAY_FOREACH_ITEM_L (subitem, subarray, sublist) |
896 | + { |
897 | + katze_array_add_item (KATZE_ARRAY (item), subitem); |
898 | + } |
899 | + |
900 | + g_object_unref (subarray); |
901 | + g_free (parentid); |
902 | + } |
903 | + } |
904 | + g_list_free (list); |
905 | + return array; |
906 | +} |
907 | |
908 | === modified file 'midori/midori-bookmarks.h' |
909 | --- midori/midori-bookmarks.h 2012-11-25 15:37:41 +0000 |
910 | +++ midori/midori-bookmarks.h 2013-06-05 17:59:27 +0000 |
911 | @@ -16,16 +16,6 @@ |
912 | #include <sqlite3.h> |
913 | #include <katze/katze.h> |
914 | |
915 | -void |
916 | -midori_bookmarks_add_item_cb (KatzeArray* array, |
917 | - KatzeItem* item, |
918 | - sqlite3* db); |
919 | - |
920 | -void |
921 | -midori_bookmarks_remove_item_cb (KatzeArray* array, |
922 | - KatzeItem* item, |
923 | - sqlite3* db); |
924 | - |
925 | KatzeArray* |
926 | midori_bookmarks_new (char** errmsg); |
927 | |
928 | @@ -33,8 +23,16 @@ |
929 | midori_bookmarks_on_quit (KatzeArray* array); |
930 | |
931 | void |
932 | -midori_bookmarks_import (const gchar* filename, |
933 | - sqlite3* db); |
934 | +midori_bookmarks_import_array (KatzeArray* bookmarks, |
935 | + KatzeArray* array, |
936 | + gint64 parentid); |
937 | + |
938 | +KatzeArray* |
939 | +midori_bookmarks_query_recursive (KatzeArray* bookmarks, |
940 | + const gchar* fields, |
941 | + const gchar* condition, |
942 | + const gchar* value, |
943 | + gboolean recursive); |
944 | |
945 | #endif /* !__MIDORI_BOOKMARKS_H__ */ |
946 | |
947 | |
948 | === modified file 'midori/midori-browser.c' |
949 | --- midori/midori-browser.c 2013-05-31 03:40:27 +0000 |
950 | +++ midori/midori-browser.c 2013-06-05 17:59:27 +0000 |
951 | @@ -96,6 +96,8 @@ |
952 | gboolean show_statusbar; |
953 | guint maximum_history_age; |
954 | guint last_web_search; |
955 | + |
956 | + gboolean bookmarkbar_populate; |
957 | }; |
958 | |
959 | G_DEFINE_TYPE (MidoriBrowser, midori_browser, GTK_TYPE_WINDOW) |
960 | @@ -162,20 +164,13 @@ |
961 | GParamSpec* pspec); |
962 | |
963 | void |
964 | -midori_bookmarks_import_array_db (sqlite3* db, |
965 | - KatzeArray* array, |
966 | - gint64 parentid); |
967 | - |
968 | -gboolean |
969 | -midori_bookmarks_update_item_db (sqlite3* db, |
970 | - KatzeItem* item); |
971 | - |
972 | -void |
973 | midori_browser_open_bookmark (MidoriBrowser* browser, |
974 | KatzeItem* item); |
975 | |
976 | static void |
977 | midori_bookmarkbar_populate (MidoriBrowser* browser); |
978 | +static void |
979 | +midori_bookmarkbar_populate_idle (MidoriBrowser* browser); |
980 | |
981 | static void |
982 | midori_bookmarkbar_clear (GtkWidget* toolbar); |
983 | @@ -484,6 +479,9 @@ |
984 | inter = ZEITGEIST_ZG_DELETE_EVENT; |
985 | else |
986 | g_assert_not_reached (); |
987 | + g_assert (KATZE_IS_ITEM (item)); |
988 | + if (KATZE_ITEM_IS_FOLDER (item)) |
989 | + return; |
990 | zeitgeist_log_insert_events_no_reply (zeitgeist_log_get_default (), |
991 | zeitgeist_event_new_full (inter, ZEITGEIST_ZG_USER_ACTIVITY, |
992 | "application://midori.desktop", |
993 | @@ -1061,16 +1059,11 @@ |
994 | if (new_bookmark) |
995 | katze_array_add_item (browser->bookmarks, bookmark); |
996 | else |
997 | - midori_bookmarks_update_item_db (db, bookmark); |
998 | - midori_browser_update_history (bookmark, "bookmark", new_bookmark ? "create" : "modify"); |
999 | + katze_array_update_item (browser->bookmarks, bookmark); |
1000 | |
1001 | - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check_toolbar))) |
1002 | - if (!gtk_widget_get_visible (browser->bookmarkbar)) |
1003 | - _action_set_active (browser, "Bookmarkbar", TRUE); |
1004 | return_status = TRUE; |
1005 | } |
1006 | - if (gtk_widget_get_visible (browser->bookmarkbar)) |
1007 | - midori_bookmarkbar_populate (browser); |
1008 | + |
1009 | gtk_widget_destroy (dialog); |
1010 | return return_status; |
1011 | } |
1012 | @@ -3096,8 +3089,8 @@ |
1013 | else |
1014 | condition = "parentid = %q"; |
1015 | |
1016 | - bookmarks = midori_array_query (browser->bookmarks, |
1017 | - "id, title, parentid, uri, app, pos_panel, pos_bar", condition, id); |
1018 | + bookmarks = midori_bookmarks_query_recursive (browser->bookmarks, |
1019 | + "id, title, parentid, uri, app, pos_panel, pos_bar", condition, id, FALSE); |
1020 | if (!bookmarks) |
1021 | return FALSE; |
1022 | |
1023 | @@ -4486,7 +4479,7 @@ |
1024 | if (error) |
1025 | g_error_free (error); |
1026 | } |
1027 | - midori_bookmarks_import_array_db (db, bookmarks, selected); |
1028 | + midori_bookmarks_import_array (browser->bookmarks, bookmarks, selected); |
1029 | katze_array_update (browser->bookmarks); |
1030 | g_object_unref (bookmarks); |
1031 | g_free (path); |
1032 | @@ -4541,7 +4534,7 @@ |
1033 | return; |
1034 | |
1035 | error = NULL; |
1036 | - bookmarks = midori_array_query_recursive (browser->bookmarks, |
1037 | + bookmarks = midori_bookmarks_query_recursive (browser->bookmarks, |
1038 | "*", "parentid IS NULL", NULL, TRUE); |
1039 | if (!midori_array_to_file (bookmarks, path, format, &error)) |
1040 | { |
1041 | @@ -5968,6 +5961,21 @@ |
1042 | } |
1043 | } |
1044 | |
1045 | +static gboolean |
1046 | +midori_browser_idle (gpointer data) |
1047 | +{ |
1048 | + MidoriBrowser* browser = MIDORI_BROWSER (data); |
1049 | + |
1050 | + if (browser->bookmarkbar_populate) |
1051 | + { |
1052 | + midori_bookmarkbar_populate_idle (browser); |
1053 | + |
1054 | + browser->bookmarkbar_populate = FALSE; |
1055 | + } |
1056 | + |
1057 | + return FALSE; |
1058 | +} |
1059 | + |
1060 | static void |
1061 | midori_browser_init (MidoriBrowser* browser) |
1062 | { |
1063 | @@ -6448,6 +6456,8 @@ |
1064 | katze_object_assign (browser->history, NULL); |
1065 | katze_object_assign (browser->dial, NULL); |
1066 | |
1067 | + g_idle_remove_by_data (browser); |
1068 | + |
1069 | G_OBJECT_CLASS (midori_browser_parent_class)->finalize (object); |
1070 | } |
1071 | |
1072 | @@ -6962,7 +6972,7 @@ |
1073 | KatzeItem* item) |
1074 | { |
1075 | MidoriBrowser* browser = midori_browser_get_for_widget (toolbar); |
1076 | - GtkAction* action = _action_by_name (browser, "Tools"); |
1077 | + GtkAction* action = _action_by_name (browser, "Bookmarks"); |
1078 | GtkToolItem* toolitem = katze_array_action_create_tool_item_for ( |
1079 | KATZE_ARRAY_ACTION (action), item); |
1080 | g_object_set_data (G_OBJECT (toolitem), "KatzeItem", item); |
1081 | @@ -6983,6 +6993,28 @@ |
1082 | } |
1083 | |
1084 | static void |
1085 | +midori_bookmarkbar_add_item_cb (KatzeArray* bookmarks, |
1086 | + KatzeItem* item, |
1087 | + MidoriBrowser* browser) |
1088 | +{ |
1089 | + if (gtk_widget_get_visible (browser->bookmarkbar)) |
1090 | + midori_bookmarkbar_populate (browser); |
1091 | + else if (katze_item_get_meta_boolean (item, "toolbar")) |
1092 | + _action_set_active (browser, "Bookmarkbar", TRUE); |
1093 | + midori_browser_update_history (item, "bookmark", "created"); |
1094 | +} |
1095 | + |
1096 | +static void |
1097 | +midori_bookmarkbar_update_item_cb (KatzeArray* bookmarks, |
1098 | + KatzeItem* item, |
1099 | + MidoriBrowser* browser) |
1100 | +{ |
1101 | + if (gtk_widget_get_visible (browser->bookmarkbar)) |
1102 | + midori_bookmarkbar_populate (browser); |
1103 | + midori_browser_update_history (item, "bookmark", "modify"); |
1104 | +} |
1105 | + |
1106 | +static void |
1107 | midori_bookmarkbar_remove_item_cb (KatzeArray* bookmarks, |
1108 | KatzeItem* item, |
1109 | MidoriBrowser* browser) |
1110 | @@ -6995,6 +7027,16 @@ |
1111 | static void |
1112 | midori_bookmarkbar_populate (MidoriBrowser* browser) |
1113 | { |
1114 | + if (browser->bookmarkbar_populate) |
1115 | + return; |
1116 | + |
1117 | + g_idle_add (midori_browser_idle, browser); |
1118 | + browser->bookmarkbar_populate = TRUE; |
1119 | +} |
1120 | + |
1121 | +static void |
1122 | +midori_bookmarkbar_populate_idle (MidoriBrowser* browser) |
1123 | +{ |
1124 | KatzeArray* array; |
1125 | KatzeItem* item; |
1126 | |
1127 | @@ -7004,8 +7046,8 @@ |
1128 | gtk_toolbar_insert (GTK_TOOLBAR (browser->bookmarkbar), |
1129 | gtk_separator_tool_item_new (), -1); |
1130 | |
1131 | - array = midori_array_query (browser->bookmarks, |
1132 | - "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "toolbar = 1", NULL); |
1133 | + array = midori_bookmarks_query_recursive (browser->bookmarks, |
1134 | + "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "toolbar = 1", NULL, FALSE); |
1135 | if (!array) |
1136 | { |
1137 | _action_set_sensitive (browser, "BookmarkAdd", FALSE); |
1138 | @@ -7015,21 +7057,7 @@ |
1139 | |
1140 | KATZE_ARRAY_FOREACH_ITEM (item, array) |
1141 | { |
1142 | - if (KATZE_ITEM_IS_BOOKMARK (item)) |
1143 | - midori_bookmarkbar_insert_item (browser->bookmarkbar, item); |
1144 | - else |
1145 | - { |
1146 | - gint64 id = katze_item_get_meta_integer (item, "id"); |
1147 | - gchar* parentid = g_strdup_printf ("%" G_GINT64_FORMAT, id); |
1148 | - KatzeArray* subfolder = midori_array_query (browser->bookmarks, |
1149 | - "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "parentid = %q AND uri != ''", |
1150 | - parentid); |
1151 | - |
1152 | - katze_item_set_name (KATZE_ITEM (subfolder), katze_item_get_name (item)); |
1153 | - katze_item_set_meta_integer (KATZE_ITEM (subfolder), "id", id); |
1154 | - midori_bookmarkbar_insert_item (browser->bookmarkbar, KATZE_ITEM (subfolder)); |
1155 | - g_free (parentid); |
1156 | - } |
1157 | + midori_bookmarkbar_insert_item (browser->bookmarkbar, item); |
1158 | } |
1159 | _action_set_sensitive (browser, "BookmarkAdd", TRUE); |
1160 | _action_set_sensitive (browser, "BookmarkFolderAdd", TRUE); |
1161 | @@ -7064,8 +7092,15 @@ |
1162 | MidoriWebSettings* settings; |
1163 | |
1164 | if (browser->bookmarks != NULL) |
1165 | + { |
1166 | + g_signal_handlers_disconnect_by_func (browser->bookmarks, |
1167 | + midori_bookmarkbar_add_item_cb, browser); |
1168 | + g_signal_handlers_disconnect_by_func (browser->bookmarks, |
1169 | + midori_bookmarkbar_update_item_cb, browser); |
1170 | g_signal_handlers_disconnect_by_func (browser->bookmarks, |
1171 | midori_bookmarkbar_remove_item_cb, browser); |
1172 | + } |
1173 | + |
1174 | settings = midori_browser_get_settings (browser); |
1175 | g_signal_handlers_disconnect_by_func (settings, |
1176 | midori_browser_show_bookmarkbar_notify_value_cb, browser); |
1177 | @@ -7094,6 +7129,10 @@ |
1178 | g_signal_connect (settings, "notify::show-bookmarkbar", |
1179 | G_CALLBACK (midori_browser_show_bookmarkbar_notify_value_cb), browser); |
1180 | g_object_notify (G_OBJECT (settings), "show-bookmarkbar"); |
1181 | + g_signal_connect_after (bookmarks, "add-item", |
1182 | + G_CALLBACK (midori_bookmarkbar_add_item_cb), browser); |
1183 | + g_signal_connect_after (bookmarks, "update-item", |
1184 | + G_CALLBACK (midori_bookmarkbar_update_item_cb), browser); |
1185 | g_signal_connect_after (bookmarks, "remove-item", |
1186 | G_CALLBACK (midori_bookmarkbar_remove_item_cb), browser); |
1187 | } |
1188 | |
1189 | === modified file 'panels/midori-bookmarks.c' |
1190 | --- panels/midori-bookmarks.c 2013-02-11 21:49:41 +0000 |
1191 | +++ panels/midori-bookmarks.c 2013-06-05 17:59:27 +0000 |
1192 | @@ -25,6 +25,111 @@ |
1193 | |
1194 | #define COMPLETION_DELAY 200 |
1195 | |
1196 | +G_BEGIN_DECLS |
1197 | + |
1198 | +#define MIDORI_BOOKMARKS_TREE_STORE_TYPE \ |
1199 | + (midori_bookmarks_tree_store_get_type ()) |
1200 | +#define MIDORI_BOOKMARKS_TREE_STORE(obj) \ |
1201 | + (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_BOOKMARKS_TREE_STORE_TYPE, MidoriBookmarksTreeStore)) |
1202 | +#define MIDORI_BOOKMARKS_TREE_STORE_CLASS(klass) \ |
1203 | + (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_BOOKMARKS_TREE_STORE_TYPE, MidoriBookmarksTreeStoreClass)) |
1204 | + |
1205 | +static gboolean |
1206 | +midori_bookmarks_tree_store_row_drop_possible (GtkTreeDragDest *drag_dest, |
1207 | + GtkTreePath *dest_path, |
1208 | + GtkSelectionData *selection_data); |
1209 | + |
1210 | +typedef struct _MidoriBookmarksTreeStore MidoriBookmarksTreeStore; |
1211 | +typedef struct _MidoriBookmarksTreeStoreClass MidoriBookmarksTreeStoreClass; |
1212 | + |
1213 | +struct _MidoriBookmarksTreeStore |
1214 | +{ |
1215 | + GtkTreeStore parent_instance; |
1216 | +}; |
1217 | + |
1218 | +struct _MidoriBookmarksTreeStoreClass |
1219 | +{ |
1220 | + GtkTreeStoreClass parent_class; |
1221 | +}; |
1222 | + |
1223 | +static GtkTreeDragDestIface * |
1224 | +gtk_tree_store_gtk_tree_drag_dest_iface = NULL; |
1225 | + |
1226 | +static void |
1227 | +midori_bookmarks_tree_store_drag_dest_init (GtkTreeDragDestIface *iface) |
1228 | +{ |
1229 | + gtk_tree_store_gtk_tree_drag_dest_iface = g_type_interface_peek_parent (iface); |
1230 | + |
1231 | + iface->row_drop_possible = midori_bookmarks_tree_store_row_drop_possible; |
1232 | +} |
1233 | + |
1234 | +static void |
1235 | +midori_bookmarks_tree_store_init (MidoriBookmarksTreeStore* item) |
1236 | +{ |
1237 | +} |
1238 | + |
1239 | +static void |
1240 | +midori_bookmarks_tree_store_class_init (MidoriBookmarksTreeStoreClass *class) |
1241 | +{ |
1242 | +} |
1243 | + |
1244 | +G_DEFINE_TYPE_WITH_CODE (MidoriBookmarksTreeStore, |
1245 | + midori_bookmarks_tree_store, |
1246 | + GTK_TYPE_TREE_STORE, |
1247 | + G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_DEST, |
1248 | + midori_bookmarks_tree_store_drag_dest_init)); |
1249 | + |
1250 | + |
1251 | +GtkTreeStore* |
1252 | +midori_bookmarks_tree_store_new (gint n_columns, ...) |
1253 | +{ |
1254 | + GtkTreeStore* tree_store = GTK_TREE_STORE (g_object_new (MIDORI_BOOKMARKS_TREE_STORE_TYPE, NULL)); |
1255 | + va_list ap; |
1256 | + GType* types; |
1257 | + gint n; |
1258 | + |
1259 | + if (!tree_store) |
1260 | + return NULL; |
1261 | + |
1262 | + types = g_new (GType, n_columns); |
1263 | + |
1264 | + if (!types) |
1265 | + { |
1266 | + g_object_unref(tree_store); |
1267 | + return NULL; |
1268 | + } |
1269 | + |
1270 | + va_start(ap, n_columns); |
1271 | + for (n = 0; n < n_columns; n++) |
1272 | + { |
1273 | + types[n] = va_arg(ap, GType); |
1274 | + } |
1275 | + va_end(ap); |
1276 | + |
1277 | + gtk_tree_store_set_column_types (tree_store, |
1278 | + n_columns, |
1279 | + types); |
1280 | + |
1281 | + g_free (types); |
1282 | + return tree_store; |
1283 | +} |
1284 | + |
1285 | + |
1286 | +GtkTreeStore* |
1287 | +midori_bookmarks_tree_store_newv (gint n_columns, GType *types) |
1288 | +{ |
1289 | + GtkTreeStore* tree_store = GTK_TREE_STORE (g_object_new (MIDORI_BOOKMARKS_TREE_STORE_TYPE, NULL)); |
1290 | + |
1291 | + if (!tree_store) |
1292 | + return NULL; |
1293 | + |
1294 | + gtk_tree_store_set_column_types (tree_store, |
1295 | + n_columns, |
1296 | + types); |
1297 | + |
1298 | + return tree_store; |
1299 | +} |
1300 | + |
1301 | gboolean |
1302 | midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser, |
1303 | KatzeItem* bookmark, |
1304 | @@ -36,6 +141,12 @@ |
1305 | midori_browser_open_bookmark (MidoriBrowser* browser, |
1306 | KatzeItem* item); |
1307 | |
1308 | +static void |
1309 | +midori_bookmarks_row_changed_cb (GtkTreeModel* model, |
1310 | + GtkTreePath* path, |
1311 | + GtkTreeIter* iter, |
1312 | + MidoriBookmarks* bookmarks); |
1313 | + |
1314 | struct _MidoriBookmarks |
1315 | { |
1316 | GtkVBox parent_instance; |
1317 | @@ -49,6 +160,8 @@ |
1318 | |
1319 | gint filter_timeout; |
1320 | gchar* filter; |
1321 | + |
1322 | + GList* pending_inserts; |
1323 | }; |
1324 | |
1325 | struct _MidoriBookmarksClass |
1326 | @@ -86,6 +199,13 @@ |
1327 | GParamSpec* pspec); |
1328 | |
1329 | static void |
1330 | +midori_bookmarks_add_item_cb (KatzeArray* array, |
1331 | + KatzeItem* item, |
1332 | + MidoriBookmarks* bookmarks); |
1333 | +static void |
1334 | +midori_bookmarks_update_cb (KatzeArray* array, |
1335 | + MidoriBookmarks* bookmarks); |
1336 | +static void |
1337 | midori_bookmarks_class_init (MidoriBookmarksClass* class) |
1338 | { |
1339 | GObjectClass* gobject_class; |
1340 | @@ -120,6 +240,7 @@ |
1341 | return STOCK_BOOKMARKS; |
1342 | } |
1343 | |
1344 | +#if 0 |
1345 | /* TODO: Function never used */ |
1346 | void |
1347 | midori_bookmarks_export_array_db (sqlite3* db, |
1348 | @@ -133,7 +254,7 @@ |
1349 | gchar* parent_id; |
1350 | |
1351 | parent_id = g_strdup_printf ("%" G_GINT64_FORMAT, parentid); |
1352 | - if (!(root_array = midori_array_query (array, "*", "parentid = %q", parent_id))) |
1353 | + if (!(root_array = midori_bookmarks_query_recursive (array, "*", "parentid = %q", parent_id, FALSE))) |
1354 | { |
1355 | g_free (parent_id); |
1356 | return; |
1357 | @@ -155,27 +276,7 @@ |
1358 | g_free (parent_id); |
1359 | g_list_free (list); |
1360 | } |
1361 | - |
1362 | -void |
1363 | -midori_bookmarks_import_array_db (sqlite3* db, |
1364 | - KatzeArray* array, |
1365 | - gint64 parentid) |
1366 | -{ |
1367 | - GList* list; |
1368 | - KatzeItem* item; |
1369 | - gint64 id; |
1370 | - |
1371 | - if (!db) |
1372 | - return; |
1373 | - |
1374 | - KATZE_ARRAY_FOREACH_ITEM_L (item, array, list) |
1375 | - { |
1376 | - id = midori_bookmarks_insert_item_db (db, item, parentid); |
1377 | - if (KATZE_IS_ARRAY (item)) |
1378 | - midori_bookmarks_import_array_db (db, KATZE_ARRAY (item), id); |
1379 | - } |
1380 | - g_list_free (list); |
1381 | -} |
1382 | +#endif |
1383 | |
1384 | static KatzeArray* |
1385 | midori_bookmarks_read_from_db (MidoriBookmarks* bookmarks, |
1386 | @@ -185,21 +286,21 @@ |
1387 | KatzeArray* array; |
1388 | |
1389 | if (keyword && *keyword) |
1390 | - array = midori_array_query (bookmarks->array, |
1391 | - "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "title LIKE '%%%q%%'", keyword); |
1392 | + array = midori_bookmarks_query_recursive (bookmarks->array, |
1393 | + "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "title LIKE '%%%q%%'", keyword, FALSE); |
1394 | else |
1395 | { |
1396 | if (parentid > 0) |
1397 | { |
1398 | gchar* parent_id = g_strdup_printf ("%" G_GINT64_FORMAT, parentid); |
1399 | - array = midori_array_query (bookmarks->array, |
1400 | - "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "parentid = %q", parent_id); |
1401 | + array = midori_bookmarks_query_recursive (bookmarks->array, |
1402 | + "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "parentid = %q", parent_id, FALSE); |
1403 | |
1404 | g_free (parent_id); |
1405 | } |
1406 | else |
1407 | - array = midori_array_query (bookmarks->array, |
1408 | - "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "parentid IS NULL", NULL); |
1409 | + array = midori_bookmarks_query_recursive (bookmarks->array, |
1410 | + "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "parentid IS NULL", NULL, FALSE); |
1411 | } |
1412 | return array ? array : katze_array_new (KATZE_TYPE_ITEM); |
1413 | } |
1414 | @@ -230,90 +331,133 @@ |
1415 | g_object_unref (item); |
1416 | } |
1417 | |
1418 | -gint64 |
1419 | -midori_bookmarks_insert_item_db (sqlite3* db, |
1420 | - KatzeItem* item, |
1421 | - gint64 parentid) |
1422 | +static gboolean |
1423 | +midori_bookmarks_reach_item_recurse (GtkTreeModel* model, |
1424 | + GtkTreeIter* iter, |
1425 | + gint64 id) |
1426 | { |
1427 | - gchar* sqlcmd; |
1428 | - char* errmsg = NULL; |
1429 | - KatzeItem* old_parent; |
1430 | - gchar* new_parentid; |
1431 | - gchar* id = NULL; |
1432 | - const gchar* uri = NULL; |
1433 | - const gchar* desc = NULL; |
1434 | - gint64 seq = 0; |
1435 | - |
1436 | - /* Bookmarks must have a name, import may produce invalid items */ |
1437 | - g_return_val_if_fail (katze_item_get_name (item), seq); |
1438 | - |
1439 | - if (!db) |
1440 | - return seq; |
1441 | - |
1442 | - if (katze_item_get_meta_integer (item, "id") > 0) |
1443 | - id = g_strdup_printf ("%" G_GINT64_FORMAT, katze_item_get_meta_integer(item, "id")); |
1444 | - else |
1445 | - id = g_strdup_printf ("NULL"); |
1446 | - |
1447 | - if (KATZE_ITEM_IS_BOOKMARK (item)) |
1448 | - uri = katze_item_get_uri (item); |
1449 | - |
1450 | - if (katze_item_get_text (item)) |
1451 | - desc = katze_item_get_text (item); |
1452 | - |
1453 | - /* Use folder, otherwise fallback to parent folder */ |
1454 | - old_parent = katze_item_get_parent (item); |
1455 | - if (parentid > 0) |
1456 | - new_parentid = g_strdup_printf ("%" G_GINT64_FORMAT, parentid); |
1457 | - else if (old_parent && katze_item_get_meta_integer (old_parent, "id") > 0) |
1458 | - new_parentid = g_strdup_printf ("%" G_GINT64_FORMAT, katze_item_get_meta_integer (old_parent, "id")); |
1459 | - else |
1460 | - new_parentid = g_strdup_printf ("NULL"); |
1461 | - |
1462 | - sqlcmd = sqlite3_mprintf ( |
1463 | - "INSERT INTO bookmarks (id, parentid, title, uri, desc, toolbar, app) " |
1464 | - "VALUES (%q, %q, '%q', '%q', '%q', %d, %d)", |
1465 | - id, |
1466 | - new_parentid, |
1467 | - katze_item_get_name (item), |
1468 | - katze_str_non_null (uri), |
1469 | - katze_str_non_null (desc), |
1470 | - katze_item_get_meta_boolean (item, "toolbar"), |
1471 | - katze_item_get_meta_boolean (item, "app")); |
1472 | - |
1473 | - if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) == SQLITE_OK) |
1474 | + do |
1475 | { |
1476 | - /* Get insert id */ |
1477 | - if (g_str_equal (id, "NULL")) |
1478 | - { |
1479 | - KatzeArray* seq_array; |
1480 | - |
1481 | - sqlite3_free (sqlcmd); |
1482 | - sqlcmd = sqlite3_mprintf ( |
1483 | - "SELECT seq FROM sqlite_sequence WHERE name = 'bookmarks'"); |
1484 | - |
1485 | - seq_array = katze_array_from_sqlite (db, sqlcmd); |
1486 | - if (katze_array_get_nth_item (seq_array, 0)) |
1487 | + GtkTreeIter child; |
1488 | + KatzeItem *item; |
1489 | + gint64 itemid = -1; |
1490 | + |
1491 | + gtk_tree_model_get (model, iter, 0, &item, -1); |
1492 | + |
1493 | + if (!KATZE_ITEM_IS_SEPARATOR(item)) |
1494 | + { |
1495 | + itemid = katze_item_get_meta_integer (item, "id"); |
1496 | + g_object_unref (item); |
1497 | + } |
1498 | + |
1499 | + if (id == itemid) |
1500 | + return TRUE; |
1501 | + |
1502 | + if (gtk_tree_model_iter_children (model, &child, iter)) |
1503 | + { |
1504 | + if (midori_bookmarks_reach_item_recurse (model, &child, id)) |
1505 | { |
1506 | - KatzeItem* seq_item = katze_array_get_nth_item (seq_array, 0); |
1507 | - |
1508 | - seq = katze_item_get_meta_integer (seq_item, "seq"); |
1509 | - katze_item_set_meta_integer (item, "id", seq); |
1510 | + *iter = child; |
1511 | + return TRUE; |
1512 | } |
1513 | - g_object_unref (seq_array); |
1514 | } |
1515 | } |
1516 | - else |
1517 | - { |
1518 | - g_printerr (_("Failed to add bookmark item: %s\n"), errmsg); |
1519 | - sqlite3_free (errmsg); |
1520 | - } |
1521 | - |
1522 | - sqlite3_free (sqlcmd); |
1523 | - g_free (new_parentid); |
1524 | - g_free (id); |
1525 | - |
1526 | - return seq; |
1527 | + while (gtk_tree_model_iter_next(model, iter)); |
1528 | + |
1529 | + return FALSE; |
1530 | +} |
1531 | + |
1532 | +static gboolean |
1533 | +midori_bookmarks_reach_item (GtkTreeModel* model, |
1534 | + GtkTreeIter* iter, |
1535 | + gint64 id) |
1536 | +{ |
1537 | + if (!gtk_tree_model_get_iter_first(model, iter)) |
1538 | + return FALSE; |
1539 | + |
1540 | + return midori_bookmarks_reach_item_recurse (model, iter, id); |
1541 | +} |
1542 | + |
1543 | +static void |
1544 | +midori_bookmarks_add_item_to_model(GtkTreeStore* model, |
1545 | + GtkTreeIter* parent, |
1546 | + KatzeItem* item) |
1547 | +{ |
1548 | + if (KATZE_ITEM_IS_BOOKMARK (item)) |
1549 | + { |
1550 | + gchar* tooltip = g_markup_escape_text (katze_item_get_uri (item), -1); |
1551 | + |
1552 | + gtk_tree_store_insert_with_values (model, NULL, parent, |
1553 | + 0, |
1554 | + 0, item, 1, tooltip, -1); |
1555 | + g_free (tooltip); |
1556 | + } |
1557 | + else |
1558 | + { |
1559 | + GtkTreeIter root_iter; |
1560 | + |
1561 | + gtk_tree_store_insert_with_values (model, &root_iter, parent, |
1562 | + 0, 0, item, -1); |
1563 | + |
1564 | + /* That's an invisible dummy, so we always have an expander */ |
1565 | + gtk_tree_store_insert_with_values (model, NULL, &root_iter, |
1566 | + 0, |
1567 | + 0, NULL, -1); |
1568 | + } |
1569 | +} |
1570 | + |
1571 | +static void |
1572 | +midori_bookmarks_update_item_in_model(MidoriBookmarks* bookmarks, |
1573 | + GtkTreeStore* model, |
1574 | + GtkTreeIter* iter, |
1575 | + KatzeItem* item) |
1576 | +{ |
1577 | + g_signal_handlers_block_by_func (model, |
1578 | + midori_bookmarks_row_changed_cb, |
1579 | + bookmarks); |
1580 | + |
1581 | + if (KATZE_ITEM_IS_BOOKMARK (item)) |
1582 | + { |
1583 | + gchar* tooltip = g_markup_escape_text (katze_item_get_uri (item), -1); |
1584 | + |
1585 | + gtk_tree_store_set(model, iter, |
1586 | + 0, item, 1, tooltip, -1); |
1587 | + |
1588 | + g_free (tooltip); |
1589 | + } |
1590 | + else |
1591 | + { |
1592 | + gtk_tree_store_set(model, iter, |
1593 | + 0, item, -1); |
1594 | + } |
1595 | + |
1596 | + g_signal_handlers_unblock_by_func (model, |
1597 | + midori_bookmarks_row_changed_cb, |
1598 | + bookmarks); |
1599 | +} |
1600 | + |
1601 | +static void |
1602 | +midori_bookmarks_add_item (KatzeItem* item, |
1603 | + MidoriBookmarks* bookmarks); |
1604 | + |
1605 | +static gboolean |
1606 | +midori_bookmarks_idle (MidoriBookmarks* bookmarks) |
1607 | +{ |
1608 | + GList* list_iter; |
1609 | + |
1610 | + for (list_iter = bookmarks->pending_inserts; list_iter; list_iter = g_list_next (list_iter)) |
1611 | + { |
1612 | + KatzeItem *item = KATZE_ITEM (list_iter->data); |
1613 | + |
1614 | + midori_bookmarks_add_item (item, bookmarks); |
1615 | + |
1616 | + g_object_unref (item); |
1617 | + } |
1618 | + |
1619 | + g_list_free (bookmarks->pending_inserts); |
1620 | + bookmarks->pending_inserts = NULL; |
1621 | + |
1622 | + return FALSE; |
1623 | } |
1624 | |
1625 | static void |
1626 | @@ -321,11 +465,98 @@ |
1627 | KatzeItem* item, |
1628 | MidoriBookmarks* bookmarks) |
1629 | { |
1630 | - GtkTreeModel* model; |
1631 | - model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview)); |
1632 | - gtk_tree_store_clear (GTK_TREE_STORE (model)); |
1633 | - midori_bookmarks_read_from_db_to_model (bookmarks, |
1634 | - GTK_TREE_STORE (model), NULL, 0, bookmarks->filter); |
1635 | + if (!bookmarks->pending_inserts) |
1636 | + g_idle_add ((GSourceFunc)midori_bookmarks_idle, bookmarks); |
1637 | + |
1638 | + g_object_ref (item); |
1639 | + bookmarks->pending_inserts = g_list_append (bookmarks->pending_inserts, item); |
1640 | +} |
1641 | + |
1642 | +static void |
1643 | +midori_bookmarks_add_item (KatzeItem* item, |
1644 | + MidoriBookmarks* bookmarks) |
1645 | +{ |
1646 | + gint64 id = katze_item_get_meta_integer (item, "id"); |
1647 | + gint64 parentid = katze_item_get_meta_integer (item, "parentid"); |
1648 | + GtkTreeModel* model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview)); |
1649 | + GtkTreeIter iter; |
1650 | + |
1651 | + if (!parentid) |
1652 | + { |
1653 | + midori_bookmarks_add_item_to_model (GTK_TREE_STORE (model), NULL, item); |
1654 | + } |
1655 | + else if (midori_bookmarks_reach_item (model, &iter, parentid)) |
1656 | + { |
1657 | + GtkTreePath* path = gtk_tree_model_get_path(model, &iter); |
1658 | + |
1659 | + if (gtk_tree_view_row_expanded (GTK_TREE_VIEW (bookmarks->treeview), path)) |
1660 | + { |
1661 | + midori_bookmarks_add_item_to_model (GTK_TREE_STORE (model), &iter, item); |
1662 | + } |
1663 | + |
1664 | + gtk_tree_path_free (path); |
1665 | + } |
1666 | +} |
1667 | + |
1668 | +static void |
1669 | +midori_bookmarks_update_item_cb (KatzeArray* array, |
1670 | + KatzeItem* item, |
1671 | + MidoriBookmarks* bookmarks) |
1672 | +{ |
1673 | + gint64 id = katze_item_get_meta_integer (item, "id"); |
1674 | + gint64 parentid = katze_item_get_meta_integer (item, "parentid"); |
1675 | + GtkTreeModel* model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview)); |
1676 | + GtkTreeIter iter; |
1677 | + |
1678 | + if (midori_bookmarks_reach_item (model, &iter, id)) |
1679 | + { |
1680 | + gint64 old_parentid = 0; |
1681 | + GtkTreeIter parent; |
1682 | + |
1683 | + if (gtk_tree_model_iter_parent (model, &parent, &iter)) |
1684 | + { |
1685 | + KatzeItem* old_parent; |
1686 | + |
1687 | + gtk_tree_model_get (model, &parent, 0, &old_parent, -1); |
1688 | + |
1689 | + old_parentid = katze_item_get_meta_integer (old_parent, "id"); |
1690 | + |
1691 | + g_object_unref (old_parent); |
1692 | + |
1693 | + if (parentid == old_parentid) |
1694 | + { |
1695 | + midori_bookmarks_update_item_in_model (bookmarks, GTK_TREE_STORE (model), &iter, item); |
1696 | + } |
1697 | + else |
1698 | + { |
1699 | + gtk_tree_store_remove (GTK_TREE_STORE (model), &iter); |
1700 | + |
1701 | + if (!gtk_tree_model_iter_has_child (model, &parent)) |
1702 | + { |
1703 | + GtkTreePath* path = gtk_tree_model_get_path(model, &parent); |
1704 | + |
1705 | + if (gtk_tree_view_row_expanded (GTK_TREE_VIEW (bookmarks->treeview), path)) |
1706 | + gtk_tree_view_collapse_row (GTK_TREE_VIEW (bookmarks->treeview), path); |
1707 | + |
1708 | + gtk_tree_path_free (path); |
1709 | + } |
1710 | + |
1711 | + midori_bookmarks_add_item (item, bookmarks); |
1712 | + } |
1713 | + } |
1714 | + else if (parentid == 0) |
1715 | + { |
1716 | + midori_bookmarks_update_item_in_model (bookmarks, GTK_TREE_STORE (model), &iter, item); |
1717 | + } |
1718 | + else |
1719 | + { |
1720 | + gtk_tree_store_remove (GTK_TREE_STORE (model), &iter); |
1721 | + |
1722 | + midori_bookmarks_add_item (item, bookmarks); |
1723 | + } |
1724 | + } |
1725 | + else |
1726 | + midori_bookmarks_add_item (item, bookmarks); |
1727 | } |
1728 | |
1729 | static void |
1730 | @@ -333,12 +564,36 @@ |
1731 | KatzeItem* item, |
1732 | MidoriBookmarks* bookmarks) |
1733 | { |
1734 | + gint64 id = katze_item_get_meta_integer (item, "id"); |
1735 | GtkTreeModel* model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview)); |
1736 | - gtk_tree_store_clear (GTK_TREE_STORE (model)); |
1737 | - midori_bookmarks_read_from_db_to_model (bookmarks, |
1738 | - GTK_TREE_STORE (model), NULL, 0, bookmarks->filter); |
1739 | + GtkTreeIter iter; |
1740 | + |
1741 | + if (midori_bookmarks_reach_item (model, &iter, id)) |
1742 | + { |
1743 | + GtkTreeIter parent; |
1744 | + |
1745 | + if (gtk_tree_model_iter_parent (model, &parent, &iter)) |
1746 | + { |
1747 | + gtk_tree_store_remove (GTK_TREE_STORE (model), &iter); |
1748 | + |
1749 | + if (!gtk_tree_model_iter_has_child (model, &parent)) |
1750 | + { |
1751 | + GtkTreePath* path = gtk_tree_model_get_path(model, &parent); |
1752 | + |
1753 | + if (gtk_tree_view_row_expanded (GTK_TREE_VIEW (bookmarks->treeview), path)) |
1754 | + gtk_tree_view_collapse_row (GTK_TREE_VIEW (bookmarks->treeview), path); |
1755 | + |
1756 | + gtk_tree_path_free (path); |
1757 | + } |
1758 | + } |
1759 | + else |
1760 | + { |
1761 | + gtk_tree_store_remove (GTK_TREE_STORE (model), &iter); |
1762 | + } |
1763 | + } |
1764 | } |
1765 | |
1766 | + |
1767 | static void |
1768 | midori_bookmarks_update_cb (KatzeArray* array, |
1769 | MidoriBookmarks* bookmarks) |
1770 | @@ -350,6 +605,42 @@ |
1771 | } |
1772 | |
1773 | |
1774 | +static gboolean |
1775 | +midori_bookmarks_tree_store_row_drop_possible (GtkTreeDragDest* drag_dest, |
1776 | + GtkTreePath* dest_path, |
1777 | + GtkSelectionData* selection_data) |
1778 | +{ |
1779 | + gboolean row_drop_possible = |
1780 | + gtk_tree_store_gtk_tree_drag_dest_iface->row_drop_possible (drag_dest, |
1781 | + dest_path, |
1782 | + selection_data); |
1783 | + |
1784 | + if (!row_drop_possible) |
1785 | + return FALSE; |
1786 | + |
1787 | + if ((!gtk_tree_path_get_depth(dest_path) > 1) |
1788 | + && gtk_tree_path_up(dest_path)) |
1789 | + { |
1790 | + GtkTreeModel* model = GTK_TREE_MODEL(drag_dest); |
1791 | + GtkTreeIter iter; |
1792 | + |
1793 | + if (gtk_tree_model_get_iter (model, &iter, dest_path)) |
1794 | + { |
1795 | + KatzeItem* item; |
1796 | + |
1797 | + gtk_tree_model_get (model, &iter, 0, &item, -1); |
1798 | + |
1799 | + if (!KATZE_ITEM_IS_FOLDER(item)) |
1800 | + row_drop_possible = FALSE; |
1801 | + |
1802 | + if (item) |
1803 | + g_object_unref (item); |
1804 | + } |
1805 | + } |
1806 | + |
1807 | + return row_drop_possible; |
1808 | +} |
1809 | + |
1810 | static void |
1811 | midori_bookmarks_row_changed_cb (GtkTreeModel* model, |
1812 | GtkTreePath* path, |
1813 | @@ -358,31 +649,37 @@ |
1814 | { |
1815 | KatzeItem* item; |
1816 | GtkTreeIter parent; |
1817 | - KatzeItem* new_parent = NULL; |
1818 | - gint64 parentid; |
1819 | - |
1820 | - gtk_tree_model_get (model, iter, 0, &item, -1); |
1821 | + gint64 parentid = 0; |
1822 | |
1823 | if (gtk_tree_model_iter_parent (model, &parent, iter)) |
1824 | { |
1825 | + KatzeItem* new_parent; |
1826 | + |
1827 | gtk_tree_model_get (model, &parent, 0, &new_parent, -1); |
1828 | |
1829 | - /* Bookmarks must not be moved into non-folder items */ |
1830 | - if (!KATZE_ITEM_IS_FOLDER (new_parent)) |
1831 | - parentid = 0; |
1832 | - else |
1833 | - parentid = katze_item_get_meta_integer (new_parent, "id"); |
1834 | + /* Bookmarks cannot be moved into non-folder items */ |
1835 | + g_assert (KATZE_ITEM_IS_FOLDER (new_parent)); |
1836 | + |
1837 | + parentid = katze_item_get_meta_integer (new_parent, "id"); |
1838 | + |
1839 | + g_object_unref (new_parent); |
1840 | } |
1841 | - else |
1842 | - parentid = 0; |
1843 | - |
1844 | - katze_array_remove_item (bookmarks->array, item); |
1845 | + |
1846 | + gtk_tree_model_get (model, iter, 0, &item, -1); |
1847 | + |
1848 | katze_item_set_meta_integer (item, "parentid", parentid); |
1849 | - katze_array_add_item (bookmarks->array, item); |
1850 | + |
1851 | + g_signal_handlers_block_by_func (bookmarks->array, |
1852 | + midori_bookmarks_update_item_cb, |
1853 | + bookmarks); |
1854 | + |
1855 | + katze_array_update_item (bookmarks->array, item); |
1856 | + |
1857 | + g_signal_handlers_unblock_by_func (bookmarks->array, |
1858 | + midori_bookmarks_update_item_cb, |
1859 | + bookmarks); |
1860 | |
1861 | g_object_unref (item); |
1862 | - if (new_parent) |
1863 | - g_object_unref (new_parent); |
1864 | } |
1865 | |
1866 | static void |
1867 | @@ -408,24 +705,15 @@ |
1868 | { |
1869 | KatzeItem* item; |
1870 | MidoriBrowser* browser; |
1871 | - gint64 parentid; |
1872 | |
1873 | gtk_tree_model_get (model, &iter, 0, &item, -1); |
1874 | |
1875 | g_assert (!KATZE_ITEM_IS_SEPARATOR (item)); |
1876 | |
1877 | browser = midori_browser_get_for_widget (bookmarks->treeview); |
1878 | - parentid = katze_item_get_meta_integer (item, "parentid"); |
1879 | midori_browser_edit_bookmark_dialog_new ( |
1880 | browser, item, FALSE, KATZE_ITEM_IS_FOLDER (item), NULL); |
1881 | |
1882 | - if (katze_item_get_meta_integer (item, "parentid") != parentid) |
1883 | - { |
1884 | - gtk_tree_store_clear (GTK_TREE_STORE (model)); |
1885 | - midori_bookmarks_read_from_db_to_model (bookmarks, GTK_TREE_STORE (model), |
1886 | - NULL, 0, NULL); |
1887 | - } |
1888 | - |
1889 | g_object_unref (item); |
1890 | } |
1891 | } |
1892 | @@ -441,47 +729,6 @@ |
1893 | gtk_widget_set_sensitive (GTK_WIDGET (bookmarks->edit), selected); |
1894 | } |
1895 | |
1896 | -gboolean |
1897 | -midori_bookmarks_update_item_db (sqlite3* db, |
1898 | - KatzeItem* item) |
1899 | -{ |
1900 | - gchar* sqlcmd; |
1901 | - char* errmsg = NULL; |
1902 | - gchar* parentid; |
1903 | - gboolean updated; |
1904 | - |
1905 | - if (katze_item_get_meta_integer (item, "parentid") > 0) |
1906 | - parentid = g_strdup_printf ("%" G_GINT64_FORMAT, |
1907 | - katze_item_get_meta_integer (item, "parentid")); |
1908 | - else |
1909 | - parentid = g_strdup_printf ("NULL"); |
1910 | - |
1911 | - sqlcmd = sqlite3_mprintf ( |
1912 | - "UPDATE bookmarks SET " |
1913 | - "parentid=%q, title='%q', uri='%q', desc='%q', toolbar=%d, app=%d " |
1914 | - "WHERE id = %" G_GINT64_FORMAT ";", |
1915 | - parentid, |
1916 | - katze_item_get_name (item), |
1917 | - katze_str_non_null (katze_item_get_uri (item)), |
1918 | - katze_str_non_null (katze_item_get_meta_string (item, "desc")), |
1919 | - katze_item_get_meta_boolean (item, "toolbar"), |
1920 | - katze_item_get_meta_boolean (item, "app"), |
1921 | - katze_item_get_meta_integer (item, "id")); |
1922 | - |
1923 | - updated = TRUE; |
1924 | - if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK) |
1925 | - { |
1926 | - updated = FALSE; |
1927 | - g_printerr (_("Failed to update bookmark : %s\n"), errmsg); |
1928 | - sqlite3_free (errmsg); |
1929 | - } |
1930 | - |
1931 | - sqlite3_free (sqlcmd); |
1932 | - g_free (parentid); |
1933 | - |
1934 | - return updated; |
1935 | -} |
1936 | - |
1937 | static void |
1938 | midori_bookmarks_delete_clicked_cb (GtkWidget* toolitem, |
1939 | MidoriBookmarks* bookmarks) |
1940 | @@ -496,13 +743,8 @@ |
1941 | |
1942 | gtk_tree_model_get (model, &iter, 0, &item, -1); |
1943 | |
1944 | - /* Manually remove the iter and block clearing the treeview */ |
1945 | - gtk_tree_store_remove (GTK_TREE_STORE (model), &iter); |
1946 | - g_signal_handlers_block_by_func (bookmarks->array, |
1947 | - midori_bookmarks_remove_item_cb, bookmarks); |
1948 | katze_array_remove_item (bookmarks->array, item); |
1949 | - g_signal_handlers_unblock_by_func (bookmarks->array, |
1950 | - midori_bookmarks_remove_item_cb, bookmarks); |
1951 | + |
1952 | g_object_unref (item); |
1953 | } |
1954 | } |
1955 | @@ -599,6 +841,8 @@ |
1956 | midori_bookmarks_read_from_db_to_model (bookmarks, GTK_TREE_STORE (model), NULL, 0, NULL); |
1957 | g_signal_connect_after (bookmarks->array, "add-item", |
1958 | G_CALLBACK (midori_bookmarks_add_item_cb), bookmarks); |
1959 | + g_signal_connect_after (bookmarks->array, "update-item", |
1960 | + G_CALLBACK (midori_bookmarks_update_item_cb), bookmarks); |
1961 | g_signal_connect (bookmarks->array, "remove-item", |
1962 | G_CALLBACK (midori_bookmarks_remove_item_cb), bookmarks); |
1963 | g_signal_connect (bookmarks->array, "update", |
1964 | @@ -1015,7 +1259,7 @@ |
1965 | gtk_box_pack_start (GTK_BOX (bookmarks), box, FALSE, FALSE, 5); |
1966 | |
1967 | /* Create the treeview */ |
1968 | - model = gtk_tree_store_new (2, KATZE_TYPE_ITEM, G_TYPE_STRING); |
1969 | + model = midori_bookmarks_tree_store_new (2, KATZE_TYPE_ITEM, G_TYPE_STRING); |
1970 | treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model)); |
1971 | gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE); |
1972 | gtk_tree_view_set_tooltip_column (GTK_TREE_VIEW (treeview), 1); |
1973 | @@ -1055,6 +1299,7 @@ |
1974 | gtk_widget_show (treeview); |
1975 | gtk_box_pack_start (GTK_BOX (bookmarks), treeview, TRUE, TRUE, 0); |
1976 | bookmarks->treeview = treeview; |
1977 | + bookmarks->pending_inserts = NULL; |
1978 | } |
1979 | |
1980 | static void |
1981 | |
1982 | === modified file 'panels/midori-bookmarks.h' |
1983 | --- panels/midori-bookmarks.h 2012-11-25 11:26:03 +0000 |
1984 | +++ panels/midori-bookmarks.h 2013-06-05 17:59:27 +0000 |
1985 | @@ -37,20 +37,6 @@ |
1986 | GType |
1987 | midori_bookmarks_get_type (void); |
1988 | |
1989 | -gint64 |
1990 | -midori_bookmarks_insert_item_db (sqlite3* db, |
1991 | - KatzeItem* item, |
1992 | - gint64 parentid); |
1993 | - |
1994 | -void |
1995 | -midori_bookmarks_import_array_db (sqlite3* db, |
1996 | - KatzeArray* array, |
1997 | - gint64 parentid); |
1998 | - |
1999 | -gboolean |
2000 | -midori_bookmarks_update_item_db (sqlite3* db, |
2001 | - KatzeItem* item); |
2002 | - |
2003 | G_END_DECLS |
2004 | |
2005 | #endif /* __MIDORI_BOOKMARKS_PANEL_H__ */ |
- if (item->parent) )item-> parent) ; update_ item ((KatzeArray* )item-> parent, item);
- katze_array_update ((KatzeArray*
+ if (item->parent && g_strcmp0(icon, picon))
+ katze_array_
katze_array_ update_ item replaces katze_array_update if I see correctly, so that should be mentioned by marking the old one as Deprecated for clarity.
The checks like g_strcmp0(icon, picon) seem to avoid updating if nothing changed - in that case, why not do this for all values in each function?