Blame gladeui/glade-adaptor-chooser-widget.c

Packit 1e8aac
/*
Packit 1e8aac
 * glade-adaptor-chooser-widget.c
Packit 1e8aac
 *
Packit 1e8aac
 * Copyright (C) 2014-2017 Juan Pablo Ugarte
Packit 1e8aac
 *
Packit 1e8aac
 * This library is free software; you can redistribute it and/or modify it
Packit 1e8aac
 * under the terms of the GNU Lesser General Public License as
Packit 1e8aac
 * published by the Free Software Foundation; either version 2.1 of
Packit 1e8aac
 * the License, or (at your option) any later version.
Packit 1e8aac
 *
Packit 1e8aac
 * This library is distributed in the hope that it will be useful, but
Packit 1e8aac
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 1e8aac
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 1e8aac
 * Lesser General Public License for more details.
Packit 1e8aac
 *
Packit 1e8aac
 * You should have received a copy of the GNU Lesser General Public 
Packit 1e8aac
 * License 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
 * Authors:
Packit 1e8aac
 *   Juan Pablo Ugarte <juanpablougarte@gmail.com>
Packit 1e8aac
 */
Packit 1e8aac
Packit 1e8aac
#include "glade-app.h"
Packit 1e8aac
#include "gladeui-enum-types.h"
Packit 1e8aac
#include "glade-adaptor-chooser-widget.h"
Packit 1e8aac
#include "glade-dnd.h"
Packit 1e8aac
Packit 1e8aac
#include <string.h>
Packit 1e8aac
Packit 1e8aac
enum
Packit 1e8aac
{
Packit 1e8aac
  COLUMN_ADAPTOR = 0,
Packit 1e8aac
  COLUMN_GROUP,
Packit 1e8aac
  COLUMN_NORMALIZED_NAME,
Packit 1e8aac
  COLUMN_NORMALIZED_NAME_LEN,
Packit 1e8aac
  N_COLUMN
Packit 1e8aac
};
Packit 1e8aac
Packit 1e8aac
struct _GladeAdaptorChooserWidgetPrivate
Packit 1e8aac
{
Packit 1e8aac
  GtkTreeView        *treeview;
Packit 1e8aac
  GtkListStore       *store;
Packit 1e8aac
  GtkTreeModelFilter *treemodelfilter;
Packit 1e8aac
  GtkSearchEntry     *searchentry;
Packit 1e8aac
  GtkEntryCompletion *entrycompletion;
Packit 1e8aac
  GtkScrolledWindow  *scrolledwindow;
Packit 1e8aac
Packit 1e8aac
  /* Needed for gtk_tree_view_column_set_cell_data_func() */
Packit 1e8aac
  GtkTreeViewColumn *column_icon;
Packit 1e8aac
  GtkCellRenderer   *icon_cell;
Packit 1e8aac
  GtkTreeViewColumn *column_adaptor;
Packit 1e8aac
  GtkCellRenderer   *adaptor_cell;
Packit 1e8aac
Packit 1e8aac
  /* Properties */
Packit 1e8aac
  _GladeAdaptorChooserWidgetFlags flags;
Packit 1e8aac
  GladeProject *project;
Packit 1e8aac
  gboolean show_group_title;
Packit 1e8aac
  gchar *search_text;
Packit 1e8aac
};
Packit 1e8aac
Packit 1e8aac
enum
Packit 1e8aac
{
Packit 1e8aac
  PROP_0,
Packit 1e8aac
Packit 1e8aac
  PROP_SHOW_FLAGS,
Packit 1e8aac
  PROP_PROJECT,
Packit 1e8aac
  PROP_SHOW_GROUP_TITLE
Packit 1e8aac
};
Packit 1e8aac
Packit 1e8aac
enum
Packit 1e8aac
{
Packit 1e8aac
  ADAPTOR_SELECTED,
Packit 1e8aac
Packit 1e8aac
  LAST_SIGNAL
Packit 1e8aac
};
Packit 1e8aac
Packit 1e8aac
static guint adaptor_chooser_signals[LAST_SIGNAL] = { 0 };
Packit 1e8aac
Packit 1e8aac
G_DEFINE_TYPE_WITH_PRIVATE (_GladeAdaptorChooserWidget, _glade_adaptor_chooser_widget, GTK_TYPE_BOX);
Packit 1e8aac
Packit 1e8aac
#define GET_PRIVATE(d) ((_GladeAdaptorChooserWidgetPrivate *) _glade_adaptor_chooser_widget_get_instance_private((_GladeAdaptorChooserWidget*)d))
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
_glade_adaptor_chooser_widget_init (_GladeAdaptorChooserWidget *chooser)
Packit 1e8aac
{
Packit 1e8aac
  gtk_widget_init_template (GTK_WIDGET (chooser));
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
_glade_adaptor_chooser_widget_finalize (GObject *object)
Packit 1e8aac
{
Packit 1e8aac
  _GladeAdaptorChooserWidgetPrivate *priv = GET_PRIVATE (object);
Packit 1e8aac
Packit 1e8aac
  g_clear_pointer (&priv->search_text, g_free);
Packit 1e8aac
  g_clear_object (&priv->project);
Packit 1e8aac
Packit 1e8aac
  G_OBJECT_CLASS (_glade_adaptor_chooser_widget_parent_class)->finalize (object);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
_glade_adaptor_chooser_widget_set_property (GObject      *object, 
Packit 1e8aac
                                            guint         prop_id,
Packit 1e8aac
                                            const GValue *value,
Packit 1e8aac
                                            GParamSpec   *pspec)
Packit 1e8aac
{ 
Packit 1e8aac
  _GladeAdaptorChooserWidgetPrivate *priv;
Packit 1e8aac
  
Packit 1e8aac
  g_return_if_fail (GLADE_IS_ADAPTOR_CHOOSER_WIDGET (object));
Packit 1e8aac
Packit 1e8aac
  priv = GET_PRIVATE (object);
Packit 1e8aac
Packit 1e8aac
  switch (prop_id)
Packit 1e8aac
    {
Packit 1e8aac
      case PROP_SHOW_FLAGS:
Packit 1e8aac
        priv->flags = g_value_get_flags (value);
Packit 1e8aac
      break;
Packit 1e8aac
      case PROP_PROJECT:
Packit 1e8aac
        _glade_adaptor_chooser_widget_set_project (GLADE_ADAPTOR_CHOOSER_WIDGET (object),
Packit 1e8aac
                                                   g_value_get_object (value));
Packit 1e8aac
      break;
Packit 1e8aac
      case PROP_SHOW_GROUP_TITLE:
Packit 1e8aac
        priv->show_group_title = g_value_get_boolean (value);
Packit 1e8aac
      break;
Packit 1e8aac
      default:
Packit 1e8aac
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Packit 1e8aac
      break;
Packit 1e8aac
    }
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
_glade_adaptor_chooser_widget_get_property (GObject    *object,
Packit 1e8aac
                                            guint       prop_id,
Packit 1e8aac
                                            GValue     *value,
Packit 1e8aac
                                            GParamSpec *pspec)
Packit 1e8aac
{
Packit 1e8aac
  _GladeAdaptorChooserWidgetPrivate *priv;
Packit 1e8aac
Packit 1e8aac
  g_return_if_fail (GLADE_IS_ADAPTOR_CHOOSER_WIDGET (object));
Packit 1e8aac
Packit 1e8aac
  priv = GET_PRIVATE (object);
Packit 1e8aac
Packit 1e8aac
  switch (prop_id)
Packit 1e8aac
    {
Packit 1e8aac
      case PROP_SHOW_FLAGS:
Packit 1e8aac
        g_value_set_flags (value, priv->flags);
Packit 1e8aac
      break;
Packit 1e8aac
      case PROP_PROJECT:
Packit 1e8aac
        g_value_set_object (value, priv->project);
Packit 1e8aac
      break;
Packit 1e8aac
      case PROP_SHOW_GROUP_TITLE:
Packit 1e8aac
        g_value_set_boolean (value, priv->show_group_title);
Packit 1e8aac
      break;
Packit 1e8aac
      default:
Packit 1e8aac
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Packit 1e8aac
      break;
Packit 1e8aac
    }
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static inline gchar *
Packit 1e8aac
normalize_name (const gchar *name)
Packit 1e8aac
{
Packit 1e8aac
  gchar *normalized_name = g_utf8_normalize (name, -1, G_NORMALIZE_DEFAULT);
Packit 1e8aac
  gchar *casefold_name = g_utf8_casefold (normalized_name, -1);
Packit 1e8aac
  g_free (normalized_name);
Packit 1e8aac
  return casefold_name;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static inline void
Packit 1e8aac
store_append_adaptor (GtkListStore *store, GladeWidgetAdaptor *adaptor)
Packit 1e8aac
{
Packit 1e8aac
  gchar *normalized_name = normalize_name (glade_widget_adaptor_get_name (adaptor));
Packit 1e8aac
Packit 1e8aac
  gtk_list_store_insert_with_values (store, NULL, -1,
Packit 1e8aac
                                     COLUMN_ADAPTOR, adaptor,
Packit 1e8aac
                                     COLUMN_NORMALIZED_NAME, normalized_name,
Packit 1e8aac
                                     COLUMN_NORMALIZED_NAME_LEN, strlen (normalized_name),
Packit 1e8aac
                                     -1);
Packit 1e8aac
  g_free (normalized_name);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
on_treeview_row_activated (GtkTreeView                *tree_view,
Packit 1e8aac
                           GtkTreePath                *path,
Packit 1e8aac
                           GtkTreeViewColumn          *column,
Packit 1e8aac
                           _GladeAdaptorChooserWidget *chooser)
Packit 1e8aac
{
Packit 1e8aac
  GtkTreeModel *model = gtk_tree_view_get_model (tree_view); 
Packit 1e8aac
  GtkTreeIter iter;
Packit 1e8aac
Packit 1e8aac
  if (gtk_tree_model_get_iter (model, &iter, path))
Packit 1e8aac
    {
Packit 1e8aac
      GladeWidgetAdaptor *adaptor;
Packit 1e8aac
Packit 1e8aac
      gtk_tree_model_get (model, &iter, COLUMN_ADAPTOR, &adaptor, -1);
Packit 1e8aac
Packit 1e8aac
      if (!adaptor)
Packit 1e8aac
        return;
Packit 1e8aac
Packit 1e8aac
      /* Emit selected signal */
Packit 1e8aac
      g_signal_emit (chooser, adaptor_chooser_signals[ADAPTOR_SELECTED], 0, adaptor);
Packit 1e8aac
Packit 1e8aac
      g_object_unref (adaptor);
Packit 1e8aac
    }
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
on_searchentry_search_changed (GtkEntry                   *entry,
Packit 1e8aac
                               _GladeAdaptorChooserWidget *chooser)
Packit 1e8aac
{
Packit 1e8aac
  _GladeAdaptorChooserWidgetPrivate *priv = GET_PRIVATE (chooser);
Packit 1e8aac
  const gchar *text = gtk_entry_get_text (entry);
Packit 1e8aac
Packit 1e8aac
  g_clear_pointer (&priv->search_text, g_free);
Packit 1e8aac
Packit 1e8aac
  if (g_utf8_strlen (text, -1))
Packit 1e8aac
    priv->search_text = normalize_name (text);
Packit 1e8aac
Packit 1e8aac
  gtk_tree_model_filter_refilter (priv->treemodelfilter);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
on_searchentry_activate (GtkEntry *entry, _GladeAdaptorChooserWidget *chooser)
Packit 1e8aac
{
Packit 1e8aac
  _GladeAdaptorChooserWidgetPrivate *priv = GET_PRIVATE (chooser);
Packit 1e8aac
  const gchar *text = gtk_entry_get_text (entry);
Packit 1e8aac
  GladeWidgetAdaptor *adaptor;
Packit 1e8aac
Packit 1e8aac
  /* try to find an adaptor by name */
Packit 1e8aac
  if (!(adaptor = glade_widget_adaptor_get_by_name (text)))
Packit 1e8aac
    {
Packit 1e8aac
      GtkTreeModel *model = GTK_TREE_MODEL (priv->treemodelfilter);
Packit 1e8aac
      gchar *normalized_name = normalize_name (text);
Packit 1e8aac
      GtkTreeIter iter;
Packit 1e8aac
      gboolean valid;
Packit 1e8aac
      gint count = 0;
Packit 1e8aac
Packit 1e8aac
      valid = gtk_tree_model_get_iter_first (model, &iter);
Packit 1e8aac
Packit 1e8aac
      /* we could not find it check if we can find it by normalized name */
Packit 1e8aac
      while (valid)
Packit 1e8aac
        {
Packit 1e8aac
          gchar *name;
Packit 1e8aac
Packit 1e8aac
          gtk_tree_model_get (model, &iter, COLUMN_NORMALIZED_NAME, &name, -1);
Packit 1e8aac
Packit 1e8aac
          if (g_strcmp0 (name, normalized_name) == 0)
Packit 1e8aac
            {
Packit 1e8aac
              gtk_tree_model_get (model, &iter, COLUMN_ADAPTOR, &adaptor, -1);
Packit 1e8aac
              g_free (name);
Packit 1e8aac
              break;
Packit 1e8aac
            }
Packit 1e8aac
Packit 1e8aac
          valid = gtk_tree_model_iter_next (model, &iter);
Packit 1e8aac
          g_free (name);
Packit 1e8aac
          count++;
Packit 1e8aac
        }
Packit 1e8aac
Packit 1e8aac
      /* if not, and there is only one row, then we select that one */
Packit 1e8aac
      if (!adaptor && count == 1 && gtk_tree_model_get_iter_first (model, &iter))
Packit 1e8aac
        gtk_tree_model_get (model, &iter, COLUMN_ADAPTOR, &adaptor, -1);
Packit 1e8aac
Packit 1e8aac
      g_free (normalized_name);
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  if (adaptor)
Packit 1e8aac
    g_signal_emit (chooser, adaptor_chooser_signals[ADAPTOR_SELECTED], 0, adaptor);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static gboolean
Packit 1e8aac
chooser_match_func (_GladeAdaptorChooserWidget *chooser,
Packit 1e8aac
                    GtkTreeModel               *model,
Packit 1e8aac
                    const gchar                *key,
Packit 1e8aac
                    GtkTreeIter                *iter)
Packit 1e8aac
{
Packit 1e8aac
  gboolean visible;
Packit 1e8aac
  gint name_len;
Packit 1e8aac
  gchar *name;
Packit 1e8aac
Packit 1e8aac
  if (!key || *key == '\0')
Packit 1e8aac
    return TRUE;
Packit 1e8aac
Packit 1e8aac
  gtk_tree_model_get (model, iter,
Packit 1e8aac
                      COLUMN_NORMALIZED_NAME, &name,
Packit 1e8aac
                      COLUMN_NORMALIZED_NAME_LEN, &name_len,
Packit 1e8aac
                      -1);
Packit 1e8aac
  if (!name)
Packit 1e8aac
    return FALSE;
Packit 1e8aac
Packit 1e8aac
  visible = (g_strstr_len (name, name_len, key) != NULL);
Packit 1e8aac
  g_free (name);
Packit 1e8aac
Packit 1e8aac
  return visible;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static gboolean
Packit 1e8aac
treemodelfilter_visible_func (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
Packit 1e8aac
{
Packit 1e8aac
  _GladeAdaptorChooserWidgetPrivate *priv = GET_PRIVATE (data);
Packit 1e8aac
  GladeWidgetAdaptor *adaptor = NULL;
Packit 1e8aac
  gboolean visible = TRUE;
Packit 1e8aac
Packit 1e8aac
  gtk_tree_model_get (model, iter, COLUMN_ADAPTOR, &adaptor, -1);
Packit 1e8aac
Packit 1e8aac
  if (!adaptor)
Packit 1e8aac
    return priv->show_group_title && !priv->search_text;
Packit 1e8aac
Packit 1e8aac
  /* Skip classes not available in project target version */
Packit 1e8aac
  if (priv->project)
Packit 1e8aac
    {
Packit 1e8aac
      const gchar *catalog = NULL;
Packit 1e8aac
      gint major, minor;
Packit 1e8aac
Packit 1e8aac
      catalog = glade_widget_adaptor_get_catalog (adaptor);
Packit 1e8aac
      glade_project_get_target_version (priv->project, catalog, &major, &minor);
Packit 1e8aac
Packit 1e8aac
      visible = GWA_VERSION_CHECK (adaptor, major, minor);
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  if (visible && priv->flags)
Packit 1e8aac
    {
Packit 1e8aac
      GType type = glade_widget_adaptor_get_object_type (adaptor);
Packit 1e8aac
      _GladeAdaptorChooserWidgetFlags flags = priv->flags;
Packit 1e8aac
Packit 1e8aac
       /* Skip adaptors according to flags */
Packit 1e8aac
       if (flags & GLADE_ADAPTOR_CHOOSER_WIDGET_SKIP_DEPRECATED && GWA_DEPRECATED (adaptor))
Packit 1e8aac
         visible = FALSE;
Packit 1e8aac
       else if (flags & GLADE_ADAPTOR_CHOOSER_WIDGET_SKIP_TOPLEVEL && GWA_IS_TOPLEVEL (adaptor))
Packit 1e8aac
         visible = FALSE;
Packit 1e8aac
       else if (flags & GLADE_ADAPTOR_CHOOSER_WIDGET_WIDGET && !g_type_is_a (type, GTK_TYPE_WIDGET))
Packit 1e8aac
         visible = FALSE;
Packit 1e8aac
       else if (flags & GLADE_ADAPTOR_CHOOSER_WIDGET_TOPLEVEL && !GWA_IS_TOPLEVEL (adaptor))
Packit 1e8aac
         visible = FALSE;
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  if (visible && priv->search_text)
Packit 1e8aac
    visible = chooser_match_func (data, model, priv->search_text, iter);
Packit 1e8aac
Packit 1e8aac
  g_clear_object (&adaptor);
Packit 1e8aac
Packit 1e8aac
  return visible;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static gboolean
Packit 1e8aac
entrycompletion_match_func (GtkEntryCompletion *entry, const gchar *key, GtkTreeIter *iter, gpointer data)
Packit 1e8aac
{
Packit 1e8aac
  return chooser_match_func (data, gtk_entry_completion_get_model (entry), key, iter);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
adaptor_icon_cell_data_func (GtkTreeViewColumn *tree_column,
Packit 1e8aac
                             GtkCellRenderer   *cell,
Packit 1e8aac
                             GtkTreeModel      *tree_model,
Packit 1e8aac
                             GtkTreeIter       *iter,
Packit 1e8aac
                             gpointer           data)
Packit 1e8aac
{
Packit 1e8aac
  GladeWidgetAdaptor *adaptor;
Packit 1e8aac
  gtk_tree_model_get (tree_model, iter, COLUMN_ADAPTOR, &adaptor, -1);
Packit 1e8aac
Packit 1e8aac
  if (adaptor)
Packit 1e8aac
    g_object_set (cell, "sensitive", TRUE, "icon-name", glade_widget_adaptor_get_icon_name (adaptor), NULL);
Packit 1e8aac
  else
Packit 1e8aac
    g_object_set (cell, "sensitive", FALSE, "icon-name", "go-down-symbolic", NULL);
Packit 1e8aac
Packit 1e8aac
  g_clear_object (&adaptor);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
adaptor_text_cell_data_func (GtkTreeViewColumn *tree_column,
Packit 1e8aac
                             GtkCellRenderer   *cell,
Packit 1e8aac
                             GtkTreeModel      *tree_model,
Packit 1e8aac
                             GtkTreeIter       *iter,
Packit 1e8aac
                             gpointer           data)
Packit 1e8aac
{
Packit 1e8aac
  GladeWidgetAdaptor *adaptor;
Packit 1e8aac
  gchar *group;
Packit 1e8aac
Packit 1e8aac
  gtk_tree_model_get (tree_model, iter,
Packit 1e8aac
                      COLUMN_ADAPTOR, &adaptor,
Packit 1e8aac
                      COLUMN_GROUP, &group,
Packit 1e8aac
                      -1);
Packit 1e8aac
  if (adaptor)
Packit 1e8aac
    g_object_set (cell,
Packit 1e8aac
                  "sensitive", TRUE,
Packit 1e8aac
                  "text", glade_widget_adaptor_get_name (adaptor),
Packit 1e8aac
                  "style", PANGO_STYLE_NORMAL,
Packit 1e8aac
                  NULL);
Packit 1e8aac
  else
Packit 1e8aac
    g_object_set (cell,
Packit 1e8aac
                  "sensitive", FALSE,
Packit 1e8aac
                  "text", group,
Packit 1e8aac
                  "style", PANGO_STYLE_ITALIC,
Packit 1e8aac
                  NULL);
Packit 1e8aac
Packit 1e8aac
  g_clear_object (&adaptor);
Packit 1e8aac
  g_free (group);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
glade_adaptor_chooser_widget_drag_begin (GtkWidget      *widget,
Packit 1e8aac
                                         GdkDragContext *context,
Packit 1e8aac
                                         gpointer        data)
Packit 1e8aac
{
Packit 1e8aac
  GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
Packit 1e8aac
  GtkTreeModel *model;
Packit 1e8aac
  GtkTreeIter iter;
Packit 1e8aac
Packit 1e8aac
  if (gtk_tree_selection_get_selected (selection, &model, &iter))
Packit 1e8aac
    {
Packit 1e8aac
      GladeWidgetAdaptor *adaptor;
Packit 1e8aac
      gtk_tree_model_get (model, &iter, COLUMN_ADAPTOR, &adaptor, -1);
Packit 1e8aac
      _glade_dnd_set_icon_widget (context,
Packit 1e8aac
                                  glade_widget_adaptor_get_icon_name (adaptor),
Packit 1e8aac
                                  glade_widget_adaptor_get_name (adaptor));
Packit 1e8aac
    }
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
glade_adaptor_chooser_widget_drag_data_get (GtkWidget          *widget,
Packit 1e8aac
                                            GdkDragContext     *context,
Packit 1e8aac
                                            GtkSelectionData   *data,
Packit 1e8aac
                                            guint               info,
Packit 1e8aac
                                            guint               time,
Packit 1e8aac
                                            gpointer            userdata)
Packit 1e8aac
{
Packit 1e8aac
  GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
Packit 1e8aac
  GtkTreeModel *model;
Packit 1e8aac
  GtkTreeIter iter;
Packit 1e8aac
Packit 1e8aac
  if (gtk_tree_selection_get_selected (selection, &model, &iter))
Packit 1e8aac
    {
Packit 1e8aac
      GladeWidgetAdaptor *adaptor;
Packit 1e8aac
      gtk_tree_model_get (model, &iter, COLUMN_ADAPTOR, &adaptor, -1);
Packit 1e8aac
      _glade_dnd_set_data (data, G_OBJECT (adaptor));
Packit 1e8aac
    }
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
_glade_adaptor_chooser_widget_constructed (GObject *object)
Packit 1e8aac
{
Packit 1e8aac
  _GladeAdaptorChooserWidget *chooser = GLADE_ADAPTOR_CHOOSER_WIDGET (object);
Packit 1e8aac
  _GladeAdaptorChooserWidgetPrivate *priv = GET_PRIVATE (chooser);
Packit 1e8aac
Packit 1e8aac
  /* Set cell data function: this save us from alocating name and icon name for each adaptor. */
Packit 1e8aac
  gtk_tree_view_column_set_cell_data_func (priv->column_icon,
Packit 1e8aac
                                           priv->icon_cell,
Packit 1e8aac
                                           adaptor_icon_cell_data_func,
Packit 1e8aac
                                           NULL, NULL);
Packit 1e8aac
  gtk_tree_view_column_set_cell_data_func (priv->column_adaptor,
Packit 1e8aac
                                           priv->adaptor_cell,
Packit 1e8aac
                                           adaptor_text_cell_data_func,
Packit 1e8aac
                                           NULL, NULL);
Packit 1e8aac
  /* Set tree model filter function */
Packit 1e8aac
  gtk_tree_model_filter_set_visible_func (priv->treemodelfilter,
Packit 1e8aac
                                          treemodelfilter_visible_func,
Packit 1e8aac
                                          chooser, NULL);
Packit 1e8aac
  /* Set completion match function */
Packit 1e8aac
  gtk_entry_completion_set_match_func (priv->entrycompletion,
Packit 1e8aac
                                       entrycompletion_match_func,
Packit 1e8aac
                                       chooser, NULL);
Packit 1e8aac
  /* Enable Drag & Drop */
Packit 1e8aac
  gtk_tree_view_enable_model_drag_source (priv->treeview, GDK_BUTTON1_MASK,
Packit 1e8aac
                                          _glade_dnd_get_target (), 1, 0);
Packit 1e8aac
  g_signal_connect_after (priv->treeview, "drag-begin",
Packit 1e8aac
                          G_CALLBACK (glade_adaptor_chooser_widget_drag_begin),
Packit 1e8aac
                          NULL);
Packit 1e8aac
  g_signal_connect (priv->treeview, "drag-data-get",
Packit 1e8aac
                    G_CALLBACK (glade_adaptor_chooser_widget_drag_data_get),
Packit 1e8aac
                    NULL);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
_glade_adaptor_chooser_widget_map (GtkWidget *widget)
Packit 1e8aac
{
Packit 1e8aac
  GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
Packit 1e8aac
Packit 1e8aac
  if (toplevel)
Packit 1e8aac
    {
Packit 1e8aac
      _GladeAdaptorChooserWidgetPrivate *priv = GET_PRIVATE (widget);
Packit 1e8aac
      gint height = gtk_widget_get_allocated_height (toplevel) - 100;
Packit 1e8aac
Packit 1e8aac
      if (height > 512)
Packit 1e8aac
        height = height * 0.75;
Packit 1e8aac
Packit 1e8aac
      gtk_scrolled_window_set_max_content_height (priv->scrolledwindow, height);
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  GTK_WIDGET_CLASS (_glade_adaptor_chooser_widget_parent_class)->map (widget);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static GType
Packit 1e8aac
_glade_adaptor_chooser_widget_flags_get_type (void)
Packit 1e8aac
{
Packit 1e8aac
    static GType etype = 0;
Packit 1e8aac
    if (G_UNLIKELY(etype == 0)) {
Packit 1e8aac
        static const GFlagsValue values[] = {
Packit 1e8aac
            { GLADE_ADAPTOR_CHOOSER_WIDGET_WIDGET, "GLADE_ADAPTOR_CHOOSER_WIDGET_WIDGET", "widget" },
Packit 1e8aac
            { GLADE_ADAPTOR_CHOOSER_WIDGET_TOPLEVEL, "GLADE_ADAPTOR_CHOOSER_WIDGET_TOPLEVEL", "toplevel" },
Packit 1e8aac
            { GLADE_ADAPTOR_CHOOSER_WIDGET_SKIP_TOPLEVEL, "GLADE_ADAPTOR_CHOOSER_WIDGET_SKIP_TOPLEVEL", "skip-toplevel" },
Packit 1e8aac
            { GLADE_ADAPTOR_CHOOSER_WIDGET_SKIP_DEPRECATED, "GLADE_ADAPTOR_CHOOSER_WIDGET_SKIP_DEPRECATED", "skip-deprecated" },
Packit 1e8aac
            { 0, NULL, NULL }
Packit 1e8aac
        };
Packit 1e8aac
        etype = g_flags_register_static (g_intern_static_string ("_GladeAdaptorChooserWidgetFlag"), values);
Packit 1e8aac
    }
Packit 1e8aac
    return etype;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
_glade_adaptor_chooser_widget_class_init (_GladeAdaptorChooserWidgetClass *klass)
Packit 1e8aac
{
Packit 1e8aac
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
Packit 1e8aac
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
Packit 1e8aac
Packit 1e8aac
  object_class->finalize = _glade_adaptor_chooser_widget_finalize;
Packit 1e8aac
  object_class->set_property = _glade_adaptor_chooser_widget_set_property;
Packit 1e8aac
  object_class->get_property = _glade_adaptor_chooser_widget_get_property;
Packit 1e8aac
  object_class->constructed = _glade_adaptor_chooser_widget_constructed;
Packit 1e8aac
Packit 1e8aac
  widget_class->map = _glade_adaptor_chooser_widget_map;
Packit 1e8aac
Packit 1e8aac
  g_object_class_install_property (object_class,
Packit 1e8aac
                                   PROP_SHOW_FLAGS,
Packit 1e8aac
                                   g_param_spec_flags ("show-flags",
Packit 1e8aac
                                                       "Show flags",
Packit 1e8aac
                                                       "Widget adaptors show flags",
Packit 1e8aac
                                                       _glade_adaptor_chooser_widget_flags_get_type (),
Packit 1e8aac
                                                       0,
Packit 1e8aac
                                                       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
Packit 1e8aac
  g_object_class_install_property (object_class,
Packit 1e8aac
                                   PROP_SHOW_GROUP_TITLE,
Packit 1e8aac
                                   g_param_spec_boolean ("show-group-title",
Packit 1e8aac
                                                         "Show group title",
Packit 1e8aac
                                                         "Whether to show the group title",
Packit 1e8aac
                                                         FALSE,
Packit 1e8aac
                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
Packit 1e8aac
  g_object_class_install_property (object_class,
Packit 1e8aac
                                   PROP_PROJECT,
Packit 1e8aac
                                   g_param_spec_object ("project",
Packit 1e8aac
                                                        "Glade Project",
Packit 1e8aac
                                                        "If set, use project target version to skip unsupported classes",
Packit 1e8aac
                                                        GLADE_TYPE_PROJECT,
Packit 1e8aac
                                                        G_PARAM_READWRITE));
Packit 1e8aac
Packit 1e8aac
  adaptor_chooser_signals[ADAPTOR_SELECTED] =
Packit 1e8aac
    g_signal_new ("adaptor-selected", G_OBJECT_CLASS_TYPE (klass), 0, 0,
Packit 1e8aac
                  NULL, NULL, NULL,
Packit 1e8aac
                  G_TYPE_NONE, 1,
Packit 1e8aac
                  GLADE_TYPE_WIDGET_ADAPTOR);
Packit 1e8aac
Packit 1e8aac
  gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/gladeui/glade-adaptor-chooser-widget.ui");
Packit 1e8aac
  gtk_widget_class_bind_template_child_private (widget_class, _GladeAdaptorChooserWidget, treeview);
Packit 1e8aac
  gtk_widget_class_bind_template_child_private (widget_class, _GladeAdaptorChooserWidget, store);
Packit 1e8aac
  gtk_widget_class_bind_template_child_private (widget_class, _GladeAdaptorChooserWidget, treemodelfilter);
Packit 1e8aac
  gtk_widget_class_bind_template_child_private (widget_class, _GladeAdaptorChooserWidget, searchentry);
Packit 1e8aac
  gtk_widget_class_bind_template_child_private (widget_class, _GladeAdaptorChooserWidget, entrycompletion);
Packit 1e8aac
  gtk_widget_class_bind_template_child_private (widget_class, _GladeAdaptorChooserWidget, column_icon);
Packit 1e8aac
  gtk_widget_class_bind_template_child_private (widget_class, _GladeAdaptorChooserWidget, icon_cell);
Packit 1e8aac
  gtk_widget_class_bind_template_child_private (widget_class, _GladeAdaptorChooserWidget, column_adaptor);
Packit 1e8aac
  gtk_widget_class_bind_template_child_private (widget_class, _GladeAdaptorChooserWidget, adaptor_cell);
Packit 1e8aac
  gtk_widget_class_bind_template_child_private (widget_class, _GladeAdaptorChooserWidget, scrolledwindow);
Packit 1e8aac
  gtk_widget_class_bind_template_callback (widget_class, on_treeview_row_activated);
Packit 1e8aac
  gtk_widget_class_bind_template_callback (widget_class, on_searchentry_search_changed);
Packit 1e8aac
  gtk_widget_class_bind_template_callback (widget_class, on_searchentry_activate);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
GtkWidget *
Packit 1e8aac
_glade_adaptor_chooser_widget_new (_GladeAdaptorChooserWidgetFlags flags, GladeProject *project)
Packit 1e8aac
{
Packit 1e8aac
  return GTK_WIDGET (g_object_new (GLADE_TYPE_ADAPTOR_CHOOSER_WIDGET,
Packit 1e8aac
                                   "show-flags", flags,
Packit 1e8aac
                                   "project", project,
Packit 1e8aac
                                   NULL));
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
void
Packit 1e8aac
_glade_adaptor_chooser_widget_set_project (_GladeAdaptorChooserWidget *chooser,
Packit 1e8aac
                                           GladeProject               *project)
Packit 1e8aac
{
Packit 1e8aac
  _GladeAdaptorChooserWidgetPrivate *priv;
Packit 1e8aac
Packit 1e8aac
  g_return_if_fail (GLADE_IS_ADAPTOR_CHOOSER_WIDGET (chooser));
Packit 1e8aac
  priv = GET_PRIVATE (chooser);
Packit 1e8aac
Packit 1e8aac
  g_clear_object (&priv->project);
Packit 1e8aac
Packit 1e8aac
  if (project)
Packit 1e8aac
    priv->project = g_object_ref (project);
Packit 1e8aac
Packit 1e8aac
  gtk_tree_model_filter_refilter (priv->treemodelfilter);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
void
Packit 1e8aac
_glade_adaptor_chooser_widget_populate (_GladeAdaptorChooserWidget *chooser)
Packit 1e8aac
{
Packit 1e8aac
  GList *l;
Packit 1e8aac
Packit 1e8aac
  for (l = glade_app_get_catalogs (); l; l = g_list_next (l))
Packit 1e8aac
    _glade_adaptor_chooser_widget_add_catalog (chooser, l->data);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
void
Packit 1e8aac
_glade_adaptor_chooser_widget_add_catalog (_GladeAdaptorChooserWidget *chooser,
Packit 1e8aac
                                           GladeCatalog               *catalog)
Packit 1e8aac
{
Packit 1e8aac
  GList *groups;
Packit 1e8aac
Packit 1e8aac
  g_return_if_fail (GLADE_IS_ADAPTOR_CHOOSER_WIDGET (chooser));
Packit 1e8aac
Packit 1e8aac
  for (groups = glade_catalog_get_widget_groups (catalog); groups;
Packit 1e8aac
       groups = g_list_next (groups))
Packit 1e8aac
    _glade_adaptor_chooser_widget_add_group (chooser, groups->data);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
void
Packit 1e8aac
_glade_adaptor_chooser_widget_add_group (_GladeAdaptorChooserWidget *chooser,
Packit 1e8aac
                                         GladeWidgetGroup           *group)
Packit 1e8aac
{
Packit 1e8aac
  _GladeAdaptorChooserWidgetPrivate *priv;
Packit 1e8aac
  const GList *adaptors;
Packit 1e8aac
Packit 1e8aac
  g_return_if_fail (GLADE_IS_ADAPTOR_CHOOSER_WIDGET (chooser));
Packit 1e8aac
  priv = GET_PRIVATE (chooser);
Packit 1e8aac
Packit 1e8aac
  if (priv->show_group_title)
Packit 1e8aac
    gtk_list_store_insert_with_values (priv->store, NULL, -1,
Packit 1e8aac
                                       COLUMN_GROUP, glade_widget_group_get_title (group),
Packit 1e8aac
                                       -1);
Packit 1e8aac
Packit 1e8aac
  for (adaptors = glade_widget_group_get_adaptors (group); adaptors;
Packit 1e8aac
       adaptors = g_list_next (adaptors))
Packit 1e8aac
    store_append_adaptor (priv->store, adaptors->data);
Packit 1e8aac
}
Packit 1e8aac