diff --git a/src/mainWindow.cpp b/src/mainWindow.cpp index 3607f6c..a30449c 100644 --- a/src/mainWindow.cpp +++ b/src/mainWindow.cpp @@ -1,891 +1,893 @@ /*************************************************************************** * KSystemLog, a system log viewer tool * * Copyright (C) 2007 by Nicolas Ternisien * * nicolas.ternisien@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "mainWindow.h" // Qt includes #include #include #include #include #include // KDE includes #include #include #include #include #include #include #include #include #include #include #include #include #include // Project includes #include "ksystemlogConfig.h" #include "statusBar.h" #include "logViewWidget.h" #include "tabLogViewsWidget.h" #include "configurationDialog.h" #include "loggerDialog.h" #include "detailDialog.h" #include "logModeConfiguration.h" #include "logManager.h" #include "logMode.h" #include "logLevel.h" #include "logFile.h" #include "logging.h" #include "view.h" #include "logViewSearchWidget.h" #include "logModePluginsLoader.h" #include "globals.h" #include "logModeAction.h" namespace KSystemLog { class MainWindowPrivate { public: QAction *saveAction; QAction *copyAction; QAction *reloadAction; QAction *sendMailAction; QAction *logMessageAction; QAction *filterBarAction; QAction *selectAllAction; QAction *expandAllAction; QAction *collapseAllAction; QAction *resumePauseAction; QAction *detailAction; QAction *printAction; QAction *findAction; QAction *findNextAction; QAction *findPreviousAction; QAction *tooltipEnabledAction; QAction *newLinesDisplayedAction; /** * Action groups which stores all Log Mode Actions */ QActionGroup *logModesActionGroup; QPrinter *printer; /** * Detail dialog */ DetailDialog *detailDialog; /** * Logged Dialog */ LoggerDialog *loggedDialog; ConfigurationDialog *configurationDialog; /** * Tab widget managing different views */ TabLogViewsWidget *tabs; KSystemLog::StatusBar *statusBar; }; MainWindow::MainWindow() : KXmlGuiWindow(nullptr) , d(new MainWindowPrivate()) { d->printer = nullptr; d->detailDialog = nullptr; d->configurationDialog = nullptr; d->tabs = nullptr; d->statusBar = nullptr; logDebug() << "Starting KSystemLog..."; // Load log modes plugins loadLogModePlugins(); // Create the GUI from XML configuration logDebug() << "Creating Gui..."; createGUI(); // TODO Improve the status bar to add a custom widget which shows an history of latest message, and add a // LogLevel for each ones // Initialize the Status Bar setupStatusBar(); // Setup the main tab bar setupTabLogViews(); // Setup the Actions setupActions(); // Setup toolbar log actions, needs to be called before setupGUI() setupLogActions(); // Apply the create the main window and ask the mainwindow to // automatically save settings if changed: window size, toolbar // position, icon size, etc. Also to add actions for the statusbar // toolbar, and keybindings if necessary. logDebug() << "Setup Gui..."; setupGUI(); // Setup Logs menu, needs to be called after setupGUI() setupLogModeMenu(); // Apply the saved mainwindow settings, if any, and ask the main window // to automatically save settings if changed: window size, tool bar // position, icon size, etc. setAutoSaveSettings(); d->configurationDialog = new ConfigurationDialog(this); connect(d->configurationDialog, &ConfigurationDialog::configurationSaved, d->tabs, &TabLogViewsWidget::reloadAll); // Show KSystemLog before loading the first log file show(); LogManager *firstLogManager = d->tabs->createTab(); // Load selected mode only if its log files exist. const QString &startupLogMode = KSystemLogConfig::startupLogMode(); if (startupLogMode.isEmpty() == false) { LogMode *mode = Globals::instance().findLogMode(startupLogMode); if (mode) { if (mode->filesExist()) { d->tabs->load(mode, firstLogManager); } else { logWarning() << mode->name() << "is selected by default, but log files do not exist."; } } } // Set focus to the list firstLogManager->usedView()->logViewWidget()->setFocus(); foreach (LogMode *logMode, Globals::instance().logModes()) { connect(logMode, &LogMode::menuChanged, this, &MainWindow::recreateActions); } } void MainWindow::loadLogModePlugins() { LogModePluginsLoader pluginsLoader(this); pluginsLoader.loadPlugins(); } void MainWindow::setupTabLogViews() { logDebug() << "Creating tab widget..."; d->tabs = new TabLogViewsWidget(); connect(d->tabs, &TabLogViewsWidget::statusBarChanged, this, &MainWindow::changeStatusBar); connect(d->tabs, &TabLogViewsWidget::logManagerCreated, this, &MainWindow::prepareCreatedLogManager); connect(d->tabs, &QTabWidget::currentChanged, this, &MainWindow::changeCurrentTab); setCentralWidget(d->tabs); } MainWindow::~MainWindow() { delete d->loggedDialog; delete d->detailDialog; delete d->configurationDialog; delete d; } void MainWindow::setupStatusBar() { d->statusBar = new KSystemLog::StatusBar(this); setStatusBar(d->statusBar); } void MainWindow::prepareCreatedLogManager(LogManager *manager) { logDebug() << "Connecting to actions the new log manager and view..."; // Contextual menu Log Manager signals QAction *separator; manager->usedView()->logViewWidget()->addAction(d->reloadAction); manager->usedView()->logViewWidget()->addAction(d->selectAllAction); separator = new QAction(this); separator->setSeparator(true); manager->usedView()->logViewWidget()->addAction(separator); manager->usedView()->logViewWidget()->addAction(d->copyAction); manager->usedView()->logViewWidget()->addAction(d->saveAction); manager->usedView()->logViewWidget()->addAction(d->sendMailAction); separator = new QAction(this); separator->setSeparator(true); manager->usedView()->logViewWidget()->addAction(separator); manager->usedView()->logViewWidget()->addAction(d->tooltipEnabledAction); manager->usedView()->logViewWidget()->addAction(d->newLinesDisplayedAction); separator = new QAction(this); separator->setSeparator(true); manager->usedView()->logViewWidget()->addAction(separator); manager->usedView()->logViewWidget()->addAction(d->detailAction); // Log Manager and View signals connect(manager, &LogManager::windowTitleChanged, this, &MainWindow::changeWindowTitle); connect(manager, &LogManager::statusBarChanged, this, &MainWindow::changeStatusBar); connect(manager, &LogManager::logUpdated, this, &MainWindow::updateStatusBar); connect(manager, &LogManager::reloaded, this, &MainWindow::changeCurrentTab); connect(manager->usedView(), &View::searchFilterChanged, this, &MainWindow::updateStatusBar); connect(manager->usedView()->logViewWidget(), &QTreeWidget::itemDoubleClicked, this, &MainWindow::showDetailsDialog); connect(manager->usedView()->logViewWidget(), &QTreeWidget::itemSelectionChanged, this, &MainWindow::updateSelection); connect(manager->usedView()->logViewWidget()->model(), &LogViewModel::processingMultipleInsertions, this, &MainWindow::updateReloading); // Correctly initialize the Status Bar updateStatusBar(); } void MainWindow::updateDetailDialog() { LogManager *currentManager = d->tabs->activeLogManager(); if (d->detailDialog != nullptr) { d->detailDialog->selectionChanged(currentManager->usedView()->logViewWidget()); } } void MainWindow::updateSelection() { // logDebug() << "Updating selection..."; LogManager *currentLogManager = d->tabs->activeLogManager(); updateDetailDialog(); bool selection = currentLogManager->usedView()->logViewWidget()->hasItemsSelected(); d->copyAction->setEnabled(selection); d->saveAction->setEnabled(selection); d->detailAction->setEnabled(selection); d->sendMailAction->setEnabled(selection); d->printAction->setEnabled(selection); } void MainWindow::updateReloading() { View *currentView = d->tabs->activeLogManager()->usedView(); bool enabled = !currentView->logViewWidget()->model()->isProcessingMultipleInsertions(); d->reloadAction->setEnabled(enabled); d->resumePauseAction->setEnabled(enabled); d->findAction->setEnabled(enabled); d->findNextAction->setEnabled(enabled); d->findPreviousAction->setEnabled(enabled); // Enables/Disables all Log Mode actions // d->logModesActionGroup->setEnabled(enabled); d->tabs->changeReloadingTab(currentView, !enabled); // Enables/Disables all Log Mode menus (useful for multiple actions menus) foreach (LogModeAction *logModeAction, Globals::instance().logModeActions()) { logModeAction->actionMenu()->setEnabled(enabled); } } void MainWindow::closeEvent(QCloseEvent *event) { + disconnect(d->tabs, &QTabWidget::currentChanged, this, &MainWindow::changeCurrentTab); + LogManager *currentLogManager = d->tabs->activeLogManager(); if (currentLogManager) { currentLogManager->stopWatching(); } logDebug() << "Saving configuration before exit..."; qCDebug(KSYSTEMLOG) << "Saving configuration before exit..."; // Write the config to the file KSystemLogConfig::self()->save(); KXmlGuiWindow::closeEvent(event); } TabLogViewsWidget *MainWindow::tabs() { return d->tabs; } void MainWindow::showDetailsDialog() { // Create the Detail dialog if it was not created if (d->detailDialog == nullptr) { d->detailDialog = new DetailDialog(this); updateDetailDialog(); } d->detailDialog->show(); } void MainWindow::toggleItemTooltip(bool enabled) { KSystemLogConfig::setTooltipEnabled(enabled); foreach (LogManager *manager, d->tabs->logManagers()) { manager->usedView()->logViewWidget()->toggleToolTip(enabled); } } void MainWindow::toggleNewLinesDisplaying(bool displayed) { KSystemLogConfig::setNewLinesDisplayed(displayed); } void MainWindow::updateStatusBar() { logDebug() << "Updating status bar..."; LogManager *currentManager = d->tabs->activeLogManager(); int itemCount = currentManager->usedView()->logViewWidget()->itemCount(); int notHiddenItemCount = currentManager->usedView()->logViewWidget()->notHiddenItemCount(); if (itemCount == notHiddenItemCount) { d->statusBar->changeLineCountMessage( i18ncp("Total displayed lines", "1 line.", "%1 lines.", currentManager->usedView()->logViewWidget()->itemCount())); } else { d->statusBar->changeLineCountMessage(i18ncp("Line not hidden by search / Total displayed lines", "1 line / %2 total.", "%1 lines / %2 total.", notHiddenItemCount, itemCount)); } d->statusBar->changeLastModification(currentManager->lastUpdate()); } void MainWindow::toggleResumePauseParsing(bool paused) { logDebug() << "Pausing parsing : " << paused; LogManager *currentLogManager = d->tabs->activeLogManager(); if (currentLogManager != nullptr) { currentLogManager->setParsingPaused(paused); } logDebug() << "Parsing paused : " << paused; } void MainWindow::changeResumePauseAction(bool paused) { if (paused == true) { d->resumePauseAction->setText(i18n("Resu&me")); d->resumePauseAction->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-start"))); d->resumePauseAction->setToolTip(i18n("Resume the watching of the current log")); d->resumePauseAction->setWhatsThis( i18n("Resumes the watching of the current log. This action is only available when the user has " "already paused the reading.")); d->resumePauseAction->setChecked(true); actionCollection()->setDefaultShortcut(d->resumePauseAction, Qt::CTRL + Qt::Key_M); } else { d->resumePauseAction->setText(i18n("S&top")); d->resumePauseAction->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-stop"))); d->resumePauseAction->setToolTip(i18n("Pause the watching of the current log")); d->resumePauseAction->setWhatsThis(i18n( "Pauses the watching of the current log. This action is particularly useful when the system is " "writing too many lines to log files, causing KSystemLog to reload too frequently.")); d->resumePauseAction->setChecked(false); actionCollection()->setDefaultShortcut(d->resumePauseAction, Qt::CTRL + Qt::Key_P); } // Be sure that the button will always have a good size foreach (QWidget *widget, d->resumePauseAction->associatedWidgets()) { if (widget->sizeHint().width() > widget->size().width()) { widget->setMinimumSize(widget->sizeHint()); } } } void MainWindow::fileOpen() { // Launch the actualizing d->tabs->load(Globals::instance().findLogMode(QStringLiteral("openLogMode")), d->tabs->activeLogManager()); } void MainWindow::showConfigurationDialog() { logDebug() << "Showing configuration dialog..."; d->configurationDialog->showConfiguration(); } void MainWindow::showLogMessageDialog() { logDebug() << "Launching the Send message dialog box..."; if (d->loggedDialog == nullptr) { d->loggedDialog = new LoggerDialog(this); } d->loggedDialog->initialize(); d->loggedDialog->exec(); } void MainWindow::changeStatusBar(const QString &text) { d->statusBar->changeMessage(text); } void MainWindow::changeWindowTitle(const QString &text) { // Display this text on the caption setCaption(text); } void MainWindow::changeCurrentTab() { logDebug() << "Tab has changed"; LogManager *currentManager = d->tabs->activeLogManager(); if (!currentManager) return; // If the tab changed, the selection changes too updateSelection(); // Update the status bar updateStatusBar(); // Updating the current reloading status updateReloading(); bool enabledReloading = !currentManager->usedView()->logViewWidget()->model()->isProcessingMultipleInsertions(); bool enabledAction; // Change the title of the window if (currentManager->logMode() == nullptr) { changeWindowTitle(i18nc("Newly created tab", "Empty Log")); enabledAction = false; } else { changeWindowTitle(currentManager->title()); enabledAction = true; } if (enabledReloading == true && enabledAction == true) { d->reloadAction->setEnabled(true); d->resumePauseAction->setEnabled(true); } else { d->reloadAction->setEnabled(false); d->resumePauseAction->setEnabled(false); } // Update Resume/Pause action state if (currentManager->isParsingPaused()) changeResumePauseAction(true); else changeResumePauseAction(false); // Updating Detail dialog updateDetailDialog(); logDebug() << "Tab changing done"; } /** * TODO Implements the session restoring * * The 'config' object points to the session managed * config file. anything you write here will be available * later when this app is restored */ void MainWindow::saveProperties(KConfigGroup & /*configuration*/) { logDebug() << "Saving properties..."; } /** * TODO Implements the session restoring * * The 'config' object points to the session managed * config file. this function is automatically called whenever * the app is being restored. read in here whatever you wrote * in 'saveProperties' */ void MainWindow::readProperties(const KConfigGroup & /*configuration*/) { logDebug() << "Reading properties..."; } void MainWindow::toggleFilterBar() { logDebug() << "Toggling filter bar..." << d->filterBarAction->isChecked(); foreach (LogManager *manager, d->tabs->logManagers()) { manager->usedView()->toggleLogViewFilter(d->filterBarAction->isChecked()); } KSystemLogConfig::setToggleFilterBar(d->filterBarAction->isChecked()); } void MainWindow::findNext() { showSearchBar(); d->tabs->activeLogManager()->usedView()->logViewSearch()->findNext(); } void MainWindow::findPrevious() { showSearchBar(); d->tabs->activeLogManager()->usedView()->logViewSearch()->findPrevious(); } void MainWindow::showSearchBar() { logDebug() << "Showing search bar..."; LogManager *activeLogManager = d->tabs->activeLogManager(); foreach (LogManager *manager, d->tabs->logManagers()) { if (manager != activeLogManager) { manager->usedView()->toggleLogViewSearch(true); } } // Be sure to display the view search of the active LogManager at last, and focus to it d->tabs->activeLogManager()->usedView()->toggleLogViewSearch(true); } void MainWindow::setupActions() { logDebug() << "Creating actions..."; QAction *fileOpenAction = actionCollection()->addAction(KStandardAction::Open, this, SLOT(fileOpen())); fileOpenAction->setToolTip(i18n("Open a file in KSystemLog")); fileOpenAction->setWhatsThis( i18n("Opens a file in KSystemLog and displays its content in the current tab.")); d->printAction = actionCollection()->addAction(KStandardAction::Print); d->printAction->setText(i18n("&Print Selection...")); d->printAction->setToolTip(i18n("Print the selection")); d->printAction->setWhatsThis(i18n( "Prints the selection. Simply select the important lines and click on this menu entry to print the " "selection.")); d->printAction->setEnabled(false); d->saveAction = actionCollection()->addAction(KStandardAction::SaveAs); // TODO Retrieve the system's shortcut of the save action (and not Save as...) d->saveAction->setToolTip(i18n("Save the selection to a file")); d->saveAction->setWhatsThis( i18n("Saves the selection to a file. This action is useful if you want to create an attachment or a " "backup of a particular log.")); d->saveAction->setEnabled(false); actionCollection()->setDefaultShortcut(d->saveAction, Qt::CTRL + Qt::Key_S); QAction *fileQuitAction = actionCollection()->addAction(KStandardAction::Quit, qApp, SLOT(quit())); fileQuitAction->setToolTip(i18n("Quit KSystemLog")); fileQuitAction->setWhatsThis(i18n("Quits KSystemLog.")); d->copyAction = actionCollection()->addAction(KStandardAction::Copy); d->copyAction->setToolTip(i18n("Copy the selection to the clipboard")); d->copyAction->setWhatsThis(i18n( "Copies the selection to the clipboard. This action is useful if you want to paste the selection in " "a chat or an email.")); d->copyAction->setEnabled(false); d->expandAllAction = actionCollection()->addAction(QStringLiteral("expand_all")); d->expandAllAction->setText(i18n("Ex&pand All")); d->expandAllAction->setToolTip(i18n("Expand all categories")); d->expandAllAction->setWhatsThis(i18n( "This action opens all main categories. This is enabled only if an option has been selected in the " "Group By menu.")); d->expandAllAction->setEnabled(false); actionCollection()->setDefaultShortcut(d->expandAllAction, Qt::CTRL + Qt::Key_X); d->collapseAllAction = actionCollection()->addAction(QStringLiteral("collapse_all")); d->collapseAllAction->setText(i18n("Col&lapse All")); d->collapseAllAction->setToolTip(i18n("Collapse all categories")); d->collapseAllAction->setWhatsThis(i18n( "This action closes all main categories. This is enabled only if an option has been selected in the " "Group By menu.")); d->collapseAllAction->setEnabled(false); actionCollection()->setDefaultShortcut(d->collapseAllAction, Qt::CTRL + Qt::Key_L); d->sendMailAction = actionCollection()->addAction(QStringLiteral("send_mail")); d->sendMailAction->setText(i18n("&Email Selection...")); d->sendMailAction->setIcon(QIcon::fromTheme(QStringLiteral("mail-message-new"))); d->sendMailAction->setToolTip(i18n("Send the selection by mail")); d->sendMailAction->setWhatsThis(i18n( "Sends the selection by mail. Simply select the important lines and click on this menu entry to send " "the selection to a friend or a mailing list.")); d->sendMailAction->setEnabled(false); actionCollection()->setDefaultShortcut(d->sendMailAction, Qt::CTRL + Qt::Key_M); d->logMessageAction = actionCollection()->addAction(QStringLiteral("log_message"), this, SLOT(showLogMessageDialog())); d->logMessageAction->setText(i18n("&Add Log Entry...")); d->logMessageAction->setIcon(QIcon::fromTheme(QStringLiteral("document-new"))); d->logMessageAction->setShortcut(Qt::CTRL + Qt::Key_L); d->logMessageAction->setToolTip(i18n("Add a log entry to the log system")); d->logMessageAction->setWhatsThis( i18n("This action will open a dialog which lets you send a message to the log system.")); actionCollection()->setDefaultShortcut(d->logMessageAction, Qt::CTRL + Qt::Key_L); d->selectAllAction = actionCollection()->addAction(KStandardAction::SelectAll); d->selectAllAction->setToolTip(i18n("Select all lines of the current log")); d->selectAllAction->setWhatsThis(i18n( "Selects all lines of the current log. This action is useful if you want, for example, to save all " "the content of the current log in a file.")); d->findAction = actionCollection()->addAction(KStandardAction::Find, this, SLOT(showSearchBar())); d->findNextAction = actionCollection()->addAction(KStandardAction::FindNext, this, SLOT(findNext())); d->findPreviousAction = actionCollection()->addAction(KStandardAction::FindPrev, this, SLOT(findPrevious())); actionCollection()->addAction(KStandardAction::Preferences, this, SLOT(showConfigurationDialog())); // TODO Find a solution to display at the right place this action (see Akregator interface) d->filterBarAction = actionCollection()->addAction(QStringLiteral("show_quick_filter"), this, SLOT(toggleFilterBar())); d->filterBarAction->setText(i18n("Show &Filter Bar")); d->filterBarAction->setEnabled(true); d->filterBarAction->setCheckable(true); d->filterBarAction->setChecked(KSystemLogConfig::toggleFilterBar()); QAction *newTabAction = actionCollection()->addAction(QStringLiteral("new_tab"), d->tabs, SLOT(createTab())); newTabAction->setText(i18n("&New Tab")); newTabAction->setIcon(QIcon::fromTheme(QStringLiteral("tab-new"))); newTabAction->setToolTip(i18n("Create a new tab")); newTabAction->setWhatsThis(i18n("Creates a new tab which can display another log.")); d->tabs->addAction(newTabAction); actionCollection()->setDefaultShortcut(newTabAction, Qt::CTRL + Qt::Key_T); QAction *closeTabAction = actionCollection()->addAction(QStringLiteral("close_tab"), d->tabs, SLOT(closeTab())); closeTabAction->setText(i18n("&Close Tab")); closeTabAction->setIcon(QIcon::fromTheme(QStringLiteral("tab-close"))); closeTabAction->setToolTip(i18n("Close the current tab")); closeTabAction->setWhatsThis(i18n("Closes the current tab.")); d->tabs->addAction(closeTabAction); actionCollection()->setDefaultShortcut(closeTabAction, Qt::CTRL + Qt::Key_W); QAction *duplicateTabAction = actionCollection()->addAction(QStringLiteral("duplicate_tab"), d->tabs, SLOT(duplicateTab())); duplicateTabAction->setText(i18n("&Duplicate Tab")); duplicateTabAction->setIcon(QIcon::fromTheme(QStringLiteral("tab-duplicate"))); duplicateTabAction->setToolTip(i18n("Duplicate the current tab")); duplicateTabAction->setWhatsThis(i18n("Duplicates the current tab.")); d->tabs->addAction(duplicateTabAction); actionCollection()->setDefaultShortcut(duplicateTabAction, Qt::SHIFT + Qt::CTRL + Qt::Key_N); QAction *separatorAction = new QAction(this); separatorAction->setSeparator(true); d->tabs->addAction(separatorAction); QAction *moveTabLeftAction = actionCollection()->addAction(QStringLiteral("move_tab_left"), d->tabs, SLOT(moveTabLeft())); moveTabLeftAction->setText(i18n("Move Tab &Left")); moveTabLeftAction->setIcon(QIcon::fromTheme(QStringLiteral("arrow-left"))); moveTabLeftAction->setToolTip(i18n("Move the current tab to the left")); moveTabLeftAction->setWhatsThis(i18n("Moves the current tab to the left.")); d->tabs->addAction(moveTabLeftAction); actionCollection()->setDefaultShortcut(moveTabLeftAction, Qt::SHIFT + Qt::CTRL + Qt::Key_Left); QAction *moveTabRightAction = actionCollection()->addAction(QStringLiteral("move_tab_right"), d->tabs, SLOT(moveTabRight())); moveTabRightAction->setText(i18n("Move Tab &Right")); moveTabRightAction->setIcon(QIcon::fromTheme(QStringLiteral("arrow-right"))); moveTabRightAction->setToolTip(i18n("Move the current tab to the right")); moveTabRightAction->setWhatsThis(i18n("Moves the current tab to the right.")); d->tabs->addAction(moveTabRightAction); actionCollection()->setDefaultShortcut(moveTabRightAction, Qt::SHIFT + Qt::CTRL + Qt::Key_Right); d->reloadAction = actionCollection()->addAction(QStringLiteral("reload"), d->tabs, SLOT(reloadCurrent())); d->reloadAction->setText(i18n("&Reload")); d->reloadAction->setIcon(QIcon::fromTheme(QStringLiteral("view-refresh"))); d->reloadAction->setToolTip(i18n("Reload the current log")); d->reloadAction->setWhatsThis( i18n("Reloads the current log, if you want to be sure that the view is correctly updated.")); actionCollection()->setDefaultShortcut(d->reloadAction, Qt::Key_F5); d->resumePauseAction = actionCollection()->addAction(QStringLiteral("resume_pause_parsing")); d->resumePauseAction->setCheckable(true); connect(d->resumePauseAction, &QAction::toggled, this, &MainWindow::changeResumePauseAction); connect(d->resumePauseAction, &QAction::toggled, this, &MainWindow::toggleResumePauseParsing); changeResumePauseAction(false); d->detailAction = actionCollection()->addAction(QStringLiteral("details"), this, SLOT(showDetailsDialog())); d->detailAction->setText(i18n("&Details")); d->detailAction->setIcon(QIcon::fromTheme(QStringLiteral("document-preview"))); d->detailAction->setToolTip(i18n("Display details on the selected line")); d->detailAction->setWhatsThis(i18n( "Displays a dialog box which contains details on the selected line. You are able to navigate through " "the logs from this dialog box with the Previous and Next buttons.")); d->detailAction->setEnabled(false); actionCollection()->setDefaultShortcut(d->detailAction, Qt::ALT + Qt::Key_Return); d->tooltipEnabledAction = actionCollection()->addAction(QStringLiteral("tooltipEnabled")); d->tooltipEnabledAction->setText(i18n("&Enable Detailed Tooltips")); d->tooltipEnabledAction->setToolTip(i18n("Disable/Enable the tooltip on the current view")); d->tooltipEnabledAction->setWhatsThis( i18n("Disables/Enables the tooltip displayed when the cursor hovers a log line.")); d->tooltipEnabledAction->setCheckable(true); d->tooltipEnabledAction->setChecked(KSystemLogConfig::tooltipEnabled()); connect(d->tooltipEnabledAction, &QAction::toggled, this, &MainWindow::toggleItemTooltip); d->newLinesDisplayedAction = actionCollection()->addAction(QStringLiteral("newLinesDisplayed")); d->newLinesDisplayedAction->setText(i18n("&Scroll to New Lines")); d->newLinesDisplayedAction->setToolTip(i18n("Scrolls or not to the new lines when the log changes")); d->newLinesDisplayedAction->setWhatsThis( i18n("Scrolls or not to the new lines when the log changes. Check this option if you do not want the " "application to scroll automatically at the bottom of the log each time it is refreshed.")); d->newLinesDisplayedAction->setCheckable(true); d->newLinesDisplayedAction->setChecked(KSystemLogConfig::newLinesDisplayed()); connect(d->newLinesDisplayedAction, &QAction::toggled, this, &MainWindow::toggleNewLinesDisplaying); // Toolbar and Menu signals connect(d->expandAllAction, &QAction::triggered, d->tabs, &TabLogViewsWidget::expandAllCurrentView); connect(d->collapseAllAction, &QAction::triggered, d->tabs, &TabLogViewsWidget::collapseAllCurrentView); connect(d->saveAction, &QAction::triggered, d->tabs, &TabLogViewsWidget::fileSaveCurrentView); connect(d->copyAction, &QAction::triggered, d->tabs, &TabLogViewsWidget::copyToClipboardCurrentView); connect(d->sendMailAction, &QAction::triggered, d->tabs, &TabLogViewsWidget::sendMailCurrentView); connect(d->printAction, &QAction::triggered, d->tabs, &TabLogViewsWidget::printSelectionCurrentView); connect(d->selectAllAction, &QAction::triggered, d->tabs, &TabLogViewsWidget::selectAllCurrentView); } void MainWindow::selectLogModeAction(bool) { QAction *action = qobject_cast(sender()); ActionData actionData = action->data().value(); QString selectedModeId = actionData.id; logDebug() << "Selected action" << selectedModeId; LogMode *currentMode = nullptr; foreach (LogMode *logMode, Globals::instance().logModes()) { if (logMode->id() == selectedModeId) { currentMode = logMode; break; } } if (currentMode == nullptr) { logCritical() << "The selected mode does not exist"; return; } logDebug() << "Selecting " << currentMode->name() << " (" << currentMode->id() << ")"; d->tabs->load(currentMode, d->tabs->activeLogManager(), actionData.analyzerOptions); } void MainWindow::recreateActions() { unplugActionList(QStringLiteral("log_mode_list")); Globals::instance().recreateLogModeActions(); setupLogActions(); setupGUI(); setupLogModeMenu(); } void MainWindow::setupLogModeMenu() { // Sets up the Logs menu. QList menuLogModeActions; int serviceItems = 0; int othersItems = 0; KActionMenu *servicesAction = new KActionMenu( QIcon::fromTheme(QStringLiteral("preferences-system-session-services")), i18n("Services"), this); KActionMenu *othersAction = new KActionMenu(QIcon::fromTheme(QStringLiteral("preferences-other")), i18n("Others"), this); foreach (LogModeAction *logModeAction, Globals::instance().logModeActions()) { if (logModeAction->category() == LogModeAction::RootCategory) { menuLogModeActions.append(logModeAction->actionMenu()); } else if (logModeAction->category() == LogModeAction::ServicesCategory) { serviceItems++; servicesAction->addAction(logModeAction->actionMenu()); } else if (logModeAction->category() == LogModeAction::OthersCategory) { othersAction->addAction(logModeAction->actionMenu()); othersItems++; } } if (serviceItems) menuLogModeActions.append(servicesAction); if (othersItems) menuLogModeActions.append(othersAction); // Menu dynamic action list unplugActionList(QStringLiteral("log_mode_list")); plugActionList(QStringLiteral("log_mode_list"), menuLogModeActions); } void MainWindow::setupLogActions() { // Sets up log mode actions. foreach (LogModeAction *logModeAction, Globals::instance().logModeActions()) { foreach (QAction *action, logModeAction->innerActions()) { ActionData actionData = action->data().value(); if (actionData.addToActionCollection) { logDebug() << "Adding action" << actionData.id; action = actionCollection()->addAction(actionData.id, action); } connect(action, &QAction::triggered, this, &MainWindow::selectLogModeAction); } } } }