📄 qlistview.cpp
字号:
/****************************************************************************** $Id: qt/src/widgets/qlistview.cpp 2.3.12 edited 2005-10-27 $**** Implementation of QListView widget class**** Created : 970809**** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.**** This file is part of the widgets module of the Qt GUI Toolkit.**** This file may be distributed under the terms of the Q Public License** as defined by Trolltech AS of Norway and appearing in the file** LICENSE.QPL included in the packaging of this file.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition** licenses may use this file in accordance with the Qt Commercial License** Agreement provided with the Software.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for** information about Qt Commercial License Agreements.** See http://www.trolltech.com/qpl/ for QPL licensing information.** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#include "qlistview.h"#ifndef QT_NO_LISTVIEW#include "qtimer.h"#include "qheader.h"#include "qpainter.h"#include "qstack.h"#include "qlist.h"#include "qstrlist.h"#include "qapplication.h"#include "qbitmap.h"#include "qdatetime.h"#include "qptrdict.h"#include "qvector.h"#include "qiconset.h"#include "qpixmapcache.h"#include <stdlib.h> // qsort#include <ctype.h> // tolower#ifdef QT_KEYPAD_MODEextern bool qt_singleFocusWidget(const QWidget *in);extern bool qt_modalEditingEnabled;#endifconst int Unsorted = 16383;static QBitmap * verticalLine = 0;static QBitmap * horizontalLine = 0;static QPixmap *buffer = 0;static void cleanupLVBuffer(){ delete buffer; buffer = 0;}static QPixmap *getCacheBuffer( const QSize &sz ){ if ( !buffer ) { qAddPostRoutine( cleanupLVBuffer ); buffer = new QPixmap; } if ( buffer->width() < sz.width() || buffer->height() < sz.height() ) buffer->resize( sz ); return buffer;}static void cleanupBitmapLines(){ delete verticalLine; delete horizontalLine; verticalLine = 0; horizontalLine = 0;}struct QListViewPrivate{ // classes that are here to avoid polluting the global name space // the magical hidden mother of all items class Root: public QListViewItem { public: Root( QListView * parent ); void setHeight( int ); void invalidateHeight(); void setup(); QListView * theListView() const; QListView * lv; }; // for the stack used in drawContentsOffset() class Pending { public: Pending( int level, int ypos, QListViewItem * item) : l(level), y(ypos), i(item) {}; int l; // level of this item; root is -1 or 0 int y; // level of this item in the tree QListViewItem * i; // the item itself }; // to remember what's on screen class DrawableItem { public: DrawableItem( Pending * pi ) { y=pi->y; l=pi->l; i=pi->i; }; int y; int l; QListViewItem * i; }; // for sorting class SortableItem { public: QString key; QListViewItem * i; }; class ItemColumnInfo { public: ItemColumnInfo(): pm( 0 ), next( 0 ), truncated( FALSE ), dirty( FALSE ), width( 0 ) {} ~ItemColumnInfo() { delete pm; delete next; } QString text, tmpText; QPixmap * pm; ItemColumnInfo * next; uint truncated : 1; uint dirty : 1; int width; }; class ViewColumnInfo { public: ViewColumnInfo(): align(Qt::AlignLeft), sortable(TRUE), next( 0 ) {} ~ViewColumnInfo() { delete next; } int align; bool sortable; ViewColumnInfo * next; }; // private variables used in QListView ViewColumnInfo * vci; QHeader * h; Root * r; uint rootIsExpandable : 1; int margin; QListViewItem * focusItem, *highlighted; QTimer * timer; QTimer * dirtyItemTimer; QTimer * visibleTimer; int levelWidth; // the list of drawables, and the range drawables covers entirely // (it may also include a few items above topPixel) QList<DrawableItem> * drawables; int topPixel; int bottomPixel; QPtrDict<void> * dirtyItems; QListView::SelectionMode selectionMode; // TRUE if the widget should take notice of mouseReleaseEvent bool buttonDown; // TRUE if the widget should ignore a double-click bool ignoreDoubleClick; // Per-column structure for information not in the QHeader struct Column { QListView::WidthMode wmode; }; QVector<Column> column; // sort column and order #### may need to move to QHeader [subclass] int sortcolumn; bool ascending; bool sortIndicator; // suggested height for the items int fontMetricsHeight; int minLeftBearing, minRightBearing; bool allColumnsShowFocus; // currently typed prefix for the keyboard interface, and the time // of the last key-press QString currentPrefix; QTime currentPrefixTime; // whether to select or deselect during this mouse press. bool select; // holds a list of iterators QList<QListViewItemIterator> *iterators; QListViewItem *pressedItem, *selectAnchor; QTimer *scrollTimer; bool clearing; bool pressedSelected; bool useDoubleBuffer; QSize sizeHint;};// these should probably be in QListViewPrivate, for future thread safetystatic bool activatedByClick;static QPoint activatedP;// NOT REVISED/*! \class QListViewItem qlistview.h \brief The QListViewItem class implements a list view item. A list view item is a multi-column object capable of displaying itself. Its design has the following main goals: <ul> <li> Work quickly and well for \e large sets of data. <li> Be easy to use in the simple case. </ul> The simplest way to use QListViewItem is to construct one with a few constant strings. This creates an item which is a child of \e parent, with two fixed-content strings, and discards the pointer to it: \code (void) new QListViewItem( parent, "first column", "second column" ); \endcode This object will be deleted when \e parent is deleted, as for \link QObject QObjects. \endlink The parent is either another QListViewItem or a QListView. If the parent is a QListView, this item is a top-level item within that QListView. If the parent is another QListViewItem, this item becomes a child of the parent item. If you keep the pointer, you can set or change the texts using setText(), add pixmaps using setPixmap(), change its mode using setSelectable(), setSelected(), setOpen() and setExpandable(), change its height using setHeight(), and do much tree traversal. The set* functions in QListView also affect QListViewItem, of course. You can traverse the tree as if it were a doubly linked list using itemAbove() and itemBelow(); they return pointers to the items directly above and below this item on the screen (even if none of the three are actually visible at the moment). You can also traverse it as a tree, using parent(), firstChild() and nextSibling(). This code does something to each of an item's children: \code QListViewItem * myChild = myItem->firstChild(); while( myChild ) { doSomething( myChild ); myChild = myChild->nextSibling(); } \endcode Also there is now an iterator class to traverse a tree of list view items. To iterate over all items of a list view, do: \code QListViewItemIterator it( listview ); for ( ; it.current(); ++it ) do_something_with_the_item( it.current() ); \endcode Note that the order of the children will change when the sorting order changes, and is undefined if the items are not visible. You can however call enforceSortOrder() at any time, and QListView will always call it before it needs to show an item. Many programs will need to reimplement QListViewItem. The most commonly reimplemented functions are: <ul> <li> text() returns the text in a column. Many subclasses will compute that on the fly. <li> key() is used for sorting. The default key() simply calls text(), but judicious use of key can be used to sort by e.g. date (as QFileDialog does). <li> setup() is called before showing the item, and whenever e.g. the font changes. <li> activate() is called whenever the user clicks on the item or presses space when the item is the currently highlighted item.</ul> Some subclasses call setExpandable( TRUE ) even when they have no children, and populate themselves when setup() or setOpen( TRUE ) is called. The dirview/dirview.cpp example program uses precisely this technique to start up quickly: The files and subdirectories in a directory aren't entered into the tree until they need to.*//*! Constructs a new top-level list view item in the QListView \a parent.*/QListViewItem::QListViewItem( QListView * parent ){ init(); parent->insertItem( this );}/*! Constructs a new list view item which is a child of \a parent and first in the parent's list of children. */QListViewItem::QListViewItem( QListViewItem * parent ){ init(); parent->insertItem( this );}/*! Constructs an empty list view item which is a child of \a parent and is after \a after in the parent's list of children */QListViewItem::QListViewItem( QListView * parent, QListViewItem * after ){ init(); parent->insertItem( this ); moveToJustAfter( after );}/*! Constructs an empty list view item which is a child of \a parent and is after \a after in the parent's list of children */QListViewItem::QListViewItem( QListViewItem * parent, QListViewItem * after ){ init(); parent->insertItem( this ); moveToJustAfter( after );}/*! Constructs a new list view item in the QListView \a parent, \a parent, with at most 8 constant strings as contents. \code (void)new QListViewItem( lv, "/", "Root directory" ); \endcode \sa setText()*/QListViewItem::QListViewItem( QListView * parent, QString label1, QString label2, QString label3, QString label4, QString label5, QString label6, QString label7, QString label8 ){ init(); parent->insertItem( this ); setText( 0, label1 ); setText( 1, label2 ); setText( 2, label3 ); setText( 3, label4 ); setText( 4, label5 ); setText( 5, label6 ); setText( 6, label7 ); setText( 7, label8 );}/*! Constructs a new list view item that's a child of the QListViewItem \a parent, with at most 8 constant strings as contents. Possible example in a threaded news or e-mail reader: \code (void)new QListViewItem( parentMessage, author, subject ); \endcode \sa setText()*/QListViewItem::QListViewItem( QListViewItem * parent, QString label1, QString label2, QString label3, QString label4, QString label5, QString label6, QString label7, QString label8 ){ init(); parent->insertItem( this ); setText( 0, label1 ); setText( 1, label2 ); setText( 2, label3 ); setText( 3, label4 ); setText( 4, label5 ); setText( 5, label6 ); setText( 6, label7 ); setText( 7, label8 );}/*! Constructs a new list view item in the QListView \a parent, after item \a after, with at most 8 constant strings as contents. Note that the order is changed according to QListViewItem::key() unless the list view's sorting is disabled using QListView::setSorting( -1 ). \sa setText()*/QListViewItem::QListViewItem( QListView * parent, QListViewItem * after, QString label1, QString label2, QString label3, QString label4, QString label5, QString label6, QString label7, QString label8 ){ init(); parent->insertItem( this ); moveToJustAfter( after ); setText( 0, label1 ); setText( 1, label2 ); setText( 2, label3 ); setText( 3, label4 ); setText( 4, label5 ); setText( 5, label6 ); setText( 6, label7 ); setText( 7, label8 );}/*! Constructs a new list view item that's a child of the QListViewItem \a parent, after item \a after, with at most 8 constant strings as contents. Note that the order is changed according to QListViewItem::key() unless the list view's sorting is disabled using QListView::setSorting( -1 ). \sa setText()*/QListViewItem::QListViewItem( QListViewItem * parent, QListViewItem * after, QString label1, QString label2,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -