File indexing completed on 2024-04-21 05:46:24
0001 /* 0002 SPDX-FileCopyrightText: 2007 Nicolas Ternisien <nicolas.ternisien@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "mainWindow.h" 0008 0009 // Qt includes 0010 #include <QAction> 0011 #include <QIcon> 0012 #include <QList> 0013 0014 // KDE includes 0015 #include <KActionCollection> 0016 #include <KActionMenu> 0017 #include <KLocalizedString> 0018 #include <KStandardAction> 0019 #include <KStandardShortcut> 0020 0021 // Project includes 0022 #include "ksystemlogConfig.h" 0023 0024 #include "statusBar.h" 0025 0026 #include "configurationDialog.h" 0027 #include "logViewWidget.h" 0028 #include "tabLogViewsWidget.h" 0029 0030 #include "loggerDialog.h" 0031 0032 #include "detailDialog.h" 0033 0034 #include "logManager.h" 0035 #include "logModeConfiguration.h" 0036 0037 #include "logFile.h" 0038 #include "logLevel.h" 0039 #include "logMode.h" 0040 0041 #include "ksystemlog_debug.h" 0042 0043 #include "logModePluginsLoader.h" 0044 #include "logViewSearchWidget.h" 0045 #include "view.h" 0046 0047 #include "globals.h" 0048 0049 namespace KSystemLog 0050 { 0051 MainWindow::MainWindow() 0052 : KXmlGuiWindow(nullptr) 0053 { 0054 qCDebug(KSYSTEMLOG) << "Starting KSystemLog..."; 0055 0056 // Load log modes plugins 0057 loadLogModePlugins(); 0058 0059 // Create the GUI from XML configuration 0060 qCDebug(KSYSTEMLOG) << "Creating Gui..."; 0061 createGUI(); 0062 0063 // TODO Improve the status bar to add a custom widget which shows an history of latest message, and add a 0064 // LogLevel for each ones 0065 // Initialize the Status Bar 0066 setupStatusBar(); 0067 0068 // Setup the main tab bar 0069 setupTabLogViews(); 0070 0071 // Setup the Actions 0072 setupActions(); 0073 0074 // Setup toolbar log actions, needs to be called before setupGUI() 0075 setupLogActions(); 0076 0077 // Apply the create the main window and ask the mainwindow to 0078 // automatically save settings if changed: window size, toolbar 0079 // position, icon size, etc. Also to add actions for the statusbar 0080 // toolbar, and keybindings if necessary. 0081 qCDebug(KSYSTEMLOG) << "Setup Gui..."; 0082 setupGUI(); 0083 0084 // Setup Logs menu, needs to be called after setupGUI() 0085 setupLogModeMenu(); 0086 0087 // Apply the saved mainwindow settings, if any, and ask the main window 0088 // to automatically save settings if changed: window size, tool bar 0089 // position, icon size, etc. 0090 setAutoSaveSettings(); 0091 0092 mConfigurationDialog = new ConfigurationDialog(this); 0093 connect(mConfigurationDialog, &ConfigurationDialog::configurationSaved, mTabs, &TabLogViewsWidget::reloadAll); 0094 0095 // Show KSystemLog before loading the first log file 0096 show(); 0097 0098 LogManager *firstLogManager = mTabs->createTab(); 0099 0100 // Load selected mode only if its log files exist. 0101 const QString &startupLogMode = KSystemLogConfig::startupLogMode(); 0102 if (!startupLogMode.isEmpty()) { 0103 LogMode *mode = Globals::instance().findLogMode(startupLogMode); 0104 if (mode) { 0105 if (mode->filesExist()) { 0106 mTabs->load(mode, firstLogManager); 0107 } else { 0108 qCWarning(KSYSTEMLOG) << mode->name() << "is selected by default, but log files do not exist."; 0109 } 0110 } 0111 } 0112 0113 // Set focus to the list 0114 firstLogManager->usedView()->logViewWidget()->setFocus(); 0115 0116 const auto logModes = Globals::instance().logModes(); 0117 for (LogMode *logMode : logModes) { 0118 connect(logMode, &LogMode::menuChanged, this, &MainWindow::recreateActions); 0119 } 0120 } 0121 0122 void MainWindow::loadLogModePlugins() 0123 { 0124 LogModePluginsLoader pluginsLoader(this); 0125 pluginsLoader.loadPlugins(); 0126 } 0127 0128 void MainWindow::setupTabLogViews() 0129 { 0130 qCDebug(KSYSTEMLOG) << "Creating tab widget..."; 0131 0132 mTabs = new TabLogViewsWidget(this); 0133 0134 connect(mTabs, &TabLogViewsWidget::statusBarChanged, this, &MainWindow::changeStatusBar); 0135 connect(mTabs, &TabLogViewsWidget::logManagerCreated, this, &MainWindow::prepareCreatedLogManager); 0136 connect(mTabs, &QTabWidget::currentChanged, this, &MainWindow::changeCurrentTab); 0137 0138 setCentralWidget(mTabs); 0139 } 0140 0141 MainWindow::~MainWindow() 0142 { 0143 delete mLoggedDialog; 0144 0145 delete mDetailDialog; 0146 0147 delete mConfigurationDialog; 0148 } 0149 0150 void MainWindow::setupStatusBar() 0151 { 0152 mStatusBar = new KSystemLog::StatusBar(this); 0153 0154 setStatusBar(mStatusBar); 0155 } 0156 0157 void MainWindow::prepareCreatedLogManager(LogManager *manager) 0158 { 0159 qCDebug(KSYSTEMLOG) << "Connecting to actions the new log manager and view..."; 0160 0161 // Contextual menu Log Manager signals 0162 0163 manager->usedView()->logViewWidget()->addAction(mReloadAction); 0164 manager->usedView()->logViewWidget()->addAction(mSelectAllAction); 0165 0166 auto separator = new QAction(this); 0167 separator->setSeparator(true); 0168 manager->usedView()->logViewWidget()->addAction(separator); 0169 0170 manager->usedView()->logViewWidget()->addAction(mCopyAction); 0171 manager->usedView()->logViewWidget()->addAction(mSaveAction); 0172 manager->usedView()->logViewWidget()->addAction(mSendMailAction); 0173 0174 separator = new QAction(this); 0175 separator->setSeparator(true); 0176 manager->usedView()->logViewWidget()->addAction(separator); 0177 0178 manager->usedView()->logViewWidget()->addAction(mTooltipEnabledAction); 0179 manager->usedView()->logViewWidget()->addAction(mNewLinesDisplayedAction); 0180 0181 separator = new QAction(this); 0182 separator->setSeparator(true); 0183 manager->usedView()->logViewWidget()->addAction(separator); 0184 0185 manager->usedView()->logViewWidget()->addAction(mDetailAction); 0186 0187 // Log Manager and View signals 0188 connect(manager, &LogManager::windowTitleChanged, this, &MainWindow::changeWindowTitle); 0189 connect(manager, &LogManager::statusBarChanged, this, &MainWindow::changeStatusBar); 0190 connect(manager, &LogManager::logUpdated, this, &MainWindow::updateStatusBar); 0191 connect(manager, &LogManager::reloaded, this, &MainWindow::changeCurrentTab); 0192 0193 connect(manager->usedView(), &View::searchFilterChanged, this, &MainWindow::updateStatusBar); 0194 connect(manager->usedView()->logViewWidget(), &QTreeWidget::itemDoubleClicked, this, &MainWindow::showDetailsDialog); 0195 connect(manager->usedView()->logViewWidget(), &QTreeWidget::itemSelectionChanged, this, &MainWindow::updateSelection); 0196 connect(manager->usedView()->logViewWidget()->model(), &LogViewModel::processingMultipleInsertions, this, &MainWindow::updateReloading); 0197 0198 // Correctly initialize the Status Bar 0199 updateStatusBar(); 0200 } 0201 0202 void MainWindow::updateDetailDialog() 0203 { 0204 LogManager *currentManager = mTabs->activeLogManager(); 0205 if (mDetailDialog) { 0206 mDetailDialog->selectionChanged(currentManager->usedView()->logViewWidget()); 0207 } 0208 } 0209 0210 void MainWindow::updateSelection() 0211 { 0212 // qCDebug(KSYSTEMLOG) << "Updating selection..."; 0213 0214 LogManager *currentLogManager = mTabs->activeLogManager(); 0215 0216 updateDetailDialog(); 0217 0218 bool const selection = currentLogManager->usedView()->logViewWidget()->hasItemsSelected(); 0219 0220 mCopyAction->setEnabled(selection); 0221 mSaveAction->setEnabled(selection); 0222 mDetailAction->setEnabled(selection); 0223 mSendMailAction->setEnabled(selection); 0224 mPrintAction->setEnabled(selection); 0225 mPrintPreviewAction->setEnabled(selection); 0226 } 0227 0228 void MainWindow::updateReloading() 0229 { 0230 View *currentView = mTabs->activeLogManager()->usedView(); 0231 0232 const bool enabled = !currentView->logViewWidget()->model()->isProcessingMultipleInsertions(); 0233 0234 mReloadAction->setEnabled(enabled); 0235 mResumePauseAction->setEnabled(enabled); 0236 mFindAction->setEnabled(enabled); 0237 mFindNextAction->setEnabled(enabled); 0238 mFindPreviousAction->setEnabled(enabled); 0239 0240 // Enables/Disables all Log Mode actions 0241 // logModesActionGroup->setEnabled(enabled); 0242 0243 mTabs->changeReloadingTab(currentView, !enabled); 0244 0245 // Enables/Disables all Log Mode menus (useful for multiple actions menus) 0246 const auto logModeActions{Globals::instance().logModeActions()}; 0247 for (LogModeAction *logModeAction : logModeActions) { 0248 logModeAction->actionMenu()->setEnabled(enabled); 0249 } 0250 } 0251 0252 void MainWindow::closeEvent(QCloseEvent *event) 0253 { 0254 disconnect(mTabs, &QTabWidget::currentChanged, this, &MainWindow::changeCurrentTab); 0255 0256 LogManager *currentLogManager = mTabs->activeLogManager(); 0257 if (currentLogManager) { 0258 currentLogManager->stopWatching(); 0259 } 0260 qCDebug(KSYSTEMLOG) << "Saving configuration before exit..."; 0261 qCDebug(KSYSTEMLOG) << "Saving configuration before exit..."; 0262 // Write the config to the file 0263 KSystemLogConfig::self()->save(); 0264 KXmlGuiWindow::closeEvent(event); 0265 } 0266 0267 TabLogViewsWidget *MainWindow::tabs() 0268 { 0269 return mTabs; 0270 } 0271 0272 void MainWindow::showDetailsDialog() 0273 { 0274 // Create the Detail dialog if it was not created 0275 if (!mDetailDialog) { 0276 mDetailDialog = new DetailDialog(this); 0277 updateDetailDialog(); 0278 } 0279 0280 mDetailDialog->show(); 0281 } 0282 0283 void MainWindow::toggleItemTooltip(bool enabled) 0284 { 0285 KSystemLogConfig::setTooltipEnabled(enabled); 0286 0287 const auto logManagers{mTabs->logManagers()}; 0288 for (LogManager *manager : logManagers) { 0289 manager->usedView()->logViewWidget()->toggleToolTip(enabled); 0290 } 0291 } 0292 0293 void MainWindow::toggleNewLinesDisplaying(bool displayed) 0294 { 0295 KSystemLogConfig::setNewLinesDisplayed(displayed); 0296 } 0297 0298 void MainWindow::updateStatusBar() 0299 { 0300 qCDebug(KSYSTEMLOG) << "Updating status bar..."; 0301 0302 LogManager *currentManager = mTabs->activeLogManager(); 0303 0304 int const itemCount = currentManager->usedView()->logViewWidget()->itemCount(); 0305 int const notHiddenItemCount = currentManager->usedView()->logViewWidget()->notHiddenItemCount(); 0306 0307 if (itemCount == notHiddenItemCount) { 0308 mStatusBar->changeLineCountMessage(i18ncp("Total displayed lines", "1 line.", "%1 lines.", currentManager->usedView()->logViewWidget()->itemCount())); 0309 } else { 0310 mStatusBar->changeLineCountMessage( 0311 i18ncp("Line not hidden by search / Total displayed lines", "1 line / %2 total.", "%1 lines / %2 total.", notHiddenItemCount, itemCount)); 0312 } 0313 0314 mStatusBar->changeLastModification(currentManager->lastUpdate()); 0315 } 0316 0317 void MainWindow::toggleResumePauseParsing(bool paused) 0318 { 0319 qCDebug(KSYSTEMLOG) << "Pausing parsing : " << paused; 0320 0321 LogManager *currentLogManager = mTabs->activeLogManager(); 0322 if (currentLogManager) { 0323 currentLogManager->setParsingPaused(paused); 0324 } 0325 0326 qCDebug(KSYSTEMLOG) << "Parsing paused : " << paused; 0327 } 0328 0329 void MainWindow::changeResumePauseAction(bool paused) 0330 { 0331 if (paused) { 0332 mResumePauseAction->setText(i18n("Resu&me")); 0333 mResumePauseAction->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-start"))); 0334 mResumePauseAction->setToolTip(i18n("Resume the watching of the current log")); 0335 mResumePauseAction->setWhatsThis( 0336 i18n("Resumes the watching of the current log. This action is only available when the user has " 0337 "already paused the reading.")); 0338 mResumePauseAction->setChecked(true); 0339 actionCollection()->setDefaultShortcut(mResumePauseAction, Qt::CTRL | Qt::Key_M); 0340 } else { 0341 mResumePauseAction->setText(i18n("S&top")); 0342 mResumePauseAction->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-stop"))); 0343 mResumePauseAction->setToolTip(i18n("Pause the watching of the current log")); 0344 mResumePauseAction->setWhatsThis( 0345 i18n("Pauses the watching of the current log. This action is particularly useful when the system is " 0346 "writing too many lines to log files, causing KSystemLog to reload too frequently.")); 0347 mResumePauseAction->setChecked(false); 0348 actionCollection()->setDefaultShortcut(mResumePauseAction, Qt::CTRL | Qt::Key_P); 0349 } 0350 0351 // Be sure that the button will always have a good size 0352 const auto associatedWidgets{mResumePauseAction->associatedObjects()}; 0353 for (QObject *obj : associatedWidgets) { 0354 QWidget *widget = qobject_cast<QWidget *>(obj); 0355 0356 if (widget && (widget->sizeHint().width() > widget->size().width())) { 0357 widget->setMinimumSize(widget->sizeHint()); 0358 } 0359 } 0360 } 0361 0362 void MainWindow::fileOpen() 0363 { 0364 // Launch the actualizing 0365 mTabs->load(Globals::instance().findLogMode(QStringLiteral("openLogMode")), mTabs->activeLogManager()); 0366 } 0367 0368 void MainWindow::showConfigurationDialog() 0369 { 0370 qCDebug(KSYSTEMLOG) << "Showing configuration dialog..."; 0371 mConfigurationDialog->showConfiguration(); 0372 } 0373 0374 void MainWindow::showLogMessageDialog() 0375 { 0376 qCDebug(KSYSTEMLOG) << "Launching the Send message dialog box..."; 0377 0378 if (!mLoggedDialog) { 0379 mLoggedDialog = new LoggerDialog(this); 0380 } 0381 0382 mLoggedDialog->initialize(); 0383 mLoggedDialog->exec(); 0384 } 0385 0386 void MainWindow::changeStatusBar(const QString &text) 0387 { 0388 mStatusBar->changeMessage(text); 0389 } 0390 0391 void MainWindow::changeWindowTitle(const QString &text) 0392 { 0393 // Display this text on the caption 0394 setCaption(text); 0395 } 0396 0397 void MainWindow::changeCurrentTab() 0398 { 0399 qCDebug(KSYSTEMLOG) << "Tab has changed"; 0400 0401 LogManager *currentManager = mTabs->activeLogManager(); 0402 0403 if (!currentManager) { 0404 return; 0405 } 0406 0407 // If the tab changed, the selection changes too 0408 updateSelection(); 0409 0410 // Update the status bar 0411 updateStatusBar(); 0412 0413 // Updating the current reloading status 0414 updateReloading(); 0415 0416 bool const enabledReloading = !currentManager->usedView()->logViewWidget()->model()->isProcessingMultipleInsertions(); 0417 0418 bool enabledAction; 0419 // Change the title of the window 0420 if (!currentManager->logMode()) { 0421 changeWindowTitle(i18nc("Newly created tab", "Empty Log")); 0422 enabledAction = false; 0423 } else { 0424 changeWindowTitle(currentManager->title()); 0425 enabledAction = true; 0426 } 0427 0428 if (enabledReloading && enabledAction) { 0429 mReloadAction->setEnabled(true); 0430 mResumePauseAction->setEnabled(true); 0431 } else { 0432 mReloadAction->setEnabled(false); 0433 mResumePauseAction->setEnabled(false); 0434 } 0435 0436 // Update Resume/Pause action state 0437 if (currentManager->isParsingPaused()) { 0438 changeResumePauseAction(true); 0439 } else { 0440 changeResumePauseAction(false); 0441 } 0442 0443 // Updating Detail dialog 0444 updateDetailDialog(); 0445 0446 qCDebug(KSYSTEMLOG) << "Tab changing done"; 0447 } 0448 0449 /** 0450 * TODO Implements the session restoring 0451 * 0452 * The 'config' object points to the session managed 0453 * config file. anything you write here will be available 0454 * later when this app is restored 0455 */ 0456 void MainWindow::saveProperties(KConfigGroup & /*configuration*/) 0457 { 0458 qCDebug(KSYSTEMLOG) << "Saving properties..."; 0459 } 0460 0461 /** 0462 * TODO Implements the session restoring 0463 * 0464 * The 'config' object points to the session managed 0465 * config file. this function is automatically called whenever 0466 * the app is being restored. read in here whatever you wrote 0467 * in 'saveProperties' 0468 */ 0469 void MainWindow::readProperties(const KConfigGroup & /*configuration*/) 0470 { 0471 qCDebug(KSYSTEMLOG) << "Reading properties..."; 0472 } 0473 0474 void MainWindow::toggleFilterBar() 0475 { 0476 qCDebug(KSYSTEMLOG) << "Toggling filter bar..." << mFilterBarAction->isChecked(); 0477 0478 const auto logManagers{mTabs->logManagers()}; 0479 for (LogManager *manager : logManagers) { 0480 manager->usedView()->toggleLogViewFilter(mFilterBarAction->isChecked()); 0481 } 0482 0483 KSystemLogConfig::setToggleFilterBar(mFilterBarAction->isChecked()); 0484 } 0485 0486 void MainWindow::findNext() 0487 { 0488 showSearchBar(); 0489 mTabs->activeLogManager()->usedView()->logViewSearch()->findNext(); 0490 } 0491 0492 void MainWindow::findPrevious() 0493 { 0494 showSearchBar(); 0495 mTabs->activeLogManager()->usedView()->logViewSearch()->findPrevious(); 0496 } 0497 0498 void MainWindow::showSearchBar() 0499 { 0500 qCDebug(KSYSTEMLOG) << "Showing search bar..."; 0501 0502 LogManager *activeLogManager = mTabs->activeLogManager(); 0503 0504 const auto logManagers = mTabs->logManagers(); 0505 for (LogManager *manager : logManagers) { 0506 if (manager != activeLogManager) { 0507 manager->usedView()->toggleLogViewSearch(true); 0508 } 0509 } 0510 0511 // Be sure to display the view search of the active LogManager at last, and focus to it 0512 mTabs->activeLogManager()->usedView()->toggleLogViewSearch(true); 0513 } 0514 0515 void MainWindow::setupActions() 0516 { 0517 qCDebug(KSYSTEMLOG) << "Creating actions..."; 0518 0519 QAction *fileOpenAction = actionCollection()->addAction(KStandardAction::Open, this, SLOT(fileOpen())); 0520 fileOpenAction->setToolTip(i18n("Open a file in KSystemLog")); 0521 fileOpenAction->setWhatsThis(i18n("Opens a file in KSystemLog and displays its content in the current tab.")); 0522 0523 mPrintAction = actionCollection()->addAction(KStandardAction::Print); 0524 mPrintAction->setText(i18n("&Print Selection...")); 0525 mPrintAction->setToolTip(i18n("Print the selection")); 0526 mPrintAction->setWhatsThis( 0527 i18n("Prints the selection. Simply select the important lines and click on this menu entry to print the " 0528 "selection.")); 0529 mPrintAction->setEnabled(false); 0530 0531 mPrintPreviewAction = actionCollection()->addAction(KStandardAction::PrintPreview); 0532 mPrintPreviewAction->setText(i18n("&Print Preview Selection...")); 0533 mPrintPreviewAction->setToolTip(i18n("Print preview the selection")); 0534 mPrintPreviewAction->setWhatsThis( 0535 i18n("Prints preview the selection. Simply select the important lines and click on this menu entry to print the " 0536 "selection.")); 0537 mPrintPreviewAction->setEnabled(false); 0538 0539 mSaveAction = actionCollection()->addAction(KStandardAction::SaveAs); 0540 // TODO Retrieve the system's shortcut of the save action (and not Save as...) 0541 mSaveAction->setToolTip(i18n("Save the selection to a file")); 0542 mSaveAction->setWhatsThis( 0543 i18n("Saves the selection to a file. This action is useful if you want to create an attachment or a " 0544 "backup of a particular log.")); 0545 mSaveAction->setEnabled(false); 0546 actionCollection()->setDefaultShortcut(mSaveAction, Qt::CTRL | Qt::Key_S); 0547 0548 QAction *fileQuitAction = actionCollection()->addAction(KStandardAction::Quit, qApp, SLOT(quit())); 0549 fileQuitAction->setToolTip(i18n("Quit KSystemLog")); 0550 fileQuitAction->setWhatsThis(i18n("Quits KSystemLog.")); 0551 0552 mCopyAction = actionCollection()->addAction(KStandardAction::Copy); 0553 mCopyAction->setToolTip(i18n("Copy the selection to the clipboard")); 0554 mCopyAction->setWhatsThis( 0555 i18n("Copies the selection to the clipboard. This action is useful if you want to paste the selection in " 0556 "a chat or an email.")); 0557 mCopyAction->setEnabled(false); 0558 0559 mExpandAllAction = actionCollection()->addAction(QStringLiteral("expand_all")); 0560 mExpandAllAction->setText(i18n("Ex&pand All")); 0561 mExpandAllAction->setToolTip(i18n("Expand all categories")); 0562 mExpandAllAction->setWhatsThis( 0563 i18n("This action opens all main categories. This is enabled only if an option has been selected in the " 0564 "<b>Group By</b> menu.")); 0565 mExpandAllAction->setEnabled(false); 0566 actionCollection()->setDefaultShortcut(mExpandAllAction, Qt::CTRL | Qt::Key_X); 0567 0568 mCollapseAllAction = actionCollection()->addAction(QStringLiteral("collapse_all")); 0569 mCollapseAllAction->setText(i18n("Col&lapse All")); 0570 mCollapseAllAction->setToolTip(i18n("Collapse all categories")); 0571 mCollapseAllAction->setWhatsThis( 0572 i18n("This action closes all main categories. This is enabled only if an option has been selected in the " 0573 "<b>Group By</b> menu.")); 0574 mCollapseAllAction->setEnabled(false); 0575 actionCollection()->setDefaultShortcut(mCollapseAllAction, Qt::CTRL | Qt::Key_L); 0576 0577 mSendMailAction = actionCollection()->addAction(QStringLiteral("send_mail")); 0578 mSendMailAction->setText(i18n("&Email Selection...")); 0579 mSendMailAction->setIcon(QIcon::fromTheme(QStringLiteral("mail-message-new"))); 0580 mSendMailAction->setToolTip(i18n("Send the selection by mail")); 0581 mSendMailAction->setWhatsThis( 0582 i18n("Sends the selection by mail. Simply select the important lines and click on this menu entry to send " 0583 "the selection to a friend or a mailing list.")); 0584 mSendMailAction->setEnabled(false); 0585 actionCollection()->setDefaultShortcut(mSendMailAction, Qt::CTRL | Qt::Key_M); 0586 0587 mLogMessageAction = actionCollection()->addAction(QStringLiteral("log_message"), this, SLOT(showLogMessageDialog())); 0588 mLogMessageAction->setText(i18n("&Add Log Entry...")); 0589 mLogMessageAction->setIcon(QIcon::fromTheme(QStringLiteral("document-new"))); 0590 mLogMessageAction->setShortcut(Qt::CTRL | Qt::Key_L); 0591 mLogMessageAction->setToolTip(i18n("Add a log entry to the log system")); 0592 mLogMessageAction->setWhatsThis(i18n("This action will open a dialog which lets you send a message to the log system.")); 0593 actionCollection()->setDefaultShortcut(mLogMessageAction, Qt::CTRL | Qt::Key_L); 0594 0595 mSelectAllAction = actionCollection()->addAction(KStandardAction::SelectAll); 0596 mSelectAllAction->setToolTip(i18n("Select all lines of the current log")); 0597 mSelectAllAction->setWhatsThis( 0598 i18n("Selects all lines of the current log. This action is useful if you want, for example, to save all " 0599 "the content of the current log in a file.")); 0600 0601 mFindAction = actionCollection()->addAction(KStandardAction::Find, this, SLOT(showSearchBar())); 0602 mFindNextAction = actionCollection()->addAction(KStandardAction::FindNext, this, SLOT(findNext())); 0603 mFindPreviousAction = actionCollection()->addAction(KStandardAction::FindPrev, this, SLOT(findPrevious())); 0604 0605 actionCollection()->addAction(KStandardAction::Preferences, this, SLOT(showConfigurationDialog())); 0606 0607 // TODO Find a solution to display at the right place this action (see Akregator interface) 0608 mFilterBarAction = actionCollection()->addAction(QStringLiteral("show_quick_filter"), this, SLOT(toggleFilterBar())); 0609 mFilterBarAction->setText(i18n("Show &Filter Bar")); 0610 mFilterBarAction->setEnabled(true); 0611 mFilterBarAction->setCheckable(true); 0612 mFilterBarAction->setChecked(KSystemLogConfig::toggleFilterBar()); 0613 0614 QAction *newTabAction = actionCollection()->addAction(QStringLiteral("new_tab"), mTabs, SLOT(createTab())); 0615 newTabAction->setText(i18n("&New Tab")); 0616 newTabAction->setIcon(QIcon::fromTheme(QStringLiteral("tab-new"))); 0617 newTabAction->setToolTip(i18n("Create a new tab")); 0618 newTabAction->setWhatsThis(i18n("Creates a new tab which can display another log.")); 0619 mTabs->addAction(newTabAction); 0620 actionCollection()->setDefaultShortcut(newTabAction, Qt::CTRL | Qt::Key_T); 0621 0622 QAction *closeTabAction = actionCollection()->addAction(QStringLiteral("close_tab"), mTabs, SLOT(closeTab())); 0623 closeTabAction->setText(i18n("&Close Tab")); 0624 closeTabAction->setIcon(QIcon::fromTheme(QStringLiteral("tab-close"))); 0625 closeTabAction->setToolTip(i18n("Close the current tab")); 0626 closeTabAction->setWhatsThis(i18n("Closes the current tab.")); 0627 mTabs->addAction(closeTabAction); 0628 actionCollection()->setDefaultShortcut(closeTabAction, Qt::CTRL | Qt::Key_W); 0629 0630 QAction *duplicateTabAction = actionCollection()->addAction(QStringLiteral("duplicate_tab"), mTabs, SLOT(duplicateTab())); 0631 duplicateTabAction->setText(i18n("&Duplicate Tab")); 0632 duplicateTabAction->setIcon(QIcon::fromTheme(QStringLiteral("tab-duplicate"))); 0633 duplicateTabAction->setToolTip(i18n("Duplicate the current tab")); 0634 duplicateTabAction->setWhatsThis(i18n("Duplicates the current tab.")); 0635 mTabs->addAction(duplicateTabAction); 0636 actionCollection()->setDefaultShortcut(duplicateTabAction, Qt::SHIFT | Qt::CTRL | Qt::Key_N); 0637 0638 auto separatorAction = new QAction(this); 0639 separatorAction->setSeparator(true); 0640 mTabs->addAction(separatorAction); 0641 0642 QAction *moveTabLeftAction = actionCollection()->addAction(QStringLiteral("move_tab_left"), mTabs, SLOT(moveTabLeft())); 0643 moveTabLeftAction->setText(i18n("Move Tab &Left")); 0644 moveTabLeftAction->setIcon(QIcon::fromTheme(QStringLiteral("arrow-left"))); 0645 moveTabLeftAction->setToolTip(i18n("Move the current tab to the left")); 0646 moveTabLeftAction->setWhatsThis(i18n("Moves the current tab to the left.")); 0647 mTabs->addAction(moveTabLeftAction); 0648 actionCollection()->setDefaultShortcut(moveTabLeftAction, Qt::SHIFT | Qt::CTRL | Qt::Key_Left); 0649 0650 QAction *moveTabRightAction = actionCollection()->addAction(QStringLiteral("move_tab_right"), mTabs, SLOT(moveTabRight())); 0651 moveTabRightAction->setText(i18n("Move Tab &Right")); 0652 moveTabRightAction->setIcon(QIcon::fromTheme(QStringLiteral("arrow-right"))); 0653 moveTabRightAction->setToolTip(i18n("Move the current tab to the right")); 0654 moveTabRightAction->setWhatsThis(i18n("Moves the current tab to the right.")); 0655 mTabs->addAction(moveTabRightAction); 0656 actionCollection()->setDefaultShortcut(moveTabRightAction, Qt::SHIFT | Qt::CTRL | Qt::Key_Right); 0657 0658 mReloadAction = actionCollection()->addAction(QStringLiteral("reload"), mTabs, SLOT(reloadCurrent())); 0659 mReloadAction->setText(i18n("&Reload")); 0660 mReloadAction->setIcon(QIcon::fromTheme(QStringLiteral("view-refresh"))); 0661 mReloadAction->setToolTip(i18n("Reload the current log")); 0662 mReloadAction->setWhatsThis(i18n("Reloads the current log, if you want to be sure that the view is correctly updated.")); 0663 actionCollection()->setDefaultShortcut(mReloadAction, Qt::Key_F5); 0664 0665 mResumePauseAction = actionCollection()->addAction(QStringLiteral("resume_pause_parsing")); 0666 mResumePauseAction->setCheckable(true); 0667 connect(mResumePauseAction, &QAction::toggled, this, &MainWindow::changeResumePauseAction); 0668 connect(mResumePauseAction, &QAction::toggled, this, &MainWindow::toggleResumePauseParsing); 0669 changeResumePauseAction(false); 0670 0671 mDetailAction = actionCollection()->addAction(QStringLiteral("details"), this, SLOT(showDetailsDialog())); 0672 mDetailAction->setText(i18n("&Details")); 0673 mDetailAction->setIcon(QIcon::fromTheme(QStringLiteral("document-preview"))); 0674 mDetailAction->setToolTip(i18n("Display details on the selected line")); 0675 mDetailAction->setWhatsThis( 0676 i18n("Displays a dialog box which contains details on the selected line. You are able to navigate through " 0677 "the logs from this dialog box with the <b>Previous</b> and <b>Next</b> buttons.")); 0678 mDetailAction->setEnabled(false); 0679 actionCollection()->setDefaultShortcut(mDetailAction, Qt::ALT | Qt::Key_Return); 0680 0681 mTooltipEnabledAction = actionCollection()->addAction(QStringLiteral("tooltipEnabled")); 0682 mTooltipEnabledAction->setText(i18n("&Enable Detailed Tooltips")); 0683 mTooltipEnabledAction->setToolTip(i18n("Disable/Enable the tooltip on the current view")); 0684 mTooltipEnabledAction->setWhatsThis(i18n("Disables/Enables the tooltip displayed when the cursor hovers a log line.")); 0685 mTooltipEnabledAction->setCheckable(true); 0686 mTooltipEnabledAction->setChecked(KSystemLogConfig::tooltipEnabled()); 0687 connect(mTooltipEnabledAction, &QAction::toggled, this, &MainWindow::toggleItemTooltip); 0688 0689 mNewLinesDisplayedAction = actionCollection()->addAction(QStringLiteral("newLinesDisplayed")); 0690 mNewLinesDisplayedAction->setText(i18n("&Scroll to New Lines")); 0691 mNewLinesDisplayedAction->setToolTip(i18n("Scrolls or not to the new lines when the log changes")); 0692 mNewLinesDisplayedAction->setWhatsThis( 0693 i18n("Scrolls or not to the new lines when the log changes. Check this option if you do not want the " 0694 "application to scroll automatically at the bottom of the log each time it is refreshed.")); 0695 mNewLinesDisplayedAction->setCheckable(true); 0696 mNewLinesDisplayedAction->setChecked(KSystemLogConfig::newLinesDisplayed()); 0697 connect(mNewLinesDisplayedAction, &QAction::toggled, this, &MainWindow::toggleNewLinesDisplaying); 0698 0699 // Toolbar and Menu signals 0700 connect(mExpandAllAction, &QAction::triggered, mTabs, &TabLogViewsWidget::expandAllCurrentView); 0701 connect(mCollapseAllAction, &QAction::triggered, mTabs, &TabLogViewsWidget::collapseAllCurrentView); 0702 connect(mSaveAction, &QAction::triggered, mTabs, &TabLogViewsWidget::fileSaveCurrentView); 0703 connect(mCopyAction, &QAction::triggered, mTabs, &TabLogViewsWidget::copyToClipboardCurrentView); 0704 connect(mSendMailAction, &QAction::triggered, mTabs, &TabLogViewsWidget::sendMailCurrentView); 0705 connect(mPrintAction, &QAction::triggered, mTabs, &TabLogViewsWidget::printSelectionCurrentView); 0706 connect(mPrintPreviewAction, &QAction::triggered, mTabs, &TabLogViewsWidget::printPreviewSelectionCurrentView); 0707 connect(mSelectAllAction, &QAction::triggered, mTabs, &TabLogViewsWidget::selectAllCurrentView); 0708 } 0709 0710 void MainWindow::selectLogModeAction(bool) 0711 { 0712 auto action = qobject_cast<QAction *>(sender()); 0713 auto actionData = action->data().value<ActionData>(); 0714 QString const selectedModeId = actionData.id; 0715 0716 qCDebug(KSYSTEMLOG) << "Selected action" << selectedModeId; 0717 0718 LogMode *currentMode = nullptr; 0719 const auto logModes{Globals::instance().logModes()}; 0720 for (LogMode *logMode : logModes) { 0721 if (logMode->id() == selectedModeId) { 0722 currentMode = logMode; 0723 break; 0724 } 0725 } 0726 0727 if (!currentMode) { 0728 qCCritical(KSYSTEMLOG) << "The selected mode does not exist"; 0729 return; 0730 } 0731 0732 qCDebug(KSYSTEMLOG) << "Selecting " << currentMode->name() << " (" << currentMode->id() << ")"; 0733 0734 mTabs->load(currentMode, mTabs->activeLogManager(), actionData.analyzerOptions); 0735 } 0736 0737 void MainWindow::recreateActions() 0738 { 0739 unplugActionList(QStringLiteral("log_mode_list")); 0740 Globals::instance().recreateLogModeActions(); 0741 setupLogActions(); 0742 setupGUI(); 0743 setupLogModeMenu(); 0744 } 0745 0746 void MainWindow::setupLogModeMenu() 0747 { 0748 // Sets up the Logs menu. 0749 QList<QAction *> menuLogModeActions; 0750 int serviceItems = 0; 0751 int othersItems = 0; 0752 0753 auto servicesAction = new KActionMenu(QIcon::fromTheme(QStringLiteral("preferences-system-session-services")), i18n("Services"), this); 0754 auto othersAction = new KActionMenu(QIcon::fromTheme(QStringLiteral("preferences-other")), i18n("Others"), this); 0755 0756 const auto logModeActions{Globals::instance().logModeActions()}; 0757 for (LogModeAction *logModeAction : logModeActions) { 0758 if (logModeAction->category() == LogModeAction::RootCategory) { 0759 menuLogModeActions.append(logModeAction->actionMenu()); 0760 } else if (logModeAction->category() == LogModeAction::ServicesCategory) { 0761 serviceItems++; 0762 servicesAction->addAction(logModeAction->actionMenu()); 0763 } else if (logModeAction->category() == LogModeAction::OthersCategory) { 0764 othersAction->addAction(logModeAction->actionMenu()); 0765 othersItems++; 0766 } 0767 } 0768 0769 if (serviceItems) { 0770 menuLogModeActions.append(servicesAction); 0771 } 0772 0773 if (othersItems) { 0774 menuLogModeActions.append(othersAction); 0775 } 0776 0777 // Menu dynamic action list 0778 unplugActionList(QStringLiteral("log_mode_list")); 0779 plugActionList(QStringLiteral("log_mode_list"), menuLogModeActions); 0780 } 0781 0782 void MainWindow::setupLogActions() 0783 { 0784 // Sets up log mode actions. 0785 const auto logModeActions{Globals::instance().logModeActions()}; 0786 for (LogModeAction *logModeAction : logModeActions) { 0787 const auto innerActions{logModeAction->innerActions()}; 0788 for (QAction *action : innerActions) { 0789 auto actionData = action->data().value<ActionData>(); 0790 if (actionData.addToActionCollection) { 0791 qCDebug(KSYSTEMLOG) << "Adding action" << actionData.id; 0792 action = actionCollection()->addAction(actionData.id, action); 0793 } 0794 connect(action, &QAction::triggered, this, &MainWindow::selectLogModeAction); 0795 } 0796 } 0797 } 0798 } 0799 0800 #include "moc_mainWindow.cpp"