source: calamares/trunk/fuentes/src/modules/keyboard/keyboardwidget/keyboardpreview.cpp @ 7538

Last change on this file since 7538 was 7538, checked in by kbut, 18 months ago

sync with github

File size: 9.3 KB
Line 
1/* === This file is part of Calamares - <https://github.com/calamares> ===
2 *
3 *   Copyright 2014, Teo Mrnjavac <teo@kde.org>
4 *
5 *   Portions from the Manjaro Installation Framework
6 *   by Roland Singer <roland@manjaro.org>
7 *   Copyright (C) 2007 Free Software Foundation, Inc.
8 *
9 *   Calamares is free software: you can redistribute it and/or modify
10 *   it under the terms of the GNU General Public License as published by
11 *   the Free Software Foundation, either version 3 of the License, or
12 *   (at your option) any later version.
13 *
14 *   Calamares is distributed in the hope that it will be useful,
15 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 *   GNU General Public License for more details.
18 *
19 *   You should have received a copy of the GNU General Public License
20 *   along with Calamares. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23#include "utils/Logger.h"
24#include "keyboardpreview.h"
25
26KeyBoardPreview::KeyBoardPreview( QWidget* parent )
27    : QWidget( parent )
28    , layout( "us" )
29    , space( 0 )
30    , usable_width( 0 )
31    , key_w( 0 )
32{
33    setMinimumSize(700, 191);
34
35    // We must set up the font size in pixels to fit the keys
36    lowerFont = QFont("Helvetica", 10, QFont::DemiBold);
37    lowerFont.setPixelSize(16);
38    upperFont = QFont("Helvetica", 8);
39    upperFont.setPixelSize(13);
40
41    // Setup keyboard types
42    kbList[KB_104].kb_extended_return = false;
43    kbList[KB_104].keys.append(QList<int>() << 0x29 << 0x2 << 0x3 << 0x4 << 0x5 << 0x6 << 0x7 << 0x8 << 0x9 << 0xa << 0xb << 0xc << 0xd);
44    kbList[KB_104].keys.append(QList<int>() << 0x10 << 0x11 << 0x12 << 0x13 << 0x14 << 0x15 << 0x16 << 0x17 << 0x18 << 0x19 << 0x1a << 0x1b << 0x2b);
45    kbList[KB_104].keys.append(QList<int>() << 0x1e << 0x1f << 0x20 << 0x21 << 0x22 << 0x23 << 0x24 << 0x25 << 0x26 << 0x27 << 0x28);
46    kbList[KB_104].keys.append(QList<int>() << 0x2c << 0x2d << 0x2e << 0x2f << 0x30 << 0x31 << 0x32 << 0x33 << 0x34 << 0x35);
47
48    kbList[KB_105].kb_extended_return = true;
49    kbList[KB_105].keys.append(QList<int>() << 0x29 << 0x2 << 0x3 << 0x4 << 0x5 << 0x6 << 0x7 << 0x8 << 0x9 << 0xa << 0xb << 0xc << 0xd);
50    kbList[KB_105].keys.append(QList<int>() << 0x10 << 0x11 << 0x12 << 0x13 << 0x14 << 0x15 << 0x16 << 0x17 << 0x18 << 0x19 << 0x1a << 0x1b);
51    kbList[KB_105].keys.append(QList<int>() << 0x1e << 0x1f << 0x20 << 0x21 << 0x22 << 0x23 << 0x24 << 0x25 << 0x26 << 0x27 << 0x28 << 0x2b);
52    kbList[KB_105].keys.append(QList<int>() << 0x54 << 0x2c << 0x2d << 0x2e << 0x2f << 0x30 << 0x31 << 0x32 << 0x33 << 0x34 << 0x35);
53
54    kbList[KB_106].kb_extended_return = true;
55    kbList[KB_106].keys.append(QList<int>() << 0x29 << 0x2 << 0x3 << 0x4 << 0x5 << 0x6 << 0x7 << 0x8 << 0x9 << 0xa << 0xb << 0xc << 0xd << 0xe);
56    kbList[KB_106].keys.append(QList<int>() << 0x10 << 0x11 << 0x12 << 0x13 << 0x14 << 0x15 << 0x16 << 0x17 << 0x18 << 0x19 << 0x1a << 0x1b);
57    kbList[KB_106].keys.append(QList<int>() << 0x1e << 0x1f << 0x20 << 0x21 << 0x22 << 0x23 << 0x24 << 0x25 << 0x26 << 0x27 << 0x28 << 0x29);
58    kbList[KB_106].keys.append(QList<int>() << 0x2c << 0x2d << 0x2e << 0x2f << 0x30 << 0x31 << 0x32 << 0x33 << 0x34 << 0x35 << 0x36);
59
60    kb = &kbList[KB_104];
61}
62
63
64
65void KeyBoardPreview::setLayout(QString _layout) {
66    layout = _layout;
67}
68
69
70
71void KeyBoardPreview::setVariant(QString _variant) {
72    variant = _variant;
73
74    if (!loadCodes())
75        return;
76
77    loadInfo();
78    repaint();
79}
80
81
82
83//###
84//### Private
85//###
86
87
88
89void KeyBoardPreview::loadInfo() {
90    // kb_104
91    if (layout == "us" || layout == "th")
92        kb = &kbList[KB_104];
93    // kb_106
94    else if (layout == "jp")
95        kb = &kbList[KB_106];
96    // most keyboards are 105 key so default to that
97    else
98        kb = &kbList[KB_105];
99}
100
101
102
103bool KeyBoardPreview::loadCodes() {
104    if (layout.isEmpty())
105        return false;
106
107    QStringList param;
108    param << "-model" << "pc106" << "-layout" << layout << "-compact";
109    if (!variant.isEmpty())
110        param << "-variant" << variant;
111
112
113    QProcess process;
114    process.setEnvironment(QStringList() << "LANG=C" << "LC_MESSAGES=C");
115    process.start("ckbcomp", param);
116    if (!process.waitForStarted())
117    {
118        cWarning() << "ckbcomp not found , keyboard preview disabled";
119        return false;
120    }
121
122    if (!process.waitForFinished())
123    {
124        cWarning() << "ckbcomp failed, keyboard preview disabled";
125        return false;
126    }
127
128    // Clear codes
129    codes.clear();
130
131    const QStringList list = QString(process.readAll()).split("\n", QString::SkipEmptyParts);
132
133    for (const QString &line : list) {
134        if (!line.startsWith("keycode") || !line.contains('='))
135            continue;
136
137        QStringList split = line.split('=').at(1).trimmed().split(' ');
138        if (split.size() < 4)
139            continue;
140
141        Code code;
142        code.plain = fromUnicodeString(split.at(0));
143        code.shift = fromUnicodeString(split.at(1));
144        code.ctrl = fromUnicodeString(split.at(2));
145        code.alt = fromUnicodeString(split.at(3));
146
147        if (code.ctrl == code.plain)
148            code.ctrl = "";
149
150        if (code.alt == code.plain)
151            code.alt = "";
152
153        codes.append(code);
154    }
155
156    return true;
157}
158
159
160
161QString KeyBoardPreview::fromUnicodeString(QString raw) {
162    if (raw.startsWith("U+"))
163        return QChar(raw.mid(2).toInt(nullptr, 16));
164    else if (raw.startsWith("+U"))
165        return QChar(raw.mid(3).toInt(nullptr, 16));
166
167    return "";
168}
169
170
171
172QString KeyBoardPreview::regular_text(int index) {
173    if (index < 0 || index >= codes.size())
174        return "";
175
176    return codes.at(index - 1).plain;
177}
178
179
180
181QString KeyBoardPreview::shift_text(int index) {
182    if (index < 0 || index >= codes.size())
183        return "";
184
185    return codes.at(index - 1).shift;
186}
187
188
189
190QString KeyBoardPreview::ctrl_text(int index) {
191    if (index < 0 || index >= codes.size())
192        return "";
193
194    return codes.at(index - 1).ctrl;
195}
196
197
198
199QString KeyBoardPreview::alt_text(int index) {
200    if (index < 0 || index >= codes.size())
201        return "";
202
203    return codes.at(index - 1).alt;
204}
205
206
207
208void KeyBoardPreview::resizeEvent(QResizeEvent *) {
209    space = 6;
210    usable_width = width()-7;
211    key_w = (usable_width - 14 * space)/15;
212
213    setMaximumHeight(key_w*4 + space*5 + 1);
214}
215
216
217
218void KeyBoardPreview::paintEvent(QPaintEvent* event) {
219    QPainter p(this);
220    p.setRenderHint(QPainter::Antialiasing);
221
222    p.setBrush(QColor(0xd6, 0xd6, 0xd6));
223    p.drawRect(rect());
224
225    QPen pen;
226    pen.setWidth(1);
227    pen.setColor(QColor(0x58, 0x58, 0x58));
228    p.setPen(pen);
229
230    p.setBrush(QColor(0x58, 0x58, 0x58));
231
232    p.setBackgroundMode(Qt::TransparentMode);
233    p.translate(0.5, 0.5);
234
235    int rx = 3;
236    int x=6;
237    int y=6;
238    int first_key_w = 0;
239    int remaining_x[] = {0,0,0,0};
240    int remaining_widths[] = {0,0,0,0};
241
242    for (int i = 0; i < 4; i++) {
243        if (first_key_w > 0) {
244            first_key_w = int(first_key_w * 1.375);
245
246            if (kb == &kbList[KB_105] && i == 3)
247                first_key_w = int(key_w * 1.275);
248
249            p.drawRoundedRect(QRectF(6, y, first_key_w, key_w), rx, rx);
250            x = 6 + first_key_w + space;
251        }
252        else {
253            first_key_w = key_w;
254        }
255
256
257
258        bool last_end = (i==1 && ! kb->kb_extended_return);
259        int rw=usable_width-x;
260        int ii=0;
261
262        for (int k : kb->keys.at(i)) {
263            QRectF rect = QRectF(x, y, key_w, key_w);
264
265            if (ii == kb->keys.at(i).size()-1 && last_end)
266                rect.setWidth(rw);
267
268            p.drawRoundedRect(rect, rx, rx);
269
270            rect.adjust(5, 1, 0, 0);
271
272            p.setPen(QColor(0x9e, 0xde, 0x00));
273            p.setFont(upperFont);
274            p.drawText(rect, Qt::AlignLeft | Qt::AlignTop, shift_text(k));
275
276            rect.setBottom(rect.bottom() - 2.5);
277
278            p.setPen(QColor(0xff, 0xff, 0xff));
279            p.setFont(lowerFont);
280            p.drawText(rect, Qt::AlignLeft | Qt::AlignBottom, regular_text(k));
281
282            rw = rw - space - key_w;
283            x = x + space + key_w;
284            ii = ii+1;
285
286            p.setPen(pen);
287        }
288
289
290
291        remaining_x[i] = x;
292        remaining_widths[i] = rw;
293
294        if (i != 1 && i != 2)
295            p.drawRoundedRect(QRectF(x, y, rw, key_w), rx, rx);
296
297        y = y + space + key_w;
298    }
299
300
301    if (kb->kb_extended_return) {
302        rx=rx*2;
303        int x1 = remaining_x[1];
304        int y1 = 6 + key_w*1 + space*1;
305        int w1 = remaining_widths[1];
306        int x2 = remaining_x[2];
307        int y2 = 6 + key_w*2 + space*2;
308
309        // this is some serious crap... but it has to be so
310        // maybe one day keyboards won't look like this...
311        // one can only hope
312        QPainterPath pp;
313        pp.moveTo(x1, y1+rx);
314        pp.arcTo(x1, y1, rx, rx, 180, -90);
315        pp.lineTo(x1+w1-rx, y1);
316        pp.arcTo(x1+w1-rx, y1, rx, rx, 90, -90);
317        pp.lineTo(x1+w1, y2+key_w-rx);
318        pp.arcTo(x1+w1-rx, y2+key_w-rx, rx, rx, 0, -90);
319        pp.lineTo(x2+rx, y2+key_w);
320        pp.arcTo(x2, y2+key_w-rx, rx, rx, -90, -90);
321        pp.lineTo(x2, y1+key_w);
322        pp.lineTo(x1+rx, y1+key_w);
323        pp.arcTo(x1, y1+key_w-rx, rx, rx, -90, -90);
324        pp.closeSubpath();
325
326        p.drawPath(pp);
327    }
328    else {
329        x= remaining_x[2];
330        y = 6 + key_w*2 + space*2;
331        p.drawRoundedRect(QRectF(x, y, remaining_widths[2], key_w), rx, rx);
332    }
333
334
335    QWidget::paintEvent(event);
336}
Note: See TracBrowser for help on using the repository browser.