Some work about adaptive color scheme for Web UI (PR #19901)
http://[316:c51a:62a3:8b9::4]/d4708/qBittorrent/src/branch/adaptive-webui
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
331 lines
12 KiB
331 lines
12 KiB
18 years ago
|
/*
|
||
|
* Bittorrent Client using Qt4 and libtorrent.
|
||
17 years ago
|
* Copyright (C) 2006 Christophe Dumez
|
||
18 years ago
|
*
|
||
17 years ago
|
* This program is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU General Public License
|
||
|
* as published by the Free Software Foundation; either version 2
|
||
|
* of the License, or (at your option) any later version.
|
||
18 years ago
|
*
|
||
|
* This program is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
17 years ago
|
* along with this program; if not, write to the Free Software
|
||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||
|
*
|
||
16 years ago
|
* In addition, as a special exception, the copyright holders give permission to
|
||
|
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||
|
* modified versions of it that use the same license as the "OpenSSL" library),
|
||
|
* and distribute the linked executables. You must obey the GNU General Public
|
||
|
* License in all respects for all of the code used other than "OpenSSL". If you
|
||
|
* modify file(s), you may extend this exception to your version of the file(s),
|
||
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||
|
* exception statement from your version.
|
||
|
*
|
||
17 years ago
|
* Contact : chris@qbittorrent.org
|
||
18 years ago
|
*/
|
||
|
|
||
|
#ifndef TORRENTADDITION_H
|
||
|
#define TORRENTADDITION_H
|
||
|
|
||
|
#include <QDir>
|
||
|
#include <QFileDialog>
|
||
|
#include <QFile>
|
||
|
#include <fstream>
|
||
|
#include <QMessageBox>
|
||
18 years ago
|
#include <QMenu>
|
||
18 years ago
|
#include <QSettings>
|
||
18 years ago
|
#include <QHeaderView>
|
||
18 years ago
|
|
||
|
#include <libtorrent/session.hpp>
|
||
|
#include <libtorrent/bencode.hpp>
|
||
16 years ago
|
#include "bittorrent.h"
|
||
18 years ago
|
#include "misc.h"
|
||
15 years ago
|
#include "proplistdelegate.h"
|
||
18 years ago
|
#include "ui_addTorrentDialog.h"
|
||
15 years ago
|
#include "torrentpersistentdata.h"
|
||
|
#include "torrentfilesmodel.h"
|
||
18 years ago
|
|
||
|
using namespace libtorrent;
|
||
|
|
||
|
class torrentAdditionDialog : public QDialog, private Ui_addTorrentDialog{
|
||
|
Q_OBJECT
|
||
|
|
||
15 years ago
|
private:
|
||
|
bittorrent *BTSession;
|
||
|
QString fileName;
|
||
|
QString hash;
|
||
|
QString filePath;
|
||
|
QString from_url;
|
||
15 years ago
|
TorrentFilesModel *PropListModel;
|
||
15 years ago
|
PropListDelegate *PropDelegate;
|
||
|
unsigned int nbFiles;
|
||
|
boost::intrusive_ptr<torrent_info> t;
|
||
18 years ago
|
|
||
15 years ago
|
public:
|
||
|
torrentAdditionDialog(QWidget *parent, bittorrent* _BTSession) : QDialog(parent) {
|
||
|
setupUi(this);
|
||
|
setAttribute(Qt::WA_DeleteOnClose);
|
||
|
BTSession = _BTSession;
|
||
|
// Set Properties list model
|
||
15 years ago
|
PropListModel = new TorrentFilesModel();
|
||
15 years ago
|
torrentContentList->setModel(PropListModel);
|
||
|
torrentContentList->hideColumn(PROGRESS);
|
||
|
PropDelegate = new PropListDelegate();
|
||
|
torrentContentList->setItemDelegate(PropDelegate);
|
||
|
connect(torrentContentList, SIGNAL(clicked(const QModelIndex&)), torrentContentList, SLOT(edit(const QModelIndex&)));
|
||
|
connect(torrentContentList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayFilesListMenu(const QPoint&)));
|
||
|
connect(actionIgnored, SIGNAL(triggered()), this, SLOT(ignoreSelection()));
|
||
|
connect(actionNormal, SIGNAL(triggered()), this, SLOT(normalSelection()));
|
||
|
connect(actionHigh, SIGNAL(triggered()), this, SLOT(highSelection()));
|
||
|
connect(actionMaximum, SIGNAL(triggered()), this, SLOT(maximumSelection()));
|
||
|
connect(collapseAllButton, SIGNAL(clicked()), torrentContentList, SLOT(collapseAll()));
|
||
|
connect(expandAllButton, SIGNAL(clicked()), torrentContentList, SLOT(expandAll()));
|
||
15 years ago
|
// Remember columns width
|
||
|
readSettings();
|
||
15 years ago
|
//torrentContentList->header()->setResizeMode(0, QHeaderView::Stretch);
|
||
|
QString home = QDir::homePath();
|
||
|
if(home[home.length()-1] != QDir::separator()){
|
||
|
home += QDir::separator();
|
||
18 years ago
|
}
|
||
15 years ago
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
||
|
savePathTxt->setText(settings.value(QString::fromUtf8("LastDirTorrentAdd"), home+QString::fromUtf8("qBT_dir")).toString());
|
||
|
if(settings.value("Preferences/Downloads/StartInPause", false).toBool()) {
|
||
|
addInPause->setChecked(true);
|
||
|
addInPause->setEnabled(false);
|
||
16 years ago
|
}
|
||
15 years ago
|
#ifndef LIBTORRENT_0_15
|
||
|
addInSeed->setEnabled(false);
|
||
|
#endif
|
||
15 years ago
|
}
|
||
16 years ago
|
|
||
15 years ago
|
~torrentAdditionDialog() {
|
||
15 years ago
|
saveSettings();
|
||
15 years ago
|
delete PropDelegate;
|
||
|
delete PropListModel;
|
||
|
}
|
||
18 years ago
|
|
||
15 years ago
|
void readSettings() {
|
||
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
||
|
QVariantList contentColsWidths = settings.value(QString::fromUtf8("TorrentAdditionDlg/filesColsWidth"), QVariantList()).toList();
|
||
|
if(contentColsWidths.empty()) {
|
||
|
torrentContentList->header()->resizeSection(0, 200);
|
||
|
} else {
|
||
|
for(int i=0; i<contentColsWidths.size(); ++i) {
|
||
|
torrentContentList->setColumnWidth(i, contentColsWidths.at(i).toInt());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void saveSettings() {
|
||
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
||
|
QVariantList contentColsWidths;
|
||
|
// -1 because we hid PROGRESS column
|
||
|
for(int i=0; i<PropListModel->columnCount()-1; ++i) {
|
||
|
contentColsWidths.append(torrentContentList->columnWidth(i));
|
||
|
}
|
||
|
settings.setValue(QString::fromUtf8("TorrentAdditionDlg/filesColsWidth"), contentColsWidths);
|
||
|
}
|
||
|
|
||
15 years ago
|
void showLoad(QString filePath, QString from_url=QString::null){
|
||
|
if(!QFile::exists(filePath)) {
|
||
|
close();
|
||
|
return;
|
||
|
}
|
||
|
this->filePath = filePath;
|
||
|
this->from_url = from_url;
|
||
|
// Getting torrent file informations
|
||
|
try {
|
||
|
t = new torrent_info(filePath.toLocal8Bit().data());
|
||
|
} catch(std::exception&) {
|
||
|
qDebug("Caught error loading torrent");
|
||
|
if(!from_url.isNull()){
|
||
|
BTSession->addConsoleMessage(tr("Unable to decode torrent file:")+QString::fromUtf8(" '")+from_url+QString::fromUtf8("'"), QString::fromUtf8("red"));
|
||
|
QFile::remove(filePath);
|
||
|
}else{
|
||
|
BTSession->addConsoleMessage(tr("Unable to decode torrent file:")+QString::fromUtf8(" '")+filePath+QString::fromUtf8("'"), QString::fromUtf8("red"));
|
||
17 years ago
|
}
|
||
15 years ago
|
close();
|
||
|
return;
|
||
17 years ago
|
}
|
||
15 years ago
|
nbFiles = t->num_files();
|
||
|
// Setting file name
|
||
|
fileName = misc::toQString(t->name());
|
||
|
hash = misc::toQString(t->info_hash());
|
||
|
// Use left() to remove .old extension
|
||
|
QString newFileName;
|
||
|
if(fileName.endsWith(QString::fromUtf8(".old"))){
|
||
|
newFileName = fileName.left(fileName.size()-4);
|
||
|
}else{
|
||
|
newFileName = fileName;
|
||
|
}
|
||
|
fileNameLbl->setText(QString::fromUtf8("<center><b>")+newFileName+QString::fromUtf8("</b></center>"));
|
||
|
// List files in torrent
|
||
15 years ago
|
PropListModel->setupModelData(*t);
|
||
|
// Expand first item if possible
|
||
|
torrentContentList->expand(PropListModel->index(0, 0));
|
||
|
connect(PropDelegate, SIGNAL(filteredFilesChanged()), this, SLOT(updateDiskSpaceLabels()));
|
||
15 years ago
|
//torrentContentList->expandAll();
|
||
15 years ago
|
connect(savePathTxt, SIGNAL(textChanged(QString)), this, SLOT(updateDiskSpaceLabels()));
|
||
15 years ago
|
updateDiskSpaceLabels();
|
||
|
show();
|
||
|
}
|
||
17 years ago
|
|
||
15 years ago
|
public slots:
|
||
|
|
||
|
void updateDiskSpaceLabels() {
|
||
15 years ago
|
long long available = misc::freeDiskSpaceOnPath(savePathTxt->text());
|
||
15 years ago
|
lbl_disk_space->setText(misc::friendlyUnit(available));
|
||
|
|
||
15 years ago
|
// Determine torrent size
|
||
15 years ago
|
qulonglong torrent_size = 0;
|
||
15 years ago
|
unsigned int nbFiles = t->num_files();
|
||
|
std::vector<int> priorities = PropListModel->getFilesPriorities(nbFiles);
|
||
|
|
||
|
for(unsigned int i=0; i<nbFiles; ++i) {
|
||
15 years ago
|
if(priorities[i] > 0)
|
||
|
torrent_size += t->file_at(i).size;
|
||
|
}
|
||
|
lbl_torrent_size->setText(misc::friendlyUnit(torrent_size));
|
||
|
// Check if free space is sufficient
|
||
|
if(available > 0) {
|
||
15 years ago
|
if((unsigned long long)available > torrent_size) {
|
||
15 years ago
|
// Space is sufficient
|
||
|
label_space_msg->setText(tr("(%1 left after torrent download)", "e.g. (100MiB left after torrent download)").arg(misc::friendlyUnit(available-torrent_size)));
|
||
|
} else {
|
||
|
// Space is unsufficient
|
||
|
label_space_msg->setText("<font color=\"red\">"+tr("(%1 more are required to download)", "e.g. (100MiB more are required to download)").arg(misc::friendlyUnit(torrent_size-available))+"</font>");
|
||
18 years ago
|
}
|
||
15 years ago
|
} else {
|
||
|
// Available disk space is unknown
|
||
|
label_space_msg->setText("");
|
||
18 years ago
|
}
|
||
15 years ago
|
}
|
||
18 years ago
|
|
||
15 years ago
|
void on_browseButton_clicked(){
|
||
|
QString dir;
|
||
|
QDir saveDir(savePathTxt->text());
|
||
|
if(saveDir.exists()){
|
||
|
dir = QFileDialog::getExistingDirectory(this, tr("Choose save path"), savePathTxt->text());
|
||
|
}else{
|
||
|
dir = QFileDialog::getExistingDirectory(this, tr("Choose save path"), QDir::homePath());
|
||
17 years ago
|
}
|
||
15 years ago
|
if(!dir.isNull()){
|
||
|
savePathTxt->setText(dir);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void on_CancelButton_clicked(){
|
||
|
close();
|
||
|
}
|
||
17 years ago
|
|
||
15 years ago
|
bool allFiltered() const {
|
||
15 years ago
|
return PropListModel->allFiltered();
|
||
15 years ago
|
}
|
||
17 years ago
|
|
||
15 years ago
|
void displayFilesListMenu(const QPoint&){
|
||
|
QMenu myFilesLlistMenu(this);
|
||
|
// Enable/disable pause/start action given the DL state
|
||
|
myFilesLlistMenu.setTitle(tr("Priority"));
|
||
|
myFilesLlistMenu.addAction(actionIgnored);
|
||
|
myFilesLlistMenu.addAction(actionNormal);
|
||
|
myFilesLlistMenu.addAction(actionHigh);
|
||
|
myFilesLlistMenu.addAction(actionMaximum);
|
||
|
// Call menu
|
||
|
myFilesLlistMenu.exec(QCursor::pos());
|
||
|
}
|
||
|
|
||
|
void ignoreSelection(){
|
||
|
QModelIndexList selectedIndexes = torrentContentList->selectionModel()->selectedIndexes();
|
||
|
foreach(const QModelIndex &index, selectedIndexes){
|
||
|
if(index.column() == PRIORITY){
|
||
|
PropListModel->setData(index, QVariant(IGNORED));
|
||
17 years ago
|
}
|
||
|
}
|
||
15 years ago
|
}
|
||
17 years ago
|
|
||
15 years ago
|
void normalSelection(){
|
||
|
QModelIndexList selectedIndexes = torrentContentList->selectionModel()->selectedIndexes();
|
||
|
foreach(const QModelIndex &index, selectedIndexes){
|
||
|
if(index.column() == PRIORITY){
|
||
|
PropListModel->setData(index, QVariant(NORMAL));
|
||
17 years ago
|
}
|
||
|
}
|
||
15 years ago
|
}
|
||
17 years ago
|
|
||
15 years ago
|
void highSelection(){
|
||
|
QModelIndexList selectedIndexes = torrentContentList->selectionModel()->selectedIndexes();
|
||
|
foreach(const QModelIndex &index, selectedIndexes){
|
||
|
if(index.column() == PRIORITY){
|
||
|
PropListModel->setData(index, QVariant(HIGH));
|
||
17 years ago
|
}
|
||
|
}
|
||
15 years ago
|
}
|
||
17 years ago
|
|
||
15 years ago
|
void maximumSelection(){
|
||
|
QModelIndexList selectedIndexes = torrentContentList->selectionModel()->selectedIndexes();
|
||
|
foreach(const QModelIndex &index, selectedIndexes){
|
||
|
if(index.column() == PRIORITY){
|
||
|
PropListModel->setData(index, QVariant(MAXIMUM));
|
||
18 years ago
|
}
|
||
|
}
|
||
15 years ago
|
}
|
||
18 years ago
|
|
||
15 years ago
|
void savePiecesPriorities(){
|
||
|
qDebug("Saving pieces priorities");
|
||
15 years ago
|
std::vector<int> priorities = PropListModel->getFilesPriorities(t->num_files());
|
||
|
TorrentTempData::setFilesPriority(hash, priorities);
|
||
15 years ago
|
}
|
||
|
|
||
|
void on_OkButton_clicked(){
|
||
|
QDir savePath(savePathTxt->text());
|
||
|
if(savePathTxt->text().trimmed().isEmpty()){
|
||
|
QMessageBox::critical(0, tr("Empty save path"), tr("Please enter a save path"));
|
||
|
return;
|
||
|
}
|
||
|
// Check if savePath exists
|
||
|
if(!savePath.exists()){
|
||
|
if(!savePath.mkpath(savePath.path())){
|
||
|
QMessageBox::critical(0, tr("Save path creation error"), tr("Could not create the save path"));
|
||
18 years ago
|
return;
|
||
|
}
|
||
|
}
|
||
15 years ago
|
// Save savepath
|
||
|
TorrentTempData::setSavePath(hash, savePath.path());
|
||
|
// Save last dir to remember it
|
||
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
||
|
settings.setValue(QString::fromUtf8("LastDirTorrentAdd"), savePathTxt->text());
|
||
|
// Create .incremental file if necessary
|
||
|
TorrentTempData::setSequential(hash, checkIncrementalDL->isChecked());
|
||
15 years ago
|
#ifdef LIBTORRENT_0_15
|
||
15 years ago
|
// Skip file checking and directly start seeding
|
||
15 years ago
|
if(addInSeed->isChecked()) {
|
||
|
// Check if local file(s) actually exist
|
||
|
if(savePath.exists(misc::toQString(t->name()))) {
|
||
|
TorrentTempData::setSeedingMode(hash, true);
|
||
|
} else {
|
||
|
QMessageBox::warning(0, tr("Seeding mode error"), tr("You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path."));
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
15 years ago
|
#endif
|
||
15 years ago
|
// Check if there is at least one selected file
|
||
|
if(allFiltered()){
|
||
|
QMessageBox::warning(0, tr("Invalid file selection"), tr("You must select at least one file in the torrent"));
|
||
|
return;
|
||
|
}
|
||
|
// save filtered files
|
||
|
savePiecesPriorities();
|
||
|
// Add to download list
|
||
|
QTorrentHandle h = BTSession->addTorrent(filePath, false, from_url);
|
||
|
if(addInPause->isChecked() && h.is_valid())
|
||
|
h.pause();
|
||
|
close();
|
||
|
}
|
||
18 years ago
|
};
|
||
|
|
||
|
#endif
|