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

« back to all changes in this revision

Viewing changes to kwin/tabbox/tabboxhandler.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
 KWin - the KDE window manager
 
3
 This file is part of the KDE project.
 
4
 
 
5
Copyright (C) 2009 Martin Gräßlin <kde@martin-graesslin.com>
 
6
 
 
7
This program is free software; you can redistribute it and/or modify
 
8
it under the terms of the GNU General Public License as published by
 
9
the Free Software Foundation; either version 2 of the License, or
 
10
(at your option) any later version.
 
11
 
 
12
This program is distributed in the hope that it will be useful,
 
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
GNU General Public License for more details.
 
16
 
 
17
You should have received a copy of the GNU General Public License
 
18
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
19
*********************************************************************/
 
20
 
 
21
// own
 
22
#include "tabboxhandler.h"
 
23
// tabbox
 
24
#include "clientitemdelegate.h"
 
25
#include "clientmodel.h"
 
26
#include "desktopitemdelegate.h"
 
27
#include "desktopmodel.h"
 
28
#include "itemlayoutconfig.h"
 
29
#include "tabboxconfig.h"
 
30
#include "tabboxview.h"
 
31
// Qt
 
32
#include <qdom.h>
 
33
#include <QFile>
 
34
#include <QKeyEvent>
 
35
#include <QModelIndex>
 
36
#include <QPainter>
 
37
#include <QX11Info>
 
38
#include <X11/Xlib.h>
 
39
// KDE
 
40
#include <KDebug>
 
41
#include <KStandardDirs>
 
42
#include <KWindowSystem>
 
43
 
 
44
namespace KWin
 
45
{
 
46
namespace TabBox
 
47
{
 
48
 
 
49
class TabBoxHandlerPrivate
 
50
{
 
51
public:
 
52
    TabBoxHandlerPrivate(TabBoxHandler *q);
 
53
 
 
54
    ~TabBoxHandlerPrivate();
 
55
 
 
56
    /**
 
57
    * Updates the currently shown outline.
 
58
    */
 
59
    void updateOutline();
 
60
    /**
 
61
    * Updates the current highlight window state
 
62
    */
 
63
    void updateHighlightWindows();
 
64
    /**
 
65
    * Ends window highlighting
 
66
    */
 
67
    void endHighlightWindows(bool abort = false);
 
68
 
 
69
    ClientModel* clientModel() const;
 
70
    DesktopModel* desktopModel() const;
 
71
    void parseConfig(const QString& fileName);
 
72
 
 
73
    TabBoxHandler *q; // public pointer
 
74
    // members
 
75
    TabBoxConfig config;
 
76
    TabBoxView* view;
 
77
    QModelIndex index;
 
78
    Window outlineLeft;
 
79
    Window outlineRight;
 
80
    Window outlineTop;
 
81
    Window outlineBottom;
 
82
    /**
 
83
    * Indicates if the tabbox is shown.
 
84
    * Used to determine if the outline has to be updated, etc.
 
85
    */
 
86
    bool isShown;
 
87
    QMap< QString, ItemLayoutConfig > tabBoxLayouts;
 
88
    TabBoxClient *lastRaisedClient, *lastRaisedClientSucc;
 
89
};
 
90
 
 
91
TabBoxHandlerPrivate::TabBoxHandlerPrivate(TabBoxHandler *q)
 
92
{
 
93
    this->q = q;
 
94
    isShown = false;
 
95
    lastRaisedClient = 0;
 
96
    lastRaisedClientSucc = 0;
 
97
    config = TabBoxConfig();
 
98
    view = new TabBoxView();
 
99
    XSetWindowAttributes attr;
 
100
    attr.override_redirect = 1;
 
101
    outlineLeft = XCreateWindow(QX11Info::display(), QX11Info::appRootWindow(), 0, 0, 1, 1, 0,
 
102
                                CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr);
 
103
    outlineRight = XCreateWindow(QX11Info::display(), QX11Info::appRootWindow(), 0, 0, 1, 1, 0,
 
104
                                 CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr);
 
105
    outlineTop = XCreateWindow(QX11Info::display(), QX11Info::appRootWindow(), 0, 0, 1, 1, 0,
 
106
                               CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr);
 
107
    outlineBottom = XCreateWindow(QX11Info::display(), QX11Info::appRootWindow(), 0, 0, 1, 1, 0,
 
108
                                  CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr);
 
109
 
 
110
    // load the layouts
 
111
    parseConfig(KStandardDirs::locate("data", "kwin/DefaultTabBoxLayouts.xml"));
 
112
    view->clientDelegate()->setConfig(tabBoxLayouts.value("Default"));
 
113
    view->additionalClientDelegate()->setConfig(tabBoxLayouts.value("Text"));
 
114
    view->desktopDelegate()->setConfig(tabBoxLayouts.value("Desktop"));
 
115
    view->desktopDelegate()->setLayouts(tabBoxLayouts);
 
116
}
 
117
 
 
118
TabBoxHandlerPrivate::~TabBoxHandlerPrivate()
 
119
{
 
120
    delete view;
 
121
}
 
122
 
 
123
ClientModel* TabBoxHandlerPrivate::clientModel() const
 
124
{
 
125
    return view->clientModel();
 
126
}
 
127
 
 
128
DesktopModel* TabBoxHandlerPrivate::desktopModel() const
 
129
{
 
130
    return view->desktopModel();
 
131
}
 
132
 
 
133
void TabBoxHandlerPrivate::updateOutline()
 
134
{
 
135
    if (config.tabBoxMode() != TabBoxConfig::ClientTabBox)
 
136
        return;
 
137
//     if ( c == NULL || !m_isShown || !c->isShown( true ) || !c->isOnCurrentDesktop())
 
138
    if (!isShown || view->clientModel()->data(index, ClientModel::EmptyRole).toBool()) {
 
139
        q->hideOutline();
 
140
        return;
 
141
    }
 
142
    TabBoxClient* c = static_cast< TabBoxClient* >(
 
143
                          view->clientModel()->data(index, ClientModel::ClientRole).value<void *>());
 
144
    q->showOutline(QRect(c->x(), c->y(), c->width(), c->height()));
 
145
}
 
146
 
 
147
void TabBoxHandlerPrivate::updateHighlightWindows()
 
148
{
 
149
    if (!isShown || config.tabBoxMode() != TabBoxConfig::ClientTabBox)
 
150
        return;
 
151
 
 
152
    Display *dpy = QX11Info::display();
 
153
    TabBoxClient *currentClient = q->client(index);
 
154
 
 
155
    if (!KWindowSystem::compositingActive()) {
 
156
        if (lastRaisedClient) {
 
157
            if (lastRaisedClientSucc)
 
158
                q->restack(lastRaisedClient, lastRaisedClientSucc);
 
159
            // TODO lastRaisedClient->setMinimized( lastRaisedClientWasMinimized );
 
160
        }
 
161
 
 
162
        lastRaisedClient = currentClient;
 
163
        if (lastRaisedClient) {
 
164
            // TODO if ( (lastRaisedClientWasMinimized = lastRaisedClient->isMinimized()) )
 
165
            //         lastRaisedClient->setMinimized( false );
 
166
            TabBoxClientList order = q->stackingOrder();
 
167
            int succIdx = order.indexOf(lastRaisedClient) + 1;   // this is likely related to the index parameter?!
 
168
            lastRaisedClientSucc = (succIdx < order.count()) ? order.at(succIdx) : 0;
 
169
            q->raiseClient(lastRaisedClient);
 
170
        }
 
171
    }
 
172
 
 
173
    WId wId;
 
174
    QVector< WId > data;
 
175
    if (config.isShowTabBox()) {
 
176
        wId = view->winId();
 
177
        data.resize(2);
 
178
        data[ 1 ] = wId;
 
179
    } else {
 
180
        wId = QX11Info::appRootWindow();
 
181
        data.resize(1);
 
182
    }
 
183
    data[ 0 ] = currentClient ? currentClient->window() : 0L;
 
184
    if (config.isShowOutline()) {
 
185
        QVector<Window> outlineWindows = q->outlineWindowIds();
 
186
        data.resize(2+outlineWindows.size());
 
187
        for (int i=0; i<outlineWindows.size(); ++i) {
 
188
            data[2+i] = outlineWindows[i];
 
189
        }
 
190
    }
 
191
    Atom atom = XInternAtom(dpy, "_KDE_WINDOW_HIGHLIGHT", False);
 
192
    XChangeProperty(dpy, wId, atom, atom, 32, PropModeReplace,
 
193
                    reinterpret_cast<unsigned char *>(data.data()), data.size());
 
194
}
 
195
 
 
196
void TabBoxHandlerPrivate::endHighlightWindows(bool abort)
 
197
{
 
198
    if (abort && lastRaisedClient && lastRaisedClientSucc)
 
199
        q->restack(lastRaisedClient, lastRaisedClientSucc);
 
200
    lastRaisedClient = 0;
 
201
    lastRaisedClientSucc = 0;
 
202
    // highlight windows
 
203
    Display *dpy = QX11Info::display();
 
204
    Atom atom = XInternAtom(dpy, "_KDE_WINDOW_HIGHLIGHT", False);
 
205
    XDeleteProperty(dpy, config.isShowTabBox() ? view->winId() : QX11Info::appRootWindow(), atom);
 
206
}
 
207
 
 
208
/***********************************************************
 
209
* Based on the implementation of Kopete's
 
210
* contaclistlayoutmanager.cpp by Nikolaj Hald Nielsen and
 
211
* Roman Jarosz
 
212
***********************************************************/
 
213
void TabBoxHandlerPrivate::parseConfig(const QString& fileName)
 
214
{
 
215
    // open the file
 
216
    if (!QFile::exists(fileName)) {
 
217
        kDebug(1212) << "File " << fileName << " does not exist";
 
218
        return;
 
219
    }
 
220
    QDomDocument doc("Layouts");
 
221
    QFile file(fileName);
 
222
    if (!file.open(QIODevice::ReadOnly)) {
 
223
        kDebug(1212) << "Error reading file " << fileName;
 
224
        return;
 
225
    }
 
226
    if (!doc.setContent(&file)) {
 
227
        kDebug(1212) << "Error parsing file " << fileName;
 
228
        file.close();
 
229
        return;
 
230
    }
 
231
    file.close();
 
232
 
 
233
    QDomElement layouts_element = doc.firstChildElement("tabbox_layouts");
 
234
    QDomNodeList layouts = layouts_element.elementsByTagName("layout");
 
235
 
 
236
    for (int i = 0; i < layouts.size(); i++) {
 
237
        QDomNode layout = layouts.item(i);
 
238
        ItemLayoutConfig currentLayout;
 
239
 
 
240
        // parse top elements
 
241
        QDomElement element = layout.toElement();
 
242
        QString layoutName = element.attribute("name", "");
 
243
 
 
244
        const bool highlightIcon = (element.attribute("highlight_selected_icon", "true").compare("true", Qt::CaseInsensitive) == 0);
 
245
        currentLayout.setHighlightSelectedIcons(highlightIcon);
 
246
 
 
247
        const bool grayscaleIcon = (element.attribute("grayscale_deselected_icon", "false").compare("true", Qt::CaseInsensitive) == 0);
 
248
        currentLayout.setGrayscaleDeselectedIcons(grayscaleIcon);
 
249
 
 
250
        // rows
 
251
        QDomNodeList rows = element.elementsByTagName("row");
 
252
        for (int j = 0; j < rows.size(); j++) {
 
253
            QDomNode rowNode = rows.item(j);
 
254
 
 
255
            ItemLayoutConfigRow row;
 
256
 
 
257
            QDomNodeList elements = rowNode.toElement().elementsByTagName("element");
 
258
            for (int k = 0; k < elements.size(); k++) {
 
259
                QDomNode elementNode = elements.item(k);
 
260
                QDomElement currentElement = elementNode.toElement();
 
261
 
 
262
                ItemLayoutConfigRowElement::ElementType type = ItemLayoutConfigRowElement::ElementType(currentElement.attribute(
 
263
                            "type", int(ItemLayoutConfigRowElement::ElementClientName)).toInt());
 
264
                ItemLayoutConfigRowElement currentRowElement;
 
265
                currentRowElement.setType(type);
 
266
 
 
267
                // width - used by all types
 
268
                qreal width = currentElement.attribute("width", "0.0").toDouble();
 
269
                currentRowElement.setWidth(width);
 
270
                switch(type) {
 
271
                case ItemLayoutConfigRowElement::ElementEmpty:
 
272
                    row.addElement(currentRowElement);
 
273
                    break;
 
274
                case ItemLayoutConfigRowElement::ElementIcon: {
 
275
                    qreal iconWidth = currentElement.attribute("icon_size", "16.0").toDouble();
 
276
                    currentRowElement.setIconSize(QSizeF(iconWidth, iconWidth));
 
277
                    currentRowElement.setRowSpan(currentElement.attribute("row_span", "true").compare(
 
278
                                                     "true", Qt::CaseInsensitive) == 0);
 
279
                    row.addElement(currentRowElement);
 
280
                    break;
 
281
                }
 
282
                case ItemLayoutConfigRowElement::ElementClientList: {
 
283
                    currentRowElement.setStretch(currentElement.attribute("stretch", "false").compare(
 
284
                                                     "true", Qt::CaseInsensitive) == 0);
 
285
                    currentRowElement.setClientListLayoutName(currentElement.attribute("layout_name", ""));
 
286
                    QString layoutMode = currentElement.attribute("layout_mode", "horizontal");
 
287
                    if (layoutMode.compare("horizontal", Qt::CaseInsensitive) == 0)
 
288
                        currentRowElement.setClientListLayoutMode(TabBoxConfig::HorizontalLayout);
 
289
                    else if (layoutMode.compare("vertical", Qt::CaseInsensitive) == 0)
 
290
                        currentRowElement.setClientListLayoutMode(TabBoxConfig::VerticalLayout);
 
291
                    else if (layoutMode.compare("tabular", Qt::CaseInsensitive) == 0)
 
292
                        currentRowElement.setClientListLayoutMode(TabBoxConfig::HorizontalVerticalLayout);
 
293
                    row.addElement(currentRowElement);
 
294
                    break;
 
295
                }
 
296
                default: { // text elements
 
297
                    currentRowElement.setStretch(currentElement.attribute("stretch", "false").compare(
 
298
                                                     "true", Qt::CaseInsensitive) == 0);
 
299
                    currentRowElement.setSmallTextSize(currentElement.attribute("small", "false").compare(
 
300
                                                           "true", Qt::CaseInsensitive) == 0);
 
301
                    currentRowElement.setBold(currentElement.attribute("bold", "false").compare(
 
302
                                                  "true", Qt::CaseInsensitive) == 0);
 
303
                    currentRowElement.setItalic(currentElement.attribute("italic", "false").compare(
 
304
                                                    "true", Qt::CaseInsensitive) == 0);
 
305
                    currentRowElement.setItalicMinimized(currentElement.attribute("italic_minimized", "true").compare(
 
306
                            "true", Qt::CaseInsensitive) == 0);
 
307
 
 
308
                    currentRowElement.setPrefix(currentElement.attribute("prefix", ""));
 
309
                    currentRowElement.setSuffix(currentElement.attribute("suffix", ""));
 
310
                    currentRowElement.setPrefixMinimized(currentElement.attribute("prefix_minimized", ""));
 
311
                    currentRowElement.setSuffixMinimzed(currentElement.attribute("suffix_minimized", ""));
 
312
 
 
313
                    QString halign = currentElement.attribute("horizontal_alignment", "left");
 
314
                    Qt::Alignment alignment;
 
315
                    if (halign.compare("left", Qt::CaseInsensitive) == 0)
 
316
                        alignment = Qt::AlignLeft;
 
317
                    else if (halign.compare("right", Qt::CaseInsensitive) == 0)
 
318
                        alignment = Qt::AlignRight;
 
319
                    else
 
320
                        alignment = Qt::AlignCenter;
 
321
                    QString valign = currentElement.attribute("vertical_alignment", "center");
 
322
                    if (valign.compare("top", Qt::CaseInsensitive) == 0)
 
323
                        alignment = alignment | Qt::AlignTop;
 
324
                    else if (valign.compare("bottom", Qt::CaseInsensitive) == 0)
 
325
                        alignment = alignment | Qt::AlignBottom;
 
326
                    else
 
327
                        alignment = alignment | Qt::AlignVCenter;
 
328
                    currentRowElement.setAlignment(alignment);
 
329
 
 
330
                    row.addElement(currentRowElement);
 
331
                    break;
 
332
                }// case default
 
333
                } // switch type
 
334
            } // for loop elements
 
335
 
 
336
            currentLayout.addRow(row);
 
337
        } // for loop rows
 
338
        if (!layoutName.isEmpty()) {
 
339
            tabBoxLayouts.insert(layoutName, currentLayout);
 
340
        }
 
341
    } // for loop layouts
 
342
}
 
343
 
 
344
/***********************************************
 
345
* TabBoxHandler
 
346
***********************************************/
 
347
 
 
348
TabBoxHandler::TabBoxHandler()
 
349
    : QObject()
 
350
{
 
351
    KWin::TabBox::tabBox = this;
 
352
    d = new TabBoxHandlerPrivate(this);
 
353
}
 
354
 
 
355
TabBoxHandler::~TabBoxHandler()
 
356
{
 
357
    delete d;
 
358
}
 
359
 
 
360
const KWin::TabBox::TabBoxConfig& TabBoxHandler::config() const
 
361
{
 
362
    return d->config;
 
363
}
 
364
 
 
365
void TabBoxHandler::setConfig(const TabBoxConfig& config)
 
366
{
 
367
    if (config.layoutName() != d->config.layoutName()) {
 
368
        // new item layout config
 
369
        if (d->tabBoxLayouts.contains(config.layoutName())) {
 
370
            d->view->clientDelegate()->setConfig(d->tabBoxLayouts.value(config.layoutName()));
 
371
            d->view->desktopDelegate()->setConfig(d->tabBoxLayouts.value(config.layoutName()));
 
372
        }
 
373
    }
 
374
    if (config.selectedItemLayoutName() != d->config.selectedItemLayoutName()) {
 
375
        // TODO: desktop layouts
 
376
        if (d->tabBoxLayouts.contains(config.selectedItemLayoutName()))
 
377
            d->view->additionalClientDelegate()->setConfig(d->tabBoxLayouts.value(config.selectedItemLayoutName()));
 
378
    }
 
379
    d->config = config;
 
380
    emit configChanged();
 
381
}
 
382
 
 
383
void TabBoxHandler::show()
 
384
{
 
385
    d->isShown = true;
 
386
    d->lastRaisedClient = 0;
 
387
    d->lastRaisedClientSucc = 0;
 
388
    // show the outline
 
389
    if (d->config.isShowOutline()) {
 
390
        d->updateOutline();
 
391
    }
 
392
    if (d->config.isShowTabBox()) {
 
393
        d->view->show();
 
394
        d->view->updateGeometry();
 
395
    }
 
396
    if (d->config.isHighlightWindows()) {
 
397
        d->updateHighlightWindows();
 
398
    }
 
399
}
 
400
 
 
401
void TabBoxHandler::hide(bool abort)
 
402
{
 
403
    d->isShown = false;
 
404
    if (d->config.isHighlightWindows()) {
 
405
        d->endHighlightWindows(abort);
 
406
    }
 
407
    if (d->config.isShowOutline()) {
 
408
        hideOutline();
 
409
    }
 
410
    d->view->hide();
 
411
}
 
412
 
 
413
QModelIndex TabBoxHandler::nextPrev(bool forward) const
 
414
{
 
415
    QModelIndex ret;
 
416
    QAbstractItemModel* model;
 
417
    switch(d->config.tabBoxMode()) {
 
418
    case TabBoxConfig::ClientTabBox:
 
419
        model = d->clientModel();
 
420
        break;
 
421
    case TabBoxConfig::DesktopTabBox:
 
422
        model = d->desktopModel();
 
423
        break;
 
424
    default:
 
425
        return d->index;
 
426
    }
 
427
    if (forward) {
 
428
        int column = d->index.column() + 1;
 
429
        int row = d->index.row();
 
430
        if (column == model->columnCount()) {
 
431
            column = 0;
 
432
            row++;
 
433
            if (row == model->rowCount())
 
434
                row = 0;
 
435
        }
 
436
        ret = model->index(row, column);
 
437
        if (!ret.isValid())
 
438
            ret = model->index(0, 0);
 
439
    } else {
 
440
        int column = d->index.column() - 1;
 
441
        int row = d->index.row();
 
442
        if (column < 0) {
 
443
            column = model->columnCount() - 1;
 
444
            row--;
 
445
            if (row < 0)
 
446
                row = model->rowCount() - 1;
 
447
        }
 
448
        ret = model->index(row, column);
 
449
        if (!ret.isValid()) {
 
450
            row = model->rowCount() - 1;
 
451
            for (int i = model->columnCount() - 1; i >= 0; i--) {
 
452
                ret = model->index(row, i);
 
453
                if (ret.isValid())
 
454
                    break;
 
455
            }
 
456
        }
 
457
    }
 
458
    if (ret.isValid())
 
459
        return ret;
 
460
    else
 
461
        return d->index;
 
462
}
 
463
 
 
464
QModelIndex TabBoxHandler::desktopIndex(int desktop) const
 
465
{
 
466
    if (d->config.tabBoxMode() != TabBoxConfig::DesktopTabBox)
 
467
        return QModelIndex();
 
468
    return d->desktopModel()->desktopIndex(desktop);
 
469
}
 
470
 
 
471
QList< int > TabBoxHandler::desktopList() const
 
472
{
 
473
    if (d->config.tabBoxMode() != TabBoxConfig::DesktopTabBox)
 
474
        return QList< int >();
 
475
    return d->desktopModel()->desktopList();
 
476
}
 
477
 
 
478
int TabBoxHandler::desktop(const QModelIndex& index) const
 
479
{
 
480
    if (!index.isValid() || (d->config.tabBoxMode() != TabBoxConfig::DesktopTabBox))
 
481
        return -1;
 
482
    QVariant ret = d->desktopModel()->data(index, DesktopModel::DesktopRole);
 
483
    if (ret.isValid())
 
484
        return ret.toInt();
 
485
    else
 
486
        return -1;
 
487
}
 
488
 
 
489
int TabBoxHandler::currentSelectedDesktop() const
 
490
{
 
491
    return desktop(d->index);
 
492
}
 
493
 
 
494
void TabBoxHandler::setCurrentIndex(const QModelIndex& index)
 
495
{
 
496
    d->view->setCurrentIndex(index);
 
497
    d->index = index;
 
498
    if (d->config.tabBoxMode() == TabBoxConfig::ClientTabBox) {
 
499
        if (d->config.isShowOutline()) {
 
500
            d->updateOutline();
 
501
        }
 
502
        if (d->config.isHighlightWindows()) {
 
503
            d->updateHighlightWindows();
 
504
        }
 
505
    }
 
506
}
 
507
 
 
508
QModelIndex TabBoxHandler::grabbedKeyEvent(QKeyEvent* event) const
 
509
{
 
510
    QModelIndex ret;
 
511
    QAbstractItemModel* model;
 
512
    switch(d->config.tabBoxMode()) {
 
513
    case TabBoxConfig::ClientTabBox:
 
514
        model = d->clientModel();
 
515
        break;
 
516
    case TabBoxConfig::DesktopTabBox:
 
517
        model = d->desktopModel();
 
518
        break;
 
519
    default:
 
520
        return d->index;
 
521
    }
 
522
    int column = d->index.column();
 
523
    int row = d->index.row();
 
524
    switch(event->key()) {
 
525
    case Qt::Key_Left:
 
526
        column--;
 
527
        if (column < 0)
 
528
            column = model->columnCount() - 1;
 
529
        break;
 
530
    case Qt::Key_Right:
 
531
        column++;
 
532
        if (column >= model->columnCount())
 
533
            column = 0;
 
534
        break;
 
535
    case Qt::Key_Up:
 
536
        row--;
 
537
        if (row < 0)
 
538
            row = model->rowCount() - 1;
 
539
        break;
 
540
    case Qt::Key_Down:
 
541
        row++;
 
542
        if (row >= model->rowCount())
 
543
            row = 0;
 
544
        break;
 
545
    default:
 
546
        // do not do anything for any other key
 
547
        break;
 
548
    }
 
549
    ret = model->index(row, column);
 
550
 
 
551
    if (ret.isValid())
 
552
        return ret;
 
553
    else
 
554
        return d->index;
 
555
}
 
556
 
 
557
bool TabBoxHandler::containsPos(const QPoint& pos) const
 
558
{
 
559
    return d->view->geometry().contains(pos);
 
560
}
 
561
 
 
562
QModelIndex TabBoxHandler::indexAt(const QPoint& pos) const
 
563
{
 
564
    QPoint widgetPos = d->view->mapFromGlobal(pos);
 
565
    QModelIndex ret = d->view->indexAt(widgetPos);
 
566
    return ret;
 
567
}
 
568
 
 
569
QModelIndex TabBoxHandler::index(KWin::TabBox::TabBoxClient* client) const
 
570
{
 
571
    return d->clientModel()->index(client);
 
572
}
 
573
 
 
574
TabBoxClientList TabBoxHandler::clientList() const
 
575
{
 
576
    if (d->config.tabBoxMode() != TabBoxConfig::ClientTabBox)
 
577
        return TabBoxClientList();
 
578
    return d->clientModel()->clientList();
 
579
}
 
580
 
 
581
TabBoxClient* TabBoxHandler::client(const QModelIndex& index) const
 
582
{
 
583
    if ((!index.isValid()) ||
 
584
            (d->config.tabBoxMode() != TabBoxConfig::ClientTabBox) ||
 
585
            (d->clientModel()->data(index, ClientModel::EmptyRole).toBool()))
 
586
        return NULL;
 
587
    TabBoxClient* c = static_cast< TabBoxClient* >(
 
588
                          d->clientModel()->data(index, ClientModel::ClientRole).value<void *>());
 
589
    return c;
 
590
}
 
591
 
 
592
void TabBoxHandler::createModel(bool partialReset)
 
593
{
 
594
    switch(d->config.tabBoxMode()) {
 
595
    case TabBoxConfig::ClientTabBox:
 
596
        d->clientModel()->createClientList(partialReset);
 
597
        if (d->lastRaisedClient && !stackingOrder().contains(d->lastRaisedClient))
 
598
            d->lastRaisedClient = 0;
 
599
        if (d->lastRaisedClientSucc && !stackingOrder().contains(d->lastRaisedClientSucc))
 
600
            d->lastRaisedClientSucc = 0;
 
601
        break;
 
602
    case TabBoxConfig::DesktopTabBox:
 
603
        d->desktopModel()->createDesktopList();
 
604
        break;
 
605
    }
 
606
    d->view->updateGeometry();
 
607
}
 
608
 
 
609
QModelIndex TabBoxHandler::first() const
 
610
{
 
611
    QAbstractItemModel* model;
 
612
    switch(d->config.tabBoxMode()) {
 
613
    case TabBoxConfig::ClientTabBox:
 
614
        model = d->clientModel();
 
615
        break;
 
616
    case TabBoxConfig::DesktopTabBox:
 
617
        model = d->desktopModel();
 
618
        break;
 
619
    default:
 
620
        return QModelIndex();
 
621
    }
 
622
    return model->index(0, 0);
 
623
}
 
624
 
 
625
QWidget* TabBoxHandler::tabBoxView() const
 
626
{
 
627
    return d->view;
 
628
}
 
629
 
 
630
TabBoxHandler* tabBox = 0;
 
631
 
 
632
TabBoxClient::TabBoxClient()
 
633
{
 
634
}
 
635
 
 
636
TabBoxClient::~TabBoxClient()
 
637
{
 
638
}
 
639
 
 
640
} // namespace TabBox
 
641
} // namespace KWin