accountview: add account import/export
Allows user to export a selected account and import
from an archive. For now the interface only allows the
selection of one account for export. Multi-account selection
can be added later.
Change-Id: I1ac46c695b335cbdc5b2cee2ea6abee618ba9c3b
Tuleap: #617
diff --git a/src/accountimportexportview.cpp b/src/accountimportexportview.cpp
new file mode 100644
index 0000000..2523e53
--- /dev/null
+++ b/src/accountimportexportview.cpp
@@ -0,0 +1,411 @@
+/*
+ * Copyright (C) 2016 Savoir-faire Linux Inc.
+ * Author: Stepan Salenikovich <stepan.salenikovich@savoirfairelinux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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 "accountimportexportview.h"
+
+#include <gtk/gtk.h>
+#include <account.h>
+#include <accountmodel.h>
+
+#include <glib/gi18n.h>
+
+struct _AccountImportExportView
+{
+ GtkBox parent;
+};
+
+struct _AccountImportExportViewClass
+{
+ GtkBoxClass parent_class;
+};
+
+typedef struct _AccountImportExportViewPrivate AccountImportExportViewPrivate;
+
+struct _AccountImportExportViewPrivate
+{
+ Account *account;
+
+ GtkWidget *label_export;
+ GtkWidget *label_import;
+ GtkWidget *hbox_export_location;
+ GtkWidget *label_export_location;
+ GtkWidget *button_export_location;
+ GtkWidget *filechooserbutton_import;
+ GtkWidget *button_export;
+ GtkWidget *button_import;
+ GtkWidget *button_cancel;
+ GtkWidget *entry_password;
+ GtkWidget *label_error;
+
+ GList *export_accounts_list;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE(AccountImportExportView, account_importexport_view, GTK_TYPE_BOX);
+
+#define ACCOUNT_IMPORTEXPORT_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), ACCOUNT_IMPORTEXPORT_VIEW_TYPE, AccountImportExportViewPrivate))
+
+/* signals */
+enum {
+ IMPORT_EXPORT_CANCELED,
+ IMPORT_EXPORT_COMPLETED,
+ LAST_SIGNAL
+};
+
+static guint account_importexport_view_signals[LAST_SIGNAL] = { 0 };
+
+static void
+account_importexport_view_dispose(GObject *object)
+{
+ G_OBJECT_CLASS(account_importexport_view_parent_class)->dispose(object);
+}
+
+static void
+account_importexport_view_finalize(GObject *object)
+{
+ AccountImportExportView *view = ACCOUNT_IMPORTEXPORT_VIEW(object);
+ AccountImportExportViewPrivate *priv = ACCOUNT_IMPORTEXPORT_VIEW_GET_PRIVATE(view);
+
+ if (priv->export_accounts_list)
+ g_list_free(priv->export_accounts_list);
+
+ G_OBJECT_CLASS(account_importexport_view_parent_class)->finalize(object);
+}
+
+static void
+choose_export_location(AccountImportExportView *self)
+{
+ AccountImportExportViewPrivate *priv = ACCOUNT_IMPORTEXPORT_VIEW_GET_PRIVATE(self);
+
+ // clear any existing error
+ gtk_label_set_text(GTK_LABEL(priv->label_error), "");
+
+ // create filechooser dialog and get export location
+ auto dialog = gtk_file_chooser_dialog_new(_("Select account export location"),
+ GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(self))),
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ _("Cancel"),
+ GTK_RESPONSE_CANCEL,
+ _("Select"),
+ GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
+ gtk_file_chooser_set_create_folders(GTK_FILE_CHOOSER(dialog), TRUE);
+
+ if (!priv->export_accounts_list->next) {
+ auto name = g_strconcat(static_cast<Account *>(priv->export_accounts_list->data)->alias().toUtf8().constData(), ".ring", NULL);
+ gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), name);
+ g_free(name);
+ } else {
+ // TODO: handle multiple account export
+ }
+
+ /* start the file chooser */
+ if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
+ if (auto filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog))) {
+ gtk_label_set_text(GTK_LABEL(priv->label_export_location), filename);
+
+ // if accounts and password are set then we're ready for export
+ auto password = gtk_entry_get_text(GTK_ENTRY(priv->entry_password));
+ if (priv->export_accounts_list && priv->export_accounts_list->data && strlen(password) > 0) {
+ gtk_widget_set_sensitive(priv->button_export, TRUE);
+ }
+ g_free (filename);
+ }
+ }
+
+ gtk_widget_destroy (dialog);
+}
+
+
+static void
+import_file_set(AccountImportExportView *self)
+{
+ AccountImportExportViewPrivate *priv = ACCOUNT_IMPORTEXPORT_VIEW_GET_PRIVATE(self);
+
+ // clear any existing error
+ gtk_label_set_text(GTK_LABEL(priv->label_error), "");
+
+ // if password is set then we're ready for import
+ auto password = gtk_entry_get_text(GTK_ENTRY(priv->entry_password));
+ if (strlen(password) > 0) {
+ gtk_widget_set_sensitive(priv->button_import, TRUE);
+ }
+}
+
+static void
+password_changed(AccountImportExportView *self)
+{
+ AccountImportExportViewPrivate *priv = ACCOUNT_IMPORTEXPORT_VIEW_GET_PRIVATE(self);
+
+ // clear any existing error
+ gtk_label_set_text(GTK_LABEL(priv->label_error), "");
+
+ // if the password and other requirements are met then enable import/export
+ auto password = gtk_entry_get_text(GTK_ENTRY(priv->entry_password));
+ if (strlen(password) > 0) {
+
+ // import
+ if (auto filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(priv->filechooserbutton_import))) {
+ gtk_widget_set_sensitive(priv->button_import, TRUE);
+ g_free(filename);
+ }
+
+ // export
+ const auto filename = gtk_label_get_text(GTK_LABEL(priv->label_export_location));
+ if (strlen(filename) > 0) {
+ if (priv->export_accounts_list && priv->export_accounts_list->data) {
+ gtk_widget_set_sensitive(priv->button_export, TRUE);
+ }
+ }
+
+ } else {
+ gtk_widget_set_sensitive(priv->button_export, FALSE);
+ gtk_widget_set_sensitive(priv->button_import, FALSE);
+ }
+}
+
+static void
+cancel_clicked(AccountImportExportView *self)
+{
+ g_signal_emit(G_OBJECT(self), account_importexport_view_signals[IMPORT_EXPORT_CANCELED], 0);
+}
+
+static void
+import_account(AccountImportExportView *self)
+{
+ g_return_if_fail(IS_ACCOUNT_IMPORTEXPORT_VIEW(self));
+
+ AccountImportExportViewPrivate *priv = ACCOUNT_IMPORTEXPORT_VIEW_GET_PRIVATE(self);
+
+ // clear any existing error
+ gtk_label_set_text(GTK_LABEL(priv->label_error), "");
+
+ if (auto filepath = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(priv->filechooserbutton_import))) {
+ const auto password = gtk_entry_get_text(GTK_ENTRY(priv->entry_password));
+ if (strlen(password) > 0) {
+ auto ret = AccountModel::instance().importAccounts(filepath, password);
+ switch(ret) {
+ case 0:
+ // done
+ g_signal_emit(G_OBJECT(self), account_importexport_view_signals[IMPORT_EXPORT_COMPLETED], 0);
+ break;
+ default:
+ //failed
+ gtk_label_set_text(GTK_LABEL(priv->label_error), _("Error importing account(s)"));
+ g_warning("failed to import account(s), err: %d", ret);
+ break;
+ }
+ } else {
+ g_warning("no password set for account import");
+ }
+ g_free(filepath);
+ } else {
+ g_warning("no file selected for account import");
+ }
+}
+
+static void
+export_account(AccountImportExportView *self)
+{
+ g_return_if_fail(IS_ACCOUNT_IMPORTEXPORT_VIEW(self));
+
+ AccountImportExportViewPrivate *priv = ACCOUNT_IMPORTEXPORT_VIEW_GET_PRIVATE(self);
+
+ // clear any existing error
+ gtk_label_set_text(GTK_LABEL(priv->label_error), "");
+
+ // check that we have some accounts to export
+ if ( !(priv->export_accounts_list && priv->export_accounts_list->data)) {
+ g_warning("no accounts are selected for export");
+ return;
+ }
+
+ const auto filepath = gtk_label_get_text(GTK_LABEL(priv->label_export_location));
+ // validate filepath
+ if (strlen(filepath)) {
+ const auto password = gtk_entry_get_text(GTK_ENTRY(priv->entry_password));
+ if (strlen(password) > 0) {
+
+ // get account id strings
+ auto account_ids = QStringList();
+ auto list = priv->export_accounts_list;
+ while (list != nullptr) {
+ auto account = static_cast<Account *>(list->data);
+ account_ids << account->id();
+ list = g_list_next(list);
+ }
+
+ auto ret = AccountModel::instance().exportAccounts(account_ids, filepath, password);
+ switch (ret) {
+ case 0:
+ // done
+ g_signal_emit(G_OBJECT(self), account_importexport_view_signals[IMPORT_EXPORT_COMPLETED], 0);
+ break;
+ default:
+ //failed
+ gtk_label_set_text(GTK_LABEL(priv->label_error), _("Error exporting account(s)"));
+ g_warning("failed to export account(s), err: %d", ret);
+ break;
+ }
+ } else {
+ g_warning("no password set for account export");
+ }
+ } else {
+ g_warning("no file selected for account export");
+ }
+}
+
+static void
+account_importexport_view_init(AccountImportExportView *self)
+{
+ gtk_widget_init_template(GTK_WIDGET(self));
+
+ AccountImportExportViewPrivate *priv = ACCOUNT_IMPORTEXPORT_VIEW_GET_PRIVATE(self);
+
+ g_signal_connect_swapped(priv->button_export_location, "clicked", G_CALLBACK(choose_export_location), self);
+ g_signal_connect_swapped(priv->filechooserbutton_import, "file-set", G_CALLBACK(import_file_set), self);
+ g_signal_connect_swapped(priv->entry_password, "changed", G_CALLBACK(password_changed), self);
+ g_signal_connect_swapped(priv->button_cancel, "clicked", G_CALLBACK(cancel_clicked), self);
+ g_signal_connect_swapped(priv->button_import, "clicked", G_CALLBACK(import_account), self);
+ g_signal_connect_swapped(priv->button_export, "clicked", G_CALLBACK(export_account), self);
+}
+
+static void
+account_importexport_view_class_init(AccountImportExportViewClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+ gobject_class->dispose = account_importexport_view_dispose;
+ gobject_class->finalize = account_importexport_view_finalize;
+
+ gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS (klass),
+ "/cx/ring/RingGnome/accountimportexportview.ui");
+
+ gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountImportExportView, label_export);
+ gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountImportExportView, label_import);
+ gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountImportExportView, hbox_export_location);
+ gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountImportExportView, label_export_location);
+ gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountImportExportView, button_export_location);
+ gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountImportExportView, filechooserbutton_import);
+ gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountImportExportView, button_export);
+ gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountImportExportView, button_import);
+ gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountImportExportView, button_cancel);
+ gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountImportExportView, entry_password);
+ gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountImportExportView, label_error);
+
+ /* add signals */
+ account_importexport_view_signals[IMPORT_EXPORT_CANCELED] = g_signal_new("import-export-canceled",
+ G_TYPE_FROM_CLASS(klass),
+ (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION),
+ 0,
+ nullptr,
+ nullptr,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ account_importexport_view_signals[IMPORT_EXPORT_COMPLETED] = g_signal_new("import-export-completed",
+ G_TYPE_FROM_CLASS(klass),
+ (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION),
+ 0,
+ nullptr,
+ nullptr,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+build_import_view(AccountImportExportView *self)
+{
+ g_return_if_fail(self);
+
+ AccountImportExportViewPrivate *priv = ACCOUNT_IMPORTEXPORT_VIEW_GET_PRIVATE(self);
+
+ gtk_widget_hide(priv->label_export);
+ gtk_widget_hide(priv->hbox_export_location);
+ gtk_widget_hide(priv->button_export);
+
+ gtk_widget_show(priv->label_import);
+ gtk_widget_show(priv->filechooserbutton_import);
+ gtk_widget_show(priv->button_import);
+}
+
+static void
+build_export_view(AccountImportExportView *self)
+{
+ g_return_if_fail(self);
+
+ AccountImportExportViewPrivate *priv = ACCOUNT_IMPORTEXPORT_VIEW_GET_PRIVATE(self);
+
+ gtk_widget_show(priv->label_export);
+ gtk_widget_show(priv->hbox_export_location);
+ gtk_widget_show(priv->button_export);
+
+ gtk_widget_hide(priv->label_import);
+ gtk_widget_hide(priv->filechooserbutton_import);
+ gtk_widget_hide(priv->button_import);
+}
+
+GtkWidget *
+account_import_view_new()
+{
+ gpointer view = g_object_new(ACCOUNT_IMPORTEXPORT_VIEW_TYPE, NULL);
+
+ build_import_view(ACCOUNT_IMPORTEXPORT_VIEW(view));
+
+ return (GtkWidget *)view;
+}
+
+GtkWidget *
+account_export_view_new()
+{
+ gpointer view = g_object_new(ACCOUNT_IMPORTEXPORT_VIEW_TYPE, NULL);
+
+ build_export_view(ACCOUNT_IMPORTEXPORT_VIEW(view));
+
+ return (GtkWidget *)view;
+}
+
+void
+account_export_view_set_accounts(AccountImportExportView *self, GList *accounts)
+{
+ g_return_if_fail(self);
+ AccountImportExportViewPrivate *priv = ACCOUNT_IMPORTEXPORT_VIEW_GET_PRIVATE(self);
+
+ // replace current list
+ if (priv->export_accounts_list) {
+ g_list_free(priv->export_accounts_list);
+ priv->export_accounts_list = nullptr;
+ }
+
+ // make sure the new list isn't empty
+ if (accounts && accounts->data) {
+ priv->export_accounts_list = g_list_copy(accounts);
+
+ if (!accounts->next) {
+ auto location = g_strconcat(g_get_home_dir(), "/", static_cast<Account *>(priv->export_accounts_list->data)->alias().toUtf8().constData(), ".ring", NULL);
+ gtk_label_set_text(GTK_LABEL(priv->label_export_location), location);
+ g_free(location);
+ } else {
+ // TODO: handle multiple account export
+ }
+ } else {
+ // no accounts are selected... this case should not normally be ever displayed
+ }
+}
diff --git a/src/accountimportexportview.h b/src/accountimportexportview.h
new file mode 100644
index 0000000..f2b9324
--- /dev/null
+++ b/src/accountimportexportview.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 Savoir-faire Linux Inc.
+ * Author: Stepan Salenikovich <stepan.salenikovich@savoirfairelinux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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.
+ */
+
+#pragma once
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define ACCOUNT_IMPORTEXPORT_VIEW_TYPE (account_importexport_view_get_type ())
+#define ACCOUNT_IMPORTEXPORT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ACCOUNT_IMPORTEXPORT_VIEW_TYPE, AccountImportExportView))
+#define ACCOUNT_IMPORTEXPORT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), ACCOUNT_IMPORTEXPORT_VIEW_TYPE, AccountImportExportViewClass))
+#define IS_ACCOUNT_IMPORTEXPORT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), ACCOUNT_IMPORTEXPORT_VIEW_TYPE))
+#define IS_ACCOUNT_IMPORTEXPORT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), ACCOUNT_IMPORTEXPORT_VIEW_TYPE))
+
+typedef struct _AccountImportExportView AccountImportExportView;
+typedef struct _AccountImportExportViewClass AccountImportExportViewClass;
+
+GType account_importexport_view_get_type (void) G_GNUC_CONST;
+GtkWidget *account_import_view_new (void);
+GtkWidget *account_export_view_new (void);
+void account_export_view_set_accounts (AccountImportExportView* self, GList *accounts);
+
+G_END_DECLS
diff --git a/src/accountview.cpp b/src/accountview.cpp
index dd57868..30ef947 100644
--- a/src/accountview.cpp
+++ b/src/accountview.cpp
@@ -36,6 +36,7 @@
#include "dialogs.h"
#include <glib/gprintf.h>
#include "utils/models.h"
+#include "accountimportexportview.h"
struct _AccountView
{
@@ -52,11 +53,14 @@
struct _AccountViewPrivate
{
GtkWidget *treeview_account_list;
+ GtkWidget *account_import_view;
+ GtkWidget *account_export_view;
GtkWidget *stack_account;
- GtkWidget *current_account_notebook;
GtkWidget *button_remove_account;
GtkWidget *button_add_account;
GtkWidget *combobox_account_type;
+ GtkWidget *button_import_account;
+ GtkWidget *button_export_account;
gint current_page; /* keeps track of current notebook page displayed */
@@ -109,19 +113,24 @@
}
static void
-account_selection_changed(GtkTreeSelection *selection, AccountView *view)
+tab_selection_changed(G_GNUC_UNUSED GtkNotebook *notebook,
+ G_GNUC_UNUSED GtkWidget *page,
+ guint page_num,
+ AccountView *self)
{
- g_return_if_fail(IS_ACCOUNT_VIEW(view));
- AccountViewPrivate *priv = ACCOUNT_VIEW_GET_PRIVATE(view);
+ g_return_if_fail(IS_ACCOUNT_VIEW(self));
+ AccountViewPrivate *priv = ACCOUNT_VIEW_GET_PRIVATE(self);
- GtkWidget *old_account_view = gtk_stack_get_visible_child(GTK_STACK(priv->stack_account));
+ priv->current_page = page_num;
+}
- /* keep track of the last tab displayed */
- if (priv->current_account_notebook)
- priv->current_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(priv->current_account_notebook));
+static void
+account_selection_changed(GtkTreeSelection *selection, AccountView *self)
+{
+ g_return_if_fail(IS_ACCOUNT_VIEW(self));
+ AccountViewPrivate *priv = ACCOUNT_VIEW_GET_PRIVATE(self);
- if (priv->current_page < 0)
- priv->current_page = 0;
+ auto old_view = gtk_stack_get_visible_child(GTK_STACK(priv->stack_account));
QModelIndex account_idx = get_index_from_selection(selection);
if (!account_idx.isValid()) {
@@ -130,7 +139,10 @@
gtk_widget_show(empty_box);
gtk_stack_add_named(GTK_STACK(priv->stack_account), empty_box, "placeholder");
gtk_stack_set_visible_child(GTK_STACK(priv->stack_account), empty_box);
- priv->current_account_notebook = NULL;
+
+ /* cannot delete nor export accounts */
+ gtk_widget_set_sensitive(priv->button_remove_account, FALSE);
+ gtk_widget_set_sensitive(priv->button_export_account, FALSE);
} else {
Account *account = AccountModel::instance().getAccountByModelIndex(account_idx);
@@ -138,47 +150,53 @@
GtkWidget *hbox_account = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
/* create account notebook */
- priv->current_account_notebook = gtk_notebook_new();
- gtk_notebook_set_scrollable(GTK_NOTEBOOK(priv->current_account_notebook), TRUE);
- gtk_notebook_set_show_border(GTK_NOTEBOOK(priv->current_account_notebook), FALSE);
- gtk_box_pack_start(GTK_BOX(hbox_account), priv->current_account_notebook, TRUE, TRUE, 0);
+ auto account_notebook = gtk_notebook_new();
+ gtk_notebook_set_scrollable(GTK_NOTEBOOK(account_notebook), TRUE);
+ gtk_notebook_set_show_border(GTK_NOTEBOOK(account_notebook), FALSE);
+ gtk_box_pack_start(GTK_BOX(hbox_account), account_notebook, TRUE, TRUE, 0);
/* customize account view based on account */
auto general_tab = create_scrolled_account_view(account_general_tab_new(account));
- gtk_notebook_append_page(GTK_NOTEBOOK(priv->current_account_notebook),
+ gtk_notebook_append_page(GTK_NOTEBOOK(account_notebook),
general_tab,
gtk_label_new(C_("Account settings", "General")));
auto audio_tab = create_scrolled_account_view(account_audio_tab_new(account));
- gtk_notebook_append_page(GTK_NOTEBOOK(priv->current_account_notebook),
+ gtk_notebook_append_page(GTK_NOTEBOOK(account_notebook),
audio_tab,
gtk_label_new(C_("Account settings", "Audio")));
auto video_tab = create_scrolled_account_view(account_video_tab_new(account));
- gtk_notebook_append_page(GTK_NOTEBOOK(priv->current_account_notebook),
+ gtk_notebook_append_page(GTK_NOTEBOOK(account_notebook),
video_tab,
gtk_label_new(C_("Account settings", "Video")));
auto advanced_tab = create_scrolled_account_view(account_advanced_tab_new(account));
- gtk_notebook_append_page(GTK_NOTEBOOK(priv->current_account_notebook),
+ gtk_notebook_append_page(GTK_NOTEBOOK(account_notebook),
advanced_tab,
gtk_label_new(C_("Account settings", "Advanced")));
auto security_tab = create_scrolled_account_view(account_security_tab_new(account));
- gtk_notebook_append_page(GTK_NOTEBOOK(priv->current_account_notebook),
+ gtk_notebook_append_page(GTK_NOTEBOOK(account_notebook),
security_tab,
gtk_label_new(C_("Account settings", "Security")));
gtk_widget_show_all(hbox_account);
/* set the tab displayed to the same as the prev account selected */
- gtk_notebook_set_current_page(GTK_NOTEBOOK(priv->current_account_notebook), priv->current_page);
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(account_notebook), priv->current_page);
+ /* now connect to the tab changed signal */
+ g_signal_connect(account_notebook, "switch-page", G_CALLBACK(tab_selection_changed), self);
/* set the new account view as visible */
char *account_view_name = g_strdup_printf("%p_account", account);
gtk_stack_add_named(GTK_STACK(priv->stack_account), hbox_account, account_view_name);
gtk_stack_set_visible_child(GTK_STACK(priv->stack_account), hbox_account);
g_free(account_view_name);
+
+ /* can delete and export accounts */
+ gtk_widget_set_sensitive(priv->button_remove_account, TRUE);
+ gtk_widget_set_sensitive(priv->button_export_account, TRUE);
}
- /* remove the old account view */
- if (old_account_view)
- gtk_container_remove(GTK_CONTAINER(priv->stack_account), old_account_view);
+ /* remove the old view */
+ if (old_view)
+ gtk_container_remove(GTK_CONTAINER(priv->stack_account), old_view);
}
static void
@@ -366,6 +384,69 @@
}
static void
+close_import_export_view(AccountView *self)
+{
+ g_return_if_fail(IS_ACCOUNT_VIEW(self));
+ AccountViewPrivate *priv = ACCOUNT_VIEW_GET_PRIVATE(self);
+
+ auto selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->treeview_account_list));
+ account_selection_changed(selection, self);
+}
+
+static void
+import_account(AccountView* self)
+{
+ g_return_if_fail(IS_ACCOUNT_VIEW(self));
+ AccountViewPrivate *priv = ACCOUNT_VIEW_GET_PRIVATE(self);
+
+ auto old_view = gtk_stack_get_visible_child(GTK_STACK(priv->stack_account));
+
+ auto import_account = account_import_view_new();
+ g_signal_connect_swapped(import_account, "import-export-canceled", G_CALLBACK(close_import_export_view), self);
+ g_signal_connect_swapped(import_account, "import-export-completed", G_CALLBACK(close_import_export_view), self);
+ auto scrolled_view = create_scrolled_account_view(import_account);
+ gtk_widget_show_all(scrolled_view);
+ gtk_stack_add_named(GTK_STACK(priv->stack_account), scrolled_view, "import_account");
+ gtk_stack_set_visible_child(GTK_STACK(priv->stack_account), scrolled_view);
+
+ /* remove the old view */
+ if (old_view)
+ gtk_container_remove(GTK_CONTAINER(priv->stack_account), old_view);
+}
+
+static void
+export_account(AccountView* self)
+{
+ g_return_if_fail(IS_ACCOUNT_VIEW(self));
+ AccountViewPrivate *priv = ACCOUNT_VIEW_GET_PRIVATE(self);
+
+ auto selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->treeview_account_list));
+ auto idx = get_index_from_selection(selection);
+ if (idx.isValid()) {
+ auto old_view = gtk_stack_get_visible_child(GTK_STACK(priv->stack_account));
+
+ auto account = AccountModel::instance().getAccountByModelIndex(idx);
+ auto export_account = account_export_view_new();
+ g_signal_connect_swapped(export_account, "import-export-canceled", G_CALLBACK(close_import_export_view), self);
+ g_signal_connect_swapped(export_account, "import-export-completed", G_CALLBACK(close_import_export_view), self);
+ GList *account_list = nullptr;
+ account_list = g_list_append(account_list, account);
+ account_export_view_set_accounts(ACCOUNT_IMPORTEXPORT_VIEW(export_account), account_list);
+ g_list_free(account_list);
+ auto scrolled_view = create_scrolled_account_view(export_account);
+ gtk_widget_show_all(scrolled_view);
+ gtk_stack_add_named(GTK_STACK(priv->stack_account), scrolled_view, "export_account");
+ gtk_stack_set_visible_child(GTK_STACK(priv->stack_account), scrolled_view);
+
+ /* remove the old view */
+ if (old_view)
+ gtk_container_remove(GTK_CONTAINER(priv->stack_account), old_view);
+
+ }
+
+}
+
+static void
account_view_init(AccountView *view)
{
gtk_widget_init_template(GTK_WIDGET(view));
@@ -474,6 +555,10 @@
/* connect signals to add/remove accounts */
g_signal_connect(priv->button_remove_account, "clicked", G_CALLBACK(remove_account), view);
g_signal_connect(priv->button_add_account, "clicked", G_CALLBACK(add_account), view);
+
+ /* signals to import/export acounts */
+ g_signal_connect_swapped(priv->button_import_account, "clicked", G_CALLBACK(import_account), view);
+ g_signal_connect_swapped(priv->button_export_account, "clicked", G_CALLBACK(export_account), view);
}
static void
@@ -490,6 +575,8 @@
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountView, button_remove_account);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountView, button_add_account);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountView, combobox_account_type);
+ gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountView, button_import_account);
+ gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountView, button_export_account);
}
GtkWidget *