Browse Source

Merge pull request #5420 from thalieht/alignment

Changes and additions in search, peerlist, transferlist
adaptive-webui-19844
sledgehammer999 8 years ago committed by GitHub
parent
commit
68ecbf4185
  1. 16
      src/base/preferences.cpp
  2. 4
      src/base/preferences.h
  3. 52
      src/gui/properties/peerlistdelegate.h
  4. 8
      src/gui/properties/peerlistwidget.cpp
  5. 3
      src/gui/search/searchlistdelegate.cpp
  6. 97
      src/gui/search/searchtab.cpp
  7. 4
      src/gui/search/searchtab.h
  8. 16
      src/gui/search/searchwidget.cpp
  9. 1
      src/gui/search/searchwidget.h
  10. 2
      src/gui/transferlistwidget.cpp

16
src/base/preferences.cpp

@ -1321,14 +1321,22 @@ void Preferences::setRssMainSplitterState(const QByteArray &state)
#endif #endif
} }
QString Preferences::getSearchColsWidth() const QByteArray Preferences::getSearchTabHeaderState() const
{ {
return value("SearchResultsColsWidth").toString(); #ifdef QBT_USES_QT5
return value("SearchTab/qt5/SearchTabHeaderState").toByteArray();
#else
return value("SearchTab/SearchTabHeaderState").toByteArray();
#endif
} }
void Preferences::setSearchColsWidth(const QString &width) void Preferences::setSearchTabHeaderState(const QByteArray &state)
{ {
setValue("SearchResultsColsWidth", width); #ifdef QBT_USES_QT5
setValue("SearchTab/qt5/SearchTabHeaderState", state);
#else
setValue("SearchTab/SearchTabHeaderState", state);
#endif
} }
QStringList Preferences::getSearchEngDisabled() const QStringList Preferences::getSearchEngDisabled() const

4
src/base/preferences.h

@ -304,8 +304,8 @@ public:
void setRssSideSplitterState(const QByteArray &state); void setRssSideSplitterState(const QByteArray &state);
QByteArray getRssMainSplitterState() const; QByteArray getRssMainSplitterState() const;
void setRssMainSplitterState(const QByteArray &state); void setRssMainSplitterState(const QByteArray &state);
QString getSearchColsWidth() const; QByteArray getSearchTabHeaderState() const;
void setSearchColsWidth(const QString &width); void setSearchTabHeaderState(const QByteArray &state);
QStringList getSearchEngDisabled() const; QStringList getSearchEngDisabled() const;
void setSearchEngDisabled(const QStringList &engines); void setSearchEngDisabled(const QStringList &engines);
QString getCreateTorLastAddPath() const; QString getCreateTorLastAddPath() const;

52
src/gui/properties/peerlistdelegate.h

@ -33,6 +33,8 @@
#include <QItemDelegate> #include <QItemDelegate>
#include <QPainter> #include <QPainter>
#include "base/preferences.h"
#include "base/utils/misc.h" #include "base/utils/misc.h"
#include "base/utils/string.h" #include "base/utils/string.h"
@ -40,45 +42,77 @@ class PeerListDelegate: public QItemDelegate {
Q_OBJECT Q_OBJECT
public: public:
enum PeerListColumns {COUNTRY, IP, PORT, CONNECTION, FLAGS, CLIENT, PROGRESS, DOWN_SPEED, UP_SPEED, enum PeerListColumns
TOT_DOWN, TOT_UP, RELEVANCE, DOWNLOADING_PIECE, IP_HIDDEN, COL_COUNT}; {
COUNTRY,
IP,
PORT,
CONNECTION,
FLAGS,
CLIENT,
PROGRESS,
DOWN_SPEED,
UP_SPEED,
TOT_DOWN,
TOT_UP, RELEVANCE,
DOWNLOADING_PIECE,
IP_HIDDEN,
COL_COUNT
};
public: public:
PeerListDelegate(QObject *parent) : QItemDelegate(parent) {} PeerListDelegate(QObject *parent) : QItemDelegate(parent) {}
~PeerListDelegate() {} ~PeerListDelegate() {}
void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const { void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
{
painter->save(); painter->save();
const bool hideValues = Preferences::instance()->getHideZeroValues();
QStyleOptionViewItem opt = QItemDelegate::setOptions(index, option); QStyleOptionViewItem opt = QItemDelegate::setOptions(index, option);
switch(index.column()) { switch(index.column()) {
case PORT: {
QItemDelegate::drawBackground(painter, opt, index);
opt.displayAlignment = Qt::AlignRight | Qt::AlignVCenter;
QItemDelegate::drawDisplay(painter, opt, option.rect, index.data().toString());
}
break;
case TOT_DOWN: case TOT_DOWN:
case TOT_UP: case TOT_UP: {
qlonglong size = index.data().toLongLong();
if (hideValues && (size <= 0))
break;
QItemDelegate::drawBackground(painter, opt, index); QItemDelegate::drawBackground(painter, opt, index);
QItemDelegate::drawDisplay(painter, opt, option.rect, Utils::Misc::friendlyUnit(index.data().toLongLong())); opt.displayAlignment = Qt::AlignRight | Qt::AlignVCenter;
QItemDelegate::drawDisplay(painter, opt, option.rect, Utils::Misc::friendlyUnit(size));
}
break; break;
case DOWN_SPEED: case DOWN_SPEED:
case UP_SPEED:{ case UP_SPEED:{
QItemDelegate::drawBackground(painter, opt, index); QItemDelegate::drawBackground(painter, opt, index);
qreal speed = index.data().toDouble(); qreal speed = index.data().toDouble();
opt.displayAlignment = Qt::AlignRight | Qt::AlignVCenter;
if (speed > 0.0) if (speed > 0.0)
QItemDelegate::drawDisplay(painter, opt, opt.rect, Utils::Misc::friendlyUnit(speed, true)); QItemDelegate::drawDisplay(painter, opt, opt.rect, Utils::Misc::friendlyUnit(speed, true));
break;
} }
break;
case PROGRESS: case PROGRESS:
case RELEVANCE:{ case RELEVANCE: {
QItemDelegate::drawBackground(painter, opt, index); QItemDelegate::drawBackground(painter, opt, index);
qreal progress = index.data().toDouble(); qreal progress = index.data().toDouble();
opt.displayAlignment = Qt::AlignRight | Qt::AlignVCenter;
QItemDelegate::drawDisplay(painter, opt, opt.rect, Utils::String::fromDouble(progress*100.0, 1)+"%"); QItemDelegate::drawDisplay(painter, opt, opt.rect, Utils::String::fromDouble(progress*100.0, 1)+"%");
break;
} }
break;
default: default:
QItemDelegate::paint(painter, option, index); QItemDelegate::paint(painter, option, index);
} }
painter->restore(); painter->restore();
} }
QWidget* createEditor(QWidget*, const QStyleOptionViewItem &, const QModelIndex &) const { QWidget* createEditor(QWidget*, const QStyleOptionViewItem &, const QModelIndex &) const
{
// No editor here // No editor here
return 0; return 0;
} }

8
src/gui/properties/peerlistwidget.cpp

@ -83,6 +83,14 @@ PeerListWidget::PeerListWidget(PropertiesWidget *parent)
m_listModel->setHeaderData(PeerListDelegate::TOT_UP, Qt::Horizontal, tr("Uploaded", "i.e: total data uploaded")); m_listModel->setHeaderData(PeerListDelegate::TOT_UP, Qt::Horizontal, tr("Uploaded", "i.e: total data uploaded"));
m_listModel->setHeaderData(PeerListDelegate::RELEVANCE, Qt::Horizontal, tr("Relevance", "i.e: How relevant this peer is to us. How many pieces it has that we don't.")); m_listModel->setHeaderData(PeerListDelegate::RELEVANCE, Qt::Horizontal, tr("Relevance", "i.e: How relevant this peer is to us. How many pieces it has that we don't."));
m_listModel->setHeaderData(PeerListDelegate::DOWNLOADING_PIECE, Qt::Horizontal, tr("Files", "i.e. files that are being downloaded right now")); m_listModel->setHeaderData(PeerListDelegate::DOWNLOADING_PIECE, Qt::Horizontal, tr("Files", "i.e. files that are being downloaded right now"));
// Set header text alignment
m_listModel->setHeaderData(PeerListDelegate::PORT, Qt::Horizontal, QVariant(Qt::AlignRight | Qt::AlignVCenter), Qt::TextAlignmentRole);
m_listModel->setHeaderData(PeerListDelegate::PROGRESS, Qt::Horizontal, QVariant(Qt::AlignRight | Qt::AlignVCenter), Qt::TextAlignmentRole);
m_listModel->setHeaderData(PeerListDelegate::DOWN_SPEED, Qt::Horizontal, QVariant(Qt::AlignRight | Qt::AlignVCenter), Qt::TextAlignmentRole);
m_listModel->setHeaderData(PeerListDelegate::UP_SPEED, Qt::Horizontal, QVariant(Qt::AlignRight | Qt::AlignVCenter), Qt::TextAlignmentRole);
m_listModel->setHeaderData(PeerListDelegate::TOT_DOWN, Qt::Horizontal, QVariant(Qt::AlignRight | Qt::AlignVCenter), Qt::TextAlignmentRole);
m_listModel->setHeaderData(PeerListDelegate::TOT_UP, Qt::Horizontal, QVariant(Qt::AlignRight | Qt::AlignVCenter), Qt::TextAlignmentRole);
m_listModel->setHeaderData(PeerListDelegate::RELEVANCE, Qt::Horizontal, QVariant(Qt::AlignRight | Qt::AlignVCenter), Qt::TextAlignmentRole);
// Proxy model to support sorting without actually altering the underlying model // Proxy model to support sorting without actually altering the underlying model
m_proxyModel = new PeerListSortModel(); m_proxyModel = new PeerListSortModel();
m_proxyModel->setDynamicSortFilter(true); m_proxyModel->setDynamicSortFilter(true);

3
src/gui/search/searchlistdelegate.cpp

@ -50,14 +50,17 @@ void SearchListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
switch(index.column()) { switch(index.column()) {
case SearchSortModel::SIZE: case SearchSortModel::SIZE:
QItemDelegate::drawBackground(painter, opt, index); QItemDelegate::drawBackground(painter, opt, index);
opt.displayAlignment = Qt::AlignRight | Qt::AlignVCenter;
QItemDelegate::drawDisplay(painter, opt, option.rect, Utils::Misc::friendlyUnit(index.data().toLongLong())); QItemDelegate::drawDisplay(painter, opt, option.rect, Utils::Misc::friendlyUnit(index.data().toLongLong()));
break; break;
case SearchSortModel::SEEDS: case SearchSortModel::SEEDS:
QItemDelegate::drawBackground(painter, opt, index); QItemDelegate::drawBackground(painter, opt, index);
opt.displayAlignment = Qt::AlignRight | Qt::AlignVCenter;
QItemDelegate::drawDisplay(painter, opt, option.rect, (index.data().toLongLong() >= 0) ? index.data().toString() : tr("Unknown")); QItemDelegate::drawDisplay(painter, opt, option.rect, (index.data().toLongLong() >= 0) ? index.data().toString() : tr("Unknown"));
break; break;
case SearchSortModel::LEECHES: case SearchSortModel::LEECHES:
QItemDelegate::drawBackground(painter, opt, index); QItemDelegate::drawBackground(painter, opt, index);
opt.displayAlignment = Qt::AlignRight | Qt::AlignVCenter;
QItemDelegate::drawDisplay(painter, opt, option.rect, (index.data().toLongLong() >= 0) ? index.data().toString() : tr("Unknown")); QItemDelegate::drawDisplay(painter, opt, option.rect, (index.data().toLongLong() >= 0) ? index.data().toString() : tr("Unknown"));
break; break;
default: default:

97
src/gui/search/searchtab.cpp

@ -30,6 +30,7 @@
#include <QApplication> #include <QApplication>
#include <QDir> #include <QDir>
#include <QMenu>
#include <QMetaEnum> #include <QMetaEnum>
#include <QTreeView> #include <QTreeView>
#include <QStandardItemModel> #include <QStandardItemModel>
@ -74,7 +75,9 @@ SearchTab::SearchTab(SearchWidget *parent)
m_ui->resultsBrowser->header()->setParent(m_ui->resultsBrowser); m_ui->resultsBrowser->header()->setParent(m_ui->resultsBrowser);
unused.setVerticalHeader(new QHeaderView(Qt::Horizontal)); unused.setVerticalHeader(new QHeaderView(Qt::Horizontal));
#endif #endif
loadSettings();
m_ui->resultsBrowser->setSelectionMode(QAbstractItemView::ExtendedSelection); m_ui->resultsBrowser->setSelectionMode(QAbstractItemView::ExtendedSelection);
header()->setStretchLastSection(false);
// Set Search results list model // Set Search results list model
m_searchListModel = new QStandardItemModel(0, SearchSortModel::NB_SEARCH_COLUMNS, this); m_searchListModel = new QStandardItemModel(0, SearchSortModel::NB_SEARCH_COLUMNS, this);
@ -83,6 +86,10 @@ SearchTab::SearchTab(SearchWidget *parent)
m_searchListModel->setHeaderData(SearchSortModel::SEEDS, Qt::Horizontal, tr("Seeders", "i.e: Number of full sources")); m_searchListModel->setHeaderData(SearchSortModel::SEEDS, Qt::Horizontal, tr("Seeders", "i.e: Number of full sources"));
m_searchListModel->setHeaderData(SearchSortModel::LEECHES, Qt::Horizontal, tr("Leechers", "i.e: Number of partial sources")); m_searchListModel->setHeaderData(SearchSortModel::LEECHES, Qt::Horizontal, tr("Leechers", "i.e: Number of partial sources"));
m_searchListModel->setHeaderData(SearchSortModel::ENGINE_URL, Qt::Horizontal, tr("Search engine")); m_searchListModel->setHeaderData(SearchSortModel::ENGINE_URL, Qt::Horizontal, tr("Search engine"));
// Set columns text alignment
m_searchListModel->setHeaderData(SearchSortModel::SIZE, Qt::Horizontal, QVariant(Qt::AlignRight | Qt::AlignVCenter), Qt::TextAlignmentRole);
m_searchListModel->setHeaderData(SearchSortModel::SEEDS, Qt::Horizontal, QVariant(Qt::AlignRight | Qt::AlignVCenter), Qt::TextAlignmentRole);
m_searchListModel->setHeaderData(SearchSortModel::LEECHES, Qt::Horizontal, QVariant(Qt::AlignRight | Qt::AlignVCenter), Qt::TextAlignmentRole);
m_proxyModel = new SearchSortModel(this); m_proxyModel = new SearchSortModel(this);
m_proxyModel->setDynamicSortFilter(true); m_proxyModel->setDynamicSortFilter(true);
@ -99,15 +106,31 @@ SearchTab::SearchTab(SearchWidget *parent)
m_ui->resultsBrowser->setAllColumnsShowFocus(true); m_ui->resultsBrowser->setAllColumnsShowFocus(true);
m_ui->resultsBrowser->setSortingEnabled(true); m_ui->resultsBrowser->setSortingEnabled(true);
//Ensure that at least one column is visible at all times
bool atLeastOne = false;
for (unsigned int i = 0; i < SearchSortModel::DL_LINK; i++) {
if (!m_ui->resultsBrowser->isColumnHidden(i)) {
atLeastOne = true;
break;
}
}
if (!atLeastOne)
m_ui->resultsBrowser->setColumnHidden(SearchSortModel::NAME, false);
//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
//in the above scenario.
for (unsigned int i = 0; i < SearchSortModel::DL_LINK; i++)
if ((m_ui->resultsBrowser->columnWidth(i) <= 0) && !m_ui->resultsBrowser->isColumnHidden(i))
m_ui->resultsBrowser->resizeColumnToContents(i);
// Connect signals to slots (search part) // Connect signals to slots (search part)
connect(m_ui->resultsBrowser, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(downloadItem(const QModelIndex&))); connect(m_ui->resultsBrowser, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(downloadItem(const QModelIndex&)));
// Load last columns width for search results list header()->setContextMenuPolicy(Qt::CustomContextMenu);
if (!loadColWidthResultsList()) connect(header(), SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(displayToggleColumnsMenu(const QPoint &)));
m_ui->resultsBrowser->header()->resizeSection(0, 275); connect(header(), SIGNAL(sectionResized(int, int, int)), this, SLOT(saveSettings()));
connect(header(), SIGNAL(sectionMoved(int, int, int)), this, SLOT(saveSettings()));
// Sort by Seeds connect(header(), SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)), this, SLOT(saveSettings()));
m_ui->resultsBrowser->sortByColumn(SearchSortModel::SEEDS, Qt::DescendingOrder);
fillFilterComboBoxes(); fillFilterComboBoxes();
@ -128,6 +151,7 @@ SearchTab::SearchTab(SearchWidget *parent)
SearchTab::~SearchTab() SearchTab::~SearchTab()
{ {
saveSettings();
delete m_ui; delete m_ui;
} }
@ -144,21 +168,6 @@ QHeaderView* SearchTab::header() const
return m_ui->resultsBrowser->header(); return m_ui->resultsBrowser->header();
} }
bool SearchTab::loadColWidthResultsList()
{
QString line = Preferences::instance()->getSearchColsWidth();
if (line.isEmpty()) return false;
QStringList widthList = line.split(' ');
if (widthList.size() > m_searchListModel->columnCount())
return false;
for (int i = 0; i < widthList.size(); ++i)
m_ui->resultsBrowser->header()->resizeSection(i, widthList.at(i).toInt());
return true;
}
QTreeView* SearchTab::getCurrentTreeView() const QTreeView* SearchTab::getCurrentTreeView() const
{ {
return m_ui->resultsBrowser; return m_ui->resultsBrowser;
@ -303,3 +312,49 @@ SearchTab::NameFilteringMode SearchTab::filteringMode() const
this->metaObject()->enumerator(this->metaObject()->indexOfEnumerator("NameFilteringMode")); this->metaObject()->enumerator(this->metaObject()->indexOfEnumerator("NameFilteringMode"));
return static_cast<NameFilteringMode>(metaEnum.keyToValue(m_ui->filterMode->itemData(m_ui->filterMode->currentIndex()).toByteArray())); return static_cast<NameFilteringMode>(metaEnum.keyToValue(m_ui->filterMode->itemData(m_ui->filterMode->currentIndex()).toByteArray()));
} }
void SearchTab::loadSettings()
{
header()->restoreState(Preferences::instance()->getSearchTabHeaderState());
}
void SearchTab::saveSettings() const
{
Preferences::instance()->setSearchTabHeaderState(header()->saveState());
}
void SearchTab::displayToggleColumnsMenu(const QPoint&)
{
QMenu hideshowColumn(this);
hideshowColumn.setTitle(tr("Column visibility"));
QList<QAction*> actions;
for (int i = 0; i < SearchSortModel::DL_LINK; ++i) {
QAction *myAct = hideshowColumn.addAction(m_searchListModel->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString());
myAct->setCheckable(true);
myAct->setChecked(!m_ui->resultsBrowser->isColumnHidden(i));
actions.append(myAct);
}
int visibleCols = 0;
for (unsigned int i = 0; i < SearchSortModel::DL_LINK; i++) {
if (!m_ui->resultsBrowser->isColumnHidden(i))
visibleCols++;
if (visibleCols > 1)
break;
}
// Call menu
QAction *act = hideshowColumn.exec(QCursor::pos());
if (act) {
int col = actions.indexOf(act);
Q_ASSERT(col >= 0);
Q_ASSERT(visibleCols > 0);
if ((!m_ui->resultsBrowser->isColumnHidden(col)) && (visibleCols == 1))
return;
qDebug("Toggling column %d visibility", col);
m_ui->resultsBrowser->setColumnHidden(col, !m_ui->resultsBrowser->isColumnHidden(col));
if ((!m_ui->resultsBrowser->isColumnHidden(col)) && (m_ui->resultsBrowser->columnWidth(col) <= 5))
m_ui->resultsBrowser->setColumnWidth(col, 100);
saveSettings();
}
}

4
src/gui/search/searchtab.h

@ -75,7 +75,6 @@ public:
QTreeView* getCurrentTreeView() const; QTreeView* getCurrentTreeView() const;
QHeaderView* header() const; QHeaderView* header() const;
bool loadColWidthResultsList();
void setRowColor(int row, const QColor &color); void setRowColor(int row, const QColor &color);
enum class Status enum class Status
@ -96,7 +95,10 @@ public slots:
void downloadItem(const QModelIndex &index); void downloadItem(const QModelIndex &index);
private slots: private slots:
void loadSettings();
void saveSettings() const;
void updateFilter(); void updateFilter();
void displayToggleColumnsMenu(const QPoint&);
private: private:
void fillFilterComboBoxes(); void fillFilterComboBoxes();

16
src/gui/search/searchwidget.cpp

@ -266,7 +266,6 @@ void SearchWidget::on_searchButton_clicked()
// Tab Addition // Tab Addition
m_currentSearchTab = new SearchTab(this); m_currentSearchTab = new SearchTab(this);
m_activeSearchTab = m_currentSearchTab; m_activeSearchTab = m_currentSearchTab;
connect(m_currentSearchTab->header(), SIGNAL(sectionResized(int, int, int)), this, SLOT(saveResultsColumnsWidth()));
m_allTabs.append(m_currentSearchTab); m_allTabs.append(m_currentSearchTab);
QString tabName = pattern; QString tabName = pattern;
tabName.replace(QRegExp("&{1}"), "&&"); tabName.replace(QRegExp("&{1}"), "&&");
@ -292,21 +291,6 @@ void SearchWidget::on_searchButton_clicked()
m_searchEngine->startSearch(pattern, selectedCategory(), plugins); m_searchEngine->startSearch(pattern, selectedCategory(), plugins);
} }
void SearchWidget::saveResultsColumnsWidth()
{
if (m_allTabs.isEmpty()) return;
QTreeView *treeview = m_allTabs.first()->getCurrentTreeView();
QStringList newWidthList;
short nbColumns = m_allTabs.first()->getCurrentSearchListModel()->columnCount();
for (short i = 0; i < nbColumns; ++i)
if (treeview->columnWidth(i) > 0)
newWidthList << QString::number(treeview->columnWidth(i));
// Don't save the width of the last column (auto column width)
newWidthList.removeLast();
Preferences::instance()->setSearchColsWidth(newWidthList.join(" "));
}
void SearchWidget::searchStarted() void SearchWidget::searchStarted()
{ {
// Update SearchEngine widgets // Update SearchEngine widgets

1
src/gui/search/searchwidget.h

@ -74,7 +74,6 @@ private slots:
void addTorrentToSession(const QString &source); void addTorrentToSession(const QString &source);
void saveResultsColumnsWidth();
void fillCatCombobox(); void fillCatCombobox();
void fillPluginComboBox(); void fillPluginComboBox();
void searchTextEdited(QString); void searchTextEdited(QString);

2
src/gui/transferlistwidget.cpp

@ -141,7 +141,7 @@ TransferListWidget::TransferListWidget(QWidget *parent, MainWindow *main_window)
//end up being size 0 when the new version is launched with //end up being size 0 when the new version is launched with
//a conf file from the previous version. //a conf file from the previous version.
for (unsigned int i = 0; i<TorrentModel::NB_COLUMNS; i++) for (unsigned int i = 0; i<TorrentModel::NB_COLUMNS; i++)
if (!columnWidth(i)) if ((columnWidth(i) <= 0) && (!isColumnHidden(i)))
resizeColumnToContents(i); resizeColumnToContents(i);
setContextMenuPolicy(Qt::CustomContextMenu); setContextMenuPolicy(Qt::CustomContextMenu);

Loading…
Cancel
Save