From bf039428e22a10887e8d85a95ff5f38dc17e7ec2 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Mon, 14 Mar 2016 20:41:35 +0100 Subject: Multi-Account support in the folderview --- .../package/contents/ui/MaildirAccountSettings.qml | 28 ++- components/package/contents/ui/FolderListView.qml | 202 ++++++++++++++++----- components/package/contents/ui/Settings.qml | 2 + framework/domain/CMakeLists.txt | 1 + framework/domain/accountsmodel.cpp | 65 +++++++ framework/domain/accountsmodel.h | 48 +++++ framework/domain/folderlistmodel.cpp | 34 +++- framework/domain/folderlistmodel.h | 10 + framework/domain/mailplugin.cpp | 2 + 9 files changed, 338 insertions(+), 54 deletions(-) create mode 100644 framework/domain/accountsmodel.cpp create mode 100644 framework/domain/accountsmodel.h diff --git a/accounts/maildir/package/contents/ui/MaildirAccountSettings.qml b/accounts/maildir/package/contents/ui/MaildirAccountSettings.qml index 61828f34..3b2dbd35 100644 --- a/accounts/maildir/package/contents/ui/MaildirAccountSettings.qml +++ b/accounts/maildir/package/contents/ui/MaildirAccountSettings.qml @@ -28,7 +28,8 @@ import org.kube.accounts.maildir 1.0 as MaildirAccount Rectangle { id: root property string accountId - property string accountName: "Maildir" + property string accountName + property string icon color: ColorPalette.background @@ -40,7 +41,22 @@ Rectangle { Text { Layout.columnSpan: 2 Layout.fillWidth: true - text: "Account: " + accountName + text: "General:" + } + + Label { text: "Account Name" } + TextField { + id: name + placeholderText: accountName + Layout.fillWidth: true + text: accountSettings.name + onTextChanged: { accountSettings.name = text; } + } + + Text { + Layout.columnSpan: 2 + Layout.fillWidth: true + text: "Maildir:" } Label { text: "Path" } @@ -133,11 +149,19 @@ Rectangle { property string password; } + KubeSettings.Settings { + id: accountSettings + identifier: "account." + accountId + property string name; + property string icon: root.icon; + } + Button { text: "Save" onClicked: { transportSettings.save(); maildirSettings.save(); + accountSettings.save(); } } Button { diff --git a/components/package/contents/ui/FolderListView.qml b/components/package/contents/ui/FolderListView.qml index fafc1623..f660846d 100644 --- a/components/package/contents/ui/FolderListView.qml +++ b/components/package/contents/ui/FolderListView.qml @@ -46,72 +46,174 @@ Item { } } - TreeView { - id: treeView + Rectangle { anchors { top: searchBox.bottom left: parent.left right: parent.right bottom: parent.bottom } - TableViewColumn { - title: "Name" - role: "name" - width: treeView.width - 5 - } - model: KubeFramework.FolderListModel { id: folderListModel } - onCurrentIndexChanged: { - model.fetchMore(currentIndex) - root.currentFolder = model.data(currentIndex, KubeFramework.FolderListModel.DomainObject) - } - backgroundVisible: false - headerVisible: false - style: TreeViewStyle { - activateItemOnSingleClick: true - rowDelegate: Rectangle { - height: Unit.size * 10 - color: "transparent" + color: "white" + ScrollView { + anchors.fill: parent + ListView { + id: listView + anchors.fill: parent + delegate: accountDelegate + model: KubeFramework.AccountsModel { id: accountsModel } } - itemDelegate: Rectangle { - radius: 5 - border.width: 1 - border.color: "lightgrey" - color: styleData.selected ? colorPalette.highlight : colorPalette.button + } + } + + Component { + id: accountDelegate + + Item { + id: wrapper + + property var accountId: model.accountId + + width: listView.width + height: 30 + + Rectangle { + id: headerView + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + + height: 30 + + color: "#333" + border.color: Qt.lighter(color, 1.2) PlasmaCore.IconItem { id: iconItem - anchors { - verticalCenter: parent.verticalCenter - left: parent.left - leftMargin: Unit.size * 3 - } + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + anchors.leftMargin: 4 source: model.icon } - Label { - anchors { - verticalCenter: parent.verticalCenter - left: iconItem.right - leftMargin: Unit.size * 3 + Text { + anchors.left: iconItem.right + anchors.verticalCenter: parent.verticalCenter + anchors.leftMargin: 4 + + font.pixelSize: parent.height-4 + color: '#fff' + + text: name + } + } + + MouseArea { + anchors.fill: parent + onClicked: { + if (parent.state != "expanded") { + parent.state = "expanded"; + } else { + parent.state = "" } - renderType: Text.NativeRendering - text: styleData.value - font.pixelSize: 16 - font.bold: true - color: styleData.selected ? colorPalette.highlightedText : colorPalette.text } } - branchDelegate: Item { - width: 16 - height: 16 - Text { - visible: styleData.column === 0 && styleData.hasChildren - text: styleData.isExpanded ? "\u25bc" : "\u25b6" - color: !control.activeFocus || styleData.selected ? styleData.textColor : "#666" - font.pointSize: 10 - renderType: Text.NativeRendering - anchors.centerIn: parent - anchors.verticalCenterOffset: styleData.isExpanded ? 2 : 0 + + Item { + id: folderView + + anchors.top: headerView.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + + opacity: 0 + visible: false + + Rectangle { + anchors.fill: parent + TreeView { + anchors.fill: parent + id: treeView + TableViewColumn { + title: "Name" + role: "name" + width: treeView.width - 5 + } + model: KubeFramework.FolderListModel { id: folderListModel; accountId: wrapper.accountId } + onCurrentIndexChanged: { + model.fetchMore(currentIndex) + root.currentFolder = model.data(currentIndex, KubeFramework.FolderListModel.DomainObject) + } + backgroundVisible: false + headerVisible: false + style: TreeViewStyle { + activateItemOnSingleClick: true + rowDelegate: Rectangle { + height: Unit.size * 10 + color: "transparent" + } + itemDelegate: Rectangle { + radius: 5 + border.width: 1 + border.color: "lightgrey" + color: styleData.selected ? colorPalette.highlight : colorPalette.button + PlasmaCore.IconItem { + id: iconItem + anchors { + verticalCenter: parent.verticalCenter + left: parent.left + leftMargin: Unit.size * 3 + } + source: model.icon + } + Label { + anchors { + verticalCenter: parent.verticalCenter + left: iconItem.right + leftMargin: Unit.size * 3 + } + renderType: Text.NativeRendering + text: styleData.value + font.pixelSize: 16 + font.bold: true + color: styleData.selected ? colorPalette.highlightedText : colorPalette.text + } + } + branchDelegate: Item { + width: 16 + height: 16 + Text { + visible: styleData.column === 0 && styleData.hasChildren + text: styleData.isExpanded ? "\u25bc" : "\u25b6" + color: !control.activeFocus || styleData.selected ? styleData.textColor : "#666" + font.pointSize: 10 + renderType: Text.NativeRendering + anchors.centerIn: parent + anchors.verticalCenterOffset: styleData.isExpanded ? 2 : 0 + } + } + } + } } } + + states: [ + State { + name: "expanded" + + PropertyChanges { target: wrapper; height: listView.height - accountsModel.rowCount() * 30 } + PropertyChanges { target: folderView; opacity: 1; visible: true } + PropertyChanges { target: wrapper.ListView.view; contentY: wrapper.y; interactive: false } + } + ] + + transitions: [ + Transition { + NumberAnimation { + duration: 150; + properties: "height,width,anchors.rightMargin,anchors.topMargin,opacity,contentY" + } + } + ] } } + } diff --git a/components/package/contents/ui/Settings.qml b/components/package/contents/ui/Settings.qml index d96ccfb0..c17109a0 100644 --- a/components/package/contents/ui/Settings.qml +++ b/components/package/contents/ui/Settings.qml @@ -102,6 +102,8 @@ Rectangle { console.warn("Loading module is ", accountFactory.accountId); accountDetails.source = accountFactory.uiPath accountDetails.item.accountId = accountFactory.accountId + accountDetails.item.icon = accountFactory.icon + accountDetails.item.accountName = accountFactory.name listView.currentIndex = model.index } } diff --git a/framework/domain/CMakeLists.txt b/framework/domain/CMakeLists.txt index 7560219f..435db5cf 100644 --- a/framework/domain/CMakeLists.txt +++ b/framework/domain/CMakeLists.txt @@ -14,6 +14,7 @@ set(mailplugin_SRCS retriever.cpp accountfactory.cpp accountscontroller.cpp + accountsmodel.cpp ) add_definitions(-DMAIL_DATA_DIR="${CMAKE_CURRENT_SOURCE_DIR}/data") diff --git a/framework/domain/accountsmodel.cpp b/framework/domain/accountsmodel.cpp new file mode 100644 index 00000000..96306464 --- /dev/null +++ b/framework/domain/accountsmodel.cpp @@ -0,0 +1,65 @@ +/* + Copyright (c) 2016 Christian Mollekopf + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ +#include "accountsmodel.h" + +#include + +#include + +AccountsModel::AccountsModel(QObject *parent) : QAbstractListModel() +{ + Kube::Settings settings("accounts"); + mAccounts = settings.property("accounts").toStringList(); +} + +AccountsModel::~AccountsModel() +{ + +} + +QHash< int, QByteArray > AccountsModel::roleNames() const +{ + QHash roles; + + roles[Name] = "name"; + roles[Icon] = "icon"; + roles[AccountId] = "accountId"; + + return roles; +} + +QVariant AccountsModel::data(const QModelIndex &idx, int role) const +{ + const auto identifier = mAccounts.at(idx.row()); + Kube::Account accountSettings(identifier.toLatin1()); + switch (role) { + case Name: + return accountSettings.property("name").toString(); + case Icon: + return accountSettings.property("icon").toString(); + case AccountId: + return identifier; + } + return QVariant(); +} + +int AccountsModel::rowCount(const QModelIndex &idx) const +{ + return mAccounts.size(); +} diff --git a/framework/domain/accountsmodel.h b/framework/domain/accountsmodel.h new file mode 100644 index 00000000..a50c2e4a --- /dev/null +++ b/framework/domain/accountsmodel.h @@ -0,0 +1,48 @@ +/* + Copyright (c) 2016 Christian Mollekopf + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + +#pragma once + +#include +#include +#include +#include + +class AccountsModel : public QAbstractListModel +{ + Q_OBJECT + +public: + AccountsModel(QObject *parent = Q_NULLPTR); + ~AccountsModel(); + + int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; + + enum Roles { + Name = Qt::UserRole + 1, + Icon, + AccountId + }; + Q_ENUMS(Roles) + + QHash roleNames() const Q_DECL_OVERRIDE; +private: + QStringList mAccounts; +}; diff --git a/framework/domain/folderlistmodel.cpp b/framework/domain/folderlistmodel.cpp index ce6fb4fd..f212e336 100644 --- a/framework/domain/folderlistmodel.cpp +++ b/framework/domain/folderlistmodel.cpp @@ -20,6 +20,7 @@ #include "folderlistmodel.h" #include +#include FolderListModel::FolderListModel(QObject *parent) : QIdentityProxyModel() { @@ -27,8 +28,7 @@ FolderListModel::FolderListModel(QObject *parent) : QIdentityProxyModel() query.liveQuery = true; query.requestedProperties << "name" << "icon" << "parent"; query.parentProperty = "parent"; - mModel = Sink::Store::loadModel(query); - setSourceModel(mModel.data()); + runQuery(query); } FolderListModel::~FolderListModel() @@ -63,3 +63,33 @@ QVariant FolderListModel::data(const QModelIndex &idx, int role) const } return QIdentityProxyModel::data(idx, role); } + +void FolderListModel::runQuery(const Sink::Query &query) +{ + mModel = Sink::Store::loadModel(query); + setSourceModel(mModel.data()); +} + +void FolderListModel::setAccountId(const QVariant &accountId) +{ + const auto account = accountId.toString(); + Kube::Account accountSettings(account.toUtf8()); + //FIXME maildirResource is obviously not good. We need a way to find resources that belong to the account and provide folders. + const auto resourceId = accountSettings.property("maildirResource").toString(); + qDebug() << "Running query for account " << account; + qDebug() << "Found resources " << resourceId; + + Sink::Query query; + query.liveQuery = true; + query.requestedProperties << "name" << "icon" << "parent"; + query.parentProperty = "parent"; + query.resources << resourceId.toUtf8(); + + runQuery(query); +} + +QVariant FolderListModel::accountId() const +{ + return QVariant(); +} + diff --git a/framework/domain/folderlistmodel.h b/framework/domain/folderlistmodel.h index 7844e59a..d30393db 100644 --- a/framework/domain/folderlistmodel.h +++ b/framework/domain/folderlistmodel.h @@ -25,10 +25,16 @@ #include #include +namespace Sink { + class Query; +} + class FolderListModel : public QIdentityProxyModel { Q_OBJECT + Q_PROPERTY (QVariant accountId READ accountId WRITE setAccountId) + public: FolderListModel(QObject *parent = Q_NULLPTR); ~FolderListModel(); @@ -45,6 +51,10 @@ public: QHash roleNames() const; + void setAccountId(const QVariant &accountId); + QVariant accountId() const; + private: + void runQuery(const Sink::Query &query); QSharedPointer mModel; }; diff --git a/framework/domain/mailplugin.cpp b/framework/domain/mailplugin.cpp index c19818ec..9f06fd5f 100644 --- a/framework/domain/mailplugin.cpp +++ b/framework/domain/mailplugin.cpp @@ -27,6 +27,7 @@ #include "retriever.h" #include "accountfactory.h" #include "accountscontroller.h" +#include "accountsmodel.h" #include @@ -41,4 +42,5 @@ void MailPlugin::registerTypes (const char *uri) qmlRegisterType(uri, 1, 0, "Retriever"); qmlRegisterType(uri, 1, 0, "AccountFactory"); qmlRegisterType(uri, 1, 0, "AccountsController"); + qmlRegisterType(uri, 1, 0, "AccountsModel"); } -- cgit v1.2.3