00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "keyboard.h"
00022 #include "configdlg.h"
00023
00024 #include <qpe/global.h>
00025 #include <qpe/qcopenvelope_qws.h>
00026
00027 #include <qwindowsystem_qws.h>
00028 #include <qpainter.h>
00029 #include <qfontmetrics.h>
00030 #include <qtimer.h>
00031 #include <qpe/qpeapplication.h>
00032 #include <qpe/config.h>
00033 #include <ctype.h>
00034 #include <qdir.h>
00035 #include <qtextstream.h>
00036 #include <qstringlist.h>
00037
00038 #include <sys/utsname.h>
00039
00040 using namespace MultiKey;
00041
00042 static const char * const kb_config_xpm[] = {
00043 "13 7 2 1",
00044 " c None",
00045 ". c #000000",
00046 " ",
00047 " . ",
00048 " ... ",
00049 " ..... ",
00050 " . ",
00051 " . ",
00052 " "};
00053
00054
00055 Keyboard::Keyboard(QWidget* parent, const char* _name, WFlags f) :
00056 QFrame(parent, _name, f), shift(0), lock(0), ctrl(0), alt(0),
00057 meta(0), circumflex(0), diaeresis(0), baccent(0), accent(0),
00058 useLargeKeys(TRUE), usePicks(0), useRepeat(0),
00059 pressedKeyRow(-1), pressedKeyCol(-1),
00060 unicode(-1), qkeycode(0), modifiers(0), schar(0), mchar(0), echar(0),
00061 configdlg(0)
00062
00063 {
00064
00065
00066 Config *config = new Config( "qpe" );
00067 config->setGroup( "Appearance" );
00068 QString familyStr = config->readEntry( "FontFamily", "smallsmooth" );
00069 int fontSize = config->readNumEntry( "FontSize", 10 );
00070 delete config;
00071
00072 config = new Config("multikey");
00073 config->setGroup ("general");
00074 usePicks = config->readBoolEntry ("usePickboard", 0);
00075 useRepeat = config->readBoolEntry ("useRepeat", 1);
00076 delete config;
00077
00078 setFont( QFont( familyStr, fontSize ) );
00079
00080 picks = new KeyboardPicks( this );
00081 picks->setFont( QFont( familyStr, fontSize ) );
00082 picks->initialise();
00083 if (usePicks) {
00084
00085 QObject::connect( picks, SIGNAL(key(ushort,ushort,ushort,bool,bool) ),
00086 this, SIGNAL(key(ushort,ushort,ushort,bool,bool)) );
00087
00088 } else picks->hide();
00089
00090 loadKeyboardColors();
00091
00092 keys = new Keys();
00093
00094 repeatTimer = new QTimer( this );
00095 connect( repeatTimer, SIGNAL(timeout()), this, SLOT(repeat()) );
00096
00097 QCopChannel* kbdChannel = new QCopChannel("MultiKey/Keyboard", this);
00098 connect(kbdChannel, SIGNAL(received(const QCString&,const QByteArray&)),
00099 this, SLOT(receive(const QCString&,const QByteArray&)));
00100 }
00101
00102 Keyboard::~Keyboard() {
00103
00104 if ( configdlg ) {
00105 delete configdlg;
00106 configdlg = 0;
00107 }
00108
00109 }
00110
00111
00112 void Keyboard::resizeEvent(QResizeEvent*)
00113 {
00114 int ph = picks->sizeHint().height();
00115 picks->setGeometry( 0, 0, width(), ph );
00116 keyHeight = (height()-(usePicks ? ph : 0))/(keys->rows()?keys->rows():1);
00117
00118 int nk;
00119 if ( useLargeKeys ) {
00120 nk = 15;
00121 } else {
00122 nk = 19;
00123 }
00124 defaultKeyWidth = (width()/nk)/2;
00125 xoffs = (width()-defaultKeyWidth*nk)/2;
00126
00127 }
00128
00129
00130 void KeyboardPicks::initialise()
00131 {
00132 setSizePolicy(QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed));
00133 mode = 0;
00134 dc = new KeyboardConfig(this);
00135 configs.append(dc);
00136 }
00137
00138
00139 QSize KeyboardPicks::sizeHint() const
00140 {
00141 return QSize(240,fontMetrics().lineSpacing());
00142 }
00143
00144
00145
00146 void KeyboardConfig::generateText(const QString &s)
00147 {
00148 #if defined(Q_WS_QWS) || defined(_WS_QWS_)
00149 for (int i=0; i<(int)backspaces; i++) {
00150 parent->emitKey( 0, ::Qt::Key_Backspace, 0, true, false );
00151 parent->emitKey( 0, ::Qt::Key_Backspace, 0, false, false );
00152 }
00153 for (int i=0; i<(int)s.length(); i++) {
00154 parent->emitKey( s[i].unicode(), 0, 0, true, false );
00155 parent->emitKey( s[i].unicode(), 0, 0, false, false );
00156 }
00157 parent->emitKey( 0, ::Qt::Key_Space, 0, true, false );
00158 parent->emitKey( 0, ::Qt::Key_Space, 0, false, false );
00159 backspaces = 0;
00160 #endif
00161 }
00162
00163
00164
00165
00166
00167 void Keyboard::paintEvent(QPaintEvent* e)
00168 {
00169 QPainter painter(this);
00170 painter.setClipRect(e->rect());
00171 drawKeyboard( painter );
00172 picks->dc->draw( &painter );
00173 }
00174
00175
00176
00177
00178 void Keyboard::drawKeyboard(QPainter &p, int row, int col)
00179 {
00180
00181
00182 if (row != -1 && col != -1) {
00183
00184 int x = 0;
00185 for (int i = 0; i < col; i++) {
00186
00187 x += keys->width(row, i) * defaultKeyWidth;
00188 }
00189 int y = (row - 1) * keyHeight + (usePicks ? picks->height() : 0);
00190
00191 int keyWidth = keys->width(row, col);
00192
00193 p.fillRect(x + 1, y + 1,
00194 keyWidth * defaultKeyWidth - 1, keyHeight - 1,
00195 pressed || keys->pressed(row, col) ? keycolor_pressed : keycolor);
00196
00197 QImage *pix = keys->pix(row,col);
00198
00199 ushort c = keys->uni(row, col);
00200
00201 p.setPen(textcolor);
00202 if (!pix) {
00203 if ((shift || lock) && keys->shift(c))
00204
00205 if (circumflex && keys->circumflex(keys->shift(c)))
00206 c = keys->circumflex(keys->shift(c));
00207 else if (diaeresis && keys->diaeresis(keys->shift(c)))
00208 c = keys->diaeresis(keys->shift(c));
00209 else if (baccent && keys->baccent(keys->shift(c)))
00210 c = keys->baccent(keys->shift(c));
00211 else if (accent && keys->accent(keys->shift(c)))
00212 c = keys->accent(keys->shift(c));
00213 else if (meta && keys->meta(keys->shift(c)))
00214 c = keys->meta(keys->shift(c));
00215 else
00216 c = keys->shift(c);
00217
00218 else if (meta && keys->meta(c))
00219 c = keys->meta(c);
00220 else if (circumflex && keys->circumflex(c))
00221 c = keys->circumflex(c);
00222 else if (baccent && keys->baccent(c))
00223 c = keys->baccent(c);
00224 else if (accent && keys->accent(c))
00225 c = keys->accent(c);
00226 else if (diaeresis && (keys->diaeresis(c) || c == 0x2c6)) {
00227
00228
00229
00230
00231 if (c == 0x2c6)
00232 c = 0xa8;
00233 else
00234 c = keys->diaeresis(c);
00235 }
00236
00237 p.drawText(x, y,
00238 defaultKeyWidth * keyWidth + 3, keyHeight,
00239 AlignCenter, (QChar)c);
00240 }
00241 else
00242
00243 p.drawImage( x + (defaultKeyWidth * keyWidth - pix->width())/2 + 1,
00244 y + (keyHeight - pix->height())/2 + 1,
00245 *pix );
00246
00247
00248
00249 p.setPen(keycolor_lines);
00250 p.drawLine(width() - 1, 0, width() - 1, height());
00251
00252 } else {
00253
00254
00255 p.fillRect(0, 0, width(), height(), keycolor);
00256
00257 for (row = 1; row <= keys->rows(); row++) {
00258
00259 int x = 0;
00260 int y = (row - 1) * keyHeight + (usePicks ? picks->height() : 0);
00261
00262 p.setPen(keycolor_lines);
00263 p.drawLine(x, y, x + width(), y);
00264
00265 for (int col = 0; col < keys->numKeys(row); col++) {
00266
00267 QImage *pix = keys->pix(row, col);
00268 int keyWidth = keys->width(row, col);
00269
00270
00271 int keyWidthPix = defaultKeyWidth * keyWidth;
00272
00273 if (keys->pressed(row, col))
00274 p.fillRect(x+1, y+1, keyWidthPix - 1,
00275 keyHeight - 1, keycolor_pressed);
00276
00277 ushort c = keys->uni(row, col);
00278
00279 p.setPen(textcolor);
00280 if (!pix) {
00281 if ((shift || lock) && keys->shift(c))
00282
00283 if (circumflex && keys->circumflex(keys->shift(c)))
00284 c = keys->circumflex(keys->shift(c));
00285 else if (diaeresis && keys->diaeresis(keys->shift(c)))
00286 c = keys->diaeresis(keys->shift(c));
00287 else if (baccent && keys->baccent(keys->shift(c)))
00288 c = keys->baccent(keys->shift(c));
00289 else if (accent && keys->accent(keys->shift(c)))
00290 c = keys->accent(keys->shift(c));
00291 else if (meta && keys->meta(keys->shift(c)))
00292 c = keys->meta(keys->shift(c));
00293 else
00294 c = keys->shift(c);
00295
00296 else if (meta && keys->meta(c))
00297 c = keys->meta(c);
00298 else if (circumflex && keys->circumflex(c))
00299 c = keys->circumflex(c);
00300 else if (baccent && keys->baccent(c))
00301 c = keys->baccent(c);
00302 else if (accent && keys->accent(c))
00303 c = keys->accent(c);
00304 else if (diaeresis && (keys->diaeresis(c) || c == 0x2c6)) {
00305
00306 if (c == 0x2c6)
00307 c = 0xa8;
00308 else
00309 c = keys->diaeresis(c);
00310 }
00311
00312 p.drawText(x, y,
00313 keyWidthPix + 3, keyHeight,
00314 AlignCenter, (QChar)c);
00315 }
00316 else {
00317
00318 pix->setColor(1, textcolor.rgb());
00319 p.drawImage( x + (keyWidthPix - pix->width())/2 + 1,
00320 y + (keyHeight - pix->height())/2 + 1,
00321 QImage(*pix) );
00322 }
00323
00324 p.setPen(keycolor_lines);
00325 p.drawLine(x, y, x, y + keyHeight);
00326
00327 x += keyWidthPix;
00328 }
00329
00330
00331 }
00332 p.setPen(keycolor_lines);
00333 p.drawLine(0, height() - 1, width(), height() - 1);
00334 p.drawLine(width() - 1, 0, width() - 1, height());
00335 }
00336
00337 }
00338
00339
00340
00341 void Keyboard::mousePressEvent(QMouseEvent *e)
00342 {
00343 int row = (e->y() - (usePicks ? picks->height() : 0)) / keyHeight + 1;
00344 if (row > 5) row = 5;
00345
00346
00347 int col = 0;
00348 for (int w = 0; e->x() >= w; col++)
00349 if (col < keys->numKeys(row))
00350 w += keys->width(row,col) * defaultKeyWidth;
00351 else break;
00352
00353 if (col <= 0) return;
00354
00355 col --;
00356
00357 qkeycode = keys->qcode(row, col);
00358 unicode = keys->uni(row, col);
00359
00360
00361
00362 bool need_repaint = FALSE;
00363
00364
00365
00366 if (unicode == 0x2c6) {
00367
00368 unicode = 0;
00369 if (shift || lock) {
00370
00371
00372 qkeycode = 0x2001;
00373 }
00374 else {
00375
00376
00377 qkeycode = 0x2000;
00378 }
00379 }
00380
00381
00382
00383
00384 if (unicode == 0x2cb) {
00385
00386 unicode = 0;
00387 if (shift || lock) {
00388
00389
00390 qkeycode = 0x2000;
00391 }
00392 else {
00393
00394
00395 qkeycode = 0x2002;
00396 }
00397 }
00398
00399
00400
00401 if (unicode == 0x2ca) {
00402
00403 unicode = 0;
00404 if (shift || lock) {
00405
00406
00407 qkeycode = 0x2001;
00408 }
00409 else {
00410
00411
00412 qkeycode = 0x2003;
00413 }
00414 }
00415
00416
00417 if (unicode == 0) {
00418
00419 if (qkeycode == Qt::Key_F1) {
00420
00421 if ( configdlg ) {
00422
00423 delete configdlg;
00424 configdlg = 0;
00425 }
00426 else {
00427 configdlg = new ConfigDlg ();
00428 connect(configdlg, SIGNAL(setMapToDefault()),
00429 this, SLOT(setMapToDefault()));
00430 connect(configdlg, SIGNAL(setMapToFile(QString)),
00431 this, SLOT(setMapToFile(QString)));
00432 connect(configdlg, SIGNAL(pickboardToggled(bool)),
00433 this, SLOT(togglePickboard(bool)));
00434 connect(configdlg, SIGNAL(repeatToggled(bool)),
00435 this, SLOT(toggleRepeat(bool)));
00436 connect(configdlg, SIGNAL(reloadKeyboard()),
00437 this, SLOT(reloadKeyboard()));
00438 connect(configdlg, SIGNAL(configDlgClosed()),
00439 this, SLOT(cleanupConfigDlg()));
00440 connect(configdlg, SIGNAL(reloadSw()),
00441 this, SLOT(reloadSw()));
00442 configdlg->showMaximized();
00443 configdlg->show();
00444 configdlg->raise();
00445 }
00446
00447 } else if (qkeycode == Qt::Key_Control) {
00448 need_repaint = TRUE;
00449
00450 if (ctrl) {
00451
00452 *ctrl = 0;
00453 ctrl = 0;
00454
00455 } else {
00456
00457 ctrl = keys->pressedPtr(row, col);
00458 need_repaint = TRUE;
00459 *ctrl = !keys->pressed(row, col);
00460
00461 }
00462
00463 } else if (qkeycode == Qt::Key_Alt) {
00464 need_repaint = TRUE;
00465
00466 if (alt) {
00467 *alt = 0;
00468 alt = 0;
00469
00470 } else {
00471
00472 alt = keys->pressedPtr(row, col);
00473 need_repaint = TRUE;
00474 *alt = !keys->pressed(row, col);
00475 }
00476
00477 } else if (qkeycode == Qt::Key_Shift) {
00478 need_repaint = TRUE;
00479
00480 if (shift) {
00481 *shift = 0;
00482 shift = 0;
00483 }
00484 else {
00485 shift = keys->pressedPtr(row, col);
00486 *shift = 1;
00487 if (lock) {
00488 *lock = 0;
00489 lock = 0;
00490 }
00491 }
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505 } else if (qkeycode == Qt::Key_CapsLock) {
00506 need_repaint = TRUE;
00507
00508 if (lock) {
00509 *lock = 0;
00510 lock = 0;
00511 }
00512 else {
00513 lock = keys->pressedPtr(row, col);;
00514 *lock = true;;
00515 if (shift) {
00516 *shift = 0;
00517 shift = 0;
00518 }
00519 }
00520
00521
00522
00523
00524
00525
00526
00527 } else if (qkeycode == Qt::Key_Meta) {
00528 need_repaint = TRUE;
00529
00530 if (meta) {
00531 *meta = 0;
00532 meta = 0;
00533
00534 } else {
00535
00536 meta = keys->pressedPtr(row, col);
00537 *meta = true;
00538 }
00539
00540
00541 if (shift) { *shift = 0; shift = 0; }
00542 if (lock) { *lock = 0; lock = 0; }
00543 if (circumflex) { *circumflex = 0; circumflex = 0; }
00544 if (diaeresis) { *diaeresis = 0; diaeresis = 0; }
00545 if (baccent) { *baccent = 0; baccent = 0; }
00546 if (accent) { *accent = 0; accent = 0; }
00547
00548
00549 qkeycode = 0;
00550
00551
00552 } else if (qkeycode == 0x2000) {
00553 need_repaint = TRUE;
00554
00555 if (circumflex) {
00556
00557 *circumflex = 0;
00558 circumflex = 0;
00559
00560 } else {
00561
00562 circumflex = keys->pressedPtr(row, col);
00563 *circumflex = true;
00564 }
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575 if (meta) { *meta = 0; meta = 0; }
00576 if (diaeresis) {
00577
00578
00579
00580
00581
00582
00583 *diaeresis = 0;
00584 diaeresis = 0;
00585 circumflex = 0;
00586 }
00587
00588 qkeycode = 0;
00589
00590
00591 } else if (qkeycode == 0x2001) {
00592 need_repaint = TRUE;
00593
00594 if (diaeresis) {
00595
00596 *diaeresis = 0;
00597 diaeresis = 0;
00598
00599 } else {
00600
00601 diaeresis = keys->pressedPtr(row, col);
00602 *diaeresis = true;
00603 }
00604
00605
00606 if (shift) { *shift = 0; shift = 0; }
00607
00608
00609
00610
00611
00612
00613
00614 if (meta) { *meta = 0; meta = 0; }
00615 if (circumflex) {
00616
00617
00618
00619
00620
00621 circumflex = 0;
00622 }
00623
00624
00625 qkeycode = 0;
00626
00627
00628 } else if (qkeycode == 0x2002) {
00629 need_repaint = TRUE;
00630
00631 if (baccent) {
00632
00633 *baccent = 0;
00634 baccent = 0;
00635
00636 } else {
00637
00638 baccent = keys->pressedPtr(row, col);
00639 *baccent = true;
00640 }
00641
00642
00643 if (shift) { *shift = 0; shift = 0; }
00644 if (meta) { *meta = 0; meta = 0; }
00645 if (accent) { *accent = 0; accent = 0; }
00646
00647 qkeycode = 0;
00648
00649
00650 } else if (qkeycode == 0x2003) {
00651 need_repaint = TRUE;
00652
00653 if (accent) {
00654
00655 *accent = 0;
00656 accent = 0;
00657
00658 } else {
00659
00660 accent = keys->pressedPtr(row, col);
00661 *accent = true;
00662 }
00663
00664
00665 if (shift) { *shift = 0; shift = 0; }
00666 if (meta) { *meta = 0; meta = 0; }
00667 if (baccent) { *baccent = 0; }
00668
00669 qkeycode = 0;
00670 }
00671
00672 }
00673 else {
00674 if ((shift || lock) && keys->shift(unicode)) {
00675
00676
00677
00678
00679 if (circumflex && keys->circumflex(keys->shift(unicode)))
00680 unicode = keys->circumflex(keys->shift(unicode));
00681 else if (diaeresis && keys->diaeresis(keys->shift(unicode)))
00682 unicode = keys->diaeresis(keys->shift(unicode));
00683 else if (baccent && keys->baccent(keys->shift(unicode)))
00684 unicode = keys->baccent(keys->shift(unicode));
00685 else if (accent && keys->accent(keys->shift(unicode)))
00686 unicode = keys->accent(keys->shift(unicode));
00687 else if (meta && keys->meta(keys->shift(unicode)))
00688 unicode = keys->meta(keys->shift(unicode));
00689 else
00690 unicode = keys->shift(unicode);
00691 }
00692 else if (meta && keys->meta(unicode)) {
00693 unicode = keys->meta(unicode);
00694 }
00695 else if (circumflex && keys->circumflex(unicode)) {
00696 unicode = keys->circumflex(unicode);
00697 }
00698 else if (diaeresis && keys->diaeresis(unicode)) {
00699
00700 unicode = keys->diaeresis(unicode);
00701 }
00702 else if (baccent && keys->baccent(unicode)) {
00703 unicode = keys->baccent(unicode);
00704 }
00705 else if (accent && keys->accent(unicode)) {
00706 unicode = keys->accent(unicode);
00707 }
00708 }
00709
00710
00711 if (keys->lang == "ko") {
00712
00713 unicode = parseKoreanInput(unicode);
00714 }
00715
00716 modifiers = (ctrl ? Qt::ControlButton : 0) | (alt ? Qt::AltButton : 0);
00717
00718 if ('A' <= unicode && unicode <= 'z' && modifiers) {
00719
00720 qkeycode = QChar(unicode).upper();
00721 unicode = qkeycode - '@';
00722 }
00723
00724 QWSServer::sendKeyEvent(unicode, qkeycode, modifiers, true, false);
00725
00726
00727 if (usePicks) {
00728
00729 KeyboardConfig *dc = picks->dc;
00730
00731 if (dc) {
00732 if (qkeycode == Qt::Key_Backspace) {
00733 dc->input.remove(dc->input.last());
00734 dc->decBackspaces();
00735 } else if ( qkeycode == Qt::Key_Return || QChar(unicode).isPunct() || QChar(unicode).isSpace() || unicode == 0) {
00736 dc->input.clear();
00737 dc->resetBackspaces();
00738 } else {
00739 dc->add(QString(QChar(unicode)));
00740 dc->incBackspaces();
00741 }
00742 }
00743 picks->repaint();
00744 }
00745
00746
00747
00748 pressed = TRUE;
00749
00750 pressedKeyRow = row;
00751 pressedKeyCol = col;
00752
00753 if (need_repaint) repaint(FALSE);
00754 else {
00755
00756
00757
00758 QPainter p(this);
00759 drawKeyboard(p, row, col);
00760
00761 }
00762
00763 if (useRepeat) repeatTimer->start( 800 );
00764
00765
00766 }
00767
00768 void Keyboard::receive(const QCString &msg, const QByteArray &data)
00769 {
00770 if (msg == "setmultikey(QString)") {
00771 QDataStream stream(data, IO_ReadOnly);
00772 QString map;
00773 stream >> map;
00774 setMapToFile(map);
00775 } else if (msg == "getmultikey()") {
00776 reloadSw();
00777 }
00778 }
00779
00780
00781 void Keyboard::mouseReleaseEvent(QMouseEvent*)
00782 {
00783 pressed = FALSE;
00784
00785 #if defined(Q_WS_QWS) || defined(_WS_QWS_)
00786 if ( unicode != -1 ) {
00787 emit key( unicode, qkeycode, modifiers, false, false );
00788 repeatTimer->stop();
00789 }
00790 #endif
00791 if (shift && unicode != 0) {
00792
00793
00794 *shift = 0;
00795 shift = 0;
00796 repaint(FALSE);
00797
00798 }
00799 if (ctrl && unicode != 0) {
00800
00801 *ctrl = 0;
00802 ctrl = 0;
00803 repaint(FALSE);
00804
00805 }
00806 if (alt && alt != 0) {
00807
00808 *alt = 0;
00809 alt = 0;
00810 repaint(FALSE);
00811
00812 }
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827 else clearHighlight();
00828 }
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848 void Keyboard::repeat()
00849 {
00850
00851 repeatTimer->start( 200 );
00852 emit key( unicode, qkeycode, modifiers, true, true );
00853 }
00854
00855 void Keyboard::clearHighlight()
00856 {
00857 if ( pressedKeyRow >= 0 && pressedKeyCol >= 0) {
00858 int tmpRow = pressedKeyRow;
00859 int tmpCol = pressedKeyCol;
00860
00861 pressedKeyRow = -1;
00862 pressedKeyCol = -1;
00863
00864 QPainter p(this);
00865 drawKeyboard(p, tmpRow, tmpCol);
00866 }
00867 }
00868
00869
00870
00871 QSize Keyboard::sizeHint() const
00872 {
00873 QFontMetrics fm=fontMetrics();
00874 int keyHeight = fm.lineSpacing() + 2;
00875
00876 return QSize( 240, keyHeight * keys->rows() + (usePicks ? picks->sizeHint().height() : 0) + 1);
00877 }
00878
00879
00880 void Keyboard::resetState()
00881 {
00882 if (shift) { *shift = 0; shift = 0; }
00883 if (lock) {*lock = 0; lock = 0; }
00884 if (meta) { *meta = 0; meta = 0; }
00885 if (circumflex) { *circumflex = 0; circumflex = 0; }
00886 if (diaeresis) { *diaeresis = 0; diaeresis = 0; }
00887 if (baccent) { *baccent = 0; baccent = 0; }
00888 if (accent) { *accent = 0; accent = 0; }
00889
00890 schar = mchar = echar = 0;
00891 picks->resetState();
00892 }
00893
00894
00895 void Keyboard::togglePickboard(bool on_off)
00896 {
00897 usePicks = on_off;
00898 if (usePicks) {
00899 picks->show();
00900
00901
00902 QObject::connect( picks, SIGNAL(key(ushort,ushort,ushort,bool,bool) ),
00903 this, SIGNAL(key(ushort,ushort,ushort,bool,bool)) );
00904 } else {
00905
00906 picks->hide();
00907 picks->resetState();
00908
00909
00910 QObject::disconnect( picks, SIGNAL(key(ushort,ushort,ushort,bool,bool) ),
00911 this, SIGNAL(key(ushort,ushort,ushort,bool,bool)) );
00912
00913 }
00914
00915
00916
00917 QCopChannel::send ("QPE/TaskBar", "hideInputMethod()");
00918 QCopChannel::send ("QPE/TaskBar", "showInputMethod()");
00919 }
00920
00921 void Keyboard::toggleRepeat(bool on) {
00922
00923 useRepeat = on;
00924
00925 }
00926
00927 void Keyboard::cleanupConfigDlg() {
00928
00929 if ( configdlg ) {
00930 delete configdlg;
00931 configdlg = 0;
00932 }
00933 }
00934
00935 void Keyboard::reloadSw() {
00936 QCopEnvelope e("MultiKey/Switcher", "setsw(QString,QString)");
00937
00938 Config* config = new Config("multikey");
00939 config->setGroup("keymaps");
00940 QString current_map = config->readEntry("current", "en.keymap");
00941 delete config;
00942
00943 e << ConfigDlg::loadSw().join("|") << current_map;
00944 }
00945
00946
00947 void Keyboard::setMapToDefault() {
00948
00949
00950
00951 Config *config = new Config("locale");
00952 config->setGroup( "Language" );
00953 QString l = config->readEntry( "Language" , "en" );
00954 delete config;
00955
00956
00957 int d = l.find('_');
00958 if (d != -1) {
00959 l.remove(d, l.length()-d);
00960 }
00961 QString key_map = QPEApplication::qpeDir() + "share/multikey/"
00962 + l + ".keymap";
00963
00964
00965 config = new Config("multikey");
00966 config->setGroup ("keymaps");
00967 config->writeEntry ("current", key_map);
00968 delete config;
00969
00970 int prevRows = keys->rows();
00971
00972 delete keys;
00973 keys = new Keys(key_map);
00974
00975
00976 if (prevRows != keys->rows()) {
00977
00978 QCopChannel::send ("QPE/TaskBar", "hideInputMethod()");
00979 QCopChannel::send ("QPE/TaskBar", "showInputMethod()");
00980
00981 } else repaint(FALSE);
00982
00983 resetState();
00984 }
00985
00986 void Keyboard::setMapToFile(QString map) {
00987
00988
00989 Config *config = new Config("multikey");
00990 config->setGroup ("keymaps");
00991 config->writeEntry ("current", map);
00992
00993 delete config;
00994
00995 int prevRows = keys->rows();
00996
00997 delete keys;
00998 if (QFile(map).exists())
00999 keys = new Keys(map);
01000 else
01001 keys = new Keys();
01002
01003 if (keys->rows() != prevRows) {
01004
01005 QCopChannel::send ("QPE/TaskBar", "hideInputMethod()");
01006 QCopChannel::send ("QPE/TaskBar", "showInputMethod()");
01007 }
01008 else repaint(FALSE);
01009
01010 resetState();
01011 }
01012
01013
01014 void Keyboard::reloadKeyboard() {
01015
01016
01017 loadKeyboardColors();
01018 repaint();
01019
01020 }
01021
01022 void Keyboard::loadKeyboardColors() {
01023
01024 Config config ("multikey");
01025 config.setGroup("colors");
01026
01027 QStringList color;
01028 color = config.readListEntry("keycolor", QChar(','));
01029 if (color.isEmpty()) {
01030 color = QStringList::split(",", "240,240,240");
01031 config.writeEntry("keycolor", color.join(","));
01032
01033 }
01034 keycolor = QColor(color[0].toInt(), color[1].toInt(), color[2].toInt());
01035
01036 color = config.readListEntry("keycolor_pressed", QChar(','));
01037 if (color.isEmpty()) {
01038 color = QStringList::split(",", "171,183,198");
01039 config.writeEntry("keycolor_pressed", color.join(","));
01040
01041 }
01042 keycolor_pressed = QColor(color[0].toInt(), color[1].toInt(), color[2].toInt());
01043
01044 color = config.readListEntry("keycolor_lines", QChar(','));
01045 if (color.isEmpty()) {
01046 color = QStringList::split(",", "138,148,160");
01047 config.writeEntry("keycolor_lines", color.join(","));
01048
01049 }
01050 keycolor_lines = QColor(color[0].toInt(), color[1].toInt(), color[2].toInt());
01051
01052 color = config.readListEntry("textcolor", QChar(','));
01053 if (color.isEmpty()) {
01054 color = QStringList::split(",", "43,54,68");
01055 config.writeEntry("textcolor", color.join(","));
01056
01057 }
01058 textcolor = QColor(color[0].toInt(), color[1].toInt(), color[2].toInt());
01059
01060 }
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090 ushort Keyboard::parseKoreanInput (ushort c) {
01091
01092 if ((c != 0 && (c < 0x1100 || 0x11c2 < c) && (c < 0xac00 || 0xd7a3 < c))
01093 ||
01094 (c == 0 && qkeycode != Qt::Key_Shift && Qt::Key_CapsLock != qkeycode
01095 && qkeycode != Qt::Key_Control && qkeycode != Qt::Key_Alt)) {
01096
01097 schar = 0, mchar = 0, echar = 0;
01098 return c;
01099 }
01100
01101 if ( 0x1100 <= c && c <= 0x1112 ) {
01102
01103 if (schar == 0 || (schar != 0 && mchar == 0)) {
01104 schar = c; mchar = 0; echar = 0;
01105 return c;
01106 }
01107 else if (mchar != 0) {
01108
01109 if (echar == 0) {
01110
01111 if (!(echar = constoe(c))) {
01112
01113 schar = c; mchar = 0; echar = 0;
01114 return c;
01115 }
01116
01117 }
01118 else {
01119
01120 if (echar == 0x11a8) {
01121
01122 if (c == 0x1100) echar = 0x11a9;
01123 else if (c == 0x1109) echar = 0x11aa;
01124 else {
01125 schar = c; mchar = 0; echar = 0;
01126 return c;
01127 }
01128
01129 } else if (echar == 0x11ab) {
01130
01131 if (c == 0x110c) echar = 0x11ac;
01132 else if (c == 0x1112) echar = 0x11ad;
01133 else {
01134 schar = c; mchar = 0; echar = 0;
01135 return c;
01136 }
01137
01138 } else if (echar == 0x11af) {
01139
01140 if (c == 0x1100) echar = 0x11b0;
01141 else if (c == 0x1106) echar = 0x11b1;
01142 else if (c == 0x1107) echar = 0x11b2;
01143 else if (c == 0x1109) echar = 0x11b3;
01144 else if (c == 0x1110) echar = 0x11b4;
01145 else if (c == 0x1111) echar = 0x11b5;
01146 else if (c == 0x1112) echar = 0x11b6;
01147 else {
01148 schar = c; mchar = 0; echar = 0;
01149 return c;
01150 }
01151
01152 } else if (echar == 0x11b8) {
01153
01154 if (c == 0x1109) echar = 0x11b9;
01155 else {
01156 schar = c; mchar = 0; echar = 0;
01157 return c;
01158 }
01159
01160 } else if (echar == 0x11ba) {
01161
01162 if (c == 0x1109) echar = 0x11bb;
01163 else {
01164 schar = c; mchar = 0; echar = 0;
01165 return c;
01166 }
01167
01168 } else {
01169
01170 schar = c; mchar = 0; echar = 0;
01171 return c;
01172 }
01173
01174 unicode = echar;
01175 }
01176 }
01177
01178 }
01179 else if (0x1161 <= c && c <= 0x1175) {
01180
01181 if (schar != 0 && mchar == 0) { mchar = c; }
01182
01183 else if (schar != 0 && mchar != 0 && echar == 0) {
01184
01185 switch (mchar) {
01186 case 0x1169:
01187 if (c == 0x1161) mchar = 0x116a;
01188 else if (c == 0x1162) mchar = 0x116b;
01189 else if (c == 0x1175) mchar = 0x116c;
01190 else {
01191 schar = 0; mchar = 0; echar = 0;
01192 return c;
01193 }
01194 break;
01195 case 0x116e:
01196 if (c == 0x1165) mchar = 0x116f;
01197 else if (c == 0x1166) mchar = 0x1170;
01198 else if (c == 0x1175) mchar = 0x1171;
01199 else {
01200 schar = 0; mchar = 0; echar = 0;
01201 return c;
01202 }
01203 break;
01204 case 0x1173:
01205 if (c == 0x1175) mchar = 0x1174;
01206 else {
01207 schar = 0; mchar = 0; echar = 0;
01208 return c;
01209 }
01210 break;
01211 default:
01212 schar = 0; mchar = 0; echar = 0;
01213 return c;
01214 }
01215 }
01216 else if (schar != 0 && mchar != 0 && echar != 0) {
01217
01218 emit key( 8, Qt::Key_Backspace, 0, true, false );
01219
01220 ushort prev = 0;
01221 switch (echar) {
01222
01223
01224
01225
01226
01227
01228 case 0x11aa:
01229 prev = combineKoreanChars(schar, mchar, 0x11a8);
01230 schar = 0x1109;
01231 break;
01232 case 0x11ac:
01233 prev = combineKoreanChars(schar, mchar, 0x11ab);
01234 schar = 0x110c;
01235 break;
01236 case 0x11ad:
01237 prev = combineKoreanChars(schar, mchar, 0x11ab);
01238 schar = 0x1112;
01239 break;
01240 case 0x11b0:
01241 prev = combineKoreanChars(schar, mchar, 0x11af);
01242 schar = 0x1100;
01243 break;
01244 case 0x11b1:
01245 prev = combineKoreanChars(schar, mchar, 0x11af);
01246 schar = 0x1106;
01247 break;
01248 case 0x11b2:
01249 prev = combineKoreanChars(schar, mchar, 0x11af);
01250 schar = 0x1107;
01251 break;
01252 case 0x11b3:
01253 prev = combineKoreanChars(schar, mchar, 0x11af);
01254 schar = 0x1109;
01255 break;
01256 case 0x11b4:
01257 prev = combineKoreanChars(schar, mchar, 0x11af);
01258 schar = 0x1110;
01259 break;
01260 case 0x11b9:
01261 prev = combineKoreanChars(schar, mchar, 0x11b8);
01262 schar = 0x1109;
01263 break;
01264
01265
01266
01267
01268
01269
01270 default:
01271
01272 if (constoe(echar)) {
01273
01274 prev = combineKoreanChars(schar, mchar, 0);
01275 schar = constoe(echar);
01276 }
01277 break;
01278 }
01279
01280 emit key( prev, prev, 0, true, false );
01281
01282 mchar = c; echar = 0;
01283
01284 return combineKoreanChars(schar, mchar, 0);
01285
01286 }
01287 else {
01288 schar = 0; mchar = 0; echar = 0;
01289 return c;
01290 }
01291
01292 }
01293 else return c;
01294
01295
01296
01297 emit key( 8, Qt::Key_Backspace, 0, true, false );
01298
01299
01300 return combineKoreanChars( schar, mchar, echar);
01301
01302 }
01303
01304 ushort Keyboard::combineKoreanChars(const ushort s, const ushort m, const ushort e) {
01305
01306 return ((s - 0x1100) * 588) + ((m - 0x1161) * 28) + (e ? e - 0x11a7 : 0) + 0xac00;
01307
01308 }
01309
01310 ushort Keyboard::constoe(const ushort c) {
01311
01312
01313
01314 if (0x1100 <= c && c <= 0x1112) {
01315
01316 switch (c) {
01317 case 0x1100: return 0x11a8;
01318 case 0x1101: return 0x11a9;
01319 case 0x1102: return 0x11ab;
01320 case 0x1103: return 0x11ae;
01321 case 0x1105: return 0x11af;
01322 case 0x1106: return 0x11b7;
01323 case 0x1107: return 0x11b8;
01324 case 0x1109: return 0x11ba;
01325 case 0x110a: return 0x11bb;
01326 case 0x110b: return 0x11bc;
01327 case 0x110c: return 0x11bd;
01328 case 0x110e: return 0x11be;
01329 case 0x110f: return 0x11bf;
01330 case 0x1110: return 0x11c0;
01331 case 0x1111: return 0x11c1;
01332 case 0x1112: return 0x11c2;
01333 default: return 0;
01334
01335 }
01336
01337 } else {
01338
01339 switch (c) {
01340 case 0x11a8: return 0x1100;
01341 case 0x11a9: return 0x1101;
01342 case 0x11ab: return 0x1102;
01343 case 0x11ae: return 0x1103;
01344 case 0x11af: return 0x1105;
01345 case 0x11b7: return 0x1106;
01346 case 0x11b8: return 0x1107;
01347 case 0x11ba: return 0x1109;
01348 case 0x11bb: return 0x110a;
01349 case 0x11bc: return 0x110b;
01350 case 0x11bd: return 0x110c;
01351 case 0x11be: return 0x110e;
01352 case 0x11bf: return 0x110f;
01353 case 0x11c0: return 0x1110;
01354 case 0x11c1: return 0x1111;
01355 case 0x11c2: return 0x1112;
01356 default: return 0;
01357
01358 }
01359
01360 }
01361 }
01362
01363
01364
01365
01366 Keys::Keys() {
01367
01368 Config *config = new Config ("multikey");
01369 config->setGroup( "keymaps" );
01370 QString map = config->readEntry( "current" );
01371 delete config;
01372
01373 if (map.isNull() || !(QFile(map).exists())) {
01374
01375 Config *config = new Config("locale");
01376 config->setGroup( "Language" );
01377 QString l = config->readEntry( "Language" , "en" );
01378 delete config;
01379
01380 map = QPEApplication::qpeDir() + "share/multikey/"
01381 + l + ".keymap";
01382
01383 }
01384 if (map.isNull() || !(QFile(map).exists())) {
01385 map = QPEApplication::qpeDir() + "share/multikey/en.keymap";
01386 }
01387
01388 setKeysFromFile(map);
01389 }
01390
01391 Keys::Keys(const char * filename) {
01392
01393 setKeysFromFile(filename);
01394 }
01395
01396
01397 void Keys::setKeysFromFile(const char * filename) {
01398
01399 QFile f(filename);
01400
01401 if (f.open(IO_ReadOnly)) {
01402
01403 QTextStream t(&f);
01404 int row;
01405 int qcode;
01406 ushort unicode;
01407 int width;
01408 QString buf;
01409 QString comment;
01410 char * xpm[256];
01411 QImage *xpm2pix = 0;
01412
01413 buf = t.readLine();
01414 while (buf) {
01415
01416
01417 buf.replace(QRegExp("#.*$", FALSE, FALSE), "");
01418
01419
01420 if (buf.contains(QRegExp("^\\d+\\s+[0-1a-fx]+", FALSE, FALSE))) {
01421
01422
01423
01424 QTextStream tmp (buf, IO_ReadOnly);
01425 tmp >> row >> qcode >> unicode >> width >> comment;
01426
01427 buf = t.readLine();
01428 int xpmLineCount = 0;
01429 xpm2pix = 0;
01430
01431
01432 while (buf.contains(QRegExp("^\\s*$")) && buf) buf = t.readLine();
01433
01434 while (buf.contains(QRegExp("^\\s*\".*\""))) {
01435
01436 QString xpmBuf = buf.stripWhiteSpace();
01437
01438 xpm[xpmLineCount] = new char [xpmBuf.length()];
01439
01440 int j = 0;
01441 for (ushort i = 0; i < xpmBuf.length(); i++) {
01442 if (xpmBuf[i].latin1() != '"') {
01443
01444 ((char *)xpm[xpmLineCount])[j] = xpmBuf.at(i).latin1();
01445 j++;
01446 }
01447
01448 }
01449
01450 ((char *)xpm[xpmLineCount])[j] = '\0';
01451
01452 xpmLineCount++;
01453 buf = t.readLine();
01454 }
01455 if (xpmLineCount) {
01456
01457 xpm2pix = new QImage((const char **)xpm);
01458 for (int i = 0; i < xpmLineCount; i++)
01459
01460 delete [] (xpm[i]);
01461
01462 }
01463 setKey(row, qcode, unicode, width, xpm2pix);
01464 }
01465
01466
01467 else if (buf.contains(QRegExp("^[0-9a-fx]+\\s+[0-9a-fx]+\\s*$", FALSE, FALSE))) {
01468
01469 QTextStream tmp (buf, IO_ReadOnly);
01470 ushort lower, shift;
01471 tmp >> lower >> shift;
01472
01473 shiftMap.insert(lower, shift);
01474
01475 buf = t.readLine();
01476 }
01477
01478
01479 else if (buf.contains(QRegExp("^\\s*m\\s+[0-9a-fx]+\\s+[0-9a-fx]+\\s*$", FALSE, FALSE))) {
01480
01481 QTextStream tmp (buf, IO_ReadOnly);
01482 ushort lower, shift;
01483 QChar m;
01484 tmp >> m >> lower >> shift;
01485
01486 metaMap.insert(lower, shift);
01487
01488 buf = t.readLine();
01489 }
01490
01491
01492 else if (buf.contains(QRegExp("^\\s*c\\s+[0-9a-fx]+\\s+[0-9a-fx]+\\s*$", FALSE, FALSE))) {
01493
01494 QTextStream tmp (buf, IO_ReadOnly);
01495 ushort lower, shift;
01496 QChar c;
01497 tmp >> c >> lower >> shift;
01498
01499 circumflexMap.insert(lower, shift);
01500
01501 buf = t.readLine();
01502 }
01503
01504 else if (buf.contains(QRegExp("^\\s*d\\s+[0-9a-fx]+\\s+[0-9a-fx]+\\s*$", FALSE, FALSE))) {
01505
01506 QTextStream tmp (buf, IO_ReadOnly);
01507 ushort lower, shift;
01508 QChar d;
01509 tmp >> d >> lower >> shift;
01510
01511 diaeresisMap.insert(lower, shift);
01512
01513 buf = t.readLine();
01514 }
01515
01516 else if (buf.contains(QRegExp("^\\s*b\\s+[0-9a-fx]+\\s+[0-9a-fx]+\\s*$", FALSE, FALSE))) {
01517
01518 QTextStream tmp (buf, IO_ReadOnly);
01519 ushort lower, shift;
01520 QChar d;
01521 tmp >> d >> lower >> shift;
01522
01523 baccentMap.insert(lower, shift);
01524
01525 qDebug ("Estoy aadiendo %i con %i", lower, shift);
01526 buf = t.readLine();
01527 }
01528
01529 else if (buf.contains(QRegExp("^\\s*a\\s+[0-9a-fx]+\\s+[0-9a-fx]+\\s*$", FALSE, FALSE))) {
01530
01531 QTextStream tmp (buf, IO_ReadOnly);
01532 ushort lower, shift;
01533 QChar d;
01534 tmp >> d >> lower >> shift;
01535
01536 accentMap.insert(lower, shift);
01537
01538 buf = t.readLine();
01539 }
01540
01541
01542 else if (buf.contains(QRegExp("^\\s*[a-zA-Z]+\\s*=\\s*[a-zA-Z0-9/]+\\s*$", FALSE, FALSE))) {
01543
01544 QTextStream tmp (buf, IO_ReadOnly);
01545 QString name, equals, value;
01546
01547 tmp >> name >> equals >> value;
01548
01549 if (name == "lang") {
01550
01551 lang = value;
01552
01553 }
01554
01555 buf = t.readLine();
01556 }
01557
01558 else if (buf.contains(QRegExp("^\\s*#"))) {
01559
01560 buf = t.readLine();
01561
01562 } else {
01563
01564 buf = t.readLine();
01565
01566 }
01567
01568 }
01569
01570 f.close();
01571 } else {
01572
01573 QImage * btn = new QImage((const char ** )kb_config_xpm);
01574 setKey(1, 0x1030, 0, 2, btn);
01575 }
01576
01577 }
01578
01579
01580
01581 void Keys::setKey(const int row, const int qcode, const ushort unicode,
01582 const int width, QImage *pix) {
01583
01584 Key * key;
01585 key = new Key;
01586 key->qcode = qcode;
01587 key->unicode = unicode;
01588 key->width = width;
01589
01590
01591 bool found = 0;
01592 for (int i = 1; i <= 5; i++) {
01593 for (unsigned int j = 0; j < keys[i].count(); j++)
01594 if (keys[i].at(j)->qcode == qcode && keys[i].at(j)->unicode == unicode) {
01595
01596 key->pressed = keys[i].at(j)->pressed;
01597 found = 1;
01598 }
01599
01600 }
01601 if (!found) {
01602
01603 key->pressed = new bool;
01604 *(key->pressed) = 0;
01605 }
01606
01607 key->pix = pix;
01608
01609
01610 keys[row].append(key);
01611 }
01612
01613
01614 Keys::~Keys() {
01615
01616 for (int i = 1; i <= 5; i++)
01617 for (unsigned int j = 0; j < keys[i].count(); j++)
01618 delete keys[i].at(j);
01619
01620 }
01621
01622
01623 int Keys::width(const int row, const int col) {
01624
01625 return keys[row].at(col)->width;
01626
01627 }
01628
01629 int Keys::rows() {
01630
01631 for (int i = 1; i <= 5; i++) {
01632
01633 if (keys[i].count() == 0)
01634 return i - 1;
01635
01636 }
01637 return 5;
01638 }
01639
01640 ushort Keys::uni(const int row, const int col) {
01641
01642 return keys[row].at(col)->unicode;
01643
01644 }
01645
01646 int Keys::qcode(const int row, const int col) {
01647
01648 return keys[row].at(col)->qcode;
01649 }
01650
01651 QImage *Keys::pix(const int row, const int col) {
01652
01653 return keys[row].at(col)->pix;
01654
01655 }
01656 bool Keys::pressed(const int row, const int col) {
01657
01658 return *(keys[row].at(col)->pressed);
01659 }
01660
01661 int Keys::numKeys(const int row) {
01662
01663 return keys[row].count();
01664 }
01665
01666 void Keys::setPressed(const int row, const int col, const bool pressed) {
01667
01668 *(keys[row].at(col)->pressed) = pressed;
01669 }
01670
01671 ushort Keys::shift(const ushort uni) {
01672
01673 if (shiftMap[uni]) return shiftMap[uni];
01674 else return 0;
01675 }
01676
01677 ushort Keys::meta(const ushort uni) {
01678
01679 if (metaMap[uni]) return metaMap[uni];
01680 else return 0;
01681 }
01682
01683 ushort Keys::circumflex(const ushort uni) {
01684
01685 if (circumflexMap[uni]) return circumflexMap[uni];
01686 else return 0;
01687 }
01688
01689 ushort Keys::diaeresis(const ushort uni) {
01690
01691 if(diaeresisMap[uni]) return diaeresisMap[uni];
01692 else return 0;
01693 }
01694
01695 ushort Keys::baccent(const ushort uni) {
01696
01697 if(baccentMap[uni]) return baccentMap[uni];
01698 else return 0;
01699 }
01700
01701 ushort Keys::accent(const ushort uni) {
01702
01703 if(accentMap[uni]) return accentMap[uni];
01704 else return 0;
01705 }
01706
01707 bool *Keys::pressedPtr(const int row, const int col) {
01708
01709 return keys[row].at(col)->pressed;
01710 }