1f60171e53
use the name of a saved config (and not the the template) when saving the config again.
2124 lines
71 KiB
C
2124 lines
71 KiB
C
#include "config.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <glib/gi18n.h>
|
|
#include <dbus/dbus-glib.h>
|
|
|
|
#ifdef USE_MOBLIN_UX
|
|
#ifdef MX_GTK_0_99_1
|
|
#include <mx-gtk/mx-gtk.h>
|
|
#else
|
|
#include <mx/mx-gtk.h>
|
|
#endif
|
|
#endif
|
|
|
|
#include "sync-ui.h"
|
|
#include "sync-config-widget.h"
|
|
|
|
/* local copy of GtkInfoBar, used when GTK+ < 2.18 */
|
|
#include "gtkinfobar.h"
|
|
|
|
|
|
#define INDICATOR_SIZE 16
|
|
#define CHILD_PADDING 3
|
|
|
|
G_DEFINE_TYPE (SyncConfigWidget, sync_config_widget, GTK_TYPE_CONTAINER)
|
|
|
|
|
|
typedef struct source_widgets {
|
|
char *name;
|
|
|
|
GtkWidget *label;
|
|
GtkWidget *entry;
|
|
GtkWidget *check;
|
|
|
|
GtkWidget *source_toggle_label;
|
|
|
|
guint count;
|
|
} source_widgets;
|
|
|
|
enum
|
|
{
|
|
PROP_0,
|
|
|
|
PROP_SERVER,
|
|
PROP_NAME,
|
|
PROP_CONFIG,
|
|
PROP_CURRENT,
|
|
PROP_HAS_TEMPLATE,
|
|
PROP_CONFIGURED,
|
|
PROP_CURRENT_SERVICE_NAME,
|
|
PROP_EXPANDED,
|
|
};
|
|
|
|
enum {
|
|
SIGNAL_CHANGED,
|
|
LAST_SIGNAL
|
|
};
|
|
static guint32 signals[LAST_SIGNAL] = {0, };
|
|
|
|
static void sync_config_widget_update_label (SyncConfigWidget *self);
|
|
|
|
static void
|
|
remove_child (GtkWidget *widget, GtkContainer *container)
|
|
{
|
|
gtk_container_remove (container, widget);
|
|
}
|
|
|
|
const char*
|
|
get_service_description (const char *service)
|
|
{
|
|
if (!service)
|
|
return NULL;
|
|
|
|
/* TRANSLATORS: Descriptions for specific services, shown in service
|
|
* configuration form */
|
|
if (strcmp (service, "ScheduleWorld") == 0) {
|
|
return _("ScheduleWorld enables you to keep your contacts, events, "
|
|
"tasks, and notes in sync.");
|
|
}else if (strcmp (service, "Google") == 0) {
|
|
return _("Google Sync can backup and synchronize your contacts "
|
|
"with your Gmail contacts.");
|
|
}else if (strcmp (service, "Funambol") == 0) {
|
|
/* TRANSLATORS: Please include the word "demo" (or the equivalent in
|
|
your language): Funambol is going to be a 90 day demo service
|
|
in the future */
|
|
return _("Backup your contacts and calendar. Sync with a single "
|
|
"click, anytime, anywhere (DEMO).");
|
|
}else if (strcmp (service, "Mobical") == 0) {
|
|
return _("Mobical Backup and Restore service allows you to securely "
|
|
"backup your personal mobile data for free.");
|
|
}else if (strcmp (service, "ZYB") == 0) {
|
|
return _("ZYB is a simple way for people to store and share mobile "
|
|
"information online.");
|
|
}else if (strcmp (service, "Memotoo") == 0) {
|
|
return _("Memotoo lets you access your personal data from any "
|
|
"computer connected to the Internet.");
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static void
|
|
update_source_uri (char *name,
|
|
GHashTable *source_configuration,
|
|
SyncConfigWidget *self)
|
|
{
|
|
const char *uri;
|
|
source_widgets *widgets;
|
|
|
|
widgets = (source_widgets*)g_hash_table_lookup (self->sources, name);
|
|
if (!widgets) {
|
|
return;
|
|
}
|
|
|
|
uri = gtk_entry_get_text (GTK_ENTRY (widgets->entry));
|
|
g_hash_table_insert (source_configuration, g_strdup ("uri"), g_strdup (uri));
|
|
}
|
|
|
|
typedef struct save_config_data {
|
|
SyncConfigWidget *widget;
|
|
gboolean delete;
|
|
gboolean temporary;
|
|
source_widgets *widgets;
|
|
} save_config_data;
|
|
|
|
static source_widgets *
|
|
source_widgets_ref (source_widgets *widgets)
|
|
{
|
|
if (widgets) {
|
|
widgets->count++;
|
|
}
|
|
return widgets;
|
|
}
|
|
|
|
static void
|
|
source_widgets_unref (source_widgets *widgets)
|
|
{
|
|
if (widgets) {
|
|
widgets->count--;
|
|
if (widgets->count == 0)
|
|
g_slice_free (source_widgets, widgets);
|
|
}
|
|
}
|
|
|
|
static void
|
|
check_source_cb (SyncevoSession *session,
|
|
GError *error,
|
|
source_widgets *widgets)
|
|
{
|
|
gboolean show = TRUE;
|
|
|
|
if (error) {
|
|
if(error->code == DBUS_GERROR_REMOTE_EXCEPTION &&
|
|
dbus_g_error_has_name (error, SYNCEVO_DBUS_ERROR_SOURCE_UNUSABLE)) {
|
|
show = FALSE;
|
|
} else {
|
|
g_warning ("CheckSource failed: %s", error->message);
|
|
/* non-fatal, ignore in UI */
|
|
}
|
|
g_error_free (error);
|
|
}
|
|
|
|
if (widgets->count > 1) {
|
|
if (show) {
|
|
/* NOTE: with the new two sources per row layout not showing things
|
|
* may look weird in some cases... the layout should really only be
|
|
* done at this point */
|
|
gtk_widget_show (widgets->source_toggle_label);
|
|
gtk_widget_show (widgets->label);
|
|
gtk_widget_show (widgets->entry);
|
|
gtk_widget_show (widgets->check);
|
|
} else {
|
|
/* next save should disable this source */
|
|
toggle_set_active (widgets->check, FALSE);
|
|
}
|
|
}
|
|
source_widgets_unref (widgets);
|
|
g_object_unref (session);
|
|
}
|
|
|
|
static void
|
|
set_config_cb (SyncevoSession *session,
|
|
GError *error,
|
|
save_config_data *data)
|
|
{
|
|
if (error) {
|
|
g_warning ("Error in Session.SetConfig: %s", error->message);
|
|
g_error_free (error);
|
|
g_object_unref (session);
|
|
show_error_dialog (GTK_WIDGET (data->widget),
|
|
_("Sorry, failed to save the configuration"));
|
|
return;
|
|
}
|
|
|
|
if (data->temporary) {
|
|
syncevo_session_check_source (session,
|
|
data->widgets->name,
|
|
(SyncevoSessionGenericCb)check_source_cb,
|
|
data->widgets);
|
|
} else {
|
|
data->widget->configured = TRUE;
|
|
g_signal_emit (data->widget, signals[SIGNAL_CHANGED], 0);
|
|
g_object_unref (session);
|
|
}
|
|
|
|
}
|
|
|
|
static void
|
|
save_config (save_config_data *data,
|
|
SyncevoSession *session)
|
|
{
|
|
if (data->delete) {
|
|
syncevo_config_free (data->widget->config);
|
|
data->widget->config = g_hash_table_new (g_str_hash, g_str_equal);
|
|
}
|
|
|
|
syncevo_session_set_config (session,
|
|
data->temporary,
|
|
data->temporary,
|
|
data->widget->config,
|
|
(SyncevoSessionGenericCb)set_config_cb,
|
|
data);
|
|
}
|
|
|
|
static void
|
|
status_changed_for_config_write_cb (SyncevoSession *session,
|
|
SyncevoSessionStatus status,
|
|
guint error_code,
|
|
SyncevoSourceStatuses *source_statuses,
|
|
save_config_data *data)
|
|
{
|
|
if (status == SYNCEVO_STATUS_IDLE) {
|
|
save_config (data, session);
|
|
}
|
|
}
|
|
|
|
static void
|
|
get_status_for_config_write_cb (SyncevoSession *session,
|
|
SyncevoSessionStatus status,
|
|
guint error_code,
|
|
SyncevoSourceStatuses *source_statuses,
|
|
GError *error,
|
|
save_config_data *data)
|
|
{
|
|
if (error) {
|
|
g_warning ("Error in Session.GetStatus: %s", error->message);
|
|
g_error_free (error);
|
|
g_object_unref (session);
|
|
/* TODO show in UI: save failed in service list */
|
|
return;
|
|
}
|
|
|
|
syncevo_source_statuses_free (source_statuses);
|
|
|
|
if (status == SYNCEVO_STATUS_IDLE) {
|
|
save_config (data, session);
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
start_session_for_config_write_cb (SyncevoServer *server,
|
|
char *path,
|
|
GError *error,
|
|
save_config_data *data)
|
|
{
|
|
SyncevoSession *session;
|
|
|
|
if (error) {
|
|
g_warning ("Error in Server.StartSession: %s", error->message);
|
|
g_error_free (error);
|
|
/* TODO show in UI: save failed in service list */
|
|
return;
|
|
}
|
|
|
|
session = syncevo_session_new (path);
|
|
|
|
/* we want to know about status changes to our session */
|
|
g_signal_connect (session, "status-changed",
|
|
G_CALLBACK (status_changed_for_config_write_cb), data);
|
|
syncevo_session_get_status (session,
|
|
(SyncevoSessionGetStatusCb)get_status_for_config_write_cb,
|
|
data);
|
|
}
|
|
|
|
static void
|
|
stop_clicked_cb (GtkButton *btn, SyncConfigWidget *self)
|
|
{
|
|
save_config_data *data;
|
|
|
|
if (!self->config) {
|
|
return;
|
|
}
|
|
|
|
syncevo_config_set_value (self->config, NULL, "defaultPeer", "");
|
|
sync_config_widget_set_current (self, FALSE);
|
|
|
|
data = g_slice_new (save_config_data);
|
|
data->widget = self;
|
|
data->delete = FALSE;
|
|
data->temporary = FALSE;
|
|
syncevo_server_start_session (self->server,
|
|
self->config_name,
|
|
(SyncevoServerStartSessionCb)start_session_for_config_write_cb,
|
|
data);
|
|
}
|
|
|
|
static void
|
|
use_clicked_cb (GtkButton *btn, SyncConfigWidget *self)
|
|
{
|
|
save_config_data *data;
|
|
const char *username, *password, *sync_url, *pretty_name;
|
|
char *real_url, *device;
|
|
gboolean send, receive;
|
|
SyncevoSyncMode mode;
|
|
|
|
if (!self->config) {
|
|
return;
|
|
}
|
|
|
|
if (strlen (self->config_name) == 0) {
|
|
g_free (self->config_name);
|
|
self->config_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (self->entry)));
|
|
}
|
|
|
|
if (self->mode_changed) {
|
|
GHashTableIter iter;
|
|
source_widgets *widgets;
|
|
char *name;
|
|
|
|
send = toggle_get_active (self->send_check);
|
|
receive = toggle_get_active (self->receive_check);
|
|
|
|
if (send && receive) {
|
|
mode = SYNCEVO_SYNC_TWO_WAY;
|
|
} else if (send) {
|
|
mode = SYNCEVO_SYNC_ONE_WAY_FROM_CLIENT;
|
|
} else if (receive) {
|
|
mode = SYNCEVO_SYNC_ONE_WAY_FROM_SERVER;
|
|
} else {
|
|
mode = SYNCEVO_SYNC_NONE;
|
|
}
|
|
|
|
g_hash_table_iter_init (&iter, self->sources);
|
|
while (g_hash_table_iter_next (&iter, (gpointer)&name, (gpointer)&widgets)) {
|
|
const char *mode_str;
|
|
gboolean active;
|
|
|
|
active = toggle_get_active (widgets->check) &&
|
|
GTK_WIDGET_SENSITIVE (widgets->check);
|
|
if (active) {
|
|
mode_str = syncevo_sync_mode_to_string (mode);
|
|
} else {
|
|
mode_str = "none";
|
|
}
|
|
syncevo_config_set_value (self->config, name, "sync", mode_str);
|
|
}
|
|
}
|
|
|
|
username = gtk_entry_get_text (GTK_ENTRY (self->username_entry));
|
|
syncevo_config_set_value (self->config, NULL, "username", username);
|
|
|
|
sync_url = gtk_entry_get_text (GTK_ENTRY (self->baseurl_entry));
|
|
/* make a wild guess if no scheme in url */
|
|
if (strstr (sync_url, "://") == NULL) {
|
|
real_url = g_strdup_printf ("http://%s", sync_url);
|
|
} else {
|
|
real_url = g_strdup (sync_url);
|
|
}
|
|
syncevo_config_set_value (self->config, NULL, "syncURL", real_url);
|
|
|
|
password = gtk_entry_get_text (GTK_ENTRY (self->password_entry));
|
|
syncevo_config_set_value (self->config, NULL, "password", password);
|
|
|
|
syncevo_config_get_value (self->config, NULL, "deviceName", &device);
|
|
if (!device || strlen (device) == 0) {
|
|
if (!self->config_name || strlen (self->config_name) == 0 ||
|
|
!sync_url || strlen (sync_url) == 0) {
|
|
show_error_dialog (GTK_WIDGET (self),
|
|
_("Service must have a name and server URL"));
|
|
return;
|
|
}
|
|
}
|
|
|
|
syncevo_config_foreach_source (self->config,
|
|
(ConfigFunc)update_source_uri,
|
|
self);
|
|
|
|
pretty_name = gtk_entry_get_text (GTK_ENTRY (self->entry));
|
|
syncevo_config_set_value (self->config, NULL, "PeerName", pretty_name);
|
|
syncevo_config_get_value (self->config, NULL, "PeerName", &self->pretty_name);
|
|
syncevo_config_set_value (self->config, NULL, "defaultPeer", self->config_name);
|
|
sync_config_widget_set_current (self, TRUE);
|
|
|
|
data = g_slice_new (save_config_data);
|
|
data->widget = self;
|
|
data->delete = FALSE;
|
|
data->temporary = FALSE;
|
|
syncevo_server_start_session (self->server,
|
|
self->config_name,
|
|
(SyncevoServerStartSessionCb)start_session_for_config_write_cb,
|
|
data);
|
|
|
|
g_free (real_url);
|
|
}
|
|
|
|
static void
|
|
reset_delete_clicked_cb (GtkButton *btn, SyncConfigWidget *self)
|
|
{
|
|
char *msg, *yes, *no;
|
|
save_config_data *data;
|
|
|
|
if (!self->config) {
|
|
return;
|
|
}
|
|
|
|
if (self->has_template) {
|
|
/*TRANSLATORS: warning dialog text for resetting pre-defined
|
|
services */
|
|
msg = g_strdup_printf
|
|
(_("Do you want to reset the settings for %s? "
|
|
"This will not remove any synced information on either end."),
|
|
self->pretty_name);
|
|
/*TRANSLATORS: buttons in reset-service warning dialog */
|
|
yes = _("Yes, reset");
|
|
no = _("No, keep settings");
|
|
} else {
|
|
/*TRANSLATORS: warning dialog text for deleting user-defined
|
|
services */
|
|
msg = g_strdup_printf
|
|
(_("Do you want to delete the settings for %s? "
|
|
"This will not remove any synced information on either "
|
|
"end but it will remove these settings."),
|
|
self->pretty_name);
|
|
/*TRANSLATORS: buttons in delete-service warning dialog */
|
|
yes = _("Yes, delete");
|
|
no = _("No, keep settings");
|
|
}
|
|
|
|
/*TRANSLATORS: decline button in "Reset/delete service" warning dialogs */
|
|
if (!show_confirmation (GTK_WIDGET (self), msg, yes, no)) {
|
|
g_free (msg);
|
|
return;
|
|
}
|
|
g_free (msg);
|
|
|
|
if (self->current) {
|
|
sync_config_widget_set_current (self, FALSE);
|
|
}
|
|
|
|
data = g_slice_new (save_config_data);
|
|
data->widget = self;
|
|
data->delete = TRUE;
|
|
data->temporary = FALSE;
|
|
syncevo_server_start_session (self->server,
|
|
self->config_name,
|
|
(SyncevoServerStartSessionCb)start_session_for_config_write_cb,
|
|
data);
|
|
}
|
|
|
|
static void update_buttons (SyncConfigWidget *self)
|
|
{
|
|
if (self->has_template) {
|
|
/* TRANSLATORS: button labels in service configuration form */
|
|
gtk_button_set_label (GTK_BUTTON (self->reset_delete_button),
|
|
_("Reset settings"));
|
|
} else {
|
|
gtk_button_set_label (GTK_BUTTON (self->reset_delete_button),
|
|
_("Delete settings"));
|
|
}
|
|
if (self->configured) {
|
|
gtk_widget_show (GTK_WIDGET (self->reset_delete_button));
|
|
} else {
|
|
gtk_widget_hide (GTK_WIDGET (self->reset_delete_button));
|
|
}
|
|
|
|
if (self->current || !self->current_service_name) {
|
|
gtk_button_set_label (GTK_BUTTON (self->use_button),
|
|
_("Save and use"));
|
|
} else {
|
|
gtk_button_set_label (GTK_BUTTON (self->use_button),
|
|
_("Save and replace\ncurrent service"));
|
|
}
|
|
|
|
|
|
|
|
if (self->current && self->config) {
|
|
char *client;
|
|
syncevo_config_get_value (self->config, NULL, "PeerIsClient", &client);
|
|
if (client && g_strcmp0 (client, "1") == 0) {
|
|
gtk_button_set_label (GTK_BUTTON (self->stop_button),
|
|
_("Stop using device"));
|
|
} else {
|
|
gtk_button_set_label (GTK_BUTTON (self->stop_button),
|
|
_("Stop using service"));
|
|
}
|
|
gtk_widget_show (self->stop_button);
|
|
} else {
|
|
gtk_widget_hide (self->stop_button);
|
|
}
|
|
}
|
|
|
|
static void
|
|
mode_widget_notify_active_cb (GtkWidget *widget,
|
|
GParamSpec *pspec,
|
|
SyncConfigWidget *self)
|
|
{
|
|
self->mode_changed = TRUE;
|
|
}
|
|
|
|
static void
|
|
source_entry_notify_text_cb (GObject *gobject,
|
|
GParamSpec *pspec,
|
|
source_widgets *widgets)
|
|
{
|
|
gboolean new_editable, old_editable;
|
|
const char *text;
|
|
|
|
text = gtk_entry_get_text (GTK_ENTRY (widgets->entry));
|
|
new_editable = (strlen (text) > 0);
|
|
old_editable = GTK_WIDGET_SENSITIVE (widgets->check);
|
|
if (new_editable != old_editable) {
|
|
gtk_widget_set_sensitive (widgets->check, new_editable);
|
|
toggle_set_active (widgets->check, new_editable);
|
|
}
|
|
}
|
|
|
|
static GtkWidget*
|
|
add_toggle_widget (SyncConfigWidget *self,
|
|
const char *title,
|
|
gboolean active,
|
|
guint row, guint col)
|
|
{
|
|
GtkWidget *toggle;
|
|
int padding;
|
|
|
|
padding = (col == 1) ? 0 : 32;
|
|
|
|
#ifdef USE_MOBLIN_UX
|
|
GtkWidget *label;
|
|
|
|
col = col * 2;
|
|
label = gtk_label_new (title);
|
|
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
|
|
gtk_widget_set_size_request (label, 260, -1);
|
|
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
|
gtk_table_attach (GTK_TABLE (self->mode_table), label,
|
|
col, col + 1, row, row + 1,
|
|
GTK_FILL, GTK_FILL, 0, 0);
|
|
toggle = mx_gtk_light_switch_new ();
|
|
g_signal_connect_swapped (toggle, "hide",
|
|
G_CALLBACK (gtk_widget_hide), label);
|
|
g_signal_connect_swapped (toggle, "show",
|
|
G_CALLBACK (gtk_widget_show), label);
|
|
toggle_set_active (toggle, active);
|
|
g_signal_connect (toggle, "switch-flipped",
|
|
G_CALLBACK (mode_widget_notify_active_cb), self);
|
|
#else
|
|
toggle = gtk_check_button_new_with_label (title);
|
|
gtk_widget_set_size_request (toggle, 260, -1);
|
|
toggle_set_active (toggle, active);
|
|
g_signal_connect (toggle, "notify::active",
|
|
G_CALLBACK (mode_widget_notify_active_cb), self);
|
|
#endif
|
|
|
|
gtk_table_attach (GTK_TABLE (self->mode_table), toggle,
|
|
col + 1, col + 2, row, row + 1,
|
|
GTK_FILL, GTK_FILL, padding, 0);
|
|
|
|
return toggle;
|
|
}
|
|
|
|
|
|
/* check if config includes a virtual source that covers the given
|
|
* source */
|
|
static gboolean
|
|
virtual_source_exists (SyncevoConfig *config, const char *name)
|
|
{
|
|
GHashTableIter iter;
|
|
const char *source_string;
|
|
GHashTable *source_config;
|
|
|
|
g_hash_table_iter_init (&iter, config);
|
|
while (g_hash_table_iter_next (&iter,
|
|
(gpointer)&source_string,
|
|
(gpointer)&source_config)) {
|
|
char **strs;
|
|
|
|
if (g_str_has_prefix (source_string, "source/")) {
|
|
const char *uri, *type;
|
|
type = g_hash_table_lookup (source_config, "type");
|
|
uri = g_hash_table_lookup (source_config, "uri");
|
|
|
|
if (!uri || !type || !g_str_has_prefix (type, "virtual:")) {
|
|
/* this source is not defined, or not virtual */
|
|
continue;
|
|
}
|
|
|
|
strs = g_strsplit (source_string + 7, "+", 0);
|
|
if (g_strv_length (strs) > 1) {
|
|
int i;
|
|
|
|
for (i = 0; strs[i]; i++) {
|
|
if (g_strcmp0 (name, strs[i]) == 0) {
|
|
g_strfreev (strs);
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
g_strfreev (strs);
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static void
|
|
init_source (char *name,
|
|
GHashTable *source_configuration,
|
|
SyncConfigWidget *self)
|
|
{
|
|
char *str, *pretty_name;
|
|
const char *uri, *type;
|
|
guint rows;
|
|
guint row;
|
|
static guint col = 0;
|
|
source_widgets *widgets;
|
|
SyncevoSyncMode mode;
|
|
save_config_data *data;
|
|
|
|
type = g_hash_table_lookup (source_configuration, "type");
|
|
uri = g_hash_table_lookup (source_configuration, "uri");
|
|
if (!type || strlen (type) == 0) {
|
|
return;
|
|
}
|
|
|
|
if (g_str_has_prefix (type, "virtual:") && !uri) {
|
|
/* undefined virtual source */
|
|
return;
|
|
}
|
|
|
|
if (virtual_source_exists (self->config, name)) {
|
|
return;
|
|
}
|
|
|
|
g_object_get (self->mode_table,
|
|
"n-rows", &rows,
|
|
NULL);
|
|
|
|
if (!self->no_source_toggles && col == 0) {
|
|
col = 1;
|
|
row = rows - 1;
|
|
} else {
|
|
col = 0;
|
|
row = rows;
|
|
}
|
|
self->no_source_toggles = FALSE;
|
|
|
|
widgets = g_slice_new0 (source_widgets);
|
|
widgets->name = name;
|
|
widgets->count = 1;
|
|
g_hash_table_insert (self->sources, name, widgets);
|
|
|
|
widgets->source_toggle_label = self->source_toggle_label;
|
|
|
|
pretty_name = get_pretty_source_name (name);
|
|
mode = syncevo_sync_mode_from_string
|
|
(g_hash_table_lookup (source_configuration, "sync"));
|
|
|
|
widgets->check = add_toggle_widget (self,
|
|
pretty_name,
|
|
(mode > SYNCEVO_SYNC_NONE),
|
|
row, col);
|
|
|
|
/* TRANSLATORS: label for an entry in service configuration form.
|
|
* Placeholder is a source name.
|
|
* Example: "Appointments URI" */
|
|
str = g_strdup_printf (_("%s URI"), pretty_name);
|
|
widgets->label = gtk_label_new (str);
|
|
g_free (str);
|
|
g_free (pretty_name);
|
|
|
|
g_object_get (self->server_settings_table,
|
|
"n-rows", &row,
|
|
NULL);
|
|
|
|
gtk_misc_set_alignment (GTK_MISC (widgets->label), 0.0, 0.5);
|
|
gtk_table_attach (GTK_TABLE (self->server_settings_table), widgets->label,
|
|
0, 1, row, row + 1, GTK_FILL, GTK_EXPAND, 0, 0);
|
|
|
|
widgets->entry = gtk_entry_new ();
|
|
gtk_entry_set_max_length (GTK_ENTRY (widgets->entry), 99);
|
|
gtk_entry_set_width_chars (GTK_ENTRY (widgets->entry), 80);
|
|
if (uri) {
|
|
gtk_entry_set_text (GTK_ENTRY (widgets->entry), uri);
|
|
}
|
|
gtk_table_attach_defaults (GTK_TABLE (self->server_settings_table),
|
|
widgets->entry,
|
|
1, 2, row, row + 1);
|
|
g_signal_connect (widgets->entry, "notify::text",
|
|
G_CALLBACK (source_entry_notify_text_cb), widgets);
|
|
|
|
gtk_widget_set_sensitive (widgets->check,
|
|
uri && strlen (uri) > 0);
|
|
|
|
/* start a session so we save a temporary config so we can do
|
|
* CheckSource, and show the source-related widgets if the
|
|
* source is available */
|
|
data = g_slice_new (save_config_data);
|
|
data->widget = self;
|
|
data->delete = FALSE;
|
|
data->temporary = TRUE;
|
|
data->widgets = source_widgets_ref (widgets);
|
|
syncevo_server_start_session (self->server,
|
|
self->config_name,
|
|
(SyncevoServerStartSessionCb)start_session_for_config_write_cb,
|
|
data);
|
|
}
|
|
|
|
static void
|
|
get_common_mode (char *name,
|
|
GHashTable *source_configuration,
|
|
SyncevoSyncMode *common_mode)
|
|
{
|
|
SyncevoSyncMode mode;
|
|
char *mode_str, *type;
|
|
|
|
type = g_hash_table_lookup (source_configuration, "type");
|
|
if (!type || strlen (type) == 0) {
|
|
return;
|
|
}
|
|
|
|
mode_str = g_hash_table_lookup (source_configuration, "sync");
|
|
mode = syncevo_sync_mode_from_string (mode_str);
|
|
|
|
if (mode == SYNCEVO_SYNC_NONE) {
|
|
return;
|
|
}
|
|
|
|
if (*common_mode == SYNCEVO_SYNC_NONE) {
|
|
*common_mode = mode;
|
|
} else if (mode != *common_mode) {
|
|
*common_mode = SYNCEVO_SYNC_UNKNOWN;
|
|
}
|
|
}
|
|
|
|
void
|
|
sync_config_widget_expand_id (SyncConfigWidget *self,
|
|
const char *id)
|
|
{
|
|
if (id && self->config) {
|
|
char *sync_url;
|
|
|
|
if (syncevo_config_get_value (self->config, NULL,
|
|
"syncURL", &sync_url) &&
|
|
strncmp (sync_url, id, strlen (id)) == 0) {
|
|
|
|
sync_config_widget_set_expanded (self, TRUE);
|
|
} else if (self->config_name &&
|
|
g_strcasecmp (self->config_name, id) == 0) {
|
|
|
|
sync_config_widget_set_expanded (self, TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
sync_config_widget_update_expander (SyncConfigWidget *self)
|
|
{
|
|
char *username = "";
|
|
char *password = "";
|
|
char *sync_url = "";
|
|
const char *descr;
|
|
char *str, *device;
|
|
GtkWidget *label, *align;
|
|
SyncevoSyncMode mode = SYNCEVO_SYNC_NONE;
|
|
gboolean send, receive;
|
|
|
|
gtk_container_foreach (GTK_CONTAINER (self->server_settings_table),
|
|
(GtkCallback)remove_child,
|
|
self->server_settings_table);
|
|
gtk_table_resize (GTK_TABLE (self->server_settings_table),
|
|
2, 1);
|
|
gtk_container_foreach (GTK_CONTAINER (self->mode_table),
|
|
(GtkCallback)remove_child,
|
|
self->mode_table);
|
|
gtk_table_resize (GTK_TABLE (self->mode_table),
|
|
2, 1);
|
|
|
|
syncevo_config_get_value (self->config, NULL, "PeerIsClient", &device);
|
|
if (device && g_strcmp0 (device, "1") == 0) {
|
|
if (!self->device_template_selected) {
|
|
gtk_widget_hide (self->settings_box);
|
|
gtk_widget_show (self->device_selector_box);
|
|
/* temporary solution for device template selection:
|
|
* show list of templates only */
|
|
} else {
|
|
gtk_widget_show (self->settings_box);
|
|
gtk_widget_hide (self->device_selector_box);
|
|
gtk_widget_hide (self->userinfo_table);
|
|
gtk_widget_hide (self->fake_expander);
|
|
}
|
|
} else {
|
|
gtk_widget_show (self->settings_box);
|
|
gtk_widget_hide (self->device_selector_box);
|
|
gtk_widget_show (self->userinfo_table);
|
|
gtk_widget_show (self->fake_expander);
|
|
}
|
|
|
|
syncevo_config_foreach_source (self->config,
|
|
(ConfigFunc)get_common_mode,
|
|
&mode);
|
|
switch (mode) {
|
|
case SYNCEVO_SYNC_TWO_WAY:
|
|
send = receive = TRUE;
|
|
break;
|
|
case SYNCEVO_SYNC_ONE_WAY_FROM_CLIENT:
|
|
send = TRUE;
|
|
receive = FALSE;
|
|
break;
|
|
case SYNCEVO_SYNC_ONE_WAY_FROM_SERVER:
|
|
send = FALSE;
|
|
receive = TRUE;
|
|
break;
|
|
default:
|
|
gtk_widget_show (self->complex_config_info_bar);
|
|
send = FALSE;
|
|
receive = FALSE;
|
|
}
|
|
self->mode_changed = FALSE;
|
|
|
|
|
|
if (self->pretty_name) {
|
|
gtk_entry_set_text (GTK_ENTRY (self->entry), self->pretty_name);
|
|
}
|
|
if (!self->config_name || strlen (self->config_name) == 0) {
|
|
gtk_expander_set_expanded (GTK_EXPANDER (self->expander), TRUE);
|
|
}
|
|
|
|
descr = get_service_description (self->config_name);
|
|
if (descr) {
|
|
gtk_label_set_text (GTK_LABEL (self->description_label),
|
|
get_service_description (self->config_name));
|
|
gtk_widget_show (self->description_label);
|
|
} else {
|
|
gtk_widget_hide (self->description_label);
|
|
}
|
|
|
|
update_buttons (self);
|
|
|
|
/* TRANSLATORS: toggles in service configuration form, placeholder is service
|
|
* or device name */
|
|
str = g_strdup_printf (_("Send changes to %s"), self->pretty_name);
|
|
self->send_check = add_toggle_widget (self, str, send, 0, 0);
|
|
gtk_widget_show (self->send_check);
|
|
g_free (str);
|
|
|
|
str = g_strdup_printf (_("Receive changes from %s"), self->pretty_name);
|
|
self->receive_check = add_toggle_widget (self, str, receive, 0, 1);
|
|
gtk_widget_show (self->receive_check);
|
|
g_free (str);
|
|
|
|
align = gtk_alignment_new (0.0, 1.0, 0.0, 0.0);
|
|
gtk_alignment_set_padding (GTK_ALIGNMENT (align), 10, 0, 0, 0);
|
|
gtk_widget_show (align);
|
|
gtk_table_attach (GTK_TABLE (self->mode_table), align,
|
|
0, 1, 1, 2,
|
|
GTK_FILL, GTK_FILL, 0, 0);
|
|
|
|
self->source_toggle_label = gtk_label_new ("");
|
|
/* TRANSLATORS: Label for the source toggles in configuration form.
|
|
This is a verb, as in "Sync Calendar". */
|
|
gtk_label_set_markup (GTK_LABEL (self->source_toggle_label),
|
|
_("<b>Sync</b>"));
|
|
gtk_widget_show (self->source_toggle_label);
|
|
gtk_container_add (GTK_CONTAINER (align), self->source_toggle_label);
|
|
|
|
syncevo_config_get_value (self->config, NULL, "username", &username);
|
|
syncevo_config_get_value (self->config, NULL, "password", &password);
|
|
syncevo_config_get_value (self->config, NULL, "syncURL", &sync_url);
|
|
|
|
if (username) {
|
|
gtk_entry_set_text (GTK_ENTRY (self->username_entry), username);
|
|
}
|
|
if (password) {
|
|
gtk_entry_set_text (GTK_ENTRY (self->password_entry), password);
|
|
}
|
|
|
|
// TRANSLATORS: label of a entry in service configuration
|
|
label = gtk_label_new (_("Server address"));
|
|
gtk_misc_set_alignment (GTK_MISC (label), 9.0, 0.5);
|
|
gtk_widget_show (label);
|
|
gtk_table_attach (GTK_TABLE (self->server_settings_table), label,
|
|
0, 1, 0, 1, GTK_FILL, GTK_EXPAND, 0, 0);
|
|
|
|
self->baseurl_entry = gtk_entry_new ();
|
|
gtk_entry_set_max_length (GTK_ENTRY (self->baseurl_entry), 99);
|
|
gtk_entry_set_width_chars (GTK_ENTRY (self->baseurl_entry), 80);
|
|
if (sync_url) {
|
|
gtk_entry_set_text (GTK_ENTRY (self->baseurl_entry), sync_url);
|
|
}
|
|
gtk_widget_show (self->baseurl_entry);
|
|
|
|
gtk_table_attach_defaults (GTK_TABLE (self->server_settings_table),
|
|
self->baseurl_entry,
|
|
1, 2, 0, 1);
|
|
|
|
/* update source widgets */
|
|
if (self->sources) {
|
|
g_hash_table_destroy (self->sources);
|
|
}
|
|
self->sources = g_hash_table_new_full (g_str_hash,
|
|
g_str_equal,
|
|
NULL,
|
|
(GDestroyNotify)source_widgets_unref);
|
|
self->no_source_toggles = TRUE;
|
|
syncevo_config_foreach_source (self->config,
|
|
(ConfigFunc)init_source,
|
|
self);
|
|
}
|
|
|
|
/* only adds config to hashtable and combo */
|
|
static void
|
|
sync_config_widget_add_config (SyncConfigWidget *self,
|
|
const char *name,
|
|
SyncevoConfig *config)
|
|
{
|
|
GtkListStore *store;
|
|
GtkTreeIter iter;
|
|
const char *guess_name;
|
|
SyncevoConfig *guess_config;
|
|
int score = 1;
|
|
int guess_score, second_guess_score = -1;
|
|
char *str;
|
|
|
|
store = GTK_LIST_STORE (gtk_combo_box_get_model (GTK_COMBO_BOX (self->combo)));
|
|
if (syncevo_config_get_value (config, NULL, "score", &str)) {
|
|
score = (int)strtol (str, NULL, 10);
|
|
}
|
|
gtk_list_store_append (store, &iter);
|
|
gtk_list_store_set (store, &iter,
|
|
0, name,
|
|
1, config,
|
|
2, score,
|
|
-1);
|
|
|
|
/* make an educated guess if possible */
|
|
gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
|
|
gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
|
|
0, &guess_name,
|
|
1, &guess_config,
|
|
2, &guess_score,
|
|
-1);
|
|
|
|
if (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter)) {
|
|
gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
|
|
2, &second_guess_score,
|
|
-1);
|
|
}
|
|
|
|
if (guess_score > 1 && guess_score > second_guess_score) {
|
|
gtk_combo_box_set_active (GTK_COMBO_BOX (self->combo), 0);
|
|
/* TRANSLATORS: explanation before a device template combobox.
|
|
* Placeholder is a device name like 'Nokia N85' or 'Syncevolution
|
|
* Client' */
|
|
str = g_strdup_printf (_("This device looks like it might be a '%s'. "
|
|
"If this is not correct, please take a look at "
|
|
"the list of supported devices and pick yours "
|
|
"if it is listed"), guess_name);
|
|
} else {
|
|
gtk_combo_box_set_active (GTK_COMBO_BOX (self->combo), -1);
|
|
str = g_strdup (_("We don't know what this device is exactly. "
|
|
"Please take a look at the list of "
|
|
"supported devices and pick yours if it "
|
|
"is listed"));
|
|
}
|
|
gtk_label_set_text (GTK_LABEL (self->device_text), str);
|
|
g_free (str);
|
|
}
|
|
|
|
static void
|
|
sync_config_widget_update_pretty_name (SyncConfigWidget *self)
|
|
{
|
|
self->pretty_name = NULL;
|
|
|
|
if (self->config) {
|
|
syncevo_config_get_value (self->config, NULL,
|
|
"PeerName", &self->pretty_name);
|
|
if (!self->pretty_name) {
|
|
syncevo_config_get_value (self->config, NULL,
|
|
"deviceName", &self->pretty_name);
|
|
}
|
|
}
|
|
|
|
if (!self->pretty_name) {
|
|
self->pretty_name = self->config_name;
|
|
}
|
|
}
|
|
|
|
static void
|
|
sync_config_widget_set_config (SyncConfigWidget *self,
|
|
SyncevoConfig *config)
|
|
{
|
|
self->config = config;
|
|
sync_config_widget_update_pretty_name (self);
|
|
}
|
|
|
|
|
|
static void
|
|
setup_service_clicked (GtkButton *btn, SyncConfigWidget *self)
|
|
{
|
|
sync_config_widget_set_expanded (self, TRUE);
|
|
}
|
|
|
|
static void
|
|
sync_config_widget_set_name (SyncConfigWidget *self,
|
|
const char *name)
|
|
{
|
|
g_free (self->config_name);
|
|
self->config_name = g_strdup (name);
|
|
sync_config_widget_update_pretty_name (self);
|
|
}
|
|
|
|
|
|
static void
|
|
device_selection_btn_clicked_cb (GtkButton *btn, SyncConfigWidget *self)
|
|
{
|
|
GtkTreeIter iter;
|
|
|
|
if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (self->combo), &iter)) {
|
|
const char *name;
|
|
SyncevoConfig *config;
|
|
GtkTreeModel *model;
|
|
|
|
self->device_template_selected = TRUE;
|
|
|
|
model = gtk_combo_box_get_model(GTK_COMBO_BOX (self->combo));
|
|
gtk_tree_model_get (model, &iter, 0, &name, -1 );
|
|
gtk_tree_model_get (model, &iter, 1, &config, -1 );
|
|
|
|
sync_config_widget_set_config (self, config);
|
|
sync_config_widget_set_name (self, name);
|
|
|
|
sync_config_widget_update_expander (self);
|
|
}
|
|
}
|
|
|
|
static void
|
|
server_settings_notify_expand_cb (GtkExpander *expander,
|
|
GParamSpec *pspec,
|
|
SyncConfigWidget *self)
|
|
{
|
|
/* NOTE: expander can be the fake or real one... */
|
|
if (gtk_expander_get_expanded (GTK_EXPANDER (self->fake_expander))) {
|
|
g_signal_handlers_disconnect_by_func (self->fake_expander,
|
|
server_settings_notify_expand_cb,
|
|
self);
|
|
|
|
gtk_widget_hide (self->fake_expander);
|
|
gtk_expander_set_expanded (GTK_EXPANDER (self->fake_expander), FALSE);
|
|
gtk_expander_set_expanded (GTK_EXPANDER (self->expander), TRUE);
|
|
gtk_widget_show (self->expander);
|
|
|
|
g_signal_connect (self->expander, "notify::expanded",
|
|
G_CALLBACK (server_settings_notify_expand_cb), self);
|
|
} else {
|
|
g_signal_handlers_disconnect_by_func (self->expander,
|
|
server_settings_notify_expand_cb,
|
|
self);
|
|
|
|
gtk_widget_hide (self->expander);
|
|
gtk_widget_show (self->fake_expander);
|
|
|
|
g_signal_connect (self->fake_expander, "notify::expanded",
|
|
G_CALLBACK (server_settings_notify_expand_cb), self);
|
|
}
|
|
}
|
|
|
|
static GdkPixbuf*
|
|
load_icon (const char *uri, guint icon_size)
|
|
{
|
|
GError *error = NULL;
|
|
GdkPixbuf *pixbuf;
|
|
const char *filename;
|
|
|
|
if (uri && strlen (uri) > 0) {
|
|
if (g_str_has_prefix (uri, "file://")) {
|
|
filename = uri+7;
|
|
} else {
|
|
g_warning ("only file:// icon uri is supported: %s", uri);
|
|
filename = THEMEDIR "sync-generic.png";
|
|
}
|
|
} else {
|
|
filename = THEMEDIR "sync-generic.png";
|
|
}
|
|
pixbuf = gdk_pixbuf_new_from_file_at_scale (filename,
|
|
icon_size, icon_size,
|
|
TRUE, &error);
|
|
|
|
if (!pixbuf) {
|
|
g_warning ("Failed to load service icon: %s", error->message);
|
|
g_error_free (error);
|
|
return NULL;
|
|
}
|
|
|
|
return pixbuf;
|
|
}
|
|
|
|
static void
|
|
sync_config_widget_update_label (SyncConfigWidget *self)
|
|
{
|
|
if (self->config && self->pretty_name) {
|
|
char *url, *sync_url;
|
|
char *str;
|
|
|
|
syncevo_config_get_value (self->config, NULL, "WebURL", &url);
|
|
syncevo_config_get_value (self->config, NULL, "syncURL", &sync_url);
|
|
|
|
if (self->current) {
|
|
str = g_strdup_printf ("<b>%s</b>", self->pretty_name);
|
|
} else {
|
|
str = g_strdup_printf ("%s", self->pretty_name);
|
|
}
|
|
if (g_str_has_prefix (sync_url, "obex-bt://")) {
|
|
char *tmp = g_strdup_printf (_("%s - Bluetooth device"), str);
|
|
g_free (str);
|
|
str = tmp;
|
|
} else if (!self->has_template) {
|
|
/* TRANSLATORS: service title for services that are not based on a
|
|
* template in service list, the placeholder is the name of the service */
|
|
char *tmp = g_strdup_printf (_("%s - manually setup"), str);
|
|
g_free (str);
|
|
str = tmp;
|
|
} else if (url && strlen (url) > 0) {
|
|
char *tmp = g_strdup_printf ("%s -",str);
|
|
g_free (str);
|
|
str = tmp;
|
|
}
|
|
|
|
gtk_label_set_markup (GTK_LABEL (self->label), str);
|
|
g_free (str);
|
|
}
|
|
}
|
|
|
|
void
|
|
sync_config_widget_set_current_service_name (SyncConfigWidget *self,
|
|
const char *name)
|
|
{
|
|
g_free (self->current_service_name);
|
|
self->current_service_name = g_strdup (name);
|
|
|
|
update_buttons (self);
|
|
}
|
|
|
|
void
|
|
sync_config_widget_set_current (SyncConfigWidget *self,
|
|
gboolean current)
|
|
{
|
|
if (self->current != current) {
|
|
self->current = current;
|
|
sync_config_widget_update_label (self);
|
|
}
|
|
}
|
|
|
|
static void
|
|
set_session (SyncConfigWidget *self, const char *path)
|
|
{
|
|
g_free (self->running_session);
|
|
self->running_session = g_strdup (path);
|
|
|
|
gtk_widget_set_sensitive (GTK_WIDGET (self->reset_delete_button),
|
|
!self->running_session);
|
|
gtk_widget_set_sensitive (GTK_WIDGET (self->use_button),
|
|
!self->running_session);
|
|
|
|
/* TODO: maybe add a explanation text somewhere:
|
|
* "Configuration changes are not possible while a sync is in progress" */
|
|
}
|
|
|
|
static void
|
|
session_changed_cb (SyncevoServer *server,
|
|
char *path,
|
|
gboolean started,
|
|
SyncConfigWidget *self)
|
|
{
|
|
if (started) {
|
|
set_session (self, path);
|
|
} else if (g_strcmp0 (self->running_session, path) == 0 ) {
|
|
set_session (self, NULL);
|
|
}
|
|
}
|
|
|
|
static void
|
|
get_sessions_cb (SyncevoServer *server,
|
|
SyncevoSessions *sessions,
|
|
GError *error,
|
|
SyncConfigWidget *self)
|
|
{
|
|
if (error) {
|
|
g_warning ("Server.GetSessions failed: %s", error->message);
|
|
g_error_free (error);
|
|
/* non-fatal, ignore in UI */
|
|
|
|
g_object_unref (self);
|
|
return;
|
|
}
|
|
|
|
set_session (self, syncevo_sessions_index (sessions, 0));
|
|
syncevo_sessions_free (sessions);
|
|
g_object_unref (self);
|
|
}
|
|
|
|
void
|
|
sync_config_widget_set_server (SyncConfigWidget *self,
|
|
SyncevoServer *server)
|
|
{
|
|
if (self->server) {
|
|
g_signal_handlers_disconnect_by_func (self->server,
|
|
session_changed_cb,
|
|
self);
|
|
g_object_unref (self->server);
|
|
self->server = NULL;
|
|
}
|
|
if (!server && !self->server) {
|
|
return;
|
|
}
|
|
|
|
self->server = g_object_ref (server);
|
|
|
|
/* monitor sessions so we can set editing buttons insensitive */
|
|
g_signal_connect (self->server, "session-changed",
|
|
G_CALLBACK (session_changed_cb), self);
|
|
|
|
/* reference is released in callback */
|
|
g_object_ref (self);
|
|
syncevo_server_get_sessions (self->server,
|
|
(SyncevoServerGetSessionsCb)get_sessions_cb,
|
|
self);
|
|
}
|
|
|
|
static void
|
|
sync_config_widget_set_property (GObject *object,
|
|
guint property_id,
|
|
const GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
SyncConfigWidget *self = SYNC_CONFIG_WIDGET (object);
|
|
|
|
switch (property_id) {
|
|
case PROP_SERVER:
|
|
sync_config_widget_set_server (self, g_value_get_pointer (value));
|
|
break;
|
|
case PROP_NAME:
|
|
sync_config_widget_set_name (self, g_value_get_string (value));
|
|
break;
|
|
case PROP_CONFIG:
|
|
sync_config_widget_set_config (self, g_value_get_pointer (value));
|
|
break;
|
|
case PROP_CURRENT:
|
|
sync_config_widget_set_current (self, g_value_get_boolean (value));
|
|
break;
|
|
case PROP_HAS_TEMPLATE:
|
|
sync_config_widget_set_has_template (self, g_value_get_boolean (value));
|
|
break;
|
|
case PROP_CONFIGURED:
|
|
sync_config_widget_set_configured (self, g_value_get_boolean (value));
|
|
break;
|
|
case PROP_CURRENT_SERVICE_NAME:
|
|
sync_config_widget_set_current_service_name (self, g_value_get_string (value));
|
|
break;
|
|
case PROP_EXPANDED:
|
|
sync_config_widget_set_expanded (self, g_value_get_boolean (value));
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
}
|
|
}
|
|
|
|
static void
|
|
sync_config_widget_get_property (GObject *object,
|
|
guint property_id,
|
|
GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
SyncConfigWidget *self = SYNC_CONFIG_WIDGET (object);
|
|
|
|
switch (property_id) {
|
|
case PROP_SERVER:
|
|
g_value_set_pointer (value, self->server);
|
|
case PROP_NAME:
|
|
g_value_set_string (value, self->config_name);
|
|
case PROP_CONFIG:
|
|
g_value_set_pointer (value, self->config);
|
|
case PROP_CURRENT:
|
|
g_value_set_boolean (value, self->current);
|
|
case PROP_HAS_TEMPLATE:
|
|
g_value_set_boolean (value, self->has_template);
|
|
case PROP_CONFIGURED:
|
|
g_value_set_boolean (value, self->configured);
|
|
case PROP_CURRENT_SERVICE_NAME:
|
|
g_value_set_string (value, self->current_service_name);
|
|
case PROP_EXPANDED:
|
|
g_value_set_boolean (value, self->expanded);
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
}
|
|
}
|
|
|
|
static void
|
|
sync_config_widget_dispose (GObject *object)
|
|
{
|
|
SyncConfigWidget *self = SYNC_CONFIG_WIDGET (object);
|
|
|
|
sync_config_widget_set_server (self, NULL);
|
|
if (self->config) {
|
|
syncevo_config_free (self->config);
|
|
}
|
|
self->config = NULL;
|
|
|
|
g_free (self->config_name);
|
|
self->config_name = NULL;
|
|
g_free (self->current_service_name);
|
|
self->current_service_name = NULL;
|
|
g_free (self->running_session);
|
|
self->running_session = NULL;
|
|
if (self->sources) {
|
|
g_hash_table_destroy (self->sources);
|
|
self->sources = NULL;
|
|
}
|
|
|
|
|
|
|
|
G_OBJECT_CLASS (sync_config_widget_parent_class)->dispose (object);
|
|
}
|
|
|
|
static void
|
|
init_default_config (SyncConfigWidget *self)
|
|
{
|
|
sync_config_widget_set_name (self, "");
|
|
self->has_template = FALSE;
|
|
|
|
syncevo_config_set_value (self->config, NULL, "username", "");
|
|
syncevo_config_set_value (self->config, NULL, "password", "");
|
|
syncevo_config_set_value (self->config, NULL, "syncURL", "");
|
|
syncevo_config_set_value (self->config, NULL, "WebURL", "");
|
|
syncevo_config_set_value (self->config, "memo", "uri", "");
|
|
syncevo_config_set_value (self->config, "todo", "uri", "");
|
|
syncevo_config_set_value (self->config, "addressbook", "uri", "");
|
|
syncevo_config_set_value (self->config, "calendar", "uri", "");
|
|
|
|
}
|
|
|
|
static gboolean
|
|
label_button_expose_cb (GtkWidget *widget,
|
|
GdkEventExpose *event,
|
|
SyncConfigWidget *self)
|
|
{
|
|
GtkExpanderStyle style;
|
|
gint indicator_x, indicator_y;
|
|
|
|
indicator_x = widget->style->xthickness + INDICATOR_SIZE / 2;
|
|
indicator_y = widget->style->ythickness +
|
|
widget->allocation.height / 2;
|
|
|
|
if (self->expanded) {
|
|
style = GTK_EXPANDER_EXPANDED;
|
|
} else {
|
|
style = GTK_EXPANDER_COLLAPSED;
|
|
}
|
|
|
|
gtk_paint_expander (widget->style,
|
|
widget->window,
|
|
widget->state,
|
|
NULL,
|
|
GTK_WIDGET (self),
|
|
NULL,
|
|
indicator_x,
|
|
indicator_y,
|
|
style);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static gboolean
|
|
sync_config_widget_expose_event (GtkWidget *widget,
|
|
GdkEventExpose *event)
|
|
{
|
|
GdkRectangle rect;
|
|
SyncConfigWidget *self = SYNC_CONFIG_WIDGET (widget);
|
|
|
|
rect.x = widget->allocation.x;
|
|
rect.y = widget->allocation.y;
|
|
rect.height = widget->allocation.height;
|
|
rect.width = widget->allocation.width;
|
|
|
|
gtk_paint_box (widget->style,
|
|
widget->window,
|
|
widget->state,
|
|
GTK_SHADOW_OUT,
|
|
&rect,
|
|
widget,
|
|
NULL,
|
|
rect.x,
|
|
rect.y,
|
|
rect.width,
|
|
rect.height);
|
|
|
|
gtk_container_propagate_expose (GTK_CONTAINER (self),
|
|
self->label_box, event);
|
|
gtk_container_propagate_expose (GTK_CONTAINER (self),
|
|
self->expando_box, event);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
static void
|
|
sync_config_widget_size_allocate (GtkWidget *widget,
|
|
GtkAllocation *allocation)
|
|
{
|
|
GtkRequisition req;
|
|
GtkAllocation alloc;
|
|
SyncConfigWidget *self = SYNC_CONFIG_WIDGET (widget);
|
|
|
|
GTK_WIDGET_CLASS (sync_config_widget_parent_class)->size_allocate (widget,
|
|
allocation);
|
|
|
|
gtk_widget_size_request (self->label_box, &req);
|
|
|
|
alloc.x = allocation->x + widget->style->xthickness;
|
|
alloc.y = allocation->y + widget->style->ythickness;
|
|
alloc.width = allocation->width - 2 * widget->style->xthickness;
|
|
alloc.height = req.height;
|
|
|
|
gtk_widget_size_allocate (self->label_box, &alloc);
|
|
|
|
|
|
if (self->expanded) {
|
|
gtk_widget_size_request (self->expando_box, &req);
|
|
|
|
alloc.x = allocation->x + 2 * widget->style->xthickness;
|
|
alloc.y = allocation->y + widget->style->ythickness +
|
|
alloc.height + CHILD_PADDING;
|
|
alloc.width = allocation->width - 4 * widget->style->xthickness;
|
|
alloc.height = req.height;
|
|
|
|
gtk_widget_size_allocate (self->expando_box, &alloc);
|
|
}
|
|
}
|
|
|
|
static void
|
|
sync_config_widget_size_request (GtkWidget *widget,
|
|
GtkRequisition *requisition)
|
|
{
|
|
SyncConfigWidget *self = SYNC_CONFIG_WIDGET (widget);
|
|
GtkRequisition req;
|
|
|
|
requisition->width = widget->style->xthickness * 2;
|
|
requisition->height = widget->style->ythickness * 2;
|
|
|
|
gtk_widget_size_request (self->label_box, &req);
|
|
|
|
requisition->width += req.width;
|
|
requisition->height = MAX (req.height, INDICATOR_SIZE) +
|
|
widget->style->ythickness * 2;
|
|
|
|
if (self->expanded) {
|
|
|
|
gtk_widget_size_request (self->expando_box, &req);
|
|
requisition->width = MAX (requisition->width,
|
|
req.width + widget->style->xthickness * 4);
|
|
requisition->height += req.height + 2 * widget->style->ythickness;
|
|
}
|
|
}
|
|
|
|
static GObject *
|
|
sync_config_widget_constructor (GType gtype,
|
|
guint n_properties,
|
|
GObjectConstructParam *properties)
|
|
{
|
|
SyncConfigWidget *self;
|
|
GObjectClass *parent_class;
|
|
char *url, *icon;
|
|
GdkPixbuf *buf;
|
|
|
|
parent_class = G_OBJECT_CLASS (sync_config_widget_parent_class);
|
|
self = SYNC_CONFIG_WIDGET (parent_class->constructor (gtype,
|
|
n_properties,
|
|
properties));
|
|
|
|
if (!self->config || !self->server) {
|
|
g_warning ("No SyncevoServer or Syncevoconfig set for SyncConfigWidget");
|
|
return G_OBJECT (self);
|
|
}
|
|
|
|
sync_config_widget_add_config (self, self->config_name, self->config);
|
|
|
|
if (g_strcmp0 (self->config_name, "default") == 0) {
|
|
|
|
init_default_config (self);
|
|
gtk_widget_show (self->entry);
|
|
gtk_widget_hide (self->label);
|
|
} else {
|
|
gtk_widget_hide (self->entry);
|
|
gtk_widget_show (self->label);
|
|
}
|
|
|
|
syncevo_config_get_value (self->config, NULL, "WebURL", &url);
|
|
syncevo_config_get_value (self->config, NULL, "IconURI", &icon);
|
|
|
|
buf = load_icon (icon, SYNC_UI_LIST_ICON_SIZE);
|
|
gtk_image_set_from_pixbuf (GTK_IMAGE (self->image), buf);
|
|
g_object_unref (buf);
|
|
|
|
if (url && strlen (url) > 0) {
|
|
gtk_link_button_set_uri (GTK_LINK_BUTTON (self->link), url);
|
|
gtk_widget_show (self->link);
|
|
} else {
|
|
gtk_widget_hide (self->link);
|
|
}
|
|
|
|
sync_config_widget_update_label (self);
|
|
sync_config_widget_update_expander (self);
|
|
|
|
/* hack to get focus in the right place on "Setup new service" */
|
|
if (GTK_WIDGET_VISIBLE (self->entry)) {
|
|
gtk_widget_grab_focus (self->entry);
|
|
}
|
|
|
|
return G_OBJECT (self);
|
|
}
|
|
|
|
static void
|
|
sync_config_widget_map (GtkWidget *widget)
|
|
{
|
|
SyncConfigWidget *self = SYNC_CONFIG_WIDGET (widget);
|
|
|
|
if (self->label_box && GTK_WIDGET_VISIBLE (self->expando_box)) {
|
|
gtk_widget_map (self->label_box);
|
|
}
|
|
if (self->expando_box && GTK_WIDGET_VISIBLE (self->expando_box)) {
|
|
gtk_widget_map (self->expando_box);
|
|
}
|
|
GTK_WIDGET_CLASS (sync_config_widget_parent_class)->map (widget);
|
|
}
|
|
|
|
static void
|
|
sync_config_widget_unmap (GtkWidget *widget)
|
|
{
|
|
SyncConfigWidget *self = SYNC_CONFIG_WIDGET (widget);
|
|
|
|
GTK_WIDGET_CLASS (sync_config_widget_parent_class)->unmap (widget);
|
|
|
|
if (self->label_box) {
|
|
gtk_widget_unmap (self->label_box);
|
|
}
|
|
if (self->expando_box) {
|
|
gtk_widget_unmap (self->expando_box);
|
|
}
|
|
}
|
|
|
|
static void
|
|
sync_config_widget_add (GtkContainer *container,
|
|
GtkWidget *widget)
|
|
{
|
|
g_warning ("Can't add widgets in to SyncConfigWidget!");
|
|
}
|
|
|
|
static void
|
|
sync_config_widget_remove (GtkContainer *container,
|
|
GtkWidget *widget)
|
|
{
|
|
SyncConfigWidget *self = SYNC_CONFIG_WIDGET (container);
|
|
|
|
|
|
if (self->label_box == widget) {
|
|
gtk_widget_unparent (widget);
|
|
self->label_box = NULL;
|
|
}
|
|
if (self->expando_box == widget) {
|
|
gtk_widget_unparent (widget);
|
|
self->expando_box = NULL;
|
|
}
|
|
}
|
|
|
|
static void
|
|
sync_config_widget_forall (GtkContainer *container,
|
|
gboolean include_internals,
|
|
GtkCallback callback,
|
|
gpointer callback_data)
|
|
{
|
|
SyncConfigWidget *self = SYNC_CONFIG_WIDGET (container);
|
|
|
|
if (self->label_box) {
|
|
(* callback) (self->label_box, callback_data);
|
|
}
|
|
if (self->expando_box) {
|
|
(* callback) (self->expando_box, callback_data);
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
sync_config_widget_class_init (SyncConfigWidgetClass *klass)
|
|
{
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
GtkWidgetClass *w_class = GTK_WIDGET_CLASS (klass);
|
|
GtkContainerClass *c_class = GTK_CONTAINER_CLASS (klass);
|
|
GParamSpec *pspec;
|
|
|
|
object_class->set_property = sync_config_widget_set_property;
|
|
object_class->get_property = sync_config_widget_get_property;
|
|
object_class->dispose = sync_config_widget_dispose;
|
|
object_class->constructor = sync_config_widget_constructor;
|
|
|
|
w_class->expose_event = sync_config_widget_expose_event;
|
|
w_class->size_request = sync_config_widget_size_request;
|
|
w_class->size_allocate = sync_config_widget_size_allocate;
|
|
w_class->map = sync_config_widget_map;
|
|
w_class->unmap = sync_config_widget_unmap;
|
|
|
|
c_class->add = sync_config_widget_add;
|
|
c_class->remove = sync_config_widget_remove;
|
|
c_class->forall = sync_config_widget_forall;
|
|
|
|
pspec = g_param_spec_pointer ("server",
|
|
"SyncevoServer",
|
|
"The SyncevoServer to use in Syncevolution DBus calls",
|
|
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
|
|
g_object_class_install_property (object_class, PROP_SERVER, pspec);
|
|
|
|
pspec = g_param_spec_string ("name",
|
|
"Configuration name",
|
|
"The name of the Syncevolution service configuration",
|
|
NULL,
|
|
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
|
|
g_object_class_install_property (object_class, PROP_NAME, pspec);
|
|
|
|
pspec = g_param_spec_pointer ("config",
|
|
"SyncevoConfig",
|
|
"The SyncevoConfig struct this widget represents. Takes ownership.",
|
|
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
|
|
g_object_class_install_property (object_class, PROP_CONFIG, pspec);
|
|
|
|
pspec = g_param_spec_boolean ("current",
|
|
"Current",
|
|
"Whether the service is currently used",
|
|
FALSE,
|
|
G_PARAM_READWRITE);
|
|
g_object_class_install_property (object_class, PROP_CURRENT, pspec);
|
|
|
|
pspec = g_param_spec_boolean ("has-template",
|
|
"has template",
|
|
"Whether the service has a matching template",
|
|
FALSE,
|
|
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
|
|
g_object_class_install_property (object_class, PROP_HAS_TEMPLATE, pspec);
|
|
|
|
pspec = g_param_spec_boolean ("configured",
|
|
"Configured",
|
|
"Whether the service has a configuration already",
|
|
FALSE,
|
|
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
|
|
g_object_class_install_property (object_class, PROP_CONFIGURED, pspec);
|
|
|
|
pspec = g_param_spec_string ("current-service-name",
|
|
"Current service name",
|
|
"The name of the currently used service or NULL",
|
|
NULL,
|
|
G_PARAM_READWRITE);
|
|
g_object_class_install_property (object_class, PROP_CURRENT_SERVICE_NAME, pspec);
|
|
|
|
pspec = g_param_spec_boolean ("expanded",
|
|
"Expanded",
|
|
"Whether the expander is open or closed",
|
|
FALSE,
|
|
G_PARAM_READWRITE);
|
|
g_object_class_install_property (object_class, PROP_EXPANDED, pspec);
|
|
|
|
signals[SIGNAL_CHANGED] =
|
|
g_signal_new ("changed",
|
|
G_TYPE_FROM_CLASS (klass),
|
|
G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
|
|
G_STRUCT_OFFSET (SyncConfigWidgetClass, changed),
|
|
NULL, NULL,
|
|
g_cclosure_marshal_VOID__VOID,
|
|
G_TYPE_NONE,
|
|
0);
|
|
|
|
}
|
|
|
|
static void
|
|
label_enter_notify_cb (GtkWidget *widget,
|
|
GdkEventCrossing *event,
|
|
SyncConfigWidget *self)
|
|
{
|
|
if (!self->expanded) {
|
|
gtk_widget_show (self->button);
|
|
}
|
|
gtk_widget_set_state (self->label_box, GTK_STATE_PRELIGHT);
|
|
}
|
|
|
|
static void
|
|
label_leave_notify_cb (GtkWidget *widget,
|
|
GdkEventCrossing *event,
|
|
SyncConfigWidget *self)
|
|
{
|
|
if (event->detail != GDK_NOTIFY_INFERIOR) {
|
|
gtk_widget_hide (self->button);
|
|
gtk_widget_set_state (self->label_box, GTK_STATE_NORMAL);
|
|
}
|
|
}
|
|
|
|
static void
|
|
device_combo_changed (GtkComboBox *combo,
|
|
SyncConfigWidget *self)
|
|
{
|
|
char *selected;
|
|
|
|
selected = gtk_combo_box_get_active_text (GTK_COMBO_BOX (combo));
|
|
gtk_widget_set_sensitive (self->device_select_btn, selected != NULL);
|
|
}
|
|
|
|
static void
|
|
label_button_release_cb (GtkWidget *widget,
|
|
GdkEventButton *event,
|
|
SyncConfigWidget *self)
|
|
|
|
{
|
|
if (event->button == 1) {
|
|
sync_config_widget_set_expanded (self,
|
|
!sync_config_widget_get_expanded (self));
|
|
}
|
|
}
|
|
|
|
static gint
|
|
compare_list_items (GtkTreeModel *model,
|
|
GtkTreeIter *a,
|
|
GtkTreeIter *b,
|
|
SyncConfigWidget *self)
|
|
{
|
|
int score_a, score_b;
|
|
|
|
gtk_tree_model_get(model, a, 2, &score_a, -1);
|
|
gtk_tree_model_get(model, b, 2, &score_b, -1);
|
|
|
|
return score_a - score_b;
|
|
}
|
|
|
|
static void
|
|
sync_config_widget_init (SyncConfigWidget *self)
|
|
{
|
|
GtkWidget *tmp_box, *hbox, *cont, *vbox, *label;
|
|
GtkListStore *store;
|
|
GtkCellRenderer *renderer;
|
|
|
|
GTK_WIDGET_SET_FLAGS (GTK_WIDGET (self), GTK_NO_WINDOW);
|
|
|
|
self->label_box = gtk_event_box_new ();
|
|
gtk_widget_set_app_paintable (self->label_box, TRUE);
|
|
gtk_widget_show (self->label_box);
|
|
gtk_widget_set_parent (self->label_box, GTK_WIDGET (self));
|
|
gtk_widget_set_size_request (self->label_box, -1, SYNC_UI_LIST_ICON_SIZE + 6);
|
|
g_signal_connect (self->label_box, "enter-notify-event",
|
|
G_CALLBACK (label_enter_notify_cb), self);
|
|
g_signal_connect (self->label_box, "leave-notify-event",
|
|
G_CALLBACK (label_leave_notify_cb), self);
|
|
g_signal_connect (self->label_box, "button-release-event",
|
|
G_CALLBACK (label_button_release_cb), self);
|
|
g_signal_connect (self->label_box, "expose-event",
|
|
G_CALLBACK (label_button_expose_cb), self);
|
|
|
|
hbox = gtk_hbox_new (FALSE, 0);
|
|
gtk_widget_show (hbox);
|
|
gtk_container_add (GTK_CONTAINER (self->label_box), hbox);
|
|
|
|
self->image = gtk_image_new ();
|
|
/* leave room for drawing the expander indicator in expose handler */
|
|
gtk_widget_set_size_request (self->image,
|
|
SYNC_UI_LIST_ICON_SIZE + INDICATOR_SIZE,
|
|
SYNC_UI_LIST_ICON_SIZE);
|
|
gtk_misc_set_alignment (GTK_MISC (self->image), 1.0, 0.5);
|
|
gtk_widget_show (self->image);
|
|
gtk_box_pack_start (GTK_BOX (hbox), self->image, FALSE, FALSE, 8);
|
|
|
|
tmp_box = gtk_hbox_new (FALSE, 0);
|
|
gtk_widget_show (tmp_box);
|
|
gtk_box_pack_start (GTK_BOX (hbox), tmp_box, FALSE, FALSE, 8);
|
|
|
|
self->label = gtk_label_new ("");
|
|
gtk_label_set_max_width_chars (GTK_LABEL (self->label), 60);
|
|
gtk_label_set_ellipsize (GTK_LABEL (self->label), PANGO_ELLIPSIZE_END);
|
|
gtk_misc_set_alignment (GTK_MISC (self->label), 0.0, 0.5);
|
|
gtk_widget_show (self->label);
|
|
gtk_box_pack_start (GTK_BOX (tmp_box), self->label, FALSE, FALSE, 0);
|
|
|
|
self->entry = gtk_entry_new ();
|
|
gtk_widget_set_no_show_all (self->entry, TRUE);
|
|
gtk_box_pack_start (GTK_BOX (tmp_box), self->entry, FALSE, FALSE, 4);
|
|
|
|
vbox = gtk_vbox_new (FALSE, 0);
|
|
gtk_widget_show (vbox);
|
|
gtk_box_pack_start (GTK_BOX (tmp_box), vbox, FALSE, FALSE, 0);
|
|
|
|
/* TRANSLATORS: link button in service configuration form */
|
|
self->link = gtk_link_button_new_with_label ("", _("Launch website"));
|
|
gtk_widget_set_no_show_all (self->link, TRUE);
|
|
gtk_box_pack_start (GTK_BOX (vbox), self->link, TRUE, FALSE, 0);
|
|
|
|
vbox = gtk_vbox_new (FALSE, 0);
|
|
gtk_widget_show (vbox);
|
|
gtk_box_pack_end (GTK_BOX (hbox), vbox, FALSE, FALSE, 32);
|
|
|
|
/* TRANSLATORS: button in service configuration form */
|
|
self->button = gtk_button_new_with_label (_("Setup now"));
|
|
gtk_widget_set_size_request (self->button, SYNC_UI_LIST_BTN_WIDTH, -1);
|
|
g_signal_connect (self->button, "clicked",
|
|
G_CALLBACK (setup_service_clicked), self);
|
|
gtk_box_pack_start (GTK_BOX (vbox), self->button, TRUE, FALSE, 0);
|
|
|
|
/* label_box built, now build expando_box */
|
|
|
|
self->expando_box = gtk_hbox_new (FALSE, 0);
|
|
gtk_widget_set_no_show_all (self->expando_box, TRUE);
|
|
gtk_widget_set_parent (self->expando_box, GTK_WIDGET (self));
|
|
|
|
self->device_selector_box = gtk_vbox_new (FALSE, 0);
|
|
gtk_box_pack_start (GTK_BOX (self->expando_box), self->device_selector_box,
|
|
TRUE, TRUE, 16);
|
|
|
|
hbox = gtk_hbox_new (FALSE, 8);
|
|
gtk_widget_show (hbox);
|
|
gtk_box_pack_start (GTK_BOX (self->device_selector_box), hbox,
|
|
FALSE, TRUE, 8);
|
|
self->device_text = gtk_label_new (("We don't know what this device is exactly. "
|
|
"Please take a look at the list of "
|
|
"supported devices and pick yours if it "
|
|
"is listed"));
|
|
gtk_widget_show (self->device_text);
|
|
gtk_label_set_line_wrap (GTK_LABEL (self->device_text), TRUE);
|
|
gtk_widget_set_size_request (self->device_text, 600, -1);
|
|
gtk_box_pack_start (GTK_BOX (hbox), self->device_text,
|
|
FALSE, TRUE, 0);
|
|
|
|
|
|
hbox = gtk_hbox_new (FALSE, 16);
|
|
gtk_widget_show (hbox);
|
|
gtk_box_pack_start (GTK_BOX (self->device_selector_box), hbox,
|
|
FALSE, TRUE, 16);
|
|
|
|
store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_INT);
|
|
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
|
|
2, GTK_SORT_DESCENDING);
|
|
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (store), 2,
|
|
(GtkTreeIterCompareFunc)compare_list_items,
|
|
NULL, NULL);
|
|
|
|
self->combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store));
|
|
g_object_unref (G_OBJECT (store));
|
|
gtk_widget_set_size_request (self->combo, 200, -1);
|
|
gtk_widget_show (self->combo);
|
|
gtk_box_pack_start (GTK_BOX (hbox), self->combo, FALSE, TRUE, 0);
|
|
|
|
renderer = gtk_cell_renderer_text_new ();
|
|
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT(self->combo), renderer, TRUE);
|
|
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT(self->combo), renderer,
|
|
"text", 0, NULL);
|
|
|
|
g_signal_connect (self->combo, "changed",
|
|
G_CALLBACK (device_combo_changed), self);
|
|
|
|
|
|
self->device_select_btn = gtk_button_new_with_label ("Use these settings");
|
|
gtk_widget_set_sensitive (self->device_select_btn, FALSE);
|
|
gtk_widget_show (self->device_select_btn);
|
|
gtk_box_pack_start (GTK_BOX (hbox), self->device_select_btn,
|
|
FALSE, TRUE, 0);
|
|
g_signal_connect (self->device_select_btn, "clicked",
|
|
G_CALLBACK (device_selection_btn_clicked_cb), self);
|
|
|
|
/* settings_box has normal expander contents */
|
|
self->settings_box = gtk_vbox_new (FALSE, 0);
|
|
gtk_widget_show (self->settings_box);
|
|
gtk_box_pack_start (GTK_BOX (self->expando_box), self->settings_box,
|
|
TRUE, TRUE, 16);
|
|
|
|
vbox = gtk_vbox_new (FALSE, 8);
|
|
gtk_widget_show (vbox);
|
|
gtk_box_pack_start (GTK_BOX (self->settings_box), vbox, TRUE, TRUE, 0);
|
|
|
|
tmp_box = gtk_vbox_new (FALSE, 0);
|
|
gtk_widget_show (tmp_box);
|
|
gtk_box_pack_start (GTK_BOX (vbox), tmp_box, FALSE, FALSE, 8);
|
|
|
|
self->description_label = gtk_label_new ("");
|
|
gtk_misc_set_alignment (GTK_MISC (self->description_label), 0.0, 0.5);
|
|
gtk_widget_set_size_request (self->description_label, 700, -1);
|
|
gtk_box_pack_start (GTK_BOX (tmp_box), self->description_label, FALSE, FALSE, 0);
|
|
|
|
tmp_box = gtk_hbox_new (FALSE, 0);
|
|
gtk_widget_show (tmp_box);
|
|
gtk_box_pack_start (GTK_BOX (vbox), tmp_box, FALSE, FALSE, 0);
|
|
|
|
self->userinfo_table = gtk_table_new (4, 2, FALSE);
|
|
gtk_table_set_row_spacings (GTK_TABLE (self->userinfo_table), 2);
|
|
gtk_table_set_col_spacings (GTK_TABLE (self->userinfo_table), 5);
|
|
gtk_widget_show (self->userinfo_table);
|
|
gtk_box_pack_start (GTK_BOX (tmp_box), self->userinfo_table, FALSE, FALSE, 0);
|
|
|
|
/* TRANSLATORS: labels of entries in service configuration form */
|
|
label = gtk_label_new (_("Username"));
|
|
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
|
gtk_widget_show (label);
|
|
gtk_table_attach_defaults (GTK_TABLE (self->userinfo_table), label,
|
|
0, 1,
|
|
0, 1);
|
|
|
|
self->username_entry = gtk_entry_new ();
|
|
gtk_widget_show (self->username_entry);
|
|
gtk_entry_set_width_chars (GTK_ENTRY (self->username_entry), 40);
|
|
gtk_entry_set_max_length (GTK_ENTRY (self->username_entry), 99);
|
|
gtk_table_attach_defaults (GTK_TABLE (self->userinfo_table), self->username_entry,
|
|
1, 2,
|
|
0, 1);
|
|
|
|
label = gtk_label_new (_("Password"));
|
|
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
|
gtk_widget_show (label);
|
|
gtk_table_attach_defaults (GTK_TABLE (self->userinfo_table), label,
|
|
0, 1,
|
|
1, 2);
|
|
|
|
self->password_entry = gtk_entry_new ();
|
|
gtk_widget_show (self->password_entry);
|
|
gtk_entry_set_width_chars (GTK_ENTRY (self->password_entry), 40);
|
|
gtk_entry_set_visibility (GTK_ENTRY (self->password_entry), FALSE);
|
|
gtk_entry_set_max_length (GTK_ENTRY (self->password_entry), 99);
|
|
gtk_table_attach_defaults (GTK_TABLE (self->userinfo_table), self->password_entry,
|
|
1, 2,
|
|
1, 2);
|
|
|
|
self->complex_config_info_bar = gtk_info_bar_new ();
|
|
gtk_info_bar_set_message_type (GTK_INFO_BAR (self->complex_config_info_bar),
|
|
GTK_MESSAGE_WARNING);
|
|
gtk_box_pack_start (GTK_BOX (vbox), self->complex_config_info_bar,
|
|
FALSE, FALSE, 0);
|
|
/* TRANSLATORS: warning in service configuration form for people
|
|
who have modified the configuration via other means. */
|
|
label = gtk_label_new (_("Current configuration is more complex "
|
|
"than what can be shown here. Changes to sync "
|
|
"mode or synced data types will overwrite that "
|
|
"configuration."));
|
|
gtk_widget_set_size_request (label, 600, -1);
|
|
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
|
|
gtk_widget_show (label);
|
|
cont = gtk_info_bar_get_content_area (
|
|
GTK_INFO_BAR (self->complex_config_info_bar));
|
|
gtk_container_add (GTK_CONTAINER (cont), label);
|
|
|
|
self->mode_table = gtk_table_new (4, 1, FALSE);
|
|
gtk_table_set_row_spacings (GTK_TABLE (self->mode_table), 2);
|
|
gtk_table_set_col_spacings (GTK_TABLE (self->mode_table), 5);
|
|
gtk_widget_show (self->mode_table);
|
|
gtk_box_pack_start (GTK_BOX (vbox), self->mode_table, FALSE, FALSE, 0);
|
|
|
|
/* TRANSLATORS: this is the epander label for server settings
|
|
in service configuration form */
|
|
self->expander = gtk_expander_new (_("Hide server settings"));
|
|
gtk_box_pack_start (GTK_BOX (vbox), self->expander, FALSE, FALSE, 8);
|
|
|
|
tmp_box = gtk_hbox_new (FALSE, 0);
|
|
gtk_widget_show (tmp_box);
|
|
gtk_container_add (GTK_CONTAINER (self->expander), tmp_box);
|
|
|
|
self->server_settings_table = gtk_table_new (1, 1, FALSE);
|
|
gtk_table_set_row_spacings (GTK_TABLE (self->server_settings_table), 2);
|
|
gtk_table_set_col_spacings (GTK_TABLE (self->server_settings_table), 5);
|
|
gtk_widget_show (self->server_settings_table);
|
|
gtk_box_pack_start (GTK_BOX (tmp_box), self->server_settings_table, FALSE, FALSE, 0);
|
|
|
|
|
|
tmp_box = gtk_hbox_new (FALSE, 0);
|
|
gtk_widget_show (tmp_box);
|
|
gtk_box_pack_start (GTK_BOX (vbox), tmp_box, FALSE, FALSE, 8);
|
|
|
|
/* TRANSLATORS: this is the epander label for server settings
|
|
in service configuration form */
|
|
self->fake_expander = gtk_expander_new (_("Show server settings"));
|
|
gtk_widget_show (self->fake_expander);
|
|
gtk_box_pack_start (GTK_BOX (tmp_box), self->fake_expander, FALSE, FALSE, 0);
|
|
g_signal_connect (self->fake_expander, "notify::expanded",
|
|
G_CALLBACK (server_settings_notify_expand_cb), self);
|
|
|
|
self->use_button = gtk_button_new ();
|
|
gtk_widget_show (self->use_button);
|
|
gtk_box_pack_end (GTK_BOX (tmp_box), self->use_button, FALSE, FALSE, 8);
|
|
g_signal_connect (self->use_button, "clicked",
|
|
G_CALLBACK (use_clicked_cb), self);
|
|
|
|
self->stop_button = gtk_button_new ();
|
|
gtk_box_pack_end (GTK_BOX (tmp_box), self->stop_button, FALSE, FALSE, 8);
|
|
g_signal_connect (self->stop_button, "clicked",
|
|
G_CALLBACK (stop_clicked_cb), self);
|
|
|
|
self->reset_delete_button = gtk_button_new ();
|
|
gtk_widget_show (self->reset_delete_button);
|
|
gtk_box_pack_end (GTK_BOX (tmp_box), self->reset_delete_button, FALSE, FALSE, 8);
|
|
g_signal_connect (self->reset_delete_button, "clicked",
|
|
G_CALLBACK (reset_delete_clicked_cb), self);
|
|
}
|
|
|
|
|
|
GtkWidget*
|
|
sync_config_widget_new (SyncevoServer *server,
|
|
const char *name,
|
|
SyncevoConfig *config,
|
|
gboolean current,
|
|
const char *current_service_name,
|
|
gboolean configured,
|
|
gboolean has_template)
|
|
{
|
|
return g_object_new (SYNC_TYPE_CONFIG_WIDGET,
|
|
"server", server,
|
|
"name", name,
|
|
"config", config,
|
|
"current", current,
|
|
"current-service-name", current_service_name,
|
|
"configured", configured,
|
|
"has-template", has_template,
|
|
NULL);
|
|
}
|
|
|
|
void
|
|
sync_config_widget_set_expanded (SyncConfigWidget *self, gboolean expanded)
|
|
{
|
|
g_return_if_fail (SYNC_IS_CONFIG_WIDGET (self));
|
|
|
|
if (self->expanded != expanded) {
|
|
|
|
self->expanded = expanded;
|
|
if (self->expanded) {
|
|
gtk_widget_hide (self->button);
|
|
gtk_widget_show (self->expando_box);
|
|
if (GTK_WIDGET_VISIBLE (self->entry)) {
|
|
gtk_widget_grab_focus (self->entry);
|
|
} else {
|
|
gtk_widget_grab_focus (self->username_entry);
|
|
}
|
|
} else {
|
|
gtk_widget_show (self->button);
|
|
gtk_widget_hide (self->expando_box);
|
|
}
|
|
g_object_notify (G_OBJECT (self), "expanded");
|
|
|
|
}
|
|
}
|
|
|
|
gboolean
|
|
sync_config_widget_get_expanded (SyncConfigWidget *self)
|
|
{
|
|
return self->expanded;
|
|
}
|
|
|
|
void
|
|
sync_config_widget_set_has_template (SyncConfigWidget *self, gboolean has_template)
|
|
{
|
|
if (self->has_template != has_template) {
|
|
self->has_template = has_template;
|
|
update_buttons (self);
|
|
sync_config_widget_update_label (self);
|
|
}
|
|
}
|
|
|
|
gboolean
|
|
sync_config_widget_get_has_template (SyncConfigWidget *self)
|
|
{
|
|
return self->has_template;
|
|
}
|
|
|
|
void
|
|
sync_config_widget_set_configured (SyncConfigWidget *self, gboolean configured)
|
|
{
|
|
if (self->configured != configured) {
|
|
self->configured = configured;
|
|
self->device_template_selected = configured;
|
|
update_buttons (self);
|
|
}
|
|
}
|
|
|
|
gboolean
|
|
sync_config_widget_get_configured (SyncConfigWidget *self)
|
|
{
|
|
return self->configured;
|
|
}
|
|
|
|
|
|
gboolean
|
|
sync_config_widget_get_current (SyncConfigWidget *widget)
|
|
{
|
|
return widget->current;
|
|
}
|
|
|
|
const char*
|
|
sync_config_widget_get_name (SyncConfigWidget *widget)
|
|
{
|
|
return widget->config_name;
|
|
}
|
|
|
|
void
|
|
sync_config_widget_add_alternative_config (SyncConfigWidget *self,
|
|
const char *name,
|
|
SyncevoConfig *config,
|
|
gboolean configured)
|
|
{
|
|
if (configured) {
|
|
sync_config_widget_set_config (self, config);
|
|
sync_config_widget_set_name (self, name);
|
|
sync_config_widget_set_configured (self, TRUE);
|
|
} else {
|
|
sync_config_widget_add_config (self, name, config);
|
|
}
|
|
sync_config_widget_update_expander (self);
|
|
}
|