diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -407,7 +407,7 @@ bool doNotAskAgainCheckboxResult = false; - const int result = KMessageBox::createKMessageBox(dialog, + const auto result = KMessageBox::createKMessageBox(dialog, buttons, QMessageBox::Warning, i18n("You have multiple tabs open in this window, are you sure you want to quit?"), @@ -434,6 +434,58 @@ } } + if (m_terminalPanel->hasProgramRunning() && 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); + auto standardButtons = QDialogButtonBox::Yes | QDialogButtonBox::Cancel; + if (!m_terminalPanel->isVisible()) { + standardButtons |= QDialogButtonBox::No; + } + QDialogButtonBox *buttons = new QDialogButtonBox(standardButtons); + KGuiItem::assign(buttons->button(QDialogButtonBox::Yes), KStandardGuiItem::quit()); + if (!m_terminalPanel->isVisible()) { + KGuiItem::assign( + buttons->button(QDialogButtonBox::No), + KGuiItem(i18n("Show &Terminal Panel"), QIcon::fromTheme(QStringLiteral("utilities-terminal")))); + } + KGuiItem::assign(buttons->button(QDialogButtonBox::Cancel), KStandardGuiItem::cancel()); + + bool doNotAskAgainCheckboxResult = false; + + const auto 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::Dangerous); + + if (doNotAskAgainCheckboxResult) { + GeneralSettings::setConfirmClosingTerminalRunningProgram(false); + } + + switch (result) { + case QDialogButtonBox::Yes: + // Quit + break; + case QDialogButtonBox::No: + actionCollection()->action("show_terminal_panel")->trigger(); + // Do not quit, ignore quit event + Q_FALLTHROUGH(); + default: + event->ignore(); + return; + } + } + GeneralSettings::setVersion(CurrentDolphinVersion); GeneralSettings::self()->save(); 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 @@ -55,7 +55,9 @@ */ void goHome(); QString currentWorkingDirectory(); - bool isHiddenInVisibleWindow(); + bool isHiddenInVisibleWindow() const; + bool hasProgramRunning() const; + QString runningProgramName() const; public slots: void terminalExited(); 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 @@ -79,12 +79,12 @@ emit hideTerminalPanel(); } -bool TerminalPanel::isHiddenInVisibleWindow() +bool TerminalPanel::isHiddenInVisibleWindow() const { return parentWidget() && parentWidget()->isHidden() && m_terminal - && (m_terminal->foregroundProcessId() == -1); + && !hasProgramRunning(); } void TerminalPanel::dockVisibilityChanged() @@ -107,13 +107,23 @@ } } +QString TerminalPanel::runningProgramName() const +{ + return m_terminal ? m_terminal->foregroundProcessName() : QString(); +} + +bool TerminalPanel::hasProgramRunning() const +{ + return m_terminal && (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 && !hasProgramRunning() && 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 @@ -47,6 +47,11 @@ QCheckBox* m_confirmMoveToTrash; QCheckBox* m_confirmEmptyTrash; QCheckBox* m_confirmDelete; + + #ifndef Q_OS_WIN + QCheckBox* m_confirmClosingTerminalRunningProgram; + #endif + 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 @@ -40,6 +40,11 @@ m_confirmMoveToTrash(nullptr), m_confirmEmptyTrash(nullptr), m_confirmDelete(nullptr), + + #ifndef Q_OS_WIN + m_confirmClosingTerminalRunningProgram(nullptr), + #endif + m_confirmClosingMultipleTabs(nullptr) { QVBoxLayout* topLayout = new QVBoxLayout(this); @@ -62,14 +67,24 @@ m_confirmClosingMultipleTabs = new QCheckBox(i18nc("@option:check Ask for confirmation in Dolphin when", "Closing windows with multiple tabs"), this); + #ifndef Q_OS_WIN + m_confirmClosingTerminalRunningProgram = new QCheckBox(i18nc("@option:check Ask for confirmation when", + "Closing windows with a program running in the Terminal panel"), this); + #endif + topLayout->addWidget(confirmLabelKde); topLayout->addWidget(m_confirmMoveToTrash); topLayout->addWidget(m_confirmEmptyTrash); topLayout->addWidget(m_confirmDelete); topLayout->addWidget(m_confirmScriptExecution); topLayout->addSpacing(Dolphin::VERTICAL_SPACER_HEIGHT); topLayout->addWidget(confirmLabelDolphin); topLayout->addWidget(m_confirmClosingMultipleTabs); + + #ifndef Q_OS_WIN + topLayout->addWidget(m_confirmClosingTerminalRunningProgram); + #endif + topLayout->addStretch(); loadSettings(); @@ -79,6 +94,10 @@ connect(m_confirmDelete, &QCheckBox::toggled, this, &ConfirmationsSettingsPage::changed); connect(m_confirmScriptExecution, &QCheckBox::toggled, this, &ConfirmationsSettingsPage::changed); connect(m_confirmClosingMultipleTabs, &QCheckBox::toggled, this, &ConfirmationsSettingsPage::changed); + + #ifndef Q_OS_WIN + connect(m_confirmClosingTerminalRunningProgram, &QCheckBox::toggled, this, &ConfirmationsSettingsPage::changed); + #endif } ConfirmationsSettingsPage::~ConfirmationsSettingsPage() @@ -103,6 +122,11 @@ GeneralSettings* settings = GeneralSettings::self(); settings->setConfirmClosingMultipleTabs(m_confirmClosingMultipleTabs->isChecked()); + + #ifndef Q_OS_WIN + settings->setConfirmClosingTerminalRunningProgram(m_confirmClosingTerminalRunningProgram->isChecked()); + #endif + settings->save(); } @@ -132,5 +156,9 @@ m_confirmScriptExecution->setChecked(value == QLatin1String("alwaysAsk")); m_confirmClosingMultipleTabs->setChecked(GeneralSettings::confirmClosingMultipleTabs()); + + #ifndef Q_OS_WIN + m_confirmClosingTerminalRunningProgram->setChecked(GeneralSettings::confirmClosingTerminalRunningProgram()); + #endif }