From b8aab3407afc541d7f057adcdbe90395e8e3a1e9 Mon Sep 17 00:00:00 2001 From: Simon Redman Date: Sat, 9 May 2020 16:50:08 +0000 Subject: [PATCH] [SMS App] Sms helper improvements --- smsapp/CMakeLists.txt | 1 + smsapp/conversationlistmodel.cpp | 5 ---- smsapp/conversationlistmodel.h | 7 ----- smsapp/conversationmodel.cpp | 13 --------- smsapp/conversationmodel.h | 14 +-------- smsapp/main.cpp | 4 +++ smsapp/qml/ChatMessage.qml | 2 +- smsapp/qml/ConversationDisplay.qml | 25 ++++++++-------- smsapp/qml/ConversationList.qml | 6 ++-- smsapp/smshelper.cpp | 24 ++++++++++++++-- smsapp/smshelper.h | 46 ++++++++++++++++++------------ 11 files changed, 71 insertions(+), 76 deletions(-) diff --git a/smsapp/CMakeLists.txt b/smsapp/CMakeLists.txt index eb159a7a7..19f69d88d 100644 --- a/smsapp/CMakeLists.txt +++ b/smsapp/CMakeLists.txt @@ -20,6 +20,7 @@ PUBLIC Qt5::Core Qt5::DBus KF5::People + Qt5::Qml kdeconnectinterfaces ) diff --git a/smsapp/conversationlistmodel.cpp b/smsapp/conversationlistmodel.cpp index fdb9a99ce..f0cb75831 100644 --- a/smsapp/conversationlistmodel.cpp +++ b/smsapp/conversationlistmodel.cpp @@ -284,8 +284,3 @@ void ConversationListModel::createConversationForAddress(const QString& address) item->setData(address, SenderRole); appendRow(item); } - -bool ConversationListModel::isAddressValid(const QString& address) -{ - return SmsHelper::isAddressValid(address); -} diff --git a/smsapp/conversationlistmodel.h b/smsapp/conversationlistmodel.h index 271cc3350..0a9dc54fc 100644 --- a/smsapp/conversationlistmodel.h +++ b/smsapp/conversationlistmodel.h @@ -57,13 +57,6 @@ public: Q_SCRIPTABLE void refresh(); - /** - * This method ensurse whether the phone number format is valid or not - * TODO: This is here because I don't know how to make the QML call the smshelper directly - * but that is what should be happening! - */ - Q_INVOKABLE bool isAddressValid(const QString& address); - /** * This method creates conversation with an arbitrary address */ diff --git a/smsapp/conversationmodel.cpp b/smsapp/conversationmodel.cpp index 80538eda1..6583edadf 100644 --- a/smsapp/conversationmodel.cpp +++ b/smsapp/conversationmodel.cpp @@ -21,8 +21,6 @@ #include "conversationmodel.h" -#include -#include #include #include @@ -112,17 +110,6 @@ void ConversationModel::requestMoreMessages(const quint32& howMany) m_conversationsInterface->requestConversation(m_threadId, numMessages, numMessages + howMany); } -QString ConversationModel::getTitleForAddresses(const QList& addresses) -{ - return SmsHelper::getTitleForAddresses(addresses); -} - -void ConversationModel::copyToClipboard(const QString& message) const -{ - // TODO: Remove this method as part of abstracting GUI elements to library - QGuiApplication::clipboard()->setText(message); -} - void ConversationModel::createRowFromMessage(const ConversationMessage& message, int pos) { if (message.threadID() != m_threadId) { diff --git a/smsapp/conversationmodel.h b/smsapp/conversationmodel.h index 8b12cb14a..80ec6ba7b 100644 --- a/smsapp/conversationmodel.h +++ b/smsapp/conversationmodel.h @@ -66,19 +66,7 @@ public: Q_INVOKABLE void sendReplyToConversation(const QString& message); Q_INVOKABLE void sendMessageWithoutConversation(const QString& message, const QString& address); Q_INVOKABLE void requestMoreMessages(const quint32& howMany = 10); - /** - * Convert a list of names into a single string suitable for display - * TODO: This is here because I don't know how to make the QML call the smshelper directly - * but that is what should be happening! - */ - Q_INVOKABLE QString getTitleForAddresses(const QList& addresses); - /** - * This is the action invoked by the right-click menu to copy to the clipboard - * QML can't do this directly but this should be part of smshelper - * TODO: Move to smshelper (or maybe make part of kirigami-addons chat library?) - */ - Q_INVOKABLE void copyToClipboard(const QString& message) const; - + Q_INVOKABLE QString getCharCountInfo(const QString& message) const; Q_SIGNALS: diff --git a/smsapp/main.cpp b/smsapp/main.cpp index feb010f63..fb7418126 100644 --- a/smsapp/main.cpp +++ b/smsapp/main.cpp @@ -33,6 +33,8 @@ #include #include +#include "smshelper.h" + int main(int argc, char *argv[]) { QApplication app(argc, argv); @@ -67,6 +69,8 @@ int main(int argc, char *argv[]) qmlRegisterType("org.kde.kdeconnect.sms", 1, 0, "ConversationModel"); qmlRegisterType("org.kde.kdeconnect.sms", 1, 0, "ConversationListModel"); + qmlRegisterSingletonType("org.kde.kdeconnect.sms", 1, 0, "SmsHelper", SmsHelper::singletonProvider); + QQmlApplicationEngine engine; engine.rootContext()->setContextObject(new KLocalizedContext(&engine)); engine.rootContext()->setContextProperties({ diff --git a/smsapp/qml/ChatMessage.qml b/smsapp/qml/ChatMessage.qml index 1a7cc5472..5b78c006f 100644 --- a/smsapp/qml/ChatMessage.qml +++ b/smsapp/qml/ChatMessage.qml @@ -60,7 +60,7 @@ RowLayout { property bool isSpoiler property string spoilerHint property bool isShowingSpoiler: false - property string avatarUrl: null//kaidan.avatarStorage.getAvatarUrl(sender) + property string avatarUrl: "" signal messageCopyRequested(string message) diff --git a/smsapp/qml/ConversationDisplay.qml b/smsapp/qml/ConversationDisplay.qml index 199905b80..827936465 100644 --- a/smsapp/qml/ConversationDisplay.qml +++ b/smsapp/qml/ConversationDisplay.qml @@ -21,7 +21,7 @@ */ import QtQuick 2.1 -import QtQuick.Controls 2.2 +import QtQuick.Controls 2.2 as Controls import QtQuick.Layouts 1.1 import org.kde.people 1.0 import org.kde.kirigami 2.4 as Kirigami @@ -54,7 +54,7 @@ Kirigami.ScrollablePage } property var addresses - title: conversationModel.getTitleForAddresses(addresses) + title: SmsHelper.getTitleForAddresses(addresses) Component.onCompleted: { if (initialMessage.length > 0) { @@ -92,7 +92,7 @@ Kirigami.ScrollablePage spacing: Kirigami.Units.largeSpacing highlightMoveDuration: 0 - BusyIndicator { + Controls.BusyIndicator { running: !isInitalized } @@ -151,7 +151,7 @@ Kirigami.ScrollablePage } onMessageCopyRequested: { - conversationModel.copyToClipboard(message) + SmsHelper.copyToClipboard(message) } } @@ -179,7 +179,7 @@ Kirigami.ScrollablePage } } - footer: Pane { + footer: Controls.Pane { id: sendingArea enabled: page.deviceConnected && !page.isMultitarget layer.enabled: sendingArea.enabled @@ -199,14 +199,14 @@ Kirigami.ScrollablePage RowLayout { anchors.fill: parent - ScrollView { + Controls.ScrollView { Layout.fillWidth: true Layout.maximumHeight: page.height > 300 ? page.height / 3 : 2 * page.height / 3 contentWidth: page.width - sendButtonArea.width clip: true - ScrollBar.horizontal.policy: ScrollBar.AlwaysOff + Controls.ScrollBar.horizontal.policy: Controls.ScrollBar.AlwaysOff - TextArea { + Controls.TextArea { anchors.fill: parent id: messageField placeholderText: page.isMultitarget ? i18nd("kdeconnect-sms", "Replying to multitarget messages is not supported") : i18nd("kdeconnect-sms", "Compose message") @@ -227,11 +227,11 @@ Kirigami.ScrollablePage } } } - + ColumnLayout { id: sendButtonArea - ToolButton { + Controls.ToolButton { id: sendButton Layout.preferredWidth: Kirigami.Units.gridUnit * 2 Layout.preferredHeight: Kirigami.Units.gridUnit * 2 @@ -267,9 +267,8 @@ Kirigami.ScrollablePage sendButton.enabled = true } } - - - Label { + + Controls.Label { id: "charCount" text: conversationModel.getCharCountInfo(messageField.text) visible: text.length > 0 diff --git a/smsapp/qml/ConversationList.qml b/smsapp/qml/ConversationList.qml index 3c1dffd9c..5be563e95 100644 --- a/smsapp/qml/ConversationList.qml +++ b/smsapp/qml/ConversationList.qml @@ -174,7 +174,7 @@ Kirigami.ScrollablePage } else { view.model.setConversationsFilterRole(ConversationListModel.ConversationIdRole) } - view.model.setFilterFixedString(filter.text) + view.model.setFilterFixedString(SmsHelper.canonicalizePhoneNumber(filter.text)) view.currentIndex = 0 } @@ -199,7 +199,7 @@ Kirigami.ScrollablePage id: newButton text: i18nd("kdeconnect-sms", "New") visible: true - enabled: conversationListModel.isAddressValid(filter.text) && deviceConnected + enabled: SmsHelper.isAddressValid(filter.text) && deviceConnected ToolTip.visible: hovered ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval ToolTip.text: i18nd("kdeconnect-sms", "Start new conversation") @@ -209,7 +209,7 @@ Kirigami.ScrollablePage filter.enabled = false // If the address entered by the user already exists then ignore adding new contact - if (!view.model.doesAddressExists(filter.text) && conversationListModel.isAddressValid(filter.text)) { + if (!view.model.doesAddressExists(filter.text) && smsHelper.isAddressValid(filter.text)) { conversationListModel.createConversationForAddress(filter.text) view.currentIndex = 0 } diff --git a/smsapp/smshelper.cpp b/smsapp/smshelper.cpp index 618aa4b05..fab12f112 100644 --- a/smsapp/smshelper.cpp +++ b/smsapp/smshelper.cpp @@ -20,6 +20,8 @@ #include "smshelper.h" +#include +#include #include #include #include @@ -36,6 +38,14 @@ Q_LOGGING_CATEGORY(KDECONNECT_SMS_SMSHELPER, "kdeconnect.sms.smshelper") +QObject* SmsHelper::singletonProvider(QQmlEngine *engine, QJSEngine *scriptEngine) +{ + Q_UNUSED(engine); + Q_UNUSED(scriptEngine); + + return new SmsHelper(); +} + bool SmsHelper::isPhoneNumberMatchCanonicalized(const QString& canonicalPhone1, const QString& canonicalPhone2) { if (canonicalPhone1.isEmpty() || canonicalPhone2.isEmpty()) { @@ -217,7 +227,8 @@ QSharedPointer SmsHelper::lookupPersonByAddress(const QStri return nullptr; } -QIcon SmsHelper::combineIcons(const QList& icons) { +QIcon SmsHelper::combineIcons(const QList& icons) +{ QIcon icon; if (icons.size() == 0) { // We have no icon :( @@ -260,7 +271,8 @@ QIcon SmsHelper::combineIcons(const QList& icons) { return icon; } -QString SmsHelper::getTitleForAddresses(const QList& addresses) { +QString SmsHelper::getTitleForAddresses(const QList& addresses) +{ QStringList titleParts; for (const ConversationAddress& address : addresses) { const auto personData = SmsHelper::lookupPersonByAddress(address.address()); @@ -277,7 +289,8 @@ QString SmsHelper::getTitleForAddresses(const QList& addres return titleParts.join(QLatin1String(", ")); } -QIcon SmsHelper::getIconForAddresses(const QList& addresses) { +QIcon SmsHelper::getIconForAddresses(const QList& addresses) +{ QList icons; for (const ConversationAddress& address : addresses) { const auto personData = SmsHelper::lookupPersonByAddress(address.address()); @@ -295,6 +308,11 @@ QIcon SmsHelper::getIconForAddresses(const QList& addresses return combineIcons(icons); } +void SmsHelper::copyToClipboard(const QString& text) +{ + QGuiApplication::clipboard()->setText(text); +} + SmsCharCount SmsHelper::getCharCount(const QString& message) { const int remainingWhenEmpty = 160; diff --git a/smsapp/smshelper.h b/smsapp/smshelper.h index 1d06a84f7..deb7afb0e 100644 --- a/smsapp/smshelper.h +++ b/smsapp/smshelper.h @@ -22,10 +22,12 @@ #define SMSHELPER_H #include +#include #include +#include +#include #include -#include #include "interfaces/conversationmessage.h" @@ -36,9 +38,15 @@ Q_DECLARE_LOGGING_CATEGORY(KDECONNECT_SMS_SMSHELPER) class PersonsCache; -class KDECONNECTSMSAPPLIB_EXPORT SmsHelper +class KDECONNECTSMSAPPLIB_EXPORT SmsHelper : public QObject { + Q_OBJECT public: + SmsHelper() = default; + ~SmsHelper() = default; + + static QObject* singletonProvider(QQmlEngine *engine, QJSEngine *scriptEngine); + enum CountryCode { Australia, CzechRepublic, @@ -48,19 +56,19 @@ public: /** * Return true to indicate the two phone numbers should be considered the same, false otherwise */ - static bool isPhoneNumberMatch(const QString& phone1, const QString& phone2); + Q_INVOKABLE static bool isPhoneNumberMatch(const QString& phone1, const QString& phone2); /** * Return true to indicate the two phone numbers should be considered the same, false otherwise * Requires canonicalized phone numbers as inputs */ - static bool isPhoneNumberMatchCanonicalized(const QString& canonicalPhone1, const QString& canonicalPhone2); + Q_INVOKABLE static bool isPhoneNumberMatchCanonicalized(const QString& canonicalPhone1, const QString& canonicalPhone2); /** * See inline comments for how short codes are determined * All information from https://en.wikipedia.org/wiki/Short_code */ - static bool isShortCode(const QString& canonicalNumber, const CountryCode& country); + Q_INVOKABLE static bool isShortCode(const QString& canonicalNumber, const CountryCode& country); /** * Try to guess the country code from the passed number @@ -70,12 +78,12 @@ public: /** * Simplify a phone number to a known form */ - static QString canonicalizePhoneNumber(const QString& phoneNumber); + Q_INVOKABLE static QString canonicalizePhoneNumber(const QString& phoneNumber); /** * Get the data for a particular person given their contact address */ - static QSharedPointer lookupPersonByAddress(const QString& address); + Q_INVOKABLE static QSharedPointer lookupPersonByAddress(const QString& address); /** * Make an icon which combines the many icons @@ -86,14 +94,14 @@ public: * If there are three, put one in the middle of the top and the remaining two in the bottom * If there are four or more, put one in each corner (If more than four, some will be left out) */ - static QIcon combineIcons(const QList& icons); + Q_INVOKABLE static QIcon combineIcons(const QList& icons); /** * Get a combination of all the addresses as a comma-separated list of: * - The KPeople contact's name (if known) * - The address (if the contact is not known) */ - static QString getTitleForAddresses(const QList& addresses); + Q_INVOKABLE static QString getTitleForAddresses(const QList& addresses); /** * Get a combined icon for all contacts by finding: @@ -101,31 +109,33 @@ public: * - A generic icon * and then using SmsHelper::combineIcons */ - static QIcon getIconForAddresses(const QList& addresses); + Q_INVOKABLE static QIcon getIconForAddresses(const QList& addresses); + + /** + * Put the specified text into the system clipboard + */ + Q_INVOKABLE static void copyToClipboard(const QString& text); /** * Get the data for all persons currently stored on device */ static QList> getAllPersons(); - + /** * Get SMS character count status of SMS. It contains number of remaining characters * in current SMS (automatically selects 7-bit, 8-bit or 16-bit mode), octet count and * number of messages in concatenated SMS. */ - static SmsCharCount getCharCount(const QString& message); - - static bool isInGsmAlphabet(const QChar& ch); - static bool isInGsmAlphabetExtension(const QChar& ch); + Q_INVOKABLE static SmsCharCount getCharCount(const QString& message); /** * Used to validate arbitrary phone number entered by the user */ - static bool isAddressValid(const QString& address); + Q_INVOKABLE static bool isAddressValid(const QString& address); private: - SmsHelper(){}; - ~SmsHelper(){}; + static bool isInGsmAlphabet(const QChar& ch); + static bool isInGsmAlphabetExtension(const QChar& ch); }; #endif // SMSHELPER_H