1 | /****************************************************************************
|
---|
2 | **
|
---|
3 | ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
---|
4 | ** Contact: Qt Software Information ([email protected])
|
---|
5 | **
|
---|
6 | ** This file is part of the Qt3Support module of the Qt Toolkit.
|
---|
7 | **
|
---|
8 | ** $QT_BEGIN_LICENSE:LGPL$
|
---|
9 | ** Commercial Usage
|
---|
10 | ** Licensees holding valid Qt Commercial licenses may use this file in
|
---|
11 | ** accordance with the Qt Commercial License Agreement provided with the
|
---|
12 | ** Software or, alternatively, in accordance with the terms contained in
|
---|
13 | ** a written agreement between you and Nokia.
|
---|
14 | **
|
---|
15 | ** GNU Lesser General Public License Usage
|
---|
16 | ** Alternatively, this file may be used under the terms of the GNU Lesser
|
---|
17 | ** General Public License version 2.1 as published by the Free Software
|
---|
18 | ** Foundation and appearing in the file LICENSE.LGPL included in the
|
---|
19 | ** packaging of this file. Please review the following information to
|
---|
20 | ** ensure the GNU Lesser General Public License version 2.1 requirements
|
---|
21 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
---|
22 | **
|
---|
23 | ** In addition, as a special exception, Nokia gives you certain
|
---|
24 | ** additional rights. These rights are described in the Nokia Qt LGPL
|
---|
25 | ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
|
---|
26 | ** package.
|
---|
27 | **
|
---|
28 | ** GNU General Public License Usage
|
---|
29 | ** Alternatively, this file may be used under the terms of the GNU
|
---|
30 | ** General Public License version 3.0 as published by the Free Software
|
---|
31 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
---|
32 | ** packaging of this file. Please review the following information to
|
---|
33 | ** ensure the GNU General Public License version 3.0 requirements will be
|
---|
34 | ** met: http://www.gnu.org/copyleft/gpl.html.
|
---|
35 | **
|
---|
36 | ** If you are unsure which license is appropriate for your use, please
|
---|
37 | ** contact the sales department at [email protected].
|
---|
38 | ** $QT_END_LICENSE$
|
---|
39 | **
|
---|
40 | ****************************************************************************/
|
---|
41 |
|
---|
42 | #include "q3combobox.h"
|
---|
43 | #ifndef QT_NO_COMBOBOX
|
---|
44 | #include "qpainter.h"
|
---|
45 | #include "qdrawutil.h"
|
---|
46 | #include "qpixmap.h"
|
---|
47 | #include "qtimer.h"
|
---|
48 | #include "qapplication.h"
|
---|
49 | #include "qlineedit.h"
|
---|
50 | #include "qbitmap.h"
|
---|
51 | #include "qstringlist.h"
|
---|
52 | #include "qstyle.h"
|
---|
53 | #include "qevent.h"
|
---|
54 | #include "qmenu.h"
|
---|
55 | #include "qmenudata.h"
|
---|
56 | #include "qstyleoption.h"
|
---|
57 | #include "qdesktopwidget.h"
|
---|
58 | #include "q3popupmenu.h"
|
---|
59 | #include "q3listbox.h"
|
---|
60 | #include "q3strlist.h"
|
---|
61 | #include "q3frame.h"
|
---|
62 | #include <limits.h>
|
---|
63 | #include <qdebug.h>
|
---|
64 | #ifndef QT_NO_EFFECTS
|
---|
65 | # include <private/qeffects_p.h>
|
---|
66 | #endif
|
---|
67 | #if defined(QT_ACCESSIBILITY_SUPPORT)
|
---|
68 | #include "qaccessible.h"
|
---|
69 | #endif
|
---|
70 |
|
---|
71 | QT_BEGIN_NAMESPACE
|
---|
72 |
|
---|
73 | /*!
|
---|
74 | \class Q3ComboBox
|
---|
75 | \brief The Q3ComboBox widget is a combined button and popup list.
|
---|
76 | \since 4.1
|
---|
77 | \compat
|
---|
78 |
|
---|
79 | A combobox is a selection widget which displays the current item
|
---|
80 | and can pop up a list of items. A combobox may be editable in
|
---|
81 | which case the user can enter arbitrary strings.
|
---|
82 |
|
---|
83 | Comboboxes provide a means of showing the user's current choice
|
---|
84 | out of a list of options in a way that takes up the minimum amount
|
---|
85 | of screen space.
|
---|
86 |
|
---|
87 | Q3ComboBox supports three different display styles: Aqua/Motif 1.x,
|
---|
88 | Motif 2.0 and Windows. In Motif 1.x, a combobox was called
|
---|
89 | XmOptionMenu. In Motif 2.0, OSF introduced an improved combobox
|
---|
90 | and named that XmComboBox. Q3ComboBox provides both.
|
---|
91 |
|
---|
92 | Q3ComboBox provides two different constructors. The simplest
|
---|
93 | constructor creates an "old-style" combobox in Motif (or Aqua)
|
---|
94 | style:
|
---|
95 | \snippet doc/src/snippets/code/src_qt3support_widgets_q3combobox.cpp 0
|
---|
96 |
|
---|
97 | The other constructor creates a new-style combobox in Motif style,
|
---|
98 | and can create both read-only and editable comboboxes:
|
---|
99 | \snippet doc/src/snippets/code/src_qt3support_widgets_q3combobox.cpp 1
|
---|
100 |
|
---|
101 | New-style comboboxes use a list box in both Motif and Windows
|
---|
102 | styles, and both the content size and the on-screen size of the
|
---|
103 | list box can be limited with sizeLimit() and setMaxCount()
|
---|
104 | respectively. Old-style comboboxes use a popup in Aqua and Motif
|
---|
105 | style, and that popup will happily grow larger than the desktop if
|
---|
106 | you put enough data into it.
|
---|
107 |
|
---|
108 | The two constructors create identical-looking comboboxes in
|
---|
109 | Windows style.
|
---|
110 |
|
---|
111 | Comboboxes can contain pixmaps as well as strings; the
|
---|
112 | insertItem() and changeItem() functions are suitably overloaded.
|
---|
113 | For editable comboboxes, the function clearEdit() is provided,
|
---|
114 | to clear the displayed string without changing the combobox's
|
---|
115 | contents.
|
---|
116 |
|
---|
117 | A combobox emits two signals, activated() and highlighted(), when
|
---|
118 | a new item has been activated (selected) or highlighted (made
|
---|
119 | current). Both signals exist in two versions, one with a \c
|
---|
120 | QString argument and one with an \c int argument. If the user
|
---|
121 | highlights or activates a pixmap, only the \c int signals are
|
---|
122 | emitted. Whenever the text of an editable combobox is changed the
|
---|
123 | textChanged() signal is emitted.
|
---|
124 |
|
---|
125 | When the user enters a new string in an editable combobox, the
|
---|
126 | widget may or may not insert it, and it can insert it in several
|
---|
127 | locations. The default policy is is \c AtBottom but you can change
|
---|
128 | this using setInsertionPolicy().
|
---|
129 |
|
---|
130 | It is possible to constrain the input to an editable combobox
|
---|
131 | using QValidator; see setValidator(). By default, any input is
|
---|
132 | accepted.
|
---|
133 |
|
---|
134 | If the combobox is not editable then it has a default
|
---|
135 | focusPolicy() of \c TabFocus, i.e. it will not grab focus if
|
---|
136 | clicked. This differs from both Windows and Motif. If the combobox
|
---|
137 | is editable then it has a default focusPolicy() of \c StrongFocus,
|
---|
138 | i.e. it will grab focus if clicked.
|
---|
139 |
|
---|
140 | A combobox can be populated using the insert functions,
|
---|
141 | insertStringList() and insertItem() for example. Items can be
|
---|
142 | changed with changeItem(). An item can be removed with
|
---|
143 | removeItem() and all items can be removed with clear(). The text
|
---|
144 | of the current item is returned by currentText(), and the text of
|
---|
145 | a numbered item is returned with text(). The current item can be
|
---|
146 | set with setCurrentItem() or setCurrentText(). The number of items
|
---|
147 | in the combobox is returned by count(); the maximum number of
|
---|
148 | items can be set with setMaxCount(). You can allow editing using
|
---|
149 | setEditable(). For editable comboboxes you can set auto-completion
|
---|
150 | using setAutoCompletion() and whether or not the user can add
|
---|
151 | duplicates is set with setDuplicatesEnabled().
|
---|
152 |
|
---|
153 | Depending on the style, Q3ComboBox will use a list box or a
|
---|
154 | popup menu to display the list of items. See setListBox() for
|
---|
155 | more information.
|
---|
156 |
|
---|
157 | \sa QComboBox, QLineEdit, QSpinBox
|
---|
158 | {GUI Design Handbook}{GUI Design Handbook: Combo Box, Drop-Down List Box}
|
---|
159 | */
|
---|
160 |
|
---|
161 |
|
---|
162 | /*!
|
---|
163 | \enum Q3ComboBox::Policy
|
---|
164 |
|
---|
165 | This enum specifies what the Q3ComboBox should do when a new string
|
---|
166 | is entered by the user.
|
---|
167 |
|
---|
168 | \value NoInsertion the string will not be inserted into the
|
---|
169 | combobox.
|
---|
170 |
|
---|
171 | \value AtTop insert the string as the first item in the combobox.
|
---|
172 |
|
---|
173 | \value AtCurrent replace the previously selected item with the
|
---|
174 | string the user has entered.
|
---|
175 |
|
---|
176 | \value AtBottom insert the string as the last item in the
|
---|
177 | combobox.
|
---|
178 |
|
---|
179 | \value AfterCurrent insert the string after the previously
|
---|
180 | selected item.
|
---|
181 |
|
---|
182 | \value BeforeCurrent insert the string before the previously
|
---|
183 | selected item.
|
---|
184 |
|
---|
185 | activated() is always emitted when the string is entered.
|
---|
186 |
|
---|
187 | If inserting the new string would cause the combobox to breach its
|
---|
188 | content size limit, the item at the other end of the list is
|
---|
189 | deleted. The definition of "other end" is
|
---|
190 | implementation-dependent.
|
---|
191 |
|
---|
192 | \omitvalue NoInsert
|
---|
193 | \omitvalue InsertAtTop
|
---|
194 | \omitvalue InsertAtCurrent
|
---|
195 | \omitvalue InsertAtBottom
|
---|
196 | \omitvalue InsertAfterCurrent
|
---|
197 | \omitvalue InsertBeforeCurrent
|
---|
198 | */
|
---|
199 |
|
---|
200 |
|
---|
201 | /*!
|
---|
202 | \fn void Q3ComboBox::activated( int index )
|
---|
203 |
|
---|
204 | This signal is emitted when a new item has been activated
|
---|
205 | (selected). The \a index is the position of the item in the
|
---|
206 | combobox.
|
---|
207 |
|
---|
208 | This signal is not emitted if the item is changed
|
---|
209 | programmatically, e.g. using setCurrentItem().
|
---|
210 | */
|
---|
211 |
|
---|
212 | /*!
|
---|
213 | \overload
|
---|
214 | \fn void Q3ComboBox::activated( const QString &string )
|
---|
215 |
|
---|
216 | This signal is emitted when a new item has been activated
|
---|
217 | (selected). \a string is the selected string.
|
---|
218 |
|
---|
219 | You can also use the activated(int) signal, but be aware that its
|
---|
220 | argument is meaningful only for selected strings, not for user
|
---|
221 | entered strings.
|
---|
222 | */
|
---|
223 |
|
---|
224 | /*!
|
---|
225 | \fn void Q3ComboBox::highlighted( int index )
|
---|
226 |
|
---|
227 | This signal is emitted when a new item has been set to be the
|
---|
228 | current item. The \a index is the position of the item in the
|
---|
229 | combobox.
|
---|
230 |
|
---|
231 | This signal is not emitted if the item is changed
|
---|
232 | programmatically, e.g. using setCurrentItem().
|
---|
233 | */
|
---|
234 |
|
---|
235 | /*!
|
---|
236 | \overload
|
---|
237 | \fn void Q3ComboBox::highlighted( const QString &string )
|
---|
238 |
|
---|
239 | This signal is emitted when a new item has been set to be the
|
---|
240 | current item. \a string is the item's text.
|
---|
241 |
|
---|
242 | You can also use the highlighted(int) signal.
|
---|
243 | */
|
---|
244 |
|
---|
245 | /*!
|
---|
246 | \fn void Q3ComboBox::textChanged( const QString &string )
|
---|
247 |
|
---|
248 | This signal is used for editable comboboxes. It is emitted
|
---|
249 | whenever the contents of the text entry field changes. \a string
|
---|
250 | contains the new text.
|
---|
251 | */
|
---|
252 |
|
---|
253 | /*!
|
---|
254 | \property Q3ComboBox::autoCompletion
|
---|
255 | \brief whether auto-completion is enabled
|
---|
256 |
|
---|
257 | This property can only be set for editable comboboxes, for
|
---|
258 | non-editable comboboxes it has no effect. It is false by default.
|
---|
259 | */
|
---|
260 |
|
---|
261 | /*!
|
---|
262 | \property Q3ComboBox::autoResize
|
---|
263 | \brief whether auto-resize is enabled
|
---|
264 | \obsolete
|
---|
265 |
|
---|
266 | If this property is set to true then the combobox will resize
|
---|
267 | itself whenever its contents change. The default is false.
|
---|
268 | */
|
---|
269 |
|
---|
270 | /*!
|
---|
271 | \property Q3ComboBox::count
|
---|
272 | \brief the number of items in the combobox
|
---|
273 | */
|
---|
274 |
|
---|
275 | /*!
|
---|
276 | \property Q3ComboBox::currentItem
|
---|
277 | \brief the index of the current item in the combobox
|
---|
278 |
|
---|
279 | Note that the activated() and highlighted() signals are only
|
---|
280 | emitted when the user changes the current item, not when it is
|
---|
281 | changed programmatically.
|
---|
282 | */
|
---|
283 |
|
---|
284 | /*!
|
---|
285 | \property Q3ComboBox::currentText
|
---|
286 | \brief the text of the combobox's current item
|
---|
287 | */
|
---|
288 |
|
---|
289 | /*!
|
---|
290 | \property Q3ComboBox::duplicatesEnabled
|
---|
291 | \brief whether duplicates are allowed
|
---|
292 |
|
---|
293 | If the combobox is editable and the user enters some text in the
|
---|
294 | combobox's lineedit and presses Enter (and the insertionPolicy()
|
---|
295 | is not \c NoInsertion), then what happens is this:
|
---|
296 | \list
|
---|
297 | \i If the text is not already in the list, the text is inserted.
|
---|
298 | \i If the text is in the list and this property is true (the
|
---|
299 | default), the text is inserted.
|
---|
300 | \i If the text is in the list and this property is false, the text
|
---|
301 | is \e not inserted; instead the item which has matching text becomes
|
---|
302 | the current item.
|
---|
303 | \endlist
|
---|
304 |
|
---|
305 | This property only affects user-interaction. You can use
|
---|
306 | insertItem() to insert duplicates if you wish regardless of this
|
---|
307 | setting.
|
---|
308 | */
|
---|
309 |
|
---|
310 | /*!
|
---|
311 | \property Q3ComboBox::editable
|
---|
312 | \brief whether the combobox is editable
|
---|
313 |
|
---|
314 | This property's default is false. Note that the combobox will be
|
---|
315 | cleared if this property is set to true for a 1.x Motif style
|
---|
316 | combobox. To avoid this, use setEditable() before inserting any
|
---|
317 | items. Also note that the 1.x version of Motif didn't have any
|
---|
318 | editable comboboxes, so the combobox will change its appearance
|
---|
319 | to a 2.0 style Motif combobox is it is set to be editable.
|
---|
320 | */
|
---|
321 |
|
---|
322 | /*!
|
---|
323 | \property Q3ComboBox::insertionPolicy
|
---|
324 | \brief the position of the items inserted by the user
|
---|
325 |
|
---|
326 | The default insertion policy is \c AtBottom. See \l Policy.
|
---|
327 | */
|
---|
328 |
|
---|
329 | /*!
|
---|
330 | \property Q3ComboBox::maxCount
|
---|
331 | \brief the maximum number of items allowed in the combobox
|
---|
332 | */
|
---|
333 |
|
---|
334 | /*!
|
---|
335 | \property Q3ComboBox::sizeLimit
|
---|
336 | \brief the maximum on-screen size of the combobox.
|
---|
337 |
|
---|
338 | This property is ignored for both Motif 1.x style and non-editable
|
---|
339 | comboboxes in Mac style. The default limit is ten
|
---|
340 | lines. If the number of items in the combobox is or grows larger
|
---|
341 | than lines, a scroll bar is added.
|
---|
342 | */
|
---|
343 |
|
---|
344 | class Q3ComboBoxPopup : public Q3PopupMenu
|
---|
345 | {
|
---|
346 | public:
|
---|
347 | Q3ComboBoxPopup( QWidget *parent=0, const char *name=0 )
|
---|
348 | : Q3PopupMenu( parent, name )
|
---|
349 | {
|
---|
350 | }
|
---|
351 |
|
---|
352 | int itemHeight( int index )
|
---|
353 | {
|
---|
354 | return Q3PopupMenu::itemHeight( index );
|
---|
355 | }
|
---|
356 | };
|
---|
357 |
|
---|
358 | static inline QString escapedComboString(const QString &str)
|
---|
359 | {
|
---|
360 | QString stringToReturn = str;
|
---|
361 | return stringToReturn.replace(QLatin1Char('&'), QLatin1String("&&"));
|
---|
362 | }
|
---|
363 |
|
---|
364 | class Q3ComboBoxPopupItem : public QMenuItem
|
---|
365 | {
|
---|
366 | Q3ListBoxItem *li;
|
---|
367 | QSize sc; // Size cache optimization
|
---|
368 | public:
|
---|
369 | Q3ComboBoxPopupItem(Q3ListBoxItem *i) : QMenuItem(), li(i), sc(0, 0) { }
|
---|
370 | virtual bool fullSpan() const { return true; }
|
---|
371 | virtual void paint( QPainter*, const QColorGroup&, bool, bool, int, int, int, int);
|
---|
372 | virtual QSize sizeHint() { if (sc.isNull()) sc = QSize(li->width(li->listBox()), QMAX(25, li->height(li->listBox()))); return sc; }
|
---|
373 | };
|
---|
374 | void Q3ComboBoxPopupItem::paint( QPainter* p, const QColorGroup&, bool,
|
---|
375 | bool, int x, int y, int, int)
|
---|
376 | {
|
---|
377 | p->save();
|
---|
378 | p->translate(x, y + ((sizeHint().height() / 2) - (li->height(li->listBox()) / 2)));
|
---|
379 | li->paint(p);
|
---|
380 | p->restore();
|
---|
381 | }
|
---|
382 |
|
---|
383 |
|
---|
384 | class Q3ComboBoxData
|
---|
385 | {
|
---|
386 | public:
|
---|
387 | Q3ComboBoxData( Q3ComboBox *cb ): current( 0 ), arrowDown(false), ed( 0 ), usingLBox( false ), pop( 0 ), lBox( 0 ), combo( cb )
|
---|
388 | {
|
---|
389 | duplicatesEnabled = true;
|
---|
390 | cb->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed ) );
|
---|
391 | }
|
---|
392 |
|
---|
393 | inline bool usingListBox() { return usingLBox; }
|
---|
394 | inline Q3ListBox * listBox() { return lBox; }
|
---|
395 | inline Q3ComboBoxPopup * popup() { return pop; }
|
---|
396 | void updateLinedGeometry();
|
---|
397 |
|
---|
398 | void setListBox( Q3ListBox *l ) { lBox = l ; usingLBox = true;
|
---|
399 | l->setMouseTracking( true );}
|
---|
400 |
|
---|
401 | void setPopupMenu( Q3ComboBoxPopup * pm, bool isPopup=true )
|
---|
402 | { pop = pm; if(isPopup) usingLBox = false; }
|
---|
403 |
|
---|
404 | QStyleOptionComboBox getStyleOption() const
|
---|
405 | {
|
---|
406 | QStyleOptionComboBox opt;
|
---|
407 | opt.init(combo);
|
---|
408 | if (!combo->editable() && combo->hasFocus())
|
---|
409 | opt.state |= QStyle::State_Selected;
|
---|
410 | opt.subControls = QStyle::SC_All;
|
---|
411 | if (arrowDown) {
|
---|
412 | opt.activeSubControls = QStyle::SC_ComboBoxArrow;
|
---|
413 | opt.state |= QStyle::State_Sunken;
|
---|
414 | }
|
---|
415 | opt.editable = combo->editable();
|
---|
416 | opt.frame = 1; // ### get from style?
|
---|
417 | if (current > -1 && current < combo->count()) {
|
---|
418 | opt.currentText = combo->text(current);
|
---|
419 | if (combo->pixmap(current))
|
---|
420 | opt.currentIcon = QIcon(*combo->pixmap(current));
|
---|
421 | }
|
---|
422 | opt.iconSize = QSize(22, 22); // ### need a sane value here
|
---|
423 | // if (container && container->isVisible())
|
---|
424 | // opt.state |= QStyle::State_On;
|
---|
425 | return opt;
|
---|
426 | }
|
---|
427 |
|
---|
428 | int current;
|
---|
429 | int maxCount;
|
---|
430 | int sizeLimit;
|
---|
431 | Q3ComboBox::Policy p;
|
---|
432 | bool autoresize;
|
---|
433 | bool poppedUp;
|
---|
434 | bool mouseWasInsidePopup;
|
---|
435 | bool arrowPressed;
|
---|
436 | bool arrowDown;
|
---|
437 | bool discardNextMousePress;
|
---|
438 | bool shortClick;
|
---|
439 | bool useCompletion;
|
---|
440 | bool completeNow;
|
---|
441 | int completeAt;
|
---|
442 | bool duplicatesEnabled;
|
---|
443 | int fullHeight, currHeight;
|
---|
444 |
|
---|
445 | QLineEdit * ed; // /bin/ed rules!
|
---|
446 | QTimer *completionTimer;
|
---|
447 |
|
---|
448 | QSize sizeHint;
|
---|
449 | QHash<int, QPixmap> popupPixmaps;
|
---|
450 |
|
---|
451 | private:
|
---|
452 | bool usingLBox;
|
---|
453 | Q3ComboBoxPopup *pop;
|
---|
454 | Q3ListBox *lBox;
|
---|
455 | Q3ComboBox *combo;
|
---|
456 | };
|
---|
457 |
|
---|
458 | void Q3ComboBoxData::updateLinedGeometry()
|
---|
459 | {
|
---|
460 | if ( !ed || !combo )
|
---|
461 | return;
|
---|
462 |
|
---|
463 | QStyleOptionComboBox opt = getStyleOption();
|
---|
464 | QRect r = combo->style()->subControlRect(
|
---|
465 | QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxEditField, combo);
|
---|
466 |
|
---|
467 | const QPixmap *pix = current < combo->count() ? combo->pixmap( current ) : 0;
|
---|
468 | if ( pix && pix->width() < r.width() )
|
---|
469 | r.setLeft( r.left() + pix->width() + 4 );
|
---|
470 | if ( r != ed->geometry() )
|
---|
471 | ed->setGeometry( r );
|
---|
472 | }
|
---|
473 |
|
---|
474 | static inline bool checkInsertIndex( const char *method, const char * name,
|
---|
475 | int count, int *index)
|
---|
476 | {
|
---|
477 | bool range_err = (*index > count);
|
---|
478 | #if defined(QT_CHECK_RANGE)
|
---|
479 | if ( range_err )
|
---|
480 | qWarning( "Q3ComboBox::%s: (%s) Index %d out of range",
|
---|
481 | method, name ? name : "<no name>", *index );
|
---|
482 | #else
|
---|
483 | Q_UNUSED( method )
|
---|
484 | Q_UNUSED( name )
|
---|
485 | #endif
|
---|
486 | if ( *index < 0 ) // append
|
---|
487 | *index = count;
|
---|
488 | return !range_err;
|
---|
489 | }
|
---|
490 |
|
---|
491 |
|
---|
492 | static inline bool checkIndex( const char *method, const char * name,
|
---|
493 | int count, int index )
|
---|
494 | {
|
---|
495 | bool range_err = (index >= count);
|
---|
496 | #if defined(QT_CHECK_RANGE)
|
---|
497 | if ( range_err )
|
---|
498 | qWarning( "Q3ComboBox::%s: (%s) Index %i out of range",
|
---|
499 | method, name ? name : "<no name>", index );
|
---|
500 | #else
|
---|
501 | Q_UNUSED( method )
|
---|
502 | Q_UNUSED( name )
|
---|
503 | #endif
|
---|
504 | return !range_err;
|
---|
505 | }
|
---|
506 |
|
---|
507 |
|
---|
508 |
|
---|
509 | /*!
|
---|
510 | Constructs a combobox widget with parent \a parent called \a name.
|
---|
511 |
|
---|
512 | This constructor creates a popup list if the program uses Motif
|
---|
513 | (or Aqua) look and feel; this is compatible with Motif 1.x and
|
---|
514 | Aqua.
|
---|
515 |
|
---|
516 | Note: If you use this constructor to create your Q3ComboBox, then
|
---|
517 | the pixmap() function will always return 0. To workaround this,
|
---|
518 | use the other constructor.
|
---|
519 |
|
---|
520 | */
|
---|
521 |
|
---|
522 |
|
---|
523 |
|
---|
524 | Q3ComboBox::Q3ComboBox( QWidget *parent, const char *name )
|
---|
525 | : QWidget( parent, name, Qt::WNoAutoErase )
|
---|
526 | {
|
---|
527 | d = new Q3ComboBoxData( this );
|
---|
528 | QStyleOptionComboBox opt;
|
---|
529 | opt.init(this);
|
---|
530 | if ( style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, this) ||
|
---|
531 | style()->styleHint(QStyle::SH_GUIStyle, &opt, this) == Qt::MotifStyle ) {
|
---|
532 | d->setPopupMenu( new Q3ComboBoxPopup( this, "in-combo" ) );
|
---|
533 | d->popup()->setFont( font() );
|
---|
534 | connect( d->popup(), SIGNAL(activated(int)),
|
---|
535 | SLOT(internalActivate(int)) );
|
---|
536 | connect( d->popup(), SIGNAL(highlighted(int)),
|
---|
537 | SLOT(internalHighlight(int)) );
|
---|
538 | } else {
|
---|
539 | setUpListBox();
|
---|
540 | }
|
---|
541 | d->ed = 0;
|
---|
542 | d->current = 0;
|
---|
543 | d->maxCount = INT_MAX;
|
---|
544 | d->sizeLimit = 10;
|
---|
545 | d->p = AtBottom;
|
---|
546 | d->autoresize = false;
|
---|
547 | d->poppedUp = false;
|
---|
548 | d->arrowDown = false;
|
---|
549 | d->arrowPressed = false;
|
---|
550 | d->discardNextMousePress = false;
|
---|
551 | d->shortClick = false;
|
---|
552 | d->useCompletion = false;
|
---|
553 | d->completeAt = 0;
|
---|
554 | d->completeNow = false;
|
---|
555 | d->completionTimer = new QTimer( this );
|
---|
556 |
|
---|
557 | setFocusPolicy( Qt::TabFocus );
|
---|
558 | setBackgroundMode( Qt::PaletteButton );
|
---|
559 | }
|
---|
560 |
|
---|
561 |
|
---|
562 | /*!
|
---|
563 | Constructs a combobox with a maximum size and either Motif 2.0 or
|
---|
564 | Windows look and feel.
|
---|
565 |
|
---|
566 | The input field can be edited if \a rw is true, otherwise the user
|
---|
567 | may only choose one of the items in the combobox.
|
---|
568 |
|
---|
569 | The \a parent and \a name arguments are passed on to the QWidget
|
---|
570 | constructor.
|
---|
571 | */
|
---|
572 |
|
---|
573 |
|
---|
574 | Q3ComboBox::Q3ComboBox( bool rw, QWidget *parent, const char *name )
|
---|
575 | : QWidget( parent, name, Qt::WNoAutoErase )
|
---|
576 | {
|
---|
577 | d = new Q3ComboBoxData( this );
|
---|
578 | setUpListBox();
|
---|
579 |
|
---|
580 | QStyleOptionComboBox opt = d->getStyleOption();
|
---|
581 | if(d->popup() && style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, this))
|
---|
582 | d->popup()->setItemChecked(d->current, false);
|
---|
583 | d->maxCount = INT_MAX;
|
---|
584 | setSizeLimit(10);
|
---|
585 | d->p = AtBottom;
|
---|
586 | d->autoresize = false;
|
---|
587 | d->poppedUp = false;
|
---|
588 | d->arrowDown = false;
|
---|
589 | d->discardNextMousePress = false;
|
---|
590 | d->shortClick = false;
|
---|
591 | d->useCompletion = false;
|
---|
592 | d->completeAt = 0;
|
---|
593 | d->completeNow = false;
|
---|
594 | d->completionTimer = new QTimer( this );
|
---|
595 |
|
---|
596 | setFocusPolicy( Qt::StrongFocus );
|
---|
597 |
|
---|
598 | d->ed = 0;
|
---|
599 | if ( rw )
|
---|
600 | setUpLineEdit();
|
---|
601 | setBackgroundMode( Qt::PaletteButton, Qt::PaletteBase );
|
---|
602 | }
|
---|
603 |
|
---|
604 |
|
---|
605 |
|
---|
606 | /*!
|
---|
607 | Destroys the combobox.
|
---|
608 | */
|
---|
609 |
|
---|
610 | Q3ComboBox::~Q3ComboBox()
|
---|
611 | {
|
---|
612 | delete d;
|
---|
613 | }
|
---|
614 |
|
---|
615 | void Q3ComboBox::setDuplicatesEnabled( bool enable )
|
---|
616 | {
|
---|
617 | d->duplicatesEnabled = enable;
|
---|
618 | }
|
---|
619 |
|
---|
620 | bool Q3ComboBox::duplicatesEnabled() const
|
---|
621 | {
|
---|
622 | return d->duplicatesEnabled;
|
---|
623 | }
|
---|
624 |
|
---|
625 | int Q3ComboBox::count() const
|
---|
626 | {
|
---|
627 | if ( d->usingListBox() )
|
---|
628 | return d->listBox()->count();
|
---|
629 | else if (d->popup())
|
---|
630 | return d->popup()->count();
|
---|
631 | else
|
---|
632 | return 0;
|
---|
633 | }
|
---|
634 |
|
---|
635 |
|
---|
636 | /*!
|
---|
637 | \overload
|
---|
638 |
|
---|
639 | Inserts the \a list of strings at position \a index in the
|
---|
640 | combobox.
|
---|
641 |
|
---|
642 | This is only for compatibility since it does not support Unicode
|
---|
643 | strings. See insertStringList().
|
---|
644 | */
|
---|
645 |
|
---|
646 | void Q3ComboBox::insertStrList( const Q3StrList &list, int index )
|
---|
647 | {
|
---|
648 | insertStrList( &list, index );
|
---|
649 | }
|
---|
650 |
|
---|
651 | /*!
|
---|
652 | \overload
|
---|
653 |
|
---|
654 | Inserts the \a list of strings at position \a index in the
|
---|
655 | combobox.
|
---|
656 |
|
---|
657 | This is only for compatibility since it does not support Unicode
|
---|
658 | strings. See insertStringList().
|
---|
659 | */
|
---|
660 |
|
---|
661 | void Q3ComboBox::insertStrList( const Q3StrList *list, int index )
|
---|
662 | {
|
---|
663 | if ( !list ) {
|
---|
664 | #if defined(QT_CHECK_NULL)
|
---|
665 | Q_ASSERT( list != 0 );
|
---|
666 | #endif
|
---|
667 | return;
|
---|
668 | }
|
---|
669 | Q3StrListIterator it( *list );
|
---|
670 | const char* tmp;
|
---|
671 | if ( index < 0 )
|
---|
672 | index = count();
|
---|
673 | while ( (tmp=it.current()) ) {
|
---|
674 | ++it;
|
---|
675 | if ( d->usingListBox() )
|
---|
676 | d->listBox()->insertItem( QString::fromLatin1(tmp), index );
|
---|
677 | else
|
---|
678 | d->popup()->insertItem( escapedComboString(QString::fromLatin1(tmp)), index, index );
|
---|
679 | if ( index++ == d->current && d->current < count() ) {
|
---|
680 | if ( d->ed ) {
|
---|
681 | d->ed->setText( text( d->current ) );
|
---|
682 | d->updateLinedGeometry();
|
---|
683 | } else
|
---|
684 | update();
|
---|
685 | currentChanged();
|
---|
686 | }
|
---|
687 | }
|
---|
688 | if ( index != count() )
|
---|
689 | reIndex();
|
---|
690 | }
|
---|
691 |
|
---|
692 | /*!
|
---|
693 | Inserts the \a list of strings at position \a index in the
|
---|
694 | combobox.
|
---|
695 | */
|
---|
696 |
|
---|
697 | void Q3ComboBox::insertStringList( const QStringList &list, int index )
|
---|
698 | {
|
---|
699 | QStringList::ConstIterator it = list.begin();
|
---|
700 | if ( index < 0 )
|
---|
701 | index = count();
|
---|
702 | while ( it != list.end() ) {
|
---|
703 | if ( d->usingListBox() )
|
---|
704 | d->listBox()->insertItem( *it, index );
|
---|
705 | else
|
---|
706 | d->popup()->insertItem( escapedComboString(*it), index, index );
|
---|
707 | if ( index++ == d->current && d->current < count() ) {
|
---|
708 | if ( d->ed ) {
|
---|
709 | d->ed->setText( text( d->current ) );
|
---|
710 | d->updateLinedGeometry();
|
---|
711 | } else
|
---|
712 | update();
|
---|
713 | currentChanged();
|
---|
714 | }
|
---|
715 | ++it;
|
---|
716 | }
|
---|
717 | if ( index != count() )
|
---|
718 | reIndex();
|
---|
719 | }
|
---|
720 |
|
---|
721 | /*!
|
---|
722 | Inserts the array of char * \a strings at position \a index in the
|
---|
723 | combobox.
|
---|
724 |
|
---|
725 | The \a numStrings argument is the number of strings. If \a
|
---|
726 | numStrings is -1 (default), the \a strings array must be
|
---|
727 | terminated with 0.
|
---|
728 |
|
---|
729 | Example:
|
---|
730 | \snippet doc/src/snippets/code/src_qt3support_widgets_q3combobox.cpp 2
|
---|
731 |
|
---|
732 | \sa insertStringList()
|
---|
733 | */
|
---|
734 |
|
---|
735 | void Q3ComboBox::insertStrList( const char **strings, int numStrings, int index)
|
---|
736 | {
|
---|
|
---|