📄 qcolumnview.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include <qglobal.h>#ifndef QT_NO_COLUMNVIEW#include "qcolumnview.h"#include "qcolumnview_p.h"#include "qcolumnviewgrip_p.h"#include <qlistview.h>#include <qabstractitemdelegate.h>#include <qscrollbar.h>#include <qpainter.h>#include <qdebug.h>#include <qpainterpath.h>#define ANIMATION_DURATION_MSEC 150/*! \since 4.3 \class QColumnView \brief The QColumnView class provides a model/view implementation of a column view. \ingroup model-view \mainclass QColumnView displays a model in a number of QListViews, one for each hierarchy in the tree. This is sometimes referred to as a cascading list. The QColumnView class is one of the \l{Model/View Classes} and is part of Qt's \l{Model/View Programming}{model/view framework}. QColumnView implements the interfaces defined by the QAbstractItemView class to allow it to display data provided by models derived from the QAbstractItemModel class. \image qcolumnview.png \sa \link model-view-programming.html Model/View Programming\endlink*//*! Constructs a column view with a \a parent to represent a model's data. Use setModel() to set the model. \sa QAbstractItemModel*/QColumnView::QColumnView(QWidget * parent): QAbstractItemView(*new QColumnViewPrivate, parent){ Q_D(QColumnView); d->initialize();}/*! \internal*/QColumnView::QColumnView(QColumnViewPrivate & dd, QWidget * parent): QAbstractItemView(dd, parent){ Q_D(QColumnView); d->initialize();}void QColumnViewPrivate::initialize(){ Q_Q(QColumnView); q->setTextElideMode(Qt::ElideMiddle); q->connect(¤tAnimation, SIGNAL(frameChanged(int)), q->horizontalScrollBar(), SLOT(setValue(int))); q->connect(¤tAnimation, SIGNAL(finished()), q, SLOT(_q_changeCurrentColumn())); delete itemDelegate; q->setItemDelegate(new QColumnViewDelegate(q));}/*! Destroys the column view.*/QColumnView::~QColumnView(){}/*! \property QColumnView::resizeGripsVisible \brief the way to specify if the list views gets resize grips or not By default, \c visible is set to true \sa setRootIndex()*/void QColumnView::setResizeGripsVisible(bool visible){ Q_D(QColumnView); if (d->showResizeGrips == visible) return; d->showResizeGrips = visible; for (int i = 0; i < d->columns.count(); ++i) { QAbstractItemView *view = d->columns[i]; if (visible) { QColumnViewGrip *grip = new QColumnViewGrip(view); view->setCornerWidget(grip); connect(grip, SIGNAL(gripMoved(int)), this, SLOT(_q_gripMoved(int))); } else { QWidget *widget = view->cornerWidget(); view->setCornerWidget(0); widget->deleteLater(); } }}bool QColumnView::resizeGripsVisible() const{ Q_D(const QColumnView); return d->showResizeGrips;}/*! \reimp*/void QColumnView::setModel(QAbstractItemModel *model){ Q_D(QColumnView); d->closeColumns(); QAbstractItemView::setModel(model);}/*! \reimp*/void QColumnView::setRootIndex(const QModelIndex &index){ Q_D(QColumnView); if (!model()) return; d->closeColumns(); Q_ASSERT(d->columns.count() == 0); QAbstractItemView *view = d->createColumn(index, true); view->selectionModel()->deleteLater(); view->setSelectionModel(selectionModel()); QAbstractItemView::setRootIndex(index); d->updateScrollbars();}/*! \reimp*/bool QColumnView::isIndexHidden(const QModelIndex &index) const{ Q_UNUSED(index); return false;}/*! \reimp*/QModelIndex QColumnView::indexAt(const QPoint &point) const{ Q_D(const QColumnView); for (int i = 0; i < d->columns.size(); ++i) { QPoint topLeft = d->columns.at(i)->frameGeometry().topLeft(); QPoint adjustedPoint(point.x() - topLeft.x(), point.y() - topLeft.y()); QModelIndex index = d->columns.at(i)->indexAt(adjustedPoint); if (index.isValid()) return index; } return QModelIndex();}/*! \reimp*/QRect QColumnView::visualRect(const QModelIndex &index) const{ if (!index.isValid()) return QRect(); Q_D(const QColumnView); for (int i = 0; i < d->columns.size(); ++i) { QRect rect = d->columns.at(i)->visualRect(index); if (!rect.isNull()) { rect.translate(d->columns.at(i)->frameGeometry().topLeft()); return rect; } } return QRect();}/*! \reimp */void QColumnView::scrollContentsBy(int dx, int dy){ Q_D(QColumnView); if (d->columns.isEmpty() || dx == 0) return; dx = isRightToLeft() ? -dx : dx; for (int i = 0; i < d->columns.count(); ++i) d->columns.at(i)->move(d->columns.at(i)->x() + dx, 0); d->offset += dx; QAbstractItemView::scrollContentsBy(dx, dy);}/*! \reimp*/void QColumnView::scrollTo(const QModelIndex &index, ScrollHint hint){ Q_D(QColumnView); Q_UNUSED(hint); if (!index.isValid() || d->columns.isEmpty()) return; if (d->currentAnimation.state() == QTimeLine::Running) return; d->currentAnimation.stop(); // Fill up what is needed to get to index d->closeColumns(index, true); QModelIndex indexParent = index.parent(); // Find the left edge of the column that contains index int currentColumn = 0; int leftEdge = 0; while (currentColumn < d->columns.size()) { if (indexParent == d->columns.at(currentColumn)->rootIndex()) break; leftEdge += d->columns.at(currentColumn)->width(); ++currentColumn; } // Don't let us scroll above the root index if (currentColumn == d->columns.size()) return; int indexColumn = currentColumn; // Find the width of what we want to show (i.e. the right edge) int visibleWidth = d->columns.at(currentColumn)->width(); // We want to always try to show two columns if (currentColumn + 1 < d->columns.size()) { ++currentColumn; visibleWidth += d->columns.at(currentColumn)->width(); } int rightEdge = leftEdge + visibleWidth; if (isRightToLeft()) { leftEdge = viewport()->width() - leftEdge; rightEdge = leftEdge - visibleWidth; qSwap(rightEdge, leftEdge); } // If it is already visible don't animate if (leftEdge > -horizontalOffset() && rightEdge <= ( -horizontalOffset() + viewport()->size().width())) { d->columns.at(indexColumn)->scrollTo(index); d->_q_changeCurrentColumn(); return; } int newScrollbarValue = 0; if (isRightToLeft()) { if (leftEdge < 0) { // scroll to the right newScrollbarValue = viewport()->size().width() - leftEdge; } else { // scroll to the left newScrollbarValue = rightEdge + horizontalOffset(); } } else { if (leftEdge > -horizontalOffset()) { // scroll to the right newScrollbarValue = rightEdge - viewport()->size().width(); } else { // scroll to the left newScrollbarValue = leftEdge; } } //horizontalScrollBar()->setValue(newScrollbarValue); //d->_q_changeCurrentColumn(); //return; // or do the following currentAnimation int oldValue = horizontalScrollBar()->value(); if (oldValue < newScrollbarValue) { d->currentAnimation.setFrameRange(oldValue, newScrollbarValue); d->currentAnimation.setDirection(QTimeLine::Forward); d->currentAnimation.setCurrentTime(0); } else { d->currentAnimation.setFrameRange(newScrollbarValue, oldValue); d->currentAnimation.setDirection(QTimeLine::Backward); } d->currentAnimation.start();}/*! \reimp Move left should go to the parent index Move right should go to the child index or down if there is no child*/QModelIndex QColumnView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers){ // the child views which have focus get to deal with this first and if // they don't accept it then it comes up this this view and we only grip left/right Q_UNUSED(modifiers); if (!model()) return QModelIndex(); QModelIndex current = currentIndex(); if (isRightToLeft()) { if (cursorAction == MoveLeft) cursorAction = MoveRight; else if (cursorAction == MoveRight) cursorAction = MoveLeft; } switch (cursorAction) { case MoveLeft: if (current.parent().isValid() && current.parent() != rootIndex()) return (current.parent()); else return current; break; case MoveRight: if (model()->hasChildren(current)) return model()->index(0, 0, current); else return current.sibling(current.row() + 1, current.column()); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -