mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-25 11:22:55 +00:00
1527 lines
56 KiB
C++
1527 lines
56 KiB
C++
![]() |
/*
|
||
|
* Copyright (C) 2011-2012 Ni Hui <shuizhuyuanluo@126.com>
|
||
|
* Copyright (C) 2013-2014 Weng Xuetian <wengxt@gmail.com>
|
||
|
*
|
||
|
* 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) version 3 or any later version
|
||
|
* accepted by the membership of KDE e.V. (or its successor approved
|
||
|
* by the membership of KDE e.V.), which shall act as a proxy
|
||
|
* defined in Section 14 of version 3 of the license.
|
||
|
*
|
||
|
* 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 <locale.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <ibus.h>
|
||
|
#include <string>
|
||
|
#include <QByteArray>
|
||
|
#include <QPair>
|
||
|
#include <QStringList>
|
||
|
#include <QDebug>
|
||
|
#include "panel.h"
|
||
|
#include "propertymanager.h"
|
||
|
#include "enginemanager.h"
|
||
|
#include "xkblayoutmanager.h"
|
||
|
#include "app.h"
|
||
|
#include "gtkaccelparse_p.h"
|
||
|
|
||
|
#ifndef DBUS_ERROR_FAILED
|
||
|
#define DBUS_ERROR_FAILED "org.freedesktop.DBus.Error.Failed"
|
||
|
#endif /* DBUS_ERROR_FAILED */
|
||
|
|
||
|
typedef struct _IBusPanelImpanelClass IBusPanelImpanelClass;
|
||
|
|
||
|
struct _IBusPanelImpanel {
|
||
|
IBusPanelService parent;
|
||
|
IBusBus *bus;
|
||
|
GDBusConnection *conn;
|
||
|
PropertyManager* propManager;
|
||
|
EngineManager* engineManager;
|
||
|
XkbLayoutManager* xkbLayoutManager;
|
||
|
App* app;
|
||
|
gboolean useSystemKeyboardLayout;
|
||
|
int selected;
|
||
|
};
|
||
|
|
||
|
struct _IBusPanelImpanelClass {
|
||
|
IBusPanelServiceClass parent;
|
||
|
};
|
||
|
|
||
|
|
||
|
static void
|
||
|
impanel_set_engine(IBusPanelImpanel* impanel, const char* name);
|
||
|
|
||
|
|
||
|
static QByteArray
|
||
|
ibus_property_to_propstr (IBusProperty *property,
|
||
|
gboolean useSymbol = FALSE);
|
||
|
|
||
|
static QByteArray
|
||
|
ibus_engine_desc_to_logo_propstr(IBusEngineDesc* engine);
|
||
|
|
||
|
void
|
||
|
impanel_update_logo_by_engine(IBusPanelImpanel* impanel, IBusEngineDesc* engine_desc)
|
||
|
{
|
||
|
if (!impanel->conn) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
QByteArray propstr = ibus_engine_desc_to_logo_propstr(engine_desc);
|
||
|
|
||
|
g_dbus_connection_emit_signal (impanel->conn,
|
||
|
NULL, "/kimpanel", "org.kde.kimpanel.inputmethod", "UpdateProperty",
|
||
|
(g_variant_new ("(s)", propstr.constData())),
|
||
|
NULL);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
ibus_panel_impanel_set_bus (IBusPanelImpanel *impanel,
|
||
|
IBusBus *bus)
|
||
|
{
|
||
|
impanel->bus = bus;
|
||
|
}
|
||
|
|
||
|
void ibus_panel_impanel_set_app(IBusPanelImpanel* impanel, App* app)
|
||
|
{
|
||
|
impanel->app = app;
|
||
|
}
|
||
|
|
||
|
void ibus_panel_impanel_accept(IBusPanelImpanel* impanel)
|
||
|
{
|
||
|
if (impanel->selected >= 0 && static_cast<size_t>(impanel->selected) < impanel->engineManager->length()) {
|
||
|
impanel_set_engine(impanel, ibus_engine_desc_get_name(impanel->engineManager->engines()[impanel->selected]));
|
||
|
impanel->selected = -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ibus_panel_impanel_navigate(IBusPanelImpanel* impanel, gboolean start, gboolean forward)
|
||
|
{
|
||
|
if (start) {
|
||
|
impanel->selected = -1;
|
||
|
}
|
||
|
|
||
|
if (impanel->engineManager->length() < 2) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
IBusEngineDesc* engine_desc = NULL;
|
||
|
if (impanel->selected < 0) {
|
||
|
engine_desc = ibus_bus_get_global_engine(impanel->bus);
|
||
|
} else if (static_cast<size_t>(impanel->selected) < impanel->engineManager->length()) {
|
||
|
engine_desc = impanel->engineManager->engines()[impanel->selected];
|
||
|
}
|
||
|
|
||
|
if (!engine_desc) {
|
||
|
engine_desc = impanel->engineManager->engines()[0];
|
||
|
}
|
||
|
|
||
|
if (engine_desc) {
|
||
|
const char* name = impanel->engineManager->navigate(engine_desc, forward);
|
||
|
impanel->selected = impanel->engineManager->getIndexByName(name);
|
||
|
} else {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (impanel->selected >= 0 && static_cast<size_t>(impanel->selected) < impanel->engineManager->length()) {
|
||
|
engine_desc = impanel->engineManager->engines()[impanel->selected];
|
||
|
|
||
|
impanel_update_logo_by_engine(impanel, engine_desc);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ibus_panel_impanel_move_next(IBusPanelImpanel* impanel)
|
||
|
{
|
||
|
if (impanel->engineManager->length() >= 2) {
|
||
|
impanel_set_engine(impanel, ibus_engine_desc_get_name(impanel->engineManager->engines()[1]));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
static GDBusNodeInfo *introspection_data = NULL;
|
||
|
|
||
|
static guint owner_id;
|
||
|
|
||
|
static const gchar introspection_xml[] =
|
||
|
"<node>"
|
||
|
" <interface name='org.kde.kimpanel.inputmethod'>"
|
||
|
" <signal name='Enable'>"
|
||
|
" <arg type='b' name='enable'/>"
|
||
|
" </signal>"
|
||
|
" <signal name='RegisterProperties'>"
|
||
|
" <arg type='as' name='prop'/>"
|
||
|
" </signal>"
|
||
|
" <signal name='UpdateProperty'>"
|
||
|
" <arg type='s' name='prop'/>"
|
||
|
" </signal>"
|
||
|
" <signal name='RemoveProperty'>"
|
||
|
" <arg type='s' name='prop'/>"
|
||
|
" </signal>"
|
||
|
" <signal name='ShowAux'>"
|
||
|
" <arg type='b' name='toshow'/>"
|
||
|
" </signal>"
|
||
|
" <signal name='ShowLookupTable'>"
|
||
|
" <arg type='b' name='toshow'/>"
|
||
|
" </signal>"
|
||
|
" <signal name='ShowPreedit'>"
|
||
|
" <arg type='b' name='toshow'/>"
|
||
|
" </signal>"
|
||
|
" <signal name='UpdateAux'>"
|
||
|
" <arg type='s' name='text'/>"
|
||
|
" <arg type='s' name='attr'/>"
|
||
|
" </signal>"
|
||
|
" <signal name='UpdateLookupTableCursor'>"
|
||
|
" <arg type='i' name='pos'/>"
|
||
|
" </signal>"
|
||
|
" <signal name='UpdateLookupTable'>"
|
||
|
" <arg type='as' name='labels'/>"
|
||
|
" <arg type='as' name='candidates'/>"
|
||
|
" <arg type='as' name='attrs'/>"
|
||
|
" <arg type='b' name='hasprev'/>"
|
||
|
" <arg type='b' name='hasnext'/>"
|
||
|
" </signal>"
|
||
|
" <signal name='UpdatePreeditCaret'>"
|
||
|
" <arg type='i' name='pos'/>"
|
||
|
" </signal>"
|
||
|
" <signal name='UpdatePreeditText'>"
|
||
|
" <arg type='s' name='text'/>"
|
||
|
" <arg type='s' name='attr'/>"
|
||
|
" </signal>"
|
||
|
" <signal name='UpdateSpotLocation'>"
|
||
|
" <arg type='i' name='x'/>"
|
||
|
" <arg type='i' name='y'/>"
|
||
|
" </signal>"
|
||
|
" <signal name='ExecMenu'>"
|
||
|
" <arg type='as' name='actions'/>"
|
||
|
" </signal>"
|
||
|
" </interface>"
|
||
|
"</node>";
|
||
|
|
||
|
/* functions prototype */
|
||
|
static void ibus_panel_impanel_class_init (IBusPanelImpanelClass *klass);
|
||
|
static void ibus_panel_impanel_init (IBusPanelImpanel *impanel);
|
||
|
static void ibus_panel_impanel_destroy (IBusPanelImpanel *impanel);
|
||
|
|
||
|
static void ibus_panel_impanel_focus_in (IBusPanelService *panel,
|
||
|
const gchar *input_context_path);
|
||
|
static void ibus_panel_impanel_focus_out (IBusPanelService *panel,
|
||
|
const gchar *input_context_path);
|
||
|
static void ibus_panel_impanel_register_properties (IBusPanelService *panel,
|
||
|
IBusPropList *prop_list);
|
||
|
static void ibus_panel_impanel_real_register_properties (IBusPanelImpanel *impanel);
|
||
|
static void ibus_panel_impanel_set_cursor_location (IBusPanelService *panel,
|
||
|
gint x,
|
||
|
gint y,
|
||
|
gint w,
|
||
|
gint h);
|
||
|
static void ibus_panel_impanel_update_auxiliary_text (IBusPanelService *panel,
|
||
|
IBusText *text,
|
||
|
gboolean visible);
|
||
|
static void ibus_panel_impanel_update_lookup_table (IBusPanelService *panel,
|
||
|
IBusLookupTable *lookup_table,
|
||
|
gboolean visible);
|
||
|
static void ibus_panel_impanel_update_preedit_text (IBusPanelService *panel,
|
||
|
IBusText *text,
|
||
|
guint cursor_pos,
|
||
|
gboolean visible);
|
||
|
static void ibus_panel_impanel_update_property (IBusPanelService *panel,
|
||
|
IBusProperty *prop);
|
||
|
static void ibus_panel_impanel_cursor_down_lookup_table (IBusPanelService *panel);
|
||
|
static void ibus_panel_impanel_cursor_up_lookup_table (IBusPanelService *panel);
|
||
|
static void ibus_panel_impanel_hide_auxiliary_text (IBusPanelService *panel);
|
||
|
static void ibus_panel_impanel_hide_language_bar (IBusPanelService *panel);
|
||
|
static void ibus_panel_impanel_hide_lookup_table (IBusPanelService *panel);
|
||
|
static void ibus_panel_impanel_hide_preedit_text (IBusPanelService *panel);
|
||
|
static void ibus_panel_impanel_page_down_lookup_table (IBusPanelService *panel);
|
||
|
static void ibus_panel_impanel_page_up_lookup_table (IBusPanelService *panel);
|
||
|
static void ibus_panel_impanel_reset (IBusPanelService *panel);
|
||
|
static void ibus_panel_impanel_show_auxiliary_text (IBusPanelService *panel);
|
||
|
static void ibus_panel_impanel_show_language_bar (IBusPanelService *panel);
|
||
|
static void ibus_panel_impanel_show_lookup_table (IBusPanelService *panel);
|
||
|
static void ibus_panel_impanel_show_preedit_text (IBusPanelService *panel);
|
||
|
static void ibus_panel_impanel_start_setup (IBusPanelService *panel);
|
||
|
static void ibus_panel_impanel_state_changed (IBusPanelService *panel);
|
||
|
|
||
|
/* impanel signal handler function */
|
||
|
static void ibus_panel_impanel_exec_im_menu (IBusPanelImpanel* impanel);
|
||
|
static void ibus_panel_impanel_exec_menu (IBusPanelImpanel* impanel, IBusPropList* prop_list);
|
||
|
|
||
|
static const char prop_sep[] = ":";
|
||
|
|
||
|
static QByteArray
|
||
|
ibus_property_args_to_propstr (const char *key,
|
||
|
const char *label,
|
||
|
const char *icon,
|
||
|
const char *tooltip)
|
||
|
{
|
||
|
QByteArray propstr("/IBus/");
|
||
|
QByteArray str(key);
|
||
|
str.replace(':', '!');
|
||
|
|
||
|
App* app = static_cast<App*>(qApp);
|
||
|
|
||
|
propstr += str;
|
||
|
propstr += prop_sep;
|
||
|
propstr += QByteArray(label).replace(':', '-').constData();
|
||
|
propstr += prop_sep;
|
||
|
propstr += app->normalizeIconName(QByteArray(icon).replace(':', '-'));
|
||
|
propstr += prop_sep;
|
||
|
propstr += QByteArray(tooltip).replace(':', '-').constData();
|
||
|
|
||
|
return propstr;
|
||
|
}
|
||
|
|
||
|
static QByteArray
|
||
|
ibus_engine_desc_to_logo_propstr(IBusEngineDesc* engine)
|
||
|
{
|
||
|
const gchar* label = "IBus";
|
||
|
const gchar* tooltip = "";
|
||
|
const gchar* icon = "input-keyboard";
|
||
|
|
||
|
gchar xkbLabel[3];
|
||
|
if (engine) {
|
||
|
const gchar* iconname = ibus_engine_desc_get_icon(engine);
|
||
|
if (iconname && iconname[0]) {
|
||
|
icon = iconname;
|
||
|
}
|
||
|
|
||
|
if (strncmp("xkb:", ibus_engine_desc_get_name(engine), 4) == 0) {
|
||
|
strncpy(xkbLabel, ibus_engine_desc_get_name(engine) + 4, 2);
|
||
|
xkbLabel[2] = 0;
|
||
|
int i = 0;
|
||
|
while (xkbLabel[i]) {
|
||
|
if (xkbLabel[i] == ':') {
|
||
|
xkbLabel[i] = 0;
|
||
|
}
|
||
|
i++;
|
||
|
}
|
||
|
label = xkbLabel;
|
||
|
icon = "";
|
||
|
}
|
||
|
|
||
|
const gchar* longname = ibus_engine_desc_get_longname(engine);
|
||
|
if (longname && longname[0]) {
|
||
|
tooltip = longname;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return ibus_property_args_to_propstr("Logo",
|
||
|
label,
|
||
|
icon,
|
||
|
tooltip);
|
||
|
}
|
||
|
|
||
|
static QByteArray
|
||
|
ibus_property_to_propstr (IBusProperty *property,
|
||
|
gboolean useSymbol)
|
||
|
{
|
||
|
const gchar* label = NULL;
|
||
|
const gchar* tooltip = ibus_text_get_text (ibus_property_get_tooltip (property));
|
||
|
const gchar* icon = ibus_property_get_icon (property);
|
||
|
|
||
|
if (useSymbol) {
|
||
|
label = ibus_text_get_text(ibus_property_get_symbol (property));
|
||
|
if (!label || label[0] == '\0') {
|
||
|
label = ibus_text_get_text(ibus_property_get_label(property));
|
||
|
}
|
||
|
} else {
|
||
|
label = ibus_text_get_text(ibus_property_get_label(property));
|
||
|
}
|
||
|
|
||
|
return ibus_property_args_to_propstr(ibus_property_get_key (property),
|
||
|
label,
|
||
|
icon,
|
||
|
tooltip);
|
||
|
}
|
||
|
|
||
|
static QByteArray
|
||
|
ibus_engine_desc_args_to_propstr (const char *name,
|
||
|
const char *language,
|
||
|
const char *longname,
|
||
|
const char *icon,
|
||
|
const char *description)
|
||
|
{
|
||
|
QByteArray propstr("/IBus/Engine/");
|
||
|
QByteArray data(name);
|
||
|
data.replace(':', '!');
|
||
|
propstr += data;
|
||
|
propstr += prop_sep;
|
||
|
if (language) {
|
||
|
propstr += language;
|
||
|
propstr += " - ";
|
||
|
}
|
||
|
propstr += longname;
|
||
|
propstr += prop_sep;
|
||
|
propstr += icon;
|
||
|
propstr += prop_sep;
|
||
|
propstr += description;
|
||
|
return propstr;
|
||
|
}
|
||
|
|
||
|
static QByteArray
|
||
|
ibus_engine_desc_to_propstr (IBusEngineDesc *engine_desc)
|
||
|
{
|
||
|
return ibus_engine_desc_args_to_propstr(ibus_engine_desc_get_name(engine_desc),
|
||
|
ibus_engine_desc_get_language(engine_desc),
|
||
|
ibus_engine_desc_get_longname(engine_desc),
|
||
|
ibus_engine_desc_get_icon(engine_desc),
|
||
|
ibus_engine_desc_get_description(engine_desc));
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
impanel_get_default_engine(IBusPanelImpanel* impanel, char*** pengine_names, gsize* plen)
|
||
|
{
|
||
|
GList* engines = ibus_bus_list_engines(impanel->bus);
|
||
|
if (!engines) {
|
||
|
*pengine_names = g_new0 (gchar*, 2);
|
||
|
*plen = 1;
|
||
|
(*pengine_names)[0] = g_strdup ("xkb:us::eng");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
QList<QByteArray> engineList;
|
||
|
impanel->xkbLayoutManager->getLayout();
|
||
|
QStringList layouts = impanel->xkbLayoutManager->defaultLayout().split(',');
|
||
|
QStringList variants = impanel->xkbLayoutManager->defaultVariant().split(',');
|
||
|
|
||
|
for (int i = 0; i < layouts.size(); i ++ ) {
|
||
|
QString variant;
|
||
|
if (i < variants.size()) {
|
||
|
variant = variants[i];
|
||
|
}
|
||
|
|
||
|
for (GList* engine = g_list_first(engines); engine != NULL ;
|
||
|
engine = g_list_next(engine)) {
|
||
|
IBusEngineDesc* desc = IBUS_ENGINE_DESC (engine->data);
|
||
|
QByteArray name = ibus_engine_desc_get_name(desc);
|
||
|
if (!name.startsWith("xkb:")) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (QLatin1String(ibus_engine_desc_get_layout(desc)) == layouts[i] &&
|
||
|
QLatin1String(ibus_engine_desc_get_layout_variant(desc)) == variant) {
|
||
|
engineList << name;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
const char* locale = setlocale(LC_CTYPE, NULL);
|
||
|
if (!locale) {
|
||
|
locale = "C";
|
||
|
}
|
||
|
|
||
|
QStringList localeList = QString(locale).split('.');
|
||
|
QString lang = localeList.size() > 0 ? localeList[0] : "";
|
||
|
|
||
|
bool added = false;
|
||
|
for (GList* engine = g_list_first(engines); engine != NULL ;
|
||
|
engine = g_list_next(engine)) {
|
||
|
IBusEngineDesc* desc = IBUS_ENGINE_DESC (engine->data);
|
||
|
QByteArray name = ibus_engine_desc_get_name(desc);
|
||
|
if (name.startsWith("xkb:")) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (QLatin1String(ibus_engine_desc_get_language(desc)) == lang &&
|
||
|
ibus_engine_desc_get_rank(desc) > 0) {
|
||
|
engineList << name;
|
||
|
added = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!added) {
|
||
|
localeList = QString(lang).split('_');
|
||
|
QString lang = localeList.size() > 0 ? localeList[0] : "";
|
||
|
|
||
|
for (GList* engine = g_list_first(engines); engine != NULL ;
|
||
|
engine = g_list_next(engine)) {
|
||
|
IBusEngineDesc* desc = IBUS_ENGINE_DESC (engine->data);
|
||
|
QByteArray name = ibus_engine_desc_get_name(desc);
|
||
|
if (name.startsWith("xkb:")) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (QLatin1String(ibus_engine_desc_get_language(desc)) == lang &&
|
||
|
ibus_engine_desc_get_rank(desc) > 0) {
|
||
|
engineList << name;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (GList* engine = g_list_first(engines); engine != NULL ;
|
||
|
engine = g_list_next(engine)) {
|
||
|
IBusEngineDesc* desc = IBUS_ENGINE_DESC (engine->data);
|
||
|
g_object_unref(desc);
|
||
|
}
|
||
|
|
||
|
g_list_free(engines);
|
||
|
|
||
|
if (engineList.size() == 0) {
|
||
|
*pengine_names = g_new0 (gchar*, 2);
|
||
|
*plen = 1;
|
||
|
(*pengine_names)[0] = g_strdup ("xkb:us::eng");
|
||
|
return;
|
||
|
} else {
|
||
|
*pengine_names = g_new0 (gchar*, engineList.size() + 1);
|
||
|
*plen = engineList.size();
|
||
|
size_t i = 0;
|
||
|
Q_FOREACH(const QByteArray& name, engineList) {
|
||
|
(*pengine_names)[i] = g_strdup (name.constData());
|
||
|
i ++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
impanel_update_engines(IBusPanelImpanel* impanel, GVariant* var_engines) {
|
||
|
gchar** engine_names = NULL;
|
||
|
size_t len = 0;
|
||
|
if (var_engines) {
|
||
|
engine_names = g_variant_dup_strv(var_engines, &len);
|
||
|
}
|
||
|
if (len == 0) {
|
||
|
g_strfreev(engine_names);
|
||
|
engine_names = NULL;
|
||
|
}
|
||
|
|
||
|
if (!engine_names) {
|
||
|
impanel_get_default_engine(impanel, &engine_names, &len);
|
||
|
IBusConfig* config = ibus_bus_get_config(impanel->bus);
|
||
|
GVariant* var = g_variant_new_strv(engine_names, len);
|
||
|
ibus_config_set_value(config, "general", "preload_engines", var);
|
||
|
}
|
||
|
|
||
|
IBusEngineDesc** engines = ibus_bus_get_engines_by_names(impanel->bus, engine_names);
|
||
|
g_strfreev(engine_names);
|
||
|
|
||
|
impanel->engineManager->setEngines(engines);
|
||
|
|
||
|
if (engines && engines[0]) {
|
||
|
ibus_bus_set_global_engine(impanel->bus, ibus_engine_desc_get_name(engines[0]));
|
||
|
}
|
||
|
|
||
|
impanel->app->setDoGrab(len > 1);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
impanel_update_engines_order(IBusPanelImpanel* impanel, GVariant* var_engines) {
|
||
|
const gchar** engine_names = NULL;
|
||
|
size_t len = 0;
|
||
|
engine_names = g_variant_get_strv(var_engines, &len);
|
||
|
if (len == 0) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
impanel->engineManager->setOrder(engine_names, len);
|
||
|
|
||
|
if (impanel->engineManager->engines()) {
|
||
|
ibus_bus_set_global_engine(impanel->bus, ibus_engine_desc_get_name(impanel->engineManager->engines()[0]));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
impanel_update_triggers(IBusPanelImpanel* impanel, GVariant* variant) {
|
||
|
gchar** triggers = NULL;
|
||
|
size_t len = 0;
|
||
|
if (variant) {
|
||
|
triggers = g_variant_dup_strv(variant, &len);
|
||
|
}
|
||
|
if (len == 0) {
|
||
|
g_strfreev(triggers);
|
||
|
triggers = 0;
|
||
|
}
|
||
|
if (!triggers) {
|
||
|
triggers = g_new0 (gchar*, 2);
|
||
|
len = 1;
|
||
|
triggers[0] = g_strdup ("<Super>space");
|
||
|
}
|
||
|
|
||
|
QList<QPair<uint, uint> > triggersList;
|
||
|
for (size_t i = 0; i < len; i ++) {
|
||
|
guint key = 0;
|
||
|
GdkModifierType mod = (GdkModifierType) 0;
|
||
|
_gtk_accelerator_parse(triggers[i], &key, &mod);
|
||
|
if (key) {
|
||
|
triggersList << qMakePair<uint, uint>(key, (uint) mod);
|
||
|
}
|
||
|
}
|
||
|
impanel->app->setTriggerKeys(triggersList);
|
||
|
}
|
||
|
|
||
|
|
||
|
static void
|
||
|
impanel_update_use_system_keyboard_layout(IBusPanelImpanel* impanel, GVariant* variant) {
|
||
|
impanel->useSystemKeyboardLayout = g_variant_get_boolean(variant);
|
||
|
}
|
||
|
static void
|
||
|
impanel_update_use_global_engine(IBusPanelImpanel* impanel, GVariant* variant) {
|
||
|
impanel->engineManager->setUseGlobalEngine(g_variant_get_boolean(variant));
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
impanel_update_latin_layouts(IBusPanelImpanel* impanel, GVariant* variant) {
|
||
|
if (!variant) {
|
||
|
return;
|
||
|
}
|
||
|
gsize length;
|
||
|
const gchar** variants = g_variant_get_strv(variant, &length);
|
||
|
|
||
|
impanel->xkbLayoutManager->setLatinLayouts(variants, length);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
impanel_config_value_changed_callback (IBusConfig* config, const gchar* section, const gchar* name, GVariant* value, gpointer user_data)
|
||
|
{
|
||
|
Q_UNUSED(config);
|
||
|
IBusPanelImpanel* impanel = ((IBusPanelImpanel *)user_data);
|
||
|
|
||
|
if (g_strcmp0(section, "general") == 0 && g_strcmp0(name, "preload_engines") == 0) {
|
||
|
impanel_update_engines(impanel, value);
|
||
|
}
|
||
|
else if (g_strcmp0(section, "general/hotkey") == 0 && g_strcmp0(name, "triggers") == 0) {
|
||
|
impanel_update_triggers(impanel, value);
|
||
|
} else if (g_strcmp0(section, "general") == 0 && g_strcmp0(name, "use-system-keyboard-layout") == 0) {
|
||
|
impanel_update_use_system_keyboard_layout(impanel, value);
|
||
|
} else if (g_strcmp0(section, "general") == 0 && g_strcmp0(name, "use-global-engine") == 0) {
|
||
|
impanel_update_use_global_engine(impanel, value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
impanel_exit_callback (GDBusConnection *connection,
|
||
|
const gchar *sender_name,
|
||
|
const gchar *object_path,
|
||
|
const gchar *interface_name,
|
||
|
const gchar *signal_name,
|
||
|
GVariant *parameters,
|
||
|
gpointer user_data)
|
||
|
{
|
||
|
Q_UNUSED(connection);
|
||
|
Q_UNUSED(sender_name);
|
||
|
Q_UNUSED(object_path);
|
||
|
Q_UNUSED(interface_name);
|
||
|
Q_UNUSED(signal_name);
|
||
|
Q_UNUSED(parameters);
|
||
|
IBusPanelImpanel* impanel = ((IBusPanelImpanel *)user_data);
|
||
|
if (impanel->bus) {
|
||
|
ibus_bus_exit(impanel->bus, FALSE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
impanel_panel_created_callback (GDBusConnection *connection,
|
||
|
const gchar *sender_name,
|
||
|
const gchar *object_path,
|
||
|
const gchar *interface_name,
|
||
|
const gchar *signal_name,
|
||
|
GVariant *parameters,
|
||
|
gpointer user_data)
|
||
|
{
|
||
|
Q_UNUSED(connection);
|
||
|
Q_UNUSED(sender_name);
|
||
|
Q_UNUSED(object_path);
|
||
|
Q_UNUSED(interface_name);
|
||
|
Q_UNUSED(signal_name);
|
||
|
Q_UNUSED(parameters);
|
||
|
IBusPanelImpanel* impanel = ((IBusPanelImpanel *)user_data);
|
||
|
ibus_panel_impanel_real_register_properties(impanel);
|
||
|
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
impanel_set_engine(IBusPanelImpanel* impanel, const char* name)
|
||
|
{
|
||
|
if (!name || !name[0]) {
|
||
|
return;
|
||
|
}
|
||
|
if (ibus_bus_set_global_engine(impanel->bus, name)) {
|
||
|
if (!impanel->useSystemKeyboardLayout) {
|
||
|
IBusEngineDesc* engine_desc = ibus_bus_get_global_engine(impanel->bus);
|
||
|
if (engine_desc) {
|
||
|
impanel->xkbLayoutManager->setLayout(engine_desc);
|
||
|
}
|
||
|
}
|
||
|
impanel->engineManager->setCurrentEngine(name);
|
||
|
} else {
|
||
|
qDebug() << "set engine failed.";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
impanel_trigger_property_callback (GDBusConnection *connection,
|
||
|
const gchar *sender_name,
|
||
|
const gchar *object_path,
|
||
|
const gchar *interface_name,
|
||
|
const gchar *signal_name,
|
||
|
GVariant *parameters,
|
||
|
gpointer user_data)
|
||
|
{
|
||
|
Q_UNUSED(connection);
|
||
|
Q_UNUSED(sender_name);
|
||
|
Q_UNUSED(object_path);
|
||
|
Q_UNUSED(interface_name);
|
||
|
Q_UNUSED(signal_name);
|
||
|
IBusPanelImpanel* impanel = IBUS_PANEL_IMPANEL(user_data);
|
||
|
gchar *s0 = NULL;
|
||
|
g_variant_get (parameters, "(s)", &s0);
|
||
|
if (!s0 || strlen(s0) <= 6)
|
||
|
return;
|
||
|
QByteArray prop_key(s0 + 6);// +6 to skip "/IBus/"
|
||
|
prop_key.replace('!', ':');
|
||
|
if (g_ascii_strncasecmp (prop_key.constData(), "Logo", 4) == 0)
|
||
|
ibus_panel_impanel_exec_im_menu(impanel);
|
||
|
else if (g_ascii_strncasecmp (prop_key.constData(), "Engine/", 7) == 0) {
|
||
|
impanel_set_engine(impanel, prop_key.constData() + 7);
|
||
|
}
|
||
|
else {
|
||
|
IBusProperty* property = impanel->propManager->property(prop_key.constData());
|
||
|
if (property) {
|
||
|
IBusPropState newstate = ibus_property_get_state(property);
|
||
|
switch (ibus_property_get_prop_type(property)) {
|
||
|
case PROP_TYPE_RADIO:
|
||
|
case PROP_TYPE_TOGGLE:
|
||
|
if (ibus_property_get_prop_type(property) == PROP_TYPE_TOGGLE) {
|
||
|
if (newstate == PROP_STATE_CHECKED)
|
||
|
newstate = PROP_STATE_UNCHECKED;
|
||
|
else if (newstate == PROP_STATE_UNCHECKED)
|
||
|
newstate = PROP_STATE_CHECKED;
|
||
|
}
|
||
|
else if (ibus_property_get_prop_type(property) == PROP_TYPE_RADIO) {
|
||
|
newstate = PROP_STATE_CHECKED;
|
||
|
}
|
||
|
case PROP_TYPE_NORMAL:
|
||
|
ibus_property_set_state(property, newstate);
|
||
|
ibus_panel_service_property_activate((IBusPanelService *)impanel, prop_key.constData(), newstate);
|
||
|
break;
|
||
|
case PROP_TYPE_MENU:
|
||
|
ibus_panel_impanel_exec_menu(impanel, ibus_property_get_sub_props(property));
|
||
|
case PROP_TYPE_SEPARATOR:
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
ibus_panel_service_property_activate((IBusPanelService *)impanel, prop_key.constData(), PROP_STATE_CHECKED);
|
||
|
}
|
||
|
}
|
||
|
g_free(s0);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
impanel_select_candidate_callback (GDBusConnection *connection,
|
||
|
const gchar *sender_name,
|
||
|
const gchar *object_path,
|
||
|
const gchar *interface_name,
|
||
|
const gchar *signal_name,
|
||
|
GVariant *parameters,
|
||
|
gpointer user_data)
|
||
|
{
|
||
|
Q_UNUSED(connection);
|
||
|
Q_UNUSED(sender_name);
|
||
|
Q_UNUSED(object_path);
|
||
|
Q_UNUSED(interface_name);
|
||
|
Q_UNUSED(signal_name);
|
||
|
|
||
|
gint i;
|
||
|
g_variant_get (parameters, "(i)", &i);
|
||
|
IBusPanelImpanel* impanel = IBUS_PANEL_IMPANEL(user_data);
|
||
|
ibus_panel_service_candidate_clicked((IBusPanelService *)impanel, i, 0, 0);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
impanel_prev_page_callback (GDBusConnection *connection,
|
||
|
const gchar *sender_name,
|
||
|
const gchar *object_path,
|
||
|
const gchar *interface_name,
|
||
|
const gchar *signal_name,
|
||
|
GVariant *parameters,
|
||
|
gpointer user_data)
|
||
|
{
|
||
|
Q_UNUSED(connection);
|
||
|
Q_UNUSED(sender_name);
|
||
|
Q_UNUSED(object_path);
|
||
|
Q_UNUSED(interface_name);
|
||
|
Q_UNUSED(signal_name);
|
||
|
Q_UNUSED(parameters);
|
||
|
|
||
|
IBusPanelImpanel* impanel = IBUS_PANEL_IMPANEL(user_data);
|
||
|
ibus_panel_service_page_up((IBusPanelService *)impanel);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
impanel_next_page_callback (GDBusConnection *connection,
|
||
|
const gchar *sender_name,
|
||
|
const gchar *object_path,
|
||
|
const gchar *interface_name,
|
||
|
const gchar *signal_name,
|
||
|
GVariant *parameters,
|
||
|
gpointer user_data)
|
||
|
{
|
||
|
Q_UNUSED(connection);
|
||
|
Q_UNUSED(sender_name);
|
||
|
Q_UNUSED(object_path);
|
||
|
Q_UNUSED(interface_name);
|
||
|
Q_UNUSED(signal_name);
|
||
|
Q_UNUSED(parameters);
|
||
|
|
||
|
IBusPanelImpanel* impanel = IBUS_PANEL_IMPANEL(user_data);
|
||
|
ibus_panel_service_page_down((IBusPanelService *)impanel);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
impanel_configure_callback (GDBusConnection *connection,
|
||
|
const gchar *sender_name,
|
||
|
const gchar *object_path,
|
||
|
const gchar *interface_name,
|
||
|
const gchar *signal_name,
|
||
|
GVariant *parameters,
|
||
|
gpointer user_data)
|
||
|
{
|
||
|
Q_UNUSED(connection);
|
||
|
Q_UNUSED(sender_name);
|
||
|
Q_UNUSED(object_path);
|
||
|
Q_UNUSED(interface_name);
|
||
|
Q_UNUSED(signal_name);
|
||
|
Q_UNUSED(parameters);
|
||
|
Q_UNUSED(user_data);
|
||
|
pid_t pid = fork();
|
||
|
if (pid == 0) {
|
||
|
execlp ("ibus-setup", "ibus-setup", (char *)0);
|
||
|
exit (0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
on_bus_acquired (GDBusConnection *connection,
|
||
|
const gchar *name,
|
||
|
gpointer user_data)
|
||
|
{
|
||
|
Q_UNUSED(name);
|
||
|
IBusPanelImpanel* impanel = ((IBusPanelImpanel *)user_data);
|
||
|
impanel->conn = connection;
|
||
|
|
||
|
g_dbus_connection_register_object (connection,
|
||
|
"/kimpanel",
|
||
|
introspection_data->interfaces[0],
|
||
|
NULL, /*&interface_vtable*/
|
||
|
NULL, /* user_data */
|
||
|
NULL, /* user_data_free_func */
|
||
|
NULL); /* GError** */
|
||
|
|
||
|
g_dbus_connection_signal_subscribe (connection,
|
||
|
"org.kde.impanel",
|
||
|
"org.kde.impanel",
|
||
|
"TriggerProperty",
|
||
|
"/org/kde/impanel",
|
||
|
NULL,
|
||
|
G_DBUS_SIGNAL_FLAGS_NONE,
|
||
|
impanel_trigger_property_callback,
|
||
|
user_data,
|
||
|
NULL);
|
||
|
g_dbus_connection_signal_subscribe (connection,
|
||
|
"org.kde.impanel",
|
||
|
"org.kde.impanel",
|
||
|
"SelectCandidate",
|
||
|
"/org/kde/impanel",
|
||
|
NULL,
|
||
|
G_DBUS_SIGNAL_FLAGS_NONE,
|
||
|
impanel_select_candidate_callback,
|
||
|
user_data,
|
||
|
NULL);
|
||
|
g_dbus_connection_signal_subscribe (connection,
|
||
|
"org.kde.impanel",
|
||
|
"org.kde.impanel",
|
||
|
"LookupTablePageUp",
|
||
|
"/org/kde/impanel",
|
||
|
NULL,
|
||
|
G_DBUS_SIGNAL_FLAGS_NONE,
|
||
|
impanel_prev_page_callback,
|
||
|
user_data,
|
||
|
NULL);
|
||
|
g_dbus_connection_signal_subscribe (connection,
|
||
|
"org.kde.impanel",
|
||
|
"org.kde.impanel",
|
||
|
"LookupTablePageDown",
|
||
|
"/org/kde/impanel",
|
||
|
NULL,
|
||
|
G_DBUS_SIGNAL_FLAGS_NONE,
|
||
|
impanel_next_page_callback,
|
||
|
user_data,
|
||
|
NULL);
|
||
|
g_dbus_connection_signal_subscribe (connection,
|
||
|
"org.kde.impanel",
|
||
|
"org.kde.impanel",
|
||
|
"PanelCreated",
|
||
|
"/org/kde/impanel",
|
||
|
NULL,
|
||
|
G_DBUS_SIGNAL_FLAGS_NONE,
|
||
|
impanel_panel_created_callback,
|
||
|
user_data,
|
||
|
NULL);
|
||
|
g_dbus_connection_signal_subscribe (connection,
|
||
|
"org.kde.impanel",
|
||
|
"org.kde.impanel",
|
||
|
"Exit",
|
||
|
"/org/kde/impanel",
|
||
|
NULL,
|
||
|
G_DBUS_SIGNAL_FLAGS_NONE,
|
||
|
impanel_exit_callback,
|
||
|
user_data,
|
||
|
NULL);
|
||
|
g_dbus_connection_signal_subscribe (connection,
|
||
|
"org.kde.impanel",
|
||
|
"org.kde.impanel",
|
||
|
"Configure",
|
||
|
"/org/kde/impanel",
|
||
|
NULL,
|
||
|
G_DBUS_SIGNAL_FLAGS_NONE,
|
||
|
impanel_configure_callback,
|
||
|
user_data,
|
||
|
NULL);
|
||
|
|
||
|
IBusConfig* config = ibus_bus_get_config(impanel->bus);
|
||
|
if (config) {
|
||
|
g_signal_connect_object(config, "value-changed", (GCallback) impanel_config_value_changed_callback, impanel, (GConnectFlags) 0);
|
||
|
ibus_config_watch(config, "general", "preload_engines");
|
||
|
ibus_config_watch(config, "general", "use-system-keyboard-layout");
|
||
|
ibus_config_watch(config, "general/hotkey", "triggers");
|
||
|
|
||
|
GVariant* var_engines = ibus_config_get_value(config, "general", "preload_engines");
|
||
|
impanel_update_engines(impanel, var_engines);
|
||
|
if (var_engines)
|
||
|
g_variant_unref(var_engines);
|
||
|
|
||
|
var_engines = ibus_config_get_value(config, "general", "engines-order");
|
||
|
if (var_engines) {
|
||
|
impanel_update_engines_order(impanel, var_engines);
|
||
|
g_variant_unref(var_engines);
|
||
|
}
|
||
|
|
||
|
GVariant* var_triggers = ibus_config_get_value(config, "general/hotkey", "triggers");
|
||
|
impanel_update_triggers(impanel, var_triggers);
|
||
|
if (var_triggers)
|
||
|
g_variant_unref(var_triggers);
|
||
|
|
||
|
IBusConfig* config = ibus_bus_get_config(impanel->bus);
|
||
|
GVariant* var_layouts = ibus_config_get_value(config, "general", "xkb-latin-layouts");
|
||
|
if (var_layouts) {
|
||
|
impanel_update_latin_layouts(impanel, var_layouts);
|
||
|
g_variant_unref(var_layouts);
|
||
|
}
|
||
|
|
||
|
GVariant* var = ibus_config_get_value(config, "general", "use-system-keyboard-layout");
|
||
|
if (var) {
|
||
|
impanel_update_use_system_keyboard_layout(impanel, var);
|
||
|
g_variant_unref(var);
|
||
|
}
|
||
|
|
||
|
var = ibus_config_get_value(config, "general", "use-global-engine");
|
||
|
if (var) {
|
||
|
impanel_update_use_global_engine(impanel, var);
|
||
|
g_variant_unref(var);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ibus_panel_impanel_real_register_properties(impanel);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
on_name_acquired (GDBusConnection *connection,
|
||
|
const gchar *name,
|
||
|
gpointer user_data)
|
||
|
{
|
||
|
Q_UNUSED(connection);
|
||
|
Q_UNUSED(name);
|
||
|
Q_UNUSED(user_data);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
on_name_lost (GDBusConnection *connection,
|
||
|
const gchar *name,
|
||
|
gpointer user_data)
|
||
|
{
|
||
|
Q_UNUSED(connection);
|
||
|
Q_UNUSED(name);
|
||
|
Q_UNUSED(user_data);
|
||
|
exit (1);
|
||
|
}
|
||
|
|
||
|
G_DEFINE_TYPE (IBusPanelImpanel, ibus_panel_impanel, IBUS_TYPE_PANEL_SERVICE)
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_class_init (IBusPanelImpanelClass *klass)
|
||
|
{
|
||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||
|
|
||
|
IBUS_OBJECT_CLASS (object_class)->destroy = (IBusObjectDestroyFunc) ibus_panel_impanel_destroy;
|
||
|
IBUS_PANEL_SERVICE_CLASS (object_class)->focus_in = ibus_panel_impanel_focus_in;
|
||
|
IBUS_PANEL_SERVICE_CLASS (object_class)->focus_out = ibus_panel_impanel_focus_out;
|
||
|
IBUS_PANEL_SERVICE_CLASS (object_class)->register_properties = ibus_panel_impanel_register_properties;
|
||
|
IBUS_PANEL_SERVICE_CLASS (object_class)->set_cursor_location = ibus_panel_impanel_set_cursor_location;
|
||
|
IBUS_PANEL_SERVICE_CLASS (object_class)->update_auxiliary_text = ibus_panel_impanel_update_auxiliary_text;
|
||
|
IBUS_PANEL_SERVICE_CLASS (object_class)->update_lookup_table = ibus_panel_impanel_update_lookup_table;
|
||
|
IBUS_PANEL_SERVICE_CLASS (object_class)->update_preedit_text = ibus_panel_impanel_update_preedit_text;
|
||
|
IBUS_PANEL_SERVICE_CLASS (object_class)->update_property = ibus_panel_impanel_update_property;
|
||
|
IBUS_PANEL_SERVICE_CLASS (object_class)->cursor_down_lookup_table = ibus_panel_impanel_cursor_down_lookup_table;
|
||
|
IBUS_PANEL_SERVICE_CLASS (object_class)->cursor_up_lookup_table = ibus_panel_impanel_cursor_up_lookup_table;
|
||
|
IBUS_PANEL_SERVICE_CLASS (object_class)->hide_auxiliary_text = ibus_panel_impanel_hide_auxiliary_text;
|
||
|
IBUS_PANEL_SERVICE_CLASS (object_class)->hide_language_bar = ibus_panel_impanel_hide_language_bar;
|
||
|
IBUS_PANEL_SERVICE_CLASS (object_class)->hide_lookup_table = ibus_panel_impanel_hide_lookup_table;
|
||
|
IBUS_PANEL_SERVICE_CLASS (object_class)->hide_preedit_text = ibus_panel_impanel_hide_preedit_text;
|
||
|
IBUS_PANEL_SERVICE_CLASS (object_class)->page_down_lookup_table = ibus_panel_impanel_page_down_lookup_table;
|
||
|
IBUS_PANEL_SERVICE_CLASS (object_class)->page_up_lookup_table = ibus_panel_impanel_page_up_lookup_table;
|
||
|
IBUS_PANEL_SERVICE_CLASS (object_class)->reset = ibus_panel_impanel_reset;
|
||
|
IBUS_PANEL_SERVICE_CLASS (object_class)->show_auxiliary_text = ibus_panel_impanel_show_auxiliary_text;
|
||
|
IBUS_PANEL_SERVICE_CLASS (object_class)->show_language_bar = ibus_panel_impanel_show_language_bar;
|
||
|
IBUS_PANEL_SERVICE_CLASS (object_class)->show_lookup_table = ibus_panel_impanel_show_lookup_table;
|
||
|
IBUS_PANEL_SERVICE_CLASS (object_class)->show_preedit_text = ibus_panel_impanel_show_preedit_text;
|
||
|
IBUS_PANEL_SERVICE_CLASS (object_class)->start_setup = ibus_panel_impanel_start_setup;
|
||
|
IBUS_PANEL_SERVICE_CLASS (object_class)->state_changed = ibus_panel_impanel_state_changed;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_init (IBusPanelImpanel *impanel)
|
||
|
{
|
||
|
impanel->bus = NULL;
|
||
|
impanel->app = NULL;
|
||
|
impanel->useSystemKeyboardLayout = false;
|
||
|
impanel->selected = -1;
|
||
|
|
||
|
introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
|
||
|
owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
|
||
|
"org.kde.kimpanel.inputmethod",
|
||
|
G_BUS_NAME_OWNER_FLAGS_REPLACE,
|
||
|
on_bus_acquired,
|
||
|
on_name_acquired,
|
||
|
on_name_lost,
|
||
|
impanel, NULL);
|
||
|
|
||
|
impanel->propManager = new PropertyManager;
|
||
|
impanel->engineManager = new EngineManager;
|
||
|
impanel->xkbLayoutManager = new XkbLayoutManager;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_destroy (IBusPanelImpanel *impanel)
|
||
|
{
|
||
|
delete impanel->propManager;
|
||
|
impanel->propManager = NULL;
|
||
|
delete impanel->engineManager;
|
||
|
impanel->engineManager = NULL;
|
||
|
delete impanel->xkbLayoutManager;
|
||
|
impanel->xkbLayoutManager = NULL;
|
||
|
|
||
|
g_bus_unown_name (owner_id);
|
||
|
g_dbus_node_info_unref (introspection_data);
|
||
|
|
||
|
IBUS_OBJECT_CLASS (ibus_panel_impanel_parent_class)->destroy ((IBusObject *)impanel);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_focus_in (IBusPanelService *panel,
|
||
|
const gchar *input_context_path)
|
||
|
{
|
||
|
IBusPanelImpanel* impanel = IBUS_PANEL_IMPANEL (panel);
|
||
|
if (impanel->app->keyboardGrabbed()) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
IBusEngineDesc *engine_desc = ibus_bus_get_global_engine(impanel->bus);
|
||
|
impanel_update_logo_by_engine(impanel, engine_desc);
|
||
|
|
||
|
impanel->engineManager->setCurrentContext(input_context_path);
|
||
|
if (!impanel->engineManager->useGlobalEngine()) {
|
||
|
impanel_set_engine(impanel, impanel->engineManager->currentEngine().toUtf8().constData());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_focus_out (IBusPanelService *panel,
|
||
|
const gchar *input_context_path)
|
||
|
{
|
||
|
Q_UNUSED(panel);
|
||
|
Q_UNUSED(input_context_path);
|
||
|
IBusPanelImpanel* impanel = IBUS_PANEL_IMPANEL (panel);
|
||
|
|
||
|
if (impanel->app->keyboardGrabbed()) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (impanel->engineManager->useGlobalEngine()) {
|
||
|
return;
|
||
|
}
|
||
|
impanel->engineManager->setCurrentContext("");
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_register_properties (IBusPanelService *panel,
|
||
|
IBusPropList *prop_list)
|
||
|
{
|
||
|
IBusPanelImpanel* impanel = IBUS_PANEL_IMPANEL (panel);
|
||
|
impanel->propManager->setProperties(prop_list);
|
||
|
ibus_panel_impanel_real_register_properties(impanel);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_real_register_properties(IBusPanelImpanel* impanel)
|
||
|
{
|
||
|
IBusProperty* property = NULL;
|
||
|
guint i = 0;
|
||
|
|
||
|
GVariantBuilder builder;
|
||
|
g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
|
||
|
|
||
|
IBusEngineDesc* engine_desc = NULL;
|
||
|
if (impanel->selected >= 0 && static_cast<size_t>(impanel->selected) < impanel->engineManager->length()) {
|
||
|
engine_desc = impanel->engineManager->engines()[impanel->selected];
|
||
|
} else {
|
||
|
engine_desc = ibus_bus_get_global_engine(impanel->bus);
|
||
|
}
|
||
|
QByteArray propstr = ibus_engine_desc_to_logo_propstr(engine_desc);
|
||
|
g_variant_builder_add (&builder, "s", propstr.constData());
|
||
|
|
||
|
IBusPropList* prop_list = impanel->propManager->properties();
|
||
|
if (prop_list) {
|
||
|
while ( ( property = ibus_prop_list_get( prop_list, i ) ) != NULL ) {
|
||
|
propstr = ibus_property_to_propstr(property, TRUE);
|
||
|
g_variant_builder_add (&builder, "s", propstr.constData());
|
||
|
++i;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!impanel->conn)
|
||
|
return;
|
||
|
|
||
|
g_dbus_connection_emit_signal (impanel->conn,
|
||
|
NULL, "/kimpanel", "org.kde.kimpanel.inputmethod", "RegisterProperties",
|
||
|
(g_variant_new ("(as)", &builder)),
|
||
|
NULL);
|
||
|
}
|
||
|
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_set_cursor_location (IBusPanelService *panel,
|
||
|
gint x,
|
||
|
gint y,
|
||
|
gint w,
|
||
|
gint h)
|
||
|
{
|
||
|
|
||
|
g_dbus_connection_call(IBUS_PANEL_IMPANEL (panel)->conn,
|
||
|
"org.kde.impanel",
|
||
|
"/org/kde/impanel",
|
||
|
"org.kde.impanel2",
|
||
|
"SetSpotRect",
|
||
|
(g_variant_new("(iiii)", x, y, w, h)),
|
||
|
NULL,
|
||
|
G_DBUS_CALL_FLAGS_NONE,
|
||
|
-1, /* timeout */
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_update_auxiliary_text (IBusPanelService *panel,
|
||
|
IBusText *text,
|
||
|
gboolean visible)
|
||
|
{
|
||
|
const gchar* t = ibus_text_get_text (text);
|
||
|
const gchar *attr = "";
|
||
|
IBusPanelImpanel* impanel = (IBusPanelImpanel*) panel;
|
||
|
|
||
|
if (!impanel->conn)
|
||
|
return;
|
||
|
|
||
|
g_dbus_connection_emit_signal (impanel->conn,
|
||
|
NULL, "/kimpanel", "org.kde.kimpanel.inputmethod", "UpdateAux",
|
||
|
(g_variant_new ("(ss)", t, attr)),
|
||
|
NULL);
|
||
|
|
||
|
if (visible == 0)
|
||
|
ibus_panel_impanel_hide_auxiliary_text(panel);
|
||
|
else
|
||
|
ibus_panel_impanel_show_auxiliary_text(panel);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_update_lookup_table (IBusPanelService *panel,
|
||
|
IBusLookupTable *lookup_table,
|
||
|
gboolean visible)
|
||
|
{
|
||
|
IBusPanelImpanel* impanel = IBUS_PANEL_IMPANEL(panel);
|
||
|
if (!impanel->conn)
|
||
|
return;
|
||
|
|
||
|
guint page_size = ibus_lookup_table_get_page_size(lookup_table);
|
||
|
guint cursor_pos = ibus_lookup_table_get_cursor_pos(lookup_table);
|
||
|
guint page = cursor_pos / page_size;
|
||
|
guint start = page * page_size;
|
||
|
guint end = start + page_size;
|
||
|
guint num = ibus_lookup_table_get_number_of_candidates(lookup_table);
|
||
|
if (end > num) {
|
||
|
end = num;
|
||
|
}
|
||
|
|
||
|
// fprintf(stderr, "%d ~ %d pgsize %d num %d\n", start, end, page_size, num);
|
||
|
|
||
|
guint i;
|
||
|
|
||
|
gchar label[16][4];// WARNING large enough I think --- nihui
|
||
|
const gchar *candidate;
|
||
|
|
||
|
GVariantBuilder builder_labels;
|
||
|
GVariantBuilder builder_candidates;
|
||
|
GVariantBuilder builder_attrs;
|
||
|
g_variant_builder_init (&builder_labels, G_VARIANT_TYPE ("as"));
|
||
|
g_variant_builder_init (&builder_candidates, G_VARIANT_TYPE ("as"));
|
||
|
g_variant_builder_init (&builder_attrs, G_VARIANT_TYPE ("as"));
|
||
|
|
||
|
const gchar *attr = "";
|
||
|
for (i = start; i < end; i++) {
|
||
|
g_snprintf (label[i-start], 4, "%d", (i-start+1) % 10);
|
||
|
// NOTE ibus always return NULL for ibus_lookup_table_get_label
|
||
|
// label = ibus_lookup_table_get_label(lookup_table, i)->text;
|
||
|
g_variant_builder_add (&builder_labels, "s", label[i-start]);
|
||
|
|
||
|
candidate = ibus_text_get_text (ibus_lookup_table_get_candidate (lookup_table, i));
|
||
|
g_variant_builder_add (&builder_candidates, "s", candidate);
|
||
|
|
||
|
g_variant_builder_add (&builder_attrs, "s", attr);
|
||
|
}
|
||
|
|
||
|
gboolean has_prev = 1;
|
||
|
gboolean has_next = 1;
|
||
|
|
||
|
guint cursor_pos_in_page;
|
||
|
if (ibus_lookup_table_is_cursor_visible(lookup_table))
|
||
|
cursor_pos_in_page = cursor_pos % page_size;
|
||
|
else
|
||
|
cursor_pos_in_page = -1;
|
||
|
|
||
|
gint orientation = ibus_lookup_table_get_orientation(lookup_table);
|
||
|
if (orientation == IBUS_ORIENTATION_HORIZONTAL) {
|
||
|
orientation = 2;
|
||
|
} else if (orientation == IBUS_ORIENTATION_VERTICAL) {
|
||
|
orientation = 1;
|
||
|
} else {
|
||
|
orientation = 0;
|
||
|
}
|
||
|
|
||
|
g_dbus_connection_call(impanel->conn,
|
||
|
"org.kde.impanel",
|
||
|
"/org/kde/impanel",
|
||
|
"org.kde.impanel2",
|
||
|
"SetLookupTable",
|
||
|
(g_variant_new ("(asasasbbii)",
|
||
|
&builder_labels,
|
||
|
&builder_candidates,
|
||
|
&builder_attrs,
|
||
|
has_prev, has_next,
|
||
|
cursor_pos_in_page, orientation)),
|
||
|
NULL,
|
||
|
G_DBUS_CALL_FLAGS_NONE,
|
||
|
-1,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL);
|
||
|
|
||
|
if (visible == 0)
|
||
|
ibus_panel_impanel_hide_lookup_table(panel);
|
||
|
else
|
||
|
ibus_panel_impanel_show_lookup_table(panel);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_update_preedit_text (IBusPanelService *panel,
|
||
|
IBusText *text,
|
||
|
guint cursor_pos,
|
||
|
gboolean visible)
|
||
|
{
|
||
|
IBusPanelImpanel* impanel = IBUS_PANEL_IMPANEL(panel);
|
||
|
if (!impanel->conn)
|
||
|
return;
|
||
|
|
||
|
const gchar* t = ibus_text_get_text (text);
|
||
|
const gchar *attr = "";
|
||
|
|
||
|
g_dbus_connection_emit_signal (impanel->conn,
|
||
|
NULL, "/kimpanel", "org.kde.kimpanel.inputmethod", "UpdatePreeditText",
|
||
|
(g_variant_new ("(ss)", t, attr)),
|
||
|
NULL);
|
||
|
|
||
|
g_dbus_connection_emit_signal (impanel->conn,
|
||
|
NULL, "/kimpanel", "org.kde.kimpanel.inputmethod", "UpdatePreeditCaret",
|
||
|
(g_variant_new ("(i)", cursor_pos)),
|
||
|
NULL);
|
||
|
|
||
|
if (visible == 0)
|
||
|
ibus_panel_impanel_hide_preedit_text(panel);
|
||
|
else
|
||
|
ibus_panel_impanel_show_preedit_text(panel);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_update_property (IBusPanelService *panel,
|
||
|
IBusProperty *prop)
|
||
|
{
|
||
|
IBusPanelImpanel* impanel = IBUS_PANEL_IMPANEL(panel);
|
||
|
if (!impanel->conn)
|
||
|
return;
|
||
|
|
||
|
impanel->propManager->updateProperty(prop);
|
||
|
|
||
|
QByteArray propstr = ibus_property_to_propstr(prop, TRUE);
|
||
|
|
||
|
g_dbus_connection_emit_signal (impanel->conn,
|
||
|
NULL, "/kimpanel", "org.kde.kimpanel.inputmethod", "UpdateProperty",
|
||
|
(g_variant_new ("(s)", propstr.constData())),
|
||
|
NULL);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_cursor_down_lookup_table (IBusPanelService *panel)
|
||
|
{
|
||
|
Q_UNUSED(panel);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_cursor_up_lookup_table (IBusPanelService *panel)
|
||
|
{
|
||
|
Q_UNUSED(panel);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_hide_auxiliary_text (IBusPanelService *panel)
|
||
|
{
|
||
|
IBusPanelImpanel* impanel = IBUS_PANEL_IMPANEL(panel);
|
||
|
if (!impanel->conn)
|
||
|
return;
|
||
|
gboolean toShow = 0;
|
||
|
|
||
|
g_dbus_connection_emit_signal (impanel->conn,
|
||
|
NULL, "/kimpanel", "org.kde.kimpanel.inputmethod", "ShowAux",
|
||
|
(g_variant_new ("(b)", toShow)),
|
||
|
NULL);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_hide_language_bar (IBusPanelService *panel)
|
||
|
{
|
||
|
Q_UNUSED(panel);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_hide_lookup_table (IBusPanelService *panel)
|
||
|
{
|
||
|
IBusPanelImpanel* impanel = IBUS_PANEL_IMPANEL(panel);
|
||
|
if (!impanel->conn)
|
||
|
return;
|
||
|
gboolean toShow = 0;
|
||
|
|
||
|
g_dbus_connection_emit_signal (impanel->conn,
|
||
|
NULL, "/kimpanel", "org.kde.kimpanel.inputmethod", "ShowLookupTable",
|
||
|
(g_variant_new ("(b)", toShow)),
|
||
|
NULL);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_hide_preedit_text (IBusPanelService *panel)
|
||
|
{
|
||
|
IBusPanelImpanel* impanel = IBUS_PANEL_IMPANEL(panel);
|
||
|
if (!impanel->conn)
|
||
|
return;
|
||
|
gboolean toShow = 0;
|
||
|
|
||
|
g_dbus_connection_emit_signal (impanel->conn,
|
||
|
NULL, "/kimpanel", "org.kde.kimpanel.inputmethod", "ShowPreedit",
|
||
|
(g_variant_new ("(b)", toShow)),
|
||
|
NULL);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_page_down_lookup_table (IBusPanelService *panel)
|
||
|
{
|
||
|
Q_UNUSED(panel);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_page_up_lookup_table (IBusPanelService *panel)
|
||
|
{
|
||
|
Q_UNUSED(panel);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_reset (IBusPanelService *panel)
|
||
|
{
|
||
|
Q_UNUSED(panel);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_show_auxiliary_text (IBusPanelService *panel)
|
||
|
{
|
||
|
IBusPanelImpanel* impanel = IBUS_PANEL_IMPANEL(panel);
|
||
|
if (!impanel->conn)
|
||
|
return;
|
||
|
gboolean toShow = 1;
|
||
|
|
||
|
g_dbus_connection_emit_signal (impanel->conn,
|
||
|
NULL, "/kimpanel", "org.kde.kimpanel.inputmethod", "ShowAux",
|
||
|
(g_variant_new ("(b)", toShow)),
|
||
|
NULL);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_show_language_bar (IBusPanelService *panel)
|
||
|
{
|
||
|
Q_UNUSED(panel);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_show_lookup_table (IBusPanelService *panel)
|
||
|
{
|
||
|
IBusPanelImpanel* impanel = IBUS_PANEL_IMPANEL(panel);
|
||
|
if (!impanel->conn)
|
||
|
return;
|
||
|
gboolean toShow = 1;
|
||
|
|
||
|
g_dbus_connection_emit_signal (impanel->conn,
|
||
|
NULL, "/kimpanel", "org.kde.kimpanel.inputmethod", "ShowLookupTable",
|
||
|
(g_variant_new ("(b)", toShow)),
|
||
|
NULL);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_show_preedit_text (IBusPanelService *panel)
|
||
|
{
|
||
|
IBusPanelImpanel* impanel = IBUS_PANEL_IMPANEL(panel);
|
||
|
if (!impanel->conn)
|
||
|
return;
|
||
|
gboolean toShow = 1;
|
||
|
|
||
|
g_dbus_connection_emit_signal (impanel->conn,
|
||
|
NULL, "/kimpanel", "org.kde.kimpanel.inputmethod", "ShowPreedit",
|
||
|
(g_variant_new ("(b)", toShow)),
|
||
|
NULL);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_start_setup (IBusPanelService *panel)
|
||
|
{
|
||
|
Q_UNUSED(panel);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_state_changed (IBusPanelService *panel)
|
||
|
{
|
||
|
IBusPanelImpanel* impanel = IBUS_PANEL_IMPANEL(panel);
|
||
|
if (!impanel->conn)
|
||
|
return;
|
||
|
|
||
|
if (impanel->app->keyboardGrabbed()) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
IBusEngineDesc *engine_desc = ibus_bus_get_global_engine(impanel->bus);
|
||
|
if (!engine_desc) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
impanel_update_logo_by_engine(impanel, engine_desc);
|
||
|
|
||
|
g_dbus_connection_emit_signal (impanel->conn,
|
||
|
NULL, "/kimpanel", "org.kde.kimpanel.inputmethod", "Enable",
|
||
|
(g_variant_new ("(b)", TRUE)),
|
||
|
NULL);
|
||
|
|
||
|
impanel->engineManager->moveToFirst(engine_desc);
|
||
|
QStringList engineList = impanel->engineManager->engineOrder();
|
||
|
|
||
|
gchar** engine_names = g_new0 (gchar*, engineList.size() + 1);
|
||
|
size_t i = 0;
|
||
|
Q_FOREACH(const QString& name, engineList) {
|
||
|
engine_names[i] = g_strdup (name.toUtf8().constData());
|
||
|
i ++;
|
||
|
}
|
||
|
|
||
|
IBusConfig* config = ibus_bus_get_config(impanel->bus);
|
||
|
if (config) {
|
||
|
GVariant* var = g_variant_new_strv(engine_names, engineList.size());
|
||
|
ibus_config_set_value(config, "general", "engines-order", var);
|
||
|
}
|
||
|
g_strfreev(engine_names);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_exec_menu(IBusPanelImpanel* impanel,
|
||
|
IBusPropList* prop_list)
|
||
|
{
|
||
|
if (!impanel->conn)
|
||
|
return;
|
||
|
|
||
|
GVariantBuilder builder;
|
||
|
g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
|
||
|
|
||
|
int i = 0;
|
||
|
while (true) {
|
||
|
IBusProperty* prop = ibus_prop_list_get(prop_list, i);
|
||
|
if (!prop)
|
||
|
break;
|
||
|
QByteArray propstr = ibus_property_to_propstr(prop);
|
||
|
g_variant_builder_add (&builder, "s", propstr.constData());
|
||
|
i ++;
|
||
|
}
|
||
|
|
||
|
g_dbus_connection_emit_signal (impanel->conn,
|
||
|
NULL, "/kimpanel", "org.kde.kimpanel.inputmethod", "ExecMenu",
|
||
|
(g_variant_new ("(as)", &builder)),
|
||
|
NULL);
|
||
|
}
|
||
|
|
||
|
|
||
|
static void
|
||
|
ibus_panel_impanel_exec_im_menu (IBusPanelImpanel* impanel)
|
||
|
{
|
||
|
if (!impanel->conn)
|
||
|
return;
|
||
|
|
||
|
GVariantBuilder builder;
|
||
|
g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
|
||
|
|
||
|
IBusEngineDesc** engines = impanel->engineManager->engines();
|
||
|
if (engines) {
|
||
|
int i = 0;
|
||
|
while (engines[i]) {
|
||
|
QByteArray propstr = ibus_engine_desc_to_propstr(engines[i]);
|
||
|
g_variant_builder_add (&builder, "s", propstr.constData());
|
||
|
i ++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
g_dbus_connection_emit_signal (impanel->conn,
|
||
|
NULL, "/kimpanel", "org.kde.kimpanel.inputmethod", "ExecMenu",
|
||
|
(g_variant_new ("(as)", &builder)),
|
||
|
NULL);
|
||
|
}
|
||
|
|
||
|
IBusPanelImpanel *
|
||
|
ibus_panel_impanel_new (GDBusConnection *connection)
|
||
|
{
|
||
|
IBusPanelImpanel *panel;
|
||
|
panel = (IBusPanelImpanel *) g_object_new (IBUS_TYPE_PANEL_IMPANEL,
|
||
|
"object-path", IBUS_PATH_PANEL,
|
||
|
"connection", connection,
|
||
|
NULL);
|
||
|
return panel;
|
||
|
}
|
||
|
|