mirror of
https://github.com/TermoraDev/termora.git
synced 2026-01-16 10:22:58 +08:00
feat: confirm tab close (#605)
This commit is contained in:
@@ -648,6 +648,11 @@ class Database private constructor(private val env: Environment) : Disposable {
|
||||
*/
|
||||
var backgroundRunning by BooleanPropertyDelegate(false)
|
||||
|
||||
/**
|
||||
* 标签关闭前确认
|
||||
*/
|
||||
var confirmTabClose by BooleanPropertyDelegate(false)
|
||||
|
||||
/**
|
||||
* 背景图片的地址
|
||||
*/
|
||||
|
||||
@@ -223,10 +223,9 @@ class SSHTerminalTab(windowScope: WindowScope, host: Host) :
|
||||
}
|
||||
}
|
||||
|
||||
override fun willBeClose(): Boolean {
|
||||
override fun beforeClose() {
|
||||
// 保存窗口状态
|
||||
terminalPanel.storeVisualWindows(host.id)
|
||||
return super.willBeClose()
|
||||
}
|
||||
|
||||
private inner class MySessionListener : SessionListener, Disposable {
|
||||
|
||||
@@ -132,6 +132,7 @@ class SettingsOptionsPane : OptionsPane() {
|
||||
val themeComboBox = FlatComboBox<String>()
|
||||
val languageComboBox = FlatComboBox<String>()
|
||||
val backgroundComBoBox = YesOrNoComboBox()
|
||||
val confirmTabCloseComBoBox = YesOrNoComboBox()
|
||||
val followSystemCheckBox = JCheckBox(I18n.getString("termora.settings.appearance.follow-system"))
|
||||
val preferredThemeBtn = JButton(Icons.settings)
|
||||
val opacitySpinner = NumberSpinner(100, 0, 100)
|
||||
@@ -180,6 +181,7 @@ class SettingsOptionsPane : OptionsPane() {
|
||||
followSystemCheckBox.isSelected = appearance.followSystem
|
||||
preferredThemeBtn.isEnabled = followSystemCheckBox.isSelected
|
||||
backgroundComBoBox.selectedItem = appearance.backgroundRunning
|
||||
confirmTabCloseComBoBox.selectedItem = appearance.confirmTabClose
|
||||
|
||||
themeComboBox.isEnabled = !followSystemCheckBox.isSelected
|
||||
themeManager.themes.keys.forEach { themeComboBox.addItem(it) }
|
||||
@@ -230,6 +232,13 @@ class SettingsOptionsPane : OptionsPane() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
confirmTabCloseComBoBox.addItemListener {
|
||||
if (it.stateChange == ItemEvent.SELECTED) {
|
||||
appearance.confirmTabClose = confirmTabCloseComBoBox.selectedItem as Boolean
|
||||
}
|
||||
}
|
||||
|
||||
followSystemCheckBox.addActionListener {
|
||||
appearance.followSystem = followSystemCheckBox.isSelected
|
||||
themeComboBox.isEnabled = !followSystemCheckBox.isSelected
|
||||
@@ -368,7 +377,7 @@ class SettingsOptionsPane : OptionsPane() {
|
||||
private fun getFormPanel(): JPanel {
|
||||
val layout = FormLayout(
|
||||
"left:pref, $formMargin, default:grow, $formMargin, default, default:grow",
|
||||
"pref, $formMargin, pref, $formMargin, pref, $formMargin, pref, $formMargin, pref"
|
||||
"pref, $formMargin, pref, $formMargin, pref, $formMargin, pref, $formMargin, pref, $formMargin, pref"
|
||||
)
|
||||
val box = FlatToolBar()
|
||||
box.add(followSystemCheckBox)
|
||||
@@ -401,7 +410,13 @@ class SettingsOptionsPane : OptionsPane() {
|
||||
.add(opacitySpinner).xy(3, rows).apply { rows += step }
|
||||
|
||||
builder.add("${I18n.getString("termora.settings.appearance.background-running")}:").xy(1, rows)
|
||||
.add(backgroundComBoBox).xy(3, rows)
|
||||
.add(backgroundComBoBox).xy(3, rows).apply { rows += step }
|
||||
|
||||
val confirmTabCloseBox = Box.createHorizontalBox()
|
||||
confirmTabCloseBox.add(JLabel("${I18n.getString("termora.settings.appearance.confirm-tab-close")}:"))
|
||||
confirmTabCloseBox.add(Box.createHorizontalStrut(8))
|
||||
confirmTabCloseBox.add(confirmTabCloseComBoBox)
|
||||
builder.add(confirmTabCloseBox).xyw(1, rows,3).apply { rows += step }
|
||||
|
||||
return builder.build()
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package app.termora
|
||||
|
||||
import app.termora.Database.Appearance
|
||||
import app.termora.actions.DataProvider
|
||||
import java.beans.PropertyChangeListener
|
||||
import javax.swing.Icon
|
||||
@@ -44,10 +45,15 @@ interface TerminalTab : Disposable, DataProvider {
|
||||
fun canClose(): Boolean = true
|
||||
|
||||
/**
|
||||
* 返回 true 表示可以关闭
|
||||
* 返回 true 表示可以关闭,只有当 [Appearance.confirmTabClose] 为 false 时才会调用
|
||||
*/
|
||||
fun willBeClose(): Boolean = true
|
||||
|
||||
/**
|
||||
* 即将关闭,已经无法挽回
|
||||
*/
|
||||
fun beforeClose() {}
|
||||
|
||||
/**
|
||||
* 是否可以克隆
|
||||
*/
|
||||
|
||||
@@ -32,6 +32,7 @@ class TerminalTabbed(
|
||||
private val actionManager = ActionManager.getInstance()
|
||||
private val dataProviderSupport = DataProviderSupport()
|
||||
private val titleProperty = UUID.randomUUID().toSimpleString()
|
||||
private val appearance get() = Database.getDatabase().appearance
|
||||
private val iconListener = PropertyChangeListener { e ->
|
||||
val source = e.source
|
||||
if (e.propertyName == "icon" && source is TerminalTab) {
|
||||
@@ -153,8 +154,29 @@ class TerminalTabbed(
|
||||
if (tabbedPane.isTabClosable(index)) {
|
||||
val tab = tabs[index]
|
||||
|
||||
// 询问是否可以关闭
|
||||
if (disposable) {
|
||||
if (!tab.willBeClose()) {
|
||||
// 如果开启了关闭确认,那么直接询问用户
|
||||
if (appearance.confirmTabClose) {
|
||||
if (OptionPane.showConfirmDialog(
|
||||
windowScope.window,
|
||||
I18n.getString("termora.tabbed.tab.close-prompt"),
|
||||
messageType = JOptionPane.QUESTION_MESSAGE,
|
||||
optionType = JOptionPane.OK_CANCEL_OPTION
|
||||
) != JOptionPane.OK_OPTION
|
||||
) {
|
||||
return
|
||||
}
|
||||
} else if (!tab.willBeClose()) { // 如果没有开启则询问用户
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 通知即将关闭
|
||||
if (disposable) {
|
||||
try {
|
||||
tab.beforeClose()
|
||||
} catch (_: Exception) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user