summaryrefslogtreecommitdiffstats
path: root/kxkb
diff options
context:
space:
mode:
Diffstat (limited to 'kxkb')
-rw-r--r--kxkb/CMakeL10n.txt6
-rw-r--r--kxkb/CMakeLists.txt8
-rw-r--r--kxkb/eventsrc13
-rw-r--r--kxkb/extension.cpp242
-rw-r--r--kxkb/extension.h61
-rw-r--r--kxkb/kcmlayout.cpp185
-rw-r--r--kxkb/kcmlayout.h8
-rw-r--r--kxkb/kcmlayoutwidget.ui159
-rw-r--r--kxkb/kcmmisc.cpp35
-rw-r--r--kxkb/kxkb.cpp435
-rw-r--r--kxkb/kxkb.h24
-rw-r--r--kxkb/kxkbbindings.cpp2
-rw-r--r--kxkb/kxkbconfig.cpp236
-rw-r--r--kxkb/kxkbconfig.h65
-rw-r--r--kxkb/kxkbtraywindow.cpp129
-rw-r--r--kxkb/kxkbtraywindow.h85
-rw-r--r--kxkb/layoutunit.h64
-rw-r--r--kxkb/pixmap.cpp177
-rw-r--r--kxkb/pixmap.h51
-rw-r--r--kxkb/rules.cpp16
-rw-r--r--kxkb/rules.h7
-rw-r--r--kxkb/x11helper.cpp27
-rw-r--r--kxkb/x11helper.h2
23 files changed, 1305 insertions, 732 deletions
diff --git a/kxkb/CMakeL10n.txt b/kxkb/CMakeL10n.txt
index 0238bd7e3..66ed038d9 100644
--- a/kxkb/CMakeL10n.txt
+++ b/kxkb/CMakeL10n.txt
@@ -27,3 +27,9 @@ tde_l10n_create_template(
SOURCES *.desktop
DESTINATION "${CMAKE_SOURCE_DIR}/translations"
)
+
+tde_l10n_create_template(
+ CATALOG "desktop_files/kxkb-eventsrc/"
+ SOURCES eventsrc
+ DESTINATION "${CMAKE_SOURCE_DIR}/translations"
+) \ No newline at end of file
diff --git a/kxkb/CMakeLists.txt b/kxkb/CMakeLists.txt
index b8bb14912..83ca72be7 100644
--- a/kxkb/CMakeLists.txt
+++ b/kxkb/CMakeLists.txt
@@ -33,6 +33,12 @@ tde_create_translated_desktop(
PO_DIR kxkb-desktops
)
+tde_create_translated_desktop(
+ SOURCE eventsrc
+ DESTINATION ${DATA_INSTALL_DIR}/kxkb
+ PO_DIR kxkb-eventsrc
+)
+
install( FILES kxkb_groups DESTINATION ${CONFIG_INSTALL_DIR} )
tde_create_translated_desktop(
@@ -61,5 +67,5 @@ tde_add_tdeinit_executable( kxkb AUTOMOC
extension.cpp x11helper.cpp rules.cpp kxkbconfig.cpp
pixmap.cpp layoutmap.cpp kxkb.cpp kxkbtraywindow.cpp
kxkb.skel
- LINK tdeui-shared ${XKBFILE_LIBRARIES}
+ LINK tdeui-shared ${XKBFILE_LIBRARIES} ${TDEHW_LIBRARIES}
)
diff --git a/kxkb/eventsrc b/kxkb/eventsrc
new file mode 100644
index 000000000..1e06d70c3
--- /dev/null
+++ b/kxkb/eventsrc
@@ -0,0 +1,13 @@
+[!Global!]
+IconName=kxkb
+Comment=TDE Keyboard Tool
+
+[LayoutChange]
+Name=Keyboard layout switch
+Comment=The keyboard layout was switched
+default_presentation=16
+
+[Error]
+Name=Keyboard layout switching error
+Comment=Error while attempting to switch the keyboard layout
+default_presentation=16 \ No newline at end of file
diff --git a/kxkb/extension.cpp b/kxkb/extension.cpp
index df61e2fa2..0fada6932 100644
--- a/kxkb/extension.cpp
+++ b/kxkb/extension.cpp
@@ -1,3 +1,32 @@
+/*******************************************************************************
+
+ Xkb extension for KXkb
+ Copyright © 2009-2025 Trinity Desktop project
+ Copyright © 2001 S.R. Haque <srhaque@iee.org>
+
+ Derived from an original by Matthias H�zer-Klpfel released under the QPL.
+
+ Some portions come from kkbswitch released under the GNU GPL v2 (or later).
+ Copyright © 2001 Leonid Zeitlin <lz@europe.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+*******************************************************************************/
+
+#include <stdlib.h>
#include <string.h>
#include <errno.h>
@@ -5,10 +34,13 @@
#include <tqmap.h>
#include <tqfile.h>
#include <tqdir.h>
+#include <tqtimer.h>
#include <kdebug.h>
-#include <kstandarddirs.h>
-#include <kprocess.h>
+#include <tdeapplication.h>
+#include <tdestandarddirs.h>
+#include <tdeprocess.h>
+#include <dcopclient.h>
#include <X11/Xatom.h>
#include <X11/Xos.h>
@@ -21,58 +53,77 @@
#include "extension.h"
+extern "C"
+{
+ static int IgnoreXError(Display *, XErrorEvent *) { return 0; }
+}
static TQString getLayoutKey(const TQString& layout, const TQString& variant)
{
return layout + "." + variant;
}
-XKBExtension::XKBExtension(Display *d)
+static XKBExtension *xkbExtension = nullptr;
+
+XKBExtension *XKBExtension::the()
{
- if ( d == NULL )
- d = tqt_xdisplay();
- m_dpy = d;
-
-// TQStringList dirs = TDEGlobal::dirs()->findDirs ( "tmp", "" );
-// m_tempDir = dirs.count() == 0 ? "/tmp/" : dirs[0];
- m_tempDir = locateLocal("tmp", "");
+ if (!xkbExtension)
+ {
+ xkbExtension = new XKBExtension;
+ if (!xkbExtension->init())
+ {
+ kdFatal() << "xkb initialization failed, exiting..." << endl;
+ ::exit(1);
+ }
+ }
+ return xkbExtension;
}
bool XKBExtension::init()
{
- // Verify the Xlib has matching XKB extension.
-
- int major = XkbMajorVersion;
- int minor = XkbMinorVersion;
-
- if (!XkbLibraryVersion(&major, &minor))
- {
- kdError() << "[kxkb-extension] Xlib XKB extension " << major << '.' << minor <<
- " != " << XkbMajorVersion << '.' << XkbMinorVersion << endl;
- return false;
- }
-
- // Verify the X server has matching XKB extension.
-
- int opcode_rtrn;
- int error_rtrn;
- int xkb_opcode;
- if (!XkbQueryExtension(m_dpy, &opcode_rtrn, &xkb_opcode, &error_rtrn,
- &major, &minor))
- {
- kdError() << "[kxkb-extension] X server XKB extension " << major << '.' << minor <<
- " != " << XkbMajorVersion << '.' << XkbMinorVersion << endl;
- return false;
- }
-
- // Do it, or face horrible memory corrupting bugs
- ::XkbInitAtoms(NULL);
-
- // watch group change events
- XkbSelectEventDetails(m_dpy, XkbUseCoreKbd, XkbStateNotify,
- XkbAllStateComponentsMask, XkbGroupStateMask);
-
- return true;
+ m_configureFilterCounter = 0;
+
+ kdDebug() << "[kxkb-extension] Initializing Xkb extension" << endl;
+ m_dpy = tqt_xdisplay();
+
+ // Verify the Xlib has matching XKB extension.
+ int major = XkbMajorVersion;
+ int minor = XkbMinorVersion;
+
+ if (!XkbLibraryVersion(&major, &minor))
+ {
+ kdError() << "[kxkb-extension] Xlib XKB extension " << major << '.' << minor <<
+ " != " << XkbMajorVersion << '.' << XkbMinorVersion << endl;
+ return false;
+ }
+
+ // Verify the X server has matching XKB extension.
+ int opcode_rtrn;
+ int error_rtrn;
+ if (!XkbQueryExtension(m_dpy, &opcode_rtrn, &m_xkb_opcode, &error_rtrn, &major, &minor))
+ {
+ kdError() << "[kxkb-extension] X server XKB extension " << major << '.' << minor <<
+ " != " << XkbMajorVersion << '.' << XkbMinorVersion << endl;
+ return false;
+ }
+
+ enableConfigureFilter();
+
+ // Do it, or face horrible memory corrupting bugs
+ ::XkbInitAtoms(nullptr);
+
+ // Watch for interesting events
+ XkbSelectEventDetails(m_dpy, XkbUseCoreKbd, XkbStateNotify,
+ XkbAllStateComponentsMask, XkbGroupStateMask);
+
+ XkbSelectEventDetails(m_dpy, XkbUseCoreKbd, XkbNewKeyboardNotify,
+ XkbAllNewKeyboardEventsMask, XkbAllNewKeyboardEventsMask);
+
+
+ m_tempDir = locateLocal("tmp", "");
+
+ disableConfigureFilter();
+ return true;
}
XKBExtension::~XKBExtension()
@@ -81,11 +132,32 @@ XKBExtension::~XKBExtension()
deletePrecompiledLayouts();*/
}
+void XKBExtension::enableConfigureFilter()
+{
+ ++m_configureFilterCounter;
+}
+
+void XKBExtension::disableConfigureFilter()
+{
+ // Without this protection in place KXkb would react to configuration
+ // changes caused by itself
+ TQTimer::singleShot(500, this, TQ_SLOT(slotReleaseConfigureLock()));
+}
+
+void XKBExtension::slotReleaseConfigureLock()
+{
+ --m_configureFilterCounter;
+}
+
bool XKBExtension::setXkbOptions(const XkbOptions options)
{
+ enableConfigureFilter();
+
TQString exe = TDEGlobal::dirs()->findExe("setxkbmap");
if (exe.isEmpty())
+ {
return false;
+ }
TDEProcess p;
p << exe;
@@ -101,7 +173,7 @@ bool XKBExtension::setXkbOptions(const XkbOptions options)
p << "-variant";
p << options.variants;
}
-
+
if (!options.model.isEmpty()) {
p << "-model";
p << options.model;
@@ -112,16 +184,15 @@ bool XKBExtension::setXkbOptions(const XkbOptions options)
}
if (!options.options.isEmpty()) {
- p << "-option";
-
if (options.resetOld)
{
- p << options.options;
+ p << "-option" << options.options;
}
else
{
// Avoid duplication of options in Append mode
- TQStringList srvOptions = TQStringList::split(",", XKBExtension::getServerOptions());
+ XkbOptions _opt = getServerOptions();
+ TQStringList srvOptions = TQStringList::split(",", _opt.options);
TQStringList kxkbOptions = TQStringList::split(",", options.options);
TQStringList newOptions;
for (TQStringList::Iterator it = kxkbOptions.begin(); it != kxkbOptions.end(); ++it)
@@ -132,48 +203,87 @@ bool XKBExtension::setXkbOptions(const XkbOptions options)
newOptions << option;
}
}
- p << newOptions.join(",");
+ if (!newOptions.isEmpty()) {
+ p << "-option" << newOptions.join(",");
+ }
}
}
+ if (p.args().count() < 2)
+ {
+ // Either the user has not configured any Xkb options or these options
+ // are already set and we are in append mode so we want to avoid
+ // duplicates
+ kdWarning() << "[setXkbOptions] No options need to be set" << endl;
+ slotReleaseConfigureLock(); // immediately release the lock
+ return true;
+ }
+
+ p << "-synch";
+
kdDebug() << "[setXkbOptions] Command: " << p.args() << endl;
p.start(TDEProcess::Block);
+ disableConfigureFilter();
+
return p.normalExit() && (p.exitStatus() == 0);
}
-TQString XKBExtension::getServerOptions()
+XkbOptions XKBExtension::getServerOptions()
{
- XkbRF_VarDefsRec vd;
- if (XkbRF_GetNamesProp(tqt_xdisplay(), nullptr, &vd) && vd.options)
- {
- kdDebug() << "[kxkb-extension] Got server options " << vd.options << endl;
- return TQString(vd.options);
- }
- return TQString::null;
+ XkbOptions options;
+ XkbRF_VarDefsRec vd;
+ if (XkbRF_GetNamesProp(tqt_xdisplay(), nullptr, &vd))
+ {
+ options.model = vd.model;
+ options.layouts = vd.layout;
+ options.variants = vd.variant;
+ options.options = vd.options;
+ }
+ return options;
}
bool XKBExtension::setGroup(unsigned int group)
{
kdDebug() << "[kxkb-extension] Setting group " << group << endl;
- return XkbLockGroup( m_dpy, XkbUseCoreKbd, group );
+ return XkbLockGroup(m_dpy, XkbUseCoreKbd, group);
}
-unsigned int XKBExtension::getGroup() const
+uint XKBExtension::getGroup() const
{
XkbStateRec xkbState;
- XkbGetState( m_dpy, XkbUseCoreKbd, &xkbState );
+ XkbGetState(m_dpy, XkbUseCoreKbd, &xkbState);
return xkbState.group;
}
-/** Examines an X Event passed to it and takes actions if the event is of
- * interest to KXkb */
+bool XKBExtension::kcmlayoutRunning()
+{
+ return tdeApp->dcopClient()->isApplicationRegistered("TDECModuleProxy-keyboard_layout");
+}
+
+// Examines an X Event passed to it and takes actions if the event is of
+// interest to KXkb
void XKBExtension::processXEvent(XEvent *event) {
- XkbEvent* xkb_event = (XkbEvent*)event;
- if (xkb_event->any.xkb_type == XkbStateNotify) {
- emit groupChanged(xkb_event->state.group);
- }
+ if (event->type == m_xkb_opcode)
+ {
+ XkbEvent *xkb_event = (XkbEvent*)event;
+ if (xkb_event->any.xkb_type == XkbStateNotify && xkb_event->state.changed & XkbGroupStateMask)
+ {
+ emit groupChanged((uint)xkb_event->state.group);
+ }
+
+ else if (xkb_event->any.xkb_type == XkbNewKeyboardNotify)
+ {
+ if (m_configureFilterCounter > 0 || kcmlayoutRunning())
+ {
+ return;
+ }
+ enableConfigureFilter();
+ emit optionsChanged();
+ disableConfigureFilter();
+ }
+ }
}
#include "extension.moc"
diff --git a/kxkb/extension.h b/kxkb/extension.h
index 9a3d2da8e..e8c9c7d7c 100644
--- a/kxkb/extension.h
+++ b/kxkb/extension.h
@@ -1,7 +1,36 @@
+/*******************************************************************************
+
+ Xkb extension for KXkb
+ Copyright © 2009-2025 Trinity Desktop project
+ Copyright © 2001 S.R. Haque <srhaque@iee.org>
+
+ Derived from an original by Matthias H�zer-Klpfel released under the QPL.
+
+ Some portions come from kkbswitch released under the GNU GPL v2 (or later).
+ Copyright © 2001 Leonid Zeitlin <lz@europe.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+*******************************************************************************/
+
#ifndef __EXTENSION_H__
#define __EXTENSION_H__
#include <X11/Xlib.h>
+
#include <tqobject.h>
#include "kxkbconfig.h"
@@ -11,24 +40,44 @@ class XKBExtension : public TQObject
TQ_OBJECT
public:
- XKBExtension(Display *display=NULL);
+ static XKBExtension *the();
~XKBExtension();
+
+ XKBExtension(XKBExtension const&) = delete;
+ void operator=(XKBExtension const&) = delete;
+
bool init();
- static bool setXkbOptions(const XkbOptions options);
- static TQString getServerOptions();
- bool setGroup(unsigned int group);
- unsigned int getGroup() const;
+ bool setXkbOptions(const XkbOptions options);
+ bool setGroup(uint group);
+
+ uint getGroup() const;
+ XkbOptions getServerOptions();
+
void processXEvent(XEvent *ev);
+ void enableConfigureFilter();
+ void disableConfigureFilter();
+
+ bool kcmlayoutRunning();
+
+private slots:
+ void slotReleaseConfigureLock();
+
+protected:
+ XKBExtension() {}
+
private:
- Display *m_dpy;
+ Display *m_dpy;
TQString m_tempDir;
int m_keycode;
static TQMap<TQString, FILE*> fileCache;
+ int m_configureFilterCounter;
+ int m_xkb_opcode;
signals:
void groupChanged(uint group);
+ void optionsChanged();
};
#endif
diff --git a/kxkb/kcmlayout.cpp b/kxkb/kcmlayout.cpp
index 3744f5a1c..d9efb9e57 100644
--- a/kxkb/kcmlayout.cpp
+++ b/kxkb/kcmlayout.cpp
@@ -14,6 +14,7 @@
#include <tqbuttongroup.h>
#include <tqspinbox.h>
#include <tqvbox.h>
+#include <tqtimer.h>
#include <tdefontrequester.h>
#include <kcolorbutton.h>
@@ -21,12 +22,12 @@
#include <tdeglobal.h>
#include <tdeconfig.h>
#include <tdelocale.h>
-#include <kstandarddirs.h>
+#include <tdestandarddirs.h>
#include <kdebug.h>
#include <tdeapplication.h>
#include <kiconloader.h>
#include <tdemessagebox.h>
-#include <kglobalaccel.h>
+#include <tdeglobalaccel.h>
#include <dcopref.h>
#include <dcopclient.h>
@@ -36,6 +37,7 @@
#include "pixmap.h"
#include "kcmmisc.h"
#include "kcmlayoutwidget.h"
+#include "x11helper.h"
#include "kcmlayout.h"
#include "kcmlayout.moc"
@@ -105,50 +107,64 @@ LayoutConfig::LayoutConfig(TQWidget *parent, const char *name)
m_rules(NULL),
m_forceGrpOverwrite(false)
{
+ X11Helper::initializeTranslations();
+
+ m_icoMgr = new LayoutIconManager(&m_kxkbConfig);
+
TQVBoxLayout *main = new TQVBoxLayout(this, 0, KDialog::spacingHint());
widget = new LayoutConfigWidget(this, "widget");
- main->addWidget(TQT_TQWIDGET(widget));
+ main->addWidget(widget);
- connect( TQT_TQOBJECT(widget->chkEnable), TQT_SIGNAL( toggled( bool )), TQT_TQOBJECT(this), TQT_SLOT(changed()));
- connect( TQT_TQOBJECT(widget->chkShowSingle), TQT_SIGNAL( toggled( bool )), TQT_TQOBJECT(this), TQT_SLOT(changed()));
+ connect( widget->chkEnable, TQ_SIGNAL( toggled( bool )), this, TQ_SLOT(changed()));
+ connect( widget->chkShowSingle, TQ_SIGNAL( toggled( bool )), this, TQ_SLOT(changed()));
- connect( TQT_TQOBJECT(widget->comboHotkey), TQT_SIGNAL(activated(int)), TQT_TQOBJECT(this), TQT_SLOT(hotkeyComboChanged()));
- connect( TQT_TQOBJECT(widget->comboHotkey), TQT_SIGNAL(activated(int)), TQT_TQOBJECT(this), TQT_SLOT(updateOptionsCommand()));
- connect( TQT_TQOBJECT(widget->comboHotkey), TQT_SIGNAL(activated(int)), TQT_TQOBJECT(this), TQT_SLOT(changed()));
- connect( TQT_TQOBJECT(widget->comboModel), TQT_SIGNAL(activated(int)), TQT_TQOBJECT(this), TQT_SLOT(changed()));
+ connect( widget->comboHotkey, TQ_SIGNAL(activated(int)), this, TQ_SLOT(hotkeyComboChanged()));
+ connect( widget->comboHotkey, TQ_SIGNAL(activated(int)), this, TQ_SLOT(updateOptionsCommand()));
+ connect( widget->comboHotkey, TQ_SIGNAL(activated(int)), this, TQ_SLOT(changed()));
+ connect( widget->comboModel, TQ_SIGNAL(activated(int)), this, TQ_SLOT(changed()));
- connect( TQT_TQOBJECT(widget->listLayoutsSrc), TQT_SIGNAL(doubleClicked(TQListViewItem*,const TQPoint&, int)),
- TQT_TQOBJECT(this), TQT_SLOT(add()));
- connect( TQT_TQOBJECT(widget->btnAdd), TQT_SIGNAL(clicked()), TQT_TQOBJECT(this), TQT_SLOT(add()));
- connect( TQT_TQOBJECT(widget->btnRemove), TQT_SIGNAL(clicked()), TQT_TQOBJECT(this), TQT_SLOT(remove()));
+ connect( widget->listLayoutsSrc, TQ_SIGNAL(doubleClicked(TQListViewItem*,const TQPoint&, int)),
+ this, TQ_SLOT(add()));
+ connect( widget->btnAdd, TQ_SIGNAL(clicked()), this, TQ_SLOT(add()));
+ connect( widget->btnRemove, TQ_SIGNAL(clicked()), this, TQ_SLOT(remove()));
- connect( TQT_TQOBJECT(widget->comboVariant), TQT_SIGNAL(activated(int)), TQT_TQOBJECT(this), TQT_SLOT(changed()));
- connect( TQT_TQOBJECT(widget->comboVariant), TQT_SIGNAL(activated(int)), TQT_TQOBJECT(this), TQT_SLOT(variantChanged()));
- connect( TQT_TQOBJECT(widget->listLayoutsDst), TQT_SIGNAL(selectionChanged(TQListViewItem *)),
- TQT_TQOBJECT(this), TQT_SLOT(layoutSelChanged(TQListViewItem *)));
+ connect( widget->comboVariant, TQ_SIGNAL(activated(int)), this, TQ_SLOT(changed()));
+ connect( widget->comboVariant, TQ_SIGNAL(activated(int)), this, TQ_SLOT(variantChanged()));
+ connect( widget->listLayoutsDst, TQ_SIGNAL(selectionChanged(TQListViewItem *)),
+ this, TQ_SLOT(layoutSelChanged(TQListViewItem *)));
- connect( widget->editDisplayName, TQT_SIGNAL(textChanged(const TQString&)), TQT_TQOBJECT(this), TQT_SLOT(displayNameChanged(const TQString&)));
+ connect( widget->editDisplayName, TQ_SIGNAL(textChanged(const TQString&)), this, TQ_SLOT(displayNameChanged(const TQString&)));
widget->btnUp->setIconSet(SmallIconSet("1uparrow"));
- connect( widget->btnUp, TQT_SIGNAL(clicked()), TQT_TQOBJECT(this), TQT_SLOT(changed()));
- connect( widget->btnUp, TQT_SIGNAL(clicked()), TQT_TQOBJECT(this), TQT_SLOT(moveUp()));
+ connect( widget->btnUp, TQ_SIGNAL(clicked()), this, TQ_SLOT(changed()));
+ connect( widget->btnUp, TQ_SIGNAL(clicked()), this, TQ_SLOT(moveUp()));
widget->btnDown->setIconSet(SmallIconSet("1downarrow"));
- connect( widget->btnDown, TQT_SIGNAL(clicked()), TQT_TQOBJECT(this), TQT_SLOT(changed()));
- connect( widget->btnDown, TQT_SIGNAL(clicked()), TQT_TQOBJECT(this), TQT_SLOT(moveDown()));
+ connect( widget->btnDown, TQ_SIGNAL(clicked()), this, TQ_SLOT(changed()));
+ connect( widget->btnDown, TQ_SIGNAL(clicked()), this, TQ_SLOT(moveDown()));
+
+ connect( widget->grpStyle, TQ_SIGNAL( clicked( int ) ), TQ_SLOT(changed()));
+ connect( widget->grpSwitching, TQ_SIGNAL( clicked( int ) ), TQ_SLOT(changed()));
+ connect( widget->grpLabel, TQ_SIGNAL( clicked( int ) ), TQ_SLOT(changed()));
+
+ connect( widget->chkFitToBox, TQ_SIGNAL(toggled(bool)), this, TQ_SLOT(changed()));
+ connect( widget->chkDimFlag, TQ_SIGNAL(toggled(bool)), this, TQ_SLOT(changed()));
+
+ connect( widget->bgColor, TQ_SIGNAL( changed(const TQColor&) ), this, TQ_SLOT(changed()));
+ connect( widget->fgColor, TQ_SIGNAL( changed(const TQColor&) ), this, TQ_SLOT(changed()));
+ connect( widget->chkBgTransparent, TQ_SIGNAL( toggled(bool) ), this, TQ_SLOT(changed()));
+ connect( widget->labelFont, TQ_SIGNAL( fontSelected(const TQFont&) ), this, TQ_SLOT(changed()));
+ connect( widget->chkLabelShadow, TQ_SIGNAL( toggled( bool ) ), this, TQ_SLOT(changed()));
+ connect( widget->shColor, TQ_SIGNAL( changed(const TQColor&) ), this, TQ_SLOT(changed()));
- connect( widget->grpStyle, TQT_SIGNAL( clicked( int ) ), TQT_SLOT(changed()));
- connect( widget->grpSwitching, TQT_SIGNAL( clicked( int ) ), TQT_SLOT(changed()));
- connect( widget->grpLabel, TQT_SIGNAL( clicked( int ) ), TQT_SLOT(changed()));
+ connect( widget->chkBevel, TQ_SIGNAL(toggled(bool)), this, TQ_SLOT(changed()));
- connect( widget->bgColor, TQT_SIGNAL( changed(const TQColor&) ), TQT_TQOBJECT(this), TQT_SLOT(changed()));
- connect( widget->fgColor, TQT_SIGNAL( changed(const TQColor&) ), TQT_TQOBJECT(this), TQT_SLOT(changed()));
- connect( widget->labelFont, TQT_SIGNAL( fontSelected(const TQFont&) ), TQT_TQOBJECT(this), TQT_SLOT(changed()));
- connect( widget->chkLabelShadow, TQT_SIGNAL( toggled( bool ) ), TQT_TQOBJECT(this), TQT_SLOT(changed()));
- connect( widget->shColor, TQT_SIGNAL( changed(const TQColor&) ), TQT_TQOBJECT(this), TQT_SLOT(changed()));
+ connect( widget->chkEnableSticky, TQ_SIGNAL(toggled(bool)), this, TQ_SLOT(changed()));
+ connect( widget->spinStickyDepth, TQ_SIGNAL(valueChanged(int)), this, TQ_SLOT(changed()));
- connect( widget->chkEnableSticky, TQT_SIGNAL(toggled(bool)), TQT_TQOBJECT(this), TQT_SLOT(changed()));
- connect( widget->spinStickyDepth, TQT_SIGNAL(valueChanged(int)), TQT_TQOBJECT(this), TQT_SLOT(changed()));
+ connect(widget->chkEnableNotify, TQ_SIGNAL(toggled(bool)), TQ_SLOT(changed()));
+ connect(widget->chkNotifyUseKMilo, TQ_SIGNAL(toggled(bool)), TQ_SLOT(changed()));
+ connect(widget->chkEnableNotify, TQ_SIGNAL(toggled(bool)), widget->chkNotifyUseKMilo, TQ_SLOT(setEnabled(bool)));
widget->listLayoutsSrc->setColumnText(LAYOUT_COLUMN_FLAG, "");
widget->listLayoutsDst->setColumnText(LAYOUT_COLUMN_FLAG, "");
@@ -157,7 +173,7 @@ LayoutConfig::LayoutConfig(TQWidget *parent, const char *name)
widget->listLayoutsSrc->setColumnWidth(LAYOUT_COLUMN_FLAG, 28);
widget->listLayoutsDst->setColumnWidth(LAYOUT_COLUMN_FLAG, 28);
- widget->listLayoutsDst->header()->setResizeEnabled(FALSE, LAYOUT_COLUMN_DISPLAY_NAME);
+ widget->listLayoutsDst->header()->setResizeEnabled(false, LAYOUT_COLUMN_DISPLAY_NAME);
// widget->listLayoutsDst->setColumnWidth(LAYOUT_COLUMN_DISPLAY_NAME, 0);
widget->listLayoutsDst->setSorting(-1);
@@ -172,31 +188,41 @@ LayoutConfig::LayoutConfig(TQWidget *parent, const char *name)
// Load global shortcuts
#define NOSLOTS
- keys = new TDEGlobalAccel(TQT_TQOBJECT(this));
+ keys = new TDEGlobalAccel(this);
#include "kxkbbindings.cpp"
+ keys->readSettings();
makeOptionsTab();
- load();
makeShortcutsTab();
+ TQTimer::singleShot(0, this, TQ_SLOT(load()));
}
LayoutConfig::~LayoutConfig()
{
- delete m_rules;
+ delete m_rules;
+ delete m_icoMgr;
}
void LayoutConfig::load()
{
- m_kxkbConfig.load(KxkbConfig::LOAD_ALL);
+ bool modified = false;
+ m_kxkbConfig.load(KxkbConfig::LOAD_ALL_OPTIONS);
- keys->readSettings();
+ // Check if the active settings are different from the saved settings
+ if (m_kxkbConfig.m_useKxkb)
+ {
+ XkbOptions options = XKBExtension::the()->getServerOptions();
+ modified = m_kxkbConfig.setFromXkbOptions(options);
+ }
- initUI();
+ m_kxkbConfig.load(KxkbConfig::LOAD_ALL_OPTIONS);
+ keys->readSettings();
+ initUI(modified);
}
-void LayoutConfig::initUI() {
+void LayoutConfig::initUI(bool modified) {
const char* modelName = m_rules->models()[m_kxkbConfig.m_model];
if( modelName == NULL )
modelName = DEFAULT_MODEL;
@@ -213,7 +239,6 @@ void LayoutConfig::initUI() {
for ( ; src_it.current(); ++src_it ) {
TQListViewItem* srcItem = src_it.current();
-
if ( layoutUnit.layout == src_it.current()->text(LAYOUT_COLUMN_MAP) ) { // check if current config knows about this layout
TQListViewItem* newItem = copyLVI(srcItem, widget->listLayoutsDst);
@@ -240,7 +265,7 @@ void LayoutConfig::initUI() {
const char *hkOpt = tqstrdup(TQString("grp:" + (*hk)).ascii());
const char *hkDesc = allOptions[hkOpt];
if (hkDesc != 0) { // the option exists
- widget->comboHotkey->insertItem(i18n(hkDesc));
+ widget->comboHotkey->insertItem(XkbRules::trOpt(hkDesc));
}
}
widget->comboHotkey->insertItem(i18n("None"));
@@ -254,6 +279,8 @@ void LayoutConfig::initUI() {
widget->radFlagLabel->setChecked( showFlag && showLabel );
widget->radFlagOnly->setChecked( showFlag && !showLabel );
widget->radLabelOnly->setChecked( !showFlag && showLabel );
+ widget->chkFitToBox->setChecked(m_kxkbConfig.m_fitToBox);
+ widget->chkDimFlag->setChecked(m_kxkbConfig.m_dimFlag);
widget->xkbOptsMode->setButton(m_kxkbConfig.m_resetOldOptions ? 0 : 1);
@@ -265,11 +292,15 @@ void LayoutConfig::initUI() {
widget->chkLabelShadow->setChecked( m_kxkbConfig.m_labelShadow );
widget->shColor->setColor( m_kxkbConfig.m_colorShadow );
+ widget->chkBevel->setChecked(m_kxkbConfig.m_bevel);
+
widget->grpLabel->setDisabled(showFlag && !showLabel);
widget->grpLabelColors->setDisabled(m_kxkbConfig.m_useThemeColors);
widget->labelBgColor->setDisabled(showFlag);
widget->bgColor->setDisabled(showFlag);
widget->chkBgTransparent->setDisabled(showFlag);
+ widget->grpFlag->setEnabled(showFlag);
+ widget->chkDimFlag->setEnabled(showFlag && showLabel);
switch( m_kxkbConfig.m_switchingPolicy ) {
default:
@@ -288,6 +319,10 @@ void LayoutConfig::initUI() {
widget->spinStickyDepth->setEnabled(m_kxkbConfig.m_stickySwitching);
widget->spinStickyDepth->setValue( m_kxkbConfig.m_stickySwitchingDepth);
+ widget->chkEnableNotify->setChecked(m_kxkbConfig.m_enableNotify);
+ widget->chkNotifyUseKMilo->setChecked(m_kxkbConfig.m_notifyUseKMilo);
+ widget->chkNotifyUseKMilo->setEnabled(m_kxkbConfig.m_enableNotify);
+
updateStickyLimit();
widget->chkEnable->setChecked( m_kxkbConfig.m_useKxkb );
@@ -308,7 +343,7 @@ void LayoutConfig::initUI() {
foundGrp = true;
}
- OptionListItem *item = m_optionGroups[i18n(optionKey.latin1())];
+ OptionListItem *item = m_optionGroups[optionKey];
if (item != NULL) {
OptionListItem *child = item->findChildItem( option );
@@ -332,7 +367,7 @@ void LayoutConfig::initUI() {
updateOptionsCommand();
updateHotkeyCombo(true);
- emit TDECModule::changed( false );
+ emit TDECModule::changed(modified);
}
@@ -344,6 +379,9 @@ void LayoutConfig::save()
m_kxkbConfig.m_resetOldOptions = widget->radXkbOverwrite->isOn();
m_kxkbConfig.m_options = createOptionString();
+ m_kxkbConfig.m_fitToBox = widget->chkFitToBox->isChecked();
+ m_kxkbConfig.m_dimFlag = widget->chkDimFlag->isChecked();
+
m_kxkbConfig.m_useThemeColors = widget->radLabelUseTheme->isChecked();
m_kxkbConfig.m_colorBackground = widget->bgColor->color();
m_kxkbConfig.m_colorLabel = widget->fgColor->color();
@@ -352,6 +390,8 @@ void LayoutConfig::save()
m_kxkbConfig.m_labelShadow = widget->chkLabelShadow->isChecked();
m_kxkbConfig.m_colorShadow = widget->shColor->color();
+ m_kxkbConfig.m_bevel = widget->chkBevel->isChecked();
+
TQListViewItem *item = widget->listLayoutsDst->firstChild();
TQValueList<LayoutUnit> layouts;
while (item) {
@@ -397,13 +437,17 @@ void LayoutConfig::save()
m_kxkbConfig.m_stickySwitching = widget->chkEnableSticky->isChecked();
m_kxkbConfig.m_stickySwitchingDepth = widget->spinStickyDepth->value();
+ m_kxkbConfig.m_enableNotify = widget->chkEnableNotify->isChecked();
+ m_kxkbConfig.m_notifyUseKMilo = widget->chkNotifyUseKMilo->isChecked();
+
m_kxkbConfig.save();
// We might need to unset previous hotkey options
if (m_forceGrpOverwrite)
{
// First get all the server's options
- TQStringList srvOptions = TQStringList::split(",", XKBExtension::getServerOptions());
+ XkbOptions _opt = XKBExtension::the()->getServerOptions();
+ TQStringList srvOptions = TQStringList::split(",", _opt.options);
TQStringList newOptions;
// Then remove all grp: options
@@ -420,7 +464,7 @@ void LayoutConfig::save()
xkbOptions.options = newOptions.join(",");
xkbOptions.resetOld = true;
- if (!XKBExtension::setXkbOptions(xkbOptions))
+ if (!XKBExtension::the()->setXkbOptions(xkbOptions))
{
kdWarning() << "[LayoutConfig::save] Could not overwrite previous grp: options!" << endl;
}
@@ -433,8 +477,8 @@ void LayoutConfig::save()
keys->writeSettings(0, true);
// Get current layout from Kxkb
- if (!kapp->dcopClient()->isAttached())
- kapp->dcopClient()->attach();
+ if (!tdeApp->dcopClient()->isAttached())
+ tdeApp->dcopClient()->attach();
DCOPRef kxkbref("kxkb", "kxkb");
DCOPReply reply = kxkbref.call( "getCurrentLayout" );
@@ -447,7 +491,7 @@ void LayoutConfig::save()
}
// Cause Kxkb to reread configuration
- kapp->tdeinitExecWait("kxkb");
+ tdeApp->tdeinitExecWait("kxkb");
// If previous call was valid, try to change layout
if ( reply.isValid() ) {
@@ -659,13 +703,13 @@ TQWidget* LayoutConfig::makeOptionsTab()
listView->setColumnText( 0, i18n( "Options" ) );
listView->clear();
- connect(listView, TQT_SIGNAL(clicked(TQListViewItem *)), TQT_SLOT(changed()));
- connect(listView, TQT_SIGNAL(clicked(TQListViewItem *)), TQT_SLOT(resolveConflicts(TQListViewItem *)));
- connect(listView, TQT_SIGNAL(clicked(TQListViewItem *)), TQT_SLOT(updateHotkeyCombo()));
+ connect(listView, TQ_SIGNAL(clicked(TQListViewItem *)), TQ_SLOT(changed()));
+ connect(listView, TQ_SIGNAL(clicked(TQListViewItem *)), TQ_SLOT(resolveConflicts(TQListViewItem *)));
+ connect(listView, TQ_SIGNAL(clicked(TQListViewItem *)), TQ_SLOT(updateHotkeyCombo()));
- connect(widget->xkbOptsMode, TQT_SIGNAL(released(int)), TQT_SLOT(changed()));
- connect(widget->xkbOptsMode, TQT_SIGNAL(released(int)), TQT_SLOT(updateOptionsCommand()));
- connect(widget->xkbOptsMode, TQT_SIGNAL(released(int)), TQT_SLOT(updateHotkeyCombo()));
+ connect(widget->xkbOptsMode, TQ_SIGNAL(released(int)), TQ_SLOT(changed()));
+ connect(widget->xkbOptsMode, TQ_SIGNAL(released(int)), TQ_SLOT(updateOptionsCommand()));
+ connect(widget->xkbOptsMode, TQ_SIGNAL(released(int)), TQ_SLOT(updateHotkeyCombo()));
//Create controllers for all options
TQDictIterator<char> it(m_rules->options());
@@ -676,25 +720,25 @@ TQWidget* LayoutConfig::makeOptionsTab()
{
if( it.currentKey() == "ctrl" || it.currentKey() == "caps"
|| it.currentKey() == "altwin") {
- parent = new OptionListItem(listView, i18n( it.current() ),
+ parent = new OptionListItem(listView, XkbRules::trOpt( it.current() ),
TQCheckListItem::RadioButtonController, it.currentKey());
OptionListItem *item = new OptionListItem(parent, i18n( "None" ),
TQCheckListItem::RadioButton, "none");
item->setState(TQCheckListItem::On);
}
else if (it.currentKey() == "grp") {
- parent = new OptionListItem(listView, i18n(it.current()),
+ parent = new OptionListItem(listView, XkbRules::trOpt(it.current()),
TQCheckListItem::RadioButtonController, it.currentKey());
parent->setSelectable(false);
OptionListItem *item = new OptionListItem(parent, i18n("None"),
TQCheckListItem::CheckBox, "grp:none");
}
else {
- parent = new OptionListItem(listView, i18n( it.current() ),
+ parent = new OptionListItem(listView, XkbRules::trOpt( it.current() ),
TQCheckListItem::CheckBoxController, it.currentKey());
}
parent->setOpen(true);
- m_optionGroups.insert(i18n(it.currentKey().local8Bit()), parent);
+ m_optionGroups.insert(it.currentKey(), parent);
}
}
@@ -714,10 +758,10 @@ TQWidget* LayoutConfig::makeOptionsTab()
text = text.replace( "Cap$", "Caps." );
if ( parent->type() == TQCheckListItem::CheckBoxController
|| key.startsWith("grp:"))
- new OptionListItem(parent, i18n(text.utf8()),
+ new OptionListItem(parent, XkbRules::trOpt(text),
TQCheckListItem::CheckBox, key);
else
- new OptionListItem(parent, i18n(text.utf8()),
+ new OptionListItem(parent, XkbRules::trOpt(text),
TQCheckListItem::RadioButton, key);
}
}
@@ -730,7 +774,7 @@ TQWidget* LayoutConfig::makeOptionsTab()
TQWidget* LayoutConfig::makeShortcutsTab() {
m_keyChooser = new KKeyChooser(keys, widget->tabShortcuts, false, false);
- connect(m_keyChooser, SIGNAL(keyChange()), this, SLOT(changed()));
+ connect(m_keyChooser, TQ_SIGNAL(keyChange()), this, TQ_SLOT(changed()));
widget->tabShortcuts->layout()->add(m_keyChooser);
return m_keyChooser;
}
@@ -978,7 +1022,8 @@ void LayoutConfig::updateHotkeyCombo(bool initial) {
// Get server options first
if (initial || widget->xkbOptsMode->selectedId() == 1)
{
- TQStringList opts = TQStringList::split(",", XKBExtension::getServerOptions());
+ XkbOptions _opt = XKBExtension::the()->getServerOptions();
+ TQStringList opts = TQStringList::split(",", _opt.options);
for (TQStringList::Iterator it = opts.begin(); it != opts.end(); ++it)
{
TQString option(*it);
@@ -1129,7 +1174,7 @@ void LayoutConfig::loadRules()
TQString layoutName = it2.current();
TQListViewItem *item = new TQListViewItem(widget->listLayoutsSrc);
- item->setPixmap(LAYOUT_COLUMN_FLAG, LayoutIcon::getInstance().findPixmap(layout, false));
+ item->setPixmap(LAYOUT_COLUMN_FLAG, m_icoMgr->find(layout, PIXMAP_STYLE_CONTEXTMENU));
item->setText(LAYOUT_COLUMN_NAME, i18n(layoutName.latin1()));
item->setText(LAYOUT_COLUMN_MAP, layout);
++it2;
@@ -1217,17 +1262,17 @@ OptionListItem * OptionListItem::findChildItem( const TQString& optionName )
extern "C"
{
- KDE_EXPORT TDECModule *create_keyboard_layout(TQWidget *parent, const char *)
+ TDE_EXPORT TDECModule *create_keyboard_layout(TQWidget *parent, const char *)
{
return new LayoutConfig(parent, "kcmlayout");
}
- KDE_EXPORT TDECModule *create_keyboard(TQWidget *parent, const char *)
+ TDE_EXPORT TDECModule *create_keyboard(TQWidget *parent, const char *)
{
return new KeyboardConfig(parent, "kcmlayout");
}
- KDE_EXPORT void init_keyboard()
+ TDE_EXPORT void init_keyboard()
{
KeyboardConfig::init_keyboard();
@@ -1235,10 +1280,10 @@ extern "C"
m_kxkbConfig.load(KxkbConfig::LOAD_INIT_OPTIONS);
if( m_kxkbConfig.m_useKxkb == true ) {
- kapp->startServiceByDesktopName("kxkb");
+ tdeApp->startServiceByDesktopName("kxkb");
}
else {
- if (!XKBExtension::setXkbOptions(m_kxkbConfig.getKXkbOptions())) {
+ if (!XKBExtension::the()->setXkbOptions(m_kxkbConfig.getKXkbOptions())) {
kdDebug() << "Setting XKB options failed!" << endl;
}
}
@@ -1323,7 +1368,7 @@ extern "C"
//these seem to be new in XFree86 4.4.0
I18N_NOOP("Shift with numpad keys works as in MS Windows.");
- I18N_NOOP("Special keys (Ctrl+Alt+<key>) handled in a server.");
+ I18N_NOOP("Special keys (Ctrl+Alt+&lt;key&gt;) handled in a server.");
I18N_NOOP("Miscellaneous compatibility options");
I18N_NOOP("Right Control key works as Right Alt");
diff --git a/kxkb/kcmlayout.h b/kxkb/kcmlayout.h
index db0f89690..0d2e153b2 100644
--- a/kxkb/kcmlayout.h
+++ b/kxkb/kcmlayout.h
@@ -11,6 +11,7 @@
class OptionListItem;
+class LayoutIconManager;
class LayoutConfigWidget;
class XkbRules;
@@ -22,11 +23,13 @@ public:
LayoutConfig(TQWidget *parent = 0L, const char *name = 0L);
virtual ~LayoutConfig();
+ void initUI(bool modified = false);
+ virtual TQString handbookDocPath() const;
+
+public slots:
void load();
void save();
void defaults();
- void initUI();
- virtual TQString handbookDocPath() const;
protected:
TQString createOptionString();
@@ -52,6 +55,7 @@ protected slots:
void changed();
private:
+ LayoutIconManager *m_icoMgr;
LayoutConfigWidget* widget;
XkbRules *m_rules;
diff --git a/kxkb/kcmlayoutwidget.ui b/kxkb/kcmlayoutwidget.ui
index c35df0921..52cab2e88 100644
--- a/kxkb/kcmlayoutwidget.ui
+++ b/kxkb/kcmlayoutwidget.ui
@@ -8,8 +8,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>709</width>
- <height>563</height>
+ <width>700</width>
+ <height>600</height>
</rect>
</property>
<property name="sizePolicy">
@@ -22,8 +22,8 @@
</property>
<property name="minimumSize">
<size>
- <width>600</width>
- <height>510</height>
+ <width>700</width>
+ <height>600</height>
</size>
</property>
<grid>
@@ -611,6 +611,41 @@
</widget>
</grid>
</widget>
+ <widget class="TQGroupBox">
+ <property name="name">
+ <cstring>grpBoxNotifications</cstring>
+ </property>
+ <property name="title">
+ <string>Notifications</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQCheckBox">
+ <property name="name">
+ <cstring>chkEnableNotify</cstring>
+ </property>
+ <property name="text">
+ <string>Enable keyboard layout notification</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>If this option is enabled, a little notification will pop up on the screen displaying the name of the currently selected layout whenever it changes.</string>
+ </property>
+ </widget>
+ <widget class="TQCheckBox">
+ <property name="name">
+ <cstring>chkNotifyUseKMilo</cstring>
+ </property>
+ <property name="text">
+ <string>Use KMilo for notifications, if available</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>If this option is enabled and KMilo is available, it will be used to display the notifications instead of the standard notification system. If KMilo is not available, notifications will be showed via the standard TDE notification system.</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
</vbox>
</widget>
<spacer>
@@ -869,36 +904,19 @@
</size>
</property>
</spacer>
- <spacer row="4" column="0">
- <property name="name">
- <cstring>spacer22</cstring>
- </property>
- <property name="orientation">
- <enum>Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>Fixed</enum>
- </property>
- <property name="sizeHint">
- <size>
- <width>20</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- <widget class="TQCheckBox" row="4" column="1" rowspan="1" colspan="3">
- <property name="name">
- <cstring>chkBgTransparent</cstring>
- </property>
- <property name="text">
- <string>Transparent background</string>
- </property>
- <property name="whatsThis" stdset="0">
- <string>Check this to remove the indicator's background. Only applicable in "Label only" mode.</string>
- </property>
- </widget>
</grid>
</widget>
+ <widget class="TQCheckBox" row="4" column="0" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>chkBgTransparent</cstring>
+ </property>
+ <property name="text">
+ <string>Transparent background</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Check this to remove the indicator's background. Only applicable in "Label only" mode.</string>
+ </property>
+ </widget>
<widget class="KSeparator" row="5" column="0" rowspan="1" colspan="3">
<property name="name">
<cstring>separator1</cstring>
@@ -957,7 +975,8 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
- </widget> <spacer row="7" column="2">
+ </widget>
+ <spacer row="7" column="2">
<property name="name">
<cstring>spacer23</cstring>
</property>
@@ -976,6 +995,35 @@
</spacer>
</grid>
</widget>
+ <widget class="TQButtonGroup" row="2" column="0" column="0" colspan="2">
+ <property name="name">
+ <cstring>grpFlag</cstring>
+ </property>
+ <property name="title">
+ <string>Flag Style</string>
+ </property>
+ <vbox>
+ <widget class="TQCheckBox">
+ <property name="name">
+ <cstring>chkFitToBox</cstring>
+ </property>
+ <property name="text">
+ <string>Stretc&amp;h flag</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>If this option is enabled, the flag will be stretched to fit the tray indicator size.</string>
+ </property>
+ </widget>
+ <widget class="TQCheckBox">
+ <property name="name">
+ <cstring>chkDimFlag</cstring>
+ </property>
+ <property name="text">
+ <string>Dim flag to make the label more visible</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
<widget class="TQButtonGroup" row="0" column="1">
<property name="name">
<cstring>grpMisc</cstring>
@@ -992,6 +1040,17 @@
<string>Show indicator for single layout</string>
</property>
</widget>
+ <widget class="TQCheckBox">
+ <property name="name">
+ <cstring>chkBevel</cstring>
+ </property>
+ <property name="text">
+ <string>Show indicator bevel</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>If this option is enabled, the layout indicator will be drawn with a thin 3D bevel around it.</string>
+ </property>
+ </widget>
</vbox>
</widget>
</grid>
@@ -1174,8 +1233,8 @@
<signal>toggled(bool)</signal>
<receiver>bgColor</receiver>
<slot>setEnabled(bool)</slot>
- </connection>
- <connection>
+ </connection>
+ <connection>
<sender>radLabelOnly</sender>
<signal>toggled(bool)</signal>
<receiver>labelBgColor</receiver>
@@ -1193,6 +1252,36 @@
<receiver>labelBgColor</receiver>
<slot>setDisabled(bool)</slot>
</connection>
+ <connection>
+ <sender>chkEnableNotify</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>chkNotifyUseKMilo</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>radFlagOnly</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>grpFlag</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>radFlagLabel</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>grpFlag</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>radLabelOnly</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>grpFlag</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>radFlagLabel</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>chkDimFlag</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
</connections>
<includes>
<include location="local" impldecl="in implementation">kiconloader.h</include>
diff --git a/kxkb/kcmmisc.cpp b/kxkb/kcmmisc.cpp
index 358d10450..0fb62a466 100644
--- a/kxkb/kcmmisc.cpp
+++ b/kxkb/kcmmisc.cpp
@@ -42,12 +42,13 @@
#include <knuminput.h>
#include <tdeapplication.h>
#include <tdeglobal.h>
-#include <kstandarddirs.h>
-#include <kprocess.h>
+#include <tdestandarddirs.h>
+#include <tdeprocess.h>
#include <kdialog.h>
#include "kcmmisc.h"
#include "kcmmiscwidget.h"
+#include "x11helper.h"
#include <X11/Xlib.h>
KeyboardConfig::KeyboardConfig (TQWidget * parent, const char *)
@@ -60,25 +61,27 @@ KeyboardConfig::KeyboardConfig (TQWidget * parent, const char *)
lay->addStretch();
ui->click->setRange(0, 100, 10);
- ui->delay->setRange(100, 5000, 50, false);
+ ui->delay->setRange(0, 5000, 10, false);
ui->rate->setRange(5, 50, 5, false);
- ui->delaySlider->setRange(1000, 50000);
+ // Values multiplied by 10 compated to the integer input field
+ ui->delaySlider->setRange(0, 50000);
ui->delaySlider->setSteps(50, 500);
ui->delaySlider->setTickInterval(2500);
+ // Values multiplied by 100 compated to the integer input field
ui->rateSlider->setRange(500, 5000);
- ui->rateSlider->setSteps(50, 500);
+ ui->rateSlider->setSteps(100, 500);
ui->rateSlider->setTickInterval(500);
- connect(ui->repeatBox, TQT_SIGNAL(clicked()), this, TQT_SLOT(changed()));
- connect(ui->delay, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(delaySpinboxChanged(int)));
- connect(ui->delaySlider, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(delaySliderChanged(int)));
- connect(ui->rate, TQT_SIGNAL(valueChanged(double)), this, TQT_SLOT(rateSpinboxChanged(double)));
- connect(ui->rateSlider, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(rateSliderChanged(int)));
+ connect(ui->repeatBox, TQ_SIGNAL(clicked()), this, TQ_SLOT(changed()));
+ connect(ui->delay, TQ_SIGNAL(valueChanged(int)), this, TQ_SLOT(delaySpinboxChanged(int)));
+ connect(ui->delaySlider, TQ_SIGNAL(valueChanged(int)), this, TQ_SLOT(delaySliderChanged(int)));
+ connect(ui->rate, TQ_SIGNAL(valueChanged(double)), this, TQ_SLOT(rateSpinboxChanged(double)));
+ connect(ui->rateSlider, TQ_SIGNAL(valueChanged(int)), this, TQ_SLOT(rateSliderChanged(int)));
- connect(ui->click, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(changed()));
- connect(ui->numlockGroup, TQT_SIGNAL(released(int)), this, TQT_SLOT(changed()));
+ connect(ui->click, TQ_SIGNAL(valueChanged(int)), this, TQ_SLOT(changed()));
+ connect(ui->numlockGroup, TQ_SIGNAL(released(int)), this, TQ_SLOT(changed()));
#if !defined(HAVE_XTEST) && !defined(HAVE_XKB)
ui->numlockGroup->setDisabled( true );
@@ -126,7 +129,7 @@ void KeyboardConfig::load()
XKeyboardState kbd;
- XGetKeyboardControl(kapp->getDisplay(), &kbd);
+ XGetKeyboardControl(tdeApp->getDisplay(), &kbd);
config.setGroup("Keyboard");
bool key = config.readBoolEntry("KeyboardRepeating", true);
@@ -153,7 +156,7 @@ void KeyboardConfig::save()
kbd.key_click_percent = clickVolume;
kbd.auto_repeat_mode = keyboardRepeat;
- XChangeKeyboardControl(kapp->getDisplay(),
+ XChangeKeyboardControl(tdeApp->getDisplay(),
KBKeyClickPercent | KBAutoRepeatMode,
&kbd);
if( keyboardRepeat ) {
@@ -535,12 +538,12 @@ void KeyboardConfig::init_keyboard()
XKeyboardState kbd;
XKeyboardControl kbdc;
- XGetKeyboardControl(kapp->getDisplay(), &kbd);
+ XGetKeyboardControl(tdeApp->getDisplay(), &kbd);
bool key = config->readBoolEntry("KeyboardRepeating", true);
kbdc.key_click_percent = config->readNumEntry("ClickVolume", kbd.key_click_percent);
kbdc.auto_repeat_mode = (key ? AutoRepeatModeOn : AutoRepeatModeOff);
- XChangeKeyboardControl(kapp->getDisplay(),
+ XChangeKeyboardControl(tdeApp->getDisplay(),
KBKeyClickPercent | KBAutoRepeatMode,
&kbdc);
diff --git a/kxkb/kxkb.cpp b/kxkb/kxkb.cpp
index 8d725e3e5..6aa5b8ee2 100644
--- a/kxkb/kxkb.cpp
+++ b/kxkb/kxkb.cpp
@@ -24,29 +24,35 @@ DESCRIPTION
*/
#include <unistd.h>
-#include <stdlib.h>
#include <assert.h>
#include <tqregexp.h>
#include <tqfile.h>
#include <tqstringlist.h>
#include <tqimage.h>
+#include <tqtimer.h>
#include <tdeaboutdata.h>
#include <tdecmdlineargs.h>
+#ifdef WITH_TDEHWLIB
+#include <tdehardwaredevices.h>
+#endif
#include <tdeglobal.h>
-#include <kglobalaccel.h>
+#include <tdeglobalaccel.h>
#include <tdelocale.h>
-#include <kprocess.h>
+#include <tdeprocess.h>
#include <twinmodule.h>
#include <twin.h>
#include <tdetempfile.h>
-#include <kstandarddirs.h>
+#include <tdestandarddirs.h>
#include <kipc.h>
#include <tdeaction.h>
#include <tdepopupmenu.h>
#include <kdebug.h>
#include <tdeconfig.h>
+#include <knotifyclient.h>
+#include <dcopclient.h>
+#include <dcopref.h>
#include "x11helper.h"
#include "kxkb.h"
@@ -59,35 +65,38 @@ DESCRIPTION
KXKBApp::KXKBApp(bool allowStyles, bool GUIenabled)
- : KUniqueApplication(allowStyles, GUIenabled),
+ : TDEUniqueApplication(allowStyles, GUIenabled),
m_prevWinId(X11Helper::UNKNOWN_WINDOW_ID),
- m_rules(NULL),
- m_tray(NULL),
- kWinModule(NULL)
+ m_rules(nullptr),
+ m_tray(nullptr),
+ kWinModule(nullptr)
{
- m_extension = new XKBExtension();
- if( !m_extension->init() ) {
- kdDebug() << "xkb initialization failed, exiting..." << endl;
- ::exit(1);
- }
- connect(m_extension, TQT_SIGNAL(groupChanged(uint)), this, TQT_SLOT(slotGroupChanged(uint)));
+ X11Helper::initializeTranslations();
+ XKBExtension *xkb = XKBExtension::the();
+ connect(xkb, TQ_SIGNAL(groupChanged(uint)), this, TQ_SLOT(slotGroupChanged(uint)));
+ connect(xkb, TQ_SIGNAL(optionsChanged()), this, TQ_SLOT(slotSyncXkbOptions()));
m_layoutOwnerMap = new LayoutMap(kxkbConfig);
// keep in sync with kcmlayout.cpp
- keys = new TDEGlobalAccel(TQT_TQOBJECT(this));
+ keys = new TDEGlobalAccel(this);
#include "kxkbbindings.cpp"
- connect( this, TQT_SIGNAL(settingsChanged(int)), TQT_SLOT(slotSettingsChanged(int)) );
+ connect( this, TQ_SIGNAL(settingsChanged(int)), TQ_SLOT(slotSettingsChanged(int)) );
addKipcEventMask( KIPC::SettingsChanged );
-}
+#if WITH_TDEHWLIB
+ TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices();
+ connect(hwdevices, TQ_SIGNAL(hardwareAdded(TDEGenericDevice*)), this, TQ_SLOT(hardwareChanged(TDEGenericDevice*)));
+ connect(hwdevices, TQ_SIGNAL(hardwareRemoved(TDEGenericDevice*)), this, TQ_SLOT(hardwareChanged(TDEGenericDevice*)));
+ connect(hwdevices, TQ_SIGNAL(hardwareUpdated(TDEGenericDevice*)), this, TQ_SLOT(hardwareChanged(TDEGenericDevice*)));
+#endif
+}
KXKBApp::~KXKBApp()
{
delete m_tray;
delete m_rules;
- delete m_extension;
delete m_layoutOwnerMap;
delete kWinModule;
delete keys;
@@ -95,193 +104,298 @@ KXKBApp::~KXKBApp()
int KXKBApp::newInstance()
{
- if (settingsRead()) {
- layoutApply();
- }
-
+ readSettings();
return 0;
}
-bool KXKBApp::settingsRead()
+void KXKBApp::readSettings()
{
- XkbOptions options = kxkbConfig.getKXkbOptions();
- if( !m_extension->setXkbOptions(options) ) {
- kdDebug() << "Setting XKB options failed!" << endl;
- }
+ // Xkb options
+ kxkbConfig.load(KxkbConfig::LOAD_INIT_OPTIONS);
- if ( kxkbConfig.m_useKxkb == false ) {
- kapp->quit();
- return false;
+ if (!kxkbConfig.m_useKxkb)
+ {
+ kdDebug() << "kxkb is disabled, applying xkb options and exiting" << endl;
+ applyXkbOptions();
+ quit();
+ return;
}
-
- m_prevWinId = X11Helper::UNKNOWN_WINDOW_ID;
-
- if( kxkbConfig.m_switchingPolicy == SWITCH_POLICY_GLOBAL ) {
- delete kWinModule;
- kWinModule = NULL;
- }
- else {
- TQDesktopWidget desktopWidget;
- if( desktopWidget.numScreens() > 1 && desktopWidget.isVirtualDesktop() == false ) {
- kdWarning() << "With non-virtual desktop only global switching policy supported on non-primary screens" << endl;
- //TODO: find out how to handle that
- }
-
- if( kWinModule == NULL ) {
- kWinModule = new KWinModule(0, KWinModule::INFO_DESKTOP);
- connect(kWinModule, TQT_SIGNAL(activeWindowChanged(WId)), TQT_SLOT(windowChanged(WId)));
- }
- m_prevWinId = kWinModule->activeWindow();
- kdDebug() << "Active window " << m_prevWinId << endl;
- }
-
- m_layoutOwnerMap->reset();
- m_layoutOwnerMap->setCurrentWindow( m_prevWinId );
-
- if( m_rules == NULL )
- m_rules = new XkbRules(false);
-
- for(int ii=0; ii<(int)kxkbConfig.m_layouts.count(); ii++) {
- LayoutUnit& layoutUnit = kxkbConfig.m_layouts[ii];
- }
-
- m_currentLayout = kxkbConfig.m_layouts[0];
- kdDebug() << "default layout is " << m_currentLayout.toPair() << endl;
-
- if( kxkbConfig.m_layouts.count() == 1 && !kxkbConfig.m_showSingle) {
- kapp->quit();
- return false;
- }
-
- initTray();
-
- TDEGlobal::config()->reparseConfiguration(); // kcontrol modified kdeglobals
- keys->readSettings();
- keys->updateConnections();
-
- return true;
+
+ kdDebug() << "applying xkb options and layouts" << endl;
+ kxkbConfig.load(KxkbConfig::LOAD_ALL_OPTIONS);
+ applyXkbOptions();
+
+ // Active window watcher
+ m_prevWinId = X11Helper::UNKNOWN_WINDOW_ID;
+
+ if (kxkbConfig.m_switchingPolicy == SWITCH_POLICY_GLOBAL)
+ {
+ delete kWinModule;
+ kWinModule = nullptr;
+ }
+
+ else
+ {
+ TQDesktopWidget desktopWidget;
+ if (desktopWidget.numScreens() > 1 && !desktopWidget.isVirtualDesktop())
+ {
+ kdWarning() << "With non-virtual desktop only global switching policy supported on non-primary screens" << endl;
+ //TODO: find out how to handle that
+ }
+
+ if (!kWinModule)
+ {
+ kWinModule = new KWinModule(nullptr, KWinModule::INFO_DESKTOP);
+ connect(kWinModule, TQ_SIGNAL(activeWindowChanged(WId)), TQ_SLOT(windowChanged(WId)));
+ }
+
+ m_prevWinId = kWinModule->activeWindow();
+ kdDebug() << "Active window " << m_prevWinId << endl;
+ }
+
+ // Init layout owner map
+ m_layoutOwnerMap->reset();
+ m_layoutOwnerMap->setCurrentWindow( m_prevWinId );
+
+ // Init rules
+ if (!m_rules)
+ {
+ m_rules = new XkbRules(false);
+ }
+
+ // Init layouts
+ for (int i = 0; i < kxkbConfig.m_layouts.count(); i++)
+ {
+ LayoutUnit& layoutUnit = kxkbConfig.m_layouts[i];
+ }
+
+ m_currentLayout = kxkbConfig.m_layouts[0];
+ setLayout(m_currentLayout);
+
+ kdDebug() << "default layout is " << m_currentLayout.toPair() << endl;
+
+ if (kxkbConfig.m_layouts.count() == 1 && !kxkbConfig.m_showSingle)
+ {
+ quit();
+ return;
+ }
+
+ TDEGlobal::config()->reparseConfiguration(); // kcontrol modified kdeglobals
+
+ // Init tray
+ if (!m_tray)
+ {
+ m_tray = new KxkbSystemTray(&kxkbConfig);
+ connect(m_tray, TQ_SIGNAL(menuActivated(int)), this, TQ_SLOT(menuActivated(int)));
+ connect(m_tray, TQ_SIGNAL(toggled()), this, TQ_SLOT(nextLayout()));
+ }
+
+ m_tray->initLayoutList(kxkbConfig.m_layouts, *m_rules);
+ m_tray->setCurrentLayout(m_currentLayout);
+ m_tray->show();
+
+ // Init keybindings
+ keys->readSettings();
+ keys->updateConnections();
}
-void KXKBApp::initTray()
+void KXKBApp::applyXkbOptions()
{
- if( !m_tray )
- {
- KSystemTray* sysTray = new KxkbSystemTray();
- TDEPopupMenu* popupMenu = sysTray->contextMenu();
- // popupMenu->insertTitle( kapp->miniIcon(), kapp->caption() );
-
- m_tray = new KxkbLabelController(sysTray, popupMenu);
- connect(popupMenu, TQT_SIGNAL(activated(int)), this, TQT_SLOT(menuActivated(int)));
- connect(sysTray, TQT_SIGNAL(toggled()), this, TQT_SLOT(nextLayout()));
- }
-
- m_tray->setShowFlag(kxkbConfig.m_showFlag);
- m_tray->initLayoutList(kxkbConfig.m_layouts, *m_rules);
- m_tray->setCurrentLayout(m_currentLayout);
- m_tray->show();
+ XkbOptions options = kxkbConfig.getKXkbOptions();
+ if (!XKBExtension::the()->setXkbOptions(options)) {
+ kdWarning() << "Setting XKB options failed!" << endl;
+ }
}
-// This function activates the keyboard layout specified by the
-// configuration members (m_currentLayout)
-void KXKBApp::layoutApply()
+void KXKBApp::hardwareChanged(TDEGenericDevice *dev)
{
- setLayout(m_currentLayout);
+# if WITH_TDEHWLIB
+ if (dev->type() == TDEGenericDeviceType::Keyboard)
+ {
+ TQTimer::singleShot(500, this, TQ_SLOT(applyXkbOptions()));
+ }
+# endif
}
// kdcop
bool KXKBApp::setLayout(const TQString& layoutPair)
{
- const LayoutUnit layoutUnitKey(layoutPair);
- if( kxkbConfig.m_layouts.contains(layoutUnitKey) ) {
- return setLayout( *kxkbConfig.m_layouts.find(layoutUnitKey) );
- }
- return false;
+ return setLayout((LayoutUnit)layoutPair);
}
// Activates the keyboard layout specified by 'layoutUnit'
bool KXKBApp::setLayout(const LayoutUnit& layoutUnit)
{
- uint group = kxkbConfig.m_layouts.findIndex(layoutUnit);
- bool res = m_extension->setGroup(group);
- if (res) {
- m_currentLayout = layoutUnit;
- }
-
- if (m_tray) {
- if (res) {
- m_tray->setCurrentLayout(layoutUnit);
- } else {
- m_tray->setError(layoutUnit.toPair());
- }
- }
-
- return res;
+ const int group = kxkbConfig.m_layouts.findIndex(layoutUnit);
+ if (group >= 0) {
+ return setLayout(group);
+ }
+ return false;
}
+
// Activates the keyboard layout specified by group number
bool KXKBApp::setLayout(const uint group)
{
- bool res = m_extension->setGroup(group);
- if (res) {
- m_currentLayout = kxkbConfig.m_layouts[group];
- }
+ // If this group is already set, just show the notification and return
+ if (XKBExtension::the()->getGroup() == group) {
+ if (kxkbConfig.m_enableNotify) {
+ showLayoutNotification();
+ }
+ return true;
+ }
- if (m_tray) {
- if (res)
- m_tray->setCurrentLayout(m_currentLayout);
- else
- m_tray->setError(m_currentLayout.toPair());
- }
+ bool ok = XKBExtension::the()->setGroup(group);
+ if (!ok) {
+ TQString layout = kxkbConfig.m_layouts[group].toPair();
+ if (m_tray) {
+ m_tray->setError(layout);
+ }
- return res;
+ if (kxkbConfig.m_enableNotify) {
+ showErrorNotification(layout);
+ }
+ }
+ return ok;
}
-
void KXKBApp::nextLayout()
{
- const LayoutUnit& layout = m_layoutOwnerMap->getNextLayout().layoutUnit;
- setLayout(layout);
+ const LayoutUnit& layout = m_layoutOwnerMap->getNextLayout().layoutUnit;
+ setLayout(layout);
}
void KXKBApp::prevLayout()
{
- const LayoutUnit& layout = m_layoutOwnerMap->getPrevLayout().layoutUnit;
- setLayout(layout);
+ const LayoutUnit& layout = m_layoutOwnerMap->getPrevLayout().layoutUnit;
+ setLayout(layout);
}
-
void KXKBApp::menuActivated(int id)
{
- if( KxkbLabelController::START_MENU_ID <= id
- && id < KxkbLabelController::START_MENU_ID + (int)kxkbConfig.m_layouts.count() )
- {
- const LayoutUnit& layout = kxkbConfig.m_layouts[id - KxkbLabelController::START_MENU_ID];
- m_layoutOwnerMap->setCurrentLayout( layout );
- setLayout( layout );
- }
- else if (id == KxkbLabelController::CONFIG_MENU_ID)
+ if (id >= KxkbSystemTray::START_MENU_ID &&
+ id < KxkbSystemTray::START_MENU_ID + kxkbConfig.m_layouts.count())
+ {
+ setLayout(id - KxkbSystemTray::START_MENU_ID);
+ }
+ else if (id == KxkbSystemTray::CONFIG_MENU_ID)
{
TDEProcess p;
p << "tdecmshell" << "keyboard_layout";
p.start(TDEProcess::DontCare);
- }
- else if (id == KxkbLabelController::HELP_MENU_ID)
- {
- TDEApplication::kApplication()->invokeHelp(0, "kxkb");
- }
-// else
-// {
-// quit();
-// }
+ }
+ else if (id == KxkbSystemTray::HELP_MENU_ID)
+ {
+ invokeHelp(0, "kxkb");
+ }
+ else
+ {
+ quit();
+ }
}
void KXKBApp::slotGroupChanged(uint group)
{
- if (group >= kxkbConfig.m_layouts.count())
+ if (!kxkbConfig.m_layouts.count()) {
+ kdError() << "[kxkb] no layout found!" << endl;
+ return;
+ }
+
+ if (group >= kxkbConfig.m_layouts.count()) {
+ kdError() << "[kxkb] unknown group requested: " << group << endl;
+ if (m_tray)
+ {
+ m_tray->setError(i18n("Unknown"));
+ }
+ if (kxkbConfig.m_enableNotify)
+ {
+ showErrorNotification(i18n("Unknown"));
+ }
+ return;
+ }
+
+ m_currentLayout = kxkbConfig.m_layouts[group];
+ m_layoutOwnerMap->setCurrentLayout(m_currentLayout);
+
+ if (m_tray) {
+ m_tray->setCurrentLayout(m_currentLayout);
+ }
+
+ if (kxkbConfig.m_enableNotify) {
+ showLayoutNotification();
+ }
+}
+
+void KXKBApp::slotSyncXkbOptions()
+{
+ // Make sure the X11 server has had enough time to apply the change
+ TQTimer::singleShot(100, this, TQ_SLOT(syncXkbOptions()));
+}
+
+void KXKBApp::syncXkbOptions()
+{
+ XkbOptions options = XKBExtension::the()->getServerOptions();
+ if (kxkbConfig.setFromXkbOptions(options))
{
- group = 0;
+ m_layoutOwnerMap->reset();
+ if (m_tray)
+ {
+ m_tray->initLayoutList(kxkbConfig.m_layouts, *m_rules);
+ }
}
- m_currentLayout = kxkbConfig.m_layouts[group];
- m_tray->setCurrentLayout(m_currentLayout);
+ slotGroupChanged(XKBExtension::the()->getGroup());
+}
+
+void KXKBApp::showLayoutNotification()
+{
+ bool useKMilo = kxkbConfig.m_notifyUseKMilo && isKMiloAvailable(),
+ notificationSent = false;
+
+ TQString layoutName(m_rules->getLayoutName(m_currentLayout));
+
+ if (useKMilo) {
+ DCOPRef kmilo("kded", "kmilod");
+ if (kmilo.send("displayText(TQString,TQPixmap)", layoutName, miniIcon())) {
+ notificationSent = true;
+ }
+ }
+
+ if (!notificationSent) {
+ WId wid = (m_tray ? m_tray->winId() : 0);
+ KNotifyClient::event(wid, "LayoutChange", layoutName);
+ }
+}
+
+void KXKBApp::showErrorNotification(TQString layout) {
+ bool useKMilo = kxkbConfig.m_notifyUseKMilo && isKMiloAvailable(),
+ notificationSent = false;
+
+ if (useKMilo) {
+ DCOPRef kmilo("kded", "kmilod");
+ if (kmilo.send("displayText(TQString,TQPixmap)", i18n("Error changing keyboard layout to '%1'").arg(layout), miniIcon())) {
+ notificationSent = true;
+ }
+ }
+
+ if (!notificationSent) {
+ WId wid = (m_tray ? m_tray->winId() : 0);
+ KNotifyClient::event(wid, "Error");
+ }
+}
+
+bool KXKBApp::isKMiloAvailable() {
+ QCStringList modules;
+ TQCString replyType;
+ TQByteArray replyData;
+ if (dcopClient()->call("kded", "kded", "loadedModules()",
+ TQByteArray(), replyType, replyData))
+ {
+ if (replyType == "QCStringList") {
+ TQDataStream reply(replyData, IO_ReadOnly);
+ reply >> modules;
+ return modules.contains("kmilod");
+ }
+ }
+ return false;
}
// TODO: we also have to handle deleted windows
@@ -294,18 +408,18 @@ void KXKBApp::windowChanged(WId winId)
}
kdDebug() << "old WinId: " << m_prevWinId << ", new WinId: " << winId << endl;
-
+
if( m_prevWinId != X11Helper::UNKNOWN_WINDOW_ID ) { // saving layout from previous window
// m_layoutOwnerMap->setCurrentWindow(m_prevWinId);
m_layoutOwnerMap->setCurrentLayout(m_currentLayout);
}
-
+
m_prevWinId = winId;
if( winId != X11Helper::UNKNOWN_WINDOW_ID ) {
m_layoutOwnerMap->setCurrentWindow(winId);
const LayoutState& layoutState = m_layoutOwnerMap->getCurrentLayout();
-
+
if( layoutState.layoutUnit != m_currentLayout ) {
kdDebug() << "switching to " << layoutState.layoutUnit.toPair() << " for " << winId << endl;
setLayout(layoutState.layoutUnit);
@@ -313,7 +427,6 @@ void KXKBApp::windowChanged(WId winId)
}
}
-
void KXKBApp::slotSettingsChanged(int category)
{
if (category == TDEApplication::SETTINGS_SHORTCUTS) {
@@ -325,13 +438,13 @@ void KXKBApp::slotSettingsChanged(int category)
bool KXKBApp::x11EventFilter(XEvent *e) {
// let the extension process the event and emit signals if necessary
- m_extension->processXEvent(e);
+ XKBExtension::the()->processXEvent(e);
return TDEApplication::x11EventFilter(e);
}
const char *DESCRIPTION = I18N_NOOP("A utility to switch keyboard maps");
-extern "C" KDE_EXPORT int kdemain(int argc, char *argv[])
+extern "C" TDE_EXPORT int kdemain(int argc, char *argv[])
{
TDEAboutData about("kxkb", I18N_NOOP("TDE Keyboard Tool"), "1.0",
DESCRIPTION, TDEAboutData::License_LGPL,
diff --git a/kxkb/kxkb.h b/kxkb/kxkb.h
index 67e61ab56..803057f61 100644
--- a/kxkb/kxkb.h
+++ b/kxkb/kxkb.h
@@ -31,7 +31,12 @@ DESCRIPTION
#include <tqdict.h>
#include <tqptrqueue.h>
-#include <kuniqueapplication.h>
+#include <tdeuniqueapplication.h>
+#ifdef WITH_TDEHWLIB
+#include <tdegenericdevice.h>
+#else
+#define TDEGenericDevice void
+#endif
#include "kxkbtraywindow.h"
#include "kxkbconfig.h"
@@ -47,7 +52,7 @@ class LayoutMap;
and switching layouts
*/
-class KXKBApp : public KUniqueApplication
+class KXKBApp : public TDEUniqueApplication
{
TQ_OBJECT
K_DCOP
@@ -72,18 +77,23 @@ public slots:
protected slots:
void menuActivated(int id);
void windowChanged(WId winId);
- void layoutApply();
void slotGroupChanged(uint group);
void slotSettingsChanged(int category);
+ void showLayoutNotification();
+ void showErrorNotification(TQString layout);
+
+ void hardwareChanged(TDEGenericDevice *dev);
-protected:
- // Read settings, and apply them.
- bool settingsRead();
+ void readSettings();
+ void applyXkbOptions();
+ void slotSyncXkbOptions();
+ void syncXkbOptions();
private:
void initTray();
bool x11EventFilter(XEvent *e);
+ bool isKMiloAvailable();
private:
KxkbConfig kxkbConfig;
@@ -95,7 +105,7 @@ private:
XKBExtension *m_extension;
XkbRules *m_rules;
- KxkbLabelController *m_tray;
+ KxkbSystemTray *m_tray;
TDEGlobalAccel *keys;
KWinModule* kWinModule;
bool m_forceSetXKBMap;
diff --git a/kxkb/kxkbbindings.cpp b/kxkb/kxkbbindings.cpp
index f4a0fb5c3..02da8a4ea 100644
--- a/kxkb/kxkbbindings.cpp
+++ b/kxkb/kxkbbindings.cpp
@@ -1,6 +1,6 @@
#ifndef NOSLOTS
# define DEF( name, key3, key4, fnSlot ) \
- keys->insert( name, i18n(name), TQString(), key3, key4, TQT_TQOBJECT(this), TQT_SLOT(fnSlot) )
+ keys->insert( name, i18n(name), TQString(), key3, key4, this, TQ_SLOT(fnSlot) )
#else
# define DEF( name, key3, key4, fnSlot ) \
keys->insert( name, i18n(name), TQString(), key3, key4, 0, 0 )
diff --git a/kxkb/kxkbconfig.cpp b/kxkb/kxkbconfig.cpp
index 52ba6941b..fd86f049a 100644
--- a/kxkb/kxkbconfig.cpp
+++ b/kxkb/kxkbconfig.cpp
@@ -30,108 +30,150 @@ static const char* switchModes[SWITCH_POLICY_COUNT] = {
const LayoutUnit DEFAULT_LAYOUT_UNIT = LayoutUnit("us", "");
const char* DEFAULT_MODEL = "pc104";
-bool KxkbConfig::load(int loadMode)
+void KxkbConfig::load(int loadMode)
{
+ // INITIAL OPTIONS (loaded regardless of whether KXkb is enabled)
+
TDEConfig *config = new TDEConfig("kxkbrc", true, false);
config->setGroup("Layout");
- if( loadMode == LOAD_ALL ) {
- m_resetOldOptions = config->readBoolEntry("ResetOldOptions", true);
- m_options = config->readEntry("Options", "");
- }
-
m_useKxkb = config->readBoolEntry("Use", false);
- kdDebug() << "Use kxkb " << m_useKxkb << endl;
- if( (m_useKxkb == false && loadMode == LOAD_ACTIVE_OPTIONS )
- || loadMode == LOAD_INIT_OPTIONS )
- return true;
+ m_resetOldOptions = config->readBoolEntry("ResetOldOptions", true);
+ m_options = config->readEntry("Options", "");
+
+ if (loadMode == LOAD_INIT_OPTIONS)
+ {
+ return;
+ }
+
+ // BASIC OPTIONS (passed to setxkbmap)
m_model = config->readEntry("Model", DEFAULT_MODEL);
- kdDebug() << "Model: " << m_model << endl;
+ // Layouts
TQStringList layoutList;
- if( config->hasKey("LayoutList") ) {
+ if (config->hasKey("LayoutList"))
+ {
layoutList = config->readListEntry("LayoutList");
}
- else { // old config
+ else
+ { // old config
TQString mainLayout = config->readEntry("Layout", DEFAULT_LAYOUT_UNIT.toPair());
layoutList = config->readListEntry("Additional");
layoutList.prepend(mainLayout);
}
- if( layoutList.count() == 0 )
+
+ if (layoutList.count() == 0)
+ {
layoutList.append("us");
+ }
+
+ TQStringList::ConstIterator it;
m_layouts.clear();
- for(TQStringList::ConstIterator it = layoutList.begin(); it != layoutList.end() ; ++it) {
+ for (it = layoutList.begin(); it != layoutList.end(); ++it)
+ {
m_layouts.append( LayoutUnit(*it) );
- kdDebug() << " layout " << LayoutUnit(*it).toPair() << " in list: " << m_layouts.contains( LayoutUnit(*it) ) << endl;
+ kdDebug() << " layout " << LayoutUnit(*it).toPair() << " in list: " << m_layouts.contains(LayoutUnit(*it)) << endl;
}
kdDebug() << "Found " << m_layouts.count() << " layouts" << endl;
+ // Display names
TQStringList displayNamesList = config->readListEntry("DisplayNames", ',');
- for(TQStringList::ConstIterator it = displayNamesList.begin(); it != displayNamesList.end() ; ++it) {
+ for (it = displayNamesList.begin(); it != displayNamesList.end() ; ++it)
+ {
TQStringList displayNamePair = TQStringList::split(':', *it );
- if( displayNamePair.count() == 2 ) {
- LayoutUnit layoutUnit( displayNamePair[0] );
- if( m_layouts.contains( layoutUnit ) ) {
+ if (displayNamePair.count() == 2)
+ {
+ LayoutUnit layoutUnit(displayNamePair[0]);
+ if (m_layouts.contains(layoutUnit))
+ {
m_layouts[m_layouts.findIndex(layoutUnit)].displayName = displayNamePair[1].left(3);
}
}
}
+ if (loadMode == LOAD_BASIC_OPTIONS)
+ {
+ return;
+ }
+
+ // ALL OTHER OPTIONS (of interest only to KXkb itself)
+
+ // Tray indicator
m_showSingle = config->readBoolEntry("ShowSingle", false);
+
m_showFlag = config->readBoolEntry("ShowFlag", true);
m_showLabel = config->readBoolEntry("ShowLabel", true);
+ m_fitToBox = config->readBoolEntry("FitFlagToBox", true);
+
m_useThemeColors = config->readBoolEntry("UseThemeColors", false);
m_colorBackground = config->readColorEntry("ColorBackground", new TQColor(TQt::gray));
m_bgTransparent = config->readBoolEntry("BgTransparent", false);
m_colorLabel = config->readColorEntry("ColorLabel", new TQColor(TQt::white));
+
m_labelFont = config->readFontEntry("LabelFont", new TQFont("sans", 10, TQFont::Bold));
m_labelShadow = config->readBoolEntry("LabelShadow", true);
m_colorShadow = config->readColorEntry("ColorShadow", new TQColor(TQt::black));
+ m_dimFlag = config->readBoolEntry("DimFlag", true);
+ m_bevel = config->readBoolEntry("IndicatorBevel", false);
+
+ // Switching policy
TQString layoutOwner = config->readEntry("SwitchMode", "Global");
- if( layoutOwner == "WinClass" ) {
+ if (layoutOwner == "WinClass")
+ {
m_switchingPolicy = SWITCH_POLICY_WIN_CLASS;
}
- else if( layoutOwner == "Window" ) {
+ else if (layoutOwner == "Window")
+ {
m_switchingPolicy = SWITCH_POLICY_WINDOW;
}
- else /*if( layoutOwner == "Global" )*/ {
+ else
+ {
m_switchingPolicy = SWITCH_POLICY_GLOBAL;
}
- if( m_layouts.count() < 2 && m_switchingPolicy != SWITCH_POLICY_GLOBAL ) {
+ if (m_layouts.count() < 2 && m_switchingPolicy != SWITCH_POLICY_GLOBAL)
+ {
kdWarning() << "Layout count is less than 2, using Global switching policy" << endl;
m_switchingPolicy = SWITCH_POLICY_GLOBAL;
}
kdDebug() << "Layout owner mode " << layoutOwner << endl;
+ // Sticky switching
m_stickySwitching = config->readBoolEntry("StickySwitching", false);
- m_stickySwitchingDepth = config->readEntry("StickySwitchingDepth", "2").toInt();
- if( m_stickySwitchingDepth < 2 )
+ m_stickySwitchingDepth = config->readNumEntry("StickySwitchingDepth", 2);
+ if (m_stickySwitchingDepth < 2)
+ {
m_stickySwitchingDepth = 2;
+ }
- if( m_stickySwitching == true ) {
- if( m_layouts.count() < 3 ) {
+ if (m_stickySwitching)
+ {
+ if (m_layouts.count() < 3)
+ {
kdWarning() << "Layout count is less than 3, sticky switching will be off" << endl;
m_stickySwitching = false;
}
- else
- if( (int)m_layouts.count() - 1 < m_stickySwitchingDepth ) {
+ else if (m_layouts.count() - 1 < m_stickySwitchingDepth)
+ {
kdWarning() << "Sticky switching depth is more than layout count -1, adjusting..." << endl;
m_stickySwitchingDepth = m_layouts.count() - 1;
}
}
- delete config;
+ // Notifications
+ config->setGroup("Notifications");
+ m_enableNotify = config->readBoolEntry("Enable", false);
+ m_notifyUseKMilo = config->readBoolEntry("UseKMilo", true);
- return true;
+ delete config;
}
void KxkbConfig::save()
@@ -139,55 +181,65 @@ void KxkbConfig::save()
TDEConfig *config = new TDEConfig("kxkbrc", false, false);
config->setGroup("Layout");
- config->writeEntry("Model", m_model);
+ config->writeEntry("Use", m_useKxkb);
config->writeEntry("ResetOldOptions", m_resetOldOptions);
config->writeEntry("Options", m_options );
+ config->writeEntry("Model", m_model);
+
+ // Layouts
TQStringList layoutList;
TQStringList displayNamesList;
TQValueList<LayoutUnit>::ConstIterator it;
- for(it = m_layouts.begin(); it != m_layouts.end(); ++it) {
+ for (it = m_layouts.begin(); it != m_layouts.end(); ++it) {
const LayoutUnit& layoutUnit = *it;
+ layoutList.append(layoutUnit.toPair());
- layoutList.append( layoutUnit.toPair() );
-
- TQString displayName( layoutUnit.displayName );
- kdDebug() << " displayName " << layoutUnit.toPair() << " : " << displayName << endl;
- if( displayName.isEmpty() == false && displayName != layoutUnit.layout ) {
+ // Display name
+ TQString displayName(layoutUnit.displayName);
+ if (!displayName.isEmpty() && displayName != layoutUnit.layout)
+ {
displayName = TQString("%1:%2").arg(layoutUnit.toPair(), displayName);
- displayNamesList.append( displayName );
+ displayNamesList.append(displayName);
}
}
-
config->writeEntry("LayoutList", layoutList);
- kdDebug() << "Saving Layouts: " << layoutList << endl;
-
-// if( displayNamesList.empty() == false )
- config->writeEntry("DisplayNames", displayNamesList);
-// else
-// config->deleteEntry("DisplayNames");
+ config->writeEntry("DisplayNames", displayNamesList);
- config->writeEntry("Use", m_useKxkb);
+ // Tray indicator
config->writeEntry("ShowSingle", m_showSingle);
config->writeEntry("ShowFlag", m_showFlag);
config->writeEntry("ShowLabel", m_showLabel);
+ config->writeEntry("FitFlagToBox", m_fitToBox);
+
config->writeEntry("UseThemeColors", m_useThemeColors);
config->writeEntry("ColorBackground", m_colorBackground);
config->writeEntry("BgTransparent", m_bgTransparent);
config->writeEntry("ColorLabel", m_colorLabel);
+
config->writeEntry("LabelFont", m_labelFont);
config->writeEntry("LabelShadow", m_labelShadow);
config->writeEntry("ColorShadow", m_colorShadow);
+ config->writeEntry("DimFlag", m_dimFlag);
+ config->writeEntry("IndicatorBevel", m_bevel);
+
+ // Switching policy
config->writeEntry("SwitchMode", switchModes[m_switchingPolicy]);
+ // Sticky switching
config->writeEntry("StickySwitching", m_stickySwitching);
config->writeEntry("StickySwitchingDepth", m_stickySwitchingDepth);
+ // Notifications
+ config->setGroup("Notifications");
+ config->writeEntry("Enable", m_enableNotify);
+ config->writeEntry("UseKMilo", m_notifyUseKMilo);
+
// remove old options
config->deleteEntry("Variants");
config->deleteEntry("Includes");
@@ -197,7 +249,6 @@ void KxkbConfig::save()
config->deleteEntry("Layout");
config->sync();
-
delete config;
}
@@ -214,6 +265,10 @@ void KxkbConfig::setDefaults()
m_useKxkb = false;
m_showSingle = false;
m_showFlag = true;
+ m_fitToBox = true;
+ m_dimFlag = true;
+
+ m_bevel = false;
m_switchingPolicy = SWITCH_POLICY_GLOBAL;
@@ -221,6 +276,74 @@ void KxkbConfig::setDefaults()
m_stickySwitchingDepth = 2;
}
+bool KxkbConfig::setFromXkbOptions(XkbOptions options)
+{
+ XkbOptions curOptions = getKXkbOptions();
+
+ bool modified = false;
+
+ // We need to fix the variants string if it is empty, otherwise the
+ // comparison below will often wrongly assume that the variants have
+ // changed
+ if (options.variants.isEmpty())
+ {
+ options.variants = ""; // ensure the string is empty but not null
+ for (int i = 0; i < options.layouts.contains(","); ++i)
+ {
+ options.variants += ",";
+ }
+ }
+
+ // Check if keyboard layout options have changed
+ if ((options.model != curOptions.model && !options.model.isNull()))
+ {
+ modified = true;
+ m_model = options.model;
+ }
+
+ if ((options.layouts != curOptions.layouts) || (options.variants != curOptions.variants))
+ {
+ modified = true;
+ m_layouts.clear();
+
+ TQStringList layouts = TQStringList::split(",", options.layouts, true);
+ TQStringList variants = TQStringList::split(",", options.variants, true);
+ TQStringList::Iterator lit = layouts.begin();
+ TQStringList::Iterator vit = variants.begin();
+
+ if (layouts.empty())
+ {
+ layouts << "us";
+ }
+
+ while (lit != layouts.end())
+ {
+ TQString layout = *lit;
+ TQString variant = vit != variants.end() ? *vit : TQString::null;
+ m_layouts.append(LayoutUnit(layout, variant));
+
+ ++lit;
+ if (vit != variants.end())
+ {
+ ++vit;
+ }
+ }
+ }
+
+ TQStringList serverOpts = TQStringList::split(",", options.options);
+ TQStringList kxkbOpts = TQStringList::split(",", curOptions.options);
+ serverOpts.sort();
+ kxkbOpts.sort();
+
+ if (serverOpts != kxkbOpts)
+ {
+ modified = true;
+ m_options = options.options;
+ }
+
+ return modified;
+}
+
TQStringList KxkbConfig::getLayoutStringList(/*bool compact*/)
{
TQStringList layoutList;
@@ -267,22 +390,25 @@ TQString KxkbConfig::getDefaultDisplayName(const LayoutUnit& layoutUnit, bool si
}
const XkbOptions KxkbConfig::getKXkbOptions() {
- load(LOAD_ALL);
-
XkbOptions options;
TQStringList layouts;
TQStringList variants;
- for(TQValueList<LayoutUnit>::ConstIterator it = m_layouts.begin(); it != m_layouts.end(); ++it) {
+ for (TQValueList<LayoutUnit>::ConstIterator it = m_layouts.begin(); it != m_layouts.end(); ++it) {
const LayoutUnit& layoutUnit = *it;
layouts << layoutUnit.layout;
variants << layoutUnit.variant;
}
options.layouts = layouts.join(",");
options.variants = variants.join(",");
- options.model = m_model;
options.options = m_options;
- kdDebug() << "[getKXkbOptions] options: " << m_options << endl;
options.resetOld = m_resetOldOptions;
+ options.model = m_model;
+
+ if (options.model.isEmpty())
+ {
+ options.model = DEFAULT_MODEL;
+ }
+
return options;
}
@@ -321,4 +447,4 @@ const TQString LayoutUnit::parseVariant(const TQString &layvar)
if( pos < 2 || len < 2 )
return "";
return varLine.mid(pos+1, len-2);
-} \ No newline at end of file
+}
diff --git a/kxkb/kxkbconfig.h b/kxkb/kxkbconfig.h
index 140a2b763..7d02fd3a3 100644
--- a/kxkb/kxkbconfig.h
+++ b/kxkb/kxkbconfig.h
@@ -19,6 +19,8 @@
#include <tqptrqueue.h>
#include <tqmap.h>
+#include "layoutunit.h"
+
struct XkbOptions {
TQString layouts;
TQString variants;
@@ -36,59 +38,6 @@ enum SwitchingPolicy {
SWITCH_POLICY_COUNT = 3
};
-
-
-inline TQString createPair(TQString key, TQString value)
-{
- if( value.isEmpty() )
- return key;
- return TQString("%1(%2)").arg(key, value);
-}
-
-struct LayoutUnit {
- TQString layout;
- TQString variant;
- TQString displayName;
-
- LayoutUnit() {}
-
- LayoutUnit(TQString layout_, TQString variant_):
- layout(layout_),
- variant(variant_)
- {}
-
- LayoutUnit(TQString pair) {
- setFromPair( pair );
- }
-
- void setFromPair(const TQString& pair) {
- layout = parseLayout(pair);
- variant = parseVariant(pair);
- }
-
- TQString toPair() const {
- return createPair(layout, variant);
- }
-
- bool operator<(const LayoutUnit& lu) const {
- return layout<lu.layout ||
- (layout==lu.layout && variant<lu.variant);
- }
-
- bool operator!=(const LayoutUnit& lu) const {
- return layout!=lu.layout || variant!=lu.variant;
- }
-
- bool operator==(const LayoutUnit& lu) const {
-// kdDebug() << layout << "==" << lu.layout << "&&" << variant << "==" << lu.variant << endl;
- return layout==lu.layout && variant==lu.variant;
- }
-
-//private:
- static const TQString parseLayout(const TQString &layvar);
- static const TQString parseVariant(const TQString &layvar);
-};
-
extern const LayoutUnit DEFAULT_LAYOUT_UNIT;
extern const char* DEFAULT_MODEL;
@@ -96,17 +45,22 @@ extern const char* DEFAULT_MODEL;
class KxkbConfig
{
public:
- enum { LOAD_INIT_OPTIONS, LOAD_ACTIVE_OPTIONS, LOAD_ALL };
+ enum { LOAD_INIT_OPTIONS, LOAD_BASIC_OPTIONS, LOAD_ALL_OPTIONS };
bool m_useKxkb;
bool m_showSingle;
bool m_showFlag;
bool m_showLabel;
+ bool m_fitToBox;
+ bool m_dimFlag;
+ bool m_bevel;
bool m_enableXkbOptions;
bool m_resetOldOptions;
SwitchingPolicy m_switchingPolicy;
bool m_stickySwitching;
int m_stickySwitchingDepth;
+ bool m_enableNotify;
+ bool m_notifyUseKMilo;
bool m_useThemeColors;
TQColor m_colorBackground;
@@ -120,7 +74,7 @@ public:
TQString m_options;
TQValueList<LayoutUnit> m_layouts;
- bool load(int loadMode);
+ void load(int loadMode);
void save();
void setDefaults();
@@ -128,6 +82,7 @@ public:
static TQString getDefaultDisplayName(const TQString& code_);
static TQString getDefaultDisplayName(const LayoutUnit& layoutUnit, bool single=false);
+ bool setFromXkbOptions(XkbOptions options);
const XkbOptions getKXkbOptions();
private:
diff --git a/kxkb/kxkbtraywindow.cpp b/kxkb/kxkbtraywindow.cpp
index 46b03da15..7871f443a 100644
--- a/kxkb/kxkbtraywindow.cpp
+++ b/kxkb/kxkbtraywindow.cpp
@@ -17,114 +17,101 @@
#include <kiconloader.h>
#include <tdepopupmenu.h>
#include <tdeaction.h>
-#include <kuniqueapplication.h>
#include "kxkbtraywindow.h"
#include "pixmap.h"
#include "rules.h"
-#include "kxkbconfig.h"
-
-KxkbLabelController::KxkbLabelController(TQLabel* label_, TDEPopupMenu* contextMenu_) :
- label(label_),
- contextMenu(contextMenu_),
- m_menuStartIndex(contextMenu_->count()),
- m_prevLayoutCount(0)
+KxkbSystemTray::KxkbSystemTray(KxkbConfig *kxkbConfig)
+ : KSystemTray(nullptr),
+ m_prevLayoutCount(0)
{
-// kdDebug() << "Creating KxkbLabelController with " << label_ << ", " << contextMenu_ << endl;
-// kdDebug() << "Creating KxkbLabelController with startMenuIndex " << m_menuStartIndex << endl;
+ m_icoMgr = new LayoutIconManager(kxkbConfig);
}
-void KxkbLabelController::setToolTip(const TQString& tip)
+KxkbSystemTray::~KxkbSystemTray()
{
- TQToolTip::remove(label);
- TQToolTip::add(label, tip);
+ delete m_icoMgr;
}
-void KxkbLabelController::setPixmap(const TQPixmap& pixmap)
+void KxkbSystemTray::setToolTip(const TQString& tip)
{
- TDEIconEffect iconeffect;
- label->setPixmap( iconeffect.apply(pixmap, TDEIcon::Panel, TDEIcon::DefaultState) );
+ TQToolTip::remove(this);
+ TQToolTip::add(this, tip);
}
-
-void KxkbLabelController::setCurrentLayout(const LayoutUnit& layoutUnit)
+void KxkbSystemTray::setPixmap(const TQPixmap& pix)
{
- setToolTip(m_descriptionMap[layoutUnit.toPair()]);
- setPixmap( LayoutIcon::getInstance().findPixmap(layoutUnit.layout, PIXMAP_STYLE_INDICATOR, layoutUnit.displayName) );
+ TDEIconEffect iconeffect;
+ KSystemTray::setPixmap(iconeffect.apply(pix, TDEIcon::Panel, TDEIcon::DefaultState));
}
+void KxkbSystemTray::setCurrentLayout(const LayoutUnit& layoutUnit)
+{
+ setToolTip(m_descriptionMap[layoutUnit.toPair()]);
+ setPixmap(m_icoMgr->find(layoutUnit.layout, PIXMAP_STYLE_INDICATOR, layoutUnit.displayName));
+}
-void KxkbLabelController::setError(const TQString& layoutInfo)
+void KxkbSystemTray::setError(const TQString& layoutInfo)
{
- TQString msg = i18n("Error changing keyboard layout to '%1'").arg(layoutInfo);
- setToolTip(msg);
+ TQString layout(layoutInfo);
+ if (layout.isNull()) {
+ layout = i18n("Unknown");
+ }
- label->setPixmap(LayoutIcon::getInstance().findPixmap("error", PIXMAP_STYLE_NORMAL));
+ TQString msg = i18n("Error changing keyboard layout to '%1'").arg(layoutInfo);
+ setToolTip(msg);
+ setPixmap(m_icoMgr->find(ERROR_CODE, PIXMAP_STYLE_NORMAL));
}
-
-void KxkbLabelController::initLayoutList(const TQValueList<LayoutUnit>& layouts, const XkbRules& rules)
+void KxkbSystemTray::initLayoutList(const TQValueList<LayoutUnit>& layouts, const XkbRules& rules)
{
- TDEPopupMenu* menu = contextMenu;
-// TQPopupMenu* menu = contextMenu;
-// int index = menu->indexOf(0);
-
m_descriptionMap.clear();
-// menu->clear();
-// menu->insertTitle( kapp->miniIcon(), kapp->caption() );
- for(int ii=0; ii<m_prevLayoutCount; ++ii) {
- menu->removeItem(START_MENU_ID + ii);
- kdDebug() << "remove item: " << START_MENU_ID + ii << endl;
- }
-/* menu->removeItem(CONFIG_MENU_ID);
- menu->removeItem(HELP_MENU_ID);*/
+ int i;
+ for (i = 0; i < m_prevLayoutCount; ++i) {
+ contextMenu()->removeItem(START_MENU_ID + i);
+ }
TDEIconEffect iconeffect;
- int cnt = 0;
+ i = 0;
TQValueList<LayoutUnit>::ConstIterator it;
- for (it=layouts.begin(); it != layouts.end(); ++it)
+ for (it = layouts.begin(); it != layouts.end(); ++it)
{
- const TQString layoutName = (*it).layout;
- const TQString variantName = (*it).variant;
+ const TQString layoutName = (*it).layout;
+ const TQString variantName = (*it).variant;
- const TQPixmap& layoutPixmap = LayoutIcon::getInstance().findPixmap(layoutName, PIXMAP_STYLE_CONTEXTMENU, (*it).displayName);
+ const TQPixmap& layoutPixmap = m_icoMgr->find((*it).layout, PIXMAP_STYLE_CONTEXTMENU, (*it).displayName);
const TQPixmap pix = iconeffect.apply(layoutPixmap, TDEIcon::Small, TDEIcon::DefaultState);
- TQString fullName = i18n((rules.layouts()[layoutName]));
- if( variantName.isEmpty() == false )
- fullName += " (" + variantName + ")";
- contextMenu->insertItem(pix, fullName, START_MENU_ID + cnt, m_menuStartIndex + cnt);
- m_descriptionMap.insert((*it).toPair(), fullName);
+ TQString fullName = rules.getLayoutName((*it));
+ contextMenu()->insertItem(pix, fullName, START_MENU_ID + i, i + 1);
+
+ m_descriptionMap.insert((*it).toPair(), fullName);
- cnt++;
+ ++i;
}
- m_prevLayoutCount = cnt;
-
- // if show config, if show help
- if( menu->indexOf(CONFIG_MENU_ID) == -1 ) {
- contextMenu->insertSeparator();
- contextMenu->insertItem(SmallIcon("configure"), i18n("Configure..."), CONFIG_MENU_ID);
- if( menu->indexOf(HELP_MENU_ID) == -1 )
- contextMenu->insertItem(SmallIcon("help"), i18n("Help"), HELP_MENU_ID);
- }
-
-/* if( index != -1 ) { //not first start
- menu->insertSeparator();
- TDEAction* quitAction = KStdAction::quit(this, TQT_SIGNAL(quitSelected()), actionCollection());
- if (quitAction)
- quitAction->plug(menu);
- }*/
+ m_prevLayoutCount = i;
+
+ if (contextMenu()->indexOf(CONFIG_MENU_ID) == -1) {
+ contextMenu()->insertSeparator();
+ contextMenu()->insertItem(SmallIcon("configure"), i18n("Configure..."), CONFIG_MENU_ID);
+
+ if (contextMenu()->indexOf(HELP_MENU_ID) == -1) {
+ contextMenu()->insertItem(SmallIcon("help"), i18n("Help"), HELP_MENU_ID);
+ }
+ }
+
+ connect(contextMenu(), TQ_SIGNAL(activated(int)), this, TQ_SIGNAL(menuActivated(int)));
}
-// void KxkbLabelController::mouseReleaseEvent(TQMouseEvent *ev)
-// {
-// if (ev->button() == TQMouseEvent::LeftButton)
-// emit toggled();
-// KSystemTray::mouseReleaseEvent(ev);
-// }
+void KxkbSystemTray::mouseReleaseEvent(TQMouseEvent *ev) {
+ if (ev->button() == TQt::LeftButton) {
+ emit toggled();
+ }
+ KSystemTray::mouseReleaseEvent(ev);
+}
#include "kxkbtraywindow.moc"
diff --git a/kxkb/kxkbtraywindow.h b/kxkb/kxkbtraywindow.h
index eb6a426a2..3e1ae2c05 100644
--- a/kxkb/kxkbtraywindow.h
+++ b/kxkb/kxkbtraywindow.h
@@ -1,7 +1,7 @@
//
// C++ Interface: kxkbtraywindow
//
-// Description:
+// Description:
//
//
// Author: Andriy Rysin <rysin@kde.org>, (C) 2006
@@ -17,75 +17,40 @@
#include <tqstring.h>
#include <tqvaluelist.h>
-#include "kxkbconfig.h"
+#include "layoutunit.h"
-
-class TQLabel;
-class TDEPopupMenu;
class XkbRules;
+class KxkbConfig;
+class LayoutIconManager;
-/* This class is responsible for displaying flag/label for the layout,
- catching keyboard/mouse events and displaying menu when selected
-*/
-
-class KxkbLabelController: public QObject
+class KxkbSystemTray : public KSystemTray
{
-// TQ_OBJECT
-
-public:
- enum { START_MENU_ID = 100, CONFIG_MENU_ID = 130, HELP_MENU_ID = 131 };
+ TQ_OBJECT
- KxkbLabelController(TQLabel *label, TDEPopupMenu* contextMenu);
+ public:
+ KxkbSystemTray(KxkbConfig *kxkbConfig);
+ ~KxkbSystemTray();
+ void initLayoutList(const TQValueList<LayoutUnit>& layouts, const XkbRules& rule);
+ void setCurrentLayout(const LayoutUnit& layout);
+ void setError(const TQString& layoutInfo = TQString::null);
- void initLayoutList(const TQValueList<LayoutUnit>& layouts, const XkbRules& rule);
- void setCurrentLayout(const LayoutUnit& layout);
-// void setCurrentLayout(const TQString& layout, const TQString &variant);
- void setError(const TQString& layoutInfo="");
- void setShowFlag(bool showFlag) { m_showFlag = showFlag; }
- void show() { label->show(); }
-
-// signals:
-//
-// void menuActivated(int);
-// void toggled();
+ enum { START_MENU_ID = 100, CONFIG_MENU_ID = 130, HELP_MENU_ID = 131 };
-// protected:
-//
-// void mouseReleaseEvent(TQMouseEvent *);
+ protected:
+ void mouseReleaseEvent(TQMouseEvent *ev);
-private:
- TQLabel* label;
- TDEPopupMenu* contextMenu;
-
- const int m_menuStartIndex;
- bool m_showFlag;
- int m_prevLayoutCount;
- TQMap<TQString, TQString> m_descriptionMap;
-
- void setToolTip(const TQString& tip);
- void setPixmap(const TQPixmap& pixmap);
-};
+ private slots:
+ void setToolTip(const TQString& tip);
+ void setPixmap(const TQPixmap& pix);
+ signals:
+ void menuActivated(int);
+ void toggled();
-class KxkbSystemTray : public KSystemTray
-{
- TQ_OBJECT
-
- public:
- KxkbSystemTray():
- KSystemTray(NULL)
- {}
-
- void mouseReleaseEvent(TQMouseEvent *ev)
- {
- if (ev->button() == Qt::LeftButton)
- emit toggled();
- KSystemTray::mouseReleaseEvent(ev);
- }
-
- signals:
- void menuActivated(int);
- void toggled();
+ private:
+ LayoutIconManager *m_icoMgr;
+ int m_prevLayoutCount;
+ TQMap<TQString, TQString> m_descriptionMap;
};
diff --git a/kxkb/layoutunit.h b/kxkb/layoutunit.h
new file mode 100644
index 000000000..f4d82f73f
--- /dev/null
+++ b/kxkb/layoutunit.h
@@ -0,0 +1,64 @@
+//
+//
+// Author: Andriy Rysin <rysin@kde.org>, (C) 2006
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef _LAYOUTUNIT_H
+#define _LAYOUTUNIT_H
+
+#include <tqstring.h>
+
+inline TQString createPair(TQString key, TQString value)
+{
+ if (value.isEmpty()) return key;
+ return TQString("%1(%2)").arg(key, value);
+}
+
+struct LayoutUnit {
+ TQString layout;
+ TQString variant;
+ TQString displayName;
+
+ LayoutUnit() {}
+
+ LayoutUnit(TQString layout_, TQString variant_):
+ layout(layout_),
+ variant(variant_)
+ {}
+
+ LayoutUnit(TQString pair) {
+ setFromPair( pair );
+ }
+
+ void setFromPair(const TQString& pair) {
+ layout = parseLayout(pair);
+ variant = parseVariant(pair);
+ }
+
+ TQString toPair() const {
+ return createPair(layout, variant);
+ }
+
+ bool operator<(const LayoutUnit& lu) const {
+ return layout<lu.layout ||
+ (layout==lu.layout && variant<lu.variant);
+ }
+
+ bool operator!=(const LayoutUnit& lu) const {
+ return layout!=lu.layout || variant!=lu.variant;
+ }
+
+ bool operator==(const LayoutUnit& lu) const {
+// kdDebug() << layout << "==" << lu.layout << "&&" << variant << "==" << lu.variant << endl;
+ return layout==lu.layout && variant==lu.variant;
+ }
+
+//private:
+ static const TQString parseLayout(const TQString &layvar);
+ static const TQString parseVariant(const TQString &layvar);
+};
+
+#endif // _LAYOUTUNIT_H \ No newline at end of file
diff --git a/kxkb/pixmap.cpp b/kxkb/pixmap.cpp
index c7e08a741..01866e71e 100644
--- a/kxkb/pixmap.cpp
+++ b/kxkb/pixmap.cpp
@@ -1,11 +1,13 @@
+#include <tqapplication.h>
#include <tqimage.h>
#include <tqbitmap.h>
#include <tqfont.h>
#include <tqpainter.h>
#include <tqregexp.h>
#include <tqdict.h>
+#include <tqdrawutil.h>
-#include <kstandarddirs.h>
+#include <tdestandarddirs.h>
#include <tdeglobalsettings.h>
#include <tdelocale.h>
#include <kdebug.h>
@@ -13,56 +15,42 @@
#include "pixmap.h"
#include "x11helper.h"
+const TQString LayoutIconManager::flagTemplate("l10n/%1/flag.png");
-static const int FLAG_MAX_DIM = 24;
-
-const TQString LayoutIcon::flagTemplate("l10n/%1/flag.png");
-const TQString& LayoutIcon::ERROR_CODE("error");
-LayoutIcon* LayoutIcon::instance;
-
-
-LayoutIcon& LayoutIcon::getInstance() {
- if( instance == NULL ) {
- instance = new LayoutIcon();
- }
- return *instance;
-}
-
-LayoutIcon::LayoutIcon():
- m_pixmapCache(80)
+LayoutIconManager::LayoutIconManager(KxkbConfig *kxkbConfig)
+ : m_pixmapCache(80),
+ m_kxkbConfig(kxkbConfig)
{
}
-const TQPixmap&
-LayoutIcon::findPixmap(const TQString& code_, int pixmapStyle, const TQString& displayName_)
+const TQPixmap& LayoutIconManager::find(const TQString& code_, int pixmapStyle, const TQString& displayName_)
{
- m_kxkbConfig.load(KxkbConfig::LOAD_ALL); // (re)load settings
-
- if (m_kxkbConfig.m_useThemeColors) { // use colors from color scheme
+ if (m_kxkbConfig->m_useThemeColors) { // use colors from color scheme
m_bgColor = TDEGlobalSettings::highlightColor();
m_fgColor = TDEGlobalSettings::highlightedTextColor();
} else {
- m_bgColor = m_kxkbConfig.m_colorBackground;
- m_fgColor = m_kxkbConfig.m_colorLabel;
+ m_bgColor = m_kxkbConfig->m_colorBackground;
+ m_fgColor = m_kxkbConfig->m_colorLabel;
}
- m_labelFont = m_kxkbConfig.m_labelFont;
- m_labelShadow = m_kxkbConfig.m_labelShadow;
- m_shColor = m_kxkbConfig.m_colorShadow;
- m_bgTransparent = m_kxkbConfig.m_bgTransparent;
+ m_labelFont = m_kxkbConfig->m_labelFont;
+ m_labelShadow = m_kxkbConfig->m_labelShadow;
+ m_shColor = m_kxkbConfig->m_colorShadow;
+ m_bgTransparent = m_kxkbConfig->m_bgTransparent;
+ m_fitToBox = m_kxkbConfig->m_fitToBox;
+ m_dimFlag = m_kxkbConfig->m_dimFlag;
+ m_bevel = m_kxkbConfig->m_bevel && !m_bgTransparent && pixmapStyle == PIXMAP_STYLE_INDICATOR;
// Decide on how to style the pixmap
switch(pixmapStyle) {
case PIXMAP_STYLE_NORMAL:
- m_fitToBox = true;
m_showFlag = true;
m_showLabel = false;
break;
case PIXMAP_STYLE_INDICATOR:
- m_fitToBox = true;
- m_showFlag = m_kxkbConfig.m_showFlag;
- m_showLabel = m_kxkbConfig.m_showLabel;
+ m_showFlag = m_kxkbConfig->m_showFlag;
+ m_showLabel = m_kxkbConfig->m_showLabel;
break;
case PIXMAP_STYLE_CONTEXTMENU:
@@ -73,7 +61,7 @@ LayoutIcon::findPixmap(const TQString& code_, int pixmapStyle, const TQString& d
}
// Label only mode is always 'fit to box'
- if( m_showLabel && !m_showFlag )
+ if (m_showLabel && !m_showFlag)
m_fitToBox = true;
TQPixmap* pm = NULL;
@@ -89,63 +77,98 @@ LayoutIcon::findPixmap(const TQString& code_, int pixmapStyle, const TQString& d
TQString displayName(displayName_);
- if( displayName.isEmpty() ) {
+ if (displayName.isEmpty()) {
displayName = KxkbConfig::getDefaultDisplayName(code_);
}
- if( displayName.length() > 3 )
+ if (displayName.length() > 3)
displayName = displayName.left(3);
const TQString pixmapKey(
- TQString( m_showFlag ? "f" : "" ) + TQString( m_showLabel ? "l" : "" ) + TQString( m_labelShadow ? "s" : "" ) + "." +
+ TQString(m_showFlag ? "f" : "") + TQString(m_showLabel ? "l" : "") + TQString(m_labelShadow ? "s" : "") + "." +
+ TQString(m_fitToBox ? "F" : "") + TQString(m_dimFlag ? "D" : "") + TQString(m_bevel ? "B" : "") + "." +
m_labelFont.key() + "." + ( m_bgTransparent ? "x" : m_bgColor.name() ) + "." + m_fgColor.name() + "." + m_shColor.name() + '.' + code_ + "." + displayName
);
// Only use cache for indicator
- if( pixmapStyle == PIXMAP_STYLE_INDICATOR ) {
+ if (pixmapStyle == PIXMAP_STYLE_INDICATOR) {
pm = m_pixmapCache[pixmapKey];
- if( pm )
+ if (pm)
return *pm;
}
- // Need to create new pixmap
- pm = new TQPixmap();
+ pm = new TQPixmap(FLAG_MAX_DIM, FLAG_MAX_DIM);
- if( m_fitToBox ) // Resize to box size
- pm->resize(FLAG_MAX_DIM, FLAG_MAX_DIM);
+ TQRect r = pm->rect();
+ TQPainter p_(pm);
- if( m_showFlag ) {
- TQString countryCode = getCountryFromLayoutName( code_ );
+ if (m_showFlag) {
+ TQString countryCode = getCountryFromLayoutName(code_);
TQString flag = locate("locale", flagTemplate.arg(countryCode));
- if( flag.isEmpty() ) {
+ if (flag.isEmpty()) {
pm->fill(m_bgColor);
m_showLabel = true;
} else {
- if( m_fitToBox ) { // Resize flag
- TQPainter p_(pm);
- p_.drawPixmap(TQRect(0, 0, FLAG_MAX_DIM, FLAG_MAX_DIM), flag);
- } else { // Show the flag as is
- pm->load(flag);
+ TQPixmap fp(flag);
+
+ if (m_dimFlag && m_showLabel)
+ {
+ TQImage image = fp.convertToImage();
+ for (int y = 0; y < image.height(); y++)
+ {
+ for(int x = 0; x < image.width(); x++)
+ {
+ TQRgb rgb = image.pixel(x,y);
+ TQRgb dimRgb(tqRgb(tqRed(rgb) * 3/4, tqGreen(rgb) * 3/4, tqBlue(rgb) * 3/4));
+ image.setPixel(x, y, dimRgb);
+ }
+ }
+ fp.convertFromImage(image);
+ }
+
+ if (!m_fitToBox)
+ {
+ r = TQRect((FLAG_MAX_DIM - fp.width()) / 2, (FLAG_MAX_DIM - fp.height()) / 2, fp.width(), fp.height());
+ }
+
+ TQRect fr(r); // flag rect might be smaller to accomodate the bevel
+ if (m_bevel)
+ {
+ fr.setX(fr.x() + 1);
+ fr.setY(fr.y() + 1);
+ fr.setWidth(fr.width() - 1);
+ fr.setHeight(fr.height() - 1);
}
- if( m_showLabel ) // only dim for label
- dimPixmap( *pm );
+ p_.drawPixmap(fr, fp);
+
+ // If we don't stretch the flag, we need to apply a mask to it
+ if (!m_fitToBox)
+ {
+ TQPixmap fpmask(FLAG_MAX_DIM, FLAG_MAX_DIM);
+ TQPainter fpmaskp(&fpmask);
+ fpmask.fill(TQt::white);
+ fpmaskp.fillRect(r, TQt::black);
+ TQBitmap fpmask_;
+ fpmask_ = fpmask;
+ pm->setMask((TQBitmap)fpmask_);
+ }
}
} else {
pm->fill(m_bgColor);
}
- if( m_showLabel ) {
+ if (m_showLabel) {
TQPainter p(pm);
p.setFont(m_labelFont);
- if( m_labelShadow ) {
+ if (m_labelShadow) {
p.setPen(m_shColor);
- p.drawText(1, 1, pm->width(), pm->height(), Qt::AlignCenter, displayName);
+ p.drawText(1, 1, pm->width(), pm->height(), TQt::AlignCenter, displayName);
}
p.setPen(m_fgColor);
- p.drawText(0, 0, pm->width(), pm->height(), Qt::AlignCenter, displayName);
+ p.drawText(0, 0, pm->width(), pm->height(), TQt::AlignCenter, displayName);
if( m_bgTransparent && !m_showFlag )
{
@@ -156,10 +179,10 @@ LayoutIcon::findPixmap(const TQString& code_, int pixmapStyle, const TQString& d
maskp.setPen(TQt::black);
maskp.setFont(m_labelFont);
- maskp.drawText(0, 0, maskpix.width(), maskpix.height(), Qt::AlignCenter, displayName);
+ maskp.drawText(0, 0, maskpix.width(), maskpix.height(), TQt::AlignCenter, displayName);
if( m_labelShadow )
{
- maskp.drawText(1, 1, maskpix.width(), maskpix.height(), Qt::AlignCenter, displayName);
+ maskp.drawText(1, 1, maskpix.width(), maskpix.height(), TQt::AlignCenter, displayName);
}
TQBitmap mask;
@@ -168,8 +191,14 @@ LayoutIcon::findPixmap(const TQString& code_, int pixmapStyle, const TQString& d
}
}
+ if (m_bevel)
+ {
+ TQPainter p_(pm);
+ qDrawShadePanel(&p_, r.x(), r.y(), r.width(), r.height(), tqApp->palette().active(), false, 1, nullptr);
+ }
+
- if( pixmapStyle == PIXMAP_STYLE_INDICATOR )
+ if (pixmapStyle == PIXMAP_STYLE_INDICATOR)
m_pixmapCache.insert(pixmapKey, pm);
return *pm;
@@ -178,7 +207,7 @@ LayoutIcon::findPixmap(const TQString& code_, int pixmapStyle, const TQString& d
/**
@brief Try to get country code from layout name in xkb before xorg 6.9.0
*/
-TQString LayoutIcon::getCountryFromLayoutName(const TQString& layoutName)
+TQString LayoutIconManager::getCountryFromLayoutName(const TQString& layoutName)
{
TQString flag;
@@ -285,35 +314,19 @@ TQString LayoutIcon::getCountryFromLayoutName(const TQString& layoutName)
return flag;
}
-
-void LayoutIcon::dimPixmap(TQPixmap& pm)
-{
- TQImage image = pm.convertToImage();
- for (int y=0; y<image.height(); y++)
- for(int x=0; x<image.width(); x++)
- {
- QRgb rgb = image.pixel(x,y);
- QRgb dimRgb(tqRgb(tqRed(rgb)*3/4, tqGreen(rgb)*3/4, tqBlue(rgb)*3/4));
- image.setPixel(x, y, dimRgb);
- }
- pm.convertFromImage(image);
-}
-
-static const char* ERROR_LABEL = "err";
-
//private
-TQPixmap* LayoutIcon::createErrorPixmap()
+TQPixmap* LayoutIconManager::createErrorPixmap()
{
TQPixmap* pm = new TQPixmap(21, 14);
- pm->fill(Qt::white);
+ pm->fill(TQt::white);
TQPainter p(pm);
p.setFont(m_labelFont);
- p.setPen(Qt::red);
- p.drawText(1, 1, pm->width(), pm->height()-2, Qt::AlignCenter, ERROR_LABEL);
- p.setPen(Qt::blue);
- p.drawText(0, 0, pm->width(), pm->height()-2, Qt::AlignCenter, ERROR_LABEL);
+ p.setPen(TQt::red);
+ p.drawText(1, 1, pm->width(), pm->height()-2, TQt::AlignCenter, ERROR_LABEL);
+ p.setPen(TQt::blue);
+ p.drawText(0, 0, pm->width(), pm->height()-2, TQt::AlignCenter, ERROR_LABEL);
m_pixmapCache.insert(ERROR_CODE, pm);
return pm;
diff --git a/kxkb/pixmap.h b/kxkb/pixmap.h
index a17f48d89..08dee8a87 100644
--- a/kxkb/pixmap.h
+++ b/kxkb/pixmap.h
@@ -8,41 +8,34 @@
#include "kxkbconfig.h"
-enum PixmapStyle {
- PIXMAP_STYLE_NORMAL = 0,
- PIXMAP_STYLE_INDICATOR = 1,
- PIXMAP_STYLE_CONTEXTMENU = 2
-};
-
-class LayoutIcon {
+#define ERROR_CODE "error"
+#define ERROR_LABEL "!"
-private:
- static LayoutIcon* instance;
- static const TQString flagTemplate;
+#define FLAG_MAX_DIM 24
- KxkbConfig m_kxkbConfig;
- bool m_showFlag;
- bool m_showLabel;
- TQColor m_bgColor;
- bool m_bgTransparent;
- TQColor m_fgColor;
- TQFont m_labelFont;
- bool m_labelShadow;
- TQColor m_shColor;
- bool m_fitToBox;
+enum PixmapStyle {
+ PIXMAP_STYLE_NORMAL = 0,
+ PIXMAP_STYLE_INDICATOR = 1,
+ PIXMAP_STYLE_CONTEXTMENU = 2
+};
- TQDict<TQPixmap> m_pixmapCache;
+class LayoutIconManager {
+ public:
+ LayoutIconManager(KxkbConfig *kxkbConfig);
+ const TQPixmap& find(const TQString& code, int pixmapStyle, const TQString& displayName = TQString::null);
- LayoutIcon();
- TQPixmap* createErrorPixmap();
- void dimPixmap(TQPixmap& pixmap);
- TQString getCountryFromLayoutName(const TQString& layoutName);
+ private:
+ TQPixmap* createErrorPixmap();
+ TQString getCountryFromLayoutName(const TQString& layoutName);
-public:
- static const TQString& ERROR_CODE;
+ private:
+ KxkbConfig *m_kxkbConfig;
+ static const TQString flagTemplate;
+ bool m_showFlag, m_showLabel, m_bgTransparent, m_labelShadow, m_fitToBox, m_dimFlag, m_bevel;
+ TQColor m_bgColor, m_fgColor, m_shColor;
+ TQFont m_labelFont;
- static LayoutIcon& getInstance();
- const TQPixmap& findPixmap(const TQString& code, int pixmapStyle, const TQString& displayName="");
+ TQDict<TQPixmap> m_pixmapCache;
};
#endif
diff --git a/kxkb/rules.cpp b/kxkb/rules.cpp
index 37cdc9bc4..f0f4b38b2 100644
--- a/kxkb/rules.cpp
+++ b/kxkb/rules.cpp
@@ -5,7 +5,7 @@
#include <tqstringlist.h>
#include <tqdir.h>
-#include <kstandarddirs.h>
+#include <tdestandarddirs.h>
#include <tdeglobal.h>
#include <tdelocale.h>
#include <kdebug.h>
@@ -73,3 +73,17 @@ XkbRules::getAvailableVariants(const TQString& layout)
return *result;
}
+TQString XkbRules::getLayoutName(LayoutUnit layout) const {
+ TQString fullName = i18n(m_layouts[layout.layout]);
+ if (!layout.variant.isEmpty()) {
+ fullName += " (" + layout.variant + ")";
+ }
+ return fullName;
+}
+
+TQString XkbRules::trOpt(TQString opt) {
+ // xkeyboard-config's translation is generated directly from the xml and has some querks
+ // like sustitution for the '<' and '>'. We will have to workaroung those manually:
+ TQString translated = i18n(opt.replace("<", "&lt;").replace(">", "&gt;").utf8());
+ return translated.replace("&lt;", "<").replace("&gt;", ">");
+}
diff --git a/kxkb/rules.h b/kxkb/rules.h
index 38dd40fb6..0a68f3dbf 100644
--- a/kxkb/rules.h
+++ b/kxkb/rules.h
@@ -3,8 +3,10 @@
#include <tqstring.h>
#include <tqdict.h>
+#include <tqstringlist.h>
#include <tqmap.h>
+#include "layoutunit.h"
class XkbRules
{
@@ -18,6 +20,11 @@ public:
TQStringList getAvailableVariants(const TQString& layout);
+ TQString getLayoutName(LayoutUnit layout) const;
+
+ /// A helper to translate option description
+ static TQString trOpt(TQString opt);
+
protected:
void loadRules(TQString filename, bool layoutsOnly=false);
diff --git a/kxkb/x11helper.cpp b/kxkb/x11helper.cpp
index 2663bf4d4..d325b32a0 100644
--- a/kxkb/x11helper.cpp
+++ b/kxkb/x11helper.cpp
@@ -8,6 +8,8 @@
#include <tqregexp.h>
#include <kdebug.h>
+#include <tdestandarddirs.h>
+#include <tdelocale.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
@@ -214,25 +216,12 @@ X11Helper::loadRules(const TQString& file, bool layoutsOnly) {
// workaround for empty 'compose' options group description
if( rulesInfo->options.find("compose:menu") && !rulesInfo->options.find("compose") ) {
- rulesInfo->options.replace("compose", "Compose Key Position");
+ rulesInfo->options.replace("compose", I18N_NOOP("Compose Key Position"));
}
}
for(TQDictIterator<char> it(rulesInfo->options) ; it.current() != NULL; ++it ) {
- // HACK 2023/06/01 some descriptions in xkb rule files have "< >" in place
- // of an actual key name, both in *.lst and *.xml files
- TQString descFix = TQString::null;
- if (it.currentKey().contains("lsgt_switch")) {
- descFix = TQString(it.current()).replace("< >", "LSGT");
- }
- else if (it.currentKey().startsWith("compose:102")) {
- descFix = TQString(it.current()).replace("< >", "102");
- }
- if (!descFix.isNull()) {
- rulesInfo->options.replace(it.currentKey(), tqstrdup(descFix.ascii()));
- }
-
// Add missing option groups
TQString option(it.currentKey());
int columnPos = option.find(":");
@@ -403,3 +392,13 @@ bool X11Helper::areSingleGroupsSupported()
{
return true; //TODO:
}
+
+void X11Helper::initializeTranslations() {
+ // TDE is usually installed into some non-standard prefix and by default system-wide locale
+ // dirs are not considered when searching for gettext message catalogues, so we have to add
+ // it explicitly.
+#ifdef WITH_XKB_TRANSLATIONS
+ TDEGlobal::dirs()->addResourceDir("locale", XKB_CONFIG_LOCALE_DIR);
+ TDEGlobal::locale()->insertCatalogue("xkeyboard-config");
+#endif
+}
diff --git a/kxkb/x11helper.h b/kxkb/x11helper.h
index 042fb4ce5..8315dc446 100644
--- a/kxkb/x11helper.h
+++ b/kxkb/x11helper.h
@@ -3,6 +3,7 @@
#include <tqdict.h>
#include <tqstringlist.h>
+#include <tqwindowdefs.h>
struct RulesInfo {
@@ -36,6 +37,7 @@ public:
static bool areLayoutsClean() { return m_layoutsClean; }
static bool areSingleGroupsSupported();
+ static void initializeTranslations();
};
#endif /*X11HELPER_H_*/