QtBase  v6.3.1
abstractitemview.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 #include <QGraphicsLayout>
29 
30 #include "abstractitemview.h"
31 #include "abstractviewitem.h"
32 #include "scrollbar.h"
33 
36  m_model(0),
37  m_rootIndex(),
38  m_container(0),
39  m_selectionModel(0),
40  m_currentIndex(),
41  m_scroller()
42 {
44 }
45 
46 /*virtual*/
48 {
49 }
50 
51 /*virtual*/
53 {
54  if (m_model == model || !model)
55  return;
56 
57  if (m_model) {
59  this, SLOT(_q_modelDestroyed()));
63  this, SLOT(rowsInserted(QModelIndex,int,int)));
65  this, SLOT(rowsRemoved(QModelIndex,int,int)));
67  this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int)));
69  this, SLOT(rowsAboutToBeInserted(QModelIndex,int,int)));
70  disconnect(m_model, SIGNAL(columnsInserted(QModelIndex,int,int)),
71  this, SLOT(columnsInserted(QModelIndex,int,int)));
72  disconnect(m_model, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)),
73  this, SLOT(columnsAboutToBeInserted(QModelIndex,int,int)));
74  disconnect(m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
75  this, SLOT(columnsRemoved(QModelIndex,int,int)));
76  disconnect(m_model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
77  this, SLOT(columnsAboutToBeRemoved(QModelIndex,int,int)));
78  disconnect(m_model, SIGNAL(modelReset()), this, SLOT(reset()));
79  disconnect(m_model, SIGNAL(layoutChanged()), this, SLOT(_q_layoutChanged()));
80 
81  m_model = 0;
82  }
83 
85 
88 
89  m_model = model;
90 
91  Q_ASSERT_X(m_model->index(0,0) == m_model->index(0,0),
92  "AbstractItemView::setModel",
93  "A model should return the exact same index "
94  "(including its internal id/pointer) when asked for it twice in a row.");
96  "AbstractItemView::setModel",
97  "The parent of a top level index should be invalid");
98 
99 
104  this, SLOT(rowsAboutToBeInserted(QModelIndex,int,int)));
106  this, SLOT(rowsInserted(QModelIndex,int,int)));
108  this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int)));
110  this, SLOT(rowsRemoved(QModelIndex,int,int)));
111  connect(m_model, SIGNAL(modelReset()), this, SLOT(reset()));
113 
115 
116  if (prototype && m_container) {
117  m_container->setItemPrototype(prototype);
118  m_container->reset();
119  }
120 }
121 
122 /*virtual*/
124 {
125  m_container = container;
126  m_container->setItemView(this);
128 
129  viewport()->setFlag(
131  m_scroller.setScrollable(this);
132  installEventFilter(&m_scroller);
133 }
134 
135 /*virtual*/
137 {
138  m_rootIndex = index;
139  // TODO fix this if we change index, container should be updated? Or do we need root index?
140 }
141 
142 /*virtual*/
144 {
145  if (m_model)
146  return m_model->rowCount(m_rootIndex);
147  return 0;
148 }
149 
150 /*virtual*/
152 {
153  return m_model;
154 }
155 
156 /*virtual*/
158 {
159  if (!m_model)
160  return QModelIndex();
161 
162  if (index.isValid())
163  return m_model->index(index.row() + 1, 0, m_rootIndex);
164  else
165  return m_model->index(0, 0, m_rootIndex);
166 }
167 
168 /*virtual*/
170 {
171  if (!m_model)
172  return QModelIndex();
173 
174  if (index.isValid())
175  return m_model->index(index.row() - 1, 0, m_rootIndex);
176  else
178 }
179 
180 /*virtual*/
182 {
183  if (prototype && m_container) {
184  m_container->setItemPrototype(prototype);
185  m_container->reset();
186  }
187 }
188 
190 {
191  if (smodel && smodel->model() != m_model) {
192  return;
193  }
194  if (m_selectionModel) {
197 
200 
201  delete m_selectionModel;
202  m_selectionModel = 0;
203  }
204 
205  m_selectionModel = smodel;
206 
207  if (m_selectionModel) {
212  }
213 }
214 
215 /*virtual*/
216 void AbstractItemView::currentIndexChanged(const QModelIndex &current, const QModelIndex &previous)
217 {
218  Q_UNUSED(previous);
219 
220  if (current != m_currentIndex)
221  m_currentIndex = current;
222 }
223 
224 /*virtual*/
226  const QItemSelection &deselected)
227 {
228  Q_UNUSED(selected);
229  Q_UNUSED(deselected);
230 }
231 
232 /*virtual*/
233 void AbstractItemView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
234 {
235  Q_UNUSED(topLeft);
236  Q_UNUSED(bottomRight);
237  // TODO implement if we like to edit view items.
238 }
239 
240 /*virtual*/
242 {
243  Q_UNUSED(index);
244  Q_UNUSED(start);
245  Q_UNUSED(end);
246 
247  // TODO implement
248 }
249 
250 /*virtual*/
252 {
253  Q_UNUSED(index);
254  Q_UNUSED(start);
255  Q_UNUSED(end);
256 }
257 
258 /*virtual*/
260 {
261  Q_UNUSED(parent);
262  Q_UNUSED(start);
263  Q_UNUSED(end);
264 
265  if (start <= m_currentIndex.row() && m_currentIndex.row() <= end) {
266  QModelIndex newCurrentIndex = m_model->index(start, 0, m_rootIndex);
267  if (!newCurrentIndex.isValid()) {
268  newCurrentIndex = m_model->index(qMax(0,start - 1), 0, m_rootIndex);
269  }
270 
271  if (m_selectionModel) {
273  }
274  }
275  for (int i = end; i >= start; --i) //The items are already removed from the model.
276  m_container->removeItem(QModelIndex()); // Indexes are already invalid.
277 }
278 
279 /*virtual*/
281 {
283 
284  if (m_container)
285  m_container->reset();
286 
288 
290 
291  if (sb)
292  sb->setSliderSize(0);
293 }
294 
295 /*virtual*/
297 {
298  if (!m_container)
299  return;
300 
301  for (int i = start; i <= end; ++i)
303 
305 }
306 
307 /*virtual*/
309 {
310  m_model = 0;
312  reset();
313 }
314 
315 /*virtual*/
317 {
318  m_container->reset();
319 }
320 
322 {
324  if (e && e->type()==QEvent::LayoutRequest) {
326  result = true;
327  }
328  if (e && e->type()==QEvent::GraphicsSceneResize) {
329  m_scroller.stopScrolling();
331 
334 
335  if (verticalScrollBar()->sliderPosition() > verticalScrollBar()->sliderSize())
337 
338  result = true;
339  }
340  return result;
341 }
342 
343 void AbstractItemView::setCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags selectionFlag)
344 {
345  if (m_selectionModel)
346  m_selectionModel->setCurrentIndex(index, selectionFlag);
347 }
348 
350 {
351  if (!m_container || !m_model)
352  return;
353 
356 
358 
359  if (sb) {
361  if (item) {
362  qreal oneItemH = item->size().height();
363  sb->setSliderSize(oneItemH*m_model->rowCount(m_rootIndex)-size().height());
364  }
367  sb->show();
368  }
369 }
370 
372 {
374 
375  if (!viewport() || !m_container || (m_container && m_container->itemCount() <= 0) ||
376  !m_model || (m_model && m_model->rowCount() <= 0) ||
378  return;
379 
380  qreal itemH = 1;
381 
383  if (item && item->size().height() > 1) {
384  itemH = item->size().height();
385  } else if (item && item->preferredHeight() > 1) {
386  itemH = item->preferredHeight();
387  }
388 
389  qreal vpx = m_container->pos().x();
390  qreal vpy = m_container->pos().y();
391 
392  if ((vpy+m_container->size().height()-dy > pos().y()+size().height()) &&
393  (qAbs(dy) < itemH) && (vpy-dy <= 0)) {
394  m_container->setPos(vpx, vpy-dy);
395  } else {
397  int startRow = m_model->index(vPos/itemH, 0).row();
398  int itemsInContainer = m_container->itemCount();
399 
400  for (int i = 0; i<itemsInContainer; ++i) {
401  AbstractViewItem *changedItem = m_container->itemAt(i);
402  changedItem->setModelIndex(m_model->index(startRow+i,0));
404  }
405 
406  qreal diff = vPos-startRow*itemH;
407 
408  if (diff < 0)
409  m_container->setPos(vpx, diff);
410  else
411  m_container->setPos(vpx, -diff);
412  }
413 }
414 
416 {
417  if (m_container)
419 }
420 
422 {
423  if (m_container)
425 }
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
virtual void addItem(const QModelIndex &index)
virtual int itemCount() const
virtual void setListItemCaching(const bool enabled, const int index)=0
virtual void removeItem(const QModelIndex &index)
virtual AbstractViewItem * itemAt(const int row) const
virtual void setItemView(AbstractItemView *view)
virtual void setItemPrototype(AbstractViewItem *ptype)
virtual QModelIndex nextIndex(const QModelIndex &index) const
virtual void setItemPrototype(AbstractViewItem *prototype)
virtual QAbstractItemModel * model() const
virtual void rowsRemoved(const QModelIndex &parent, int start, int end)
virtual QModelIndex previousIndex(const QModelIndex &index) const
virtual bool event(QEvent *e)
QAbstractItemModel * m_model
virtual void scrollContentsBy(qreal dx, qreal dy)
AbstractItemContainer * m_container
void setSelectionModel(QItemSelectionModel *smodel)
virtual void setRootIndex(const QModelIndex &index)
virtual void currentSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
virtual void rowsInserted(const QModelIndex &parent, int start, int end)
virtual void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
AbstractItemView(QGraphicsWidget *parent=nullptr)
virtual void setModel(QAbstractItemModel *model, AbstractViewItem *prototype)
virtual void setContainer(AbstractItemContainer *container)
virtual void rowsAboutToBeRemoved(const QModelIndex &index, int start, int end)
virtual int indexCount() const
virtual bool listItemCaching() const =0
void setCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags selectionFlag=QItemSelectionModel::NoUpdate)
virtual void layoutChanged()
virtual void modelDestroyed()
virtual void reset()
QItemSelectionModel * m_selectionModel
virtual void currentIndexChanged(const QModelIndex &current, const QModelIndex &previous)
QPersistentModelIndex m_rootIndex
QPersistentModelIndex m_currentIndex
virtual void rowsAboutToBeInserted(const QModelIndex &index, int start, int end)
virtual ~AbstractItemView()
virtual bool event(QEvent *e)
Qt::ScrollBarPolicy verticalScrollBarPolicy() const
ScrollBar * verticalScrollBar() const
QGraphicsWidget * viewport() const
virtual void scrollContentsBy(qreal dx, qreal dy)
void setModelIndex(const QModelIndex &index)
The QAbstractItemModel class provides the abstract interface for item model classes.
virtual Q_INVOKABLE int rowCount(const QModelIndex &parent=QModelIndex()) const =0
virtual Q_INVOKABLE QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const =0
The QEvent class is the base class of all event classes. Event objects contain event parameters.
Definition: qcoreevent.h:58
@ LayoutRequest
Definition: qcoreevent.h:125
@ GraphicsSceneResize
Definition: qcoreevent.h:238
@ ItemClipsChildrenToShape
Definition: qgraphicsitem.h:90
void setPos(const QPointF &pos)
void setParentItem(QGraphicsItem *parent)
void setFlag(GraphicsItemFlag flag, bool enabled=true)
bool isVisible() const
bool isActivated() const
qreal preferredHeight() const
QPointF pos
the position of the item
qreal y
the y position of the item
QGraphicsObject * parent
the parent of the item
The QGraphicsWidget class is the base class for all widget items in a QGraphicsScene.
void resize(const QSizeF &size)
QRectF boundingRect() const override
QGraphicsLayout * layout
The layout of the widget.
QSizeF size
the size of the widget
The QItemSelection class manages information about selected items in a model.
virtual void setCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags command)
QAbstractItemModel * model
The QModelIndex class is used to locate data in a data model.
constexpr int row() const noexcept
QModelIndex parent() const
constexpr bool isValid() const noexcept
void installEventFilter(QObject *filterObj)
Definition: qobject.cpp:2235
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Definition: qobject.cpp:2772
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
Definition: qobject.cpp:3048
void destroyed(QObject *=nullptr)
constexpr qreal x() const noexcept
Definition: qpoint.h:361
constexpr qreal y() const noexcept
Definition: qpoint.h:366
constexpr qreal height() const noexcept
Definition: qrect.h:741
constexpr qreal height() const noexcept
Definition: qsize.h:352
qreal sliderPosition() const
Definition: scrollbar.cpp:176
void setSliderSize(const qreal s)
Definition: scrollbar.cpp:161
void setSliderPosition(qreal pos)
Definition: scrollbar.cpp:167
void setScrollable(AbstractScrollArea *area)
Definition: scroller.cpp:264
void stopScrolling()
Definition: scroller.cpp:287
double e
@ ScrollBarAlwaysOff
Definition: qnamespace.h:1278
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
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLuint GLuint end
GLint GLsizei width
GLuint start
GLuint64EXT * result
[6]
Definition: qopenglext.h:10932
#define Q_ASSERT_X(cond, x, msg)
Definition: qrandom.cpp:85
QPointF qAbs(const QPointF &p)
Definition: qscroller.cpp:119
QSqlQueryModel * model
[16]
Q_UNUSED(salary)
[21]
QGraphicsItem * item
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent