From 54b263e7b69ef3c8dd7f2efa239e5f361a158c91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Thu, 17 Jan 2013 08:53:09 +0100 Subject: [PATCH] Add icons of selected desktop to Desktop TabBox To support this feature the DesktopModel is turned into a tree model with the desktops on the root level and the Client's at the next level. In the view a VisualDataModel is used which kind of supports a tree model by setting the root index. A list view is added underneath all the desktops showing the icons of the windows on the desktop one switches to. BUG: 306187 FIXED-IN: 4.11 REVIEW: 108445 --- tabbox/clientmodel.cpp | 2 +- tabbox/declarative.cpp | 21 +++++++++---- tabbox/desktopmodel.cpp | 58 +++++++++++++++++++++++++++-------- tabbox/qml/desktop.qml | 67 +++++++++++++++++++++++++++++++++++++++-- 4 files changed, 125 insertions(+), 23 deletions(-) diff --git a/tabbox/clientmodel.cpp b/tabbox/clientmodel.cpp index c8b1d19df2..c27d3ffa2d 100644 --- a/tabbox/clientmodel.cpp +++ b/tabbox/clientmodel.cpp @@ -62,7 +62,7 @@ QVariant ClientModel::data(const QModelIndex& index, int role) const return QVariant(); } - int clientIndex = index.row() * columnCount() + index.column(); + int clientIndex = index.row(); if (clientIndex >= m_clientList.count()) return QVariant(); QSharedPointer client = m_clientList[ clientIndex ].toStrongRef(); diff --git a/tabbox/declarative.cpp b/tabbox/declarative.cpp index 5beaf1bcf9..20f6cb1cf1 100644 --- a/tabbox/declarative.cpp +++ b/tabbox/declarative.cpp @@ -64,15 +64,24 @@ QPixmap ImageProvider::requestPixmap(const QString &id, QSize *size, const QSize QStringList parts = id.split('/'); const int row = parts.first().toInt(&ok); if (!ok) { - return QDeclarativeImageProvider::requestPixmap(id, size, requestedSize); + return QPixmap(); } - const QModelIndex index = m_model->index(row, 0); + QModelIndex parentIndex; + const int parentRow = parts.at(1).toInt(&ok); + if (ok) { + // we have parent index + parentIndex = m_model->index(parentRow, 0); + if (!parentIndex.isValid()) { + return QPixmap(); + } + } + const QModelIndex index = m_model->index(row, 0, parentIndex); if (!index.isValid()) { - return QDeclarativeImageProvider::requestPixmap(id, size, requestedSize); + return QPixmap(); } TabBoxClient* client = static_cast< TabBoxClient* >(index.model()->data(index, ClientModel::ClientRole).value()); if (!client) { - return QDeclarativeImageProvider::requestPixmap(id, size, requestedSize); + return QPixmap(); } QSize s(32, 32); @@ -92,9 +101,9 @@ QPixmap ImageProvider::requestPixmap(const QString &id, QSize *size, const QSize if (parts.size() > 2) { KIconEffect *effect = KIconLoader::global()->iconEffect(); KIconLoader::States state = KIconLoader::DefaultState; - if (parts.at(2) == QLatin1String("selected")) { + if (parts.last() == QLatin1String("selected")) { state = KIconLoader::ActiveState; - } else if (parts.at(2) == QLatin1String("disabled")) { + } else if (parts.last() == QLatin1String("disabled")) { state = KIconLoader::DisabledState; } icon = effect->apply(icon, KIconLoader::Desktop, state); diff --git a/tabbox/desktopmodel.cpp b/tabbox/desktopmodel.cpp index 0e43ce8e42..0839f7d3b0 100644 --- a/tabbox/desktopmodel.cpp +++ b/tabbox/desktopmodel.cpp @@ -42,10 +42,16 @@ DesktopModel::~DesktopModel() QVariant DesktopModel::data(const QModelIndex& index, int role) const { - if (!index.isValid()) + if (!index.isValid() || index.column() != 0) return QVariant(); - int desktopIndex = index.row() * columnCount() + index.column(); + if (index.parent().isValid()) { + // parent is valid -> access to Client + ClientModel *model = m_clientModels[ m_desktopList[ index.internalId() - 1] ]; + return model->data(model->index(index.row(), 0), role); + } + + const int desktopIndex = index.row(); if (desktopIndex >= m_desktopList.count()) return QVariant(); switch(role) { @@ -69,21 +75,49 @@ int DesktopModel::columnCount(const QModelIndex& parent) const int DesktopModel::rowCount(const QModelIndex& parent) const { - Q_UNUSED(parent) + if (parent.isValid()) { + if (parent.internalId() != 0 || parent.row() >= m_desktopList.count()) { + return 0; + } + const int desktop = m_desktopList.at(parent.row()); + const ClientModel *model = m_clientModels.value(desktop); + return model->rowCount(); + } return m_desktopList.count(); } QModelIndex DesktopModel::parent(const QModelIndex& child) const { - Q_UNUSED(child) - return QModelIndex(); + if (!child.isValid() || child.internalId() == 0) { + return QModelIndex(); + } + const int row = child.internalId() -1; + if (row >= m_desktopList.count()) { + return QModelIndex(); + } + return createIndex(row, 0); } QModelIndex DesktopModel::index(int row, int column, const QModelIndex& parent) const { - Q_UNUSED(parent) - int index = row * columnCount() + column; - if (index > m_desktopList.count() || m_desktopList.isEmpty()) + if (column != 0) { + return QModelIndex(); + } + if (row < 0) { + return QModelIndex(); + } + if (parent.isValid()) { + if (parent.row() < 0 || parent.row() >= m_desktopList.count() || parent.internalId() != 0) { + return QModelIndex(); + } + const int desktop = m_desktopList.at(parent.row()); + const ClientModel *model = m_clientModels.value(desktop); + if (row >= model->rowCount()) { + return QModelIndex(); + } + return createIndex(row, column, parent.row() + 1); + } + if (row > m_desktopList.count() || m_desktopList.isEmpty()) return QModelIndex(); return createIndex(row, column); } @@ -92,14 +126,12 @@ QModelIndex DesktopModel::desktopIndex(int desktop) const { if (desktop > m_desktopList.count()) return QModelIndex(); - int index = m_desktopList.indexOf(desktop); - int row = index / columnCount(); - int column = index % columnCount(); - return createIndex(row, column); + return createIndex(m_desktopList.indexOf(desktop), 0); } void DesktopModel::createDesktopList() { + beginResetModel(); m_desktopList.clear(); qDeleteAll(m_clientModels); m_clientModels.clear(); @@ -126,7 +158,7 @@ void DesktopModel::createDesktopList() break; } } - reset(); + endResetModel(); } } // namespace Tabbox diff --git a/tabbox/qml/desktop.qml b/tabbox/qml/desktop.qml index 6c24ef32ea..0f43e37e23 100644 --- a/tabbox/qml/desktop.qml +++ b/tabbox/qml/desktop.qml @@ -28,7 +28,7 @@ Item { property bool allDesktops: true property string longestCaption: "" property int optimalWidth: listView.maxRowWidth - property int optimalHeight: listView.rowHeight * listView.count + background.topMargin + background.bottomMargin + property int optimalHeight: listView.rowHeight * listView.count + clientArea.height + 4 + background.topMargin + background.bottomMargin property bool canStretchX: true property bool canStretchY: false property string maskImagePath: background.maskImagePath @@ -47,9 +47,16 @@ Item { function setModel(model) { listView.model = model; + desktopClientModel.model = model; + desktopClientModel.imageId++; listView.maxRowWidth = listView.calculateMaxRowWidth(); } + function modelChanged() { + listView.currentIndex = -1; + desktopClientModel.imageId++; + } + PlasmaCore.Theme { id: theme } @@ -153,11 +160,14 @@ Item { // used for image provider URL to trick Qt into reloading icons when the model changes property int imageId: 0 anchors { - fill: parent + top: parent.top + left: parent.left + right: parent.right + bottom: clientArea.top topMargin: background.topMargin leftMargin: background.leftMargin rightMargin: background.rightMargin - bottomMargin: background.bottomMargin + bottomMargin: clientArea.top } clip: true delegate: listDelegate @@ -170,4 +180,55 @@ Item { highlightMoveDuration: 250 boundsBehavior: Flickable.StopAtBounds } + Component { + id: clientIconDelegate + Image { + sourceSize { + width: 16 + height: 16 + } + width: 16 + height: 16 + Component.onCompleted: { + source = "image://client/" + index + "/" + listView.currentIndex + "/" + desktopClientModel.imagePathPrefix + "-" + desktopClientModel.imageId; + } + } + } + Item { + id: clientArea + VisualDataModel { + property alias desktopIndex: listView.currentIndex + property int imagePathPrefix: (new Date()).getTime() + property int imageId: 0 + id: desktopClientModel + model: clientModel + delegate: clientIconDelegate + onDesktopIndexChanged: { + desktopClientModel.imageId++; + desktopClientModel.rootIndex = desktopClientModel.parentModelIndex(); + desktopClientModel.rootIndex = desktopClientModel.modelIndex(desktopClientModel.desktopIndex); + } + } + ListView { + id: iconsListView + model: desktopClientModel + clip: true + orientation: ListView.Horizontal + spacing: 4 + anchors { + fill: parent + leftMargin: 34 + } + } + height: 18 + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + topMargin: 2 + leftMargin: background.leftMargin + rightMargin: background.rightMargin + bottomMargin: background.bottomMargin + } + } }