~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to kcontrol/keyboard/kcm_view_models.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Copyright (C) 2010 Andriy Rysin (rysin@kde.org)
 
3
 *
 
4
 *  This program is free software; you can redistribute it and/or modify
 
5
 *  it under the terms of the GNU General Public License as published by
 
6
 *  the Free Software Foundation; either version 2 of the License, or
 
7
 *  (at your option) any later version.
 
8
 *
 
9
 *  This program is distributed in the hope that it will be useful,
 
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 *  GNU General Public License for more details.
 
13
 *
 
14
 *  You should have received a copy of the GNU General Public License
 
15
 *  along with this program; if not, write to the Free Software
 
16
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
17
 */
 
18
 
 
19
#include "kcm_view_models.h"
 
20
 
 
21
#include <klocalizedstring.h>
 
22
#include <kkeysequencewidget.h>
 
23
 
 
24
#include <QtGui/QTreeView>
 
25
#include <QtGui/QComboBox>
 
26
#include <QtGui/QLineEdit>
 
27
#include <QtGui/QPainter>
 
28
#include <QtGui/QKeySequence>
 
29
 
 
30
#ifdef DRAG_ENABLED
 
31
#include <QtCore/QMimeData>
 
32
#endif
 
33
 
 
34
#include "keyboard_config.h"
 
35
#include "xkb_rules.h"
 
36
#include "flags.h"
 
37
#include "x11_helper.h"
 
38
#include "bindings.h"
 
39
 
 
40
const int LayoutsTableModel::MAP_COLUMN = 0;
 
41
const int LayoutsTableModel::LAYOUT_COLUMN = 1;
 
42
const int LayoutsTableModel::VARIANT_COLUMN = 2;
 
43
const int LayoutsTableModel::DISPLAY_NAME_COLUMN = 3;
 
44
const int LayoutsTableModel::SHORTCUT_COLUMN = 4;
 
45
static const int COLUMN_COUNT = 5;
 
46
 
 
47
LayoutsTableModel::LayoutsTableModel(Rules* rules_, Flags *flags_, KeyboardConfig* keyboardConfig_, QObject* parent):
 
48
        QAbstractTableModel(parent),
 
49
        keyboardConfig(keyboardConfig_),
 
50
        rules(rules_),
 
51
        countryFlags(flags_)
 
52
{
 
53
}
 
54
 
 
55
void LayoutsTableModel::refresh()
 
56
{
 
57
        beginResetModel();
 
58
        endResetModel();
 
59
}
 
60
 
 
61
int LayoutsTableModel::rowCount(const QModelIndex &/*parent*/) const
 
62
{
 
63
        return keyboardConfig->layouts.count();
 
64
}
 
65
 
 
66
int LayoutsTableModel::columnCount(const QModelIndex&) const
 
67
{
 
68
        return COLUMN_COUNT;
 
69
}
 
70
 
 
71
Qt::ItemFlags LayoutsTableModel::flags(const QModelIndex &index) const
 
72
{
 
73
        if (!index.isValid())
 
74
                return 0;
 
75
 
 
76
        Qt::ItemFlags flags = QAbstractTableModel::flags(index);
 
77
 
 
78
        if( index.column() == DISPLAY_NAME_COLUMN
 
79
                        || index.column() == VARIANT_COLUMN
 
80
                        || index.column() == SHORTCUT_COLUMN ) {
 
81
                flags |= Qt::ItemIsEditable;
 
82
        }
 
83
 
 
84
#ifdef DRAG_ENABLED
 
85
        flags |= Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
 
86
#endif
 
87
 
 
88
        return flags;
 
89
}
 
90
 
 
91
#ifdef DRAG_ENABLED
 
92
QStringList LayoutsTableModel::mimeTypes() const
 
93
{
 
94
    QStringList types;
 
95
    types << "application/keyboard-layout-item";
 
96
    return types;
 
97
}
 
98
 
 
99
QMimeData *LayoutsTableModel::mimeData(const QModelIndexList &indexes) const
 
100
 {
 
101
     QMimeData *mimeData = new QMimeData();
 
102
     QByteArray encodedData;
 
103
 
 
104
     QDataStream stream(&encodedData, QIODevice::WriteOnly);
 
105
 
 
106
     QSet<int> rows;
 
107
     foreach (const QModelIndex& index, indexes) {
 
108
         if (index.isValid()) {
 
109
                 rows << index.row();
 
110
         }
 
111
     }
 
112
     foreach (int row, rows) {
 
113
         stream << row;
 
114
         kDebug() << "idx: " << row;
 
115
     }
 
116
 
 
117
     mimeData->setData("application/keyboard-layout-item", encodedData);
 
118
     return mimeData;
 
119
}
 
120
#endif
 
121
 
 
122
QVariant LayoutsTableModel::data(const QModelIndex &index, int role) const
 
123
{
 
124
     if (!index.isValid())
 
125
         return QVariant();
 
126
 
 
127
     if (index.row() >= keyboardConfig->layouts.size())
 
128
         return QVariant();
 
129
 
 
130
         const LayoutUnit& layoutUnit = keyboardConfig->layouts.at(index.row());
 
131
 
 
132
     if (role == Qt::DecorationRole) {
 
133
         switch( index.column() ) {
 
134
         case DISPLAY_NAME_COLUMN: {
 
135
                        if( keyboardConfig->showFlag ) {
 
136
                                QIcon icon = countryFlags->getIcon(layoutUnit.layout);
 
137
                                return icon.isNull() ? countryFlags->getTransparentPixmap() : icon;
 
138
                        }
 
139
         }
 
140
//TODO: show the cells are editable
 
141
//       case VARIANT_COLUMN: {
 
142
//       case DISPLAY_NAME_COLUMN: {
 
143
//               int sz = 5;
 
144
//               QPixmap pm = QPixmap(sz, sz+5);
 
145
//               pm.fill(Qt::transparent);
 
146
//               QPainter p(&pm);
 
147
//               QPoint points[] = { QPoint(0, 0), QPoint(0, sz), QPoint(sz, 0) };
 
148
//               p.drawPolygon(points, 3);
 
149
//               return pm;
 
150
//       }
 
151
         break;
 
152
         }
 
153
     }
 
154
     else
 
155
     if( role == Qt::BackgroundRole ) {
 
156
         if( keyboardConfig->layoutLoopCount != KeyboardConfig::NO_LOOPING
 
157
                         && index.row() >= keyboardConfig->layoutLoopCount ) {
 
158
                 return QBrush(Qt::lightGray);
 
159
         }
 
160
     }
 
161
     else
 
162
     if (role == Qt::DisplayRole) {
 
163
         switch( index.column() ) {
 
164
         case MAP_COLUMN:
 
165
                 return layoutUnit.layout;
 
166
         break;
 
167
         case LAYOUT_COLUMN: {
 
168
                 const LayoutInfo* layoutInfo = rules->getLayoutInfo(layoutUnit.layout);
 
169
             return layoutInfo != NULL ? layoutInfo->description : layoutUnit.layout;
 
170
         }
 
171
         case VARIANT_COLUMN: {
 
172
                 if( layoutUnit.variant.isEmpty() )
 
173
                         return QVariant();
 
174
                 const LayoutInfo* layoutInfo = rules->getLayoutInfo(layoutUnit.layout);
 
175
                 if( layoutInfo == NULL )
 
176
                         return QVariant();
 
177
                 const VariantInfo* variantInfo = layoutInfo->getVariantInfo(layoutUnit.variant);
 
178
                 return variantInfo != NULL ? variantInfo->description : layoutUnit.variant;
 
179
         }
 
180
         break;
 
181
         case DISPLAY_NAME_COLUMN:
 
182
                        if( ! keyboardConfig->showFlag ) {
 
183
                                return layoutUnit.getDisplayName();
 
184
                        }
 
185
         break;
 
186
         case SHORTCUT_COLUMN: {
 
187
                return layoutUnit.getShortcut().toString();
 
188
         }
 
189
         break;
 
190
         }
 
191
     }
 
192
     else if (role==Qt::EditRole ) {
 
193
         switch( index.column() ) {
 
194
         case DISPLAY_NAME_COLUMN:
 
195
                 return layoutUnit.getDisplayName();
 
196
         break;
 
197
         case VARIANT_COLUMN:
 
198
                 return layoutUnit.variant;
 
199
         break;
 
200
         case SHORTCUT_COLUMN:
 
201
                 return layoutUnit.getShortcut().toString();
 
202
         break;
 
203
         default:;
 
204
         }
 
205
     }
 
206
     else if( role == Qt::TextAlignmentRole ) {
 
207
         switch( index.column() ) {
 
208
         case MAP_COLUMN:
 
209
         case DISPLAY_NAME_COLUMN:
 
210
         case SHORTCUT_COLUMN:
 
211
                 return Qt::AlignCenter;
 
212
         break;
 
213
         default:;
 
214
         }
 
215
     }
 
216
     return QVariant();
 
217
}
 
218
 
 
219
QVariant LayoutsTableModel::headerData(int section, Qt::Orientation orientation, int role) const
 
220
{
 
221
     if (role != Qt::DisplayRole)
 
222
         return QVariant();
 
223
 
 
224
     if (orientation == Qt::Horizontal) {
 
225
         const QString headers[] = {i18nc("layout map name", "Map"), i18n("Layout"), i18n("Variant"), i18n("Label"), i18n("Shortcut")};
 
226
         return headers[section];
 
227
     }
 
228
 
 
229
     return QVariant();
 
230
}
 
231
 
 
232
bool LayoutsTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
 
233
{
 
234
        if (role != Qt::EditRole
 
235
                        || (index.column() != DISPLAY_NAME_COLUMN && index.column() != VARIANT_COLUMN && index.column() != SHORTCUT_COLUMN) )
 
236
                return false;
 
237
 
 
238
        if (index.row() >= keyboardConfig->layouts.size())
 
239
                return false;
 
240
 
 
241
        LayoutUnit& layoutUnit = keyboardConfig->layouts[index.row()];
 
242
 
 
243
        switch( index.column() ) {
 
244
        case DISPLAY_NAME_COLUMN: {
 
245
                QString displayText = value.toString().left(3);
 
246
                layoutUnit.setDisplayName(displayText);
 
247
        }
 
248
        break;
 
249
        case VARIANT_COLUMN: {
 
250
                QString variant = value.toString();
 
251
                layoutUnit.variant = variant;
 
252
        }
 
253
        break;
 
254
        case SHORTCUT_COLUMN: {
 
255
                QString shortcut = value.toString();
 
256
                layoutUnit.setShortcut(QKeySequence(shortcut));
 
257
        }
 
258
        break;
 
259
        }
 
260
        emit dataChanged(index, index);
 
261
 
 
262
        return true;
 
263
}
 
264
 
 
265
//
 
266
// LabelEditDelegate
 
267
//
 
268
LabelEditDelegate::LabelEditDelegate(const KeyboardConfig* keyboardConfig_, QObject *parent):
 
269
        QStyledItemDelegate(parent),
 
270
        keyboardConfig(keyboardConfig_)
 
271
{}
 
272
 
 
273
QWidget *LabelEditDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem & option ,
 
274
                const QModelIndex & index ) const
 
275
{
 
276
        if( keyboardConfig->showFlag )
 
277
                return NULL;
 
278
 
 
279
        QWidget* widget = QStyledItemDelegate::createEditor(parent, option, index);
 
280
        QLineEdit* lineEdit = static_cast<QLineEdit*>(widget);
 
281
        if( lineEdit != NULL ) {
 
282
                lineEdit->setMaxLength(LayoutUnit::MAX_LABEL_LENGTH);
 
283
        }
 
284
        return widget;
 
285
}
 
286
 
 
287
//void LabelEditDelegate::paint( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
 
288
//{
 
289
//      QStyleOptionViewItem option2(option);
 
290
////    option2.decorationPosition =  QStyleOptionViewItem::Right;
 
291
//      option2.decorationAlignment = Qt::AlignHCenter | Qt::AlignVCenter;
 
292
//      QStyledItemDelegate::paint(painter, option2, index);
 
293
//}
 
294
 
 
295
 
 
296
//
 
297
// VariantComboDelegate
 
298
//
 
299
//TODO: reuse this function in kcm_add_layout_dialog.cpp
 
300
static void populateComboWithVariants(QComboBox* combo, const QString& layout, const Rules* rules)
 
301
{
 
302
        combo->clear();
 
303
        const LayoutInfo* layoutInfo = rules->getLayoutInfo(layout);
 
304
    foreach(const VariantInfo* variantInfo, layoutInfo->variantInfos) {
 
305
        combo->addItem(variantInfo->description, variantInfo->name);
 
306
    }
 
307
    combo->model()->sort(0);
 
308
    combo->insertItem(0, i18nc("variant", "Default"), "");
 
309
    combo->setCurrentIndex(0);
 
310
}
 
311
 
 
312
VariantComboDelegate::VariantComboDelegate(const KeyboardConfig* keyboardConfig_, const Rules* rules_, QObject *parent):
 
313
        QStyledItemDelegate(parent),
 
314
        keyboardConfig(keyboardConfig_),
 
315
        rules(rules_)
 
316
{}
 
317
 
 
318
QWidget *VariantComboDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &/* option */,
 
319
                const QModelIndex & index ) const
 
320
{
 
321
        QComboBox *editor = new QComboBox(parent);
 
322
        const LayoutUnit& layoutUnit = keyboardConfig->layouts[index.row()];
 
323
        populateComboWithVariants(editor, layoutUnit.layout, rules);
 
324
        return editor;
 
325
}
 
326
 
 
327
void VariantComboDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
 
328
{
 
329
        QComboBox *combo = static_cast<QComboBox*>(editor);
 
330
        QString variant = index.model()->data(index, Qt::EditRole).toString();
 
331
        int itemIndex = combo->findData(variant);
 
332
        if( itemIndex == -1 ) {
 
333
                itemIndex = 0;
 
334
        }
 
335
        combo->setCurrentIndex(itemIndex);
 
336
}
 
337
 
 
338
void VariantComboDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
 
339
                const QModelIndex &index) const
 
340
{
 
341
        QComboBox *combo = static_cast<QComboBox*>(editor);
 
342
        QString variant = combo->itemData(combo->currentIndex()).toString();
 
343
        model->setData(index, variant, Qt::EditRole);
 
344
}
 
345
 
 
346
void VariantComboDelegate::updateEditorGeometry(QWidget *editor,
 
347
                const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
 
348
{
 
349
        editor->setGeometry(option.rect);
 
350
}
 
351
 
 
352
//
 
353
// KKeySequenceWidgetDelegate
 
354
//
 
355
KKeySequenceWidgetDelegate::KKeySequenceWidgetDelegate(const KeyboardConfig* keyboardConfig_, QObject *parent):
 
356
        QStyledItemDelegate(parent),
 
357
        keyboardConfig(keyboardConfig_)
 
358
{}
 
359
 
 
360
QWidget *KKeySequenceWidgetDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem & /*option*/,
 
361
                const QModelIndex & index ) const
 
362
{
 
363
        itemsBeingEdited.insert(index);
 
364
 
 
365
        KKeySequenceWidget *editor = new KKeySequenceWidget(parent);
 
366
    editor->setFocusPolicy(Qt::StrongFocus);
 
367
    editor->setModifierlessAllowed(false);
 
368
 
 
369
    const LayoutUnit& layoutUnit = keyboardConfig->layouts[index.row()];
 
370
        editor->setKeySequence(layoutUnit.getShortcut());
 
371
 
 
372
        editor->captureKeySequence();
 
373
 
 
374
        return editor;
 
375
}
 
376
 
 
377
//void KKeySequenceWidgetDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
 
378
//{
 
379
//      KKeySequenceWidget *kkeysequencewidget = static_cast<KKeySequenceWidget*>(editor);
 
380
//      QString shortcut = index.model()->data(index, Qt::EditRole).toString();
 
381
//      kkeysequencewidget->setKeySequence(QKeySequence(shortcut));
 
382
//      kkeysequencewidget->captureKeySequence();
 
383
////    kDebug() << "set editor data";
 
384
//}
 
385
 
 
386
void KKeySequenceWidgetDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
 
387
                const QModelIndex &index) const
 
388
{
 
389
        KKeySequenceWidget *kkeysequencewidget = static_cast<KKeySequenceWidget*>(editor);
 
390
        QString shortcut = kkeysequencewidget->keySequence().toString();
 
391
        model->setData(index, shortcut, Qt::EditRole);
 
392
        itemsBeingEdited.remove(index);
 
393
}
 
394
 
 
395
void KKeySequenceWidgetDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,
 
396
                                    const QModelIndex& index) const
 
397
{
 
398
      if (itemsBeingEdited.contains(index)) {
 
399
//        StyledBackgroundPainter::drawBackground(painter,option,index);
 
400
      }
 
401
      else {
 
402
          QStyledItemDelegate::paint(painter,option,index);
 
403
      }
 
404
}
 
405
//
 
406
// Xkb Options Tree View
 
407
//
 
408
 
 
409
int XkbOptionsTreeModel::rowCount(const QModelIndex& parent) const {
 
410
    if( ! parent.isValid() )
 
411
        return rules->optionGroupInfos.count();
 
412
    if( ! parent.parent().isValid() )
 
413
        return rules->optionGroupInfos[parent.row()]->optionInfos.count();
 
414
    return 0;
 
415
}
 
416
 
 
417
QVariant XkbOptionsTreeModel::data(const QModelIndex& index, int role) const
 
418
{
 
419
    if (!index.isValid())
 
420
        return QVariant();
 
421
 
 
422
    int row = index.row();
 
423
 
 
424
    if (role == Qt::DisplayRole) {
 
425
        if( ! index.parent().isValid() ) {
 
426
            return rules->optionGroupInfos[row]->description;
 
427
        }
 
428
        else {
 
429
            int groupRow = index.parent().row();
 
430
            const OptionGroupInfo* xkbGroup = rules->optionGroupInfos[groupRow];
 
431
            return xkbGroup->optionInfos[row]->description;
 
432
        }
 
433
    }
 
434
    else if (role==Qt::CheckStateRole ) {
 
435
        if( index.parent().isValid() ) {
 
436
                int groupRow = index.parent().row();
 
437
                const OptionGroupInfo* xkbGroup = rules->optionGroupInfos[groupRow];
 
438
                const QString& xkbOptionName = xkbGroup->optionInfos[row]->name;
 
439
                return keyboardConfig->xkbOptions.indexOf(xkbOptionName) == -1
 
440
                                ? Qt::Unchecked : Qt::Checked;
 
441
        }
 
442
        else {
 
443
                int groupRow = index.row();
 
444
                const OptionGroupInfo* xkbGroup = rules->optionGroupInfos[groupRow];
 
445
                foreach(const OptionInfo* optionInfo, xkbGroup->optionInfos) {
 
446
                        if( keyboardConfig->xkbOptions.indexOf(optionInfo->name) != -1 )
 
447
                                return Qt::PartiallyChecked;
 
448
                }
 
449
                        return Qt::Unchecked;
 
450
        }
 
451
    }
 
452
    return QVariant();
 
453
}
 
454
 
 
455
bool XkbOptionsTreeModel::setData(const QModelIndex & index, const QVariant & value, int role) {
 
456
    int groupRow = index.parent().row();
 
457
    if( groupRow < 0 ) return false;
 
458
 
 
459
    const OptionGroupInfo* xkbGroup = rules->optionGroupInfos[groupRow];
 
460
    const OptionInfo* option = xkbGroup->optionInfos[index.row()];
 
461
 
 
462
    if( value.toInt() == Qt::Checked ) {
 
463
        if( xkbGroup->exclusive ) {
 
464
            // clear if exclusive (TODO: radiobutton)
 
465
            int idx = keyboardConfig->xkbOptions.indexOf(QRegExp(xkbGroup->name + ".*"));
 
466
            if( idx >= 0 ) {
 
467
                for(int i=0; i<xkbGroup->optionInfos.count(); i++)
 
468
                    if( xkbGroup->optionInfos[i]->name == keyboardConfig->xkbOptions[idx] ) {
 
469
                        setData(createIndex(i, index.column(), (quint32)index.internalId()-index.row()+i), Qt::Unchecked, role);
 
470
                        break;
 
471
                    }
 
472
            //    m_kxkbConfig->m_options.removeAt(idx);
 
473
            //    idx = m_kxkbConfig->m_options.indexOf(QRegExp(xkbGroupNm+".*"));
 
474
            }
 
475
        }
 
476
        if( keyboardConfig->xkbOptions.indexOf(option->name) < 0 ) {
 
477
            keyboardConfig->xkbOptions.append(option->name);
 
478
        }
 
479
    }
 
480
    else {
 
481
        keyboardConfig->xkbOptions.removeAll(option->name);
 
482
    }
 
483
 
 
484
    emit dataChanged(index, index);
 
485
    emit dataChanged(index.parent(), index.parent());
 
486
    return true;
 
487
}
 
488
 
 
489
void XkbOptionsTreeModel::gotoGroup(const QString& groupName, QTreeView* view) {
 
490
        const OptionGroupInfo* optionGroupInfo = rules->getOptionGroupInfo(groupName);
 
491
    int index = rules->optionGroupInfos.indexOf((OptionGroupInfo*)optionGroupInfo);
 
492
    if( index != -1 ) {
 
493
        QModelIndex modelIdx = createIndex(index,0);
 
494
//            view->selectionModel()->setCurrentIndex(createIndex(index,0), QItemSelectionModel::NoUpdate);
 
495
        view->setExpanded(modelIdx, true);
 
496
        view->scrollTo(modelIdx, QAbstractItemView::PositionAtTop);
 
497
        view->selectionModel()->setCurrentIndex(modelIdx, QItemSelectionModel::Current);
 
498
        view->setFocus(Qt::OtherFocusReason);
 
499
    }
 
500
//    else {
 
501
//        kDebug() << "can't scroll to group" << group;
 
502
//    }
 
503
}
 
504