From a7af120cf0635f048e5df18e6ca6c1e853071825 Mon Sep 17 00:00:00 2001 From: Yihe Li Date: Thu, 27 Mar 2025 07:22:05 +0800 Subject: [PATCH] Fix interaction with invalid chars Signed-off-by: Yihe Li --- launcher/InstanceDirUpdate.cpp | 19 +++++++++++-------- launcher/InstanceDirUpdate.h | 4 ++-- launcher/InstanceList.cpp | 17 +++++++++++++++++ launcher/InstanceList.h | 2 ++ launcher/ui/MainWindow.cpp | 25 ++++++++++++++++++------- launcher/ui/MainWindow.h | 1 + 6 files changed, 51 insertions(+), 17 deletions(-) diff --git a/launcher/InstanceDirUpdate.cpp b/launcher/InstanceDirUpdate.cpp index a6ca6ca23..8064082fd 100644 --- a/launcher/InstanceDirUpdate.cpp +++ b/launcher/InstanceDirUpdate.cpp @@ -46,24 +46,27 @@ #include "InstanceList.h" #include "ui/dialogs/CustomMessageBox.h" -bool askToUpdateInstanceDirName(InstancePtr instance, QWidget* parent) +QString askToUpdateInstanceDirName(InstancePtr instance, QWidget* parent) { QString renamingMode = APPLICATION->settings()->get("InstRenamingMode").toString(); if (renamingMode == "MetadataOnly") - return false; + return QString(); auto oldRoot = instance->instanceRoot(); auto oldName = QFileInfo(oldRoot).baseName(); + if (oldName == FS::RemoveInvalidFilenameChars(instance->name(), '-')) + return QString(); + auto newName = FS::DirNameFromString(instance->name(), QFileInfo(oldRoot).dir().absolutePath()); auto newRoot = FS::PathCombine(QFileInfo(oldRoot).dir().absolutePath(), newName); if (oldRoot == newRoot) - return false; + return QString(); // Check for conflict if (QDir(newRoot).exists()) { QMessageBox::warning(parent, QObject::tr("Cannot rename instance"), QObject::tr("New instance root (%1) already exists.
Only the metadata will be renamed.").arg(newRoot)); - return false; + return QString(); } // Ask if we should rename @@ -86,12 +89,12 @@ bool askToUpdateInstanceDirName(InstancePtr instance, QWidget* parent) APPLICATION->settings()->set("InstRenamingMode", "MetadataOnly"); } if (res == QMessageBox::No) - return false; + return QString(); } // Check for linked instances if (!checkLinkedInstances(instance->id(), parent)) - return false; + return QString(); // Now we can confirm that a renaming is happening if (!instance->syncInstanceDirName(newRoot)) { @@ -101,9 +104,9 @@ bool askToUpdateInstanceDirName(InstancePtr instance, QWidget* parent) " - New instance root: %2
" "Only the metadata is renamed.") .arg(oldRoot, newRoot)); - return false; + return QString(); } - return true; + return newRoot; } bool checkLinkedInstances(const QString& id, QWidget* parent) diff --git a/launcher/InstanceDirUpdate.h b/launcher/InstanceDirUpdate.h index 0059d8b7b..23738a19a 100644 --- a/launcher/InstanceDirUpdate.h +++ b/launcher/InstanceDirUpdate.h @@ -39,8 +39,8 @@ #include "BaseInstance.h" -/// Update instanceRoot to make it sync with name/id; return true if a refresh is needed -bool askToUpdateInstanceDirName(InstancePtr instance, QWidget* parent); +/// Update instanceRoot to make it sync with name/id; return newRoot if a directory rename happened +QString askToUpdateInstanceDirName(InstancePtr instance, QWidget* parent); /// Check if there are linked instances, and display a warning; return true if the operation should proceed bool checkLinkedInstances(const QString& id, QWidget* parent); diff --git a/launcher/InstanceList.cpp b/launcher/InstanceList.cpp index 918fa1073..a4f694e2e 100644 --- a/launcher/InstanceList.cpp +++ b/launcher/InstanceList.cpp @@ -583,6 +583,18 @@ InstancePtr InstanceList::getInstanceById(QString instId) const return InstancePtr(); } +InstancePtr InstanceList::getInstanceByRoot(QString instanceRoot) const +{ + if (instanceRoot.isEmpty()) + return InstancePtr(); + for (auto& inst : m_instances) { + if (inst->instanceRoot() == instanceRoot) { + return inst; + } + } + return InstancePtr(); +} + InstancePtr InstanceList::getInstanceByManagedName(const QString& managed_name) const { if (managed_name.isEmpty()) @@ -601,6 +613,11 @@ QModelIndex InstanceList::getInstanceIndexById(const QString& id) const return index(getInstIndex(getInstanceById(id).get())); } +QModelIndex InstanceList::getInstanceIndexByRoot(const QString& instanceRoot) const +{ + return index(getInstIndex(getInstanceByRoot(instanceRoot).get())); +} + int InstanceList::getInstIndex(BaseInstance* inst) const { int count = m_instances.count(); diff --git a/launcher/InstanceList.h b/launcher/InstanceList.h index c85fe55c7..dace9e5cf 100644 --- a/launcher/InstanceList.h +++ b/launcher/InstanceList.h @@ -99,9 +99,11 @@ class InstanceList : public QAbstractListModel { /* O(n) */ InstancePtr getInstanceById(QString id) const; + InstancePtr getInstanceByRoot(QString instanceRoot) const; /* O(n) */ InstancePtr getInstanceByManagedName(const QString& managed_name) const; QModelIndex getInstanceIndexById(const QString& id) const; + QModelIndex getInstanceIndexByRoot(const QString& instanceRoot) const; QStringList getGroups(); bool isGroupCollapsed(const QString& groupName); diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index f357b0765..43fe5c067 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -294,6 +294,12 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWi view->setFrameShape(QFrame::NoFrame); // do not show ugly blue border on the mac view->setAttribute(Qt::WA_MacShowFocusRect, false); + connect(view->itemDelegate(), &QAbstractItemDelegate::closeEditor, this, [this] { + if (auto newRoot = askToUpdateInstanceDirName(m_selectedInstance, this); !newRoot.isEmpty()) { + refreshInstances(); + setSelectedInstanceByRoot(newRoot); + } + }); view->installEventFilter(this); view->setContextMenuPolicy(Qt::CustomContextMenu); @@ -1133,6 +1139,18 @@ void MainWindow::setSelectedInstanceById(const QString& id) } } +void MainWindow::setSelectedInstanceByRoot(const QString& instanceRoot) +{ + if (instanceRoot.isNull()) + return; + const QModelIndex index = APPLICATION->instances()->getInstanceIndexByRoot(instanceRoot); + if (index.isValid()) { + QModelIndex selectionIndex = proxymodel->mapFromSource(index); + view->selectionModel()->setCurrentIndex(selectionIndex, QItemSelectionModel::ClearAndSelect); + updateStatusCenter(); + } +} + void MainWindow::on_actionChangeInstGroup_triggered() { if (!m_selectedInstance) @@ -1428,13 +1446,6 @@ void MainWindow::on_actionExportInstanceFlamePack_triggered() void MainWindow::on_actionRenameInstance_triggered() { if (m_selectedInstance) { - connect(view->itemDelegate(), &QAbstractItemDelegate::closeEditor, this, [this] { - if (askToUpdateInstanceDirName(m_selectedInstance, this)) { - auto newID = m_selectedInstance->name(); - refreshInstances(); - setSelectedInstanceById(newID); - } - }, Qt::SingleShotConnection); view->edit(view->currentIndex()); } } diff --git a/launcher/ui/MainWindow.h b/launcher/ui/MainWindow.h index 0e692eda7..02e9bb31e 100644 --- a/launcher/ui/MainWindow.h +++ b/launcher/ui/MainWindow.h @@ -224,6 +224,7 @@ class MainWindow : public QMainWindow { void setCatBackground(bool enabled); void updateInstanceToolIcon(QString new_icon); void setSelectedInstanceById(const QString& id); + void setSelectedInstanceByRoot(const QString& instanceRoot); void updateStatusCenter(); void setInstanceActionsEnabled(bool enabled);