From d57bd62add52df91c8495c172a7b19d9fca6b919 Mon Sep 17 00:00:00 2001 From: vit9696 Date: Tue, 12 Dec 2017 18:00:56 +0300 Subject: [PATCH 1/3] Fix torrent file selection in Finder on mac --- src/gui/macutilities.h | 1 + src/gui/macutilities.mm | 13 +++++++++++++ src/gui/transferlistwidget.cpp | 14 ++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/src/gui/macutilities.h b/src/gui/macutilities.h index b9eda325f..02c4a1be6 100644 --- a/src/gui/macutilities.h +++ b/src/gui/macutilities.h @@ -36,5 +36,6 @@ QPixmap pixmapForExtension(const QString &ext, const QSize &size); void overrideDockClickHandler(bool (*dockClickHandler)(id, SEL, ...)); void displayNotification(const QString &title, const QString &message); +void openFiles(const QSet &pathsList); #endif // MACUTILITIES_H diff --git a/src/gui/macutilities.mm b/src/gui/macutilities.mm index 2a6b0c6f6..d950e21c6 100644 --- a/src/gui/macutilities.mm +++ b/src/gui/macutilities.mm @@ -28,6 +28,7 @@ #include "macutilities.h" +#include #include #include #import @@ -81,3 +82,15 @@ void displayNotification(const QString &title, const QString &message) [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification]; } } + +void openFiles(const QSet &pathsList) +{ + @autoreleasepool { + NSMutableArray *pathURLs = [NSMutableArray arrayWithCapacity:pathsList.size()]; + + for (const auto &path : pathsList) + [pathURLs addObject:[NSURL fileURLWithPath:path.toNSString()]]; + + [[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs:pathURLs]; + } +} diff --git a/src/gui/transferlistwidget.cpp b/src/gui/transferlistwidget.cpp index 756588b23..4a1a730a7 100644 --- a/src/gui/transferlistwidget.cpp +++ b/src/gui/transferlistwidget.cpp @@ -62,6 +62,10 @@ #include "transferlistsortmodel.h" #include "updownratiodlg.h" +#ifdef Q_OS_MAC +#include "macutilities.h" +#endif + namespace { using ToggleFn = std::function; @@ -548,6 +552,15 @@ void TransferListWidget::hidePriorityColumn(bool hide) void TransferListWidget::openSelectedTorrentsFolder() const { QSet pathsList; +#ifdef Q_OS_MAC + // On macOS you expect both the files and folders to be opened in their parent + // folders prehilighted for opening, so we use a custom method. + foreach (BitTorrent::TorrentHandle *const torrent, getSelectedTorrents()) { + QString path = torrent->contentPath(true); + pathsList.insert(path); + } + openFiles(pathsList); +#else foreach (BitTorrent::TorrentHandle *const torrent, getSelectedTorrents()) { QString path = torrent->contentPath(true); if (!pathsList.contains(path)) { @@ -558,6 +571,7 @@ void TransferListWidget::openSelectedTorrentsFolder() const } pathsList.insert(path); } +#endif } void TransferListWidget::previewSelectedTorrents() From d7fa5b6b6bba36e9748f5565fa63d84b9f19def4 Mon Sep 17 00:00:00 2001 From: vit9696 Date: Tue, 12 Dec 2017 20:20:48 +0300 Subject: [PATCH 2/3] Put macOS specific functions to MacUtils namespace --- src/gui/macutilities.h | 11 ++-- src/gui/macutilities.mm | 99 +++++++++++++++++---------------- src/gui/mainwindow.cpp | 4 +- src/gui/torrentcontentmodel.cpp | 2 +- src/gui/transferlistwidget.cpp | 2 +- 5 files changed, 62 insertions(+), 56 deletions(-) diff --git a/src/gui/macutilities.h b/src/gui/macutilities.h index 02c4a1be6..cbf00bc09 100644 --- a/src/gui/macutilities.h +++ b/src/gui/macutilities.h @@ -33,9 +33,12 @@ #include #include -QPixmap pixmapForExtension(const QString &ext, const QSize &size); -void overrideDockClickHandler(bool (*dockClickHandler)(id, SEL, ...)); -void displayNotification(const QString &title, const QString &message); -void openFiles(const QSet &pathsList); +namespace MacUtils +{ + QPixmap pixmapForExtension(const QString &ext, const QSize &size); + void overrideDockClickHandler(bool (*dockClickHandler)(id, SEL, ...)); + void displayNotification(const QString &title, const QString &message); + void openFiles(const QSet &pathsList); +} #endif // MACUTILITIES_H diff --git a/src/gui/macutilities.mm b/src/gui/macutilities.mm index d950e21c6..5a8e81aeb 100644 --- a/src/gui/macutilities.mm +++ b/src/gui/macutilities.mm @@ -33,64 +33,67 @@ #include #import -QPixmap pixmapForExtension(const QString &ext, const QSize &size) +namespace MacUtils { - @autoreleasepool { - NSImage *image = [[NSWorkspace sharedWorkspace] iconForFileType:ext.toNSString()]; - if (image) { - NSRect rect = NSMakeRect(0, 0, size.width(), size.height()); - CGImageRef cgImage = [image CGImageForProposedRect:&rect context:nil hints:nil]; - return QtMac::fromCGImageRef(cgImage); + QPixmap pixmapForExtension(const QString &ext, const QSize &size) + { + @autoreleasepool { + NSImage *image = [[NSWorkspace sharedWorkspace] iconForFileType:ext.toNSString()]; + if (image) { + NSRect rect = NSMakeRect(0, 0, size.width(), size.height()); + CGImageRef cgImage = [image CGImageForProposedRect:&rect context:nil hints:nil]; + return QtMac::fromCGImageRef(cgImage); + } + + return QPixmap(); } - - return QPixmap(); } -} -void overrideDockClickHandler(bool (*dockClickHandler)(id, SEL, ...)) -{ - NSApplication *appInst = [NSApplication sharedApplication]; - - if (!appInst) - return; - - Class delClass = [[appInst delegate] class]; - SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:"); - - if (class_getInstanceMethod(delClass, shouldHandle)) { - if (class_replaceMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:")) - qDebug("Registered dock click handler (replaced original method)"); - else - qWarning("Failed to replace method for dock click handler"); - } - else { - if (class_addMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:")) - qDebug("Registered dock click handler"); - else - qWarning("Failed to register dock click handler"); + void overrideDockClickHandler(bool (*dockClickHandler)(id, SEL, ...)) + { + NSApplication *appInst = [NSApplication sharedApplication]; + + if (!appInst) + return; + + Class delClass = [[appInst delegate] class]; + SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:"); + + if (class_getInstanceMethod(delClass, shouldHandle)) { + if (class_replaceMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:")) + qDebug("Registered dock click handler (replaced original method)"); + else + qWarning("Failed to replace method for dock click handler"); + } + else { + if (class_addMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:")) + qDebug("Registered dock click handler"); + else + qWarning("Failed to register dock click handler"); + } } -} -void displayNotification(const QString &title, const QString &message) -{ - @autoreleasepool { - NSUserNotification *notification = [[NSUserNotification alloc] init]; - notification.title = title.toNSString(); - notification.informativeText = message.toNSString(); - notification.soundName = NSUserNotificationDefaultSoundName; + void displayNotification(const QString &title, const QString &message) + { + @autoreleasepool { + NSUserNotification *notification = [[NSUserNotification alloc] init]; + notification.title = title.toNSString(); + notification.informativeText = message.toNSString(); + notification.soundName = NSUserNotificationDefaultSoundName; - [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification]; + [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification]; + } } -} -void openFiles(const QSet &pathsList) -{ - @autoreleasepool { - NSMutableArray *pathURLs = [NSMutableArray arrayWithCapacity:pathsList.size()]; + void openFiles(const QSet &pathsList) + { + @autoreleasepool { + NSMutableArray *pathURLs = [NSMutableArray arrayWithCapacity:pathsList.size()]; - for (const auto &path : pathsList) - [pathURLs addObject:[NSURL fileURLWithPath:path.toNSString()]]; + for (const auto &path : pathsList) + [pathURLs addObject:[NSURL fileURLWithPath:path.toNSString()]]; - [[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs:pathURLs]; + [[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs:pathURLs]; + } } } diff --git a/src/gui/mainwindow.cpp b/src/gui/mainwindow.cpp index 431fd7904..790afbeca 100644 --- a/src/gui/mainwindow.cpp +++ b/src/gui/mainwindow.cpp @@ -1298,7 +1298,7 @@ static bool dockClickHandler(id self, SEL cmd, ...) void MainWindow::setupDockClickHandler() { dockMainWindowHandle = this; - overrideDockClickHandler(dockClickHandler); + MacUtils::overrideDockClickHandler(dockClickHandler); } #endif @@ -1557,7 +1557,7 @@ void MainWindow::showNotificationBaloon(QString title, QString msg) const if (!reply.isError()) return; #elif defined(Q_OS_MAC) - displayNotification(title, msg); + MacUtils::displayNotification(title, msg); #else if (m_systrayIcon && QSystemTrayIcon::supportsMessages()) m_systrayIcon->showMessage(title, msg, QSystemTrayIcon::Information, TIME_TRAY_BALLOON); diff --git a/src/gui/torrentcontentmodel.cpp b/src/gui/torrentcontentmodel.cpp index 48a05ec9d..9130c86b7 100644 --- a/src/gui/torrentcontentmodel.cpp +++ b/src/gui/torrentcontentmodel.cpp @@ -150,7 +150,7 @@ namespace { QPixmap pixmapForExtension(const QString &ext) const override { - return ::pixmapForExtension(ext, QSize(32, 32)); + return MacUtils::pixmapForExtension(ext, QSize(32, 32)); } }; #else diff --git a/src/gui/transferlistwidget.cpp b/src/gui/transferlistwidget.cpp index 4a1a730a7..50471b189 100644 --- a/src/gui/transferlistwidget.cpp +++ b/src/gui/transferlistwidget.cpp @@ -559,7 +559,7 @@ void TransferListWidget::openSelectedTorrentsFolder() const QString path = torrent->contentPath(true); pathsList.insert(path); } - openFiles(pathsList); + MacUtils::openFiles(pathsList); #else foreach (BitTorrent::TorrentHandle *const torrent, getSelectedTorrents()) { QString path = torrent->contentPath(true); From ed154d35bac9b5c54c8d1b15fc5a23fec8403be0 Mon Sep 17 00:00:00 2001 From: vit9696 Date: Sun, 17 Dec 2017 02:16:36 +0300 Subject: [PATCH 3/3] Fix Finder reveal in preview and torrent contents --- src/gui/properties/propertieswidget.cpp | 8 ++++++++ src/gui/transferlistwidget.cpp | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/src/gui/properties/propertieswidget.cpp b/src/gui/properties/propertieswidget.cpp index 4f6384da0..2e6fcb625 100644 --- a/src/gui/properties/propertieswidget.cpp +++ b/src/gui/properties/propertieswidget.cpp @@ -65,6 +65,10 @@ #include "ui_propertieswidget.h" +#ifdef Q_OS_MAC +#include "macutilities.h" +#endif + PropertiesWidget::PropertiesWidget(QWidget *parent, MainWindow *mainWindow, TransferListWidget *transferList) : QWidget(parent) , m_ui(new Ui::PropertiesWidget()) @@ -574,10 +578,14 @@ void PropertiesWidget::openFolder(const QModelIndex &index, bool containingFolde // Flush data m_torrent->flushCache(); +#ifdef Q_OS_MAC + MacUtils::openFiles(QSet{absolutePath}); +#else if (containingFolder) Utils::Misc::openFolderSelect(absolutePath); else Utils::Misc::openPath(absolutePath); +#endif } void PropertiesWidget::displayFilesListMenu(const QPoint &) diff --git a/src/gui/transferlistwidget.cpp b/src/gui/transferlistwidget.cpp index 50471b189..df965096b 100644 --- a/src/gui/transferlistwidget.cpp +++ b/src/gui/transferlistwidget.cpp @@ -362,10 +362,14 @@ void TransferListWidget::torrentDoubleClicked() torrent->pause(); break; case OPEN_DEST: +#ifdef Q_OS_MAC + MacUtils::openFiles(QSet{torrent->contentPath(true)}); +#else if (torrent->filesCount() == 1) Utils::Misc::openFolderSelect(torrent->contentPath(true)); else Utils::Misc::openPath(torrent->contentPath(true)); +#endif break; } }