?? qcombobox.cpp
字號:
/************************************************************************ $Id: qt/src/widgets/qcombobox.cpp 2.3.12 edited 2005-10-27 $**** Implementation of QComboBox widget class**** Created : 940426**** 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 "qcombobox.h"#ifndef QT_NO_COMBOBOX#include "qpopupmenu.h"#include "qlistbox.h"#include "qpainter.h"#include "qdrawutil.h"#include "qstrlist.h"#include "qpixmap.h"#include "qtimer.h"#include "qapplication.h"#include "qlineedit.h"#include "qbitmap.h"#include "qeffects_p.h"#include <limits.h>#ifdef QT_KEYPAD_MODEextern bool qt_modalEditingEnabled;#endif#ifndef _WS_QWS_#define Q_WS_REPLAYSONPOPDOWN#endif// NOT REVISED/*! \class QComboBox qcombobox.h \brief The QComboBox widget is a combined button and popup list. \ingroup basic A combo box may be defined as a selection widget which displays the current selection, and which can pop up a list of possible selections. Some combo boxes also allow the user to select arbitrary strings, using a line editor. Since combo boxes occupy little screen space and always display the current selection, they are very well suited to displaying and selecting modes (such as font family and size): The user can always see what mode he/she is in, and the majority of the screen space is available for real work. QComboBox supports three different appearances: Motif 1.x, Motif 2.0 and Windows 95. In Motif 1.x, a combo box was called XmOptionMenu. In Motif 2.0, OSF introduced an improved combo box and named that XmComboBox. QComboBox provides both. QComboBox provides two different constructors. The simplest one creates an old-style combo box in Motif style: \code QComboBox * c = new QComboBox( this, "read-only combo" ); \endcode The other one creates a new-style combo box in Motif style, and can create both read-only and read-write combo boxes: \code QComboBox * c1 = new QComboBox( FALSE, this, "read-only combo" ); QComboBox * c2 = new QComboBox( TRUE, this, "read-write combo" ); \endcode New-style combo boxes use a list box in both Motif and Windows styles, and both the content size and the on-screen size of the list box can be limited. Old-style combo boxes use a popup in Motif style, and that popup will happily grow larger than the desktop if you put enough data in it. The two constructors create identical-looking combos in Windows style. Combo boxes can contain pixmaps as well as texts; the insert() and changeItem() functions are suitably overloaded. For read-write combo boxes, the function clearEdit() is provided, to clear the displayed string without changing the combo box' contents. A combo box emits two signals, activated() and highlighted(), when a new item has been activated (selected) or highlighted (set to current). Both signals exist in two versions, one with a \c char* argument and one with an \c int argument. If the user highlights or activates a pixmap, only the \c int signals are emitted. When the user enters a new string in a read-write combo, the widget may or may not insert it, and it can insert it in several locations. The default policy is is \c AtBottom, you can change it using setInsertionPolicy(). It is possible to constrain the input to an editable combo box using QValidator; see setValidator(). By default, all input is accepted. If the combo box is not editable then it has a default focusPolicy() of \c TabFocus, i.e. it will not grab focus if clicked. This differs from both Windows and Motif. If the combo box is editable then it has a default focusPolicy() of \c StrongFocus, i.e. it will grab focus if clicked. <img src="qcombo1-m.png">(Motif 1, read-only)<br clear=all> <img src="qcombo2-m.png">(Motif 2, read-write)<br clear=all> <img src="qcombo3-m.png">(Motif 2, read-only)<br clear=all> <img src="qcombo1-w.png">(Windows style) \sa QLineEdit QListBox QSpinBox QRadioButton QButtonGroup <a href="guibooks.html#fowler">GUI Design Handbook: Combo Box,</a> <a href="guibooks.html#fowler">GUI Design Handbook: Drop-Down List Box.</a>*//*! \enum QComboBox::Policy This enum type specifies what QComboBox should do with a new string entered by the user. The following policies are defined: <ul> <li> \c NoInsertion means not to insert the string in the combo. <li> \c AtTop means to insert the string at the top of the combo box. <li> \c AtCurrent means to replace the previously selected item with the typed string. <li> \c AtBottom means to insert the string at the bottom of the combo box. <li> \c AfterCurrent means to to insert the string just after the previously selected item. <li> \c BeforeCurrent means to to insert the string just before the previously selected item. </ul> activated() is always emitted, of course. If inserting the new string would cause the combo box to breach its content size limit, the item at the other end of the list is deleted. The definition of "other end" is implementation-dependent.*//*! \fn void QComboBox::activated( int index ) This signal is emitted when a new item has been activated (selected). The \e index is the position of the item in the popup list.*//*! \fn void QComboBox::activated( const QString &string ) This signal is emitted when a new item has been activated (selected). \a string is the activated string. You can also use activated(int) signal, but be aware that its argument is meaningful only for selected strings, not for typed strings.*//*! \fn void QComboBox::highlighted( int index ) This signal is emitted when a new item has been set to current. The \e index is the position of the item in the popup list.*//*! \fn void QComboBox::highlighted( const QString &string ) This signal is emitted when a new item has been highlighted. \a string is the highlighted string. You can also use highlighted(int) signal.*//*! \fn void QComboBox::textChanged( const QString &string ) This signal is useful for editable comboboxes. It is emitted whenever the contents of the text entry field changes.*/class QComboBoxPopup : public QPopupMenu{public: int itemHeight( int index ) { return QPopupMenu::itemHeight( index ); }};struct QComboData{ QComboData( QComboBox *cb ): usingLBox( FALSE ), pop( 0 ), lBox( 0 ), combo( cb ) { duplicatesEnabled = TRUE; cb->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed ) ); } ~QComboData() { delete pop; } bool usingListBox() { return usingLBox; } QListBox * listBox() { ASSERT(usingLBox); return lBox; } QComboBoxPopup * popup() { ASSERT(!usingLBox); return pop; } void updateLinedGeometry(); void setListBox( QListBox *l ) { lBox = l ; usingLBox = TRUE; l->setMouseTracking( TRUE );} void setPopupMenu( QComboBoxPopup * pm ) { pop = pm; usingLBox = FALSE; } int current; int maxCount; int sizeLimit; QComboBox::Policy p; bool autoresize; bool poppedUp; bool mouseWasInsidePopup; bool arrowPressed; bool arrowDown;#ifdef Q_WS_REPLAYSONPOPDOWN bool discardNextMousePress;#endif bool shortClick; bool useCompletion; bool completeNow; int completeAt; bool duplicatesEnabled; int fullHeight, currHeight; QLineEdit * ed; // /bin/ed rules! QSize sizeHint;#ifdef QT_KEYPAD_MODE QString orgTxt;#endifprivate: bool usingLBox; QComboBoxPopup *pop; QListBox *lBox; QComboBox *combo;};void QComboData::updateLinedGeometry(){ if ( !ed || !combo ) return; if ( current == 0 && combo->count() == 0 ) { ed->setGeometry( combo->style().comboButtonRect( 0, 0, combo->width(), combo->height() ) ); return; } const QPixmap *pix = current < combo->count() ? combo->pixmap( current ) : 0; QRect r( combo->style().comboButtonRect( 0, 0, combo->width(), combo->height() ) ); if ( pix && pix->width() < r.width() ) r.setLeft( r.left() + pix->width() + 4 ); if ( r != ed->geometry() ) ed->setGeometry( r );}bool QComboBox::getMetrics( int *dist, int *buttonW, int *buttonH ) const{ if ( d->usingListBox() && style() == WindowsStyle ) { QRect r = arrowRect(); *buttonW = r.width(); *buttonH = r.height(); *dist = 4; } else if ( d->usingListBox() ) { *dist = 6; *buttonW = 16; *buttonH = 18; } else { *dist = 8; *buttonH = 7; *buttonW = 11; } return TRUE;}static inline bool checkInsertIndex( const char *method, const char * name, int count, int *index){ bool range_err = (*index > count);#if defined(CHECK_RANGE) if ( range_err ) qWarning( "QComboBox::%s: (%s) Index %d out of range", method, name ? name : "<no name>", *index );#else Q_UNUSED( method ) Q_UNUSED( name )#endif if ( *index < 0 ) // append *index = count; return !range_err;}static inline bool checkIndex( const char *method, const char * name, int count, int index ){ bool range_err = (index >= count);#if defined(CHECK_RANGE) if ( range_err ) qWarning( "QComboBox::%s: (%s) Index %i out of range", method, name ? name : "<no name>", index );#else Q_UNUSED( method ) Q_UNUSED( name )#endif return !range_err;}/*! Constructs a combo box widget with a parent and a name. This constructor creates a popup menu if the program uses Motif look and feel; this is compatible with Motif 1.x.*/QComboBox::QComboBox( QWidget *parent, const char *name ) : QWidget( parent, name, WResizeNoErase ){ d = new QComboData( this ); if ( style() == WindowsStyle ) { setUpListBox(); } else { d->setPopupMenu( new QComboBoxPopup ); d->popup()->setFont( font() ); connect( d->popup(), SIGNAL(activated(int)), SLOT(internalActivate(int)) ); connect( d->popup(), SIGNAL(highlighted(int)), SLOT(internalHighlight(int)) ); } d->ed = 0; d->current = 0; d->maxCount = INT_MAX; d->sizeLimit = 10; d->p = AtBottom; d->autoresize = FALSE; d->poppedUp = FALSE; d->arrowDown = FALSE;#ifdef Q_WS_REPLAYSONPOPDOWN d->discardNextMousePress = FALSE;#endif d->shortClick = FALSE; d->useCompletion = FALSE; setFocusPolicy( TabFocus ); setPalettePropagation( AllChildren ); setFontPropagation( AllChildren );}/*! Constructs a combo box with a maximum size and either Motif 2.0 or Windows look and feel. The input field can be edited if \a rw is TRUE, otherwise the user may only choose one of the items in the combo box.*/QComboBox::QComboBox( bool rw, QWidget *parent, const char *name ) : QWidget( parent, name, WResizeNoErase ){ d = new QComboData( this ); setUpListBox(); d->current = 0; d->maxCount = INT_MAX; setSizeLimit(10); d->p = AtBottom; d->autoresize = FALSE; d->poppedUp = FALSE; d->arrowDown = FALSE;#ifdef Q_WS_REPLAYSONPOPDOWN d->discardNextMousePress = FALSE;#endif d->shortClick = FALSE; d->useCompletion = FALSE; setFocusPolicy( StrongFocus ); d->ed = 0; if ( rw ) setUpLineEdit();#ifdef QT_KEYPAD_MODE if( qt_modalEditingEnabled ) setBackgroundMode( PaletteBackground ); else#endif setBackgroundMode( PaletteButton ); setPalettePropagation( AllChildren ); setFontPropagation( AllChildren );}/*! Destructs the combo box.*/QComboBox::~QComboBox(){ delete d;}/*! If the combobox is editable and the user enters some text in the lineedit of the combobox and presses return (and the insertionPolicy() is different from \c NoInsertion), the entered text is inserted into the list of this combobox. Now, if you set \a enable to TRUE here, this new text is always inserted, else it's only inserted if it doesn't already exist in the list. If you set \a enable to FALSE and the text exists already in the list, the item which contains the same text like which should be inserted, this item gets the new current item. This setting only applies when the user want's to insert a text with pressing the return key. It does \e not affect methods like insertItem() and similar.*/void QComboBox::setDuplicatesEnabled( bool enable ){ d->duplicatesEnabled = enable;}/*! Returns TRUE if the same text can be inserted multiple times into the list of the combobox, else FALSE. \sa setDuplicatesEnabled();*/bool QComboBox::duplicatesEnabled() const{ return d->duplicatesEnabled;}/*! Returns the number of items in the combo box.*/int QComboBox::count() const{ if ( d->usingListBox() ) return d->listBox()->count(); else return d->popup()->count();}/*! \overload*/void QComboBox::insertStrList( const QStrList &list, int index ){ insertStrList( &list, index );}/*! Inserts the list of strings at the index \e index in the combo box. This is only for compatibility, as it does not support Unicode strings. See insertStringList().*/void QComboBox::insertStrList( const QStrList *list, int index ){ if ( !list ) {#if defined(CHECK_NULL) ASSERT( list != 0 );#endif return; } QStrListIterator it( *list ); const char* tmp; if ( index < 0 ) index = count(); while ( (tmp=it.current()) ) { ++it; if ( d->usingListBox() ) d->listBox()->insertItem( QString::fromLatin1(tmp), index ); else d->popup()->insertItem( QString::fromLatin1(tmp), index, index ); if ( index++ == d->current && d->current < count() ) { if ( d->ed ) { d->ed->setText( text( d->current ) ); d->updateLinedGeometry(); } else update(); currentChanged(); } } if ( index != count() ) reIndex();}/*! Inserts the list of strings at the index \e index in the combo box.*/void QComboBox::insertStringList( const QStringList &list, int index ){ QStringList::ConstIterator it = list.begin(); if ( index < 0 ) index = count(); while ( it != list.end() ) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -