Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

dvorak.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2000 Trolltech AS.  All rights reserved.
00003 **
00004 ** This file is part of Qtopia Environment.
00005 **
00006 ** This file may be distributed and/or modified under the terms of the
00007 ** GNU General Public License version 2 as published by the Free Software
00008 ** Foundation and appearing in the file LICENSE.GPL included in the
00009 ** packaging of this file.
00010 **
00011 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 **
00014 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00015 **
00016 ** Contact info@trolltech.com if any conditions of this licensing are
00017 ** not clear to you.
00018 **
00019 **********************************************************************/
00020 
00021 #include "dvorak.h"
00022 
00023 #include <qpe/global.h>
00024 #include <qpe/config.h>
00025 #include <qwindowsystem_qws.h>
00026 #include <qpainter.h>
00027 #include <qfontmetrics.h>
00028 #include <qtimer.h>
00029 #include <ctype.h>
00030 
00031 
00032 #define USE_SMALL_BACKSPACE
00033 
00034 using namespace Dvorak;
00035 
00036 Keyboard::Keyboard(QWidget* parent, const char* name, WFlags f) :
00037     QFrame(parent, name, f),  shift(FALSE), lock(FALSE), ctrl(FALSE),
00038     alt(FALSE), useLargeKeys(TRUE), useOptiKeys(0), pressedKey(-1),
00039     unicode(-1), qkeycode(0), modifiers(0)
00040 {
00041     //  setPalette(QPalette(QColor(240,240,230))); // Beige!
00042     //  setFont( QFont( "Helvetica", 8 ) );
00043 //    setPalette(QPalette(QColor(200,200,200))); // Gray
00044     setPalette(QPalette(QColor(220,220,220))); // Gray
00045 
00046     // get the default font
00047     Config *config = new Config( "qpe" );
00048     config->setGroup( "Appearance" );
00049     QString familyStr = config->readEntry( "FontFamily", "smallsmooth" );
00050     int fontSize = config->readNumEntry( "FontSize", 10 );
00051     delete config;
00052 
00053     picks = new KeyboardPicks( this );
00054     picks->setFont( QFont( familyStr, fontSize ) );
00055     setFont( QFont( familyStr, fontSize ) );
00056     picks->initialise();
00057     QObject::connect( picks, SIGNAL(key(ushort,ushort,ushort,bool,bool) ),
00058             this, SIGNAL(key(ushort,ushort,ushort,bool,bool)) );
00059 
00060     repeatTimer = new QTimer( this );
00061     connect( repeatTimer, SIGNAL(timeout()), this, SLOT(repeat()) );
00062 }
00063 
00064 void Keyboard::resizeEvent(QResizeEvent*)
00065 {
00066     int ph = picks->sizeHint().height();
00067     picks->setGeometry( 0, 0, width(), ph );
00068     keyHeight = (height()-ph)/5;
00069     int nk;
00070     if ( useOptiKeys ) {
00071         nk = 15;
00072     } else if ( useLargeKeys ) {
00073         nk = 15;
00074     } else {
00075         nk = 19;
00076     }
00077     defaultKeyWidth = width()/nk;
00078     xoffs = (width()-defaultKeyWidth*nk)/2;
00079 }
00080 
00081 void KeyboardPicks::initialise()
00082 {
00083     setSizePolicy(QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed));
00084     mode = 0;
00085     dc = new KeyboardConfig(this);
00086     configs.append(dc);
00087 }
00088 
00089 QSize KeyboardPicks::sizeHint() const
00090 {
00091     return QSize(240,fontMetrics().lineSpacing());
00092 }
00093 
00094 
00095 void  KeyboardConfig::generateText(const QString &s)
00096 {
00097 #if defined(Q_WS_QWS) || defined(_WS_QWS_)
00098     for (int i=0; i<(int)backspaces; i++) {
00099         parent->emitKey( 0, ::Qt::Key_Backspace, 0, true, false );
00100         parent->emitKey( 0, ::Qt::Key_Backspace, 0, false, false );
00101     }
00102     for (int i=0; i<(int)s.length(); i++) {
00103         parent->emitKey( s[i].unicode(), 0, 0, true, false );
00104         parent->emitKey( s[i].unicode(), 0, 0, false, false );
00105     }
00106     parent->emitKey( 0, ::Qt::Key_Space, 0, true, false );
00107     parent->emitKey( 0, ::Qt::Key_Space, 0, false, false );
00108     backspaces = 0;
00109 #endif
00110 }
00111 
00112 
00113 //PC keyboard layout and scancodes
00114 
00115 /*
00116   Format: length, code, length, code, ..., 0
00117   
00118   length is measured in half the width of a standard key.
00119   If code < 0x80 we have length/2 consecutive standard keys,
00120   starting with scancode code.
00121   
00122   Special keys are hardcoded, one at a time, with length of key
00123   and code >= 0x80, these are NOT standard PC scancodes, but are looked
00124   up in specialM[]. (The special keys are not keymappable.)
00125   
00126  */
00127 
00128 static const uchar * const keyboard_opti[5] = { 
00129     (const uchar *const) "\001\223\003\240\002\20\002\41\002\26\002\62\002\56\002\45\002\54\003\200\001\223\002\226\002\235\002\234\002\236",
00130     (const uchar *const) "\001\223\003\201\004\207\002\30\002\24\002\43\004\207\003\203\001\223\006\002\002\065",
00131     (const uchar *const) "\001\223\003\202\002\60\002\37\002\23\002\22\002\36\002\21\002\55\003\203\001\223\006\005\002\055",
00132     (const uchar *const) "\001\223\003\205\004\207\002\27\002\61\002\40\004\207\003\204\001\223\006\010\002\014",
00133     (const uchar *const) "\001\223\003\206\002\44\002\31\002\57\002\42\002\46\002\25\002\207\003\204\001\223\002\013\002\064\002\015\002\230"
00134 };
00135 
00136 static const uchar * const keyboard_standard[5] = {
00137 
00138 #ifdef USE_SMALL_BACKSPACE
00139     (const uchar *const)"\002\240\002`\0021\0022\0023\0024\0025\0026\0027\0028\0029\0020\002[\002]\002\200\002\223\002\215\002\216\002\217",
00140 #else
00141     (const uchar *const)"\002\051\0021\0022\0023\0024\0025\0026\0027\0028\0029\0020\002[\002]\004\200\002\223\002\215\002\216\002\217",
00142 #endif
00143     //~ + 123...+ BACKSPACE //+ INSERT + HOME + PGUP
00144 
00145     (const uchar *const)"\003\201\002'\002,\002.\002p\002y\002f\002g\002c\002r\002l\002/\002=\002\\\001\224\002\223\002\221\002\220\002\222",
00146     //TAB + qwerty..  + backslash //+ DEL + END + PGDN
00147 
00148     (const uchar *const)"\004\202\002a\002o\002e\002u\002i\002d\002h\002t\002n\002s\002-\004\203",
00149     //CAPS + asdf.. + RETURN
00150 
00151     (const uchar *const)"\005\204\002;\002q\002j\002k\002x\002b\002m\002w\002v\002z\005\204\002\223\002\223\002\211",
00152     //SHIFT + zxcv... //+ UP
00153 
00154     (const uchar *const)"\003\205\003\206\022\207\003\206\003\205\002\223\002\212\002\213\002\214"
00155     //CTRL + ALT + SPACE //+ LEFT + DOWN + RIGHT
00156 
00157 };
00158 
00159 
00160 struct ShiftMap {
00161     char normal;
00162     char shifted;
00163 };
00164 
00165 
00166 static const ShiftMap shiftMap[] = {
00167     { '`', '~' },
00168     { '1', '!' },
00169     { '2', '@' },
00170     { '3', '#' },
00171     { '4', '$' },
00172     { '5', '%' },
00173     { '6', '^' },
00174     { '7', '&' },
00175     { '8', '*' },
00176     { '9', '(' },
00177     { '0', ')' },
00178     { '-', '_' },
00179     { '=', '+' },
00180     { '\\', '|' },
00181     { '[', '{' },
00182     { ']', '}' },
00183     { ';', ':' },
00184     { '\'', '"' },
00185     { ',', '<' },
00186     { '.', '>' },
00187     { '/', '?' }
00188 };
00189 
00190 
00191 /* XPM */
00192 static const char * const uparrow_xpm[]={
00193 "9 9 2 1",
00194 "a c #000000",
00195 ". c None",
00196 ".........",
00197 "....a....",
00198 "...aaa...",
00199 "..aaaaa..",
00200 "....a....",
00201 "....a....",
00202 "....a....",
00203 "....a....",
00204 "........."};
00205 /* XPM */
00206 static const char * const leftarrow_xpm[]={
00207 "9 9 2 1",
00208 "a c #000000",
00209 ". c None",
00210 ".........",
00211 ".........",
00212 "...a.....",
00213 "..aa.....",
00214 ".aaaaaaa.",
00215 "..aa.....",
00216 "...a.....",
00217 ".........",
00218 "........."};
00219 /* XPM */
00220 static const char * const downarrow_xpm[]={
00221 "9 9 2 1",
00222 "a c #000000",
00223 ". c None",
00224 ".........",
00225 "....a....",
00226 "....a....",
00227 "....a....",
00228 "....a....",
00229 "..aaaaa..",
00230 "...aaa...",
00231 "....a....",
00232 "........."};
00233 /* XPM */
00234 static const char * const rightarrow_xpm[]={
00235 "9 9 2 1",
00236 "a c #000000",
00237 ". c None",
00238 ".........",
00239 ".........",
00240 ".....a...",
00241 ".....aa..",
00242 ".aaaaaaa.",
00243 ".....aa..",
00244 ".....a...",
00245 ".........",
00246 "........."};
00247 /* XPM */
00248 static const char * const insert_xpm[]={
00249 "9 9 2 1",
00250 "a c #000000",
00251 ". c None",
00252 ".........",
00253 "a........",
00254 "a.aaa.aaa",
00255 "a.a.a.a..",
00256 "a.a.a..a.",
00257 "a.a.a...a",
00258 "a.a.a.aaa",
00259 ".........",
00260 "........."};
00261 /* XPM */
00262 static const char * const delete_xpm[]={
00263 "9 9 2 1",
00264 "a c #000000",
00265 ". c None",
00266 ".........",
00267 "aa......a",
00268 "a.a.aaa.a",
00269 "a.a.a.a.a",
00270 "a.a.aaa.a.",
00271 "a.a.a...a",
00272 "aaa.aaa.a",
00273 ".........",
00274 "........."};
00275 /* XPM */
00276 static const char * const home_xpm[]={
00277 "9 9 2 1",
00278 "a c #000000",
00279 ". c None",
00280 "....a....",
00281 "...a.a...",
00282 "..a...a..",
00283 ".a.....a.",
00284 "aa.aaa.aa",
00285 ".a.a.a.a.",
00286 ".a.a.a.a.",
00287 ".aaaaaaa.",
00288 "........."};
00289 /* XPM */
00290 static const char * const end_xpm[]={
00291 "10 9 2 1",
00292 "a c #000000",
00293 ". c None",
00294 "..........",
00295 "aa.......a",
00296 "a..aaa.aaa",
00297 "aa.a.a.a.a",
00298 "a..a.a.a.a",
00299 "a..a.a.a.a",
00300 "aa.a.a.aaa",
00301 "..........",
00302 ".........."};
00303 /* XPM */
00304 static const char * const pageup_xpm[]={
00305 "9 9 2 1",
00306 "a c #000000",
00307 ". c None",
00308 ".aaa.aaa.",
00309 ".a.a.a.a.",
00310 ".aaa..aa.",
00311 ".a...aaa.",
00312 ".........",
00313 ".a.a.aaa.",
00314 ".a.a.a.a.",
00315 ".aaa.aaa.",
00316 ".....a..."};
00317 /* XPM */
00318 static const char * const pagedown_xpm[]={
00319 "9 9 2 1",
00320 "a c #000000",
00321 ". c None",
00322 ".aaa.aaa.",
00323 ".a.a.a.a.",
00324 ".aaa..aa.",
00325 ".a...aaa.",
00326 ".........",
00327 "...a.....",
00328 ".aaa.aaa.",
00329 ".a.a.a.a.",
00330 ".aaa.a.a."};
00331 /* XPM */
00332 static const char * const expand_xpm[]={
00333 "4 9 2 1",
00334 "a c #408040",
00335 ". c None",
00336 "a...",
00337 "aa..",
00338 "aaa.",
00339 "aaaa",
00340 "aaaa",
00341 "aaaa",
00342 "aaa.",
00343 "aa..",
00344 "a..."};
00345 /* XPM */
00346 #ifdef USE_SMALL_BACKSPACE
00347 static const char * const backspace_xpm[]={
00348 "9 9 2 1",
00349 "a c #000000",
00350 ". c None",
00351 ".........",
00352 ".........",
00353 "...a.....",
00354 "..aa.....",
00355 ".aaaaaaaa",
00356 "..aa.....",
00357 "...a.....",
00358 ".........",
00359 "........."};
00360 #else
00361 static const char * const backspace_xpm[]={
00362 "21 9 2 1",
00363 "a c #000000",
00364 ". c None",
00365 ".....................",
00366 ".....................",
00367 ".....aaa..a..........",
00368 ".a...a..a.a.a.aaa.aaa",
00369 "aaaa.aaa..aa..aa..a.a",
00370 ".a...a..a.aaa..aa.a.a",
00371 ".....aaaa.a.a.aaa.aa.",
00372 "..................a..",
00373 "....................."};
00374 #endif
00375 /* XPM */
00376 static const char * const escape_xpm[]={
00377 "9 9 2 1",
00378 "a c #000000",
00379 ". c None",
00380 ".........",
00381 ".........",
00382 ".aa.aa.aa",
00383 ".a..a..a.",
00384 ".aa.aa.a.",
00385 ".a...a.a.",
00386 ".aa.aa.aa",
00387 ".........",
00388 "........."};
00389 
00390 
00391 enum { BSCode = 0x80, TabCode, CapsCode, RetCode, 
00392        ShiftCode, CtrlCode, AltCode, SpaceCode, BackSlash,
00393        UpCode, LeftCode, DownCode, RightCode, Blank, Expand,
00394        Opti, ResetDict,
00395        Divide, Multiply, Add, Subtract, Decimal, Equal,
00396        Percent, Sqrt, Inverse, Escape };
00397 
00398 typedef struct SpecialMap {
00399     int qcode;
00400     ushort unicode;
00401     const char * label;
00402     const char * const * xpm;
00403 };
00404 
00405 
00406 static const SpecialMap specialM[] = {
00407     {   Qt::Key_Backspace,      8,      "<",     backspace_xpm },
00408     {   Qt::Key_Tab,            9,      "Tab",   NULL },
00409     {   Qt::Key_CapsLock,       0,      "Caps",  NULL },
00410     {   Qt::Key_Return,         13,     "Ret",   NULL },
00411     {   Qt::Key_Shift,          0,      "Shift", NULL },
00412     {   Qt::Key_Control,        0,      "Ctrl",  NULL },
00413     {   Qt::Key_Alt,            0,      "Alt",   NULL },
00414     {   Qt::Key_Space,          ' ',    "",      NULL },
00415     {   BackSlash,              43,     "\\",    NULL },
00416 
00417     // Need images?
00418     {   Qt::Key_Up,             0,      "^",     uparrow_xpm },
00419     {   Qt::Key_Left,           0,      "<",     leftarrow_xpm },
00420     {   Qt::Key_Down,           0,      "v",     downarrow_xpm },
00421     {   Qt::Key_Right,          0,      ">",     rightarrow_xpm },
00422     {   Qt::Key_Insert,         0,      "I",     insert_xpm },
00423     {   Qt::Key_Home,           0,      "H",     home_xpm },
00424     {   Qt::Key_PageUp,         0,      "U",     pageup_xpm },
00425     {   Qt::Key_End,            0,      "E",     end_xpm },
00426     {   Qt::Key_Delete,         0,      "X",     delete_xpm },
00427     {   Qt::Key_PageDown,       0,      "D",     pagedown_xpm },
00428     {   Blank,                  0,      " ",     NULL },
00429     {   Expand,                 0,      "->",    expand_xpm },
00430     {   Opti,                   0,      "#",     NULL },
00431     {   ResetDict,              0,      "R",     NULL },
00432    
00433     // number pad stuff
00434     {   Divide,                 0,      "/",     NULL },
00435     {   Multiply,               0,      "*",     NULL },
00436     {   Add,                    0,      "+",     NULL },
00437     {   Subtract,               0,      "-",     NULL },
00438     {   Decimal,                0,      ".",     NULL },
00439     {   Equal,                  0,      "=",     NULL },
00440     {   Percent,                0,      "%",     NULL },
00441     {   Sqrt,                   0,      "^1/2",  NULL },
00442     {   Inverse,                0,      "1/x",   NULL },
00443 
00444     {   Escape,                 27,     "ESC",   escape_xpm }
00445 };
00446 
00447 
00448 static int keycode( int i2, int j, const uchar **keyboard )
00449 {
00450     if ( j <0 || j >= 5 )
00451         return 0;
00452     
00453     const uchar *row = keyboard[j];
00454 
00455     while ( *row && *row <= i2 ) {
00456         i2 -= *row;
00457         row += 2;
00458     }
00459 
00460     if ( !*row ) return 0;
00461     
00462     int k;
00463     if ( row[1] >= 0x80 ) {
00464         k = row[1];
00465     } else {
00466         k = row[1]+i2/2;
00467     }
00468     
00469     return k;
00470 }
00471 
00472 
00473 /*
00474   return scancode and width of first key in row \a j if \a j >= 0,
00475   or next key on current row if \a j < 0.
00476   
00477 */
00478 
00479 int Keyboard::getKey( int &w, int j ) {
00480     static const uchar *row = 0;
00481     static int key_i = 0;
00482     static int scancode = 0;
00483     static int half = 0;
00484     
00485     if ( j >= 0 && j < 5 ) {
00486         if (useOptiKeys)
00487             row = keyboard_opti[j];
00488         else
00489             row = keyboard_standard[j];
00490         half=0;
00491     }
00492 
00493     if ( !row || !*row ) {
00494         return 0;    
00495     } else if ( row[1] >= 0x80 ) {
00496         scancode = row[1];
00497         w = (row[0] * w + (half++&1)) / 2;
00498         row += 2;
00499         return scancode;
00500     } else if ( key_i <= 0 ) {
00501         key_i = row[0]/2;
00502         scancode = row[1];
00503     }
00504     key_i--;
00505     if ( key_i <= 0 )
00506         row += 2;
00507     return scancode++;
00508 }
00509     
00510 
00511 void Keyboard::paintEvent(QPaintEvent* e)
00512 {
00513     QPainter painter(this);
00514     painter.setClipRect(e->rect());
00515     drawKeyboard( painter );
00516     picks->dc->draw( &painter );
00517 }
00518 
00519 
00520 /*
00521   Draw the keyboard.
00522 
00523   If key >= 0, only the specified key is drawn.
00524 */
00525 void Keyboard::drawKeyboard( QPainter &p, int key )
00526 {
00527     const bool threeD = FALSE;
00528     const QColorGroup& cg = colorGroup();
00529     QColor keycolor = // cg.background();
00530                         QColor(240,240,230); // Beige!
00531     QColor keycolor_pressed = cg.mid();
00532     QColor keycolor_lo = cg.dark();
00533     QColor keycolor_hi = cg.light();
00534     QColor textcolor = QColor(0,0,0); // cg.text();
00535 
00536     int margin = threeD ? 1 : 0;
00537     
00538 //    p.fillRect( 0, , kw-1, keyHeight-2, keycolor_pressed );
00539 
00540     for ( int j = 0; j < 5; j++ ) {
00541         int y = j * keyHeight + picks->height() + 1;
00542         int x = xoffs;
00543         int kw = defaultKeyWidth;
00544         int k= getKey( kw, j );
00545         while ( k ) {
00546             if ( key < 0 || k == key ) {
00547                 QString s;
00548                 bool pressed = (k == pressedKey);
00549                 bool blank = (k == 0223);
00550                 const char * const * xpm = NULL;
00551                 
00552                 if ( k >= 0x80 ) {
00553                     s = specialM[k - 0x80].label;
00554 
00555                     xpm = specialM[k - 0x80].xpm;
00556                         
00557                     if ( k == ShiftCode ) {
00558                         pressed = shift;
00559                     } else if ( k == CapsCode ) {
00560                         pressed = lock;
00561                     } else if ( k == CtrlCode ) {
00562                         pressed = ctrl;
00563                     } else if ( k == AltCode ) {
00564                         pressed = alt;
00565                     } 
00566                 } else {
00567 #if defined(Q_WS_QWS) || defined(_WS_QWS_)
00568 /*
00569                     s = QChar( shift^lock ? QWSServer::keyMap()[k].shift_unicode : 
00570                                QWSServer::keyMap()[k].unicode);
00571 */
00572                     // ### Fixme, bad code, needs improving, whole thing needs to
00573                     // be re-coded to get rid of the way it did things with scancodes etc
00574                     char shifted = k;
00575                     if ( !isalpha( k ) ) {
00576                         for ( unsigned i = 0; i < sizeof(shiftMap)/sizeof(ShiftMap); i++ )
00577                             if ( shiftMap[i].normal == k )
00578                                 shifted = shiftMap[i].shifted;
00579                     } else {
00580                         shifted = toupper( k );
00581                     }
00582                     s = QChar( shift^lock ? shifted : k );
00583 #endif
00584                 }
00585 
00586                 if (!blank) {
00587                     if ( pressed )
00588                         p.fillRect( x+margin, y+margin, kw-margin, keyHeight-margin-1, keycolor_pressed );
00589                     else
00590                         p.fillRect( x+margin, y+margin, kw-margin, keyHeight-margin-1, keycolor );
00591 
00592                     if ( threeD ) {
00593                         p.setPen(pressed ? keycolor_lo : keycolor_hi);
00594                         p.drawLine( x, y+1, x, y+keyHeight-2 );
00595                         p.drawLine( x+1, y+1, x+1, y+keyHeight-3 );
00596                         p.drawLine( x+1, y+1, x+1+kw-2, y+1 );
00597                     } else if ( j == 0 ) {
00598                         p.setPen(pressed ? keycolor_hi : keycolor_lo);
00599                         p.drawLine( x, y, x+kw, y );
00600                     }
00601 
00602                     // right
00603                     p.setPen(pressed ? keycolor_hi : keycolor_lo);
00604                     p.drawLine( x+kw-1, y, x+kw-1, y+keyHeight-2 );
00605 
00606                     if ( threeD ) {
00607                         p.setPen(keycolor_lo.light());
00608                         p.drawLine( x+kw-2, y+keyHeight-2, x+kw-2, y+1 );
00609                         p.drawLine( x+kw-2, y+keyHeight-2, x+1, y+keyHeight-2 );
00610                     }
00611 
00612                     if (xpm) {
00613                         p.drawPixmap( x + 1, y + 2, QPixmap((const char**)xpm) );
00614                     } else {
00615                         p.setPen(textcolor);
00616                         p.drawText( x - 1, y, kw, keyHeight-2, AlignCenter, s );
00617                     }
00618             
00619                     if ( threeD ) {
00620                         p.setPen(keycolor_hi);
00621                         p.drawLine( x, y, x+kw-1, y );
00622                     }
00623 
00624                     // bottom
00625                     p.setPen(keycolor_lo);
00626                     p.drawLine( x, y+keyHeight-1, x+kw-1, y+keyHeight-1 );
00627             
00628                 } else {
00629                     p.fillRect( x, y, kw, keyHeight, cg.background() );
00630                 }
00631             }
00632 
00633             x += kw;
00634             kw = defaultKeyWidth;
00635             k = getKey( kw );
00636         }
00637     }
00638 }
00639 
00640 
00641 void Keyboard::mousePressEvent(QMouseEvent *e)
00642 {
00643     clearHighlight(); // typing fast?
00644 
00645     int i2 = ((e->x() - xoffs) * 2) / defaultKeyWidth;
00646     int j = (e->y() - picks->height()) / keyHeight;
00647 
00648     int k = keycode( i2, j, (const uchar **)((useOptiKeys) ? keyboard_opti : keyboard_standard) );
00649     bool need_repaint = FALSE;
00650     unicode = -1;
00651     qkeycode = 0;
00652     if ( k >= 0x80 ) {
00653         if ( k == ShiftCode ) {
00654             shift = !shift;
00655             need_repaint = TRUE;
00656         } else if ( k == AltCode ){
00657             alt = !alt;
00658             need_repaint = TRUE;
00659         } else if ( k == CapsCode ) {
00660             lock = !lock;
00661             need_repaint = TRUE;
00662         } else if ( k == CtrlCode ) {
00663             ctrl = !ctrl;
00664             need_repaint = TRUE;
00665         } else if ( k == 0224 /* Expand */ ) {
00666             useLargeKeys = !useLargeKeys;
00667             resizeEvent(0);
00668             repaint( TRUE ); // need it to clear first
00669         } else if ( k == 0225 /* Opti/Toggle */ ) {
00670             useOptiKeys = !useOptiKeys;
00671             resizeEvent(0);
00672             repaint( TRUE ); // need it to clear first
00673         } else {
00674             qkeycode = specialM[ k - 0x80 ].qcode;
00675             unicode = specialM[ k - 0x80 ].unicode;
00676         }
00677     } else {
00678 #if defined(Q_WS_QWS) || defined(_WS_QWS_)
00679 /*
00680         qk = QWSServer::keyMap()[k].key_code;
00681         if ( qk != Key_unknown ) {
00682                 if ( ctrl )
00683                     u = QWSServer::keyMap()[k].ctrl_unicode;
00684                 else if ( shift^lock )
00685                     u = QWSServer::keyMap()[k].shift_unicode;
00686                 else 
00687                     u = QWSServer::keyMap()[k].unicode;
00688         }
00689 */
00690         char shifted = k;
00691         if ( !isalpha( k ) ) {
00692             // ### Fixme, bad code, needs improving, whole thing needs to
00693             // be re-coded to get rid of the way it did things with scancodes etc
00694             for ( unsigned i = 0; i < sizeof(shiftMap)/sizeof(ShiftMap); i++ )
00695                 if ( shiftMap[i].normal == k )
00696                     shifted = shiftMap[i].shifted;
00697         } else {
00698             shifted = toupper( k );
00699         }
00700         QChar tempChar( shift^lock ? shifted : k );
00701         unicode = tempChar.unicode();
00702 #endif
00703     }
00704     if  ( unicode != -1 ) {
00705         modifiers = (shift ? Qt::ShiftButton : 0) | (ctrl ? Qt::ControlButton : 0) |
00706                   (alt ? Qt::AltButton : 0);
00707 #if defined(Q_WS_QWS) || defined(_WS_QWS_)
00708         emit key( unicode, qkeycode, modifiers, true, false );
00709         repeatTimer->start( 500 );
00710 #endif
00711         need_repaint = shift || alt || ctrl;
00712         shift = alt = ctrl = FALSE;
00713         //qDebug( "pressed %d -> %04x ('%c')", k, u, u&0xffff < 256 ? u&0xff : 0 );
00714 
00715         KeyboardConfig *dc = picks->dc;
00716 
00717         if (dc) {
00718             if (qkeycode == Qt::Key_Backspace) {
00719                 dc->input.remove(dc->input.last()); // remove last input
00720                 dc->decBackspaces();
00721             } else if ( k == 0226 || qkeycode == Qt::Key_Return ||
00722                         qkeycode == Qt::Key_Space ||
00723                         QChar(unicode).isPunct() ) {
00724                 dc->input.clear();
00725                 dc->resetBackspaces();
00726             } else {
00727                 dc->add(QString(QChar(unicode)));
00728                 dc->incBackspaces();
00729             }
00730         }
00731 
00732         picks->repaint();
00733 
00734     }
00735     pressedKey = k;
00736     if ( need_repaint ) {
00737         repaint( FALSE );
00738     } else {
00739         QPainter p(this);
00740         drawKeyboard( p, pressedKey );
00741     }
00742     pressTid = startTimer(80);
00743     pressed = TRUE;
00744 }
00745 
00746 
00747 void Keyboard::mouseReleaseEvent(QMouseEvent*)
00748 {
00749     if ( pressTid == 0 )
00750         clearHighlight();
00751 #if defined(Q_WS_QWS) || defined(_WS_QWS_)
00752     if ( unicode != -1 ) {
00753         emit key( unicode, qkeycode, modifiers, false, false );
00754         repeatTimer->stop();
00755     }
00756 #endif
00757     pressed = FALSE;
00758 }
00759 
00760 void Keyboard::timerEvent(QTimerEvent* e)
00761 {
00762     if ( e->timerId() == pressTid ) {
00763         killTimer(pressTid);
00764         pressTid = 0;
00765         if ( !pressed )
00766             clearHighlight();
00767     }
00768 }
00769 
00770 void Keyboard::repeat()
00771 {
00772     repeatTimer->start( 150 );
00773     emit key( unicode, qkeycode, modifiers, true, true );
00774 }
00775 
00776 void Keyboard::clearHighlight()
00777 {
00778     if ( pressedKey >= 0 ) {
00779         int tmp = pressedKey;
00780         pressedKey = -1;
00781         QPainter p(this);
00782         drawKeyboard( p, tmp );
00783     }
00784 }
00785 
00786 
00787 QSize Keyboard::sizeHint() const
00788 {
00789     QFontMetrics fm=fontMetrics();
00790     int keyHeight = fm.lineSpacing()+2;
00791 
00792     if (useOptiKeys)
00793         keyHeight += 1;
00794     
00795     return QSize( 320, keyHeight * 5 + picks->sizeHint().height() + 1 );
00796 }
00797 
00798 
00799 void Keyboard::resetState()
00800 {
00801     picks->resetState();
00802 }

Generated on Sat Nov 5 16:16:01 2005 for OPIE by  doxygen 1.4.2