source: trunk/qt/filterbar.cc @ 14392

Last change on this file since 14392 was 14392, checked in by mikedld, 8 years ago

Move filter text clearing button into line edit. Use Qt-provided button on Qt 5.2+.

  • Property svn:keywords set to Date Rev Author Id
File size: 21.0 KB
Line 
1/*
2 * This file Copyright (C) 2012-2014 Mnemosyne LLC
3 *
4 * It may be used under the GNU Public License v2 or v3 licenses,
5 * or any future license endorsed by Mnemosyne LLC.
6 *
7 * $Id: filterbar.cc 14392 2014-12-21 15:34:52Z mikedld $
8 */
9
10#include <QAbstractItemView>
11#include <QLabel>
12#include <QHBoxLayout>
13#include <QStylePainter>
14#include <QString>
15#include <QToolButton>
16#include <QtGui>
17
18#include "app.h"
19#include "favicon.h"
20#include "filters.h"
21#include "filterbar.h"
22#include "hig.h"
23#include "prefs.h"
24#include "torrent-filter.h"
25#include "torrent-model.h"
26#include "utils.h"
27
28/****
29*****
30*****  DELEGATE
31*****
32****/
33
34enum
35{
36  TorrentCountRole = Qt::UserRole + 1,
37  TorrentCountStringRole,
38  ActivityRole,
39  TrackerRole
40};
41
42namespace
43{
44  int getHSpacing (QWidget * w)
45  {
46    return qMax (int (HIG::PAD_SMALL), w->style ()->pixelMetric (QStyle::PM_LayoutHorizontalSpacing, 0, w));
47  }
48}
49
50FilterBarComboBoxDelegate::FilterBarComboBoxDelegate (QObject * parent, QComboBox * combo):
51  QItemDelegate (parent),
52  myCombo (combo)
53{
54}
55
56bool
57FilterBarComboBoxDelegate::isSeparator (const QModelIndex& index)
58{
59  return index.data (Qt::AccessibleDescriptionRole).toString () == QLatin1String ("separator");
60}
61void
62FilterBarComboBoxDelegate::setSeparator (QAbstractItemModel * model, const QModelIndex& index)
63{
64  model->setData (index, QString::fromLatin1 ("separator"), Qt::AccessibleDescriptionRole);
65
66  if (QStandardItemModel *m = qobject_cast<QStandardItemModel*> (model))
67    if (QStandardItem *item = m->itemFromIndex (index))
68      item->setFlags (item->flags () & ~ (Qt::ItemIsSelectable|Qt::ItemIsEnabled));
69}
70
71void
72FilterBarComboBoxDelegate::paint (QPainter                    * painter,
73                                  const QStyleOptionViewItem  & option,
74                                  const QModelIndex           & index) const
75{
76  if (isSeparator (index))
77    {
78      QRect rect = option.rect;
79      if (const QStyleOptionViewItemV3 *v3 = qstyleoption_cast<const QStyleOptionViewItemV3*> (&option))
80        if (const QAbstractItemView *view = qobject_cast<const QAbstractItemView*> (v3->widget))
81          rect.setWidth (view->viewport ()->width ());
82      QStyleOption opt;
83      opt.rect = rect;
84      myCombo->style ()->drawPrimitive (QStyle::PE_IndicatorToolBarSeparator, &opt, painter, myCombo);
85    }
86  else
87    {
88      QStyleOptionViewItem disabledOption = option;
89      disabledOption.state &= ~ (QStyle::State_Enabled | QStyle::State_Selected);
90      QRect boundingBox = option.rect;
91
92      const int hmargin = getHSpacing (myCombo);
93      boundingBox.setLeft (boundingBox.left () + hmargin);
94      boundingBox.setRight (boundingBox.right () - hmargin);
95
96      QRect decorationRect = rect (option, index, Qt::DecorationRole);
97      decorationRect.moveLeft (decorationRect.left ());
98      decorationRect.setSize (myCombo->iconSize ());
99      decorationRect = QStyle::alignedRect (Qt::LeftToRight,
100                                            Qt::AlignLeft|Qt::AlignVCenter,
101                                            decorationRect.size (), boundingBox);
102      boundingBox.setLeft (decorationRect.right () + hmargin);
103
104      QRect countRect  = rect (option, index, TorrentCountStringRole);
105      countRect = QStyle::alignedRect (Qt::LeftToRight,
106                                       Qt::AlignRight|Qt::AlignVCenter,
107                                       countRect.size (), boundingBox);
108      boundingBox.setRight (countRect.left () - hmargin);
109      const QRect displayRect = boundingBox;
110
111      drawBackground (painter, option, index);
112      QStyleOptionViewItem option2 = option;
113      option2.decorationSize = myCombo->iconSize ();
114      drawDecoration (painter, option, decorationRect, decoration (option2,index.data (Qt::DecorationRole)));
115      drawDisplay (painter, option, displayRect, index.data (Qt::DisplayRole).toString ());
116      drawDisplay (painter, disabledOption, countRect, index.data (TorrentCountStringRole).toString ());
117      drawFocus (painter, option, displayRect|countRect);
118    }
119}
120
121QSize
122FilterBarComboBoxDelegate::sizeHint (const QStyleOptionViewItem & option,
123                                     const QModelIndex          & index) const
124{
125  if (isSeparator (index))
126    {
127      const int pm = myCombo->style ()->pixelMetric (QStyle::PM_DefaultFrameWidth, 0, myCombo);
128      return QSize (pm, pm + 10);
129    }
130  else
131    {
132      QStyle * s = myCombo->style ();
133      const int hmargin = getHSpacing (myCombo);
134
135      QSize size = QItemDelegate::sizeHint (option, index);
136      size.setHeight (qMax (size.height (), myCombo->iconSize ().height () + 6));
137      size.rwidth () += s->pixelMetric (QStyle::PM_FocusFrameHMargin, 0, myCombo);
138      size.rwidth () += rect (option,index,TorrentCountStringRole).width ();
139      size.rwidth () += hmargin * 4;
140      return size;
141    }
142}
143
144/**
145***
146**/
147
148FilterBarComboBox::FilterBarComboBox (QWidget * parent):
149  QComboBox (parent)
150{
151}
152
153int
154FilterBarComboBox::currentCount () const
155{
156  int count = 0;
157
158  const QModelIndex modelIndex = model ()->index (currentIndex (), 0, rootModelIndex ());
159  if (modelIndex.isValid ())
160    count = modelIndex.data (TorrentCountRole).toInt ();
161
162  return count;
163}
164
165void
166FilterBarComboBox::paintEvent (QPaintEvent * e)
167{
168  Q_UNUSED (e);
169
170  QStylePainter painter (this);
171  painter.setPen (palette ().color (QPalette::Text));
172
173  // draw the combobox frame, focusrect and selected etc.
174  QStyleOptionComboBox opt;
175  initStyleOption (&opt);
176  painter.drawComplexControl (QStyle::CC_ComboBox, opt);
177
178  // draw the icon and text
179  const QModelIndex modelIndex = model ()->index (currentIndex (), 0, rootModelIndex ());
180  if (modelIndex.isValid ())
181    {
182      QStyle * s = style ();
183      QRect rect = s->subControlRect (QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxEditField, this);
184      const int hmargin = getHSpacing (this);
185      rect.setRight (rect.right () - hmargin);
186
187      // draw the icon
188      QPixmap pixmap;
189      QVariant variant = modelIndex.data (Qt::DecorationRole);
190      switch (variant.type ())
191        {
192          case QVariant::Pixmap: pixmap = qvariant_cast<QPixmap> (variant); break;
193          case QVariant::Icon:   pixmap = qvariant_cast<QIcon> (variant).pixmap (iconSize ()); break;
194          default: break;
195        }
196      if (!pixmap.isNull ())
197        {
198          s->drawItemPixmap (&painter, rect, Qt::AlignLeft|Qt::AlignVCenter, pixmap);
199          rect.setLeft (rect.left () + pixmap.width () + hmargin);
200        }
201
202      // draw the count
203      QString text = modelIndex.data (TorrentCountStringRole).toString ();
204      if (!text.isEmpty ())
205        {
206          const QPen pen = painter.pen ();
207          painter.setPen (opt.palette.color (QPalette::Disabled, QPalette::Text));
208          QRect r = s->itemTextRect (painter.fontMetrics (), rect, Qt::AlignRight|Qt::AlignVCenter, false, text);
209          painter.drawText (r, 0, text);
210          rect.setRight (r.left () - hmargin);
211          painter.setPen (pen);
212        }
213
214      // draw the text
215      text = modelIndex.data (Qt::DisplayRole).toString ();
216      text = painter.fontMetrics ().elidedText (text, Qt::ElideRight, rect.width ());
217      s->drawItemText (&painter, rect, Qt::AlignLeft|Qt::AlignVCenter, opt.palette, true, text);
218    }
219}
220
221/****
222*****
223****/
224
225FilterBarLineEdit::FilterBarLineEdit (QWidget * parent):
226  QLineEdit (parent),
227  myClearButton (nullptr)
228{
229#if QT_VERSION < QT_VERSION_CHECK(5, 2, 0)
230  const QIcon icon = QIcon::fromTheme ("edit-clear", style ()->standardIcon (QStyle::SP_DialogCloseButton));
231  const int iconSize = style ()->pixelMetric (QStyle::PM_SmallIconSize);
232
233  myClearButton = new QToolButton (this);
234  myClearButton->setStyleSheet (QLatin1String ("QToolButton{border:0;padding:0;margin:0}"));
235  myClearButton->setToolButtonStyle (Qt::ToolButtonIconOnly);
236  myClearButton->setFocusPolicy (Qt::NoFocus);
237  myClearButton->setCursor (Qt::ArrowCursor);
238  myClearButton->setIconSize (QSize (iconSize, iconSize));
239  myClearButton->setIcon (icon);
240  myClearButton->hide ();
241
242  const int frameWidth = style ()->pixelMetric (QStyle::PM_DefaultFrameWidth);
243  const QSize minSizeHint = minimumSizeHint ();
244  const QSize buttonSizeHint = myClearButton->sizeHint ();
245
246  setStyleSheet (QString::fromLatin1 ("QLineEdit{padding-right:%1px}").arg (buttonSizeHint.width () + frameWidth + 1));
247  setMinimumSize (qMax (minSizeHint.width (), buttonSizeHint.width () + frameWidth * 2 + 2),
248                  qMax (minSizeHint.height (), buttonSizeHint.height () + frameWidth * 2 + 2));
249
250  connect (this, SIGNAL (textChanged (QString)), this, SLOT (updateClearButtonVisibility ()));
251  connect (myClearButton, SIGNAL (clicked ()), this, SLOT (clear ()));
252#else
253  setClearButtonEnabled (true);
254#endif
255}
256
257void FilterBarLineEdit::resizeEvent (QResizeEvent * event)
258{
259  QLineEdit::resizeEvent (event);
260
261#if QT_VERSION < QT_VERSION_CHECK(5, 2, 0)
262  const int frameWidth = style ()->pixelMetric (QStyle::PM_DefaultFrameWidth);
263  const QRect editRect = rect();
264  const QSize buttonSizeHint = myClearButton->sizeHint ();
265
266  myClearButton->move (editRect.right () - frameWidth - buttonSizeHint.width (),
267                       editRect.top () + (editRect.height () - buttonSizeHint.height ()) / 2);
268#endif
269}
270
271void FilterBarLineEdit::updateClearButtonVisibility ()
272{
273#if QT_VERSION < QT_VERSION_CHECK(5, 2, 0)
274  myClearButton->setVisible (!text ().isEmpty ());
275#endif
276}
277
278/****
279*****
280*****  ACTIVITY
281*****
282****/
283
284FilterBarComboBox *
285FilterBar::createActivityCombo ()
286{
287  FilterBarComboBox * c = new FilterBarComboBox (this);
288  FilterBarComboBoxDelegate * delegate = new FilterBarComboBoxDelegate (this, c);
289  c->setItemDelegate (delegate);
290
291  QPixmap blankPixmap (c->iconSize ());
292  blankPixmap.fill (Qt::transparent);
293  QIcon blankIcon (blankPixmap);
294
295  QStandardItemModel * model = new QStandardItemModel (this);
296
297  QStandardItem * row = new QStandardItem (tr ("All"));
298  row->setData (FilterMode::SHOW_ALL, ActivityRole);
299  model->appendRow (row);
300
301  model->appendRow (new QStandardItem); // separator
302  delegate->setSeparator (model, model->index (1, 0));
303
304  row = new QStandardItem (QIcon::fromTheme ("system-run", blankIcon), tr ("Active"));
305  row->setData (FilterMode::SHOW_ACTIVE, ActivityRole);
306  model->appendRow (row);
307
308  row = new QStandardItem (QIcon::fromTheme ("go-down", blankIcon), tr ("Downloading"));
309  row->setData (FilterMode::SHOW_DOWNLOADING, ActivityRole);
310  model->appendRow (row);
311
312  row = new QStandardItem (QIcon::fromTheme ("go-up", blankIcon), tr ("Seeding"));
313  row->setData (FilterMode::SHOW_SEEDING, ActivityRole);
314  model->appendRow (row);
315
316  row = new QStandardItem (QIcon::fromTheme ("media-playback-pause", blankIcon), tr ("Paused"));
317  row->setData (FilterMode::SHOW_PAUSED, ActivityRole);
318  model->appendRow (row);
319
320  row = new QStandardItem (blankIcon, tr ("Finished"));
321  row->setData (FilterMode::SHOW_FINISHED, ActivityRole);
322  model->appendRow (row);
323
324  row = new QStandardItem (QIcon::fromTheme ("view-refresh", blankIcon), tr ("Verifying"));
325  row->setData (FilterMode::SHOW_VERIFYING, ActivityRole);
326  model->appendRow (row);
327
328  row = new QStandardItem (QIcon::fromTheme ("dialog-error", blankIcon), tr ("Error"));
329  row->setData (FilterMode::SHOW_ERROR, ActivityRole);
330  model->appendRow (row);
331
332  c->setModel (model);
333  return c;
334}
335
336/****
337*****
338*****
339*****
340****/
341
342namespace
343{
344  QString readableHostName (const QString& host)
345  {
346    // get the readable name...
347    QString name = host;
348    const int pos = name.lastIndexOf ('.');
349    if (pos >= 0)
350      name.truncate (pos);
351    if (!name.isEmpty ())
352      name[0] = name[0].toUpper ();
353    return name;
354  }
355}
356
357void
358FilterBar::refreshTrackers ()
359{
360  Favicons& favicons = dynamic_cast<MyApp*> (QApplication::instance ())->favicons;
361  const int firstTrackerRow = 2; // skip over the "All" and separator...
362
363  // pull info from the tracker model...
364  QSet<QString> oldHosts;
365  for (int row=firstTrackerRow; ; ++row)
366    {
367      QModelIndex index = myTrackerModel->index (row, 0);
368      if (!index.isValid ())
369        break;
370      oldHosts << index.data (TrackerRole).toString ();
371    }
372
373  // pull the new stats from the torrent model...
374  QSet<QString> newHosts;
375  QMap<QString,int> torrentsPerHost;
376  for (int row=0; ; ++row)
377    {
378      QModelIndex index = myTorrents.index (row, 0);
379      if (!index.isValid ())
380        break;
381      const Torrent * tor = index.data (TorrentModel::TorrentRole).value<const Torrent*> ();
382      QSet<QString> torrentNames;
383      foreach (QString host, tor->hosts ())
384        {
385          newHosts.insert (host);
386          torrentNames.insert (readableHostName (host));
387        }
388      foreach (QString name, torrentNames)
389        ++torrentsPerHost[name];
390    }
391
392  // update the "All" row
393  myTrackerModel->setData (myTrackerModel->index (0,0), myTorrents.rowCount (), TorrentCountRole);
394  myTrackerModel->setData (myTrackerModel->index (0,0), getCountString (myTorrents.rowCount ()), TorrentCountStringRole);
395
396  // rows to update
397  foreach (QString host, oldHosts & newHosts)
398    {
399      const QString name = readableHostName (host);
400      QStandardItem * row = myTrackerModel->findItems (name).front ();
401      const int count = torrentsPerHost[name];
402      row->setData (count, TorrentCountRole);
403      row->setData (getCountString (count), TorrentCountStringRole);
404      row->setData (favicons.findFromHost (host), Qt::DecorationRole);
405    }
406
407  // rows to remove
408  foreach (QString host, oldHosts - newHosts)
409    {
410      const QString name = readableHostName (host);
411      QStandardItem * item = myTrackerModel->findItems (name).front ();
412      if (!item->data (TrackerRole).toString ().isEmpty ()) // don't remove "All"
413        myTrackerModel->removeRows (item->row (), 1);
414    }
415
416  // rows to add
417  bool anyAdded = false;
418  foreach (QString host, newHosts - oldHosts)
419    {
420      const QString name = readableHostName (host);
421
422      if (!myTrackerModel->findItems (name).isEmpty ())
423        continue;
424
425      // find the sorted position to add this row
426      int i = firstTrackerRow;
427      for (int n=myTrackerModel->rowCount (); i<n; ++i)
428        {
429          const QString rowName = myTrackerModel->index (i,0).data (Qt::DisplayRole).toString ();
430          if (rowName >= name)
431            break;
432        }
433
434      // add the row
435      QStandardItem * row = new QStandardItem (favicons.findFromHost (host), name);
436      const int count = torrentsPerHost[host];
437      row->setData (count, TorrentCountRole);
438      row->setData (getCountString (count), TorrentCountStringRole);
439      row->setData (favicons.findFromHost (host), Qt::DecorationRole);
440      row->setData (host, TrackerRole);
441      myTrackerModel->insertRow (i, row);
442      anyAdded = true;
443    }
444
445  if (anyAdded) // the one added might match our filter...
446    refreshPref (Prefs::FILTER_TRACKERS);
447}
448
449
450FilterBarComboBox *
451FilterBar::createTrackerCombo (QStandardItemModel * model)
452{
453  FilterBarComboBox * c = new FilterBarComboBox (this);
454  FilterBarComboBoxDelegate * delegate = new FilterBarComboBoxDelegate (this, c);
455  c->setItemDelegate (delegate);
456
457  QStandardItem * row = new QStandardItem (tr ("All"));
458  row->setData ("", TrackerRole);
459  const int count = myTorrents.rowCount ();
460  row->setData (count, TorrentCountRole);
461  row->setData (getCountString (count), TorrentCountStringRole);
462  model->appendRow (row);
463
464  model->appendRow (new QStandardItem); // separator
465  delegate->setSeparator (model, model->index (1, 0));
466
467  c->setModel (model);
468  return c;
469}
470
471/****
472*****
473*****
474*****
475****/
476
477FilterBar::FilterBar (Prefs& prefs, TorrentModel& torrents, TorrentFilter& filter, QWidget * parent):
478  QWidget (parent),
479  myPrefs (prefs),
480  myTorrents (torrents),
481  myFilter (filter),
482  myRecountTimer (new QTimer (this)),
483  myIsBootstrapping (true)
484{
485  QHBoxLayout * h = new QHBoxLayout (this);
486  const int hmargin = qMax (int (HIG::PAD), style ()->pixelMetric (QStyle::PM_LayoutHorizontalSpacing));
487
488  myCountLabel = new QLabel (this);
489  h->setSpacing (0);
490  h->setContentsMargins (2, 2, 2, 2);
491  h->addWidget (myCountLabel);
492  h->addSpacing (hmargin);
493
494  myActivityCombo = createActivityCombo ();
495  h->addWidget (myActivityCombo, 1);
496  h->addSpacing (hmargin);
497
498  myTrackerModel = new QStandardItemModel (this);
499  myTrackerCombo = createTrackerCombo (myTrackerModel);
500  h->addWidget (myTrackerCombo, 1);
501  h->addSpacing (hmargin*2);
502
503  myLineEdit = new FilterBarLineEdit (this);
504  h->addWidget (myLineEdit);
505  connect (myLineEdit, SIGNAL (textChanged (QString)), this, SLOT (onTextChanged (QString)));
506
507  // listen for changes from the other players
508  connect (&myPrefs, SIGNAL (changed (int)), this, SLOT (refreshPref (int)));
509  connect (myActivityCombo, SIGNAL (currentIndexChanged (int)), this, SLOT (onActivityIndexChanged (int)));
510  connect (myTrackerCombo, SIGNAL (currentIndexChanged (int)), this, SLOT (onTrackerIndexChanged (int)));
511  connect (&myFilter, SIGNAL (rowsInserted (QModelIndex, int, int)), this, SLOT (refreshCountLabel ()));
512  connect (&myFilter, SIGNAL (rowsRemoved (QModelIndex, int, int)), this, SLOT (refreshCountLabel ()));
513  connect (&myTorrents, SIGNAL (modelReset ()), this, SLOT (onTorrentModelReset ()));
514  connect (&myTorrents, SIGNAL (rowsInserted (QModelIndex, int, int)), this, SLOT (onTorrentModelRowsInserted (QModelIndex, int, int)));
515  connect (&myTorrents, SIGNAL (rowsRemoved (QModelIndex, int, int)), this, SLOT (onTorrentModelRowsRemoved (QModelIndex, int, int)));
516  connect (&myTorrents, SIGNAL (dataChanged (QModelIndex, QModelIndex)), this, SLOT (onTorrentModelDataChanged (QModelIndex, QModelIndex)));
517  connect (myRecountTimer, SIGNAL (timeout ()), this, SLOT (recount ()));
518
519  recountSoon ();
520  refreshTrackers ();
521  refreshCountLabel ();
522  myIsBootstrapping = false;
523
524  // initialize our state
525  QList<int> initKeys;
526  initKeys << Prefs::FILTER_MODE
527           << Prefs::FILTER_TRACKERS;
528  foreach (int key, initKeys)
529      refreshPref (key);
530}
531
532FilterBar::~FilterBar ()
533{
534  delete myRecountTimer;
535}
536
537/***
538****
539***/
540
541void
542FilterBar::refreshPref (int key)
543{
544  switch (key)
545    {
546      case Prefs::FILTER_MODE:
547        {
548          const FilterMode m = myPrefs.get<FilterMode> (key);
549          QAbstractItemModel * model = myActivityCombo->model ();
550          QModelIndexList indices = model->match (model->index (0,0), ActivityRole, m.mode ());
551          myActivityCombo->setCurrentIndex (indices.isEmpty () ? 0 : indices.first ().row ());
552          break;
553        }
554
555      case Prefs::FILTER_TRACKERS:
556        {
557          const QString tracker = myPrefs.getString (key);
558          const QString name = readableHostName (tracker);
559          QList<QStandardItem*> rows = myTrackerModel->findItems (name);
560          if (!rows.isEmpty ())
561            {
562              myTrackerCombo->setCurrentIndex (rows.front ()->row ());
563            }
564          else // hm, we don't seem to have this tracker anymore...
565            {
566              const bool isBootstrapping = myTrackerModel->rowCount () <= 2;
567              if (!isBootstrapping)
568                myPrefs.set (key, "");
569            }
570          break;
571        }
572    }
573}
574
575void
576FilterBar::onTextChanged (const QString& str)
577{
578  if (!myIsBootstrapping)
579    myPrefs.set (Prefs::FILTER_TEXT, str.trimmed ());
580}
581
582void
583FilterBar::onTrackerIndexChanged (int i)
584{
585  if (!myIsBootstrapping)
586    {
587      QString str;
588      const bool isTracker = !myTrackerCombo->itemData (i,TrackerRole).toString ().isEmpty ();
589      if (!isTracker) // show all
590        {
591          str = "";
592        }
593      else
594        {
595          str = myTrackerCombo->itemData (i,TrackerRole).toString ();
596          const int pos = str.lastIndexOf ('.');
597          if (pos >= 0)
598            str.truncate (pos+1);
599        }
600      myPrefs.set (Prefs::FILTER_TRACKERS, str);
601    }
602}
603
604void
605FilterBar::onActivityIndexChanged (int i)
606{
607  if (!myIsBootstrapping)
608    {
609      const FilterMode mode = myActivityCombo->itemData (i, ActivityRole).toInt ();
610      myPrefs.set (Prefs::FILTER_MODE, mode);
611    }
612}
613
614/***
615****
616***/
617
618void FilterBar::onTorrentModelReset () { recountSoon (); }
619void FilterBar::onTorrentModelRowsInserted (const QModelIndex&, int, int) { recountSoon (); }
620void FilterBar::onTorrentModelRowsRemoved (const QModelIndex&, int, int) { recountSoon (); }
621void FilterBar::onTorrentModelDataChanged (const QModelIndex&, const QModelIndex&) { recountSoon (); }
622
623void
624FilterBar::recountSoon ()
625{
626  if (!myRecountTimer->isActive ())
627    {
628      myRecountTimer->setSingleShot (true);
629      myRecountTimer->start (800);
630    }
631}
632void
633FilterBar::recount ()
634{
635  QAbstractItemModel * model = myActivityCombo->model ();
636
637  int torrentsPerMode[FilterMode::NUM_MODES] = {};
638  myFilter.countTorrentsPerMode (torrentsPerMode);
639
640  for (int row=0, n=model->rowCount (); row<n; ++row)
641    {
642      QModelIndex index = model->index (row, 0);
643      const int mode = index.data (ActivityRole).toInt ();
644      const int count = torrentsPerMode [mode];
645      model->setData (index, count, TorrentCountRole);
646      model->setData (index, getCountString (count), TorrentCountStringRole);
647    }
648
649  refreshTrackers ();
650  refreshCountLabel ();
651}
652
653QString
654FilterBar::getCountString (int n) const
655{
656  return QString ("%L1").arg (n);
657}
658
659void
660FilterBar::refreshCountLabel ()
661{
662  const int visibleCount = myFilter.rowCount ();
663  const int trackerCount = myTrackerCombo->currentCount ();
664  const int activityCount = myActivityCombo->currentCount ();
665
666  if ((visibleCount == activityCount) || (visibleCount == trackerCount))
667    myCountLabel->setText (tr("Show:"));
668  else
669    myCountLabel->setText (tr("Show %Ln of:", 0, visibleCount));
670}
Note: See TracBrowser for help on using the repository browser.