|
 |
481f2ee |
From a8f02d4be33f87cf97039736407cd13e795b992b Mon Sep 17 00:00:00 2001
|
|
 |
60148ca |
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
 |
481f2ee |
Date: Fri, 18 Nov 2011 18:05:42 +0900
|
|
 |
60148ca |
Subject: [PATCH] Add XKB layouts
|
|
 |
60148ca |
|
|
 |
60148ca |
---
|
|
 |
e0a5e11 |
Makefile.am | 7 +
|
|
 |
e0a5e11 |
configure.ac | 56 +
|
|
 |
481f2ee |
data/ibus.schemas.in | 47 +
|
|
 |
e0a5e11 |
ibus-1.0.pc.in | 2 +
|
|
 |
e0a5e11 |
ibus/Makefile.am | 26 +
|
|
 |
e0a5e11 |
ibus/__init__.py | 2 +
|
|
 |
e0a5e11 |
ibus/bus.py | 3 +
|
|
 |
e0a5e11 |
ibus/interface/iibus.py | 3 +
|
|
 |
481f2ee |
ibus/xkblayout.py.in | 360 ++++
|
|
 |
e0a5e11 |
ibus/xkbxml.py.in | 419 ++++
|
|
 |
e0a5e11 |
setup/Makefile.am | 1 +
|
|
 |
e0a5e11 |
setup/enginecombobox.py | 7 +-
|
|
 |
e0a5e11 |
setup/main.py | 3 +
|
|
 |
e0a5e11 |
setup/setup.ui | 609 ++++++-
|
|
 |
e0a5e11 |
setup/xkbsetup.py | 457 +++++
|
|
 |
e0a5e11 |
src/Makefile.am | 5 +
|
|
 |
e0a5e11 |
src/ibus.h | 1 +
|
|
 |
e0a5e11 |
src/ibusxkbxml.c | 441 +++++
|
|
 |
e0a5e11 |
src/ibusxkbxml.h | 172 ++
|
|
 |
e0a5e11 |
ui/gtk/panel.py | 41 +
|
|
 |
e0a5e11 |
xkb/Makefile.am | 107 +
|
|
 |
e0a5e11 |
xkb/Makefile.am.orig | 104 +
|
|
 |
e0a5e11 |
xkb/gtkimcontextsimpleseqs.h | 4484 ++++++++++++++++++++++++++++++++++++++++++
|
|
 |
e0a5e11 |
xkb/ibus-engine-xkb-main.c | 303 +++
|
|
 |
e0a5e11 |
xkb/ibus-engine-xkb-main.h | 32 +
|
|
 |
5fabd65 |
xkb/ibus-simple-engine.c | 1003 ++++++++++
|
|
 |
5fabd65 |
xkb/ibus-simple-engine.h | 13 +
|
|
 |
e0a5e11 |
xkb/ibus-xkb-main.c | 112 ++
|
|
 |
e0a5e11 |
xkb/xkblayout.xml.in | 16 +
|
|
 |
e0a5e11 |
xkb/xkblayoutconfig.xml.in | 6 +
|
|
 |
e0a5e11 |
xkb/xkblib.c | 327 +++
|
|
 |
e0a5e11 |
xkb/xkblib.h | 41 +
|
|
 |
e0a5e11 |
xkb/xkbxml.c | 345 ++++
|
|
 |
e0a5e11 |
xkb/xkbxml.h | 113 ++
|
|
 |
481f2ee |
34 files changed, 9664 insertions(+), 4 deletions(-)
|
|
 |
60148ca |
create mode 100644 ibus/xkblayout.py.in
|
|
 |
60148ca |
create mode 100644 ibus/xkbxml.py.in
|
|
 |
b95ef1a |
create mode 100644 setup/xkbsetup.py
|
|
 |
63b857f |
create mode 100644 src/ibusxkbxml.c
|
|
 |
63b857f |
create mode 100644 src/ibusxkbxml.h
|
|
 |
60148ca |
create mode 100644 xkb/Makefile.am
|
|
 |
e0a5e11 |
create mode 100644 xkb/Makefile.am.orig
|
|
 |
e0a5e11 |
create mode 100644 xkb/gtkimcontextsimpleseqs.h
|
|
 |
60148ca |
create mode 100644 xkb/ibus-engine-xkb-main.c
|
|
 |
60148ca |
create mode 100644 xkb/ibus-engine-xkb-main.h
|
|
 |
e0a5e11 |
create mode 100644 xkb/ibus-simple-engine.c
|
|
 |
e0a5e11 |
create mode 100644 xkb/ibus-simple-engine.h
|
|
 |
60148ca |
create mode 100644 xkb/ibus-xkb-main.c
|
|
 |
60148ca |
create mode 100644 xkb/xkblayout.xml.in
|
|
 |
60148ca |
create mode 100644 xkb/xkblayoutconfig.xml.in
|
|
 |
60148ca |
create mode 100644 xkb/xkblib.c
|
|
 |
60148ca |
create mode 100644 xkb/xkblib.h
|
|
 |
60148ca |
create mode 100644 xkb/xkbxml.c
|
|
 |
60148ca |
create mode 100644 xkb/xkbxml.h
|
|
 |
60148ca |
|
|
 |
60148ca |
diff --git a/Makefile.am b/Makefile.am
|
|
 |
095f9c1 |
index ff0fabc..056ddfc 100644
|
|
 |
60148ca |
--- a/Makefile.am
|
|
 |
60148ca |
+++ b/Makefile.am
|
|
 |
f0777a3 |
@@ -42,6 +42,12 @@ DAEMON_DIRS = \
|
|
 |
60148ca |
$(NULL)
|
|
 |
60148ca |
endif
|
|
 |
60148ca |
|
|
 |
60148ca |
+if ENABLE_XKB
|
|
 |
f0777a3 |
+XKB_DIRS = \
|
|
 |
f0777a3 |
+ xkb \
|
|
 |
60148ca |
+ $(NULL)
|
|
 |
60148ca |
+endif
|
|
 |
60148ca |
+
|
|
 |
f0777a3 |
if ENABLE_MEMCONF
|
|
 |
f0777a3 |
MEMCONF_DIRS = \
|
|
 |
f0777a3 |
memconf \
|
|
 |
e0a5e11 |
@@ -66,6 +72,7 @@ SUBDIRS = \
|
|
 |
f0777a3 |
$(DAEMON_DIRS) \
|
|
 |
f0777a3 |
$(PYTHON_DIRS) \
|
|
 |
f0777a3 |
$(GCONF_DIRS) \
|
|
 |
f0777a3 |
+ $(XKB_DIRS) \
|
|
 |
60148ca |
$(MEMCONF_DIRS) \
|
|
 |
e0a5e11 |
$(DCONF_DIRS) \
|
|
 |
60148ca |
$(NULL)
|
|
 |
60148ca |
diff --git a/configure.ac b/configure.ac
|
|
 |
5f53fe6 |
index f452666..227e28e 100644
|
|
 |
60148ca |
--- a/configure.ac
|
|
 |
60148ca |
+++ b/configure.ac
|
|
 |
5f53fe6 |
@@ -221,6 +221,60 @@ else
|
|
 |
60148ca |
enable_xim="no (disabled, use --enable-xim to enable)"
|
|
 |
60148ca |
fi
|
|
 |
60148ca |
|
|
 |
60148ca |
+AC_ARG_ENABLE(xkb,
|
|
 |
60148ca |
+ AS_HELP_STRING([--disable-xkb],
|
|
 |
60148ca |
+ [Do not build xkb]),
|
|
 |
60148ca |
+ [enable_xkb=$enableval],
|
|
 |
60148ca |
+ [enable_xkb=yes]
|
|
 |
60148ca |
+)
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+AM_CONDITIONAL([ENABLE_XKB], [test x"$enable_xkb" = x"yes"])
|
|
 |
60148ca |
+if test x"$enable_xkb" = x"yes"; then
|
|
 |
60148ca |
+ PKG_CHECK_MODULES(X11, [
|
|
 |
60148ca |
+ x11
|
|
 |
60148ca |
+ ])
|
|
 |
60148ca |
+ PKG_CHECK_MODULES(XKB,
|
|
 |
60148ca |
+ [xkbfile],,
|
|
 |
60148ca |
+ [XKB_LIBS="-lxkbfile"]
|
|
 |
60148ca |
+ )
|
|
 |
60148ca |
+ AC_DEFINE(HAVE_XKB, 1, [define to 1 if you have xkbfile])
|
|
 |
84d8da5 |
+ HAVE_IBUS_XKB=true
|
|
 |
60148ca |
+else
|
|
 |
60148ca |
+ enable_xkb="no (disabled, use --enable-xkb to enable)"
|
|
 |
84d8da5 |
+ HAVE_IBUS_XKB=false
|
|
 |
60148ca |
+fi
|
|
 |
84d8da5 |
+AC_SUBST(HAVE_IBUS_XKB)
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+# define XKB rules file
|
|
 |
60148ca |
+AC_ARG_WITH(xkb-rules-xml,
|
|
 |
60148ca |
+ AS_HELP_STRING([--with-xkb-rules-xml[=$DIR/evdev.xml]],
|
|
 |
60148ca |
+ [Set evdev.xml file path (default: /usr/share/X11/xkb/rules/evdev.xml)]),
|
|
 |
60148ca |
+ XKB_RULES_XML_FILE=$with_xkb_rules_xml,
|
|
 |
60148ca |
+ XKB_RULES_XML_FILE="/usr/share/X11/xkb/rules/evdev.xml"
|
|
 |
60148ca |
+)
|
|
 |
60148ca |
+AC_DEFINE_UNQUOTED(XKB_RULES_XML_FILE, "$XKB_RULES_XML_FILE",
|
|
 |
60148ca |
+ [Define file path of evdev.xml])
|
|
 |
60148ca |
+AC_SUBST(XKB_RULES_XML_FILE)
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+# define XKB preload layouts
|
|
 |
60148ca |
+AC_ARG_WITH(xkb-preload-layouts,
|
|
 |
60148ca |
+ AS_HELP_STRING([--with-xkb-preload-layouts[=layout,...]],
|
|
 |
60148ca |
+ [Set preload xkb layouts (default: us,fr,de,...)]),
|
|
 |
60148ca |
+ XKB_PRELOAD_LAYOUTS=$with_xkb_preload_layouts,
|
|
 |
60148ca |
+ [XKB_PRELOAD_LAYOUTS=""\
|
|
 |
e5da135 |
+"us,us(chr),us(dvorak),ad,al,am,ara,az,ba,bd,be,bg,br,bt,by,"\
|
|
 |
b95ef1a |
+"de,dk,ca,ch,cn(tib),cz,ee,epo,es,et,fi,fo,fr,"\
|
|
 |
60148ca |
+"gb,ge,ge(dsb),ge(ru),ge(os),gh,gh(akan),gh(ewe),gh(fula),gh(ga),gh(hausa),"\
|
|
 |
60148ca |
+"gn,gr,hu,hr,ie,ie(CloGaelach),il,"\
|
|
 |
60148ca |
+"in,in(ben),in(guj),in(guru),in(jhelum),in(kan),in(mal),in(ori),in(tam),"\
|
|
 |
b95ef1a |
+"in(tel),in(urd-phonetic),in(bolnagri),iq,iq(ku),ir,ir(ku),is,it,"\
|
|
 |
b95ef1a |
+"kg,kh,kz,la,latam,lk,lk(tam_unicode),lt,lv,ma,ma(tifinagh),mal,mao,"\
|
|
 |
60148ca |
+"me,mk,mm,mt,mv,ng,ng(hausa),ng,ng(igbo),ng(yoruba),nl,no,no(smi),np,"\
|
|
 |
60148ca |
+"pk,pl,pl(csb),pt,ro,rs,ru,ru(cv),ru(kom),ru(sah),ru(tt),ru(xal),"\
|
|
 |
60148ca |
+"se,si,sk,sy,sy(ku),th,tj,tr,ua,uz,vn"]
|
|
 |
60148ca |
+)
|
|
 |
60148ca |
+AC_SUBST(XKB_PRELOAD_LAYOUTS)
|
|
 |
60148ca |
+
|
|
 |
60148ca |
# GObject introspection
|
|
 |
60148ca |
GOBJECT_INTROSPECTION_CHECK([0.6.8])
|
|
 |
60148ca |
|
|
 |
5f53fe6 |
@@ -478,6 +532,7 @@ bindings/Makefile
|
|
 |
60148ca |
bindings/vala/Makefile
|
|
 |
e0a5e11 |
dconf/Makefile
|
|
 |
e0a5e11 |
dconf/dconf.xml.in
|
|
 |
60148ca |
+xkb/Makefile
|
|
 |
60148ca |
])
|
|
 |
60148ca |
|
|
 |
60148ca |
AC_OUTPUT
|
|
 |
5f53fe6 |
@@ -493,6 +548,7 @@ Build options:
|
|
 |
60148ca |
Build gtk2 immodule $enable_gtk2
|
|
 |
60148ca |
Build gtk3 immodule $enable_gtk3
|
|
 |
60148ca |
Build XIM agent server $enable_xim
|
|
 |
60148ca |
+ Build XKB $enable_xkb
|
|
 |
60148ca |
Build python modules $enable_python
|
|
 |
60148ca |
Build gconf modules $enable_gconf
|
|
 |
60148ca |
Build memconf modules $enable_memconf
|
|
 |
60148ca |
diff --git a/data/ibus.schemas.in b/data/ibus.schemas.in
|
|
 |
481f2ee |
index 663358c..e0a6a37 100644
|
|
 |
60148ca |
--- a/data/ibus.schemas.in
|
|
 |
60148ca |
+++ b/data/ibus.schemas.in
|
|
 |
481f2ee |
@@ -191,6 +191,53 @@
|
|
 |
60148ca |
</locale>
|
|
 |
60148ca |
</schema>
|
|
 |
60148ca |
<schema>
|
|
 |
7232d5e |
+ <key>/schemas/desktop/ibus/general/system_keyboard_layout</key>
|
|
 |
7232d5e |
+ <applyto>/desktop/ibus/general/system_keyboard_layout</applyto>
|
|
 |
60148ca |
+ <owner>ibus</owner>
|
|
 |
60148ca |
+ <type>string</type>
|
|
 |
60148ca |
+ <default>default</default>
|
|
 |
60148ca |
+ <gettext_domain>ibus</gettext_domain>
|
|
 |
60148ca |
+ <locale name="C">
|
|
 |
7232d5e |
+ <short>Set system keyboard layout</short>
|
|
 |
60148ca |
+ <long>Override default system keyboard layout. default is 'default'</long>
|
|
 |
60148ca |
+ </locale>
|
|
 |
60148ca |
+ </schema>
|
|
 |
60148ca |
+ <schema>
|
|
 |
7232d5e |
+ <key>/schemas/desktop/ibus/general/system_keyboard_option</key>
|
|
 |
7232d5e |
+ <applyto>/desktop/ibus/general/system_keyboard_option</applyto>
|
|
 |
7232d5e |
+ <owner>ibus</owner>
|
|
 |
7232d5e |
+ <type>string</type>
|
|
 |
7232d5e |
+ <default>default</default>
|
|
 |
7232d5e |
+ <gettext_domain>ibus</gettext_domain>
|
|
 |
7232d5e |
+ <locale name="C">
|
|
 |
7232d5e |
+ <short>Set system keyboard option</short>
|
|
 |
7232d5e |
+ <long>Override default system keyboard option. default is 'default'</long>
|
|
 |
7232d5e |
+ </locale>
|
|
 |
7232d5e |
+ </schema>
|
|
 |
7232d5e |
+ <schema>
|
|
 |
481f2ee |
+ <key>/schemas/desktop/ibus/general/use_xmodmap</key>
|
|
 |
481f2ee |
+ <applyto>/desktop/ibus/general/use_xmodmap</applyto>
|
|
 |
481f2ee |
+ <owner>ibus</owner>
|
|
 |
481f2ee |
+ <type>bool</type>
|
|
 |
481f2ee |
+ <default>true</default>
|
|
 |
481f2ee |
+ <locale name="C">
|
|
 |
481f2ee |
+ <short>Use xmodmap</short>
|
|
 |
481f2ee |
+ <long>Run xmodmap if .xmodmap/.Xmodmap exists.</long>
|
|
 |
481f2ee |
+ </locale>
|
|
 |
481f2ee |
+ </schema>
|
|
 |
481f2ee |
+ <schema>
|
|
 |
60148ca |
+ <key>/schemas/desktop/ibus/general/xkb_latin_layouts</key>
|
|
 |
60148ca |
+ <applyto>/desktop/ibus/general/xkb_latin_layouts</applyto>
|
|
 |
60148ca |
+ <owner>ibus</owner>
|
|
 |
60148ca |
+ <type>list</type>
|
|
 |
60148ca |
+ <list_type>string</list_type>
|
|
 |
b95ef1a |
+ <default>[ara,bg,cz,dev,gr,gur,in,jp(kana),mal,mkd,ru,ua]</default>
|
|
 |
60148ca |
+ <locale name="C">
|
|
 |
60148ca |
+ <short>Latin layout which have no ASCII</short>
|
|
 |
60148ca |
+ <long>us layout is appended to the latin layouts. variant is not needed.</long>
|
|
 |
60148ca |
+ </locale>
|
|
 |
60148ca |
+ </schema>
|
|
 |
60148ca |
+ <schema>
|
|
 |
60148ca |
<key>/schemas/desktop/ibus/panel/use_custom_font</key>
|
|
 |
60148ca |
<applyto>/desktop/ibus/panel/use_custom_font</applyto>
|
|
 |
60148ca |
<owner>ibus</owner>
|
|
 |
84d8da5 |
diff --git a/ibus-1.0.pc.in b/ibus-1.0.pc.in
|
|
 |
84d8da5 |
index 9f593ab..51eb67a 100644
|
|
 |
84d8da5 |
--- a/ibus-1.0.pc.in
|
|
 |
84d8da5 |
+++ b/ibus-1.0.pc.in
|
|
 |
84d8da5 |
@@ -4,6 +4,8 @@ libdir=@libdir@
|
|
 |
84d8da5 |
includedir=@includedir@
|
|
 |
84d8da5 |
datadir=@datadir@
|
|
 |
84d8da5 |
pkgdatadir=@datadir@/ibus
|
|
 |
84d8da5 |
+have_ibus_xkb=@HAVE_IBUS_XKB@
|
|
 |
84d8da5 |
+ibus_xkb=@libexecdir@/ibus-xkb
|
|
 |
84d8da5 |
|
|
 |
84d8da5 |
Name: IBus
|
|
 |
84d8da5 |
Description: IBus Library
|
|
 |
60148ca |
diff --git a/ibus/Makefile.am b/ibus/Makefile.am
|
|
 |
e5da135 |
index c71df1b..508c98f 100644
|
|
 |
60148ca |
--- a/ibus/Makefile.am
|
|
 |
60148ca |
+++ b/ibus/Makefile.am
|
|
 |
60148ca |
@@ -58,12 +58,38 @@ nodist_ibus_PYTHON = \
|
|
 |
60148ca |
|
|
 |
60148ca |
ibusdir = @pkgpythondir@
|
|
 |
60148ca |
|
|
 |
60148ca |
+xkblayout_py_in_files = \
|
|
 |
60148ca |
+ xkblayout.py.in \
|
|
 |
60148ca |
+ xkbxml.py.in \
|
|
 |
60148ca |
+ $(NULL)
|
|
 |
60148ca |
+xkblayout_py_DATA = $(xkblayout_py_in_files:.py.in=.py)
|
|
 |
60148ca |
+xkblayout_pydir = @pkgpythondir@
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+ibus_PYTHON += $(xkblayout_py_DATA)
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+if ENABLE_XKB
|
|
 |
cf977d1 |
+XKB_COMMAND=\\\"$(libexecdir)/ibus-xkb\\\"
|
|
 |
60148ca |
+HAVE_XKB=True
|
|
 |
60148ca |
+else
|
|
 |
60148ca |
+XKB_COMMAND="None"
|
|
 |
60148ca |
+HAVE_XKB=False
|
|
 |
60148ca |
+endif
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+%.py : %.py.in
|
|
 |
60148ca |
+ @sed -e "s|\@XKB_COMMAND\@|$(XKB_COMMAND)|g" \
|
|
 |
60148ca |
+ -e "s|\@XKB_RULES_XML_FILE\@|$(XKB_RULES_XML_FILE)|g" \
|
|
 |
60148ca |
+ -e "s|\@HAVE_XKB\@|$(HAVE_XKB)|g" \
|
|
 |
60148ca |
+ -e "s|\@datadir\@|$(datadir)|g" \
|
|
 |
60148ca |
+ $< > $@
|
|
 |
60148ca |
+
|
|
 |
60148ca |
EXTRA_DIST = \
|
|
 |
60148ca |
_config.py.in \
|
|
 |
60148ca |
+ $(xkblayout_py_in_files) \
|
|
 |
60148ca |
$(NULL)
|
|
 |
60148ca |
|
|
 |
60148ca |
CLEANFILES = \
|
|
 |
60148ca |
*.pyc \
|
|
 |
60148ca |
+ $(xkblayout_py_DATA) \
|
|
 |
60148ca |
$(NULL)
|
|
 |
60148ca |
|
|
 |
60148ca |
DISTCLEANFILES = \
|
|
 |
60148ca |
diff --git a/ibus/__init__.py b/ibus/__init__.py
|
|
 |
60148ca |
index 7c8f8be..3c25605 100644
|
|
 |
60148ca |
--- a/ibus/__init__.py
|
|
 |
60148ca |
+++ b/ibus/__init__.py
|
|
 |
60148ca |
@@ -41,4 +41,6 @@ from text import *
|
|
 |
60148ca |
from observedpath import *
|
|
 |
60148ca |
from enginedesc import *
|
|
 |
60148ca |
from component import *
|
|
 |
60148ca |
+from xkblayout import *
|
|
 |
60148ca |
+from xkbxml import *
|
|
 |
60148ca |
from _config import *
|
|
 |
60148ca |
diff --git a/ibus/bus.py b/ibus/bus.py
|
|
 |
5f53fe6 |
index a8a458d..84b4140 100644
|
|
 |
60148ca |
--- a/ibus/bus.py
|
|
 |
60148ca |
+++ b/ibus/bus.py
|
|
 |
5f53fe6 |
@@ -163,6 +163,9 @@ class Bus(object.Object):
|
|
 |
60148ca |
data = serializable.deserialize_object(data)
|
|
 |
60148ca |
return data
|
|
 |
60148ca |
|
|
 |
60148ca |
+ def get_use_sys_layout(self):
|
|
 |
60148ca |
+ return self.__ibus.GetUseSysLayout();
|
|
 |
60148ca |
+
|
|
 |
60148ca |
def introspect_ibus(self):
|
|
 |
60148ca |
return self.__ibus.Introspect()
|
|
 |
60148ca |
|
|
 |
60148ca |
diff --git a/ibus/interface/iibus.py b/ibus/interface/iibus.py
|
|
 |
9d6bb4f |
index 678d517..7de56fc 100644
|
|
 |
60148ca |
--- a/ibus/interface/iibus.py
|
|
 |
60148ca |
+++ b/ibus/interface/iibus.py
|
|
 |
9d6bb4f |
@@ -75,6 +75,9 @@ class IIBus(dbus.service.Object):
|
|
 |
60148ca |
@method(in_signature="v", out_signature="v")
|
|
 |
60148ca |
def Ping(self, data, dbusconn): pass
|
|
 |
60148ca |
|
|
 |
60148ca |
+ @method(out_signature="b")
|
|
 |
60148ca |
+ def GetUseSysLayout(self, dbusconn): pass
|
|
 |
60148ca |
+
|
|
 |
60148ca |
@signal(signature="")
|
|
 |
60148ca |
def RegistryChanged(self): pass
|
|
 |
60148ca |
|
|
 |
60148ca |
diff --git a/ibus/xkblayout.py.in b/ibus/xkblayout.py.in
|
|
 |
60148ca |
new file mode 100644
|
|
 |
481f2ee |
index 0000000..c0c95ce
|
|
 |
60148ca |
--- /dev/null
|
|
 |
60148ca |
+++ b/ibus/xkblayout.py.in
|
|
 |
481f2ee |
@@ -0,0 +1,360 @@
|
|
 |
60148ca |
+# vim:set et sts=4 sw=4:
|
|
 |
60148ca |
+#
|
|
 |
60148ca |
+# ibus - The Input Bus
|
|
 |
60148ca |
+#
|
|
 |
63b857f |
+# Copyright (c) 2011 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
 |
63b857f |
+# Copyright (c) 2011 Peng Huang <shawn.p.huang@gmail.com>
|
|
 |
63b857f |
+# Copyright (c) 2011 Red Hat, Inc.
|
|
 |
60148ca |
+#
|
|
 |
60148ca |
+# This library is free software; you can redistribute it and/or
|
|
 |
60148ca |
+# modify it under the terms of the GNU Lesser General Public
|
|
 |
60148ca |
+# License as published by the Free Software Foundation; either
|
|
 |
60148ca |
+# version 2 of the License, or (at your option) any later version.
|
|
 |
60148ca |
+#
|
|
 |
60148ca |
+# This library is distributed in the hope that it will be useful,
|
|
 |
60148ca |
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
 |
60148ca |
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
 |
60148ca |
+# GNU Lesser General Public License for more details.
|
|
 |
60148ca |
+#
|
|
 |
60148ca |
+# You should have received a copy of the GNU Lesser General Public
|
|
 |
60148ca |
+# License along with this program; if not, write to the
|
|
 |
60148ca |
+# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
|
 |
60148ca |
+# Boston, MA 02111-1307 USA
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+__all__ = (
|
|
 |
095f9c1 |
+ 'XKBLayout',
|
|
 |
60148ca |
+ )
|
|
 |
60148ca |
+
|
|
 |
cf977d1 |
+import os, sys, time
|
|
 |
481f2ee |
+import glib
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+XKB_COMMAND = @XKB_COMMAND@
|
|
 |
cf977d1 |
+XKB_SESSION_TIME_OUT = 30.0
|
|
 |
481f2ee |
+XMODMAP_CMD = 'xmodmap'
|
|
 |
481f2ee |
+XMODMAP_KNOWN_FILES = ['.xmodmap', '.xmodmaprc', '.Xmodmap', '.Xmodmaprc']
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+class XKBLayout():
|
|
 |
60148ca |
+ def __init__(self, config = None, command=XKB_COMMAND):
|
|
 |
60148ca |
+ self.__config = config
|
|
 |
60148ca |
+ self.__command = command
|
|
 |
7232d5e |
+ self.__use_xkb = True
|
|
 |
481f2ee |
+ self.__xkb_pid = None
|
|
 |
481f2ee |
+ self.__xmodmap_pid = None
|
|
 |
481f2ee |
+ self.__use_xmodmap = True
|
|
 |
7232d5e |
+ if self.__command == None:
|
|
 |
7232d5e |
+ self.__use_xkb = False
|
|
 |
60148ca |
+ self.__default_layout = self.get_layout()
|
|
 |
7232d5e |
+ self.__default_model = self.get_model()
|
|
 |
7232d5e |
+ self.__default_option = self.get_option()
|
|
 |
cf977d1 |
+ self.__time_lag_session_xkb_layout = True
|
|
 |
cf977d1 |
+ self.__time_lag_session_xkb_option = True
|
|
 |
cf977d1 |
+ self.__time_lag_session_xkb_timer = time.time()
|
|
 |
9b3b748 |
+ self.__xkb_latin_layouts = []
|
|
 |
9b3b748 |
+ if config != None:
|
|
 |
095f9c1 |
+ self.__xkb_latin_layouts = list(self.__config.get_value('general',
|
|
 |
095f9c1 |
+ 'xkb_latin_layouts',
|
|
 |
9b3b748 |
+ []))
|
|
 |
481f2ee |
+ self.__use_xmodmap = bool(self.__config.get_value('general',
|
|
 |
481f2ee |
+ 'use_xmodmap',
|
|
 |
481f2ee |
+ True))
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+
|
|
 |
7232d5e |
+ def __get_model_from_layout(self, layout):
|
|
 |
47affbc |
+ left_bracket = layout.find('(')
|
|
 |
47affbc |
+ right_bracket = layout.find(')')
|
|
 |
47affbc |
+ if left_bracket >= 0 and right_bracket > left_bracket:
|
|
 |
095f9c1 |
+ return (layout[:left_bracket] + layout[right_bracket + 1:], \
|
|
 |
47affbc |
+ layout[left_bracket + 1:right_bracket])
|
|
 |
095f9c1 |
+ return (layout, 'default')
|
|
 |
095f9c1 |
+
|
|
 |
095f9c1 |
+ def __get_option_from_layout(self, layout):
|
|
 |
095f9c1 |
+ left_bracket = layout.find('[')
|
|
 |
095f9c1 |
+ right_bracket = layout.find(']')
|
|
 |
095f9c1 |
+ if left_bracket >= 0 and right_bracket > left_bracket:
|
|
 |
095f9c1 |
+ return (layout[:left_bracket] + layout[right_bracket + 1:], \
|
|
 |
095f9c1 |
+ layout[left_bracket + 1:right_bracket])
|
|
 |
095f9c1 |
+ return (layout, 'default')
|
|
 |
7232d5e |
+
|
|
 |
63b857f |
+ def __get_output_from_cmdline(self, arg, string):
|
|
 |
095f9c1 |
+ exec_command = '%s %s' % (self.__command, arg)
|
|
 |
63b857f |
+ retval = None
|
|
 |
63b857f |
+ for line in os.popen(exec_command).readlines():
|
|
 |
63b857f |
+ line = line.strip()
|
|
 |
63b857f |
+ if line.startswith(string):
|
|
 |
63b857f |
+ retval = line[len(string):]
|
|
 |
63b857f |
+ break
|
|
 |
63b857f |
+ return retval
|
|
 |
63b857f |
+
|
|
 |
481f2ee |
+ def __get_userhome(self):
|
|
 |
481f2ee |
+ if 'HOME' not in os.environ:
|
|
 |
481f2ee |
+ import pwd
|
|
 |
481f2ee |
+ userhome = pwd.getpwuid(os.getuid()).pw_dir
|
|
 |
481f2ee |
+ else:
|
|
 |
481f2ee |
+ userhome = os.environ['HOME']
|
|
 |
481f2ee |
+ userhome = userhome.rstrip('/')
|
|
 |
481f2ee |
+ return userhome
|
|
 |
481f2ee |
+
|
|
 |
481f2ee |
+ def __get_fullpath(self, command):
|
|
 |
481f2ee |
+ if 'PATH' in os.environ:
|
|
 |
481f2ee |
+ envpath = os.environ['PATH']
|
|
 |
481f2ee |
+ else:
|
|
 |
481f2ee |
+ envpath = os.defpath
|
|
 |
481f2ee |
+ PATH = envpath.split(os.pathsep)
|
|
 |
481f2ee |
+ for dir in PATH:
|
|
 |
481f2ee |
+ filepath = os.path.join(dir, command)
|
|
 |
481f2ee |
+ if os.path.exists(filepath):
|
|
 |
481f2ee |
+ return filepath
|
|
 |
481f2ee |
+ return None
|
|
 |
481f2ee |
+
|
|
 |
481f2ee |
+ def __set_layout_cb(self, pid, status):
|
|
 |
481f2ee |
+ if self.__xkb_pid != pid:
|
|
 |
481f2ee |
+ print >> sys.stderr, \
|
|
 |
481f2ee |
+ 'ibus.xkblayout: set_layout_cb has another pid'
|
|
 |
481f2ee |
+ return
|
|
 |
481f2ee |
+ self.__xkb_pid.close()
|
|
 |
481f2ee |
+ self.__xkb_pid = None
|
|
 |
481f2ee |
+ self.set_xmodmap()
|
|
 |
481f2ee |
+
|
|
 |
481f2ee |
+ def __set_xmodmap_cb(self, pid, status):
|
|
 |
481f2ee |
+ if self.__xmodmap_pid != pid:
|
|
 |
481f2ee |
+ print >> sys.stderr, \
|
|
 |
481f2ee |
+ 'ibus.xkblayout: set_xmodmap_cb has another pid'
|
|
 |
481f2ee |
+ return
|
|
 |
481f2ee |
+ self.__xmodmap_pid.close()
|
|
 |
481f2ee |
+ self.__xmodmap_pid = None
|
|
 |
481f2ee |
+
|
|
 |
7232d5e |
+ def use_xkb(self, enable):
|
|
 |
60148ca |
+ if self.__command == None:
|
|
 |
7232d5e |
+ return
|
|
 |
7232d5e |
+ self.__use_xkb = enable
|
|
 |
7232d5e |
+
|
|
 |
7232d5e |
+ def get_layout(self):
|
|
 |
7232d5e |
+ if not self.__use_xkb:
|
|
 |
60148ca |
+ return None
|
|
 |
095f9c1 |
+ return self.__get_output_from_cmdline('--get', 'layout: ')
|
|
 |
60148ca |
+
|
|
 |
7232d5e |
+ def get_model(self):
|
|
 |
7232d5e |
+ if not self.__use_xkb:
|
|
 |
7232d5e |
+ return None
|
|
 |
095f9c1 |
+ return self.__get_output_from_cmdline('--get', 'model: ')
|
|
 |
7232d5e |
+
|
|
 |
7232d5e |
+ def get_option(self):
|
|
 |
7232d5e |
+ if not self.__use_xkb:
|
|
 |
7232d5e |
+ return None
|
|
 |
095f9c1 |
+ return self.__get_output_from_cmdline('--get', 'option: ')
|
|
 |
63b857f |
+
|
|
 |
63b857f |
+ def get_group(self):
|
|
 |
63b857f |
+ if not self.__use_xkb:
|
|
 |
63b857f |
+ return 0
|
|
 |
095f9c1 |
+ return int(self.__get_output_from_cmdline('--get-group', 'group: '))
|
|
 |
7232d5e |
+
|
|
 |
095f9c1 |
+ def set_layout(self, layout='default', model='default', option='default'):
|
|
 |
7232d5e |
+ if not self.__use_xkb:
|
|
 |
7232d5e |
+ return
|
|
 |
7232d5e |
+ if layout == None:
|
|
 |
60148ca |
+ return
|
|
 |
1e452ff |
+ if self.__default_layout == None:
|
|
 |
1e452ff |
+ # Maybe opening display was failed in constructor.
|
|
 |
1e452ff |
+ self.reload_default_layout()
|
|
 |
1e452ff |
+ if self.__default_layout == None:
|
|
 |
1e452ff |
+ return
|
|
 |
60148ca |
+ layout = str(layout)
|
|
 |
cf977d1 |
+ # if set_default_layout() is not default, the default layout is
|
|
 |
cf977d1 |
+ # pulled from the current XKB. But it's possible gnome-settings-daemon
|
|
 |
cf977d1 |
+ # does not run yet. I added XKB_SESSION_TIME_OUT for the timer.
|
|
 |
cf977d1 |
+ if self.__time_lag_session_xkb_layout == True:
|
|
 |
cf977d1 |
+ self.__default_layout = self.get_layout()
|
|
 |
cf977d1 |
+ self.__default_model = self.get_model()
|
|
 |
cf977d1 |
+ if self.__time_lag_session_xkb_option == True:
|
|
 |
cf977d1 |
+ self.__default_option = self.get_option()
|
|
 |
cf977d1 |
+ if (self.__time_lag_session_xkb_layout == True or \
|
|
 |
cf977d1 |
+ self.__time_lag_session_xkb_option == True ) and \
|
|
 |
84d8da5 |
+ (time.time() - self.__time_lag_session_xkb_timer \
|
|
 |
cf977d1 |
+ > XKB_SESSION_TIME_OUT):
|
|
 |
cf977d1 |
+ self.__time_lag_session_xkb_layout = False
|
|
 |
cf977d1 |
+ self.__time_lag_session_xkb_option = False
|
|
 |
095f9c1 |
+ if layout == 'default':
|
|
 |
60148ca |
+ layout = self.__default_layout
|
|
 |
cf977d1 |
+ else:
|
|
 |
cf977d1 |
+ self.__time_lag_session_xkb_layout = False
|
|
 |
7232d5e |
+ if model != None:
|
|
 |
7232d5e |
+ model = str(model)
|
|
 |
095f9c1 |
+ if model == 'default':
|
|
 |
7232d5e |
+ (layout, model) = self.__get_model_from_layout(layout)
|
|
 |
095f9c1 |
+ if model == 'default':
|
|
 |
7232d5e |
+ model = self.__default_model
|
|
 |
cf977d1 |
+ else:
|
|
 |
cf977d1 |
+ self.__time_lag_session_xkb_layout = False
|
|
 |
7232d5e |
+ if option != None:
|
|
 |
7232d5e |
+ option = str(option)
|
|
 |
095f9c1 |
+ if option == 'default':
|
|
 |
095f9c1 |
+ (layout, engine_option) = self.__get_option_from_layout(layout)
|
|
 |
095f9c1 |
+ if engine_option != None and engine_option != 'default':
|
|
 |
095f9c1 |
+ option = self.__default_option
|
|
 |
095f9c1 |
+ if option == None:
|
|
 |
095f9c1 |
+ option = engine_option
|
|
 |
095f9c1 |
+ else:
|
|
 |
095f9c1 |
+ option = '%s,%s' % (option, engine_option)
|
|
 |
095f9c1 |
+ self.__time_lag_session_xkb_option = False
|
|
 |
095f9c1 |
+ if option == 'default':
|
|
 |
7232d5e |
+ option = self.__default_option
|
|
 |
60148ca |
+ need_us_layout = False
|
|
 |
60148ca |
+ for latin_layout in self.__xkb_latin_layouts:
|
|
 |
60148ca |
+ latin_layout = str(latin_layout)
|
|
 |
3ef409f |
+ # layout 'in' and model 'eng' is English layout.
|
|
 |
3ef409f |
+ if layout == latin_layout and model != 'eng':
|
|
 |
60148ca |
+ need_us_layout = True
|
|
 |
60148ca |
+ break
|
|
 |
b95ef1a |
+ if model != None and layout + '(' + model + ')' == latin_layout:
|
|
 |
b95ef1a |
+ need_us_layout = True
|
|
 |
b95ef1a |
+ break
|
|
 |
60148ca |
+ if need_us_layout:
|
|
 |
095f9c1 |
+ layout = layout + ',us'
|
|
 |
7232d5e |
+ if model != None:
|
|
 |
095f9c1 |
+ model = model + ','
|
|
 |
7232d5e |
+ if layout == self.get_layout() and \
|
|
 |
7232d5e |
+ model == self.get_model() and \
|
|
 |
7232d5e |
+ option == self.get_option():
|
|
 |
9b3b748 |
+ return
|
|
 |
9b3b748 |
+ args = []
|
|
 |
9b3b748 |
+ args.append(self.__command)
|
|
 |
095f9c1 |
+ args.append('--layout')
|
|
 |
60148ca |
+ args.append(layout)
|
|
 |
7232d5e |
+ if model != None:
|
|
 |
095f9c1 |
+ args.append('--model')
|
|
 |
7232d5e |
+ args.append(model)
|
|
 |
7232d5e |
+ if option != None:
|
|
 |
095f9c1 |
+ args.append('--option')
|
|
 |
7232d5e |
+ args.append(option)
|
|
 |
481f2ee |
+ pid = glib.spawn_async(argv=args,
|
|
 |
481f2ee |
+ flags=glib.SPAWN_DO_NOT_REAP_CHILD)[0]
|
|
 |
481f2ee |
+ self.__xkb_pid = pid
|
|
 |
481f2ee |
+ glib.child_watch_add(self.__xkb_pid, self.__set_layout_cb)
|
|
 |
60148ca |
+
|
|
 |
095f9c1 |
+ def set_default_layout(self, layout='default', model='default'):
|
|
 |
7232d5e |
+ if not self.__use_xkb:
|
|
 |
60148ca |
+ return
|
|
 |
cf977d1 |
+ if layout == None:
|
|
 |
095f9c1 |
+ print >> sys.stderr, 'ibus.xkblayout: None layout'
|
|
 |
cf977d1 |
+ return
|
|
 |
cf977d1 |
+ if model == None:
|
|
 |
095f9c1 |
+ print >> sys.stderr, 'ibus.xkblayout: None model'
|
|
 |
cf977d1 |
+ return
|
|
 |
60148ca |
+ if layout == 'default':
|
|
 |
60148ca |
+ self.__default_layout = self.get_layout()
|
|
 |
b95ef1a |
+ self.__default_model = self.get_model()
|
|
 |
60148ca |
+ else:
|
|
 |
b95ef1a |
+ if model == 'default':
|
|
 |
b95ef1a |
+ (layout, model) = self.__get_model_from_layout(layout)
|
|
 |
60148ca |
+ self.__default_layout = layout
|
|
 |
cf977d1 |
+ self.__time_lag_session_xkb_layout = False
|
|
 |
b95ef1a |
+ if model == 'default':
|
|
 |
b95ef1a |
+ self.__default_model = None
|
|
 |
b95ef1a |
+ else:
|
|
 |
b95ef1a |
+ self.__default_model = model
|
|
 |
60148ca |
+
|
|
 |
095f9c1 |
+ def set_default_option(self, option='default'):
|
|
 |
7232d5e |
+ if not self.__use_xkb:
|
|
 |
7232d5e |
+ return
|
|
 |
cf977d1 |
+ if option == None:
|
|
 |
095f9c1 |
+ print >> sys.stderr, 'ibus.xkblayout: None option'
|
|
 |
cf977d1 |
+ return
|
|
 |
7232d5e |
+ if option == 'default':
|
|
 |
7232d5e |
+ self.__default_option = self.get_option()
|
|
 |
7232d5e |
+ else:
|
|
 |
7232d5e |
+ self.__default_option = option
|
|
 |
cf977d1 |
+ self.__time_lag_session_xkb_option = False
|
|
 |
7232d5e |
+
|
|
 |
63b857f |
+ def get_default_layout(self):
|
|
 |
63b857f |
+ return [self.__default_layout, self.__default_model];
|
|
 |
63b857f |
+
|
|
 |
63b857f |
+ def get_default_option(self):
|
|
 |
63b857f |
+ return self.__default_option
|
|
 |
63b857f |
+
|
|
 |
60148ca |
+ def reload_default_layout(self):
|
|
 |
7232d5e |
+ if not self.__use_xkb:
|
|
 |
60148ca |
+ return
|
|
 |
60148ca |
+ self.__default_layout = self.get_layout()
|
|
 |
7232d5e |
+ self.__default_model = self.get_model()
|
|
 |
7232d5e |
+ self.__default_option = self.get_option()
|
|
 |
481f2ee |
+
|
|
 |
481f2ee |
+ def set_xmodmap(self):
|
|
 |
481f2ee |
+ if not self.__use_xmodmap:
|
|
 |
481f2ee |
+ return
|
|
 |
481f2ee |
+ if self.__xmodmap_pid != None:
|
|
 |
481f2ee |
+ return
|
|
 |
481f2ee |
+ xmodmap_cmdpath = self.__get_fullpath(XMODMAP_CMD)
|
|
 |
481f2ee |
+ if xmodmap_cmdpath == None:
|
|
 |
481f2ee |
+ xmodmap_cmdpath = XMODMAP_CMD
|
|
 |
481f2ee |
+ for xmodmap_file in XMODMAP_KNOWN_FILES:
|
|
 |
481f2ee |
+ xmodmap_filepath = os.path.join(self.__get_userhome(), xmodmap_file)
|
|
 |
481f2ee |
+ if not os.path.exists(xmodmap_filepath):
|
|
 |
481f2ee |
+ continue
|
|
 |
481f2ee |
+ pid = glib.spawn_async(argv=[xmodmap_cmdpath, xmodmap_filepath],
|
|
 |
481f2ee |
+ flags=glib.SPAWN_DO_NOT_REAP_CHILD)[0]
|
|
 |
481f2ee |
+ self.__xmodmap_pid = pid
|
|
 |
481f2ee |
+ glib.child_watch_add(self.__xmodmap_pid, self.__set_xmodmap_cb)
|
|
 |
481f2ee |
+ break
|
|
 |
481f2ee |
+
|
|
 |
481f2ee |
+
|
|
 |
481f2ee |
+def test():
|
|
 |
481f2ee |
+ import gtk
|
|
 |
481f2ee |
+ import ibus
|
|
 |
481f2ee |
+
|
|
 |
481f2ee |
+ window = None
|
|
 |
481f2ee |
+ config = None
|
|
 |
481f2ee |
+ xkblayout = None
|
|
 |
481f2ee |
+
|
|
 |
481f2ee |
+ def __destroy(*args):
|
|
 |
481f2ee |
+ window.hide()
|
|
 |
481f2ee |
+ gtk.main_quit()
|
|
 |
481f2ee |
+
|
|
 |
481f2ee |
+ def __test_set_session_xkb(button):
|
|
 |
481f2ee |
+ xkblayout.set_layout('default')
|
|
 |
481f2ee |
+ print 'Reset the default keymap'
|
|
 |
481f2ee |
+ print 'Layout:', xkblayout.get_default_layout()
|
|
 |
481f2ee |
+ print 'Option:', xkblayout.get_default_option()
|
|
 |
481f2ee |
+
|
|
 |
481f2ee |
+ def __test_set_user_xkb(button):
|
|
 |
481f2ee |
+ layout = 'us'
|
|
 |
481f2ee |
+ model = 'default'
|
|
 |
481f2ee |
+ option = 'default'
|
|
 |
481f2ee |
+ if len(sys.argv) > 1:
|
|
 |
481f2ee |
+ layout = sys.argv[1]
|
|
 |
481f2ee |
+ if len(sys.argv) > 2:
|
|
 |
481f2ee |
+ model = sys.argv[2]
|
|
 |
481f2ee |
+ if model == 'None':
|
|
 |
481f2ee |
+ model = None
|
|
 |
481f2ee |
+ if len(sys.argv) > 3:
|
|
 |
481f2ee |
+ option = sys.argv[3]
|
|
 |
481f2ee |
+ if option == 'None':
|
|
 |
481f2ee |
+ optoin = None
|
|
 |
481f2ee |
+ xkblayout.set_layout(layout, model, option)
|
|
 |
481f2ee |
+ print 'Test set_layout:', layout, model, option
|
|
 |
481f2ee |
+
|
|
 |
481f2ee |
+ if ibus.get_address() != None:
|
|
 |
481f2ee |
+ bus = ibus.Bus()
|
|
 |
481f2ee |
+ config = bus.get_config()
|
|
 |
481f2ee |
+ else:
|
|
 |
481f2ee |
+ print 'no ibus'
|
|
 |
481f2ee |
+ xkblayout = XKBLayout(config)
|
|
 |
481f2ee |
+ print 'Layout:', xkblayout.get_default_layout()
|
|
 |
481f2ee |
+ print 'Option:', xkblayout.get_default_option()
|
|
 |
481f2ee |
+ window = gtk.Window(gtk.WINDOW_TOPLEVEL)
|
|
 |
481f2ee |
+ window.connect('destroy', __destroy)
|
|
 |
481f2ee |
+ vb = gtk.VBox()
|
|
 |
481f2ee |
+ window.add(vb)
|
|
 |
481f2ee |
+ b = gtk.Button('Test xkb')
|
|
 |
481f2ee |
+ b.connect('clicked', __test_set_user_xkb)
|
|
 |
481f2ee |
+ vb.add(b)
|
|
 |
481f2ee |
+ b = gtk.Button('Reset the default xkb')
|
|
 |
481f2ee |
+ b.connect('clicked', __test_set_session_xkb)
|
|
 |
481f2ee |
+ vb.add(b)
|
|
 |
481f2ee |
+ window.show_all()
|
|
 |
481f2ee |
+ if config != None:
|
|
 |
481f2ee |
+ ibus.main()
|
|
 |
481f2ee |
+ else:
|
|
 |
481f2ee |
+ gtk.main()
|
|
 |
481f2ee |
+
|
|
 |
481f2ee |
+if __name__ == '__main__':
|
|
 |
481f2ee |
+ test()
|
|
 |
60148ca |
diff --git a/ibus/xkbxml.py.in b/ibus/xkbxml.py.in
|
|
 |
60148ca |
new file mode 100644
|
|
 |
0318d1b |
index 0000000..9407c13
|
|
 |
60148ca |
--- /dev/null
|
|
 |
60148ca |
+++ b/ibus/xkbxml.py.in
|
|
 |
0318d1b |
@@ -0,0 +1,419 @@
|
|
 |
60148ca |
+# vim:set et sts=4 sw=4:
|
|
 |
60148ca |
+#
|
|
 |
60148ca |
+# ibus - The Input Bus
|
|
 |
60148ca |
+#
|
|
 |
63b857f |
+# Copyright (c) 2011 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
 |
63b857f |
+# Copyright (c) 2011 Peng Huang <shawn.p.huang@gmail.com>
|
|
 |
63b857f |
+# Copyright (c) 2011 Red Hat, Inc.
|
|
 |
60148ca |
+#
|
|
 |
60148ca |
+# This library is free software; you can redistribute it and/or
|
|
 |
60148ca |
+# modify it under the terms of the GNU Lesser General Public
|
|
 |
60148ca |
+# License as published by the Free Software Foundation; either
|
|
 |
60148ca |
+# version 2 of the License, or (at your option) any later version.
|
|
 |
60148ca |
+#
|
|
 |
60148ca |
+# This library is distributed in the hope that it will be useful,
|
|
 |
60148ca |
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
 |
60148ca |
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
 |
60148ca |
+# GNU Lesser General Public License for more details.
|
|
 |
60148ca |
+#
|
|
 |
60148ca |
+# You should have received a copy of the GNU Lesser General Public
|
|
 |
60148ca |
+# License along with this program; if not, write to the
|
|
 |
60148ca |
+# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
|
 |
60148ca |
+# Boston, MA 02111-1307 USA
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+__all__ = (
|
|
 |
095f9c1 |
+ 'XKBConfigRegistry',
|
|
 |
095f9c1 |
+ 'XKBLayoutConfig',
|
|
 |
60148ca |
+ )
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+import os
|
|
 |
60148ca |
+import string
|
|
 |
60148ca |
+import xml.sax as sax
|
|
 |
60148ca |
+import enginedesc
|
|
 |
60148ca |
+from xml.sax.saxutils import XMLFilterBase, XMLGenerator
|
|
 |
60148ca |
+from xml.sax._exceptions import SAXParseException
|
|
 |
60148ca |
+from cStringIO import StringIO
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+try:
|
|
 |
60148ca |
+ from glib import get_user_config_dir
|
|
 |
60148ca |
+except ImportError:
|
|
 |
60148ca |
+ get_user_config_dir = lambda : None
|
|
 |
60148ca |
+
|
|
 |
095f9c1 |
+XKB_RULES_XML_FILE = '@XKB_RULES_XML_FILE@'
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+class XKBConfigRegistryHandler(XMLFilterBase):
|
|
 |
60148ca |
+ def __init__(self, parser=None, root='root'):
|
|
 |
60148ca |
+ XMLFilterBase.__init__(self, parser)
|
|
 |
60148ca |
+ self.__root = root
|
|
 |
60148ca |
+ self.__current_node = root
|
|
 |
7232d5e |
+ self.__layoutlist_array = {}
|
|
 |
7232d5e |
+ self.__layoutlist = False
|
|
 |
60148ca |
+ self.__layout = False
|
|
 |
60148ca |
+ self.__layout_label = None
|
|
 |
60148ca |
+ self.__layout_desc = {}
|
|
 |
60148ca |
+ self.__layout_lang = {}
|
|
 |
60148ca |
+ self.__variantlist = False
|
|
 |
60148ca |
+ self.__variant = False
|
|
 |
60148ca |
+ self.__variant_label = None
|
|
 |
60148ca |
+ self.__variant_desc = {}
|
|
 |
7232d5e |
+ self.__optionlist_array = {}
|
|
 |
7232d5e |
+ self.__optionlist = False
|
|
 |
7232d5e |
+ self.__option_group_desc = {}
|
|
 |
7232d5e |
+ self.__option_desc = {}
|
|
 |
7232d5e |
+ self.__option = False
|
|
 |
7232d5e |
+ self.__option_label = None
|
|
 |
7232d5e |
+ self.__group = False
|
|
 |
7232d5e |
+ self.__group_label = None
|
|
 |
7232d5e |
+
|
|
 |
7232d5e |
+ def __characters_layoutlist(self, text):
|
|
 |
60148ca |
+ if not self.__layout:
|
|
 |
60148ca |
+ return
|
|
 |
60148ca |
+ if self.__variant:
|
|
 |
095f9c1 |
+ if self.__current_node == 'name':
|
|
 |
60148ca |
+ self.__variant_label = text
|
|
 |
60148ca |
+ if self.__layout_label != None and \
|
|
 |
7232d5e |
+ self.__layout_label in self.__layoutlist_array:
|
|
 |
7232d5e |
+ self.__layoutlist_array[self.__layout_label].append(text)
|
|
 |
095f9c1 |
+ elif self.__current_node == 'description':
|
|
 |
095f9c1 |
+ label = '%s(%s)' % (self.__layout_label, self.__variant_label)
|
|
 |
e5da135 |
+ self.__variant_desc[label] = text
|
|
 |
095f9c1 |
+ elif self.__current_node == 'iso639Id':
|
|
 |
60148ca |
+ label = self.__layout_label
|
|
 |
60148ca |
+ if label != None:
|
|
 |
095f9c1 |
+ label = '%s(%s)' % (label, self.__variant_label)
|
|
 |
60148ca |
+ else:
|
|
 |
60148ca |
+ label = self.__variant_label
|
|
 |
60148ca |
+ if label not in self.__layout_lang:
|
|
 |
60148ca |
+ self.__layout_lang[label] = []
|
|
 |
60148ca |
+ self.__layout_lang[label].append(text)
|
|
 |
60148ca |
+ else:
|
|
 |
60148ca |
+ pass
|
|
 |
60148ca |
+ else:
|
|
 |
095f9c1 |
+ if self.__current_node == 'name':
|
|
 |
60148ca |
+ self.__layout_label = text
|
|
 |
7232d5e |
+ self.__layoutlist_array[self.__layout_label] = []
|
|
 |
095f9c1 |
+ elif self.__current_node == 'description':
|
|
 |
60148ca |
+ self.__layout_desc[self.__layout_label] = text
|
|
 |
095f9c1 |
+ elif self.__current_node == 'iso639Id':
|
|
 |
60148ca |
+ if self.__layout_label not in self.__layout_lang:
|
|
 |
60148ca |
+ self.__layout_lang[self.__layout_label] = []
|
|
 |
60148ca |
+ self.__layout_lang[self.__layout_label].append(text)
|
|
 |
60148ca |
+ else:
|
|
 |
60148ca |
+ pass
|
|
 |
60148ca |
+
|
|
 |
7232d5e |
+ def __characters_optionlist(self, text):
|
|
 |
7232d5e |
+ if not self.__group:
|
|
 |
7232d5e |
+ return
|
|
 |
7232d5e |
+ if self.__option:
|
|
 |
095f9c1 |
+ if self.__current_node == 'name':
|
|
 |
7232d5e |
+ self.__option_label = text
|
|
 |
7232d5e |
+ if self.__group_label != None and \
|
|
 |
7232d5e |
+ self.__group_label in self.__optionlist_array:
|
|
 |
7232d5e |
+ self.__optionlist_array[self.__group_label].append(text)
|
|
 |
095f9c1 |
+ elif self.__current_node == 'description':
|
|
 |
7232d5e |
+ self.__option_desc[self.__option_label] = text
|
|
 |
7232d5e |
+ else:
|
|
 |
7232d5e |
+ pass
|
|
 |
7232d5e |
+ else:
|
|
 |
095f9c1 |
+ if self.__current_node == 'name':
|
|
 |
7232d5e |
+ self.__group_label = text
|
|
 |
7232d5e |
+ self.__optionlist_array[self.__group_label] = []
|
|
 |
095f9c1 |
+ elif self.__current_node == 'description':
|
|
 |
7232d5e |
+ self.__option_group_desc[self.__group_label] = text
|
|
 |
7232d5e |
+ else:
|
|
 |
7232d5e |
+ pass
|
|
 |
7232d5e |
+
|
|
 |
7232d5e |
+ def startElement(self, name, attrs):
|
|
 |
7232d5e |
+ self.__current_node = name
|
|
 |
095f9c1 |
+ if name == 'layoutList':
|
|
 |
7232d5e |
+ self.__layoutlist = True
|
|
 |
095f9c1 |
+ elif name == 'layout':
|
|
 |
7232d5e |
+ self.__layout = True
|
|
 |
7232d5e |
+ self.__layout_label = None
|
|
 |
095f9c1 |
+ elif name == 'variantList':
|
|
 |
7232d5e |
+ self.__variantlist = True
|
|
 |
095f9c1 |
+ elif name == 'variant':
|
|
 |
7232d5e |
+ self.__variant = True
|
|
 |
7232d5e |
+ self.__variant_label = None
|
|
 |
095f9c1 |
+ elif name == 'optionList':
|
|
 |
7232d5e |
+ self.__optionlist = True
|
|
 |
095f9c1 |
+ elif name == 'option':
|
|
 |
7232d5e |
+ self.__option = True
|
|
 |
7232d5e |
+ self.__option_label = None
|
|
 |
095f9c1 |
+ elif name == 'group':
|
|
 |
7232d5e |
+ self.__group = True
|
|
 |
7232d5e |
+ self.__group_label = None
|
|
 |
7232d5e |
+
|
|
 |
7232d5e |
+ def endElement(self, name):
|
|
 |
7232d5e |
+ self.__current_node = self.__root
|
|
 |
095f9c1 |
+ if name == 'layoutList':
|
|
 |
7232d5e |
+ self.__layoutlist = False
|
|
 |
095f9c1 |
+ elif name == 'layout':
|
|
 |
7232d5e |
+ self.__layout = False
|
|
 |
095f9c1 |
+ elif name == 'variantList':
|
|
 |
7232d5e |
+ self.__variantlist = False
|
|
 |
095f9c1 |
+ elif name == 'variant':
|
|
 |
7232d5e |
+ self.__variant = False
|
|
 |
095f9c1 |
+ elif name == 'optionList':
|
|
 |
7232d5e |
+ self.__optionlist = False
|
|
 |
095f9c1 |
+ elif name == 'option':
|
|
 |
7232d5e |
+ self.__option = False
|
|
 |
095f9c1 |
+ elif name == 'group':
|
|
 |
7232d5e |
+ self.__group = False
|
|
 |
7232d5e |
+
|
|
 |
7232d5e |
+ def characters(self, text):
|
|
 |
7232d5e |
+ if self.__current_node == self.__root:
|
|
 |
7232d5e |
+ return
|
|
 |
7232d5e |
+ if self.__layoutlist:
|
|
 |
7232d5e |
+ self.__characters_layoutlist(text)
|
|
 |
7232d5e |
+ elif self.__optionlist:
|
|
 |
7232d5e |
+ self.__characters_optionlist(text)
|
|
 |
7232d5e |
+
|
|
 |
60148ca |
+ def getLayoutList(self):
|
|
 |
7232d5e |
+ return self.__layoutlist_array
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+ def getLayoutDesc(self):
|
|
 |
60148ca |
+ return self.__layout_desc
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+ def getLayoutLang(self):
|
|
 |
60148ca |
+ return self.__layout_lang
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+ def getVariantDesc(self):
|
|
 |
60148ca |
+ return self.__variant_desc
|
|
 |
60148ca |
+
|
|
 |
7232d5e |
+ def getOptionList(self):
|
|
 |
7232d5e |
+ return self.__optionlist_array
|
|
 |
7232d5e |
+
|
|
 |
7232d5e |
+ def getOptionGroupDesc(self):
|
|
 |
7232d5e |
+ return self.__option_group_desc
|
|
 |
7232d5e |
+
|
|
 |
7232d5e |
+ def getOptionDesc(self):
|
|
 |
7232d5e |
+ return self.__option_desc
|
|
 |
7232d5e |
+
|
|
 |
60148ca |
+class XKBLayoutConfigHandler(XMLFilterBase):
|
|
 |
60148ca |
+ def __init__(self,
|
|
 |
60148ca |
+ parser=None,
|
|
 |
60148ca |
+ downstream=None,
|
|
 |
60148ca |
+ preload_layouts=None,
|
|
 |
60148ca |
+ root='root'):
|
|
 |
60148ca |
+ XMLFilterBase.__init__(self, parser)
|
|
 |
60148ca |
+ self.__downstream = downstream
|
|
 |
60148ca |
+ self.__preload_layouts = preload_layouts
|
|
 |
60148ca |
+ self.__root = root
|
|
 |
60148ca |
+ self.__current_node = root
|
|
 |
60148ca |
+ self.__xkblayout = False
|
|
 |
60148ca |
+ self.__config = False
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+ def startDocument(self):
|
|
 |
60148ca |
+ if self.__downstream != None:
|
|
 |
60148ca |
+ self.__downstream.startDocument()
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+ def endDocument(self):
|
|
 |
60148ca |
+ if self.__downstream != None:
|
|
 |
60148ca |
+ self.__downstream.endDocument()
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+ def startElement(self, name, attrs):
|
|
 |
60148ca |
+ self.__current_node = name
|
|
 |
095f9c1 |
+ if name == 'xkblayout':
|
|
 |
60148ca |
+ self.__xkblayout = True
|
|
 |
095f9c1 |
+ if name == 'config':
|
|
 |
60148ca |
+ self.__config = True
|
|
 |
60148ca |
+ if self.__downstream != None:
|
|
 |
60148ca |
+ self.__downstream.startElement(name, {})
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+ def endElement(self, name):
|
|
 |
60148ca |
+ self.__current_node = self.__root
|
|
 |
095f9c1 |
+ if name == 'xkblayout':
|
|
 |
60148ca |
+ self.__xkblayout = False
|
|
 |
095f9c1 |
+ if name == 'config':
|
|
 |
60148ca |
+ self.__config = False
|
|
 |
60148ca |
+ if self.__downstream != None:
|
|
 |
60148ca |
+ self.__downstream.endElement(name)
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+ def characters(self, text):
|
|
 |
60148ca |
+ if self.__current_node == self.__root:
|
|
 |
60148ca |
+ return
|
|
 |
60148ca |
+ if not self.__xkblayout or not self.__config:
|
|
 |
60148ca |
+ return
|
|
 |
095f9c1 |
+ if self.__current_node == 'preload_layouts':
|
|
 |
60148ca |
+ if self.__preload_layouts == None:
|
|
 |
60148ca |
+ self.__preload_layouts = text.split(',')
|
|
 |
60148ca |
+ self.__preload_layouts.sort()
|
|
 |
60148ca |
+ if self.__downstream != None:
|
|
 |
60148ca |
+ self.__downstream.characters(string.join(self.__preload_layouts,
|
|
 |
60148ca |
+ ','))
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+ def getPreloadLayouts(self):
|
|
 |
60148ca |
+ return self.__preload_layouts
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+class XKBConfigRegistry():
|
|
 |
60148ca |
+ def __init__(self, file_path=XKB_RULES_XML_FILE):
|
|
 |
60148ca |
+ self.__handler = None
|
|
 |
60148ca |
+ parser = sax.make_parser()
|
|
 |
60148ca |
+ parser.setFeature(sax.handler.feature_namespaces, 0)
|
|
 |
60148ca |
+ self.__handler = XKBConfigRegistryHandler(parser)
|
|
 |
60148ca |
+ parser.setContentHandler(self.__handler)
|
|
 |
60148ca |
+ f = file(file_path, 'r')
|
|
 |
60148ca |
+ try:
|
|
 |
60148ca |
+ parser.parse(f)
|
|
 |
60148ca |
+ except SAXParseException:
|
|
 |
095f9c1 |
+ print 'ERROR: invalid file format', file_path
|
|
 |
60148ca |
+ finally:
|
|
 |
60148ca |
+ f.close()
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+ def get_layout_list(self):
|
|
 |
60148ca |
+ return self.__handler.getLayoutList()
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+ def get_layout_desc(self):
|
|
 |
60148ca |
+ return self.__handler.getLayoutDesc()
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+ def get_layout_lang(self):
|
|
 |
60148ca |
+ return self.__handler.getLayoutLang()
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+ def get_variant_desc(self):
|
|
 |
60148ca |
+ return self.__handler.getVariantDesc()
|
|
 |
60148ca |
+
|
|
 |
7232d5e |
+ def get_option_list(self):
|
|
 |
7232d5e |
+ return self.__handler.getOptionList()
|
|
 |
7232d5e |
+
|
|
 |
7232d5e |
+ def get_option_group_desc(self):
|
|
 |
7232d5e |
+ return self.__handler.getOptionGroupDesc()
|
|
 |
7232d5e |
+
|
|
 |
7232d5e |
+ def get_option_desc(self):
|
|
 |
7232d5e |
+ return self.__handler.getOptionDesc()
|
|
 |
7232d5e |
+
|
|
 |
60148ca |
+ @classmethod
|
|
 |
60148ca |
+ def have_xkb(self):
|
|
 |
60148ca |
+ return @HAVE_XKB@
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+ @classmethod
|
|
 |
60148ca |
+ def engine_desc_new(self,
|
|
 |
60148ca |
+ lang,
|
|
 |
60148ca |
+ layout,
|
|
 |
60148ca |
+ layout_desc=None,
|
|
 |
60148ca |
+ variant=None,
|
|
 |
095f9c1 |
+ variant_desc=None,
|
|
 |
0318d1b |
+ name=None):
|
|
 |
692f6ca |
+ if variant_desc != None:
|
|
 |
692f6ca |
+ longname = variant_desc
|
|
 |
60148ca |
+ elif layout != None and variant != None:
|
|
 |
095f9c1 |
+ longname = layout + ' - ' + variant
|
|
 |
60148ca |
+ elif layout_desc != None:
|
|
 |
60148ca |
+ longname = layout_desc
|
|
 |
60148ca |
+ else:
|
|
 |
60148ca |
+ longname = layout
|
|
 |
0318d1b |
+ name_prefix='xkb:layout:'
|
|
 |
60148ca |
+ if variant != None:
|
|
 |
0318d1b |
+ if name == None:
|
|
 |
0318d1b |
+ name = name_prefix + layout + ':' + variant
|
|
 |
095f9c1 |
+ desc = 'XKB ' + layout + '(' + variant + ') keyboard layout'
|
|
 |
095f9c1 |
+ engine_layout = layout + '(' + variant + ')'
|
|
 |
60148ca |
+ else:
|
|
 |
0318d1b |
+ if name == None:
|
|
 |
0318d1b |
+ name = name_prefix + layout
|
|
 |
095f9c1 |
+ desc = 'XKB ' + layout + ' keyboard layout'
|
|
 |
60148ca |
+ engine_layout = layout
|
|
 |
60148ca |
+
|
|
 |
095f9c1 |
+ icon = 'ibus-engine'
|
|
 |
095f9c1 |
+
|
|
 |
60148ca |
+ engine = enginedesc.EngineDesc(name, longname, desc, lang,
|
|
 |
095f9c1 |
+ 'LGPL2.1',
|
|
 |
095f9c1 |
+ 'Takao Fujiwara <takao.fujiwara1@gmail.com>',
|
|
 |
095f9c1 |
+ icon,
|
|
 |
60148ca |
+ engine_layout)
|
|
 |
60148ca |
+ return engine
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+class XKBLayoutConfig():
|
|
 |
60148ca |
+ def __init__(self,
|
|
 |
095f9c1 |
+ system_config='@datadir@/ibus/xkb/xkblayoutconfig.xml'):
|
|
 |
60148ca |
+ self.__user_config = get_user_config_dir()
|
|
 |
60148ca |
+ if self.__user_config == None:
|
|
 |
095f9c1 |
+ self.__user_config = os.environ['HOME'] + '/.config'
|
|
 |
60148ca |
+ self.__user_config = self.__user_config + \
|
|
 |
095f9c1 |
+ '/ibus/xkb/xkblayoutconfig.xml'
|
|
 |
60148ca |
+ self.__system_config = system_config
|
|
 |
60148ca |
+ self.__filter_handler = None
|
|
 |
60148ca |
+ self.__load()
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+ def __load(self, downstream=None, preload_layouts=None):
|
|
 |
60148ca |
+ parser = sax.make_parser()
|
|
 |
60148ca |
+ parser.setFeature(sax.handler.feature_namespaces, 0)
|
|
 |
60148ca |
+ self.__filter_handler = XKBLayoutConfigHandler(parser,
|
|
 |
60148ca |
+ downstream,
|
|
 |
60148ca |
+ preload_layouts)
|
|
 |
60148ca |
+ parser.setContentHandler(self.__filter_handler)
|
|
 |
60148ca |
+ f = None
|
|
 |
60148ca |
+ if os.path.exists(self.__user_config):
|
|
 |
60148ca |
+ f = file(self.__user_config)
|
|
 |
60148ca |
+ elif os.path.exists(self.__system_config):
|
|
 |
60148ca |
+ f = file(self.__system_config)
|
|
 |
60148ca |
+ if f == None:
|
|
 |
60148ca |
+ return
|
|
 |
60148ca |
+ try:
|
|
 |
60148ca |
+ parser.parse(f)
|
|
 |
60148ca |
+ except SAXParseException:
|
|
 |
095f9c1 |
+ print 'ERROR: invalid file format', self.__user_config
|
|
 |
60148ca |
+ finally:
|
|
 |
60148ca |
+ f.close()
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+ def get_preload_layouts(self):
|
|
 |
60148ca |
+ return self.__filter_handler.getPreloadLayouts()
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+ def save_preload_layouts(self, layouts):
|
|
 |
60148ca |
+ if layouts == None:
|
|
 |
60148ca |
+ if os.path.exists(self.__user_config):
|
|
 |
60148ca |
+ os.unlink(self.__user_config)
|
|
 |
60148ca |
+ return
|
|
 |
60148ca |
+ parser = sax.make_parser()
|
|
 |
60148ca |
+ parser.setFeature(sax.handler.feature_namespaces, 0)
|
|
 |
60148ca |
+ result = StringIO()
|
|
 |
60148ca |
+ downstream_handler = XMLGenerator(result, 'utf-8')
|
|
 |
60148ca |
+ self.__load(downstream_handler, layouts)
|
|
 |
60148ca |
+ contents = result.getvalue()
|
|
 |
60148ca |
+ dir = os.path.dirname(self.__user_config)
|
|
 |
60148ca |
+ if not os.path.exists(dir):
|
|
 |
60148ca |
+ os.makedirs(dir, 0700)
|
|
 |
60148ca |
+ f = open(self.__user_config, 'w')
|
|
 |
60148ca |
+ f.write(contents)
|
|
 |
60148ca |
+ f.close()
|
|
 |
60148ca |
+ os.chmod(self.__user_config, 0600)
|
|
 |
60148ca |
+
|
|
 |
60148ca |
+def test():
|
|
 |
60148ca |
+ xkbconfig = XKBConfigRegistry()
|
|
 |
60148ca |
+ layout_list = xkbconfig.get_layout_list()
|
|
 |
60148ca |
+ layout_desc = xkbconfig.get_layout_desc()
|
|
 |
60148ca |
+ layout_lang = xkbconfig.get_layout_lang()
|
|
 |
60148ca |
+ variant_desc = xkbconfig.get_variant_desc()
|
|
 |
60148ca |
+ for layout in layout_list.keys():
|
|
 |
60148ca |
+ if layout not in layout_lang:
|
|
 |
095f9c1 |
+ print 'layout name:', layout, 'NO-LANG description:', layout_desc[layout]
|
|
 |
60148ca |
+ continue
|
|
 |
60148ca |
+ lang = layout_lang[layout]
|
|
 |
095f9c1 |
+ print 'layout name:', layout, 'lang:', lang, 'description:', layout_desc[layout]
|
|
 |
60148ca |
+ for variant in layout_list[layout]:
|
|
 |
095f9c1 |
+ label = '%s(%s)' % (layout, variant)
|
|
 |
60148ca |
+ if label in layout_lang:
|
|
 |
60148ca |
+ lang = layout_lang[label]
|
|
 |
095f9c1 |
+ print ' variant name:', variant, 'lang:', lang, 'description:', variant_desc[variant]
|
|
 |
60148ca |
+
|
|
 |
7232d5e |
+ option_list = xkbconfig.get_option_list()
|
|
 |
7232d5e |
+ option_group_desc = xkbconfig.get_option_group_desc()
|
|
 |
7232d5e |
+ option_desc = xkbconfig.get_option_desc()
|
|
 |
7232d5e |
+ for option_group in option_list.keys():
|
|
 |
095f9c1 |
+ print 'option group name:', option_group, 'description:', option_group_desc[option_group]
|
|
 |
7232d5e |
+ for option in option_list[option_group]:
|
|
 |
095f9c1 |
+ print ' option name:', option, 'description:', option_desc[option]
|
|
 |
7232d5e |
+
|
|
 |
60148ca |
+def test2():
|
|
 |
095f9c1 |
+ xkblayoutconfig = XKBLayoutConfig('../xkb/xkblayoutconfig.xml')
|
|
 |
60148ca |
+ list = xkblayoutconfig.get_preload_layouts()
|
|
 |
60148ca |
+ print list
|
|
 |
60148ca |
+ if list == None:
|
|
 |
60148ca |
+ list = []
|
|
 |
095f9c1 |
+ list.append('gb(test)')
|
|
 |
60148ca |
+ list.sort()
|
|
 |
60148ca |
+ #xkblayoutconfig.save_preload_layouts(list)
|
|
 |
60148ca |
+
|
|
 |
095f9c1 |
+if __name__ == '__main__':
|
|
 |
60148ca |
+ test()
|
|
 |
60148ca |
+ test2()
|
|
 |
7232d5e |
diff --git a/setup/Makefile.am b/setup/Makefile.am
|
|
 |
e5da135 |
index 9618d7f..48b1fed 100644
|
|
 |
7232d5e |
--- a/setup/Makefile.am
|
|
 |
7232d5e |
+++ b/setup/Makefile.am
|
|
 |
f0777a3 |
@@ -28,6 +28,7 @@ ibussetup_PYTHON = \
|
|
 |
7232d5e |
enginetreeview.py \
|
|
 |
7232d5e |
engineabout.py \
|
|
 |
7232d5e |
keyboardshortcut.py \
|
|
 |
b95ef1a |
+ xkbsetup.py \
|
|
 |
7232d5e |
$(NULL)
|
|
 |
7232d5e |
|
|
 |
7232d5e |
ibussetup_DATA = \
|
|
 |
b95ef1a |
diff --git a/setup/enginecombobox.py b/setup/enginecombobox.py
|
|
 |
f0777a3 |
index 2fd8876..7383177 100644
|
|
 |
b95ef1a |
--- a/setup/enginecombobox.py
|
|
 |
b95ef1a |
+++ b/setup/enginecombobox.py
|
|
 |
f0777a3 |
@@ -43,6 +43,7 @@ class EngineComboBox(gtk.ComboBox):
|
|
 |
b95ef1a |
self.connect("notify::active", self.__notify_active_cb)
|
|
 |
b95ef1a |
|
|
 |
b95ef1a |
self.__model = None
|
|
 |
b95ef1a |
+ self.__title = _("Select an input method")
|
|
 |
b95ef1a |
|
|
 |
b95ef1a |
renderer = gtk.CellRendererPixbuf()
|
|
 |
b95ef1a |
renderer.set_property("xalign", 0)
|
|
 |
b95ef1a |
@@ -117,7 +118,7 @@ class EngineComboBox(gtk.ComboBox):
|
|
 |
b95ef1a |
renderer.set_property("weight", pango.WEIGHT_NORMAL)
|
|
 |
b95ef1a |
elif isinstance(engine, int):
|
|
 |
b95ef1a |
renderer.set_property("sensitive", True)
|
|
 |
b95ef1a |
- renderer.set_property("text", _("Select an input method"))
|
|
 |
b95ef1a |
+ renderer.set_property("text", self.__title)
|
|
 |
b95ef1a |
renderer.set_property("weight", pango.WEIGHT_NORMAL)
|
|
 |
b95ef1a |
else:
|
|
 |
b95ef1a |
renderer.set_property("sensitive", True)
|
|
 |
b95ef1a |
@@ -140,5 +141,9 @@ class EngineComboBox(gtk.ComboBox):
|
|
 |
b95ef1a |
def get_active_engine(self):
|
|
 |
b95ef1a |
return self.get_property("active-engine")
|
|
 |
b95ef1a |
|
|
 |
b95ef1a |
+ def get_title(self):
|
|
 |
b95ef1a |
+ return self.__title
|
|
 |
b95ef1a |
|
|
 |
b95ef1a |
+ def set_title(self, title):
|
|
 |
b95ef1a |
+ self.__title = title
|
|
 |
b95ef1a |
|
|
 |
60148ca |
diff --git a/setup/main.py b/setup/main.py
|
|
 |
9d6bb4f |
index a22bb0c..7f4a040 100644
|
|
 |
60148ca |
--- a/setup/main.py
|
|
 |
60148ca |
+++ b/setup/main.py
|
|
 |
f0777a3 |
@@ -37,6 +37,7 @@ from gtk import gdk
|
|
 |
7232d5e |
from enginecombobox import EngineComboBox
|
|
 |
7232d5e |
from enginetreeview import EngineTreeView
|
|
 |
7232d5e |
from engineabout import EngineAbout
|
|
 |
b95ef1a |
+from xkbsetup import XKBSetup
|
|
 |
3b5789d |
from i18n import DOMAINNAME, _, N_, init as i18n_init
|
|
 |
7232d5e |
|
|
 |
f0777a3 |
(
|
|
 |
9d6bb4f |
@@ -241,6 +242,8 @@ class Setup(object):
|
|
 |
60148ca |
self.__combobox.connect("notify::active-engine", self.__combobox_notify_active_engine_cb)
|
|
 |
60148ca |
self.__treeview.connect("notify", self.__treeview_notify_cb)
|
|
 |
60148ca |
|
|
 |
b95ef1a |
+ XKBSetup(self.__config, self.__builder)
|
|
 |
60148ca |
+
|
|
 |
60148ca |
def __combobox_notify_active_engine_cb(self, combobox, property):
|
|
 |
60148ca |
engine = self.__combobox.get_active_engine()
|
|
 |
60148ca |
button = self.__builder.get_object("button_engine_add")
|
|
 |
60148ca |
diff --git a/setup/setup.ui b/setup/setup.ui
|
|
 |
e5da135 |
index 0a69df8..f1e6d0b 100644
|
|
 |
60148ca |
--- a/setup/setup.ui
|
|
 |
60148ca |
+++ b/setup/setup.ui
|
|
 |
9d6bb4f |
@@ -117,7 +117,6 @@
|
|
 |
60148ca |
<child>
|
|
 |
60148ca |
<object class="GtkLabel" id="label9">
|
|
 |
60148ca |
<property name="visible">True</property>
|
|
 |
60148ca |
- <property name="sensitive">False</property>
|
|
 |
60148ca |
<property name="tooltip_text" translatable="yes">The shortcut keys for switching to previous input method in the list</property>
|
|
 |
60148ca |
<property name="xalign">0</property>
|
|
 |
60148ca |
<property name="label" translatable="yes">Previous input method:</property>
|
|
 |
9d6bb4f |
@@ -204,7 +203,6 @@
|
|
 |
60148ca |
<child>
|
|
 |
60148ca |
<object class="GtkEntry" id="entry_prev_engine">
|
|
 |
60148ca |
<property name="visible">True</property>
|
|
 |
60148ca |
- <property name="sensitive">False</property>
|
|
 |
60148ca |
<property name="can_focus">True</property>
|
|
 |
60148ca |
<property name="editable">False</property>
|
|
 |
60148ca |
</object>
|
|
 |
9d6bb4f |
@@ -216,7 +214,6 @@
|
|
 |
60148ca |
<object class="GtkButton" id="button_prev_engine">
|
|
 |
60148ca |
<property name="label" translatable="yes">...</property>
|
|
 |
60148ca |
<property name="visible">True</property>
|
|
 |
60148ca |
- <property name="sensitive">False</property>
|
|
 |
60148ca |
<property name="can_focus">True</property>
|
|
 |
60148ca |
<property name="receives_default">False</property>
|
|
 |
60148ca |
<property name="use_underline">True</property>
|
|
 |
9d6bb4f |
@@ -825,6 +822,7 @@ You may use up/down buttons to change it.</i></small></property>
|
|
 |
60148ca |
<property name="visible">True</property>
|
|
 |
60148ca |
<property name="orientation">vertical</property>
|
|
 |
60148ca |
<property name="spacing">6</property>
|
|
 |
60148ca |
+ <property name="no_show_all">True</property>
|
|
 |
60148ca |
<child>
|
|
 |
60148ca |
<object class="GtkCheckButton" id="checkbutton_use_sys_layout">
|
|
 |
60148ca |
<property name="label" translatable="yes">Use system keyboard layout</property>
|
|
 |
9d6bb4f |
@@ -840,6 +838,57 @@ You may use up/down buttons to change it.</i></small></property>
|
|
 |
60148ca |
<property name="position">0</property>
|
|
 |
60148ca |
</packing>
|
|
 |
60148ca |
</child>
|
|
 |
60148ca |
+ <child>
|
|
 |
7232d5e |
+ <object class="GtkHBox" id="hbox_system_keyboard_layout">
|
|
 |
60148ca |
+ <property name="visible">True</property>
|
|
 |
60148ca |
+ <property name="spacing">6</property>
|
|
 |
60148ca |
+ <child>
|
|
 |
9d6bb4f |
+ <object class="GtkLabel" id="label20">
|
|
 |
60148ca |
+ <property name="visible">True</property>
|
|
 |
7232d5e |
+ <property name="label" translatable="yes">System Keyboard Layout:</property>
|
|
 |
60148ca |
+ <property name="use_markup">True</property>
|
|
 |
60148ca |
+ <property name="justify">center</property>
|
|
 |
60148ca |
+ </object>
|
|
 |
60148ca |
+ <packing>
|
|
 |
60148ca |
+ <property name="expand">False</property>
|
|
 |
60148ca |
+ <property name="fill">False</property>
|
|
 |
60148ca |
+ <property name="position">0</property>
|
|
 |
60148ca |
+ </packing>
|
|
 |
60148ca |
+ </child>
|
|
 |
60148ca |
+ <child>
|
|
 |
7232d5e |
+ <object class="GtkButton" id="button_system_keyboard_layout">
|
|
 |
60148ca |
+ <property name="label"></property>
|
|
 |
60148ca |
+ <property name="visible">True</property>
|
|
 |
60148ca |
+ <property name="can_focus">True</property>
|
|
 |
60148ca |
+ <property name="receives_default">False</property>
|
|
 |
60148ca |
+ </object>
|
|
 |
60148ca |
+ <packing>
|
|
 |
60148ca |
+ <property name="expand">False</property>
|
|
 |
60148ca |
+ <property name="fill">False</property>
|
|
 |
60148ca |
+ <property name="position">1</property>
|
|
 |
60148ca |
+ </packing>
|
|
 |
60148ca |
+ </child>
|
|
 |
60148ca |
+ </object>
|
|
 |
60148ca |
+ <packing>
|
|
 |
60148ca |
+ <property name="expand">False</property>
|
|
 |
60148ca |
+ <property name="fill">False</property>
|
|
 |
60148ca |
+ <property name="position">1</property>
|
|
 |
60148ca |
+ </packing>
|
|
 |
60148ca |
+ </child>
|
|
 |
6cc8efa |
+ <child>
|
|
 |
6cc8efa |
+ <object class="GtkButton" id="button_config_layouts">
|
|
 |
6cc8efa |
+ <property name="label">Add or remove layouts in 'Select an input method' list</property>
|
|
 |
6cc8efa |
+ <property name="visible">True</property>
|
|
 |
6cc8efa |
+ <property name="can_focus">True</property>
|
|
 |
6cc8efa |
+ <property name="receives_default">False</property>
|
|
 |
6cc8efa |
+ <property name="tooltip_text" translatable="yes">Add or remove keyboard layouts in all input method engnines</property>
|
|
 |
6cc8efa |
+ </object>
|
|
 |
6cc8efa |
+ <packing>
|
|
 |
6cc8efa |
+ <property name="expand">False</property>
|
|
 |
6cc8efa |
+ <property name="fill">False</property>
|
|
 |
6cc8efa |
+ <property name="position">2</property>
|
|
 |
6cc8efa |
+ </packing>
|
|
 |
6cc8efa |
+ </child>
|
|
 |
60148ca |
</object>
|
|
 |
60148ca |
</child>
|
|
 |
60148ca |
</object>
|
|
 |
9d6bb4f |
@@ -1038,4 +1087,558 @@ Homepage: http://code.google.com/p/ibus
|
|
 |
60148ca |
</object>
|
|
 |
60148ca |
</child>
|
|
 |
60148ca |
</object>
|
|
 |
60148ca |
+ <object class="GtkDialog" id="dialog_config_layouts">
|
|
 |
b95ef1a |
+ <property name="title" translatable="yes">Add or Remove Layouts</property>
|
|
 |
60148ca |
+ <property name="icon_name">ibus-setup</property>
|
|
 |
60148ca |
+ <child internal-child="vbox">
|
|
 |
60148ca |
+ <object class="GtkVBox" id="vbox101">
|
|
 |
60148ca |
+ <property name="orientation">vertical</property>
|
|
 |
60148ca |
+ <property name="visible">True</property>
|
|
 |
60148ca |
+ <property name="border-width">10</property>
|
|
 |
60148ca |
+ <property name="spacing">12</property>
|
|
 |
60148ca |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkAlignment" id="alignment101">
|
|
 |
60148ca |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="top_padding">12</property>
|
|
 |
b95ef1a |
+ <property name="left_padding">12</property>
|
|
 |
60148ca |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkFrame" id="frame101">
|
|
 |
60148ca |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="label_xalign">0</property>
|
|
 |
b95ef1a |
+ <property name="shadow_type">none</property>
|
|
 |
60148ca |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkAlignment" id="alignment102">
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="top_padding">12</property>
|
|
 |
b95ef1a |
+ <property name="left_padding">12</property>
|
|
 |
b95ef1a |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkVBox" id="vbox102">
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="orientation">vertical</property>
|
|
 |
b95ef1a |
+ <property name="spacing">6</property>
|
|
 |
b95ef1a |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkScrolledWindow" id="scrolledwindow101">
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="can_focus">True</property>
|
|
 |
b95ef1a |
+ <property name="border_width">5</property>
|
|
 |
b95ef1a |
+ <property name="width_request">450</property>
|
|
 |
b95ef1a |
+ <property name="height_request">350</property>
|
|
 |
b95ef1a |
+ <property name="hscrollbar_policy">automatic</property>
|
|
 |
b95ef1a |
+ <property name="vscrollbar_policy">automatic</property>
|
|
 |
b95ef1a |
+ <property name="shadow_type">out</property>
|
|
 |
b95ef1a |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkViewport" id="viewport101">
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="shadow_type">none</property>
|
|
 |
b95ef1a |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkVBox" id="vbox_all_keyboard_layouts">
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="orientation">vertical</property>
|
|
 |
b95ef1a |
+ </object>
|
|
 |
b95ef1a |
+ </child>
|
|
 |
b95ef1a |
+ </object>
|
|
 |
b95ef1a |
+ </child>
|
|
 |
b95ef1a |
+ </object>
|
|
 |
b95ef1a |
+ <packing>
|
|
 |
b95ef1a |
+ <property name="position">0</property>
|
|
 |
b95ef1a |
+ </packing>
|
|
 |
b95ef1a |
+ </child>
|
|
 |
b95ef1a |
+ </object>
|
|
 |
b95ef1a |
+ </child>
|
|
 |
60148ca |
+ </object>
|
|
 |
60148ca |
+ </child>
|
|
 |
b95ef1a |
+ <child type="label">
|
|
 |
b95ef1a |
+ <object class="GtkLabel" id="label101">
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="label" translatable="yes"><b>Keyboard Layout</b></property>
|
|
 |
b95ef1a |
+ <property name="use_markup">True</property>
|
|
 |
60148ca |
+ </object>
|
|
 |
60148ca |
+ </child>
|
|
 |
60148ca |
+ </object>
|
|
 |
60148ca |
+ </child>
|
|
 |
60148ca |
+ </object>
|
|
 |
60148ca |
+ <packing>
|
|
 |
60148ca |
+ <property name="expand">False</property>
|
|
 |
60148ca |
+ <property name="position">0</property>
|
|
 |
60148ca |
+ </packing>
|
|
 |
60148ca |
+ </child>
|
|
 |
60148ca |
+ <child internal-child="action_area">
|
|
 |
60148ca |
+ <object class="GtkHButtonBox" id="hbuttonbox101">
|
|
 |
60148ca |
+ <property name="visible">True</property>
|
|
 |
60148ca |
+ <property name="homogeneous">True</property>
|
|
 |
60148ca |
+ <property name="layout_style">end</property>
|
|
 |
60148ca |
+ <child>
|
|
 |
60148ca |
+ <object class="GtkButton" id="button_config_layouts_cancel">
|
|
 |
60148ca |
+ <property name="label">gtk-cancel</property>
|
|
 |
60148ca |
+ <property name="visible">True</property>
|
|
 |
60148ca |
+ <property name="use_stock">True</property>
|
|
 |
60148ca |
+ </object>
|
|
 |
60148ca |
+ <packing>
|
|
 |
60148ca |
+ <property name="expand">False</property>
|
|
 |
60148ca |
+ <property name="fill">False</property>
|
|
 |
60148ca |
+ <property name="position">0</property>
|
|
 |
60148ca |
+ </packing>
|
|
 |
60148ca |
+ </child>
|
|
 |
60148ca |
+ <child>
|
|
 |
60148ca |
+ <object class="GtkButton" id="button_config_layouts_ok">
|
|
 |
60148ca |
+ <property name="label">gtk-ok</property>
|
|
 |
60148ca |
+ <property name="visible">True</property>
|
|
 |
60148ca |
+ <property name="use_stock">True</property>
|
|
 |
60148ca |
+ <property name="receives_default">True</property>
|
|
 |
60148ca |
+ </object>
|
|
 |
60148ca |
+ <packing>
|
|
 |
60148ca |
+ <property name="expand">False</property>
|
|
 |
60148ca |
+ <property name="fill">False</property>
|
|
 |
60148ca |
+ <property name="position">1</property>
|
|
 |
60148ca |
+ </packing>
|
|
 |
60148ca |
+ </child>
|
|
 |
60148ca |
+ </object>
|
|
 |
60148ca |
+ <packing>
|
|
 |
60148ca |
+ <property name="expand">False</property>
|
|
 |
60148ca |
+ <property name="fill">False</property>
|
|
 |
60148ca |
+ <property name="pack_type">end</property>
|
|
 |
60148ca |
+ <property name="position">1</property>
|
|
 |
60148ca |
+ </packing>
|
|
 |
60148ca |
+ </child>
|
|
 |
60148ca |
+ </object>
|
|
 |
60148ca |
+ </child>
|
|
 |
60148ca |
+ </object>
|
|
 |
7232d5e |
+ <object class="GtkDialog" id="dialog_system_keyboard_layout">
|
|
 |
7232d5e |
+ <property name="title" translatable="yes">System Keyboard Layout Setup</property>
|
|
 |
60148ca |
+ <property name="icon_name">ibus-setup</property>
|
|
 |
60148ca |
+ <child internal-child="vbox">
|
|
 |
60148ca |
+ <object class="GtkVBox" id="vbox201">
|
|
 |
60148ca |
+ <property name="orientation">vertical</property>
|
|
 |
60148ca |
+ <property name="visible">True</property>
|
|
 |
60148ca |
+ <property name="border-width">10</property>
|
|
 |
60148ca |
+ <property name="spacing">12</property>
|
|
 |
60148ca |
+ <child>
|
|
 |
7232d5e |
+ <object class="GtkAlignment" id="alignment201">
|
|
 |
60148ca |
+ <property name="visible">True</property>
|
|
 |
7232d5e |
+ <property name="top_padding">12</property>
|
|
 |
7232d5e |
+ <property name="left_padding">12</property>
|
|
 |
60148ca |
+ <child>
|
|
 |
7232d5e |
+ <object class="GtkFrame" id="frame201">
|
|
 |
60148ca |
+ <property name="visible">True</property>
|
|
 |
7232d5e |
+ <property name="label_xalign">0</property>
|
|
 |
7232d5e |
+ <property name="shadow_type">none</property>
|
|
 |
60148ca |
+ <child>
|
|
 |
7232d5e |
+ <object class="GtkAlignment" id="alignment202">
|
|
 |
60148ca |
+ <property name="visible">True</property>
|
|
 |
7232d5e |
+ <property name="top_padding">12</property>
|
|
 |
7232d5e |
+ <property name="left_padding">12</property>
|
|
 |
7232d5e |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkVBox" id="vbox202">
|
|
 |
7232d5e |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="orientation">vertical</property>
|
|
 |
b95ef1a |
+ <property name="spacing">6</property>
|
|
 |
7232d5e |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkHBox" id="hbox201">
|
|
 |
7232d5e |
+ <property name="visible">True</property>
|
|
 |
7232d5e |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkVBox" id="vbox203">
|
|
 |
7232d5e |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="orientation">vertical</property>
|
|
 |
b95ef1a |
+ <property name="spacing">6</property>
|
|
 |
b95ef1a |
+ <child>
|
|
 |
b95ef1a |
+ <object class="EngineComboBox" id="combobox_system_keyboard_layout_engines">
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ </object>
|
|
 |
b95ef1a |
+ <packing>
|
|
 |
b95ef1a |
+ <property name="expand">False</property>
|
|
 |
b95ef1a |
+ <property name="position">0</property>
|
|
 |
b95ef1a |
+ </packing>
|
|
 |
b95ef1a |
+ </child>
|
|
 |
b95ef1a |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkScrolledWindow" id="scrolledwindow201">
|
|
 |
b95ef1a |
+ <property name="height_request">150</property>
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="can_focus">True</property>
|
|
 |
b95ef1a |
+ <property name="hscrollbar_policy">automatic</property>
|
|
 |
b95ef1a |
+ <property name="vscrollbar_policy">automatic</property>
|
|
 |
b95ef1a |
+ <property name="shadow_type">in</property>
|
|
 |
b95ef1a |
+ <child>
|
|
 |
b95ef1a |
+ <object class="EngineTreeView" id="treeview_system_keyboard_layout_engines">
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="can_focus">True</property>
|
|
 |
b95ef1a |
+ <property name="height_request">150</property>
|
|
 |
b95ef1a |
+ </object>
|
|
 |
b95ef1a |
+ </child>
|
|
 |
b95ef1a |
+ </object>
|
|
 |
b95ef1a |
+ <packing>
|
|
 |
b95ef1a |
+ <property name="expand">False</property>
|
|
 |
b95ef1a |
+ <property name="position">1</property>
|
|
 |
b95ef1a |
+ </packing>
|
|
 |
b95ef1a |
+ </child>
|
|
 |
7232d5e |
+ </object>
|
|
 |
b95ef1a |
+ <packing>
|
|
 |
b95ef1a |
+ <property name="position">0</property>
|
|
 |
b95ef1a |
+ </packing>
|
|
 |
b95ef1a |
+ </child>
|
|
 |
b95ef1a |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkVButtonBox" id="vbuttonbox201">
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="orientation">vertical</property>
|
|
 |
b95ef1a |
+ <property name="spacing">5</property>
|
|
 |
b95ef1a |
+ <property name="layout_style">start</property>
|
|
 |
b95ef1a |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkButton" id="button_system_keyboard_layout_engine_add">
|
|
 |
b95ef1a |
+ <property name="label">gtk-add</property>
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="sensitive">False</property>
|
|
 |
b95ef1a |
+ <property name="can_focus">True</property>
|
|
 |
b95ef1a |
+ <property name="receives_default">True</property>
|
|
 |
b95ef1a |
+ <property name="tooltip_text" translatable="yes">Add the selected keyboard layout into the system keyboard layouts</property>
|
|
 |
b95ef1a |
+ <property name="use_stock">True</property>
|
|
 |
b95ef1a |
+ </object>
|
|
 |
b95ef1a |
+ <packing>
|
|
 |
b95ef1a |
+ <property name="expand">False</property>
|
|
 |
b95ef1a |
+ <property name="fill">False</property>
|
|
 |
b95ef1a |
+ <property name="position">0</property>
|
|
 |
b95ef1a |
+ </packing>
|
|
 |
b95ef1a |
+ </child>
|
|
 |
b95ef1a |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkButton" id="button_system_keyboard_layout_engine_remove">
|
|
 |
b95ef1a |
+ <property name="label">gtk-remove</property>
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="sensitive">False</property>
|
|
 |
b95ef1a |
+ <property name="can_focus">True</property>
|
|
 |
b95ef1a |
+ <property name="receives_default">True</property>
|
|
 |
b95ef1a |
+ <property name="tooltip_text" translatable="yes">Remove the selected keyboard layout from the system keyboard layouts</property>
|
|
 |
b95ef1a |
+ <property name="use_stock">True</property>
|
|
 |
b95ef1a |
+ </object>
|
|
 |
b95ef1a |
+ <packing>
|
|
 |
b95ef1a |
+ <property name="expand">False</property>
|
|
 |
b95ef1a |
+ <property name="fill">False</property>
|
|
 |
b95ef1a |
+ <property name="position">1</property>
|
|
 |
b95ef1a |
+ </packing>
|
|
 |
b95ef1a |
+ </child>
|
|
 |
b95ef1a |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkButton" id="button_system_keyboard_layout_engine_up">
|
|
 |
b95ef1a |
+ <property name="label">gtk-go-up</property>
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="sensitive">False</property>
|
|
 |
b95ef1a |
+ <property name="can_focus">True</property>
|
|
 |
b95ef1a |
+ <property name="receives_default">True</property>
|
|
 |
b95ef1a |
+ <property name="tooltip_text" translatable="yes">Move up the selected keyboard layout in the system keyboard layouts list</property>
|
|
 |
b95ef1a |
+ <property name="use_stock">True</property>
|
|
 |
b95ef1a |
+ </object>
|
|
 |
b95ef1a |
+ <packing>
|
|
 |
b95ef1a |
+ <property name="expand">False</property>
|
|
 |
b95ef1a |
+ <property name="fill">False</property>
|
|
 |
b95ef1a |
+ <property name="position">2</property>
|
|
 |
b95ef1a |
+ </packing>
|
|
 |
b95ef1a |
+ </child>
|
|
 |
b95ef1a |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkButton" id="button_system_keyboard_layout_engine_down">
|
|
 |
b95ef1a |
+ <property name="label">gtk-go-down</property>
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="sensitive">False</property>
|
|
 |
b95ef1a |
+ <property name="can_focus">True</property>
|
|
 |
b95ef1a |
+ <property name="receives_default">True</property>
|
|
 |
b95ef1a |
+ <property name="tooltip_text" translatable="yes">Move down the selected keyboard layout in the system keyboard layouts list</property>
|
|
 |
b95ef1a |
+ <property name="use_stock">True</property>
|
|
 |
b95ef1a |
+ </object>
|
|
 |
b95ef1a |
+ <packing>
|
|
 |
b95ef1a |
+ <property name="expand">False</property>
|
|
 |
b95ef1a |
+ <property name="fill">False</property>
|
|
 |
b95ef1a |
+ <property name="position">3</property>
|
|
 |
b95ef1a |
+ </packing>
|
|
 |
b95ef1a |
+ </child>
|
|
 |
b95ef1a |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkButton" id="button_system_keyboard_layout_engine_reset">
|
|
 |
b95ef1a |
+ <property name="label" translatable="yes">Rese_t</property>
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="sensitive">False</property>
|
|
 |
b95ef1a |
+ <property name="can_focus">True</property>
|
|
 |
b95ef1a |
+ <property name="receives_default">True</property>
|
|
 |
b95ef1a |
+ <property name="tooltip_text" translatable="yes">Reset the system keyboard layouts list</property>
|
|
 |
b95ef1a |
+ <property name="use_underline">True</property>
|
|
 |
b95ef1a |
+ </object>
|
|
 |
b95ef1a |
+ <packing>
|
|
 |
b95ef1a |
+ <property name="expand">False</property>
|
|
 |
b95ef1a |
+ <property name="fill">False</property>
|
|
 |
b95ef1a |
+ <property name="position">4</property>
|
|
 |
b95ef1a |
+ </packing>
|
|
 |
b95ef1a |
+ </child>
|
|
 |
b95ef1a |
+ </object>
|
|
 |
b95ef1a |
+ <packing>
|
|
 |
b95ef1a |
+ <property name="position">1</property>
|
|
 |
b95ef1a |
+ </packing>
|
|
 |
7232d5e |
+ </child>
|
|
 |
7232d5e |
+ </object>
|
|
 |
7232d5e |
+ <packing>
|
|
 |
b95ef1a |
+ <property name="position">0</property>
|
|
 |
7232d5e |
+ </packing>
|
|
 |
7232d5e |
+ </child>
|
|
 |
7232d5e |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkHBox" id="hbox202">
|
|
 |
7232d5e |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="spacing">6</property>
|
|
 |
b95ef1a |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkImage" id="image201">
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="stock">gtk-info</property>
|
|
 |
b95ef1a |
+ <property name="icon-size">2</property>
|
|
 |
b95ef1a |
+ </object>
|
|
 |
b95ef1a |
+ <packing>
|
|
 |
b95ef1a |
+ <property name="expand">False</property>
|
|
 |
b95ef1a |
+ <property name="position">0</property>
|
|
 |
b95ef1a |
+ </packing>
|
|
 |
b95ef1a |
+ </child>
|
|
 |
b95ef1a |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkLabel" id="label_system_keyboard_layout_engines">
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="xalign">0</property>
|
|
 |
b95ef1a |
+ <property name="use_markup">True</property>
|
|
 |
b95ef1a |
+ </object>
|
|
 |
b95ef1a |
+ <packing>
|
|
 |
b95ef1a |
+ <property name="position">1</property>
|
|
 |
b95ef1a |
+ </packing>
|
|
 |
b95ef1a |
+ </child>
|
|
 |
7232d5e |
+ </object>
|
|
 |
7232d5e |
+ <packing>
|
|
 |
b95ef1a |
+ <property name="position">1</property>
|
|
 |
7232d5e |
+ </packing>
|
|
 |
7232d5e |
+ </child>
|
|
 |
7232d5e |
+ </object>
|
|
 |
7232d5e |
+ </child>
|
|
 |
7232d5e |
+ </object>
|
|
 |
7232d5e |
+ </child>
|
|
 |
7232d5e |
+ <child type="label">
|
|
 |
7232d5e |
+ <object class="GtkLabel" id="label201">
|
|
 |
7232d5e |
+ <property name="visible">True</property>
|
|
 |
7232d5e |
+ <property name="label" translatable="yes"><b>Keyboard Layout</b></property>
|
|
 |
7232d5e |
+ <property name="use_markup">True</property>
|
|
 |
60148ca |
+ </object>
|
|
 |
60148ca |
+ </child>
|
|
 |
60148ca |
+ </object>
|
|
 |
60148ca |
+ </child>
|
|
 |
7232d5e |
+ </object>
|
|
 |
7232d5e |
+ <packing>
|
|
 |
7232d5e |
+ <property name="expand">False</property>
|
|
 |
7232d5e |
+ <property name="position">0</property>
|
|
 |
7232d5e |
+ </packing>
|
|
 |
7232d5e |
+ </child>
|
|
 |
7232d5e |
+ <child>
|
|
 |
7232d5e |
+ <object class="GtkAlignment" id="alignment204">
|
|
 |
7232d5e |
+ <property name="visible">True</property>
|
|
 |
7232d5e |
+ <property name="top_padding">12</property>
|
|
 |
7232d5e |
+ <property name="left_padding">12</property>
|
|
 |
60148ca |
+ <child>
|
|
 |
7232d5e |
+ <object class="GtkFrame" id="frame202">
|
|
 |
60148ca |
+ <property name="visible">True</property>
|
|
 |
7232d5e |
+ <property name="label_xalign">0</property>
|
|
 |
7232d5e |
+ <property name="shadow_type">none</property>
|
|
 |
7232d5e |
+ <child>
|
|
 |
7232d5e |
+ <object class="GtkAlignment" id="alignment205">
|
|
 |
7232d5e |
+ <property name="visible">True</property>
|
|
 |
7232d5e |
+ <property name="top_padding">12</property>
|
|
 |
7232d5e |
+ <property name="left_padding">12</property>
|
|
 |
7232d5e |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkVBox" id="vbox204">
|
|
 |
7232d5e |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="orientation">vertical</property>
|
|
 |
b95ef1a |
+ <property name="spacing">6</property>
|
|
 |
7232d5e |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkHButtonBox" id="hbuttonbox201">
|
|
 |
7232d5e |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="homogeneous">True</property>
|
|
 |
b95ef1a |
+ <property name="layout_style">start</property>
|
|
 |
7232d5e |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkButton" id="button_system_keyboard_option_setup">
|
|
 |
7232d5e |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="label" translatable="yes">_Options...</property>
|
|
 |
b95ef1a |
+ <property name="can_focus">True</property>
|
|
 |
b95ef1a |
+ <property name="use_underline">True</property>
|
|
 |
7232d5e |
+ </object>
|
|
 |
b95ef1a |
+ <packing>
|
|
 |
b95ef1a |
+ <property name="expand">False</property>
|
|
 |
b95ef1a |
+ <property name="fill">False</property>
|
|
 |
b95ef1a |
+ <property name="position">0</property>
|
|
 |
b95ef1a |
+ </packing>
|
|
 |
7232d5e |
+ </child>
|
|
 |
7232d5e |
+ </object>
|
|
 |
7232d5e |
+ <packing>
|
|
 |
b95ef1a |
+ <property name="expand">False</property>
|
|
 |
b95ef1a |
+ <property name="fill">False</property>
|
|
 |
b95ef1a |
+ <property name="position">0</property>
|
|
 |
7232d5e |
+ </packing>
|
|
 |
7232d5e |
+ </child>
|
|
 |
7232d5e |
+ </object>
|
|
 |
7232d5e |
+ </child>
|
|
 |
7232d5e |
+ </object>
|
|
 |
7232d5e |
+ </child>
|
|
 |
7232d5e |
+ <child type="label">
|
|
 |
7232d5e |
+ <object class="GtkLabel" id="label202">
|
|
 |
7232d5e |
+ <property name="visible">True</property>
|
|
 |
7232d5e |
+ <property name="label" translatable="yes"><b>Keyboard Option</b></property>
|
|
 |
7232d5e |
+ <property name="use_markup">True</property>
|
|
 |
7232d5e |
+ </object>
|
|
 |
7232d5e |
+ </child>
|
|
 |
60148ca |
+ </object>
|
|
 |
60148ca |
+ </child>
|
|
 |
60148ca |
+ </object>
|
|
 |
60148ca |
+ <packing>
|
|
 |
60148ca |
+ <property name="expand">False</property>
|
|
 |
7232d5e |
+ <property name="position">1</property>
|
|
 |
60148ca |
+ </packing>
|
|
 |
60148ca |
+ </child>
|
|
 |
60148ca |
+ <child internal-child="action_area">
|
|
 |
b95ef1a |
+ <object class="GtkHButtonBox" id="hbuttonbox202">
|
|
 |
60148ca |
+ <property name="visible">True</property>
|
|
 |
60148ca |
+ <property name="homogeneous">True</property>
|
|
 |
60148ca |
+ <property name="layout_style">end</property>
|
|
 |
60148ca |
+ <child>
|
|
 |
7232d5e |
+ <object class="GtkButton" id="button_system_keyboard_layout_cancel">
|
|
 |
60148ca |
+ <property name="label">gtk-cancel</property>
|
|
 |
60148ca |
+ <property name="visible">True</property>
|
|
 |
60148ca |
+ <property name="use_stock">True</property>
|
|
 |
60148ca |
+ </object>
|
|
 |
60148ca |
+ <packing>
|
|
 |
60148ca |
+ <property name="expand">False</property>
|
|
 |
60148ca |
+ <property name="fill">False</property>
|
|
 |
60148ca |
+ <property name="position">0</property>
|
|
 |
60148ca |
+ </packing>
|
|
 |
60148ca |
+ </child>
|
|
 |
60148ca |
+ <child>
|
|
 |
7232d5e |
+ <object class="GtkButton" id="button_system_keyboard_layout_ok">
|
|
 |
60148ca |
+ <property name="label">gtk-ok</property>
|
|
 |
60148ca |
+ <property name="visible">True</property>
|
|
 |
60148ca |
+ <property name="use_stock">True</property>
|
|
 |
60148ca |
+ <property name="receives_default">True</property>
|
|
 |
60148ca |
+ </object>
|
|
 |
60148ca |
+ <packing>
|
|
 |
60148ca |
+ <property name="expand">False</property>
|
|
 |
60148ca |
+ <property name="fill">False</property>
|
|
 |
60148ca |
+ <property name="position">1</property>
|
|
 |
60148ca |
+ </packing>
|
|
 |
60148ca |
+ </child>
|
|
 |
60148ca |
+ </object>
|
|
 |
60148ca |
+ <packing>
|
|
 |
60148ca |
+ <property name="expand">False</property>
|
|
 |
60148ca |
+ <property name="fill">False</property>
|
|
 |
60148ca |
+ <property name="pack_type">end</property>
|
|
 |
60148ca |
+ <property name="position">1</property>
|
|
 |
60148ca |
+ </packing>
|
|
 |
60148ca |
+ </child>
|
|
 |
60148ca |
+ </object>
|
|
 |
60148ca |
+ </child>
|
|
 |
60148ca |
+ </object>
|
|
 |
b95ef1a |
+ <object class="GtkDialog" id="dialog_system_keyboard_option">
|
|
 |
b95ef1a |
+ <property name="title" translatable="yes">System Keyboard Option Setup</property>
|
|
 |
b95ef1a |
+ <property name="icon_name">ibus-setup</property>
|
|
 |
b95ef1a |
+ <child internal-child="vbox">
|
|
 |
b95ef1a |
+ <object class="GtkVBox" id="vbox301">
|
|
 |
b95ef1a |
+ <property name="orientation">vertical</property>
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="border-width">10</property>
|
|
 |
b95ef1a |
+ <property name="spacing">12</property>
|
|
 |
b95ef1a |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkAlignment" id="alignment301">
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="top_padding">12</property>
|
|
 |
b95ef1a |
+ <property name="left_padding">12</property>
|
|
 |
b95ef1a |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkFrame" id="frame301">
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="label_xalign">0</property>
|
|
 |
b95ef1a |
+ <property name="shadow_type">none</property>
|
|
 |
b95ef1a |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkAlignment" id="alignment302">
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="top_padding">12</property>
|
|
 |
b95ef1a |
+ <property name="left_padding">12</property>
|
|
 |
b95ef1a |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkVBox" id="vbox302">
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="orientation">vertical</property>
|
|
 |
b95ef1a |
+ <property name="spacing">6</property>
|
|
 |
b95ef1a |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkCheckButton" id="checkbutton_use_system_keyboard_option">
|
|
 |
b95ef1a |
+ <property name="label" translatable="yes">Use the default keyboard option</property>
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="can_focus">True</property>
|
|
 |
b95ef1a |
+ <property name="receives_default">False</property>
|
|
 |
b95ef1a |
+ <property name="tooltip_text" translatable="yes">Use the defualt XKB option</property>
|
|
 |
b95ef1a |
+ <property name="draw_indicator">True</property>
|
|
 |
b95ef1a |
+ </object>
|
|
 |
b95ef1a |
+ <packing>
|
|
 |
b95ef1a |
+ <property name="position">0</property>
|
|
 |
b95ef1a |
+ </packing>
|
|
 |
b95ef1a |
+ </child>
|
|
 |
b95ef1a |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkScrolledWindow" id="scrolledwindow301">
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="can_focus">True</property>
|
|
 |
b95ef1a |
+ <property name="border_width">5</property>
|
|
 |
b95ef1a |
+ <property name="width_request">450</property>
|
|
 |
b95ef1a |
+ <property name="height_request">350</property>
|
|
 |
b95ef1a |
+ <property name="hscrollbar_policy">automatic</property>
|
|
 |
b95ef1a |
+ <property name="vscrollbar_policy">automatic</property>
|
|
 |
b95ef1a |
+ <property name="shadow_type">out</property>
|
|
 |
b95ef1a |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkViewport" id="viewport301">
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="shadow_type">none</property>
|
|
 |
b95ef1a |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkVBox" id="vbox_system_keyboard_options">
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="orientation">vertical</property>
|
|
 |
b95ef1a |
+ </object>
|
|
 |
b95ef1a |
+ </child>
|
|
 |
b95ef1a |
+ </object>
|
|
 |
b95ef1a |
+ </child>
|
|
 |
b95ef1a |
+ </object>
|
|
 |
b95ef1a |
+ <packing>
|
|
 |
b95ef1a |
+ <property name="position">1</property>
|
|
 |
b95ef1a |
+ </packing>
|
|
 |
b95ef1a |
+ </child>
|
|
 |
b95ef1a |
+ </object>
|
|
 |
b95ef1a |
+ </child>
|
|
 |
b95ef1a |
+ </object>
|
|
 |
b95ef1a |
+ </child>
|
|
 |
b95ef1a |
+ <child type="label">
|
|
 |
b95ef1a |
+ <object class="GtkLabel" id="label301">
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="label" translatable="yes"><b>Keyboard Option</b></property>
|
|
 |
b95ef1a |
+ <property name="use_markup">True</property>
|
|
 |
b95ef1a |
+ </object>
|
|
 |
b95ef1a |
+ </child>
|
|
 |
b95ef1a |
+ </object>
|
|
 |
b95ef1a |
+ </child>
|
|
 |
b95ef1a |
+ </object>
|
|
 |
b95ef1a |
+ <packing>
|
|
 |
b95ef1a |
+ <property name="expand">False</property>
|
|
 |
b95ef1a |
+ <property name="position">0</property>
|
|
 |
b95ef1a |
+ </packing>
|
|
 |
b95ef1a |
+ </child>
|
|
 |
b95ef1a |
+ <child internal-child="action_area">
|
|
 |
b95ef1a |
+ <object class="GtkHButtonBox" id="hbuttonbox301">
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="homogeneous">True</property>
|
|
 |
b95ef1a |
+ <property name="layout_style">end</property>
|
|
 |
b95ef1a |
+ <child>
|
|
 |
b95ef1a |
+ <object class="GtkButton" id="button_system_keyboard_option_close">
|
|
 |
b95ef1a |
+ <property name="label">gtk-close</property>
|
|
 |
b95ef1a |
+ <property name="visible">True</property>
|
|
 |
b95ef1a |
+ <property name="use_stock">True</property>
|
|
 |
b95ef1a |
+ </object>
|
|
 |
b95ef1a |
+ <packing>
|
|
 |
b95ef1a |
+ <property name="expand">False</property>
|
|
 |
b95ef1a |
+ <property name="fill">False</property>
|
|
 |
b95ef1a |
+ <property name="position">0</property>
|
|
 |
b95ef1a |
+ </packing>
|
|
 |
b95ef1a |
+ </child>
|
|
 |
b95ef1a |
+ </object>
|
|
 |
b95ef1a |
+ <packing>
|
|
 |
b95ef1a |
+ <property name="expand">False</property>
|
|
 |
b95ef1a |
+ <property name="fill">False</property>
|
|
 |
b95ef1a |
+ <property name="pack_type">end</property>
|
|
 |
b95ef1a |
+ <property name="position">1</property>
|
|
 |
b95ef1a |
+ </packing>
|
|
 |
b95ef1a |
+ </child>
|
|
 |
b95ef1a |
+ </object>
|
|
 |
b95ef1a |
+ </child>
|
|
 |
b95ef1a |
+ </object>
|
|
 |
60148ca |
</interface>
|
|
 |
b95ef1a |
diff --git a/setup/xkbsetup.py b/setup/xkbsetup.py
|
|
 |
7232d5e |
new file mode 100644
|
|
 |
e0a5e11 |
index 0000000..af9ec53
|
|
 |
7232d5e |
--- /dev/null
|
|
 |
b95ef1a |
+++ b/setup/xkbsetup.py
|
|
 |
e0a5e11 |
@@ -0,0 +1,457 @@
|
|
 |
7232d5e |
+# vim:set et sts=4 sw=4:
|
|
 |
7232d5e |
+#
|
|
 |
7232d5e |
+# ibus - The Input Bus
|
|
 |
7232d5e |
+#
|
|
 |
63b857f |
+# Copyright (c) 2011 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
 |
63b857f |
+# Copyright (c) 2011 Peng Huang <shawn.p.huang@gmail.com>
|
|
 |
63b857f |
+# Copyright (c) 2011 Red Hat, Inc.
|
|
 |
7232d5e |
+#
|
|
 |
7232d5e |
+# This library is free software; you can redistribute it and/or
|
|
 |
7232d5e |
+# modify it under the terms of the GNU Lesser General Public
|
|
 |
7232d5e |
+# License as published by the Free Software Foundation; either
|
|
 |
7232d5e |
+# version 2 of the License, or (at your option) any later version.
|
|
 |
7232d5e |
+#
|
|
 |
7232d5e |
+# This library is distributed in the hope that it will be useful,
|
|
 |
7232d5e |
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
 |
7232d5e |
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
 |
7232d5e |
+# GNU Lesser General Public License for more details.
|
|
 |
7232d5e |
+#
|
|
 |
7232d5e |
+# You should have received a copy of the GNU Lesser General Public
|
|
 |
7232d5e |
+# License along with this program; if not, write to the
|
|
 |
7232d5e |
+# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
|
 |
7232d5e |
+# Boston, MA 02111-1307 USA
|
|
 |
7232d5e |
+
|
|
 |
b95ef1a |
+import gettext
|
|
 |
7232d5e |
+import gobject
|
|
 |
b95ef1a |
+import gtk
|
|
 |
7232d5e |
+import ibus
|
|
 |
7232d5e |
+
|
|
 |
7232d5e |
+_ = lambda a : gettext.dgettext("ibus", a)
|
|
 |
b95ef1a |
+XKB_MAX_LAYOUTS = 4
|
|
 |
7232d5e |
+
|
|
 |
b95ef1a |
+class XKBSetup(gobject.GObject):
|
|
 |
b95ef1a |
+ def __init__(self, config, builder):
|
|
 |
b95ef1a |
+ super(XKBSetup, self).__init__()
|
|
 |
7232d5e |
+
|
|
 |
b95ef1a |
+ self.__config = config
|
|
 |
b95ef1a |
+ self.__builder = builder
|
|
 |
7232d5e |
+
|
|
 |
b95ef1a |
+ # system keyboard layout setting
|
|
 |
b95ef1a |
+ self.__button_system_keyboard_layout = self.__builder.get_object("button_system_keyboard_layout")
|
|
 |
b95ef1a |
+ text = str(self.__config.get_value("general", "system_keyboard_layout", ''))
|
|
 |
b95ef1a |
+ if text == 'default' or text == '':
|
|
 |
b95ef1a |
+ text = _("Default")
|
|
 |
b95ef1a |
+ self.__button_system_keyboard_layout.set_label(text)
|
|
 |
b95ef1a |
+ if not self.__config.get_value("general", "use_system_keyboard_layout", True):
|
|
 |
b95ef1a |
+ self.__button_system_keyboard_layout.set_sensitive(False)
|
|
 |
b95ef1a |
+ self.__button_system_keyboard_layout.connect("clicked", self.__button_system_keyboard_layout_cb)
|
|
 |
b95ef1a |
+
|
|
 |
b95ef1a |
+ # use system keyboard layout setting
|
|
 |
e0a5e11 |
+ self.__config.connect("value-changed", self.__config_value_changed_cb)
|
|
 |
b95ef1a |
+
|
|
 |
b95ef1a |
+ self.__xkblayoutconfig = None
|
|
 |
b95ef1a |
+ self.__preload_xkb_engines = []
|
|
 |
b95ef1a |
+ self.__other_xkb_engines = []
|
|
 |
b95ef1a |
+ self.__default_xkb_engine = None
|
|
 |
b95ef1a |
+ if ibus.XKBConfigRegistry.have_xkb():
|
|
 |
b95ef1a |
+ self.__xkblayoutconfig = ibus.XKBLayoutConfig()
|
|
 |
7232d5e |
+
|
|
 |
b95ef1a |
+ # config layouts dialog
|
|
 |
b95ef1a |
+ self.__init_config_layouts()
|
|
 |
7232d5e |
+
|
|
 |
b95ef1a |
+ # default system keyboard dialog
|
|
 |
b95ef1a |
+ self.__init_system_keyboard()
|
|
 |
b95ef1a |
+
|
|
 |
e0a5e11 |
+ def __config_value_changed_cb(self, bus, section, name, value):
|
|
 |
e0a5e11 |
+ if section == "general" and name == "use_system_keyboard_layout":
|
|
 |
e0a5e11 |
+ self.__button_system_keyboard_layout.set_sensitive(value)
|
|
 |
e0a5e11 |
+
|
|
 |
b95ef1a |
+ def __get_xkb_engines(self):
|
|
 |
b95ef1a |
+ xkb_engines = []
|
|
 |
b95ef1a |
+ xkbconfig = ibus.XKBConfigRegistry()
|
|
 |
b95ef1a |
+ layout_list = xkbconfig.get_layout_list()
|
|
 |
b95ef1a |
+ layout_desc = xkbconfig.get_layout_desc()
|
|
 |
b95ef1a |
+ layout_lang = xkbconfig.get_layout_lang()
|
|
 |
b95ef1a |
+ variant_desc = xkbconfig.get_variant_desc()
|
|
 |
b95ef1a |
+ for layout in layout_list.keys():
|
|
 |
48fb145 |
+ langs = []
|
|
 |
48fb145 |
+ if layout in layout_lang:
|
|
 |
48fb145 |
+ langs = layout_lang[layout]
|
|
 |
b95ef1a |
+ for lang in langs:
|
|
 |
b95ef1a |
+ engine = ibus.XKBConfigRegistry.engine_desc_new(
|
|
 |
b95ef1a |
+ lang,
|
|
 |
b95ef1a |
+ layout,
|
|
 |
b95ef1a |
+ layout_desc[layout],
|
|
 |
b95ef1a |
+ None,
|
|
 |
b95ef1a |
+ None)
|
|
 |
b95ef1a |
+ xkb_engines.append(engine)
|
|
 |
b95ef1a |
+ for variant in layout_list[layout]:
|
|
 |
b95ef1a |
+ label = "%s(%s)" % (layout, variant)
|
|
 |
e5da135 |
+ sub_langs = []
|
|
 |
b95ef1a |
+ if label in layout_lang:
|
|
 |
e5da135 |
+ sub_langs = layout_lang[label]
|
|
 |
e5da135 |
+ else:
|
|
 |
e5da135 |
+ sub_langs = langs
|
|
 |
e5da135 |
+ for lang in sub_langs:
|
|
 |
b95ef1a |
+ engine = ibus.XKBConfigRegistry.engine_desc_new(
|
|
 |
b95ef1a |
+ lang,
|
|
 |
b95ef1a |
+ layout,
|
|
 |
b95ef1a |
+ layout_desc[layout],
|
|
 |
b95ef1a |
+ variant,
|
|
 |
e5da135 |
+ variant_desc[label])
|
|
 |
b95ef1a |
+ xkb_engines.append(engine)
|
|
 |
b95ef1a |
+ return xkb_engines
|
|
 |
b95ef1a |
+
|
|
 |
b95ef1a |
+ def __get_default_xkb_engine(self):
|
|
 |
b95ef1a |
+ if self.__default_xkb_engine != None:
|
|
 |
b95ef1a |
+ return self.__default_xkb_engine
|
|
 |
b95ef1a |
+ self.__default_xkb_engine = ibus.XKBConfigRegistry.engine_desc_new(
|
|
 |
b95ef1a |
+ "other",
|
|
 |
b95ef1a |
+ "default",
|
|
 |
b95ef1a |
+ _("Default"),
|
|
 |
b95ef1a |
+ None,
|
|
 |
b95ef1a |
+ None)
|
|
 |
b95ef1a |
+ return self.__default_xkb_engine
|
|
 |
b95ef1a |
+
|
|
 |
b95ef1a |
+ def __init_config_layouts(self):
|
|
 |
b95ef1a |
+ if not ibus.XKBConfigRegistry.have_xkb():
|
|
 |
b95ef1a |
+ button = self.__builder.get_object("button_config_layouts")
|
|
 |
b95ef1a |
+ button.hide()
|
|
 |
b95ef1a |
+ return
|
|
 |
b95ef1a |
+
|
|
 |
b95ef1a |
+ self.__dialog_config_layouts = self.__builder.get_object("dialog_config_layouts")
|
|
 |
b95ef1a |
+ self.__button_config_layouts_cancel = self.__builder.get_object("button_config_layouts_cancel")
|
|
 |
b95ef1a |
+ self.__button_config_layouts_cancel.connect("clicked", self.__button_config_layouts_cancel_cb)
|
|
 |
b95ef1a |
+ self.__button_config_layouts_ok = self.__builder.get_object("button_config_layouts_ok")
|
|
 |
b95ef1a |
+ self.__button_config_layouts_ok.connect("clicked", self.__button_config_layouts_ok_cb)
|
|
 |
b95ef1a |
+ self.__vbox_all_keyboard_layouts = self.__builder.get_object("vbox_all_keyboard_layouts")
|
|
 |
b95ef1a |
+
|
|
 |
b95ef1a |
+ xkb_engines = self.__get_xkb_engines()
|
|
 |
b95ef1a |
+ if len(xkb_engines) > 0:
|
|
 |
b95ef1a |
+ button = self.__builder.get_object("button_config_layouts")
|
|
 |
b95ef1a |
+ button.connect("clicked", self.__button_config_layouts_cb)
|
|
 |
b95ef1a |
+ button.set_sensitive(True)
|
|
 |
b95ef1a |
+
|
|
 |
b95ef1a |
+ engine_dict = {}
|
|
 |
b95ef1a |
+ for engine in xkb_engines:
|
|
 |
b95ef1a |
+ if not engine.name.startswith("xkb:layout:"):
|
|
 |
b95ef1a |
+ continue
|
|
 |
b95ef1a |
+ lang = ibus.get_language_name(engine.language)
|
|
 |
b95ef1a |
+ if lang not in engine_dict:
|
|
 |
b95ef1a |
+ engine_dict[lang] = []
|
|
 |
b95ef1a |
+ engine_dict[lang].append(engine)
|
|
 |
b95ef1a |
+
|
|
 |
b95ef1a |
+ keys = engine_dict.keys()
|
|
 |
b95ef1a |
+ keys.sort()
|
|
 |
b95ef1a |
+ if ibus.get_language_name("Other") in keys:
|
|
 |
b95ef1a |
+ keys.remove(ibus.get_language_name("Other"))
|
|
 |
b95ef1a |
+ keys += [ibus.get_language_name("Other")]
|
|
 |
b95ef1a |
+
|
|
 |
b95ef1a |
+ preload_xkb_engines = self.__xkblayoutconfig.get_preload_layouts()
|
|
 |
b95ef1a |
+ for lang in keys:
|
|
 |
b95ef1a |
+ expander = gtk.Expander("")
|
|
 |
b95ef1a |
+ self.__vbox_all_keyboard_layouts.pack_start(expander, True, True, 0)
|
|
 |
b95ef1a |
+ expander.show()
|
|
 |
b95ef1a |
+ label = expander.get_label_widget()
|
|
 |
b95ef1a |
+ label.set_label(lang)
|
|
 |
b95ef1a |
+ align = gtk.Alignment(0, 0, 1, 0)
|
|
 |
b95ef1a |
+ align.set_padding(6, 0, 18, 0)
|
|
 |
b95ef1a |
+ expander.add(align)
|
|
 |
b95ef1a |
+ align.show()
|
|
 |
b95ef1a |
+ vbox = gtk.VBox(False, 0)
|
|
 |
b95ef1a |
+ align.add(vbox)
|
|
 |
b95ef1a |
+ vbox.show()
|
|
 |
b95ef1a |
+
|
|
 |
b95ef1a |
+ def cmp_engine(a, b):
|
|
 |
b95ef1a |
+ if a.rank == b.rank:
|
|
 |
b95ef1a |
+ return cmp(a.longname, b.longname)
|
|
 |
b95ef1a |
+ return int(b.rank - a.rank)
|
|
 |
b95ef1a |
+ engine_dict[lang].sort(cmp_engine)
|
|
 |
b95ef1a |
+
|
|
 |
b95ef1a |
+ for engine in engine_dict[lang]:
|
|
 |
b95ef1a |
+ sub_name = engine.name[len("xkb:layout:"):]
|
|
 |
b95ef1a |
+ layout_list = sub_name.split(':')
|
|
 |
b95ef1a |
+ if len(layout_list) > 1:
|
|
 |
b95ef1a |
+ layout = "%s(%s)" % (layout_list[0], layout_list[1])
|
|
 |
b95ef1a |
+ else:
|
|
 |
b95ef1a |
+ layout = layout_list[0]
|
|
 |
b95ef1a |
+ has_preloaded = False
|
|
 |
b95ef1a |
+ for preload_name in preload_xkb_engines:
|
|
 |
b95ef1a |
+ preload_name = str(preload_name)
|
|
 |
b95ef1a |
+ if len(preload_name) == 0:
|
|
 |
b95ef1a |
+ continue
|
|
 |
b95ef1a |
+ if layout == preload_name:
|
|
 |
b95ef1a |
+ has_preloaded = True
|
|