From 36e81949e00e4cfee015966817047b547cb593a4 Mon Sep 17 00:00:00 2001 From: TellowKrinkle Date: Sat, 9 Sep 2023 02:15:41 -0500 Subject: [PATCH] Qt: Use proper Show in Finder on macOS --- common/CocoaTools.h | 2 ++ common/CocoaTools.mm | 9 +++++++++ pcsx2-qt/MainWindow.cpp | 5 ++--- pcsx2-qt/QtUtils.cpp | 39 +++++++++++++++++++++++++++++++++++++++ pcsx2-qt/QtUtils.h | 7 +++++++ 5 files changed, 59 insertions(+), 3 deletions(-) diff --git a/common/CocoaTools.h b/common/CocoaTools.h index 42cfbd882c..7a1a1be521 100644 --- a/common/CocoaTools.h +++ b/common/CocoaTools.h @@ -23,6 +23,8 @@ namespace CocoaTools std::optional MoveToTrash(std::string_view file); /// Launch the given application once this one quits bool DelayedLaunch(std::string_view file); + /// Open a Finder window to the given URL + bool ShowInFinder(std::string_view file); } #endif // __APPLE__ diff --git a/common/CocoaTools.mm b/common/CocoaTools.mm index 2b68f0bc7f..63d69fde7b 100644 --- a/common/CocoaTools.mm +++ b/common/CocoaTools.mm @@ -176,3 +176,12 @@ bool CocoaTools::DelayedLaunch(std::string_view file) return [task launchAndReturnError:nil]; } } + +// MARK: - Directory Services + +bool CocoaTools::ShowInFinder(std::string_view file) +{ + NSString* str = [[NSString alloc] initWithBytes:file.data() length:file.size() encoding:NSUTF8StringEncoding]; + return [[NSWorkspace sharedWorkspace] selectFile:str + inFileViewerRootedAtPath:nil]; +} diff --git a/pcsx2-qt/MainWindow.cpp b/pcsx2-qt/MainWindow.cpp index c48af575f6..f60ab33763 100644 --- a/pcsx2-qt/MainWindow.cpp +++ b/pcsx2-qt/MainWindow.cpp @@ -1318,11 +1318,10 @@ void MainWindow::onGameListEntryContextMenuRequested(const QPoint& point) }); } - //: Refers to the directory where a game is contained. - action = menu.addAction(tr("Open Containing Directory...")); + action = menu.addAction(QtUtils::GetShowInFileExplorerMessage()); connect(action, &QAction::triggered, [this, entry]() { const QFileInfo fi(QString::fromStdString(entry->path)); - QtUtils::OpenURL(this, QUrl::fromLocalFile(fi.absolutePath())); + QtUtils::ShowInFileExplorer(this, fi); }); action = menu.addAction(tr("Set Cover Image...")); diff --git a/pcsx2-qt/QtUtils.cpp b/pcsx2-qt/QtUtils.cpp index b09737d2cf..c0a2c5924f 100644 --- a/pcsx2-qt/QtUtils.cpp +++ b/pcsx2-qt/QtUtils.cpp @@ -4,6 +4,7 @@ #include "QtUtils.h" #include +#include #include #include #include @@ -26,10 +27,12 @@ #include #include +#include "common/CocoaTools.h" #include "common/Console.h" #if defined(_WIN32) #include "common/RedtapeWindows.h" +#include #elif !defined(APPLE) #include #endif @@ -129,6 +132,42 @@ namespace QtUtils ResizeColumnsForView(view, widths); } + void ShowInFileExplorer(QWidget* parent, const QFileInfo& file) + { +#if defined(_WIN32) + std::wstring wstr = QDir::toNativeSeparators(file.absoluteFilePath()).toStdWString(); + bool ok = false; + if (PIDLIST_ABSOLUTE pidl = ILCreateFromPath(wstr.c_str())) + { + ok = SUCCEEDED(SHOpenFolderAndSelectItems(pidl, 0, nullptr, 0)); + ILFree(pidl); + } +#elif defined(__APPLE__) + bool ok = CocoaTools::ShowInFinder(file.absoluteFilePath().toStdString()); +#else + bool ok = QDesktopServices::openUrl(QUrl::fromLocalFile(file.absolutePath())); +#endif + if (!ok) + { + QMessageBox::critical(parent, QCoreApplication::translate("FileOperations", "Failed to show file"), + QCoreApplication::translate("FileOperations", "Failed to show file in file explorer.\n\nThe file was: %1").arg(file.absoluteFilePath())); + } + } + + QString GetShowInFileExplorerMessage() + { +#if defined(_WIN32) + //: Windows action to show a file in Windows Explorer + return QCoreApplication::translate("FileOperations", "Show in Folder"); +#elif defined(__APPLE__) + //: macOS action to show a file in Finder + return QCoreApplication::translate("FileOperations", "Show in Finder"); +#else + //: Opens the system file manager to the directory containing a selected file + return QCoreApplication::translate("FileOperations", "Open Containing Directory"); +#endif + } + void OpenURL(QWidget* parent, const QUrl& qurl) { if (!QDesktopServices::openUrl(qurl)) diff --git a/pcsx2-qt/QtUtils.h b/pcsx2-qt/QtUtils.h index 651cfe426b..6818ee6f93 100644 --- a/pcsx2-qt/QtUtils.h +++ b/pcsx2-qt/QtUtils.h @@ -18,6 +18,7 @@ class ByteStream; class QAction; class QComboBox; +class QFileInfo; class QFrame; class QKeyEvent; class QTableView; @@ -49,6 +50,12 @@ namespace QtUtils /// NOTE: Defined in QtKeyCodes.cpp, not QtUtils.cpp. u32 KeyEventToCode(const QKeyEvent* ev); + /// Shows a file, or the containing folder if unsupported, with the system file explorer + void ShowInFileExplorer(QWidget* parent, const QFileInfo& file); + + /// Get the context menu name for the action performed by ShowInFileExplorer + QString GetShowInFileExplorerMessage(); + /// Opens a URL with the default handler. void OpenURL(QWidget* parent, const QUrl& qurl);