Browse Source

Extract desktop integration stuff into separate class

PR #17313.
adaptive-webui-19844
Vladimir Golovnev 2 years ago committed by GitHub
parent
commit
890630944d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 56
      src/app/application.cpp
  2. 8
      src/app/application.h
  3. 2
      src/gui/CMakeLists.txt
  4. 23
      src/gui/advancedsettings.cpp
  5. 273
      src/gui/desktopintegration.cpp
  6. 93
      src/gui/desktopintegration.h
  7. 2
      src/gui/gui.pri
  8. 5
      src/gui/interfaces/iguiapplication.h
  9. 361
      src/gui/mainwindow.cpp
  10. 43
      src/gui/mainwindow.h
  11. 16
      src/gui/search/searchwidget.cpp
  12. 6
      src/gui/search/searchwidget.h

56
src/app/application.cpp

@ -88,6 +88,7 @@ @@ -88,6 +88,7 @@
#ifndef DISABLE_GUI
#include "gui/addnewtorrentdialog.h"
#include "gui/desktopintegration.h"
#include "gui/mainwindow.h"
#include "gui/shutdownconfirmdialog.h"
#include "gui/uithememanager.h"
@ -102,6 +103,7 @@ namespace @@ -102,6 +103,7 @@ namespace
{
#define SETTINGS_KEY(name) u"Application/" name
#define FILELOGGER_SETTINGS_KEY(name) (SETTINGS_KEY(u"FileLogger/") name)
#define NOTIFICATIONS_SETTINGS_KEY(name) (SETTINGS_KEY(u"GUI/Notifications/"_qs) name)
const QString LOG_FOLDER = u"logs"_qs;
const QChar PARAMS_SEPARATOR = u'|';
@ -112,7 +114,7 @@ namespace @@ -112,7 +114,7 @@ namespace
const int MAX_FILELOG_SIZE = 1000 * 1024 * 1024; // 1000MiB
const int DEFAULT_FILELOG_SIZE = 65 * 1024; // 65KiB
#if !defined(DISABLE_GUI)
#ifndef DISABLE_GUI
const int PIXMAP_CACHE_SIZE = 64 * 1024 * 1024; // 64MiB
#endif
}
@ -132,6 +134,9 @@ Application::Application(int &argc, char **argv) @@ -132,6 +134,9 @@ Application::Application(int &argc, char **argv)
#ifdef Q_OS_WIN
, m_processMemoryPriority(SETTINGS_KEY(u"ProcessMemoryPriority"_qs))
#endif
#ifndef DISABLE_GUI
, m_storeNotificationTorrentAdded(NOTIFICATIONS_SETTINGS_KEY(u"TorrentAdded"_qs))
#endif
{
qRegisterMetaType<Log::Msg>("Log::Msg");
qRegisterMetaType<Log::Peer>("Log::Peer");
@ -198,10 +203,25 @@ Application::~Application() @@ -198,10 +203,25 @@ Application::~Application()
}
#ifndef DISABLE_GUI
DesktopIntegration *Application::desktopIntegration()
{
return m_desktopIntegration;
}
MainWindow *Application::mainWindow()
{
return m_window;
}
bool Application::isTorrentAddedNotificationsEnabled() const
{
return m_storeNotificationTorrentAdded;
}
void Application::setTorrentAddedNotificationsEnabled(const bool value)
{
m_storeNotificationTorrentAdded = value;
}
#endif
const QBtCommandLineParameters &Application::commandLineArgs() const
@ -683,6 +703,40 @@ int Application::exec(const QStringList &params) @@ -683,6 +703,40 @@ int Application::exec(const QStringList &params)
#endif // DISABLE_WEBUI
#else
UIThemeManager::initInstance();
const auto *btSession = BitTorrent::Session::instance();
m_desktopIntegration = new DesktopIntegration(this);
connect(btSession, &BitTorrent::Session::fullDiskError, this
, [this](const BitTorrent::Torrent *torrent, const QString &msg)
{
m_desktopIntegration->showNotification(tr("I/O Error", "i.e: Input/Output Error")
, tr("An I/O error occurred for torrent '%1'.\n Reason: %2"
, "e.g: An error occurred for torrent 'xxx.avi'.\n Reason: disk is full.").arg(torrent->name(), msg));
});
connect(btSession, &BitTorrent::Session::loadTorrentFailed, this
, [this](const QString &error)
{
m_desktopIntegration->showNotification(tr("Error"), tr("Failed to add torrent: %1").arg(error));
});
connect(btSession, &BitTorrent::Session::torrentAdded, this
, [this](const BitTorrent::Torrent *torrent)
{
if (isTorrentAddedNotificationsEnabled())
m_desktopIntegration->showNotification(tr("Torrent added"), tr("'%1' was added.", "e.g: xxx.avi was added.").arg(torrent->name()));
});
connect(btSession, &BitTorrent::Session::torrentFinished, this
, [this](const BitTorrent::Torrent *torrent)
{
m_desktopIntegration->showNotification(tr("Download completed"), tr("'%1' has finished downloading.", "e.g: xxx.avi has finished downloading.").arg(torrent->name()));
});
connect(btSession, &BitTorrent::Session::downloadFromUrlFailed, this
, [this](const QString &url, const QString &reason)
{
m_desktopIntegration->showNotification(tr("URL download error")
, tr("Couldn't download file at URL '%1', reason: %2.").arg(url, reason));
});
m_window = new MainWindow(this);
#endif // DISABLE_GUI

8
src/app/application.h

@ -67,6 +67,7 @@ namespace RSS @@ -67,6 +67,7 @@ namespace RSS
}
#ifndef DISABLE_GUI
class DesktopIntegration;
class MainWindow;
using BaseApplication = QApplication;
@ -124,7 +125,11 @@ public: @@ -124,7 +125,11 @@ public:
#endif
#ifndef DISABLE_GUI
DesktopIntegration *desktopIntegration() override;
MainWindow *mainWindow() override;
bool isTorrentAddedNotificationsEnabled() const override;
void setTorrentAddedNotificationsEnabled(bool value) override;
#endif
private slots:
@ -194,6 +199,9 @@ private: @@ -194,6 +199,9 @@ private:
#endif
#ifndef DISABLE_GUI
SettingValue<bool> m_storeNotificationTorrentAdded;
DesktopIntegration *m_desktopIntegration = nullptr;
MainWindow *m_window = nullptr;
#endif

2
src/gui/CMakeLists.txt

@ -45,6 +45,7 @@ add_library(qbt_gui STATIC @@ -45,6 +45,7 @@ add_library(qbt_gui STATIC
cookiesdialog.h
cookiesmodel.h
deletionconfirmationdialog.h
desktopintegration.h
downloadfromurldialog.h
executionlogwidget.h
fspathedit.h
@ -128,6 +129,7 @@ add_library(qbt_gui STATIC @@ -128,6 +129,7 @@ add_library(qbt_gui STATIC
cookiesdialog.cpp
cookiesmodel.cpp
deletionconfirmationdialog.cpp
desktopintegration.cpp
downloadfromurldialog.cpp
executionlogwidget.cpp
fspathedit.cpp

23
src/gui/advancedsettings.cpp

@ -40,6 +40,7 @@ @@ -40,6 +40,7 @@
#include "base/preferences.h"
#include "base/unicodestrings.h"
#include "gui/addnewtorrentdialog.h"
#include "gui/desktopintegration.h"
#include "gui/mainwindow.h"
#include "interfaces/iguiapplication.h"
@ -271,16 +272,15 @@ void AdvancedSettings::saveAdvancedSettings() const @@ -271,16 +272,15 @@ void AdvancedSettings::saveAdvancedSettings() const
// Stop tracker timeout
session->setStopTrackerTimeout(m_spinBoxStopTrackerTimeout.value());
// Program notification
MainWindow *mainWindow = app()->mainWindow();
mainWindow->setNotificationsEnabled(m_checkBoxProgramNotifications.isChecked());
mainWindow->setTorrentAddedNotificationsEnabled(m_checkBoxTorrentAddedNotifications.isChecked());
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)) && defined(QT_DBUS_LIB)
mainWindow->setNotificationTimeout(m_spinBoxNotificationTimeout.value());
app()->desktopIntegration()->setNotificationsEnabled(m_checkBoxProgramNotifications.isChecked());
#ifdef QBT_USES_CUSTOMDBUSNOTIFICATIONS
app()->desktopIntegration()->setNotificationTimeout(m_spinBoxNotificationTimeout.value());
#endif
app()->setTorrentAddedNotificationsEnabled(m_checkBoxTorrentAddedNotifications.isChecked());
// Reannounce to all trackers when ip/port changed
session->setReannounceWhenAddressChangedEnabled(m_checkBoxReannounceWhenAddressChanged.isChecked());
// Misc GUI properties
mainWindow->setDownloadTrackerFavicon(m_checkBoxTrackerFavicon.isChecked());
app()->mainWindow()->setDownloadTrackerFavicon(m_checkBoxTrackerFavicon.isChecked());
AddNewTorrentDialog::setSavePathHistoryLength(m_spinBoxSavePathHistoryLength.value());
pref->setSpeedWidgetEnabled(m_checkBoxSpeedWidgetEnabled.isChecked());
#ifndef Q_OS_MACOS
@ -677,17 +677,16 @@ void AdvancedSettings::loadAdvancedSettings() @@ -677,17 +677,16 @@ void AdvancedSettings::loadAdvancedSettings()
, &m_spinBoxStopTrackerTimeout);
// Program notifications
const MainWindow *mainWindow = app()->mainWindow();
m_checkBoxProgramNotifications.setChecked(mainWindow->isNotificationsEnabled());
m_checkBoxProgramNotifications.setChecked(app()->desktopIntegration()->isNotificationsEnabled());
addRow(PROGRAM_NOTIFICATIONS, tr("Display notifications"), &m_checkBoxProgramNotifications);
// Torrent added notifications
m_checkBoxTorrentAddedNotifications.setChecked(mainWindow->isTorrentAddedNotificationsEnabled());
m_checkBoxTorrentAddedNotifications.setChecked(app()->isTorrentAddedNotificationsEnabled());
addRow(TORRENT_ADDED_NOTIFICATIONS, tr("Display notifications for added torrents"), &m_checkBoxTorrentAddedNotifications);
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)) && defined(QT_DBUS_LIB)
#ifdef QBT_USES_CUSTOMDBUSNOTIFICATIONS
// Notification timeout
m_spinBoxNotificationTimeout.setMinimum(-1);
m_spinBoxNotificationTimeout.setMaximum(std::numeric_limits<int>::max());
m_spinBoxNotificationTimeout.setValue(mainWindow->getNotificationTimeout());
m_spinBoxNotificationTimeout.setValue(app()->desktopIntegration()->notificationTimeout());
m_spinBoxNotificationTimeout.setSpecialValueText(tr("System default"));
m_spinBoxNotificationTimeout.setSuffix(tr(" ms", " milliseconds"));
addRow(NOTIFICATION_TIMEOUT, tr("Notification timeout [0: infinite]"), &m_spinBoxNotificationTimeout);
@ -696,7 +695,7 @@ void AdvancedSettings::loadAdvancedSettings() @@ -696,7 +695,7 @@ void AdvancedSettings::loadAdvancedSettings()
m_checkBoxReannounceWhenAddressChanged.setChecked(session->isReannounceWhenAddressChangedEnabled());
addRow(REANNOUNCE_WHEN_ADDRESS_CHANGED, tr("Reannounce to all trackers when IP or port changed"), &m_checkBoxReannounceWhenAddressChanged);
// Download tracker's favicon
m_checkBoxTrackerFavicon.setChecked(mainWindow->isDownloadTrackerFavicon());
m_checkBoxTrackerFavicon.setChecked(app()->mainWindow()->isDownloadTrackerFavicon());
addRow(DOWNLOAD_TRACKER_FAVICON, tr("Download tracker's favicon"), &m_checkBoxTrackerFavicon);
// Save path history length
m_spinBoxSavePathHistoryLength.setRange(AddNewTorrentDialog::minPathHistoryLength, AddNewTorrentDialog::maxPathHistoryLength);

273
src/gui/desktopintegration.cpp

@ -0,0 +1,273 @@ @@ -0,0 +1,273 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2022 Vladimir Golovnev <glassez@yandex.ru>
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*/
#include "desktopintegration.h"
#include <chrono>
#include <QMenu>
#include <QTimer>
#ifndef Q_OS_MACOS
#include <QSystemTrayIcon>
#endif
#include "base/logger.h"
#include "base/preferences.h"
#include "uithememanager.h"
#ifdef Q_OS_MACOS
#include "macutilities.h"
#endif
#ifdef QBT_USES_CUSTOMDBUSNOTIFICATIONS
#include "notifications/dbusnotifier.h"
#endif
namespace
{
#ifdef Q_OS_MACOS
DesktopIntegration *desktopIntegrationInstance = nullptr;
bool handleDockClicked(id self, SEL cmd, ...)
{
Q_UNUSED(self);
Q_UNUSED(cmd);
Q_ASSERT(desktopIntegrationInstance);
emit desktopIntegrationInstance->activationRequested();
return true;
}
#endif
}
using namespace std::chrono_literals;
#define SETTINGS_KEY(name) u"GUI/" name
#define NOTIFICATIONS_SETTINGS_KEY(name) (SETTINGS_KEY(u"Notifications/"_qs) name)
DesktopIntegration::DesktopIntegration(QObject *parent)
: QObject(parent)
, m_storeNotificationEnabled {NOTIFICATIONS_SETTINGS_KEY(u"Enabled"_qs), true}
#ifdef QBT_USES_CUSTOMDBUSNOTIFICATIONS
, m_storeNotificationTimeOut {NOTIFICATIONS_SETTINGS_KEY(u"Timeout"_qs), -1}
#endif
{
#ifdef Q_OS_MACOS
desktopIntegrationInstance = this;
MacUtils::overrideDockClickHandler(handleDockClicked);
#else
if (Preferences::instance()->systemTrayEnabled())
createTrayIcon(20);
#ifdef QBT_USES_CUSTOMDBUSNOTIFICATIONS
if (isNotificationsEnabled())
{
m_notifier = new DBusNotifier(this);
connect(m_notifier, &DBusNotifier::messageClicked, this, &DesktopIntegration::notificationClicked);
}
#endif
#endif
connect(Preferences::instance(), &Preferences::changed, this, &DesktopIntegration::onPreferencesChanged);
}
bool DesktopIntegration::isActive() const
{
#ifdef Q_OS_MACOS
return true;
#else
return (m_systrayIcon != nullptr);
#endif
}
QString DesktopIntegration::toolTip() const
{
return m_toolTip;
}
void DesktopIntegration::setToolTip(const QString &toolTip)
{
if (m_toolTip == toolTip)
return;
#ifndef Q_OS_MACOS
if (m_systrayIcon)
m_systrayIcon->setToolTip(toolTip);
#endif
}
QMenu *DesktopIntegration::menu() const
{
return m_menu;
}
void DesktopIntegration::setMenu(QMenu *menu)
{
if (menu == m_menu)
return;
m_menu = menu;
#ifdef Q_OS_MACOS
if (m_menu)
m_menu->setAsDockMenu();
#else
if (m_systrayIcon)
m_systrayIcon->setContextMenu(m_menu);
#endif
}
bool DesktopIntegration::isNotificationsEnabled() const
{
return m_storeNotificationEnabled;
}
void DesktopIntegration::setNotificationsEnabled(const bool value)
{
if (m_storeNotificationEnabled == value)
return;
m_storeNotificationEnabled = value;
#ifdef QBT_USES_CUSTOMDBUSNOTIFICATIONS
if (value)
{
m_notifier = new DBusNotifier(this);
connect(m_notifier, &DBusNotifier::messageClicked, this, &DesktopIntegration::notificationClicked);
}
else
{
delete m_notifier;
m_notifier = nullptr;
}
#endif
}
int DesktopIntegration::notificationTimeout() const
{
#ifdef QBT_USES_CUSTOMDBUSNOTIFICATIONS
return m_storeNotificationTimeOut;
#else
return 5000;
#endif
}
#ifdef QBT_USES_CUSTOMDBUSNOTIFICATIONS
void DesktopIntegration::setNotificationTimeout(const int value)
{
m_storeNotificationTimeOut = value;
}
#endif
void DesktopIntegration::showNotification(const QString &title, const QString &msg) const
{
if (!isNotificationsEnabled())
return;
#ifdef Q_OS_MACOS
MacUtils::displayNotification(title, msg);
#else
#ifdef QBT_USES_CUSTOMDBUSNOTIFICATIONS
m_notifier->showMessage(title, msg, notificationTimeout());
#else
if (m_systrayIcon && QSystemTrayIcon::supportsMessages())
m_systrayIcon->showMessage(title, msg, QSystemTrayIcon::Information, notificationTimeout());
#endif
#endif
}
void DesktopIntegration::onPreferencesChanged()
{
#ifndef Q_OS_MACOS
if (Preferences::instance()->systemTrayEnabled())
{
if (m_systrayIcon)
{
// Reload systray icon
m_systrayIcon->setIcon(UIThemeManager::instance()->getSystrayIcon());
}
else
{
createTrayIcon(20);
}
}
else
{
delete m_systrayIcon;
m_systrayIcon = nullptr;
emit stateChanged();
}
#endif
}
#ifndef Q_OS_MACOS
void DesktopIntegration::createTrayIcon(const int retries)
{
Q_ASSERT(!m_systrayIcon);
if (QSystemTrayIcon::isSystemTrayAvailable())
{
m_systrayIcon = new QSystemTrayIcon(UIThemeManager::instance()->getSystrayIcon(), this);
m_systrayIcon->setToolTip(m_toolTip);
if (m_menu)
m_systrayIcon->setContextMenu(m_menu);
connect(m_systrayIcon, &QSystemTrayIcon::activated, this
, [this](const QSystemTrayIcon::ActivationReason reason)
{
if (reason == QSystemTrayIcon::Trigger)
emit activationRequested();
});
#ifndef QBT_USES_CUSTOMDBUSNOTIFICATIONS
connect(m_systrayIcon, &QSystemTrayIcon::messageClicked, this, &DesktopIntegration::notificationClicked);
#endif
m_systrayIcon->show();
emit stateChanged();
}
else if (retries > 0)
{
LogMsg(tr("System tray icon is not available, retrying..."), Log::WARNING);
QTimer::singleShot(2s, this, [this, retries]()
{
if (Preferences::instance()->systemTrayEnabled())
createTrayIcon(retries - 1);
});
}
else
{
LogMsg(tr("System tray icon is still not available after retries. Disabling it."), Log::WARNING);
Preferences::instance()->setSystemTrayEnabled(false);
}
}
#endif // Q_OS_MACOS

93
src/gui/desktopintegration.h

@ -0,0 +1,93 @@ @@ -0,0 +1,93 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2022 Vladimir Golovnev <glassez@yandex.ru>
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*/
#pragma once
#include <QObject>
#include "base/settingvalue.h"
class QMenu;
#ifndef Q_OS_MACOS
class QSystemTrayIcon;
#endif
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)) && defined(QT_DBUS_LIB)
#define QBT_USES_CUSTOMDBUSNOTIFICATIONS
class DBusNotifier;
#endif
class DesktopIntegration final : public QObject
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(DesktopIntegration)
public:
explicit DesktopIntegration(QObject *parent = nullptr);
bool isActive() const;
QString toolTip() const;
void setToolTip(const QString &toolTip);
QMenu *menu() const;
void setMenu(QMenu *menu);
bool isNotificationsEnabled() const;
void setNotificationsEnabled(bool value);
int notificationTimeout() const;
#ifdef QBT_USES_CUSTOMDBUSNOTIFICATIONS
void setNotificationTimeout(const int value);
#endif
void showNotification(const QString &title, const QString &msg) const;
signals:
void activationRequested();
void notificationClicked();
void stateChanged();
private:
void onPreferencesChanged();
#ifndef Q_OS_MACOS
void createTrayIcon(int retries);
#endif // Q_OS_MACOS
CachedSettingValue<bool> m_storeNotificationEnabled;
QMenu *m_menu = nullptr;
QString m_toolTip;
#ifndef Q_OS_MACOS
QSystemTrayIcon *m_systrayIcon = nullptr;
#endif
#ifdef QBT_USES_CUSTOMDBUSNOTIFICATIONS
CachedSettingValue<int> m_storeNotificationTimeOut;
DBusNotifier *m_notifier = nullptr;
#endif
};

2
src/gui/gui.pri

@ -12,6 +12,7 @@ HEADERS += \ @@ -12,6 +12,7 @@ HEADERS += \
$$PWD/cookiesdialog.h \
$$PWD/cookiesmodel.h \
$$PWD/deletionconfirmationdialog.h \
$$PWD/desktopintegration.h \
$$PWD/downloadfromurldialog.h \
$$PWD/executionlogwidget.h \
$$PWD/fspathedit.h \
@ -95,6 +96,7 @@ SOURCES += \ @@ -95,6 +96,7 @@ SOURCES += \
$$PWD/cookiesdialog.cpp \
$$PWD/cookiesmodel.cpp \
$$PWD/deletionconfirmationdialog.cpp \
$$PWD/desktopintegration.cpp \
$$PWD/downloadfromurldialog.cpp \
$$PWD/executionlogwidget.cpp \
$$PWD/fspathedit.cpp \

5
src/gui/interfaces/iguiapplication.h

@ -32,6 +32,7 @@ @@ -32,6 +32,7 @@
#include "base/interfaces/iapplication.h"
class DesktopIntegration;
class MainWindow;
class IGUIApplication : public IApplication
@ -39,5 +40,9 @@ class IGUIApplication : public IApplication @@ -39,5 +40,9 @@ class IGUIApplication : public IApplication
public:
virtual ~IGUIApplication() = default;
virtual DesktopIntegration *desktopIntegration() = 0;
virtual MainWindow *mainWindow() = 0;
virtual bool isTorrentAddedNotificationsEnabled() const = 0;
virtual void setTorrentAddedNotificationsEnabled(bool value) = 0;
};

361
src/gui/mainwindow.cpp

@ -71,6 +71,7 @@ @@ -71,6 +71,7 @@
#include "addnewtorrentdialog.h"
#include "autoexpandabledialog.h"
#include "cookiesdialog.h"
#include "desktopintegration.h"
#include "downloadfromurldialog.h"
#include "executionlogwidget.h"
#include "hidabletabwidget.h"
@ -106,12 +107,8 @@ namespace @@ -106,12 +107,8 @@ namespace
{
#define SETTINGS_KEY(name) u"GUI/" name
#define EXECUTIONLOG_SETTINGS_KEY(name) (SETTINGS_KEY(u"Log/"_qs) name)
#define NOTIFICATIONS_SETTINGS_KEY(name) (SETTINGS_KEY(u"Notifications/"_qs) name)
const std::chrono::seconds PREVENT_SUSPEND_INTERVAL {60};
#if !defined(Q_OS_MACOS)
const int TIME_TRAY_BALLOON = 5000;
#endif
bool isTorrentLink(const QString &str)
{
@ -120,21 +117,6 @@ namespace @@ -120,21 +117,6 @@ namespace
|| (!str.startsWith(u"file:", Qt::CaseInsensitive)
&& Net::DownloadManager::hasSupportedScheme(str));
}
#ifdef Q_OS_MACOS
MainWindow *dockMainWindowHandle = nullptr;
bool dockClickHandler(id self, SEL cmd, ...)
{
Q_UNUSED(self)
Q_UNUSED(cmd)
if (dockMainWindowHandle && !dockMainWindowHandle->isVisible())
dockMainWindowHandle->activate();
return true;
}
#endif
}
MainWindow::MainWindow(IGUIApplication *app, QWidget *parent)
@ -143,12 +125,7 @@ MainWindow::MainWindow(IGUIApplication *app, QWidget *parent) @@ -143,12 +125,7 @@ MainWindow::MainWindow(IGUIApplication *app, QWidget *parent)
, m_ui(new Ui::MainWindow)
, m_storeExecutionLogEnabled(EXECUTIONLOG_SETTINGS_KEY(u"Enabled"_qs))
, m_storeDownloadTrackerFavicon(SETTINGS_KEY(u"DownloadTrackerFavicon"_qs))
, m_storeNotificationEnabled(NOTIFICATIONS_SETTINGS_KEY(u"Enabled"_qs))
, m_storeNotificationTorrentAdded(NOTIFICATIONS_SETTINGS_KEY(u"TorrentAdded"_qs))
, m_storeExecutionLogTypes(EXECUTIONLOG_SETTINGS_KEY(u"Types"_qs), Log::MsgType::ALL)
#ifdef QBT_USES_CUSTOMDBUSNOTIFICATIONS
, m_storeNotificationTimeOut(NOTIFICATIONS_SETTINGS_KEY(u"Timeout"_qs))
#endif
{
m_ui->setupUi(this);
@ -197,27 +174,10 @@ MainWindow::MainWindow(IGUIApplication *app, QWidget *parent) @@ -197,27 +174,10 @@ MainWindow::MainWindow(IGUIApplication *app, QWidget *parent)
lockMenu->addAction(tr("&Set Password"), this, &MainWindow::defineUILockPassword);
lockMenu->addAction(tr("&Clear Password"), this, &MainWindow::clearUILockPassword);
m_ui->actionLock->setMenu(lockMenu);
connect(this, &MainWindow::systemTrayIconCreated, this, [this]()
{
m_ui->actionLock->setVisible(true);
});
#ifdef QBT_USES_CUSTOMDBUSNOTIFICATIONS
if (isNotificationsEnabled())
{
m_notifier = new DBusNotifier(this);
connect(m_notifier, &DBusNotifier::messageClicked, this, &MainWindow::balloonClicked);
}
#endif
// Creating Bittorrent session
updateAltSpeedsBtn(BitTorrent::Session::instance()->isAltGlobalSpeedLimitEnabled());
connect(BitTorrent::Session::instance(), &BitTorrent::Session::fullDiskError, this, &MainWindow::fullDiskError);
connect(BitTorrent::Session::instance(), &BitTorrent::Session::loadTorrentFailed, this, &MainWindow::addTorrentFailed);
connect(BitTorrent::Session::instance(), &BitTorrent::Session::torrentAdded,this, &MainWindow::torrentNew);
connect(BitTorrent::Session::instance(), &BitTorrent::Session::torrentFinished, this, &MainWindow::finishedTorrent);
connect(BitTorrent::Session::instance(), &BitTorrent::Session::downloadFromUrlFailed, this, &MainWindow::handleDownloadFromUrlFailure);
connect(BitTorrent::Session::instance(), &BitTorrent::Session::speedLimitModeChanged, this, &MainWindow::updateAltSpeedsBtn);
connect(BitTorrent::Session::instance(), &BitTorrent::Session::recursiveTorrentDownloadPossible, this, &MainWindow::askRecursiveTorrentDownloadConfirmation);
@ -311,7 +271,7 @@ MainWindow::MainWindow(IGUIApplication *app, QWidget *parent) @@ -311,7 +271,7 @@ MainWindow::MainWindow(IGUIApplication *app, QWidget *parent)
connect(m_ui->actionDecreaseQueuePos, &QAction::triggered, m_transferListWidget, &TransferListWidget::decreaseQueuePosSelectedTorrents);
connect(m_ui->actionBottomQueuePos, &QAction::triggered, m_transferListWidget, &TransferListWidget::bottomQueuePosSelectedTorrents);
#ifndef Q_OS_MACOS
connect(m_ui->actionToggleVisibility, &QAction::triggered, this, [this]() { toggleVisibility(); });
connect(m_ui->actionToggleVisibility, &QAction::triggered, this, &MainWindow::toggleVisibility);
#endif
connect(m_ui->actionMinimize, &QAction::triggered, this, &MainWindow::minimizeWindow);
connect(m_ui->actionUseAlternativeSpeedLimits, &QAction::triggered, this, &MainWindow::toggleAlternativeSpeeds);
@ -400,6 +360,25 @@ MainWindow::MainWindow(IGUIApplication *app, QWidget *parent) @@ -400,6 +360,25 @@ MainWindow::MainWindow(IGUIApplication *app, QWidget *parent)
// Load Window state and sizes
readSettings();
app->desktopIntegration()->setMenu(createDesktopIntegrationMenu());
#ifndef Q_OS_MACOS
m_ui->actionLock->setVisible(app->desktopIntegration()->isActive());
connect(app->desktopIntegration(), &DesktopIntegration::stateChanged, this, [this, app]()
{
m_ui->actionLock->setVisible(app->desktopIntegration()->isActive());
});
#endif
connect(app->desktopIntegration(), &DesktopIntegration::notificationClicked, this, &MainWindow::desktopNotificationClicked);
connect(app->desktopIntegration(), &DesktopIntegration::activationRequested, this, [this]()
{
#ifdef Q_OS_MACOS
if (!isVisible())
activate();
#else
toggleVisibility();
#endif
});
#ifdef Q_OS_MACOS
// Make sure the Window is visible if we don't have a tray icon
if (pref->startMinimized())
@ -413,7 +392,7 @@ MainWindow::MainWindow(IGUIApplication *app, QWidget *parent) @@ -413,7 +392,7 @@ MainWindow::MainWindow(IGUIApplication *app, QWidget *parent)
raise();
}
#else
if (m_systrayIcon)
if (app->desktopIntegration()->isActive())
{
if (!(pref->startMinimized() || m_uiLocked))
{
@ -429,7 +408,7 @@ MainWindow::MainWindow(IGUIApplication *app, QWidget *parent) @@ -429,7 +408,7 @@ MainWindow::MainWindow(IGUIApplication *app, QWidget *parent)
hide();
if (!pref->minimizeToTrayNotified())
{
showNotificationBalloon(tr("qBittorrent is minimized to tray"), tr("This behavior can be changed in the settings. You won't be reminded again."));
app->desktopIntegration()->showNotification(tr("qBittorrent is minimized to tray"), tr("This behavior can be changed in the settings. You won't be reminded again."));
pref->setMinimizeToTrayNotified(true);
}
}
@ -498,11 +477,6 @@ MainWindow::MainWindow(IGUIApplication *app, QWidget *parent) @@ -498,11 +477,6 @@ MainWindow::MainWindow(IGUIApplication *app, QWidget *parent)
}
}
#endif
#ifdef Q_OS_MACOS
setupDockClickHandler();
createTrayIconMenu();
m_trayIconMenu->setAsDockMenu();
#endif
}
MainWindow::~MainWindow()
@ -531,54 +505,6 @@ void MainWindow::setExecutionLogMsgTypes(const Log::MsgTypes value) @@ -531,54 +505,6 @@ void MainWindow::setExecutionLogMsgTypes(const Log::MsgTypes value)
m_storeExecutionLogTypes = value;
}
bool MainWindow::isNotificationsEnabled() const
{
return m_storeNotificationEnabled.get(true);
}
void MainWindow::setNotificationsEnabled(const bool value)
{
if (m_storeNotificationEnabled == value)
return;
m_storeNotificationEnabled = value;
#ifdef QBT_USES_CUSTOMDBUSNOTIFICATIONS
if (value)
{
m_notifier = new DBusNotifier(this);
connect(m_notifier, &DBusNotifier::messageClicked, this, &MainWindow::balloonClicked);
}
else
{
delete m_notifier;
m_notifier = nullptr;
}
#endif
}
bool MainWindow::isTorrentAddedNotificationsEnabled() const
{
return m_storeNotificationTorrentAdded;
}
void MainWindow::setTorrentAddedNotificationsEnabled(const bool value)
{
m_storeNotificationTorrentAdded = value;
}
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)) && defined(QT_DBUS_LIB)
int MainWindow::getNotificationTimeout() const
{
return m_storeNotificationTimeOut.get(-1);
}
void MainWindow::setNotificationTimeout(const int value)
{
m_storeNotificationTimeOut = value;
}
#endif
bool MainWindow::isDownloadTrackerFavicon() const
{
return m_storeDownloadTrackerFavicon;
@ -721,7 +647,7 @@ void MainWindow::on_actionLock_triggered() @@ -721,7 +647,7 @@ void MainWindow::on_actionLock_triggered()
// Lock the interface
m_uiLocked = true;
pref->setUILocked(true);
m_trayIconMenu->setEnabled(false);
app()->desktopIntegration()->menu()->setEnabled(false);
hide();
}
@ -778,7 +704,7 @@ void MainWindow::displaySearchTab(bool enable) @@ -778,7 +704,7 @@ void MainWindow::displaySearchTab(bool enable)
// RSS tab
if (!m_searchWidget)
{
m_searchWidget = new SearchWidget(this);
m_searchWidget = new SearchWidget(app(), this);
m_tabs->insertTab(1, m_searchWidget,
#ifndef Q_OS_MACOS
UIThemeManager::instance()->getIcon(u"edit-find"_qs),
@ -873,7 +799,7 @@ void MainWindow::readSettings() @@ -873,7 +799,7 @@ void MainWindow::readSettings()
m_posInitialized = true;
}
void MainWindow::balloonClicked()
void MainWindow::desktopNotificationClicked()
{
if (isHidden())
{
@ -892,32 +818,6 @@ void MainWindow::balloonClicked() @@ -892,32 +818,6 @@ void MainWindow::balloonClicked()
activateWindow();
}
void MainWindow::addTorrentFailed(const QString &error) const
{
showNotificationBalloon(tr("Error"), tr("Failed to add torrent: %1").arg(error));
}
// called when a torrent was added
void MainWindow::torrentNew(BitTorrent::Torrent *const torrent) const
{
if (isTorrentAddedNotificationsEnabled())
showNotificationBalloon(tr("Torrent added"), tr("'%1' was added.", "e.g: xxx.avi was added.").arg(torrent->name()));
}
// called when a torrent has finished
void MainWindow::finishedTorrent(BitTorrent::Torrent *const torrent) const
{
showNotificationBalloon(tr("Download completed"), tr("'%1' has finished downloading.", "e.g: xxx.avi has finished downloading.").arg(torrent->name()));
}
// Notification when disk is full
void MainWindow::fullDiskError(BitTorrent::Torrent *const torrent, const QString &msg) const
{
showNotificationBalloon(tr("I/O Error", "i.e: Input/Output Error")
, tr("An I/O error occurred for torrent '%1'.\n Reason: %2"
, "e.g: An error occurred for torrent 'xxx.avi'.\n Reason: disk is full.").arg(torrent->name(), msg));
}
void MainWindow::createKeyboardShortcuts()
{
m_ui->actionCreateTorrent->setShortcut(QKeySequence::New);
@ -1026,13 +926,6 @@ void MainWindow::askRecursiveTorrentDownloadConfirmation(BitTorrent::Torrent *co @@ -1026,13 +926,6 @@ void MainWindow::askRecursiveTorrentDownloadConfirmation(BitTorrent::Torrent *co
confirmBox->open();
}
void MainWindow::handleDownloadFromUrlFailure(const QString &url, const QString &reason) const
{
// Display a message box
showNotificationBalloon(tr("URL download error")
, tr("Couldn't download file at URL '%1', reason: %2.").arg(url, reason));
}
void MainWindow::on_actionSetGlobalSpeedLimits_triggered()
{
auto dialog = new SpeedLimitDialog {this};
@ -1098,7 +991,7 @@ bool MainWindow::unlockUI() @@ -1098,7 +991,7 @@ bool MainWindow::unlockUI()
m_uiLocked = false;
pref->setUILocked(false);
m_trayIconMenu->setEnabled(true);
app()->desktopIntegration()->menu()->setEnabled(true);
return true;
}
@ -1115,32 +1008,24 @@ void MainWindow::notifyOfUpdate(const QString &) @@ -1115,32 +1008,24 @@ void MainWindow::notifyOfUpdate(const QString &)
#ifndef Q_OS_MACOS
// Toggle Main window visibility
void MainWindow::toggleVisibility(const QSystemTrayIcon::ActivationReason reason)
void MainWindow::toggleVisibility()
{
switch (reason)
if (isHidden())
{
case QSystemTrayIcon::Trigger:
if (isHidden())
{
if (m_uiLocked && !unlockUI()) // Ask for UI lock password
return;
if (m_uiLocked && !unlockUI()) // Ask for UI lock password
return;
// Make sure the window is not minimized
setWindowState((windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
// Make sure the window is not minimized
setWindowState((windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
// Then show it
show();
raise();
activateWindow();
}
else
{
hide();
}
break;
default:
break;
// Then show it
show();
raise();
activateWindow();
}
else
{
hide();
}
}
#endif // Q_OS_MACOS
@ -1245,13 +1130,13 @@ void MainWindow::closeEvent(QCloseEvent *e) @@ -1245,13 +1130,13 @@ void MainWindow::closeEvent(QCloseEvent *e)
}
#else
const bool goToSystrayOnExit = pref->closeToTray();
if (!m_forceExit && m_systrayIcon && goToSystrayOnExit && !this->isHidden())
if (!m_forceExit && app()->desktopIntegration()->isActive() && goToSystrayOnExit && !this->isHidden())
{
e->ignore();
QMetaObject::invokeMethod(this, &QWidget::hide, Qt::QueuedConnection);
if (!pref->closeToTrayNotified())
{
showNotificationBalloon(tr("qBittorrent is closed to tray"), tr("This behavior can be changed in the settings. You won't be reminded again."));
app()->desktopIntegration()->showNotification(tr("qBittorrent is closed to tray"), tr("This behavior can be changed in the settings. You won't be reminded again."));
pref->setCloseToTrayNotified(true);
}
return;
@ -1287,14 +1172,9 @@ void MainWindow::closeEvent(QCloseEvent *e) @@ -1287,14 +1172,9 @@ void MainWindow::closeEvent(QCloseEvent *e)
}
// Disable some UI to prevent user interactions
#ifndef Q_OS_MACOS
if (m_systrayIcon)
{
m_systrayIcon->disconnect();
m_systrayIcon->setToolTip(tr("qBittorrent is shutting down..."));
m_trayIconMenu->setEnabled(false);
}
#endif
app()->desktopIntegration()->disconnect();
app()->desktopIntegration()->setToolTip(tr("qBittorrent is shutting down..."));
app()->desktopIntegration()->menu()->setEnabled(false);
// Accept exit
e->accept();
@ -1328,14 +1208,13 @@ bool MainWindow::event(QEvent *e) @@ -1328,14 +1208,13 @@ bool MainWindow::event(QEvent *e)
switch (e->type())
{
case QEvent::WindowStateChange:
{
qDebug("Window change event");
// Now check to see if the window is minimised
if (isMinimized())
{
qDebug("minimisation");
Preferences *const pref = Preferences::instance();
if (m_systrayIcon && pref->minimizeToTray())
if (app()->desktopIntegration()->isActive() && pref->minimizeToTray())
{
qDebug() << "Has active window:" << (qApp->activeWindow() != nullptr);
// Check if there is a modal window
@ -1350,7 +1229,7 @@ bool MainWindow::event(QEvent *e) @@ -1350,7 +1229,7 @@ bool MainWindow::event(QEvent *e)
QMetaObject::invokeMethod(this, &QWidget::hide, Qt::QueuedConnection);
if (!pref->minimizeToTrayNotified())
{
showNotificationBalloon(tr("qBittorrent is minimized to tray"), tr("This behavior can be changed in the settings. You won't be reminded again."));
app()->desktopIntegration()->showNotification(tr("qBittorrent is minimized to tray"), tr("This behavior can be changed in the settings. You won't be reminded again."));
pref->setMinimizeToTrayNotified(true);
}
return true;
@ -1358,17 +1237,16 @@ bool MainWindow::event(QEvent *e) @@ -1358,17 +1237,16 @@ bool MainWindow::event(QEvent *e)
}
}
break;
}
case QEvent::ToolBarChange:
{
qDebug("MAC: Received a toolbar change event!");
bool ret = QMainWindow::event(e);
{
qDebug("MAC: Received a toolbar change event!");
const bool ret = QMainWindow::event(e);
qDebug("MAC: new toolbar visibility is %d", !m_ui->actionTopToolBar->isChecked());
m_ui->actionTopToolBar->toggle();
Preferences::instance()->setToolbarDisplayed(m_ui->actionTopToolBar->isChecked());
return ret;
}
qDebug("MAC: new toolbar visibility is %d", !m_ui->actionTopToolBar->isChecked());
m_ui->actionTopToolBar->toggle();
Preferences::instance()->setToolbarDisplayed(m_ui->actionTopToolBar->isChecked());
return ret;
}
default:
break;
}
@ -1443,14 +1321,6 @@ void MainWindow::dragEnterEvent(QDragEnterEvent *event) @@ -1443,14 +1321,6 @@ void MainWindow::dragEnterEvent(QDragEnterEvent *event)
event->acceptProposedAction();
}
#ifdef Q_OS_MACOS
void MainWindow::setupDockClickHandler()
{
dockMainWindowHandle = this;
MacUtils::overrideDockClickHandler(dockClickHandler);
}
#endif // Q_OS_MACOS
/*****************************************************
* *
* Torrent *
@ -1552,28 +1422,6 @@ void MainWindow::loadPreferences() @@ -1552,28 +1422,6 @@ void MainWindow::loadPreferences()
{
const Preferences *pref = Preferences::instance();
#ifndef Q_OS_MACOS
// system tray icon
if (pref->systemTrayEnabled())
{
if (m_systrayIcon)
{
// Reload systray icon
m_systrayIcon->setIcon(UIThemeManager::instance()->getSystrayIcon());
}
else
{
createTrayIcon(20);
}
}
else
{
delete m_systrayIcon;
delete m_trayIconMenu;
m_ui->actionLock->setVisible(false);
}
#endif
// General
if (pref->isToolbarDisplayed())
{
@ -1680,12 +1528,12 @@ void MainWindow::reloadSessionStats() @@ -1680,12 +1528,12 @@ void MainWindow::reloadSessionStats()
MacUtils::setBadgeLabelText({});
}
#else
if (m_systrayIcon)
if (app()->desktopIntegration()->isActive())
{
const auto toolTip = u"%1\n%2"_qs.arg(
tr("DL speed: %1", "e.g: Download speed: 10 KiB/s").arg(Utils::Misc::friendlyUnit(status.payloadDownloadRate, true))
, tr("UP speed: %1", "e.g: Upload speed: 10 KiB/s").arg(Utils::Misc::friendlyUnit(status.payloadUploadRate, true)));
m_systrayIcon->setToolTip(toolTip); // tray icon
app()->desktopIntegration()->setToolTip(toolTip); // tray icon
}
#endif // Q_OS_MACOS
@ -1707,21 +1555,6 @@ void MainWindow::reloadTorrentStats(const QVector<BitTorrent::Torrent *> &torren @@ -1707,21 +1555,6 @@ void MainWindow::reloadTorrentStats(const QVector<BitTorrent::Torrent *> &torren
}
}
void MainWindow::showNotificationBalloon(const QString &title, const QString &msg) const
{
if (!isNotificationsEnabled())
return;
#ifdef QBT_USES_CUSTOMDBUSNOTIFICATIONS
m_notifier->showMessage(title, msg, getNotificationTimeout());
#elif defined(Q_OS_MACOS)
MacUtils::displayNotification(title, msg);
#else
if (m_systrayIcon && QSystemTrayIcon::supportsMessages())
m_systrayIcon->showMessage(title, msg, QSystemTrayIcon::Information, TIME_TRAY_BALLOON);
#endif
}
/*****************************************************
* *
* Utils *
@ -1746,82 +1579,40 @@ void MainWindow::downloadFromURLList(const QStringList &urlList) @@ -1746,82 +1579,40 @@ void MainWindow::downloadFromURLList(const QStringList &urlList)
* *
*****************************************************/
#ifndef Q_OS_MACOS
void MainWindow::createTrayIcon(const int retries)
{
if (m_systrayIcon)
return;
if (QSystemTrayIcon::isSystemTrayAvailable())
{
m_systrayIcon = new QSystemTrayIcon(UIThemeManager::instance()->getSystrayIcon(), this);
createTrayIconMenu();
m_systrayIcon->setContextMenu(m_trayIconMenu);
connect(m_systrayIcon, &QSystemTrayIcon::activated, this, &MainWindow::toggleVisibility);
#ifndef QBT_USES_CUSTOMDBUSNOTIFICATIONS
connect(m_systrayIcon, &QSystemTrayIcon::messageClicked, this, &MainWindow::balloonClicked);
#endif
m_systrayIcon->show();
emit systemTrayIconCreated();
}
else
{
if (retries > 0)
{
LogMsg(tr("System tray icon is not available, retrying..."), Log::WARNING);
QTimer::singleShot(2s, this, [this, retries]()
{
if (Preferences::instance()->systemTrayEnabled())
createTrayIcon(retries - 1);
});
}
else
{
LogMsg(tr("System tray icon is still not available after retries. Disabling it."), Log::WARNING);
Preferences::instance()->setSystemTrayEnabled(false);
}
}
}
#endif // Q_OS_MACOS
void MainWindow::createTrayIconMenu()
QMenu *MainWindow::createDesktopIntegrationMenu()
{
if (m_trayIconMenu)
return;
m_trayIconMenu = new QMenu(this);
auto *menu = new QMenu(this);
#ifndef Q_OS_MACOS
connect(m_trayIconMenu, &QMenu::aboutToShow, this, [this]()
connect(menu, &QMenu::aboutToShow, this, [this]()
{
m_ui->actionToggleVisibility->setText(isVisible() ? tr("Hide") : tr("Show"));
});
m_trayIconMenu->addAction(m_ui->actionToggleVisibility);
m_trayIconMenu->addSeparator();
menu->addAction(m_ui->actionToggleVisibility);
menu->addSeparator();
#endif
m_trayIconMenu->addAction(m_ui->actionOpen);
m_trayIconMenu->addAction(m_ui->actionDownloadFromURL);
m_trayIconMenu->addSeparator();
menu->addAction(m_ui->actionOpen);
menu->addAction(m_ui->actionDownloadFromURL);
menu->addSeparator();
m_trayIconMenu->addAction(m_ui->actionUseAlternativeSpeedLimits);
m_trayIconMenu->addAction(m_ui->actionSetGlobalSpeedLimits);
m_trayIconMenu->addSeparator();
menu->addAction(m_ui->actionUseAlternativeSpeedLimits);
menu->addAction(m_ui->actionSetGlobalSpeedLimits);
menu->addSeparator();
m_trayIconMenu->addAction(m_ui->actionStartAll);
m_trayIconMenu->addAction(m_ui->actionPauseAll);
menu->addAction(m_ui->actionStartAll);
menu->addAction(m_ui->actionPauseAll);
#ifndef Q_OS_MACOS
m_trayIconMenu->addSeparator();
m_trayIconMenu->addAction(m_ui->actionExit);
menu->addSeparator();
menu->addAction(m_ui->actionExit);
#endif
if (m_uiLocked)
m_trayIconMenu->setEnabled(false);
menu->setEnabled(false);
return menu;
}
void MainWindow::updateAltSpeedsBtn(const bool alternative)

43
src/gui/mainwindow.h

@ -31,10 +31,6 @@ @@ -31,10 +31,6 @@
#include <QMainWindow>
#include <QPointer>
#ifndef Q_OS_MACOS
#include <QSystemTrayIcon>
#endif
#include "base/bittorrent/torrent.h"
#include "base/logger.h"
#include "base/settingvalue.h"
@ -97,14 +93,6 @@ public: @@ -97,14 +93,6 @@ public:
void setExecutionLogMsgTypes(Log::MsgTypes value);
// Notifications properties
bool isNotificationsEnabled() const;
void setNotificationsEnabled(bool value);
bool isTorrentAddedNotificationsEnabled() const;
void setTorrentAddedNotificationsEnabled(bool value);
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)) && defined(QT_DBUS_LIB)
int getNotificationTimeout() const;
void setNotificationTimeout(int value);
#endif
// Misc properties
bool isDownloadTrackerFavicon() const;
@ -113,19 +101,12 @@ public: @@ -113,19 +101,12 @@ public:
void activate();
void cleanup();
void showNotificationBalloon(const QString &title, const QString &msg) const;
signals:
void systemTrayIconCreated();
private slots:
void showFilterContextMenu();
void balloonClicked();
void desktopNotificationClicked();
void writeSettings();
void writeSplitterSettings();
void readSettings();
void fullDiskError(BitTorrent::Torrent *const torrent, const QString &msg) const;
void handleDownloadFromUrlFailure(const QString &, const QString &) const;
void tabChanged(int newTab);
bool defineUILockPassword();
void clearUILockPassword();
@ -143,9 +124,6 @@ private slots: @@ -143,9 +124,6 @@ private slots:
void reloadSessionStats();
void reloadTorrentStats(const QVector<BitTorrent::Torrent *> &torrents);
void loadPreferences();
void addTorrentFailed(const QString &error) const;
void torrentNew(BitTorrent::Torrent *const torrent) const;
void finishedTorrent(BitTorrent::Torrent *const torrent) const;
void askRecursiveTorrentDownloadConfirmation(BitTorrent::Torrent *const torrent);
void optionsSaved();
void toggleAlternativeSpeeds();
@ -199,16 +177,11 @@ private slots: @@ -199,16 +177,11 @@ private slots:
#ifdef Q_OS_MACOS
void on_actionCloseWindow_triggered();
#else
void toggleVisibility(const QSystemTrayIcon::ActivationReason reason = QSystemTrayIcon::Trigger);
void toggleVisibility();
#endif
private:
void createTrayIconMenu();
#ifdef Q_OS_MACOS
void setupDockClickHandler();
#else
void createTrayIcon(int retries);
#endif
QMenu *createDesktopIntegrationMenu();
#ifdef Q_OS_WIN
void installPython();
#endif
@ -238,9 +211,6 @@ private: @@ -238,9 +211,6 @@ private:
QPointer<TorrentCreatorDialog> m_createTorrentDlg;
QPointer<DownloadFromURLDialog> m_downloadFromURLDialog;
#ifndef Q_OS_MACOS
QPointer<QSystemTrayIcon> m_systrayIcon;
#endif
QPointer<QMenu> m_trayIconMenu;
TransferListWidget *m_transferListWidget = nullptr;
@ -267,15 +237,8 @@ private: @@ -267,15 +237,8 @@ private:
SettingValue<bool> m_storeExecutionLogEnabled;
SettingValue<bool> m_storeDownloadTrackerFavicon;
SettingValue<bool> m_storeNotificationEnabled;
SettingValue<bool> m_storeNotificationTorrentAdded;
CachedSettingValue<Log::MsgTypes> m_storeExecutionLogTypes;
#ifdef QBT_USES_CUSTOMDBUSNOTIFICATIONS
SettingValue<int> m_storeNotificationTimeOut;
DBusNotifier *m_notifier = nullptr;
#endif
#if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
void checkProgramUpdate(bool invokedByUser);
void handleUpdateCheckFinished(ProgramUpdater *updater, bool invokedByUser);

16
src/gui/search/searchwidget.cpp

@ -52,6 +52,7 @@ @@ -52,6 +52,7 @@
#include "base/search/searchhandler.h"
#include "base/search/searchpluginmanager.h"
#include "base/utils/foreignapps.h"
#include "gui/desktopintegration.h"
#include "gui/mainwindow.h"
#include "gui/uithememanager.h"
#include "pluginselectdialog.h"
@ -83,10 +84,11 @@ namespace @@ -83,10 +84,11 @@ namespace
}
}
SearchWidget::SearchWidget(MainWindow *mainWindow)
SearchWidget::SearchWidget(IGUIApplication *app, MainWindow *mainWindow)
: QWidget(mainWindow)
, m_ui(new Ui::SearchWidget())
, m_mainWindow(mainWindow)
, GUIApplicationComponent(app)
, m_ui {new Ui::SearchWidget()}
, m_mainWindow {mainWindow}
{
m_ui->setupUi(this);
m_ui->tabWidget->tabBar()->installEventFilter(this);
@ -304,7 +306,7 @@ void SearchWidget::on_searchButton_clicked() @@ -304,7 +306,7 @@ void SearchWidget::on_searchButton_clicked()
{
if (!Utils::ForeignApps::pythonInfo().isValid())
{
m_mainWindow->showNotificationBalloon(tr("Search Engine"), tr("Please install Python to use the Search Engine."));
app()->desktopIntegration()->showNotification(tr("Search Engine"), tr("Please install Python to use the Search Engine."));
return;
}
@ -370,12 +372,12 @@ void SearchWidget::tabStatusChanged(QWidget *tab) @@ -370,12 +372,12 @@ void SearchWidget::tabStatusChanged(QWidget *tab)
{
Q_ASSERT(m_activeSearchTab->status() != SearchJobWidget::Status::Ongoing);
if (m_mainWindow->isNotificationsEnabled() && (m_mainWindow->currentTabWidget() != this))
if (app()->desktopIntegration()->isNotificationsEnabled() && (m_mainWindow->currentTabWidget() != this))
{
if (m_activeSearchTab->status() == SearchJobWidget::Status::Error)
m_mainWindow->showNotificationBalloon(tr("Search Engine"), tr("Search has failed"));
app()->desktopIntegration()->showNotification(tr("Search Engine"), tr("Search has failed"));
else
m_mainWindow->showNotificationBalloon(tr("Search Engine"), tr("Search has finished"));
app()->desktopIntegration()->showNotification(tr("Search Engine"), tr("Search has finished"));
}
m_activeSearchTab = nullptr;

6
src/gui/search/searchwidget.h

@ -34,6 +34,8 @@ @@ -34,6 +34,8 @@
#include <QPointer>
#include <QWidget>
#include "gui/guiapplicationcomponent.h"
class QEvent;
class QObject;
class QTabWidget;
@ -46,13 +48,13 @@ namespace Ui @@ -46,13 +48,13 @@ namespace Ui
class SearchWidget;
}
class SearchWidget : public QWidget
class SearchWidget : public QWidget, public GUIApplicationComponent
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(SearchWidget)
public:
explicit SearchWidget(MainWindow *mainWindow);
explicit SearchWidget(IGUIApplication *app, MainWindow *mainWindow);
~SearchWidget() override;
void giveFocusToSearchInput();

Loading…
Cancel
Save