diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -411,6 +411,55 @@ case QDialogButtonBox::No: // Close only the current tab m_tabWidget->closeTab(); + // fall through + default: + event->ignore(); + return; + } + } + + if (m_terminalPanel->isAnyProgramRunning() && GeneralSettings::confirmClosingTerminalRunningProgram() && closedByUser) { + // Ask if the user really wants to quit Dolphin with a program that is still running in the Terminal panel + // Open a confirmation dialog with 3 buttons: + // QDialogButtonBox::Yes -> Quit + // QDialogButtonBox::No -> Show Terminal Panel + // QDialogButtonBox::Cancel -> do nothing + QDialog *dialog = new QDialog(this, Qt::Dialog); + dialog->setWindowTitle(i18nc("@title:window", "Confirmation")); + dialog->setModal(true); + QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Yes | QDialogButtonBox::No | QDialogButtonBox::Cancel); + KGuiItem::assign(buttons->button(QDialogButtonBox::Yes), KStandardGuiItem::quit()); + KGuiItem::assign(buttons->button(QDialogButtonBox::No), KGuiItem(i18n("Show &Terminal Panel"), QIcon::fromTheme(QStringLiteral("utilities-terminal")))); + KGuiItem::assign(buttons->button(QDialogButtonBox::Cancel), KStandardGuiItem::cancel()); + buttons->button(QDialogButtonBox::Cancel)->setDefault(true); + + bool doNotAskAgainCheckboxResult = false; + + const int result = KMessageBox::createKMessageBox( + dialog, + buttons, + QMessageBox::Warning, + i18n("The program '%1' is still running in the Terminal panel. Are you sure you want to quit?", m_terminalPanel->runningProgramName()), + QStringList(), + i18n("Do not ask again"), + &doNotAskAgainCheckboxResult, + KMessageBox::Notify); + + if (doNotAskAgainCheckboxResult) { + GeneralSettings::setConfirmClosingTerminalRunningProgram(false); + } + + switch (result) { + case QDialogButtonBox::Yes: + // Quit + break; + case QDialogButtonBox::No: + if (!m_terminalPanel->isVisible()) + actionCollection()->action("show_terminal_panel")->trigger(); + else + m_terminalPanel->setFocus(); + // Do not quit + // fall through default: event->ignore(); return; diff --git a/src/panels/terminal/terminalpanel.h b/src/panels/terminal/terminalpanel.h --- a/src/panels/terminal/terminalpanel.h +++ b/src/panels/terminal/terminalpanel.h @@ -53,8 +53,10 @@ * home when an unmounting request is received. */ void goHome(); - QString currentWorkingDirectory(); - bool isHiddenInVisibleWindow(); + QString currentWorkingDirectory() const; + bool isHiddenInVisibleWindow() const; + bool isAnyProgramRunning() const; + QString runningProgramName() const; public slots: void terminalExited(); @@ -96,6 +98,7 @@ KParts::ReadOnlyPart* m_konsolePart; QString m_konsolePartCurrentDirectory; QQueue m_sendCdToTerminalHistory; + }; #endif // TERMINALPANEL_H diff --git a/src/panels/terminal/terminalpanel.cpp b/src/panels/terminal/terminalpanel.cpp --- a/src/panels/terminal/terminalpanel.cpp +++ b/src/panels/terminal/terminalpanel.cpp @@ -59,7 +59,7 @@ sendCdToTerminal(QDir::homePath(), HistoryPolicy::SkipHistory); } -QString TerminalPanel::currentWorkingDirectory() +QString TerminalPanel::currentWorkingDirectory() const { if (m_terminal) { return m_terminal->currentWorkingDirectory(); @@ -73,12 +73,12 @@ emit hideTerminalPanel(); } -bool TerminalPanel::isHiddenInVisibleWindow() +bool TerminalPanel::isHiddenInVisibleWindow() const { return parentWidget() && parentWidget()->isHidden() && m_terminal - && (m_terminal->foregroundProcessId() == -1); + && !isAnyProgramRunning(); } void TerminalPanel::dockVisibilityChanged() @@ -101,13 +101,23 @@ } } +QString TerminalPanel::runningProgramName() const +{ + return m_terminal->foregroundProcessName(); +} + +bool TerminalPanel::isAnyProgramRunning() const +{ + return m_terminal->foregroundProcessId() != -1; +} + bool TerminalPanel::urlChanged() { if (!url().isValid()) { return false; } - const bool sendInput = m_terminal && (m_terminal->foregroundProcessId() == -1) && isVisible(); + const bool sendInput = m_terminal && !isAnyProgramRunning() && isVisible(); if (sendInput) { changeDir(url()); } diff --git a/src/settings/dolphin_generalsettings.kcfg b/src/settings/dolphin_generalsettings.kcfg --- a/src/settings/dolphin_generalsettings.kcfg +++ b/src/settings/dolphin_generalsettings.kcfg @@ -58,6 +58,10 @@ true + + + true + true diff --git a/src/settings/general/confirmationssettingspage.h b/src/settings/general/confirmationssettingspage.h --- a/src/settings/general/confirmationssettingspage.h +++ b/src/settings/general/confirmationssettingspage.h @@ -46,6 +46,7 @@ private: QCheckBox* m_confirmMoveToTrash; QCheckBox* m_confirmDelete; + QCheckBox* m_confirmClosingTerminalRunningProgram; QCheckBox* m_confirmClosingMultipleTabs; QCheckBox* m_confirmScriptExecution; }; diff --git a/src/settings/general/confirmationssettingspage.cpp b/src/settings/general/confirmationssettingspage.cpp --- a/src/settings/general/confirmationssettingspage.cpp +++ b/src/settings/general/confirmationssettingspage.cpp @@ -37,7 +37,8 @@ SettingsPageBase(parent), m_confirmMoveToTrash(nullptr), m_confirmDelete(nullptr), - m_confirmClosingMultipleTabs(nullptr) + m_confirmClosingMultipleTabs(nullptr), + m_confirmClosingTerminalRunningProgram(nullptr) { QVBoxLayout* topLayout = new QVBoxLayout(this); @@ -56,21 +57,26 @@ m_confirmClosingMultipleTabs = new QCheckBox(i18nc("@option:check Ask for confirmation when", "Closing Dolphin windows with multiple tabs"), this); + m_confirmClosingTerminalRunningProgram = new QCheckBox(i18nc("@option:check Ask for confirmation when", + "Closing Dolphin windows with a program that is still running in the Terminal panel."), this); + topLayout->addWidget(confirmLabelKde); topLayout->addWidget(m_confirmMoveToTrash); topLayout->addWidget(m_confirmDelete); topLayout->addWidget(m_confirmScriptExecution); topLayout->addWidget(confirmLabelDolphin); topLayout->addWidget(m_confirmClosingMultipleTabs); + topLayout->addWidget(m_confirmClosingTerminalRunningProgram); topLayout->addStretch(); loadSettings(); connect(m_confirmMoveToTrash, &QCheckBox::toggled, this, &ConfirmationsSettingsPage::changed); connect(m_confirmDelete, &QCheckBox::toggled, this, &ConfirmationsSettingsPage::changed); connect(m_confirmScriptExecution, &QCheckBox::toggled, this, &ConfirmationsSettingsPage::changed); connect(m_confirmClosingMultipleTabs, &QCheckBox::toggled, this, &ConfirmationsSettingsPage::changed); + connect(m_confirmClosingTerminalRunningProgram, &QCheckBox::toggled, this, &ConfirmationsSettingsPage::changed); } ConfirmationsSettingsPage::~ConfirmationsSettingsPage() @@ -93,6 +99,7 @@ GeneralSettings* settings = GeneralSettings::self(); settings->setConfirmClosingMultipleTabs(m_confirmClosingMultipleTabs->isChecked()); + settings->setConfirmClosingTerminalRunningProgram(m_confirmClosingTerminalRunningProgram->isChecked()); settings->save(); } @@ -120,5 +127,6 @@ m_confirmScriptExecution->setChecked(value == QLatin1String("alwaysAsk")); m_confirmClosingMultipleTabs->setChecked(GeneralSettings::confirmClosingMultipleTabs()); + m_confirmClosingTerminalRunningProgram->setChecked(GeneralSettings::confirmClosingTerminalRunningProgram()); }