diff options
-rw-r--r-- | shell/ChangeLog | 24 | ||||
-rw-r--r-- | shell/e-config-upgrade.c | 154 | ||||
-rw-r--r-- | shell/e-shell-importer.c | 56 |
3 files changed, 183 insertions, 51 deletions
diff --git a/shell/ChangeLog b/shell/ChangeLog index dd517ec0a9..4eb210ce89 100644 --- a/shell/ChangeLog +++ b/shell/ChangeLog @@ -1,3 +1,27 @@ +2003-04-28 Not Zed <NotZed@Ximian.com> + + [#41013] + + * e-shell-importer.c (html_size_req): removed. + (create_help): renamed from create_html. Only creates a plain + label widget now, with line wrap turned on. Also make the + g_return an assert, it failing is entirely based on internal code. + (show_import_wizard): s/create_html/create_help/g + + [#41648] + + * e-config-upgrade.c (upgrade_xml_file): upgrade_xml_file_1_0 made + a bit more generic, this handles io, a callback handles xml + changes. + (is_xml1encoded): new function to tell if a string is in gal's + xml1 'encoded' format, or raw locale text. + (decode_xml1): decode xml1 encoded format to valid utf8. + (upgrade_xml_1_2_rec): upgrades xml1 encoded or badly encoded xml + content for specific parent->child nodes. + (CONF_REVISION): bump the config revision to 1.3.1. + (e_config_upgrade): if config revision < 1.3.1, then check xml + files for xml1 content. + 2003-04-28 Rodney Dawes <dobey@ximian.com> * Makefile.am: Fix up some stuff for the nognome script diff --git a/shell/e-config-upgrade.c b/shell/e-config-upgrade.c index 04e3edbf85..48f141bde8 100644 --- a/shell/e-config-upgrade.c +++ b/shell/e-config-upgrade.c @@ -31,6 +31,7 @@ #include <errno.h> #include <regex.h> #include <string.h> +#include <ctype.h> #include <glib.h> #include <gconf/gconf.h> @@ -42,12 +43,12 @@ #include "e-config-upgrade.h" -#define d(x) +#define d(x) /* output revision of configuration */ #define CONF_MAJOR (1) #define CONF_MINOR (3) -#define CONF_REVISION (0) +#define CONF_REVISION (1) /* major/minor/revision of existing config */ static unsigned int major = -1; @@ -541,7 +542,131 @@ static int upgrade_xml_1_0_rec(xmlNodePtr node) return work; } -static int upgrade_xml_file_1_0(const char *filename) +/* ********************************************************************** */ +/* XML 1 content encoding */ + +static int +is_xml1encoded(const char *txt) +{ + const unsigned char *p; + int isxml1 = FALSE; + int is8bit = FALSE; + + p = (const unsigned char *)txt; + while (*p) { + if (p[0] == '\\' && p[1] == 'U' && p[2] == '+' + && isxdigit(p[3]) && isxdigit(p[4]) && isxdigit(p[5]) && isxdigit(p[6]) + && p[7] == '\\') { + isxml1 = TRUE; + p+=7; + } else if (p[0] >= 0x80) + is8bit = TRUE; + p++; + } + + /* check for invalid utf8 that needs cleaning */ + if (is8bit && (!isxml1)) + isxml1 = !g_utf8_validate(txt, -1, NULL); + + return isxml1; +} + +static char * +decode_xml1(const char *txt) +{ + GString *out = g_string_new(""); + const unsigned char *p; + char *res; + + /* convert: + \U+XXXX\ -> utf8 + 8 bit characters -> utf8 (iso-8859-1) */ + + p = (const unsigned char *)txt; + while (*p) { + if (p[0] > 0x80 + || (p[0] == '\\' && p[1] == 'U' && p[2] == '+' + && isxdigit(p[3]) && isxdigit(p[4]) && isxdigit(p[5]) && isxdigit(p[6]) + && p[7] == '\\')) { + char utf8[8]; + gunichar u; + + if (p[0] == '\\') { + memcpy(utf8, p+3, 4); + utf8[4] = 0; + u = strtoul(utf8, NULL, 16); + p+=7; + } else + u = p[0]; + utf8[g_unichar_to_utf8(u, utf8)] = 0; + g_string_append(out, utf8); + } else { + g_string_append_c(out, *p); + } + p++; + } + + res = out->str; + g_string_free(out, FALSE); + + return res; +} + +static int +upgrade_xml_1_2_rec(xmlNodePtr node) +{ + const char *value_tags[] = { "string", "address", "regex", "file", "command", NULL }; + const char *rule_tags[] = { "title", NULL }; + const struct { + char *name; + const char **tags; + } tags[] = { + { "value", value_tags }, + { "rule", rule_tags }, + { 0 }, + }; + int changed = 0; + xmlNodePtr work; + int i,j; + char *txt, *tmp; + + /* upgrades the content of a node, if the node has a specific parent/node name */ + + for (i=0;tags[i].name;i++) { + if (!strcmp(node->name, tags[i].name)) { + work = node->children; + while (work) { + for (j=0;tags[i].tags[j];j++) { + if (!strcmp(work->name, tags[i].tags[j])) { + txt = xmlNodeGetContent(work); + if (is_xml1encoded(txt)) { + tmp = decode_xml1(txt); + d(printf("upgrading xml node %s/%s '%s' -> '%s'\n", tags[i].name, tags[i].tags[j], txt, tmp)); + xmlNodeSetContent(work, tmp); + changed = 1; + g_free(tmp); + } + xmlFree(txt); + } + } + work = work->next; + } + break; + } + } + + node = node->children; + while (node) { + changed |= upgrade_xml_1_2_rec(node); + node = node->next; + } + + return changed; +} + +/* ********************************************************************** */ + +static int upgrade_xml_file(const char *filename, int (*upgrade_rec)(xmlNodePtr root)) { xmlDocPtr doc; char *savename; @@ -567,9 +692,9 @@ static int upgrade_xml_file_1_0(const char *filename) return -1; } - if (!upgrade_xml_1_0_rec(doc->xmlRootNode)) { + if (!upgrade_rec(doc->xmlRootNode)) { xmlFreeDoc(doc); - printf("file %s contains no old urls\n", filename); + printf("file %s contains nothing to upgrade\n", filename); return 0; } @@ -1700,7 +1825,7 @@ e_config_upgrade(const char *edir) char *path; path = g_build_filename(evolution_dir, xml_files[i], NULL); - if (upgrade_xml_file_1_0(path) == -1) + if (upgrade_xml_file(path, upgrade_xml_1_0_rec) == -1) g_warning("Could not upgrade xml file %s", xml_files[i]); g_free(path); @@ -1715,6 +1840,23 @@ e_config_upgrade(const char *edir) } } + if (major <=1 && minor <=3 && revision < 1) { + /* check for xml 1 encoding from version 1.2 upgrade or from a previous previous 1.3.0 upgrade */ + char *xml_files[] = { "vfolders.xml", "filters.xml" }; + + d(printf("Checking for xml1 format xml files\n")); + + for (i=0;i<sizeof(xml_files)/sizeof(xml_files[0]);i++) { + char *path; + + path = g_build_filename(evolution_dir, xml_files[i], NULL); + if (upgrade_xml_file(path, upgrade_xml_1_2_rec) == -1) + g_warning("Could not upgrade xml file %s", xml_files[i]); + + g_free(path); + } + } + /* 3. we're done, update our version info if its changed */ if (major < CONF_MAJOR || minor < CONF_MINOR diff --git a/shell/e-shell-importer.c b/shell/e-shell-importer.c index bc03ab4417..309fa313a9 100644 --- a/shell/e-shell-importer.c +++ b/shell/e-shell-importer.c @@ -53,7 +53,6 @@ #include "importer/evolution-importer-client.h" #include <glade/glade.h> -#include <gtkhtml/gtkhtml.h> #include <gal/widgets/e-gui-utils.h> #include <gal/widgets/e-unicode.h> @@ -132,7 +131,6 @@ typedef struct _SelectedImporterData{ #define OUT #endif -/* Some HTML helper functions copied from mail/mail-config-druid.c */ static struct { char *name; char *text; @@ -150,57 +148,25 @@ static struct { N_("Please select the information that you would like to import:") } }; -static int num_info = (sizeof (info) / sizeof (info[0])); - -static void -html_size_req (GtkWidget *widget, - GtkRequisition *requisition) -{ - requisition->height = GTK_LAYOUT (widget)->height; -} +#define num_info (sizeof (info) / sizeof (info[0])) static GtkWidget * -create_html (const char *name) +create_help (const char *name) { - GtkWidget *scrolled, *html; - GtkHTMLStream *stream; - GtkStyle *style; + GtkWidget *label; int i; - html = gtk_html_new (); - GTK_LAYOUT (html)->height = 0; - g_signal_connect (html, "size_request", - G_CALLBACK (html_size_req), NULL); - gtk_html_set_editable (GTK_HTML (html), FALSE); - style = gtk_rc_get_style (html); - if (!style) - style = gtk_widget_get_style (html); - if (style) { - gtk_widget_modify_base (html, GTK_STATE_NORMAL, &style->bg[GTK_STATE_NORMAL]); - gtk_widget_modify_text (html, GTK_STATE_NORMAL, &style->fg[GTK_STATE_NORMAL]); - } - gtk_widget_show (html); - - scrolled = gtk_scrolled_window_new (NULL, NULL); - gtk_widget_show (scrolled); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), - GTK_POLICY_NEVER, GTK_POLICY_NEVER); - gtk_container_add (GTK_CONTAINER (scrolled), html); - for (i = 0; i < num_info; i++) { if (!strcmp (name, info[i].name)) break; } - g_return_val_if_fail (i != num_info, scrolled); + g_assert(i != num_info); - stream = gtk_html_begin_content (GTK_HTML (html), - "text/html; charset=utf-8"); - gtk_html_write (GTK_HTML (html), stream, "<html><p>", 9); - gtk_html_write (GTK_HTML (html), stream, _(info[i].text), strlen (_(info[i].text))); - gtk_html_write (GTK_HTML (html), stream, "</p></html>", 11); - gtk_html_end (GTK_HTML (html), stream, GTK_HTML_STREAM_OK); + label = gtk_label_new(_(info[i].text)); + gtk_widget_show (label); + gtk_label_set_line_wrap((GtkLabel *)label, TRUE); - return scrolled; + return label; } /* Importing functions */ @@ -1217,7 +1183,7 @@ show_import_wizard (BonoboUIComponent *component, g_signal_connect (data->typedialog, "next", G_CALLBACK (next_type_page), data); data->typepage = importer_type_page_new (data); - html = create_html ("type_html"); + html = create_help ("type_html"); gtk_box_pack_start (GTK_BOX (data->typepage->vbox), html, FALSE, TRUE, 0); gtk_box_reorder_child (GTK_BOX (data->typepage->vbox), html, 0); @@ -1232,7 +1198,7 @@ show_import_wizard (BonoboUIComponent *component, G_CALLBACK (prepare_intelligent_page), data); data->importerpage = importer_importer_page_new (data); - html = create_html ("intelligent_html"); + html = create_help ("intelligent_html"); gtk_box_pack_start (GTK_BOX (data->importerpage->vbox), html, FALSE, TRUE, 0); gtk_box_reorder_child (GTK_BOX (data->importerpage->vbox), html, 0); @@ -1253,7 +1219,7 @@ show_import_wizard (BonoboUIComponent *component, data->filepage = importer_file_page_new (data); - html = create_html ("file_html"); + html = create_help ("file_html"); gtk_box_pack_start (GTK_BOX (data->filepage->vbox), html, FALSE, TRUE, 0); gtk_box_reorder_child (GTK_BOX (data->filepage->vbox), html, 0); |