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: |
3290 lines (+1933/-637) 12 files modified
katze/katze-array.c (+37/-30) katze/katze-array.h (+37/-0) katze/katze-item.c (+8/-2) midori/midori-array.c (+17/-248) midori/midori-array.h (+5/-20) midori/midori-bookmarks-db.c (+1213/-69) midori/midori-bookmarks-db.h (+60/-21) midori/midori-browser.c (+87/-48) midori/midori-frontend.c (+5/-5) midori/midori.h (+1/-1) panels/midori-bookmarks.c (+463/-179) 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 |
---|---|---|---|
Midori Devs | Pending | ||
André Auzi | Pending | ||
Review via email:
|
This proposal supersedes a proposal from 2013-05-21.
Commit message
Description of the change
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Cris Dywan (kalikiana) wrote : Posted in a previous version of this proposal | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Cris Dywan (kalikiana) wrote : Posted in a previous version of this proposal | # |
A side note on the comment "panels/
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
André Auzi (aauzi) wrote : Posted in a previous version of this proposal | # |
> - 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 : Posted in a previous version of this proposal | # |
> 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 : Posted in a previous version of this proposal | # |
> > 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 : Posted in a previous version of this proposal | # |
> 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.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
André Auzi (aauzi) wrote : Posted in a previous version of this proposal | # |
> > 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 : Posted in a previous version of this proposal | # |
> 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.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
André Auzi (aauzi) wrote : Posted in a previous version of this proposal | # |
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.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
André Auzi (aauzi) wrote : Posted in a previous version of this proposal | # |
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-11 20:53:24 +0000 |
4 | @@ -25,40 +25,11 @@ |
5 | * #KatzeArray is a type aware container for items. |
6 | */ |
7 | |
8 | -struct _KatzeArray |
9 | -{ |
10 | - KatzeItem parent_instance; |
11 | - |
12 | - GType type; |
13 | - GList* items; |
14 | -}; |
15 | - |
16 | -struct _KatzeArrayClass |
17 | -{ |
18 | - KatzeItemClass parent_class; |
19 | - |
20 | - /* Signals */ |
21 | - void |
22 | - (*add_item) (KatzeArray* array, |
23 | - gpointer item); |
24 | - void |
25 | - (*remove_item) (KatzeArray* array, |
26 | - gpointer item); |
27 | - void |
28 | - (*move_item) (KatzeArray* array, |
29 | - gpointer item, |
30 | - gint index); |
31 | - void |
32 | - (*clear) (KatzeArray* array); |
33 | - |
34 | - void |
35 | - (*update) (KatzeArray* array); |
36 | -}; |
37 | - |
38 | G_DEFINE_TYPE (KatzeArray, katze_array, KATZE_TYPE_ITEM); |
39 | |
40 | enum { |
41 | ADD_ITEM, |
42 | + UPDATE_ITEM, |
43 | REMOVE_ITEM, |
44 | MOVE_ITEM, |
45 | CLEAR, |
46 | @@ -95,6 +66,13 @@ |
47 | } |
48 | |
49 | static void |
50 | +_katze_array_update_item (KatzeArray* array, |
51 | + gpointer item) |
52 | +{ |
53 | + _katze_array_update (array); |
54 | +} |
55 | + |
56 | +static void |
57 | _katze_array_remove_item (KatzeArray* array, |
58 | gpointer item) |
59 | { |
60 | @@ -147,6 +125,17 @@ |
61 | G_TYPE_NONE, 1, |
62 | G_TYPE_POINTER); |
63 | |
64 | + signals[UPDATE_ITEM] = g_signal_new ( |
65 | + "update-item", |
66 | + G_TYPE_FROM_CLASS (class), |
67 | + (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION), |
68 | + G_STRUCT_OFFSET (KatzeArrayClass, update_item), |
69 | + 0, |
70 | + NULL, |
71 | + g_cclosure_marshal_VOID__POINTER, |
72 | + G_TYPE_NONE, 1, |
73 | + G_TYPE_POINTER); |
74 | + |
75 | signals[REMOVE_ITEM] = g_signal_new ( |
76 | "remove-item", |
77 | G_TYPE_FROM_CLASS (class), |
78 | @@ -213,6 +202,7 @@ |
79 | gobject_class->finalize = katze_array_finalize; |
80 | |
81 | class->add_item = _katze_array_add_item; |
82 | + class->update_item = _katze_array_update_item; |
83 | class->remove_item = _katze_array_remove_item; |
84 | class->move_item = _katze_array_move_item; |
85 | class->clear = _katze_array_clear; |
86 | @@ -301,6 +291,23 @@ |
87 | } |
88 | |
89 | /** |
90 | + * katze_array_update_item: |
91 | + * @array: a #KatzeArray |
92 | + * @item: an item |
93 | + * |
94 | + * Notify an update of the item of the array. |
95 | + * |
96 | + **/ |
97 | +void |
98 | +katze_array_update_item (KatzeArray* array, |
99 | + gpointer item) |
100 | +{ |
101 | + g_return_if_fail (KATZE_IS_ARRAY (array)); |
102 | + |
103 | + g_signal_emit (array, signals[UPDATE_ITEM], 0, item); |
104 | +} |
105 | + |
106 | +/** |
107 | * katze_array_remove_item: |
108 | * @array: a #KatzeArray |
109 | * @item: an item |
110 | |
111 | === modified file 'katze/katze-array.h' |
112 | --- katze/katze-array.h 2011-01-19 20:58:26 +0000 |
113 | +++ katze/katze-array.h 2013-06-11 20:53:24 +0000 |
114 | @@ -32,6 +32,39 @@ |
115 | typedef struct _KatzeArray KatzeArray; |
116 | typedef struct _KatzeArrayClass KatzeArrayClass; |
117 | |
118 | +struct _KatzeArray |
119 | +{ |
120 | + KatzeItem parent_instance; |
121 | + |
122 | + GType type; |
123 | + GList* items; |
124 | +}; |
125 | + |
126 | +struct _KatzeArrayClass |
127 | +{ |
128 | + KatzeItemClass parent_class; |
129 | + |
130 | + /* Signals */ |
131 | + void |
132 | + (*add_item) (KatzeArray* array, |
133 | + gpointer item); |
134 | + void |
135 | + (*update_item) (KatzeArray* array, |
136 | + gpointer item); |
137 | + void |
138 | + (*remove_item) (KatzeArray* array, |
139 | + gpointer item); |
140 | + void |
141 | + (*move_item) (KatzeArray* array, |
142 | + gpointer item, |
143 | + gint index); |
144 | + void |
145 | + (*clear) (KatzeArray* array); |
146 | + |
147 | + void |
148 | + (*update) (KatzeArray* array); |
149 | +}; |
150 | + |
151 | GType |
152 | katze_array_get_type (void) G_GNUC_CONST; |
153 | |
154 | @@ -47,6 +80,10 @@ |
155 | gpointer item); |
156 | |
157 | void |
158 | +katze_array_update_item (KatzeArray* array, |
159 | + gpointer item); |
160 | + |
161 | +void |
162 | katze_array_remove_item (KatzeArray* array, |
163 | gpointer item); |
164 | |
165 | |
166 | === modified file 'katze/katze-item.c' |
167 | --- katze/katze-item.c 2013-05-31 22:00:38 +0000 |
168 | +++ katze/katze-item.c 2013-06-11 20:53:24 +0000 |
169 | @@ -316,9 +316,12 @@ |
170 | { |
171 | g_return_if_fail (KATZE_IS_ITEM (item)); |
172 | |
173 | + if (!g_strcmp0 (item->name, name)) |
174 | + return; |
175 | + |
176 | katze_assign (item->name, g_strdup (name)); |
177 | if (item->parent) |
178 | - katze_array_update ((KatzeArray*)item->parent); |
179 | + katze_array_update_item ((KatzeArray*)item->parent, item); |
180 | g_object_notify (G_OBJECT (item), "name"); |
181 | } |
182 | |
183 | @@ -420,9 +423,12 @@ |
184 | { |
185 | g_return_if_fail (KATZE_IS_ITEM (item)); |
186 | |
187 | + if (!g_strcmp0 (katze_item_get_meta_string (item, "icon"), icon)) |
188 | + return; |
189 | + |
190 | katze_item_set_meta_string (item, "icon", icon); |
191 | if (item->parent) |
192 | - katze_array_update ((KatzeArray*)item->parent); |
193 | + katze_array_update_item ((KatzeArray*)item->parent, item); |
194 | g_object_notify (G_OBJECT (item), "icon"); |
195 | } |
196 | |
197 | |
198 | === modified file 'midori/midori-array.c' |
199 | --- midori/midori-array.c 2013-05-30 21:57:04 +0000 |
200 | +++ midori/midori-array.c 2013-06-11 20:53:24 +0000 |
201 | @@ -97,15 +97,15 @@ |
202 | if (katze_str_equal ((gchar*)cur->name, "title")) |
203 | { |
204 | gchar* value = g_strstrip ((gchar*)xmlNodeGetContent (cur)); |
205 | + katze_item_set_name (KATZE_ITEM (array), value); |
206 | + xmlFree (value); |
207 | + } |
208 | + else if (katze_str_equal ((gchar*)cur->name, "desc")) |
209 | + { |
210 | + gchar* value = g_strstrip ((gchar*)xmlNodeGetContent (cur)); |
211 | katze_item_set_text (KATZE_ITEM (array), value); |
212 | xmlFree (value); |
213 | } |
214 | - else if (katze_str_equal ((gchar*)cur->name, "desc")) |
215 | - { |
216 | - gchar* value = g_strstrip ((gchar*)xmlNodeGetContent (cur)); |
217 | - katze_item_set_name (KATZE_ITEM (array), value); |
218 | - xmlFree (value); |
219 | - } |
220 | else if (katze_str_equal ((gchar*)cur->name, "info")) |
221 | katze_xbel_parse_info ((KatzeItem*)array, cur); |
222 | else if (katze_str_equal ((gchar*)cur->name, "folder")) |
223 | @@ -986,7 +986,17 @@ |
224 | return FALSE; |
225 | } |
226 | |
227 | -static void |
228 | +/** |
229 | + * katze_item_set_value_from_columne: |
230 | + * @stmt: prepared statement |
231 | + * @column: column to read |
232 | + * @item: #KatzeItem to populate |
233 | + * |
234 | + * Stores the column in the given #KatzeItem. |
235 | + * |
236 | + * Since: 0.2.7 |
237 | + **/ |
238 | +void |
239 | katze_item_set_value_from_column (sqlite3_stmt* stmt, |
240 | gint column, |
241 | KatzeItem* item) |
242 | @@ -1103,244 +1113,3 @@ |
243 | return katze_array_from_statement (stmt); |
244 | } |
245 | |
246 | -/** |
247 | - * midori_array_query_recursive: |
248 | - * @array: the main bookmark array |
249 | - * @fields: comma separated list of fields |
250 | - * @condition: condition, like "folder = '%q'" |
251 | - * @value: a value to be inserted if @condition contains %q |
252 | - * @recursive: if %TRUE include children |
253 | - * |
254 | - * Stores the result in a #KatzeArray. |
255 | - * |
256 | - * Return value: a #KatzeArray on success, %NULL otherwise |
257 | - * |
258 | - * Since: 0.4.4 |
259 | - **/ |
260 | -KatzeArray* |
261 | -midori_array_query_recursive (KatzeArray* bookmarks, |
262 | - const gchar* fields, |
263 | - const gchar* condition, |
264 | - const gchar* value, |
265 | - gboolean recursive) |
266 | -{ |
267 | - sqlite3* db; |
268 | - gchar* sqlcmd; |
269 | - char* sqlcmd_value; |
270 | - KatzeArray* array; |
271 | - KatzeItem* item; |
272 | - GList* list; |
273 | - |
274 | - g_return_val_if_fail (KATZE_IS_ARRAY (bookmarks), NULL); |
275 | - g_return_val_if_fail (fields, NULL); |
276 | - g_return_val_if_fail (condition, NULL); |
277 | - db = g_object_get_data (G_OBJECT (bookmarks), "db"); |
278 | - g_return_val_if_fail (db != NULL, NULL); |
279 | - |
280 | - sqlcmd = g_strdup_printf ("SELECT %s FROM bookmarks WHERE %s " |
281 | - "ORDER BY (uri='') ASC, title DESC", fields, condition); |
282 | - if (strstr (condition, "%q")) |
283 | - { |
284 | - sqlcmd_value = sqlite3_mprintf (sqlcmd, value ? value : ""); |
285 | - array = katze_array_from_sqlite (db, sqlcmd_value); |
286 | - sqlite3_free (sqlcmd_value); |
287 | - } |
288 | - else |
289 | - array = katze_array_from_sqlite (db, sqlcmd); |
290 | - g_free (sqlcmd); |
291 | - |
292 | - if (!recursive) |
293 | - return array; |
294 | - |
295 | - KATZE_ARRAY_FOREACH_ITEM_L (item, array, list) |
296 | - { |
297 | - if (KATZE_ITEM_IS_FOLDER (item)) |
298 | - { |
299 | - gchar* parentid = g_strdup_printf ("%" G_GINT64_FORMAT, |
300 | - katze_item_get_meta_integer (item, "id")); |
301 | - KatzeArray* subarray = midori_array_query_recursive (bookmarks, |
302 | - fields, "parentid=%q", parentid, TRUE); |
303 | - katze_item_set_name (KATZE_ITEM (subarray), katze_item_get_name (item)); |
304 | - katze_array_add_item (array, subarray); |
305 | - |
306 | - g_free (parentid); |
307 | - } |
308 | - } |
309 | - g_list_free (list); |
310 | - return array; |
311 | -} |
312 | - |
313 | -/** |
314 | - * midori_array_query: |
315 | - * @array: the main bookmark array |
316 | - * @fields: comma separated list of fields |
317 | - * @condition: condition, like "folder = '%q'" |
318 | - * @value: a value to be inserted if @condition contains %q |
319 | - * |
320 | - * Stores the result in a #KatzeArray. |
321 | - * |
322 | - * Return value: a #KatzeArray on success, %NULL otherwise |
323 | - * |
324 | - * Since: 0.4.3 |
325 | - * |
326 | - * Deprecated: 0.4.4: Use midori_array_query_recursive() instead. |
327 | - **/ |
328 | -KatzeArray* |
329 | -midori_array_query (KatzeArray* bookmarks, |
330 | - const gchar* fields, |
331 | - const gchar* condition, |
332 | - const gchar* value) |
333 | -{ |
334 | - return midori_array_query_recursive (bookmarks, fields, condition, value, FALSE); |
335 | -} |
336 | - |
337 | -static gint64 |
338 | -count_from_sqlite (sqlite3* db, |
339 | - const gchar* sqlcmd) |
340 | -{ |
341 | - gint64 count = -1; |
342 | - sqlite3_stmt* stmt; |
343 | - gint result; |
344 | - |
345 | - result = sqlite3_prepare_v2 (db, sqlcmd, -1, &stmt, NULL); |
346 | - if (result != SQLITE_OK) |
347 | - return -1; |
348 | - |
349 | - g_assert (sqlite3_column_count (stmt) == 1); |
350 | - |
351 | - if ((result = sqlite3_step (stmt)) == SQLITE_ROW) |
352 | - count = sqlite3_column_int64(stmt, 0); |
353 | - |
354 | - sqlite3_clear_bindings (stmt); |
355 | - sqlite3_reset (stmt); |
356 | - |
357 | - return count; |
358 | -} |
359 | - |
360 | -static gint64 |
361 | -midori_array_count_recursive_by_id (KatzeArray* bookmarks, |
362 | - const gchar* condition, |
363 | - const gchar* value, |
364 | - gint64 id, |
365 | - gboolean recursive) |
366 | -{ |
367 | - gint64 count = -1; |
368 | - sqlite3* db; |
369 | - gchar* sqlcmd; |
370 | - char* sqlcmd_value; |
371 | - sqlite3_stmt* stmt; |
372 | - gint result; |
373 | - GList* ids; |
374 | - GList* iter_ids; |
375 | - |
376 | - g_return_val_if_fail (condition, -1); |
377 | - g_return_val_if_fail (KATZE_IS_ARRAY (bookmarks), -1); |
378 | - db = g_object_get_data (G_OBJECT (bookmarks), "db"); |
379 | - g_return_val_if_fail (db != NULL, -1); |
380 | - |
381 | - g_assert(!strstr("parentid", condition)); |
382 | - |
383 | - if (id > 0) |
384 | - sqlcmd = g_strdup_printf ("SELECT COUNT(*) FROM bookmarks " |
385 | - "WHERE parentid = %" G_GINT64_FORMAT " AND %s", |
386 | - id, |
387 | - condition); |
388 | - else |
389 | - sqlcmd = g_strdup_printf ("SELECT COUNT(*) FROM bookmarks " |
390 | - "WHERE parentid IS NULL AND %s ", |
391 | - condition); |
392 | - |
393 | - if (strstr (condition, "%q")) |
394 | - { |
395 | - sqlcmd_value = sqlite3_mprintf (sqlcmd, value ? value : ""); |
396 | - count = count_from_sqlite (db, sqlcmd_value); |
397 | - sqlite3_free (sqlcmd_value); |
398 | - } |
399 | - else |
400 | - count = count_from_sqlite (db, sqlcmd); |
401 | - |
402 | - g_free (sqlcmd); |
403 | - |
404 | - if (!recursive || (count < 0)) |
405 | - return count; |
406 | - |
407 | - ids = NULL; |
408 | - |
409 | - if (id > 0) |
410 | - sqlcmd_value = sqlite3_mprintf ( |
411 | - "SELECT id FROM bookmarks " |
412 | - "WHERE parentid = %" G_GINT64_FORMAT " AND uri = ''", id); |
413 | - else |
414 | - sqlcmd_value = sqlite3_mprintf ( |
415 | - "SELECT id FROM bookmarks " |
416 | - "WHERE parentid IS NULL AND uri = ''"); |
417 | - |
418 | - if (sqlite3_prepare_v2 (db, sqlcmd_value, -1, &stmt, NULL) == SQLITE_OK) |
419 | - { |
420 | - g_assert (sqlite3_column_count (stmt) == 1); |
421 | - |
422 | - if ((result = sqlite3_step (stmt)) == SQLITE_ROW) |
423 | - { |
424 | - gint64* pid = g_new (gint64, 1); |
425 | - |
426 | - *pid = sqlite3_column_int64(stmt, 0); |
427 | - ids = g_list_append (ids, pid); |
428 | - } |
429 | - |
430 | - sqlite3_clear_bindings (stmt); |
431 | - sqlite3_reset (stmt); |
432 | - } |
433 | - |
434 | - sqlite3_free (sqlcmd_value); |
435 | - |
436 | - iter_ids = ids; |
437 | - while (iter_ids) |
438 | - { |
439 | - gint64 sub_count = midori_array_count_recursive_by_id (bookmarks, |
440 | - condition, |
441 | - value, |
442 | - *(gint64*)(iter_ids->data), |
443 | - recursive); |
444 | - |
445 | - if (sub_count < 0) |
446 | - { |
447 | - g_list_free_full (ids, g_free); |
448 | - return -1; |
449 | - } |
450 | - |
451 | - count += sub_count; |
452 | - iter_ids = g_list_next (iter_ids); |
453 | - } |
454 | - |
455 | - g_list_free_full (ids, g_free); |
456 | - return count; |
457 | -} |
458 | - |
459 | -/** |
460 | - * midori_array_count_recursive: |
461 | - * @array: the main bookmark array |
462 | - * @condition: condition, like "folder = '%q'" |
463 | - * @value: a value to be inserted if @condition contains %q |
464 | - * @recursive: if %TRUE include children |
465 | - * |
466 | - * Return value: the number of elements on success, -1 otherwise |
467 | - * |
468 | - * Since: 0.5.2 |
469 | - **/ |
470 | -gint64 |
471 | -midori_array_count_recursive (KatzeArray* bookmarks, |
472 | - const gchar* condition, |
473 | - const gchar* value, |
474 | - KatzeItem* folder, |
475 | - gboolean recursive) |
476 | -{ |
477 | - gint64 id = -1; |
478 | - |
479 | - g_return_val_if_fail (!folder || KATZE_ITEM_IS_FOLDER (folder), -1); |
480 | - |
481 | - id = folder ? katze_item_get_meta_integer (folder, "id") : 0; |
482 | - |
483 | - return midori_array_count_recursive_by_id (bookmarks, condition, |
484 | - value, id, |
485 | - recursive); |
486 | -} |
487 | |
488 | === modified file 'midori/midori-array.h' |
489 | --- midori/midori-array.h 2013-05-21 21:46:26 +0000 |
490 | +++ midori/midori-array.h 2013-06-11 20:53:24 +0000 |
491 | @@ -27,31 +27,16 @@ |
492 | const gchar* format, |
493 | GError** error); |
494 | |
495 | +void |
496 | +katze_item_set_value_from_column (sqlite3_stmt* stmt, |
497 | + gint column, |
498 | + KatzeItem* item); |
499 | + |
500 | KatzeArray* |
501 | katze_array_from_statement (sqlite3_stmt* stmt); |
502 | |
503 | KatzeArray* |
504 | -midori_array_query (KatzeArray* array, |
505 | - const gchar* fields, |
506 | - const gchar* condition, |
507 | - const gchar* value); |
508 | - |
509 | -KatzeArray* |
510 | -midori_array_query_recursive (KatzeArray* array, |
511 | - const gchar* fields, |
512 | - const gchar* condition, |
513 | - const gchar* value, |
514 | - gboolean recursive); |
515 | - |
516 | -KatzeArray* |
517 | katze_array_from_sqlite (sqlite3* db, |
518 | const gchar* sqlcmd); |
519 | |
520 | -gint64 |
521 | -midori_array_count_recursive (KatzeArray* bookmarks, |
522 | - const gchar* condition, |
523 | - const gchar* value, |
524 | - KatzeItem* folder, |
525 | - gboolean recursive); |
526 | - |
527 | #endif /* !__MIDORI_ARRAY_H__ */ |
528 | |
529 | === renamed file 'midori/midori-bookmarks.c' => 'midori/midori-bookmarks-db.c' |
530 | --- midori/midori-bookmarks.c 2012-11-25 15:37:41 +0000 |
531 | +++ midori/midori-bookmarks-db.c 2013-06-11 20:53:24 +0000 |
532 | @@ -10,8 +10,8 @@ |
533 | See the file COPYING for the full license text. |
534 | */ |
535 | |
536 | -#include "midori-bookmarks.h" |
537 | -#include "panels/midori-bookmarks.h" |
538 | +#include "midori-bookmarks-db.h" |
539 | + |
540 | #include "midori-app.h" |
541 | #include "midori-array.h" |
542 | #include "sokoke.h" |
543 | @@ -25,42 +25,818 @@ |
544 | #include <unistd.h> |
545 | #endif |
546 | |
547 | -void |
548 | -midori_bookmarks_dbtracer (void* dummy, |
549 | - const char* query) |
550 | -{ |
551 | - g_printerr ("%s\n", query); |
552 | -} |
553 | - |
554 | -void |
555 | -midori_bookmarks_add_item_cb (KatzeArray* array, |
556 | - KatzeItem* item, |
557 | - sqlite3* db) |
558 | -{ |
559 | - midori_bookmarks_insert_item_db (db, item, |
560 | - katze_item_get_meta_integer (item, "parentid")); |
561 | -} |
562 | - |
563 | -void |
564 | -midori_bookmarks_remove_item_cb (KatzeArray* array, |
565 | - KatzeItem* item, |
566 | - sqlite3* db) |
567 | -{ |
568 | - gchar* sqlcmd; |
569 | - char* errmsg = NULL; |
570 | - |
571 | - |
572 | - sqlcmd = sqlite3_mprintf ( |
573 | - "DELETE FROM bookmarks WHERE id = %" G_GINT64_FORMAT ";", |
574 | +/** |
575 | + * SECTION:midory-bookmarks-db |
576 | + * @short_description: A #KatzeArray connected to a database |
577 | + * @see_also: #KatzeArray |
578 | + * |
579 | + * #MidoriBookmarksDb is a #KatzeArray specialized for database |
580 | + * interraction. |
581 | + */ |
582 | + |
583 | +struct _MidoriBookmarksDb |
584 | +{ |
585 | + KatzeArray parent_instance; |
586 | + |
587 | + sqlite3* db; |
588 | + GList* pending_inserts; |
589 | + GHashTable* pending_updates; |
590 | + GHashTable* pending_deletes; |
591 | + GHashTable* all_items; |
592 | + gboolean in_idle_func; |
593 | +}; |
594 | + |
595 | +struct _MidoriBookmarksDbClass |
596 | +{ |
597 | + KatzeArrayClass parent_class; |
598 | +}; |
599 | + |
600 | +G_DEFINE_TYPE (MidoriBookmarksDb, midori_bookmarks_db, KATZE_TYPE_ARRAY); |
601 | + |
602 | +static void |
603 | +_midori_bookmarks_db_add_item (KatzeArray* array, |
604 | + gpointer item); |
605 | + |
606 | +static void |
607 | +_midori_bookmarks_db_update_item (KatzeArray* array, |
608 | + gpointer item); |
609 | + |
610 | +static void |
611 | +_midori_bookmarks_db_remove_item (KatzeArray* array, |
612 | + gpointer item); |
613 | + |
614 | +static void |
615 | +_midori_bookmarks_db_move_item (KatzeArray* array, |
616 | + gpointer item, |
617 | + gint position); |
618 | + |
619 | +static void |
620 | +_midori_bookmarks_db_clear (KatzeArray* array); |
621 | + |
622 | +static void |
623 | +midori_bookmarks_db_force_idle (MidoriBookmarksDb* bookmarks); |
624 | + |
625 | +static void |
626 | +midori_bookmarks_db_finalize (GObject* object); |
627 | + |
628 | +static gint64 |
629 | +midori_bookmarks_db_insert_item_db (sqlite3* db, |
630 | + KatzeItem* item, |
631 | + gint64 parentid); |
632 | + |
633 | +static gboolean |
634 | +midori_bookmarks_db_update_item_db (sqlite3* db, |
635 | + KatzeItem* item); |
636 | + |
637 | +static gboolean |
638 | +midori_bookmarks_db_remove_item_db (sqlite3* db, |
639 | + KatzeItem* item); |
640 | + |
641 | +static guint |
642 | +item_hash (gconstpointer item) |
643 | +{ |
644 | + gint64 id = katze_item_get_meta_integer (KATZE_ITEM (item), "id"); |
645 | + return g_int64_hash (&id); |
646 | +} |
647 | + |
648 | +static gboolean |
649 | +item_equal (gconstpointer item_a, gconstpointer item_b) |
650 | +{ |
651 | + gint64 id_a = katze_item_get_meta_integer (KATZE_ITEM (item_a), "id"); |
652 | + gint64 id_b = katze_item_get_meta_integer (KATZE_ITEM (item_b), "id"); |
653 | + return (id_a == id_b)? TRUE : FALSE; |
654 | +} |
655 | + |
656 | +static void |
657 | +midori_bookmarks_db_class_init (MidoriBookmarksDbClass* class) |
658 | +{ |
659 | + GObjectClass* gobject_class; |
660 | + KatzeArrayClass* katze_array_class; |
661 | + |
662 | + gobject_class = G_OBJECT_CLASS (class); |
663 | + gobject_class->finalize = midori_bookmarks_db_finalize; |
664 | + |
665 | + katze_array_class = KATZE_ARRAY_CLASS (class); |
666 | + |
667 | + katze_array_class->add_item = _midori_bookmarks_db_add_item; |
668 | + katze_array_class->update_item = _midori_bookmarks_db_update_item; |
669 | + katze_array_class->remove_item = _midori_bookmarks_db_remove_item; |
670 | + katze_array_class->move_item = _midori_bookmarks_db_move_item; |
671 | + katze_array_class->clear = _midori_bookmarks_db_clear; |
672 | +} |
673 | + |
674 | +static void |
675 | +midori_bookmarks_db_init (MidoriBookmarksDb* bookmarks) |
676 | +{ |
677 | + bookmarks->db = NULL; |
678 | + bookmarks->pending_inserts = NULL; |
679 | + bookmarks->pending_updates = g_hash_table_new (item_hash, item_equal); |
680 | + bookmarks->pending_deletes = g_hash_table_new (item_hash, item_equal); |
681 | + bookmarks->all_items = g_hash_table_new (item_hash, item_equal); |
682 | + |
683 | + bookmarks->in_idle_func = FALSE; |
684 | + |
685 | + katze_item_set_meta_integer (KATZE_ITEM (bookmarks), "id", 0); |
686 | + g_hash_table_insert (bookmarks->all_items, bookmarks, bookmarks); |
687 | + /* g_object_ref (bookmarks); */ |
688 | +} |
689 | + |
690 | +static void |
691 | +midori_bookmarks_db_finalize (GObject* object) |
692 | +{ |
693 | + MidoriBookmarksDb* bookmarks = MIDORI_BOOKMARKS_DB (object); |
694 | + |
695 | + if (bookmarks->db) |
696 | + { |
697 | + midori_bookmarks_db_force_idle (bookmarks); |
698 | + sqlite3_close (bookmarks->db); |
699 | + } |
700 | + |
701 | + g_list_free (bookmarks->pending_inserts); |
702 | + g_hash_table_unref (bookmarks->pending_updates); |
703 | + g_hash_table_unref (bookmarks->pending_deletes); |
704 | + g_hash_table_unref (bookmarks->all_items); |
705 | + |
706 | + G_OBJECT_CLASS (midori_bookmarks_db_parent_class)->finalize (object); |
707 | +} |
708 | + |
709 | +/** |
710 | + * midori_bookmarks_db_get_item_parent: |
711 | + * @bookmarks: the main bookmarks array |
712 | + * @item: a #KatzeItem |
713 | + * |
714 | + * Internal function that find the parent of the @item thanks to its %parentid |
715 | + **/ |
716 | +static KatzeArray* |
717 | +midori_bookmarks_db_get_item_parent (MidoriBookmarksDb* bookmarks, |
718 | + gpointer item) |
719 | +{ |
720 | + KatzeArray* parent; |
721 | + gint64 parentid; |
722 | + |
723 | + parentid = katze_item_get_meta_integer (KATZE_ITEM (item), "parentid"); |
724 | + |
725 | + if (parentid == 0) |
726 | + { |
727 | + parent = KATZE_ARRAY (bookmarks); |
728 | + } |
729 | + else |
730 | + { |
731 | + KatzeItem *search = katze_item_new (); |
732 | + |
733 | + katze_item_set_meta_integer(search, "id", parentid); |
734 | + |
735 | + parent = KATZE_ARRAY (g_hash_table_lookup (bookmarks->all_items, search)); |
736 | + |
737 | + g_object_unref (search); |
738 | + } |
739 | + |
740 | + return parent; |
741 | +} |
742 | + |
743 | +/** |
744 | + * _midori_bookmarks_db_add_item: |
745 | + * @array: the main bookmarks array |
746 | + * @item: a #KatzeItem |
747 | + * |
748 | + * Internal function that overloads the #KatzeArray %katze_array_add_item(). |
749 | + * It relays the add item to the appropriate #KatzeArray. |
750 | + **/ |
751 | +static void |
752 | +_midori_bookmarks_db_add_item (KatzeArray* array, |
753 | + gpointer item) |
754 | +{ |
755 | + MidoriBookmarksDb *bookmarks; |
756 | + KatzeArray* parent; |
757 | + |
758 | + g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (array)); |
759 | + g_return_if_fail (KATZE_IS_ITEM (item)); |
760 | + |
761 | + bookmarks = MIDORI_BOOKMARKS_DB (array); |
762 | + g_return_if_fail (bookmarks->in_idle_func); |
763 | + |
764 | + parent = katze_item_get_parent (KATZE_ITEM (item)); |
765 | + |
766 | + g_return_if_fail (!parent); |
767 | + |
768 | + parent = midori_bookmarks_db_get_item_parent (bookmarks, item); |
769 | + |
770 | + g_return_if_fail (parent); |
771 | + |
772 | + KATZE_ARRAY_CLASS (midori_bookmarks_db_parent_class)->add_item (parent, item); |
773 | +} |
774 | + |
775 | +/** |
776 | + * _midori_bookmarks_db_update_item: |
777 | + * @array: the main bookmarks array |
778 | + * @item: a #KatzeItem |
779 | + * |
780 | + * Internal function that overloads the #KatzeArray %katze_array_update_item(). |
781 | + * It relays the update item to the appropriate #KatzeArray. |
782 | + **/ |
783 | +static void |
784 | +_midori_bookmarks_db_update_item (KatzeArray* array, |
785 | + gpointer item) |
786 | +{ |
787 | + MidoriBookmarksDb *bookmarks; |
788 | + KatzeArray* parent; |
789 | + |
790 | + g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (array)); |
791 | + g_return_if_fail (KATZE_IS_ITEM (item)); |
792 | + |
793 | + bookmarks = MIDORI_BOOKMARKS_DB (array); |
794 | + g_return_if_fail (bookmarks->in_idle_func); |
795 | + |
796 | + parent = katze_item_get_parent (KATZE_ITEM (item)); |
797 | + |
798 | + g_return_if_fail (parent); |
799 | + |
800 | + KATZE_ARRAY_CLASS (midori_bookmarks_db_parent_class)->update_item (parent, item); |
801 | +} |
802 | + |
803 | +/** |
804 | + * _midori_bookmarks_db_remove_item: |
805 | + * @array: the main bookmarks array |
806 | + * @item: a #KatzeItem |
807 | + * |
808 | + * Internal function that overloads the #KatzeArray %katze_array_remove_item(). |
809 | + * It relays the remove item to the appropriate #KatzeArray. |
810 | + **/ |
811 | +static void |
812 | +_midori_bookmarks_db_remove_item (KatzeArray* array, |
813 | + gpointer item) |
814 | +{ |
815 | + MidoriBookmarksDb *bookmarks; |
816 | + KatzeArray* parent; |
817 | + |
818 | + g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (array)); |
819 | + g_return_if_fail (KATZE_IS_ITEM (item)); |
820 | + |
821 | + bookmarks = MIDORI_BOOKMARKS_DB (array); |
822 | + g_return_if_fail (bookmarks->in_idle_func); |
823 | + |
824 | + parent = katze_item_get_parent (KATZE_ITEM (item)); |
825 | + |
826 | + g_return_if_fail (parent); |
827 | + |
828 | + KATZE_ARRAY_CLASS (midori_bookmarks_db_parent_class)->remove_item (parent, item); |
829 | +} |
830 | + |
831 | +/** |
832 | + * _midori_bookmarks_db_move_item: |
833 | + * @array: the main bookmarks array |
834 | + * @item: a #KatzeItem |
835 | + * @position: the new @item position |
836 | + * |
837 | + * Internal function that overloads the #KatzeArray %katze_array_move_item(). |
838 | + * It relays the move @item to the appropriate #KatzeArray. |
839 | + **/ |
840 | +static void |
841 | +_midori_bookmarks_db_move_item (KatzeArray* array, |
842 | + gpointer item, |
843 | + gint position) |
844 | +{ |
845 | + MidoriBookmarksDb *bookmarks; |
846 | + KatzeArray* parent; |
847 | + |
848 | + g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (array)); |
849 | + g_return_if_fail (KATZE_IS_ITEM (item)); |
850 | + |
851 | + parent = katze_item_get_parent (KATZE_ITEM (item)); |
852 | + |
853 | + g_return_if_fail (parent); |
854 | + |
855 | + KATZE_ARRAY_CLASS (midori_bookmarks_db_parent_class)->move_item (parent, item, position); |
856 | +} |
857 | + |
858 | +/** |
859 | + * _midori_bookmarks_db_clear: |
860 | + * @array: the main bookmarks array |
861 | + * |
862 | + * Internal function that overloads the #KatzeArray %katze_array_clear(). |
863 | + * It deletes the whole bookmarks data. |
864 | + **/ |
865 | +static void |
866 | +_midori_bookmarks_db_clear (KatzeArray* array) |
867 | +{ |
868 | + MidoriBookmarksDb *bookmarks; |
869 | + g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (array)); |
870 | + |
871 | + bookmarks = MIDORI_BOOKMARKS_DB (array); |
872 | + |
873 | + g_critical ("_midori_bookmarks_db_clear: not implemented\n"); |
874 | +} |
875 | + |
876 | +/** |
877 | + * midori_bookmarks_db_begin_transaction: |
878 | + * @db: the removed #KatzeItem |
879 | + * |
880 | + * Internal function that starts an SQL transaction. |
881 | + **/ |
882 | +static gboolean |
883 | +midori_bookmarks_db_begin_transaction (sqlite3* db) |
884 | +{ |
885 | + char* errmsg = NULL; |
886 | + |
887 | + if (sqlite3_exec (db, "BEGIN TRANSACTION;", NULL, NULL, &errmsg) != SQLITE_OK) |
888 | + { |
889 | + g_printerr (_("Failed to begin transaction: %s\n"), errmsg); |
890 | + sqlite3_free (errmsg); |
891 | + return FALSE; |
892 | + } |
893 | + |
894 | + return TRUE; |
895 | +} |
896 | + |
897 | +/** |
898 | + * midori_bookmarks_db_end_transaction: |
899 | + * @db: the removed #KatzeItem |
900 | + * @commit : boolean |
901 | + * |
902 | + * Internal function that ends an SQL transaction. |
903 | + * If @commit is %TRUE, the transaction is ended by a COMMIT. |
904 | + * It is ended by a ROLLBACK otherwise. |
905 | + **/ |
906 | +static void |
907 | +midori_bookmarks_db_end_transaction (sqlite3* db, gboolean commit) |
908 | +{ |
909 | + char* errmsg = NULL; |
910 | + if (sqlite3_exec (db, (commit ? "COMMIT;" : "ROLLBACK;"), NULL, NULL, &errmsg) != SQLITE_OK) |
911 | + { |
912 | + if (commit) |
913 | + g_printerr (_("Failed to end transaction: %s\n"), errmsg); |
914 | + else |
915 | + g_printerr (_("Failed to cancel transaction: %s\n"), errmsg); |
916 | + sqlite3_free (errmsg); |
917 | + } |
918 | +} |
919 | + |
920 | +/** |
921 | + * midori_bookmarks_db_add_item_recursive: |
922 | + * @item: the removed #KatzeItem |
923 | + * @bookmarks : the main bookmarks array |
924 | + * |
925 | + * Internal function that creates memory records of the added @item. |
926 | + * If @item is a #KatzeArray, the function recursiveley adds records |
927 | + * of all its childs. |
928 | + **/ |
929 | +static gint |
930 | +midori_bookmarks_db_add_item_recursive (MidoriBookmarksDb* bookmarks, |
931 | + KatzeItem* item) |
932 | +{ |
933 | + GList* list; |
934 | + KatzeArray* array; |
935 | + gint64 id = 0; |
936 | + gint count = 0; |
937 | + gint64 parentid = katze_item_get_meta_integer (item, "parentid"); |
938 | + |
939 | + id = midori_bookmarks_db_insert_item_db (bookmarks->db, item, parentid); |
940 | + count++; |
941 | + |
942 | + g_object_ref (item); |
943 | + g_hash_table_insert (bookmarks->all_items, item, item); |
944 | + |
945 | + if (!KATZE_IS_ARRAY (item)) |
946 | + return count; |
947 | + |
948 | + array = KATZE_ARRAY (item); |
949 | + |
950 | + KATZE_ARRAY_FOREACH_ITEM_L (item, array, list) |
951 | + { |
952 | + katze_item_set_meta_integer (item, "parentid", id); |
953 | + count += midori_bookmarks_db_add_item_recursive (bookmarks, item); |
954 | + } |
955 | + |
956 | + g_list_free (list); |
957 | + return count; |
958 | +} |
959 | + |
960 | +/** |
961 | + * midori_bookmarks_db_remove_item_recursive: |
962 | + * @item: the removed #KatzeItem |
963 | + * @bookmarks : the main bookmarks array |
964 | + * |
965 | + * Internal function that removes memory records of the removed @item. |
966 | + * If @item is a #KatzeArray, the function recursiveley removes records |
967 | + * of all its childs. |
968 | + **/ |
969 | +static void |
970 | +midori_bookmarks_db_remove_item_recursive (KatzeItem* item, |
971 | + MidoriBookmarksDb* bookmarks) |
972 | +{ |
973 | + gint64 id = katze_item_get_meta_integer (item, "id"); |
974 | + GHashTableIter hash_iter; |
975 | + gpointer key, value; |
976 | + gpointer found; |
977 | + KatzeArray* array; |
978 | + KatzeItem* child; |
979 | + GList* list; |
980 | + |
981 | + if (NULL != (found = g_list_find (bookmarks->pending_inserts, item))) |
982 | + { |
983 | + g_object_unref (((GList*)found)->data); |
984 | + bookmarks->pending_inserts = g_list_delete_link (bookmarks->pending_inserts, |
985 | + ((GList*)found)); |
986 | + } |
987 | + |
988 | + if (NULL != (found = g_hash_table_lookup (bookmarks->pending_updates, item))) |
989 | + { |
990 | + g_hash_table_remove (bookmarks->pending_updates, found); |
991 | + g_object_unref (found); |
992 | + } |
993 | + |
994 | + if (NULL != (found = g_hash_table_lookup (bookmarks->all_items, item))) |
995 | + { |
996 | + g_hash_table_remove (bookmarks->all_items, found); |
997 | + g_object_unref (found); |
998 | + } |
999 | + |
1000 | + if (!KATZE_IS_ARRAY (item)) |
1001 | + return; |
1002 | + |
1003 | + array = KATZE_ARRAY (item); |
1004 | + |
1005 | + KATZE_ARRAY_FOREACH_ITEM_L (child, array, list) |
1006 | + { |
1007 | + midori_bookmarks_db_remove_item_recursive (child, bookmarks); |
1008 | + } |
1009 | + |
1010 | + g_list_free (list); |
1011 | +} |
1012 | + |
1013 | +/** |
1014 | + * midori_bookmarks_db_idle_func: |
1015 | + * @data: the main bookmark array |
1016 | + * |
1017 | + * Internal function executed during idle time that Packs pending database |
1018 | + * operations in one transaction. |
1019 | + * |
1020 | + * Pending operations are either: |
1021 | + * a. a list of pending add items, |
1022 | + * all child #KatzeItem of a #KatzeArray are recursively added. |
1023 | + * Each added #KatzeItem is memorized for future use. |
1024 | + * (See %midori_bookmarks_db_array_from_statement()) |
1025 | + * b. a hash table of items to update, |
1026 | + * c. or a hash table of items to remove |
1027 | + * the database CASCADE on delete takes care of removal of the childs |
1028 | + * #KatzeItem of a #KatzeArray in the database |
1029 | + * |
1030 | + * When database operations are done, the #KatzeArray equivalent operations |
1031 | + * are called to: |
1032 | + * 1. update the #KatzeArray tree content |
1033 | + * 2. signal the client views of the #KatzeArray tree content change. |
1034 | + **/ |
1035 | +static gboolean |
1036 | +midori_bookmarks_db_idle_func (gpointer data) |
1037 | +{ |
1038 | + GTimer *timer = g_timer_new(); |
1039 | + gint count = 0; |
1040 | + gulong microseconds; |
1041 | + gboolean with_transaction; |
1042 | + MidoriBookmarksDb* bookmarks = MIDORI_BOOKMARKS_DB (data); |
1043 | + GList* list_iter; |
1044 | + GHashTableIter hash_iter; |
1045 | + gpointer key, value; |
1046 | + |
1047 | + bookmarks->in_idle_func = TRUE; |
1048 | + |
1049 | + g_timer_start (timer); |
1050 | + |
1051 | + with_transaction = midori_bookmarks_db_begin_transaction (bookmarks->db); |
1052 | + |
1053 | + for (list_iter = bookmarks->pending_inserts; list_iter; list_iter = g_list_next (list_iter)) |
1054 | + { |
1055 | + KatzeItem *item = KATZE_ITEM (list_iter->data); |
1056 | + |
1057 | + count += midori_bookmarks_db_add_item_recursive (bookmarks, item); |
1058 | + katze_array_add_item (KATZE_ARRAY (bookmarks), item); |
1059 | + |
1060 | + g_object_unref (item); |
1061 | + } |
1062 | + |
1063 | + g_hash_table_iter_init (&hash_iter, bookmarks->pending_updates); |
1064 | + |
1065 | + while (g_hash_table_iter_next (&hash_iter, &key, &value)) |
1066 | + { |
1067 | + KatzeItem *item = KATZE_ITEM (value); |
1068 | + |
1069 | + midori_bookmarks_db_update_item_db (bookmarks->db, item); |
1070 | + katze_array_update_item (KATZE_ARRAY (bookmarks), item); |
1071 | + g_object_unref (item); |
1072 | + count++; |
1073 | + } |
1074 | + |
1075 | + g_hash_table_iter_init (&hash_iter, bookmarks->pending_deletes); |
1076 | + |
1077 | + while (g_hash_table_iter_next (&hash_iter, &key, &value)) |
1078 | + { |
1079 | + KatzeItem *item = KATZE_ITEM (value); |
1080 | + |
1081 | + midori_bookmarks_db_remove_item_db (bookmarks->db, item); |
1082 | + katze_array_remove_item (KATZE_ARRAY (bookmarks), item); |
1083 | + g_object_unref (item); |
1084 | + count++; |
1085 | + } |
1086 | + |
1087 | + if (with_transaction) |
1088 | + midori_bookmarks_db_end_transaction (bookmarks->db, TRUE); |
1089 | + |
1090 | + g_timer_elapsed (timer, µseconds); |
1091 | + g_print ("midori_bookmarks_db_idle: %d DB operation(s) in %lu micro-seconds\n", |
1092 | + count, microseconds); |
1093 | + |
1094 | + g_timer_destroy (timer); |
1095 | + |
1096 | + g_hash_table_remove_all (bookmarks->pending_deletes); |
1097 | + g_hash_table_remove_all (bookmarks->pending_updates); |
1098 | + g_list_free (bookmarks->pending_inserts); |
1099 | + bookmarks->pending_inserts = NULL; |
1100 | + |
1101 | + bookmarks->in_idle_func = FALSE; |
1102 | + |
1103 | + return FALSE; |
1104 | +} |
1105 | + |
1106 | +/** |
1107 | + * midori_bookmarks_db_idle_start: |
1108 | + * @bookmarks: the main bookmark array |
1109 | + * |
1110 | + * Internal function that checks whether idle processing is pending, |
1111 | + * if not, add a new one. |
1112 | + **/ |
1113 | +static void |
1114 | +midori_bookmarks_db_idle_start (MidoriBookmarksDb* bookmarks) |
1115 | +{ |
1116 | + g_return_if_fail (bookmarks->db != NULL); |
1117 | + |
1118 | + if (bookmarks->pending_inserts |
1119 | + || g_hash_table_size (bookmarks->pending_updates) |
1120 | + || g_hash_table_size (bookmarks->pending_deletes)) |
1121 | + return; |
1122 | + |
1123 | + g_idle_add (midori_bookmarks_db_idle_func, bookmarks); |
1124 | +} |
1125 | + |
1126 | +/** |
1127 | + * midori_bookmarks_db_insert_item_db: |
1128 | + * @db: the #sqlite3 |
1129 | + * @item: #KatzeItem the item to insert |
1130 | + * |
1131 | + * Internal function that does the actual SQL INSERT of the @item in @db. |
1132 | + * |
1133 | + * Since: 0.5.2 |
1134 | + **/ |
1135 | +static gint64 |
1136 | +midori_bookmarks_db_insert_item_db (sqlite3* db, |
1137 | + KatzeItem* item, |
1138 | + gint64 parentid) |
1139 | +{ |
1140 | + gchar* sqlcmd; |
1141 | + char* errmsg = NULL; |
1142 | + KatzeItem* old_parent; |
1143 | + gchar* new_parentid; |
1144 | + gchar* id = NULL; |
1145 | + const gchar* uri = NULL; |
1146 | + const gchar* desc = NULL; |
1147 | + gint64 seq = 0; |
1148 | + |
1149 | + /* Bookmarks must have a name, import may produce invalid items */ |
1150 | + g_return_val_if_fail (katze_item_get_name (item), seq); |
1151 | + |
1152 | + if (!db) |
1153 | + return seq; |
1154 | + |
1155 | + if (katze_item_get_meta_integer (item, "id") > 0) |
1156 | + id = g_strdup_printf ("%" G_GINT64_FORMAT, katze_item_get_meta_integer(item, "id")); |
1157 | + else |
1158 | + id = g_strdup_printf ("NULL"); |
1159 | + |
1160 | + if (KATZE_ITEM_IS_BOOKMARK (item)) |
1161 | + uri = katze_item_get_uri (item); |
1162 | + |
1163 | + if (katze_item_get_text (item)) |
1164 | + desc = katze_item_get_text (item); |
1165 | + |
1166 | + /* Use folder, otherwise fallback to parent folder */ |
1167 | + old_parent = katze_item_get_parent (item); |
1168 | + if (parentid > 0) |
1169 | + new_parentid = g_strdup_printf ("%" G_GINT64_FORMAT, parentid); |
1170 | + else if (old_parent && katze_item_get_meta_integer (old_parent, "id") > 0) |
1171 | + new_parentid = g_strdup_printf ("%" G_GINT64_FORMAT, katze_item_get_meta_integer (old_parent, "id")); |
1172 | + else |
1173 | + new_parentid = g_strdup_printf ("NULL"); |
1174 | + |
1175 | + sqlcmd = sqlite3_mprintf ( |
1176 | + "INSERT INTO bookmarks (id, parentid, title, uri, desc, toolbar, app) " |
1177 | + "VALUES (%q, %q, '%q', '%q', '%q', %d, %d)", |
1178 | + id, |
1179 | + new_parentid, |
1180 | + katze_item_get_name (item), |
1181 | + katze_str_non_null (uri), |
1182 | + katze_str_non_null (desc), |
1183 | + katze_item_get_meta_boolean (item, "toolbar"), |
1184 | + katze_item_get_meta_boolean (item, "app")); |
1185 | + |
1186 | + if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) == SQLITE_OK) |
1187 | + { |
1188 | + /* Get insert id */ |
1189 | + if (g_str_equal (id, "NULL")) |
1190 | + { |
1191 | + KatzeArray* seq_array; |
1192 | + |
1193 | + sqlite3_free (sqlcmd); |
1194 | + sqlcmd = sqlite3_mprintf ( |
1195 | + "SELECT seq FROM sqlite_sequence WHERE name = 'bookmarks'"); |
1196 | + |
1197 | + seq_array = katze_array_from_sqlite (db, sqlcmd); |
1198 | + if (katze_array_get_nth_item (seq_array, 0)) |
1199 | + { |
1200 | + KatzeItem* seq_item = katze_array_get_nth_item (seq_array, 0); |
1201 | + |
1202 | + seq = katze_item_get_meta_integer (seq_item, "seq"); |
1203 | + katze_item_set_meta_integer (item, "id", seq); |
1204 | + } |
1205 | + g_object_unref (seq_array); |
1206 | + } |
1207 | + } |
1208 | + else |
1209 | + { |
1210 | + g_printerr (_("Failed to add bookmark item: %s\n"), errmsg); |
1211 | + sqlite3_free (errmsg); |
1212 | + } |
1213 | + |
1214 | + sqlite3_free (sqlcmd); |
1215 | + g_free (new_parentid); |
1216 | + g_free (id); |
1217 | + |
1218 | + return seq; |
1219 | +} |
1220 | + |
1221 | +/** |
1222 | + * midori_bookmarks_db_update_item_db: |
1223 | + * @db: the #sqlite3 |
1224 | + * @item: #KatzeItem the item to update |
1225 | + * |
1226 | + * Internal function that does the actual SQL UPDATE of the @item in @db. |
1227 | + * |
1228 | + * Since: 0.5.2 |
1229 | + **/ |
1230 | +static gboolean |
1231 | +midori_bookmarks_db_update_item_db (sqlite3* db, |
1232 | + KatzeItem* item) |
1233 | +{ |
1234 | + gchar* sqlcmd; |
1235 | + char* errmsg = NULL; |
1236 | + gchar* parentid; |
1237 | + gboolean updated; |
1238 | + |
1239 | + if (katze_item_get_meta_integer (item, "parentid") > 0) |
1240 | + parentid = g_strdup_printf ("%" G_GINT64_FORMAT, |
1241 | + katze_item_get_meta_integer (item, "parentid")); |
1242 | + else |
1243 | + parentid = g_strdup_printf ("NULL"); |
1244 | + |
1245 | + sqlcmd = sqlite3_mprintf ( |
1246 | + "UPDATE bookmarks SET " |
1247 | + "parentid=%q, title='%q', uri='%q', desc='%q', toolbar=%d, app=%d " |
1248 | + "WHERE id = %" G_GINT64_FORMAT ";", |
1249 | + parentid, |
1250 | + katze_item_get_name (item), |
1251 | + katze_str_non_null (katze_item_get_uri (item)), |
1252 | + katze_str_non_null (katze_item_get_meta_string (item, "desc")), |
1253 | + katze_item_get_meta_boolean (item, "toolbar"), |
1254 | + katze_item_get_meta_boolean (item, "app"), |
1255 | katze_item_get_meta_integer (item, "id")); |
1256 | |
1257 | - if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK) |
1258 | - { |
1259 | - g_printerr (_("Failed to remove history item: %s\n"), errmsg); |
1260 | - sqlite3_free (errmsg); |
1261 | - } |
1262 | - |
1263 | - sqlite3_free (sqlcmd); |
1264 | + updated = TRUE; |
1265 | + if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK) |
1266 | + { |
1267 | + updated = FALSE; |
1268 | + g_printerr (_("Failed to update bookmark : %s\n"), errmsg); |
1269 | + sqlite3_free (errmsg); |
1270 | + } |
1271 | + |
1272 | + sqlite3_free (sqlcmd); |
1273 | + g_free (parentid); |
1274 | + |
1275 | + return updated; |
1276 | +} |
1277 | + |
1278 | +/** |
1279 | + * midori_bookmarks_db_remove_item_db: |
1280 | + * @db: the #sqlite3 |
1281 | + * @item: #KatzeItem the item to delete |
1282 | + * |
1283 | + * Internal function that does the actual SQL DELETE of the @item in @db. |
1284 | + * |
1285 | + * Since: 0.5.2 |
1286 | + **/ |
1287 | +static gboolean |
1288 | +midori_bookmarks_db_remove_item_db (sqlite3* db, |
1289 | + KatzeItem* item) |
1290 | +{ |
1291 | + char* errmsg = NULL; |
1292 | + gchar* sqlcmd; |
1293 | + gboolean removed = TRUE; |
1294 | + |
1295 | + sqlcmd = sqlite3_mprintf ( |
1296 | + "DELETE FROM bookmarks WHERE id = %" G_GINT64_FORMAT ";", |
1297 | + katze_item_get_meta_integer (item, "id")); |
1298 | + |
1299 | + if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK) |
1300 | + { |
1301 | + g_printerr (_("Failed to remove bookmark item: %s\n"), errmsg); |
1302 | + sqlite3_free (errmsg); |
1303 | + removed = FALSE; |
1304 | + } |
1305 | + |
1306 | + sqlite3_free (sqlcmd); |
1307 | + return removed; |
1308 | +} |
1309 | + |
1310 | +/** |
1311 | + * midori_bookmarks_db_add_item: |
1312 | + * @bookmarks: the main bookmark array |
1313 | + * @item: #KatzeItem the item to update |
1314 | + * |
1315 | + * Adds the @item in the bookmark data base. |
1316 | + * |
1317 | + * Since: 0.5.2 |
1318 | + **/ |
1319 | +void |
1320 | +midori_bookmarks_db_add_item (MidoriBookmarksDb* bookmarks, KatzeItem* item) |
1321 | +{ |
1322 | + g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (bookmarks)); |
1323 | + g_return_if_fail (KATZE_IS_ITEM (item)); |
1324 | + g_return_if_fail (NULL == katze_item_get_meta_string (item, "id")); |
1325 | + |
1326 | + gpointer found = g_list_find (bookmarks->pending_inserts, item); |
1327 | + |
1328 | + if (found) |
1329 | + return; |
1330 | + |
1331 | + midori_bookmarks_db_idle_start (bookmarks); |
1332 | + |
1333 | + g_object_ref (item); |
1334 | + bookmarks->pending_inserts = g_list_append (bookmarks->pending_inserts, item); |
1335 | +} |
1336 | + |
1337 | +/** |
1338 | + * midori_bookmarks_db_update_item: |
1339 | + * @bookmarks: the main bookmark array |
1340 | + * @item: #KatzeItem the item to update |
1341 | + * |
1342 | + * Updates the @item in the bookmark data base. |
1343 | + * |
1344 | + * Since: 0.5.2 |
1345 | + **/ |
1346 | +void |
1347 | +midori_bookmarks_db_update_item (MidoriBookmarksDb* bookmarks, KatzeItem* item) |
1348 | +{ |
1349 | + g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (bookmarks)); |
1350 | + g_return_if_fail (KATZE_IS_ITEM (item)); |
1351 | + g_return_if_fail (katze_item_get_meta_string (item, "id")); |
1352 | + g_return_if_fail (0 != katze_item_get_meta_integer (item, "id")); |
1353 | + |
1354 | + gpointer found = g_hash_table_lookup (bookmarks->pending_updates, item); |
1355 | + |
1356 | + if (found) |
1357 | + return; |
1358 | + |
1359 | + midori_bookmarks_db_idle_start (bookmarks); |
1360 | + |
1361 | + g_object_ref (item); |
1362 | + g_hash_table_insert (bookmarks->pending_updates, item, item); |
1363 | +} |
1364 | + |
1365 | +/** |
1366 | + * midori_bookmarks_db_remove_item: |
1367 | + * @bookmarks: the main bookmark array |
1368 | + * @item: #KatzeItem the item to remove |
1369 | + * |
1370 | + * Removes the @item from the bookmark data base. |
1371 | + * |
1372 | + * Since: 0.5.2 |
1373 | + **/ |
1374 | +void |
1375 | +midori_bookmarks_db_remove_item (MidoriBookmarksDb* bookmarks, KatzeItem* item) |
1376 | +{ |
1377 | + g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (bookmarks)); |
1378 | + g_return_if_fail (KATZE_IS_ITEM (item)); |
1379 | + g_return_if_fail (katze_item_get_meta_string (item, "id")); |
1380 | + g_return_if_fail (0 != katze_item_get_meta_integer (item, "id")); |
1381 | + |
1382 | + gpointer found = g_hash_table_lookup (bookmarks->pending_deletes, item); |
1383 | + |
1384 | + if (found) |
1385 | + return; |
1386 | + |
1387 | + midori_bookmarks_db_idle_start (bookmarks); |
1388 | + |
1389 | + midori_bookmarks_db_remove_item_recursive (item, bookmarks); |
1390 | + |
1391 | + g_object_ref (item); |
1392 | + g_hash_table_insert (bookmarks->pending_deletes, item, item); |
1393 | } |
1394 | |
1395 | #define _APPEND_TO_SQL_ERRORMSG(custom_errmsg) \ |
1396 | @@ -74,8 +850,8 @@ |
1397 | g_string_append (errmsg_str, custom_errmsg); \ |
1398 | } while (0) |
1399 | |
1400 | -gboolean |
1401 | -midori_bookmarks_import_from_old_db (sqlite3* db, |
1402 | +static gboolean |
1403 | +midori_bookmarks_db_import_from_old_db (sqlite3* db, |
1404 | const gchar* oldfile, |
1405 | gchar** errmsg) |
1406 | { |
1407 | @@ -130,8 +906,24 @@ |
1408 | } |
1409 | #undef _APPEND_TO_SQL_ERRORMSG |
1410 | |
1411 | -KatzeArray* |
1412 | -midori_bookmarks_new (char** errmsg) |
1413 | +static void |
1414 | +midori_bookmarks_db_dbtracer (void* dummy, |
1415 | + const char* query) |
1416 | +{ |
1417 | + g_printerr ("%s\n", query); |
1418 | +} |
1419 | + |
1420 | +/** |
1421 | + * midori_bookmarks_db_new: |
1422 | + * |
1423 | + * Initializes the bookmark data base. |
1424 | + * |
1425 | + * Returns: the main bookmarks array |
1426 | + * |
1427 | + * Since: 0.5.2 |
1428 | + **/ |
1429 | +MidoriBookmarksDb* |
1430 | +midori_bookmarks_db_new (char** errmsg) |
1431 | { |
1432 | sqlite3* db; |
1433 | gchar* oldfile; |
1434 | @@ -141,6 +933,7 @@ |
1435 | gchar* sql_errmsg = NULL; |
1436 | gchar* import_errmsg = NULL; |
1437 | KatzeArray* array; |
1438 | + MidoriBookmarksDb* bookmarks; |
1439 | |
1440 | g_return_val_if_fail (errmsg != NULL, NULL); |
1441 | |
1442 | @@ -158,7 +951,7 @@ |
1443 | } |
1444 | |
1445 | if (midori_debug ("bookmarks")) |
1446 | - sqlite3_trace (db, midori_bookmarks_dbtracer, NULL); |
1447 | + sqlite3_trace (db, midori_bookmarks_db_dbtracer, NULL); |
1448 | |
1449 | create_stmt = /* Table structure */ |
1450 | "CREATE TABLE IF NOT EXISTS bookmarks " |
1451 | @@ -269,7 +1062,7 @@ |
1452 | |
1453 | if (oldfile_exists) |
1454 | /* import from old db */ |
1455 | - if (!midori_bookmarks_import_from_old_db (db, oldfile, &import_errmsg)) |
1456 | + if (!midori_bookmarks_db_import_from_old_db (db, oldfile, &import_errmsg)) |
1457 | { |
1458 | *errmsg = g_strdup_printf (_("Couldn't import from old database: %s\n"), |
1459 | import_errmsg ? import_errmsg : "(err = NULL)"); |
1460 | @@ -279,13 +1072,11 @@ |
1461 | init_success: |
1462 | g_free (newfile); |
1463 | g_free (oldfile); |
1464 | - array = katze_array_new (KATZE_TYPE_ARRAY); |
1465 | - g_signal_connect (array, "add-item", |
1466 | - G_CALLBACK (midori_bookmarks_add_item_cb), db); |
1467 | - g_signal_connect (array, "remove-item", |
1468 | - G_CALLBACK (midori_bookmarks_remove_item_cb), db); |
1469 | - g_object_set_data (G_OBJECT (array), "db", db); |
1470 | - return array; |
1471 | + bookmarks = MIDORI_BOOKMARKS_DB (g_object_new (TYPE_MIDORI_BOOKMARKS_DB, NULL)); |
1472 | + bookmarks->db = db; |
1473 | + |
1474 | + g_object_set_data (G_OBJECT (bookmarks), "db", db); |
1475 | + return bookmarks; |
1476 | |
1477 | init_failed: |
1478 | g_free (newfile); |
1479 | @@ -297,31 +1088,384 @@ |
1480 | return NULL; |
1481 | } |
1482 | |
1483 | +/** |
1484 | + * midori_bookmarks_db_on_quit: |
1485 | + * @bookmarks: the main bookmark array |
1486 | + * |
1487 | + * Delete the main bookmark array. |
1488 | + * |
1489 | + * Since: 0.5.2 |
1490 | + **/ |
1491 | void |
1492 | -midori_bookmarks_import (const gchar* filename, |
1493 | - sqlite3* db) |
1494 | +midori_bookmarks_db_on_quit (MidoriBookmarksDb* bookmarks) |
1495 | { |
1496 | - KatzeArray* bookmarks; |
1497 | - GError* error = NULL; |
1498 | - |
1499 | - bookmarks = katze_array_new (KATZE_TYPE_ARRAY); |
1500 | - |
1501 | - if (!midori_array_from_file (bookmarks, filename, "xbel", &error)) |
1502 | - { |
1503 | - g_warning (_("The bookmarks couldn't be saved. %s"), error->message); |
1504 | - g_error_free (error); |
1505 | - return; |
1506 | - } |
1507 | - midori_bookmarks_import_array_db (db, bookmarks, 0); |
1508 | + g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (bookmarks)); |
1509 | + |
1510 | + g_object_unref (bookmarks); |
1511 | } |
1512 | |
1513 | +/** |
1514 | + * midori_bookmarks_db_import_array: |
1515 | + * @array: the main bookmark array |
1516 | + * @array: #KatzeArray containing the items to import |
1517 | + * @parentid: the id of folder |
1518 | + * |
1519 | + * Imports the items of @array as childs of the folder |
1520 | + * identfied by @parentid. |
1521 | + * |
1522 | + * Since: 0.5.2 |
1523 | + **/ |
1524 | void |
1525 | -midori_bookmarks_on_quit (KatzeArray* array) |
1526 | +midori_bookmarks_db_import_array (MidoriBookmarksDb* bookmarks, |
1527 | + KatzeArray* array, |
1528 | + gint64 parentid) |
1529 | { |
1530 | + GList* list; |
1531 | + KatzeItem* item; |
1532 | + |
1533 | + g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (bookmarks)); |
1534 | g_return_if_fail (KATZE_IS_ARRAY (array)); |
1535 | |
1536 | - sqlite3* db = g_object_get_data (G_OBJECT (array), "db"); |
1537 | - g_return_if_fail (db != NULL); |
1538 | - sqlite3_close (db); |
1539 | -} |
1540 | - |
1541 | + KATZE_ARRAY_FOREACH_ITEM_L (item, array, list) |
1542 | + { |
1543 | + katze_item_set_meta_integer (item, "parentid", parentid); |
1544 | + midori_bookmarks_db_add_item (bookmarks, item); |
1545 | + } |
1546 | + |
1547 | + g_list_free (list); |
1548 | +} |
1549 | + |
1550 | +/** |
1551 | + * midori_bookmarks_db_force_idle: |
1552 | + * @array: the main bookmark array |
1553 | + * |
1554 | + * Internal function that checks if idle processing is pending. |
1555 | + * If it is the case, removes it from idle time processing and |
1556 | + * executes it immediately. |
1557 | + **/ |
1558 | +static void |
1559 | +midori_bookmarks_db_force_idle (MidoriBookmarksDb* bookmarks) |
1560 | +{ |
1561 | + if (g_idle_remove_by_data (bookmarks)) |
1562 | + midori_bookmarks_db_idle_func (bookmarks); |
1563 | +} |
1564 | + |
1565 | +/** |
1566 | + * midori_bookmarks_db_array_from_statement: |
1567 | + * @stmt: the sqlite returned statement |
1568 | + * @bookmarks: the database controller |
1569 | + * |
1570 | + * Internal function that populate a #KatzeArray by processing the @stmt |
1571 | + * rows identifying: |
1572 | + * a- if the item is already in memory |
1573 | + * in this case the item data is updated with retreived database content |
1574 | + * and the already existing item is populated in the returned #KatzeArray |
1575 | + * b- if the data is a folder |
1576 | + * a new #KatzeArray item is populated in the returned #KatzeArray and |
1577 | + * memorized for furure use. |
1578 | + * c- if the data is a bookmark |
1579 | + * a new #KatzeItem item is populated in the returned #KatzeArray and |
1580 | + * memorized for furure use. |
1581 | + * |
1582 | + * Return value: the populated #KatzeArray |
1583 | + **/ |
1584 | +static KatzeArray* |
1585 | +midori_bookmarks_db_array_from_statement (sqlite3_stmt* stmt, |
1586 | + MidoriBookmarksDb* bookmarks) |
1587 | +{ |
1588 | + KatzeArray *array; |
1589 | + gint result; |
1590 | + gint cols; |
1591 | + |
1592 | + array = katze_array_new (KATZE_TYPE_ITEM); |
1593 | + cols = sqlite3_column_count (stmt); |
1594 | + |
1595 | + while ((result = sqlite3_step (stmt)) == SQLITE_ROW) |
1596 | + { |
1597 | + gint i; |
1598 | + KatzeItem* item; |
1599 | + KatzeItem* found; |
1600 | + |
1601 | + item = katze_item_new (); |
1602 | + for (i = 0; i < cols; i++) |
1603 | + katze_item_set_value_from_column (stmt, i, item); |
1604 | + |
1605 | + if (NULL != (found = g_hash_table_lookup (bookmarks->all_items, item))) |
1606 | + { |
1607 | + for (i = 0; i < cols; i++) |
1608 | + katze_item_set_value_from_column (stmt, i, found); |
1609 | + |
1610 | + g_object_unref (item); |
1611 | + |
1612 | + item = found; |
1613 | + } |
1614 | + else if (KATZE_ITEM_IS_FOLDER (item)) |
1615 | + { |
1616 | + item = KATZE_ITEM (katze_array_new (KATZE_TYPE_ITEM)); |
1617 | + |
1618 | + for (i = 0; i < cols; i++) |
1619 | + katze_item_set_value_from_column (stmt, i, item); |
1620 | + |
1621 | + g_object_ref (item); |
1622 | + g_hash_table_insert (bookmarks->all_items, item, item); |
1623 | + } |
1624 | + else |
1625 | + { |
1626 | + g_object_ref (item); |
1627 | + g_hash_table_insert (bookmarks->all_items, item, item); |
1628 | + } |
1629 | + |
1630 | + katze_array_add_item (array, item); |
1631 | + } |
1632 | + |
1633 | + sqlite3_clear_bindings (stmt); |
1634 | + sqlite3_reset (stmt); |
1635 | + return array; |
1636 | +} |
1637 | + |
1638 | +/** |
1639 | + * midori_bookmarks_db_array_from_sqlite: |
1640 | + * @array: the main bookmark array |
1641 | + * @sqlcmd: the sqlcmd to execute |
1642 | + * |
1643 | + * Internal function that first forces pending idle processing to update the |
1644 | + * database then process the requested @sqlcmd. |
1645 | + * |
1646 | + * Return value: a #KatzeArray on success, %NULL otherwise |
1647 | + **/ |
1648 | +static KatzeArray* |
1649 | +midori_bookmarks_db_array_from_sqlite (MidoriBookmarksDb* bookmarks, |
1650 | + const gchar* sqlcmd) |
1651 | +{ |
1652 | + sqlite3_stmt* stmt; |
1653 | + gint result; |
1654 | + |
1655 | + g_return_val_if_fail (bookmarks->db != NULL, NULL); |
1656 | + |
1657 | + midori_bookmarks_db_force_idle (bookmarks); |
1658 | + |
1659 | + result = sqlite3_prepare_v2 (bookmarks->db, sqlcmd, -1, &stmt, NULL); |
1660 | + if (result != SQLITE_OK) |
1661 | + return NULL; |
1662 | + |
1663 | + return midori_bookmarks_db_array_from_statement (stmt, bookmarks); |
1664 | +} |
1665 | + |
1666 | +/** |
1667 | + * midori_bookmarks_db_query_recursive: |
1668 | + * @array: the main bookmark array |
1669 | + * @fields: comma separated list of fields |
1670 | + * @condition: condition, like "folder = '%q'" |
1671 | + * @value: a value to be inserted if @condition contains %q |
1672 | + * @recursive: if %TRUE include children |
1673 | + * |
1674 | + * Stores the result in a #KatzeArray. |
1675 | + * |
1676 | + * Return value: a #KatzeArray on success, %NULL otherwise |
1677 | + * |
1678 | + * Since: 0.5.2 |
1679 | + **/ |
1680 | +KatzeArray* |
1681 | +midori_bookmarks_db_query_recursive (MidoriBookmarksDb* bookmarks, |
1682 | + const gchar* fields, |
1683 | + const gchar* condition, |
1684 | + const gchar* value, |
1685 | + gboolean recursive) |
1686 | +{ |
1687 | + gchar* sqlcmd; |
1688 | + char* sqlcmd_value; |
1689 | + KatzeArray* array; |
1690 | + KatzeItem* item; |
1691 | + GList* list; |
1692 | + |
1693 | + g_return_val_if_fail (IS_MIDORI_BOOKMARKS_DB (bookmarks), NULL); |
1694 | + g_return_val_if_fail (fields, NULL); |
1695 | + g_return_val_if_fail (condition, NULL); |
1696 | + |
1697 | + sqlcmd = g_strdup_printf ("SELECT %s FROM bookmarks WHERE %s " |
1698 | + "ORDER BY (uri='') ASC, title DESC", fields, condition); |
1699 | + if (strstr (condition, "%q")) |
1700 | + { |
1701 | + sqlcmd_value = sqlite3_mprintf (sqlcmd, value ? value : ""); |
1702 | + array = midori_bookmarks_db_array_from_sqlite (bookmarks, sqlcmd_value); |
1703 | + sqlite3_free (sqlcmd_value); |
1704 | + } |
1705 | + else |
1706 | + array = midori_bookmarks_db_array_from_sqlite (bookmarks, sqlcmd); |
1707 | + g_free (sqlcmd); |
1708 | + |
1709 | + if (!recursive) |
1710 | + return array; |
1711 | + |
1712 | + KATZE_ARRAY_FOREACH_ITEM_L (item, array, list) |
1713 | + { |
1714 | + if (KATZE_ITEM_IS_FOLDER (item)) |
1715 | + { |
1716 | + gchar* parentid = g_strdup_printf ("%" G_GINT64_FORMAT, |
1717 | + katze_item_get_meta_integer (item, "id")); |
1718 | + KatzeArray* subarray = midori_bookmarks_db_query_recursive (bookmarks, |
1719 | + fields, "parentid=%q", parentid, TRUE); |
1720 | + KatzeItem* subitem; |
1721 | + GList* sublist; |
1722 | + |
1723 | + KATZE_ARRAY_FOREACH_ITEM_L (subitem, subarray, sublist) |
1724 | + { |
1725 | + katze_array_add_item (KATZE_ARRAY (item), subitem); |
1726 | + } |
1727 | + |
1728 | + g_object_unref (subarray); |
1729 | + g_free (parentid); |
1730 | + } |
1731 | + } |
1732 | + g_list_free (list); |
1733 | + return array; |
1734 | +} |
1735 | + |
1736 | +static gint64 |
1737 | +midori_bookmarks_db_count_from_sqlite (sqlite3* db, |
1738 | + const gchar* sqlcmd) |
1739 | +{ |
1740 | + gint64 count = -1; |
1741 | + sqlite3_stmt* stmt; |
1742 | + gint result; |
1743 | + |
1744 | + result = sqlite3_prepare_v2 (db, sqlcmd, -1, &stmt, NULL); |
1745 | + if (result != SQLITE_OK) |
1746 | + return -1; |
1747 | + |
1748 | + g_assert (sqlite3_column_count (stmt) == 1); |
1749 | + |
1750 | + if ((result = sqlite3_step (stmt)) == SQLITE_ROW) |
1751 | + count = sqlite3_column_int64(stmt, 0); |
1752 | + |
1753 | + sqlite3_clear_bindings (stmt); |
1754 | + sqlite3_reset (stmt); |
1755 | + |
1756 | + return count; |
1757 | +} |
1758 | + |
1759 | +static gint64 |
1760 | +midori_bookmarks_db_count_recursive_by_id (MidoriBookmarksDb* bookmarks, |
1761 | + const gchar* condition, |
1762 | + const gchar* value, |
1763 | + gint64 id, |
1764 | + gboolean recursive) |
1765 | +{ |
1766 | + gint64 count = -1; |
1767 | + gchar* sqlcmd; |
1768 | + char* sqlcmd_value; |
1769 | + sqlite3_stmt* stmt; |
1770 | + gint result; |
1771 | + GList* ids; |
1772 | + GList* iter_ids; |
1773 | + |
1774 | + g_return_val_if_fail (condition, -1); |
1775 | + g_return_val_if_fail (MIDORI_BOOKMARKS_DB (bookmarks), -1); |
1776 | + g_return_val_if_fail (bookmarks->db != NULL, -1); |
1777 | + |
1778 | + g_assert(!strstr("parentid", condition)); |
1779 | + |
1780 | + if (id > 0) |
1781 | + sqlcmd = g_strdup_printf ("SELECT COUNT(*) FROM bookmarks " |
1782 | + "WHERE parentid = %" G_GINT64_FORMAT " AND %s", |
1783 | + id, |
1784 | + condition); |
1785 | + else |
1786 | + sqlcmd = g_strdup_printf ("SELECT COUNT(*) FROM bookmarks " |
1787 | + "WHERE parentid IS NULL AND %s ", |
1788 | + condition); |
1789 | + |
1790 | + if (strstr (condition, "%q")) |
1791 | + { |
1792 | + sqlcmd_value = sqlite3_mprintf (sqlcmd, value ? value : ""); |
1793 | + count = midori_bookmarks_db_count_from_sqlite (bookmarks->db, sqlcmd_value); |
1794 | + sqlite3_free (sqlcmd_value); |
1795 | + } |
1796 | + else |
1797 | + count = midori_bookmarks_db_count_from_sqlite (bookmarks->db, sqlcmd); |
1798 | + |
1799 | + g_free (sqlcmd); |
1800 | + |
1801 | + if (!recursive || (count < 0)) |
1802 | + return count; |
1803 | + |
1804 | + ids = NULL; |
1805 | + |
1806 | + if (id > 0) |
1807 | + sqlcmd_value = sqlite3_mprintf ( |
1808 | + "SELECT id FROM bookmarks " |
1809 | + "WHERE parentid = %" G_GINT64_FORMAT " AND uri = ''", id); |
1810 | + else |
1811 | + sqlcmd_value = sqlite3_mprintf ( |
1812 | + "SELECT id FROM bookmarks " |
1813 | + "WHERE parentid IS NULL AND uri = ''"); |
1814 | + |
1815 | + if (sqlite3_prepare_v2 (bookmarks->db, sqlcmd_value, -1, &stmt, NULL) == SQLITE_OK) |
1816 | + { |
1817 | + g_assert (sqlite3_column_count (stmt) == 1); |
1818 | + |
1819 | + if ((result = sqlite3_step (stmt)) == SQLITE_ROW) |
1820 | + { |
1821 | + gint64* pid = g_new (gint64, 1); |
1822 | + |
1823 | + *pid = sqlite3_column_int64(stmt, 0); |
1824 | + ids = g_list_append (ids, pid); |
1825 | + } |
1826 | + |
1827 | + sqlite3_clear_bindings (stmt); |
1828 | + sqlite3_reset (stmt); |
1829 | + } |
1830 | + |
1831 | + sqlite3_free (sqlcmd_value); |
1832 | + |
1833 | + iter_ids = ids; |
1834 | + while (iter_ids) |
1835 | + { |
1836 | + gint64 sub_count = midori_bookmarks_db_count_recursive_by_id (bookmarks, |
1837 | + condition, |
1838 | + value, |
1839 | + *(gint64*)(iter_ids->data), |
1840 | + recursive); |
1841 | + |
1842 | + if (sub_count < 0) |
1843 | + { |
1844 | + g_list_free_full (ids, g_free); |
1845 | + return -1; |
1846 | + } |
1847 | + |
1848 | + count += sub_count; |
1849 | + iter_ids = g_list_next (iter_ids); |
1850 | + } |
1851 | + |
1852 | + g_list_free_full (ids, g_free); |
1853 | + return count; |
1854 | +} |
1855 | + |
1856 | +/** |
1857 | + * midori_bookmarks_db_count_recursive: |
1858 | + * @bookmarks: the main bookmark array |
1859 | + * @condition: condition, like "folder = '%q'" |
1860 | + * @value: a value to be inserted if @condition contains %q |
1861 | + * @recursive: if %TRUE include children |
1862 | + * |
1863 | + * Return value: the number of elements on success, -1 otherwise |
1864 | + * |
1865 | + * Since: 0.5.2 |
1866 | + **/ |
1867 | +gint64 |
1868 | +midori_bookmarks_db_count_recursive (MidoriBookmarksDb* bookmarks, |
1869 | + const gchar* condition, |
1870 | + const gchar* value, |
1871 | + KatzeItem* folder, |
1872 | + gboolean recursive) |
1873 | +{ |
1874 | + gint64 id = -1; |
1875 | + |
1876 | + g_return_val_if_fail (!folder || KATZE_ITEM_IS_FOLDER (folder), -1); |
1877 | + |
1878 | + id = folder ? katze_item_get_meta_integer (folder, "id") : 0; |
1879 | + |
1880 | + return midori_bookmarks_db_count_recursive_by_id (bookmarks, condition, |
1881 | + value, id, |
1882 | + recursive); |
1883 | +} |
1884 | |
1885 | === renamed file 'midori/midori-bookmarks.h' => 'midori/midori-bookmarks-db.h' |
1886 | --- midori/midori-bookmarks.h 2012-11-25 15:37:41 +0000 |
1887 | +++ midori/midori-bookmarks-db.h 2013-06-11 20:53:24 +0000 |
1888 | @@ -10,31 +10,70 @@ |
1889 | See the file COPYING for the full license text. |
1890 | */ |
1891 | |
1892 | -#ifndef __MIDORI_BOOKMARKS_H__ |
1893 | -#define __MIDORI_BOOKMARKS_H__ 1 |
1894 | +#ifndef __MIDORI_BOOKMARKS_DB_H__ |
1895 | +#define __MIDORI_BOOKMARKS_DB_H__ 1 |
1896 | |
1897 | #include <sqlite3.h> |
1898 | #include <katze/katze.h> |
1899 | |
1900 | -void |
1901 | -midori_bookmarks_add_item_cb (KatzeArray* array, |
1902 | - KatzeItem* item, |
1903 | - sqlite3* db); |
1904 | - |
1905 | -void |
1906 | -midori_bookmarks_remove_item_cb (KatzeArray* array, |
1907 | - KatzeItem* item, |
1908 | - sqlite3* db); |
1909 | +G_BEGIN_DECLS |
1910 | + |
1911 | +#define TYPE_MIDORI_BOOKMARKS_DB \ |
1912 | + (midori_bookmarks_db_get_type ()) |
1913 | +#define MIDORI_BOOKMARKS_DB(obj) \ |
1914 | + (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_MIDORI_BOOKMARKS_DB, MidoriBookmarksDb)) |
1915 | +#define MIDORI_BOOKMARKS_DB_CLASS(klass) \ |
1916 | + (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_MIDORI_BOOKMARKS_DB, MidoriBookmarksDbClass)) |
1917 | +#define IS_MIDORI_BOOKMARKS_DB(obj) \ |
1918 | + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_MIDORI_BOOKMARKS_DB)) |
1919 | +#define IS_MIDORI_BOOKMARKS_DB_CLASS(klass) \ |
1920 | + (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_MIDORI_BOOKMARKS_DB)) |
1921 | +#define MIDORI_BOOKMARKS_DB_GET_CLASS(obj) \ |
1922 | + (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_MIDORI_BOOKMARKS_DB, MidoriBookmarksDbClass)) |
1923 | + |
1924 | +typedef struct _MidoriBookmarksDb MidoriBookmarksDb; |
1925 | +typedef struct _MidoriBookmarksDbClass MidoriBookmarksDbClass; |
1926 | + |
1927 | +GType |
1928 | +midori_bookmarks_db_get_type (void) G_GNUC_CONST; |
1929 | + |
1930 | +MidoriBookmarksDb* |
1931 | +midori_bookmarks_db_new (char** errmsg); |
1932 | + |
1933 | +void |
1934 | +midori_bookmarks_db_on_quit (MidoriBookmarksDb* array); |
1935 | + |
1936 | +void |
1937 | +midori_bookmarks_db_add_item (MidoriBookmarksDb* bookmarks, KatzeItem* item); |
1938 | + |
1939 | +void |
1940 | +midori_bookmarks_db_update_item (MidoriBookmarksDb* bookmarks, KatzeItem* item); |
1941 | + |
1942 | +void |
1943 | +midori_bookmarks_db_remove_item (MidoriBookmarksDb* bookmarks, KatzeItem* item); |
1944 | + |
1945 | +void |
1946 | +midori_bookmarks_db_import_array (MidoriBookmarksDb* bookmarks, |
1947 | + KatzeArray* array, |
1948 | + gint64 parentid); |
1949 | |
1950 | KatzeArray* |
1951 | -midori_bookmarks_new (char** errmsg); |
1952 | - |
1953 | -void |
1954 | -midori_bookmarks_on_quit (KatzeArray* array); |
1955 | - |
1956 | -void |
1957 | -midori_bookmarks_import (const gchar* filename, |
1958 | - sqlite3* db); |
1959 | - |
1960 | -#endif /* !__MIDORI_BOOKMARKS_H__ */ |
1961 | +midori_bookmarks_db_query_recursive (MidoriBookmarksDb* bookmarks, |
1962 | + const gchar* fields, |
1963 | + const gchar* condition, |
1964 | + const gchar* value, |
1965 | + gboolean recursive); |
1966 | + |
1967 | +gint64 |
1968 | +midori_bookmarks_db_count_recursive (MidoriBookmarksDb* bookmarks, |
1969 | + const gchar* condition, |
1970 | + const gchar* value, |
1971 | + KatzeItem* folder, |
1972 | + gboolean recursive); |
1973 | + |
1974 | +void |
1975 | +midori_bookmarks_db_on_quit (MidoriBookmarksDb* array); |
1976 | + |
1977 | + |
1978 | +#endif /* !__MIDORI_BOOKMARKS_DB_H__ */ |
1979 | |
1980 | |
1981 | === modified file 'midori/midori-browser.c' |
1982 | --- midori/midori-browser.c 2013-06-02 13:30:16 +0000 |
1983 | +++ midori/midori-browser.c 2013-06-11 20:53:24 +0000 |
1984 | @@ -26,6 +26,7 @@ |
1985 | #include "midori-privatedata.h" |
1986 | #include "midori-core.h" |
1987 | #include "midori-privatedata.h" |
1988 | +#include "midori-bookmarks-db.h" |
1989 | |
1990 | #include "marshal.h" |
1991 | |
1992 | @@ -85,7 +86,7 @@ |
1993 | |
1994 | MidoriWebSettings* settings; |
1995 | KatzeArray* proxy_array; |
1996 | - KatzeArray* bookmarks; |
1997 | + MidoriBookmarksDb* bookmarks; |
1998 | KatzeArray* trash; |
1999 | KatzeArray* search_engines; |
2000 | KatzeArray* history; |
2001 | @@ -96,6 +97,8 @@ |
2002 | gboolean show_statusbar; |
2003 | guint maximum_history_age; |
2004 | guint last_web_search; |
2005 | + |
2006 | + gboolean bookmarkbar_populate; |
2007 | }; |
2008 | |
2009 | G_DEFINE_TYPE (MidoriBrowser, midori_browser, GTK_TYPE_WINDOW) |
2010 | @@ -162,20 +165,13 @@ |
2011 | GParamSpec* pspec); |
2012 | |
2013 | void |
2014 | -midori_bookmarks_import_array_db (sqlite3* db, |
2015 | - KatzeArray* array, |
2016 | - gint64 parentid); |
2017 | - |
2018 | -gboolean |
2019 | -midori_bookmarks_update_item_db (sqlite3* db, |
2020 | - KatzeItem* item); |
2021 | - |
2022 | -void |
2023 | midori_browser_open_bookmark (MidoriBrowser* browser, |
2024 | KatzeItem* item); |
2025 | |
2026 | static void |
2027 | midori_bookmarkbar_populate (MidoriBrowser* browser); |
2028 | +static void |
2029 | +midori_bookmarkbar_populate_idle (MidoriBrowser* browser); |
2030 | |
2031 | static void |
2032 | midori_bookmarkbar_clear (GtkWidget* toolbar); |
2033 | @@ -203,8 +199,8 @@ |
2034 | GtkToolbarStyle style); |
2035 | |
2036 | static void |
2037 | -midori_browser_set_bookmarks (MidoriBrowser* browser, |
2038 | - KatzeArray* bookmarks); |
2039 | +midori_browser_set_bookmarks (MidoriBrowser* browser, |
2040 | + MidoriBookmarksDb* bookmarks); |
2041 | |
2042 | static void |
2043 | midori_browser_add_speed_dial (MidoriBrowser* browser); |
2044 | @@ -484,6 +480,9 @@ |
2045 | inter = ZEITGEIST_ZG_DELETE_EVENT; |
2046 | else |
2047 | g_assert_not_reached (); |
2048 | + g_assert (KATZE_IS_ITEM (item)); |
2049 | + if (KATZE_ITEM_IS_FOLDER (item)) |
2050 | + return; |
2051 | zeitgeist_log_insert_events_no_reply (zeitgeist_log_get_default (), |
2052 | zeitgeist_event_new_full (inter, ZEITGEIST_ZG_USER_ACTIVITY, |
2053 | "application://midori.desktop", |
2054 | @@ -817,7 +816,7 @@ |
2055 | } |
2056 | |
2057 | static GtkWidget* |
2058 | -midori_bookmark_folder_button_new (KatzeArray* array, |
2059 | +midori_bookmark_folder_button_new (MidoriBookmarksDb* array, |
2060 | gboolean new_bookmark, |
2061 | gint64 selected, |
2062 | gint64 parentid) |
2063 | @@ -1059,18 +1058,13 @@ |
2064 | katze_item_set_meta_integer (bookmark, "parentid", selected); |
2065 | |
2066 | if (new_bookmark) |
2067 | - katze_array_add_item (browser->bookmarks, bookmark); |
2068 | + midori_bookmarks_db_add_item (browser->bookmarks, bookmark); |
2069 | else |
2070 | - midori_bookmarks_update_item_db (db, bookmark); |
2071 | - midori_browser_update_history (bookmark, "bookmark", new_bookmark ? "create" : "modify"); |
2072 | + midori_bookmarks_db_update_item (browser->bookmarks, bookmark); |
2073 | |
2074 | - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check_toolbar))) |
2075 | - if (!gtk_widget_get_visible (browser->bookmarkbar)) |
2076 | - _action_set_active (browser, "Bookmarkbar", TRUE); |
2077 | return_status = TRUE; |
2078 | } |
2079 | - if (gtk_widget_get_visible (browser->bookmarkbar)) |
2080 | - midori_bookmarkbar_populate (browser); |
2081 | + |
2082 | gtk_widget_destroy (dialog); |
2083 | return return_status; |
2084 | } |
2085 | @@ -2321,7 +2315,7 @@ |
2086 | "bookmarks", |
2087 | "Bookmarks", |
2088 | "The bookmarks folder, containing all bookmarks", |
2089 | - KATZE_TYPE_ARRAY, |
2090 | + TYPE_MIDORI_BOOKMARKS_DB, |
2091 | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
2092 | |
2093 | /** |
2094 | @@ -3096,8 +3090,8 @@ |
2095 | else |
2096 | condition = "parentid = %q"; |
2097 | |
2098 | - bookmarks = midori_array_query (browser->bookmarks, |
2099 | - "id, title, parentid, uri, app, pos_panel, pos_bar", condition, id); |
2100 | + bookmarks = midori_bookmarks_db_query_recursive (browser->bookmarks, |
2101 | + "id, title, parentid, uri, app, pos_panel, pos_bar", condition, id, FALSE); |
2102 | if (!bookmarks) |
2103 | return FALSE; |
2104 | |
2105 | @@ -4227,7 +4221,7 @@ |
2106 | KatzeItem* item; |
2107 | |
2108 | item = (KatzeItem*)g_object_get_data (G_OBJECT (menuitem), "KatzeItem"); |
2109 | - katze_array_remove_item (browser->bookmarks, item); |
2110 | + midori_bookmarks_db_remove_item (browser->bookmarks, item); |
2111 | } |
2112 | |
2113 | static void |
2114 | @@ -4242,7 +4236,7 @@ |
2115 | menu = gtk_menu_new (); |
2116 | if (KATZE_ITEM_IS_FOLDER (item)) |
2117 | { |
2118 | - gint child_bookmarks_count = midori_array_count_recursive (browser->bookmarks, |
2119 | + gint child_bookmarks_count = midori_bookmarks_db_count_recursive (browser->bookmarks, |
2120 | "uri <> ''", NULL, item, FALSE); |
2121 | |
2122 | midori_browser_bookmark_popup_item (menu, |
2123 | @@ -4497,8 +4491,7 @@ |
2124 | if (error) |
2125 | g_error_free (error); |
2126 | } |
2127 | - midori_bookmarks_import_array_db (db, bookmarks, selected); |
2128 | - katze_array_update (browser->bookmarks); |
2129 | + midori_bookmarks_db_import_array (browser->bookmarks, bookmarks, selected); |
2130 | g_object_unref (bookmarks); |
2131 | g_free (path); |
2132 | } |
2133 | @@ -4552,7 +4545,7 @@ |
2134 | return; |
2135 | |
2136 | error = NULL; |
2137 | - bookmarks = midori_array_query_recursive (browser->bookmarks, |
2138 | + bookmarks = midori_bookmarks_db_query_recursive (browser->bookmarks, |
2139 | "*", "parentid IS NULL", NULL, TRUE); |
2140 | if (!midori_array_to_file (bookmarks, path, format, &error)) |
2141 | { |
2142 | @@ -5979,6 +5972,21 @@ |
2143 | } |
2144 | } |
2145 | |
2146 | +static gboolean |
2147 | +midori_browser_idle (gpointer data) |
2148 | +{ |
2149 | + MidoriBrowser* browser = MIDORI_BROWSER (data); |
2150 | + |
2151 | + if (browser->bookmarkbar_populate) |
2152 | + { |
2153 | + midori_bookmarkbar_populate_idle (browser); |
2154 | + |
2155 | + browser->bookmarkbar_populate = FALSE; |
2156 | + } |
2157 | + |
2158 | + return FALSE; |
2159 | +} |
2160 | + |
2161 | static void |
2162 | midori_browser_init (MidoriBrowser* browser) |
2163 | { |
2164 | @@ -6459,6 +6467,8 @@ |
2165 | katze_object_assign (browser->history, NULL); |
2166 | katze_object_assign (browser->dial, NULL); |
2167 | |
2168 | + g_idle_remove_by_data (browser); |
2169 | + |
2170 | G_OBJECT_CLASS (midori_browser_parent_class)->finalize (object); |
2171 | } |
2172 | |
2173 | @@ -6973,7 +6983,7 @@ |
2174 | KatzeItem* item) |
2175 | { |
2176 | MidoriBrowser* browser = midori_browser_get_for_widget (toolbar); |
2177 | - GtkAction* action = _action_by_name (browser, "Tools"); |
2178 | + GtkAction* action = _action_by_name (browser, "Bookmarks"); |
2179 | GtkToolItem* toolitem = katze_array_action_create_tool_item_for ( |
2180 | KATZE_ARRAY_ACTION (action), item); |
2181 | g_object_set_data (G_OBJECT (toolitem), "KatzeItem", item); |
2182 | @@ -6994,6 +7004,28 @@ |
2183 | } |
2184 | |
2185 | static void |
2186 | +midori_bookmarkbar_add_item_cb (KatzeArray* bookmarks, |
2187 | + KatzeItem* item, |
2188 | + MidoriBrowser* browser) |
2189 | +{ |
2190 | + if (gtk_widget_get_visible (browser->bookmarkbar)) |
2191 | + midori_bookmarkbar_populate (browser); |
2192 | + else if (katze_item_get_meta_boolean (item, "toolbar")) |
2193 | + _action_set_active (browser, "Bookmarkbar", TRUE); |
2194 | + midori_browser_update_history (item, "bookmark", "created"); |
2195 | +} |
2196 | + |
2197 | +static void |
2198 | +midori_bookmarkbar_update_item_cb (KatzeArray* bookmarks, |
2199 | + KatzeItem* item, |
2200 | + MidoriBrowser* browser) |
2201 | +{ |
2202 | + if (gtk_widget_get_visible (browser->bookmarkbar)) |
2203 | + midori_bookmarkbar_populate (browser); |
2204 | + midori_browser_update_history (item, "bookmark", "modify"); |
2205 | +} |
2206 | + |
2207 | +static void |
2208 | midori_bookmarkbar_remove_item_cb (KatzeArray* bookmarks, |
2209 | KatzeItem* item, |
2210 | MidoriBrowser* browser) |
2211 | @@ -7006,6 +7038,16 @@ |
2212 | static void |
2213 | midori_bookmarkbar_populate (MidoriBrowser* browser) |
2214 | { |
2215 | + if (browser->bookmarkbar_populate) |
2216 | + return; |
2217 | + |
2218 | + g_idle_add (midori_browser_idle, browser); |
2219 | + browser->bookmarkbar_populate = TRUE; |
2220 | +} |
2221 | + |
2222 | +static void |
2223 | +midori_bookmarkbar_populate_idle (MidoriBrowser* browser) |
2224 | +{ |
2225 | KatzeArray* array; |
2226 | KatzeItem* item; |
2227 | |
2228 | @@ -7015,8 +7057,8 @@ |
2229 | gtk_toolbar_insert (GTK_TOOLBAR (browser->bookmarkbar), |
2230 | gtk_separator_tool_item_new (), -1); |
2231 | |
2232 | - array = midori_array_query (browser->bookmarks, |
2233 | - "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "toolbar = 1", NULL); |
2234 | + array = midori_bookmarks_db_query_recursive (browser->bookmarks, |
2235 | + "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "toolbar = 1", NULL, FALSE); |
2236 | if (!array) |
2237 | { |
2238 | _action_set_sensitive (browser, "BookmarkAdd", FALSE); |
2239 | @@ -7026,21 +7068,7 @@ |
2240 | |
2241 | KATZE_ARRAY_FOREACH_ITEM (item, array) |
2242 | { |
2243 | - if (KATZE_ITEM_IS_BOOKMARK (item)) |
2244 | - midori_bookmarkbar_insert_item (browser->bookmarkbar, item); |
2245 | - else |
2246 | - { |
2247 | - gint64 id = katze_item_get_meta_integer (item, "id"); |
2248 | - gchar* parentid = g_strdup_printf ("%" G_GINT64_FORMAT, id); |
2249 | - KatzeArray* subfolder = midori_array_query (browser->bookmarks, |
2250 | - "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "parentid = %q AND uri != ''", |
2251 | - parentid); |
2252 | - |
2253 | - katze_item_set_name (KATZE_ITEM (subfolder), katze_item_get_name (item)); |
2254 | - katze_item_set_meta_integer (KATZE_ITEM (subfolder), "id", id); |
2255 | - midori_bookmarkbar_insert_item (browser->bookmarkbar, KATZE_ITEM (subfolder)); |
2256 | - g_free (parentid); |
2257 | - } |
2258 | + midori_bookmarkbar_insert_item (browser->bookmarkbar, item); |
2259 | } |
2260 | _action_set_sensitive (browser, "BookmarkAdd", TRUE); |
2261 | _action_set_sensitive (browser, "BookmarkFolderAdd", TRUE); |
2262 | @@ -7070,13 +7098,20 @@ |
2263 | |
2264 | static void |
2265 | midori_browser_set_bookmarks (MidoriBrowser* browser, |
2266 | - KatzeArray* bookmarks) |
2267 | + MidoriBookmarksDb* bookmarks) |
2268 | { |
2269 | MidoriWebSettings* settings; |
2270 | |
2271 | if (browser->bookmarks != NULL) |
2272 | + { |
2273 | + g_signal_handlers_disconnect_by_func (browser->bookmarks, |
2274 | + midori_bookmarkbar_add_item_cb, browser); |
2275 | + g_signal_handlers_disconnect_by_func (browser->bookmarks, |
2276 | + midori_bookmarkbar_update_item_cb, browser); |
2277 | g_signal_handlers_disconnect_by_func (browser->bookmarks, |
2278 | midori_bookmarkbar_remove_item_cb, browser); |
2279 | + } |
2280 | + |
2281 | settings = midori_browser_get_settings (browser); |
2282 | g_signal_handlers_disconnect_by_func (settings, |
2283 | midori_browser_show_bookmarkbar_notify_value_cb, browser); |
2284 | @@ -7105,6 +7140,10 @@ |
2285 | g_signal_connect (settings, "notify::show-bookmarkbar", |
2286 | G_CALLBACK (midori_browser_show_bookmarkbar_notify_value_cb), browser); |
2287 | g_object_notify (G_OBJECT (settings), "show-bookmarkbar"); |
2288 | + g_signal_connect_after (bookmarks, "add-item", |
2289 | + G_CALLBACK (midori_bookmarkbar_add_item_cb), browser); |
2290 | + g_signal_connect_after (bookmarks, "update-item", |
2291 | + G_CALLBACK (midori_bookmarkbar_update_item_cb), browser); |
2292 | g_signal_connect_after (bookmarks, "remove-item", |
2293 | G_CALLBACK (midori_bookmarkbar_remove_item_cb), browser); |
2294 | } |
2295 | |
2296 | === modified file 'midori/midori-frontend.c' |
2297 | --- midori/midori-frontend.c 2013-05-23 22:15:27 +0000 |
2298 | +++ midori/midori-frontend.c 2013-06-11 20:53:24 +0000 |
2299 | @@ -10,7 +10,7 @@ |
2300 | */ |
2301 | |
2302 | #include "midori-array.h" |
2303 | -#include "midori-bookmarks.h" |
2304 | +#include "midori-bookmarks-db.h" |
2305 | #include "midori-history.h" |
2306 | #include "midori-preferences.h" |
2307 | #include "midori-privatedata.h" |
2308 | @@ -487,9 +487,9 @@ |
2309 | } |
2310 | g_free (uri); |
2311 | |
2312 | - KatzeArray* bookmarks; |
2313 | + MidoriBookmarksDb* bookmarks; |
2314 | gchar* errmsg = NULL; |
2315 | - if (!(bookmarks = midori_bookmarks_new (&errmsg))) |
2316 | + if (!(bookmarks = midori_bookmarks_db_new (&errmsg))) |
2317 | { |
2318 | g_string_append_printf (error_messages, |
2319 | _("Bookmarks couldn't be loaded: %s\n"), errmsg); |
2320 | @@ -594,11 +594,11 @@ |
2321 | midori_normal_app_on_quit (MidoriApp* app) |
2322 | { |
2323 | MidoriWebSettings* settings = katze_object_get_object (app, "settings"); |
2324 | - KatzeArray* bookmarks = katze_object_get_object (app, "bookmarks"); |
2325 | + MidoriBookmarksDb* bookmarks = katze_object_get_object (app, "bookmarks"); |
2326 | KatzeArray* history = katze_object_get_object (app, "history"); |
2327 | |
2328 | g_object_notify (G_OBJECT (settings), "load-on-startup"); |
2329 | - midori_bookmarks_on_quit (bookmarks); |
2330 | + midori_bookmarks_db_on_quit (bookmarks); |
2331 | midori_history_on_quit (history, settings); |
2332 | midori_private_data_on_quit (settings); |
2333 | /* Removing KatzeHttpCookies makes it save outstanding changes */ |
2334 | |
2335 | === modified file 'midori/midori.h' |
2336 | --- midori/midori.h 2012-12-02 15:32:20 +0000 |
2337 | +++ midori/midori.h 2013-06-11 20:53:24 +0000 |
2338 | @@ -14,7 +14,7 @@ |
2339 | |
2340 | #include "midori-app.h" |
2341 | #include "midori-array.h" |
2342 | -#include "midori-bookmarks.h" |
2343 | +#include "midori-bookmarks-db.h" |
2344 | #include "midori-browser.h" |
2345 | #include "midori-extension.h" |
2346 | #include "midori-frontend.h" |
2347 | |
2348 | === modified file 'panels/midori-bookmarks.c' |
2349 | --- panels/midori-bookmarks.c 2013-06-04 17:28:05 +0000 |
2350 | +++ panels/midori-bookmarks.c 2013-06-11 20:53:24 +0000 |
2351 | @@ -17,6 +17,7 @@ |
2352 | #include "midori-platform.h" |
2353 | #include "midori-view.h" |
2354 | #include "midori-core.h" |
2355 | +#include "midori-bookmarks-db.h" |
2356 | |
2357 | #include <glib/gi18n.h> |
2358 | #include <string.h> |
2359 | @@ -25,6 +26,111 @@ |
2360 | |
2361 | #define COMPLETION_DELAY 200 |
2362 | |
2363 | +G_BEGIN_DECLS |
2364 | + |
2365 | +#define MIDORI_BOOKMARKS_TREE_STORE_TYPE \ |
2366 | + (midori_bookmarks_tree_store_get_type ()) |
2367 | +#define MIDORI_BOOKMARKS_TREE_STORE(obj) \ |
2368 | + (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_BOOKMARKS_TREE_STORE_TYPE, MidoriBookmarksTreeStore)) |
2369 | +#define MIDORI_BOOKMARKS_TREE_STORE_CLASS(klass) \ |
2370 | + (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_BOOKMARKS_TREE_STORE_TYPE, MidoriBookmarksTreeStoreClass)) |
2371 | + |
2372 | +static gboolean |
2373 | +midori_bookmarks_tree_store_row_drop_possible (GtkTreeDragDest *drag_dest, |
2374 | + GtkTreePath *dest_path, |
2375 | + GtkSelectionData *selection_data); |
2376 | + |
2377 | +typedef struct _MidoriBookmarksTreeStore MidoriBookmarksTreeStore; |
2378 | +typedef struct _MidoriBookmarksTreeStoreClass MidoriBookmarksTreeStoreClass; |
2379 | + |
2380 | +struct _MidoriBookmarksTreeStore |
2381 | +{ |
2382 | + GtkTreeStore parent_instance; |
2383 | +}; |
2384 | + |
2385 | +struct _MidoriBookmarksTreeStoreClass |
2386 | +{ |
2387 | + GtkTreeStoreClass parent_class; |
2388 | +}; |
2389 | + |
2390 | +static GtkTreeDragDestIface * |
2391 | +gtk_tree_store_gtk_tree_drag_dest_iface = NULL; |
2392 | + |
2393 | +static void |
2394 | +midori_bookmarks_tree_store_drag_dest_init (GtkTreeDragDestIface *iface) |
2395 | +{ |
2396 | + gtk_tree_store_gtk_tree_drag_dest_iface = g_type_interface_peek_parent (iface); |
2397 | + |
2398 | + iface->row_drop_possible = midori_bookmarks_tree_store_row_drop_possible; |
2399 | +} |
2400 | + |
2401 | +static void |
2402 | +midori_bookmarks_tree_store_init (MidoriBookmarksTreeStore* item) |
2403 | +{ |
2404 | +} |
2405 | + |
2406 | +static void |
2407 | +midori_bookmarks_tree_store_class_init (MidoriBookmarksTreeStoreClass *class) |
2408 | +{ |
2409 | +} |
2410 | + |
2411 | +G_DEFINE_TYPE_WITH_CODE (MidoriBookmarksTreeStore, |
2412 | + midori_bookmarks_tree_store, |
2413 | + GTK_TYPE_TREE_STORE, |
2414 | + G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_DEST, |
2415 | + midori_bookmarks_tree_store_drag_dest_init)); |
2416 | + |
2417 | + |
2418 | +GtkTreeStore* |
2419 | +midori_bookmarks_tree_store_new (gint n_columns, ...) |
2420 | +{ |
2421 | + GtkTreeStore* tree_store = GTK_TREE_STORE (g_object_new (MIDORI_BOOKMARKS_TREE_STORE_TYPE, NULL)); |
2422 | + va_list ap; |
2423 | + GType* types; |
2424 | + gint n; |
2425 | + |
2426 | + if (!tree_store) |
2427 | + return NULL; |
2428 | + |
2429 | + types = g_new (GType, n_columns); |
2430 | + |
2431 | + if (!types) |
2432 | + { |
2433 | + g_object_unref(tree_store); |
2434 | + return NULL; |
2435 | + } |
2436 | + |
2437 | + va_start(ap, n_columns); |
2438 | + for (n = 0; n < n_columns; n++) |
2439 | + { |
2440 | + types[n] = va_arg(ap, GType); |
2441 | + } |
2442 | + va_end(ap); |
2443 | + |
2444 | + gtk_tree_store_set_column_types (tree_store, |
2445 | + n_columns, |
2446 | + types); |
2447 | + |
2448 | + g_free (types); |
2449 | + return tree_store; |
2450 | +} |
2451 | + |
2452 | + |
2453 | +GtkTreeStore* |
2454 | +midori_bookmarks_tree_store_newv (gint n_columns, GType *types) |
2455 | +{ |
2456 | + GtkTreeStore* tree_store = GTK_TREE_STORE (g_object_new (MIDORI_BOOKMARKS_TREE_STORE_TYPE, NULL)); |
2457 | + |
2458 | + if (!tree_store) |
2459 | + return NULL; |
2460 | + |
2461 | + gtk_tree_store_set_column_types (tree_store, |
2462 | + n_columns, |
2463 | + types); |
2464 | + |
2465 | + return tree_store; |
2466 | +} |
2467 | + |
2468 | gboolean |
2469 | midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser, |
2470 | KatzeItem* bookmark, |
2471 | @@ -36,6 +142,12 @@ |
2472 | midori_browser_open_bookmark (MidoriBrowser* browser, |
2473 | KatzeItem* item); |
2474 | |
2475 | +static void |
2476 | +midori_bookmarks_row_changed_cb (GtkTreeModel* model, |
2477 | + GtkTreePath* path, |
2478 | + GtkTreeIter* iter, |
2479 | + MidoriBookmarks* bookmarks); |
2480 | + |
2481 | struct _MidoriBookmarks |
2482 | { |
2483 | GtkVBox parent_instance; |
2484 | @@ -44,11 +156,12 @@ |
2485 | GtkWidget* delete; |
2486 | GtkWidget* treeview; |
2487 | MidoriApp* app; |
2488 | - KatzeArray* array; |
2489 | + MidoriBookmarksDb* bookmarks_db; |
2490 | |
2491 | gint filter_timeout; |
2492 | gchar* filter; |
2493 | |
2494 | + GList* pending_inserts; |
2495 | KatzeItem* hovering_item; |
2496 | }; |
2497 | |
2498 | @@ -87,7 +200,12 @@ |
2499 | GParamSpec* pspec); |
2500 | |
2501 | static void |
2502 | -midori_bookmarks_statusbar_update (MidoriBookmarks *bookmarks); |
2503 | +midori_bookmarks_add_item_cb (KatzeArray* array, |
2504 | + KatzeItem* item, |
2505 | + MidoriBookmarks* bookmarks); |
2506 | +static void |
2507 | +midori_bookmarks_update_cb (KatzeArray* array, |
2508 | + MidoriBookmarks* bookmarks); |
2509 | |
2510 | static void |
2511 | midori_bookmarks_class_init (MidoriBookmarksClass* class) |
2512 | @@ -124,6 +242,7 @@ |
2513 | return STOCK_BOOKMARKS; |
2514 | } |
2515 | |
2516 | +#if 0 |
2517 | /* TODO: Function never used */ |
2518 | void |
2519 | midori_bookmarks_export_array_db (sqlite3* db, |
2520 | @@ -137,7 +256,7 @@ |
2521 | gchar* parent_id; |
2522 | |
2523 | parent_id = g_strdup_printf ("%" G_GINT64_FORMAT, parentid); |
2524 | - if (!(root_array = midori_array_query (array, "*", "parentid = %q", parent_id))) |
2525 | + if (!(root_array = midori_bookmarks_db_query_recursive (array, "*", "parentid = %q", parent_id, FALSE))) |
2526 | { |
2527 | g_free (parent_id); |
2528 | return; |
2529 | @@ -159,27 +278,7 @@ |
2530 | g_free (parent_id); |
2531 | g_list_free (list); |
2532 | } |
2533 | - |
2534 | -void |
2535 | -midori_bookmarks_import_array_db (sqlite3* db, |
2536 | - KatzeArray* array, |
2537 | - gint64 parentid) |
2538 | -{ |
2539 | - GList* list; |
2540 | - KatzeItem* item; |
2541 | - gint64 id; |
2542 | - |
2543 | - if (!db) |
2544 | - return; |
2545 | - |
2546 | - KATZE_ARRAY_FOREACH_ITEM_L (item, array, list) |
2547 | - { |
2548 | - id = midori_bookmarks_insert_item_db (db, item, parentid); |
2549 | - if (KATZE_IS_ARRAY (item)) |
2550 | - midori_bookmarks_import_array_db (db, KATZE_ARRAY (item), id); |
2551 | - } |
2552 | - g_list_free (list); |
2553 | -} |
2554 | +#endif |
2555 | |
2556 | static KatzeArray* |
2557 | midori_bookmarks_read_from_db (MidoriBookmarks* bookmarks, |
2558 | @@ -189,21 +288,21 @@ |
2559 | KatzeArray* array; |
2560 | |
2561 | if (keyword && *keyword) |
2562 | - array = midori_array_query (bookmarks->array, |
2563 | - "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "title LIKE '%%%q%%'", keyword); |
2564 | + array = midori_bookmarks_db_query_recursive (bookmarks->bookmarks_db, |
2565 | + "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "title LIKE '%%%q%%'", keyword, FALSE); |
2566 | else |
2567 | { |
2568 | if (parentid > 0) |
2569 | { |
2570 | gchar* parent_id = g_strdup_printf ("%" G_GINT64_FORMAT, parentid); |
2571 | - array = midori_array_query (bookmarks->array, |
2572 | - "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "parentid = %q", parent_id); |
2573 | + array = midori_bookmarks_db_query_recursive (bookmarks->bookmarks_db, |
2574 | + "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "parentid = %q", parent_id, FALSE); |
2575 | |
2576 | g_free (parent_id); |
2577 | } |
2578 | else |
2579 | - array = midori_array_query (bookmarks->array, |
2580 | - "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "parentid IS NULL", NULL); |
2581 | + array = midori_bookmarks_db_query_recursive (bookmarks->bookmarks_db, |
2582 | + "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "parentid IS NULL", NULL, FALSE); |
2583 | } |
2584 | return array ? array : katze_array_new (KATZE_TYPE_ITEM); |
2585 | } |
2586 | @@ -234,90 +333,133 @@ |
2587 | g_object_unref (item); |
2588 | } |
2589 | |
2590 | -gint64 |
2591 | -midori_bookmarks_insert_item_db (sqlite3* db, |
2592 | - KatzeItem* item, |
2593 | - gint64 parentid) |
2594 | +static gboolean |
2595 | +midori_bookmarks_reach_item_recurse (GtkTreeModel* model, |
2596 | + GtkTreeIter* iter, |
2597 | + gint64 id) |
2598 | { |
2599 | - gchar* sqlcmd; |
2600 | - char* errmsg = NULL; |
2601 | - KatzeItem* old_parent; |
2602 | - gchar* new_parentid; |
2603 | - gchar* id = NULL; |
2604 | - const gchar* uri = NULL; |
2605 | - const gchar* desc = NULL; |
2606 | - gint64 seq = 0; |
2607 | - |
2608 | - /* Bookmarks must have a name, import may produce invalid items */ |
2609 | - g_return_val_if_fail (katze_item_get_name (item), seq); |
2610 | - |
2611 | - if (!db) |
2612 | - return seq; |
2613 | - |
2614 | - if (katze_item_get_meta_integer (item, "id") > 0) |
2615 | - id = g_strdup_printf ("%" G_GINT64_FORMAT, katze_item_get_meta_integer(item, "id")); |
2616 | - else |
2617 | - id = g_strdup_printf ("NULL"); |
2618 | - |
2619 | - if (KATZE_ITEM_IS_BOOKMARK (item)) |
2620 | - uri = katze_item_get_uri (item); |
2621 | - |
2622 | - if (katze_item_get_text (item)) |
2623 | - desc = katze_item_get_text (item); |
2624 | - |
2625 | - /* Use folder, otherwise fallback to parent folder */ |
2626 | - old_parent = katze_item_get_parent (item); |
2627 | - if (parentid > 0) |
2628 | - new_parentid = g_strdup_printf ("%" G_GINT64_FORMAT, parentid); |
2629 | - else if (old_parent && katze_item_get_meta_integer (old_parent, "id") > 0) |
2630 | - new_parentid = g_strdup_printf ("%" G_GINT64_FORMAT, katze_item_get_meta_integer (old_parent, "id")); |
2631 | - else |
2632 | - new_parentid = g_strdup_printf ("NULL"); |
2633 | - |
2634 | - sqlcmd = sqlite3_mprintf ( |
2635 | - "INSERT INTO bookmarks (id, parentid, title, uri, desc, toolbar, app) " |
2636 | - "VALUES (%q, %q, '%q', '%q', '%q', %d, %d)", |
2637 | - id, |
2638 | - new_parentid, |
2639 | - katze_item_get_name (item), |
2640 | - katze_str_non_null (uri), |
2641 | - katze_str_non_null (desc), |
2642 | - katze_item_get_meta_boolean (item, "toolbar"), |
2643 | - katze_item_get_meta_boolean (item, "app")); |
2644 | - |
2645 | - if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) == SQLITE_OK) |
2646 | + do |
2647 | { |
2648 | - /* Get insert id */ |
2649 | - if (g_str_equal (id, "NULL")) |
2650 | - { |
2651 | - KatzeArray* seq_array; |
2652 | - |
2653 | - sqlite3_free (sqlcmd); |
2654 | - sqlcmd = sqlite3_mprintf ( |
2655 | - "SELECT seq FROM sqlite_sequence WHERE name = 'bookmarks'"); |
2656 | - |
2657 | - seq_array = katze_array_from_sqlite (db, sqlcmd); |
2658 | - if (katze_array_get_nth_item (seq_array, 0)) |
2659 | + GtkTreeIter child; |
2660 | + KatzeItem *item; |
2661 | + gint64 itemid = -1; |
2662 | + |
2663 | + gtk_tree_model_get (model, iter, 0, &item, -1); |
2664 | + |
2665 | + if (!KATZE_ITEM_IS_SEPARATOR(item)) |
2666 | + { |
2667 | + itemid = katze_item_get_meta_integer (item, "id"); |
2668 | + g_object_unref (item); |
2669 | + } |
2670 | + |
2671 | + if (id == itemid) |
2672 | + return TRUE; |
2673 | + |
2674 | + if (gtk_tree_model_iter_children (model, &child, iter)) |
2675 | + { |
2676 | + if (midori_bookmarks_reach_item_recurse (model, &child, id)) |
2677 | { |
2678 | - KatzeItem* seq_item = katze_array_get_nth_item (seq_array, 0); |
2679 | - |
2680 | - seq = katze_item_get_meta_integer (seq_item, "seq"); |
2681 | - katze_item_set_meta_integer (item, "id", seq); |
2682 | + *iter = child; |
2683 | + return TRUE; |
2684 | } |
2685 | - g_object_unref (seq_array); |
2686 | } |
2687 | } |
2688 | - else |
2689 | - { |
2690 | - g_printerr (_("Failed to add bookmark item: %s\n"), errmsg); |
2691 | - sqlite3_free (errmsg); |
2692 | - } |
2693 | - |
2694 | - sqlite3_free (sqlcmd); |
2695 | - g_free (new_parentid); |
2696 | - g_free (id); |
2697 | - |
2698 | - return seq; |
2699 | + while (gtk_tree_model_iter_next(model, iter)); |
2700 | + |
2701 | + return FALSE; |
2702 | +} |
2703 | + |
2704 | +static gboolean |
2705 | +midori_bookmarks_reach_item (GtkTreeModel* model, |
2706 | + GtkTreeIter* iter, |
2707 | + gint64 id) |
2708 | +{ |
2709 | + if (!gtk_tree_model_get_iter_first(model, iter)) |
2710 | + return FALSE; |
2711 | + |
2712 | + return midori_bookmarks_reach_item_recurse (model, iter, id); |
2713 | +} |
2714 | + |
2715 | +static void |
2716 | +midori_bookmarks_add_item_to_model(GtkTreeStore* model, |
2717 | + GtkTreeIter* parent, |
2718 | + KatzeItem* item) |
2719 | +{ |
2720 | + if (KATZE_ITEM_IS_BOOKMARK (item)) |
2721 | + { |
2722 | + gchar* tooltip = g_markup_escape_text (katze_item_get_uri (item), -1); |
2723 | + |
2724 | + gtk_tree_store_insert_with_values (model, NULL, parent, |
2725 | + 0, |
2726 | + 0, item, 1, tooltip, -1); |
2727 | + g_free (tooltip); |
2728 | + } |
2729 | + else |
2730 | + { |
2731 | + GtkTreeIter root_iter; |
2732 | + |
2733 | + gtk_tree_store_insert_with_values (model, &root_iter, parent, |
2734 | + 0, 0, item, -1); |
2735 | + |
2736 | + /* That's an invisible dummy, so we always have an expander */ |
2737 | + gtk_tree_store_insert_with_values (model, NULL, &root_iter, |
2738 | + 0, |
2739 | + 0, NULL, -1); |
2740 | + } |
2741 | +} |
2742 | + |
2743 | +static void |
2744 | +midori_bookmarks_update_item_in_model(MidoriBookmarks* bookmarks, |
2745 | + GtkTreeStore* model, |
2746 | + GtkTreeIter* iter, |
2747 | + KatzeItem* item) |
2748 | +{ |
2749 | + g_signal_handlers_block_by_func (model, |
2750 | + midori_bookmarks_row_changed_cb, |
2751 | + bookmarks); |
2752 | + |
2753 | + if (KATZE_ITEM_IS_BOOKMARK (item)) |
2754 | + { |
2755 | + gchar* tooltip = g_markup_escape_text (katze_item_get_uri (item), -1); |
2756 | + |
2757 | + gtk_tree_store_set(model, iter, |
2758 | + 0, item, 1, tooltip, -1); |
2759 | + |
2760 | + g_free (tooltip); |
2761 | + } |
2762 | + else |
2763 | + { |
2764 | + gtk_tree_store_set(model, iter, |
2765 | + 0, item, -1); |
2766 | + } |
2767 | + |
2768 | + g_signal_handlers_unblock_by_func (model, |
2769 | + midori_bookmarks_row_changed_cb, |
2770 | + bookmarks); |
2771 | +} |
2772 | + |
2773 | +static void |
2774 | +midori_bookmarks_add_item (KatzeItem* item, |
2775 | + MidoriBookmarks* bookmarks); |
2776 | + |
2777 | +static gboolean |
2778 | +midori_bookmarks_idle (MidoriBookmarks* bookmarks) |
2779 | +{ |
2780 | + GList* list_iter; |
2781 | + |
2782 | + for (list_iter = bookmarks->pending_inserts; list_iter; list_iter = g_list_next (list_iter)) |
2783 | + { |
2784 | + KatzeItem *item = KATZE_ITEM (list_iter->data); |
2785 | + |
2786 | + midori_bookmarks_add_item (item, bookmarks); |
2787 | + |
2788 | + g_object_unref (item); |
2789 | + } |
2790 | + |
2791 | + g_list_free (bookmarks->pending_inserts); |
2792 | + bookmarks->pending_inserts = NULL; |
2793 | + |
2794 | + return FALSE; |
2795 | } |
2796 | |
2797 | static void |
2798 | @@ -325,11 +467,98 @@ |
2799 | KatzeItem* item, |
2800 | MidoriBookmarks* bookmarks) |
2801 | { |
2802 | - GtkTreeModel* model; |
2803 | - model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview)); |
2804 | - gtk_tree_store_clear (GTK_TREE_STORE (model)); |
2805 | - midori_bookmarks_read_from_db_to_model (bookmarks, |
2806 | - GTK_TREE_STORE (model), NULL, 0, bookmarks->filter); |
2807 | + if (!bookmarks->pending_inserts) |
2808 | + g_idle_add ((GSourceFunc)midori_bookmarks_idle, bookmarks); |
2809 | + |
2810 | + g_object_ref (item); |
2811 | + bookmarks->pending_inserts = g_list_append (bookmarks->pending_inserts, item); |
2812 | +} |
2813 | + |
2814 | +static void |
2815 | +midori_bookmarks_add_item (KatzeItem* item, |
2816 | + MidoriBookmarks* bookmarks) |
2817 | +{ |
2818 | + gint64 id = katze_item_get_meta_integer (item, "id"); |
2819 | + gint64 parentid = katze_item_get_meta_integer (item, "parentid"); |
2820 | + GtkTreeModel* model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview)); |
2821 | + GtkTreeIter iter; |
2822 | + |
2823 | + if (!parentid) |
2824 | + { |
2825 | + midori_bookmarks_add_item_to_model (GTK_TREE_STORE (model), NULL, item); |
2826 | + } |
2827 | + else if (midori_bookmarks_reach_item (model, &iter, parentid)) |
2828 | + { |
2829 | + GtkTreePath* path = gtk_tree_model_get_path(model, &iter); |
2830 | + |
2831 | + if (gtk_tree_view_row_expanded (GTK_TREE_VIEW (bookmarks->treeview), path)) |
2832 | + { |
2833 | + midori_bookmarks_add_item_to_model (GTK_TREE_STORE (model), &iter, item); |
2834 | + } |
2835 | + |
2836 | + gtk_tree_path_free (path); |
2837 | + } |
2838 | +} |
2839 | + |
2840 | +static void |
2841 | +midori_bookmarks_update_item_cb (KatzeArray* array, |
2842 | + KatzeItem* item, |
2843 | + MidoriBookmarks* bookmarks) |
2844 | +{ |
2845 | + gint64 id = katze_item_get_meta_integer (item, "id"); |
2846 | + gint64 parentid = katze_item_get_meta_integer (item, "parentid"); |
2847 | + GtkTreeModel* model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview)); |
2848 | + GtkTreeIter iter; |
2849 | + |
2850 | + if (midori_bookmarks_reach_item (model, &iter, id)) |
2851 | + { |
2852 | + gint64 old_parentid = 0; |
2853 | + GtkTreeIter parent; |
2854 | + |
2855 | + if (gtk_tree_model_iter_parent (model, &parent, &iter)) |
2856 | + { |
2857 | + KatzeItem* old_parent; |
2858 | + |
2859 | + gtk_tree_model_get (model, &parent, 0, &old_parent, -1); |
2860 | + |
2861 | + old_parentid = katze_item_get_meta_integer (old_parent, "id"); |
2862 | + |
2863 | + g_object_unref (old_parent); |
2864 | + |
2865 | + if (parentid == old_parentid) |
2866 | + { |
2867 | + midori_bookmarks_update_item_in_model (bookmarks, GTK_TREE_STORE (model), &iter, item); |
2868 | + } |
2869 | + else |
2870 | + { |
2871 | + gtk_tree_store_remove (GTK_TREE_STORE (model), &iter); |
2872 | + |
2873 | + if (!gtk_tree_model_iter_has_child (model, &parent)) |
2874 | + { |
2875 | + GtkTreePath* path = gtk_tree_model_get_path(model, &parent); |
2876 | + |
2877 | + if (gtk_tree_view_row_expanded (GTK_TREE_VIEW (bookmarks->treeview), path)) |
2878 | + gtk_tree_view_collapse_row (GTK_TREE_VIEW (bookmarks->treeview), path); |
2879 | + |
2880 | + gtk_tree_path_free (path); |
2881 | + } |
2882 | + |
2883 | + midori_bookmarks_add_item (item, bookmarks); |
2884 | + } |
2885 | + } |
2886 | + else if (parentid == 0) |
2887 | + { |
2888 | + midori_bookmarks_update_item_in_model (bookmarks, GTK_TREE_STORE (model), &iter, item); |
2889 | + } |
2890 | + else |
2891 | + { |
2892 | + gtk_tree_store_remove (GTK_TREE_STORE (model), &iter); |
2893 | + |
2894 | + midori_bookmarks_add_item (item, bookmarks); |
2895 | + } |
2896 | + } |
2897 | + else |
2898 | + midori_bookmarks_add_item (item, bookmarks); |
2899 | } |
2900 | |
2901 | static void |
2902 | @@ -337,12 +566,36 @@ |
2903 | KatzeItem* item, |
2904 | MidoriBookmarks* bookmarks) |
2905 | { |
2906 | + gint64 id = katze_item_get_meta_integer (item, "id"); |
2907 | GtkTreeModel* model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview)); |
2908 | - gtk_tree_store_clear (GTK_TREE_STORE (model)); |
2909 | - midori_bookmarks_read_from_db_to_model (bookmarks, |
2910 | - GTK_TREE_STORE (model), NULL, 0, bookmarks->filter); |
2911 | + GtkTreeIter iter; |
2912 | + |
2913 | + if (midori_bookmarks_reach_item (model, &iter, id)) |
2914 | + { |
2915 | + GtkTreeIter parent; |
2916 | + |
2917 | + if (gtk_tree_model_iter_parent (model, &parent, &iter)) |
2918 | + { |
2919 | + gtk_tree_store_remove (GTK_TREE_STORE (model), &iter); |
2920 | + |
2921 | + if (!gtk_tree_model_iter_has_child (model, &parent)) |
2922 | + { |
2923 | + GtkTreePath* path = gtk_tree_model_get_path(model, &parent); |
2924 | + |
2925 | + if (gtk_tree_view_row_expanded (GTK_TREE_VIEW (bookmarks->treeview), path)) |
2926 | + gtk_tree_view_collapse_row (GTK_TREE_VIEW (bookmarks->treeview), path); |
2927 | + |
2928 | + gtk_tree_path_free (path); |
2929 | + } |
2930 | + } |
2931 | + else |
2932 | + { |
2933 | + gtk_tree_store_remove (GTK_TREE_STORE (model), &iter); |
2934 | + } |
2935 | + } |
2936 | } |
2937 | |
2938 | + |
2939 | static void |
2940 | midori_bookmarks_update_cb (KatzeArray* array, |
2941 | MidoriBookmarks* bookmarks) |
2942 | @@ -354,6 +607,42 @@ |
2943 | } |
2944 | |
2945 | |
2946 | +static gboolean |
2947 | +midori_bookmarks_tree_store_row_drop_possible (GtkTreeDragDest* drag_dest, |
2948 | + GtkTreePath* dest_path, |
2949 | + GtkSelectionData* selection_data) |
2950 | +{ |
2951 | + gboolean row_drop_possible = |
2952 | + gtk_tree_store_gtk_tree_drag_dest_iface->row_drop_possible (drag_dest, |
2953 | + dest_path, |
2954 | + selection_data); |
2955 | + |
2956 | + if (!row_drop_possible) |
2957 | + return FALSE; |
2958 | + |
2959 | + if ((!gtk_tree_path_get_depth(dest_path) > 1) |
2960 | + && gtk_tree_path_up(dest_path)) |
2961 | + { |
2962 | + GtkTreeModel* model = GTK_TREE_MODEL(drag_dest); |
2963 | + GtkTreeIter iter; |
2964 | + |
2965 | + if (gtk_tree_model_get_iter (model, &iter, dest_path)) |
2966 | + { |
2967 | + KatzeItem* item; |
2968 | + |
2969 | + gtk_tree_model_get (model, &iter, 0, &item, -1); |
2970 | + |
2971 | + if (!KATZE_ITEM_IS_FOLDER(item)) |
2972 | + row_drop_possible = FALSE; |
2973 | + |
2974 | + if (item) |
2975 | + g_object_unref (item); |
2976 | + } |
2977 | + } |
2978 | + |
2979 | + return row_drop_possible; |
2980 | +} |
2981 | + |
2982 | static void |
2983 | midori_bookmarks_row_changed_cb (GtkTreeModel* model, |
2984 | GtkTreePath* path, |
2985 | @@ -362,31 +651,37 @@ |
2986 | { |
2987 | KatzeItem* item; |
2988 | GtkTreeIter parent; |
2989 | - KatzeItem* new_parent = NULL; |
2990 | - gint64 parentid; |
2991 | - |
2992 | - gtk_tree_model_get (model, iter, 0, &item, -1); |
2993 | + gint64 parentid = 0; |
2994 | |
2995 | if (gtk_tree_model_iter_parent (model, &parent, iter)) |
2996 | { |
2997 | + KatzeItem* new_parent; |
2998 | + |
2999 | gtk_tree_model_get (model, &parent, 0, &new_parent, -1); |
3000 | |
3001 | - /* Bookmarks must not be moved into non-folder items */ |
3002 | - if (!KATZE_ITEM_IS_FOLDER (new_parent)) |
3003 | - parentid = 0; |
3004 | - else |
3005 | - parentid = katze_item_get_meta_integer (new_parent, "id"); |
3006 | + /* Bookmarks cannot be moved into non-folder items */ |
3007 | + g_assert (KATZE_ITEM_IS_FOLDER (new_parent)); |
3008 | + |
3009 | + parentid = katze_item_get_meta_integer (new_parent, "id"); |
3010 | + |
3011 | + g_object_unref (new_parent); |
3012 | } |
3013 | - else |
3014 | - parentid = 0; |
3015 | - |
3016 | - katze_array_remove_item (bookmarks->array, item); |
3017 | + |
3018 | + gtk_tree_model_get (model, iter, 0, &item, -1); |
3019 | + |
3020 | katze_item_set_meta_integer (item, "parentid", parentid); |
3021 | - katze_array_add_item (bookmarks->array, item); |
3022 | + |
3023 | + g_signal_handlers_block_by_func (bookmarks->bookmarks_db, |
3024 | + midori_bookmarks_update_item_cb, |
3025 | + bookmarks); |
3026 | + |
3027 | + midori_bookmarks_db_update_item (bookmarks->bookmarks_db, item); |
3028 | + |
3029 | + g_signal_handlers_unblock_by_func (bookmarks->bookmarks_db, |
3030 | + midori_bookmarks_update_item_cb, |
3031 | + bookmarks); |
3032 | |
3033 | g_object_unref (item); |
3034 | - if (new_parent) |
3035 | - g_object_unref (new_parent); |
3036 | } |
3037 | |
3038 | static void |
3039 | @@ -412,24 +707,15 @@ |
3040 | { |
3041 | KatzeItem* item; |
3042 | MidoriBrowser* browser; |
3043 | - gint64 parentid; |
3044 | |
3045 | gtk_tree_model_get (model, &iter, 0, &item, -1); |
3046 | |
3047 | g_assert (!KATZE_ITEM_IS_SEPARATOR (item)); |
3048 | |
3049 | browser = midori_browser_get_for_widget (bookmarks->treeview); |
3050 | - parentid = katze_item_get_meta_integer (item, "parentid"); |
3051 | midori_browser_edit_bookmark_dialog_new ( |
3052 | browser, item, FALSE, KATZE_ITEM_IS_FOLDER (item), NULL); |
3053 | |
3054 | - if (katze_item_get_meta_integer (item, "parentid") != parentid) |
3055 | - { |
3056 | - gtk_tree_store_clear (GTK_TREE_STORE (model)); |
3057 | - midori_bookmarks_read_from_db_to_model (bookmarks, GTK_TREE_STORE (model), |
3058 | - NULL, 0, NULL); |
3059 | - } |
3060 | - |
3061 | g_object_unref (item); |
3062 | } |
3063 | } |
3064 | @@ -445,7 +731,7 @@ |
3065 | gtk_widget_set_sensitive (GTK_WIDGET (bookmarks->edit), selected); |
3066 | } |
3067 | |
3068 | -static gchar* |
3069 | +static gchar* |
3070 | midori_bookmarks_statusbar_bookmarks_str (gint count) |
3071 | { |
3072 | if (!count) |
3073 | @@ -455,7 +741,7 @@ |
3074 | return g_strdup_printf (ngettext ("%d bookmark", "%d bookmarks", count), count); |
3075 | } |
3076 | |
3077 | -static gchar* |
3078 | +static gchar* |
3079 | midori_bookmarks_statusbar_subfolders_str (gint count) |
3080 | { |
3081 | if (!count) |
3082 | @@ -481,9 +767,9 @@ |
3083 | |
3084 | if (KATZE_ITEM_IS_FOLDER (item)) |
3085 | { |
3086 | - gint child_folders_count = midori_array_count_recursive (bookmarks->array, |
3087 | + gint child_folders_count = midori_bookmarks_db_count_recursive (bookmarks->bookmarks_db, |
3088 | "uri = ''", NULL, item, FALSE); |
3089 | - gint child_bookmarks_count = midori_array_count_recursive (bookmarks->array, |
3090 | + gint child_bookmarks_count = midori_bookmarks_db_count_recursive (bookmarks->bookmarks_db, |
3091 | "uri <> ''", NULL, item, FALSE); |
3092 | gchar* child_folders_str = midori_bookmarks_statusbar_subfolders_str (child_folders_count); |
3093 | gchar* child_bookmarks_str = midori_bookmarks_statusbar_bookmarks_str (child_bookmarks_count); |
3094 | @@ -516,13 +802,13 @@ |
3095 | } |
3096 | else |
3097 | { |
3098 | - gint child_folders_count = midori_array_count_recursive (bookmarks->array, |
3099 | + gint child_folders_count = midori_bookmarks_db_count_recursive (bookmarks->bookmarks_db, |
3100 | "uri = ''", NULL, NULL, FALSE); |
3101 | - gint child_bookmarks_count = midori_array_count_recursive (bookmarks->array, |
3102 | + gint child_bookmarks_count = midori_bookmarks_db_count_recursive (bookmarks->bookmarks_db, |
3103 | "uri <> ''", NULL, NULL, FALSE); |
3104 | gchar* child_folders_str = midori_bookmarks_statusbar_subfolders_str (child_folders_count); |
3105 | gchar* child_bookmarks_str = midori_bookmarks_statusbar_bookmarks_str (child_bookmarks_count); |
3106 | - |
3107 | + |
3108 | if (!child_bookmarks_count && (child_folders_count >= 1)) |
3109 | /* i18n: [[n] folder(s)] and no bookmark */ |
3110 | text = g_strdup_printf (_("%s and no bookmark"), |
3111 | @@ -533,7 +819,7 @@ |
3112 | /* i18n: [[n] bookmark(s)] and [[n] folder(s)] */ |
3113 | text = g_strdup_printf (_("%s and %s"), |
3114 | child_bookmarks_str, child_folders_str); |
3115 | - |
3116 | + |
3117 | g_free (child_folders_str); |
3118 | g_free (child_bookmarks_str); |
3119 | } |
3120 | @@ -541,9 +827,9 @@ |
3121 | if (text) |
3122 | { |
3123 | MidoriBrowser* browser = midori_browser_get_for_widget (bookmarks->treeview); |
3124 | - |
3125 | + |
3126 | g_object_set (browser, "statusbar-text", text, NULL); |
3127 | - |
3128 | + |
3129 | g_free(text); |
3130 | } |
3131 | } |
3132 | @@ -603,13 +889,8 @@ |
3133 | |
3134 | gtk_tree_model_get (model, &iter, 0, &item, -1); |
3135 | |
3136 | - /* Manually remove the iter and block clearing the treeview */ |
3137 | - gtk_tree_store_remove (GTK_TREE_STORE (model), &iter); |
3138 | - g_signal_handlers_block_by_func (bookmarks->array, |
3139 | - midori_bookmarks_remove_item_cb, bookmarks); |
3140 | - katze_array_remove_item (bookmarks->array, item); |
3141 | - g_signal_handlers_unblock_by_func (bookmarks->array, |
3142 | - midori_bookmarks_remove_item_cb, bookmarks); |
3143 | + midori_bookmarks_db_remove_item (bookmarks->bookmarks_db, item); |
3144 | + |
3145 | g_object_unref (item); |
3146 | } |
3147 | } |
3148 | @@ -693,9 +974,9 @@ |
3149 | GtkTreeModel* model; |
3150 | |
3151 | model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview)); |
3152 | - if (bookmarks->array) |
3153 | + if (bookmarks->bookmarks_db) |
3154 | { |
3155 | - g_object_unref (bookmarks->array); |
3156 | + g_object_unref (bookmarks->bookmarks_db); |
3157 | gtk_tree_store_clear (GTK_TREE_STORE (model)); |
3158 | } |
3159 | katze_assign (bookmarks->app, app); |
3160 | @@ -703,17 +984,19 @@ |
3161 | return; |
3162 | |
3163 | g_object_ref (app); |
3164 | - bookmarks->array = katze_object_get_object (app, "bookmarks"); |
3165 | + bookmarks->bookmarks_db = katze_object_get_object (app, "bookmarks"); |
3166 | midori_bookmarks_read_from_db_to_model (bookmarks, GTK_TREE_STORE (model), NULL, 0, NULL); |
3167 | - g_signal_connect_after (bookmarks->array, "add-item", |
3168 | - G_CALLBACK (midori_bookmarks_add_item_cb), bookmarks); |
3169 | - g_signal_connect (bookmarks->array, "remove-item", |
3170 | - G_CALLBACK (midori_bookmarks_remove_item_cb), bookmarks); |
3171 | - g_signal_connect (bookmarks->array, "update", |
3172 | - G_CALLBACK (midori_bookmarks_update_cb), bookmarks); |
3173 | + g_signal_connect_after (bookmarks->bookmarks_db, "add-item", |
3174 | + G_CALLBACK (midori_bookmarks_add_item_cb), bookmarks); |
3175 | + g_signal_connect_after (bookmarks->bookmarks_db, "update-item", |
3176 | + G_CALLBACK (midori_bookmarks_update_item_cb), bookmarks); |
3177 | + g_signal_connect (bookmarks->bookmarks_db, "remove-item", |
3178 | + G_CALLBACK (midori_bookmarks_remove_item_cb), bookmarks); |
3179 | + g_signal_connect (bookmarks->bookmarks_db, "update", |
3180 | + G_CALLBACK (midori_bookmarks_update_cb), bookmarks); |
3181 | g_signal_connect_after (model, "row-changed", |
3182 | - G_CALLBACK (midori_bookmarks_row_changed_cb), |
3183 | - bookmarks); |
3184 | + G_CALLBACK (midori_bookmarks_row_changed_cb), |
3185 | + bookmarks); |
3186 | } |
3187 | |
3188 | static void |
3189 | @@ -943,12 +1226,12 @@ |
3190 | menu = gtk_menu_new (); |
3191 | if (KATZE_ITEM_IS_FOLDER (item)) |
3192 | { |
3193 | - gint child_bookmarks_count = midori_array_count_recursive (bookmarks->array, |
3194 | + gint child_bookmarks_count = midori_bookmarks_db_count_recursive (bookmarks->bookmarks_db, |
3195 | "uri <> ''", NULL, item, FALSE); |
3196 | |
3197 | midori_bookmarks_popup_item (menu, |
3198 | - STOCK_TAB_NEW, _("Open all in _Tabs"), item, |
3199 | - (!child_bookmarks_count ? NULL : midori_bookmarks_open_in_tab_activate_cb), |
3200 | + STOCK_TAB_NEW, _("Open all in _Tabs"), item, |
3201 | + (!child_bookmarks_count ? NULL : midori_bookmarks_open_in_tab_activate_cb), |
3202 | bookmarks); |
3203 | } |
3204 | else |
3205 | @@ -1080,7 +1363,7 @@ |
3206 | static KatzeItem* |
3207 | midori_bookmarks_get_item_at_pos (GtkTreeView *treeview, |
3208 | gint x, gint y) |
3209 | -{ |
3210 | +{ |
3211 | GtkTreeModel* model = gtk_tree_view_get_model (treeview); |
3212 | GtkTreePath* path; |
3213 | GtkTreeIter iter; |
3214 | @@ -1088,13 +1371,13 @@ |
3215 | |
3216 | gtk_tree_view_get_path_at_pos (treeview, x, y, |
3217 | &path, NULL, NULL, NULL); |
3218 | - |
3219 | + |
3220 | if (!path) |
3221 | return NULL; |
3222 | - |
3223 | + |
3224 | if (gtk_tree_model_get_iter (model, &iter, path)) |
3225 | gtk_tree_model_get (model, &iter, 0, &item, -1); |
3226 | - |
3227 | + |
3228 | gtk_tree_path_free (path); |
3229 | |
3230 | return item; |
3231 | @@ -1166,7 +1449,7 @@ |
3232 | |
3233 | if (bookmarks->hovering_item) |
3234 | g_object_unref (bookmarks->hovering_item); |
3235 | - |
3236 | + |
3237 | bookmarks->hovering_item = NULL; |
3238 | |
3239 | g_object_set (browser, "statusbar-text", "", NULL); |
3240 | @@ -1229,7 +1512,7 @@ |
3241 | gtk_box_pack_start (GTK_BOX (bookmarks), box, FALSE, FALSE, 5); |
3242 | |
3243 | /* Create the treeview */ |
3244 | - model = gtk_tree_store_new (2, KATZE_TYPE_ITEM, G_TYPE_STRING); |
3245 | + model = midori_bookmarks_tree_store_new (2, KATZE_TYPE_ITEM, G_TYPE_STRING); |
3246 | treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model)); |
3247 | gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE); |
3248 | gtk_tree_view_set_tooltip_column (GTK_TREE_VIEW (treeview), 1); |
3249 | @@ -1268,7 +1551,7 @@ |
3250 | "signal::leave-notify-event", |
3251 | midori_bookmarks_leave_notify_event_cb, bookmarks, |
3252 | NULL); |
3253 | - gtk_widget_add_events (GTK_WIDGET (treeview), |
3254 | + gtk_widget_add_events (GTK_WIDGET (treeview), |
3255 | GDK_POINTER_MOTION_MASK |
3256 | | GDK_POINTER_MOTION_HINT_MASK); |
3257 | |
3258 | @@ -1279,6 +1562,7 @@ |
3259 | gtk_widget_show (treeview); |
3260 | gtk_box_pack_start (GTK_BOX (bookmarks), treeview, TRUE, TRUE, 0); |
3261 | bookmarks->treeview = treeview; |
3262 | + bookmarks->pending_inserts = NULL; |
3263 | bookmarks->hovering_item = NULL; |
3264 | } |
3265 | |
3266 | |
3267 | === modified file 'panels/midori-bookmarks.h' |
3268 | --- panels/midori-bookmarks.h 2012-11-25 11:26:03 +0000 |
3269 | +++ panels/midori-bookmarks.h 2013-06-11 20:53:24 +0000 |
3270 | @@ -37,20 +37,6 @@ |
3271 | GType |
3272 | midori_bookmarks_get_type (void); |
3273 | |
3274 | -gint64 |
3275 | -midori_bookmarks_insert_item_db (sqlite3* db, |
3276 | - KatzeItem* item, |
3277 | - gint64 parentid); |
3278 | - |
3279 | -void |
3280 | -midori_bookmarks_import_array_db (sqlite3* db, |
3281 | - KatzeArray* array, |
3282 | - gint64 parentid); |
3283 | - |
3284 | -gboolean |
3285 | -midori_bookmarks_update_item_db (sqlite3* db, |
3286 | - KatzeItem* item); |
3287 | - |
3288 | G_END_DECLS |
3289 | |
3290 | #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?