You've already forked qBittorrent
mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-10-09 18:32:15 +02:00
Compare commits
1 Commits
release-1.
...
release-1.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
943e863be0 |
@@ -1,4 +1,4 @@
|
||||
* Thu Sep 3 2009 - Christophe Dumez <chris@qbittorrent.org> - v1.5.0
|
||||
* Unknown - Christophe Dumez <chris@qbittorrent.org> - v1.5.0
|
||||
- FEATURE: Added Magnet URI support
|
||||
- FEATURE: Search engine supports category-based requests
|
||||
- FEATURE: Make use of torrent enclosure in RSS feeds for direct download
|
||||
@@ -12,13 +12,9 @@
|
||||
- FEATURE: If a torrent contains a torrent file, process downloaded torrent file too
|
||||
- FEATURE: A random listening port can be chosen automatically
|
||||
- BUGFIX: torrent resume code rewrited
|
||||
- BUGFIX: Fixed uTorrent spoofing code
|
||||
- BUGFIX: Greatly improved column sorting code
|
||||
- BUGFIX: Possibility to create trackerless torrents
|
||||
- BUGFIX: Better item coloring in torrent content filtering dialog
|
||||
- COSMETIC: Redesigned search tab to improve usability
|
||||
- COSMETIC: Redesigned RSS tab to improve usability
|
||||
- COSMETIC: Improved tracker errors readability
|
||||
|
||||
* Sun Aug 21 2009 - Christophe Dumez <chris@qbittorrent.org> - v1.4.1
|
||||
- BUGFIX: Fix problems when changing save path (if using temporary download folder)
|
||||
|
@@ -77,6 +77,7 @@ FinishedTorrents::FinishedTorrents(QObject *parent, bittorrent *BTSession) : par
|
||||
// Make download list header clickable for sorting
|
||||
finishedList->header()->setClickable(true);
|
||||
finishedList->header()->setSortIndicatorShown(true);
|
||||
connect(finishedList->header(), SIGNAL(sectionPressed(int)), this, SLOT(toggleFinishedListSortOrder(int)));
|
||||
finishedListDelegate = new FinishedListDelegate(finishedList);
|
||||
finishedList->setItemDelegate(finishedListDelegate);
|
||||
connect(finishedList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayFinishedListMenu(const QPoint&)));
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 743 B |
Binary file not shown.
Before Width: | Height: | Size: 659 B |
@@ -1,26 +1,19 @@
|
||||
[Desktop Entry]
|
||||
Categories=Qt;Network;P2P;
|
||||
Categories=Qt;Network;P2P
|
||||
Comment=V1.5.0
|
||||
Exec=qbittorrent %f
|
||||
GenericName=Bittorrent client
|
||||
GenericName[bg]=Торент клиент
|
||||
GenericName[cs]=Bittorrent klient
|
||||
GenericName[de]=Bittorren Client
|
||||
GenericName[el]=Bittorrent πελάτης
|
||||
GenericName[el]=Τορεντ πελάτης
|
||||
GenericName[es]=Cliente Bittorrent
|
||||
GenericName[fi]=Bittorrent-ohjelma
|
||||
GenericName[fr]=Client Bittorrent
|
||||
GenericName[hu]=Bittorrent kliens
|
||||
GenericName[it]=Client Bittorrent
|
||||
GenericName[ja]=Bittorrent クライアント
|
||||
GenericName[ko]=비토렌트 클라이언트
|
||||
GenericName[nl]=Bittorrent-cliënt
|
||||
GenericName[nl]=Bittorrent client
|
||||
GenericName[pl]=Klient Bittorrent
|
||||
GenericName[pt]=Cliente Bittorrent
|
||||
GenericName[pt_BR]=Cliente Bittorrent
|
||||
GenericName[ro]=Client Bittorrent
|
||||
GenericName[ru]=клиент Bittorrent
|
||||
GenericName[sk]=Klient siete Bittorrent
|
||||
GenericName[sv]=Bittorrent-klient
|
||||
GenericName[tr]=Bittorrent istemcisi
|
||||
GenericName[uk]=Bittorrent-клієнт
|
||||
|
@@ -33,7 +33,6 @@
|
||||
#include <QStandardItemModel>
|
||||
#include <QHeaderView>
|
||||
#include <QSettings>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
#include "SearchTab.h"
|
||||
#include "SearchListDelegate.h"
|
||||
@@ -46,63 +45,45 @@
|
||||
#define SEARCH_LEECHERS 3
|
||||
#define SEARCH_ENGINE 4
|
||||
|
||||
SearchTab::SearchTab(SearchEngine *parent) : QWidget(), parent(parent)
|
||||
SearchTab::SearchTab(SearchEngine *parent) : QWidget()
|
||||
{
|
||||
box=new QVBoxLayout();
|
||||
results_lbl=new QLabel();
|
||||
resultsBrowser = new QTreeView();
|
||||
resultsBrowser->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
box->addWidget(results_lbl);
|
||||
box->addWidget(resultsBrowser);
|
||||
|
||||
setLayout(box);
|
||||
// Set Search results list model
|
||||
SearchListModel = new QStandardItemModel(0,6);
|
||||
SearchListModel->setHeaderData(SEARCH_NAME, Qt::Horizontal, tr("Name", "i.e: file name"));
|
||||
SearchListModel->setHeaderData(SEARCH_SIZE, Qt::Horizontal, tr("Size", "i.e: file size"));
|
||||
SearchListModel->setHeaderData(SEARCH_SEEDERS, Qt::Horizontal, tr("Seeders", "i.e: Number of full sources"));
|
||||
SearchListModel->setHeaderData(SEARCH_LEECHERS, Qt::Horizontal, tr("Leechers", "i.e: Number of partial sources"));
|
||||
SearchListModel->setHeaderData(SEARCH_ENGINE, Qt::Horizontal, tr("Search engine"));
|
||||
resultsBrowser->hideColumn(URL_COLUMN); // Hide url column
|
||||
|
||||
proxyModel = new QSortFilterProxyModel();
|
||||
proxyModel->setDynamicSortFilter(true);
|
||||
proxyModel->setSourceModel(SearchListModel);
|
||||
resultsBrowser->setModel(proxyModel);
|
||||
|
||||
SearchDelegate = new SearchListDelegate();
|
||||
resultsBrowser->setItemDelegate(SearchDelegate);
|
||||
|
||||
resultsBrowser->setRootIsDecorated(false);
|
||||
resultsBrowser->setAllColumnsShowFocus(true);
|
||||
resultsBrowser->setSortingEnabled(true);
|
||||
|
||||
// Connect signals to slots (search part)
|
||||
connect(resultsBrowser, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(downloadSelectedItem(const QModelIndex&)));
|
||||
|
||||
// Load last columns width for search results list
|
||||
if(!loadColWidthResultsList()){
|
||||
resultsBrowser->header()->resizeSection(0, 275);
|
||||
}
|
||||
|
||||
// Sort by Seeds
|
||||
resultsBrowser->sortByColumn(SEEDERS, Qt::DescendingOrder);
|
||||
}
|
||||
|
||||
void SearchTab::downloadSelectedItem(const QModelIndex& index) {
|
||||
QString engine_url = proxyModel->data(proxyModel->index(index.row(), ENGINE_URL_COLUMN)).toString();
|
||||
QString torrent_url = proxyModel->data(proxyModel->index(index.row(), URL_COLUMN)).toString();
|
||||
setRowColor(index.row(), "red");
|
||||
parent->downloadTorrent(engine_url, torrent_url);
|
||||
box=new QVBoxLayout();
|
||||
results_lbl=new QLabel();
|
||||
resultsBrowser = new QTreeView();
|
||||
resultsBrowser->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
box->addWidget(results_lbl);
|
||||
box->addWidget(resultsBrowser);
|
||||
|
||||
setLayout(box);
|
||||
// Set Search results list model
|
||||
SearchListModel = new QStandardItemModel(0,6);
|
||||
SearchListModel->setHeaderData(SEARCH_NAME, Qt::Horizontal, tr("Name", "i.e: file name"));
|
||||
SearchListModel->setHeaderData(SEARCH_SIZE, Qt::Horizontal, tr("Size", "i.e: file size"));
|
||||
SearchListModel->setHeaderData(SEARCH_SEEDERS, Qt::Horizontal, tr("Seeders", "i.e: Number of full sources"));
|
||||
SearchListModel->setHeaderData(SEARCH_LEECHERS, Qt::Horizontal, tr("Leechers", "i.e: Number of partial sources"));
|
||||
SearchListModel->setHeaderData(SEARCH_ENGINE, Qt::Horizontal, tr("Search engine"));
|
||||
resultsBrowser->setModel(SearchListModel);
|
||||
resultsBrowser->hideColumn(URL_COLUMN); // Hide url column
|
||||
SearchDelegate = new SearchListDelegate();
|
||||
resultsBrowser->setItemDelegate(SearchDelegate);
|
||||
// Make search list header clickable for sorting
|
||||
resultsBrowser->header()->setClickable(true);
|
||||
resultsBrowser->header()->setSortIndicatorShown(true);
|
||||
|
||||
// Connect signals to slots (search part)
|
||||
connect(resultsBrowser, SIGNAL(doubleClicked(const QModelIndex&)), parent, SLOT(downloadSelectedItem(const QModelIndex&)));
|
||||
connect(resultsBrowser->header(), SIGNAL(sectionPressed(int)), this, SLOT(sortSearchList(int)));
|
||||
|
||||
// Load last columns width for search results list
|
||||
if(!loadColWidthResultsList()){
|
||||
resultsBrowser->header()->resizeSection(0, 275);
|
||||
}
|
||||
}
|
||||
|
||||
SearchTab::~SearchTab() {
|
||||
delete box;
|
||||
delete results_lbl;
|
||||
delete resultsBrowser;
|
||||
delete SearchListModel;
|
||||
delete proxyModel;
|
||||
delete SearchDelegate;
|
||||
delete resultsBrowser;
|
||||
delete SearchListModel;
|
||||
delete SearchDelegate;
|
||||
}
|
||||
|
||||
QHeaderView* SearchTab::header() const {
|
||||
@@ -119,31 +100,87 @@ bool SearchTab::loadColWidthResultsList() {
|
||||
return false;
|
||||
unsigned int listSize = width_list.size();
|
||||
for(unsigned int i=0; i<listSize; ++i){
|
||||
resultsBrowser->header()->resizeSection(i, width_list.at(i).toInt());
|
||||
resultsBrowser->header()->resizeSection(i, width_list.at(i).toInt());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QLabel* SearchTab::getCurrentLabel()
|
||||
{
|
||||
return results_lbl;
|
||||
return results_lbl;
|
||||
}
|
||||
|
||||
QTreeView* SearchTab::getCurrentTreeView()
|
||||
{
|
||||
return resultsBrowser;
|
||||
return resultsBrowser;
|
||||
}
|
||||
|
||||
QStandardItemModel* SearchTab::getCurrentSearchListModel()
|
||||
{
|
||||
return SearchListModel;
|
||||
return SearchListModel;
|
||||
}
|
||||
|
||||
// Set the color of a row in data model
|
||||
void SearchTab::setRowColor(int row, QString color){
|
||||
for(int i=0; i<proxyModel->columnCount(); ++i){
|
||||
proxyModel->setData(proxyModel->index(row, i), QVariant(QColor(color)), Qt::ForegroundRole);
|
||||
for(int i=0; i<SearchListModel->columnCount(); ++i){
|
||||
SearchListModel->setData(SearchListModel->index(row, i), QVariant(QColor(color)), Qt::ForegroundRole);
|
||||
}
|
||||
}
|
||||
|
||||
void SearchTab::sortSearchList(int index){
|
||||
static Qt::SortOrder sortOrder = Qt::AscendingOrder;
|
||||
if(resultsBrowser->header()->sortIndicatorSection() == index){
|
||||
sortOrder = (sortOrder == Qt::DescendingOrder) ? Qt::AscendingOrder : Qt::DescendingOrder; ;
|
||||
}
|
||||
resultsBrowser->header()->setSortIndicator(index, sortOrder);
|
||||
switch(index){
|
||||
case SEEDERS:
|
||||
case LEECHERS:
|
||||
case SIZE:
|
||||
sortSearchListInt(index, sortOrder);
|
||||
break;
|
||||
default:
|
||||
sortSearchListString(index, sortOrder);
|
||||
}
|
||||
}
|
||||
|
||||
void SearchTab::sortSearchListInt(int index, Qt::SortOrder sortOrder){
|
||||
QList<QPair<int, qlonglong> > lines;
|
||||
// Insertion sorting
|
||||
for(int i=0; i<SearchListModel->rowCount(); ++i){
|
||||
misc::insertSort(lines, QPair<int,qlonglong>(i, SearchListModel->data(SearchListModel->index(i, index)).toLongLong()), sortOrder);
|
||||
}
|
||||
// Insert items in new model, in correct order
|
||||
int nbRows_old = lines.size();
|
||||
for(int row=0; row<lines.size(); ++row){
|
||||
SearchListModel->insertRow(SearchListModel->rowCount());
|
||||
int sourceRow = lines[row].first;
|
||||
for(int col=0; col<6; ++col){
|
||||
SearchListModel->setData(SearchListModel->index(nbRows_old+row, col), SearchListModel->data(SearchListModel->index(sourceRow, col)));
|
||||
SearchListModel->setData(SearchListModel->index(nbRows_old+row, col), SearchListModel->data(SearchListModel->index(sourceRow, col), Qt::ForegroundRole), Qt::ForegroundRole);
|
||||
}
|
||||
}
|
||||
// Remove old rows
|
||||
SearchListModel->removeRows(0, nbRows_old);
|
||||
}
|
||||
|
||||
void SearchTab::sortSearchListString(int index, Qt::SortOrder sortOrder){
|
||||
QList<QPair<int, QString> > lines;
|
||||
// Insetion sorting
|
||||
for(int i=0; i<SearchListModel->rowCount(); ++i){
|
||||
misc::insertSortString(lines, QPair<int, QString>(i, SearchListModel->data(SearchListModel->index(i, index)).toString()), sortOrder);
|
||||
}
|
||||
// Insert items in new model, in correct order
|
||||
int nbRows_old = lines.size();
|
||||
for(int row=0; row<nbRows_old; ++row){
|
||||
SearchListModel->insertRow(SearchListModel->rowCount());
|
||||
int sourceRow = lines[row].first;
|
||||
for(int col=0; col<6; ++col){
|
||||
SearchListModel->setData(SearchListModel->index(nbRows_old+row, col), SearchListModel->data(SearchListModel->index(sourceRow, col)));
|
||||
SearchListModel->setData(SearchListModel->index(nbRows_old+row, col), SearchListModel->data(SearchListModel->index(sourceRow, col), Qt::ForegroundRole), Qt::ForegroundRole);
|
||||
}
|
||||
}
|
||||
// Remove old rows
|
||||
SearchListModel->removeRows(0, nbRows_old);
|
||||
}
|
||||
|
||||
|
@@ -41,34 +41,32 @@ class SearchEngine;
|
||||
class QTreeView;
|
||||
class QHeaderView;
|
||||
class QStandardItemModel;
|
||||
class QSortFilterProxyModel;
|
||||
|
||||
class SearchTab: public QWidget, public Ui::search_engine {
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
QVBoxLayout *box;
|
||||
QLabel *results_lbl;
|
||||
QTreeView *resultsBrowser;
|
||||
QStandardItemModel *SearchListModel;
|
||||
QSortFilterProxyModel *proxyModel;
|
||||
SearchListDelegate *SearchDelegate;
|
||||
SearchEngine *parent;
|
||||
|
||||
protected slots:
|
||||
void downloadSelectedItem(const QModelIndex& index);
|
||||
|
||||
public:
|
||||
SearchTab(SearchEngine *parent);
|
||||
~SearchTab();
|
||||
bool loadColWidthResultsList();
|
||||
QLabel * getCurrentLabel();
|
||||
QStandardItemModel * getCurrentSearchListModel();
|
||||
QTreeView * getCurrentTreeView();
|
||||
void setRowColor(int row, QString color);
|
||||
QHeaderView* header() const;
|
||||
|
||||
class SearchTab : public QWidget, public Ui::search_engine
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
QVBoxLayout *box;
|
||||
QLabel *results_lbl;
|
||||
QTreeView *resultsBrowser;
|
||||
QStandardItemModel *SearchListModel;
|
||||
SearchListDelegate *SearchDelegate;
|
||||
public:
|
||||
SearchTab(SearchEngine *parent);
|
||||
~SearchTab();
|
||||
bool loadColWidthResultsList();
|
||||
QLabel * getCurrentLabel();
|
||||
QStandardItemModel * getCurrentSearchListModel();
|
||||
QTreeView * getCurrentTreeView();
|
||||
void setRowColor(int row, QString color);
|
||||
QHeaderView* header() const;
|
||||
|
||||
protected slots:
|
||||
void sortSearchList(int index);
|
||||
void sortSearchListInt(int index, Qt::SortOrder sortOrder);
|
||||
void sortSearchListString(int index, Qt::SortOrder sortOrder);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -114,9 +114,6 @@ class bittorrent : public QObject {
|
||||
public slots:
|
||||
QTorrentHandle addTorrent(QString path, bool fromScanDir = false, QString from_url = QString(), bool resumed = false);
|
||||
QTorrentHandle addMagnetUri(QString magnet_uri, bool resumed=false);
|
||||
void importOldTorrents();
|
||||
void applyFormerAttributeFiles(QTorrentHandle h);
|
||||
void importOldTempData(QString torrent_path);
|
||||
void loadSessionState();
|
||||
void saveSessionState();
|
||||
void downloadFromUrl(QString url);
|
||||
@@ -136,6 +133,7 @@ class bittorrent : public QObject {
|
||||
void enableIPFilter(QString filter);
|
||||
void disableIPFilter();
|
||||
void setQueueingEnabled(bool enable);
|
||||
void saveTorrentSpeedLimits(QString hash);
|
||||
void loadTorrentSpeedLimits(QString hash);
|
||||
void handleDownloadFailure(QString url, QString reason);
|
||||
void loadWebSeeds(QString fileHash);
|
||||
|
@@ -166,10 +166,10 @@ void createtorrent::on_createButton_clicked(){
|
||||
return;
|
||||
}
|
||||
QStringList trackers = allItems(trackers_list);
|
||||
/*if(!trackers.size()){
|
||||
if(!trackers.size()){
|
||||
QMessageBox::critical(0, tr("No tracker path set"), tr("Please set at least one tracker"));
|
||||
return;
|
||||
}*/
|
||||
}
|
||||
QString destination = QFileDialog::getSaveFileName(this, tr("Select destination torrent file"), QDir::homePath(), tr("Torrent Files")+QString::fromUtf8(" (*.torrent)"));
|
||||
if(!destination.isEmpty()) {
|
||||
if(!destination.endsWith(QString::fromUtf8(".torrent")))
|
||||
|
@@ -141,7 +141,6 @@ void subDownloadThread::run(){
|
||||
qDebug("Downloading %s", url.toLocal8Bit().data());
|
||||
if(!abort)
|
||||
res = curl_easy_perform(curl);
|
||||
qDebug("done downloading %s", url.toLocal8Bit().data());
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
fclose(f);
|
||||
@@ -152,7 +151,6 @@ void subDownloadThread::run(){
|
||||
} else {
|
||||
emit downloadFinishedST(this, url, filePath);
|
||||
}
|
||||
qDebug("%s Raised the signal", url.toLocal8Bit().data());
|
||||
} else {
|
||||
std::cerr << "Could not initialize CURL" << "\n";
|
||||
}
|
||||
@@ -215,7 +213,6 @@ void downloadThread::propagateDownloadedFile(subDownloadThread* st, QString url,
|
||||
Q_ASSERT(index != -1);
|
||||
subThreads.removeAt(index);
|
||||
mutex.unlock();
|
||||
qDebug("Deleting subthread");
|
||||
delete st;
|
||||
emit downloadFinished(url, path);
|
||||
mutex.lock();
|
||||
@@ -223,7 +220,6 @@ void downloadThread::propagateDownloadedFile(subDownloadThread* st, QString url,
|
||||
condition.wakeOne();
|
||||
}
|
||||
mutex.unlock();
|
||||
qDebug("Out of propagateDownloadedFile");
|
||||
}
|
||||
|
||||
void downloadThread::propagateDownloadFailure(subDownloadThread* st, QString url, QString reason){
|
||||
|
@@ -85,7 +85,6 @@
|
||||
<file>Icons/oxygen/encrypted.png</file>
|
||||
<file>Icons/oxygen/edit_clear.png</file>
|
||||
<file>Icons/oxygen/download.png</file>
|
||||
<file>Icons/oxygen/application-x-kgetlist-no.png</file>
|
||||
<file>Icons/oxygen/gear.png</file>
|
||||
<file>Icons/oxygen/remove.png</file>
|
||||
<file>Icons/oxygen/browse.png</file>
|
||||
@@ -102,7 +101,6 @@
|
||||
<file>Icons/oxygen/connection.png</file>
|
||||
<file>Icons/oxygen/bug.png</file>
|
||||
<file>Icons/oxygen/list-add.png</file>
|
||||
<file>Icons/oxygen/application-x-kgetlist.png</file>
|
||||
<file>Icons/oxygen/folder.png</file>
|
||||
<file>Icons/oxygen/edit-cut.png</file>
|
||||
<file>Icons/oxygen/unsubscribe.png</file>
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user