[evolution-kolab] EPlugin: added dialog for sync conflict resolution
- From: Christian Hilberg <chilberg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-kolab] EPlugin: added dialog for sync conflict resolution
- Date: Tue, 21 Feb 2012 16:10:13 +0000 (UTC)
commit f87506d7ab04c1a5a245cfd477505616fdf20ce1
Author: Christian Hilberg <hilberg kernelconcepts de>
Date: Tue Feb 21 15:17:02 2012 +0100
EPlugin: added dialog for sync conflict resolution
* replicates https://roundup.kolab.org/file1562/new-conflictdialog-7-en.png,
minus the "Details..." buttons which we will leave out for the
first shot
* no functionality as yet, dialog will not be visible
until the frontend<->backend extra communication
has been implemented
src/eplugin/Makefile.am | 2 +
src/eplugin/e-kolab-backend-sync-conflict.c | 370 +++++++++++++++++++++++++++
src/eplugin/e-kolab-backend-sync-conflict.h | 47 ++++
src/eplugin/e-kolab-plugin.c | 10 +
4 files changed, 429 insertions(+), 0 deletions(-)
---
diff --git a/src/eplugin/Makefile.am b/src/eplugin/Makefile.am
index 8ae9677..45ea299 100644
--- a/src/eplugin/Makefile.am
+++ b/src/eplugin/Makefile.am
@@ -11,6 +11,7 @@ AM_CPPFLAGS = \
noinst_HEADERS = \
e-kolab-account-setup.h \
+ e-kolab-backend-sync-conflict.h \
e-kolab-folder-metadata.h \
e-kolab-folder-permissions.h \
e-kolab-freebusy.h \
@@ -26,6 +27,7 @@ plugin_LTLIBRARIES = liborg-gnome-kolab.la
liborg_gnome_kolab_la_SOURCES = \
e-kolab-account-setup.c \
+ e-kolab-backend-sync-conflict.c \
e-kolab-folder-metadata.c \
e-kolab-folder-permissions.c \
e-kolab-freebusy.c \
diff --git a/src/eplugin/e-kolab-backend-sync-conflict.c b/src/eplugin/e-kolab-backend-sync-conflict.c
new file mode 100644
index 0000000..76dd2d4
--- /dev/null
+++ b/src/eplugin/e-kolab-backend-sync-conflict.c
@@ -0,0 +1,370 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/***************************************************************************
+ * e-kolab-backend-sync-conflict.c
+ *
+ * Fri Feb 20 22:54:05 2012
+ * Copyright 2012 Christian Hilberg
+ * <hilberg kernelconcepts de>
+ *
+ ****************************************************************************/
+
+/*
+ * 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.1 of the License, or (at your option) any later version.
+ *
+ * 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA
+ */
+/*----------------------------------------------------------------------------*/
+
+#include <config.h>
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <glib/gi18n-lib.h>
+
+#include "e-kolab-backend-sync-conflict.h"
+
+/*----------------------------------------------------------------------------*/
+
+typedef struct _KolabBackendSyncConflictUIWidgets KolabBackendSyncConflictUIWidgets;
+struct _KolabBackendSyncConflictUIWidgets {
+ GtkWidget *container;
+ /* sub-widgets of container */
+ GtkWidget *lbl_folder_name;
+ GtkWidget *lbl_local_subject;
+ GtkWidget *lbl_local_modtime;
+ GtkWidget *lbl_remote_subject;
+ GtkWidget *lbl_remote_modtime;
+ GSList *radio_group;
+ GtkWidget *radio_btn_this_sync;
+ GtkWidget *radio_btn_this_session;
+ GtkWidget *radio_btn_permanent;
+ GtkWidget *radio_btn_ask_again;
+ GtkWidget *btn_strategy_newer;
+ GtkWidget *btn_strategy_server;
+ GtkWidget *btn_strategy_client;
+ GtkWidget *btn_strategy_dupe;
+};
+
+typedef struct _KolabBackendSyncConflictUIData KolabBackendSyncConflictUIData;
+struct _KolabBackendSyncConflictUIData {
+ KolabBackendSyncConflictUIWidgets *widgets;
+ /* FIXME add payload "data" part here */
+};
+
+/* corresponds to sync strategy,
+ * maybe we can unify this
+ */
+enum {
+ KOLAB_SYNC_CONFLICT_RESPONSE_NEWER = 0,
+ KOLAB_SYNC_CONFLICT_RESPONSE_SERVER,
+ KOLAB_SYNC_CONFLICT_RESPONSE_CLIENT,
+ KOLAB_SYNC_CONFLICT_RESPONSE_DUPE,
+ KOLAB_SYNC_CONFLICT_LAST_RESPONSE,
+ KOLAB_SYNC_CONFLICT_RESPONSE_DEFAULT = KOLAB_SYNC_CONFLICT_RESPONSE_NEWER
+};
+
+#define KOLAB_SYNC_CONFLICT_WIDGET_BORDER_WIDTH 8
+
+/*----------------------------------------------------------------------------*/
+/* internal statics (non-UI) */
+
+
+/*----------------------------------------------------------------------------*/
+/* internal statics (UI) */
+
+
+/*----------------------------------------------------------------------------*/
+/* API functions (non-UI) */
+
+/*----------------------------------------------------------------------------*/
+/* API functions (UI) */
+
+static KolabBackendSyncConflictUIData*
+kolab_backend_sync_conflict_ui_new (void)
+{
+ KolabBackendSyncConflictUIData *uidata = g_new0 (KolabBackendSyncConflictUIData, 1);
+ GtkWidget *content = NULL;
+ GtkWidget *ev_box = NULL;
+ GtkWidget *frame_info = NULL;
+ GtkWidget *frame_take_dur = NULL;
+ GtkWidget *frame_take = NULL;
+ GtkGrid *grid = NULL;
+ GtkWidget *widget = NULL;
+ GtkWidget *label = NULL;
+ gchar *tmp_str = NULL;
+ const guint state_flags = GTK_STATE_FLAG_NORMAL;
+ const GdkRGBA color = { 0.933, 0.965, 1.0, 1.0 };
+ gint row = 0;
+
+ uidata->widgets = g_new0 (KolabBackendSyncConflictUIWidgets, 1);
+ uidata->widgets->container = gtk_dialog_new ();
+ gtk_window_set_modal (GTK_WINDOW (uidata->widgets->container), TRUE);
+ gtk_window_set_resizable (GTK_WINDOW (uidata->widgets->container), FALSE);
+ content = gtk_dialog_get_content_area (GTK_DIALOG (uidata->widgets->container));
+ gtk_container_set_border_width (GTK_CONTAINER (content), KOLAB_SYNC_CONFLICT_WIDGET_BORDER_WIDTH);
+
+ /* sync conflict information */
+ frame_info = gtk_frame_new (NULL);
+ gtk_container_set_border_width (GTK_CONTAINER (frame_info), KOLAB_SYNC_CONFLICT_WIDGET_BORDER_WIDTH);
+ gtk_container_add (GTK_CONTAINER (content), frame_info);
+ ev_box = gtk_event_box_new ();
+ gtk_container_set_border_width (GTK_CONTAINER (ev_box), 1);
+ gtk_widget_override_background_color (ev_box, state_flags, &color);
+ gtk_container_add (GTK_CONTAINER (frame_info), ev_box);
+ widget = gtk_label_new (NULL);
+ gtk_label_set_text (GTK_LABEL (widget),
+ _("A synchronization error occured: \nProbably someone modified an entry remotely (i.e. on the server), \nwhich you have also modified locally (i.e. on your client)."));
+ gtk_label_set_justify (GTK_LABEL (widget), GTK_JUSTIFY_LEFT);
+ gtk_container_add (GTK_CONTAINER (ev_box), widget);
+
+ /* object detail */
+
+ grid = GTK_GRID (gtk_grid_new ());
+ gtk_grid_set_row_homogeneous (grid, TRUE);
+ gtk_grid_set_row_spacing (grid, 6);
+ gtk_grid_set_column_homogeneous (grid, FALSE);
+ gtk_grid_set_column_spacing (grid, 6);
+ gtk_container_set_border_width (GTK_CONTAINER (grid), KOLAB_SYNC_CONFLICT_WIDGET_BORDER_WIDTH);
+ /* gtk_container_set_resize_mode (GTK_CONTAINER (grid), GTK_RESIZE_QUEUE); */
+ gtk_container_add (GTK_CONTAINER (content), GTK_WIDGET (grid));
+
+ row = 0;
+
+ /* conflict folder name */
+ tmp_str = g_strconcat (_("Conflict in folder"), ":", NULL);
+ label = gtk_label_new (tmp_str);
+ gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
+ g_free (tmp_str);
+ gtk_grid_attach (grid, label, 0, row, 1, 1);
+ label = gtk_label_new (NULL /* FIXME add folder path here */);
+ gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
+ uidata->widgets->lbl_folder_name = label;
+ gtk_grid_attach (grid, label, 1, row, 1, 1);
+
+ row++;
+
+ /* local object - subject */
+ tmp_str = g_strconcat (_("Local entry"), ":", NULL);
+ label = gtk_label_new (tmp_str);
+ gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
+ g_free (tmp_str);
+ gtk_grid_attach (grid, label, 0, row, 1, 1);
+ label = gtk_label_new (NULL /* FIXME add subject here */);
+ gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
+ uidata->widgets->lbl_local_subject = label;
+ gtk_grid_attach (grid, label, 1, row, 1, 1);
+
+ row++;
+
+ /* local object - last modified */
+ tmp_str = g_strconcat (_("Last modified"), ":", NULL);
+ label = gtk_label_new (tmp_str);
+ gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
+ g_free (tmp_str);
+ gtk_grid_attach (grid, label, 0, row, 1, 1);
+ label = gtk_label_new (NULL /* FIXME add modtime here */);
+ gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
+ uidata->widgets->lbl_local_modtime = label;
+ gtk_grid_attach (grid, label, 1, row, 1, 1);
+
+ row++;
+
+ /* remote object - subject */
+ tmp_str = g_strconcat (_("Remote entry"), ":", NULL);
+ label = gtk_label_new (tmp_str);
+ gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
+ g_free (tmp_str);
+ gtk_grid_attach (grid, label, 0, row, 1, 1);
+ label = gtk_label_new (NULL /* FIXME add subject here */);
+ gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
+ uidata->widgets->lbl_remote_subject = label;
+ gtk_grid_attach (grid, label, 1, row, 1, 1);
+
+ row++;
+
+ /* remote object - last modified */
+ tmp_str = g_strconcat (_("Last modified"), ":", NULL);
+ label = gtk_label_new (tmp_str);
+ gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
+ g_free (tmp_str);
+ gtk_grid_attach (grid, label, 0, row, 1, 1);
+ label = gtk_label_new (NULL /* FIXME add modtime here */);
+ gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
+ uidata->widgets->lbl_remote_modtime = label;
+ gtk_grid_attach (grid, label, 1, row, 1, 1);
+
+ row++;
+
+ /* take option duration */
+
+ frame_take_dur = gtk_frame_new (_("Take option duration"));
+ gtk_container_set_border_width (GTK_CONTAINER (frame_take_dur), KOLAB_SYNC_CONFLICT_WIDGET_BORDER_WIDTH);
+ gtk_container_add (GTK_CONTAINER (content), frame_take_dur);
+
+ grid = GTK_GRID (gtk_grid_new ());
+ gtk_grid_set_row_homogeneous (grid, TRUE);
+ gtk_grid_set_row_spacing (grid, 0);
+ gtk_grid_set_column_homogeneous (grid, FALSE);
+ gtk_grid_set_column_spacing (grid, 6);
+ gtk_container_set_border_width (GTK_CONTAINER (grid), 6);
+ /* gtk_container_set_resize_mode (GTK_CONTAINER (grid), GTK_RESIZE_QUEUE); */
+ gtk_container_add (GTK_CONTAINER (frame_take_dur), GTK_WIDGET (grid));
+
+ row = 0;
+
+ tmp_str = g_strconcat (_("Please choose how long the \"Take option\" specified below \nshould remain in effect"), ":", NULL);
+ label = gtk_label_new (tmp_str);
+ gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
+ g_free (tmp_str);
+ gtk_grid_attach (grid, label, 1, row, 1, 1);
+
+ row++;
+
+ widget = gtk_radio_button_new_with_label (NULL, _("Apply to all conflicts occuring during this synchronization"));
+ uidata->widgets->radio_btn_this_sync = widget;
+ uidata->widgets->radio_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
+ gtk_grid_attach (grid, widget, 1, row, 1, 1);
+
+ row++;
+
+ widget = gtk_radio_button_new_with_label (uidata->widgets->radio_group, _("Apply to all conflicts occuring during this Evolution session"));
+ uidata->widgets->radio_btn_this_session = widget;
+ gtk_grid_attach (grid, widget, 1, row, 1, 1);
+
+ row++;
+
+ widget = gtk_radio_button_new_with_label (uidata->widgets->radio_group, _("Apply always and permanently"));
+ uidata->widgets->radio_btn_permanent = widget;
+ gtk_grid_attach (grid, widget, 1, row, 1, 1);
+
+ row++;
+
+ widget = gtk_radio_button_new_with_label (uidata->widgets->radio_group, _("Apply only to this conflict (ask each time)"));
+ uidata->widgets->radio_btn_permanent = widget;
+ gtk_grid_attach (grid, widget, 1, row, 1, 1);
+
+ /* take options (actions!) */
+
+ frame_take = gtk_frame_new (_("Take options"));
+ gtk_container_set_border_width (GTK_CONTAINER (frame_take), KOLAB_SYNC_CONFLICT_WIDGET_BORDER_WIDTH);
+ gtk_container_add (GTK_CONTAINER (content), frame_take);
+
+ grid = GTK_GRID (gtk_grid_new ());
+ gtk_grid_set_row_homogeneous (grid, TRUE);
+ gtk_grid_set_row_spacing (grid, 2);
+ gtk_grid_set_column_homogeneous (grid, FALSE);
+ gtk_grid_set_column_spacing (grid, 6);
+ gtk_container_set_border_width (GTK_CONTAINER (grid), 6);
+ /* gtk_container_set_resize_mode (GTK_CONTAINER (grid), GTK_RESIZE_QUEUE); */
+ gtk_container_add (GTK_CONTAINER (frame_take), GTK_WIDGET (grid));
+
+ row = 0;
+
+ tmp_str = g_strconcat (_("Please choose which of the two entries should be retained"), ":", NULL);
+ label = gtk_label_new (tmp_str);
+ gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
+ g_free (tmp_str);
+ gtk_grid_attach (grid, label, 1, row, 2, 1);
+
+ row++;
+
+ widget = gtk_button_new_with_label (_("Take Newer (last modified)"));
+ uidata->widgets->btn_strategy_newer = widget;
+ gtk_grid_attach (grid, widget, 1, row, 1, 1);
+
+ row++;
+
+ widget = gtk_button_new_with_label (_("Take Remote (server-side)"));
+ uidata->widgets->btn_strategy_server = widget;
+ gtk_grid_attach (grid, widget, 1, row, 1, 1);
+
+ row++;
+
+ widget = gtk_button_new_with_label (_("Take Local (client-side)"));
+ uidata->widgets->btn_strategy_client = widget;
+ gtk_grid_attach (grid, widget, 1, row, 1, 1);
+
+ row++;
+
+ widget = gtk_button_new_with_label (_("Take Both (resulting in two different, parallel entries)"));
+ uidata->widgets->btn_strategy_dupe = widget;
+ gtk_grid_attach (grid, widget, 1, row, 1, 1);
+
+ /* FIXME connect signals */
+ g_warning ("%s: FIXME connect signals", __func__);
+
+ gtk_widget_show_all (content);
+
+ return uidata;
+}
+
+static void
+kolab_backend_sync_conflict_ui_free (KolabBackendSyncConflictUIData *uidata)
+{
+ if (uidata == NULL)
+ return;
+
+ /* the actual widgets will have been deleted already,
+ * so just deleting the struct shell here
+ */
+ if (uidata->widgets != NULL)
+ g_free (uidata->widgets);
+
+ /* free payload data here */
+
+ g_free (uidata);
+}
+
+static void
+kolab_backend_sync_conflict_ui_destroy (gpointer ptr)
+{
+ KolabBackendSyncConflictUIData *uidata = ptr;
+ kolab_backend_sync_conflict_ui_free (uidata);
+}
+
+static void
+e_kolab_backend_sync_ui_conflict_response_cb (GObject *dialog,
+ gint response_id)
+{
+ g_return_if_fail (dialog != NULL);
+
+ if (response_id != GTK_RESPONSE_OK) {
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ return;
+ }
+
+ /* FIXME implement me */
+ g_warning ("%s: FIXME implement me", __func__);
+}
+
+void
+e_kolab_backend_sync_ui_conflict_cb (EShellView *shell_view)
+{
+ GObject *dialog = NULL;
+
+ KolabBackendSyncConflictUIData *uidata = NULL;
+
+ if (shell_view != NULL)
+ g_assert (E_IS_SHELL_VIEW (shell_view));
+
+ uidata = kolab_backend_sync_conflict_ui_new ();
+ dialog = G_OBJECT (uidata->widgets->container);
+ g_object_set_data_full (dialog, "e-kolab-backend-sync-prop", uidata, kolab_backend_sync_conflict_ui_destroy);
+
+ /* signals */
+
+ gtk_widget_show (GTK_WIDGET (dialog));
+}
+
+/*----------------------------------------------------------------------------*/
diff --git a/src/eplugin/e-kolab-backend-sync-conflict.h b/src/eplugin/e-kolab-backend-sync-conflict.h
new file mode 100644
index 0000000..993c924
--- /dev/null
+++ b/src/eplugin/e-kolab-backend-sync-conflict.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/***************************************************************************
+ * e-kolab-backend-sync-conflict.h
+ *
+ * Fri Feb 20 22:32:05 2012
+ * Copyright 2012 Christian Hilberg
+ * <hilberg kernelconcepts de>
+ *
+ ****************************************************************************/
+
+/*
+ * 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.1 of the License, or (at your option) any later version.
+ *
+ * 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA
+ */
+
+/*----------------------------------------------------------------------------*/
+
+#ifndef _E_KOLAB_BACKEND_SYNC_CONFLICT_H_
+#define _E_KOLAB_BACKEND_SYNC_CONFLICT_H_
+
+/*----------------------------------------------------------------------------*/
+
+#include <e-util/e-config.h>
+#include <e-util/e-plugin.h>
+#include <shell/e-shell-view.h>
+
+/*----------------------------------------------------------------------------*/
+
+void
+e_kolab_backend_sync_ui_conflict_cb (EShellView *shell_view);
+
+/*----------------------------------------------------------------------------*/
+
+#endif /* _E_KOLAB_BACKEND_SYNC_CONFLICT_H_ */
+
+/*----------------------------------------------------------------------------*/
diff --git a/src/eplugin/e-kolab-plugin.c b/src/eplugin/e-kolab-plugin.c
index a4b4a2d..d3ad1b4 100644
--- a/src/eplugin/e-kolab-plugin.c
+++ b/src/eplugin/e-kolab-plugin.c
@@ -26,6 +26,10 @@
/*----------------------------------------------------------------------------*/
+#define d(x) x
+
+/*----------------------------------------------------------------------------*/
+
#include <config.h>
#include "e-kolab-account-setup.h"
@@ -33,6 +37,8 @@
#include "e-kolab-plugin-ui.h"
#include "e-kolab-plugin.h"
+#include "e-kolab-backend-sync-conflict.h"
+
/*----------------------------------------------------------------------------*/
/* plugin */
@@ -55,6 +61,10 @@ e_plugin_lib_enable (EPlugin *epl,
} else {
g_debug ("%s(): Kolab plugin disabled", __func__);
}
+
+ /* FIXME remove me! */
+ d (e_kolab_backend_sync_ui_conflict_cb (NULL);)
+
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]