Browse Source

- Rewrote Column sorting code in search result lists

adaptive-webui-19844
Christophe Dumez 15 years ago
parent
commit
4fe22dbc57
  1. 154
      src/SearchTab.cpp
  2. 46
      src/SearchTab.h
  3. 46
      src/searchEngine.cpp
  4. 3
      src/searchEngine.h
  5. 2
      src/src.pro

154
src/SearchTab.cpp

@ -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);
}

46
src/SearchTab.h

@ -41,31 +41,33 @@ class SearchEngine;
class QTreeView; class QTreeView;
class QHeaderView; class QHeaderView;
class QStandardItemModel; class QStandardItemModel;
class QSortFilterProxyModel;
class SearchTab : public QWidget, public Ui::search_engine class SearchTab: public QWidget, public Ui::search_engine {
{ Q_OBJECT
Q_OBJECT
private: private:
QVBoxLayout *box; QVBoxLayout *box;
QLabel *results_lbl; QLabel *results_lbl;
QTreeView *resultsBrowser; QTreeView *resultsBrowser;
QStandardItemModel *SearchListModel; QStandardItemModel *SearchListModel;
SearchListDelegate *SearchDelegate; QSortFilterProxyModel *proxyModel;
public: SearchListDelegate *SearchDelegate;
SearchTab(SearchEngine *parent); SearchEngine *parent;
~SearchTab();
bool loadColWidthResultsList(); protected slots:
QLabel * getCurrentLabel(); void downloadSelectedItem(const QModelIndex& index);
QStandardItemModel * getCurrentSearchListModel();
QTreeView * getCurrentTreeView(); public:
void setRowColor(int row, QString color); SearchTab(SearchEngine *parent);
QHeaderView* header() const; ~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);
}; };

46
src/searchEngine.cpp

@ -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
}
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
} }
// Add url to searchResultsUrls associative array 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

3
src/searchEngine.h

@ -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();

2
src/src.pro

@ -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…
Cancel
Save