Browse Source

Allow to set qBittorrent as default program

Register qBittorrent as possible default program for .torrent files and
magnet links during install.

PR #19446.
adaptive-webui-19844
Vladimir Golovnev 1 year ago committed by GitHub
parent
commit
6860c0d60d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 94
      dist/windows/installer.nsh
  2. 40
      dist/windows/uninstaller.nsh
  3. 17
      src/app/application.cpp
  4. 15
      src/base/preferences.cpp
  5. 5
      src/base/preferences.h
  6. 88
      src/base/utils/os.cpp
  7. 7
      src/base/utils/os.h
  8. 20
      src/gui/optionsdialog.cpp
  9. 1
      src/gui/optionsdialog.h
  10. 43
      src/gui/optionsdialog.ui

94
dist/windows/installer.nsh vendored

@ -32,6 +32,27 @@ Section $(inst_qbt_req) ;"qBittorrent (required)" @@ -32,6 +32,27 @@ Section $(inst_qbt_req) ;"qBittorrent (required)"
; Write the installation path into the registry
WriteRegStr HKLM "Software\qBittorrent" "InstallLocation" "$INSTDIR"
; Register qBittorrent as possible default program for .torrent files and magnet links
WriteRegStr HKLM "Software\qBittorrent\Capabilities" "ApplicationDescription" "A BitTorrent client in Qt"
WriteRegStr HKLM "Software\qBittorrent\Capabilities" "ApplicationName" "qBittorrent"
WriteRegStr HKLM "Software\qBittorrent\Capabilities\FileAssociations" ".torrent" "qBittorrent.File.Torrent"
WriteRegStr HKLM "Software\qBittorrent\Capabilities\UrlAssociations" "magnet" "qBittorrent.Url.Magnet"
WriteRegStr HKLM "Software\RegisteredApplications" "qBittorrent" "Software\qBittorrent\Capabilities"
; Register qBittorrent ProgIDs
WriteRegStr HKLM "Software\Classes\qBittorrent.File.Torrent" "" "Torrent File"
WriteRegStr HKLM "Software\Classes\qBittorrent.File.Torrent\DefaultIcon" "" '"$INSTDIR\qbittorrent.exe",1'
WriteRegStr HKLM "Software\Classes\qBittorrent.File.Torrent\shell\open\command" "" '"$INSTDIR\qbittorrent.exe" "%1"'
WriteRegStr HKLM "Software\Classes\qBittorrent.Url.Magnet" "" "Magnet URI"
WriteRegStr HKLM "Software\Classes\qBittorrent.Url.Magnet\DefaultIcon" "" '"$INSTDIR\qbittorrent.exe",1'
WriteRegStr HKLM "Software\Classes\qBittorrent.Url.Magnet\shell\open\command" "" '"$INSTDIR\qbittorrent.exe" "%1"'
WriteRegStr HKLM "Software\Classes\.torrent" "Content Type" "application/x-bittorrent"
WriteRegStr HKLM "Software\Classes\magnet" "" "URL:Magnet URI"
WriteRegStr HKLM "Software\Classes\magnet" "Content Type" "application/x-magnet"
WriteRegStr HKLM "Software\Classes\magnet" "URL Protocol" ""
System::Call 'Shell32::SHChangeNotify(i ${SHCNE_ASSOCCHANGED}, i ${SHCNF_IDLIST}, p 0, p 0)'
; Write the uninstall keys for Windows
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\qBittorrent" "DisplayName" "qBittorrent"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\qBittorrent" "UninstallString" '"$INSTDIR\uninst.exe"'
@ -46,13 +67,6 @@ Section $(inst_qbt_req) ;"qBittorrent (required)" @@ -46,13 +67,6 @@ Section $(inst_qbt_req) ;"qBittorrent (required)"
IntFmt $0 "0x%08X" $0
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\qBittorrent" "EstimatedSize" "$0"
; qBittorrent ProgID
WriteRegStr HKLM "Software\Classes\qBittorrent" "" "qBittorrent Torrent File"
WriteRegStr HKLM "Software\Classes\qBittorrent" "FriendlyTypeName" "qBittorrent Torrent File"
WriteRegStr HKLM "Software\Classes\qBittorrent\shell" "" "open"
WriteRegStr HKLM "Software\Classes\qBittorrent\shell\open\command" "" '"$INSTDIR\qbittorrent.exe" "%1"'
WriteRegStr HKLM "Software\Classes\qBittorrent\DefaultIcon" "" '"$INSTDIR\qbittorrent.exe",1'
SectionEnd
; Optional section (can be disabled by the user)
@ -82,72 +96,6 @@ Function inst_startup_user @@ -82,72 +96,6 @@ Function inst_startup_user
FunctionEnd
Section $(inst_torrent) ;"Open .torrent files with qBittorrent"
ReadRegStr $0 HKLM "Software\Classes\.torrent" ""
StrCmp $0 "qBittorrent" clear_errors 0
;Check if empty string
StrCmp $0 "" clear_errors 0
;Write old value to OpenWithProgIds
WriteRegStr HKLM "Software\Classes\.torrent\OpenWithProgIds" $0 ""
clear_errors:
ClearErrors
WriteRegStr HKLM "Software\Classes\.torrent" "" "qBittorrent"
WriteRegStr HKLM "Software\Classes\.torrent" "Content Type" "application/x-bittorrent"
!insertmacro UAC_AsUser_Call Function inst_torrent_user ${UAC_SYNCREGISTERS}|${UAC_SYNCOUTDIR}|${UAC_SYNCINSTDIR}
System::Call 'Shell32::SHChangeNotify(i ${SHCNE_ASSOCCHANGED}, i ${SHCNF_IDLIST}, p 0, p 0)'
SectionEnd
Function inst_torrent_user
ReadRegStr $0 HKCU "Software\Classes\.torrent" ""
StrCmp $0 "qBittorrent" clear_errors 0
;Check if empty string
StrCmp $0 "" clear_errors 0
;Write old value to OpenWithProgIds
WriteRegStr HKCU "Software\Classes\.torrent\OpenWithProgIds" $0 ""
clear_errors:
ClearErrors
WriteRegStr HKCU "Software\Classes\.torrent" "" "qBittorrent"
WriteRegStr HKCU "Software\Classes\.torrent" "Content Type" "application/x-bittorrent"
FunctionEnd
Section $(inst_magnet) ;"Open magnet links with qBittorrent"
WriteRegStr HKLM "Software\Classes\magnet" "" "URL:Magnet link"
WriteRegStr HKLM "Software\Classes\magnet" "Content Type" "application/x-magnet"
WriteRegStr HKLM "Software\Classes\magnet" "URL Protocol" ""
WriteRegStr HKLM "Software\Classes\magnet\DefaultIcon" "" '"$INSTDIR\qbittorrent.exe",1'
WriteRegStr HKLM "Software\Classes\magnet\shell" "" "open"
WriteRegStr HKLM "Software\Classes\magnet\shell\open\command" "" '"$INSTDIR\qbittorrent.exe" "%1"'
!insertmacro UAC_AsUser_Call Function inst_magnet_user ${UAC_SYNCREGISTERS}|${UAC_SYNCOUTDIR}|${UAC_SYNCINSTDIR}
System::Call 'Shell32::SHChangeNotify(i ${SHCNE_ASSOCCHANGED}, i ${SHCNF_IDLIST}, p 0, p 0)'
SectionEnd
Function inst_magnet_user
WriteRegStr HKCU "Software\Classes\magnet" "" "URL:Magnet link"
WriteRegStr HKCU "Software\Classes\magnet" "Content Type" "application/x-magnet"
WriteRegStr HKCU "Software\Classes\magnet" "URL Protocol" ""
WriteRegStr HKCU "Software\Classes\magnet\DefaultIcon" "" '"$INSTDIR\qbittorrent.exe",1'
WriteRegStr HKCU "Software\Classes\magnet\shell" "" "open"
WriteRegStr HKCU "Software\Classes\magnet\shell\open\command" "" '"$INSTDIR\qbittorrent.exe" "%1"'
FunctionEnd
Section $(inst_firewall)
DetailPrint $(inst_firewallinfo)

40
dist/windows/uninstaller.nsh vendored

@ -19,48 +19,14 @@ Section "un.$(remove_shortcuts)" ;"un.Remove shortcuts" @@ -19,48 +19,14 @@ Section "un.$(remove_shortcuts)" ;"un.Remove shortcuts"
Delete "$DESKTOP\qBittorrent.lnk"
SectionEnd
Section "un.$(remove_associations)" ;"un.Remove file associations"
SectionIn RO
ReadRegStr $0 HKLM "Software\Classes\.torrent" ""
StrCmp $0 "qBittorrent" 0 torrent_end
DetailPrint "$(uninst_tor_warn) $0"
DeleteRegValue HKLM "Software\Classes\.torrent" ""
DeleteRegKey /ifempty HKLM "Software\Classes\.torrent"
torrent_end:
ReadRegStr $0 HKLM "Software\Classes\magnet\shell\open\command" ""
StrCmp $0 '"$INSTDIR\qbittorrent.exe" "%1"' 0 magnet_end
DetailPrint "$(uninst_mag_warn) $0"
DeleteRegKey HKLM "Software\Classes\magnet"
magnet_end:
!insertmacro UAC_AsUser_Call Function un.remove_associations_user ${UAC_SYNCREGISTERS}|${UAC_SYNCOUTDIR}|${UAC_SYNCINSTDIR}
System::Call 'Shell32::SHChangeNotify(i ${SHCNE_ASSOCCHANGED}, i ${SHCNF_IDLIST}, p 0, p 0)'
SectionEnd
Function un.remove_associations_user
ReadRegStr $0 HKCU "Software\Classes\.torrent" ""
StrCmp $0 "qBittorrent" 0 torrent_end
DetailPrint "$(uninst_tor_warn) $0"
DeleteRegValue HKCU "Software\Classes\.torrent" ""
DeleteRegKey /ifempty HKCU "Software\Classes\.torrent"
torrent_end:
ReadRegStr $0 HKCU "Software\Classes\magnet\shell\open\command" ""
StrCmp $0 '"$INSTDIR\qbittorrent.exe" "%1"' 0 magnet_end
DetailPrint "$(uninst_mag_warn) $0"
DeleteRegKey HKCU "Software\Classes\magnet"
magnet_end:
FunctionEnd
Section "un.$(remove_registry)" ;"un.Remove registry keys"
SectionIn RO
; Remove registry keys
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\qBittorrent"
DeleteRegKey HKLM "Software\qBittorrent"
DeleteRegKey HKLM "Software\Classes\qBittorrent"
; Remove ProgIDs
DeleteRegKey HKLM "Software\Classes\qBittorrent.File.Torrent"
DeleteRegKey HKLM "Software\Classes\qBittorrent.Url.Magnet"
System::Call 'Shell32::SHChangeNotify(i ${SHCNE_ASSOCCHANGED}, i ${SHCNF_IDLIST}, p 0, p 0)'
SectionEnd

17
src/app/application.cpp

@ -885,23 +885,6 @@ int Application::exec() @@ -885,23 +885,6 @@ int Application::exec()
#endif
m_window = new MainWindow(this, windowState);
delete m_startupProgressDialog;
#ifdef Q_OS_WIN
auto *pref = Preferences::instance();
if (!pref->neverCheckFileAssoc() && (!Utils::OS::isTorrentFileAssocSet() || !Utils::OS::isMagnetLinkAssocSet()))
{
if (QMessageBox::question(m_window, tr("Torrent file association")
, tr("qBittorrent is not the default application for opening torrent files or Magnet links.\nDo you want to make qBittorrent the default application for these?")
, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes)
{
Utils::OS::setTorrentFileAssoc(true);
Utils::OS::setMagnetLinkAssoc(true);
}
else
{
pref->setNeverCheckFileAssoc();
}
}
#endif // Q_OS_WIN
#endif // DISABLE_GUI
#ifndef DISABLE_WEBUI

15
src/base/preferences.cpp

@ -1293,21 +1293,6 @@ void Preferences::setRecursiveDownloadEnabled(const bool enable) @@ -1293,21 +1293,6 @@ void Preferences::setRecursiveDownloadEnabled(const bool enable)
setValue(u"Preferences/Advanced/DisableRecursiveDownload"_s, !enable);
}
#ifdef Q_OS_WIN
bool Preferences::neverCheckFileAssoc() const
{
return value(u"Preferences/Win32/NeverCheckFileAssocation"_s, false);
}
void Preferences::setNeverCheckFileAssoc(const bool check)
{
if (check == neverCheckFileAssoc())
return;
setValue(u"Preferences/Win32/NeverCheckFileAssocation"_s, check);
}
#endif // Q_OS_WIN
int Preferences::getTrackerPort() const
{
return value<int>(u"Preferences/Advanced/trackerPort"_s, 9000);

5
src/base/preferences.h

@ -287,11 +287,6 @@ public: @@ -287,11 +287,6 @@ public:
#endif
bool isRecursiveDownloadEnabled() const;
void setRecursiveDownloadEnabled(bool enable);
#ifdef Q_OS_WIN
bool neverCheckFileAssoc() const;
void setNeverCheckFileAssoc(bool check = true);
#endif
int getTrackerPort() const;
void setTrackerPort(int port);
bool isTrackerPortForwardingEnabled() const;

88
src/base/utils/os.cpp

@ -34,18 +34,8 @@ @@ -34,18 +34,8 @@
#include <CoreServices/CoreServices.h>
#endif // Q_OS_MACOS
#ifdef Q_OS_WIN
#include <shlobj.h>
#endif // Q_OS_WIN
#include <QString>
#ifdef Q_OS_WIN
#include <QCoreApplication>
#include <QRegularExpression>
#include <QSettings>
#endif // Q_OS_WIN
#include "base/global.h"
#include "base/path.h"
@ -114,81 +104,3 @@ void Utils::OS::setMagnetLinkAssoc() @@ -114,81 +104,3 @@ void Utils::OS::setMagnetLinkAssoc()
::LSSetDefaultHandlerForURLScheme(magnetUrlScheme, myBundleId);
}
#endif // Q_OS_MACOS
#ifdef Q_OS_WIN
bool Utils::OS::isTorrentFileAssocSet()
{
const QSettings settings(u"HKEY_CURRENT_USER\\Software\\Classes"_s, QSettings::NativeFormat);
return settings.value(u".torrent/Default"_s).toString() == u"qBittorrent";
}
void Utils::OS::setTorrentFileAssoc(const bool set)
{
if (set == isTorrentFileAssocSet())
return;
QSettings settings(u"HKEY_CURRENT_USER\\Software\\Classes"_s, QSettings::NativeFormat);
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);
settings.setValue(u".torrent/Content Type"_s, u"application/x-bittorrent"_s);
}
else
{
settings.setValue(u".torrent/Default"_s, QString());
}
::SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr);
}
bool Utils::OS::isMagnetLinkAssocSet()
{
const QSettings settings(u"HKEY_CURRENT_USER\\Software\\Classes"_s, QSettings::NativeFormat);
const QString shellCommand = settings.value(u"magnet/shell/open/command/Default"_s).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 Utils::OS::setMagnetLinkAssoc(const bool set)
{
if (set == isMagnetLinkAssocSet())
return;
QSettings settings(u"HKEY_CURRENT_USER\\Software\\Classes"_s, QSettings::NativeFormat);
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/DefaultIcon/Default"_s, iconStr);
settings.setValue(u"magnet/shell/Default"_s, u"open"_s);
settings.setValue(u"magnet/shell/open/command/Default"_s, commandStr);
settings.setValue(u"magnet/URL Protocol"_s, QString());
}
else
{
// only wipe values that are specific to qbt
settings.setValue(u"magnet/DefaultIcon/Default"_s, QString());
settings.setValue(u"magnet/shell/open/command/Default"_s, QString());
}
::SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr);
}
#endif // Q_OS_WIN

7
src/base/utils/os.h

@ -40,11 +40,4 @@ namespace Utils::OS @@ -40,11 +40,4 @@ namespace Utils::OS
bool isMagnetLinkAssocSet();
void setMagnetLinkAssoc();
#endif // Q_OS_MACOS
#ifdef Q_OS_WIN
bool isTorrentFileAssocSet();
void setTorrentFileAssoc(bool set);
bool isMagnetLinkAssocSet();
void setMagnetLinkAssoc(bool set);
#endif // Q_OS_WIN
}

20
src/gui/optionsdialog.cpp

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2023 Vladimir Golovnev <glassez@yandex.ru>
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
*
* This program is free software; you can redistribute it and/or
@ -55,6 +56,7 @@ @@ -55,6 +56,7 @@
#include "base/utils/io.h"
#include "base/utils/misc.h"
#include "base/utils/net.h"
#include "base/utils/os.h"
#include "base/utils/password.h"
#include "base/utils/random.h"
#include "addnewtorrentdialog.h"
@ -287,8 +289,6 @@ void OptionsDialog::loadBehaviorTabOptions() @@ -287,8 +289,6 @@ void OptionsDialog::loadBehaviorTabOptions()
#ifdef Q_OS_WIN
m_ui->checkStartup->setChecked(pref->WinStartup());
m_ui->checkAssociateTorrents->setChecked(Utils::OS::isTorrentFileAssocSet());
m_ui->checkAssociateMagnetLinks->setChecked(Utils::OS::isMagnetLinkAssocSet());
#endif
#ifdef Q_OS_MACOS
@ -369,12 +369,23 @@ void OptionsDialog::loadBehaviorTabOptions() @@ -369,12 +369,23 @@ void OptionsDialog::loadBehaviorTabOptions()
connect(m_ui->checkPreventFromSuspendWhenDownloading, &QAbstractButton::toggled, this, &ThisType::enableApplyButton);
connect(m_ui->checkPreventFromSuspendWhenSeeding, &QAbstractButton::toggled, this, &ThisType::enableApplyButton);
#if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
#if defined(Q_OS_MACOS)
connect(m_ui->checkAssociateTorrents, &QAbstractButton::toggled, this, &ThisType::enableApplyButton);
connect(m_ui->checkAssociateMagnetLinks, &QAbstractButton::toggled, this, &ThisType::enableApplyButton);
#endif
#if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
connect(m_ui->checkProgramUpdates, &QAbstractButton::toggled, this, &ThisType::enableApplyButton);
#endif
#ifdef Q_OS_WIN
m_ui->assocPanel->hide();
#endif
#ifdef Q_OS_MAC
m_ui->defaultProgramPanel->hide();
#endif
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)) && !defined(QBT_USES_DBUS)
m_ui->checkPreventFromSuspendWhenDownloading->setDisabled(true);
m_ui->checkPreventFromSuspendWhenSeeding->setDisabled(true);
@ -435,9 +446,6 @@ void OptionsDialog::saveBehaviorTabOptions() const @@ -435,9 +446,6 @@ void OptionsDialog::saveBehaviorTabOptions() const
#ifdef Q_OS_WIN
pref->setWinStartup(WinStartup());
Utils::OS::setTorrentFileAssoc(m_ui->checkAssociateTorrents->isChecked());
Utils::OS::setMagnetLinkAssoc(m_ui->checkAssociateMagnetLinks->isChecked());
#endif
#ifndef Q_OS_MACOS

1
src/gui/optionsdialog.h

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2023 Vladimir Golovnev <glassez@yandex.ru>
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
*
* This program is free software; you can redistribute it and/or

43
src/gui/optionsdialog.ui

@ -568,6 +568,21 @@ @@ -568,6 +568,21 @@
<string>File association</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_28">
<item>
<widget class="QWidget" name="assocPanel" native="true">
<layout class="QVBoxLayout" name="assocPanelLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QCheckBox" name="checkAssociateTorrents">
<property name="text">
@ -585,6 +600,34 @@ @@ -585,6 +600,34 @@
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="defaultProgramPanel" native="true">
<layout class="QVBoxLayout" name="defaultProgramPanelLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="labelSetAssoc">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;To set qBittorrent as default program for .torrent files and/or Magnet links&lt;br/&gt;you can use &lt;span style=&quot; font-weight:600;&quot;&gt;Default Programs&lt;/span&gt; dialog from &lt;span style=&quot; font-weight:600;&quot;&gt;Control Panel&lt;/span&gt;.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkProgramUpdates">
<property name="text">

Loading…
Cancel
Save