#include <config.h>
#endif
+#include <glib/gstdio.h>
#include <glib/gi18n.h>
#if HAVE_LIBXML
return TRUE;
}
+static gboolean
+katze_array_from_opera_file (KatzeArray* array,
+ FILE* file)
+{
+ gchar line[200];
+ KatzeArray* folder = array;
+ KatzeItem* item = NULL;
+
+ while (fgets (line, 200, file))
+ {
+ g_strstrip (line);
+ if (line[0] == '\0')
+ {
+ item = NULL;
+ continue;
+ }
+ else if (line[0] == '-')
+ {
+ item = NULL;
+ if (folder != array)
+ folder = katze_item_get_parent ((KatzeItem*)folder);
+ else
+ g_warning ("A level-up although we are at the top level");
+ continue;
+ }
+
+ if (line[0] == '#')
+ {
+ const gchar* element = &line[1];
+ if (!g_ascii_strncasecmp (element, "FOLDER", 6))
+ {
+ item = (KatzeItem*)katze_array_new (KATZE_TYPE_ARRAY);
+ katze_array_add_item (folder, item);
+ folder = (KatzeArray*)item;
+ }
+ else if (!g_ascii_strncasecmp (element, "URL", 3))
+ {
+ item = katze_item_new ();
+ katze_array_add_item (folder, item);
+ }
+ else
+ g_warning ("Unexpected element: %s", element);
+ }
+ else if (item)
+ {
+ gchar** parts = g_strsplit (line, "=", 2);
+ if (parts && parts[0] && parts[1])
+ {
+ if (g_str_equal (parts[0], "NAME"))
+ katze_item_set_name (item, parts[1]);
+ else if (g_str_equal (parts[0], "URL"))
+ katze_item_set_uri (item, parts[1]);
+ else if (g_str_equal (parts[0], "DESCRIPTION"))
+ katze_item_set_text (item, parts[1]);
+ else if (g_str_equal (parts[0], "CREATED"))
+ katze_item_set_added (item,
+ g_ascii_strtoull (parts[1], NULL, 10));
+ /* FIXME: Implement visited time
+ else if (g_str_equal (parts[0], "VISITED"))
+ katze_item_set_visited (item,
+ g_ascii_strtoull (parts[1], NULL, 10)); */
+ /* FIXME: Implement bookmarkbar flag
+ else if (g_str_equal (parts[0], "ON PERSONALBAR"))
+ ; */
+ /* FIXME: Implement websites as panels
+ else if (g_str_equal (parts[0], "IN PANEL"))
+ ; */
+ }
+ else
+ g_warning ("Broken property: %s", line);
+ g_strfreev (parts);
+ }
+ else
+ g_warning ("Unexpected property outside of element: %s", line);
+ }
+ return TRUE;
+}
+
/**
* midori_array_from_file:
* @array: a #KatzeArray
* @filename: a filename to load from
- * @format: the desired format
+ * @format: "xbel", "opera", or %NULL
* @error: a #GError or %NULL
*
* Loads the contents of a file in the specified format.
*
+ * Since 0.2.2 @format can be %NULL to indicate that the
+ * file should be loaded if it's any supported format.
+ *
* Return value: %TRUE on success, %FALSE otherwise
*
* Since: 0.1.6
const gchar* format,
GError** error)
{
- xmlDocPtr doc;
-
g_return_val_if_fail (katze_array_is_a (array, KATZE_TYPE_ITEM), FALSE);
g_return_val_if_fail (filename != NULL, FALSE);
- g_return_val_if_fail (!g_strcmp0 (format, "xbel"), FALSE);
g_return_val_if_fail (!error || !*error, FALSE);
if (!g_file_test (filename, G_FILE_TEST_EXISTS))
return FALSE;
}
- if ((doc = xmlParseFile (filename)) == NULL)
+ /* Opera6 */
+ if (!g_strcmp0 (format, "opera")
+ || (!format && g_str_has_suffix (filename, ".adr")))
{
- /* No valid xml or broken encoding */
- if (error)
- *error = g_error_new_literal (G_FILE_ERROR, G_FILE_ERROR_FAILED,
- _("Malformed document."));
- return FALSE;
+ FILE* file;
+ if ((file = g_fopen (filename, "r")))
+ {
+ guint verify;
+ gchar line[50];
+
+ verify = 0;
+ while (fgets (line, 50, file))
+ {
+ g_strstrip (line);
+ if (verify == 0 && !strcmp (line, "Opera Hotlist version 2.0"))
+ verify++;
+ else if (verify == 1
+ && !strcmp (line, "Options: encoding = utf8, version=3"))
+ verify++;
+ else if (verify == 2)
+ {
+ if (!katze_array_from_opera_file (array, file))
+ {
+ /* Parsing failed */
+ fclose (file);
+ if (error)
+ *error = g_error_new_literal (G_FILE_ERROR,
+ G_FILE_ERROR_FAILED, _("Malformed document."));
+ return FALSE;
+ }
+ return TRUE;
+ }
+ else
+ break;
+ }
+ fclose (file);
+ }
}
- if (!katze_array_from_xmlDocPtr (array, doc))
+ /* XBEL */
+ if (!g_strcmp0 (format, "xbel")
+ || !format)
{
- /* Parsing failed */
+ xmlDocPtr doc;
+
+ if ((doc = xmlParseFile (filename)) == NULL)
+ {
+ /* No valid xml or broken encoding */
+ if (error)
+ *error = g_error_new_literal (G_FILE_ERROR, G_FILE_ERROR_FAILED,
+ _("Malformed document."));
+ return FALSE;
+ }
+
+ if (!katze_array_from_xmlDocPtr (array, doc))
+ {
+ /* Parsing failed */
+ xmlFreeDoc (doc);
+ if (error)
+ *error = g_error_new_literal (G_FILE_ERROR, G_FILE_ERROR_FAILED,
+ _("Malformed document."));
+ return FALSE;
+ }
xmlFreeDoc (doc);
- if (error)
- *error = g_error_new_literal (G_FILE_ERROR, G_FILE_ERROR_FAILED,
- _("Malformed document."));
- return FALSE;
+ return TRUE;
}
- xmlFreeDoc (doc);
- return TRUE;
+
+ if (error)
+ *error = g_error_new_literal (G_FILE_ERROR, G_FILE_ERROR_FAILED,
+ _("Unrecognized bookmark format."));
+ return FALSE;
}
#endif
} BookmarkClient;
static const BookmarkClient bookmark_clients[] = {
{ ".local/share/data/Arora/bookmarks.xbel", N_("Arora") },
+ { ".opera/bookmarks.adr", N_("Opera") },
};
GtkWidget* dialog;
GtkWidget* label;
GtkWidget* combo;
GtkComboBox* combobox;
+ GtkComboBox* combobox_folder;
guint i;
KatzeItem* item;
gtk_size_group_add_widget (sizegroup, label);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
combo = gtk_combo_box_new_text ();
- combobox = GTK_COMBO_BOX (combo);
- gtk_combo_box_append_text (combobox, _("Toplevel folder"));
- gtk_combo_box_set_active (combobox, 0);
+ combobox_folder = GTK_COMBO_BOX (combo);
+ gtk_combo_box_append_text (combobox_folder, _("Toplevel folder"));
+ gtk_combo_box_set_active (combobox_folder, 0);
i = 0;
while ((item = katze_array_get_nth_item (browser->bookmarks, i++)))
{
if (KATZE_IS_ARRAY (item))
{
const gchar* name = katze_item_get_name (item);
- gtk_combo_box_append_text (combobox, name);
+ if (name)
+ gtk_combo_box_append_text (combobox_folder, name);
}
}
gtk_box_pack_start (GTK_BOX (hbox), combo, TRUE, TRUE, 0);
i = gtk_combo_box_get_active (combobox);
path = g_build_filename (g_get_home_dir (), bookmark_clients[i].path, NULL);
- selected = gtk_combo_box_get_active_text (combobox);
+ selected = gtk_combo_box_get_active_text (combobox_folder);
folder = browser->bookmarks;
if (g_strcmp0 (selected, _("Toplevel folder")))
{
g_free (selected);
error = NULL;
- if (!midori_array_from_file (folder, path, "xbel", &error))
+ if (!midori_array_from_file (folder, path, NULL, &error))
{
GtkWidget* error_dialog = gtk_message_dialog_new (
GTK_WINDOW (browser), GTK_DIALOG_DESTROY_WITH_PARENT,