[SMS App] Sms helper improvements
This commit is contained in:
parent
4254b23d5d
commit
b8aab3407a
11 changed files with 71 additions and 76 deletions
|
@ -20,6 +20,7 @@ PUBLIC
|
|||
Qt5::Core
|
||||
Qt5::DBus
|
||||
KF5::People
|
||||
Qt5::Qml
|
||||
kdeconnectinterfaces
|
||||
)
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -21,8 +21,6 @@
|
|||
|
||||
#include "conversationmodel.h"
|
||||
|
||||
#include <QClipboard>
|
||||
#include <QGuiApplication>
|
||||
#include <QLoggingCategory>
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
@ -112,17 +110,6 @@ void ConversationModel::requestMoreMessages(const quint32& howMany)
|
|||
m_conversationsInterface->requestConversation(m_threadId, numMessages, numMessages + howMany);
|
||||
}
|
||||
|
||||
QString ConversationModel::getTitleForAddresses(const QList<ConversationAddress>& 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) {
|
||||
|
|
|
@ -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<ConversationAddress>& 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:
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
#include <KLocalizedContext>
|
||||
#include <KDBusService>
|
||||
|
||||
#include "smshelper.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
@ -67,6 +69,8 @@ int main(int argc, char *argv[])
|
|||
qmlRegisterType<ConversationModel>("org.kde.kdeconnect.sms", 1, 0, "ConversationModel");
|
||||
qmlRegisterType<ConversationListModel>("org.kde.kdeconnect.sms", 1, 0, "ConversationListModel");
|
||||
|
||||
qmlRegisterSingletonType<SmsHelper>("org.kde.kdeconnect.sms", 1, 0, "SmsHelper", SmsHelper::singletonProvider);
|
||||
|
||||
QQmlApplicationEngine engine;
|
||||
engine.rootContext()->setContextObject(new KLocalizedContext(&engine));
|
||||
engine.rootContext()->setContextProperties({
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#include "smshelper.h"
|
||||
|
||||
#include <QClipboard>
|
||||
#include <QGuiApplication>
|
||||
#include <QIcon>
|
||||
#include <QPainter>
|
||||
#include <QRegularExpression>
|
||||
|
@ -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<KPeople::PersonData> SmsHelper::lookupPersonByAddress(const QStri
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
QIcon SmsHelper::combineIcons(const QList<QPixmap>& icons) {
|
||||
QIcon SmsHelper::combineIcons(const QList<QPixmap>& icons)
|
||||
{
|
||||
QIcon icon;
|
||||
if (icons.size() == 0) {
|
||||
// We have no icon :(
|
||||
|
@ -260,7 +271,8 @@ QIcon SmsHelper::combineIcons(const QList<QPixmap>& icons) {
|
|||
return icon;
|
||||
}
|
||||
|
||||
QString SmsHelper::getTitleForAddresses(const QList<ConversationAddress>& addresses) {
|
||||
QString SmsHelper::getTitleForAddresses(const QList<ConversationAddress>& addresses)
|
||||
{
|
||||
QStringList titleParts;
|
||||
for (const ConversationAddress& address : addresses) {
|
||||
const auto personData = SmsHelper::lookupPersonByAddress(address.address());
|
||||
|
@ -277,7 +289,8 @@ QString SmsHelper::getTitleForAddresses(const QList<ConversationAddress>& addres
|
|||
return titleParts.join(QLatin1String(", "));
|
||||
}
|
||||
|
||||
QIcon SmsHelper::getIconForAddresses(const QList<ConversationAddress>& addresses) {
|
||||
QIcon SmsHelper::getIconForAddresses(const QList<ConversationAddress>& addresses)
|
||||
{
|
||||
QList<QPixmap> icons;
|
||||
for (const ConversationAddress& address : addresses) {
|
||||
const auto personData = SmsHelper::lookupPersonByAddress(address.address());
|
||||
|
@ -295,6 +308,11 @@ QIcon SmsHelper::getIconForAddresses(const QList<ConversationAddress>& addresses
|
|||
return combineIcons(icons);
|
||||
}
|
||||
|
||||
void SmsHelper::copyToClipboard(const QString& text)
|
||||
{
|
||||
QGuiApplication::clipboard()->setText(text);
|
||||
}
|
||||
|
||||
SmsCharCount SmsHelper::getCharCount(const QString& message)
|
||||
{
|
||||
const int remainingWhenEmpty = 160;
|
||||
|
|
|
@ -22,10 +22,12 @@
|
|||
#define SMSHELPER_H
|
||||
|
||||
#include <QIcon>
|
||||
#include <QJSEngine>
|
||||
#include <QLoggingCategory>
|
||||
#include <QQmlEngine>
|
||||
#include <QSharedPointer>
|
||||
|
||||
#include <KPeople/PersonData>
|
||||
#include <QSharedPointer>
|
||||
|
||||
#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<KPeople::PersonData> lookupPersonByAddress(const QString& address);
|
||||
Q_INVOKABLE static QSharedPointer<KPeople::PersonData> 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<QPixmap>& icons);
|
||||
Q_INVOKABLE static QIcon combineIcons(const QList<QPixmap>& 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<ConversationAddress>& addresses);
|
||||
Q_INVOKABLE static QString getTitleForAddresses(const QList<ConversationAddress>& 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<ConversationAddress>& addresses);
|
||||
Q_INVOKABLE static QIcon getIconForAddresses(const QList<ConversationAddress>& 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<QSharedPointer<KPeople::PersonData>> 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
|
||||
|
|
Loading…
Reference in a new issue