qtableview.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/widgets/itemviews/qtableview.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
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 QtWidgets module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL$-
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 Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39-
40#include "qtableview.h"-
41-
42#ifndef QT_NO_TABLEVIEW-
43#include <qheaderview.h>-
44#include <qitemdelegate.h>-
45#include <qapplication.h>-
46#include <qpainter.h>-
47#include <qstyle.h>-
48#include <qsize.h>-
49#include <qevent.h>-
50#include <qbitarray.h>-
51#include <qscrollbar.h>-
52#include <qabstractbutton.h>-
53#include <private/qtableview_p.h>-
54#include <private/qheaderview_p.h>-
55#include <private/qscrollbar_p.h>-
56#ifndef QT_NO_ACCESSIBILITY-
57#include <qaccessible.h>-
58#endif-
59-
60QT_BEGIN_NAMESPACE-
61-
62/** \internal-
63 Add a span to the collection. the collection takes the ownership.-
64 */-
65void QSpanCollection::addSpan(QSpanCollection::Span *span)-
66{-
67 spans.append(span);-
68 Index::iterator it_y = index.lowerBound(-span->top());-
69 if (it_y == index.end() || it_y.key() != -span->top()) {-
70 //there is no spans that starts with the row in the index, so create a sublist for it.-
71 SubIndex sub_index;-
72 if (it_y != index.end()) {-
73 //the previouslist is the list of spans that sarts _before_ the row of the span.-
74 // and which may intersect this row.-
75 const SubIndex previousList = it_y.value();-
76 foreach(Span *s, previousList) {-
77 //If a subspans intersect the row, we need to split it into subspans-
78 if(s->bottom() >= span->top())-
79 sub_index.insert(-s->left(), s);-
80 }-
81 }-
82 it_y = index.insert(-span->top(), sub_index);-
83 //we will insert span to *it_y in the later loop-
84 }-
85-
86 //insert the span as supspan in all the lists that intesects the span-
87 while(-it_y.key() <= span->bottom()) {-
88 (*it_y).insert(-span->left(), span);-
89 if(it_y == index.begin())-
90 break;-
91 --it_y;-
92 }-
93}-
94-
95-
96/** \internal-
97* Has to be called after the height and width of a span is changed.-
98*-
99* old_height is the height before the change-
100*-
101* if the size of the span is now 0x0 the span will be deleted.-
102*/-
103void QSpanCollection::updateSpan(QSpanCollection::Span *span, int old_height)-
104{-
105 if (old_height < span->height()) {-
106 //add the span as subspan in all the lists that intersect the new covered columns-
107 Index::iterator it_y = index.lowerBound(-(span->top() + old_height - 1));-
108 Q_ASSERT(it_y != index.end()); //it_y must exist since the span is in the list-
109 while (-it_y.key() <= span->bottom()) {-
110 (*it_y).insert(-span->left(), span);-
111 if(it_y == index.begin())-
112 break;-
113 --it_y;-
114 }-
115 } else if (old_height > span->height()) {-
116 //remove the span from all the subspans lists that intersect the columns not covered anymore-
117 Index::iterator it_y = index.lowerBound(-qMax(span->bottom(), span->top())); //qMax useful if height is 0-
118 Q_ASSERT(it_y != index.end()); //it_y must exist since the span is in the list-
119 while (-it_y.key() <= span->top() + old_height -1) {-
120 if (-it_y.key() > span->bottom()) {-
121 int removed = (*it_y).remove(-span->left());-
122 Q_ASSERT(removed == 1); Q_UNUSED(removed);-
123 if (it_y->isEmpty()) {-
124 it_y = index.erase(it_y);-
125 }-
126 }-
127 if(it_y == index.begin())-
128 break;-
129 --it_y;-
130 }-
131 }-
132-
133 if (span->width() == 0 && span->height() == 0) {-
134 spans.removeOne(span);-
135 delete span;-
136 }-
137}-
138-
139/** \internal-
140 * \return a spans that spans over cell x,y (column,row) or 0 if there is none.-
141 */-
142QSpanCollection::Span *QSpanCollection::spanAt(int x, int y) const-
143{-
144 Index::const_iterator it_y = index.lowerBound(-y);-
145 if (it_y == index.end())-
146 return 0;-
147 SubIndex::const_iterator it_x = (*it_y).lowerBound(-x);-
148 if (it_x == (*it_y).end())-
149 return 0;-
150 Span *span = *it_x;-
151 if (span->right() >= x && span->bottom() >= y)-
152 return span;-
153 return 0;-
154}-
155-
156-
157/** \internal-
158* remove and deletes all spans inside the collection-
159*/-
160void QSpanCollection::clear()-
161{-
162 qDeleteAll(spans);-
163 index.clear();-
164 spans.clear();-
165}-
166-
167/** \internal-
168 * return a list to all the spans that spans over cells in the given rectangle-
169 */-
170QList<QSpanCollection::Span *> QSpanCollection::spansInRect(int x, int y, int w, int h) const-
171{-
172 QSet<Span *> list;-
173 Index::const_iterator it_y = index.lowerBound(-y);-
174 if(it_y == index.end())-
175 --it_y;-
176 while(-it_y.key() <= y + h) {-
177 SubIndex::const_iterator it_x = (*it_y).lowerBound(-x);-
178 if (it_x == (*it_y).end())-
179 --it_x;-
180 while(-it_x.key() <= x + w) {-
181 Span *s = *it_x;-
182 if (s->bottom() >= y && s->right() >= x)-
183 list << s;-
184 if (it_x == (*it_y).begin())-
185 break;-
186 --it_x;-
187 }-
188 if(it_y == index.begin())-
189 break;-
190 --it_y;-
191 }-
192 return list.toList();-
193}-
194-
195#undef DEBUG_SPAN_UPDATE-
196-
197#ifdef DEBUG_SPAN_UPDATE-
198QDebug operator<<(QDebug str, const QSpanCollection::Span &span)-
199{-
200 str << '(' << span.top() << ',' << span.left() << ',' << span.bottom() << ',' << span.right() << ')';-
201 return str;-
202}-
203#endif-
204-
205/** \internal-
206* Updates the span collection after row insertion.-
207*/-
208void QSpanCollection::updateInsertedRows(int start, int end)-
209{-
210#ifdef DEBUG_SPAN_UPDATE-
211 qDebug() << start << end << endl << index;-
212#endif-
213 if (spans.isEmpty())-
214 return;-
215-
216 int delta = end - start + 1;-
217#ifdef DEBUG_SPAN_UPDATE-
218 qDebug("Before");-
219#endif-
220 for (SpanList::iterator it = spans.begin(); it != spans.end(); ++it) {-
221 Span *span = *it;-
222#ifdef DEBUG_SPAN_UPDATE-
223 qDebug() << span << *span;-
224#endif-
225 if (span->m_bottom < start)-
226 continue;-
227 if (span->m_top >= start)-
228 span->m_top += delta;-
229 span->m_bottom += delta;-
230 }-
231-
232#ifdef DEBUG_SPAN_UPDATE-
233 qDebug("After");-
234 foreach (QSpanCollection::Span *span, spans)-
235 qDebug() << span << *span;-
236#endif-
237-
238 for (Index::iterator it_y = index.begin(); it_y != index.end(); ) {-
239 int y = -it_y.key();-
240 if (y < start) {-
241 ++it_y;-
242 continue;-
243 }-
244-
245 index.insert(-y - delta, it_y.value());-
246 it_y = index.erase(it_y);-
247 }-
248#ifdef DEBUG_SPAN_UPDATE-
249 qDebug() << index;-
250#endif-
251}-
252-
253/** \internal-
254* Updates the span collection after column insertion.-
255*/-
256void QSpanCollection::updateInsertedColumns(int start, int end)-
257{-
258#ifdef DEBUG_SPAN_UPDATE-
259 qDebug() << start << end << endl << index;-
260#endif-
261 if (spans.isEmpty())-
262 return;-
263-
264 int delta = end - start + 1;-
265#ifdef DEBUG_SPAN_UPDATE-
266 qDebug("Before");-
267#endif-
268 for (SpanList::iterator it = spans.begin(); it != spans.end(); ++it) {-
269 Span *span = *it;-
270#ifdef DEBUG_SPAN_UPDATE-
271 qDebug() << span << *span;-
272#endif-
273 if (span->m_right < start)-
274 continue;-
275 if (span->m_left >= start)-
276 span->m_left += delta;-
277 span->m_right += delta;-
278 }-
279-
280#ifdef DEBUG_SPAN_UPDATE-
281 qDebug("After");-
282 foreach (QSpanCollection::Span *span, spans)-
283 qDebug() << span << *span;-
284#endif-
285-
286 for (Index::iterator it_y = index.begin(); it_y != index.end(); ++it_y) {-
287 SubIndex &subindex = it_y.value();-
288 for (SubIndex::iterator it = subindex.begin(); it != subindex.end(); ) {-
289 int x = -it.key();-
290 if (x < start) {-
291 ++it;-
292 continue;-
293 }-
294 subindex.insert(-x - delta, it.value());-
295 it = subindex.erase(it);-
296 }-
297 }-
298#ifdef DEBUG_SPAN_UPDATE-
299 qDebug() << index;-
300#endif-
301}-
302-
303/** \internal-
304* Cleans a subindex from to be deleted spans. The update argument is used-
305* to move the spans inside the subindex, in case their anchor changed.-
306* \return true if no span in this subindex starts at y, and should thus be deleted.-
307*/-
308bool QSpanCollection::cleanSpanSubIndex(QSpanCollection::SubIndex &subindex, int y, bool update)-
309{-
310 if (subindex.isEmpty())-
311 return true;-
312-
313 bool should_be_deleted = true;-
314 SubIndex::iterator it = subindex.end();-
315 do {-
316 --it;-
317 int x = -it.key();-
318 Span *span = it.value();-
319 if (span->will_be_deleted) {-
320 it = subindex.erase(it);-
321 continue;-
322 }-
323 if (update && span->m_left != x) {-
324 subindex.insert(-span->m_left, span);-
325 it = subindex.erase(it);-
326 }-
327 if (should_be_deleted && span->m_top == y)-
328 should_be_deleted = false;-
329 } while (it != subindex.begin());-
330-
331 return should_be_deleted;-
332}-
333-
334/** \internal-
335* Updates the span collection after row removal.-
336*/-
337void QSpanCollection::updateRemovedRows(int start, int end)-
338{-
339#ifdef DEBUG_SPAN_UPDATE-
340 qDebug() << start << end << endl << index;-
341#endif-
342 if (spans.isEmpty())-
343 return;-
344-
345 SpanList spansToBeDeleted;-
346 int delta = end - start + 1;-
347#ifdef DEBUG_SPAN_UPDATE-
348 qDebug("Before");-
349#endif-
350 for (SpanList::iterator it = spans.begin(); it != spans.end(); ) {-
351 Span *span = *it;-
352#ifdef DEBUG_SPAN_UPDATE-
353 qDebug() << span << *span;-
354#endif-
355 if (span->m_bottom < start) {-
356 ++it;-
357 continue;-
358 }-
359 if (span->m_top < start) {-
360 if (span->m_bottom <= end)-
361 span->m_bottom = start - 1;-
362 else-
363 span->m_bottom -= delta;-
364 } else {-
365 if (span->m_bottom > end) {-
366 if (span->m_top <= end)-
367 span->m_top = start;-
368 else-
369 span->m_top -= delta;-
370 span->m_bottom -= delta;-
371 } else {-
372 span->will_be_deleted = true;-
373 }-
374 }-
375 if (span->m_top == span->m_bottom && span->m_left == span->m_right)-
376 span->will_be_deleted = true;-
377 if (span->will_be_deleted) {-
378 spansToBeDeleted.append(span);-
379 it = spans.erase(it);-
380 } else {-
381 ++it;-
382 }-
383 }-
384-
385#ifdef DEBUG_SPAN_UPDATE-
386 qDebug("After");-
387 foreach (QSpanCollection::Span *span, spans)-
388 qDebug() << span << *span;-
389#endif-
390 if (spans.isEmpty()) {-
391 qDeleteAll(spansToBeDeleted);-
392 index.clear();-
393 return;-
394 }-
395-
396 Index::iterator it_y = index.end();-
397 do {-
398 --it_y;-
399 int y = -it_y.key();-
400 SubIndex &subindex = it_y.value();-
401 if (y < start) {-
402 if (cleanSpanSubIndex(subindex, y))-
403 it_y = index.erase(it_y);-
404 } else if (y >= start && y <= end) {-
405 bool span_at_start = false;-
406 SubIndex spansToBeMoved;-
407 for (SubIndex::iterator it = subindex.begin(); it != subindex.end(); ++it) {-
408 Span *span = it.value();-
409 if (span->will_be_deleted)-
410 continue;-
411 if (!span_at_start && span->m_top == start)-
412 span_at_start = true;-
413 spansToBeMoved.insert(it.key(), span);-
414 }-
415-
416 if (y == start && span_at_start)-
417 subindex.clear();-
418 else-
419 it_y = index.erase(it_y);-
420-
421 if (span_at_start) {-
422 Index::iterator it_start;-
423 if (y == start)-
424 it_start = it_y;-
425 else {-
426 it_start = index.find(-start);-
427 if (it_start == index.end())-
428 it_start = index.insert(-start, SubIndex());-
429 }-
430 SubIndex &start_subindex = it_start.value();-
431 for (SubIndex::iterator it = spansToBeMoved.begin(); it != spansToBeMoved.end(); ++it)-
432 start_subindex.insert(it.key(), it.value());-
433 }-
434 } else {-
435 if (y == end + 1) {-
436 Index::iterator it_top = index.find(-y + delta);-
437 if (it_top == index.end())-
438 it_top = index.insert(-y + delta, SubIndex());-
439 for (SubIndex::iterator it = subindex.begin(); it != subindex.end(); ) {-
440 Span *span = it.value();-
441 if (!span->will_be_deleted)-
442 it_top.value().insert(it.key(), span);-
443 ++it;-
444 }-
445 } else {-
446 index.insert(-y + delta, subindex);-
447 }-
448 it_y = index.erase(it_y);-
449 }-
450 } while (it_y != index.begin());-
451-
452#ifdef DEBUG_SPAN_UPDATE-
453 qDebug() << index;-
454 qDebug("Deleted");-
455 foreach (QSpanCollection::Span *span, spansToBeDeleted)-
456 qDebug() << span << *span;-
457#endif-
458 qDeleteAll(spansToBeDeleted);-
459}-
460-
461/** \internal-
462* Updates the span collection after column removal.-
463*/-
464void QSpanCollection::updateRemovedColumns(int start, int end)-
465{-
466#ifdef DEBUG_SPAN_UPDATE-
467 qDebug() << start << end << endl << index;-
468#endif-
469 if (spans.isEmpty())-
470 return;-
471-
472 SpanList toBeDeleted;-
473 int delta = end - start + 1;-
474#ifdef DEBUG_SPAN_UPDATE-
475 qDebug("Before");-
476#endif-
477 for (SpanList::iterator it = spans.begin(); it != spans.end(); ) {-
478 Span *span = *it;-
479#ifdef DEBUG_SPAN_UPDATE-
480 qDebug() << span << *span;-
481#endif-
482 if (span->m_right < start) {-
483 ++it;-
484 continue;-
485 }-
486 if (span->m_left < start) {-
487 if (span->m_right <= end)-
488 span->m_right = start - 1;-
489 else-
490 span->m_right -= delta;-
491 } else {-
492 if (span->m_right > end) {-
493 if (span->m_left <= end)-
494 span->m_left = start;-
495 else-
496 span->m_left -= delta;-
497 span->m_right -= delta;-
498 } else {-
499 span->will_be_deleted = true;-
500 }-
501 }-
502 if (span->m_top == span->m_bottom && span->m_left == span->m_right)-
503 span->will_be_deleted = true;-
504 if (span->will_be_deleted) {-
505 toBeDeleted.append(span);-
506 it = spans.erase(it);-
507 } else {-
508 ++it;-
509 }-
510 }-
511-
512#ifdef DEBUG_SPAN_UPDATE-
513 qDebug("After");-
514 foreach (QSpanCollection::Span *span, spans)-
515 qDebug() << span << *span;-
516#endif-
517 if (spans.isEmpty()) {-
518 qDeleteAll(toBeDeleted);-
519 index.clear();-
520 return;-
521 }-
522-
523 for (Index::iterator it_y = index.begin(); it_y != index.end(); ) {-
524 int y = -it_y.key();-
525 if (cleanSpanSubIndex(it_y.value(), y, true))-
526 it_y = index.erase(it_y);-
527 else-
528 ++it_y;-
529 }-
530-
531#ifdef DEBUG_SPAN_UPDATE-
532 qDebug() << index;-
533 qDebug("Deleted");-
534 foreach (QSpanCollection::Span *span, toBeDeleted)-
535 qDebug() << span << *span;-
536#endif-
537 qDeleteAll(toBeDeleted);-
538}-
539-
540#ifdef QT_BUILD_INTERNAL-
541/*!-
542 \internal-
543 Checks whether the span index structure is self-consistent, and consistent with the spans list.-
544*/-
545bool QSpanCollection::checkConsistency() const-
546{-
547 for (Index::const_iterator it_y = index.begin(); it_y != index.end(); ++it_y) {-
548 int y = -it_y.key();-
549 const SubIndex &subIndex = it_y.value();-
550 for (SubIndex::const_iterator it = subIndex.begin(); it != subIndex.end(); ++it) {-
551 int x = -it.key();-
552 Span *span = it.value();-
553 if (!spans.contains(span) || span->left() != x-
554 || y < span->top() || y > span->bottom())-
555 return false;-
556 }-
557 }-
558-
559 foreach (const Span *span, spans) {-
560 if (span->width() < 1 || span->height() < 1-
561 || (span->width() == 1 && span->height() == 1))-
562 return false;-
563 for (int y = span->top(); y <= span->bottom(); ++y) {-
564 Index::const_iterator it_y = index.find(-y);-
565 if (it_y == index.end()) {-
566 if (y == span->top())-
567 return false;-
568 else-
569 continue;-
570 }-
571 const SubIndex &subIndex = it_y.value();-
572 SubIndex::const_iterator it = subIndex.find(-span->left());-
573 if (it == subIndex.end() || it.value() != span)-
574 return false;-
575 }-
576 }-
577 return true;-
578}-
579#endif-
580-
581class QTableCornerButton : public QAbstractButton-
582{-
583 Q_OBJECT-
584public:-
585 QTableCornerButton(QWidget *parent) : QAbstractButton(parent) {}-
586 void paintEvent(QPaintEvent*) Q_DECL_OVERRIDE {-
587 QStyleOptionHeader opt;-
588 opt.init(this);-
589 QStyle::State state = QStyle::State_None;-
590 if (isEnabled())-
591 state |= QStyle::State_Enabled;-
592 if (isActiveWindow())-
593 state |= QStyle::State_Active;-
594 if (isDown())-
595 state |= QStyle::State_Sunken;-
596 opt.state = state;-
597 opt.rect = rect();-
598 opt.position = QStyleOptionHeader::OnlyOneSection;-
599 QPainter painter(this);-
600 style()->drawControl(QStyle::CE_Header, &opt, &painter, this);-
601 }-
602};-
603-
604void QTableViewPrivate::init()-
605{-
606 Q_Q(QTableView);-
607-
608 q->setEditTriggers(editTriggers|QAbstractItemView::AnyKeyPressed);-
609-
610 QHeaderView *vertical = new QHeaderView(Qt::Vertical, q);-
611 vertical->setSectionsClickable(true);-
612 vertical->setHighlightSections(true);-
613 q->setVerticalHeader(vertical);-
614-
615 QHeaderView *horizontal = new QHeaderView(Qt::Horizontal, q);-
616 horizontal->setSectionsClickable(true);-
617 horizontal->setHighlightSections(true);-
618 q->setHorizontalHeader(horizontal);-
619-
620 tabKeyNavigation = true;-
621-
622 cornerWidget = new QTableCornerButton(q);-
623 cornerWidget->setFocusPolicy(Qt::NoFocus);-
624 QObject::connect(cornerWidget, SIGNAL(clicked()), q, SLOT(selectAll()));-
625}-
626-
627/*!-
628 \internal-
629 Trims away indices that are hidden in the treeview due to hidden horizontal or vertical sections.-
630*/-
631void QTableViewPrivate::trimHiddenSelections(QItemSelectionRange *range) const-
632{-
633 Q_ASSERT(range && range->isValid());-
634-
635 int top = range->top();-
636 int left = range->left();-
637 int bottom = range->bottom();-
638 int right = range->right();-
639-
640 while (bottom >= top && verticalHeader->isSectionHidden(bottom))-
641 --bottom;-
642 while (right >= left && horizontalHeader->isSectionHidden(right))-
643 --right;-
644-
645 if (top > bottom || left > right) { // everything is hidden-
646 *range = QItemSelectionRange();-
647 return;-
648 }-
649-
650 while (verticalHeader->isSectionHidden(top) && top <= bottom)-
651 ++top;-
652 while (horizontalHeader->isSectionHidden(left) && left <= right)-
653 ++left;-
654-
655 if (top > bottom || left > right) { // everything is hidden-
656 *range = QItemSelectionRange();-
657 return;-
658 }-
659-
660 QModelIndex bottomRight = model->index(bottom, right, range->parent());-
661 QModelIndex topLeft = model->index(top, left, range->parent());-
662 *range = QItemSelectionRange(topLeft, bottomRight);-
663}-
664-
665/*!-
666 \internal-
667 Sets the span for the cell at (\a row, \a column).-
668*/-
669void QTableViewPrivate::setSpan(int row, int column, int rowSpan, int columnSpan)-
670{-
671 if (Q_UNLIKELY(row < 0 || column < 0 || rowSpan <= 0 || columnSpan <= 0))) {
__builtin_expe... <= 0), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
672 qWarning("QTableView::setSpan: invalid span given: (%d, %d, %d, %d)",-
673 row, column, rowSpan, columnSpan);-
674 return;
never executed: return;
0
675 }-
676 QSpanCollection::Span *sp = spans.spanAt(column, row);-
677 if (sp) {
spDescription
TRUEnever evaluated
FALSEnever evaluated
0
678 if (sp->top() != row || sp->left() != column) {
sp->top() != rowDescription
TRUEnever evaluated
FALSEnever evaluated
sp->left() != columnDescription
TRUEnever evaluated
FALSEnever evaluated
0
679 qWarning("QTableView::setSpan: span cannot overlap");-
680 return;
never executed: return;
0
681 }-
682 if (rowSpan == 1 && columnSpan == 1) {
rowSpan == 1Description
TRUEnever evaluated
FALSEnever evaluated
columnSpan == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
683 rowSpan = columnSpan = 0;-
684 }
never executed: end of block
0
685 const int old_height = sp->height();-
686 sp->m_bottom = row + rowSpan - 1;-
687 sp->m_right = column + columnSpan - 1;-
688 spans.updateSpan(sp, old_height);-
689 return;
never executed: return;
0
690 } else if (Q_UNLIKELY(rowSpan == 1 && columnSpan == 1))) {
__builtin_expe... == 1), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
691 qWarning("QTableView::setSpan: single cell span won't be added");-
692 return;
never executed: return;
0
693 }-
694 sp = new QSpanCollection::Span(row, column, rowSpan, columnSpan);-
695 spans.addSpan(sp);-
696}
never executed: end of block
0
697-
698/*!-
699 \internal-
700 Gets the span information for the cell at (\a row, \a column).-
701*/-
702QSpanCollection::Span QTableViewPrivate::span(int row, int column) const-
703{-
704 QSpanCollection::Span *sp = spans.spanAt(column, row);-
705 if (sp)-
706 return *sp;-
707-
708 return QSpanCollection::Span(row, column, 1, 1);-
709}-
710-
711/*!-
712 \internal-
713 Returns the logical index of the last section that's part of the span.-
714*/-
715int QTableViewPrivate::sectionSpanEndLogical(const QHeaderView *header, int logical, int span) const-
716{-
717 int visual = header->visualIndex(logical);-
718 for (int i = 1; i < span; ) {-
719 if (++visual >= header->count())-
720 break;-
721 logical = header->logicalIndex(visual);-
722 ++i;-
723 }-
724 return logical;-
725}-
726-
727/*!-
728 \internal-
729 Returns the size of the span starting at logical index \a logical-
730 and spanning \a span sections.-
731*/-
732int QTableViewPrivate::sectionSpanSize(const QHeaderView *header, int logical, int span) const-
733{-
734 int endLogical = sectionSpanEndLogical(header, logical, span);-
735 return header->sectionPosition(endLogical)-
736 - header->sectionPosition(logical)-
737 + header->sectionSize(endLogical);-
738}-
739-
740/*!-
741 \internal-
742 Returns \c true if the section at logical index \a logical is part of the span-
743 starting at logical index \a spanLogical and spanning \a span sections;-
744 otherwise, returns \c false.-
745*/-
746bool QTableViewPrivate::spanContainsSection(const QHeaderView *header, int logical, int spanLogical, int span) const-
747{-
748 if (logical == spanLogical)-
749 return true; // it's the start of the span-
750 int visual = header->visualIndex(spanLogical);-
751 for (int i = 1; i < span; ) {-
752 if (++visual >= header->count())-
753 break;-
754 spanLogical = header->logicalIndex(visual);-
755 if (logical == spanLogical)-
756 return true;-
757 ++i;-
758 }-
759 return false;-
760}-
761-
762/*!-
763 \internal-
764 Returns the visual rect for the given \a span.-
765*/-
766QRect QTableViewPrivate::visualSpanRect(const QSpanCollection::Span &span) const-
767{-
768 Q_Q(const QTableView);-
769 // vertical-
770 int row = span.top();-
771 int rowp = verticalHeader->sectionViewportPosition(row);-
772 int rowh = rowSpanHeight(row, span.height());-
773 // horizontal-
774 int column = span.left();-
775 int colw = columnSpanWidth(column, span.width());-
776 if (q->isRightToLeft())-
777 column = span.right();-
778 int colp = horizontalHeader->sectionViewportPosition(column);-
779-
780 const int i = showGrid ? 1 : 0;-
781 if (q->isRightToLeft())-
782 return QRect(colp + i, rowp, colw - i, rowh - i);-
783 return QRect(colp, rowp, colw - i, rowh - i);-
784}-
785-
786/*!-
787 \internal-
788 Draws the spanning cells within rect \a area, and clips them off as-
789 preparation for the main drawing loop.-
790 \a drawn is a QBitArray of visualRowCountxvisualCoulumnCount which say if particular cell has been drawn-
791*/-
792void QTableViewPrivate::drawAndClipSpans(const QRegion &area, QPainter *painter,-
793 const QStyleOptionViewItem &option, QBitArray *drawn,-
794 int firstVisualRow, int lastVisualRow, int firstVisualColumn, int lastVisualColumn)-
795{-
796 bool alternateBase = false;-
797 QRegion region = viewport->rect();-
798-
799 QList<QSpanCollection::Span *> visibleSpans;-
800 bool sectionMoved = verticalHeader->sectionsMoved() || horizontalHeader->sectionsMoved();
verticalHeader...ectionsMoved()Description
TRUEnever evaluated
FALSEnever evaluated
horizontalHead...ectionsMoved()Description
TRUEnever evaluated
FALSEnever evaluated
0
801-
802 if (!sectionMoved) {
!sectionMovedDescription
TRUEnever evaluated
FALSEnever evaluated
0
803 visibleSpans = spans.spansInRect(logicalColumn(firstVisualColumn), logicalRow(firstVisualRow),-
804 lastVisualColumn - firstVisualColumn + 1, lastVisualRow - firstVisualRow + 1);-
805 } else {
never executed: end of block
0
806 QSet<QSpanCollection::Span *> set;-
807 for(int x = firstVisualColumn; x <= lastVisualColumn; x++)
x <= lastVisualColumnDescription
TRUEnever evaluated
FALSEnever evaluated
0
808 for(int y = firstVisualRow; y <= lastVisualRow; y++)
y <= lastVisualRowDescription
TRUEnever evaluated
FALSEnever evaluated
0
809 set.insert(spans.spanAt(x,y));
never executed: set.insert(spans.spanAt(x,y));
0
810 set.remove(0);-
811 visibleSpans = set.toList();-
812 }
never executed: end of block
0
813-
814 foreach (QSpanCollection::Span *span, visibleSpans) {-
815 int row = span->top();-
816 int col = span->left();-
817 QModelIndex index = model->index(row, col, root);-
818 if (!index.isValid())
!index.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
819 continue;
never executed: continue;
0
820 QRect rect = visualSpanRect(*span);-
821 rect.translate(scrollDelayOffset);-
822 if (!area.intersects(rect))
!area.intersects(rect)Description
TRUEnever evaluated
FALSEnever evaluated
0
823 continue;
never executed: continue;
0
824 QStyleOptionViewItem opt = option;-
825 opt.rect = rect;-
826 alternateBase = alternatingColors && (span->top() & 1);
alternatingColorsDescription
TRUEnever evaluated
FALSEnever evaluated
(span->top() & 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
827 if (alternateBase)opt.features|= QStyleOptionViewItem::Alternate;-
else
opt.features &= ~setFlag(QStyleOptionViewItem::Alternate;, alternateBase);
828 drawCell(painter, opt, index);-
829 region -= rect;-
830 for (int r = span->top(); r <= span->bottom(); ++r) {
r <= span->bottom()Description
TRUEnever evaluated
FALSEnever evaluated
0
831 const int vr = visualRow(r);-
832 if (vr < firstVisualRow || vr > lastVisualRow)
vr < firstVisualRowDescription
TRUEnever evaluated
FALSEnever evaluated
vr > lastVisualRowDescription
TRUEnever evaluated
FALSEnever evaluated
0
833 continue;
never executed: continue;
0
834 for (int c = span->left(); c <= span->right(); ++c) {
c <= span->right()Description
TRUEnever evaluated
FALSEnever evaluated
0
835 const int vc = visualColumn(c);-
836 if (vc < firstVisualColumn || vc > lastVisualColumn)
vc < firstVisualColumnDescription
TRUEnever evaluated
FALSEnever evaluated
vc > lastVisualColumnDescription
TRUEnever evaluated
FALSEnever evaluated
0
837 continue;
never executed: continue;
0
838 drawn->setBit((vr - firstVisualRow) * (lastVisualColumn - firstVisualColumn + 1)-
839 + vc - firstVisualColumn);-
840 }
never executed: end of block
0
841 }
never executed: end of block
0
842-
843 }
never executed: end of block
0
844 painter->setClipRegion(region);-
845}
never executed: end of block
0
846-
847/*!-
848 \internal-
849 Updates spans after row insertion.-
850*/-
851void QTableViewPrivate::_q_updateSpanInsertedRows(const QModelIndex &parent, int start, int end)-
852{-
853 Q_UNUSED(parent)-
854 spans.updateInsertedRows(start, end);-
855}-
856-
857/*!-
858 \internal-
859 Updates spans after column insertion.-
860*/-
861void QTableViewPrivate::_q_updateSpanInsertedColumns(const QModelIndex &parent, int start, int end)-
862{-
863 Q_UNUSED(parent)-
864 spans.updateInsertedColumns(start, end);-
865}-
866-
867/*!-
868 \internal-
869 Updates spans after row removal.-
870*/-
871void QTableViewPrivate::_q_updateSpanRemovedRows(const QModelIndex &parent, int start, int end)-
872{-
873 Q_UNUSED(parent)-
874 spans.updateRemovedRows(start, end);-
875}-
876-
877/*!-
878 \internal-
879 Updates spans after column removal.-
880*/-
881void QTableViewPrivate::_q_updateSpanRemovedColumns(const QModelIndex &parent, int start, int end)-
882{-
883 Q_UNUSED(parent)-
884 spans.updateRemovedColumns(start, end);-
885}-
886-
887/*!-
888 \internal-
889 Draws a table cell.-
890*/-
891void QTableViewPrivate::drawCell(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index)-
892{-
893 Q_Q(QTableView);-
894 QStyleOptionViewItem opt = option;-
895-
896 if (selectionModel && selectionModel->isSelected(index))-
897 opt.state |= QStyle::State_Selected;-
898 if (index == hover)-
899 opt.state |= QStyle::State_MouseOver;-
900 if (option.state & QStyle::State_Enabled) {-
901 QPalette::ColorGroup cg;-
902 if ((model->flags(index) & Qt::ItemIsEnabled) == 0) {-
903 opt.state &= ~QStyle::State_Enabled;-
904 cg = QPalette::Disabled;-
905 } else {-
906 cg = QPalette::Normal;-
907 }-
908 opt.palette.setCurrentColorGroup(cg);-
909 }-
910-
911 if (index == q->currentIndex()) {-
912 const bool focus = (q->hasFocus() || viewport->hasFocus()) && q->currentIndex().isValid();-
913 if (focus)-
914 opt.state |= QStyle::State_HasFocus;-
915 }-
916-
917 q->style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &opt, painter, q);-
918-
919 q->itemDelegate(index)->paint(painter, opt, index);-
920}-
921-
922/*!-
923 \internal-
924 Get sizeHint width for single Index (providing existing hint and style option)-
925*/-
926int QTableViewPrivate::widthHintForIndex(const QModelIndex &index, int hint, const QStyleOptionViewItem &option) const-
927{-
928 Q_Q(const QTableView);-
929 QWidget *editor = editorForIndex(index).widget.data();-
930 if (editor && persistent.contains(editor)) {-
931 hint = qMax(hint, editor->sizeHint().width());-
932 int min = editor->minimumSize().width();-
933 int max = editor->maximumSize().width();-
934 hint = qBound(min, hint, max);-
935 }-
936 hint = qMax(hint, q->itemDelegate(index)->sizeHint(option, index).width());-
937 return hint;-
938}-
939-
940/*!-
941 \internal-
942 Get sizeHint height for single Index (providing existing hint and style option)-
943*/-
944int QTableViewPrivate::heightHintForIndex(const QModelIndex &index, int hint, QStyleOptionViewItem &option) const-
945{-
946 Q_Q(const QTableView);-
947 QWidget *editor = editorForIndex(index).widget.data();-
948 if (editor && persistent.contains(editor)) {-
949 hint = qMax(hint, editor->sizeHint().height());-
950 int min = editor->minimumSize().height();-
951 int max = editor->maximumSize().height();-
952 hint = qBound(min, hint, max);-
953 }-
954-
955 if (wrapItemText) {// for wrapping boundaries-
956 option.rect.setY(q->rowViewportPosition(index.row()));-
957 int height = q->rowHeight(index.row());-
958 // if the option.height == 0 then q->itemDelegate(index)->sizeHint(option, index) will be wrong.-
959 // The option.height == 0 is used to conclude that the text is not wrapped, and hence it will-
960 // (exactly like widthHintForIndex) return a QSize with a long width (that we don't use) --
961 // and the height of the text if it was/is on one line.-
962 // What we want is a height hint for the current width (and we know that this section is not hidden)-
963 // Therefore we catch this special situation with:-
964 if (height == 0)-
965 height = 1;-
966 option.rect.setHeight(height);-
967 option.rect.setX(q->columnViewportPosition(index.column()));-
968 option.rect.setWidth(q->columnWidth(index.column()));-
969 }-
970 hint = qMax(hint, q->itemDelegate(index)->sizeHint(option, index).height());-
971 return hint;-
972}-
973-
974-
975/*!-
976 \class QTableView-
977-
978 \brief The QTableView class provides a default model/view-
979 implementation of a table view.-
980-
981 \ingroup model-view-
982 \ingroup advanced-
983 \inmodule QtWidgets-
984-
985 A QTableView implements a table view that displays items from a-
986 model. This class is used to provide standard tables that were-
987 previously provided by the QTable class, but using the more-
988 flexible approach provided by Qt's model/view architecture.-
989-
990 The QTableView class is one of the \l{Model/View Classes}-
991 and is part of Qt's \l{Model/View Programming}{model/view framework}.-
992-
993 QTableView implements the interfaces defined by the-
994 QAbstractItemView class to allow it to display data provided by-
995 models derived from the QAbstractItemModel class.-
996-
997 \section1 Navigation-
998-
999 You can navigate the cells in the table by clicking on a cell with the-
1000 mouse, or by using the arrow keys. Because QTableView enables-
1001 \l{QAbstractItemView::tabKeyNavigation}{tabKeyNavigation} by default, you-
1002 can also hit Tab and Backtab to move from cell to cell.-
1003-
1004 \section1 Visual Appearance-
1005-
1006 The table has a vertical header that can be obtained using the-
1007 verticalHeader() function, and a horizontal header that is available-
1008 through the horizontalHeader() function. The height of each row in the-
1009 table can be found by using rowHeight(); similarly, the width of-
1010 columns can be found using columnWidth(). Since both of these are plain-
1011 widgets, you can hide either of them using their hide() functions.-
1012-
1013 Rows and columns can be hidden and shown with hideRow(), hideColumn(),-
1014 showRow(), and showColumn(). They can be selected with selectRow()-
1015 and selectColumn(). The table will show a grid depending on the-
1016 \l showGrid property.-
1017-
1018 The items shown in a table view, like those in the other item views, are-
1019 rendered and edited using standard \l{QItemDelegate}{delegates}. However,-
1020 for some tasks it is sometimes useful to be able to insert widgets in a-
1021 table instead. Widgets are set for particular indexes with the-
1022 \l{QAbstractItemView::}{setIndexWidget()} function, and-
1023 later retrieved with \l{QAbstractItemView::}{indexWidget()}.-
1024-
1025 \table-
1026 \row \li \inlineimage qtableview-resized.png-
1027 \li By default, the cells in a table do not expand to fill the available space.-
1028-
1029 You can make the cells fill the available space by stretching the last-
1030 header section. Access the relevant header using horizontalHeader()-
1031 or verticalHeader() and set the header's \l{QHeaderView::}{stretchLastSection}-
1032 property.-
1033-
1034 To distribute the available space according to the space requirement of-
1035 each column or row, call the view's resizeColumnsToContents() or-
1036 resizeRowsToContents() functions.-
1037 \endtable-
1038-
1039 \section1 Coordinate Systems-
1040-
1041 For some specialized forms of tables it is useful to be able to-
1042 convert between row and column indexes and widget coordinates.-
1043 The rowAt() function provides the y-coordinate within the view of the-
1044 specified row; the row index can be used to obtain a corresponding-
1045 y-coordinate with rowViewportPosition(). The columnAt() and-
1046 columnViewportPosition() functions provide the equivalent conversion-
1047 operations between x-coordinates and column indexes.-
1048-
1049 \section1 Styles-
1050-
1051 QTableView is styled appropriately for each platform. The following images show-
1052 how it looks on three different platforms. Go to the \l{Qt Widget Gallery} to see-
1053 its appearance in other styles.-
1054-
1055 \table 100%-
1056 \row \li \inlineimage windowsvista-tableview.png Screenshot of a Windows Vista style table view-
1057 \li \inlineimage macintosh-tableview.png Screenshot of a Macintosh style table view-
1058 \li \inlineimage fusion-tableview.png Screenshot of a Fusion style table view-
1059 \row \li A \l{Windows Vista Style Widget Gallery}{Windows Vista style} table view.-
1060 \li A \l{Macintosh Style Widget Gallery}{Macintosh style} table view.-
1061 \li A \l{Fusion Style Widget Gallery}{Fusion style} table view.-
1062 \endtable-
1063-
1064 \sa QTableWidget, {View Classes}, QAbstractItemModel, QAbstractItemView,-
1065 {Chart Example}, {Pixelator Example}, {Table Model Example}-
1066*/-
1067-
1068/*!-
1069 Constructs a table view with a \a parent to represent the data.-
1070-
1071 \sa QAbstractItemModel-
1072*/-
1073-
1074QTableView::QTableView(QWidget *parent)-
1075 : QAbstractItemView(*new QTableViewPrivate, parent)-
1076{-
1077 Q_D(QTableView);-
1078 d->init();-
1079}-
1080-
1081/*!-
1082 \internal-
1083*/-
1084QTableView::QTableView(QTableViewPrivate &dd, QWidget *parent)-
1085 : QAbstractItemView(dd, parent)-
1086{-
1087 Q_D(QTableView);-
1088 d->init();-
1089}-
1090-
1091/*!-
1092 Destroys the table view.-
1093*/-
1094QTableView::~QTableView()-
1095{-
1096}-
1097-
1098/*!-
1099 \reimp-
1100*/-
1101QSize QTableView::viewportSizeHint() const-
1102{-
1103 Q_D(const QTableView);-
1104 QSize result( (d->verticalHeader->isHidden() ? 0 : d->verticalHeader->width()) + d->horizontalHeader->length(),-
1105 (d->horizontalHeader->isHidden() ? 0 : d->horizontalHeader->height()) + d->verticalHeader->length());-
1106 result += QSize(verticalScrollBar()->isVisible() ? verticalScrollBar()->width() : 0,-
1107 horizontalScrollBar()->isVisible() ? horizontalScrollBar()->height() : 0);-
1108 return result;-
1109}-
1110-
1111/*!-
1112 \reimp-
1113*/-
1114void QTableView::setModel(QAbstractItemModel *model)-
1115{-
1116 Q_D(QTableView);-
1117 if (model == d->model)-
1118 return;-
1119 //let's disconnect from the old model-
1120 if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel()) {-
1121 disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),-
1122 this, SLOT(_q_updateSpanInsertedRows(QModelIndex,int,int)));-
1123 disconnect(d->model, SIGNAL(columnsInserted(QModelIndex,int,int)),-
1124 this, SLOT(_q_updateSpanInsertedColumns(QModelIndex,int,int)));-
1125 disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),-
1126 this, SLOT(_q_updateSpanRemovedRows(QModelIndex,int,int)));-
1127 disconnect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)),-
1128 this, SLOT(_q_updateSpanRemovedColumns(QModelIndex,int,int)));-
1129 }-
1130 if (d->selectionModel) { // support row editing-
1131 disconnect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),-
1132 d->model, SLOT(submit()));-
1133 }-
1134 if (model) { //and connect to the new one-
1135 connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)),-
1136 this, SLOT(_q_updateSpanInsertedRows(QModelIndex,int,int)));-
1137 connect(model, SIGNAL(columnsInserted(QModelIndex,int,int)),-
1138 this, SLOT(_q_updateSpanInsertedColumns(QModelIndex,int,int)));-
1139 connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)),-
1140 this, SLOT(_q_updateSpanRemovedRows(QModelIndex,int,int)));-
1141 connect(model, SIGNAL(columnsRemoved(QModelIndex,int,int)),-
1142 this, SLOT(_q_updateSpanRemovedColumns(QModelIndex,int,int)));-
1143 }-
1144 d->verticalHeader->setModel(model);-
1145 d->horizontalHeader->setModel(model);-
1146 QAbstractItemView::setModel(model);-
1147}-
1148-
1149/*!-
1150 \reimp-
1151*/-
1152void QTableView::setRootIndex(const QModelIndex &index)-
1153{-
1154 Q_D(QTableView);-
1155 if (index == d->root) {-
1156 viewport()->update();-
1157 return;-
1158 }-
1159 d->verticalHeader->setRootIndex(index);-
1160 d->horizontalHeader->setRootIndex(index);-
1161 QAbstractItemView::setRootIndex(index);-
1162}-
1163-
1164/*!-
1165 \internal-
1166*/-
1167void QTableView::doItemsLayout()-
1168{-
1169 Q_D(QTableView);-
1170 QAbstractItemView::doItemsLayout();-
1171 d->verticalHeader->d_func()->setScrollOffset(verticalScrollBar(), verticalScrollMode());-
1172 if (!d->verticalHeader->updatesEnabled())-
1173 d->verticalHeader->setUpdatesEnabled(true);-
1174}-
1175-
1176/*!-
1177 \reimp-
1178*/-
1179void QTableView::setSelectionModel(QItemSelectionModel *selectionModel)-
1180{-
1181 Q_D(QTableView);-
1182 Q_ASSERT(selectionModel);-
1183 if (d->selectionModel) {-
1184 // support row editing-
1185 disconnect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),-
1186 d->model, SLOT(submit()));-
1187 }-
1188-
1189 d->verticalHeader->setSelectionModel(selectionModel);-
1190 d->horizontalHeader->setSelectionModel(selectionModel);-
1191 QAbstractItemView::setSelectionModel(selectionModel);-
1192-
1193 if (d->selectionModel) {-
1194 // support row editing-
1195 connect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),-
1196 d->model, SLOT(submit()));-
1197 }-
1198}-
1199-
1200/*!-
1201 Returns the table view's horizontal header.-
1202-
1203 \sa setHorizontalHeader(), verticalHeader(), QAbstractItemModel::headerData()-
1204*/-
1205QHeaderView *QTableView::horizontalHeader() const-
1206{-
1207 Q_D(const QTableView);-
1208 return d->horizontalHeader;-
1209}-
1210-
1211/*!-
1212 Returns the table view's vertical header.-
1213-
1214 \sa setVerticalHeader(), horizontalHeader(), QAbstractItemModel::headerData()-
1215*/-
1216QHeaderView *QTableView::verticalHeader() const-
1217{-
1218 Q_D(const QTableView);-
1219 return d->verticalHeader;-
1220}-
1221-
1222/*!-
1223 Sets the widget to use for the horizontal header to \a header.-
1224-
1225 \sa horizontalHeader(), setVerticalHeader()-
1226*/-
1227void QTableView::setHorizontalHeader(QHeaderView *header)-
1228{-
1229 Q_D(QTableView);-
1230-
1231 if (!header || header == d->horizontalHeader)-
1232 return;-
1233 if (d->horizontalHeader && d->horizontalHeader->parent() == this)-
1234 delete d->horizontalHeader;-
1235 d->horizontalHeader = header;-
1236 d->horizontalHeader->setParent(this);-
1237 d->horizontalHeader->d_func()->setAllowUserMoveOfSection0(true);-
1238 if (!d->horizontalHeader->model()) {-
1239 d->horizontalHeader->setModel(d->model);-
1240 if (d->selectionModel)-
1241 d->horizontalHeader->setSelectionModel(d->selectionModel);-
1242 }-
1243-
1244 connect(d->horizontalHeader,SIGNAL(sectionResized(int,int,int)),-
1245 this, SLOT(columnResized(int,int,int)));-
1246 connect(d->horizontalHeader, SIGNAL(sectionMoved(int,int,int)),-
1247 this, SLOT(columnMoved(int,int,int)));-
1248 connect(d->horizontalHeader, SIGNAL(sectionCountChanged(int,int)),-
1249 this, SLOT(columnCountChanged(int,int)));-
1250 connect(d->horizontalHeader, SIGNAL(sectionPressed(int)), this, SLOT(selectColumn(int)));-
1251 connect(d->horizontalHeader, SIGNAL(sectionEntered(int)), this, SLOT(_q_selectColumn(int)));-
1252 connect(d->horizontalHeader, SIGNAL(sectionHandleDoubleClicked(int)),-
1253 this, SLOT(resizeColumnToContents(int)));-
1254 connect(d->horizontalHeader, SIGNAL(geometriesChanged()), this, SLOT(updateGeometries()));-
1255-
1256 //update the sorting enabled states on the new header-
1257 setSortingEnabled(d->sortingEnabled);-
1258}-
1259-
1260/*!-
1261 Sets the widget to use for the vertical header to \a header.-
1262-
1263 \sa verticalHeader(), setHorizontalHeader()-
1264*/-
1265void QTableView::setVerticalHeader(QHeaderView *header)-
1266{-
1267 Q_D(QTableView);-
1268-
1269 if (!header || header == d->verticalHeader)-
1270 return;-
1271 if (d->verticalHeader && d->verticalHeader->parent() == this)-
1272 delete d->verticalHeader;-
1273 d->verticalHeader = header;-
1274 d->verticalHeader->setParent(this);-
1275 d->verticalHeader->d_func()->setAllowUserMoveOfSection0(true);-
1276 if (!d->verticalHeader->model()) {-
1277 d->verticalHeader->setModel(d->model);-
1278 if (d->selectionModel)-
1279 d->verticalHeader->setSelectionModel(d->selectionModel);-
1280 }-
1281-
1282 connect(d->verticalHeader, SIGNAL(sectionResized(int,int,int)),-
1283 this, SLOT(rowResized(int,int,int)));-
1284 connect(d->verticalHeader, SIGNAL(sectionMoved(int,int,int)),-
1285 this, SLOT(rowMoved(int,int,int)));-
1286 connect(d->verticalHeader, SIGNAL(sectionCountChanged(int,int)),-
1287 this, SLOT(rowCountChanged(int,int)));-
1288 connect(d->verticalHeader, SIGNAL(sectionPressed(int)), this, SLOT(selectRow(int)));-
1289 connect(d->verticalHeader, SIGNAL(sectionEntered(int)), this, SLOT(_q_selectRow(int)));-
1290 connect(d->verticalHeader, SIGNAL(sectionHandleDoubleClicked(int)),-
1291 this, SLOT(resizeRowToContents(int)));-
1292 connect(d->verticalHeader, SIGNAL(geometriesChanged()), this, SLOT(updateGeometries()));-
1293}-
1294-
1295/*!-
1296 \internal-
1297-
1298 Scroll the contents of the table view by (\a dx, \a dy).-
1299*/-
1300void QTableView::scrollContentsBy(int dx, int dy)-
1301{-
1302 Q_D(QTableView);-
1303-
1304 d->delayedAutoScroll.stop(); // auto scroll was canceled by the user scrolling-
1305-
1306 dx = isRightToLeft() ? -dx : dx;-
1307 if (dx) {-
1308 int oldOffset = d->horizontalHeader->offset();-
1309 d->horizontalHeader->d_func()->setScrollOffset(horizontalScrollBar(), horizontalScrollMode());-
1310 if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) {-
1311 int newOffset = d->horizontalHeader->offset();-
1312 dx = isRightToLeft() ? newOffset - oldOffset : oldOffset - newOffset;-
1313 }-
1314 }-
1315 if (dy) {-
1316 int oldOffset = d->verticalHeader->offset();-
1317 d->verticalHeader->d_func()->setScrollOffset(verticalScrollBar(), verticalScrollMode());-
1318 if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {-
1319 int newOffset = d->verticalHeader->offset();-
1320 dy = oldOffset - newOffset;-
1321 }-
1322 }-
1323 d->scrollContentsBy(dx, dy);-
1324-
1325 if (d->showGrid) {-
1326 //we need to update the first line of the previous top item in the view-
1327 //because it has the grid drawn if the header is invisible.-
1328 //It is strictly related to what's done at then end of the paintEvent-
1329 if (dy > 0 && d->horizontalHeader->isHidden() && d->verticalScrollMode == ScrollPerItem) {-
1330 d->viewport->update(0, dy, d->viewport->width(), dy);-
1331 }-
1332 if (dx > 0 && d->verticalHeader->isHidden() && d->horizontalScrollMode == ScrollPerItem) {-
1333 d->viewport->update(dx, 0, dx, d->viewport->height());-
1334 }-
1335 }-
1336}-
1337-
1338/*!-
1339 \reimp-
1340*/-
1341QStyleOptionViewItem QTableView::viewOptions() const-
1342{-
1343 QStyleOptionViewItem option = QAbstractItemView::viewOptions();-
1344 option.showDecorationSelected = true;-
1345 return option;-
1346}-
1347-
1348/*!-
1349 Paints the table on receipt of the given paint event \a event.-
1350*/-
1351void QTableView::paintEvent(QPaintEvent *event)-
1352{-
1353 Q_D(QTableView);-
1354 // setup temp variables for the painting-
1355 QStyleOptionViewItem option = d->viewOptionsV1();-
1356 const QPoint offset = d->scrollDelayOffset;-
1357 const bool showGrid = d->showGrid;-
1358 const int gridSize = showGrid ? 1 : 0;
showGridDescription
TRUEnever evaluated
FALSEnever evaluated
0
1359 const int gridHint = style()->styleHint(QStyle::SH_Table_GridLineColor, &option, this);-
1360 const QColor gridColor = static_cast<QRgb>(gridHint);-
1361 const QPen gridPen = QPen(gridColor, 0, d->gridStyle);-
1362 const QHeaderView *verticalHeader = d->verticalHeader;-
1363 const QHeaderView *horizontalHeader = d->horizontalHeader;-
1364 const bool alternate = d->alternatingColors;-
1365 const bool rightToLeft = isRightToLeft();-
1366-
1367 QPainter painter(d->viewport);-
1368-
1369 // if there's nothing to do, clear the area and return-
1370 if (horizontalHeader->count() == 0 || verticalHeader->count() == 0 || !d->itemDelegate)
horizontalHeader->count() == 0Description
TRUEnever evaluated
FALSEnever evaluated
verticalHeader->count() == 0Description
TRUEnever evaluated
FALSEnever evaluated
!d->itemDelegateDescription
TRUEnever evaluated
FALSEnever evaluated
0
1371 return;
never executed: return;
0
1372-
1373 uint x = horizontalHeader->length() - horizontalHeader->offset() - (rightToLeft ? 0 : 1);
rightToLeftDescription
TRUEnever evaluated
FALSEnever evaluated
0
1374 uint y = verticalHeader->length() - verticalHeader->offset() - 1;-
1375-
1376 const QRegion region = event->region().translated(offset);-
const QVector<QRect> rects = region.rects();//firstVisualRow is the visual index of the first visible row. lastVisualRow is the visual index of the last visible Row.
1377 //same goes for ...VisualColumn-
1378 int firstVisualRow = qMax(verticalHeader->visualIndexAt(0),0);-
1379 int lastVisualRow = verticalHeader->visualIndexAt(verticalHeader->viewport()->height());-
1380 if (lastVisualRow == -1)
lastVisualRow == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1381 lastVisualRow = d->model->rowCount(d->root) - 1;
never executed: lastVisualRow = d->model->rowCount(d->root) - 1;
0
1382-
1383 int firstVisualColumn = horizontalHeader->visualIndexAt(0);-
1384 int lastVisualColumn = horizontalHeader->visualIndexAt(horizontalHeader->viewport()->width());-
1385 if (rightToLeft)
rightToLeftDescription
TRUEnever evaluated
FALSEnever evaluated
0
1386 qSwap(firstVisualColumn, lastVisualColumn);
never executed: qSwap(firstVisualColumn, lastVisualColumn);
0
1387 if (firstVisualColumn == -1)
firstVisualColumn == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1388 firstVisualColumn = 0;
never executed: firstVisualColumn = 0;
0
1389 if (lastVisualColumn == -1)
lastVisualColumn == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1390 lastVisualColumn = horizontalHeader->count() - 1;
never executed: lastVisualColumn = horizontalHeader->count() - 1;
0
1391-
1392 QBitArray drawn((lastVisualRow - firstVisualRow + 1) * (lastVisualColumn - firstVisualColumn + 1));-
1393-
1394 const QRegion region = event->region().translated(offset);-
1395-
1396 if (d->hasSpans()) {
d->hasSpans()Description
TRUEnever evaluated
FALSEnever evaluated
0
1397 d->drawAndClipSpans(region, &painter, option, &drawn,-
1398 firstVisualRow, lastVisualRow, firstVisualColumn, lastVisualColumn);-
1399 }
never executed: end of block
0
1400-
1401 for (int i = 0; iconst QVector<QRect> rects = region.sizerects();-
1402 ++i) {-
QRectfor (auto dirtyArea =: rects.at(i);) {
1403 dirtyArea.setBottom(qMin(dirtyArea.bottom(), int(y)));-
1404 if (rightToLeft) {
rightToLeftDescription
TRUEnever evaluated
FALSEnever evaluated
0
1405 dirtyArea.setLeft(qMax(dirtyArea.left(), d->viewport->width() - int(x)));-
1406 } else {
never executed: end of block
0
1407 dirtyArea.setRight(qMin(dirtyArea.right(), int(x)));-
1408 }
never executed: end of block
0
1409-
1410 // get the horizontal start and end visual sections-
1411 int left = horizontalHeader->visualIndexAt(dirtyArea.left());-
1412 int right = horizontalHeader->visualIndexAt(dirtyArea.right());-
1413 if (rightToLeft)
rightToLeftDescription
TRUEnever evaluated
FALSEnever evaluated
0
1414 qSwap(left, right);
never executed: qSwap(left, right);
0
1415 if (left == -1) left = 0;
never executed: left = 0;
left == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1416 if (right == -1) right = horizontalHeader->count() - 1;
never executed: right = horizontalHeader->count() - 1;
right == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1417-
1418 // get the vertical start and end visual sections and if alternate color-
1419 int bottom = verticalHeader->visualIndexAt(dirtyArea.bottom());-
1420 if (bottom == -1) bottom = verticalHeader->count() - 1;
never executed: bottom = verticalHeader->count() - 1;
bottom == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1421 int top = 0;-
1422 bool alternateBase = false;-
1423 if (alternate && verticalHeader->sectionsHidden()) {
alternateDescription
TRUEnever evaluated
FALSEnever evaluated
verticalHeader...ctionsHidden()Description
TRUEnever evaluated
FALSEnever evaluated
0
1424 uint verticalOffset = verticalHeader->offset();-
1425 int row = verticalHeader->logicalIndex(top);-
1426 for (int y = 0;-
1427 ((uint)(y += verticalHeader->sectionSize(top)) <= verticalOffset) && (top < bottom);
((uint)(y += v...erticalOffset)Description
TRUEnever evaluated
FALSEnever evaluated
(top < bottom)Description
TRUEnever evaluated
FALSEnever evaluated
0
1428 ++top) {-
1429 row = verticalHeader->logicalIndex(top);-
1430 if (alternate && !verticalHeader->isSectionHidden(row))
alternateDescription
TRUEnever evaluated
FALSEnever evaluated
!verticalHeade...ionHidden(row)Description
TRUEnever evaluated
FALSEnever evaluated
0
1431 alternateBase = !alternateBase;
never executed: alternateBase = !alternateBase;
0
1432 }
never executed: end of block
0
1433 } else {
never executed: end of block
0
1434 top = verticalHeader->visualIndexAt(dirtyArea.top());-
1435 alternateBase = (top & 1) && alternate;
(top & 1)Description
TRUEnever evaluated
FALSEnever evaluated
alternateDescription
TRUEnever evaluated
FALSEnever evaluated
0
1436 }
never executed: end of block
0
1437 if (top == -1 || top > bottom)
top == -1Description
TRUEnever evaluated
FALSEnever evaluated
top > bottomDescription
TRUEnever evaluated
FALSEnever evaluated
0
1438 continue;
never executed: continue;
0
1439-
1440 // Paint each row item-
1441 for (int visualRowIndex = top; visualRowIndex <= bottom; ++visualRowIndex) {
visualRowIndex <= bottomDescription
TRUEnever evaluated
FALSEnever evaluated
0
1442 int row = verticalHeader->logicalIndex(visualRowIndex);-
1443 if (verticalHeader->isSectionHidden(row))
verticalHeader...ionHidden(row)Description
TRUEnever evaluated
FALSEnever evaluated
0
1444 continue;
never executed: continue;
0
1445 int rowY = rowViewportPosition(row);-
1446 rowY += offset.y();-
1447 int rowh = rowHeight(row) - gridSize;-
1448-
1449 // Paint each column item-
1450 for (int visualColumnIndex = left; visualColumnIndex <= right; ++visualColumnIndex) {
visualColumnIndex <= rightDescription
TRUEnever evaluated
FALSEnever evaluated
0
1451 int currentBit = (visualRowIndex - firstVisualRow) * (lastVisualColumn - firstVisualColumn + 1)-
1452 + visualColumnIndex - firstVisualColumn;-
1453-
1454 if (currentBit < 0 || currentBit >= drawn.size() || drawn.testBit(currentBit))
currentBit < 0Description
TRUEnever evaluated
FALSEnever evaluated
currentBit >= drawn.size()Description
TRUEnever evaluated
FALSEnever evaluated
drawn.testBit(currentBit)Description
TRUEnever evaluated
FALSEnever evaluated
0
1455 continue;
never executed: continue;
0
1456 drawn.setBit(currentBit);-
1457-
1458 int col = horizontalHeader->logicalIndex(visualColumnIndex);-
1459 if (horizontalHeader->isSectionHidden(col))
horizontalHead...ionHidden(col)Description
TRUEnever evaluated
FALSEnever evaluated
0
1460 continue;
never executed: continue;
0
1461 int colp = columnViewportPosition(col);-
1462 colp += offset.x();-
1463 int colw = columnWidth(col) - gridSize;-
1464-
1465 const QModelIndex index = d->model->index(row, col, d->root);-
1466 if (index.isValid()) {
index.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
1467 option.rect = QRect(colp + (showGrid && rightToLeft ? 1 : 0), rowY, colw, rowh);-
1468 if (alternate) {
alternateDescription
TRUEnever evaluated
FALSEnever evaluated
0
1469 if (alternateBase)
alternateBaseDescription
TRUEnever evaluated
FALSEnever evaluated
0
1470 option.features |= QStyleOptionViewItem::Alternate;
never executed: option.features |= QStyleOptionViewItem::Alternate;
0
1471 else-
1472 option.features &= ~QStyleOptionViewItem::Alternate;
never executed: option.features &= ~QStyleOptionViewItem::Alternate;
0
1473 }-
1474 d->drawCell(&painter, option, index);-
1475 }
never executed: end of block
0
1476 }
never executed: end of block
0
1477 alternateBase = !alternateBase && alternate;
!alternateBaseDescription
TRUEnever evaluated
FALSEnever evaluated
alternateDescription
TRUEnever evaluated
FALSEnever evaluated
0
1478 }
never executed: end of block
0
1479-
1480 if (showGrid) {
showGridDescription
TRUEnever evaluated
FALSEnever evaluated
0
1481 // Find the bottom right (the last rows/columns might be hidden)-
1482 while (verticalHeader->isSectionHidden(verticalHeader->logicalIndex(bottom))) --bottom;
never executed: --bottom;
verticalHeader...Index(bottom))Description
TRUEnever evaluated
FALSEnever evaluated
0
1483 QPen old = painter.pen();-
1484 painter.setPen(gridPen);-
1485 // Paint each row-
1486 for (int visualIndex = top; visualIndex <= bottom; ++visualIndex) {
visualIndex <= bottomDescription
TRUEnever evaluated
FALSEnever evaluated
0
1487 int row = verticalHeader->logicalIndex(visualIndex);-
1488 if (verticalHeader->isSectionHidden(row))
verticalHeader...ionHidden(row)Description
TRUEnever evaluated
FALSEnever evaluated
0
1489 continue;
never executed: continue;
0
1490 int rowY = rowViewportPosition(row);-
1491 rowY += offset.y();-
1492 int rowh = rowHeight(row) - gridSize;-
1493 painter.drawLine(dirtyArea.left(), rowY + rowh, dirtyArea.right(), rowY + rowh);-
1494 }
never executed: end of block
0
1495-
1496 // Paint each column-
1497 for (int h = left; h <= right; ++h) {
h <= rightDescription
TRUEnever evaluated
FALSEnever evaluated
0
1498 int col = horizontalHeader->logicalIndex(h);-
1499 if (horizontalHeader->isSectionHidden(col))
horizontalHead...ionHidden(col)Description
TRUEnever evaluated
FALSEnever evaluated
0
1500 continue;
never executed: continue;
0
1501 int colp = columnViewportPosition(col);-
1502 colp += offset.x();-
1503 if (!rightToLeft)
!rightToLeftDescription
TRUEnever evaluated
FALSEnever evaluated
0
1504 colp += columnWidth(col) - gridSize;
never executed: colp += columnWidth(col) - gridSize;
0
1505 painter.drawLine(colp, dirtyArea.top(), colp, dirtyArea.bottom());-
1506 }
never executed: end of block
0
1507-
1508 //draw the top & left grid lines if the headers are not visible.-
1509 //We do update this line when subsequent scroll happen (see scrollContentsBy)-
1510 if (horizontalHeader->isHidden() && verticalScrollMode() == ScrollPerItem)
horizontalHeader->isHidden()Description
TRUEnever evaluated
FALSEnever evaluated
verticalScroll... ScrollPerItemDescription
TRUEnever evaluated
FALSEnever evaluated
0
1511 painter.drawLine(dirtyArea.left(), 0, dirtyArea.right(), 0);
never executed: painter.drawLine(dirtyArea.left(), 0, dirtyArea.right(), 0);
0
1512 if (verticalHeader->isHidden() && horizontalScrollMode() == ScrollPerItem)
verticalHeader->isHidden()Description
TRUEnever evaluated
FALSEnever evaluated
horizontalScro... ScrollPerItemDescription
TRUEnever evaluated
FALSEnever evaluated
0
1513 painter.drawLine(0, dirtyArea.top(), 0, dirtyArea.bottom());
never executed: painter.drawLine(0, dirtyArea.top(), 0, dirtyArea.bottom());
0
1514 painter.setPen(old);-
1515 }
never executed: end of block
0
1516 }
never executed: end of block
0
1517-
1518#ifndef QT_NO_DRAGANDDROP-
1519 // Paint the dropIndicator-
1520 d->paintDropIndicator(&painter);-
1521#endif-
1522}
never executed: end of block
0
1523-
1524/*!-
1525 Returns the index position of the model item corresponding to the-
1526 table item at position \a pos in contents coordinates.-
1527*/-
1528QModelIndex QTableView::indexAt(const QPoint &pos) const-
1529{-
1530 Q_D(const QTableView);-
1531 d->executePostedLayout();-
1532 int r = rowAt(pos.y());-
1533 int c = columnAt(pos.x());-
1534 if (r >= 0 && c >= 0) {-
1535 if (d->hasSpans()) {-
1536 QSpanCollection::Span span = d->span(r, c);-
1537 r = span.top();-
1538 c = span.left();-
1539 }-
1540 return d->model->index(r, c, d->root);-
1541 }-
1542 return QModelIndex();-
1543}-
1544-
1545/*!-
1546 Returns the horizontal offset of the items in the table view.-
1547-
1548 Note that the table view uses the horizontal header section-
1549 positions to determine the positions of columns in the view.-
1550-
1551 \sa verticalOffset()-
1552*/-
1553int QTableView::horizontalOffset() const-
1554{-
1555 Q_D(const QTableView);-
1556 return d->horizontalHeader->offset();-
1557}-
1558-
1559/*!-
1560 Returns the vertical offset of the items in the table view.-
1561-
1562 Note that the table view uses the vertical header section-
1563 positions to determine the positions of rows in the view.-
1564-
1565 \sa horizontalOffset()-
1566*/-
1567int QTableView::verticalOffset() const-
1568{-
1569 Q_D(const QTableView);-
1570 return d->verticalHeader->offset();-
1571}-
1572-
1573/*!-
1574 \fn QModelIndex QTableView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers)-
1575-
1576 Moves the cursor in accordance with the given \a cursorAction, using the-
1577 information provided by the \a modifiers.-
1578-
1579 \sa QAbstractItemView::CursorAction-
1580*/-
1581QModelIndex QTableView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers)-
1582{-
1583 Q_D(QTableView);-
1584 Q_UNUSED(modifiers);-
1585-
1586 int bottom = d->model->rowCount(d->root) - 1;-
1587 // make sure that bottom is the bottommost *visible* row-
1588 while (bottom >= 0 && isRowHidden(d->logicalRow(bottom)))-
1589 --bottom;-
1590-
1591 int right = d->model->columnCount(d->root) - 1;-
1592-
1593 while (right >= 0 && isColumnHidden(d->logicalColumn(right)))-
1594 --right;-
1595-
1596 if (bottom == -1 || right == -1)-
1597 return QModelIndex(); // model is empty-
1598-
1599 QModelIndex current = currentIndex();-
1600-
1601 if (!current.isValid()) {-
1602 int row = 0;-
1603 int column = 0;-
1604 while (column < right && isColumnHidden(d->logicalColumn(column)))-
1605 ++column;-
1606 while (isRowHidden(d->logicalRow(row)) && row < bottom)-
1607 ++row;-
1608 d->visualCursor = QPoint(column, row);-
1609 return d->model->index(d->logicalRow(row), d->logicalColumn(column), d->root);-
1610 }-
1611-
1612 // Update visual cursor if current index has changed.-
1613 QPoint visualCurrent(d->visualColumn(current.column()), d->visualRow(current.row()));-
1614 if (visualCurrent != d->visualCursor) {-
1615 if (d->hasSpans()) {-
1616 QSpanCollection::Span span = d->span(current.row(), current.column());-
1617 if (span.top() > d->visualCursor.y() || d->visualCursor.y() > span.bottom()-
1618 || span.left() > d->visualCursor.x() || d->visualCursor.x() > span.right())-
1619 d->visualCursor = visualCurrent;-
1620 } else {-
1621 d->visualCursor = visualCurrent;-
1622 }-
1623 }-
1624-
1625 int visualRow = d->visualCursor.y();-
1626 if (visualRow > bottom)-
1627 visualRow = bottom;-
1628 Q_ASSERT(visualRow != -1);-
1629 int visualColumn = d->visualCursor.x();-
1630 if (visualColumn > right)-
1631 visualColumn = right;-
1632 Q_ASSERT(visualColumn != -1);-
1633-
1634 if (isRightToLeft()) {-
1635 if (cursorAction == MoveLeft)-
1636 cursorAction = MoveRight;-
1637 else if (cursorAction == MoveRight)-
1638 cursorAction = MoveLeft;-
1639 }-
1640-
1641 switch (cursorAction) {-
1642 case MoveUp: {-
1643 int originalRow = visualRow;-
1644#ifdef QT_KEYPAD_NAVIGATION-
1645 if (QApplication::keypadNavigationEnabled() && visualRow == 0)-
1646 visualRow = d->visualRow(model()->rowCount() - 1) + 1;-
1647 // FIXME? visualRow = bottom + 1;-
1648#endif-
1649 int r = d->logicalRow(visualRow);-
1650 int c = d->logicalColumn(visualColumn);-
1651 if (r != -1 && d->hasSpans()) {-
1652 QSpanCollection::Span span = d->span(r, c);-
1653 if (span.width() > 1 || span.height() > 1)-
1654 visualRow = d->visualRow(span.top());-
1655 }-
1656 while (visualRow >= 0) {-
1657 --visualRow;-
1658 r = d->logicalRow(visualRow);-
1659 c = d->logicalColumn(visualColumn);-
1660 if (r == -1 || (!isRowHidden(r) && d->isCellEnabled(r, c)))-
1661 break;-
1662 }-
1663 if (visualRow < 0)-
1664 visualRow = originalRow;-
1665 break;-
1666 }-
1667 case MoveDown: {-
1668 int originalRow = visualRow;-
1669 if (d->hasSpans()) {-
1670 QSpanCollection::Span span = d->span(current.row(), current.column());-
1671 visualRow = d->visualRow(d->rowSpanEndLogical(span.top(), span.height()));-
1672 }-
1673#ifdef QT_KEYPAD_NAVIGATION-
1674 if (QApplication::keypadNavigationEnabled() && visualRow >= bottom)-
1675 visualRow = -1;-
1676#endif-
1677 int r = d->logicalRow(visualRow);-
1678 int c = d->logicalColumn(visualColumn);-
1679 if (r != -1 && d->hasSpans()) {-
1680 QSpanCollection::Span span = d->span(r, c);-
1681 if (span.width() > 1 || span.height() > 1)-
1682 visualRow = d->visualRow(d->rowSpanEndLogical(span.top(), span.height()));-
1683 }-
1684 while (visualRow <= bottom) {-
1685 ++visualRow;-
1686 r = d->logicalRow(visualRow);-
1687 c = d->logicalColumn(visualColumn);-
1688 if (r == -1 || (!isRowHidden(r) && d->isCellEnabled(r, c)))-
1689 break;-
1690 }-
1691 if (visualRow > bottom)-
1692 visualRow = originalRow;-
1693 break;-
1694 }-
1695 case MovePrevious:-
1696 case MoveLeft: {-
1697 int originalRow = visualRow;-
1698 int originalColumn = visualColumn;-
1699 bool firstTime = true;-
1700 bool looped = false;-
1701 bool wrapped = false;-
1702 do {-
1703 int r = d->logicalRow(visualRow);-
1704 int c = d->logicalColumn(visualColumn);-
1705 if (firstTime && c != -1 && d->hasSpans()) {-
1706 firstTime = false;-
1707 QSpanCollection::Span span = d->span(r, c);-
1708 if (span.width() > 1 || span.height() > 1)-
1709 visualColumn = d->visualColumn(span.left());-
1710 }-
1711 while (visualColumn >= 0) {-
1712 --visualColumn;-
1713 r = d->logicalRow(visualRow);-
1714 c = d->logicalColumn(visualColumn);-
1715 if (r == -1 || c == -1 || (!isRowHidden(r) && !isColumnHidden(c) && d->isCellEnabled(r, c)))-
1716 break;-
1717 if (wrapped && (originalRow < visualRow || (originalRow == visualRow && originalColumn <= visualColumn))) {-
1718 looped = true;-
1719 break;-
1720 }-
1721 }-
1722 if (cursorAction == MoveLeft || visualColumn >= 0)-
1723 break;-
1724 visualColumn = right + 1;-
1725 if (visualRow == 0) {-
1726 wrapped = true;-
1727 visualRow = bottom;-
1728 } else {-
1729 --visualRow;-
1730 }-
1731 } while (!looped);-
1732 if (visualColumn < 0)-
1733 visualColumn = originalColumn;-
1734 break;-
1735 }-
1736 case MoveNext:-
1737 case MoveRight: {-
1738 int originalRow = visualRow;-
1739 int originalColumn = visualColumn;-
1740 bool firstTime = true;-
1741 bool looped = false;-
1742 bool wrapped = false;-
1743 do {-
1744 int r = d->logicalRow(visualRow);-
1745 int c = d->logicalColumn(visualColumn);-
1746 if (firstTime && c != -1 && d->hasSpans()) {-
1747 firstTime = false;-
1748 QSpanCollection::Span span = d->span(r, c);-
1749 if (span.width() > 1 || span.height() > 1)-
1750 visualColumn = d->visualColumn(d->columnSpanEndLogical(span.left(), span.width()));-
1751 }-
1752 while (visualColumn <= right) {-
1753 ++visualColumn;-
1754 r = d->logicalRow(visualRow);-
1755 c = d->logicalColumn(visualColumn);-
1756 if (r == -1 || c == -1 || (!isRowHidden(r) && !isColumnHidden(c) && d->isCellEnabled(r, c)))-
1757 break;-
1758 if (wrapped && (originalRow > visualRow || (originalRow == visualRow && originalColumn >= visualColumn))) {-
1759 looped = true;-
1760 break;-
1761 }-
1762 }-
1763 if (cursorAction == MoveRight || visualColumn <= right)-
1764 break;-
1765 visualColumn = -1;-
1766 if (visualRow == bottom) {-
1767 wrapped = true;-
1768 visualRow = 0;-
1769 } else {-
1770 ++visualRow;-
1771 }-
1772 } while (!looped);-
1773 if (visualColumn > right)-
1774 visualColumn = originalColumn;-
1775 break;-
1776 }-
1777 case MoveHome:-
1778 visualColumn = 0;-
1779 while (visualColumn < right && d->isVisualColumnHiddenOrDisabled(visualRow, visualColumn))-
1780 ++visualColumn;-
1781 if (modifiers & Qt::ControlModifier) {-
1782 visualRow = 0;-
1783 while (visualRow < bottom && d->isVisualRowHiddenOrDisabled(visualRow, visualColumn))-
1784 ++visualRow;-
1785 }-
1786 break;-
1787 case MoveEnd:-
1788 visualColumn = right;-
1789 if (modifiers & Qt::ControlModifier)-
1790 visualRow = bottom;-
1791 break;-
1792 case MovePageUp: {-
1793 int newRow = rowAt(visualRect(current).bottom() - d->viewport->height());-
1794 if (newRow == -1)-
1795 newRow = d->logicalRow(0);-
1796 return d->model->index(newRow, current.column(), d->root);-
1797 }-
1798 case MovePageDown: {-
1799 int newRow = rowAt(visualRect(current).top() + d->viewport->height());-
1800 if (newRow == -1)-
1801 newRow = d->logicalRow(bottom);-
1802 return d->model->index(newRow, current.column(), d->root);-
1803 }}-
1804-
1805 d->visualCursor = QPoint(visualColumn, visualRow);-
1806 int logicalRow = d->logicalRow(visualRow);-
1807 int logicalColumn = d->logicalColumn(visualColumn);-
1808 if (!d->model->hasIndex(logicalRow, logicalColumn, d->root))-
1809 return QModelIndex();-
1810-
1811 QModelIndex result = d->model->index(logicalRow, logicalColumn, d->root);-
1812 if (!d->isRowHidden(logicalRow) && !d->isColumnHidden(logicalColumn) && d->isIndexEnabled(result)) {-
1813 if (d->hasSpans()) {-
1814 QSpanCollection::Span span = d->span(result.row(), result.column());-
1815 if (span.width() > 1 || span.height() > 1) {-
1816 result = d->model->sibling(span.top(), span.left(), result);-
1817 }-
1818 }-
1819 return result;-
1820 }-
1821-
1822 return QModelIndex();-
1823}-
1824-
1825/*!-
1826 \fn void QTableView::setSelection(const QRect &rect,-
1827 QItemSelectionModel::SelectionFlags flags)-
1828-
1829 Selects the items within the given \a rect and in accordance with-
1830 the specified selection \a flags.-
1831*/-
1832void QTableView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command)-
1833{-
1834 Q_D(QTableView);-
1835 QModelIndex tl = indexAt(QPoint(isRightToLeft() ? qMax(rect.left(), rect.right())-
1836 : qMin(rect.left(), rect.right()), qMin(rect.top(), rect.bottom())));-
1837 QModelIndex br = indexAt(QPoint(isRightToLeft() ? qMin(rect.left(), rect.right()) :-
1838 qMax(rect.left(), rect.right()), qMax(rect.top(), rect.bottom())));-
1839 if (!d->selectionModel || !tl.isValid() || !br.isValid() || !d->isIndexEnabled(tl) || !d->isIndexEnabled(br))-
1840 return;-
1841-
1842 bool verticalMoved = verticalHeader()->sectionsMoved();-
1843 bool horizontalMoved = horizontalHeader()->sectionsMoved();-
1844-
1845 QItemSelection selection;-
1846-
1847 if (d->hasSpans()) {-
1848 bool expanded;-
1849 int top = qMin(d->visualRow(tl.row()), d->visualRow(br.row()));-
1850 int left = qMin(d->visualColumn(tl.column()), d->visualColumn(br.column()));-
1851 int bottom = qMax(d->visualRow(tl.row()), d->visualRow(br.row()));-
1852 int right = qMax(d->visualColumn(tl.column()), d->visualColumn(br.column()));-
1853 do {-
1854 expanded = false;-
1855 foreach (QSpanCollection::Span *it, d->spans.spans) {-
1856 const QSpanCollection::Span &span = *it;-
1857 int t = d->visualRow(span.top());-
1858 int l = d->visualColumn(span.left());-
1859 int b = d->visualRow(d->rowSpanEndLogical(span.top(), span.height()));-
1860 int r = d->visualColumn(d->columnSpanEndLogical(span.left(), span.width()));-
1861 if ((t > bottom) || (l > right) || (top > b) || (left > r))-
1862 continue; // no intersect-
1863 if (t < top) {-
1864 top = t;-
1865 expanded = true;-
1866 }-
1867 if (l < left) {-
1868 left = l;-
1869 expanded = true;-
1870 }-
1871 if (b > bottom) {-
1872 bottom = b;-
1873 expanded = true;-
1874 }-
1875 if (r > right) {-
1876 right = r;-
1877 expanded = true;-
1878 }-
1879 if (expanded)-
1880 break;-
1881 }-
1882 } while (expanded);-
1883 selection.reserve((right - left + 1) * (bottom - top + 1));-
1884 for (int horizontal = left; horizontal <= right; ++horizontal) {-
1885 int column = d->logicalColumn(horizontal);-
1886 for (int vertical = top; vertical <= bottom; ++vertical) {-
1887 int row = d->logicalRow(vertical);-
1888 QModelIndex index = d->model->index(row, column, d->root);-
1889 selection.append(QItemSelectionRange(index));-
1890 }-
1891 }-
1892 } else if (verticalMoved && horizontalMoved) {-
1893 int top = d->visualRow(tl.row());-
1894 int left = d->visualColumn(tl.column());-
1895 int bottom = d->visualRow(br.row());-
1896 int right = d->visualColumn(br.column());-
1897 selection.reserve((right - left + 1) * (bottom - top + 1));-
1898 for (int horizontal = left; horizontal <= right; ++horizontal) {-
1899 int column = d->logicalColumn(horizontal);-
1900 for (int vertical = top; vertical <= bottom; ++vertical) {-
1901 int row = d->logicalRow(vertical);-
1902 QModelIndex index = d->model->index(row, column, d->root);-
1903 selection.append(QItemSelectionRange(index));-
1904 }-
1905 }-
1906 } else if (horizontalMoved) {-
1907 int left = d->visualColumn(tl.column());-
1908 int right = d->visualColumn(br.column());-
1909 selection.reserve(right - left + 1);-
1910 for (int visual = left; visual <= right; ++visual) {-
1911 int column = d->logicalColumn(visual);-
1912 QModelIndex topLeft = d->model->index(tl.row(), column, d->root);-
1913 QModelIndex bottomRight = d->model->index(br.row(), column, d->root);-
1914 selection.append(QItemSelectionRange(topLeft, bottomRight));-
1915 }-
1916 } else if (verticalMoved) {-
1917 int top = d->visualRow(tl.row());-
1918 int bottom = d->visualRow(br.row());-
1919 selection.reserve(bottom - top + 1);-
1920 for (int visual = top; visual <= bottom; ++visual) {-
1921 int row = d->logicalRow(visual);-
1922 QModelIndex topLeft = d->model->index(row, tl.column(), d->root);-
1923 QModelIndex bottomRight = d->model->index(row, br.column(), d->root);-
1924 selection.append(QItemSelectionRange(topLeft, bottomRight));-
1925 }-
1926 } else { // nothing moved-
1927 QItemSelectionRange range(tl, br);-
1928 if (!range.isEmpty())-
1929 selection.append(range);-
1930 }-
1931-
1932 d->selectionModel->select(selection, command);-
1933}-
1934-
1935/*!-
1936 \internal-
1937-
1938 Returns the rectangle from the viewport of the items in the given-
1939 \a selection.-
1940-
1941 Since 4.7, the returned region only contains rectangles intersecting-
1942 (or included in) the viewport.-
1943*/-
1944QRegion QTableView::visualRegionForSelection(const QItemSelection &selection) const-
1945{-
1946 Q_D(const QTableView);-
1947-
1948 if (selection.isEmpty())
selection.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
1949 return QRegion();
never executed: return QRegion();
0
1950-
1951 QRegion selectionRegion;-
1952 const QRect &viewportRect = d->viewport->rect();-
1953 bool verticalMoved = verticalHeader()->sectionsMoved();-
1954 bool horizontalMoved = horizontalHeader()->sectionsMoved();-
1955-
1956 if ((verticalMoved && horizontalMoved) || (d->hasSpans() && (verticalMoved || horizontalMoved))) {
verticalMovedDescription
TRUEnever evaluated
FALSEnever evaluated
horizontalMovedDescription
TRUEnever evaluated
FALSEnever evaluated
d->hasSpans()Description
TRUEnever evaluated
FALSEnever evaluated
verticalMovedDescription
TRUEnever evaluated
FALSEnever evaluated
horizontalMovedDescription
TRUEnever evaluated
FALSEnever evaluated
0
1957 for (int i = 0; i <const auto &range : selection.count(); ++i) {-
1958 QItemSelectionRange range = selection.at(i);if (range.parent() != d->root || !range.isValid())
range.parent() != d->rootDescription
TRUEnever evaluated
FALSEnever evaluated
!range.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
1959 continue;
never executed: continue;
0
1960 for (int r = range.top(); r <= range.bottom(); ++r)
r <= range.bottom()Description
TRUEnever evaluated
FALSEnever evaluated
0
1961 for (int c = range.left(); c <= range.right(); ++c) {
c <= range.right()Description
TRUEnever evaluated
FALSEnever evaluated
0
1962 const QRect &rangeRect = visualRect(d->model->index(r, c, d->root));-
1963 if (viewportRect.intersects(rangeRect))
viewportRect.i...cts(rangeRect)Description
TRUEnever evaluated
FALSEnever evaluated
0
1964 selectionRegion += rangeRect;
never executed: selectionRegion += rangeRect;
0
1965 }
never executed: end of block
0
1966 }
never executed: end of block
0
1967 } else if (horizontalMoved) {
never executed: end of block
horizontalMovedDescription
TRUEnever evaluated
FALSEnever evaluated
0
1968 for (int i = 0; i <const auto &range : selection.count(); ++i) {-
1969 QItemSelectionRange range = selection.at(i);if (range.parent() != d->root || !range.isValid())
range.parent() != d->rootDescription
TRUEnever evaluated
FALSEnever evaluated
!range.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
1970 continue;
never executed: continue;
0
1971 int top = rowViewportPosition(range.top());-
1972 int bottom = rowViewportPosition(range.bottom()) + rowHeight(range.bottom());-
1973 if (top > bottom)
top > bottomDescription
TRUEnever evaluated
FALSEnever evaluated
0
1974 qSwap<int>(top, bottom);
never executed: qSwap<int>(top, bottom);
0
1975 int height = bottom - top;-
1976 for (int c = range.left(); c <= range.right(); ++c) {
c <= range.right()Description
TRUEnever evaluated
FALSEnever evaluated
0
1977 const QRect rangeRect(columnViewportPosition(c), top, columnWidth(c), height);-
1978 if (viewportRect.intersects(rangeRect))
viewportRect.i...cts(rangeRect)Description
TRUEnever evaluated
FALSEnever evaluated
0
1979 selectionRegion += rangeRect;
never executed: selectionRegion += rangeRect;
0
1980 }
never executed: end of block
0
1981 }
never executed: end of block
0
1982 } else if (verticalMoved) {
never executed: end of block
verticalMovedDescription
TRUEnever evaluated
FALSEnever evaluated
0
1983 for (int i = 0; i <const auto &range : selection.count(); ++i) {-
1984 QItemSelectionRange range = selection.at(i);if (range.parent() != d->root || !range.isValid())
range.parent() != d->rootDescription
TRUEnever evaluated
FALSEnever evaluated
!range.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
1985 continue;
never executed: continue;
0
1986 int left = columnViewportPosition(range.left());-
1987 int right = columnViewportPosition(range.right()) + columnWidth(range.right());-
1988 if (left > right)
left > rightDescription
TRUEnever evaluated
FALSEnever evaluated
0
1989 qSwap<int>(left, right);
never executed: qSwap<int>(left, right);
0
1990 int width = right - left;-
1991 for (int r = range.top(); r <= range.bottom(); ++r) {
r <= range.bottom()Description
TRUEnever evaluated
FALSEnever evaluated
0
1992 const QRect rangeRect(left, rowViewportPosition(r), width, rowHeight(r));-
1993 if (viewportRect.intersects(rangeRect))
viewportRect.i...cts(rangeRect)Description
TRUEnever evaluated
FALSEnever evaluated
0
1994 selectionRegion += rangeRect;
never executed: selectionRegion += rangeRect;
0
1995 }
never executed: end of block
0
1996 }
never executed: end of block
0
1997 } else { // nothing moved
never executed: end of block
0
1998 const int gridAdjust = showGrid() ? 1 : 0;
showGrid()Description
TRUEnever evaluated
FALSEnever evaluated
0
1999 for (int i = 0; i <auto range : selection.count(); ++i) {-
2000 QItemSelectionRange range = selection.at(i);if (range.parent() != d->root || !range.isValid())
range.parent() != d->rootDescription
TRUEnever evaluated
FALSEnever evaluated
!range.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
2001 continue;
never executed: continue;
0
2002 d->trimHiddenSelections(&range);-
2003-
2004 const int rtop = rowViewportPosition(range.top());-
2005 const int rbottom = rowViewportPosition(range.bottom()) + rowHeight(range.bottom());-
2006 int rleft;-
2007 int rright;-
2008 if (isLeftToRight()) {
isLeftToRight()Description
TRUEnever evaluated
FALSEnever evaluated
0
2009 rleft = columnViewportPosition(range.left());-
2010 rright = columnViewportPosition(range.right()) + columnWidth(range.right());-
2011 } else {
never executed: end of block
0
2012 rleft = columnViewportPosition(range.right());-
2013 rright = columnViewportPosition(range.left()) + columnWidth(range.left());-
2014 }
never executed: end of block
0
2015 const QRect rangeRect(QPoint(rleft, rtop), QPoint(rright - 1 - gridAdjust, rbottom - 1 - gridAdjust));-
2016 if (viewportRect.intersects(rangeRect))
viewportRect.i...cts(rangeRect)Description
TRUEnever evaluated
FALSEnever evaluated
0
2017 selectionRegion += rangeRect;
never executed: selectionRegion += rangeRect;
0
2018 if (d->hasSpans()) {
d->hasSpans()Description
TRUEnever evaluated
FALSEnever evaluated
0
2019 foreach (QSpanCollection::Span *s,const auto spansInRect = d->spans.spansInRect(range.left(), range.top(), range.width(), range.height()))());-
2020 for (QSpanCollection::Span *s : spansInRect) {-
2021 if (range.contains(s->top(), s->left(), range.parent())) {
range.contains...ange.parent())Description
TRUEnever evaluated
FALSEnever evaluated
0
2022 const QRect &visualSpanRect = d->visualSpanRect(*s);-
2023 if (viewportRect.intersects(visualSpanRect))
viewportRect.i...isualSpanRect)Description
TRUEnever evaluated
FALSEnever evaluated
0
2024 selectionRegion += visualSpanRect;
never executed: selectionRegion += visualSpanRect;
0
2025 }
never executed: end of block
0
2026 }
never executed: end of block
0
2027 }
never executed: end of block
0
2028 }
never executed: end of block
0
2029 }
never executed: end of block
0
2030-
2031 return selectionRegion;
never executed: return selectionRegion;
0
2032}-
2033-
2034-
2035/*!-
2036 \reimp-
2037*/-
2038QModelIndexList QTableView::selectedIndexes() const-
2039{-
2040 Q_D(const QTableView);-
2041 QModelIndexList viewSelected;-
2042 QModelIndexList modelSelected;-
2043 if (d->selectionModel)-
2044 modelSelected = d->selectionModel->selectedIndexes();-
2045 for (int i = 0; i < modelSelected.count(); ++i) {-
2046 QModelIndex index = modelSelected.at(i);-
2047 if (!isIndexHidden(index) && index.parent() == d->root)-
2048 viewSelected.append(index);-
2049 }-
2050 return viewSelected;-
2051}-
2052-
2053-
2054/*!-
2055 This slot is called whenever rows are added or deleted. The-
2056 previous number of rows is specified by \a oldCount, and the new-
2057 number of rows is specified by \a newCount.-
2058*/-
2059void QTableView::rowCountChanged(int oldCount, int newCount )-
2060{-
2061 Q_D(QTableView);-
2062 //when removing rows, we need to disable updates for the header until the geometries have been-
2063 //updated and the offset has been adjusted, or we risk calling paintSection for all the sections-
2064 if (newCount < oldCount)-
2065 d->verticalHeader->setUpdatesEnabled(false);-
2066 d->doDelayedItemsLayout();-
2067}-
2068-
2069/*!-
2070 This slot is called whenever columns are added or deleted. The-
2071 previous number of columns is specified by \a oldCount, and the new-
2072 number of columns is specified by \a newCount.-
2073*/-
2074void QTableView::columnCountChanged(int, int)-
2075{-
2076 Q_D(QTableView);-
2077 updateGeometries();-
2078 if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem)-
2079 d->horizontalHeader->setOffsetToSectionPosition(horizontalScrollBar()->value());-
2080 else-
2081 d->horizontalHeader->setOffset(horizontalScrollBar()->value());-
2082 d->viewport->update();-
2083}-
2084-
2085/*!-
2086 \reimp-
2087*/-
2088void QTableView::updateGeometries()-
2089{-
2090 Q_D(QTableView);-
2091 if (d->geometryRecursionBlock)
d->geometryRecursionBlockDescription
TRUEnever evaluated
FALSEnever evaluated
0
2092 return;
never executed: return;
0
2093 d->geometryRecursionBlock = true;-
2094-
2095 int width = 0;-
2096 if (!d->verticalHeader->isHidden()) {
!d->verticalHeader->isHidden()Description
TRUEnever evaluated
FALSEnever evaluated
0
2097 width = qMax(d->verticalHeader->minimumWidth(), d->verticalHeader->sizeHint().width());-
2098 width = qMin(width, d->verticalHeader->maximumWidth());-
2099 }
never executed: end of block
0
2100 int height = 0;-
2101 if (!d->horizontalHeader->isHidden()) {
!d->horizontal...er->isHidden()Description
TRUEnever evaluated
FALSEnever evaluated
0
2102 height = qMax(d->horizontalHeader->minimumHeight(), d->horizontalHeader->sizeHint().height());-
2103 height = qMin(height, d->horizontalHeader->maximumHeight());-
2104 }
never executed: end of block
0
2105 bool reverse = isRightToLeft();-
2106 if (reverse)
reverseDescription
TRUEnever evaluated
FALSEnever evaluated
0
2107 setViewportMargins(0, height, width, 0);
never executed: setViewportMargins(0, height, width, 0);
0
2108 else-
2109 setViewportMargins(width, height, 0, 0);
never executed: setViewportMargins(width, height, 0, 0);
0
2110-
2111 // update headers-
2112-
2113 QRect vg = d->viewport->geometry();-
2114-
2115 int verticalLeft = reverse ? vg.right() + 1 : (vg.left() - width);
reverseDescription
TRUEnever evaluated
FALSEnever evaluated
0
2116 d->verticalHeader->setGeometry(verticalLeft, vg.top(), width, vg.height());-
2117 if (d->verticalHeader->isHidden())
d->verticalHeader->isHidden()Description
TRUEnever evaluated
FALSEnever evaluated
0
2118 QMetaObject::invokeMethod(d->verticalHeader, "updateGeometries");
never executed: QMetaObject::invokeMethod(d->verticalHeader, "updateGeometries");
0
2119-
2120 int horizontalTop = vg.top() - height;-
2121 d->horizontalHeader->setGeometry(vg.left(), horizontalTop, vg.width(), height);-
2122 if (d->horizontalHeader->isHidden())
d->horizontalH...er->isHidden()Description
TRUEnever evaluated
FALSEnever evaluated
0
2123 QMetaObject::invokeMethod(d->horizontalHeader, "updateGeometries");
never executed: QMetaObject::invokeMethod(d->horizontalHeader, "updateGeometries");
0
2124-
2125 // update cornerWidget-
2126 if (d->horizontalHeader->isHidden() || d->verticalHeader->isHidden()) {
d->horizontalH...er->isHidden()Description
TRUEnever evaluated
FALSEnever evaluated
d->verticalHeader->isHidden()Description
TRUEnever evaluated
FALSEnever evaluated
0
2127 d->cornerWidget->setHidden(true);-
2128 } else {
never executed: end of block
0
2129 d->cornerWidget->setHidden(false);-
2130 d->cornerWidget->setGeometry(verticalLeft, horizontalTop, width, height);-
2131 }
never executed: end of block
0
2132-
2133 // update scroll bars-
2134-
2135 // ### move this block into the if-
2136 QSize vsize = d->viewport->size();-
2137 QSize max = maximumViewportSize();-
2138 uint horizontalLength = d->horizontalHeader->length();-
2139 uint verticalLength = d->verticalHeader->length();-
2140 if ((uint)max.width() >= horizontalLength && (uint)max.height() >= verticalLength)
(uint)max.widt...rizontalLengthDescription
TRUEnever evaluated
FALSEnever evaluated
(uint)max.heig...verticalLengthDescription
TRUEnever evaluated
FALSEnever evaluated
0
2141 vsize = max;
never executed: vsize = max;
0
2142-
2143 // horizontal scroll bar-
2144 const int columnCount = d->horizontalHeader->count();-
2145 const int viewportWidth = vsize.width();-
2146 int columnsInViewport = 0;-
2147 for (int width = 0, column = columnCount - 1; column >= 0; --column) {
column >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2148 int logical = d->horizontalHeader->logicalIndex(column);-
2149 if (!d->horizontalHeader->isSectionHidden(logical)) {
!d->horizontal...idden(logical)Description
TRUEnever evaluated
FALSEnever evaluated
0
2150 width += d->horizontalHeader->sectionSize(logical);-
2151 if (width > viewportWidth)
width > viewportWidthDescription
TRUEnever evaluated
FALSEnever evaluated
0
2152 break;
never executed: break;
0
2153 ++columnsInViewport;-
2154 }
never executed: end of block
0
2155 }
never executed: end of block
0
2156 columnsInViewport = qMax(columnsInViewport, 1); //there must be always at least 1 column-
2157-
2158 if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) {
horizontalScro...:ScrollPerItemDescription
TRUEnever evaluated
FALSEnever evaluated
0
2159 const int visibleColumns = columnCount - d->horizontalHeader->hiddenSectionCount();-
2160 horizontalScrollBar()->setRange(0, visibleColumns - columnsInViewport);-
2161 horizontalScrollBar()->setPageStep(columnsInViewport);-
2162 if (columnsInViewport >= visibleColumns)
columnsInViewp...visibleColumnsDescription
TRUEnever evaluated
FALSEnever evaluated
0
2163 d->horizontalHeader->setOffset(0);
never executed: d->horizontalHeader->setOffset(0);
0
2164 horizontalScrollBar()->setSingleStep(1);-
2165 } else { // ScrollPerPixel
never executed: end of block
0
2166 horizontalScrollBar()->setPageStep(vsize.width());-
2167 horizontalScrollBar()->setRange(0, horizontalLength - vsize.width());-
2168 horizontalScrollBar()->setSingleStepd_func()->itemviewChangeSingleStep(qMax(vsize.width() / (columnsInViewport + 1), 2));-
2169 }
never executed: end of block
0
2170-
2171 // vertical scroll bar-
2172 const int rowCount = d->verticalHeader->count();-
2173 const int viewportHeight = vsize.height();-
2174 int rowsInViewport = 0;-
2175 for (int height = 0, row = rowCount - 1; row >= 0; --row) {
row >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2176 int logical = d->verticalHeader->logicalIndex(row);-
2177 if (!d->verticalHeader->isSectionHidden(logical)) {
!d->verticalHe...idden(logical)Description
TRUEnever evaluated
FALSEnever evaluated
0
2178 height += d->verticalHeader->sectionSize(logical);-
2179 if (height > viewportHeight)
height > viewportHeightDescription
TRUEnever evaluated
FALSEnever evaluated
0
2180 break;
never executed: break;
0
2181 ++rowsInViewport;-
2182 }
never executed: end of block
0
2183 }
never executed: end of block
0
2184 rowsInViewport = qMax(rowsInViewport, 1); //there must be always at least 1 row-
2185-
2186 if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {
verticalScroll...:ScrollPerItemDescription
TRUEnever evaluated
FALSEnever evaluated
0
2187 const int visibleRows = rowCount - d->verticalHeader->hiddenSectionCount();-
2188 verticalScrollBar()->setRange(0, visibleRows - rowsInViewport);-
2189 verticalScrollBar()->setPageStep(rowsInViewport);-
2190 if (rowsInViewport >= visibleRows)
rowsInViewport >= visibleRowsDescription
TRUEnever evaluated
FALSEnever evaluated
0
2191 d->verticalHeader->setOffset(0);
never executed: d->verticalHeader->setOffset(0);
0
2192 verticalScrollBar()->setSingleStep(1);-
2193 } else { // ScrollPerPixel
never executed: end of block
0
2194 verticalScrollBar()->setPageStep(vsize.height());-
2195 verticalScrollBar()->setRange(0, verticalLength - vsize.height());-
2196 verticalScrollBar()->setSingleStepd_func()->itemviewChangeSingleStep(qMax(vsize.height() / (rowsInViewport + 1), 2));-
2197 }
never executed: end of block
0
2198-
2199 d->geometryRecursionBlock = false;-
2200 QAbstractItemView::updateGeometries();-
2201}
never executed: end of block
0
2202-
2203/*!-
2204 Returns the size hint for the given \a row's height or -1 if there-
2205 is no model.-
2206-
2207 If you need to set the height of a given row to a fixed value, call-
2208 QHeaderView::resizeSection() on the table's vertical header.-
2209-
2210 If you reimplement this function in a subclass, note that the value you-
2211 return is only used when resizeRowToContents() is called. In that case,-
2212 if a larger row height is required by either the vertical header or-
2213 the item delegate, that width will be used instead.-
2214-
2215 \sa QWidget::sizeHint, verticalHeader(), QHeaderView::resizeContentsPrecision()-
2216*/-
2217int QTableView::sizeHintForRow(int row) const-
2218{-
2219 Q_D(const QTableView);-
2220-
2221 if (!model())-
2222 return -1;-
2223-
2224 ensurePolished();-
2225 const int maximumProcessCols = d->verticalHeader->resizeContentsPrecision();-
2226-
2227-
2228 int left = qMax(0, d->horizontalHeader->visualIndexAt(0));-
2229 int right = d->horizontalHeader->visualIndexAt(d->viewport->width());-
2230 if (right == -1) // the table don't have enough columns to fill the viewport-
2231 right = d->model->columnCount(d->root) - 1;-
2232-
2233 QStyleOptionViewItem option = d->viewOptionsV1();-
2234-
2235 int hint = 0;-
2236 QModelIndex index;-
2237 int columnsProcessed = 0;-
2238 int column = left;-
2239 for (; column <= right; ++column) {-
2240 int logicalColumn = d->horizontalHeader->logicalIndex(column);-
2241 if (d->horizontalHeader->isSectionHidden(logicalColumn))-
2242 continue;-
2243 index = d->model->index(row, logicalColumn, d->root);-
2244 hint = d->heightHintForIndex(index, hint, option);-
2245-
2246 ++columnsProcessed;-
2247 if (columnsProcessed == maximumProcessCols)-
2248 break;-
2249 }-
2250-
2251 int actualRight = d->model->columnCount(d->root) - 1;-
2252 int idxLeft = left;-
2253 int idxRight = column - 1;-
2254-
2255 if (maximumProcessCols == 0)-
2256 columnsProcessed = 0; // skip the while loop-
2257-
2258 while (columnsProcessed != maximumProcessCols && (idxLeft > 0 || idxRight < actualRight)) {-
2259 int logicalIdx = -1;-
2260-
2261 if ((columnsProcessed % 2 && idxLeft > 0) || idxRight == actualRight) {-
2262 while (idxLeft > 0) {-
2263 --idxLeft;-
2264 int logcol = d->horizontalHeader->logicalIndex(idxLeft);-
2265 if (d->horizontalHeader->isSectionHidden(logcol))-
2266 continue;-
2267 logicalIdx = logcol;-
2268 break;-
2269 }-
2270 } else {-
2271 while (idxRight < actualRight) {-
2272 ++idxRight;-
2273 int logcol = d->horizontalHeader->logicalIndex(idxRight);-
2274 if (d->horizontalHeader->isSectionHidden(logcol))-
2275 continue;-
2276 logicalIdx = logcol;-
2277 break;-
2278 }-
2279 }-
2280 if (logicalIdx < 0)-
2281 continue;-
2282-
2283 index = d->model->index(row, logicalIdx, d->root);-
2284 hint = d->heightHintForIndex(index, hint, option);-
2285 ++columnsProcessed;-
2286 }-
2287-
2288 return d->showGrid ? hint + 1 : hint;-
2289}-
2290-
2291/*!-
2292 Returns the size hint for the given \a column's width or -1 if-
2293 there is no model.-
2294-
2295 If you need to set the width of a given column to a fixed value, call-
2296 QHeaderView::resizeSection() on the table's horizontal header.-
2297-
2298 If you reimplement this function in a subclass, note that the value you-
2299 return will be used when resizeColumnToContents() or-
2300 QHeaderView::resizeSections() is called. If a larger column width is-
2301 required by either the horizontal header or the item delegate, the larger-
2302 width will be used instead.-
2303-
2304 \sa QWidget::sizeHint, horizontalHeader(), QHeaderView::resizeContentsPrecision()-
2305*/-
2306int QTableView::sizeHintForColumn(int column) const-
2307{-
2308 Q_D(const QTableView);-
2309-
2310 if (!model())-
2311 return -1;-
2312-
2313 ensurePolished();-
2314 const int maximumProcessRows = d->horizontalHeader->resizeContentsPrecision();-
2315-
2316 int top = qMax(0, d->verticalHeader->visualIndexAt(0));-
2317 int bottom = d->verticalHeader->visualIndexAt(d->viewport->height());-
2318 if (!isVisible() || bottom == -1) // the table don't have enough rows to fill the viewport-
2319 bottom = d->model->rowCount(d->root) - 1;-
2320-
2321 QStyleOptionViewItem option = d->viewOptionsV1();-
2322-
2323 int hint = 0;-
2324 int rowsProcessed = 0;-
2325 QModelIndex index;-
2326 int row = top;-
2327 for (; row <= bottom; ++row) {-
2328 int logicalRow = d->verticalHeader->logicalIndex(row);-
2329 if (d->verticalHeader->isSectionHidden(logicalRow))-
2330 continue;-
2331 index = d->model->index(logicalRow, column, d->root);-
2332-
2333 hint = d->widthHintForIndex(index, hint, option);-
2334 ++rowsProcessed;-
2335 if (rowsProcessed == maximumProcessRows)-
2336 break;-
2337 }-
2338-
2339 int actualBottom = d->model->rowCount(d->root) - 1;-
2340 int idxTop = top;-
2341 int idxBottom = row - 1;-
2342-
2343 if (maximumProcessRows == 0)-
2344 rowsProcessed = 0; // skip the while loop-
2345-
2346 while (rowsProcessed != maximumProcessRows && (idxTop > 0 || idxBottom < actualBottom)) {-
2347 int logicalIdx = -1;-
2348-
2349 if ((rowsProcessed % 2 && idxTop > 0) || idxBottom == actualBottom) {-
2350 while (idxTop > 0) {-
2351 --idxTop;-
2352 int logrow = d->verticalHeader->logicalIndex(idxTop);-
2353 if (d->verticalHeader->isSectionHidden(logrow))-
2354 continue;-
2355 logicalIdx = logrow;-
2356 break;-
2357 }-
2358 } else {-
2359 while (idxBottom < actualBottom) {-
2360 ++idxBottom;-
2361 int logrow = d->verticalHeader->logicalIndex(idxBottom);-
2362 if (d->verticalHeader->isSectionHidden(logrow))-
2363 continue;-
2364 logicalIdx = logrow;-
2365 break;-
2366 }-
2367 }-
2368 if (logicalIdx < 0)-
2369 continue;-
2370-
2371 index = d->model->index(logicalIdx, column, d->root);-
2372 hint = d->widthHintForIndex(index, hint, option);-
2373 ++rowsProcessed;-
2374 }-
2375-
2376 return d->showGrid ? hint + 1 : hint;-
2377}-
2378-
2379/*!-
2380 Returns the y-coordinate in contents coordinates of the given \a-
2381 row.-
2382*/-
2383int QTableView::rowViewportPosition(int row) const-
2384{-
2385 Q_D(const QTableView);-
2386 return d->verticalHeader->sectionViewportPosition(row);-
2387}-
2388-
2389/*!-
2390 Returns the row in which the given y-coordinate, \a y, in contents-
2391 coordinates is located.-
2392-
2393 \note This function returns -1 if the given coordinate is not valid-
2394 (has no row).-
2395-
2396 \sa columnAt()-
2397*/-
2398int QTableView::rowAt(int y) const-
2399{-
2400 Q_D(const QTableView);-
2401 return d->verticalHeader->logicalIndexAt(y);-
2402}-
2403-
2404/*!-
2405 \since 4.1-
2406-
2407 Sets the height of the given \a row to be \a height.-
2408*/-
2409void QTableView::setRowHeight(int row, int height)-
2410{-
2411 Q_D(const QTableView);-
2412 d->verticalHeader->resizeSection(row, height);-
2413}-
2414-
2415/*!-
2416 Returns the height of the given \a row.-
2417-
2418 \sa resizeRowToContents(), columnWidth()-
2419*/-
2420int QTableView::rowHeight(int row) const-
2421{-
2422 Q_D(const QTableView);-
2423 return d->verticalHeader->sectionSize(row);-
2424}-
2425-
2426/*!-
2427 Returns the x-coordinate in contents coordinates of the given \a-
2428 column.-
2429*/-
2430int QTableView::columnViewportPosition(int column) const-
2431{-
2432 Q_D(const QTableView);-
2433 return d->horizontalHeader->sectionViewportPosition(column);-
2434}-
2435-
2436/*!-
2437 Returns the column in which the given x-coordinate, \a x, in contents-
2438 coordinates is located.-
2439-
2440 \note This function returns -1 if the given coordinate is not valid-
2441 (has no column).-
2442-
2443 \sa rowAt()-
2444*/-
2445int QTableView::columnAt(int x) const-
2446{-
2447 Q_D(const QTableView);-
2448 return d->horizontalHeader->logicalIndexAt(x);-
2449}-
2450-
2451/*!-
2452 \since 4.1-
2453-
2454 Sets the width of the given \a column to be \a width.-
2455*/-
2456void QTableView::setColumnWidth(int column, int width)-
2457{-
2458 Q_D(const QTableView);-
2459 d->horizontalHeader->resizeSection(column, width);-
2460}-
2461-
2462/*!-
2463 Returns the width of the given \a column.-
2464-
2465 \sa resizeColumnToContents(), rowHeight()-
2466*/-
2467int QTableView::columnWidth(int column) const-
2468{-
2469 Q_D(const QTableView);-
2470 return d->horizontalHeader->sectionSize(column);-
2471}-
2472-
2473/*!-
2474 Returns \c true if the given \a row is hidden; otherwise returns \c false.-
2475-
2476 \sa isColumnHidden()-
2477*/-
2478bool QTableView::isRowHidden(int row) const-
2479{-
2480 Q_D(const QTableView);-
2481 return d->verticalHeader->isSectionHidden(row);-
2482}-
2483-
2484/*!-
2485 If \a hide is true \a row will be hidden, otherwise it will be shown.-
2486-
2487 \sa setColumnHidden()-
2488*/-
2489void QTableView::setRowHidden(int row, bool hide)-
2490{-
2491 Q_D(QTableView);-
2492 if (row < 0 || row >= d->verticalHeader->count())-
2493 return;-
2494 d->verticalHeader->setSectionHidden(row, hide);-
2495}-
2496-
2497/*!-
2498 Returns \c true if the given \a column is hidden; otherwise returns \c false.-
2499-
2500 \sa isRowHidden()-
2501*/-
2502bool QTableView::isColumnHidden(int column) const-
2503{-
2504 Q_D(const QTableView);-
2505 return d->horizontalHeader->isSectionHidden(column);-
2506}-
2507-
2508/*!-
2509 If \a hide is true the given \a column will be hidden; otherwise it-
2510 will be shown.-
2511-
2512 \sa setRowHidden()-
2513*/-
2514void QTableView::setColumnHidden(int column, bool hide)-
2515{-
2516 Q_D(QTableView);-
2517 if (column < 0 || column >= d->horizontalHeader->count())-
2518 return;-
2519 d->horizontalHeader->setSectionHidden(column, hide);-
2520}-
2521-
2522/*!-
2523 \since 4.2-
2524 \property QTableView::sortingEnabled-
2525 \brief whether sorting is enabled-
2526-
2527 If this property is \c true, sorting is enabled for the table. If-
2528 this property is \c false, sorting is not enabled. The default value-
2529 is false.-
2530-
2531 \note. Setting the property to true with setSortingEnabled()-
2532 immediately triggers a call to sortByColumn() with the current-
2533 sort section and order.-
2534-
2535 \sa sortByColumn()-
2536*/-
2537-
2538/*!-
2539 If \a enable is true, enables sorting for the table and immediately-
2540 trigger a call to sortByColumn() with the current sort section and-
2541 order-
2542 */-
2543void QTableView::setSortingEnabled(bool enable)-
2544{-
2545 Q_D(QTableView);-
2546 d->sortingEnabled = enable;-
2547 horizontalHeader()->setSortIndicatorShown(enable);-
2548 if (enable) {-
2549 disconnect(d->horizontalHeader, SIGNAL(sectionEntered(int)),-
2550 this, SLOT(_q_selectColumn(int)));-
2551 disconnect(horizontalHeader(), SIGNAL(sectionPressed(int)),-
2552 this, SLOT(selectColumn(int)));-
2553 connect(horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),-
2554 this, SLOT(sortByColumn(int)), Qt::UniqueConnection);-
2555 sortByColumn(horizontalHeader()->sortIndicatorSection(),-
2556 horizontalHeader()->sortIndicatorOrder());-
2557 } else {-
2558 connect(d->horizontalHeader, SIGNAL(sectionEntered(int)),-
2559 this, SLOT(_q_selectColumn(int)), Qt::UniqueConnection);-
2560 connect(horizontalHeader(), SIGNAL(sectionPressed(int)),-
2561 this, SLOT(selectColumn(int)), Qt::UniqueConnection);-
2562 disconnect(horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),-
2563 this, SLOT(sortByColumn(int)));-
2564 }-
2565}-
2566-
2567bool QTableView::isSortingEnabled() const-
2568{-
2569 Q_D(const QTableView);-
2570 return d->sortingEnabled;-
2571}-
2572-
2573/*!-
2574 \property QTableView::showGrid-
2575 \brief whether the grid is shown-
2576-
2577 If this property is \c true a grid is drawn for the table; if the-
2578 property is \c false, no grid is drawn. The default value is true.-
2579*/-
2580bool QTableView::showGrid() const-
2581{-
2582 Q_D(const QTableView);-
2583 return d->showGrid;-
2584}-
2585-
2586void QTableView::setShowGrid(bool show)-
2587{-
2588 Q_D(QTableView);-
2589 if (d->showGrid != show) {-
2590 d->showGrid = show;-
2591 d->viewport->update();-
2592 }-
2593}-
2594-
2595/*!-
2596 \property QTableView::gridStyle-
2597 \brief the pen style used to draw the grid.-
2598-
2599 This property holds the style used when drawing the grid (see \l{showGrid}).-
2600*/-
2601Qt::PenStyle QTableView::gridStyle() const-
2602{-
2603 Q_D(const QTableView);-
2604 return d->gridStyle;-
2605}-
2606-
2607void QTableView::setGridStyle(Qt::PenStyle style)-
2608{-
2609 Q_D(QTableView);-
2610 if (d->gridStyle != style) {-
2611 d->gridStyle = style;-
2612 d->viewport->update();-
2613 }-
2614}-
2615-
2616/*!-
2617 \property QTableView::wordWrap-
2618 \brief the item text word-wrapping policy-
2619 \since 4.3-
2620-
2621 If this property is \c true then the item text is wrapped where-
2622 necessary at word-breaks; otherwise it is not wrapped at all.-
2623 This property is \c true by default.-
2624-
2625 Note that even of wrapping is enabled, the cell will not be-
2626 expanded to fit all text. Ellipsis will be inserted according to-
2627 the current \l{QAbstractItemView::}{textElideMode}.-
2628-
2629*/-
2630void QTableView::setWordWrap(bool on)-
2631{-
2632 Q_D(QTableView);-
2633 if (d->wrapItemText == on)-
2634 return;-
2635 d->wrapItemText = on;-
2636 QMetaObject::invokeMethod(d->verticalHeader, "resizeSections");-
2637 QMetaObject::invokeMethod(d->horizontalHeader, "resizeSections");-
2638}-
2639-
2640bool QTableView::wordWrap() const-
2641{-
2642 Q_D(const QTableView);-
2643 return d->wrapItemText;-
2644}-
2645-
2646/*!-
2647 \property QTableView::cornerButtonEnabled-
2648 \brief whether the button in the top-left corner is enabled-
2649 \since 4.3-
2650-
2651 If this property is \c true then button in the top-left corner-
2652 of the table view is enabled. Clicking on this button will-
2653 select all the cells in the table view.-
2654-
2655 This property is \c true by default.-
2656*/-
2657void QTableView::setCornerButtonEnabled(bool enable)-
2658{-
2659 Q_D(QTableView);-
2660 d->cornerWidget->setEnabled(enable);-
2661}-
2662-
2663bool QTableView::isCornerButtonEnabled() const-
2664{-
2665 Q_D(const QTableView);-
2666 return d->cornerWidget->isEnabled();-
2667}-
2668-
2669/*!-
2670 \internal-
2671-
2672 Returns the rectangle on the viewport occupied by the given \a-
2673 index.-
2674 If the index is hidden in the view it will return a null QRect.-
2675*/-
2676QRect QTableView::visualRect(const QModelIndex &index) const-
2677{-
2678 Q_D(const QTableView);-
2679 if (!d->isIndexValid(index) || index.parent() != d->root-
2680 || (!d->hasSpans() && isIndexHidden(index)))-
2681 return QRect();-
2682-
2683 d->executePostedLayout();-
2684-
2685 if (d->hasSpans()) {-
2686 QSpanCollection::Span span = d->span(index.row(), index.column());-
2687 return d->visualSpanRect(span);-
2688 }-
2689-
2690 int rowp = rowViewportPosition(index.row());-
2691 int rowh = rowHeight(index.row());-
2692 int colp = columnViewportPosition(index.column());-
2693 int colw = columnWidth(index.column());-
2694-
2695 const int i = showGrid() ? 1 : 0;-
2696 return QRect(colp, rowp, colw - i, rowh - i);-
2697}-
2698-
2699/*!-
2700 \internal-
2701-
2702 Makes sure that the given \a item is visible in the table view,-
2703 scrolling if necessary.-
2704*/-
2705void QTableView::scrollTo(const QModelIndex &index, ScrollHint hint)-
2706{-
2707 Q_D(QTableView);-
2708-
2709 // check if we really need to do anything-
2710 if (!d->isIndexValid(index)-
2711 || (d->model->parent(index) != d->root)-
2712 || isRowHidden(index.row()) || isColumnHidden(index.column()))-
2713 return;-
2714-
2715 QSpanCollection::Span span;-
2716 if (d->hasSpans())-
2717 span = d->span(index.row(), index.column());-
2718-
2719 // Adjust horizontal position-
2720-
2721 int viewportWidth = d->viewport->width();-
2722 int horizontalOffset = d->horizontalHeader->offset();-
2723 int horizontalPosition = d->horizontalHeader->sectionPosition(index.column());-
2724 int horizontalIndex = d->horizontalHeader->visualIndex(index.column());-
2725 int cellWidth = d->hasSpans()-
2726 ? d->columnSpanWidth(index.column(), span.width())-
2727 : d->horizontalHeader->sectionSize(index.column());-
2728-
2729 if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) {-
2730-
2731 bool positionAtLeft = (horizontalPosition - horizontalOffset < 0);-
2732 bool positionAtRight = (horizontalPosition - horizontalOffset + cellWidth > viewportWidth);-
2733-
2734 if (hint == PositionAtCenter || positionAtRight) {-
2735 int w = (hint == PositionAtCenter ? viewportWidth / 2 : viewportWidth);-
2736 int x = cellWidth;-
2737 while (horizontalIndex > 0) {-
2738 x += columnWidth(d->horizontalHeader->logicalIndex(horizontalIndex-1));-
2739 if (x > w)-
2740 break;-
2741 --horizontalIndex;-
2742 }-
2743 }-
2744-
2745 if (positionAtRight || hint == PositionAtCenter || positionAtLeft) {-
2746 int hiddenSections = 0;-
2747 if (d->horizontalHeader->sectionsHidden()) {-
2748 for (int s = horizontalIndex - 1; s >= 0; --s) {-
2749 int column = d->horizontalHeader->logicalIndex(s);-
2750 if (d->horizontalHeader->isSectionHidden(column))-
2751 ++hiddenSections;-
2752 }-
2753 }-
2754 horizontalScrollBar()->setValue(horizontalIndex - hiddenSections);-
2755 }-
2756-
2757 } else { // ScrollPerPixel-
2758 if (hint == PositionAtCenter) {-
2759 horizontalScrollBar()->setValue(horizontalPosition - ((viewportWidth - cellWidth) / 2));-
2760 } else {-
2761 if (horizontalPosition - horizontalOffset < 0 || cellWidth > viewportWidth)-
2762 horizontalScrollBar()->setValue(horizontalPosition);-
2763 else if (horizontalPosition - horizontalOffset + cellWidth > viewportWidth)-
2764 horizontalScrollBar()->setValue(horizontalPosition - viewportWidth + cellWidth);-
2765 }-
2766 }-
2767-
2768 // Adjust vertical position-
2769-
2770 int viewportHeight = d->viewport->height();-
2771 int verticalOffset = d->verticalHeader->offset();-
2772 int verticalPosition = d->verticalHeader->sectionPosition(index.row());-
2773 int verticalIndex = d->verticalHeader->visualIndex(index.row());-
2774 int cellHeight = d->hasSpans()-
2775 ? d->rowSpanHeight(index.row(), span.height())-
2776 : d->verticalHeader->sectionSize(index.row());-
2777-
2778 if (verticalPosition - verticalOffset < 0 || cellHeight > viewportHeight) {-
2779 if (hint == EnsureVisible)-
2780 hint = PositionAtTop;-
2781 } else if (verticalPosition - verticalOffset + cellHeight > viewportHeight) {-
2782 if (hint == EnsureVisible)-
2783 hint = PositionAtBottom;-
2784 }-
2785-
2786 if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {-
2787-
2788 if (hint == PositionAtBottom || hint == PositionAtCenter) {-
2789 int h = (hint == PositionAtCenter ? viewportHeight / 2 : viewportHeight);-
2790 int y = cellHeight;-
2791 while (verticalIndex > 0) {-
2792 int row = d->verticalHeader->logicalIndex(verticalIndex - 1);-
2793 y += d->verticalHeader->sectionSize(row);-
2794 if (y > h)-
2795 break;-
2796 --verticalIndex;-
2797 }-
2798 }-
2799-
2800 if (hint == PositionAtBottom || hint == PositionAtCenter || hint == PositionAtTop) {-
2801 int hiddenSections = 0;-
2802 if (d->verticalHeader->sectionsHidden()) {-
2803 for (int s = verticalIndex - 1; s >= 0; --s) {-
2804 int row = d->verticalHeader->logicalIndex(s);-
2805 if (d->verticalHeader->isSectionHidden(row))-
2806 ++hiddenSections;-
2807 }-
2808 }-
2809 verticalScrollBar()->setValue(verticalIndex - hiddenSections);-
2810 }-
2811-
2812 } else { // ScrollPerPixel-
2813 if (hint == PositionAtTop) {-
2814 verticalScrollBar()->setValue(verticalPosition);-
2815 } else if (hint == PositionAtBottom) {-
2816 verticalScrollBar()->setValue(verticalPosition - viewportHeight + cellHeight);-
2817 } else if (hint == PositionAtCenter) {-
2818 verticalScrollBar()->setValue(verticalPosition - ((viewportHeight - cellHeight) / 2));-
2819 }-
2820 }-
2821-
2822 update(index);-
2823}-
2824-
2825/*!-
2826 This slot is called to change the height of the given \a row. The-
2827 old height is specified by \a oldHeight, and the new height by \a-
2828 newHeight.-
2829-
2830 \sa columnResized()-
2831*/-
2832void QTableView::rowResized(int row, int, int)-
2833{-
2834 Q_D(QTableView);-
2835 d->rowsToUpdate.append(row);-
2836 if (d->rowResizeTimerID == 0)-
2837 d->rowResizeTimerID = startTimer(0);-
2838}-
2839-
2840/*!-
2841 This slot is called to change the width of the given \a column.-
2842 The old width is specified by \a oldWidth, and the new width by \a-
2843 newWidth.-
2844-
2845 \sa rowResized()-
2846*/-
2847void QTableView::columnResized(int column, int, int)-
2848{-
2849 Q_D(QTableView);-
2850 d->columnsToUpdate.append(column);-
2851 if (d->columnResizeTimerID == 0)-
2852 d->columnResizeTimerID = startTimer(0);-
2853}-
2854-
2855/*!-
2856 \reimp-
2857 */-
2858void QTableView::timerEvent(QTimerEvent *event)-
2859{-
2860 Q_D(QTableView);-
2861-
2862 if (event->timerId() == d->columnResizeTimerID) {-
2863 updateGeometries();-
2864 killTimer(d->columnResizeTimerID);-
2865 d->columnResizeTimerID = 0;-
2866-
2867 QRect rect;-
2868 int viewportHeight = d->viewport->height();-
2869 int viewportWidth = d->viewport->width();-
2870 if (d->hasSpans()) {-
2871 rect = QRect(0, 0, viewportWidth, viewportHeight);-
2872 } else {-
2873 for (int i = d->columnsToUpdate.size()-1; i >= 0; --i) {-
2874 int column = d->columnsToUpdate.at(i);-
2875 int x = columnViewportPosition(column);-
2876 if (isRightToLeft())-
2877 rect |= QRect(0, 0, x + columnWidth(column), viewportHeight);-
2878 else-
2879 rect |= QRect(x, 0, viewportWidth - x, viewportHeight);-
2880 }-
2881 }-
2882-
2883 d->viewport->update(rect.normalized());-
2884 d->columnsToUpdate.clear();-
2885 }-
2886-
2887 if (event->timerId() == d->rowResizeTimerID) {-
2888 updateGeometries();-
2889 killTimer(d->rowResizeTimerID);-
2890 d->rowResizeTimerID = 0;-
2891-
2892 int viewportHeight = d->viewport->height();-
2893 int viewportWidth = d->viewport->width();-
2894 int top;-
2895 if (d->hasSpans()) {-
2896 top = 0;-
2897 } else {-
2898 top = viewportHeight;-
2899 for (int i = d->rowsToUpdate.size()-1; i >= 0; --i) {-
2900 int y = rowViewportPosition(d->rowsToUpdate.at(i));-
2901 top = qMin(top, y);-
2902 }-
2903 }-
2904-
2905 d->viewport->update(QRect(0, top, viewportWidth, viewportHeight - top));-
2906 d->rowsToUpdate.clear();-
2907 }-
2908-
2909 QAbstractItemView::timerEvent(event);-
2910}-
2911-
2912/*!-
2913 This slot is called to change the index of the given \a row in the-
2914 table view. The old index is specified by \a oldIndex, and the new-
2915 index by \a newIndex.-
2916-
2917 \sa columnMoved()-
2918*/-
2919void QTableView::rowMoved(int, int oldIndex, int newIndex)-
2920{-
2921 Q_D(QTableView);-
2922-
2923 updateGeometries();-
2924 int logicalOldIndex = d->verticalHeader->logicalIndex(oldIndex);-
2925 int logicalNewIndex = d->verticalHeader->logicalIndex(newIndex);-
2926 if (d->hasSpans()) {-
2927 d->viewport->update();-
2928 } else {-
2929 int oldTop = rowViewportPosition(logicalOldIndex);-
2930 int newTop = rowViewportPosition(logicalNewIndex);-
2931 int oldBottom = oldTop + rowHeight(logicalOldIndex);-
2932 int newBottom = newTop + rowHeight(logicalNewIndex);-
2933 int top = qMin(oldTop, newTop);-
2934 int bottom = qMax(oldBottom, newBottom);-
2935 int height = bottom - top;-
2936 d->viewport->update(0, top, d->viewport->width(), height);-
2937 }-
2938}-
2939-
2940/*!-
2941 This slot is called to change the index of the given \a column in-
2942 the table view. The old index is specified by \a oldIndex, and-
2943 the new index by \a newIndex.-
2944-
2945 \sa rowMoved()-
2946*/-
2947void QTableView::columnMoved(int, int oldIndex, int newIndex)-
2948{-
2949 Q_D(QTableView);-
2950-
2951 updateGeometries();-
2952 int logicalOldIndex = d->horizontalHeader->logicalIndex(oldIndex);-
2953 int logicalNewIndex = d->horizontalHeader->logicalIndex(newIndex);-
2954 if (d->hasSpans()) {-
2955 d->viewport->update();-
2956 } else {-
2957 int oldLeft = columnViewportPosition(logicalOldIndex);-
2958 int newLeft = columnViewportPosition(logicalNewIndex);-
2959 int oldRight = oldLeft + columnWidth(logicalOldIndex);-
2960 int newRight = newLeft + columnWidth(logicalNewIndex);-
2961 int left = qMin(oldLeft, newLeft);-
2962 int right = qMax(oldRight, newRight);-
2963 int width = right - left;-
2964 d->viewport->update(left, 0, width, d->viewport->height());-
2965 }-
2966}-
2967-
2968/*!-
2969 Selects the given \a row in the table view if the current-
2970 SelectionMode and SelectionBehavior allows rows to be selected.-
2971-
2972 \sa selectColumn()-
2973*/-
2974void QTableView::selectRow(int row)-
2975{-
2976 Q_D(QTableView);-
2977 d->selectRow(row, true);-
2978}-
2979-
2980/*!-
2981 Selects the given \a column in the table view if the current-
2982 SelectionMode and SelectionBehavior allows columns to be selected.-
2983-
2984 \sa selectRow()-
2985*/-
2986void QTableView::selectColumn(int column)-
2987{-
2988 Q_D(QTableView);-
2989 d->selectColumn(column, true);-
2990}-
2991-
2992/*!-
2993 Hide the given \a row.-
2994-
2995 \sa showRow(), hideColumn()-
2996*/-
2997void QTableView::hideRow(int row)-
2998{-
2999 Q_D(QTableView);-
3000 d->verticalHeader->hideSection(row);-
3001}-
3002-
3003/*!-
3004 Hide the given \a column.-
3005-
3006 \sa showColumn(), hideRow()-
3007*/-
3008void QTableView::hideColumn(int column)-
3009{-
3010 Q_D(QTableView);-
3011 d->horizontalHeader->hideSection(column);-
3012}-
3013-
3014/*!-
3015 Show the given \a row.-
3016-
3017 \sa hideRow(), showColumn()-
3018*/-
3019void QTableView::showRow(int row)-
3020{-
3021 Q_D(QTableView);-
3022 d->verticalHeader->showSection(row);-
3023}-
3024-
3025/*!-
3026 Show the given \a column.-
3027-
3028 \sa hideColumn(), showRow()-
3029*/-
3030void QTableView::showColumn(int column)-
3031{-
3032 Q_D(QTableView);-
3033 d->horizontalHeader->showSection(column);-
3034}-
3035-
3036/*!-
3037 Resizes the given \a row based on the size hints of the delegate-
3038 used to render each item in the row.-
3039-
3040 \sa resizeRowsToContents(), sizeHintForRow(), QHeaderView::resizeContentsPrecision()-
3041*/-
3042void QTableView::resizeRowToContents(int row)-
3043{-
3044 Q_D(QTableView);-
3045 int content = sizeHintForRow(row);-
3046 int header = d->verticalHeader->sectionSizeHint(row);-
3047 d->verticalHeader->resizeSection(row, qMax(content, header));-
3048}-
3049-
3050/*!-
3051 Resizes all rows based on the size hints of the delegate-
3052 used to render each item in the rows.-
3053-
3054 \sa resizeRowToContents(), sizeHintForRow(), QHeaderView::resizeContentsPrecision()-
3055*/-
3056void QTableView::resizeRowsToContents()-
3057{-
3058 Q_D(QTableView);-
3059 d->verticalHeader->resizeSections(QHeaderView::ResizeToContents);-
3060}-
3061-
3062/*!-
3063 Resizes the given \a column based on the size hints of the delegate-
3064 used to render each item in the column.-
3065-
3066 \note Only visible columns will be resized. Reimplement sizeHintForColumn()-
3067 to resize hidden columns as well.-
3068-
3069 \sa resizeColumnsToContents(), sizeHintForColumn(), QHeaderView::resizeContentsPrecision()-
3070*/-
3071void QTableView::resizeColumnToContents(int column)-
3072{-
3073 Q_D(QTableView);-
3074 int content = sizeHintForColumn(column);-
3075 int header = d->horizontalHeader->sectionSizeHint(column);-
3076 d->horizontalHeader->resizeSection(column, qMax(content, header));-
3077}-
3078-
3079/*!-
3080 Resizes all columns based on the size hints of the delegate-
3081 used to render each item in the columns.-
3082-
3083 \sa resizeColumnToContents(), sizeHintForColumn(), QHeaderView::resizeContentsPrecision()-
3084*/-
3085void QTableView::resizeColumnsToContents()-
3086{-
3087 Q_D(QTableView);-
3088 d->horizontalHeader->resizeSections(QHeaderView::ResizeToContents);-
3089}-
3090-
3091/*!-
3092 \obsolete-
3093 \overload-
3094-
3095 Sorts the model by the values in the given \a column.-
3096*/-
3097void QTableView::sortByColumn(int column)-
3098{-
3099 Q_D(QTableView);-
3100 if (column == -1)-
3101 return;-
3102 d->model->sort(column, d->horizontalHeader->sortIndicatorOrder());-
3103}-
3104-
3105/*!-
3106 \since 4.2-
3107-
3108 Sorts the model by the values in the given \a column in the given \a order.-
3109-
3110 \sa sortingEnabled-
3111 */-
3112void QTableView::sortByColumn(int column, Qt::SortOrder order)-
3113{-
3114 Q_D(QTableView);-
3115 d->horizontalHeader->setSortIndicator(column, order);-
3116 sortByColumn(column);-
3117}-
3118-
3119/*!-
3120 \internal-
3121*/-
3122void QTableView::verticalScrollbarAction(int action)-
3123{-
3124 QAbstractItemView::verticalScrollbarAction(action);-
3125}-
3126-
3127/*!-
3128 \internal-
3129*/-
3130void QTableView::horizontalScrollbarAction(int action)-
3131{-
3132 QAbstractItemView::horizontalScrollbarAction(action);-
3133}-
3134-
3135/*!-
3136 \reimp-
3137*/-
3138bool QTableView::isIndexHidden(const QModelIndex &index) const-
3139{-
3140 Q_D(const QTableView);-
3141 Q_ASSERT(d->isIndexValid(index));-
3142 if (isRowHidden(index.row()) || isColumnHidden(index.column()))-
3143 return true;-
3144 if (d->hasSpans()) {-
3145 QSpanCollection::Span span = d->span(index.row(), index.column());-
3146 return !((span.top() == index.row()) && (span.left() == index.column()));-
3147 }-
3148 return false;-
3149}-
3150-
3151/*!-
3152 \fn void QTableView::setSpan(int row, int column, int rowSpanCount, int columnSpanCount)-
3153 \since 4.2-
3154-
3155 Sets the span of the table element at (\a row, \a column) to the number of-
3156 rows and columns specified by (\a rowSpanCount, \a columnSpanCount).-
3157-
3158 \sa rowSpan(), columnSpan()-
3159*/-
3160void QTableView::setSpan(int row, int column, int rowSpan, int columnSpan)-
3161{-
3162 Q_D(QTableView);-
3163 if (row < 0 || column < 0 || rowSpan < 0 || columnSpan < 0)-
3164 return;-
3165 d->setSpan(row, column, rowSpan, columnSpan);-
3166 d->viewport->update();-
3167}-
3168-
3169/*!-
3170 \since 4.2-
3171-
3172 Returns the row span of the table element at (\a row, \a column).-
3173 The default is 1.-
3174-
3175 \sa setSpan(), columnSpan()-
3176*/-
3177int QTableView::rowSpan(int row, int column) const-
3178{-
3179 Q_D(const QTableView);-
3180 return d->rowSpan(row, column);-
3181}-
3182-
3183/*!-
3184 \since 4.2-
3185-
3186 Returns the column span of the table element at (\a row, \a-
3187 column). The default is 1.-
3188-
3189 \sa setSpan(), rowSpan()-
3190*/-
3191int QTableView::columnSpan(int row, int column) const-
3192{-
3193 Q_D(const QTableView);-
3194 return d->columnSpan(row, column);-
3195}-
3196-
3197/*!-
3198 \since 4.4-
3199-
3200 Removes all row and column spans in the table view.-
3201-
3202 \sa setSpan()-
3203*/-
3204-
3205void QTableView::clearSpans()-
3206{-
3207 Q_D(QTableView);-
3208 d->spans.clear();-
3209 d->viewport->update();-
3210}-
3211-
3212void QTableViewPrivate::_q_selectRow(int row)-
3213{-
3214 selectRow(row, false);-
3215}-
3216-
3217void QTableViewPrivate::_q_selectColumn(int column)-
3218{-
3219 selectColumn(column, false);-
3220}-
3221-
3222void QTableViewPrivate::selectRow(int row, bool anchor)-
3223{-
3224 Q_Q(QTableView);-
3225-
3226 if (q->selectionBehavior() == QTableView::SelectColumns-
3227 || (q->selectionMode() == QTableView::SingleSelection-
3228 && q->selectionBehavior() == QTableView::SelectItems))-
3229 return;-
3230-
3231 if (row >= 0 && row < model->rowCount(root)) {-
3232 int column = horizontalHeader->logicalIndexAt(q->isRightToLeft() ? viewport->width() : 0);-
3233 QModelIndex index = model->index(row, column, root);-
3234 QItemSelectionModel::SelectionFlags command = q->selectionCommand(index);-
3235 selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);-
3236 if ((anchor && !(command & QItemSelectionModel::Current))-
3237 || (q->selectionMode() == QTableView::SingleSelection))-
3238 rowSectionAnchor = row;-
3239-
3240 if (q->selectionMode() != QTableView::SingleSelection-
3241 && command.testFlag(QItemSelectionModel::Toggle)) {-
3242 if (anchor)-
3243 ctrlDragSelectionFlag = verticalHeader->selectionModel()->selectedRows().contains(index)-
3244 ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;-
3245 command &= ~QItemSelectionModel::Toggle;-
3246 command |= ctrlDragSelectionFlag;-
3247 if (!anchor)-
3248 command |= QItemSelectionModel::Current;-
3249 }-
3250-
3251 QModelIndex upper = model->index(qMin(rowSectionAnchor, row), column, root);-
3252 QModelIndex lower = model->index(qMax(rowSectionAnchor, row), column, root);-
3253 if ((verticalHeader->sectionsMoved() && upper.row() != lower.row())) {-
3254 q->setSelection(q->visualRect(upper) | q->visualRect(lower), command | QItemSelectionModel::Rows);-
3255 } else {-
3256 selectionModel->select(QItemSelection(upper, lower), command | QItemSelectionModel::Rows);-
3257 }-
3258 }-
3259}-
3260-
3261void QTableViewPrivate::selectColumn(int column, bool anchor)-
3262{-
3263 Q_Q(QTableView);-
3264-
3265 if (q->selectionBehavior() == QTableView::SelectRows-
3266 || (q->selectionMode() == QTableView::SingleSelection-
3267 && q->selectionBehavior() == QTableView::SelectItems))-
3268 return;-
3269-
3270 if (column >= 0 && column < model->columnCount(root)) {-
3271 int row = verticalHeader->logicalIndexAt(0);-
3272 QModelIndex index = model->index(row, column, root);-
3273 QItemSelectionModel::SelectionFlags command = q->selectionCommand(index);-
3274 selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);-
3275 if ((anchor && !(command & QItemSelectionModel::Current))-
3276 || (q->selectionMode() == QTableView::SingleSelection))-
3277 columnSectionAnchor = column;-
3278-
3279 if (q->selectionMode() != QTableView::SingleSelection-
3280 && command.testFlag(QItemSelectionModel::Toggle)) {-
3281 if (anchor)-
3282 ctrlDragSelectionFlag = horizontalHeader->selectionModel()->selectedColumns().contains(index)-
3283 ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;-
3284 command &= ~QItemSelectionModel::Toggle;-
3285 command |= ctrlDragSelectionFlag;-
3286 if (!anchor)-
3287 command |= QItemSelectionModel::Current;-
3288 }-
3289-
3290 QModelIndex left = model->index(row, qMin(columnSectionAnchor, column), root);-
3291 QModelIndex right = model->index(row, qMax(columnSectionAnchor, column), root);-
3292 if ((horizontalHeader->sectionsMoved() && left.column() != right.column())) {-
3293 q->setSelection(q->visualRect(left) | q->visualRect(right), command | QItemSelectionModel::Columns);-
3294 } else {-
3295 selectionModel->select(QItemSelection(left, right), command | QItemSelectionModel::Columns);-
3296 }-
3297 }-
3298}-
3299-
3300/*!-
3301 \reimp-
3302 */-
3303void QTableView::currentChanged(const QModelIndex &current, const QModelIndex &previous)-
3304{-
3305#ifndef QT_NO_ACCESSIBILITY-
3306 if (QAccessible::isActive()) {-
3307 if (current.isValid()) {-
3308 Q_D(QTableView);-
3309 int entry = d->accessibleTable2Index(current);-
3310 QAccessibleEvent event(this, QAccessible::Focus);-
3311 event.setChild(entry);-
3312 QAccessible::updateAccessibility(&event);-
3313 }-
3314 }-
3315#endif-
3316 QAbstractItemView::currentChanged(current, previous);-
3317}-
3318-
3319/*!-
3320 \reimp-
3321 */-
3322void QTableView::selectionChanged(const QItemSelection &selected,-
3323 const QItemSelection &deselected)-
3324{-
3325 Q_D(QTableView);-
3326 Q_UNUSED(d)-
3327#ifndef QT_NO_ACCESSIBILITY-
3328 if (QAccessible::isActive()) {-
3329 // ### does not work properly for selection ranges.-
3330 QModelIndex sel = selected.indexes().value(0);-
3331 if (sel.isValid()) {-
3332 int entry = d->accessibleTable2Index(sel);-
3333 QAccessibleEvent event(this, QAccessible::SelectionAdd);-
3334 event.setChild(entry);-
3335 QAccessible::updateAccessibility(&event);-
3336 }-
3337 QModelIndex desel = deselected.indexes().value(0);-
3338 if (desel.isValid()) {-
3339 int entry = d->accessibleTable2Index(desel);-
3340 QAccessibleEvent event(this, QAccessible::SelectionRemove);-
3341 event.setChild(entry);-
3342 QAccessible::updateAccessibility(&event);-
3343 }-
3344 }-
3345#endif-
3346 QAbstractItemView::selectionChanged(selected, deselected);-
3347}-
3348-
3349int QTableView::visualIndex(const QModelIndex &index) const-
3350{-
3351 return index.row();-
3352}-
3353-
3354QT_END_NAMESPACE-
3355-
3356#include "qtableview.moc"-
3357-
3358#include "moc_qtableview.cpp"-
3359-
3360#endif // QT_NO_TABLEVIEW-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9