[gnome-terminal] client: Allow specifying a profile by UUID or name



commit f728cf6ce5e3668bbe94e7543b12889e8c936443
Author: Christian Persch <chpe gnome org>
Date:   Wed Jan 23 00:00:24 2013 +0100

    client: Allow specifying a profile by UUID or name
    
    When a profile with the given string doesn't exist, try finding it by name.

 src/Makefile.am              |    8 ++
 src/client.c                 |   21 ++++-
 src/terminal-app.c           |   46 +---------
 src/terminal-client-utils.c  |    2 +-
 src/terminal-client-utils.h  |    3 +
 src/terminal-options.c       |   20 +++-
 src/terminal-profile-utils.c |  207 ++++++++++++++++++++++++++++++++++++++++++
 src/terminal-profile-utils.h |   36 +++++++
 8 files changed, 294 insertions(+), 49 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 6aa34de..1983be6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -50,6 +50,8 @@ gnome_terminal_server_SOURCES = \
 	terminal-mdi-container.h \
 	terminal-notebook.c \
 	terminal-notebook.h \
+	terminal-profile-utils.c \
+	terminal-profile-utils.h \
 	terminal-schemas.h \
 	terminal-screen.c \
 	terminal-screen.h \
@@ -147,6 +149,9 @@ gnome_terminal_client_SOURCES = \
 	terminal-client-utils.h \
 	terminal-defines.h \
 	terminal-intl.h \
+	terminal-profile-utils.c \
+	terminal-profile-utils.h \
+	terminal-schemas.h \
 	$(NULL)
 
 nodist_gnome_terminal_client_SOURCES = \
@@ -186,6 +191,9 @@ gnome_terminal_SOURCES = \
 	terminal-intl.h \
 	terminal-options.c \
 	terminal-options.h \
+	terminal-profile-utils.c \
+	terminal-profile-utils.h \
+	terminal-schemas.h \
 	$(NULL)
 
 nodist_gnome_terminal_SOURCES = \
diff --git a/src/client.c b/src/client.c
index f0e19ea..1f845df 100644
--- a/src/client.c
+++ b/src/client.c
@@ -44,6 +44,7 @@
 #include "terminal-gdbus-generated.h"
 #include "terminal-defines.h"
 #include "terminal-client-utils.h"
+#include "terminal-profile-utils.h"
 
 static gboolean quiet = FALSE;
 
@@ -327,6 +328,24 @@ option_fd_cb (const gchar *option_name,
   return TRUE;
 }
 
+static gboolean
+option_profile_cb (const gchar *option_name,
+                   const gchar *value,
+                   gpointer     user_data,
+                   GError     **error)
+{
+  OptionData *data = user_data;
+
+  if (data->profile != NULL) {
+    g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
+                 "May only use option %s once", option_name);
+    return FALSE;
+  }
+
+  data->profile = terminal_profile_util_get_profile_by_uuid (value, error);
+  return data->profile != NULL;
+}
+
 static GOptionContext *
 get_goption_context (OptionData *data)
 {
@@ -354,7 +373,7 @@ get_goption_context (OptionData *data)
   };
 
   const GOptionEntry terminal_goptions[] = {
-    { "profile", 0, 0, G_OPTION_ARG_STRING, &data->profile,
+    { "profile", 0, 0, G_OPTION_ARG_CALLBACK, option_profile_cb,
       N_("Use the given profile instead of the default profile"),
       N_("UUID") },
     { "title", 0, 0, G_OPTION_ARG_STRING, &data->title,
diff --git a/src/terminal-app.c b/src/terminal-app.c
index 9883f65..58541db 100644
--- a/src/terminal-app.c
+++ b/src/terminal-app.c
@@ -32,6 +32,7 @@
 #include "terminal-screen.h"
 #include "terminal-screen-container.h"
 #include "terminal-window.h"
+#include "terminal-profile-utils.h"
 #include "terminal-util.h"
 #include "profile-editor.h"
 #include "terminal-encoding.h"
@@ -811,46 +812,6 @@ profile_list_row_activated_cb (GtkTreeView       *tree_view,
   g_object_unref (selected_profile);
 }
 
-static gboolean
-validate_profile_name (const char *name)
-{
-  uuid_t u;
-
-  return uuid_parse ((char *) name, u) == 0;
-}
-
-static gboolean
-validate_profile_list (char **profiles)
-{
-  guint i;
-
-  g_assert (profiles != NULL);
-
-  for (i = 0; profiles[i]; i++) {
-    if (!validate_profile_name (profiles[i]))
-      return FALSE;
-  }
-
-  return i > 0;
-}
-
-static gboolean
-map_profiles_list (GVariant *value,
-                   gpointer *result,
-                   gpointer user_data G_GNUC_UNUSED)
-{
-  char **profiles;
-
-  g_variant_get (value, "^a&s", &profiles);
-  if (validate_profile_list (profiles)) {
-    *result = profiles;
-    return TRUE;
-  }
-
-  g_free (profiles);
-  return FALSE;
-}
-
 static void
 terminal_app_profile_list_changed_cb (GSettings *settings,
                                       const char *key,
@@ -864,8 +825,7 @@ terminal_app_profile_list_changed_cb (GSettings *settings,
   /* 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 = g_settings_get_mapped (app->global_settings, TERMINAL_SETTING_PROFILES_KEY,
-                                    map_profiles_list, NULL);
+  profiles = terminal_profile_util_get_profiles (app->global_settings);
   g_settings_get (app->global_settings, TERMINAL_SETTING_DEFAULT_PROFILE_KEY,
                   "&s", &default_profile);
 
@@ -895,7 +855,7 @@ terminal_app_profile_list_changed_cb (GSettings *settings,
 
     g_hash_table_insert (new_profiles, g_strdup (name) /* adopted */, profile /* adopted */);
   }
-  g_free (profiles);
+  g_strfreev (profiles);
 
   g_assert (g_hash_table_size (new_profiles) > 0);
 
diff --git a/src/terminal-client-utils.c b/src/terminal-client-utils.c
index 5c44494..737240f 100644
--- a/src/terminal-client-utils.c
+++ b/src/terminal-client-utils.c
@@ -3,7 +3,7 @@
  * Copyright  2002 Red Hat, Inc.
  * Copyright  2002 Sun Microsystems
  * Copyright  2003 Mariano Suarez-Alvarez
- * Copyright  2011 Christian Persch
+ * 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
diff --git a/src/terminal-client-utils.h b/src/terminal-client-utils.h
index 494f3de..3f9a30b 100644
--- a/src/terminal-client-utils.h
+++ b/src/terminal-client-utils.h
@@ -22,6 +22,9 @@
 
 G_BEGIN_DECLS
 
+char *terminal_client_get_profile (const char *name_or_id,
+                                   GError **error);
+
 void terminal_client_append_create_instance_options (GVariantBuilder *builder,
                                                      const char      *display_name,
                                                      const char      *startup_id,
diff --git a/src/terminal-options.c b/src/terminal-options.c
index d27b49b..c0db827 100644
--- a/src/terminal-options.c
+++ b/src/terminal-options.c
@@ -31,6 +31,7 @@
 #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"
 
@@ -296,19 +297,24 @@ option_profile_cb (const gchar *option_name,
                    GError     **error)
 {
   TerminalOptions *options = data;
+  char *profile;
+
+  profile = terminal_profile_util_get_profile_by_uuid_or_name (value, error);
+  if (profile == NULL)
+    return FALSE;
 
   if (options->initial_windows)
     {
       InitialTab *it = ensure_top_tab (options);
 
       g_free (it->profile);
-      it->profile = g_strdup (value);
+      it->profile = profile;
       it->profile_is_id = FALSE;
     }
   else
     {
       g_free (options->default_profile);
-      options->default_profile = g_strdup (value);
+      options->default_profile = profile;
       options->default_profile_is_id = FALSE;
     }
 
@@ -322,19 +328,25 @@ option_profile_id_cb (const gchar *option_name,
                       GError     **error)
 {
   TerminalOptions *options = data;
+  char *profile;
+
+  profile = terminal_profile_util_get_profile_by_uuid (value, error);
+  if (profile == NULL)
+    return FALSE;
+
 
   if (options->initial_windows)
     {
       InitialTab *it = ensure_top_tab (options);
 
       g_free (it->profile);
-      it->profile = g_strdup (value);
+      it->profile = profile;
       it->profile_is_id = TRUE;
     }
   else
     {
       g_free (options->default_profile);
-      options->default_profile = g_strdup (value);
+      options->default_profile = profile;
       options->default_profile_is_id = TRUE;
     }
 
diff --git a/src/terminal-profile-utils.c b/src/terminal-profile-utils.c
new file mode 100644
index 0000000..24fdff1
--- /dev/null
+++ b/src/terminal-profile-utils.c
@@ -0,0 +1,207 @@
+/*
+ * 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-profile-utils.h"
+#include "terminal-schemas.h"
+
+#include <string.h>
+#include <uuid.h>
+
+static gboolean
+validate_profile_name (const char *name)
+{
+  uuid_t u;
+
+  return uuid_parse ((char *) name, u) == 0;
+}
+
+static gboolean
+validate_profile_list (char **profiles)
+{
+  guint i;
+
+  if (profiles == NULL)
+    return FALSE;
+
+  for (i = 0; profiles[i]; i++) {
+    if (!validate_profile_name (profiles[i]))
+      return FALSE;
+  }
+
+  return i > 0;
+}
+
+static gboolean
+map_profiles_list (GVariant *value,
+                   gpointer *result,
+                   gpointer user_data G_GNUC_UNUSED)
+{
+  char **profiles;
+
+  profiles = g_variant_dup_strv (value, NULL);
+  if (validate_profile_list (profiles)) {
+    *result = profiles;
+    return TRUE;
+  }
+
+  g_strfreev (profiles);
+  return FALSE;
+}
+
+/**
+ * terminal_profile_util_get_profiles:
+ * @settings: a #GSettings for the TERMINAL_SETTINGS_SCHEMA schema
+ *
+ * Returns: (transfer full): the list of profile UUIDs, or %NULL
+ */
+char **
+terminal_profile_util_get_profiles (GSettings *settings)
+{
+  /* 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.
+   */
+  return g_settings_get_mapped (settings,
+                                TERMINAL_SETTING_PROFILES_KEY,
+                                map_profiles_list, NULL);
+}
+
+static char **
+get_profiles (void)
+{
+  GSettings *settings;
+  char **profiles;
+
+  settings = g_settings_new (TERMINAL_SETTING_SCHEMA);
+  profiles = terminal_profile_util_get_profiles (settings);
+  g_object_unref (settings);
+
+  return profiles;
+}
+
+static char **
+get_profile_names (char **profiles)
+{
+  GSettings *profile;
+  char **names, *path;
+  guint i, n;
+
+  n = g_strv_length (profiles);
+  names = g_new0 (char *, n + 1);
+  for (i = 0; i < n; i++) {
+    path = g_strdup_printf (TERMINAL_PROFILES_PATH_PREFIX ":%s/", profiles[i]);
+    profile = g_settings_new_with_path (TERMINAL_PROFILE_SCHEMA, path);
+    g_free (path);
+
+    names[i] = g_settings_get_string (profile, TERMINAL_PROFILE_VISIBLE_NAME_KEY);
+    g_object_unref (profile);
+  }
+
+  names[n] = NULL;
+  return names;
+}
+
+/* Counts occurrences of @str in @strv */
+static guint
+strv_contains (char **strv,
+               const char *str)
+{
+  guint n;
+
+  if (strv == NULL)
+    return 0;
+
+  n = 0;
+  for ( ; *strv; strv++)
+    if (strcmp (*strv, str) == 0)
+      n++;
+
+  return n;
+}
+
+/**
+ * terminal_profile_util_get_profile_by_uuid:
+ * @uuid:
+ * @error:
+ *
+ * Returns: (transfer full): the UUID of the profile specified by @uuid, or %NULL
+ */
+char *
+terminal_profile_util_get_profile_by_uuid (const char *uuid,
+                                           GError **error)
+{
+  char **profiles;
+  guint n;
+
+  profiles = get_profiles ();
+  n = strv_contains (profiles, uuid);
+  g_strfreev (profiles);
+
+  if (n != 0)
+    return g_strdup (uuid);
+
+  g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
+               "No profile with UUID \"%s\" exists", uuid);
+  return NULL;
+}
+
+/**
+ * terminal_profile_util_get_profile_by_uuid:
+ * @uuid:
+ * @error:
+ *
+ * Returns: (transfer full): the UUID of the profile specified by @uuid, or %NULL
+ */
+char *
+terminal_profile_util_get_profile_by_uuid_or_name (const char *uuid_or_name,
+                                                   GError **error)
+{
+  char **profiles, **profile_names;
+  guint n;
+
+  profiles = get_profiles ();
+  n = strv_contains (profiles, uuid_or_name);
+
+  if (n != 0) {
+    g_strfreev (profiles);
+    return g_strdup (uuid_or_name);
+  }
+
+  /* Not found as UUID; try finding a profile with this string as 'visible-name' */
+  profile_names = get_profile_names (profiles);
+  g_strfreev (profiles);
+
+  n = strv_contains (profile_names, uuid_or_name);
+  g_strfreev (profile_names);
+
+  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);
+    return 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);
+    return NULL;
+  }
+
+  return g_strdup (uuid_or_name);
+}
diff --git a/src/terminal-profile-utils.h b/src/terminal-profile-utils.h
new file mode 100644
index 0000000..c71e059
--- /dev/null
+++ b/src/terminal-profile-utils.h
@@ -0,0 +1,36 @@
+/*
+ * 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_PROFILE_UTILS_H
+#define TERMINAL_PROFILE_UTILS_H
+
+#include <glib.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+char **terminal_profile_util_get_profiles (GSettings *settings);
+
+char *terminal_profile_util_get_profile_by_uuid (const char *uuid,
+                                                 GError **error);
+
+char *terminal_profile_util_get_profile_by_uuid_or_name (const char *uuid_or_name,
+                                                         GError **error);
+
+G_END_DECLS
+
+#endif /* TERMINAL_UTIL_UTILS_H */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]