2006-09-30 20:02:39 +04:00
/*
2016-01-24 13:16:25 +03:00
* Bittorrent Client using Qt and libtorrent .
2007-07-14 18:31:59 +04:00
* Copyright ( C ) 2006 Christophe Dumez
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 .
*
2007-07-14 18:31:59 +04:00
* Contact : chris @ qbittorrent . org
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"
2017-06-12 22:47:28 +03:00
# ifdef Q_OS_MAC
# include <objc/objc.h>
# include <objc/message.h>
# include <QtMacExtras>
# include <QtMac>
# endif
2011-04-02 12:54:28 +04:00
# include <QtGlobal>
2013-09-21 11:59:58 +04:00
# if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC)) && defined(QT_DBUS_LIB)
2011-04-02 12:54:28 +04:00
# include <QDBusConnection>
# include "notifications.h"
2009-11-25 23:32:18 +03:00
# endif
2015-08-27 14:25:14 +03:00
# include <QDebug>
2006-09-30 20:02:39 +04:00
# include <QFileDialog>
2010-08-23 23:42:15 +04:00
# include <QFileSystemWatcher>
2006-09-30 20:02:39 +04:00
# include <QMessageBox>
# include <QTimer>
2006-12-27 06:19:38 +03:00
# include <QDesktopServices>
2008-07-11 00:19:28 +04:00
# include <QStatusBar>
2009-08-17 14:22:41 +04:00
# include <QClipboard>
2007-03-27 22:49:29 +04:00
# include <QCloseEvent>
2007-07-19 16:58:45 +04:00
# include <QShortcut>
2010-10-08 21:47:34 +04:00
# include <QScrollBar>
2017-04-11 15:35:10 +03:00
# include <QSplitter>
2016-11-01 01:19:37 +03:00
# include <QSysInfo>
2013-09-21 11:59:58 +04:00
# include <QMimeData>
2014-07-05 16:44:13 +04:00
# include <QCryptographicHash>
2016-01-24 13:16:25 +03:00
# include <QProcess>
2006-12-28 02:56:30 +03:00
2016-01-24 13:16:25 +03:00
# include "base/preferences.h"
# include "base/settingsstorage.h"
# include "base/logger.h"
2015-09-25 11:10:05 +03:00
# include "base/utils/misc.h"
2015-08-27 14:25:14 +03:00
# include "base/utils/fs.h"
2016-01-24 13:16:25 +03:00
# ifdef Q_OS_WIN
# include "base/net/downloadmanager.h"
# include "base/net/downloadhandler.h"
# endif
2015-09-25 11:10:05 +03:00
# include "base/bittorrent/session.h"
# include "base/bittorrent/sessionstatus.h"
# include "base/bittorrent/torrenthandle.h"
2016-04-29 12:25:15 +03:00
# include "base/global.h"
2017-03-07 16:10:42 +03:00
# include "base/rss/rss_folder.h"
# include "base/rss/rss_session.h"
2016-01-24 13:16:25 +03:00
# include "application.h"
# if defined(Q_OS_WIN) || defined(Q_OS_MAC)
# include "programupdater.h"
# endif
# include "powermanagement.h"
# include "guiiconprovider.h"
# include "torrentmodel.h"
# include "autoexpandabledialog.h"
# include "torrentcreatordlg.h"
# include "downloadfromurldlg.h"
# include "addnewtorrentdialog.h"
# include "statsdialog.h"
# include "cookiesdialog.h"
2009-11-17 16:11:32 +03:00
# include "speedlimitdlg.h"
2016-01-24 13:16:25 +03:00
# include "transferlistwidget.h"
# include "search/searchwidget.h"
2010-01-13 02:16:18 +03:00
# include "trackerlist.h"
# include "peerlistwidget.h"
2009-11-20 10:48:44 +03:00
# include "transferlistfilterswidget.h"
2009-11-08 17:20:58 +03:00
# include "propertieswidget.h"
2009-11-18 16:18:55 +03:00
# include "statusbar.h"
2017-03-07 16:10:42 +03:00
# include "rss/rsswidget.h"
2016-01-24 13:16:25 +03:00
# include "about_imp.h"
2016-04-25 10:54:38 +03:00
# include "optionsdlg.h"
2017-05-01 20:27:07 +03:00
# if LIBTORRENT_VERSION_NUM < 10100
2016-01-24 13:16:25 +03:00
# include "trackerlogin.h"
2017-05-01 20:27:07 +03:00
# endif
2016-01-24 13:16:25 +03:00
# include "lineedit.h"
2010-12-20 21:07:36 +03:00
# include "executionlog.h"
2016-01-24 13:16:25 +03:00
# include "hidabletabwidget.h"
# include "ui_mainwindow.h"
2013-09-21 11:59:58 +04:00
# ifdef Q_OS_MAC
2010-06-09 19:43:29 +04:00
void qt_mac_set_dock_menu ( QMenu * menu ) ;
2010-06-08 19:17:15 +04:00
# endif
2007-03-04 20:13:29 +03:00
2009-11-26 01:36:42 +03:00
# define TIME_TRAY_BALLOON 5000
2011-02-06 17:27:34 +03:00
# define PREVENT_SUSPEND_INTERVAL 60000
2009-11-26 01:36:42 +03:00
2016-03-14 15:39:13 +03:00
namespace
{
2016-04-17 22:56:51 +03:00
# define SETTINGS_KEY(name) "GUI / " name
2016-03-14 15:39:13 +03:00
// ExecutionLog properties keys
2016-04-17 22:56:51 +03:00
# define EXECUTIONLOG_SETTINGS_KEY(name) SETTINGS_KEY("Log / ") name
2016-03-14 15:39:13 +03:00
const QString KEY_EXECUTIONLOG_ENABLED = EXECUTIONLOG_SETTINGS_KEY ( " Enabled " ) ;
const QString KEY_EXECUTIONLOG_TYPES = EXECUTIONLOG_SETTINGS_KEY ( " Types " ) ;
2016-04-17 22:56:51 +03:00
// Notifications properties keys
# define NOTIFICATIONS_SETTINGS_KEY(name) SETTINGS_KEY("Notifications / ") name
const QString KEY_NOTIFICATIONS_ENABLED = NOTIFICATIONS_SETTINGS_KEY ( " Enabled " ) ;
const QString KEY_NOTIFICATIONS_TORRENTADDED = NOTIFICATIONS_SETTINGS_KEY ( " TorrentAdded " ) ;
2016-11-13 23:46:17 +03:00
// Misc
const QString KEY_DOWNLOAD_TRACKER_FAVICON = NOTIFICATIONS_SETTINGS_KEY ( " DownloadTrackerFavicon " ) ;
2017-01-08 03:46:01 +03:00
// just a shortcut
inline SettingsStorage * settings ( )
{
return SettingsStorage : : instance ( ) ;
}
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 )
2015-01-22 15:56:16 +03:00
, m_posInitialized ( false )
2016-01-24 13:16:25 +03:00
, m_forceExit ( false )
, m_unlockDlgShowing ( false )
2015-12-13 18:29:55 +03:00
# if defined(Q_OS_WIN) || defined(Q_OS_MAC)
2015-12-13 17:41:58 +03:00
, m_wasUpdateCheckEnabled ( false )
2015-12-13 18:29:55 +03:00
# endif
2016-01-24 13:16:25 +03:00
, m_hasPython ( false )
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 ( ) ;
2017-03-03 11:42:13 +03:00
setWindowTitle ( " 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
2017-06-12 22:47:28 +03:00
# ifndef Q_OS_MAC
# ifdef Q_OS_UNIX
2014-12-20 20:53:58 +03:00
if ( Preferences : : instance ( ) - > useSystemIconTheme ( ) )
2016-01-24 13:16:25 +03:00
setWindowIcon ( QIcon : : fromTheme ( " qbittorrent " , QIcon ( " :/icons/skin/qbittorrent32.png " ) ) ) ;
2014-12-20 20:53:58 +03:00
else
2017-06-12 22:47:28 +03:00
# endif // Q_OS_UNIX
2017-01-08 03:46:01 +03:00
setWindowIcon ( QIcon ( " :/icons/skin/qbittorrent32.png " ) ) ;
2017-06-12 22:47:28 +03:00
# endif // Q_OS_MAC
# 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 ( ) ;
2016-01-24 13:16:25 +03:00
m_ui - > actionOpen - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " list-add " ) ) ;
m_ui - > actionDownloadFromURL - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " insert-link " ) ) ;
2017-01-17 20:05:08 +03:00
m_ui - > actionSetUploadLimit - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " kt-set-max-upload-speed " ) ) ;
m_ui - > actionSetDownloadLimit - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " kt-set-max-download-speed " ) ) ;
m_ui - > actionSetGlobalUploadLimit - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " kt-set-max-upload-speed " ) ) ;
m_ui - > actionSetGlobalDownloadLimit - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " kt-set-max-download-speed " ) ) ;
2016-01-24 13:16:25 +03:00
m_ui - > actionCreateTorrent - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " document-edit " ) ) ;
m_ui - > actionAbout - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " help-about " ) ) ;
m_ui - > actionStatistics - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " view-statistics " ) ) ;
m_ui - > actionDecreasePriority - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " go-down " ) ) ;
m_ui - > actionBottomPriority - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " go-bottom " ) ) ;
m_ui - > actionDelete - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " list-remove " ) ) ;
m_ui - > actionDocumentation - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " help-contents " ) ) ;
m_ui - > actionDonateMoney - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " wallet-open " ) ) ;
m_ui - > actionExit - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " application-exit " ) ) ;
m_ui - > actionIncreasePriority - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " go-up " ) ) ;
m_ui - > actionTopPriority - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " go-top " ) ) ;
m_ui - > actionLock - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " object-locked " ) ) ;
2017-01-20 22:02:49 +03:00
m_ui - > actionOptions - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " configure " , " preferences-system " ) ) ;
2016-01-24 13:16:25 +03:00
m_ui - > actionPause - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " media-playback-pause " ) ) ;
m_ui - > actionPauseAll - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " media-playback-pause " ) ) ;
m_ui - > actionStart - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " media-playback-start " ) ) ;
m_ui - > actionStartAll - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " media-playback-start " ) ) ;
m_ui - > menuAutoShutdownOnDownloadsCompletion - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " application-exit " ) ) ;
m_ui - > actionManageCookies - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " preferences-web-browser-cookies " ) ) ;
2014-12-20 20:53:58 +03:00
QMenu * lockMenu = new QMenu ( this ) ;
2015-04-08 08:27:46 +03:00
QAction * defineUiLockPasswdAct = lockMenu - > addAction ( tr ( " &Set Password " ) ) ;
2017-07-16 07:10:13 +03:00
connect ( defineUiLockPasswdAct , & QAction : : triggered , this , & MainWindow : : defineUILockPassword ) ;
2015-04-08 08:27:46 +03:00
QAction * clearUiLockPasswdAct = lockMenu - > addAction ( tr ( " &Clear Password " ) ) ;
2017-07-16 07:10:13 +03:00
connect ( clearUiLockPasswdAct , & QAction : : triggered , this , & MainWindow : : clearUILockPassword ) ;
2016-01-24 13:16:25 +03:00
m_ui - > actionLock - > setMenu ( lockMenu ) ;
2015-01-26 17:00:23 +03:00
2014-12-20 20:53:58 +03:00
// Creating Bittorrent session
2017-07-16 07:10:13 +03:00
connect ( BitTorrent : : Session : : instance ( ) , & BitTorrent : : Session : : fullDiskError , this , & MainWindow : : fullDiskError ) ;
connect ( BitTorrent : : Session : : instance ( ) , & BitTorrent : : Session : : addTorrentFailed , this , & MainWindow : : addTorrentFailed ) ;
connect ( BitTorrent : : Session : : instance ( ) , & BitTorrent : : Session : : torrentNew , this , & MainWindow : : torrentNew ) ;
connect ( BitTorrent : : Session : : instance ( ) , & BitTorrent : : Session : : torrentFinished , this , & MainWindow : : finishedTorrent ) ;
connect ( BitTorrent : : Session : : instance ( ) , & BitTorrent : : Session : : trackerAuthenticationRequired , this , & MainWindow : : trackerAuthenticationRequired ) ;
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
2016-01-24 13:16:25 +03:00
QSplitter * 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 ) ;
m_searchFilterAction = m_ui - > toolBar - > insertWidget ( m_ui - > actionLock , m_searchFilter ) ;
m_searchFilter - > setPlaceholderText ( tr ( " Filter torrent list... " ) ) ;
m_searchFilter - > setFixedWidth ( 200 ) ;
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 ) ;
2017-01-08 03:46:01 +03:00
// transferList->setStyleSheet("QTreeView {border: none;}"); // borderless
2016-01-24 13:16:25 +03:00
m_propertiesWidget = new PropertiesWidget ( hSplitter , this , m_transferListWidget ) ;
m_transferListFiltersWidget = new TransferListFiltersWidget ( m_splitter , m_transferListWidget ) ;
2016-11-13 23:46:17 +03:00
m_transferListFiltersWidget - > setDownloadTrackerFavicon ( isDownloadTrackerFavicon ( ) ) ;
2016-01-24 13:16:25 +03:00
hSplitter - > addWidget ( m_transferListWidget ) ;
hSplitter - > addWidget ( m_propertiesWidget ) ;
m_splitter - > addWidget ( m_transferListFiltersWidget ) ;
m_splitter - > addWidget ( hSplitter ) ;
m_splitter - > setCollapsible ( 0 , true ) ;
m_splitter - > setCollapsible ( 1 , false ) ;
2017-06-12 22:47:28 +03:00
m_tabs - > addTab ( m_splitter ,
# ifndef Q_OS_MAC
GuiIconProvider : : instance ( ) - > getIcon ( " folder-remote " ) ,
# 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 ) ;
connect ( m_splitter , & QSplitter : : splitterMoved , this , & MainWindow : : writeSettings ) ;
connect ( BitTorrent : : Session : : instance ( ) , & BitTorrent : : Session : : trackersChanged , m_propertiesWidget , & PropertiesWidget : : loadTrackers ) ;
connect ( BitTorrent : : Session : : instance ( ) , & BitTorrent : : Session : : trackersAdded , m_transferListFiltersWidget , & TransferListFiltersWidget : : addTrackers ) ;
connect ( BitTorrent : : Session : : instance ( ) , & BitTorrent : : Session : : trackersRemoved , m_transferListFiltersWidget , & TransferListFiltersWidget : : removeTrackers ) ;
connect ( BitTorrent : : Session : : instance ( ) , & BitTorrent : : Session : : trackerlessStateChanged , m_transferListFiltersWidget , & TransferListFiltersWidget : : changeTrackerless ) ;
using Func = void ( TransferListFiltersWidget : : * ) ( BitTorrent : : TorrentHandle * const , const QString & ) ;
connect ( BitTorrent : : Session : : instance ( ) , & BitTorrent : : Session : : trackerSuccess , m_transferListFiltersWidget , static_cast < Func > ( & TransferListFiltersWidget : : trackerSuccess ) ) ;
connect ( BitTorrent : : Session : : instance ( ) , & BitTorrent : : Session : : trackerError , m_transferListFiltersWidget , static_cast < Func > ( & TransferListFiltersWidget : : trackerError ) ) ;
connect ( BitTorrent : : Session : : instance ( ) , & BitTorrent : : Session : : trackerWarning , m_transferListFiltersWidget , static_cast < Func > ( & TransferListFiltersWidget : : trackerWarning ) ) ;
2014-12-20 20:53:58 +03:00
2017-06-12 22:47:28 +03:00
# ifdef Q_OS_MAC
// 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
2016-01-24 13:16:25 +03:00
m_prioSeparator = m_ui - > toolBar - > insertSeparator ( m_ui - > actionTopPriority ) ;
m_prioSeparatorMenu = m_ui - > menuEdit - > insertSeparator ( m_ui - > actionTopPriority ) ;
2017-07-16 06:47:53 +03:00
2017-06-12 22:47:28 +03:00
# ifdef Q_OS_MAC
foreach ( QAction * action , m_ui - > toolBar - > actions ( ) ) {
if ( action - > isSeparator ( ) ) {
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 ) ;
}
# endif
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 ) ;
connect ( m_ui - > actionTopPriority , & QAction : : triggered , m_transferListWidget , & TransferListWidget : : topPrioSelectedTorrents ) ;
connect ( m_ui - > actionIncreasePriority , & QAction : : triggered , m_transferListWidget , & TransferListWidget : : increasePrioSelectedTorrents ) ;
connect ( m_ui - > actionDecreasePriority , & QAction : : triggered , m_transferListWidget , & TransferListWidget : : decreasePrioSelectedTorrents ) ;
connect ( m_ui - > actionBottomPriority , & QAction : : triggered , m_transferListWidget , & TransferListWidget : : bottomPrioSelectedTorrents ) ;
2017-06-12 22:47:28 +03:00
# ifndef Q_OS_MAC
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
2013-09-21 11:59:58 +04:00
# if defined(Q_OS_WIN) || defined(Q_OS_MAC)
2016-01-24 13:16:25 +03:00
m_programUpdateTimer = new QTimer ( this ) ;
m_programUpdateTimer - > setInterval ( 60 * 60 * 1000 ) ;
m_programUpdateTimer - > setSingleShot ( true ) ;
2017-07-16 07:10:13 +03:00
connect ( m_programUpdateTimer , & QTimer : : timeout , this , & MainWindow : : checkProgramUpdate ) ;
connect ( m_ui - > actionCheckForUpdates , & QAction : : triggered , this , & MainWindow : : checkProgramUpdate ) ;
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 ) ;
2017-07-16 07:10:13 +03:00
connect ( m_preventTimer , & QTimer : : timeout , this , & MainWindow : : checkForActiveTorrents ) ;
2014-12-20 20:53:58 +03:00
// Configure BT session according to options
loadPreferences ( false ) ;
2017-07-16 07:10:13 +03:00
connect ( BitTorrent : : Session : : instance ( ) , & BitTorrent : : Session : : torrentsUpdated , this , & MainWindow : : updateGUI ) ;
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
2013-09-21 11:59:58 +04:00
# ifdef Q_OS_MAC
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
2016-03-14 15:39:13 +03:00
Log : : MsgTypes flags ( executionLogMsgTypes ( ) ) ;
2016-01-24 13:16:25 +03:00
m_ui - > actionNormalMessages - > setChecked ( flags & Log : : NORMAL ) ;
m_ui - > actionInformationMessages - > setChecked ( flags & Log : : INFO ) ;
m_ui - > actionWarningMessages - > setChecked ( flags & Log : : WARNING ) ;
m_ui - > actionCriticalMessages - > setChecked ( flags & Log : : CRITICAL ) ;
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 ( ) )
QTimer : : singleShot ( 0 , this , SLOT ( on_actionSearchWidget_triggered ( ) ) ) ;
2014-12-20 20:53:58 +03:00
// Auto shutdown actions
2015-01-26 17:00:23 +03:00
QActionGroup * 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 ) ;
2013-09-21 11:59:58 +04:00
# if (!defined(Q_OS_UNIX) || defined(Q_OS_MAC)) || 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
2017-06-12 22:47:28 +03:00
# ifndef Q_OS_MAC
2016-01-24 13:16:25 +03:00
if ( m_systrayIcon ) {
if ( ! ( pref - > startMinimized ( ) | | m_uiLocked ) ) {
2014-12-20 20:53:58 +03:00
show ( ) ;
activateWindow ( ) ;
raise ( ) ;
}
2015-06-20 23:28:40 +03:00
else if ( pref - > startMinimized ( ) ) {
2015-07-03 22:09:37 +03:00
showMinimized ( ) ;
2015-06-20 23:28:40 +03:00
if ( pref - > minimizeToTray ( ) )
2015-07-03 22:09:37 +03:00
hide ( ) ;
2015-04-21 12:58:21 +03:00
}
}
else {
2017-06-12 22:47:28 +03:00
# endif
2015-04-21 12:58:21 +03:00
// Make sure the Window is visible if we don't have a tray icon
if ( pref - > startMinimized ( ) ) {
showMinimized ( ) ;
}
else {
show ( ) ;
activateWindow ( ) ;
raise ( ) ;
}
2017-06-12 22:47:28 +03:00
# ifndef Q_OS_MAC
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
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
2014-12-20 20:53:58 +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 " ) ,
2014-12-20 20:53:58 +03:00
tr ( " qBittorrent is not the default application to open torrent files or Magnet links. \n Do you want to associate qBittorrent to torrent files and Magnet links? " ) ,
QMessageBox : : Yes | QMessageBox : : No , QMessageBox : : Yes ) = = QMessageBox : : Yes ) {
Preferences : : setTorrentFileAssoc ( true ) ;
Preferences : : setMagnetLinkAssoc ( true ) ;
}
else {
pref - > setNeverCheckFileAssoc ( ) ;
}
2010-06-02 17:08:26 +04:00
}
2010-05-31 01:45:55 +04:00
# endif
2013-09-21 11:59:58 +04:00
# ifdef Q_OS_MAC
2017-06-12 22:47:28 +03:00
setupDockClickHandler ( ) ;
2016-01-24 13:16:25 +03:00
qt_mac_set_dock_menu ( trayIconMenu ( ) ) ;
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
{
return settings ( ) - > loadValue ( KEY_EXECUTIONLOG_ENABLED , false ) . toBool ( ) ;
}
void MainWindow : : setExecutionLogEnabled ( bool value )
{
settings ( ) - > storeValue ( KEY_EXECUTIONLOG_ENABLED , value ) ;
}
int MainWindow : : executionLogMsgTypes ( ) const
{
// as default value we need all the bits set
// -1 is considered the portable way to achieve that
return settings ( ) - > loadValue ( KEY_EXECUTIONLOG_TYPES , - 1 ) . toInt ( ) ;
}
void MainWindow : : setExecutionLogMsgTypes ( const int value )
{
m_executionLog - > showMsgTypes ( static_cast < Log : : MsgTypes > ( value ) ) ;
settings ( ) - > storeValue ( KEY_EXECUTIONLOG_TYPES , value ) ;
}
2016-04-17 22:56:51 +03:00
bool MainWindow : : isNotificationsEnabled ( ) const
{
return settings ( ) - > loadValue ( KEY_NOTIFICATIONS_ENABLED , true ) . toBool ( ) ;
}
void MainWindow : : setNotificationsEnabled ( bool value )
{
settings ( ) - > storeValue ( KEY_NOTIFICATIONS_ENABLED , value ) ;
}
bool MainWindow : : isTorrentAddedNotificationsEnabled ( ) const
{
return settings ( ) - > loadValue ( KEY_NOTIFICATIONS_TORRENTADDED , false ) . toBool ( ) ;
}
void MainWindow : : setTorrentAddedNotificationsEnabled ( bool value )
{
settings ( ) - > storeValue ( KEY_NOTIFICATIONS_TORRENTADDED , value ) ;
}
2016-11-13 23:46:17 +03:00
bool MainWindow : : isDownloadTrackerFavicon ( ) const
{
return settings ( ) - > loadValue ( KEY_DOWNLOAD_TRACKER_FAVICON , true ) . toBool ( ) ;
}
void MainWindow : : setDownloadTrackerFavicon ( bool value )
{
m_transferListFiltersWidget - > setDownloadTrackerFavicon ( value ) ;
settings ( ) - > storeValue ( KEY_DOWNLOAD_TRACKER_FAVICON , value ) ;
}
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
2016-01-24 13:16:25 +03:00
QAction * iconsOnly = new QAction ( tr ( " Icons Only " ) , m_toolbarMenu ) ;
2017-07-16 07:10:13 +03:00
connect ( iconsOnly , & QAction : : triggered , this , & MainWindow : : toolbarIconsOnly ) ;
2016-01-24 13:16:25 +03:00
QAction * textOnly = new QAction ( tr ( " Text Only " ) , m_toolbarMenu ) ;
2017-07-16 07:10:13 +03:00
connect ( textOnly , & QAction : : triggered , this , & MainWindow : : toolbarTextOnly ) ;
2016-01-24 13:16:25 +03:00
QAction * textBesideIcons = new QAction ( tr ( " Text Alongside Icons " ) , m_toolbarMenu ) ;
2017-07-16 07:10:13 +03:00
connect ( textBesideIcons , & QAction : : triggered , this , & MainWindow : : toolbarTextBeside ) ;
2016-01-24 13:16:25 +03:00
QAction * textUnderIcons = new QAction ( tr ( " Text Under Icons " ) , m_toolbarMenu ) ;
2017-07-16 07:10:13 +03:00
connect ( textUnderIcons , & QAction : : triggered , this , & MainWindow : : toolbarTextUnder ) ;
2016-01-24 13:16:25 +03:00
QAction * followSystemStyle = new QAction ( tr ( " Follow System Style " ) , m_toolbarMenu ) ;
2017-07-16 07:10:13 +03:00
connect ( followSystemStyle , & QAction : : triggered , this , & MainWindow : : toolbarFollowSystem ) ;
2016-01-24 13:16:25 +03:00
m_toolbarMenu - > addAction ( iconsOnly ) ;
m_toolbarMenu - > addAction ( textOnly ) ;
m_toolbarMenu - > addAction ( textBesideIcons ) ;
m_toolbarMenu - > addAction ( textUnderIcons ) ;
m_toolbarMenu - > addAction ( followSystemStyle ) ;
QActionGroup * 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 ) ;
const Qt : : ToolButtonStyle 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 ) ;
2014-10-18 18:18:58 +04:00
switch ( buttonStyle ) {
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 ( )
{
CookiesDialog ( this ) . exec ( ) ;
}
2014-10-18 18:18:58 +04:00
void MainWindow : : toolbarMenuRequested ( QPoint point )
{
2016-01-24 13:16:25 +03:00
m_toolbarMenu - > exec ( m_ui - > toolBar - > mapToGlobal ( point ) ) ;
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 ) ;
}
2014-12-20 20:53:58 +03:00
void MainWindow : : defineUILockPassword ( )
{
2016-01-24 13:16:25 +03:00
QString oldPassMd5 = Preferences : : instance ( ) - > getUILockPasswordMD5 ( ) ;
if ( oldPassMd5 . isNull ( ) )
oldPassMd5 = " " ;
2014-12-20 20:53:58 +03:00
bool ok = false ;
2016-01-24 13:16:25 +03:00
QString newClearPassword = AutoExpandableDialog : : getText ( this , tr ( " UI lock password " ) , tr ( " Please type the UI lock password: " ) , QLineEdit : : Password , oldPassMd5 , & ok ) ;
2014-12-20 20:53:58 +03:00
if ( ok ) {
2016-01-24 13:16:25 +03:00
newClearPassword = newClearPassword . trimmed ( ) ;
if ( newClearPassword . size ( ) < 3 ) {
2014-12-20 20:53:58 +03:00
QMessageBox : : warning ( this , tr ( " Invalid password " ) , tr ( " The password should contain at least 3 characters " ) ) ;
}
2016-01-24 13:16:25 +03:00
else {
if ( newClearPassword ! = oldPassMd5 )
Preferences : : instance ( ) - > setUILockPassword ( newClearPassword ) ;
QMessageBox : : information ( this , tr ( " Password update " ) , tr ( " The UI lock password has been successfully updated " ) ) ;
}
2010-08-19 20:30:13 +04:00
}
}
2014-12-20 20:53:58 +03:00
void MainWindow : : clearUILockPassword ( )
{
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 ) ;
if ( answer = = QMessageBox : : Yes )
Preferences : : instance ( ) - > clearUILockPassword ( ) ;
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 ( ) ;
2014-12-20 20:53:58 +03:00
// Check if there is a password
if ( pref - > getUILockPasswordMD5 ( ) . isEmpty ( ) ) {
// Ask for a password
bool ok = false ;
2016-01-24 13:16:25 +03:00
QString clearPassword = 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 ;
2016-01-24 13:16:25 +03:00
pref - > setUILockPassword ( clearPassword ) ;
2009-08-16 07:09:20 +04: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 )
{
if ( enable ) {
// RSS tab
2016-01-24 13:16:25 +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 ) ;
int indexTab = m_tabs - > addTab ( m_rssWidget , tr ( " RSS (%1) " ) . arg ( RSS : : Session : : instance ( ) - > rootFolder ( ) - > unreadCount ( ) ) ) ;
2017-06-12 22:47:28 +03:00
# ifndef Q_OS_MAC
2016-01-24 13:16:25 +03:00
m_tabs - > setTabIcon ( indexTab , GuiIconProvider : : instance ( ) - > getIcon ( " application-rss+xml " ) ) ;
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
}
2016-01-24 13:16:25 +03:00
else if ( m_rssWidget ) {
delete m_rssWidget ;
2015-01-26 17:00:23 +03:00
}
2014-12-20 20:53:58 +03:00
}
void MainWindow : : displaySearchTab ( bool enable )
{
Preferences : : instance ( ) - > setSearchEnabled ( enable ) ;
if ( enable ) {
// RSS tab
2016-01-24 13:16:25 +03:00
if ( ! m_searchWidget ) {
m_searchWidget = new SearchWidget ( this ) ;
2017-06-12 22:47:28 +03:00
m_tabs - > insertTab ( 1 , m_searchWidget ,
# ifndef Q_OS_MAC
GuiIconProvider : : instance ( ) - > getIcon ( " edit-find " ) ,
# endif
tr ( " Search " ) ) ;
2014-12-20 20:53:58 +03:00
}
2010-06-22 17:58:22 +04:00
}
2016-01-24 13:16:25 +03:00
else if ( m_searchWidget ) {
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
{
2016-01-24 13:16:25 +03:00
QDesktopServices : : openUrl ( QUrl ( " http://doc.qbittorrent.org " ) ) ;
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
2016-01-24 13:16:25 +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 ;
}
else {
2016-01-24 13:16:25 +03:00
m_searchFilterAction - > setVisible ( false ) ;
2014-12-20 20:53:58 +03:00
}
2016-01-24 13:16:25 +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 ( ) ) ;
// Splitter size
2016-01-24 13:16:25 +03:00
pref - > setMainVSplitterState ( m_splitter - > saveState ( ) ) ;
m_propertiesWidget - > saveSettings ( ) ;
2009-11-06 17:30:14 +03:00
}
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 ;
2017-06-12 22:47:28 +03:00
# ifndef Q_OS_MAC
2016-01-24 13:16:25 +03:00
if ( m_systrayCreator )
m_systrayCreator - > stop ( ) ;
2017-06-12 22:47:28 +03:00
# endif
2016-01-24 13:16:25 +03:00
if ( m_preventTimer )
m_preventTimer - > stop ( ) ;
2015-05-03 01:21:06 +03:00
# if (defined(Q_OS_WIN) || defined(Q_OS_MAC))
2016-01-24 13:16:25 +03:00
m_programUpdateTimer - > stop ( ) ;
2015-05-03 01:21:06 +03:00
# endif
2016-03-13 07:51:27 +03:00
2016-01-24 13:16:25 +03:00
delete m_searchFilterAction ;
2016-03-13 07:51:27 +03:00
// remove all child widgets
2017-01-08 03:46:01 +03:00
while ( QWidget * 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 ;
2014-12-20 20:53:58 +03:00
const QByteArray splitterState = pref - > getMainVSplitterState ( ) ;
if ( splitterState . isEmpty ( ) )
// Default sizes
2016-01-24 13:16:25 +03:00
m_splitter - > setSizes ( { 120 , m_splitter - > width ( ) - 120 } ) ;
2014-12-20 20:53:58 +03:00
else
2016-01-24 13:16:25 +03:00
m_splitter - > restoreState ( splitterState ) ;
2010-12-04 12:37:13 +03:00
}
2014-12-20 20:53:58 +03:00
void MainWindow : : balloonClicked ( )
{
if ( isHidden ( ) ) {
2016-01-24 13:16:25 +03:00
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
{
showNotificationBaloon ( tr ( " Error " ) , tr ( " Failed to add torrent: %1 " ) . arg ( error ) ) ;
}
2016-04-17 22:56:51 +03:00
// called when a torrent was added
2016-04-30 01:38:24 +03:00
void MainWindow : : torrentNew ( BitTorrent : : TorrentHandle * const torrent ) const
2016-04-17 22:56:51 +03:00
{
if ( isTorrentAddedNotificationsEnabled ( ) )
showNotificationBaloon ( tr ( " Torrent added " ) , tr ( " '%1' was added. " , " e.g: xxx.avi was added. " ) . arg ( torrent - > name ( ) ) ) ;
}
2009-11-06 17:30:14 +03:00
// called when a torrent has finished
2015-04-19 18:17:47 +03:00
void MainWindow : : finishedTorrent ( BitTorrent : : TorrentHandle * const torrent ) const
2014-12-20 20:53:58 +03:00
{
2015-08-08 16:19:46 +03:00
showNotificationBaloon ( tr ( " Download completion " ) , 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
2015-04-19 18:17:47 +03:00
void MainWindow : : fullDiskError ( BitTorrent : : TorrentHandle * const torrent , QString msg ) const
2014-12-20 20:53:58 +03:00
{
2015-08-08 16:19:46 +03:00
showNotificationBaloon ( tr ( " I/O Error " , " i.e: Input/Output Error " ) , tr ( " An I/O error occurred for torrent '%1'. \n Reason: %2 " , " e.g: An error occurred for torrent 'xxx.avi'. \n Reason: disk is full. " ) . arg ( torrent - > name ( ) ) . arg ( 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-01-25 12:33:13 +03:00
m_ui - > actionDownloadFromURL - > setShortcut ( Qt : : CTRL + Qt : : SHIFT + Qt : : Key_O ) ;
m_ui - > actionExit - > setShortcut ( Qt : : CTRL + Qt : : Key_Q ) ;
2015-01-26 17:00:23 +03:00
2017-01-25 12:33:13 +03:00
QShortcut * switchTransferShortcut = new QShortcut ( Qt : : ALT + Qt : : Key_1 , this ) ;
2017-07-16 07:10:13 +03:00
connect ( switchTransferShortcut , & QShortcut : : activated , this , & MainWindow : : displayTransferTab ) ;
using Func = void ( MainWindow : : * ) ( ) ;
2017-01-25 12:33:13 +03:00
QShortcut * switchSearchShortcut = new QShortcut ( Qt : : ALT + Qt : : Key_2 , this ) ;
2017-07-16 07:10:13 +03:00
connect ( switchSearchShortcut , & QShortcut : : activated , this , static_cast < Func > ( & MainWindow : : displaySearchTab ) ) ;
2017-01-25 12:33:13 +03:00
QShortcut * switchRSSShortcut = new QShortcut ( Qt : : ALT + Qt : : Key_3 , this ) ;
2017-07-16 07:10:13 +03:00
connect ( switchRSSShortcut , & QShortcut : : activated , this , static_cast < Func > ( & MainWindow : : displayRSSTab ) ) ;
2017-01-25 12:33:13 +03:00
QShortcut * switchExecutionLogShortcut = new QShortcut ( Qt : : ALT + Qt : : Key_4 , this ) ;
2017-07-16 07:10:13 +03:00
connect ( switchExecutionLogShortcut , & QShortcut : : activated , this , & MainWindow : : displayExecutionLogTab ) ;
2016-11-11 17:32:58 +03:00
QShortcut * switchSearchFilterShortcut = new QShortcut ( QKeySequence : : Find , this ) ;
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 ) ;
2017-01-25 12:33:13 +03:00
m_ui - > actionOptions - > setShortcut ( Qt : : ALT + Qt : : Key_O ) ;
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 - > actionBottomPriority - > setShortcut ( Qt : : CTRL + Qt : : SHIFT + Qt : : Key_Minus ) ;
m_ui - > actionDecreasePriority - > setShortcut ( Qt : : CTRL + Qt : : Key_Minus ) ;
m_ui - > actionIncreasePriority - > setShortcut ( Qt : : CTRL + Qt : : Key_Plus ) ;
m_ui - > actionTopPriority - > setShortcut ( Qt : : CTRL + Qt : : SHIFT + Qt : : Key_Plus ) ;
2013-09-21 11:59:58 +04:00
# ifdef Q_OS_MAC
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
{
2017-01-26 22:01:19 +03:00
if ( ! m_searchWidget ) {
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
{
2017-01-26 22:01:19 +03:00
if ( ! m_rssWidget ) {
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
{
2017-01-26 22:01:19 +03:00
if ( ! m_executionLog ) {
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
2015-04-19 18:17:47 +03:00
void MainWindow : : askRecursiveTorrentDownloadConfirmation ( BitTorrent : : TorrentHandle * 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 ;
// Get Torrent name
2016-01-24 13:16:25 +03:00
QString torrentName = torrent - > name ( ) ;
2015-11-11 06:19:16 +03:00
QMessageBox confirmBox ( QMessageBox : : Question , tr ( " Recursive download confirmation " ) , tr ( " The torrent '%1' contains torrent files, do you want to proceed with their download? " ) . arg ( torrentName ) , QMessageBox : : NoButton , this ) ;
2014-12-20 20:53:58 +03:00
QPushButton * yes = confirmBox . addButton ( tr ( " Yes " ) , QMessageBox : : YesRole ) ;
/*QPushButton *no = */ confirmBox . addButton ( tr ( " No " ) , QMessageBox : : NoRole ) ;
QPushButton * never = confirmBox . addButton ( tr ( " Never " ) , QMessageBox : : NoRole ) ;
confirmBox . exec ( ) ;
2015-04-19 18:17:47 +03:00
if ( confirmBox . clickedButton ( ) = = yes )
BitTorrent : : Session : : instance ( ) - > recursiveTorrentDownload ( torrent - > hash ( ) ) ;
else if ( confirmBox . clickedButton ( ) = = never )
2014-12-20 20:53:58 +03:00
pref - > disableRecursiveDownload ( ) ;
}
void MainWindow : : handleDownloadFromUrlFailure ( QString url , QString reason ) const
{
// Display a message box
2015-08-08 16:19:46 +03:00
showNotificationBaloon ( tr ( " URL download error " ) , tr ( " Couldn't download file at URL '%1', reason: %2. " ) . arg ( url ) . arg ( reason ) ) ;
2014-12-20 20:53:58 +03:00
}
2016-01-24 13:16:25 +03:00
void MainWindow : : on_actionSetGlobalUploadLimit_triggered ( )
2014-12-20 20:53:58 +03:00
{
2015-10-17 17:41:53 +03:00
qDebug ( ) < < Q_FUNC_INFO ;
2015-10-26 11:38:54 +03:00
2016-05-01 11:05:52 +03:00
BitTorrent : : Session * const session = BitTorrent : : Session : : instance ( ) ;
2016-10-30 03:36:47 +03:00
bool ok = false ;
2016-05-01 11:05:52 +03:00
const long newLimit = SpeedLimitDialog : : askSpeedLimit (
2015-10-26 11:38:54 +03:00
this , & ok , tr ( " Global Upload Speed Limit " ) , session - > uploadSpeedLimit ( ) ) ;
2014-12-20 20:53:58 +03:00
if ( ok ) {
2016-01-24 13:16:25 +03:00
qDebug ( " Setting global upload rate limit to %.1fKb/s " , newLimit / 1024. ) ;
2016-05-01 11:05:52 +03:00
session - > setUploadSpeedLimit ( newLimit ) ;
2014-12-20 20:53:58 +03:00
}
}
2016-01-24 13:16:25 +03:00
void MainWindow : : on_actionSetGlobalDownloadLimit_triggered ( )
2014-12-20 20:53:58 +03:00
{
2015-10-17 17:41:53 +03:00
qDebug ( ) < < Q_FUNC_INFO ;
2015-10-26 11:38:54 +03:00
2016-05-01 11:05:52 +03:00
BitTorrent : : Session * const session = BitTorrent : : Session : : instance ( ) ;
2016-10-30 03:36:47 +03:00
bool ok = false ;
2016-05-01 11:05:52 +03:00
const long newLimit = SpeedLimitDialog : : askSpeedLimit (
2015-10-26 11:38:54 +03:00
this , & ok , tr ( " Global Download Speed Limit " ) , session - > downloadSpeedLimit ( ) ) ;
2014-12-20 20:53:58 +03:00
if ( ok ) {
2016-01-24 13:16:25 +03:00
qDebug ( " Setting global download rate limit to %.1fKb/s " , newLimit / 1024. ) ;
2016-05-01 11:05:52 +03:00
session - > setDownloadSpeedLimit ( newLimit ) ;
2014-12-20 20:53:58 +03:00
}
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
}
2017-01-08 03:46:01 +03:00
QWidget * MainWindow : : currentTabWidget ( ) const
2014-12-20 20:53:58 +03:00
{
if ( isMinimized ( ) | | ! isVisible ( ) )
return 0 ;
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 ;
else
2016-01-24 13:16:25 +03:00
m_unlockDlgShowing = true ;
2014-12-20 20:53:58 +03:00
bool ok = false ;
2016-01-24 13:16:25 +03:00
QString clearPassword = AutoExpandableDialog : : getText ( this , tr ( " UI lock password " ) , tr ( " Please type the UI lock password: " ) , QLineEdit : : Password , " " , & ok ) ;
m_unlockDlgShowing = false ;
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 ( ) ;
2016-01-24 13:16:25 +03:00
QString realPassMd5 = pref - > getUILockPasswordMD5 ( ) ;
2014-12-20 20:53:58 +03:00
QCryptographicHash md5 ( QCryptographicHash : : Md5 ) ;
2016-01-24 13:16:25 +03:00
md5 . addData ( clearPassword . toLocal8Bit ( ) ) ;
QString passwordMd5 = md5 . result ( ) . toHex ( ) ;
if ( realPassMd5 = = passwordMd5 ) {
m_uiLocked = false ;
2014-12-20 20:53:58 +03:00
pref - > setUILocked ( false ) ;
2016-01-24 13:16:25 +03:00
m_trayIconMenu - > setEnabled ( true ) ;
2014-12-20 20:53:58 +03:00
return true ;
}
QMessageBox : : warning ( this , tr ( " Invalid password " ) , tr ( " The password is invalid " ) ) ;
2014-10-20 21:34:46 +04:00
return false ;
2014-12-20 20:53:58 +03:00
}
void MainWindow : : notifyOfUpdate ( QString )
{
// 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 ;
m_executableWatcher = 0 ;
2010-08-23 23:42:15 +04:00
}
2017-06-12 22:47:28 +03:00
# ifndef Q_OS_MAC
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
{
2017-05-02 10:12:24 +03:00
switch ( reason ) {
case QSystemTrayIcon : : Trigger : {
2014-12-20 20:53:58 +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 ( ) ;
}
else {
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
}
2017-06-12 22:47:28 +03:00
# endif
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 )
2017-05-30 09:00:00 +03:00
m_aboutDlg - > activateWindow ( ) ;
2014-12-20 20:53:58 +03:00
else
2016-01-24 13:16:25 +03:00
m_aboutDlg = new about ( this ) ;
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 )
2017-05-30 09:00:00 +03:00
m_statsDlg - > activateWindow ( ) ;
2014-12-20 20:53:58 +03:00
else
2016-01-24 13:16:25 +03:00
m_statsDlg = new StatsDialog ( this ) ;
2013-11-17 01:16:24 +04:00
}
2014-12-20 20:53:58 +03:00
void MainWindow : : showEvent ( QShowEvent * e )
{
qDebug ( " ** Show Event ** " ) ;
2011-01-21 21:38:58 +03:00
2016-01-24 13:16:25 +03:00
if ( currentTabWidget ( ) = = m_transferListWidget )
m_propertiesWidget - > loadDynamicData ( ) ;
2011-01-22 22:51:06 +03:00
2014-12-20 20:53:58 +03:00
e - > accept ( ) ;
2011-01-22 22:51:06 +03:00
2014-12-20 20:53:58 +03:00
// Make sure the window is initially centered
if ( ! m_posInitialized ) {
2015-05-06 14:53:27 +03:00
move ( Utils : : Misc : : screenCenter ( this ) ) ;
2014-12-20 20:53:58 +03:00
m_posInitialized = true ;
}
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 ( ) ;
2017-06-12 22:47:28 +03:00
# ifdef Q_OS_MAC
if ( ! m_forceExit ) {
hide ( ) ;
e - > accept ( ) ;
return ;
}
# else
2014-12-20 20:53:58 +03:00
const bool goToSystrayOnExit = pref - > closeToTray ( ) ;
2016-01-24 13:16:25 +03:00
if ( ! m_forceExit & & m_systrayIcon & & goToSystrayOnExit & & ! this - > isHidden ( ) ) {
2014-12-20 20:53:58 +03:00
hide ( ) ;
e - > accept ( ) ;
2009-11-06 17:30:14 +03:00
return ;
2007-11-16 21:53:21 +03:00
}
2017-06-12 22:47:28 +03:00
# endif
2015-04-21 12:58:21 +03:00
2015-04-19 18:17:47 +03:00
if ( pref - > confirmOnExit ( ) & & BitTorrent : : Session : : instance ( ) - > hasActiveTorrents ( ) ) {
2016-01-24 13:16:25 +03:00
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
tr ( " Some files are currently transferring. " ) + " \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 ( ) ;
2016-01-24 13:16:25 +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
2017-01-08 03:46:01 +03:00
// abort search if any
2016-01-24 13:16:25 +03:00
if ( m_searchWidget )
delete m_searchWidget ;
2015-03-07 23:54:31 +03:00
2014-12-20 20:53:58 +03:00
hide ( ) ;
2017-06-12 22:47:28 +03:00
# ifndef Q_OS_MAC
2015-04-21 12:58:21 +03:00
// Hide tray icon
2016-01-24 13:16:25 +03:00
if ( m_systrayIcon )
m_systrayIcon - > hide ( ) ;
2017-06-12 22:47:28 +03:00
# endif
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
{
createTorrentTriggered ( ) ;
}
void MainWindow : : createTorrentTriggered ( const QString & path )
2014-12-20 20:53:58 +03:00
{
2016-04-30 13:43:41 +03:00
if ( m_createTorrentDlg ) {
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
2016-04-28 14:06:02 +03:00
m_createTorrentDlg = new TorrentCreatorDlg ( this , path ) ;
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
{
2017-06-12 22:47:28 +03:00
# ifndef Q_OS_MAC
2017-01-08 03:46:01 +03:00
switch ( e - > type ( ) ) {
2014-12-20 20:53:58 +03:00
case QEvent : : WindowStateChange : {
qDebug ( " Window change event " ) ;
2017-01-08 03:46:01 +03:00
// Now check to see if the window is minimised
2014-12-20 20:53:58 +03:00
if ( isMinimized ( ) ) {
qDebug ( " minimisation " ) ;
2016-01-24 13:16:25 +03:00
if ( m_systrayIcon & & Preferences : : instance ( ) - > 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
2016-01-24 13:16:25 +03:00
bool hasModalWindow = false ;
2014-12-20 20:53:58 +03:00
foreach ( QWidget * widget , QApplication : : allWidgets ( ) ) {
if ( widget - > isModal ( ) ) {
2016-01-24 13:16:25 +03:00
hasModalWindow = true ;
2014-12-20 20:53:58 +03:00
break ;
}
}
// Iconify if there is no modal window
2016-01-24 13:16:25 +03:00
if ( ! hasModalWindow ) {
2014-12-20 20:53:58 +03:00
qDebug ( " Minimize to Tray enabled, hiding! " ) ;
e - > ignore ( ) ;
QTimer : : singleShot ( 0 , this , SLOT ( hide ( ) ) ) ;
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
}
2014-12-20 20:53:58 +03:00
case QEvent : : ToolBarChange : {
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 ;
}
2017-06-12 22:47:28 +03:00
# endif
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 ;
if ( event - > mimeData ( ) - > hasUrls ( ) ) {
const QList < QUrl > urls = event - > mimeData ( ) - > urls ( ) ;
foreach ( const QUrl & url , urls ) {
if ( ! url . isEmpty ( ) ) {
if ( url . scheme ( ) . compare ( " file " , Qt : : CaseInsensitive ) = = 0 )
files < < url . toLocalFile ( ) ;
else
files < < url . toString ( ) ;
}
}
2009-11-06 17:30:14 +03:00
}
2014-12-20 20:53:58 +03:00
else {
2016-01-24 13:16:25 +03:00
files = event - > mimeData ( ) - > text ( ) . split ( ' \n ' ) ;
2010-07-23 02:19:42 +04:00
}
2015-04-19 18:17:47 +03:00
2016-04-28 14:06:02 +03:00
// differentiate ".torrent" files and others
QStringList torrentFiles , otherFiles ;
foreach ( const QString & file , files ) {
2016-04-29 12:25:15 +03:00
if ( file . endsWith ( C_TORRENT_FILE_EXTENSION , Qt : : CaseInsensitive ) )
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 ( ) ;
2016-04-28 14:06:02 +03:00
foreach ( const QString & file , torrentFiles ) {
2017-08-13 13:56:03 +03:00
qDebug ( " Dropped file %s on download list " , qUtf8Printable ( file ) ) ;
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
foreach ( const QString & file , otherFiles ) {
createTorrentTriggered ( file ) ;
// currently only hande the first entry
// 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 )
{
foreach ( const QString & mime , event - > mimeData ( ) - > formats ( ) )
qDebug ( " mimeData: %s " , mime . toLocal8Bit ( ) . data ( ) ) ;
2016-01-24 13:16:25 +03:00
if ( event - > mimeData ( ) - > hasFormat ( " text/plain " ) | | event - > mimeData ( ) - > hasFormat ( " text/uri-list " ) )
2014-12-20 20:53:58 +03:00
event - > acceptProposedAction ( ) ;
2009-11-06 17:30:14 +03:00
}
2017-06-12 22:47:28 +03:00
# ifdef Q_OS_MAC
static MainWindow * dockMainWindowHandle ;
static bool dockClickHandler ( id self , SEL cmd , . . . )
{
Q_UNUSED ( self )
Q_UNUSED ( cmd )
2017-07-16 06:47:53 +03:00
2017-06-12 22:47:28 +03:00
qDebug ( " Dock icon clicked! " ) ;
2017-07-16 06:47:53 +03:00
2017-06-12 22:47:28 +03:00
if ( dockMainWindowHandle & & ! dockMainWindowHandle - > isVisible ( ) ) {
dockMainWindowHandle - > activate ( ) ;
}
2017-07-16 06:47:53 +03:00
2017-06-12 22:47:28 +03:00
// Return NO (false) to suppress the default OS X actions
return false ;
}
void MainWindow : : setupDockClickHandler ( )
{
Class cls = objc_getClass ( " NSApplication " ) ;
objc_object * appInst = objc_msgSend ( reinterpret_cast < objc_object * > ( cls ) , sel_registerName ( " sharedApplication " ) ) ;
2017-07-16 06:47:53 +03:00
2017-06-12 22:47:28 +03:00
if ( ! appInst )
return ;
dockMainWindowHandle = this ;
objc_object * delegate = objc_msgSend ( appInst , sel_registerName ( " delegate " ) ) ;
Class delClass = reinterpret_cast < Class > ( objc_msgSend ( delegate , sel_registerName ( " class " ) ) ) ;
SEL shouldHandle = sel_registerName ( " applicationShouldHandleReopen:hasVisibleWindows: " ) ;
if ( class_getInstanceMethod ( delClass , shouldHandle ) ) {
if ( class_replaceMethod ( delClass , shouldHandle , reinterpret_cast < IMP > ( dockClickHandler ) , " B@: " ) )
qDebug ( " Registered dock click handler (replaced original method) " ) ;
else
qWarning ( " Failed to replace method for dock click handler " ) ;
}
else {
if ( class_addMethod ( delClass , shouldHandle , reinterpret_cast < IMP > ( dockClickHandler ) , " B@: " ) )
qDebug ( " Registered dock click handler " ) ;
else
qWarning ( " Failed to register dock click handler " ) ;
}
}
# endif
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 =
2015-10-26 10:45:14 +03:00
QFileDialog : : getOpenFileNames ( this , tr ( " Open Torrent Files " ) , pref - > getMainLastDir ( ) ,
2016-04-29 12:25:15 +03:00
tr ( " Torrent Files " ) + " (* " + C_TORRENT_FILE_EXTENSION + ' ) ' ) ;
2015-10-26 10:45:14 +03:00
2016-02-09 11:56:48 +03:00
const bool useTorrentAdditionDialog = AddNewTorrentDialog : : isEnabled ( ) ;
2015-06-16 09:08:25 +03:00
if ( ! pathsList . isEmpty ( ) ) {
foreach ( QString file , pathsList ) {
2017-08-13 13:56:03 +03:00
qDebug ( " Dropped file %s on download list " , qUtf8Printable ( file ) ) ;
2015-06-16 09:08:25 +03:00
if ( useTorrentAdditionDialog )
AddNewTorrentDialog : : show ( file , this ) ;
else
BitTorrent : : Session : : instance ( ) - > addTorrent ( file ) ;
}
2015-04-19 18:17:47 +03:00
2015-06-16 09:08:25 +03:00
// Save last dir to remember it
2016-01-24 13:16:25 +03:00
QStringList topDir = Utils : : Fs : : fromNativePath ( pathsList . at ( 0 ) ) . split ( " / " ) ;
topDir . removeLast ( ) ;
pref - > setMainLastDir ( Utils : : Fs : : fromNativePath ( topDir . join ( " / " ) ) ) ;
2015-06-16 09:08:25 +03:00
}
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
{
2016-01-24 13:16:25 +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 ( )
{
loadPreferences ( ) ;
2009-11-15 13:00:07 +03:00
}
2017-05-25 17:50:05 +03:00
void MainWindow : : showStatusBar ( bool show )
{
2017-05-28 20:59:52 +03:00
if ( ! show ) {
// Remove status bar
setStatusBar ( nullptr ) ;
}
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 ) ;
}
}
2016-01-24 13:16:25 +03:00
void MainWindow : : loadPreferences ( bool configureSession )
2014-12-20 20:53:58 +03:00
{
2015-01-06 04:34:10 +03:00
Logger : : instance ( ) - > addMessage ( tr ( " Options were saved successfully. " ) ) ;
2017-01-08 03:46:01 +03:00
const Preferences * const pref = Preferences : : instance ( ) ;
2017-06-12 22:47:28 +03:00
# ifndef Q_OS_MAC
2014-12-20 20:53:58 +03:00
const bool newSystrayIntegration = pref - > systrayIntegration ( ) ;
2016-01-24 13:16:25 +03:00
m_ui - > actionLock - > setVisible ( newSystrayIntegration ) ;
if ( newSystrayIntegration ! = ( m_systrayIcon ! = 0 ) ) {
2014-12-20 20:53:58 +03:00
if ( newSystrayIntegration ) {
// create the trayicon
if ( ! QSystemTrayIcon : : isSystemTrayAvailable ( ) ) {
2016-01-24 13:16:25 +03:00
if ( ! configureSession ) { // Program startup
m_systrayCreator = new QTimer ( this ) ;
2017-07-16 07:10:13 +03:00
connect ( m_systrayCreator . data ( ) , & QTimer : : timeout , this , & MainWindow : : createSystrayDelayed ) ;
2016-01-24 13:16:25 +03:00
m_systrayCreator - > setSingleShot ( true ) ;
m_systrayCreator - > start ( 2000 ) ;
2014-12-20 20:53:58 +03:00
qDebug ( " Info: System tray is unavailable, trying again later. " ) ;
}
else {
qDebug ( " Warning: System tray is unavailable. " ) ;
}
}
else {
createTrayIcon ( ) ;
}
}
else {
// Destroy trayicon
2016-01-24 13:16:25 +03:00
delete m_systrayIcon ;
delete m_trayIconMenu ;
2009-11-18 21:45:06 +03:00
}
2009-11-14 22:08:28 +03:00
}
2014-12-20 20:53:58 +03:00
// Reload systray icon
2016-01-24 13:16:25 +03:00
if ( newSystrayIntegration & & m_systrayIcon )
m_systrayIcon - > setIcon ( getSystrayIcon ( ) ) ;
2017-06-12 22:47:28 +03:00
# endif
2014-12-20 20:53:58 +03:00
// General
if ( pref - > isToolbarDisplayed ( ) ) {
2016-01-24 13:16:25 +03:00
m_ui - > toolBar - > setVisible ( true ) ;
2014-12-20 20:53:58 +03:00
}
else {
// 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
2016-01-24 13:16:25 +03:00
if ( pref - > preventFromSuspend ( ) & & ! m_preventTimer - > isActive ( ) ) {
m_preventTimer - > start ( PREVENT_SUSPEND_INTERVAL ) ;
2014-12-20 20:53:58 +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
2016-05-01 11:05:52 +03:00
if ( BitTorrent : : Session : : instance ( ) - > isQueueingSystemEnabled ( ) ) {
2016-01-24 13:16:25 +03:00
if ( ! m_ui - > actionDecreasePriority - > isVisible ( ) ) {
m_transferListWidget - > hidePriorityColumn ( false ) ;
m_ui - > actionDecreasePriority - > setVisible ( true ) ;
m_ui - > actionIncreasePriority - > setVisible ( true ) ;
m_ui - > actionTopPriority - > setVisible ( true ) ;
m_ui - > actionBottomPriority - > setVisible ( true ) ;
2017-06-12 22:47:28 +03:00
# ifndef Q_OS_MAC
2016-01-24 13:16:25 +03:00
m_prioSeparator - > setVisible ( true ) ;
2017-06-12 22:47:28 +03:00
# endif
2016-01-24 13:16:25 +03:00
m_prioSeparatorMenu - > setVisible ( true ) ;
2014-12-20 20:53:58 +03:00
}
2009-08-16 07:09:20 +04:00
}
2014-12-20 20:53:58 +03:00
else {
2016-01-24 13:16:25 +03:00
if ( m_ui - > actionDecreasePriority - > isVisible ( ) ) {
m_transferListWidget - > hidePriorityColumn ( true ) ;
m_ui - > actionDecreasePriority - > setVisible ( false ) ;
m_ui - > actionIncreasePriority - > setVisible ( false ) ;
m_ui - > actionTopPriority - > setVisible ( false ) ;
m_ui - > actionBottomPriority - > setVisible ( false ) ;
2017-06-12 22:47:28 +03:00
# ifndef Q_OS_MAC
2016-01-24 13:16:25 +03:00
m_prioSeparator - > setVisible ( false ) ;
2017-06-12 22:47:28 +03:00
# endif
2016-01-24 13:16:25 +03:00
m_prioSeparatorMenu - > 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
2013-09-21 11:59:58 +04:00
# if defined(Q_OS_WIN) || defined(Q_OS_MAC)
2015-12-13 17:41:58 +03:00
if ( pref - > isUpdateCheckEnabled ( ) & & ! m_wasUpdateCheckEnabled ) {
m_wasUpdateCheckEnabled = true ;
2014-12-20 20:53:58 +03:00
checkProgramUpdate ( ) ;
2015-12-13 17:41:58 +03:00
}
else if ( ! pref - > isUpdateCheckEnabled ( ) & & m_wasUpdateCheckEnabled ) {
m_wasUpdateCheckEnabled = false ;
2016-01-24 13:16:25 +03:00
m_programUpdateTimer - > stop ( ) ;
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
}
2017-01-08 03:46:01 +03:00
void MainWindow : : addUnauthenticatedTracker ( const QPair < BitTorrent : : TorrentHandle * , QString > & tracker )
2014-12-20 20:53:58 +03:00
{
// Trackers whose authentication was cancelled
2016-01-24 13:16:25 +03:00
if ( m_unauthenticatedTrackers . indexOf ( tracker ) < 0 )
m_unauthenticatedTrackers < < tracker ;
2009-11-06 17:30:14 +03:00
}
// Called when a tracker requires authentication
2015-04-19 18:17:47 +03:00
void MainWindow : : trackerAuthenticationRequired ( BitTorrent : : TorrentHandle * const torrent )
2014-12-20 20:53:58 +03:00
{
2017-05-01 20:27:07 +03:00
# if LIBTORRENT_VERSION_NUM < 10100
2016-01-24 13:16:25 +03:00
if ( m_unauthenticatedTrackers . indexOf ( qMakePair ( torrent , torrent - > currentTracker ( ) ) ) < 0 )
2014-12-20 20:53:58 +03:00
// Tracker login
2015-04-19 18:17:47 +03:00
new trackerLogin ( this , torrent ) ;
2017-05-01 20:27:07 +03:00
# else
Q_UNUSED ( torrent ) ;
# endif
2009-11-06 17:30:14 +03:00
}
// Check connection status and display right icon
2014-12-20 20:53:58 +03:00
void MainWindow : : updateGUI ( )
{
2017-04-29 14:45:30 +03:00
const BitTorrent : : SessionStatus & status = BitTorrent : : Session : : instance ( ) - > status ( ) ;
2015-04-19 18:17:47 +03:00
2014-12-20 20:53:58 +03:00
// update global informations
2017-06-12 22:47:28 +03:00
# ifndef Q_OS_MAC
2016-01-24 13:16:25 +03:00
if ( m_systrayIcon ) {
2017-06-12 22:47:28 +03:00
# ifdef Q_OS_UNIX
2014-12-20 20:53:58 +03:00
QString html = " <div style='background-color: #678db2; color: #fff;height: 18px; font-weight: bold; margin-bottom: 5px;'> " ;
html + = " qBittorrent " ;
html + = " </div> " ;
html + = " <div style='vertical-align: baseline; height: 18px;'> " ;
2017-04-29 14:45:30 +03:00
html + = " <img src=':/icons/skin/download.png' height='14'/> " + tr ( " DL speed: %1 " , " e.g: Download speed: 10 KiB/s " ) . arg ( Utils : : Misc : : friendlyUnit ( status . payloadDownloadRate , true ) ) ;
2014-12-20 20:53:58 +03:00
html + = " </div> " ;
html + = " <div style='vertical-align: baseline; height: 18px;'> " ;
2017-04-29 14:45:30 +03:00
html + = " <img src=':/icons/skin/seeding.png' height='14'/> " + tr ( " UP speed: %1 " , " e.g: Upload speed: 10 KiB/s " ) . arg ( Utils : : Misc : : friendlyUnit ( status . payloadUploadRate , true ) ) ;
2014-12-20 20:53:58 +03:00
html + = " </div> " ;
2010-03-30 15:35:20 +04:00
# else
2014-12-20 20:53:58 +03:00
// OSes such as Windows do not support html here
2017-04-29 14:45:30 +03:00
QString html = tr ( " DL speed: %1 " , " e.g: Download speed: 10 KiB/s " ) . arg ( Utils : : Misc : : friendlyUnit ( status . payloadDownloadRate , true ) ) ;
2014-12-20 20:53:58 +03:00
html + = " \n " ;
2017-04-29 14:45:30 +03:00
html + = tr ( " UP speed: %1 " , " e.g: Upload speed: 10 KiB/s " ) . arg ( Utils : : Misc : : friendlyUnit ( status . payloadUploadRate , true ) ) ;
2017-06-12 22:47:28 +03:00
# endif // Q_OS_UNIX
2016-01-24 13:16:25 +03:00
m_systrayIcon - > setToolTip ( html ) ; // tray icon
}
2017-06-12 22:47:28 +03:00
# else
if ( status . payloadDownloadRate > 0 )
QtMac : : setBadgeLabelText ( tr ( " %1/s " , " s is a shorthand for seconds " )
. arg ( Utils : : Misc : : friendlyUnit ( status . payloadDownloadRate ) ) ) ;
else if ( ! QtMac : : badgeLabelText ( ) . isEmpty ( ) )
QtMac : : setBadgeLabelText ( " " ) ;
# endif // Q_OS_MAC
2016-01-24 13:16:25 +03:00
if ( m_displaySpeedInTitle ) {
setWindowTitle ( tr ( " [D: %1, U: %2] qBittorrent %3 " , " D = Download; U = Upload; %3 is qBittorrent version " )
2017-04-29 14:45:30 +03:00
. arg ( Utils : : Misc : : friendlyUnit ( status . payloadDownloadRate , true ) )
. arg ( Utils : : Misc : : friendlyUnit ( status . payloadUploadRate , true ) )
2017-03-03 11:42:13 +03:00
. arg ( QBT_VERSION ) ) ;
2014-12-20 20:53:58 +03:00
}
2009-11-06 17:30:14 +03:00
}
2014-12-20 20:53:58 +03:00
void MainWindow : : showNotificationBaloon ( QString title , QString msg ) const
{
2016-04-17 22:56:51 +03:00
if ( ! isNotificationsEnabled ( ) ) return ;
2013-09-21 11:59:58 +04:00
# if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC)) && defined(QT_DBUS_LIB)
2014-12-20 20:53:58 +03:00
org : : freedesktop : : Notifications notifications ( " org.freedesktop.Notifications " ,
" /org/freedesktop/Notifications " ,
QDBusConnection : : sessionBus ( ) ) ;
// 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.
QVariantMap hints ;
hints [ " desktop-entry " ] = " qBittorrent " ;
QDBusPendingReply < uint > reply = notifications . Notify ( " qBittorrent " , 0 , " qbittorrent " , title ,
msg , QStringList ( ) , hints , - 1 ) ;
reply . waitForFinished ( ) ;
if ( ! reply . isError ( ) )
return ;
2017-06-12 22:47:28 +03:00
# elif (!defined(Q_OS_MAC))
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 ( ) ;
2016-01-24 13:16:25 +03:00
foreach ( QString url , urlList ) {
2017-01-08 03:46:01 +03:00
if ( ( ( url . size ( ) = = 40 ) & & ! url . contains ( QRegExp ( " [^0-9A-Fa-f] " ) ) )
| | ( ( url . size ( ) = = 32 ) & & ! url . contains ( QRegExp ( " [^2-7A-Za-z] " ) ) ) )
2014-12-20 20:53:58 +03:00
url = " magnet:?xt=urn:btih: " + url ;
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 *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2017-06-12 22:47:28 +03:00
# ifndef Q_OS_MAC
2014-12-20 20:53:58 +03:00
void MainWindow : : createSystrayDelayed ( )
{
static int timeout = 20 ;
if ( QSystemTrayIcon : : isSystemTrayAvailable ( ) ) {
// Ok, systray integration is now supported
// Create systray icon
createTrayIcon ( ) ;
2016-01-24 13:16:25 +03:00
delete m_systrayCreator ;
2014-12-20 20:53:58 +03:00
}
else {
if ( timeout ) {
// Retry a bit later
2016-01-24 13:16:25 +03:00
m_systrayCreator - > start ( 2000 ) ;
2014-12-20 20:53:58 +03:00
- - timeout ;
}
else {
// Timed out, apparently system really does not
// support systray icon
2016-01-24 13:16:25 +03:00
delete m_systrayCreator ;
2014-12-20 20:53:58 +03:00
// Disable it in program preferences to
2015-05-04 02:09:30 +03:00
// avoid trying at each startup
2014-12-20 20:53:58 +03:00
Preferences : : instance ( ) - > setSystrayIntegration ( false ) ;
}
2008-01-04 23:09:37 +03:00
}
2009-11-06 17:30:14 +03:00
}
2017-06-12 22:47:28 +03:00
void MainWindow : : updateTrayIconMenu ( )
2014-12-20 20:53:58 +03:00
{
2017-06-12 22:47:28 +03:00
m_ui - > actionToggleVisibility - > setText ( isVisible ( ) ? tr ( " Hide " ) : tr ( " Show " ) ) ;
2010-01-23 23:44:09 +03:00
}
2017-06-12 22:47:28 +03:00
void MainWindow : : createTrayIcon ( )
2012-05-20 17:51:32 +04:00
{
2017-06-12 22:47:28 +03:00
// Tray icon
m_systrayIcon = new QSystemTrayIcon ( getSystrayIcon ( ) , this ) ;
2017-07-16 06:47:53 +03:00
2017-06-12 22:47:28 +03:00
m_systrayIcon - > setContextMenu ( trayIconMenu ( ) ) ;
2017-07-16 07:10:13 +03:00
connect ( m_systrayIcon . data ( ) , & QSystemTrayIcon : : messageClicked , this , & MainWindow : : balloonClicked ) ;
2017-06-12 22:47:28 +03:00
// End of Icon Menu
2017-07-16 07:10:13 +03:00
connect ( m_systrayIcon . data ( ) , & QSystemTrayIcon : : activated , this , & MainWindow : : toggleVisibility ) ;
2017-06-12 22:47:28 +03:00
m_systrayIcon - > show ( ) ;
2012-05-20 17:51:32 +04:00
}
2017-06-12 22:47:28 +03:00
# endif
2012-05-20 17:51:32 +04:00
2017-01-08 03:46:01 +03:00
QMenu * MainWindow : : trayIconMenu ( )
2014-12-20 20:53:58 +03:00
{
2016-01-24 13:16:25 +03:00
if ( m_trayIconMenu ) return m_trayIconMenu ;
m_trayIconMenu = new QMenu ( this ) ;
2017-06-12 22:47:28 +03:00
# ifndef Q_OS_MAC
2017-07-16 07:10:13 +03:00
connect ( m_trayIconMenu . data ( ) , & QMenu : : aboutToShow , this , & MainWindow : : updateTrayIconMenu ) ;
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
2016-01-24 13:16:25 +03:00
m_trayIconMenu - > addAction ( m_ui - > actionOpen ) ;
m_trayIconMenu - > addAction ( m_ui - > actionDownloadFromURL ) ;
m_trayIconMenu - > addSeparator ( ) ;
2016-05-01 11:05:52 +03:00
const bool isAltBWEnabled = BitTorrent : : Session : : instance ( ) - > isAltGlobalSpeedLimitEnabled ( ) ;
2014-12-20 20:53:58 +03:00
updateAltSpeedsBtn ( isAltBWEnabled ) ;
2016-01-24 13:16:25 +03:00
m_ui - > actionUseAlternativeSpeedLimits - > setChecked ( isAltBWEnabled ) ;
m_trayIconMenu - > addAction ( m_ui - > actionUseAlternativeSpeedLimits ) ;
m_trayIconMenu - > addAction ( m_ui - > actionSetGlobalDownloadLimit ) ;
m_trayIconMenu - > addAction ( m_ui - > actionSetGlobalUploadLimit ) ;
m_trayIconMenu - > addSeparator ( ) ;
m_trayIconMenu - > addAction ( m_ui - > actionStartAll ) ;
m_trayIconMenu - > addAction ( m_ui - > actionPauseAll ) ;
2017-06-12 22:47:28 +03:00
# ifndef Q_OS_MAC
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
2016-01-24 13:16:25 +03:00
if ( m_uiLocked )
m_trayIconMenu - > setEnabled ( false ) ;
return m_trayIconMenu ;
}
2017-06-12 22:47:28 +03:00
void MainWindow : : updateAltSpeedsBtn ( 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 )
2017-05-30 09:00:00 +03:00
m_options - > activateWindow ( ) ;
2015-12-13 17:41:58 +03:00
else
2016-04-25 10:54:38 +03:00
m_options = new OptionsDialog ( this ) ;
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
{
2017-05-25 17:50:05 +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 ( )
{
2017-05-25 17:50:05 +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
}
2016-01-24 13:16:25 +03:00
void MainWindow : : on_actionSpeedInTitleBar_triggered ( )
2014-12-20 20:53:58 +03:00
{
2017-01-08 03:46:01 +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 )
2014-12-20 20:53:58 +03:00
updateGUI ( ) ;
else
2017-03-03 11:42:13 +03:00
setWindowTitle ( " 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
{
2016-01-24 13:16:25 +03:00
if ( ! m_hasPython & & m_ui - > actionSearchWidget - > isChecked ( ) ) {
2015-07-21 01:11:05 +03:00
int pythonVersion = Utils : : Misc : : pythonVersion ( ) ;
2014-09-14 22:58:20 +04:00
2014-12-20 20:53:58 +03:00
// Check if python is already in PATH
2015-07-21 01:11:05 +03:00
if ( pythonVersion > 0 )
2016-11-07 07:29:55 +03:00
// Prevent translators from messing with PATH
Logger : : instance ( ) - > addMessage ( tr ( " Python found in %1: %2 " , " Python found in PATH: /usr/local/bin:/usr/bin:/etc/bin " ) . arg ( " PATH " ) . arg ( qgetenv ( " PATH " ) . constData ( ) ) , Log : : INFO ) ;
2015-07-21 01:11:05 +03:00
# ifdef Q_OS_WIN
else if ( addPythonPathToEnv ( ) )
pythonVersion = Utils : : Misc : : pythonVersion ( ) ;
# endif
bool res = false ;
2017-07-06 01:07:09 +03:00
if ( ( pythonVersion = = 2 ) | | ( pythonVersion = = 3 ) ) {
// Check Python minimum requirement: 2.7.9 / 3.3.0
2015-07-25 15:26:56 +03:00
QString version = Utils : : Misc : : pythonVersionComplete ( ) ;
2015-07-21 01:11:05 +03:00
QStringList splitted = version . split ( ' . ' ) ;
2017-07-06 01:07:09 +03:00
if ( splitted . size ( ) > 2 ) {
2015-07-21 01:11:05 +03:00
int middleVer = splitted . at ( 1 ) . toInt ( ) ;
2017-07-06 01:07:09 +03:00
int lowerVer = splitted . at ( 2 ) . toInt ( ) ;
if ( ( ( pythonVersion = = 2 ) & & ( middleVer < 7 ) )
| | ( ( pythonVersion = = 2 ) & & ( middleVer = = 7 ) & & ( lowerVer < 9 ) )
| | ( ( pythonVersion = = 3 ) & & ( middleVer < 3 ) ) ) {
QMessageBox : : information ( this , tr ( " Old Python Interpreter " ) , tr ( " Your Python version (%1) is outdated. Please upgrade to latest version for search engines to work. \n Minimum requirement: 2.7.9 / 3.3.0. " ) . arg ( version ) ) ;
2016-01-24 13:16:25 +03:00
m_ui - > actionSearchWidget - > setChecked ( false ) ;
2015-07-21 01:11:05 +03:00
Preferences : : instance ( ) - > setSearchEnabled ( false ) ;
return ;
}
else {
res = true ;
}
}
else {
QMessageBox : : information ( this , tr ( " Undetermined Python version " ) , tr ( " Couldn't determine your Python version (%1). Search engine disabled. " ) . arg ( version ) ) ;
2016-01-24 13:16:25 +03:00
m_ui - > actionSearchWidget - > setChecked ( false ) ;
2015-07-21 01:11:05 +03:00
Preferences : : instance ( ) - > setSearchEnabled ( false ) ;
return ;
}
}
2014-12-20 20:53:58 +03:00
if ( res ) {
2016-01-24 13:16:25 +03:00
m_hasPython = true ;
2014-12-20 20:53:58 +03:00
}
2015-07-21 01:11:05 +03:00
# ifdef Q_OS_WIN
2014-12-20 20:53:58 +03:00
else if ( QMessageBox : : question ( this , tr ( " Missing Python Interpreter " ) ,
2015-03-01 23:00:00 +03:00
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? " ) ,
2014-12-20 20:53:58 +03:00
QMessageBox : : Yes | QMessageBox : : No , QMessageBox : : Yes ) = = QMessageBox : : Yes ) {
// Download and Install Python
installPython ( ) ;
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 ) ;
return ;
}
2015-07-21 01:11:05 +03:00
# endif
2014-12-20 20:53:58 +03:00
else {
2015-07-21 01:11:05 +03:00
# ifndef Q_OS_WIN
QMessageBox : : information ( this , tr ( " Missing Python Interpreter " ) , tr ( " Python is required to use the search engine but it does not seem to be installed. " ) ) ;
# endif
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 ) ;
return ;
}
2014-09-14 15:30:22 +04: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
{
2016-01-24 13:16:25 +03:00
if ( ! m_downloadFromURLDialog ) {
m_downloadFromURLDialog = new downloadFromURL ( this ) ;
2017-07-16 07:10:13 +03:00
connect ( m_downloadFromURLDialog . data ( ) , & downloadFromURL : : urlsReadyToBeDownloaded , this , & MainWindow : : downloadFromURLList ) ;
2014-12-20 20:53:58 +03:00
}
2009-11-06 17:30:14 +03:00
}
2010-06-22 17:58:22 +04:00
2013-09-21 11:59:58 +04:00
# if defined(Q_OS_WIN) || defined(Q_OS_MAC)
2010-10-24 01:46:05 +04:00
2016-01-24 13:16:25 +03:00
void MainWindow : : handleUpdateCheckFinished ( bool updateAvailable , QString newVersion , bool invokedByUser )
2010-10-24 01:46:05 +04:00
{
2014-12-20 20:53:58 +03:00
QMessageBox : : StandardButton answer = QMessageBox : : Yes ;
2016-01-24 13:16:25 +03:00
if ( updateAvailable ) {
2015-08-02 21:40:16 +03:00
answer = QMessageBox : : question ( this , tr ( " qBittorrent Update Available " ) ,
2016-01-24 13:16:25 +03:00
tr ( " A new version is available. \n Do you want to download %1? " ) . arg ( newVersion ) ,
2014-12-20 20:53:58 +03:00
QMessageBox : : Yes | QMessageBox : : No , QMessageBox : : Yes ) ;
if ( answer = = QMessageBox : : Yes ) {
// The user want to update, let's download the update
2017-01-08 03:46:01 +03:00
ProgramUpdater * updater = dynamic_cast < ProgramUpdater * > ( sender ( ) ) ;
2014-12-20 20:53:58 +03:00
updater - > updateProgram ( ) ;
}
2010-10-24 01:46:05 +04:00
}
2014-12-20 20:53:58 +03:00
else if ( invokedByUser ) {
2015-08-02 21:40:16 +03:00
QMessageBox : : information ( this , tr ( " Already Using the Latest qBittorrent Version " ) ,
2015-06-26 09:10:41 +03:00
tr ( " No updates available. \n You are already using the latest version. " ) ) ;
2014-12-20 20:53:58 +03:00
}
sender ( ) - > deleteLater ( ) ;
2016-01-24 13:16:25 +03:00
m_ui - > actionCheckForUpdates - > setEnabled ( true ) ;
m_ui - > actionCheckForUpdates - > setText ( tr ( " &Check for Updates " ) ) ;
m_ui - > actionCheckForUpdates - > setToolTip ( tr ( " Check for program updates " ) ) ;
2014-12-20 20:53:58 +03:00
// Don't bother the user again in this session if he chose to ignore the update
2016-01-24 13:16:25 +03:00
if ( Preferences : : instance ( ) - > isUpdateCheckEnabled ( ) & & ( answer = = QMessageBox : : Yes ) )
m_programUpdateTimer - > start ( ) ;
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 ( ) ;
if ( session - > isBandwidthSchedulerEnabled ( ) )
m_statusBar - > showMessage ( tr ( " Manual change of rate limits mode. The scheduler is disabled. " ) , 5000 ) ;
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
{
2015-10-04 22:26:56 +03:00
QDesktopServices : : openUrl ( QUrl ( " http://www.qbittorrent.org/donate " ) ) ;
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
{
2014-12-20 20:53:58 +03:00
if ( checked ) {
Q_ASSERT ( ! m_executionLog ) ;
2016-01-24 13:16:25 +03:00
m_executionLog = new ExecutionLog ( m_tabs , static_cast < Log : : MsgType > ( executionLogMsgTypes ( ) ) ) ;
int indexTab = m_tabs - > addTab ( m_executionLog , tr ( " Execution Log " ) ) ;
2017-06-12 22:47:28 +03:00
# ifndef Q_OS_MAC
2016-01-24 13:16:25 +03:00
m_tabs - > setTabIcon ( indexTab , GuiIconProvider : : instance ( ) - > getIcon ( " view-calendar-journal " ) ) ;
2017-06-12 22:47:28 +03:00
# endif
2014-12-20 20:53:58 +03:00
}
2015-01-26 17:00:23 +03:00
else if ( m_executionLog ) {
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
2016-01-24 22:38:45 +03:00
void MainWindow : : on_actionNormalMessages_triggered ( bool checked )
{
if ( ! m_executionLog )
return ;
2016-03-14 15:39:13 +03:00
Log : : MsgTypes flags ( executionLogMsgTypes ( ) ) ;
2016-01-24 22:38:45 +03:00
checked ? ( flags | = Log : : NORMAL ) : ( flags & = ~ Log : : NORMAL ) ;
2016-03-14 15:39:13 +03:00
setExecutionLogMsgTypes ( flags ) ;
2016-01-24 22:38:45 +03:00
}
void MainWindow : : on_actionInformationMessages_triggered ( bool checked )
{
if ( ! m_executionLog )
return ;
2016-03-14 15:39:13 +03:00
Log : : MsgTypes flags ( executionLogMsgTypes ( ) ) ;
2016-01-24 22:38:45 +03:00
checked ? ( flags | = Log : : INFO ) : ( flags & = ~ Log : : INFO ) ;
2016-03-14 15:39:13 +03:00
setExecutionLogMsgTypes ( flags ) ;
2016-01-24 22:38:45 +03:00
}
void MainWindow : : on_actionWarningMessages_triggered ( bool checked )
{
if ( ! m_executionLog )
return ;
2016-03-14 15:39:13 +03:00
Log : : MsgTypes flags ( executionLogMsgTypes ( ) ) ;
2016-01-24 22:38:45 +03:00
checked ? ( flags | = Log : : WARNING ) : ( flags & = ~ Log : : WARNING ) ;
2016-03-14 15:39:13 +03:00
setExecutionLogMsgTypes ( flags ) ;
2016-01-24 22:38:45 +03:00
}
void MainWindow : : on_actionCriticalMessages_triggered ( bool checked )
{
if ( ! m_executionLog )
return ;
2016-03-14 15:39:13 +03:00
Log : : MsgTypes flags ( executionLogMsgTypes ( ) ) ;
2016-01-24 22:38:45 +03:00
checked ? ( flags | = Log : : CRITICAL ) : ( flags & = ~ Log : : CRITICAL ) ;
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
void MainWindow : : checkForActiveTorrents ( )
{
2015-04-19 18:17:47 +03:00
m_pwr - > setActivityState ( BitTorrent : : Session : : instance ( ) - > hasActiveTorrents ( ) ) ;
2011-02-06 17:27:34 +03:00
}
2011-03-12 23:59:44 +03:00
2017-06-12 22:47:28 +03:00
# ifndef Q_OS_MAC
2011-03-12 23:59:44 +03:00
QIcon MainWindow : : getSystrayIcon ( ) const
{
2017-07-05 14:16:57 +03:00
# if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC))
if ( Preferences : : instance ( ) - > useSystemIconTheme ( ) )
return QIcon : : fromTheme ( " qbittorrent-tray " ) ;
# endif
const TrayIcon : : Style style = Preferences : : instance ( ) - > trayIconStyle ( ) ;
// on Linux we use theme icons, and icons from resources everywhere else
# if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC))
switch ( style ) {
case TrayIcon : : MONO_DARK :
return QIcon : : fromTheme ( QLatin1String ( " qbittorrent-tray-dark " ) ) ;
case TrayIcon : : MONO_LIGHT :
return QIcon : : fromTheme ( QLatin1String ( " qbittorrent-tray-light " ) ) ;
default :
break ;
}
# else
2017-01-08 03:46:01 +03:00
switch ( style ) {
2014-12-20 20:53:58 +03:00
case TrayIcon : : MONO_DARK :
2017-07-05 14:16:57 +03:00
return QIcon ( QLatin1String ( " :/icons/skin/qbittorrent-tray-dark.svg " ) ) ;
2014-12-20 20:53:58 +03:00
case TrayIcon : : MONO_LIGHT :
2017-07-05 14:16:57 +03:00
return QIcon ( QLatin1String ( " :/icons/skin/qbittorrent-tray-light.svg " ) ) ;
2014-12-20 20:53:58 +03:00
default :
break ;
}
2017-07-05 14:16:57 +03:00
# endif
2014-12-20 20:53:58 +03:00
2015-05-13 16:50:15 +03:00
QIcon icon ;
2017-07-05 14:16:57 +03:00
icon . addFile ( " :/icons/skin/qbittorrent22.png " , QSize ( 22 , 22 ) ) ;
icon . addFile ( " :/icons/skin/qbittorrent16.png " , QSize ( 16 , 16 ) ) ;
icon . addFile ( " :/icons/skin/qbittorrent32.png " , QSize ( 32 , 32 ) ) ;
2014-12-20 20:53:58 +03:00
return icon ;
2011-03-12 23:59:44 +03:00
}
2017-06-12 22:47:28 +03:00
# endif
2013-11-23 16:58:03 +04:00
2013-09-21 11:59:58 +04:00
# if defined(Q_OS_WIN) || defined(Q_OS_MAC)
2014-12-20 20:53:58 +03:00
void MainWindow : : checkProgramUpdate ( )
{
2016-01-24 13:16:25 +03:00
m_programUpdateTimer - > stop ( ) ; // If the user had clicked the menu item
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 " ) ) ;
2017-01-08 03:46:01 +03:00
bool invokedByUser = m_ui - > actionCheckForUpdates = = qobject_cast < QAction * > ( sender ( ) ) ;
2014-12-20 20:53:58 +03:00
ProgramUpdater * updater = new ProgramUpdater ( this , invokedByUser ) ;
2017-07-16 07:10:13 +03:00
connect ( updater , & ProgramUpdater : : updateCheckFinished , this , & MainWindow : : handleUpdateCheckFinished ) ;
2014-12-20 20:53:58 +03:00
updater - > checkForUpdates ( ) ;
2013-11-23 16:58:03 +04:00
}
2017-01-08 03:46:01 +03:00
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
bool MainWindow : : addPythonPathToEnv ( )
{
2016-01-24 13:16:25 +03:00
if ( m_hasPython ) return true ;
QString pythonPath = Preferences : : getPythonPath ( ) ;
if ( ! pythonPath . isEmpty ( ) ) {
Logger : : instance ( ) - > addMessage ( tr ( " Python found in '%1' " ) . arg ( Utils : : Fs : : toNativePath ( pythonPath ) ) , Log : : INFO ) ;
2014-12-20 20:53:58 +03:00
// Add it to PATH envvar
2016-01-24 13:16:25 +03:00
QString pathEnvar = QString : : fromLocal8Bit ( qgetenv ( " PATH " ) . constData ( ) ) ;
if ( pathEnvar . isNull ( ) )
pathEnvar = " " ;
pathEnvar = pythonPath + " ; " + pathEnvar ;
2017-08-13 13:56:03 +03:00
qDebug ( " New PATH envvar is: %s " , qUtf8Printable ( pathEnvar ) ) ;
2016-01-24 13:16:25 +03:00
qputenv ( " PATH " , Utils : : Fs : : toNativePath ( pathEnvar ) . toLocal8Bit ( ) ) ;
2014-12-20 20:53:58 +03:00
return true ;
2014-09-14 15:30:22 +04:00
}
2014-12-20 20:53:58 +03:00
return false ;
}
void MainWindow : : installPython ( )
{
setCursor ( QCursor ( Qt : : WaitCursor ) ) ;
// Download python
2016-11-01 01:19:37 +03:00
Net : : DownloadHandler * handler = nullptr ;
if ( QSysInfo : : windowsVersion ( ) > = QSysInfo : : WV_VISTA )
handler = Net : : DownloadManager : : instance ( ) - > downloadUrl ( " https://www.python.org/ftp/python/3.5.2/python-3.5.2.exe " , true ) ;
else
handler = Net : : DownloadManager : : instance ( ) - > downloadUrl ( " https://www.python.org/ftp/python/3.4.4/python-3.4.4.msi " , true ) ;
2017-07-16 07:10:13 +03:00
using Func = void ( Net : : DownloadHandler : : * ) ( const QString & , const QString & ) ;
connect ( handler , static_cast < Func > ( & Net : : DownloadHandler : : downloadFinished ) , this , & MainWindow : : pythonDownloadSuccess ) ;
connect ( handler , static_cast < Func > ( & Net : : DownloadHandler : : downloadFailed ) , this , & MainWindow : : pythonDownloadFailure ) ;
2014-12-20 20:53:58 +03:00
}
2015-04-19 18:17:47 +03:00
void MainWindow : : pythonDownloadSuccess ( const QString & url , const QString & filePath )
2014-12-20 20:53:58 +03:00
{
2015-04-19 18:17:47 +03:00
Q_UNUSED ( url )
2014-12-20 20:53:58 +03:00
setCursor ( QCursor ( Qt : : ArrowCursor ) ) ;
QProcess installer ;
qDebug ( " Launching Python installer in passive mode... " ) ;
2016-11-01 01:19:37 +03:00
if ( QSysInfo : : windowsVersion ( ) > = QSysInfo : : WV_VISTA ) {
QFile : : rename ( filePath , filePath + " .exe " ) ;
installer . start ( " \" " + Utils : : Fs : : toNativePath ( filePath ) + " .exe \" /passive " ) ;
}
else {
QFile : : rename ( filePath , filePath + " .msi " ) ;
installer . start ( Utils : : Misc : : windowsSystemPath ( ) + " \\ msiexec.exe /passive /i \" " + Utils : : Fs : : toNativePath ( filePath ) + " .msi \" " ) ;
}
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! " ) ;
// Delete temp file
2016-11-01 01:19:37 +03:00
if ( QSysInfo : : windowsVersion ( ) > = QSysInfo : : WV_VISTA )
Utils : : Fs : : forceRemove ( filePath + " .exe " ) ;
else
Utils : : Fs : : forceRemove ( filePath + " .msi " ) ;
2014-12-20 20:53:58 +03:00
// Reload search engine
2016-01-24 13:16:25 +03:00
m_hasPython = addPythonPathToEnv ( ) ;
if ( m_hasPython ) {
2015-07-21 01:11:05 +03:00
// Make it print the version to Log
Utils : : Misc : : pythonVersion ( ) ;
2016-01-24 13:16:25 +03:00
m_ui - > actionSearchWidget - > setChecked ( true ) ;
2014-12-20 20:53:58 +03:00
displaySearchTab ( true ) ;
}
}
2015-04-19 18:17:47 +03:00
void MainWindow : : pythonDownloadFailure ( const QString & url , const QString & error )
2014-12-20 20:53:58 +03:00
{
2015-04-19 18:17:47 +03:00
Q_UNUSED ( url )
2014-12-20 20:53:58 +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 ( error ) ) ;
2014-09-14 15:30:22 +04:00
}
2017-01-08 03:46:01 +03:00
2014-09-14 15:30:22 +04:00
# endif