1 /*
2    SPDX-FileCopyrightText: 2020-2021 Laurent Montel <montel@kde.org>
3 
4    SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "ruqolamainwindow.h"
8 #include "ruqolaglobalconfig.h"
9 #include "ruqolawidgets_debug.h"
10 
11 #include "accountmanager.h"
12 #include "administratordialog/administratordialog.h"
13 #include "config-ruqola.h"
14 #include "configuredialog/configuresettingsdialog.h"
15 #include "connection.h"
16 #include "dialogs/channelpassworddialog.h"
17 #include "dialogs/createdirectmessagesdialog.h"
18 #include "dialogs/createnewchanneldialog.h"
19 #include "dialogs/createnewdiscussiondialog.h"
20 #include "dialogs/createnewserverdialog.h"
21 #include "dialogs/modifystatusdialog.h"
22 #include "dialogs/searchchanneldialog.h"
23 #include "dialogs/serverinfo/serverinfodialog.h"
24 #include "directory/directorydialog.h"
25 #include "localmessagelogger.h"
26 #include "misc/accountsoverviewwidget.h"
27 #include "misc/servermenu.h"
28 #include "misc/statuscombobox.h"
29 #include "model/statusmodel.h"
30 #include "model/statusmodelfilterproxymodel.h"
31 #include "myaccount/myaccountconfiguredialog.h"
32 #include "notifications/notification.h"
33 #include "receivetypingnotificationmanager.h"
34 #include "registeruser/registeruserdialog.h"
35 #include "rocketchataccount.h"
36 #include "room.h"
37 #include "ruqola.h"
38 #include "ruqolacentralwidget.h"
39 #include "ruqolaserverconfig.h"
40 #include "teams/teamscreatejob.h"
41 #include <KActionCollection>
42 #include <KConfigGroup>
43 #include <KIO/JobUiDelegate>
44 #include <KIO/OpenUrlJob>
45 #include <KLocalizedString>
46 #include <KMessageBox>
47 #include <KNotifyConfigWidget>
48 #include <KSharedConfig>
49 #include <KStandardAction>
50 #include <QApplication>
51 #include <QDir>
52 #include <QFontDatabase>
53 #include <QHBoxLayout>
54 #include <QIcon>
55 #include <QLabel>
56 #include <QMenu>
57 #include <QStatusBar>
58 #include <QTemporaryFile>
59 #include <QWidgetAction>
60 
61 #if HAVE_KUSERFEEDBACK
62 #include "userfeedback/userfeedbackmanager.h"
63 #include <KUserFeedback/NotificationPopup>
64 #include <KUserFeedback/Provider>
65 #endif
66 
67 namespace
68 {
69 static const char myRuqolaMainWindowGroupName[] = "RuqolaMainWindow";
70 }
71 
RuqolaMainWindow(QWidget * parent)72 RuqolaMainWindow::RuqolaMainWindow(QWidget *parent)
73     : KXmlGuiWindow(parent)
74     , mMainWidget(new RuqolaCentralWidget(this))
75     , mStatusProxyModel(new StatusModelFilterProxyModel(this))
76 {
77     mMainWidget->setObjectName(QStringLiteral("mMainWidget"));
78     connect(mMainWidget, &RuqolaCentralWidget::loginPageActivated, this, &RuqolaMainWindow::slotLoginPageActivated);
79     setCentralWidget(mMainWidget);
80     setupActions();
81     setupStatusBar();
82     setupGUI(/*QStringLiteral(":/kxmlgui5/ruqola/ruqolaui.rc")*/);
83     readConfig();
84     createSystemTray();
85     connect(Ruqola::self()->accountManager(), &AccountManager::currentAccountChanged, this, &RuqolaMainWindow::slotAccountChanged);
86     connect(Ruqola::self()->accountManager(), &AccountManager::updateNotification, this, &RuqolaMainWindow::updateNotification);
87     connect(Ruqola::self()->accountManager(), &AccountManager::roomNeedAttention, this, &RuqolaMainWindow::slotRoomNeedAttention);
88     connect(Ruqola::self()->accountManager(), &AccountManager::logoutAccountDone, this, &RuqolaMainWindow::logout);
89 
90     slotAccountChanged();
91 #if HAVE_KUSERFEEDBACK
92     auto userFeedBackNotificationPopup = new KUserFeedback::NotificationPopup(this);
93     userFeedBackNotificationPopup->setFeedbackProvider(UserFeedBackManager::self()->userFeedbackProvider());
94 #endif
95 }
96 
~RuqolaMainWindow()97 RuqolaMainWindow::~RuqolaMainWindow()
98 {
99     KSharedConfig::Ptr config = KSharedConfig::openConfig();
100     KConfigGroup group = config->group(myRuqolaMainWindowGroupName);
101     group.writeEntry("Size", size());
102 
103     delete mMainWidget; // before Ruqola::destroy()
104 
105     Ruqola::destroy();
106 }
107 
slotRoomNeedAttention()108 void RuqolaMainWindow::slotRoomNeedAttention()
109 {
110     if (mNotification) {
111         mNotification->roomNeedAttention();
112     }
113 }
114 
logout(const QString & accountName)115 void RuqolaMainWindow::logout(const QString &accountName)
116 {
117     if (mNotification) {
118         mNotification->clearNotification(accountName);
119     }
120 }
121 
updateNotification(bool hasAlert,int nbUnread,const QString & accountName)122 void RuqolaMainWindow::updateNotification(bool hasAlert, int nbUnread, const QString &accountName)
123 {
124     if (mNotification) {
125         mNotification->updateNotification(hasAlert, nbUnread, accountName);
126     }
127 }
128 
setupStatusBar()129 void RuqolaMainWindow::setupStatusBar()
130 {
131     mStatusBarTypingMessage = new QLabel(this);
132     mStatusBarTypingMessage->setTextFormat(Qt::RichText);
133     mStatusBarTypingMessage->setObjectName(QStringLiteral("mStatusBarTypingMessage"));
134     statusBar()->addPermanentWidget(mStatusBarTypingMessage);
135     mAccountOverviewWidget = new AccountsOverviewWidget(this);
136     statusBar()->addPermanentWidget(mAccountOverviewWidget);
137 }
138 
slotAccountChanged()139 void RuqolaMainWindow::slotAccountChanged()
140 {
141     if (mCurrentRocketChatAccount) {
142         disconnect(mCurrentRocketChatAccount, nullptr, this, nullptr);
143         disconnect(mCurrentRocketChatAccount->receiveTypingNotificationManager(), nullptr, this, nullptr);
144     }
145     mCurrentRocketChatAccount = Ruqola::self()->rocketChatAccount();
146     connect(mCurrentRocketChatAccount->receiveTypingNotificationManager(),
147             &ReceiveTypingNotificationManager::notificationChanged,
148             this,
149             &RuqolaMainWindow::slotTypingNotificationChanged);
150     connect(mCurrentRocketChatAccount->receiveTypingNotificationManager(),
151             &ReceiveTypingNotificationManager::clearNotification,
152             this,
153             &RuqolaMainWindow::slotClearNotification);
154     connect(mCurrentRocketChatAccount, &RocketChatAccount::missingChannelPassword, this, &RuqolaMainWindow::slotMissingChannelPassword);
155     connect(mCurrentRocketChatAccount, &RocketChatAccount::publicSettingChanged, this, &RuqolaMainWindow::updateActions);
156     connect(mCurrentRocketChatAccount, &RocketChatAccount::serverVersionChanged, this, [this]() {
157         slotPermissionChanged();
158         updateActions();
159     });
160     connect(mCurrentRocketChatAccount, &RocketChatAccount::ownInfoChanged, this, [this]() {
161         updateActions();
162         slotPermissionChanged();
163     });
164     connect(mCurrentRocketChatAccount, &RocketChatAccount::raiseWindow, this, &RuqolaMainWindow::slotRaiseWindow);
165     connect(mCurrentRocketChatAccount, &RocketChatAccount::permissionChanged, this, &RuqolaMainWindow::slotPermissionChanged);
166     connect(mCurrentRocketChatAccount, &RocketChatAccount::registerUserSuccess, this, &RuqolaMainWindow::slotRegisterUserSuccessed);
167     connect(mCurrentRocketChatAccount,
168             &RocketChatAccount::userStatusUpdated,
169             this,
170             [this](User::PresenceStatus status, const QString &customText, const QString &accountName) {
171                 if (mCurrentRocketChatAccount->accountName() == accountName) {
172                     mStatusComboBox->blockSignals(true);
173                     mStatusComboBox->setStatus(status, customText);
174                     mStatusComboBox->blockSignals(false);
175                 }
176             });
177     connect(mCurrentRocketChatAccount, &RocketChatAccount::updateStatusComboBox, this, &RuqolaMainWindow::slotUpdateCustomUserStatus);
178 
179     updateActions();
180     slotClearNotification(); // Clear notification when we switch too.
181     mMainWidget->setCurrentRocketChatAccount(mCurrentRocketChatAccount);
182 
183     mStatusComboBox->blockSignals(true);
184     mStatusProxyModel->setSourceModel(mCurrentRocketChatAccount->statusModel());
185     mStatusComboBox->setModel(mStatusProxyModel);
186 
187     slotUpdateCustomUserStatus();
188     mStatusComboBox->setStatus(mCurrentRocketChatAccount->presenceStatus());
189     mStatusComboBox->blockSignals(false);
190 }
191 
slotRaiseWindow()192 void RuqolaMainWindow::slotRaiseWindow()
193 {
194     show();
195     raise();
196     activateWindow();
197 }
198 
slotPermissionChanged()199 void RuqolaMainWindow::slotPermissionChanged()
200 {
201     mCreateTeam->setEnabled(mCurrentRocketChatAccount->teamEnabled());
202 }
203 
updateActions()204 void RuqolaMainWindow::updateActions()
205 {
206     mUnreadOnTop->setChecked(mCurrentRocketChatAccount->sortUnreadOnTop());
207     mRegisterNewUser->setEnabled(mCurrentRocketChatAccount->registrationFromEnabled());
208     mAdministrator->setEnabled(mCurrentRocketChatAccount->isAdministrator());
209     mCreateDiscussion->setEnabled(mCurrentRocketChatAccount->discussionEnabled());
210 }
211 
readConfig()212 void RuqolaMainWindow::readConfig()
213 {
214     KSharedConfig::Ptr config = KSharedConfig::openConfig();
215     KConfigGroup group = KConfigGroup(config, myRuqolaMainWindowGroupName);
216     const QSize sizeDialog = group.readEntry("Size", QSize(800, 600));
217     if (sizeDialog.isValid()) {
218         resize(sizeDialog);
219     }
220 }
221 
slotClearNotification()222 void RuqolaMainWindow::slotClearNotification()
223 {
224     mStatusBarTypingMessage->clear();
225 }
226 
slotTypingNotificationChanged(const QString & roomId,const QString & notificationStr)227 void RuqolaMainWindow::slotTypingNotificationChanged(const QString &roomId, const QString &notificationStr)
228 {
229     if (mMainWidget->roomId() == roomId) {
230         mStatusBarTypingMessage->setText(notificationStr);
231     }
232 }
233 
setupActions()234 void RuqolaMainWindow::setupActions()
235 {
236     KActionCollection *ac = actionCollection();
237 
238     KStandardAction::quit(this, &RuqolaMainWindow::slotClose, ac);
239     KStandardAction::preferences(this, &RuqolaMainWindow::slotConfigure, ac);
240     KStandardAction::configureNotifications(this, &RuqolaMainWindow::slotConfigureNotifications, ac);
241 
242     auto act = new QAction(i18n("Add Server..."), this);
243     connect(act, &QAction::triggered, this, &RuqolaMainWindow::slotAddServer);
244     ac->addAction(QStringLiteral("add_server"), act);
245 
246     // Move in specific server widget
247     mServerInfo = new QAction(i18n("Server Info..."), this);
248     connect(mServerInfo, &QAction::triggered, this, &RuqolaMainWindow::slotServerInfo);
249     ac->addAction(QStringLiteral("server_info"), mServerInfo);
250 
251     mLogout = new QAction(i18n("Logout Current Server"), this);
252     connect(mLogout, &QAction::triggered, this, &RuqolaMainWindow::slotLogout);
253     ac->addAction(QStringLiteral("logout"), mLogout);
254 
255     mSearchChannel = new QAction(i18n("Search Channel..."), this);
256     connect(mSearchChannel, &QAction::triggered, this, &RuqolaMainWindow::slotSearchChannel);
257     ac->addAction(QStringLiteral("search_channel"), mSearchChannel);
258 
259     mNextUnreadChannel = new QAction(i18n("Jump to Next Unread Channel"), this);
260     connect(mNextUnreadChannel, &QAction::triggered, this, &RuqolaMainWindow::slotSelectNextUnreadChannel);
261     ac->setDefaultShortcut(mNextUnreadChannel, Qt::Key_Control | Qt::Key_PageDown);
262     ac->addAction(QStringLiteral("next_unread_channel"), mNextUnreadChannel);
263 
264     mCreateNewChannel = new QAction(i18n("Create New Channel..."), this);
265     mCreateNewChannel->setIcon(QIcon::fromTheme(QStringLiteral("irc-join-channel")));
266     connect(mCreateNewChannel, &QAction::triggered, this, &RuqolaMainWindow::slotCreateNewChannel);
267     ac->addAction(QStringLiteral("create_new_channel"), mCreateNewChannel);
268 
269     mCreateDirectMessages = new QAction(i18n("Create Direct Messages..."), this);
270     mCreateDirectMessages->setIcon(QIcon::fromTheme(QStringLiteral("irc-join-channel")));
271     connect(mCreateDirectMessages, &QAction::triggered, this, &RuqolaMainWindow::slotCreateDirectMessages);
272     ac->addAction(QStringLiteral("create_direct_messages"), mCreateDirectMessages);
273 
274     mCreateDiscussion = new QAction(i18n("Create Discussion..."), this);
275     mCreateDiscussion->setIcon(QIcon::fromTheme(QStringLiteral("irc-join-channel")));
276     connect(mCreateDiscussion, &QAction::triggered, this, &RuqolaMainWindow::slotCreateDiscussion);
277     ac->addAction(QStringLiteral("create_discussion"), mCreateDiscussion);
278 
279     mCreateTeam = new QAction(i18n("Create Team..."), this);
280     mCreateTeam->setIcon(QIcon::fromTheme(QStringLiteral("irc-join-channel")));
281     connect(mCreateTeam, &QAction::triggered, this, &RuqolaMainWindow::slotCreateTeam);
282     ac->addAction(QStringLiteral("create_team"), mCreateTeam);
283 
284     mServerMenu = new ServerMenu(this);
285     mServerMenu->setActionCollection(ac);
286     ac->addAction(QStringLiteral("server_menu"), mServerMenu);
287 
288     mUnreadOnTop = new QAction(i18n("Unread on Top"), this);
289     mUnreadOnTop->setCheckable(true);
290     connect(mUnreadOnTop, &QAction::triggered, this, &RuqolaMainWindow::slotUnreadOnTop);
291     ac->addAction(QStringLiteral("unread_on_top"), mUnreadOnTop);
292 
293     mShowLog = new QAction(QIcon::fromTheme(QStringLiteral("view-history")), i18n("Show Channel Log"), this);
294     connect(mShowLog, &QAction::triggered, this, &RuqolaMainWindow::slotShowLog);
295     ac->addAction(QStringLiteral("show_log"), mShowLog);
296 
297     mClearAlerts = new QAction(i18n("Mark All Channels as Read"), this);
298     ac->setDefaultShortcut(mClearAlerts, Qt::SHIFT | Qt::Key_Escape);
299     connect(mClearAlerts, &QAction::triggered, this, &RuqolaMainWindow::slotClearAccountAlerts);
300     ac->addAction(QStringLiteral("mark_all_channels_read"), mClearAlerts);
301 
302     mRegisterNewUser = new QAction(i18n("Register a New User..."), this);
303     connect(mRegisterNewUser, &QAction::triggered, this, &RuqolaMainWindow::slotRegisterNewUser);
304     ac->addAction(QStringLiteral("register_new_user"), mRegisterNewUser);
305 
306     mMyAccount = new QAction(i18n("My Account..."), this);
307     connect(mMyAccount, &QAction::triggered, this, &RuqolaMainWindow::slotConfigureMyAccount);
308     ac->addAction(QStringLiteral("configure_my_account"), mMyAccount);
309 
310     mAdministrator = new QAction(i18n("Administrator..."), this);
311     connect(mAdministrator, &QAction::triggered, this, &RuqolaMainWindow::slotAdministrator);
312     ac->addAction(QStringLiteral("administrator"), mAdministrator);
313 
314     mDirectory = new QAction(i18n("Directory..."), this);
315     connect(mDirectory, &QAction::triggered, this, &RuqolaMainWindow::slotDirectory);
316     ac->addAction(QStringLiteral("directory"), mDirectory);
317 
318     {
319         auto action = new QWidgetAction(this);
320         action->setText(i18n("Status"));
321         auto container = new QWidget(this);
322         // use the same font as other toolbar buttons
323         container->setFont(qApp->font("QToolButton"));
324         action->setDefaultWidget(container);
325         auto layout = new QHBoxLayout(container);
326         layout->setContentsMargins({});
327         auto label = new QLabel(i18n("Status:"), container);
328         label->setObjectName(QStringLiteral("label"));
329         layout->addWidget(label);
330 
331         mStatusComboBox = new StatusCombobox(container);
332         mStatusComboBox->setObjectName(QStringLiteral("mStatusComboBox"));
333         layout->addWidget(mStatusComboBox);
334         connect(mStatusComboBox, &StatusCombobox::currentIndexChanged, this, &RuqolaMainWindow::slotStatusChanged);
335 
336         mStatus = action;
337         connect(mStatus, &QAction::triggered, mStatusComboBox, &QComboBox::showPopup);
338         ac->addAction(QStringLiteral("status"), mStatus);
339     }
340 }
341 
slotClearAccountAlerts()342 void RuqolaMainWindow::slotClearAccountAlerts()
343 {
344     if (auto acct = Ruqola::self()->accountManager()->account()) {
345         acct->clearAllUnreadMessages();
346     }
347 }
348 
slotCreateTeam()349 void RuqolaMainWindow::slotCreateTeam()
350 {
351     QPointer<CreateNewChannelDialog> dlg = new CreateNewChannelDialog(mCurrentRocketChatAccount, this);
352     dlg->setWindowTitle(i18nc("@title:window", "Create Team"));
353     CreateNewChannelWidget::Features flags;
354     if (mCurrentRocketChatAccount->broadCastEnabled()) {
355         flags |= CreateNewChannelWidget::Feature::BroadCast;
356     }
357     if (mCurrentRocketChatAccount->encryptionEnabled()) {
358         flags |= CreateNewChannelWidget::Feature::Encrypted;
359     }
360     dlg->setFeatures(flags);
361     if (dlg->exec()) {
362         const CreateNewChannelDialog::NewChannelInfo info = dlg->channelInfo();
363         auto job = new RocketChatRestApi::TeamsCreateJob(this);
364         RocketChatRestApi::CreateRoomInfo teamInfo = info.info;
365         job->setTeamsCreateJobInfo(teamInfo);
366         mCurrentRocketChatAccount->restApi()->initializeRestApiJob(job);
367         connect(job, &RocketChatRestApi::TeamsCreateJob::teamCreateDone, this, []() {
368             qCDebug(RUQOLAWIDGETS_LOG) << " teamCreateDone";
369             // TODO switch to new team ?
370         });
371         if (!job->start()) {
372             qCWarning(RUQOLAWIDGETS_LOG) << "Impossible to start TeamsCreateJob";
373         }
374     }
375     delete dlg;
376 }
377 
slotCreateDiscussion()378 void RuqolaMainWindow::slotCreateDiscussion()
379 {
380     CreateNewDiscussionDialog dlg(mCurrentRocketChatAccount, this);
381     dlg.exec();
382 }
383 
slotCreateDirectMessages()384 void RuqolaMainWindow::slotCreateDirectMessages()
385 {
386     CreateDirectMessagesDialog dlg(mCurrentRocketChatAccount, this);
387     dlg.exec();
388 }
389 
slotCreateNewChannel()390 void RuqolaMainWindow::slotCreateNewChannel()
391 {
392     QPointer<CreateNewChannelDialog> dlg = new CreateNewChannelDialog(mCurrentRocketChatAccount, this);
393     CreateNewChannelWidget::Features flags;
394     if (mCurrentRocketChatAccount->broadCastEnabled()) {
395         flags |= CreateNewChannelWidget::Feature::BroadCast;
396     }
397     if (mCurrentRocketChatAccount->encryptionEnabled()) {
398         flags |= CreateNewChannelWidget::Feature::Encrypted;
399     }
400     dlg->setFeatures(flags);
401     if (dlg->exec()) {
402         const CreateNewChannelDialog::NewChannelInfo info = dlg->channelInfo();
403         // TODO adapt createNewChannel api for using QStringList
404         mCurrentRocketChatAccount->createNewChannel(info.info, info.privateChannel);
405     }
406     delete dlg;
407 }
408 
slotConfigure()409 void RuqolaMainWindow::slotConfigure()
410 {
411     QPointer<ConfigureSettingsDialog> dlg = new ConfigureSettingsDialog(this);
412     if (dlg->exec()) {
413         if (RuqolaGlobalConfig::self()->useCustomFont()) {
414             qApp->setFont(RuqolaGlobalConfig::self()->generalFont());
415         } else {
416             qApp->setFont(QFontDatabase::systemFont(QFontDatabase::GeneralFont));
417         }
418 
419         mAccountOverviewWidget->updateButtons();
420         createSystemTray();
421     }
422     delete dlg;
423 }
424 
slotAddServer()425 void RuqolaMainWindow::slotAddServer()
426 {
427     QPointer<CreateNewServerDialog> dlg = new CreateNewServerDialog(this);
428     const QStringList lst = Ruqola::self()->accountManager()->accountsName();
429     dlg->setExistingAccountName(lst);
430     if (dlg->exec()) {
431         const AccountManager::AccountManagerInfo info = dlg->accountInfo();
432         Ruqola::self()->accountManager()->addAccount(info);
433     }
434     delete dlg;
435 }
436 
slotServerInfo()437 void RuqolaMainWindow::slotServerInfo()
438 {
439     ServerInfoDialog dlg(this);
440     dlg.setServerConfigInfo(mCurrentRocketChatAccount->serverConfigInfo());
441     dlg.exec();
442 }
443 
slotLogout()444 void RuqolaMainWindow::slotLogout()
445 {
446     mCurrentRocketChatAccount->logOut();
447 }
448 
slotSearchChannel()449 void RuqolaMainWindow::slotSearchChannel()
450 {
451     SearchChannelDialog dlg(mCurrentRocketChatAccount, this);
452     dlg.exec();
453 }
454 
slotSelectNextUnreadChannel()455 void RuqolaMainWindow::slotSelectNextUnreadChannel()
456 {
457     mMainWidget->selectNextUnreadChannel();
458 }
459 
slotUnreadOnTop(bool checked)460 void RuqolaMainWindow::slotUnreadOnTop(bool checked)
461 {
462     mCurrentRocketChatAccount->setSortUnreadOnTop(checked);
463 }
464 
slotShowLog()465 void RuqolaMainWindow::slotShowLog()
466 {
467     auto *room = mMainWidget->room();
468     if (room) {
469         QTemporaryFile tempFile(QDir::tempPath() + QStringLiteral("/XXXXXX.log.txt"));
470         tempFile.setAutoRemove(false);
471         if (tempFile.open()) {
472             LocalMessageLogger logger;
473             if (logger.saveToFile(tempFile, mCurrentRocketChatAccount->accountName(), room->displayFName())) {
474                 const QString fileName = tempFile.fileName();
475                 tempFile.close();
476                 auto job = new KIO::OpenUrlJob(QUrl::fromLocalFile(fileName), this);
477                 job->setUiDelegate(new KIO::JobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this));
478                 job->setDeleteTemporaryFile(true);
479                 job->start();
480             }
481         }
482     }
483 }
484 
slotMissingChannelPassword(const RocketChatRestApi::ChannelGroupBaseJob::ChannelGroupInfo & channelInfo)485 void RuqolaMainWindow::slotMissingChannelPassword(const RocketChatRestApi::ChannelGroupBaseJob::ChannelGroupInfo &channelInfo)
486 {
487     QPointer<ChannelPasswordDialog> dlg = new ChannelPasswordDialog(this);
488     // TODO add channel name!
489     if (dlg->exec()) {
490         // FIXME channelinfo
491         mCurrentRocketChatAccount->joinRoom(channelInfo.identifier, dlg->password());
492     }
493     delete dlg;
494 }
495 
slotLoginPageActivated(bool loginPageActivated)496 void RuqolaMainWindow::slotLoginPageActivated(bool loginPageActivated)
497 {
498     mSearchChannel->setEnabled(!loginPageActivated);
499     mCreateNewChannel->setEnabled(!loginPageActivated);
500     mCreateDirectMessages->setEnabled(!loginPageActivated);
501     mLogout->setEnabled(!loginPageActivated);
502     mClearAlerts->setEnabled(!loginPageActivated);
503     mMyAccount->setEnabled(!loginPageActivated);
504     mStatus->setEnabled(!loginPageActivated);
505     mCreateDiscussion->setEnabled(!loginPageActivated);
506     mCreateTeam->setEnabled(!loginPageActivated);
507 }
508 
slotConfigureNotifications()509 void RuqolaMainWindow::slotConfigureNotifications()
510 {
511     KNotifyConfigWidget::configure(this);
512 }
513 
slotRegisterNewUser()514 void RuqolaMainWindow::slotRegisterNewUser()
515 {
516     RegisterUserDialog dlg(mCurrentRocketChatAccount, this);
517     dlg.exec();
518 }
519 
slotRegisterUserSuccessed()520 void RuqolaMainWindow::slotRegisterUserSuccessed()
521 {
522     KMessageBox::information(
523         this,
524         i18n("We have sent you an email to confirm your registration.\nIf you do not receive an email shortly, please come back and try again."),
525         i18n("Register New User"));
526 }
527 
slotConfigureMyAccount()528 void RuqolaMainWindow::slotConfigureMyAccount()
529 {
530     MyAccountConfigureDialog dlg(mCurrentRocketChatAccount, this);
531     dlg.initialize();
532     dlg.exec();
533 }
534 
slotAdministrator()535 void RuqolaMainWindow::slotAdministrator()
536 {
537     AdministratorDialog dlg(mCurrentRocketChatAccount, this);
538     dlg.initialize();
539     dlg.exec();
540 }
541 
slotDirectory()542 void RuqolaMainWindow::slotDirectory()
543 {
544     DirectoryDialog dlg(mCurrentRocketChatAccount, this);
545     dlg.fillTabs();
546     dlg.exec();
547 }
548 
queryClose()549 bool RuqolaMainWindow::queryClose()
550 {
551     if (qApp->isSavingSession() || mReallyClose || !mNotification) {
552         return true;
553     }
554     hide();
555     return false;
556 }
557 
slotClose()558 void RuqolaMainWindow::slotClose()
559 {
560     mReallyClose = true;
561     close();
562 }
563 
createSystemTray()564 void RuqolaMainWindow::createSystemTray()
565 {
566 #if !defined(Q_OS_IOS)
567     if (!RuqolaGlobalConfig::self()->enableSystemTray()) {
568         delete mNotification;
569         mNotification = nullptr;
570         return;
571     }
572     if (!mNotification) {
573         mNotification = new Notification(this);
574         auto trayMenu = mNotification->contextMenu();
575         trayMenu->addAction(actionCollection()->action(QLatin1String(KStandardAction::name(KStandardAction::Preferences))));
576         trayMenu->addAction(actionCollection()->action(QLatin1String(KStandardAction::name(KStandardAction::ConfigureNotifications))));
577         // Create systray to show notifications on Desktop
578         connect(mNotification, &Notification::alert, this, [this]() {
579             QApplication::alert(this, 0);
580         });
581     }
582 #endif
583 }
584 
slotStatusChanged()585 void RuqolaMainWindow::slotStatusChanged()
586 {
587     // const auto currentStatusInfo = mCurrentRocketChatAccount->statusModel()->currentStatusInfo();
588     User::PresenceStatus status = mStatusComboBox->status();
589     QString messageStatus; // = currentStatusInfo.statusStr;
590     if (status == User::PresenceStatus::Unknown) {
591         QPointer<ModifyStatusDialog> dlg = new ModifyStatusDialog(this);
592         const auto currentStatusInfo = mCurrentRocketChatAccount->statusModel()->currentStatusInfo();
593         dlg->setMessageStatus(mCurrentRocketChatAccount->statusModel()->customText());
594         dlg->setStatus(currentStatusInfo.status);
595         if (dlg->exec()) {
596             messageStatus = dlg->messageStatus();
597             status = dlg->status();
598             delete dlg;
599         } else {
600             mStatusComboBox->setStatus(mCurrentRocketChatAccount->statusModel()->currentUserStatus());
601             delete dlg;
602             return;
603         }
604     }
605     mCurrentRocketChatAccount->setDefaultStatus(status, messageStatus);
606 }
607 
slotUpdateCustomUserStatus()608 void RuqolaMainWindow::slotUpdateCustomUserStatus()
609 {
610     mStatusProxyModel->sort(0);
611 }
612