mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-01-11 15:27:54 +00:00
Fix coding style for several files
trackerlist autoexpandabledialog previewselect shutdownconfirmdlg torrentcontentfiltermodel torrentcontenttreeview peerlistsortmodel.h
This commit is contained in:
parent
fd05f5dec5
commit
91f528bc96
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt4 and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2013 Nick Tiskov
|
* Copyright (C) 2013 Nick Tiskov <daymansmail@gmail.com>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@ -24,71 +24,74 @@
|
|||||||
* modify file(s), you may extend this exception to your version of the file(s),
|
* 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
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*
|
|
||||||
* Contact : daymansmail@gmail.com
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "autoexpandabledialog.h"
|
||||||
|
|
||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
|
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "autoexpandabledialog.h"
|
|
||||||
#include "ui_autoexpandabledialog.h"
|
#include "ui_autoexpandabledialog.h"
|
||||||
|
|
||||||
AutoExpandableDialog::AutoExpandableDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AutoExpandableDialog) {
|
AutoExpandableDialog::AutoExpandableDialog(QWidget *parent)
|
||||||
ui->setupUi(this);
|
: QDialog(parent)
|
||||||
|
, m_ui(new Ui::AutoExpandableDialog)
|
||||||
|
{
|
||||||
|
m_ui->setupUi(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoExpandableDialog::~AutoExpandableDialog() {
|
AutoExpandableDialog::~AutoExpandableDialog()
|
||||||
delete ui;
|
{
|
||||||
|
delete m_ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AutoExpandableDialog::getText(QWidget *parent, const QString &title, const QString &label,
|
QString AutoExpandableDialog::getText(QWidget *parent, const QString &title, const QString &label,
|
||||||
QLineEdit::EchoMode mode, const QString &text, bool *ok,
|
QLineEdit::EchoMode mode, const QString &text,
|
||||||
Qt::InputMethodHints inputMethodHints) {
|
bool *ok, Qt::InputMethodHints inputMethodHints)
|
||||||
|
{
|
||||||
|
AutoExpandableDialog d(parent);
|
||||||
|
d.setWindowTitle(title);
|
||||||
|
d.m_ui->textLabel->setText(label);
|
||||||
|
d.m_ui->textEdit->setText(text);
|
||||||
|
d.m_ui->textEdit->setEchoMode(mode);
|
||||||
|
d.m_ui->textEdit->setInputMethodHints(inputMethodHints);
|
||||||
|
|
||||||
AutoExpandableDialog d(parent);
|
bool res = d.exec();
|
||||||
d.setWindowTitle(title);
|
if (ok)
|
||||||
d.ui->textLabel->setText(label);
|
*ok = res;
|
||||||
d.ui->textEdit->setText(text);
|
|
||||||
d.ui->textEdit->setEchoMode(mode);
|
|
||||||
d.ui->textEdit->setInputMethodHints(inputMethodHints);
|
|
||||||
|
|
||||||
bool res = d.exec();
|
if (!res) return QString();
|
||||||
if (ok)
|
|
||||||
*ok = res;
|
|
||||||
|
|
||||||
if (!res)
|
return d.m_ui->textEdit->text();
|
||||||
return QString();
|
|
||||||
|
|
||||||
return d.ui->textEdit->text();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoExpandableDialog::showEvent(QShowEvent *e) {
|
void AutoExpandableDialog::showEvent(QShowEvent *e)
|
||||||
// Overriding showEvent is required for consistent UI with fixed size under custom DPI
|
{
|
||||||
// Show dialog
|
// Overriding showEvent is required for consistent UI with fixed size under custom DPI
|
||||||
QDialog::showEvent(e);
|
// Show dialog
|
||||||
// and resize textbox to fit the text
|
QDialog::showEvent(e);
|
||||||
|
// and resize textbox to fit the text
|
||||||
|
|
||||||
// NOTE: For some strange reason QFontMetrics gets more accurate
|
// NOTE: For some strange reason QFontMetrics gets more accurate
|
||||||
// when called from showEvent. Only 6 symbols off instead of 11 symbols off.
|
// when called from showEvent. Only 6 symbols off instead of 11 symbols off.
|
||||||
int textW = ui->textEdit->fontMetrics().width(ui->textEdit->text()) + 4;
|
int textW = m_ui->textEdit->fontMetrics().width(m_ui->textEdit->text()) + 4;
|
||||||
int wd = textW;
|
int wd = textW;
|
||||||
|
|
||||||
if (!windowTitle().isEmpty()) {
|
if (!windowTitle().isEmpty()) {
|
||||||
int _w = fontMetrics().width(windowTitle());
|
int w = fontMetrics().width(windowTitle());
|
||||||
if (_w > wd)
|
if (w > wd)
|
||||||
wd = _w;
|
wd = w;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ui->textLabel->text().isEmpty()) {
|
if (!m_ui->textLabel->text().isEmpty()) {
|
||||||
int _w = ui->textLabel->fontMetrics().width(ui->textLabel->text());
|
int w = m_ui->textLabel->fontMetrics().width(m_ui->textLabel->text());
|
||||||
if (_w > wd)
|
if (w > wd)
|
||||||
wd = _w;
|
wd = w;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now resize the dialog to fit the contents
|
// Now resize the dialog to fit the contents
|
||||||
// max width of text from either of: label, title, textedit
|
// max width of text from either of: label, title, textedit
|
||||||
// If the value is less than dialog default size default size is used
|
// If the value is less than dialog default size, default size is used
|
||||||
if (wd > width())
|
if (wd > width())
|
||||||
resize(width() - ui->verticalLayout->sizeHint().width() + wd, height());
|
resize(width() - m_ui->verticalLayout->sizeHint().width() + wd, height());
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt4 and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2013 Nick Tiskov
|
* Copyright (C) 2013 Nick Tiskov <daymansmail@gmail.com>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@ -24,37 +24,37 @@
|
|||||||
* modify file(s), you may extend this exception to your version of the file(s),
|
* 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
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*
|
|
||||||
* Contact : daymansmail@gmail.com
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef AUTOEXPANDABLEDIALOG_H
|
#ifndef AUTOEXPANDABLEDIALOG_H
|
||||||
#define AUTOEXPANDABLEDIALOG_H
|
#define AUTOEXPANDABLEDIALOG_H
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QString>
|
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui
|
||||||
class AutoExpandableDialog;
|
{
|
||||||
|
class AutoExpandableDialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
class AutoExpandableDialog : public QDialog {
|
class AutoExpandableDialog: public QDialog
|
||||||
Q_OBJECT
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AutoExpandableDialog(QWidget *parent);
|
explicit AutoExpandableDialog(QWidget *parent);
|
||||||
~AutoExpandableDialog();
|
~AutoExpandableDialog();
|
||||||
|
|
||||||
static QString getText(QWidget *parent, const QString& title, const QString& label,
|
static QString getText(QWidget *parent, const QString &title, const QString &label,
|
||||||
QLineEdit::EchoMode mode = QLineEdit::Normal, const QString & text = QString(),
|
QLineEdit::EchoMode mode = QLineEdit::Normal, const QString &text = QString(),
|
||||||
bool * ok = 0, Qt::InputMethodHints inputMethodHints = Qt::ImhNone);
|
bool *ok = 0, Qt::InputMethodHints inputMethodHints = Qt::ImhNone);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void showEvent(QShowEvent *e);
|
void showEvent(QShowEvent *e);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::AutoExpandableDialog *ui;
|
Ui::AutoExpandableDialog *m_ui;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // AUTOEXPANDABLEDIALOG_H
|
#endif // AUTOEXPANDABLEDIALOG_H
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt4 and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2011 Christophe Dumez
|
* Copyright (C) 2011 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@ -24,106 +24,113 @@
|
|||||||
* modify file(s), you may extend this exception to your version of the file(s),
|
* 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
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*
|
|
||||||
* Contact : chris@qbittorrent.org
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <QStandardItemModel>
|
#include "previewselect.h"
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QFile>
|
#include <QStandardItemModel>
|
||||||
#include <QTableView>
|
#include <QTableView>
|
||||||
|
|
||||||
|
#include "base/preferences.h"
|
||||||
|
#include "base/utils/fs.h"
|
||||||
#include "base/utils/misc.h"
|
#include "base/utils/misc.h"
|
||||||
#include "previewlistdelegate.h"
|
#include "previewlistdelegate.h"
|
||||||
#include "previewselect.h"
|
|
||||||
#include "base/utils/fs.h"
|
|
||||||
#include "base/preferences.h"
|
|
||||||
|
|
||||||
PreviewSelect::PreviewSelect(QWidget* parent, BitTorrent::TorrentHandle *const torrent)
|
PreviewSelect::PreviewSelect(QWidget* parent, BitTorrent::TorrentHandle *const torrent)
|
||||||
: QDialog(parent)
|
: QDialog(parent)
|
||||||
, m_torrent(torrent)
|
, m_torrent(torrent)
|
||||||
{
|
{
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
Preferences* const pref = Preferences::instance();
|
Preferences *const pref = Preferences::instance();
|
||||||
// Preview list
|
// Preview list
|
||||||
previewListModel = new QStandardItemModel(0, NB_COLUMNS);
|
m_previewListModel = new QStandardItemModel(0, NB_COLUMNS);
|
||||||
previewListModel->setHeaderData(NAME, Qt::Horizontal, tr("Name"));
|
m_previewListModel->setHeaderData(NAME, Qt::Horizontal, tr("Name"));
|
||||||
previewListModel->setHeaderData(SIZE, Qt::Horizontal, tr("Size"));
|
m_previewListModel->setHeaderData(SIZE, Qt::Horizontal, tr("Size"));
|
||||||
previewListModel->setHeaderData(PROGRESS, Qt::Horizontal, tr("Progress"));
|
m_previewListModel->setHeaderData(PROGRESS, Qt::Horizontal, tr("Progress"));
|
||||||
|
|
||||||
// This hack fixes reordering of first column with Qt5.
|
// This hack fixes reordering of first column with Qt5.
|
||||||
// https://github.com/qtproject/qtbase/commit/e0fc088c0c8bc61dbcaf5928b24986cd61a22777
|
// https://github.com/qtproject/qtbase/commit/e0fc088c0c8bc61dbcaf5928b24986cd61a22777
|
||||||
QTableView unused;
|
QTableView unused;
|
||||||
unused.setVerticalHeader(previewList->header());
|
unused.setVerticalHeader(previewList->header());
|
||||||
previewList->header()->setParent(previewList);
|
previewList->header()->setParent(previewList);
|
||||||
unused.setVerticalHeader(new QHeaderView(Qt::Horizontal));
|
unused.setVerticalHeader(new QHeaderView(Qt::Horizontal));
|
||||||
previewList->setModel(previewListModel);
|
|
||||||
previewList->hideColumn(FILE_INDEX);
|
previewList->setModel(m_previewListModel);
|
||||||
listDelegate = new PreviewListDelegate(this);
|
previewList->hideColumn(FILE_INDEX);
|
||||||
previewList->setItemDelegate(listDelegate);
|
m_listDelegate = new PreviewListDelegate(this);
|
||||||
previewList->header()->resizeSection(0, 200);
|
previewList->setItemDelegate(m_listDelegate);
|
||||||
previewList->setAlternatingRowColors(pref->useAlternatingRowColors());
|
previewList->header()->resizeSection(0, 200);
|
||||||
// Fill list in
|
previewList->setAlternatingRowColors(pref->useAlternatingRowColors());
|
||||||
QVector<qreal> fp = torrent->filesProgress();
|
// Fill list in
|
||||||
int nbFiles = torrent->filesCount();
|
QVector<qreal> fp = torrent->filesProgress();
|
||||||
for (int i = 0; i < nbFiles; ++i) {
|
int nbFiles = torrent->filesCount();
|
||||||
QString fileName = torrent->fileName(i);
|
for (int i = 0; i < nbFiles; ++i) {
|
||||||
if (fileName.endsWith(QB_EXT))
|
QString fileName = torrent->fileName(i);
|
||||||
fileName.chop(4);
|
if (fileName.endsWith(QB_EXT))
|
||||||
QString extension = Utils::Fs::fileExtension(fileName).toUpper();
|
fileName.chop(4);
|
||||||
if (Utils::Misc::isPreviewable(extension)) {
|
QString extension = Utils::Fs::fileExtension(fileName).toUpper();
|
||||||
int row = previewListModel->rowCount();
|
if (Utils::Misc::isPreviewable(extension)) {
|
||||||
previewListModel->insertRow(row);
|
int row = m_previewListModel->rowCount();
|
||||||
previewListModel->setData(previewListModel->index(row, NAME), QVariant(fileName));
|
m_previewListModel->insertRow(row);
|
||||||
previewListModel->setData(previewListModel->index(row, SIZE), QVariant(torrent->fileSize(i)));
|
m_previewListModel->setData(m_previewListModel->index(row, NAME), QVariant(fileName));
|
||||||
previewListModel->setData(previewListModel->index(row, PROGRESS), QVariant(fp[i]));
|
m_previewListModel->setData(m_previewListModel->index(row, SIZE), QVariant(torrent->fileSize(i)));
|
||||||
previewListModel->setData(previewListModel->index(row, FILE_INDEX), QVariant(i));
|
m_previewListModel->setData(m_previewListModel->index(row, PROGRESS), QVariant(fp[i]));
|
||||||
|
m_previewListModel->setData(m_previewListModel->index(row, FILE_INDEX), QVariant(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!previewListModel->rowCount()) {
|
if (m_previewListModel->rowCount() == 0) {
|
||||||
QMessageBox::critical(this->parentWidget(), tr("Preview impossible"), tr("Sorry, we can't preview this file"));
|
QMessageBox::critical(this->parentWidget(), tr("Preview impossible"), tr("Sorry, we can't preview this file"));
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
connect(this, SIGNAL(readyToPreviewFile(QString)), parent, SLOT(previewFile(QString)));
|
||||||
|
m_previewListModel->sort(NAME);
|
||||||
|
previewList->header()->setSortIndicator(0, Qt::AscendingOrder);
|
||||||
|
previewList->selectionModel()->select(m_previewListModel->index(0, NAME), QItemSelectionModel::Select | QItemSelectionModel::Rows);
|
||||||
|
|
||||||
|
if (m_previewListModel->rowCount() == 1) {
|
||||||
|
qDebug("Torrent file only contains one file, no need to display selection dialog before preview");
|
||||||
|
// Only one file : no choice
|
||||||
|
on_previewButton_clicked();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
qDebug("Displaying media file selection dialog for preview");
|
||||||
|
show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PreviewSelect::~PreviewSelect()
|
||||||
|
{
|
||||||
|
delete m_previewListModel;
|
||||||
|
delete m_listDelegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PreviewSelect::on_previewButton_clicked()
|
||||||
|
{
|
||||||
|
QModelIndexList selectedIndexes = previewList->selectionModel()->selectedRows(FILE_INDEX);
|
||||||
|
if (selectedIndexes.size() == 0) return;
|
||||||
|
|
||||||
|
// Flush data
|
||||||
|
m_torrent->flushCache();
|
||||||
|
|
||||||
|
QStringList absolutePaths(m_torrent->absoluteFilePaths());
|
||||||
|
// Only one file should be selected
|
||||||
|
QString path = absolutePaths.at(selectedIndexes.at(0).data().toInt());
|
||||||
|
// File
|
||||||
|
if (QFile::exists(path))
|
||||||
|
emit readyToPreviewFile(path);
|
||||||
|
else
|
||||||
|
QMessageBox::critical(this->parentWidget(), tr("Preview impossible"), tr("Sorry, we can't preview this file"));
|
||||||
|
|
||||||
close();
|
close();
|
||||||
}
|
|
||||||
connect(this, SIGNAL(readyToPreviewFile(QString)), parent, SLOT(previewFile(QString)));
|
|
||||||
previewListModel->sort(NAME);
|
|
||||||
previewList->header()->setSortIndicator(0, Qt::AscendingOrder);
|
|
||||||
previewList->selectionModel()->select(previewListModel->index(0, NAME), QItemSelectionModel::Select | QItemSelectionModel::Rows);
|
|
||||||
|
|
||||||
if (previewListModel->rowCount() == 1) {
|
|
||||||
qDebug("Torrent file only contains one file, no need to display selection dialog before preview");
|
|
||||||
// Only one file : no choice
|
|
||||||
on_previewButton_clicked();
|
|
||||||
}else{
|
|
||||||
qDebug("Displaying media file selection dialog for preview");
|
|
||||||
show();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PreviewSelect::~PreviewSelect() {
|
void PreviewSelect::on_cancelButton_clicked()
|
||||||
delete previewListModel;
|
{
|
||||||
delete listDelegate;
|
close();
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PreviewSelect::on_previewButton_clicked() {
|
|
||||||
QModelIndexList selectedIndexes = previewList->selectionModel()->selectedRows(FILE_INDEX);
|
|
||||||
if (selectedIndexes.size() == 0) return;
|
|
||||||
// Flush data
|
|
||||||
m_torrent->flushCache();
|
|
||||||
|
|
||||||
QStringList absolute_paths(m_torrent->absoluteFilePaths());
|
|
||||||
//only one file should be selected
|
|
||||||
QString path = absolute_paths.at(selectedIndexes.at(0).data().toInt());
|
|
||||||
// File
|
|
||||||
if (QFile::exists(path))
|
|
||||||
emit readyToPreviewFile(path);
|
|
||||||
else
|
|
||||||
QMessageBox::critical(this->parentWidget(), tr("Preview impossible"), tr("Sorry, we can't preview this file"));
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PreviewSelect::on_cancelButton_clicked() {
|
|
||||||
close();
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt4 and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2006 Christophe Dumez
|
* Copyright (C) 2011 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@ -24,8 +24,6 @@
|
|||||||
* modify file(s), you may extend this exception to your version of the file(s),
|
* 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
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*
|
|
||||||
* Contact : chris@qbittorrent.org
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PREVIEWSELECT_H
|
#ifndef PREVIEWSELECT_H
|
||||||
@ -33,36 +31,43 @@
|
|||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include "ui_preview.h"
|
|
||||||
#include "base/bittorrent/torrenthandle.h"
|
#include "base/bittorrent/torrenthandle.h"
|
||||||
|
#include "ui_preview.h"
|
||||||
|
|
||||||
|
class QStandardItemModel;
|
||||||
|
|
||||||
class PreviewListDelegate;
|
class PreviewListDelegate;
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
class PreviewSelect: public QDialog, private Ui::preview
|
||||||
class QStandardItemModel;
|
{
|
||||||
QT_END_NAMESPACE
|
Q_OBJECT
|
||||||
|
|
||||||
class PreviewSelect: public QDialog, private Ui::preview {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum PreviewColumn { NAME, SIZE, PROGRESS, FILE_INDEX, NB_COLUMNS };
|
enum PreviewColumn
|
||||||
|
{
|
||||||
|
NAME,
|
||||||
|
SIZE,
|
||||||
|
PROGRESS,
|
||||||
|
FILE_INDEX,
|
||||||
|
|
||||||
public:
|
NB_COLUMNS
|
||||||
PreviewSelect(QWidget* parent, BitTorrent::TorrentHandle *const torrent);
|
};
|
||||||
~PreviewSelect();
|
|
||||||
|
PreviewSelect(QWidget* parent, BitTorrent::TorrentHandle *const torrent);
|
||||||
|
~PreviewSelect();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void readyToPreviewFile(QString) const;
|
void readyToPreviewFile(QString) const;
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void on_previewButton_clicked();
|
void on_previewButton_clicked();
|
||||||
void on_cancelButton_clicked();
|
void on_cancelButton_clicked();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QStandardItemModel *previewListModel;
|
QStandardItemModel *m_previewListModel;
|
||||||
PreviewListDelegate *listDelegate;
|
PreviewListDelegate *m_listDelegate;
|
||||||
BitTorrent::TorrentHandle *const m_torrent;
|
BitTorrent::TorrentHandle *const m_torrent;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif // PREVIEWSELECT_H
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt4 and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2013 Nick Tiskov
|
* Copyright (C) 2013 Nick Tiskov <daymansmail@gmail.com>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@ -24,36 +24,40 @@
|
|||||||
* modify file(s), you may extend this exception to your version of the file(s),
|
* 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
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*
|
|
||||||
* Contact : daymansmail@gmail.com
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PEERLISTSORTMODEL_H
|
#ifndef PEERLISTSORTMODEL_H
|
||||||
#define PEERLISTSORTMODEL_H
|
#define PEERLISTSORTMODEL_H
|
||||||
|
|
||||||
#include <QStringList>
|
|
||||||
#include <QSortFilterProxyModel>
|
#include <QSortFilterProxyModel>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
#include "peerlistdelegate.h"
|
#include "peerlistdelegate.h"
|
||||||
|
|
||||||
class PeerListSortModel : public QSortFilterProxyModel {
|
class PeerListSortModel: public QSortFilterProxyModel
|
||||||
Q_OBJECT
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PeerListSortModel(QObject *parent = 0) : QSortFilterProxyModel(parent) {}
|
PeerListSortModel(QObject *parent = 0)
|
||||||
|
: QSortFilterProxyModel(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const {
|
bool lessThan(const QModelIndex &left, const QModelIndex &right) const
|
||||||
switch (sortColumn()) {
|
{
|
||||||
case PeerListDelegate::IP:
|
switch (sortColumn()) {
|
||||||
case PeerListDelegate::CLIENT: {
|
case PeerListDelegate::IP:
|
||||||
QString vL = left.data().toString();
|
case PeerListDelegate::CLIENT: {
|
||||||
QString vR = right.data().toString();
|
QString vL = left.data().toString();
|
||||||
return Utils::String::naturalCompareCaseInsensitive(vL, vR);
|
QString vR = right.data().toString();
|
||||||
}
|
return Utils::String::naturalCompareCaseInsensitive(vL, vR);
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return QSortFilterProxyModel::lessThan(left, right);
|
return QSortFilterProxyModel::lessThan(left, right);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PEERLISTSORTMODEL_H
|
#endif // PEERLISTSORTMODEL_H
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt4 and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2006 Christophe Dumez
|
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@ -24,8 +24,6 @@
|
|||||||
* modify file(s), you may extend this exception to your version of the file(s),
|
* 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
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*
|
|
||||||
* Contact : chris@qbittorrent.org
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "trackerlist.h"
|
#include "trackerlist.h"
|
||||||
@ -58,66 +56,66 @@ TrackerList::TrackerList(PropertiesWidget *properties)
|
|||||||
: QTreeWidget()
|
: QTreeWidget()
|
||||||
, m_properties(properties)
|
, m_properties(properties)
|
||||||
{
|
{
|
||||||
// Set header
|
// Set header
|
||||||
// Must be set before calling loadSettings() otherwise the header is reset on restart
|
// Must be set before calling loadSettings() otherwise the header is reset on restart
|
||||||
setHeaderLabels(headerLabels());
|
setHeaderLabels(headerLabels());
|
||||||
// Load settings
|
// Load settings
|
||||||
loadSettings();
|
loadSettings();
|
||||||
// Graphical settings
|
// Graphical settings
|
||||||
setRootIsDecorated(false);
|
setRootIsDecorated(false);
|
||||||
setAllColumnsShowFocus(true);
|
setAllColumnsShowFocus(true);
|
||||||
setItemsExpandable(false);
|
setItemsExpandable(false);
|
||||||
setSelectionMode(QAbstractItemView::ExtendedSelection);
|
setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||||
header()->setStretchLastSection(false); // Must be set after loadSettings() in order to work
|
header()->setStretchLastSection(false); // Must be set after loadSettings() in order to work
|
||||||
// Ensure that at least one column is visible at all times
|
// Ensure that at least one column is visible at all times
|
||||||
if (visibleColumnsCount() == 0)
|
if (visibleColumnsCount() == 0)
|
||||||
setColumnHidden(COL_URL, false);
|
setColumnHidden(COL_URL, false);
|
||||||
// To also mitigate the above issue, we have to resize each column when
|
// To also mitigate the above issue, we have to resize each column when
|
||||||
// its size is 0, because explicitly 'showing' the column isn't enough
|
// its size is 0, because explicitly 'showing' the column isn't enough
|
||||||
// in the above scenario.
|
// in the above scenario.
|
||||||
for (unsigned int i = 0; i < COL_COUNT; ++i)
|
for (unsigned int i = 0; i < COL_COUNT; ++i)
|
||||||
if ((columnWidth(i) <= 0) && !isColumnHidden(i))
|
if ((columnWidth(i) <= 0) && !isColumnHidden(i))
|
||||||
resizeColumnToContents(i);
|
resizeColumnToContents(i);
|
||||||
// Context menu
|
// Context menu
|
||||||
setContextMenuPolicy(Qt::CustomContextMenu);
|
setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showTrackerListMenu(QPoint)));
|
connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showTrackerListMenu(QPoint)));
|
||||||
// Header context menu
|
// Header context menu
|
||||||
header()->setContextMenuPolicy(Qt::CustomContextMenu);
|
header()->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
connect(header(), SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayToggleColumnsMenu(const QPoint&)));
|
connect(header(), SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayToggleColumnsMenu(const QPoint&)));
|
||||||
// Set DHT, PeX, LSD items
|
// Set DHT, PeX, LSD items
|
||||||
m_DHTItem = new QTreeWidgetItem({ "", "** [DHT] **", "", "0", "", "", "0" });
|
m_DHTItem = new QTreeWidgetItem({ "", "** [DHT] **", "", "0", "", "", "0" });
|
||||||
insertTopLevelItem(0, m_DHTItem);
|
insertTopLevelItem(0, m_DHTItem);
|
||||||
setRowColor(0, QColor("grey"));
|
setRowColor(0, QColor("grey"));
|
||||||
m_PEXItem = new QTreeWidgetItem({ "", "** [PeX] **", "", "0", "", "", "0" });
|
m_PEXItem = new QTreeWidgetItem({ "", "** [PeX] **", "", "0", "", "", "0" });
|
||||||
insertTopLevelItem(1, m_PEXItem);
|
insertTopLevelItem(1, m_PEXItem);
|
||||||
setRowColor(1, QColor("grey"));
|
setRowColor(1, QColor("grey"));
|
||||||
m_LSDItem = new QTreeWidgetItem({ "", "** [LSD] **", "", "0", "", "", "0" });
|
m_LSDItem = new QTreeWidgetItem({ "", "** [LSD] **", "", "0", "", "", "0" });
|
||||||
insertTopLevelItem(2, m_LSDItem);
|
insertTopLevelItem(2, m_LSDItem);
|
||||||
setRowColor(2, QColor("grey"));
|
setRowColor(2, QColor("grey"));
|
||||||
// Set static items alignment
|
// Set static items alignment
|
||||||
m_DHTItem->setTextAlignment(COL_RECEIVED, (Qt::AlignRight | Qt::AlignVCenter));
|
m_DHTItem->setTextAlignment(COL_RECEIVED, (Qt::AlignRight | Qt::AlignVCenter));
|
||||||
m_PEXItem->setTextAlignment(COL_RECEIVED, (Qt::AlignRight | Qt::AlignVCenter));
|
m_PEXItem->setTextAlignment(COL_RECEIVED, (Qt::AlignRight | Qt::AlignVCenter));
|
||||||
m_LSDItem->setTextAlignment(COL_RECEIVED, (Qt::AlignRight | Qt::AlignVCenter));
|
m_LSDItem->setTextAlignment(COL_RECEIVED, (Qt::AlignRight | Qt::AlignVCenter));
|
||||||
m_DHTItem->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter));
|
m_DHTItem->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter));
|
||||||
m_PEXItem->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter));
|
m_PEXItem->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter));
|
||||||
m_LSDItem->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter));
|
m_LSDItem->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter));
|
||||||
m_DHTItem->setTextAlignment(COL_PEERS, (Qt::AlignRight | Qt::AlignVCenter));
|
m_DHTItem->setTextAlignment(COL_PEERS, (Qt::AlignRight | Qt::AlignVCenter));
|
||||||
m_PEXItem->setTextAlignment(COL_PEERS, (Qt::AlignRight | Qt::AlignVCenter));
|
m_PEXItem->setTextAlignment(COL_PEERS, (Qt::AlignRight | Qt::AlignVCenter));
|
||||||
m_LSDItem->setTextAlignment(COL_PEERS, (Qt::AlignRight | Qt::AlignVCenter));
|
m_LSDItem->setTextAlignment(COL_PEERS, (Qt::AlignRight | Qt::AlignVCenter));
|
||||||
m_DHTItem->setTextAlignment(COL_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter));
|
m_DHTItem->setTextAlignment(COL_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter));
|
||||||
m_PEXItem->setTextAlignment(COL_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter));
|
m_PEXItem->setTextAlignment(COL_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter));
|
||||||
m_LSDItem->setTextAlignment(COL_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter));
|
m_LSDItem->setTextAlignment(COL_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter));
|
||||||
// Set header alignment
|
// Set header alignment
|
||||||
headerItem()->setTextAlignment(COL_TIER, (Qt::AlignRight | Qt::AlignVCenter));
|
headerItem()->setTextAlignment(COL_TIER, (Qt::AlignRight | Qt::AlignVCenter));
|
||||||
headerItem()->setTextAlignment(COL_RECEIVED, (Qt::AlignRight | Qt::AlignVCenter));
|
headerItem()->setTextAlignment(COL_RECEIVED, (Qt::AlignRight | Qt::AlignVCenter));
|
||||||
headerItem()->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter));
|
headerItem()->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter));
|
||||||
headerItem()->setTextAlignment(COL_PEERS, (Qt::AlignRight | Qt::AlignVCenter));
|
headerItem()->setTextAlignment(COL_PEERS, (Qt::AlignRight | Qt::AlignVCenter));
|
||||||
headerItem()->setTextAlignment(COL_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter));
|
headerItem()->setTextAlignment(COL_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter));
|
||||||
// Set hotkeys
|
// Set hotkeys
|
||||||
m_editHotkey = new QShortcut(Qt::Key_F2, this, SLOT(editSelectedTracker()), 0, Qt::WidgetShortcut);
|
m_editHotkey = new QShortcut(Qt::Key_F2, this, SLOT(editSelectedTracker()), 0, Qt::WidgetShortcut);
|
||||||
connect(this, SIGNAL(doubleClicked(QModelIndex)), SLOT(editSelectedTracker()));
|
connect(this, SIGNAL(doubleClicked(QModelIndex)), SLOT(editSelectedTracker()));
|
||||||
m_deleteHotkey = new QShortcut(QKeySequence::Delete, this, SLOT(deleteSelectedTrackers()), 0, Qt::WidgetShortcut);
|
m_deleteHotkey = new QShortcut(QKeySequence::Delete, this, SLOT(deleteSelectedTrackers()), 0, Qt::WidgetShortcut);
|
||||||
m_copyHotkey = new QShortcut(QKeySequence::Copy, this, SLOT(copyTrackerUrl()), 0, Qt::WidgetShortcut);
|
m_copyHotkey = new QShortcut(QKeySequence::Copy, this, SLOT(copyTrackerUrl()), 0, Qt::WidgetShortcut);
|
||||||
|
|
||||||
// This hack fixes reordering of first column with Qt5.
|
// This hack fixes reordering of first column with Qt5.
|
||||||
// https://github.com/qtproject/qtbase/commit/e0fc088c0c8bc61dbcaf5928b24986cd61a22777
|
// https://github.com/qtproject/qtbase/commit/e0fc088c0c8bc61dbcaf5928b24986cd61a22777
|
||||||
@ -132,99 +130,106 @@ TrackerList::~TrackerList()
|
|||||||
saveSettings();
|
saveSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QTreeWidgetItem*> TrackerList::getSelectedTrackerItems() const {
|
QList<QTreeWidgetItem*> TrackerList::getSelectedTrackerItems() const
|
||||||
const QList<QTreeWidgetItem*> selected_items = selectedItems();
|
{
|
||||||
QList<QTreeWidgetItem*> selected_trackers;
|
const QList<QTreeWidgetItem *> selectedTrackerItems = selectedItems();
|
||||||
foreach (QTreeWidgetItem *item, selected_items) {
|
QList<QTreeWidgetItem *> selectedTrackers;
|
||||||
if (indexOfTopLevelItem(item) >= NB_STICKY_ITEM) { // Ignore STICKY ITEMS
|
foreach (QTreeWidgetItem *item, selectedTrackerItems) {
|
||||||
selected_trackers << item;
|
if (indexOfTopLevelItem(item) >= NB_STICKY_ITEM) // Ignore STICKY ITEMS
|
||||||
|
selectedTrackers << item;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return selected_trackers;
|
return selectedTrackers;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackerList::setRowColor(int row, QColor color) {
|
void TrackerList::setRowColor(int row, QColor color)
|
||||||
unsigned int nbColumns = columnCount();
|
{
|
||||||
QTreeWidgetItem *item = topLevelItem(row);
|
unsigned int nbColumns = columnCount();
|
||||||
for (unsigned int i=0; i<nbColumns; ++i) {
|
QTreeWidgetItem *item = topLevelItem(row);
|
||||||
item->setData(i, Qt::ForegroundRole, color);
|
for (unsigned int i = 0; i < nbColumns; ++i)
|
||||||
}
|
item->setData(i, Qt::ForegroundRole, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackerList::moveSelectionUp() {
|
void TrackerList::moveSelectionUp()
|
||||||
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent();
|
{
|
||||||
if (!torrent) {
|
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent();
|
||||||
clear();
|
if (!torrent) {
|
||||||
return;
|
clear();
|
||||||
}
|
return;
|
||||||
QList<QTreeWidgetItem *> selected_items = getSelectedTrackerItems();
|
|
||||||
if (selected_items.isEmpty()) return;
|
|
||||||
bool change = false;
|
|
||||||
foreach (QTreeWidgetItem *item, selected_items) {
|
|
||||||
int index = indexOfTopLevelItem(item);
|
|
||||||
if (index > NB_STICKY_ITEM) {
|
|
||||||
insertTopLevelItem(index-1, takeTopLevelItem(index));
|
|
||||||
change = true;
|
|
||||||
}
|
}
|
||||||
}
|
QList<QTreeWidgetItem *> selectedTrackerItems = getSelectedTrackerItems();
|
||||||
if (!change) return;
|
if (selectedTrackerItems.isEmpty()) return;
|
||||||
// Restore selection
|
|
||||||
QItemSelectionModel *selection = selectionModel();
|
|
||||||
foreach (QTreeWidgetItem *item, selected_items) {
|
|
||||||
selection->select(indexFromItem(item), QItemSelectionModel::Rows|QItemSelectionModel::Select);
|
|
||||||
}
|
|
||||||
setSelectionModel(selection);
|
|
||||||
// Update torrent trackers
|
|
||||||
QList<BitTorrent::TrackerEntry> trackers;
|
|
||||||
for (int i = NB_STICKY_ITEM; i < topLevelItemCount(); ++i) {
|
|
||||||
QString tracker_url = topLevelItem(i)->data(COL_URL, Qt::DisplayRole).toString();
|
|
||||||
BitTorrent::TrackerEntry e(tracker_url);
|
|
||||||
e.setTier(i - NB_STICKY_ITEM);
|
|
||||||
trackers.append(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
torrent->replaceTrackers(trackers);
|
bool change = false;
|
||||||
// Reannounce
|
foreach (QTreeWidgetItem *item, selectedTrackerItems) {
|
||||||
if (!torrent->isPaused())
|
int index = indexOfTopLevelItem(item);
|
||||||
torrent->forceReannounce();
|
if (index > NB_STICKY_ITEM) {
|
||||||
|
insertTopLevelItem(index - 1, takeTopLevelItem(index));
|
||||||
|
change = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!change) return;
|
||||||
|
|
||||||
|
// Restore selection
|
||||||
|
QItemSelectionModel *selection = selectionModel();
|
||||||
|
foreach (QTreeWidgetItem *item, selectedTrackerItems)
|
||||||
|
selection->select(indexFromItem(item), (QItemSelectionModel::Rows | QItemSelectionModel::Select));
|
||||||
|
|
||||||
|
setSelectionModel(selection);
|
||||||
|
// Update torrent trackers
|
||||||
|
QList<BitTorrent::TrackerEntry> trackers;
|
||||||
|
for (int i = NB_STICKY_ITEM; i < topLevelItemCount(); ++i) {
|
||||||
|
QString trackerURL = topLevelItem(i)->data(COL_URL, Qt::DisplayRole).toString();
|
||||||
|
BitTorrent::TrackerEntry e(trackerURL);
|
||||||
|
e.setTier(i - NB_STICKY_ITEM);
|
||||||
|
trackers.append(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
torrent->replaceTrackers(trackers);
|
||||||
|
// Reannounce
|
||||||
|
if (!torrent->isPaused())
|
||||||
|
torrent->forceReannounce();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackerList::moveSelectionDown() {
|
void TrackerList::moveSelectionDown()
|
||||||
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent();
|
{
|
||||||
if (!torrent) {
|
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent();
|
||||||
clear();
|
if (!torrent) {
|
||||||
return;
|
clear();
|
||||||
}
|
return;
|
||||||
QList<QTreeWidgetItem *> selected_items = getSelectedTrackerItems();
|
|
||||||
if (selected_items.isEmpty()) return;
|
|
||||||
bool change = false;
|
|
||||||
for (int i=selectedItems().size()-1; i>= 0; --i) {
|
|
||||||
int index = indexOfTopLevelItem(selected_items.at(i));
|
|
||||||
if (index < topLevelItemCount()-1) {
|
|
||||||
insertTopLevelItem(index+1, takeTopLevelItem(index));
|
|
||||||
change = true;
|
|
||||||
}
|
}
|
||||||
}
|
QList<QTreeWidgetItem *> selectedTrackerItems = getSelectedTrackerItems();
|
||||||
if (!change) return;
|
if (selectedTrackerItems.isEmpty()) return;
|
||||||
// Restore selection
|
|
||||||
QItemSelectionModel *selection = selectionModel();
|
|
||||||
foreach (QTreeWidgetItem *item, selected_items) {
|
|
||||||
selection->select(indexFromItem(item), QItemSelectionModel::Rows|QItemSelectionModel::Select);
|
|
||||||
}
|
|
||||||
setSelectionModel(selection);
|
|
||||||
// Update torrent trackers
|
|
||||||
QList<BitTorrent::TrackerEntry> trackers;
|
|
||||||
for (int i = NB_STICKY_ITEM; i < topLevelItemCount(); ++i) {
|
|
||||||
QString tracker_url = topLevelItem(i)->data(COL_URL, Qt::DisplayRole).toString();
|
|
||||||
BitTorrent::TrackerEntry e(tracker_url);
|
|
||||||
e.setTier(i - NB_STICKY_ITEM);
|
|
||||||
trackers.append(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
torrent->replaceTrackers(trackers);
|
bool change = false;
|
||||||
// Reannounce
|
for (int i = selectedItems().size() - 1; i >= 0; --i) {
|
||||||
if (!torrent->isPaused())
|
int index = indexOfTopLevelItem(selectedTrackerItems.at(i));
|
||||||
torrent->forceReannounce();
|
if (index < (topLevelItemCount() - 1)) {
|
||||||
|
insertTopLevelItem(index + 1, takeTopLevelItem(index));
|
||||||
|
change = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!change) return;
|
||||||
|
|
||||||
|
// Restore selection
|
||||||
|
QItemSelectionModel *selection = selectionModel();
|
||||||
|
foreach (QTreeWidgetItem *item, selectedTrackerItems)
|
||||||
|
selection->select(indexFromItem(item), (QItemSelectionModel::Rows | QItemSelectionModel::Select));
|
||||||
|
|
||||||
|
setSelectionModel(selection);
|
||||||
|
// Update torrent trackers
|
||||||
|
QList<BitTorrent::TrackerEntry> trackers;
|
||||||
|
for (int i = NB_STICKY_ITEM; i < topLevelItemCount(); ++i) {
|
||||||
|
QString trackerURL = topLevelItem(i)->data(COL_URL, Qt::DisplayRole).toString();
|
||||||
|
BitTorrent::TrackerEntry e(trackerURL);
|
||||||
|
e.setTier(i - NB_STICKY_ITEM);
|
||||||
|
trackers.append(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
torrent->replaceTrackers(trackers);
|
||||||
|
// Reannounce
|
||||||
|
if (!torrent->isPaused())
|
||||||
|
torrent->forceReannounce();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackerList::clear()
|
void TrackerList::clear()
|
||||||
@ -245,34 +250,35 @@ void TrackerList::clear()
|
|||||||
m_LSDItem->setText(COL_MSG, "");
|
m_LSDItem->setText(COL_MSG, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackerList::loadStickyItems(BitTorrent::TorrentHandle *const torrent) {
|
void TrackerList::loadStickyItems(BitTorrent::TorrentHandle *const torrent)
|
||||||
QString working = tr("Working");
|
{
|
||||||
QString disabled = tr("Disabled");
|
QString working = tr("Working");
|
||||||
|
QString disabled = tr("Disabled");
|
||||||
|
|
||||||
// load DHT information
|
// load DHT information
|
||||||
if (BitTorrent::Session::instance()->isDHTEnabled() && !torrent->isPrivate())
|
if (BitTorrent::Session::instance()->isDHTEnabled() && !torrent->isPrivate())
|
||||||
m_DHTItem->setText(COL_STATUS, working);
|
m_DHTItem->setText(COL_STATUS, working);
|
||||||
else
|
else
|
||||||
m_DHTItem->setText(COL_STATUS, disabled);
|
m_DHTItem->setText(COL_STATUS, disabled);
|
||||||
|
|
||||||
// Load PeX Information
|
// Load PeX Information
|
||||||
if (BitTorrent::Session::instance()->isPeXEnabled() && !torrent->isPrivate())
|
if (BitTorrent::Session::instance()->isPeXEnabled() && !torrent->isPrivate())
|
||||||
m_PEXItem->setText(COL_STATUS, working);
|
m_PEXItem->setText(COL_STATUS, working);
|
||||||
else
|
else
|
||||||
m_PEXItem->setText(COL_STATUS, disabled);
|
m_PEXItem->setText(COL_STATUS, disabled);
|
||||||
|
|
||||||
// Load LSD Information
|
// Load LSD Information
|
||||||
if (BitTorrent::Session::instance()->isLSDEnabled() && !torrent->isPrivate())
|
if (BitTorrent::Session::instance()->isLSDEnabled() && !torrent->isPrivate())
|
||||||
m_LSDItem->setText(COL_STATUS, working);
|
m_LSDItem->setText(COL_STATUS, working);
|
||||||
else
|
else
|
||||||
m_LSDItem->setText(COL_STATUS, disabled);
|
m_LSDItem->setText(COL_STATUS, disabled);
|
||||||
|
|
||||||
if (torrent->isPrivate()) {
|
if (torrent->isPrivate()) {
|
||||||
QString privateMsg = tr("This torrent is private");
|
QString privateMsg = tr("This torrent is private");
|
||||||
m_DHTItem->setText(COL_MSG, privateMsg);
|
m_DHTItem->setText(COL_MSG, privateMsg);
|
||||||
m_PEXItem->setText(COL_MSG, privateMsg);
|
m_PEXItem->setText(COL_MSG, privateMsg);
|
||||||
m_LSDItem->setText(COL_MSG, privateMsg);
|
m_LSDItem->setText(COL_MSG, privateMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX: libtorrent should provide this info...
|
// XXX: libtorrent should provide this info...
|
||||||
// Count peers from DHT, PeX, LSD
|
// Count peers from DHT, PeX, LSD
|
||||||
@ -308,252 +314,261 @@ void TrackerList::loadStickyItems(BitTorrent::TorrentHandle *const torrent) {
|
|||||||
m_LSDItem->setText(COL_PEERS, QString::number(peersLSD));
|
m_LSDItem->setText(COL_PEERS, QString::number(peersLSD));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackerList::loadTrackers() {
|
void TrackerList::loadTrackers()
|
||||||
// Load trackers from torrent handle
|
{
|
||||||
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent();
|
// Load trackers from torrent handle
|
||||||
if (!torrent) return;
|
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent();
|
||||||
|
if (!torrent) return;
|
||||||
|
|
||||||
loadStickyItems(torrent);
|
loadStickyItems(torrent);
|
||||||
// Load actual trackers information
|
|
||||||
QHash<QString, BitTorrent::TrackerInfo> trackers_data = torrent->trackerInfos();
|
|
||||||
QStringList old_trackers_urls = m_trackerItems.keys();
|
|
||||||
foreach (const BitTorrent::TrackerEntry &entry, torrent->trackers()) {
|
|
||||||
QString trackerUrl = entry.url();
|
|
||||||
QTreeWidgetItem *item = m_trackerItems.value(trackerUrl, 0);
|
|
||||||
if (!item) {
|
|
||||||
item = new QTreeWidgetItem();
|
|
||||||
item->setText(COL_URL, trackerUrl);
|
|
||||||
addTopLevelItem(item);
|
|
||||||
m_trackerItems[trackerUrl] = item;
|
|
||||||
} else {
|
|
||||||
old_trackers_urls.removeOne(trackerUrl);
|
|
||||||
}
|
|
||||||
item->setText(COL_TIER, QString::number(entry.tier()));
|
|
||||||
BitTorrent::TrackerInfo data = trackers_data.value(trackerUrl);
|
|
||||||
QString error_message = data.lastMessage.trimmed();
|
|
||||||
switch (entry.status()) {
|
|
||||||
case BitTorrent::TrackerEntry::Working:
|
|
||||||
item->setText(COL_STATUS, tr("Working"));
|
|
||||||
item->setText(COL_MSG, "");
|
|
||||||
break;
|
|
||||||
case BitTorrent::TrackerEntry::Updating:
|
|
||||||
item->setText(COL_STATUS, tr("Updating..."));
|
|
||||||
item->setText(COL_MSG, "");
|
|
||||||
break;
|
|
||||||
case BitTorrent::TrackerEntry::NotWorking:
|
|
||||||
item->setText(COL_STATUS, tr("Not working"));
|
|
||||||
item->setText(COL_MSG, error_message);
|
|
||||||
break;
|
|
||||||
case BitTorrent::TrackerEntry::NotContacted:
|
|
||||||
item->setText(COL_STATUS, tr("Not contacted yet"));
|
|
||||||
item->setText(COL_MSG, "");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
item->setText(COL_RECEIVED, QString::number(data.numPeers));
|
|
||||||
|
|
||||||
|
// Load actual trackers information
|
||||||
|
QHash<QString, BitTorrent::TrackerInfo> trackerData = torrent->trackerInfos();
|
||||||
|
QStringList oldTrackerURLs = m_trackerItems.keys();
|
||||||
|
foreach (const BitTorrent::TrackerEntry &entry, torrent->trackers()) {
|
||||||
|
QString trackerURL = entry.url();
|
||||||
|
QTreeWidgetItem *item = m_trackerItems.value(trackerURL, 0);
|
||||||
|
if (!item) {
|
||||||
|
item = new QTreeWidgetItem();
|
||||||
|
item->setText(COL_URL, trackerURL);
|
||||||
|
addTopLevelItem(item);
|
||||||
|
m_trackerItems[trackerURL] = item;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
oldTrackerURLs.removeOne(trackerURL);
|
||||||
|
}
|
||||||
|
item->setText(COL_TIER, QString::number(entry.tier()));
|
||||||
|
BitTorrent::TrackerInfo data = trackerData.value(trackerURL);
|
||||||
|
QString errorMessage = data.lastMessage.trimmed();
|
||||||
|
switch (entry.status()) {
|
||||||
|
case BitTorrent::TrackerEntry::Working:
|
||||||
|
item->setText(COL_STATUS, tr("Working"));
|
||||||
|
item->setText(COL_MSG, "");
|
||||||
|
break;
|
||||||
|
case BitTorrent::TrackerEntry::Updating:
|
||||||
|
item->setText(COL_STATUS, tr("Updating..."));
|
||||||
|
item->setText(COL_MSG, "");
|
||||||
|
break;
|
||||||
|
case BitTorrent::TrackerEntry::NotWorking:
|
||||||
|
item->setText(COL_STATUS, tr("Not working"));
|
||||||
|
item->setText(COL_MSG, errorMessage);
|
||||||
|
break;
|
||||||
|
case BitTorrent::TrackerEntry::NotContacted:
|
||||||
|
item->setText(COL_STATUS, tr("Not contacted yet"));
|
||||||
|
item->setText(COL_MSG, "");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
item->setText(COL_RECEIVED, QString::number(data.numPeers));
|
||||||
#if LIBTORRENT_VERSION_NUM >= 10000
|
#if LIBTORRENT_VERSION_NUM >= 10000
|
||||||
item->setText(COL_SEEDS, QString::number(entry.nativeEntry().scrape_complete > 0 ? entry.nativeEntry().scrape_complete : 0));
|
item->setText(COL_SEEDS, QString::number(entry.nativeEntry().scrape_complete > 0 ? entry.nativeEntry().scrape_complete : 0));
|
||||||
item->setText(COL_PEERS, QString::number(entry.nativeEntry().scrape_incomplete > 0 ? entry.nativeEntry().scrape_incomplete : 0));
|
item->setText(COL_PEERS, QString::number(entry.nativeEntry().scrape_incomplete > 0 ? entry.nativeEntry().scrape_incomplete : 0));
|
||||||
item->setText(COL_DOWNLOADED, QString::number(entry.nativeEntry().scrape_downloaded > 0 ? entry.nativeEntry().scrape_downloaded : 0));
|
item->setText(COL_DOWNLOADED, QString::number(entry.nativeEntry().scrape_downloaded > 0 ? entry.nativeEntry().scrape_downloaded : 0));
|
||||||
#else
|
#else
|
||||||
item->setText(COL_SEEDS, "0");
|
item->setText(COL_SEEDS, "0");
|
||||||
item->setText(COL_PEERS, "0");
|
item->setText(COL_PEERS, "0");
|
||||||
item->setText(COL_DOWNLOADED, "0");
|
item->setText(COL_DOWNLOADED, "0");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
item->setTextAlignment(COL_TIER, (Qt::AlignRight | Qt::AlignVCenter));
|
item->setTextAlignment(COL_TIER, (Qt::AlignRight | Qt::AlignVCenter));
|
||||||
item->setTextAlignment(COL_RECEIVED, (Qt::AlignRight | Qt::AlignVCenter));
|
item->setTextAlignment(COL_RECEIVED, (Qt::AlignRight | Qt::AlignVCenter));
|
||||||
item->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter));
|
item->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter));
|
||||||
item->setTextAlignment(COL_PEERS, (Qt::AlignRight | Qt::AlignVCenter));
|
item->setTextAlignment(COL_PEERS, (Qt::AlignRight | Qt::AlignVCenter));
|
||||||
item->setTextAlignment(COL_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter));
|
item->setTextAlignment(COL_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter));
|
||||||
}
|
}
|
||||||
// Remove old trackers
|
// Remove old trackers
|
||||||
foreach (const QString &tracker, old_trackers_urls) {
|
foreach (const QString &tracker, oldTrackerURLs)
|
||||||
delete m_trackerItems.take(tracker);
|
delete m_trackerItems.take(tracker);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ask the user for new trackers and add them to the torrent
|
// Ask the user for new trackers and add them to the torrent
|
||||||
void TrackerList::askForTrackers() {
|
void TrackerList::askForTrackers()
|
||||||
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent();
|
{
|
||||||
if (!torrent) return;
|
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent();
|
||||||
|
if (!torrent) return;
|
||||||
|
|
||||||
QList<BitTorrent::TrackerEntry> trackers;
|
QList<BitTorrent::TrackerEntry> trackers;
|
||||||
foreach (const QString &tracker, TrackersAdditionDlg::askForTrackers(this, torrent))
|
foreach (const QString &tracker, TrackersAdditionDlg::askForTrackers(this, torrent))
|
||||||
trackers << tracker;
|
trackers << tracker;
|
||||||
torrent->addTrackers(trackers);
|
|
||||||
|
torrent->addTrackers(trackers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackerList::copyTrackerUrl() {
|
void TrackerList::copyTrackerUrl()
|
||||||
QList<QTreeWidgetItem *> selected_items = getSelectedTrackerItems();
|
{
|
||||||
if (selected_items.isEmpty()) return;
|
QList<QTreeWidgetItem *> selectedTrackerItems = getSelectedTrackerItems();
|
||||||
QStringList urls_to_copy;
|
if (selectedTrackerItems.isEmpty()) return;
|
||||||
foreach (QTreeWidgetItem *item, selected_items) {
|
|
||||||
QString tracker_url = item->data(COL_URL, Qt::DisplayRole).toString();
|
QStringList URLsToCopy;
|
||||||
qDebug() << QString("Copy: ") + tracker_url;
|
foreach (QTreeWidgetItem *item, selectedTrackerItems) {
|
||||||
urls_to_copy << tracker_url;
|
QString trackerURL = item->data(COL_URL, Qt::DisplayRole).toString();
|
||||||
|
qDebug() << QString("Copy: ") + trackerURL;
|
||||||
|
URLsToCopy << trackerURL;
|
||||||
}
|
}
|
||||||
QApplication::clipboard()->setText(urls_to_copy.join("\n"));
|
QApplication::clipboard()->setText(URLsToCopy.join("\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TrackerList::deleteSelectedTrackers() {
|
void TrackerList::deleteSelectedTrackers()
|
||||||
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent();
|
{
|
||||||
if (!torrent) {
|
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent();
|
||||||
clear();
|
if (!torrent) {
|
||||||
return;
|
clear();
|
||||||
}
|
return;
|
||||||
|
|
||||||
QList<QTreeWidgetItem *> selected_items = getSelectedTrackerItems();
|
|
||||||
if (selected_items.isEmpty()) return;
|
|
||||||
|
|
||||||
QStringList urls_to_remove;
|
|
||||||
foreach (QTreeWidgetItem *item, selected_items) {
|
|
||||||
QString tracker_url = item->data(COL_URL, Qt::DisplayRole).toString();
|
|
||||||
urls_to_remove << tracker_url;
|
|
||||||
m_trackerItems.remove(tracker_url);
|
|
||||||
delete item;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Iterate of trackers and remove selected ones
|
|
||||||
QList<BitTorrent::TrackerEntry> remaining_trackers;
|
|
||||||
QList<BitTorrent::TrackerEntry> trackers = torrent->trackers();
|
|
||||||
foreach (const BitTorrent::TrackerEntry &entry, trackers) {
|
|
||||||
if (!urls_to_remove.contains(entry.url())) {
|
|
||||||
remaining_trackers.push_back(entry);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
torrent->replaceTrackers(remaining_trackers);
|
QList<QTreeWidgetItem *> selectedTrackerItems = getSelectedTrackerItems();
|
||||||
if (!torrent->isPaused())
|
if (selectedTrackerItems.isEmpty()) return;
|
||||||
torrent->forceReannounce();
|
|
||||||
|
QStringList URLsToRemove;
|
||||||
|
foreach (QTreeWidgetItem *item, selectedTrackerItems) {
|
||||||
|
QString trackerURL = item->data(COL_URL, Qt::DisplayRole).toString();
|
||||||
|
URLsToRemove << trackerURL;
|
||||||
|
m_trackerItems.remove(trackerURL);
|
||||||
|
delete item;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate over the trackers and remove the selected ones
|
||||||
|
QList<BitTorrent::TrackerEntry> remainingTrackers;
|
||||||
|
QList<BitTorrent::TrackerEntry> trackers = torrent->trackers();
|
||||||
|
foreach (const BitTorrent::TrackerEntry &entry, trackers) {
|
||||||
|
if (!URLsToRemove.contains(entry.url()))
|
||||||
|
remainingTrackers.push_back(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
torrent->replaceTrackers(remainingTrackers);
|
||||||
|
if (!torrent->isPaused())
|
||||||
|
torrent->forceReannounce();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackerList::editSelectedTracker() {
|
void TrackerList::editSelectedTracker()
|
||||||
|
{
|
||||||
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent();
|
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent();
|
||||||
if (!torrent) return;
|
if (!torrent) return;
|
||||||
|
|
||||||
QString hash = torrent->hash();
|
QString hash = torrent->hash();
|
||||||
|
|
||||||
QList<QTreeWidgetItem *> selected_items = getSelectedTrackerItems();
|
QList<QTreeWidgetItem *> selectedTrackerItems = getSelectedTrackerItems();
|
||||||
if (selected_items.isEmpty())
|
if (selectedTrackerItems.isEmpty()) return;
|
||||||
return;
|
|
||||||
// During multi-select only process item selected last
|
// During multi-select only process item selected last
|
||||||
QUrl tracker_url = selected_items.last()->text(COL_URL);
|
QUrl trackerURL = selectedTrackerItems.last()->text(COL_URL);
|
||||||
|
|
||||||
bool ok;
|
bool ok;
|
||||||
QUrl new_tracker_url = AutoExpandableDialog::getText(this, tr("Tracker editing"), tr("Tracker URL:"),
|
QUrl newTrackerURL = AutoExpandableDialog::getText(this, tr("Tracker editing"), tr("Tracker URL:"),
|
||||||
QLineEdit::Normal, tracker_url.toString(), &ok).trimmed();
|
QLineEdit::Normal, trackerURL.toString(), &ok).trimmed();
|
||||||
if (!ok)
|
if (!ok) return;
|
||||||
return;
|
|
||||||
|
|
||||||
if (!new_tracker_url.isValid()) {
|
if (!newTrackerURL.isValid()) {
|
||||||
QMessageBox::warning(this, tr("Tracker editing failed"), tr("The tracker URL entered is invalid."));
|
QMessageBox::warning(this, tr("Tracker editing failed"), tr("The tracker URL entered is invalid."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (new_tracker_url == tracker_url)
|
if (newTrackerURL == trackerURL) return;
|
||||||
return;
|
|
||||||
|
|
||||||
QList<BitTorrent::TrackerEntry> trackers = torrent->trackers();
|
QList<BitTorrent::TrackerEntry> trackers = torrent->trackers();
|
||||||
bool match = false;
|
bool match = false;
|
||||||
for (int i = 0; i < trackers.size(); ++i) {
|
for (int i = 0; i < trackers.size(); ++i) {
|
||||||
BitTorrent::TrackerEntry &entry = trackers[i];
|
BitTorrent::TrackerEntry &entry = trackers[i];
|
||||||
if (new_tracker_url == QUrl(entry.url())) {
|
if (newTrackerURL == QUrl(entry.url())) {
|
||||||
QMessageBox::warning(this, tr("Tracker editing failed"), tr("The tracker URL already exists."));
|
QMessageBox::warning(this, tr("Tracker editing failed"), tr("The tracker URL already exists."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tracker_url == QUrl(entry.url()) && !match) {
|
if (trackerURL == QUrl(entry.url()) && !match) {
|
||||||
BitTorrent::TrackerEntry new_entry(new_tracker_url.toString());
|
BitTorrent::TrackerEntry newEntry(newTrackerURL.toString());
|
||||||
new_entry.setTier(entry.tier());
|
newEntry.setTier(entry.tier());
|
||||||
match = true;
|
match = true;
|
||||||
entry = new_entry;
|
entry = newEntry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
torrent->replaceTrackers(trackers);
|
torrent->replaceTrackers(trackers);
|
||||||
if (!torrent->isPaused()) {
|
if (!torrent->isPaused())
|
||||||
torrent->forceReannounce();
|
torrent->forceReannounce();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackerList::reannounceSelected() {
|
void TrackerList::reannounceSelected()
|
||||||
QList<QTreeWidgetItem *> selected_items = selectedItems();
|
{
|
||||||
if (selected_items.isEmpty()) return;
|
QList<QTreeWidgetItem *> selItems = selectedItems();
|
||||||
|
if (selItems.isEmpty()) return;
|
||||||
|
|
||||||
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent();
|
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent();
|
||||||
if (!torrent) return;
|
if (!torrent) return;
|
||||||
|
|
||||||
QList<BitTorrent::TrackerEntry> trackers = torrent->trackers();
|
QList<BitTorrent::TrackerEntry> trackers = torrent->trackers();
|
||||||
|
|
||||||
foreach (QTreeWidgetItem* item, selected_items) {
|
foreach (QTreeWidgetItem* item, selItems) {
|
||||||
// DHT case
|
// DHT case
|
||||||
if (item == m_DHTItem) {
|
if (item == m_DHTItem) {
|
||||||
torrent->forceDHTAnnounce();
|
torrent->forceDHTAnnounce();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trackers case
|
// Trackers case
|
||||||
for (int i = 0; i < trackers.size(); ++i) {
|
for (int i = 0; i < trackers.size(); ++i) {
|
||||||
if (item->text(COL_URL) == trackers[i].url()) {
|
if (item->text(COL_URL) == trackers[i].url()) {
|
||||||
torrent->forceReannounce(i);
|
torrent->forceReannounce(i);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loadTrackers();
|
loadTrackers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackerList::showTrackerListMenu(QPoint) {
|
void TrackerList::showTrackerListMenu(QPoint)
|
||||||
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent();
|
{
|
||||||
if (!torrent) return;
|
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent();
|
||||||
//QList<QTreeWidgetItem*> selected_items = getSelectedTrackerItems();
|
if (!torrent) return;
|
||||||
QMenu menu;
|
|
||||||
// Add actions
|
//QList<QTreeWidgetItem*> selected_items = getSelectedTrackerItems();
|
||||||
QAction *addAct = menu.addAction(GuiIconProvider::instance()->getIcon("list-add"), tr("Add a new tracker..."));
|
QMenu menu;
|
||||||
QAction *copyAct = nullptr;
|
// Add actions
|
||||||
QAction *delAct = nullptr;
|
QAction *addAct = menu.addAction(GuiIconProvider::instance()->getIcon("list-add"), tr("Add a new tracker..."));
|
||||||
QAction *editAct = nullptr;
|
QAction *copyAct = nullptr;
|
||||||
if (!getSelectedTrackerItems().isEmpty()) {
|
QAction *delAct = nullptr;
|
||||||
delAct = menu.addAction(GuiIconProvider::instance()->getIcon("list-remove"), tr("Remove tracker"));
|
QAction *editAct = nullptr;
|
||||||
copyAct = menu.addAction(GuiIconProvider::instance()->getIcon("edit-copy"), tr("Copy tracker URL"));
|
if (!getSelectedTrackerItems().isEmpty()) {
|
||||||
editAct = menu.addAction(GuiIconProvider::instance()->getIcon("edit-rename"),tr("Edit selected tracker URL"));
|
delAct = menu.addAction(GuiIconProvider::instance()->getIcon("list-remove"), tr("Remove tracker"));
|
||||||
}
|
copyAct = menu.addAction(GuiIconProvider::instance()->getIcon("edit-copy"), tr("Copy tracker URL"));
|
||||||
QAction *reannounceSelAct = nullptr;
|
editAct = menu.addAction(GuiIconProvider::instance()->getIcon("edit-rename"),tr("Edit selected tracker URL"));
|
||||||
QAction *reannounceAct = nullptr;
|
}
|
||||||
if (!torrent->isPaused()) {
|
QAction *reannounceSelAct = nullptr;
|
||||||
reannounceSelAct = menu.addAction(GuiIconProvider::instance()->getIcon("view-refresh"), tr("Force reannounce to selected trackers"));
|
QAction *reannounceAllAct = nullptr;
|
||||||
menu.addSeparator();
|
if (!torrent->isPaused()) {
|
||||||
reannounceAct = menu.addAction(GuiIconProvider::instance()->getIcon("view-refresh"), tr("Force reannounce to all trackers"));
|
reannounceSelAct = menu.addAction(GuiIconProvider::instance()->getIcon("view-refresh"), tr("Force reannounce to selected trackers"));
|
||||||
}
|
menu.addSeparator();
|
||||||
QAction *act = menu.exec(QCursor::pos());
|
reannounceAllAct = menu.addAction(GuiIconProvider::instance()->getIcon("view-refresh"), tr("Force reannounce to all trackers"));
|
||||||
if (act == nullptr) return;
|
}
|
||||||
if (act == addAct) {
|
QAction *act = menu.exec(QCursor::pos());
|
||||||
askForTrackers();
|
if (act == nullptr) return;
|
||||||
return;
|
|
||||||
}
|
if (act == addAct) {
|
||||||
if (act == copyAct) {
|
askForTrackers();
|
||||||
copyTrackerUrl();
|
return;
|
||||||
return;
|
}
|
||||||
}
|
if (act == copyAct) {
|
||||||
if (act == delAct) {
|
copyTrackerUrl();
|
||||||
deleteSelectedTrackers();
|
return;
|
||||||
return;
|
}
|
||||||
}
|
if (act == delAct) {
|
||||||
if (act == reannounceSelAct) {
|
deleteSelectedTrackers();
|
||||||
reannounceSelected();
|
return;
|
||||||
return;
|
}
|
||||||
}
|
if (act == reannounceSelAct) {
|
||||||
if (act == reannounceAct) {
|
reannounceSelected();
|
||||||
BitTorrent::TorrentHandle *h = m_properties->getCurrentTorrent();
|
return;
|
||||||
h->forceReannounce();
|
}
|
||||||
h->forceDHTAnnounce();
|
if (act == reannounceAllAct) {
|
||||||
return;
|
BitTorrent::TorrentHandle *h = m_properties->getCurrentTorrent();
|
||||||
}
|
h->forceReannounce();
|
||||||
if (act == editAct) {
|
h->forceDHTAnnounce();
|
||||||
editSelectedTracker();
|
return;
|
||||||
return;
|
}
|
||||||
}
|
if (act == editAct) {
|
||||||
|
editSelectedTracker();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackerList::loadSettings()
|
void TrackerList::loadSettings()
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt4 and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2006 Christophe Dumez
|
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@ -24,8 +24,6 @@
|
|||||||
* modify file(s), you may extend this exception to your version of the file(s),
|
* 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
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*
|
|
||||||
* Contact : chris@qbittorrent.org
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TRACKERLIST_H
|
#ifndef TRACKERLIST_H
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2011 Christophe Dumez
|
* Copyright (C) 2014 sledgehammer999 <hammered999@gmail.com>
|
||||||
* Copyright (C) 2014 sledgehammer999
|
* Copyright (C) 2011 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@ -25,42 +25,38 @@
|
|||||||
* modify file(s), you may extend this exception to your version of the file(s),
|
* 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
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*
|
|
||||||
* Contact : chris@qbittorrent.org
|
|
||||||
* Contact : hammered999@gmail.com
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "shutdownconfirmdlg.h"
|
#include "shutdownconfirmdlg.h"
|
||||||
#include "ui_shutdownconfirmdlg.h"
|
|
||||||
|
|
||||||
#include <QStyle>
|
|
||||||
#include <QIcon>
|
|
||||||
#include <QDialogButtonBox>
|
#include <QDialogButtonBox>
|
||||||
|
#include <QIcon>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
#include <QStyle>
|
||||||
|
|
||||||
#include "base/preferences.h"
|
#include "base/preferences.h"
|
||||||
#include "base/utils/misc.h"
|
#include "base/utils/misc.h"
|
||||||
|
#include "ui_shutdownconfirmdlg.h"
|
||||||
|
|
||||||
ShutdownConfirmDlg::ShutdownConfirmDlg(QWidget *parent, const ShutdownDialogAction &action)
|
ShutdownConfirmDlg::ShutdownConfirmDlg(QWidget *parent, const ShutdownDialogAction &action)
|
||||||
: QDialog(parent)
|
: QDialog(parent)
|
||||||
, ui(new Ui::confirmShutdownDlg)
|
, m_ui(new Ui::confirmShutdownDlg)
|
||||||
, m_timeout(15)
|
, m_timeout(15)
|
||||||
, m_action(action)
|
, m_action(action)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
|
|
||||||
initText();
|
initText();
|
||||||
QIcon warningIcon(style()->standardIcon(QStyle::SP_MessageBoxWarning));
|
QIcon warningIcon(style()->standardIcon(QStyle::SP_MessageBoxWarning));
|
||||||
ui->warningLabel->setPixmap(warningIcon.pixmap(32));
|
m_ui->warningLabel->setPixmap(warningIcon.pixmap(32));
|
||||||
|
|
||||||
if (m_action == ShutdownDialogAction::Exit)
|
if (m_action == ShutdownDialogAction::Exit)
|
||||||
ui->neverShowAgainCheckbox->setVisible(true);
|
m_ui->neverShowAgainCheckbox->setVisible(true);
|
||||||
else
|
else
|
||||||
ui->neverShowAgainCheckbox->setVisible(false);
|
m_ui->neverShowAgainCheckbox->setVisible(false);
|
||||||
|
|
||||||
// Cancel Button
|
// Cancel Button
|
||||||
QPushButton *cancelButton = ui->buttonBox->button(QDialogButtonBox::Cancel);
|
QPushButton *cancelButton = m_ui->buttonBox->button(QDialogButtonBox::Cancel);
|
||||||
cancelButton->setFocus();
|
cancelButton->setFocus();
|
||||||
cancelButton->setDefault(true);
|
cancelButton->setDefault(true);
|
||||||
|
|
||||||
@ -74,7 +70,7 @@ ShutdownConfirmDlg::ShutdownConfirmDlg(QWidget *parent, const ShutdownDialogActi
|
|||||||
|
|
||||||
ShutdownConfirmDlg::~ShutdownConfirmDlg()
|
ShutdownConfirmDlg::~ShutdownConfirmDlg()
|
||||||
{
|
{
|
||||||
delete ui;
|
delete m_ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShutdownConfirmDlg::showEvent(QShowEvent *event)
|
void ShutdownConfirmDlg::showEvent(QShowEvent *event)
|
||||||
@ -101,36 +97,32 @@ void ShutdownConfirmDlg::updateSeconds()
|
|||||||
|
|
||||||
void ShutdownConfirmDlg::accept()
|
void ShutdownConfirmDlg::accept()
|
||||||
{
|
{
|
||||||
Preferences::instance()->setDontConfirmAutoExit(ui->neverShowAgainCheckbox->isChecked());
|
Preferences::instance()->setDontConfirmAutoExit(m_ui->neverShowAgainCheckbox->isChecked());
|
||||||
QDialog::accept();
|
QDialog::accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShutdownConfirmDlg::initText()
|
void ShutdownConfirmDlg::initText()
|
||||||
{
|
{
|
||||||
QPushButton *okButton = ui->buttonBox->button(QDialogButtonBox::Ok);
|
QPushButton *okButton = m_ui->buttonBox->button(QDialogButtonBox::Ok);
|
||||||
|
|
||||||
switch (m_action) {
|
switch (m_action) {
|
||||||
case ShutdownDialogAction::Exit:
|
case ShutdownDialogAction::Exit:
|
||||||
m_msg = tr("qBittorrent will now exit.");
|
m_msg = tr("qBittorrent will now exit.");
|
||||||
|
|
||||||
okButton->setText(tr("E&xit Now"));
|
okButton->setText(tr("E&xit Now"));
|
||||||
setWindowTitle(tr("Exit confirmation"));
|
setWindowTitle(tr("Exit confirmation"));
|
||||||
break;
|
break;
|
||||||
case ShutdownDialogAction::Shutdown:
|
case ShutdownDialogAction::Shutdown:
|
||||||
m_msg = tr("The computer is going to shutdown.");
|
m_msg = tr("The computer is going to shutdown.");
|
||||||
|
|
||||||
okButton->setText(tr("&Shutdown Now"));
|
okButton->setText(tr("&Shutdown Now"));
|
||||||
setWindowTitle(tr("Shutdown confirmation"));
|
setWindowTitle(tr("Shutdown confirmation"));
|
||||||
break;
|
break;
|
||||||
case ShutdownDialogAction::Suspend:
|
case ShutdownDialogAction::Suspend:
|
||||||
m_msg = tr("The computer is going to enter suspend mode.");
|
m_msg = tr("The computer is going to enter suspend mode.");
|
||||||
|
|
||||||
okButton->setText(tr("&Suspend Now"));
|
okButton->setText(tr("&Suspend Now"));
|
||||||
setWindowTitle(tr("Suspend confirmation"));
|
setWindowTitle(tr("Suspend confirmation"));
|
||||||
break;
|
break;
|
||||||
case ShutdownDialogAction::Hibernate:
|
case ShutdownDialogAction::Hibernate:
|
||||||
m_msg = tr("The computer is going to enter hibernation mode.");
|
m_msg = tr("The computer is going to enter hibernation mode.");
|
||||||
|
|
||||||
okButton->setText(tr("&Hibernate Now"));
|
okButton->setText(tr("&Hibernate Now"));
|
||||||
setWindowTitle(tr("Hibernate confirmation"));
|
setWindowTitle(tr("Hibernate confirmation"));
|
||||||
break;
|
break;
|
||||||
@ -143,5 +135,5 @@ void ShutdownConfirmDlg::initText()
|
|||||||
void ShutdownConfirmDlg::updateText()
|
void ShutdownConfirmDlg::updateText()
|
||||||
{
|
{
|
||||||
QString t = tr("You can cancel the action within %1 seconds.").arg(QString::number(m_timeout)) + "\n";
|
QString t = tr("You can cancel the action within %1 seconds.").arg(QString::number(m_timeout)) + "\n";
|
||||||
ui->shutdownText->setText(m_msg + t);
|
m_ui->shutdownText->setText(m_msg + t);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2011 Christophe Dumez
|
* Copyright (C) 2011 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@ -24,8 +24,6 @@
|
|||||||
* modify file(s), you may extend this exception to your version of the file(s),
|
* 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
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*
|
|
||||||
* Contact : chris@qbittorrent.org
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SHUTDOWNCONFIRMDLG_H
|
#ifndef SHUTDOWNCONFIRMDLG_H
|
||||||
@ -33,6 +31,7 @@
|
|||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
#include "base/types.h"
|
#include "base/types.h"
|
||||||
|
|
||||||
namespace Ui
|
namespace Ui
|
||||||
@ -63,7 +62,7 @@ private:
|
|||||||
void updateText();
|
void updateText();
|
||||||
|
|
||||||
// Vars
|
// Vars
|
||||||
Ui::confirmShutdownDlg *ui;
|
Ui::confirmShutdownDlg *m_ui;
|
||||||
QTimer m_timer;
|
QTimer m_timer;
|
||||||
int m_timeout;
|
int m_timeout;
|
||||||
ShutdownDialogAction m_action;
|
ShutdownDialogAction m_action;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt4 and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2006-2012 Christophe Dumez
|
* Copyright (C) 2006-2012 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@ -24,117 +24,122 @@
|
|||||||
* modify file(s), you may extend this exception to your version of the file(s),
|
* 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
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*
|
|
||||||
* Contact : chris@qbittorrent.org
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "base/utils/string.h"
|
|
||||||
#include "torrentcontentfiltermodel.h"
|
#include "torrentcontentfiltermodel.h"
|
||||||
|
|
||||||
|
#include "base/utils/string.h"
|
||||||
#include "torrentcontentmodel.h"
|
#include "torrentcontentmodel.h"
|
||||||
|
|
||||||
TorrentContentFilterModel::TorrentContentFilterModel(QObject *parent):
|
TorrentContentFilterModel::TorrentContentFilterModel(QObject *parent)
|
||||||
QSortFilterProxyModel(parent), m_model(new TorrentContentModel(this))
|
: QSortFilterProxyModel(parent)
|
||||||
|
, m_model(new TorrentContentModel(this))
|
||||||
{
|
{
|
||||||
connect(m_model, SIGNAL(filteredFilesChanged()), this, SIGNAL(filteredFilesChanged()));
|
connect(m_model, SIGNAL(filteredFilesChanged()), this, SIGNAL(filteredFilesChanged()));
|
||||||
setSourceModel(m_model);
|
setSourceModel(m_model);
|
||||||
// Filter settings
|
// Filter settings
|
||||||
setFilterKeyColumn(TorrentContentModelItem::COL_NAME);
|
setFilterKeyColumn(TorrentContentModelItem::COL_NAME);
|
||||||
setFilterRole(Qt::DisplayRole);
|
setFilterRole(Qt::DisplayRole);
|
||||||
setDynamicSortFilter(true);
|
setDynamicSortFilter(true);
|
||||||
setSortCaseSensitivity(Qt::CaseInsensitive);
|
setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
TorrentContentFilterModel::~TorrentContentFilterModel()
|
TorrentContentFilterModel::~TorrentContentFilterModel()
|
||||||
{
|
{
|
||||||
delete m_model;
|
delete m_model;
|
||||||
}
|
}
|
||||||
|
|
||||||
TorrentContentModel* TorrentContentFilterModel::model() const
|
TorrentContentModel *TorrentContentFilterModel::model() const
|
||||||
{
|
{
|
||||||
return m_model;
|
return m_model;
|
||||||
}
|
}
|
||||||
|
|
||||||
TorrentContentModelItem::ItemType TorrentContentFilterModel::itemType(const QModelIndex& index) const
|
TorrentContentModelItem::ItemType TorrentContentFilterModel::itemType(const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
return m_model->itemType(mapToSource(index));
|
return m_model->itemType(mapToSource(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
int TorrentContentFilterModel::getFileIndex(const QModelIndex& index) const
|
int TorrentContentFilterModel::getFileIndex(const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
return m_model->getFileIndex(mapToSource(index));
|
return m_model->getFileIndex(mapToSource(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex TorrentContentFilterModel::parent(const QModelIndex& child) const
|
QModelIndex TorrentContentFilterModel::parent(const QModelIndex &child) const
|
||||||
{
|
{
|
||||||
if (!child.isValid()) return QModelIndex();
|
if (!child.isValid()) return QModelIndex();
|
||||||
QModelIndex sourceParent = m_model->parent(mapToSource(child));
|
|
||||||
if (!sourceParent.isValid()) return QModelIndex();
|
QModelIndex sourceParent = m_model->parent(mapToSource(child));
|
||||||
return mapFromSource(sourceParent);
|
if (!sourceParent.isValid()) return QModelIndex();
|
||||||
|
|
||||||
|
return mapFromSource(sourceParent);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TorrentContentFilterModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
|
bool TorrentContentFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
|
||||||
{
|
{
|
||||||
if (m_model->itemType(m_model->index(source_row, 0, source_parent)) == TorrentContentModelItem::FolderType) {
|
if (m_model->itemType(m_model->index(sourceRow, 0, sourceParent)) == TorrentContentModelItem::FolderType) {
|
||||||
// accept folders if they have at least one filtered item
|
// accept folders if they have at least one filtered item
|
||||||
return hasFiltered(m_model->index(source_row, 0, source_parent));
|
return hasFiltered(m_model->index(sourceRow, 0, sourceParent));
|
||||||
}
|
}
|
||||||
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
|
|
||||||
|
return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TorrentContentFilterModel::lessThan(const QModelIndex &left, const QModelIndex &right) const {
|
bool TorrentContentFilterModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
|
||||||
switch (sortColumn()) {
|
{
|
||||||
case TorrentContentModelItem::COL_NAME: {
|
switch (sortColumn()) {
|
||||||
QString vL = left.data().toString();
|
case TorrentContentModelItem::COL_NAME: {
|
||||||
QString vR = right.data().toString();
|
QString vL = left.data().toString();
|
||||||
TorrentContentModelItem::ItemType leftType = m_model->itemType(m_model->index(left.row(), 0, left.parent()));
|
QString vR = right.data().toString();
|
||||||
TorrentContentModelItem::ItemType rightType = m_model->itemType(m_model->index(right.row(), 0, right.parent()));
|
TorrentContentModelItem::ItemType leftType = m_model->itemType(m_model->index(left.row(), 0, left.parent()));
|
||||||
|
TorrentContentModelItem::ItemType rightType = m_model->itemType(m_model->index(right.row(), 0, right.parent()));
|
||||||
|
|
||||||
if (leftType == rightType)
|
if (leftType == rightType)
|
||||||
return Utils::String::naturalCompareCaseInsensitive(vL, vR);
|
return Utils::String::naturalCompareCaseInsensitive(vL, vR);
|
||||||
else if (leftType == TorrentContentModelItem::FolderType && sortOrder() == Qt::AscendingOrder)
|
else if ((leftType == TorrentContentModelItem::FolderType) && (sortOrder() == Qt::AscendingOrder))
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return QSortFilterProxyModel::lessThan(left, right);
|
return QSortFilterProxyModel::lessThan(left, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentContentFilterModel::selectAll()
|
void TorrentContentFilterModel::selectAll()
|
||||||
{
|
{
|
||||||
for (int i=0; i<rowCount(); ++i) {
|
for (int i = 0; i < rowCount(); ++i)
|
||||||
setData(index(i, 0), Qt::Checked, Qt::CheckStateRole);
|
setData(index(i, 0), Qt::Checked, Qt::CheckStateRole);
|
||||||
}
|
|
||||||
emit dataChanged(index(0,0), index(rowCount(), columnCount()));
|
emit dataChanged(index(0,0), index(rowCount(), columnCount()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentContentFilterModel::selectNone()
|
void TorrentContentFilterModel::selectNone()
|
||||||
{
|
{
|
||||||
for (int i=0; i<rowCount(); ++i) {
|
for (int i = 0; i < rowCount(); ++i)
|
||||||
setData(index(i, 0), Qt::Unchecked, Qt::CheckStateRole);
|
setData(index(i, 0), Qt::Unchecked, Qt::CheckStateRole);
|
||||||
}
|
|
||||||
emit dataChanged(index(0,0), index(rowCount(), columnCount()));
|
emit dataChanged(index(0,0), index(rowCount(), columnCount()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TorrentContentFilterModel::hasFiltered(const QModelIndex& folder) const {
|
bool TorrentContentFilterModel::hasFiltered(const QModelIndex &folder) const
|
||||||
// this should be called only with folders
|
{
|
||||||
// check if the folder name itself matches the filter string
|
// this should be called only with folders
|
||||||
QString name = folder.data().toString();
|
// check if the folder name itself matches the filter string
|
||||||
if (name.contains(filterRegExp()))
|
QString name = folder.data().toString();
|
||||||
return true;
|
|
||||||
for (int child = 0; child < m_model->rowCount(folder); child++) {
|
|
||||||
QModelIndex childIndex = m_model->index(child, 0, folder);
|
|
||||||
if (m_model->hasChildren(childIndex)) {
|
|
||||||
if (hasFiltered(childIndex))
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
name = childIndex.data().toString();
|
|
||||||
if (name.contains(filterRegExp()))
|
if (name.contains(filterRegExp()))
|
||||||
return true;
|
return true;
|
||||||
}
|
for (int child = 0; child < m_model->rowCount(folder); child++) {
|
||||||
|
QModelIndex childIndex = m_model->index(child, 0, folder);
|
||||||
|
if (m_model->hasChildren(childIndex)) {
|
||||||
|
if (hasFiltered(childIndex))
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
name = childIndex.data().toString();
|
||||||
|
if (name.contains(filterRegExp()))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt4 and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2006-2012 Christophe Dumez
|
* Copyright (C) 2006-2012 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@ -24,44 +24,44 @@
|
|||||||
* modify file(s), you may extend this exception to your version of the file(s),
|
* 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
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*
|
|
||||||
* Contact : chris@qbittorrent.org
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TORRENTCONTENTFILTERMODEL_H
|
#ifndef TORRENTCONTENTFILTERMODEL_H
|
||||||
#define TORRENTCONTENTFILTERMODEL_H
|
#define TORRENTCONTENTFILTERMODEL_H
|
||||||
|
|
||||||
#include <QSortFilterProxyModel>
|
#include <QSortFilterProxyModel>
|
||||||
|
|
||||||
#include "torrentcontentmodelitem.h"
|
#include "torrentcontentmodelitem.h"
|
||||||
|
|
||||||
class TorrentContentModel;
|
class TorrentContentModel;
|
||||||
|
|
||||||
class TorrentContentFilterModel: public QSortFilterProxyModel {
|
class TorrentContentFilterModel: public QSortFilterProxyModel
|
||||||
Q_OBJECT
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TorrentContentFilterModel(QObject *parent = 0);
|
TorrentContentFilterModel(QObject *parent = 0);
|
||||||
virtual ~TorrentContentFilterModel();
|
virtual ~TorrentContentFilterModel();
|
||||||
|
|
||||||
TorrentContentModel* model() const;
|
TorrentContentModel *model() const;
|
||||||
TorrentContentModelItem::ItemType itemType(const QModelIndex& index) const;
|
TorrentContentModelItem::ItemType itemType(const QModelIndex &index) const;
|
||||||
int getFileIndex(const QModelIndex& index) const;
|
int getFileIndex(const QModelIndex &index) const;
|
||||||
virtual QModelIndex parent(const QModelIndex& child) const;
|
virtual QModelIndex parent(const QModelIndex &child) const;
|
||||||
|
|
||||||
signals:
|
|
||||||
void filteredFilesChanged();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const;
|
|
||||||
virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void selectAll();
|
void selectAll();
|
||||||
void selectNone();
|
void selectNone();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void filteredFilesChanged();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
|
||||||
|
virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TorrentContentModel* m_model;
|
TorrentContentModel *m_model;
|
||||||
bool hasFiltered(const QModelIndex& folder) const;
|
bool hasFiltered(const QModelIndex &folder) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TORRENTCONTENTFILTERMODEL_H
|
#endif // TORRENTCONTENTFILTERMODEL_H
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt4 and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2014 Ivan Sorokin
|
* Copyright (C) 2014 Ivan Sorokin <vanyacpp@gmail.com>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@ -24,21 +24,19 @@
|
|||||||
* modify file(s), you may extend this exception to your version of the file(s),
|
* 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
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*
|
|
||||||
* Contact : vanyacpp@gmail.com
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "torrentcontenttreeview.h"
|
#include "torrentcontenttreeview.h"
|
||||||
|
|
||||||
|
#include <QHeaderView>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QModelIndexList>
|
#include <QModelIndexList>
|
||||||
#include <QTableView>
|
#include <QTableView>
|
||||||
#include <QHeaderView>
|
|
||||||
|
|
||||||
#include "torrentcontentmodelitem.h"
|
#include "torrentcontentmodelitem.h"
|
||||||
|
|
||||||
TorrentContentTreeView::TorrentContentTreeView(QWidget* parent)
|
TorrentContentTreeView::TorrentContentTreeView(QWidget *parent)
|
||||||
: QTreeView(parent)
|
: QTreeView(parent)
|
||||||
{
|
{
|
||||||
// This hack fixes reordering of first column with Qt5.
|
// This hack fixes reordering of first column with Qt5.
|
||||||
// https://github.com/qtproject/qtbase/commit/e0fc088c0c8bc61dbcaf5928b24986cd61a22777
|
// https://github.com/qtproject/qtbase/commit/e0fc088c0c8bc61dbcaf5928b24986cd61a22777
|
||||||
@ -48,40 +46,42 @@ TorrentContentTreeView::TorrentContentTreeView(QWidget* parent)
|
|||||||
unused.setVerticalHeader(new QHeaderView(Qt::Horizontal));
|
unused.setVerticalHeader(new QHeaderView(Qt::Horizontal));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentContentTreeView::keyPressEvent(QKeyEvent *event) {
|
void TorrentContentTreeView::keyPressEvent(QKeyEvent *event)
|
||||||
if (event->key() != Qt::Key_Space && event->key() != Qt::Key_Select) {
|
{
|
||||||
QTreeView::keyPressEvent(event);
|
if ((event->key() != Qt::Key_Space) && (event->key() != Qt::Key_Select)) {
|
||||||
return;
|
QTreeView::keyPressEvent(event);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
event->accept();
|
event->accept();
|
||||||
|
|
||||||
QModelIndex current = currentNameCell();
|
QModelIndex current = currentNameCell();
|
||||||
|
|
||||||
QVariant value = current.data(Qt::CheckStateRole);
|
QVariant value = current.data(Qt::CheckStateRole);
|
||||||
if (!value.isValid()) {
|
if (!value.isValid()) {
|
||||||
Q_ASSERT(false);
|
Q_ASSERT(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Qt::CheckState state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked
|
Qt::CheckState state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked
|
||||||
? Qt::Unchecked : Qt::Checked);
|
? Qt::Unchecked : Qt::Checked);
|
||||||
|
|
||||||
QModelIndexList selection = selectionModel()->selectedRows(TorrentContentModelItem::COL_NAME);
|
QModelIndexList selection = selectionModel()->selectedRows(TorrentContentModelItem::COL_NAME);
|
||||||
|
|
||||||
for (QModelIndexList::const_iterator i = selection.begin(); i != selection.end(); ++i) {
|
for (QModelIndexList::const_iterator i = selection.begin(); i != selection.end(); ++i) {
|
||||||
QModelIndex index = *i;
|
QModelIndex index = *i;
|
||||||
Q_ASSERT(i->column() == TorrentContentModelItem::COL_NAME);
|
Q_ASSERT(i->column() == TorrentContentModelItem::COL_NAME);
|
||||||
model()->setData(index, state, Qt::CheckStateRole);
|
model()->setData(index, state, Qt::CheckStateRole);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex TorrentContentTreeView::currentNameCell() {
|
QModelIndex TorrentContentTreeView::currentNameCell()
|
||||||
QModelIndex current = currentIndex();
|
{
|
||||||
if (!current.isValid()) {
|
QModelIndex current = currentIndex();
|
||||||
Q_ASSERT(false);
|
if (!current.isValid()) {
|
||||||
return QModelIndex();
|
Q_ASSERT(false);
|
||||||
}
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
|
||||||
return model()->index(current.row(), TorrentContentModelItem::COL_NAME, current.parent());
|
return model()->index(current.row(), TorrentContentModelItem::COL_NAME, current.parent());
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt4 and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2014 Ivan Sorokin
|
* Copyright (C) 2014 Ivan Sorokin <vanyacpp@gmail.com>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@ -24,8 +24,6 @@
|
|||||||
* modify file(s), you may extend this exception to your version of the file(s),
|
* 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
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*
|
|
||||||
* Contact : vanyacpp@gmail.com
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TORRENTCONTENTTREEVIEW_H
|
#ifndef TORRENTCONTENTTREEVIEW_H
|
||||||
@ -33,15 +31,16 @@
|
|||||||
|
|
||||||
#include <QTreeView>
|
#include <QTreeView>
|
||||||
|
|
||||||
class TorrentContentTreeView : public QTreeView {
|
class TorrentContentTreeView: public QTreeView
|
||||||
Q_OBJECT
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit TorrentContentTreeView(QWidget *parent = 0);
|
explicit TorrentContentTreeView(QWidget *parent = 0);
|
||||||
void keyPressEvent(QKeyEvent *event);
|
void keyPressEvent(QKeyEvent *event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QModelIndex currentNameCell();
|
QModelIndex currentNameCell();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif // TORRENTCONTENTTREEVIEW_H
|
||||||
|
Loading…
Reference in New Issue
Block a user