diff --git a/src/roommodel.cpp b/src/roommodel.cpp index 688673e2..567f7be1 100644 --- a/src/roommodel.cpp +++ b/src/roommodel.cpp @@ -1,233 +1,249 @@ /* * * Copyright 2016 Riccardo Iaconelli * * 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 . * */ #include "roommodel.h" #include "ruqola.h" #include #include Room RoomModel::fromJSon(const QJsonObject& o) { Room r; - r.name = o["name"].toString(); r.id = o["id"].toString(); + r.type = o["t"].toString(); + r.name = o["name"].toString(); + r.userName = o["userName"].toString(); + r.userID = o["userID"].toString(); + r.topic = o["topic"].toString(); + r.mutedUsers = o["muted"].toString(); + r.jitsiTimeout = o["jitsiTimeout"].toDouble(); + r.ro = o["ro"].toBool(); r.unread = o["unread"].toInt(0); return r; } QByteArray RoomModel::serialize(const Room& r) { QJsonDocument d; QJsonObject o; - o["name"] = r.name; + o["id"] = r.id; + o["t"] = r.type; + o["name"] = r.name; + o["userName"] = r.userName; + o["userID"] = r.userID; + o["topic"] = r.topic; + o["muted"] = r.mutedUsers; + o["jitsiTimeout"] = r.jitsiTimeout; + o["ro"] = r.ro; o["unread"] = r.unread; + d.setObject(o); return d.toBinaryData(); } RoomWrapper::RoomWrapper(QObject *parent) : QObject(parent) {} RoomWrapper::RoomWrapper(const Room &r, QObject *parent) : QObject(parent) { m_name = r.name; m_topic = r.topic; m_unread = r.unread; m_id = r.id; m_selected = r.selected; } RoomModel::RoomModel(QObject* parent) : QAbstractListModel(parent) { // connect(Ruqola::self(), &Ruqola::loginStatusChanged, this, &RoomModel::onLoginStatusChanged); } RoomModel::~RoomModel() { QDir cacheDir(Ruqola::self()->cacheBasePath()); if (!cacheDir.exists(cacheDir.path())) { cacheDir.mkpath(cacheDir.path()); } QFile f(cacheDir.absoluteFilePath("rooms")); if (f.open(QIODevice::WriteOnly)) { QDataStream out(&f); foreach (const Room m, m_roomsList) { QByteArray ms = RoomModel::serialize(m); out.writeBytes(ms, ms.size()); } } } void RoomModel::clear() { if (m_roomsList.size()) { beginRemoveRows(QModelIndex(), 0, rowCount()-1); m_roomsList.clear(); QAbstractItemModel::endRemoveRows(); } } RoomWrapper* RoomModel::findRoom(const QString& roomID) const { foreach (const Room r, m_roomsList) { if (r.id == roomID) { return new RoomWrapper(r); } } Room r; return new RoomWrapper(r); } // Clear data and refill it with data in the cache, if there is void RoomModel::reset() { if (Ruqola::self()->cacheBasePath().isEmpty()) { return; } clear(); QDir cacheDir(Ruqola::self()->cacheBasePath()); // load cache if (cacheDir.exists(cacheDir.path())) { QFile f(cacheDir.absoluteFilePath("rooms")); if (f.open(QIODevice::ReadOnly)) { QDataStream in(&f); while (!f.atEnd()) { char * byteArray; quint32 length; in.readBytes(byteArray, length); QByteArray arr = QByteArray::fromRawData(byteArray, length); Room m = RoomModel::fromJSon(QJsonDocument::fromBinaryData(arr).object()); addRoom(m.id, m.name, m.selected); } } qDebug() << "Cache Loaded"; } } QHash RoomModel::roleNames() const { QHash roles; roles[RoomName] = "name"; roles[RoomID] = "room_id"; roles[RoomSelected] = "selected"; roles[RoomUnread] = "unread"; return roles; } int RoomModel::rowCount(const QModelIndex & parent) const { Q_UNUSED(parent); // if (m_roomsHash.size() > 4) {return 4;} // qDebug() << m_roomsList.size() << "ROOMS"; return m_roomsList.size(); } QVariant RoomModel::data(const QModelIndex & index, int role) const { Room r = m_roomsList.at(index.row()); if (role == RoomModel::RoomName) { return r.name; } else if (role == RoomModel::RoomID) { return r.id; } else if (role == RoomModel::RoomSelected) { return r.selected; } else { return QVariant("0"); } } // void RoomModel::setActiveRoom(const QString& activeRoom) // { // foreach (const QString &id, m_roomsHash.keys()) { // qDebug() << id; // m_roomsHash[id].selected = (id == activeRoom); // } // // emit dataChanged(createIndex(1, 1), createIndex(rowCount(), 1)); // } void RoomModel::addRoom(const QString& roomID, const QString& roomName, bool selected) { if (roomID.isEmpty() || roomName.isEmpty()) { return; } qDebug() << "Adding room" << roomID << roomName; Room r; r.id = roomID; r.name = roomName; r.selected = selected; addRoom(r); } void RoomModel::addRoom(const Room &room) { auto existingRoom = qFind(m_roomsList.begin(), m_roomsList.end(), room); bool present = (existingRoom != m_roomsList.end()); auto i = qUpperBound(m_roomsList.begin(), m_roomsList.end(), room); int pos = i-m_roomsList.begin(); bool roomChanged = false; qDebug() << pos; // if (qFind(m_roomsList.begin(), m_roomsList.end(), room) != m_roomsList.end() && pos > 0) { if (present) { // qDebug() << (qFind(m_roomsList.begin(), m_roomsList.end(), room) - m_roomsList.begin()); // if (pos != m_roomsList.size()) { // we're at the end qDebug() << "Room changed!"; roomChanged = true; //Figure out a better way to update just the really changed message } else { beginInsertRows(QModelIndex(), pos, pos); } if (roomChanged) { m_roomsList.replace(pos-1, room); } else { qDebug() << "Inserting room at position" <getModelForRoom(room.id); } // #include "roommodel.moc" diff --git a/src/roommodel.h b/src/roommodel.h index 3e928269..c79f99dd 100644 --- a/src/roommodel.h +++ b/src/roommodel.h @@ -1,143 +1,177 @@ /* * * Copyright 2016 Riccardo Iaconelli * * 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 . * */ #ifndef ROOMMODEL_H #define ROOMMODEL_H #include #include class Room { public: // Room(const Room &room) // { // // this->parent = room.parent(); // } // To be used in ID find: message ID inline bool operator==(const Room &other) const { return other.id == id; } // To be used in sorted insert: timestamp inline bool operator<(const Room &other) const { return name < other.name; } QString getName() const { return name; } QString getTopic() const { return topic; } // private: // friend class RoomModel; // friend class RoomWrapper; // When you add a field, please remember to also add relevant code // to the enum declaration, roleNames, fromJSon and serialize - QString name, topic, id; + + //Room Object Fields + + // _id + QString id; + + // t (can take values "d" , "c" or "p") + QString type; + + // name + QString name; + + // u + QString userName; + QString userID; + + // topic + QString topic; + + // muted - collection of muted users by its usernames + QString mutedUsers; //QStringList + + // jitsiTimeout + qint64 jitsiTimeout; + + // ro - read-only chat or not + bool ro; + int unread; bool selected = false; }; class RoomWrapper : public QObject { Q_PROPERTY(QString name READ getName NOTIFY nameChanged) Q_PROPERTY(QString topic READ getTopic NOTIFY topicChanged) Q_OBJECT public: RoomWrapper(QObject *parent = 0); RoomWrapper(const Room &r, QObject *parent = 0); QString getName() { return m_name; } QString getTopic() { return m_topic; } signals: void nameChanged(); void topicChanged(); private: QString m_name, m_topic, m_id; int m_unread; bool m_selected; }; class RoomModel : public QAbstractListModel { Q_OBJECT public: enum RoomRoles { RoomName = Qt::UserRole + 1, RoomSelected, RoomID, - RoomUnread + RoomUnread, + RoomType, + RoomUserName, //created by UserName + RoomUserID, + RoomTopic, + RoomMuted, + RoomJitsiTimeout, + RoomRO }; RoomModel(QObject *parent = 0); virtual ~RoomModel(); virtual int rowCount(const QModelIndex & parent = QModelIndex()) const; virtual QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; // void setCurrentRoom(const QString &newRoom); // QString getCurrentRoom() const; Q_INVOKABLE void addRoom(const QString& roomID, const QString& roomName, bool selected = false); void addRoom(const Room& room); RoomWrapper* findRoom(const QString &roomID) const; static Room fromJSon(const QJsonObject &source); static QByteArray serialize(const Room &r); // void setActiveRoom(const QString &activeRoom); void reset(); void clear(); protected: virtual QHash roleNames() const; private: QVector m_roomsList; // QHash< QString, Room > m_roomsHash; }; #endif // ROOMMODEL_H