-rw-r--r-- | inputmethods/multikey/keyboard.cpp | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/inputmethods/multikey/keyboard.cpp b/inputmethods/multikey/keyboard.cpp index bded447..2ce6dd3 100644 --- a/inputmethods/multikey/keyboard.cpp +++ b/inputmethods/multikey/keyboard.cpp @@ -1,233 +1,245 @@ /********************************************************************** ** Copyright (C) 2000 Trolltech AS. All rights reserved. ** ** This file is part of Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #include "keyboard.h" #include "configdlg.h" #include <qpe/global.h> #include <qpe/qcopenvelope_qws.h> #include <qwindowsystem_qws.h> #include <qpainter.h> #include <qfontmetrics.h> #include <qtimer.h> #include <qpe/qpeapplication.h> #include <qpe/config.h> #include <ctype.h> #include <qfile.h> #include <qtextstream.h> #include <qstringlist.h> #include <sys/utsname.h> using namespace MultiKey; +static const char * const kb_config_xpm[] = { +"13 7 2 1", +" c None", +". c #000000", +" ", +" . ", +" ... ", +" ..... ", +" . ", +" . ", +" "}; + /* Keyboard::Keyboard {{{1 */ Keyboard::Keyboard(QWidget* parent, const char* _name, WFlags f) : QFrame(parent, _name, f), shift(0), lock(0), ctrl(0), alt(0), meta(0), circumflex(0), diaeresis(0), baccent(0), accent(0), useLargeKeys(TRUE), usePicks(0), useRepeat(0), pressedKeyRow(-1), pressedKeyCol(-1), unicode(-1), qkeycode(0), modifiers(0), schar(0), mchar(0), echar(0), configdlg(0) { // get the default font Config *config = new Config( "qpe" ); config->setGroup( "Appearance" ); QString familyStr = config->readEntry( "FontFamily", "smallsmooth" ); delete config; config = new Config("multikey"); config->setGroup ("general"); usePicks = config->readBoolEntry ("usePickboard", 0); // default closed useRepeat = config->readBoolEntry ("useRepeat", 1); delete config; setFont( QFont( familyStr, 10 ) ); picks = new KeyboardPicks( this ); picks->setFont( QFont( familyStr, 10 ) ); picks->initialise(); if (usePicks) { QObject::connect( picks, SIGNAL(key(ushort,ushort,ushort,bool,bool) ), this, SIGNAL(key(ushort,ushort,ushort,bool,bool)) ); } else picks->hide(); loadKeyboardColors(); keys = new Keys(); repeatTimer = new QTimer( this ); connect( repeatTimer, SIGNAL(timeout()), this, SLOT(repeat()) ); } Keyboard::~Keyboard() { if ( configdlg ) { delete (ConfigDlg *) configdlg; configdlg = 0; } } /* Keyboard::resizeEvent {{{1 */ void Keyboard::resizeEvent(QResizeEvent*) { int ph = picks->sizeHint().height(); picks->setGeometry( 0, 0, width(), ph ); keyHeight = (height()-(usePicks ? ph : 0))/(keys->rows()?keys->rows():1); int nk; // number of keys? if ( useLargeKeys ) { nk = 15; } else { nk = 19; } defaultKeyWidth = (width()/nk)/2; xoffs = (width()-defaultKeyWidth*nk)/2; // empty key spaces? } /* KeyboardPicks::initialize {{{1 */ void KeyboardPicks::initialise() { setSizePolicy(QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed)); mode = 0; dc = new KeyboardConfig(this); configs.append(dc); } /* KeyboardPicks::sizeHint {{{1 */ QSize KeyboardPicks::sizeHint() const { return QSize(240,fontMetrics().lineSpacing()); } /* KeyboardConfig::generateText {{{1 */ void KeyboardConfig::generateText(const QString &s) { #if defined(Q_WS_QWS) || defined(_WS_QWS_) for (int i=0; i<(int)backspaces; i++) { parent->emitKey( 0, Qt::Key_Backspace, 0, true, false ); parent->emitKey( 0, Qt::Key_Backspace, 0, false, false ); } for (int i=0; i<(int)s.length(); i++) { parent->emitKey( s[i].unicode(), 0, 0, true, false ); parent->emitKey( s[i].unicode(), 0, 0, false, false ); } parent->emitKey( 0, Qt::Key_Space, 0, true, false ); parent->emitKey( 0, Qt::Key_Space, 0, false, false ); backspaces = 0; #endif } /* Keyboard::paintEvent {{{1 */ void Keyboard::paintEvent(QPaintEvent* e) { QPainter painter(this); painter.setClipRect(e->rect()); drawKeyboard( painter ); picks->dc->draw( &painter ); } /* Keyboard::drawKeyboard {{{1 */ void Keyboard::drawKeyboard(QPainter &p, int row, int col) { if (row != -1 && col != -1) { //just redraw one key int x = 0; for (int i = 0; i < col; i++) { x += keys->width(row, i) * defaultKeyWidth; } int y = (row - 1) * keyHeight + (usePicks ? picks->height() : 0); int keyWidth = keys->width(row, col); p.fillRect(x + 1, y + 1, keyWidth * defaultKeyWidth - 1, keyHeight - 1, pressed || keys->pressed(row, col) ? keycolor_pressed : keycolor); QImage *pix = keys->pix(row,col); ushort c = keys->uni(row, col); p.setPen(textcolor); if (!pix) { if ((shift || lock) && keys->shift(c)) if (circumflex && keys->circumflex(keys->shift(c))) c = keys->circumflex(keys->shift(c)); else if (diaeresis && keys->diaeresis(keys->shift(c))) c = keys->diaeresis(keys->shift(c)); else if (baccent && keys->baccent(keys->shift(c))) c = keys->baccent(keys->shift(c)); else if (accent && keys->accent(keys->shift(c))) c = keys->accent(keys->shift(c)); else if (meta && keys->meta(keys->shift(c))) c = keys->meta(keys->shift(c)); else c = keys->shift(c); else if (meta && keys->meta(c)) c = keys->meta(c); else if (circumflex && keys->circumflex(c)) c = keys->circumflex(c); else if (baccent && keys->baccent(c)) c = keys->baccent(c); else if (accent && keys->accent(c)) c = keys->accent(c); else if (diaeresis && (keys->diaeresis(c) || c == 0x2c6)) { // the diaeresis key itself has to be in the diaeresisMap, // or just do this to make it display the diaeresis char. if (c == 0x2c6) c = 0xa8; else c = keys->diaeresis(c); } p.drawText(x, y, defaultKeyWidth * keyWidth + 3, keyHeight, AlignCenter, (QChar)c); } else // center the image in the middle of the key p.drawImage( x + (defaultKeyWidth * keyWidth - pix->width())/2 + 1, y + (keyHeight - pix->height())/2 + 1, *pix ); // this fixes the problem that the very right end of the board's vertical line // gets painted over, because it's one pixel shorter than all other keys @@ -1333,328 +1345,334 @@ Keys::Keys() { QString l = config->readEntry( "Language" , "en" ); delete config; map = QPEApplication::qpeDir() + "/share/multikey/" + l + ".keymap"; } if (map.isNull() || !(QFile(map).exists())) { map = QPEApplication::qpeDir() + "/share/multikey/en.keymap"; } setKeysFromFile(map); } Keys::Keys(const char * filename) { setKeysFromFile(filename); } // Keys::setKeysFromFile {{{2 void Keys::setKeysFromFile(const char * filename) { QFile f(filename); if (f.open(IO_ReadOnly)) { QTextStream t(&f); int row; int qcode; ushort unicode; int width; QString buf; QString comment; char * xpm[256]; //couldnt be larger than that... could it? QImage *xpm2pix = 0; buf = t.readLine(); while (buf) { // get rid of comments buf.replace(QRegExp("#.*$", FALSE, FALSE), ""); // key definition if (buf.contains(QRegExp("^\\d+\\s+[0-1a-fx]+", FALSE, FALSE))) { // no $1 type referencing!!! this implementation of regexp sucks // dont know of any sscanf() type funcs in Qt lib QTextStream tmp (buf, IO_ReadOnly); tmp >> row >> qcode >> unicode >> width >> comment; buf = t.readLine(); int xpmLineCount = 0; xpm2pix = 0; // erase blank space while (buf.contains(QRegExp("^\\s*$")) && buf) buf = t.readLine(); while (buf.contains(QRegExp("^\\s*\".*\""))) { QString xpmBuf = buf.stripWhiteSpace(); xpm[xpmLineCount] = new char [xpmBuf.length()]; int j = 0; for (ushort i = 0; i < xpmBuf.length(); i++) { if (xpmBuf[i].latin1() != '"') { ((char *)xpm[xpmLineCount])[j] = xpmBuf.at(i).latin1(); j++; } } // have to close that facker up ((char *)xpm[xpmLineCount])[j] = '\0'; xpmLineCount++; buf = t.readLine(); } if (xpmLineCount) { xpm2pix = new QImage((const char **)xpm); for (int i = 0; i < xpmLineCount; i++) delete [] (xpm[i]); } setKey(row, qcode, unicode, width, xpm2pix); } // shift map else if (buf.contains(QRegExp("^[0-9a-fx]+\\s+[0-9a-fx]+\\s*$", FALSE, FALSE))) { QTextStream tmp (buf, IO_ReadOnly); ushort lower, shift; tmp >> lower >> shift; shiftMap.insert(lower, shift); buf = t.readLine(); } // meta key map else if (buf.contains(QRegExp("^\\s*m\\s+[0-9a-fx]+\\s+[0-9a-fx]+\\s*$", FALSE, FALSE))) { QTextStream tmp (buf, IO_ReadOnly); ushort lower, shift; QChar m; tmp >> m >> lower >> shift; metaMap.insert(lower, shift); buf = t.readLine(); } // circumflex else if (buf.contains(QRegExp("^\\s*c\\s+[0-9a-fx]+\\s+[0-9a-fx]+\\s*$", FALSE, FALSE))) { QTextStream tmp (buf, IO_ReadOnly); ushort lower, shift; QChar c; tmp >> c >> lower >> shift; circumflexMap.insert(lower, shift); buf = t.readLine(); } // diaeresis else if (buf.contains(QRegExp("^\\s*d\\s+[0-9a-fx]+\\s+[0-9a-fx]+\\s*$", FALSE, FALSE))) { QTextStream tmp (buf, IO_ReadOnly); ushort lower, shift; QChar d; tmp >> d >> lower >> shift; diaeresisMap.insert(lower, shift); buf = t.readLine(); } // back accent else if (buf.contains(QRegExp("^\\s*b\\s+[0-9a-fx]+\\s+[0-9a-fx]+\\s*$", FALSE, FALSE))) { QTextStream tmp (buf, IO_ReadOnly); ushort lower, shift; QChar d; tmp >> d >> lower >> shift; baccentMap.insert(lower, shift); qDebug ("Estoy aadiendo %i con %i", lower, shift); buf = t.readLine(); } // accent else if (buf.contains(QRegExp("^\\s*a\\s+[0-9a-fx]+\\s+[0-9a-fx]+\\s*$", FALSE, FALSE))) { QTextStream tmp (buf, IO_ReadOnly); ushort lower, shift; QChar d; tmp >> d >> lower >> shift; accentMap.insert(lower, shift); buf = t.readLine(); } // other variables like lang & title else if (buf.contains(QRegExp("^\\s*[a-zA-Z]+\\s*=\\s*[a-zA-Z0-9/]+\\s*$", FALSE, FALSE))) { QTextStream tmp (buf, IO_ReadOnly); QString name, equals, value; tmp >> name >> equals >> value; if (name == "lang") { lang = value; } buf = t.readLine(); } // comments else if (buf.contains(QRegExp("^\\s*#"))) { buf = t.readLine(); } else { // blank line, or garbage buf = t.readLine(); } } + f.close(); + } else { + // We couldnt find the selected keymap, give them a configure button + QImage * btn = new QImage((const char ** )kb_config_xpm); + setKey(1, 0x1030, 0, 2, btn); } } + // Keys::setKey {{{2 void Keys::setKey(const int row, const int qcode, const ushort unicode, const int width, QImage *pix) { Key * key; key = new Key; key->qcode = qcode; key->unicode = unicode; key->width = width; // share key->pressed between same keys bool found = 0; for (int i = 1; i <= 5; i++) { for (unsigned int j = 0; j < keys[i].count(); j++) if (keys[i].at(j)->qcode == qcode && keys[i].at(j)->unicode == unicode) { key->pressed = keys[i].at(j)->pressed; found = 1; } } if (!found) { key->pressed = new bool; *(key->pressed) = 0; } key->pix = pix; keys[row].append(key); } // Keys::~Keys {{{2 Keys::~Keys() { for (int i = 1; i <= 5; i++) for (unsigned int j = 0; j < keys[i].count(); j++) delete keys[i].at(j); } // Keys:: other functions {{{2 int Keys::width(const int row, const int col) { return keys[row].at(col)->width; } int Keys::rows() { for (int i = 1; i <= 5; i++) { if (keys[i].count() == 0) return i - 1; } return 5; } ushort Keys::uni(const int row, const int col) { return keys[row].at(col)->unicode; } int Keys::qcode(const int row, const int col) { return keys[row].at(col)->qcode; } QImage *Keys::pix(const int row, const int col) { return keys[row].at(col)->pix; } bool Keys::pressed(const int row, const int col) { return *(keys[row].at(col)->pressed); } int Keys::numKeys(const int row) { return keys[row].count(); } void Keys::setPressed(const int row, const int col, const bool pressed) { *(keys[row].at(col)->pressed) = pressed; } ushort Keys::shift(const ushort uni) { if (shiftMap[uni]) return shiftMap[uni]; else return 0; } ushort Keys::meta(const ushort uni) { if (metaMap[uni]) return metaMap[uni]; else return 0; } ushort Keys::circumflex(const ushort uni) { if (circumflexMap[uni]) return circumflexMap[uni]; else return 0; } ushort Keys::diaeresis(const ushort uni) { if(diaeresisMap[uni]) return diaeresisMap[uni]; else return 0; } ushort Keys::baccent(const ushort uni) { if(baccentMap[uni]) return baccentMap[uni]; else return 0; } ushort Keys::accent(const ushort uni) { if(accentMap[uni]) return accentMap[uni]; else return 0; } bool *Keys::pressedPtr(const int row, const int col) { return keys[row].at(col)->pressed; } |