[gnome-terminal] all: New settings list implementation
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-terminal] all: New settings list implementation
- Date: Sat, 9 Feb 2013 14:32:18 +0000 (UTC)
commit 9266b411f01ae1e90045cafd48fcad905c12c644
Author: Christian Persch <chpe gnome org>
Date: Wed Feb 6 20:41:51 2013 +0100
all: New settings list implementation
Split the settings list implementation out into its own class.
configure.ac | 1 +
src/Makefile.am | 30 +-
src/client.c | 24 +-
src/migration.c | 102 ++--
src/org.gnome.Terminal.gschema.xml.in | 28 +-
src/profile-editor.c | 8 +-
src/terminal-app.c | 361 ++------------
src/terminal-app.h | 10 +-
src/terminal-debug.c | 15 +-
src/terminal-debug.h | 15 +-
src/terminal-enums.h | 6 +
src/terminal-gdbus.c | 6 +-
src/terminal-options.c | 24 +-
src/terminal-options.h | 4 +
src/terminal-prefs.c | 84 ++--
src/terminal-profile-utils.c | 276 -----------
src/terminal-profile-utils.h | 43 --
src/terminal-profiles-list.c | 258 ++++++++++
src/terminal-profiles-list.h | 53 ++
src/terminal-schemas.h | 9 +-
src/terminal-settings-list.c | 881 +++++++++++++++++++++++++++++++++
src/terminal-settings-list.h | 74 +++
src/terminal-window.c | 24 +-
23 files changed, 1541 insertions(+), 795 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index cb462c4..ddb482d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -127,6 +127,7 @@ if test "$enable_migration" = "yes"; then
gio-2.0 >= $GIO_REQUIRED
vte$VTE_PC_VERSION >= $VTE_REQUIRED
gconf-2.0 >= $GCONF_REQUIRED
+ dconf >= $DCONF_REQUIRED
uuid])
AC_DEFINE([ENABLE_MIGRATION],[1],[Define to 1 to enable prefs migration from GConf to GSettings])
fi
diff --git a/src/Makefile.am b/src/Makefile.am
index f736f81..da5179c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -52,9 +52,11 @@ gnome_terminal_server_SOURCES = \
terminal-notebook.h \
terminal-prefs.c \
terminal-prefs.h \
- terminal-profile-utils.c \
- terminal-profile-utils.h \
+ terminal-profiles-list.c \
+ terminal-profiles-list.h \
terminal-schemas.h \
+ terminal-settings-list.c \
+ terminal-settings-list.h \
terminal-screen.c \
terminal-screen.h \
terminal-screen-container.c \
@@ -149,16 +151,22 @@ gnome_terminal_client_SOURCES = \
client.c \
terminal-client-utils.c \
terminal-client-utils.h \
+ terminal-debug.c \
+ terminal-debug.h \
terminal-defines.h \
terminal-intl.h \
- terminal-profile-utils.c \
- terminal-profile-utils.h \
+ terminal-profiles-list.c \
+ terminal-profiles-list.h \
terminal-schemas.h \
+ terminal-settings-list.c \
+ terminal-settings-list.h \
$(NULL)
nodist_gnome_terminal_client_SOURCES = \
terminal-gdbus-generated.c \
terminal-gdbus-generated.h \
+ terminal-type-builtins.c \
+ terminal-type-builtins.h \
$(NULL)
gnome_terminal_client_CPPFLAGS = \
@@ -193,14 +201,18 @@ gnome_terminal_SOURCES = \
terminal-intl.h \
terminal-options.c \
terminal-options.h \
- terminal-profile-utils.c \
- terminal-profile-utils.h \
+ terminal-profiles-list.c \
+ terminal-profiles-list.h \
terminal-schemas.h \
+ terminal-settings-list.c \
+ terminal-settings-list.h \
$(NULL)
nodist_gnome_terminal_SOURCES = \
terminal-gdbus-generated.c \
terminal-gdbus-generated.h \
+ terminal-type-builtins.c \
+ terminal-type-builtins.h \
$(NULL)
gnome_terminal_CPPFLAGS = \
@@ -256,7 +268,13 @@ libexec_PROGRAMS += gnome-terminal-migration
gnome_terminal_migration_SOURCES = \
migration.c \
+ terminal-debug.c \
+ terminal-debug.h \
+ terminal-profiles-list.c \
+ terminal-profiles-list.h \
terminal-schemas.h \
+ terminal-settings-list.c \
+ terminal-settings-list.h \
$(NULL)
nodist_gnome_terminal_migration_SOURCES = \
diff --git a/src/client.c b/src/client.c
index 3bd07a1..92be7fd 100644
--- a/src/client.c
+++ b/src/client.c
@@ -44,9 +44,11 @@
#include "terminal-gdbus-generated.h"
#include "terminal-defines.h"
#include "terminal-client-utils.h"
-#include "terminal-profile-utils.h"
+#include "terminal-profiles-list.h"
+#include "terminal-debug.h"
static gboolean quiet = FALSE;
+static TerminalSettingsList *profiles_list = NULL;
static void _printerr (const char *format, ...) G_GNUC_PRINTF (1, 2);
@@ -127,6 +129,15 @@ modify_argv0_for_command (gint *argc, gchar **argv[], const gchar *command)
g_free (program_name);
}
+static TerminalSettingsList *
+ensure_profiles_list (void)
+{
+ if (profiles_list == NULL)
+ profiles_list = terminal_profiles_list_new ();
+
+ return profiles_list;
+}
+
typedef struct
{
char *server_app_id;
@@ -309,7 +320,7 @@ option_profile_cb (const gchar *option_name,
return FALSE;
}
- data->profile = terminal_profile_util_get_profile_by_uuid (value, error);
+ data->profile = terminal_profiles_list_dup_uuid (ensure_profiles_list (), value, error);
return data->profile != NULL;
}
@@ -748,9 +759,9 @@ complete (int *argcp,
{
char **profiles, **p;
- profiles = terminal_profile_util_list_profiles ();
+ profiles = terminal_settings_list_dupv_children (ensure_profiles_list ());
if (profiles == NULL)
- return FALSE;
+ return TRUE;
for (p = profiles; *p; p++)
g_print ("%s\n", *p);
@@ -790,6 +801,8 @@ main (gint argc, gchar *argv[])
g_type_init ();
#endif
+ _terminal_debug_init ();
+
ret = EXIT_FAILURE;
if (argc < 2)
@@ -827,5 +840,8 @@ main (gint argc, gchar *argv[])
}
out:
+
+ g_clear_object (&profiles_list);
+
return ret;
}
diff --git a/src/migration.c b/src/migration.c
index ee6b53f..1e3ae19 100644
--- a/src/migration.c
+++ b/src/migration.c
@@ -24,17 +24,21 @@
#include <glib.h>
#include <glib/gi18n.h>
#include <gconf/gconf-client.h>
+#include <dconf.h>
#include <vte/vte.h>
-#include <uuid.h>
#include "terminal-schemas.h"
+#include "terminal-profiles-list.h"
#include "terminal-type-builtins.h"
+#include "terminal-debug.h"
+static gboolean clean = FALSE;
static gboolean dry_run = FALSE;
static gboolean force = FALSE;
static gboolean verbose = FALSE;
static const GOptionEntry options[] = {
+ { "clean", 0, 0, G_OPTION_ARG_NONE, &clean, NULL, NULL },
{ "dry-run", 0, 0, G_OPTION_ARG_NONE, &dry_run, NULL, NULL },
{ "force", 0, 0, G_OPTION_ARG_NONE, &force, NULL, NULL },
{ "verbose", 0, 0, G_OPTION_ARG_NONE, &verbose, NULL, NULL },
@@ -43,6 +47,8 @@ static const GOptionEntry options[] = {
#define ERROR_DOMAIN (g_intern_static_string ("gnome-terminal-migration-error"))
+#define TERMINAL_PATH_PREFIX "/org/gnome/terminal/"
+
enum {
ERROR_GENERIC
};
@@ -306,28 +312,42 @@ migrate_global_prefs (GSettings *settings,
return TRUE;
}
-static char *
-migrate_profile (GConfClient *client,
- GSettings *global_settings,
+static void
+do_clean (void)
+{
+ DConfClient *client;
+
+ if (verbose)
+ g_printerr ("Cleaning...\n");
+
+#ifdef HAVE_DCONF_1_2
+ client = dconf_client_new (NULL, NULL, NULL, NULL);
+ dconf_client_write (client, TERMINAL_PATH_PREFIX, NULL, NULL, NULL, NULL);
+#else /* modern DConf */
+ client = dconf_client_new ();
+ dconf_client_write_sync (client, TERMINAL_PATH_PREFIX, NULL, NULL, NULL, NULL);
+#endif
+ g_object_unref (client);
+}
+
+static void
+migrate_profile (TerminalSettingsList *list,
+ GConfClient *client,
const char *gconf_id,
- gboolean is_default)
+ const char *default_gconf_id)
{
GSettings *settings;
- char *path;
+ char *child_name, *path;
const char *name;
- uuid_t u;
- char str[37];
-
- uuid_generate (u);
- uuid_unparse (u, str);
-
- path = g_strdup_printf (TERMINAL_PROFILES_PATH_PREFIX ":%s/", str);
- if (verbose)
- g_printerr ("Migrating profile \"%s\" to \"%s\" is-default %s\n",
- gconf_id, path, is_default ? "true" : "false");
- settings = g_settings_new_with_path (TERMINAL_PROFILE_SCHEMA, path);
- g_free (path);
+ if (g_strcmp0 (gconf_id, default_gconf_id) == 0) {
+ /* Re-use the default list child */
+ settings = terminal_settings_list_ref_default_child (list);
+ } else {
+ child_name = terminal_settings_list_add_child (list);
+ settings = terminal_settings_list_ref_child (list, child_name);
+ g_free (child_name);
+ }
path = gconf_concat_dir_and_key (GCONF_PROFILES_PREFIX, gconf_id);
@@ -422,26 +442,20 @@ migrate_profile (GConfClient *client,
g_free (path);
g_object_unref (settings);
-
- return g_strdup (str);
}
static gboolean
migrate_profiles (GSettings *global_settings,
GError **error)
{
+ TerminalSettingsList *list;
GConfClient *client;
GConfValue *value, *dvalue;
GSList *l;
- GPtrArray *profile_uuids;
- char *uuid;
- const char *profile, *default_profile, *default_uuid;
- gboolean is_default;
+ const char *default_profile;
client = gconf_client_get_default ();
- profile_uuids = g_ptr_array_new_with_free_func ((GDestroyNotify) g_free);
-
dvalue = gconf_client_get (client, GCONF_GLOBAL_PREFIX "/default_profile", NULL);
if (dvalue != NULL &&
dvalue->type == GCONF_VALUE_STRING)
@@ -449,19 +463,16 @@ migrate_profiles (GSettings *global_settings,
else
default_profile = NULL;
- default_uuid = NULL;
+ list = terminal_profiles_list_new ();
+
value = gconf_client_get (client, GCONF_GLOBAL_PREFIX "/profile_list", NULL);
if (value != NULL &&
value->type == GCONF_VALUE_LIST &&
gconf_value_get_list_type (value) == GCONF_VALUE_STRING) {
for (l = gconf_value_get_list (value); l != NULL; l = l->next) {
- profile = gconf_value_get_string (l->data);
-
- is_default = g_strcmp0 (profile, default_profile) == 0;
- uuid = migrate_profile (client, global_settings, profile, is_default);
- g_ptr_array_add (profile_uuids, uuid);
- if (is_default)
- default_uuid = uuid;
+ migrate_profile (list, client,
+ gconf_value_get_string (l->data),
+ default_profile);
}
}
@@ -480,27 +491,13 @@ migrate_profiles (GSettings *global_settings,
g_free (path);
}
- /* Only write profile list if there were any profiles migrated */
- if (profile_uuids->len) {
- g_ptr_array_add (profile_uuids, NULL);
- g_settings_set_strv (global_settings, TERMINAL_SETTING_PROFILES_KEY,
- (const char * const *) profile_uuids->pdata);
-
- /* The GConf setting might be corrupt, with the default profile pointing to a profile
- * that doesn't actually exist. In this case, just pick the first profile as default.
- */
- if (default_uuid == NULL)
- default_uuid = (const char *) profile_uuids->pdata[0];
-
- g_settings_set_string (global_settings, TERMINAL_SETTING_DEFAULT_PROFILE_KEY, default_uuid);
- }
-
if (value)
gconf_value_free (value);
if (dvalue)
gconf_value_free (dvalue);
g_object_unref (client);
- g_ptr_array_free (profile_uuids, TRUE);
+
+ g_object_unref (list);
return TRUE;
}
@@ -608,6 +605,8 @@ main (int argc,
g_type_init ();
#endif
+ _terminal_debug_init ();
+
context = g_option_context_new ("");
g_option_context_add_main_entries (context, options, NULL);
@@ -628,6 +627,9 @@ main (int argc,
goto out;
}
+ if (clean)
+ do_clean ();
+
if (!migrate (global_settings, &error)) {
g_printerr ("Error: %s\n", error->message);
g_error_free (error);
diff --git a/src/org.gnome.Terminal.gschema.xml.in b/src/org.gnome.Terminal.gschema.xml.in
index 4181396..819a03d 100644
--- a/src/org.gnome.Terminal.gschema.xml.in
+++ b/src/org.gnome.Terminal.gschema.xml.in
@@ -65,6 +65,26 @@
<value nick='underline' value='2'/>
</enum>
+ <!-- SettingsList base schema -->
+
+ <schema id="org.gnome.Terminal.SettingsList">
+ <key name="list" type="as">
+ <default>[]</default>
+ </key>
+ <key name="default" type="s">
+ <default>''</default>
+ </key>
+ </schema>
+
+ <!-- Profiles list schema -->
+
+ <schema id="org.gnome.Terminal.ProfilesList"
+ extends="org.gnome.Terminal.SettingsList"
+ path="/org/gnome/terminal/legacy/profiles:/">
+ <override name="list">['b1dcc9dd-5262-4d8d-a863-c897e6d979b9']</override>
+ <override name="default">'b1dcc9dd-5262-4d8d-a863-c897e6d979b9'</override>
+ </schema>
+
<!-- A terminal profile -->
<schema id="org.gnome.Terminal.Legacy.Profile">
@@ -505,13 +525,7 @@
<_summary>Whether to show the menubar in new windows</_summary>
</key>
- <key name="profiles" type="as">
- <default>['b1dcc9dd-5262-4d8d-a863-c897e6d979b9']</default>
- </key>
-
- <key name="default-profile" type="s">
- <default>'b1dcc9dd-5262-4d8d-a863-c897e6d979b9'</default>
- </key>
+ <!-- <child name="profiles" schema="org.gnome.Terminal.ProfilesList" /> -->
<key name="schema-version" type="u">
<default>0</default>
diff --git a/src/profile-editor.c b/src/profile-editor.c
index 3302cad..8537576 100644
--- a/src/profile-editor.c
+++ b/src/profile-editor.c
@@ -25,13 +25,14 @@
#include <glib.h>
#include <gio/gio.h>
+#include "terminal-app.h"
#include "terminal-enums.h"
#include "terminal-intl.h"
#include "profile-editor.h"
#include "terminal-schemas.h"
#include "terminal-type-builtins.h"
#include "terminal-util.h"
-#include "terminal-profile-utils.h"
+#include "terminal-profiles-list.h"
typedef struct _TerminalColorScheme TerminalColorScheme;
@@ -674,6 +675,7 @@ terminal_profile_edit (GSettings *profile,
GtkWindow *transient_parent,
const char *widget_name)
{
+ TerminalSettingsList *profiles_list;
GtkBuilder *builder;
GError *error = NULL;
GtkWidget *editor, *w;
@@ -691,6 +693,8 @@ terminal_profile_edit (GSettings *profile,
return;
}
+ profiles_list = terminal_app_get_profiles_list (terminal_app_get ());
+
builder = gtk_builder_new ();
gtk_builder_add_from_resource (builder, "/org/gnome/terminal/ui/profile-preferences.ui", &error);
g_assert_no_error (error);
@@ -716,7 +720,7 @@ terminal_profile_edit (GSettings *profile,
gtk_widget_add_events (w, GDK_BUTTON_PRESS_MASK | GDK_SCROLL_MASK);
g_signal_connect (w, "scroll-event", G_CALLBACK (scroll_event_cb), NULL);
- uuid = terminal_profile_util_get_profile_uuid (profile);
+ uuid = terminal_settings_list_dup_uuid_from_child (profiles_list, profile);
gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "profile-uuid")),
uuid);
g_free (uuid);
diff --git a/src/terminal-app.c b/src/terminal-app.c
index 6d51603..bfe5ca9 100644
--- a/src/terminal-app.c
+++ b/src/terminal-app.c
@@ -32,7 +32,7 @@
#include "terminal-screen.h"
#include "terminal-screen-container.h"
#include "terminal-window.h"
-#include "terminal-profile-utils.h"
+#include "terminal-profiles-list.h"
#include "terminal-util.h"
#include "profile-editor.h"
#include "terminal-encoding.h"
@@ -46,9 +46,6 @@
#include <stdlib.h>
#include <time.h>
-#include <uuid.h>
-#include <dconf.h>
-
#define DESKTOP_INTERFACE_SETTINGS_SCHEMA "org.gnome.desktop.interface"
#define SYSTEM_PROXY_SETTINGS_SCHEMA "org.gnome.system.proxy"
@@ -65,7 +62,6 @@
struct _TerminalAppClass {
GtkApplicationClass parent_class;
- void (* profile_list_changed) (TerminalApp *app);
void (* encoding_list_changed) (TerminalApp *app);
};
@@ -75,22 +71,18 @@ struct _TerminalApp
GDBusObjectManagerServer *object_manager;
- GtkWidget *new_profile_dialog;
-
- GHashTable *profiles_hash;
+ TerminalSettingsList *profiles_list;
GHashTable *encodings;
gboolean encodings_locked;
GSettings *global_settings;
- GSettings *profiles_settings;
GSettings *desktop_interface_settings;
GSettings *system_proxy_settings;
};
enum
{
- PROFILE_LIST_CHANGED,
ENCODING_LIST_CHANGED,
LAST_SIGNAL
};
@@ -147,272 +139,50 @@ maybe_migrate_settings (TerminalApp *app)
#endif /* ENABLE_MIGRATION */
}
-static char **
-strv_insert (char **strv,
- char *str)
-{
- guint i;
-
- for (i = 0; strv[i]; i++)
- if (strcmp (strv[i], str) == 0)
- return strv;
-
- /* Not found; append */
- strv = g_realloc_n (strv, i + 2, sizeof (char *));
- strv[i++] = str;
- strv[i] = NULL;
-
- return strv;
-}
-
-static char **
-strv_remove (char **strv,
- char *str)
-{
- char **a, **b;
-
- a = b = strv;
- while (*a) {
- if (strcmp (*a, str) != 0)
- *b++ = *a;
- a++;
- }
- *b = NULL;
-
- return strv;
-}
-
-static GSettings * /* ref */
-profile_clone (TerminalApp *app,
- GSettings *base_profile)
+void
+terminal_app_new_profile (TerminalApp *app,
+ GSettings *base_profile,
+ GtkWindow *transient_parent)
{
GSettings *profile;
- uuid_t u;
- char str[37];
- char *new_path;
- char **profiles;
-
- uuid_generate (u);
- uuid_unparse (u, str);
- new_path = g_strdup_printf (TERMINAL_PROFILES_PATH_PREFIX ":%s/", str);
-
- if (base_profile)
- {
- static const char * const keys[] = {
- TERMINAL_PROFILE_ALLOW_BOLD_KEY,
- TERMINAL_PROFILE_AUDIBLE_BELL_KEY,
- TERMINAL_PROFILE_BACKGROUND_COLOR_KEY,
- TERMINAL_PROFILE_BACKSPACE_BINDING_KEY,
- TERMINAL_PROFILE_BOLD_COLOR_KEY,
- TERMINAL_PROFILE_BOLD_COLOR_SAME_AS_FG_KEY,
- TERMINAL_PROFILE_CURSOR_BLINK_MODE_KEY,
- TERMINAL_PROFILE_CURSOR_SHAPE_KEY,
- TERMINAL_PROFILE_CUSTOM_COMMAND_KEY,
- TERMINAL_PROFILE_DEFAULT_SIZE_COLUMNS_KEY,
- TERMINAL_PROFILE_DEFAULT_SIZE_ROWS_KEY,
- TERMINAL_PROFILE_DELETE_BINDING_KEY,
- TERMINAL_PROFILE_ENCODING,
- TERMINAL_PROFILE_EXIT_ACTION_KEY,
- TERMINAL_PROFILE_FONT_KEY,
- TERMINAL_PROFILE_FOREGROUND_COLOR_KEY,
- TERMINAL_PROFILE_LOGIN_SHELL_KEY,
- TERMINAL_PROFILE_NAME_KEY,
- TERMINAL_PROFILE_PALETTE_KEY,
- TERMINAL_PROFILE_SCROLLBACK_LINES_KEY,
- TERMINAL_PROFILE_SCROLLBACK_UNLIMITED_KEY,
- TERMINAL_PROFILE_SCROLLBAR_POLICY_KEY,
- TERMINAL_PROFILE_SCROLL_ON_KEYSTROKE_KEY,
- TERMINAL_PROFILE_SCROLL_ON_OUTPUT_KEY,
- TERMINAL_PROFILE_TITLE_MODE_KEY,
- TERMINAL_PROFILE_TITLE_KEY,
- TERMINAL_PROFILE_UPDATE_RECORDS_KEY,
- TERMINAL_PROFILE_USE_CUSTOM_COMMAND_KEY,
- TERMINAL_PROFILE_USE_CUSTOM_DEFAULT_SIZE_KEY,
- TERMINAL_PROFILE_USE_SKEY_KEY,
- TERMINAL_PROFILE_USE_SYSTEM_FONT_KEY,
- TERMINAL_PROFILE_USE_THEME_COLORS_KEY,
- /* TERMINAL_PROFILE_VISIBLE_NAME_KEY, */
- TERMINAL_PROFILE_WORD_CHARS_KEY,
- };
- DConfClient *client;
-#ifndef HAVE_DCONF_1_2
- DConfChangeset *changeset;
-#endif
- char *base_path;
- guint i;
-
- g_object_get (base_profile, "path", &base_path, NULL);
-
-#ifdef HAVE_DCONF_1_2
- client = dconf_client_new (NULL, NULL, NULL, NULL);
-#else
- client = dconf_client_new ();
- changeset = dconf_changeset_new ();
-#endif
+ char *base_uuid, *uuid;
- for (i = 0; i < G_N_ELEMENTS (keys); i++)
- {
- GVariant *value;
- char *p;
-
- p = g_strconcat (base_path, keys[i], NULL);
-#ifdef HAVE_DCONF_1_2
- value = dconf_client_read_no_default (client, p);
-#else
- value = dconf_client_read (client, p);
-#endif
- g_free (p);
-
- if (value)
- {
- p = g_strconcat (new_path, keys[i], NULL);
-#ifdef HAVE_DCONF_1_2
- dconf_client_write (client, p, value, NULL, NULL, NULL);
-#else
- dconf_changeset_set (changeset, p, value);
-#endif
- g_free (p);
- g_variant_unref (value);
- }
- }
-
-#ifndef HAVE_DCONF_1_2
- dconf_client_change_sync (client, changeset, NULL, NULL, NULL);
- g_object_unref (changeset);
-#endif
- g_object_unref (client);
- g_free (base_path);
- }
-
- profile = g_settings_new_with_path (TERMINAL_PROFILE_SCHEMA, new_path);
- g_free (new_path);
-
- if (base_profile)
- {
- const char *base_name;
- char *new_name;
-
- g_settings_get (base_profile, TERMINAL_PROFILE_VISIBLE_NAME_KEY, "&s", &base_name);
- new_name = g_strdup_printf ("%s (Cloned)", base_name);
- g_settings_set_string (profile, TERMINAL_PROFILE_VISIBLE_NAME_KEY, new_name);
- g_free (new_name);
- }
+ if (base_profile) {
+ base_uuid = terminal_settings_list_dup_uuid_from_child (app->profiles_list, base_profile);
+ uuid = terminal_settings_list_clone_child (app->profiles_list, base_uuid);
+ g_free (base_uuid);
+ } else {
+ uuid = terminal_settings_list_add_child (app->profiles_list);
+ }
- /* Store the new UUID in the list of profiles, and add the profile to the hash table.
- * We'll get a changed signal for the profile list key, but that will result in a no-op.
- */
- g_hash_table_insert (app->profiles_hash, g_strdup (str) /* adopted */, profile /* adopted */);
- g_signal_emit (app, signals[PROFILE_LIST_CHANGED], 0);
+ if (uuid == NULL)
+ return;
- g_settings_get (app->global_settings, TERMINAL_SETTING_PROFILES_KEY, "^a&s", &profiles);
- profiles = strv_insert (profiles, str);
- g_settings_set_strv (app->global_settings, TERMINAL_SETTING_PROFILES_KEY, (const char * const *) profiles);
- g_free (profiles);
+ profile = terminal_settings_list_ref_child (app->profiles_list, uuid);
+ g_free (uuid);
+ if (profile == NULL)
+ return;
- return g_object_ref (profile);
+ terminal_profile_edit (profile, transient_parent, "profile-name-entry");
+ g_object_unref (profile);
}
void
terminal_app_remove_profile (TerminalApp *app,
GSettings *profile)
{
- char *uuid, *path;
- char **profiles;
- DConfClient *client;
-
- uuid = terminal_profile_util_get_profile_uuid (profile);
- g_object_get (profile, "path", &path, NULL);
-
- g_settings_get (app->global_settings, TERMINAL_SETTING_PROFILES_KEY, "^a&s", &profiles);
- profiles = strv_remove (profiles, uuid);
- g_settings_set_strv (app->global_settings, TERMINAL_SETTING_PROFILES_KEY, (const char * const *) profiles);
- g_free (profiles);
-
- /* unset all keys under the profile's path */
-#ifdef HAVE_DCONF_1_2
- client = dconf_client_new (NULL, NULL, NULL, NULL);
- dconf_client_write (client, path, NULL, NULL, NULL, NULL);
-#else /* modern DConf */
- client = dconf_client_new ();
- dconf_client_write_sync (client, path, NULL, NULL, NULL, NULL);
-#endif
- g_object_unref (client);
+ char *uuid;
+ uuid = terminal_settings_list_dup_uuid_from_child (app->profiles_list, profile);
+ terminal_settings_list_remove_child (app->profiles_list, uuid);
g_free (uuid);
- g_free (path);
}
gboolean
terminal_app_can_remove_profile (TerminalApp *app,
GSettings *profile)
{
- return g_hash_table_size (app->profiles_hash) > 1;
-}
-
-void
-terminal_app_get_profiles_iter (TerminalApp *app,
- GHashTableIter *iter)
-{
- g_hash_table_iter_init (iter, app->profiles_hash);
-}
-
-static void
-terminal_app_profile_list_changed_cb (GSettings *settings,
- const char *key,
- TerminalApp *app)
-{
- char **profiles, *default_profile;
- guint i;
- GHashTable *new_profiles;
- gboolean changed = FALSE;
-
- /* Use get_mapped so we can be sure never to get valid profile names, and
- * never an empty profile list, since the schema defines one profile.
- */
- profiles = terminal_profile_util_get_profiles (app->global_settings);
- g_settings_get (app->global_settings, TERMINAL_SETTING_DEFAULT_PROFILE_KEY,
- "&s", &default_profile);
-
- new_profiles = g_hash_table_new_full (g_str_hash, g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) g_object_unref);
-
- for (i = 0; profiles[i] != NULL; i++) {
- const char *name = profiles[i];
- GSettings *profile;
-
- if (app->profiles_hash)
- profile = g_hash_table_lookup (app->profiles_hash, name);
- else
- profile = NULL;
-
- if (profile) {
- g_object_ref (profile);
- g_hash_table_remove (app->profiles_hash, name);
- } else {
- char *path;
- path = g_strdup_printf (TERMINAL_PROFILES_PATH_PREFIX ":%s/", name);
- profile = g_settings_new_with_path (TERMINAL_PROFILE_SCHEMA, path);
- g_free (path);
- changed = TRUE;
- }
-
- g_hash_table_insert (new_profiles, g_strdup (name) /* adopted */, profile /* adopted */);
- }
- g_strfreev (profiles);
-
- g_assert (g_hash_table_size (new_profiles) > 0);
-
- if (app->profiles_hash == NULL ||
- g_hash_table_size (app->profiles_hash) > 0)
- changed = TRUE;
-
- if (app->profiles_hash != NULL)
- g_hash_table_unref (app->profiles_hash);
- app->profiles_hash = new_profiles;
-
- if (changed)
- g_signal_emit (app, signals[PROFILE_LIST_CHANGED], 0);
+ return TRUE;
}
static int
@@ -472,18 +242,6 @@ terminal_app_encoding_list_notify_cb (GSettings *settings,
g_signal_emit (app, signals[ENCODING_LIST_CHANGED], 0);
}
-void
-terminal_app_new_profile (TerminalApp *app,
- GSettings *base_profile,
- GtkWindow *transient_parent)
-{
- GSettings *new_profile;
-
- new_profile = profile_clone (app, base_profile);
- terminal_profile_edit (new_profile, transient_parent, "profile-name-entry");
- g_object_unref (new_profile);
-}
-
/* App menu callbacks */
static void
@@ -592,11 +350,7 @@ terminal_app_init (TerminalApp *app)
maybe_migrate_settings (app);
/* Get the profiles */
- terminal_app_profile_list_changed_cb (app->global_settings, NULL, app);
- g_signal_connect (app->global_settings,
- "changed::" TERMINAL_SETTING_PROFILES_KEY,
- G_CALLBACK (terminal_app_profile_list_changed_cb),
- app);
+ app->profiles_list = terminal_profiles_list_new ();
/* Get the encodings */
app->encodings = terminal_encodings_get_builtins ();
@@ -619,11 +373,6 @@ terminal_app_finalize (GObject *object)
app);
g_hash_table_destroy (app->encodings);
- g_signal_handlers_disconnect_by_func (app->global_settings,
- G_CALLBACK (terminal_app_profile_list_changed_cb),
- app);
- g_hash_table_unref (app->profiles_hash);
-
g_object_unref (app->global_settings);
g_object_unref (app->desktop_interface_settings);
g_object_unref (app->system_proxy_settings);
@@ -694,20 +443,11 @@ terminal_app_class_init (TerminalAppClass *klass)
g_application_class->dbus_register = terminal_app_dbus_register;
g_application_class->dbus_unregister = terminal_app_dbus_unregister;
- signals[PROFILE_LIST_CHANGED] =
- g_signal_new (I_("profile-list-changed"),
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (TerminalAppClass, profile_list_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
signals[ENCODING_LIST_CHANGED] =
g_signal_new (I_("encoding-list-changed"),
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (TerminalAppClass, profile_list_changed),
+ G_STRUCT_OFFSET (TerminalAppClass, encoding_list_changed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
@@ -792,49 +532,14 @@ terminal_app_edit_encodings (TerminalApp *app,
}
/**
- * terminal_profile_get_list:
+ * terminal_app_get_profiles_list:
*
- * Returns: a #GList containing all profile #GSettings objects.
- * The content of the list is owned by the backend and
- * should not be modified or freed. Use g_list_free() when done
- * using the list.
+ * Returns: (transfer none): returns the singleton profiles list #TerminalSettingsList
*/
-GList*
-terminal_app_get_profile_list (TerminalApp *app)
+TerminalSettingsList *
+terminal_app_get_profiles_list (TerminalApp *app)
{
- g_return_val_if_fail (TERMINAL_IS_APP (app), NULL);
-
- return g_list_sort (g_hash_table_get_values (app->profiles_hash), terminal_profile_util_profiles_compare);
-}
-
-/**
- * terminal_app_get_profile_by_uuid:
- * @app:
- * @uuid:
- * @error:
- *
- * Returns: (transfer none): the #GSettings for the profile identified by @uuid
- */
-GSettings *
-terminal_app_ref_profile_by_uuid (TerminalApp *app,
- const char *uuid,
- GError **error)
-{
- GSettings *profile = NULL;
-
- if (uuid == NULL)
- g_settings_get (app->global_settings, TERMINAL_SETTING_DEFAULT_PROFILE_KEY, "&s", &uuid);
-
- profile = g_hash_table_lookup (app->profiles_hash, uuid);
-
- if (profile == NULL)
- {
- g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
- "Profile \"%s\" does not exist", uuid);
- return NULL;
- }
-
- return g_object_ref (profile);
+ return app->profiles_list;
}
GHashTable *
diff --git a/src/terminal-app.h b/src/terminal-app.h
index 7911695..67d86c3 100644
--- a/src/terminal-app.h
+++ b/src/terminal-app.h
@@ -23,6 +23,7 @@
#include "terminal-encoding.h"
#include "terminal-screen.h"
+#include "terminal-profiles-list.h"
G_BEGIN_DECLS
@@ -84,14 +85,7 @@ void terminal_app_edit_preferences (TerminalApp *app,
void terminal_app_edit_encodings (TerminalApp *app,
GtkWindow *transient_parent);
-GList* terminal_app_get_profile_list (TerminalApp *app);
-
-void terminal_app_get_profiles_iter (TerminalApp *app,
- GHashTableIter *iter);
-
-GSettings* terminal_app_ref_profile_by_uuid (TerminalApp *app,
- const char *uuid,
- GError **error);
+TerminalSettingsList *terminal_app_get_profiles_list (TerminalApp *app);
TerminalEncoding *terminal_app_ensure_encoding (TerminalApp *app,
const char *charset);
diff --git a/src/terminal-debug.c b/src/terminal-debug.c
index e350a36..4657291 100644
--- a/src/terminal-debug.c
+++ b/src/terminal-debug.c
@@ -28,13 +28,14 @@ _terminal_debug_init(void)
{
#ifdef GNOME_ENABLE_DEBUG
const GDebugKey keys[] = {
- { "accels", TERMINAL_DEBUG_ACCELS },
- { "encodings", TERMINAL_DEBUG_ENCODINGS },
- { "server", TERMINAL_DEBUG_SERVER },
- { "geometry", TERMINAL_DEBUG_GEOMETRY },
- { "mdi", TERMINAL_DEBUG_MDI },
- { "processes", TERMINAL_DEBUG_PROCESSES },
- { "profile", TERMINAL_DEBUG_PROFILE }
+ { "accels", TERMINAL_DEBUG_ACCELS },
+ { "encodings", TERMINAL_DEBUG_ENCODINGS },
+ { "server", TERMINAL_DEBUG_SERVER },
+ { "geometry", TERMINAL_DEBUG_GEOMETRY },
+ { "mdi", TERMINAL_DEBUG_MDI },
+ { "processes", TERMINAL_DEBUG_PROCESSES },
+ { "profile", TERMINAL_DEBUG_PROFILE },
+ { "settings-list", TERMINAL_DEBUG_SETTINGS_LIST },
};
_terminal_debug_flags = g_parse_debug_string (g_getenv ("GNOME_TERMINAL_DEBUG"),
diff --git a/src/terminal-debug.h b/src/terminal-debug.h
index 6c26eca..b5bb792 100644
--- a/src/terminal-debug.h
+++ b/src/terminal-debug.h
@@ -25,13 +25,14 @@
G_BEGIN_DECLS
typedef enum {
- TERMINAL_DEBUG_ACCELS = 1 << 0,
- TERMINAL_DEBUG_ENCODINGS = 1 << 1,
- TERMINAL_DEBUG_SERVER = 1 << 2,
- TERMINAL_DEBUG_GEOMETRY = 1 << 3,
- TERMINAL_DEBUG_MDI = 1 << 4,
- TERMINAL_DEBUG_PROCESSES = 1 << 5,
- TERMINAL_DEBUG_PROFILE = 1 << 6
+ TERMINAL_DEBUG_ACCELS = 1 << 0,
+ TERMINAL_DEBUG_ENCODINGS = 1 << 1,
+ TERMINAL_DEBUG_SERVER = 1 << 2,
+ TERMINAL_DEBUG_GEOMETRY = 1 << 3,
+ TERMINAL_DEBUG_MDI = 1 << 4,
+ TERMINAL_DEBUG_PROCESSES = 1 << 5,
+ TERMINAL_DEBUG_PROFILE = 1 << 6,
+ TERMINAL_DEBUG_SETTINGS_LIST = 1 << 7
} TerminalDebugFlags;
void _terminal_debug_init(void);
diff --git a/src/terminal-enums.h b/src/terminal-enums.h
index 4ea6e7a..d0a7635 100644
--- a/src/terminal-enums.h
+++ b/src/terminal-enums.h
@@ -39,6 +39,12 @@ typedef enum
TERMINAL_EXIT_HOLD
} TerminalExitAction;
+typedef enum {
+ TERMINAL_SETTINGS_LIST_FLAG_NONE = 0,
+ TERMINAL_SETTINGS_LIST_FLAG_HAS_DEFAULT = 1 << 0,
+ TERMINAL_SETTINGS_LIST_FLAG_ALLOW_EMPTY = 1 << 1
+} TerminalSettingsListFlags;
+
G_END_DECLS
#endif /* TERMINAL_ENUMS_H */
diff --git a/src/terminal-gdbus.c b/src/terminal-gdbus.c
index 9d3eab7..6f702cc 100644
--- a/src/terminal-gdbus.c
+++ b/src/terminal-gdbus.c
@@ -352,6 +352,7 @@ terminal_factory_impl_create_instance (TerminalFactory *factory,
GVariant *options)
{
TerminalApp *app = terminal_app_get ();
+ TerminalSettingsList *profiles_list;
GDBusObjectManagerServer *object_manager;
TerminalWindow *window;
TerminalScreen *screen;
@@ -372,8 +373,9 @@ terminal_factory_impl_create_instance (TerminalFactory *factory,
if (!g_variant_lookup (options, "profile", "&s", &profile_uuid))
profile_uuid = NULL;
- profile = terminal_app_ref_profile_by_uuid (app, profile_uuid, &err);
- if (profile == NULL)
+ profiles_list = terminal_app_get_profiles_list (app);
+ profile = terminal_profiles_list_ref_profile_by_uuid (profiles_list, profile_uuid, &err);
+ if (profile == NULL)
{
g_dbus_method_invocation_return_gerror (invocation, err);
g_error_free (err);
diff --git a/src/terminal-options.c b/src/terminal-options.c
index 6262eda..f2a54b6 100644
--- a/src/terminal-options.c
+++ b/src/terminal-options.c
@@ -31,12 +31,20 @@
#include "terminal-screen.h"
#include "terminal-app.h"
#include "terminal-intl.h"
-#include "terminal-profile-utils.h"
#include "terminal-util.h"
#include "terminal-version.h"
static GOptionContext *get_goption_context (TerminalOptions *options);
+static TerminalSettingsList *
+terminal_options_ensure_profiles_list (TerminalOptions *options)
+{
+ if (options->profiles_list == NULL)
+ options->profiles_list = terminal_profiles_list_new ();
+
+ return options->profiles_list;
+}
+
static char *
terminal_util_key_file_get_string_unescape (GKeyFile *key_file,
const char *group,
@@ -296,7 +304,8 @@ option_profile_cb (const gchar *option_name,
TerminalOptions *options = data;
char *profile;
- profile = terminal_profile_util_get_profile_by_uuid_or_name (value, error);
+ profile = terminal_profiles_list_dup_uuid_or_name (terminal_options_ensure_profiles_list (options),
+ value, error);
if (profile == NULL)
return FALSE;
@@ -325,7 +334,8 @@ option_profile_id_cb (const gchar *option_name,
TerminalOptions *options = data;
char *profile;
- profile = terminal_profile_util_get_profile_by_uuid (value, error);
+ profile = terminal_profiles_list_dup_uuid (terminal_options_ensure_profiles_list (options),
+ value, error);
if (profile == NULL)
return FALSE;
@@ -355,7 +365,8 @@ option_window_callback (const gchar *option_name,
TerminalOptions *options = data;
char *profile;
- profile = terminal_profile_util_get_profile_by_uuid (value, error);
+ profile = terminal_profiles_list_dup_uuid (terminal_options_ensure_profiles_list (options),
+ value, error);
if (profile == NULL)
return FALSE;
@@ -373,7 +384,8 @@ option_tab_callback (const gchar *option_name,
TerminalOptions *options = data;
char *profile;
- profile = terminal_profile_util_get_profile_by_uuid (value, error);
+ profile = terminal_profiles_list_dup_uuid (terminal_options_ensure_profiles_list (options),
+ value, error);
if (profile == NULL)
return FALSE;
@@ -985,6 +997,8 @@ terminal_options_free (TerminalOptions *options)
g_free (options->sm_client_id);
g_free (options->sm_config_prefix);
+ g_clear_object (&options->profiles_list);
+
g_slice_free (TerminalOptions, options);
}
diff --git a/src/terminal-options.h b/src/terminal-options.h
index 9cab113..709c6d3 100644
--- a/src/terminal-options.h
+++ b/src/terminal-options.h
@@ -24,6 +24,8 @@
#include <glib.h>
+#include "terminal-profiles-list.h"
+
G_BEGIN_DECLS
#define TERMINAL_CONFIG_VERSION (1) /* Bump this for any changes */
@@ -58,6 +60,8 @@ enum
typedef struct
{
+ TerminalSettingsList *profiles_list; /* may be NULL */
+
char *server_app_id;
gboolean remote_arguments;
char *startup_id;
diff --git a/src/terminal-prefs.c b/src/terminal-prefs.c
index 07335ce..4408865 100644
--- a/src/terminal-prefs.c
+++ b/src/terminal-prefs.c
@@ -32,10 +32,11 @@
#include "terminal-intl.h"
#include "terminal-schemas.h"
#include "terminal-util.h"
-#include "terminal-profile-utils.h"
+#include "terminal-profiles-list.h"
#include "terminal-encoding.h"
typedef struct {
+ TerminalSettingsList *profiles_list;
GtkWidget *dialog;
GtkWindow *parent;
@@ -44,7 +45,7 @@ typedef struct {
GtkWidget *manage_profiles_edit_button;
GtkWidget *manage_profiles_clone_button;
GtkWidget *manage_profiles_delete_button;
- GtkWidget *manage_profiles_default_menu;
+ GtkWidget *profiles_default_combo;
GtkListStore *encoding_base_store;
GtkTreeModel *encodings_model;
@@ -82,7 +83,7 @@ profile_cell_data_func (GtkTreeViewColumn *tree_column,
GtkCellRenderer *cell,
GtkTreeModel *tree_model,
GtkTreeIter *iter,
- gpointer user_data)
+ PrefData *data)
{
GSettings *profile;
const char *text;
@@ -91,7 +92,7 @@ profile_cell_data_func (GtkTreeViewColumn *tree_column,
gtk_tree_model_get (tree_model, iter, (int) COL_PROFILE, &profile, (int) -1);
g_settings_get (profile, TERMINAL_PROFILE_VISIBLE_NAME_KEY, "&s", &text);
- uuid = terminal_profile_util_get_profile_uuid (profile);
+ uuid = terminal_settings_list_dup_uuid_from_child (data->profiles_list, profile);
g_value_init (&value, G_TYPE_STRING);
g_value_take_string (&value,
@@ -117,7 +118,7 @@ profile_sort_func (GtkTreeModel *model,
gtk_tree_model_get (model, a, (int) COL_PROFILE, &profile_a, (int) -1);
gtk_tree_model_get (model, b, (int) COL_PROFILE, &profile_b, (int) -1);
- retval = terminal_profile_util_profiles_compare (profile_a, profile_b);
+ retval = terminal_profiles_compare (profile_a, profile_b);
g_object_unref (profile_a);
g_object_unref (profile_b);
@@ -126,14 +127,14 @@ profile_sort_func (GtkTreeModel *model,
}
static /* ref */ GtkTreeModel *
-profile_liststore_new (GSettings *selected_profile,
+profile_liststore_new (PrefData *data,
+ GSettings *selected_profile,
GtkTreeIter *selected_profile_iter,
gboolean *selected_profile_iter_set)
{
GtkListStore *store;
GtkTreeIter iter;
- GHashTableIter ht_iter;
- gpointer value;
+ GList *list, *l;
G_STATIC_ASSERT (NUM_PROFILE_COLUMNS == 1);
store = gtk_list_store_new (NUM_PROFILE_COLUMNS, G_TYPE_SETTINGS);
@@ -141,10 +142,10 @@ profile_liststore_new (GSettings *selected_profile,
if (selected_profile_iter)
*selected_profile_iter_set = FALSE;
- terminal_app_get_profiles_iter (terminal_app_get (), &ht_iter);
- while (g_hash_table_iter_next (&ht_iter, NULL, &value))
+ list = terminal_settings_list_ref_children (data->profiles_list);
+ for (l = list; l != NULL; l = l->next)
{
- GSettings *profile = (GSettings *) value;
+ GSettings *profile = (GSettings *) l->data;
gtk_list_store_insert_with_values (store, &iter, 0,
(int) COL_PROFILE, profile,
@@ -157,6 +158,8 @@ profile_liststore_new (GSettings *selected_profile,
}
}
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
+
/* Now turn on sorting */
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (store),
COL_PROFILE,
@@ -169,9 +172,8 @@ profile_liststore_new (GSettings *selected_profile,
}
static /* ref */ GSettings*
-profile_combo_box_ref_selected (GtkWidget *widget)
+profile_combo_box_ref_selected (GtkComboBox *combo)
{
- GtkComboBox *combo = GTK_COMBO_BOX (widget);
GSettings *profile;
GtkTreeIter iter;
@@ -185,17 +187,18 @@ profile_combo_box_ref_selected (GtkWidget *widget)
}
static void
-profile_combo_box_refill (GtkWidget *combo_widget)
+profile_combo_box_refill (PrefData *data)
{
- GtkComboBox *combo = GTK_COMBO_BOX (combo_widget);
+ GtkComboBox *combo = GTK_COMBO_BOX (data->profiles_default_combo);
GtkTreeIter iter;
gboolean iter_set;
GSettings *selected_profile;
GtkTreeModel *model;
- selected_profile = profile_combo_box_ref_selected (combo_widget);
+ selected_profile = profile_combo_box_ref_selected (combo);
- model = profile_liststore_new (selected_profile,
+ model = profile_liststore_new (data,
+ selected_profile,
&iter,
&iter_set);
gtk_combo_box_set_model (combo, model);
@@ -227,10 +230,11 @@ profile_combo_box_new (PrefData *data)
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo), renderer,
(GtkCellLayoutDataFunc) profile_cell_data_func,
- NULL, NULL);
+ data, NULL);
- default_profile = terminal_app_ref_profile_by_uuid (terminal_app_get (), NULL, NULL);
- model = profile_liststore_new (default_profile,
+ default_profile = terminal_settings_list_ref_default_child (data->profiles_list);
+ model = profile_liststore_new (data,
+ default_profile,
&iter,
&iter_set);
gtk_combo_box_set_model (combo, model);
@@ -242,9 +246,6 @@ profile_combo_box_new (PrefData *data)
if (default_profile)
g_object_unref (default_profile);
- g_signal_connect (terminal_app_get (), "profile-list-changed",
- G_CALLBACK (profile_combo_box_refill), combo);
-
gtk_widget_show (combo_widget);
return combo_widget;
}
@@ -253,19 +254,18 @@ static void
profile_combo_box_changed_cb (GtkWidget *widget,
PrefData *data)
{
- GSettings *profile, *settings;
+ GSettings *profile;
char *uuid;
- profile = profile_combo_box_ref_selected (widget);
+ profile = profile_combo_box_ref_selected (GTK_COMBO_BOX (data->profiles_default_combo));
if (!profile)
return;
- uuid = terminal_profile_util_get_profile_uuid (profile);
- settings = terminal_app_get_global_settings (terminal_app_get ());
- g_settings_set_string (settings, TERMINAL_SETTING_DEFAULT_PROFILE_KEY, uuid);
+ uuid = terminal_settings_list_dup_uuid_from_child (data->profiles_list, profile);
+ g_object_unref (profile);
+ terminal_settings_list_set_default_child (data->profiles_list, uuid);
g_free (uuid);
- g_object_unref (profile);
}
static GSettings *
@@ -295,7 +295,8 @@ profile_list_treeview_refill (PrefData *data)
GtkTreeModel *model;
selected_profile = profile_list_ref_selected (data);
- model = profile_liststore_new (selected_profile,
+ model = profile_liststore_new (data,
+ selected_profile,
&iter,
&iter_set);
gtk_tree_view_set_model (tree_view, model);
@@ -349,7 +350,7 @@ profile_list_treeview_new (PrefData *data)
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer, TRUE);
gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (column), renderer,
(GtkCellLayoutDataFunc) profile_cell_data_func,
- NULL, NULL);
+ data, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view),
GTK_TREE_VIEW_COLUMN (column));
@@ -572,10 +573,12 @@ prefs_dialog_destroy_cb (GtkWidget *widget,
{
TerminalApp *app = terminal_app_get ();
- g_signal_handlers_disconnect_by_func (app, G_CALLBACK (profile_list_treeview_refill), data);
- g_signal_handlers_disconnect_by_func (app, G_CALLBACK (profile_combo_box_refill), data);
+ g_signal_handlers_disconnect_by_func (data->profiles_list, G_CALLBACK (profile_combo_box_refill), data);
+ g_signal_handlers_disconnect_by_func (data->profiles_list, G_CALLBACK (profile_list_treeview_refill), data);
+
g_signal_handlers_disconnect_by_func (app, G_CALLBACK (encodings_list_changed_cb), data);
+ /* Don't run this handler again */
g_signal_handlers_disconnect_by_func (widget, G_CALLBACK (prefs_dialog_destroy_cb), data);
g_free (data);
}
@@ -603,6 +606,7 @@ terminal_prefs_show_preferences (GtkWindow *transient_parent,
data = g_new0 (PrefData, 1);
data->parent = transient_parent;
+ data->profiles_list = terminal_app_get_profiles_list (app);
terminal_util_load_builder_resource ("/org/gnome/terminal/ui/preferences.ui",
"preferences-dialog",
@@ -662,7 +666,7 @@ terminal_prefs_show_preferences (GtkWindow *transient_parent,
g_signal_connect (selection, "changed", G_CALLBACK (profile_list_selection_changed_cb), data);
profile_list_treeview_refill (data);
- g_signal_connect_swapped (app, "profile-list-changed",
+ g_signal_connect_swapped (data->profiles_list, "children-changed",
G_CALLBACK (profile_list_treeview_refill), data);
gtk_container_add (GTK_CONTAINER (tree_view_container), GTK_WIDGET (data->manage_profiles_list));
@@ -681,15 +685,17 @@ terminal_prefs_show_preferences (GtkWindow *transient_parent,
G_CALLBACK (profile_list_delete_button_clicked_cb),
data);
- data->manage_profiles_default_menu = profile_combo_box_new (data);
- g_signal_connect (data->manage_profiles_default_menu, "changed",
+ data->profiles_default_combo = profile_combo_box_new (data);
+ g_signal_connect_swapped (data->profiles_list, "children-changed",
+ G_CALLBACK (profile_combo_box_refill), data);
+ g_signal_connect (data->profiles_default_combo, "changed",
G_CALLBACK (profile_combo_box_changed_cb), data);
- gtk_box_pack_start (GTK_BOX (default_hbox), data->manage_profiles_default_menu, FALSE, FALSE, 0);
- gtk_widget_show (data->manage_profiles_default_menu);
+ gtk_box_pack_start (GTK_BOX (default_hbox), data->profiles_default_combo, FALSE, FALSE, 0);
+ gtk_widget_show (data->profiles_default_combo);
// FIXMEchpe
- gtk_label_set_mnemonic_widget (GTK_LABEL (default_label), data->manage_profiles_default_menu);
+ gtk_label_set_mnemonic_widget (GTK_LABEL (default_label), data->profiles_default_combo);
/* Encodings tab */
diff --git a/src/terminal-profiles-list.c b/src/terminal-profiles-list.c
new file mode 100644
index 0000000..284cfd5
--- /dev/null
+++ b/src/terminal-profiles-list.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright  2001, 2002 Havoc Pennington
+ * Copyright  2002 Red Hat, Inc.
+ * Copyright  2002 Sun Microsystems
+ * Copyright  2003 Mariano Suarez-Alvarez
+ * Copyright  2011, 2013 Christian Persch
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "terminal-profiles-list.h"
+#include "terminal-schemas.h"
+
+#include <string.h>
+#include <uuid.h>
+
+/* Counts occurrences of @str in @strv */
+static guint
+strv_contains (char **strv,
+ const char *str,
+ guint *idx)
+{
+ guint n, i;
+
+ if (strv == NULL)
+ return 0;
+
+ n = 0;
+ for (i = 0; strv[i]; i++) {
+ if (strcmp (strv[i], str) == 0) {
+ n++;
+ if (idx)
+ *idx = i;
+ }
+ }
+
+ return n;
+}
+
+/**
+ * terminal_profiles_list_new:
+ *
+ * Returns: (transfer full): a new #TerminalSettingsList for the profiles list
+ */
+TerminalSettingsList *
+terminal_profiles_list_new (void)
+{
+ return terminal_settings_list_new (TERMINAL_PROFILES_PATH_PREFIX,
+ TERMINAL_PROFILES_LIST_SCHEMA,
+ TERMINAL_PROFILE_SCHEMA,
+ TERMINAL_SETTINGS_LIST_FLAG_HAS_DEFAULT);
+}
+
+static void
+get_profile_names (TerminalSettingsList *list,
+ char ***profilesp,
+ char ***namesp)
+{
+ GSettings *profile;
+ char **profiles, **names;
+ guint i, n;
+
+ *profilesp = profiles = terminal_settings_list_dupv_children (list);
+
+ n = g_strv_length (profiles);
+ *namesp = names = g_new0 (char *, n + 1);
+ for (i = 0; i < n; i++) {
+ profile = terminal_settings_list_ref_child (list, profiles[i]);
+ names[i] = g_settings_get_string (profile, TERMINAL_PROFILE_VISIBLE_NAME_KEY);
+ g_object_unref (profile);
+ }
+
+ names[n] = NULL;
+}
+
+/**
+ * terminal_profiles_list_get_children:
+ * @list:
+ *
+ * Returns: (transfer full):
+ */
+GList *
+terminal_profiles_list_ref_children (TerminalSettingsList *list)
+{
+ return g_list_sort (terminal_settings_list_ref_children (list),
+ terminal_profiles_compare);
+}
+
+/**
+ * terminal_profiles_list_dup_uuid:
+ * @list:
+ * @uuid: (allow-none):
+ * @error:
+ *
+ * Returns: (transfer full): the UUID of the profile specified by @uuid, or %NULL
+ */
+char *
+terminal_profiles_list_dup_uuid (TerminalSettingsList *list,
+ const char *uuid,
+ GError **error)
+{
+ char *rv;
+
+ if (uuid == NULL) {
+ rv = terminal_settings_list_dup_default_child (list);
+ if (rv == NULL)
+ goto err;
+ return rv;
+ }
+
+ if (terminal_settings_list_has_child (list, uuid))
+ return g_strdup (uuid);
+
+ err:
+ g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
+ "No profile with UUID \"%s\" exists", uuid);
+ return NULL;
+}
+
+/**
+ * terminal_profiles_list_ref_profile_by_uuid_or_name:
+ * @list:
+ * @uuid:
+ * @error:
+ *
+ * Returns: (transfer full): the profile #GSettings specified by @uuid, or %NULL
+ */
+GSettings *
+terminal_profiles_list_ref_profile_by_uuid (TerminalSettingsList *list,
+ const char *uuid,
+ GError **error)
+{
+ char *profile_uuid;
+ GSettings *profile;
+
+ profile_uuid = terminal_profiles_list_dup_uuid (list, uuid, error);
+ if (profile_uuid == NULL)
+ return NULL;
+
+ profile = terminal_settings_list_ref_child (list, profile_uuid);
+ g_free (profile_uuid);
+ g_assert (profile != NULL);
+ return profile;
+}
+
+/**
+ * terminal_profiles_list_get_profile_by_uuid:
+ * @list:
+ * @uuid: (allow-none):
+ * @error:
+ *
+ * Returns: (transfer full): the UUID of the profile specified by @uuid, or %NULL
+ */
+char *
+terminal_profiles_list_dup_uuid_or_name (TerminalSettingsList *list,
+ const char *uuid_or_name,
+ GError **error)
+{
+ char **profiles, **profile_names;
+ char *rv;
+ guint n, i;
+
+ rv = terminal_profiles_list_dup_uuid (list, uuid_or_name, NULL);
+ if (rv != NULL)
+ return rv;
+
+ /* Not found as UUID; try finding a profile with this string as 'visible-name' */
+ get_profile_names (list, &profiles, &profile_names);
+ n = strv_contains (profile_names, uuid_or_name, &i);
+
+ if (n == 0) {
+ g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
+ "No profile with UUID or name \"%s\" exists", uuid_or_name);
+ rv = NULL;
+ } else if (n != 1) {
+ g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
+ "No profile with UUID \"%s\" found and name is ambiguous", uuid_or_name);
+ rv = NULL;
+ } else {
+ rv = g_strdup (profiles[i]);
+ }
+
+ g_strfreev (profiles);
+ g_strfreev (profile_names);
+
+ return rv;
+}
+
+/**
+ * terminal_profiles_list_ref_profile_by_uuid_or_name:
+ * @list:
+ * @uuid:
+ * @error:
+ *
+ * Returns: (transfer full): the profile #GSettings specified by @uuid, or %NULL
+ */
+GSettings *
+terminal_profiles_list_ref_profile_by_uuid_or_name (TerminalSettingsList *list,
+ const char *uuid_or_name,
+ GError **error)
+{
+ char *uuid;
+ GSettings *profile;
+
+ uuid = terminal_profiles_list_dup_uuid_or_name (list, uuid_or_name, error);
+ if (uuid == NULL)
+ return NULL;
+
+ profile = terminal_settings_list_ref_child (list, uuid);
+ g_free (uuid);
+ g_assert (profile != NULL);
+ return profile;
+}
+
+int
+terminal_profiles_compare (gconstpointer pa,
+ gconstpointer pb)
+{
+ GSettings *a = (GSettings *) pa;
+ GSettings *b = (GSettings *) pb;
+ const char *na, *nb;
+ char *patha, *pathb;
+ int result;
+
+ if (pa == pb)
+ return 0;
+ if (pa == NULL)
+ return 1;
+ if (pb == NULL)
+ return -1;
+
+ g_settings_get (a, TERMINAL_PROFILE_VISIBLE_NAME_KEY, "&s", &na);
+ g_settings_get (b, TERMINAL_PROFILE_VISIBLE_NAME_KEY, "&s", &nb);
+ result = g_utf8_collate (na, nb);
+ if (result != 0)
+ return result;
+
+ g_object_get (a, "path", &patha, NULL);
+ g_object_get (b, "path", &pathb, NULL);
+ result = strcmp (patha, pathb);
+ g_free (patha);
+ g_free (pathb);
+
+ return result;
+}
diff --git a/src/terminal-profiles-list.h b/src/terminal-profiles-list.h
new file mode 100644
index 0000000..42ed11c
--- /dev/null
+++ b/src/terminal-profiles-list.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright  2013 Christian Persch
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TERMINAL_PROFILES_LIST_H
+#define TERMINAL_PROFILES_LIST_H
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include "terminal-settings-list.h"
+
+G_BEGIN_DECLS
+
+TerminalSettingsList *terminal_profiles_list_new (void);
+
+GList *terminal_profiles_list_ref_children (TerminalSettingsList *list);
+
+char *terminal_profiles_list_dup_uuid (TerminalSettingsList *list,
+ const char *uuid,
+ GError **error);
+
+GSettings *terminal_profiles_list_ref_profile_by_uuid (TerminalSettingsList *list,
+ const char *uuid,
+ GError **error);
+
+char *terminal_profiles_list_dup_uuid_or_name (TerminalSettingsList *list,
+ const char *uuid_or_name,
+ GError **error);
+
+GSettings *terminal_profiles_list_ref_profile_by_uuid_or_name (TerminalSettingsList *list,
+ const char *uuid_or_name,
+ GError **error);
+
+int terminal_profiles_compare (gconstpointer pa,
+ gconstpointer pb);
+
+G_END_DECLS
+
+#endif /* TERMINAL_PROFILES_LIST_H */
diff --git a/src/terminal-schemas.h b/src/terminal-schemas.h
index f31a035..45386a1 100644
--- a/src/terminal-schemas.h
+++ b/src/terminal-schemas.h
@@ -22,11 +22,13 @@
G_BEGIN_DECLS
-#define TERMINAL_SCHEMA_VERSION (1u)
+#define TERMINAL_SCHEMA_VERSION (2u)
#define TERMINAL_KEYBINDINGS_SCHEMA "org.gnome.Terminal.Legacy.Keybindings"
#define TERMINAL_PROFILE_SCHEMA "org.gnome.Terminal.Legacy.Profile"
#define TERMINAL_SETTING_SCHEMA "org.gnome.Terminal.Legacy.Settings"
+#define TERMINAL_SETTINGS_LIST_SCHEMA "org.gnome.Terminal.SettingsList"
+#define TERMINAL_PROFILES_LIST_SCHEMA "org.gnome.Terminal.ProfilesList"
#define TERMINAL_PROFILE_ALLOW_BOLD_KEY "allow-bold"
#define TERMINAL_PROFILE_AUDIBLE_BELL_KEY "audible-bell"
@@ -64,14 +66,15 @@ G_BEGIN_DECLS
#define TERMINAL_PROFILE_WORD_CHARS_KEY "word-chars"
#define TERMINAL_SETTING_CONFIRM_CLOSE_KEY "confirm-close"
-#define TERMINAL_SETTING_DEFAULT_PROFILE_KEY "default-profile"
#define TERMINAL_SETTING_DEFAULT_SHOW_MENUBAR_KEY "default-show-menubar"
#define TERMINAL_SETTING_ENABLE_MENU_BAR_ACCEL_KEY "menu-accelerator-enabled"
#define TERMINAL_SETTING_ENABLE_MNEMONICS_KEY "mnemonics-enabled"
-#define TERMINAL_SETTING_PROFILES_KEY "profiles"
#define TERMINAL_SETTING_ENCODINGS_KEY "encodings"
#define TERMINAL_SETTING_SCHEMA_VERSION "schema-version"
+#define TERMINAL_SETTINGS_LIST_LIST_KEY "list"
+#define TERMINAL_SETTINGS_LIST_DEFAULT_KEY "default"
+
#define TERMINAL_PROFILES_PATH_PREFIX "/org/gnome/terminal/legacy/profiles:/"
G_END_DECLS
diff --git a/src/terminal-settings-list.c b/src/terminal-settings-list.c
new file mode 100644
index 0000000..c2934fa
--- /dev/null
+++ b/src/terminal-settings-list.c
@@ -0,0 +1,881 @@
+/*
+ * Copyright  2013 Christian Persch
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "terminal-settings-list.h"
+
+#include <string.h>
+#include <uuid.h>
+#include <dconf.h>
+
+#include "terminal-type-builtins.h"
+#include "terminal-schemas.h"
+#include "terminal-debug.h"
+
+struct _TerminalSettingsList {
+ GSettings parent;
+
+ char *path;
+ char *child_schema_id;
+
+ char **uuids;
+ char *default_uuid;
+
+ GHashTable *children;
+
+ TerminalSettingsListFlags flags;
+};
+
+struct _TerminalSettingsListClass {
+ GSettingsClass parent;
+
+ void (* children_changed) (TerminalSettingsList *list);
+ void (* default_changed) (TerminalSettingsList *list);
+};
+
+enum {
+ PROP_CHILD_SCHEMA_ID = 1,
+ PROP_FLAGS
+};
+
+enum {
+ SIGNAL_CHILDREN_CHANGED,
+ SIGNAL_DEFAULT_CHANGED,
+ N_SIGNALS
+};
+
+static guint signals[N_SIGNALS];
+
+static void
+strv_printerr (char **strv)
+{
+ char **p;
+
+ if (strv == NULL) {
+ g_printerr ("(null)");
+ return;
+ }
+
+ for (p = strv; *p; p++)
+ g_printerr ("%s'%s'", p != strv ? ", " : "", *p);
+}
+
+static char **
+strv_sort (char **strv)
+{
+ // FIXMEchpe
+ return strv;
+}
+
+static gboolean
+strv_equal (char **a,
+ char **b)
+{
+ char **e, **f;
+
+ if (a == NULL || b == NULL)
+ return a == b;
+
+ for (e = a, f = b; *e && *f; e++, f++) {
+ if (!g_str_equal (*e, *f))
+ return FALSE;
+ }
+
+ return *e == *f;
+}
+
+static int
+strv_find (char **strv,
+ const char *str)
+{
+ int i;
+
+ if (strv == NULL || str == NULL)
+ return -1;
+
+ for (i = 0; strv[i]; i++) {
+ if (!g_str_equal (strv[i], str))
+ continue;
+
+ return i;
+ }
+
+ return -1;
+}
+
+static char **
+strv_dupv_insert (char **strv,
+ const char *str)
+{
+ char **nstrv, **p, **q;
+
+ if (strv == NULL) {
+ char *s[2] = { (char *) str, NULL };
+ return g_strdupv (s);
+ }
+
+ /* Is it already in the list? */
+ for (p = strv; *p; p++)
+ if (g_str_equal (*p, str))
+ return g_strdupv (strv);
+
+ /* Not found; append */
+ nstrv = g_new (char *, (p - strv) + 2);
+ for (p = strv, q = nstrv; *p; p++, q++)
+ *q = g_strdup (*p);
+ *q++ = g_strdup (str);
+ *q = NULL;
+
+ return strv_sort (nstrv);
+}
+
+static char **
+strv_dupv_remove (char **strv,
+ const char *str)
+{
+ char **nstrv, **p, **q;
+
+ if (strv == NULL)
+ return NULL;
+
+ nstrv = g_strdupv (strv);
+ for (p = q = nstrv; *p; p++) {
+ if (!g_str_equal (*p, str))
+ *q++ = *p;
+ else
+ g_free (*p);
+ }
+ *q = NULL;
+
+ return nstrv;
+}
+
+static gboolean
+is_valid_uuid (const char *str)
+{
+ uuid_t u;
+
+ if (str == NULL)
+ return FALSE;
+
+ return uuid_parse ((char *) str, u) == 0;
+}
+
+static char *
+new_list_entry (void)
+{
+ uuid_t u;
+ char name[37];
+
+ uuid_generate (u);
+ uuid_unparse (u, name);
+
+ return g_strdup (name);
+}
+
+static gboolean
+validate_list (TerminalSettingsList *list,
+ char **entries)
+{
+ gboolean allow_empty = (list->flags & TERMINAL_SETTINGS_LIST_FLAG_ALLOW_EMPTY) != 0;
+ guint i;
+
+ if (entries == NULL)
+ return allow_empty;
+
+ for (i = 0; entries[i]; i++) {
+ if (!is_valid_uuid (entries[i]))
+ return FALSE;
+ }
+
+ return (i > 0) || allow_empty;
+}
+
+static gboolean
+list_map_func (GVariant *value,
+ gpointer *result,
+ gpointer user_data)
+{
+ TerminalSettingsList *list = user_data;
+ char **entries;
+
+ entries = strv_sort (g_variant_dup_strv (value, NULL));
+
+ if (validate_list (list, entries)) {
+ *result = entries;
+ return TRUE;
+ }
+
+ g_strfreev (entries);
+ return FALSE;
+}
+
+static char *
+path_new (TerminalSettingsList *list,
+ const char *uuid)
+{
+ return g_strdup_printf ("%s:%s/", list->path, uuid);
+}
+
+static GSettings *
+terminal_settings_list_ref_child_internal (TerminalSettingsList *list,
+ const char *uuid)
+{
+ GSettings *child;
+ char *path;
+
+ if (strv_find (list->uuids, uuid) == -1)
+ return NULL;
+
+ _terminal_debug_print (TERMINAL_DEBUG_SETTINGS_LIST,
+ "%s UUID %s\n", G_STRFUNC, uuid);
+
+ child = g_hash_table_lookup (list->children, uuid);
+ if (child)
+ goto done;
+
+ path = path_new (list, uuid);
+ child = g_settings_new_with_path (list->child_schema_id, path);
+ g_hash_table_insert (list->children, g_strdup (uuid), child /* adopted */);
+ g_free (path);
+
+ done:
+ return g_object_ref (child);
+}
+
+static char *
+clone_child (TerminalSettingsList *list,
+ const char *uuid)
+{
+ char *new_uuid;
+ char *path, *new_path;
+ char **keys, *key;
+ guint i;
+ GVariant *value;
+ DConfClient *client;
+#ifndef HAVE_DCONF_1_2
+ DConfChangeset *changeset;
+#endif
+
+ new_uuid = new_list_entry ();
+
+ _terminal_debug_print (TERMINAL_DEBUG_SETTINGS_LIST,
+ "%s UUID %s NEW UUID %s \n", G_STRFUNC, uuid ? uuid : "(null)", new_uuid);
+
+ path = path_new (list, uuid);
+ new_path = path_new (list, new_uuid);
+
+#ifdef HAVE_DCONF_1_2
+ client = dconf_client_new (NULL, NULL, NULL, NULL);
+#else
+ client = dconf_client_new ();
+ changeset = dconf_changeset_new ();
+#endif
+
+ /* FIXME: this is beyond ugly. Need API on GSettingsSchema to list all the keys! */
+ {
+ GSettings *dummy = g_settings_new_with_path (list->child_schema_id, "/foo");
+ keys = g_settings_list_keys (dummy);
+ g_object_unref (dummy);
+ }
+
+ for (i = 0; keys[i]; i++) {
+ key = g_strconcat (path, keys[i], NULL);
+#ifdef HAVE_DCONF_1_2
+ value = dconf_client_read_no_default (client, key);
+#else
+ value = dconf_client_read (client, key);
+#endif
+ g_free (key);
+
+ if (value) {
+ key = g_strconcat (new_path, keys[i], NULL);
+#ifdef HAVE_DCONF_1_2
+ dconf_client_write (client, key, value, NULL, NULL, NULL);
+#else
+ dconf_changeset_set (changeset, key, value);
+#endif
+ g_free (key);
+ g_variant_unref (value);
+ }
+ }
+
+#ifndef HAVE_DCONF_1_2
+ dconf_client_change_sync (client, changeset, NULL, NULL, NULL);
+ g_object_unref (changeset);
+#endif
+ g_object_unref (client);
+ g_free (path);
+ g_free (new_path);
+
+ return new_uuid;
+}
+
+static char *
+terminal_settings_list_add_child_internal (TerminalSettingsList *list,
+ const char *uuid)
+{
+ char *new_uuid;
+ char **new_uuids;
+
+ if (uuid)
+ new_uuid = clone_child (list, uuid);
+ else
+ new_uuid = new_list_entry ();
+
+ _terminal_debug_print (TERMINAL_DEBUG_SETTINGS_LIST,
+ "%s NEW UUID %s\n", G_STRFUNC, new_uuid);
+
+ new_uuids = strv_dupv_insert (list->uuids, new_uuid);
+ g_settings_set_strv (&list->parent, TERMINAL_SETTINGS_LIST_LIST_KEY,
+ (const char * const *) new_uuids);
+ g_strfreev (new_uuids);
+
+ return new_uuid;
+}
+
+static void
+terminal_settings_list_remove_child_internal (TerminalSettingsList *list,
+ const char *uuid)
+{
+ char **new_uuids, *path;
+ DConfClient *client;
+
+ _terminal_debug_print (TERMINAL_DEBUG_SETTINGS_LIST,
+ "%s UUID %s\n", G_STRFUNC, uuid);
+
+ new_uuids = strv_dupv_remove (list->uuids, uuid);
+
+ if ((new_uuids == NULL || new_uuids[0] == NULL) &&
+ (list->flags & TERMINAL_SETTINGS_LIST_FLAG_ALLOW_EMPTY) == 0) {
+ g_strfreev (new_uuids);
+ return;
+ }
+
+ g_settings_set_strv (&list->parent, TERMINAL_SETTINGS_LIST_LIST_KEY, (const char * const *) new_uuids);
+ g_strfreev (new_uuids);
+
+ if (list->default_uuid != NULL &&
+ g_str_equal (list->default_uuid, uuid))
+ g_settings_set_string (&list->parent, TERMINAL_SETTINGS_LIST_DEFAULT_KEY, "");
+
+ /* Now we unset all keys under the child */
+ path = path_new (list, uuid);
+
+#ifdef HAVE_DCONF_1_2
+ client = dconf_client_new (NULL, NULL, NULL, NULL);
+ dconf_client_write (client, path, NULL, NULL, NULL, NULL);
+#else /* modern DConf */
+ client = dconf_client_new ();
+ dconf_client_write_sync (client, path, NULL, NULL, NULL, NULL);
+#endif
+ g_object_unref (client);
+
+ g_free (path);
+}
+
+static void
+terminal_settings_list_update_list (TerminalSettingsList *list)
+{
+ char **uuids, *uuid;
+ GSettings *child;
+ GHashTable *new_children;
+ guint i;
+ gboolean changed;
+
+ uuids = g_settings_get_mapped (&list->parent,
+ TERMINAL_SETTINGS_LIST_LIST_KEY,
+ list_map_func, list);
+
+ _TERMINAL_DEBUG_IF (TERMINAL_DEBUG_SETTINGS_LIST) {
+ g_printerr ("%s: current UUIDs [", G_STRFUNC);
+ strv_printerr (list->uuids);
+ g_printerr ("]\n new UUIDs [");
+ strv_printerr (uuids);
+ g_printerr ("]\n");
+ }
+
+ if (strv_equal (uuids, list->uuids) &&
+ ((list->flags & TERMINAL_SETTINGS_LIST_FLAG_HAS_DEFAULT) == 0 ||
+ strv_find (list->uuids, list->default_uuid) != -1)) {
+ g_strfreev (uuids);
+ return;
+ }
+
+ new_children = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) g_object_unref);
+
+ if (uuids) {
+ for (i = 0; uuids[i] != NULL; i++) {
+ uuid = uuids[i];
+
+ child = g_hash_table_lookup (list->children, uuid);
+
+ if (child) {
+ g_object_ref (child);
+ g_hash_table_remove (list->children, uuid);
+ g_hash_table_insert (new_children, g_strdup (uuid), child /* adopted */);
+ }
+ }
+
+ changed = !strv_equal (uuids, list->uuids);
+ } else {
+ changed = g_strv_length (list->uuids) != 0;
+ }
+
+ g_hash_table_unref (list->children);
+ list->children = new_children;
+
+ g_strfreev (list->uuids);
+ list->uuids = uuids; /* adopts */
+
+ if (changed)
+ g_signal_emit (list, signals[SIGNAL_CHILDREN_CHANGED], 0);
+}
+
+static void
+terminal_settings_list_update_default (TerminalSettingsList *list)
+{
+ if ((list->flags & TERMINAL_SETTINGS_LIST_FLAG_HAS_DEFAULT) == 0)
+ return;
+
+ g_free (list->default_uuid);
+ list->default_uuid = g_settings_get_string (&list->parent,
+ TERMINAL_SETTINGS_LIST_DEFAULT_KEY);
+
+ _terminal_debug_print (TERMINAL_DEBUG_SETTINGS_LIST,
+ "%s new default UUID %s\n", G_STRFUNC, list->default_uuid);
+
+ g_signal_emit (list, signals[SIGNAL_DEFAULT_CHANGED], 0);
+}
+
+G_DEFINE_TYPE (TerminalSettingsList, terminal_settings_list, G_TYPE_SETTINGS);
+
+static void
+terminal_settings_list_changed (GSettings *list_settings,
+ const char *key)
+{
+ TerminalSettingsList *list = TERMINAL_SETTINGS_LIST (list_settings);
+
+ _terminal_debug_print (TERMINAL_DEBUG_SETTINGS_LIST,
+ "%s key %s", G_STRFUNC, key ? key : "(null)");
+
+ if (key == NULL ||
+ g_str_equal (key, TERMINAL_SETTINGS_LIST_LIST_KEY)) {
+ terminal_settings_list_update_list (list);
+ terminal_settings_list_update_default (list);
+ }
+
+ if (key == NULL)
+ return;
+
+ if (g_str_equal (key, TERMINAL_SETTINGS_LIST_DEFAULT_KEY)) {
+ terminal_settings_list_update_default (list);
+ }
+}
+
+static void
+terminal_settings_list_init (TerminalSettingsList *list)
+{
+ list->flags = TERMINAL_SETTINGS_LIST_FLAG_NONE;
+}
+
+static void
+terminal_settings_list_constructed (GObject *object)
+{
+ TerminalSettingsList *list = TERMINAL_SETTINGS_LIST (object);
+
+ G_OBJECT_CLASS (terminal_settings_list_parent_class)->constructed (object);
+
+ g_assert (list->child_schema_id != NULL);
+
+ g_object_get (object, "path", &list->path, NULL);
+
+ list->children = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) g_object_unref);
+
+ terminal_settings_list_changed (&list->parent, NULL);
+}
+
+static void
+terminal_settings_list_finalize (GObject *object)
+{
+ TerminalSettingsList *list = TERMINAL_SETTINGS_LIST (object);
+
+ g_free (list->path);
+ g_free (list->child_schema_id);
+ g_strfreev (list->uuids);
+ g_free (list->default_uuid);
+ g_hash_table_unref (list->children);
+
+ G_OBJECT_CLASS (terminal_settings_list_parent_class)->finalize (object);
+}
+
+static void
+terminal_settings_list_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ TerminalSettingsList *list = TERMINAL_SETTINGS_LIST (object);
+
+ switch (prop_id) {
+ case PROP_CHILD_SCHEMA_ID:
+ list->child_schema_id = g_value_dup_string (value);
+ break;
+ case PROP_FLAGS:
+ list->flags = g_value_get_flags (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+terminal_settings_list_class_init (TerminalSettingsListClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GSettingsClass *settings_class = G_SETTINGS_CLASS (klass);
+
+ object_class->set_property = terminal_settings_list_set_property;
+ object_class->constructed = terminal_settings_list_constructed;
+ object_class->finalize = terminal_settings_list_finalize;
+
+ /**
+ * TerminalSettingsList:child-schema-id:
+ *
+ * The name of the schema of the children of this list.
+ */
+ g_object_class_install_property (object_class, PROP_CHILD_SCHEMA_ID,
+ g_param_spec_string ("child-schema-id", NULL,NULL,
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * TerminalSettingsList:flags:
+ *
+ * Flags from #TerminalSettingsListFlags.
+ */
+ g_object_class_install_property (object_class, PROP_FLAGS,
+ g_param_spec_flags ("flags", NULL,NULL,
+ TERMINAL_TYPE_SETTINGS_LIST_FLAGS,
+ TERMINAL_SETTINGS_LIST_FLAG_NONE,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * TerminalSettingsList::children-changed:
+ * @list: the object on which the signal was emitted
+ *
+ * The "children-changed" signal is emitted when the list of children
+ * has potentially changed.
+ */
+ signals[SIGNAL_CHILDREN_CHANGED] =
+ g_signal_new ("children-changed", TERMINAL_TYPE_SETTINGS_LIST,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (TerminalSettingsListClass, children_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ /**
+ * TerminalSettingsList::default-changed:
+ * @list: the object on which the signal was emitted
+ *
+ * The "default-changed" signal is emitted when the default child
+ * has potentially changed.
+ */
+ signals[SIGNAL_DEFAULT_CHANGED] =
+ g_signal_new ("default-changed", TERMINAL_TYPE_SETTINGS_LIST,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (TerminalSettingsListClass, default_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ settings_class->changed = terminal_settings_list_changed;
+}
+
+
+/**
+ * terminal_settings_list_new:
+ * @path: the settings path for the list
+ * @schema_id: the schema of the list, equal to or derived from "org.gnome.Terminal.SettingsList"
+ * @child_schema_id: the schema of the list children
+ * @flags: list flags
+ *
+ * Returns: (transfer full): the newly created #TerminalSettingsList
+ */
+TerminalSettingsList *
+terminal_settings_list_new (const char *path,
+ const char *schema_id,
+ const char *child_schema_id,
+ TerminalSettingsListFlags flags)
+{
+ g_return_val_if_fail (path != NULL, NULL);
+ g_return_val_if_fail (schema_id != NULL, NULL);
+ g_return_val_if_fail (child_schema_id != NULL, NULL);
+ g_return_val_if_fail (g_str_has_suffix (path, ":/"), NULL);
+
+ return g_object_new (TERMINAL_TYPE_SETTINGS_LIST,
+ "schema-id", schema_id,
+ "child-schema-id", child_schema_id,
+ "path", path,
+ "flags", flags,
+ NULL);
+}
+
+/**
+ * terminal_settings_list_dupv_children:
+ * @list: a #TerminalSettingsList
+ *
+ * Returns: (transfer full): the UUIDs of the children in the settings list, or %NULL
+ * if the list is empty
+ */
+char **
+terminal_settings_list_dupv_children (TerminalSettingsList *list)
+{
+ g_return_val_if_fail (TERMINAL_IS_SETTINGS_LIST (list), NULL);
+
+ return g_strdupv (list->uuids);
+}
+
+/**
+ * terminal_settings_list_dup_default_child:
+ * @list: a #TerminalSettingsList
+ *
+ * Returns: (transfer full): the UUID of the default child in the settings list
+ */
+char *
+terminal_settings_list_dup_default_child (TerminalSettingsList *list)
+{
+ g_return_val_if_fail (TERMINAL_IS_SETTINGS_LIST (list), NULL);
+
+ if ((list->flags & TERMINAL_SETTINGS_LIST_FLAG_HAS_DEFAULT) == 0)
+ return NULL;
+
+ if ((strv_find (list->uuids, list->default_uuid)) != -1)
+ return g_strdup (list->default_uuid);
+
+ /* Just randomly designate the first child as default, but don't write that
+ * to dconf.
+ */
+ if (list->uuids == NULL || list->uuids[0] == NULL) {
+ g_warn_if_fail ((list->flags & TERMINAL_SETTINGS_LIST_FLAG_ALLOW_EMPTY));
+ return NULL;
+ }
+
+ return g_strdup (list->uuids[0]);
+}
+
+/**
+ * terminal_settings_list_has_child:
+ * @list: a #TerminalSettingsList
+ * @uuid: the UUID of a list child
+ *
+ * Returns: %TRUE iff the child with @uuid exists
+ */
+gboolean
+terminal_settings_list_has_child (TerminalSettingsList *list,
+ const char *uuid)
+{
+ g_return_val_if_fail (TERMINAL_IS_SETTINGS_LIST (list), FALSE);
+ g_return_val_if_fail (is_valid_uuid (uuid), FALSE);
+
+ return strv_find (list->uuids, uuid) != -1;
+}
+
+/**
+ * terminal_settings_list_ref_child:
+ * @list: a #TerminalSettingsList
+ * @uuid: the UUID of a list child
+ *
+ * Returns the child #GSettings for the list child with UUID @uuid, or %NULL
+ * if @list has no such child.
+ *
+ * Returns: (transfer full): a reference to the #GSettings for the child, or %NULL
+ */
+GSettings *
+terminal_settings_list_ref_child (TerminalSettingsList *list,
+ const char *uuid)
+{
+ g_return_val_if_fail (TERMINAL_IS_SETTINGS_LIST (list), NULL);
+ g_return_val_if_fail (is_valid_uuid (uuid), NULL);
+
+ return terminal_settings_list_ref_child_internal (list, uuid);
+}
+
+/**
+ * terminal_settings_list_ref_children:
+ * @list: a #TerminalSettingsList
+ *
+ * Returns the list of children #GSettings or @list.
+ *
+ * Returns: (transfer full): a list of child #GSettings of @list
+ */
+GList *
+terminal_settings_list_ref_children (TerminalSettingsList *list)
+{
+ GList *l;
+ guint i;
+
+ g_return_val_if_fail (TERMINAL_IS_SETTINGS_LIST (list), NULL);
+
+ if (list->uuids == NULL)
+ return NULL;
+
+ l = NULL;
+ for (i = 0; list->uuids[i]; i++)
+ l = g_list_prepend (l, terminal_settings_list_ref_child (list, list->uuids[i]));
+
+ return g_list_reverse (l);
+}
+
+/**
+ * terminal_settings_list_ref_default_child:
+ * @list: a #TerminalSettingsList
+ *
+ * Returns the default child #GSettings for the list, or %NULL if @list has no
+ * children.
+ *
+ * Returns: (transfer full): a reference to the #GSettings for the default child, or %NULL
+ */
+GSettings *
+terminal_settings_list_ref_default_child (TerminalSettingsList *list)
+{
+ char *uuid;
+
+ g_return_val_if_fail (TERMINAL_IS_SETTINGS_LIST (list), NULL);
+
+ uuid = terminal_settings_list_dup_default_child (list);
+ if (uuid == NULL)
+ return NULL;
+
+ return terminal_settings_list_ref_child_internal (list, uuid);
+}
+
+/**
+ * terminal_settings_list_add_child:
+ * @list: a #TerminalSettingsList
+ *
+ * Adds a new child to the list, and returns a reference to its #GSettings.
+ *
+ * Returns: (transfer full): the UUID of new child
+ */
+char *
+terminal_settings_list_add_child (TerminalSettingsList *list)
+{
+ g_return_val_if_fail (TERMINAL_IS_SETTINGS_LIST (list), NULL);
+
+ return terminal_settings_list_add_child_internal (list, NULL);
+}
+
+/**
+ * terminal_settings_list_clone_child:
+ * @list: a #TerminalSettingsList
+ * @uuid: the UUID of the child to clone
+ *
+ * Adds a new child to the list, and returns a reference to its #GSettings.
+ * All keys of the new child will have the same value as @uuid's.
+ *
+ * Returns: (transfer full): the UUID of new child
+ */
+char *
+terminal_settings_list_clone_child (TerminalSettingsList *list,
+ const char *uuid)
+{
+ g_return_val_if_fail (TERMINAL_IS_SETTINGS_LIST (list), NULL);
+ g_return_val_if_fail (is_valid_uuid (uuid), NULL);
+
+ return terminal_settings_list_add_child_internal (list, uuid);
+}
+
+/**
+ * terminal_settings_list_remove_child:
+ * @list: a #TerminalSettingsList
+ * @uuid: the UUID of a list child
+ *
+ * Removes the child with UUID @uuid from the list.
+ */
+void
+terminal_settings_list_remove_child (TerminalSettingsList *list,
+ const char *uuid)
+{
+ g_return_if_fail (TERMINAL_IS_SETTINGS_LIST (list));
+ g_return_if_fail (is_valid_uuid (uuid));
+
+ terminal_settings_list_remove_child_internal (list, uuid);
+}
+
+/**
+ * terminal_settings_list_dup_uuid_from_child:
+ * @list: a #TerminalSettingsList
+ * @child: a #GSettings of a child in the list
+ *
+ * Returns the UUID of @child in the list, or %NULL if @child is in the list.
+ *
+ * Returns: (transfer full): the UUID of the child in the settings list, or %NULL
+ */
+char *
+terminal_settings_list_dup_uuid_from_child (TerminalSettingsList *list,
+ GSettings *child)
+{
+ char *path, *p;
+
+ g_return_val_if_fail (TERMINAL_IS_SETTINGS_LIST (list), NULL);
+
+ g_object_get (child, "path", &path, NULL);
+ g_return_val_if_fail (g_str_has_prefix (path, list->path), NULL);
+
+ p = path + strlen (list->path);
+ g_return_val_if_fail (p[0] == ':', NULL);
+ p++;
+ g_return_val_if_fail (strlen (p) == 37, NULL);
+ p[36] = '\0';
+ g_return_val_if_fail (is_valid_uuid (p), NULL);
+
+ p = g_strdup (p);
+ g_free (path);
+ return p;
+}
+
+/**
+ * terminal_settings_list_get_set_default_child:
+ * @list: a #TerminalSettingsList
+ * @uuid: the UUID of a child in the list
+ *
+ * Sets @uuid as the default child.
+ */
+void
+terminal_settings_list_set_default_child (TerminalSettingsList *list,
+ const char *uuid)
+{
+ g_return_if_fail (TERMINAL_IS_SETTINGS_LIST (list));
+ g_return_if_fail (is_valid_uuid (uuid));
+
+ if (!terminal_settings_list_has_child (list, uuid))
+ return;
+
+ g_settings_set_string (&list->parent, TERMINAL_SETTINGS_LIST_DEFAULT_KEY, uuid);
+}
diff --git a/src/terminal-settings-list.h b/src/terminal-settings-list.h
new file mode 100644
index 0000000..ff00c99
--- /dev/null
+++ b/src/terminal-settings-list.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright  2013 Christian Persch
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TERMINAL_SETTINGS_LIST_H
+#define TERMINAL_SETTINGS_LIST_H
+
+#include <gio/gio.h>
+
+#include "terminal-enums.h"
+
+G_BEGIN_DECLS
+
+#define TERMINAL_TYPE_SETTINGS_LIST (terminal_settings_list_get_type ())
+#define TERMINAL_SETTINGS_LIST(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), TERMINAL_TYPE_SETTINGS_LIST, TerminalSettingsList))
+#define TERMINAL_SETTINGS_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TERMINAL_TYPE_SETTINGS_LIST, TerminalSettingsListClass))
+#define TERMINAL_IS_SETTINGS_LIST(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), TERMINAL_TYPE_SETTINGS_LIST))
+#define TERMINAL_IS_SETTINGS_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TERMINAL_TYPE_SETTINGS_LIST))
+#define TERMINAL_SETTINGS_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TERMINAL_TYPE_SETTINGS_LIST, TerminalSettingsListClass))
+
+typedef struct _TerminalSettingsList TerminalSettingsList;
+typedef struct _TerminalSettingsListClass TerminalSettingsListClass;
+
+GType terminal_settings_list_get_type (void);
+
+TerminalSettingsList *terminal_settings_list_new (const char *path,
+ const char *schema_id,
+ const char *child_schema_id,
+ TerminalSettingsListFlags flags);
+
+char **terminal_settings_list_dupv_children (TerminalSettingsList *list);
+
+GList *terminal_settings_list_ref_children (TerminalSettingsList *list);
+
+gboolean terminal_settings_list_has_child (TerminalSettingsList *list,
+ const char *uuid);
+
+GSettings *terminal_settings_list_ref_child (TerminalSettingsList *list,
+ const char *uuid);
+
+char *terminal_settings_list_add_child (TerminalSettingsList *list);
+
+char *terminal_settings_list_clone_child (TerminalSettingsList *list,
+ const char *uuid);
+
+void terminal_settings_list_remove_child (TerminalSettingsList *list,
+ const char *uuid);
+
+char *terminal_settings_list_dup_uuid_from_child (TerminalSettingsList *list,
+ GSettings *child);
+
+GSettings *terminal_settings_list_ref_default_child (TerminalSettingsList *list);
+
+char *terminal_settings_list_dup_default_child (TerminalSettingsList *list);
+
+void terminal_settings_list_set_default_child (TerminalSettingsList *list,
+ const char *uuid);
+
+G_END_DECLS
+
+#endif /* TERMINAL_SETTINGS_LIST_H */
diff --git a/src/terminal-window.c b/src/terminal-window.c
index 8162132..638e67d 100644
--- a/src/terminal-window.c
+++ b/src/terminal-window.c
@@ -511,6 +511,7 @@ terminal_window_update_set_profile_menu (TerminalWindow *window)
GSettings *active_profile;
GtkActionGroup *action_group;
GtkAction *action;
+ TerminalSettingsList *profiles_list;
GList *profiles, *p;
GSList *group;
guint n;
@@ -531,11 +532,13 @@ terminal_window_update_set_profile_menu (TerminalWindow *window)
priv->profiles_action_group = NULL;
}
- profiles = terminal_app_get_profile_list (terminal_app_get ());
+ profiles_list = terminal_app_get_profiles_list (terminal_app_get ());
+ profiles = terminal_profiles_list_ref_children (profiles_list);
action = gtk_action_group_get_action (priv->action_group, "TerminalProfiles");
single_profile = !profiles || profiles->next == NULL; /* list length <= 1 */
gtk_action_set_sensitive (action, !single_profile);
+
if (profiles == NULL)
return;
@@ -595,7 +598,7 @@ terminal_window_update_set_profile_menu (TerminalWindow *window)
GTK_UI_MANAGER_MENUITEM, FALSE);
}
- g_list_free (profiles);
+ g_list_free_full (profiles, (GDestroyNotify) g_object_unref);
}
static void
@@ -629,6 +632,7 @@ terminal_window_update_new_terminal_menus (TerminalWindow *window)
TerminalWindowPrivate *priv = window->priv;
GtkActionGroup *action_group;
GtkAction *action;
+ TerminalSettingsList *profiles_list;
GList *profiles, *p;
guint n;
gboolean have_single_profile;
@@ -648,7 +652,9 @@ terminal_window_update_new_terminal_menus (TerminalWindow *window)
priv->new_terminal_action_group = NULL;
}
- profiles = terminal_app_get_profile_list (terminal_app_get ());
+ profiles_list = terminal_app_get_profiles_list (terminal_app_get ());
+ profiles = terminal_profiles_list_ref_children (profiles_list);
+
have_single_profile = !profiles || !profiles->next;
action = gtk_action_group_get_action (priv->action_group, "FileNewTab");
@@ -658,7 +664,7 @@ terminal_window_update_new_terminal_menus (TerminalWindow *window)
if (have_single_profile)
{
- g_list_free (profiles);
+ g_list_free_full (profiles, (GDestroyNotify) g_object_unref);
return;
}
@@ -703,7 +709,7 @@ terminal_window_update_new_terminal_menus (TerminalWindow *window)
++n;
}
- g_list_free (profiles);
+ g_list_free_full (profiles, (GDestroyNotify) g_object_unref);
}
static void
@@ -1596,7 +1602,7 @@ terminal_window_screen_changed (GtkWidget *widget,
}
static void
-terminal_window_profile_list_changed_cb (TerminalApp *app,
+terminal_window_profile_list_changed_cb (TerminalSettingsList *profiles_list,
TerminalWindow *window)
{
terminal_window_update_set_profile_menu (window);
@@ -1799,6 +1805,7 @@ terminal_window_init (TerminalWindow *window)
};
TerminalWindowPrivate *priv;
TerminalApp *app;
+ TerminalSettingsList *profiles_list;
GtkActionGroup *action_group;
GtkAction *action;
GtkUIManager *manager;
@@ -1916,8 +1923,9 @@ terminal_window_init (TerminalWindow *window)
priv->tabs_menu = terminal_tabs_menu_new (window);
app = terminal_app_get ();
- terminal_window_profile_list_changed_cb (app, window);
- g_signal_connect (app, "profile-list-changed",
+ profiles_list = terminal_app_get_profiles_list (app);
+ terminal_window_profile_list_changed_cb (profiles_list, window);
+ g_signal_connect (profiles_list, "children-changed",
G_CALLBACK (terminal_window_profile_list_changed_cb), window);
terminal_window_encoding_list_changed_cb (app, window);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]