/*
* 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 .
*/
#include "config.h"
#include "terminal-profiles-list.h"
#include "terminal-schemas.h"
#include "terminal-libgsystem.h"
#include
#include
/* 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;
}
static gboolean
valid_uuid (const char *str,
GError **error)
{
if (terminal_settings_list_valid_uuid (str))
return TRUE;
g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
"\"%s\" is not a valid UUID", str);
return FALSE;
}
/**
* 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)
{
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++) {
gs_unref_object GSettings *profile;
profile = terminal_settings_list_ref_child (list, profiles[i]);
names[i] = g_settings_get_string (profile, TERMINAL_PROFILE_VISIBLE_NAME_KEY);
}
names[n] = NULL;
}
/**
* terminal_profiles_list_ref_children_sorted:
* @list:
*
* Returns: (transfer full):
*/
GList *
terminal_profiles_list_ref_children_sorted (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;
} else if (!valid_uuid (uuid, error))
return NULL;
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)
{
gs_free 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);
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)
{
gs_free 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_assert (profile != NULL);
return profile;
}
int
terminal_profiles_compare (gconstpointer pa,
gconstpointer pb)
{
GSettings *a = (GSettings *) pa;
GSettings *b = (GSettings *) pb;
gs_free char *na = NULL;
gs_free char *nb = NULL;
gs_free char *patha = NULL;
gs_free char *pathb = NULL;
int result;
if (pa == pb)
return 0;
if (pa == NULL)
return 1;
if (pb == NULL)
return -1;
na = g_settings_get_string (a, TERMINAL_PROFILE_VISIBLE_NAME_KEY);
nb = g_settings_get_string (b, TERMINAL_PROFILE_VISIBLE_NAME_KEY);
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);
return strcmp (patha, pathb);
}