File indexing completed on 2024-12-01 07:42:31
0001 /* 0002 SPDX-FileCopyrightText: 2020-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "ruqolamainwindow.h" 0008 #include "databasedialog/exploredatabasedialog.h" 0009 #include "explorepermissionsdialog/explorepermissionsdialog.h" 0010 #include "notificationhistorymanager.h" 0011 #include "ruqolaglobalconfig.h" 0012 #include "ruqolawidgets_debug.h" 0013 0014 #include "accountmanager.h" 0015 #include "administratordialog/administratordialog.h" 0016 #include "administratorsettingsdialog/administratorsettingsdialog.h" 0017 #include "servererrorinfohistory/servererrorinfomessagehistorydialog.h" 0018 0019 #include "bannerinfodialog/bannerinfodialog.h" 0020 #include "config-ruqola.h" 0021 #include "configuredialog/configuresettingsdialog.h" 0022 #include "connection.h" 0023 #include "createnewserver/createnewserverdialog.h" 0024 #include "dialogs/channelpassworddialog.h" 0025 #include "dialogs/createdirectmessagesdialog.h" 0026 #include "dialogs/createnewchanneldialog.h" 0027 #include "dialogs/createnewdiscussiondialog.h" 0028 #include "dialogs/modifystatusdialog.h" 0029 #include "dialogs/serverinfo/serverinfodialog.h" 0030 #include "directory/directorydialog.h" 0031 #include "importexportdata/exportdata/exportdatawizard.h" 0032 #include "importexportdata/importdata/importdatawizard.h" 0033 #include "localdatabase/localmessagelogger.h" 0034 #include "misc/accountsoverviewwidget.h" 0035 #include "misc/messagestylelayoutmenu.h" 0036 #include "misc/servermenu.h" 0037 #include "misc/statuscombobox.h" 0038 #include "model/statusmodel.h" 0039 #include "model/statusmodelfilterproxymodel.h" 0040 #include "myaccount/myaccountconfiguredialog.h" 0041 #include "notificationhistory/notificationhistorydialog.h" 0042 #include "notifications/notification.h" 0043 #include "ownuser/ownuserpreferences.h" 0044 #include "receivetypingnotificationmanager.h" 0045 #include "registeruser/registeruserdialog.h" 0046 #include "rocketchataccount.h" 0047 #include "room.h" 0048 #include "ruqola.h" 0049 #include "ruqolacentralwidget.h" 0050 #include "ruqolacommandlineoptions.h" 0051 #include "ruqolaserverconfig.h" 0052 #include "switchchannelhistory/switchchanneltreeviewmanager.h" 0053 #include "teams/teamscreatejob.h" 0054 #include "whatsnew/whatsnewdialog.h" 0055 0056 #include <KActionCollection> 0057 #include <KColorSchemeManager> 0058 #include <KConfigGroup> 0059 #include <KIO/JobUiDelegateFactory> 0060 #include <KIO/OpenUrlJob> 0061 #include <KLocalizedString> 0062 #include <KMessageBox> 0063 #include <KNotifyConfigWidget> 0064 #include <KSharedConfig> 0065 #include <KStandardAction> 0066 #include <KToggleFullScreenAction> 0067 #include <KToolBar> 0068 #include <QActionGroup> 0069 #include <QApplication> 0070 #include <QCommandLineParser> 0071 #include <QDir> 0072 #include <QFontDatabase> 0073 #include <QHBoxLayout> 0074 #include <QIcon> 0075 #include <QKeyCombination> 0076 #include <QLabel> 0077 #include <QMenu> 0078 #include <QMenuBar> 0079 #include <QStatusBar> 0080 #include <QTemporaryFile> 0081 #include <QToolButton> 0082 #include <QWidgetAction> 0083 0084 #include <KColorSchemeMenu> 0085 0086 #if !defined(Q_OS_WIN) && !defined(Q_OS_MACOS) 0087 #include <KWindowSystem> 0088 #endif 0089 0090 #if HAVE_KUSERFEEDBACK 0091 #include "userfeedback/userfeedbackmanager.h" 0092 #include <KUserFeedback/NotificationPopup> 0093 #include <KUserFeedback/Provider> 0094 #endif 0095 #include "colorsandmessageviewstyle.h" 0096 0097 namespace 0098 { 0099 static const char myRuqolaMainWindowGroupName[] = "RuqolaMainWindow"; 0100 } 0101 0102 RuqolaMainWindow::RuqolaMainWindow(QWidget *parent) 0103 : KXmlGuiWindow(parent) 0104 , mMainWidget(new RuqolaCentralWidget(this)) 0105 , mStatusProxyModel(new StatusModelFilterProxyModel(this)) 0106 , mSwitchChannelTreeManager(new SwitchChannelTreeViewManager(this)) 0107 { 0108 mMainWidget->setObjectName(QStringLiteral("mMainWidget")); 0109 connect(mMainWidget, &RuqolaCentralWidget::loginPageActivated, this, &RuqolaMainWindow::slotLoginPageActivated); 0110 setCentralWidget(mMainWidget); 0111 setupActions(); 0112 setupStatusBar(); 0113 setupGUI(/*QStringLiteral(":/kxmlgui5/ruqola/ruqolaui.rc")*/); 0114 readConfig(); 0115 createSystemTray(); 0116 mSwitchChannelTreeManager->setParentWidget(mMainWidget); 0117 connect(mSwitchChannelTreeManager, &SwitchChannelTreeViewManager::switchToChannel, this, &RuqolaMainWindow::slotHistorySwitchChannel); 0118 mAccountManager = Ruqola::self()->accountManager(); 0119 connect(mAccountManager, &AccountManager::currentAccountChanged, this, &RuqolaMainWindow::slotAccountChanged); 0120 connect(mAccountManager, &AccountManager::updateNotification, this, &RuqolaMainWindow::updateNotification); 0121 connect(mAccountManager, &AccountManager::roomNeedAttention, this, &RuqolaMainWindow::slotRoomNeedAttention); 0122 connect(mAccountManager, &AccountManager::messageUrlNotFound, this, &RuqolaMainWindow::slotMessageUrlNotFound); 0123 connect(mAccountManager, &AccountManager::logoutAccountDone, this, &RuqolaMainWindow::logout); 0124 0125 slotAccountChanged(); 0126 #if HAVE_KUSERFEEDBACK 0127 auto userFeedBackNotificationPopup = new KUserFeedback::NotificationPopup(this); 0128 userFeedBackNotificationPopup->setFeedbackProvider(UserFeedBackManager::self()->userFeedbackProvider()); 0129 #endif 0130 mShowMenuBarAction->setChecked(RuqolaGlobalConfig::self()->showMenuBar()); 0131 slotToggleMenubar(true); 0132 } 0133 0134 RuqolaMainWindow::~RuqolaMainWindow() 0135 { 0136 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0137 KConfigGroup group = config->group(QLatin1String(myRuqolaMainWindowGroupName)); 0138 group.writeEntry("Size", size()); 0139 0140 delete mMainWidget; // before Ruqola::destroy() 0141 0142 Ruqola::destroy(); 0143 } 0144 0145 void RuqolaMainWindow::parseCommandLine(QCommandLineParser *parser) 0146 { 0147 if (parser->isSet(QStringLiteral("messageurl"))) { 0148 const QString messageUrl = parser->value(QStringLiteral("messageurl")); 0149 if (!messageUrl.isEmpty()) { 0150 Ruqola::self()->openMessageUrl(messageUrl); 0151 } 0152 } 0153 if (parser->isSet(QStringLiteral("account"))) { 0154 const QString loadAccount = parser->value(QStringLiteral("account")); 0155 if (!loadAccount.isEmpty()) { 0156 Ruqola::self()->setCurrentAccount(loadAccount); 0157 } 0158 } 0159 } 0160 0161 #if !defined(Q_OS_WIN) && !defined(Q_OS_MACOS) 0162 void RuqolaMainWindow::slotActivateRequested(const QStringList &arguments, const QString &workingDirectory) 0163 { 0164 Q_UNUSED(workingDirectory) 0165 if (!arguments.isEmpty()) { 0166 QCommandLineParser parser; 0167 ruqolaOptions(&parser); 0168 parser.parse(arguments); 0169 parseCommandLine(&parser); 0170 } 0171 0172 KWindowSystem::updateStartupId(windowHandle()); 0173 KWindowSystem::activateWindow(windowHandle()); 0174 } 0175 #endif 0176 0177 void RuqolaMainWindow::slotRoomNeedAttention() 0178 { 0179 if (mNotification) { 0180 mNotification->roomNeedAttention(); 0181 } 0182 } 0183 0184 void RuqolaMainWindow::logout(const QString &accountName) 0185 { 0186 if (mNotification) { 0187 mNotification->clearNotification(accountName); 0188 } 0189 } 0190 0191 void RuqolaMainWindow::updateNotification(bool hasAlert, int nbUnread, const QString &accountName) 0192 { 0193 if (mNotification) { 0194 mNotification->updateNotification(hasAlert, nbUnread, accountName); 0195 } 0196 } 0197 0198 void RuqolaMainWindow::setupStatusBar() 0199 { 0200 mStatusBarTypingMessage = new QLabel(this); 0201 mStatusBarTypingMessage->setTextFormat(Qt::RichText); 0202 mStatusBarTypingMessage->setObjectName(QStringLiteral("mStatusBarTypingMessage")); 0203 statusBar()->addPermanentWidget(mStatusBarTypingMessage); 0204 mAccountOverviewWidget = new AccountsOverviewWidget(this); 0205 mAccountOverviewWidget->setObjectName(QStringLiteral("mAccountOverviewWidget")); 0206 statusBar()->addPermanentWidget(mAccountOverviewWidget); 0207 mNotificationToolButton = new QToolButton(this); 0208 mNotificationToolButton->setIcon(QIcon::fromTheme(QStringLiteral("notifications"))); 0209 mNotificationToolButton->setObjectName(QStringLiteral("mNotificationToolButton")); 0210 mNotificationToolButton->setToolTip(i18n("Show New Notifications")); 0211 #ifndef QT_NO_ACCESSIBILITY 0212 mNotificationToolButton->setAccessibleName(i18n("Show New Notifications")); 0213 #endif 0214 0215 mNotificationToolButton->hide(); // Hide at start 0216 mNotificationToolButton->setAutoRaise(true); 0217 connect(mNotificationToolButton, &QToolButton::clicked, this, &RuqolaMainWindow::slotOpenNotificationHistory); 0218 statusBar()->addPermanentWidget(mNotificationToolButton); 0219 connect(NotificationHistoryManager::self(), &NotificationHistoryManager::newNotification, this, &RuqolaMainWindow::slotNewNotification); 0220 } 0221 0222 void RuqolaMainWindow::slotNewNotification() 0223 { 0224 mNotificationToolButton->show(); 0225 } 0226 0227 void RuqolaMainWindow::slotAccountChanged() 0228 { 0229 if (mCurrentRocketChatAccount) { 0230 disconnect(mCurrentRocketChatAccount, nullptr, this, nullptr); 0231 disconnect(mCurrentRocketChatAccount->receiveTypingNotificationManager(), nullptr, this, nullptr); 0232 } 0233 mCurrentRocketChatAccount = Ruqola::self()->rocketChatAccount(); 0234 connect(mCurrentRocketChatAccount->receiveTypingNotificationManager(), 0235 &ReceiveTypingNotificationManager::notificationChanged, 0236 this, 0237 &RuqolaMainWindow::slotTypingNotificationChanged); 0238 connect(mCurrentRocketChatAccount->receiveTypingNotificationManager(), 0239 &ReceiveTypingNotificationManager::clearNotification, 0240 this, 0241 &RuqolaMainWindow::slotClearNotification); 0242 connect(mCurrentRocketChatAccount, &RocketChatAccount::missingChannelPassword, this, &RuqolaMainWindow::slotMissingChannelPassword); 0243 connect(mCurrentRocketChatAccount, &RocketChatAccount::publicSettingChanged, this, &RuqolaMainWindow::updateActions); 0244 connect(mCurrentRocketChatAccount, &RocketChatAccount::serverVersionChanged, this, [this]() { 0245 slotPermissionChanged(); 0246 updateActions(); 0247 }); 0248 connect(mCurrentRocketChatAccount, &RocketChatAccount::ownInfoChanged, this, [this]() { 0249 updateActions(); 0250 slotPermissionChanged(); 0251 }); 0252 connect(mCurrentRocketChatAccount, &RocketChatAccount::ownUserPreferencesChanged, this, [this]() { 0253 updateActions(); 0254 }); 0255 connect(mCurrentRocketChatAccount, &RocketChatAccount::raiseWindow, this, &RuqolaMainWindow::slotRaiseWindow); 0256 connect(mCurrentRocketChatAccount, &RocketChatAccount::permissionChanged, this, &RuqolaMainWindow::slotPermissionChanged); 0257 connect(mCurrentRocketChatAccount, &RocketChatAccount::registerUserSuccess, this, &RuqolaMainWindow::slotRegisterUserSuccessed); 0258 connect(mCurrentRocketChatAccount, 0259 &RocketChatAccount::userStatusUpdated, 0260 this, 0261 [this](User::PresenceStatus status, const QString &customText, const QString &accountName) { 0262 if (mCurrentRocketChatAccount->accountName() == accountName) { 0263 mStatusComboBox->blockSignals(true); 0264 mStatusComboBox->setStatus(status, customText); 0265 mStatusComboBox->blockSignals(false); 0266 } 0267 }); 0268 connect(mCurrentRocketChatAccount, &RocketChatAccount::customStatusChanged, this, &RuqolaMainWindow::slotUpdateCustomUserStatus); 0269 connect(mCurrentRocketChatAccount, &RocketChatAccount::privateSettingsChanged, this, &RuqolaMainWindow::slotPrivateSettingsChanged); 0270 connect(mCurrentRocketChatAccount, &RocketChatAccount::publicSettingChanged, this, &RuqolaMainWindow::slotPrivateSettingsChanged); 0271 0272 updateActions(); 0273 slotClearNotification(); // Clear notification when we switch too. 0274 mMainWidget->setCurrentRocketChatAccount(mCurrentRocketChatAccount); 0275 mSwitchChannelTreeManager->setCurrentRocketChatAccount(mCurrentRocketChatAccount); 0276 0277 mStatusComboBox->blockSignals(true); 0278 mStatusProxyModel->setSourceModel(mCurrentRocketChatAccount->statusModel()); 0279 slotPrivateSettingsChanged(); 0280 mStatusComboBox->setModel(mStatusProxyModel); 0281 0282 slotUpdateCustomUserStatus(); 0283 mStatusComboBox->setStatus(mCurrentRocketChatAccount->presenceStatus()); 0284 mStatusComboBox->blockSignals(false); 0285 0286 slotUpdateStatusMenu(); 0287 } 0288 0289 void RuqolaMainWindow::slotPrivateSettingsChanged() 0290 { 0291 mStatusProxyModel->setAllowOfflineSupport(mCurrentRocketChatAccount->ruqolaServerConfig()->accountsAllowInvisibleStatusOption()); 0292 mStatusProxyModel->setUseOnlyStandardStatus(!mCurrentRocketChatAccount->ruqolaServerConfig()->allowCustomStatusMessage()); 0293 } 0294 0295 void RuqolaMainWindow::slotRaiseWindow() 0296 { 0297 show(); 0298 raise(); 0299 #if !defined(Q_OS_WIN) && !defined(Q_OS_MACOS) 0300 KWindowSystem::activateWindow(windowHandle()); 0301 #else 0302 activateWindow(); 0303 #endif 0304 } 0305 0306 void RuqolaMainWindow::slotPermissionChanged() 0307 { 0308 mCreateNewChannel->setEnabled(canCreateChannels()); 0309 mCreateDirectMessages->setEnabled(canCreateDirectMessages()); 0310 mCreateTeam->setEnabled(canCreateTeams()); 0311 } 0312 0313 void RuqolaMainWindow::updateActions() 0314 { 0315 mUnreadOnTop->setChecked(mCurrentRocketChatAccount->ownUserPreferences().showUnread()); 0316 const auto roomListSortOrder = mCurrentRocketChatAccount->ownUserPreferences().roomListSortOrder(); 0317 mRoomListSortByLastMessage->setChecked(roomListSortOrder == OwnUserPreferences::RoomListSortOrder::ByLastMessage); 0318 mRoomListSortAlphabetically->setChecked(roomListSortOrder == OwnUserPreferences::RoomListSortOrder::Alphabetically); 0319 mRegisterNewUser->setVisible(mCurrentRocketChatAccount->registrationFormEnabled()); 0320 mCreateDiscussion->setEnabled(mCurrentRocketChatAccount->discussionEnabled() 0321 && (mCurrentRocketChatAccount->loginStatus() == DDPAuthenticationManager::LoggedIn)); 0322 const bool isAdministrator{mCurrentRocketChatAccount->isAdministrator()}; 0323 mAdministrator->setEnabled(isAdministrator); 0324 mAdministratorServerSettings->setEnabled(isAdministrator); 0325 mAdministratorMenu->setVisible(isAdministrator); 0326 mShowRocketChatServerInfo->setVisible(hasBannerInfo()); 0327 mRoomAvatar->setChecked(mCurrentRocketChatAccount->ownUserPreferences().showRoomAvatar()); 0328 mRoomFavorite->setChecked(mCurrentRocketChatAccount->ownUserPreferences().showFavorite()); 0329 mCreateNewChannel->setEnabled(canCreateChannels()); 0330 mCreateDirectMessages->setEnabled(canCreateDirectMessages()); 0331 mCreateTeam->setEnabled(canCreateTeams()); 0332 } 0333 0334 bool RuqolaMainWindow::canCreateChannels() const 0335 { 0336 return mCurrentRocketChatAccount && mCurrentRocketChatAccount->hasPermission(QStringLiteral("create-c")); 0337 } 0338 0339 bool RuqolaMainWindow::canCreateDirectMessages() const 0340 { 0341 return mCurrentRocketChatAccount && mCurrentRocketChatAccount->hasPermission(QStringLiteral("create-d")); 0342 } 0343 0344 bool RuqolaMainWindow::canCreateTeams() const 0345 { 0346 return mCurrentRocketChatAccount && mCurrentRocketChatAccount->hasPermission(QStringLiteral("create-team")); 0347 } 0348 0349 bool RuqolaMainWindow::hasBannerInfo() const 0350 { 0351 return mCurrentRocketChatAccount && !mCurrentRocketChatAccount->bannerInfos().isEmpty(); 0352 } 0353 0354 void RuqolaMainWindow::readConfig() 0355 { 0356 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0357 KConfigGroup group = KConfigGroup(config, QLatin1String(myRuqolaMainWindowGroupName)); 0358 const QSize sizeDialog = group.readEntry("Size", QSize(800, 600)); 0359 if (sizeDialog.isValid()) { 0360 resize(sizeDialog); 0361 } 0362 } 0363 0364 void RuqolaMainWindow::slotClearNotification() 0365 { 0366 mStatusBarTypingMessage->clear(); 0367 } 0368 0369 void RuqolaMainWindow::slotTypingNotificationChanged(const QString &roomId, const QString ¬ificationStr) 0370 { 0371 if (mMainWidget->roomId() == roomId) { 0372 mStatusBarTypingMessage->setText(notificationStr); 0373 } 0374 } 0375 0376 void RuqolaMainWindow::setupActions() 0377 { 0378 KActionCollection *ac = actionCollection(); 0379 0380 mShowMenuBarAction = KStandardAction::showMenubar(this, &RuqolaMainWindow::slotToggleMenubar, ac); 0381 0382 KStandardAction::quit(this, &RuqolaMainWindow::slotClose, ac); 0383 KStandardAction::preferences(this, &RuqolaMainWindow::slotConfigure, ac); 0384 KStandardAction::configureNotifications(this, &RuqolaMainWindow::slotConfigureNotifications, ac); 0385 0386 auto act = new QAction(i18n("Add Server..."), this); 0387 connect(act, &QAction::triggered, this, &RuqolaMainWindow::slotAddServer); 0388 ac->addAction(QStringLiteral("add_server"), act); 0389 0390 // Move in specific server widget 0391 mServerInfo = new QAction(i18n("Server Info..."), this); 0392 connect(mServerInfo, &QAction::triggered, this, &RuqolaMainWindow::slotServerInfo); 0393 ac->addAction(QStringLiteral("server_info"), mServerInfo); 0394 0395 mLogout = new QAction(i18n("Logout Current Server"), this); 0396 connect(mLogout, &QAction::triggered, this, &RuqolaMainWindow::slotLogout); 0397 ac->addAction(QStringLiteral("logout"), mLogout); 0398 0399 mNextUnreadChannel = new QAction(i18n("Jump to Next Unread Channel"), this); 0400 connect(mNextUnreadChannel, &QAction::triggered, this, &RuqolaMainWindow::slotSelectNextUnreadChannel); 0401 ac->setDefaultShortcut(mNextUnreadChannel, Qt::Key_Control | Qt::Key_PageDown); 0402 ac->addAction(QStringLiteral("next_unread_channel"), mNextUnreadChannel); 0403 0404 mCreateNewChannel = new QAction(QIcon::fromTheme(QStringLiteral("irc-join-channel")), i18n("Create New Channel..."), this); 0405 connect(mCreateNewChannel, &QAction::triggered, this, &RuqolaMainWindow::slotCreateNewChannel); 0406 ac->addAction(QStringLiteral("create_new_channel"), mCreateNewChannel); 0407 0408 mCreateDirectMessages = new QAction(QIcon::fromTheme(QStringLiteral("irc-join-channel")), i18n("Create Direct Messages..."), this); 0409 connect(mCreateDirectMessages, &QAction::triggered, this, &RuqolaMainWindow::slotCreateDirectMessages); 0410 ac->addAction(QStringLiteral("create_direct_messages"), mCreateDirectMessages); 0411 0412 mCreateDiscussion = new QAction(QIcon::fromTheme(QStringLiteral("irc-join-channel")), i18n("Create Discussion..."), this); 0413 connect(mCreateDiscussion, &QAction::triggered, this, &RuqolaMainWindow::slotCreateDiscussion); 0414 ac->addAction(QStringLiteral("create_discussion"), mCreateDiscussion); 0415 0416 mCreateTeam = new QAction(QIcon::fromTheme(QStringLiteral("irc-join-channel")), i18n("Create Team..."), this); 0417 connect(mCreateTeam, &QAction::triggered, this, &RuqolaMainWindow::slotCreateTeam); 0418 ac->addAction(QStringLiteral("create_team"), mCreateTeam); 0419 0420 mServerMenu = new ServerMenu(this); 0421 mServerMenu->setActionCollection(ac); 0422 ac->addAction(QStringLiteral("server_menu"), mServerMenu); 0423 0424 mUnreadOnTop = new QAction(i18n("Unread on Top"), this); 0425 mUnreadOnTop->setCheckable(true); 0426 connect(mUnreadOnTop, &QAction::triggered, this, &RuqolaMainWindow::slotUnreadOnTop); 0427 ac->addAction(QStringLiteral("unread_on_top"), mUnreadOnTop); 0428 0429 QActionGroup *roomListSortOrder = new QActionGroup(this); 0430 roomListSortOrder->setExclusive(true); 0431 0432 mRoomListSortByLastMessage = new QAction(i18n("By Last Message"), this); 0433 mRoomListSortByLastMessage->setCheckable(true); 0434 connect(mRoomListSortByLastMessage, &QAction::triggered, this, &RuqolaMainWindow::slotRoomListSortByLastMessage); 0435 roomListSortOrder->addAction(mRoomListSortByLastMessage); 0436 ac->addAction(QStringLiteral("room_list_sort_by_last_message"), mRoomListSortByLastMessage); 0437 0438 mRoomListSortAlphabetically = new QAction(i18n("Alphabetically"), this); 0439 mRoomListSortAlphabetically->setCheckable(true); 0440 connect(mRoomListSortAlphabetically, &QAction::triggered, this, &RuqolaMainWindow::slotRoomListSortAlphabetically); 0441 roomListSortOrder->addAction(mRoomListSortAlphabetically); 0442 ac->addAction(QStringLiteral("room_list_sort_alphabetically"), mRoomListSortAlphabetically); 0443 0444 mShowLog = new QAction(QIcon::fromTheme(QStringLiteral("view-history")), i18n("Show Channel Log"), this); 0445 connect(mShowLog, &QAction::triggered, this, &RuqolaMainWindow::slotShowLog); 0446 ac->addAction(QStringLiteral("show_log"), mShowLog); 0447 0448 mShowServerInfo = new QAction(QIcon::fromTheme(QStringLiteral("data-error")), i18n("Show Server Errors"), this); 0449 connect(mShowServerInfo, &QAction::triggered, this, &RuqolaMainWindow::slotShowServerInfo); 0450 ac->addAction(QStringLiteral("show_server_errors"), mShowServerInfo); 0451 0452 if (Ruqola::self()->debug()) { 0453 mMenuDebug = new QAction(QStringLiteral("Debug"), this); 0454 ac->addAction(QStringLiteral("debug_menu"), mMenuDebug); 0455 auto menu = new QMenu(this); 0456 mMenuDebug->setMenu(menu); 0457 mShowDatabaseMessages = new QAction(QStringLiteral("Show Database Messages"), this); 0458 connect(mShowDatabaseMessages, &QAction::triggered, this, &RuqolaMainWindow::slotShowDatabaseMessages); 0459 ac->addAction(QStringLiteral("show_database_messages"), mShowDatabaseMessages); 0460 menu->addAction(mShowDatabaseMessages); 0461 mShowPermissions = new QAction(QStringLiteral("Show Permissions"), this); 0462 connect(mShowPermissions, &QAction::triggered, this, &RuqolaMainWindow::slotShowPermissions); 0463 ac->addAction(QStringLiteral("show_permissions"), mShowPermissions); 0464 menu->addAction(mShowPermissions); 0465 } 0466 0467 mClearAlerts = new QAction(i18n("Mark All Channels as Read"), this); 0468 ac->setDefaultShortcut(mClearAlerts, Qt::SHIFT | Qt::Key_Escape); 0469 connect(mClearAlerts, &QAction::triggered, this, &RuqolaMainWindow::slotClearAccountAlerts); 0470 ac->addAction(QStringLiteral("mark_all_channels_read"), mClearAlerts); 0471 0472 mRegisterNewUser = new QAction(i18n("Register a New User..."), this); 0473 connect(mRegisterNewUser, &QAction::triggered, this, &RuqolaMainWindow::slotRegisterNewUser); 0474 ac->addAction(QStringLiteral("register_new_user"), mRegisterNewUser); 0475 0476 mMyAccount = new QAction(i18n("My Account..."), this); 0477 connect(mMyAccount, &QAction::triggered, this, &RuqolaMainWindow::slotConfigureMyAccount); 0478 ac->addAction(QStringLiteral("configure_my_account"), mMyAccount); 0479 0480 mAdministratorMenu = new KActionMenu(i18n("Administrator"), this); 0481 mAdministrator = new QAction(i18n("Administrator..."), this); 0482 ac->addAction(QStringLiteral("administrator_account_settings"), mAdministrator); 0483 connect(mAdministrator, &QAction::triggered, this, &RuqolaMainWindow::slotAdministrator); 0484 mAdministratorMenu->addAction(mAdministrator); 0485 ac->addAction(QStringLiteral("administrator"), mAdministratorMenu); 0486 0487 mAdministratorServerSettings = new QAction(i18n("Server Settings..."), this); 0488 connect(mAdministratorServerSettings, &QAction::triggered, this, &RuqolaMainWindow::slotAdministratorServerSettings); 0489 ac->addAction(QStringLiteral("administrator_server_settings"), mAdministratorServerSettings); 0490 mAdministratorMenu->addAction(mAdministratorServerSettings); 0491 0492 mDirectory = new QAction(i18nc("Action which allows to search room/user/team", "Directory..."), this); 0493 connect(mDirectory, &QAction::triggered, this, &RuqolaMainWindow::slotDirectory); 0494 ac->addAction(QStringLiteral("directory"), mDirectory); 0495 0496 // Actions to navigate through the different pages 0497 QList<QKeySequence> nextShortcut; 0498 QList<QKeySequence> prevShortcut; 0499 0500 QString nextIcon, prevIcon; 0501 if (QApplication::isRightToLeft()) { 0502 prevShortcut.append(QKeySequence(QStringLiteral("Alt+Right"))); 0503 nextShortcut.append(QKeySequence(QStringLiteral("Alt+Left"))); 0504 nextIcon = QStringLiteral("go-previous-view"); 0505 prevIcon = QStringLiteral("go-next-view"); 0506 } else { 0507 nextShortcut.append(QKeySequence(QStringLiteral("Alt+Right"))); 0508 prevShortcut.append(QKeySequence(QStringLiteral("Alt+Left"))); 0509 nextIcon = QStringLiteral("go-next-view"); 0510 prevIcon = QStringLiteral("go-previous-view"); 0511 } 0512 0513 mNextTab = new QAction(QIcon::fromTheme(nextIcon), i18n("&Next Server"), this); 0514 actionCollection()->setDefaultShortcuts(mNextTab, nextShortcut); 0515 connect(mNextTab, &QAction::triggered, this, &RuqolaMainWindow::showNextView); 0516 actionCollection()->addAction(QStringLiteral("next_tab"), mNextTab); 0517 0518 mPreviewTab = new QAction(QIcon::fromTheme(prevIcon), i18n("&Previous Server"), this); 0519 actionCollection()->setDefaultShortcuts(mPreviewTab, prevShortcut); 0520 connect(mPreviewTab, &QAction::triggered, this, &RuqolaMainWindow::showPreviousView); 0521 actionCollection()->addAction(QStringLiteral("previous_tab"), mPreviewTab); 0522 0523 { 0524 auto action = new QWidgetAction(this); 0525 action->setText(i18n("Status")); 0526 auto container = new QWidget(this); 0527 // use the same font as other toolbar buttons 0528 container->setFont(qApp->font("QToolButton")); 0529 action->setDefaultWidget(container); 0530 auto layout = new QHBoxLayout(container); 0531 layout->setContentsMargins({}); 0532 auto label = new QLabel(i18n("Status:"), container); 0533 label->setObjectName(QStringLiteral("label")); 0534 layout->addWidget(label); 0535 0536 mStatusComboBox = new StatusCombobox(container); 0537 mStatusComboBox->setObjectName(QStringLiteral("mStatusComboBox")); 0538 layout->addWidget(mStatusComboBox); 0539 connect(mStatusComboBox, &StatusCombobox::currentIndexChanged, this, &RuqolaMainWindow::slotStatusChanged); 0540 connect(mStatusComboBox, &StatusCombobox::currentIndexChanged, this, &RuqolaMainWindow::slotUpdateStatusMenu); 0541 0542 mStatus = action; 0543 connect(mStatus, &QAction::triggered, mStatusComboBox, &QComboBox::showPopup); 0544 ac->addAction(QStringLiteral("status"), mStatus); 0545 } 0546 0547 { 0548 QList<QAction *> listActions; 0549 auto act = new QAction(i18n("Previous Selected Channel"), this); 0550 ac->setDefaultShortcut(act, QKeySequence(Qt::CTRL | Qt::Key_Tab)); 0551 ac->addAction(QStringLiteral("previous_channel"), act); 0552 listActions.append(act); 0553 0554 connect(act, &QAction::triggered, this, &RuqolaMainWindow::undoSwitchChannel); 0555 0556 act = new QAction(i18n("Next Selected Channel"), this); 0557 ac->addAction(QStringLiteral("next_channel"), act); 0558 QKeyCombination combinationKeys(Qt::CTRL | Qt::SHIFT, Qt::Key_Tab); 0559 ac->setDefaultShortcut(act, combinationKeys); 0560 connect(act, &QAction::triggered, this, &RuqolaMainWindow::redoSwitchChannel); 0561 listActions.append(act); 0562 0563 mSwitchChannelTreeManager->addActions(listActions); 0564 } 0565 0566 if (menuBar()) { 0567 mHamburgerMenu = KStandardAction::hamburgerMenu(nullptr, nullptr, actionCollection()); 0568 mHamburgerMenu->setShowMenuBarAction(mShowMenuBarAction); 0569 mHamburgerMenu->setMenuBar(menuBar()); 0570 connect(mHamburgerMenu, &KHamburgerMenu::aboutToShowMenu, this, [this]() { 0571 updateHamburgerMenu(); 0572 // Immediately disconnect. We only need to run this once, but on demand. 0573 // NOTE: The nullptr at the end disconnects all connections between 0574 // q and mHamburgerMenu's aboutToShowMenu signal. 0575 disconnect(mHamburgerMenu, &KHamburgerMenu::aboutToShowMenu, this, nullptr); 0576 }); 0577 } 0578 0579 auto manager = new KColorSchemeManager(this); 0580 ac->addAction(QStringLiteral("colorscheme_menu"), KColorSchemeMenu::createMenu(manager, this)); 0581 0582 mShowFullScreenAction = KStandardAction::fullScreen(nullptr, nullptr, this, ac); 0583 ac->setDefaultShortcut(mShowFullScreenAction, Qt::Key_F11); 0584 connect(mShowFullScreenAction, &QAction::toggled, this, &RuqolaMainWindow::slotFullScreen); 0585 0586 mShowNotifyHistory = new QAction(QIcon::fromTheme(QStringLiteral("notifications")), i18n("Show Notify History"), this); 0587 connect(mShowNotifyHistory, &QAction::triggered, this, &RuqolaMainWindow::slotOpenNotificationHistory); 0588 ac->addAction(QStringLiteral("show_notify_history"), mShowNotifyHistory); 0589 0590 mShowRocketChatServerInfo = new QAction(i18n("Show RocketChat Information"), this); 0591 connect(mShowRocketChatServerInfo, &QAction::triggered, this, &RuqolaMainWindow::slotRocketChatInformation); 0592 ac->addAction(QStringLiteral("show_rocketchat_information"), mShowRocketChatServerInfo); 0593 0594 mRoomAvatar = new QAction(i18n("Show Room Avatar"), this); 0595 mRoomAvatar->setCheckable(true); 0596 connect(mRoomAvatar, &QAction::triggered, this, &RuqolaMainWindow::slotShowRoomAvatar); 0597 ac->addAction(QStringLiteral("room_avatar"), mRoomAvatar); 0598 0599 mRoomFavorite = new QAction(i18n("Show Favorite Room"), this); 0600 mRoomFavorite->setCheckable(true); 0601 connect(mRoomFavorite, &QAction::triggered, this, &RuqolaMainWindow::slotShowFavoriteRoom); 0602 ac->addAction(QStringLiteral("room_favorite"), mRoomFavorite); 0603 0604 auto showWhatsNewAction = new QAction(QIcon::fromTheme(QStringLiteral("ruqola")), i18n("What's new"), this); 0605 ac->addAction(QStringLiteral("whatsnew_ruqola"), showWhatsNewAction); 0606 connect(showWhatsNewAction, &QAction::triggered, this, &RuqolaMainWindow::slotWhatsNew); 0607 0608 mImportAccountsAction = new QAction(QIcon::fromTheme(QStringLiteral("document-import")), i18n("Import Accounts"), this); 0609 connect(mImportAccountsAction, &QAction::triggered, this, &RuqolaMainWindow::slotImportAccounts); 0610 ac->addAction(QStringLiteral("import_accounts"), mImportAccountsAction); 0611 0612 mExportAccountsAction = new QAction(QIcon::fromTheme(QStringLiteral("document-export")), i18n("Export Accounts"), this); 0613 connect(mExportAccountsAction, &QAction::triggered, this, &RuqolaMainWindow::slotExportAccounts); 0614 ac->addAction(QStringLiteral("export_accounts"), mExportAccountsAction); 0615 0616 auto messageStyleAction = new MessageStyleLayoutMenu(this); 0617 ac->addAction(QStringLiteral("message_style"), messageStyleAction); 0618 connect(messageStyleAction, &MessageStyleLayoutMenu::styleChanged, this, &RuqolaMainWindow::slotMessageStyleChanged); 0619 } 0620 0621 void RuqolaMainWindow::slotMessageStyleChanged() 0622 { 0623 Q_EMIT ColorsAndMessageViewStyle::self().needUpdateMessageStyle(); 0624 } 0625 0626 void RuqolaMainWindow::slotWhatsNew() 0627 { 0628 WhatsNewDialog dlg(this); 0629 dlg.updateInformations(); 0630 dlg.exec(); 0631 } 0632 0633 void RuqolaMainWindow::showNextView() 0634 { 0635 mAccountOverviewWidget->showNextView(); 0636 } 0637 0638 void RuqolaMainWindow::showPreviousView() 0639 { 0640 mAccountOverviewWidget->showPreviousView(); 0641 } 0642 0643 void RuqolaMainWindow::slotClearAccountAlerts() 0644 { 0645 if (auto acct = mAccountManager->account()) { 0646 acct->clearAllUnreadMessages(); 0647 } 0648 } 0649 0650 void RuqolaMainWindow::slotCreateTeam() 0651 { 0652 QPointer<CreateNewChannelDialog> dlg = new CreateNewChannelDialog(mCurrentRocketChatAccount, this); 0653 dlg->setWindowTitle(i18nc("@title:window", "Create Team")); 0654 CreateNewChannelWidget::Features flags; 0655 if (mCurrentRocketChatAccount->broadCastEnabled()) { 0656 flags |= CreateNewChannelWidget::Feature::BroadCast; 0657 } 0658 if (mCurrentRocketChatAccount->encryptionEnabled()) { 0659 flags |= CreateNewChannelWidget::Feature::Encrypted; 0660 } 0661 dlg->setFeatures(flags); 0662 if (dlg->exec()) { 0663 RocketChatRestApi::CreateChannelTeamInfo teamInfo = dlg->channelInfo(true); 0664 teamInfo.infoType = RocketChatRestApi::CreateChannelTeamInfo::CreateInfoType::Team; 0665 auto job = new RocketChatRestApi::TeamsCreateJob(this); 0666 job->setTeamsCreateJobInfo(teamInfo); 0667 mCurrentRocketChatAccount->restApi()->initializeRestApiJob(job); 0668 connect(job, &RocketChatRestApi::TeamsCreateJob::teamCreateDone, this, []() { 0669 qCDebug(RUQOLAWIDGETS_LOG) << " teamCreateDone"; 0670 // TODO switch to new team ? 0671 }); 0672 if (!job->start()) { 0673 qCWarning(RUQOLAWIDGETS_LOG) << "Impossible to start TeamsCreateJob"; 0674 } 0675 } 0676 delete dlg; 0677 } 0678 0679 void RuqolaMainWindow::slotCreateDiscussion() 0680 { 0681 CreateNewDiscussionDialog dlg(mCurrentRocketChatAccount, this); 0682 dlg.exec(); 0683 } 0684 0685 void RuqolaMainWindow::slotCreateDirectMessages() 0686 { 0687 CreateDirectMessagesDialog dlg(mCurrentRocketChatAccount, this); 0688 dlg.exec(); 0689 } 0690 0691 void RuqolaMainWindow::slotCreateNewChannel() 0692 { 0693 QPointer<CreateNewChannelDialog> dlg = new CreateNewChannelDialog(mCurrentRocketChatAccount, this); 0694 CreateNewChannelWidget::Features flags; 0695 if (mCurrentRocketChatAccount->broadCastEnabled()) { 0696 flags |= CreateNewChannelWidget::Feature::BroadCast; 0697 } 0698 if (mCurrentRocketChatAccount->encryptionEnabled()) { 0699 flags |= CreateNewChannelWidget::Feature::Encrypted; 0700 } 0701 dlg->setFeatures(flags); 0702 if (dlg->exec()) { 0703 RocketChatRestApi::CreateChannelTeamInfo info = dlg->channelInfo(false); 0704 info.infoType = RocketChatRestApi::CreateChannelTeamInfo::CreateInfoType::Channel; 0705 mCurrentRocketChatAccount->createNewChannel(info); 0706 } 0707 delete dlg; 0708 } 0709 0710 void RuqolaMainWindow::slotConfigure() 0711 { 0712 QPointer<ConfigureSettingsDialog> dlg = new ConfigureSettingsDialog(this); 0713 if (dlg->exec()) { 0714 if (RuqolaGlobalConfig::self()->useCustomFont()) { 0715 qApp->setFont(RuqolaGlobalConfig::self()->generalFont()); 0716 } else { 0717 qApp->setFont(QFontDatabase::systemFont(QFontDatabase::GeneralFont)); 0718 } 0719 0720 mAccountOverviewWidget->updateButtons(); 0721 createSystemTray(); 0722 Q_EMIT Ruqola::self()->translatorMenuChanged(); 0723 } 0724 delete dlg; 0725 } 0726 0727 void RuqolaMainWindow::slotAuthentication(AuthenticationManager::AuthMethodType type) 0728 { 0729 qDebug() << "Not implement plugin " << type; 0730 } 0731 0732 void RuqolaMainWindow::slotAddServer() 0733 { 0734 QPointer<CreateNewServerDialog> dlg = new CreateNewServerDialog(this); 0735 connect(dlg, &CreateNewServerDialog::authentication, this, &RuqolaMainWindow::slotAuthentication); 0736 const QStringList lst = mAccountManager->accountsName(); 0737 dlg->setExistingAccountName(lst); 0738 if (dlg->exec()) { 0739 const AccountManager::AccountManagerInfo info = dlg->accountInfo(); 0740 mAccountManager->addAccount(std::move(info)); 0741 } 0742 delete dlg; 0743 } 0744 0745 void RuqolaMainWindow::slotServerInfo() 0746 { 0747 ServerInfoDialog dlg(mCurrentRocketChatAccount, this); 0748 dlg.exec(); 0749 } 0750 0751 void RuqolaMainWindow::slotLogout() 0752 { 0753 mCurrentRocketChatAccount->logOut(); 0754 } 0755 0756 void RuqolaMainWindow::slotSelectNextUnreadChannel() 0757 { 0758 mMainWidget->selectNextUnreadChannel(); 0759 } 0760 0761 void RuqolaMainWindow::slotUnreadOnTop(bool checked) 0762 { 0763 mCurrentRocketChatAccount->setSortUnreadOnTop(checked); 0764 } 0765 0766 void RuqolaMainWindow::slotRoomListSortByLastMessage() 0767 { 0768 mCurrentRocketChatAccount->setRoomListSortOrder(OwnUserPreferences::RoomListSortOrder::ByLastMessage); 0769 } 0770 0771 void RuqolaMainWindow::slotRoomListSortAlphabetically() 0772 { 0773 mCurrentRocketChatAccount->setRoomListSortOrder(OwnUserPreferences::RoomListSortOrder::Alphabetically); 0774 } 0775 0776 void RuqolaMainWindow::slotShowDatabaseMessages() 0777 { 0778 // Use only when we want to debug and has database support 0779 ExploreDatabaseDialog dlg(mCurrentRocketChatAccount, this); 0780 dlg.exec(); 0781 } 0782 0783 void RuqolaMainWindow::slotShowPermissions() 0784 { 0785 ExplorePermissionsDialog dlg(this); 0786 dlg.setPermissions(mCurrentRocketChatAccount->permissions()); 0787 dlg.setOWnRoles(mCurrentRocketChatAccount->ownUserPermission()); 0788 dlg.exec(); 0789 } 0790 0791 void RuqolaMainWindow::slotShowServerInfo() 0792 { 0793 ServerErrorInfoMessageHistoryDialog dlg(this); 0794 dlg.addServerList(Ruqola::self()->accountManager()->accountNamesSorted()); 0795 dlg.exec(); 0796 } 0797 0798 void RuqolaMainWindow::slotShowLog() 0799 { 0800 auto *room = mMainWidget->room(); 0801 if (room) { 0802 QTemporaryFile tempFile(QDir::tempPath() + QStringLiteral("/XXXXXX.log.txt")); 0803 tempFile.setAutoRemove(false); 0804 if (tempFile.open()) { 0805 LocalMessageLogger logger; 0806 if (logger.saveToFile(tempFile, mCurrentRocketChatAccount->accountName(), room->displayFName())) { 0807 const QString fileName = tempFile.fileName(); 0808 tempFile.close(); 0809 auto job = new KIO::OpenUrlJob(QUrl::fromLocalFile(fileName), this); 0810 job->setUiDelegate(KIO::createDefaultJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this)); 0811 job->setDeleteTemporaryFile(true); 0812 job->start(); 0813 } else { 0814 KMessageBox::information(this, i18n("Impossible to open log."), i18n("Show Log")); 0815 } 0816 } 0817 } 0818 } 0819 0820 void RuqolaMainWindow::slotMissingChannelPassword(const RocketChatRestApi::ChannelGroupBaseJob::ChannelGroupInfo &channelInfo) 0821 { 0822 QPointer<ChannelPasswordDialog> dlg = new ChannelPasswordDialog(this); 0823 // TODO add channel name! 0824 if (dlg->exec()) { 0825 // FIXME channelinfo 0826 mCurrentRocketChatAccount->joinRoom(channelInfo.identifier, dlg->password()); 0827 } 0828 delete dlg; 0829 } 0830 0831 void RuqolaMainWindow::slotLoginPageActivated(bool loginPageActivated) 0832 { 0833 mCreateNewChannel->setEnabled(!loginPageActivated && canCreateChannels()); 0834 mCreateDirectMessages->setEnabled(!loginPageActivated && canCreateDirectMessages()); 0835 mLogout->setEnabled(!loginPageActivated); 0836 mClearAlerts->setEnabled(!loginPageActivated); 0837 mMyAccount->setEnabled(!loginPageActivated); 0838 mStatus->setEnabled(!loginPageActivated); 0839 mCreateDiscussion->setEnabled(!loginPageActivated); 0840 mCreateTeam->setEnabled(!loginPageActivated && canCreateTeams()); 0841 mDirectory->setEnabled(!loginPageActivated); 0842 mNextUnreadChannel->setEnabled(!loginPageActivated); 0843 mShowLog->setEnabled(!loginPageActivated); 0844 mShowRocketChatServerInfo->setVisible(!loginPageActivated && hasBannerInfo()); 0845 mRoomAvatar->setEnabled(!loginPageActivated); 0846 mUnreadOnTop->setEnabled(!loginPageActivated); 0847 mRoomListSortByLastMessage->setEnabled(!loginPageActivated); 0848 mRoomListSortAlphabetically->setEnabled(!loginPageActivated); 0849 mRoomFavorite->setEnabled(!loginPageActivated); 0850 if (mContextStatusMenu) { 0851 mContextStatusMenu->menuAction()->setVisible(!loginPageActivated); 0852 } 0853 if (mShowDatabaseMessages) { 0854 mShowDatabaseMessages->setEnabled(!loginPageActivated); 0855 } 0856 if (mShowPermissions) { 0857 mShowPermissions->setEnabled(!loginPageActivated); 0858 } 0859 } 0860 0861 void RuqolaMainWindow::slotConfigureNotifications() 0862 { 0863 KNotifyConfigWidget::configure(this); 0864 } 0865 0866 void RuqolaMainWindow::slotRegisterNewUser() 0867 { 0868 QPointer<RegisterUserDialog> dlg = new RegisterUserDialog(this); 0869 connect(dlg, &RegisterUserDialog::registerNewAccount, this, [this, dlg]() { 0870 mCurrentRocketChatAccount->registerNewUser(dlg->registerUserInfo()); 0871 }); 0872 dlg->exec(); 0873 delete dlg; 0874 } 0875 0876 void RuqolaMainWindow::slotRegisterUserSuccessed() 0877 { 0878 KMessageBox::information( 0879 this, 0880 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."), 0881 i18n("Register New User")); 0882 } 0883 0884 void RuqolaMainWindow::slotConfigureMyAccount() 0885 { 0886 MyAccountConfigureDialog dlg(mCurrentRocketChatAccount, this); 0887 dlg.initialize(); 0888 dlg.exec(); 0889 } 0890 0891 void RuqolaMainWindow::slotAdministrator() 0892 { 0893 AdministratorDialog dlg(mCurrentRocketChatAccount, this); 0894 dlg.initialize(); 0895 dlg.exec(); 0896 } 0897 0898 void RuqolaMainWindow::slotAdministratorServerSettings() 0899 { 0900 AdministratorSettingsDialog dlg(mCurrentRocketChatAccount, this); 0901 dlg.loadSettings(); 0902 dlg.exec(); 0903 } 0904 0905 void RuqolaMainWindow::slotDirectory() 0906 { 0907 auto dlg = new DirectoryDialog(mCurrentRocketChatAccount, this); 0908 dlg->fillTabs(); 0909 dlg->show(); 0910 } 0911 0912 bool RuqolaMainWindow::queryClose() 0913 { 0914 if (qApp->isSavingSession() || mReallyClose || !mNotification) { 0915 return true; 0916 } 0917 hide(); 0918 return false; 0919 } 0920 0921 void RuqolaMainWindow::slotClose() 0922 { 0923 mReallyClose = true; 0924 close(); 0925 } 0926 0927 void RuqolaMainWindow::createSystemTray() 0928 { 0929 #if !defined(Q_OS_IOS) 0930 if (!RuqolaGlobalConfig::self()->enableSystemTray()) { 0931 delete mNotification; 0932 mNotification = nullptr; 0933 return; 0934 } 0935 if (!mNotification) { 0936 mNotification = new Notification(this); 0937 auto trayMenu = mNotification->contextMenu(); 0938 0939 mContextStatusMenu = mNotification->contextMenu()->addMenu(i18nc("@item:inmenu Instant message presence status", "Status")); 0940 mContextStatusMenu->menuAction()->setVisible(false); 0941 trayMenu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::Preferences))); 0942 trayMenu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::ConfigureNotifications))); 0943 // Create systray to show notifications on Desktop 0944 connect(mNotification, &Notification::alert, this, [this]() { 0945 QApplication::alert(this, 0); 0946 }); 0947 } 0948 #endif 0949 } 0950 0951 void RuqolaMainWindow::slotStatusChanged() 0952 { 0953 // const auto currentStatusInfo = mCurrentRocketChatAccount->statusModel()->currentStatusInfo(); 0954 User::PresenceStatus status = mStatusComboBox->status(); 0955 QString messageStatus; // = currentStatusInfo.statusStr; 0956 if (status == User::PresenceStatus::Unknown) { 0957 QPointer<ModifyStatusDialog> dlg = new ModifyStatusDialog(this); 0958 const auto currentStatusInfo = mCurrentRocketChatAccount->statusModel()->currentStatusInfo(); 0959 dlg->setMessageStatus(mCurrentRocketChatAccount->statusModel()->customText()); 0960 dlg->setStatus(currentStatusInfo.status); 0961 if (dlg->exec()) { 0962 messageStatus = dlg->messageStatus(); 0963 status = dlg->status(); 0964 delete dlg; 0965 } else { 0966 mStatusComboBox->setStatus(mCurrentRocketChatAccount->statusModel()->currentUserStatus()); 0967 delete dlg; 0968 return; 0969 } 0970 } 0971 mCurrentRocketChatAccount->setDefaultStatus(status, messageStatus); 0972 } 0973 0974 void RuqolaMainWindow::slotUpdateStatusMenu() 0975 { 0976 if (mContextStatusMenu) { 0977 const User::PresenceStatus status = mStatusComboBox->status(); 0978 mContextStatusMenu->setTitle(Utils::displaytextFromPresenceStatus(status)); 0979 mContextStatusMenu->setIcon(QIcon::fromTheme(Utils::iconFromPresenceStatus(status))); 0980 } 0981 } 0982 0983 void RuqolaMainWindow::slotUpdateCustomUserStatus() 0984 { 0985 mStatusProxyModel->sort(0); 0986 0987 if (mContextStatusMenu) { 0988 // mContextStatusMenu->menuAction()->setVisible(true); 0989 mContextStatusMenu->clear(); 0990 0991 for (int i = 0; i < mStatusProxyModel->rowCount(); i++) { 0992 const QModelIndex index = mStatusProxyModel->index(i, 0); 0993 QAction *action = mContextStatusMenu->addAction(index.data(Qt::DisplayRole).toString()); 0994 action->setIcon(index.data(Qt::DecorationRole).value<QIcon>()); 0995 0996 connect(action, &QAction::triggered, this, [this, index] { 0997 mStatusComboBox->setStatus(index.data(StatusModel::StatusRoles::Status).value<User::PresenceStatus>()); 0998 }); 0999 } 1000 } 1001 } 1002 1003 void RuqolaMainWindow::slotMessageUrlNotFound(const QString &str) 1004 { 1005 KMessageBox::information(this, str, i18n("Message")); 1006 } 1007 1008 void RuqolaMainWindow::slotHistorySwitchChannel(const QString &identifier) 1009 { 1010 Q_EMIT mCurrentRocketChatAccount->selectRoomByRoomIdRequested(identifier); 1011 } 1012 1013 void RuqolaMainWindow::undoSwitchChannel() 1014 { 1015 mSwitchChannelTreeManager->selectForward(); 1016 } 1017 1018 void RuqolaMainWindow::redoSwitchChannel() 1019 { 1020 mSwitchChannelTreeManager->selectBackward(); 1021 } 1022 1023 void RuqolaMainWindow::slotToggleMenubar(bool dontShowWarning) 1024 { 1025 if (menuBar()) { 1026 if (mShowMenuBarAction->isChecked()) { 1027 menuBar()->show(); 1028 } else { 1029 if (!dontShowWarning && (!toolBar()->isVisible() || !toolBar()->actions().contains(mHamburgerMenu))) { 1030 const QString accel = mShowMenuBarAction->shortcut().toString(); 1031 KMessageBox::information(this, 1032 i18n("<qt>This will hide the menu bar completely." 1033 " You can show it again by typing %1.</qt>", 1034 accel), 1035 i18n("Hide menu bar"), 1036 QStringLiteral("HideMenuBarWarning")); 1037 } 1038 menuBar()->hide(); 1039 } 1040 RuqolaGlobalConfig::self()->setShowMenuBar(mShowMenuBarAction->isChecked()); 1041 RuqolaGlobalConfig::self()->save(); 1042 } 1043 } 1044 1045 void RuqolaMainWindow::updateHamburgerMenu() 1046 { 1047 auto menu = new QMenu(this); 1048 menu->addAction(actionCollection()->action(QStringLiteral("add_server"))); 1049 menu->addSeparator(); 1050 menu->addAction(actionCollection()->action(QStringLiteral("configure_my_account"))); 1051 menu->addSeparator(); 1052 menu->addAction(actionCollection()->action(QStringLiteral("directory"))); 1053 menu->addSeparator(); 1054 menu->addAction(actionCollection()->action(QStringLiteral("logout"))); 1055 menu->addSeparator(); 1056 menu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::Quit))); 1057 mHamburgerMenu->setMenu(menu); 1058 } 1059 1060 void RuqolaMainWindow::slotFullScreen(bool t) 1061 { 1062 KToggleFullScreenAction::setFullScreen(this, t); 1063 QMenuBar *mb = menuBar(); 1064 if (t) { 1065 auto b = new QToolButton(mb); 1066 b->setDefaultAction(mShowFullScreenAction); 1067 b->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Ignored)); 1068 b->setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont)); 1069 mb->setCornerWidget(b, Qt::TopRightCorner); 1070 b->setVisible(true); 1071 b->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); 1072 } else { 1073 QWidget *w = mb->cornerWidget(Qt::TopRightCorner); 1074 if (w) { 1075 w->deleteLater(); 1076 } 1077 } 1078 } 1079 1080 void RuqolaMainWindow::slotShowNotifyMessage(const QString &accountName, const QString &messageId, const QString &roomId) 1081 { 1082 Ruqola::self()->setCurrentAccount(accountName); 1083 Q_EMIT mCurrentRocketChatAccount->selectRoomByRoomIdRequested(roomId, messageId); 1084 } 1085 1086 void RuqolaMainWindow::slotOpenNotificationHistory() 1087 { 1088 mNotificationToolButton->hide(); 1089 NotificationHistoryDialog dlg(this); 1090 dlg.addServerList(Ruqola::self()->accountManager()->accountNamesSorted()); 1091 connect(&dlg, &NotificationHistoryDialog::showNotifyMessage, this, &RuqolaMainWindow::slotShowNotifyMessage); 1092 dlg.exec(); 1093 } 1094 1095 void RuqolaMainWindow::slotRocketChatInformation() 1096 { 1097 BannerInfoDialog dlg(mCurrentRocketChatAccount, this); 1098 dlg.exec(); 1099 } 1100 1101 void RuqolaMainWindow::slotShowRoomAvatar(bool checked) 1102 { 1103 mCurrentRocketChatAccount->setShowRoomAvatar(checked); 1104 } 1105 1106 void RuqolaMainWindow::slotShowFavoriteRoom(bool checked) 1107 { 1108 mCurrentRocketChatAccount->setShowFavoriteRoom(checked); 1109 } 1110 1111 void RuqolaMainWindow::slotImportAccounts() 1112 { 1113 ImportDataWizard dlg(this); 1114 dlg.exec(); 1115 } 1116 1117 void RuqolaMainWindow::slotExportAccounts() 1118 { 1119 ExportDataWizard dlg(this); 1120 dlg.exec(); 1121 } 1122 1123 #include "moc_ruqolamainwindow.cpp"