1.1.18
by Sebastien Bacher
Import upstream version 2.17.4 |
1 |
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
2 |
/*
|
1.1.15
by Sebastien Bacher
Import upstream version 2.16.1 |
3 |
* Copyright © 2002-2004 Marco Pesenti Gritti
|
4 |
* Copyright © 2003, 2004 Christian Persch
|
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
5 |
*
|
6 |
* This program is free software; you can redistribute it and/or modify
|
|
7 |
* it under the terms of the GNU General Public License as published by
|
|
8 |
* the Free Software Foundation; either version 2, or (at your option)
|
|
9 |
* any later version.
|
|
10 |
*
|
|
11 |
* This program is distributed in the hope that it will be useful,
|
|
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14 |
* GNU General Public License for more details.
|
|
15 |
*
|
|
16 |
* You should have received a copy of the GNU General Public License
|
|
17 |
* along with this program; if not, write to the Free Software
|
|
1.1.24
by Sebastien Bacher
Import upstream version 2.18.1 |
18 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
19 |
*
|
20 |
*/
|
|
21 |
||
22 |
#include "config.h" |
|
23 |
#include "ephy-bookmarks.h" |
|
1.7.7
by Jeremy Bicha
Import upstream version 3.3.91 |
24 |
|
25 |
#include "ephy-bookmark-properties.h" |
|
26 |
#include "ephy-bookmarks-export.h" |
|
27 |
#include "ephy-bookmarks-import.h" |
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
28 |
#include "ephy-bookmarks-type-builtins.h" |
1.7.7
by Jeremy Bicha
Import upstream version 3.3.91 |
29 |
#include "ephy-debug.h" |
30 |
#include "ephy-embed-shell.h" |
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
31 |
#include "ephy-file-helpers.h" |
1.7.7
by Jeremy Bicha
Import upstream version 3.3.91 |
32 |
#include "ephy-history-service.h" |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
33 |
#include "ephy-node-common.h" |
34 |
#include "ephy-prefs.h" |
|
1.8.9
by Gustavo Noronha Silva
Import upstream version 3.7.91 |
35 |
#include "ephy-profile-utils.h" |
1.1.62
by Emilio Pozuelo Monfort
Import upstream version 2.91.5 |
36 |
#include "ephy-settings.h" |
1.7.7
by Jeremy Bicha
Import upstream version 3.3.91 |
37 |
#include "ephy-shell.h" |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
38 |
#include "ephy-signal-accumulator.h" |
1.7.7
by Jeremy Bicha
Import upstream version 3.3.91 |
39 |
#include "ephy-tree-model-node.h" |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
40 |
|
1.8.7
by Jeremy Bicha
Import upstream version 3.6.0 |
41 |
#include <avahi-common/error.h> |
42 |
#include <avahi-gobject/ga-client.h> |
|
43 |
#include <avahi-gobject/ga-enums.h> |
|
44 |
#include <avahi-gobject/ga-service-browser.h> |
|
45 |
#include <avahi-gobject/ga-service-resolver.h> |
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
46 |
#include <glib/gi18n.h> |
1.1.39
by Sebastien Bacher
Import upstream version 2.23.91 |
47 |
#include <gtk/gtk.h> |
1.7.7
by Jeremy Bicha
Import upstream version 3.3.91 |
48 |
#include <string.h> |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
49 |
|
50 |
#define EPHY_BOOKMARKS_XML_ROOT "ephy_bookmarks"
|
|
51 |
#define EPHY_BOOKMARKS_XML_VERSION "1.03"
|
|
1.1.19
by Sebastien Bacher
Import upstream version 2.17.5 |
52 |
#define BOOKMARKS_SAVE_DELAY 3 /* seconds */ |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
53 |
#define UPDATE_URI_DATA_KEY "updated-uri"
|
54 |
||
55 |
#define EPHY_BOOKMARKS_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_BOOKMARKS, EphyBookmarksPrivate))
|
|
56 |
||
1.1.11
by Sebastien Bacher
Import upstream version 2.15.3 |
57 |
static const char zeroconf_protos[3][6] = |
58 |
{
|
|
59 |
"http", |
|
60 |
"https", |
|
61 |
"ftp"
|
|
62 |
};
|
|
63 |
||
1
by Sebastien Bacher
Import upstream version 1.9.2 |
64 |
struct _EphyBookmarksPrivate |
65 |
{
|
|
66 |
gboolean init_defaults; |
|
67 |
gboolean dirty; |
|
68 |
guint save_timeout_id; |
|
69 |
char *xml_file; |
|
70 |
char *rdf_file; |
|
71 |
EphyNodeDb *db; |
|
72 |
EphyNode *bookmarks; |
|
73 |
EphyNode *keywords; |
|
74 |
EphyNode *notcategorized; |
|
75 |
EphyNode *smartbookmarks; |
|
76 |
EphyNode *lower_fav; |
|
77 |
double lower_score; |
|
78 |
||
79 |
/* Local sites */
|
|
80 |
EphyNode *local; |
|
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
81 |
GaClient *ga_client; |
82 |
GaServiceBrowser *browse_handles[G_N_ELEMENTS (zeroconf_protos)]; |
|
1.1.5
by Sebastien Bacher
Import upstream version 1.9.7 |
83 |
GHashTable *resolve_handles; |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
84 |
};
|
85 |
||
86 |
static const char *default_topics [] = |
|
87 |
{
|
|
88 |
N_("Entertainment"), |
|
89 |
N_("News"), |
|
90 |
N_("Shopping"), |
|
91 |
N_("Sports"), |
|
92 |
N_("Travel"), |
|
93 |
N_("Work") |
|
94 |
};
|
|
95 |
||
96 |
/* Signals */
|
|
97 |
enum
|
|
98 |
{
|
|
99 |
TREE_CHANGED, |
|
100 |
RESOLVE_ADDRESS, |
|
101 |
LAST_SIGNAL
|
|
102 |
};
|
|
103 |
||
1.1.48
by Gustavo Noronha Silva
Import upstream version 2.28.0 |
104 |
static guint ephy_bookmarks_signals[LAST_SIGNAL]; |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
105 |
|
106 |
static void ephy_bookmarks_class_init (EphyBookmarksClass *klass); |
|
107 |
static void ephy_bookmarks_init (EphyBookmarks *tab); |
|
108 |
static void ephy_bookmarks_finalize (GObject *object); |
|
109 |
static char *impl_resolve_address (EphyBookmarks*, const char*, const char*); |
|
1.1.38
by Sebastien Bacher
Import upstream version 2.22.3 |
110 |
static void ephy_local_bookmarks_start_client (EphyBookmarks *bookmarks); |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
111 |
|
1.1.69
by Gustavo Noronha Silva
Import upstream version 3.2.0 |
112 |
G_DEFINE_TYPE (EphyBookmarks, ephy_bookmarks, G_TYPE_OBJECT) |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
113 |
|
114 |
static void |
|
115 |
ephy_bookmarks_init_defaults (EphyBookmarks *eb) |
|
116 |
{
|
|
117 |
int i; |
|
118 |
||
119 |
for (i = 0; i < G_N_ELEMENTS (default_topics); i++) |
|
120 |
{
|
|
121 |
ephy_bookmarks_add_keyword (eb, _(default_topics[i])); |
|
122 |
}
|
|
123 |
||
1.1.48
by Gustavo Noronha Silva
Import upstream version 2.28.0 |
124 |
ephy_bookmarks_import_rdf (eb, DATADIR "/default-bookmarks.rdf"); |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
125 |
}
|
126 |
||
127 |
static void |
|
128 |
ephy_bookmarks_class_init (EphyBookmarksClass *klass) |
|
129 |
{
|
|
130 |
GObjectClass *object_class = G_OBJECT_CLASS (klass); |
|
131 |
||
132 |
object_class->finalize = ephy_bookmarks_finalize; |
|
133 |
||
134 |
klass->resolve_address = impl_resolve_address; |
|
135 |
||
136 |
ephy_bookmarks_signals[TREE_CHANGED] = |
|
137 |
g_signal_new ("tree-changed", |
|
138 |
G_OBJECT_CLASS_TYPE (object_class), |
|
139 |
G_SIGNAL_RUN_LAST, |
|
140 |
G_STRUCT_OFFSET (EphyBookmarksClass, tree_changed), |
|
141 |
NULL, NULL, |
|
142 |
g_cclosure_marshal_VOID__VOID, |
|
143 |
G_TYPE_NONE, |
|
144 |
0); |
|
145 |
||
146 |
ephy_bookmarks_signals[RESOLVE_ADDRESS] = |
|
147 |
g_signal_new ("resolve-address", |
|
148 |
G_OBJECT_CLASS_TYPE (object_class), |
|
149 |
G_SIGNAL_RUN_LAST, |
|
150 |
G_STRUCT_OFFSET (EphyBookmarksClass, resolve_address), |
|
151 |
ephy_signal_accumulator_string, NULL, |
|
1.1.69
by Gustavo Noronha Silva
Import upstream version 3.2.0 |
152 |
g_cclosure_marshal_generic, |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
153 |
G_TYPE_STRING, |
154 |
2, |
|
155 |
G_TYPE_STRING, |
|
156 |
G_TYPE_STRING); |
|
157 |
||
158 |
g_type_class_add_private (object_class, sizeof(EphyBookmarksPrivate)); |
|
159 |
}
|
|
160 |
||
161 |
static gboolean |
|
162 |
save_filter (EphyNode *node, |
|
163 |
EphyBookmarks *bookmarks) |
|
164 |
{
|
|
165 |
EphyBookmarksPrivate *priv = bookmarks->priv; |
|
166 |
||
167 |
return node != priv->bookmarks && |
|
168 |
node != priv->notcategorized && |
|
169 |
node != priv->local; |
|
170 |
}
|
|
171 |
||
172 |
static gboolean |
|
173 |
save_filter_local (EphyNode *node, |
|
174 |
EphyBookmarks *bookmarks) |
|
175 |
{
|
|
176 |
EphyBookmarksPrivate *priv = bookmarks->priv; |
|
177 |
||
1.1.11
by Sebastien Bacher
Import upstream version 2.15.3 |
178 |
return !ephy_node_has_child (priv->local, node); |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
179 |
}
|
180 |
||
181 |
static void |
|
182 |
ephy_bookmarks_save (EphyBookmarks *eb) |
|
183 |
{
|
|
184 |
||
185 |
LOG ("Saving bookmarks"); |
|
186 |
||
187 |
ephy_node_db_write_to_xml_safe
|
|
188 |
(eb->priv->db, |
|
189 |
(xmlChar *) eb->priv->xml_file, |
|
190 |
(xmlChar *) EPHY_BOOKMARKS_XML_ROOT, |
|
191 |
(xmlChar *) EPHY_BOOKMARKS_XML_VERSION, |
|
192 |
(xmlChar *) "Do not rely on this file, it's only for internal use. Use bookmarks.rdf instead.", |
|
193 |
eb->priv->keywords, (EphyNodeFilterFunc) save_filter, eb, |
|
194 |
eb->priv->bookmarks, (EphyNodeFilterFunc) save_filter_local, eb, |
|
195 |
NULL); |
|
196 |
||
197 |
/* Export bookmarks in rdf */
|
|
198 |
ephy_bookmarks_export_rdf (eb, eb->priv->rdf_file); |
|
199 |
}
|
|
200 |
||
201 |
static gboolean |
|
202 |
save_bookmarks_delayed (EphyBookmarks *bookmarks) |
|
203 |
{
|
|
204 |
ephy_bookmarks_save (bookmarks); |
|
205 |
bookmarks->priv->dirty = FALSE; |
|
206 |
bookmarks->priv->save_timeout_id = 0; |
|
207 |
||
208 |
return FALSE; |
|
209 |
}
|
|
210 |
||
211 |
static void |
|
212 |
ephy_bookmarks_save_delayed (EphyBookmarks *bookmarks, int delay) |
|
213 |
{
|
|
214 |
if (!bookmarks->priv->dirty) |
|
215 |
{
|
|
216 |
bookmarks->priv->dirty = TRUE; |
|
217 |
||
218 |
if (delay > 0) |
|
219 |
{
|
|
220 |
bookmarks->priv->save_timeout_id = |
|
1.1.19
by Sebastien Bacher
Import upstream version 2.17.5 |
221 |
g_timeout_add_seconds (BOOKMARKS_SAVE_DELAY, |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
222 |
(GSourceFunc) save_bookmarks_delayed, |
223 |
bookmarks); |
|
1.8.12
by Sjoerd Simons
Import upstream version 3.12.0 |
224 |
g_source_set_name_by_id (bookmarks->priv->save_timeout_id, "[epiphany] save_bookmarks_delayed"); |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
225 |
}
|
226 |
else
|
|
227 |
{
|
|
228 |
bookmarks->priv->save_timeout_id = |
|
229 |
g_idle_add ((GSourceFunc) save_bookmarks_delayed, |
|
230 |
bookmarks); |
|
231 |
}
|
|
232 |
}
|
|
233 |
}
|
|
234 |
||
1.8.9
by Gustavo Noronha Silva
Import upstream version 3.7.91 |
235 |
static void |
236 |
icon_updated_cb (WebKitFaviconDatabase *favicon_database, |
|
237 |
const char *address, |
|
238 |
const char *icon, |
|
239 |
EphyBookmarks *eb) |
|
240 |
{
|
|
241 |
ephy_bookmarks_set_icon (eb, address, icon); |
|
242 |
}
|
|
1.1.33
by Sebastien Bacher
Import upstream version 2.21.4 |
243 |
|
244 |
static void |
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
245 |
ephy_setup_history_notifiers (EphyBookmarks *eb) |
246 |
{
|
|
1.8.9
by Gustavo Noronha Silva
Import upstream version 3.7.91 |
247 |
WebKitFaviconDatabase *favicon_database; |
1.8.16
by Michael Biebl
Import upstream version 3.16.1 |
248 |
EphyEmbedShell *shell = ephy_embed_shell_get_default (); |
1.8.9
by Gustavo Noronha Silva
Import upstream version 3.7.91 |
249 |
|
1.8.16
by Michael Biebl
Import upstream version 3.16.1 |
250 |
favicon_database = webkit_web_context_get_favicon_database (ephy_embed_shell_get_web_context (shell)); |
1.8.9
by Gustavo Noronha Silva
Import upstream version 3.7.91 |
251 |
g_signal_connect (favicon_database, "favicon-changed", |
252 |
G_CALLBACK (icon_updated_cb), eb); |
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
253 |
}
|
254 |
||
255 |
static void |
|
256 |
update_bookmark_keywords (EphyBookmarks *eb, EphyNode *bookmark) |
|
257 |
{
|
|
258 |
GPtrArray *children; |
|
259 |
int i; |
|
260 |
GString *list; |
|
261 |
const char *title; |
|
262 |
char *normalized_keywords, *case_normalized_keywords; |
|
263 |
||
264 |
list = g_string_new (NULL); |
|
265 |
||
266 |
children = ephy_node_get_children (eb->priv->keywords); |
|
267 |
for (i = 0; i < children->len; i++) |
|
268 |
{
|
|
269 |
EphyNode *kid; |
|
270 |
||
271 |
kid = g_ptr_array_index (children, i); |
|
272 |
||
273 |
if (kid != eb->priv->notcategorized && |
|
274 |
kid != eb->priv->bookmarks && |
|
275 |
kid != eb->priv->local && |
|
276 |
ephy_node_has_child (kid, bookmark)) |
|
277 |
{
|
|
278 |
const char *topic; |
|
279 |
topic = ephy_node_get_property_string |
|
280 |
(kid, EPHY_NODE_KEYWORD_PROP_NAME); |
|
281 |
g_string_append (list, topic); |
|
282 |
g_string_append (list, " "); |
|
283 |
}
|
|
284 |
}
|
|
285 |
||
286 |
title = ephy_node_get_property_string |
|
287 |
(bookmark, EPHY_NODE_BMK_PROP_TITLE); |
|
288 |
g_string_append (list, " "); |
|
289 |
g_string_append (list, title); |
|
290 |
||
291 |
normalized_keywords = g_utf8_normalize (list->str, -1, G_NORMALIZE_ALL); |
|
292 |
case_normalized_keywords = g_utf8_casefold (normalized_keywords, -1); |
|
293 |
||
1.1.18
by Sebastien Bacher
Import upstream version 2.17.4 |
294 |
ephy_node_set_property_string (bookmark, EPHY_NODE_BMK_PROP_KEYWORDS, |
295 |
case_normalized_keywords); |
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
296 |
|
297 |
g_string_free (list, TRUE); |
|
298 |
g_free (normalized_keywords); |
|
299 |
g_free (case_normalized_keywords); |
|
300 |
}
|
|
301 |
||
302 |
static void |
|
303 |
bookmarks_changed_cb (EphyNode *node, |
|
304 |
EphyNode *child, |
|
305 |
guint property_id, |
|
306 |
EphyBookmarks *eb) |
|
307 |
{
|
|
308 |
if (property_id == EPHY_NODE_BMK_PROP_TITLE) |
|
309 |
{
|
|
310 |
update_bookmark_keywords (eb, child); |
|
311 |
}
|
|
312 |
||
313 |
ephy_bookmarks_save_delayed (eb, BOOKMARKS_SAVE_DELAY); |
|
314 |
}
|
|
315 |
||
316 |
static void |
|
317 |
bookmarks_removed_cb (EphyNode *node, |
|
318 |
EphyNode *child, |
|
319 |
guint old_index, |
|
320 |
EphyBookmarks *eb) |
|
321 |
{
|
|
322 |
ephy_bookmarks_save_delayed (eb, BOOKMARKS_SAVE_DELAY); |
|
323 |
}
|
|
324 |
||
325 |
static gboolean |
|
326 |
bookmark_is_categorized (EphyBookmarks *eb, EphyNode *bookmark) |
|
327 |
{
|
|
328 |
GPtrArray *children; |
|
329 |
int i; |
|
330 |
||
331 |
children = ephy_node_get_children (eb->priv->keywords); |
|
332 |
for (i = 0; i < children->len; i++) |
|
333 |
{
|
|
334 |
EphyNode *kid; |
|
335 |
||
336 |
kid = g_ptr_array_index (children, i); |
|
337 |
||
338 |
if (kid != eb->priv->notcategorized && |
|
339 |
kid != eb->priv->bookmarks && |
|
340 |
kid != eb->priv->local && |
|
341 |
ephy_node_has_child (kid, bookmark)) |
|
342 |
{
|
|
343 |
return TRUE; |
|
344 |
}
|
|
345 |
}
|
|
346 |
||
347 |
return FALSE; |
|
348 |
}
|
|
349 |
||
350 |
static void |
|
351 |
topics_removed_cb (EphyNode *node, |
|
352 |
EphyNode *child, |
|
353 |
guint old_index, |
|
354 |
EphyBookmarks *eb) |
|
355 |
{
|
|
356 |
GPtrArray *children; |
|
357 |
int i; |
|
358 |
||
359 |
children = ephy_node_get_children (child); |
|
360 |
for (i = 0; i < children->len; i++) |
|
361 |
{
|
|
362 |
EphyNode *kid; |
|
363 |
||
364 |
kid = g_ptr_array_index (children, i); |
|
365 |
||
366 |
if (!bookmark_is_categorized (eb, kid) && |
|
367 |
!ephy_node_has_child (eb->priv->notcategorized, kid)) |
|
368 |
{
|
|
369 |
ephy_node_add_child
|
|
370 |
(eb->priv->notcategorized, kid); |
|
371 |
}
|
|
372 |
||
373 |
update_bookmark_keywords (eb, kid); |
|
374 |
}
|
|
375 |
}
|
|
376 |
||
377 |
static void |
|
1.1.5
by Sebastien Bacher
Import upstream version 1.9.7 |
378 |
fix_hierarchy_topic (EphyBookmarks *eb, |
379 |
EphyNode *topic) |
|
380 |
{
|
|
381 |
GPtrArray *children; |
|
382 |
EphyNode *bookmark; |
|
383 |
const char *name; |
|
384 |
char **split; |
|
385 |
int i, j; |
|
386 |
||
387 |
children = ephy_node_get_children (topic); |
|
388 |
name = ephy_node_get_property_string (topic, EPHY_NODE_KEYWORD_PROP_NAME); |
|
389 |
split = g_strsplit (name, "->", -1); |
|
390 |
||
391 |
for (i = 0; split[i]; i++) |
|
392 |
{
|
|
393 |
if (split[i][0] == '\0') continue; |
|
394 |
||
395 |
topic = ephy_bookmarks_find_keyword (eb, split[i], FALSE); |
|
396 |
if (topic == NULL) |
|
397 |
{
|
|
398 |
topic = ephy_bookmarks_add_keyword (eb, split[i]); |
|
399 |
}
|
|
400 |
for (j = 0; j < children->len; j++) |
|
401 |
{
|
|
402 |
bookmark = g_ptr_array_index (children, j); |
|
403 |
ephy_bookmarks_set_keyword (eb, topic, bookmark); |
|
404 |
}
|
|
405 |
}
|
|
406 |
||
407 |
g_strfreev (split); |
|
408 |
}
|
|
409 |
||
410 |
static void |
|
411 |
fix_hierarchy (EphyBookmarks *eb) |
|
412 |
{
|
|
413 |
GPtrArray *topics; |
|
414 |
EphyNode *topic; |
|
415 |
const char *name; |
|
416 |
int i; |
|
417 |
||
418 |
topics = ephy_node_get_children (eb->priv->keywords); |
|
419 |
for (i = (int)topics->len - 1; i >= 0; i--) |
|
420 |
{
|
|
421 |
topic = (EphyNode *)g_ptr_array_index (topics, i); |
|
422 |
name = ephy_node_get_property_string |
|
423 |
(topic, EPHY_NODE_KEYWORD_PROP_NAME); |
|
424 |
if (strstr (name, "->") != NULL) |
|
425 |
{
|
|
426 |
fix_hierarchy_topic (eb, topic); |
|
427 |
ephy_node_remove_child (eb->priv->keywords, topic); |
|
428 |
}
|
|
429 |
}
|
|
430 |
}
|
|
431 |
||
432 |
static void |
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
433 |
backup_file (const char *original_filename, const char *extension) |
434 |
{
|
|
435 |
char *template, *backup_filename; |
|
436 |
int result = 0; |
|
437 |
||
438 |
if (g_file_test (original_filename, G_FILE_TEST_EXISTS) == FALSE) |
|
439 |
{
|
|
440 |
return; |
|
441 |
}
|
|
442 |
||
443 |
template = g_strconcat (original_filename, ".backup-XXXXXX", NULL); |
|
444 |
backup_filename = ephy_file_tmp_filename (template, extension); |
|
445 |
||
446 |
if (backup_filename != NULL) |
|
447 |
{
|
|
448 |
result = rename (original_filename, backup_filename); |
|
449 |
}
|
|
450 |
||
451 |
if (result >= 0) |
|
452 |
{
|
|
453 |
g_message ("Your old bookmarks file was backed up as \"%s\".\n", |
|
454 |
backup_filename); |
|
455 |
}
|
|
456 |
else
|
|
457 |
{
|
|
458 |
g_warning ("Backup failed! Your old bookmarks file was lost.\n"); |
|
459 |
}
|
|
460 |
||
461 |
g_free (template); |
|
462 |
g_free (backup_filename); |
|
463 |
}
|
|
464 |
||
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
465 |
/* C&P adapted from gnome-vfs-dns-sd.c */
|
466 |
static GHashTable * |
|
467 |
decode_txt_record (AvahiStringList *input_text) |
|
468 |
{
|
|
469 |
GHashTable *hash; |
|
470 |
int i; |
|
471 |
int len; |
|
472 |
char *key, *value, *end; |
|
473 |
char *key_dup, *value_dup; |
|
474 |
char *raw_txt; |
|
475 |
size_t raw_txt_len; |
|
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
476 |
|
477 |
if (!input_text) |
|
478 |
return NULL; |
|
479 |
||
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
480 |
raw_txt_len = avahi_string_list_serialize (input_text, NULL, 0); |
481 |
raw_txt = g_malloc (raw_txt_len); |
|
482 |
raw_txt_len = avahi_string_list_serialize (input_text, raw_txt, raw_txt_len); |
|
483 |
||
484 |
if (raw_txt == NULL) |
|
485 |
return NULL; |
|
486 |
||
487 |
hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); |
|
488 |
||
489 |
i = 0; |
|
490 |
while (i < raw_txt_len) { |
|
491 |
len = raw_txt[i++]; |
|
492 |
||
493 |
if (i + len > raw_txt_len) { |
|
494 |
break; |
|
495 |
}
|
|
496 |
||
497 |
if (len == 0) { |
|
498 |
continue; |
|
499 |
}
|
|
500 |
||
501 |
key = &raw_txt[i]; |
|
502 |
end = &raw_txt[i + len]; |
|
503 |
i += len; |
|
504 |
||
505 |
if (*key == '=') { |
|
506 |
/* 6.4 - silently ignore keys starting with = */
|
|
507 |
continue; |
|
508 |
}
|
|
509 |
||
510 |
value = memchr (key, '=', len); |
|
511 |
if (value) { |
|
512 |
key_dup = g_strndup (key, value - key); |
|
513 |
value++; /* Skip '=' */ |
|
514 |
value_dup = g_strndup (value, end - value); |
|
515 |
} else { |
|
516 |
key_dup = g_strndup (key, len); |
|
517 |
value_dup = NULL; |
|
518 |
}
|
|
519 |
if (!g_hash_table_lookup_extended (hash, |
|
520 |
key_dup, |
|
521 |
NULL, NULL)) { |
|
522 |
g_hash_table_insert (hash, |
|
523 |
key_dup, |
|
524 |
value_dup); |
|
525 |
} else { |
|
526 |
g_free (key_dup); |
|
527 |
g_free (value_dup); |
|
528 |
}
|
|
529 |
}
|
|
530 |
||
531 |
return hash; |
|
532 |
}
|
|
533 |
||
534 |
/* End of copied code */
|
|
535 |
||
1.1.5
by Sebastien Bacher
Import upstream version 1.9.7 |
536 |
static char * |
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
537 |
get_id_for_response (const char *type, |
538 |
const char *domain, |
|
539 |
const char *name) |
|
1.1.5
by Sebastien Bacher
Import upstream version 1.9.7 |
540 |
{
|
541 |
/* FIXME: limit length! */
|
|
542 |
return g_strdup_printf ("%s\1%s\1%s", |
|
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
543 |
type, |
544 |
domain, |
|
545 |
name); |
|
1.1.5
by Sebastien Bacher
Import upstream version 1.9.7 |
546 |
}
|
547 |
||
548 |
typedef struct |
|
549 |
{
|
|
550 |
EphyBookmarks *bookmarks; |
|
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
551 |
GaServiceResolver *resolver; |
1.1.5
by Sebastien Bacher
Import upstream version 1.9.7 |
552 |
EphyNode *node; |
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
553 |
char *name; |
554 |
char *type; |
|
555 |
char *domain; |
|
1.1.5
by Sebastien Bacher
Import upstream version 1.9.7 |
556 |
} ResolveData; |
557 |
||
1
by Sebastien Bacher
Import upstream version 1.9.2 |
558 |
static void |
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
559 |
resolver_found_cb (GaServiceResolver *resolver, |
560 |
int interface, |
|
561 |
GaProtocol protocol, |
|
562 |
const char *name, |
|
563 |
const char *type, |
|
564 |
const char *domain, |
|
565 |
const char *host_name, |
|
566 |
const AvahiAddress *address, |
|
567 |
guint16 port, |
|
568 |
AvahiStringList *txt, |
|
569 |
glong flags, |
|
570 |
ResolveData *data) |
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
571 |
{
|
1.1.5
by Sebastien Bacher
Import upstream version 1.9.7 |
572 |
EphyBookmarks *bookmarks = data->bookmarks; |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
573 |
EphyBookmarksPrivate *priv = bookmarks->priv; |
574 |
GValue value = { 0, }; |
|
575 |
const char *path = NULL; |
|
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
576 |
char host[128]; |
577 |
GHashTable *text_table; |
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
578 |
char *url; |
1.1.10
by Sebastien Bacher
Import upstream version 2.14.1.1 |
579 |
gboolean was_immutable; |
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
580 |
gboolean is_new_node = FALSE; |
1.1.11
by Sebastien Bacher
Import upstream version 2.15.3 |
581 |
guint i; |
1.1.10
by Sebastien Bacher
Import upstream version 2.14.1.1 |
582 |
|
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
583 |
LOG ("resolver_found_cb resolver %p\n", resolver); |
584 |
||
1.1.10
by Sebastien Bacher
Import upstream version 2.14.1.1 |
585 |
was_immutable = ephy_node_db_is_immutable (priv->db); |
586 |
ephy_node_db_set_immutable (priv->db, FALSE); |
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
587 |
|
1.1.11
by Sebastien Bacher
Import upstream version 2.15.3 |
588 |
/* Find the protocol */
|
589 |
for (i = 0; i < G_N_ELEMENTS (zeroconf_protos); ++i) |
|
590 |
{
|
|
591 |
char proto[20]; |
|
592 |
||
593 |
g_snprintf (proto, sizeof (proto), "_%s._tcp", zeroconf_protos[i]); |
|
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
594 |
if (strcmp (type, proto) == 0) break; |
1.1.11
by Sebastien Bacher
Import upstream version 2.15.3 |
595 |
}
|
596 |
if (i == G_N_ELEMENTS (zeroconf_protos)) return; |
|
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
597 |
|
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
598 |
if (address == NULL) |
599 |
{
|
|
600 |
g_warning ("Zeroconf failed to resolve host %s", name); |
|
601 |
return; |
|
602 |
}
|
|
603 |
||
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
604 |
text_table = decode_txt_record (txt); |
1.1.11
by Sebastien Bacher
Import upstream version 2.15.3 |
605 |
|
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
606 |
if (text_table != NULL) |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
607 |
{
|
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
608 |
path = g_hash_table_lookup (text_table, "path"); |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
609 |
}
|
610 |
if (path == NULL || path[0] == '\0') |
|
611 |
{
|
|
612 |
path = "/"; |
|
613 |
}
|
|
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
614 |
|
615 |
avahi_address_snprint (host, sizeof (host), address); |
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
616 |
|
1.1.11
by Sebastien Bacher
Import upstream version 2.15.3 |
617 |
LOG ("0conf RESOLVED type=%s domain=%s name=%s => proto=%s host=%s port=%d path=%s\n", |
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
618 |
type, domain, name, |
619 |
zeroconf_protos[i], host, port, path); |
|
1.1.5
by Sebastien Bacher
Import upstream version 1.9.7 |
620 |
|
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
621 |
was_immutable = ephy_node_db_is_immutable (priv->db); |
622 |
ephy_node_db_set_immutable (priv->db, FALSE); |
|
623 |
||
624 |
if (data->node == NULL) |
|
625 |
{
|
|
626 |
is_new_node = TRUE; |
|
627 |
||
628 |
data->node = ephy_node_new (priv->db); |
|
629 |
g_assert (data->node != NULL); |
|
630 |
||
631 |
/* don't allow dragging this node */
|
|
632 |
ephy_node_set_is_drag_source (data->node, FALSE); |
|
633 |
||
634 |
g_value_init (&value, G_TYPE_STRING); |
|
635 |
g_value_take_string (&value, |
|
636 |
get_id_for_response (data->type, |
|
637 |
data->domain, |
|
638 |
data->name)); |
|
639 |
ephy_node_set_property (data->node, EPHY_NODE_BMK_PROP_SERVICE_ID, &value); |
|
640 |
g_value_unset (&value); |
|
641 |
||
642 |
/* FIXME: limit length! */
|
|
643 |
ephy_node_set_property_string (data->node, |
|
644 |
EPHY_NODE_BMK_PROP_TITLE, |
|
645 |
name); |
|
646 |
||
647 |
ephy_node_set_property_boolean (data->node, |
|
648 |
EPHY_NODE_BMK_PROP_IMMUTABLE, |
|
649 |
TRUE); |
|
650 |
}
|
|
651 |
||
1.1.5
by Sebastien Bacher
Import upstream version 1.9.7 |
652 |
/* FIXME: limit length! */
|
1.1.11
by Sebastien Bacher
Import upstream version 2.15.3 |
653 |
url = g_strdup_printf ("%s://%s:%d%s", zeroconf_protos[i], host, port, path); |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
654 |
|
655 |
g_value_init (&value, G_TYPE_STRING); |
|
656 |
g_value_take_string (&value, url); |
|
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
657 |
ephy_node_set_property (data->node, EPHY_NODE_BMK_PROP_LOCATION, &value); |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
658 |
g_value_unset (&value); |
659 |
||
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
660 |
if (is_new_node) |
1.1.5
by Sebastien Bacher
Import upstream version 1.9.7 |
661 |
{
|
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
662 |
ephy_node_add_child (priv->bookmarks, data->node); |
663 |
ephy_node_add_child (priv->local, data->node); |
|
1.1.5
by Sebastien Bacher
Import upstream version 1.9.7 |
664 |
}
|
1.1.10
by Sebastien Bacher
Import upstream version 2.14.1.1 |
665 |
|
666 |
ephy_node_db_set_immutable (priv->db, was_immutable); |
|
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
667 |
|
1.1.44
by Sebastien Bacher
Import upstream version 2.25.91 |
668 |
if (text_table != NULL) |
669 |
{
|
|
670 |
g_hash_table_unref (text_table); |
|
671 |
}
|
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
672 |
}
|
673 |
||
674 |
static void |
|
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
675 |
resolver_failure_cb (GaServiceResolver *resolver, |
676 |
GError *error, |
|
677 |
ResolveData *data) |
|
678 |
{
|
|
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
679 |
LOG ("resolver_failure_cb resolver %p: %s\n", resolver, error?error->message:"(null)"); |
680 |
||
681 |
/* Remove the node, if present */
|
|
682 |
if (data->node != NULL) |
|
683 |
{
|
|
684 |
EphyBookmarks *bookmarks = data->bookmarks; |
|
685 |
EphyBookmarksPrivate *priv = bookmarks->priv; |
|
686 |
gboolean was_immutable; |
|
687 |
||
688 |
was_immutable = ephy_node_db_is_immutable (priv->db); |
|
689 |
ephy_node_db_set_immutable (priv->db, FALSE); |
|
690 |
ephy_node_unref (data->node); |
|
691 |
data->node = NULL; |
|
692 |
ephy_node_db_set_immutable (priv->db, was_immutable); |
|
693 |
}
|
|
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
694 |
}
|
695 |
||
696 |
static void |
|
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
697 |
resolve_data_free (ResolveData* data) |
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
698 |
{
|
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
699 |
if (data->resolver) |
700 |
g_object_unref (data->resolver); |
|
701 |
||
702 |
g_free (data->type); |
|
703 |
g_free (data->name); |
|
704 |
g_free (data->domain); |
|
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
705 |
g_slice_free (ResolveData, data); |
706 |
}
|
|
707 |
||
708 |
static void |
|
709 |
browser_new_service_cb (GaServiceBrowser *browser, |
|
710 |
int interface, |
|
711 |
GaProtocol protocol, |
|
712 |
const char *name, |
|
713 |
const char *type, |
|
714 |
const char *domain, |
|
715 |
glong flags, |
|
716 |
EphyBookmarks *bookmarks) |
|
717 |
{
|
|
718 |
EphyBookmarksPrivate *priv = bookmarks->priv; |
|
1.1.5
by Sebastien Bacher
Import upstream version 1.9.7 |
719 |
ResolveData *data; |
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
720 |
char *node_id; |
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
721 |
GError *error = NULL; |
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
722 |
|
723 |
node_id = get_id_for_response (type, domain, name); |
|
724 |
||
1.1.5
by Sebastien Bacher
Import upstream version 1.9.7 |
725 |
LOG ("0conf ADD: type=%s domain=%s name=%s\n", |
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
726 |
type, domain, name); |
727 |
||
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
728 |
if (g_hash_table_lookup (priv->resolve_handles, node_id) != NULL) |
1.1.5
by Sebastien Bacher
Import upstream version 1.9.7 |
729 |
{
|
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
730 |
g_free (node_id); |
731 |
return; |
|
1.1.5
by Sebastien Bacher
Import upstream version 1.9.7 |
732 |
}
|
733 |
||
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
734 |
data = g_slice_new0 (ResolveData); |
1.1.5
by Sebastien Bacher
Import upstream version 1.9.7 |
735 |
data->bookmarks = bookmarks; |
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
736 |
data->node = NULL; |
737 |
data->type = g_strdup (type); |
|
738 |
data->name = g_strdup (name); |
|
739 |
data->domain = g_strdup (domain); |
|
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
740 |
|
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
741 |
data->resolver = ga_service_resolver_new (AVAHI_IF_UNSPEC, |
742 |
AVAHI_PROTO_UNSPEC, |
|
743 |
name, type, domain, |
|
744 |
AVAHI_PROTO_UNSPEC, |
|
745 |
GA_LOOKUP_USE_MULTICAST); |
|
746 |
g_signal_connect (data->resolver, "found", |
|
747 |
G_CALLBACK (resolver_found_cb), data); |
|
748 |
g_signal_connect (data->resolver, "failure", |
|
749 |
G_CALLBACK (resolver_failure_cb), data); |
|
750 |
if (!ga_service_resolver_attach (data->resolver, |
|
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
751 |
priv->ga_client, |
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
752 |
&error)) |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
753 |
{
|
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
754 |
g_warning ("Unable to resolve Zeroconf service %s: %s", name, error ? error->message : "(null)"); |
755 |
g_clear_error (&error); |
|
756 |
resolve_data_free (data); |
|
757 |
g_free (node_id); |
|
1.1.5
by Sebastien Bacher
Import upstream version 1.9.7 |
758 |
return; |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
759 |
}
|
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
760 |
|
1.1.5
by Sebastien Bacher
Import upstream version 1.9.7 |
761 |
g_hash_table_insert (priv->resolve_handles, |
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
762 |
node_id /* transfer ownership */, data); |
763 |
}
|
|
764 |
||
765 |
static void |
|
766 |
browser_removed_service_cb (GaServiceBrowser *browser, |
|
767 |
int interface, |
|
768 |
GaProtocol protocol, |
|
769 |
const char *name, |
|
770 |
const char *type, |
|
771 |
const char *domain, |
|
772 |
glong flags, |
|
773 |
EphyBookmarks *bookmarks) |
|
774 |
{
|
|
775 |
EphyBookmarksPrivate *priv = bookmarks->priv; |
|
776 |
char *node_id; |
|
777 |
ResolveData *data; |
|
778 |
||
779 |
node_id = get_id_for_response (type, domain, name); |
|
780 |
data = g_hash_table_lookup (priv->resolve_handles, node_id); |
|
781 |
/* shouldn't really happen, but let's play safe */
|
|
782 |
if (!data) |
|
783 |
{
|
|
784 |
g_free (node_id); |
|
785 |
return; |
|
786 |
}
|
|
787 |
||
788 |
if (data->node != NULL) |
|
789 |
{
|
|
790 |
gboolean was_immutable; |
|
791 |
||
792 |
was_immutable = ephy_node_db_is_immutable (priv->db); |
|
793 |
ephy_node_db_set_immutable (priv->db, FALSE); |
|
794 |
ephy_node_unref (data->node); |
|
795 |
data->node = NULL; |
|
796 |
ephy_node_db_set_immutable (priv->db, was_immutable); |
|
797 |
}
|
|
798 |
||
799 |
g_hash_table_remove (priv->resolve_handles, node_id); |
|
800 |
g_free (node_id); |
|
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
801 |
}
|
802 |
||
803 |
static void |
|
804 |
start_browsing (GaClient *ga_client, |
|
805 |
EphyBookmarks *bookmarks) |
|
806 |
{
|
|
807 |
EphyBookmarksPrivate *priv = bookmarks->priv; |
|
808 |
guint i; |
|
809 |
||
810 |
for (i = 0; i < G_N_ELEMENTS (zeroconf_protos); ++i) |
|
811 |
{
|
|
812 |
GaServiceBrowser *browser = NULL; |
|
813 |
char proto[20]; |
|
814 |
||
815 |
g_snprintf (proto, sizeof (proto), "_%s._tcp", zeroconf_protos[i]); |
|
816 |
||
817 |
browser = ga_service_browser_new (proto); |
|
818 |
g_signal_connect (browser, "new-service", |
|
819 |
G_CALLBACK (browser_new_service_cb), bookmarks); |
|
820 |
g_signal_connect (browser, "removed-service", |
|
821 |
G_CALLBACK (browser_removed_service_cb), bookmarks); |
|
822 |
if (!ga_service_browser_attach (browser, |
|
823 |
ga_client, |
|
824 |
NULL)) |
|
825 |
{
|
|
826 |
g_warning ("Unable to start Zeroconf subsystem"); |
|
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
827 |
g_object_unref (browser); |
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
828 |
return; |
829 |
}
|
|
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
830 |
|
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
831 |
priv->browse_handles[i] = browser; |
832 |
}
|
|
833 |
}
|
|
834 |
||
835 |
static void |
|
836 |
ga_client_state_changed_cb (GaClient *ga_client, |
|
837 |
GaClientState state, |
|
838 |
EphyBookmarks *bookmarks) |
|
839 |
{
|
|
840 |
if (state == GA_CLIENT_STATE_FAILURE) |
|
841 |
{
|
|
842 |
if (avahi_client_errno (ga_client->avahi_client) == AVAHI_ERR_DISCONNECTED) |
|
843 |
{
|
|
1.1.38
by Sebastien Bacher
Import upstream version 2.22.3 |
844 |
EphyBookmarksPrivate *priv = bookmarks->priv; |
845 |
||
846 |
g_object_unref (priv->ga_client); |
|
847 |
priv->ga_client = NULL; |
|
848 |
||
849 |
ephy_local_bookmarks_start_client (bookmarks); |
|
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
850 |
}
|
851 |
}
|
|
852 |
if (state == GA_CLIENT_STATE_S_RUNNING) |
|
853 |
{
|
|
854 |
start_browsing (ga_client, bookmarks); |
|
855 |
}
|
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
856 |
}
|
857 |
||
858 |
static void |
|
1.1.38
by Sebastien Bacher
Import upstream version 2.22.3 |
859 |
ephy_local_bookmarks_start_client (EphyBookmarks *bookmarks) |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
860 |
{
|
861 |
EphyBookmarksPrivate *priv = bookmarks->priv; |
|
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
862 |
GaClient *ga_client; |
863 |
||
864 |
ga_client = ga_client_new (GA_CLIENT_FLAG_NO_FAIL); |
|
865 |
g_signal_connect (ga_client, "state-changed", |
|
866 |
G_CALLBACK (ga_client_state_changed_cb), |
|
867 |
bookmarks); |
|
868 |
if (!ga_client_start (ga_client, NULL)) |
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
869 |
{
|
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
870 |
g_warning ("Unable to start Zeroconf subsystem"); |
1.1.38
by Sebastien Bacher
Import upstream version 2.22.3 |
871 |
g_object_unref (ga_client); |
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
872 |
return; |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
873 |
}
|
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
874 |
priv->ga_client = ga_client; |
1.1.38
by Sebastien Bacher
Import upstream version 2.22.3 |
875 |
}
|
876 |
||
877 |
static void |
|
878 |
ephy_local_bookmarks_init (EphyBookmarks *bookmarks) |
|
879 |
{
|
|
880 |
EphyBookmarksPrivate *priv = bookmarks->priv; |
|
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
881 |
priv->resolve_handles = g_hash_table_new_full (g_str_hash, g_str_equal, |
882 |
g_free, |
|
883 |
(GDestroyNotify) resolve_data_free); |
|
1.1.38
by Sebastien Bacher
Import upstream version 2.22.3 |
884 |
ephy_local_bookmarks_start_client (bookmarks); |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
885 |
}
|
886 |
||
887 |
static void |
|
888 |
ephy_local_bookmarks_stop (EphyBookmarks *bookmarks) |
|
889 |
{
|
|
890 |
EphyBookmarksPrivate *priv = bookmarks->priv; |
|
1.1.11
by Sebastien Bacher
Import upstream version 2.15.3 |
891 |
guint i; |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
892 |
|
1.1.11
by Sebastien Bacher
Import upstream version 2.15.3 |
893 |
for (i = 0; i < G_N_ELEMENTS (zeroconf_protos); ++i) |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
894 |
{
|
1.1.11
by Sebastien Bacher
Import upstream version 2.15.3 |
895 |
if (priv->browse_handles[i] != NULL) |
896 |
{
|
|
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
897 |
g_object_unref (priv->browse_handles[i]); |
1.1.11
by Sebastien Bacher
Import upstream version 2.15.3 |
898 |
priv->browse_handles[i] = NULL; |
899 |
}
|
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
900 |
}
|
901 |
||
1.1.5
by Sebastien Bacher
Import upstream version 1.9.7 |
902 |
if (priv->resolve_handles != NULL) |
903 |
{
|
|
904 |
g_hash_table_destroy (priv->resolve_handles); |
|
905 |
priv->resolve_handles = NULL; |
|
906 |
}
|
|
1.1.11
by Sebastien Bacher
Import upstream version 2.15.3 |
907 |
|
908 |
if (priv->local != NULL) |
|
909 |
{
|
|
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
910 |
ephy_node_unref (priv->local); |
911 |
priv->local = NULL; |
|
1.1.11
by Sebastien Bacher
Import upstream version 2.15.3 |
912 |
}
|
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
913 |
|
914 |
if (priv->ga_client != NULL) |
|
915 |
{
|
|
916 |
g_object_unref (priv->ga_client); |
|
917 |
priv->ga_client = NULL; |
|
918 |
}
|
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
919 |
}
|
920 |
||
921 |
static void |
|
922 |
ephy_bookmarks_init (EphyBookmarks *eb) |
|
923 |
{
|
|
924 |
EphyNodeDb *db; |
|
925 |
||
1.1.18
by Sebastien Bacher
Import upstream version 2.17.4 |
926 |
/* Translators: this topic contains all bookmarks */
|
1.1.48
by Gustavo Noronha Silva
Import upstream version 2.28.0 |
927 |
const char *bk_all = C_("bookmarks", "All"); |
1.1.18
by Sebastien Bacher
Import upstream version 2.17.4 |
928 |
|
929 |
/* Translators: this topic contains the not categorized
|
|
930 |
bookmarks */
|
|
1.1.48
by Gustavo Noronha Silva
Import upstream version 2.28.0 |
931 |
const char *bk_not_categorized = C_("bookmarks", "Not Categorized"); |
1.1.18
by Sebastien Bacher
Import upstream version 2.17.4 |
932 |
|
933 |
/* Translators: this is an automatic topic containing local
|
|
934 |
* websites bookmarks autodiscovered with zeroconf. */
|
|
1.1.48
by Gustavo Noronha Silva
Import upstream version 2.28.0 |
935 |
const char *bk_local_sites = C_("bookmarks", "Nearby Sites"); |
1.1.18
by Sebastien Bacher
Import upstream version 2.17.4 |
936 |
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
937 |
eb->priv = EPHY_BOOKMARKS_GET_PRIVATE (eb); |
938 |
||
939 |
db = ephy_node_db_new (EPHY_NODE_DB_BOOKMARKS); |
|
940 |
eb->priv->db = db; |
|
941 |
||
942 |
eb->priv->xml_file = g_build_filename (ephy_dot_dir (), |
|
1.8.9
by Gustavo Noronha Silva
Import upstream version 3.7.91 |
943 |
EPHY_BOOKMARKS_FILE, |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
944 |
NULL); |
945 |
eb->priv->rdf_file = g_build_filename (ephy_dot_dir (), |
|
1.8.9
by Gustavo Noronha Silva
Import upstream version 3.7.91 |
946 |
EPHY_BOOKMARKS_FILE_RDF, |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
947 |
NULL); |
948 |
||
949 |
/* Bookmarks */
|
|
950 |
eb->priv->bookmarks = ephy_node_new_with_id (db, BOOKMARKS_NODE_ID); |
|
1.1.18
by Sebastien Bacher
Import upstream version 2.17.4 |
951 |
|
952 |
ephy_node_set_property_string (eb->priv->bookmarks, |
|
953 |
EPHY_NODE_KEYWORD_PROP_NAME, |
|
954 |
bk_all); |
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
955 |
ephy_node_signal_connect_object (eb->priv->bookmarks, |
956 |
EPHY_NODE_CHILD_REMOVED, |
|
957 |
(EphyNodeCallback) bookmarks_removed_cb, |
|
958 |
G_OBJECT (eb)); |
|
959 |
ephy_node_signal_connect_object (eb->priv->bookmarks, |
|
960 |
EPHY_NODE_CHILD_CHANGED, |
|
961 |
(EphyNodeCallback) bookmarks_changed_cb, |
|
962 |
G_OBJECT (eb)); |
|
963 |
||
964 |
/* Keywords */
|
|
965 |
eb->priv->keywords = ephy_node_new_with_id (db, KEYWORDS_NODE_ID); |
|
1.1.18
by Sebastien Bacher
Import upstream version 2.17.4 |
966 |
ephy_node_set_property_int (eb->priv->bookmarks, |
967 |
EPHY_NODE_KEYWORD_PROP_PRIORITY, |
|
968 |
EPHY_NODE_ALL_PRIORITY); |
|
969 |
||
1
by Sebastien Bacher
Import upstream version 1.9.2 |
970 |
ephy_node_signal_connect_object (eb->priv->keywords, |
971 |
EPHY_NODE_CHILD_REMOVED, |
|
972 |
(EphyNodeCallback) topics_removed_cb, |
|
973 |
G_OBJECT (eb)); |
|
974 |
||
975 |
ephy_node_add_child (eb->priv->keywords, |
|
976 |
eb->priv->bookmarks); |
|
977 |
||
978 |
/* Not categorized */
|
|
979 |
eb->priv->notcategorized = ephy_node_new_with_id (db, BMKS_NOTCATEGORIZED_NODE_ID); |
|
1.1.18
by Sebastien Bacher
Import upstream version 2.17.4 |
980 |
|
981 |
||
982 |
ephy_node_set_property_string (eb->priv->notcategorized, |
|
983 |
EPHY_NODE_KEYWORD_PROP_NAME, |
|
984 |
bk_not_categorized); |
|
985 |
||
986 |
ephy_node_set_property_int (eb->priv->notcategorized, |
|
987 |
EPHY_NODE_KEYWORD_PROP_PRIORITY, |
|
988 |
EPHY_NODE_SPECIAL_PRIORITY); |
|
989 |
||
1
by Sebastien Bacher
Import upstream version 1.9.2 |
990 |
ephy_node_add_child (eb->priv->keywords, eb->priv->notcategorized); |
991 |
||
992 |
/* Local Websites */
|
|
993 |
eb->priv->local = ephy_node_new_with_id (db, BMKS_LOCAL_NODE_ID); |
|
994 |
||
995 |
/* don't allow drags to this topic */
|
|
996 |
ephy_node_set_is_drag_dest (eb->priv->local, FALSE); |
|
997 |
||
1.1.18
by Sebastien Bacher
Import upstream version 2.17.4 |
998 |
|
999 |
ephy_node_set_property_string (eb->priv->local, |
|
1000 |
EPHY_NODE_KEYWORD_PROP_NAME, |
|
1001 |
bk_local_sites); |
|
1002 |
ephy_node_set_property_int (eb->priv->local, |
|
1003 |
EPHY_NODE_KEYWORD_PROP_PRIORITY, |
|
1004 |
EPHY_NODE_SPECIAL_PRIORITY); |
|
1005 |
||
1
by Sebastien Bacher
Import upstream version 1.9.2 |
1006 |
ephy_node_add_child (eb->priv->keywords, eb->priv->local); |
1007 |
ephy_local_bookmarks_init (eb); |
|
1008 |
||
1009 |
/* Smart bookmarks */
|
|
1010 |
eb->priv->smartbookmarks = ephy_node_new_with_id (db, SMARTBOOKMARKS_NODE_ID); |
|
1011 |
||
1012 |
if (g_file_test (eb->priv->xml_file, G_FILE_TEST_EXISTS) == FALSE |
|
1013 |
&& g_file_test (eb->priv->rdf_file, G_FILE_TEST_EXISTS) == FALSE) |
|
1014 |
{
|
|
1015 |
eb->priv->init_defaults = TRUE; |
|
1016 |
}
|
|
1017 |
else if (ephy_node_db_load_from_file (eb->priv->db, eb->priv->xml_file, |
|
1018 |
(xmlChar *) EPHY_BOOKMARKS_XML_ROOT, |
|
1019 |
(xmlChar *) EPHY_BOOKMARKS_XML_VERSION) == FALSE) |
|
1020 |
{
|
|
1021 |
/* save the corrupted files so the user can late try to
|
|
1022 |
* manually recover them. See bug #128308.
|
|
1023 |
*/
|
|
1024 |
||
1025 |
g_warning ("Could not read bookmarks file \"%s\", trying to " |
|
1026 |
"re-import bookmarks from \"%s\"\n", |
|
1027 |
eb->priv->xml_file, eb->priv->rdf_file); |
|
1028 |
||
1029 |
backup_file (eb->priv->xml_file, "xml"); |
|
1030 |
||
1031 |
if (ephy_bookmarks_import_rdf (eb, eb->priv->rdf_file) == FALSE) |
|
1032 |
{
|
|
1033 |
backup_file (eb->priv->rdf_file, "rdf"); |
|
1034 |
||
1035 |
eb->priv->init_defaults = TRUE; |
|
1036 |
}
|
|
1037 |
}
|
|
1038 |
||
1039 |
if (eb->priv->init_defaults) |
|
1040 |
{
|
|
1041 |
ephy_bookmarks_init_defaults (eb); |
|
1042 |
}
|
|
1.1.5
by Sebastien Bacher
Import upstream version 1.9.7 |
1043 |
|
1044 |
fix_hierarchy (eb); |
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
1045 |
|
1.1.62
by Emilio Pozuelo Monfort
Import upstream version 2.91.5 |
1046 |
g_settings_bind (EPHY_SETTINGS_LOCKDOWN, |
1047 |
EPHY_PREFS_LOCKDOWN_BOOKMARK_EDITING, |
|
1048 |
eb->priv->db, "immutable", |
|
1049 |
G_SETTINGS_BIND_GET); |
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
1050 |
|
1051 |
ephy_setup_history_notifiers (eb); |
|
1052 |
}
|
|
1053 |
||
1054 |
static void |
|
1055 |
ephy_bookmarks_finalize (GObject *object) |
|
1056 |
{
|
|
1057 |
EphyBookmarks *eb = EPHY_BOOKMARKS (object); |
|
1.1.5
by Sebastien Bacher
Import upstream version 1.9.7 |
1058 |
EphyBookmarksPrivate *priv = eb->priv; |
1059 |
||
1060 |
if (priv->save_timeout_id != 0) |
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
1061 |
{
|
1.1.5
by Sebastien Bacher
Import upstream version 1.9.7 |
1062 |
g_source_remove (priv->save_timeout_id); |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
1063 |
}
|
1064 |
||
1.1.5
by Sebastien Bacher
Import upstream version 1.9.7 |
1065 |
ephy_bookmarks_save (eb); |
1066 |
||
1
by Sebastien Bacher
Import upstream version 1.9.2 |
1067 |
ephy_local_bookmarks_stop (eb); |
1068 |
||
1.1.5
by Sebastien Bacher
Import upstream version 1.9.7 |
1069 |
ephy_node_unref (priv->bookmarks); |
1070 |
ephy_node_unref (priv->keywords); |
|
1071 |
ephy_node_unref (priv->notcategorized); |
|
1.1.62
by Emilio Pozuelo Monfort
Import upstream version 2.91.5 |
1072 |
ephy_node_unref (priv->smartbookmarks); |
1.1.5
by Sebastien Bacher
Import upstream version 1.9.7 |
1073 |
|
1074 |
g_object_unref (priv->db); |
|
1075 |
||
1076 |
g_free (priv->xml_file); |
|
1077 |
g_free (priv->rdf_file); |
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
1078 |
|
1079 |
LOG ("Bookmarks finalized"); |
|
1080 |
||
1.1.37
by Alexander Sack
Import upstream version 2.22.1.1 |
1081 |
G_OBJECT_CLASS (ephy_bookmarks_parent_class)->finalize (object); |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
1082 |
}
|
1083 |
||
1084 |
EphyBookmarks * |
|
1085 |
ephy_bookmarks_new (void) |
|
1086 |
{
|
|
1.1.5
by Sebastien Bacher
Import upstream version 1.9.7 |
1087 |
return EPHY_BOOKMARKS (g_object_new (EPHY_TYPE_BOOKMARKS, NULL)); |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
1088 |
}
|
1089 |
||
1090 |
static void |
|
1091 |
update_has_smart_address (EphyBookmarks *bookmarks, EphyNode *bmk, const char *address) |
|
1092 |
{
|
|
1093 |
EphyNode *smart_bmks; |
|
1094 |
gboolean smart = FALSE, with_options = FALSE; |
|
1095 |
||
1096 |
smart_bmks = bookmarks->priv->smartbookmarks; |
|
1097 |
||
1098 |
if (address) |
|
1099 |
{
|
|
1100 |
smart = strstr (address, "%s") != NULL; |
|
1101 |
with_options = strstr (address, "%s%{") != NULL; |
|
1102 |
}
|
|
1103 |
||
1104 |
/* if we have a smart bookmark with width specification,
|
|
1105 |
* remove from smart bookmarks first to force an update
|
|
1106 |
* in the toolbar
|
|
1107 |
*/
|
|
1108 |
if (smart && with_options) |
|
1109 |
{
|
|
1.1.16
by Sebastien Bacher
Import upstream version 2.17.2 |
1110 |
if (ephy_node_has_child (smart_bmks, bmk)) |
1111 |
{
|
|
1112 |
ephy_node_remove_child (smart_bmks, bmk); |
|
1113 |
}
|
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
1114 |
ephy_node_add_child (smart_bmks, bmk); |
1115 |
}
|
|
1116 |
else if (smart) |
|
1117 |
{
|
|
1118 |
if (!ephy_node_has_child (smart_bmks, bmk)) |
|
1119 |
{
|
|
1120 |
ephy_node_add_child (smart_bmks, bmk); |
|
1121 |
}
|
|
1122 |
}
|
|
1123 |
else
|
|
1124 |
{
|
|
1125 |
if (ephy_node_has_child (smart_bmks, bmk)) |
|
1126 |
{
|
|
1127 |
ephy_node_remove_child (smart_bmks, bmk); |
|
1128 |
}
|
|
1129 |
}
|
|
1130 |
}
|
|
1131 |
||
1132 |
EphyNode * |
|
1133 |
ephy_bookmarks_add (EphyBookmarks *eb, |
|
1134 |
const char *title, |
|
1135 |
const char *url) |
|
1136 |
{
|
|
1137 |
EphyNode *bm; |
|
1.8.1
by Jeremy Bicha
Import upstream version 3.3.92 |
1138 |
WebKitFaviconDatabase *favicon_database; |
1.8.16
by Michael Biebl
Import upstream version 3.16.1 |
1139 |
EphyEmbedShell *shell = ephy_embed_shell_get_default (); |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
1140 |
|
1141 |
bm = ephy_node_new (eb->priv->db); |
|
1142 |
||
1143 |
if (bm == NULL) return NULL; |
|
1.1.3
by Sebastien Bacher
Import upstream version 1.9.5.1 |
1144 |
|
1145 |
if (url == NULL) return NULL; |
|
1.1.18
by Sebastien Bacher
Import upstream version 2.17.4 |
1146 |
ephy_node_set_property_string (bm, EPHY_NODE_BMK_PROP_LOCATION, url); |
1147 |
||
1.1.3
by Sebastien Bacher
Import upstream version 1.9.5.1 |
1148 |
if (title == NULL || title[0] == '\0') |
1149 |
{
|
|
1150 |
title = _("Untitled"); |
|
1.1.18
by Sebastien Bacher
Import upstream version 2.17.4 |
1151 |
}
|
1152 |
ephy_node_set_property_string (bm, EPHY_NODE_BMK_PROP_TITLE, title); |
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
1153 |
|
1.8.16
by Michael Biebl
Import upstream version 3.16.1 |
1154 |
favicon_database = webkit_web_context_get_favicon_database (ephy_embed_shell_get_web_context (shell)); |
1.8.1
by Jeremy Bicha
Import upstream version 3.3.92 |
1155 |
if (favicon_database != NULL) |
1.1.3
by Sebastien Bacher
Import upstream version 1.9.5.1 |
1156 |
{
|
1.8.5
by Jeremy Bicha
Import upstream version 3.5.3 |
1157 |
char *icon = webkit_favicon_database_get_favicon_uri (favicon_database, url); |
1.1.3
by Sebastien Bacher
Import upstream version 1.9.5.1 |
1158 |
if (icon != NULL) |
1159 |
{
|
|
1.1.18
by Sebastien Bacher
Import upstream version 2.17.4 |
1160 |
ephy_node_set_property_string
|
1161 |
(bm, EPHY_NODE_BMK_PROP_ICON, icon); |
|
1.8.5
by Jeremy Bicha
Import upstream version 3.5.3 |
1162 |
g_free (icon); |
1.1.3
by Sebastien Bacher
Import upstream version 1.9.5.1 |
1163 |
}
|
1164 |
}
|
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
1165 |
|
1166 |
update_has_smart_address (eb, bm, url); |
|
1167 |
update_bookmark_keywords (eb, bm); |
|
1168 |
||
1169 |
ephy_node_add_child (eb->priv->bookmarks, bm); |
|
1170 |
ephy_node_add_child (eb->priv->notcategorized, bm); |
|
1171 |
||
1172 |
ephy_bookmarks_save_delayed (eb, 0); |
|
1173 |
||
1174 |
return bm; |
|
1175 |
}
|
|
1176 |
||
1177 |
void
|
|
1178 |
ephy_bookmarks_set_address (EphyBookmarks *eb, |
|
1179 |
EphyNode *bookmark, |
|
1180 |
const char *address) |
|
1181 |
{
|
|
1.1.18
by Sebastien Bacher
Import upstream version 2.17.4 |
1182 |
ephy_node_set_property_string (bookmark, EPHY_NODE_BMK_PROP_LOCATION, |
1183 |
address); |
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
1184 |
|
1185 |
update_has_smart_address (eb, bookmark, address); |
|
1186 |
}
|
|
1187 |
||
1188 |
EphyNode * |
|
1189 |
ephy_bookmarks_find_bookmark (EphyBookmarks *eb, |
|
1190 |
const char *url) |
|
1191 |
{
|
|
1192 |
GPtrArray *children; |
|
1193 |
int i; |
|
1194 |
||
1195 |
g_return_val_if_fail (EPHY_IS_BOOKMARKS (eb), NULL); |
|
1196 |
g_return_val_if_fail (eb->priv->bookmarks != NULL, NULL); |
|
1197 |
g_return_val_if_fail (url != NULL, NULL); |
|
1198 |
||
1199 |
children = ephy_node_get_children (eb->priv->bookmarks); |
|
1200 |
for (i = 0; i < children->len; i++) |
|
1201 |
{
|
|
1202 |
EphyNode *kid; |
|
1203 |
const char *location; |
|
1204 |
||
1205 |
kid = g_ptr_array_index (children, i); |
|
1206 |
location = ephy_node_get_property_string |
|
1207 |
(kid, EPHY_NODE_BMK_PROP_LOCATION); |
|
1208 |
||
1209 |
if (location != NULL && strcmp (url, location) == 0) |
|
1210 |
{
|
|
1211 |
return kid; |
|
1212 |
}
|
|
1213 |
}
|
|
1214 |
||
1215 |
return NULL; |
|
1216 |
}
|
|
1217 |
||
1.1.4
by Sebastien Bacher
Import upstream version 1.9.6 |
1218 |
static gboolean |
1219 |
is_similar (const char *url1, const char *url2) |
|
1220 |
{
|
|
1.1.5
by Sebastien Bacher
Import upstream version 1.9.7 |
1221 |
int i, j; |
1222 |
||
1223 |
for (i = 0; url1[i]; i++) |
|
1224 |
if (url1[i] == '#' || url1[i] == '?') |
|
1225 |
break; |
|
1226 |
while(i>0 && url1[i] == '/') |
|
1227 |
i--; |
|
1228 |
||
1229 |
for (j = 0; url2[j]; j++) |
|
1230 |
if (url2[j] == '#' || url2[j] == '?') |
|
1231 |
break; |
|
1232 |
while(j>0 && url2[j] == '/') |
|
1233 |
j--; |
|
1234 |
||
1235 |
if (i != j) return FALSE; |
|
1236 |
if (strncmp (url1, url2, i) != 0) return FALSE; |
|
1237 |
return TRUE; |
|
1.1.4
by Sebastien Bacher
Import upstream version 1.9.6 |
1238 |
}
|
1239 |
||
1240 |
gint
|
|
1241 |
ephy_bookmarks_get_similar (EphyBookmarks *eb, |
|
1242 |
EphyNode *bookmark, |
|
1243 |
GPtrArray *identical, |
|
1244 |
GPtrArray *similar) |
|
1245 |
{
|
|
1246 |
GPtrArray *children; |
|
1247 |
const char *url; |
|
1248 |
int i, result; |
|
1249 |
||
1250 |
g_return_val_if_fail (EPHY_IS_BOOKMARKS (eb), -1); |
|
1251 |
g_return_val_if_fail (eb->priv->bookmarks != NULL, -1); |
|
1252 |
g_return_val_if_fail (bookmark != NULL, -1); |
|
1253 |
||
1254 |
url = ephy_node_get_property_string |
|
1255 |
(bookmark, EPHY_NODE_BMK_PROP_LOCATION); |
|
1256 |
||
1257 |
g_return_val_if_fail (url != NULL, -1); |
|
1258 |
||
1259 |
result = 0; |
|
1260 |
||
1261 |
children = ephy_node_get_children (eb->priv->bookmarks); |
|
1262 |
for (i = 0; i < children->len; i++) |
|
1263 |
{
|
|
1264 |
EphyNode *kid; |
|
1265 |
const char *location; |
|
1266 |
||
1267 |
kid = g_ptr_array_index (children, i); |
|
1268 |
if (kid == bookmark) |
|
1269 |
{
|
|
1270 |
continue; |
|
1271 |
}
|
|
1272 |
||
1273 |
location = ephy_node_get_property_string |
|
1274 |
(kid, EPHY_NODE_BMK_PROP_LOCATION); |
|
1275 |
||
1276 |
if (location != NULL) |
|
1277 |
{
|
|
1278 |
if(identical != NULL && strcmp (url, location) == 0) |
|
1279 |
{
|
|
1280 |
g_ptr_array_add (identical, kid); |
|
1281 |
result++; |
|
1282 |
}
|
|
1283 |
else if(is_similar (url, location)) |
|
1284 |
{
|
|
1285 |
if (similar != NULL) |
|
1286 |
{
|
|
1287 |
g_ptr_array_add (similar, kid); |
|
1288 |
}
|
|
1289 |
result++; |
|
1290 |
}
|
|
1291 |
}
|
|
1292 |
}
|
|
1293 |
||
1294 |
return result; |
|
1295 |
}
|
|
1296 |
||
1
by Sebastien Bacher
Import upstream version 1.9.2 |
1297 |
void
|
1298 |
ephy_bookmarks_set_icon (EphyBookmarks *eb, |
|
1299 |
const char *url, |
|
1300 |
const char *icon) |
|
1301 |
{
|
|
1302 |
EphyNode *node; |
|
1303 |
||
1304 |
g_return_if_fail (icon != NULL); |
|
1305 |
||
1306 |
node = ephy_bookmarks_find_bookmark (eb, url); |
|
1307 |
if (node == NULL) return; |
|
1308 |
||
1.1.18
by Sebastien Bacher
Import upstream version 2.17.4 |
1309 |
ephy_node_set_property_string (node, EPHY_NODE_BMK_PROP_ICON, icon); |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
1310 |
}
|
1311 |
||
1.1.3
by Sebastien Bacher
Import upstream version 1.9.5.1 |
1312 |
|
1313 |
void
|
|
1314 |
ephy_bookmarks_set_usericon (EphyBookmarks *eb, |
|
1315 |
const char *url, |
|
1316 |
const char *icon) |
|
1317 |
{
|
|
1318 |
EphyNode *node; |
|
1319 |
||
1320 |
g_return_if_fail (icon != NULL); |
|
1321 |
||
1322 |
node = ephy_bookmarks_find_bookmark (eb, url); |
|
1323 |
if (node == NULL) return; |
|
1324 |
||
1.1.18
by Sebastien Bacher
Import upstream version 2.17.4 |
1325 |
ephy_node_set_property_string (node, EPHY_NODE_BMK_PROP_USERICON, |
1326 |
icon); |
|
1.1.3
by Sebastien Bacher
Import upstream version 1.9.5.1 |
1327 |
}
|
1328 |
||
1329 |
||
1
by Sebastien Bacher
Import upstream version 1.9.2 |
1330 |
/* name must end with '=' */
|
1331 |
static char * |
|
1332 |
get_option (char *start, |
|
1333 |
const char *name, |
|
1334 |
char **optionsend) |
|
1335 |
{
|
|
1336 |
char *end, *p; |
|
1337 |
||
1338 |
*optionsend = start; |
|
1339 |
||
1340 |
if (start == NULL || start[0] != '%' || start[1] != '{') return NULL; |
|
1341 |
start += 2; |
|
1342 |
||
1343 |
end = strstr (start, "}"); |
|
1344 |
if (end == NULL) return NULL; |
|
1345 |
*optionsend = end + 1; |
|
1346 |
||
1347 |
start = strstr (start, name); |
|
1348 |
if (start == NULL || start > end) return NULL; |
|
1349 |
start += strlen (name); |
|
1350 |
||
1351 |
/* Find end of option, either ',' or '}' */
|
|
1352 |
end = strstr (start, ","); |
|
1353 |
if (end == NULL || end >= *optionsend) end = *optionsend - 1; |
|
1354 |
||
1355 |
/* limit option length and sanity-check it */
|
|
1356 |
if (end - start > 32) return NULL; |
|
1357 |
for (p = start; p < end; ++p) |
|
1358 |
{
|
|
1359 |
if (!g_ascii_isalnum (*p)) return NULL; |
|
1360 |
}
|
|
1361 |
||
1362 |
return g_strndup (start, end - start); |
|
1363 |
}
|
|
1364 |
||
1365 |
static char * |
|
1366 |
impl_resolve_address (EphyBookmarks *eb, |
|
1367 |
const char *address, |
|
1368 |
const char *content) |
|
1369 |
{
|
|
1370 |
GString *result; |
|
1371 |
char *pos, *oldpos, *arg, *escaped_arg, *encoding, *optionsend; |
|
1372 |
||
1373 |
if (address == NULL) return NULL; |
|
1374 |
if (content == NULL) content = ""; |
|
1375 |
||
1376 |
result = g_string_new_len (NULL, strlen (content) + strlen (address)); |
|
1377 |
||
1378 |
/* substitute %s's */
|
|
1379 |
oldpos = (char*) address; |
|
1380 |
while ((pos = strstr (oldpos, "%s")) != NULL) |
|
1381 |
{
|
|
1382 |
g_string_append_len (result, oldpos, pos - oldpos); |
|
1383 |
pos += 2; |
|
1384 |
||
1385 |
encoding = get_option (pos, "encoding=", &optionsend); |
|
1386 |
if (encoding != NULL) |
|
1387 |
{
|
|
1388 |
GError *error = NULL; |
|
1389 |
||
1390 |
arg = g_convert (content, strlen (content), encoding, |
|
1391 |
"UTF-8", NULL, NULL, &error); |
|
1392 |
if (error != NULL) |
|
1393 |
{
|
|
1394 |
g_warning ("Error when converting arg to encoding '%s': %s\n", |
|
1395 |
encoding, error->message); |
|
1396 |
g_error_free (error); |
|
1397 |
}
|
|
1398 |
else
|
|
1399 |
{
|
|
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
1400 |
escaped_arg = g_uri_escape_string (arg, NULL, TRUE); |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
1401 |
g_string_append (result, escaped_arg); |
1402 |
g_free (escaped_arg); |
|
1403 |
g_free (arg); |
|
1404 |
}
|
|
1405 |
||
1406 |
g_free (encoding); |
|
1407 |
}
|
|
1408 |
else
|
|
1409 |
{
|
|
1.1.34
by Alexander Sack
Import upstream version 2.21.90 |
1410 |
arg = g_uri_escape_string (content, NULL, TRUE); |
1
by Sebastien Bacher
Import upstream version 1.9.2 |
1411 |
g_string_append (result, arg); |
1412 |
g_free (arg); |
|
1413 |
}
|
|
1414 |
||
1415 |
oldpos = optionsend; |
|
1416 |
}
|
|
1417 |
g_string_append (result, oldpos); |
|
1418 |
||
1419 |
return g_string_free (result, FALSE); |
|
1420 |
}
|
|
1421 |
||
1422 |
char * |
|
1423 |
ephy_bookmarks_resolve_address (EphyBookmarks *eb, |
|
1424 |
const char *address, |
|
1425 |
const char *parameter) |
|
1426 |
{
|
|
1427 |
char *retval = NULL; |
|
1428 |
||
1429 |
g_return_val_if_fail (EPHY_IS_BOOKMARKS (eb), NULL); |
|
1430 |
g_return_val_if_fail (address != NULL, NULL); |
|
1431 |
||
1432 |
g_signal_emit (eb, ephy_bookmarks_signals[RESOLVE_ADDRESS], 0, |
|
1433 |
address, parameter, &retval); |
|
1434 |
||
1435 |
return retval; |
|
1436 |
}
|
|
1437 |
||
1438 |
guint
|
|
1439 |
ephy_bookmarks_get_smart_bookmark_width (EphyNode *bookmark) |
|
1440 |
{
|
|
1441 |
const char *url; |
|
1442 |
char *option, *end, *number; |
|
1443 |
guint width; |
|
1444 |
||
1445 |
url = ephy_node_get_property_string (bookmark, EPHY_NODE_BMK_PROP_LOCATION); |
|
1446 |
if (url == NULL) return 0; |
|
1447 |
||
1448 |
/* this takes the first %s, but that's okay since we only support one text entry box */
|
|
1449 |
option = strstr (url, "%s%{"); |
|
1450 |
if (option == NULL) return 0; |
|
1451 |
option += 2; |
|
1452 |
||
1453 |
number = get_option (option, "width=", &end); |
|
1454 |
if (number == NULL) return 0; |
|
1455 |
||
1456 |
width = (guint) g_ascii_strtoull (number, NULL, 10); |
|
1457 |
g_free (number); |
|
1458 |
||
1459 |
return CLAMP (width, 1, 64); |
|
1460 |
}
|
|
1461 |
||
1462 |
EphyNode * |
|
1463 |
ephy_bookmarks_add_keyword (EphyBookmarks *eb, |
|
1464 |
const char *name) |
|
1465 |
{
|
|
1466 |
EphyNode *key; |
|
1467 |
||
1468 |
key = ephy_node_new (eb->priv->db); |
|
1469 |
||
1470 |
if (key == NULL) return NULL; |
|
1471 |
||
1.1.18
by Sebastien Bacher
Import upstream version 2.17.4 |
1472 |
ephy_node_set_property_string (key, EPHY_NODE_KEYWORD_PROP_NAME, |
1473 |
name); |
|
1474 |
ephy_node_set_property_int (key, EPHY_NODE_KEYWORD_PROP_PRIORITY, |
|
1475 |
EPHY_NODE_NORMAL_PRIORITY); |
|
1476 |
||
1
by Sebastien Bacher
Import upstream version 1.9.2 |
1477 |
ephy_node_add_child (eb->priv->keywords, key); |
1478 |
||
1479 |
return key; |
|
1480 |
}
|
|
1481 |
||
1482 |
void
|
|
1483 |
ephy_bookmarks_remove_keyword (EphyBookmarks *eb, |
|
1484 |
EphyNode *keyword) |
|
1485 |
{
|
|
1486 |
ephy_node_remove_child (eb->priv->keywords, keyword); |
|
1487 |
}
|
|
1488 |
||
1489 |
char * |
|
1490 |
ephy_bookmarks_get_topic_uri (EphyBookmarks *eb, |
|
1491 |
EphyNode *node) |
|
1492 |
{
|
|
1493 |
char *uri; |
|
1494 |
||
1495 |
if (ephy_bookmarks_get_bookmarks (eb) == node) |
|
1496 |
{
|
|
1497 |
uri = g_strdup ("topic://Special/All"); |
|
1498 |
}
|
|
1499 |
else if (ephy_bookmarks_get_not_categorized (eb) == node) |
|
1500 |
{
|
|
1501 |
uri = g_strdup ("topic://Special/NotCategorized"); |
|
1502 |
}
|
|
1503 |
else if (ephy_bookmarks_get_local (eb) == node) |
|
1504 |
{
|
|
1.1.27
by Sebastien Bacher
Import upstream version 2.19.6 |
1505 |
/* Note: do not change to "Nearby" because of existing custom toolbars */
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
1506 |
uri = g_strdup ("topic://Special/Local"); |
1507 |
}
|
|
1508 |
else
|
|
1509 |
{
|
|
1510 |
const char *name; |
|
1511 |
||
1512 |
name = ephy_node_get_property_string |
|
1513 |
(node, EPHY_NODE_KEYWORD_PROP_NAME); |
|
1514 |
||
1515 |
uri = g_strdup_printf ("topic://%s", name); |
|
1516 |
}
|
|
1517 |
||
1518 |
return uri; |
|
1519 |
}
|
|
1520 |
||
1521 |
EphyNode * |
|
1522 |
ephy_bookmarks_find_keyword (EphyBookmarks *eb, |
|
1523 |
const char *name, |
|
1524 |
gboolean partial_match) |
|
1525 |
{
|
|
1526 |
EphyNode *node; |
|
1527 |
GPtrArray *children; |
|
1528 |
int i; |
|
1529 |
const char *topic_name; |
|
1530 |
||
1531 |
g_return_val_if_fail (name != NULL, NULL); |
|
1532 |
||
1533 |
topic_name = name; |
|
1534 |
||
1535 |
if (g_utf8_strlen (name, -1) == 0) |
|
1536 |
{
|
|
1537 |
LOG ("Empty name, no keyword matches."); |
|
1538 |
return NULL; |
|
1539 |
}
|
|
1540 |
||
1541 |
if (strcmp (name, "topic://Special/All") == 0) |
|
1542 |
{
|
|
1543 |
return ephy_bookmarks_get_bookmarks (eb); |
|
1544 |
}
|
|
1545 |
else if (strcmp (name, "topic://Special/NotCategorized") == 0) |
|
1546 |
{
|
|
1547 |
return ephy_bookmarks_get_not_categorized (eb); |
|
1548 |
}
|
|
1549 |
else if (strcmp (name, "topic://Special/Local") == 0) |
|
1550 |
{
|
|
1551 |
return ephy_bookmarks_get_local (eb); |
|
1552 |
}
|
|
1553 |
else if (g_str_has_prefix (name, "topic://")) |
|
1554 |
{
|
|
1555 |
topic_name += strlen ("topic://"); |
|
1556 |
}
|
|
1557 |
||
1558 |
children = ephy_node_get_children (eb->priv->keywords); |
|
1559 |
node = NULL; |
|
1560 |
for (i = 0; i < children->len; i++) |
|
1561 |
{
|
|
1562 |
EphyNode *kid; |
|
1563 |
const char *key; |
|
1564 |
||
1565 |
kid = g_ptr_array_index (children, i); |
|
1566 |
key = ephy_node_get_property_string (kid, EPHY_NODE_KEYWORD_PROP_NAME); |
|
1567 |
||
1568 |
if ((partial_match && g_str_has_prefix (key, topic_name) > 0) || |
|
1569 |
(!partial_match && strcmp (key, topic_name) == 0)) |
|
1570 |
{
|
|
1571 |
node = kid; |
|
1572 |
}
|
|
1573 |
}
|
|
1574 |
||
1575 |
return node; |
|
1576 |
}
|
|
1577 |
||
1578 |
gboolean
|
|
1579 |
ephy_bookmarks_has_keyword (EphyBookmarks *eb, |
|
1580 |
EphyNode *keyword, |
|
1581 |
EphyNode *bookmark) |
|
1582 |
{
|
|
1583 |
return ephy_node_has_child (keyword, bookmark); |
|
1584 |
}
|
|
1585 |
||
1586 |
void
|
|
1587 |
ephy_bookmarks_set_keyword (EphyBookmarks *eb, |
|
1588 |
EphyNode *keyword, |
|
1589 |
EphyNode *bookmark) |
|
1590 |
{
|
|
1591 |
if (ephy_node_has_child (keyword, bookmark)) return; |
|
1592 |
||
1593 |
ephy_node_add_child (keyword, bookmark); |
|
1594 |
||
1595 |
if (ephy_node_has_child (eb->priv->notcategorized, bookmark)) |
|
1596 |
{
|
|
1597 |
LOG ("Remove from categorized bookmarks"); |
|
1598 |
ephy_node_remove_child
|
|
1599 |
(eb->priv->notcategorized, bookmark); |
|
1600 |
}
|
|
1601 |
||
1602 |
update_bookmark_keywords (eb, bookmark); |
|
1603 |
||
1604 |
g_signal_emit (G_OBJECT (eb), ephy_bookmarks_signals[TREE_CHANGED], 0); |
|
1605 |
}
|
|
1606 |
||
1607 |
void
|
|
1608 |
ephy_bookmarks_unset_keyword (EphyBookmarks *eb, |
|
1609 |
EphyNode *keyword, |
|
1610 |
EphyNode *bookmark) |
|
1611 |
{
|
|
1612 |
if (!ephy_node_has_child (keyword, bookmark)) return; |
|
1613 |
||
1614 |
ephy_node_remove_child (keyword, bookmark); |
|
1615 |
||
1616 |
if (!bookmark_is_categorized (eb, bookmark) && |
|
1617 |
!ephy_node_has_child (eb->priv->notcategorized, bookmark)) |
|
1618 |
{
|
|
1619 |
LOG ("Add to not categorized bookmarks"); |
|
1620 |
ephy_node_add_child
|
|
1621 |
(eb->priv->notcategorized, bookmark); |
|
1622 |
}
|
|
1623 |
||
1624 |
update_bookmark_keywords (eb, bookmark); |
|
1625 |
||
1626 |
g_signal_emit (G_OBJECT (eb), ephy_bookmarks_signals[TREE_CHANGED], 0); |
|
1627 |
}
|
|
1628 |
||
1.1.51
by Sebastian Dröge
Import upstream version 2.29.3 |
1629 |
/**
|
1630 |
* ephy_bookmarks_get_smart_bookmarks:
|
|
1631 |
*
|
|
1632 |
* Return value: (transfer none):
|
|
1633 |
**/
|
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
1634 |
EphyNode * |
1635 |
ephy_bookmarks_get_smart_bookmarks (EphyBookmarks *eb) |
|
1636 |
{
|
|
1637 |
return eb->priv->smartbookmarks; |
|
1638 |
}
|
|
1639 |
||
1.1.51
by Sebastian Dröge
Import upstream version 2.29.3 |
1640 |
/**
|
1641 |
* ephy_bookmarks_get_keywords:
|
|
1642 |
*
|
|
1643 |
* Return value: (transfer none):
|
|
1644 |
**/
|
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
1645 |
EphyNode * |
1646 |
ephy_bookmarks_get_keywords (EphyBookmarks *eb) |
|
1647 |
{
|
|
1648 |
return eb->priv->keywords; |
|
1649 |
}
|
|
1650 |
||
1.1.51
by Sebastian Dröge
Import upstream version 2.29.3 |
1651 |
/**
|
1652 |
* ephy_bookmarks_get_bookmarks:
|
|
1653 |
*
|
|
1654 |
* Return value: (transfer none):
|
|
1655 |
**/
|
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
1656 |
EphyNode * |
1657 |
ephy_bookmarks_get_bookmarks (EphyBookmarks *eb) |
|
1658 |
{
|
|
1659 |
return eb->priv->bookmarks; |
|
1660 |
}
|
|
1661 |
||
1.1.51
by Sebastian Dröge
Import upstream version 2.29.3 |
1662 |
/**
|
1663 |
* ephy_bookmarks_get_local:
|
|
1664 |
*
|
|
1665 |
* Return value: (transfer none):
|
|
1666 |
**/
|
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
1667 |
EphyNode * |
1668 |
ephy_bookmarks_get_local (EphyBookmarks *eb) |
|
1669 |
{
|
|
1670 |
return eb->priv->local; |
|
1671 |
}
|
|
1672 |
||
1.1.51
by Sebastian Dröge
Import upstream version 2.29.3 |
1673 |
/**
|
1674 |
* ephy_bookmarks_get_not_categorized:
|
|
1675 |
*
|
|
1676 |
* Return value: (transfer none):
|
|
1677 |
**/
|
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
1678 |
EphyNode * |
1679 |
ephy_bookmarks_get_not_categorized (EphyBookmarks *eb) |
|
1680 |
{
|
|
1681 |
return eb->priv->notcategorized; |
|
1682 |
}
|
|
1683 |
||
1.1.51
by Sebastian Dröge
Import upstream version 2.29.3 |
1684 |
/**
|
1685 |
* ephy_bookmarks_get_from_id:
|
|
1686 |
*
|
|
1687 |
* Return value: (transfer none):
|
|
1688 |
**/
|
|
1
by Sebastien Bacher
Import upstream version 1.9.2 |
1689 |
EphyNode * |
1690 |
ephy_bookmarks_get_from_id (EphyBookmarks *eb, long id) |
|
1691 |
{
|
|
1692 |
return ephy_node_db_get_node_from_id (eb->priv->db, id); |
|
1693 |
}
|
|
1694 |
||
1695 |
int
|
|
1696 |
ephy_bookmarks_compare_topics (gconstpointer a, gconstpointer b) |
|
1697 |
{
|
|
1698 |
EphyNode *node_a = (EphyNode *)a; |
|
1699 |
EphyNode *node_b = (EphyNode *)b; |
|
1700 |
const char *title1, *title2; |
|
1701 |
int priority1, priority2; |
|
1702 |
||
1703 |
priority1 = ephy_node_get_property_int (node_a, EPHY_NODE_KEYWORD_PROP_PRIORITY); |
|
1704 |
priority2 = ephy_node_get_property_int (node_b, EPHY_NODE_KEYWORD_PROP_PRIORITY); |
|
1705 |
||
1706 |
if (priority1 > priority2) return 1; |
|
1707 |
if (priority1 < priority2) return -1; |
|
1708 |
||
1709 |
title1 = ephy_node_get_property_string (node_a, EPHY_NODE_KEYWORD_PROP_NAME); |
|
1710 |
title2 = ephy_node_get_property_string (node_b, EPHY_NODE_KEYWORD_PROP_NAME); |
|
1711 |
||
1712 |
if (title1 == title2) return 0; |
|
1713 |
if (title1 == NULL) return -1; |
|
1714 |
if (title2 == NULL) return 1; |
|
1715 |
return g_utf8_collate (title1, title2); |
|
1716 |
}
|
|
1717 |
||
1718 |
int
|
|
1719 |
ephy_bookmarks_compare_topic_pointers (gconstpointer a, gconstpointer b) |
|
1720 |
{
|
|
1721 |
EphyNode *node_a = *(EphyNode **)a; |
|
1722 |
EphyNode *node_b = *(EphyNode **)b; |
|
1723 |
||
1724 |
return ephy_bookmarks_compare_topics (node_a, node_b); |
|
1725 |
}
|
|
1726 |
||
1727 |
int
|
|
1728 |
ephy_bookmarks_compare_bookmarks (gconstpointer a, gconstpointer b) |
|
1729 |
{
|
|
1730 |
EphyNode *node_a = (EphyNode *)a; |
|
1731 |
EphyNode *node_b = (EphyNode *)b; |
|
1732 |
const char *title1, *title2; |
|
1733 |
||
1734 |
title1 = ephy_node_get_property_string (node_a, EPHY_NODE_BMK_PROP_TITLE); |
|
1735 |
title2 = ephy_node_get_property_string (node_b, EPHY_NODE_BMK_PROP_TITLE); |
|
1736 |
||
1737 |
if (title1 == title2) return 0; |
|
1738 |
if (title1 == NULL) return -1; |
|
1739 |
if (title2 == NULL) return 1; |
|
1740 |
return g_utf8_collate (title1, title2); |
|
1741 |
}
|
|
1742 |
||
1743 |
int
|
|
1744 |
ephy_bookmarks_compare_bookmark_pointers (gconstpointer a, gconstpointer b) |
|
1745 |
{
|
|
1746 |
EphyNode *node_a = *(EphyNode **)a; |
|
1747 |
EphyNode *node_b = *(EphyNode **)b; |
|
1748 |
||
1749 |
return ephy_bookmarks_compare_bookmarks (node_a, node_b); |
|
1750 |
}
|