Browse Source

Merge pull request #8032 from vit9696/fopen

Fix torrent file selection in Finder on mac
adaptive-webui-19844
sledgehammer999 7 years ago committed by GitHub
parent
commit
ea44923cce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      src/gui/macutilities.h
  2. 88
      src/gui/macutilities.mm
  3. 4
      src/gui/mainwindow.cpp
  4. 8
      src/gui/properties/propertieswidget.cpp
  5. 2
      src/gui/torrentcontentmodel.cpp
  6. 18
      src/gui/transferlistwidget.cpp

10
src/gui/macutilities.h

@ -33,8 +33,12 @@
#include <QSize> #include <QSize>
#include <objc/objc.h> #include <objc/objc.h>
QPixmap pixmapForExtension(const QString &ext, const QSize &size); namespace MacUtils
void overrideDockClickHandler(bool (*dockClickHandler)(id, SEL, ...)); {
void displayNotification(const QString &title, const QString &message); 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<QString> &pathsList);
}
#endif // MACUTILITIES_H #endif // MACUTILITIES_H

88
src/gui/macutilities.mm

@ -28,56 +28,72 @@
#include "macutilities.h" #include "macutilities.h"
#include <QSet>
#include <QtMac> #include <QtMac>
#include <objc/message.h> #include <objc/message.h>
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
QPixmap pixmapForExtension(const QString &ext, const QSize &size) namespace MacUtils
{ {
@autoreleasepool { QPixmap pixmapForExtension(const QString &ext, const QSize &size)
NSImage *image = [[NSWorkspace sharedWorkspace] iconForFileType:ext.toNSString()]; {
if (image) { @autoreleasepool {
NSRect rect = NSMakeRect(0, 0, size.width(), size.height()); NSImage *image = [[NSWorkspace sharedWorkspace] iconForFileType:ext.toNSString()];
CGImageRef cgImage = [image CGImageForProposedRect:&rect context:nil hints:nil]; if (image) {
return QtMac::fromCGImageRef(cgImage); 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, ...)) void overrideDockClickHandler(bool (*dockClickHandler)(id, SEL, ...))
{ {
NSApplication *appInst = [NSApplication sharedApplication]; NSApplication *appInst = [NSApplication sharedApplication];
if (!appInst) if (!appInst)
return; return;
Class delClass = [[appInst delegate] class]; Class delClass = [[appInst delegate] class];
SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:"); SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:");
if (class_getInstanceMethod(delClass, shouldHandle)) { if (class_getInstanceMethod(delClass, shouldHandle)) {
if (class_replaceMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:")) if (class_replaceMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:"))
qDebug("Registered dock click handler (replaced original method)"); qDebug("Registered dock click handler (replaced original method)");
else else
qWarning("Failed to replace method for dock click handler"); 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");
}
} }
else {
if (class_addMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:")) void displayNotification(const QString &title, const QString &message)
qDebug("Registered dock click handler"); {
else @autoreleasepool {
qWarning("Failed to register dock click handler"); NSUserNotification *notification = [[NSUserNotification alloc] init];
notification.title = title.toNSString();
notification.informativeText = message.toNSString();
notification.soundName = NSUserNotificationDefaultSoundName;
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
}
} }
}
void displayNotification(const QString &title, const QString &message) void openFiles(const QSet<QString> &pathsList)
{ {
@autoreleasepool { @autoreleasepool {
NSUserNotification *notification = [[NSUserNotification alloc] init]; NSMutableArray *pathURLs = [NSMutableArray arrayWithCapacity:pathsList.size()];
notification.title = title.toNSString();
notification.informativeText = message.toNSString(); for (const auto &path : pathsList)
notification.soundName = NSUserNotificationDefaultSoundName; [pathURLs addObject:[NSURL fileURLWithPath:path.toNSString()]];
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification]; [[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs:pathURLs];
}
} }
} }

4
src/gui/mainwindow.cpp

@ -1298,7 +1298,7 @@ static bool dockClickHandler(id self, SEL cmd, ...)
void MainWindow::setupDockClickHandler() void MainWindow::setupDockClickHandler()
{ {
dockMainWindowHandle = this; dockMainWindowHandle = this;
overrideDockClickHandler(dockClickHandler); MacUtils::overrideDockClickHandler(dockClickHandler);
} }
#endif #endif
@ -1557,7 +1557,7 @@ void MainWindow::showNotificationBaloon(QString title, QString msg) const
if (!reply.isError()) if (!reply.isError())
return; return;
#elif defined(Q_OS_MAC) #elif defined(Q_OS_MAC)
displayNotification(title, msg); MacUtils::displayNotification(title, msg);
#else #else
if (m_systrayIcon && QSystemTrayIcon::supportsMessages()) if (m_systrayIcon && QSystemTrayIcon::supportsMessages())
m_systrayIcon->showMessage(title, msg, QSystemTrayIcon::Information, TIME_TRAY_BALLOON); m_systrayIcon->showMessage(title, msg, QSystemTrayIcon::Information, TIME_TRAY_BALLOON);

8
src/gui/properties/propertieswidget.cpp

@ -65,6 +65,10 @@
#include "ui_propertieswidget.h" #include "ui_propertieswidget.h"
#ifdef Q_OS_MAC
#include "macutilities.h"
#endif
PropertiesWidget::PropertiesWidget(QWidget *parent, MainWindow *mainWindow, TransferListWidget *transferList) PropertiesWidget::PropertiesWidget(QWidget *parent, MainWindow *mainWindow, TransferListWidget *transferList)
: QWidget(parent) : QWidget(parent)
, m_ui(new Ui::PropertiesWidget()) , m_ui(new Ui::PropertiesWidget())
@ -574,10 +578,14 @@ void PropertiesWidget::openFolder(const QModelIndex &index, bool containingFolde
// Flush data // Flush data
m_torrent->flushCache(); m_torrent->flushCache();
#ifdef Q_OS_MAC
MacUtils::openFiles(QSet<QString>{absolutePath});
#else
if (containingFolder) if (containingFolder)
Utils::Misc::openFolderSelect(absolutePath); Utils::Misc::openFolderSelect(absolutePath);
else else
Utils::Misc::openPath(absolutePath); Utils::Misc::openPath(absolutePath);
#endif
} }
void PropertiesWidget::displayFilesListMenu(const QPoint &) void PropertiesWidget::displayFilesListMenu(const QPoint &)

2
src/gui/torrentcontentmodel.cpp

@ -150,7 +150,7 @@ namespace
{ {
QPixmap pixmapForExtension(const QString &ext) const override QPixmap pixmapForExtension(const QString &ext) const override
{ {
return ::pixmapForExtension(ext, QSize(32, 32)); return MacUtils::pixmapForExtension(ext, QSize(32, 32));
} }
}; };
#else #else

18
src/gui/transferlistwidget.cpp

@ -62,6 +62,10 @@
#include "transferlistsortmodel.h" #include "transferlistsortmodel.h"
#include "updownratiodlg.h" #include "updownratiodlg.h"
#ifdef Q_OS_MAC
#include "macutilities.h"
#endif
namespace namespace
{ {
using ToggleFn = std::function<void (Qt::CheckState)>; using ToggleFn = std::function<void (Qt::CheckState)>;
@ -358,10 +362,14 @@ void TransferListWidget::torrentDoubleClicked()
torrent->pause(); torrent->pause();
break; break;
case OPEN_DEST: case OPEN_DEST:
#ifdef Q_OS_MAC
MacUtils::openFiles(QSet<QString>{torrent->contentPath(true)});
#else
if (torrent->filesCount() == 1) if (torrent->filesCount() == 1)
Utils::Misc::openFolderSelect(torrent->contentPath(true)); Utils::Misc::openFolderSelect(torrent->contentPath(true));
else else
Utils::Misc::openPath(torrent->contentPath(true)); Utils::Misc::openPath(torrent->contentPath(true));
#endif
break; break;
} }
} }
@ -548,6 +556,15 @@ void TransferListWidget::hidePriorityColumn(bool hide)
void TransferListWidget::openSelectedTorrentsFolder() const void TransferListWidget::openSelectedTorrentsFolder() const
{ {
QSet<QString> pathsList; QSet<QString> 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);
}
MacUtils::openFiles(pathsList);
#else
foreach (BitTorrent::TorrentHandle *const torrent, getSelectedTorrents()) { foreach (BitTorrent::TorrentHandle *const torrent, getSelectedTorrents()) {
QString path = torrent->contentPath(true); QString path = torrent->contentPath(true);
if (!pathsList.contains(path)) { if (!pathsList.contains(path)) {
@ -558,6 +575,7 @@ void TransferListWidget::openSelectedTorrentsFolder() const
} }
pathsList.insert(path); pathsList.insert(path);
} }
#endif
} }
void TransferListWidget::previewSelectedTorrents() void TransferListWidget::previewSelectedTorrents()

Loading…
Cancel
Save