diff --git a/src/GUI.cpp b/src/GUI.cpp index bdb24788b..62f98af5c 100644 --- a/src/GUI.cpp +++ b/src/GUI.cpp @@ -194,1461 +194,1461 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis } #endif if (!localServer->listen("qBittorrent-"+uid)) { - std::cerr << "Couldn't create socket, single instance mode won't work...\n"; - } - connect(localServer, SIGNAL(newConnection()), this, SLOT(acceptConnection())); - // Start connection checking timer - checkConnect = new QTimer(this); - connect(checkConnect, SIGNAL(timeout()), this, SLOT(checkConnectionStatus())); - checkConnect->start(5000); - // Accept drag 'n drops - setAcceptDrops(true); - createKeyboardShortcuts(); - connecStatusLblIcon = new QLabel(); - connecStatusLblIcon->setFrameShape(QFrame::NoFrame); - connecStatusLblIcon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/skin/firewalled.png"))); - connecStatusLblIcon->setToolTip(QString::fromUtf8("")+tr("Connection status:")+QString::fromUtf8("
")+QString::fromUtf8("")+tr("No direct connections. This may indicate network configuration problems.")+QString::fromUtf8("")); - dlSpeedLbl = new QLabel(tr("DL: %1 KiB/s").arg("0.0")); - upSpeedLbl = new QLabel(tr("UP: %1 KiB/s").arg("0.0")); - ratioLbl = new QLabel(tr("Ratio: %1").arg("1.0")); - DHTLbl = new QLabel(tr("DHT: %1 nodes").arg(0)); - statusSep1 = new QFrame(); - statusSep1->setFixedWidth(1); - statusSep1->setFrameStyle(QFrame::Box); - statusSep2 = new QFrame(); - statusSep2->setFixedWidth(1); - statusSep2->setFrameStyle(QFrame::Box); - statusSep3 = new QFrame(); - statusSep3->setFixedWidth(1); - statusSep3->setFrameStyle(QFrame::Box); - statusSep4 = new QFrame(); - statusSep4->setFixedWidth(1); - statusSep4->setFrameStyle(QFrame::Box); - QMainWindow::statusBar()->addPermanentWidget(DHTLbl); - QMainWindow::statusBar()->addPermanentWidget(statusSep1); - QMainWindow::statusBar()->addPermanentWidget(connecStatusLblIcon); - QMainWindow::statusBar()->addPermanentWidget(statusSep2); - QMainWindow::statusBar()->addPermanentWidget(dlSpeedLbl); - QMainWindow::statusBar()->addPermanentWidget(statusSep3); - QMainWindow::statusBar()->addPermanentWidget(upSpeedLbl); - QMainWindow::statusBar()->addPermanentWidget(statusSep4); - QMainWindow::statusBar()->addPermanentWidget(ratioLbl); - show(); - if(settings.value(QString::fromUtf8("Preferences/General/StartMinimized"), false).toBool()) { - this->setWindowState(Qt::WindowMinimized); - } - scrapeTimer = new QTimer(this); - connect(scrapeTimer, SIGNAL(timeout()), this, SLOT(scrapeTrackers())); - scrapeTimer->start(20000); - qDebug("GUI Built"); + std::cerr << "Couldn't create socket, single instance mode won't work...\n"; } - - // Destructor - GUI::~GUI() { - qDebug("GUI destruction"); - hide(); - // Do this as soon as possible - BTSession->saveDHTEntry(); - BTSession->saveSessionState(); - BTSession->saveFastResumeData(); - scrapeTimer->stop(); - delete scrapeTimer; - delete dlSpeedLbl; - delete upSpeedLbl; - delete ratioLbl; - delete DHTLbl; - delete statusSep1; - delete statusSep2; - delete statusSep3; - delete statusSep4; - if(rssWidget != 0) + connect(localServer, SIGNAL(newConnection()), this, SLOT(acceptConnection())); + // Start connection checking timer + checkConnect = new QTimer(this); + connect(checkConnect, SIGNAL(timeout()), this, SLOT(checkConnectionStatus())); + checkConnect->start(5000); + // Accept drag 'n drops + setAcceptDrops(true); + createKeyboardShortcuts(); + connecStatusLblIcon = new QLabel(); + connecStatusLblIcon->setFrameShape(QFrame::NoFrame); + connecStatusLblIcon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/skin/firewalled.png"))); + connecStatusLblIcon->setToolTip(QString::fromUtf8("")+tr("Connection status:")+QString::fromUtf8("
")+QString::fromUtf8("")+tr("No direct connections. This may indicate network configuration problems.")+QString::fromUtf8("")); + dlSpeedLbl = new QLabel(tr("DL: %1 KiB/s").arg("0.0")); + upSpeedLbl = new QLabel(tr("UP: %1 KiB/s").arg("0.0")); + ratioLbl = new QLabel(tr("Ratio: %1").arg("1.0")); + DHTLbl = new QLabel(tr("DHT: %1 nodes").arg(0)); + statusSep1 = new QFrame(); + statusSep1->setFixedWidth(1); + statusSep1->setFrameStyle(QFrame::Box); + statusSep2 = new QFrame(); + statusSep2->setFixedWidth(1); + statusSep2->setFrameStyle(QFrame::Box); + statusSep3 = new QFrame(); + statusSep3->setFixedWidth(1); + statusSep3->setFrameStyle(QFrame::Box); + statusSep4 = new QFrame(); + statusSep4->setFixedWidth(1); + statusSep4->setFrameStyle(QFrame::Box); + QMainWindow::statusBar()->addPermanentWidget(DHTLbl); + QMainWindow::statusBar()->addPermanentWidget(statusSep1); + QMainWindow::statusBar()->addPermanentWidget(connecStatusLblIcon); + QMainWindow::statusBar()->addPermanentWidget(statusSep2); + QMainWindow::statusBar()->addPermanentWidget(dlSpeedLbl); + QMainWindow::statusBar()->addPermanentWidget(statusSep3); + QMainWindow::statusBar()->addPermanentWidget(upSpeedLbl); + QMainWindow::statusBar()->addPermanentWidget(statusSep4); + QMainWindow::statusBar()->addPermanentWidget(ratioLbl); + show(); + if(settings.value(QString::fromUtf8("Preferences/General/StartMinimized"), false).toBool()) { + this->setWindowState(Qt::WindowMinimized); + } + scrapeTimer = new QTimer(this); + connect(scrapeTimer, SIGNAL(timeout()), this, SLOT(scrapeTrackers())); + scrapeTimer->start(20000); + qDebug("GUI Built"); +} + +// Destructor +GUI::~GUI() { + qDebug("GUI destruction"); + hide(); + // Do this as soon as possible + BTSession->saveDHTEntry(); + BTSession->saveSessionState(); + BTSession->saveFastResumeData(); + scrapeTimer->stop(); + delete scrapeTimer; + delete dlSpeedLbl; + delete upSpeedLbl; + delete ratioLbl; + delete DHTLbl; + delete statusSep1; + delete statusSep2; + delete statusSep3; + delete statusSep4; + if(rssWidget != 0) + delete rssWidget; + delete searchEngine; + delete refresher; + delete downloadingTorrentTab; + delete finishedTorrentTab; + delete checkConnect; + qDebug("1"); + if(systrayCreator) { + delete systrayCreator; + } + if(systrayIntegration) { + delete myTrayIcon; + delete myTrayIconMenu; + } + qDebug("2"); + localServer->close(); + delete localServer; + delete connecStatusLblIcon; + delete tabs; + // HTTP Server + if(httpServer) + delete httpServer; + qDebug("3"); + // Keyboard shortcuts + delete switchSearchShortcut; + delete switchSearchShortcut2; + delete switchDownShortcut; + delete switchUpShortcut; + delete switchRSSShortcut; + qDebug("4"); + delete BTSession; + qDebug("5"); +} + +void GUI::displayRSSTab(bool enable) { + if(enable) { + // RSS tab + if(rssWidget == 0) { + rssWidget = new RSSImp(BTSession); + tabs->addTab(rssWidget, tr("RSS")); + tabs->setTabIcon(3, QIcon(QString::fromUtf8(":/Icons/rss32.png"))); + } + } else { + if(rssWidget != 0) { delete rssWidget; - delete searchEngine; - delete refresher; - delete downloadingTorrentTab; - delete finishedTorrentTab; - delete checkConnect; - qDebug("1"); - if(systrayCreator) { - delete systrayCreator; + rssWidget = 0; } - if(systrayIntegration) { - delete myTrayIcon; - delete myTrayIconMenu; - } - qDebug("2"); - localServer->close(); - delete localServer; - delete connecStatusLblIcon; - delete tabs; - // HTTP Server - if(httpServer) - delete httpServer; - qDebug("3"); - // Keyboard shortcuts - delete switchSearchShortcut; - delete switchSearchShortcut2; - delete switchDownShortcut; - delete switchUpShortcut; - delete switchRSSShortcut; - qDebug("4"); - delete BTSession; - qDebug("5"); } - - void GUI::displayRSSTab(bool enable) { - if(enable) { - // RSS tab - if(rssWidget == 0) { - rssWidget = new RSSImp(BTSession); - tabs->addTab(rssWidget, tr("RSS")); - tabs->setTabIcon(3, QIcon(QString::fromUtf8(":/Icons/rss32.png"))); +} + +void GUI::scrapeTrackers() { + std::vector torrents = BTSession->getTorrents(); + std::vector::iterator torrentIT; + for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) { + QTorrentHandle h = QTorrentHandle(*torrentIT); + if(!h.is_valid()) continue; + h.scrape_tracker(); + } +} + +void GUI::updateRatio() { + // Update ratio info + float ratio = 1.; + session_status sessionStatus = BTSession->getSessionStatus(); + if(sessionStatus.total_payload_download == 0) { + if(sessionStatus.total_payload_upload == 0) + ratio = 1.; + else + ratio = 10.; + }else{ + ratio = (double)sessionStatus.total_payload_upload / (double)sessionStatus.total_payload_download; + if(ratio > 10.) + ratio = 10.; + } + ratioLbl->setText(tr("Ratio: %1").arg(QString(QByteArray::number(ratio, 'f', 1)))); + // Update DHT nodes + DHTLbl->setText(tr("DHT: %1 nodes").arg(QString::number(sessionStatus.dht_nodes))); +} + +void GUI::on_actionWebsite_triggered() const { + QDesktopServices::openUrl(QUrl(QString::fromUtf8("http://www.qbittorrent.org"))); +} + +void GUI::on_actionDocumentation_triggered() const { + QDesktopServices::openUrl(QUrl(QString::fromUtf8("http://wiki.qbittorrent.org"))); +} + +void GUI::on_actionBugReport_triggered() const { + QDesktopServices::openUrl(QUrl(QString::fromUtf8("http://bugs.qbittorrent.org"))); +} + +void GUI::writeSettings() { + QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + settings.beginGroup(QString::fromUtf8("MainWindow")); + settings.setValue(QString::fromUtf8("size"), size()); + settings.setValue(QString::fromUtf8("pos"), pos()); + settings.endGroup(); +} + +// called when a torrent has finished +void GUI::finishedTorrent(QTorrentHandle& h) const { + qDebug("In GUI, a torrent has finished"); + QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + bool show_msg = true; + if(TorrentPersistentData::isSeed(h.hash())) + show_msg = false; + QString fileName = h.name(); + bool useNotificationBalloons = settings.value(QString::fromUtf8("Preferences/General/NotificationBaloons"), true).toBool(); + // Add it to finished tab + QString hash = h.hash(); + if(show_msg) + BTSession->addConsoleMessage(tr("%1 has finished downloading.", "e.g: xxx.avi has finished downloading.").arg(fileName)); + downloadingTorrentTab->deleteTorrent(hash); + finishedTorrentTab->addTorrent(hash); + if(show_msg && systrayIntegration && useNotificationBalloons) { + myTrayIcon->showMessage(tr("Download finished"), tr("%1 has finished downloading.", "e.g: xxx.avi has finished downloading.").arg(fileName), QSystemTrayIcon::Information, TIME_TRAY_BALLOON); + } +} + +void GUI::addedTorrent(QTorrentHandle& h) const { + if(h.is_seed()) { + finishedTorrentTab->addTorrent(h.hash()); + } else { + downloadingTorrentTab->addTorrent(h.hash()); + } +} + +void GUI::pausedTorrent(QTorrentHandle& h) const { + if(h.is_seed()) { + finishedTorrentTab->pauseTorrent(h.hash()); + } else { + downloadingTorrentTab->pauseTorrent(h.hash()); + } +} + +void GUI::resumedTorrent(QTorrentHandle& h) const { + if(h.is_seed()) { + finishedTorrentTab->updateTorrent(h); + } else { + downloadingTorrentTab->updateTorrent(h); + } +} + +void GUI::checkedTorrent(QTorrentHandle& h) const { + if(h.is_seed()) { + // Move torrent to finished tab + downloadingTorrentTab->deleteTorrent(h.hash()); + finishedTorrentTab->addTorrent(h.hash()); + } else { + // Move torrent back to download list (if necessary) + if(TorrentPersistentData::isSeed(h.hash())) { + TorrentPersistentData::saveSeedStatus(h); + finishedTorrentTab->deleteTorrent(h.hash()); + downloadingTorrentTab->addTorrent(h.hash()); + } + } +} + +// Notification when disk is full +void GUI::fullDiskError(QTorrentHandle& h, QString msg) const { + QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + bool useNotificationBalloons = settings.value(QString::fromUtf8("Preferences/General/NotificationBaloons"), true).toBool(); + if(systrayIntegration && useNotificationBalloons) { + myTrayIcon->showMessage(tr("I/O Error", "i.e: Input/Output Error"), tr("An I/O error occured for torrent %1.\n Reason: %2", "e.g: An error occured for torrent xxx.avi.\n Reason: disk is full.").arg(h.name()).arg(msg), QSystemTrayIcon::Critical, TIME_TRAY_BALLOON); + } + // Download will be paused by libtorrent. Updating GUI information accordingly + QString hash = h.hash(); + qDebug("Full disk error, pausing torrent %s", hash.toLocal8Bit().data()); + setPaused(h); + BTSession->addConsoleMessage(tr("An error occured (full disk?), '%1' paused.", "e.g: An error occured (full disk?), 'xxx.avi' paused.").arg(h.name())); +} + +void GUI::setPaused(QTorrentHandle &h) const { + if(!h.is_paused()) { + // FIXME in v1.6.0: Add Error state and stop using pause for this + h.pause(); + } + qDebug("Marking torrent %s as paused", h.hash().toLocal8Bit().data()); + if(h.is_seed()) { + // In finished list + qDebug("Automatically paused torrent was in finished list"); + finishedTorrentTab->pauseTorrent(h.hash()); + }else{ + downloadingTorrentTab->pauseTorrent(h.hash()); + } +} + +void GUI::createKeyboardShortcuts() { + actionCreate_torrent->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+N"))); + actionOpen->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+O"))); + actionExit->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+Q"))); + switchDownShortcut = new QShortcut(QKeySequence(tr("Alt+1", "shortcut to switch to first tab")), this); + connect(switchDownShortcut, SIGNAL(activated()), this, SLOT(displayDownTab())); + switchUpShortcut = new QShortcut(QKeySequence(tr("Alt+2", "shortcut to switch to second tab")), this); + connect(switchUpShortcut, SIGNAL(activated()), this, SLOT(displayUpTab())); + switchSearchShortcut = new QShortcut(QKeySequence(tr("Alt+3", "shortcut to switch to third tab")), this); + connect(switchSearchShortcut, SIGNAL(activated()), this, SLOT(displaySearchTab())); + switchSearchShortcut2 = new QShortcut(QKeySequence(tr("Ctrl+F", "shortcut to switch to search tab")), this); + connect(switchSearchShortcut2, SIGNAL(activated()), this, SLOT(displaySearchTab())); + switchRSSShortcut = new QShortcut(QKeySequence(tr("Alt+4", "shortcut to switch to fourth tab")), this); + connect(switchRSSShortcut, SIGNAL(activated()), this, SLOT(displayRSSTab())); + actionTorrent_Properties->setShortcut(QKeySequence(QString::fromUtf8("Alt+P"))); + actionOptions->setShortcut(QKeySequence(QString::fromUtf8("Alt+O"))); + actionDelete->setShortcut(QKeySequence(QString::fromUtf8("Del"))); + actionDelete_Permanently->setShortcut(QKeySequence(QString::fromUtf8("Shift+Del"))); + actionStart->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+S"))); + actionStart_All->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+Shift+S"))); + actionPause->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+P"))); + actionPause_All->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+Shift+P"))); + actionDecreasePriority->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+-"))); + actionIncreasePriority->setShortcut(QKeySequence(QString::fromUtf8("Ctrl++"))); +} + +// Keyboard shortcuts slots +void GUI::displayDownTab() const { + tabs->setCurrentIndex(0); +} + +void GUI::displayUpTab() const { + tabs->setCurrentIndex(1); +} + +void GUI::displaySearchTab() const { + tabs->setCurrentIndex(2); +} + +void GUI::displayRSSTab() const { + tabs->setCurrentIndex(3); +} + +// End of keyboard shortcuts slots + +void GUI::readSettings() { + QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + settings.beginGroup(QString::fromUtf8("MainWindow")); + resize(settings.value(QString::fromUtf8("size"), size()).toSize()); + move(settings.value(QString::fromUtf8("pos"), screenCenter()).toPoint()); + settings.endGroup(); +} + +void GUI::balloonClicked() { + if(isHidden()) { + show(); + if(isMinimized()) { + showNormal(); + } + raise(); + activateWindow(); + } +} + +void GUI::acceptConnection() { + clientConnection = localServer->nextPendingConnection(); + connect(clientConnection, SIGNAL(disconnected()), this, SLOT(readParamsOnSocket())); + qDebug("accepted connection from another instance"); +} + +void GUI::readParamsOnSocket() { + if(clientConnection) { + QByteArray params = clientConnection->readAll(); + if(!params.isEmpty()) { + processParams(QString::fromUtf8(params.data()).split(QString::fromUtf8("\n"))); + qDebug("Received parameters from another instance"); + } + } +} + +void GUI::handleDownloadFromUrlFailure(QString url, QString reason) const{ + // Display a message box + QMessageBox::critical(0, tr("Url download error"), tr("Couldn't download file at url: %1, reason: %2.").arg(url).arg(reason)); +} + +void GUI::on_actionSet_global_upload_limit_triggered() { + qDebug("actionSet_global_upload_limit_triggered"); + new BandwidthAllocationDialog(this, true, BTSession, QStringList()); +} + +void GUI::on_actionShow_console_triggered() { + new consoleDlg(this, BTSession); +} + +void GUI::on_actionSet_global_download_limit_triggered() { + qDebug("actionSet_global_download_limit_triggered"); + new BandwidthAllocationDialog(this, false, BTSession, QStringList()); +} + +void GUI::on_actionPreview_file_triggered() { + QString hash; + switch(tabs->currentIndex()){ + case 0: + hash = downloadingTorrentTab->getSelectedTorrents(true).first(); + break; + case 1: + hash = finishedTorrentTab->getSelectedTorrents(true).first(); + break; + default: + return; + } + QTorrentHandle h = BTSession->getTorrentHandle(hash); + new previewSelect(this, h); +} + +void GUI::openDestinationFolder() const { + QStringList hashes; + switch(tabs->currentIndex()){ + case 0: + hashes = downloadingTorrentTab->getSelectedTorrents(true); + break; + case 1: + hashes = finishedTorrentTab->getSelectedTorrents(true); + break; + default: + return; + } + QStringList pathsList; + foreach(const QString &hash, hashes) { + QTorrentHandle h = BTSession->getTorrentHandle(hash); + QString savePath = h.save_path(); + if(!pathsList.contains(savePath)) { + pathsList.append(savePath); + QDesktopServices::openUrl(QString("file://")+savePath); + } + } +} + +void GUI::copyMagnetURI() const { + QStringList hashes; + switch(tabs->currentIndex()){ + case 0: + hashes = downloadingTorrentTab->getSelectedTorrents(); + break; + case 1: + hashes = finishedTorrentTab->getSelectedTorrents(); + break; + default: + return; + } + QStringList magnet_uris; + foreach(QString hash, hashes) { + QTorrentHandle h = BTSession->getTorrentHandle(hash); + if(h.is_valid()) { + magnet_uris << misc::toQString(make_magnet_uri(h.get_torrent_info())); + } + } + qApp->clipboard()->setText(magnet_uris.join("\n")); +} + +void GUI::goBuyPage() const { + QStringList hashes; + switch(tabs->currentIndex()){ + case 0: + hashes = downloadingTorrentTab->getSelectedTorrents(true); + break; + case 1: + hashes = finishedTorrentTab->getSelectedTorrents(true); + break; + default: + return; + } + QStringList pathsList; + foreach(const QString &hash, hashes) { + QTorrentHandle h = BTSession->getTorrentHandle(hash); + QDesktopServices::openUrl("http://match.sharemonkey.com/?info_hash="+hash+"&n="+h.name()+"&cid=33"); + } +} + +// Necessary if we want to close the window +// in one time if "close to systray" is enabled +void GUI::on_actionExit_triggered() { + force_exit = true; + close(); +} + +void GUI::previewFile(QString filePath) { + QDesktopServices::openUrl(QString("file://")+filePath); +} + +int GUI::getCurrentTabIndex() const{ + if(isMinimized() || isHidden()) + return -1; + return tabs->currentIndex(); +} + +void GUI::setTabText(int index, QString text) const { + tabs->setTabText(index, text); +} + +// Toggle Main window visibility +void GUI::toggleVisibility(QSystemTrayIcon::ActivationReason e) { + if(e == QSystemTrayIcon::Trigger || e == QSystemTrayIcon::DoubleClick) { + if(isHidden()) { + show(); + if(isMinimized()) { + if(isMaximized()) { + showMaximized(); + }else{ + showNormal(); + } } + raise(); + activateWindow(); + }else{ + hide(); + } + } +} + +// Center window +QPoint GUI::screenCenter() const{ + int scrn = 0; + QWidget *w = this->topLevelWidget(); + + if(w) + scrn = QApplication::desktop()->screenNumber(w); + else if(QApplication::desktop()->isVirtualDesktop()) + scrn = QApplication::desktop()->screenNumber(QCursor::pos()); + else + scrn = QApplication::desktop()->screenNumber(this); + + QRect desk(QApplication::desktop()->availableGeometry(scrn)); + return QPoint((desk.width() - this->frameGeometry().width()) / 2, (desk.height() - this->frameGeometry().height()) / 2); +} + +// Display About Dialog +void GUI::on_actionAbout_triggered() { + //About dialog + new about(this); +} + +void GUI::showEvent(QShowEvent *e) { + qDebug("** Show Event **"); + updateLists(true); + e->accept(); +} + +// Called when we close the program +void GUI::closeEvent(QCloseEvent *e) { + + QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + bool goToSystrayOnExit = settings.value(QString::fromUtf8("Preferences/General/CloseToTray"), false).toBool(); + if(!force_exit && systrayIntegration && goToSystrayOnExit && !this->isHidden()) { + hide(); + //e->ignore(); + e->accept(); + return; + } + if(settings.value(QString::fromUtf8("Preferences/General/ExitConfirm"), true).toBool() && downloadingTorrentTab->getNbTorrentsInList()) { + show(); + if(!isMaximized()) + showNormal(); + if(e->spontaneous() == true || force_exit == true) { + if(QMessageBox::question(this, + tr("Are you sure you want to quit?")+QString::fromUtf8(" -- ")+tr("qBittorrent"), + tr("The download list is not empty.\nAre you sure you want to quit qBittorrent?"), + tr("&Yes"), tr("&No"), + QString(), 0, 1)) { + e->ignore(); + force_exit = false; + return; + } + } + } + hide(); + if(systrayIntegration) { + // Hide tray icon + myTrayIcon->hide(); + } + // Save window size, columns size + writeSettings(); + // Accept exit + e->accept(); + qApp->exit(); +} + + +// Display window to create a torrent +void GUI::on_actionCreate_torrent_triggered() { + createtorrent *ct = new createtorrent(this); + connect(ct, SIGNAL(torrent_to_seed(QString)), this, SLOT(addTorrent(QString))); +} + +bool GUI::event(QEvent * e) { + if(e->type() == QEvent::WindowStateChange) { + //Now check to see if the window is minimised + if(isMinimized()) { + qDebug("minimisation"); + QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + if(systrayIntegration && settings.value(QString::fromUtf8("Preferences/General/MinimizeToTray"), false).toBool()) { + hide(); + } + } + } + return QMainWindow::event(e); +} + +// Action executed when a file is dropped +void GUI::dropEvent(QDropEvent *event) { + event->acceptProposedAction(); + QStringList files; + if(event->mimeData()->hasUrls()) { + QList urls = event->mimeData()->urls(); + foreach(const QUrl &url, urls) { + QString tmp = url.toString().trimmed(); + if(!tmp.isEmpty()) + files << url.toString(); + } + } else { + files = event->mimeData()->text().split(QString::fromUtf8("\n")); + } + // Add file to download list + QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + bool useTorrentAdditionDialog = settings.value(QString::fromUtf8("Preferences/Downloads/AdditionDialog"), true).toBool(); + foreach(QString file, files) { + file = file.trimmed().replace(QString::fromUtf8("file://"), QString::fromUtf8(""), Qt::CaseInsensitive); + qDebug("Dropped file %s on download list", file.toLocal8Bit().data()); + if(file.startsWith(QString::fromUtf8("http://"), Qt::CaseInsensitive) || file.startsWith(QString::fromUtf8("ftp://"), Qt::CaseInsensitive) || file.startsWith(QString::fromUtf8("https://"), Qt::CaseInsensitive)) { + BTSession->downloadFromUrl(file); + continue; + } + if(file.startsWith("magnet:", Qt::CaseInsensitive)) { + // FIXME: Possibly skipped torrent addition dialog + BTSession->addMagnetUri(file); + continue; + } + if(useTorrentAdditionDialog) { + torrentAdditionDialog *dialog = new torrentAdditionDialog(this, BTSession); + dialog->showLoad(file); + }else{ + BTSession->addTorrent(file); + } + } +} + +// Decode if we accept drag 'n drop or not +void GUI::dragEnterEvent(QDragEnterEvent *event) { + foreach(const QString &mime, event->mimeData()->formats()){ + qDebug("mimeData: %s", mime.toLocal8Bit().data()); + } + if (event->mimeData()->hasFormat(QString::fromUtf8("text/plain")) || event->mimeData()->hasFormat(QString::fromUtf8("text/uri-list"))) { + event->acceptProposedAction(); + } +} + +/***************************************************** + * * + * Torrent * + * * + *****************************************************/ + +// Display a dialog to allow user to add +// torrents to download list +void GUI::on_actionOpen_triggered() { + QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + // Open File Open Dialog + // Note: it is possible to select more than one file + QStringList pathsList = QFileDialog::getOpenFileNames(0, + tr("Open Torrent Files"), settings.value(QString::fromUtf8("MainWindowLastDir"), QDir::homePath()).toString(), + tr("Torrent Files")+QString::fromUtf8(" (*.torrent)")); + if(!pathsList.empty()) { + bool useTorrentAdditionDialog = settings.value(QString::fromUtf8("Preferences/Downloads/AdditionDialog"), true).toBool(); + unsigned int listSize = pathsList.size(); + for(unsigned int i=0; ishowLoad(pathsList.at(i)); + }else{ + BTSession->addTorrent(pathsList.at(i)); + } + } + // Save last dir to remember it + QStringList top_dir = pathsList.at(0).split(QDir::separator()); + top_dir.removeLast(); + settings.setValue(QString::fromUtf8("MainWindowLastDir"), top_dir.join(QDir::separator())); + } +} + +// delete from download list AND from hard drive +void GUI::on_actionDelete_Permanently_triggered() { + QStringList hashes; + bool inDownloadList = true; + switch(tabs->currentIndex()){ + case 0: + hashes = downloadingTorrentTab->getSelectedTorrents(); + break; + case 1: + hashes = finishedTorrentTab->getSelectedTorrents(); + inDownloadList = false; + break; + default: + return; + } + if(hashes.empty()) return; + int ret; + if(inDownloadList) { + ret = QMessageBox::question( + this, + tr("Are you sure? -- qBittorrent"), + tr("Are you sure you want to delete the selected item(s) from download list and from hard drive?"), + tr("&Yes"), tr("&No"), + QString(), 0, 1); + }else{ + ret = QMessageBox::question( + this, + tr("Are you sure? -- qBittorrent"), + tr("Are you sure you want to delete the selected item(s) from finished list and from hard drive?"), + tr("&Yes"), tr("&No"), + QString(), 0, 1); + } + if(ret) return; + //User clicked YES + foreach(const QString &hash, hashes) { + // Get the file name + QTorrentHandle h = BTSession->getTorrentHandle(hash); + QString fileName = h.name(); + // Remove the torrent + BTSession->deleteTorrent(hash, true); + } +} + +void GUI::deleteTorrent(QString hash) { + // Delete item from list + downloadingTorrentTab->deleteTorrent(hash); + finishedTorrentTab->deleteTorrent(hash); +} + +// delete selected items in the list +void GUI::on_actionDelete_triggered() { + QStringList hashes; + bool inDownloadList = true; + switch(tabs->currentIndex()){ + case 0: // DL + hashes = downloadingTorrentTab->getSelectedTorrents(); + break; + case 1: // SEED + hashes = finishedTorrentTab->getSelectedTorrents(); + inDownloadList = false; + break; + case 3: //RSSImp + rssWidget->deleteSelectedItems(); + return; + default: + return; + } + if(hashes.empty()) return; + int ret; + if(inDownloadList) { + ret = QMessageBox::question( + this, + tr("Are you sure? -- qBittorrent"), + tr("Are you sure you want to delete the selected item(s) in download list?"), + tr("&Yes"), tr("&No"), + QString(), 0, 1); + } else { + ret = QMessageBox::question( + this, + tr("Are you sure? -- qBittorrent"), + tr("Are you sure you want to delete the selected item(s) in finished list?"), + tr("&Yes"), tr("&No"), + QString(), 0, 1); + } + if(ret) return; + //User clicked YES + foreach(const QString &hash, hashes) { + // Get the file name + QTorrentHandle h = BTSession->getTorrentHandle(hash); + QString fileName = h.name(); + // Remove the torrent + BTSession->deleteTorrent(hash, false); + } +} + +// As program parameters, we can get paths or urls. +// This function parse the parameters and call +// the right addTorrent function, considering +// the parameter type. +void GUI::processParams(const QStringList& params) { + QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + bool useTorrentAdditionDialog = settings.value(QString::fromUtf8("Preferences/Downloads/AdditionDialog"), true).toBool(); + foreach(QString param, params) { + param = param.trimmed(); + if(param.startsWith("--")) continue; + if(param.startsWith(QString::fromUtf8("http://"), Qt::CaseInsensitive) || param.startsWith(QString::fromUtf8("ftp://"), Qt::CaseInsensitive) || param.startsWith(QString::fromUtf8("https://"), Qt::CaseInsensitive)) { + BTSession->downloadFromUrl(param); + }else{ + if(param.startsWith("magnet:", Qt::CaseInsensitive)) { + // FIXME: Possibily skipped torrent addition dialog + BTSession->addMagnetUri(param); + } else { + if(useTorrentAdditionDialog) { + torrentAdditionDialog *dialog = new torrentAdditionDialog(this, BTSession); + dialog->showLoad(param); + }else{ + BTSession->addTorrent(param); + } + } + } + } +} + +void GUI::addTorrent(QString path) { + BTSession->addTorrent(path); +} + +void GUI::processDownloadedFiles(QString path, QString url) { + QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + bool useTorrentAdditionDialog = settings.value(QString::fromUtf8("Preferences/Downloads/AdditionDialog"), true).toBool(); + if(useTorrentAdditionDialog) { + torrentAdditionDialog *dialog = new torrentAdditionDialog(this, BTSession); + dialog->showLoad(path, url); + }else{ + BTSession->addTorrent(path, false, url); + } +} + +// Set BT session configuration +void GUI::configureSession(bool deleteOptions) { + qDebug("Configuring session"); + // General + bool new_displaySpeedInTitle = options->speedInTitleBar(); + if(!new_displaySpeedInTitle && new_displaySpeedInTitle != displaySpeedInTitle) { + // Reset title + setWindowTitle(tr("qBittorrent %1", "e.g: qBittorrent v0.x").arg(QString::fromUtf8(VERSION))); + } + displaySpeedInTitle = new_displaySpeedInTitle; + if(options->isToolbarDisplayed()) { + toolBar->setVisible(true); + toolBar->layout()->setSpacing(7); + } else { + toolBar->setVisible(false); + } + unsigned int new_refreshInterval = options->getRefreshInterval(); + if(refreshInterval != new_refreshInterval) { + refreshInterval = new_refreshInterval; + refresher->start(refreshInterval); + } + // Downloads + // * Save path + BTSession->setDefaultSavePath(options->getSavePath()); + if(options->isTempPathEnabled()) { + BTSession->setDefaultTempPath(options->getTempPath()); + } else { + BTSession->setDefaultTempPath(QString::null); + } + BTSession->preAllocateAllFiles(options->preAllocateAllFiles()); + BTSession->startTorrentsInPause(options->addTorrentsInPause()); + // * Scan dir + if(options->getScanDir().isNull()) { + BTSession->disableDirectoryScanning(); + }else{ + //Interval first + BTSession->enableDirectoryScanning(options->getScanDir()); + } + // Connection + // * Ports binding + unsigned short old_listenPort = BTSession->getListenPort(); + BTSession->setListeningPort(options->getPort()); + unsigned short new_listenPort = BTSession->getListenPort(); + if(new_listenPort != old_listenPort) { + BTSession->addConsoleMessage(tr("qBittorrent is bound to port: TCP/%1", "e.g: qBittorrent is bound to port: 6881").arg( misc::toQString(new_listenPort))); + } + // * Global download limit + QPair limits = options->getGlobalBandwidthLimits(); + if(limits.first <= 0) { + // Download limit disabled + BTSession->setDownloadRateLimit(-1); + } else { + // Enabled + BTSession->setDownloadRateLimit(limits.first*1024); + } + // * Global Upload limit + if(limits.second <= 0) { + // Upload limit disabled + BTSession->setUploadRateLimit(-1); + } else { + // Enabled + BTSession->setUploadRateLimit(limits.second*1024); + } + // * UPnP + if(options->isUPnPEnabled()) { + BTSession->enableUPnP(true); + BTSession->addConsoleMessage(tr("UPnP support [ON]"), QString::fromUtf8("blue")); + } else { + BTSession->enableUPnP(false); + BTSession->addConsoleMessage(tr("UPnP support [OFF]"), QString::fromUtf8("blue")); + } + // * NAT-PMP + if(options->isNATPMPEnabled()) { + BTSession->enableNATPMP(true); + BTSession->addConsoleMessage(tr("NAT-PMP support [ON]"), QString::fromUtf8("blue")); + } else { + BTSession->enableNATPMP(false); + BTSession->addConsoleMessage(tr("NAT-PMP support [OFF]"), QString::fromUtf8("blue")); + } + // * Session settings + session_settings sessionSettings; + if(options->shouldSpoofAzureus()) { + sessionSettings.user_agent = "Azureus 3.0.5.2"; + } else { + sessionSettings.user_agent = "qBittorrent "VERSION; + } + sessionSettings.upnp_ignore_nonrouters = true; + sessionSettings.use_dht_as_fallback = false; + // To keep same behavior as in qbittorrent v1.2.0 + sessionSettings.rate_limit_ip_overhead = false; + // Queueing System + if(options->isQueueingSystemEnabled()) { + if(!BTSession->isQueueingEnabled()) { + downloadingTorrentTab->hidePriorityColumn(false); + actionDecreasePriority->setVisible(true); + actionIncreasePriority->setVisible(true); + prioSeparator->setVisible(true); + prioSeparator2->setVisible(true); + toolBar->layout()->setSpacing(7); + } + int max_torrents = options->getMaxActiveTorrents(); + int max_uploads = options->getMaxActiveUploads(); + int max_downloads = options->getMaxActiveDownloads(); + sessionSettings.active_downloads = max_downloads; + sessionSettings.active_seeds = max_uploads; + sessionSettings.active_limit = max_torrents; + sessionSettings.dont_count_slow_torrents = false; + BTSession->setQueueingEnabled(true); + } else { + if(BTSession->isQueueingEnabled()) { + sessionSettings.active_downloads = -1; + sessionSettings.active_seeds = -1; + sessionSettings.active_limit = -1; + BTSession->setQueueingEnabled(false); + downloadingTorrentTab->hidePriorityColumn(true); + actionDecreasePriority->setVisible(false); + actionIncreasePriority->setVisible(false); + prioSeparator->setVisible(false); + prioSeparator2->setVisible(false); + toolBar->layout()->setSpacing(7); + } + } + BTSession->setSessionSettings(sessionSettings); + // Bittorrent + // * Max connections limit + BTSession->setMaxConnections(options->getMaxConnecs()); + // * Max connections per torrent limit + BTSession->setMaxConnectionsPerTorrent(options->getMaxConnecsPerTorrent()); + // * Max uploads per torrent limit + BTSession->setMaxUploadsPerTorrent(options->getMaxUploadsPerTorrent()); + // * DHT + if(options->isDHTEnabled()) { + // Set DHT Port + BTSession->setDHTPort(options->getDHTPort()); + if(BTSession->enableDHT(true)) { + int dht_port = new_listenPort; + if(options->getDHTPort()) + dht_port = options->getDHTPort(); + BTSession->addConsoleMessage(tr("DHT support [ON], port: UDP/%1").arg(dht_port), QString::fromUtf8("blue")); } else { - if(rssWidget != 0) { - delete rssWidget; - rssWidget = 0; + BTSession->addConsoleMessage(tr("DHT support [OFF]"), QString::fromUtf8("red")); + } + } else { + BTSession->enableDHT(false); + BTSession->addConsoleMessage(tr("DHT support [OFF]"), QString::fromUtf8("blue")); + } + // * PeX + BTSession->addConsoleMessage(tr("PeX support [ON]"), QString::fromUtf8("blue")); + // * LSD + if(options->isLSDEnabled()) { + BTSession->enableLSD(true); + BTSession->addConsoleMessage(tr("Local Peer Discovery [ON]"), QString::fromUtf8("blue")); + } else { + BTSession->enableLSD(false); + BTSession->addConsoleMessage(tr("Local Peer Discovery support [OFF]"), QString::fromUtf8("blue")); + } + // * Encryption + int encryptionState = options->getEncryptionSetting(); + // The most secure, rc4 only so that all streams and encrypted + pe_settings encryptionSettings; + encryptionSettings.allowed_enc_level = pe_settings::rc4; + encryptionSettings.prefer_rc4 = true; + switch(encryptionState) { + case 0: //Enabled + encryptionSettings.out_enc_policy = pe_settings::enabled; + encryptionSettings.in_enc_policy = pe_settings::enabled; + BTSession->addConsoleMessage(tr("Encryption support [ON]"), QString::fromUtf8("blue")); + break; + case 1: // Forced + encryptionSettings.out_enc_policy = pe_settings::forced; + encryptionSettings.in_enc_policy = pe_settings::forced; + BTSession->addConsoleMessage(tr("Encryption support [FORCED]"), QString::fromUtf8("blue")); + break; + default: // Disabled + encryptionSettings.out_enc_policy = pe_settings::disabled; + encryptionSettings.in_enc_policy = pe_settings::disabled; + BTSession->addConsoleMessage(tr("Encryption support [OFF]"), QString::fromUtf8("blue")); + } + BTSession->applyEncryptionSettings(encryptionSettings); + // * Desired ratio + BTSession->setGlobalRatio(options->getDesiredRatio()); + // * Maximum ratio + BTSession->setDeleteRatio(options->getDeleteRatio()); + // Ip Filter + if(options->isFilteringEnabled()) { + BTSession->enableIPFilter(options->getFilter()); + }else{ + BTSession->disableIPFilter(); + } + // RSS + if(options->isRSSEnabled()) { + displayRSSTab(true); + } else { + displayRSSTab(false); + } + // * Proxy settings + proxy_settings proxySettings; + if(options->isProxyEnabled()) { + qDebug("Enabling P2P proxy"); + proxySettings.hostname = options->getProxyIp().toStdString(); + qDebug("hostname is %s", proxySettings.hostname.c_str()); + proxySettings.port = options->getProxyPort(); + qDebug("port is %d", proxySettings.port); + if(options->isProxyAuthEnabled()) { + + proxySettings.username = options->getProxyUsername().toStdString(); + proxySettings.password = options->getProxyPassword().toStdString(); + qDebug("username is %s", proxySettings.username.c_str()); + qDebug("password is %s", proxySettings.password.c_str()); + } + switch(options->getProxyType()) { + case HTTP: + qDebug("type: http"); + proxySettings.type = proxy_settings::http; + break; + case HTTP_PW: + qDebug("type: http_pw"); + proxySettings.type = proxy_settings::http_pw; + break; + case SOCKS5: + qDebug("type: socks5"); + proxySettings.type = proxy_settings::socks5; + break; + default: + qDebug("type: socks5_pw"); + proxySettings.type = proxy_settings::socks5_pw; + break; + } + qDebug("booleans: %d %d %d %d", options->useProxyForTrackers(), options->useProxyForPeers(), options->useProxyForWebseeds(), options->useProxyForDHT()); + BTSession->setProxySettings(proxySettings, options->useProxyForTrackers(), options->useProxyForPeers(), options->useProxyForWebseeds(), options->useProxyForDHT()); + } else { + qDebug("Disabling P2P proxy"); + BTSession->setProxySettings(proxySettings, false, false, false, false); + } + if(options->isHTTPProxyEnabled()) { + qDebug("Enabling Search HTTP proxy"); + // HTTP Proxy + QString proxy_str; + switch(options->getHTTPProxyType()) { + case HTTP_PW: + proxy_str = misc::toQString("http://")+options->getHTTPProxyUsername()+":"+options->getHTTPProxyPassword()+"@"+options->getHTTPProxyIp()+":"+misc::toQString(options->getHTTPProxyPort()); + break; + default: + proxy_str = misc::toQString("http://")+options->getHTTPProxyIp()+":"+misc::toQString(options->getHTTPProxyPort()); + } + // We need this for urllib in search engine plugins +#ifdef Q_WS_WIN + char proxystr[512]; + snprintf(proxystr, 512, "http_proxy=%s", proxy_str.toLocal8Bit().data()); + putenv(proxystr); +#else + qDebug("HTTP: proxy string: %s", proxy_str.toLocal8Bit().data()); + setenv("http_proxy", proxy_str.toLocal8Bit().data(), 1); +#endif + } else { + qDebug("Disabling search proxy"); +#ifdef Q_WS_WIN + putenv("http_proxy="); +#else + unsetenv("http_proxy"); +#endif + } + // Clean up + if(deleteOptions && options) { + qDebug("Deleting options"); + //delete options; + options->deleteLater(); + } + qDebug("Session configured"); +} + +void GUI::updateUnfinishedTorrentNumber(unsigned int nb) { + unsigned int paused = BTSession->getUnfinishedPausedTorrentsNb(); + tabs->setTabText(0, tr("Downloads") +QString::fromUtf8(" (")+misc::toQString(nb-paused)+"/"+misc::toQString(nb)+QString::fromUtf8(")")); +} + +void GUI::updateFinishedTorrentNumber(unsigned int nb) { + unsigned int paused = BTSession->getFinishedPausedTorrentsNb(); + tabs->setTabText(1, tr("Finished") +QString::fromUtf8(" (")+misc::toQString(nb-paused)+"/"+misc::toQString(nb)+QString::fromUtf8(")")); +} + +// Allow to change action on double-click +void GUI::torrentDoubleClicked(QString hash, bool finished) { + int action; + QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + QTorrentHandle h = BTSession->getTorrentHandle(hash); + + if(finished) { + action = settings.value(QString::fromUtf8("Preferences/Downloads/DblClOnTorFN"), 0).toInt(); + } else { + action = settings.value(QString::fromUtf8("Preferences/Downloads/DblClOnTorDl"), 0).toInt(); + } + + switch(action) { + case TOGGLE_PAUSE: + this->togglePausedState(hash); + break; + case OPEN_DEST: { + QTorrentHandle h = BTSession->getTorrentHandle(hash); + QString savePath = h.save_path(); + QDesktopServices::openUrl(QUrl(savePath)); + break; + } + case SHOW_PROPERTIES : + if(finished) { + finishedTorrentTab->showPropertiesFromHash(hash); + } else { + downloadingTorrentTab->showPropertiesFromHash(hash); + } + break; + } +} + +// Toggle paused state of selected torrent +void GUI::togglePausedState(QString hash) { + if(tabs->currentIndex() > 1) return; + bool inDownloadList = true; + if(tabs->currentIndex() == 1) + inDownloadList = false; + QTorrentHandle h = BTSession->getTorrentHandle(hash); + if(h.is_paused()) { + h.resume(); + resumedTorrent(h); + if(inDownloadList) { + updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList()); + }else{ + updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList()); + } + }else{ + h.pause(); + pausedTorrent(h); + if(inDownloadList) { + updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList()); + }else{ + updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList()); + } + } +} + +// Pause All Downloads in DL list +void GUI::on_actionPause_All_triggered() { + bool change = false; + std::vector torrents = BTSession->getTorrents(); + std::vector::iterator torrentIT; + for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) { + QTorrentHandle h = QTorrentHandle(*torrentIT); + if(!h.is_valid() || h.is_paused()) continue; + change = true; + h.pause(); + pausedTorrent(h); + } + if(change) { + updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList()); + updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList()); + } +} + +void GUI::on_actionIncreasePriority_triggered() { + if(tabs->currentIndex() != 0) + return; + QStringList hashes = downloadingTorrentTab->getSelectedTorrents(); + foreach(const QString &hash, hashes) { + BTSession->increaseDlTorrentPriority(hash); + } + updateLists(); +} + +void GUI::on_actionDecreasePriority_triggered() { + Q_ASSERT(tabs->currentIndex() == 0); + QStringList hashes = downloadingTorrentTab->getSelectedTorrents(); + foreach(const QString &hash, hashes) { + BTSession->decreaseDlTorrentPriority(hash); + } + updateLists(); +} + +// pause selected items in the list +void GUI::on_actionPause_triggered() { + bool inDownloadList = true; + if(tabs->currentIndex() > 1) return; + if(tabs->currentIndex() == 1) + inDownloadList = false; + QStringList hashes; + if(inDownloadList) { + hashes = downloadingTorrentTab->getSelectedTorrents(); + } else { + hashes = finishedTorrentTab->getSelectedTorrents(); + } + qDebug("nb hashes: %d", hashes.size()); + foreach(const QString &hash, hashes) { + QTorrentHandle h = BTSession->getTorrentHandle(hash); + if(!h.is_paused()){ + h.pause(); + pausedTorrent(h); + if(inDownloadList) { + updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList()); + } else { + updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList()); } } } - - void GUI::scrapeTrackers() { +} + +// Resume All Downloads in DL list +void GUI::on_actionStart_All_triggered() { + bool change = false; + std::vector torrents = BTSession->getTorrents(); + std::vector::iterator torrentIT; + for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) { + QTorrentHandle h = QTorrentHandle(*torrentIT); + if(!h.is_valid() || !h.is_paused()) continue; + change = true; + h.resume(); + resumedTorrent(h); + } + if(change) { + updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList()); + updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList()); + } +} + +// start selected items in the list +void GUI::on_actionStart_triggered() { + bool inDownloadList = true; + if(tabs->currentIndex() > 1) return; + if(tabs->currentIndex() == 1) + inDownloadList = false; + QStringList hashes; + if(inDownloadList) { + hashes = downloadingTorrentTab->getSelectedTorrents(); + } else { + hashes = finishedTorrentTab->getSelectedTorrents(); + } + foreach(const QString &hash, hashes) { + QTorrentHandle h = BTSession->getTorrentHandle(hash); + if(h.is_paused()){ + h.resume(); + resumedTorrent(h); + if(inDownloadList) { + updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList()); + } else { + updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList()); + } + } + } +} + +void GUI::addUnauthenticatedTracker(QPair tracker) { + // Trackers whose authentication was cancelled + if(unauthenticated_trackers.indexOf(tracker) < 0) { + unauthenticated_trackers << tracker; + } +} + +// display properties of selected items +void GUI::on_actionTorrent_Properties_triggered() { + if(tabs->currentIndex() > 1) return; + switch(tabs->currentIndex()){ + case 1: // DL List + finishedTorrentTab->propertiesSelection(); + break; + default: + downloadingTorrentTab->propertiesSelection(); + } +} + +void GUI::updateLists(bool force) { + if(isVisible() || force) { + // update global informations + dlSpeedLbl->setText(tr("DL: %1 KiB/s").arg(QString(QByteArray::number(BTSession->getPayloadDownloadRate()/1024., 'f', 1)))); + upSpeedLbl->setText(tr("UP: %1 KiB/s").arg(QString(QByteArray::number(BTSession->getPayloadUploadRate()/1024., 'f', 1)))); std::vector torrents = BTSession->getTorrents(); std::vector::iterator torrentIT; for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) { QTorrentHandle h = QTorrentHandle(*torrentIT); if(!h.is_valid()) continue; - h.scrape_tracker(); - } - } - - void GUI::updateRatio() { - // Update ratio info - float ratio = 1.; - session_status sessionStatus = BTSession->getSessionStatus(); - if(sessionStatus.total_payload_download == 0) { - if(sessionStatus.total_payload_upload == 0) - ratio = 1.; - else - ratio = 10.; - }else{ - ratio = (double)sessionStatus.total_payload_upload / (double)sessionStatus.total_payload_download; - if(ratio > 10.) - ratio = 10.; - } - ratioLbl->setText(tr("Ratio: %1").arg(QString(QByteArray::number(ratio, 'f', 1)))); - // Update DHT nodes - DHTLbl->setText(tr("DHT: %1 nodes").arg(QString::number(sessionStatus.dht_nodes))); - } - - void GUI::on_actionWebsite_triggered() const { - QDesktopServices::openUrl(QUrl(QString::fromUtf8("http://www.qbittorrent.org"))); - } - - void GUI::on_actionDocumentation_triggered() const { - QDesktopServices::openUrl(QUrl(QString::fromUtf8("http://wiki.qbittorrent.org"))); - } - - void GUI::on_actionBugReport_triggered() const { - QDesktopServices::openUrl(QUrl(QString::fromUtf8("http://bugs.qbittorrent.org"))); - } - - void GUI::writeSettings() { - QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); - settings.beginGroup(QString::fromUtf8("MainWindow")); - settings.setValue(QString::fromUtf8("size"), size()); - settings.setValue(QString::fromUtf8("pos"), pos()); - settings.endGroup(); - } - - // called when a torrent has finished - void GUI::finishedTorrent(QTorrentHandle& h) const { - qDebug("In GUI, a torrent has finished"); - QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); - bool show_msg = true; - if(TorrentPersistentData::isSeed(h.hash())) - show_msg = false; - QString fileName = h.name(); - bool useNotificationBalloons = settings.value(QString::fromUtf8("Preferences/General/NotificationBaloons"), true).toBool(); - // Add it to finished tab - QString hash = h.hash(); - if(show_msg) - BTSession->addConsoleMessage(tr("%1 has finished downloading.", "e.g: xxx.avi has finished downloading.").arg(fileName)); - downloadingTorrentTab->deleteTorrent(hash); - finishedTorrentTab->addTorrent(hash); - if(show_msg && systrayIntegration && useNotificationBalloons) { - myTrayIcon->showMessage(tr("Download finished"), tr("%1 has finished downloading.", "e.g: xxx.avi has finished downloading.").arg(fileName), QSystemTrayIcon::Information, TIME_TRAY_BALLOON); - } - } - - void GUI::addedTorrent(QTorrentHandle& h) const { - if(h.is_seed()) { - finishedTorrentTab->addTorrent(h.hash()); - } else { - downloadingTorrentTab->addTorrent(h.hash()); - } - } - - void GUI::pausedTorrent(QTorrentHandle& h) const { - if(h.is_seed()) { - finishedTorrentTab->pauseTorrent(h.hash()); - } else { - downloadingTorrentTab->pauseTorrent(h.hash()); - } - } - - void GUI::resumedTorrent(QTorrentHandle& h) const { - if(h.is_seed()) { - finishedTorrentTab->updateTorrent(h); - } else { - downloadingTorrentTab->updateTorrent(h); - } - } - - void GUI::checkedTorrent(QTorrentHandle& h) const { - if(h.is_seed()) { - // Move torrent to finished tab - downloadingTorrentTab->deleteTorrent(h.hash()); - finishedTorrentTab->addTorrent(h.hash()); - } else { - // Move torrent back to download list (if necessary) - if(TorrentPersistentData::isSeed(h.hash())) { - TorrentPersistentData::saveSeedStatus(h); - finishedTorrentTab->deleteTorrent(h.hash()); - downloadingTorrentTab->addTorrent(h.hash()); + try { + if(h.is_seed()) { + // Update in finished list + finishedTorrentTab->updateTorrent(h); + } else { + // Update in download list + if(downloadingTorrentTab->updateTorrent(h)) { + // Torrent was added, we may need to remove it from finished tab + finishedTorrentTab->deleteTorrent(h.hash()); + TorrentPersistentData::saveSeedStatus(h); + } + } + } catch(invalid_handle e) { + qDebug("Caught Invalid handle exception, lucky us."); } } } - - // Notification when disk is full - void GUI::fullDiskError(QTorrentHandle& h, QString msg) const { - QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); - bool useNotificationBalloons = settings.value(QString::fromUtf8("Preferences/General/NotificationBaloons"), true).toBool(); - if(systrayIntegration && useNotificationBalloons) { - myTrayIcon->showMessage(tr("I/O Error", "i.e: Input/Output Error"), tr("An I/O error occured for torrent %1.\n Reason: %2", "e.g: An error occured for torrent xxx.avi.\n Reason: disk is full.").arg(h.name()).arg(msg), QSystemTrayIcon::Critical, TIME_TRAY_BALLOON); - } - // Download will be paused by libtorrent. Updating GUI information accordingly - QString hash = h.hash(); - qDebug("Full disk error, pausing torrent %s", hash.toLocal8Bit().data()); - setPaused(h); - BTSession->addConsoleMessage(tr("An error occured (full disk?), '%1' paused.", "e.g: An error occured (full disk?), 'xxx.avi' paused.").arg(h.name())); - } - - void GUI::setPaused(QTorrentHandle &h) const { - if(!h.is_paused()) { - // FIXME in v1.6.0: Add Error state and stop using pause for this - h.pause(); - } - qDebug("Marking torrent %s as paused", h.hash().toLocal8Bit().data()); - if(h.is_seed()) { - // In finished list - qDebug("Automatically paused torrent was in finished list"); - finishedTorrentTab->pauseTorrent(h.hash()); - }else{ - downloadingTorrentTab->pauseTorrent(h.hash()); - } - } - - void GUI::createKeyboardShortcuts() { - actionCreate_torrent->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+N"))); - actionOpen->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+O"))); - actionExit->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+Q"))); - switchDownShortcut = new QShortcut(QKeySequence(tr("Alt+1", "shortcut to switch to first tab")), this); - connect(switchDownShortcut, SIGNAL(activated()), this, SLOT(displayDownTab())); - switchUpShortcut = new QShortcut(QKeySequence(tr("Alt+2", "shortcut to switch to second tab")), this); - connect(switchUpShortcut, SIGNAL(activated()), this, SLOT(displayUpTab())); - switchSearchShortcut = new QShortcut(QKeySequence(tr("Alt+3", "shortcut to switch to third tab")), this); - connect(switchSearchShortcut, SIGNAL(activated()), this, SLOT(displaySearchTab())); - switchSearchShortcut2 = new QShortcut(QKeySequence(tr("Ctrl+F", "shortcut to switch to search tab")), this); - connect(switchSearchShortcut2, SIGNAL(activated()), this, SLOT(displaySearchTab())); - switchRSSShortcut = new QShortcut(QKeySequence(tr("Alt+4", "shortcut to switch to fourth tab")), this); - connect(switchRSSShortcut, SIGNAL(activated()), this, SLOT(displayRSSTab())); - actionTorrent_Properties->setShortcut(QKeySequence(QString::fromUtf8("Alt+P"))); - actionOptions->setShortcut(QKeySequence(QString::fromUtf8("Alt+O"))); - actionDelete->setShortcut(QKeySequence(QString::fromUtf8("Del"))); - actionDelete_Permanently->setShortcut(QKeySequence(QString::fromUtf8("Shift+Del"))); - actionStart->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+S"))); - actionStart_All->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+Shift+S"))); - actionPause->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+P"))); - actionPause_All->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+Shift+P"))); - actionDecreasePriority->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+-"))); - actionIncreasePriority->setShortcut(QKeySequence(QString::fromUtf8("Ctrl++"))); - } - - // Keyboard shortcuts slots - void GUI::displayDownTab() const { - tabs->setCurrentIndex(0); - } - - void GUI::displayUpTab() const { - tabs->setCurrentIndex(1); - } - - void GUI::displaySearchTab() const { - tabs->setCurrentIndex(2); - } - - void GUI::displayRSSTab() const { - tabs->setCurrentIndex(3); - } - - // End of keyboard shortcuts slots - - void GUI::readSettings() { - QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); - settings.beginGroup(QString::fromUtf8("MainWindow")); - resize(settings.value(QString::fromUtf8("size"), size()).toSize()); - move(settings.value(QString::fromUtf8("pos"), screenCenter()).toPoint()); - settings.endGroup(); - } - - void GUI::balloonClicked() { - if(isHidden()) { - show(); - if(isMinimized()) { - showNormal(); - } - raise(); - activateWindow(); - } - } - - void GUI::acceptConnection() { - clientConnection = localServer->nextPendingConnection(); - connect(clientConnection, SIGNAL(disconnected()), this, SLOT(readParamsOnSocket())); - qDebug("accepted connection from another instance"); - } - - void GUI::readParamsOnSocket() { - if(clientConnection) { - QByteArray params = clientConnection->readAll(); - if(!params.isEmpty()) { - processParams(QString::fromUtf8(params.data()).split(QString::fromUtf8("\n"))); - qDebug("Received parameters from another instance"); - } - } - } - - void GUI::handleDownloadFromUrlFailure(QString url, QString reason) const{ - // Display a message box - QMessageBox::critical(0, tr("Url download error"), tr("Couldn't download file at url: %1, reason: %2.").arg(url).arg(reason)); - } - - void GUI::on_actionSet_global_upload_limit_triggered() { - qDebug("actionSet_global_upload_limit_triggered"); - new BandwidthAllocationDialog(this, true, BTSession, QStringList()); - } - - void GUI::on_actionShow_console_triggered() { - new consoleDlg(this, BTSession); - } - - void GUI::on_actionSet_global_download_limit_triggered() { - qDebug("actionSet_global_download_limit_triggered"); - new BandwidthAllocationDialog(this, false, BTSession, QStringList()); - } - - void GUI::on_actionPreview_file_triggered() { - QString hash; - switch(tabs->currentIndex()){ - case 0: - hash = downloadingTorrentTab->getSelectedTorrents(true).first(); - break; - case 1: - hash = finishedTorrentTab->getSelectedTorrents(true).first(); - break; - default: - return; - } - QTorrentHandle h = BTSession->getTorrentHandle(hash); - new previewSelect(this, h); - } - - void GUI::openDestinationFolder() const { - QStringList hashes; - switch(tabs->currentIndex()){ - case 0: - hashes = downloadingTorrentTab->getSelectedTorrents(true); - break; - case 1: - hashes = finishedTorrentTab->getSelectedTorrents(true); - break; - default: - return; - } - QStringList pathsList; - foreach(const QString &hash, hashes) { - QTorrentHandle h = BTSession->getTorrentHandle(hash); - QString savePath = h.save_path(); - if(!pathsList.contains(savePath)) { - pathsList.append(savePath); - QDesktopServices::openUrl(QString("file://")+savePath); - } - } + if(displaySpeedInTitle) { + QString dl_rate = QByteArray::number(BTSession->getSessionStatus().payload_download_rate/1024, 'f', 1); + QString up_rate = QByteArray::number(BTSession->getSessionStatus().payload_upload_rate/1024, 'f', 1); + setWindowTitle(tr("qBittorrent %1 (DL: %2KiB/s, UP: %3KiB/s)", "%1 is qBittorrent version").arg(QString::fromUtf8(VERSION)).arg(dl_rate).arg(up_rate)); } +} - void GUI::copyMagnetURI() const { - QStringList hashes; - switch(tabs->currentIndex()){ - case 0: - hashes = downloadingTorrentTab->getSelectedTorrents(); - break; - case 1: - hashes = finishedTorrentTab->getSelectedTorrents(); - break; - default: - return; - } - QStringList magnet_uris; - foreach(QString hash, hashes) { - QTorrentHandle h = BTSession->getTorrentHandle(hash); - if(h.is_valid()) { - magnet_uris << misc::toQString(make_magnet_uri(h.get_torrent_info())); - } - } - qApp->clipboard()->setText(magnet_uris.join("\n")); +// Called when a tracker requires authentication +void GUI::trackerAuthenticationRequired(QTorrentHandle& h) { + if(unauthenticated_trackers.indexOf(QPair(h, h.current_tracker())) < 0) { + // Tracker login + new trackerLogin(this, h); } - - void GUI::goBuyPage() const { - QStringList hashes; - switch(tabs->currentIndex()){ - case 0: - hashes = downloadingTorrentTab->getSelectedTorrents(true); - break; - case 1: - hashes = finishedTorrentTab->getSelectedTorrents(true); - break; - default: - return; - } - QStringList pathsList; - foreach(const QString &hash, hashes) { - QTorrentHandle h = BTSession->getTorrentHandle(hash); - QDesktopServices::openUrl("http://match.sharemonkey.com/?info_hash="+hash+"&n="+h.name()+"&cid=33"); - } - } - - // Necessary if we want to close the window - // in one time if "close to systray" is enabled - void GUI::on_actionExit_triggered() { - force_exit = true; - close(); - } - - void GUI::previewFile(QString filePath) { - QDesktopServices::openUrl(QString("file://")+filePath); - } - - int GUI::getCurrentTabIndex() const{ - if(isMinimized() || isHidden()) - return -1; - return tabs->currentIndex(); - } - - void GUI::setTabText(int index, QString text) const { - tabs->setTabText(index, text); - } - - // Toggle Main window visibility - void GUI::toggleVisibility(QSystemTrayIcon::ActivationReason e) { - if(e == QSystemTrayIcon::Trigger || e == QSystemTrayIcon::DoubleClick) { - if(isHidden()) { - show(); - if(isMinimized()) { - if(isMaximized()) { - showMaximized(); - }else{ - showNormal(); - } - } - raise(); - activateWindow(); - }else{ - hide(); - } - } - } - - // Center window - QPoint GUI::screenCenter() const{ - int scrn = 0; - QWidget *w = this->topLevelWidget(); - - if(w) - scrn = QApplication::desktop()->screenNumber(w); - else if(QApplication::desktop()->isVirtualDesktop()) - scrn = QApplication::desktop()->screenNumber(QCursor::pos()); - else - scrn = QApplication::desktop()->screenNumber(this); - - QRect desk(QApplication::desktop()->availableGeometry(scrn)); - return QPoint((desk.width() - this->frameGeometry().width()) / 2, (desk.height() - this->frameGeometry().height()) / 2); - } - - // Display About Dialog - void GUI::on_actionAbout_triggered() { - //About dialog - new about(this); - } - - void GUI::showEvent(QShowEvent *e) { - qDebug("** Show Event **"); - updateLists(true); - e->accept(); - } - - // Called when we close the program - void GUI::closeEvent(QCloseEvent *e) { - - QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); - bool goToSystrayOnExit = settings.value(QString::fromUtf8("Preferences/General/CloseToTray"), false).toBool(); - if(!force_exit && systrayIntegration && goToSystrayOnExit && !this->isHidden()) { - hide(); - //e->ignore(); - e->accept(); - return; - } - if(settings.value(QString::fromUtf8("Preferences/General/ExitConfirm"), true).toBool() && downloadingTorrentTab->getNbTorrentsInList()) { - show(); - if(!isMaximized()) - showNormal(); - if(e->spontaneous() == true || force_exit == true) { - if(QMessageBox::question(this, - tr("Are you sure you want to quit?")+QString::fromUtf8(" -- ")+tr("qBittorrent"), - tr("The download list is not empty.\nAre you sure you want to quit qBittorrent?"), - tr("&Yes"), tr("&No"), - QString(), 0, 1)) { - e->ignore(); - force_exit = false; - return; - } - } - } - hide(); - if(systrayIntegration) { - // Hide tray icon - myTrayIcon->hide(); - } - // Save window size, columns size - writeSettings(); - // Accept exit - e->accept(); - qApp->exit(); - } - - - // Display window to create a torrent - void GUI::on_actionCreate_torrent_triggered() { - createtorrent *ct = new createtorrent(this); - connect(ct, SIGNAL(torrent_to_seed(QString)), this, SLOT(addTorrent(QString))); - } - - bool GUI::event(QEvent * e) { - if(e->type() == QEvent::WindowStateChange) { - //Now check to see if the window is minimised - if(isMinimized()) { - qDebug("minimisation"); - QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); - if(systrayIntegration && settings.value(QString::fromUtf8("Preferences/General/MinimizeToTray"), false).toBool()) { - hide(); - } - } - } - return QMainWindow::event(e); - } - - // Action executed when a file is dropped - void GUI::dropEvent(QDropEvent *event) { - event->acceptProposedAction(); - QStringList files; - if(event->mimeData()->hasUrls()) { - QList urls = event->mimeData()->urls(); - foreach(const QUrl &url, urls) { - QString tmp = url.toString().trimmed(); - if(!tmp.isEmpty()) - files << url.toString(); - } - } else { - files = event->mimeData()->text().split(QString::fromUtf8("\n")); - } - // Add file to download list - QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); - bool useTorrentAdditionDialog = settings.value(QString::fromUtf8("Preferences/Downloads/AdditionDialog"), true).toBool(); - foreach(QString file, files) { - file = file.trimmed().replace(QString::fromUtf8("file://"), QString::fromUtf8(""), Qt::CaseInsensitive); - qDebug("Dropped file %s on download list", file.toLocal8Bit().data()); - if(file.startsWith(QString::fromUtf8("http://"), Qt::CaseInsensitive) || file.startsWith(QString::fromUtf8("ftp://"), Qt::CaseInsensitive) || file.startsWith(QString::fromUtf8("https://"), Qt::CaseInsensitive)) { - BTSession->downloadFromUrl(file); - continue; - } - if(file.startsWith("magnet:", Qt::CaseInsensitive)) { - // FIXME: Possibly skipped torrent addition dialog - BTSession->addMagnetUri(file); - continue; - } - if(useTorrentAdditionDialog) { - torrentAdditionDialog *dialog = new torrentAdditionDialog(this, BTSession); - dialog->showLoad(file); - }else{ - BTSession->addTorrent(file); - } - } - } - - // Decode if we accept drag 'n drop or not - void GUI::dragEnterEvent(QDragEnterEvent *event) { - foreach(const QString &mime, event->mimeData()->formats()){ - qDebug("mimeData: %s", mime.toLocal8Bit().data()); - } - if (event->mimeData()->hasFormat(QString::fromUtf8("text/plain")) || event->mimeData()->hasFormat(QString::fromUtf8("text/uri-list"))) { - event->acceptProposedAction(); - } - } - - /***************************************************** - * * - * Torrent * - * * - *****************************************************/ - - // Display a dialog to allow user to add - // torrents to download list - void GUI::on_actionOpen_triggered() { - QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); - // Open File Open Dialog - // Note: it is possible to select more than one file - QStringList pathsList = QFileDialog::getOpenFileNames(0, - tr("Open Torrent Files"), settings.value(QString::fromUtf8("MainWindowLastDir"), QDir::homePath()).toString(), - tr("Torrent Files")+QString::fromUtf8(" (*.torrent)")); - if(!pathsList.empty()) { - bool useTorrentAdditionDialog = settings.value(QString::fromUtf8("Preferences/Downloads/AdditionDialog"), true).toBool(); - unsigned int listSize = pathsList.size(); - for(unsigned int i=0; ishowLoad(pathsList.at(i)); - }else{ - BTSession->addTorrent(pathsList.at(i)); - } - } - // Save last dir to remember it - QStringList top_dir = pathsList.at(0).split(QDir::separator()); - top_dir.removeLast(); - settings.setValue(QString::fromUtf8("MainWindowLastDir"), top_dir.join(QDir::separator())); - } - } - - // delete from download list AND from hard drive - void GUI::on_actionDelete_Permanently_triggered() { - QStringList hashes; - bool inDownloadList = true; - switch(tabs->currentIndex()){ - case 0: - hashes = downloadingTorrentTab->getSelectedTorrents(); - break; - case 1: - hashes = finishedTorrentTab->getSelectedTorrents(); - inDownloadList = false; - break; - default: - return; - } - if(hashes.empty()) return; - int ret; - if(inDownloadList) { - ret = QMessageBox::question( - this, - tr("Are you sure? -- qBittorrent"), - tr("Are you sure you want to delete the selected item(s) from download list and from hard drive?"), - tr("&Yes"), tr("&No"), - QString(), 0, 1); - }else{ - ret = QMessageBox::question( - this, - tr("Are you sure? -- qBittorrent"), - tr("Are you sure you want to delete the selected item(s) from finished list and from hard drive?"), - tr("&Yes"), tr("&No"), - QString(), 0, 1); - } - if(ret) return; - //User clicked YES - foreach(const QString &hash, hashes) { - // Get the file name - QTorrentHandle h = BTSession->getTorrentHandle(hash); - QString fileName = h.name(); - // Remove the torrent - BTSession->deleteTorrent(hash, true); - } - } - - void GUI::deleteTorrent(QString hash) { - // Delete item from list - downloadingTorrentTab->deleteTorrent(hash); - finishedTorrentTab->deleteTorrent(hash); - } - - // delete selected items in the list - void GUI::on_actionDelete_triggered() { - QStringList hashes; - bool inDownloadList = true; - switch(tabs->currentIndex()){ - case 0: // DL - hashes = downloadingTorrentTab->getSelectedTorrents(); - break; - case 1: // SEED - hashes = finishedTorrentTab->getSelectedTorrents(); - inDownloadList = false; - break; - case 3: //RSSImp - rssWidget->deleteSelectedItems(); - return; - default: - return; - } - if(hashes.empty()) return; - int ret; - if(inDownloadList) { - ret = QMessageBox::question( - this, - tr("Are you sure? -- qBittorrent"), - tr("Are you sure you want to delete the selected item(s) in download list?"), - tr("&Yes"), tr("&No"), - QString(), 0, 1); - } else { - ret = QMessageBox::question( - this, - tr("Are you sure? -- qBittorrent"), - tr("Are you sure you want to delete the selected item(s) in finished list?"), - tr("&Yes"), tr("&No"), - QString(), 0, 1); - } - if(ret) return; - //User clicked YES - foreach(const QString &hash, hashes) { - // Get the file name - QTorrentHandle h = BTSession->getTorrentHandle(hash); - QString fileName = h.name(); - // Remove the torrent - BTSession->deleteTorrent(hash, false); - } - } - - // As program parameters, we can get paths or urls. - // This function parse the parameters and call - // the right addTorrent function, considering - // the parameter type. - void GUI::processParams(const QStringList& params) { - QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); - bool useTorrentAdditionDialog = settings.value(QString::fromUtf8("Preferences/Downloads/AdditionDialog"), true).toBool(); - foreach(QString param, params) { - param = param.trimmed(); - if(param.startsWith("--")) continue; - if(param.startsWith(QString::fromUtf8("http://"), Qt::CaseInsensitive) || param.startsWith(QString::fromUtf8("ftp://"), Qt::CaseInsensitive) || param.startsWith(QString::fromUtf8("https://"), Qt::CaseInsensitive)) { - BTSession->downloadFromUrl(param); - }else{ - if(param.startsWith("magnet:", Qt::CaseInsensitive)) { - // FIXME: Possibily skipped torrent addition dialog - BTSession->addMagnetUri(param); - } else { - if(useTorrentAdditionDialog) { - torrentAdditionDialog *dialog = new torrentAdditionDialog(this, BTSession); - dialog->showLoad(param); - }else{ - BTSession->addTorrent(param); - } - } - } - } - } - - void GUI::addTorrent(QString path) { - BTSession->addTorrent(path); - } - - void GUI::processDownloadedFiles(QString path, QString url) { - QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); - bool useTorrentAdditionDialog = settings.value(QString::fromUtf8("Preferences/Downloads/AdditionDialog"), true).toBool(); - if(useTorrentAdditionDialog) { - torrentAdditionDialog *dialog = new torrentAdditionDialog(this, BTSession); - dialog->showLoad(path, url); - }else{ - BTSession->addTorrent(path, false, url); - } - } - - // Set BT session configuration - void GUI::configureSession(bool deleteOptions) { - qDebug("Configuring session"); - // General - bool new_displaySpeedInTitle = options->speedInTitleBar(); - if(!new_displaySpeedInTitle && new_displaySpeedInTitle != displaySpeedInTitle) { - // Reset title - setWindowTitle(tr("qBittorrent %1", "e.g: qBittorrent v0.x").arg(QString::fromUtf8(VERSION))); - } - displaySpeedInTitle = new_displaySpeedInTitle; - if(options->isToolbarDisplayed()) { - toolBar->setVisible(true); - toolBar->layout()->setSpacing(7); - } else { - toolBar->setVisible(false); - } - unsigned int new_refreshInterval = options->getRefreshInterval(); - if(refreshInterval != new_refreshInterval) { - refreshInterval = new_refreshInterval; - refresher->start(refreshInterval); - } - // Downloads - // * Save path - BTSession->setDefaultSavePath(options->getSavePath()); - if(options->isTempPathEnabled()) { - BTSession->setDefaultTempPath(options->getTempPath()); - } else { - BTSession->setDefaultTempPath(QString::null); - } - BTSession->preAllocateAllFiles(options->preAllocateAllFiles()); - BTSession->startTorrentsInPause(options->addTorrentsInPause()); - // * Scan dir - if(options->getScanDir().isNull()) { - BTSession->disableDirectoryScanning(); - }else{ - //Interval first - BTSession->enableDirectoryScanning(options->getScanDir()); - } - // Connection - // * Ports binding - unsigned short old_listenPort = BTSession->getListenPort(); - BTSession->setListeningPort(options->getPort()); - unsigned short new_listenPort = BTSession->getListenPort(); - if(new_listenPort != old_listenPort) { - BTSession->addConsoleMessage(tr("qBittorrent is bound to port: TCP/%1", "e.g: qBittorrent is bound to port: 6881").arg( misc::toQString(new_listenPort))); - } - // * Global download limit - QPair limits = options->getGlobalBandwidthLimits(); - if(limits.first <= 0) { - // Download limit disabled - BTSession->setDownloadRateLimit(-1); - } else { - // Enabled - BTSession->setDownloadRateLimit(limits.first*1024); - } - // * Global Upload limit - if(limits.second <= 0) { - // Upload limit disabled - BTSession->setUploadRateLimit(-1); - } else { - // Enabled - BTSession->setUploadRateLimit(limits.second*1024); - } - // * UPnP - if(options->isUPnPEnabled()) { - BTSession->enableUPnP(true); - BTSession->addConsoleMessage(tr("UPnP support [ON]"), QString::fromUtf8("blue")); - } else { - BTSession->enableUPnP(false); - BTSession->addConsoleMessage(tr("UPnP support [OFF]"), QString::fromUtf8("blue")); - } - // * NAT-PMP - if(options->isNATPMPEnabled()) { - BTSession->enableNATPMP(true); - BTSession->addConsoleMessage(tr("NAT-PMP support [ON]"), QString::fromUtf8("blue")); - } else { - BTSession->enableNATPMP(false); - BTSession->addConsoleMessage(tr("NAT-PMP support [OFF]"), QString::fromUtf8("blue")); - } - // * Session settings - session_settings sessionSettings; - if(options->shouldSpoofAzureus()) { - sessionSettings.user_agent = "Azureus 3.0.5.2"; - } else { - sessionSettings.user_agent = "qBittorrent "VERSION; - } - sessionSettings.upnp_ignore_nonrouters = true; - sessionSettings.use_dht_as_fallback = false; - // To keep same behavior as in qbittorrent v1.2.0 - sessionSettings.rate_limit_ip_overhead = false; - // Queueing System - if(options->isQueueingSystemEnabled()) { - if(!BTSession->isQueueingEnabled()) { - downloadingTorrentTab->hidePriorityColumn(false); - actionDecreasePriority->setVisible(true); - actionIncreasePriority->setVisible(true); - prioSeparator->setVisible(true); - prioSeparator2->setVisible(true); - toolBar->layout()->setSpacing(7); - } - int max_torrents = options->getMaxActiveTorrents(); - int max_uploads = options->getMaxActiveUploads(); - int max_downloads = options->getMaxActiveDownloads(); - sessionSettings.active_downloads = max_downloads; - sessionSettings.active_seeds = max_uploads; - sessionSettings.active_limit = max_torrents; - sessionSettings.dont_count_slow_torrents = false; - BTSession->setQueueingEnabled(true); - } else { - if(BTSession->isQueueingEnabled()) { - sessionSettings.active_downloads = -1; - sessionSettings.active_seeds = -1; - sessionSettings.active_limit = -1; - BTSession->setQueueingEnabled(false); - downloadingTorrentTab->hidePriorityColumn(true); - actionDecreasePriority->setVisible(false); - actionIncreasePriority->setVisible(false); - prioSeparator->setVisible(false); - prioSeparator2->setVisible(false); - toolBar->layout()->setSpacing(7); - } - } - BTSession->setSessionSettings(sessionSettings); - // Bittorrent - // * Max connections limit - BTSession->setMaxConnections(options->getMaxConnecs()); - // * Max connections per torrent limit - BTSession->setMaxConnectionsPerTorrent(options->getMaxConnecsPerTorrent()); - // * Max uploads per torrent limit - BTSession->setMaxUploadsPerTorrent(options->getMaxUploadsPerTorrent()); - // * DHT - if(options->isDHTEnabled()) { - // Set DHT Port - BTSession->setDHTPort(options->getDHTPort()); - if(BTSession->enableDHT(true)) { - int dht_port = new_listenPort; - if(options->getDHTPort()) - dht_port = options->getDHTPort(); - BTSession->addConsoleMessage(tr("DHT support [ON], port: UDP/%1").arg(dht_port), QString::fromUtf8("blue")); - } else { - BTSession->addConsoleMessage(tr("DHT support [OFF]"), QString::fromUtf8("red")); - } - } else { - BTSession->enableDHT(false); - BTSession->addConsoleMessage(tr("DHT support [OFF]"), QString::fromUtf8("blue")); - } - // * PeX - BTSession->addConsoleMessage(tr("PeX support [ON]"), QString::fromUtf8("blue")); - // * LSD - if(options->isLSDEnabled()) { - BTSession->enableLSD(true); - BTSession->addConsoleMessage(tr("Local Peer Discovery [ON]"), QString::fromUtf8("blue")); - } else { - BTSession->enableLSD(false); - BTSession->addConsoleMessage(tr("Local Peer Discovery support [OFF]"), QString::fromUtf8("blue")); - } - // * Encryption - int encryptionState = options->getEncryptionSetting(); - // The most secure, rc4 only so that all streams and encrypted - pe_settings encryptionSettings; - encryptionSettings.allowed_enc_level = pe_settings::rc4; - encryptionSettings.prefer_rc4 = true; - switch(encryptionState) { - case 0: //Enabled - encryptionSettings.out_enc_policy = pe_settings::enabled; - encryptionSettings.in_enc_policy = pe_settings::enabled; - BTSession->addConsoleMessage(tr("Encryption support [ON]"), QString::fromUtf8("blue")); - break; - case 1: // Forced - encryptionSettings.out_enc_policy = pe_settings::forced; - encryptionSettings.in_enc_policy = pe_settings::forced; - BTSession->addConsoleMessage(tr("Encryption support [FORCED]"), QString::fromUtf8("blue")); - break; - default: // Disabled - encryptionSettings.out_enc_policy = pe_settings::disabled; - encryptionSettings.in_enc_policy = pe_settings::disabled; - BTSession->addConsoleMessage(tr("Encryption support [OFF]"), QString::fromUtf8("blue")); - } - BTSession->applyEncryptionSettings(encryptionSettings); - // * Desired ratio - BTSession->setGlobalRatio(options->getDesiredRatio()); - // * Maximum ratio - BTSession->setDeleteRatio(options->getDeleteRatio()); - // Ip Filter - if(options->isFilteringEnabled()) { - BTSession->enableIPFilter(options->getFilter()); - }else{ - BTSession->disableIPFilter(); - } - // RSS - if(options->isRSSEnabled()) { - displayRSSTab(true); - } else { - displayRSSTab(false); - } - // * Proxy settings - proxy_settings proxySettings; - if(options->isProxyEnabled()) { - qDebug("Enabling P2P proxy"); - proxySettings.hostname = options->getProxyIp().toStdString(); - qDebug("hostname is %s", proxySettings.hostname.c_str()); - proxySettings.port = options->getProxyPort(); - qDebug("port is %d", proxySettings.port); - if(options->isProxyAuthEnabled()) { - - proxySettings.username = options->getProxyUsername().toStdString(); - proxySettings.password = options->getProxyPassword().toStdString(); - qDebug("username is %s", proxySettings.username.c_str()); - qDebug("password is %s", proxySettings.password.c_str()); - } - switch(options->getProxyType()) { - case HTTP: - qDebug("type: http"); - proxySettings.type = proxy_settings::http; - break; - case HTTP_PW: - qDebug("type: http_pw"); - proxySettings.type = proxy_settings::http_pw; - break; - case SOCKS5: - qDebug("type: socks5"); - proxySettings.type = proxy_settings::socks5; - break; - default: - qDebug("type: socks5_pw"); - proxySettings.type = proxy_settings::socks5_pw; - break; - } - qDebug("booleans: %d %d %d %d", options->useProxyForTrackers(), options->useProxyForPeers(), options->useProxyForWebseeds(), options->useProxyForDHT()); - BTSession->setProxySettings(proxySettings, options->useProxyForTrackers(), options->useProxyForPeers(), options->useProxyForWebseeds(), options->useProxyForDHT()); - } else { - qDebug("Disabling P2P proxy"); - BTSession->setProxySettings(proxySettings, false, false, false, false); - } - if(options->isHTTPProxyEnabled()) { - qDebug("Enabling Search HTTP proxy"); - // HTTP Proxy - QString proxy_str; - switch(options->getHTTPProxyType()) { - case HTTP_PW: - proxy_str = misc::toQString("http://")+options->getHTTPProxyUsername()+":"+options->getHTTPProxyPassword()+"@"+options->getHTTPProxyIp()+":"+misc::toQString(options->getHTTPProxyPort()); - break; - default: - proxy_str = misc::toQString("http://")+options->getHTTPProxyIp()+":"+misc::toQString(options->getHTTPProxyPort()); - } - // We need this for urllib in search engine plugins +} + +// Check connection status and display right icon +void GUI::checkConnectionStatus() { + // qDebug("Checking connection status"); + // Update Ratio + updateRatio(); + // update global informations + if(systrayIntegration) { #ifdef Q_WS_WIN - char proxystr[512]; - snprintf(proxystr, 512, "http_proxy=%s", proxy_str.toLocal8Bit().data()); - putenv(proxystr); + // Windows does not support html here + QString html =tr("DL speed: %1 KiB/s", "e.g: Download speed: 10 KiB/s").arg(QString(QByteArray::number(BTSession->getPayloadDownloadRate()/1024., 'f', 1))); + html += "\n"; + html += tr("UP speed: %1 KiB/s", "e.g: Upload speed: 10 KiB/s").arg(QString(QByteArray::number(BTSession->getPayloadUploadRate()/1024., 'f', 1))); #else - qDebug("HTTP: proxy string: %s", proxy_str.toLocal8Bit().data()); - setenv("http_proxy", proxy_str.toLocal8Bit().data(), 1); + QString html = "
"; + html += tr("qBittorrent"); + html += "
"; + html += "
"; + html += " "+tr("DL speed: %1 KiB/s", "e.g: Download speed: 10 KiB/s").arg(QString(QByteArray::number(BTSession->getPayloadDownloadRate()/1024., 'f', 1))); + html += "
"; + html += "
"; + html += " "+tr("UP speed: %1 KiB/s", "e.g: Upload speed: 10 KiB/s").arg(QString(QByteArray::number(BTSession->getPayloadUploadRate()/1024., 'f', 1))); + html += "
"; #endif - } else { - qDebug("Disabling search proxy"); -#ifdef Q_WS_WIN - putenv("http_proxy="); -#else - unsetenv("http_proxy"); -#endif - } - // Clean up - if(deleteOptions && options) { - qDebug("Deleting options"); - //delete options; - options->deleteLater(); - } - qDebug("Session configured"); + myTrayIcon->setToolTip(html); // tray icon } - - void GUI::updateUnfinishedTorrentNumber(unsigned int nb) { - unsigned int paused = BTSession->getUnfinishedPausedTorrentsNb(); - tabs->setTabText(0, tr("Downloads") +QString::fromUtf8(" (")+misc::toQString(nb-paused)+"/"+misc::toQString(nb)+QString::fromUtf8(")")); + session_status sessionStatus = BTSession->getSessionStatus(); + if(sessionStatus.has_incoming_connections) { + // Connection OK + connecStatusLblIcon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/skin/connected.png"))); + connecStatusLblIcon->setToolTip(QString::fromUtf8("")+tr("Connection Status:")+QString::fromUtf8("
")+tr("Online")); + }else{ + connecStatusLblIcon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/skin/firewalled.png"))); + connecStatusLblIcon->setToolTip(QString::fromUtf8("")+tr("Connection status:")+QString::fromUtf8("
")+QString::fromUtf8("")+tr("No direct connections. This may indicate network configuration problems.")+QString::fromUtf8("")); } - - void GUI::updateFinishedTorrentNumber(unsigned int nb) { - unsigned int paused = BTSession->getFinishedPausedTorrentsNb(); - tabs->setTabText(1, tr("Finished") +QString::fromUtf8(" (")+misc::toQString(nb-paused)+"/"+misc::toQString(nb)+QString::fromUtf8(")")); - } - - // Allow to change action on double-click - void GUI::torrentDoubleClicked(QString hash, bool finished) { - int action; - QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); - QTorrentHandle h = BTSession->getTorrentHandle(hash); - - if(finished) { - action = settings.value(QString::fromUtf8("Preferences/Downloads/DblClOnTorFN"), 0).toInt(); - } else { - action = settings.value(QString::fromUtf8("Preferences/Downloads/DblClOnTorDl"), 0).toInt(); - } - - switch(action) { - case TOGGLE_PAUSE: - this->togglePausedState(hash); - break; - case OPEN_DEST: { - QTorrentHandle h = BTSession->getTorrentHandle(hash); - QString savePath = h.save_path(); - QDesktopServices::openUrl(QUrl(savePath)); - break; - } - case SHOW_PROPERTIES : - if(finished) { - finishedTorrentTab->showPropertiesFromHash(hash); - } else { - downloadingTorrentTab->showPropertiesFromHash(hash); - } - break; - } - } - - // Toggle paused state of selected torrent - void GUI::togglePausedState(QString hash) { - if(tabs->currentIndex() > 1) return; - bool inDownloadList = true; - if(tabs->currentIndex() == 1) - inDownloadList = false; - QTorrentHandle h = BTSession->getTorrentHandle(hash); - if(h.is_paused()) { - h.resume(); - resumedTorrent(h); - if(inDownloadList) { - updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList()); - }else{ - updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList()); - } - }else{ - h.pause(); - pausedTorrent(h); - if(inDownloadList) { - updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList()); - }else{ - updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList()); - } - } - } - - // Pause All Downloads in DL list - void GUI::on_actionPause_All_triggered() { - bool change = false; - std::vector torrents = BTSession->getTorrents(); - std::vector::iterator torrentIT; - for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) { - QTorrentHandle h = QTorrentHandle(*torrentIT); - if(!h.is_valid() || h.is_paused()) continue; - change = true; - h.pause(); - pausedTorrent(h); - } - if(change) { - updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList()); - updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList()); - } - } - - void GUI::on_actionIncreasePriority_triggered() { - if(tabs->currentIndex() != 0) - return; - QStringList hashes = downloadingTorrentTab->getSelectedTorrents(); - foreach(const QString &hash, hashes) { - BTSession->increaseDlTorrentPriority(hash); - } - updateLists(); - } - - void GUI::on_actionDecreasePriority_triggered() { - Q_ASSERT(tabs->currentIndex() == 0); - QStringList hashes = downloadingTorrentTab->getSelectedTorrents(); - foreach(const QString &hash, hashes) { - BTSession->decreaseDlTorrentPriority(hash); - } - updateLists(); - } - - // pause selected items in the list - void GUI::on_actionPause_triggered() { - bool inDownloadList = true; - if(tabs->currentIndex() > 1) return; - if(tabs->currentIndex() == 1) - inDownloadList = false; - QStringList hashes; - if(inDownloadList) { - hashes = downloadingTorrentTab->getSelectedTorrents(); - } else { - hashes = finishedTorrentTab->getSelectedTorrents(); - } - qDebug("nb hashes: %d", hashes.size()); - foreach(const QString &hash, hashes) { - QTorrentHandle h = BTSession->getTorrentHandle(hash); - if(!h.is_paused()){ - h.pause(); - pausedTorrent(h); - if(inDownloadList) { - updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList()); - } else { - updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList()); - } - } - } - } - - // Resume All Downloads in DL list - void GUI::on_actionStart_All_triggered() { - bool change = false; - std::vector torrents = BTSession->getTorrents(); - std::vector::iterator torrentIT; - for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) { - QTorrentHandle h = QTorrentHandle(*torrentIT); - if(!h.is_valid() || !h.is_paused()) continue; - change = true; - h.resume(); - resumedTorrent(h); - } - if(change) { - updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList()); - updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList()); - } - } - - // start selected items in the list - void GUI::on_actionStart_triggered() { - bool inDownloadList = true; - if(tabs->currentIndex() > 1) return; - if(tabs->currentIndex() == 1) - inDownloadList = false; - QStringList hashes; - if(inDownloadList) { - hashes = downloadingTorrentTab->getSelectedTorrents(); - } else { - hashes = finishedTorrentTab->getSelectedTorrents(); - } - foreach(const QString &hash, hashes) { - QTorrentHandle h = BTSession->getTorrentHandle(hash); - if(h.is_paused()){ - h.resume(); - resumedTorrent(h); - if(inDownloadList) { - updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList()); - } else { - updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList()); - } - } - } - } - - void GUI::addUnauthenticatedTracker(QPair tracker) { - // Trackers whose authentication was cancelled - if(unauthenticated_trackers.indexOf(tracker) < 0) { - unauthenticated_trackers << tracker; - } - } - - // display properties of selected items - void GUI::on_actionTorrent_Properties_triggered() { - if(tabs->currentIndex() > 1) return; - switch(tabs->currentIndex()){ - case 1: // DL List - finishedTorrentTab->propertiesSelection(); - break; - default: - downloadingTorrentTab->propertiesSelection(); - } - } - - void GUI::updateLists(bool force) { - if(isVisible() || force) { - // update global informations - dlSpeedLbl->setText(tr("DL: %1 KiB/s").arg(QString(QByteArray::number(BTSession->getPayloadDownloadRate()/1024., 'f', 1)))); - upSpeedLbl->setText(tr("UP: %1 KiB/s").arg(QString(QByteArray::number(BTSession->getPayloadUploadRate()/1024., 'f', 1)))); - std::vector torrents = BTSession->getTorrents(); - std::vector::iterator torrentIT; - for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) { - QTorrentHandle h = QTorrentHandle(*torrentIT); - if(!h.is_valid()) continue; - try { - if(h.is_seed()) { - // Update in finished list - finishedTorrentTab->updateTorrent(h); - } else { - // Update in download list - if(downloadingTorrentTab->updateTorrent(h)) { - // Torrent was added, we may need to remove it from finished tab - finishedTorrentTab->deleteTorrent(h.hash()); - TorrentPersistentData::saveSeedStatus(h); - } - } - } catch(invalid_handle e) { - qDebug("Caught Invalid handle exception, lucky us."); - } - } - } - if(displaySpeedInTitle) { - QString dl_rate = QByteArray::number(BTSession->getSessionStatus().payload_download_rate/1024, 'f', 1); - QString up_rate = QByteArray::number(BTSession->getSessionStatus().payload_upload_rate/1024, 'f', 1); - setWindowTitle(tr("qBittorrent %1 (DL: %2KiB/s, UP: %3KiB/s)", "%1 is qBittorrent version").arg(QString::fromUtf8(VERSION)).arg(dl_rate).arg(up_rate)); - } - } - - // Called when a tracker requires authentication - void GUI::trackerAuthenticationRequired(QTorrentHandle& h) { - if(unauthenticated_trackers.indexOf(QPair(h, h.current_tracker())) < 0) { - // Tracker login - new trackerLogin(this, h); - } - } - - // Check connection status and display right icon - void GUI::checkConnectionStatus() { - // qDebug("Checking connection status"); - // Update Ratio - updateRatio(); - // update global informations - if(systrayIntegration) { -#ifdef Q_WS_WIN - // Windows does not support html here - QString html =tr("DL speed: %1 KiB/s", "e.g: Download speed: 10 KiB/s").arg(QString(QByteArray::number(BTSession->getPayloadDownloadRate()/1024., 'f', 1))); - html += "\n"; - html += tr("UP speed: %1 KiB/s", "e.g: Upload speed: 10 KiB/s").arg(QString(QByteArray::number(BTSession->getPayloadUploadRate()/1024., 'f', 1))); -#else - QString html = "
"; - html += tr("qBittorrent"); - html += "
"; - html += "
"; - html += " "+tr("DL speed: %1 KiB/s", "e.g: Download speed: 10 KiB/s").arg(QString(QByteArray::number(BTSession->getPayloadDownloadRate()/1024., 'f', 1))); - html += "
"; - html += "
"; - html += " "+tr("UP speed: %1 KiB/s", "e.g: Upload speed: 10 KiB/s").arg(QString(QByteArray::number(BTSession->getPayloadUploadRate()/1024., 'f', 1))); - html += "
"; -#endif - myTrayIcon->setToolTip(html); // tray icon - } - session_status sessionStatus = BTSession->getSessionStatus(); - if(sessionStatus.has_incoming_connections) { - // Connection OK - connecStatusLblIcon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/skin/connected.png"))); - connecStatusLblIcon->setToolTip(QString::fromUtf8("")+tr("Connection Status:")+QString::fromUtf8("
")+tr("Online")); - }else{ - connecStatusLblIcon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/skin/firewalled.png"))); - connecStatusLblIcon->setToolTip(QString::fromUtf8("")+tr("Connection status:")+QString::fromUtf8("
")+QString::fromUtf8("")+tr("No direct connections. This may indicate network configuration problems.")+QString::fromUtf8("")); - } - } - - /***************************************************** +} + +/***************************************************** * * * Utils * * * *****************************************************/ - - void GUI::downloadFromURLList(const QStringList& url_list) { - foreach(const QString url, url_list) { - if(url.startsWith("magnet:", Qt::CaseInsensitive)) { - BTSession->addMagnetUri(url); - } else { - BTSession->downloadFromUrl(url); - } + +void GUI::downloadFromURLList(const QStringList& url_list) { + foreach(const QString url, url_list) { + if(url.startsWith("magnet:", Qt::CaseInsensitive)) { + BTSession->addMagnetUri(url); + } else { + BTSession->downloadFromUrl(url); } } - - /***************************************************** +} + +/***************************************************** * * * Options * * * *****************************************************/ - - void GUI::createSystrayDelayed() { - static int timeout = 10; - if(QSystemTrayIcon::isSystemTrayAvailable()) { - // Ok, systray integration is now supported - // Create systray icon - createTrayIcon(); - systrayIntegration = true; - delete systrayCreator; + +void GUI::createSystrayDelayed() { + static int timeout = 10; + if(QSystemTrayIcon::isSystemTrayAvailable()) { + // Ok, systray integration is now supported + // Create systray icon + createTrayIcon(); + systrayIntegration = true; + delete systrayCreator; + } else { + if(timeout) { + // Retry a bit later + systrayCreator->start(1000); + --timeout; } else { - if(timeout) { - // Retry a bit later - systrayCreator->start(1000); - --timeout; - } else { - // Timed out, apparently system really does not - // support systray icon - delete systrayCreator; - } + // Timed out, apparently system really does not + // support systray icon + delete systrayCreator; } } - - void GUI::createTrayIcon() { - // Tray icon +} + +void GUI::createTrayIcon() { + // Tray icon #ifdef Q_WS_WIN - myTrayIcon = new QSystemTrayIcon(QIcon(QString::fromUtf8(":/Icons/skin/qbittorrent16.png")), this); + myTrayIcon = new QSystemTrayIcon(QIcon(QString::fromUtf8(":/Icons/skin/qbittorrent16.png")), this); #endif #ifndef Q_WS_WIN - myTrayIcon = new QSystemTrayIcon(QIcon(QString::fromUtf8(":/Icons/skin/qbittorrent22.png")), this); + myTrayIcon = new QSystemTrayIcon(QIcon(QString::fromUtf8(":/Icons/skin/qbittorrent22.png")), this); #endif - // Tray icon Menu - myTrayIconMenu = new QMenu(this); - myTrayIconMenu->addAction(actionOpen); - myTrayIconMenu->addAction(actionDownload_from_URL); - myTrayIconMenu->addSeparator(); - myTrayIconMenu->addAction(actionSet_global_download_limit); - myTrayIconMenu->addAction(actionSet_global_upload_limit); - myTrayIconMenu->addSeparator(); - myTrayIconMenu->addAction(actionStart_All); - myTrayIconMenu->addAction(actionPause_All); - myTrayIconMenu->addSeparator(); - myTrayIconMenu->addAction(actionExit); - myTrayIcon->setContextMenu(myTrayIconMenu); - connect(myTrayIcon, SIGNAL(messageClicked()), this, SLOT(balloonClicked())); - // End of Icon Menu - connect(myTrayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(toggleVisibility(QSystemTrayIcon::ActivationReason))); - myTrayIcon->show(); - } - - // Display Program Options - void GUI::on_actionOptions_triggered() { - options = new options_imp(this); - connect(options, SIGNAL(status_changed(bool)), this, SLOT(OptionsSaved(bool))); - options->show(); - } - - // Is executed each time options are saved - void GUI::OptionsSaved(bool deleteOptions) { - BTSession->addConsoleMessage(tr("Options were saved successfully.")); - bool newSystrayIntegration = options->systrayIntegration(); - if(newSystrayIntegration != systrayIntegration) { - if(newSystrayIntegration) { - // create the trayicon - createTrayIcon(); - } else { - // Destroy trayicon - delete myTrayIcon; - delete myTrayIconMenu; - } - systrayIntegration = newSystrayIntegration; + // Tray icon Menu + myTrayIconMenu = new QMenu(this); + myTrayIconMenu->addAction(actionOpen); + myTrayIconMenu->addAction(actionDownload_from_URL); + myTrayIconMenu->addSeparator(); + myTrayIconMenu->addAction(actionSet_global_download_limit); + myTrayIconMenu->addAction(actionSet_global_upload_limit); + myTrayIconMenu->addSeparator(); + myTrayIconMenu->addAction(actionStart_All); + myTrayIconMenu->addAction(actionPause_All); + myTrayIconMenu->addSeparator(); + myTrayIconMenu->addAction(actionExit); + myTrayIcon->setContextMenu(myTrayIconMenu); + connect(myTrayIcon, SIGNAL(messageClicked()), this, SLOT(balloonClicked())); + // End of Icon Menu + connect(myTrayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(toggleVisibility(QSystemTrayIcon::ActivationReason))); + myTrayIcon->show(); +} + +// Display Program Options +void GUI::on_actionOptions_triggered() { + options = new options_imp(this); + connect(options, SIGNAL(status_changed(bool)), this, SLOT(OptionsSaved(bool))); + options->show(); +} + +// Is executed each time options are saved +void GUI::OptionsSaved(bool deleteOptions) { + BTSession->addConsoleMessage(tr("Options were saved successfully.")); + bool newSystrayIntegration = options->systrayIntegration(); + if(newSystrayIntegration != systrayIntegration) { + if(newSystrayIntegration) { + // create the trayicon + createTrayIcon(); + } else { + // Destroy trayicon + delete myTrayIcon; + delete myTrayIconMenu; } - // Update Web UI - if (options->isWebUiEnabled()) { - quint16 port = options->webUiPort(); - QString username = options->webUiUsername(); - QString password = options->webUiPassword(); - initWebUi(username, password, port); - } else if(httpServer) { - delete httpServer; - } - // Update session - configureSession(deleteOptions); + systrayIntegration = newSystrayIntegration; } - - bool GUI::initWebUi(QString username, QString password, int port) { - if(httpServer) - httpServer->close(); - else - httpServer = new HttpServer(BTSession, 3000, this); - httpServer->setAuthorization(username, password); - bool success = httpServer->listen(QHostAddress::Any, port); - if (success) - qDebug("Web UI listening on port %d", port); - else - QMessageBox::critical(this, "Web User Interface Error", "Unable to initialize HTTP Server on port " + misc::toQString(port)); - return success; + // Update Web UI + if (options->isWebUiEnabled()) { + quint16 port = options->webUiPort(); + QString username = options->webUiUsername(); + QString password = options->webUiPassword(); + initWebUi(username, password, port); + } else if(httpServer) { + delete httpServer; } - - /***************************************************** + // Update session + configureSession(deleteOptions); +} + +bool GUI::initWebUi(QString username, QString password, int port) { + if(httpServer) + httpServer->close(); + else + httpServer = new HttpServer(BTSession, 3000, this); + httpServer->setAuthorization(username, password); + bool success = httpServer->listen(QHostAddress::Any, port); + if (success) + qDebug("Web UI listening on port %d", port); + else + QMessageBox::critical(this, "Web User Interface Error", "Unable to initialize HTTP Server on port " + misc::toQString(port)); + return success; +} + +/***************************************************** * * * HTTP Downloader * * * *****************************************************/ - - // Display an input dialog to prompt user for - // an url - void GUI::on_actionDownload_from_URL_triggered() { - downloadFromURL *downloadFromURLDialog = new downloadFromURL(this); - connect(downloadFromURLDialog, SIGNAL(urlsReadyToBeDownloaded(const QStringList&)), BTSession, SLOT(downloadFromURLList(const QStringList&))); - } - + +// Display an input dialog to prompt user for +// an url +void GUI::on_actionDownload_from_URL_triggered() { + downloadFromURL *downloadFromURLDialog = new downloadFromURL(this); + connect(downloadFromURLDialog, SIGNAL(urlsReadyToBeDownloaded(const QStringList&)), BTSession, SLOT(downloadFromURLList(const QStringList&))); +} +