⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qheader.cpp

📁 qtopia-phone-2.2.0下公共的控件实现源代码。
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************** $Id: qt/src/widgets/qheader.cpp   2.3.12   edited 2005-10-27 $**** Implementation of QHeader widget class (table header)**** Created : 961105**** 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 "qheader.h"#ifndef QT_NO_HEADER#include "qpainter.h"#include "qdrawutil.h"#include "qbitmap.h"#include "qbitarray.h"#include "qvector.h"static const int GRIPMARGIN  = 4;		//half the size of the resize areastatic const int MARKSIZE = 32;static const int QH_MARGIN = 4;struct QHeaderData{    QHeaderData(int n)    {	count = n;	labels.setAutoDelete( TRUE );	iconsets.setAutoDelete( TRUE );	sizes.resize(n);	positions.resize(n);	heights.resize(n);	labels.resize(n);	if ( int( iconsets.size() ) < n )	    iconsets.resize( n );	i2s.resize(n);	s2i.resize(n);	clicks.resize(n);	resize.resize(n);	int p =0;	for ( int i = 0; i < n ; i ++ ) {	    sizes[i] = 88;	    // heights[i] = 10; set properly in QHeader::init()	    i2s[i] = i;	    s2i[i] = i;	    positions[i] = p;	    p += sizes[i];	}	clicks_default = TRUE;	resize_default = TRUE;	clicks.fill( clicks_default );	resize.fill( resize_default );	move = TRUE;	sortColumn = -1;	sortDirection = TRUE;	positionsDirty = TRUE;    }    QArray<QCOORD>	sizes;    QArray<QCOORD>	heights;    QArray<QCOORD>	positions; // sorted by index    QVector<QString>	labels;    QVector<QIconSet>	iconsets;    QArray<int>	        i2s;    QArray<int>	        s2i;    QBitArray           clicks;    QBitArray           resize;    uint move : 1;    uint clicks_default : 1; // default value for new clicks bits    uint resize_default : 1; // default value for new resize bits    bool sortDirection;    int sortColumn;    int count;    bool positionsDirty;    void calculatePositions(){	// positions is sorted by index, not by section	positionsDirty = FALSE;	int p = 0;	for ( int i = 0; i < count; i++ ) {	    positions[i] = p;	    p +=sizes[i2s[i]];	}    }    int sectionAt( int pos ) {	// positions is sorted by index, not by section	if ( !count )	    return -1;	int l = 0;	int r = count - 1;	int i = ( (l+r+1) / 2 );	while ( r - l ) {	    if ( positions[i] > pos )		r = i -1;	    else		l = i;	    i = ( (l+r+1) / 2 );	}	if ( positions[i] <= pos && pos <= positions[i] + sizes[ i2s[i] ] )	    return i2s[i];	return -1;    }};// BEING REVISED: eiriken/*!  \class QHeader qheader.h  \brief The QHeader class provides a table header.  \ingroup advanced  This class provides a table header as known from spreadsheet-like widgets.  QHeader can be used vertically or horizontally (see setOrientation()).  With addLabel() you can add sections, and with removeLabel() you can remove  them. If you enabled clicking for one or all sections (see setClickEnabled()),  the user can reorder the sections and click on them which may be used for  sorting (see also setSortIndicator()). This feature is turned on by default.  So, if the user reorders the sections by clicking and moving them with the mouse the index  of a section may change. This means, the section you inserted at the first  position might be displayed at a different index then. To get the index at which e.g  the first section is displayed, use mapToIndex() with 0 as argument for our example.  If you want e.g. to know which section is displayed at e.g. index 3 use  mapToSection() with 3 as argument.  So, you can always work with the section numbers as you inserted them  without caring about the index at which they are displayed at the moment. Also  the API of QHeader works with the section numbers.  <img src=qheader-m.png> <img src=qheader-w.png>  \sa QListView QTableView *//*!  Constructs a horizontal header.  The \e parent and \e name arguments are sent to the QWidget constructor.*/QHeader::QHeader( QWidget *parent, const char *name )    : QWidget( parent, name, WNorthWestGravity ){    orient = Horizontal;    init( 0 );}/*!  Constructs a horizontal header with \a n sections.  The \e parent and \e name arguments are sent to the QWidget constructor.*/QHeader::QHeader( int n,  QWidget *parent, const char *name )    : QWidget( parent, name, WNorthWestGravity ){    orient = Horizontal;    init( n );}/*!  Destructs the header. */QHeader::~QHeader(){    delete d;    d = 0;}/*! \reimp */void QHeader::showEvent( QShowEvent *e ){    d->calculatePositions();    QWidget::showEvent( e );}/*!  \fn void QHeader::sizeChange( int section, int oldSize, int newSize )  This signal is emitted when the user has changed the size of some  of a \a section of the header from \a oldSize to \a newSize. This signal is  typically connected to a slot that repaints the table.*//*!  \fn void QHeader::clicked( int section )  This signal is emitted when the user clicked onto the section  \a section.  \sa pressed(), released()*//*!  \fn void QHeader::pressed( int section )  This signal is emitted when the user presses section \a section down.  \sa released()*//*!  \fn void QHeader::released( int section )  This signal is emitted when section \a section is released.  \sa pressed()*//*!  \fn void QHeader::indexChange( int section, int fromIndex, int toIndex )  This signal is emitted if the user moved the section \a section, which  was displayed at the index \a fromIndex to the new index \a toIndex.*//*!  \fn void QHeader::moved( int fromIndex, int toIndex )  \obsolete  Use indexChange() instead!  This signal is emitted when the user has moved the section which  is displayed at the index \a fromIndex to the index \a toIndex.*//*!  \fn void QHeader::sectionClicked( int index )  \obsolete  Use clicked() instead!  This signal is emitted when a part of the header is clicked. \a  index is the index at which the section is displayed.  In a list view, this signal would typically be connected to a slot  which sorts the specified column (or row).*//*!  \obsolete  Use sectionSize() instead!  Returns the size in pixels of the section which is displayed at  the index \a i.*/int QHeader::cellSize( int i ) const{    return sectionSize( mapToSection(i) );}/*!  \obsolete  Use sectionPos() instead!  Returns the position in pixels of the section which is displayed at the  index \a i. The  position is measured from the start of the header.*/int QHeader::cellPos( int i ) const{    if ( i == count() && i > 0 )	return d->positions[i-1] + d->sizes[d->i2s[i-1]]; // compatibility    return sectionPos( mapToSection(i) );}/*!  Returns the number of sections in the header.*/int QHeader::count() const{    return d->count;}/*!  \fn Orientation QHeader::orientation() const  Returns \c Horizontal if the header is horizontal, \c Vertical if  the header is vertical.  *//*!  \fn void QHeader::setTracking( bool enable )  Sets tracking if \a enable is TRUE, otherwise turns off tracking.  If tracking is on, the sizeChange() signal is emitted continuously  while the mouse is moved, otherwise it is only emitted when the  mouse button is released.  \sa tracking()  *//*!  \fn bool QHeader::tracking() const  Returns TRUE if tracking is on, FALSE otherwise.  \sa setTracking()  *//*!  Initializes with \a n columns. */void QHeader::init( int n ){    state = Idle;    offs = 0;    cachedIdx = 0; // unused    cachedPos = 0; // unused    d = new QHeaderData(n);    for ( int i = 0; i < n ; i ++ ) {	d->heights[i] = fontMetrics().lineSpacing()+6;    }    handleIdx = 0;    setMouseTracking( TRUE );    trackingIsOn = FALSE;    setBackgroundMode( PaletteButton );    setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed ) );}/*!  Sets the header orientation.  The \e orientation must be  QHeader::Vertical or QHeader::Horizontal.  When adding labels without the size parameter, setOrientation  should be called first, otherwise labels will be sized incorrectly.  \sa orientation()*/void QHeader::setOrientation( Orientation orientation ){    if (orient==orientation) return;    orient = orientation;    if ( orient == Horizontal )	setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed ) );    else	setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Preferred ) );    update();    updateGeometry();}/*!  Paints a rectangle starting at \a p, with length \s.  */void QHeader::paintRect( int p, int s ){    QPainter paint( this );    paint.setPen( QPen( black, 1, DotLine ) );    if ( orient == Horizontal )	paint.drawRect( p, 3, s, height() - 5 );    else	paint.drawRect( 3, p, height() - 5, s );}/*!  Marks the division line at \a idx.  */void QHeader::markLine( int idx ){    QPainter paint( this );    paint.setPen( QPen( black, 1, DotLine ) );    int p = pPos( idx );    int x = p - MARKSIZE/2;    int y = 2;    int x2 = p + MARKSIZE/2;    int y2 = height() - 3;    if ( orient == Vertical ) {	int t = x; x = y; y = t;	t = x2; x2 = y2; y2 = t;    }    paint.drawLine( x, y, x2, y );    paint.drawLine( x, y+1, x2, y+1 );    paint.drawLine( x, y2, x2, y2 );    paint.drawLine( x, y2-1, x2, y2-1 );    paint.drawLine( x, y, x, y2 );    paint.drawLine( x+1, y, x+1, y2 );    paint.drawLine( x2, y, x2, y2 );    paint.drawLine( x2-1, y, x2-1, y2 );}/*!  Removes the mark at the division line at \a idx.  */void QHeader::unMarkLine( int idx ){    if ( idx < 0 )	return;    int p = pPos( idx );    int x = p - MARKSIZE/2;    int y = 2;    int x2 = p + MARKSIZE/2;    int y2 = height() - 3;    if ( orient == Vertical ) {	int t = x; x = y; y = t;	t = x2; x2 = y2; y2 = t;    }    repaint( x, y, x2-x+1, y2-y+1 );}/*!  \obsolete  Use sectionAt() instead!  Returns the index at which the section is displayed, which contains  \a pos in widget coordinates, or -1 if \a pos is outside the header  sections.*/int QHeader::cellAt( int pos ) const{    return mapToIndex( sectionAt(pos + offset()) );}/*!  Tries to find a line that is not a neighbor of  \c handleIdx. */int QHeader::findLine( int c ){    int lastpos = d->positions[d->count-1] + d->sizes[d->i2s[d->count-1]];    int i = 0;    if ( c > lastpos ) {	return d->count;    } else {	int section = sectionAt( c );	if ( section < 0 )	    return handleIdx;	i = d->s2i[section];    }    if ( i == handleIdx )	return i;    if ( i == handleIdx - 1 &&  pPos( handleIdx ) - c > MARKSIZE/2 )	return i;    if ( i == handleIdx + 1 && c - pPos( i ) > MARKSIZE/2 )	return i + 1;    if ( c - pPos( i ) > pSize( i ) / 2 )	return i + 1;    else	return i;}/*!  \obsolete  Use moveSection() instead!  Moves the section which is currently displayed at the index \a fromIndex  to the index \a toIdx.*/void QHeader::moveCell( int fromIdx, int toIdx ){    moveSection( mapToSection(fromIdx), toIdx );}/*!  \reimp*/void QHeader::mousePressEvent( QMouseEvent *e ){    if ( e->button() != LeftButton || state != Idle )	return;    handleIdx = 0;    int c = orient == Horizontal ? e->pos().x() : e->pos().y();    c += offset();    int section = sectionAt( c );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -