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