source: trunk/qt/TorrentDelegateMin.cc @ 14537

Last change on this file since 14537 was 14537, checked in by mikedld, 6 years ago

Use PascalCase? for Qt client filenames

Split FileTree?.{h,cc} and FilterBar?.{h,cc} files so that each class
is in its own file.

This breaks translations (some classes got renamed => context changed),
to be fixed by next commit (along with Tx sync).

  • Property svn:keywords set to Date Rev Author Id
File size: 7.9 KB
Line 
1/*
2 * This file Copyright (C) 2009-2015 Mnemosyne LLC
3 *
4 * It may be used under the GNU GPL versions 2 or 3
5 * or any future license endorsed by Mnemosyne LLC.
6 *
7 * $Id: TorrentDelegateMin.cc 14537 2015-06-10 21:27:11Z mikedld $
8 */
9
10#include <iostream>
11
12#include <QApplication>
13#include <QBrush>
14#include <QFont>
15#include <QFontMetrics>
16#include <QIcon>
17#include <QModelIndex>
18#include <QPainter>
19#include <QPixmap>
20#include <QPixmapCache>
21#include <QStyleOptionProgressBar>
22
23#include <libtransmission/transmission.h>
24#include <libtransmission/utils.h>
25
26#include "Torrent.h"
27#include "TorrentDelegateMin.h"
28#include "TorrentModel.h"
29#include "Utils.h"
30
31enum
32{
33  GUI_PAD = 6,
34  BAR_WIDTH = 50,
35  BAR_HEIGHT = 12,
36  LINE_SPACING = 4
37};
38
39/***
40****
41****   +---------+-----------------------------------------------+
42****   |  Icon   |   Title      shortStatusString [Progressbar]  |
43****   +-------- +-----------------------------------------------+
44****
45***/
46
47namespace
48{
49  class ItemLayout
50  {
51    private:
52      QString myNameText;
53      QString myStatusText;
54
55    public:
56      QFont nameFont;
57      QFont statusFont;
58
59      QRect iconRect;
60      QRect emblemRect;
61      QRect nameRect;
62      QRect statusRect;
63      QRect barRect;
64
65    public:
66      ItemLayout(const QString& nameText, const QString& statusText, const QIcon& emblemIcon,
67                 const QFont& baseFont, Qt::LayoutDirection direction, const QPoint& topLeft, int width);
68
69      QSize size () const
70      {
71        return (iconRect | nameRect | statusRect | barRect).size ();
72      }
73
74      QString nameText () const { return elidedText (nameFont, myNameText, nameRect.width ()); }
75      QString statusText () const { return myStatusText; }
76
77    private:
78      QString elidedText (const QFont& font, const QString& text, int width) const
79      {
80        return QFontMetrics (font).elidedText (text, Qt::ElideRight, width);
81      }
82  };
83
84  ItemLayout::ItemLayout(const QString& nameText, const QString& statusText, const QIcon& emblemIcon,
85                         const QFont& baseFont, Qt::LayoutDirection direction, const QPoint& topLeft, int width):
86    myNameText (nameText),
87    myStatusText (statusText),
88    nameFont (baseFont),
89    statusFont (baseFont)
90  {
91    const QStyle * style (qApp->style ());
92    const int iconSize (style->pixelMetric (QStyle::PM_SmallIconSize));
93
94    const QFontMetrics nameFM (nameFont);
95    const QSize nameSize (nameFM.size (0, myNameText));
96
97    statusFont.setPointSize (static_cast<int> (statusFont.pointSize () * 0.85));
98    const QFontMetrics statusFM (statusFont);
99    const QSize statusSize (statusFM.size (0, myStatusText));
100
101    QRect baseRect (topLeft, QSize (width, qMax (iconSize, qMax (nameSize.height (), qMax (statusSize.height (), static_cast<int>(BAR_HEIGHT))))));
102
103    iconRect = style->alignedRect (direction, Qt::AlignLeft | Qt::AlignVCenter, QSize (iconSize, iconSize), baseRect);
104    emblemRect = style->alignedRect (direction, Qt::AlignRight | Qt::AlignBottom,
105                                     emblemIcon.actualSize (iconRect.size () / 2, QIcon::Normal, QIcon::On),
106                                     iconRect);
107    barRect = style->alignedRect (direction, Qt::AlignRight | Qt::AlignVCenter, QSize (BAR_WIDTH, BAR_HEIGHT), baseRect);
108    Utils::narrowRect (baseRect, iconRect.width () + GUI_PAD, barRect.width () + GUI_PAD, direction);
109    statusRect = style->alignedRect (direction, Qt::AlignRight | Qt::AlignVCenter, QSize (statusSize.width (), baseRect.height ()), baseRect);
110    Utils::narrowRect (baseRect, 0, statusRect.width () + GUI_PAD, direction);
111    nameRect = baseRect;
112  }
113}
114
115QSize
116TorrentDelegateMin::sizeHint (const QStyleOptionViewItem & option,
117                              const Torrent              & tor) const
118{
119  const bool isMagnet (!tor.hasMetadata());
120  const QSize m (margin (*qApp->style()));
121  const ItemLayout layout (isMagnet ? progressString (tor) : tor.name(), shortStatusString (tor), QIcon (),
122                           option.font, option.direction, QPoint (0, 0), option.rect.width () - m.width () * 2);
123  return layout.size () + m * 2;
124}
125
126void
127TorrentDelegateMin::drawTorrent (QPainter                   * painter,
128                                 const QStyleOptionViewItem & option,
129                                 const Torrent              & tor) const
130{
131  const QStyle * style (qApp->style());
132
133  const bool isPaused (tor.isPaused());
134  const bool isMagnet (!tor.hasMetadata());
135
136  const bool isItemSelected ((option.state & QStyle::State_Selected) != 0);
137  const bool isItemEnabled ((option.state & QStyle::State_Enabled) != 0);
138  const bool isItemActive ((option.state & QStyle::State_Active) != 0);
139
140  painter->save();
141
142  if (isItemSelected)
143    {
144      QPalette::ColorGroup cg = isItemEnabled ? QPalette::Normal : QPalette::Disabled;
145      if (cg == QPalette::Normal && !isItemActive)
146        cg = QPalette::Inactive;
147
148      painter->fillRect(option.rect, option.palette.brush(cg, QPalette::Highlight));
149    }
150
151  QIcon::Mode im;
152  if (isPaused || !isItemEnabled)
153    im = QIcon::Disabled;
154  else if (isItemSelected)
155    im = QIcon::Selected;
156  else
157    im = QIcon::Normal;
158
159  QIcon::State qs;
160  if (isPaused)
161    qs = QIcon::Off;
162  else
163    qs = QIcon::On;
164
165  QPalette::ColorGroup cg = QPalette::Normal;
166  if (isPaused || !isItemEnabled)
167    cg = QPalette::Disabled;
168  if (cg == QPalette::Normal && !isItemActive)
169    cg = QPalette::Inactive;
170
171  QPalette::ColorRole cr;
172  if (isItemSelected)
173    cr = QPalette::HighlightedText;
174  else
175    cr = QPalette::Text;
176
177  QStyle::State progressBarState (option.state);
178  if (isPaused)
179    progressBarState = QStyle::State_None;
180  progressBarState |= QStyle::State_Small;
181
182  const QIcon::Mode emblemIm = isItemSelected ? QIcon::Selected : QIcon::Normal;
183  const QIcon emblemIcon = tor.hasError () ? QIcon::fromTheme (QLatin1String ("emblem-important"), style->standardIcon (QStyle::SP_MessageBoxWarning)) : QIcon ();
184
185  // layout
186  const QSize m (margin (*style));
187  const QRect contentRect (option.rect.adjusted (m.width(), m.height(), -m.width(), -m.height()));
188  const ItemLayout layout (isMagnet ? progressString (tor) : tor.name(), shortStatusString (tor), emblemIcon,
189                           option.font, option.direction, contentRect.topLeft (), contentRect.width ());
190
191  // render
192  if (tor.hasError() && !isItemSelected)
193    painter->setPen (QColor ("red"));
194  else
195    painter->setPen (option.palette.color (cg, cr));
196  tor.getMimeTypeIcon().paint (painter, layout.iconRect, Qt::AlignCenter, im, qs);
197  if (!emblemIcon.isNull ())
198    emblemIcon.paint (painter, layout.emblemRect, Qt::AlignCenter, emblemIm, qs);
199  painter->setFont (layout.nameFont);
200  painter->drawText (layout.nameRect, Qt::AlignLeft | Qt::AlignVCenter, layout.nameText ());
201  painter->setFont (layout.statusFont);
202  painter->drawText (layout.statusRect, Qt::AlignLeft | Qt::AlignVCenter, layout.statusText ());
203  myProgressBarStyle->rect = layout.barRect;
204  if (tor.isDownloading())
205    {
206      myProgressBarStyle->palette.setBrush (QPalette::Highlight, blueBrush);
207      myProgressBarStyle->palette.setColor (QPalette::Base, blueBack);
208      myProgressBarStyle->palette.setColor (QPalette::Window, blueBack);
209    }
210  else if (tor.isSeeding())
211    {
212      myProgressBarStyle->palette.setBrush (QPalette::Highlight, greenBrush);
213      myProgressBarStyle->palette.setColor (QPalette::Base, greenBack);
214      myProgressBarStyle->palette.setColor (QPalette::Window, greenBack);
215    }
216  else
217    {
218      myProgressBarStyle->palette.setBrush (QPalette::Highlight, silverBrush);
219      myProgressBarStyle->palette.setColor (QPalette::Base, silverBack);
220      myProgressBarStyle->palette.setColor (QPalette::Window, silverBack);
221    }
222  myProgressBarStyle->state = progressBarState;
223  myProgressBarStyle->text = QString::fromLatin1 ("%1%").arg (static_cast<int> (tr_truncd (100.0 * tor.percentDone (), 0)));
224  myProgressBarStyle->textVisible = true;
225  myProgressBarStyle->textAlignment = Qt::AlignCenter;
226  setProgressBarPercentDone (option, tor);
227  style->drawControl (QStyle::CE_ProgressBar, myProgressBarStyle, painter);
228
229  painter->restore();
230}
Note: See TracBrowser for help on using the repository browser.