[gnome-control-center] region: Create classes for input sources
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center] region: Create classes for input sources
- Date: Wed, 24 Oct 2018 04:56:18 +0000 (UTC)
commit 9c655bfba0ab2929dae527b606cc64e13c96557f
Author: Robert Ancell <robert ancell canonical com>
Date: Wed Sep 12 10:33:06 2018 +1200
region: Create classes for input sources
panels/region/cc-input-chooser.c | 27 ++--
panels/region/cc-input-chooser.h | 7 +-
panels/region/cc-input-row.c | 64 +++------
panels/region/cc-input-row.h | 18 +--
panels/region/cc-input-source-ibus.c | 155 +++++++++++++++++++++
panels/region/cc-input-source-ibus.h | 46 +++++++
panels/region/cc-input-source-xkb.c | 134 ++++++++++++++++++
panels/region/cc-input-source-xkb.h | 39 ++++++
panels/region/cc-input-source.c | 84 ++++++++++++
panels/region/cc-input-source.h | 49 +++++++
panels/region/cc-region-panel.c | 254 ++++++++++++-----------------------
panels/region/meson.build | 3 +
12 files changed, 632 insertions(+), 248 deletions(-)
---
diff --git a/panels/region/cc-input-chooser.c b/panels/region/cc-input-chooser.c
index af22e8b9f..f08e1fb5b 100644
--- a/panels/region/cc-input-chooser.c
+++ b/panels/region/cc-input-chooser.c
@@ -26,6 +26,8 @@
#include "cc-common-language.h"
#include "cc-util.h"
#include "cc-input-chooser.h"
+#include "cc-input-source-ibus.h"
+#include "cc-input-source-xkb.h"
#ifdef HAVE_IBUS
#include <ibus.h>
@@ -1072,31 +1074,28 @@ cc_input_chooser_set_ibus_engines (CcInputChooser *self,
#endif /* HAVE_IBUS */
}
-gboolean
-cc_input_chooser_get_selected (CcInputChooser *self,
- gchar **type,
- gchar **id,
- gchar **name)
+CcInputSource *
+cc_input_chooser_get_source (CcInputChooser *self)
{
GtkListBoxRow *selected;
- const gchar *t, *i, *n;
+ const gchar *t, *i;
g_return_val_if_fail (CC_IS_INPUT_CHOOSER (self), FALSE);
selected = gtk_list_box_get_selected_row (self->input_sources_listbox);
if (!selected)
- return FALSE;
+ return NULL;
t = g_object_get_data (G_OBJECT (selected), "type");
i = g_object_get_data (G_OBJECT (selected), "id");
- n = g_object_get_data (G_OBJECT (selected), "name");
- if (!t || !i || !n)
+ if (!t || !i)
return FALSE;
- *type = g_strdup (t);
- *id = g_strdup (i);
- *name = g_strdup (n);
-
- return TRUE;
+ if (g_strcmp0 (t, "xkb") == 0)
+ return CC_INPUT_SOURCE (cc_input_source_xkb_new_from_id (self->xkb_info, i));
+ else if (g_strcmp0 (t, "ibus") == 0)
+ return CC_INPUT_SOURCE (cc_input_source_ibus_new (i));
+ else
+ return NULL;
}
diff --git a/panels/region/cc-input-chooser.h b/panels/region/cc-input-chooser.h
index bc75d9299..836378266 100644
--- a/panels/region/cc-input-chooser.h
+++ b/panels/region/cc-input-chooser.h
@@ -19,6 +19,8 @@
#include <gtk/gtk.h>
+#include "cc-input-source.h"
+
#define GNOME_DESKTOP_USE_UNSTABLE_API
#include <libgnome-desktop/gnome-xkb-info.h>
@@ -34,9 +36,6 @@ CcInputChooser *cc_input_chooser_new (gboolean is_login,
void cc_input_chooser_set_ibus_engines (CcInputChooser *chooser,
GHashTable *ibus_engines);
-gboolean cc_input_chooser_get_selected (CcInputChooser *chooser,
- gchar **type,
- gchar **id,
- gchar **name);
+CcInputSource *cc_input_chooser_get_source (CcInputChooser *chooser);
G_END_DECLS
diff --git a/panels/region/cc-input-row.c b/panels/region/cc-input-row.c
index 86b452dee..c3d269bf6 100644
--- a/panels/region/cc-input-row.c
+++ b/panels/region/cc-input-row.c
@@ -17,14 +17,13 @@
#include <config.h>
#include "cc-input-row.h"
+#include "cc-input-source-ibus.h"
struct _CcInputRow
{
GtkListBoxRow parent_instance;
- gchar *type;
- gchar *id;
- GDesktopAppInfo *app_info;
+ CcInputSource *source;
GtkWidget *name_label;
GtkWidget *icon_image;
@@ -37,9 +36,7 @@ cc_input_row_dispose (GObject *object)
{
CcInputRow *self = CC_INPUT_ROW (object);
- g_clear_pointer (&self->type, g_free);
- g_clear_pointer (&self->id, g_free);
- g_clear_object (&self->app_info);
+ g_clear_object (&self->source);
G_OBJECT_CLASS (cc_input_row_parent_class)->dispose (object);
}
@@ -63,55 +60,32 @@ cc_input_row_init (CcInputRow *row)
gtk_widget_init_template (GTK_WIDGET (row));
}
+static void
+label_changed_cb (CcInputRow *row)
+{
+ g_autofree gchar *label = cc_input_source_get_label (row->source);
+ gtk_label_set_text (GTK_LABEL (row->name_label), label);
+}
+
CcInputRow *
-cc_input_row_new (const gchar *type,
- const gchar *id,
- GDesktopAppInfo *app_info)
+cc_input_row_new (CcInputSource *source)
{
CcInputRow *row;
row = g_object_new (CC_TYPE_INPUT_ROW, NULL);
- row->type = g_strdup (type);
- row->id = g_strdup (id);
- if (app_info != NULL)
- row->app_info = g_object_ref (app_info);
+ row->source = g_object_ref (source);
- return row;
-}
+ g_signal_connect_object (source, "label-changed", G_CALLBACK (label_changed_cb), row, G_CONNECT_SWAPPED);
+ label_changed_cb (row);
-const gchar *
-cc_input_row_get_input_type (CcInputRow *row)
-{
- g_return_val_if_fail (CC_IS_INPUT_ROW (row), NULL);
- return row->type;
-}
+ gtk_widget_set_visible (row->icon_image, CC_IS_INPUT_SOURCE_IBUS (source));
-const gchar *
-cc_input_row_get_id (CcInputRow *row)
-{
- g_return_val_if_fail (CC_IS_INPUT_ROW (row), NULL);
- return row->id;
+ return row;
}
-GDesktopAppInfo *
-cc_input_row_get_app_info (CcInputRow *row)
+CcInputSource *
+cc_input_row_get_source (CcInputRow *row)
{
g_return_val_if_fail (CC_IS_INPUT_ROW (row), NULL);
- return row->app_info;
-}
-
-void
-cc_input_row_set_label (CcInputRow *row,
- const gchar *text)
-{
- g_return_if_fail (CC_IS_INPUT_ROW (row));
- gtk_label_set_text (GTK_LABEL (row->name_label), text);
-}
-
-void
-cc_input_row_set_is_input_method (CcInputRow *row,
- gboolean is_input_method)
-{
- g_return_if_fail (CC_IS_INPUT_ROW (row));
- gtk_widget_set_visible (row->icon_image, is_input_method);
+ return row->source;
}
diff --git a/panels/region/cc-input-row.h b/panels/region/cc-input-row.h
index dba8b6158..a5c0ec62c 100644
--- a/panels/region/cc-input-row.h
+++ b/panels/region/cc-input-row.h
@@ -20,25 +20,15 @@
#include <gtk/gtk.h>
#include <gio/gdesktopappinfo.h>
+#include "cc-input-source.h"
+
G_BEGIN_DECLS
#define CC_TYPE_INPUT_ROW (cc_input_row_get_type ())
G_DECLARE_FINAL_TYPE (CcInputRow, cc_input_row, CC, INPUT_ROW, GtkListBoxRow)
-CcInputRow *cc_input_row_new (const gchar *type,
- const gchar *id,
- GDesktopAppInfo *app_info);
-
-const gchar *cc_input_row_get_input_type (CcInputRow *row);
-
-const gchar *cc_input_row_get_id (CcInputRow *row);
-
-GDesktopAppInfo *cc_input_row_get_app_info (CcInputRow *row);
-
-void cc_input_row_set_label (CcInputRow *row,
- const gchar *text);
+CcInputRow *cc_input_row_new (CcInputSource *source);
-void cc_input_row_set_is_input_method (CcInputRow *row,
- gboolean is_input_method);
+CcInputSource *cc_input_row_get_source (CcInputRow *row);
G_END_DECLS
diff --git a/panels/region/cc-input-source-ibus.c b/panels/region/cc-input-source-ibus.c
new file mode 100644
index 000000000..1aa1ab8a2
--- /dev/null
+++ b/panels/region/cc-input-source-ibus.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright © 2018 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cc-input-source-ibus.h"
+#ifdef HAVE_IBUS
+#include "cc-ibus-utils.h"
+#endif
+
+struct _CcInputSourceIBus
+{
+ CcInputSource parent_instance;
+
+ gchar *engine_name;
+#ifdef HAVE_IBUS
+ IBusEngineDesc *engine_desc;
+#endif
+};
+
+G_DEFINE_TYPE (CcInputSourceIBus, cc_input_source_ibus, CC_TYPE_INPUT_SOURCE)
+
+static gchar *
+cc_input_source_ibus_get_label (CcInputSource *source)
+{
+ CcInputSourceIBus *self = CC_INPUT_SOURCE_IBUS (source);
+#ifdef HAVE_IBUS
+ if (self->engine_desc)
+ return g_strdup (engine_get_display_name (self->engine_desc));
+ else
+#endif
+ return g_strdup (self->engine_name);
+}
+
+static gboolean
+cc_input_source_ibus_matches (CcInputSource *source,
+ CcInputSource *source2)
+{
+ if (!CC_IS_INPUT_SOURCE_IBUS (source2))
+ return FALSE;
+
+ return g_strcmp0 (CC_INPUT_SOURCE_IBUS (source)->engine_name, CC_INPUT_SOURCE_IBUS (source2)->engine_name)
== 0;
+}
+
+static const gchar *
+cc_input_source_ibus_get_layout (CcInputSource *source)
+{
+#ifdef HAVE_IBUS
+ CcInputSourceIBus *self = CC_INPUT_SOURCE_IBUS (source);
+ if (self->engine_desc != NULL)
+ return ibus_engine_desc_get_layout (self->engine_desc);
+ else
+#endif
+ return NULL;
+}
+
+static const gchar *
+cc_input_source_ibus_get_layout_variant (CcInputSource *source)
+{
+#ifdef HAVE_IBUS
+ CcInputSourceIBus *self = CC_INPUT_SOURCE_IBUS (source);
+ if (self->engine_desc != NULL)
+ return ibus_engine_desc_get_layout_variant (self->engine_desc);
+ else
+#endif
+ return NULL;
+}
+
+static void
+cc_input_source_ibus_dispose (GObject *object)
+{
+ CcInputSourceIBus *self = CC_INPUT_SOURCE_IBUS (object);
+
+ g_clear_pointer (&self->engine_name, g_free);
+#ifdef HAVE_IBUS
+ g_clear_object (&self->engine_desc);
+#endif
+
+ G_OBJECT_CLASS (cc_input_source_ibus_parent_class)->dispose (object);
+}
+
+void
+cc_input_source_ibus_class_init (CcInputSourceIBusClass *klass)
+{
+ CcInputSourceClass *input_source_class = CC_INPUT_SOURCE_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ input_source_class->get_label = cc_input_source_ibus_get_label;
+ input_source_class->matches = cc_input_source_ibus_matches;
+ input_source_class->get_layout = cc_input_source_ibus_get_layout;
+ input_source_class->get_layout_variant = cc_input_source_ibus_get_layout_variant;
+ object_class->dispose = cc_input_source_ibus_dispose;
+}
+
+void
+cc_input_source_ibus_init (CcInputSourceIBus *source)
+{
+}
+
+CcInputSourceIBus *
+cc_input_source_ibus_new (const gchar *engine_name)
+{
+ CcInputSourceIBus *source;
+
+ source = g_object_new (CC_TYPE_INPUT_SOURCE_IBUS, NULL);
+ source->engine_name = g_strdup (engine_name);
+
+ return source;
+}
+
+#ifdef HAVE_IBUS
+void
+cc_input_source_ibus_set_engine_desc (CcInputSourceIBus *source,
+ IBusEngineDesc *engine_desc)
+{
+ g_return_if_fail (CC_IS_INPUT_SOURCE_IBUS (source));
+
+ g_clear_object (&source->engine_desc);
+ source->engine_desc = g_object_ref (engine_desc);
+ cc_input_source_emit_label_changed (CC_INPUT_SOURCE (source));
+}
+#endif
+
+const gchar *
+cc_input_source_ibus_get_engine_name (CcInputSourceIBus *source)
+{
+ g_return_val_if_fail (CC_IS_INPUT_SOURCE_IBUS (source), NULL);
+ return source->engine_name;
+}
+
+GDesktopAppInfo *
+cc_input_source_ibus_get_app_info (CcInputSourceIBus *source)
+{
+ g_auto(GStrv) tokens = NULL;
+ g_autofree gchar *desktop_file_name = NULL;
+
+ g_return_val_if_fail (CC_IS_INPUT_SOURCE_IBUS (source), NULL);
+
+ tokens = g_strsplit (source->engine_name, ":", 2);
+ desktop_file_name = g_strdup_printf ("ibus-setup-%s.desktop", tokens[0]);
+
+ return g_desktop_app_info_new (desktop_file_name);
+}
diff --git a/panels/region/cc-input-source-ibus.h b/panels/region/cc-input-source-ibus.h
new file mode 100644
index 000000000..2c09d01c6
--- /dev/null
+++ b/panels/region/cc-input-source-ibus.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright © 2018 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <config.h>
+
+#ifdef HAVE_IBUS
+#include <ibus.h>
+#endif
+
+#include <gio/gdesktopappinfo.h>
+
+#include "cc-input-source.h"
+
+G_BEGIN_DECLS
+
+#define CC_TYPE_INPUT_SOURCE_IBUS (cc_input_source_ibus_get_type ())
+G_DECLARE_FINAL_TYPE (CcInputSourceIBus, cc_input_source_ibus, CC, INPUT_SOURCE_IBUS, CcInputSource)
+
+CcInputSourceIBus *cc_input_source_ibus_new (const gchar *engine_name);
+
+#ifdef HAVE_IBUS
+void cc_input_source_ibus_set_engine_desc (CcInputSourceIBus *source,
+ IBusEngineDesc *engine_desc);
+#endif
+
+const gchar *cc_input_source_ibus_get_engine_name (CcInputSourceIBus *source);
+
+GDesktopAppInfo *cc_input_source_ibus_get_app_info (CcInputSourceIBus *source);
+
+G_END_DECLS
diff --git a/panels/region/cc-input-source-xkb.c b/panels/region/cc-input-source-xkb.c
new file mode 100644
index 000000000..2ea30beb5
--- /dev/null
+++ b/panels/region/cc-input-source-xkb.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright © 2018 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include "cc-input-source-xkb.h"
+
+struct _CcInputSourceXkb
+{
+ CcInputSource parent_instance;
+
+ GnomeXkbInfo *xkb_info;
+ gchar *layout;
+ gchar *variant;
+};
+
+G_DEFINE_TYPE (CcInputSourceXkb, cc_input_source_xkb, CC_TYPE_INPUT_SOURCE)
+
+static gchar *
+cc_input_source_xkb_get_label (CcInputSource *source)
+{
+ CcInputSourceXkb *self = CC_INPUT_SOURCE_XKB (source);
+ g_autofree gchar *id = NULL;
+ const gchar *name;
+
+ id = cc_input_source_xkb_get_id (self);
+ gnome_xkb_info_get_layout_info (self->xkb_info, id, &name, NULL, NULL, NULL);
+ if (name)
+ return g_strdup (name);
+ else
+ return g_strdup (id);
+}
+
+static gboolean
+cc_input_source_xkb_matches (CcInputSource *source,
+ CcInputSource *source2)
+{
+ if (!CC_IS_INPUT_SOURCE_XKB (source2))
+ return FALSE;
+
+ return g_strcmp0 (CC_INPUT_SOURCE_XKB (source)->layout, CC_INPUT_SOURCE_XKB (source2)->layout) == 0 &&
+ g_strcmp0 (CC_INPUT_SOURCE_XKB (source)->variant, CC_INPUT_SOURCE_XKB (source2)->variant) == 0;
+}
+
+static void
+cc_input_source_xkb_dispose (GObject *object)
+{
+ CcInputSourceXkb *self = CC_INPUT_SOURCE_XKB (object);
+
+ g_clear_object (&self->xkb_info);
+ g_clear_pointer (&self->layout, g_free);
+ g_clear_pointer (&self->variant, g_free);
+
+ G_OBJECT_CLASS (cc_input_source_xkb_parent_class)->dispose (object);
+}
+
+static const gchar *
+cc_input_source_xkb_get_layout (CcInputSource *source)
+{
+ return CC_INPUT_SOURCE_XKB (source)->layout;
+}
+
+static const gchar *
+cc_input_source_xkb_get_layout_variant (CcInputSource *source)
+{
+ return CC_INPUT_SOURCE_XKB (source)->variant;
+}
+
+void
+cc_input_source_xkb_class_init (CcInputSourceXkbClass *klass)
+{
+ CcInputSourceClass *input_source_class = CC_INPUT_SOURCE_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ input_source_class->get_label = cc_input_source_xkb_get_label;
+ input_source_class->matches = cc_input_source_xkb_matches;
+ input_source_class->get_layout = cc_input_source_xkb_get_layout;
+ input_source_class->get_layout_variant = cc_input_source_xkb_get_layout_variant;
+ object_class->dispose = cc_input_source_xkb_dispose;
+}
+
+void
+cc_input_source_xkb_init (CcInputSourceXkb *source)
+{
+}
+
+CcInputSourceXkb *
+cc_input_source_xkb_new (GnomeXkbInfo *xkb_info,
+ const gchar *layout,
+ const gchar *variant)
+{
+ CcInputSourceXkb *source;
+
+ source = g_object_new (CC_TYPE_INPUT_SOURCE_XKB, NULL);
+ source->xkb_info = g_object_ref (xkb_info);
+ source->layout = g_strdup (layout);
+ source->variant = g_strdup (variant);
+
+ return source;
+}
+
+CcInputSourceXkb *
+cc_input_source_xkb_new_from_id (GnomeXkbInfo *xkb_info,
+ const gchar *id)
+{
+ g_auto(GStrv) tokens = NULL;
+
+ tokens = g_strsplit (id, "+", 2);
+
+ return cc_input_source_xkb_new (xkb_info, tokens[0], tokens[1]);
+}
+
+gchar *
+cc_input_source_xkb_get_id (CcInputSourceXkb *source)
+{
+ g_return_val_if_fail (CC_IS_INPUT_SOURCE_XKB (source), NULL);
+ if (source->variant != NULL)
+ return g_strdup_printf ("%s+%s", source->layout, source->variant);
+ else
+ return g_strdup (source->layout);
+}
diff --git a/panels/region/cc-input-source-xkb.h b/panels/region/cc-input-source-xkb.h
new file mode 100644
index 000000000..e8886d014
--- /dev/null
+++ b/panels/region/cc-input-source-xkb.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright © 2018 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#define GNOME_DESKTOP_USE_UNSTABLE_API
+#include <libgnome-desktop/gnome-xkb-info.h>
+
+#include "cc-input-source.h"
+
+G_BEGIN_DECLS
+
+#define CC_TYPE_INPUT_SOURCE_XKB (cc_input_source_xkb_get_type ())
+G_DECLARE_FINAL_TYPE (CcInputSourceXkb, cc_input_source_xkb, CC, INPUT_SOURCE_XKB, CcInputSource)
+
+CcInputSourceXkb *cc_input_source_xkb_new (GnomeXkbInfo *xkb_info,
+ const gchar *layout,
+ const gchar *variant);
+
+CcInputSourceXkb *cc_input_source_xkb_new_from_id (GnomeXkbInfo *xkb_info,
+ const gchar *id);
+
+gchar *cc_input_source_xkb_get_id (CcInputSourceXkb *source);
+
+G_END_DECLS
diff --git a/panels/region/cc-input-source.c b/panels/region/cc-input-source.c
new file mode 100644
index 000000000..df8db8b9c
--- /dev/null
+++ b/panels/region/cc-input-source.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright © 2018 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include "cc-input-source.h"
+
+enum
+{
+ SIGNAL_LABEL_CHANGED,
+ SIGNAL_LAST
+};
+
+static guint signals[SIGNAL_LAST] = {0};
+
+G_DEFINE_TYPE (CcInputSource, cc_input_source, G_TYPE_OBJECT)
+
+void
+cc_input_source_class_init (CcInputSourceClass *klass)
+{
+ signals[SIGNAL_LABEL_CHANGED] =
+ g_signal_new ("label-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE,
+ 0);
+}
+
+void
+cc_input_source_init (CcInputSource *source)
+{
+}
+
+void
+cc_input_source_emit_label_changed (CcInputSource *source)
+{
+ g_return_if_fail (CC_IS_INPUT_SOURCE (source));
+ g_signal_emit (source, signals[SIGNAL_LABEL_CHANGED], 0);
+}
+
+gchar *
+cc_input_source_get_label (CcInputSource *source)
+{
+ g_return_val_if_fail (CC_IS_INPUT_SOURCE (source), NULL);
+ return CC_INPUT_SOURCE_GET_CLASS (source)->get_label (source);
+}
+
+gboolean
+cc_input_source_matches (CcInputSource *source,
+ CcInputSource *source2)
+{
+ g_return_val_if_fail (CC_IS_INPUT_SOURCE (source), FALSE);
+ return CC_INPUT_SOURCE_GET_CLASS (source)->matches (source, source2);
+}
+
+const gchar *
+cc_input_source_get_layout (CcInputSource *source)
+{
+ g_return_val_if_fail (CC_IS_INPUT_SOURCE (source), NULL);
+ return CC_INPUT_SOURCE_GET_CLASS (source)->get_layout (source);
+}
+
+const gchar *
+cc_input_source_get_layout_variant (CcInputSource *source)
+{
+ g_return_val_if_fail (CC_IS_INPUT_SOURCE (source), NULL);
+ return CC_INPUT_SOURCE_GET_CLASS (source)->get_layout_variant (source);
+}
diff --git a/panels/region/cc-input-source.h b/panels/region/cc-input-source.h
new file mode 100644
index 000000000..5b7865d5c
--- /dev/null
+++ b/panels/region/cc-input-source.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright © 2018 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define CC_TYPE_INPUT_SOURCE (cc_input_source_get_type ())
+G_DECLARE_DERIVABLE_TYPE (CcInputSource, cc_input_source, CC, INPUT_SOURCE, GObject)
+
+struct _CcInputSourceClass
+{
+ GObjectClass parent_class;
+
+ gchar* (*get_label) (CcInputSource *source);
+ gboolean (*matches) (CcInputSource *source,
+ CcInputSource *source2);
+ const gchar* (*get_layout) (CcInputSource *source);
+ const gchar* (*get_layout_variant) (CcInputSource *source);
+};
+
+void cc_input_source_emit_label_changed (CcInputSource *source);
+
+gchar *cc_input_source_get_label (CcInputSource *source);
+
+gboolean cc_input_source_matches (CcInputSource *source,
+ CcInputSource *source2);
+
+const gchar *cc_input_source_get_layout (CcInputSource *source);
+
+const gchar *cc_input_source_get_layout_variant (CcInputSource *source);
+
+G_END_DECLS
diff --git a/panels/region/cc-region-panel.c b/panels/region/cc-region-panel.c
index 2c6b29e46..5c9cb50fd 100644
--- a/panels/region/cc-region-panel.c
+++ b/panels/region/cc-region-panel.c
@@ -33,6 +33,8 @@
#include "cc-format-chooser.h"
#include "cc-input-chooser.h"
#include "cc-input-row.h"
+#include "cc-input-source-ibus.h"
+#include "cc-input-source-xkb.h"
#include "cc-common-language.h"
@@ -42,7 +44,6 @@
#ifdef HAVE_IBUS
#include <ibus.h>
-#include "cc-ibus-utils.h"
#endif
#include <act/act.h>
@@ -53,9 +54,6 @@
#define GNOME_SYSTEM_LOCALE_DIR "org.gnome.system.locale"
#define KEY_REGION "region"
-#define INPUT_SOURCE_TYPE_XKB "xkb"
-#define INPUT_SOURCE_TYPE_IBUS "ibus"
-
#define DEFAULT_LOCALE "en_US.utf-8"
struct _CcRegionPanel {
@@ -639,20 +637,20 @@ update_ibus_active_sources (CcRegionPanel *self)
rows = gtk_container_get_children (GTK_CONTAINER (self->input_list));
for (l = rows; l; l = l->next) {
CcInputRow *row;
+ CcInputSourceIBus *source;
IBusEngineDesc *engine_desc;
if (!CC_IS_INPUT_ROW (l->data))
continue;
row = CC_INPUT_ROW (l->data);
- if (g_strcmp0 (cc_input_row_get_input_type (row), INPUT_SOURCE_TYPE_IBUS) != 0)
+ if (!CC_IS_INPUT_SOURCE_IBUS (cc_input_row_get_source (row)))
continue;
+ source = CC_INPUT_SOURCE_IBUS (cc_input_row_get_source (row));
- engine_desc = g_hash_table_lookup (self->ibus_engines, cc_input_row_get_id (row));
- if (engine_desc) {
- g_autofree gchar *display_name = engine_get_display_name (engine_desc);
- cc_input_row_set_label (row, display_name);
- }
+ engine_desc = g_hash_table_lookup (self->ibus_engines, cc_input_source_ibus_get_engine_name
(source));
+ if (engine_desc != NULL)
+ cc_input_source_ibus_set_engine_desc (source, engine_desc);
}
}
@@ -717,34 +715,17 @@ maybe_start_ibus (void)
NULL));
}
-static GDesktopAppInfo *
-setup_app_info_for_id (const gchar *id)
-{
- g_autofree gchar *desktop_file_name = NULL;
- g_auto(GStrv) strv = NULL;
-
- strv = g_strsplit (id, ":", 2);
- desktop_file_name = g_strdup_printf ("ibus-setup-%s.desktop", strv[0]);
-
- return g_desktop_app_info_new (desktop_file_name);
-}
#endif
static void
-add_input_row (CcRegionPanel *self,
- const gchar *type,
- const gchar *id,
- const gchar *name,
- GDesktopAppInfo *app_info)
+add_input_row (CcRegionPanel *self, CcInputSource *source)
{
CcInputRow *row;
gtk_widget_set_visible (GTK_WIDGET (self->no_inputs_row), FALSE);
- row = cc_input_row_new (type, id, app_info);
+ row = cc_input_row_new (source);
gtk_widget_show (GTK_WIDGET (row));
- cc_input_row_set_label (row, name);
- cc_input_row_set_is_input_method (row, strcmp (type, INPUT_SOURCE_TYPE_IBUS) == 0);
gtk_container_add (GTK_CONTAINER (self->input_list), GTK_WIDGET (row));
cc_list_box_adjust_scrolling (self->input_list);
@@ -764,37 +745,25 @@ add_input_sources (CcRegionPanel *self,
g_variant_iter_init (&iter, sources);
while (g_variant_iter_next (&iter, "(&s&s)", &type, &id)) {
- g_autoptr(GDesktopAppInfo) app_info = NULL;
- g_autofree gchar *display_name = NULL;
-
- if (g_str_equal (type, INPUT_SOURCE_TYPE_XKB)) {
- const gchar *name;
+ g_autoptr(CcInputSource) source = NULL;
- gnome_xkb_info_get_layout_info (self->xkb_info, id, &name, NULL, NULL, NULL);
- if (!name) {
- g_warning ("Couldn't find XKB input source '%s'", id);
- continue;
- }
- display_name = g_strdup (name);
- type = INPUT_SOURCE_TYPE_XKB;
+ if (g_str_equal (type, "xkb")) {
+ source = CC_INPUT_SOURCE (cc_input_source_xkb_new_from_id (self->xkb_info, id));
+ } else if (g_str_equal (type, "ibus")) {
+ source = CC_INPUT_SOURCE (cc_input_source_ibus_new (id));
#ifdef HAVE_IBUS
- } else if (g_str_equal (type, INPUT_SOURCE_TYPE_IBUS)) {
- IBusEngineDesc *engine_desc = NULL;
-
- if (self->ibus_engines)
- engine_desc = g_hash_table_lookup (self->ibus_engines, id);
- if (engine_desc)
- display_name = engine_get_display_name (engine_desc);
-
- app_info = setup_app_info_for_id (id);
- type = INPUT_SOURCE_TYPE_IBUS;
+ if (self->ibus_engines) {
+ IBusEngineDesc *engine_desc = g_hash_table_lookup (self->ibus_engines, id);
+ if (engine_desc != NULL)
+ cc_input_source_ibus_set_engine_desc (CC_INPUT_SOURCE_IBUS (source),
engine_desc);
+ }
#endif
} else {
g_warning ("Unhandled input source type '%s'", type);
continue;
}
- add_input_row (self, type, id, display_name ? display_name : id, app_info);
+ add_input_row (self, source);
}
}
@@ -821,25 +790,25 @@ clear_input_sources (CcRegionPanel *self)
cc_list_box_adjust_scrolling (self->input_list);
}
-static void
-select_by_id (GtkWidget *row,
- gpointer data)
+static CcInputRow *
+get_row_by_source (CcRegionPanel *self, CcInputSource *source)
{
- const gchar *id = data;
+ g_autoptr(GList) list = NULL;
+ GList *l;
- if (!CC_IS_INPUT_ROW (row))
- return;
+ list = gtk_container_get_children (GTK_CONTAINER (self->input_list));
+ for (l = list; l; l = l->next) {
+ CcInputRow *row;
- if (g_strcmp0 (cc_input_row_get_id (CC_INPUT_ROW (row)), id) == 0)
- gtk_list_box_select_row (GTK_LIST_BOX (gtk_widget_get_parent (row)), GTK_LIST_BOX_ROW (row));
-}
+ if (!CC_IS_INPUT_ROW (l->data))
+ continue;
+ row = CC_INPUT_ROW (l->data);
-static void
-select_input (CcRegionPanel *self,
- const gchar *id)
-{
- gtk_container_foreach (GTK_CONTAINER (self->input_list),
- select_by_id, (gpointer)id);
+ if (cc_input_source_matches (source, cc_input_row_get_source (row)))
+ return row;
+ }
+
+ return NULL;
}
static void
@@ -848,18 +817,20 @@ input_sources_changed (GSettings *settings,
CcRegionPanel *self)
{
CcInputRow *selected;
- g_autofree gchar *id = NULL;
+ g_autoptr(CcInputSource) source = NULL;
selected = CC_INPUT_ROW (gtk_list_box_get_selected_row (self->input_list));
if (selected)
- id = g_strdup (cc_input_row_get_id (selected));
+ source = g_object_ref (cc_input_row_get_source (selected));
clear_input_sources (self);
add_input_sources_from_settings (self);
- if (id)
- select_input (self, id);
+ if (source != NULL) {
+ CcInputRow *row = get_row_by_source (self, source);
+ if (row != NULL)
+ gtk_list_box_select_row (GTK_LIST_BOX (self->input_list), GTK_LIST_BOX_ROW (row));
+ }
}
-
static void
update_buttons (CcRegionPanel *self)
{
@@ -878,13 +849,11 @@ update_buttons (CcRegionPanel *self)
gtk_widget_set_sensitive (GTK_WIDGET (self->move_up_input_button), FALSE);
gtk_widget_set_sensitive (GTK_WIDGET (self->move_down_input_button), FALSE);
} else {
- GDesktopAppInfo *app_info;
gint index;
- app_info = cc_input_row_get_app_info (selected);
index = gtk_list_box_row_get_index (GTK_LIST_BOX_ROW (selected));
- gtk_widget_set_visible (GTK_WIDGET (self->show_config_button), app_info != NULL);
+ gtk_widget_set_visible (GTK_WIDGET (self->show_config_button), CC_IS_INPUT_SOURCE_IBUS
(cc_input_row_get_source (selected)));
gtk_widget_set_sensitive (GTK_WIDGET (self->show_layout_button), TRUE);
gtk_widget_set_sensitive (GTK_WIDGET (self->remove_input_button), n_rows > 1);
gtk_widget_set_sensitive (GTK_WIDGET (self->move_up_input_button), index > 1);
@@ -906,12 +875,20 @@ set_input_settings (CcRegionPanel *self)
list = gtk_container_get_children (GTK_CONTAINER (self->input_list));
for (l = list; l; l = l->next) {
CcInputRow *row;
+ CcInputSource *source;
if (!CC_IS_INPUT_ROW (l->data))
continue;
-
row = CC_INPUT_ROW (l->data);
- g_variant_builder_add (&builder, "(ss)", cc_input_row_get_input_type (row),
cc_input_row_get_id (row));
+ source = cc_input_row_get_source (row);
+
+ if (CC_IS_INPUT_SOURCE_XKB (source)) {
+ g_autofree gchar *id = cc_input_source_xkb_get_id (CC_INPUT_SOURCE_XKB (source));
+ g_variant_builder_add (&builder, "(ss)", "xkb", id);
+ } else if (CC_IS_INPUT_SOURCE_IBUS (source)) {
+ g_variant_builder_add (&builder, "(ss)", "ibus",
+ cc_input_source_ibus_get_engine_name (CC_INPUT_SOURCE_IBUS
(source)));
+ }
}
g_settings_set_value (self->input_settings, KEY_INPUT_SOURCES, g_variant_builder_end (&builder));
@@ -932,33 +909,10 @@ update_input (CcRegionPanel *self)
}
}
-static gboolean
-input_source_already_added (CcRegionPanel *self,
- const gchar *id)
-{
- g_autoptr(GList) list = NULL;
- GList *l;
-
- list = gtk_container_get_children (GTK_CONTAINER (self->input_list));
- for (l = list; l; l = l->next) {
- if (!CC_IS_INPUT_ROW (l->data))
- continue;
-
- if (g_str_equal (id, cc_input_row_get_id (CC_INPUT_ROW (l->data)))) {
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
static void
show_input_chooser (CcRegionPanel *self)
{
CcInputChooser *chooser;
- g_autofree gchar *type = NULL;
- g_autofree gchar *id = NULL;
- g_autofree gchar *name = NULL;
chooser = cc_input_chooser_new (self->login,
self->xkb_info,
@@ -970,27 +924,15 @@ show_input_chooser (CcRegionPanel *self)
);
gtk_window_set_transient_for (GTK_WINDOW (chooser), GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET
(self))));
- if (gtk_dialog_run (GTK_DIALOG (chooser)) != GTK_RESPONSE_OK) {
- gtk_widget_destroy (GTK_WIDGET (chooser));
- return;
- }
-
- if (cc_input_chooser_get_selected (chooser, &type, &id, &name) &&
- !input_source_already_added (self, id)) {
- g_autoptr(GDesktopAppInfo) app_info = NULL;
+ if (gtk_dialog_run (GTK_DIALOG (chooser)) == GTK_RESPONSE_OK) {
+ CcInputSource *source;
- if (g_str_equal (type, INPUT_SOURCE_TYPE_IBUS)) {
-#ifdef HAVE_IBUS
- app_info = setup_app_info_for_id (id);
-#endif
- } else {
- g_free (type);
- type = g_strdup (INPUT_SOURCE_TYPE_XKB);
+ source = cc_input_chooser_get_source (chooser);
+ if (source != NULL && get_row_by_source (self, source) == NULL) {
+ add_input_row (self, source);
+ update_buttons (self);
+ update_input (self);
}
-
- add_input_row (self, type, id, name, app_info);
- update_buttons (self);
- update_input (self);
}
gtk_widget_destroy (GTK_WIDGET (chooser));
}
@@ -1163,23 +1105,26 @@ static void
show_selected_settings (CcRegionPanel *self)
{
CcInputRow *selected;
+ CcInputSourceIBus *source;
g_autoptr(GdkAppLaunchContext) ctx = NULL;
- GDesktopAppInfo *app_info;
+ g_autoptr(GDesktopAppInfo) app_info = NULL;
g_autoptr(GError) error = NULL;
selected = CC_INPUT_ROW (gtk_list_box_get_selected_row (self->input_list));
if (selected == NULL)
return;
+ g_return_if_fail (CC_IS_INPUT_SOURCE_IBUS (cc_input_row_get_source (selected)));
+ source = CC_INPUT_SOURCE_IBUS (cc_input_row_get_source (selected));
- app_info = cc_input_row_get_app_info (selected);
- if (app_info == NULL)
+ app_info = cc_input_source_ibus_get_app_info (source);
+ if (app_info == NULL)
return;
ctx = gdk_display_get_app_launch_context (gdk_display_get_default ());
gdk_app_launch_context_set_timestamp (ctx, gtk_get_current_event_time ());
g_app_launch_context_setenv (G_APP_LAUNCH_CONTEXT (ctx),
- "IBUS_ENGINE_NAME", cc_input_row_get_id (selected));
+ "IBUS_ENGINE_NAME", cc_input_source_ibus_get_engine_name (source));
if (!g_app_info_launch (G_APP_INFO (app_info), NULL, G_APP_LAUNCH_CONTEXT (ctx), &error))
g_warning ("Failed to launch input source setup: %s", error->message);
@@ -1189,49 +1134,21 @@ static void
show_selected_layout (CcRegionPanel *self)
{
CcInputRow *selected;
- const gchar *type, *id;
- const gchar *layout;
- const gchar *variant;
+ CcInputSource *source;
+ const gchar *layout, *layout_variant;
g_autofree gchar *commandline = NULL;
selected = CC_INPUT_ROW (gtk_list_box_get_selected_row (self->input_list));
if (selected == NULL)
return;
+ source = cc_input_row_get_source (selected);
- type = cc_input_row_get_input_type (selected);
- id = cc_input_row_get_id (selected);
- if (g_str_equal (type, INPUT_SOURCE_TYPE_XKB)) {
- gnome_xkb_info_get_layout_info (self->xkb_info,
- id, NULL, NULL,
- &layout, &variant);
+ layout = cc_input_source_get_layout (source);
+ layout_variant = cc_input_source_get_layout_variant (source);
- if (!layout || !layout[0]) {
- g_warning ("Couldn't find XKB input source '%s'", id);
- return;
- }
-#ifdef HAVE_IBUS
- } else if (g_str_equal (type, INPUT_SOURCE_TYPE_IBUS)) {
- IBusEngineDesc *engine_desc = NULL;
-
- if (self->ibus_engines)
- engine_desc = g_hash_table_lookup (self->ibus_engines, id);
-
- if (engine_desc) {
- layout = ibus_engine_desc_get_layout (engine_desc);
- variant = ibus_engine_desc_get_layout_variant (engine_desc);
- } else {
- g_warning ("Couldn't find IBus input source '%s'", id);
- return;
- }
-#endif
- } else {
- g_warning ("Unhandled input source type '%s'", type);
- return;
- }
-
- if (variant && variant[0])
+ if (layout_variant && layout_variant[0])
commandline = g_strdup_printf ("gkbd-keyboard-display -l \"%s\t%s\"",
- layout, variant);
+ layout, layout_variant);
else
commandline = g_strdup_printf ("gkbd-keyboard-display -l %s",
layout);
@@ -1440,17 +1357,8 @@ add_input_sources_from_localed (CcRegionPanel *self)
n = 0;
for (i = 0; i < n && layouts[i][0]; i++) {
- const gchar *name;
- g_autofree gchar *id = NULL;
-
- if (variants && variants[i] && variants[i][0])
- id = g_strdup_printf ("%s+%s", layouts[i], variants[i]);
- else
- id = g_strdup (layouts[i]);
-
- gnome_xkb_info_get_layout_info (self->xkb_info, id, &name, NULL, NULL, NULL);
-
- add_input_row (self, INPUT_SOURCE_TYPE_XKB, id, name ? name : id, NULL);
+ g_autoptr(CcInputSourceXkb) source = cc_input_source_xkb_new (self->xkb_info, layouts[i],
variants[i]);
+ add_input_row (self, CC_INPUT_SOURCE (source));
}
gtk_widget_set_visible (GTK_WIDGET (self->no_inputs_row), n == 0);
}
@@ -1504,16 +1412,20 @@ set_localed_input (CcRegionPanel *self)
list = gtk_container_get_children (GTK_CONTAINER (self->input_list));
for (li = list; li; li = li->next) {
CcInputRow *row;
+ CcInputSourceXkb *source;
+ g_autofree gchar *id = NULL;
const gchar *l, *v;
if (!CC_IS_INPUT_ROW (li->data))
continue;
row = CC_INPUT_ROW (li->data);
- if (g_str_equal (cc_input_row_get_input_type (row), INPUT_SOURCE_TYPE_IBUS))
+ if (!CC_IS_INPUT_SOURCE_XKB (cc_input_row_get_source (row)))
continue;
+ source = CC_INPUT_SOURCE_XKB (cc_input_row_get_source (row));
- if (gnome_xkb_info_get_layout_info (self->xkb_info, cc_input_row_get_id (row), NULL, NULL,
&l, &v)) {
+ id = cc_input_source_xkb_get_id (source);
+ if (gnome_xkb_info_get_layout_info (self->xkb_info, id, NULL, NULL, &l, &v)) {
if (layouts->str[0]) {
g_string_append_c (layouts, ',');
g_string_append_c (variants, ',');
diff --git a/panels/region/meson.build b/panels/region/meson.build
index 57b407597..c0b886dd4 100644
--- a/panels/region/meson.build
+++ b/panels/region/meson.build
@@ -23,6 +23,9 @@ sources = files(
'cc-ibus-utils.c',
'cc-input-chooser.c',
'cc-input-row.c',
+ 'cc-input-source.c',
+ 'cc-input-source-ibus.c',
+ 'cc-input-source-xkb.c',
)
resource_data = files(
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]