Improve .torrent associate handling

* Use correct pointer type in NSIS scripts
* Only remove qbt specific registry keys when uninstalling or disassociating
* Set .torrent Content Type when associating .torrent format
* Move ".torrent association" functions to Utils::OS class

PR #19709.
This commit is contained in:
Chocobo1 2023-10-16 14:51:17 +08:00 committed by GitHub
parent 90e023f138
commit cba433823f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 276 additions and 185 deletions

View file

@ -32,13 +32,6 @@
#include <algorithm>
#include <chrono>
#ifdef Q_OS_MACOS
#include <CoreServices/CoreServices.h>
#endif
#ifdef Q_OS_WIN
#include <shlobj.h>
#endif
#include <QCoreApplication>
#include <QDateTime>
#include <QDir>
@ -48,10 +41,6 @@
#include <QSettings>
#include <QTime>
#ifdef Q_OS_WIN
#include <QRegularExpression>
#endif
#include "algorithm.h"
#include "global.h"
#include "path.h"
@ -1317,150 +1306,8 @@ void Preferences::setNeverCheckFileAssoc(const bool check)
setValue(u"Preferences/Win32/NeverCheckFileAssocation"_s, check);
}
bool Preferences::isTorrentFileAssocSet()
{
const QSettings settings(u"HKEY_CURRENT_USER\\Software\\Classes"_s, QSettings::NativeFormat);
if (settings.value(u".torrent/Default"_s).toString() != u"qBittorrent")
{
qDebug(".torrent != qBittorrent");
return false;
}
return true;
}
void Preferences::setTorrentFileAssoc(const bool set)
{
QSettings settings(u"HKEY_CURRENT_USER\\Software\\Classes"_s, QSettings::NativeFormat);
// .Torrent association
if (set)
{
const QString oldProgId = settings.value(u".torrent/Default"_s).toString();
if (!oldProgId.isEmpty() && (oldProgId != u"qBittorrent"))
settings.setValue((u".torrent/OpenWithProgids/" + oldProgId), QString());
settings.setValue(u".torrent/Default"_s, u"qBittorrent"_s);
}
else if (isTorrentFileAssocSet())
{
settings.setValue(u".torrent/Default"_s, QString());
}
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0);
}
bool Preferences::isMagnetLinkAssocSet()
{
const QSettings settings(u"HKEY_CURRENT_USER\\Software\\Classes"_s, QSettings::NativeFormat);
// Check magnet link assoc
const QString shellCommand = settings.value(u"magnet/shell/open/command/Default"_s, QString()).toString();
const QRegularExpressionMatch exeRegMatch = QRegularExpression(u"\"([^\"]+)\".*"_s).match(shellCommand);
if (!exeRegMatch.hasMatch())
return false;
const Path assocExe {exeRegMatch.captured(1)};
if (assocExe != Path(qApp->applicationFilePath()))
return false;
return true;
}
void Preferences::setMagnetLinkAssoc(const bool set)
{
QSettings settings(u"HKEY_CURRENT_USER\\Software\\Classes"_s, QSettings::NativeFormat);
// Magnet association
if (set)
{
const QString applicationFilePath = Path(qApp->applicationFilePath()).toString();
const QString commandStr = u'"' + applicationFilePath + u"\" \"%1\"";
const QString iconStr = u'"' + applicationFilePath + u"\",1";
settings.setValue(u"magnet/Default"_s, u"URL:Magnet link"_s);
settings.setValue(u"magnet/Content Type"_s, u"application/x-magnet"_s);
settings.setValue(u"magnet/URL Protocol"_s, QString());
settings.setValue(u"magnet/DefaultIcon/Default"_s, iconStr);
settings.setValue(u"magnet/shell/Default"_s, u"open"_s);
settings.setValue(u"magnet/shell/open/command/Default"_s, commandStr);
}
else if (isMagnetLinkAssocSet())
{
settings.remove(u"magnet"_s);
}
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0);
}
#endif // Q_OS_WIN
#ifdef Q_OS_MACOS
namespace
{
const CFStringRef torrentExtension = CFSTR("torrent");
const CFStringRef magnetUrlScheme = CFSTR("magnet");
}
bool Preferences::isTorrentFileAssocSet()
{
bool isSet = false;
const CFStringRef torrentId = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, torrentExtension, NULL);
if (torrentId != NULL)
{
const CFStringRef defaultHandlerId = LSCopyDefaultRoleHandlerForContentType(torrentId, kLSRolesViewer);
if (defaultHandlerId != NULL)
{
const CFStringRef myBundleId = CFBundleGetIdentifier(CFBundleGetMainBundle());
if (myBundleId != NULL)
isSet = CFStringCompare(myBundleId, defaultHandlerId, 0) == kCFCompareEqualTo;
CFRelease(defaultHandlerId);
}
CFRelease(torrentId);
}
return isSet;
}
void Preferences::setTorrentFileAssoc()
{
if (isTorrentFileAssocSet())
return;
const CFStringRef torrentId = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, torrentExtension, NULL);
if (torrentId != NULL)
{
const CFStringRef myBundleId = CFBundleGetIdentifier(CFBundleGetMainBundle());
if (myBundleId != NULL)
LSSetDefaultRoleHandlerForContentType(torrentId, kLSRolesViewer, myBundleId);
CFRelease(torrentId);
}
}
bool Preferences::isMagnetLinkAssocSet()
{
bool isSet = false;
const CFStringRef defaultHandlerId = LSCopyDefaultHandlerForURLScheme(magnetUrlScheme);
if (defaultHandlerId != NULL)
{
const CFStringRef myBundleId = CFBundleGetIdentifier(CFBundleGetMainBundle());
if (myBundleId != NULL)
isSet = CFStringCompare(myBundleId, defaultHandlerId, 0) == kCFCompareEqualTo;
CFRelease(defaultHandlerId);
}
return isSet;
}
void Preferences::setMagnetLinkAssoc()
{
if (isMagnetLinkAssocSet())
return;
const CFStringRef myBundleId = CFBundleGetIdentifier(CFBundleGetMainBundle());
if (myBundleId != NULL)
LSSetDefaultHandlerForURLScheme(magnetUrlScheme, myBundleId);
}
#endif // Q_OS_MACOS
int Preferences::getTrackerPort() const
{
return value<int>(u"Preferences/Advanced/trackerPort"_s, 9000);