Merge pull request #10573 from f321x/qml_wallet_rename
qml: allow renaming wallets
This commit is contained in:
@@ -585,6 +585,17 @@ class Daemon(Logger):
|
||||
return True
|
||||
return False
|
||||
|
||||
def rename_wallet_file(self, old_path: str, new_path: str):
|
||||
old_path = standardize_path(old_path)
|
||||
new_path = standardize_path(new_path)
|
||||
if os.path.exists(new_path):
|
||||
raise ValueError("Wallet file already exists")
|
||||
os.rename(old_path, new_path)
|
||||
self.logger.debug(f'renamed wallet: {old_path} -> {new_path}')
|
||||
self.update_recently_opened_wallets(old_path, remove=True)
|
||||
if self.config.CURRENT_WALLET == old_path:
|
||||
self.config.CURRENT_WALLET = new_path
|
||||
|
||||
def stop_wallet(self, path: str) -> bool:
|
||||
"""Returns True iff a wallet was found."""
|
||||
assert util.get_running_loop() != util.get_asyncio_loop(), 'must not be called from asyncio thread'
|
||||
|
||||
@@ -130,6 +130,64 @@ Pane {
|
||||
visible: Daemon.currentWallet
|
||||
columns: 2
|
||||
|
||||
Label {
|
||||
Layout.columnSpan: 2
|
||||
Layout.topMargin: constants.paddingSmall
|
||||
text: qsTr('Name')
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
TextHighlightPane {
|
||||
id: walletNameContent
|
||||
property bool editmode: false
|
||||
Layout.columnSpan: 2
|
||||
Layout.fillWidth: true
|
||||
|
||||
RowLayout {
|
||||
width: parent.width
|
||||
Label {
|
||||
visible: !walletNameContent.editmode
|
||||
text: Daemon.currentWallet.name
|
||||
wrapMode: Text.Wrap
|
||||
Layout.fillWidth: true
|
||||
font.pixelSize: constants.fontSizeLarge
|
||||
}
|
||||
ToolButton {
|
||||
visible: !walletNameContent.editmode
|
||||
icon.source: '../../icons/pen.png'
|
||||
icon.color: 'transparent'
|
||||
onClicked: {
|
||||
walletNameEdit.text = Daemon.currentWallet.name
|
||||
walletNameContent.editmode = true
|
||||
walletNameEdit.focus = true
|
||||
}
|
||||
}
|
||||
TextField {
|
||||
id: walletNameEdit
|
||||
visible: walletNameContent.editmode
|
||||
Layout.fillWidth: true
|
||||
font.pixelSize: constants.fontSizeLarge
|
||||
}
|
||||
ToolButton {
|
||||
visible: walletNameContent.editmode
|
||||
icon.source: '../../icons/confirmed.png'
|
||||
icon.color: enabled ? 'transparent' : constants.mutedForeground
|
||||
enabled: walletNameEdit.text !== Daemon.currentWallet.name
|
||||
&& Daemon.isValidWalletName(walletNameEdit.text)
|
||||
onClicked: {
|
||||
walletNameContent.editmode = false
|
||||
Daemon.renameWallet(walletNameEdit.text)
|
||||
}
|
||||
}
|
||||
ToolButton {
|
||||
visible: walletNameContent.editmode
|
||||
icon.source: '../../icons/closebutton.png'
|
||||
icon.color: 'transparent'
|
||||
onClicked: walletNameContent.editmode = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.columnSpan: 2
|
||||
Layout.topMargin: constants.paddingSmall
|
||||
@@ -526,6 +584,14 @@ Pane {
|
||||
dialog.open()
|
||||
}
|
||||
}
|
||||
function onWalletRenameError(message) {
|
||||
var dialog = app.messageDialog.createObject(app, {
|
||||
title: qsTr('Error'),
|
||||
iconSource: Qt.resolvedUrl('../../icons/warning.png'),
|
||||
text: message
|
||||
})
|
||||
dialog.open()
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
|
||||
@@ -150,6 +150,7 @@ class QEDaemon(AuthMixin, QObject):
|
||||
walletRequiresPassword = pyqtSignal([str, str], arguments=['name', 'path'])
|
||||
walletOpenError = pyqtSignal([str], arguments=["error"])
|
||||
walletDeleteError = pyqtSignal([str, str], arguments=['code', 'message'])
|
||||
walletRenameError = pyqtSignal([str], arguments=['message'])
|
||||
|
||||
def __init__(self, daemon: 'Daemon', plugins: 'Plugins', parent=None):
|
||||
super().__init__(parent)
|
||||
@@ -310,6 +311,34 @@ class QEDaemon(AuthMixin, QObject):
|
||||
|
||||
self.availableWallets.remove_wallet(path)
|
||||
|
||||
@pyqtSlot(str, result=bool)
|
||||
def isValidWalletName(self, wallet_name: str) -> bool:
|
||||
if not wallet_name:
|
||||
return False
|
||||
if self.availableWallets.wallet_name_exists(wallet_name):
|
||||
return False
|
||||
# ensure wallet_name is not interpreted as path
|
||||
if os.path.basename(wallet_name) != wallet_name: # '/foo/bar/' returns 'bar'
|
||||
return False
|
||||
return True
|
||||
|
||||
@pyqtSlot(str)
|
||||
def renameWallet(self, new_name: str):
|
||||
wallet = self._current_wallet
|
||||
assert wallet, "name change without wallet?"
|
||||
old_path = standardize_path(wallet.wallet.storage.path)
|
||||
wallet_dir = os.path.dirname(old_path)
|
||||
new_path = standardize_path(os.path.join(wallet_dir, new_name))
|
||||
if old_path == new_path:
|
||||
return
|
||||
self._current_wallet = None
|
||||
self.daemon.stop_wallet(old_path)
|
||||
try:
|
||||
self.daemon.rename_wallet_file(old_path, new_path)
|
||||
except Exception as e:
|
||||
self.walletRenameError.emit(_('Error renaming wallet:\n') + str(e))
|
||||
self.walletLoaded.emit(None, None)
|
||||
|
||||
@pyqtProperty(bool, notify=loadingChanged)
|
||||
def loading(self):
|
||||
return self._loading
|
||||
|
||||
Reference in New Issue
Block a user