QtMoko2

QtMoko2 Commit Details

Date:2009-09-11 11:14:08 (15 years 6 months ago)
Author:ANT
Commit:3c668996efc3fa773a722bd005fa65ca19cc65f5
Parents: 45a1edcff8d261e55510ff48def5ea8390929870
Message:FingerKeyboard - added support of additional unicode layout

Changes:
Msrc/plugins/inputmethods/fingerkeyboard/keyboardframe.cpp (21 diffs)
Msrc/plugins/inputmethods/fingerkeyboard/keyboardframe.h (4 diffs)

File differences

src/plugins/inputmethods/fingerkeyboard/keyboardframe.cpp
11
22
33
4
4
55
66
77
......
3737
3838
3939
40
41
42
43
44
45
46
47
48
4049
4150
4251
......
6069
6170
6271
72
73
74
6375
6476
6577
......
99111
100112
101113
102
103
114
115
116
117
118
119
120
121
122
123
124
125
126
104127
105128
129
106130
107131
108
132
109133
110
134
135
111136
112137
138
139
140
113141
114142
115143
......
172200
173201
174202
203
204
205
206
175207
176208
177209
......
188220
189221
190222
191
223
192224
193225
194226
......
208240
209241
210242
211
243
212244
213245
214246
......
217249
218250
219251
220
252
221253
222254
223255
......
386418
387419
388420
389
390
421
422
391423
392424
393
394
425
426
395427
396428
397429
......
403435
404436
405437
406
438
439
440
441
442
443
444
445
446
447
448
449
450
407451
408452
409453
......
453497
454498
455499
456
500
457501
502
503
458504
459505
460506
......
486532
487533
488534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
489553
490554
491555
......
518582
519583
520584
521
522
585
586
523587
588
589
590
591
592
593
594
595
524596
525597
526598
......
532604
533605
534606
535
607
608
609
610
536611
537612
538613
......
540615
541616
542617
543
544
545
546
547
548
549
550
551
618
619
620
552621
553622
554623
......
582651
583652
584653
585
654
586655
587656
588657
......
611680
612681
613682
614
683
684
685
686
687
688
689
690
691
692
615693
616694
617695
618696
619
697
698
699
700
701
702
703
704
705
706
707
620708
621709
622710
......
632720
633721
634722
635
723
724
725
726
636727
637728
638729
639730
640731
641732
642
733
734
735
736
737
738
739
740
643741
644742
645743
......
658756
659757
660758
759
661760
662761
663762
......
766865
767866
768867
769
868
770869
771870
772871
......
814913
815914
816915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
/****************************************************************************
**
** Copyright (C) 2000-2008 TROLLTECH ASA. All rights reserved,
** Leonardo Maccari. All rights expressed in the GPL license.
** Leonardo Maccari, Anton Olkhovik. All rights expressed in the GPL license.
**
**
** This software is licensed under the terms of the GNU General Public
#include <qtopialog.h>
#include <QTextCodec>
#include <QDir>
#include <QSettings>
#include <Qtopia>
#include <QList>
#include <QStringList>
#define USE_SMALL_BACKSPACE
#define USE_LARGE_KEYS 1
#define KEYBOARD_ROWS 6
    QPixmap *pic;
};
static uchar *keyboard_national_6[KEYBOARD_ROWS]; //
#define SPEC_SYMBOL_COUNT  33
static SpecialMap specialM[] = {
    // LM: backspace pixmaps obviously doesn't scale
    {   Qt::Key_Backspace,      8,      "<",     "backspace", 0 },
    {   Sqrt,                   0,      "^1/2",  NULL, 0 },
    {   Inverse,                0,      "1/x",   NULL, 0 },
    {   Escape,                 27,     "ESC",   "escape", 0 },
    {   0,                      0,      NULL,    NULL, 0}
    {   Escape,                 27,     "ESC",   "escape", 0 }, // <<---[32]
    { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 },
    { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 },
    { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 },
    { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 },
    { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 },
    { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 },
    { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 },
    { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 },
    { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 },
    { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 }, { 0,0,NULL,NULL,0 },
    { 0,0,NULL,NULL,0 }
};
KeyboardFrame::KeyboardFrame(QWidget* parent, Qt::WFlags f) :
    QFrame(parent, f), shift(false), lock(false), ctrl(false),
    alt(false), useLargeKeys(USE_LARGE_KEYS), useOptiKeys(0), pressedKey(-1),
    alt(false), useLargeKeys(USE_LARGE_KEYS), layoutNumber(0), pressedKey(-1),
    unicode(-1), qkeycode(0), modifiers(Qt::NoModifier), pressTid(0), pressed(false),
    positionTop(true)
    positionTop(true), nationalLoaded(false),
    layoutFileName("/etc/fingerkeyboard/extralayout.conf")
{
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
    LoadNationalLayout();
/* begin of hack code for screen rotation
QtopiaServiceRequest svreq("RotationManager", "setCurrentRotation(int)");
    }
//QtopiaServiceRequest svreq("RotationManager", "defaultRotation()");
//svreq.send();
    //free memory allocated for additional layout
    for (int i=0; i<KEYBOARD_ROWS; i++)
        free(keyboard_national_6[i]);
}
void KeyboardFrame::showEvent(QShowEvent *e)
    keyHeight = (height()-ph)/KEYBOARD_ROWS;
    int nk;
    if ( useOptiKeys ) {
    if ( layoutNumber == OPTI_LAYOUT_NUMBER ) {
        nk = KEYBOARD_OPTI_PICS;
    } else if ( useLargeKeys ) {
        nk = KEYBOARD_PICS; // LM: unused ?
    resetState();
    // Let keyboardimpl know that we're hidden now, and it should update the menu
    emit hiding();
};
}
void KeyboardFrame::resizeEvent(QResizeEvent*)
//    picks->setGeometry( 0, 50, width(), ph );
    keyHeight = (height()-ph)/KEYBOARD_ROWS;
    int nk;
    if ( useOptiKeys ) {
    if ( layoutNumber == OPTI_LAYOUT_NUMBER ) {
        nk = KEYBOARD_OPTI_PICS;
    } else if ( useLargeKeys ) {
        nk = KEYBOARD_PICS; // unused ?
struct ShiftMap {
    char normal;
    char shifted;
    int normal;
    int shifted;
};
static const ShiftMap shiftMap[] = {
#define SHIFT_SYMBOL_COUNT  12
static ShiftMap shiftMap[] = {
    { '1', '<' },
    { '2', '>' },
    { '3', '"' },
    { '9', '~' },
    { '0', '^' },
    { '.', '-' },
    { ',', '\'' }
    { ',', '\'' }, // <<---[11]
    {0,0},{0,0},{0,0},{0,0},{0,0},
    {0,0},{0,0},{0,0},{0,0},{0,0},
    {0,0},{0,0},{0,0},{0,0},{0,0},
    {0,0},{0,0},{0,0},{0,0},{0,0},
    {0,0},{0,0},{0,0},{0,0},{0,0},
    {0,0},{0,0},{0,0},{0,0},{0,0},
    {0,0},{0,0},{0,0},{0,0},{0,0},
    {0,0},{0,0},{0,0},{0,0},{0,0},
    {0,0},{0,0},{0,0},{0,0},{0,0},
    {0,0},{0,0},{0,0},{0,0},{0,0},
    {0,0}
};
    static int half = 0;
    if ( j >= 0 && j < KEYBOARD_ROWS ) {
        if (useOptiKeys)
        if (layoutNumber == OPTI_LAYOUT_NUMBER)
            row = keyboard_opti_6[j];
        else if (layoutNumber == NATIONAL_LAYOUT_NUMBER)
            row = keyboard_national_6[j];
        else
            row = keyboard_standard_6[j];
        half=0;
    picks->dc->draw( &painter );
}
int KeyboardFrame::FindShifted(int k)
{
    int shifted = k;
    bool shiftFound = false;
    for ( unsigned i = 0; shiftMap[i].normal != 0; i++ )
        if ( shiftMap[i].normal == k )
        {
            shifted = shiftMap[i].shifted;
            shiftFound = true;
            break;
        }
    if ( (!shiftFound) && (k < 0x80) )
        if ( isalpha( k ) ) {
            shifted = toupper( k );
        }
    return shifted;
}
/*
  Draw the KeyboardFrame.
                    bool blank = (k == 0223);
                    QPixmap *pic = 0;
                    if ( k >= 0x80 ) {
                        s = specialM[k - 0x80].label;
                    bool catched = false;
                    int kcode = k;
                    if (k >= 0x80 + SPEC_SYMBOL_COUNT)
                    {
                        kcode = specialM[k - 0x80].unicode;
                    }
                    else if ( k >= 0x80 )
                    {
                        catched = true;
                        s = specialM[k - 0x80].label;
                        pic = specialM[k - 0x80].pic;
                        if ( k == ShiftCode ) {
                        } else if ( k == AltCode ) {
                            pressed = alt;
                        }
                    } else {
                    }
                    if (!catched)
                    {
    #if defined(Q_WS_QWS) || defined(Q_WS_QWS)
    /*
                        s = QChar( shift^lock ? QWSServer::keyMap()[k].shift_unicode :
    */
                        // ### Fixme, bad code, needs improving, whole thing needs to
                        // be re-coded to get rid of the way it did things with scancodes etc
                        char shifted = k;
                        if ( !isalpha( k ) ) {
                            for ( unsigned i = 0; i < sizeof(shiftMap)/sizeof(ShiftMap); i++ )
                                if ( shiftMap[i].normal == k )
                                    shifted = shiftMap[i].shifted;
                        } else {
                            shifted = toupper( k );
                        }
                        s = QChar( shift^lock ? shifted : k );
                        int shifted = FindShifted(kcode);
                        s = QChar( shift^lock ? shifted : kcode );
    #endif
                    }
                            p.drawPixmap( x + 1, y + 2, *pic );
                        } else {
                            p.setPen(textcolor);
                            p.drawText( x - 1, y, kw, keyHeight-2, Qt::AlignCenter, s );
                            p.drawText( x - 1, y, kw, keyHeight-2, Qt::AlignCenter, s ); //
                        }
                        if ( threeD ) {
    int j = (e->y() - picks->height()) / keyHeight;
    QRect keyrect;
    int k = keycode( i2, j, (const uchar **)((useOptiKeys) ?  keyboard_opti_6 : keyboard_standard_6), &keyrect );
    const uchar **cur_keys;
    if (layoutNumber == OPTI_LAYOUT_NUMBER)
        cur_keys = (const uchar **)keyboard_opti_6;
    else if (layoutNumber == NATIONAL_LAYOUT_NUMBER)
        cur_keys = (const uchar **)keyboard_national_6;
    else
        cur_keys = (const uchar **)keyboard_standard_6;
   
    int k = keycode( i2, j, cur_keys, &keyrect );
    bool key_down = false;
    unicode = -1;
    qkeycode = 0;
    if ( k >= 0x80 ) {
    bool catched = false;
    int kcode = k;
    if (k >= 0x80 + SPEC_SYMBOL_COUNT)
    {
        kcode = specialM[k - 0x80].unicode;
    }
    else if ( k >= 0x80 )
    {
        catched = true;        
        if ( k == ShiftCode ) {
            shift = !shift;
            keyrect = rect();
            resizeEvent(0);
            repaint( ); // need it to clear first
        } else if ( k == 0225 /* Opti/Toggle */ ) {
            useOptiKeys = !useOptiKeys;
            //useOptiKeys = !useOptiKeys;
            layoutNumber++;
            if ((layoutNumber == NATIONAL_LAYOUT_NUMBER) && (!nationalLoaded)) layoutNumber++;
            if (layoutNumber >= LAYOUTS_COUNT) layoutNumber=0;
            resizeEvent(0);
            repaint( ); // need it to clear first
        } else {
            qkeycode = specialM[ k - 0x80 ].qcode;
            unicode = specialM[ k - 0x80 ].unicode;
        }
    } else {
    }
    if (!catched)
    {
        int shifted = FindShifted(kcode);
        qkeycode = shifted;
        unicode = shift^lock ? shifted : kcode;
/*
        //due to the way the keyboard is defined, we know that
        //k is within the ASCII range, and can be directly mapped to
        //a qkeycode; except letters, which are all uppercase
        } else {
            unicode = k;
        }
*/
    }
    if  ( unicode != -1 ) {
        if ( ctrl && unicode >= 'a' && unicode <= 'z' )
    QFontMetrics fm=fontMetrics();
    int keyHeight = fm.lineSpacing()+2;
    if (useOptiKeys)
    if (layoutNumber == OPTI_LAYOUT_NUMBER)
        keyHeight += 1;
    return QSize( 320, keyHeight * KEYBOARD_ROWS + picks->sizeHint().height() + 1 );
        positionTop = true;
    }
}
//====================================================================
void KeyboardFrame::LoadNationalLayout()
{
    QString layout(NULL);
    if (QFile::exists(Qtopia::qtopiaDir() + layoutFileName))
    {
        layout = Qtopia::qtopiaDir() + layoutFileName;
    }
    else
    {
        layout = FindInSandboxes();
    }
    if (!layout.isNull())
    {
        qLog(Input) << "FingerKeyboard - loading additional layout";
        qLog(Input) << layout;
        //allocating memory for additional layout
        for (int i=0; i<KEYBOARD_ROWS; i++)
            keyboard_national_6[i] = (uchar*)malloc(12*2+2); //max 12 keys is the row
        LoadSet(layout);
        nationalLoaded = true;
    }
}
QString KeyboardFrame::FindInSandboxes()
{
     QString homePath = QDir::homePath();
     QString packagesPath = homePath+"/packages";
     QDir pkgs = QDir(packagesPath);
     QStringList dirs;
     dirs = pkgs.entryList(QStringList("*"), QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot);
     for (int i=0; i<dirs.count(); i++)
     {
         QString fullName = packagesPath+"/"+dirs[i]+layoutFileName;
         if (QFile::exists(fullName))
         {
             return fullName;
         }
     }
     return QString(NULL);
}
void KeyboardFrame::LoadSet(QString s)
{
    QSettings settings(s, QSettings::IniFormat);
    settings.beginGroup("Letters");
    QStringList list_lower, list_upper;
    list_lower = settings.value("lower").toStringList();
    list_upper = settings.value("upper").toStringList();
    for (int i=0; i<list_lower.count(); i++)
    {
        QString sl = list_lower[i];
        QString su = list_upper[i];
        int code_sl = sl.toInt();
        int code_su = su.toInt();
        specialM[SPEC_SYMBOL_COUNT + i].qcode = code_sl;
        specialM[SPEC_SYMBOL_COUNT + i].unicode = code_sl;
        shiftMap[SHIFT_SYMBOL_COUNT + i].normal = code_sl;
        shiftMap[SHIFT_SYMBOL_COUNT + i].shifted = code_su;
    }
    settings.endGroup();
    settings.beginGroup("Board");
    QStringList list_rows;
    list_rows = settings.value("keyrows").toStringList();
    for (int i=0; i<list_rows.count(); i++)
    {
        QString row = list_rows[i];
        QStringList keys = row.split("|");
        for (int j=0; j<keys.count(); j++)
        {
            QString key = keys[j];
            QStringList fields = key.split(" ");
            int key_width = fields[0].toInt();
            QString key_chartype = fields[1];
            QString key_char = fields[2];
            int key_code = 0;
            if (key_chartype=="ch") key_code=(int)(key_char.toAscii().data()[0]);
            if (key_chartype=="id") key_code=key_char.toInt();
            if (key_chartype=="ex") key_code=key_char.toInt() + 0x80 + SPEC_SYMBOL_COUNT;
            keyboard_national_6[i][j*2+0] = (uchar)(key_width);
            keyboard_national_6[i][j*2+1] = (uchar)(key_code);
        }
        keyboard_national_6[i][list_rows.count()*2+0] = 0;
        keyboard_national_6[i][list_rows.count()*2+1] = 0;
    }
    settings.endGroup();
}
src/plugins/inputmethods/fingerkeyboard/keyboardframe.h
3232
3333
3434
35
36
37
38
39
3540
3641
3742
......
8691
8792
8893
89
94
95
96
97
98
9099
91100
92101
......
124133
125134
126135
136
137
138
139
127140
128141
129142
130143
131144
132145
133
146
147
134148
135149
136150
......
154168
155169
156170
171
172
173
157174
158175
159176
    Bottom
};
//#define STANDARD_LAYOUT_NUMBER 0
#define NATIONAL_LAYOUT_NUMBER 1
#define OPTI_LAYOUT_NUMBER     2
#define LAYOUTS_COUNT 3
class KeyboardConfig : public DictFilterConfig
{
public:
    void hideEvent ( QHideEvent * );
    void setMode(int mode) { useOptiKeys = mode; }
    void setMode(int mode)
    {
        //useOptiKeys = mode;
        layoutNumber = mode;
    }
    QSize sizeHint() const;
    int keycode( int i2, int j, const uchar **keyboard, QRect *repaintrect );
    int getKey( int &w, int j = -1 );
    void clearHighlight();
    int FindShifted(int k);
    void LoadNationalLayout();
    QString FindInSandboxes();
    void LoadSet(QString s);
    uint shift:1;
    uint lock:1;
    uint ctrl:1;
    uint alt:1;
    uint useLargeKeys:1;
    uint useOptiKeys:1;
    //uint useOptiKeys:1;
    uint layoutNumber;
    int pressedKey;
    QRect pressedKeyRect;
    bool positionTop;
    QTimer *repeatTimer;
    bool nationalLoaded;
    QString layoutFileName;
};
#endif

Archive Download the corresponding diff file