mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-03-10 20:31:47 +00:00
- Rewrote Column sorting code in search result lists
This commit is contained in:
parent
1d9b524b77
commit
4fe22dbc57
@ -33,6 +33,7 @@
|
|||||||
#include <QStandardItemModel>
|
#include <QStandardItemModel>
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
|
||||||
#include "SearchTab.h"
|
#include "SearchTab.h"
|
||||||
#include "SearchListDelegate.h"
|
#include "SearchListDelegate.h"
|
||||||
@ -45,45 +46,60 @@
|
|||||||
#define SEARCH_LEECHERS 3
|
#define SEARCH_LEECHERS 3
|
||||||
#define SEARCH_ENGINE 4
|
#define SEARCH_ENGINE 4
|
||||||
|
|
||||||
SearchTab::SearchTab(SearchEngine *parent) : QWidget()
|
SearchTab::SearchTab(SearchEngine *parent) : QWidget(), parent(parent)
|
||||||
{
|
{
|
||||||
box=new QVBoxLayout();
|
box=new QVBoxLayout();
|
||||||
results_lbl=new QLabel();
|
results_lbl=new QLabel();
|
||||||
resultsBrowser = new QTreeView();
|
resultsBrowser = new QTreeView();
|
||||||
resultsBrowser->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
resultsBrowser->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||||
box->addWidget(results_lbl);
|
box->addWidget(results_lbl);
|
||||||
box->addWidget(resultsBrowser);
|
box->addWidget(resultsBrowser);
|
||||||
|
|
||||||
setLayout(box);
|
setLayout(box);
|
||||||
// Set Search results list model
|
// Set Search results list model
|
||||||
SearchListModel = new QStandardItemModel(0,6);
|
SearchListModel = new QStandardItemModel(0,6);
|
||||||
SearchListModel->setHeaderData(SEARCH_NAME, Qt::Horizontal, tr("Name", "i.e: file name"));
|
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_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_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_LEECHERS, Qt::Horizontal, tr("Leechers", "i.e: Number of partial sources"));
|
||||||
SearchListModel->setHeaderData(SEARCH_ENGINE, Qt::Horizontal, tr("Search engine"));
|
SearchListModel->setHeaderData(SEARCH_ENGINE, Qt::Horizontal, tr("Search engine"));
|
||||||
resultsBrowser->setModel(SearchListModel);
|
resultsBrowser->hideColumn(URL_COLUMN); // Hide url column
|
||||||
resultsBrowser->hideColumn(URL_COLUMN); // Hide url column
|
|
||||||
SearchDelegate = new SearchListDelegate();
|
proxyModel = new QSortFilterProxyModel();
|
||||||
resultsBrowser->setItemDelegate(SearchDelegate);
|
proxyModel->setDynamicSortFilter(true);
|
||||||
// Make search list header clickable for sorting
|
proxyModel->setSourceModel(SearchListModel);
|
||||||
resultsBrowser->header()->setClickable(true);
|
resultsBrowser->setModel(proxyModel);
|
||||||
resultsBrowser->header()->setSortIndicatorShown(true);
|
|
||||||
|
SearchDelegate = new SearchListDelegate();
|
||||||
// Connect signals to slots (search part)
|
resultsBrowser->setItemDelegate(SearchDelegate);
|
||||||
connect(resultsBrowser, SIGNAL(doubleClicked(const QModelIndex&)), parent, SLOT(downloadSelectedItem(const QModelIndex&)));
|
|
||||||
connect(resultsBrowser->header(), SIGNAL(sectionPressed(int)), this, SLOT(sortSearchList(int)));
|
resultsBrowser->setRootIsDecorated(false);
|
||||||
|
resultsBrowser->setAllColumnsShowFocus(true);
|
||||||
// Load last columns width for search results list
|
resultsBrowser->setSortingEnabled(true);
|
||||||
if(!loadColWidthResultsList()){
|
|
||||||
resultsBrowser->header()->resizeSection(0, 275);
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
SearchTab::~SearchTab() {
|
SearchTab::~SearchTab() {
|
||||||
delete resultsBrowser;
|
delete box;
|
||||||
delete SearchListModel;
|
delete results_lbl;
|
||||||
delete SearchDelegate;
|
delete resultsBrowser;
|
||||||
|
delete SearchListModel;
|
||||||
|
delete proxyModel;
|
||||||
|
delete SearchDelegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
QHeaderView* SearchTab::header() const {
|
QHeaderView* SearchTab::header() const {
|
||||||
@ -100,87 +116,31 @@ bool SearchTab::loadColWidthResultsList() {
|
|||||||
return false;
|
return false;
|
||||||
unsigned int listSize = width_list.size();
|
unsigned int listSize = width_list.size();
|
||||||
for(unsigned int i=0; i<listSize; ++i){
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QLabel* SearchTab::getCurrentLabel()
|
QLabel* SearchTab::getCurrentLabel()
|
||||||
{
|
{
|
||||||
return results_lbl;
|
return results_lbl;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTreeView* SearchTab::getCurrentTreeView()
|
QTreeView* SearchTab::getCurrentTreeView()
|
||||||
{
|
{
|
||||||
return resultsBrowser;
|
return resultsBrowser;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStandardItemModel* SearchTab::getCurrentSearchListModel()
|
QStandardItemModel* SearchTab::getCurrentSearchListModel()
|
||||||
{
|
{
|
||||||
return SearchListModel;
|
return SearchListModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the color of a row in data model
|
// Set the color of a row in data model
|
||||||
void SearchTab::setRowColor(int row, QString color){
|
void SearchTab::setRowColor(int row, QString color){
|
||||||
for(int i=0; i<SearchListModel->columnCount(); ++i){
|
for(int i=0; i<proxyModel->columnCount(); ++i){
|
||||||
SearchListModel->setData(SearchListModel->index(row, i), QVariant(QColor(color)), Qt::ForegroundRole);
|
proxyModel->setData(proxyModel->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,32 +41,34 @@ class SearchEngine;
|
|||||||
class QTreeView;
|
class QTreeView;
|
||||||
class QHeaderView;
|
class QHeaderView;
|
||||||
class QStandardItemModel;
|
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
|
#endif
|
||||||
|
@ -311,19 +311,6 @@ void SearchEngine::searchStarted(){
|
|||||||
search_button->setText("Stop");
|
search_button->setText("Stop");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Download the given item from search results list
|
|
||||||
void SearchEngine::downloadSelectedItem(const QModelIndex& index){
|
|
||||||
int row = index.row();
|
|
||||||
// Get Item url
|
|
||||||
QStandardItemModel *model = all_tab.at(tabWidget->currentIndex())->getCurrentSearchListModel();
|
|
||||||
QString engine_url = model->data(model->index(index.row(), ENGINE_URL_COLUMN)).toString();
|
|
||||||
QString torrent_url = model->data(model->index(index.row(), URL_COLUMN)).toString();
|
|
||||||
// Download from url
|
|
||||||
downloadTorrent(engine_url, torrent_url);
|
|
||||||
// Set item color to RED
|
|
||||||
all_tab.at(tabWidget->currentIndex())->setRowColor(row, "red");
|
|
||||||
}
|
|
||||||
|
|
||||||
// search Qprocess return output as soon as it gets new
|
// search Qprocess return output as soon as it gets new
|
||||||
// stuff to read. We split it into lines and add each
|
// stuff to read. We split it into lines and add each
|
||||||
// line to search results calling appendSearchResult().
|
// line to search results calling appendSearchResult().
|
||||||
@ -475,19 +462,30 @@ void SearchEngine::appendSearchResult(QString line){
|
|||||||
if(parts.size() != 6){
|
if(parts.size() != 6){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QString url = parts.takeFirst().trimmed();
|
|
||||||
QString filename = parts.first().trimmed();
|
|
||||||
parts << url;
|
|
||||||
// Add item to search result list
|
// Add item to search result list
|
||||||
int row = currentSearchTab->getCurrentSearchListModel()->rowCount();
|
QStandardItemModel *cur_model = currentSearchTab->getCurrentSearchListModel();
|
||||||
currentSearchTab->getCurrentSearchListModel()->insertRow(row);
|
int row = cur_model->rowCount();
|
||||||
for(int i=0; i<6; ++i){
|
cur_model->insertRow(row);
|
||||||
if(parts.at(i).trimmed().toFloat() == -1 && i != SIZE)
|
|
||||||
currentSearchTab->getCurrentSearchListModel()->setData(currentSearchTab->getCurrentSearchListModel()->index(row, i), tr("Unknown"));
|
cur_model->setData(cur_model->index(row, 5), parts.at(0).trimmed()); // download URL
|
||||||
else
|
cur_model->setData(cur_model->index(row, 0), parts.at(1).trimmed()); // Name
|
||||||
currentSearchTab->getCurrentSearchListModel()->setData(currentSearchTab->getCurrentSearchListModel()->index(row, i), QVariant(parts.at(i).trimmed()));
|
cur_model->setData(cur_model->index(row, 1), parts.at(2).trimmed().toLongLong()); // Size
|
||||||
|
bool ok = false;
|
||||||
|
qlonglong nb_seeders = parts.at(3).trimmed().toLongLong(&ok);
|
||||||
|
if(!ok || nb_seeders < 0) {
|
||||||
|
cur_model->setData(cur_model->index(row, 2), tr("Unknown")); // Seeders
|
||||||
|
} else {
|
||||||
|
cur_model->setData(cur_model->index(row, 2), nb_seeders); // Seeders
|
||||||
}
|
}
|
||||||
// Add url to searchResultsUrls associative array
|
qlonglong nb_leechers = parts.at(4).trimmed().toLongLong(&ok);
|
||||||
|
if(!ok || nb_leechers < 0) {
|
||||||
|
cur_model->setData(cur_model->index(row, 3), tr("Unknown")); // Leechers
|
||||||
|
} else {
|
||||||
|
cur_model->setData(cur_model->index(row, 3), nb_leechers); // Leechers
|
||||||
|
}
|
||||||
|
cur_model->setData(cur_model->index(row, 4), parts.at(5).trimmed()); // Engine URL
|
||||||
|
|
||||||
no_search_results = false;
|
no_search_results = false;
|
||||||
++nb_search_results;
|
++nb_search_results;
|
||||||
// Enable clear & download buttons
|
// Enable clear & download buttons
|
||||||
|
@ -78,7 +78,7 @@ public:
|
|||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void on_download_button_clicked();
|
void on_download_button_clicked();
|
||||||
void downloadSelectedItem(const QModelIndex& index);
|
void downloadTorrent(QString engine_url, QString torrent_url);
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
// Search slots
|
// Search slots
|
||||||
@ -96,7 +96,6 @@ protected slots:
|
|||||||
void propagateSectionResized(int index, int oldsize , int newsize);
|
void propagateSectionResized(int index, int oldsize , int newsize);
|
||||||
void saveResultsColumnsWidth();
|
void saveResultsColumnsWidth();
|
||||||
void downloadFinished(int exitcode, QProcess::ExitStatus);
|
void downloadFinished(int exitcode, QProcess::ExitStatus);
|
||||||
void downloadTorrent(QString engine_url, QString torrent_url);
|
|
||||||
void displayPatternContextMenu(QPoint);
|
void displayPatternContextMenu(QPoint);
|
||||||
void createCompleter();
|
void createCompleter();
|
||||||
void fillCatCombobox();
|
void fillCatCombobox();
|
||||||
|
@ -14,7 +14,7 @@ CONFIG += qt \
|
|||||||
network
|
network
|
||||||
|
|
||||||
# Update this VERSION for each release
|
# Update this VERSION for each release
|
||||||
DEFINES += VERSION=\\\"v1.5.0rc2\\\"
|
DEFINES += VERSION=\\\"v1.5.0rc3\\\"
|
||||||
DEFINES += VERSION_MAJOR=1
|
DEFINES += VERSION_MAJOR=1
|
||||||
DEFINES += VERSION_MINOR=5
|
DEFINES += VERSION_MINOR=5
|
||||||
DEFINES += VERSION_BUGFIX=0
|
DEFINES += VERSION_BUGFIX=0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user