~ubuntu-branches/ubuntu/lucid/kkbswitch/lucid

« back to all changes in this revision

Viewing changes to kkbswitch/kbconfig.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Lior Kaplan
  • Date: 2005-09-07 02:01:14 UTC
  • Revision ID: james.westby@ubuntu.com-20050907020114-2wyo9eu21uihq86n
Tags: upstream-1.4.3
ImportĀ upstreamĀ versionĀ 1.4.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
                          kbconfig.cpp  -  description
 
3
                             -------------------
 
4
    begin                : Sun Jul 8 2001
 
5
    copyright            : (C) 2001 by Leonid Zeitlin
 
6
    email                : lz@europe.com
 
7
 ***************************************************************************/
 
8
 
 
9
/***************************************************************************
 
10
 *                                                                         *
 
11
 *   This program is free software; you can redistribute it and/or modify  *
 
12
 *   it under the terms of the GNU General Public License as published by  *
 
13
 *   the Free Software Foundation; either version 2 of the License, or     *
 
14
 *   (at your option) any later version.                                   *
 
15
 *                                                                         *
 
16
 ***************************************************************************/
 
17
 
 
18
#include <config.h> 
 
19
#include <kdeversion.h>
 
20
#include <klocale.h>
 
21
#include <kglobal.h>
 
22
#if KDE_VERSION_MAJOR >= 3
 
23
  #include <kstandarddirs.h>
 
24
  #include <kapplication.h>
 
25
#else
 
26
  #include <kstddirs.h>
 
27
  #include <kapp.h>
 
28
#endif
 
29
#include <kglobalsettings.h>
 
30
#include <kdebug.h>
 
31
#include <kglobalaccel.h>
 
32
 
 
33
#include <qnamespace.h>
 
34
#include <qpainter.h>
 
35
#include <qimage.h>
 
36
 
 
37
#include "kbconfig.h"
 
38
#include "xkeyboard.h"
 
39
 
 
40
#ifdef HAVE_X11_EXTENSIONS_XKBRULES_H
 
41
  #include <X11/extensions/XKBrules.h>
 
42
#endif
 
43
 
 
44
#define TOGGLE_MODE_ENTRY "toggle_mode"
 
45
#define DEFAULT_GROUP_ENTRY "default_group"
 
46
//#define PERWINDOW_GROUP_ENTRY "perwindow_group"
 
47
#define ICON_TYPE_ENTRY "icon_type"
 
48
#define AUTOSTART_ENTRY "autostart"
 
49
#define USE_SHORTCUTS_ENTRY "use_shorcuts"
 
50
#define GROUP_SCOPE_ENTRY "group_scope"
 
51
 
 
52
KBConfig::KBConfig()
 
53
{
 
54
  m_toggle_mode = false;
 
55
  m_groups.setAutoDelete(true);
 
56
  m_default_groupno = 0;
 
57
  //m_perwindow_group = false;
 
58
  m_group_scope = SCOPE_GLOBAL;
 
59
  m_autostart = true;
 
60
  m_icon_style = ICON_CODE_AND_FLAG;
 
61
  //m_keys = new KGlobalAccel(NULL);
 
62
  m_keys = NULL;
 
63
}
 
64
 
 
65
KBConfig::~KBConfig()
 
66
{
 
67
        delete m_keys;
 
68
}
 
69
 
 
70
/** load the KBSwitch configration from the application KConfig object */
 
71
void KBConfig::load(KConfig *config){
 
72
  config->setGroup(OPTIONS_SECTION);
 
73
  m_toggle_mode = config->readBoolEntry(TOGGLE_MODE_ENTRY);
 
74
  m_default_groupno = config->readNumEntry(DEFAULT_GROUP_ENTRY);
 
75
  //m_perwindow_group = config->readBoolEntry(PERWINDOW_GROUP_ENTRY);
 
76
  m_group_scope = GroupScope(config->readNumEntry(GROUP_SCOPE_ENTRY, SCOPE_GLOBAL));
 
77
  m_autostart = config->readBoolEntry(AUTOSTART_ENTRY, true);
 
78
  m_icon_style = IconStyle(config->readNumEntry(ICON_TYPE_ENTRY, ICON_FLAG));
 
79
  m_use_shortcuts = config->readBoolEntry(USE_SHORTCUTS_ENTRY, false);
 
80
        
 
81
  XKeyboard *xkb = XKeyboard::self();
 
82
  QStringList list;
 
83
  xkb->getGroupNames(list);
 
84
  unsigned int i = 0;
 
85
  m_groups.clear();
 
86
  m_groups.resize(xkb->getNumKbdGroups());
 
87
  QString name;
 
88
  for (QStringList::Iterator iter = list.begin(); iter != list.end(); iter++, i++) {
 
89
    name = *iter;
 
90
    if (name == QString::null) name = i18n("<Unnamed>");
 
91
    m_groups.insert(i, new KBGroup(name));
 
92
  }
 
93
 
 
94
  QValueVector<QPixmap> pixlist;
 
95
  QStringList iconpaths;
 
96
  drawIcons(m_icon_style, &pixlist, &iconpaths);
 
97
  for (i = 0; i < m_groups.count(); i++) {
 
98
                m_groups[i]->setPixmap(pixlist[i]);
 
99
                m_groups[i]->setIconPath(iconpaths[i]);
 
100
        }
 
101
 
 
102
        if (m_keys) delete m_keys;
 
103
  m_keys = new KGlobalAccel(NULL);
 
104
  for (int i = 0; i < groupCount(); i++) {
 
105
    m_keys->insert(QString::fromLatin1("SetGroup %1").arg(i),
 
106
      i18n("Activate %1 keyboard layout").arg(m_groups[i]->getName()),
 
107
      QString::null, Qt::ALT+Qt::CTRL+Qt::Key_1 + i, KKey::QtWIN+Qt::CTRL+Qt::Key_1 + i,
 
108
      kapp, SLOT(slotGroupSelected(int)));
 
109
  }
 
110
  m_keys->readSettings(config);
 
111
  checkKeysEnabled();
 
112
}
 
113
 
 
114
void KBConfig::save(KConfig *config)
 
115
{
 
116
  config->setGroup(OPTIONS_SECTION);
 
117
  config->writeEntry(TOGGLE_MODE_ENTRY, m_toggle_mode);
 
118
  config->writeEntry(DEFAULT_GROUP_ENTRY, m_default_groupno);
 
119
  //config->writeEntry(PERWINDOW_GROUP_ENTRY, m_perwindow_group);
 
120
  config->writeEntry(GROUP_SCOPE_ENTRY, m_group_scope);
 
121
  config->writeEntry(ICON_TYPE_ENTRY, m_icon_style);
 
122
  config->writeEntry(AUTOSTART_ENTRY, m_autostart);
 
123
  config->writeEntry(USE_SHORTCUTS_ENTRY, m_use_shortcuts);
 
124
  m_keys->writeSettings(config);
 
125
}
 
126
 
 
127
void KBConfig::drawIcons(IconStyle icon_style, QValueVector<QPixmap> *icons,
 
128
  QStringList *iconpaths)
 
129
{
 
130
  QString path, countryCode, langCode;
 
131
  QStringList layouts;
 
132
  
 
133
  KGlobal::dirs()->addResourceDir("appdata", ".");
 
134
  KConfig map("group_names", true, true, "appdata");
 
135
  KConfig *config = kapp->config();
 
136
  config->setGroup(ICONS_SECTION);
 
137
  getXkbLayouts(layouts);
 
138
 
 
139
  icons->clear();
 
140
  icons->resize(m_groups.count());
 
141
  iconpaths->clear();
 
142
  for (unsigned int i = 0; i < m_groups.count(); i++) {
 
143
    map.setGroup("Mapping");
 
144
    countryCode = map.readEntry(m_groups[i]->getName());
 
145
    // if the country code can't be guessed from group name, try XKB layout name
 
146
    if (countryCode.isEmpty() && i < layouts.count()) countryCode = layouts[i];
 
147
    map.setGroup("Languages");
 
148
    langCode = map.readEntry(m_groups[i]->getName());
 
149
    if (langCode.isEmpty()) langCode = countryCode;
 
150
    QPixmap &pix = (*icons)[i];
 
151
    pix.resize(0, 0);
 
152
    path = QString::null;
 
153
    if (icon_style == ICON_FLAG /*&& !countryCode.isEmpty()*/)
 
154
      drawFlagPixmap(pix, path, countryCode, i, config);
 
155
    else if (icon_style == ICON_CODE_AND_FLAG /*&& !countryCode.isEmpty()*/)
 
156
      drawCodeAndFlagPixmap(pix, path, countryCode, langCode, i, config);
 
157
    if (pix.isNull() && !langCode.isEmpty())
 
158
    drawCodePixmap(pix, langCode);
 
159
    if (pix.isNull()) drawDefaultPixmap(pix, i);
 
160
    iconpaths->append(path);
 
161
  }
 
162
}
 
163
 
 
164
/** No descriptions */
 
165
/*void KBConfig::guessGroupPixmaps(){
 
166
  KGlobal::dirs()->addResourceDir("appdata", ".");
 
167
  KConfig map("group_names", true, true, "appdata");
 
168
  QString path, countryCode, langCode;
 
169
  QPixmap pix;
 
170
 
 
171
  for (unsigned int i = 0; i < m_groups.count(); i++) {
 
172
    if (m_groups[i]->getPixmap().isNull()) {
 
173
          map.setGroup("Mapping");
 
174
      countryCode = map.readEntry(m_groups[i]->getName());
 
175
          map.setGroup("Languages");
 
176
      langCode = map.readEntry(m_groups[i]->getName());
 
177
      if (langCode.isEmpty()) langCode = countryCode;
 
178
                pix.resize(0, 0);
 
179
                if (m_icon_type == ICON_FLAG && !countryCode.isEmpty())
 
180
              drawFlagPixmap(pix, countryCode);
 
181
                  else if (m_icon_type == ICON_CODE_AND_FLAG && !countryCode.isEmpty())
 
182
                    drawCodeAndFlagPixmap(pix, countryCode, langCode);
 
183
                if (pix.isNull() && !langCode.isEmpty())
 
184
        drawCodePixmap(pix, langCode);
 
185
      if (!pix.isNull()) m_groups[i]->setPixmap(pix);
 
186
    }
 
187
  }
 
188
}*/
 
189
 
 
190
bool KBConfig::getGroupImage(QImage &img, QString &path, const QString &code,
 
191
  int group, KConfig *config)
 
192
{
 
193
  bool ret = true;
 
194
  bool need_to_scale = false;
 
195
        
 
196
  path = config->readEntry(m_groups[group]->getName()/*entryForGroup(group)*/);
 
197
  if (path.isEmpty() || !img.load(path)) {
 
198
    if (code.isEmpty()) ret = false;
 
199
    else {
 
200
      path = locate("locale", QString("l10n/%1/flag.png").arg(code));
 
201
      if (!path.isEmpty()) ret = img.load(path);
 
202
      else {
 
203
        // I am told in Red Hat 9 standard KDE flag pixmaps are missing.
 
204
        // Workaround: we have to simulate them by rescaling GKB's pixmaps
 
205
        path = QString("/usr/share/pixmaps/gkb/%1.png").arg(code);
 
206
        ret = img.load(path) && !img.isNull();
 
207
        need_to_scale = true;
 
208
      }
 
209
    } 
 
210
  }
 
211
  if (ret) {
 
212
     // if need_to_scale is not already set, set it if image is too wide
 
213
     if (!need_to_scale) need_to_scale = img.width() > 24;
 
214
     if (need_to_scale) img = img.smoothScale(FLAG_ICON_WIDTH, FLAG_ICON_HEIGHT);
 
215
  }
 
216
  return ret;
 
217
}
 
218
 
 
219
void KBConfig::drawFlagPixmap(QPixmap &pix, QString &path, const QString &code,
 
220
  int group, KConfig *config)
 
221
{
 
222
  QImage img;
 
223
  if (getGroupImage(img, path, code, group, config)) 
 
224
    pix.convertFromImage(img);
 
225
}
 
226
 
 
227
void KBConfig::drawCodePixmap(QPixmap &pix, const QString &code)
 
228
{
 
229
  pix.resize(19, 16);
 
230
        
 
231
  QPainter painter(&pix);
 
232
  QFont font("helvetica", 9, QFont::Bold);
 
233
  font.setPixelSize(10);
 
234
  painter.setFont(font);
 
235
        painter.setPen(KGlobalSettings::highlightedTextColor());
 
236
        
 
237
        pix.fill(KGlobalSettings::highlightColor());
 
238
  painter.drawText(1, 0, pix.width(), pix.height(),
 
239
    Qt::AlignHCenter | Qt::AlignVCenter, code.upper());
 
240
 
 
241
  /*QSize size = painter.fontMetrics().size(0, code.upper());
 
242
  kdDebug() << size.width() << " x " << size.height() << endl;*/
 
243
}
 
244
 
 
245
void KBConfig::drawCodeAndFlagPixmap(QPixmap &pix, QString &path,
 
246
  const QString &countryCode, const QString &langCode, int group, KConfig *config)
 
247
{
 
248
        QImage img;
 
249
        if (!getGroupImage(img, path, countryCode, group, config)) return; // could not find flag
 
250
        if (img.depth() <= 8) img = img.convertDepth(32);
 
251
 
 
252
        // the following code is taken from kdebase/kxkb/pixmap.cpp
 
253
  for (int y = 0; y < img.height(); y++)
 
254
    for(int x = 0; x < img.width(); x++) {
 
255
      QRgb rgb = img.pixel(x, y);
 
256
      img.setPixel(x, y, qRgb(qRed(rgb)*3/4, qGreen(rgb)*3/4, qBlue(rgb)*3/4));
 
257
    }
 
258
  pix.convertFromImage(img);
 
259
 
 
260
  QPainter painter(&pix);
 
261
  painter.setPen(Qt::black);
 
262
  painter.setFont(QFont("helvetica", 10, QFont::Bold));
 
263
  painter.drawText(1, 1, pix.width(), pix.height()-2, Qt::AlignCenter, langCode);
 
264
  painter.setPen(Qt::white);
 
265
  painter.drawText(0, 0, pix.width(), pix.height()-2, Qt::AlignCenter, langCode);
 
266
}
 
267
 
 
268
void KBConfig::drawDefaultPixmap(QPixmap &pix, int group)
 
269
{
 
270
  pix.resize(FLAG_ICON_WIDTH, FLAG_ICON_HEIGHT);
 
271
  QPainter painter(&pix);
 
272
  pix.fill();
 
273
  painter.drawText(0, 0, pix.width(), pix.height(),
 
274
    Qt::AlignHCenter | Qt::AlignVCenter, QString::number(group+1));
 
275
}       
 
276
 
 
277
void KBConfig::checkKeysEnabled()
 
278
{
 
279
  m_keys->setEnabled(m_use_shortcuts);
 
280
  m_keys->updateConnections();
 
281
}
 
282
 
 
283
 
 
284
/** No descriptions */
 
285
/*void KBConfig::drawDefaultPixmaps(){
 
286
  QPixmap pix(16, 16);
 
287
  QPainter painter(&pix);
 
288
 
 
289
  for (unsigned int i = 0; i < m_groups.count(); i++) {
 
290
    if (m_groups[i]->getPixmap().isNull()) {
 
291
      pix.fill();
 
292
      painter.drawText(0, 0, pix.width(), pix.height(),
 
293
        Qt::AlignHCenter | Qt::AlignVCenter, QString::number(i+1));
 
294
      m_groups[i]->setPixmap(pix);
 
295
    }
 
296
  }
 
297
}*/
 
298
 
 
299
/** No descriptions */
 
300
/*void KBConfig::loadConfiguredPixmaps(KConfig *config){
 
301
  QString path;
 
302
  QPixmap pix;
 
303
  config->setGroup(ICONS_SECTION);
 
304
  for (unsigned int i = 0; i < m_groups.count(); i++) {
 
305
    path = config->readEntry(entryForGroup(i));
 
306
    if (!path.isEmpty() && pix.load(path))
 
307
      m_groups[i]->setPixmap(pix);
 
308
  }
 
309
}*/
 
310
 
 
311
/** No descriptions */
 
312
/*void KBConfig::notifyChanged(){
 
313
  emit changed();
 
314
}*/
 
315
 
 
316
 
 
317
/*!
 
318
    \fn KBConfig::getXkbLayouts(const QStringList &layouts)
 
319
 */
 
320
void KBConfig::getXkbLayouts(QStringList &layouts)
 
321
{
 
322
#if HAVE_X11_EXTENSIONS_XKBRULES_H && HAVE_LIBXKBFILE
 
323
  XkbRF_VarDefsRec vardefs;
 
324
  int i;
 
325
 
 
326
  usleep(10000);
 
327
  if (XkbRF_GetNamesProp(qt_xdisplay(), NULL, &vardefs)) {
 
328
    layouts = QStringList::split(',', vardefs.layout, true);
 
329
    for (QStringList::Iterator it = layouts.begin(); it != layouts.end(); ++it) {
 
330
      i = 0;
 
331
      while ((*it)[i] >= 'a' && (*it)[i] <= 'z') i++;
 
332
      *it = (*it).left(i);
 
333
    }
 
334
    if (vardefs.layout) XFree(vardefs.layout);
 
335
    if (vardefs.model) XFree(vardefs.model);
 
336
    if (vardefs.variant) XFree(vardefs.variant);
 
337
    if (vardefs.options) XFree(vardefs.options);
 
338
  }
 
339
#endif
 
340
}