evolution r36560 - in branches/kill-bonobo: addressbook/gui/component calendar/gui calendar/modules doc/reference/shell doc/reference/shell/tmpl shell shell/test
- From: mbarnes svn gnome org
- To: svn-commits-list gnome org
- Subject: evolution r36560 - in branches/kill-bonobo: addressbook/gui/component calendar/gui calendar/modules doc/reference/shell doc/reference/shell/tmpl shell shell/test
- Date: Sun, 5 Oct 2008 04:12:09 +0000 (UTC)
Author: mbarnes
Date: Sun Oct 5 04:12:09 2008
New Revision: 36560
URL: http://svn.gnome.org/viewvc/evolution?rev=36560&view=rev
Log:
Support migration in the new shell design.
Some code got duplicated for calendars and tasks. Made a note to revisit.
Added:
branches/kill-bonobo/addressbook/gui/component/e-book-shell-module-migrate.c (contents, props changed)
- copied, changed from r36534, /branches/kill-bonobo/addressbook/gui/component/addressbook-migrate.c
branches/kill-bonobo/addressbook/gui/component/e-book-shell-module-migrate.h (contents, props changed)
- copied, changed from r36307, /branches/kill-bonobo/addressbook/gui/component/addressbook-migrate.h
branches/kill-bonobo/calendar/modules/e-cal-shell-module-migrate.c
branches/kill-bonobo/calendar/modules/e-cal-shell-module-migrate.h
branches/kill-bonobo/calendar/modules/e-memo-shell-module-migrate.c
branches/kill-bonobo/calendar/modules/e-memo-shell-module-migrate.h
branches/kill-bonobo/calendar/modules/e-task-shell-module-migrate.c
branches/kill-bonobo/calendar/modules/e-task-shell-module-migrate.h
branches/kill-bonobo/shell/e-shell-migrate.c (contents, props changed)
branches/kill-bonobo/shell/e-shell-migrate.h (contents, props changed)
Removed:
branches/kill-bonobo/addressbook/gui/component/addressbook-migrate.c
branches/kill-bonobo/addressbook/gui/component/addressbook-migrate.h
branches/kill-bonobo/calendar/gui/migration.c
branches/kill-bonobo/calendar/gui/migration.h
Modified:
branches/kill-bonobo/addressbook/gui/component/Makefile.am
branches/kill-bonobo/addressbook/gui/component/e-book-shell-module.c
branches/kill-bonobo/addressbook/gui/component/e-book-shell-view-private.c
branches/kill-bonobo/calendar/gui/Makefile.am
branches/kill-bonobo/calendar/gui/e-cal-event.c
branches/kill-bonobo/calendar/gui/e-cal-event.h
branches/kill-bonobo/calendar/modules/e-cal-shell-module.c
branches/kill-bonobo/calendar/modules/e-memo-shell-module.c
branches/kill-bonobo/calendar/modules/e-task-shell-module.c
branches/kill-bonobo/calendar/modules/e-task-shell-sidebar.c
branches/kill-bonobo/doc/reference/shell/Makefile.am
branches/kill-bonobo/doc/reference/shell/eshell-sections.txt
branches/kill-bonobo/doc/reference/shell/tmpl/e-shell-module.sgml
branches/kill-bonobo/doc/reference/shell/tmpl/e-shell.sgml
branches/kill-bonobo/shell/Makefile.am
branches/kill-bonobo/shell/e-shell-module.c
branches/kill-bonobo/shell/e-shell-module.h
branches/kill-bonobo/shell/e-shell.c
branches/kill-bonobo/shell/e-shell.h
branches/kill-bonobo/shell/test/e-test-shell-module.c
Modified: branches/kill-bonobo/addressbook/gui/component/Makefile.am
==============================================================================
--- branches/kill-bonobo/addressbook/gui/component/Makefile.am (original)
+++ branches/kill-bonobo/addressbook/gui/component/Makefile.am Sun Oct 5 04:12:09 2008
@@ -28,8 +28,6 @@
libevolution_addressbook_la_SOURCES = \
addressbook-config.c \
addressbook-config.h \
- addressbook-migrate.c \
- addressbook-migrate.h \
autocompletion-config.c \
autocompletion-config.h \
addressbook.c \
@@ -37,6 +35,8 @@
e-book-shell-content.c \
e-book-shell-content.h \
e-book-shell-module.c \
+ e-book-shell-module-migrate.c \
+ e-book-shell-module-migrate.h \
e-book-shell-sidebar.c \
e-book-shell-sidebar.h \
e-book-shell-view.c \
Copied: branches/kill-bonobo/addressbook/gui/component/e-book-shell-module-migrate.c (from r36534, /branches/kill-bonobo/addressbook/gui/component/addressbook-migrate.c)
==============================================================================
--- /branches/kill-bonobo/addressbook/gui/component/addressbook-migrate.c (original)
+++ branches/kill-bonobo/addressbook/gui/component/e-book-shell-module-migrate.c Sun Oct 5 04:12:09 2008
@@ -1,4 +1,6 @@
/*
+ * e-book-shell-module-migrate.c
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -45,7 +47,7 @@
#include "e-util/e-xml-utils.h"
#include "e-util/e-folder-map.h"
-#include "addressbook-migrate.h"
+#include "e-book-shell-module-migrate.h"
/*#define SLOW_MIGRATION*/
@@ -1110,11 +1112,11 @@
}
gboolean
-addressbook_migrate (EShellModule *shell_module,
- gint major,
- gint minor,
- gint revision,
- GError **error)
+e_book_shell_module_migrate (EShellModule *shell_module,
+ gint major,
+ gint minor,
+ gint micro,
+ GError **error)
{
ESourceGroup *on_this_computer;
ESourceGroup *on_ldap_servers;
@@ -1123,8 +1125,6 @@
gboolean need_dialog = FALSE;
const gchar *data_dir;
- printf ("addressbook_migrate (%d.%d.%d)\n", major, minor, revision);
-
g_return_val_if_fail (E_IS_SHELL_MODULE (shell_module), FALSE);
data_dir = e_shell_module_get_data_dir (shell_module);
@@ -1139,7 +1139,7 @@
if (major == 1
/* we only need the most recent upgrade point here.
further decomposition will happen below. */
- && (minor < 5 || (minor == 5 && revision <= 10)))
+ && (minor < 5 || (minor == 5 && micro <= 10)))
need_dialog = TRUE;
if (need_dialog)
@@ -1147,7 +1147,7 @@
if (major == 1) {
- if (minor < 5 || (minor == 5 && revision <= 2)) {
+ if (minor < 5 || (minor == 5 && micro <= 2)) {
/* initialize our dialog */
dialog_set_label (context,
_("The location and hierarchy of the Evolution contact "
@@ -1162,7 +1162,7 @@
migrate_completion_folders (context);
}
- if (minor < 5 || (minor == 5 && revision <= 7)) {
+ if (minor < 5 || (minor == 5 && micro <= 7)) {
dialog_set_label (context,
_("The format of mailing list contacts has changed.\n\n"
"Please be patient while Evolution migrates your "
@@ -1171,7 +1171,7 @@
migrate_contact_lists_for_local_folders (context, on_this_computer);
}
- if (minor < 5 || (minor == 5 && revision <= 8)) {
+ if (minor < 5 || (minor == 5 && micro <= 8)) {
dialog_set_label (context,
_("The way Evolution stores some phone numbers has changed.\n\n"
"Please be patient while Evolution migrates your "
@@ -1180,7 +1180,7 @@
migrate_company_phone_for_local_folders (context, on_this_computer);
}
- if (minor < 5 || (minor == 5 && revision <= 10)) {
+ if (minor < 5 || (minor == 5 && micro <= 10)) {
char *old_path, *new_path;
dialog_set_label (context, _("Evolution's Palm Sync changelog and map files have changed.\n\n"
@@ -1199,7 +1199,7 @@
during one phase of development, as they take
precedent over relative uris (but aren't updated
when editing an ESource). */
- if (minor == 5 && revision <= 11) {
+ if (minor == 5 && micro <= 11) {
GSList *g;
for (g = e_source_list_peek_groups (context->source_list); g; g = g->next) {
ESourceGroup *group = g->data;
Copied: branches/kill-bonobo/addressbook/gui/component/e-book-shell-module-migrate.h (from r36307, /branches/kill-bonobo/addressbook/gui/component/addressbook-migrate.h)
==============================================================================
--- /branches/kill-bonobo/addressbook/gui/component/addressbook-migrate.h (original)
+++ branches/kill-bonobo/addressbook/gui/component/e-book-shell-module-migrate.h Sun Oct 5 04:12:09 2008
@@ -1,4 +1,5 @@
/*
+ * e-book-shell-module-migrate.h
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -21,20 +22,20 @@
*
*/
-#ifndef _ADDRESSBOOK_MIGRATE_H_
-#define _ADDRESSBOOK_MIGRATE_H_
+#ifndef E_BOOK_SHELL_MODULE_MIGRATE_H
+#define E_BOOK_SHELL_MODULE_MIGRATE_H
#include <glib.h>
-#include <e-shell-module.h>
+#include <shell/e-shell-module.h>
G_BEGIN_DECLS
-gboolean addressbook_migrate (EShellModule *shell_module,
+gboolean e_book_shell_module_migrate (EShellModule *shell_module,
gint major,
gint minor,
- gint revision,
+ gint micro,
GError **error);
G_END_DECLS
-#endif /* _ADDRESSBOOK_MIGRATE_H_ */
+#endif /* E_BOOK_SHELL_MODULE_MIGRATE_H */
Modified: branches/kill-bonobo/addressbook/gui/component/e-book-shell-module.c
==============================================================================
--- branches/kill-bonobo/addressbook/gui/component/e-book-shell-module.c (original)
+++ branches/kill-bonobo/addressbook/gui/component/e-book-shell-module.c Sun Oct 5 04:12:09 2008
@@ -27,19 +27,21 @@
#include <libedataserver/e-source-list.h>
#include <libedataserver/e-source-group.h>
-#include <e-shell.h>
-#include <e-shell-module.h>
-#include <e-shell-window.h>
+#include "shell/e-shell.h"
+#include "shell/e-shell-module.h"
+#include "shell/e-shell-window.h"
-#include <e-util/e-import.h>
-#include <addressbook/importers/evolution-addressbook-importers.h>
+#include "e-util/e-import.h"
+#include "addressbook/importers/evolution-addressbook-importers.h"
#include <eab-config.h>
#include <eab-gui-util.h>
-#include <e-book-shell-view.h>
#include <addressbook-config.h>
#include <autocompletion-config.h>
+#include "e-book-shell-view.h"
+#include "e-book-shell-module-migrate.h"
+
#define MODULE_NAME "addressbook"
#define MODULE_ALIASES "contacts"
#define MODULE_SCHEMES ""
@@ -52,7 +54,7 @@
void e_shell_module_init (GTypeModule *type_module);
static void
-book_module_ensure_sources (EShellModule *shell_module)
+book_shell_module_ensure_sources (EShellModule *shell_module)
{
/* XXX This is basically the same algorithm across all modules.
* Maybe we could somehow integrate this into EShellModule? */
@@ -182,7 +184,7 @@
}
static void
-book_module_init_importers (void)
+book_shell_module_init_importers (void)
{
EImportClass *import_class;
EImportImporter *importer;
@@ -206,9 +208,9 @@
}
static void
-book_module_book_loaded_cb (EBook *book,
- EBookStatus status,
- gpointer user_data)
+book_shell_module_book_loaded_cb (EBook *book,
+ EBookStatus status,
+ gpointer user_data)
{
EContact *contact;
GtkAction *action;
@@ -266,7 +268,8 @@
if (book == NULL)
book = e_book_new_default_addressbook (NULL);
- e_book_async_open (book, FALSE, book_module_book_loaded_cb, action);
+ e_book_async_open (
+ book, FALSE, book_shell_module_book_loaded_cb, action);
}
static void
@@ -304,21 +307,21 @@
};
static gboolean
-book_module_is_busy (EShellModule *shell_module)
+book_shell_module_is_busy (EShellModule *shell_module)
{
return !eab_editor_request_close_all ();
}
static gboolean
-book_module_shutdown (EShellModule *shell_module)
+book_shell_module_shutdown (EShellModule *shell_module)
{
/* FIXME */
return TRUE;
}
static gboolean
-book_module_handle_uri (EShellModule *shell_module,
- const gchar *uri)
+book_shell_module_handle_uri (EShellModule *shell_module,
+ const gchar *uri)
{
EUri *euri;
const gchar *cp;
@@ -383,8 +386,8 @@
}
static void
-book_module_window_created (EShellModule *shell_module,
- EShellWindow *shell_window)
+book_shell_module_window_created (EShellModule *shell_module,
+ EShellWindow *shell_window)
{
const gchar *module_name;
@@ -407,8 +410,9 @@
MODULE_SORT_ORDER,
/* Methods */
- book_module_is_busy,
- book_module_shutdown
+ book_shell_module_is_busy,
+ book_shell_module_shutdown,
+ e_book_shell_module_migrate
};
void
@@ -425,18 +429,18 @@
e_shell_module_set_info (shell_module, &module_info);
- book_module_init_importers ();
- book_module_ensure_sources (shell_module);
+ book_shell_module_init_importers ();
+ book_shell_module_ensure_sources (shell_module);
e_plugin_hook_register_type (eab_config_get_type ());
g_signal_connect_swapped (
shell, "handle-uri",
- G_CALLBACK (book_module_handle_uri), shell_module);
+ G_CALLBACK (book_shell_module_handle_uri), shell_module);
g_signal_connect_swapped (
shell, "window-created",
- G_CALLBACK (book_module_window_created), shell_module);
+ G_CALLBACK (book_shell_module_window_created), shell_module);
autocompletion_config_init ();
}
Modified: branches/kill-bonobo/addressbook/gui/component/e-book-shell-view-private.c
==============================================================================
--- branches/kill-bonobo/addressbook/gui/component/e-book-shell-view-private.c (original)
+++ branches/kill-bonobo/addressbook/gui/component/e-book-shell-view-private.c Sun Oct 5 04:12:09 2008
@@ -70,7 +70,7 @@
EShellView *shell_view;
gint n_selected;
- shell_view = E_SHELL_VIEW (shell_view);
+ shell_view = E_SHELL_VIEW (book_shell_view);
book_shell_content = book_shell_view->priv->book_shell_content;
current_view = e_book_shell_content_get_current_view (book_shell_content);
Modified: branches/kill-bonobo/calendar/gui/Makefile.am
==============================================================================
--- branches/kill-bonobo/calendar/gui/Makefile.am (original)
+++ branches/kill-bonobo/calendar/gui/Makefile.am Sun Oct 5 04:12:09 2008
@@ -50,8 +50,6 @@
# cal-search-bar.c
# cal-search-bar.h
# main.c
-# migration.c
-# migration.h
libcal_gui_la_SOURCES = \
e-calendar-view.c \
Modified: branches/kill-bonobo/calendar/gui/e-cal-event.c
==============================================================================
--- branches/kill-bonobo/calendar/gui/e-cal-event.c (original)
+++ branches/kill-bonobo/calendar/gui/e-cal-event.c Sun Oct 5 04:12:09 2008
@@ -43,10 +43,10 @@
ece_target_free (EEvent *ev, EEventTarget *t)
{
switch (t->type) {
- case E_CAL_EVENT_TARGET_COMPONENT: {
- ECalEventTargetComponent *s = (ECalEventTargetComponent *) t;
- if (s->component)
- g_object_unref (s->component);
+ case E_CAL_EVENT_TARGET_MODULE: {
+ ECalEventTargetModule *s = (ECalEventTargetModule *) t;
+ if (s->shell_module)
+ g_object_unref (s->shell_module);
break; }
}
@@ -92,12 +92,12 @@
return e_cal_event;
}
-ECalEventTargetComponent *
-e_cal_event_target_new_component (ECalEvent *ece, struct _CalendarComponent *component, guint32 flags)
+ECalEventTargetModule *
+e_cal_event_target_new_module (ECalEvent *ece, EShellModule *shell_module, guint32 flags)
{
- ECalEventTargetComponent *t = e_event_target_new (&ece->event, E_CAL_EVENT_TARGET_COMPONENT, sizeof (*t));
+ ECalEventTargetModule *t = e_event_target_new (&ece->event, E_CAL_EVENT_TARGET_MODULE, sizeof (*t));
- t->component = g_object_ref (component);
+ t->shell_module = g_object_ref (shell_module);
t->target.mask = ~flags;
return t;
@@ -107,13 +107,13 @@
static void *eceh_parent_class;
-static const EEventHookTargetMask eceh_component_masks[] = {
- { "migration", E_CAL_EVENT_COMPONENT_MIGRATION },
+static const EEventHookTargetMask eceh_module_masks[] = {
+ { "migration", E_CAL_EVENT_MODULE_MIGRATION },
{ NULL },
};
static const EEventHookTargetMap eceh_targets[] = {
- { "component", E_CAL_EVENT_TARGET_COMPONENT, eceh_component_masks },
+ { "module", E_CAL_EVENT_TARGET_MODULE, eceh_module_masks },
{ NULL },
};
Modified: branches/kill-bonobo/calendar/gui/e-cal-event.h
==============================================================================
--- branches/kill-bonobo/calendar/gui/e-cal-event.h (original)
+++ branches/kill-bonobo/calendar/gui/e-cal-event.h Sun Oct 5 04:12:09 2008
@@ -27,6 +27,7 @@
#include <glib-object.h>
#include "e-util/e-event.h"
+#include "shell/e-shell-module.h"
#ifdef __cplusplus
extern "C" {
@@ -37,20 +38,19 @@
typedef struct _ECalEventClass ECalEventClass;
enum _e_cal_event_target_t {
- E_CAL_EVENT_TARGET_COMPONENT,
+ E_CAL_EVENT_TARGET_MODULE,
};
-/* Flags that describe TARGET_COMPONENT */
+/* Flags that describe TARGET_MODULE */
enum {
- E_CAL_EVENT_COMPONENT_MIGRATION = 1 << 0,
+ E_CAL_EVENT_MODULE_MIGRATION = 1 << 0,
};
-typedef struct _ECalEventTargetComponent ECalEventTargetComponent;
+typedef struct _ECalEventTargetModule ECalEventTargetModule;
-struct _ECalEventTargetComponent {
+struct _ECalEventTargetModule {
EEventTarget target;
-
- struct _CalendarComponent *component;
+ EShellModule *shell_module;
};
struct _ECalEvent {
@@ -65,7 +65,7 @@
GType e_cal_event_get_type (void);
ECalEvent* e_cal_event_peek (void);
-ECalEventTargetComponent* e_cal_event_target_new_component (ECalEvent *ece, struct _CalendarComponent *component, guint32 flags);
+ECalEventTargetModule* e_cal_event_target_new_module (ECalEvent *ece, EShellModule *shell_module, guint32 flags);
/* ********************************************************************** */
Added: branches/kill-bonobo/calendar/modules/e-cal-shell-module-migrate.c
==============================================================================
--- (empty file)
+++ branches/kill-bonobo/calendar/modules/e-cal-shell-module-migrate.c Sun Oct 5 04:12:09 2008
@@ -0,0 +1,785 @@
+/*
+ * e-cal-shell-module-migrate.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-cal-shell-module-migrate.h"
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <libebackend/e-dbhash.h>
+#include <libedataserver/e-source.h>
+#include <libedataserver/e-source-group.h>
+#include <libedataserver/e-source-list.h>
+#include <libedataserver/e-xml-hash-utils.h>
+
+#include "e-util/e-bconf-map.h"
+#include "e-util/e-folder-map.h"
+#include "e-util/e-util-private.h"
+#include "calendar/gui/calendar-config.h"
+#include "calendar/gui/calendar-config-keys.h"
+#include "calendar/gui/e-cal-event.h"
+
+#define WEBCAL_BASE_URI "webcal://"
+#define CONTACTS_BASE_URI "contacts://"
+#define BAD_CONTACTS_BASE_URI "contact://"
+#define PERSONAL_RELATIVE_URI "system"
+
+static e_gconf_map_t calendar_display_map[] = {
+ /* /Calendar/Display */
+ { "Timezone", "calendar/display/timezone", E_GCONF_MAP_STRING },
+ { "Use24HourFormat", "calendar/display/use_24hour_format", E_GCONF_MAP_BOOL },
+ { "WeekStartDay", "calendar/display/week_start_day", E_GCONF_MAP_INT },
+ { "DayStartHour", "calendar/display/day_start_hour", E_GCONF_MAP_INT },
+ { "DayStartMinute", "calendar/display/day_start_minute", E_GCONF_MAP_INT },
+ { "DayEndHour", "calendar/display/day_end_hour", E_GCONF_MAP_INT },
+ { "DayEndMinute", "calendar/display/day_end_minute", E_GCONF_MAP_INT },
+ { "TimeDivisions", "calendar/display/time_divisions", E_GCONF_MAP_INT },
+ { "View", "calendar/display/default_view", E_GCONF_MAP_INT },
+ { "HPanePosition", "calendar/display/hpane_position", E_GCONF_MAP_FLOAT },
+ { "VPanePosition", "calendar/display/vpane_position", E_GCONF_MAP_FLOAT },
+ { "MonthHPanePosition", "calendar/display/month_hpane_position", E_GCONF_MAP_FLOAT },
+ { "MonthVPanePosition", "calendar/display/month_vpane_position", E_GCONF_MAP_FLOAT },
+ { "CompressWeekend", "calendar/display/compress_weekend", E_GCONF_MAP_BOOL },
+ { "ShowEventEndTime", "calendar/display/show_event_end", E_GCONF_MAP_BOOL },
+ { "WorkingDays", "calendar/display/working_days", E_GCONF_MAP_INT },
+ { NULL },
+};
+
+static e_gconf_map_t calendar_other_map[] = {
+ /* /Calendar/Other */
+ { "ConfirmDelete", "calendar/prompts/confirm_delete", E_GCONF_MAP_BOOL },
+ { "ConfirmExpunge", "calendar/prompts/confirm_purge", E_GCONF_MAP_BOOL },
+ { "UseDefaultReminder", "calendar/other/use_default_reminder", E_GCONF_MAP_BOOL },
+ { "DefaultReminderInterval", "calendar/other/default_reminder_interval", E_GCONF_MAP_INT },
+ { "DefaultReminderUnits", "calendar/other/default_reminder_units", E_GCONF_MAP_STRING },
+ { NULL },
+};
+
+static e_gconf_map_t calendar_datenavigator_map[] = {
+ /* /Calendar/DateNavigator */
+ { "ShowWeekNumbers", "calendar/date_navigator/show_week_numbers", E_GCONF_MAP_BOOL },
+ { NULL },
+};
+
+static e_gconf_map_t calendar_alarmnotify_map[] = {
+ /* /Calendar/AlarmNotify */
+ { "LastNotificationTime", "calendar/notify/last_notification_time", E_GCONF_MAP_INT },
+ { "CalendarToLoad%i", "calendar/notify/calendars", E_GCONF_MAP_STRING|E_GCONF_MAP_LIST },
+ { "BlessedProgram%i", "calendar/notify/programs", E_GCONF_MAP_STRING|E_GCONF_MAP_LIST },
+ { NULL },
+};
+
+static e_gconf_map_list_t calendar_remap_list[] = {
+
+ { "/Calendar/Display", calendar_display_map },
+ { "/Calendar/Other/Map", calendar_other_map },
+ { "/Calendar/DateNavigator", calendar_datenavigator_map },
+ { "/Calendar/AlarmNotify", calendar_alarmnotify_map },
+
+ { NULL },
+};
+
+static GtkWidget *window;
+static GtkLabel *label;
+static GtkProgressBar *progress;
+
+#ifndef G_OS_WIN32
+
+/* No previous versions have been available on Win32, so don't
+ * bother with upgrade support from 1.x on Win32.
+ */
+
+static void
+setup_progress_dialog (void)
+{
+ GtkWidget *vbox, *hbox, *w;
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title ((GtkWindow *) window, _("Migrating..."));
+ gtk_window_set_modal ((GtkWindow *) window, TRUE);
+ gtk_container_set_border_width ((GtkContainer *) window, 6);
+
+ vbox = gtk_vbox_new (FALSE, 6);
+ gtk_widget_show (vbox);
+ gtk_container_add ((GtkContainer *) window, vbox);
+
+ w = gtk_label_new (_("The location and hierarchy of the Evolution calendar "
+ "folders has changed since Evolution 1.x.\n\nPlease be "
+ "patient while Evolution migrates your folders..."));
+
+ gtk_label_set_line_wrap ((GtkLabel *) w, TRUE);
+ gtk_widget_show (w);
+ gtk_box_pack_start_defaults ((GtkBox *) vbox, w);
+
+ hbox = gtk_hbox_new (FALSE, 6);
+ gtk_widget_show (hbox);
+ gtk_box_pack_start_defaults ((GtkBox *) vbox, hbox);
+
+ label = (GtkLabel *) gtk_label_new ("");
+ gtk_widget_show ((GtkWidget *) label);
+ gtk_box_pack_start_defaults ((GtkBox *) hbox, (GtkWidget *) label);
+
+ progress = (GtkProgressBar *) gtk_progress_bar_new ();
+ gtk_widget_show ((GtkWidget *) progress);
+ gtk_box_pack_start_defaults ((GtkBox *) hbox, (GtkWidget *) progress);
+
+ gtk_widget_show (window);
+}
+
+static void
+dialog_close (void)
+{
+ gtk_widget_destroy ((GtkWidget *) window);
+}
+
+static void
+dialog_set_folder_name (const char *folder_name)
+{
+ char *text;
+
+ text = g_strdup_printf (_("Migrating '%s':"), folder_name);
+ gtk_label_set_text (label, text);
+ g_free (text);
+
+ gtk_progress_bar_set_fraction (progress, 0.0);
+
+ while (gtk_events_pending ())
+ gtk_main_iteration ();
+}
+
+static void
+dialog_set_progress (double percent)
+{
+ char text[5];
+
+ snprintf (text, sizeof (text), "%d%%", (int) (percent * 100.0f));
+
+ gtk_progress_bar_set_fraction (progress, percent);
+ gtk_progress_bar_set_text (progress, text);
+
+ while (gtk_events_pending ())
+ gtk_main_iteration ();
+}
+
+static gboolean
+check_for_conflict (ESourceGroup *group, char *name)
+{
+ GSList *sources;
+ GSList *s;
+
+ sources = e_source_group_peek_sources (group);
+
+ for (s = sources; s; s = s->next) {
+ ESource *source = E_SOURCE (s->data);
+
+ if (!strcmp (e_source_peek_name (source), name))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static char *
+get_source_name (ESourceGroup *group, const char *path)
+{
+ char **p = g_strsplit (path, "/", 0);
+ int i, j, starting_index;
+ int num_elements;
+ gboolean conflict;
+ GString *s = g_string_new (NULL);
+
+ for (i = 0; p[i]; i ++) ;
+
+ num_elements = i;
+ i--;
+
+ /* p[i] is now the last path element */
+
+ /* check if it conflicts */
+ starting_index = i;
+ do {
+ for (j = starting_index; j < num_elements; j += 2) {
+ if (j != starting_index)
+ g_string_append_c (s, '_');
+ g_string_append (s, p[j]);
+ }
+
+ conflict = check_for_conflict (group, s->str);
+
+
+ /* if there was a conflict back up 2 levels (skipping the /subfolder/ element) */
+ if (conflict)
+ starting_index -= 2;
+
+ /* we always break out if we can't go any further,
+ regardless of whether or not we conflict. */
+ if (starting_index < 0)
+ break;
+
+ } while (conflict);
+ g_strfreev (p);
+
+ return g_string_free (s, FALSE);
+}
+
+static gboolean
+migrate_ical (ECal *old_ecal, ECal *new_ecal)
+{
+ GList *l, *objects;
+ int num_added = 0;
+ int num_objects;
+ gboolean retval = TRUE;
+
+ /* both ecals are loaded, start the actual migration */
+ if (!e_cal_get_object_list (old_ecal, "#t", &objects, NULL))
+ return FALSE;
+
+ num_objects = g_list_length (objects);
+ for (l = objects; l; l = l->next) {
+ icalcomponent *ical_comp = l->data;
+ GError *error = NULL;
+
+ if (!e_cal_create_object (new_ecal, ical_comp, NULL, &error)) {
+ g_warning ("Migration of object failed: %s", error->message);
+ retval = FALSE;
+ }
+
+ g_clear_error (&error);
+
+ num_added ++;
+ dialog_set_progress ((double)num_added / num_objects);
+ }
+
+ g_list_foreach (objects, (GFunc) icalcomponent_free, NULL);
+ g_list_free (objects);
+
+ return retval;
+}
+
+static gboolean
+migrate_ical_folder_to_source (char *old_path, ESource *new_source, ECalSourceType type)
+{
+ ECal *old_ecal = NULL, *new_ecal = NULL;
+ ESource *old_source;
+ ESourceGroup *group;
+ char *old_uri = g_strdup_printf ("file://%s", old_path);
+ GError *error = NULL;
+ gboolean retval = FALSE;
+
+ group = e_source_group_new ("", old_uri);
+ old_source = e_source_new ("", "");
+ e_source_group_add_source (group, old_source, -1);
+
+ dialog_set_folder_name (e_source_peek_name (new_source));
+
+ if (!(old_ecal = e_cal_new (old_source, type))) {
+ g_warning ("could not find a backend for '%s'", e_source_get_uri (old_source));
+ goto finish;
+ }
+ if (!e_cal_open (old_ecal, FALSE, &error)) {
+ g_warning ("failed to load source ecal for migration: '%s' (%s)", error->message,
+ e_source_get_uri (old_source));
+ goto finish;
+ }
+
+ if (!(new_ecal = e_cal_new (new_source, type))) {
+ g_warning ("could not find a backend for '%s'", e_source_get_uri (new_source));
+ goto finish;
+ }
+ if (!e_cal_open (new_ecal, FALSE, &error)) {
+ g_warning ("failed to load destination ecal for migration: '%s' (%s)", error->message,
+ e_source_get_uri (new_source));
+ goto finish;
+ }
+
+ retval = migrate_ical (old_ecal, new_ecal);
+
+finish:
+ g_clear_error (&error);
+ if (old_ecal)
+ g_object_unref (old_ecal);
+ g_object_unref (group);
+ if (new_ecal)
+ g_object_unref (new_ecal);
+ g_free (old_uri);
+
+ return retval;
+}
+
+static gboolean
+migrate_ical_folder (char *old_path, ESourceGroup *dest_group, char *source_name, ECalSourceType type)
+{
+ ESource *new_source;
+ gboolean retval;
+
+ new_source = e_source_new (source_name, source_name);
+ e_source_set_relative_uri (new_source, e_source_peek_uid (new_source));
+ e_source_group_add_source (dest_group, new_source, -1);
+
+ retval = migrate_ical_folder_to_source (old_path, new_source, type);
+
+ g_object_unref (new_source);
+
+ return retval;
+}
+
+#endif /* !G_OS_WIN32 */
+
+#ifndef G_OS_WIN32
+
+static void
+migrate_pilot_db_key (const char *key, gpointer user_data)
+{
+ EXmlHash *xmlhash = user_data;
+
+ e_xmlhash_add (xmlhash, key, "");
+}
+
+static void
+migrate_pilot_data (const char *component, const char *conduit, const char *old_path, const char *new_path)
+{
+ char *changelog, *map;
+ const char *dent;
+ const char *ext;
+ char *filename;
+ GDir *dir;
+
+ if (!(dir = g_dir_open (old_path, 0, NULL)))
+ return;
+
+ map = g_alloca (12 + strlen (conduit));
+ sprintf (map, "pilot-map-%s-", conduit);
+
+ changelog = g_alloca (24 + strlen (conduit));
+ sprintf (changelog, "pilot-sync-evolution-%s-", conduit);
+
+ while ((dent = g_dir_read_name (dir))) {
+ if (!strncmp (dent, map, strlen (map)) &&
+ ((ext = strrchr (dent, '.')) && !strcmp (ext, ".xml"))) {
+ /* pilot map file - src and dest file formats are identical */
+ unsigned char inbuf[4096];
+ size_t nread, nwritten;
+ int fd0, fd1;
+ ssize_t n;
+
+ filename = g_build_filename (old_path, dent, NULL);
+ if ((fd0 = g_open (filename, O_RDONLY|O_BINARY, 0)) == -1) {
+ g_free (filename);
+ continue;
+ }
+
+ g_free (filename);
+ filename = g_build_filename (new_path, dent, NULL);
+ if ((fd1 = g_open (filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666)) == -1) {
+ g_free (filename);
+ close (fd0);
+ continue;
+ }
+
+ do {
+ do {
+ n = read (fd0, inbuf, sizeof (inbuf));
+ } while (n == -1 && errno == EINTR);
+
+ if (n < 1)
+ break;
+
+ nread = n;
+ nwritten = 0;
+ do {
+ do {
+ n = write (fd1, inbuf + nwritten, nread - nwritten);
+ } while (n == -1 && errno == EINTR);
+
+ if (n > 0)
+ nwritten += n;
+ } while (nwritten < nread && n != -1);
+
+ if (n == -1)
+ break;
+ } while (1);
+
+ if (n != -1)
+ n = fsync (fd1);
+
+ if (n == -1) {
+ g_warning ("Failed to migrate %s: %s", dent, strerror (errno));
+ g_unlink (filename);
+ }
+
+ close (fd0);
+ close (fd1);
+ g_free (filename);
+ } else if (!strncmp (dent, changelog, strlen (changelog)) &&
+ ((ext = strrchr (dent, '.')) && !strcmp (ext, ".db"))) {
+ /* src and dest formats differ, src format is db3 while dest format is xml */
+ EXmlHash *xmlhash;
+ EDbHash *dbhash;
+ struct stat st;
+
+ filename = g_build_filename (old_path, dent, NULL);
+ if (g_stat (filename, &st) == -1) {
+ g_free (filename);
+ continue;
+ }
+
+ dbhash = e_dbhash_new (filename);
+ g_free (filename);
+
+ filename = g_strdup_printf ("%s/%s.ics-%s", new_path, component, dent);
+ if (g_stat (filename, &st) != -1)
+ g_unlink (filename);
+ xmlhash = e_xmlhash_new (filename);
+ g_free (filename);
+
+ e_dbhash_foreach_key (dbhash, migrate_pilot_db_key, xmlhash);
+
+ e_dbhash_destroy (dbhash);
+
+ e_xmlhash_write (xmlhash);
+ e_xmlhash_destroy (xmlhash);
+ }
+ }
+
+ g_dir_close (dir);
+}
+
+#endif
+
+static ESourceGroup *
+create_calendar_contact_source (ESourceList *source_list)
+{
+ ESourceGroup *group;
+ ESource *source;
+
+ /* Create the contacts group */
+ group = e_source_group_new (_("Contacts"), CONTACTS_BASE_URI);
+ e_source_list_add_group (source_list, group, -1);
+
+ source = e_source_new (_("Birthdays & Anniversaries"), "/");
+ e_source_group_add_source (group, source, -1);
+ g_object_unref (source);
+
+ e_source_set_color_spec (source, "#FED4D3");
+ e_source_group_set_readonly (group, TRUE);
+
+ return group;
+}
+
+static void
+create_calendar_sources (EShellModule *shell_module,
+ ESourceList *source_list,
+ ESourceGroup **on_this_computer,
+ ESource **personal_source,
+ ESourceGroup **on_the_web,
+ ESourceGroup **contacts)
+{
+ GSList *groups;
+ ESourceGroup *group;
+ char *base_uri, *base_uri_proto;
+ const gchar *base_dir;
+
+ *on_this_computer = NULL;
+ *on_the_web = NULL;
+ *contacts = NULL;
+ *personal_source = NULL;
+
+ base_dir = e_shell_module_get_config_dir (shell_module);
+ base_uri = g_build_filename (base_dir, "local", NULL);
+
+ base_uri_proto = g_filename_to_uri (base_uri, NULL, NULL);
+
+ groups = e_source_list_peek_groups (source_list);
+ if (groups) {
+ /* groups are already there, we need to search for things... */
+ GSList *g;
+
+ for (g = groups; g; g = g->next) {
+
+ group = E_SOURCE_GROUP (g->data);
+
+ if (!strcmp (BAD_CONTACTS_BASE_URI, e_source_group_peek_base_uri (group)))
+ e_source_group_set_base_uri (group, CONTACTS_BASE_URI);
+
+ if (!strcmp (base_uri, e_source_group_peek_base_uri (group)))
+ e_source_group_set_base_uri (group, base_uri_proto);
+
+ if (!*on_this_computer && !strcmp (base_uri_proto, e_source_group_peek_base_uri (group)))
+ *on_this_computer = g_object_ref (group);
+ else if (!*on_the_web && !strcmp (WEBCAL_BASE_URI, e_source_group_peek_base_uri (group)))
+ *on_the_web = g_object_ref (group);
+ else if (!*contacts && !strcmp (CONTACTS_BASE_URI, e_source_group_peek_base_uri (group)))
+ *contacts = g_object_ref (group);
+ }
+ }
+
+ if (*on_this_computer) {
+ /* make sure "Personal" shows up as a source under
+ this group */
+ GSList *sources = e_source_group_peek_sources (*on_this_computer);
+ GSList *s;
+ for (s = sources; s; s = s->next) {
+ ESource *source = E_SOURCE (s->data);
+ const gchar *relative_uri;
+
+ relative_uri = e_source_peek_relative_uri (source);
+ if (relative_uri == NULL)
+ continue;
+ if (!strcmp (PERSONAL_RELATIVE_URI, relative_uri)) {
+ *personal_source = g_object_ref (source);
+ break;
+ }
+ }
+ } else {
+ /* create the local source group */
+ group = e_source_group_new (_("On This Computer"), base_uri_proto);
+ e_source_list_add_group (source_list, group, -1);
+
+ *on_this_computer = group;
+ }
+
+ if (!*personal_source) {
+ char *primary_calendar = calendar_config_get_primary_calendar ();
+
+ /* Create the default Person calendar */
+ ESource *source = e_source_new (_("Personal"), PERSONAL_RELATIVE_URI);
+ e_source_group_add_source (*on_this_computer, source, -1);
+
+ if (!primary_calendar && !calendar_config_get_calendars_selected ()) {
+ GSList selected;
+
+ calendar_config_set_primary_calendar (e_source_peek_uid (source));
+
+ selected.data = (gpointer)e_source_peek_uid (source);
+ selected.next = NULL;
+ calendar_config_set_calendars_selected (&selected);
+ }
+
+ g_free (primary_calendar);
+ e_source_set_color_spec (source, "#BECEDD");
+ *personal_source = source;
+ }
+
+ if (!*on_the_web) {
+ /* Create the Webcal source group */
+ group = e_source_group_new (_("On The Web"), WEBCAL_BASE_URI);
+ e_source_list_add_group (source_list, group, -1);
+
+ *on_the_web = group;
+ }
+
+ if (!*contacts) {
+ group = create_calendar_contact_source (source_list);
+
+ *contacts = group;
+ }
+
+ g_free (base_uri_proto);
+ g_free (base_uri);
+}
+
+gboolean
+e_cal_shell_module_migrate (EShellModule *shell_module,
+ gint major,
+ gint minor,
+ gint micro,
+ GError **error)
+{
+ ESourceGroup *on_this_computer = NULL, *on_the_web = NULL, *contacts = NULL;
+ ESource *personal_source = NULL;
+ ESourceList *source_list;
+ ECalEvent *ece;
+ ECalEventTargetModule *target;
+ gboolean retval = FALSE;
+
+ source_list = g_object_get_data (
+ G_OBJECT (shell_module), "source-list");
+
+ /* we call this unconditionally now - create_groups either
+ creates the groups/sources or it finds the necessary
+ groups/sources. */
+ create_calendar_sources (
+ shell_module, source_list, &on_this_computer,
+ &personal_source, &on_the_web, &contacts);
+
+#ifndef G_OS_WIN32
+ if (major == 1) {
+ xmlDocPtr config_doc = NULL;
+ char *conf_file;
+ struct stat st;
+
+ conf_file = g_build_filename (g_get_home_dir (), "evolution", "config.xmldb", NULL);
+ if (lstat (conf_file, &st) == 0 && S_ISREG (st.st_mode))
+ config_doc = xmlParseFile (conf_file);
+ g_free (conf_file);
+
+ if (config_doc && minor <= 2) {
+ GConfClient *gconf;
+ int res = 0;
+
+ /* move bonobo config to gconf */
+ gconf = gconf_client_get_default ();
+
+ res = e_bconf_import (gconf, config_doc, calendar_remap_list);
+
+ g_object_unref (gconf);
+
+ xmlFreeDoc(config_doc);
+
+ if (res != 0) {
+ /* FIXME: set proper domain/code */
+ g_set_error(error, 0, 0, _("Unable to migrate old settings from evolution/config.xmldb"));
+ goto fail;
+ }
+ }
+
+ if (minor <= 4) {
+ GSList *migration_dirs, *l;
+ char *path, *local_cal_folder;
+
+ setup_progress_dialog ();
+
+ path = g_build_filename (g_get_home_dir (), "evolution", "local", NULL);
+ migration_dirs = e_folder_map_local_folders (path, "calendar");
+ local_cal_folder = g_build_filename (path, "Calendar", NULL);
+ g_free (path);
+
+ if (personal_source)
+ migrate_ical_folder_to_source (local_cal_folder, personal_source, E_CAL_SOURCE_TYPE_EVENT);
+
+ for (l = migration_dirs; l; l = l->next) {
+ char *source_name;
+
+ if (personal_source && !strcmp ((char*)l->data, local_cal_folder))
+ continue;
+
+ source_name = get_source_name (on_this_computer, (char*)l->data);
+
+ if (!migrate_ical_folder (l->data, on_this_computer, source_name, E_CAL_SOURCE_TYPE_EVENT)) {
+ /* FIXME: domain/code */
+ g_set_error(error, 0, 0, _("Unable to migrate calendar `%s'"), source_name);
+ g_free(source_name);
+ goto fail;
+ }
+
+ g_free (source_name);
+ }
+
+ g_free (local_cal_folder);
+
+ dialog_close ();
+ }
+
+ if (minor <= 4 || (minor == 5 && micro < 5)) {
+ GConfClient *gconf;
+ GConfValue *gconf_val;
+ int i;
+ const char *keys[] = {
+ CALENDAR_CONFIG_HPANE_POS,
+ CALENDAR_CONFIG_VPANE_POS,
+ CALENDAR_CONFIG_MONTH_HPANE_POS,
+ CALENDAR_CONFIG_MONTH_VPANE_POS,
+ NULL
+ };
+
+ gconf = gconf_client_get_default ();
+
+ for (i = 0; keys[i]; i++) {
+ gconf_val = gconf_client_get (gconf, keys[i], NULL);
+ if (gconf_val) {
+ if (gconf_val->type != GCONF_VALUE_INT)
+ gconf_client_unset (gconf, keys[i], NULL);
+ gconf_value_free (gconf_val);
+ }
+ }
+
+ g_object_unref (gconf);
+ }
+
+ if (minor < 5 || (minor == 5 && micro <= 10)) {
+ char *old_path, *new_path;
+
+ old_path = g_build_filename (g_get_home_dir (), "evolution", "local", "Calendar", NULL);
+ new_path = g_build_filename (e_shell_module_get_config_dir (shell_module),
+ "local", "system", NULL);
+ migrate_pilot_data ("calendar", "calendar", old_path, new_path);
+ g_free (new_path);
+ g_free (old_path);
+ }
+
+ /* we only need to do this next step if people ran
+ older versions of 1.5. We need to clear out the
+ absolute URI's that were assigned to ESources
+ during one phase of development, as they take
+ precedent over relative uris (but aren't updated
+ when editing an ESource). */
+ if (minor == 5 && micro <= 11) {
+ GSList *g;
+ for (g = e_source_list_peek_groups (source_list); g; g = g->next) {
+ ESourceGroup *group = g->data;
+ GSList *s;
+
+ for (s = e_source_group_peek_sources (group); s; s = s->next) {
+ ESource *source = s->data;
+ e_source_set_absolute_uri (source, NULL);
+ }
+ }
+ }
+
+ }
+#endif /* !G_OS_WIN32 */
+
+ e_source_list_sync (source_list, NULL);
+
+ /** @Event: component.migration
+ * @Title: Migration step in component initialization
+ * @Target: ECalEventTargetComponent
+ *
+ * component.migration is emitted during the calendar component
+ * initialization process. This allows new calendar backend types
+ * to be distributed as an e-d-s backend and a plugin without
+ * reaching their grubby little fingers into migration.c
+ */
+ /* Fire off migration event */
+ ece = e_cal_event_peek ();
+ target = e_cal_event_target_new_module (ece, shell_module, 0);
+ e_event_emit ((EEvent *) ece, "module.migration", (EEventTarget *) target);
+
+ retval = TRUE;
+fail:
+ if (on_this_computer)
+ g_object_unref (on_this_computer);
+ if (on_the_web)
+ g_object_unref (on_the_web);
+ if (contacts)
+ g_object_unref (contacts);
+ if (personal_source)
+ g_object_unref (personal_source);
+
+ return retval;
+}
+
Added: branches/kill-bonobo/calendar/modules/e-cal-shell-module-migrate.h
==============================================================================
--- (empty file)
+++ branches/kill-bonobo/calendar/modules/e-cal-shell-module-migrate.h Sun Oct 5 04:12:09 2008
@@ -0,0 +1,38 @@
+/*
+ * e-cal-shell-module-migrate.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_CAL_SHELL_MODULE_MIGRATE_H
+#define E_CAL_SHELL_MODULE_MIGRATE_H
+
+#include <glib.h>
+#include <shell/e-shell-module.h>
+
+G_BEGIN_DECLS
+
+gboolean e_cal_shell_module_migrate (EShellModule *shell_module,
+ gint major,
+ gint minor,
+ gint micro,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* E_CAL_SHELL_MODULE_MIGRATE_H */
Modified: branches/kill-bonobo/calendar/modules/e-cal-shell-module.c
==============================================================================
--- branches/kill-bonobo/calendar/modules/e-cal-shell-module.c (original)
+++ branches/kill-bonobo/calendar/modules/e-cal-shell-module.c Sun Oct 5 04:12:09 2008
@@ -33,6 +33,7 @@
#include "calendar/gui/calendar-config.h"
#include "e-cal-shell-view.h"
+#include "e-cal-shell-module-migrate.h"
#define MODULE_NAME "calendar"
#define MODULE_ALIASES ""
@@ -370,7 +371,11 @@
MODULE_NAME,
MODULE_ALIASES,
MODULE_SCHEMES,
- MODULE_SORT_ORDER
+ MODULE_SORT_ORDER,
+
+ /* is_busy */ NULL,
+ /* shutdown */ NULL,
+ e_cal_shell_module_migrate
};
void
Added: branches/kill-bonobo/calendar/modules/e-memo-shell-module-migrate.c
==============================================================================
--- (empty file)
+++ branches/kill-bonobo/calendar/modules/e-memo-shell-module-migrate.c Sun Oct 5 04:12:09 2008
@@ -0,0 +1,257 @@
+/*
+ * e-memo-shell-module-migrate.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-memo-shell-module-migrate.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include <camel/camel-url.h>
+#include <libedataserver/e-account.h>
+#include <libedataserver/e-account-list.h>
+#include <libedataserver/e-source.h>
+#include <libedataserver/e-source-group.h>
+#include <libedataserver/e-source-list.h>
+
+#include "calendar/gui/calendar-config.h"
+#include "calendar/gui/calendar-config-keys.h"
+
+#define WEBCAL_BASE_URI "webcal://"
+#define PERSONAL_RELATIVE_URI "system"
+#define GROUPWISE_BASE_URI "groupwise://"
+
+static void
+create_memo_sources (EShellModule *shell_module,
+ ESourceList *source_list,
+ ESourceGroup **on_this_computer,
+ ESourceGroup **on_the_web,
+ ESource **personal_source)
+{
+ GSList *groups;
+ ESourceGroup *group;
+ char *base_uri, *base_uri_proto;
+ const gchar *base_dir;
+
+ *on_this_computer = NULL;
+ *on_the_web = NULL;
+ *personal_source = NULL;
+
+ base_dir = e_shell_module_get_config_dir (shell_module);
+ base_uri = g_build_filename (base_dir, "local", NULL);
+
+ base_uri_proto = g_filename_to_uri (base_uri, NULL, NULL);
+
+ groups = e_source_list_peek_groups (source_list);
+ if (groups) {
+ /* groups are already there, we need to search for things... */
+ GSList *g;
+
+ for (g = groups; g; g = g->next) {
+
+ group = E_SOURCE_GROUP (g->data);
+
+ if (!*on_this_computer && !strcmp (base_uri_proto, e_source_group_peek_base_uri (group)))
+ *on_this_computer = g_object_ref (group);
+ else if (!*on_the_web && !strcmp (WEBCAL_BASE_URI, e_source_group_peek_base_uri (group)))
+ *on_the_web = g_object_ref (group);
+ }
+ }
+
+ if (*on_this_computer) {
+ /* make sure "Personal" shows up as a source under
+ this group */
+ GSList *sources = e_source_group_peek_sources (*on_this_computer);
+ GSList *s;
+ for (s = sources; s; s = s->next) {
+ ESource *source = E_SOURCE (s->data);
+ const gchar *relative_uri;
+
+ relative_uri = e_source_peek_relative_uri (source);
+ if (relative_uri == NULL)
+ continue;
+ if (!strcmp (PERSONAL_RELATIVE_URI, relative_uri)) {
+ *personal_source = g_object_ref (source);
+ break;
+ }
+ }
+ } else {
+ /* create the local source group */
+ group = e_source_group_new (_("On This Computer"), base_uri_proto);
+ e_source_list_add_group (source_list, group, -1);
+
+ *on_this_computer = group;
+ }
+
+ if (!*personal_source) {
+ /* Create the default Person task list */
+ ESource *source = e_source_new (_("Personal"), PERSONAL_RELATIVE_URI);
+ e_source_group_add_source (*on_this_computer, source, -1);
+
+ if (!calendar_config_get_primary_memos () && !calendar_config_get_memos_selected ()) {
+ GSList selected;
+
+ calendar_config_set_primary_memos (e_source_peek_uid (source));
+
+ selected.data = (gpointer)e_source_peek_uid (source);
+ selected.next = NULL;
+ calendar_config_set_memos_selected (&selected);
+ }
+
+ e_source_set_color_spec (source, "#BECEDD");
+ *personal_source = source;
+ }
+
+ if (!*on_the_web) {
+ /* Create the Webcal source group */
+ group = e_source_group_new (_("On The Web"), WEBCAL_BASE_URI);
+ e_source_list_add_group (source_list, group, -1);
+
+ *on_the_web = group;
+ }
+
+ g_free (base_uri_proto);
+ g_free (base_uri);
+}
+
+static gboolean
+is_groupwise_account (EAccount *account)
+{
+ if (account->source->url != NULL) {
+ return g_str_has_prefix (account->source->url, GROUPWISE_BASE_URI);
+ } else {
+ return FALSE;
+ }
+}
+
+static void
+add_gw_esource (ESourceList *source_list, const char *group_name, const char *source_name, CamelURL *url, GConfClient *client)
+{
+ ESourceGroup *group;
+ ESource *source;
+ GSList *ids, *temp ;
+ GError *error = NULL;
+ char *relative_uri;
+ const char *soap_port;
+ const char * use_ssl;
+ const char *poa_address;
+ const char *offline_sync;
+
+
+ poa_address = url->host;
+ if (!poa_address || strlen (poa_address) ==0)
+ return;
+ soap_port = camel_url_get_param (url, "soap_port");
+
+ if (!soap_port || strlen (soap_port) == 0)
+ soap_port = "7191";
+
+ use_ssl = camel_url_get_param (url, "use_ssl");
+ offline_sync = camel_url_get_param (url, "offline_sync");
+
+ group = e_source_group_new (group_name, GROUPWISE_BASE_URI);
+ if (!e_source_list_add_group (source_list, group, -1))
+ return;
+ relative_uri = g_strdup_printf ("%s %s/", url->user, poa_address);
+
+ source = e_source_new (source_name, relative_uri);
+ e_source_set_property (source, "auth", "1");
+ e_source_set_property (source, "username", url->user);
+ e_source_set_property (source, "port", camel_url_get_param (url, "soap_port"));
+ e_source_set_property (source, "auth-domain", "Groupwise");
+ e_source_set_property (source, "use_ssl", use_ssl);
+ e_source_set_property (source, "offline_sync", offline_sync ? "1" : "0" );
+
+ e_source_set_color_spec (source, "#EEBC60");
+ e_source_group_add_source (group, source, -1);
+
+ ids = gconf_client_get_list (client, CALENDAR_CONFIG_MEMOS_SELECTED_MEMOS, GCONF_VALUE_STRING, &error);
+ if ( error != NULL ) {
+ g_warning("%s (%s) %s\n", G_STRLOC, G_STRFUNC, error->message);
+ g_error_free(error);
+ }
+ ids = g_slist_append (ids, g_strdup (e_source_peek_uid (source)));
+ gconf_client_set_list (client, CALENDAR_CONFIG_MEMOS_SELECTED_MEMOS, GCONF_VALUE_STRING, ids, NULL);
+ temp = ids;
+ for (; temp != NULL; temp = g_slist_next (temp))
+ g_free (temp->data);
+
+ g_slist_free (ids);
+ g_object_unref (source);
+ g_object_unref (group);
+ g_free (relative_uri);
+}
+
+gboolean
+e_memo_shell_module_migrate (EShellModule *shell_module,
+ gint major,
+ gint minor,
+ gint revision,
+ GError **error)
+{
+ ESourceGroup *on_this_computer = NULL;
+ ESourceGroup *on_the_web = NULL;
+ ESource *personal_source = NULL;
+ ESourceList *source_list = NULL;
+ gboolean retval = FALSE;
+
+ source_list = g_object_get_data (
+ G_OBJECT (shell_module), "source-list");
+
+ /* we call this unconditionally now - create_groups either
+ creates the groups/sources or it finds the necessary
+ groups/sources. */
+ create_memo_sources (
+ shell_module, source_list, &on_this_computer,
+ &on_the_web, &personal_source);
+
+ /* Migration for Gw accounts between versions < 2.8 */
+ if (major == 2 && minor < 8) {
+ EAccountList *al;
+ EAccount *a;
+ CamelURL *url;
+ EIterator *it;
+ GConfClient *gconf_client = gconf_client_get_default ();
+ al = e_account_list_new (gconf_client);
+ for (it = e_list_get_iterator((EList *)al);
+ e_iterator_is_valid(it);
+ e_iterator_next(it)) {
+ a = (EAccount *) e_iterator_get(it);
+ if (!a->enabled || !is_groupwise_account (a))
+ continue;
+ url = camel_url_new (a->source->url, NULL);
+ add_gw_esource (source_list, a->name, _("Notes"), url, gconf_client);
+ camel_url_free (url);
+ }
+ g_object_unref (al);
+ g_object_unref (gconf_client);
+ }
+
+ e_source_list_sync (source_list, NULL);
+ retval = TRUE;
+
+ if (on_this_computer)
+ g_object_unref (on_this_computer);
+ if (on_the_web)
+ g_object_unref (on_the_web);
+ if (personal_source)
+ g_object_unref (personal_source);
+
+ return retval;
+}
Added: branches/kill-bonobo/calendar/modules/e-memo-shell-module-migrate.h
==============================================================================
--- (empty file)
+++ branches/kill-bonobo/calendar/modules/e-memo-shell-module-migrate.h Sun Oct 5 04:12:09 2008
@@ -0,0 +1,38 @@
+/*
+ * e-memo-shell-module-migrate.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MEMO_SHELL_MODULE_MIGRATE_H
+#define E_MEMO_SHELL_MODULE_MIGRATE_H
+
+#include <glib.h>
+#include <shell/e-shell-module.h>
+
+G_BEGIN_DECLS
+
+gboolean e_memo_shell_module_migrate (EShellModule *shell_module,
+ gint major,
+ gint minor,
+ gint micro,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* E_MEMO_SHELL_MODULE_MIGRATE_H */
Modified: branches/kill-bonobo/calendar/modules/e-memo-shell-module.c
==============================================================================
--- branches/kill-bonobo/calendar/modules/e-memo-shell-module.c (original)
+++ branches/kill-bonobo/calendar/modules/e-memo-shell-module.c Sun Oct 5 04:12:09 2008
@@ -38,6 +38,7 @@
#include "calendar/gui/dialogs/memo-editor.h"
#include "e-memo-shell-view.h"
+#include "e-memo-shell-module-migrate.h"
#define MODULE_NAME "memos"
#define MODULE_ALIASES ""
@@ -463,7 +464,11 @@
MODULE_NAME,
MODULE_ALIASES,
MODULE_SCHEMES,
- MODULE_SORT_ORDER
+ MODULE_SORT_ORDER,
+
+ /* is_busy */ NULL,
+ /* shutdown */ NULL,
+ e_memo_shell_module_migrate
};
void
Added: branches/kill-bonobo/calendar/modules/e-task-shell-module-migrate.c
==============================================================================
--- (empty file)
+++ branches/kill-bonobo/calendar/modules/e-task-shell-module-migrate.c Sun Oct 5 04:12:09 2008
@@ -0,0 +1,664 @@
+/*
+ * e-task-shell-module-migrate.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-task-shell-module-migrate.h"
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <libebackend/e-dbhash.h>
+#include <libedataserver/e-source.h>
+#include <libedataserver/e-source-group.h>
+#include <libedataserver/e-source-list.h>
+#include <libedataserver/e-xml-hash-utils.h>
+#include <libedataserver/e-xml-utils.h>
+
+#include "e-util/e-bconf-map.h"
+#include "e-util/e-folder-map.h"
+#include "e-util/e-util-private.h"
+#include "calendar/gui/calendar-config.h"
+#include "calendar/gui/calendar-config-keys.h"
+
+#define WEBCAL_BASE_URI "webcal://"
+#define PERSONAL_RELATIVE_URI "system"
+
+static e_gconf_map_t calendar_tasks_map[] = {
+ /* /Calendar/Tasks */
+ { "HideCompletedTasks", "calendar/tasks/hide_completed", E_GCONF_MAP_BOOL },
+ { "HideCompletedTasksUnits", "calendar/tasks/hide_completed_units", E_GCONF_MAP_STRING },
+ { "HideCompletedTasksValue", "calendar/tasks/hide_completed_value", E_GCONF_MAP_INT },
+ { NULL },
+};
+
+static e_gconf_map_t calendar_tasks_colours_map[] = {
+ /* /Calendar/Tasks/Colors */
+ { "TasksDueToday", "calendar/tasks/colors/due_today", E_GCONF_MAP_STRING },
+ { "TasksOverDue", "calendar/tasks/colors/overdue", E_GCONF_MAP_STRING },
+ { "TasksDueToday", "calendar/tasks/colors/due_today", E_GCONF_MAP_STRING },
+ { NULL },
+};
+
+static e_gconf_map_list_t task_remap_list[] = {
+
+ { "/Calendar/Tasks", calendar_tasks_map },
+ { "/Calendar/Tasks/Colors", calendar_tasks_colours_map },
+
+ { NULL },
+};
+
+static GtkWidget *window;
+static GtkLabel *label;
+static GtkProgressBar *progress;
+
+#ifndef G_OS_WIN32
+
+/* No previous versions have been available on Win32, so don't
+ * bother with upgrade support from 1.x on Win32.
+ */
+
+static void
+setup_progress_dialog (void)
+{
+ GtkWidget *vbox, *hbox, *w;
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title ((GtkWindow *) window, _("Migrating..."));
+ gtk_window_set_modal ((GtkWindow *) window, TRUE);
+ gtk_container_set_border_width ((GtkContainer *) window, 6);
+
+ vbox = gtk_vbox_new (FALSE, 6);
+ gtk_widget_show (vbox);
+ gtk_container_add ((GtkContainer *) window, vbox);
+
+ w = gtk_label_new (_("The location and hierarchy of the Evolution task "
+ "folders has changed since Evolution 1.x.\n\nPlease be "
+ "patient while Evolution migrates your folders..."));
+
+ gtk_label_set_line_wrap ((GtkLabel *) w, TRUE);
+ gtk_widget_show (w);
+ gtk_box_pack_start_defaults ((GtkBox *) vbox, w);
+
+ hbox = gtk_hbox_new (FALSE, 6);
+ gtk_widget_show (hbox);
+ gtk_box_pack_start_defaults ((GtkBox *) vbox, hbox);
+
+ label = (GtkLabel *) gtk_label_new ("");
+ gtk_widget_show ((GtkWidget *) label);
+ gtk_box_pack_start_defaults ((GtkBox *) hbox, (GtkWidget *) label);
+
+ progress = (GtkProgressBar *) gtk_progress_bar_new ();
+ gtk_widget_show ((GtkWidget *) progress);
+ gtk_box_pack_start_defaults ((GtkBox *) hbox, (GtkWidget *) progress);
+
+ gtk_widget_show (window);
+}
+
+static void
+dialog_close (void)
+{
+ gtk_widget_destroy ((GtkWidget *) window);
+}
+
+static void
+dialog_set_folder_name (const char *folder_name)
+{
+ char *text;
+
+ text = g_strdup_printf (_("Migrating '%s':"), folder_name);
+ gtk_label_set_text (label, text);
+ g_free (text);
+
+ gtk_progress_bar_set_fraction (progress, 0.0);
+
+ while (gtk_events_pending ())
+ gtk_main_iteration ();
+}
+
+static void
+dialog_set_progress (double percent)
+{
+ char text[5];
+
+ snprintf (text, sizeof (text), "%d%%", (int) (percent * 100.0f));
+
+ gtk_progress_bar_set_fraction (progress, percent);
+ gtk_progress_bar_set_text (progress, text);
+
+ while (gtk_events_pending ())
+ gtk_main_iteration ();
+}
+
+static gboolean
+check_for_conflict (ESourceGroup *group, char *name)
+{
+ GSList *sources;
+ GSList *s;
+
+ sources = e_source_group_peek_sources (group);
+
+ for (s = sources; s; s = s->next) {
+ ESource *source = E_SOURCE (s->data);
+
+ if (!strcmp (e_source_peek_name (source), name))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static char *
+get_source_name (ESourceGroup *group, const char *path)
+{
+ char **p = g_strsplit (path, "/", 0);
+ int i, j, starting_index;
+ int num_elements;
+ gboolean conflict;
+ GString *s = g_string_new (NULL);
+
+ for (i = 0; p[i]; i ++) ;
+
+ num_elements = i;
+ i--;
+
+ /* p[i] is now the last path element */
+
+ /* check if it conflicts */
+ starting_index = i;
+ do {
+ for (j = starting_index; j < num_elements; j += 2) {
+ if (j != starting_index)
+ g_string_append_c (s, '_');
+ g_string_append (s, p[j]);
+ }
+
+ conflict = check_for_conflict (group, s->str);
+
+
+ /* if there was a conflict back up 2 levels (skipping the /subfolder/ element) */
+ if (conflict)
+ starting_index -= 2;
+
+ /* we always break out if we can't go any further,
+ regardless of whether or not we conflict. */
+ if (starting_index < 0)
+ break;
+
+ } while (conflict);
+ g_strfreev (p);
+
+ return g_string_free (s, FALSE);
+}
+
+static gboolean
+migrate_ical (ECal *old_ecal, ECal *new_ecal)
+{
+ GList *l, *objects;
+ int num_added = 0;
+ int num_objects;
+ gboolean retval = TRUE;
+
+ /* both ecals are loaded, start the actual migration */
+ if (!e_cal_get_object_list (old_ecal, "#t", &objects, NULL))
+ return FALSE;
+
+ num_objects = g_list_length (objects);
+ for (l = objects; l; l = l->next) {
+ icalcomponent *ical_comp = l->data;
+ GError *error = NULL;
+
+ if (!e_cal_create_object (new_ecal, ical_comp, NULL, &error)) {
+ g_warning ("Migration of object failed: %s", error->message);
+ retval = FALSE;
+ }
+
+ g_clear_error (&error);
+
+ num_added ++;
+ dialog_set_progress ((double)num_added / num_objects);
+ }
+
+ g_list_foreach (objects, (GFunc) icalcomponent_free, NULL);
+ g_list_free (objects);
+
+ return retval;
+}
+
+static gboolean
+migrate_ical_folder_to_source (char *old_path, ESource *new_source, ECalSourceType type)
+{
+ ECal *old_ecal = NULL, *new_ecal = NULL;
+ ESource *old_source;
+ ESourceGroup *group;
+ char *old_uri = g_strdup_printf ("file://%s", old_path);
+ GError *error = NULL;
+ gboolean retval = FALSE;
+
+ group = e_source_group_new ("", old_uri);
+ old_source = e_source_new ("", "");
+ e_source_group_add_source (group, old_source, -1);
+
+ dialog_set_folder_name (e_source_peek_name (new_source));
+
+ if (!(old_ecal = e_cal_new (old_source, type))) {
+ g_warning ("could not find a backend for '%s'", e_source_get_uri (old_source));
+ goto finish;
+ }
+ if (!e_cal_open (old_ecal, FALSE, &error)) {
+ g_warning ("failed to load source ecal for migration: '%s' (%s)", error->message,
+ e_source_get_uri (old_source));
+ goto finish;
+ }
+
+ if (!(new_ecal = e_cal_new (new_source, type))) {
+ g_warning ("could not find a backend for '%s'", e_source_get_uri (new_source));
+ goto finish;
+ }
+ if (!e_cal_open (new_ecal, FALSE, &error)) {
+ g_warning ("failed to load destination ecal for migration: '%s' (%s)", error->message,
+ e_source_get_uri (new_source));
+ goto finish;
+ }
+
+ retval = migrate_ical (old_ecal, new_ecal);
+
+finish:
+ g_clear_error (&error);
+ if (old_ecal)
+ g_object_unref (old_ecal);
+ g_object_unref (group);
+ if (new_ecal)
+ g_object_unref (new_ecal);
+ g_free (old_uri);
+
+ return retval;
+}
+
+static gboolean
+migrate_ical_folder (char *old_path, ESourceGroup *dest_group, char *source_name, ECalSourceType type)
+{
+ ESource *new_source;
+ gboolean retval;
+
+ new_source = e_source_new (source_name, source_name);
+ e_source_set_relative_uri (new_source, e_source_peek_uid (new_source));
+ e_source_group_add_source (dest_group, new_source, -1);
+
+ retval = migrate_ical_folder_to_source (old_path, new_source, type);
+
+ g_object_unref (new_source);
+
+ return retval;
+}
+
+#endif /* !G_OS_WIN32 */
+
+#ifndef G_OS_WIN32
+
+static void
+migrate_pilot_db_key (const char *key, gpointer user_data)
+{
+ EXmlHash *xmlhash = user_data;
+
+ e_xmlhash_add (xmlhash, key, "");
+}
+
+static void
+migrate_pilot_data (const char *component, const char *conduit, const char *old_path, const char *new_path)
+{
+ char *changelog, *map;
+ const char *dent;
+ const char *ext;
+ char *filename;
+ GDir *dir;
+
+ if (!(dir = g_dir_open (old_path, 0, NULL)))
+ return;
+
+ map = g_alloca (12 + strlen (conduit));
+ sprintf (map, "pilot-map-%s-", conduit);
+
+ changelog = g_alloca (24 + strlen (conduit));
+ sprintf (changelog, "pilot-sync-evolution-%s-", conduit);
+
+ while ((dent = g_dir_read_name (dir))) {
+ if (!strncmp (dent, map, strlen (map)) &&
+ ((ext = strrchr (dent, '.')) && !strcmp (ext, ".xml"))) {
+ /* pilot map file - src and dest file formats are identical */
+ unsigned char inbuf[4096];
+ size_t nread, nwritten;
+ int fd0, fd1;
+ ssize_t n;
+
+ filename = g_build_filename (old_path, dent, NULL);
+ if ((fd0 = g_open (filename, O_RDONLY|O_BINARY, 0)) == -1) {
+ g_free (filename);
+ continue;
+ }
+
+ g_free (filename);
+ filename = g_build_filename (new_path, dent, NULL);
+ if ((fd1 = g_open (filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666)) == -1) {
+ g_free (filename);
+ close (fd0);
+ continue;
+ }
+
+ do {
+ do {
+ n = read (fd0, inbuf, sizeof (inbuf));
+ } while (n == -1 && errno == EINTR);
+
+ if (n < 1)
+ break;
+
+ nread = n;
+ nwritten = 0;
+ do {
+ do {
+ n = write (fd1, inbuf + nwritten, nread - nwritten);
+ } while (n == -1 && errno == EINTR);
+
+ if (n > 0)
+ nwritten += n;
+ } while (nwritten < nread && n != -1);
+
+ if (n == -1)
+ break;
+ } while (1);
+
+ if (n != -1)
+ n = fsync (fd1);
+
+ if (n == -1) {
+ g_warning ("Failed to migrate %s: %s", dent, strerror (errno));
+ g_unlink (filename);
+ }
+
+ close (fd0);
+ close (fd1);
+ g_free (filename);
+ } else if (!strncmp (dent, changelog, strlen (changelog)) &&
+ ((ext = strrchr (dent, '.')) && !strcmp (ext, ".db"))) {
+ /* src and dest formats differ, src format is db3 while dest format is xml */
+ EXmlHash *xmlhash;
+ EDbHash *dbhash;
+ struct stat st;
+
+ filename = g_build_filename (old_path, dent, NULL);
+ if (g_stat (filename, &st) == -1) {
+ g_free (filename);
+ continue;
+ }
+
+ dbhash = e_dbhash_new (filename);
+ g_free (filename);
+
+ filename = g_strdup_printf ("%s/%s.ics-%s", new_path, component, dent);
+ if (g_stat (filename, &st) != -1)
+ g_unlink (filename);
+ xmlhash = e_xmlhash_new (filename);
+ g_free (filename);
+
+ e_dbhash_foreach_key (dbhash, migrate_pilot_db_key, xmlhash);
+
+ e_dbhash_destroy (dbhash);
+
+ e_xmlhash_write (xmlhash);
+ e_xmlhash_destroy (xmlhash);
+ }
+ }
+
+ g_dir_close (dir);
+}
+
+#endif
+
+static void
+create_task_sources (EShellModule *shell_module,
+ ESourceList *source_list,
+ ESourceGroup **on_this_computer,
+ ESourceGroup **on_the_web,
+ ESource **personal_source)
+{
+ GSList *groups;
+ ESourceGroup *group;
+ char *base_uri, *base_uri_proto;
+ const gchar *base_dir;
+
+ *on_this_computer = NULL;
+ *on_the_web = NULL;
+ *personal_source = NULL;
+
+ base_dir = e_shell_module_get_config_dir (shell_module);
+ base_uri = g_build_filename (base_dir, "local", NULL);
+
+ base_uri_proto = g_filename_to_uri (base_uri, NULL, NULL);
+
+ groups = e_source_list_peek_groups (source_list);
+ if (groups) {
+ /* groups are already there, we need to search for things... */
+ GSList *g;
+
+ for (g = groups; g; g = g->next) {
+
+ group = E_SOURCE_GROUP (g->data);
+
+ if (!*on_this_computer && !strcmp (base_uri_proto, e_source_group_peek_base_uri (group)))
+ *on_this_computer = g_object_ref (group);
+ else if (!*on_the_web && !strcmp (WEBCAL_BASE_URI, e_source_group_peek_base_uri (group)))
+ *on_the_web = g_object_ref (group);
+ }
+ }
+
+ if (*on_this_computer) {
+ /* make sure "Personal" shows up as a source under
+ this group */
+ GSList *sources = e_source_group_peek_sources (*on_this_computer);
+ GSList *s;
+ for (s = sources; s; s = s->next) {
+ ESource *source = E_SOURCE (s->data);
+ const gchar *relative_uri;
+
+ relative_uri = e_source_peek_relative_uri (source);
+ if (relative_uri == NULL)
+ continue;
+ if (!strcmp (PERSONAL_RELATIVE_URI, relative_uri)) {
+ *personal_source = g_object_ref (source);
+ break;
+ }
+ }
+ } else {
+ /* create the local source group */
+ group = e_source_group_new (_("On This Computer"), base_uri_proto);
+ e_source_list_add_group (source_list, group, -1);
+
+ *on_this_computer = group;
+ }
+
+ if (!*personal_source) {
+ /* Create the default Person task list */
+ ESource *source = e_source_new (_("Personal"), PERSONAL_RELATIVE_URI);
+ e_source_group_add_source (*on_this_computer, source, -1);
+
+ if (!calendar_config_get_primary_tasks () && !calendar_config_get_tasks_selected ()) {
+ GSList selected;
+
+ calendar_config_set_primary_tasks (e_source_peek_uid (source));
+
+ selected.data = (gpointer)e_source_peek_uid (source);
+ selected.next = NULL;
+ calendar_config_set_tasks_selected (&selected);
+ }
+
+ e_source_set_color_spec (source, "#BECEDD");
+ *personal_source = source;
+ }
+
+ if (!*on_the_web) {
+ /* Create the Webcal source group */
+ group = e_source_group_new (_("On The Web"), WEBCAL_BASE_URI);
+ e_source_list_add_group (source_list, group, -1);
+
+ *on_the_web = group;
+ }
+
+ g_free (base_uri_proto);
+ g_free (base_uri);
+}
+
+gboolean
+e_task_shell_module_migrate (EShellModule *shell_module,
+ gint major,
+ gint minor,
+ gint micro,
+ GError **error)
+{
+ ESourceGroup *on_this_computer = NULL;
+ ESourceGroup *on_the_web = NULL;
+ ESource *personal_source = NULL;
+ ESourceList *source_list;
+ gboolean retval = FALSE;
+
+ source_list = g_object_get_data (
+ G_OBJECT (source_list), "source-list");
+
+ /* we call this unconditionally now - create_groups either
+ creates the groups/sources or it finds the necessary
+ groups/sources. */
+ create_task_sources (
+ shell_module, source_list, &on_this_computer,
+ &on_the_web, &personal_source);
+
+#ifndef G_OS_WIN32
+ if (major == 1) {
+ xmlDocPtr config_doc = NULL;
+ char *conf_file;
+
+ conf_file = g_build_filename (g_get_home_dir (), "evolution", "config.xmldb", NULL);
+ if (g_file_test (conf_file, G_FILE_TEST_IS_REGULAR))
+ config_doc = e_xml_parse_file (conf_file);
+ g_free (conf_file);
+
+ if (config_doc && minor <= 2) {
+ GConfClient *gconf;
+ int res = 0;
+
+ /* move bonobo config to gconf */
+ gconf = gconf_client_get_default ();
+
+ res = e_bconf_import (gconf, config_doc, task_remap_list);
+
+ g_object_unref (gconf);
+
+ xmlFreeDoc(config_doc);
+
+ if (res != 0) {
+ g_set_error(error, 0, 0, _("Unable to migrate old settings from evolution/config.xmldb"));
+ goto fail;
+ }
+ }
+
+ if (minor <= 4) {
+ GSList *migration_dirs, *l;
+ char *path, *local_task_folder;
+
+ setup_progress_dialog ();
+
+ path = g_build_filename (g_get_home_dir (), "evolution", "local", NULL);
+ migration_dirs = e_folder_map_local_folders (path, "tasks");
+ local_task_folder = g_build_filename (path, "Tasks", NULL);
+ g_free (path);
+
+ if (personal_source)
+ migrate_ical_folder_to_source (local_task_folder, personal_source, E_CAL_SOURCE_TYPE_TODO);
+
+ for (l = migration_dirs; l; l = l->next) {
+ char *source_name;
+
+ if (personal_source && !strcmp ((char*)l->data, local_task_folder))
+ continue;
+
+ source_name = get_source_name (on_this_computer, (char*)l->data);
+
+ if (!migrate_ical_folder (l->data, on_this_computer, source_name, E_CAL_SOURCE_TYPE_TODO)) {
+ /* FIXME: domain/code */
+ g_set_error(error, 0, 0, _("Unable to migrate tasks `%s'"), source_name);
+ g_free(source_name);
+ goto fail;
+ }
+
+ g_free (source_name);
+ }
+
+ g_free (local_task_folder);
+
+ dialog_close ();
+ }
+
+ if (minor < 5 || (minor == 5 && micro <= 10)) {
+ char *old_path, *new_path;
+
+ old_path = g_build_filename (g_get_home_dir (), "evolution", "local", "Tasks", NULL);
+ new_path = g_build_filename (e_shell_module_get_config_dir (shell_module),
+ "local", "system", NULL);
+ migrate_pilot_data ("tasks", "todo", old_path, new_path);
+ g_free (new_path);
+ g_free (old_path);
+ }
+
+ /* we only need to do this next step if people ran
+ older versions of 1.5. We need to clear out the
+ absolute URI's that were assigned to ESources
+ during one phase of development, as they take
+ precedent over relative uris (but aren't updated
+ when editing an ESource). */
+ if (minor == 5 && micro <= 11) {
+ GSList *g;
+ for (g = e_source_list_peek_groups (source_list); g; g = g->next) {
+ ESourceGroup *group = g->data;
+ GSList *s;
+
+ for (s = e_source_group_peek_sources (group); s; s = s->next) {
+ ESource *source = s->data;
+ e_source_set_absolute_uri (source, NULL);
+ }
+ }
+ }
+ }
+#endif /* !G_OS_WIN32 */
+ e_source_list_sync (source_list, NULL);
+ retval = TRUE;
+fail:
+ if (on_this_computer)
+ g_object_unref (on_this_computer);
+ if (on_the_web)
+ g_object_unref (on_the_web);
+ if (personal_source)
+ g_object_unref (personal_source);
+
+ return retval;
+}
Added: branches/kill-bonobo/calendar/modules/e-task-shell-module-migrate.h
==============================================================================
--- (empty file)
+++ branches/kill-bonobo/calendar/modules/e-task-shell-module-migrate.h Sun Oct 5 04:12:09 2008
@@ -0,0 +1,38 @@
+/*
+ * e-task-shell-module-migrate.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_TASK_SHELL_MODULE_MIGRATE_H
+#define E_TASK_SHELL_MODULE_MIGRATE_H
+
+#include <glib.h>
+#include <shell/e-shell-module.h>
+
+G_BEGIN_DECLS
+
+gboolean e_task_shell_module_migrate (EShellModule *shell_module,
+ gint major,
+ gint minor,
+ gint micro,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* E_TASK_SHELL_MODULE_MIGRATE_H */
Modified: branches/kill-bonobo/calendar/modules/e-task-shell-module.c
==============================================================================
--- branches/kill-bonobo/calendar/modules/e-task-shell-module.c (original)
+++ branches/kill-bonobo/calendar/modules/e-task-shell-module.c Sun Oct 5 04:12:09 2008
@@ -38,6 +38,7 @@
#include "calendar/gui/dialogs/task-editor.h"
#include "e-task-shell-view.h"
+#include "e-task-shell-module-migrate.h"
#define MODULE_NAME "tasks"
#define MODULE_ALIASES ""
@@ -469,7 +470,11 @@
MODULE_NAME,
MODULE_ALIASES,
MODULE_SCHEMES,
- MODULE_SORT_ORDER
+ MODULE_SORT_ORDER,
+
+ /* is_busy */ NULL,
+ /* shutdown */ NULL,
+ e_task_shell_module_migrate
};
void
Modified: branches/kill-bonobo/calendar/modules/e-task-shell-sidebar.c
==============================================================================
--- branches/kill-bonobo/calendar/modules/e-task-shell-sidebar.c (original)
+++ branches/kill-bonobo/calendar/modules/e-task-shell-sidebar.c Sun Oct 5 04:12:09 2008
@@ -434,7 +434,7 @@
g_signal_connect_swapped (
widget, "primary-selection-changed",
- G_CALLBACK (task_shell_sidebar_selection_changed_cb),
+ G_CALLBACK (task_shell_sidebar_primary_selection_changed_cb),
object);
}
Modified: branches/kill-bonobo/doc/reference/shell/Makefile.am
==============================================================================
--- branches/kill-bonobo/doc/reference/shell/Makefile.am (original)
+++ branches/kill-bonobo/doc/reference/shell/Makefile.am Sun Oct 5 04:12:09 2008
@@ -76,12 +76,15 @@
$(top_builddir)/shell/.libs/e-shell-sidebar.o \
$(top_builddir)/shell/.libs/e-shell-switcher.o \
$(top_builddir)/shell/.libs/e-shell-taskbar.o \
+ $(top_builddir)/shell/.libs/e-shell-upgrade.o \
$(top_builddir)/shell/.libs/e-shell-view.o \
$(top_builddir)/shell/.libs/e-shell-window-actions.o \
$(top_builddir)/shell/.libs/e-shell-window.o \
+ $(top_builddir)/e-util/.libs/e-bconf-map.o \
$(top_builddir)/e-util/.libs/e-dialog-utils.o \
$(top_builddir)/e-util/.libs/e-error.o \
$(top_builddir)/e-util/.libs/e-event.o \
+ $(top_builddir)/e-util/.libs/e-fsutils.o \
$(top_builddir)/e-util/.libs/e-icon-factory.o \
$(top_builddir)/e-util/.libs/e-import.o \
$(top_builddir)/e-util/.libs/e-logger.o \
Modified: branches/kill-bonobo/doc/reference/shell/eshell-sections.txt
==============================================================================
--- branches/kill-bonobo/doc/reference/shell/eshell-sections.txt (original)
+++ branches/kill-bonobo/doc/reference/shell/eshell-sections.txt Sun Oct 5 04:12:09 2008
@@ -19,6 +19,8 @@
e_shell_is_busy
e_shell_do_quit
e_shell_quit
+E_SHELL_UPGRADE_ERROR
+e_shell_upgrade_attempt
<SUBSECTION Standard>
E_SHELL
E_IS_SHELL
@@ -30,6 +32,7 @@
e_shell_get_type
<SUBSECTION Private>
EShellPrivate
+e_shell_upgrade_error_quirk
</SECTION>
<SECTION>
@@ -94,6 +97,7 @@
e_shell_module_add_activity
e_shell_module_is_busy
e_shell_module_shutdown
+e_shell_module_upgrade
e_shell_module_set_info
<SUBSECTION Standard>
E_SHELL_MODULE
Modified: branches/kill-bonobo/doc/reference/shell/tmpl/e-shell-module.sgml
==============================================================================
--- branches/kill-bonobo/doc/reference/shell/tmpl/e-shell-module.sgml (original)
+++ branches/kill-bonobo/doc/reference/shell/tmpl/e-shell-module.sgml Sun Oct 5 04:12:09 2008
@@ -52,6 +52,7 @@
@sort_order:
@is_busy:
@shutdown:
+ upgrade:
<!-- ##### FUNCTION e_shell_module_new ##### -->
<para>
@@ -136,6 +137,19 @@
@Returns:
+<!-- ##### FUNCTION e_shell_module_upgrade ##### -->
+<para>
+
+</para>
+
+ shell_module:
+ major:
+ minor:
+ micro:
+ error:
+ Returns:
+
+
<!-- ##### FUNCTION e_shell_module_set_info ##### -->
<para>
Modified: branches/kill-bonobo/doc/reference/shell/tmpl/e-shell.sgml
==============================================================================
--- branches/kill-bonobo/doc/reference/shell/tmpl/e-shell.sgml (original)
+++ branches/kill-bonobo/doc/reference/shell/tmpl/e-shell.sgml Sun Oct 5 04:12:09 2008
@@ -218,3 +218,19 @@
@Returns:
+<!-- ##### MACRO E_SHELL_UPGRADE_ERROR ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### FUNCTION e_shell_upgrade_attempt ##### -->
+<para>
+
+</para>
+
+ shell:
+ Returns:
+
+
Modified: branches/kill-bonobo/shell/Makefile.am
==============================================================================
--- branches/kill-bonobo/shell/Makefile.am (original)
+++ branches/kill-bonobo/shell/Makefile.am Sun Oct 5 04:12:09 2008
@@ -61,6 +61,7 @@
eshellinclude_HEADERS = \
e-shell-common.h \
e-shell-content.h \
+ e-shell-migrate.h \
e-shell-module.h \
e-shell-sidebar.h \
e-shell-switcher.h \
@@ -73,6 +74,7 @@
libeshell_la_SOURCES = \
$(IDL_GENERATED) \
e-shell-content.c \
+ e-shell-migrate.c \
e-shell-module.c \
e-shell-sidebar.c \
e-shell-switcher.c \
Added: branches/kill-bonobo/shell/e-shell-migrate.c
==============================================================================
--- (empty file)
+++ branches/kill-bonobo/shell/e-shell-migrate.c Sun Oct 5 04:12:09 2008
@@ -0,0 +1,339 @@
+/*
+ * e-shell-migrate.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-shell-migrate.h"
+
+#include <string.h>
+#include <unistd.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <libedataserver/e-xml-utils.h>
+
+#include "e-util/e-bconf-map.h"
+#include "e-util/e-error.h"
+#include "e-util/e-fsutils.h"
+#include "e-util/e-util.h"
+
+#define GCONF_VERSION_KEY "/apps/evolution/version"
+#define GCONF_LAST_VERSION_KEY "/apps/evolution/last_version"
+
+static const gchar *
+shell_migrate_get_old_data_dir (void)
+{
+ static gchar *old_data_dir = NULL;
+
+ if (G_UNLIKELY (old_data_dir == NULL))
+ old_data_dir = g_build_filename (
+ g_get_home_dir (), "evolution", NULL);
+
+ return old_data_dir;
+}
+
+static gboolean
+shell_migrate_attempt (EShell *shell,
+ gint major,
+ gint minor,
+ gint micro)
+{
+ GList *modules;
+ gboolean success = TRUE;
+
+ modules = e_shell_list_modules (shell);
+
+ while (success && modules != NULL) {
+ EShellModule *shell_module = modules->data;
+ GError *error = NULL;
+
+ success = e_shell_module_migrate (
+ shell_module, major, minor, micro, &error);
+
+ if (error != NULL) {
+ gint response;
+
+ response = e_error_run (
+ NULL, "shell:upgrade-failed",
+ error->message, NULL);
+
+ if (response == GTK_RESPONSE_CANCEL)
+ success = FALSE;
+
+ g_error_free (error);
+ }
+
+ modules = g_list_next (modules);
+ }
+
+ return success;
+}
+
+static void
+shell_migrate_get_version (gint *major,
+ gint *minor,
+ gint *micro)
+{
+ GConfClient *client;
+ const gchar *key;
+ const gchar *old_data_dir;
+ gchar *string;
+
+ old_data_dir = shell_migrate_get_old_data_dir ();
+
+ key = GCONF_VERSION_KEY;
+ client = gconf_client_get_default ();
+ string = gconf_client_get_string (client, key, NULL);
+ g_object_unref (client);
+
+ if (string != NULL) {
+ /* Since 1.4.0 we've kept the version key in GConf. */
+ sscanf (string, "%d.%d.%d", major, minor, micro);
+ g_free (string);
+
+ } else if (!g_file_test (old_data_dir, G_FILE_TEST_IS_DIR)) {
+ /* If the old data directory does not exist,
+ * it must be a new installation. */
+ *major = 0;
+ *minor = 0;
+ *micro = 0;
+
+ } else {
+ xmlDocPtr doc;
+ xmlNodePtr source;
+ gchar *filename;
+
+ filename = g_build_filename (
+ old_data_dir, "config.xmldb", NULL);
+ doc = e_xml_parse_file (filename);
+ g_free (filename);
+
+ if (doc == NULL)
+ return;
+
+ source = e_bconf_get_path (doc, "/Shell");
+ if (source != NULL) {
+ key = "upgrade_from_1_0_to_1_2_performed";
+ string = e_bconf_get_value (source, key);
+ }
+
+ if (string != NULL && *string == '1') {
+ *major = 1;
+ *minor = 2;
+ *micro = 0;
+ } else {
+ *major = 1;
+ *minor = 0;
+ *micro = 0;
+ }
+
+ g_free (string);
+
+ if (doc != NULL)
+ xmlFreeDoc (doc);
+ }
+}
+
+static gint
+shell_migrate_remove_dir (const gchar *root,
+ const gchar *path)
+{
+ GDir *dir;
+ const gchar *basename;
+ gchar *filename;
+ gint result = -1;
+
+ /* Recursively removes a directory and its contents. */
+
+ dir = g_dir_open (path, 0, NULL);
+ if (dir == NULL)
+ return -1;
+
+ while ((basename = g_dir_read_name (dir)) != NULL) {
+ filename = g_build_filename (path, basename, NULL);
+
+ /* Make sure we haven't strayed from the evolution dir. */
+ g_return_val_if_fail (strlen (path) >= strlen (root), -1);
+ g_return_val_if_fail (g_str_has_prefix (path, root), -1);
+
+ if (g_file_test (filename, G_FILE_TEST_IS_DIR)) {
+ if (shell_migrate_remove_dir (root, filename) < 0)
+ goto fail;
+ } else {
+ if (g_unlink (filename) < 0)
+ goto fail;
+ }
+
+ g_free (filename);
+ filename = NULL;
+ }
+
+ result = g_rmdir (path);
+
+fail:
+ g_free (filename);
+ g_dir_close (dir);
+
+ return result;
+}
+
+gboolean
+e_shell_migrate_attempt (EShell *shell)
+{
+ GConfClient *client;
+ const gchar *key;
+ const gchar *old_data_dir;
+ gint major, minor, micro;
+ gint last_major, last_minor, last_micro;
+ gint curr_major, curr_minor, curr_micro;
+ gboolean migrated = FALSE;
+ gchar *string;
+
+ g_return_val_if_fail (E_IS_SHELL (shell), FALSE);
+
+ old_data_dir = shell_migrate_get_old_data_dir ();
+
+ if (sscanf (BASE_VERSION, "%d.%d", &curr_major, &curr_minor) != 2) {
+ g_warning ("Could not parse BASE_VERSION (%s)", BASE_VERSION);
+ return TRUE;
+ }
+
+ curr_micro = atoi (UPGRADE_REVISION);
+
+ shell_migrate_get_version (&major, &minor, µ);
+
+ if (!(curr_major > major ||
+ (curr_major == major && curr_minor > minor) ||
+ (curr_minor == minor && curr_micro > micro)))
+ goto check_old;
+
+ /* If upgrading from < 1.5, we need to copy most data from
+ * ~/evolution to ~/.evolution. Make sure we have the disk
+ * space for it before proceeding. */
+ if (major == 1 && minor < 5) {
+ glong avail;
+ glong usage;
+
+ usage = e_fsutils_usage (old_data_dir);
+ avail = e_fsutils_avail (g_get_home_dir ());
+ if (usage >= 0 && avail >= 0 && avail < usage) {
+ gchar *need;
+ gchar *have;
+
+ need = g_strdup_printf (_("%ld KB"), usage);
+ have = g_strdup_printf (_("%ld KB"), avail);
+
+ e_error_run (
+ NULL, "shell:upgrade-nospace",
+ need, have, NULL);
+
+ g_free (need);
+ g_free (have);
+
+ _exit (EXIT_SUCCESS);
+ }
+ }
+
+ if (!shell_migrate_attempt (shell, major, minor, micro))
+ _exit (EXIT_SUCCESS);
+
+ /* Record a successful migration. */
+ client = gconf_client_get_default ();
+ string = g_strdup_printf ("%d.%d.%d", major, minor, micro);
+ gconf_client_set_string (client, GCONF_VERSION_KEY, string, NULL);
+ g_object_unref (client);
+ g_free (string);
+
+ migrated = TRUE;
+
+check_old:
+
+ key = GCONF_LAST_VERSION_KEY;
+ client = gconf_client_get_default ();
+
+ /* Try to retrieve the last migrated version from GConf. */
+ string = gconf_client_get_string (client, key, NULL);
+ if (migrated || string == NULL || sscanf (string, "%d.%d.%d",
+ &last_major, &last_minor, &last_micro) != 3) {
+ last_major = major;
+ last_minor = minor;
+ last_micro = micro;
+ }
+ g_free (string);
+
+ /* If the last migrated version was old, check for stuff to remove. */
+ if (last_major == 1 && last_minor < 5 &&
+ g_file_test (old_data_dir, G_FILE_TEST_IS_DIR)) {
+
+ gint response;
+
+ string = g_strdup_printf (
+ "%d.%d.%d", last_major, last_minor, last_micro);
+ response = e_error_run (
+ NULL, "shel:upgrade-remove-1-4", string, NULL);
+ g_free (string);
+
+ switch (response) {
+ case GTK_RESPONSE_OK: /* delete */
+ response = e_error_run (
+ NULL,
+ "shell:upgrade-remove-1-4-confirm",
+ NULL);
+ if (response == GTK_RESPONSE_OK)
+ shell_migrate_remove_dir (
+ old_data_dir, old_data_dir);
+ else
+ break;
+ /* fall through */
+
+ case GTK_RESPONSE_ACCEPT: /* keep */
+ last_major = curr_major;
+ last_minor = curr_minor;
+ last_micro = curr_micro;
+ break;
+
+ default:
+ break;
+ }
+ } else {
+ last_major = curr_major;
+ last_minor = curr_minor;
+ last_micro = curr_micro;
+ }
+
+ string = g_strdup_printf (
+ "%d.%d.%d", last_major, last_minor, last_micro);
+ gconf_client_set_string (client, key, string, NULL);
+ g_free (string);
+
+ g_object_unref (client);
+
+ return TRUE;
+}
+
+GQuark
+e_shell_migrate_error_quark (void)
+{
+ static GQuark quark = 0;
+
+ if (G_UNLIKELY (quark == 0))
+ quark = g_quark_from_static_string (
+ "e-shell-migrate-error-quark");
+
+ return quark;
+}
Added: branches/kill-bonobo/shell/e-shell-migrate.h
==============================================================================
--- (empty file)
+++ branches/kill-bonobo/shell/e-shell-migrate.h Sun Oct 5 04:12:09 2008
@@ -0,0 +1,45 @@
+/*
+ * e-shell-migrate.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/* This is an EShell extension that handles migrating from older versions. */
+
+#ifndef E_SHELL_MIGRATE_H
+#define E_SHELL_MIGRATE_H
+
+#include <shell/e-shell-common.h>
+#include <shell/e-shell.h>
+
+#define E_SHELL_MIGRATE_ERROR \
+ (e_shell_migrate_error_quark ())
+
+G_BEGIN_DECLS
+
+/* XXX Need more specific error codes? */
+typedef enum {
+ E_SHELL_MIGRATE_ERROR_FAILED
+} EShellMigrateError;
+
+gboolean e_shell_migrate_attempt (EShell *shell);
+GQuark e_shell_migrate_error_quark (void);
+
+G_END_DECLS
+
+#endif /* E_SHELL_MIGRATE_H */
Modified: branches/kill-bonobo/shell/e-shell-module.c
==============================================================================
--- branches/kill-bonobo/shell/e-shell-module.c (original)
+++ branches/kill-bonobo/shell/e-shell-module.c Sun Oct 5 04:12:09 2008
@@ -499,6 +499,40 @@
}
/**
+ * e_shell_migrate:
+ * @shell_module: an #EShellModule
+ * @major: major part of version to migrate from
+ * @minor: minor part of version to migrate from
+ * @micro: micro part of version to migrate from
+ * @error: return location for a #GError, or %NULL
+ *
+ * Attempts to migrate data and settings from version %major.%minor.%micro.
+ * Returns %TRUE if the migration was successful or if no action was
+ * necessary. Returns %FALSE and sets %error if the migration failed.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise
+ **/
+gboolean
+e_shell_module_migrate (EShellModule *shell_module,
+ gint major,
+ gint minor,
+ gint micro,
+ GError **error)
+{
+ EShellModuleInfo *module_info;
+
+ g_return_val_if_fail (E_IS_SHELL_MODULE (shell_module), TRUE);
+
+ module_info = &shell_module->priv->info;
+
+ if (module_info->migrate != NULL)
+ return module_info->migrate (
+ shell_module, major, minor, micro, error);
+
+ return TRUE;
+}
+
+/**
* e_shell_module_set_info:
* @shell_module: an #EShellModule
* @info: an #EShellModuleInfo
@@ -535,6 +569,7 @@
module_info->is_busy = info->is_busy;
module_info->shutdown = info->shutdown;
+ module_info->migrate = info->migrate;
/* Determine the user data directory for this module. */
g_free (shell_module->priv->data_dir);
Modified: branches/kill-bonobo/shell/e-shell-module.h
==============================================================================
--- branches/kill-bonobo/shell/e-shell-module.h (original)
+++ branches/kill-bonobo/shell/e-shell-module.h Sun Oct 5 04:12:09 2008
@@ -81,6 +81,10 @@
* shutting down. Returning %FALSE indicates there
* are still unfinished operations and the #EShell
* should check back shortly.
+ * @migrate: Callback for notifying the module to migrate data and
+ * settings from the given version. Returns %TRUE if the
+ * migration was successful or if no action was necessary.
+ * Returns %FALSE and sets a #GError if the migration failed.
**/
struct _EShellModuleInfo {
const gchar *name;
@@ -90,6 +94,11 @@
gboolean (*is_busy) (EShellModule *shell_module);
gboolean (*shutdown) (EShellModule *shell_module);
+ gboolean (*migrate) (EShellModule *shell_module,
+ gint major,
+ gint minor,
+ gint micro,
+ GError **error);
};
/**
@@ -120,6 +129,11 @@
EActivity *activity);
gboolean e_shell_module_is_busy (EShellModule *shell_module);
gboolean e_shell_module_shutdown (EShellModule *shell_module);
+gboolean e_shell_module_migrate (EShellModule *shell_module,
+ gint major,
+ gint minor,
+ gint micro,
+ GError **error);
void e_shell_module_set_info (EShellModule *shell_module,
const EShellModuleInfo *info);
Modified: branches/kill-bonobo/shell/e-shell.c
==============================================================================
--- branches/kill-bonobo/shell/e-shell.c (original)
+++ branches/kill-bonobo/shell/e-shell.c Sun Oct 5 04:12:09 2008
@@ -26,6 +26,7 @@
#include <e-util/e-util.h>
#include <e-shell-module.h>
+#include <e-shell-upgrade.h>
#include <e-shell-window.h>
#define SHUTDOWN_TIMEOUT 500 /* milliseconds */
@@ -79,6 +80,31 @@
return !e_shell_quit (shell);
}
+static gboolean
+shell_window_focus_in_event_cb (EShell *shell,
+ GdkEventFocus *event,
+ EShellWindow *shell_window)
+{
+ GList *list, *link;
+
+ /* Keep the active windows list sorted by most recently focused,
+ * so the first item in the list should always be the currently
+ * focused shell window. */
+
+ list = shell->priv->active_windows;
+ link = g_list_find (list, shell_window);
+ g_return_val_if_fail (link != NULL, FALSE);
+
+ if (link != list) {
+ list = g_list_remove_link (list, link);
+ list = g_list_concat (link, list);
+ }
+
+ shell->priv->active_windows = list;
+
+ return FALSE;
+}
+
static void
shell_window_weak_notify_cb (EShell *shell,
GObject *where_the_object_was)
@@ -300,6 +326,8 @@
}
g_dir_close (dir);
+
+ e_shell_upgrade_attempt (shell);
}
static void
@@ -493,6 +521,10 @@
shell_window, "delete-event",
G_CALLBACK (shell_window_delete_event_cb), shell);
+ g_signal_connect_swapped (
+ shell_window, "focus-in-event",
+ G_CALLBACK (shell_window_focus_in_event_cb), shell);
+
g_object_weak_ref (
G_OBJECT (shell_window), (GWeakNotify)
shell_window_weak_notify_cb, shell);
@@ -504,6 +536,17 @@
return shell_window;
}
+GtkWidget *
+e_shell_get_focused_window (EShell *shell)
+{
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
+
+ if (shell->priv->active_windows == NULL)
+ return NULL;
+
+ return GTK_WIDGET (shell->priv->active_windows->data);
+}
+
gboolean
e_shell_handle_uri (EShell *shell,
const gchar *uri)
Modified: branches/kill-bonobo/shell/e-shell.h
==============================================================================
--- branches/kill-bonobo/shell/e-shell.h (original)
+++ branches/kill-bonobo/shell/e-shell.h Sun Oct 5 04:12:09 2008
@@ -90,6 +90,7 @@
EShellModule * e_shell_get_module_by_scheme (EShell *shell,
const gchar *scheme);
GtkWidget * e_shell_create_window (EShell *shell);
+GtkWidget * e_shell_get_focused_window (EShell *shell);
gboolean e_shell_handle_uri (EShell *shell,
const gchar *uri);
void e_shell_send_receive (EShell *shell,
Modified: branches/kill-bonobo/shell/test/e-test-shell-module.c
==============================================================================
--- branches/kill-bonobo/shell/test/e-test-shell-module.c (original)
+++ branches/kill-bonobo/shell/test/e-test-shell-module.c Sun Oct 5 04:12:09 2008
@@ -86,8 +86,20 @@
}
static gboolean
-test_module_handle_uri (EShellModule *shell_module,
- const gchar *uri)
+test_module_migrate (EShellModule *shell_module,
+ gint major,
+ gint minor,
+ gint micro,
+ GError **error)
+{
+ g_debug ("%s (from %d.%d.%d)", G_STRFUNC, major, minor, micro);
+
+ return TRUE;
+}
+
+static gboolean
+test_module_handle_uri_cb (EShellModule *shell_module,
+ const gchar *uri)
{
g_debug ("%s (uri=%s)", G_STRFUNC, uri);
@@ -95,15 +107,15 @@
}
static void
-test_module_send_receive (EShellModule *shell_module,
- GtkWindow *parent_window)
+test_module_send_receive_cb (EShellModule *shell_module,
+ GtkWindow *parent_window)
{
g_debug ("%s (window=%p)", G_STRFUNC, parent_window);
}
static void
-test_module_window_created (EShellModule *shell_module,
- EShellWindow *shell_window)
+test_module_window_created_cb (EShellModule *shell_module,
+ EShellWindow *shell_window)
{
const gchar *module_name;
@@ -121,8 +133,8 @@
}
static void
-test_module_window_destroyed (EShellModule *shell_module,
- gboolean last_window)
+test_module_window_destroyed_cb (EShellModule *shell_module,
+ gboolean last_window)
{
g_debug ("%s (last=%d)", G_STRFUNC, last_window);
}
@@ -136,7 +148,8 @@
/* Methods */
test_module_is_busy,
- test_module_shutdown
+ test_module_shutdown,
+ test_module_migrate
};
void
@@ -153,17 +166,17 @@
g_signal_connect_swapped (
shell, "handle-uri",
- G_CALLBACK (test_module_handle_uri), shell_module);
+ G_CALLBACK (test_module_handle_uri_cb), shell_module);
g_signal_connect_swapped (
shell, "send-receive",
- G_CALLBACK (test_module_send_receive), shell_module);
+ G_CALLBACK (test_module_send_receive_cb), shell_module);
g_signal_connect_swapped (
shell, "window-created",
- G_CALLBACK (test_module_window_created), shell_module);
+ G_CALLBACK (test_module_window_created_cb), shell_module);
g_signal_connect_swapped (
shell, "window-destroyed",
- G_CALLBACK (test_module_window_destroyed), shell_module);
+ G_CALLBACK (test_module_window_destroyed_cb), shell_module);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]