diff --git a/src/apps/qml/qml/Desktop.qml b/src/apps/qml/qml/Desktop.qml index 4cdd438b..b9ee41ef 100644 --- a/src/apps/qml/qml/Desktop.qml +++ b/src/apps/qml/qml/Desktop.qml @@ -1,513 +1,513 @@ /* * Copyright 2016 Riccardo Iaconelli * Copyright (c) 2017-2020 Laurent Montel * * 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 . * */ import QtQuick 2.9 import QtQuick.Window 2.2 import QtQuick.Dialogs 1.2 import QtQuick.Layouts 1.12 import QtQuick.Controls 2.5 as QQC2 import Ruqola 1.0 import org.kde.kirigami 2.7 as Kirigami Kirigami.ApplicationWindow { id: appid readonly property int margin: 11 property string selectedRoomID: ""; property QtObject selectedRoom property QtObject messageModel property QtObject userModel property QtObject rocketChatAccount: accountManager.account property QtObject filesModel: appid.rocketChatAccount.filesForRoomFilterProxyModel property QtObject discussionsModel: appid.rocketChatAccount.discussionsFilterProxyModel property QtObject accountManager: Ruqola.accountManager() property QtObject accountManagerModel: accountManager.rocketChatAccountModel property QtObject searchMessageModel: rocketChatAccount.searchMessageFilterProxyModel - property QtObject emojiModel: rocketChatAccount.emoticonModel + property QtObject emojiModel: rocketChatAccount.emoticonFilterModel property QtObject threadsModel: rocketChatAccount.threadsFilterProxyModel property QtObject threadMessagesModel: rocketChatAccount.threadMessageModel property QtObject listMessagesModel: rocketChatAccount.listMessagesFilterProxyModel property QtObject autotranslateLanguagesModel: rocketChatAccount.autoTranslateLanguagesModel property string userInputMessageText: ""; width: Kirigami.Units.gridUnit * 55 height: Kirigami.Units.gridUnit * 40 title: i18n("Ruqola") function switchToRoom(roomID) { if (roomID === selectedRoomID) { return; } if (appid.messageModel) { appid.messageModel.deactivate() } appid.rocketChatAccount.switchingToRoom(roomID) appid.rocketChatAccount.setUserCurrentMessage(appid.userInputMessageText, selectedRoomID) appid.selectedRoomID = roomID; appid.messageModel = appid.rocketChatAccount.messageModelForRoom(roomID) appid.messageModel.enableQmlHacks(true) appid.messageModel.activate() appid.selectedRoom = appid.rocketChatAccount.roomWrapper(roomID) appid.userModel = appid.rocketChatAccount.usersForRoomFilterProxyModel(roomID) } pageStack.defaultColumnWidth: Kirigami.Units.gridUnit * 15 pageStack.initialPage: [roomsComponent, mainComponent] pageStack.visible: rocketChatAccount.loginStatus === DDPClient.LoggedIn globalDrawer: Kirigami.GlobalDrawer { drawerOpen: false handleVisible: true resetMenuOnTriggered: true isMenu: true topContent: [ QQC2.Label { text: rocketChatAccount.userName === "" ? "" : i18n("Hello, %1", rocketChatAccount.userName) textFormat: Text.PlainText } ] actions: [ Kirigami.Action { text: i18n("About") iconName: "ruqola" onTriggered: { pageStack.push(aboutPage) } }, Kirigami.Action { text: i18n("Report a Bug") iconName: "tools-report-bug" onTriggered: { Qt.openUrlExternally("https://bugs.kde.org/report.cgi"); } }, Kirigami.Action { text: i18n("Configure Account") iconName: "settings-configure" onTriggered: pageStack.push(Qt.resolvedUrl("ConfigureServerList.qml"), {accountModel: accountManagerModel}) }, Kirigami.Action { text: i18n("Handbook") iconName: "system-help" onTriggered: { rocketChatAccount.openDocumentation(); } }, Kirigami.Action { separator: true }, Kirigami.Action { text: i18n("Log out") iconName: "system-log-out" onTriggered: { rocketChatAccount.logOut(); appid.globalDrawer.drawerOpen = false; } }, // Kirigami.Action { // text: i18n("autotranslate") // onTriggered: { // rocketChatAccount.getSupportedLanguages(); // } // }, Kirigami.Action { separator: true }, Kirigami.Action { shortcut: StandardKey.Quit text: i18n("Quit") iconName: "application-exit" onTriggered: { Qt.quit(); } } ] } LoginPage { id: loginTab rcAccount: rocketChatAccount } Component { id: aboutPage Kirigami.AboutPage { aboutData: Ruqola.applicationData() actions.main: Kirigami.Action { text: i18n("Close") icon.name: "window-close-symbolic" onTriggered: pageStack.pop() } } } Loader { id: customUserStatusDialogLoader active: false sourceComponent: CustomUserStatusDialog { id: customUserStatusDialog parent: appid.pageStack onRejected: { customUserStatusDialogLoader.active = false } onAccepted: { customUserStatusDialogLoader.active = false } Component.onCompleted: { open() } } } Loader { id: privateChannelInfoDialogLoader active: false sourceComponent: PrivateChannelInfoDialog { id: privateChannelInfoDialog roomInfo: appid.selectedRoom parent: appid.pageStack onBlockUser: { rocketChatAccount.blockUser(rid, block) } onRejected: { privateChannelInfoDialogLoader.active = false } onAccepted: { privateChannelInfoDialogLoader.active = false } Component.onCompleted: { initializeAndOpen() } } } Loader { id: notificationsDialogLoader active: false sourceComponent: NotificationOptionsDialog { id: notificationsDialog parent: appid.pageStack onModifyNotificationsSetting: { rocketChatAccount.changeNotificationsSettings(roomId, type, newVal) } Component.onCompleted: { rid = (appid && appid.selectedRoomID) ? appid.selectedRoomID : "" roomInfo = appid ? appid.selectedRoom : "" initializeAndOpen() } onRejected: { notificationsDialogLoader.active = false } onAccepted: { notificationsDialogLoader.active = false } } } Loader { id: channelInfoDialogLoader active: false sourceComponent: ChannelInfoDialog { id: channelInfoDialog parent: appid.pageStack roomInfo: appid.selectedRoom channelName: (appid && appid.selectedRoomID) ? appid.selectedRoomID : "" onDeleteRoom: { rocketChatAccount.eraseRoom(roomId, appid.selectedRoom.channelType) } onModifyChannelSetting: { rocketChatAccount.changeChannelSettings(roomId, type, newVal, channelType) } onRejected: { channelInfoDialogLoader.active = false } onAccepted: { channelInfoDialogLoader.active = false } Component.onCompleted: { open() } } } Loader { id: leaveChannelDialogLoader active: false property string rid property string roomType sourceComponent: LeaveChannelDialog { id: leaveChannelDialog parent: appid.pageStack onLeaveChannel: { rocketChatAccount.leaveRoom(roomId, channelType) } onRejected: { leaveChannelDialogLoader.active = false } onAccepted: { leaveChannelDialogLoader.active = false } Component.onCompleted: { leaveChannelDialog.rId = leaveChannelDialogLoader.rid leaveChannelDialog.channelType = leaveChannelDialogLoader.roomType open() } } } Loader { id: addUserDialogLoader active: false sourceComponent: AddUserDialog { id: addUserDialog parent: appid.pageStack completerModel: rocketChatAccount.userCompleterFilterModelProxy roomInfo: appid.selectedRoom roomId: appid.selectedRoomID onSearchUserName: { rocketChatAccount.userAutocomplete(pattern, ""); } onAddUser: { rocketChatAccount.addUserToRoom(userId, rid, channelType) } onRejected: { addUserDialogLoader.active = false } onAccepted: { addUserDialogLoader.active = false } Component.onCompleted: { initializeAndOpen() } } } Loader { id: searchMessageDialogLoader active: false sourceComponent: ShowSearchMessageDialog { id: searchMessageDialog roomId: appid.selectedRoomID parent: appid.pageStack searchMessageModel: appid.searchMessageModel onSearchMessage: { rocketChatAccount.messageSearch(pattern, rid) } onGoToMessage: { console.log(RuqolaDebugCategorySingleton.category, "Show history to message: " + messageId) } onRejected: { rocketChatAccount.clearSearchModel() searchMessageDialogLoader.active = false } onAccepted: { rocketChatAccount.clearSearchModel() searchMessageDialogLoader.active = false } Component.onCompleted: { roomId = appid.selectedRoomID initializeAndOpen() } } } Loader { id: jobErrorMessageDialogLoader property string jobMessageError active: false sourceComponent: JobErrorMessageDialog { id: jobErrorMessageDialog parent: appid.pageStack Component.onCompleted: { jobErrorMessageDialog.jobMessageError = jobErrorMessageDialogLoader.jobMessageError open() } onRejected: { jobErrorMessageDialogLoader.active = false } onAccepted: { jobErrorMessageDialogLoader.active = false } } } Loader { id: createNewChannelDialogLoader active: false sourceComponent: CreateNewChannelDialog { parent: appid.pageStack Component.onCompleted: { encryptedRoomEnabled = appid.rocketChatAccount.encryptedEnabled initializeAndOpen() } onRejected: { createNewChannelDialogLoader.active = false } onAccepted: { createNewChannelDialogLoader.active = false } onCreateNewChannel: { rocketChatAccount.createNewChannel(name, readOnly, privateRoom, usernames, encryptedRoom, password, broadcast); } } } Loader { id: serverinfodialogLoader active: false sourceComponent: ServerInfoDialog { rcAccount: appid.rocketChatAccount parent: appid.pageStack Component.onCompleted: { open() } onRejected: { serverinfodialogLoader.active = false } } } SearchChannelDialog { id: searchChannelDialog searchChannelModel: rocketChatAccount.searchChannelFilterProxyModel onSearchChannel: { rocketChatAccount.channelAndPrivateAutocomplete(pattern); } onOpenChannel: { if (channeltype === Channel.Room) { rocketChatAccount.openChannel(channelid, RocketChatAccount.RoomId) } else if (channeltype === Channel.PrivateChannel) { if (rocketChatAccount.userName !== channelid) { rocketChatAccount.openDirectChannel(channelid) } } else { console.log(RuqolaDebugCategorySingleton.category, "Unknown open channel type : " + channeltype + " channelid : " + channelid + " channelname : " + channelname) } } } Loader { id: takeVideoMessageLoader active: false sourceComponent: TakeVideoMessageDialog { id: takeVideoMessage parent: appid.pageStack rcAccount: rocketChatAccount Component.onCompleted: { open() } onRejected: { takeVideoMessageLoader.active = false } onAccepted: { takeVideoMessageLoader.active = false } } } QQC2.BusyIndicator { id: busy anchors.centerIn: parent visible: rocketChatAccount.loginStatus === DDPClient.LoggingIn } RoomsComponent { id: roomsComponent } MainComponent { id: mainComponent } Loader { id: channelPasswordDialogLoader active: false property string roomId sourceComponent: ChannelPasswordDialog { id: channelPasswordDialog parent: appid.pageStack onJoinRoom: { rocketChatAccount.joinRoom(roomId, password) } Component.onCompleted: { roomId = channelPasswordDialogLoader.roomId initializeAndOpen() } onRejected: { channelPasswordDialogLoader.active = false } onAccepted: { channelPasswordDialogLoader.active = false } } } Connections { target: rocketChatAccount onMissingChannelPassword: { channelPasswordDialogLoader.roomId = roomId channelPasswordDialogLoader.active = true } onJobFailed: { jobErrorMessageDialogLoader.jobMessageError = message jobErrorMessageDialogLoader.active = true } } onClosing: { Qt.quit(); } function toggleShow() { if (visible) { hide(); } else { show(); raise(); requestActivate(); } } Component.onCompleted: { if (Qt.platform.os == "android") { return; } systrayIcon.activateRequested.connect(toggleShow); } } diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 0d80c624..613464de 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1,228 +1,228 @@ set(Ruqola_ddpapi_SRCS ddpapi/ddpclient.cpp ) set (Ruqola_model_core_srcs model/messagemodel.cpp model/roommodel.cpp model/roomfilterproxymodel.cpp model/usersforroommodel.cpp model/usersforroomfilterproxymodel.cpp model/usersmodel.cpp model/usercompleterfilterproxymodel.cpp model/usercompletermodel.cpp model/statusmodel.cpp model/filesforroommodel.cpp model/filesforroomfilterproxymodel.cpp model/searchchannelmodel.cpp model/searchchannelfilterproxymodel.cpp model/inputcompletermodel.cpp model/loginmethodmodel.cpp model/searchmessagemodel.cpp model/searchmessagefilterproxymodel.cpp model/rocketchataccountmodel.cpp model/rocketchataccountfilterproxymodel.cpp - model/emoticonmodel.cpp + model/emoticonfiltermodel.cpp model/notificationpreferencemodel.cpp model/notificationdesktopdurationpreferencemodel.cpp model/notificationdesktopsoundpreferencemodel.cpp model/discussionsmodel.cpp model/discussionsfilterproxymodel.cpp model/threadsmodel.cpp model/threadsfilterproxymodel.cpp model/emoticoncategoriesmodel.cpp model/threadmessagemodel.cpp model/listmessagesmodel.cpp model/listmessagesmodelfilterproxymodel.cpp model/autotranslatelanguagesmodel.cpp ) set(Ruqola_plugins_srcs plugins/pluginauthenticationinterface.cpp plugins/pluginauthentication.cpp ) set(Ruqola_emoticons_srcs emoticons/emoji.cpp emoticons/emojimanager.cpp emoticons/unicodeemoticon.cpp emoticons/unicodeemoticonparser.cpp ) set(Ruqola_messages_srcs messages/message.cpp messages/messageattachment.cpp messages/messageurl.cpp messages/messagestarred.cpp messages/reactions.cpp messages/reaction.cpp messages/messagepinned.cpp messages/messagetranslation.cpp ) set(Ruqola_message_convertertextjob_SRCS convertertextjob/convertertextabstractjob.cpp convertertextjob/translatetextjob.cpp ) set(Ruqola_autotranslatelanguage_SRCS autotranslatelanguage.cpp autotranslatelanguages.cpp ) set (Ruqola_core_srcs ${Ruqola_autotranslatelanguage_SRCS} ${Ruqola_message_convertertextjob_SRCS} ${Ruqola_emoticons_srcs} ${Ruqola_messages_srcs} ${Ruqola_model_core_srcs} ${Ruqola_plugins_srcs} ${Ruqola_ddpapi_SRCS} authenticationinfo.cpp room.cpp roomwrapper.cpp notificationoptionswrapper.cpp ruqola.cpp ruqolautils.cpp rocketchatbackend.cpp messagequeue.cpp rocketchatmessage.cpp typingnotification.cpp changetemporarystatus.cpp user.cpp utils.cpp clipboardproxy.cpp otr.cpp otrmanager.cpp abstractwebsocket.cpp ruqolawebsocket.cpp rocketchataccount.cpp rocketchataccountsettings.cpp ruqolalogger.cpp ruqolaregisterengine.cpp ruqolaserverconfig.cpp rocketchatcache.cpp texthighlighter.cpp textconverter.cpp loadrecenthistorymanager.cpp file.cpp channel.cpp inputtextmanager.cpp authenticationmanager.cpp accountmanager.cpp managerdatapaths.cpp notificationoptions.cpp syntaxhighlightingmanager.cpp receivetypingnotificationmanager.cpp serverconfiginfo.cpp notificationpreferences.cpp roles.cpp role.cpp avatarmanager.cpp discussion.cpp discussions.cpp threads.cpp emoticoncategory.cpp listmessages.cpp messagedownloadmanager.cpp fileattachments.cpp accountroomsettings.cpp ) if (NOT WIN32) set(Ruqola_core_srcs ${Ruqola_core_srcs} unityservicemanager.cpp) endif() if (NOT ANDROID) list(APPEND Ruqola_core_srcs notification.cpp) endif() ecm_qt_declare_logging_category(Ruqola_core_srcs HEADER ruqola_debug.h IDENTIFIER RUQOLA_LOG CATEGORY_NAME org.kde.ruqola) ecm_qt_declare_logging_category(Ruqola_core_srcs HEADER ruqola_message_debug.h IDENTIFIER RUQOLA_MESSAGE_LOG CATEGORY_NAME org.kde.ruqola.message) ecm_qt_declare_logging_category(Ruqola_core_srcs HEADER ruqola_ddpapi_debug.h IDENTIFIER RUQOLA_DDPAPI_LOG CATEGORY_NAME org.kde.ruqola.ddpapi) ecm_qt_declare_logging_category(Ruqola_core_srcs HEADER ruqola_ddpapi_command_debug.h IDENTIFIER RUQOLA_DDPAPI_COMMAND_LOG CATEGORY_NAME org.kde.ruqola.ddpapi.command) ecm_qt_declare_logging_category(Ruqola_core_srcs HEADER ruqola_unknown_collectiontype_debug.h IDENTIFIER RUQOLA_UNKNOWN_COLLECTIONTYPE_LOG CATEGORY_NAME org.kde.ruqola.ddp.collectiontype) qt5_add_resources(libruqolacore_RSC ruqolacore.qrc) add_library(libruqolacore ${Ruqola_core_srcs} ${libruqolacore_RSC}) generate_export_header(libruqolacore BASE_NAME libruqolacore) target_link_libraries(libruqolacore Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Qml Qt5::Quick Qt5::WebSockets Qt5::Network Qt5::NetworkAuth KF5::CoreAddons KF5::I18n KF5::Notifications KF5::SyntaxHighlighting librocketchatrestapi-qt5 ) if (NOT WIN32) target_link_libraries(libruqolacore Qt5::DBus) endif() if (WIN32 OR APPLE) target_link_libraries(libruqolacore KF5::IconThemes) endif() if (Qt5Keychain_FOUND) target_link_libraries(libruqolacore qt5keychain) target_include_directories(libruqolacore PRIVATE ${QTKEYCHAIN_INCLUDE_DIRS}) endif() set_target_properties(libruqolacore PROPERTIES OUTPUT_NAME ruqolacore VERSION ${RUQOLA_LIB_VERSION} SOVERSION ${RUQOLA_LIB_SOVERSION} ) if (BUILD_TESTING) add_subdirectory(autotests) endif() install(TARGETS libruqolacore ${KDE_INSTALL_TARGETS_DEFAULT_ARGS} LIBRARY NAMELINK_SKIP) if (ANDROID) install(FILES ruqolacore-android-dependencies.xml DESTINATION ${KDE_INSTALL_LIBDIR}) endif() diff --git a/src/core/autotests/emoticonmodeltest.cpp b/src/core/autotests/emoticonmodeltest.cpp index 29630ece..e6df4c4d 100644 --- a/src/core/autotests/emoticonmodeltest.cpp +++ b/src/core/autotests/emoticonmodeltest.cpp @@ -1,54 +1,54 @@ /* Copyright (c) 2018-2020 Laurent Montel This library 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 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "emoticonmodeltest.h" -#include "model/emoticonmodel.h" +#include "model/emoticonfiltermodel.h" #include QTEST_GUILESS_MAIN(EmoticonModelTest) EmoticonModelTest::EmoticonModelTest(QObject *parent) : QObject(parent) { } void EmoticonModelTest::shouldHaveDefaultValue() { - EmoticonModel w; + EmoticonFilterModel w; QVERIFY(w.currentCategory().isEmpty()); QVERIFY(w.emoticons().isEmpty()); QHash roles; - roles[EmoticonModel::Identifier] = QByteArrayLiteral("identifier"); - roles[EmoticonModel::EmoticonModel::Text] = QByteArrayLiteral("text"); - roles[EmoticonModel::UnicodeEmoji] = QByteArrayLiteral("unicodeEmoji"); - roles[EmoticonModel::Order] = QByteArrayLiteral("order"); + roles[EmoticonFilterModel::Identifier] = QByteArrayLiteral("identifier"); + roles[EmoticonFilterModel::EmoticonFilterModel::Text] = QByteArrayLiteral("text"); + roles[EmoticonFilterModel::UnicodeEmoji] = QByteArrayLiteral("unicodeEmoji"); + roles[EmoticonFilterModel::Order] = QByteArrayLiteral("order"); QCOMPARE(w.roleNames(), roles); QVERIFY(w.emoticonCategoriesModel()); } void EmoticonModelTest::shouldAssignCategory() { - EmoticonModel w; + EmoticonFilterModel w; const QString category = QStringLiteral("bla"); w.setCurrentCategory(category); QCOMPARE(w.currentCategory(), category); } //TODO add more check diff --git a/src/core/model/emoticonmodel.cpp b/src/core/model/emoticonfiltermodel.cpp similarity index 79% rename from src/core/model/emoticonmodel.cpp rename to src/core/model/emoticonfiltermodel.cpp index c034f69f..262f3169 100644 --- a/src/core/model/emoticonmodel.cpp +++ b/src/core/model/emoticonfiltermodel.cpp @@ -1,113 +1,113 @@ /* Copyright (c) 2018-2020 Laurent Montel This library 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 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "emoticonmodel.h" +#include "emoticonfiltermodel.h" -EmoticonModel::EmoticonModel(QObject *parent) +EmoticonFilterModel::EmoticonFilterModel(QObject *parent) : QAbstractListModel(parent) { mEmoticonCategoriesModel = new EmoticonCategoriesModel(this); } -EmoticonModel::~EmoticonModel() +EmoticonFilterModel::~EmoticonFilterModel() { } -int EmoticonModel::rowCount(const QModelIndex &parent) const +int EmoticonFilterModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); if (mEmoticons.contains(mCurrentCategory)) { return mEmoticons[mCurrentCategory].count(); } return 0; } -QVariant EmoticonModel::data(const QModelIndex &index, int role) const +QVariant EmoticonFilterModel::data(const QModelIndex &index, int role) const { const QVector emoticonsFromCategoryList = mEmoticons.value(mCurrentCategory); if (index.row() < 0 || index.row() >= emoticonsFromCategoryList.count()) { return {}; } const UnicodeEmoticon unicodeEmoti = emoticonsFromCategoryList.at(index.row()); switch (role) { case Identifier: return unicodeEmoti.identifier(); case Text: return unicodeEmoti.key(); case UnicodeEmoji: return unicodeEmoti.unicode(); case Order: return unicodeEmoti.order(); } return {}; } -QHash EmoticonModel::roleNames() const +QHash EmoticonFilterModel::roleNames() const { QHash roles; roles[Identifier] = QByteArrayLiteral("identifier"); roles[Text] = QByteArrayLiteral("text"); roles[UnicodeEmoji] = QByteArrayLiteral("unicodeEmoji"); roles[Order] = QByteArrayLiteral("order"); return roles; } -QMap > EmoticonModel::emoticons() const +QMap > EmoticonFilterModel::emoticons() const { return mEmoticons; } -void EmoticonModel::setEmoticons(const QMap > &emoticons) +void EmoticonFilterModel::setEmoticons(const QMap > &emoticons) { if (rowCount() != 0) { beginRemoveRows(QModelIndex(), 0, mEmoticons.count() - 1); mEmoticons.clear(); endRemoveRows(); } if (!emoticons.isEmpty()) { beginInsertRows(QModelIndex(), 0, emoticons.count() - 1); mEmoticons = emoticons; endInsertRows(); } if (!mEmoticons.isEmpty()) { mCurrentCategory = mEmoticons.keys().at(0); mEmoticonCategoriesModel->setEmoticons(emoticons); } } -void EmoticonModel::setCurrentCategory(const QString &category) +void EmoticonFilterModel::setCurrentCategory(const QString &category) { if (mCurrentCategory != category) { beginResetModel(); mCurrentCategory = category; endResetModel(); } } -QString EmoticonModel::currentCategory() const +QString EmoticonFilterModel::currentCategory() const { return mCurrentCategory; } -EmoticonCategoriesModel *EmoticonModel::emoticonCategoriesModel() const +EmoticonCategoriesModel *EmoticonFilterModel::emoticonCategoriesModel() const { return mEmoticonCategoriesModel; } diff --git a/src/core/model/emoticonmodel.h b/src/core/model/emoticonfiltermodel.h similarity index 87% rename from src/core/model/emoticonmodel.h rename to src/core/model/emoticonfiltermodel.h index c81305ca..d3f2f814 100644 --- a/src/core/model/emoticonmodel.h +++ b/src/core/model/emoticonfiltermodel.h @@ -1,66 +1,66 @@ /* Copyright (c) 2018-2020 Laurent Montel This library 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 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef EMOTICONMODEL_H -#define EMOTICONMODEL_H +#ifndef EMOTICONFILTERMODEL_H +#define EMOTICONFILTERMODEL_H #include #include "libruqolacore_export.h" #include "emoticons/unicodeemoticon.h" #include "emoticoncategoriesmodel.h" // Model showing emojis from a single category -class LIBRUQOLACORE_EXPORT EmoticonModel : public QAbstractListModel +class LIBRUQOLACORE_EXPORT EmoticonFilterModel : public QAbstractListModel { Q_OBJECT public: enum EmoticonsRoles { Identifier = Qt::UserRole + 1, Text, UnicodeEmoji, Order }; Q_ENUM(EmoticonsRoles) - explicit EmoticonModel(QObject *parent = nullptr); - ~EmoticonModel() override; + explicit EmoticonFilterModel(QObject *parent = nullptr); + ~EmoticonFilterModel() override; Q_REQUIRED_RESULT int rowCount(const QModelIndex &parent = QModelIndex()) const override; Q_REQUIRED_RESULT QVariant data(const QModelIndex &index, int role) const override; Q_REQUIRED_RESULT QHash roleNames() const override; Q_REQUIRED_RESULT QMap > emoticons() const; void setEmoticons(const QMap > &emoticons); Q_INVOKABLE void setCurrentCategory(const QString &category); Q_INVOKABLE Q_REQUIRED_RESULT QString currentCategory() const; Q_INVOKABLE EmoticonCategoriesModel *emoticonCategoriesModel() const; private: - Q_DISABLE_COPY(EmoticonModel) + Q_DISABLE_COPY(EmoticonFilterModel) QMap > mEmoticons; QString mCurrentCategory; EmoticonCategoriesModel *mEmoticonCategoriesModel = nullptr; }; -#endif // EMOTICONMODEL_H +#endif // EMOTICONFILTERMODEL_H diff --git a/src/core/rocketchataccount.cpp b/src/core/rocketchataccount.cpp index 323c72a3..99098c3d 100644 --- a/src/core/rocketchataccount.cpp +++ b/src/core/rocketchataccount.cpp @@ -1,1968 +1,1968 @@ /* Copyright (c) 2017-2020 Laurent Montel This library 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 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "model/messagemodel.h" #include "rocketchataccount.h" #include "model/roommodel.h" #include "roomwrapper.h" #include "typingnotification.h" #include "model/usersmodel.h" #include "ruqola_debug.h" #include "ruqola.h" #include "messagequeue.h" #include "rocketchatbackend.h" #include "model/roomfilterproxymodel.h" #include "ruqolalogger.h" #include "ruqolaserverconfig.h" #include "model/usercompletermodel.h" #include "model/usercompleterfilterproxymodel.h" #include "model/statusmodel.h" #include "utils.h" #include "rocketchatcache.h" #include "fileattachments.h" #include "emoticons/emojimanager.h" -#include "model/emoticonmodel.h" +#include "model/emoticonfiltermodel.h" #include "otrmanager.h" #include "inputtextmanager.h" #include "model/usersforroommodel.h" #include "model/filesforroommodel.h" #include "model/searchchannelfilterproxymodel.h" #include "model/searchchannelmodel.h" #include "model/loginmethodmodel.h" #include "model/inputcompletermodel.h" #include "model/searchmessagemodel.h" #include "model/searchmessagefilterproxymodel.h" #include "model/discussionsmodel.h" #include "model/threadsmodel.h" #include "model/filesforroomfilterproxymodel.h" #include "model/discussionsfilterproxymodel.h" #include "model/threadsfilterproxymodel.h" #include "model/listmessagesmodel.h" #include "model/threadmessagemodel.h" #include "model/listmessagesmodelfilterproxymodel.h" #include "model/autotranslatelanguagesmodel.h" #include "managerdatapaths.h" #include "authenticationmanager.h" #include "ddpapi/ddpclient.h" #include "discussions.h" #include "receivetypingnotificationmanager.h" #include "restapirequest.h" #include "serverconfiginfo.h" #include "listmessages.h" #include "threads.h" #include #include #include #include #include #include "users/setstatusjob.h" #include "users/usersautocompletejob.h" #define USE_REASTAPI_JOB 1 RocketChatAccount::RocketChatAccount(const QString &accountFileName, QObject *parent) : QObject(parent) { mAccountRoomSettings = new AccountRoomSettings; qCDebug(RUQOLA_LOG) << " RocketChatAccount::RocketChatAccount(const QString &accountFileName, QObject *parent)"<accountName()); } mServerConfigInfo = new ServerConfigInfo(this, this); //Create it before loading settings mLoginMethodModel = new LoginMethodModel(this); mInputTextManager = new InputTextManager(this); connect(mInputTextManager, &InputTextManager::inputCompleter, this, &RocketChatAccount::inputAutocomplete); mInputThreadMessageTextManager = new InputTextManager(this); connect(mInputThreadMessageTextManager, &InputTextManager::inputCompleter, this, &RocketChatAccount::inputAutocomplete); mRuqolaServerConfig = new RuqolaServerConfig; mReceiveTypingNotificationManager = new ReceiveTypingNotificationManager(this); initializeAuthenticationPlugins(); mRocketChatBackend = new RocketChatBackend(this, this); - mEmoticonModel = new EmoticonModel(this); + mEmoticonModel = new EmoticonFilterModel(this); //After loadSettings mEmojiManager = new EmojiManager(this); mEmojiManager->setServerUrl(mSettings->serverUrl()); mEmoticonModel->setEmoticons(mEmojiManager->unicodeEmojiList()); mOtrManager = new OtrManager(this); mRoomFilterProxyModel = new RoomFilterProxyModel(this); mUserCompleterModel = new UserCompleterModel(this); mUserCompleterFilterModelProxy = new UserCompleterFilterProxyModel(this); mUserCompleterFilterModelProxy->setSourceModel(mUserCompleterModel); mSearchChannelModel = new SearchChannelModel(this); mSearchChannelFilterProxyModel = new SearchChannelFilterProxyModel(this); mSearchChannelFilterProxyModel->setSourceModel(mSearchChannelModel); mSearchMessageModel = new SearchMessageModel(QString(), this, nullptr, this); mSearchMessageFilterProxyModel = new SearchMessageFilterProxyModel(mSearchMessageModel, this); mFilesModelForRoom = new FilesForRoomModel(this, this); mFilesModelForRoom->setObjectName(QStringLiteral("filesmodelforrooms")); mFilesForRoomFilterProxyModel = new FilesForRoomFilterProxyModel(mFilesModelForRoom, this); mFilesForRoomFilterProxyModel->setObjectName(QStringLiteral("filesforroomfiltermodelproxy")); mDiscussionsModel = new DiscussionsModel(this); mDiscussionsModel->setObjectName(QStringLiteral("discussionsmodel")); mDiscussionsFilterProxyModel = new DiscussionsFilterProxyModel(mDiscussionsModel, this); mDiscussionsFilterProxyModel->setObjectName(QStringLiteral("discussionsfilterproxymodel")); mThreadsModel = new ThreadsModel(this); mThreadsModel->setObjectName(QStringLiteral("threadsmodel")); mThreadsFilterProxyModel = new ThreadsFilterProxyModel(mThreadsModel, this); mThreadsFilterProxyModel->setObjectName(QStringLiteral("threadsfiltermodelproxy")); mThreadMessageModel = new ThreadMessageModel(QString(), this, nullptr, this); mThreadMessageModel->setObjectName(QStringLiteral("threadmessagemodel")); mListMessageModel = new ListMessagesModel(QString(), this, nullptr, this); mListMessageModel->setObjectName(QStringLiteral("listmessagemodel")); mListMessagesFilterProxyModel = new ListMessagesModelFilterProxyModel(mListMessageModel, this); mListMessagesFilterProxyModel->setObjectName(QStringLiteral("listmessagesfiltermodelproxy")); mAutoTranslateLanguagesModel = new AutotranslateLanguagesModel(this); mAutoTranslateLanguagesModel->setObjectName(QStringLiteral("autotranslatelanguagesmodel")); mStatusModel = new StatusModel(this); mRoomModel = new RoomModel(this, this); connect(mRoomModel, &RoomModel::needToUpdateNotification, this, &RocketChatAccount::slotNeedToUpdateNotification); mRoomFilterProxyModel->setSourceModel(mRoomModel); mUserModel = new UsersModel(this); connect(mUserModel, &UsersModel::userStatusChanged, this, &RocketChatAccount::userStatusChanged); mMessageQueue = new MessageQueue(this, this); //TODO fix mem leak ! mTypingNotification = new TypingNotification(this); mCache = new RocketChatCache(this, this); connect(mCache, &RocketChatCache::fileDownloaded, this, &RocketChatAccount::fileDownloaded); connect(mTypingNotification, &TypingNotification::informTypingStatus, this, &RocketChatAccount::slotInformTypingStatus); QTimer::singleShot(0, this, &RocketChatAccount::clearModels); } RocketChatAccount::~RocketChatAccount() { delete mCache; mCache = nullptr; delete mRuqolaServerConfig; delete mRuqolaLogger; delete mAccountRoomSettings; } void RocketChatAccount::removeSettings() { mSettings->removeSettings(); } void RocketChatAccount::loadSettings(const QString &accountFileName) { delete mSettings; mSettings = new RocketChatAccountSettings(accountFileName, this); connect(mSettings, &RocketChatAccountSettings::serverURLChanged, this, &RocketChatAccount::serverUrlChanged); connect(mSettings, &RocketChatAccountSettings::userIDChanged, this, &RocketChatAccount::userIDChanged); connect(mSettings, &RocketChatAccountSettings::userNameChanged, this, &RocketChatAccount::userNameChanged); connect(mSettings, &RocketChatAccountSettings::passwordChanged, this, &RocketChatAccount::passwordChanged); } void RocketChatAccount::slotNeedToUpdateNotification() { bool hasAlert = false; int nbUnread = 0; mRoomModel->getUnreadAlertFromAccount(hasAlert, nbUnread); Q_EMIT updateNotification(hasAlert, nbUnread, accountName()); } void RocketChatAccount::clearModels() { // Clear rooms data and refill it with data in the cache, if there is mRoomModel->reset(); mMessageQueue->loadCache(); //Try to send queue message mMessageQueue->processQueue(); } SearchChannelFilterProxyModel *RocketChatAccount::searchChannelFilterProxyModel() const { return mSearchChannelFilterProxyModel; } SearchChannelModel *RocketChatAccount::searchChannelModel() const { return mSearchChannelModel; } UserCompleterModel *RocketChatAccount::userCompleterModel() const { return mUserCompleterModel; } UserCompleterFilterProxyModel *RocketChatAccount::userCompleterFilterModelProxy() const { return mUserCompleterFilterModelProxy; } EmojiManager *RocketChatAccount::emojiManager() const { return mEmojiManager; } QString RocketChatAccount::userStatusIconFileName(const QString &name) { return mUserModel->userStatusIconFileName(name); } StatusModel *RocketChatAccount::statusModel() const { return mStatusModel; } RuqolaServerConfig *RocketChatAccount::ruqolaServerConfig() const { return mRuqolaServerConfig; } RuqolaLogger *RocketChatAccount::ruqolaLogger() const { return mRuqolaLogger; } RoomFilterProxyModel *RocketChatAccount::roomFilterProxyModel() const { return mRoomFilterProxyModel; } UsersForRoomFilterProxyModel *RocketChatAccount::usersForRoomFilterProxyModel(const QString &roomId) const { return mRoomModel->usersForRoomFilterProxyModel(roomId); } FilesForRoomFilterProxyModel *RocketChatAccount::filesForRoomFilterProxyModel() const { return mFilesForRoomFilterProxyModel; } RocketChatBackend *RocketChatAccount::rocketChatBackend() const { return mRocketChatBackend; } MessageQueue *RocketChatAccount::messageQueue() const { return mMessageQueue; } RocketChatAccountSettings *RocketChatAccount::settings() const { return mSettings; } void RocketChatAccount::slotInformTypingStatus(const QString &room, bool typing) { ddp()->informTypingStatus(room, typing, mSettings->userName()); } RoomModel *RocketChatAccount::roomModel() const { return mRoomModel; } UsersModel *RocketChatAccount::usersModel() const { return mUserModel; } Room *RocketChatAccount::getRoom(const QString &roomId) { return mRoomModel->findRoom(roomId); } DiscussionsFilterProxyModel *RocketChatAccount::discussionsFilterProxyModel() const { return mDiscussionsFilterProxyModel; } ThreadsFilterProxyModel *RocketChatAccount::threadsFilterProxyModel() const { return mThreadsFilterProxyModel; } RoomWrapper *RocketChatAccount::roomWrapper(const QString &roomId) { return mRoomModel->findRoomWrapper(roomId); } MessageModel *RocketChatAccount::messageModelForRoom(const QString &roomID) { return mRoomModel->messageModel(roomID); } void RocketChatAccount::changeDisplayAttachment(const QString &roomId, const QString &messageId, bool displayAttachment) { MessageModel *model = mRoomModel->messageModel(roomId); if (model) { model->changeDisplayAttachment(messageId, displayAttachment); } else { qCWarning(RUQOLA_LOG) << "impossible to find room: " << roomId; } //TODO } void RocketChatAccount::changeShowOriginalMessage(const QString &roomId, const QString &messageId, bool showOriginal) { MessageModel *model = mRoomModel->messageModel(roomId); if (model) { model->changeShowOriginalMessage(messageId, showOriginal); } else { qCWarning(RUQOLA_LOG) << "impossible to find room: " << roomId; } //TODO } QString RocketChatAccount::getUserCurrentMessage(const QString &roomId) { return mRoomModel->inputMessage(roomId); } void RocketChatAccount::setUserCurrentMessage(const QString &message, const QString &roomId) { mRoomModel->setInputMessage(roomId, message); } void RocketChatAccount::textEditing(const QString &roomId, bool clearNotification) { mTypingNotification->textNotificationChanged(roomId, clearNotification); } void RocketChatAccount::reactOnMessage(const QString &messageId, const QString &emoji, bool shouldReact) { restApi()->reactOnMessage(messageId, emoji, shouldReact); } void RocketChatAccount::replyToMessage(const QString &roomID, const QString &message, const QString &messageId) { restApi()->postMessage(roomID, message); } void RocketChatAccount::sendMessage(const QString &roomID, const QString &message) { restApi()->postMessage(roomID, message); } void RocketChatAccount::updateMessage(const QString &roomID, const QString &messageId, const QString &message) { restApi()->updateMessage(roomID, messageId, message); } void RocketChatAccount::replyOnThread(const QString &roomID, const QString &threadMessageId, const QString &message) { restApi()->sendMessage(roomID, message, QString(), threadMessageId); } QString RocketChatAccount::avatarUrlFromDirectChannel(const QString &rid) { return mCache->avatarUrl(Utils::userIdFromDirectChannel(rid, userID())); } void RocketChatAccount::deleteFileMessage(const QString &roomId, const QString &fileId, const QString &channelType) { ddp()->deleteFileMessage(roomId, fileId, channelType); } QString RocketChatAccount::avatarUrl(const QString &userId) { return mCache->avatarUrl(userId); } void RocketChatAccount::insertAvatarUrl(const QString &userId, const QUrl &url) { mCache->insertAvatarUrl(userId, url); } RocketChatRestApi::RestApiRequest *RocketChatAccount::restApi() { if (!mRestApi) { mRestApi = new RocketChatRestApi::RestApiRequest(this); connect(mRestApi, &RocketChatRestApi::RestApiRequest::setChannelJoinDone, this, &RocketChatAccount::setChannelJoinDone); connect(mRestApi, &RocketChatRestApi::RestApiRequest::missingChannelPassword, this, &RocketChatAccount::missingChannelPassword); connect(mRestApi, &RocketChatRestApi::RestApiRequest::loadEmojiCustomDone, this, &RocketChatAccount::loadEmoji); connect(mRestApi, &RocketChatRestApi::RestApiRequest::openArchivedRoom, this, &RocketChatAccount::openArchivedRoom); connect(mRestApi, &RocketChatRestApi::RestApiRequest::channelMembersDone, this, &RocketChatAccount::parseUsersForRooms); connect(mRestApi, &RocketChatRestApi::RestApiRequest::channelFilesDone, this, &RocketChatAccount::slotChannelFilesDone); connect(mRestApi, &RocketChatRestApi::RestApiRequest::channelRolesDone, this, &RocketChatAccount::slotChannelRolesDone); connect(mRestApi, &RocketChatRestApi::RestApiRequest::searchMessageDone, this, &RocketChatAccount::slotSearchMessages); connect(mRestApi, &RocketChatRestApi::RestApiRequest::failed, this, &RocketChatAccount::jobFailed); connect(mRestApi, &RocketChatRestApi::RestApiRequest::spotlightDone, this, &RocketChatAccount::slotSplotLightDone); connect(mRestApi, &RocketChatRestApi::RestApiRequest::getThreadMessagesDone, this, &RocketChatAccount::slotGetThreadMessagesDone); connect(mRestApi, &RocketChatRestApi::RestApiRequest::getThreadsDone, this, &RocketChatAccount::slotGetThreadsListDone); connect(mRestApi, &RocketChatRestApi::RestApiRequest::getDiscussionsDone, this, &RocketChatAccount::slotGetDiscussionsListDone); connect(mRestApi, &RocketChatRestApi::RestApiRequest::channelGetAllUserMentionsDone, this, [this](const QJsonObject &obj, const QString &roomId) { slotGetListMessagesDone(obj, roomId, ListMessagesModel::ListMessageType::MentionsMessages); }); connect(mRestApi, &RocketChatRestApi::RestApiRequest::getPinnedMessagesDone, this, [this](const QJsonObject &obj, const QString &roomId) { slotGetListMessagesDone(obj, roomId, ListMessagesModel::ListMessageType::PinnedMessages); }); connect(mRestApi, &RocketChatRestApi::RestApiRequest::getSnippetedMessagesDone, this, [this](const QJsonObject &obj, const QString &roomId) { slotGetListMessagesDone(obj, roomId, ListMessagesModel::ListMessageType::SnipperedMessages); }); connect(mRestApi, &RocketChatRestApi::RestApiRequest::getStarredMessagesDone, this, [this](const QJsonObject &obj, const QString &roomId) { slotGetListMessagesDone(obj, roomId, ListMessagesModel::ListMessageType::StarredMessages); }); connect(mRestApi, &RocketChatRestApi::RestApiRequest::getSupportedLanguagesDone, this, &RocketChatAccount::slotGetSupportedLanguagesDone); connect(mRestApi, &RocketChatRestApi::RestApiRequest::usersPresenceDone, this, &RocketChatAccount::slotUsersPresenceDone); connect(mRestApi, &RocketChatRestApi::RestApiRequest::usersAutocompleteDone, this, &RocketChatAccount::slotUserAutoCompleterDone); connect(mRestApi, &RocketChatRestApi::RestApiRequest::roomsAutoCompleteChannelAndPrivateDone, this, &RocketChatAccount::slotRoomsAutoCompleteChannelAndPrivateDone); mRestApi->setServerUrl(mSettings->serverUrl()); mRestApi->setRestApiLogger(mRuqolaLogger); } return mRestApi; } void RocketChatAccount::leaveRoom(const QString &roomId, const QString &channelType) { if (channelType == QLatin1Char('c')) { restApi()->leaveChannel(roomId); } else if (channelType == QLatin1Char('p')) { restApi()->leaveGroups(roomId); } else { qCWarning(RUQOLA_LOG) << " unsupport leave room for type " << channelType; } } void RocketChatAccount::hideRoom(const QString &roomId, const QString &channelType) { restApi()->closeChannel(roomId, channelType); } DDPClient *RocketChatAccount::ddp() { if (!mDdp) { mDdp = new DDPClient(this, this); connect(mDdp, &DDPClient::loginStatusChanged, this, &RocketChatAccount::loginStatusChanged); connect(mDdp, &DDPClient::connectedChanged, this, &RocketChatAccount::connectedChanged); connect(mDdp, &DDPClient::changed, this, &RocketChatAccount::changed); connect(mDdp, &DDPClient::added, this, &RocketChatAccount::added); connect(mDdp, &DDPClient::removed, this, &RocketChatAccount::removed); connect(mDdp, &DDPClient::socketError, this, &RocketChatAccount::socketError); connect(mDdp, &DDPClient::disconnectedByServer, this, &RocketChatAccount::slotDisconnectedByServer); if (mSettings) { mDdp->setServerUrl(mSettings->serverUrl()); } mDdp->start(); } return mDdp; } bool RocketChatAccount::editingMode() const { return mEditingMode; } DDPClient::LoginStatus RocketChatAccount::loginStatus() { if (mDdp) { return ddp()->loginStatus(); } else { return DDPClient::LoggedOut; } } void RocketChatAccount::tryLogin() { qCDebug(RUQOLA_LOG) << "Attempting login" << mSettings->userName() << "on" << mSettings->serverUrl(); delete mDdp; mDdp = nullptr; // This creates a new ddp() object. // DDP will automatically try to connect and login. ddp(); // In the meantime, load cache... mRoomModel->reset(); } void RocketChatAccount::logOut() { mSettings->logout(); mRoomModel->clear(); #ifdef USE_REASTAPI_JOB restApi()->logout(); #else QJsonObject user; user[QStringLiteral("username")] = mSettings->userName(); QJsonObject json; json[QStringLiteral("user")] = user; ddp()->method(QStringLiteral("logout"), QJsonDocument(json)); #endif delete mDdp; mDdp = nullptr; Q_EMIT logoutDone(accountName()); Q_EMIT loginStatusChanged(); qCDebug(RUQOLA_LOG) << "Successfully logged out!"; } void RocketChatAccount::clearAllUnreadMessages() { for (int roomIdx = 0, nRooms = mRoomModel->rowCount(); roomIdx < nRooms; ++roomIdx) { const auto roomModelIndex = mRoomModel->index(roomIdx); const auto roomId = roomModelIndex.data(RoomModel::RoomID).toString(); const bool roomHasAlert = roomModelIndex.data(RoomModel::RoomAlert).toBool(); if (roomHasAlert) { clearUnreadMessages(roomId); } } } void RocketChatAccount::clearUnreadMessages(const QString &roomId) { restApi()->markAsRead(roomId); } void RocketChatAccount::changeFavorite(const QString &roomId, bool checked) { restApi()->markAsFavorite(roomId, checked); } void RocketChatAccount::openChannel(const QString &url, ChannelTypeInfo typeInfo) { RocketChatRestApi::ChannelBaseJob::ChannelInfo info; switch (typeInfo) { case ChannelTypeInfo::RoomId: info.channelInfoType = RocketChatRestApi::ChannelBaseJob::ChannelInfoType::RoomId; break; case ChannelTypeInfo::RoomName: info.channelInfoType = RocketChatRestApi::ChannelBaseJob::ChannelInfoType::RoomName; break; } info.channelInfoIdentifier = url; qCDebug(RUQOLA_LOG) << "opening channel" << url; restApi()->channelJoin(info, QString()); } void RocketChatAccount::setChannelJoinDone(const RocketChatRestApi::ChannelBaseJob::ChannelInfo &channelInfo) { ddp()->subscribeRoomMessage(channelInfo.channelInfoIdentifier); //FIXME room is not added yet... switch (channelInfo.channelInfoType) { case RocketChatRestApi::ChannelBaseJob::ChannelInfoType::Unknown: qCWarning(RUQOLA_LOG) << "setChannelJoinDone : RocketChatRestApi::ChannelBaseJob::ChannelInfoType::Unknown"; break; case RocketChatRestApi::ChannelBaseJob::ChannelInfoType::RoomId: Q_EMIT selectRoomByRoomIdRequested(channelInfo.channelInfoIdentifier); break; case RocketChatRestApi::ChannelBaseJob::ChannelInfoType::RoomName: Q_EMIT selectRoomByRoomNameRequested(channelInfo.channelInfoIdentifier); break; } } void RocketChatAccount::openArchivedRoom(const RocketChatRestApi::ChannelBaseJob::ChannelInfo &channelInfo) { //TODO } void RocketChatAccount::joinJitsiConfCall(const QString &roomId) { qCDebug(RUQOLA_LOG) << " void RocketChatAccount::joinJitsiConfCall(const QString &roomId)"<uniqueId() + roomId).toUtf8(), QCryptographicHash::Md5).toHex()); #if defined(Q_OS_IOS) || defined(Q_OS_ANDROID) const QString scheme = QStringLiteral("org.jitsi.meet://"); #else const QString scheme = QStringLiteral("https://"); #endif const QString url = scheme + mRuqolaServerConfig->jitsiMeetUrl() + QLatin1Char('/') + mRuqolaServerConfig->jitsiMeetPrefix() + hash; const QUrl clickedUrl = QUrl::fromUserInput(url); QDesktopServices::openUrl(clickedUrl); } void RocketChatAccount::eraseRoom(const QString &roomId, const QString &channelType) { if (channelType == QLatin1Char('c')) { restApi()->channelDelete(roomId); } else if (channelType == QLatin1Char('p')) { restApi()->groupDelete(roomId); } else { qCWarning(RUQOLA_LOG) << " unsupport delete for type " << channelType; } } void RocketChatAccount::openDirectChannel(const QString &username) { //Laurent for the moment I didn't find a restapi method for it //TODO verify username vs userId //#ifdef USE_REASTAPI_JOB // restApi()->openDirectMessage(username); //#else qDebug() << "Open direct conversation channel with" << username; ddp()->openDirectChannel(username); //#endif } void RocketChatAccount::createNewChannel(const QString &name, bool readOnly, bool privateRoom, const QString &userNames, bool encryptedRoom, const QString &password, bool broadcast) { //TODO use encrypted room //TODO use broadcast if (!name.trimmed().isEmpty()) { const QStringList lstUsers = userNames.split(QLatin1Char(','), QString::SkipEmptyParts); if (privateRoom) { //TODO add password ??? restApi()->createGroups(name, readOnly, lstUsers); } else { restApi()->createChannels(name, readOnly, lstUsers, password); } } else { qCDebug(RUQOLA_LOG) << "Channel name can't be empty"; } } void RocketChatAccount::joinRoom(const QString &roomId, const QString &joinCode) { RocketChatRestApi::ChannelBaseJob::ChannelInfo info; info.channelInfoType = RocketChatRestApi::ChannelBaseJob::ChannelInfoType::RoomId; info.channelInfoIdentifier = roomId; restApi()->channelJoin(info, joinCode); } void RocketChatAccount::channelAndPrivateAutocomplete(const QString &pattern) { if (pattern.isEmpty()) { searchChannelModel()->clear(); } else { //Use restapi //Avoid to show own user #ifdef USE_REASTAPI_JOB restApi()->searchRoomUser(pattern); #else const QString addUserNameToException = userName(); ddp()->channelAndPrivateAutocomplete(pattern, addUserNameToException); #endif } } void RocketChatAccount::listEmojiCustom() { restApi()->listEmojiCustom(); } void RocketChatAccount::setDefaultStatus(User::PresenceStatus status, const QString &messageStatus) { #ifdef USE_REASTAPI_JOB RocketChatRestApi::SetStatusJob::StatusType type = RocketChatRestApi::SetStatusJob::Unknown; switch (status) { case User::PresenceStatus::PresenceOnline: type = RocketChatRestApi::SetStatusJob::OnLine; break; case User::PresenceStatus::PresenceBusy: type = RocketChatRestApi::SetStatusJob::Busy; break; case User::PresenceStatus::PresenceAway: type = RocketChatRestApi::SetStatusJob::Away; break; case User::PresenceStatus::PresenceOffline: type = RocketChatRestApi::SetStatusJob::Offline; break; case User::PresenceStatus::Unknown: type = RocketChatRestApi::SetStatusJob::Unknown; break; } restApi()->setUserStatus(userID(), type, messageStatus); #else Q_UNUSED(messageStatus); ddp()->setDefaultStatus(status); #endif } void RocketChatAccount::changeDefaultStatus(int index, const QString &messageStatus) { setDefaultStatus(mStatusModel->status(index), messageStatus); } void RocketChatAccount::loadEmoji(const QJsonObject &obj) { mEmojiManager->loadCustomEmoji(obj); } void RocketChatAccount::deleteMessage(const QString &messageId, const QString &roomId) { restApi()->deleteMessage(roomId, messageId); } void RocketChatAccount::insertCompleterUsers() { userCompleterModel()->insertUsers(rocketChatBackend()->users()); } void RocketChatAccount::userAutocomplete(const QString &searchText, const QString &exception) { userCompleterModel()->clear(); if (mRuqolaServerConfig->hasAtLeastVersion(2, 4, 0)) { if (!searchText.isEmpty()) { RocketChatRestApi::UsersAutocompleteJob::UsersAutocompleterInfo info; info.pattern = searchText; info.exception = exception; restApi()->usersAutocomplete(info); } } else { //Clear before to create new search rocketChatBackend()->clearUsersList(); if (!searchText.isEmpty()) { //Avoid to show own user QString addUserNameToException; if (exception.isEmpty()) { addUserNameToException = userName(); } else { addUserNameToException = exception + QLatin1Char(',') + userName(); } ddp()->userAutocomplete(searchText, addUserNameToException); } } } void RocketChatAccount::membersInRoom(const QString &roomId, const QString &roomType) { restApi()->membersInRoom(roomId, roomType); } void RocketChatAccount::parseUsersForRooms(const QJsonObject &obj, const RocketChatRestApi::ChannelBaseJob::ChannelInfo &channelInfo) { //FIXME channelInfo const QString channelInfoIdentifier = channelInfo.channelInfoIdentifier; UsersForRoomModel *usersModelForRoom = roomModel()->usersModelForRoom(channelInfoIdentifier); if (usersModelForRoom) { usersModelForRoom->parseUsersForRooms(obj, mUserModel, true); } else { qCWarning(RUQOLA_LOG) << " Impossible to find room " << channelInfoIdentifier; } } void RocketChatAccount::loadAutoCompleteChannel(const QJsonObject &obj) { mSearchChannelModel->parseChannels(obj); } void RocketChatAccount::roomFiles(const QString &roomId, const QString &channelType) { mFilesModelForRoom->initialize(); restApi()->filesInRoom(roomId, channelType); } MessageModel *RocketChatAccount::threadMessageModel() const { return mThreadMessageModel; } ThreadsModel *RocketChatAccount::threadsModel() const { return mThreadsModel; } DiscussionsModel *RocketChatAccount::discussionsModel() const { return mDiscussionsModel; } FilesForRoomModel *RocketChatAccount::filesModelForRoom() const { return mFilesModelForRoom; } -EmoticonModel *RocketChatAccount::emoticonModel() const +EmoticonFilterModel *RocketChatAccount::emoticonFilterModel() const { return mEmoticonModel; } ReceiveTypingNotificationManager *RocketChatAccount::receiveTypingNotificationManager() const { return mReceiveTypingNotificationManager; } void RocketChatAccount::slotChannelRolesDone(const QJsonObject &obj, const RocketChatRestApi::ChannelBaseJob::ChannelInfo &channelInfo) { Room *room = mRoomModel->findRoom(channelInfo.channelInfoIdentifier); if (room) { Roles r; r.parseRole(obj); room->setRolesForRooms(r); } else { qCWarning(RUQOLA_LOG) << " Impossible to find room " << channelInfo.channelInfoIdentifier; } } void RocketChatAccount::slotGetThreadMessagesDone(const QJsonObject &obj, const QString &threadMessageId) { if (mThreadMessageModel->threadMessageId() != threadMessageId) { mThreadMessageModel->setThreadMessageId(threadMessageId); mThreadMessageModel->parseThreadMessages(obj); } else { mThreadMessageModel->loadMoreThreadMessages(obj); } } void RocketChatAccount::slotGetDiscussionsListDone(const QJsonObject &obj, const QString &roomId) { if (mDiscussionsModel->roomId() != roomId) { mDiscussionsModel->parseDiscussions(obj, roomId); } else { mDiscussionsModel->addMoreDiscussions(obj); } mDiscussionsModel->setLoadMoreDiscussionsInProgress(false); } void RocketChatAccount::slotGetListMessagesDone(const QJsonObject &obj, const QString &roomId, ListMessagesModel::ListMessageType type) { if (mListMessageModel->roomId() != roomId || mListMessageModel->listMessageType() != type) { mListMessageModel->setRoomId(roomId); mListMessageModel->setListMessageType(type); mListMessageModel->parseListMessages(obj); } else { mListMessageModel->loadMoreListMessages(obj); } mListMessageModel->setLoadMoreListMessagesInProgress(false); } void RocketChatAccount::slotUserAutoCompleterDone(const QJsonObject &obj) { const QVector users = User::parseUsersList(obj); mUserCompleterModel->insertUsers(users); } void RocketChatAccount::slotRoomsAutoCompleteChannelAndPrivateDone(const QJsonObject &obj) { //TODO } AccountRoomSettings *RocketChatAccount::accountRoomSettings() const { return mAccountRoomSettings; } ListMessagesModelFilterProxyModel *RocketChatAccount::listMessagesFilterProxyModel() const { return mListMessagesFilterProxyModel; } ListMessagesModel *RocketChatAccount::listMessageModel() const { return mListMessageModel; } void RocketChatAccount::slotGetThreadsListDone(const QJsonObject &obj, const QString &roomId) { if (mThreadsModel->roomId() != roomId) { mThreadsModel->parseThreads(obj, roomId); } else { mThreadsModel->addMoreThreads(obj); } mThreadsModel->setLoadMoreThreadsInProgress(false); } void RocketChatAccount::slotSplotLightDone(const QJsonObject &obj) { //qDebug() << " void RocketChatAccount::slotSplotLightDone(const QJsonObject &obj)"<roomId() != channelInfo.channelInfoIdentifier) { mFilesModelForRoom->parseFileAttachments(obj, channelInfo.channelInfoIdentifier); } else { mFilesModelForRoom->addMoreFileAttachments(obj); } mFilesModelForRoom->setLoadMoreFilesInProgress(false); } void RocketChatAccount::loadMoreUsersInRoom(const QString &roomId, const QString &channelType) { UsersForRoomModel *usersModelForRoom = roomModel()->usersModelForRoom(roomId); const int offset = usersModelForRoom->usersCount(); if (offset < usersModelForRoom->total()) { restApi()->membersInRoom(roomId, channelType, offset, qMin(50, usersModelForRoom->total() - offset)); } } void RocketChatAccount::getMentionsMessages(const QString &roomId) { mListMessageModel->clear(); mListMessageModel->setRoomId(roomId); restApi()->channelGetAllUserMentions(roomId); } void RocketChatAccount::getPinnedMessages(const QString &roomId) { if (hasPinnedMessagesSupport()) { mListMessageModel->clear(); mListMessageModel->setRoomId(roomId); restApi()->getPinnedMessages(roomId); } else { qCWarning(RUQOLA_LOG) << " RocketChatAccount::getPinnedMessages is not supported before server 2.0.0"; } } bool RocketChatAccount::hasPinnedMessagesSupport() const { return mRuqolaServerConfig->hasAtLeastVersion(1, 4, 0); } bool RocketChatAccount::hasStarredMessagesSupport() const { return mRuqolaServerConfig->hasAtLeastVersion(2, 3, 0); } void RocketChatAccount::getStarredMessages(const QString &roomId) { if (hasStarredMessagesSupport()) { mListMessageModel->clear(); mListMessageModel->setRoomId(roomId); restApi()->getStarredMessages(roomId); } else { qCWarning(RUQOLA_LOG) << " RocketChatAccount::getStarredMessages is not supported before server 2.3.0"; } } bool RocketChatAccount::hasInviteUserSupport() const { return mRuqolaServerConfig->hasAtLeastVersion(2, 4, 0); } bool RocketChatAccount::hasSnippetedMessagesSupport() const { return mRuqolaServerConfig->hasAtLeastVersion(2, 3, 0); } void RocketChatAccount::getSnippetedMessages(const QString &roomId) { if (hasSnippetedMessagesSupport()) { mListMessageModel->clear(); mListMessageModel->setRoomId(roomId); restApi()->getSnippetedMessages(roomId); } else { qCWarning(RUQOLA_LOG) << " RocketChatAccount::getSnippetedMessages is not supported before server 2.3.0"; } } void RocketChatAccount::loadMoreFileAttachments(const QString &roomId, const QString &channelType) { if (!mFilesModelForRoom->loadMoreFilesInProgress()) { const int offset = mFilesModelForRoom->fileAttachments()->filesCount(); if (offset < mFilesModelForRoom->fileAttachments()->total()) { mFilesModelForRoom->setLoadMoreFilesInProgress(true); restApi()->filesInRoom(roomId, channelType, offset, qMin(50, mFilesModelForRoom->fileAttachments()->total() - offset)); } } } void RocketChatAccount::loadMoreDiscussions(const QString &roomId) { if (!mDiscussionsModel->loadMoreDiscussionsInProgress()) { const int offset = mDiscussionsModel->discussions()->discussionsCount(); if (offset < mDiscussionsModel->discussions()->total()) { mDiscussionsModel->setLoadMoreDiscussionsInProgress(true); restApi()->getDiscussions(roomId, offset, qMin(50, mDiscussionsModel->discussions()->total() - offset)); } } } void RocketChatAccount::updateThreadMessageList(const Message &m) { if (mThreadMessageModel->threadMessageId() == m.threadMessageId()) { mThreadMessageModel->addMessage(m); } } void RocketChatAccount::loadMoreThreads(const QString &roomId) { if (!mThreadsModel->loadMoreThreadsInProgress()) { const int offset = mThreadsModel->threads()->threadsCount(); if (offset < mThreadsModel->threads()->total()) { restApi()->getThreadsList(roomId, offset, qMin(50, mThreadsModel->threads()->total() - offset)); } } } void RocketChatAccount::getListMessages(const QString &roomId, ListMessagesModel::ListMessageType type) { mListMessageModel->setListMessageType(type); switch (type) { case ListMessagesModel::Unknown: qCWarning(RUQOLA_LOG) << " Error when using getListMessages"; break; case ListMessagesModel::StarredMessages: if (hasStarredMessagesSupport()) { getStarredMessages(roomId); } break; case ListMessagesModel::SnipperedMessages: if (hasSnippetedMessagesSupport()) { getSnippetedMessages(roomId); } break; case ListMessagesModel::PinnedMessages: getPinnedMessages(roomId); break; case ListMessagesModel::MentionsMessages: getMentionsMessages(roomId); break; } } QUrl RocketChatAccount::urlForLink(const QString &link) const { return mCache->urlForLink(link); } void RocketChatAccount::loadMoreListMessages(const QString &roomId) { if (!mListMessageModel->loadMoreListMessagesInProgress()) { const int offset = mListMessageModel->rowCount(); if (offset < mListMessageModel->total()) { switch (mListMessageModel->listMessageType()) { case ListMessagesModel::Unknown: qCWarning(RUQOLA_LOG) << " Error when using loadMoreListMessages"; break; case ListMessagesModel::StarredMessages: if (hasStarredMessagesSupport()) { restApi()->getStarredMessages(roomId, offset, qMin(50, mListMessageModel->total() - offset)); } break; case ListMessagesModel::SnipperedMessages: if (hasSnippetedMessagesSupport()) { restApi()->getSnippetedMessages(roomId, offset, qMin(50, mListMessageModel->total() - offset)); } break; case ListMessagesModel::PinnedMessages: restApi()->getPinnedMessages(roomId, offset, qMin(50, mListMessageModel->total() - offset)); break; case ListMessagesModel::MentionsMessages: restApi()->channelGetAllUserMentions(roomId, offset, qMin(50, mListMessageModel->total() - offset)); break; } } } } void RocketChatAccount::loadThreadMessagesHistory(const QString &threadMessageId) { restApi()->getThreadMessages(threadMessageId); } void RocketChatAccount::createJitsiConfCall(const QString &roomId) { //TODO use restapi ddp()->createJitsiConfCall(roomId); joinJitsiConfCall(roomId); } void RocketChatAccount::addUserToRoom(const QString &userId, const QString &roomId, const QString &channelType) { if (channelType == QLatin1Char('c')) { restApi()->addUserInChannel(roomId, userId); } else if (channelType == QLatin1Char('p')) { restApi()->addUserInGroup(roomId, userId); } } void RocketChatAccount::clearSearchModel() { mSearchMessageModel->clear(); } void RocketChatAccount::messageSearch(const QString &pattern, const QString &rid) { if (pattern.isEmpty()) { clearSearchModel(); } else { restApi()->searchMessages(rid, pattern); } } void RocketChatAccount::slotSearchMessages(const QJsonObject &obj) { mSearchMessageModel->parse(obj); } void RocketChatAccount::starMessage(const QString &messageId, bool starred) { restApi()->starMessage(messageId, starred); } void RocketChatAccount::pinMessage(const QString &messageId, bool pinned) { restApi()->pinMessage(messageId, pinned); } void RocketChatAccount::uploadFile(const QString &roomId, const QString &description, const QString &messageText, const QUrl &fileUrl) { restApi()->uploadFile(roomId, description, messageText, fileUrl); } void RocketChatAccount::changeChannelSettings(const QString &roomId, RocketChatAccount::RoomInfoType infoType, const QVariant &newValue, const QString &channelType) { switch (infoType) { case Announcement: if (channelType == QLatin1Char('c')) { restApi()->changeChannelAnnouncement(roomId, newValue.toString()); } else if (channelType == QLatin1Char('p')) { restApi()->changeGroupsAnnouncement(roomId, newValue.toString()); } else { qCWarning(RUQOLA_LOG) << " unsupport change announcement for type " << channelType; } break; case Description: if (channelType == QLatin1Char('c')) { restApi()->changeChannelDescription(roomId, newValue.toString()); } else if (channelType == QLatin1Char('p')) { restApi()->changeGroupsDescription(roomId, newValue.toString()); } else { qCWarning(RUQOLA_LOG) << " unsupport change description for type " << channelType; } break; case Name: if (channelType == QLatin1Char('c')) { restApi()->changeChannelName(roomId, newValue.toString()); } else if (channelType == QLatin1Char('p')) { restApi()->changeGroupName(roomId, newValue.toString()); } else { qCWarning(RUQOLA_LOG) << " unsupport change name for type " << channelType; } break; case Topic: if (channelType == QLatin1Char('c')) { restApi()->changeChannelTopic(roomId, newValue.toString()); } else if (channelType == QLatin1Char('p')) { restApi()->changeGroupsTopic(roomId, newValue.toString()); } else { //TODO : change topic in direct channel qCWarning(RUQOLA_LOG) << " unsupport change topic for type " << channelType; } break; case ReadOnly: if (channelType == QLatin1Char('c')) { restApi()->changeChannelReadOnly(roomId, newValue.toBool()); } else if (channelType == QLatin1Char('p')) { restApi()->changeGroupsReadOnly(roomId, newValue.toBool()); } else { qCWarning(RUQOLA_LOG) << " unsupport change readonly for type " << channelType; } break; case Archive: if (channelType == QLatin1Char('c')) { restApi()->archiveChannel(roomId, newValue.toBool()); } else if (channelType == QLatin1Char('p')) { restApi()->archiveGroups(roomId, newValue.toBool()); } else { qCWarning(RUQOLA_LOG) << " unsupport archiving for type " << channelType; } break; case RoomType: if (channelType == QLatin1Char('c')) { restApi()->setChannelType(roomId, newValue.toBool()); } else if (channelType == QLatin1Char('p')) { restApi()->setGroupType(roomId, newValue.toBool()); } else { qCWarning(RUQOLA_LOG) << " unsupport roomtype for type " << channelType; } break; case Encrypted: if (channelType == QLatin1Char('c')) { restApi()->changeChannelEncrypted(roomId, newValue.toBool()); } else if (channelType == QLatin1Char('p')) { restApi()->changeGroupsEncrypted(roomId, newValue.toBool()); } else { qCWarning(RUQOLA_LOG) << " unsupport encrypted mode for type " << channelType; } break; case Password: //FIXME channel type ??? //restApi()->setJoinCodeChannel(roomId, newValue.toString()); break; } } void RocketChatAccount::reportMessage(const QString &messageId, const QString &message) { restApi()->reportMessage(messageId, message); } void RocketChatAccount::getThreadMessages(const QString &threadMessageId) { mThreadMessageModel->clear(); restApi()->getThreadMessages(threadMessageId); } void RocketChatAccount::changeNotificationsSettings(const QString &roomId, RocketChatAccount::NotificationOptionsType notificationsType, const QVariant &newValue) { switch (notificationsType) { case DisableNotifications: restApi()->disableNotifications(roomId, newValue.toBool()); break; case HideUnreadStatus: restApi()->hideUnreadStatus(roomId, newValue.toBool()); break; case AudioNotifications: restApi()->audioNotifications(roomId, newValue.toString()); break; case DesktopNotifications: restApi()->desktopNotifications(roomId, newValue.toString()); break; case EmailNotifications: restApi()->emailNotifications(roomId, newValue.toString()); break; case MobilePushNotifications: restApi()->mobilePushNotifications(roomId, newValue.toString()); break; case UnreadAlert: restApi()->unreadAlert(roomId, newValue.toString()); break; case MuteGroupMentions: restApi()->muteGroupMentions(roomId, newValue.toBool()); break; case DesktopDurationNotifications: restApi()->desktopDurationNotifications(roomId, newValue.toInt()); break; case DesktopSoundNotifications: restApi()->desktopSoundNotifications(roomId, newValue.toString()); break; } } void RocketChatAccount::parsePublicSettings(const QJsonObject &obj) { QJsonArray configs = obj.value(QLatin1String("result")).toArray(); for (QJsonValueRef currentConfig : configs) { QJsonObject currentConfObject = currentConfig.toObject(); const QString id = currentConfObject[QStringLiteral("_id")].toString(); const QVariant value = currentConfObject[QStringLiteral("value")].toVariant(); if (id == QLatin1String("uniqueID")) { mRuqolaServerConfig->setUniqueId(value.toString()); } else if (id == QLatin1String("Jitsi_Enabled")) { mRuqolaServerConfig->setJitsiEnabled(value.toBool()); } else if (id == QLatin1String("Jitsi_Domain")) { mRuqolaServerConfig->setJitsiMeetUrl(value.toString()); } else if (id == QLatin1String("Jitsi_URL_Room_Prefix")) { mRuqolaServerConfig->setJitsiMeetPrefix(value.toString()); } else if (id == QLatin1String("FileUpload_Storage_Type")) { mRuqolaServerConfig->setFileUploadStorageType(value.toString()); } else if (id == QLatin1String("Message_AllowEditing")) { mRuqolaServerConfig->setAllowMessageEditing(value.toBool()); } else if (id == QLatin1String("Message_AllowEditing_BlockEditInMinutes")) { mRuqolaServerConfig->setBlockEditingMessageInMinutes(value.toInt()); } else if (id == QLatin1String("OTR_Enable")) { mRuqolaServerConfig->setOtrEnabled(value.toBool()); } else if (id.contains(QRegularExpression(QStringLiteral("^Accounts_OAuth_\\w+")))) { if (value.toBool()) { mRuqolaServerConfig->addOauthService(id); } } else if (id == QLatin1String("Site_Url")) { mRuqolaServerConfig->setSiteUrl(value.toString()); } else if (id == QLatin1String("Site_Name")) { mRuqolaServerConfig->setSiteName(value.toString()); } else if (id == QLatin1String("E2E_Enable")) { mRuqolaServerConfig->setEncryptionEnabled(value.toBool()); } else if (id == QLatin1String("Message_AllowPinning")) { mRuqolaServerConfig->setAllowMessagePinningEnabled(value.toBool()); } else if (id == QLatin1String("Message_AllowSnippeting")) { mRuqolaServerConfig->setAllowMessageSnippetingEnabled(value.toBool()); } else if (id == QLatin1String("Message_AllowStarring")) { mRuqolaServerConfig->setAllowMessageStarringEnabled(value.toBool()); } else if (id == QLatin1String("Message_AllowDeleting")) { mRuqolaServerConfig->setAllowMessageDeletingEnabled(value.toBool()); } else if (id == QLatin1String("Threads_enabled")) { mRuqolaServerConfig->setThreadsEnabled(value.toBool()); } else if (id == QLatin1String("Discussion_enabled")) { mRuqolaServerConfig->setDiscussionEnabled(value.toBool()); } else if (id == QLatin1String("AutoTranslate_Enabled")) { mRuqolaServerConfig->setAutoTranslateEnabled(value.toBool()); } else if (id == QLatin1String("AutoTranslate_GoogleAPIKey")) { mRuqolaServerConfig->setAutoTranslateGoogleKey(value.toString()); } else { qCDebug(RUQOLA_LOG) << "Other public settings id " << id << value; } //TODO add Accounts_AllowUserStatusMessageChange when we will have a RestAPI method for it. } fillOauthModel(); Q_EMIT publicSettingChanged(); } void RocketChatAccount::fillOauthModel() { QVector fillModel; for (int i = 0, total = mLstInfos.count(); i < total; ++i) { if (mRuqolaServerConfig->canShowOauthService(mLstInfos.at(i).oauthType())) { fillModel.append(mLstInfos.at(i)); } } mLoginMethodModel->setAuthenticationInfos(fillModel); } void RocketChatAccount::changeDefaultAuthentication(int index) { setDefaultAuthentication(mLoginMethodModel->loginType(index)); } void RocketChatAccount::setDefaultAuthentication(AuthenticationManager::OauthType type) { PluginAuthenticationInterface *interface = mLstPluginAuthenticationInterface.value(type); if (interface) { mDefaultAuthenticationInterface = interface; } else { qCWarning(RUQOLA_LOG) << "No interface defined for " << type; } } SearchMessageFilterProxyModel *RocketChatAccount::searchMessageFilterProxyModel() const { return mSearchMessageFilterProxyModel; } SearchMessageModel *RocketChatAccount::searchMessageModel() const { return mSearchMessageModel; } void RocketChatAccount::initializeAuthenticationPlugins() { //TODO change it when we change server //Clean up at the end. const QVector lstPlugins = AuthenticationManager::self()->pluginsList(); qCDebug(RUQOLA_LOG) <<" void RocketChatAccount::initializeAuthenticationPlugins()" << lstPlugins.count(); if (lstPlugins.isEmpty()) { qCWarning(RUQOLA_LOG) <<" No plugins loaded. Please verify your installation."; } mLstPluginAuthenticationInterface.clear(); mLstInfos.clear(); for (PluginAuthentication *abstractPlugin : lstPlugins) { AuthenticationInfo info; info.setIconName(abstractPlugin->iconName()); info.setName(abstractPlugin->name()); info.setOauthType(abstractPlugin->type()); if (info.isValid()) { mLstInfos.append(info); } PluginAuthenticationInterface *interface = abstractPlugin->createInterface(this); interface->setAccount(this); mRuqolaServerConfig->addRuqolaAuthenticationSupport(abstractPlugin->type()); mLstPluginAuthenticationInterface.insert(abstractPlugin->type(), interface); //For the moment initialize default interface if (abstractPlugin->type() == AuthenticationManager::OauthType::Password) { mDefaultAuthenticationInterface = interface; } qCDebug(RUQOLA_LOG) << " plugin type " << abstractPlugin->type(); } //TODO fill ??? or store QVector } PluginAuthenticationInterface *RocketChatAccount::defaultAuthenticationInterface() const { return mDefaultAuthenticationInterface; } LoginMethodModel *RocketChatAccount::loginMethodModel() const { return mLoginMethodModel; } QString RocketChatAccount::authToken() const { return settings()->authToken(); } QString RocketChatAccount::userName() const { return settings()->userName(); } void RocketChatAccount::setAccountName(const QString &accountname) { //Initialize new account room //qDebug() << "void RocketChatAccount::setAccountName(const QString &servername)"<accountConfigFileName(accountname)); settings()->setAccountName(accountname); } QString RocketChatAccount::accountName() const { return settings()->accountName(); } QString RocketChatAccount::userID() const { return settings()->userId(); } QString RocketChatAccount::password() const { return settings()->password(); } QString RocketChatAccount::twoFactorAuthenticationCode() const { return settings()->twoFactorAuthenticationCode(); } void RocketChatAccount::setAuthToken(const QString &token) { settings()->setAuthToken(token); } void RocketChatAccount::setPassword(const QString &password) { settings()->setPassword(password); } void RocketChatAccount::setTwoFactorAuthenticationCode(const QString &twoFactorAuthenticationCode) { settings()->setTwoFactorAuthenticationCode(twoFactorAuthenticationCode); } void RocketChatAccount::setAccountEnabled(bool enabled) { settings()->setAccountEnabled(enabled); } void RocketChatAccount::setUserName(const QString &username) { settings()->setUserName(username); } bool RocketChatAccount::accountEnabled() const { return settings()->accountEnabled(); } void RocketChatAccount::setUserID(const QString &userID) { settings()->setUserId(userID); } QString RocketChatAccount::serverUrl() const { return settings()->serverUrl(); } void RocketChatAccount::setServerUrl(const QString &serverURL) { settings()->setServerUrl(serverURL); restApi()->setServerUrl(serverURL); mEmojiManager->setServerUrl(serverURL); } QString RocketChatAccount::recordingVideoPath() const { return mCache->recordingVideoPath(accountName()); } QString RocketChatAccount::recordingImagePath() const { return mCache->recordingImagePath(accountName()); } void RocketChatAccount::downloadFile(const QString &downloadFileUrl, const QUrl &localFile) { mCache->downloadFile(downloadFileUrl, localFile, false); } QUrl RocketChatAccount::attachmentUrl(const QString &url) { return mCache->attachmentUrl(url); } void RocketChatAccount::loadHistory(const QString &roomID, const QString &channelType, bool initial) { //TODO port to restapi Q_UNUSED(channelType); MessageModel *roomModel = messageModelForRoom(roomID); if (roomModel) { //TODO add autotest for it ! QJsonArray params; params.append(QJsonValue(roomID)); // Load history const qint64 endDateTime = roomModel->lastTimestamp(); if (initial || roomModel->isEmpty()) { params.append(QJsonValue(QJsonValue::Null)); params.append(QJsonValue(50)); // Max number of messages to load; QJsonObject dateObject; //qDebug() << "roomModel->lastTimestamp()" << roomModel->lastTimestamp() << " ROOMID " << roomID; dateObject[QStringLiteral("$date")] = QJsonValue(endDateTime); params.append(dateObject); } else { const qint64 startDateTime = roomModel->generateNewStartTimeStamp(endDateTime); QJsonObject dateObjectEnd; dateObjectEnd[QStringLiteral("$date")] = QJsonValue(endDateTime); //qDebug() << " QDATE TIME END" << QDateTime::fromMSecsSinceEpoch(endDateTime) << " START " << QDateTime::fromMSecsSinceEpoch(startDateTime) << " ROOMID" << roomID; params.append(dateObjectEnd); params.append(QJsonValue(50)); // Max number of messages to load; QJsonObject dateObjectStart; //qDebug() << "roomModel->lastTimestamp()" << roomModel->lastTimestamp() << " ROOMID " << roomID; dateObjectStart[QStringLiteral("$date")] = QJsonValue(startDateTime); params.append(dateObjectStart); } ddp()->loadHistory(params); } else { qCWarning(RUQOLA_LOG) << "Room is not found " << roomID; } } void RocketChatAccount::setServerVersion(const QString &version) { qCDebug(RUQOLA_LOG) << " void RocketChatAccount::setServerVersion(const QString &version)" << version; mRuqolaServerConfig->setServerVersion(version); Q_EMIT serverVersionChanged(); } bool RocketChatAccount::needAdaptNewSubscriptionRC60() const { return mRuqolaServerConfig->needAdaptNewSubscriptionRC60(); } bool RocketChatAccount::otrEnabled() const { return mRuqolaServerConfig->otrEnabled(); } bool RocketChatAccount::encryptedEnabled() const { return mRuqolaServerConfig->encryptionEnabled(); } bool RocketChatAccount::allowMessagePinningEnabled() const { return mRuqolaServerConfig->allowMessagePinningEnabled(); } bool RocketChatAccount::allowMessageSnippetingEnabled() const { return mRuqolaServerConfig->allowMessageSnippetingEnabled(); } bool RocketChatAccount::allowMessageStarringEnabled() const { return mRuqolaServerConfig->allowMessageStarringEnabled(); } bool RocketChatAccount::allowMessageDeletingEnabled() const { return mRuqolaServerConfig->allowMessageDeletingEnabled(); } bool RocketChatAccount::threadsEnabled() const { return mRuqolaServerConfig->threadsEnabled(); } bool RocketChatAccount::autoTranslateEnabled() const { return mRuqolaServerConfig->autoTranslateEnabled(); } bool RocketChatAccount::discussionEnabled() const { return mRuqolaServerConfig->discussionEnabled(); } QString RocketChatAccount::serverVersionStr() const { return mRuqolaServerConfig->serverVersionStr(); } ServerConfigInfo *RocketChatAccount::serverConfigInfo() const { return mServerConfigInfo; } bool RocketChatAccount::jitsiEnabled() const { return mRuqolaServerConfig->jitsiEnabled(); } void RocketChatAccount::groupInfo(const QString &roomId) { restApi()->groupInfo(roomId); } void RocketChatAccount::switchEditingMode(bool b) { if (mEditingMode != b) { mEditingMode = b; Q_EMIT editingModeChanged(); } } void RocketChatAccount::setSortUnreadOnTop(bool b) { if (settings()->setShowUnreadOnTop(b)) { mRoomFilterProxyModel->invalidate(); Q_EMIT sortUnreadOnTopChanged(); } } bool RocketChatAccount::sortUnreadOnTop() const { return settings()->showUnreadOnTop(); } void RocketChatAccount::kickUser(const QString &roomId, const QString &userId, const QString &channelType) { if (channelType == QLatin1Char('c')) { restApi()->channelKick(roomId, userId); } else if (channelType == QLatin1Char('p')) { restApi()->groupKick(roomId, userId); } else { qCWarning(RUQOLA_LOG) << " unsupport kickUser room for type " << channelType; } } void RocketChatAccount::rolesInRoom(const QString &roomId, const QString &channelType) { if (channelType == QLatin1Char('c')) { restApi()->getChannelRoles(roomId); } else if (channelType == QLatin1Char('p')) { restApi()->getGroupRoles(roomId); } else if (channelType == QLatin1Char('d')) { //No a problem here. } else { qCWarning(RUQOLA_LOG) << " unsupport get roles room for type " << channelType; } } void RocketChatAccount::switchingToRoom(const QString &roomID) { clearTypingNotification(); checkInitializedRoom(roomID); } void RocketChatAccount::changeRoles(const QString &roomId, const QString &userId, const QString &channelType, RocketChatAccount::RoleType roleType) { if (channelType == QLatin1Char('c')) { switch (roleType) { case RocketChatAccount::AddOwner: restApi()->channelAddOwner(roomId, userId); break; case RocketChatAccount::AddLeader: restApi()->channelAddLeader(roomId, userId); break; case RocketChatAccount::AddModerator: restApi()->channelAddModerator(roomId, userId); break; case RocketChatAccount::RemoveOwner: restApi()->channelRemoveOwner(roomId, userId); break; case RocketChatAccount::RemoveLeader: restApi()->channelRemoveLeader(roomId, userId); break; case RocketChatAccount::RemoveModerator: restApi()->channelRemoveModerator(roomId, userId); break; } } else if (channelType == QLatin1Char('p')) { switch (roleType) { case RocketChatAccount::AddOwner: restApi()->groupAddOwner(roomId, userId); break; case RocketChatAccount::AddLeader: restApi()->groupAddLeader(roomId, userId); break; case RocketChatAccount::AddModerator: restApi()->groupAddModerator(roomId, userId); break; case RocketChatAccount::RemoveOwner: restApi()->groupRemoveOwner(roomId, userId); break; case RocketChatAccount::RemoveLeader: restApi()->groupRemoveLeader(roomId, userId); break; case RocketChatAccount::RemoveModerator: restApi()->groupRemoveModerator(roomId, userId); break; } } else { qCWarning(RUQOLA_LOG) << " unsupport changeRoles room for type " << channelType; } } void RocketChatAccount::channelInfo(const QString &roomId) { restApi()->channelInfo(roomId); } bool RocketChatAccount::allowEditingMessages() const { return mRuqolaServerConfig->allowMessageEditing(); } void RocketChatAccount::parseOtr(const QJsonArray &contents) { qCWarning(RUQOLA_LOG) << " NOT IMPLEMENTED YET"; //const Otr t = mOtrManager->parseOtr(contents); //qDebug() << " void RocketChatAccount::parseOtr(const QJsonArray &contents)"<avatarUrlFromCacheOnly(sender); //qDebug() << " iconFileName"<inputChannelAutocomplete(pattern, exceptions); break; case InputTextManager::CompletionForType::User: ddp()->inputUserAutocomplete(pattern, exceptions); break; } } AutotranslateLanguagesModel *RocketChatAccount::autoTranslateLanguagesModel() const { return mAutoTranslateLanguagesModel; } void RocketChatAccount::updateUser(const QJsonObject &object) { mUserModel->updateUser(object); } void RocketChatAccount::userStatusChanged(const User &user) { if (user.userId() == userID()) { const User::PresenceStatus status = Utils::presenceStatusFromString(user.status()); statusModel()->setCurrentPresenceStatus(status); Q_EMIT userStatusUpdated(status); } mRoomModel->userStatusChanged(user); } void RocketChatAccount::ignoreUser(const QString &rid, const QString &userId, bool ignore) { restApi()->ignoreUser(rid, userId, ignore); } void RocketChatAccount::blockUser(const QString &rid, bool block) { //TODO use restapi if (rid.isEmpty()) { qCWarning(RUQOLA_LOG) << " void RocketChatAccount::blockUser EMPTY rid ! block " << block; } else { //qDebug() << " void RocketChatAccount::blockUser userId " << userId << " block " << block << " rid " << rid << " own userdId" << userID(); const QString userId = Utils::userIdFromDirectChannel(rid, userID()); if (block) { ddp()->blockUser(rid, userId); } else { ddp()->unBlockUser(rid, userId); } } } void RocketChatAccount::clearTypingNotification() { mReceiveTypingNotificationManager->clearTypingNotification(); } void RocketChatAccount::checkInitializedRoom(const QString &roomId) { Room *r = mRoomModel->findRoom(roomId); if (r && !r->wasInitialized()) { r->setWasInitialized(true); ddp()->subscribeRoomMessage(roomId); if (!r->archived()) { membersInRoom(r->roomId(), r->channelType()); rolesInRoom(r->roomId(), r->channelType()); } loadHistory(r->roomId(), QString(), true /*initial loading*/); } else if (!r) { qWarning() << " Room " << roomId << " was no found! Need to open it"; //openDirectChannel(roomId); } QMetaObject::invokeMethod(this, &RocketChatAccount::switchedRooms, Qt::QueuedConnection); } void RocketChatAccount::openDocumentation() { QDesktopServices::openUrl(QUrl(QStringLiteral("help:/"))); } void RocketChatAccount::rolesChanged(const QJsonArray &contents) { for (int i = 0; i < contents.count(); ++i) { const QJsonObject obj = contents.at(i).toObject(); const QString scope = obj[QLatin1String("scope")].toString(); Room *room = mRoomModel->findRoom(scope); if (room) { room->updateRoles(obj); } } } void RocketChatAccount::createDiscussion(const QString &parentRoomId, const QString &discussionName, const QString &replyMessage, const QString &messageId, const QStringList &users) { restApi()->createDiscussion(parentRoomId, discussionName, replyMessage, messageId, users); } void RocketChatAccount::threadsInRoom(const QString &roomId) { mThreadsModel->initialize(); restApi()->getThreadsList(roomId); } void RocketChatAccount::discussionsInRoom(const QString &roomId) { mDiscussionsModel->initialize(); restApi()->getDiscussions(roomId); } void RocketChatAccount::followMessage(const QString &messageId, bool follow) { if (follow) { restApi()->followMessage(messageId); } else { restApi()->unFollowMessage(messageId); } } void RocketChatAccount::getSupportedLanguages() { if (mRuqolaServerConfig->hasAtLeastVersion(1, 99, 0) && autoTranslateEnabled()) { restApi()->getSupportedLanguagesMessages(); } else { qCWarning(RUQOLA_LOG) << " RocketChatAccount::getSupportedLanguages is not supported before server 2.0.0"; } } void RocketChatAccount::slotGetSupportedLanguagesDone(const QJsonObject &obj) { mAutoTranslateLanguagesModel->parseLanguages(obj); } void RocketChatAccount::autoTranslateSaveLanguageSettings(const QString &roomId, const QString &language) { if (mRuqolaServerConfig->hasAtLeastVersion(1, 99, 0)) { restApi()->autoTranslateSaveLanguageSettings(roomId, language); } else { qCWarning(RUQOLA_LOG) << " RocketChatAccount::autoTranslateSaveLanguageSettings is not supported before server 2.0.0"; } } void RocketChatAccount::autoTranslateSaveAutoTranslateSettings(const QString &roomId, bool autoTranslate) { if (mRuqolaServerConfig->hasAtLeastVersion(1, 99, 0)) { restApi()->autoTranslateSaveAutoTranslateSettings(roomId, autoTranslate); } else { qCWarning(RUQOLA_LOG) << " RocketChatAccount::autoTranslateSaveLanguageSettings is not supported before server 2.0.0"; } } void RocketChatAccount::slotUsersPresenceDone(const QJsonObject &obj) { qDebug() << " void RocketChatAccount::slotUsersPresenceDone(const QJsonObject &obj)" << obj; } void RocketChatAccount::slotDisconnectedByServer() { // This happens when we didn't react to pings for a while // (e.g. while stopped in gdb, or if network went down for a bit) // Let's try connecting in again // TODO: delay this more and more like RC+ ? QTimer::singleShot(100, this, [this]() { qCDebug(RUQOLA_LOG) << "Attempting to reconnect after the server disconnected us"; // Do the parts of logOut() that don't actually try talking to the server mRoomModel->clear(); delete mDdp; mDdp = nullptr; tryLogin(); }); } void RocketChatAccount::usersPresence() { restApi()->usersPresence(); } void RocketChatAccount::customUsersStatus() { if (mRuqolaServerConfig->hasAtLeastVersion(2, 4, 0)) { restApi()->customUserStatus(); } else { qCWarning(RUQOLA_LOG) << " RocketChatAccount::customUserStatus is not supported before server 2.4.0"; } } void RocketChatAccount::initializeAccount() { listEmojiCustom(); //load when necessary //account->usersPresence(); if (mRuqolaServerConfig->autoTranslateEnabled()) { getSupportedLanguages(); } //Force set online. //TODO don't reset message status ! ddp()->setDefaultStatus(User::PresenceStatus::PresenceOnline); //customUsersStatus(); Only for test } diff --git a/src/core/rocketchataccount.h b/src/core/rocketchataccount.h index 764753db..7e800b70 100644 --- a/src/core/rocketchataccount.h +++ b/src/core/rocketchataccount.h @@ -1,521 +1,521 @@ /* Copyright (c) 2017-2020 Laurent Montel This library 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 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef ROCKETCHATACCOUNT_H #define ROCKETCHATACCOUNT_H #include #include #include #include #include #include "messages/message.h" #include "rocketchataccountsettings.h" #include "libruqolacore_export.h" #include "authenticationinfo.h" #include "file.h" #include "inputtextmanager.h" #include "accountroomsettings.h" class TypingNotification; class UsersModel; class RoomModel; class RoomWrapper; class MessageModel; class DDPClient; class MessageQueue; class RocketChatBackend; class RoomFilterProxyModel; class RuqolaLogger; class RuqolaServerConfig; class UserCompleterModel; class UserCompleterFilterProxyModel; class StatusModel; class RocketChatCache; class EmojiManager; class OtrManager; class UsersForRoomFilterProxyModel; class FilesForRoomFilterProxyModel; class FilesForRoomModel; class SearchChannelModel; class SearchChannelFilterProxyModel; class LoginMethodModel; class InputTextManager; class PluginAuthenticationInterface; class Room; class SearchMessageModel; class SearchMessageFilterProxyModel; class ThreadsFilterProxyModel; class ServerConfigInfo; class ReceiveTypingNotificationManager; -class EmoticonModel; +class EmoticonFilterModel; class DiscussionsFilterProxyModel; class DiscussionsModel; class ThreadsModel; class ThreadMessageModel; class ListMessagesModel; class ListMessagesModelFilterProxyModel; class AutotranslateLanguagesModel; namespace RocketChatRestApi { class RestApiRequest; } class LIBRUQOLACORE_EXPORT RocketChatAccount : public QObject { Q_OBJECT Q_PROPERTY(QString userName READ userName WRITE setUserName NOTIFY userNameChanged) Q_PROPERTY(QString userID READ userID WRITE setUserID NOTIFY userIDChanged) Q_PROPERTY(QString serverUrl READ serverUrl WRITE setServerUrl NOTIFY serverUrlChanged) Q_PROPERTY(QString accountName READ accountName WRITE setAccountName NOTIFY accountNameChanged) Q_PROPERTY(QString password READ password WRITE setPassword NOTIFY passwordChanged) Q_PROPERTY(QString twoFactorAuthenticationCode READ twoFactorAuthenticationCode WRITE setTwoFactorAuthenticationCode NOTIFY twoFactorAuthenticationCodeChanged) Q_PROPERTY(DDPClient::LoginStatus loginStatus READ loginStatus NOTIFY loginStatusChanged) Q_PROPERTY(bool editingMode READ editingMode NOTIFY editingModeChanged) Q_PROPERTY(bool sortUnreadOnTop READ sortUnreadOnTop NOTIFY sortUnreadOnTopChanged) Q_PROPERTY(bool autoTranslateEnabled READ autoTranslateEnabled CONSTANT) Q_PROPERTY(bool jitsiEnabled READ jitsiEnabled CONSTANT) Q_PROPERTY(bool encryptedEnabled READ encryptedEnabled CONSTANT) Q_PROPERTY(bool allowMessagePinningEnabled READ allowMessagePinningEnabled CONSTANT) Q_PROPERTY(bool allowMessageSnippetingEnabled READ allowMessageSnippetingEnabled CONSTANT) Q_PROPERTY(bool allowMessageStarringEnabled READ allowMessageStarringEnabled CONSTANT) Q_PROPERTY(bool allowMessageDeletingEnabled READ allowMessageDeletingEnabled CONSTANT) Q_PROPERTY(bool threadsEnabled READ threadsEnabled CONSTANT) Q_PROPERTY(bool discussionEnabled READ discussionEnabled CONSTANT) Q_PROPERTY(bool hasPinnedMessagesSupport READ hasPinnedMessagesSupport CONSTANT) Q_PROPERTY(bool hasSnippetedMessagesSupport READ hasSnippetedMessagesSupport CONSTANT) Q_PROPERTY(bool hasStarredMessagesSupport READ hasStarredMessagesSupport CONSTANT) Q_PROPERTY(bool allowEditingMessages READ allowEditingMessages CONSTANT) Q_PROPERTY(bool otrEnabled READ otrEnabled CONSTANT) Q_PROPERTY(bool hasInviteUserSupport READ hasInviteUserSupport CONSTANT) Q_PROPERTY(ServerConfigInfo* serverConfigInfo READ serverConfigInfo CONSTANT) Q_PROPERTY(AutotranslateLanguagesModel* autoTranslateLanguagesModel READ autoTranslateLanguagesModel CONSTANT) Q_PROPERTY(QString recordingVideoPath READ recordingVideoPath CONSTANT) Q_PROPERTY(QString recordingImagePath READ recordingImagePath CONSTANT) Q_PROPERTY(LoginMethodModel* loginMethodModel READ loginMethodModel CONSTANT) Q_PROPERTY(StatusModel* statusModel READ statusModel CONSTANT) Q_PROPERTY(DiscussionsFilterProxyModel* discussionsFilterProxyModel READ discussionsFilterProxyModel CONSTANT) Q_PROPERTY(SearchChannelFilterProxyModel* searchChannelFilterProxyModel READ searchChannelFilterProxyModel CONSTANT) Q_PROPERTY(InputTextManager* inputTextManager READ inputTextManager CONSTANT) Q_PROPERTY(InputTextManager* inputThreadMessageTextManager READ inputThreadMessageTextManager CONSTANT) Q_PROPERTY(ThreadsFilterProxyModel* threadsFilterProxyModel READ threadsFilterProxyModel CONSTANT) Q_PROPERTY(MessageModel* threadMessageModel READ threadMessageModel CONSTANT) - Q_PROPERTY(EmoticonModel* emoticonModel READ emoticonModel CONSTANT) + Q_PROPERTY(EmoticonFilterModel* emoticonFilterModel READ emoticonFilterModel CONSTANT) Q_PROPERTY(FilesForRoomFilterProxyModel* filesForRoomFilterProxyModel READ filesForRoomFilterProxyModel CONSTANT) Q_PROPERTY(SearchMessageFilterProxyModel* searchMessageFilterProxyModel READ searchMessageFilterProxyModel CONSTANT) Q_PROPERTY(ListMessagesModelFilterProxyModel* listMessagesFilterProxyModel READ listMessagesFilterProxyModel CONSTANT) Q_PROPERTY(RoomFilterProxyModel* roomFilterProxyModel READ roomFilterProxyModel CONSTANT) Q_PROPERTY(UsersModel* usersModel READ usersModel CONSTANT) Q_PROPERTY(ReceiveTypingNotificationManager* receiveTypingNotificationManager READ receiveTypingNotificationManager CONSTANT) Q_PROPERTY(UserCompleterFilterProxyModel* userCompleterFilterModelProxy READ userCompleterFilterModelProxy CONSTANT) public: explicit RocketChatAccount(const QString &accountName = QString(), QObject *parent = nullptr); ~RocketChatAccount() override; enum ChannelTypeInfo { RoomId, RoomName, }; Q_ENUM(ChannelTypeInfo) enum RoomInfoType { Announcement, Description, Name, Topic, ReadOnly, Archive, RoomType, Encrypted, Password }; Q_ENUM(RoomInfoType) enum NotificationOptionsType { DisableNotifications, HideUnreadStatus, AudioNotifications, DesktopNotifications, DesktopDurationNotifications, DesktopSoundNotifications, EmailNotifications, MobilePushNotifications, UnreadAlert, MuteGroupMentions }; Q_ENUM(NotificationOptionsType) enum RoleType { AddOwner, AddLeader, AddModerator, RemoveOwner, RemoveLeader, RemoveModerator }; Q_ENUM(RoleType) Q_INVOKABLE Q_REQUIRED_RESULT QString getUserCurrentMessage(const QString &roomId); Q_INVOKABLE void setUserCurrentMessage(const QString &message, const QString &roomId); Q_INVOKABLE void textEditing(const QString &roomId, bool clearNotification); Q_INVOKABLE void leaveRoom(const QString &roomId, const QString &channelType); Q_INVOKABLE void hideRoom(const QString &roomId, const QString &channelType = QString()); Q_INVOKABLE void tryLogin(); Q_INVOKABLE void logOut(); Q_INVOKABLE void clearAllUnreadMessages(); Q_INVOKABLE void clearUnreadMessages(const QString &roomId); Q_INVOKABLE void changeFavorite(const QString &roomId, bool checked); Q_INVOKABLE void sendMessage(const QString &roomID, const QString &message); Q_INVOKABLE void updateMessage(const QString &roomID, const QString &messageId, const QString &message); Q_INVOKABLE void replyOnThread(const QString &roomID, const QString &threadMessageId, const QString &message); Q_INVOKABLE void openChannel(const QString &url, RocketChatAccount::ChannelTypeInfo typeInfo); Q_INVOKABLE void joinJitsiConfCall(const QString &roomId); Q_INVOKABLE void createNewChannel(const QString &name, bool readOnly, bool privateRoom, const QString &userNames, bool encryptedRoom, const QString &password, bool broadcast); Q_INVOKABLE void joinRoom(const QString &roomId, const QString &joinCode = QString()); Q_INVOKABLE void openDirectChannel(const QString &username); Q_INVOKABLE void setDefaultStatus(User::PresenceStatus status, const QString &messageStatus); //Move to private no ? Q_INVOKABLE void changeDefaultStatus(int index, const QString &messageStatus); Q_INVOKABLE void createJitsiConfCall(const QString &roomId); Q_INVOKABLE void deleteMessage(const QString &messageId, const QString &roomId); Q_INVOKABLE void userAutocomplete(const QString &searchText, const QString &exception); Q_INVOKABLE void eraseRoom(const QString &roomId, const QString &channelType); Q_INVOKABLE void changeChannelSettings(const QString &roomId, RocketChatAccount::RoomInfoType infoType, const QVariant &newValue, const QString &channelType = QString()); Q_INVOKABLE void changeNotificationsSettings(const QString &roomId, RocketChatAccount::NotificationOptionsType notificationsType, const QVariant &newValue); Q_INVOKABLE void downloadFile(const QString &downloadFileUrl, const QUrl &localFile); Q_INVOKABLE void starMessage(const QString &messageId, bool starred); Q_INVOKABLE void pinMessage(const QString &messageId, bool pinned); Q_INVOKABLE void uploadFile(const QString &roomId, const QString &description, const QString &messageText, const QUrl &fileUrl); Q_INVOKABLE Q_REQUIRED_RESULT QString avatarUrl(const QString &userId); Q_INVOKABLE Q_REQUIRED_RESULT QUrl attachmentUrl(const QString &url); Q_INVOKABLE void loadHistory(const QString &roomID, const QString &channelType = QString(), bool initial = false); Q_INVOKABLE void channelAndPrivateAutocomplete(const QString &pattern); Q_INVOKABLE void roomFiles(const QString &roomId, const QString &channelType = QString()); Q_INVOKABLE void addUserToRoom(const QString &username, const QString &roomId, const QString &channelType); Q_INVOKABLE void changeDefaultAuthentication(int index); Q_INVOKABLE void messageSearch(const QString &pattern, const QString &rid); InputTextManager *inputTextManager() const { return mInputTextManager; } InputTextManager *inputThreadMessageTextManager() const { return mInputThreadMessageTextManager; } Q_INVOKABLE void blockUser(const QString &userId, bool block); Q_INVOKABLE Q_REQUIRED_RESULT QString avatarUrlFromDirectChannel(const QString &rid); Q_INVOKABLE void deleteFileMessage(const QString &roomId, const QString &fileId, const QString &channelType); Q_INVOKABLE void openDocumentation(); Q_INVOKABLE void clearSearchModel(); Q_INVOKABLE void reactOnMessage(const QString &messageId, const QString &emoji, bool shouldReact); Q_INVOKABLE void ignoreUser(const QString &rid, const QString &userId, bool ignore); Q_INVOKABLE void channelInfo(const QString &roomId); Q_INVOKABLE void groupInfo(const QString &roomId); Q_INVOKABLE void switchEditingMode(bool b); Q_INVOKABLE void setSortUnreadOnTop(bool b); Q_INVOKABLE void kickUser(const QString &rid, const QString &userId, const QString &channelType); Q_INVOKABLE void changeRoles(const QString &rid, const QString &userId, const QString &channelType, RocketChatAccount::RoleType roleType); Q_INVOKABLE void rolesInRoom(const QString &roomId, const QString &channelType); Q_INVOKABLE void switchingToRoom(const QString &roomID); Q_INVOKABLE void reportMessage(const QString &messageId, const QString &message); Q_INVOKABLE void getThreadMessages(const QString &threadMessageId); Q_INVOKABLE void createDiscussion(const QString &parentRoomName, const QString &discussionName, const QString &replyMessage, const QString &messageId, const QStringList &users = QStringList()); Q_INVOKABLE void threadsInRoom(const QString &roomId); Q_INVOKABLE void discussionsInRoom(const QString &roomId); Q_INVOKABLE void followMessage(const QString &messageId, bool follow); Q_INVOKABLE void replyToMessage(const QString &roomID, const QString &message, const QString &messageId); Q_INVOKABLE void loadMoreFileAttachments(const QString &roomId, const QString &channelType); Q_INVOKABLE void loadMoreDiscussions(const QString &roomId); Q_INVOKABLE void loadMoreThreads(const QString &roomId); Q_INVOKABLE void loadThreadMessagesHistory(const QString &roomId); Q_INVOKABLE void loadMoreUsersInRoom(const QString &roomId, const QString &channelType); Q_INVOKABLE void getPinnedMessages(const QString &roomId); Q_INVOKABLE void getStarredMessages(const QString &roomId); Q_INVOKABLE void getSnippetedMessages(const QString &roomId); Q_INVOKABLE void getMentionsMessages(const QString &roomId); Q_INVOKABLE void autoTranslateSaveLanguageSettings(const QString &roomId, const QString &language); Q_INVOKABLE void autoTranslateSaveAutoTranslateSettings(const QString &roomId, bool autoTranslate); Q_INVOKABLE UsersForRoomFilterProxyModel *usersForRoomFilterProxyModel(const QString &roomId) const; Q_INVOKABLE RoomWrapper *roomWrapper(const QString &roomId); Q_INVOKABLE MessageModel *messageModelForRoom(const QString &roomID); Q_INVOKABLE void changeDisplayAttachment(const QString &roomId, const QString &messageId, bool displayAttachment); Q_INVOKABLE void changeShowOriginalMessage(const QString &roomId, const QString &messageId, bool showOriginal); Q_INVOKABLE void loadMoreListMessages(const QString &roomId); Q_INVOKABLE void getListMessages(const QString &roomId, ListMessagesModel::ListMessageType type); QUrl urlForLink(const QString &link) const; SearchMessageFilterProxyModel *searchMessageFilterProxyModel() const; FilesForRoomFilterProxyModel *filesForRoomFilterProxyModel() const; ReceiveTypingNotificationManager *receiveTypingNotificationManager() const; UserCompleterFilterProxyModel *userCompleterFilterModelProxy() const; UsersModel *usersModel() const; RoomFilterProxyModel *roomFilterProxyModel() const; MessageModel *threadMessageModel() const; - EmoticonModel *emoticonModel() const; + EmoticonFilterModel *emoticonFilterModel() const; SearchChannelFilterProxyModel *searchChannelFilterProxyModel() const; AutotranslateLanguagesModel *autoTranslateLanguagesModel() const; DiscussionsFilterProxyModel *discussionsFilterProxyModel() const; SearchChannelModel *searchChannelModel() const; UserCompleterModel *userCompleterModel() const; RocketChatAccountSettings *settings() const; ThreadsFilterProxyModel *threadsFilterProxyModel() const; DDPClient *ddp(); RoomModel *roomModel() const; LoginMethodModel *loginMethodModel() const; Q_REQUIRED_RESULT bool editingMode() const; Q_REQUIRED_RESULT QString serverVersionStr() const; Q_REQUIRED_RESULT bool sortUnreadOnTop() const; Q_REQUIRED_RESULT DDPClient::LoginStatus loginStatus(); RocketChatRestApi::RestApiRequest *restApi(); //Make it private in future void slotInformTypingStatus(const QString &room, bool typing); MessageQueue *messageQueue() const; RocketChatBackend *rocketChatBackend() const; RuqolaLogger *ruqolaLogger() const; void parsePublicSettings(const QJsonObject &obj); RuqolaServerConfig *ruqolaServerConfig() const; void setUserName(const QString &username); Q_REQUIRED_RESULT QString userName() const; void setAccountName(const QString &servername); Q_REQUIRED_RESULT QString accountName() const; void setUserID(const QString &userID); Q_REQUIRED_RESULT QString userID() const; void setPassword(const QString &password); Q_REQUIRED_RESULT QString password() const; void setTwoFactorAuthenticationCode(const QString &twoFactorAuthenticationCode); Q_REQUIRED_RESULT QString twoFactorAuthenticationCode() const; void setAuthToken(const QString &token); Q_REQUIRED_RESULT QString authToken() const; void setServerUrl(const QString &serverUrl); void sendNotification(const QJsonArray &contents); void parseOtr(const QJsonArray &contents); void setServerVersion(const QString &version); Q_REQUIRED_RESULT bool needAdaptNewSubscriptionRC60() const; EmojiManager *emojiManager() const; Q_REQUIRED_RESULT QString userStatusIconFileName(const QString &id); void membersInRoom(const QString &roomId, const QString &roomType); void parseUsersForRooms(const QJsonObject &obj, const RocketChatRestApi::ChannelBaseJob::ChannelInfo &channelInfo); void loadAutoCompleteChannel(const QJsonObject &obj); void insertCompleterUsers(); PluginAuthenticationInterface *defaultAuthenticationInterface() const; SearchMessageModel *searchMessageModel() const; void updateUser(const QJsonObject &object); void removeSettings(); void rolesChanged(const QJsonArray &contents); FilesForRoomModel *filesModelForRoom() const; DiscussionsModel *discussionsModel() const; ThreadsModel *threadsModel() const; Q_REQUIRED_RESULT bool encryptedEnabled() const; void updateThreadMessageList(const Message &m); void initializeAccount(); Q_REQUIRED_RESULT bool allowEditingMessages() const; Q_REQUIRED_RESULT bool otrEnabled() const; ListMessagesModel *listMessageModel() const; ListMessagesModelFilterProxyModel *listMessagesFilterProxyModel() const; Q_REQUIRED_RESULT ServerConfigInfo *serverConfigInfo() const; Q_REQUIRED_RESULT QString serverUrl() const; Q_REQUIRED_RESULT StatusModel *statusModel() const; void customUsersStatus(); Q_REQUIRED_RESULT bool jitsiEnabled() const; Q_REQUIRED_RESULT bool allowMessagePinningEnabled() const; Q_REQUIRED_RESULT bool allowMessageSnippetingEnabled() const; Q_REQUIRED_RESULT bool allowMessageStarringEnabled() const; Q_REQUIRED_RESULT bool allowMessageDeletingEnabled() const; Q_REQUIRED_RESULT bool hasPinnedMessagesSupport() const; Q_REQUIRED_RESULT bool hasStarredMessagesSupport() const; Q_REQUIRED_RESULT bool hasSnippetedMessagesSupport() const; Q_REQUIRED_RESULT bool autoTranslateEnabled() const; Q_REQUIRED_RESULT bool threadsEnabled() const; Q_REQUIRED_RESULT bool discussionEnabled() const; Q_REQUIRED_RESULT QString recordingVideoPath() const; Q_REQUIRED_RESULT QString recordingImagePath() const; void setAccountEnabled(bool enabled); Q_REQUIRED_RESULT bool accountEnabled() const; void insertAvatarUrl(const QString &userId, const QUrl &url); Q_REQUIRED_RESULT AccountRoomSettings *accountRoomSettings() const; Q_REQUIRED_RESULT bool hasInviteUserSupport() const; Q_SIGNALS: void connectedChanged(); void accountNameChanged(); void userNameChanged(); void userIDChanged(); void passwordChanged(); void twoFactorAuthenticationCodeChanged(); void serverUrlChanged(); void loginStatusChanged(); void socketError(QAbstractSocket::SocketError error, const QString &errorString); void logoutDone(const QString &accountname); void added(const QJsonObject &item); void changed(const QJsonObject &item); void removed(const QJsonObject &item); void notification(const QString &title, const QString &message, const QPixmap &pixmap); void fileDownloaded(const QString &filePath, const QUrl &cacheImageUrl); void updateNotification(bool hasAlert, int nbUnread, const QString &accountName); void missingChannelPassword(const RocketChatRestApi::ChannelBaseJob::ChannelInfo &channelInfo); void editingModeChanged(); void sortUnreadOnTopChanged(); void jobFailed(const QString &message); void switchedRooms(); void userStatusUpdated(User::PresenceStatus status); void publicSettingChanged(); void serverVersionChanged(); void openLinkRequested(const QString &link); void selectRoomByRoomIdRequested(const QString &identifier); void selectRoomByRoomNameRequested(const QString &identifier); private: Q_DISABLE_COPY(RocketChatAccount) Room *getRoom(const QString &roomId); void slotChannelFilesDone(const QJsonObject &obj, const RocketChatRestApi::ChannelBaseJob::ChannelInfo &channelInfo); void slotChannelRolesDone(const QJsonObject &obj, const RocketChatRestApi::ChannelBaseJob::ChannelInfo &channelInfo); void slotSplotLightDone(const QJsonObject &obj); void slotGetThreadMessagesDone(const QJsonObject &obj, const QString &threadMessageId); void slotGetThreadsListDone(const QJsonObject &obj, const QString &roomId); void slotGetDiscussionsListDone(const QJsonObject &obj, const QString &roomId); void slotGetSupportedLanguagesDone(const QJsonObject &obj); void slotUsersPresenceDone(const QJsonObject &obj); void slotSocketError(QAbstractSocket::SocketError error, const QString &errorString); void slotDisconnectedByServer(); void loadEmoji(const QJsonObject &obj); void slotSearchMessages(const QJsonObject &obj); void slotNeedToUpdateNotification(); void loadSettings(const QString &accountFileName); void clearModels(); void fillOauthModel(); void initializeAuthenticationPlugins(); void setDefaultAuthentication(AuthenticationManager::OauthType type); void userStatusChanged(const User &user); void setChannelJoinDone(const RocketChatRestApi::ChannelBaseJob::ChannelInfo &channelInfo); void openArchivedRoom(const RocketChatRestApi::ChannelBaseJob::ChannelInfo &channelInfo); void getSupportedLanguages(); void usersPresence(); void listEmojiCustom(); void checkInitializedRoom(const QString &roomId); void clearTypingNotification(); void inputAutocomplete(const QString &pattern, const QString &exceptions, InputTextManager::CompletionForType type); void slotGetListMessagesDone(const QJsonObject &obj, const QString &roomId, ListMessagesModel::ListMessageType type); void slotUserAutoCompleterDone(const QJsonObject &obj); void slotRoomsAutoCompleteChannelAndPrivateDone(const QJsonObject &obj); AccountRoomSettings *mAccountRoomSettings = nullptr; PluginAuthenticationInterface *mDefaultAuthenticationInterface = nullptr; QHash mLstPluginAuthenticationInterface; QVector mLstInfos; RocketChatAccountSettings *mSettings = nullptr; EmojiManager *mEmojiManager = nullptr; TypingNotification *mTypingNotification = nullptr; UsersModel *mUserModel = nullptr; RoomModel *mRoomModel = nullptr; RoomFilterProxyModel *mRoomFilterProxyModel = nullptr; DDPClient *mDdp = nullptr; RocketChatRestApi::RestApiRequest *mRestApi = nullptr; MessageQueue *mMessageQueue = nullptr; RocketChatBackend *mRocketChatBackend = nullptr; RuqolaLogger *mRuqolaLogger = nullptr; RuqolaServerConfig *mRuqolaServerConfig = nullptr; UserCompleterModel *mUserCompleterModel = nullptr; UserCompleterFilterProxyModel *mUserCompleterFilterModelProxy = nullptr; StatusModel *mStatusModel = nullptr; RocketChatCache *mCache = nullptr; OtrManager *mOtrManager = nullptr; SearchChannelModel *mSearchChannelModel = nullptr; SearchChannelFilterProxyModel *mSearchChannelFilterProxyModel = nullptr; LoginMethodModel *mLoginMethodModel = nullptr; InputTextManager *mInputTextManager = nullptr; InputTextManager *mInputThreadMessageTextManager = nullptr; SearchMessageModel *mSearchMessageModel = nullptr; SearchMessageFilterProxyModel *mSearchMessageFilterProxyModel = nullptr; ReceiveTypingNotificationManager *mReceiveTypingNotificationManager = nullptr; ServerConfigInfo *mServerConfigInfo = nullptr; FilesForRoomModel *mFilesModelForRoom = nullptr; FilesForRoomFilterProxyModel *mFilesForRoomFilterProxyModel = nullptr; DiscussionsFilterProxyModel *mDiscussionsFilterProxyModel = nullptr; DiscussionsModel *mDiscussionsModel = nullptr; ThreadsModel *mThreadsModel = nullptr; ThreadsFilterProxyModel *mThreadsFilterProxyModel = nullptr; - EmoticonModel *mEmoticonModel = nullptr; + EmoticonFilterModel *mEmoticonModel = nullptr; ThreadMessageModel *mThreadMessageModel = nullptr; ListMessagesModel *mListMessageModel = nullptr; ListMessagesModelFilterProxyModel *mListMessagesFilterProxyModel = nullptr; AutotranslateLanguagesModel *mAutoTranslateLanguagesModel = nullptr; bool mEditingMode = false; }; #endif // ROCKETCHATACCOUNT_H diff --git a/src/core/ruqolaregisterengine.cpp b/src/core/ruqolaregisterengine.cpp index b3e5a5c9..d2b5c9ca 100644 --- a/src/core/ruqolaregisterengine.cpp +++ b/src/core/ruqolaregisterengine.cpp @@ -1,148 +1,148 @@ /* Copyright (c) 2017-2020 Laurent Montel This library 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 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "messages/message.h" #include "rocketchataccount.h" #include "roomwrapper.h" #include "ruqola.h" #include "ruqola_debug.h" #include "ruqolaregisterengine.h" #include "ruqolautils.h" #include "clipboardproxy.h" #include "authenticationmanager.h" #include "accountmanager.h" #include "notificationoptionswrapper.h" #include "receivetypingnotificationmanager.h" #include "serverconfiginfo.h" #include "model/usersforroommodel.h" #include "model/usersmodel.h" #include "model/roommodel.h" #include "model/statusmodel.h" #include "model/usersforroomfilterproxymodel.h" #include "model/usercompleterfilterproxymodel.h" #include "model/filesforroomfilterproxymodel.h" #include "model/searchchannelfilterproxymodel.h" #include "model/inputcompletermodel.h" #include "model/roomfilterproxymodel.h" #include "model/usercompletermodel.h" #include "model/loginmethodmodel.h" #include "model/searchmessagefilterproxymodel.h" #include "model/rocketchataccountmodel.h" #include "model/rocketchataccountfilterproxymodel.h" -#include "model/emoticonmodel.h" +#include "model/emoticonfiltermodel.h" #include "model/notificationpreferencemodel.h" #include "model/notificationdesktopdurationpreferencemodel.h" #include "model/notificationdesktopsoundpreferencemodel.h" #include "model/threadsfilterproxymodel.h" #include "model/listmessagesmodel.h" #include "model/discussionsfilterproxymodel.h" #include "model/emoticoncategoriesmodel.h" #include "notificationpreferences.h" #include "model/listmessagesmodelfilterproxymodel.h" #include "model/autotranslatelanguagesmodel.h" #include "channel.h" #include #include #include #define URI "Ruqola" RuqolaRegisterEngine::RuqolaRegisterEngine() { } RuqolaRegisterEngine::~RuqolaRegisterEngine() { delete mEngine; } bool RuqolaRegisterEngine::initialize() { //Singleton qmlRegisterSingletonType(QUrl(QStringLiteral("qrc:/ExtraColors.qml")), URI, 1, 0, "RuqolaSingleton"); qmlRegisterSingletonType(QUrl(QStringLiteral("qrc:/DebugCategory.qml")), URI, 1, 0, "RuqolaDebugCategorySingleton"); qmlRegisterSingletonType(URI, 1, 0, "Ruqola", ruqola_singletontype_provider); qmlRegisterSingletonType(URI, 1, 0, "RuqolaUtils", ruqolautils_singletontype_provider); qmlRegisterSingletonType(URI, 1, 0, "NotificationPreferences", notificationpreferences_singletontype_provider); qmlRegisterType(URI, 1, 0, "MessageModel"); qmlRegisterType(URI, 1, 0, "RoomWrapper"); qmlRegisterType(URI, 1, 0, "RoomModel"); qmlRegisterType(URI, 1, 0, "Room"); qmlRegisterType(URI, 1, 0, "RocketChatAccount"); qmlRegisterType(URI, 1, 0, "UsersModel"); qmlRegisterType(URI, 1, 0, "RoomFilterProxyModel"); qmlRegisterType(URI, 1, 0, "UsersForRoomFilterProxyModel"); qmlRegisterType(URI, 1, 0, "UserCompleterFilterModelProxy"); qmlRegisterType(URI, 1, 0, "FilesForRoomFilterProxyModel"); qmlRegisterType(URI, 1, 0, "UserCompleterModel"); qmlRegisterType(URI, 1, 0, "StatusModel"); qmlRegisterType(URI, 1, 0, "NotificationPreferenceModel"); qmlRegisterType(URI, 1, 0, "NotificationDesktopDurationPreferenceModel"); qmlRegisterType(URI, 1, 0, "NotificationDesktopSoundPreferenceModel"); qmlRegisterType(URI, 1, 0, "SearchChannelFilterProxyModel"); qmlRegisterType(URI, 1, 0, "InputCompleterModel"); qmlRegisterType(URI, 1, 0, "LoginMethodModel"); qmlRegisterType(URI, 1, 0, "SearchMessageFilterProxyModel"); qmlRegisterType(URI, 1, 0, "AccountManager"); qmlRegisterType(URI, 1, 0, "RocketChatAccountFilterProxyModel"); qmlRegisterType(URI, 1, 0, "RocketChatAccountModel"); qmlRegisterType(URI, 1, 0, "Clipboard"); qmlRegisterType(URI, 1, 0, "NotificationOptionsWrapper"); - qmlRegisterType(URI, 1, 0, "EmoticonModel"); + qmlRegisterType(URI, 1, 0, "EmoticonFilterModel"); qmlRegisterType(URI, 1, 0, "ThreadsFilterProxyModel"); qmlRegisterType(URI, 1, 0, "DiscussionsFilterProxyModel"); qmlRegisterType(URI, 1, 0, "EmoticonCategoriesModel"); qmlRegisterType(URI, 1, 0, "ListMessagesModelFilterProxyModel"); qmlRegisterType(URI, 1, 0, "AutotranslateLanguagesModel"); qmlRegisterType(URI, 1, 0, "ReceiveTypingNotificationManager"); qmlRegisterUncreatableType(URI, 1, 0, "Message", QStringLiteral("MessageType is an enum container")); qmlRegisterUncreatableType(URI, 1, 0, "Channel", QStringLiteral("ChannelType is an enum container")); qmlRegisterUncreatableType(URI, 1, 0, "DDPClient", QStringLiteral("DDPClient.LoginStatus is an enum container")); qmlRegisterType(URI, 1, 0, "ServerConfigInfo"); qmlRegisterType(URI, 1, 0, "ListMessagesModel"); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); mEngine = new QQmlApplicationEngine; QQmlContext *ctxt = mEngine->rootContext(); #if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) qmlRegisterType(URI, 1, 0, "Notification"); ctxt->setContextProperty(QStringLiteral("systrayIcon"), Ruqola::self()->notification()); #endif ctxt->setContextObject(new KLocalizedContext(mEngine)); mEngine->load(QUrl(QStringLiteral("qrc:/Desktop.qml"))); if (mEngine->rootObjects().isEmpty()) { qCWarning(RUQOLA_LOG) << "Impossible to load object from Desktop.qml"; return false; } return true; } diff --git a/src/widgets/misc/emoticonmenuwidget.cpp b/src/widgets/misc/emoticonmenuwidget.cpp index e2ac3a53..4125846b 100644 --- a/src/widgets/misc/emoticonmenuwidget.cpp +++ b/src/widgets/misc/emoticonmenuwidget.cpp @@ -1,68 +1,68 @@ /* Copyright (c) 2020 Laurent Montel This library 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 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "emoticonmenuwidget.h" #include "emoticonselectorwidget.h" #include "ruqola.h" #include "rocketchataccount.h" -#include "model/emoticonmodel.h" +#include "model/emoticonfiltermodel.h" #include #include EmoticonMenuWidget::EmoticonMenuWidget(QWidget *parent) : QWidget(parent) { auto *layout = new QVBoxLayout(this); layout->setObjectName(QStringLiteral("layout")); layout->setContentsMargins(0, 0, 0, 0); mTabWidget = new QTabWidget(this); mTabWidget->setObjectName(QStringLiteral("mTabWidget")); layout->addWidget(mTabWidget); QFont f = mTabWidget->font(); f.setPointSize(22); f.setFamily(QStringLiteral("NotoColorEmoji")); mTabWidget->setFont(f); } EmoticonMenuWidget::~EmoticonMenuWidget() { } void EmoticonMenuWidget::setCurrentRocketChatAccount(RocketChatAccount *account) { mTabWidget->clear(); initializeTab(account); } void EmoticonMenuWidget::initializeTab(RocketChatAccount *account) { - EmoticonModel *model = account->emoticonModel(); + EmoticonFilterModel *model = account->emoticonFilterModel(); const QMap > emojiMap = model->emoticons(); QMapIterator > i(emojiMap); while (i.hasNext()) { i.next(); auto *w = new EmoticonSelectorWidget(this); mTabWidget->addTab(w, i.value().at(0).unicode()); w->setEmoticon(i.value()); connect(w, &EmoticonSelectorWidget::itemSelected, this, &EmoticonMenuWidget::insertEmoticons); } }