00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "qheaderview.h"
00025
00026 #ifndef QT_NO_ITEMVIEWS
00027 #include <qbitarray.h>
00028 #include <qbrush.h>
00029 #include <qdebug.h>
00030 #include <qevent.h>
00031 #include <qpainter.h>
00032 #include <qscrollbar.h>
00033 #include <qtooltip.h>
00034 #include <qwhatsthis.h>
00035 #include <qstyle.h>
00036 #include <qstyleoption.h>
00037 #include <qvector.h>
00038 #include <qapplication.h>
00039 #include <qvarlengtharray.h>
00040 #include <qabstractitemdelegate.h>
00041 #include <qvariant.h>
00042 #include <private/qheaderview_p.h>
00043
00204
00205
00221 QHeaderView::QHeaderView(Qt::Orientation orientation, QWidget *parent)
00222 : QAbstractItemView(*new QHeaderViewPrivate, parent)
00223 {
00224 Q_D(QHeaderView);
00225 d->setDefaultValues(orientation);
00226 initialize();
00227 }
00228
00232 QHeaderView::QHeaderView(QHeaderViewPrivate &dd,
00233 Qt::Orientation orientation, QWidget *parent)
00234 : QAbstractItemView(dd, parent)
00235 {
00236 Q_D(QHeaderView);
00237 d->setDefaultValues(orientation);
00238 initialize();
00239 }
00240
00245 QHeaderView::~QHeaderView()
00246 {
00247 }
00248
00252 void QHeaderView::initialize()
00253 {
00254 Q_D(QHeaderView);
00255 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00256 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00257 setFrameStyle(NoFrame);
00258 d->viewport->setMouseTracking(true);
00259 d->viewport->setBackgroundRole(QPalette::Button);
00260 d->textElideMode = Qt::ElideNone;
00261 delete d->itemDelegate;
00262 }
00263
00267 void QHeaderView::setModel(QAbstractItemModel *model)
00268 {
00269
00270
00271
00272
00273 Q_D(QHeaderView);
00274 if (d->orientation == Qt::Horizontal) {
00275 QObject::disconnect(d->model, SIGNAL(columnsInserted(QModelIndex,int,int)),
00276 this, SLOT(sectionsInserted(QModelIndex,int,int)));
00277 QObject::disconnect(d->model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
00278 this, SLOT(sectionsAboutToBeRemoved(QModelIndex,int,int)));
00279 QObject::disconnect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
00280 this, SLOT(_q_sectionsRemoved(QModelIndex,int,int)));
00281 } else {
00282 QObject::disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
00283 this, SLOT(sectionsInserted(QModelIndex,int,int)));
00284 QObject::disconnect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
00285 this, SLOT(sectionsAboutToBeRemoved(QModelIndex,int,int)));
00286 QObject::disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
00287 this, SLOT(_q_sectionsRemoved(QModelIndex,int,int)));
00288 }
00289 QObject::disconnect(d->model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
00290 this, SLOT(headerDataChanged(Qt::Orientation,int,int)));
00291
00292 if (model) {
00293 if (d->orientation == Qt::Horizontal) {
00294 QObject::connect(model, SIGNAL(columnsInserted(QModelIndex,int,int)),
00295 this, SLOT(sectionsInserted(QModelIndex,int,int)));
00296 QObject::connect(model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
00297 this, SLOT(sectionsAboutToBeRemoved(QModelIndex,int,int)));
00298 QObject::connect(model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
00299 this, SLOT(_q_sectionsRemoved(QModelIndex,int,int)));
00300 } else {
00301 QObject::connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)),
00302 this, SLOT(sectionsInserted(QModelIndex,int,int)));
00303 QObject::connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
00304 this, SLOT(sectionsAboutToBeRemoved(QModelIndex,int,int)));
00305 QObject::connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
00306 this, SLOT(_q_sectionsRemoved(QModelIndex,int,int)));
00307 }
00308 QObject::connect(model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
00309 this, SLOT(headerDataChanged(Qt::Orientation,int,int)));
00310 }
00311 d->clear();
00312
00313 QAbstractItemView::setModel(model);
00314
00315
00316
00317 initializeSections();
00318 }
00319
00326 Qt::Orientation QHeaderView::orientation() const
00327 {
00328 Q_D(const QHeaderView);
00329 return d->orientation;
00330 }
00331
00339 int QHeaderView::offset() const
00340 {
00341 Q_D(const QHeaderView);
00342 return d->offset;
00343 }
00344
00353 void QHeaderView::setOffset(int newOffset)
00354 {
00355 Q_D(QHeaderView);
00356 if (d->offset == (uint)newOffset)
00357 return;
00358 int ndelta = d->offset - newOffset;
00359 d->offset = newOffset;
00360 if (d->orientation == Qt::Horizontal)
00361 d->viewport->scroll(isRightToLeft() ? -ndelta : ndelta, 0);
00362 else
00363 d->viewport->scroll(0, ndelta);
00364 if (d->state == QHeaderViewPrivate::ResizeSection) {
00365 QPoint cursorPos = QCursor::pos();
00366 if (d->orientation == Qt::Horizontal)
00367 QCursor::setPos(cursorPos.x() + ndelta, cursorPos.y());
00368 else
00369 QCursor::setPos(cursorPos.x(), cursorPos.y() + ndelta);
00370 d->firstPos += ndelta;
00371 d->lastPos += ndelta;
00372 }
00373 }
00374
00381 void QHeaderView::setOffsetToSectionPosition(int visualIndex)
00382 {
00383 Q_D(QHeaderView);
00384 if (visualIndex > -1 && visualIndex < d->sectionCount) {
00385 int position = d->headerSectionPosition(d->adjustedVisualIndex(visualIndex));
00386 setOffset(position);
00387 }
00388 }
00389
00396 int QHeaderView::length() const
00397 {
00398 Q_D(const QHeaderView);
00399
00400 return d->length;
00401 }
00402
00409 QSize QHeaderView::sizeHint() const
00410 {
00411 Q_D(const QHeaderView);
00412 if (count() < 1)
00413 return QSize(0, 0);
00414 if (d->cachedSizeHint.isValid())
00415 return d->cachedSizeHint;
00416 int width = 0;
00417 int height = 0;
00418
00419 int c = qMin(count(), 100);
00420 for (int i = 0; i < c; ++i) {
00421 QSize hint = sectionSizeFromContents(i);
00422 width = qMax(hint.width(), width);
00423 height = qMax(hint.height(), height);
00424 }
00425
00426 c = qMax(count() - 100, c);
00427 for (int j = count() - 1; j >= c; --j) {
00428 QSize hint = sectionSizeFromContents(j);
00429 width = qMax(hint.width(), width);
00430 height = qMax(hint.height(), height);
00431 }
00432 d->cachedSizeHint = QSize(width, height);
00433 return d->cachedSizeHint;
00434 }
00435
00442 int QHeaderView::sectionSizeHint(int logicalIndex) const
00443 {
00444 Q_D(const QHeaderView);
00445 if (logicalIndex < 0 || logicalIndex >= count())
00446 return -1;
00447 QSize size = sectionSizeFromContents(logicalIndex);
00448 int hint = d->orientation == Qt::Horizontal ? size.width() : size.height();
00449 return qMax(minimumSectionSize(), hint);
00450 }
00451
00458 int QHeaderView::visualIndexAt(int position) const
00459 {
00460 Q_D(const QHeaderView);
00461 uint vposition = position;
00462 d->executePostedLayout();
00463 const int count = d->sectionCount;
00464 if (count < 1)
00465 return -1;
00466
00467 if (d->reverse())
00468 vposition = d->viewport->width() - vposition;
00469 vposition += d->offset;
00470
00471 if (vposition > d->length)
00472 return -1;
00473 int visual = d->headerVisualIndexAt(vposition);
00474 if (visual < 0)
00475 return -1;
00476
00477 while (d->isVisualIndexHidden(visual)){
00478 ++visual;
00479 if (visual >= count)
00480 return -1;
00481 }
00482 return visual;
00483 }
00484
00491 int QHeaderView::logicalIndexAt(int position) const
00492 {
00493 const int visual = visualIndexAt(position);
00494 if (visual > -1)
00495 return logicalIndex(visual);
00496 return -1;
00497 }
00498
00505 int QHeaderView::sectionSize(int logicalIndex) const
00506 {
00507 Q_D(const QHeaderView);
00508 if (logicalIndex < 0 || logicalIndex >= count())
00509 return 0;
00510 if (isSectionHidden(logicalIndex))
00511 return 0;
00512 int visual = visualIndex(logicalIndex);
00513 if (visual == -1)
00514 return 0;
00515 return d->headerSectionSize(visual);
00516 }
00517
00525 int QHeaderView::sectionPosition(int logicalIndex) const
00526 {
00527 Q_D(const QHeaderView);
00528 int visual = visualIndex(logicalIndex);
00529
00530
00531 if (visual == -1)
00532 return -1;
00533 return d->headerSectionPosition(visual);
00534 }
00535
00544 int QHeaderView::sectionViewportPosition(int logicalIndex) const
00545 {
00546 Q_D(const QHeaderView);
00547 if (logicalIndex < 0 || logicalIndex >= count())
00548 return -1;
00549 int position = sectionPosition(logicalIndex);
00550 if (position < 0)
00551 return position;
00552 int offsetPosition = position - d->offset;
00553 if (d->reverse())
00554 return d->viewport->width() - (offsetPosition + sectionSize(logicalIndex));
00555 return offsetPosition;
00556 }
00557
00582 void QHeaderView::moveSection(int from, int to)
00583 {
00584 Q_D(QHeaderView);
00585
00586 d->executePostedLayout();
00587 if (from < 0 || from >= d->sectionCount || to < 0 || to >= d->sectionCount)
00588 return;
00589
00590 if (from == to) {
00591 int logical = logicalIndex(from);
00592 Q_ASSERT(logical != -1);
00593 updateSection(logical);
00594 return;
00595 }
00596
00597
00598 d->initializeIndexMapping();
00599
00600 QBitArray sectionHidden = d->sectionHidden;
00601 int *visualIndices = d->visualIndices.data();
00602 int *logicalIndices = d->logicalIndices.data();
00603 int logical = logicalIndices[from];
00604 int visual = from;
00605
00606 int affected_count = qAbs(to - from) + 1;
00607 QVarLengthArray<int> sizes(affected_count);
00608 QVarLengthArray<ResizeMode> modes(affected_count);
00609
00610
00611 if (to > from) {
00612 sizes[to - from] = d->headerSectionSize(from);
00613 modes[to - from] = d->headerSectionResizeMode(from);
00614 while (visual < to) {
00615 sizes[visual - from] = d->headerSectionSize(visual + 1);
00616 modes[visual - from] = d->headerSectionResizeMode(visual + 1);
00617 if (!sectionHidden.isEmpty())
00618 sectionHidden.setBit(visual, sectionHidden.testBit(visual + 1));
00619 visualIndices[logicalIndices[visual + 1]] = visual;
00620 logicalIndices[visual] = logicalIndices[visual + 1];
00621 ++visual;
00622 }
00623 } else {
00624 sizes[0] = d->headerSectionSize(from);
00625 modes[0] = d->headerSectionResizeMode(from);
00626 while (visual > to) {
00627 sizes[visual - to] = d->headerSectionSize(visual - 1);
00628 modes[visual - to] = d->headerSectionResizeMode(visual - 1);
00629 if (!sectionHidden.isEmpty())
00630 sectionHidden.setBit(visual, sectionHidden.testBit(visual - 1));
00631 visualIndices[logicalIndices[visual - 1]] = visual;
00632 logicalIndices[visual] = logicalIndices[visual - 1];
00633 --visual;
00634 }
00635 }
00636 if (!sectionHidden.isEmpty()) {
00637 sectionHidden.setBit(to, d->sectionHidden.testBit(from));
00638 d->sectionHidden = sectionHidden;
00639 }
00640 visualIndices[logical] = to;
00641 logicalIndices[to] = logical;
00642
00643
00644
00645
00646 if (to > from) {
00647 for (visual = from; visual <= to; ++visual) {
00648 int size = sizes[visual - from];
00649 ResizeMode mode = modes[visual - from];
00650 d->createSectionSpan(visual, visual, size, mode);
00651 }
00652 } else {
00653 for (visual = to; visual <= from; ++visual) {
00654 int size = sizes[visual - to];
00655 ResizeMode mode = modes[visual - to];
00656 d->createSectionSpan(visual, visual, size, mode);
00657 }
00658 }
00659
00660
00661
00662 d->viewport->update();
00663 emit sectionMoved(logical, from, to);
00664 }
00665
00672 void QHeaderView::swapSections(int first, int second)
00673 {
00674 Q_D(QHeaderView);
00675
00676 if (first == second)
00677 return;
00678 d->executePostedLayout();
00679 if (first < 0 || first >= d->sectionCount || second < 0 || second >= d->sectionCount)
00680 return;
00681
00682 int firstSize = d->headerSectionSize(first);
00683 ResizeMode firstMode = d->headerSectionResizeMode(first);
00684 int firstLogical = d->logicalIndex(first);
00685
00686 int secondSize = d->headerSectionSize(second);
00687 ResizeMode secondMode = d->headerSectionResizeMode(second);
00688 int secondLogical = d->logicalIndex(second);
00689
00690 d->createSectionSpan(second, second, firstSize, firstMode);
00691 d->createSectionSpan(first, first, secondSize, secondMode);
00692
00693 d->initializeIndexMapping();
00694
00695 d->visualIndices[firstLogical] = second;
00696 d->logicalIndices[second] = firstLogical;
00697
00698 d->visualIndices[secondLogical] = first;
00699 d->logicalIndices[first] = secondLogical;
00700
00701 if (!d->sectionHidden.isEmpty()) {
00702 bool firstHidden = d->sectionHidden.testBit(first);
00703 bool secondHidden = d->sectionHidden.testBit(second);
00704 d->sectionHidden.setBit(first, secondHidden);
00705 d->sectionHidden.setBit(second, firstHidden);
00706 }
00707
00708 d->viewport->update();
00709 emit sectionMoved(firstLogical, first, second);
00710 emit sectionMoved(secondLogical, second, first);
00711 }
00712
00721 void QHeaderView::resizeSection(int logical, int size)
00722 {
00723 Q_D(QHeaderView);
00724 if (logical < 0 || logical >= count())
00725 return;
00726
00727 if (isSectionHidden(logical))
00728 return;
00729
00730 int oldSize = sectionSize(logical);
00731 if (oldSize == size)
00732 return;
00733
00734 d->executePostedLayout();
00735 d->invalidateCachedSizeHint();
00736
00737 int visual = visualIndex(logical);
00738 Q_ASSERT(visual != -1);
00739
00740 if (stretchLastSection() && visual == count() - 1)
00741 d->lastSectionSize = size;
00742
00743 if (size != oldSize)
00744 d->createSectionSpan(visual, visual, size, d->headerSectionResizeMode(visual));
00745
00746 int w = d->viewport->width();
00747 int h = d->viewport->height();
00748 int pos = sectionViewportPosition(logical);
00749 QRect r;
00750 if (orientation() == Qt::Horizontal)
00751 if (isRightToLeft())
00752 r.setRect(0, 0, pos + size, h);
00753 else
00754 r.setRect(pos, 0, w - pos, h);
00755 else
00756 r.setRect(0, pos, w, h - pos);
00757
00758 if (d->hasAutoResizeSections()) {
00759 resizeSections();
00760 r = d->viewport->rect();
00761 }
00762 d->viewport->update(r.normalized());
00763 emit sectionResized(logical, oldSize, size);
00764 }
00765
00773 void QHeaderView::resizeSections(QHeaderView::ResizeMode mode)
00774 {
00775 Q_D(QHeaderView);
00776 d->resizeSections(mode, true);
00777 }
00778
00800 bool QHeaderView::isSectionHidden(int logicalIndex) const
00801 {
00802 Q_D(const QHeaderView);
00803 if (logicalIndex >= d->sectionHidden.count() || logicalIndex < 0 || logicalIndex >= d->sectionCount)
00804 return false;
00805 d->executePostedLayout();
00806 int visual = visualIndex(logicalIndex);
00807 Q_ASSERT(visual != -1);
00808 return d->sectionHidden.testBit(visual);
00809 }
00810
00818 int QHeaderView::hiddenSectionCount() const
00819 {
00820 Q_D(const QHeaderView);
00821 return d->hiddenSectionSize.count();
00822 }
00823
00831 void QHeaderView::setSectionHidden(int logicalIndex, bool hide)
00832 {
00833 Q_D(QHeaderView);
00834 if (logicalIndex < 0 || logicalIndex >= count())
00835 return;
00836
00837 d->executePostedLayout();
00838 int visual = visualIndex(logicalIndex);
00839 Q_ASSERT(visual != -1);
00840 if (hide && d->isVisualIndexHidden(visual))
00841 return;
00842 if (hide) {
00843 int size = sectionSize(logicalIndex);
00844 if (!d->hasAutoResizeSections())
00845 resizeSection(logicalIndex, 0);
00846 d->hiddenSectionSize.insert(logicalIndex, size);
00847 if (d->sectionHidden.count() < count())
00848 d->sectionHidden.resize(count());
00849 d->sectionHidden.setBit(visual, true);
00850 if (d->hasAutoResizeSections())
00851 resizeSections();
00852 } else if (d->isVisualIndexHidden(visual)) {
00853 int size = d->hiddenSectionSize.value(logicalIndex, d->defaultSectionSize);
00854 d->hiddenSectionSize.remove(logicalIndex);
00855 if (d->hiddenSectionSize.isEmpty()) {
00856 d->sectionHidden.clear();
00857 } else {
00858 Q_ASSERT(visual <= d->sectionHidden.count());
00859 d->sectionHidden.setBit(visual, false);
00860 }
00861 resizeSection(logicalIndex, size);
00862 }
00863 }
00864
00871 int QHeaderView::count() const
00872 {
00873 Q_D(const QHeaderView);
00874
00875
00876 d->executePostedLayout();
00877 return d->sectionCount;
00878 }
00879
00888 int QHeaderView::visualIndex(int logicalIndex) const
00889 {
00890 Q_D(const QHeaderView);
00891 if (logicalIndex < 0)
00892 return -1;
00893 d->executePostedLayout();
00894 if (d->visualIndices.isEmpty()) {
00895 if (logicalIndex < d->sectionCount)
00896 return logicalIndex;
00897 } else if (logicalIndex < d->visualIndices.count()) {
00898 int visual = d->visualIndices.at(logicalIndex);
00899 Q_ASSERT(visual < d->sectionCount);
00900 return visual;
00901 }
00902 return -1;
00903 }
00904
00912 int QHeaderView::logicalIndex(int visualIndex) const
00913 {
00914 Q_D(const QHeaderView);
00915 if (visualIndex < 0 || visualIndex >= d->sectionCount)
00916 return -1;
00917 return d->logicalIndex(visualIndex);
00918 }
00919
00927
00928 void QHeaderView::setMovable(bool movable)
00929 {
00930 Q_D(QHeaderView);
00931 d->movableSections = movable;
00932 }
00933
00941
00942 bool QHeaderView::isMovable() const
00943 {
00944 Q_D(const QHeaderView);
00945 return d->movableSections;
00946 }
00947
00954
00955 void QHeaderView::setClickable(bool clickable)
00956 {
00957 Q_D(QHeaderView);
00958 d->clickableSections = clickable;
00959 }
00960
00969
00970 bool QHeaderView::isClickable() const
00971 {
00972 Q_D(const QHeaderView);
00973 return d->clickableSections;
00974 }
00975
00976 void QHeaderView::setHighlightSections(bool highlight)
00977 {
00978 Q_D(QHeaderView);
00979 d->highlightSelected = highlight;
00980 }
00981
00982 bool QHeaderView::highlightSections() const
00983 {
00984 Q_D(const QHeaderView);
00985 return d->highlightSelected;
00986 }
00987
00995 void QHeaderView::setResizeMode(ResizeMode mode)
00996 {
00997 Q_D(QHeaderView);
00998 initializeSections();
00999 d->stretchSections = (mode == Stretch ? count() : 0);
01000 d->contentsSections = (mode == ResizeToContents ? count() : 0);
01001 d->setGlobalHeaderResizeMode(mode);
01002 if (d->hasAutoResizeSections())
01003 resizeSections();
01004 }
01005
01013
01014 void QHeaderView::setResizeMode(int logicalIndex, ResizeMode mode)
01015 {
01016 Q_D(QHeaderView);
01017 int visual = visualIndex(logicalIndex);
01018 Q_ASSERT(visual != -1);
01019
01020 ResizeMode old = d->headerSectionResizeMode(visual);
01021 d->setHeaderSectionResizeMode(visual, mode);
01022
01023 if (mode == Stretch && old != Stretch)
01024 ++d->stretchSections;
01025 else if (mode == ResizeToContents && old != ResizeToContents)
01026 ++d->contentsSections;
01027 else if (mode != Stretch && old == Stretch)
01028 --d->stretchSections;
01029 else if (mode != ResizeToContents && old == ResizeToContents)
01030 --d->contentsSections;
01031
01032 if (d->hasAutoResizeSections() && d->state == QHeaderViewPrivate::NoState)
01033 resizeSections();
01034 }
01035
01042 QHeaderView::ResizeMode QHeaderView::resizeMode(int logicalIndex) const
01043 {
01044 Q_D(const QHeaderView);
01045 int visual = visualIndex(logicalIndex);
01046 Q_ASSERT(visual != -1);
01047 return d->visualIndexResizeMode(visual);
01048 }
01049
01059 int QHeaderView::stretchSectionCount() const
01060 {
01061 Q_D(const QHeaderView);
01062 return d->stretchSections;
01063 }
01064
01072 void QHeaderView::setSortIndicatorShown(bool show)
01073 {
01074 Q_D(QHeaderView);
01075 d->sortIndicatorShown = show;
01076
01077 if (sortIndicatorSection() < 0 || sortIndicatorSection() > count())
01078 return;
01079
01080 if (d->visualIndexResizeMode(sortIndicatorSection()) == ResizeToContents) {
01081 resizeSections();
01082 d->viewport->update();
01083 }
01084 }
01085
01086 bool QHeaderView::isSortIndicatorShown() const
01087 {
01088 Q_D(const QHeaderView);
01089 return d->sortIndicatorShown;
01090 }
01091
01100 void QHeaderView::setSortIndicator(int logicalIndex, Qt::SortOrder order)
01101 {
01102 Q_D(QHeaderView);
01103
01104 Q_ASSERT(logicalIndex >= 0);
01105
01106
01107 int old = d->sortIndicatorSection;
01108 d->sortIndicatorSection = logicalIndex;
01109 d->sortIndicatorOrder = order;
01110
01111 if (logicalIndex >= d->sectionCount)
01112 return;
01113
01114 if (old != logicalIndex && resizeMode(logicalIndex) == ResizeToContents) {
01115 resizeSections();
01116 d->viewport->update();
01117 } else {
01118 if (old != logicalIndex)
01119 updateSection(old);
01120 updateSection(logicalIndex);
01121 }
01122 }
01123
01131 int QHeaderView::sortIndicatorSection() const
01132 {
01133 Q_D(const QHeaderView);
01134 return d->sortIndicatorSection;
01135 }
01136
01144 Qt::SortOrder QHeaderView::sortIndicatorOrder() const
01145 {
01146 Q_D(const QHeaderView);
01147 return d->sortIndicatorOrder;
01148 }
01149
01162 bool QHeaderView::stretchLastSection() const
01163 {
01164 Q_D(const QHeaderView);
01165 return d->stretchLastSection;
01166 }
01167
01168 void QHeaderView::setStretchLastSection(bool stretch)
01169 {
01170 Q_D(QHeaderView);
01171 d->stretchLastSection = stretch;
01172 if (d->state != QHeaderViewPrivate::NoState)
01173 return;
01174 if (stretch)
01175 resizeSections();
01176 else if (count())
01177 resizeSection(count() - 1, d->defaultSectionSize);
01178 }
01179
01192 bool QHeaderView::cascadingSectionResizes() const
01193 {
01194 Q_D(const QHeaderView);
01195 return d->cascadingResizing;
01196 }
01197
01198 void QHeaderView::setCascadingSectionResizes(bool enable)
01199 {
01200 Q_D(QHeaderView);
01201 d->cascadingResizing = enable;
01202 }
01203
01212 int QHeaderView::defaultSectionSize() const
01213 {
01214 Q_D(const QHeaderView);
01215 return d->defaultSectionSize;
01216 }
01217
01218 void QHeaderView::setDefaultSectionSize(int size)
01219 {
01220 Q_D(QHeaderView);
01221 d->defaultSectionSize = size;
01222 }
01223
01238 int QHeaderView::minimumSectionSize() const
01239 {
01240 Q_D(const QHeaderView);
01241 if (d->minimumSectionSize == -1) {
01242 QSize strut = QApplication::globalStrut();
01243 int margin = style()->pixelMetric(QStyle::PM_HeaderMargin);
01244 if (orientation() == Qt::Horizontal)
01245 return qMax(strut.width(), (fontMetrics().maxWidth() + margin));
01246 return qMax(strut.height(), (fontMetrics().lineSpacing() + margin));
01247 }
01248 return d->minimumSectionSize;
01249 }
01250
01251 void QHeaderView::setMinimumSectionSize(int size)
01252 {
01253 Q_D(QHeaderView);
01254 d->minimumSectionSize = size;
01255 }
01256
01263 Qt::Alignment QHeaderView::defaultAlignment() const
01264 {
01265 Q_D(const QHeaderView);
01266 return d->defaultAlignment;
01267 }
01268
01269 void QHeaderView::setDefaultAlignment(Qt::Alignment alignment)
01270 {
01271 Q_D(QHeaderView);
01272 d->defaultAlignment = alignment;
01273 }
01274
01278 void QHeaderView::doItemsLayout()
01279 {
01280 initializeSections();
01281 QAbstractItemView::doItemsLayout();
01282 }
01283
01290 bool QHeaderView::sectionsMoved() const
01291 {
01292 Q_D(const QHeaderView);
01293 return !d->visualIndices.isEmpty();
01294 }
01295
01304 bool QHeaderView::sectionsHidden() const
01305 {
01306 Q_D(const QHeaderView);
01307 return !d->hiddenSectionSize.isEmpty();
01308 }
01309
01314 void QHeaderView::headerDataChanged(Qt::Orientation orientation, int logicalFirst, int logicalLast)
01315 {
01316 Q_D(QHeaderView);
01317 if (d->orientation != orientation)
01318 return;
01319
01320 if (logicalFirst < 0 || logicalLast < 0 || logicalFirst >= count() || logicalLast >= count())
01321 return;
01322
01323 d->invalidateCachedSizeHint();
01324
01325 if (orientation == Qt::Horizontal) {
01326 int left = sectionViewportPosition(logicalFirst);
01327 int right = sectionViewportPosition(logicalLast);
01328 right += sectionSize(logicalLast);
01329 d->viewport->update(left, 0, right - left, d->viewport->height());
01330 } else {
01331 int top = sectionViewportPosition(logicalFirst);
01332 int bottom = sectionViewportPosition(logicalLast);
01333 bottom += sectionSize(logicalLast);
01334 d->viewport->update(0, top, d->viewport->width(), bottom - top);
01335 }
01336 }
01337
01345 void QHeaderView::updateSection(int logicalIndex)
01346 {
01347 Q_D(QHeaderView);
01348 if (orientation() == Qt::Horizontal)
01349 d->viewport->update(QRect(sectionViewportPosition(logicalIndex),
01350 0, sectionSize(logicalIndex), d->viewport->height()));
01351 else
01352 d->viewport->update(QRect(0, sectionViewportPosition(logicalIndex),
01353 d->viewport->width(), sectionSize(logicalIndex)));
01354 }
01355
01361 void QHeaderView::resizeSections()
01362 {
01363 Q_D(QHeaderView);
01364 if (d->hasAutoResizeSections())
01365 d->resizeSections(Interactive, false);
01366 }
01367
01377 void QHeaderView::sectionsInserted(const QModelIndex &parent, int logicalFirst, int)
01378 {
01379 Q_D(QHeaderView);
01380 if (parent != d->root)
01381 return;
01382 int lastSection;
01383 if (d->orientation == Qt::Horizontal)
01384 lastSection = qMax(d->model->columnCount(d->root) - 1, 0);
01385 else
01386 lastSection = qMax(d->model->rowCount(d->root) - 1, 0);
01387 int oldCount = d->sectionCount;
01388 int oldLastSection = qMax(oldCount - 1, 0);
01389 initializeSections(qMin(oldLastSection + 1, logicalFirst), lastSection);
01390 resizeSections();
01391 emit sectionCountChanged(oldCount, count());
01392 }
01393
01401 void QHeaderView::sectionsAboutToBeRemoved(const QModelIndex &parent,
01402 int logicalFirst, int logicalLast)
01403 {
01404 Q_UNUSED(parent);
01405 Q_UNUSED(logicalFirst);
01406 Q_UNUSED(logicalLast);
01407 }
01408
01409 void QHeaderViewPrivate::_q_sectionsRemoved(const QModelIndex &parent,
01410 int logicalFirst, int logicalLast)
01411 {
01412 Q_Q(QHeaderView);
01413 if (parent != root)
01414 return;
01415 if (qMin(logicalFirst, logicalLast) < 0
01416 || qMax(logicalLast, logicalFirst) >= sectionCount)
01417 return;
01418 int oldCount = q->count();
01419 int changeCount = logicalLast - logicalFirst + 1;
01420 if (visualIndices.isEmpty() && logicalIndices.isEmpty()) {
01421 for (int i = logicalFirst; i <= changeCount+logicalFirst; ++i)
01422 hiddenSectionSize.remove(i);
01423
01424 removeSectionsFromSpans(logicalFirst, logicalLast);
01425 } else {
01426 for (int l = logicalLast; l >= logicalFirst; --l) {
01427 int visual = visualIndices.at(l);
01428 for (int v = 0; v < sectionCount; ++v) {
01429 if (v > visual) {
01430 int logical = logicalIndex(v);
01431 --(visualIndices[logical]);
01432 }
01433 if (logicalIndex(v) > l)
01434 --(logicalIndices[v]);
01435 }
01436 hiddenSectionSize.remove(l);
01437 logicalIndices.remove(visual);
01438 visualIndices.remove(l);
01439
01440 removeSectionsFromSpans(visual, visual);
01441 }
01442
01443 }
01444 sectionCount -= changeCount;
01445
01446
01447 if (sectionCount <= 0)
01448 clear();
01449 invalidateCachedSizeHint();
01450 emit q->sectionCountChanged(oldCount, q->count());
01451 viewport->update();
01452 }
01453
01458 void QHeaderView::initializeSections()
01459 {
01460 Q_D(QHeaderView);
01461 if (d->orientation == Qt::Horizontal) {
01462 int c = d->model->columnCount(d->root);
01463 if (c == 0) {
01464 int oldCount = count();
01465 d->clear();
01466 emit sectionCountChanged(oldCount, 0);
01467 } else if (c != count() && c > 0) {
01468 initializeSections(0, c - 1);
01469 }
01470 } else {
01471 int r = d->model->rowCount(d->root);
01472 if (r == 0) {
01473 int oldCount = count();
01474 d->clear();
01475 emit sectionCountChanged(oldCount, 0);
01476 } else if (r != count() && r > 0) {
01477 initializeSections(0, r - 1);
01478 }
01479 }
01480 if (stretchLastSection())
01481 d->lastSectionSize = sectionSizeHint(logicalIndex(count() - 1));
01482 }
01483
01488 void QHeaderView::initializeSections(int start, int end)
01489 {
01490 Q_D(QHeaderView);
01491
01492 Q_ASSERT(start >= 0);
01493 Q_ASSERT(end >= 0);
01494
01495 d->invalidateCachedSizeHint();
01496
01497
01498 if (end < count())
01499 d->removeSectionsFromSpans(end + 1, count());
01500
01501 int oldCount = d->sectionCount;
01502 d->sectionCount = end + 1;
01503
01504 if (!d->logicalIndices.isEmpty()) {
01505 d->logicalIndices.resize(d->sectionCount);
01506 d->visualIndices.resize(d->sectionCount);
01507 for (int i = start; i < d->sectionCount; ++i){
01508 d->logicalIndices[i] = i;
01509 d->visualIndices[i] = i;
01510 }
01511 }
01512
01513 if (d->globalResizeMode == Stretch)
01514 d->stretchSections = d->sectionCount;
01515 else if (d->globalResizeMode == ResizeToContents)
01516 d->contentsSections = d->sectionCount;
01517 if (!d->sectionHidden.isEmpty())
01518 d->sectionHidden.resize(d->sectionCount);
01519
01520 d->createSectionSpan(start, end, (end - start + 1) * d->defaultSectionSize, d->globalResizeMode);
01521
01522
01523 emit sectionCountChanged(oldCount, d->sectionCount);
01524 d->viewport->update();
01525 }
01526
01531 void QHeaderView::currentChanged(const QModelIndex ¤t, const QModelIndex &old)
01532 {
01533 Q_D(QHeaderView);
01534
01535 if (d->orientation == Qt::Horizontal && current.column() != old.column()) {
01536 if (old.isValid() && old.parent() == d->root)
01537 d->setDirtyRegion(QRect(sectionViewportPosition(old.column()), 0,
01538 sectionSize(old.column()), d->viewport->height()));
01539 if (current.isValid() && current.parent() == d->root)
01540 d->setDirtyRegion(QRect(sectionViewportPosition(current.column()), 0,
01541 sectionSize(current.column()), d->viewport->height()));
01542 } else if (d->orientation == Qt::Vertical && current.row() != old.row()) {
01543 if (old.isValid() && old.parent() == d->root)
01544 d->setDirtyRegion(QRect(0, sectionViewportPosition(old.row()),
01545 d->viewport->width(), sectionSize(old.row())));
01546 if (current.isValid() && current.parent() == d->root)
01547 d->setDirtyRegion(QRect(0, sectionViewportPosition(current.row()),
01548 d->viewport->width(), sectionSize(current.row())));
01549 }
01550 d->updateDirtyRegion();
01551 }
01552
01553
01558 bool QHeaderView::event(QEvent *e)
01559 {
01560 Q_D(QHeaderView);
01561 switch (e->type()) {
01562 case QEvent::HoverEnter: {
01563 QHoverEvent *he = static_cast<QHoverEvent*>(e);
01564 d->hover = logicalIndexAt(he->pos());
01565 if (d->hover != -1)
01566 updateSection(d->hover);
01567 break; }
01568 case QEvent::HoverLeave: {
01569 if (d->hover != -1)
01570 updateSection(d->hover);
01571 d->hover = -1;
01572 break; }
01573 case QEvent::HoverMove: {
01574 QHoverEvent *he = static_cast<QHoverEvent*>(e);
01575 int oldHover = d->hover;
01576 d->hover = logicalIndexAt(he->pos());
01577 if (d->hover != oldHover) {
01578 if (oldHover != -1)
01579 updateSection(oldHover);
01580 if (d->hover != -1)
01581 updateSection(d->hover);
01582 }
01583 break; }
01584 default:
01585 break;
01586 }
01587 return QAbstractItemView::event(e);
01588 }
01589
01594 void QHeaderView::paintEvent(QPaintEvent *e)
01595 {
01596 Q_D(QHeaderView);
01597
01598 if (count() == 0)
01599 return;
01600
01601 QPainter painter(d->viewport);
01602 const QPoint offset = d->scrollDelayOffset;
01603 QRect translatedEventRect = e->rect();
01604 translatedEventRect.translate(offset);
01605
01606 int start = -1;
01607 int end = -1;
01608 if (orientation() == Qt::Horizontal) {
01609 start = visualIndexAt(translatedEventRect.left());
01610 end = visualIndexAt(translatedEventRect.right());
01611 } else {
01612 start = visualIndexAt(translatedEventRect.top());
01613 end = visualIndexAt(translatedEventRect.bottom());
01614 }
01615
01616 if (d->reverse()) {
01617 start = (start == -1 ? count() - 1 : start);
01618 end = (end == -1 ? 0 : end);
01619 } else {
01620 start = (start == -1 ? 0 : start);
01621 end = (end == -1 ? count() - 1 : end);
01622 }
01623
01624 int tmp = start;
01625 start = qMin(start, end);
01626 end = qMax(tmp, end);
01627
01628 d->prepareSectionSelected();
01629
01630 QRect currentSectionRect;
01631 int logical;
01632 const int width = d->viewport->width();
01633 const int height = d->viewport->height();
01634 const bool active = isActiveWindow();
01635 for (int i = start; i <= end; ++i) {
01636 if (d->isVisualIndexHidden(i))
01637 continue;
01638 painter.save();
01639 logical = logicalIndex(i);
01640 bool highlight = false;
01641 if (orientation() == Qt::Horizontal) {
01642 currentSectionRect.setRect(sectionViewportPosition(logical), 0, sectionSize(logical), height);
01643 if (d->highlightSelected && active)
01644 highlight = d->columnIntersectsSelection(logical);
01645 } else {
01646 currentSectionRect.setRect(0, sectionViewportPosition(logical), width, sectionSize(logical));
01647 if (d->highlightSelected && active)
01648 highlight = d->rowIntersectsSelection(logical);
01649 }
01650 currentSectionRect.translate(offset);
01651
01652 QVariant variant = d->model->headerData(logical, orientation(),
01653 Qt::FontRole);
01654 if (variant.isValid() && qVariantCanConvert<QFont>(variant)) {
01655 QFont sectionFont = qvariant_cast<QFont>(variant);
01656 if (highlight)
01657 sectionFont.setBold(true);
01658 painter.setFont(sectionFont);
01659 }
01660 paintSection(&painter, currentSectionRect, logical);
01661 painter.restore();
01662 }
01663
01664
01665 if (d->reverse()) {
01666 if (currentSectionRect.left() > translatedEventRect.left())
01667 painter.fillRect(translatedEventRect.left(), 0,
01668 currentSectionRect.left() - translatedEventRect.left(), height,
01669 palette().background());
01670 } else if (currentSectionRect.right() < translatedEventRect.right()) {
01671
01672 painter.fillRect(currentSectionRect.right() + 1, 0,
01673 translatedEventRect.right() - currentSectionRect.right(), height,
01674 palette().background());
01675 } else if (currentSectionRect.bottom() < translatedEventRect.bottom()) {
01676 painter.fillRect(0, currentSectionRect.bottom() + 1,
01677 width, height - currentSectionRect.bottom() - 1,
01678 palette().background());
01679 }
01680
01681 #if 0
01682
01683 for (int a = 0, i = 0; i < d->sectionSpans.count(); ++i) {
01684 QColor color((i & 4 ? 255 : 0), (i & 2 ? 255 : 0), (i & 1 ? 255 : 0));
01685 if (orientation() == Qt::Horizontal)
01686 painter.fillRect(a - d->offset, 0, d->sectionSpans.at(i).size, 4, color);
01687 else
01688 painter.fillRect(0, a - d->offset, 4, d->sectionSpans.at(i).size, color);
01689 a += d->sectionSpans.at(i).size;
01690 }
01691
01692 #endif
01693 }
01694
01699 void QHeaderView::mousePressEvent(QMouseEvent *e)
01700 {
01701 Q_D(QHeaderView);
01702 if (d->state != QHeaderViewPrivate::NoState || e->button() != Qt::LeftButton)
01703 return;
01704 int pos = orientation() == Qt::Horizontal ? e->x() : e->y();
01705 int handle = d->sectionHandleAt(pos);
01706 while (handle > -1 && isSectionHidden(handle)) --handle;
01707 if (handle == -1) {
01708 d->pressed = logicalIndexAt(pos);
01709 if (d->movableSections) {
01710 d->section = d->target = d->pressed;
01711 if (d->section == -1)
01712 return;
01713 d->state = QHeaderViewPrivate::MoveSection;
01714 d->setupSectionIndicator(d->section, pos);
01715 }
01716 if (d->clickableSections && d->pressed != -1) {
01717 updateSection(d->pressed);
01718 emit sectionPressed(d->pressed);
01719 }
01720 } else if (resizeMode(handle) == Interactive) {
01721 Q_ASSERT(d->originalSize == -1);
01722 d->originalSize = sectionSize(handle);
01723 d->state = QHeaderViewPrivate::ResizeSection;
01724 d->section = handle;
01725 }
01726
01727 d->firstPos = pos;
01728 d->lastPos = pos;
01729
01730 d->clearCascadingSections();
01731 }
01732
01737 void QHeaderView::mouseMoveEvent(QMouseEvent *e)
01738 {
01739 Q_D(QHeaderView);
01740 int pos = orientation() == Qt::Horizontal ? e->x() : e->y();
01741 if (pos < 0)
01742 return;
01743 if (e->buttons() == Qt::NoButton) {
01744 d->state = QHeaderViewPrivate::NoState;
01745 d->pressed = -1;
01746 }
01747 switch (d->state) {
01748 case QHeaderViewPrivate::ResizeSection: {
01749 Q_ASSERT(d->originalSize != -1);
01750 if (d->cascadingResizing) {
01751 int delta = d->reverse() ? d->lastPos - pos : pos - d->lastPos;
01752 int visual = visualIndex(d->section);
01753 d->cascadingResize(visual, d->headerSectionSize(visual) + delta);
01754 } else {
01755 int delta = d->reverse() ? d->firstPos - pos : pos - d->firstPos;
01756 resizeSection(d->section, qMax(d->originalSize + delta, minimumSectionSize()));
01757 }
01758 d->lastPos = pos;
01759 return;
01760 }
01761 case QHeaderViewPrivate::MoveSection: {
01762 if (qAbs(pos - d->firstPos) >= QApplication::startDragDistance()) {
01763 int indicatorCenter = (orientation() == Qt::Horizontal
01764 ? d->sectionIndicator->width()
01765 : d->sectionIndicator->height()) / 2;
01766 int centerOffset = indicatorCenter - d->sectionIndicatorOffset;
01767
01768
01769 int visual = visualIndexAt(pos + centerOffset);
01770 if (visual == -1)
01771 return;
01772 d->target = d->logicalIndex(visual);
01773 d->updateSectionIndicator(d->section, pos);
01774 } else {
01775 int visual = visualIndexAt(d->firstPos);
01776 if (visual == -1)
01777 return;
01778 d->target = d->logicalIndex(visual);
01779 d->updateSectionIndicator(d->section, d->firstPos);
01780 }
01781 return;
01782 }
01783 case QHeaderViewPrivate::NoState: {
01784 #ifndef QT_NO_CURSOR
01785 int handle = d->sectionHandleAt(pos);
01786 if (handle != -1 && (resizeMode(handle) == Interactive))
01787 setCursor(orientation() == Qt::Horizontal ? Qt::SplitHCursor : Qt::SplitVCursor);
01788 else
01789 setCursor(Qt::ArrowCursor);
01790 #endif
01791 return;
01792 }
01793 }
01794 }
01795
01800 void QHeaderView::mouseReleaseEvent(QMouseEvent *e)
01801 {
01802 Q_D(QHeaderView);
01803 int pos = orientation() == Qt::Horizontal ? e->x() : e->y();
01804 switch (d->state) {
01805 case QHeaderViewPrivate::MoveSection:
01806 if (!d->sectionIndicator->isHidden()) {
01807 int from = visualIndex(d->section);
01808 Q_ASSERT(from != -1);
01809 int to = visualIndex(d->target);
01810 Q_ASSERT(to != -1);
01811 moveSection(from, to);
01812 d->section = d->target = -1;
01813 d->updateSectionIndicator(d->section, pos);
01814 break;
01815 }
01816 case QHeaderViewPrivate::NoState:
01817 if (d->clickableSections) {
01818 int section = logicalIndexAt(pos);
01819 if (section != -1 && section == d->pressed) {
01820 if (d->sortIndicatorShown)
01821 d->flipSortIndicator(section);
01822 emit sectionClicked(logicalIndexAt(pos));
01823 }
01824 if (d->pressed != -1)
01825 updateSection(d->pressed);
01826 }
01827 break;
01828 case QHeaderViewPrivate::ResizeSection:
01829 d->originalSize = -1;
01830 d->clearCascadingSections();
01831 break;
01832 }
01833 d->state = QHeaderViewPrivate::NoState;
01834 d->pressed = -1;
01835 }
01836
01841 void QHeaderView::mouseDoubleClickEvent(QMouseEvent *e)
01842 {
01843 Q_D(QHeaderView);
01844 int pos = orientation() == Qt::Horizontal ? e->x() : e->y();
01845 int handle = d->sectionHandleAt(pos);
01846 while (handle > -1 && isSectionHidden(handle)) handle--;
01847 if (handle > -1 && resizeMode(handle) == Interactive) {
01848 emit sectionHandleDoubleClicked(handle);
01849 #ifndef QT_NO_CURSOR
01850 Qt::CursorShape splitCursor = (orientation() == Qt::Horizontal)
01851 ? Qt::SplitHCursor : Qt::SplitVCursor;
01852 if (cursor().shape() == splitCursor) {
01853
01854 handle = d->sectionHandleAt(pos);
01855 while (handle > -1 && isSectionHidden(handle)) handle--;
01856 if (!(handle > -1 && resizeMode(handle) == Interactive))
01857 setCursor(Qt::ArrowCursor);
01858 }
01859 #endif
01860 } else {
01861 emit sectionDoubleClicked(logicalIndexAt(e->pos()));
01862 }
01863 }
01864
01869 bool QHeaderView::viewportEvent(QEvent *e)
01870 {
01871 Q_D(QHeaderView);
01872 switch (e->type()) {
01873 #ifndef QT_NO_TOOLTIP
01874 case QEvent::ToolTip: {
01875 if (!isActiveWindow())
01876 break;
01877 QHelpEvent *he = static_cast<QHelpEvent*>(e);
01878 int logical = logicalIndexAt(he->pos());
01879 if (logical != -1) {
01880 QVariant variant = d->model->headerData(logical, orientation(), Qt::ToolTipRole);
01881 if (variant.isValid()) {
01882 QToolTip::showText(he->globalPos(), variant.toString(), this);
01883 return true;
01884 }
01885 }
01886 break; }
01887 #endif
01888 #ifndef QT_NO_WHATSTHIS
01889 case QEvent::QueryWhatsThis: {
01890 QHelpEvent *he = static_cast<QHelpEvent*>(e);
01891 int logical = logicalIndexAt(he->pos());
01892 if (logical != -1
01893 && d->model->headerData(logical, orientation(), Qt::WhatsThisRole).isValid())
01894 return true;
01895 break; }
01896 case QEvent::WhatsThis: {
01897 QHelpEvent *he = static_cast<QHelpEvent*>(e);
01898 int logical = logicalIndexAt(he->pos());
01899 if (logical != -1) {
01900 QVariant whatsthis = d->model->headerData(logical, orientation(),
01901 Qt::WhatsThisRole);
01902 if (whatsthis.isValid()) {
01903 QWhatsThis::showText(he->globalPos(), whatsthis.toString(), this);
01904 return true;
01905 }
01906 }
01907 break; }
01908 #endif // QT_NO_WHATSTHIS
01909 #ifndef QT_NO_STATUSTIP
01910 case QEvent::StatusTip: {
01911 QHelpEvent *he = static_cast<QHelpEvent*>(e);
01912 int logical = logicalIndexAt(he->pos());
01913 if (logical != -1) {
01914 QString statustip = d->model->headerData(logical, orientation(),
01915 Qt::StatusTipRole).toString();
01916 if (!statustip.isEmpty())
01917 setStatusTip(statustip);
01918 }
01919 return true; }
01920 #endif // QT_NO_STATUSTIP
01921 case QEvent::Hide:
01922 case QEvent::Show:
01923 case QEvent::FontChange:
01924 resizeSections();
01925 emit geometriesChanged();
01926 break;
01927 case QEvent::ContextMenu: {
01928 d->state = QHeaderViewPrivate::NoState;
01929 d->pressed =d->section = d->target = -1;
01930 d->updateSectionIndicator(d->section, -1);
01931 }
01932 default:
01933 break;
01934 }
01935 return QAbstractItemView::viewportEvent(e);
01936 }
01937
01944 void QHeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
01945 {
01946 Q_D(const QHeaderView);
01947 if (!rect.isValid())
01948 return;
01949
01950 QStyleOptionHeader opt = d->getStyleOption();
01951 QStyle::State state = QStyle::State_None;
01952 if (isEnabled())
01953 state |= QStyle::State_Enabled;
01954 if (window()->isActiveWindow())
01955 state |= QStyle::State_Active;
01956 if (d->clickableSections) {
01957 if (logicalIndex == d->hover)
01958 state |= QStyle::State_MouseOver;
01959 if (logicalIndex == d->pressed)
01960 state |= QStyle::State_Sunken;
01961 else if (d->highlightSelected && d->isSectionSelected(logicalIndex))
01962 state |= QStyle::State_On | QStyle::State_Sunken;
01963 }
01964 if (isSortIndicatorShown() && sortIndicatorSection() == logicalIndex)
01965 opt.sortIndicator = (sortIndicatorOrder() == Qt::AscendingOrder)
01966 ? QStyleOptionHeader::SortDown : QStyleOptionHeader::SortUp;
01967
01968
01969 QVariant textAlignment = d->model->headerData(logicalIndex, orientation(),
01970 Qt::TextAlignmentRole);
01971 opt.rect = rect;
01972 opt.section = logicalIndex;
01973 opt.state |= state;
01974 opt.textAlignment = Qt::Alignment(textAlignment.isValid()
01975 ? Qt::Alignment(textAlignment.toInt())
01976 : d->defaultAlignment);
01977 opt.iconAlignment = Qt::AlignVCenter;
01978 opt.text = d->model->headerData(logicalIndex, orientation(),
01979 Qt::DisplayRole).toString();
01980 if (d->textElideMode != Qt::ElideNone)
01981 opt.text = opt.fontMetrics.elidedText(opt.text, d->textElideMode , rect.width() - 4);
01982
01983 QVariant variant = d->model->headerData(logicalIndex, orientation(),
01984 Qt::DecorationRole);
01985 opt.icon = qvariant_cast<QIcon>(variant);
01986 if (opt.icon.isNull())
01987 opt.icon = qvariant_cast<QPixmap>(variant);
01988 QVariant foregroundBrush = d->model->headerData(logicalIndex, orientation(),
01989 Qt::ForegroundRole);
01990 if (qVariantCanConvert<QBrush>(foregroundBrush))
01991 opt.palette.setBrush(QPalette::ButtonText, qvariant_cast<QBrush>(foregroundBrush));
01992
01993 QPointF oldBO = painter->brushOrigin();
01994 QVariant backgroundBrush = d->model->headerData(logicalIndex, orientation(),
01995 Qt::BackgroundRole);
01996 if (qVariantCanConvert<QBrush>(backgroundBrush)) {
01997 opt.palette.setBrush(QPalette::Button, qvariant_cast<QBrush>(backgroundBrush));
01998 opt.palette.setBrush(QPalette::Window, qvariant_cast<QBrush>(backgroundBrush));
01999 painter->setBrushOrigin(opt.rect.topLeft());
02000 }
02001
02002
02003 int visual = visualIndex(logicalIndex);
02004 Q_ASSERT(visual != -1);
02005 if (count() == 1)
02006 opt.position = QStyleOptionHeader::OnlyOneSection;
02007 else if (visual == 0)
02008 opt.position = QStyleOptionHeader::Beginning;
02009 else if (visual == count() - 1)
02010 opt.position = QStyleOptionHeader::End;
02011 else
02012 opt.position = QStyleOptionHeader::Middle;
02013 opt.orientation = d->orientation;
02014
02015 bool previousSelected = d->isSectionSelected(this->logicalIndex(visual - 1));
02016 bool nextSelected = d->isSectionSelected(this->logicalIndex(visual + 1));
02017 if (previousSelected && nextSelected)
02018 opt.selectedPosition = QStyleOptionHeader::NextAndPreviousAreSelected;
02019 else if (previousSelected)
02020 opt.selectedPosition = QStyleOptionHeader::PreviousIsSelected;
02021 else if (nextSelected)
02022 opt.selectedPosition = QStyleOptionHeader::NextIsSelected;
02023 else
02024 opt.selectedPosition = QStyleOptionHeader::NotAdjacent;
02025
02026 style()->drawControl(QStyle::CE_Header, &opt, painter, this);
02027
02028 painter->setBrushOrigin(oldBO);
02029 }
02030
02037 QSize QHeaderView::sectionSizeFromContents(int logicalIndex) const
02038 {
02039 Q_D(const QHeaderView);
02040 Q_ASSERT(logicalIndex >= 0);
02041 QSize size(100, 30);
02042
02043
02044 QVariant variant = d->model->headerData(logicalIndex, orientation(), Qt::SizeHintRole);
02045 if (variant.isValid())
02046 return qvariant_cast<QSize>(variant);
02047
02048
02049 QStyleOptionHeader opt = d->getStyleOption();
02050 QVariant var = d->model->headerData(logicalIndex, orientation(),
02051 Qt::FontRole);
02052 QFont fnt;
02053 if (var.isValid() && qVariantCanConvert<QFont>(var))
02054 fnt = qvariant_cast<QFont>(var);
02055 else
02056 fnt = font();
02057 fnt.setBold(true);
02058 opt.fontMetrics = QFontMetrics(fnt);
02059 opt.text = d->model->headerData(logicalIndex, orientation(),
02060 Qt::DisplayRole).toString();
02061 variant = d->model->headerData(logicalIndex, orientation(), Qt::DecorationRole);
02062 opt.icon = qvariant_cast<QIcon>(variant);
02063 if (opt.icon.isNull())
02064 opt.icon = qvariant_cast<QPixmap>(variant);
02065 size = style()->sizeFromContents(QStyle::CT_HeaderSection, &opt, size, this);
02066
02067 if (isSortIndicatorShown() && sortIndicatorSection() == logicalIndex) {
02068 int margin = style()->pixelMetric(QStyle::PM_HeaderMargin);
02069 if (orientation() == Qt::Horizontal)
02070 size.rwidth() += size.height() + margin;
02071 else
02072 size.rheight() += size.width() + margin;
02073 }
02074 return size;
02075 }
02076
02084 int QHeaderView::horizontalOffset() const
02085 {
02086 Q_D(const QHeaderView);
02087 if (orientation() == Qt::Horizontal)
02088 return d->offset;
02089 return 0;
02090 }
02091
02099 int QHeaderView::verticalOffset() const
02100 {
02101 Q_D(const QHeaderView);
02102 if (orientation() == Qt::Vertical)
02103 return d->offset;
02104 return 0;
02105 }
02106
02112 void QHeaderView::updateGeometries()
02113 {
02114 Q_D(QHeaderView);
02115 d->layoutChildren();
02116 if (d->hasAutoResizeSections())
02117 resizeSections();
02118 }
02119
02125 void QHeaderView::scrollContentsBy(int dx, int dy)
02126 {
02127 Q_D(QHeaderView);
02128 d->scrollDirtyRegion(dx, dy);
02129 }
02130
02135 void QHeaderView::dataChanged(const QModelIndex &, const QModelIndex &)
02136 {
02137 Q_D(QHeaderView);
02138 d->invalidateCachedSizeHint();
02139 }
02140
02147 void QHeaderView::rowsInserted(const QModelIndex &, int, int)
02148 {
02149
02150 }
02151
02159 QRect QHeaderView::visualRect(const QModelIndex &) const
02160 {
02161 return QRect();
02162 }
02163
02171 void QHeaderView::scrollTo(const QModelIndex &, ScrollHint)
02172 {
02173
02174 }
02175
02183 QModelIndex QHeaderView::indexAt(const QPoint &) const
02184 {
02185 return QModelIndex();
02186 }
02187
02195 bool QHeaderView::isIndexHidden(const QModelIndex &) const
02196 {
02197 return true;
02198 }
02199
02207 QModelIndex QHeaderView::moveCursor(CursorAction, Qt::KeyboardModifiers)
02208 {
02209 return QModelIndex();
02210 }
02211
02221 void QHeaderView::setSelection(const QRect&, QItemSelectionModel::SelectionFlags)
02222 {
02223
02224 }
02225
02230 QRegion QHeaderView::visualRegionForSelection(const QItemSelection &selection) const
02231 {
02232 Q_D(const QHeaderView);
02233 if (orientation() == Qt::Horizontal) {
02234 int left = d->model->columnCount(d->root) - 1;
02235 int right = 0;
02236 int rangeLeft, rangeRight;
02237
02238 for (int i = 0; i < selection.count(); ++i) {
02239 QItemSelectionRange r = selection.at(i);
02240 if (r.parent().isValid() || !r.isValid())
02241 continue;
02242
02243 rangeLeft = visualIndex(r.left());
02244 if (rangeLeft == -1)
02245 continue;
02246 rangeRight = visualIndex(r.right());
02247 if (rangeRight == -1)
02248 continue;
02249 if (rangeLeft < left)
02250 left = rangeLeft;
02251 if (rangeRight > right)
02252 right = rangeRight;
02253 }
02254
02255 int logicalLeft = logicalIndex(left);
02256 int logicalRight = logicalIndex(right);
02257
02258 if (logicalLeft < 0 || logicalLeft >= count() ||
02259 logicalRight < 0 || logicalRight >= count())
02260 return QRegion();
02261
02262 int leftPos = sectionViewportPosition(logicalLeft);
02263 int rightPos = sectionViewportPosition(logicalRight);
02264 rightPos += sectionSize(logicalRight);
02265 return QRect(leftPos, 0, rightPos - leftPos, height());
02266 }
02267
02268 int top = d->model->rowCount(d->root) - 1;
02269 int bottom = 0;
02270 int rangeTop, rangeBottom;
02271
02272 for (int i = 0; i < selection.count(); ++i) {
02273 QItemSelectionRange r = selection.at(i);
02274 if (r.parent().isValid() || !r.isValid())
02275 continue;
02276
02277 rangeTop = visualIndex(r.top());
02278 if (rangeTop == -1)
02279 continue;
02280 rangeBottom = visualIndex(r.bottom());
02281 if (rangeBottom == -1)
02282 continue;
02283 if (rangeTop < top)
02284 top = rangeTop;
02285 if (rangeBottom > bottom)
02286 bottom = rangeBottom;
02287 }
02288
02289 int logicalTop = logicalIndex(top);
02290 int logicalBottom = logicalIndex(bottom);
02291
02292 if (logicalTop == -1 || logicalBottom == -1)
02293 return QRect();
02294
02295 int topPos = sectionViewportPosition(logicalTop);
02296 int bottomPos = sectionViewportPosition(logicalBottom) + sectionSize(logicalBottom);
02297
02298 return QRect(0, topPos, width(), bottomPos - topPos);
02299 }
02300
02301
02302
02303
02304 int QHeaderViewPrivate::sectionHandleAt(int position)
02305 {
02306 Q_Q(QHeaderView);
02307 int visual = q->visualIndexAt(position);
02308 if (visual == -1)
02309 return -1;
02310 int log = logicalIndex(visual);
02311 int pos = q->sectionViewportPosition(log);
02312 int grip = q->style()->pixelMetric(QStyle::PM_HeaderGripMargin);
02313 if (reverse()) {
02314 if (position < pos + grip)
02315 return log;
02316 if (visual > 0 && position > pos + q->sectionSize(log) - grip)
02317 return q->logicalIndex(visual - 1);
02318 } else {
02319 if (visual > 0 && position < pos + grip)
02320 return q->logicalIndex(visual - 1);
02321 if (position > pos + q->sectionSize(log) - grip)
02322 return log;
02323 }
02324 return -1;
02325 }
02326
02327 void QHeaderViewPrivate::setupSectionIndicator(int section, int position)
02328 {
02329 Q_Q(QHeaderView);
02330 if (!sectionIndicator) {
02331 sectionIndicator = new QLabel(viewport);
02332 sectionIndicator->setWindowOpacity(0.75);
02333 }
02334
02335 int x, y, w, h;
02336 int p = q->sectionViewportPosition(section);
02337 if (orientation == Qt::Horizontal) {
02338 x = p;
02339 y = 0;
02340 w = q->sectionSize(section);
02341 h = viewport->height();
02342 } else {
02343 x = 0;
02344 y = p;
02345 w = viewport->width();
02346 h = q->sectionSize(section);
02347 }
02348 sectionIndicator->resize(w, h);
02349 QPixmap pix = QPixmap::grabWidget(viewport, x, y, w, h);
02350 sectionIndicator->setPixmap(pix);
02351 sectionIndicatorOffset = position - qMax(p, 0);
02352
02353 }
02354
02355 void QHeaderViewPrivate::updateSectionIndicator(int section, int position)
02356 {
02357 if (!sectionIndicator)
02358 return;
02359
02360 if (section == -1 || target == -1) {
02361 sectionIndicator->hide();
02362 return;
02363 }
02364
02365 if (orientation == Qt::Horizontal)
02366 sectionIndicator->move(position - sectionIndicatorOffset, 0);
02367 else
02368 sectionIndicator->move(0, position - sectionIndicatorOffset);
02369
02370 sectionIndicator->show();
02371 }
02372
02373 QStyleOptionHeader QHeaderViewPrivate::getStyleOption() const
02374 {
02375 Q_Q(const QHeaderView);
02376 QStyleOptionHeader opt;
02377 opt.initFrom(q);
02378 opt.state = QStyle::State_None | QStyle::State_Raised;
02379 opt.orientation = orientation;
02380 if (orientation == Qt::Horizontal)
02381 opt.state |= QStyle::State_Horizontal;
02382 if (q->isEnabled())
02383 opt.state |= QStyle::State_Enabled;
02384 opt.section = 0;
02385 return opt;
02386 }
02387
02388 bool QHeaderViewPrivate::isSectionSelected(int section) const
02389 {
02390 int i = section * 2;
02391 if (i < 0 || i >= sectionSelected.count())
02392 return false;
02393 if (sectionSelected.testBit(i))
02394 return sectionSelected.testBit(i + 1);
02395 bool s = false;
02396 if (orientation == Qt::Horizontal)
02397 s = isColumnSelected(section);
02398 else
02399 s = isRowSelected(section);
02400 sectionSelected.setBit(i + 1, s);
02401 sectionSelected.setBit(i, true);
02402 return s;
02403 }
02404
02418 void QHeaderViewPrivate::resizeSections(QHeaderView::ResizeMode globalMode, bool useGlobalMode)
02419 {
02420 Q_Q(QHeaderView);
02421
02422 executePostedLayout();
02423 if (sectionCount == 0)
02424 return;
02425 invalidateCachedSizeHint();
02426
02427
02428 int stretchSection = -1;
02429 if (stretchLastSection && !useGlobalMode) {
02430 for (int i = sectionCount - 1; i >= 0; --i) {
02431 if (!isVisualIndexHidden(i)) {
02432 stretchSection = i;
02433 break;
02434 }
02435 }
02436 }
02437
02438
02439 int lengthToStrech = (orientation == Qt::Horizontal ? viewport->width() : viewport->height());
02440 int numberOfStretchedSections = 0;
02441 QList<int> section_sizes;
02442 for (int i = 0; i < sectionCount; ++i) {
02443 if (isVisualIndexHidden(i))
02444 continue;
02445
02446 QHeaderView::ResizeMode resizeMode;
02447 if (useGlobalMode && (i != stretchSection))
02448 resizeMode = globalMode;
02449 else
02450 resizeMode = (i == stretchSection ? QHeaderView::Stretch : visualIndexResizeMode(i));
02451
02452 if (resizeMode == QHeaderView::Stretch) {
02453 ++numberOfStretchedSections;
02454 continue;
02455 }
02456
02457
02458 int sectionSize = 0;
02459 if (resizeMode == QHeaderView::Interactive || resizeMode == QHeaderView::Fixed) {
02460 sectionSize = headerSectionSize(i);
02461 } else {
02462 int logicalIndex = q->logicalIndex(i);
02463 sectionSize = qMax(viewSectionSizeHint(logicalIndex),
02464 q->sectionSizeHint(logicalIndex));
02465 }
02466 section_sizes.append(sectionSize);
02467 lengthToStrech -= sectionSize;
02468 }
02469
02470
02471 int stretchSectionLength = 0;
02472 int pixelReminder = 0;
02473 if (numberOfStretchedSections > 0) {
02474 int hintLengthForEveryStretchedSection = lengthToStrech / numberOfStretchedSections;
02475 stretchSectionLength = qMax(hintLengthForEveryStretchedSection, q->minimumSectionSize());
02476 pixelReminder = lengthToStrech % numberOfStretchedSections;
02477 }
02478
02479 int spanStartSection = 0;
02480 int previousSectionLength = 0;
02481 QHeaderView::ResizeMode previousSectionResizeMode = QHeaderView::Interactive;
02482
02483
02484 for (int i = 0; i < sectionCount; ++i) {
02485 int oldSectionLength = headerSectionSize(i);
02486 int newSectionLength = -1;
02487 QHeaderView::ResizeMode newSectionResizeMode = headerSectionResizeMode(i);
02488
02489 if (isVisualIndexHidden(i)) {
02490 newSectionLength = 0;
02491 } else {
02492 QHeaderView::ResizeMode resizeMode;
02493 if (useGlobalMode)
02494 resizeMode = globalMode;
02495 else
02496 resizeMode = (i == stretchSection
02497 ? QHeaderView::Stretch
02498 : visualIndexResizeMode(i));
02499 if (resizeMode == QHeaderView::Stretch) {
02500 if (i == sectionCount - 1)
02501 newSectionLength = qMax(stretchSectionLength, lastSectionSize);
02502 else
02503 newSectionLength = stretchSectionLength;
02504 if (pixelReminder > 0) {
02505 newSectionLength += 1;
02506 --pixelReminder;
02507 }
02508 } else {
02509 newSectionLength = section_sizes.front();
02510 section_sizes.removeFirst();
02511 }
02512 }
02513
02514
02515 if ((previousSectionResizeMode != newSectionResizeMode
02516 || previousSectionLength != newSectionLength) && i > 0) {
02517 int spanLength = (i - spanStartSection) * previousSectionLength;
02518 createSectionSpan(spanStartSection, i - 1, spanLength, previousSectionResizeMode);
02519
02520 spanStartSection = i;
02521 }
02522
02523 if (newSectionLength != oldSectionLength)
02524 emit q->sectionResized(i, oldSectionLength, newSectionLength);
02525
02526 previousSectionLength = newSectionLength;
02527 previousSectionResizeMode = newSectionResizeMode;
02528 }
02529
02530 createSectionSpan(spanStartSection, sectionCount - 1,
02531 (sectionCount - spanStartSection) * previousSectionLength,
02532 previousSectionResizeMode);
02533
02534
02535 viewport->update();
02536 }
02537
02538 void QHeaderViewPrivate::createSectionSpan(int start, int end, int size, QHeaderView::ResizeMode mode)
02539 {
02540
02541
02542
02543 SectionSpan span(size, (end - start) + 1, mode);
02544 int start_section = 0;
02545 #ifndef QT_NO_DEBUG
02546 int initial_section_count = headerSectionCount();
02547 #endif
02548
02549 QList<int> spansToRemove;
02550 for (int i = 0; i < sectionSpans.count(); ++i) {
02551 int end_section = start_section + sectionSpans.at(i).count - 1;
02552 int section_count = sectionSpans.at(i).count;
02553 if (start <= start_section && end > end_section) {
02554
02555 spansToRemove.append(i);
02556 } else if (start < start_section && end >= end_section) {
02557
02558 spansToRemove.append(i);
02559 } else if (start == start_section && end == end_section) {
02560
02561 length -= sectionSpans.at(i).size;
02562 length += size;
02563 sectionSpans[i].size = size;
02564 sectionSpans[i].resizeMode = mode;
02565
02566 removeSpans(spansToRemove);
02567 Q_ASSERT(initial_section_count == headerSectionCount());
02568 return;
02569 } else if (start > start_section && end < end_section) {
02570 if (sectionSpans.at(i).sectionSize() == span.sectionSize()
02571 && sectionSpans.at(i).resizeMode == span.resizeMode) {
02572 Q_ASSERT(initial_section_count == headerSectionCount());
02573 return;
02574 }
02575
02576 length -= sectionSpans.at(i).size;
02577 int section_size = sectionSpans.at(i).sectionSize();
02578 #ifndef QT_NO_DEBUG
02579 int span_count = sectionSpans.at(i).count;
02580 #endif
02581 QHeaderView::ResizeMode span_mode = sectionSpans.at(i).resizeMode;
02582
02583 int first_span_count = start - start_section;
02584 int first_span_size = section_size * first_span_count;
02585 sectionSpans[i].count = first_span_count;
02586 sectionSpans[i].size = first_span_size;
02587 sectionSpans[i].resizeMode = span_mode;
02588 length += first_span_size;
02589
02590 #ifndef QT_NO_DEBUG
02591 int mid_span_count = span.count;
02592 #endif
02593 int mid_span_size = span.size;
02594 sectionSpans.insert(i + 1, span);
02595 length += mid_span_size;
02596
02597 int last_span_count = end_section - end;
02598 int last_span_size = section_size * last_span_count;
02599 sectionSpans.insert(i + 2, SectionSpan(last_span_size, last_span_count, span_mode));
02600 length += last_span_size;
02601 Q_ASSERT(span_count == first_span_count + mid_span_count + last_span_count);
02602 removeSpans(spansToRemove);
02603 Q_ASSERT(initial_section_count == headerSectionCount());
02604 return;
02605 } else if (start > start_section && start <= end_section && end >= end_section) {
02606
02607 length -= sectionSpans.at(i).size;
02608 int removed_count = (end_section - start + 1);
02609 int span_count = sectionSpans.at(i).count - removed_count;
02610 int section_size = sectionSpans.at(i).sectionSize();
02611 int span_size = section_size * span_count;
02612 sectionSpans[i].count = span_count;
02613 sectionSpans[i].size = span_size;
02614 length += span_size;
02615 if (end == end_section) {
02616 sectionSpans.insert(i + 1, span);
02617 length += span.size;
02618 removeSpans(spansToRemove);
02619 Q_ASSERT(initial_section_count == headerSectionCount());
02620 return;
02621 }
02622 } else if (end < end_section && end >= start_section && start <= start_section) {
02623
02624 length -= sectionSpans.at(i).size;
02625 int removed_count = (end - start_section + 1);
02626 int section_size = sectionSpans.at(i).sectionSize();
02627 int span_count = sectionSpans.at(i).count - removed_count;
02628 int span_size = section_size * span_count;
02629 sectionSpans[i].count = span_count;
02630 sectionSpans[i].size = span_size;
02631 length += span_size;
02632 sectionSpans.insert(i, span);
02633 length += span.size;
02634 removeSpans(spansToRemove);
02635 Q_ASSERT(initial_section_count == headerSectionCount());
02636 return;
02637 }
02638 start_section += section_count;
02639 }
02640
02641
02642
02643
02644 if (spansToRemove.isEmpty()) {
02645 if (!sectionSpans.isEmpty()
02646 && sectionSpans.last().sectionSize() == span.sectionSize()
02647 && sectionSpans.last().resizeMode == span.resizeMode) {
02648 length += span.size;
02649 int last = sectionSpans.count() - 1;
02650 sectionSpans[last].count += span.count;
02651 sectionSpans[last].size += span.size;
02652 sectionSpans[last].resizeMode = span.resizeMode;
02653 } else {
02654 length += span.size;
02655 sectionSpans.append(span);
02656 }
02657 } else {
02658 removeSpans(spansToRemove);
02659 length += span.size;
02660 sectionSpans.insert(spansToRemove.first(), span);
02661
02662 }
02663 }
02664
02665 void QHeaderViewPrivate::removeSectionsFromSpans(int start, int end)
02666 {
02667
02668 int start_section = 0;
02669 QList<int> spansToRemove;
02670 for (int i = 0; i < sectionSpans.count(); ++i) {
02671 int end_section = start_section + sectionSpans.at(i).count - 1;
02672 int section_size = sectionSpans.at(i).sectionSize();
02673 int section_count = sectionSpans.at(i).count;
02674 if (start <= start_section && end >= end_section) {
02675
02676 spansToRemove.append(i);
02677 if (end == end_section)
02678 break;
02679 } else if (start > start_section && end < end_section) {
02680
02681 int change = (end - start + 1);
02682 sectionSpans[i].count -= change;
02683 sectionSpans[i].size = section_size * sectionSpans.at(i).count;
02684 length -= (change * section_size);
02685 break;
02686 } else if (start >= start_section && start <= end_section) {
02687
02688 int change = qMin(end_section - start + 1, end - start + 1);
02689 sectionSpans[i].count -= change;
02690 sectionSpans[i].size = section_size * sectionSpans.at(i).count;
02691 start += change;
02692 length -= (change * section_size);
02693
02694 } else if (end >= start_section && end <= end_section) {
02695
02696 int change = qMin((end - start_section + 1), end - start + 1);
02697 sectionSpans[i].count -= change;
02698 sectionSpans[i].size = section_size * sectionSpans.at(i).count;
02699 length -= (change * section_size);
02700 break;
02701 }
02702 start_section += section_count;
02703 }
02704
02705 for (int i = spansToRemove.count() - 1; i >= 0; --i) {
02706 int s = spansToRemove.at(i);
02707 length -= sectionSpans.at(s).size;
02708 sectionSpans.remove(s);
02709
02710 }
02711 }
02712
02713 void QHeaderViewPrivate::clear()
02714 {
02715 length = 0;
02716 sectionCount = 0;
02717 visualIndices.clear();
02718 logicalIndices.clear();
02719 sectionSelected.clear();
02720 sectionHidden.clear();
02721 hiddenSectionSize.clear();
02722 sectionSpans.clear();
02723 }
02724
02725 void QHeaderViewPrivate::flipSortIndicator(int section)
02726 {
02727 Q_Q(QHeaderView);
02728 bool ascending = (sortIndicatorSection != section
02729 || sortIndicatorOrder == Qt::DescendingOrder);
02730 q->setSortIndicator(section, ascending ? Qt::AscendingOrder : Qt::DescendingOrder);
02731 }
02732
02733 void QHeaderViewPrivate::cascadingResize(int visual, int newSize)
02734 {
02735 Q_Q(QHeaderView);
02736 const int minimumSize = q->minimumSectionSize();
02737 const int oldSize = headerSectionSize(visual);
02738 int delta = newSize - oldSize;
02739
02740 if (delta > 0) {
02741 bool sectionResized = false;
02742
02743
02744 for (int i = firstCascadingSection; i < visual; ++i) {
02745 if (cascadingSectionSize.contains(i)) {
02746 int currentSectionSize = headerSectionSize(i);
02747 int originalSectionSize = cascadingSectionSize.value(i);
02748 if (currentSectionSize < originalSectionSize) {
02749 int newSectionSize = currentSectionSize + delta;
02750 resizeSectionSpan(i, currentSectionSize, newSectionSize);
02751 if (newSectionSize >= originalSectionSize && false)
02752 cascadingSectionSize.remove(i);
02753 sectionResized = true;
02754 break;
02755 }
02756 }
02757
02758 }
02759
02760
02761 if (!sectionResized) {
02762 newSize = qMax(newSize, minimumSize);
02763 if (oldSize != newSize)
02764 resizeSectionSpan(visual, oldSize, newSize);
02765 }
02766
02767
02768 for (int i = visual + 1; i < sectionCount; ++i) {
02769 if (!sectionIsCascadable(i))
02770 continue;
02771 int currentSectionSize = headerSectionSize(i);
02772 if (currentSectionSize <= minimumSize)
02773 continue;
02774 int newSectionSize = qMax(currentSectionSize - delta, minimumSize);
02775
02776 resizeSectionSpan(i, currentSectionSize, newSectionSize);
02777 saveCascadingSectionSize(i, currentSectionSize);
02778 delta = delta - (currentSectionSize - newSectionSize);
02779
02780
02781 if (delta <= 0)
02782 break;
02783 }
02784 } else {
02785 bool sectionResized = false;
02786
02787
02788 for (int i = lastCascadingSection; i > visual; --i) {
02789 if (!cascadingSectionSize.contains(i))
02790 continue;
02791 int currentSectionSize = headerSectionSize(i);
02792 int originalSectionSize = cascadingSectionSize.value(i);
02793 if (currentSectionSize >= originalSectionSize)
02794 continue;
02795 int newSectionSize = currentSectionSize - delta;
02796 resizeSectionSpan(i, currentSectionSize, newSectionSize);
02797 if (newSectionSize >= originalSectionSize && false) {
02798
02799 cascadingSectionSize.remove(i);
02800 }
02801 sectionResized = true;
02802 break;
02803 }
02804
02805
02806 resizeSectionSpan(visual, oldSize, qMax(newSize, minimumSize));
02807
02808
02809 if (delta < 0 && newSize < minimumSize) {
02810 for (int i = visual - 1; i >= 0; --i) {
02811 if (!sectionIsCascadable(i))
02812 continue;
02813 int sectionSize = headerSectionSize(i);
02814 if (sectionSize <= minimumSize)
02815 continue;
02816 resizeSectionSpan(i, sectionSize, qMax(sectionSize + delta, minimumSize));
02817 saveCascadingSectionSize(i, sectionSize);
02818 break;
02819 }
02820 }
02821
02822
02823 if (!sectionResized) {
02824 for (int i = visual + 1; i < sectionCount; ++i) {
02825 if (!sectionIsCascadable(i))
02826 continue;
02827 int currentSectionSize = headerSectionSize(i);
02828 int newSectionSize = qMax(currentSectionSize - delta, minimumSize);
02829 resizeSectionSpan(i, currentSectionSize, newSectionSize);
02830 break;
02831 }
02832 }
02833 }
02834
02835 if (hasAutoResizeSections())
02836 q->resizeSections();
02837
02838 viewport->update();
02839 }
02840
02841 void QHeaderViewPrivate::resizeSectionSpan(int visualIndex, uint oldSize, uint newSize)
02842 {
02843 Q_Q(QHeaderView);
02844 QHeaderView::ResizeMode mode = headerSectionResizeMode(visualIndex);
02845 createSectionSpan(visualIndex, visualIndex, newSize, mode);
02846 emit q->sectionResized(logicalIndex(visualIndex), oldSize, newSize);
02847 }
02848
02849 int QHeaderViewPrivate::headerSectionSize(int visual) const
02850 {
02851
02852 int section_start = 0;
02853 for (int i = 0; i < sectionSpans.count(); ++i) {
02854 int section_end = section_start + sectionSpans.at(i).count - 1;
02855 if (visual >= section_start && visual <= section_end)
02856 return sectionSpans.at(i).sectionSize();
02857 section_start = section_end + 1;
02858 }
02859 return -1;
02860 }
02861
02862 int QHeaderViewPrivate::headerSectionPosition(int visual) const
02863 {
02864
02865 int section_start = 0;
02866 int span_position = 0;
02867 for (int i = 0; i < sectionSpans.count(); ++i) {
02868 int section_end = section_start + sectionSpans.at(i).count - 1;
02869 if (visual >= section_start && visual <= section_end)
02870 return span_position + (visual - section_start) * sectionSpans.at(i).sectionSize();
02871 section_start = section_end + 1;
02872 span_position += sectionSpans.at(i).size;
02873 }
02874 return -1;
02875 }
02876
02877 int QHeaderViewPrivate::headerVisualIndexAt(uint position) const
02878 {
02879
02880 uint span_start_section = 0;
02881 uint span_position = 0;
02882 for (int i = 0; i < sectionSpans.count(); ++i) {
02883 uint next_span_start_section = span_start_section + sectionSpans.at(i).count;
02884 uint next_span_position = span_position + sectionSpans.at(i).size;
02885 if (position == span_position)
02886 return span_start_section;
02887 if (position > span_position && position < next_span_position) {
02888 uint position_in_span = position - span_position;
02889 return span_start_section + (position_in_span / sectionSpans.at(i).sectionSize());
02890 }
02891 span_start_section = next_span_start_section;
02892 span_position = next_span_position;
02893 }
02894 return -1;
02895 }
02896
02897 void QHeaderViewPrivate::setHeaderSectionResizeMode(int visual, QHeaderView::ResizeMode mode)
02898 {
02899 int size = headerSectionSize(visual);
02900 createSectionSpan(visual, visual, size, mode);
02901 }
02902
02903 QHeaderView::ResizeMode QHeaderViewPrivate::headerSectionResizeMode(int visual) const
02904 {
02905 int span = sectionSpanIndex(visual);
02906 if (span == -1)
02907 return globalResizeMode;
02908 return sectionSpans.at(span).resizeMode;
02909 }
02910
02911 void QHeaderViewPrivate::setGlobalHeaderResizeMode(QHeaderView::ResizeMode mode)
02912 {
02913 globalResizeMode = mode;
02914 for (int i = 0; i < sectionSpans.count(); ++i)
02915 sectionSpans[i].resizeMode = mode;
02916 }
02917
02918 int QHeaderViewPrivate::viewSectionSizeHint(int logical) const
02919 {
02920 Q_Q(const QHeaderView);
02921 if (QAbstractItemView *parent = ::qobject_cast<QAbstractItemView*>(q->parent())) {
02922 return (orientation == Qt::Horizontal
02923 ? parent->sizeHintForColumn(logical)
02924 : parent->sizeHintForRow(logical));
02925 }
02926 return 0;
02927 }
02928
02929 int QHeaderViewPrivate::adjustedVisualIndex(int visualIndex) const
02930 {
02931 if (hiddenSectionSize.count() > 0) {
02932 int adjustedVisualIndex = visualIndex;
02933 int currentVisualIndex = 0;
02934 for (int i = 0; i < sectionSpans.count(); ++i) {
02935 if (sectionSpans.at(i).size == 0)
02936 adjustedVisualIndex += sectionSpans.at(i).count;
02937 else
02938 currentVisualIndex += sectionSpans.at(i).count;
02939 if (currentVisualIndex >= visualIndex)
02940 break;
02941 }
02942 visualIndex = adjustedVisualIndex;
02943 }
02944 return visualIndex;
02945 }
02946
02947 #endif // QT_NO_ITEMVIEWS
02948
02949 #include "moc_qheaderview.cpp"