QtBase  v6.3.1
simplelistview.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the examples of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21 ** included in the packaging of this file. Please review the following
22 ** information to ensure the GNU General Public License requirements will
23 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24 **
25 ** $QT_END_LICENSE$
26 **
27 ****************************************************************************/
28 
29 #include "simplelistview.h"
30 #include "scrollbar.h"
31 #include "simplelistview.h"
32 #include "scrollbar.h"
33 #include "listitem.h"
34 #include "listitemcache.h"
35 #include "theme.h"
36 
37 #include <QtGui>
38 #include <QGraphicsGridLayout>
39 #include <QGraphicsSceneResizeEvent>
40 
42 {
43  Q_DECLARE_PUBLIC(SimpleListView)
44 
45 public:
46 
48  : m_content(0)
49  , m_layout(0)
51  , q_ptr(button)
53  {
54  Q_Q(SimpleListView);
55 
57  m_layout->setContentsMargins(0, 0, 0, 0);
58  m_layout->setSpacing(0);
61  m_layout->setRowSpacing(0,0);
62  m_layout->setRowSpacing(1,0);
65  m_content->setParentItem(q->viewport());
67 
68  q->horizontalScrollBar()->setSliderSize(0.0);
69 
70  QObject::connect(Theme::p(), SIGNAL(themeChanged()), q, SLOT(themeChange()));
71  }
72 
74  {
75  if (!m_content->parentItem() && !m_content->parent())
76  delete m_content;
77  }
78 
80  {
81  Q_UNUSED(s);
82  Q_Q(SimpleListView);
83 
84  if (!m_content)
85  return;
86 
87  const bool caching = q->listItemCaching();
88  q->setListItemCaching(false);
89 
90  m_content->resize(q->viewport()->size().width(),
92  const bool clip =
93  m_content->size().width() > q->viewport()->size().width()
94  || m_content->size().height() > q->viewport()->size().height();
95 
96  q->viewport()->setFlag(
98 
99  q->setListItemCaching(caching);
100  }
101 
103  {
104  Q_Q(SimpleListView);
105 
106  if (!m_content)
107  return;
108 
111 
112  QRectF contentRect = m_content->boundingRect();
113  QRectF listRect = q->boundingRect();
114 
115  // List do not have horizontal scroll bar visible.
116  q->horizontalScrollBar()->setSliderSize(0.0);
117 
118  if (contentRect.height()-q->boundingRect().height() > 0) {
119  q->verticalScrollBar()->setSliderSize(contentRect.height()-q->boundingRect().height());
120  if (q->verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff &&
121  !q->verticalScrollBar()->isVisible()) {
122  q->verticalScrollBar()->show();
123  }
124  }
125  else if (q->verticalScrollBarPolicy() == Qt::ScrollBarAsNeeded ||
126  q->verticalScrollBarPolicy() == Qt::ScrollBarAlwaysOff) {
127  q->verticalScrollBar()->setSliderSize(0.0);
128  q->verticalScrollBar()->hide();
129  }
130  else {
131  q->verticalScrollBar()->setSliderSize(0.0);
132  }
133 
134  qreal pos = 0.0;
135  if ((m_content->boundingRect().height() - q->boundingRect().height()) != 0) {
136  qreal min = qMin(-contentRect.top(), m_content->pos().y());
137  qreal diff = contentRect.height() - listRect.height();
138  pos = qAbs(contentRect.top() + min) / diff;
139  }
140 
141  q->verticalScrollBar()->setSliderPosition(pos);
142  }
143 
145  {
146  Q_Q(SimpleListView);
147 
148  const bool caching = q->listItemCaching();
149  q->setListItemCaching(false);
150 
151  const QString defaultIcon = Theme::p()->pixmapPath()+"contact_default_icon.svg";
152  const int itemCount = m_layout->count();
153 
154  for (int i=0; i<itemCount; ++i) {
155  ListItem* item = static_cast<ListItem*>(m_layout->itemAt(i));
156 
157  // Update default icons
158  const QString filename = item->icon(ListItem::LeftIcon)->fileName();
159  if (filename.contains("contact_default_icon")) {
160  item->icon(ListItem::LeftIcon)->setFileName(defaultIcon);
161  }
162 
163  // Update status icons
164  QString statusIcon = item->icon(ListItem::RightIcon)->fileName();
165  const int index = statusIcon.indexOf("contact_status");
166  if (index != -1) {
167  statusIcon.remove(0, index);
168  item->icon(ListItem::RightIcon)->setFileName(Theme::p()->pixmapPath()+statusIcon);
169  }
170 
171  // Update fonts
175 
176  // Update list dividers
177  if (i%2) {
178  item->setBackgroundBrush(Theme::p()->listItemBackgroundBrushOdd());
179  item->setBackgroundOpacity(Theme::p()->listItemBackgroundOpacityOdd());
180  }
181  else {
182  item->setBackgroundBrush(Theme::p()->listItemBackgroundBrushEven());
183  item->setBackgroundOpacity(Theme::p()->listItemBackgroundOpacityEven());
184  }
185 
186  // Update borders
187  item->setBorderPen(Theme::p()->listItemBorderPen());
188  item->setRounding(Theme::p()->listItemRounding());
189 
190  // Update icons
195  item->icon(ListItem::LeftIcon)->setSmoothTransformationEnabled(Theme::p()->isIconSmoothTransformationEnabled(ListItem::LeftIcon));
196  item->icon(ListItem::RightIcon)->setSmoothTransformationEnabled(Theme::p()->isIconSmoothTransformationEnabled(ListItem::RightIcon));
197  }
198  q->setListItemCaching(caching);
199  }
200 
202  {
203  Q_Q(SimpleListView);
204 
205  const bool caching = q->listItemCaching();
206  q->setListItemCaching(false);
207 
208  const int itemCount = m_layout->count();
209 
210  for (int i=index; i<itemCount; ++i) {
211  ListItem* item = static_cast<ListItem*>(m_layout->itemAt(i));
212  if (i%2) {
213  item->setBackgroundBrush(Theme::p()->listItemBackgroundBrushOdd());
214  item->setBackgroundOpacity(Theme::p()->listItemBackgroundOpacityOdd());
215  }
216  else {
217  item->setBackgroundBrush(Theme::p()->listItemBackgroundBrushEven());
218  item->setBackgroundOpacity(Theme::p()->listItemBackgroundOpacityEven());
219  }
220  }
221 
222  q->setListItemCaching(caching);
223  }
224 
225  void setTwoColumns(const bool twoColumns)
226  {
227  if(twoColumns == m_twoColumns)
228  return;
229 
230  Q_Q(SimpleListView);
232 
233  bool cache = q->listItemCaching();
234  q->setListItemCaching(false);
235 
236  QList<QGraphicsLayoutItem *> moveditems;
237  if(twoColumns) {
238  int half = m_layout->count()/2;
239  for (int i = m_layout->count()-1; i>=half; --i) {
241  m_layout->removeAt(i);
242  moveditems.append(item);
243  }
244  for ( int i = 0; i < moveditems.count(); ++i)
245  m_layout->addItem(moveditems.at(i), i, 1);
246 
249  m_layout->setRowSpacing(0,0);
250  m_layout->setRowSpacing(1,0);
251  }
252  else {
253  int count = m_layout->count()/2;
254  for (int i = m_layout->count()-1; i>=0; --i) {
255  if (i >= count)
256  moveditems.append(m_layout->itemAt(i));
257  else
258  moveditems.insert(moveditems.begin(), m_layout->itemAt(i));
259  m_layout->removeAt(i);
260  }
261  for (int i = 0; i<moveditems.count(); ++i) {
262  m_layout->addItem(moveditems.at(i), m_layout->count(), 0);
263  }
264  }
265 
266  resizeContents(q->size());
268 
269  q->setListItemCaching(cache);
270  }
271 
272  bool twoColumns()
273  {
274  return m_twoColumns;
275  }
276 
282 };
283 
286  , d_ptr(new SimpleListViewPrivate(this))
287 {
289  setContentsMargins(0, 0, 0, 0);
290  verticalScrollBar()->hide();
292 }
293 
295 {
296  Q_D(SimpleListView);
297 
298  if (d->m_content) {
299  d->m_content->setParentItem(0);
300  }
301 
302  delete d_ptr;
303 }
304 
306 {
307  Q_D(SimpleListView);
308 
309  Q_ASSERT(item);
310 
311  insertItem(d->m_layout->count(), item);
312 }
313 
315 {
316  Q_D(SimpleListView);
317 
318  // Grid layout doe not have insert item method.
319  // We need to first remove all items, add new item and
320  // append old items to layout.
321  QList<QGraphicsLayoutItem *> moveditems;
322 
323  for (int i = d->m_layout->count()-1; i >= index; --i) {
324  moveditems.append(d->m_layout->itemAt(i));
325  d->m_layout->removeAt(i);
326  }
327  moveditems.append(item);
328 
329  for (int i = moveditems.count()-1; i>=0; --i) {
330  d->m_layout->addItem(moveditems.at(i), d->m_layout->count(), 0);
331  }
332 
334  item->setGraphicsEffect(cache);
335  cache->setEnabled(listItemCaching());
336 
337  d->resizeScrollBars();
338  d->updateListItemBackgrounds(index);
339 }
340 
342 {
343  Q_D(SimpleListView);
344 
345  QGraphicsWidget *item = 0;
346 
347  if (index >= 0 && d->m_layout->count() > index) {
348  QList<QGraphicsLayoutItem *> moveditems;
349  for (int i = d->m_layout->count()-1; i >=0; --i) {
350  if (index != i)
351  moveditems.insert(moveditems.begin(), d->m_layout->itemAt(i));
352  else {
353  item = static_cast<QGraphicsWidget*>(d->m_layout->itemAt(index));
354  item->setGraphicsEffect(0);
355  }
356 
357  d->m_layout->removeAt(i);
358  }
359 
360  for (int i = 0; i < moveditems.count(); ++i)
361  d->m_layout->addItem(moveditems.at(i), d->m_layout->count(), 0);
362  }
363  d->resizeScrollBars();
364  return item;
365 }
366 
368 {
369  Q_D(SimpleListView);
370 
371  QGraphicsWidget *item = 0;
372 
373  if (row >= 0 && d->m_layout->count() > row) {
374  item = static_cast<QGraphicsWidget*>(d->m_layout->itemAt(row));
375  }
376 
377  return item;
378 }
379 
381 {
382  Q_D(SimpleListView);
383  return d->m_layout->count();
384 }
385 
387 {
388  Q_D(const SimpleListView);
389  return d->m_listItemCaching;
390 }
391 
393 {
394  Q_D(SimpleListView);
395 
396  if (d->m_listItemCaching == enabled)
397  return;
398 
399  d->m_listItemCaching = enabled;
400 
401  for (int i = 0; i < d->m_layout->count(); ++i) {
402  ListItem *item = static_cast<ListItem*>(d->m_layout->itemAt(i));
403  ListItemCache *cache = static_cast<ListItemCache *>(
404  item->graphicsEffect());
405  cache->setEnabled(enabled);
406  }
407 }
408 
410 {
411  Q_D(SimpleListView);
412  Q_UNUSED(dx);
413  QRectF contentRect = d->m_content->boundingRect();
414  QRectF viewportRect = viewport()->boundingRect();
415  QPointF contentPos = d->m_content->pos();
416 
417  qreal newy = contentPos.y() - dy;
418  qreal miny = qMin(qreal(0.0), -(contentRect.height() - viewportRect.height()));
419 
420  if (newy < miny)
421  newy = miny;
422  else if (newy > 0)
423  newy = 0.0;
424 
425  d->m_content->setPos(contentPos.x(), newy);
426 }
427 
429 {
430  Q_D(SimpleListView);
431 
433  d->resizeContents(event->newSize());
434  d->resizeScrollBars();
435 }
436 
437 QSizeF SimpleListView::sizeHint(Qt::SizeHint which, const QSizeF & constraint) const
438 {
439  Q_D(const SimpleListView);
440 
441  if (which == Qt::PreferredSize)
442  return d->m_content->size();
443 
444  return AbstractScrollArea::sizeHint(which, constraint);
445 }
446 
448 {
449  Q_D(SimpleListView);
450 
451  d->updateListContents();
452  d->resizeScrollBars();
453 }
454 
455 void SimpleListView::setTwoColumns(const bool twoColumns)
456 {
457  Q_D(SimpleListView);
458  d->setTwoColumns(twoColumns);
459 }
460 
462 {
463  Q_D(SimpleListView);
464  return d->twoColumns();
465 }
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
ScrollBar * horizontalScrollBar() const
ScrollBar * verticalScrollBar() const
QGraphicsWidget * viewport() const
@ LeftIcon
Definition: listitem.h:56
@ RightIcon
Definition: listitem.h:57
@ ThirdPos
Definition: listitem.h:51
@ SecondPos
Definition: listitem.h:50
@ FirstPos
Definition: listitem.h:49
The QGraphicsGridLayout class provides a grid layout for managing widgets in Graphics View.
void setRowSpacing(int row, qreal spacing)
void removeAt(int index) override
void setColumnSpacing(int column, qreal spacing)
void addItem(QGraphicsLayoutItem *item, int row, int column, int rowSpan, int columnSpan, Qt::Alignment alignment=Qt::Alignment())
QGraphicsLayoutItem * itemAt(int row, int column) const
void setSpacing(qreal spacing)
int count() const override
void setRotation(qreal angle)
@ ItemClipsChildrenToShape
Definition: qgraphicsitem.h:90
void setParentItem(QGraphicsItem *parent)
QGraphicsItem * parentItem() const
void setContentsMargins(qreal left, qreal top, qreal right, qreal bottom)
The QGraphicsLayoutItem class can be inherited to allow your custom items to be managed by layouts.
void setSizePolicy(const QSizePolicy &policy)
qreal preferredHeight() const
bool enabled
whether the item is enabled or not
QPointF pos
the position of the item
QGraphicsObject * parent
the parent of the item
The QGraphicsSceneResizeEvent class provides events for widget resizing in the graphics view framewor...
The QGraphicsWidget class is the base class for all widget items in a QGraphicsScene.
void setLayout(QGraphicsLayout *layout)
void setContentsMargins(qreal left, qreal top, qreal right, qreal bottom)
void resize(const QSizeF &size)
QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint=QSizeF()) const override
QRectF boundingRect() const override
QSizeF size
the size of the widget
virtual void resizeEvent(QGraphicsSceneResizeEvent *event)
iterator insert(qsizetype i, parameter_type t)
Definition: qlist.h:499
const_reference at(qsizetype i) const noexcept
Definition: qlist.h:457
qsizetype count() const noexcept
Definition: qlist.h:415
iterator begin()
Definition: qlist.h:623
void append(parameter_type t)
Definition: qlist.h:469
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Definition: qobject.cpp:2772
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:242
constexpr qreal x() const noexcept
Definition: qpoint.h:361
constexpr qreal y() const noexcept
Definition: qpoint.h:366
The QRectF class defines a finite rectangle in the plane using floating point precision.
Definition: qrect.h:511
constexpr qreal height() const noexcept
Definition: qrect.h:741
constexpr qreal top() const noexcept
Definition: qrect.h:525
The QSizeF class defines the size of a two-dimensional object using floating point precision.
Definition: qsize.h:235
constexpr qreal width() const noexcept
Definition: qsize.h:349
constexpr qreal height() const noexcept
Definition: qsize.h:352
The QString class provides a Unicode character string.
Definition: qstring.h:388
static QString static QString qsizetype indexOf(QChar c, qsizetype from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.cpp:4197
QString & remove(qsizetype i, qsizetype len)
Definition: qstring.cpp:3252
void insertItem(int index, QGraphicsWidget *item)
QGraphicsWidget * itemAt(int row)
void setListItemCaching(bool enabled)
void addItem(QGraphicsWidget *item)
bool listItemCaching() const
virtual void scrollContentsBy(qreal dx, qreal dy)
SimpleListView(QGraphicsWidget *parent=nullptr)
virtual ~SimpleListView()
void resizeEvent(QGraphicsSceneResizeEvent *event)
QGraphicsWidget * takeItem(int row)
void setTwoColumns(const bool twoColumns)
QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
SimpleListView * q_ptr
SimpleListViewPrivate(SimpleListView *button)
void setTwoColumns(const bool twoColumns)
QGraphicsWidget * m_content
void updateListItemBackgrounds(int index)
void resizeContents(QSizeF s)
QGraphicsGridLayout * m_layout
QBrush listItemBackgroundBrushEven() const
Definition: theme.h:75
qreal iconRotation(const ListItem::IconItemPos iconPos) const
Definition: theme.h:85
@ ContactEmail
Definition: theme.h:53
@ ContactNumber
Definition: theme.h:52
@ ContactName
Definition: theme.h:51
QFont font(Fonts type) const
Definition: theme.h:72
qreal listItemBackgroundOpacityEven() const
Definition: theme.h:77
bool isIconOpacityEffectEnabled(const ListItem::IconItemPos iconPos) const
Definition: theme.h:83
bool isIconSmoothTransformationEnabled(const ListItem::IconItemPos iconPos) const
Definition: theme.h:86
QSize listItemRounding() const
Definition: theme.h:81
QString pixmapPath() const
Definition: theme.h:73
qreal listItemBackgroundOpacityOdd() const
Definition: theme.h:78
QBrush listItemBackgroundBrushOdd() const
Definition: theme.h:76
QPen listItemBorderPen() const
Definition: theme.h:80
static Theme * p()
Definition: theme.cpp:64
#define this
Definition: dialogs.cpp:56
QPushButton * button
[2]
QCache< int, Employee > cache
[0]
@ ScrollBarAlwaysOff
Definition: qnamespace.h:1278
@ ScrollBarAsNeeded
Definition: qnamespace.h:1277
SizeHint
Definition: qnamespace.h:1589
@ PreferredSize
Definition: qnamespace.h:1591
QT_END_INCLUDE_NAMESPACE typedef double qreal
Definition: qglobal.h:341
#define SLOT(a)
Definition: qobjectdefs.h:87
#define SIGNAL(a)
Definition: qobjectdefs.h:88
GLuint index
[2]
GLenum GLenum GLsizei count
GLenum GLenum GLsizei const GLuint GLboolean enabled
struct _cl_event * event
Definition: qopenglext.h:2998
GLdouble GLdouble GLdouble GLdouble q
Definition: qopenglext.h:259
GLenum GLenum GLsizei void * row
Definition: qopenglext.h:2747
GLdouble s
[6]
Definition: qopenglext.h:235
#define Q_ASSERT(cond)
Definition: qrandom.cpp:84
QPointF qAbs(const QPointF &p)
Definition: qscroller.cpp:119
Q_UNUSED(salary)
[21]
QGraphicsItem * item
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent