summaryrefslogtreecommitdiff
path: root/pidgin
diff options
context:
space:
mode:
Diffstat (limited to 'pidgin')
-rw-r--r--pidgin/pidginaccounteditor.c159
-rw-r--r--pidgin/pidginaccounteditor.h40
-rw-r--r--pidgin/pidginaccountmanager.c105
-rw-r--r--pidgin/pidginaccountmanager.h22
-rw-r--r--pidgin/pidginapplication.c42
-rw-r--r--pidgin/resources/Accounts/editor.ui328
-rw-r--r--pidgin/resources/Accounts/manager.ui155
7 files changed, 545 insertions, 306 deletions
diff --git a/pidgin/pidginaccounteditor.c b/pidgin/pidginaccounteditor.c
index 8824e10ff1..aaa87ee58b 100644
--- a/pidgin/pidginaccounteditor.c
+++ b/pidgin/pidginaccounteditor.c
@@ -29,10 +29,12 @@
#include "pidginprotocolchooser.h"
struct _PidginAccountEditor {
- GtkDialog parent;
+ AdwPreferencesPage parent;
PurpleAccount *account;
+ gboolean valid;
+
/* Login Options */
GtkWidget *login_options;
GtkWidget *protocol;
@@ -71,6 +73,7 @@ struct _PidginAccountEditor {
enum {
PROP_0,
PROP_ACCOUNT,
+ PROP_VALID,
N_PROPERTIES,
};
static GParamSpec *properties[N_PROPERTIES] = {NULL, };
@@ -86,6 +89,17 @@ static void pidgin_account_editor_connection_changed_cb(GObject *obj,
* Helpers
*****************************************************************************/
static void
+pidgin_account_editor_set_valid(PidginAccountEditor *editor, gboolean valid) {
+ g_return_if_fail(PIDGIN_IS_ACCOUNT_EDITOR(editor));
+
+ if(editor->valid != valid) {
+ editor->valid = valid;
+
+ g_object_notify_by_pspec(G_OBJECT(editor), properties[PROP_VALID]);
+ }
+}
+
+static void
pidgin_account_editor_add_user_split(gpointer data, gpointer user_data) {
PurpleAccountUserSplit *split = data;
PidginAccountEditor *editor = user_data;
@@ -652,8 +666,7 @@ pidgin_account_editor_update(PidginAccountEditor *editor) {
pidgin_account_editor_update_advanced_options(editor, protocol);
pidgin_account_editor_update_proxy_options(editor);
- gtk_dialog_set_response_sensitive(GTK_DIALOG(editor), GTK_RESPONSE_APPLY,
- sensitive);
+ pidgin_account_editor_set_valid(editor, sensitive);
}
static void
@@ -706,23 +719,6 @@ pidgin_account_editor_login_options_update_editable(PidginAccountEditor *editor)
gtk_widget_set_sensitive(editor->require_password, editable);
}
-static void
-pidgin_account_editor_set_account(PidginAccountEditor *editor,
- PurpleAccount *account)
-{
- if(g_set_object(&editor->account, account)) {
- if(PURPLE_IS_ACCOUNT(account)) {
- g_signal_connect_object(account, "notify::connection",
- G_CALLBACK(pidgin_account_editor_connection_changed_cb),
- editor, 0);
- }
-
- g_object_notify_by_pspec(G_OBJECT(editor), properties[PROP_ACCOUNT]);
- }
-
- pidgin_account_editor_update(editor);
-}
-
static gboolean
pidgin_account_editor_save_login_options(PidginAccountEditor *editor) {
PurpleProtocol *protocol = NULL;
@@ -912,35 +908,6 @@ pidgin_account_editor_save_proxy(PidginAccountEditor *editor,
purple_proxy_info_set_password(info, svalue);
}
-static void
-pidgin_account_editor_save_account(PidginAccountEditor *editor) {
- gboolean new_account = FALSE;
-
- new_account = pidgin_account_editor_save_login_options(editor);
- pidgin_account_editor_save_user_options(editor);
- pidgin_account_editor_save_advanced_options(editor);
- pidgin_account_editor_save_proxy(editor, new_account);
-
- /* If this is a new account, add it to the account manager and bring it
- * online.
- */
- if(new_account) {
- PurpleAccountManager *manager = NULL;
- const PurpleSavedStatus *saved_status;
-
- manager = purple_account_manager_get_default();
-
- purple_account_manager_add(manager, editor->account);
-
- saved_status = purple_savedstatus_get_current();
- if (saved_status != NULL) {
- purple_savedstatus_activate_for_account(saved_status,
- editor->account);
- purple_account_set_enabled(editor->account, TRUE);
- }
- }
-}
-
/******************************************************************************
* Callbacks
*****************************************************************************/
@@ -959,7 +926,7 @@ pidgin_account_editor_response_cb(GtkDialog *dialog, gint response_id,
G_GNUC_UNUSED gpointer data)
{
if(response_id == GTK_RESPONSE_APPLY) {
- pidgin_account_editor_save_account(PIDGIN_ACCOUNT_EDITOR(dialog));
+ pidgin_account_editor_save(PIDGIN_ACCOUNT_EDITOR(dialog));
}
gtk_window_destroy(GTK_WINDOW(dialog));
@@ -983,8 +950,7 @@ pidgin_account_editor_username_changed_cb(GtkEditable *self, gpointer data) {
sensitive = TRUE;
}
- gtk_dialog_set_response_sensitive(GTK_DIALOG(editor), GTK_RESPONSE_APPLY,
- sensitive);
+ pidgin_account_editor_set_valid(editor, sensitive);
}
static void
@@ -1103,7 +1069,8 @@ pidgin_account_editor_proxy_type_changed_cb(G_GNUC_UNUSED GObject *obj,
/******************************************************************************
* GObject Implementation
*****************************************************************************/
-G_DEFINE_TYPE(PidginAccountEditor, pidgin_account_editor, GTK_TYPE_DIALOG)
+G_DEFINE_TYPE(PidginAccountEditor, pidgin_account_editor,
+ ADW_TYPE_PREFERENCES_PAGE)
static void
pidgin_account_editor_get_property(GObject *obj, guint param_id, GValue *value,
@@ -1116,6 +1083,10 @@ pidgin_account_editor_get_property(GObject *obj, guint param_id, GValue *value,
g_value_set_object(value,
pidgin_account_editor_get_account(editor));
break;
+ case PROP_VALID:
+ g_value_set_boolean(value,
+ pidgin_account_editor_get_is_valid(editor));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
break;
@@ -1208,7 +1179,19 @@ pidgin_account_editor_class_init(PidginAccountEditorClass *klass) {
"account", "account",
"The account to modify",
PURPLE_TYPE_ACCOUNT,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * PidginAccountEditor::valid:
+ *
+ * Whether or not the account settings are valid and it is okay to save the
+ * account.
+ */
+ properties[PROP_VALID] = g_param_spec_boolean(
+ "valid", "valid",
+ "Whether or not the account settings are valid",
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
@@ -1293,3 +1276,71 @@ pidgin_account_editor_get_account(PidginAccountEditor *editor) {
return editor->account;
}
+
+void
+pidgin_account_editor_set_account(PidginAccountEditor *editor,
+ PurpleAccount *account)
+{
+ g_return_if_fail(PIDGIN_IS_ACCOUNT_EDITOR(editor));
+
+ /* Disconnect the notify handler from the previous account. */
+ if(PURPLE_IS_ACCOUNT(editor->account)) {
+ g_signal_handlers_disconnect_by_func(editor->account,
+ G_CALLBACK(pidgin_account_editor_connection_changed_cb),
+ editor);
+ }
+
+ if(g_set_object(&editor->account, account)) {
+ if(PURPLE_IS_ACCOUNT(account)) {
+ pidgin_protocol_chooser_set_protocol(PIDGIN_PROTOCOL_CHOOSER(editor->protocol),
+ purple_account_get_protocol(editor->account));
+
+ g_signal_connect_object(account, "notify::connection",
+ G_CALLBACK(pidgin_account_editor_connection_changed_cb),
+ editor, 0);
+ }
+
+ g_object_notify_by_pspec(G_OBJECT(editor), properties[PROP_ACCOUNT]);
+ }
+
+ pidgin_account_editor_update(editor);
+}
+
+gboolean
+pidgin_account_editor_get_is_valid(PidginAccountEditor *editor) {
+ g_return_val_if_fail(PIDGIN_IS_ACCOUNT_EDITOR(editor), FALSE);
+
+ return editor->valid;
+}
+
+void
+pidgin_account_editor_save(PidginAccountEditor *editor) {
+ gboolean new_account = FALSE;
+
+ g_return_if_fail(PIDGIN_IS_ACCOUNT_EDITOR(editor));
+ g_return_if_fail(editor->valid == TRUE);
+
+ new_account = pidgin_account_editor_save_login_options(editor);
+ pidgin_account_editor_save_user_options(editor);
+ pidgin_account_editor_save_advanced_options(editor);
+ pidgin_account_editor_save_proxy(editor, new_account);
+
+ /* If this is a new account, add it to the account manager and bring it
+ * online.
+ */
+ if(new_account) {
+ PurpleAccountManager *manager = NULL;
+ const PurpleSavedStatus *saved_status;
+
+ manager = purple_account_manager_get_default();
+
+ purple_account_manager_add(manager, editor->account);
+
+ saved_status = purple_savedstatus_get_current();
+ if(saved_status != NULL) {
+ purple_savedstatus_activate_for_account(saved_status,
+ editor->account);
+ purple_account_set_enabled(editor->account, TRUE);
+ }
+ }
+}
diff --git a/pidgin/pidginaccounteditor.h b/pidgin/pidginaccounteditor.h
index f37ebabeb8..50bf55bc00 100644
--- a/pidgin/pidginaccounteditor.h
+++ b/pidgin/pidginaccounteditor.h
@@ -29,6 +29,8 @@
#include <gtk/gtk.h>
+#include <adwaita.h>
+
#include <purple.h>
/**
@@ -43,7 +45,7 @@ G_BEGIN_DECLS
#define PIDGIN_TYPE_ACCOUNT_EDITOR pidgin_account_editor_get_type()
G_DECLARE_FINAL_TYPE(PidginAccountEditor, pidgin_account_editor, PIDGIN,
- ACCOUNT_EDITOR, GtkDialog)
+ ACCOUNT_EDITOR, AdwPreferencesPage)
/**
* pidgin_account_editor_new:
@@ -70,6 +72,42 @@ GtkWidget *pidgin_account_editor_new(PurpleAccount *account);
*/
PurpleAccount *pidgin_account_editor_get_account(PidginAccountEditor *editor);
+/**
+ * pidgin_account_editor_set_account:
+ * @editor: The instance.
+ * @account: (nullable): The new account to edit.
+ *
+ * Sets the account that @editor is editing to @account. You can pass %NULL
+ * to remove the current account or edit a new account.
+ *
+ * Since: 3.0.0
+ */
+void pidgin_account_editor_set_account(PidginAccountEditor *editor, PurpleAccount *account);
+
+/**
+ * pidgin_account_editor_get_is_valid:
+ * @editor: The instance.
+ *
+ * Gets whether or not the settings for the account is valid and can be saved.
+ *
+ * Returns: %TRUE if the account being edited has valid values, otherwise
+ * %FALSE.
+ *
+ * Since: 3.0.0
+ */
+gboolean pidgin_account_editor_get_is_valid(PidginAccountEditor *editor);
+
+/**
+ * pidgin_account_editor_save:
+ * @editor: The instance.
+ *
+ * Save the account to disk. If this is a new account, it will be set to match
+ * the current global status which is "online" in most cases.
+ *
+ * Since: 3.0.0
+ */
+void pidgin_account_editor_save(PidginAccountEditor *editor);
+
G_END_DECLS
#endif /* PIDGIN_ACCOUNT_EDITOR_H */
diff --git a/pidgin/pidginaccountmanager.c b/pidgin/pidginaccountmanager.c
index 4162d8a617..ca036d875c 100644
--- a/pidgin/pidginaccountmanager.c
+++ b/pidgin/pidginaccountmanager.c
@@ -36,6 +36,15 @@ struct _PidginAccountManager {
GtkListBox *list_box;
GtkWidget *add;
+
+ GtkWidget *stack;
+ GtkWidget *editor;
+
+ /* This is used to not go back to the manager when an account was edited
+ * directly, via the `accounts->(account)->edit` menu or the
+ * `connection error` notification.
+ */
+ gboolean edit_only;
};
enum {
@@ -59,16 +68,32 @@ pidgin_account_manager_create_widget(gpointer item,
}
static void
-pidgin_account_manager_create_account(PidginAccountManager *manager) {
- GtkWidget *editor = pidgin_account_editor_new(NULL);
- gtk_window_set_transient_for(GTK_WINDOW(editor),
- GTK_WINDOW(manager));
- gtk_window_present_with_time(GTK_WINDOW(editor), GDK_CURRENT_TIME);
+pidgin_account_manager_real_edit_account(PidginAccountManager *manager,
+ PurpleAccount *account,
+ gboolean edit_only)
+{
+ g_return_if_fail(PIDGIN_IS_ACCOUNT_MANAGER(manager));
+
+ manager->edit_only = edit_only;
+
+ pidgin_account_editor_set_account(PIDGIN_ACCOUNT_EDITOR(manager->editor),
+ account);
+
+ gtk_stack_set_visible_child_name(GTK_STACK(manager->stack), "editor-page");
}
/******************************************************************************
* Callbacks
*****************************************************************************/
+/* This is used by the add button on the placeholder page. */
+static void
+pidgin_account_manager_create_account(G_GNUC_UNUSED GtkButton *self,
+ gpointer data)
+{
+ PidginAccountManager *manager = data;
+
+ pidgin_account_manager_real_edit_account(manager, NULL, FALSE);
+}
static void
pidgin_account_manager_refresh_add_cb(GListModel *list,
@@ -92,7 +117,7 @@ pidgin_account_manager_response_cb(GtkDialog *dialog, gint response_id,
switch(response_id) {
case RESPONSE_ADD:
- pidgin_account_manager_create_account(manager);
+ pidgin_account_manager_real_edit_account(manager, NULL, FALSE);
break;
case GTK_RESPONSE_CLOSE:
case GTK_RESPONSE_DELETE_EVENT:
@@ -106,14 +131,49 @@ pidgin_account_manager_response_cb(GtkDialog *dialog, gint response_id,
static void
pidgin_account_manager_row_activated_cb(G_GNUC_UNUSED GtkListBox *box,
GtkListBoxRow *row,
- G_GNUC_UNUSED gpointer data)
+ gpointer data)
{
- GtkWidget *editor = NULL;
PurpleAccount *account = NULL;
+ PidginAccountManager *manager = data;
account = pidgin_account_row_get_account(PIDGIN_ACCOUNT_ROW(row));
- editor = pidgin_account_editor_new(account);
- gtk_widget_show(editor);
+
+ pidgin_account_manager_real_edit_account(manager, account, FALSE);
+}
+
+static void
+pidgin_account_manager_back_clicked_cb(G_GNUC_UNUSED GtkButton *self,
+ gpointer data)
+{
+ PidginAccountManager *manager = data;
+
+#if ADW_CHECK_VERSION(1, 3, 0)
+ /* Scroll the editor back to the top of the scrolled window. */
+ adw_preferences_page_scroll_to_top(ADW_PREFERENCES_PAGE(manager->editor));
+#endif
+
+ /* Disconnect the account which will remove all of the account options as
+ * well.
+ */
+ pidgin_account_editor_set_account(PIDGIN_ACCOUNT_EDITOR(manager->editor),
+ NULL);
+
+ pidgin_account_manager_show_overview(manager);
+}
+
+static void
+pidgin_account_manager_save_clicked_cb(G_GNUC_UNUSED GtkButton *self,
+ gpointer data)
+{
+ PidginAccountManager *manager = data;
+
+ pidgin_account_editor_save(PIDGIN_ACCOUNT_EDITOR(manager->editor));
+
+ if(manager->edit_only) {
+ gtk_window_destroy(GTK_WINDOW(manager));
+ } else {
+ gtk_stack_set_visible_child_name(GTK_STACK(manager->stack), "overview");
+ }
}
/******************************************************************************
@@ -147,6 +207,10 @@ pidgin_account_manager_class_init(PidginAccountManagerClass *klass) {
list_box);
gtk_widget_class_bind_template_child(widget_class, PidginAccountManager,
add);
+ gtk_widget_class_bind_template_child(widget_class, PidginAccountManager,
+ stack);
+ gtk_widget_class_bind_template_child(widget_class, PidginAccountManager,
+ editor);
gtk_widget_class_bind_template_callback(widget_class,
pidgin_account_manager_response_cb);
@@ -154,6 +218,10 @@ pidgin_account_manager_class_init(PidginAccountManagerClass *klass) {
pidgin_account_manager_row_activated_cb);
gtk_widget_class_bind_template_callback(widget_class,
pidgin_account_manager_create_account);
+ gtk_widget_class_bind_template_callback(widget_class,
+ pidgin_account_manager_back_clicked_cb);
+ gtk_widget_class_bind_template_callback(widget_class,
+ pidgin_account_manager_save_clicked_cb);
}
/******************************************************************************
@@ -163,3 +231,20 @@ GtkWidget *
pidgin_account_manager_new(void) {
return g_object_new(PIDGIN_TYPE_ACCOUNT_MANAGER, NULL);
}
+
+void
+pidgin_account_manager_show_overview(PidginAccountManager *manager) {
+ g_return_if_fail(PIDGIN_IS_ACCOUNT_MANAGER(manager));
+
+ gtk_stack_set_visible_child_name(GTK_STACK(manager->stack), "overview");
+}
+
+void
+pidgin_account_manager_edit_account(PidginAccountManager *manager,
+ PurpleAccount *account)
+{
+ g_return_if_fail(PIDGIN_IS_ACCOUNT_MANAGER(manager));
+ g_return_if_fail(PURPLE_IS_ACCOUNT(account));
+
+ pidgin_account_manager_real_edit_account(manager, account, TRUE);
+}
diff --git a/pidgin/pidginaccountmanager.h b/pidgin/pidginaccountmanager.h
index 84fca9ea9e..6f757b65b6 100644
--- a/pidgin/pidginaccountmanager.h
+++ b/pidgin/pidginaccountmanager.h
@@ -54,6 +54,28 @@ G_DECLARE_FINAL_TYPE(PidginAccountManager, pidgin_account_manager, PIDGIN,
*/
GtkWidget *pidgin_account_manager_new(void);
+/**
+ * pidgin_account_managet_show_overview:
+ * @manager: The instance.
+ *
+ * Switches @manager to the overview page. This is useful as @manager might
+ * already be visible but editing an account.
+ *
+ * Since: 3.0.0
+ */
+void pidgin_account_manager_show_overview(PidginAccountManager *manager);
+
+/**
+ * pidgin_account_manager_edit_account:
+ * @manager: The instance.
+ * @account: The account to edit.
+ *
+ * Opens the account editor in @manager for the given account.
+ *
+ * Since: 3.0.0
+ */
+void pidgin_account_manager_edit_account(PidginAccountManager *manager, PurpleAccount *account);
+
G_END_DECLS
#endif /* PIDGIN_ACCOUNT_MANAGER_H */
diff --git a/pidgin/pidginapplication.c b/pidgin/pidginapplication.c
index 603f2e7e6e..177f67ae84 100644
--- a/pidgin/pidginapplication.c
+++ b/pidgin/pidginapplication.c
@@ -95,6 +95,26 @@ G_DEFINE_TYPE(PidginApplication, pidgin_application, GTK_TYPE_APPLICATION)
*****************************************************************************/
/*
+ * pidgin_application_get_account_manager:
+ *
+ * The Pidgin account manager can get opened from multiple actions, so this
+ * helper manages the singleton.
+ *
+ * Since: 3.0.0
+ */
+static GtkWidget *
+pidgin_application_get_account_manager(void) {
+ static GtkWidget *manager = NULL;
+
+ if(!PIDGIN_IS_ACCOUNT_MANAGER(manager)) {
+ manager = pidgin_account_manager_new();
+ g_object_add_weak_pointer(G_OBJECT(manager), (gpointer)&manager);
+ }
+
+ return manager;
+}
+
+/*
* pidgin_application_present_transient_window:
* @application: The application instance.
* @window: The [class@Gtk.Window] to present.
@@ -275,12 +295,9 @@ pidgin_application_accounts(G_GNUC_UNUSED GSimpleAction *simple,
G_GNUC_UNUSED GVariant *parameter, gpointer data)
{
PidginApplication *application = data;
- static GtkWidget *manager = NULL;
+ GtkWidget *manager = pidgin_application_get_account_manager();
- if(!GTK_IS_WIDGET(manager)) {
- manager = pidgin_account_manager_new();
- g_object_add_weak_pointer(G_OBJECT(manager), (gpointer)&manager);
- }
+ pidgin_account_manager_show_overview(PIDGIN_ACCOUNT_MANAGER(manager));
pidgin_application_present_transient_window(application,
GTK_WINDOW(manager));
@@ -377,16 +394,27 @@ pidgin_application_edit_account(G_GNUC_UNUSED GSimpleAction *simple,
PurpleAccountManager *manager = NULL;
const gchar *id = NULL;
+ if(!g_variant_is_of_type(parameter, G_VARIANT_TYPE_STRING)) {
+ g_warning("parameter is of type %s, expected %s",
+ g_variant_get_type_string(parameter),
+ (char *)G_VARIANT_TYPE_STRING);
+
+ return;
+ }
+
id = g_variant_get_string(parameter, NULL);
manager = purple_account_manager_get_default();
account = purple_account_manager_find_by_id(manager, id);
if(PURPLE_IS_ACCOUNT(account)) {
- GtkWidget *editor = pidgin_account_editor_new(account);
+ GtkWidget *account_manager = pidgin_application_get_account_manager();
+
+ pidgin_account_manager_edit_account(PIDGIN_ACCOUNT_MANAGER(account_manager),
+ account);
pidgin_application_present_transient_window(application,
- GTK_WINDOW(editor));
+ GTK_WINDOW(account_manager));
}
}
diff --git a/pidgin/resources/Accounts/editor.ui b/pidgin/resources/Accounts/editor.ui
index 5b93fb81e1..f89d0c8f0b 100644
--- a/pidgin/resources/Accounts/editor.ui
+++ b/pidgin/resources/Accounts/editor.ui
@@ -26,195 +26,181 @@ along with this program; if not, see <https://www.gnu.org/licenses/>.
<!-- interface-name Pidgin -->
<!-- interface-description Internet Messenger -->
<!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
- <template class="PidginAccountEditor" parent="GtkDialog">
- <property name="resizable">0</property>
- <property name="default-height">600</property>
- <property name="default-width">400</property>
- <property name="title" translatable="1">Edit Account</property>
- <signal name="response" handler="pidgin_account_editor_response_cb" swapped="no"/>
- <child internal-child="content_area">
- <object class="GtkBox">
- <property name="vexpand">1</property>
+ <template class="PidginAccountEditor" parent="AdwPreferencesPage">
+ <property name="vexpand">1</property>
+ <property name="hexpand">1</property>
+ <child>
+ <object class="AdwPreferencesGroup" id="login_options">
+ <property name="title" translatable="1">Login Options</property>
<child>
- <object class="AdwPreferencesPage">
- <property name="vexpand">1</property>
- <property name="hexpand">1</property>
+ <object class="PidginProtocolChooser" id="protocol">
+ <property name="title" translatable="1">Pro_tocol</property>
+ <property name="use-underline">1</property>
+ <signal name="notify::protocol" handler="pidgin_account_editor_protocol_changed_cb" object="PidginAccountEditor" swapped="no"/>
+ </object>
+ </child>
+ <child>
+ <object class="AdwPreferencesRow">
+ <property name="focusable">0</property>
<child>
- <object class="AdwPreferencesGroup" id="login_options">
- <property name="title" translatable="1">Login Options</property>
- <child>
- <object class="PidginProtocolChooser" id="protocol">
- <property name="title" translatable="1">Pro_tocol</property>
- <property name="use-underline">1</property>
- <signal name="notify::protocol" handler="pidgin_account_editor_protocol_changed_cb" object="PidginAccountEditor" swapped="no"/>
- </object>
- </child>
+ <object class="GtkListBox" id="user_splits">
+ <property name="focusable">0</property>
<child>
- <object class="AdwPreferencesRow">
+ <object class="AdwEntryRow" id="username">
<property name="focusable">0</property>
- <child>
- <object class="GtkListBox" id="user_splits">
- <property name="focusable">0</property>
- <child>
- <object class="AdwEntryRow" id="username">
- <property name="focusable">0</property>
- <property name="title" translatable="1">_Username</property>
- <property name="use-underline">1</property>
- <signal name="changed" handler="pidgin_account_editor_username_changed_cb" object="PidginAccountEditor" swapped="no"/>
- </object>
- </child>
- </object>
- </child>
+ <property name="title" translatable="1">_Username</property>
+ <property name="use-underline">1</property>
+ <signal name="changed" handler="pidgin_account_editor_username_changed_cb" object="PidginAccountEditor" swapped="no"/>
</object>
</child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="AdwActionRow" id="require_password_row">
+ <property name="activatable-widget">avatar</property>
+ <property name="focusable">0</property>
+ <property name="title" translatable="1">Require _password</property>
+ <property name="subtitle" translatable="1">This account has an optional password, setting this will make it required</property>
+ <property name="use-underline">1</property>
+ <property name="visible">0</property>
+ <child type="suffix">
+ <object class="GtkSwitch" id="require_password">
+ <property name="valign">center</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="AdwPreferencesGroup">
+ <property name="title" translatable="1">User Options</property>
+ <child>
+ <object class="AdwEntryRow" id="alias">
+ <property name="focusable">0</property>
+ <property name="title" translatable="1">_Local alias</property>
+ <property name="use-underline">1</property>
+ </object>
+ </child>
+ <child>
+ <object class="AdwActionRow" id="avatar_row">
+ <property name="activatable-widget">avatar</property>
+ <property name="focusable">0</property>
+ <property name="title" translatable="1">Use custom _avatar</property>
+ <property name="use-underline">1</property>
+ <property name="visible">0</property>
+ <child type="prefix">
+ <object class="GtkSwitch" id="use_custom_avatar">
+ <property name="valign">center</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="css-classes">flat</property>
+ <property name="valign">center</property>
+ <binding name="sensitive">
+ <lookup name="active">use_custom_avatar</lookup>
+ </binding>
<child>
- <object class="AdwActionRow" id="require_password_row">
- <property name="activatable-widget">avatar</property>
- <property name="focusable">0</property>
- <property name="title" translatable="1">Require _password</property>
- <property name="subtitle" translatable="1">This account has an optional password, setting this will make it required</property>
- <property name="use-underline">1</property>
- <property name="visible">0</property>
- <child type="suffix">
- <object class="GtkSwitch" id="require_password">
- <property name="valign">center</property>
- </object>
- </child>
+ <object class="GtkImage" id="avatar">
+ <property name="icon-name">select-avatar</property>
+ <property name="icon-size">large</property>
</object>
</child>
+ <signal name="clicked" handler="pidgin_account_editor_avatar_set_clicked_cb" object="PidginAccountEditor" swapped="no"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="remove">
+ <property name="label" translatable="1">_Remove</property>
+ <property name="use-underline">1</property>
+ <property name="valign">center</property>
+ <binding name="sensitive">
+ <lookup name="active">use_custom_avatar</lookup>
+ </binding>
+ <signal name="clicked" handler="pidgin_account_editor_avatar_remove_clicked_cb" object="PidginAccountEditor" swapped="no"/>
</object>
</child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="AdwPreferencesGroup" id="advanced_group">
+ <property name="title" translatable="1">Advanced Options</property>
+ <property name="description" translatable="1">Additional options for this account.</property>
+ <property name="visible">0</property>
+ <child type="header-suffix">
+ <object class="GtkSwitch" id="advanced_toggle">
+ <property name="active">0</property>
+ <property name="valign">center</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="AdwPreferencesGroup">
+ <property name="title" translatable="1">Proxy</property>
+ <child>
+ <object class="AdwComboRow" id="proxy_type">
+ <property name="title" translatable="1">Proxy t_ype</property>
+ <property name="use-underline">1</property>
+ <property name="use-subtitle">1</property>
+ <property name="model">
+ <object class="GtkStringList">
+ <items>
+ <item>global</item>
+ <item>none</item>
+ <item>socks4</item>
+ <item>socks5</item>
+ <item>tor</item>
+ <item>http</item>
+ <item>envvar</item>
+ </items>
+ </object>
+ </property>
+ <property name="expression">
+ <closure type="gchararray" function="pidgin_account_editor_proxy_type_expression_cb"/>
+ </property>
+ <signal name="notify::selected" handler="pidgin_account_editor_proxy_type_changed_cb" object="PidginAccountEditor" swapped="no"/>
+ </object>
+ </child>
+ <child>
+ <object class="AdwPreferencesRow" id="proxy_options">
+ <property name="focusable">0</property>
+ <property name="visible">0</property>
<child>
- <object class="AdwPreferencesGroup">
- <property name="title" translatable="1">User Options</property>
+ <object class="GtkListBox">
+ <property name="focusable">0</property>
<child>
- <object class="AdwEntryRow" id="alias">
+ <object class="AdwEntryRow" id="proxy_host">
<property name="focusable">0</property>
- <property name="title" translatable="1">_Local alias</property>
+ <property name="title" translatable="1">_Host</property>
<property name="use-underline">1</property>
</object>
</child>
<child>
- <object class="AdwActionRow" id="avatar_row">
- <property name="activatable-widget">avatar</property>
+ <object class="AdwEntryRow" id="proxy_port">
<property name="focusable">0</property>
- <property name="title" translatable="1">Use custom _avatar</property>
+ <property name="title" translatable="1">P_ort</property>
<property name="use-underline">1</property>
- <property name="visible">0</property>
- <child type="prefix">
- <object class="GtkSwitch" id="use_custom_avatar">
- <property name="valign">center</property>
- </object>
- </child>
- <child>
- <object class="GtkButton">
- <property name="css-classes">flat</property>
- <property name="valign">center</property>
- <binding name="sensitive">
- <lookup name="active">use_custom_avatar</lookup>
- </binding>
- <child>
- <object class="GtkImage" id="avatar">
- <property name="icon-name">select-avatar</property>
- <property name="icon-size">large</property>
- </object>
- </child>
- <signal name="clicked" handler="pidgin_account_editor_avatar_set_clicked_cb" object="PidginAccountEditor" swapped="no"/>
- </object>
- </child>
- <child>
- <object class="GtkButton" id="remove">
- <property name="label" translatable="1">_Remove</property>
- <property name="use-underline">1</property>
- <property name="valign">center</property>
- <binding name="sensitive">
- <lookup name="active">use_custom_avatar</lookup>
- </binding>
- <signal name="clicked" handler="pidgin_account_editor_avatar_remove_clicked_cb" object="PidginAccountEditor" swapped="no"/>
- </object>
- </child>
+ <property name="input-purpose">number</property>
</object>
</child>
- </object>
- </child>
- <child>
- <object class="AdwPreferencesGroup" id="advanced_group">
- <property name="title" translatable="1">Advanced Options</property>
- <property name="description" translatable="1">Additional options for this account.</property>
- <property name="visible">0</property>
- <child type="header-suffix">
- <object class="GtkSwitch" id="advanced_toggle">
- <property name="active">0</property>
- <property name="valign">center</property>
- </object>
- </child>
- </object>
- </child>
- <child>
- <object class="AdwPreferencesGroup">
- <property name="title" translatable="1">Proxy</property>
<child>
- <object class="AdwComboRow" id="proxy_type">
- <property name="title" translatable="1">Proxy t_ype</property>
+ <object class="AdwEntryRow" id="proxy_username">
+ <property name="focusable">0</property>
+ <property name="title" translatable="1">User_name</property>
<property name="use-underline">1</property>
- <property name="use-subtitle">1</property>
- <property name="model">
- <object class="GtkStringList">
- <items>
- <item>global</item>
- <item>none</item>
- <item>socks4</item>
- <item>socks5</item>
- <item>tor</item>
- <item>http</item>
- <item>envvar</item>
- </items>
- </object>
- </property>
- <property name="expression">
- <closure type="gchararray" function="pidgin_account_editor_proxy_type_expression_cb"/>
- </property>
- <signal name="notify::selected" handler="pidgin_account_editor_proxy_type_changed_cb" object="PidginAccountEditor" swapped="no"/>
</object>
</child>
<child>
- <object class="AdwPreferencesRow" id="proxy_options">
+ <object class="AdwPasswordEntryRow" id="proxy_password">
<property name="focusable">0</property>
- <property name="visible">0</property>
- <child>
- <object class="GtkListBox">
- <property name="focusable">0</property>
- <child>
- <object class="AdwEntryRow" id="proxy_host">
- <property name="focusable">0</property>
- <property name="title" translatable="1">_Host</property>
- <property name="use-underline">1</property>
- </object>
- </child>
- <child>
- <object class="AdwEntryRow" id="proxy_port">
- <property name="focusable">0</property>
- <property name="title" translatable="1">P_ort</property>
- <property name="use-underline">1</property>
- <property name="input-purpose">number</property>
- </object>
- </child>
- <child>
- <object class="AdwEntryRow" id="proxy_username">
- <property name="focusable">0</property>
- <property name="title" translatable="1">User_name</property>
- <property name="use-underline">1</property>
- </object>
- </child>
- <child>
- <object class="AdwPasswordEntryRow" id="proxy_password">
- <property name="focusable">0</property>
- <property name="title" translatable="1">Pa_ssword</property>
- <property name="use-underline">1</property>
- </object>
- </child>
- </object>
- </child>
+ <property name="title" translatable="1">Pa_ssword</property>
+ <property name="use-underline">1</property>
</object>
</child>
</object>
@@ -223,25 +209,5 @@ along with this program; if not, see <https://www.gnu.org/licenses/>.
</child>
</object>
</child>
- <child type="action">
- <object class="GtkButton" id="button1">
- <property name="label" translatable="1">_Cancel</property>
- <property name="receives-default">1</property>
- <property name="use-underline">1</property>
- </object>
- </child>
- <child type="action">
- <object class="GtkButton" id="button2">
- <property name="css-classes">suggested-action</property>
- <property name="label" translatable="1">_Save</property>
- <property name="receives-default">1</property>
- <property name="sensitive">0</property>
- <property name="use-underline">1</property>
- </object>
- </child>
- <action-widgets>
- <action-widget response="cancel">button1</action-widget>
- <action-widget response="apply">button2</action-widget>
- </action-widgets>
</template>
</interface>
diff --git a/pidgin/resources/Accounts/manager.ui b/pidgin/resources/Accounts/manager.ui
index 001cdc449e..434a225692 100644
--- a/pidgin/resources/Accounts/manager.ui
+++ b/pidgin/resources/Accounts/manager.ui
@@ -32,64 +32,122 @@ along with this program; if not, see <https://www.gnu.org/licenses/>.
<child internal-child="content_area">
<object class="GtkBox">
<child>
- <object class="GtkScrolledWindow">
- <property name="vexpand">1</property>
- <property name="child">
- <object class="AdwClamp">
- <property name="margin-bottom">24</property>
- <property name="margin-end">24</property>
- <property name="margin-start">24</property>
- <property name="margin-top">24</property>
- <property name="orientation">horizontal</property>
- <child>
- <object class="GtkListBox" id="list_box">
- <property name="css-classes">boxed-list
-rich-list</property>
- <property name="selection-mode">none</property>
- <property name="show-separators">1</property>
- <signal name="row-activated" handler="pidgin_account_manager_row_activated_cb" swapped="no"/>
- <child type="placeholder">
- <object class="GtkBox">
- <property name="margin-bottom">48</property>
- <property name="margin-top">48</property>
- <property name="orientation">vertical</property>
- <property name="spacing">12</property>
- <property name="valign">center</property>
- <property name="vexpand">1</property>
+ <object class="GtkStack" id="stack">
+ <property name="transition-type">slide-left-right</property>
+ <property name="vhomogeneous">0</property>
+ <child>
+ <object class="GtkStackPage">
+ <property name="name">overview</property>
+ <property name="child">
+ <object class="GtkScrolledWindow">
+ <property name="hscrollbar_policy">never</property>
+ <property name="vexpand">1</property>
+ <property name="child">
+ <object class="AdwClamp">
+ <property name="margin-bottom">24</property>
+ <property name="margin-end">24</property>
+ <property name="margin-start">24</property>
+ <property name="margin-top">24</property>
+ <property name="orientation">horizontal</property>
<child>
- <object class="GtkImage">
- <property name="css-classes">dim-label</property>
- <property name="icon-name">view-list-symbolic</property>
- <property name="pixel-size">128</property>
+ <object class="GtkListBox" id="list_box">
+ <property name="css-classes">boxed-list
+ rich-list</property>
+ <property name="selection-mode">none</property>
+ <property name="show-separators">1</property>
+ <signal name="row-activated" handler="pidgin_account_manager_row_activated_cb" swapped="no"/>
+ <child type="placeholder">
+ <object class="GtkBox">
+ <property name="margin-bottom">48</property>
+ <property name="margin-top">48</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <property name="valign">center</property>
+ <property name="vexpand">1</property>
+ <child>
+ <object class="GtkImage">
+ <property name="css-classes">dim-label</property>
+ <property name="icon-name">view-list-symbolic</property>
+ <property name="pixel-size">128</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="css-classes">title-1</property>
+ <property name="label" translatable="1">No Accounts</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="css-classes">pill
+suggested-action</property>
+ <property name="halign">center</property>
+ <signal name="clicked" handler="pidgin_account_manager_create_account"/>
+ <property name="child">
+ <object class="AdwButtonContent">
+ <property name="icon-name">list-add-symbolic</property>
+ <property name="label" translatable="1">_Add…</property>
+ <property name="use-underline">1</property>
+ </object>
+ </property>
+ </object>
+ </child>
+ </object>
+ </child>
</object>
</child>
+ </object>
+ </property>
+ </object>
+ </property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkStackPage">
+ <property name="name">editor-page</property>
+ <property name="child">
+ <object class="GtkBox">
+ <property name="margin-bottom">24</property>
+ <property name="margin-end">24</property>
+ <property name="margin-start">24</property>
+ <property name="margin-top">24</property>
+ <property name="orientation">horizontal</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
<child>
- <object class="GtkLabel">
- <property name="css-classes">title-1</property>
- <property name="label" translatable="1">No Accounts</property>
+ <object class="GtkButton">
+ <property name="css-classes">flat</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="icon-name">go-previous-symbolic</property>
+ <property name="tooltip-text" translatable="1">Back</property>
+ <signal name="clicked" handler="pidgin_account_manager_back_clicked_cb"/>
</object>
</child>
<child>
<object class="GtkButton">
- <property name="css-classes">pill
-suggested-action</property>
- <property name="halign">center</property>
- <signal name="clicked" handler="pidgin_account_manager_create_account" swapped="yes"/>
- <property name="child">
- <object class="AdwButtonContent">
- <property name="icon-name">list-add-symbolic</property>
- <property name="label" translatable="1">_Add…</property>
- <property name="use-underline">1</property>
- </object>
- </property>
+ <property name="css-classes">flat</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="icon-name">document-save-symbolic</property>
+ <property name="tooltip-text" translatable="1">Save</property>
+ <binding name="sensitive">
+ <lookup name="valid">editor</lookup>
+ </binding>
+ <signal name="clicked" handler="pidgin_account_manager_save_clicked_cb"/>
</object>
</child>
</object>
</child>
+ <child>
+ <object class="PidginAccountEditor" id="editor"/>
+ </child>
</object>
- </child>
+ </property>
</object>
- </property>
+ </child>
</object>
</child>
</object>
@@ -108,17 +166,8 @@ suggested-action</property>
</property>
</object>
</child>
- <child type="action">
- <object class="GtkButton" id="button2">
- <property name="label" translatable="1">_Close</property>
- <property name="focusable">1</property>
- <property name="receives-default">1</property>
- <property name="use-underline">1</property>
- </object>
- </child>
<action-widgets>
<action-widget response="0">add</action-widget>
- <action-widget response="close">button2</action-widget>
</action-widgets>
</template>
</interface>