Show notice on top of filtered torrents list

This has a couple of benefits: 1) it is clearly visible to the user that
the list is filtered (doesn't display all the torrents) even when filter
bar is hidden, 2) doesn't lead to filter bar controls being shifted to
the left/right as when "Show:" label text changes.
This commit is contained in:
Mike Gelfand 2015-10-19 20:30:26 +00:00
parent f89fab72f9
commit 585e3df30c
10 changed files with 197 additions and 54 deletions

View File

@ -62,6 +62,7 @@ set(${PROJECT_NAME}_SOURCES
TorrentDelegateMin.cc
TorrentFilter.cc
TorrentModel.cc
TorrentView.cc
TrackerDelegate.cc
TrackerModel.cc
TrackerModelFilter.cc
@ -110,6 +111,7 @@ set(${PROJECT_NAME}_HEADERS
TorrentDelegateMin.h
TorrentFilter.h
TorrentModel.h
TorrentView.h
TrackerDelegate.h
TrackerModel.h
TrackerModelFilter.h

View File

@ -230,7 +230,7 @@ FilterBar::FilterBar (Prefs& prefs, const TorrentModel& torrents, const TorrentF
QHBoxLayout * h = new QHBoxLayout (this);
h->setContentsMargins (3, 3, 3, 3);
myCountLabel = new QLabel (this);
myCountLabel = new QLabel (tr ("Show:"), this);
h->addWidget (myCountLabel);
myActivityCombo = createActivityCombo ();
@ -249,8 +249,6 @@ FilterBar::FilterBar (Prefs& prefs, const TorrentModel& torrents, const TorrentF
connect (&myPrefs, SIGNAL (changed (int)), this, SLOT (refreshPref (int)));
connect (myActivityCombo, SIGNAL (currentIndexChanged (int)), this, SLOT (onActivityIndexChanged (int)));
connect (myTrackerCombo, SIGNAL (currentIndexChanged (int)), this, SLOT (onTrackerIndexChanged (int)));
connect (&myFilter, SIGNAL (rowsInserted (QModelIndex, int, int)), this, SLOT (refreshCountLabel ()));
connect (&myFilter, SIGNAL (rowsRemoved (QModelIndex, int, int)), this, SLOT (refreshCountLabel ()));
connect (&myTorrents, SIGNAL (modelReset ()), this, SLOT (recountSoon ()));
connect (&myTorrents, SIGNAL (rowsInserted (QModelIndex, int, int)), this, SLOT (recountSoon ()));
connect (&myTorrents, SIGNAL (rowsRemoved (QModelIndex, int, int)), this, SLOT (recountSoon ()));
@ -259,7 +257,6 @@ FilterBar::FilterBar (Prefs& prefs, const TorrentModel& torrents, const TorrentF
recountSoon ();
refreshTrackers ();
refreshCountLabel ();
myIsBootstrapping = false;
// initialize our state
@ -383,7 +380,6 @@ FilterBar::recount ()
}
refreshTrackers ();
refreshCountLabel ();
}
QString
@ -391,16 +387,3 @@ FilterBar::getCountString (int n) const
{
return QString::fromLatin1 ("%L1").arg (n);
}
void
FilterBar::refreshCountLabel ()
{
const int visibleCount = myFilter.rowCount ();
const int trackerCount = myTrackerCombo->currentCount ();
const int activityCount = myActivityCombo->currentCount ();
if ((visibleCount == activityCount) || (visibleCount == trackerCount))
myCountLabel->setText (tr("Show:"));
else
myCountLabel->setText (tr("Show %Ln of:", 0, visibleCount));
}

View File

@ -40,7 +40,6 @@ class FilterBar: public QWidget
void recountSoon ();
void recount ();
void refreshPref (int key);
void refreshCountLabel ();
void onActivityIndexChanged (int index);
void onTrackerIndexChanged (int index);
void onTextChanged (const QString&);

View File

@ -254,6 +254,11 @@ MainWindow::MainWindow (Session& session, Prefs& prefs, TorrentModel& model, boo
initStatusBar ();
ui.verticalLayout->insertWidget (0, myFilterBar = new FilterBar (myPrefs, myModel, myFilterModel));
connect (&myModel, SIGNAL (rowsInserted (QModelIndex, int, int)), SLOT (refreshTorrentViewHeader ()));
connect (&myModel, SIGNAL (rowsRemoved (QModelIndex, int, int)), SLOT (refreshTorrentViewHeader ()));
connect (&myFilterModel, SIGNAL (rowsInserted (QModelIndex, int, int)), SLOT (refreshTorrentViewHeader ()));
connect (&myFilterModel, SIGNAL (rowsRemoved (QModelIndex, int, int)), SLOT (refreshTorrentViewHeader ()));
QList<int> initKeys;
initKeys << Prefs::MAIN_WINDOW_X
<< Prefs::SHOW_TRAY_ICON
@ -300,6 +305,7 @@ MainWindow::MainWindow (Session& session, Prefs& prefs, TorrentModel& model, boo
refreshTrayIconSoon ();
refreshStatusBar ();
refreshTitle ();
refreshTorrentViewHeader ();
}
MainWindow::~MainWindow ()
@ -726,7 +732,17 @@ MainWindow::refreshStatusBar ()
ui.statsLabel->setText (str);
}
void
MainWindow::refreshTorrentViewHeader ()
{
const int totalCount = myModel.rowCount ();
const int visibleCount = myFilterModel.rowCount ();
if (visibleCount == totalCount)
ui.listView->setHeaderText (QString ());
else
ui.listView->setHeaderText (tr ("Showing %L1 of %Ln torrent(s)", 0, totalCount).arg (visibleCount));
}
void
MainWindow::refreshActionSensitivitySoon ()

View File

@ -110,6 +110,7 @@ class MainWindow: public QMainWindow
void refreshStatusBar ();
void refreshTrayIcon ();
void refreshTrayIconSoon ();
void refreshTorrentViewHeader ();
void openTorrent ();
void openURL ();
void newTorrent ();

View File

@ -25,7 +25,7 @@
<number>0</number>
</property>
<item>
<widget class="QListView" name="listView">
<widget class="TorrentView" name="listView">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
@ -779,6 +779,11 @@
<extends>QToolButton</extends>
<header>IconToolButton.h</header>
</customwidget>
<customwidget>
<class>TorrentView</class>
<extends>QListView</extends>
<header>TorrentView.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="application.qrc"/>

99
qt/TorrentView.cc Normal file
View File

@ -0,0 +1,99 @@
/*
* This file Copyright (C) 2015 Mnemosyne LLC
*
* It may be used under the GNU GPL versions 2 or 3
* or any future license endorsed by Mnemosyne LLC.
*
* $Id$
*/
#include <QApplication>
#include <QStyleOptionHeader>
#include <QStylePainter>
#include "TorrentView.h"
class TorrentView::HeaderWidget: public QWidget
{
public:
HeaderWidget (QWidget * parent):
QWidget (parent),
myText ()
{
setFont (qApp->font ("QMiniFont"));
}
void setText (const QString& text)
{
myText = text;
update ();
}
// QWidget
virtual QSize sizeHint () const
{
QStyleOptionHeader option;
option.rect = QRect (0, 0, 100, 100);
const QRect labelRect = style ()->subElementRect (QStyle::SE_HeaderLabel, &option, this);
return QSize (100, fontMetrics ().height () + (option.rect.height () - labelRect.height ()));
}
protected:
// QWidget
virtual void paintEvent (QPaintEvent * /*event*/)
{
QStyleOptionHeader option;
option.initFrom (this);
option.state = QStyle::State_Enabled;
option.position = QStyleOptionHeader::OnlyOneSection;
QStylePainter painter (this);
painter.drawControl (QStyle::CE_HeaderSection, option);
option.rect = style ()->subElementRect (QStyle::SE_HeaderLabel, &option, this);
painter.drawItemText (option.rect, Qt::AlignCenter, option.palette, true, myText, QPalette::ButtonText);
}
private:
QString myText;
};
TorrentView::TorrentView (QWidget * parent):
QListView (parent),
myHeaderWidget (new HeaderWidget (this))
{
}
void
TorrentView::setHeaderText (const QString& text)
{
const bool headerVisible = !text.isEmpty ();
myHeaderWidget->setText (text);
myHeaderWidget->setVisible (headerVisible);
if (headerVisible)
adjustHeaderPosition ();
setViewportMargins (0, headerVisible ? myHeaderWidget->height () : 0, 0, 0);
}
void
TorrentView::resizeEvent (QResizeEvent * event)
{
QListView::resizeEvent (event);
if (myHeaderWidget->isVisible ())
adjustHeaderPosition ();
}
void
TorrentView::adjustHeaderPosition ()
{
QRect headerWidgetRect = contentsRect ();
headerWidgetRect.setWidth (viewport ()->width ());
headerWidgetRect.setHeight (myHeaderWidget->sizeHint ().height ());
myHeaderWidget->setGeometry (headerWidgetRect);
}

38
qt/TorrentView.h Normal file
View File

@ -0,0 +1,38 @@
/*
* This file Copyright (C) 2015 Mnemosyne LLC
*
* It may be used under the GNU GPL versions 2 or 3
* or any future license endorsed by Mnemosyne LLC.
*
* $Id$
*/
#ifndef QTR_TORRENT_VIEW_H
#define QTR_TORRENT_VIEW_H
#include <QListView>
class TorrentView: public QListView
{
Q_OBJECT
public:
TorrentView (QWidget * parent = nullptr);
public slots:
void setHeaderText (const QString& text);
protected:
virtual void resizeEvent (QResizeEvent * event);
private:
class HeaderWidget;
private:
void adjustHeaderPosition ();
private:
HeaderWidget * const myHeaderWidget;
};
#endif // QTR_TORRENT_VIEW_H

View File

@ -105,6 +105,7 @@ SOURCES += AboutDialog.cc \
TorrentDelegateMin.cc \
TorrentFilter.cc \
TorrentModel.cc \
TorrentView.cc \
TrackerDelegate.cc \
TrackerModel.cc \
TrackerModelFilter.cc \

View File

@ -43,7 +43,7 @@
<context>
<name>Application</name>
<message>
<location filename="../Application.cc" line="+300"/>
<location filename="../Application.cc" line="+304"/>
<source>&lt;b&gt;Transmission is a file sharing program.&lt;/b&gt;</source>
<translation type="unfinished"></translation>
</message>
@ -571,29 +571,29 @@
<context>
<name>FileTreeItem</name>
<message>
<location filename="../FileTreeItem.cc" line="+256"/>
<location filename="../FileTreeView.cc" line="+110"/>
<location line="+263"/>
<location filename="../FileTreeItem.cc" line="+271"/>
<location filename="../FileTreeView.cc" line="+105"/>
<location line="+257"/>
<source>Low</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
<location filename="../FileTreeView.cc" line="-262"/>
<location line="+260"/>
<location filename="../FileTreeView.cc" line="-256"/>
<location line="+254"/>
<source>High</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
<location filename="../FileTreeView.cc" line="-261"/>
<location line="+262"/>
<location filename="../FileTreeView.cc" line="-255"/>
<location line="+256"/>
<source>Normal</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
<location filename="../FileTreeView.cc" line="-261"/>
<location filename="../FileTreeView.cc" line="-255"/>
<source>Mixed</source>
<translation type="unfinished"></translation>
</message>
@ -629,18 +629,18 @@
<context>
<name>FileTreeView</name>
<message>
<location filename="../FileTreeView.cc" line="+253"/>
<source>Check selected</source>
<location filename="../FileTreeView.cc" line="+247"/>
<source>Check Selected</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
<source>Uncheck selected</source>
<source>Uncheck Selected</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
<source>Only check selected</source>
<source>Only Check Selected</source>
<translation type="unfinished"></translation>
</message>
<message>
@ -692,16 +692,8 @@
<source>Finished</source>
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
<location line="+326"/>
<source>Show %Ln of:</source>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
</translation>
</message>
<message>
<location line="-322"/>
<location line="+4"/>
<source>Verifying</source>
<translation type="unfinished"></translation>
</message>
@ -711,7 +703,7 @@
<translation type="unfinished"></translation>
</message>
<message>
<location line="+316"/>
<location line="+141"/>
<source>Show:</source>
<translation type="unfinished"></translation>
</message>
@ -935,7 +927,6 @@
</message>
<message>
<location line="-161"/>
<location filename="../MainWindow.cc" line="+1442"/>
<source>Queue</source>
<translation type="unfinished"></translation>
</message>
@ -1257,7 +1248,7 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cc" line="-1015"/>
<location filename="../MainWindow.cc" line="+433"/>
<source>Limit Download Speed</source>
<translation type="unfinished"></translation>
</message>
@ -1268,13 +1259,13 @@
</message>
<message>
<location line="+6"/>
<location line="+615"/>
<location line="+641"/>
<location line="+8"/>
<source>Limited at %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="-573"/>
<location line="-599"/>
<source>Limit Upload Speed</source>
<translation type="unfinished"></translation>
</message>
@ -1290,12 +1281,12 @@
</message>
<message>
<location line="+6"/>
<location line="+601"/>
<location line="+627"/>
<source>Stop at Ratio (%1)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="-378"/>
<location line="-393"/>
<source> - %1:%2</source>
<extracomment>Second (optional) part of main window title &quot;Transmission - host:port&quot; (added when connected to remote session); notice that leading space (before the dash) is included here</extracomment>
<translation type="unfinished"></translation>
@ -1318,7 +1309,7 @@
<translation type="unfinished"></translation>
</message>
<message>
<location line="+406"/>
<location line="+421"/>
<source>Torrent Files (*.torrent);;All Files (*.*)</source>
<translation type="unfinished"></translation>
</message>
@ -1333,17 +1324,17 @@
<translation type="unfinished"></translation>
</message>
<message>
<location line="-885"/>
<location line="-917"/>
<source>Speed Limits</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+431"/>
<location line="+448"/>
<source>Network Error</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+418"/>
<location line="+433"/>
<source>Click to disable Temporary Speed Limits
(%1 down, %2 up)</source>
<translation type="unfinished"></translation>
@ -1373,7 +1364,15 @@
</translation>
</message>
<message numerus="yes">
<location line="+6"/>
<location line="-499"/>
<source>Showing %L1 of %Ln torrent(s)</source>
<translation type="unfinished">
<numerusform>Showing %L1 of %Ln torrent</numerusform>
<numerusform>Showing %L1 of %Ln torrents</numerusform>
</translation>
</message>
<message numerus="yes">
<location line="+505"/>
<source>Delete these %Ln torrent(s)&apos; downloaded files?</source>
<translation>
<numerusform>Delete this %Ln torrent&apos;s downloaded files?</numerusform>