mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-02-05 11:24:15 +00:00
Merge pull request #8032 from vit9696/fopen
Fix torrent file selection in Finder on mac
This commit is contained in:
commit
ea44923cce
@ -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
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void openFiles(const QSet<QString> &pathsList)
|
||||||
|
{
|
||||||
|
@autoreleasepool {
|
||||||
|
NSMutableArray *pathURLs = [NSMutableArray arrayWithCapacity:pathsList.size()];
|
||||||
|
|
||||||
|
for (const auto &path : pathsList)
|
||||||
|
[pathURLs addObject:[NSURL fileURLWithPath:path.toNSString()]];
|
||||||
|
|
||||||
|
[[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs:pathURLs];
|
||||||
}
|
}
|
||||||
|
|
||||||
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 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];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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 &)
|
||||||
|
@ -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
|
||||||
|
@ -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…
x
Reference in New Issue
Block a user