Blame gladeui/glade-named-icon-chooser-dialog.c

Packit 1e8aac
/*
Packit 1e8aac
 * glade-named-icon-chooser-widget.c - Named icon chooser widget
Packit 1e8aac
 *
Packit 1e8aac
 * Copyright (C) 2007 Vincent Geddes
Packit 1e8aac
 *
Packit 1e8aac
 * Author:  Vincent Geddes <vgeddes@gnome.org>
Packit 1e8aac
 *
Packit 1e8aac
 * This program is free software; you can redistribute it and/or modify
Packit 1e8aac
 * it under the terms of the GNU General Public License as published by
Packit 1e8aac
 * the Free Software Foundation; either version 2 of the License, or
Packit 1e8aac
 * (at your option) any later version.
Packit 1e8aac
 *
Packit 1e8aac
 * This program is distributed in the hope that it will be useful,
Packit 1e8aac
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 1e8aac
 * MERCHANNAMED_ICON_CHOOSERILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 1e8aac
 * GNU General Public License for more details.
Packit 1e8aac
 *
Packit 1e8aac
 * You should have received a copy of the GNU General Public License
Packit 1e8aac
 * along with this program; if not, write to the Free Software
Packit 1e8aac
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Packit 1e8aac
 */
Packit 1e8aac
Packit 1e8aac
#include <config.h>
Packit 1e8aac
Packit 1e8aac
#include "glade-private.h"
Packit 1e8aac
#include "glade-named-icon-chooser-dialog.h"
Packit 1e8aac
#include "icon-naming-spec.c"
Packit 1e8aac
Packit 1e8aac
#include <gtk/gtk.h>
Packit 1e8aac
#include <glib/gi18n-lib.h>
Packit 1e8aac
#include <string.h>
Packit 1e8aac
#include <errno.h>
Packit 1e8aac
Packit 1e8aac
Packit 1e8aac
#define DEFAULT_SETTING_LIST_STANDARD_ONLY   TRUE
Packit 1e8aac
Packit 1e8aac
enum
Packit 1e8aac
{
Packit 1e8aac
  CONTEXTS_ID_COLUMN,
Packit 1e8aac
  CONTEXTS_NAME_COLUMN,
Packit 1e8aac
  CONTEXTS_TITLE_COLUMN,
Packit 1e8aac
Packit 1e8aac
  CONTEXTS_N_COLUMS
Packit 1e8aac
};
Packit 1e8aac
Packit 1e8aac
enum
Packit 1e8aac
{
Packit 1e8aac
  ICONS_CONTEXT_COLUMN,
Packit 1e8aac
  ICONS_STANDARD_COLUMN,
Packit 1e8aac
  ICONS_NAME_COLUMN,
Packit 1e8aac
Packit 1e8aac
  ICONS_N_COLUMNS
Packit 1e8aac
};
Packit 1e8aac
Packit 1e8aac
enum
Packit 1e8aac
{
Packit 1e8aac
  GLADE_NAMED_ICON
Packit 1e8aac
};
Packit 1e8aac
Packit 1e8aac
enum
Packit 1e8aac
{
Packit 1e8aac
  ICON_ACTIVATED,
Packit 1e8aac
  SELECTION_CHANGED,
Packit 1e8aac
Packit 1e8aac
  LAST_SIGNAL
Packit 1e8aac
};
Packit 1e8aac
Packit 1e8aac
struct _GladeNamedIconChooserDialogPrivate
Packit 1e8aac
{
Packit 1e8aac
  GtkWidget *icons_view;
Packit 1e8aac
  GtkTreeModel *filter_model;   /* filtering model  */
Packit 1e8aac
  GtkListStore *icons_store;    /* data store       */
Packit 1e8aac
  GtkTreeSelection *selection;
Packit 1e8aac
Packit 1e8aac
  GtkWidget *contexts_view;
Packit 1e8aac
  GtkListStore *contexts_store;
Packit 1e8aac
Packit 1e8aac
  GtkWidget *entry;
Packit 1e8aac
  GtkEntryCompletion *entry_completion;
Packit 1e8aac
Packit 1e8aac
  GtkWidget *button;            /* list-standard-only checkbutton */
Packit 1e8aac
Packit 1e8aac
  gint context_id;              /* current icon name context for icon filtering */
Packit 1e8aac
Packit 1e8aac
  gchar *pending_select_name;   /* an icon name for a pending treeview selection.
Packit 1e8aac
                                 * can only select name after model is loaded
Packit 1e8aac
                                 * and the widget is mapped */
Packit 1e8aac
Packit 1e8aac
  GtkIconTheme *icon_theme;     /* the current icon theme */
Packit 1e8aac
  guint load_id;                /* id of the idle function for loading data into model */
Packit 1e8aac
Packit 1e8aac
  gboolean settings_list_standard;      /* whether to list standard icon names only */
Packit 1e8aac
Packit 1e8aac
  GtkWidget *last_focus_widget;
Packit 1e8aac
Packit 1e8aac
  gboolean icons_loaded;        /* whether the icons have been loaded into the model */
Packit 1e8aac
};
Packit 1e8aac
Packit 1e8aac
static GHashTable *standard_icon_quarks = NULL;
Packit 1e8aac
Packit 1e8aac
static guint dialog_signals[LAST_SIGNAL] = { 0, };
Packit 1e8aac
Packit 1e8aac
gchar *
Packit 1e8aac
glade_named_icon_chooser_dialog_get_icon_name (GladeNamedIconChooserDialog *dialog);
Packit 1e8aac
Packit 1e8aac
void
Packit 1e8aac
glade_named_icon_chooser_dialog_set_icon_name (GladeNamedIconChooserDialog *dialog,
Packit 1e8aac
                                               const gchar                 *icon_name);
Packit 1e8aac
Packit 1e8aac
gboolean
Packit 1e8aac
glade_named_icon_chooser_dialog_set_context (GladeNamedIconChooserDialog *dialog,
Packit 1e8aac
                                             const gchar                 *context);
Packit 1e8aac
Packit 1e8aac
gchar *
Packit 1e8aac
glade_named_icon_chooser_dialog_get_context (GladeNamedIconChooserDialog *dialog);
Packit 1e8aac
Packit 1e8aac
static gboolean should_respond (GladeNamedIconChooserDialog *dialog);
Packit 1e8aac
Packit 1e8aac
static void filter_icons_model (GladeNamedIconChooserDialog *dialog);
Packit 1e8aac
Packit 1e8aac
static gboolean scan_for_name_func (GtkTreeModel *model,
Packit 1e8aac
                                    GtkTreePath  *path,
Packit 1e8aac
                                    GtkTreeIter  *iter,
Packit 1e8aac
                                    gpointer      data);
Packit 1e8aac
Packit 1e8aac
static gboolean scan_for_context_func (GtkTreeModel *model,
Packit 1e8aac
                                       GtkTreePath  *path,
Packit 1e8aac
                                       GtkTreeIter  *iter,
Packit 1e8aac
                                       gpointer      data);
Packit 1e8aac
Packit 1e8aac
static void settings_load (GladeNamedIconChooserDialog *dialog);
Packit 1e8aac
Packit 1e8aac
static void settings_save (GladeNamedIconChooserDialog *dialog);
Packit 1e8aac
Packit 1e8aac
Packit 1e8aac
G_DEFINE_TYPE_WITH_PRIVATE (GladeNamedIconChooserDialog,
Packit 1e8aac
                            glade_named_icon_chooser_dialog,
Packit 1e8aac
                            GTK_TYPE_DIALOG);
Packit 1e8aac
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
entry_set_name (GladeNamedIconChooserDialog *dialog, const gchar *name)
Packit 1e8aac
{
Packit 1e8aac
  /* Must disable completion before setting text, in order to avoid
Packit 1e8aac
   * spurious warnings (possible GTK+ bug).
Packit 1e8aac
   */
Packit 1e8aac
  gtk_entry_set_completion (GTK_ENTRY (dialog->priv->entry), NULL);
Packit 1e8aac
Packit 1e8aac
  gtk_entry_set_text (GTK_ENTRY (dialog->priv->entry), name);
Packit 1e8aac
Packit 1e8aac
  gtk_entry_set_completion (GTK_ENTRY (dialog->priv->entry),
Packit 1e8aac
                            dialog->priv->entry_completion);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static GtkIconTheme *
Packit 1e8aac
get_icon_theme_for_widget (GtkWidget *widget)
Packit 1e8aac
{
Packit 1e8aac
  if (gtk_widget_has_screen (widget))
Packit 1e8aac
    return gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
Packit 1e8aac
Packit 1e8aac
  return gtk_icon_theme_get_default ();
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
/* validates name according to the icon naming spec (en_US.US_ASCII [a-z1-9_-.])  */
Packit 1e8aac
static gboolean
Packit 1e8aac
is_well_formed (const gchar * name)
Packit 1e8aac
{
Packit 1e8aac
  gchar *c = (gchar *) name;
Packit 1e8aac
  for (; *c; c++)
Packit 1e8aac
    {
Packit 1e8aac
      if (g_ascii_isalnum (*c))
Packit 1e8aac
        {
Packit 1e8aac
          if (g_ascii_isalpha (*c) && !g_ascii_islower (*c))
Packit 1e8aac
            return FALSE;
Packit 1e8aac
        }
Packit 1e8aac
      else if (*c != '_' && *c != '-' && *c != '.')
Packit 1e8aac
        {
Packit 1e8aac
          return FALSE;
Packit 1e8aac
        }
Packit 1e8aac
    }
Packit 1e8aac
  return TRUE;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
check_entry_text (GladeNamedIconChooserDialog *dialog,
Packit 1e8aac
                  gchar                      **name_ret,
Packit 1e8aac
                  gboolean                    *is_wellformed_ret,
Packit 1e8aac
                  gboolean                    *is_empty_ret)
Packit 1e8aac
{
Packit 1e8aac
  if (strlen (gtk_entry_get_text (GTK_ENTRY (dialog->priv->entry))) == 0)
Packit 1e8aac
    {
Packit 1e8aac
      *name_ret = NULL;
Packit 1e8aac
      *is_wellformed_ret = TRUE;
Packit 1e8aac
      *is_empty_ret = TRUE;
Packit 1e8aac
Packit 1e8aac
      return;
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  *is_empty_ret = FALSE;
Packit 1e8aac
Packit 1e8aac
  *is_wellformed_ret =
Packit 1e8aac
      is_well_formed (gtk_entry_get_text (GTK_ENTRY (dialog->priv->entry)));
Packit 1e8aac
Packit 1e8aac
  if (*is_wellformed_ret)
Packit 1e8aac
    *name_ret = g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->priv->entry)));
Packit 1e8aac
  else
Packit 1e8aac
    *name_ret = NULL;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
changed_text_handler (GtkEditable                 *editable,
Packit 1e8aac
                      GladeNamedIconChooserDialog *dialog)
Packit 1e8aac
{
Packit 1e8aac
  g_signal_emit_by_name (dialog, "selection-changed", NULL);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
/* ensure that only valid text can be inserted into entry */
Packit 1e8aac
static void
Packit 1e8aac
insert_text_handler (GtkEditable                 *editable,
Packit 1e8aac
                     const gchar                 *text,
Packit 1e8aac
                     gint                         length,
Packit 1e8aac
                     gint                        *position,
Packit 1e8aac
                     GladeNamedIconChooserDialog *dialog)
Packit 1e8aac
{
Packit 1e8aac
  if (is_well_formed (text))
Packit 1e8aac
    {
Packit 1e8aac
Packit 1e8aac
      g_signal_handlers_block_by_func (editable, (gpointer) insert_text_handler,
Packit 1e8aac
                                       dialog);
Packit 1e8aac
Packit 1e8aac
      gtk_editable_insert_text (editable, text, length, position);
Packit 1e8aac
Packit 1e8aac
      g_signal_handlers_unblock_by_func (editable,
Packit 1e8aac
                                         (gpointer) insert_text_handler,
Packit 1e8aac
                                         dialog);
Packit 1e8aac
Packit 1e8aac
    }
Packit 1e8aac
  else
Packit 1e8aac
    {
Packit 1e8aac
      gdk_display_beep (gtk_widget_get_display (GTK_WIDGET (dialog)));
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  g_signal_stop_emission_by_name (editable, "insert-text");
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
typedef struct
Packit 1e8aac
{
Packit 1e8aac
  gchar *name;                  /* the name of the icon or context */
Packit 1e8aac
Packit 1e8aac
  guint found:1;                /* whether an item matching `name' was found */
Packit 1e8aac
  guint do_select:1;            /* select the matched row */
Packit 1e8aac
  guint do_cursor:1;            /* put cursor at the matched row */
Packit 1e8aac
  guint do_activate:1;          /* activate the matched row */
Packit 1e8aac
Packit 1e8aac
  GladeNamedIconChooserDialog *dialog;
Packit 1e8aac
} ForEachFuncData;
Packit 1e8aac
Packit 1e8aac
void
Packit 1e8aac
glade_named_icon_chooser_dialog_set_icon_name (GladeNamedIconChooserDialog *dialog, 
Packit 1e8aac
                                               const gchar                 *name)
Packit 1e8aac
{
Packit 1e8aac
  ForEachFuncData *data;
Packit 1e8aac
  gboolean located_in_theme;
Packit 1e8aac
Packit 1e8aac
  g_return_if_fail (GLADE_IS_NAMED_ICON_CHOOSER_DIALOG (dialog));
Packit 1e8aac
  g_return_if_fail (gtk_widget_has_screen (GTK_WIDGET (dialog)));
Packit 1e8aac
Packit 1e8aac
  if (name == NULL)
Packit 1e8aac
    {
Packit 1e8aac
      gtk_tree_selection_unselect_all (dialog->priv->selection);
Packit 1e8aac
      entry_set_name (dialog, "");
Packit 1e8aac
      return;
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  located_in_theme =
Packit 1e8aac
      gtk_icon_theme_has_icon (get_icon_theme_for_widget (GTK_WIDGET (dialog)),
Packit 1e8aac
                               name);
Packit 1e8aac
Packit 1e8aac
  if (located_in_theme)
Packit 1e8aac
    {
Packit 1e8aac
Packit 1e8aac
      if (dialog->priv->icons_loaded && dialog->priv->filter_model)
Packit 1e8aac
        {
Packit 1e8aac
Packit 1e8aac
          data = g_slice_new0 (ForEachFuncData);
Packit 1e8aac
          data->name = g_strdup (name);
Packit 1e8aac
          data->found = FALSE;
Packit 1e8aac
          data->do_activate = FALSE;
Packit 1e8aac
          data->do_select = TRUE;
Packit 1e8aac
          data->do_cursor = TRUE;
Packit 1e8aac
          data->dialog = dialog;
Packit 1e8aac
Packit 1e8aac
          gtk_tree_model_foreach (dialog->priv->filter_model,
Packit 1e8aac
                                  scan_for_name_func, data);
Packit 1e8aac
Packit 1e8aac
          g_free (data->name);
Packit 1e8aac
          g_slice_free (ForEachFuncData, data);
Packit 1e8aac
Packit 1e8aac
        }
Packit 1e8aac
      else
Packit 1e8aac
        {
Packit 1e8aac
          dialog->priv->pending_select_name = g_strdup (name);
Packit 1e8aac
        }
Packit 1e8aac
Packit 1e8aac
      /* selecting a treeview row will set the entry text,
Packit 1e8aac
       * but we must have this here in case the row has been filtered out
Packit 1e8aac
       */
Packit 1e8aac
      entry_set_name (dialog, name);
Packit 1e8aac
Packit 1e8aac
    }
Packit 1e8aac
  else if (is_well_formed (name))
Packit 1e8aac
    {
Packit 1e8aac
Packit 1e8aac
      gtk_tree_selection_unselect_all (dialog->priv->selection);
Packit 1e8aac
Packit 1e8aac
      entry_set_name (dialog, name);
Packit 1e8aac
    }
Packit 1e8aac
  else
Packit 1e8aac
    {
Packit 1e8aac
      g_warning ("invalid icon name: '%s' is not well formed", name);
Packit 1e8aac
    }
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
gboolean
Packit 1e8aac
glade_named_icon_chooser_dialog_set_context (GladeNamedIconChooserDialog *dialog,
Packit 1e8aac
                                             const gchar                 *name)
Packit 1e8aac
{
Packit 1e8aac
  ForEachFuncData *data;
Packit 1e8aac
Packit 1e8aac
  g_return_val_if_fail (GLADE_IS_NAMED_ICON_CHOOSER_DIALOG (dialog), FALSE);
Packit 1e8aac
Packit 1e8aac
  data = g_slice_new0 (ForEachFuncData);
Packit 1e8aac
Packit 1e8aac
  if (name)
Packit 1e8aac
    data->name = g_strdup (name);
Packit 1e8aac
  else
Packit 1e8aac
    data->name = g_strdup ("All Contexts");
Packit 1e8aac
Packit 1e8aac
  data->found = FALSE;
Packit 1e8aac
  data->do_select = TRUE;
Packit 1e8aac
  data->do_activate = FALSE;
Packit 1e8aac
  data->do_cursor = FALSE;
Packit 1e8aac
  data->dialog = dialog;
Packit 1e8aac
Packit 1e8aac
  gtk_tree_model_foreach (GTK_TREE_MODEL (dialog->priv->contexts_store),
Packit 1e8aac
                          (GtkTreeModelForeachFunc) scan_for_context_func,
Packit 1e8aac
                          data);
Packit 1e8aac
Packit 1e8aac
  g_free (data->name);
Packit 1e8aac
  g_slice_free (ForEachFuncData, data);
Packit 1e8aac
Packit 1e8aac
  return TRUE;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
gchar *
Packit 1e8aac
glade_named_icon_chooser_dialog_get_context (GladeNamedIconChooserDialog *dialog)
Packit 1e8aac
{
Packit 1e8aac
  GtkTreeSelection *sel;
Packit 1e8aac
  GtkTreeIter iter;
Packit 1e8aac
  gchar *context_name;
Packit 1e8aac
Packit 1e8aac
  g_return_val_if_fail (GLADE_IS_NAMED_ICON_CHOOSER_DIALOG (dialog), NULL);
Packit 1e8aac
Packit 1e8aac
  sel =
Packit 1e8aac
      gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->priv->contexts_view));
Packit 1e8aac
Packit 1e8aac
  if (gtk_tree_selection_get_selected (sel, NULL, &iter))
Packit 1e8aac
    {
Packit 1e8aac
Packit 1e8aac
      gtk_tree_model_get (GTK_TREE_MODEL (dialog->priv->contexts_store), &iter,
Packit 1e8aac
                          CONTEXTS_NAME_COLUMN, &context_name, -1);
Packit 1e8aac
Packit 1e8aac
      /* if context_name is NULL, then it is the 'all categories' special context */
Packit 1e8aac
      return context_name;
Packit 1e8aac
Packit 1e8aac
    }
Packit 1e8aac
  else
Packit 1e8aac
    {
Packit 1e8aac
      return NULL;
Packit 1e8aac
    }
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static gchar *
Packit 1e8aac
get_icon_name_from_selection (GladeNamedIconChooserDialog *dialog)
Packit 1e8aac
{
Packit 1e8aac
  GtkTreeIter iter;
Packit 1e8aac
  GtkTreeModel *model;
Packit 1e8aac
  gchar *name;
Packit 1e8aac
Packit 1e8aac
  if (!gtk_tree_selection_get_selected (dialog->priv->selection, &model, &iter))
Packit 1e8aac
    return NULL;
Packit 1e8aac
Packit 1e8aac
  gtk_tree_model_get (model, &iter, ICONS_NAME_COLUMN, &name, -1);
Packit 1e8aac
Packit 1e8aac
  return name;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
gchar *
Packit 1e8aac
glade_named_icon_chooser_dialog_get_icon_name (GladeNamedIconChooserDialog *dialog)
Packit 1e8aac
{
Packit 1e8aac
  GtkWidget *current_focus;
Packit 1e8aac
  gchar *name;
Packit 1e8aac
Packit 1e8aac
  g_return_val_if_fail (GLADE_IS_NAMED_ICON_CHOOSER_DIALOG (dialog), NULL);
Packit 1e8aac
Packit 1e8aac
  current_focus = gtk_window_get_focus (GTK_WINDOW (dialog));
Packit 1e8aac
Packit 1e8aac
  if (current_focus == dialog->priv->icons_view)
Packit 1e8aac
    {
Packit 1e8aac
Packit 1e8aac
    view:
Packit 1e8aac
      name = get_icon_name_from_selection (dialog);
Packit 1e8aac
Packit 1e8aac
      if (name == NULL)
Packit 1e8aac
        goto entry;
Packit 1e8aac
Packit 1e8aac
    }
Packit 1e8aac
  else if (current_focus == dialog->priv->entry)
Packit 1e8aac
    {
Packit 1e8aac
      gboolean is_wellformed, is_empty;
Packit 1e8aac
    entry:
Packit 1e8aac
      check_entry_text (dialog, &name, &is_wellformed, &is_empty);
Packit 1e8aac
Packit 1e8aac
      if (!is_wellformed || is_empty)
Packit 1e8aac
        return NULL;
Packit 1e8aac
Packit 1e8aac
    }
Packit 1e8aac
  else if (dialog->priv->last_focus_widget == dialog->priv->icons_view)
Packit 1e8aac
    {
Packit 1e8aac
      goto view;
Packit 1e8aac
    }
Packit 1e8aac
  else if (dialog->priv->last_focus_widget == dialog->priv->entry)
Packit 1e8aac
    {
Packit 1e8aac
      goto entry;
Packit 1e8aac
    }
Packit 1e8aac
  else
Packit 1e8aac
    {
Packit 1e8aac
      goto view;
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  return name;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
set_busy_cursor (GladeNamedIconChooserDialog *dialog, gboolean busy)
Packit 1e8aac
{
Packit 1e8aac
  GdkDisplay *display;
Packit 1e8aac
  GdkCursor *cursor;
Packit 1e8aac
Packit 1e8aac
  if (!gtk_widget_get_realized (GTK_WIDGET (dialog)))
Packit 1e8aac
    return;
Packit 1e8aac
Packit 1e8aac
  display = gtk_widget_get_display (GTK_WIDGET (dialog));
Packit 1e8aac
Packit 1e8aac
  if (busy)
Packit 1e8aac
    cursor = gdk_cursor_new_for_display (display, GDK_WATCH);
Packit 1e8aac
  else
Packit 1e8aac
    cursor = NULL;
Packit 1e8aac
Packit 1e8aac
  gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (dialog)), cursor);
Packit 1e8aac
  gdk_display_flush (display);
Packit 1e8aac
Packit 1e8aac
  if (cursor)
Packit 1e8aac
    g_object_unref (cursor);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static GtkListStore *
Packit 1e8aac
populate_icon_contexts_model (void)
Packit 1e8aac
{
Packit 1e8aac
  GtkListStore *store;
Packit 1e8aac
  GtkTreeIter iter;
Packit 1e8aac
  guint i;
Packit 1e8aac
Packit 1e8aac
  store = gtk_list_store_new (CONTEXTS_N_COLUMS,
Packit 1e8aac
                              G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING);
Packit 1e8aac
Packit 1e8aac
Packit 1e8aac
  gtk_list_store_append (store, &iter);
Packit 1e8aac
  gtk_list_store_set (store, &iter,
Packit 1e8aac
                      CONTEXTS_ID_COLUMN, -1,
Packit 1e8aac
                      CONTEXTS_NAME_COLUMN, "All Contexts",
Packit 1e8aac
                      CONTEXTS_TITLE_COLUMN, _("All Contexts"), -1);
Packit 1e8aac
Packit 1e8aac
  gtk_list_store_append (store, &iter);
Packit 1e8aac
  gtk_list_store_set (store, &iter,
Packit 1e8aac
                      CONTEXTS_ID_COLUMN, -1,
Packit 1e8aac
                      CONTEXTS_NAME_COLUMN, NULL,
Packit 1e8aac
                      CONTEXTS_TITLE_COLUMN, NULL, -1);
Packit 1e8aac
Packit 1e8aac
  for (i = 0; i < G_N_ELEMENTS (standard_contexts); i++)
Packit 1e8aac
    {
Packit 1e8aac
Packit 1e8aac
      gtk_list_store_append (store, &iter);
Packit 1e8aac
      gtk_list_store_set (store, &iter,
Packit 1e8aac
                          CONTEXTS_ID_COLUMN, i,
Packit 1e8aac
                          CONTEXTS_NAME_COLUMN, standard_contexts[i].name,
Packit 1e8aac
                          CONTEXTS_TITLE_COLUMN, _(standard_contexts[i].title),
Packit 1e8aac
                          -1);
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  return store;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
icons_row_activated_cb (GtkTreeView                 *view,
Packit 1e8aac
                        GtkTreePath                 *path,
Packit 1e8aac
                        GtkTreeViewColumn           *column,
Packit 1e8aac
                        GladeNamedIconChooserDialog *dialog)
Packit 1e8aac
{
Packit 1e8aac
  g_signal_emit_by_name (dialog, "icon-activated", NULL);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
icons_selection_changed_cb (GtkTreeSelection * selection,
Packit 1e8aac
                            GladeNamedIconChooserDialog * dialog)
Packit 1e8aac
{
Packit 1e8aac
  GtkTreeModel *model;
Packit 1e8aac
  GtkTreeIter iter;
Packit 1e8aac
  gchar *name;
Packit 1e8aac
Packit 1e8aac
  if (gtk_tree_selection_get_selected (selection, &model, &iter))
Packit 1e8aac
    {
Packit 1e8aac
      gtk_tree_model_get (model, &iter, ICONS_NAME_COLUMN, &name, -1);
Packit 1e8aac
      if (name)
Packit 1e8aac
        entry_set_name (dialog, name);
Packit 1e8aac
Packit 1e8aac
      g_free (name);
Packit 1e8aac
    }
Packit 1e8aac
  else
Packit 1e8aac
    {
Packit 1e8aac
      /* entry_set_name (dialog, ""); */
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  /* we emit "selection-changed" for chooser in insert_text_handler()
Packit 1e8aac
   * to avoid emitting the signal twice */
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
contexts_row_activated_cb (GtkTreeView                 *view,
Packit 1e8aac
                           GtkTreePath                 *cpath,
Packit 1e8aac
                           GtkTreeViewColumn           *column,
Packit 1e8aac
                           GladeNamedIconChooserDialog *dialog)
Packit 1e8aac
{
Packit 1e8aac
  GtkTreeIter iter;
Packit 1e8aac
  GtkTreePath *path;
Packit 1e8aac
Packit 1e8aac
  if (gtk_tree_model_get_iter_first (dialog->priv->filter_model, &iter))
Packit 1e8aac
    {
Packit 1e8aac
Packit 1e8aac
      gtk_tree_selection_select_iter (dialog->priv->selection, &iter);
Packit 1e8aac
Packit 1e8aac
      path = gtk_tree_model_get_path (dialog->priv->filter_model, &iter);
Packit 1e8aac
Packit 1e8aac
      gtk_tree_selection_select_path (dialog->priv->selection, path);
Packit 1e8aac
Packit 1e8aac
      gtk_tree_view_scroll_to_point (GTK_TREE_VIEW (dialog->priv->icons_view),
Packit 1e8aac
                                     -1, 0);
Packit 1e8aac
Packit 1e8aac
      gtk_tree_path_free (path);
Packit 1e8aac
Packit 1e8aac
    }
Packit 1e8aac
  gtk_widget_grab_focus (dialog->priv->icons_view);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
contexts_selection_changed_cb (GtkTreeSelection            *selection,
Packit 1e8aac
                               GladeNamedIconChooserDialog *dialog)
Packit 1e8aac
{
Packit 1e8aac
  GtkTreeIter iter;
Packit 1e8aac
  GtkTreeModel *model;
Packit 1e8aac
  gboolean retval;
Packit 1e8aac
  gint context_id;
Packit 1e8aac
Packit 1e8aac
  retval = gtk_tree_selection_get_selected (selection, &model, &iter);
Packit 1e8aac
Packit 1e8aac
  if (retval)
Packit 1e8aac
    {
Packit 1e8aac
Packit 1e8aac
      gtk_tree_model_get (model, &iter, CONTEXTS_ID_COLUMN, &context_id, -1);
Packit 1e8aac
Packit 1e8aac
      dialog->priv->context_id = context_id;
Packit 1e8aac
Packit 1e8aac
      if (!dialog->priv->filter_model)
Packit 1e8aac
        return;
Packit 1e8aac
Packit 1e8aac
      filter_icons_model (dialog);
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  entry_set_name (dialog, "");
Packit 1e8aac
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static gboolean
Packit 1e8aac
row_separator_func (GtkTreeModel *model, GtkTreeIter *iter, gpointer unused)
Packit 1e8aac
{
Packit 1e8aac
  gboolean retval;
Packit 1e8aac
  gchar *name, *title;
Packit 1e8aac
Packit 1e8aac
  gtk_tree_model_get (model, iter,
Packit 1e8aac
                      CONTEXTS_NAME_COLUMN, &name,
Packit 1e8aac
                      CONTEXTS_TITLE_COLUMN, &title, -1);
Packit 1e8aac
Packit 1e8aac
  retval = !name && !title;
Packit 1e8aac
Packit 1e8aac
  g_free (name);
Packit 1e8aac
  g_free (title);
Packit 1e8aac
Packit 1e8aac
  return retval;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static GtkWidget *
Packit 1e8aac
create_contexts_view (GladeNamedIconChooserDialog *dialog)
Packit 1e8aac
{
Packit 1e8aac
  GtkTreeView *view;
Packit 1e8aac
  GtkTreeViewColumn *column;
Packit 1e8aac
  GtkTreePath *path;
Packit 1e8aac
Packit 1e8aac
  dialog->priv->contexts_store = populate_icon_contexts_model ();
Packit 1e8aac
Packit 1e8aac
  view =
Packit 1e8aac
      GTK_TREE_VIEW (gtk_tree_view_new_with_model
Packit 1e8aac
                     (GTK_TREE_MODEL (dialog->priv->contexts_store)));
Packit 1e8aac
Packit 1e8aac
  column = gtk_tree_view_column_new_with_attributes (NULL,
Packit 1e8aac
                                                     gtk_cell_renderer_text_new
Packit 1e8aac
                                                     (), "text",
Packit 1e8aac
                                                     CONTEXTS_TITLE_COLUMN,
Packit 1e8aac
                                                     NULL);
Packit 1e8aac
Packit 1e8aac
  gtk_tree_view_append_column (view, column);
Packit 1e8aac
  gtk_tree_view_set_headers_visible (view, FALSE);
Packit 1e8aac
Packit 1e8aac
  gtk_tree_view_set_row_separator_func (view,
Packit 1e8aac
                                        (GtkTreeViewRowSeparatorFunc)
Packit 1e8aac
                                        row_separator_func, NULL, NULL);
Packit 1e8aac
Packit 1e8aac
  gtk_tree_selection_set_mode (gtk_tree_view_get_selection (view),
Packit 1e8aac
                               GTK_SELECTION_BROWSE);
Packit 1e8aac
Packit 1e8aac
  path = gtk_tree_path_new_from_indices (0, -1);
Packit 1e8aac
  gtk_tree_selection_select_path (gtk_tree_view_get_selection (view), path);
Packit 1e8aac
  gtk_tree_path_free (path);
Packit 1e8aac
Packit 1e8aac
  g_signal_connect (view, "row-activated",
Packit 1e8aac
                    G_CALLBACK (contexts_row_activated_cb), dialog);
Packit 1e8aac
Packit 1e8aac
  g_signal_connect (gtk_tree_view_get_selection (view), "changed",
Packit 1e8aac
                    G_CALLBACK (contexts_selection_changed_cb), dialog);
Packit 1e8aac
Packit 1e8aac
  gtk_widget_show (GTK_WIDGET (view));
Packit 1e8aac
Packit 1e8aac
  return GTK_WIDGET (view);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
/* filters the icons model based on the current state */
Packit 1e8aac
static void
Packit 1e8aac
filter_icons_model (GladeNamedIconChooserDialog *dialog)
Packit 1e8aac
{
Packit 1e8aac
Packit 1e8aac
  set_busy_cursor (dialog, TRUE);
Packit 1e8aac
Packit 1e8aac
  g_object_ref (dialog->priv->filter_model);
Packit 1e8aac
  gtk_tree_view_set_model (GTK_TREE_VIEW (dialog->priv->icons_view), NULL);
Packit 1e8aac
  gtk_entry_completion_set_model (dialog->priv->entry_completion, NULL);
Packit 1e8aac
Packit 1e8aac
  gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER
Packit 1e8aac
                                  (dialog->priv->filter_model));
Packit 1e8aac
Packit 1e8aac
  gtk_tree_view_set_model (GTK_TREE_VIEW (dialog->priv->icons_view),
Packit 1e8aac
                           dialog->priv->filter_model);
Packit 1e8aac
  gtk_entry_completion_set_model (dialog->priv->entry_completion,
Packit 1e8aac
                                  GTK_TREE_MODEL (dialog->priv->icons_store));
Packit 1e8aac
  gtk_entry_completion_set_text_column (dialog->priv->entry_completion,
Packit 1e8aac
                                        ICONS_NAME_COLUMN);
Packit 1e8aac
  g_object_unref (dialog->priv->filter_model);
Packit 1e8aac
Packit 1e8aac
  set_busy_cursor (dialog, FALSE);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static gboolean
Packit 1e8aac
filter_visible_func (GtkTreeModel                *model,
Packit 1e8aac
                     GtkTreeIter                 *iter,
Packit 1e8aac
                     GladeNamedIconChooserDialog *dialog)
Packit 1e8aac
{
Packit 1e8aac
  gboolean standard;
Packit 1e8aac
  gint context_id;
Packit 1e8aac
Packit 1e8aac
  gtk_tree_model_get (model, iter,
Packit 1e8aac
                      ICONS_CONTEXT_COLUMN, &context_id,
Packit 1e8aac
                      ICONS_STANDARD_COLUMN, &standard, -1);
Packit 1e8aac
Packit 1e8aac
  if (dialog->priv->context_id == -1)
Packit 1e8aac
    return (dialog->priv->settings_list_standard) ? TRUE && standard : TRUE;
Packit 1e8aac
Packit 1e8aac
  if (context_id == dialog->priv->context_id)
Packit 1e8aac
    return (dialog->priv->settings_list_standard) ? TRUE && standard : TRUE;
Packit 1e8aac
  else
Packit 1e8aac
    return FALSE;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
Packit 1e8aac
static gboolean
Packit 1e8aac
search_equal_func (GtkTreeModel                *model,
Packit 1e8aac
                   gint                         column,
Packit 1e8aac
                   const gchar                 *key,
Packit 1e8aac
                   GtkTreeIter                 *iter,
Packit 1e8aac
                   GladeNamedIconChooserDialog *dialog)
Packit 1e8aac
{
Packit 1e8aac
  gchar *name;
Packit 1e8aac
  gboolean retval;
Packit 1e8aac
Packit 1e8aac
  gtk_tree_model_get (model, iter, ICONS_NAME_COLUMN, &name, -1);
Packit 1e8aac
Packit 1e8aac
  retval = !g_str_has_prefix (name, key);
Packit 1e8aac
Packit 1e8aac
  g_free (name);
Packit 1e8aac
Packit 1e8aac
  return retval;
Packit 1e8aac
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static gboolean
Packit 1e8aac
scan_for_context_func (GtkTreeModel *model,
Packit 1e8aac
                       GtkTreePath  *path,
Packit 1e8aac
                       GtkTreeIter  *iter,
Packit 1e8aac
                       gpointer      user_data)
Packit 1e8aac
{
Packit 1e8aac
  ForEachFuncData *data = (ForEachFuncData *) user_data;
Packit 1e8aac
  GtkTreeSelection *selection =
Packit 1e8aac
      gtk_tree_view_get_selection (GTK_TREE_VIEW
Packit 1e8aac
                                   (data->dialog->priv->contexts_view));
Packit 1e8aac
  gchar *name = NULL;
Packit 1e8aac
Packit 1e8aac
  gtk_tree_model_get (model, iter, CONTEXTS_NAME_COLUMN, &name, -1);
Packit 1e8aac
  if (!name)
Packit 1e8aac
    return FALSE;
Packit 1e8aac
Packit 1e8aac
  if (strcmp (name, data->name) == 0)
Packit 1e8aac
    {
Packit 1e8aac
Packit 1e8aac
      data->found = TRUE;
Packit 1e8aac
Packit 1e8aac
      if (data->do_activate)
Packit 1e8aac
        gtk_tree_view_row_activated (GTK_TREE_VIEW
Packit 1e8aac
                                     (data->dialog->priv->contexts_view), path,
Packit 1e8aac
                                     gtk_tree_view_get_column (GTK_TREE_VIEW
Packit 1e8aac
                                                               (data->dialog->
Packit 1e8aac
                                                                priv->
Packit 1e8aac
                                                                contexts_view),
Packit 1e8aac
                                                               0));
Packit 1e8aac
Packit 1e8aac
      if (data->do_select)
Packit 1e8aac
        gtk_tree_selection_select_path (selection, path);
Packit 1e8aac
      else
Packit 1e8aac
        gtk_tree_selection_unselect_path (selection, path);
Packit 1e8aac
Packit 1e8aac
      if (data->do_cursor)
Packit 1e8aac
        gtk_tree_view_set_cursor (GTK_TREE_VIEW
Packit 1e8aac
                                  (data->dialog->priv->contexts_view), path,
Packit 1e8aac
                                  NULL, FALSE);
Packit 1e8aac
Packit 1e8aac
      g_free (name);
Packit 1e8aac
Packit 1e8aac
      return TRUE;
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  g_free (name);
Packit 1e8aac
Packit 1e8aac
  return FALSE;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
gboolean
Packit 1e8aac
scan_for_name_func (GtkTreeModel *model,
Packit 1e8aac
                    GtkTreePath  *path,
Packit 1e8aac
                    GtkTreeIter  *iter,
Packit 1e8aac
                    gpointer      user_data)
Packit 1e8aac
{
Packit 1e8aac
  ForEachFuncData *data = (ForEachFuncData *) user_data;
Packit 1e8aac
  gchar *name = NULL;
Packit 1e8aac
Packit 1e8aac
  gtk_tree_model_get (model, iter, ICONS_NAME_COLUMN, &name, -1);
Packit 1e8aac
  if (!name)
Packit 1e8aac
    return FALSE;
Packit 1e8aac
Packit 1e8aac
  if (strcmp (name, data->name) == 0)
Packit 1e8aac
    {
Packit 1e8aac
Packit 1e8aac
      data->found = TRUE;
Packit 1e8aac
Packit 1e8aac
      if (data->do_activate)
Packit 1e8aac
        gtk_tree_view_row_activated (GTK_TREE_VIEW
Packit 1e8aac
                                     (data->dialog->priv->icons_view), path,
Packit 1e8aac
                                     gtk_tree_view_get_column (GTK_TREE_VIEW
Packit 1e8aac
                                                               (data->dialog->
Packit 1e8aac
                                                                priv->
Packit 1e8aac
                                                                icons_view),
Packit 1e8aac
                                                               0));
Packit 1e8aac
Packit 1e8aac
      if (data->do_select)
Packit 1e8aac
        gtk_tree_selection_select_path (data->dialog->priv->selection, path);
Packit 1e8aac
      else
Packit 1e8aac
        gtk_tree_selection_unselect_path (data->dialog->priv->selection, path);
Packit 1e8aac
Packit 1e8aac
      if (data->do_cursor)
Packit 1e8aac
        gtk_tree_view_set_cursor (GTK_TREE_VIEW
Packit 1e8aac
                                  (data->dialog->priv->icons_view), path, NULL,
Packit 1e8aac
                                  FALSE);
Packit 1e8aac
Packit 1e8aac
      g_free (name);
Packit 1e8aac
Packit 1e8aac
      return TRUE;
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  g_free (name);
Packit 1e8aac
Packit 1e8aac
  return FALSE;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
centre_selected_row (GladeNamedIconChooserDialog *dialog)
Packit 1e8aac
{
Packit 1e8aac
  GList *l;
Packit 1e8aac
Packit 1e8aac
  g_assert (dialog->priv->icons_store != NULL);
Packit 1e8aac
  g_assert (dialog->priv->selection != NULL);
Packit 1e8aac
Packit 1e8aac
  l = gtk_tree_selection_get_selected_rows (dialog->priv->selection, NULL);
Packit 1e8aac
Packit 1e8aac
  if (l)
Packit 1e8aac
    {
Packit 1e8aac
      g_assert (gtk_widget_get_mapped (GTK_WIDGET (dialog)));
Packit 1e8aac
      g_assert (gtk_widget_get_visible (GTK_WIDGET (dialog)));
Packit 1e8aac
Packit 1e8aac
      gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (dialog->priv->icons_view),
Packit 1e8aac
                                    (GtkTreePath *) l->data,
Packit 1e8aac
                                    NULL, TRUE, 0.5, 0.0);
Packit 1e8aac
Packit 1e8aac
/*		gtk_tree_view_set_cursor (GTK_TREE_VIEW (dialog->priv->icons_view),
Packit 1e8aac
					 (GtkTreePath *) l->data,
Packit 1e8aac
					 0,
Packit 1e8aac
					 FALSE);
Packit 1e8aac
					 
Packit 1e8aac
		gtk_widget_grab_focus (dialog->priv->icons_view);		
Packit 1e8aac
*/
Packit 1e8aac
      g_list_foreach (l, (GFunc) gtk_tree_path_free, NULL);
Packit 1e8aac
      g_list_free (l);
Packit 1e8aac
    }
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
select_first_row (GladeNamedIconChooserDialog *dialog)
Packit 1e8aac
{
Packit 1e8aac
  GtkTreePath *path;
Packit 1e8aac
Packit 1e8aac
  if (!dialog->priv->filter_model)
Packit 1e8aac
    return;
Packit 1e8aac
Packit 1e8aac
  path = gtk_tree_path_new_from_indices (0, -1);
Packit 1e8aac
  gtk_tree_view_set_cursor (GTK_TREE_VIEW (dialog->priv->icons_view), path,
Packit 1e8aac
                            NULL, FALSE);
Packit 1e8aac
  gtk_tree_path_free (path);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
pending_select_name_process (GladeNamedIconChooserDialog *dialog)
Packit 1e8aac
{
Packit 1e8aac
  ForEachFuncData *data;
Packit 1e8aac
Packit 1e8aac
  g_assert (dialog->priv->icons_store != NULL);
Packit 1e8aac
  g_assert (dialog->priv->selection != NULL);
Packit 1e8aac
Packit 1e8aac
  if (dialog->priv->pending_select_name)
Packit 1e8aac
    {
Packit 1e8aac
Packit 1e8aac
      data = g_slice_new0 (ForEachFuncData);
Packit 1e8aac
Packit 1e8aac
      data->name = dialog->priv->pending_select_name;
Packit 1e8aac
      data->do_select = TRUE;
Packit 1e8aac
      data->do_activate = FALSE;
Packit 1e8aac
      data->dialog = dialog;
Packit 1e8aac
Packit 1e8aac
      gtk_tree_model_foreach (dialog->priv->filter_model,
Packit 1e8aac
                              scan_for_name_func, data);
Packit 1e8aac
Packit 1e8aac
      g_free (dialog->priv->pending_select_name);
Packit 1e8aac
      dialog->priv->pending_select_name = NULL;
Packit 1e8aac
Packit 1e8aac
      g_slice_free (ForEachFuncData, data);
Packit 1e8aac
Packit 1e8aac
    }
Packit 1e8aac
  else
Packit 1e8aac
    {
Packit 1e8aac
      if (strlen (gtk_entry_get_text (GTK_ENTRY (dialog->priv->entry))) == 0)
Packit 1e8aac
        {
Packit 1e8aac
          select_first_row (dialog);
Packit 1e8aac
        }
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  centre_selected_row (dialog);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static gboolean
Packit 1e8aac
is_standard_icon_name (const gchar *icon_name)
Packit 1e8aac
{
Packit 1e8aac
  GQuark quark;
Packit 1e8aac
Packit 1e8aac
  quark = g_quark_try_string (icon_name);
Packit 1e8aac
Packit 1e8aac
  if (quark == 0)
Packit 1e8aac
    return FALSE;
Packit 1e8aac
Packit 1e8aac
  return (g_hash_table_lookup (standard_icon_quarks, GUINT_TO_POINTER (quark))
Packit 1e8aac
          != NULL);
Packit 1e8aac
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
cleanup_after_load (GladeNamedIconChooserDialog *dialog)
Packit 1e8aac
{
Packit 1e8aac
  dialog->priv->load_id = 0;
Packit 1e8aac
Packit 1e8aac
  pending_select_name_process (dialog);
Packit 1e8aac
Packit 1e8aac
  set_busy_cursor (dialog, FALSE);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
chooser_set_model (GladeNamedIconChooserDialog *dialog)
Packit 1e8aac
{
Packit 1e8aac
Packit 1e8aac
  /* filter model */
Packit 1e8aac
  dialog->priv->filter_model =
Packit 1e8aac
      gtk_tree_model_filter_new (GTK_TREE_MODEL (dialog->priv->icons_store),
Packit 1e8aac
                                 NULL);
Packit 1e8aac
Packit 1e8aac
  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER
Packit 1e8aac
                                          (dialog->priv->filter_model),
Packit 1e8aac
                                          (GtkTreeModelFilterVisibleFunc)
Packit 1e8aac
                                          filter_visible_func, dialog, NULL);
Packit 1e8aac
Packit 1e8aac
  gtk_tree_view_set_model (GTK_TREE_VIEW (dialog->priv->icons_view),
Packit 1e8aac
                           dialog->priv->filter_model);
Packit 1e8aac
  g_object_unref (dialog->priv->filter_model);
Packit 1e8aac
Packit 1e8aac
  gtk_entry_completion_set_model (dialog->priv->entry_completion,
Packit 1e8aac
                                  GTK_TREE_MODEL (dialog->priv->icons_store));
Packit 1e8aac
  gtk_entry_completion_set_text_column (dialog->priv->entry_completion,
Packit 1e8aac
                                        ICONS_NAME_COLUMN);
Packit 1e8aac
Packit 1e8aac
  gtk_tree_view_set_search_column (GTK_TREE_VIEW (dialog->priv->icons_view),
Packit 1e8aac
                                   ICONS_NAME_COLUMN);
Packit 1e8aac
Packit 1e8aac
  dialog->priv->icons_loaded = TRUE;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
typedef struct
Packit 1e8aac
{
Packit 1e8aac
  gchar *name;
Packit 1e8aac
  gint context;
Packit 1e8aac
} IconData;
Packit 1e8aac
Packit 1e8aac
static gint
Packit 1e8aac
icon_data_compare (IconData *a, IconData *b)
Packit 1e8aac
{
Packit 1e8aac
  return g_ascii_strcasecmp (a->name, b->name);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static gboolean
Packit 1e8aac
reload_icons (GladeNamedIconChooserDialog *dialog)
Packit 1e8aac
{
Packit 1e8aac
  GtkListStore *store = dialog->priv->icons_store;
Packit 1e8aac
  GtkTreeIter iter;
Packit 1e8aac
  guint i;
Packit 1e8aac
  GList *l, *icons = NULL;
Packit 1e8aac
Packit 1e8aac
  /* retrieve icon names from each context */
Packit 1e8aac
  for (i = 0; i < G_N_ELEMENTS (standard_contexts); i++)
Packit 1e8aac
    {
Packit 1e8aac
Packit 1e8aac
      GList *icons_in_context =
Packit 1e8aac
          gtk_icon_theme_list_icons (dialog->priv->icon_theme,
Packit 1e8aac
                                     standard_contexts[i].name);
Packit 1e8aac
Packit 1e8aac
      for (l = icons_in_context; l; l = l->next)
Packit 1e8aac
        {
Packit 1e8aac
Packit 1e8aac
          IconData *data = g_slice_new (IconData);
Packit 1e8aac
Packit 1e8aac
          data->name = (gchar *) l->data;
Packit 1e8aac
          data->context = i;
Packit 1e8aac
Packit 1e8aac
          icons = g_list_prepend (icons, data);
Packit 1e8aac
        }
Packit 1e8aac
Packit 1e8aac
      g_list_free (icons_in_context);
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  /* sort icon names */
Packit 1e8aac
  icons = g_list_sort (icons, (GCompareFunc) icon_data_compare);
Packit 1e8aac
Packit 1e8aac
  /* put into to model */
Packit 1e8aac
  for (l = icons; l; l = l->next)
Packit 1e8aac
    {
Packit 1e8aac
Packit 1e8aac
      IconData *data = (IconData *) l->data;
Packit 1e8aac
Packit 1e8aac
      gtk_list_store_append (store, &iter);
Packit 1e8aac
      gtk_list_store_set (store, &iter,
Packit 1e8aac
                          ICONS_CONTEXT_COLUMN, data->context,
Packit 1e8aac
                          ICONS_STANDARD_COLUMN,
Packit 1e8aac
                          is_standard_icon_name (data->name), ICONS_NAME_COLUMN,
Packit 1e8aac
                          data->name, -1);
Packit 1e8aac
Packit 1e8aac
      g_free (data->name);
Packit 1e8aac
      g_slice_free (IconData, data);
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  g_list_free (icons);
Packit 1e8aac
Packit 1e8aac
  chooser_set_model (dialog);
Packit 1e8aac
Packit 1e8aac
  return FALSE;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
change_icon_theme (GladeNamedIconChooserDialog *dialog)
Packit 1e8aac
{
Packit 1e8aac
  if (dialog->priv->icon_theme == NULL)
Packit 1e8aac
    dialog->priv->icon_theme = get_icon_theme_for_widget (GTK_WIDGET (dialog));
Packit 1e8aac
Packit 1e8aac
  gtk_tree_view_set_model (GTK_TREE_VIEW (dialog->priv->icons_view), NULL);
Packit 1e8aac
  gtk_list_store_clear (dialog->priv->icons_store);
Packit 1e8aac
Packit 1e8aac
  set_busy_cursor (dialog, TRUE);
Packit 1e8aac
Packit 1e8aac
  dialog->priv->load_id = g_idle_add_full (G_PRIORITY_HIGH_IDLE + 300,
Packit 1e8aac
                                           (GSourceFunc) reload_icons,
Packit 1e8aac
                                           dialog,
Packit 1e8aac
                                           (GDestroyNotify) cleanup_after_load);
Packit 1e8aac
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
glade_named_icon_chooser_dialog_screen_changed (GtkWidget *widget,
Packit 1e8aac
                                                GdkScreen *previous_screen)
Packit 1e8aac
{
Packit 1e8aac
  GladeNamedIconChooserDialog *dialog;
Packit 1e8aac
Packit 1e8aac
  dialog = GLADE_NAMED_ICON_CHOOSER_DIALOG (widget);
Packit 1e8aac
Packit 1e8aac
  if (GTK_WIDGET_CLASS (glade_named_icon_chooser_dialog_parent_class)->
Packit 1e8aac
      screen_changed)
Packit 1e8aac
    GTK_WIDGET_CLASS (glade_named_icon_chooser_dialog_parent_class)->
Packit 1e8aac
        screen_changed (widget, previous_screen);
Packit 1e8aac
Packit 1e8aac
  if (gtk_widget_get_mapped (widget))
Packit 1e8aac
    change_icon_theme (dialog);
Packit 1e8aac
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static GtkWidget *
Packit 1e8aac
create_icons_view (GladeNamedIconChooserDialog *dialog)
Packit 1e8aac
{
Packit 1e8aac
  GtkTreeView *view;
Packit 1e8aac
  GtkTreeViewColumn *column;
Packit 1e8aac
  GtkCellRenderer *pixbuf_renderer, *text_renderer;
Packit 1e8aac
Packit 1e8aac
  view = GTK_TREE_VIEW (gtk_tree_view_new ());
Packit 1e8aac
Packit 1e8aac
  column = gtk_tree_view_column_new ();
Packit 1e8aac
  gtk_tree_view_column_set_min_width (column, 56);
Packit 1e8aac
  gtk_tree_view_column_set_title (column, NULL);
Packit 1e8aac
  pixbuf_renderer = gtk_cell_renderer_pixbuf_new ();
Packit 1e8aac
Packit 1e8aac
  gtk_tree_view_column_pack_start (column, pixbuf_renderer, TRUE);
Packit 1e8aac
Packit 1e8aac
  gtk_tree_view_column_set_attributes (column,
Packit 1e8aac
                                       pixbuf_renderer,
Packit 1e8aac
                                       "icon-name", ICONS_NAME_COLUMN, NULL);
Packit 1e8aac
Packit 1e8aac
  gtk_tree_view_append_column (view, column);
Packit 1e8aac
  g_object_set (pixbuf_renderer,
Packit 1e8aac
                "xpad", 2,
Packit 1e8aac
                "xalign", 1.0, "stock-size", GTK_ICON_SIZE_MENU, NULL);
Packit 1e8aac
Packit 1e8aac
  column = gtk_tree_view_column_new ();
Packit 1e8aac
  gtk_tree_view_column_set_title (column, "Name");
Packit 1e8aac
  text_renderer = gtk_cell_renderer_text_new ();
Packit 1e8aac
  g_object_set (G_OBJECT (text_renderer),
Packit 1e8aac
                "ellipsize", PANGO_ELLIPSIZE_END, "yalign", 0.0, NULL);
Packit 1e8aac
Packit 1e8aac
  gtk_tree_view_column_pack_start (column, text_renderer, TRUE);
Packit 1e8aac
Packit 1e8aac
  gtk_tree_view_column_set_attributes (column,
Packit 1e8aac
                                       text_renderer,
Packit 1e8aac
                                       "text", ICONS_NAME_COLUMN, NULL);
Packit 1e8aac
Packit 1e8aac
Packit 1e8aac
  gtk_tree_view_append_column (view, column);
Packit 1e8aac
  gtk_tree_view_column_set_expand (column, TRUE);
Packit 1e8aac
  gtk_tree_view_column_set_resizable (column, FALSE);
Packit 1e8aac
Packit 1e8aac
  gtk_tree_view_set_headers_visible (view, FALSE);
Packit 1e8aac
Packit 1e8aac
  gtk_tree_view_set_enable_search (view, TRUE);
Packit 1e8aac
  gtk_tree_view_set_search_equal_func (view,
Packit 1e8aac
                                       (GtkTreeViewSearchEqualFunc)
Packit 1e8aac
                                       search_equal_func, dialog, NULL);
Packit 1e8aac
Packit 1e8aac
  g_signal_connect (view, "row-activated",
Packit 1e8aac
                    G_CALLBACK (icons_row_activated_cb), dialog);
Packit 1e8aac
Packit 1e8aac
  g_signal_connect (gtk_tree_view_get_selection (view), "changed",
Packit 1e8aac
                    G_CALLBACK (icons_selection_changed_cb), dialog);
Packit 1e8aac
Packit 1e8aac
  gtk_tree_selection_set_mode (gtk_tree_view_get_selection (view),
Packit 1e8aac
                               GTK_SELECTION_BROWSE);
Packit 1e8aac
Packit 1e8aac
  dialog->priv->selection = gtk_tree_view_get_selection (view);
Packit 1e8aac
Packit 1e8aac
  gtk_tree_view_set_rules_hint (view, TRUE);
Packit 1e8aac
Packit 1e8aac
  gtk_widget_show (GTK_WIDGET (view));
Packit 1e8aac
Packit 1e8aac
  return GTK_WIDGET (view);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
/* sets the 'list-standard' state and refilters the icons model */
Packit 1e8aac
static void
Packit 1e8aac
button_toggled (GtkToggleButton *button, GladeNamedIconChooserDialog *dialog)
Packit 1e8aac
{
Packit 1e8aac
  dialog->priv->settings_list_standard = gtk_toggle_button_get_active (button);
Packit 1e8aac
Packit 1e8aac
  if (dialog->priv->filter_model != NULL)
Packit 1e8aac
    filter_icons_model (dialog);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static GHashTable *
Packit 1e8aac
create_standard_icon_quarks (void)
Packit 1e8aac
{
Packit 1e8aac
  GHashTable *table;
Packit 1e8aac
  GQuark quark;
Packit 1e8aac
  guint i;
Packit 1e8aac
Packit 1e8aac
  table = g_hash_table_new (NULL, NULL);
Packit 1e8aac
Packit 1e8aac
  for (i = 0; i < G_N_ELEMENTS (standard_icon_names); i++)
Packit 1e8aac
    {
Packit 1e8aac
Packit 1e8aac
      quark = g_quark_from_static_string (standard_icon_names[i]);
Packit 1e8aac
Packit 1e8aac
      g_hash_table_insert (table,
Packit 1e8aac
                           GUINT_TO_POINTER (quark), GUINT_TO_POINTER (quark));
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  return table;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
glade_named_icon_chooser_dialog_style_set (GtkWidget *widget,
Packit 1e8aac
                                           GtkStyle  *previous_style)
Packit 1e8aac
{
Packit 1e8aac
  if (gtk_widget_has_screen (widget) && gtk_widget_get_mapped (widget))
Packit 1e8aac
    change_icon_theme (GLADE_NAMED_ICON_CHOOSER_DIALOG (widget));
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
/* override GtkWidget::show_all since we have internal widgets we wish to keep
Packit 1e8aac
 * hidden unless we decide otherwise, like the list-standard-icons-only checkbox.
Packit 1e8aac
 */
Packit 1e8aac
static void
Packit 1e8aac
glade_named_icon_chooser_dialog_show_all (GtkWidget *widget)
Packit 1e8aac
{
Packit 1e8aac
  gtk_widget_show (widget);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
/* Handler for GtkWindow::set-focus; this is where we save the last-focused
Packit 1e8aac
 * widget on our toplevel.  See glade_named_icon_chooser_dialog_hierarchy_changed()
Packit 1e8aac
 */
Packit 1e8aac
static void
Packit 1e8aac
glade_named_icon_chooser_dialog_set_focus (GtkWindow *window, GtkWidget *focus)
Packit 1e8aac
{
Packit 1e8aac
Packit 1e8aac
  GTK_WINDOW_CLASS (glade_named_icon_chooser_dialog_parent_class)->
Packit 1e8aac
      set_focus (window, focus);
Packit 1e8aac
Packit 1e8aac
  GLADE_NAMED_ICON_CHOOSER_DIALOG (window)->priv->last_focus_widget =
Packit 1e8aac
      gtk_window_get_focus (window);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
glade_named_icon_chooser_dialog_finalize (GObject *object)
Packit 1e8aac
{
Packit 1e8aac
  GladeNamedIconChooserDialog *dialog =
Packit 1e8aac
      GLADE_NAMED_ICON_CHOOSER_DIALOG (object);
Packit 1e8aac
Packit 1e8aac
  if (dialog->priv->pending_select_name)
Packit 1e8aac
    {
Packit 1e8aac
      g_free (dialog->priv->pending_select_name);
Packit 1e8aac
      dialog->priv->pending_select_name = NULL;
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  G_OBJECT_CLASS (glade_named_icon_chooser_dialog_parent_class)->
Packit 1e8aac
    finalize (object);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
glade_named_icon_chooser_dialog_map (GtkWidget *widget)
Packit 1e8aac
{
Packit 1e8aac
  GladeNamedIconChooserDialog *dialog =
Packit 1e8aac
      GLADE_NAMED_ICON_CHOOSER_DIALOG (widget);
Packit 1e8aac
Packit 1e8aac
  GTK_WIDGET_CLASS (glade_named_icon_chooser_dialog_parent_class)->map (widget);
Packit 1e8aac
Packit 1e8aac
  settings_load (dialog);
Packit 1e8aac
Packit 1e8aac
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->button),
Packit 1e8aac
                                dialog->priv->settings_list_standard);
Packit 1e8aac
Packit 1e8aac
  gtk_widget_grab_focus (dialog->priv->icons_view);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
glade_named_icon_chooser_dialog_unmap (GtkWidget *widget)
Packit 1e8aac
{
Packit 1e8aac
  GladeNamedIconChooserDialog *dialog =
Packit 1e8aac
      GLADE_NAMED_ICON_CHOOSER_DIALOG (widget);
Packit 1e8aac
Packit 1e8aac
  settings_save (dialog);
Packit 1e8aac
Packit 1e8aac
  GTK_WIDGET_CLASS (glade_named_icon_chooser_dialog_parent_class)->
Packit 1e8aac
      unmap (widget);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
/* we load the icons in expose() because we want the widget
Packit 1e8aac
 * to be fully painted before loading begins
Packit 1e8aac
 */
Packit 1e8aac
static gboolean
Packit 1e8aac
glade_named_icon_chooser_dialog_draw (GtkWidget *widget, cairo_t *cr)
Packit 1e8aac
{
Packit 1e8aac
  GladeNamedIconChooserDialog *dialog =
Packit 1e8aac
      GLADE_NAMED_ICON_CHOOSER_DIALOG (widget);
Packit 1e8aac
  gboolean retval;
Packit 1e8aac
Packit 1e8aac
  retval =
Packit 1e8aac
      GTK_WIDGET_CLASS (glade_named_icon_chooser_dialog_parent_class)->
Packit 1e8aac
      draw (widget, cr);
Packit 1e8aac
  if (!dialog->priv->icons_loaded)
Packit 1e8aac
    {
Packit 1e8aac
      change_icon_theme (GLADE_NAMED_ICON_CHOOSER_DIALOG (widget));
Packit 1e8aac
      dialog->priv->icons_loaded = TRUE;
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  return retval;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
response_cb (GtkDialog *dialog, gint response_id)
Packit 1e8aac
{
Packit 1e8aac
  /* Act only on response IDs we recognize */
Packit 1e8aac
  if (!(response_id == GTK_RESPONSE_ACCEPT
Packit 1e8aac
        || response_id == GTK_RESPONSE_OK
Packit 1e8aac
        || response_id == GTK_RESPONSE_YES
Packit 1e8aac
        || response_id == GTK_RESPONSE_APPLY))
Packit 1e8aac
    return;
Packit 1e8aac
Packit 1e8aac
  if (!should_respond (GLADE_NAMED_ICON_CHOOSER_DIALOG (dialog)))
Packit 1e8aac
    {
Packit 1e8aac
      g_signal_stop_emission_by_name (dialog, "response");
Packit 1e8aac
    }
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
/* we intercept the GladeNamedIconChooser::icon-activated signal and try to
Packit 1e8aac
 * make the dialog emit a valid response signal
Packit 1e8aac
 */
Packit 1e8aac
static void
Packit 1e8aac
icon_activated_cb (GladeNamedIconChooserDialog *dialog)
Packit 1e8aac
{
Packit 1e8aac
  GList *children, *l;
Packit 1e8aac
Packit 1e8aac
  children =
Packit 1e8aac
      gtk_container_get_children (GTK_CONTAINER
Packit 1e8aac
                                  (gtk_dialog_get_action_area
Packit 1e8aac
                                   (GTK_DIALOG (dialog))));
Packit 1e8aac
Packit 1e8aac
  for (l = children; l; l = l->next)
Packit 1e8aac
    {
Packit 1e8aac
      GtkWidget *widget;
Packit 1e8aac
      gint response_id;
Packit 1e8aac
Packit 1e8aac
      widget = GTK_WIDGET (l->data);
Packit 1e8aac
      response_id =
Packit 1e8aac
          gtk_dialog_get_response_for_widget (GTK_DIALOG (dialog), widget);
Packit 1e8aac
Packit 1e8aac
      if (response_id == GTK_RESPONSE_ACCEPT ||
Packit 1e8aac
          response_id == GTK_RESPONSE_OK ||
Packit 1e8aac
          response_id == GTK_RESPONSE_YES || response_id == GTK_RESPONSE_APPLY)
Packit 1e8aac
        {
Packit 1e8aac
          g_list_free (children);
Packit 1e8aac
Packit 1e8aac
          gtk_dialog_response (GTK_DIALOG (dialog), response_id);
Packit 1e8aac
Packit 1e8aac
          return;
Packit 1e8aac
        }
Packit 1e8aac
    }
Packit 1e8aac
  g_list_free (children);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
/* we intercept the GladeNamedIconChooser::selection-changed signal and try to
Packit 1e8aac
 * make the affirmative response button insensitive when the selection is empty 
Packit 1e8aac
 */
Packit 1e8aac
static void
Packit 1e8aac
selection_changed_cb (GladeNamedIconChooserDialog *dialog)
Packit 1e8aac
{
Packit 1e8aac
  GList *children, *l;
Packit 1e8aac
  gchar *icon_name;
Packit 1e8aac
Packit 1e8aac
  children =
Packit 1e8aac
      gtk_container_get_children (GTK_CONTAINER
Packit 1e8aac
                                  (gtk_dialog_get_action_area
Packit 1e8aac
                                   (GTK_DIALOG (dialog))));
Packit 1e8aac
Packit 1e8aac
  for (l = children; l; l = l->next)
Packit 1e8aac
    {
Packit 1e8aac
      GtkWidget *widget;
Packit 1e8aac
      gint response_id;
Packit 1e8aac
Packit 1e8aac
      widget = GTK_WIDGET (l->data);
Packit 1e8aac
      response_id =
Packit 1e8aac
          gtk_dialog_get_response_for_widget (GTK_DIALOG (dialog), widget);
Packit 1e8aac
Packit 1e8aac
      if (response_id == GTK_RESPONSE_ACCEPT ||
Packit 1e8aac
          response_id == GTK_RESPONSE_OK ||
Packit 1e8aac
          response_id == GTK_RESPONSE_YES || response_id == GTK_RESPONSE_APPLY)
Packit 1e8aac
        {
Packit 1e8aac
          icon_name = glade_named_icon_chooser_dialog_get_icon_name (dialog);
Packit 1e8aac
Packit 1e8aac
          gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
Packit 1e8aac
                                             response_id, icon_name != NULL);
Packit 1e8aac
          g_free (icon_name);
Packit 1e8aac
          g_list_free (children);
Packit 1e8aac
          return;
Packit 1e8aac
        }
Packit 1e8aac
    }
Packit 1e8aac
  g_list_free (children);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
glade_named_icon_chooser_dialog_init (GladeNamedIconChooserDialog *dialog)
Packit 1e8aac
{
Packit 1e8aac
  GtkWidget *contents;
Packit 1e8aac
  GtkWidget *hbox;
Packit 1e8aac
  GtkWidget *vbox;
Packit 1e8aac
  GtkWidget *sw;
Packit 1e8aac
  GtkWidget *label;
Packit 1e8aac
  GtkWidget *hpaned;
Packit 1e8aac
  GtkWidget *content_area;
Packit 1e8aac
  GtkSizeGroup *group;
Packit 1e8aac
Packit 1e8aac
  dialog->priv = glade_named_icon_chooser_dialog_get_instance_private (dialog);
Packit 1e8aac
Packit 1e8aac
  dialog->priv->filter_model = NULL;
Packit 1e8aac
  dialog->priv->icons_store = NULL;
Packit 1e8aac
  dialog->priv->context_id = -1;
Packit 1e8aac
  dialog->priv->pending_select_name = NULL;
Packit 1e8aac
  dialog->priv->last_focus_widget = NULL;
Packit 1e8aac
  dialog->priv->icons_loaded = FALSE;
Packit 1e8aac
Packit 1e8aac
Packit 1e8aac
  gtk_window_set_title (GTK_WINDOW (dialog), _("Named Icon Chooser"));
Packit 1e8aac
Packit 1e8aac
  gtk_window_set_default_size (GTK_WINDOW (dialog), 610, 480);
Packit 1e8aac
Packit 1e8aac
  _glade_util_dialog_set_hig (GTK_DIALOG (dialog));
Packit 1e8aac
  content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
Packit 1e8aac
Packit 1e8aac
  /* We do a signal connection here rather than overriding the method in
Packit 1e8aac
   * class_init because GtkDialog::response is a RUN_LAST signal.  We want *our*
Packit 1e8aac
   * handler to be run *first*, regardless of whether the user installs response
Packit 1e8aac
   * handlers of his own.
Packit 1e8aac
   */
Packit 1e8aac
  g_signal_connect (dialog, "response", G_CALLBACK (response_cb), NULL);
Packit 1e8aac
Packit 1e8aac
  g_signal_connect (dialog, "icon-activated",
Packit 1e8aac
                    G_CALLBACK (icon_activated_cb), NULL);
Packit 1e8aac
Packit 1e8aac
  g_signal_connect (dialog, "selection-changed",
Packit 1e8aac
                    G_CALLBACK (selection_changed_cb), NULL);
Packit 1e8aac
Packit 1e8aac
Packit 1e8aac
  if (standard_icon_quarks == NULL)
Packit 1e8aac
    standard_icon_quarks = create_standard_icon_quarks ();
Packit 1e8aac
Packit 1e8aac
  contents = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
Packit 1e8aac
  gtk_container_set_border_width (GTK_CONTAINER (contents), 5);
Packit 1e8aac
  gtk_widget_show (contents);
Packit 1e8aac
Packit 1e8aac
  label = gtk_label_new_with_mnemonic (_("Icon _Name:"));
Packit 1e8aac
  gtk_widget_set_halign (label, GTK_ALIGN_START);
Packit 1e8aac
  gtk_widget_show (label);
Packit 1e8aac
Packit 1e8aac
  dialog->priv->entry = gtk_entry_new ();
Packit 1e8aac
  gtk_entry_set_activates_default (GTK_ENTRY (dialog->priv->entry), TRUE);
Packit 1e8aac
  gtk_entry_set_width_chars (GTK_ENTRY (dialog->priv->entry), 40);
Packit 1e8aac
  g_object_set (G_OBJECT (dialog->priv->entry), "truncate-multiline", TRUE,
Packit 1e8aac
                NULL);
Packit 1e8aac
  g_signal_connect (G_OBJECT (dialog->priv->entry), "changed",
Packit 1e8aac
                    G_CALLBACK (changed_text_handler), dialog);
Packit 1e8aac
  g_signal_connect (G_OBJECT (dialog->priv->entry), "insert-text",
Packit 1e8aac
                    G_CALLBACK (insert_text_handler), dialog);
Packit 1e8aac
  gtk_widget_show (dialog->priv->entry);
Packit 1e8aac
Packit 1e8aac
  dialog->priv->entry_completion = gtk_entry_completion_new ();
Packit 1e8aac
  gtk_entry_set_completion (GTK_ENTRY (dialog->priv->entry),
Packit 1e8aac
                            dialog->priv->entry_completion);
Packit 1e8aac
  gtk_entry_completion_set_popup_completion (dialog->priv->entry_completion,
Packit 1e8aac
                                             FALSE);
Packit 1e8aac
  gtk_entry_completion_set_inline_completion (dialog->priv->entry_completion,
Packit 1e8aac
                                              TRUE);
Packit 1e8aac
Packit 1e8aac
  gtk_label_set_mnemonic_widget (GTK_LABEL (label), dialog->priv->entry);
Packit 1e8aac
Packit 1e8aac
  hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
Packit 1e8aac
  gtk_widget_show (hbox);
Packit 1e8aac
Packit 1e8aac
  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
Packit 1e8aac
  gtk_box_pack_start (GTK_BOX (hbox), dialog->priv->entry, TRUE, TRUE, 0);
Packit 1e8aac
  gtk_box_pack_start (GTK_BOX (contents), hbox, FALSE, FALSE, 6);
Packit 1e8aac
Packit 1e8aac
  hpaned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
Packit 1e8aac
  gtk_paned_set_position (GTK_PANED (hpaned), 150);
Packit 1e8aac
  gtk_widget_show (hpaned);
Packit 1e8aac
Packit 1e8aac
  dialog->priv->contexts_view = create_contexts_view (dialog);
Packit 1e8aac
  dialog->priv->icons_view = create_icons_view (dialog);
Packit 1e8aac
Packit 1e8aac
  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
Packit 1e8aac
  gtk_widget_show (vbox);
Packit 1e8aac
Packit 1e8aac
  group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
Packit 1e8aac
Packit 1e8aac
  label = gtk_label_new_with_mnemonic (_("C_ontexts:"));
Packit 1e8aac
  gtk_label_set_mnemonic_widget (GTK_LABEL (label),
Packit 1e8aac
                                 dialog->priv->contexts_view);
Packit 1e8aac
  gtk_widget_set_halign (label, GTK_ALIGN_START);
Packit 1e8aac
  gtk_size_group_add_widget (group, label);
Packit 1e8aac
  gtk_widget_show (label);
Packit 1e8aac
Packit 1e8aac
  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
Packit 1e8aac
Packit 1e8aac
  sw = gtk_scrolled_window_new (NULL, NULL);
Packit 1e8aac
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_NEVER,
Packit 1e8aac
                                  GTK_POLICY_AUTOMATIC);
Packit 1e8aac
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN);
Packit 1e8aac
  gtk_widget_show (sw);
Packit 1e8aac
Packit 1e8aac
  gtk_container_add (GTK_CONTAINER (sw), dialog->priv->contexts_view);
Packit 1e8aac
  gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
Packit 1e8aac
  gtk_paned_pack1 (GTK_PANED (hpaned), vbox, FALSE, FALSE);
Packit 1e8aac
Packit 1e8aac
Packit 1e8aac
  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
Packit 1e8aac
  gtk_widget_show (vbox);
Packit 1e8aac
Packit 1e8aac
  label = gtk_label_new_with_mnemonic (_("Icon Na_mes:"));
Packit 1e8aac
  gtk_label_set_mnemonic_widget (GTK_LABEL (label), dialog->priv->icons_view);
Packit 1e8aac
  gtk_widget_set_halign (label, GTK_ALIGN_START);
Packit 1e8aac
  gtk_size_group_add_widget (group, label);
Packit 1e8aac
  gtk_widget_show (label);
Packit 1e8aac
Packit 1e8aac
  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
Packit 1e8aac
Packit 1e8aac
  sw = gtk_scrolled_window_new (NULL, NULL);
Packit 1e8aac
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_NEVER,
Packit 1e8aac
                                  GTK_POLICY_AUTOMATIC);
Packit 1e8aac
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN);
Packit 1e8aac
  gtk_widget_show (sw);
Packit 1e8aac
Packit 1e8aac
  gtk_container_add (GTK_CONTAINER (sw), dialog->priv->icons_view);
Packit 1e8aac
  gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
Packit 1e8aac
  gtk_paned_pack2 (GTK_PANED (hpaned), vbox, TRUE, FALSE);
Packit 1e8aac
Packit 1e8aac
  gtk_box_pack_start (GTK_BOX (contents), hpaned, TRUE, TRUE, 0);
Packit 1e8aac
Packit 1e8aac
Packit 1e8aac
  g_object_unref (G_OBJECT (group));
Packit 1e8aac
Packit 1e8aac
  dialog->priv->button =
Packit 1e8aac
      gtk_check_button_new_with_mnemonic (_("_List standard icons only"));
Packit 1e8aac
  gtk_widget_show (dialog->priv->button);
Packit 1e8aac
Packit 1e8aac
  g_signal_connect (dialog->priv->button, "toggled",
Packit 1e8aac
                    G_CALLBACK (button_toggled), dialog);
Packit 1e8aac
Packit 1e8aac
  gtk_box_pack_start (GTK_BOX (contents), dialog->priv->button, FALSE, FALSE,
Packit 1e8aac
                      0);
Packit 1e8aac
  gtk_box_pack_start (GTK_BOX (content_area), contents, TRUE, TRUE, 0);
Packit 1e8aac
Packit 1e8aac
  /* underlying model */
Packit 1e8aac
  dialog->priv->icons_store = gtk_list_store_new (ICONS_N_COLUMNS,
Packit 1e8aac
                                                  G_TYPE_UINT,
Packit 1e8aac
                                                  G_TYPE_BOOLEAN,
Packit 1e8aac
                                                  G_TYPE_STRING);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
glade_named_icon_chooser_dialog_class_init (GladeNamedIconChooserDialogClass *klass)
Packit 1e8aac
{
Packit 1e8aac
  GObjectClass *object_class;
Packit 1e8aac
  GtkWidgetClass *widget_class;
Packit 1e8aac
  GtkWindowClass *window_class;
Packit 1e8aac
Packit 1e8aac
  object_class = G_OBJECT_CLASS (klass);
Packit 1e8aac
  widget_class = GTK_WIDGET_CLASS (klass);
Packit 1e8aac
  window_class = GTK_WINDOW_CLASS (klass);
Packit 1e8aac
Packit 1e8aac
  object_class->finalize = glade_named_icon_chooser_dialog_finalize;
Packit 1e8aac
Packit 1e8aac
  widget_class->map = glade_named_icon_chooser_dialog_map;
Packit 1e8aac
  widget_class->unmap = glade_named_icon_chooser_dialog_unmap;
Packit 1e8aac
  widget_class->draw = glade_named_icon_chooser_dialog_draw;
Packit 1e8aac
  widget_class->show_all = glade_named_icon_chooser_dialog_show_all;
Packit 1e8aac
  widget_class->style_set = glade_named_icon_chooser_dialog_style_set;
Packit 1e8aac
  widget_class->screen_changed = glade_named_icon_chooser_dialog_screen_changed;
Packit 1e8aac
Packit 1e8aac
  window_class->set_focus = glade_named_icon_chooser_dialog_set_focus;
Packit 1e8aac
Packit 1e8aac
        /**
Packit 1e8aac
	 * GladeNamedIconChooserDialog::icon-activated
Packit 1e8aac
	 * @chooser: the object which received the signal
Packit 1e8aac
	 *
Packit 1e8aac
	 * This signal is emitted when the user "activates" an icon
Packit 1e8aac
	 * in the named icon chooser.  This can happen by double-clicking on an item
Packit 1e8aac
	 * in the recently used resources list, or by pressing
Packit 1e8aac
	 * <keycap>Enter</keycap>.
Packit 1e8aac
	*/
Packit 1e8aac
  dialog_signals[ICON_ACTIVATED] =
Packit 1e8aac
      g_signal_new ("icon-activated",
Packit 1e8aac
                    G_TYPE_FROM_CLASS (object_class),
Packit 1e8aac
                    G_SIGNAL_RUN_LAST,
Packit 1e8aac
                    G_STRUCT_OFFSET (GladeNamedIconChooserDialogClass,
Packit 1e8aac
                                     icon_activated), NULL, NULL,
Packit 1e8aac
                    g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
Packit 1e8aac
Packit 1e8aac
        /**
Packit 1e8aac
	 * GladeNamedIconChooserDialog::selection-changed
Packit 1e8aac
	 * @chooser: the object which received the signal
Packit 1e8aac
	 *
Packit 1e8aac
	 * This signal is emitted when there is a change in the set of
Packit 1e8aac
	 * selected icon names.  This can happen when a user
Packit 1e8aac
	 * modifies the selection with the mouse or the keyboard, or when
Packit 1e8aac
	 * explicitely calling functions to change the selection.
Packit 1e8aac
	*/
Packit 1e8aac
  dialog_signals[SELECTION_CHANGED] =
Packit 1e8aac
      g_signal_new ("selection-changed",
Packit 1e8aac
                    G_TYPE_FROM_CLASS (object_class),
Packit 1e8aac
                    G_SIGNAL_RUN_LAST,
Packit 1e8aac
                    G_STRUCT_OFFSET (GladeNamedIconChooserDialogClass,
Packit 1e8aac
                                     selection_changed), NULL, NULL,
Packit 1e8aac
                    g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static gboolean
Packit 1e8aac
should_respond (GladeNamedIconChooserDialog *dialog)
Packit 1e8aac
{
Packit 1e8aac
  gchar *icon_name;
Packit 1e8aac
Packit 1e8aac
  /* is there an icon selected? */
Packit 1e8aac
  icon_name = glade_named_icon_chooser_dialog_get_icon_name (dialog);
Packit 1e8aac
  if (!icon_name)
Packit 1e8aac
    return FALSE;
Packit 1e8aac
Packit 1e8aac
  g_free (icon_name);
Packit 1e8aac
  return TRUE;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
/* get's the name of the configuration file */
Packit 1e8aac
static gchar *
Packit 1e8aac
get_config_filename (void)
Packit 1e8aac
{
Packit 1e8aac
  return g_build_filename (g_get_user_config_dir (), "gladeui", "config", NULL);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
/* get's the name of the directory that contains the config file */
Packit 1e8aac
static char *
Packit 1e8aac
get_config_dirname (void)
Packit 1e8aac
{
Packit 1e8aac
  return g_build_filename (g_get_user_config_dir (), "gladeui", NULL);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
/* loads the configuration settings */
Packit 1e8aac
static void
Packit 1e8aac
settings_load (GladeNamedIconChooserDialog *dialog)
Packit 1e8aac
{
Packit 1e8aac
  GKeyFile *keyfile;
Packit 1e8aac
  gboolean success, boolean_value;
Packit 1e8aac
  gchar *filename;
Packit 1e8aac
  GError *error = NULL;
Packit 1e8aac
Packit 1e8aac
  keyfile = g_key_file_new ();
Packit 1e8aac
Packit 1e8aac
  filename = get_config_filename ();
Packit 1e8aac
  success = g_key_file_load_from_file (keyfile,
Packit 1e8aac
                                       filename, G_KEY_FILE_NONE, &error);
Packit 1e8aac
  g_free (filename);
Packit 1e8aac
Packit 1e8aac
  if (!success)
Packit 1e8aac
    {
Packit 1e8aac
Packit 1e8aac
      dialog->priv->settings_list_standard = DEFAULT_SETTING_LIST_STANDARD_ONLY;
Packit 1e8aac
Packit 1e8aac
      g_clear_error (&error);
Packit 1e8aac
      g_key_file_free (keyfile);
Packit 1e8aac
      return;
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
Packit 1e8aac
  boolean_value = g_key_file_get_boolean (keyfile,
Packit 1e8aac
                                          "Named Icon Chooser",
Packit 1e8aac
                                          "ListStandardOnly", &error);
Packit 1e8aac
  if (error)
Packit 1e8aac
    {
Packit 1e8aac
      dialog->priv->settings_list_standard = DEFAULT_SETTING_LIST_STANDARD_ONLY;
Packit 1e8aac
      g_clear_error (&error);
Packit 1e8aac
    }
Packit 1e8aac
  else
Packit 1e8aac
    {
Packit 1e8aac
      dialog->priv->settings_list_standard = boolean_value;
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  g_key_file_free (keyfile);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
/* creates a GKeyFile based on the current settings */
Packit 1e8aac
static GKeyFile *
Packit 1e8aac
settings_to_keyfile (GladeNamedIconChooserDialog *dialog)
Packit 1e8aac
{
Packit 1e8aac
  GKeyFile *keyfile;
Packit 1e8aac
  gchar *filename;
Packit 1e8aac
Packit 1e8aac
  keyfile = g_key_file_new ();
Packit 1e8aac
Packit 1e8aac
  filename = get_config_filename ();
Packit 1e8aac
  g_key_file_load_from_file (keyfile,
Packit 1e8aac
                             get_config_filename (),
Packit 1e8aac
                             G_KEY_FILE_NONE, NULL);
Packit 1e8aac
  g_free (filename);
Packit 1e8aac
Packit 1e8aac
  g_key_file_set_boolean (keyfile,
Packit 1e8aac
                          "Named Icon Chooser",
Packit 1e8aac
                          "ListStandardOnly",
Packit 1e8aac
                          dialog->priv->settings_list_standard);
Packit 1e8aac
Packit 1e8aac
  return keyfile;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
/* serializes the the current configuration to the config file */
Packit 1e8aac
static void
Packit 1e8aac
settings_save (GladeNamedIconChooserDialog *dialog)
Packit 1e8aac
{
Packit 1e8aac
  GKeyFile *keyfile;
Packit 1e8aac
  gchar *contents;
Packit 1e8aac
  gsize contents_length;
Packit 1e8aac
  gchar *filename = NULL, *dirname = NULL;
Packit 1e8aac
  GError *error = NULL;
Packit 1e8aac
Packit 1e8aac
  keyfile = settings_to_keyfile (dialog);
Packit 1e8aac
Packit 1e8aac
  contents = g_key_file_to_data (keyfile, &contents_length, &error);
Packit 1e8aac
Packit 1e8aac
  if (error)
Packit 1e8aac
    goto out;
Packit 1e8aac
Packit 1e8aac
  filename = get_config_filename ();
Packit 1e8aac
Packit 1e8aac
  if (!g_file_set_contents (filename, contents, contents_length, NULL))
Packit 1e8aac
    {
Packit 1e8aac
      gchar *dirname;
Packit 1e8aac
      gint saved_errno;
Packit 1e8aac
Packit 1e8aac
      dirname = get_config_dirname ();
Packit 1e8aac
      if (g_mkdir_with_parents (dirname, 0700) != 0)    /* 0700 per the XDG basedir spec */
Packit 1e8aac
        {
Packit 1e8aac
Packit 1e8aac
          saved_errno = errno;
Packit 1e8aac
          g_set_error (&error,
Packit 1e8aac
                       G_FILE_ERROR,
Packit 1e8aac
                       g_file_error_from_errno (saved_errno),
Packit 1e8aac
                       _("Could not create directory: %s"), dirname);
Packit 1e8aac
          goto out;
Packit 1e8aac
        }
Packit 1e8aac
Packit 1e8aac
      if (!g_file_set_contents (filename, contents, contents_length, &error))
Packit 1e8aac
        {
Packit 1e8aac
          goto out;
Packit 1e8aac
        }
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
out:
Packit 1e8aac
Packit 1e8aac
  g_free (contents);
Packit 1e8aac
  g_free (dirname);
Packit 1e8aac
  g_free (filename);
Packit 1e8aac
  g_clear_error (&error);
Packit 1e8aac
  g_key_file_free (keyfile);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static GtkWidget *
Packit 1e8aac
glade_named_icon_chooser_dialog_new_valist (const gchar *title,
Packit 1e8aac
                                            GtkWindow   *parent,
Packit 1e8aac
                                            const gchar *first_button_text,
Packit 1e8aac
                                            va_list      varargs)
Packit 1e8aac
{
Packit 1e8aac
  GtkWidget *result;
Packit 1e8aac
  const char *button_text = first_button_text;
Packit 1e8aac
  gint response_id;
Packit 1e8aac
Packit 1e8aac
  result = g_object_new (GLADE_TYPE_NAMED_ICON_CHOOSER_DIALOG,
Packit 1e8aac
                         "title", title, "transient-for", parent, NULL);
Packit 1e8aac
Packit 1e8aac
  while (button_text)
Packit 1e8aac
    {
Packit 1e8aac
      response_id = va_arg (varargs, gint);
Packit 1e8aac
      gtk_dialog_add_button (GTK_DIALOG (result), button_text, response_id);
Packit 1e8aac
      button_text = va_arg (varargs, const gchar *);
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  return result;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
/**
Packit 1e8aac
 * glade_named_icon_chooser_dialog_new:
Packit 1e8aac
 * @title: Title of the dialog, or %NULL
Packit 1e8aac
 * @parent: Transient parent of the dialog, or %NULL,
Packit 1e8aac
 * @first_button_text: stock ID or text to go in the first button, or %NULL
Packit 1e8aac
 * @Varargs: response ID for the first button, then additional (button, id)
Packit 1e8aac
 *   pairs, ending with %NULL
Packit 1e8aac
 *
Packit 1e8aac
 * Creates a new #GladeNamedIconChooserDialog.  This function is analogous to
Packit 1e8aac
 * gtk_dialog_new_with_buttons().
Packit 1e8aac
 *
Packit 1e8aac
 * Return value: a new #GladeNamedIconChooserDialog
Packit 1e8aac
 */
Packit 1e8aac
GtkWidget *
Packit 1e8aac
glade_named_icon_chooser_dialog_new (const gchar *title,
Packit 1e8aac
                                     GtkWindow   *parent,
Packit 1e8aac
                                     const gchar *first_button_text,
Packit 1e8aac
                                     ...)
Packit 1e8aac
{
Packit 1e8aac
  GtkWidget *result;
Packit 1e8aac
  va_list varargs;
Packit 1e8aac
Packit 1e8aac
  va_start (varargs, first_button_text);
Packit 1e8aac
  result = glade_named_icon_chooser_dialog_new_valist (title,
Packit 1e8aac
                                                       parent,
Packit 1e8aac
                                                       first_button_text,
Packit 1e8aac
                                                       varargs);
Packit 1e8aac
  va_end (varargs);
Packit 1e8aac
Packit 1e8aac
  return result;
Packit 1e8aac
}