diff --git a/Changelog b/Changelog index fbed539cb..2a65dc9d7 100644 --- a/Changelog +++ b/Changelog @@ -1,5 +1,6 @@ * Unreleased - Christophe Dumez - v2.2.0 - FEATURE: User can set alternative speed limits for fast toggling + - FEATURE: Bandwidth scheduler (automatically use alternative speed limits for a given period) * Mon Jan 18 2010 - Christophe Dumez - v2.1.0 - FEATURE: Graphical User Interface can be disabled at compilation time (headless running) diff --git a/src/GUI.cpp b/src/GUI.cpp index 87cec4dd5..2c11d8dd6 100644 --- a/src/GUI.cpp +++ b/src/GUI.cpp @@ -116,6 +116,7 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis connect(BTSession, SIGNAL(trackerAuthenticationRequired(QTorrentHandle&)), this, SLOT(trackerAuthenticationRequired(QTorrentHandle&))); connect(BTSession, SIGNAL(newDownloadedTorrent(QString, QString)), this, SLOT(processDownloadedFiles(QString, QString))); connect(BTSession, SIGNAL(downloadFromUrlFailure(QString, QString)), this, SLOT(handleDownloadFromUrlFailure(QString, QString))); + connect(BTSession, SIGNAL(alternativeSpeedsModeChanged(bool)), this, SLOT(updateAltSpeedsBtn(bool))); qDebug("create tabWidget"); tabs = new QTabWidget(); @@ -181,7 +182,6 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis // Create status bar status_bar = new StatusBar(QMainWindow::statusBar(), BTSession); connect(actionUse_alternative_speed_limits, SIGNAL(triggered()), status_bar, SLOT(toggleAlternativeSpeeds())); - connect(status_bar, SIGNAL(alternativeSpeedsToggled(bool)), this, SLOT(updateAltSpeedsBtn(bool))); show(); diff --git a/src/bandwidthscheduler.h b/src/bandwidthscheduler.h new file mode 100644 index 000000000..d9ed84cf2 --- /dev/null +++ b/src/bandwidthscheduler.h @@ -0,0 +1,111 @@ +#ifndef BANDWIDTHSCHEDULER_H +#define BANDWIDTHSCHEDULER_H + +#include +#include +#include +#include "preferences.h" +#include + +class BandwidthScheduler: public QTimer { + Q_OBJECT + +private: + bool in_alternative_mode; + +public: + BandwidthScheduler(QObject *parent): QTimer(parent), in_alternative_mode(false) { + Q_ASSERT(Preferences::isSchedulerEnabled()); + // Signal shot, we call start() again manually + setSingleShot(true); + // Connect Signals/Slots + connect(this, SIGNAL(timeout()), this, SLOT(switchMode())); + } + +public slots: + void start() { + Q_ASSERT(Preferences::isSchedulerEnabled()); + + QTime startAltSpeeds = Preferences::getSchedulerStartTime(); + QTime endAltSpeeds = Preferences::getSchedulerEndTime(); + if(startAltSpeeds == endAltSpeeds) { + std::cerr << "Error: bandwidth scheduler have the same start time and end time." << std::endl; + std::cerr << "The bandwidth scheduler will be disabled" << std::endl; + stop(); + emit switchToAlternativeMode(false); + return; + } + + // Determine what the closest QTime is + QTime now = QTime::currentTime(); + uint time_to_start = secsTo(now, startAltSpeeds); + uint time_to_end = secsTo(now, endAltSpeeds); + if(time_to_end < time_to_start) { + // We should be in alternative mode + in_alternative_mode = true; + // Start counting + QTimer::start(time_to_end*1000); + } else { + // We should be in normal mode + in_alternative_mode = false; + // Start counting + QTimer::start(time_to_start*1000); + } + // Send signal to notify BTSession + emit switchToAlternativeMode(in_alternative_mode); + } + + void switchMode() { + // Get the day this mode was started (either today or yesterday) + QDate current_date = QDateTime::currentDateTime().toLocalTime().date(); + int day = current_date.dayOfWeek(); + if(in_alternative_mode) { + // It is possible that starttime was yesterday + if(QTime::currentTime().secsTo(Preferences::getSchedulerStartTime()) > 0) { + current_date.addDays(-1); // Go to yesterday + day = current_date.day(); + } + } + // Check if the day is in scheduler days + // Notify BTSession only if necessary + switch(Preferences::getSchedulerDays()) { + case EVERY_DAY: + emit switchToAlternativeMode(!in_alternative_mode); + break; + case WEEK_ENDS: + if(day == Qt::Saturday || day == Qt::Sunday) + emit switchToAlternativeMode(!in_alternative_mode); + break; + case WEEK_DAYS: + if(day != Qt::Saturday && day != Qt::Sunday) + emit switchToAlternativeMode(!in_alternative_mode); + break; + default: + // Convert our enum index to Qt enum index + int scheduler_day = ((int)Preferences::getSchedulerDays()) - 2; + if(day == scheduler_day) + emit switchToAlternativeMode(!in_alternative_mode); + break; + } + // Call start again + start(); + } + +signals: + void switchToAlternativeMode(bool alternative); + +private: + // Qt function can return negative values and we + // don't want that + uint secsTo(QTime now, QTime t) { + int diff = now.secsTo(t); + if(diff < 0) { + // 86400 seconds in a day + diff += 86400; + } + Q_ASSERT(diff >= 0); + return diff; + } +}; + +#endif // BANDWIDTHSCHEDULER_H diff --git a/src/bittorrent.cpp b/src/bittorrent.cpp index 74dc354a6..e1c0b6d38 100644 --- a/src/bittorrent.cpp +++ b/src/bittorrent.cpp @@ -46,6 +46,7 @@ #endif #include "torrentpersistentdata.h" #include "httpserver.h" +#include "bandwidthscheduler.h" #include #ifdef LIBTORRENT_0_15 #include @@ -173,9 +174,10 @@ Bittorrent::~Bittorrent() { if(filterParser) delete filterParser; delete downloader; - if(FSWatcher) { + if(FSWatcher) delete FSWatcher; - } + if(bd_scheduler) + delete bd_scheduler; // HTTP Server if(httpServer) delete httpServer; @@ -313,6 +315,15 @@ void Bittorrent::configureSession() { // Enabled setUploadRateLimit(up_limit*1024); } + if(Preferences::isSchedulerEnabled()) { + if(!bd_scheduler) { + bd_scheduler = new BandwidthScheduler(this); + connect(bd_scheduler, SIGNAL(switchToAlternativeMode(bool)), this, SLOT(useAlternativeSpeedsLimit(bool))); + } + bd_scheduler->start(); + } else { + if(bd_scheduler) delete bd_scheduler; + } #ifndef DISABLE_GUI // Resolve countries qDebug("Loading country resolution settings"); @@ -587,6 +598,20 @@ bool Bittorrent::initWebUi(QString username, QString password, int port) { return success; } +void Bittorrent::useAlternativeSpeedsLimit(bool alternative) { + // Save new state to remember it on startup + Preferences::setAltBandwidthEnabled(alternative); + // Apply settings to the bittorrent session + if(alternative) { + s->set_download_rate_limit(Preferences::getAltGlobalDownloadLimit()*1024); + s->set_upload_rate_limit(Preferences::getAltGlobalUploadLimit()*1024); + } else { + s->set_download_rate_limit(Preferences::getGlobalDownloadLimit()*1024); + s->set_upload_rate_limit(Preferences::getGlobalUploadLimit()*1024); + } + emit alternativeSpeedsModeChanged(alternative); +} + void Bittorrent::takeETASamples() { bool change = false;; foreach(const QString &hash, ETA_samples.keys()) { diff --git a/src/bittorrent.h b/src/bittorrent.h index 69cd539af..8a75c96d7 100644 --- a/src/bittorrent.h +++ b/src/bittorrent.h @@ -55,6 +55,7 @@ class QTimer; class FileSystemWatcher; class FilterParserThread; class HttpServer; +class BandwidthScheduler; class TrackerInfos { public: @@ -92,6 +93,7 @@ private: // Bittorrent session *s; QPointer timerAlerts; + QPointer bd_scheduler; QMap savepath_fromurl; QHash > trackersInfos; QStringList torrentsToPausedAfterChecking; @@ -182,6 +184,7 @@ public slots: void startUpTorrents(); session_proxy asyncDeletion(); void recheckTorrent(QString hash); + void useAlternativeSpeedsLimit(bool alternative); /* Needed by Web UI */ void pauseAllTorrents(); void pauseTorrent(QString hash); @@ -261,6 +264,7 @@ signals: void metadataReceived(QTorrentHandle &h); void savePathChanged(QTorrentHandle &h); void newConsoleMessage(QString msg); + void alternativeSpeedsModeChanged(bool alternative); }; #endif diff --git a/src/feedList.h b/src/feedList.h index 39616d5f9..bbb79677f 100644 --- a/src/feedList.h +++ b/src/feedList.h @@ -37,7 +37,7 @@ public: } ~FeedList() { - //delete unread_item; + delete unread_item; } void itemAdded(QTreeWidgetItem *item, RssFile* file) { diff --git a/src/src.pro b/src/src.pro index 343b0e331..af6a13568 100644 --- a/src/src.pro +++ b/src/src.pro @@ -204,7 +204,8 @@ HEADERS += misc.h \ stacktrace.h \ torrentpersistentdata.h \ filesystemwatcher.h \ - preferences.h + preferences.h \ + bandwidthscheduler.h contains(DEFINES, DISABLE_GUI) { HEADERS += headlessloader.h diff --git a/src/statusbar.h b/src/statusbar.h index 97c63a045..c78949300 100644 --- a/src/statusbar.h +++ b/src/statusbar.h @@ -64,6 +64,7 @@ private: public: StatusBar(QStatusBar *bar, Bittorrent *BTSession): bar(bar), BTSession(BTSession) { + connect(BTSession, SIGNAL(alternativeSpeedsModeChanged(bool)), this, SLOT(updateAltSpeedsBtn(bool))); container = new QWidget(); layout = new QGridLayout(container); layout->setVerticalSpacing(0); @@ -198,17 +199,7 @@ public slots: } void toggleAlternativeSpeeds() { - bool alt = !Preferences::isAltBandwidthEnabled(); - Preferences::setAltBandwidthEnabled(alt); - if(alt) { - BTSession->getSession()->set_download_rate_limit(Preferences::getAltGlobalDownloadLimit()*1024); - BTSession->getSession()->set_upload_rate_limit(Preferences::getAltGlobalUploadLimit()*1024); - } else { - BTSession->getSession()->set_download_rate_limit(Preferences::getGlobalDownloadLimit()*1024); - BTSession->getSession()->set_upload_rate_limit(Preferences::getGlobalUploadLimit()*1024); - } - updateAltSpeedsBtn(alt); - emit alternativeSpeedsToggled(alt); + BTSession->useAlternativeSpeedsLimit(!Preferences::isAltBandwidthEnabled()); } void capDownloadSpeed() { @@ -246,8 +237,6 @@ public slots: } } -signals: - void alternativeSpeedsToggled(bool alternative); }; #endif // STATUSBAR_H diff --git a/src/ui/options.ui b/src/ui/options.ui index 2ffe266c2..39f07e238 100644 --- a/src/ui/options.ui +++ b/src/ui/options.ui @@ -1661,6 +1661,12 @@ QGroupBox { false + + hh:mm + + + false +