2006-09-30 20:02:39 +04:00
/*
2016-01-24 13:16:25 +03:00
* Bittorrent Client using Qt and libtorrent .
2018-06-06 16:48:17 +03:00
* Copyright ( C ) 2006 Christophe Dumez < chris @ qbittorrent . org >
2006-09-30 20:02:39 +04:00
*
2007-07-14 18:31:59 +04:00
* 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 .
2006-09-30 20:02:39 +04:00
*
* 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
2007-07-14 18:31:59 +04:00
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
*
2009-04-05 21:00:55 +04:00
* 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 .
2006-09-30 20:02:39 +04:00
*/
2011-04-02 12:54:28 +04:00
2017-04-11 15:35:10 +03:00
# include "mainwindow.h"
2022-01-19 19:35:12 +03:00
# include <algorithm>
2020-04-04 06:55:10 +03:00
# include <chrono>
2021-03-19 13:59:04 +03:00
# include <QActionGroup>
2020-10-30 20:49:15 +03:00
# include <QClipboard>
2017-11-24 10:33:11 +03:00
# include <QCloseEvent>
2015-08-27 14:25:14 +03:00
# include <QDebug>
2017-11-24 10:33:11 +03:00
# include <QDesktopServices>
2006-09-30 20:02:39 +04:00
# include <QFileDialog>
2010-08-23 23:42:15 +04:00
# include <QFileSystemWatcher>
2020-10-30 20:49:15 +03:00
# include <QKeyEvent>
2006-09-30 20:02:39 +04:00
# include <QMessageBox>
2022-04-12 11:19:09 +03:00
# include <QMetaObject>
2017-11-24 10:33:11 +03:00
# include <QMimeData>
# include <QProcess>
2018-05-23 12:27:19 +03:00
# include <QPushButton>
2017-11-24 10:33:11 +03:00
# include <QShortcut>
2017-04-11 15:35:10 +03:00
# include <QSplitter>
2017-11-24 10:33:11 +03:00
# include <QStatusBar>
# include <QtGlobal>
# include <QTimer>
2006-12-28 02:56:30 +03:00
2019-09-05 15:11:33 +03:00
# if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)) && defined(QT_DBUS_LIB)
2017-11-24 10:33:11 +03:00
# include <QDBusConnection>
2020-04-30 10:53:43 +03:00
# include "qtnotify/notifications.h"
2017-11-24 10:33:11 +03:00
# endif
2015-09-25 11:10:05 +03:00
# include "base/bittorrent/session.h"
# include "base/bittorrent/sessionstatus.h"
2016-04-29 12:25:15 +03:00
# include "base/global.h"
2018-12-29 15:38:51 +03:00
# include "base/net/downloadmanager.h"
2022-02-08 06:03:48 +03:00
# include "base/path.h"
2017-11-24 10:33:11 +03:00
# include "base/preferences.h"
2017-03-07 16:10:42 +03:00
# include "base/rss/rss_folder.h"
# include "base/rss/rss_session.h"
2018-06-19 15:04:54 +03:00
# include "base/utils/foreignapps.h"
2017-11-24 10:33:11 +03:00
# include "base/utils/fs.h"
# include "base/utils/misc.h"
2018-11-21 16:40:31 +03:00
# include "base/utils/password.h"
2021-01-04 10:02:13 +03:00
# include "base/version.h"
2018-06-14 12:54:23 +03:00
# include "aboutdialog.h"
2018-06-06 16:48:17 +03:00
# include "addnewtorrentdialog.h"
# include "autoexpandabledialog.h"
2016-01-24 13:16:25 +03:00
# include "cookiesdialog.h"
2018-05-23 11:43:03 +03:00
# include "downloadfromurldialog.h"
2018-06-14 12:54:23 +03:00
# include "executionlogwidget.h"
2017-11-24 10:33:11 +03:00
# include "hidabletabwidget.h"
# include "lineedit.h"
2018-06-14 12:54:23 +03:00
# include "optionsdialog.h"
2020-04-30 10:53:43 +03:00
# include "powermanagement/powermanagement.h"
# include "properties/peerlistwidget.h"
# include "properties/propertieswidget.h"
# include "properties/trackerlistwidget.h"
2017-03-07 16:10:42 +03:00
# include "rss/rsswidget.h"
2017-11-24 10:33:11 +03:00
# include "search/searchwidget.h"
2018-06-14 12:54:23 +03:00
# include "speedlimitdialog.h"
2017-11-24 10:33:11 +03:00
# include "statsdialog.h"
# include "statusbar.h"
2018-06-14 12:54:23 +03:00
# include "torrentcreatordialog.h"
2017-11-24 10:33:11 +03:00
# include "transferlistfilterswidget.h"
2019-07-16 07:01:33 +03:00
# include "transferlistmodel.h"
2017-11-24 10:33:11 +03:00
# include "transferlistwidget.h"
2016-01-24 13:16:25 +03:00
# include "ui_mainwindow.h"
2019-07-16 07:01:33 +03:00
# include "uithememanager.h"
2017-11-24 12:13:22 +03:00
# include "utils.h"
2016-01-24 13:16:25 +03:00
2019-09-05 15:11:33 +03:00
# ifdef Q_OS_MACOS
2017-08-11 08:37:06 +03:00
# include "macutilities.h"
# endif
2019-09-05 15:11:33 +03:00
# if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
2017-11-24 10:33:11 +03:00
# include "programupdater.h"
# endif
2017-08-11 08:37:06 +03:00
2021-01-25 10:49:41 +03:00
using namespace std : : chrono_literals ;
2016-03-14 15:39:13 +03:00
namespace
{
2022-03-23 18:56:47 +03:00
# 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)
2016-11-13 23:46:17 +03:00
2020-04-04 06:55:10 +03:00
const std : : chrono : : seconds PREVENT_SUSPEND_INTERVAL { 60 } ;
2020-04-06 10:29:55 +03:00
# if !defined(Q_OS_MACOS)
const int TIME_TRAY_BALLOON = 5000 ;
# endif
2020-04-04 06:55:10 +03:00
2020-10-30 20:49:15 +03:00
bool isTorrentLink ( const QString & str )
{
2022-03-29 05:41:17 +03:00
return str . startsWith ( u " magnet: " , Qt : : CaseInsensitive )
2022-03-04 08:25:22 +03:00
| | str . endsWith ( TORRENT_FILE_EXTENSION , Qt : : CaseInsensitive )
2022-03-29 05:41:17 +03:00
| | ( ! str . startsWith ( u " file: " , Qt : : CaseInsensitive )
2020-10-30 20:49:15 +03:00
& & Net : : DownloadManager : : hasSupportedScheme ( str ) ) ;
}
2022-05-26 22:12:10 +03:00
# 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
2016-03-14 15:39:13 +03:00
}
2015-01-22 15:56:16 +03:00
MainWindow : : MainWindow ( QWidget * parent )
: QMainWindow ( parent )
2016-01-24 13:16:25 +03:00
, m_ui ( new Ui : : MainWindow )
2022-03-23 18:56:47 +03:00
, 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 )
2021-11-08 08:23:33 +03:00
# if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)) && defined(QT_DBUS_LIB)
2022-03-23 18:56:47 +03:00
, m_storeNotificationTimeOut ( NOTIFICATIONS_SETTINGS_KEY ( u " Timeout " _qs ) )
2021-11-08 08:23:33 +03:00
# endif
2014-09-14 15:30:22 +04:00
{
2016-01-24 13:16:25 +03:00
m_ui - > setupUi ( this ) ;
2011-04-09 21:39:51 +04:00
2017-01-08 03:46:01 +03:00
Preferences * const pref = Preferences : : instance ( ) ;
2016-01-24 13:16:25 +03:00
m_uiLocked = pref - > isUILocked ( ) ;
2022-03-12 17:00:58 +03:00
setWindowTitle ( QStringLiteral ( " qBittorrent " QBT_VERSION ) ) ;
2016-01-24 13:16:25 +03:00
m_displaySpeedInTitle = pref - > speedInTitleBar ( ) ;
2014-12-20 20:53:58 +03:00
// Setting icons
2019-09-05 15:11:33 +03:00
# ifndef Q_OS_MACOS
2022-03-12 17:00:58 +03:00
const QIcon appLogo ( UIThemeManager : : instance ( ) - > getIcon ( u " qbittorrent " _qs , u " qbittorrent-tray " _qs ) ) ;
2018-05-08 16:30:12 +03:00
setWindowIcon ( appLogo ) ;
2019-09-05 15:11:33 +03:00
# endif // Q_OS_MACOS
2017-06-12 22:47:28 +03:00
# if (defined(Q_OS_UNIX))
m_ui - > actionOptions - > setText ( tr ( " Preferences " ) ) ;
# endif
2013-03-11 22:50:32 +04:00
2014-10-18 18:18:58 +04:00
addToolbarContextMenu ( ) ;
2022-03-12 17:00:58 +03:00
m_ui - > actionOpen - > setIcon ( UIThemeManager : : instance ( ) - > getIcon ( u " list-add " _qs ) ) ;
m_ui - > actionDownloadFromURL - > setIcon ( UIThemeManager : : instance ( ) - > getIcon ( u " insert-link " _qs ) ) ;
m_ui - > actionSetGlobalSpeedLimits - > setIcon ( UIThemeManager : : instance ( ) - > getIcon ( u " speedometer " _qs ) ) ;
m_ui - > actionCreateTorrent - > setIcon ( UIThemeManager : : instance ( ) - > getIcon ( u " document-edit " _qs ) ) ;
m_ui - > actionAbout - > setIcon ( UIThemeManager : : instance ( ) - > getIcon ( u " help-about " _qs ) ) ;
m_ui - > actionStatistics - > setIcon ( UIThemeManager : : instance ( ) - > getIcon ( u " view-statistics " _qs ) ) ;
m_ui - > actionTopQueuePos - > setIcon ( UIThemeManager : : instance ( ) - > getIcon ( u " go-top " _qs ) ) ;
m_ui - > actionIncreaseQueuePos - > setIcon ( UIThemeManager : : instance ( ) - > getIcon ( u " go-up " _qs ) ) ;
m_ui - > actionDecreaseQueuePos - > setIcon ( UIThemeManager : : instance ( ) - > getIcon ( u " go-down " _qs ) ) ;
m_ui - > actionBottomQueuePos - > setIcon ( UIThemeManager : : instance ( ) - > getIcon ( u " go-bottom " _qs ) ) ;
m_ui - > actionDelete - > setIcon ( UIThemeManager : : instance ( ) - > getIcon ( u " list-remove " _qs ) ) ;
m_ui - > actionDocumentation - > setIcon ( UIThemeManager : : instance ( ) - > getIcon ( u " help-contents " _qs ) ) ;
m_ui - > actionDonateMoney - > setIcon ( UIThemeManager : : instance ( ) - > getIcon ( u " wallet-open " _qs ) ) ;
m_ui - > actionExit - > setIcon ( UIThemeManager : : instance ( ) - > getIcon ( u " application-exit " _qs ) ) ;
m_ui - > actionLock - > setIcon ( UIThemeManager : : instance ( ) - > getIcon ( u " object-locked " _qs ) ) ;
m_ui - > actionOptions - > setIcon ( UIThemeManager : : instance ( ) - > getIcon ( u " configure " _qs , u " preferences-system " _qs ) ) ;
m_ui - > actionPause - > setIcon ( UIThemeManager : : instance ( ) - > getIcon ( u " media-playback-pause " _qs ) ) ;
m_ui - > actionPauseAll - > setIcon ( UIThemeManager : : instance ( ) - > getIcon ( u " media-playback-pause " _qs ) ) ;
m_ui - > actionStart - > setIcon ( UIThemeManager : : instance ( ) - > getIcon ( u " media-playback-start " _qs ) ) ;
m_ui - > actionStartAll - > setIcon ( UIThemeManager : : instance ( ) - > getIcon ( u " media-playback-start " _qs ) ) ;
m_ui - > menuAutoShutdownOnDownloadsCompletion - > setIcon ( UIThemeManager : : instance ( ) - > getIcon ( u " application-exit " _qs ) ) ;
m_ui - > actionManageCookies - > setIcon ( UIThemeManager : : instance ( ) - > getIcon ( u " preferences-web-browser-cookies " _qs ) ) ;
2014-12-20 20:53:58 +03:00
2019-02-13 18:12:02 +03:00
auto * lockMenu = new QMenu ( this ) ;
2021-01-17 09:56:56 +03:00
lockMenu - > addAction ( tr ( " &Set Password " ) , this , & MainWindow : : defineUILockPassword ) ;
lockMenu - > addAction ( tr ( " &Clear Password " ) , this , & MainWindow : : clearUILockPassword ) ;
2016-01-24 13:16:25 +03:00
m_ui - > actionLock - > setMenu ( lockMenu ) ;
2021-12-14 09:38:31 +03:00
connect ( this , & MainWindow : : systemTrayIconCreated , this , [ this ] ( )
{
m_ui - > actionLock - > setVisible ( true ) ;
} ) ;
2015-01-26 17:00:23 +03:00
2014-12-20 20:53:58 +03:00
// Creating Bittorrent session
2021-12-13 10:56:20 +03:00
updateAltSpeedsBtn ( BitTorrent : : Session : : instance ( ) - > isAltGlobalSpeedLimitEnabled ( ) ) ;
2017-07-16 07:10:13 +03:00
connect ( BitTorrent : : Session : : instance ( ) , & BitTorrent : : Session : : fullDiskError , this , & MainWindow : : fullDiskError ) ;
2020-08-05 08:31:41 +03:00
connect ( BitTorrent : : Session : : instance ( ) , & BitTorrent : : Session : : loadTorrentFailed , this , & MainWindow : : addTorrentFailed ) ;
connect ( BitTorrent : : Session : : instance ( ) , & BitTorrent : : Session : : torrentAdded , this , & MainWindow : : torrentNew ) ;
2017-07-16 07:10:13 +03:00
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 ) ;
2009-11-07 22:55:33 +03:00
2014-12-20 20:53:58 +03:00
qDebug ( " create tabWidget " ) ;
2016-01-24 13:16:25 +03:00
m_tabs = new HidableTabWidget ( this ) ;
2017-07-16 07:10:13 +03:00
connect ( m_tabs . data ( ) , & QTabWidget : : currentChanged , this , & MainWindow : : tabChanged ) ;
2015-01-26 17:00:23 +03:00
2016-01-24 13:16:25 +03:00
m_splitter = new QSplitter ( Qt : : Horizontal , this ) ;
2017-01-08 03:46:01 +03:00
// vSplitter->setChildrenCollapsible(false);
2015-01-26 17:00:23 +03:00
2019-02-13 18:12:02 +03:00
auto * hSplitter = new QSplitter ( Qt : : Vertical , this ) ;
2014-12-20 20:53:58 +03:00
hSplitter - > setChildrenCollapsible ( false ) ;
2015-07-12 11:52:18 +03:00
hSplitter - > setFrameShape ( QFrame : : NoFrame ) ;
2014-12-20 20:53:58 +03:00
// Name filter
2016-01-24 13:16:25 +03:00
m_searchFilter = new LineEdit ( this ) ;
2020-02-23 17:40:45 +03:00
m_searchFilter - > setPlaceholderText ( tr ( " Filter torrent names... " ) ) ;
2022-03-11 08:40:58 +03:00
m_searchFilter - > setFixedWidth ( 200 ) ;
2018-07-29 15:46:19 +03:00
m_searchFilter - > setContextMenuPolicy ( Qt : : CustomContextMenu ) ;
connect ( m_searchFilter , & QWidget : : customContextMenuRequested , this , & MainWindow : : showFilterContextMenu ) ;
m_searchFilterAction = m_ui - > toolBar - > insertWidget ( m_ui - > actionLock , m_searchFilter ) ;
2015-01-26 17:00:23 +03:00
2014-12-20 20:53:58 +03:00
QWidget * spacer = new QWidget ( this ) ;
spacer - > setSizePolicy ( QSizePolicy : : Expanding , QSizePolicy : : Fixed ) ;
2016-01-24 13:16:25 +03:00
m_ui - > toolBar - > insertWidget ( m_searchFilterAction , spacer ) ;
2014-12-20 20:53:58 +03:00
// Transfer List tab
2016-01-24 13:16:25 +03:00
m_transferListWidget = new TransferListWidget ( hSplitter , this ) ;
2019-01-26 11:43:07 +03:00
// m_transferListWidget->setStyleSheet("QTreeView {border: none;}"); // borderless
m_propertiesWidget = new PropertiesWidget ( hSplitter ) ;
connect ( m_transferListWidget , & TransferListWidget : : currentTorrentChanged , m_propertiesWidget , & PropertiesWidget : : loadTorrentInfos ) ;
2016-01-24 13:16:25 +03:00
hSplitter - > addWidget ( m_transferListWidget ) ;
hSplitter - > addWidget ( m_propertiesWidget ) ;
m_splitter - > addWidget ( hSplitter ) ;
2022-03-21 07:41:06 +03:00
m_splitter - > setCollapsible ( 0 , false ) ;
2017-06-12 22:47:28 +03:00
m_tabs - > addTab ( m_splitter ,
2019-09-05 15:11:33 +03:00
# ifndef Q_OS_MACOS
2022-03-12 17:00:58 +03:00
UIThemeManager : : instance ( ) - > getIcon ( u " folder-remote " _qs ) ,
2017-06-12 22:47:28 +03:00
# endif
tr ( " Transfers " ) ) ;
2016-01-24 13:16:25 +03:00
2017-07-16 07:10:13 +03:00
connect ( m_searchFilter , & LineEdit : : textChanged , m_transferListWidget , & TransferListWidget : : applyNameFilter ) ;
connect ( hSplitter , & QSplitter : : splitterMoved , this , & MainWindow : : writeSettings ) ;
2022-03-21 07:41:06 +03:00
connect ( m_splitter , & QSplitter : : splitterMoved , this , & MainWindow : : writeSplitterSettings ) ;
2017-07-16 07:10:13 +03:00
connect ( BitTorrent : : Session : : instance ( ) , & BitTorrent : : Session : : trackersChanged , m_propertiesWidget , & PropertiesWidget : : loadTrackers ) ;
2014-12-20 20:53:58 +03:00
2019-09-05 15:11:33 +03:00
# ifdef Q_OS_MACOS
2017-06-12 22:47:28 +03:00
// Increase top spacing to avoid tab overlapping
m_ui - > centralWidgetLayout - > addSpacing ( 8 ) ;
# endif
2016-01-24 13:16:25 +03:00
m_ui - > centralWidgetLayout - > addWidget ( m_tabs ) ;
2014-12-20 20:53:58 +03:00
2018-12-08 02:01:09 +03:00
m_queueSeparator = m_ui - > toolBar - > insertSeparator ( m_ui - > actionTopQueuePos ) ;
m_queueSeparatorMenu = m_ui - > menuEdit - > insertSeparator ( m_ui - > actionTopQueuePos ) ;
2017-07-16 06:47:53 +03:00
2019-09-05 15:11:33 +03:00
# ifdef Q_OS_MACOS
2020-11-16 10:02:11 +03:00
for ( QAction * action : asConst ( m_ui - > toolBar - > actions ( ) ) )
{
if ( action - > isSeparator ( ) )
{
2017-06-12 22:47:28 +03:00
QWidget * spacer = new QWidget ( this ) ;
spacer - > setSizePolicy ( QSizePolicy : : Fixed , QSizePolicy : : Fixed ) ;
spacer - > setMinimumWidth ( 16 ) ;
m_ui - > toolBar - > insertWidget ( action , spacer ) ;
m_ui - > toolBar - > removeAction ( action ) ;
}
}
{
QWidget * spacer = new QWidget ( this ) ;
spacer - > setSizePolicy ( QSizePolicy : : Fixed , QSizePolicy : : Fixed ) ;
spacer - > setMinimumWidth ( 8 ) ;
m_ui - > toolBar - > insertWidget ( m_ui - > actionDownloadFromURL , spacer ) ;
}
{
QWidget * spacer = new QWidget ( this ) ;
spacer - > setSizePolicy ( QSizePolicy : : Fixed , QSizePolicy : : Fixed ) ;
spacer - > setMinimumWidth ( 8 ) ;
m_ui - > toolBar - > addWidget ( spacer ) ;
}
2019-09-05 15:11:33 +03:00
# endif // Q_OS_MACOS
2014-12-20 20:53:58 +03:00
// Transfer list slots
2017-07-16 07:10:13 +03:00
connect ( m_ui - > actionStart , & QAction : : triggered , m_transferListWidget , & TransferListWidget : : startSelectedTorrents ) ;
connect ( m_ui - > actionStartAll , & QAction : : triggered , m_transferListWidget , & TransferListWidget : : resumeAllTorrents ) ;
connect ( m_ui - > actionPause , & QAction : : triggered , m_transferListWidget , & TransferListWidget : : pauseSelectedTorrents ) ;
connect ( m_ui - > actionPauseAll , & QAction : : triggered , m_transferListWidget , & TransferListWidget : : pauseAllTorrents ) ;
connect ( m_ui - > actionDelete , & QAction : : triggered , m_transferListWidget , & TransferListWidget : : softDeleteSelectedTorrents ) ;
2018-12-08 02:01:09 +03:00
connect ( m_ui - > actionTopQueuePos , & QAction : : triggered , m_transferListWidget , & TransferListWidget : : topQueuePosSelectedTorrents ) ;
connect ( m_ui - > actionIncreaseQueuePos , & QAction : : triggered , m_transferListWidget , & TransferListWidget : : increaseQueuePosSelectedTorrents ) ;
connect ( m_ui - > actionDecreaseQueuePos , & QAction : : triggered , m_transferListWidget , & TransferListWidget : : decreaseQueuePosSelectedTorrents ) ;
connect ( m_ui - > actionBottomQueuePos , & QAction : : triggered , m_transferListWidget , & TransferListWidget : : bottomQueuePosSelectedTorrents ) ;
2019-09-05 15:11:33 +03:00
# ifndef Q_OS_MACOS
2017-07-19 10:21:15 +03:00
connect ( m_ui - > actionToggleVisibility , & QAction : : triggered , this , [ this ] ( ) { toggleVisibility ( ) ; } ) ;
2017-06-12 22:47:28 +03:00
# endif
2017-07-16 07:10:13 +03:00
connect ( m_ui - > actionMinimize , & QAction : : triggered , this , & MainWindow : : minimizeWindow ) ;
2017-05-25 17:50:05 +03:00
connect ( m_ui - > actionUseAlternativeSpeedLimits , & QAction : : triggered , this , & MainWindow : : toggleAlternativeSpeeds ) ;
2009-11-07 22:55:33 +03:00
2019-09-05 15:11:33 +03:00
# if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
2021-01-25 10:49:29 +03:00
connect ( m_ui - > actionCheckForUpdates , & QAction : : triggered , this , [ this ] ( ) { checkProgramUpdate ( true ) ; } ) ;
// trigger an early check on startup
if ( pref - > isUpdateCheckEnabled ( ) )
checkProgramUpdate ( false ) ;
2013-11-23 16:58:03 +04:00
# else
2016-01-24 13:16:25 +03:00
m_ui - > actionCheckForUpdates - > setVisible ( false ) ;
2013-11-23 16:58:03 +04:00
# endif
2017-07-19 21:11:19 +03:00
// Certain menu items should reside at specific places on macOS.
// Qt partially does it on its own, but updates and different languages require tuning.
m_ui - > actionExit - > setMenuRole ( QAction : : QuitRole ) ;
m_ui - > actionAbout - > setMenuRole ( QAction : : AboutRole ) ;
m_ui - > actionCheckForUpdates - > setMenuRole ( QAction : : ApplicationSpecificRole ) ;
m_ui - > actionOptions - > setMenuRole ( QAction : : PreferencesRole ) ;
2017-07-16 07:10:13 +03:00
connect ( m_ui - > actionManageCookies , & QAction : : triggered , this , & MainWindow : : manageCookies ) ;
2016-01-23 15:12:13 +03:00
2014-12-20 20:53:58 +03:00
m_pwr = new PowerManagement ( this ) ;
2016-01-24 13:16:25 +03:00
m_preventTimer = new QTimer ( this ) ;
2018-08-02 22:45:21 +03:00
connect ( m_preventTimer , & QTimer : : timeout , this , & MainWindow : : updatePowerManagementState ) ;
2014-12-20 20:53:58 +03:00
// Configure BT session according to options
2021-12-13 10:56:20 +03:00
loadPreferences ( ) ;
2014-12-20 20:53:58 +03:00
2019-09-24 06:29:07 +03:00
connect ( BitTorrent : : Session : : instance ( ) , & BitTorrent : : Session : : statsUpdated , this , & MainWindow : : reloadSessionStats ) ;
connect ( BitTorrent : : Session : : instance ( ) , & BitTorrent : : Session : : torrentsUpdated , this , & MainWindow : : reloadTorrentStats ) ;
2015-04-19 18:17:47 +03:00
2014-12-20 20:53:58 +03:00
// Accept drag 'n drops
setAcceptDrops ( true ) ;
createKeyboardShortcuts ( ) ;
2009-11-08 15:23:04 +03:00
2019-09-05 15:11:33 +03:00
# ifdef Q_OS_MACOS
2014-12-20 20:53:58 +03:00
setUnifiedTitleAndToolBarOnMac ( true ) ;
2010-06-09 11:37:05 +04:00
# endif
2014-12-20 20:53:58 +03:00
// View settings
2016-01-24 13:16:25 +03:00
m_ui - > actionTopToolBar - > setChecked ( pref - > isToolbarDisplayed ( ) ) ;
2015-10-30 16:03:44 +03:00
m_ui - > actionShowStatusbar - > setChecked ( pref - > isStatusbarDisplayed ( ) ) ;
2016-01-24 13:16:25 +03:00
m_ui - > actionSpeedInTitleBar - > setChecked ( pref - > speedInTitleBar ( ) ) ;
2017-03-07 16:10:42 +03:00
m_ui - > actionRSSReader - > setChecked ( pref - > isRSSWidgetEnabled ( ) ) ;
2016-01-24 13:16:25 +03:00
m_ui - > actionSearchWidget - > setChecked ( pref - > isSearchEnabled ( ) ) ;
m_ui - > actionExecutionLogs - > setChecked ( isExecutionLogEnabled ( ) ) ;
2016-01-24 22:38:45 +03:00
2021-11-08 08:23:33 +03:00
const Log : : MsgTypes flags = executionLogMsgTypes ( ) ;
m_ui - > actionNormalMessages - > setChecked ( flags . testFlag ( Log : : NORMAL ) ) ;
m_ui - > actionInformationMessages - > setChecked ( flags . testFlag ( Log : : INFO ) ) ;
m_ui - > actionWarningMessages - > setChecked ( flags . testFlag ( Log : : WARNING ) ) ;
m_ui - > actionCriticalMessages - > setChecked ( flags . testFlag ( Log : : CRITICAL ) ) ;
2016-01-24 13:16:25 +03:00
displayRSSTab ( m_ui - > actionRSSReader - > isChecked ( ) ) ;
on_actionExecutionLogs_triggered ( m_ui - > actionExecutionLogs - > isChecked ( ) ) ;
on_actionNormalMessages_triggered ( m_ui - > actionNormalMessages - > isChecked ( ) ) ;
on_actionInformationMessages_triggered ( m_ui - > actionInformationMessages - > isChecked ( ) ) ;
on_actionWarningMessages_triggered ( m_ui - > actionWarningMessages - > isChecked ( ) ) ;
on_actionCriticalMessages_triggered ( m_ui - > actionCriticalMessages - > isChecked ( ) ) ;
if ( m_ui - > actionSearchWidget - > isChecked ( ) )
2022-04-12 11:19:09 +03:00
QMetaObject : : invokeMethod ( this , & MainWindow : : on_actionSearchWidget_triggered , Qt : : QueuedConnection ) ;
2014-12-20 20:53:58 +03:00
// Auto shutdown actions
2019-02-13 18:12:02 +03:00
auto * autoShutdownGroup = new QActionGroup ( this ) ;
2014-12-20 20:53:58 +03:00
autoShutdownGroup - > setExclusive ( true ) ;
2016-01-24 13:16:25 +03:00
autoShutdownGroup - > addAction ( m_ui - > actionAutoShutdownDisabled ) ;
autoShutdownGroup - > addAction ( m_ui - > actionAutoExit ) ;
autoShutdownGroup - > addAction ( m_ui - > actionAutoShutdown ) ;
autoShutdownGroup - > addAction ( m_ui - > actionAutoSuspend ) ;
autoShutdownGroup - > addAction ( m_ui - > actionAutoHibernate ) ;
2019-09-05 15:11:33 +03:00
# if (!defined(Q_OS_UNIX) || defined(Q_OS_MACOS)) || defined(QT_DBUS_LIB)
2016-01-24 13:16:25 +03:00
m_ui - > actionAutoShutdown - > setChecked ( pref - > shutdownWhenDownloadsComplete ( ) ) ;
m_ui - > actionAutoSuspend - > setChecked ( pref - > suspendWhenDownloadsComplete ( ) ) ;
m_ui - > actionAutoHibernate - > setChecked ( pref - > hibernateWhenDownloadsComplete ( ) ) ;
2011-03-07 23:25:20 +03:00
# else
2016-01-24 13:16:25 +03:00
m_ui - > actionAutoShutdown - > setDisabled ( true ) ;
m_ui - > actionAutoSuspend - > setDisabled ( true ) ;
m_ui - > actionAutoHibernate - > setDisabled ( true ) ;
2011-03-07 23:22:35 +03:00
# endif
2016-01-24 13:16:25 +03:00
m_ui - > actionAutoExit - > setChecked ( pref - > shutdownqBTWhenDownloadsComplete ( ) ) ;
2011-03-07 23:22:35 +03:00
2014-12-20 20:53:58 +03:00
if ( ! autoShutdownGroup - > checkedAction ( ) )
2016-01-24 13:16:25 +03:00
m_ui - > actionAutoShutdownDisabled - > setChecked ( true ) ;
2010-06-21 22:32:01 +04:00
2014-12-20 20:53:58 +03:00
// Load Window state and sizes
readSettings ( ) ;
2009-11-08 15:23:04 +03:00
2021-12-13 10:56:20 +03:00
# ifdef Q_OS_MACOS
// Make sure the Window is visible if we don't have a tray icon
if ( pref - > startMinimized ( ) )
{
showMinimized ( ) ;
}
else
{
show ( ) ;
activateWindow ( ) ;
raise ( ) ;
}
# else
2020-11-16 10:02:11 +03:00
if ( m_systrayIcon )
{
if ( ! ( pref - > startMinimized ( ) | | m_uiLocked ) )
{
2014-12-20 20:53:58 +03:00
show ( ) ;
activateWindow ( ) ;
raise ( ) ;
}
2020-11-16 10:02:11 +03:00
else if ( pref - > startMinimized ( ) )
{
2015-07-03 22:09:37 +03:00
showMinimized ( ) ;
2020-11-16 10:02:11 +03:00
if ( pref - > minimizeToTray ( ) )
{
2015-07-03 22:09:37 +03:00
hide ( ) ;
2020-11-16 10:02:11 +03:00
if ( ! pref - > minimizeToTrayNotified ( ) )
{
2021-10-09 19:14:18 +03:00
showNotificationBalloon ( tr ( " qBittorrent is minimized to tray " ) , tr ( " This behavior can be changed in the settings. You won't be reminded again. " ) ) ;
2018-08-03 14:55:20 +03:00
pref - > setMinimizeToTrayNotified ( true ) ;
}
}
2015-04-21 12:58:21 +03:00
}
}
2020-11-16 10:02:11 +03:00
else
{
2015-04-21 12:58:21 +03:00
// Make sure the Window is visible if we don't have a tray icon
2020-11-16 10:02:11 +03:00
if ( pref - > startMinimized ( ) )
{
2015-04-21 12:58:21 +03:00
showMinimized ( ) ;
}
2020-11-16 10:02:11 +03:00
else
{
2015-04-21 12:58:21 +03:00
show ( ) ;
activateWindow ( ) ;
raise ( ) ;
}
2011-01-17 20:29:25 +03:00
}
2017-06-12 22:47:28 +03:00
# endif
2009-11-08 15:23:04 +03:00
2016-01-24 13:16:25 +03:00
m_propertiesWidget - > readSettings ( ) ;
2011-02-06 00:27:13 +03:00
2022-03-21 07:41:06 +03:00
const bool isFiltersSidebarVisible = pref - > isFiltersSidebarVisible ( ) ;
m_ui - > actionShowFiltersSidebar - > setChecked ( isFiltersSidebarVisible ) ;
if ( isFiltersSidebarVisible )
{
showFiltersSidebar ( true ) ;
}
else
{
m_transferListWidget - > applyStatusFilter ( pref - > getTransSelFilter ( ) ) ;
m_transferListWidget - > applyCategoryFilter ( QString ( ) ) ;
m_transferListWidget - > applyTagFilter ( QString ( ) ) ;
m_transferListWidget - > applyTrackerFilterAll ( ) ;
}
2014-12-20 20:53:58 +03:00
// Start watching the executable for updates
2016-01-24 13:16:25 +03:00
m_executableWatcher = new QFileSystemWatcher ( this ) ;
2017-07-16 07:10:13 +03:00
connect ( m_executableWatcher , & QFileSystemWatcher : : fileChanged , this , & MainWindow : : notifyOfUpdate ) ;
2016-01-24 13:16:25 +03:00
m_executableWatcher - > addPath ( qApp - > applicationFilePath ( ) ) ;
2010-08-23 23:42:15 +04:00
2016-01-24 13:16:25 +03:00
m_transferListWidget - > setFocus ( ) ;
2010-11-14 18:28:22 +03:00
2014-12-20 20:53:58 +03:00
// Update the number of torrents (tab)
updateNbTorrents ( ) ;
2017-07-16 07:10:13 +03:00
connect ( m_transferListWidget - > getSourceModel ( ) , & QAbstractItemModel : : rowsInserted , this , & MainWindow : : updateNbTorrents ) ;
connect ( m_transferListWidget - > getSourceModel ( ) , & QAbstractItemModel : : rowsRemoved , this , & MainWindow : : updateNbTorrents ) ;
2010-12-25 12:23:04 +03:00
2017-07-16 07:10:13 +03:00
connect ( pref , & Preferences : : changed , this , & MainWindow : : optionsSaved ) ;
2015-12-13 17:41:58 +03:00
2014-12-20 20:53:58 +03:00
qDebug ( " GUI Built " ) ;
2013-09-21 11:59:58 +04:00
# ifdef Q_OS_WIN
2020-11-16 10:02:11 +03:00
if ( ! pref - > neverCheckFileAssoc ( ) & & ( ! Preferences : : isTorrentFileAssocSet ( ) | | ! Preferences : : isMagnetLinkAssocSet ( ) ) )
{
2015-11-11 06:19:16 +03:00
if ( QMessageBox : : question ( this , tr ( " Torrent file association " ) ,
2021-09-12 11:45:00 +03:00
tr ( " qBittorrent is not the default application for opening torrent files or Magnet links. \n Do you want to make qBittorrent the default application for these? " ) ,
2020-11-16 10:02:11 +03:00
QMessageBox : : Yes | QMessageBox : : No , QMessageBox : : Yes ) = = QMessageBox : : Yes )
{
2014-12-20 20:53:58 +03:00
Preferences : : setTorrentFileAssoc ( true ) ;
Preferences : : setMagnetLinkAssoc ( true ) ;
}
2020-11-16 10:02:11 +03:00
else
{
2014-12-20 20:53:58 +03:00
pref - > setNeverCheckFileAssoc ( ) ;
}
2010-06-02 17:08:26 +04:00
}
2010-05-31 01:45:55 +04:00
# endif
2019-09-05 15:11:33 +03:00
# ifdef Q_OS_MACOS
2017-06-12 22:47:28 +03:00
setupDockClickHandler ( ) ;
2021-12-13 10:56:20 +03:00
createTrayIconMenu ( ) ;
m_trayIconMenu - > setAsDockMenu ( ) ;
2010-06-09 19:40:55 +04:00
# endif
2014-12-20 20:53:58 +03:00
}
2015-01-26 17:00:23 +03:00
MainWindow : : ~ MainWindow ( )
{
2016-01-24 13:16:25 +03:00
delete m_ui ;
2015-01-26 17:00:23 +03:00
}
2016-03-14 15:39:13 +03:00
bool MainWindow : : isExecutionLogEnabled ( ) const
{
2021-11-08 08:23:33 +03:00
return m_storeExecutionLogEnabled ;
2016-03-14 15:39:13 +03:00
}
2021-11-08 08:23:33 +03:00
void MainWindow : : setExecutionLogEnabled ( const bool value )
2016-03-14 15:39:13 +03:00
{
2021-11-08 08:23:33 +03:00
m_storeExecutionLogEnabled = value ;
2016-03-14 15:39:13 +03:00
}
2021-11-08 08:23:33 +03:00
Log : : MsgTypes MainWindow : : executionLogMsgTypes ( ) const
2016-03-14 15:39:13 +03:00
{
2021-11-08 08:23:33 +03:00
return m_storeExecutionLogTypes ;
2016-03-14 15:39:13 +03:00
}
2021-11-08 08:23:33 +03:00
void MainWindow : : setExecutionLogMsgTypes ( const Log : : MsgTypes value )
2016-03-14 15:39:13 +03:00
{
2021-11-08 08:23:33 +03:00
m_executionLog - > setMessageTypes ( value ) ;
m_storeExecutionLogTypes = value ;
2016-03-14 15:39:13 +03:00
}
2016-04-17 22:56:51 +03:00
bool MainWindow : : isNotificationsEnabled ( ) const
{
2021-11-08 08:23:33 +03:00
return m_storeNotificationEnabled . get ( true ) ;
2016-04-17 22:56:51 +03:00
}
void MainWindow : : setNotificationsEnabled ( bool value )
{
2021-11-08 08:23:33 +03:00
m_storeNotificationEnabled = value ;
2016-04-17 22:56:51 +03:00
}
bool MainWindow : : isTorrentAddedNotificationsEnabled ( ) const
{
2021-11-08 08:23:33 +03:00
return m_storeNotificationTorrentAdded ;
2016-04-17 22:56:51 +03:00
}
2021-11-08 08:23:33 +03:00
void MainWindow : : setTorrentAddedNotificationsEnabled ( const bool value )
2016-04-17 22:56:51 +03:00
{
2021-11-08 08:23:33 +03:00
m_storeNotificationTorrentAdded = value ;
2016-04-17 22:56:51 +03:00
}
2021-04-13 17:22:48 +03:00
# if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)) && defined(QT_DBUS_LIB)
int MainWindow : : getNotificationTimeout ( ) const
{
2021-11-08 08:23:33 +03:00
return m_storeNotificationTimeOut . get ( - 1 ) ;
2021-04-13 17:22:48 +03:00
}
void MainWindow : : setNotificationTimeout ( const int value )
{
2021-11-08 08:23:33 +03:00
m_storeNotificationTimeOut = value ;
2021-04-13 17:22:48 +03:00
}
# endif
2016-11-13 23:46:17 +03:00
bool MainWindow : : isDownloadTrackerFavicon ( ) const
{
2021-11-08 08:23:33 +03:00
return m_storeDownloadTrackerFavicon ;
2016-11-13 23:46:17 +03:00
}
2021-11-08 08:23:33 +03:00
void MainWindow : : setDownloadTrackerFavicon ( const bool value )
2016-11-13 23:46:17 +03:00
{
2022-03-21 07:41:06 +03:00
if ( m_transferListFiltersWidget )
m_transferListFiltersWidget - > setDownloadTrackerFavicon ( value ) ;
2021-11-08 08:23:33 +03:00
m_storeDownloadTrackerFavicon = value ;
2016-11-13 23:46:17 +03:00
}
2014-10-18 18:18:58 +04:00
void MainWindow : : addToolbarContextMenu ( )
{
2017-01-08 03:46:01 +03:00
const Preferences * const pref = Preferences : : instance ( ) ;
2016-01-24 13:16:25 +03:00
m_toolbarMenu = new QMenu ( this ) ;
2014-10-18 18:18:58 +04:00
2016-01-24 13:16:25 +03:00
m_ui - > toolBar - > setContextMenuPolicy ( Qt : : CustomContextMenu ) ;
2017-07-16 07:10:13 +03:00
connect ( m_ui - > toolBar , & QWidget : : customContextMenuRequested , this , & MainWindow : : toolbarMenuRequested ) ;
2014-10-18 18:18:58 +04:00
2021-01-17 09:56:56 +03:00
QAction * iconsOnly = m_toolbarMenu - > addAction ( tr ( " Icons Only " ) , this , & MainWindow : : toolbarIconsOnly ) ;
QAction * textOnly = m_toolbarMenu - > addAction ( tr ( " Text Only " ) , this , & MainWindow : : toolbarTextOnly ) ;
QAction * textBesideIcons = m_toolbarMenu - > addAction ( tr ( " Text Alongside Icons " ) , this , & MainWindow : : toolbarTextBeside ) ;
QAction * textUnderIcons = m_toolbarMenu - > addAction ( tr ( " Text Under Icons " ) , this , & MainWindow : : toolbarTextUnder ) ;
QAction * followSystemStyle = m_toolbarMenu - > addAction ( tr ( " Follow System Style " ) , this , & MainWindow : : toolbarFollowSystem ) ;
2019-06-23 18:27:37 +03:00
2019-02-13 18:12:02 +03:00
auto * textPositionGroup = new QActionGroup ( m_toolbarMenu ) ;
2014-10-18 18:18:58 +04:00
textPositionGroup - > addAction ( iconsOnly ) ;
iconsOnly - > setCheckable ( true ) ;
textPositionGroup - > addAction ( textOnly ) ;
textOnly - > setCheckable ( true ) ;
textPositionGroup - > addAction ( textBesideIcons ) ;
textBesideIcons - > setCheckable ( true ) ;
textPositionGroup - > addAction ( textUnderIcons ) ;
textUnderIcons - > setCheckable ( true ) ;
textPositionGroup - > addAction ( followSystemStyle ) ;
followSystemStyle - > setCheckable ( true ) ;
2019-02-13 18:12:02 +03:00
const auto buttonStyle = static_cast < Qt : : ToolButtonStyle > ( pref - > getToolbarTextPosition ( ) ) ;
2016-01-24 13:16:25 +03:00
if ( ( buttonStyle > = Qt : : ToolButtonIconOnly ) & & ( buttonStyle < = Qt : : ToolButtonFollowStyle ) )
m_ui - > toolBar - > setToolButtonStyle ( buttonStyle ) ;
2020-11-16 10:02:11 +03:00
switch ( buttonStyle )
{
2014-10-18 18:18:58 +04:00
case Qt : : ToolButtonIconOnly :
iconsOnly - > setChecked ( true ) ;
break ;
case Qt : : ToolButtonTextOnly :
textOnly - > setChecked ( true ) ;
break ;
case Qt : : ToolButtonTextBesideIcon :
textBesideIcons - > setChecked ( true ) ;
break ;
case Qt : : ToolButtonTextUnderIcon :
textUnderIcons - > setChecked ( true ) ;
break ;
default :
followSystemStyle - > setChecked ( true ) ;
}
}
2016-01-23 15:12:13 +03:00
void MainWindow : : manageCookies ( )
{
2019-06-03 10:10:19 +03:00
auto * cookieDialog = new CookiesDialog ( this ) ;
cookieDialog - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
cookieDialog - > open ( ) ;
2016-01-23 15:12:13 +03:00
}
2022-01-21 12:31:31 +03:00
void MainWindow : : toolbarMenuRequested ( )
2014-10-18 18:18:58 +04:00
{
2022-01-21 12:31:31 +03:00
m_toolbarMenu - > popup ( QCursor : : pos ( ) ) ;
2014-10-18 18:18:58 +04:00
}
void MainWindow : : toolbarIconsOnly ( )
{
2016-01-24 13:16:25 +03:00
m_ui - > toolBar - > setToolButtonStyle ( Qt : : ToolButtonIconOnly ) ;
2014-10-18 18:18:58 +04:00
Preferences : : instance ( ) - > setToolbarTextPosition ( Qt : : ToolButtonIconOnly ) ;
}
void MainWindow : : toolbarTextOnly ( )
{
2016-01-24 13:16:25 +03:00
m_ui - > toolBar - > setToolButtonStyle ( Qt : : ToolButtonTextOnly ) ;
2014-10-18 18:18:58 +04:00
Preferences : : instance ( ) - > setToolbarTextPosition ( Qt : : ToolButtonTextOnly ) ;
}
void MainWindow : : toolbarTextBeside ( )
{
2016-01-24 13:16:25 +03:00
m_ui - > toolBar - > setToolButtonStyle ( Qt : : ToolButtonTextBesideIcon ) ;
2014-10-18 18:18:58 +04:00
Preferences : : instance ( ) - > setToolbarTextPosition ( Qt : : ToolButtonTextBesideIcon ) ;
}
void MainWindow : : toolbarTextUnder ( )
{
2016-01-24 13:16:25 +03:00
m_ui - > toolBar - > setToolButtonStyle ( Qt : : ToolButtonTextUnderIcon ) ;
2014-10-18 18:18:58 +04:00
Preferences : : instance ( ) - > setToolbarTextPosition ( Qt : : ToolButtonTextUnderIcon ) ;
}
void MainWindow : : toolbarFollowSystem ( )
{
2016-01-24 13:16:25 +03:00
m_ui - > toolBar - > setToolButtonStyle ( Qt : : ToolButtonFollowStyle ) ;
2014-10-18 18:18:58 +04:00
Preferences : : instance ( ) - > setToolbarTextPosition ( Qt : : ToolButtonFollowStyle ) ;
}
2018-11-21 16:40:31 +03:00
bool MainWindow : : defineUILockPassword ( )
2014-12-20 20:53:58 +03:00
{
bool ok = false ;
2018-11-21 16:40:31 +03:00
const QString newPassword = AutoExpandableDialog : : getText ( this , tr ( " UI lock password " )
, tr ( " Please type the UI lock password: " ) , QLineEdit : : Password , { } , & ok ) ;
if ( ! ok )
return false ;
2020-11-16 10:02:11 +03:00
if ( newPassword . size ( ) < 3 )
{
2021-09-12 11:45:00 +03:00
QMessageBox : : warning ( this , tr ( " Invalid password " ) , tr ( " The password must be at least 3 characters long " ) ) ;
2018-11-21 16:40:31 +03:00
return false ;
2010-08-19 20:30:13 +04:00
}
2018-11-21 16:40:31 +03:00
Preferences : : instance ( ) - > setUILockPassword ( Utils : : Password : : PBKDF2 : : generate ( newPassword ) ) ;
return true ;
2010-08-19 20:30:13 +04:00
}
2014-12-20 20:53:58 +03:00
void MainWindow : : clearUILockPassword ( )
{
2018-11-21 16:40:31 +03:00
const QMessageBox : : StandardButton answer = QMessageBox : : question ( this , tr ( " Clear the password " )
, tr ( " Are you sure you want to clear the password? " ) , ( QMessageBox : : Yes | QMessageBox : : No ) , QMessageBox : : No ) ;
2014-12-20 20:53:58 +03:00
if ( answer = = QMessageBox : : Yes )
2018-11-21 16:40:31 +03:00
Preferences : : instance ( ) - > setUILockPassword ( { } ) ;
2013-10-25 00:23:56 +04:00
}
2016-01-24 13:16:25 +03:00
void MainWindow : : on_actionLock_triggered ( )
2014-12-20 20:53:58 +03:00
{
2017-01-08 03:46:01 +03:00
Preferences * const pref = Preferences : : instance ( ) ;
2018-11-21 16:40:31 +03:00
2014-12-20 20:53:58 +03:00
// Check if there is a password
2020-11-16 10:02:11 +03:00
if ( pref - > getUILockPassword ( ) . isEmpty ( ) )
{
2018-11-21 16:40:31 +03:00
if ( ! defineUILockPassword ( ) )
return ;
2009-08-16 07:09:20 +04:00
}
2018-11-21 16:40:31 +03:00
2014-12-20 20:53:58 +03:00
// Lock the interface
2016-01-24 13:16:25 +03:00
m_uiLocked = true ;
2014-12-20 20:53:58 +03:00
pref - > setUILocked ( true ) ;
2016-01-24 13:16:25 +03:00
m_trayIconMenu - > setEnabled ( false ) ;
2014-12-20 20:53:58 +03:00
hide ( ) ;
2009-11-06 17:30:14 +03:00
}
2017-03-07 16:10:42 +03:00
void MainWindow : : handleRSSUnreadCountUpdated ( int count )
{
m_tabs - > setTabText ( m_tabs - > indexOf ( m_rssWidget ) , tr ( " RSS (%1) " ) . arg ( count ) ) ;
}
2014-12-20 20:53:58 +03:00
void MainWindow : : displayRSSTab ( bool enable )
{
2020-11-16 10:02:11 +03:00
if ( enable )
{
2014-12-20 20:53:58 +03:00
// RSS tab
2020-11-16 10:02:11 +03:00
if ( ! m_rssWidget )
{
2017-03-07 16:10:42 +03:00
m_rssWidget = new RSSWidget ( m_tabs ) ;
connect ( m_rssWidget . data ( ) , & RSSWidget : : unreadCountUpdated , this , & MainWindow : : handleRSSUnreadCountUpdated ) ;
2019-09-05 15:11:33 +03:00
# ifdef Q_OS_MACOS
2018-05-04 19:56:42 +03:00
m_tabs - > addTab ( m_rssWidget , tr ( " RSS (%1) " ) . arg ( RSS : : Session : : instance ( ) - > rootFolder ( ) - > unreadCount ( ) ) ) ;
# else
2018-03-12 09:29:58 +03:00
const int indexTab = m_tabs - > addTab ( m_rssWidget , tr ( " RSS (%1) " ) . arg ( RSS : : Session : : instance ( ) - > rootFolder ( ) - > unreadCount ( ) ) ) ;
2022-03-12 17:00:58 +03:00
m_tabs - > setTabIcon ( indexTab , UIThemeManager : : instance ( ) - > getIcon ( u " application-rss+xml " _qs ) ) ;
2017-06-12 22:47:28 +03:00
# endif
2014-12-20 20:53:58 +03:00
}
2010-06-22 17:58:22 +04:00
}
2020-11-16 10:02:11 +03:00
else
{
2016-01-24 13:16:25 +03:00
delete m_rssWidget ;
2015-01-26 17:00:23 +03:00
}
2014-12-20 20:53:58 +03:00
}
2022-01-21 12:31:31 +03:00
void MainWindow : : showFilterContextMenu ( )
2018-07-29 15:46:19 +03:00
{
const Preferences * pref = Preferences : : instance ( ) ;
QMenu * menu = m_searchFilter - > createStandardContextMenu ( ) ;
2019-06-03 10:10:19 +03:00
menu - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
2018-07-29 15:46:19 +03:00
menu - > addSeparator ( ) ;
2019-06-03 10:10:19 +03:00
2019-06-23 18:27:37 +03:00
QAction * useRegexAct = menu - > addAction ( tr ( " Use regular expressions " ) ) ;
2018-07-29 15:46:19 +03:00
useRegexAct - > setCheckable ( true ) ;
2018-08-12 17:46:16 +03:00
useRegexAct - > setChecked ( pref - > getRegexAsFilteringPatternForTransferList ( ) ) ;
connect ( useRegexAct , & QAction : : toggled , pref , & Preferences : : setRegexAsFilteringPatternForTransferList ) ;
2018-07-29 15:46:19 +03:00
connect ( useRegexAct , & QAction : : toggled , this , [ this ] ( ) { m_transferListWidget - > applyNameFilter ( m_searchFilter - > text ( ) ) ; } ) ;
2019-06-03 10:10:19 +03:00
menu - > popup ( QCursor : : pos ( ) ) ;
2018-07-29 15:46:19 +03:00
}
2014-12-20 20:53:58 +03:00
void MainWindow : : displaySearchTab ( bool enable )
{
Preferences : : instance ( ) - > setSearchEnabled ( enable ) ;
2020-11-16 10:02:11 +03:00
if ( enable )
{
2014-12-20 20:53:58 +03:00
// RSS tab
2020-11-16 10:02:11 +03:00
if ( ! m_searchWidget )
{
2016-01-24 13:16:25 +03:00
m_searchWidget = new SearchWidget ( this ) ;
2017-06-12 22:47:28 +03:00
m_tabs - > insertTab ( 1 , m_searchWidget ,
2019-09-05 15:11:33 +03:00
# ifndef Q_OS_MACOS
2022-03-12 17:00:58 +03:00
UIThemeManager : : instance ( ) - > getIcon ( u " edit-find " _qs ) ,
2017-06-12 22:47:28 +03:00
# endif
tr ( " Search " ) ) ;
2014-12-20 20:53:58 +03:00
}
2010-06-22 17:58:22 +04:00
}
2020-11-16 10:02:11 +03:00
else
{
2016-01-24 13:16:25 +03:00
delete m_searchWidget ;
2015-01-26 17:00:23 +03:00
}
2010-06-22 17:58:22 +04:00
}
2016-11-11 17:32:58 +03:00
void MainWindow : : focusSearchFilter ( )
{
m_searchFilter - > setFocus ( ) ;
m_searchFilter - > selectAll ( ) ;
}
2014-12-20 20:53:58 +03:00
void MainWindow : : updateNbTorrents ( )
{
2016-01-24 13:16:25 +03:00
m_tabs - > setTabText ( 0 , tr ( " Transfers (%1) " ) . arg ( m_transferListWidget - > getSourceModel ( ) - > rowCount ( ) ) ) ;
2010-05-21 18:56:56 +04:00
}
2014-12-20 20:53:58 +03:00
void MainWindow : : on_actionDocumentation_triggered ( ) const
{
2022-03-12 17:00:58 +03:00
QDesktopServices : : openUrl ( QUrl ( u " http://doc.qbittorrent.org " _qs ) ) ;
2009-11-06 17:30:14 +03:00
}
2016-01-24 13:16:25 +03:00
void MainWindow : : tabChanged ( int newTab )
2014-12-20 20:53:58 +03:00
{
2016-01-24 13:16:25 +03:00
Q_UNUSED ( newTab ) ;
// We cannot rely on the index newTab
2014-12-20 20:53:58 +03:00
// because the tab order is undetermined now
2020-11-16 10:02:11 +03:00
if ( m_tabs - > currentWidget ( ) = = m_splitter )
{
2014-12-20 20:53:58 +03:00
qDebug ( " Changed tab to transfer list, refreshing the list " ) ;
2016-01-24 13:16:25 +03:00
m_propertiesWidget - > loadDynamicData ( ) ;
m_searchFilterAction - > setVisible ( true ) ;
2014-12-20 20:53:58 +03:00
return ;
}
2019-02-12 21:05:01 +03:00
m_searchFilterAction - > setVisible ( false ) ;
2020-11-16 10:02:11 +03:00
if ( m_tabs - > currentWidget ( ) = = m_searchWidget )
{
2014-12-20 20:53:58 +03:00
qDebug ( " Changed tab to search engine, giving focus to search input " ) ;
2016-01-24 13:16:25 +03:00
m_searchWidget - > giveFocusToSearchInput ( ) ;
2014-12-20 20:53:58 +03:00
}
2009-11-21 17:16:54 +03:00
}
2014-12-20 20:53:58 +03:00
void MainWindow : : writeSettings ( )
{
2017-01-08 03:46:01 +03:00
Preferences * const pref = Preferences : : instance ( ) ;
2014-12-20 20:53:58 +03:00
pref - > setMainGeometry ( saveGeometry ( ) ) ;
2016-01-24 13:16:25 +03:00
m_propertiesWidget - > saveSettings ( ) ;
2009-11-06 17:30:14 +03:00
}
2022-03-21 07:41:06 +03:00
void MainWindow : : writeSplitterSettings ( )
{
Q_ASSERT ( m_splitter - > widget ( 0 ) = = m_transferListFiltersWidget ) ;
Preferences * const pref = Preferences : : instance ( ) ;
pref - > setFiltersSidebarWidth ( m_splitter - > sizes ( ) [ 0 ] ) ;
}
2015-04-16 00:47:59 +03:00
void MainWindow : : cleanup ( )
{
writeSettings ( ) ;
2017-03-07 16:10:42 +03:00
// delete RSSWidget explicitly to avoid crash in
// handleRSSUnreadCountUpdated() at application shutdown
delete m_rssWidget ;
2016-01-24 13:16:25 +03:00
delete m_executableWatcher ;
2020-04-04 06:55:10 +03:00
m_preventTimer - > stop ( ) ;
2019-09-05 15:11:33 +03:00
# if (defined(Q_OS_WIN) || defined(Q_OS_MACOS))
2021-01-25 10:49:29 +03:00
if ( m_programUpdateTimer )
m_programUpdateTimer - > stop ( ) ;
2015-05-03 01:21:06 +03:00
# endif
2016-03-13 07:51:27 +03:00
// remove all child widgets
2019-02-13 18:12:02 +03:00
while ( auto * w = findChild < QWidget * > ( ) )
2016-03-13 07:51:27 +03:00
delete w ;
2015-04-16 00:47:59 +03:00
}
2014-12-20 20:53:58 +03:00
void MainWindow : : readSettings ( )
{
2017-01-08 03:46:01 +03:00
const Preferences * const pref = Preferences : : instance ( ) ;
2014-12-20 20:53:58 +03:00
const QByteArray mainGeo = pref - > getMainGeometry ( ) ;
2016-01-24 13:16:25 +03:00
if ( ! mainGeo . isEmpty ( ) & & restoreGeometry ( mainGeo ) )
m_posInitialized = true ;
2010-12-04 12:37:13 +03:00
}
2014-12-20 20:53:58 +03:00
void MainWindow : : balloonClicked ( )
{
2020-11-16 10:02:11 +03:00
if ( isHidden ( ) )
{
if ( m_uiLocked )
{
2014-12-20 20:53:58 +03:00
// Ask for UI lock password
if ( ! unlockUI ( ) )
return ;
}
show ( ) ;
if ( isMinimized ( ) )
showNormal ( ) ;
2013-07-22 02:46:10 +04:00
}
2014-06-19 00:22:25 +04:00
2014-12-20 20:53:58 +03:00
raise ( ) ;
activateWindow ( ) ;
2010-12-04 12:37:13 +03:00
}
2015-04-19 18:17:47 +03:00
void MainWindow : : addTorrentFailed ( const QString & error ) const
{
2021-10-09 19:14:18 +03:00
showNotificationBalloon ( tr ( " Error " ) , tr ( " Failed to add torrent: %1 " ) . arg ( error ) ) ;
2015-04-19 18:17:47 +03:00
}
2016-04-17 22:56:51 +03:00
// called when a torrent was added
2021-01-06 15:12:40 +03:00
void MainWindow : : torrentNew ( BitTorrent : : Torrent * const torrent ) const
2016-04-17 22:56:51 +03:00
{
if ( isTorrentAddedNotificationsEnabled ( ) )
2021-10-09 19:14:18 +03:00
showNotificationBalloon ( tr ( " Torrent added " ) , tr ( " '%1' was added. " , " e.g: xxx.avi was added. " ) . arg ( torrent - > name ( ) ) ) ;
2016-04-17 22:56:51 +03:00
}
2009-11-06 17:30:14 +03:00
// called when a torrent has finished
2021-01-06 15:12:40 +03:00
void MainWindow : : finishedTorrent ( BitTorrent : : Torrent * const torrent ) const
2014-12-20 20:53:58 +03:00
{
2021-10-09 19:14:18 +03:00
showNotificationBalloon ( tr ( " Download completed " ) , tr ( " '%1' has finished downloading. " , " e.g: xxx.avi has finished downloading. " ) . arg ( torrent - > name ( ) ) ) ;
2009-11-06 17:30:14 +03:00
}
// Notification when disk is full
2021-01-06 15:12:40 +03:00
void MainWindow : : fullDiskError ( BitTorrent : : Torrent * const torrent , const QString & msg ) const
2014-12-20 20:53:58 +03:00
{
2021-10-09 19:14:18 +03:00
showNotificationBalloon ( tr ( " I/O Error " , " i.e: Input/Output Error " )
2018-03-06 18:49:12 +03:00
, 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 ) ) ;
2014-12-20 20:53:58 +03:00
}
void MainWindow : : createKeyboardShortcuts ( )
{
2016-08-06 06:27:44 +03:00
m_ui - > actionCreateTorrent - > setShortcut ( QKeySequence : : New ) ;
m_ui - > actionOpen - > setShortcut ( QKeySequence : : Open ) ;
2017-10-04 17:43:25 +03:00
m_ui - > actionDelete - > setShortcut ( QKeySequence : : Delete ) ;
2017-10-09 20:31:06 +03:00
m_ui - > actionDelete - > setShortcutContext ( Qt : : WidgetShortcut ) ; // nullify its effect: delete key event is handled by respective widgets, not here
2021-03-19 13:59:59 +03:00
m_ui - > actionDownloadFromURL - > setShortcut ( Qt : : CTRL | Qt : : SHIFT | Qt : : Key_O ) ;
m_ui - > actionExit - > setShortcut ( Qt : : CTRL | Qt : : Key_Q ) ;
2019-09-05 15:11:33 +03:00
# ifdef Q_OS_MACOS
2017-12-12 18:01:55 +03:00
m_ui - > actionCloseWindow - > setShortcut ( QKeySequence : : Close ) ;
# else
m_ui - > actionCloseWindow - > setVisible ( false ) ;
# endif
2015-01-26 17:00:23 +03:00
2021-03-19 13:59:59 +03:00
const auto * switchTransferShortcut = new QShortcut ( ( Qt : : ALT | Qt : : Key_1 ) , this ) ;
2017-07-16 07:10:13 +03:00
connect ( switchTransferShortcut , & QShortcut : : activated , this , & MainWindow : : displayTransferTab ) ;
2021-03-19 13:59:59 +03:00
const auto * switchSearchShortcut = new QShortcut ( ( Qt : : ALT | Qt : : Key_2 ) , this ) ;
2019-07-24 20:41:09 +03:00
connect ( switchSearchShortcut , & QShortcut : : activated , this , qOverload < > ( & MainWindow : : displaySearchTab ) ) ;
2021-03-19 13:59:59 +03:00
const auto * switchRSSShortcut = new QShortcut ( ( Qt : : ALT | Qt : : Key_3 ) , this ) ;
2019-07-24 20:41:09 +03:00
connect ( switchRSSShortcut , & QShortcut : : activated , this , qOverload < > ( & MainWindow : : displayRSSTab ) ) ;
2021-03-19 13:59:59 +03:00
const auto * switchExecutionLogShortcut = new QShortcut ( ( Qt : : ALT | Qt : : Key_4 ) , this ) ;
2017-07-16 07:10:13 +03:00
connect ( switchExecutionLogShortcut , & QShortcut : : activated , this , & MainWindow : : displayExecutionLogTab ) ;
2019-07-24 20:41:09 +03:00
const auto * switchSearchFilterShortcut = new QShortcut ( QKeySequence : : Find , m_transferListWidget ) ;
2017-07-16 07:10:13 +03:00
connect ( switchSearchFilterShortcut , & QShortcut : : activated , this , & MainWindow : : focusSearchFilter ) ;
2016-11-11 17:32:58 +03:00
2016-08-06 06:27:44 +03:00
m_ui - > actionDocumentation - > setShortcut ( QKeySequence : : HelpContents ) ;
2021-03-19 13:59:59 +03:00
m_ui - > actionOptions - > setShortcut ( Qt : : ALT | Qt : : Key_O ) ;
m_ui - > actionStatistics - > setShortcut ( Qt : : CTRL | Qt : : Key_I ) ;
m_ui - > actionStart - > setShortcut ( Qt : : CTRL | Qt : : Key_S ) ;
m_ui - > actionStartAll - > setShortcut ( Qt : : CTRL | Qt : : SHIFT | Qt : : Key_S ) ;
m_ui - > actionPause - > setShortcut ( Qt : : CTRL | Qt : : Key_P ) ;
m_ui - > actionPauseAll - > setShortcut ( Qt : : CTRL | Qt : : SHIFT | Qt : : Key_P ) ;
m_ui - > actionBottomQueuePos - > setShortcut ( Qt : : CTRL | Qt : : SHIFT | Qt : : Key_Minus ) ;
m_ui - > actionDecreaseQueuePos - > setShortcut ( Qt : : CTRL | Qt : : Key_Minus ) ;
m_ui - > actionIncreaseQueuePos - > setShortcut ( Qt : : CTRL | Qt : : Key_Plus ) ;
m_ui - > actionTopQueuePos - > setShortcut ( Qt : : CTRL | Qt : : SHIFT | Qt : : Key_Plus ) ;
2019-09-05 15:11:33 +03:00
# ifdef Q_OS_MACOS
2017-01-25 12:33:13 +03:00
m_ui - > actionMinimize - > setShortcut ( Qt : : CTRL + Qt : : Key_M ) ;
2016-01-24 13:16:25 +03:00
addAction ( m_ui - > actionMinimize ) ;
2012-02-07 21:48:25 +04:00
# endif
2009-11-06 17:30:14 +03:00
}
// Keyboard shortcuts slots
2014-12-20 20:53:58 +03:00
void MainWindow : : displayTransferTab ( ) const
{
2016-01-24 13:16:25 +03:00
m_tabs - > setCurrentWidget ( m_transferListWidget ) ;
2009-11-06 17:30:14 +03:00
}
2017-01-26 22:01:19 +03:00
void MainWindow : : displaySearchTab ( )
2014-12-20 20:53:58 +03:00
{
2020-11-16 10:02:11 +03:00
if ( ! m_searchWidget )
{
2017-01-26 22:01:19 +03:00
m_ui - > actionSearchWidget - > setChecked ( true ) ;
displaySearchTab ( true ) ;
}
m_tabs - > setCurrentWidget ( m_searchWidget ) ;
2009-11-06 17:30:14 +03:00
}
2017-01-26 22:01:19 +03:00
void MainWindow : : displayRSSTab ( )
2014-12-20 20:53:58 +03:00
{
2020-11-16 10:02:11 +03:00
if ( ! m_rssWidget )
{
2017-01-26 22:01:19 +03:00
m_ui - > actionRSSReader - > setChecked ( true ) ;
displayRSSTab ( true ) ;
}
m_tabs - > setCurrentWidget ( m_rssWidget ) ;
2009-11-06 17:30:14 +03:00
}
2017-01-26 22:01:19 +03:00
void MainWindow : : displayExecutionLogTab ( )
2017-01-25 11:54:10 +03:00
{
2020-11-16 10:02:11 +03:00
if ( ! m_executionLog )
{
2017-01-26 22:01:19 +03:00
m_ui - > actionExecutionLogs - > setChecked ( true ) ;
on_actionExecutionLogs_triggered ( true ) ;
}
m_tabs - > setCurrentWidget ( m_executionLog ) ;
2017-01-25 11:54:10 +03:00
}
2009-11-06 17:30:14 +03:00
// End of keyboard shortcuts slots
2021-01-06 15:12:40 +03:00
void MainWindow : : askRecursiveTorrentDownloadConfirmation ( BitTorrent : : Torrent * const torrent )
2014-12-20 20:53:58 +03:00
{
2017-01-08 03:46:01 +03:00
Preferences * const pref = Preferences : : instance ( ) ;
2014-12-20 20:53:58 +03:00
if ( pref - > recursiveDownloadDisabled ( ) ) return ;
2018-06-12 09:53:12 +03:00
2021-03-05 12:43:58 +03:00
const auto torrentID = torrent - > id ( ) ;
2018-06-12 09:53:12 +03:00
QMessageBox * confirmBox = new QMessageBox ( QMessageBox : : Question , tr ( " Recursive download confirmation " )
, tr ( " The torrent '%1' contains torrent files, do you want to proceed with their download? " ) . arg ( torrent - > name ( ) )
, QMessageBox : : NoButton , this ) ;
confirmBox - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
const QPushButton * yes = confirmBox - > addButton ( tr ( " Yes " ) , QMessageBox : : YesRole ) ;
/*QPushButton *no = */ confirmBox - > addButton ( tr ( " No " ) , QMessageBox : : NoRole ) ;
const QPushButton * never = confirmBox - > addButton ( tr ( " Never " ) , QMessageBox : : NoRole ) ;
2021-03-05 12:43:58 +03:00
connect ( confirmBox , & QMessageBox : : buttonClicked , this , [ torrentID , yes , never ] ( const QAbstractButton * button )
2018-06-12 09:53:12 +03:00
{
if ( button = = yes )
2021-03-05 12:43:58 +03:00
BitTorrent : : Session : : instance ( ) - > recursiveTorrentDownload ( torrentID ) ;
2018-06-12 09:53:12 +03:00
if ( button = = never )
Preferences : : instance ( ) - > disableRecursiveDownload ( ) ;
} ) ;
2022-04-05 07:26:17 +03:00
confirmBox - > open ( ) ;
2014-12-20 20:53:58 +03:00
}
2019-02-12 03:45:30 +03:00
void MainWindow : : handleDownloadFromUrlFailure ( const QString & url , const QString & reason ) const
2014-12-20 20:53:58 +03:00
{
// Display a message box
2021-10-09 19:14:18 +03:00
showNotificationBalloon ( tr ( " URL download error " )
2018-03-06 18:49:12 +03:00
, tr ( " Couldn't download file at URL '%1', reason: %2. " ) . arg ( url , reason ) ) ;
2014-12-20 20:53:58 +03:00
}
2019-08-25 21:19:05 +03:00
void MainWindow : : on_actionSetGlobalSpeedLimits_triggered ( )
2014-12-20 20:53:58 +03:00
{
2019-08-25 21:19:05 +03:00
auto dialog = new SpeedLimitDialog { this } ;
dialog - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
dialog - > open ( ) ;
2009-11-06 17:30:14 +03:00
}
// Necessary if we want to close the window
// in one time if "close to systray" is enabled
2014-12-20 20:53:58 +03:00
void MainWindow : : on_actionExit_triggered ( )
{
// UI locking enforcement.
2017-01-08 03:46:01 +03:00
if ( isHidden ( ) & & m_uiLocked )
2014-12-20 20:53:58 +03:00
// Ask for UI lock password
2016-01-24 13:16:25 +03:00
if ( ! unlockUI ( ) ) return ;
2013-01-12 21:18:39 +04:00
2016-01-24 13:16:25 +03:00
m_forceExit = true ;
2014-12-20 20:53:58 +03:00
close ( ) ;
2009-11-06 17:30:14 +03:00
}
2019-09-05 15:11:33 +03:00
# ifdef Q_OS_MACOS
2017-12-12 18:01:55 +03:00
void MainWindow : : on_actionCloseWindow_triggered ( )
{
// On macOS window close is basically equivalent to window hide.
// If you decide to implement this functionality for other OS,
2017-12-27 02:22:03 +03:00
// then you will also need ui lock checks like in actionExit.
2017-12-12 18:01:55 +03:00
close ( ) ;
}
# endif
2017-01-08 03:46:01 +03:00
QWidget * MainWindow : : currentTabWidget ( ) const
2014-12-20 20:53:58 +03:00
{
if ( isMinimized ( ) | | ! isVisible ( ) )
2018-09-07 14:12:38 +03:00
return nullptr ;
2016-01-24 13:16:25 +03:00
if ( m_tabs - > currentIndex ( ) = = 0 )
return m_transferListWidget ;
return m_tabs - > currentWidget ( ) ;
2009-11-06 17:30:14 +03:00
}
2016-01-24 13:16:25 +03:00
TransferListWidget * MainWindow : : transferListWidget ( ) const
2014-12-20 20:53:58 +03:00
{
2016-01-24 13:16:25 +03:00
return m_transferListWidget ;
2009-11-06 17:30:14 +03:00
}
2014-12-20 20:53:58 +03:00
bool MainWindow : : unlockUI ( )
{
2016-01-24 13:16:25 +03:00
if ( m_unlockDlgShowing )
2014-12-20 20:53:58 +03:00
return false ;
bool ok = false ;
2018-11-21 16:40:31 +03:00
const QString password = AutoExpandableDialog : : getText ( this , tr ( " UI lock password " )
, tr ( " Please type the UI lock password: " ) , QLineEdit : : Password , { } , & ok ) ;
2014-12-20 20:53:58 +03:00
if ( ! ok ) return false ;
2016-01-24 13:16:25 +03:00
2017-01-08 03:46:01 +03:00
Preferences * const pref = Preferences : : instance ( ) ;
2018-11-21 16:40:31 +03:00
const QByteArray secret = pref - > getUILockPassword ( ) ;
2020-11-16 10:02:11 +03:00
if ( ! Utils : : Password : : PBKDF2 : : verify ( secret , password ) )
{
2018-11-21 16:40:31 +03:00
QMessageBox : : warning ( this , tr ( " Invalid password " ) , tr ( " The password is invalid " ) ) ;
return false ;
2014-12-20 20:53:58 +03:00
}
2018-11-21 16:40:31 +03:00
m_uiLocked = false ;
pref - > setUILocked ( false ) ;
m_trayIconMenu - > setEnabled ( true ) ;
return true ;
2014-12-20 20:53:58 +03:00
}
2019-02-12 03:45:30 +03:00
void MainWindow : : notifyOfUpdate ( const QString & )
2014-12-20 20:53:58 +03:00
{
// Show restart message
2016-01-24 13:16:25 +03:00
m_statusBar - > showRestartRequired ( ) ;
2017-05-25 17:50:05 +03:00
Logger : : instance ( ) - > addMessage ( tr ( " qBittorrent was just updated and needs to be restarted for the changes to be effective. " )
, Log : : CRITICAL ) ;
2014-12-20 20:53:58 +03:00
// Delete the executable watcher
2016-01-24 13:16:25 +03:00
delete m_executableWatcher ;
2018-04-15 13:06:31 +03:00
m_executableWatcher = nullptr ;
2010-08-23 23:42:15 +04:00
}
2019-09-05 15:11:33 +03:00
# ifndef Q_OS_MACOS
2009-11-06 17:30:14 +03:00
// Toggle Main window visibility
2017-05-02 10:12:24 +03:00
void MainWindow : : toggleVisibility ( const QSystemTrayIcon : : ActivationReason reason )
2014-12-20 20:53:58 +03:00
{
2020-11-16 10:02:11 +03:00
switch ( reason )
{
2018-06-06 16:48:17 +03:00
case QSystemTrayIcon : : Trigger :
2020-11-16 10:02:11 +03:00
if ( isHidden ( ) )
{
2017-05-02 10:12:24 +03:00
if ( m_uiLocked & & ! unlockUI ( ) ) // Ask for UI lock password
return ;
2014-12-20 20:53:58 +03:00
// Make sure the window is not minimized
2016-10-23 14:57:43 +03:00
setWindowState ( ( windowState ( ) & ~ Qt : : WindowMinimized ) | Qt : : WindowActive ) ;
2017-05-02 10:12:24 +03:00
2014-12-20 20:53:58 +03:00
// Then show it
show ( ) ;
raise ( ) ;
activateWindow ( ) ;
}
2020-11-16 10:02:11 +03:00
else
{
2014-12-20 20:53:58 +03:00
hide ( ) ;
}
2017-05-02 10:12:24 +03:00
break ;
default :
break ;
2009-08-16 07:09:20 +04:00
}
2009-11-06 17:30:14 +03:00
}
2019-09-05 15:11:33 +03:00
# endif // Q_OS_MACOS
2009-11-06 17:30:14 +03:00
// Display About Dialog
2014-12-20 20:53:58 +03:00
void MainWindow : : on_actionAbout_triggered ( )
{
2017-01-08 03:46:01 +03:00
// About dialog
2016-01-24 13:16:25 +03:00
if ( m_aboutDlg )
2022-06-02 14:51:26 +03:00
{
2017-05-30 09:00:00 +03:00
m_aboutDlg - > activateWindow ( ) ;
2022-06-02 14:51:26 +03:00
}
2014-12-20 20:53:58 +03:00
else
2022-06-02 14:51:26 +03:00
{
2018-06-06 16:48:17 +03:00
m_aboutDlg = new AboutDialog ( this ) ;
2022-06-02 14:51:26 +03:00
m_aboutDlg - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
m_aboutDlg - > show ( ) ;
}
2009-11-06 17:30:14 +03:00
}
2014-12-20 20:53:58 +03:00
void MainWindow : : on_actionStatistics_triggered ( )
{
2016-01-24 13:16:25 +03:00
if ( m_statsDlg )
2022-06-02 14:51:26 +03:00
{
2017-05-30 09:00:00 +03:00
m_statsDlg - > activateWindow ( ) ;
2022-06-02 14:51:26 +03:00
}
2014-12-20 20:53:58 +03:00
else
2022-06-02 14:51:26 +03:00
{
2016-01-24 13:16:25 +03:00
m_statsDlg = new StatsDialog ( this ) ;
2022-06-02 14:51:26 +03:00
m_statsDlg - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
m_statsDlg - > show ( ) ;
}
2013-11-17 01:16:24 +04:00
}
2014-12-20 20:53:58 +03:00
void MainWindow : : showEvent ( QShowEvent * e )
{
qDebug ( " ** Show Event ** " ) ;
2021-05-31 07:19:22 +03:00
e - > accept ( ) ;
2011-01-21 21:38:58 +03:00
2021-05-31 07:19:22 +03:00
if ( isVisible ( ) )
{
// preparations before showing the window
2011-01-22 22:51:06 +03:00
2021-05-31 07:19:22 +03:00
if ( currentTabWidget ( ) = = m_transferListWidget )
m_propertiesWidget - > loadDynamicData ( ) ;
2011-01-22 22:51:06 +03:00
2021-05-31 07:19:22 +03:00
// Make sure the window is initially centered
if ( ! m_posInitialized )
{
move ( Utils : : Gui : : screenCenter ( this ) ) ;
m_posInitialized = true ;
}
}
else
2020-11-16 10:02:11 +03:00
{
2021-05-31 07:19:22 +03:00
// to avoid blank screen when restoring from tray icon
show ( ) ;
2014-12-20 20:53:58 +03:00
}
2009-11-06 17:30:14 +03:00
}
2020-10-30 20:49:15 +03:00
void MainWindow : : keyPressEvent ( QKeyEvent * event )
{
2020-11-16 10:02:11 +03:00
if ( event - > matches ( QKeySequence : : Paste ) )
{
2020-10-30 20:49:15 +03:00
const QMimeData * mimeData { QGuiApplication : : clipboard ( ) - > mimeData ( ) } ;
2020-11-16 10:02:11 +03:00
if ( mimeData - > hasText ( ) )
{
2020-10-30 20:49:15 +03:00
const bool useTorrentAdditionDialog { AddNewTorrentDialog : : isEnabled ( ) } ;
2022-03-12 17:00:58 +03:00
const QStringList lines { mimeData - > text ( ) . split ( u ' \n ' , Qt : : SkipEmptyParts ) } ;
2020-10-30 20:49:15 +03:00
2020-11-16 10:02:11 +03:00
for ( QString line : lines )
{
2020-10-30 20:49:15 +03:00
line = line . trimmed ( ) ;
if ( ! isTorrentLink ( line ) )
continue ;
if ( useTorrentAdditionDialog )
AddNewTorrentDialog : : show ( line , this ) ;
else
BitTorrent : : Session : : instance ( ) - > addTorrent ( line ) ;
}
return ;
}
}
QMainWindow : : keyPressEvent ( event ) ;
}
2009-11-06 17:30:14 +03:00
// Called when we close the program
2014-12-20 20:53:58 +03:00
void MainWindow : : closeEvent ( QCloseEvent * e )
{
2017-01-08 03:46:01 +03:00
Preferences * const pref = Preferences : : instance ( ) ;
2019-09-05 15:11:33 +03:00
# ifdef Q_OS_MACOS
2020-11-16 10:02:11 +03:00
if ( ! m_forceExit )
{
2017-06-12 22:47:28 +03:00
hide ( ) ;
e - > accept ( ) ;
return ;
}
# else
2014-12-20 20:53:58 +03:00
const bool goToSystrayOnExit = pref - > closeToTray ( ) ;
2020-11-16 10:02:11 +03:00
if ( ! m_forceExit & & m_systrayIcon & & goToSystrayOnExit & & ! this - > isHidden ( ) )
{
2019-05-07 02:08:46 +03:00
e - > ignore ( ) ;
2022-04-12 11:19:09 +03:00
QMetaObject : : invokeMethod ( this , & QWidget : : hide , Qt : : QueuedConnection ) ;
2020-11-16 10:02:11 +03:00
if ( ! pref - > closeToTrayNotified ( ) )
{
2021-10-09 19:14:18 +03:00
showNotificationBalloon ( tr ( " qBittorrent is closed to tray " ) , tr ( " This behavior can be changed in the settings. You won't be reminded again. " ) ) ;
2018-08-03 14:55:20 +03:00
pref - > setCloseToTrayNotified ( true ) ;
}
2009-11-06 17:30:14 +03:00
return ;
2007-11-16 21:53:21 +03:00
}
2019-09-05 15:11:33 +03:00
# endif // Q_OS_MACOS
2015-04-21 12:58:21 +03:00
2020-11-16 10:02:11 +03:00
if ( pref - > confirmOnExit ( ) & & BitTorrent : : Session : : instance ( ) - > hasActiveTorrents ( ) )
{
if ( e - > spontaneous ( ) | | m_forceExit )
{
2014-12-20 20:53:58 +03:00
if ( ! isVisible ( ) )
show ( ) ;
QMessageBox confirmBox ( QMessageBox : : Question , tr ( " Exiting qBittorrent " ) ,
2017-05-01 01:45:02 +03:00
// Split it because the last sentence is used in the Web UI
2022-03-12 17:00:58 +03:00
tr ( " Some files are currently transferring. " ) + u ' \n ' + tr ( " Are you sure you want to quit qBittorrent? " ) ,
2014-12-20 20:53:58 +03:00
QMessageBox : : NoButton , this ) ;
2015-05-26 08:25:12 +03:00
QPushButton * noBtn = confirmBox . addButton ( tr ( " &No " ) , QMessageBox : : NoRole ) ;
2015-07-20 00:13:18 +03:00
confirmBox . addButton ( tr ( " &Yes " ) , QMessageBox : : YesRole ) ;
2015-05-26 08:25:12 +03:00
QPushButton * alwaysBtn = confirmBox . addButton ( tr ( " &Always Yes " ) , QMessageBox : : YesRole ) ;
confirmBox . setDefaultButton ( noBtn ) ;
2014-12-20 20:53:58 +03:00
confirmBox . exec ( ) ;
2020-11-16 10:02:11 +03:00
if ( ! confirmBox . clickedButton ( ) | | ( confirmBox . clickedButton ( ) = = noBtn ) )
{
2014-12-20 20:53:58 +03:00
// Cancel exit
e - > ignore ( ) ;
2016-01-24 13:16:25 +03:00
m_forceExit = false ;
2014-12-20 20:53:58 +03:00
return ;
}
2017-01-08 03:46:01 +03:00
if ( confirmBox . clickedButton ( ) = = alwaysBtn )
2014-12-20 20:53:58 +03:00
// Remember choice
Preferences : : instance ( ) - > setConfirmOnExit ( false ) ;
}
}
2015-04-21 12:58:21 +03:00
2021-12-13 10:55:33 +03:00
// Disable some UI to prevent user interactions
2019-09-05 15:11:33 +03:00
# ifndef Q_OS_MACOS
2016-01-24 13:16:25 +03:00
if ( m_systrayIcon )
2021-12-13 10:55:33 +03:00
{
2022-01-31 06:54:44 +03:00
m_systrayIcon - > disconnect ( ) ;
2021-12-13 10:55:33 +03:00
m_systrayIcon - > setToolTip ( tr ( " qBittorrent is shutting down... " ) ) ;
m_trayIconMenu - > setEnabled ( false ) ;
}
2017-06-12 22:47:28 +03:00
# endif
2021-12-01 07:37:32 +03:00
2014-12-20 20:53:58 +03:00
// Accept exit
e - > accept ( ) ;
qApp - > exit ( ) ;
2009-11-06 17:30:14 +03:00
}
// Display window to create a torrent
2016-01-24 13:16:25 +03:00
void MainWindow : : on_actionCreateTorrent_triggered ( )
2016-04-28 14:06:02 +03:00
{
2022-02-08 06:03:48 +03:00
createTorrentTriggered ( { } ) ;
2016-04-28 14:06:02 +03:00
}
2022-02-08 06:03:48 +03:00
void MainWindow : : createTorrentTriggered ( const Path & path )
2014-12-20 20:53:58 +03:00
{
2020-11-16 10:02:11 +03:00
if ( m_createTorrentDlg )
{
2016-04-30 13:43:41 +03:00
m_createTorrentDlg - > updateInputPath ( path ) ;
2017-05-30 09:00:00 +03:00
m_createTorrentDlg - > activateWindow ( ) ;
2016-04-30 13:43:41 +03:00
}
2015-04-19 18:17:47 +03:00
else
2022-02-08 06:03:48 +03:00
{
2018-06-14 12:54:23 +03:00
m_createTorrentDlg = new TorrentCreatorDialog ( this , path ) ;
2022-06-02 14:51:26 +03:00
m_createTorrentDlg - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
m_createTorrentDlg - > show ( ) ;
2022-02-08 06:03:48 +03:00
}
2014-12-20 20:53:58 +03:00
}
2016-01-24 13:16:25 +03:00
bool MainWindow : : event ( QEvent * e )
2014-12-20 20:53:58 +03:00
{
2019-09-05 15:11:33 +03:00
# ifndef Q_OS_MACOS
2020-11-16 10:02:11 +03:00
switch ( e - > type ( ) )
{
case QEvent : : WindowStateChange :
{
2014-12-20 20:53:58 +03:00
qDebug ( " Window change event " ) ;
2017-01-08 03:46:01 +03:00
// Now check to see if the window is minimised
2020-11-16 10:02:11 +03:00
if ( isMinimized ( ) )
{
2014-12-20 20:53:58 +03:00
qDebug ( " minimisation " ) ;
2018-08-03 14:55:20 +03:00
Preferences * const pref = Preferences : : instance ( ) ;
2020-11-16 10:02:11 +03:00
if ( m_systrayIcon & & pref - > minimizeToTray ( ) )
{
2017-05-29 15:10:31 +03:00
qDebug ( ) < < " Has active window: " < < ( qApp - > activeWindow ( ) ! = nullptr ) ;
2014-12-20 20:53:58 +03:00
// Check if there is a modal window
2022-01-19 19:35:12 +03:00
const QWidgetList allWidgets = QApplication : : allWidgets ( ) ;
const bool hasModalWindow = std : : any_of ( allWidgets . cbegin ( ) , allWidgets . cend ( )
, [ ] ( const QWidget * widget ) { return widget - > isModal ( ) ; } ) ;
2014-12-20 20:53:58 +03:00
// Iconify if there is no modal window
2020-11-16 10:02:11 +03:00
if ( ! hasModalWindow )
{
2014-12-20 20:53:58 +03:00
qDebug ( " Minimize to Tray enabled, hiding! " ) ;
e - > ignore ( ) ;
2022-04-12 11:19:09 +03:00
QMetaObject : : invokeMethod ( this , & QWidget : : hide , Qt : : QueuedConnection ) ;
2020-11-16 10:02:11 +03:00
if ( ! pref - > minimizeToTrayNotified ( ) )
{
2021-10-09 19:14:18 +03:00
showNotificationBalloon ( tr ( " qBittorrent is minimized to tray " ) , tr ( " This behavior can be changed in the settings. You won't be reminded again. " ) ) ;
2018-08-03 14:55:20 +03:00
pref - > setMinimizeToTrayNotified ( true ) ;
}
2014-12-20 20:53:58 +03:00
return true ;
}
}
2010-10-24 01:46:05 +04:00
}
2014-12-20 20:53:58 +03:00
break ;
2006-09-30 20:02:39 +04:00
}
2020-11-16 10:02:11 +03:00
case QEvent : : ToolBarChange :
{
2014-12-20 20:53:58 +03:00
qDebug ( " MAC: Received a toolbar change event! " ) ;
bool ret = QMainWindow : : event ( e ) ;
2016-01-24 13:16:25 +03:00
qDebug ( " MAC: new toolbar visibility is %d " , ! m_ui - > actionTopToolBar - > isChecked ( ) ) ;
m_ui - > actionTopToolBar - > toggle ( ) ;
Preferences : : instance ( ) - > setToolbarDisplayed ( m_ui - > actionTopToolBar - > isChecked ( ) ) ;
2014-12-20 20:53:58 +03:00
return ret ;
}
default :
break ;
}
2019-09-05 15:11:33 +03:00
# endif // Q_OS_MACOS
2016-01-24 13:16:25 +03:00
2014-12-20 20:53:58 +03:00
return QMainWindow : : event ( e ) ;
2009-11-06 17:30:14 +03:00
}
2016-01-24 13:16:25 +03:00
// action executed when a file is dropped
2014-12-20 20:53:58 +03:00
void MainWindow : : dropEvent ( QDropEvent * event )
{
event - > acceptProposedAction ( ) ;
2016-04-28 14:06:02 +03:00
// remove scheme
2014-12-20 20:53:58 +03:00
QStringList files ;
2020-11-16 10:02:11 +03:00
if ( event - > mimeData ( ) - > hasUrls ( ) )
{
for ( const QUrl & url : asConst ( event - > mimeData ( ) - > urls ( ) ) )
{
2017-11-27 11:40:06 +03:00
if ( url . isEmpty ( ) )
continue ;
2022-03-12 17:00:58 +03:00
files < < ( ( url . scheme ( ) . compare ( u " file " , Qt : : CaseInsensitive ) = = 0 )
2017-11-27 11:40:06 +03:00
? url . toLocalFile ( )
: url . toString ( ) ) ;
2014-12-20 20:53:58 +03:00
}
2009-11-06 17:30:14 +03:00
}
2020-11-16 10:02:11 +03:00
else
{
2022-03-12 17:00:58 +03:00
files = event - > mimeData ( ) - > text ( ) . split ( u ' \n ' ) ;
2010-07-23 02:19:42 +04:00
}
2015-04-19 18:17:47 +03:00
2017-11-27 11:40:06 +03:00
// differentiate ".torrent" files/links & magnet links from others
2016-04-28 14:06:02 +03:00
QStringList torrentFiles , otherFiles ;
2020-11-16 10:02:11 +03:00
for ( const QString & file : asConst ( files ) )
{
2020-10-30 20:49:15 +03:00
if ( isTorrentLink ( file ) )
2016-04-28 14:06:02 +03:00
torrentFiles < < file ;
else
otherFiles < < file ;
}
// Download torrents
2016-02-09 11:56:48 +03:00
const bool useTorrentAdditionDialog = AddNewTorrentDialog : : isEnabled ( ) ;
2020-11-16 10:02:11 +03:00
for ( const QString & file : asConst ( torrentFiles ) )
{
2015-04-19 18:17:47 +03:00
if ( useTorrentAdditionDialog )
AddNewTorrentDialog : : show ( file , this ) ;
else
BitTorrent : : Session : : instance ( ) - > addTorrent ( file ) ;
2008-08-02 00:03:16 +04:00
}
2016-04-28 14:06:02 +03:00
if ( ! torrentFiles . isEmpty ( ) ) return ;
// Create torrent
2020-11-16 10:02:11 +03:00
for ( const QString & file : asConst ( otherFiles ) )
{
2022-02-08 06:03:48 +03:00
createTorrentTriggered ( Path ( file ) ) ;
2016-04-28 14:06:02 +03:00
2020-10-20 13:44:04 +03:00
// currently only handle the first entry
2016-04-28 14:06:02 +03:00
// this is a stub that can be expanded later to create many torrents at once
break ;
}
2009-11-06 17:30:14 +03:00
}
// Decode if we accept drag 'n drop or not
2014-12-20 20:53:58 +03:00
void MainWindow : : dragEnterEvent ( QDragEnterEvent * event )
{
2018-11-27 23:15:04 +03:00
for ( const QString & mime : asConst ( event - > mimeData ( ) - > formats ( ) ) )
2014-12-20 20:53:58 +03:00
qDebug ( " mimeData: %s " , mime . toLocal8Bit ( ) . data ( ) ) ;
2022-03-12 17:00:58 +03:00
if ( event - > mimeData ( ) - > hasFormat ( u " text/plain " _qs ) | | event - > mimeData ( ) - > hasFormat ( u " text/uri-list " _qs ) )
2014-12-20 20:53:58 +03:00
event - > acceptProposedAction ( ) ;
2009-11-06 17:30:14 +03:00
}
2019-09-05 15:11:33 +03:00
# ifdef Q_OS_MACOS
2017-06-12 22:47:28 +03:00
void MainWindow : : setupDockClickHandler ( )
2017-08-20 18:00:23 +03:00
{
2017-06-12 22:47:28 +03:00
dockMainWindowHandle = this ;
2017-12-12 20:20:48 +03:00
MacUtils : : overrideDockClickHandler ( dockClickHandler ) ;
2017-06-12 22:47:28 +03:00
}
2019-09-05 15:11:33 +03:00
# endif // Q_OS_MACOS
2017-06-12 22:47:28 +03:00
2009-11-06 17:30:14 +03:00
/*****************************************************
2014-12-20 20:53:58 +03:00
* *
* Torrent *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-11-06 17:30:14 +03:00
// Display a dialog to allow user to add
// torrents to download list
2014-12-20 20:53:58 +03:00
void MainWindow : : on_actionOpen_triggered ( )
{
2017-01-08 03:46:01 +03:00
Preferences * const pref = Preferences : : instance ( ) ;
2014-12-20 20:53:58 +03:00
// Open File Open Dialog
// Note: it is possible to select more than one file
2015-04-19 18:17:47 +03:00
const QStringList pathsList =
2022-02-08 06:03:48 +03:00
QFileDialog : : getOpenFileNames ( this , tr ( " Open Torrent Files " ) , pref - > getMainLastDir ( ) . data ( ) ,
2022-03-04 08:25:22 +03:00
tr ( " Torrent Files " ) + u " (* " + TORRENT_FILE_EXTENSION + u ' ) ' ) ;
2015-10-26 10:45:14 +03:00
2019-08-06 18:07:57 +03:00
if ( pathsList . isEmpty ( ) )
return ;
2016-02-09 11:56:48 +03:00
const bool useTorrentAdditionDialog = AddNewTorrentDialog : : isEnabled ( ) ;
2015-04-19 18:17:47 +03:00
2020-11-16 10:02:11 +03:00
for ( const QString & file : pathsList )
{
2019-08-06 18:07:57 +03:00
if ( useTorrentAdditionDialog )
AddNewTorrentDialog : : show ( file , this ) ;
else
BitTorrent : : Session : : instance ( ) - > addTorrent ( file ) ;
2015-06-16 09:08:25 +03:00
}
2019-08-06 18:07:57 +03:00
// Save last dir to remember it
2022-02-08 06:03:48 +03:00
const Path topDir { pathsList . at ( 0 ) } ;
const Path parentDir = topDir . parentPath ( ) ;
pref - > setMainLastDir ( parentDir . isEmpty ( ) ? topDir : parentDir ) ;
2009-11-06 17:30:14 +03:00
}
2015-01-22 15:56:16 +03:00
void MainWindow : : activate ( )
2014-12-20 20:53:58 +03:00
{
2020-11-16 10:02:11 +03:00
if ( ! m_uiLocked | | unlockUI ( ) )
{
2015-01-22 15:56:16 +03:00
show ( ) ;
activateWindow ( ) ;
raise ( ) ;
2006-09-30 20:02:39 +04:00
}
2009-11-06 17:30:14 +03:00
}
2014-12-20 20:53:58 +03:00
void MainWindow : : optionsSaved ( )
{
2021-09-12 11:45:00 +03:00
Logger : : instance ( ) - > addMessage ( tr ( " Options saved. " ) ) ;
2014-12-20 20:53:58 +03:00
loadPreferences ( ) ;
2009-11-15 13:00:07 +03:00
}
2017-05-25 17:50:05 +03:00
void MainWindow : : showStatusBar ( bool show )
{
2020-11-16 10:02:11 +03:00
if ( ! show )
{
2017-05-28 20:59:52 +03:00
// Remove status bar
setStatusBar ( nullptr ) ;
}
2020-11-16 10:02:11 +03:00
else if ( ! m_statusBar )
{
2017-05-25 17:50:05 +03:00
// Create status bar
m_statusBar = new StatusBar ;
connect ( m_statusBar . data ( ) , & StatusBar : : connectionButtonClicked , this , & MainWindow : : showConnectionSettings ) ;
connect ( m_statusBar . data ( ) , & StatusBar : : alternativeSpeedsButtonClicked , this , & MainWindow : : toggleAlternativeSpeeds ) ;
setStatusBar ( m_statusBar ) ;
}
}
2022-03-21 07:41:06 +03:00
void MainWindow : : showFiltersSidebar ( const bool show )
{
Preferences * const pref = Preferences : : instance ( ) ;
if ( show & & ! m_transferListFiltersWidget )
{
const int width = pref - > getFiltersSidebarWidth ( ) ;
m_transferListFiltersWidget = new TransferListFiltersWidget ( m_splitter , m_transferListWidget , isDownloadTrackerFavicon ( ) ) ;
m_splitter - > insertWidget ( 0 , m_transferListFiltersWidget ) ;
m_splitter - > setCollapsible ( 0 , true ) ;
m_splitter - > setSizes ( { width , ( m_splitter - > width ( ) - width ) } ) ;
connect ( BitTorrent : : Session : : instance ( ) , & BitTorrent : : Session : : trackersAdded , m_transferListFiltersWidget , & TransferListFiltersWidget : : addTrackers ) ;
connect ( BitTorrent : : Session : : instance ( ) , & BitTorrent : : Session : : trackersRemoved , m_transferListFiltersWidget , & TransferListFiltersWidget : : removeTrackers ) ;
2022-05-22 09:09:11 +03:00
connect ( BitTorrent : : Session : : instance ( ) , & BitTorrent : : Session : : trackersChanged , m_transferListFiltersWidget , & TransferListFiltersWidget : : refreshTrackers ) ;
2022-03-21 07:41:06 +03:00
connect ( BitTorrent : : Session : : instance ( ) , & BitTorrent : : Session : : trackerlessStateChanged , m_transferListFiltersWidget , & TransferListFiltersWidget : : changeTrackerless ) ;
connect ( BitTorrent : : Session : : instance ( ) , & BitTorrent : : Session : : trackerEntriesUpdated , m_transferListFiltersWidget , & TransferListFiltersWidget : : trackerEntriesUpdated ) ;
}
else if ( ! show & & m_transferListFiltersWidget )
{
Q_ASSERT ( m_splitter - > widget ( 0 ) = = m_transferListFiltersWidget ) ;
pref - > setFiltersSidebarWidth ( m_splitter - > sizes ( ) [ 0 ] ) ;
delete m_transferListFiltersWidget ;
m_transferListFiltersWidget = nullptr ;
}
}
2021-12-13 10:56:20 +03:00
void MainWindow : : loadPreferences ( )
2014-12-20 20:53:58 +03:00
{
2021-12-13 10:56:20 +03:00
const Preferences * pref = Preferences : : instance ( ) ;
# ifndef Q_OS_MACOS
// system tray icon
2021-12-14 09:38:31 +03:00
if ( pref - > systemTrayEnabled ( ) )
2020-11-16 10:02:11 +03:00
{
2021-12-13 10:56:20 +03:00
if ( m_systrayIcon )
2020-11-16 10:02:11 +03:00
{
2021-12-13 10:56:20 +03:00
// Reload systray icon
m_systrayIcon - > setIcon ( UIThemeManager : : instance ( ) - > getSystrayIcon ( ) ) ;
2014-12-20 20:53:58 +03:00
}
2020-11-16 10:02:11 +03:00
else
{
2021-12-13 10:56:20 +03:00
createTrayIcon ( 20 ) ;
2009-11-18 21:45:06 +03:00
}
2009-11-14 22:08:28 +03:00
}
2021-12-13 10:56:20 +03:00
else
{
delete m_systrayIcon ;
delete m_trayIconMenu ;
2021-12-14 09:38:31 +03:00
m_ui - > actionLock - > setVisible ( false ) ;
2021-12-13 10:56:20 +03:00
}
2017-06-12 22:47:28 +03:00
# endif
2021-12-13 10:56:20 +03:00
2014-12-20 20:53:58 +03:00
// General
2020-11-16 10:02:11 +03:00
if ( pref - > isToolbarDisplayed ( ) )
{
2016-01-24 13:16:25 +03:00
m_ui - > toolBar - > setVisible ( true ) ;
2014-12-20 20:53:58 +03:00
}
2020-11-16 10:02:11 +03:00
else
{
2014-12-20 20:53:58 +03:00
// Clear search filter before hiding the top toolbar
2016-01-24 13:16:25 +03:00
m_searchFilter - > clear ( ) ;
m_ui - > toolBar - > setVisible ( false ) ;
2014-12-20 20:53:58 +03:00
}
2017-05-25 17:50:05 +03:00
showStatusBar ( pref - > isStatusbarDisplayed ( ) ) ;
2015-10-30 16:03:44 +03:00
2020-11-16 10:02:11 +03:00
if ( pref - > preventFromSuspendWhenDownloading ( ) | | pref - > preventFromSuspendWhenSeeding ( ) )
{
if ( ! m_preventTimer - > isActive ( ) )
{
2020-04-04 06:59:25 +03:00
updatePowerManagementState ( ) ;
m_preventTimer - > start ( PREVENT_SUSPEND_INTERVAL ) ;
}
2014-12-20 20:53:58 +03:00
}
2020-11-16 10:02:11 +03:00
else
{
2016-01-24 13:16:25 +03:00
m_preventTimer - > stop ( ) ;
2014-12-20 20:53:58 +03:00
m_pwr - > setActivityState ( false ) ;
}
2016-01-24 13:16:25 +03:00
m_transferListWidget - > setAlternatingRowColors ( pref - > useAlternatingRowColors ( ) ) ;
m_propertiesWidget - > getFilesList ( ) - > setAlternatingRowColors ( pref - > useAlternatingRowColors ( ) ) ;
m_propertiesWidget - > getTrackerList ( ) - > setAlternatingRowColors ( pref - > useAlternatingRowColors ( ) ) ;
m_propertiesWidget - > getPeerList ( ) - > setAlternatingRowColors ( pref - > useAlternatingRowColors ( ) ) ;
2014-12-20 20:53:58 +03:00
// Queueing System
2020-11-16 10:02:11 +03:00
if ( BitTorrent : : Session : : instance ( ) - > isQueueingSystemEnabled ( ) )
{
if ( ! m_ui - > actionDecreaseQueuePos - > isVisible ( ) )
{
2018-12-08 02:01:09 +03:00
m_transferListWidget - > hideQueuePosColumn ( false ) ;
m_ui - > actionDecreaseQueuePos - > setVisible ( true ) ;
m_ui - > actionIncreaseQueuePos - > setVisible ( true ) ;
m_ui - > actionTopQueuePos - > setVisible ( true ) ;
m_ui - > actionBottomQueuePos - > setVisible ( true ) ;
2019-09-05 15:11:33 +03:00
# ifndef Q_OS_MACOS
2018-12-08 02:01:09 +03:00
m_queueSeparator - > setVisible ( true ) ;
2017-06-12 22:47:28 +03:00
# endif
2018-12-08 02:01:09 +03:00
m_queueSeparatorMenu - > setVisible ( true ) ;
2014-12-20 20:53:58 +03:00
}
2009-08-16 07:09:20 +04:00
}
2020-11-16 10:02:11 +03:00
else
{
if ( m_ui - > actionDecreaseQueuePos - > isVisible ( ) )
{
2018-12-08 02:01:09 +03:00
m_transferListWidget - > hideQueuePosColumn ( true ) ;
m_ui - > actionDecreaseQueuePos - > setVisible ( false ) ;
m_ui - > actionIncreaseQueuePos - > setVisible ( false ) ;
m_ui - > actionTopQueuePos - > setVisible ( false ) ;
m_ui - > actionBottomQueuePos - > setVisible ( false ) ;
2019-09-05 15:11:33 +03:00
# ifndef Q_OS_MACOS
2018-12-08 02:01:09 +03:00
m_queueSeparator - > setVisible ( false ) ;
2017-06-12 22:47:28 +03:00
# endif
2018-12-08 02:01:09 +03:00
m_queueSeparatorMenu - > setVisible ( false ) ;
2014-12-20 20:53:58 +03:00
}
2009-08-16 07:09:20 +04:00
}
2009-11-14 22:08:28 +03:00
2014-12-20 20:53:58 +03:00
// Torrent properties
2016-01-24 13:16:25 +03:00
m_propertiesWidget - > reloadPreferences ( ) ;
2009-11-15 13:00:07 +03:00
2019-09-05 15:11:33 +03:00
# if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
2021-01-25 10:49:29 +03:00
if ( pref - > isUpdateCheckEnabled ( ) )
2020-11-16 10:02:11 +03:00
{
2021-01-25 10:49:29 +03:00
if ( ! m_programUpdateTimer )
{
m_programUpdateTimer = new QTimer ( this ) ;
2021-01-25 10:49:41 +03:00
m_programUpdateTimer - > setInterval ( 24 h ) ;
2021-01-25 10:49:29 +03:00
m_programUpdateTimer - > setSingleShot ( true ) ;
connect ( m_programUpdateTimer , & QTimer : : timeout , this , [ this ] ( ) { checkProgramUpdate ( false ) ; } ) ;
m_programUpdateTimer - > start ( ) ;
}
2015-12-13 17:41:58 +03:00
}
2021-01-25 10:49:29 +03:00
else
2020-11-16 10:02:11 +03:00
{
2021-01-25 10:49:29 +03:00
delete m_programUpdateTimer ;
m_programUpdateTimer = nullptr ;
2015-12-13 17:41:58 +03:00
}
2013-11-23 16:58:03 +04:00
# endif
2014-12-20 20:53:58 +03:00
qDebug ( " GUI settings loaded " ) ;
2009-11-06 17:30:14 +03:00
}
2019-09-24 06:29:07 +03:00
void MainWindow : : reloadSessionStats ( )
2014-12-20 20:53:58 +03:00
{
2017-04-29 14:45:30 +03:00
const BitTorrent : : SessionStatus & status = BitTorrent : : Session : : instance ( ) - > status ( ) ;
2015-04-19 18:17:47 +03:00
2018-03-14 18:15:51 +03:00
// update global information
2019-09-24 06:29:07 +03:00
# ifdef Q_OS_MACOS
2020-11-16 10:02:11 +03:00
if ( status . payloadDownloadRate > 0 )
{
2021-04-12 13:15:30 +03:00
MacUtils : : setBadgeLabelText ( tr ( " %1/s " , " s is a shorthand for seconds " )
2019-09-24 06:29:07 +03:00
. arg ( Utils : : Misc : : friendlyUnit ( status . payloadDownloadRate ) ) ) ;
}
2021-04-12 13:15:30 +03:00
else if ( ! MacUtils : : badgeLabelText ( ) . isEmpty ( ) )
2020-11-16 10:02:11 +03:00
{
2022-03-19 10:57:41 +03:00
MacUtils : : setBadgeLabelText ( { } ) ;
2019-09-24 06:29:07 +03:00
}
# else
2020-11-16 10:02:11 +03:00
if ( m_systrayIcon )
{
2022-03-29 05:41:17 +03:00
const auto toolTip = u " %1 \n %2 " _qs . arg (
2019-05-27 11:19:24 +03:00
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 ) ) ) ;
2019-09-24 06:29:07 +03:00
m_systrayIcon - > setToolTip ( toolTip ) ; // tray icon
2016-01-24 13:16:25 +03:00
}
2019-09-24 06:29:07 +03:00
# endif // Q_OS_MACOS
2016-01-24 13:16:25 +03:00
2020-11-16 10:02:11 +03:00
if ( m_displaySpeedInTitle )
{
2016-01-24 13:16:25 +03:00
setWindowTitle ( tr ( " [D: %1, U: %2] qBittorrent %3 " , " D = Download; U = Upload; %3 is qBittorrent version " )
2018-03-06 18:49:12 +03:00
. arg ( Utils : : Misc : : friendlyUnit ( status . payloadDownloadRate , true )
, Utils : : Misc : : friendlyUnit ( status . payloadUploadRate , true )
2022-03-12 17:00:58 +03:00
, QStringLiteral ( QBT_VERSION ) ) ) ;
2014-12-20 20:53:58 +03:00
}
2009-11-06 17:30:14 +03:00
}
2021-01-06 15:12:40 +03:00
void MainWindow : : reloadTorrentStats ( const QVector < BitTorrent : : Torrent * > & torrents )
2019-09-24 06:29:07 +03:00
{
2020-11-16 10:02:11 +03:00
if ( currentTabWidget ( ) = = m_transferListWidget )
{
2019-09-24 06:29:07 +03:00
if ( torrents . contains ( m_propertiesWidget - > getCurrentTorrent ( ) ) )
m_propertiesWidget - > loadDynamicData ( ) ;
}
}
2021-10-09 19:14:18 +03:00
void MainWindow : : showNotificationBalloon ( const QString & title , const QString & msg ) const
2014-12-20 20:53:58 +03:00
{
2021-04-10 10:58:14 +03:00
if ( ! isNotificationsEnabled ( ) )
return ;
2019-09-05 15:11:33 +03:00
# if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)) && defined(QT_DBUS_LIB)
2022-03-29 05:41:17 +03:00
OrgFreedesktopNotificationsInterface notifications ( u " org.freedesktop.Notifications " _qs
, u " /org/freedesktop/Notifications " _qs
2021-04-10 10:58:14 +03:00
, QDBusConnection : : sessionBus ( ) ) ;
2014-12-20 20:53:58 +03:00
// Testing for 'notifications.isValid()' isn't helpful here.
// If the notification daemon is configured to run 'as needed'
// the above check can be false if the daemon wasn't started
// by another application. In this case DBus will be able to
// start the notification daemon and complete our request. Such
// a daemon is xfce4-notifyd, DBus autostarts it and after
// some inactivity shuts it down. Other DEs, like GNOME, choose
// to start their daemons at the session startup and have it sit
// idling for the whole session.
2022-03-29 05:41:17 +03:00
const QVariantMap hints { { u " desktop-entry " _qs , u " org.qbittorrent.qBittorrent " _qs } } ;
QDBusPendingReply < uint > reply = notifications . Notify ( u " qBittorrent " _qs , 0
, u " qbittorrent " _qs , title , msg , { } , hints , getNotificationTimeout ( ) ) ;
2021-04-10 10:58:14 +03:00
2014-12-20 20:53:58 +03:00
reply . waitForFinished ( ) ;
if ( ! reply . isError ( ) )
return ;
2019-09-05 15:11:33 +03:00
# elif defined(Q_OS_MACOS)
2017-12-12 20:20:48 +03:00
MacUtils : : displayNotification ( title , msg ) ;
2017-08-15 21:16:37 +03:00
# else
2016-01-24 13:16:25 +03:00
if ( m_systrayIcon & & QSystemTrayIcon : : supportsMessages ( ) )
m_systrayIcon - > showMessage ( title , msg , QSystemTrayIcon : : Information , TIME_TRAY_BALLOON ) ;
2017-06-12 22:47:28 +03:00
# endif
2009-11-07 22:55:33 +03:00
}
2009-11-06 17:30:14 +03:00
/*****************************************************
2014-12-20 20:53:58 +03:00
* *
* Utils *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2017-01-08 03:46:01 +03:00
void MainWindow : : downloadFromURLList ( const QStringList & urlList )
2014-12-20 20:53:58 +03:00
{
2016-02-09 11:56:48 +03:00
const bool useTorrentAdditionDialog = AddNewTorrentDialog : : isEnabled ( ) ;
2020-11-16 10:02:11 +03:00
for ( const QString & url : urlList )
{
2015-04-19 18:17:47 +03:00
if ( useTorrentAdditionDialog )
AddNewTorrentDialog : : show ( url , this ) ;
else
BitTorrent : : Session : : instance ( ) - > addTorrent ( url ) ;
2013-09-11 01:28:19 +04:00
}
2009-11-06 17:30:14 +03:00
}
/*****************************************************
2014-12-20 20:53:58 +03:00
* *
* Options *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2019-09-05 15:11:33 +03:00
# ifndef Q_OS_MACOS
2021-12-13 10:56:20 +03:00
void MainWindow : : createTrayIcon ( const int retries )
2014-12-20 20:53:58 +03:00
{
2021-12-13 10:56:20 +03:00
if ( m_systrayIcon )
return ;
2020-11-16 10:02:11 +03:00
if ( QSystemTrayIcon : : isSystemTrayAvailable ( ) )
{
2021-12-13 10:56:20 +03:00
m_systrayIcon = new QSystemTrayIcon ( UIThemeManager : : instance ( ) - > getSystrayIcon ( ) , this ) ;
createTrayIconMenu ( ) ;
m_systrayIcon - > setContextMenu ( m_trayIconMenu ) ;
connect ( m_systrayIcon , & QSystemTrayIcon : : activated , this , & MainWindow : : toggleVisibility ) ;
connect ( m_systrayIcon , & QSystemTrayIcon : : messageClicked , this , & MainWindow : : balloonClicked ) ;
m_systrayIcon - > show ( ) ;
2021-12-14 09:38:31 +03:00
emit systemTrayIconCreated ( ) ;
2014-12-20 20:53:58 +03:00
}
2020-11-16 10:02:11 +03:00
else
{
2021-12-13 10:56:20 +03:00
if ( retries > 0 )
2020-11-16 10:02:11 +03:00
{
2022-03-12 17:00:58 +03:00
LogMsg ( tr ( " System tray icon is not available, retrying... " ) , Log : : WARNING ) ;
2021-12-13 10:56:20 +03:00
QTimer : : singleShot ( std : : chrono : : seconds ( 2 ) , this , [ this , retries ] ( )
{
if ( Preferences : : instance ( ) - > systemTrayEnabled ( ) )
createTrayIcon ( retries - 1 ) ;
} ) ;
2014-12-20 20:53:58 +03:00
}
2020-11-16 10:02:11 +03:00
else
{
2022-03-12 17:00:58 +03:00
LogMsg ( tr ( " System tray icon is still not available after retries. Disabling it. " ) , Log : : WARNING ) ;
2021-12-13 10:56:20 +03:00
Preferences : : instance ( ) - > setSystemTrayEnabled ( false ) ;
2014-12-20 20:53:58 +03:00
}
2008-01-04 23:09:37 +03:00
}
2009-11-06 17:30:14 +03:00
}
2019-09-05 15:11:33 +03:00
# endif // Q_OS_MACOS
2012-05-20 17:51:32 +04:00
2021-12-13 10:56:20 +03:00
void MainWindow : : createTrayIconMenu ( )
2014-12-20 20:53:58 +03:00
{
2021-12-13 10:56:20 +03:00
if ( m_trayIconMenu )
return ;
2016-01-24 13:16:25 +03:00
m_trayIconMenu = new QMenu ( this ) ;
2021-12-13 10:56:20 +03:00
2019-09-05 15:11:33 +03:00
# ifndef Q_OS_MACOS
2021-12-13 10:56:20 +03:00
connect ( m_trayIconMenu , & QMenu : : aboutToShow , this , [ this ] ( )
{
m_ui - > actionToggleVisibility - > setText ( isVisible ( ) ? tr ( " Hide " ) : tr ( " Show " ) ) ;
} ) ;
2016-01-24 13:16:25 +03:00
m_trayIconMenu - > addAction ( m_ui - > actionToggleVisibility ) ;
m_trayIconMenu - > addSeparator ( ) ;
2017-06-12 22:47:28 +03:00
# endif
2021-12-13 10:56:20 +03:00
2016-01-24 13:16:25 +03:00
m_trayIconMenu - > addAction ( m_ui - > actionOpen ) ;
m_trayIconMenu - > addAction ( m_ui - > actionDownloadFromURL ) ;
m_trayIconMenu - > addSeparator ( ) ;
2021-12-13 10:56:20 +03:00
2016-01-24 13:16:25 +03:00
m_trayIconMenu - > addAction ( m_ui - > actionUseAlternativeSpeedLimits ) ;
2019-08-25 21:19:05 +03:00
m_trayIconMenu - > addAction ( m_ui - > actionSetGlobalSpeedLimits ) ;
2016-01-24 13:16:25 +03:00
m_trayIconMenu - > addSeparator ( ) ;
2021-12-13 10:56:20 +03:00
2016-01-24 13:16:25 +03:00
m_trayIconMenu - > addAction ( m_ui - > actionStartAll ) ;
m_trayIconMenu - > addAction ( m_ui - > actionPauseAll ) ;
2021-12-13 10:56:20 +03:00
2019-09-05 15:11:33 +03:00
# ifndef Q_OS_MACOS
2016-01-24 13:16:25 +03:00
m_trayIconMenu - > addSeparator ( ) ;
m_trayIconMenu - > addAction ( m_ui - > actionExit ) ;
2017-06-12 22:47:28 +03:00
# endif
2021-12-13 10:56:20 +03:00
2016-01-24 13:16:25 +03:00
if ( m_uiLocked )
m_trayIconMenu - > setEnabled ( false ) ;
}
2021-12-13 10:56:20 +03:00
void MainWindow : : updateAltSpeedsBtn ( const bool alternative )
2016-01-24 13:16:25 +03:00
{
2017-06-12 22:47:28 +03:00
m_ui - > actionUseAlternativeSpeedLimits - > setChecked ( alternative ) ;
2010-06-09 19:40:55 +04:00
}
2017-06-12 22:47:28 +03:00
PropertiesWidget * MainWindow : : propertiesWidget ( ) const
2014-12-20 20:53:58 +03:00
{
2017-06-12 22:47:28 +03:00
return m_propertiesWidget ;
2009-11-06 17:30:14 +03:00
}
// Display Program Options
2014-12-20 20:53:58 +03:00
void MainWindow : : on_actionOptions_triggered ( )
{
2016-01-24 13:16:25 +03:00
if ( m_options )
2022-06-02 14:51:26 +03:00
{
2017-05-30 09:00:00 +03:00
m_options - > activateWindow ( ) ;
2022-06-02 14:51:26 +03:00
}
2015-12-13 17:41:58 +03:00
else
2022-06-02 14:51:26 +03:00
{
2016-04-25 10:54:38 +03:00
m_options = new OptionsDialog ( this ) ;
2022-06-02 14:51:26 +03:00
m_options - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
m_options - > open ( ) ;
}
2014-12-20 20:53:58 +03:00
}
2016-01-24 13:16:25 +03:00
void MainWindow : : on_actionTopToolBar_triggered ( )
2014-12-20 20:53:58 +03:00
{
2021-01-17 09:56:56 +03:00
const bool isVisible = static_cast < QAction * > ( sender ( ) ) - > isChecked ( ) ;
2016-01-24 13:16:25 +03:00
m_ui - > toolBar - > setVisible ( isVisible ) ;
Preferences : : instance ( ) - > setToolbarDisplayed ( isVisible ) ;
2010-06-21 22:32:01 +04:00
}
2015-10-30 16:03:44 +03:00
void MainWindow : : on_actionShowStatusbar_triggered ( )
{
2021-01-17 09:56:56 +03:00
const bool isVisible = static_cast < QAction * > ( sender ( ) ) - > isChecked ( ) ;
2015-10-30 16:03:44 +03:00
Preferences : : instance ( ) - > setStatusbarDisplayed ( isVisible ) ;
2017-05-25 17:50:05 +03:00
showStatusBar ( isVisible ) ;
2015-10-30 16:03:44 +03:00
}
2022-03-21 07:41:06 +03:00
void MainWindow : : on_actionShowFiltersSidebar_triggered ( const bool checked )
{
Preferences * const pref = Preferences : : instance ( ) ;
pref - > setFiltersSidebarVisible ( checked ) ;
showFiltersSidebar ( checked ) ;
}
2016-01-24 13:16:25 +03:00
void MainWindow : : on_actionSpeedInTitleBar_triggered ( )
2014-12-20 20:53:58 +03:00
{
2021-01-17 09:56:56 +03:00
m_displaySpeedInTitle = static_cast < QAction * > ( sender ( ) ) - > isChecked ( ) ;
2016-01-24 13:16:25 +03:00
Preferences : : instance ( ) - > showSpeedInTitleBar ( m_displaySpeedInTitle ) ;
if ( m_displaySpeedInTitle )
2019-09-24 06:29:07 +03:00
reloadSessionStats ( ) ;
2014-12-20 20:53:58 +03:00
else
2022-03-12 17:00:58 +03:00
setWindowTitle ( QStringLiteral ( " qBittorrent " QBT_VERSION ) ) ;
2010-06-22 17:39:49 +04:00
}
2010-06-21 22:32:01 +04:00
2016-01-24 13:16:25 +03:00
void MainWindow : : on_actionRSSReader_triggered ( )
2014-12-20 20:53:58 +03:00
{
2017-03-07 16:10:42 +03:00
Preferences : : instance ( ) - > setRSSWidgetVisible ( m_ui - > actionRSSReader - > isChecked ( ) ) ;
2016-01-24 13:16:25 +03:00
displayRSSTab ( m_ui - > actionRSSReader - > isChecked ( ) ) ;
2014-12-20 20:53:58 +03:00
}
2016-01-24 13:16:25 +03:00
void MainWindow : : on_actionSearchWidget_triggered ( )
2014-12-20 20:53:58 +03:00
{
2020-11-16 10:02:11 +03:00
if ( ! m_hasPython & & m_ui - > actionSearchWidget - > isChecked ( ) )
{
2018-09-06 10:31:14 +03:00
const Utils : : ForeignApps : : PythonInfo pyInfo = Utils : : ForeignApps : : pythonInfo ( ) ;
2014-09-14 22:58:20 +04:00
2018-09-06 10:31:14 +03:00
// Not installed
2020-11-16 10:02:11 +03:00
if ( ! pyInfo . isValid ( ) )
{
2018-06-19 15:16:15 +03:00
m_ui - > actionSearchWidget - > setChecked ( false ) ;
Preferences : : instance ( ) - > setSearchEnabled ( false ) ;
2015-07-21 01:11:05 +03:00
# ifdef Q_OS_WIN
2018-09-06 10:31:14 +03:00
const QMessageBox : : StandardButton buttonPressed = QMessageBox : : question ( this , tr ( " Missing Python Runtime " )
, tr ( " Python is required to use the search engine but it does not seem to be installed. \n Do you want to install it now? " )
, ( QMessageBox : : Yes | QMessageBox : : No ) , QMessageBox : : Yes ) ;
if ( buttonPressed = = QMessageBox : : Yes )
installPython ( ) ;
# else
QMessageBox : : information ( this , tr ( " Missing Python Runtime " )
, tr ( " Python is required to use the search engine but it does not seem to be installed. " ) ) ;
# endif
2014-12-20 20:53:58 +03:00
return ;
}
2018-09-06 10:31:14 +03:00
// Check version requirement
2020-11-16 10:02:11 +03:00
if ( ! pyInfo . isSupportedVersion ( ) )
{
2016-01-24 13:16:25 +03:00
m_ui - > actionSearchWidget - > setChecked ( false ) ;
2014-12-20 20:53:58 +03:00
Preferences : : instance ( ) - > setSearchEnabled ( false ) ;
2018-09-06 10:31:14 +03:00
# ifdef Q_OS_WIN
const QMessageBox : : StandardButton buttonPressed = QMessageBox : : question ( this , tr ( " Old Python Runtime " )
2021-10-09 12:45:26 +03:00
, tr ( " Your Python version (%1) is outdated. Minimum requirement: %2. \n Do you want to install a newer version now? " )
2022-03-25 09:17:22 +03:00
. arg ( pyInfo . version . toString ( ) , u " 3.5.0 " )
2018-09-06 10:31:14 +03:00
, ( QMessageBox : : Yes | QMessageBox : : No ) , QMessageBox : : Yes ) ;
if ( buttonPressed = = QMessageBox : : Yes )
installPython ( ) ;
# else
QMessageBox : : information ( this , tr ( " Old Python Runtime " )
2021-10-09 12:45:26 +03:00
, tr ( " Your Python version (%1) is outdated. Please upgrade to latest version for search engines to work. \n Minimum requirement: %2. " )
2022-03-25 09:17:22 +03:00
. arg ( pyInfo . version . toString ( ) , u " 3.5.0 " ) ) ;
2018-09-06 10:31:14 +03:00
# endif
2014-12-20 20:53:58 +03:00
return ;
}
2018-09-06 10:31:14 +03:00
m_hasPython = true ;
m_ui - > actionSearchWidget - > setChecked ( true ) ;
Preferences : : instance ( ) - > setSearchEnabled ( true ) ;
2014-09-14 15:30:22 +04:00
}
2018-09-06 10:31:14 +03:00
2016-01-24 13:16:25 +03:00
displaySearchTab ( m_ui - > actionSearchWidget - > isChecked ( ) ) ;
2010-06-22 17:58:22 +04:00
}
2009-11-06 17:30:14 +03:00
/*****************************************************
2014-12-20 20:53:58 +03:00
* *
* HTTP Downloader *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-11-06 17:30:14 +03:00
// Display an input dialog to prompt user for
// an url
2016-01-24 13:16:25 +03:00
void MainWindow : : on_actionDownloadFromURL_triggered ( )
2014-12-20 20:53:58 +03:00
{
2020-11-16 10:02:11 +03:00
if ( ! m_downloadFromURLDialog )
{
2018-05-23 11:43:03 +03:00
m_downloadFromURLDialog = new DownloadFromURLDialog ( this ) ;
2022-06-02 14:51:26 +03:00
m_downloadFromURLDialog - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
2018-05-23 11:43:03 +03:00
connect ( m_downloadFromURLDialog . data ( ) , & DownloadFromURLDialog : : urlsReadyToBeDownloaded , this , & MainWindow : : downloadFromURLList ) ;
2022-06-02 14:51:26 +03:00
m_downloadFromURLDialog - > open ( ) ;
2014-12-20 20:53:58 +03:00
}
2009-11-06 17:30:14 +03:00
}
2010-06-22 17:58:22 +04:00
2019-09-05 15:11:33 +03:00
# if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
2021-01-25 10:49:29 +03:00
void MainWindow : : handleUpdateCheckFinished ( ProgramUpdater * updater , const bool invokedByUser )
2010-10-24 01:46:05 +04:00
{
2021-01-20 07:12:07 +03:00
m_ui - > actionCheckForUpdates - > setEnabled ( true ) ;
m_ui - > actionCheckForUpdates - > setText ( tr ( " &Check for Updates " ) ) ;
m_ui - > actionCheckForUpdates - > setToolTip ( tr ( " Check for program updates " ) ) ;
2021-01-25 10:49:29 +03:00
const auto cleanup = [ this , updater ] ( )
{
if ( m_programUpdateTimer )
m_programUpdateTimer - > start ( ) ;
updater - > deleteLater ( ) ;
} ;
2021-01-20 07:12:07 +03:00
2021-01-25 10:49:29 +03:00
const QString newVersion = updater - > getNewVersion ( ) ;
if ( ! newVersion . isEmpty ( ) )
2020-11-16 10:02:11 +03:00
{
2022-03-19 10:57:41 +03:00
const QString msg { tr ( " A new version is available. " ) + u " <br/> "
+ tr ( " Do you want to download %1? " ) . arg ( newVersion ) + u " <br/><br/> "
2022-03-29 05:41:17 +03:00
+ u " <a href= \" https://www.qbittorrent.org/news.php \" >%1</a> " _qs . arg ( tr ( " Open changelog... " ) ) } ;
2021-01-20 07:12:07 +03:00
auto * msgBox = new QMessageBox { QMessageBox : : Question , tr ( " qBittorrent Update Available " ) , msg
, ( QMessageBox : : Yes | QMessageBox : : No ) , this } ;
msgBox - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
msgBox - > setAttribute ( Qt : : WA_ShowWithoutActivating ) ;
msgBox - > setDefaultButton ( QMessageBox : : Yes ) ;
2022-05-01 16:18:22 +03:00
msgBox - > setWindowModality ( Qt : : NonModal ) ;
2021-03-05 17:17:55 +03:00
connect ( msgBox , & QMessageBox : : buttonClicked , this , [ msgBox , updater ] ( QAbstractButton * button )
2020-11-16 10:02:11 +03:00
{
2021-01-20 07:12:07 +03:00
if ( msgBox - > buttonRole ( button ) = = QMessageBox : : YesRole )
{
updater - > updateProgram ( ) ;
}
} ) ;
2021-01-25 10:49:29 +03:00
connect ( msgBox , & QDialog : : finished , this , cleanup ) ;
2022-05-01 16:18:22 +03:00
msgBox - > show ( ) ;
2010-10-24 01:46:05 +04:00
}
2021-01-25 10:49:29 +03:00
else
2020-11-16 10:02:11 +03:00
{
2021-01-25 10:49:29 +03:00
if ( invokedByUser )
2021-01-20 07:12:07 +03:00
{
2022-03-29 05:41:17 +03:00
auto * msgBox = new QMessageBox { QMessageBox : : Information , u " qBittorrent " _qs
2021-01-25 10:49:29 +03:00
, tr ( " No updates available. \n You are already using the latest version. " )
, QMessageBox : : Ok , this } ;
msgBox - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
2022-05-01 16:18:22 +03:00
msgBox - > setWindowModality ( Qt : : NonModal ) ;
2021-01-25 10:49:29 +03:00
connect ( msgBox , & QDialog : : finished , this , cleanup ) ;
2022-05-01 16:18:22 +03:00
msgBox - > show ( ) ;
2021-01-25 10:49:29 +03:00
}
else
{
cleanup ( ) ;
}
2014-12-20 20:53:58 +03:00
}
2010-10-24 01:46:05 +04:00
}
# endif
2010-10-31 15:03:24 +03:00
2017-05-25 17:50:05 +03:00
void MainWindow : : toggleAlternativeSpeeds ( )
{
BitTorrent : : Session * const session = BitTorrent : : Session : : instance ( ) ;
session - > setAltGlobalSpeedLimitEnabled ( ! session - > isAltGlobalSpeedLimitEnabled ( ) ) ;
}
2016-01-24 13:16:25 +03:00
void MainWindow : : on_actionDonateMoney_triggered ( )
2010-10-31 15:03:24 +03:00
{
2022-03-12 17:00:58 +03:00
QDesktopServices : : openUrl ( QUrl ( u " https://www.qbittorrent.org/donate " _qs ) ) ;
2010-11-08 21:17:54 +03:00
}
2010-11-14 00:15:52 +03:00
void MainWindow : : showConnectionSettings ( )
2010-11-08 21:17:54 +03:00
{
2014-12-20 20:53:58 +03:00
on_actionOptions_triggered ( ) ;
2016-01-24 13:16:25 +03:00
m_options - > showConnectionTab ( ) ;
2010-10-31 15:03:24 +03:00
}
2010-12-20 21:07:36 +03:00
2012-02-07 21:48:25 +04:00
void MainWindow : : minimizeWindow ( )
{
2016-10-23 15:04:40 +03:00
setWindowState ( windowState ( ) | Qt : : WindowMinimized ) ;
2012-02-07 21:48:25 +04:00
}
2016-01-24 22:38:45 +03:00
void MainWindow : : on_actionExecutionLogs_triggered ( bool checked )
2010-12-20 21:07:36 +03:00
{
2020-11-16 10:02:11 +03:00
if ( checked )
{
2014-12-20 20:53:58 +03:00
Q_ASSERT ( ! m_executionLog ) ;
2021-11-08 08:23:33 +03:00
m_executionLog = new ExecutionLogWidget ( executionLogMsgTypes ( ) , m_tabs ) ;
2019-09-05 15:11:33 +03:00
# ifdef Q_OS_MACOS
2018-05-04 19:56:42 +03:00
m_tabs - > addTab ( m_executionLog , tr ( " Execution Log " ) ) ;
# else
2018-03-12 09:29:58 +03:00
const int indexTab = m_tabs - > addTab ( m_executionLog , tr ( " Execution Log " ) ) ;
2022-03-12 17:00:58 +03:00
m_tabs - > setTabIcon ( indexTab , UIThemeManager : : instance ( ) - > getIcon ( u " view-calendar-journal " _qs ) ) ;
2017-06-12 22:47:28 +03:00
# endif
2014-12-20 20:53:58 +03:00
}
2020-11-16 10:02:11 +03:00
else
{
2014-12-20 20:53:58 +03:00
delete m_executionLog ;
2015-01-26 17:00:23 +03:00
}
2016-01-24 22:38:45 +03:00
2016-01-24 13:16:25 +03:00
m_ui - > actionNormalMessages - > setEnabled ( checked ) ;
m_ui - > actionInformationMessages - > setEnabled ( checked ) ;
m_ui - > actionWarningMessages - > setEnabled ( checked ) ;
m_ui - > actionCriticalMessages - > setEnabled ( checked ) ;
2016-03-14 15:39:13 +03:00
setExecutionLogEnabled ( checked ) ;
2010-12-20 21:07:36 +03:00
}
2010-12-31 16:36:32 +03:00
2021-11-08 08:23:33 +03:00
void MainWindow : : on_actionNormalMessages_triggered ( const bool checked )
2016-01-24 22:38:45 +03:00
{
if ( ! m_executionLog )
return ;
2021-11-08 08:23:33 +03:00
const Log : : MsgTypes flags = executionLogMsgTypes ( ) . setFlag ( Log : : NORMAL , checked ) ;
2016-03-14 15:39:13 +03:00
setExecutionLogMsgTypes ( flags ) ;
2016-01-24 22:38:45 +03:00
}
2021-11-08 08:23:33 +03:00
void MainWindow : : on_actionInformationMessages_triggered ( const bool checked )
2016-01-24 22:38:45 +03:00
{
if ( ! m_executionLog )
return ;
2021-11-08 08:23:33 +03:00
const Log : : MsgTypes flags = executionLogMsgTypes ( ) . setFlag ( Log : : INFO , checked ) ;
2016-03-14 15:39:13 +03:00
setExecutionLogMsgTypes ( flags ) ;
2016-01-24 22:38:45 +03:00
}
2021-11-08 08:23:33 +03:00
void MainWindow : : on_actionWarningMessages_triggered ( const bool checked )
2016-01-24 22:38:45 +03:00
{
if ( ! m_executionLog )
return ;
2021-11-08 08:23:33 +03:00
const Log : : MsgTypes flags = executionLogMsgTypes ( ) . setFlag ( Log : : WARNING , checked ) ;
2016-03-14 15:39:13 +03:00
setExecutionLogMsgTypes ( flags ) ;
2016-01-24 22:38:45 +03:00
}
2021-11-08 08:23:33 +03:00
void MainWindow : : on_actionCriticalMessages_triggered ( const bool checked )
2016-01-24 22:38:45 +03:00
{
if ( ! m_executionLog )
return ;
2021-11-08 08:23:33 +03:00
const Log : : MsgTypes flags = executionLogMsgTypes ( ) . setFlag ( Log : : CRITICAL , checked ) ;
2016-03-14 15:39:13 +03:00
setExecutionLogMsgTypes ( flags ) ;
2016-01-24 22:38:45 +03:00
}
2016-01-24 13:16:25 +03:00
void MainWindow : : on_actionAutoExit_toggled ( bool enabled )
2010-12-31 16:36:32 +03:00
{
2014-12-20 20:53:58 +03:00
qDebug ( ) < < Q_FUNC_INFO < < enabled ;
Preferences : : instance ( ) - > setShutdownqBTWhenDownloadsComplete ( enabled ) ;
2010-12-31 16:36:32 +03:00
}
2016-01-24 13:16:25 +03:00
void MainWindow : : on_actionAutoSuspend_toggled ( bool enabled )
2010-12-31 16:36:32 +03:00
{
2014-12-20 20:53:58 +03:00
qDebug ( ) < < Q_FUNC_INFO < < enabled ;
Preferences : : instance ( ) - > setSuspendWhenDownloadsComplete ( enabled ) ;
2010-12-31 16:36:32 +03:00
}
2016-01-24 13:16:25 +03:00
void MainWindow : : on_actionAutoHibernate_toggled ( bool enabled )
2014-12-20 20:53:58 +03:00
{
qDebug ( ) < < Q_FUNC_INFO < < enabled ;
Preferences : : instance ( ) - > setHibernateWhenDownloadsComplete ( enabled ) ;
2014-07-06 13:13:36 +04:00
}
2016-01-24 13:16:25 +03:00
void MainWindow : : on_actionAutoShutdown_toggled ( bool enabled )
2010-12-31 16:36:32 +03:00
{
2014-12-20 20:53:58 +03:00
qDebug ( ) < < Q_FUNC_INFO < < enabled ;
Preferences : : instance ( ) - > setShutdownWhenDownloadsComplete ( enabled ) ;
2010-12-31 16:36:32 +03:00
}
2011-02-06 17:27:34 +03:00
2018-08-02 22:45:21 +03:00
void MainWindow : : updatePowerManagementState ( )
2011-02-06 17:27:34 +03:00
{
2018-08-02 22:45:21 +03:00
const bool inhibitSuspend = ( Preferences : : instance ( ) - > preventFromSuspendWhenDownloading ( ) & & BitTorrent : : Session : : instance ( ) - > hasUnfinishedTorrents ( ) )
| | ( Preferences : : instance ( ) - > preventFromSuspendWhenSeeding ( ) & & BitTorrent : : Session : : instance ( ) - > hasRunningSeed ( ) ) ;
m_pwr - > setActivityState ( inhibitSuspend ) ;
2011-02-06 17:27:34 +03:00
}
2011-03-12 23:59:44 +03:00
2019-09-05 15:11:33 +03:00
# if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
2021-01-25 10:49:29 +03:00
void MainWindow : : checkProgramUpdate ( const bool invokedByUser )
2014-12-20 20:53:58 +03:00
{
2021-01-25 10:49:29 +03:00
if ( m_programUpdateTimer )
m_programUpdateTimer - > stop ( ) ;
2016-01-24 13:16:25 +03:00
m_ui - > actionCheckForUpdates - > setEnabled ( false ) ;
m_ui - > actionCheckForUpdates - > setText ( tr ( " Checking for Updates... " ) ) ;
m_ui - > actionCheckForUpdates - > setToolTip ( tr ( " Already checking for program updates in the background " ) ) ;
2021-01-25 10:49:29 +03:00
auto * updater = new ProgramUpdater ( this ) ;
connect ( updater , & ProgramUpdater : : updateCheckFinished
, this , [ this , invokedByUser , updater ] ( )
{
handleUpdateCheckFinished ( updater , invokedByUser ) ;
} ) ;
2014-12-20 20:53:58 +03:00
updater - > checkForUpdates ( ) ;
2013-11-23 16:58:03 +04:00
}
# endif
2014-09-14 15:30:22 +04:00
# ifdef Q_OS_WIN
2014-12-20 20:53:58 +03:00
void MainWindow : : installPython ( )
{
setCursor ( QCursor ( Qt : : WaitCursor ) ) ;
// Download python
2019-08-09 07:47:52 +03:00
# ifdef QBT_APP_64BIT
2022-03-19 10:57:41 +03:00
const auto installerURL = u " https://www.python.org/ftp/python/3.8.10/python-3.8.10-amd64.exe " _qs ;
2019-08-09 07:47:52 +03:00
# else
2022-03-19 10:57:41 +03:00
const auto installerURL = u " https://www.python.org/ftp/python/3.8.10/python-3.8.10.exe " _qs ;
2019-08-09 07:47:52 +03:00
# endif
2019-03-03 12:43:42 +03:00
Net : : DownloadManager : : instance ( ) - > download (
Net : : DownloadRequest ( installerURL ) . saveToFile ( true )
, this , & MainWindow : : pythonDownloadFinished ) ;
2014-12-20 20:53:58 +03:00
}
2019-03-01 10:38:16 +03:00
void MainWindow : : pythonDownloadFinished ( const Net : : DownloadResult & result )
2014-12-20 20:53:58 +03:00
{
2020-11-16 10:02:11 +03:00
if ( result . status ! = Net : : DownloadStatus : : Success )
{
2019-03-01 10:38:16 +03:00
setCursor ( QCursor ( Qt : : ArrowCursor ) ) ;
QMessageBox : : warning (
this , tr ( " Download error " )
, tr ( " Python setup could not be downloaded, reason: %1. \n Please install it manually. " )
. arg ( result . errorString ) ) ;
return ;
}
2014-12-20 20:53:58 +03:00
setCursor ( QCursor ( Qt : : ArrowCursor ) ) ;
QProcess installer ;
qDebug ( " Launching Python installer in passive mode... " ) ;
2022-03-23 18:56:47 +03:00
const Path exePath = result . filePath + u " .exe " ;
2022-02-08 06:03:48 +03:00
Utils : : Fs : : renameFile ( result . filePath , exePath ) ;
2022-03-19 10:57:41 +03:00
installer . start ( exePath . toString ( ) , { u " /passive " _qs } ) ;
2016-11-01 01:19:37 +03:00
2014-12-20 20:53:58 +03:00
// Wait for setup to complete
2016-11-01 01:19:37 +03:00
installer . waitForFinished ( 10 * 60 * 1000 ) ;
2014-12-20 20:53:58 +03:00
qDebug ( " Installer stdout: %s " , installer . readAllStandardOutput ( ) . data ( ) ) ;
qDebug ( " Installer stderr: %s " , installer . readAllStandardError ( ) . data ( ) ) ;
qDebug ( " Setup should be complete! " ) ;
2019-07-26 18:16:35 +03:00
2014-12-20 20:53:58 +03:00
// Delete temp file
2022-02-08 06:03:48 +03:00
Utils : : Fs : : removeFile ( exePath ) ;
2019-07-26 18:16:35 +03:00
2014-12-20 20:53:58 +03:00
// Reload search engine
2020-11-16 10:02:11 +03:00
if ( Utils : : ForeignApps : : pythonInfo ( ) . isSupportedVersion ( ) )
{
2016-01-24 13:16:25 +03:00
m_ui - > actionSearchWidget - > setChecked ( true ) ;
2014-12-20 20:53:58 +03:00
displaySearchTab ( true ) ;
}
}
2018-06-06 16:48:17 +03:00
# endif // Q_OS_WIN