You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
343 lines
11 KiB
343 lines
11 KiB
/***************************************************************************
|
|
kbconfig.cpp - description
|
|
-------------------
|
|
begin : Sun Jul 8 2001
|
|
copyright : (C) 2001 by Leonid Zeitlin
|
|
email : lz@europe.com
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <config.h>
|
|
#include <tdeversion.h>
|
|
#include <tdelocale.h>
|
|
#include <tdeglobal.h>
|
|
#if TDE_VERSION_MAJOR >= 3
|
|
#include <kstandarddirs.h>
|
|
#include <tdeapplication.h>
|
|
#else
|
|
#include <kstddirs.h>
|
|
#include <kapp.h>
|
|
#endif
|
|
#include <tdeglobalsettings.h>
|
|
#include <kdebug.h>
|
|
#include <kglobalaccel.h>
|
|
|
|
#include <ntqnamespace.h>
|
|
#include <ntqpainter.h>
|
|
#include <ntqimage.h>
|
|
|
|
#include "kbconfig.h"
|
|
#include "xkeyboard.h"
|
|
|
|
#ifdef HAVE_X11_EXTENSIONS_XKBRULES_H
|
|
#include <X11/extensions/XKBrules.h>
|
|
#endif
|
|
|
|
#define TOGGLE_MODE_ENTRY "toggle_mode"
|
|
#define DEFAULT_GROUP_ENTRY "default_group"
|
|
//#define PERWINDOW_GROUP_ENTRY "perwindow_group"
|
|
#define ICON_TYPE_ENTRY "icon_type"
|
|
#define AUTOSTART_ENTRY "autostart"
|
|
#define USE_SHORTCUTS_ENTRY "use_shorcuts"
|
|
#define GROUP_SCOPE_ENTRY "group_scope"
|
|
|
|
KBConfig::KBConfig()
|
|
{
|
|
m_toggle_mode = false;
|
|
m_groups.setAutoDelete(true);
|
|
m_default_groupno = 0;
|
|
//m_perwindow_group = false;
|
|
m_group_scope = SCOPE_GLOBAL;
|
|
m_autostart = true;
|
|
m_icon_style = ICON_CODE_AND_FLAG;
|
|
//m_keys = new TDEGlobalAccel(NULL);
|
|
m_keys = NULL;
|
|
}
|
|
|
|
KBConfig::~KBConfig()
|
|
{
|
|
delete m_keys;
|
|
}
|
|
|
|
/** load the KBSwitch configration from the application TDEConfig object */
|
|
void KBConfig::load(TDEConfig *config){
|
|
config->setGroup(OPTIONS_SECTION);
|
|
m_toggle_mode = config->readBoolEntry(TOGGLE_MODE_ENTRY);
|
|
m_default_groupno = config->readNumEntry(DEFAULT_GROUP_ENTRY);
|
|
//m_perwindow_group = config->readBoolEntry(PERWINDOW_GROUP_ENTRY);
|
|
m_group_scope = GroupScope(config->readNumEntry(GROUP_SCOPE_ENTRY, SCOPE_GLOBAL));
|
|
m_autostart = config->readBoolEntry(AUTOSTART_ENTRY, true);
|
|
m_icon_style = IconStyle(config->readNumEntry(ICON_TYPE_ENTRY, ICON_FLAG));
|
|
m_use_shortcuts = config->readBoolEntry(USE_SHORTCUTS_ENTRY, false);
|
|
|
|
XKeyboard *xkb = XKeyboard::self();
|
|
TQStringList list;
|
|
xkb->getGroupNames(list);
|
|
unsigned int i = 0;
|
|
m_groups.clear();
|
|
m_groups.resize(xkb->getNumKbdGroups());
|
|
TQString name;
|
|
for (TQStringList::Iterator iter = list.begin(); iter != list.end(); iter++, i++) {
|
|
name = *iter;
|
|
if (name == TQString::null) name = i18n("<Unnamed>");
|
|
m_groups.insert(i, new KBGroup(name));
|
|
}
|
|
|
|
TQValueVector<TQPixmap> pixlist;
|
|
TQStringList iconpaths;
|
|
drawIcons(m_icon_style, &pixlist, &iconpaths);
|
|
for (i = 0; i < m_groups.count(); i++) {
|
|
m_groups[i]->setPixmap(pixlist[i]);
|
|
m_groups[i]->setIconPath(iconpaths[i]);
|
|
}
|
|
|
|
if (m_keys) delete m_keys;
|
|
m_keys = new TDEGlobalAccel(NULL);
|
|
for (int i = 0; i < groupCount(); i++) {
|
|
m_keys->insert(TQString::fromLatin1("SetGroup %1").arg(i),
|
|
i18n("Activate %1 keyboard layout").arg(m_groups[i]->getName()),
|
|
TQString::null, TQt::ALT+TQt::CTRL+TQt::Key_1 + i, KKey::QtWIN+TQt::CTRL+TQt::Key_1 + i,
|
|
kapp, SLOT(slotGroupSelected(int)));
|
|
}
|
|
m_keys->readSettings(config);
|
|
checkKeysEnabled();
|
|
}
|
|
|
|
void KBConfig::save(TDEConfig *config)
|
|
{
|
|
config->setGroup(OPTIONS_SECTION);
|
|
config->writeEntry(TOGGLE_MODE_ENTRY, m_toggle_mode);
|
|
config->writeEntry(DEFAULT_GROUP_ENTRY, m_default_groupno);
|
|
//config->writeEntry(PERWINDOW_GROUP_ENTRY, m_perwindow_group);
|
|
config->writeEntry(GROUP_SCOPE_ENTRY, m_group_scope);
|
|
config->writeEntry(ICON_TYPE_ENTRY, m_icon_style);
|
|
config->writeEntry(AUTOSTART_ENTRY, m_autostart);
|
|
config->writeEntry(USE_SHORTCUTS_ENTRY, m_use_shortcuts);
|
|
m_keys->writeSettings(config);
|
|
}
|
|
|
|
void KBConfig::drawIcons(IconStyle icon_style, TQValueVector<TQPixmap> *icons,
|
|
TQStringList *iconpaths)
|
|
{
|
|
TQString path, countryCode, langCode;
|
|
TQStringList layouts;
|
|
|
|
TDEGlobal::dirs()->addResourceDir("appdata", ".");
|
|
TDEConfig map("group_names", true, true, "appdata");
|
|
TDEConfig *config = kapp->config();
|
|
config->setGroup(ICONS_SECTION);
|
|
getXkbLayouts(layouts);
|
|
|
|
icons->clear();
|
|
icons->resize(m_groups.count());
|
|
iconpaths->clear();
|
|
for (unsigned int i = 0; i < m_groups.count(); i++) {
|
|
map.setGroup("Mapping");
|
|
countryCode = map.readEntry(m_groups[i]->getName());
|
|
// if the country code can't be guessed from group name, try XKB layout name
|
|
if (countryCode.isEmpty() && i < layouts.count()) countryCode = layouts[i];
|
|
map.setGroup("Languages");
|
|
langCode = map.readEntry(m_groups[i]->getName());
|
|
if (langCode.isEmpty()) langCode = countryCode;
|
|
TQPixmap &pix = (*icons)[i];
|
|
pix.resize(0, 0);
|
|
path = TQString::null;
|
|
if (icon_style == ICON_FLAG /*&& !countryCode.isEmpty()*/)
|
|
drawFlagPixmap(pix, path, countryCode, i, config);
|
|
else if (icon_style == ICON_CODE_AND_FLAG /*&& !countryCode.isEmpty()*/)
|
|
drawCodeAndFlagPixmap(pix, path, countryCode, langCode, i, config);
|
|
if (pix.isNull() && !langCode.isEmpty())
|
|
drawCodePixmap(pix, langCode);
|
|
if (pix.isNull()) drawDefaultPixmap(pix, i);
|
|
iconpaths->append(path);
|
|
}
|
|
}
|
|
|
|
/** No descriptions */
|
|
/*void KBConfig::guessGroupPixmaps(){
|
|
TDEGlobal::dirs()->addResourceDir("appdata", ".");
|
|
TDEConfig map("group_names", true, true, "appdata");
|
|
TQString path, countryCode, langCode;
|
|
TQPixmap pix;
|
|
|
|
for (unsigned int i = 0; i < m_groups.count(); i++) {
|
|
if (m_groups[i]->getPixmap().isNull()) {
|
|
map.setGroup("Mapping");
|
|
countryCode = map.readEntry(m_groups[i]->getName());
|
|
map.setGroup("Languages");
|
|
langCode = map.readEntry(m_groups[i]->getName());
|
|
if (langCode.isEmpty()) langCode = countryCode;
|
|
pix.resize(0, 0);
|
|
if (m_icon_type == ICON_FLAG && !countryCode.isEmpty())
|
|
drawFlagPixmap(pix, countryCode);
|
|
else if (m_icon_type == ICON_CODE_AND_FLAG && !countryCode.isEmpty())
|
|
drawCodeAndFlagPixmap(pix, countryCode, langCode);
|
|
if (pix.isNull() && !langCode.isEmpty())
|
|
drawCodePixmap(pix, langCode);
|
|
if (!pix.isNull()) m_groups[i]->setPixmap(pix);
|
|
}
|
|
}
|
|
}*/
|
|
|
|
bool KBConfig::getGroupImage(TQImage &img, TQString &path, const TQString &code,
|
|
int group, TDEConfig *config)
|
|
{
|
|
bool ret = true;
|
|
bool need_to_scale = false;
|
|
|
|
path = config->readEntry(m_groups[group]->getName()/*entryForGroup(group)*/);
|
|
if (path.isEmpty() || !img.load(path)) {
|
|
if (code.isEmpty()) ret = false;
|
|
else {
|
|
path = locate("locale", TQString("l10n/%1/flag.png").arg(code));
|
|
if (!path.isEmpty()) ret = img.load(path);
|
|
else {
|
|
// I am told in Red Hat 9 standard KDE flag pixmaps are missing.
|
|
// Workaround: we have to simulate them by rescaling GKB's pixmaps
|
|
path = TQString("/usr/share/pixmaps/gkb/%1.png").arg(code);
|
|
ret = img.load(path) && !img.isNull();
|
|
need_to_scale = true;
|
|
}
|
|
}
|
|
}
|
|
if (ret) {
|
|
// if need_to_scale is not already set, set it if image is too wide
|
|
if (!need_to_scale) need_to_scale = img.width() > 24;
|
|
if (need_to_scale) img = img.smoothScale(FLAG_ICON_WIDTH, FLAG_ICON_HEIGHT);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void KBConfig::drawFlagPixmap(TQPixmap &pix, TQString &path, const TQString &code,
|
|
int group, TDEConfig *config)
|
|
{
|
|
TQImage img;
|
|
if (getGroupImage(img, path, code, group, config))
|
|
pix.convertFromImage(img);
|
|
}
|
|
|
|
void KBConfig::drawCodePixmap(TQPixmap &pix, const TQString &code)
|
|
{
|
|
pix.resize(19, 16);
|
|
|
|
TQPainter painter(&pix);
|
|
TQFont font("helvetica", 9, TQFont::Bold);
|
|
font.setPixelSize(10);
|
|
painter.setFont(font);
|
|
painter.setPen(TDEGlobalSettings::highlightedTextColor());
|
|
|
|
pix.fill(TDEGlobalSettings::highlightColor());
|
|
painter.drawText(1, 0, pix.width(), pix.height(),
|
|
TQt::AlignHCenter | TQt::AlignVCenter, code.upper());
|
|
|
|
/*TQSize size = painter.fontMetrics().size(0, code.upper());
|
|
kdDebug() << size.width() << " x " << size.height() << endl;*/
|
|
}
|
|
|
|
void KBConfig::drawCodeAndFlagPixmap(TQPixmap &pix, TQString &path,
|
|
const TQString &countryCode, const TQString &langCode, int group, TDEConfig *config)
|
|
{
|
|
TQImage img;
|
|
if (!getGroupImage(img, path, countryCode, group, config)) return; // could not find flag
|
|
if (img.depth() <= 8) img = img.convertDepth(32);
|
|
|
|
// the following code is taken from tdebase/kxkb/pixmap.cpp
|
|
for (int y = 0; y < img.height(); y++)
|
|
for(int x = 0; x < img.width(); x++) {
|
|
TQRgb rgb = img.pixel(x, y);
|
|
img.setPixel(x, y, tqRgb(tqRed(rgb)*3/4, tqGreen(rgb)*3/4, tqBlue(rgb)*3/4));
|
|
}
|
|
pix.convertFromImage(img);
|
|
|
|
TQPainter painter(&pix);
|
|
painter.setPen(TQt::black);
|
|
painter.setFont(TQFont("helvetica", 10, TQFont::Bold));
|
|
painter.drawText(1, 1, pix.width(), pix.height()-2, TQt::AlignCenter, langCode);
|
|
painter.setPen(TQt::white);
|
|
painter.drawText(0, 0, pix.width(), pix.height()-2, TQt::AlignCenter, langCode);
|
|
}
|
|
|
|
void KBConfig::drawDefaultPixmap(TQPixmap &pix, int group)
|
|
{
|
|
pix.resize(FLAG_ICON_WIDTH, FLAG_ICON_HEIGHT);
|
|
TQPainter painter(&pix);
|
|
pix.fill();
|
|
painter.drawText(0, 0, pix.width(), pix.height(),
|
|
TQt::AlignHCenter | TQt::AlignVCenter, TQString::number(group+1));
|
|
}
|
|
|
|
void KBConfig::checkKeysEnabled()
|
|
{
|
|
m_keys->setEnabled(m_use_shortcuts);
|
|
m_keys->updateConnections();
|
|
}
|
|
|
|
|
|
/** No descriptions */
|
|
/*void KBConfig::drawDefaultPixmaps(){
|
|
TQPixmap pix(16, 16);
|
|
TQPainter painter(&pix);
|
|
|
|
for (unsigned int i = 0; i < m_groups.count(); i++) {
|
|
if (m_groups[i]->getPixmap().isNull()) {
|
|
pix.fill();
|
|
painter.drawText(0, 0, pix.width(), pix.height(),
|
|
TQt::AlignHCenter | TQt::AlignVCenter, TQString::number(i+1));
|
|
m_groups[i]->setPixmap(pix);
|
|
}
|
|
}
|
|
}*/
|
|
|
|
/** No descriptions */
|
|
/*void KBConfig::loadConfiguredPixmaps(TDEConfig *config){
|
|
TQString path;
|
|
TQPixmap pix;
|
|
config->setGroup(ICONS_SECTION);
|
|
for (unsigned int i = 0; i < m_groups.count(); i++) {
|
|
path = config->readEntry(entryForGroup(i));
|
|
if (!path.isEmpty() && pix.load(path))
|
|
m_groups[i]->setPixmap(pix);
|
|
}
|
|
}*/
|
|
|
|
/** No descriptions */
|
|
/*void KBConfig::notifyChanged(){
|
|
emit changed();
|
|
}*/
|
|
|
|
|
|
/*!
|
|
\fn KBConfig::getXkbLayouts(const TQStringList &layouts)
|
|
*/
|
|
void KBConfig::getXkbLayouts(TQStringList &layouts)
|
|
{
|
|
#if HAVE_X11_EXTENSIONS_XKBRULES_H && HAVE_LIBXKBFILE
|
|
XkbRF_VarDefsRec vardefs;
|
|
int i;
|
|
|
|
usleep(10000);
|
|
if (XkbRF_GetNamesProp(tqt_xdisplay(), NULL, &vardefs)) {
|
|
layouts = TQStringList::split(',', vardefs.layout, true);
|
|
for (TQStringList::Iterator it = layouts.begin(); it != layouts.end(); ++it) {
|
|
i = 0;
|
|
while ((*it)[i] >= 'a' && (*it)[i] <= 'z') i++;
|
|
*it = (*it).left(i);
|
|
}
|
|
if (vardefs.layout) XFree(vardefs.layout);
|
|
if (vardefs.model) XFree(vardefs.model);
|
|
if (vardefs.variant) XFree(vardefs.variant);
|
|
if (vardefs.options) XFree(vardefs.options);
|
|
}
|
|
#endif
|
|
}
|