Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

conversationsdbusinterface.cpp 4.49 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
/**
 * Copyright 2018 Simon Redman <simon@ergotech.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License or (at your option) version 3 or any later version
 * accepted by the membership of KDE e.V. (or its successor approved
 * by the membership of KDE e.V.), which shall act as a proxy
 * defined in Section 14 of version 3 of the license.
 *
 * 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 General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "conversationsdbusinterface.h"
#include "interfaces/dbusinterfaces.h"
#include "interfaces/conversationmessage.h"

#include <QDBusConnection>

#include <core/device.h>
#include <core/kdeconnectplugin.h>

30
Q_LOGGING_CATEGORY(KDECONNECT_CONVERSATIONS, "kdeconnect.conversations")
31 32 33 34 35 36

ConversationsDbusInterface::ConversationsDbusInterface(KdeConnectPlugin* plugin)
    : QDBusAbstractAdaptor(const_cast<Device*>(plugin->device()))
    , m_device(plugin->device())
    , m_plugin(plugin)
    , m_lastId(0)
37
    , m_smsInterface(m_device->id())
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
{
    ConversationMessage::registerDbusType();
}

ConversationsDbusInterface::~ConversationsDbusInterface()
{
}

QStringList ConversationsDbusInterface::activeConversations()
{
    return m_conversations.keys();
}

void ConversationsDbusInterface::requestConversation(const QString& conversationID, int start, int end)
{
Simon Redman's avatar
Simon Redman committed
53
    const auto messagesList = m_conversations[conversationID].values();
54

55
    if (messagesList.isEmpty()) {
56
        // Since there are no messages in the conversation, it's likely that it is a junk ID, but go ahead anyway
57
        qCWarning(KDECONNECT_CONVERSATIONS) << "Got a conversationID for a conversation with no messages!" << conversationID;
58 59
    }

60
    m_smsInterface.requestConversation(conversationID);
61

Simon Redman's avatar
Simon Redman committed
62 63 64 65
    // Messages are sorted in ascending order of keys, meaning the front of the list has the oldest
    // messages (smallest timestamp number)
    // Therefore, return the end of the list first (most recent messages)
    int i = start;
66
    for(auto it = messagesList.crbegin(); it != messagesList.crend(); ++it) {
Simon Redman's avatar
Simon Redman committed
67 68
        Q_EMIT conversationMessageReceived(it->toVariant(), i);
        i++;
69
        if (i >= end) {
Simon Redman's avatar
Simon Redman committed
70
            break;
71 72 73 74 75 76 77 78
        }
    }
}

void ConversationsDbusInterface::addMessage(const ConversationMessage &message)
{
    const QString& threadId = QString::number(message.threadID());

79
    if (m_known_messages[threadId].contains(message.uID())) {
80 81 82 83 84 85
        // This message has already been processed. Don't do anything.
        return;
    }

    // Store the Message in the list corresponding to its thread
    bool newConversation = !m_conversations.contains(threadId);
Simon Redman's avatar
Simon Redman committed
86
    m_conversations[threadId].insert(message.date(), message);
87 88 89
    m_known_messages[threadId].insert(message.uID());

    // Tell the world about what just happened
90
    if (newConversation) {
91
        Q_EMIT conversationCreated(threadId);
92
    } else {
93
        Q_EMIT conversationUpdated(message.toVariant());
94 95 96 97 98 99 100 101 102 103 104
    }
}

void ConversationsDbusInterface::removeMessage(const QString& internalId)
{
    // TODO: Delete the specified message from our internal structures
}

void ConversationsDbusInterface::replyToConversation(const QString& conversationID, const QString& message)
{
    const auto messagesList = m_conversations[conversationID];
105
    if (messagesList.isEmpty()) {
106
        // Since there are no messages in the conversation, we can't do anything sensible
107
        qCWarning(KDECONNECT_CONVERSATIONS) << "Got a conversationID for a conversation with no messages!";
108 109
        return;
    }
Simon Redman's avatar
Simon Redman committed
110 111 112 113 114
    // Caution:
    // This method assumes that the address of any message (in this case, whichever one pops out
    // with .first()) will be the same. This works fine for single-target SMS but might break down
    // for group MMS, etc.
    const QString& address = messagesList.first().address();
115
    m_smsInterface.sendSms(address, message);
116 117 118 119 120
}

void ConversationsDbusInterface::requestAllConversationThreads()
{
    // Prepare the list of conversations by requesting the first in every thread
121
    m_smsInterface.requestAllConversations();
122 123 124 125 126 127
}

QString ConversationsDbusInterface::newId()
{
    return QString::number(++m_lastId);
}