104
104
#define BOOKMARK_NAME_ATTRIBUTE "name"
105
105
#define BOOKMARK_EXEC_ATTRIBUTE "exec"
106
106
#define BOOKMARK_COUNT_ATTRIBUTE "count"
107
#define BOOKMARK_TIMESTAMP_ATTRIBUTE "timestamp"
107
#define BOOKMARK_TIMESTAMP_ATTRIBUTE "timestamp" /* deprecated by "modified" */
108
#define BOOKMARK_MODIFIED_ATTRIBUTE "modified"
108
109
#define BOOKMARK_HREF_ATTRIBUTE "href"
109
110
#define BOOKMARK_TYPE_ATTRIBUTE "type"
258
259
name = g_markup_escape_text (app_info->name, -1);
259
260
exec = g_markup_escape_text (app_info->exec, -1);
261
retval = g_strdup_printf (" <%s:%s %s=\"%s\" %s=\"%s\" %s=\"%ld\" %s=\"%u\"/>\n",
262
BOOKMARK_NAMESPACE_NAME,
263
BOOKMARK_APPLICATION_ELEMENT,
264
BOOKMARK_NAME_ATTRIBUTE, name,
265
BOOKMARK_EXEC_ATTRIBUTE, exec,
266
BOOKMARK_TIMESTAMP_ATTRIBUTE, (time_t) app_info->stamp,
267
BOOKMARK_COUNT_ATTRIBUTE, app_info->count);
261
modified = timestamp_to_iso8601 (app_info->stamp);
262
count = g_strdup_printf ("%u", app_info->count);
264
retval = g_strconcat (" "
265
"<" BOOKMARK_NAMESPACE_NAME ":" BOOKMARK_APPLICATION_ELEMENT
266
" " BOOKMARK_NAME_ATTRIBUTE "=\"", name, "\""
267
" " BOOKMARK_EXEC_ATTRIBUTE "=\"", exec, "\""
268
" " BOOKMARK_MODIFIED_ATTRIBUTE "=\"", modified, "\""
269
" " BOOKMARK_COUNT_ATTRIBUTE "=\"", count, "\"/>\n",
325
330
(GFunc) bookmark_app_info_free,
327
332
g_list_free (metadata->applications);
329
g_hash_table_destroy (metadata->apps_by_name);
335
g_hash_table_destroy (metadata->apps_by_name);
332
337
g_free (metadata->icon_href);
333
338
g_free (metadata->icon_mime);
339
344
bookmark_metadata_dump (BookmarkMetadata *metadata)
343
349
if (!metadata->applications)
346
retval = g_string_new (NULL);
352
retval = g_string_sized_new (1024);
348
354
/* metadata container */
349
g_string_append_printf (retval,
351
XBEL_METADATA_ELEMENT,
352
XBEL_OWNER_ATTRIBUTE, BOOKMARK_METADATA_OWNER);
355
g_string_append (retval,
357
"<" XBEL_METADATA_ELEMENT
358
" " XBEL_OWNER_ATTRIBUTE "=\"" BOOKMARK_METADATA_OWNER
355
if (metadata->mime_type)
356
g_string_append_printf (retval,
357
" <%s:%s %s=\"%s\"/>\n",
360
MIME_TYPE_ATTRIBUTE, metadata->mime_type);
362
if (metadata->mime_type) {
363
buffer = g_strconcat (" "
364
"<" MIME_NAMESPACE_NAME ":" MIME_TYPE_ELEMENT " "
365
MIME_TYPE_ATTRIBUTE "=\"", metadata->mime_type, "\"/>\n",
367
g_string_append (retval, buffer);
362
371
if (metadata->groups)
366
375
/* open groups container */
367
g_string_append_printf (retval,
369
BOOKMARK_NAMESPACE_NAME,
370
BOOKMARK_GROUPS_ELEMENT);
376
g_string_append (retval,
378
"<" BOOKMARK_NAMESPACE_NAME
379
":" BOOKMARK_GROUPS_ELEMENT ">\n");
372
381
for (l = g_list_last (metadata->groups); l != NULL; l = l->prev)
374
383
gchar *group_name;
376
385
group_name = g_markup_escape_text ((gchar *) l->data, -1);
377
g_string_append_printf (retval,
378
" <%s:%s>%s</%s:%s>\n",
379
BOOKMARK_NAMESPACE_NAME,
380
BOOKMARK_GROUP_ELEMENT,
382
BOOKMARK_NAMESPACE_NAME,
383
BOOKMARK_GROUP_ELEMENT);
386
buffer = g_strconcat (" "
387
"<" BOOKMARK_NAMESPACE_NAME
388
":" BOOKMARK_GROUP_ELEMENT ">",
390
"</" BOOKMARK_NAMESPACE_NAME
391
":" BOOKMARK_GROUP_ELEMENT ">\n", NULL);
392
g_string_append (retval, buffer);
384
395
g_free (group_name);
387
398
/* close groups container */
388
g_string_append_printf (retval,
390
BOOKMARK_NAMESPACE_NAME,
391
BOOKMARK_GROUPS_ELEMENT);
399
g_string_append (retval,
401
"</" BOOKMARK_NAMESPACE_NAME
402
":" BOOKMARK_GROUPS_ELEMENT ">\n");
394
405
if (metadata->applications)
398
409
/* open applications container */
399
g_string_append_printf (retval,
401
BOOKMARK_NAMESPACE_NAME,
402
BOOKMARK_APPLICATIONS_ELEMENT);
410
g_string_append (retval,
412
"<" BOOKMARK_NAMESPACE_NAME
413
":" BOOKMARK_APPLICATIONS_ELEMENT ">\n");
404
415
for (l = g_list_last (metadata->applications); l != NULL; l = l->prev)
421
432
/* close applications container */
422
g_string_append_printf (retval,
424
BOOKMARK_NAMESPACE_NAME,
425
BOOKMARK_APPLICATIONS_ELEMENT);
433
g_string_append (retval,
435
"</" BOOKMARK_NAMESPACE_NAME
436
":" BOOKMARK_APPLICATIONS_ELEMENT ">\n");
431
442
if (!metadata->icon_mime)
432
443
metadata->icon_mime = g_strdup ("application/octet-stream");
434
g_string_append_printf (retval,
435
" <%s:%s %s=\"%s\" %s=\"%s\"/>\n",
436
BOOKMARK_NAMESPACE_NAME,
437
BOOKMARK_ICON_ELEMENT,
438
BOOKMARK_HREF_ATTRIBUTE, metadata->icon_href,
439
BOOKMARK_TYPE_ATTRIBUTE, metadata->icon_mime);
445
buffer = g_strconcat (" "
446
"<" BOOKMARK_NAMESPACE_NAME
447
":" BOOKMARK_ICON_ELEMENT
448
" " BOOKMARK_HREF_ATTRIBUTE "=\"", metadata->icon_href,
449
"\" " BOOKMARK_TYPE_ATTRIBUTE "=\"", metadata->icon_mime, "\"/>\n", NULL);
450
g_string_append (retval, buffer);
442
455
/* private hint */
443
456
if (metadata->is_private)
444
g_string_append_printf (retval,
446
BOOKMARK_NAMESPACE_NAME,
447
BOOKMARK_PRIVATE_ELEMENT);
457
g_string_append (retval,
459
"<" BOOKMARK_NAMESPACE_NAME
460
":" BOOKMARK_PRIVATE_ELEMENT "/>\n");
449
462
/* close metadata container */
450
g_string_append_printf (retval, " </%s>\n", XBEL_METADATA_ELEMENT);
463
g_string_append (retval,
465
"</" XBEL_METADATA_ELEMENT ">\n");
452
467
return g_string_free (retval, FALSE);
502
517
gchar *added, *visited, *modified;
503
518
gchar *escaped_uri;
505
521
/* at this point, we must have at least a registered application; if we don't
506
522
* we don't screw up the bookmark file, and just skip this item
514
retval = g_string_new (NULL);
530
retval = g_string_sized_new (4096);
516
532
added = timestamp_to_iso8601 (item->added);
517
533
modified = timestamp_to_iso8601 (item->modified);
518
534
visited = timestamp_to_iso8601 (item->visited);
520
536
escaped_uri = g_markup_escape_text (item->uri, -1);
522
g_string_append_printf (retval,
523
" <%s %s=\"%s\" %s=\"%s\" %s=\"%s\" %s=\"%s\">\n",
524
XBEL_BOOKMARK_ELEMENT,
525
XBEL_HREF_ATTRIBUTE, escaped_uri,
526
XBEL_ADDED_ATTRIBUTE, added,
527
XBEL_MODIFIED_ATTRIBUTE, modified,
528
XBEL_VISITED_ATTRIBUTE, visited);
538
buffer = g_strconcat (" <"
539
XBEL_BOOKMARK_ELEMENT
541
XBEL_HREF_ATTRIBUTE "=\"", escaped_uri, "\" "
542
XBEL_ADDED_ATTRIBUTE "=\"", added, "\" "
543
XBEL_MODIFIED_ATTRIBUTE "=\"", modified, "\" "
544
XBEL_VISITED_ATTRIBUTE "=\"", visited, "\">\n",
547
g_string_append (retval, buffer);
529
549
g_free (escaped_uri);
530
550
g_free (visited);
531
551
g_free (modified);
536
557
gchar *escaped_title;
538
559
escaped_title = g_markup_escape_text (item->title, -1);
539
g_string_append_printf (retval,
560
buffer = g_strconcat (" "
561
"<" XBEL_TITLE_ELEMENT ">",
563
"</" XBEL_TITLE_ELEMENT ">\n",
565
g_string_append (retval, buffer);
544
567
g_free (escaped_title);
547
571
if (item->description)
549
573
gchar *escaped_desc;
551
575
escaped_desc = g_markup_escape_text (item->description, -1);
552
g_string_append_printf (retval,
576
buffer = g_strconcat (" "
577
"<" XBEL_DESC_ELEMENT ">",
579
"</" XBEL_DESC_ELEMENT ">\n",
581
g_string_append (retval, buffer);
557
583
g_free (escaped_desc);
560
587
if (item->metadata)
564
/* open info container */
565
g_string_append_printf (retval, " <%s>\n", XBEL_INFO_ELEMENT);
567
591
metadata = bookmark_metadata_dump (item->metadata);
570
retval = g_string_append (retval, metadata);
594
buffer = g_strconcat (" "
595
"<" XBEL_INFO_ELEMENT ">\n",
598
"</" XBEL_INFO_ELEMENT ">\n",
600
retval = g_string_append (retval, buffer);
572
603
g_free (metadata);
575
/* close info container */
576
g_string_append_printf (retval, " </%s>\n", XBEL_INFO_ELEMENT);
579
g_string_append_printf (retval, " </%s>\n", XBEL_BOOKMARK_ELEMENT);
607
g_string_append (retval, " </" XBEL_BOOKMARK_ELEMENT ">\n");
581
609
return g_string_free (retval, FALSE);
700
728
visited = attribute_values[i];
731
/* bookmark is defined by the XBEL spec, so we need
732
* to error out if the element has different or
703
735
g_set_error (error, G_MARKUP_ERROR,
704
736
G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
705
737
_("Unexpected attribute '%s' for element '%s'"),
755
787
const gchar **attribute_values,
758
const gchar *name, *exec, *count, *stamp;
790
const gchar *name, *exec, *count, *stamp, *modified;
759
791
const gchar *attr;
761
793
BookmarkItem *item;
764
796
g_warn_if_fail ((parse_data != NULL) && (parse_data->state == STATE_APPLICATION));
767
name = exec = count = stamp = NULL;
799
name = exec = count = stamp = modified = NULL;
768
800
for (attr = attribute_names[i]; attr != NULL; attr = attribute_names[++i])
770
802
if (IS_ATTRIBUTE (attr, BOOKMARK_NAME_ATTRIBUTE))
775
807
count = attribute_values[i];
776
808
else if (IS_ATTRIBUTE (attr, BOOKMARK_TIMESTAMP_ATTRIBUTE))
777
809
stamp = attribute_values[i];
780
g_set_error (error, G_MARKUP_ERROR,
781
G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
782
_("Unexpected attribute '%s' for element '%s'"),
784
BOOKMARK_APPLICATION_ELEMENT);
810
else if (IS_ATTRIBUTE (attr, BOOKMARK_MODIFIED_ATTRIBUTE))
811
modified = attribute_values[i];
814
/* the "name" and "exec" attributes are mandatory */
791
817
g_set_error (error, G_MARKUP_ERROR,
827
853
ai->count = atoi (count);
832
ai->stamp = (time_t) atol (stamp);
858
ai->stamp = timestamp_from_iso8601 (modified);
834
ai->stamp = time (NULL);
861
/* the timestamp attribute has been deprecated but we still parse
862
* it for backward compatibility
865
ai->stamp = (time_t) atol (stamp);
867
ai->stamp = time (NULL);
855
889
if (IS_ATTRIBUTE (attr, MIME_TYPE_ATTRIBUTE))
856
890
type = attribute_values[i];
859
g_set_error (error, G_MARKUP_ERROR,
860
G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
861
_("Unexpected attribute '%s' for element '%s'"),
901
926
href = attribute_values[i];
902
927
else if (IS_ATTRIBUTE (attr, BOOKMARK_TYPE_ATTRIBUTE))
903
928
type = attribute_values[i];
906
g_set_error (error, G_MARKUP_ERROR,
907
G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
908
_("Unexpected attribute '%s' for element '%s'"),
910
BOOKMARK_ICON_ELEMENT);
931
/* the "href" attribute is mandatory */
917
934
g_set_error (error, G_MARKUP_ERROR,
1017
1034
* namespace has been set, just do a plain comparison between @full_element
1018
1035
* and @element.
1020
p = strchr (element_full, ':');
1037
p = g_utf8_strchr (element_full, -1, ':');
1023
1040
ns_name = g_strndup (element_full, p - element_full);
1038
1055
return (0 == strcmp (element_full, element));
1041
resolved = g_strdup_printf ("%s%c%s", ns_uri, sep, element_name);
1042
s = g_strdup_printf ("%s%c%s", namespace, sep, element);
1043
retval = (0 == strcmp (resolved, s));
1058
retval = (0 == strcmp (ns_uri, namespace) &&
1059
0 == strcmp (element_name, element));
1045
1061
g_free (ns_name);
1438
1452
GError **error)
1440
1454
GString *retval;
1443
retval = g_string_new (NULL);
1445
g_string_append_printf (retval,
1446
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
1448
/* XXX - do we really need the doctype? */
1454
" xmlns:%s=\"%s\"\n"
1455
" xmlns:%s=\"%s\"\n>",
1457
/* XXX - do we really need the doctype? */
1459
XBEL_DTD_SYSTEM, XBEL_DTD_URI,
1462
XBEL_VERSION_ATTRIBUTE, XBEL_VERSION,
1463
BOOKMARK_NAMESPACE_NAME, BOOKMARK_NAMESPACE_URI,
1464
MIME_NAMESPACE_NAME, MIME_NAMESPACE_URI);
1458
retval = g_string_sized_new (4096);
1460
g_string_append (retval,
1461
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
1463
/* XXX - do we really need the doctype? */
1464
"<!DOCTYPE " XBEL_DTD_NICK "\n"
1465
" PUBLIC \"" XBEL_DTD_SYSTEM "\"\n"
1466
" \"" XBEL_DTD_URI "\">\n"
1468
"<" XBEL_ROOT_ELEMENT " " XBEL_VERSION_ATTRIBUTE "=\"" XBEL_VERSION "\"\n"
1469
" xmlns:" BOOKMARK_NAMESPACE_NAME "=\"" BOOKMARK_NAMESPACE_URI "\"\n"
1470
" xmlns:" MIME_NAMESPACE_NAME "=\"" MIME_NAMESPACE_URI "\"\n>");
1466
1472
if (bookmark->title)
1468
1474
gchar *escaped_title;
1470
1476
escaped_title = g_markup_escape_text (bookmark->title, -1);
1472
g_string_append_printf (retval, " <%s>%s</%s>\n",
1475
XBEL_TITLE_ELEMENT);
1478
buffer = g_strconcat (" "
1479
"<" XBEL_TITLE_ELEMENT ">",
1481
"</" XBEL_TITLE_ELEMENT ">\n", NULL);
1483
g_string_append (retval, buffer);
1477
1486
g_free (escaped_title);
1480
1489
if (bookmark->description)
1482
1491
gchar *escaped_desc;
1484
1493
escaped_desc = g_markup_escape_text (bookmark->description, -1);
1486
g_string_append_printf (retval, " <%s>%s</%s>\n",
1495
buffer = g_strconcat (" "
1496
"<" XBEL_DESC_ELEMENT ">",
1498
"</" XBEL_DESC_ELEMENT ">\n", NULL);
1499
g_string_append (retval, buffer);
1491
1502
g_free (escaped_desc);
1510
1522
retval = g_string_append (retval, item_dump);
1516
g_string_append_printf (retval, "</%s>", XBEL_ROOT_ELEMENT);
1528
g_string_append (retval, "</" XBEL_ROOT_ELEMENT ">");
1519
1531
*length = retval->len;
1779
g_set_error (error, G_BOOKMARK_FILE_ERROR,
1780
G_BOOKMARK_FILE_ERROR_FILE_NOT_FOUND,
1781
_("No valid bookmark file found in data dirs"));
1791
g_set_error_literal (error, G_BOOKMARK_FILE_ERROR,
1792
G_BOOKMARK_FILE_ERROR_FILE_NOT_FOUND,
1793
_("No valid bookmark file found in data dirs"));
2086
2098
n_items = g_list_length (bookmark->items);
2087
2099
uris = g_new0 (gchar *, n_items + 1);
2101
/* the items are stored in reverse order, so we walk the list backward */
2089
2102
for (l = g_list_last (bookmark->items), i = 0; l != NULL; l = l->prev)
2091
2104
BookmarkItem *item = (BookmarkItem *) l->data;
3598
3611
* @href: the URI of the icon for the bookmark, or %NULL
3599
3612
* @mime_type: the MIME type of the icon for the bookmark
3601
* Sets the icon for the bookmark for @uri. If @href is %NULL, unsets
3602
* the currently set icon.
3614
* Sets the icon for the bookmark for @uri. If @href is %NULL, unsets
3615
* the currently set icon. @href can either be a full URL for the icon
3616
* file or the icon name following the Icon Naming specification.
3604
* If no bookmark for @uri is found it is created.
3618
* If no bookmark for @uri is found one is created.