Blame gladeui/glade-adaptor-chooser.c

Packit 1e8aac
/*
Packit 1e8aac
 * glade-adaptor-chooser.c
Packit 1e8aac
 *
Packit 1e8aac
 * Copyright (C) 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-adaptor-chooser-widget.h"
Packit 1e8aac
#include "glade-adaptor-chooser.h"
Packit 1e8aac
#include "glade-app.h"
Packit 1e8aac
Packit 1e8aac
typedef struct
Packit 1e8aac
{
Packit 1e8aac
  GladeProject *project;
Packit 1e8aac
Packit 1e8aac
  GtkWidget *gtk_button_box;
Packit 1e8aac
  GtkWidget *extra_button;
Packit 1e8aac
  GtkWidget *others_button;
Packit 1e8aac
  GtkImage *class_image;
Packit 1e8aac
  GtkLabel *class_label;
Packit 1e8aac
  GtkWidget *all_button;
Packit 1e8aac
Packit 1e8aac
  GList *choosers;
Packit 1e8aac
} GladeAdaptorChooserPrivate;
Packit 1e8aac
Packit 1e8aac
struct _GladeAdaptorChooser
Packit 1e8aac
{
Packit 1e8aac
  GtkBox parent_instance;
Packit 1e8aac
};
Packit 1e8aac
Packit 1e8aac
enum
Packit 1e8aac
{
Packit 1e8aac
  PROP_0,
Packit 1e8aac
  PROP_PROJECT,
Packit 1e8aac
Packit 1e8aac
  N_PROPERTIES
Packit 1e8aac
};
Packit 1e8aac
Packit 1e8aac
static GParamSpec *properties[N_PROPERTIES];
Packit 1e8aac
Packit 1e8aac
G_DEFINE_TYPE_WITH_PRIVATE (GladeAdaptorChooser,
Packit 1e8aac
                            glade_adaptor_chooser,
Packit 1e8aac
                            GTK_TYPE_BOX);
Packit 1e8aac
Packit 1e8aac
#define GET_PRIVATE(d) ((GladeAdaptorChooserPrivate *) glade_adaptor_chooser_get_instance_private((GladeAdaptorChooser*)d))
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
glade_adaptor_chooser_init (GladeAdaptorChooser *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_finalize (GObject *object)
Packit 1e8aac
{
Packit 1e8aac
  GladeAdaptorChooserPrivate *priv = GET_PRIVATE (object);
Packit 1e8aac
Packit 1e8aac
  g_list_free (priv->choosers);
Packit 1e8aac
Packit 1e8aac
  G_OBJECT_CLASS (glade_adaptor_chooser_parent_class)->finalize (object);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
glade_adaptor_chooser_set_property (GObject      *object,
Packit 1e8aac
                                    guint         prop_id,
Packit 1e8aac
                                    const GValue *value,
Packit 1e8aac
                                    GParamSpec   *pspec)
Packit 1e8aac
{
Packit 1e8aac
  g_return_if_fail (GLADE_IS_ADAPTOR_CHOOSER (object));
Packit 1e8aac
Packit 1e8aac
  switch (prop_id)
Packit 1e8aac
    {
Packit 1e8aac
      case PROP_PROJECT:
Packit 1e8aac
        glade_adaptor_chooser_set_project (GLADE_ADAPTOR_CHOOSER (object),
Packit 1e8aac
                                               g_value_get_object (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_get_property (GObject    *object,
Packit 1e8aac
                                    guint       prop_id,
Packit 1e8aac
                                    GValue     *value,
Packit 1e8aac
                                    GParamSpec *pspec)
Packit 1e8aac
{
Packit 1e8aac
  GladeAdaptorChooserPrivate *priv;
Packit 1e8aac
Packit 1e8aac
  g_return_if_fail (GLADE_IS_ADAPTOR_CHOOSER (object));
Packit 1e8aac
  priv = GET_PRIVATE (object);
Packit 1e8aac
Packit 1e8aac
  switch (prop_id)
Packit 1e8aac
    {
Packit 1e8aac
      case PROP_PROJECT:
Packit 1e8aac
        g_value_set_object (value, priv->project);
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
on_adaptor_selected (GtkWidget           *widget,
Packit 1e8aac
                     GladeWidgetAdaptor  *adaptor,
Packit 1e8aac
                     GladeAdaptorChooser *chooser)
Packit 1e8aac
{
Packit 1e8aac
  GladeAdaptorChooserPrivate *priv = GET_PRIVATE (chooser);
Packit 1e8aac
Packit 1e8aac
  /* Auto-create toplevel types */
Packit 1e8aac
  if (GWA_IS_TOPLEVEL (adaptor))
Packit 1e8aac
    {
Packit 1e8aac
      glade_command_create (adaptor, NULL, NULL, priv->project);
Packit 1e8aac
    }
Packit 1e8aac
  else
Packit 1e8aac
    {
Packit 1e8aac
      glade_project_set_add_item (priv->project, adaptor);
Packit 1e8aac
      glade_project_set_pointer_mode (priv->project, GLADE_POINTER_ADD_WIDGET);
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_parent (widget)));
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
glade_adaptor_chooser_button_add_chooser (GtkWidget *button, GtkWidget *chooser)
Packit 1e8aac
{
Packit 1e8aac
  GtkWidget *popover;
Packit 1e8aac
Packit 1e8aac
  popover = gtk_popover_new (button);
Packit 1e8aac
  gtk_container_add (GTK_CONTAINER (popover), chooser);
Packit 1e8aac
  gtk_widget_show (chooser);
Packit 1e8aac
Packit 1e8aac
  gtk_menu_button_set_popover (GTK_MENU_BUTTON (button), popover);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static GtkWidget *
Packit 1e8aac
glade_adaptor_chooser_add_chooser (GladeAdaptorChooser *chooser,
Packit 1e8aac
                                   gboolean             show_group_title)
Packit 1e8aac
{
Packit 1e8aac
  GladeAdaptorChooserPrivate *priv = GET_PRIVATE (chooser);
Packit 1e8aac
  GtkWidget *chooser_widget = g_object_new (GLADE_TYPE_ADAPTOR_CHOOSER_WIDGET,
Packit 1e8aac
                                            "show-group-title", show_group_title,
Packit 1e8aac
                                            NULL);
Packit 1e8aac
Packit 1e8aac
  priv->choosers = g_list_prepend (priv->choosers, chooser_widget);
Packit 1e8aac
  g_signal_connect (chooser_widget, "adaptor-selected",
Packit 1e8aac
                    G_CALLBACK (on_adaptor_selected),
Packit 1e8aac
                    chooser);
Packit 1e8aac
Packit 1e8aac
  return chooser_widget;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
button_box_populate_from_catalog (GladeAdaptorChooser *chooser,
Packit 1e8aac
                                  GladeCatalog        *catalog)
Packit 1e8aac
{
Packit 1e8aac
  GladeAdaptorChooserPrivate *priv = GET_PRIVATE (chooser);
Packit 1e8aac
  GtkWidget *extra_chooser = NULL;
Packit 1e8aac
  GList *groups;
Packit 1e8aac
    
Packit 1e8aac
  groups = glade_catalog_get_widget_groups (catalog);
Packit 1e8aac
  gtk_box_set_homogeneous (GTK_BOX (priv->gtk_button_box), FALSE);
Packit 1e8aac
          
Packit 1e8aac
  for (; groups; groups = g_list_next (groups))
Packit 1e8aac
    {
Packit 1e8aac
      GladeWidgetGroup *group = GLADE_WIDGET_GROUP (groups->data);
Packit 1e8aac
Packit 1e8aac
      if (!glade_widget_group_get_adaptors (group))
Packit 1e8aac
        continue;
Packit 1e8aac
Packit 1e8aac
      if (glade_widget_group_get_expanded (group))
Packit 1e8aac
        {
Packit 1e8aac
          GtkWidget *button, *chooser_widget;
Packit 1e8aac
          
Packit 1e8aac
          chooser_widget = glade_adaptor_chooser_add_chooser (chooser, FALSE);
Packit 1e8aac
          button = gtk_menu_button_new ();
Packit 1e8aac
          gtk_button_set_label (GTK_BUTTON (button), glade_widget_group_get_title (group));
Packit 1e8aac
          glade_adaptor_chooser_button_add_chooser (button, chooser_widget);
Packit 1e8aac
          _glade_adaptor_chooser_widget_add_group (GLADE_ADAPTOR_CHOOSER_WIDGET (chooser_widget), group);
Packit 1e8aac
          gtk_box_pack_start (GTK_BOX (priv->gtk_button_box), button, FALSE, FALSE, 0);
Packit 1e8aac
          gtk_widget_show (button);
Packit 1e8aac
        }
Packit 1e8aac
      else
Packit 1e8aac
        {
Packit 1e8aac
          if (!extra_chooser)
Packit 1e8aac
            {
Packit 1e8aac
              extra_chooser = glade_adaptor_chooser_add_chooser (chooser, TRUE);
Packit 1e8aac
              glade_adaptor_chooser_button_add_chooser (priv->extra_button, extra_chooser);
Packit 1e8aac
              gtk_widget_show (priv->extra_button);
Packit 1e8aac
            }
Packit 1e8aac
Packit 1e8aac
          _glade_adaptor_chooser_widget_add_group (GLADE_ADAPTOR_CHOOSER_WIDGET (extra_chooser), group);
Packit 1e8aac
        }
Packit 1e8aac
    }
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
glade_adaptor_chooser_constructed (GObject *object)
Packit 1e8aac
{
Packit 1e8aac
  GladeAdaptorChooser *chooser = GLADE_ADAPTOR_CHOOSER (object);
Packit 1e8aac
  GladeAdaptorChooserPrivate *priv = GET_PRIVATE (object);
Packit 1e8aac
  GtkWidget *others_chooser, *all_chooser;
Packit 1e8aac
  GladeCatalog *gtk_catalog;
Packit 1e8aac
  GList *l;
Packit 1e8aac
Packit 1e8aac
  /* GTK+ catalog goes first subdivided by group */
Packit 1e8aac
  gtk_catalog = glade_app_get_catalog ("gtk+");
Packit 1e8aac
  button_box_populate_from_catalog (chooser, gtk_catalog);
Packit 1e8aac
Packit 1e8aac
  others_chooser = glade_adaptor_chooser_add_chooser (chooser, TRUE);
Packit 1e8aac
  all_chooser = glade_adaptor_chooser_add_chooser (chooser, TRUE);
Packit 1e8aac
  glade_adaptor_chooser_button_add_chooser (priv->others_button, others_chooser);
Packit 1e8aac
  glade_adaptor_chooser_button_add_chooser (priv->all_button, all_chooser);
Packit 1e8aac
Packit 1e8aac
  /* then the rest */
Packit 1e8aac
  for (l = glade_app_get_catalogs (); l; l = g_list_next (l))
Packit 1e8aac
    {
Packit 1e8aac
      GladeCatalog *catalog = l->data;
Packit 1e8aac
Packit 1e8aac
      _glade_adaptor_chooser_widget_add_catalog (GLADE_ADAPTOR_CHOOSER_WIDGET (all_chooser), catalog);
Packit 1e8aac
Packit 1e8aac
      if (catalog != gtk_catalog)
Packit 1e8aac
        _glade_adaptor_chooser_widget_add_catalog (GLADE_ADAPTOR_CHOOSER_WIDGET (others_chooser), catalog);
Packit 1e8aac
    }
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
glade_adaptor_chooser_class_init (GladeAdaptorChooserClass *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_finalize;
Packit 1e8aac
  object_class->constructed = glade_adaptor_chooser_constructed;
Packit 1e8aac
  object_class->set_property = glade_adaptor_chooser_set_property;
Packit 1e8aac
  object_class->get_property = glade_adaptor_chooser_get_property;
Packit 1e8aac
Packit 1e8aac
  /* Properties */
Packit 1e8aac
  properties[PROP_PROJECT] =
Packit 1e8aac
    g_param_spec_object ("project", "Project",
Packit 1e8aac
                         "This adaptor chooser's current project",
Packit 1e8aac
                         GLADE_TYPE_PROJECT,
Packit 1e8aac
                         G_PARAM_READWRITE);
Packit 1e8aac
Packit 1e8aac
  g_object_class_install_properties (object_class, N_PROPERTIES, properties);
Packit 1e8aac
  
Packit 1e8aac
  gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/gladeui/glade-adaptor-chooser.ui");
Packit 1e8aac
  gtk_widget_class_bind_template_child_private (widget_class, GladeAdaptorChooser, gtk_button_box);
Packit 1e8aac
  gtk_widget_class_bind_template_child_private (widget_class, GladeAdaptorChooser, extra_button);
Packit 1e8aac
  gtk_widget_class_bind_template_child_private (widget_class, GladeAdaptorChooser, others_button);
Packit 1e8aac
  gtk_widget_class_bind_template_child_private (widget_class, GladeAdaptorChooser, class_image);
Packit 1e8aac
  gtk_widget_class_bind_template_child_private (widget_class, GladeAdaptorChooser, class_label);
Packit 1e8aac
  gtk_widget_class_bind_template_child_private (widget_class, GladeAdaptorChooser, all_button);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
/* Public API */
Packit 1e8aac
Packit 1e8aac
GtkWidget *
Packit 1e8aac
glade_adaptor_chooser_new ()
Packit 1e8aac
{
Packit 1e8aac
  return (GtkWidget*) g_object_new (GLADE_TYPE_ADAPTOR_CHOOSER, NULL);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
glade_adaptor_chooser_update_adaptor (GladeAdaptorChooser *chooser)
Packit 1e8aac
{
Packit 1e8aac
  GladeAdaptorChooserPrivate *priv = GET_PRIVATE (chooser);
Packit 1e8aac
  GladeWidgetAdaptor *adaptor;
Packit 1e8aac
  
Packit 1e8aac
  if (priv->project && (adaptor = glade_project_get_add_item (priv->project)))
Packit 1e8aac
    {
Packit 1e8aac
      gtk_image_set_from_icon_name (priv->class_image,
Packit 1e8aac
                                    glade_widget_adaptor_get_icon_name (adaptor),
Packit 1e8aac
                                    GTK_ICON_SIZE_BUTTON);
Packit 1e8aac
      gtk_label_set_label (priv->class_label,
Packit 1e8aac
                           glade_widget_adaptor_get_name (adaptor));
Packit 1e8aac
    }
Packit 1e8aac
  else
Packit 1e8aac
    {
Packit 1e8aac
      gtk_image_set_from_pixbuf (priv->class_image, NULL);
Packit 1e8aac
      gtk_label_set_label (priv->class_label, "");
Packit 1e8aac
    }
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
void
Packit 1e8aac
glade_adaptor_chooser_set_project (GladeAdaptorChooser *chooser,
Packit 1e8aac
                                   GladeProject        *project)
Packit 1e8aac
{
Packit 1e8aac
  GladeAdaptorChooserPrivate *priv;
Packit 1e8aac
  GList *l;
Packit 1e8aac
Packit 1e8aac
  g_return_if_fail (GLADE_IS_ADAPTOR_CHOOSER (chooser));
Packit 1e8aac
  priv = GET_PRIVATE (chooser);
Packit 1e8aac
Packit 1e8aac
  if (priv->project)
Packit 1e8aac
    {
Packit 1e8aac
      g_signal_handlers_disconnect_by_func (G_OBJECT (priv->project),
Packit 1e8aac
                                            G_CALLBACK (glade_adaptor_chooser_update_adaptor),
Packit 1e8aac
                                            chooser);
Packit 1e8aac
      g_clear_object (&priv->project);
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  if (project)
Packit 1e8aac
    {
Packit 1e8aac
      priv->project = g_object_ref (project);
Packit 1e8aac
      g_signal_connect_swapped (G_OBJECT (project), "notify::add-item",
Packit 1e8aac
                                G_CALLBACK (glade_adaptor_chooser_update_adaptor),
Packit 1e8aac
                                chooser);
Packit 1e8aac
      gtk_widget_set_sensitive (GTK_WIDGET (chooser), TRUE);
Packit 1e8aac
    }
Packit 1e8aac
  else
Packit 1e8aac
    gtk_widget_set_sensitive (GTK_WIDGET (chooser), FALSE);
Packit 1e8aac
Packit 1e8aac
  /* Set project in chooser for filter to work */
Packit 1e8aac
  for (l = priv->choosers; l; l = g_list_next (l))
Packit 1e8aac
    _glade_adaptor_chooser_widget_set_project (l->data, project);
Packit 1e8aac
Packit 1e8aac
  /* Update class image and label */
Packit 1e8aac
  glade_adaptor_chooser_update_adaptor (chooser);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
GladeProject *
Packit 1e8aac
glade_adaptor_chooser_get_project (GladeAdaptorChooser *chooser)
Packit 1e8aac
{
Packit 1e8aac
  g_return_val_if_fail (GLADE_IS_ADAPTOR_CHOOSER (chooser), NULL);
Packit 1e8aac
  
Packit 1e8aac
  return GET_PRIVATE (chooser)->project;
Packit 1e8aac
}