Browse Source

Merge pull request #2284 from pmzqla/webui-features

WebUI changes
adaptive-webui-19844
sledgehammer999 10 years ago
parent
commit
3d7ca1da77
  1. 19
      src/webui/btjson.cpp
  2. 2
      src/webui/httprequestparser.cpp
  3. 101
      src/webui/requesthandler.cpp
  4. 2
      src/webui/requesthandler.h
  5. 3
      src/webui/webapplication.cpp
  6. 11
      src/webui/www/private/index.html
  7. 4
      src/webui/www/public/css/Layout.css
  8. 81
      src/webui/www/public/downloadlimit.html
  9. 12
      src/webui/www/public/filters.html
  10. 295
      src/webui/www/public/scripts/client.js
  11. 1
      src/webui/www/public/scripts/contextmenu.js
  12. 4
      src/webui/www/public/scripts/mocha-init.js
  13. 2
      src/webui/www/public/scripts/mocha-yc.js
  14. 10
      src/webui/www/public/scripts/mocha.js
  15. 81
      src/webui/www/public/uploadlimit.html

19
src/webui/btjson.cpp

@ -140,6 +140,8 @@ static const char KEY_TRANSFER_DLRATELIMIT[] = "dl_rate_limit";
static const char KEY_TRANSFER_UPSPEED[] = "up_info_speed"; static const char KEY_TRANSFER_UPSPEED[] = "up_info_speed";
static const char KEY_TRANSFER_UPDATA[] = "up_info_data"; static const char KEY_TRANSFER_UPDATA[] = "up_info_data";
static const char KEY_TRANSFER_UPRATELIMIT[] = "up_rate_limit"; static const char KEY_TRANSFER_UPRATELIMIT[] = "up_rate_limit";
static const char KEY_TRANSFER_DHT_NODES[] = "dht_nodes";
static const char KEY_TRANSFER_CONNECTION_STATUS[] = "connection_status";
class QTorrentCompare class QTorrentCompare
{ {
@ -213,7 +215,7 @@ static QVariantMap toMap(const QTorrentHandle& h)
ret[KEY_TORRENT_LEECHS] = status.num_peers - status.num_seeds; ret[KEY_TORRENT_LEECHS] = status.num_peers - status.num_seeds;
ret[KEY_TORRENT_NUM_INCOMPLETE] = status.num_incomplete; ret[KEY_TORRENT_NUM_INCOMPLETE] = status.num_incomplete;
const qreal ratio = QBtSession::instance()->getRealRatio(status); const qreal ratio = QBtSession::instance()->getRealRatio(status);
ret[KEY_TORRENT_RATIO] = (ratio > 100.) ? -1 : ratio; ret[KEY_TORRENT_RATIO] = (ratio > QBtSession::MAX_RATIO) ? -1 : ratio;
ret[KEY_TORRENT_STATE] = h.torrentState().toString(); ret[KEY_TORRENT_STATE] = h.torrentState().toString();
ret[KEY_TORRENT_ETA] = h.eta(); ret[KEY_TORRENT_ETA] = h.eta();
if (h.has_metadata()) { if (h.has_metadata()) {
@ -245,6 +247,8 @@ static QVariantMap toMap(const QTorrentHandle& h)
* - "ratio": Torrent share ratio * - "ratio": Torrent share ratio
* - "eta": Torrent ETA * - "eta": Torrent ETA
* - "state": Torrent state * - "state": Torrent state
* - "seq_dl": Torrent sequential download state
* - "f_l_piece_prio": Torrent first last piece priority state
*/ */
QByteArray btjson::getTorrents(QString filter, QString label, QByteArray btjson::getTorrents(QString filter, QString label,
QString sortedColumn, bool reverse, int limit, int offset) QString sortedColumn, bool reverse, int limit, int offset)
@ -381,7 +385,7 @@ QByteArray btjson::getPropertiesForTorrent(const QString& hash)
data[KEY_PROP_CONNECT_COUNT] = status.num_connections; data[KEY_PROP_CONNECT_COUNT] = status.num_connections;
data[KEY_PROP_CONNECT_COUNT_LIMIT] = status.connections_limit; data[KEY_PROP_CONNECT_COUNT_LIMIT] = status.connections_limit;
const qreal ratio = QBtSession::instance()->getRealRatio(status); const qreal ratio = QBtSession::instance()->getRealRatio(status);
data[KEY_PROP_RATIO] = ratio > 100. ? -1 : ratio; data[KEY_PROP_RATIO] = ratio > QBtSession::MAX_RATIO ? -1 : ratio;
} }
catch(const std::exception& e) { catch(const std::exception& e) {
qWarning() << Q_FUNC_INFO << "Invalid torrent: " << misc::toQStringU(e.what()); qWarning() << Q_FUNC_INFO << "Invalid torrent: " << misc::toQStringU(e.what());
@ -446,10 +450,14 @@ QByteArray btjson::getFilesForTorrent(const QString& hash)
* - "dl_info_data": Data downloaded this session * - "dl_info_data": Data downloaded this session
* - "up_info_speed": Global upload rate * - "up_info_speed": Global upload rate
* - "up_info_data": Data uploaded this session * - "up_info_data": Data uploaded this session
* - "dl_rate_limit": Download rate limit
* - "up_rate_limit": Upload rate limit
* - "dht_nodes": DHT nodes connected to
* - "connection_status": Connection status
*/ */
QByteArray btjson::getTransferInfo() QByteArray btjson::getTransferInfo()
{ {
CACHED_VARIABLE(QVariantMap, info, CACHE_DURATION_MS); QVariantMap info;
session_status sessionStatus = QBtSession::instance()->getSessionStatus(); session_status sessionStatus = QBtSession::instance()->getSessionStatus();
session_settings sessionSettings = QBtSession::instance()->getSession()->settings(); session_settings sessionSettings = QBtSession::instance()->getSession()->settings();
info[KEY_TRANSFER_DLSPEED] = sessionStatus.payload_download_rate; info[KEY_TRANSFER_DLSPEED] = sessionStatus.payload_download_rate;
@ -460,5 +468,10 @@ QByteArray btjson::getTransferInfo()
info[KEY_TRANSFER_DLRATELIMIT] = sessionSettings.download_rate_limit; info[KEY_TRANSFER_DLRATELIMIT] = sessionSettings.download_rate_limit;
if (sessionSettings.upload_rate_limit) if (sessionSettings.upload_rate_limit)
info[KEY_TRANSFER_UPRATELIMIT] = sessionSettings.upload_rate_limit; info[KEY_TRANSFER_UPRATELIMIT] = sessionSettings.upload_rate_limit;
info[KEY_TRANSFER_DHT_NODES] = sessionStatus.dht_nodes;
if (!QBtSession::instance()->getSession()->is_listening())
info[KEY_TRANSFER_CONNECTION_STATUS] = "disconnected";
else
info[KEY_TRANSFER_CONNECTION_STATUS] = sessionStatus.has_incoming_connections ? "connected" : "firewalled";
return json::toJson(info); return json::toJson(info);
} }

2
src/webui/httprequestparser.cpp

@ -243,7 +243,7 @@ bool HttpRequestParser::parseContent(const QByteArray& data)
while (i.hasNext()) while (i.hasNext())
{ {
QPair<QString, QString> pair = i.next(); QPair<QString, QString> pair = i.next();
request_.posts[pair.first] = pair.second; request_.posts[pair.first.toLower()] = pair.second;
} }
return true; return true;

101
src/webui/requesthandler.cpp

@ -100,6 +100,8 @@ QMap<QString, QMap<QString, RequestHandler::Action> > RequestHandler::initialize
ADD_ACTION(command, getTorrentDlLimit); ADD_ACTION(command, getTorrentDlLimit);
ADD_ACTION(command, setTorrentUpLimit); ADD_ACTION(command, setTorrentUpLimit);
ADD_ACTION(command, setTorrentDlLimit); ADD_ACTION(command, setTorrentDlLimit);
ADD_ACTION(command, alternativeSpeedLimitsEnabled);
ADD_ACTION(command, toggleAlternativeSpeedLimits);
ADD_ACTION(command, toggleSequentialDownload); ADD_ACTION(command, toggleSequentialDownload);
ADD_ACTION(command, toggleFirstLastPiecePrio); ADD_ACTION(command, toggleFirstLastPiecePrio);
ADD_ACTION(command, delete); ADD_ACTION(command, delete);
@ -116,6 +118,25 @@ QMap<QString, QMap<QString, RequestHandler::Action> > RequestHandler::initialize
return actions; return actions;
} }
#define CHECK_URI() \
if (!args_.isEmpty()) { \
status(404, "Not Found"); \
return; \
}
#define CHECK_PARAMETERS(PARAMETERS) \
QStringList parameters; \
parameters << PARAMETERS; \
if (parameters.size() != request().posts.size()) { \
status(400, "Bad Request"); \
return; \
} \
foreach (QString key, request().posts.keys()) { \
if (!parameters.contains(key, Qt::CaseInsensitive)) { \
status(400, "Bad Request"); \
return; \
} \
}
void RequestHandler::action_public_index() void RequestHandler::action_public_index()
{ {
QString path; QString path;
@ -163,6 +184,7 @@ void RequestHandler::action_public_login()
void RequestHandler::action_public_logout() void RequestHandler::action_public_logout()
{ {
CHECK_URI();
sessionEnd(); sessionEnd();
} }
@ -200,6 +222,7 @@ void RequestHandler::action_public_images()
// - offset (int): set offset (if less than 0 - offset from end) // - offset (int): set offset (if less than 0 - offset from end)
void RequestHandler::action_json_torrents() void RequestHandler::action_json_torrents()
{ {
CHECK_URI();
const QStringMap& gets = request().gets; const QStringMap& gets = request().gets;
print(btjson::getTorrents( print(btjson::getTorrents(
@ -210,41 +233,49 @@ void RequestHandler::action_json_torrents()
void RequestHandler::action_json_preferences() void RequestHandler::action_json_preferences()
{ {
CHECK_URI();
print(prefjson::getPreferences(), CONTENT_TYPE_JS); print(prefjson::getPreferences(), CONTENT_TYPE_JS);
} }
void RequestHandler::action_json_transferInfo() void RequestHandler::action_json_transferInfo()
{ {
CHECK_URI();
print(btjson::getTransferInfo(), CONTENT_TYPE_JS); print(btjson::getTransferInfo(), CONTENT_TYPE_JS);
} }
void RequestHandler::action_json_propertiesGeneral() void RequestHandler::action_json_propertiesGeneral()
{ {
CHECK_URI();
print(btjson::getPropertiesForTorrent(args_.front()), CONTENT_TYPE_JS); print(btjson::getPropertiesForTorrent(args_.front()), CONTENT_TYPE_JS);
} }
void RequestHandler::action_json_propertiesTrackers() void RequestHandler::action_json_propertiesTrackers()
{ {
CHECK_URI();
print(btjson::getTrackersForTorrent(args_.front()), CONTENT_TYPE_JS); print(btjson::getTrackersForTorrent(args_.front()), CONTENT_TYPE_JS);
} }
void RequestHandler::action_json_propertiesFiles() void RequestHandler::action_json_propertiesFiles()
{ {
CHECK_URI();
print(btjson::getFilesForTorrent(args_.front()), CONTENT_TYPE_JS); print(btjson::getFilesForTorrent(args_.front()), CONTENT_TYPE_JS);
} }
void RequestHandler::action_version_api() void RequestHandler::action_version_api()
{ {
CHECK_URI();
print(QString::number(API_VERSION), CONTENT_TYPE_TXT); print(QString::number(API_VERSION), CONTENT_TYPE_TXT);
} }
void RequestHandler::action_version_api_min() void RequestHandler::action_version_api_min()
{ {
CHECK_URI();
print(QString::number(API_VERSION_MIN), CONTENT_TYPE_TXT); print(QString::number(API_VERSION_MIN), CONTENT_TYPE_TXT);
} }
void RequestHandler::action_version_qbittorrent() void RequestHandler::action_version_qbittorrent()
{ {
CHECK_URI();
print(QString(VERSION), CONTENT_TYPE_TXT); print(QString(VERSION), CONTENT_TYPE_TXT);
} }
@ -255,11 +286,14 @@ void RequestHandler::action_command_shutdown()
// need to reply to the Web UI before // need to reply to the Web UI before
// actually shutting down. // actually shutting down.
CHECK_URI();
QTimer::singleShot(0, qApp, SLOT(quit())); QTimer::singleShot(0, qApp, SLOT(quit()));
} }
void RequestHandler::action_command_download() void RequestHandler::action_command_download()
{ {
CHECK_URI();
CHECK_PARAMETERS("urls");
QString urls = request().posts["urls"]; QString urls = request().posts["urls"];
QStringList list = urls.split('\n'); QStringList list = urls.split('\n');
@ -284,6 +318,7 @@ void RequestHandler::action_command_download()
void RequestHandler::action_command_upload() void RequestHandler::action_command_upload()
{ {
qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO;
CHECK_URI();
foreach(const UploadedFile& torrent, request().files) { foreach(const UploadedFile& torrent, request().files) {
QString filePath = saveTmpFile(torrent.data); QString filePath = saveTmpFile(torrent.data);
@ -307,6 +342,8 @@ void RequestHandler::action_command_upload()
void RequestHandler::action_command_addTrackers() void RequestHandler::action_command_addTrackers()
{ {
CHECK_URI();
CHECK_PARAMETERS("hash" << "urls");
QString hash = request().posts["hash"]; QString hash = request().posts["hash"];
if (!hash.isEmpty()) { if (!hash.isEmpty()) {
@ -326,31 +363,41 @@ void RequestHandler::action_command_addTrackers()
void RequestHandler::action_command_resumeAll() void RequestHandler::action_command_resumeAll()
{ {
CHECK_URI();
QBtSession::instance()->resumeAllTorrents(); QBtSession::instance()->resumeAllTorrents();
} }
void RequestHandler::action_command_pauseAll() void RequestHandler::action_command_pauseAll()
{ {
CHECK_URI();
QBtSession::instance()->pauseAllTorrents(); QBtSession::instance()->pauseAllTorrents();
} }
void RequestHandler::action_command_resume() void RequestHandler::action_command_resume()
{ {
CHECK_URI();
CHECK_PARAMETERS("hash");
QBtSession::instance()->resumeTorrent(request().posts["hash"]); QBtSession::instance()->resumeTorrent(request().posts["hash"]);
} }
void RequestHandler::action_command_pause() void RequestHandler::action_command_pause()
{ {
CHECK_URI();
CHECK_PARAMETERS("hash");
QBtSession::instance()->pauseTorrent(request().posts["hash"]); QBtSession::instance()->pauseTorrent(request().posts["hash"]);
} }
void RequestHandler::action_command_setPreferences() void RequestHandler::action_command_setPreferences()
{ {
CHECK_URI();
CHECK_PARAMETERS("json");
prefjson::setPreferences(request().posts["json"]); prefjson::setPreferences(request().posts["json"]);
} }
void RequestHandler::action_command_setFilePrio() void RequestHandler::action_command_setFilePrio()
{ {
CHECK_URI();
CHECK_PARAMETERS("hash" << "id" << "priority");
QString hash = request().posts["hash"]; QString hash = request().posts["hash"];
int file_id = request().posts["id"].toInt(); int file_id = request().posts["id"].toInt();
int priority = request().posts["priority"].toInt(); int priority = request().posts["priority"].toInt();
@ -362,34 +409,48 @@ void RequestHandler::action_command_setFilePrio()
void RequestHandler::action_command_getGlobalUpLimit() void RequestHandler::action_command_getGlobalUpLimit()
{ {
CHECK_URI();
print(QByteArray::number(QBtSession::instance()->getSession()->settings().upload_rate_limit)); print(QByteArray::number(QBtSession::instance()->getSession()->settings().upload_rate_limit));
} }
void RequestHandler::action_command_getGlobalDlLimit() void RequestHandler::action_command_getGlobalDlLimit()
{ {
CHECK_URI();
print(QByteArray::number(QBtSession::instance()->getSession()->settings().download_rate_limit)); print(QByteArray::number(QBtSession::instance()->getSession()->settings().download_rate_limit));
} }
void RequestHandler::action_command_setGlobalUpLimit() void RequestHandler::action_command_setGlobalUpLimit()
{ {
CHECK_URI();
CHECK_PARAMETERS("limit");
qlonglong limit = request().posts["limit"].toLongLong(); qlonglong limit = request().posts["limit"].toLongLong();
if (limit == 0) limit = -1; if (limit == 0) limit = -1;
QBtSession::instance()->setUploadRateLimit(limit); QBtSession::instance()->setUploadRateLimit(limit);
Preferences::instance()->setGlobalUploadLimit(limit / 1024.); if (Preferences::instance()->isAltBandwidthEnabled())
Preferences::instance()->setAltGlobalUploadLimit(limit / 1024.);
else
Preferences::instance()->setGlobalUploadLimit(limit / 1024.);
} }
void RequestHandler::action_command_setGlobalDlLimit() void RequestHandler::action_command_setGlobalDlLimit()
{ {
CHECK_URI();
CHECK_PARAMETERS("limit");
qlonglong limit = request().posts["limit"].toLongLong(); qlonglong limit = request().posts["limit"].toLongLong();
if (limit == 0) limit = -1; if (limit == 0) limit = -1;
QBtSession::instance()->setDownloadRateLimit(limit); QBtSession::instance()->setDownloadRateLimit(limit);
Preferences::instance()->setGlobalDownloadLimit(limit / 1024.); if (Preferences::instance()->isAltBandwidthEnabled())
Preferences::instance()->setAltGlobalDownloadLimit(limit / 1024.);
else
Preferences::instance()->setGlobalDownloadLimit(limit / 1024.);
} }
void RequestHandler::action_command_getTorrentUpLimit() void RequestHandler::action_command_getTorrentUpLimit()
{ {
CHECK_URI();
CHECK_PARAMETERS("hash");
QString hash = request().posts["hash"]; QString hash = request().posts["hash"];
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash); QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
@ -399,6 +460,8 @@ void RequestHandler::action_command_getTorrentUpLimit()
void RequestHandler::action_command_getTorrentDlLimit() void RequestHandler::action_command_getTorrentDlLimit()
{ {
CHECK_URI();
CHECK_PARAMETERS("hash");
QString hash = request().posts["hash"]; QString hash = request().posts["hash"];
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash); QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
@ -408,6 +471,8 @@ void RequestHandler::action_command_getTorrentDlLimit()
void RequestHandler::action_command_setTorrentUpLimit() void RequestHandler::action_command_setTorrentUpLimit()
{ {
CHECK_URI();
CHECK_PARAMETERS("hash" << "limit");
QString hash = request().posts["hash"]; QString hash = request().posts["hash"];
qlonglong limit = request().posts["limit"].toLongLong(); qlonglong limit = request().posts["limit"].toLongLong();
if (limit == 0) limit = -1; if (limit == 0) limit = -1;
@ -419,6 +484,8 @@ void RequestHandler::action_command_setTorrentUpLimit()
void RequestHandler::action_command_setTorrentDlLimit() void RequestHandler::action_command_setTorrentDlLimit()
{ {
CHECK_URI();
CHECK_PARAMETERS("hash" << "limit");
QString hash = request().posts["hash"]; QString hash = request().posts["hash"];
qlonglong limit = request().posts["limit"].toLongLong(); qlonglong limit = request().posts["limit"].toLongLong();
if (limit == 0) limit = -1; if (limit == 0) limit = -1;
@ -428,8 +495,22 @@ void RequestHandler::action_command_setTorrentDlLimit()
h.set_download_limit(limit); h.set_download_limit(limit);
} }
void RequestHandler::action_command_toggleAlternativeSpeedLimits()
{
CHECK_URI();
QBtSession::instance()->useAlternativeSpeedsLimit(!Preferences::instance()->isAltBandwidthEnabled());
}
void RequestHandler::action_command_alternativeSpeedLimitsEnabled()
{
CHECK_URI();
print(QByteArray::number(Preferences::instance()->isAltBandwidthEnabled()));
}
void RequestHandler::action_command_toggleSequentialDownload() void RequestHandler::action_command_toggleSequentialDownload()
{ {
CHECK_URI();
CHECK_PARAMETERS("hashes");
QStringList hashes = request().posts["hashes"].split("|"); QStringList hashes = request().posts["hashes"].split("|");
foreach (const QString &hash, hashes) { foreach (const QString &hash, hashes) {
try { try {
@ -442,6 +523,8 @@ void RequestHandler::action_command_toggleSequentialDownload()
void RequestHandler::action_command_toggleFirstLastPiecePrio() void RequestHandler::action_command_toggleFirstLastPiecePrio()
{ {
CHECK_URI();
CHECK_PARAMETERS("hashes");
QStringList hashes = request().posts["hashes"].split("|"); QStringList hashes = request().posts["hashes"].split("|");
foreach (const QString &hash, hashes) { foreach (const QString &hash, hashes) {
try { try {
@ -454,6 +537,8 @@ void RequestHandler::action_command_toggleFirstLastPiecePrio()
void RequestHandler::action_command_delete() void RequestHandler::action_command_delete()
{ {
CHECK_URI();
CHECK_PARAMETERS("hashes");
QStringList hashes = request().posts["hashes"].split("|"); QStringList hashes = request().posts["hashes"].split("|");
foreach (const QString &hash, hashes) foreach (const QString &hash, hashes)
QBtSession::instance()->deleteTorrent(hash, false); QBtSession::instance()->deleteTorrent(hash, false);
@ -461,6 +546,8 @@ void RequestHandler::action_command_delete()
void RequestHandler::action_command_deletePerm() void RequestHandler::action_command_deletePerm()
{ {
CHECK_URI();
CHECK_PARAMETERS("hashes");
QStringList hashes = request().posts["hashes"].split("|"); QStringList hashes = request().posts["hashes"].split("|");
foreach (const QString &hash, hashes) foreach (const QString &hash, hashes)
QBtSession::instance()->deleteTorrent(hash, true); QBtSession::instance()->deleteTorrent(hash, true);
@ -468,6 +555,8 @@ void RequestHandler::action_command_deletePerm()
void RequestHandler::action_command_increasePrio() void RequestHandler::action_command_increasePrio()
{ {
CHECK_URI();
CHECK_PARAMETERS("hashes");
QStringList hashes = request().posts["hashes"].split("|"); QStringList hashes = request().posts["hashes"].split("|");
std::priority_queue<QPair<int, QTorrentHandle>, std::priority_queue<QPair<int, QTorrentHandle>,
@ -499,6 +588,8 @@ void RequestHandler::action_command_increasePrio()
void RequestHandler::action_command_decreasePrio() void RequestHandler::action_command_decreasePrio()
{ {
CHECK_URI();
CHECK_PARAMETERS("hashes");
QStringList hashes = request().posts["hashes"].split("|"); QStringList hashes = request().posts["hashes"].split("|");
std::priority_queue<QPair<int, QTorrentHandle>, std::priority_queue<QPair<int, QTorrentHandle>,
@ -531,6 +622,8 @@ void RequestHandler::action_command_decreasePrio()
void RequestHandler::action_command_topPrio() void RequestHandler::action_command_topPrio()
{ {
CHECK_URI();
CHECK_PARAMETERS("hashes");
foreach (const QString &hash, request().posts["hashes"].split("|")) { foreach (const QString &hash, request().posts["hashes"].split("|")) {
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash); QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
if (h.is_valid()) h.queue_position_top(); if (h.is_valid()) h.queue_position_top();
@ -539,6 +632,8 @@ void RequestHandler::action_command_topPrio()
void RequestHandler::action_command_bottomPrio() void RequestHandler::action_command_bottomPrio()
{ {
CHECK_URI();
CHECK_PARAMETERS("hashes");
foreach (const QString &hash, request().posts["hashes"].split("|")) { foreach (const QString &hash, request().posts["hashes"].split("|")) {
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash); QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
if (h.is_valid()) h.queue_position_bottom(); if (h.is_valid()) h.queue_position_bottom();
@ -547,6 +642,8 @@ void RequestHandler::action_command_bottomPrio()
void RequestHandler::action_command_recheck() void RequestHandler::action_command_recheck()
{ {
CHECK_URI();
CHECK_PARAMETERS("hash");
QBtSession::instance()->recheckTorrent(request().posts["hash"]); QBtSession::instance()->recheckTorrent(request().posts["hash"]);
} }

2
src/webui/requesthandler.h

@ -74,6 +74,8 @@ private:
void action_command_getTorrentDlLimit(); void action_command_getTorrentDlLimit();
void action_command_setTorrentUpLimit(); void action_command_setTorrentUpLimit();
void action_command_setTorrentDlLimit(); void action_command_setTorrentDlLimit();
void action_command_alternativeSpeedLimitsEnabled();
void action_command_toggleAlternativeSpeedLimits();
void action_command_toggleSequentialDownload(); void action_command_toggleSequentialDownload();
void action_command_toggleFirstLastPiecePrio(); void action_command_toggleFirstLastPiecePrio();
void action_command_delete(); void action_command_delete();

3
src/webui/webapplication.cpp

@ -193,7 +193,8 @@ void WebApplication::translateDocument(QString& data)
"TransferListFiltersWidget", "TransferListWidget", "PropertiesWidget", "TransferListFiltersWidget", "TransferListWidget", "PropertiesWidget",
"HttpServer", "confirmDeletionDlg", "TrackerList", "TorrentFilesModel", "HttpServer", "confirmDeletionDlg", "TrackerList", "TorrentFilesModel",
"options_imp", "Preferences", "TrackersAdditionDlg", "ScanFoldersModel", "options_imp", "Preferences", "TrackersAdditionDlg", "ScanFoldersModel",
"PropTabBar", "TorrentModel", "downloadFromURL", "MainWindow", "misc" "PropTabBar", "TorrentModel", "downloadFromURL", "MainWindow", "misc",
"StatusBar"
}; };
const size_t context_count = sizeof(contexts) / sizeof(contexts[0]); const size_t context_count = sizeof(contexts) / sizeof(contexts[0]);
int i = 0; int i = 0;

11
src/webui/www/private/index.html

@ -117,7 +117,16 @@
<div id="desktopFooter"> <div id="desktopFooter">
<span id="error_div"></span> <span id="error_div"></span>
<table style="position: absolute; right: 5px;"> <table style="position: absolute; right: 5px;">
<tr><td id="DlInfos" style="cursor:pointer;"></td><td style="width: 2px;margin:0;"><img src="images/skin/toolbox-divider.gif" alt="" style="height: 18px; padding-left: 10px; padding-right: 10px; margin-bottom: -2px;"/></td><td id="UpInfos" style="cursor:pointer;"></td></tr> <tr>
<td id="DHTNodes"></td>
<td style="width: 2px;margin:0;"><img src="images/skin/toolbox-divider.gif" alt="" style="height: 18px; padding-left: 10px; padding-right: 10px; margin-bottom: -2px;"/></td>
<td><img id="connectionStatus" alt="Connection Status" src="images/skin/firewalled.png" /></td>
<td style="width: 2px;margin:0;"><img src="images/skin/toolbox-divider.gif" alt="" style="height: 18px; padding-left: 10px; padding-right: 10px; margin-bottom: -2px;"/></td>
<td style="cursor:pointer;"><img id="alternativeSpeedLimits" alt="_(Alternative speed limits)" src="images/slow_off.png" /></td>
<td style="width: 2px;margin:0;"><img src="images/skin/toolbox-divider.gif" alt="" style="height: 18px; padding-left: 10px; padding-right: 10px; margin-bottom: -2px;"/></td>
<td id="DlInfos" style="cursor:pointer; min-width: 200px"></td>
<td style="width: 2px;margin:0;"><img src="images/skin/toolbox-divider.gif" alt="" style="height: 18px; padding-left: 10px; padding-right: 10px; margin-bottom: -2px;"/></td>
<td id="UpInfos" style="cursor:pointer; min-width: 200px"></td></tr>
</table> </table>
</div> </div>
</div> </div>

4
src/webui/www/public/css/Layout.css

@ -423,3 +423,7 @@ div.toolbox.divider { /* Have to specify div here for IE6's sake */
height: 16px; height: 16px;
} }
#desktopFooter td {
vertical-align: top;
text-align: center;
}

81
src/webui/www/public/downloadlimit.html

@ -1,52 +1,61 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>_(Torrent Download Speed Limiting)</title> <title>_(Torrent Download Speed Limiting)</title>
<link rel="stylesheet" href="css/style.css" type="text/css" /> <link rel="stylesheet" href="css/style.css" type="text/css" />
<script type="text/javascript" src="scripts/mootools-1.2-core-yc.js" charset="utf-8"></script> <script type="text/javascript" src="scripts/mootools-1.2-core-yc.js" charset="utf-8"></script>
<script type="text/javascript" src="scripts/mootools-1.2-more.js" charset="utf-8"></script> <script type="text/javascript" src="scripts/mootools-1.2-more.js" charset="utf-8"></script>
<script type="text/javascript" src="scripts/mocha-yc.js" charset="utf-8"></script> <script type="text/javascript" src="scripts/mocha-yc.js" charset="utf-8"></script>
<script type="text/javascript" src="scripts/parametrics.js" charset="utf-8"></script> <script type="text/javascript" src="scripts/parametrics.js" charset="utf-8"></script>
</head> </head>
<body> <body>
<div style="width: 100%; text-align: center; margin: 0 auto;"> <div style="width: 100%; text-align: center; margin: 0 auto; overflow: hidden">
<div id="dllimitSlider" class="slider"> <div id="dllimitSlider" class="slider">
<div id="dllimitUpdate" class="update">_(Download limit:) <input id="dllimitUpdatevalue" size="6" placeholder="∞" style="text-align: center;"> <span id="dlLimitUnit">_(KiB/s)</span></div> <div id="dllimitUpdate" class="update">_(Download limit:) <input id="dllimitUpdatevalue" size="6" placeholder="∞" style="text-align: center;"> <span id="dlLimitUnit">_(KiB/s)</span></div>
<div class="sliderWrapper"> <div class="sliderWrapper">
<div id="dllimitSliderknob" class="sliderknob"></div> <div id="dllimitSliderknob" class="sliderknob"></div>
<div id="dllimitSliderarea" class="sliderarea"></div> <div id="dllimitSliderarea" class="sliderarea"></div>
</div> </div>
<div class="clear"></div> <div class="clear"></div>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
var hash = new URI().getData('hash'); var hash = new URI().getData('hash');
setDlLimit = function() { setDlLimit = function() {
var limit = $("dllimitUpdatevalue").value.toInt() * 1024; var limit = $("dllimitUpdatevalue").value.toInt() * 1024;
if(hash == "global") { if (hash == "global") {
new Request({url: 'command/setGlobalDlLimit', new Request({
method: 'post', url: 'command/setGlobalDlLimit',
data: {'limit': limit}, method: 'post',
onComplete: function() { data: {
window.parent.closeWindows(); 'limit': limit
} },
}).send(); onComplete: function() {
} else { window.parent.updateTransferInfo();
new Request({url: 'command/setTorrentDlLimit', window.parent.closeWindows();
method: 'post', }
data: {'hash': hash, 'limit': limit}, }).send();
onComplete: function() { }
window.parent.closeWindows(); else {
} new Request({
}).send(); url: 'command/setTorrentDlLimit',
} method: 'post',
} data: {
'hash': hash,
'limit': limit
},
onComplete: function() {
window.parent.closeWindows();
}
}).send();
}
}
</script> </script>
<input type="button" value="_(Apply)" onclick="setDlLimit()"/> <input type="button" value="_(Apply)" onclick="setDlLimit()"/>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
MochaUI.addDlLimitSlider(hash); MochaUI.addDlLimitSlider(hash);
</script> </script>
</body> </body>

12
src/webui/www/public/filters.html

@ -1,8 +1,8 @@
<ul class="filterList"> <ul class="filterList">
<li id="all_filter"><a href="#" onclick="setFilter('all');"><img src="images/skin/filterall.png"/>_(All)</a></li> <li id="all_filter"><a href="#" onclick="setFilter('all');return false;"><img src="images/skin/filterall.png"/>_(All)</a></li>
<li id="downloading_filter"><a href="#" onclick="setFilter('downloading');"><img src="images/skin/downloading.png"/>_(Downloading)</a></li> <li id="downloading_filter"><a href="#" onclick="setFilter('downloading');return false;"><img src="images/skin/downloading.png"/>_(Downloading)</a></li>
<li id="completed_filter"><a href="#" onclick="setFilter('completed');"><img src="images/skin/uploading.png"/>_(Completed)</a></li> <li id="completed_filter"><a href="#" onclick="setFilter('completed');return false;"><img src="images/skin/uploading.png"/>_(Completed)</a></li>
<li id="paused_filter"><a href="#" onclick="setFilter('paused');"><img src="images/skin/paused.png"/>_(Paused)</a></li> <li id="paused_filter"><a href="#" onclick="setFilter('paused');return false;"><img src="images/skin/paused.png"/>_(Paused)</a></li>
<li id="active_filter"><a href="#" onclick="setFilter('active');"><img src="images/skin/filteractive.png"/>_(Active)</a></li> <li id="active_filter"><a href="#" onclick="setFilter('active');return false;"><img src="images/skin/filteractive.png"/>_(Active)</a></li>
<li id="inactive_filter"><a href="#" onclick="setFilter('inactive');"><img src="images/skin/filterinactive.png"/>_(Inactive)</a></li> <li id="inactive_filter"><a href="#" onclick="setFilter('inactive');return false;"><img src="images/skin/filterinactive.png"/>_(Inactive)</a></li>
</ul> </ul>

295
src/webui/www/public/scripts/client.js

@ -25,6 +25,9 @@
myTable = new dynamicTable(); myTable = new dynamicTable();
var updatePropertiesPanel = function(){}; var updatePropertiesPanel = function(){};
var updateTransferInfo = function(){};
var updateTransferList = function(){};
var alternativeSpeedsLimit = false;
var stateToImg = function (state) { var stateToImg = function (state) {
if (state == "pausedUP" || state == "pausedDL") { if (state == "pausedUP" || state == "pausedDL") {
@ -43,122 +46,20 @@ var stateToImg = function (state) {
filter = getLocalStorageItem('selected_filter', 'all'); filter = getLocalStorageItem('selected_filter', 'all');
var loadTorrentsInfoTimer;
var loadTorrentsInfo = function () {
var queueing_enabled = false;
var url = new URI('json/torrents');
url.setData('filter', filter);
url.setData('sort', myTable.table.sortedColumn);
url.setData('reverse', myTable.table.reverseSort);
var request = new Request.JSON({
url : url,
noCache : true,
method : 'get',
onFailure : function () {
$('error_div').set('html', '_(qBittorrent client is not reachable)');
clearTimeout(loadTorrentsInfoTimer);
loadTorrentsInfoTimer = loadTorrentsInfo.delay(2000);
},
onSuccess : function (events) {
$('error_div').set('html', '');
if (events) {
// Add new torrents or update them
torrent_hashes = myTable.getRowIds();
events_hashes = new Array();
pos = 0;
events.each(function (event) {
events_hashes[events_hashes.length] = event.hash;
var row = new Array();
var data = new Array();
row.length = 10;
row[0] = stateToImg(event.state);
row[1] = event.name;
row[2] = event.priority > -1 ? event.priority : null;
data[2] = event.priority;
row[3] = friendlyUnit(event.size, false);
data[3] = event.size;
row[4] = (event.progress * 100).round(1);
if (row[4] == 100.0 && event.progress != 1.0)
row[4] = 99.9;
data[4] = event.progress;
row[5] = event.num_seeds;
if (event.num_complete != -1)
row[5] += " (" + event.num_complete + ")";
data[5] = event.num_seeds;
row[6] = event.num_leechs;
if (event.num_incomplete != -1)
row[6] += " (" + event.num_incomplete + ")";
data[6] = event.num_leechs;
row[7] = friendlyUnit(event.dlspeed, true);
data[7] = event.dlspeed;
row[8] = friendlyUnit(event.upspeed, true);
data[8] = event.upspeed;
row[9] = friendlyDuration(event.eta);
data[9] = event.eta;
if (event.ratio == -1)
row[10] = "∞";
else
row[10] = (Math.floor(100 * event.ratio) / 100).toFixed(2); //Don't round up
data[10] = event.ratio;
if (row[2] != null)
queueing_enabled = true;
attrs = {};
attrs['downloaded'] = (event.progress == 1.0);
attrs['state'] = event.state;
attrs['seq_dl'] = (event.seq_dl == true);
attrs['f_l_piece_prio'] = (event.f_l_piece_prio == true);
if (!torrent_hashes.contains(event.hash)) {
// New unfinished torrent
torrent_hashes[torrent_hashes.length] = event.hash;
//alert("Inserting row");
myTable.insertRow(event.hash, row, data, attrs, pos);
} else {
// Update torrent data
myTable.updateRow(event.hash, row, data, attrs, pos);
}
pos++;
});
// Remove deleted torrents
torrent_hashes.each(function (hash) {
if (!events_hashes.contains(hash)) {
myTable.removeRow(hash);
}
});
if (queueing_enabled) {
$('queueingButtons').removeClass('invisible');
$('queueingMenuItems').removeClass('invisible');
myTable.showPriority();
} else {
$('queueingButtons').addClass('invisible');
$('queueingMenuItems').addClass('invisible');
myTable.hidePriority();
}
myTable.altRow();
}
clearTimeout(loadTorrentsInfoTimer);
loadTorrentsInfoTimer = loadTorrentsInfo.delay(1500);
}
}).send();
};
var updateTransferList = function() {
clearTimeout(loadTorrentsInfoTimer);
loadTorrentsInfo();
}
window.addEvent('load', function () { window.addEvent('load', function () {
var saveColumnSizes = function () { var saveColumnSizes = function () {
var filters_width = $('Filters').getSize().x; var filters_width = $('Filters').getSize().x;
var properties_height = $('propertiesPanel').getSize().y; var properties_height_rel = $('propertiesPanel').getSize().y / Window.getSize().y;
localStorage.setItem('filters_width', filters_width); localStorage.setItem('filters_width', filters_width);
localStorage.setItem('properties_height', properties_height); localStorage.setItem('properties_height_rel', properties_height_rel);
} }
window.addEvent('resize', function() {
// Resizing might takes some time.
saveColumnSizes.delay(200);
});
/*MochaUI.Desktop = new MochaUI.Desktop(); /*MochaUI.Desktop = new MochaUI.Desktop();
MochaUI.Desktop.desktop.setStyles({ MochaUI.Desktop.desktop.setStyles({
'background': '#fff', 'background': '#fff',
@ -226,6 +127,113 @@ window.addEvent('load', function () {
if (!speedInTitle) if (!speedInTitle)
$('speedInBrowserTitleBarLink').firstChild.style.opacity = '0'; $('speedInBrowserTitleBarLink').firstChild.style.opacity = '0';
var loadTorrentsInfoTimer;
var loadTorrentsInfo = function () {
var queueing_enabled = false;
var url = new URI('json/torrents');
url.setData('filter', filter);
url.setData('sort', myTable.table.sortedColumn);
url.setData('reverse', myTable.table.reverseSort);
var request = new Request.JSON({
url : url,
noCache : true,
method : 'get',
onFailure : function () {
$('error_div').set('html', '_(qBittorrent client is not reachable)');
clearTimeout(loadTorrentsInfoTimer);
loadTorrentsInfoTimer = loadTorrentsInfo.delay(2000);
},
onSuccess : function (events) {
$('error_div').set('html', '');
if (events) {
// Add new torrents or update them
torrent_hashes = myTable.getRowIds();
events_hashes = new Array();
pos = 0;
events.each(function (event) {
events_hashes[events_hashes.length] = event.hash;
var row = new Array();
var data = new Array();
row.length = 10;
row[0] = stateToImg(event.state);
row[1] = event.name;
row[2] = event.priority > -1 ? event.priority : null;
data[2] = event.priority;
row[3] = friendlyUnit(event.size, false);
data[3] = event.size;
row[4] = (event.progress * 100).round(1);
if (row[4] == 100.0 && event.progress != 1.0)
row[4] = 99.9;
data[4] = event.progress;
row[5] = event.num_seeds;
if (event.num_complete != -1)
row[5] += " (" + event.num_complete + ")";
data[5] = event.num_seeds;
row[6] = event.num_leechs;
if (event.num_incomplete != -1)
row[6] += " (" + event.num_incomplete + ")";
data[6] = event.num_leechs;
row[7] = friendlyUnit(event.dlspeed, true);
data[7] = event.dlspeed;
row[8] = friendlyUnit(event.upspeed, true);
data[8] = event.upspeed;
row[9] = friendlyDuration(event.eta);
data[9] = event.eta;
if (event.ratio == -1)
row[10] = "∞";
else
row[10] = (Math.floor(100 * event.ratio) / 100).toFixed(2); //Don't round up
data[10] = event.ratio;
if (row[2] != null)
queueing_enabled = true;
attrs = {};
attrs['downloaded'] = (event.progress == 1.0);
attrs['state'] = event.state;
attrs['seq_dl'] = (event.seq_dl == true);
attrs['f_l_piece_prio'] = (event.f_l_piece_prio == true);
if (!torrent_hashes.contains(event.hash)) {
// New unfinished torrent
torrent_hashes[torrent_hashes.length] = event.hash;
//alert("Inserting row");
myTable.insertRow(event.hash, row, data, attrs, pos);
} else {
// Update torrent data
myTable.updateRow(event.hash, row, data, attrs, pos);
}
pos++;
});
// Remove deleted torrents
torrent_hashes.each(function (hash) {
if (!events_hashes.contains(hash)) {
myTable.removeRow(hash);
}
});
if (queueing_enabled) {
$('queueingButtons').removeClass('invisible');
$('queueingMenuItems').removeClass('invisible');
myTable.showPriority();
} else {
$('queueingButtons').addClass('invisible');
$('queueingMenuItems').addClass('invisible');
myTable.hidePriority();
}
myTable.altRow();
}
clearTimeout(loadTorrentsInfoTimer);
loadTorrentsInfoTimer = loadTorrentsInfo.delay(1500);
}
}).send();
};
updateTransferList = function() {
clearTimeout(loadTorrentsInfoTimer);
loadTorrentsInfo();
}
var loadTransferInfoTimer; var loadTransferInfoTimer;
var loadTransferInfo = function () { var loadTransferInfo = function () {
var url = 'json/transferInfo'; var url = 'json/transferInfo';
@ -240,24 +248,29 @@ window.addEvent('load', function () {
}, },
onSuccess : function (info) { onSuccess : function (info) {
if (info) { if (info) {
dl_limit = ""; var transfer_info = "";
if (info.dl_rate_limit != undefined) if (info.dl_rate_limit != undefined)
dl_limit = "[%1] ".replace("%1", friendlyUnit(info.dl_rate_limit, true)); transfer_info += "[" + friendlyUnit(info.dl_rate_limit, true) + "] ";
$("DlInfos").set('html', "%3_(D: %1 - T: %2)" transfer_info += friendlyUnit(info.dl_info_speed, true);
.replace("%1", friendlyUnit(info.dl_info_speed, true)) transfer_info += " (" + friendlyUnit(info.dl_info_data, false) + ")"
.replace("%2", friendlyUnit(info.dl_info_data, false)) $("DlInfos").set('html', transfer_info);
.replace("%3", dl_limit)); transfer_info = "";
up_limit = "";
if (info.up_rate_limit != undefined) if (info.up_rate_limit != undefined)
up_limit = "[%1] ".replace("%1", friendlyUnit(info.up_rate_limit, true)); transfer_info += "[" + friendlyUnit(info.up_rate_limit, true) + "] ";
$("UpInfos").set('html', "%3_(U: %1 - T: %2)" transfer_info += friendlyUnit(info.up_info_speed, true)
.replace("%1", friendlyUnit(info.up_info_speed, true)) transfer_info += " (" + friendlyUnit(info.up_info_data, false) + ")"
.replace("%2", friendlyUnit(info.up_info_data, false)) $("UpInfos").set('html', transfer_info);
.replace("%3", up_limit));
if (speedInTitle) if (speedInTitle)
document.title = "_(D:%1 U:%2)".replace("%1", friendlyUnit(info.dl_info_speed, true)).replace("%2", friendlyUnit(info.up_info_speed, true)); document.title = "_(D:%1 U:%2)".replace("%1", friendlyUnit(info.dl_info_speed, true)).replace("%2", friendlyUnit(info.up_info_speed, true));
else else
document.title = "_(qBittorrent web User Interface)"; document.title = "_(qBittorrent web User Interface)";
$('DHTNodes').set('html', '_(DHT: %1 nodes)'.replace("%1", info.dht_nodes));
if (info.connection_status == "connected")
$('connectionStatus').src = 'images/skin/connected.png';
else if (info.connection_status == "firewalled")
$('connectionStatus').src = 'images/skin/firewalled.png';
else
$('connectionStatus').src = 'images/skin/disconnected.png';
clearTimeout(loadTransferInfoTimer); clearTimeout(loadTransferInfoTimer);
loadTransferInfoTimer = loadTransferInfo.delay(3000); loadTransferInfoTimer = loadTransferInfo.delay(3000);
} }
@ -265,7 +278,7 @@ window.addEvent('load', function () {
}).send(); }).send();
}; };
var updateTransferInfo = function() { updateTransferInfo = function() {
clearTimeout(loadTransferInfoTimer); clearTimeout(loadTransferInfoTimer);
loadTransferInfo(); loadTransferInfo();
} }
@ -273,6 +286,40 @@ window.addEvent('load', function () {
// Start fetching data now // Start fetching data now
loadTransferInfo(); loadTransferInfo();
var updateAltSpeedIcon = function(enabled) {
if (enabled)
$('alternativeSpeedLimits').src = "images/slow.png";
else
$('alternativeSpeedLimits').src = "images/slow_off.png"
}
// Determine whether the alternative speed limits are enabled or not
new Request({url: 'command/alternativeSpeedLimitsEnabled',
method: 'get',
onSuccess : function (isEnabled) {
alternativeSpeedsLimit = !!isEnabled;
if (alternativeSpeedsLimit)
$('alternativeSpeedLimits').src = "images/slow.png"
}
}).send();
$('alternativeSpeedLimits').addEvent('click', function() {
// Change icon immediately to give some feedback
updateAltSpeedIcon(!alternativeSpeedsLimit);
new Request({url: 'command/toggleAlternativeSpeedLimits',
method: 'post',
onComplete: function() {
alternativeSpeedsLimit = !alternativeSpeedsLimit;
updateTransferInfo();
},
onFailure: function() {
// Restore icon in case of failure
updateAltSpeedIcon(alternativeSpeedsLimit)
}
}).send();
});
$('DlInfos').addEvent('click', globalDownloadLimitFN); $('DlInfos').addEvent('click', globalDownloadLimitFN);
$('UpInfos').addEvent('click', globalUploadLimitFN); $('UpInfos').addEvent('click', globalUploadLimitFN);
@ -310,9 +357,9 @@ window.addEvent('load', function () {
onResize : saveColumnSizes, onResize : saveColumnSizes,
height : null height : null
}); });
var prop_h = localStorage.getItem('properties_height'); var prop_h = localStorage.getItem('properties_height_rel');
if ($defined(prop_h)) if ($defined(prop_h))
prop_h = prop_h.toInt(); prop_h = prop_h.toFloat() * Window.getSize().y;
else else
prop_h = Window.getSize().y / 2.; prop_h = Window.getSize().y / 2.;
new MochaUI.Panel({ new MochaUI.Panel({

1
src/webui/www/public/scripts/contextmenu.js

@ -114,6 +114,7 @@ var ContextMenu = new Class({
/* menu items */ /* menu items */
this.menu.getElements('a').each(function(item) { this.menu.getElements('a').each(function(item) {
item.addEvent('click', function(e) { item.addEvent('click', function(e) {
e.preventDefault();
if (!item.hasClass('disabled')) { if (!item.hasClass('disabled')) {
this.execute(item.get('href').split('#')[1], $(this.options.element)); this.execute(item.get('href').split('#')[1], $(this.options.element));
this.fireEvent('click', [item, e]); this.fireEvent('click', [item, e]);

4
src/webui/www/public/scripts/mocha-init.js

@ -101,7 +101,7 @@ initializeWindows = function() {
globalUploadLimitFN = function() { globalUploadLimitFN = function() {
new MochaUI.Window({ new MochaUI.Window({
id: 'uploadLimitPage', id: 'uploadLimitPage',
title: "_(Global Upload Speed Limiting)", title: "_(Global Upload Speed Limit)",
loadMethod: 'iframe', loadMethod: 'iframe',
contentURL: 'uploadlimit.html?hash=global', contentURL: 'uploadlimit.html?hash=global',
scrollbars: false, scrollbars: false,
@ -165,7 +165,7 @@ initializeWindows = function() {
globalDownloadLimitFN = function() { globalDownloadLimitFN = function() {
new MochaUI.Window({ new MochaUI.Window({
id: 'downloadLimitPage', id: 'downloadLimitPage',
title: "_(Global Download Speed Limiting)", title: "_(Global Download Speed Limit)",
loadMethod: 'iframe', loadMethod: 'iframe',
contentURL: 'downloadlimit.html?hash=global', contentURL: 'downloadlimit.html?hash=global',
scrollbars: false, scrollbars: false,

2
src/webui/www/public/scripts/mocha-yc.js

File diff suppressed because one or more lines are too long

10
src/webui/www/public/scripts/mocha.js

@ -4648,7 +4648,7 @@ MUI.Column = new Class({
this.columnToggle(); this.columnToggle();
}.bind(this)); }.bind(this));
this.resize.attach(); this.resize.attach();
this.handleEl.setStyle('cursor', Browser.Engine.webkit ? 'col-resize' : 'e-resize').addClass('attached'); this.handleEl.setStyle('cursor', (Browser.Engine.webkit || Browser.Engine.gecko) ? 'col-resize' : 'e-resize').addClass('attached');
MUI.rWidth(); MUI.rWidth();
this.fireEvent('onExpand'); this.fireEvent('onExpand');
@ -5104,7 +5104,7 @@ MUI.extend({
instance.resize.attach(); instance.resize.attach();
instance.handleEl.setStyles({ instance.handleEl.setStyles({
'display': 'block', 'display': 'block',
'cursor': Browser.Engine.webkit ? 'row-resize' : 'n-resize' 'cursor': (Browser.Engine.webkit || Browser.Engine.gecko) ? 'row-resize' : 'n-resize'
}).removeClass('detached'); }).removeClass('detached');
} else { } else {
instance.resize.detach(); instance.resize.detach();
@ -5345,7 +5345,7 @@ function addResizeRight(element, min, max){
var instance = instances.get(element.id); var instance = instances.get(element.id);
var handle = element.getNext('.columnHandle'); var handle = element.getNext('.columnHandle');
handle.setStyle('cursor', Browser.Engine.webkit ? 'col-resize' : 'e-resize'); handle.setStyle('cursor', (Browser.Engine.webkit || Browser.Engine.gecko) ? 'col-resize' : 'e-resize');
if (!min) min = 50; if (!min) min = 50;
if (!max) max = 250; if (!max) max = 250;
if (MUI.ieLegacySupport) { if (MUI.ieLegacySupport) {
@ -5401,7 +5401,7 @@ function addResizeLeft(element, min, max){
var instance = instances.get(element.id); var instance = instances.get(element.id);
var handle = element.getPrevious('.columnHandle'); var handle = element.getPrevious('.columnHandle');
handle.setStyle('cursor', Browser.Engine.webkit ? 'col-resize' : 'e-resize'); handle.setStyle('cursor', (Browser.Engine.webkit || Browser.Engine.gecko) ? 'col-resize' : 'e-resize');
var partner = element.getPrevious('.column'); var partner = element.getPrevious('.column');
if (!min) min = 50; if (!min) min = 50;
if (!max) max = 250; if (!max) max = 250;
@ -5443,7 +5443,7 @@ function addResizeBottom(element){
var instances = MUI.Panels.instances; var instances = MUI.Panels.instances;
var instance = instances.get(element.id); var instance = instances.get(element.id);
var handle = instance.handleEl; var handle = instance.handleEl;
handle.setStyle('cursor', Browser.Engine.webkit ? 'row-resize' : 'n-resize'); handle.setStyle('cursor', (Browser.Engine.webkit || Browser.Engine.gecko) ? 'row-resize' : 'n-resize');
partner = instance.partner; partner = instance.partner;
min = 0; min = 0;
max = function(){ max = function(){

81
src/webui/www/public/uploadlimit.html

@ -1,52 +1,61 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>_(Torrent Upload Speed Limiting)</title> <title>_(Torrent Upload Speed Limiting)</title>
<link rel="stylesheet" href="css/style.css" type="text/css" /> <link rel="stylesheet" href="css/style.css" type="text/css" />
<script type="text/javascript" src="scripts/mootools-1.2-core-yc.js" charset="utf-8"></script> <script type="text/javascript" src="scripts/mootools-1.2-core-yc.js" charset="utf-8"></script>
<script type="text/javascript" src="scripts/mootools-1.2-more.js" charset="utf-8"></script> <script type="text/javascript" src="scripts/mootools-1.2-more.js" charset="utf-8"></script>
<script type="text/javascript" src="scripts/mocha-yc.js" charset="utf-8"></script> <script type="text/javascript" src="scripts/mocha-yc.js" charset="utf-8"></script>
<script type="text/javascript" src="scripts/parametrics.js" charset="utf-8"></script> <script type="text/javascript" src="scripts/parametrics.js" charset="utf-8"></script>
</head> </head>
<body> <body>
<div style="width: 100%; text-align: center; margin: 0 auto;"> <div style="width: 100%; text-align: center; margin: 0 auto; overflow: hidden">
<div id="uplimitSlider" class="slider"> <div id="uplimitSlider" class="slider">
<div id="uplimitUpdate" class="update">_(Upload limit:) <input id="uplimitUpdatevalue" size="6" placeholder="∞" style="text-align: center;"> <span id="upLimitUnit">_(KiB/s)</span></div> <div id="uplimitUpdate" class="update">_(Upload limit:) <input id="uplimitUpdatevalue" size="6" placeholder="∞" style="text-align: center;"> <span id="upLimitUnit">_(KiB/s)</span></div>
<div class="sliderWrapper"> <div class="sliderWrapper">
<div id="uplimitSliderknob" class="sliderknob"></div> <div id="uplimitSliderknob" class="sliderknob"></div>
<div id="uplimitSliderarea" class="sliderarea"></div> <div id="uplimitSliderarea" class="sliderarea"></div>
</div> </div>
<div class="clear"></div> <div class="clear"></div>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
var hash = new URI().getData('hash'); var hash = new URI().getData('hash');
setUpLimit = function() { setUpLimit = function() {
var limit = $("uplimitUpdatevalue").value.toInt() * 1024; var limit = $("uplimitUpdatevalue").value.toInt() * 1024;
if(hash == "global") { if (hash == "global") {
new Request({url: 'command/setGlobalUpLimit', new Request({
method: 'post', url: 'command/setGlobalUpLimit',
data: {'limit': limit}, method: 'post',
onComplete: function() { data: {
window.parent.closeWindows(); 'limit': limit
} },
}).send(); onComplete: function() {
}else { window.parent.updateTransferInfo();
new Request({url: 'command/setTorrentUpLimit', window.parent.closeWindows();
method: 'post', }
data: {'hash': hash, 'limit': limit}, }).send();
onComplete: function() { }
window.parent.closeWindows(); else {
} new Request({
}).send(); url: 'command/setTorrentUpLimit',
} method: 'post',
} data: {
'hash': hash,
'limit': limit
},
onComplete: function() {
window.parent.closeWindows();
}
}).send();
}
}
</script> </script>
<input type="button" value="_(Apply)" onclick="setUpLimit()"/> <input type="button" value="_(Apply)" onclick="setUpLimit()"/>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
MochaUI.addUpLimitSlider(hash); MochaUI.addUpLimitSlider(hash);
</script> </script>
</body> </body>

Loading…
Cancel
Save