Skip to content

Commit

Permalink
Remove the gedit style scheme manager instance
Browse files Browse the repository at this point in the history
Instead of reimplementing our singleton for the style scheme manager,
leverage the gtksourceview one, so that plugins can simply obtain it
with get_default(). We just need to make sure the search path is set
at startup before any document is opened.
The utility functions to install/uninstall a style scheme are now in
the pref dialog file since in five years we never needed to export them
or use them in another context.
  • Loading branch information
pbor committed Feb 2, 2012
1 parent 039f516 commit f5d46ef
Show file tree
Hide file tree
Showing 9 changed files with 283 additions and 425 deletions.
2 changes: 0 additions & 2 deletions gedit/Makefile.am
Expand Up @@ -123,7 +123,6 @@ NOINST_H_FILES = \
gedit-session.h \
gedit-settings.h \
gedit-status-combo-box.h \
gedit-style-scheme-manager.h \
gedit-tab-label.h \
gedittextregion.h \
gedit-ui.h \
Expand Down Expand Up @@ -208,7 +207,6 @@ libgedit_c_files = \
gedit-settings.c \
gedit-statusbar.c \
gedit-status-combo-box.c \
gedit-style-scheme-manager.c \
gedit-tab.c \
gedit-tab-label.c \
gedit-utils.c \
Expand Down
267 changes: 248 additions & 19 deletions gedit/dialogs/gedit-preferences-dialog.c
Expand Up @@ -35,15 +35,17 @@

#include <stdio.h>
#include <string.h>
#include <errno.h>

#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <libpeas-gtk/peas-gtk-plugin-manager.h>
#include <gtksourceview/gtksourcestyleschememanager.h>

#include "gedit-preferences-dialog.h"
#include "gedit-utils.h"
#include "gedit-debug.h"
#include "gedit-document.h"
#include "gedit-style-scheme-manager.h"
#include "gedit-dirs.h"
#include "gedit-settings.h"
#include "gedit-utils.h"
Expand Down Expand Up @@ -464,16 +466,36 @@ setup_font_colors_page_font_section (GeditPreferencesDialog *dlg)
G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
}

static gboolean
is_gedit_user_style_scheme (const gchar *scheme_id)
{
GtkSourceStyleSchemeManager *manager;
GtkSourceStyleScheme *scheme;
gboolean res = FALSE;

manager = gtk_source_style_scheme_manager_get_default ();
scheme = gtk_source_style_scheme_manager_get_scheme (manager, scheme_id);
if (scheme != NULL)
{
const gchar *filename;

filename = gtk_source_style_scheme_get_filename (scheme);
if (filename != NULL)
{
res = g_str_has_prefix (filename, gedit_dirs_get_user_styles_dir ());
}
}

return res;
}

static void
set_buttons_sensisitivity_according_to_scheme (GeditPreferencesDialog *dlg,
const gchar *scheme_id)
{
gboolean editable;

editable = (scheme_id != NULL) &&
_gedit_style_scheme_manager_scheme_is_gedit_user_scheme (
gedit_get_style_scheme_manager (),
scheme_id);

editable = ((scheme_id != NULL) && is_gedit_user_style_scheme (scheme_id));

gtk_widget_set_sensitive (dlg->priv->uninstall_scheme_button,
editable);
Expand Down Expand Up @@ -509,9 +531,10 @@ static const gchar *
ensure_color_scheme_id (GeditPreferencesDialog *dlg,
const gchar *id)
{
GtkSourceStyleSchemeManager *manager;
GtkSourceStyleScheme *scheme = NULL;
GtkSourceStyleSchemeManager *manager = gedit_get_style_scheme_manager ();

manager = gtk_source_style_scheme_manager_get_default ();
if (id == NULL)
{
gchar *pref_id;
Expand Down Expand Up @@ -545,13 +568,10 @@ ensure_color_scheme_id (GeditPreferencesDialog *dlg,
return gtk_source_style_scheme_get_id (scheme);
}

/* If def_id is NULL, use the default scheme as returned by
* gedit_style_scheme_manager_get_default_scheme. If this one returns NULL
* use the first available scheme as default */
static const gchar *
populate_color_scheme_list (GeditPreferencesDialog *dlg, const gchar *def_id)
{
GtkSourceStyleSchemeManager *sm;
GtkSourceStyleSchemeManager *manager;
const gchar * const *ids;
gint i;

Expand All @@ -565,16 +585,16 @@ populate_color_scheme_list (GeditPreferencesDialog *dlg, const gchar *def_id)
return NULL;
}

sm = gedit_get_style_scheme_manager ();
ids = gtk_source_style_scheme_manager_get_scheme_ids (sm);
manager = gtk_source_style_scheme_manager_get_default ();
ids = gtk_source_style_scheme_manager_get_scheme_ids (manager);
for (i = 0; ids[i] != NULL; i++)
{
GtkSourceStyleScheme *scheme;
const gchar *name;
const gchar *description;
GtkTreeIter iter;

scheme = gtk_source_style_scheme_manager_get_scheme (sm, ids[i]);
scheme = gtk_source_style_scheme_manager_get_scheme (manager, ids[i]);

name = gtk_source_style_scheme_get_name (scheme);
description = gtk_source_style_scheme_get_description (scheme);
Expand All @@ -600,6 +620,217 @@ populate_color_scheme_list (GeditPreferencesDialog *dlg, const gchar *def_id)
return def_id;
}

/*
* file_copy:
* @name: a pointer to a %NULL-terminated string, that names
* the file to be copied, in the GLib file name encoding
* @dest_name: a pointer to a %NULL-terminated string, that is the
* name for the destination file, in the GLib file name encoding
* @error: return location for a #GError, or %NULL
*
* Copies file @name to @dest_name.
*
* If the call was successful, it returns %TRUE. If the call was not
* successful, it returns %FALSE and sets @error. The error domain
* is #G_FILE_ERROR. Possible error
* codes are those in the #GFileError enumeration.
*
* Return value: %TRUE on success, %FALSE otherwise.
*/
static gboolean
file_copy (const gchar *name,
const gchar *dest_name,
GError **error)
{
gchar *contents;
gsize length;
gchar *dest_dir;

/* FIXME - Paolo (Aug. 13, 2007):
* Since the style scheme files are relatively small, we can implement
* file copy getting all the content of the source file in a buffer and
* then write the content to the destination file. In this way we
* can use the g_file_get_contents and g_file_set_contents and avoid to
* write custom code to copy the file (with sane error management).
* If needed we can improve this code later. */

g_return_val_if_fail (name != NULL, FALSE);
g_return_val_if_fail (dest_name != NULL, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

/* Note: we allow to copy a file to itself since this is not a problem
* in our use case */

/* Ensure the destination directory exists */
dest_dir = g_path_get_dirname (dest_name);

errno = 0;
if (g_mkdir_with_parents (dest_dir, 0755) != 0)
{
gint save_errno = errno;
gchar *display_filename = g_filename_display_name (dest_dir);

g_set_error (error,
G_FILE_ERROR,
g_file_error_from_errno (save_errno),
_("Directory '%s' could not be created: g_mkdir_with_parents() failed: %s"),
display_filename,
g_strerror (save_errno));

g_free (dest_dir);
g_free (display_filename);

return FALSE;
}

g_free (dest_dir);

if (!g_file_get_contents (name, &contents, &length, error))
return FALSE;

if (!g_file_set_contents (dest_name, contents, length, error))
return FALSE;

g_free (contents);

return TRUE;
}

/*
* install_style_scheme:
* @manager: a #GtkSourceStyleSchemeManager
* @fname: the file name of the style scheme to be installed
*
* Install a new user scheme.
* This function copies @fname in #GEDIT_STYLES_DIR and ask the style manager to
* recompute the list of available style schemes. It then checks if a style
* scheme with the right file name exists.
*
* If the call was succesful, it returns the id of the installed scheme
* otherwise %NULL.
*
* Return value: the id of the installed scheme, %NULL otherwise.
*/
static const gchar *
install_style_scheme (const gchar *fname)
{
GtkSourceStyleSchemeManager *manager;
gchar *new_file_name = NULL;
gchar *dirname;
const gchar *styles_dir;
GError *error = NULL;
gboolean copied = FALSE;
const gchar* const *ids;

g_return_val_if_fail (fname != NULL, NULL);

manager = gtk_source_style_scheme_manager_get_default ();

dirname = g_path_get_dirname (fname);
styles_dir = gedit_dirs_get_user_styles_dir ();

if (strcmp (dirname, styles_dir) != 0)
{
gchar *basename;

basename = g_path_get_basename (fname);
new_file_name = g_build_filename (styles_dir, basename, NULL);
g_free (basename);

/* Copy the style scheme file into GEDIT_STYLES_DIR */
if (!file_copy (fname, new_file_name, &error))
{
g_free (new_file_name);

g_message ("Cannot install style scheme:\n%s",
error->message);

return NULL;
}

copied = TRUE;
}
else
{
new_file_name = g_strdup (fname);
}

g_free (dirname);

/* Reload the available style schemes */
gtk_source_style_scheme_manager_force_rescan (manager);

/* Check the new style scheme has been actually installed */
ids = gtk_source_style_scheme_manager_get_scheme_ids (manager);

while (*ids != NULL)
{
GtkSourceStyleScheme *scheme;
const gchar *filename;

scheme = gtk_source_style_scheme_manager_get_scheme (manager, *ids);

filename = gtk_source_style_scheme_get_filename (scheme);

if (filename && (strcmp (filename, new_file_name) == 0))
{
/* The style scheme has been correctly installed */
g_free (new_file_name);

return gtk_source_style_scheme_get_id (scheme);
}
++ids;
}

/* The style scheme has not been correctly installed */
if (copied)
g_unlink (new_file_name);

g_free (new_file_name);

return NULL;
}

/**
* uninstall_style_scheme:
* @manager: a #GtkSourceStyleSchemeManager
* @id: the id of the style scheme to be uninstalled
*
* Uninstall a user scheme.
*
* If the call was succesful, it returns %TRUE
* otherwise %FALSE.
*
* Return value: %TRUE on success, %FALSE otherwise.
*/
static gboolean
uninstall_style_scheme (const gchar *id)
{
GtkSourceStyleSchemeManager *manager;
GtkSourceStyleScheme *scheme;
const gchar *filename;

g_return_val_if_fail (id != NULL, FALSE);

manager = gtk_source_style_scheme_manager_get_default ();

scheme = gtk_source_style_scheme_manager_get_scheme (manager, id);
if (scheme == NULL)
return FALSE;

filename = gtk_source_style_scheme_get_filename (scheme);
if (filename == NULL)
return FALSE;

if (g_unlink (filename) == -1)
return FALSE;

/* Reload the available style schemes */
gtk_source_style_scheme_manager_force_rescan (manager);

return TRUE;
}

static void
add_scheme_chooser_response_cb (GtkDialog *chooser,
gint res_id,
Expand All @@ -619,10 +850,8 @@ add_scheme_chooser_response_cb (GtkDialog *chooser,
return;

gtk_widget_hide (GTK_WIDGET (chooser));

scheme_id = _gedit_style_scheme_manager_install_scheme (
gedit_get_style_scheme_manager (),
filename);

scheme_id = install_style_scheme (filename);
g_free (filename);

if (scheme_id == NULL)
Expand Down Expand Up @@ -719,7 +948,7 @@ uninstall_scheme_clicked (GtkButton *button,
NAME_COLUMN, &name,
-1);

if (!_gedit_style_scheme_manager_uninstall_scheme (gedit_get_style_scheme_manager (), id))
if (!uninstall_style_scheme (id))
{
gedit_warning (GTK_WINDOW (dlg),
_("Could not remove color scheme \"%s\"."),
Expand Down
12 changes: 12 additions & 0 deletions gedit/gedit-app.c
Expand Up @@ -37,6 +37,7 @@

#include <glib/gi18n.h>
#include <libpeas/peas-extension-set.h>
#include <gtksourceview/gtksourcestyleschememanager.h>

#include "gedit-app.h"
#include "gedit-commands.h"
Expand Down Expand Up @@ -652,6 +653,8 @@ extension_removed (PeasExtensionSet *extensions,
static void
gedit_app_init (GeditApp *app)
{
GtkSourceStyleSchemeManager *manager;

app->priv = GEDIT_APP_GET_PRIVATE (app);

/* Load settings */
Expand All @@ -661,6 +664,15 @@ gedit_app_init (GeditApp *app)
/* initial lockdown state */
app->priv->lockdown = gedit_settings_get_lockdown (GEDIT_SETTINGS (app->priv->settings));

/*
* We use the default gtksourceview style scheme manager so that plugins
* can obtain it easily without a gedit specific api, but we need to
* add our search path at startup before the manager is actually used.
*/
manager = gtk_source_style_scheme_manager_get_default ();
gtk_source_style_scheme_manager_append_search_path (manager,
gedit_dirs_get_user_styles_dir ());

app->priv->extensions = peas_extension_set_new (PEAS_ENGINE (gedit_plugins_engine_get_default ()),
GEDIT_TYPE_APP_ACTIVATABLE,
"app", app,
Expand Down

0 comments on commit f5d46ef

Please sign in to comment.