Logo Search packages:      
Sourcecode: gretl version File versions  Download package

gtksourcelanguagesmanager.c

/*  gtksourcelanguagesmanager.c
 *
 *  Copyright (C) 2003 - Paolo Maggi <paolo.maggi@polito.it>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Library General Public License as published by
 *  the Free Software Foundation; either version 2 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 Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <string.h>

#include <libxml/xmlreader.h>

#include "gtksourcelanguagesmanager.h"

#include "gtksourcelanguage-private.h"
#include "gtksourceview-i18n.h"

#include "gtksourcelanguage.h"
#include "gtksourcetag.h"

#define DEFAULT_GCONF_BASE_DIR            "/apps/gtksourceview"

#define DEFAULT_LANGUAGE_DIR        DATADIR "/gtksourceview"
#define USER_LANGUAGE_DIR           "gtksourceview-1.0/language-specs"
#define USER_CONFIG_BASE_DIR  ".gnome2"

enum {
      PROP_0,
      PROP_LANG_SPECS_DIRS
};

struct _GtkSourceLanguagesManagerPrivate {

      GSList            *available_languages;

      GSList            *language_specs_directories;
};

static GObjectClass *parent_class = NULL;

static void  gtk_source_languages_manager_class_init        (GtkSourceLanguagesManagerClass *klass);
static void  gtk_source_languages_manager_instance_init     (GtkSourceLanguagesManager *lm);
static void  gtk_source_languages_manager_finalize          (GObject             *object);

static void  slist_deep_free                    (GSList              *list);
static GSList     *get_lang_files                     (GtkSourceLanguagesManager *lm);
static GSList     *build_file_listing                       (const gchar               *directory, 
                                                 GSList                    *filenames);

static void  gtk_source_languages_manager_set_property      (GObject             *object, 
                                                 guint                      prop_id,
                                                 const GValue              *value, 
                                                 GParamSpec          *pspec);
static void  gtk_source_languages_manager_get_property      (GObject             *object, 
                                                 guint                      prop_id,
                                                 GValue              *value, 
                                                 GParamSpec          *pspec);
static void  gtk_source_languages_manager_set_specs_dirs    (GtkSourceLanguagesManager *lm,
                                                 const GSList              *dirs);

GType
gtk_source_languages_manager_get_type (void)
{
      static GType languages_manager_type = 0;

      if (languages_manager_type == 0)
      {
                  static const GTypeInfo our_info =
                  {
                  sizeof (GtkSourceLanguagesManagerClass),
                  NULL,       /* base_init */
                  NULL,       /* base_finalize */
                  (GClassInitFunc) gtk_source_languages_manager_class_init,
                  NULL,           /* class_finalize */
                  NULL,           /* class_data */
                  sizeof (GtkSourceLanguagesManager),
                  0,              /* n_preallocs */
                  (GInstanceInitFunc) gtk_source_languages_manager_instance_init
                  };

                  languages_manager_type = g_type_register_static (G_TYPE_OBJECT,
                                              "GtkSourceLanguagesManager",
                                              &our_info,
                                              0);
      }

      return languages_manager_type;
}

static void
gtk_source_languages_manager_class_init (GtkSourceLanguagesManagerClass *klass)
{
      GObjectClass *object_class = G_OBJECT_CLASS (klass);

      parent_class            = g_type_class_peek_parent (klass);
      object_class->finalize  = gtk_source_languages_manager_finalize;

      object_class->set_property = gtk_source_languages_manager_set_property;
      object_class->get_property = gtk_source_languages_manager_get_property;
      
      g_object_class_install_property (object_class,
                               PROP_LANG_SPECS_DIRS,
                               g_param_spec_pointer ("lang_files_dirs",
                                                 _("Language specification directories"),
                                                 _("List of directories where the "
                                                 "language specification files (.lang) "
                                                 "are located"),
                                                 (G_PARAM_READWRITE | 
                                                  G_PARAM_CONSTRUCT_ONLY)));
}

static void
gtk_source_languages_manager_set_property (GObject    *object, 
                                 guint     prop_id,
                                 const GValue *value, 
                                 GParamSpec     *pspec)
{
      GtkSourceLanguagesManager *lm;

      g_return_if_fail (GTK_IS_SOURCE_LANGUAGES_MANAGER (object));

      lm = GTK_SOURCE_LANGUAGES_MANAGER (object);
    
      switch (prop_id) {      
          case PROP_LANG_SPECS_DIRS:
            gtk_source_languages_manager_set_specs_dirs (
                        lm, 
                        g_value_get_pointer (value));
            break;

          default:
            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
            break;
      }
}

static void
gtk_source_languages_manager_get_property (GObject    *object, 
                                 guint     prop_id,
                                 GValue   *value, 
                                 GParamSpec     *pspec)
{
      GtkSourceLanguagesManager *lm;

      g_return_if_fail (GTK_IS_SOURCE_LANGUAGES_MANAGER (object));

      lm = GTK_SOURCE_LANGUAGES_MANAGER (object);
    
      switch (prop_id) {      
          case PROP_LANG_SPECS_DIRS:
                g_value_set_pointer (value, lm->priv->language_specs_directories);
                break;
          default:
            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
            break;
      }
}

static void
gtk_source_languages_manager_instance_init (GtkSourceLanguagesManager *lm)
{
      lm->priv = g_new0 (GtkSourceLanguagesManagerPrivate, 1);    
}


GtkSourceLanguagesManager *
gtk_source_languages_manager_new (void)
{
      return GTK_SOURCE_LANGUAGES_MANAGER (
                              g_object_new (GTK_TYPE_SOURCE_LANGUAGES_MANAGER,
                                    NULL));
}

static void
gtk_source_languages_manager_finalize (GObject *object)
{
      GtkSourceLanguagesManager *lm;
       
      lm = GTK_SOURCE_LANGUAGES_MANAGER (object);
      
      if (lm->priv->available_languages != NULL)
      {
            GSList *list = lm->priv->available_languages;
            
            g_slist_foreach (list, (GFunc) g_object_unref, NULL);
            g_slist_free (list);
      }

      slist_deep_free (lm->priv->language_specs_directories);

      g_free (lm->priv);

      (* G_OBJECT_CLASS (parent_class)->finalize) (object);
}

static void 
gtk_source_languages_manager_set_specs_dirs (GtkSourceLanguagesManager  *lm,
                                   const GSList       *dirs)
{
      g_return_if_fail (GTK_IS_SOURCE_LANGUAGES_MANAGER (lm));
      g_return_if_fail (lm->priv->language_specs_directories == NULL);
                  
      if (dirs == NULL)
      {
            lm->priv->language_specs_directories =
                  g_slist_prepend (lm->priv->language_specs_directories,
                              g_strdup (DEFAULT_LANGUAGE_DIR));
            lm->priv->language_specs_directories = 
                  g_slist_prepend (lm->priv->language_specs_directories,
                              g_build_filename (g_get_home_dir(), 
                                    USER_CONFIG_BASE_DIR, USER_LANGUAGE_DIR, 
                                    NULL));

            return;
      }

      while (dirs != NULL)
      {
            lm->priv->language_specs_directories = 
                  g_slist_prepend (lm->priv->language_specs_directories,
                               g_strdup ((const gchar*)dirs->data));

            dirs = g_slist_next (dirs);
      }
}

const GSList *
gtk_source_languages_manager_get_lang_files_dirs (GtkSourceLanguagesManager *lm)
{
      g_return_val_if_fail (GTK_IS_SOURCE_LANGUAGES_MANAGER (lm), NULL);

      return lm->priv->language_specs_directories;
}

const GSList *
gtk_source_languages_manager_get_available_languages (GtkSourceLanguagesManager *lm)
{
      GSList *filenames;

      g_return_val_if_fail (GTK_IS_SOURCE_LANGUAGES_MANAGER (lm), NULL);

      if (lm->priv->available_languages != NULL)
      {
            return lm->priv->available_languages;
      }
      
      /* Build list of availables languages */
      filenames = get_lang_files (lm);
      
      while (filenames != NULL)
      {
            GtkSourceLanguage *lang;
            
            lang = _gtk_source_language_new_from_file ((const gchar*)filenames->data,
                                             lm);

            if (lang == NULL)
            {
                  g_warning ("Error reading language specification file '%s'", 
                           (const gchar*)filenames->data);
            }
            else
            {     
                  lm->priv->available_languages = 
                        g_slist_prepend (lm->priv->available_languages, lang);
            }

            filenames = g_slist_next (filenames);
      }

      slist_deep_free (filenames);

      /* TODO: remove duplicates - Paolo */

      return lm->priv->available_languages;
}

GtkSourceLanguage *
gtk_source_languages_manager_get_language_from_mime_type (GtkSourceLanguagesManager       *lm,
                                            const gchar                 *mime_type)
{
      const GSList *languages;
      g_return_val_if_fail (mime_type != NULL, NULL);

      languages = gtk_source_languages_manager_get_available_languages (lm);

      while (languages != NULL)
      {
            GSList *mime_types, *tmp;

            GtkSourceLanguage *lang = GTK_SOURCE_LANGUAGE (languages->data);
            
            tmp = mime_types = gtk_source_language_get_mime_types (lang);

            while (tmp != NULL)
            {
                  if (strcmp ((const gchar*)tmp->data, mime_type) == 0)
                  {           
                        break;
                  }

                  tmp = g_slist_next (tmp);
            }

            slist_deep_free (mime_types);
            if (tmp != NULL)
                  return lang;
            
            languages = g_slist_next (languages);
      }

      return NULL;
}

static GSList *
get_lang_files (GtkSourceLanguagesManager *lm)
{
      GSList *filenames = NULL;
      GSList *dirs;

      g_return_val_if_fail (lm->priv->language_specs_directories != NULL, NULL);

      dirs = lm->priv->language_specs_directories;

      while (dirs != NULL)
      {
            filenames = build_file_listing ((const gchar*)dirs->data,
                                    filenames);

            dirs = g_slist_next (dirs);
      }

      return filenames;
}

static GSList *
build_file_listing (const gchar *directory, GSList *filenames)
{
      GDir *dir;
      const gchar *file_name;
      
      dir = g_dir_open (directory, 0, NULL);
      
      if (dir == NULL)
            return filenames;

      file_name = g_dir_read_name (dir);
      
      while (file_name != NULL)
      {
            gchar *full_path = g_build_filename (directory, file_name, NULL);
            gchar *last_dot = strrchr (full_path, '.');
            
            if (!g_file_test (full_path, G_FILE_TEST_IS_DIR) && 
                last_dot && 
                (strcmp (last_dot + 1, "lang") == 0))
                  filenames = g_slist_prepend (filenames, full_path);
            else
                  g_free (full_path);

            file_name = g_dir_read_name (dir);
      }

      g_dir_close (dir);

      return filenames;
}

static void
slist_deep_free (GSList *list)
{
      g_slist_foreach (list, (GFunc) g_free, NULL);
      g_slist_free (list);
}


Generated by  Doxygen 1.6.0   Back to index