src/gui/itemviews/qheaderview_p.h
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #ifndef QHEADERVIEW_P_H
       
    43 #define QHEADERVIEW_P_H
       
    44 
       
    45 //
       
    46 //  W A R N I N G
       
    47 //  -------------
       
    48 //
       
    49 // This file is not part of the Qt API.  It exists purely as an
       
    50 // implementation detail.  This header file may change from version to
       
    51 // version without notice, or even be removed.
       
    52 //
       
    53 // We mean it.
       
    54 //
       
    55 
       
    56 #include "private/qabstractitemview_p.h"
       
    57 
       
    58 #ifndef QT_NO_ITEMVIEWS
       
    59 
       
    60 #include "QtCore/qbitarray.h"
       
    61 #include "QtGui/qapplication.h"
       
    62 #include "QtGui/qlabel.h"
       
    63 
       
    64 QT_BEGIN_NAMESPACE
       
    65 
       
    66 class QHeaderViewPrivate: public QAbstractItemViewPrivate
       
    67 {
       
    68     Q_DECLARE_PUBLIC(QHeaderView)
       
    69 
       
    70 public:
       
    71     enum StateVersion { VersionMarker = 0xff };
       
    72 
       
    73     QHeaderViewPrivate()
       
    74         : state(NoState),
       
    75           offset(0),
       
    76           sortIndicatorOrder(Qt::DescendingOrder),
       
    77           sortIndicatorSection(0),
       
    78           sortIndicatorShown(false),
       
    79           lastPos(-1),
       
    80           firstPos(-1),
       
    81           originalSize(-1),
       
    82           section(-1),
       
    83           target(-1),
       
    84           pressed(-1),
       
    85           hover(-1),
       
    86           length(0),
       
    87           sectionCount(0),
       
    88           movableSections(false),
       
    89           clickableSections(false),
       
    90           highlightSelected(false),
       
    91           stretchLastSection(false),
       
    92           cascadingResizing(false),
       
    93           resizeRecursionBlock(false),
       
    94           stretchSections(0),
       
    95           contentsSections(0),
       
    96           minimumSectionSize(-1),
       
    97           lastSectionSize(0),
       
    98           sectionIndicatorOffset(0),
       
    99           sectionIndicator(0),
       
   100           globalResizeMode(QHeaderView::Interactive)
       
   101     {}
       
   102 
       
   103 
       
   104     int lastVisibleVisualIndex() const;
       
   105     int sectionHandleAt(int position);
       
   106     void setupSectionIndicator(int section, int position);
       
   107     void updateSectionIndicator(int section, int position);
       
   108     void updateHiddenSections(int logicalFirst, int logicalLast);
       
   109     void resizeSections(QHeaderView::ResizeMode globalMode, bool useGlobalMode = false);
       
   110     void _q_sectionsRemoved(const QModelIndex &,int,int);
       
   111     void _q_layoutAboutToBeChanged();
       
   112     void _q_layoutChanged();
       
   113 
       
   114     bool isSectionSelected(int section) const;
       
   115 
       
   116     inline bool rowIntersectsSelection(int row) const {
       
   117         return (selectionModel ? selectionModel->rowIntersectsSelection(row, root) : false);
       
   118     }
       
   119 
       
   120     inline bool columnIntersectsSelection(int column) const {
       
   121         return (selectionModel ? selectionModel->columnIntersectsSelection(column, root) : false);
       
   122     }
       
   123 
       
   124     inline bool sectionIntersectsSelection(int logical) const {
       
   125         return (orientation == Qt::Horizontal ? columnIntersectsSelection(logical) : rowIntersectsSelection(logical));
       
   126     }
       
   127 
       
   128     inline bool isRowSelected(int row) const {
       
   129         return (selectionModel ? selectionModel->isRowSelected(row, root) : false);
       
   130     }
       
   131 
       
   132     inline bool isColumnSelected(int column) const {
       
   133         return (selectionModel ? selectionModel->isColumnSelected(column, root) : false);
       
   134     }
       
   135 
       
   136     inline void prepareSectionSelected() {
       
   137         if (!selectionModel || !selectionModel->hasSelection())
       
   138             sectionSelected.clear();
       
   139         else if (sectionSelected.count() != sectionCount * 2)
       
   140             sectionSelected.fill(false, sectionCount * 2);
       
   141         else sectionSelected.fill(false);
       
   142     }
       
   143 
       
   144     inline bool reverse() const {
       
   145         return orientation == Qt::Horizontal && q_func()->isRightToLeft();
       
   146     }
       
   147 
       
   148     inline int logicalIndex(int visualIndex) const {
       
   149         return logicalIndices.isEmpty() ? visualIndex : logicalIndices.at(visualIndex);
       
   150     }
       
   151 
       
   152     inline int visualIndex(int logicalIndex) const {
       
   153         return visualIndices.isEmpty() ? logicalIndex : visualIndices.at(logicalIndex);
       
   154     }
       
   155 
       
   156     inline void setDefaultValues(Qt::Orientation o) {
       
   157         orientation = o;
       
   158         defaultSectionSize = (o == Qt::Horizontal ? 100
       
   159                               : qMax(q_func()->minimumSectionSize(), 30));
       
   160         defaultAlignment = (o == Qt::Horizontal
       
   161                             ? Qt::Alignment(Qt::AlignCenter)
       
   162                             : Qt::AlignLeft|Qt::AlignVCenter);
       
   163     }
       
   164 
       
   165     inline bool isVisualIndexHidden(int visual) const {
       
   166         return !sectionHidden.isEmpty() && sectionHidden.at(visual);
       
   167     }
       
   168 
       
   169     inline void setVisualIndexHidden(int visual, bool hidden) {
       
   170         if (!sectionHidden.isEmpty()) sectionHidden.setBit(visual, hidden);
       
   171     }
       
   172 
       
   173     inline bool hasAutoResizeSections() const {
       
   174         return stretchSections || stretchLastSection || contentsSections;
       
   175     }
       
   176 
       
   177     QStyleOptionHeader getStyleOption() const;
       
   178 
       
   179     inline void invalidateCachedSizeHint() const {
       
   180         cachedSizeHint = QSize();
       
   181     }
       
   182 
       
   183     inline void initializeIndexMapping() const {
       
   184         if (visualIndices.count() != sectionCount
       
   185             || logicalIndices.count() != sectionCount) {
       
   186             visualIndices.resize(sectionCount);
       
   187             logicalIndices.resize(sectionCount);
       
   188             for (int s = 0; s < sectionCount; ++s) {
       
   189                 visualIndices[s] = s;
       
   190                 logicalIndices[s] = s;
       
   191             }
       
   192         }
       
   193     }
       
   194 
       
   195     inline void clearCascadingSections() {
       
   196         firstCascadingSection = sectionCount;
       
   197         lastCascadingSection = 0;
       
   198         cascadingSectionSize.clear();
       
   199     }
       
   200 
       
   201     inline void saveCascadingSectionSize(int visual, int size) {
       
   202         if (!cascadingSectionSize.contains(visual)) {
       
   203             cascadingSectionSize.insert(visual, size);
       
   204             firstCascadingSection = qMin(firstCascadingSection, visual);
       
   205             lastCascadingSection = qMax(lastCascadingSection, visual);
       
   206         }
       
   207     }
       
   208 
       
   209     inline bool sectionIsCascadable(int visual) const {
       
   210         return headerSectionResizeMode(visual) == QHeaderView::Interactive;
       
   211     }
       
   212 
       
   213     inline int modelSectionCount() const {
       
   214         return (orientation == Qt::Horizontal
       
   215                 ? model->columnCount(root)
       
   216                 : model->rowCount(root));
       
   217     }
       
   218 
       
   219     inline bool modelIsEmpty() const {
       
   220         return (model->rowCount(root) == 0 || model->columnCount(root) == 0);
       
   221     }
       
   222 
       
   223     inline void doDelayedResizeSections() {
       
   224         if (!delayedResize.isActive())
       
   225             delayedResize.start(0, q_func());
       
   226     }
       
   227 
       
   228     inline void executePostedResize() const {
       
   229         if (delayedResize.isActive() && state == NoState) {
       
   230             const_cast<QHeaderView*>(q_func())->resizeSections();
       
   231         }
       
   232     }
       
   233 
       
   234     void clear();
       
   235     void flipSortIndicator(int section);
       
   236     void cascadingResize(int visual, int newSize);
       
   237 
       
   238     enum State { NoState, ResizeSection, MoveSection, SelectSections, NoClear } state;
       
   239 
       
   240     int offset;
       
   241     Qt::Orientation orientation;
       
   242     Qt::SortOrder sortIndicatorOrder;
       
   243     int sortIndicatorSection;
       
   244     bool sortIndicatorShown;
       
   245 
       
   246     mutable QVector<int> visualIndices; // visualIndex = visualIndices.at(logicalIndex)
       
   247     mutable QVector<int> logicalIndices; // logicalIndex = row or column in the model
       
   248     mutable QBitArray sectionSelected; // from logical index to bit
       
   249     mutable QBitArray sectionHidden; // from visual index to bit
       
   250     mutable QHash<int, int> hiddenSectionSize; // from logical index to section size
       
   251     mutable QHash<int, int> cascadingSectionSize; // from visual index to section size
       
   252     mutable QSize cachedSizeHint;
       
   253     mutable QBasicTimer delayedResize;
       
   254 
       
   255     int firstCascadingSection;
       
   256     int lastCascadingSection;
       
   257 
       
   258     int lastPos;
       
   259     int firstPos;
       
   260     int originalSize;
       
   261     int section; // used for resizing and moving sections
       
   262     int target;
       
   263     int pressed;
       
   264     int hover;
       
   265 
       
   266     int length;
       
   267     int sectionCount;
       
   268     bool movableSections;
       
   269     bool clickableSections;
       
   270     bool highlightSelected;
       
   271     bool stretchLastSection;
       
   272     bool cascadingResizing;
       
   273     bool resizeRecursionBlock;
       
   274     int stretchSections;
       
   275     int contentsSections;
       
   276     int defaultSectionSize;
       
   277     int minimumSectionSize;
       
   278     int lastSectionSize; // $$$
       
   279     int sectionIndicatorOffset;
       
   280     Qt::Alignment defaultAlignment;
       
   281     QLabel *sectionIndicator;
       
   282     QHeaderView::ResizeMode globalResizeMode;
       
   283     QList<QPersistentModelIndex> persistentHiddenSections;
       
   284 
       
   285     // header section spans
       
   286 
       
   287     struct SectionSpan {
       
   288         int size;
       
   289         int count;
       
   290         QHeaderView::ResizeMode resizeMode;
       
   291         inline SectionSpan() : size(0), count(0), resizeMode(QHeaderView::Interactive) {}
       
   292         inline SectionSpan(int length, int sections, QHeaderView::ResizeMode mode)
       
   293             : size(length), count(sections), resizeMode(mode) {}
       
   294         inline int sectionSize() const { return (count > 0 ? size / count : 0); }
       
   295 #ifndef QT_NO_DATASTREAM
       
   296         inline void write(QDataStream &out) const
       
   297         { out << size; out << count; out << (int)resizeMode; }
       
   298         inline void read(QDataStream &in)
       
   299         { in >> size; in >> count; int m; in >> m; resizeMode = (QHeaderView::ResizeMode)m; }
       
   300 #endif
       
   301     };
       
   302 
       
   303     QVector<SectionSpan> sectionSpans;
       
   304 
       
   305     void createSectionSpan(int start, int end, int size, QHeaderView::ResizeMode mode);
       
   306     void removeSectionsFromSpans(int start, int end);
       
   307     void resizeSectionSpan(int visualIndex, int oldSize, int newSize);
       
   308     void setDefaultSectionSize(int size);
       
   309 
       
   310     inline int headerSectionCount() const { // for debugging
       
   311         int count = 0;
       
   312         for (int i = 0; i < sectionSpans.count(); ++i)
       
   313             count += sectionSpans.at(i).count;
       
   314         return count;
       
   315     }
       
   316 
       
   317     inline int headerLength() const { // for debugging
       
   318         int len = 0;
       
   319         for (int i = 0; i < sectionSpans.count(); ++i)
       
   320             len += sectionSpans.at(i).size;
       
   321         return len;
       
   322     }
       
   323 
       
   324     inline void removeSpans(const QList<int> &spans) {
       
   325         for (int i = spans.count() - 1; i >= 0; --i) {
       
   326             length -= sectionSpans.at(spans.at(i)).size;
       
   327             sectionSpans.remove(spans.at(i));
       
   328         }
       
   329     }
       
   330 
       
   331     inline int sectionSpanIndex(int visual) const {
       
   332         int section_start = 0;
       
   333         for (int i = 0; i < sectionSpans.count(); ++i) {
       
   334             int section_end = section_start + sectionSpans.at(i).count - 1;
       
   335             if (visual >= section_start && visual <= section_end)
       
   336                 return i;
       
   337             section_start = section_end + 1;
       
   338         }
       
   339         return -1;
       
   340     }
       
   341 
       
   342     int headerSectionSize(int visual) const;
       
   343     int headerSectionPosition(int visual) const;
       
   344     int headerVisualIndexAt(int position) const;
       
   345 
       
   346     // resize mode
       
   347     void setHeaderSectionResizeMode(int visual, QHeaderView::ResizeMode mode);
       
   348     QHeaderView::ResizeMode headerSectionResizeMode(int visual) const;
       
   349     void setGlobalHeaderResizeMode(QHeaderView::ResizeMode mode);
       
   350 
       
   351     // other
       
   352     int viewSectionSizeHint(int logical) const;
       
   353     int adjustedVisualIndex(int visualIndex) const;
       
   354 
       
   355 #ifndef QT_NO_DATASTREAM
       
   356     void write(QDataStream &out) const;
       
   357     bool read(QDataStream &in);
       
   358 #endif
       
   359 
       
   360 };
       
   361 
       
   362 QT_END_NAMESPACE
       
   363 
       
   364 #endif // QT_NO_ITEMVIEWS
       
   365 
       
   366 #endif // QHEADERVIEW_P_H