diff --git a/src/contents/ui/ActionDelegate.qml b/src/contents/ui/ActionDelegate.qml index 862f49f..fd97055 100644 --- a/src/contents/ui/ActionDelegate.qml +++ b/src/contents/ui/ActionDelegate.qml @@ -1,27 +1,27 @@ /* Copyright (C) 2012 Lasath Fernando Copyright (C) 2012 David Edmundson This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ import QtQuick 2.1 -import org.kde.kirigami 2.1 as Kirigami +import QtQuick.Controls 2.1 -Kirigami.Label { +Label { wrapMode: Text.Wrap width: view.width text: "* " + model.senderAlias + " " + model.text + "" } diff --git a/src/contents/ui/ContactList.qml b/src/contents/ui/ContactList.qml index cda72b3..217df36 100644 --- a/src/contents/ui/ContactList.qml +++ b/src/contents/ui/ContactList.qml @@ -1,192 +1,190 @@ /** * Copyright 2016 Martin Klapetek * * This program 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 or * (at your option) any later version. * * This program 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 General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.3 -import QtQuick.Controls 1.4 +import QtQuick.Controls 2.5 as Controls import QtQuick.Layouts 1.1 import org.kde.people 1.0 as KPeople import org.kde.kquickcontrolsaddons 2.0 as ExtraComponents import org.kde.plasma.core 2.1 as PlasmaCore import org.kde.kirigami 2.1 as Kirigami import org.kde.telepathy 0.1 ListView { id: contactsList property bool delegateSelected: false property string numberToCall property alias requiredProperties: kpeopleProxyModel.requiredProperties property QtObject sourceModel property string filterRegExp property bool executeDefaultAction: false signal contactClicked(string personUri) section.property: "display" section.criteria: ViewSection.FirstCharacter clip: true focus: true model: PlasmaCore.SortFilterModel { id: plasmaSortFilterModel sourceModel: KPeople.PersonsSortFilterProxyModel { id: kpeopleProxyModel sourceModel: contactsList.sourceModel } sortRole: "display" filterRole: "display" filterRegExp: ".*" + contactsList.filterRegExp + ".*" sortOrder: Qt.AscendingOrder } boundsBehavior: Flickable.StopAtBounds // highlightRangeMode: ListView.ApplyRange // highlight: PlasmaComponents.Highlight { // // } highlightMoveDuration: 0 KPeople.PersonActions { id: personActionsModel } onCurrentIndexChanged: print("---> " + currentIndex); delegate: Kirigami.AbstractListItem { supportsMouseEvents: true height: actionsRow.visible ? units.gridUnit * 6 : units.gridUnit * 3 enabled: true clip: true opacity: contactsList.delegateSelected && contactsList.currentIndex != index ? 0.4 : 1 onClicked: { contactsList.currentIndex = index; personActionsModel.personUri = model.personUri; if (contactsList.executeDefaultAction) { personActionsModel.triggerAction(0); } else { actionsListProxy.sourceModel = personActionsModel; } contactsList.contactClicked(model.personUri); } Item { anchors.fill: parent // Clear the actions model when index is switched Connections { target: contactsList onCurrentIndexChanged: { if (contactsList.currentIndex != index) { actionsListProxy.sourceModel = null; } } } ColumnLayout { anchors.fill: parent RowLayout { id: mainLayout Layout.fillHeight: true Layout.maximumHeight: units.gridUnit * 3 Layout.fillWidth: true ExtraComponents.QPixmapItem { id: avatarLabel Layout.maximumWidth: parent.height Layout.minimumWidth: parent.height Layout.fillHeight: true pixmap: model.decoration fillMode: ExtraComponents.QPixmapItem.PreserveAspectFit smooth: true } ColumnLayout { Layout.fillHeight: true Layout.fillWidth: true - Kirigami.Label { + Controls.Label { id: nickLabel Layout.fillWidth: true text: model.display elide: Text.ElideRight } - Kirigami.Label { + Controls.Label { id: dataLabel Layout.fillWidth: true text: model.phoneNumber !== undefined ? model.phoneNumber : (model.accountDisplayName !== undefined ? model.accountDisplayName : "") elide: Text.ElideRight - visible: dataLabel.text != nickLabel.text + visible: dataLabel.text !== nickLabel.text opacity: 0.4 } } } RowLayout { id: actionsRow Layout.fillWidth: true Layout.fillHeight: true visible: actionsList.count > 0 ListView { id: actionsList Layout.fillWidth: true Layout.fillHeight: true orientation: ListView.Horizontal model: PlasmaCore.SortFilterModel { id: actionsListProxy filterRole: "actionType" filterCallback: function(source_row, value) { return value == KPeople.ActionType.TextChatAction; } } - delegate: Button { + delegate: Controls.Button { Layout.fillWidth: true text: model.display - iconSource: model.iconName + icon.source: model.iconName onClicked: { personActionsModel.triggerAction(actionsListProxy.mapRowToSource(index)); } } } } } } - - } // CustomSectionScroller { // listView: contactsList // } } diff --git a/src/contents/ui/MainPage.qml b/src/contents/ui/MainPage.qml index 337f598..25cf968 100644 --- a/src/contents/ui/MainPage.qml +++ b/src/contents/ui/MainPage.qml @@ -1,155 +1,153 @@ /** * Copyright 2016 Martin Klapetek * * This program 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 or * (at your option) any later version. * * This program 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 General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.3 -import QtQuick.Controls 1.4 +import QtQuick.Controls 2.3 as Controls import QtQuick.Layouts 1.1 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.kirigami 2.1 as Kirigami -import org.kde.plasma.extras 2.0 as PlasmaExtras import org.kde.telepathy 0.1 as KTp Kirigami.Page { title: "Your Conversations" mainAction: Kirigami.Action { text: "Start New Conversation" iconName: "document-edit" onTriggered: { if (root.pageStack.depth === 2) { root.pageStack.pop(); } root.pageStack.push(newConversationPageComponent); print("Action button clicked") } } Loader { anchors.fill: parent active: telepathyManager.ready sourceComponent: mainModelComponent } Component { id: mainModelComponent ColumnLayout { id: rootLayout anchors.fill: parent ListView { Layout.fillHeight: true Layout.fillWidth: true clip: true model: PlasmaCore.SortFilterModel { id: plasmaSortFilterModel sortRole: "lastMessageDate" sortOrder: Qt.DescendingOrder sourceModel: KTp.MainLogModel { id: mainModel onNewRequestedChannel: { if (root.pageStack.currentPage.pageName === "newConversationPage" || openIncomingChannel) { - root.pageStack.pop(); - root.pageStack.push(conversationPageComponent); + root.pageStack.replace(conversationPageComponent); root.pageStack.currentPage.conversation = mainModel.data(index.row, "conversation"); openIncomingChannel = false; } } Component.onCompleted: { telepathyManager.registerClient(mainModel, "SpaceBar"); telepathyManager.registerClient(mainModel.observerProxy(), "SpaceBarObserverProxy"); mainModel.setAccountManager(telepathyManager.accountManager); } Component.onDestruction: { telepathyManager.unregisterClient(mainModel); } } } delegate: Kirigami.AbstractListItem { supportsMouseEvents: true onClicked: { - if (root.pageStack.depth == 2) { + if (root.pageStack.depth === 2) { root.pageStack.pop(); } root.pageStack.push(conversationPageComponent); root.pageStack.currentItem.conversation = model.conversation; // If the account is online, request a channel if (mainModel.canChat(accountId)) { mainModel.startChat(accountId, contactId); } } Rectangle { anchors.fill: parent color: "white" opacity: 0.8 visible: model.hasUnreadMessages } ColumnLayout { id: messageLayout width: parent.width - PlasmaExtras.Heading { + Kirigami.Heading { Layout.fillWidth: true text: { var t = model.contactDisplayName === "" ? model.contactId : model.contactDisplayName; if (model.hasUnreadMessages) { t += " "; t += i18nc("N unread messages", "(%1 unread)", model.unreadMessagesCount); } return t; } wrapMode: Text.WordWrap elide: Text.ElideRight maximumLineCount: 1 level: 4 } - Kirigami.Label { + Controls.Label { Layout.fillWidth: true text: model.lastMessageText wrapMode: Text.WordWrap elide: Text.ElideRight maximumLineCount: 2 } - Kirigami.Label { + Controls.Label { Layout.fillWidth: true text: Qt.formatDateTime(model.lastMessageDate) wrapMode: Text.WordWrap elide: Text.ElideRight maximumLineCount: 1 } } } } } } } diff --git a/src/contents/ui/NewConversationPage.qml b/src/contents/ui/NewConversationPage.qml index 2a73c2c..98ddb39 100644 --- a/src/contents/ui/NewConversationPage.qml +++ b/src/contents/ui/NewConversationPage.qml @@ -1,76 +1,63 @@ /** * Copyright 2016 Martin Klapetek * * This program 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 or * (at your option) any later version. * * This program 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 General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.3 -import QtQuick.Controls 1.4 +import QtQuick.Controls 2.5 as Controls import QtQuick.Layouts 1.1 import org.kde.plasma.private.kpeoplehelper 1.0 import org.kde.kirigami 2.1 as Kirigami import org.kde.plasma.extras 2.0 as PlasmaExtras import org.kde.telepathy 0.1 -Kirigami.Page { +Kirigami.ScrollablePage { focus: true + title: i18n("Start New Conversation") property string pageName: "newConversationPage" - GridLayout { - anchors.fill: parent - - columns: 2 - - PlasmaExtras.Title { - Layout.columnSpan: 2 - Layout.fillWidth: true - text: i18n("Start New Conversation") - } - - Kirigami.Label { - Layout.alignment: Qt.AlignRight - text: i18n("To:") + header: Rectangle { + clip: true + id: header + height: searchField.implicitHeight + 2 * Kirigami.Units.largeSpacing + width: root.width + + Controls.TextField { + id: searchField + placeholderText: i18n("Search") + anchors.centerIn: parent + anchors.margins: Kirigami.Units.largeSpacing + width: parent.width - 2 * Kirigami.Units.largeSpacing } + } - TextField { - id: toInputField - Layout.alignment: Qt.AlignLeft - Layout.fillWidth: true + ContactList { + anchors.fill: parent + id: contactListView + requiredProperties: ["phoneNumber", "telepathy-contactUri"] + executeDefaultAction: true + filterRegExp: toInputField.text + sourceModel: KPeopleHelper { + id: contactsModel } - PlasmaExtras.ScrollArea { - Layout.fillWidth: true - Layout.fillHeight: true - Layout.columnSpan: 2 - verticalScrollBarPolicy: Qt.ScrollBarAlwaysOff - - contentItem: ContactList { - id: contactListView - requiredProperties: ["phoneNumber", "telepathy-contactUri"] - executeDefaultAction: true - filterRegExp: toInputField.text - sourceModel: KPeopleHelper { - id: contactsModel - } - - onContactClicked: { - root.requestedChannel = personUri; - } - } + onContactClicked: { + root.requestedChannel = personUri; } } } diff --git a/src/main.cpp b/src/main.cpp index 5ce172e..749f2de 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,68 +1,70 @@ /* * Copyright (C) 2016 Martin Klapetek * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include #include #include #include #include #include #include #include int main(int argc, char** argv) { QGuiApplication app(argc, argv); app.setApplicationDisplayName("SpaceBar"); app.setOrganizationDomain("kde.org"); + KDBusService service(KDBusService::Unique); + QCommandLineParser parser; parser.addOption(QCommandLineOption("contact", i18n("Open with the conversation matching the contact id"))); parser.addOption(QCommandLineOption("openIncomingChannel", i18n("If defined, it will automatically open the first handed channel"))); parser.addHelpOption(); parser.process(app); if (parser.positionalArguments().size() > 1) { parser.showHelp(1); } if (parser.isSet("contact")) { // TODO } QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:///main.qml"))); if (engine.rootObjects().isEmpty()) { return -1; } int ret = app.exec(); return ret; return app.exec(); }