| File: | libslab/bookmark-agent.c |
| Warning: | line 1107, column 5 Null pointer passed to 1st parameter expecting 'nonnull' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* | |||
| 2 | * This file is part of the Main Menu. | |||
| 3 | * | |||
| 4 | * Copyright (c) 2007 Novell, Inc. | |||
| 5 | * | |||
| 6 | * The Main Menu is free software; you can redistribute it and/or modify it | |||
| 7 | * under the terms of the GNU General Public License as published by the Free | |||
| 8 | * Software Foundation; either version 2 of the License, or (at your option) | |||
| 9 | * any later version. | |||
| 10 | * | |||
| 11 | * The Main Menu is distributed in the hope that it will be useful, but WITHOUT | |||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |||
| 14 | * more details. | |||
| 15 | * | |||
| 16 | * You should have received a copy of the GNU General Public License along with | |||
| 17 | * the Main Menu; if not, write to the Free Software Foundation, Inc., 51 | |||
| 18 | * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |||
| 19 | */ | |||
| 20 | ||||
| 21 | #include "bookmark-agent.h" | |||
| 22 | ||||
| 23 | #ifdef HAVE_CONFIG_H1 | |||
| 24 | # include <config.h> | |||
| 25 | #else | |||
| 26 | # define PACKAGE"cafe-control-center" "cafe-main-menu" | |||
| 27 | #endif | |||
| 28 | ||||
| 29 | #include <ctk/ctk.h> | |||
| 30 | ||||
| 31 | #include <string.h> | |||
| 32 | #include <stdlib.h> | |||
| 33 | #include <glib/gi18n-lib.h> | |||
| 34 | #include <glib/gstdio.h> | |||
| 35 | #include <gio/gio.h> | |||
| 36 | ||||
| 37 | #include "libslab-utils.h" | |||
| 38 | ||||
| 39 | #define USER_APPS_STORE_FILE_NAME"applications.xbel" "applications.xbel" | |||
| 40 | #define USER_DOCS_STORE_FILE_NAME"documents.xbel" "documents.xbel" | |||
| 41 | #define USER_DIRS_STORE_FILE_NAME"places.xbel" "places.xbel" | |||
| 42 | #define SYSTEM_STORE_FILE_NAME"system-items.xbel" "system-items.xbel" | |||
| 43 | #define CALC_TEMPLATE_FILE_NAME"empty.ots" "empty.ots" | |||
| 44 | #define WRITER_TEMPLATE_FILE_NAME"empty.ott" "empty.ott" | |||
| 45 | ||||
| 46 | #define CTK_BOOKMARKS_FILE"bookmarks" "bookmarks" | |||
| 47 | ||||
| 48 | #define TYPE_IS_RECENT(type)((type) == BOOKMARK_STORE_RECENT_APPS || (type) == BOOKMARK_STORE_RECENT_DOCS ) ((type) == BOOKMARK_STORE_RECENT_APPS || (type) == BOOKMARK_STORE_RECENT_DOCS) | |||
| 49 | ||||
| 50 | typedef struct { | |||
| 51 | BookmarkStoreType type; | |||
| 52 | ||||
| 53 | BookmarkItem **items; | |||
| 54 | gint n_items; | |||
| 55 | BookmarkStoreStatus status; | |||
| 56 | ||||
| 57 | GBookmarkFile *store; | |||
| 58 | gboolean needs_sync; | |||
| 59 | ||||
| 60 | gchar *store_path; | |||
| 61 | gchar *user_store_path; | |||
| 62 | gboolean user_modifiable; | |||
| 63 | gboolean reorderable; | |||
| 64 | const gchar *store_filename; | |||
| 65 | ||||
| 66 | GFileMonitor *store_monitor; | |||
| 67 | GFileMonitor *user_store_monitor; | |||
| 68 | ||||
| 69 | void (* update_path) (BookmarkAgent *); | |||
| 70 | void (* load_store) (BookmarkAgent *); | |||
| 71 | void (* save_store) (BookmarkAgent *); | |||
| 72 | void (* create_item) (BookmarkAgent *, const gchar *); | |||
| 73 | ||||
| 74 | gchar *ctk_store_path; | |||
| 75 | GFileMonitor *ctk_store_monitor; | |||
| 76 | } BookmarkAgentPrivate; | |||
| 77 | ||||
| 78 | enum { | |||
| 79 | PROP_0, | |||
| 80 | PROP_ITEMS, | |||
| 81 | PROP_STATUS | |||
| 82 | }; | |||
| 83 | ||||
| 84 | static BookmarkAgent *instances [BOOKMARK_STORE_N_TYPES]; | |||
| 85 | ||||
| 86 | static BookmarkAgentClass *bookmark_agent_parent_class = NULL((void*)0); | |||
| 87 | ||||
| 88 | static void bookmark_agent_base_init (BookmarkAgentClass *); | |||
| 89 | static void bookmark_agent_class_init (BookmarkAgentClass *); | |||
| 90 | static void bookmark_agent_init (BookmarkAgent *); | |||
| 91 | static BookmarkAgent *bookmark_agent_new (BookmarkStoreType ); | |||
| 92 | ||||
| 93 | static void get_property (GObject *, guint, GValue *, GParamSpec *); | |||
| 94 | static void set_property (GObject *, guint, const GValue *, GParamSpec *); | |||
| 95 | static void finalize (GObject *); | |||
| 96 | ||||
| 97 | static void update_agent (BookmarkAgent *); | |||
| 98 | static void update_items (BookmarkAgent *); | |||
| 99 | static void save_store (BookmarkAgent *); | |||
| 100 | static gint get_rank (BookmarkAgent *, const gchar *); | |||
| 101 | static void set_rank (BookmarkAgent *, const gchar *, gint); | |||
| 102 | ||||
| 103 | static void load_xbel_store (BookmarkAgent *); | |||
| 104 | static void load_places_store (BookmarkAgent *); | |||
| 105 | static void update_user_spec_path (BookmarkAgent *); | |||
| 106 | static void save_xbel_store (BookmarkAgent *); | |||
| 107 | static void create_app_item (BookmarkAgent *, const gchar *); | |||
| 108 | static void create_doc_item (BookmarkAgent *, const gchar *); | |||
| 109 | static void create_dir_item (BookmarkAgent *, const gchar *); | |||
| 110 | ||||
| 111 | static void store_monitor_cb (GFileMonitor *, GFile *, GFile *, | |||
| 112 | GFileMonitorEvent, gpointer); | |||
| 113 | static void weak_destroy_cb (gpointer, GObject *); | |||
| 114 | ||||
| 115 | static gint recent_item_mru_comp_func (gconstpointer a, gconstpointer b); | |||
| 116 | ||||
| 117 | static gchar *find_package_data_file (const gchar *filename); | |||
| 118 | ||||
| 119 | static gint BookmarkAgent_private_offset; | |||
| 120 | ||||
| 121 | static inline gpointer bookmark_agent_get_instance_private (BookmarkAgent *this) | |||
| 122 | { | |||
| 123 | return (G_STRUCT_MEMBER_P (this, BookmarkAgent_private_offset)((gpointer) ((guint8*) (this) + (glong) (BookmarkAgent_private_offset )))); | |||
| 124 | } | |||
| 125 | ||||
| 126 | GType | |||
| 127 | bookmark_agent_get_type () | |||
| 128 | { | |||
| 129 | static GType g_define_type_id = 0; | |||
| 130 | ||||
| 131 | if (G_UNLIKELY (g_define_type_id == 0)(g_define_type_id == 0)) { | |||
| 132 | static const GTypeInfo info = { | |||
| 133 | sizeof (BookmarkAgentClass), | |||
| 134 | (GBaseInitFunc) bookmark_agent_base_init, | |||
| 135 | NULL((void*)0), | |||
| 136 | (GClassInitFunc) bookmark_agent_class_init, | |||
| 137 | NULL((void*)0), NULL((void*)0), | |||
| 138 | sizeof (BookmarkAgent), 0, | |||
| 139 | (GInstanceInitFunc) bookmark_agent_init, | |||
| 140 | NULL((void*)0) | |||
| 141 | }; | |||
| 142 | ||||
| 143 | g_define_type_id = g_type_register_static ( | |||
| 144 | G_TYPE_OBJECT((GType) ((20) << (2))), "BookmarkAgent", & info, 0); | |||
| 145 | G_ADD_PRIVATE (BookmarkAgent){ BookmarkAgent_private_offset = g_type_add_instance_private ( g_define_type_id, sizeof (BookmarkAgentPrivate)); }; | |||
| 146 | } | |||
| 147 | ||||
| 148 | return g_define_type_id; | |||
| 149 | } | |||
| 150 | ||||
| 151 | BookmarkAgent * | |||
| 152 | bookmark_agent_get_instance (BookmarkStoreType type) | |||
| 153 | { | |||
| 154 | g_return_val_if_fail (0 <= type, NULL)do { if ((0 <= type)) { } else { g_return_if_fail_warning ( "libslab", ((const char*) (__func__)), "0 <= type"); return (((void*)0)); } } while (0); | |||
| 155 | g_return_val_if_fail (type < BOOKMARK_STORE_N_TYPES, NULL)do { if ((type < BOOKMARK_STORE_N_TYPES)) { } else { g_return_if_fail_warning ("libslab", ((const char*) (__func__)), "type < BOOKMARK_STORE_N_TYPES" ); return (((void*)0)); } } while (0); | |||
| 156 | ||||
| 157 | if (! instances [type]) { | |||
| 158 | instances [type] = bookmark_agent_new (type); | |||
| 159 | g_object_weak_ref (G_OBJECT (instances [type])((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((instances [type])), (((GType) ((20) << (2)))))))), weak_destroy_cb, GINT_TO_POINTER (type)((gpointer) (glong) (type))); | |||
| 160 | } | |||
| 161 | else | |||
| 162 | g_object_ref (G_OBJECT (instances [type]))((__typeof__ (((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((instances [type])), (((GType) ((20) << (2)))))))))) (g_object_ref) (((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((instances [type])), (((GType) ((20) << (2)))))))))); | |||
| 163 | ||||
| 164 | return instances [type]; | |||
| 165 | } | |||
| 166 | ||||
| 167 | gboolean | |||
| 168 | bookmark_agent_has_item (BookmarkAgent *this, const gchar *uri) | |||
| 169 | { | |||
| 170 | BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); | |||
| 171 | return g_bookmark_file_has_item (priv->store, uri); | |||
| 172 | } | |||
| 173 | ||||
| 174 | void | |||
| 175 | bookmark_agent_add_item (BookmarkAgent *this, const BookmarkItem *item) | |||
| 176 | { | |||
| 177 | BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); | |||
| 178 | ||||
| 179 | if (! item) | |||
| 180 | return; | |||
| 181 | ||||
| 182 | g_return_if_fail (priv->user_modifiable)do { if ((priv->user_modifiable)) { } else { g_return_if_fail_warning ("libslab", ((const char*) (__func__)), "priv->user_modifiable" ); return; } } while (0); | |||
| 183 | g_return_if_fail (item->uri)do { if ((item->uri)) { } else { g_return_if_fail_warning ( "libslab", ((const char*) (__func__)), "item->uri"); return ; } } while (0); | |||
| 184 | g_return_if_fail (item->mime_type)do { if ((item->mime_type)) { } else { g_return_if_fail_warning ("libslab", ((const char*) (__func__)), "item->mime_type" ); return; } } while (0); | |||
| 185 | ||||
| 186 | g_bookmark_file_set_mime_type (priv->store, item->uri, item->mime_type); | |||
| 187 | ||||
| 188 | if (item->mtime) | |||
| 189 | g_bookmark_file_set_modified (priv->store, item->uri, item->mtime); | |||
| 190 | ||||
| 191 | if (item->title) | |||
| 192 | g_bookmark_file_set_title (priv->store, item->uri, item->title); | |||
| 193 | ||||
| 194 | g_bookmark_file_add_application (priv->store, item->uri, item->app_name, item->app_exec); | |||
| 195 | ||||
| 196 | set_rank (this, item->uri, g_bookmark_file_get_size (priv->store) - 1); | |||
| 197 | ||||
| 198 | save_store (this); | |||
| 199 | } | |||
| 200 | ||||
| 201 | void | |||
| 202 | bookmark_agent_move_item (BookmarkAgent *this, const gchar *uri, const gchar *uri_new) | |||
| 203 | { | |||
| 204 | BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); | |||
| 205 | ||||
| 206 | GError *error = NULL((void*)0); | |||
| 207 | ||||
| 208 | if (! TYPE_IS_RECENT (priv->type)((priv->type) == BOOKMARK_STORE_RECENT_APPS || (priv->type ) == BOOKMARK_STORE_RECENT_DOCS)) | |||
| 209 | return; | |||
| 210 | ||||
| 211 | ctk_recent_manager_move_item (ctk_recent_manager_get_default (), uri, uri_new, &error); | |||
| 212 | if (error) { | |||
| 213 | g_warning ("Unable to update %s with renamed file, [%s] -> [%s]: %s", | |||
| 214 | priv->store_path, uri, uri_new, error->message); | |||
| 215 | g_error_free (error); | |||
| 216 | } | |||
| 217 | } | |||
| 218 | ||||
| 219 | void | |||
| 220 | bookmark_agent_purge_items (BookmarkAgent *this) | |||
| 221 | { | |||
| 222 | BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); | |||
| 223 | ||||
| 224 | GError *error = NULL((void*)0); | |||
| 225 | ||||
| 226 | gchar **uris = NULL((void*)0); | |||
| 227 | gsize uris_len; | |||
| 228 | gint i; | |||
| 229 | g_return_if_fail (priv->user_modifiable)do { if ((priv->user_modifiable)) { } else { g_return_if_fail_warning ("libslab", ((const char*) (__func__)), "priv->user_modifiable" ); return; } } while (0); | |||
| 230 | ||||
| 231 | uris = g_bookmark_file_get_uris (priv->store, &uris_len); | |||
| 232 | if (TYPE_IS_RECENT (priv->type)((priv->type) == BOOKMARK_STORE_RECENT_APPS || (priv->type ) == BOOKMARK_STORE_RECENT_DOCS)) { | |||
| 233 | for (i = 0; i < uris_len; i++) { | |||
| 234 | ctk_recent_manager_remove_item (ctk_recent_manager_get_default (), uris [i], &error); | |||
| 235 | if (error) { | |||
| 236 | g_warning ("Unable to remove [%s] from %s: %s", | |||
| 237 | priv->store_path, uris [i], error->message); | |||
| 238 | g_error_free (error); | |||
| 239 | } | |||
| 240 | } | |||
| 241 | } else { | |||
| 242 | for (i = 0; i < uris_len; i++) { | |||
| 243 | g_bookmark_file_remove_item (priv->store, uris [i], NULL((void*)0)); | |||
| 244 | } | |||
| 245 | save_store (this); | |||
| 246 | } | |||
| 247 | g_strfreev (uris); | |||
| 248 | } | |||
| 249 | ||||
| 250 | void | |||
| 251 | bookmark_agent_remove_item (BookmarkAgent *this, const gchar *uri) | |||
| 252 | { | |||
| 253 | BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); | |||
| 254 | gint rank; | |||
| 255 | ||||
| 256 | GError *error = NULL((void*)0); | |||
| 257 | ||||
| 258 | gchar **uris = NULL((void*)0); | |||
| 259 | gint rank_i; | |||
| 260 | gint i; | |||
| 261 | ||||
| 262 | ||||
| 263 | g_return_if_fail (priv->user_modifiable)do { if ((priv->user_modifiable)) { } else { g_return_if_fail_warning ("libslab", ((const char*) (__func__)), "priv->user_modifiable" ); return; } } while (0); | |||
| 264 | ||||
| 265 | if (! bookmark_agent_has_item (this, uri)) | |||
| 266 | return; | |||
| 267 | ||||
| 268 | if (TYPE_IS_RECENT (priv->type)((priv->type) == BOOKMARK_STORE_RECENT_APPS || (priv->type ) == BOOKMARK_STORE_RECENT_DOCS)) { | |||
| 269 | ctk_recent_manager_remove_item (ctk_recent_manager_get_default (), uri, &error); | |||
| 270 | if (error) { | |||
| 271 | g_warning ("Unable to remove [%s] from %s: %s", priv->store_path, uri, error->message); | |||
| 272 | g_error_free (error); | |||
| 273 | } | |||
| 274 | } | |||
| 275 | else { | |||
| 276 | rank = get_rank (this, uri); | |||
| 277 | ||||
| 278 | g_bookmark_file_remove_item (priv->store, uri, NULL((void*)0)); | |||
| 279 | ||||
| 280 | if (rank >= 0) { | |||
| 281 | uris = g_bookmark_file_get_uris (priv->store, NULL((void*)0)); | |||
| 282 | ||||
| 283 | for (i = 0; uris && uris [i]; ++i) { | |||
| 284 | rank_i = get_rank (this, uris [i]); | |||
| 285 | ||||
| 286 | if (rank_i > rank) | |||
| 287 | set_rank (this, uris [i], rank_i - 1); | |||
| 288 | } | |||
| 289 | ||||
| 290 | g_strfreev (uris); | |||
| 291 | } | |||
| 292 | ||||
| 293 | save_store (this); | |||
| 294 | } | |||
| 295 | } | |||
| 296 | ||||
| 297 | void | |||
| 298 | bookmark_agent_reorder_items (BookmarkAgent *this, const gchar **uris) | |||
| 299 | { | |||
| 300 | BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); | |||
| 301 | ||||
| 302 | gint i; | |||
| 303 | ||||
| 304 | ||||
| 305 | g_return_if_fail (priv->reorderable)do { if ((priv->reorderable)) { } else { g_return_if_fail_warning ("libslab", ((const char*) (__func__)), "priv->reorderable" ); return; } } while (0); | |||
| 306 | ||||
| 307 | for (i = 0; uris && uris [i]; ++i) | |||
| 308 | set_rank (this, uris [i], i); | |||
| 309 | ||||
| 310 | save_store (this); | |||
| 311 | } | |||
| 312 | ||||
| 313 | static GList * | |||
| 314 | make_items_from_bookmark_file (BookmarkAgent *this, GBookmarkFile *store) | |||
| 315 | { | |||
| 316 | BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); | |||
| 317 | gchar **uris; | |||
| 318 | gint i; | |||
| 319 | GList *items_ordered; | |||
| 320 | ||||
| 321 | if (!store) | |||
| 322 | return NULL((void*)0); | |||
| 323 | ||||
| 324 | uris = g_bookmark_file_get_uris (store, NULL((void*)0)); | |||
| 325 | items_ordered = NULL((void*)0); | |||
| 326 | ||||
| 327 | for (i = 0; uris && uris [i]; ++i) { | |||
| 328 | gboolean include; | |||
| 329 | ||||
| 330 | if (priv->type == BOOKMARK_STORE_RECENT_APPS) | |||
| 331 | include = g_bookmark_file_has_group (store, uris [i], "recently-used-apps", NULL((void*)0)); | |||
| 332 | else | |||
| 333 | include = ! g_bookmark_file_get_is_private (store, uris [i], NULL((void*)0)); | |||
| 334 | ||||
| 335 | if (include) { | |||
| 336 | BookmarkItem *item; | |||
| 337 | ||||
| 338 | item = g_new0 (BookmarkItem, 1)((BookmarkItem *) g_malloc0_n ((1), sizeof (BookmarkItem))); | |||
| 339 | ||||
| 340 | item->uri = g_strdup (uris [i])g_strdup_inline (uris [i]); | |||
| 341 | item->mime_type = g_bookmark_file_get_mime_type (store, uris [i], NULL((void*)0)); | |||
| 342 | item->mtime = g_bookmark_file_get_modified (store, uris [i], NULL((void*)0)); | |||
| 343 | ||||
| 344 | items_ordered = g_list_prepend (items_ordered, item); | |||
| 345 | } | |||
| 346 | } | |||
| 347 | ||||
| 348 | items_ordered = g_list_sort (items_ordered, recent_item_mru_comp_func); | |||
| 349 | ||||
| 350 | g_strfreev (uris); | |||
| 351 | ||||
| 352 | return items_ordered; | |||
| 353 | } | |||
| 354 | ||||
| 355 | void | |||
| 356 | bookmark_agent_update_from_bookmark_file (BookmarkAgent *this, GBookmarkFile *store) | |||
| 357 | { | |||
| 358 | BookmarkAgentPrivate *priv; | |||
| 359 | GList *items_ordered; | |||
| 360 | GList *node; | |||
| 361 | ||||
| 362 | g_return_if_fail (IS_BOOKMARK_AGENT (this))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((this)); GType __t = ((bookmark_agent_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("libslab", ((const char*) ( __func__)), "IS_BOOKMARK_AGENT (this)"); return; } } while (0 ); | |||
| 363 | ||||
| 364 | priv = bookmark_agent_get_instance_private (this); | |||
| 365 | ||||
| 366 | items_ordered = make_items_from_bookmark_file (this, store); | |||
| 367 | ||||
| 368 | g_bookmark_file_free (priv->store); | |||
| 369 | priv->store = g_bookmark_file_new (); | |||
| 370 | ||||
| 371 | for (node = items_ordered; node; node = node->next) { | |||
| 372 | BookmarkItem *item; | |||
| 373 | ||||
| 374 | item = (BookmarkItem *) node->data; | |||
| 375 | ||||
| 376 | g_bookmark_file_set_mime_type (priv->store, item->uri, item->mime_type); | |||
| 377 | g_bookmark_file_set_modified (priv->store, item->uri, item->mtime); | |||
| 378 | ||||
| 379 | bookmark_item_free (item); | |||
| 380 | } | |||
| 381 | ||||
| 382 | g_list_free (items_ordered); | |||
| 383 | ||||
| 384 | update_items (this); | |||
| 385 | } | |||
| 386 | ||||
| 387 | void | |||
| 388 | bookmark_item_free (BookmarkItem *item) | |||
| 389 | { | |||
| 390 | if (! item) | |||
| 391 | return; | |||
| 392 | ||||
| 393 | g_free (item->uri); | |||
| 394 | g_free (item->title); | |||
| 395 | g_free (item->mime_type); | |||
| 396 | g_free (item->icon); | |||
| 397 | g_free (item->app_name); | |||
| 398 | g_free (item->app_exec); | |||
| 399 | g_free (item); | |||
| 400 | } | |||
| 401 | ||||
| 402 | static void | |||
| 403 | bookmark_agent_base_init (BookmarkAgentClass *this_class) | |||
| 404 | { | |||
| 405 | gint i; | |||
| 406 | ||||
| 407 | for (i = 0; i < BOOKMARK_STORE_N_TYPES; ++i) | |||
| 408 | instances [i] = NULL((void*)0); | |||
| 409 | } | |||
| 410 | ||||
| 411 | static void | |||
| 412 | bookmark_agent_class_init (BookmarkAgentClass *this_class) | |||
| 413 | { | |||
| 414 | GObjectClass *g_obj_class = G_OBJECT_CLASS (this_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((this_class)), (((GType) ((20) << (2)))))))); | |||
| 415 | ||||
| 416 | GParamSpec *items_pspec; | |||
| 417 | GParamSpec *status_pspec; | |||
| 418 | ||||
| 419 | if (BookmarkAgent_private_offset != 0) | |||
| 420 | g_type_class_adjust_private_offset (this_class, &BookmarkAgent_private_offset); | |||
| 421 | ||||
| 422 | g_obj_class->get_property = get_property; | |||
| 423 | g_obj_class->set_property = set_property; | |||
| 424 | g_obj_class->finalize = finalize; | |||
| 425 | ||||
| 426 | items_pspec = g_param_spec_pointer ( | |||
| 427 | BOOKMARK_AGENT_ITEMS_PROP"items", BOOKMARK_AGENT_ITEMS_PROP"items", | |||
| 428 | "the null-terminated list which contains the bookmark items in this store", | |||
| 429 | G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB); | |||
| 430 | ||||
| 431 | status_pspec = g_param_spec_int ( | |||
| 432 | BOOKMARK_AGENT_STORE_STATUS_PROP"store-status", BOOKMARK_AGENT_STORE_STATUS_PROP"store-status", "the status of the store", | |||
| 433 | BOOKMARK_STORE_DEFAULT_ONLY, BOOKMARK_STORE_USER, BOOKMARK_STORE_DEFAULT, | |||
| 434 | G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB); | |||
| 435 | ||||
| 436 | g_object_class_install_property (g_obj_class, PROP_ITEMS, items_pspec); | |||
| 437 | g_object_class_install_property (g_obj_class, PROP_STATUS, status_pspec); | |||
| 438 | ||||
| 439 | bookmark_agent_parent_class = g_type_class_peek_parent (this_class); | |||
| 440 | } | |||
| 441 | ||||
| 442 | static void | |||
| 443 | bookmark_agent_init (BookmarkAgent *this) | |||
| 444 | { | |||
| 445 | BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); | |||
| 446 | ||||
| 447 | priv->type = -1; | |||
| 448 | ||||
| 449 | priv->items = NULL((void*)0); | |||
| 450 | priv->n_items = 0; | |||
| 451 | priv->status = BOOKMARK_STORE_ABSENT; | |||
| 452 | ||||
| 453 | priv->store = NULL((void*)0); | |||
| 454 | priv->needs_sync = FALSE(0); | |||
| 455 | ||||
| 456 | priv->store_path = NULL((void*)0); | |||
| 457 | priv->user_store_path = NULL((void*)0); | |||
| 458 | priv->user_modifiable = FALSE(0); | |||
| 459 | priv->reorderable = FALSE(0); | |||
| 460 | priv->store_filename = NULL((void*)0); | |||
| 461 | ||||
| 462 | priv->store_monitor = NULL((void*)0); | |||
| 463 | priv->user_store_monitor = NULL((void*)0); | |||
| 464 | ||||
| 465 | priv->update_path = NULL((void*)0); | |||
| 466 | priv->load_store = NULL((void*)0); | |||
| 467 | priv->save_store = NULL((void*)0); | |||
| 468 | priv->create_item = NULL((void*)0); | |||
| 469 | ||||
| 470 | priv->ctk_store_path = NULL((void*)0); | |||
| 471 | priv->ctk_store_monitor = NULL((void*)0); | |||
| 472 | } | |||
| 473 | ||||
| 474 | static BookmarkAgent * | |||
| 475 | bookmark_agent_new (BookmarkStoreType type) | |||
| 476 | { | |||
| 477 | BookmarkAgent *this; | |||
| 478 | BookmarkAgentPrivate *priv; | |||
| 479 | GFile *ctk_store_file; | |||
| 480 | ||||
| 481 | this = g_object_new (BOOKMARK_AGENT_TYPE(bookmark_agent_get_type ()), NULL((void*)0)); | |||
| 482 | priv = bookmark_agent_get_instance_private (this); | |||
| 483 | ||||
| 484 | priv->type = type; | |||
| 485 | priv->store = g_bookmark_file_new (); | |||
| 486 | ||||
| 487 | switch (type) { | |||
| 488 | case BOOKMARK_STORE_USER_APPS: | |||
| 489 | priv->store_filename = USER_APPS_STORE_FILE_NAME"applications.xbel"; | |||
| 490 | priv->create_item = create_app_item; | |||
| 491 | ||||
| 492 | break; | |||
| 493 | ||||
| 494 | case BOOKMARK_STORE_USER_DOCS: | |||
| 495 | priv->store_filename = USER_DOCS_STORE_FILE_NAME"documents.xbel"; | |||
| 496 | priv->create_item = create_doc_item; | |||
| 497 | ||||
| 498 | break; | |||
| 499 | ||||
| 500 | case BOOKMARK_STORE_USER_DIRS: | |||
| 501 | priv->store_filename = USER_DIRS_STORE_FILE_NAME"places.xbel"; | |||
| 502 | priv->create_item = create_dir_item; | |||
| 503 | ||||
| 504 | priv->user_modifiable = TRUE(!(0)); | |||
| 505 | priv->reorderable = FALSE(0); | |||
| 506 | ||||
| 507 | priv->load_store = load_places_store; | |||
| 508 | ||||
| 509 | priv->ctk_store_path = g_build_filename (g_get_user_config_dir (), | |||
| 510 | "ctk-3.0", CTK_BOOKMARKS_FILE"bookmarks", NULL((void*)0)); | |||
| 511 | ctk_store_file = g_file_new_for_path (priv->ctk_store_path); | |||
| 512 | priv->ctk_store_monitor = g_file_monitor_file (ctk_store_file, | |||
| 513 | 0, NULL((void*)0), NULL((void*)0)); | |||
| 514 | if (priv->ctk_store_monitor) { | |||
| 515 | g_signal_connect (priv->ctk_store_monitor, "changed",g_signal_connect_data ((priv->ctk_store_monitor), ("changed" ), (((GCallback) (store_monitor_cb))), (this), ((void*)0), (GConnectFlags ) 0) | |||
| 516 | G_CALLBACK (store_monitor_cb), this)g_signal_connect_data ((priv->ctk_store_monitor), ("changed" ), (((GCallback) (store_monitor_cb))), (this), ((void*)0), (GConnectFlags ) 0); | |||
| 517 | } | |||
| 518 | ||||
| 519 | g_object_unref (ctk_store_file); | |||
| 520 | ||||
| 521 | break; | |||
| 522 | ||||
| 523 | case BOOKMARK_STORE_RECENT_APPS: | |||
| 524 | case BOOKMARK_STORE_RECENT_DOCS: | |||
| 525 | priv->user_modifiable = TRUE(!(0)); | |||
| 526 | priv->reorderable = FALSE(0); | |||
| 527 | ||||
| 528 | priv->store_path = g_build_filename (g_get_user_data_dir (), "recently-used.xbel", NULL((void*)0)); | |||
| 529 | ||||
| 530 | break; | |||
| 531 | ||||
| 532 | case BOOKMARK_STORE_SYSTEM: | |||
| 533 | priv->store_filename = SYSTEM_STORE_FILE_NAME"system-items.xbel"; | |||
| 534 | priv->create_item = create_app_item; | |||
| 535 | ||||
| 536 | break; | |||
| 537 | ||||
| 538 | default: | |||
| 539 | break; | |||
| 540 | } | |||
| 541 | ||||
| 542 | if ( | |||
| 543 | type == BOOKMARK_STORE_USER_APPS || type == BOOKMARK_STORE_USER_DOCS || | |||
| 544 | type == BOOKMARK_STORE_USER_DIRS || type == BOOKMARK_STORE_SYSTEM) | |||
| 545 | { | |||
| 546 | priv->user_modifiable = TRUE(!(0)); | |||
| 547 | ||||
| 548 | priv->user_store_path = g_build_filename ( | |||
| 549 | g_get_user_data_dir (), PACKAGE"cafe-control-center", priv->store_filename, NULL((void*)0)); | |||
| 550 | ||||
| 551 | priv->update_path = update_user_spec_path; | |||
| 552 | } | |||
| 553 | ||||
| 554 | if (type == BOOKMARK_STORE_USER_APPS || type == BOOKMARK_STORE_USER_DOCS || type == BOOKMARK_STORE_SYSTEM) { | |||
| 555 | priv->reorderable = TRUE(!(0)); | |||
| 556 | priv->load_store = load_xbel_store; | |||
| 557 | priv->save_store = save_xbel_store; | |||
| 558 | } | |||
| 559 | ||||
| 560 | update_agent (this); | |||
| 561 | ||||
| 562 | return this; | |||
| 563 | } | |||
| 564 | ||||
| 565 | static void | |||
| 566 | get_property (GObject *g_obj, guint prop_id, GValue *value, GParamSpec *pspec) | |||
| 567 | { | |||
| 568 | BookmarkAgent *this = BOOKMARK_AGENT (g_obj)((((BookmarkAgent*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((g_obj)), ((bookmark_agent_get_type ())))))); | |||
| 569 | BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); | |||
| 570 | ||||
| 571 | ||||
| 572 | switch (prop_id) { | |||
| 573 | case PROP_ITEMS: | |||
| 574 | g_value_set_pointer (value, priv->items); | |||
| 575 | break; | |||
| 576 | ||||
| 577 | case PROP_STATUS: | |||
| 578 | g_value_set_int (value, priv->status); | |||
| 579 | break; | |||
| 580 | } | |||
| 581 | } | |||
| 582 | ||||
| 583 | static void | |||
| 584 | set_property (GObject *g_obj, guint prop_id, const GValue *value, GParamSpec *pspec) | |||
| 585 | { | |||
| 586 | /* no writeable properties */ | |||
| 587 | } | |||
| 588 | ||||
| 589 | static void | |||
| 590 | finalize (GObject *g_obj) | |||
| 591 | { | |||
| 592 | BookmarkAgent *this = BOOKMARK_AGENT (g_obj)((((BookmarkAgent*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((g_obj)), ((bookmark_agent_get_type ())))))); | |||
| 593 | BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); | |||
| 594 | ||||
| 595 | gint i; | |||
| 596 | ||||
| 597 | ||||
| 598 | for (i = 0; priv->items && priv->items [i]; ++i) | |||
| 599 | bookmark_item_free (priv->items [i]); | |||
| 600 | ||||
| 601 | g_free (priv->items); | |||
| 602 | g_free (priv->store_path); | |||
| 603 | g_free (priv->user_store_path); | |||
| 604 | g_free (priv->ctk_store_path); | |||
| 605 | ||||
| 606 | if (priv->store_monitor) { | |||
| 607 | g_signal_handlers_disconnect_by_func (priv->store_monitor, store_monitor_cb, this)g_signal_handlers_disconnect_matched ((priv->store_monitor ), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (store_monitor_cb), (this)); | |||
| 608 | g_file_monitor_cancel (priv->store_monitor); | |||
| 609 | g_object_unref (priv->store_monitor); | |||
| 610 | } | |||
| 611 | ||||
| 612 | if (priv->user_store_monitor) { | |||
| 613 | g_signal_handlers_disconnect_by_func (priv->user_store_monitor, store_monitor_cb, this)g_signal_handlers_disconnect_matched ((priv->user_store_monitor ), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (store_monitor_cb), (this)); | |||
| 614 | g_file_monitor_cancel (priv->user_store_monitor); | |||
| 615 | g_object_unref (priv->user_store_monitor); | |||
| 616 | } | |||
| 617 | ||||
| 618 | if (priv->ctk_store_monitor) { | |||
| 619 | g_signal_handlers_disconnect_by_func (priv->ctk_store_monitor, store_monitor_cb, this)g_signal_handlers_disconnect_matched ((priv->ctk_store_monitor ), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (store_monitor_cb), (this)); | |||
| 620 | g_file_monitor_cancel (priv->ctk_store_monitor); | |||
| 621 | g_object_unref (priv->ctk_store_monitor); | |||
| 622 | } | |||
| 623 | ||||
| 624 | g_bookmark_file_free (priv->store); | |||
| 625 | ||||
| 626 | G_OBJECT_CLASS (bookmark_agent_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((bookmark_agent_parent_class)), (((GType) ((20) << ( 2))))))))->finalize (g_obj); | |||
| 627 | } | |||
| 628 | ||||
| 629 | static void | |||
| 630 | update_agent (BookmarkAgent *this) | |||
| 631 | { | |||
| 632 | BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); | |||
| 633 | ||||
| 634 | if (priv->update_path) | |||
| 635 | priv->update_path (this); | |||
| 636 | ||||
| 637 | if (priv->load_store) | |||
| 638 | priv->load_store (this); | |||
| 639 | ||||
| 640 | update_items (this); | |||
| 641 | } | |||
| 642 | ||||
| 643 | static void | |||
| 644 | update_items (BookmarkAgent *this) | |||
| 645 | { | |||
| 646 | BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); | |||
| 647 | ||||
| 648 | gchar **uris = NULL((void*)0); | |||
| 649 | gchar **uris_ordered = NULL((void*)0); | |||
| 650 | gsize n_uris = 0; | |||
| 651 | gint rank = -1; | |||
| 652 | gint rank_corr = -1; | |||
| 653 | gboolean needs_update = FALSE(0); | |||
| 654 | gboolean store_corrupted = FALSE(0); | |||
| 655 | gchar *new_title, *old_title; | |||
| 656 | ||||
| 657 | gint i; | |||
| 658 | ||||
| 659 | ||||
| 660 | uris = g_bookmark_file_get_uris (priv->store, & n_uris); | |||
| 661 | uris_ordered = g_new0 (gchar *, n_uris + 1)((gchar * *) g_malloc0_n ((n_uris + 1), sizeof (gchar *))); | |||
| 662 | uris_ordered [n_uris] = NULL((void*)0); | |||
| 663 | ||||
| 664 | for (i = 0; uris && uris [i]; ++i) { | |||
| 665 | rank = get_rank (this, uris [i]); | |||
| 666 | ||||
| 667 | if (rank < 0 || rank >= n_uris) | |||
| 668 | rank = i; | |||
| 669 | ||||
| 670 | if (uris_ordered [rank]) { | |||
| 671 | store_corrupted = TRUE(!(0)); | |||
| 672 | rank_corr = rank; | |||
| 673 | ||||
| 674 | for (rank = 0; rank < n_uris; ++rank) | |||
| 675 | if (! uris_ordered [rank]) | |||
| 676 | break; | |||
| 677 | ||||
| 678 | g_warning ( | |||
| 679 | "store corruption [%s] - multiple uris with same rank (%d): [%s] [%s], moving latter to %d", | |||
| 680 | priv->store_path, rank_corr, uris_ordered [rank_corr], uris [i], rank); | |||
| 681 | } | |||
| 682 | ||||
| 683 | set_rank (this, uris [i], rank); | |||
| 684 | ||||
| 685 | uris_ordered [rank] = uris [i]; | |||
| 686 | } | |||
| 687 | ||||
| 688 | if (priv->n_items != n_uris) | |||
| 689 | needs_update = TRUE(!(0)); | |||
| 690 | ||||
| 691 | for (i = 0; ! needs_update && uris_ordered && uris_ordered [i]; ++i) { | |||
| 692 | if (priv->type == BOOKMARK_STORE_USER_DIRS) { | |||
| 693 | new_title = g_bookmark_file_get_title (priv->store, uris_ordered [i], NULL((void*)0)); | |||
| 694 | old_title = priv->items [i]->title; | |||
| 695 | if (!new_title && !old_title) { | |||
| 696 | if (strcmp (priv->items [i]->uri, uris_ordered [i])) | |||
| 697 | needs_update = TRUE(!(0)); | |||
| 698 | } | |||
| 699 | else if ((new_title && !old_title) || (!new_title && old_title)) | |||
| 700 | needs_update = TRUE(!(0)); | |||
| 701 | else if (strcmp (old_title, new_title)) | |||
| 702 | needs_update = TRUE(!(0)); | |||
| 703 | g_free (new_title); | |||
| 704 | } | |||
| 705 | else if (strcmp (priv->items [i]->uri, uris_ordered [i])) | |||
| 706 | needs_update = TRUE(!(0)); | |||
| 707 | } | |||
| 708 | ||||
| 709 | if (needs_update) { | |||
| 710 | for (i = 0; priv->items && priv->items [i]; ++i) | |||
| 711 | bookmark_item_free (priv->items [i]); | |||
| 712 | ||||
| 713 | g_free (priv->items); | |||
| 714 | ||||
| 715 | priv->n_items = n_uris; | |||
| 716 | priv->items = g_new0 (BookmarkItem *, priv->n_items + 1)((BookmarkItem * *) g_malloc0_n ((priv->n_items + 1), sizeof (BookmarkItem *))); | |||
| 717 | ||||
| 718 | for (i = 0; uris_ordered && uris_ordered [i]; ++i) { | |||
| 719 | priv->items [i] = g_new0 (BookmarkItem, 1)((BookmarkItem *) g_malloc0_n ((1), sizeof (BookmarkItem))); | |||
| 720 | priv->items [i]->uri = g_strdup (uris_ordered [i])g_strdup_inline (uris_ordered [i]); | |||
| 721 | priv->items [i]->title = g_bookmark_file_get_title (priv->store, uris_ordered [i], NULL((void*)0)); | |||
| 722 | priv->items [i]->mime_type = g_bookmark_file_get_mime_type (priv->store, uris_ordered [i], NULL((void*)0)); | |||
| 723 | priv->items [i]->mtime = g_bookmark_file_get_modified (priv->store, uris_ordered [i], NULL((void*)0)); | |||
| 724 | priv->items [i]->app_name = NULL((void*)0); | |||
| 725 | priv->items [i]->app_exec = NULL((void*)0); | |||
| 726 | ||||
| 727 | g_bookmark_file_get_icon (priv->store, uris_ordered [i], & priv->items [i]->icon, NULL((void*)0), NULL((void*)0)); | |||
| 728 | } | |||
| 729 | ||||
| 730 | /* Since the bookmark store for recently-used items is updated by the caller of BookmarkAgent, | |||
| 731 | * we don't emit notifications in that case. The caller will know when to update itself. | |||
| 732 | */ | |||
| 733 | if (!TYPE_IS_RECENT (priv->type)((priv->type) == BOOKMARK_STORE_RECENT_APPS || (priv->type ) == BOOKMARK_STORE_RECENT_DOCS)) | |||
| 734 | g_object_notify (G_OBJECT (this)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((this)), (((GType) ((20) << (2)))))))), BOOKMARK_AGENT_ITEMS_PROP"items"); | |||
| 735 | } | |||
| 736 | ||||
| 737 | if (store_corrupted) | |||
| 738 | save_store (this); | |||
| 739 | ||||
| 740 | g_strfreev (uris); | |||
| 741 | g_free (uris_ordered); | |||
| 742 | } | |||
| 743 | ||||
| 744 | static void | |||
| 745 | save_store (BookmarkAgent *this) | |||
| 746 | { | |||
| 747 | BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); | |||
| 748 | ||||
| 749 | gchar *dir; | |||
| 750 | ||||
| 751 | ||||
| 752 | g_return_if_fail (priv->user_modifiable)do { if ((priv->user_modifiable)) { } else { g_return_if_fail_warning ("libslab", ((const char*) (__func__)), "priv->user_modifiable" ); return; } } while (0); | |||
| 753 | ||||
| 754 | priv->needs_sync = TRUE(!(0)); | |||
| 755 | priv->update_path (this); | |||
| 756 | ||||
| 757 | dir = g_path_get_dirname (priv->store_path); | |||
| 758 | g_mkdir_with_parents (dir, 0700); | |||
| 759 | g_free (dir); | |||
| 760 | ||||
| 761 | priv->save_store (this); | |||
| 762 | update_items (this); | |||
| 763 | } | |||
| 764 | ||||
| 765 | static gint | |||
| 766 | get_rank (BookmarkAgent *this, const gchar *uri) | |||
| 767 | { | |||
| 768 | BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); | |||
| 769 | ||||
| 770 | gchar **groups; | |||
| 771 | gint rank; | |||
| 772 | ||||
| 773 | gint i; | |||
| 774 | ||||
| 775 | ||||
| 776 | if (! priv->reorderable) | |||
| 777 | return -1; | |||
| 778 | ||||
| 779 | groups = g_bookmark_file_get_groups (priv->store, uri, NULL((void*)0), NULL((void*)0)); | |||
| 780 | rank = -1; | |||
| 781 | ||||
| 782 | for (i = 0; groups && groups [i]; ++i) { | |||
| 783 | if (g_str_has_prefix (groups [i], "rank-")(__builtin_constant_p ("rank-")? __extension__ ({ const char * const __str = (groups [i]); const char * const __prefix = ("rank-" ); gboolean __result = (0); if (__str == ((void*)0) || __prefix == ((void*)0)) __result = (g_str_has_prefix) (__str, __prefix ); else { const size_t __str_len = strlen (((__str) + !(__str ))); const size_t __prefix_len = strlen (((__prefix) + !(__prefix ))); if (__str_len >= __prefix_len) __result = memcmp (((__str ) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len) == 0 ; } __result; }) : (g_str_has_prefix) (groups [i], "rank-") )) { | |||
| 784 | if (rank >= 0) | |||
| 785 | g_warning ( | |||
| 786 | "store corruption - multiple ranks for same uri: [%s] [%s]", | |||
| 787 | priv->store_path, uri); | |||
| 788 | ||||
| 789 | rank = atoi (& groups [i] [5]); | |||
| 790 | } | |||
| 791 | } | |||
| 792 | ||||
| 793 | g_strfreev (groups); | |||
| 794 | ||||
| 795 | return rank; | |||
| 796 | } | |||
| 797 | ||||
| 798 | static void | |||
| 799 | set_rank (BookmarkAgent *this, const gchar *uri, gint rank) | |||
| 800 | { | |||
| 801 | BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); | |||
| 802 | ||||
| 803 | gchar **groups; | |||
| 804 | gchar *group; | |||
| 805 | ||||
| 806 | gint i; | |||
| 807 | ||||
| 808 | ||||
| 809 | if (! (priv->reorderable && bookmark_agent_has_item (this, uri))) | |||
| 810 | return; | |||
| 811 | ||||
| 812 | groups = g_bookmark_file_get_groups (priv->store, uri, NULL((void*)0), NULL((void*)0)); | |||
| 813 | ||||
| 814 | for (i = 0; groups && groups [i]; ++i) | |||
| 815 | if (g_str_has_prefix (groups [i], "rank-")(__builtin_constant_p ("rank-")? __extension__ ({ const char * const __str = (groups [i]); const char * const __prefix = ("rank-" ); gboolean __result = (0); if (__str == ((void*)0) || __prefix == ((void*)0)) __result = (g_str_has_prefix) (__str, __prefix ); else { const size_t __str_len = strlen (((__str) + !(__str ))); const size_t __prefix_len = strlen (((__prefix) + !(__prefix ))); if (__str_len >= __prefix_len) __result = memcmp (((__str ) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len) == 0 ; } __result; }) : (g_str_has_prefix) (groups [i], "rank-") )) | |||
| 816 | g_bookmark_file_remove_group (priv->store, uri, groups [i], NULL((void*)0)); | |||
| 817 | ||||
| 818 | g_strfreev (groups); | |||
| 819 | ||||
| 820 | group = g_strdup_printf ("rank-%d", rank); | |||
| 821 | g_bookmark_file_add_group (priv->store, uri, group); | |||
| 822 | g_free (group); | |||
| 823 | } | |||
| 824 | ||||
| 825 | static void | |||
| 826 | load_xbel_store (BookmarkAgent *this) | |||
| 827 | { | |||
| 828 | BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); | |||
| 829 | ||||
| 830 | gchar **uris = NULL((void*)0); | |||
| 831 | ||||
| 832 | GError *error = NULL((void*)0); | |||
| 833 | ||||
| 834 | gint i; | |||
| 835 | gboolean success; | |||
| 836 | ||||
| 837 | if (!priv->store_path) | |||
| 838 | success = FALSE(0); | |||
| 839 | else { | |||
| 840 | success = g_bookmark_file_load_from_file (priv->store, priv->store_path, & error); | |||
| 841 | } | |||
| 842 | ||||
| 843 | if (!success) { | |||
| 844 | g_bookmark_file_free (priv->store); | |||
| 845 | priv->store = g_bookmark_file_new (); | |||
| 846 | ||||
| 847 | if (error) { | |||
| 848 | g_debug ("Couldn't load bookmark file [%s]: %s", priv->store_path, error->message); | |||
| 849 | g_error_free (error); | |||
| 850 | } else { | |||
| 851 | g_debug ("Couldn't load bookmark file [NULL]"); | |||
| 852 | } | |||
| 853 | return; | |||
| 854 | } | |||
| 855 | ||||
| 856 | uris = g_bookmark_file_get_uris (priv->store, NULL((void*)0)); | |||
| 857 | ||||
| 858 | for (i = 0; uris && uris [i]; ++i) | |||
| 859 | priv->create_item (this, uris [i]); | |||
| 860 | ||||
| 861 | g_strfreev (uris); | |||
| 862 | } | |||
| 863 | ||||
| 864 | static void | |||
| 865 | load_places_store (BookmarkAgent *this) | |||
| 866 | { | |||
| 867 | BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); | |||
| 868 | ||||
| 869 | gchar **uris; | |||
| 870 | gchar **groups; | |||
| 871 | gchar **bookmarks = NULL((void*)0); | |||
| 872 | ||||
| 873 | gchar *buf, *label, *uri; | |||
| 874 | ||||
| 875 | gint i, j, bookmark_len; | |||
| 876 | ||||
| 877 | load_xbel_store (this); | |||
| 878 | ||||
| 879 | uris = g_bookmark_file_get_uris (priv->store, NULL((void*)0)); | |||
| 880 | ||||
| 881 | for (i = 0; uris && uris [i]; ++i) { | |||
| 882 | groups = g_bookmark_file_get_groups (priv->store, uris [i], NULL((void*)0), NULL((void*)0)); | |||
| 883 | ||||
| 884 | for (j = 0; groups && groups [j]; ++j) { | |||
| 885 | if (! strcmp (groups [j], "ctk-bookmarks")) { | |||
| 886 | g_bookmark_file_remove_item (priv->store, uris [i], NULL((void*)0)); | |||
| 887 | ||||
| 888 | break; | |||
| 889 | } | |||
| 890 | } | |||
| 891 | ||||
| 892 | g_strfreev (groups); | |||
| 893 | } | |||
| 894 | ||||
| 895 | g_strfreev (uris); | |||
| 896 | ||||
| 897 | g_file_get_contents (priv->ctk_store_path, & buf, NULL((void*)0), NULL((void*)0)); | |||
| 898 | ||||
| 899 | if (buf) { | |||
| 900 | bookmarks = g_strsplit (buf, "\n", -1); | |||
| 901 | g_free (buf); | |||
| 902 | } | |||
| 903 | ||||
| 904 | for (i = 0; bookmarks && bookmarks [i]; ++i) { | |||
| 905 | bookmark_len = strlen (bookmarks [i]); | |||
| 906 | if (bookmark_len > 0) { | |||
| 907 | label = strstr (bookmarks[i], " "); | |||
| 908 | if (label != NULL((void*)0)) | |||
| 909 | uri = g_strndup (bookmarks [i], bookmark_len - strlen (label)); | |||
| 910 | else | |||
| 911 | uri = bookmarks [i]; | |||
| 912 | g_bookmark_file_add_group (priv->store, uri, "ctk-bookmarks"); | |||
| 913 | priv->create_item (this, uri); | |||
| 914 | if (label != NULL((void*)0)) { | |||
| 915 | label++; | |||
| 916 | if (strlen (label) > 0) | |||
| 917 | g_bookmark_file_set_title (priv->store, uri, label); | |||
| 918 | g_free (uri); | |||
| 919 | } | |||
| 920 | } | |||
| 921 | } | |||
| 922 | ||||
| 923 | g_strfreev (bookmarks); | |||
| 924 | } | |||
| 925 | ||||
| 926 | static gchar * | |||
| 927 | find_package_data_file (const gchar *filename) | |||
| 928 | { | |||
| 929 | const gchar * const *dirs = NULL((void*)0); | |||
| 930 | gchar *path = NULL((void*)0); | |||
| 931 | gint i; | |||
| 932 | ||||
| 933 | ||||
| 934 | dirs = g_get_system_data_dirs (); | |||
| 935 | ||||
| 936 | for (i = 0; ! path && dirs && dirs [i]; ++i) { | |||
| 937 | path = g_build_filename (dirs [i], PACKAGE"cafe-control-center", filename, NULL((void*)0)); | |||
| 938 | ||||
| 939 | if (! g_file_test (path, G_FILE_TEST_EXISTS)) { | |||
| 940 | g_free (path); | |||
| 941 | path = NULL((void*)0); | |||
| 942 | } | |||
| 943 | } | |||
| 944 | ||||
| 945 | return path; | |||
| 946 | } | |||
| 947 | ||||
| 948 | static void | |||
| 949 | update_user_spec_path (BookmarkAgent *this) | |||
| 950 | { | |||
| 951 | BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); | |||
| 952 | ||||
| 953 | gboolean use_user_path; | |||
| 954 | gchar *path = NULL((void*)0); | |||
| 955 | ||||
| 956 | BookmarkStoreStatus status; | |||
| 957 | ||||
| 958 | use_user_path = priv->user_modifiable && | |||
| 959 | (priv->needs_sync || g_file_test (priv->user_store_path, G_FILE_TEST_EXISTS)); | |||
| 960 | ||||
| 961 | if (use_user_path) | |||
| 962 | path = g_strdup (priv->user_store_path)g_strdup_inline (priv->user_store_path); | |||
| 963 | else | |||
| 964 | path = find_package_data_file (priv->store_filename); | |||
| 965 | ||||
| 966 | if (use_user_path) | |||
| 967 | status = BOOKMARK_STORE_USER; | |||
| 968 | else if (path && priv->user_modifiable) | |||
| 969 | status = BOOKMARK_STORE_DEFAULT; | |||
| 970 | else if (path) | |||
| 971 | status = BOOKMARK_STORE_DEFAULT_ONLY; | |||
| 972 | else | |||
| 973 | status = BOOKMARK_STORE_ABSENT; | |||
| 974 | ||||
| 975 | if (priv->status != status) { | |||
| 976 | priv->status = status; | |||
| 977 | g_object_notify (G_OBJECT (this)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((this)), (((GType) ((20) << (2)))))))), BOOKMARK_AGENT_STORE_STATUS_PROP"store-status"); | |||
| 978 | ||||
| 979 | if (priv->user_store_monitor) { | |||
| 980 | g_file_monitor_cancel (priv->user_store_monitor); | |||
| 981 | g_object_unref (priv->user_store_monitor); | |||
| 982 | priv->user_store_monitor = NULL((void*)0); | |||
| 983 | } | |||
| 984 | ||||
| 985 | if (priv->status == BOOKMARK_STORE_DEFAULT) { | |||
| 986 | GFile *user_store_file; | |||
| 987 | ||||
| 988 | user_store_file = g_file_new_for_path (priv->user_store_path); | |||
| 989 | priv->user_store_monitor = g_file_monitor_file (user_store_file, | |||
| 990 | 0, NULL((void*)0), NULL((void*)0)); | |||
| 991 | if (priv->user_store_monitor) { | |||
| 992 | g_signal_connect (priv->user_store_monitor, "changed",g_signal_connect_data ((priv->user_store_monitor), ("changed" ), (((GCallback) (store_monitor_cb))), (this), ((void*)0), (GConnectFlags ) 0) | |||
| 993 | G_CALLBACK (store_monitor_cb), this)g_signal_connect_data ((priv->user_store_monitor), ("changed" ), (((GCallback) (store_monitor_cb))), (this), ((void*)0), (GConnectFlags ) 0); | |||
| 994 | } | |||
| 995 | ||||
| 996 | g_object_unref (user_store_file); | |||
| 997 | } | |||
| 998 | } | |||
| 999 | ||||
| 1000 | if (libslab_strcmp (priv->store_path, path)) { | |||
| 1001 | g_free (priv->store_path); | |||
| 1002 | priv->store_path = path; | |||
| 1003 | ||||
| 1004 | if (priv->store_monitor) { | |||
| 1005 | g_file_monitor_cancel (priv->store_monitor); | |||
| 1006 | g_object_unref (priv->store_monitor); | |||
| 1007 | } | |||
| 1008 | ||||
| 1009 | if (priv->store_path) { | |||
| 1010 | GFile *store_file; | |||
| 1011 | ||||
| 1012 | store_file = g_file_new_for_path (priv->store_path); | |||
| 1013 | priv->store_monitor = g_file_monitor_file (store_file, | |||
| 1014 | 0, NULL((void*)0), NULL((void*)0)); | |||
| 1015 | if (priv->store_monitor) { | |||
| 1016 | g_signal_connect (priv->store_monitor, "changed",g_signal_connect_data ((priv->store_monitor), ("changed"), (((GCallback) (store_monitor_cb))), (this), ((void*)0), (GConnectFlags ) 0) | |||
| 1017 | G_CALLBACK (store_monitor_cb), this)g_signal_connect_data ((priv->store_monitor), ("changed"), (((GCallback) (store_monitor_cb))), (this), ((void*)0), (GConnectFlags ) 0); | |||
| 1018 | } | |||
| 1019 | ||||
| 1020 | g_object_unref (store_file); | |||
| 1021 | } | |||
| 1022 | } | |||
| 1023 | else | |||
| 1024 | g_free (path); | |||
| 1025 | } | |||
| 1026 | ||||
| 1027 | static void | |||
| 1028 | save_xbel_store (BookmarkAgent *this) | |||
| 1029 | { | |||
| 1030 | BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); | |||
| 1031 | ||||
| 1032 | GError *error = NULL((void*)0); | |||
| 1033 | ||||
| 1034 | if (g_bookmark_file_to_file (priv->store, priv->store_path, &error)) | |||
| 1035 | return; | |||
| 1036 | ||||
| 1037 | if (error) { | |||
| 1038 | g_warning ("Couldn't save bookmark file [%s]: %s", priv->store_path, error->message); | |||
| 1039 | g_error_free (error); | |||
| 1040 | } else { | |||
| 1041 | g_warning ("Couldn't save bookmark file [%s]", priv->store_path); | |||
| 1042 | } | |||
| 1043 | } | |||
| 1044 | ||||
| 1045 | static void | |||
| 1046 | create_app_item (BookmarkAgent *this, const gchar *uri) | |||
| 1047 | { | |||
| 1048 | BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); | |||
| 1049 | ||||
| 1050 | CafeDesktopItem *ditem; | |||
| 1051 | gchar *uri_new = NULL((void*)0); | |||
| 1052 | ||||
| 1053 | ditem = libslab_cafe_desktop_item_new_from_unknown_id (uri); | |||
| 1054 | ||||
| 1055 | if (ditem) { | |||
| 1056 | uri_new = g_strdup (cafe_desktop_item_get_location (ditem))g_strdup_inline (cafe_desktop_item_get_location (ditem)); | |||
| 1057 | cafe_desktop_item_unref (ditem); | |||
| 1058 | } | |||
| 1059 | ||||
| 1060 | if (! uri_new) | |||
| 1061 | return; | |||
| 1062 | ||||
| 1063 | if (libslab_strcmp (uri, uri_new)) | |||
| 1064 | g_bookmark_file_move_item (priv->store, uri, uri_new, NULL((void*)0)); | |||
| 1065 | ||||
| 1066 | g_free (uri_new); | |||
| 1067 | } | |||
| 1068 | ||||
| 1069 | static void | |||
| 1070 | create_doc_item (BookmarkAgent *this, const gchar *uri) | |||
| 1071 | { | |||
| 1072 | BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); | |||
| 1073 | ||||
| 1074 | gchar *uri_new = NULL((void*)0); | |||
| 1075 | ||||
| 1076 | if ((strcmp (uri, "BLANK_SPREADSHEET") == 0) || (strcmp (uri, "BLANK_DOCUMENT") == 0)) { | |||
| 1077 | gchar *template = NULL((void*)0); | |||
| 1078 | gchar *file; | |||
| 1079 | ||||
| 1080 | gchar *dir = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS))g_strdup_inline (g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS )); | |||
| 1081 | if (!dir) | |||
| ||||
| 1082 | dir = g_build_filename (g_get_home_dir (), "Documents", NULL((void*)0)); | |||
| 1083 | ||||
| 1084 | if (strcmp (uri, "BLANK_SPREADSHEET") == 0) { | |||
| 1085 | g_bookmark_file_set_title (priv->store, uri, "BLANK_SPREADSHEET"); | |||
| 1086 | file = g_strconcat (_("New Spreadsheet")((char *) g_dgettext ("cafe-control-center", "New Spreadsheet" )), ".ots", NULL((void*)0)); | |||
| 1087 | template = find_package_data_file (CALC_TEMPLATE_FILE_NAME"empty.ots"); | |||
| 1088 | } else { | |||
| 1089 | g_bookmark_file_set_title (priv->store, uri, "BLANK_DOCUMENT"); | |||
| 1090 | file = g_strconcat (_("New Document")((char *) g_dgettext ("cafe-control-center", "New Document")), ".ott", NULL((void*)0)); | |||
| 1091 | template = find_package_data_file (WRITER_TEMPLATE_FILE_NAME"empty.ott"); | |||
| 1092 | } | |||
| 1093 | ||||
| 1094 | gchar *path = g_build_filename (dir, file, NULL((void*)0)); | |||
| 1095 | if (!g_file_test (path, G_FILE_TEST_EXISTS)) { | |||
| 1096 | g_mkdir_with_parents (dir, 0700); | |||
| 1097 | ||||
| 1098 | if (template != NULL((void*)0)) { | |||
| 1099 | gchar *contents; | |||
| 1100 | gsize length; | |||
| 1101 | ||||
| 1102 | if (g_file_get_contents (template, &contents, &length, NULL((void*)0))) | |||
| 1103 | g_file_set_contents (path, contents, length, NULL((void*)0)); | |||
| 1104 | ||||
| 1105 | g_free (contents); | |||
| 1106 | } else { | |||
| 1107 | fclose (g_fopenfopen (path, "w")); | |||
| ||||
| 1108 | } | |||
| 1109 | } | |||
| 1110 | ||||
| 1111 | uri_new = g_filename_to_uri (path, NULL((void*)0), NULL((void*)0)); | |||
| 1112 | ||||
| 1113 | g_free (dir); | |||
| 1114 | g_free (file); | |||
| 1115 | g_free (path); | |||
| 1116 | g_free (template); | |||
| 1117 | } | |||
| 1118 | ||||
| 1119 | if (!uri_new) | |||
| 1120 | return; | |||
| 1121 | ||||
| 1122 | if (libslab_strcmp (uri, uri_new)) | |||
| 1123 | g_bookmark_file_move_item (priv->store, uri, uri_new, NULL((void*)0)); | |||
| 1124 | ||||
| 1125 | g_free (uri_new); | |||
| 1126 | } | |||
| 1127 | ||||
| 1128 | static void | |||
| 1129 | create_dir_item (BookmarkAgent *this, const gchar *uri) | |||
| 1130 | { | |||
| 1131 | BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); | |||
| 1132 | ||||
| 1133 | gchar *uri_new = NULL((void*)0); | |||
| 1134 | gchar *path = NULL((void*)0); | |||
| 1135 | gchar *name = NULL((void*)0); | |||
| 1136 | gchar *icon = NULL((void*)0); | |||
| 1137 | ||||
| 1138 | gchar *search_string = NULL((void*)0); | |||
| 1139 | ||||
| 1140 | gboolean gotta_free_name = FALSE(0); | |||
| 1141 | ||||
| 1142 | if (strcmp (uri, "HOME") == 0) { | |||
| 1143 | uri_new = g_filename_to_uri (g_get_home_dir (), NULL((void*)0), NULL((void*)0)); | |||
| 1144 | name = g_strdup (C_("Home folder", "Home"))g_strdup_inline (g_dpgettext ("cafe-control-center", "Home folder" "\004" "Home", strlen ("Home folder") + 1)); | |||
| 1145 | gotta_free_name = TRUE(!(0)); | |||
| 1146 | icon = "user-home"; | |||
| 1147 | } else if (strcmp (uri, "DOCUMENTS") == 0) { | |||
| 1148 | path = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS))g_strdup_inline (g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS )); | |||
| 1149 | if (!path) | |||
| 1150 | path = g_build_filename (g_get_home_dir (), "Documents", NULL((void*)0)); | |||
| 1151 | name = _("Documents")((char *) g_dgettext ("cafe-control-center", "Documents")); | |||
| 1152 | uri_new = g_filename_to_uri (path, NULL((void*)0), NULL((void*)0)); | |||
| 1153 | } else if (strcmp (uri, "DESKTOP") == 0) { | |||
| 1154 | path = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP))g_strdup_inline (g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP )); | |||
| 1155 | if (!path) | |||
| 1156 | path = g_build_filename (g_get_home_dir (), "Desktop", NULL((void*)0)); | |||
| 1157 | name = _("Desktop")((char *) g_dgettext ("cafe-control-center", "Desktop")); | |||
| 1158 | uri_new = g_filename_to_uri (path, NULL((void*)0), NULL((void*)0)); | |||
| 1159 | icon = "user-desktop"; | |||
| 1160 | } else if (strcmp (uri, "file:///") == 0) { | |||
| 1161 | icon = "drive-harddisk"; | |||
| 1162 | name = _("File System")((char *) g_dgettext ("cafe-control-center", "File System")); | |||
| 1163 | } else if (strcmp (uri, "network:") == 0) { | |||
| 1164 | icon = "network-workgroup"; | |||
| 1165 | name = _("Network Servers")((char *) g_dgettext ("cafe-control-center", "Network Servers" )); | |||
| 1166 | } else if (g_str_has_prefix (uri, "x-baul-search")(__builtin_constant_p ("x-baul-search")? __extension__ ({ const char * const __str = (uri); const char * const __prefix = ("x-baul-search" ); gboolean __result = (0); if (__str == ((void*)0) || __prefix == ((void*)0)) __result = (g_str_has_prefix) (__str, __prefix ); else { const size_t __str_len = strlen (((__str) + !(__str ))); const size_t __prefix_len = strlen (((__prefix) + !(__prefix ))); if (__str_len >= __prefix_len) __result = memcmp (((__str ) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len) == 0 ; } __result; }) : (g_str_has_prefix) (uri, "x-baul-search") )) { | |||
| 1167 | icon = "system-search"; | |||
| 1168 | ||||
| 1169 | path = g_build_filename (g_get_user_data_dir (), "baul", "searches", & uri [21], NULL((void*)0)); | |||
| 1170 | ||||
| 1171 | if (g_file_test (path, G_FILE_TEST_EXISTS)) { | |||
| 1172 | gchar *buf = NULL((void*)0); | |||
| 1173 | g_file_get_contents (path, &buf, NULL((void*)0), NULL((void*)0)); | |||
| 1174 | ||||
| 1175 | gchar *tag_open_ptr = NULL((void*)0); | |||
| 1176 | gchar *tag_close_ptr = NULL((void*)0); | |||
| 1177 | ||||
| 1178 | if (buf) { | |||
| 1179 | tag_open_ptr = strstr (buf, "<text>"); | |||
| 1180 | tag_close_ptr = strstr (buf, "</text>"); | |||
| 1181 | } | |||
| 1182 | ||||
| 1183 | if (tag_open_ptr && tag_close_ptr) { | |||
| 1184 | tag_close_ptr [0] = '\0'; | |||
| 1185 | tag_close_ptr [0] = 'a'; | |||
| 1186 | search_string = g_strdup_printf ("\"%s\"", &tag_open_ptr[6]); | |||
| 1187 | } | |||
| 1188 | ||||
| 1189 | g_free (buf); | |||
| 1190 | } | |||
| 1191 | ||||
| 1192 | if (search_string) { | |||
| 1193 | name = search_string; | |||
| 1194 | gotta_free_name = TRUE(!(0)); | |||
| 1195 | } else { | |||
| 1196 | name = _("Search")((char *) g_dgettext ("cafe-control-center", "Search")); | |||
| 1197 | } | |||
| 1198 | } | |||
| 1199 | ||||
| 1200 | if (icon) | |||
| 1201 | g_bookmark_file_set_icon (priv->store, uri, icon, "image/png"); | |||
| 1202 | ||||
| 1203 | if (name) | |||
| 1204 | g_bookmark_file_set_title (priv->store, uri, name); | |||
| 1205 | ||||
| 1206 | if (uri_new && libslab_strcmp (uri, uri_new)) | |||
| 1207 | g_bookmark_file_move_item (priv->store, uri, uri_new, NULL((void*)0)); | |||
| 1208 | ||||
| 1209 | if (gotta_free_name) { | |||
| 1210 | g_free (name); | |||
| 1211 | } | |||
| 1212 | ||||
| 1213 | g_free (path); | |||
| 1214 | g_free (uri_new); | |||
| 1215 | } | |||
| 1216 | ||||
| 1217 | static void | |||
| 1218 | store_monitor_cb (GFileMonitor *mon, GFile *f1, GFile *f2, | |||
| 1219 | GFileMonitorEvent event_type, gpointer user_data) | |||
| 1220 | { | |||
| 1221 | update_agent (BOOKMARK_AGENT (user_data)((((BookmarkAgent*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((user_data)), ((bookmark_agent_get_type ()))))))); | |||
| 1222 | } | |||
| 1223 | ||||
| 1224 | static void | |||
| 1225 | weak_destroy_cb (gpointer data, GObject *g_obj) | |||
| 1226 | { | |||
| 1227 | instances [GPOINTER_TO_INT (data)((gint) (glong) (data))] = NULL((void*)0); | |||
| 1228 | } | |||
| 1229 | ||||
| 1230 | static gint | |||
| 1231 | recent_item_mru_comp_func (gconstpointer a, gconstpointer b) | |||
| 1232 | { | |||
| 1233 | return ((BookmarkItem *) b)->mtime - ((BookmarkItem *) a)->mtime; | |||
| 1234 | } |