[gnome-builder/wip/commands2] commands: move workspace and active tab to GbCommandProvider
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/commands2] commands: move workspace and active tab to GbCommandProvider
- Date: Thu, 9 Oct 2014 23:30:38 +0000 (UTC)
commit f87194e3073e4f2c0c18f38628485dfee1e03ebb
Author: Christian Hergert <christian hergert me>
Date: Thu Oct 9 16:29:36 2014 -0700
commands: move workspace and active tab to GbCommandProvider
This refactors the workspace and active-tab properties into the
base class, GbCommandProvider. They are likely to be needed by
most providers, so might as well track things there.
src/commands/gb-command-gaction-provider.c | 230 ++-------------------------
src/commands/gb-command-gaction-provider.h | 1 -
src/commands/gb-command-provider.c | 197 +++++++++++++++++++++++-
src/commands/gb-command-provider.h | 21 ++-
4 files changed, 224 insertions(+), 225 deletions(-)
---
diff --git a/src/commands/gb-command-gaction-provider.c b/src/commands/gb-command-gaction-provider.c
index 028b5b4..dd8c86f 100644
--- a/src/commands/gb-command-gaction-provider.c
+++ b/src/commands/gb-command-gaction-provider.c
@@ -18,28 +18,12 @@
#define G_LOG_DOMAIN "gaction-commands"
-#include <glib/gi18n.h>
+#include <string.h>
#include "gb-command-gaction-provider.h"
-#include "gb-tab.h"
-struct _GbCommandGactionProviderPrivate
-{
- GbWorkbench *workbench;
- GtkWidget *focus;
-};
-
-G_DEFINE_TYPE_WITH_PRIVATE (GbCommandGactionProvider,
- gb_command_gaction_provider,
- GB_TYPE_COMMAND_PROVIDER)
-
-enum {
- PROP_0,
- PROP_WORKBENCH,
- LAST_PROP
-};
-
-static GParamSpec *gParamSpecs [LAST_PROP];
+G_DEFINE_TYPE (GbCommandGactionProvider, gb_command_gaction_provider,
+ GB_TYPE_COMMAND_PROVIDER)
GbCommandProvider *
gb_command_gaction_provider_new (GbWorkbench *workbench)
@@ -48,127 +32,6 @@ gb_command_gaction_provider_new (GbWorkbench *workbench)
"workbench", workbench,
NULL);
}
-
-GbWorkbench *
-gb_command_gaction_provider_get_workbench (GbCommandGactionProvider *provider)
-{
- g_return_val_if_fail (GB_IS_COMMAND_GACTION_PROVIDER (provider), NULL);
-
- return provider->priv->workbench;
-}
-
-static void
-gb_command_gaction_provider_update_focus (GbCommandGactionProvider *provider,
- GtkWidget *focus)
-{
- GbCommandGactionProviderPrivate *priv;
-
- g_return_if_fail (GB_IS_COMMAND_GACTION_PROVIDER (provider));
- g_return_if_fail (!focus || GTK_IS_WIDGET (focus));
-
- priv = provider->priv;
-
- if (priv->focus)
- {
- g_object_remove_weak_pointer (G_OBJECT (priv->focus),
- (gpointer *)&priv->focus);
- priv->focus = NULL;
- }
-
- if (focus)
- {
- priv->focus = focus;
- g_object_add_weak_pointer (G_OBJECT (priv->focus),
- (gpointer *)&priv->focus);
- }
-}
-
-static void
-on_workbench_set_focus (GbCommandGactionProvider *provider,
- GtkWidget *widget,
- GbWorkbench *workbench)
-{
- GtkWidget *parent = widget;
-
- g_return_if_fail (GB_IS_COMMAND_GACTION_PROVIDER (provider));
- g_return_if_fail (GTK_IS_WIDGET (widget));
-
- /*
- * Try to locate the nearest GbTab in the widget hierarchy starting from
- * the new focus widget. If this widget is not a decendent of a tab, we
- * will just ignore things.
- */
- while (!GB_IS_TAB (parent))
- {
- parent = gtk_widget_get_parent (parent);
- if (!parent)
- break;
- }
-
- if (GB_IS_TAB (parent))
- gb_command_gaction_provider_update_focus (provider, parent);
-}
-
-static void
-gb_command_gaction_provider_connect (GbCommandGactionProvider *provider,
- GbWorkbench *workbench)
-{
- g_return_if_fail (GB_IS_COMMAND_GACTION_PROVIDER (provider));
- g_return_if_fail (GB_IS_WORKBENCH (workbench));
-
- g_signal_connect_object (workbench,
- "set-focus",
- G_CALLBACK (on_workbench_set_focus),
- provider,
- G_CONNECT_SWAPPED);
-}
-
-static void
-gb_command_gaction_provider_disconnect (GbCommandGactionProvider *provider,
- GbWorkbench *workbench)
-{
- g_return_if_fail (GB_IS_COMMAND_GACTION_PROVIDER (provider));
- g_return_if_fail (GB_IS_WORKBENCH (workbench));
-
- g_signal_handlers_disconnect_by_func (workbench,
- G_CALLBACK (on_workbench_set_focus),
- provider);
-}
-
-void
-gb_command_gaction_provider_set_workbench (GbCommandGactionProvider *provider,
- GbWorkbench *workbench)
-{
- GbCommandGactionProviderPrivate *priv;
-
- g_return_if_fail (GB_IS_COMMAND_GACTION_PROVIDER (provider));
- g_return_if_fail (!workbench || GB_IS_WORKBENCH (workbench));
-
- priv = provider->priv;
-
- if (workbench != priv->workbench)
- {
- if (priv->workbench)
- {
- gb_command_gaction_provider_disconnect (provider, workbench);
- g_object_remove_weak_pointer (G_OBJECT (priv->workbench),
- (gpointer *)&priv->workbench);
- priv->workbench = NULL;
- }
-
- if (workbench)
- {
- gb_command_gaction_provider_connect (provider, workbench);
- priv->workbench = workbench;
- g_object_add_weak_pointer (G_OBJECT (workbench),
- (gpointer *)&priv->workbench);
- }
-
- g_object_notify_by_pspec (G_OBJECT (provider),
- gParamSpecs [PROP_WORKBENCH]);
- }
-}
-
static GAction *
gb_command_gaction_provider_lookup (GbCommandProvider *provider,
const gchar *command_text,
@@ -183,11 +46,6 @@ gb_command_gaction_provider_lookup (GbCommandProvider *provider,
g_return_val_if_fail (GB_IS_COMMAND_GACTION_PROVIDER (self), NULL);
- if (!self->priv->focus)
- return NULL;
-
- widget = self->priv->focus;
-
/* Determine the command name */
tmp = g_strdelimit (g_strdup (command_text), "(", ' ');
parts = g_strsplit (tmp, " ", 2);
@@ -222,6 +80,7 @@ gb_command_gaction_provider_lookup (GbCommandProvider *provider,
* ApplicationWindow which is a GActionMap.
*/
+ widget = GTK_WIDGET (gb_command_provider_get_active_tab (provider));
while (widget)
{
if (G_IS_ACTION_MAP (widget))
@@ -234,6 +93,18 @@ gb_command_gaction_provider_lookup (GbCommandProvider *provider,
widget = gtk_widget_get_parent (widget);
}
+ /*
+ * Now try to lookup the action inside of the GApplication.
+ * This is useful for stuff like "quit", and "preferences".
+ */
+ if (!action)
+ {
+ GApplication *app;
+
+ app = g_application_get_default ();
+ action = g_action_map_lookup_action (G_ACTION_MAP (app), name);
+ }
+
if (!action && *parameters)
{
g_variant_unref (*parameters);
@@ -243,85 +114,18 @@ gb_command_gaction_provider_lookup (GbCommandProvider *provider,
cleanup:
g_free (name);
- return action;
-}
-
-static void
-gb_command_gaction_provider_dispose (GObject *object)
-{
- GbCommandGactionProvider *provider = (GbCommandGactionProvider *)object;
-
- gb_command_gaction_provider_update_focus (provider, NULL);
- gb_command_gaction_provider_set_workbench (provider, NULL);
-
- G_OBJECT_CLASS (gb_command_gaction_provider_parent_class)->dispose (object);
-}
-
-static void
-gb_command_gaction_provider_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GbCommandGactionProvider *self = GB_COMMAND_GACTION_PROVIDER (object);
-
- switch (prop_id)
- {
- case PROP_WORKBENCH:
- g_value_set_object (value,
- gb_command_gaction_provider_get_workbench (self));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-static void
-gb_command_gaction_provider_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GbCommandGactionProvider *self = GB_COMMAND_GACTION_PROVIDER (object);
-
- switch (prop_id)
- {
- case PROP_WORKBENCH:
- gb_command_gaction_provider_set_workbench (self,
- g_value_get_object (value));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
+ return action ? g_object_ref (action) : NULL;
}
static void
gb_command_gaction_provider_class_init (GbCommandGactionProviderClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
GbCommandProviderClass *provider_class = GB_COMMAND_PROVIDER_CLASS (klass);
- object_class->dispose = gb_command_gaction_provider_dispose;
- object_class->get_property = gb_command_gaction_provider_get_property;
- object_class->set_property = gb_command_gaction_provider_set_property;
-
provider_class->lookup = gb_command_gaction_provider_lookup;
-
- gParamSpecs [PROP_WORKBENCH] =
- g_param_spec_object ("workbench",
- _("Workbench"),
- _("The workbench containing the actions."),
- GB_TYPE_WORKBENCH,
- (G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_WORKBENCH,
- gParamSpecs [PROP_WORKBENCH]);
}
static void
gb_command_gaction_provider_init (GbCommandGactionProvider *self)
{
- self->priv = gb_command_gaction_provider_get_instance_private (self);
}
diff --git a/src/commands/gb-command-gaction-provider.h b/src/commands/gb-command-gaction-provider.h
index d7dc040..622700d 100644
--- a/src/commands/gb-command-gaction-provider.h
+++ b/src/commands/gb-command-gaction-provider.h
@@ -20,7 +20,6 @@
#define GB_COMMAND_GACTION_PROVIDER_H
#include "gb-command-provider.h"
-#include "gb-workbench.h"
G_BEGIN_DECLS
diff --git a/src/commands/gb-command-provider.c b/src/commands/gb-command-provider.c
index c7ff6bd..575d85f 100644
--- a/src/commands/gb-command-provider.c
+++ b/src/commands/gb-command-provider.c
@@ -22,7 +22,9 @@
struct _GbCommandProviderPrivate
{
- gint priority;
+ GbWorkbench *workbench;
+ GbTab *active_tab;
+ gint priority;
};
G_DEFINE_TYPE_WITH_PRIVATE (GbCommandProvider, gb_command_provider,
@@ -30,7 +32,9 @@ G_DEFINE_TYPE_WITH_PRIVATE (GbCommandProvider, gb_command_provider,
enum {
PROP_0,
+ PROP_ACTIVE_TAB,
PROP_PRIORITY,
+ PROP_WORKBENCH,
LAST_PROP
};
@@ -43,9 +47,143 @@ static GParamSpec *gParamSpecs [LAST_PROP];
static guint gSignals [LAST_SIGNAL];
GbCommandProvider *
-gb_command_provider_new (void)
+gb_command_provider_new (GbWorkbench *workbench)
{
- return g_object_new (GB_TYPE_COMMAND_PROVIDER, NULL);
+ return g_object_new (GB_TYPE_COMMAND_PROVIDER,
+ "workbench", workbench,
+ NULL);
+}
+
+/**
+ * gb_command_provider_get_active_tab:
+ *
+ * Returns the "active-tab" property. The active-tab is the last tab that
+ * was focused in the workbench.
+ *
+ * Returns: (transfer none): A #GbTab or %NULL.
+ */
+GbTab *
+gb_command_provider_get_active_tab (GbCommandProvider *provider)
+{
+ g_return_val_if_fail (GB_IS_COMMAND_PROVIDER (provider), NULL);
+
+ return provider->priv->active_tab;
+}
+
+static void
+gb_command_provider_set_active_tab (GbCommandProvider *provider,
+ GbTab *tab)
+{
+ GbCommandProviderPrivate *priv;
+
+ g_return_if_fail (GB_IS_COMMAND_PROVIDER (provider));
+ g_return_if_fail (!tab || GB_IS_TAB (tab));
+
+ priv = provider->priv;
+
+ if (priv->active_tab)
+ {
+ g_object_remove_weak_pointer (G_OBJECT (priv->active_tab),
+ (gpointer *)&priv->active_tab);
+ priv->active_tab = NULL;
+ }
+
+ if (tab)
+ {
+ priv->active_tab = tab;
+ g_object_add_weak_pointer (G_OBJECT (priv->active_tab),
+ (gpointer *)&priv->active_tab);
+ }
+
+ g_object_notify_by_pspec (G_OBJECT (provider),
+ gParamSpecs [PROP_ACTIVE_TAB]);
+}
+
+static void
+on_workbench_set_focus (GbCommandProvider *provider,
+ GtkWidget *widget,
+ GbWorkbench *workbench)
+{
+ g_return_if_fail (GB_IS_COMMAND_PROVIDER (provider));
+ g_return_if_fail (GB_IS_WORKBENCH (workbench));
+ g_return_if_fail (!widget || GTK_IS_WIDGET (widget));
+
+ /* walk the hierarchy to find a tab */
+ if (widget)
+ while (!GB_IS_TAB (widget))
+ if (!(widget = gtk_widget_get_parent (widget)))
+ break;
+
+ if (GB_IS_TAB (widget))
+ gb_command_provider_set_active_tab (provider, GB_TAB (widget));
+}
+
+static void
+gb_command_provider_connect (GbCommandProvider *provider,
+ GbWorkbench *workbench)
+{
+ g_return_if_fail (GB_IS_COMMAND_PROVIDER (provider));
+ g_return_if_fail (GB_IS_WORKBENCH (workbench));
+
+ g_signal_connect_object (workbench,
+ "set-focus",
+ G_CALLBACK (on_workbench_set_focus),
+ provider,
+ G_CONNECT_SWAPPED);
+}
+
+static void
+gb_command_provider_disconnect (GbCommandProvider *provider,
+ GbWorkbench *workbench)
+{
+ g_return_if_fail (GB_IS_COMMAND_PROVIDER (provider));
+ g_return_if_fail (GB_IS_WORKBENCH (workbench));
+
+ g_signal_handlers_disconnect_by_func (workbench,
+ G_CALLBACK (on_workbench_set_focus),
+ provider);
+}
+
+GbWorkbench *
+gb_command_provider_get_workbench (GbCommandProvider *provider)
+{
+ g_return_val_if_fail (GB_IS_COMMAND_PROVIDER (provider), NULL);
+
+ return provider->priv->workbench;
+}
+
+static void
+gb_command_provider_set_workbench (GbCommandProvider *provider,
+ GbWorkbench *workbench)
+{
+ GbCommandProviderPrivate *priv;
+
+ g_return_if_fail (GB_IS_COMMAND_PROVIDER (provider));
+ g_return_if_fail (!workbench || GB_IS_WORKBENCH (workbench));
+
+ priv = provider->priv;
+
+ if (priv->workbench != workbench)
+ {
+ if (priv->workbench)
+ {
+ gb_command_provider_disconnect (provider, workbench);
+ g_object_remove_weak_pointer (G_OBJECT (priv->workbench),
+ (gpointer *)&priv->workbench);
+ priv->workbench = NULL;
+ }
+
+ if (workbench)
+ {
+ priv->workbench = workbench;
+ g_object_add_weak_pointer (G_OBJECT (priv->workbench),
+ (gpointer *)&priv->workbench);
+ gb_command_provider_connect (provider, workbench);
+ }
+
+ g_object_notify_by_pspec (G_OBJECT (provider),
+ gParamSpecs [PROP_WORKBENCH]);
+ }
}
gint
@@ -70,6 +208,19 @@ gb_command_provider_set_priority (GbCommandProvider *provider,
}
}
+/**
+ * gb_command_provider_lookup:
+ * @provider: (in): The #GbCommandProvider
+ * @command_text: (in): Command text to be parsed
+ * @parameter: (allow-none) (out): location for a resulting #GVariant parameter
+ *
+ * This function causes the provider to attept to parse @command_text and
+ * generate a GAction to execute the command. If the @command_text could not
+ * be parsed, then %NULL is returned.
+ *
+ * Returns: (transfer full): A #GAction that should be freed with
+ * g_object_unref().
+ */
GAction *
gb_command_provider_lookup (GbCommandProvider *provider,
const gchar *command_text,
@@ -98,10 +249,18 @@ gb_command_provider_get_property (GObject *object,
switch (prop_id)
{
+ case PROP_ACTIVE_TAB:
+ g_value_set_object (value, gb_command_provider_get_active_tab (self));
+ break;
+
case PROP_PRIORITY:
g_value_set_int (value, gb_command_provider_get_priority (self));
break;
+ case PROP_WORKBENCH:
+ g_value_set_object (value, gb_command_provider_get_workbench (self));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -121,6 +280,10 @@ gb_command_provider_set_property (GObject *object,
gb_command_provider_set_priority (self, g_value_get_int (value));
break;
+ case PROP_WORKBENCH:
+ gb_command_provider_set_workbench (self, g_value_get_object (value));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -134,6 +297,16 @@ gb_command_provider_class_init (GbCommandProviderClass *klass)
object_class->get_property = gb_command_provider_get_property;
object_class->set_property = gb_command_provider_set_property;
+ gParamSpecs [PROP_ACTIVE_TAB] =
+ g_param_spec_object ("active-tab",
+ _("Active Tab"),
+ _("The last focused GbTab widget."),
+ GB_TYPE_TAB,
+ (G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_ACTIVE_TAB,
+ gParamSpecs [PROP_ACTIVE_TAB]);
+
/**
* GbCommandProvider:priority:
*
@@ -158,6 +331,24 @@ gb_command_provider_class_init (GbCommandProviderClass *klass)
gParamSpecs [PROP_PRIORITY]);
/**
+ * GbCommandProvider:workbench:
+ *
+ * The "workbench" property is the top-level window containing our project
+ * and the workbench to work on it. It keeps track of the last focused tab
+ * for convenience by action providers.
+ */
+ gParamSpecs [PROP_WORKBENCH] =
+ g_param_spec_object ("workbench",
+ _("Workbench"),
+ _("The target workbench."),
+ GB_TYPE_WORKBENCH,
+ (G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_WORKBENCH,
+ gParamSpecs [PROP_WORKBENCH]);
+
+ /**
* GbCommandProvider::lookup:
* @command_text: (in): the command line text to be processed.
* @parameter: (out): a location to store any parsed parameters.
diff --git a/src/commands/gb-command-provider.h b/src/commands/gb-command-provider.h
index 3540530..2398515 100644
--- a/src/commands/gb-command-provider.h
+++ b/src/commands/gb-command-provider.h
@@ -21,6 +21,9 @@
#include <gio/gio.h>
+#include "gb-tab.h"
+#include "gb-workbench.h"
+
G_BEGIN_DECLS
#define GB_TYPE_COMMAND_PROVIDER (gb_command_provider_get_type())
@@ -58,14 +61,16 @@ struct _GbCommandProviderClass
gpointer _padding5;
};
-GType gb_command_provider_get_type (void) G_GNUC_CONST;
-GbCommandProvider *gb_command_provider_new (void);
-gint gb_command_provider_get_priority (GbCommandProvider *provider);
-void gb_command_provider_set_priority (GbCommandProvider *provider,
- gint priority);
-GAction *gb_command_provider_lookup (GbCommandProvider *provider,
- const gchar *command_text,
- GVariant **parameters);
+GType gb_command_provider_get_type (void) G_GNUC_CONST;
+GbCommandProvider *gb_command_provider_new (GbWorkbench *workbench);
+GbWorkbench *gb_command_provider_get_workbench (GbCommandProvider *provider);
+GbTab *gb_command_provider_get_active_tab (GbCommandProvider *provider);
+gint gb_command_provider_get_priority (GbCommandProvider *provider);
+void gb_command_provider_set_priority (GbCommandProvider *provider,
+ gint priority);
+GAction *gb_command_provider_lookup (GbCommandProvider *provider,
+ const gchar *command_text,
+ GVariant **parameters);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]