1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the Qt 3 compatibility classes of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
31
// needed for qsort() because of a std namespace problem on Borland
32
#include "qplatformdefs.h"
35
#include "q3listbox.h"
37
#include "qapplication.h"
39
#include "qfontmetrics.h"
42
#include "qstringlist.h"
44
#include "qstyleoption.h"
47
#ifndef QT_NO_ACCESSIBILITY
48
#include "qaccessible.h"
53
class Q3ListBoxPrivate
56
Q3ListBoxPrivate(Q3ListBox *lb):
57
head(0), last(0), cache(0), cacheIndex(-1), current(0),
58
highlighted(0), columnPos(1), rowPos(1), rowPosCache(0),
59
columnPosOne(0), rowMode(Q3ListBox::FixedNumber),
60
columnMode(Q3ListBox::FixedNumber), numRows(1), numColumns(1),
61
currentRow(0), currentColumn(0),
62
mousePressRow(-1), mousePressColumn(-1),
63
mouseMoveRow(-1), mouseMoveColumn(-1), mouseInternalPress(false),
64
scrollTimer(0), updateTimer(0), visibleTimer(0),
65
selectionMode(Q3ListBox::Single),
67
listBox(lb), currInputString(QString()),
74
variableHeight(true /* !!! ### false */),
78
int findItemByName(int item, const QString &text);
81
Q3ListBoxItem * head, *last, *cache;
83
Q3ListBoxItem * current, *highlighted, *tmpCurrent;
85
QVector<int> columnPos;
90
Q3ListBox::LayoutMode rowMode;
91
Q3ListBox::LayoutMode columnMode;
101
bool mouseInternalPress;
103
QTimer * scrollTimer;
104
QTimer * updateTimer;
105
QTimer * visibleTimer;
106
QTimer * resizeTimer;
110
Q3ListBox::SelectionMode selectionMode;
116
QString currInputString;
119
Q3ListBoxItem *pressedItem, *selectAnchor;
122
uint pressedSelected :1;
127
uint mustPaintAll :1;
130
uint variableHeight :1;
131
uint variableWidth :1;
136
struct SortableItem {
142
Q3ListBoxPrivate::~Q3ListBoxPrivate()
149
\class Q3ListBoxItem qlistbox.h
150
\brief The Q3ListBoxItem class is the base class of all list box items.
154
This class is an abstract base class used for all list box items.
155
If you need to insert customized items into a Q3ListBox you must
156
inherit this class and reimplement paint(), height() and width().
162
Constructs an empty list box item in the list box \a listbox.
165
Q3ListBoxItem::Q3ListBoxItem(Q3ListBox* listbox)
170
custom_highlight = false;
175
listbox->insertItem(this);
179
Constructs an empty list box item in the list box \a listbox and
180
inserts it after the item \a after or at the beginning if \a after
184
Q3ListBoxItem::Q3ListBoxItem(Q3ListBox* listbox, Q3ListBoxItem *after)
189
custom_highlight = false;
194
listbox->insertItem(this, after);
199
Destroys the list box item.
202
Q3ListBoxItem::~Q3ListBoxItem()
205
lbox->takeItem(this);
210
Defines whether the list box item is responsible for drawing
211
itself in a highlighted state when being selected.
213
If \a b is false (the default), the list box will draw some
214
default highlight indicator before calling paint().
216
\sa isSelected(), paint()
218
void Q3ListBoxItem::setCustomHighlighting(bool b)
220
custom_highlight = b;
224
\fn void Q3ListBoxItem::paint(QPainter *p)
226
Implement this function to draw your item. The painter, \a p, is
227
already open for painting.
229
\sa height(), width()
233
\fn int Q3ListBoxItem::width(const Q3ListBox* lb) const
235
Reimplement this function to return the width of your item. The \a
236
lb parameter is the same as listBox() and is provided for
237
convenience and compatibility.
239
The default implementation returns
240
\l{QApplication::globalStrut()}'s width.
242
\sa paint(), height()
244
int Q3ListBoxItem::width(const Q3ListBox*) const
246
return QApplication::globalStrut().width();
250
\fn int Q3ListBoxItem::height(const Q3ListBox* lb) const
252
Implement this function to return the height of your item. The \a
253
lb parameter is the same as listBox() and is provided for
254
convenience and compatibility.
256
The default implementation returns
257
\l{QApplication::globalStrut()}'s height.
261
int Q3ListBoxItem::height(const Q3ListBox*) const
263
return QApplication::globalStrut().height();
268
Returns the text of the item. This text is also used for sorting.
272
QString Q3ListBoxItem::text() const
278
Returns the pixmap associated with the item, or 0 if there isn't
281
The default implementation returns 0.
283
const QPixmap *Q3ListBoxItem::pixmap() const
288
/*! \fn void Q3ListBoxItem::setSelectable(bool b)
290
If \a b is true (the default) then this item can be selected by
291
the user; otherwise this item cannot be selected by the user.
296
/*! \fn bool Q3ListBoxItem::isSelectable() const
298
Returns true if this item is selectable (the default); otherwise
306
\fn void Q3ListBoxItem::setText(const QString &text)
308
Sets the text of the Q3ListBoxItem to \a text. This \a text is also
309
used for sorting. The text is not shown unless explicitly drawn in
317
\class Q3ListBoxText qlistbox.h
318
\brief The Q3ListBoxText class provides list box items that display text.
322
The text is drawn in the widget's current font. If you need
323
several different fonts, you must implement your own subclass of
326
\sa Q3ListBox, Q3ListBoxItem
331
Constructs a list box item in list box \a listbox showing the text
334
Q3ListBoxText::Q3ListBoxText(Q3ListBox *listbox, const QString &text)
335
:Q3ListBoxItem(listbox)
341
Constructs a list box item showing the text \a text.
344
Q3ListBoxText::Q3ListBoxText(const QString &text)
351
Constructs a list box item in list box \a listbox showing the text
352
\a text. The item is inserted after the item \a after, or at the
353
beginning if \a after is 0.
356
Q3ListBoxText::Q3ListBoxText(Q3ListBox* listbox, const QString &text, Q3ListBoxItem *after)
357
: Q3ListBoxItem(listbox, after)
366
Q3ListBoxText::~Q3ListBoxText()
371
Draws the text using \a painter.
374
void Q3ListBoxText::paint(QPainter *painter)
376
int itemHeight = height(listBox());
377
QFontMetrics fm = painter->fontMetrics();
378
int yPos = ((itemHeight - fm.height()) / 2) + fm.ascent();
379
painter->drawText(3, yPos, text());
383
Returns the height of a line of text in list box \a lb.
388
int Q3ListBoxText::height(const Q3ListBox* lb) const
390
int h = lb ? lb->fontMetrics().lineSpacing() + 2 : 0;
391
return qMax(h, QApplication::globalStrut().height());
395
Returns the width of this line in list box \a lb.
397
\sa paint(), height()
400
int Q3ListBoxText::width(const Q3ListBox* lb) const
402
int w = lb ? lb->fontMetrics().width(text()) + 6 : 0;
403
return qMax(w, QApplication::globalStrut().width());
407
\fn int Q3ListBoxText::rtti() const
413
Make your derived classes return their own values for rtti(), and
414
you can distinguish between listbox items. You should use values
415
greater than 1000 preferably a large random number, to allow for
416
extensions to this class.
419
int Q3ListBoxText::rtti() const
425
\class Q3ListBoxPixmap qlistbox.h
426
\brief The Q3ListBoxPixmap class provides list box items with a
427
pixmap and optional text.
431
Items of this class are drawn with the pixmap on the left with the
432
optional text to the right of the pixmap.
434
\sa Q3ListBox, Q3ListBoxItem
439
Constructs a new list box item in list box \a listbox showing the
443
Q3ListBoxPixmap::Q3ListBoxPixmap(Q3ListBox* listbox, const QPixmap &pixmap)
444
: Q3ListBoxItem(listbox)
450
Constructs a new list box item showing the pixmap \a pixmap.
453
Q3ListBoxPixmap::Q3ListBoxPixmap(const QPixmap &pixmap)
460
Constructs a new list box item in list box \a listbox showing the
461
pixmap \a pixmap. The item gets inserted after the item \a after,
462
or at the beginning if \a after is 0.
465
Q3ListBoxPixmap::Q3ListBoxPixmap(Q3ListBox* listbox, const QPixmap &pixmap, Q3ListBoxItem *after)
466
: Q3ListBoxItem(listbox, after)
476
Q3ListBoxPixmap::~Q3ListBoxPixmap()
482
Constructs a new list box item in list box \a listbox showing the
483
pixmap \a pix and the text \a text.
485
Q3ListBoxPixmap::Q3ListBoxPixmap(Q3ListBox* listbox, const QPixmap &pix, const QString& text)
486
: Q3ListBoxItem(listbox)
493
Constructs a new list box item showing the pixmap \a pix and the
496
Q3ListBoxPixmap::Q3ListBoxPixmap(const QPixmap & pix, const QString& text)
504
Constructs a new list box item in list box \a listbox showing the
505
pixmap \a pix and the string \a text. The item gets inserted after
506
the item \a after, or at the beginning if \a after is 0.
508
Q3ListBoxPixmap::Q3ListBoxPixmap(Q3ListBox* listbox, const QPixmap & pix, const QString& text,
509
Q3ListBoxItem *after)
510
: Q3ListBoxItem(listbox, after)
517
\fn const QPixmap *Q3ListBoxPixmap::pixmap() const
519
Returns the pixmap associated with the item.
524
Draws the pixmap using \a painter.
527
void Q3ListBoxPixmap::paint(QPainter *painter)
529
int itemHeight = height(listBox());
532
const QPixmap *pm = pixmap();
533
if (pm && ! pm->isNull()) {
534
yPos = (itemHeight - pm->height()) / 2;
535
painter->drawPixmap(3, yPos, *pm);
538
if (!text().isEmpty()) {
539
QFontMetrics fm = painter->fontMetrics();
540
yPos = ((itemHeight - fm.height()) / 2) + fm.ascent();
541
painter->drawText(pm->width() + 5, yPos, text());
546
Returns the height of the pixmap in list box \a lb.
551
int Q3ListBoxPixmap::height(const Q3ListBox* lb) const
554
if (text().isEmpty())
557
h = qMax(pm.height(), lb->fontMetrics().lineSpacing() + 2);
558
return qMax(h, QApplication::globalStrut().height());
562
Returns the width of the pixmap plus some margin in list box \a lb.
564
\sa paint(), height()
567
int Q3ListBoxPixmap::width(const Q3ListBox* lb) const
569
if (text().isEmpty())
570
return qMax(pm.width() + 6, QApplication::globalStrut().width());
571
return qMax(pm.width() + lb->fontMetrics().width(text()) + 6,
572
QApplication::globalStrut().width());
576
\fn int Q3ListBoxPixmap::rtti() const
582
Make your derived classes return their own values for rtti(), and
583
you can distinguish between listbox items. You should use values
584
greater than 1000 preferably a large random number, to allow for
585
extensions to this class.
588
int Q3ListBoxPixmap::rtti() const
594
\class Q3ListBox qlistbox.h
595
\brief The Q3ListBox widget provides a list of selectable, read-only items.
599
This is typically a single-column list in which either no item or
600
one item is selected, but it can also be used in many other ways.
602
Q3ListBox will add scroll bars as necessary, but it isn't intended
603
for \e really big lists. If you want more than a few thousand
604
items, it's probably better to use a different widget mainly
605
because the scroll bars won't provide very good navigation, but
606
also because Q3ListBox may become slow with huge lists. (See
607
Q3ListView and Q3Table for possible alternatives.)
609
There are a variety of selection modes described in the
610
Q3ListBox::SelectionMode documentation. The default is \c Single
611
selection mode, but you can change it using setSelectionMode().
612
(setMultiSelection() is still provided for compatibility with Qt
613
1.x. We recommend using setSelectionMode() in all code.)
615
Because Q3ListBox offers multiple selection it must display
616
keyboard focus and selection state separately. Therefore there are
617
functions both to set the selection state of an item, i.e.
618
setSelected(), and to set which item displays keyboard focus, i.e.
621
The list box normally arranges its items in a single column and
622
adds a vertical scroll bar if required. It is possible to have a
623
different fixed number of columns (setColumnMode()), or as many
624
columns as will fit in the list box's assigned screen space
625
(setColumnMode(FitToWidth)), or to have a fixed number of rows
626
(setRowMode()) or as many rows as will fit in the list box's
627
assigned screen space (setRowMode(FitToHeight)). In all these
628
cases Q3ListBox will add scroll bars, as appropriate, in at least
631
If multiple rows are used, each row can be as high as necessary
632
(the normal setting), or you can request that all items will have
633
the same height by calling setVariableHeight(false). The same
634
applies to a column's width, see setVariableWidth().
636
The Q3ListBox's items are Q3ListBoxItem objects. Q3ListBox provides
637
methods to insert new items as strings, as pixmaps, and as
638
Q3ListBoxItem * (insertItem() with various arguments), and to
639
replace an existing item with a new string, pixmap or Q3ListBoxItem
640
(changeItem() with various arguments). You can also remove items
641
singly with removeItem() or clear() the entire list box. Note that
642
if you create a Q3ListBoxItem yourself and insert it, Q3ListBox
643
takes ownership of the item.
645
You can also create a Q3ListBoxItem, such as Q3ListBoxText or
646
Q3ListBoxPixmap, with the list box as first parameter. The item
647
will then append itself. When you delete an item it is
648
automatically removed from the list box.
650
The list of items can be arbitrarily large; Q3ListBox will add
651
scroll bars if necessary. Q3ListBox can display a single-column
652
(the common case) or multiple-columns, and offers both single and
653
multiple selection. Q3ListBox does not support multiple-column
654
items (but Q3ListView and Q3Table do), or tree hierarchies (but
657
The list box items can be accessed both as Q3ListBoxItem objects
658
(recommended) and using integer indexes (the original Q3ListBox
659
implementation used an array of strings internally, and the API
660
still supports this mode of operation). Everything can be done
661
using the new objects, and most things can be done using indexes.
663
Each item in a Q3ListBox contains a Q3ListBoxItem. One of the items
664
can be the current item. The currentChanged() signal and the
665
highlighted() signal are emitted when a new item becomes current,
666
e.g. because the user clicks on it or Q3ListBox::setCurrentItem()
667
is called. The selected() signal is emitted when the user
668
double-clicks on an item or presses Enter on the current item.
670
If the user does not select anything, no signals are emitted and
671
currentItem() returns -1.
673
A list box has \c Qt::WheelFocus as a default focusPolicy(), i.e. it
674
can get keyboard focus by tabbing, clicking and through the use of
677
New items can be inserted using insertItem(), insertStrList() or
680
By default, vertical and horizontal scroll bars are added and
681
removed as necessary. setHScrollBarMode() and setVScrollBarMode()
682
can be used to change this policy.
684
If you need to insert types other than strings and pixmaps, you
685
must define new classes which inherit Q3ListBoxItem.
687
\warning The list box assumes ownership of all list box items and
688
will delete them when it does not need them any more.
690
\inlineimage qlistbox-m.png Screenshot in Motif style
691
\inlineimage qlistbox-w.png Screenshot in Windows style
693
\sa Q3ListView, QComboBox, QButtonGroup
697
\enum Q3ListBox::SelectionMode
699
This enumerated type is used by Q3ListBox to indicate how it reacts
700
to selection by the user.
702
\value Single When the user selects an item, any already-selected
703
item becomes unselected and the user cannot unselect the selected
704
item. This means that the user can never clear the selection, even
705
though the selection may be cleared by the application programmer
706
using Q3ListBox::clearSelection().
708
\value Multi When the user selects an item the selection status
709
of that item is toggled and the other items are left alone.
711
\value Extended When the user selects an item the selection is
712
cleared and the new item selected. However, if the user presses
713
the Ctrl key when clicking on an item, the clicked item gets
714
toggled and all other items are left untouched. And if the user
715
presses the Shift key while clicking on an item, all items between
716
the current item and the clicked item get selected or unselected,
717
depending on the state of the clicked item. Also, multiple items
718
can be selected by dragging the mouse while the left mouse button
721
\value NoSelection Items cannot be selected.
723
In other words, \c Single is a real single-selection list box, \c
724
Multi is a real multi-selection list box, \c Extended is a list
725
box in which users can select multiple items but usually want to
726
select either just one or a range of contiguous items, and \c
727
NoSelection is for a list box where the user can look but not
733
\enum Q3ListBox::LayoutMode
735
This enum type is used to specify how Q3ListBox lays out its rows
738
\value FixedNumber There is a fixed number of rows (or columns).
740
\value FitToWidth There are as many columns as will fit
743
\value FitToHeight There are as many rows as will fit on-screen.
745
\value Variable There are as many rows as are required by the
746
column mode. (Or as many columns as required by the row mode.)
748
Example: When you call setRowMode(FitToHeight), columnMode()
749
automatically becomes \c Variable to accommodate the row mode
754
\fn void Q3ListBox::onItem(Q3ListBoxItem *i)
756
This signal is emitted when the user moves the mouse cursor onto
757
an item, similar to the QWidget::enterEvent() function. \a i is
758
the Q3ListBoxItem that the mouse has moved on.
761
// ### bug here too? enter/leave event may noit considered. move the
762
// mouse out of the window and back in, to the same item - does it
766
\fn void Q3ListBox::onViewport()
768
This signal is emitted when the user moves the mouse cursor from
769
an item to an empty part of the list box.
774
Constructs a new empty list box called \a name and with parent \a
775
parent and widget attributes \a f.
777
This constructor sets the \c WA_StaticContent and the \c
778
Qt::WA_NoBackground attributes to boost performance when drawing
779
Q3ListBoxItems. This may be unsuitable for custom Q3ListBoxItem
780
classes, in which case \c Qt::WA_StaticContents and \c Qt::WA_NoBackground
781
should be cleared on the viewport() after construction.
784
Q3ListBox::Q3ListBox(QWidget *parent, const char *name, Qt::WFlags f)
785
: Q3ScrollView(parent, name, f | Qt::WStaticContents | Qt::WNoAutoErase)
787
d = new Q3ListBoxPrivate(this);
788
d->updateTimer = new QTimer(this, "listbox update timer");
789
d->visibleTimer = new QTimer(this, "listbox visible timer");
790
d->inputTimer = new QTimer(this, "listbox input timer");
791
d->resizeTimer = new QTimer(this, "listbox resize timer");
798
setMouseTracking(true);
799
viewport()->setMouseTracking(true);
801
connect(d->updateTimer, SIGNAL(timeout()),
802
this, SLOT(refreshSlot()));
803
connect(d->visibleTimer, SIGNAL(timeout()),
804
this, SLOT(ensureCurrentVisible()));
805
connect(d->resizeTimer, SIGNAL(timeout()),
806
this, SLOT(adjustItems()));
807
viewport()->setBackgroundRole(QPalette::Base);
808
viewport()->setFocusProxy(this);
809
viewport()->setFocusPolicy(Qt::WheelFocus);
813
Q3ListBox * Q3ListBox::changedListBox = 0;
816
Destroys the list box. Deletes all list box items.
819
Q3ListBox::~Q3ListBox()
821
if (changedListBox == this)
829
\fn void Q3ListBox::pressed(Q3ListBoxItem *item)
831
This signal is emitted when the user presses any mouse button. If
832
\a item is not 0, the cursor is on \a item. If \a item is 0, the
833
mouse cursor isn't on any item.
835
Note that you must not delete any Q3ListBoxItem objects in slots
836
connected to this signal.
840
\fn void Q3ListBox::pressed(Q3ListBoxItem *item, const QPoint &pnt)
843
This signal is emitted when the user presses any mouse button. If
844
\a item is not 0, the cursor is on \a item. If \a item is 0, the
845
mouse cursor isn't on any item.
847
\a pnt is the position of the mouse cursor in the global
848
coordinate system (QMouseEvent::globalPos()).
850
Note that you must not delete any Q3ListBoxItem objects in slots
851
connected to this signal.
853
\sa mouseButtonPressed() rightButtonPressed() clicked()
857
\fn void Q3ListBox::clicked(Q3ListBoxItem *item)
859
This signal is emitted when the user clicks any mouse button. If
860
\a item is not 0, the cursor is on \a item. If \a item is 0, the
861
mouse cursor isn't on any item.
863
Note that you must not delete any Q3ListBoxItem objects in slots
864
connected to this signal.
868
\fn void Q3ListBox::clicked(Q3ListBoxItem *item, const QPoint &pnt)
871
This signal is emitted when the user clicks any mouse button. If
872
\a item is not 0, the cursor is on \a item. If \a item is 0, the
873
mouse cursor isn't on any item.
875
\a pnt is the position of the mouse cursor in the global
876
coordinate system (QMouseEvent::globalPos()). (If the click's
877
press and release differs by a pixel or two, \a pnt is the
878
position at release time.)
880
Note that you must not delete any Q3ListBoxItem objects in slots
881
connected to this signal.
885
\fn void Q3ListBox::mouseButtonClicked (int button, Q3ListBoxItem * item, const QPoint & pos)
887
This signal is emitted when the user clicks mouse button \a
888
button. If \a item is not 0, the cursor is on \a item. If \a item
889
is 0, the mouse cursor isn't on any item.
891
\a pos is the position of the mouse cursor in the global
892
coordinate system (QMouseEvent::globalPos()). (If the click's
893
press and release differs by a pixel or two, \a pos is the
894
position at release time.)
896
Note that you must not delete any Q3ListBoxItem objects in slots
897
connected to this signal.
901
\fn void Q3ListBox::mouseButtonPressed (int button, Q3ListBoxItem * item, const QPoint & pos)
903
This signal is emitted when the user presses mouse button \a
904
button. If \a item is not 0, the cursor is on \a item. If \a item
905
is 0, the mouse cursor isn't on any item.
907
\a pos is the position of the mouse cursor in the global
908
coordinate system (QMouseEvent::globalPos()).
910
Note that you must not delete any Q3ListBoxItem objects in slots
911
connected to this signal.
915
\fn void Q3ListBox::doubleClicked(Q3ListBoxItem *item)
917
This signal is emitted whenever an item is double-clicked. It's
918
emitted on the second button press, not the second button release.
919
If \a item is not 0, the cursor is on \a item. If \a item is 0,
920
the mouse cursor isn't on any item.
925
\fn void Q3ListBox::returnPressed(Q3ListBoxItem *item)
927
This signal is emitted when Enter or Return is pressed. The
928
\a item passed in the argument is currentItem().
932
\fn void Q3ListBox::rightButtonClicked(Q3ListBoxItem *item, const QPoint& point)
934
This signal is emitted when the right button is clicked. The \a
935
item is the item that the button was clicked on (which could be
936
0 if no item was clicked on), and the \a point is where the
937
click took place in global coordinates.
942
\fn void Q3ListBox::rightButtonPressed (Q3ListBoxItem *item, const QPoint &point)
944
This signal is emitted when the right button is pressed. The \a
945
item is the item that the button was pressed over (which could be
946
0 if no item was pressed over), and the \a point is where the
947
press took place in global coordinates.
951
\fn void Q3ListBox::contextMenuRequested(Q3ListBoxItem *item, const QPoint & pos)
953
This signal is emitted when the user invokes a context menu with
954
the right mouse button or with special system keys, with \a item
955
being the item under the mouse cursor or the current item,
958
\a pos is the position for the context menu in the global
963
\fn void Q3ListBox::selectionChanged()
965
This signal is emitted when the selection set of a list box
966
changes. This signal is emitted in each selection mode. If the
967
user selects five items by drag-selecting, Q3ListBox tries to emit
968
just one selectionChanged() signal so the signal can be connected
969
to computationally expensive slots.
971
\sa selected() currentItem()
975
\fn void Q3ListBox::selectionChanged(Q3ListBoxItem *item)
978
This signal is emitted when the selection in a \c Single selection
979
list box changes. \a item is the newly selected list box item.
981
\sa selected() currentItem()
985
\fn void Q3ListBox::currentChanged(Q3ListBoxItem *item)
987
This signal is emitted when the user makes a new item the current
988
item. \a item is the new current list box item.
990
\sa setCurrentItem() currentItem()
994
\fn void Q3ListBox::highlighted(int index)
996
This signal is emitted when the user makes a new item the current
997
item. \a index is the index of the new current item.
999
\sa currentChanged() selected() currentItem() selectionChanged()
1003
\fn void Q3ListBox::highlighted(Q3ListBoxItem *item)
1007
This signal is emitted when the user makes a new \a item the current
1010
\sa currentChanged() selected() currentItem() selectionChanged()
1014
\fn void Q3ListBox::highlighted(const QString & text)
1018
This signal is emitted when the user makes a new item the current
1019
item and the item is (or has) as string. The argument is the new
1020
current item's \a text.
1022
\sa currentChanged() selected() currentItem() selectionChanged()
1026
\fn void Q3ListBox::selected(int index)
1028
This signal is emitted when the user double-clicks on an item or
1029
presses Enter on the current item. \a index is the index of the
1032
\sa currentChanged() highlighted() selectionChanged()
1036
\fn void Q3ListBox::selected(Q3ListBoxItem *item)
1040
This signal is emitted when the user double-clicks on an \a item or
1041
presses Enter on the current \a item.
1043
\sa currentChanged() highlighted() selectionChanged()
1047
\fn void Q3ListBox::selected(const QString &text)
1051
This signal is emitted when the user double-clicks on an item or
1052
presses Enter on the current item, and the item is (or has) a
1053
string. The argument is the \a text of the selected item.
1055
\sa currentChanged() highlighted() selectionChanged()
1059
\property Q3ListBox::count
1060
\brief the number of items in the list box
1063
uint Q3ListBox::count() const
1068
// ### fix before Qt 4.0
1071
Inserts the string list \a list into the list at position \a
1074
If \a index is negative, \a list is inserted at the end of the
1075
list. If \a index is too large, the operation is ignored.
1077
\warning This function uses \c{const char *} rather than QString,
1078
so we recommend against using it. It is provided so that legacy
1079
code will continue to work, and so that programs that certainly
1080
will not need to handle code outside a single 8-bit locale can use
1081
it. See insertStringList() which uses real QStrings.
1083
\warning This function is never significantly faster than a loop
1084
around insertItem().
1086
\sa insertItem(), insertStringList()
1089
void Q3ListBox::insertStrList(const QStrList *list, int index)
1092
Q_ASSERT(list != 0);
1095
insertStrList(*list, index);
1101
Inserts the string list \a list into the list at position \a
1104
If \a index is negative, \a list is inserted at the end of the
1105
list. If \a index is too large, the operation is ignored.
1107
\warning This function is never significantly faster than a loop
1108
around insertItem().
1110
\sa insertItem(), insertStrList()
1113
void Q3ListBox::insertStringList(const QStringList & list, int index)
1117
for (QStringList::ConstIterator it = list.begin(); it != list.end(); ++it)
1118
insertItem(new Q3ListBoxText(*it), index++);
1122
// ### fix before Qt 4.0
1127
Inserts the string list \a list into the list at position \a
1130
If \a index is negative, \a list is inserted at the end of the
1131
list. If \a index is too large, the operation is ignored.
1133
\warning This function uses \c{const char *} rather than QString,
1134
so we recommend against using it. It is provided so that legacy
1135
code will continue to work, and so that programs that certainly
1136
will not need to handle code outside a single 8-bit locale can use
1137
it. See insertStringList() which uses real QStrings.
1139
\warning This function is never significantly faster than a loop
1140
around insertItem().
1142
\sa insertItem(), insertStringList()
1144
void Q3ListBox::insertStrList(const QStrList & list, int index)
1146
QStrListIterator it(list);
1150
while ((txt=it.current())) {
1152
insertItem(new Q3ListBoxText(QString::fromLatin1(txt)),
1155
if (hasFocus() && !d->current)
1156
setCurrentItem(d->head);
1162
Inserts the \a numStrings strings of the array \a strings into the
1163
list at position \a index.
1165
If \a index is negative, insertStrList() inserts \a strings at the
1166
end of the list. If \a index is too large, the operation is
1169
\warning This function uses \c{const char *} rather than QString,
1170
so we recommend against using it. It is provided so that legacy
1171
code will continue to work, and so that programs that certainly
1172
will not need to handle code outside a single 8-bit locale can use
1173
it. See insertStringList() which uses real QStrings.
1175
\warning This function is never significantly faster than a loop
1176
around insertItem().
1178
\sa insertItem(), insertStringList()
1181
void Q3ListBox::insertStrList(const char **strings, int numStrings, int index)
1184
Q_ASSERT(strings != 0);
1190
while ((numStrings<0 && strings[i]!=0) || i<numStrings) {
1191
insertItem(new Q3ListBoxText(QString::fromLatin1(strings[i])),
1195
if (hasFocus() && !d->current)
1196
setCurrentItem(d->head);
1200
Inserts the item \a lbi into the list at position \a index.
1202
If \a index is negative or larger than the number of items in the
1203
list box, \a lbi is inserted at the end of the list.
1208
void Q3ListBox::insertItem(const Q3ListBoxItem *lbi, int index)
1216
if (index >= d->count) {
1217
insertItem(lbi, d->last);
1221
Q3ListBoxItem * item = (Q3ListBoxItem *)lbi;
1226
if (!d->head || index == 0) {
1234
Q3ListBoxItem * i = d->head;
1235
while (i->n && index > 1) {
1251
if (hasFocus() && !d->current) {
1252
d->current = d->head;
1253
updateItem(d->current);
1254
emit highlighted(d->current);
1255
emit highlighted(d->current->text());
1256
emit highlighted(index);
1259
triggerUpdate(true);
1265
Inserts the item \a lbi into the list after the item \a after, or
1266
at the beginning if \a after is 0.
1271
void Q3ListBox::insertItem(const Q3ListBoxItem *lbi, const Q3ListBoxItem *after)
1276
Q3ListBoxItem * item = (Q3ListBoxItem*)lbi;
1281
if (!d->head || !after) {
1289
Q3ListBoxItem * i = (Q3ListBoxItem*) after;
1300
if (after == d->last)
1301
d->last = (Q3ListBoxItem*) lbi;
1303
if (hasFocus() && !d->current) {
1304
d->current = d->head;
1305
updateItem(d->current);
1306
emit highlighted(d->current);
1307
emit highlighted(d->current->text());
1308
emit highlighted(index(d->current));
1311
triggerUpdate(true);
1317
Inserts a new list box text item with the text \a text into the
1318
list at position \a index.
1320
If \a index is negative, \a text is inserted at the end of the
1326
void Q3ListBox::insertItem(const QString &text, int index)
1328
insertItem(new Q3ListBoxText(text), index);
1334
Inserts a new list box pixmap item with the pixmap \a pixmap into
1335
the list at position \a index.
1337
If \a index is negative, \a pixmap is inserted at the end of the
1343
void Q3ListBox::insertItem(const QPixmap &pixmap, int index)
1345
insertItem(new Q3ListBoxPixmap(pixmap), index);
1351
Inserts a new list box pixmap item with the pixmap \a pixmap and
1352
the text \a text into the list at position \a index.
1354
If \a index is negative, \a pixmap is inserted at the end of the
1360
void Q3ListBox::insertItem(const QPixmap &pixmap, const QString &text, int index)
1362
insertItem(new Q3ListBoxPixmap(pixmap, text), index);
1366
Removes and deletes the item at position \a index. If \a index is
1367
equal to currentItem(), a new item becomes current and the
1368
currentChanged() and highlighted() signals are emitted.
1370
\sa insertItem(), clear()
1373
void Q3ListBox::removeItem(int index)
1375
bool wasVisible = itemVisible(currentItem());
1377
triggerUpdate(true);
1379
ensureCurrentVisible();
1384
Deletes all the items in the list.
1389
void Q3ListBox::clear()
1391
setContentsPos(0, 0);
1392
bool blocked = signalsBlocked();
1396
Q3ListBoxItem * i = d->head;
1399
Q3ListBoxItem * n = i->n;
1408
d->currentColumn = 0;
1409
d->mousePressRow = -1;
1410
d->mousePressColumn = -1;
1411
d->mouseMoveRow = -1;
1412
d->mouseMoveColumn = -1;
1414
blockSignals(blocked);
1415
triggerUpdate(true);
1417
d->clearing = false;
1422
Returns the text at position \a index, or an empty string if there
1423
is no text at that position.
1428
QString Q3ListBox::text(int index) const
1430
Q3ListBoxItem * i = item(index);
1438
Returns a pointer to the pixmap at position \a index, or 0 if
1439
there is no pixmap there.
1444
const QPixmap *Q3ListBox::pixmap(int index) const
1446
Q3ListBoxItem * i = item(index);
1455
Replaces the item at position \a index with a new list box text
1456
item with text \a text.
1458
The operation is ignored if \a index is out of range.
1460
\sa insertItem(), removeItem()
1463
void Q3ListBox::changeItem(const QString &text, int index)
1465
if(index >= 0 && index < (int)count())
1466
changeItem(new Q3ListBoxText(text), index);
1472
Replaces the item at position \a index with a new list box pixmap
1473
item with pixmap \a pixmap.
1475
The operation is ignored if \a index is out of range.
1477
\sa insertItem(), removeItem()
1480
void Q3ListBox::changeItem(const QPixmap &pixmap, int index)
1482
if(index >= 0 && index < (int)count())
1483
changeItem(new Q3ListBoxPixmap(pixmap), index);
1489
Replaces the item at position \a index with a new list box pixmap
1490
item with pixmap \a pixmap and text \a text.
1492
The operation is ignored if \a index is out of range.
1494
\sa insertItem(), removeItem()
1497
void Q3ListBox::changeItem(const QPixmap &pixmap, const QString &text, int index)
1499
if(index >= 0 && index < (int)count())
1500
changeItem(new Q3ListBoxPixmap(pixmap, text), index);
1506
Replaces the item at position \a index with \a lbi. If \a index is
1507
negative or too large, changeItem() does nothing.
1509
The item that has been changed will become selected.
1511
\sa insertItem(), removeItem()
1514
void Q3ListBox::changeItem(const Q3ListBoxItem *lbi, int index)
1516
if (!lbi || index < 0 || index >= (int)count())
1520
insertItem(lbi, index);
1521
setCurrentItem(index);
1526
\property Q3ListBox::numItemsVisible
1527
\brief the number of visible items.
1529
Both partially and entirely visible items are counted.
1532
int Q3ListBox::numItemsVisible() const
1538
int x = contentsX();
1540
while (i < (int)d->columnPos.size()-1 &&
1541
d->columnPos[i] < x)
1543
if (i < (int)d->columnPos.size()-1 &&
1544
d->columnPos[i] > x)
1546
x += visibleWidth();
1547
while (i < (int)d->columnPos.size()-1 &&
1548
d->columnPos[i] < x) {
1553
int y = contentsY();
1555
while (i < (int)d->rowPos.size()-1 &&
1558
if (i < (int)d->rowPos.size()-1 &&
1561
y += visibleHeight();
1562
while (i < (int)d->rowPos.size()-1 &&
1568
return rows*columns;
1571
int Q3ListBox::currentItem() const
1573
if (!d->current || !d->head)
1576
return index(d->current);
1581
\property Q3ListBox::currentText
1582
\brief the text of the current item.
1584
This is equivalent to text(currentItem()).
1589
\property Q3ListBox::currentItem
1590
\brief the current highlighted item
1592
When setting this property, the highlighting is moved to the item
1593
and the list box scrolled as necessary.
1595
If no item is current, currentItem() returns -1.
1598
void Q3ListBox::setCurrentItem(int index)
1600
setCurrentItem(item(index));
1606
QVariant Q3ListBox::inputMethodQuery(Qt::InputMethodQuery query) const
1608
if (query == Qt::ImMicroFocus)
1609
return d->current ? itemRect(d->current) : QRect();
1610
return QWidget::inputMethodQuery(query);
1616
Sets the current item to the Q3ListBoxItem \a i.
1618
void Q3ListBox::setCurrentItem(Q3ListBoxItem * i)
1620
if (!i || d->current == i)
1623
Q3ListBoxItem * o = d->current;
1627
if (i && selectionMode() == Single) {
1628
bool changed = false;
1633
if (i && !i->s && d->selectionMode != NoSelection && i->isSelectable()) {
1636
emit selectionChanged(i);
1637
#ifndef QT_NO_ACCESSIBILITY
1638
QAccessible::updateAccessibility(viewport(), ind+1, QAccessible::StateChanged);
1642
emit selectionChanged();
1643
#ifndef QT_NO_ACCESSIBILITY
1644
QAccessible::updateAccessibility(viewport(), 0, QAccessible::Selection);
1649
d->currentColumn = ind / numRows();
1650
d->currentRow = ind % numRows();
1655
// scroll after the items are redrawn
1656
d->visibleTimer->start(1, true);
1661
emit highlighted(i);
1663
emit highlighted(tmp);
1664
emit highlighted(ind);
1665
emit currentChanged(i);
1667
#ifndef QT_NO_ACCESSIBILITY
1668
QAccessible::updateAccessibility(viewport(), ind+1, QAccessible::Focus);
1674
Returns a pointer to the item at position \a index, or 0 if \a
1675
index is out of bounds.
1680
Q3ListBoxItem *Q3ListBox::item(int index) const
1682
if (index < 0 || index > d->count -1)
1685
Q3ListBoxItem * i = d->head;
1687
if (d->cache && index > 0) {
1689
int idx = d->cacheIndex;
1690
while (i && idx < index) {
1694
while (i && idx > index) {
1700
while (i && idx > 0) {
1708
d->cacheIndex = index;
1716
Returns the index of \a lbi, or -1 if the item is not in this list
1722
int Q3ListBox::index(const Q3ListBoxItem * lbi) const
1726
Q3ListBoxItem * i_n = d->head;
1730
c_n = d->cacheIndex;
1732
Q3ListBoxItem* i_p = i_n;
1734
while ((i_n != 0 || i_p != 0) && i_n != lbi && i_p != lbi) {
1754
Returns true if the item at position \a index is at least partly
1755
visible; otherwise returns false.
1758
bool Q3ListBox::itemVisible(int index)
1760
Q3ListBoxItem * i = item(index);
1761
return i ? itemVisible(i) : false;
1768
Returns true if \a item is at least partly visible; otherwise
1772
bool Q3ListBox::itemVisible(const Q3ListBoxItem * item)
1777
int i = index(item);
1778
int col = i / numRows();
1779
int row = i % numRows();
1780
return (d->columnPos[col] < contentsX()+visibleWidth() &&
1781
d->rowPos[row] < contentsY()+visibleHeight() &&
1782
d->columnPos[col+1] > contentsX() &&
1783
d->rowPos[row+1] > contentsY());
1789
void Q3ListBox::mousePressEvent(QMouseEvent *e)
1791
mousePressEventEx(e);
1794
void Q3ListBox::mousePressEventEx(QMouseEvent *e)
1796
d->mouseInternalPress = true;
1797
Q3ListBoxItem * i = itemAt(e->pos());
1799
if (!i && !d->current && d->head) {
1800
d->current = d->head;
1801
updateItem(d->head);
1804
if (!i && (d->selectionMode != Single || e->button() == Qt::RightButton)
1805
&& !(e->state() & Qt::ControlButton))
1808
d->select = d->selectionMode == Multi ? (i ? !i->isSelected() : false) : true;
1809
d->pressedSelected = i && i->s;
1812
d->selectAnchor = i;
1814
switch(selectionMode()) {
1817
if (!i->s || i != d->current) {
1818
if (i->isSelectable())
1819
setSelected(i, true);
1826
bool shouldBlock = false;
1827
if (!(e->state() & Qt::ShiftButton) &&
1828
!(e->state() & Qt::ControlButton)) {
1829
if (!i->isSelected()) {
1830
bool b = signalsBlocked();
1835
setSelected(i, true);
1836
d->dragging = true; // always assume dragging
1838
} else if (e->state() & Qt::ShiftButton) {
1839
d->pressedSelected = false;
1840
Q3ListBoxItem *oldCurrent = item(currentItem());
1841
bool down = index(oldCurrent) < index(i);
1843
Q3ListBoxItem *lit = down ? oldCurrent : i;
1844
bool select = d->select;
1845
bool blocked = signalsBlocked();
1847
for (;; lit = lit->n) {
1849
triggerUpdate(false);
1852
if (down && lit == i) {
1853
setSelected(i, select);
1854
triggerUpdate(false);
1857
if (!down && lit == oldCurrent) {
1858
setSelected(oldCurrent, select);
1859
triggerUpdate(false);
1862
setSelected(lit, select);
1864
blockSignals(blocked);
1865
emit selectionChanged();
1866
} else if (e->state() & Qt::ControlButton) {
1867
setSelected(i, !i->isSelected());
1869
d->pressedSelected = false;
1871
bool blocked = signalsBlocked();
1872
blockSignals(shouldBlock);
1874
blockSignals(blocked);
1879
setSelected(i, !i->s);
1880
bool b = signalsBlocked();
1891
bool unselect = true;
1892
if (e->button() == Qt::LeftButton) {
1893
if (d->selectionMode == Multi ||
1894
d->selectionMode == Extended) {
1895
d->tmpCurrent = d->current;
1897
updateItem(d->tmpCurrent);
1901
d->rubber = new QRect(e->x(), e->y(), 0, 0);
1903
if (d->selectionMode == Extended && !(e->state() & Qt::ControlButton))
1907
if (unselect && (e->button() == Qt::RightButton ||
1908
(selectionMode() == Multi || selectionMode() == Extended)))
1913
// for sanity, in case people are event-filtering or whatnot
1914
delete d->scrollTimer;
1917
d->mousePressColumn = d->currentColumn;
1918
d->mousePressRow = d->currentRow;
1920
d->mousePressColumn = -1;
1921
d->mousePressRow = -1;
1923
d->ignoreMoves = false;
1928
emit pressed(i, e->globalPos());
1929
emit mouseButtonPressed(e->button(), i, e->globalPos());
1930
if (e->button() == Qt::RightButton)
1931
emit rightButtonPressed(i, e->globalPos());
1937
void Q3ListBox::mouseReleaseEvent(QMouseEvent *e)
1939
if (d->selectionMode == Extended &&
1941
d->dragging = false;
1942
if (d->current != d->pressedItem) {
1943
updateSelection(); // when we drag, we get an update after we release
1951
d->current = d->tmpCurrent;
1952
updateItem(d->current);
1956
delete d->scrollTimer;
1958
d->ignoreMoves = false;
1960
if (d->selectionMode == Extended &&
1961
d->current == d->pressedItem &&
1962
d->pressedSelected && d->current) {
1963
bool block = signalsBlocked();
1966
blockSignals(block);
1967
d->current->s = true;
1968
emit selectionChanged();
1971
Q3ListBoxItem * i = itemAt(e->pos());
1972
bool emitClicked = d->mousePressColumn != -1 && d->mousePressRow != -1 || !d->pressedItem;
1973
emitClicked = emitClicked && d->pressedItem == i;
1975
d->mousePressRow = -1;
1976
d->mousePressColumn = -1;
1977
d->mouseInternalPress = false;
1980
emit clicked(i, e->globalPos());
1981
emit mouseButtonClicked(e->button(), i, e->globalPos());
1982
if (e->button() == Qt::RightButton)
1983
emit rightButtonClicked(i, e->globalPos());
1990
void Q3ListBox::mouseDoubleClickEvent(QMouseEvent *e)
1993
Q3ListBoxItem *i = itemAt(e->pos());
1994
if (!i || selectionMode() == NoSelection)
1997
d->ignoreMoves = true;
1999
if (d->current && ok) {
2000
Q3ListBoxItem * i = d->current;
2001
QString tmp = d->current->text();
2002
emit selected(currentItem());
2006
emit doubleClicked(i);
2013
void Q3ListBox::mouseMoveEvent(QMouseEvent *e)
2015
Q3ListBoxItem * i = itemAt(e->pos());
2016
if (i != d->highlighted) {
2026
QRect r = d->rubber->normalized();
2028
d->rubber->setCoords(d->rubber->x(), d->rubber->y(), e->x(), e->y());
2029
doRubberSelection(r, d->rubber->normalized());
2034
if (((e->state() & (Qt::RightButton | Qt::LeftButton | Qt::MidButton)) == 0) ||
2038
// hack to keep the combo (and what else?) working: if we get a
2039
// move outside the listbox without having seen a press, discard
2041
if (!QRect(0, 0, visibleWidth(), visibleHeight()).contains(e->pos()) &&
2042
(d->mousePressColumn < 0 && d->mousePressRow < 0 ||
2043
(e->state() == Qt::NoButton && !d->pressedItem)))
2046
// figure out in what direction to drag-select and perhaps scroll
2049
if (x >= visibleWidth()) {
2050
x = visibleWidth()-1;
2056
d->mouseMoveColumn = columnAt(x + contentsX());
2058
// sanitize mousePressColumn, if we got here without a mouse press event
2059
if (d->mousePressColumn < 0 && d->mouseMoveColumn >= 0)
2060
d->mousePressColumn = d->mouseMoveColumn;
2061
if (d->mousePressColumn < 0 && d->currentColumn >= 0)
2062
d->mousePressColumn = d->currentColumn;
2064
// if it's beyond the last column, use the last one
2065
if (d->mouseMoveColumn < 0)
2066
d->mouseMoveColumn = dx >= 0 ? numColumns()-1 : 0;
2071
if (y >= visibleHeight()) {
2072
y = visibleHeight()-1;
2078
d->mouseMoveRow = rowAt(y + contentsY());
2080
if (d->mousePressRow < 0 && d->mouseMoveRow >= 0)
2081
d->mousePressRow = d->mouseMoveRow;
2082
if (d->mousePressRow < 0 && d->currentRow >= 0)
2083
d->mousePressRow = d->currentRow;
2085
if (d->mousePressRow < 0)
2086
d->mousePressRow = rowAt(x + contentsX());
2088
d->scrollPos = QPoint(dx, dy);
2090
if ((dx || dy) && !d->scrollTimer && e->state() == Qt::LeftButton && e->button() != Qt::LeftButton) {
2091
// start autoscrolling if necessary
2092
d->scrollTimer = new QTimer(this);
2093
connect(d->scrollTimer, SIGNAL(timeout()),
2094
this, SLOT(doAutoScroll()));
2095
d->scrollTimer->start(100, false);
2097
} else if (!d->scrollTimer) {
2098
// or just select the required bits
2105
void Q3ListBox::updateSelection()
2107
if (d->mouseMoveColumn >= 0 && d->mouseMoveRow >= 0 &&
2108
d->mousePressColumn >= 0 && d->mousePressRow >= 0) {
2109
Q3ListBoxItem * i = item(d->mouseMoveColumn * numRows() +
2111
#ifndef QT_NO_ACCESSIBILITY
2114
if (selectionMode() == Single || selectionMode() == NoSelection) {
2115
if (i && (d->mouseInternalPress || (windowType() == Qt::Popup)))
2118
if (d->selectionMode == Extended && (
2119
(d->current == d->pressedItem && d->pressedSelected) ||
2120
(d->dirtyDrag && !d->dragging))) {
2121
if (d->dirtyDrag && !d->dragging) // emit after dragging stops
2122
d->dirtyDrag = false;
2124
clearSelection(); // dont reset drag-selected items
2126
if (i && i->isSelectable()) {
2127
bool block = signalsBlocked();
2130
blockSignals(block);
2131
emit selectionChanged();
2132
#ifndef QT_NO_ACCESSIBILITY
2133
QAccessible::updateAccessibility(viewport(), ind+1, QAccessible::StateChanged);
2134
QAccessible::updateAccessibility(viewport(), 0, QAccessible::Selection);
2135
QAccessible::updateAccessibility(viewport(), ind+1, QAccessible::SelectionAdd);
2138
triggerUpdate(false);
2140
int c = qMin(d->mouseMoveColumn, d->mousePressColumn);
2141
int r = qMin(d->mouseMoveRow, d->mousePressRow);
2142
int c2 = qMax(d->mouseMoveColumn, d->mousePressColumn);
2143
int r2 = qMax(d->mouseMoveRow, d->mousePressRow);
2144
bool changed = false;
2146
Q3ListBoxItem * i = item(c*numRows()+r);
2148
while(i && rtmp <= r2) {
2149
if ((bool)i->s != (bool)d->select && i->isSelectable()) {
2151
#ifndef QT_NO_ACCESSIBILITY
2152
QAccessible::updateAccessibility(viewport(), ind+1, QAccessible::StateChanged);
2153
QAccessible::updateAccessibility(viewport(), ind+1, d->select ? QAccessible::SelectionAdd : QAccessible::SelectionRemove);
2156
d->dirtyDrag = changed = true;
2164
if (!d->dragging) // emit after dragging stops instead
2165
emit selectionChanged();
2166
#ifndef QT_NO_ACCESSIBILITY
2167
QAccessible::updateAccessibility(viewport(), 0, QAccessible::Selection);
2169
triggerUpdate(false);
2178
void Q3ListBox::repaintSelection()
2180
if (d->numColumns == 1) {
2181
for (uint i = topItem(); itemVisible(i) && i < count(); ++i) {
2182
Q3ListBoxItem *it = item(i);
2185
if (it->isSelected())
2189
for (uint i = 0; i < count(); ++i) {
2190
Q3ListBoxItem *it = item(i);
2193
if (it->isSelected())
2202
void Q3ListBox::contentsContextMenuEvent(QContextMenuEvent *e)
2204
if (!receivers(SIGNAL(contextMenuRequested(Q3ListBoxItem*,QPoint)))) {
2208
if (e->reason() == QContextMenuEvent::Keyboard) {
2209
Q3ListBoxItem *i = item(currentItem());
2211
QRect r = itemRect(i);
2212
emit contextMenuRequested(i, mapToGlobal(r.topLeft() + QPoint(width() / 2, r.height() / 2)));
2215
Q3ListBoxItem * i = itemAt(contentsToViewport(e->pos()));
2216
emit contextMenuRequested(i, e->globalPos());
2222
void Q3ListBox::keyPressEvent(QKeyEvent *e)
2224
if ((e->key() == Qt::Key_Tab || e->key() == Qt::Key_Backtab)
2225
&& e->state() & Qt::ControlButton)
2233
Q3ListBoxItem *old = d->current;
2235
setCurrentItem(d->head);
2236
if (d->selectionMode == Single)
2237
setSelected(d->head, true);
2242
bool selectCurrent = false;
2246
d->currInputString.clear();
2247
if (currentItem() > 0) {
2248
setCurrentItem(currentItem() - 1);
2249
handleItemChange(old, e->state() & Qt::ShiftButton, e->state() & Qt::ControlButton);
2251
if (!(e->state() & Qt::ShiftButton) || !d->selectAnchor)
2252
d->selectAnchor = d->current;
2257
d->currInputString.clear();
2258
if (currentItem() < (int)count() - 1) {
2259
setCurrentItem(currentItem() + 1);
2260
handleItemChange(old, e->state() & Qt::ShiftButton, e->state() & Qt::ControlButton);
2262
if (!(e->state() & Qt::ShiftButton) || !d->selectAnchor)
2263
d->selectAnchor = d->current;
2268
d->currInputString.clear();
2269
if (currentColumn() > 0) {
2270
setCurrentItem(currentItem() - numRows());
2271
handleItemChange(old, e->state() & Qt::ShiftButton, e->state() & Qt::ControlButton);
2272
} else if (numColumns() > 1 && currentItem() > 0) {
2273
int row = currentRow();
2274
setCurrentItem(currentRow() - 1 + (numColumns() - 1) * numRows());
2276
if (currentItem() == -1)
2277
setCurrentItem(row - 1 + (numColumns() - 2) * numRows());
2279
handleItemChange(old, e->state() & Qt::ShiftButton, e->state() & Qt::ControlButton);
2281
QApplication::sendEvent(horizontalScrollBar(), e);
2283
if (!(e->state() & Qt::ShiftButton) || !d->selectAnchor)
2284
d->selectAnchor = d->current;
2289
d->currInputString.clear();
2290
if (currentColumn() < numColumns()-1) {
2291
int row = currentRow();
2292
int i = currentItem();
2293
Q3ListBoxItem *it = item(i + numRows());
2295
it = item(count()-1);
2298
if (currentItem() == -1) {
2299
if (row < numRows() - 1)
2300
setCurrentItem(row + 1);
2305
handleItemChange(old, e->state() & Qt::ShiftButton, e->state() & Qt::ControlButton);
2306
} else if (numColumns() > 1 && currentRow() < numRows()) {
2307
if (currentRow() + 1 < numRows()) {
2308
setCurrentItem(currentRow() + 1);
2309
handleItemChange(old, e->state() & Qt::ShiftButton, e->state() & Qt::ControlButton);
2312
QApplication::sendEvent(horizontalScrollBar(), e);
2314
if (!(e->state() & Qt::ShiftButton) || !d->selectAnchor)
2315
d->selectAnchor = d->current;
2320
d->currInputString.clear();
2322
if (numColumns() == 1) {
2323
i = currentItem() + numItemsVisible();
2324
i = i > (int)count() - 1 ? (int)count() - 1 : i;
2328
// I'm not sure about this behavior...
2329
if (currentRow() == numRows() - 1)
2330
i = currentItem() + numRows();
2332
i = currentItem() + numRows() - currentRow() - 1;
2333
i = i > (int)count() - 1 ? (int)count() - 1 : i;
2336
handleItemChange(old, e->state() & Qt::ShiftButton, e->state() & Qt::ControlButton);
2337
if (!(e->state() & Qt::ShiftButton) || !d->selectAnchor)
2338
d->selectAnchor = d->current;
2343
selectCurrent = true;
2344
d->currInputString.clear();
2346
if (numColumns() == 1) {
2347
i = currentItem() - numItemsVisible();
2352
// I'm not sure about this behavior...
2353
if (currentRow() == 0)
2354
i = currentItem() - numRows();
2356
i = currentItem() - currentRow();
2360
handleItemChange(old, e->state() & Qt::ShiftButton, e->state() & Qt::ControlButton);
2361
if (!(e->state() & Qt::ShiftButton) || !d->selectAnchor)
2362
d->selectAnchor = d->current;
2367
selectCurrent = true;
2368
d->currInputString.clear();
2369
toggleCurrentItem();
2370
if (selectionMode() == Extended && d->current->isSelected())
2371
emit highlighted(currentItem());
2372
if (!(e->state() & Qt::ShiftButton) || !d->selectAnchor)
2373
d->selectAnchor = d->current;
2376
case Qt::Key_Return:
2379
selectCurrent = true;
2380
d->currInputString.clear();
2381
if (currentItem() >= 0 && selectionMode() != NoSelection) {
2382
QString tmp = item(currentItem())->text();
2383
emit selected(currentItem());
2384
emit selected(item(currentItem()));
2387
emit returnPressed(item(currentItem()));
2389
if (!(e->state() & Qt::ShiftButton) || !d->selectAnchor)
2390
d->selectAnchor = d->current;
2395
selectCurrent = true;
2396
d->currInputString.clear();
2398
handleItemChange(old, e->state() & Qt::ShiftButton, e->state() & Qt::ControlButton);
2399
if (!(e->state() & Qt::ShiftButton) || !d->selectAnchor)
2400
d->selectAnchor = d->current;
2405
selectCurrent = true;
2406
d->currInputString.clear();
2407
int i = (int)count() - 1;
2409
handleItemChange(old, e->state() & Qt::ShiftButton, e->state() & Qt::ControlButton);
2410
if (!(e->state() & Qt::ShiftButton) || !d->selectAnchor)
2411
d->selectAnchor = d->current;
2416
if (!e->text().isEmpty() && e->text()[0].isPrint() && count()) {
2417
int curItem = currentItem();
2420
if (!d->inputTimer->isActive()) {
2421
d->currInputString = e->text();
2422
curItem = d->findItemByName(++curItem, d->currInputString);
2424
d->inputTimer->stop();
2425
d->currInputString += e->text();
2426
int oldCurItem = curItem;
2427
curItem = d->findItemByName(curItem, d->currInputString);
2429
curItem = d->findItemByName(++oldCurItem, e->text());
2430
d->currInputString = e->text();
2434
setCurrentItem(curItem);
2435
if (curItem >= 0 && selectionMode() == Q3ListBox::Extended) {
2436
bool changed = false;
2437
bool block = signalsBlocked();
2440
blockSignals(block);
2441
Q3ListBoxItem *i = item(curItem);
2442
if (!i->s && i->isSelectable()) {
2448
emit selectionChanged();
2450
d->inputTimer->start(400, true);
2452
d->currInputString.clear();
2453
if (e->state() & Qt::ControlButton) {
2466
if (selectCurrent && selectionMode() == Single &&
2467
d->current && !d->current->s) {
2468
updateItem(d->current);
2469
setSelected(d->current, true);
2476
void Q3ListBox::focusInEvent(QFocusEvent *e)
2478
d->mousePressRow = -1;
2479
d->mousePressColumn = -1;
2480
d->inMenuMode = false;
2481
if (e->reason() != Qt::MouseFocusReason && !d->current && d->head) {
2482
d->current = d->head;
2483
Q3ListBoxItem *i = d->current;
2487
int tmp2 = index(i);
2488
emit highlighted(i);
2490
emit highlighted(tmp);
2491
emit highlighted(tmp2);
2492
emit currentChanged(i);
2494
if (style()->styleHint(QStyle::SH_ItemView_ChangeHighlightOnFocus, 0, this))
2498
updateItem(currentItem());
2504
void Q3ListBox::focusOutEvent(QFocusEvent *e)
2506
if (style()->styleHint(QStyle::SH_ItemView_ChangeHighlightOnFocus, 0, this)) {
2508
e->reason() == Qt::PopupFocusReason ||
2509
(qApp->focusWidget() && qApp->focusWidget()->inherits("QMenuBar"));
2515
updateItem(currentItem());
2520
bool Q3ListBox::eventFilter(QObject *o, QEvent *e)
2522
return Q3ScrollView::eventFilter(o, e);
2526
Repaints the item at position \a index in the list.
2529
void Q3ListBox::updateItem(int index)
2532
updateItem(item(index));
2539
Repaints the Q3ListBoxItem \a i.
2542
void Q3ListBox::updateItem(Q3ListBoxItem * i)
2547
d->updateTimer->start(0, true);
2552
\property Q3ListBox::selectionMode
2553
\brief the selection mode of the list box
2555
Sets the list box's selection mode, which may be one of \c Single
2556
(the default), \c Extended, \c Multi or \c NoSelection.
2561
void Q3ListBox::setSelectionMode(SelectionMode mode)
2563
if (d->selectionMode == mode)
2566
if ((selectionMode() == Multi || selectionMode() == Extended)
2567
&& (mode == Q3ListBox::Single || mode == Q3ListBox::NoSelection)){
2569
if ((mode == Q3ListBox::Single) && currentItem())
2570
setSelected(currentItem(), true);
2573
d->selectionMode = mode;
2574
triggerUpdate(true);
2578
Q3ListBox::SelectionMode Q3ListBox::selectionMode() const
2580
return d->selectionMode;
2585
\property Q3ListBox::multiSelection
2586
\brief whether or not the list box is in Multi selection mode
2588
Consider using the \l Q3ListBox::selectionMode property instead of
2591
When setting this property, Multi selection mode is used if set to true and
2592
to Single selection mode if set to false.
2594
When getting this property, true is returned if the list box is in
2595
Multi selection mode or Extended selection mode, and false if it is
2596
in Single selection mode or NoSelection mode.
2601
bool Q3ListBox::isMultiSelection() const
2603
return selectionMode() == Multi || selectionMode() == Extended;
2606
void Q3ListBox::setMultiSelection(bool enable)
2608
setSelectionMode(enable ? Multi : Single);
2613
Toggles the selection status of currentItem() and repaints if the
2614
list box is a \c Multi selection list box.
2616
\sa setMultiSelection()
2619
void Q3ListBox::toggleCurrentItem()
2621
if (selectionMode() == Single ||
2622
selectionMode() == NoSelection ||
2626
if (d->current->s || d->current->isSelectable()) {
2627
d->current->s = !d->current->s;
2628
emit selectionChanged();
2629
#ifndef QT_NO_ACCESSIBILITY
2630
int ind = index(d->current);
2631
QAccessible::updateAccessibility(viewport(), 0, QAccessible::Selection);
2632
QAccessible::updateAccessibility(viewport(), ind+1, QAccessible::StateChanged);
2633
QAccessible::updateAccessibility(viewport(), ind+1, d->current->s ? QAccessible::SelectionAdd : QAccessible::SelectionRemove);
2636
updateItem(d->current);
2643
If \a select is true the item at position \a index is selected;
2644
otherwise the item is deselected.
2647
void Q3ListBox::setSelected(int index, bool select)
2649
setSelected(item(index), select);
2654
Selects \a item if \a select is true or unselects it if \a select
2655
is false, and repaints the item appropriately.
2657
If the list box is a \c Single selection list box and \a select is
2658
true, setSelected() calls setCurrentItem().
2660
If the list box is a \c Single selection list box, \a select is
2661
false, setSelected() calls clearSelection().
2663
\sa setMultiSelection(), setCurrentItem(), clearSelection(), currentItem()
2666
void Q3ListBox::setSelected(Q3ListBoxItem * item, bool select)
2668
if (!item || !item->isSelectable() ||
2669
(bool)item->s == select || d->selectionMode == NoSelection)
2672
int ind = index(item);
2673
bool emitHighlighted = (d->current != item);
2674
if (selectionMode() == Single) {
2675
if (d->current != item) {
2676
Q3ListBoxItem *o = d->current;
2677
if (d->current && d->current->s)
2678
d->current->s = false;
2680
#ifndef QT_NO_ACCESSIBILITY
2681
QAccessible::updateAccessibility(viewport(), ind+1, QAccessible::Focus);
2683
d->currentColumn = ind / numRows();
2684
d->currentRow = ind % numRows();
2691
item->s = (uint)select;
2694
if (d->selectionMode == Single && select) {
2695
emit selectionChanged(item);
2696
#ifndef QT_NO_ACCESSIBILITY
2697
QAccessible::updateAccessibility(viewport(), ind+1, QAccessible::StateChanged);
2700
emit selectionChanged();
2701
#ifndef QT_NO_ACCESSIBILITY
2702
QAccessible::updateAccessibility(viewport(), 0, QAccessible::Selection);
2703
if (d->selectionMode != Single)
2704
QAccessible::updateAccessibility(viewport(), ind+1, select ? QAccessible::SelectionAdd : QAccessible::SelectionRemove);
2707
if (emitHighlighted) {
2711
int tmp2 = index(item);
2712
emit highlighted(item);
2714
emit highlighted(tmp);
2715
emit highlighted(tmp2);
2716
emit currentChanged(item);
2722
Returns true if item \a i is selected; otherwise returns false.
2725
bool Q3ListBox::isSelected(int i) const
2727
if (selectionMode() == Single && i != currentItem())
2730
Q3ListBoxItem * lbi = item(i);
2732
return false; // should not happen
2740
Returns true if item \a i is selected; otherwise returns false.
2743
bool Q3ListBox::isSelected(const Q3ListBoxItem * i) const
2751
/*! Returns the selected item if the list box is in
2752
single-selection mode and an item is selected.
2754
If no items are selected or the list box is in another selection mode
2755
this function returns 0.
2757
\sa setSelected() setMultiSelection()
2760
Q3ListBoxItem* Q3ListBox::selectedItem() const
2762
if (d->selectionMode != Single)
2764
if (isSelected(currentItem()))
2771
Deselects all items, if possible.
2773
Note that a \c Single selection list box will automatically select
2774
an item if it has keyboard focus.
2777
void Q3ListBox::clearSelection()
2783
In \c Multi and \c Extended modes, this function sets all items to
2784
be selected if \a select is true, and to be unselected if \a
2787
In \c Single and \c NoSelection modes, this function only changes
2788
the selection status of currentItem().
2791
void Q3ListBox::selectAll(bool select)
2793
if (selectionMode() == Multi || selectionMode() == Extended) {
2794
bool b = signalsBlocked();
2796
for (int i = 0; i < (int)count(); i++)
2797
setSelected(i, select);
2799
emit selectionChanged();
2800
} else if (d->current) {
2801
Q3ListBoxItem * i = d->current;
2802
setSelected(i, select);
2807
Inverts the selection. Only works in \c Multi and \c Extended
2811
void Q3ListBox::invertSelection()
2813
if (d->selectionMode == Single ||
2814
d->selectionMode == NoSelection)
2817
bool b = signalsBlocked();
2819
for (int i = 0; i < (int)count(); i++)
2820
setSelected(i, !item(i)->isSelected());
2822
emit selectionChanged();
2827
Not used anymore; provided for compatibility.
2830
void Q3ListBox::emitChangedSignal(bool)
2837
QSize Q3ListBox::sizeHint() const
2839
if (cachedSizeHint().isValid())
2840
return cachedSizeHint();
2847
i < (int)d->columnPos.size()-1 &&
2848
d->columnPos[i] < 200)
2851
x = qMin(200, d->columnPos[i] +
2852
2 * style()->pixelMetric(QStyle::PM_DefaultFrameWidth));
2857
i < (int)d->rowPos.size()-1 &&
2861
y = qMin(200, d->rowPos[i] +
2862
2 * style()->pixelMetric(QStyle::PM_DefaultFrameWidth));
2866
setCachedSizeHint(s);
2874
QSize Q3ListBox::minimumSizeHint() const
2876
return Q3ScrollView::minimumSizeHint();
2881
Ensures that a single paint event will occur at the end of the
2882
current event loop iteration. If \a doLayout is true, the layout
2886
void Q3ListBox::triggerUpdate(bool doLayout)
2889
d->layoutDirty = d->mustPaintAll = true;
2890
d->updateTimer->start(0, true);
2894
void Q3ListBox::setColumnMode(LayoutMode mode)
2896
if (mode == Variable)
2898
d->rowModeWins = false;
2899
d->columnMode = mode;
2900
triggerUpdate(true);
2904
void Q3ListBox::setColumnMode(int columns)
2908
d->columnMode = FixedNumber;
2909
d->numColumns = columns;
2910
d->rowModeWins = false;
2911
triggerUpdate(true);
2914
void Q3ListBox::setRowMode(LayoutMode mode)
2916
if (mode == Variable)
2918
d->rowModeWins = true;
2920
triggerUpdate(true);
2924
void Q3ListBox::setRowMode(int rows)
2928
d->rowMode = FixedNumber;
2930
d->rowModeWins = true;
2931
triggerUpdate(true);
2935
\property Q3ListBox::columnMode
2936
\brief the column layout mode for this list box.
2938
setColumnMode() sets the layout mode and adjusts the number of
2939
displayed columns. The row layout mode automatically becomes \c
2940
Variable, unless the column mode is \c Variable.
2942
\sa setRowMode() rowMode numColumns
2946
Q3ListBox::LayoutMode Q3ListBox::columnMode() const
2951
return d->columnMode;
2956
\property Q3ListBox::rowMode
2957
\brief the row layout mode for this list box
2959
This property is normally \c Variable.
2961
setRowMode() sets the layout mode and adjusts the number of
2962
displayed rows. The column layout mode automatically becomes \c
2963
Variable, unless the row mode is \c Variable.
2969
Q3ListBox::LayoutMode Q3ListBox::rowMode() const
2979
\property Q3ListBox::numColumns
2980
\brief the number of columns in the list box
2982
This is normally 1, but can be different if \l
2983
Q3ListBox::columnMode or \l Q3ListBox::rowMode has been set.
2985
\sa columnMode rowMode numRows
2988
int Q3ListBox::numColumns() const
2992
if (!d->rowModeWins && d->columnMode == FixedNumber)
2993
return d->numColumns;
2995
return d->columnPos.size()-1;
3000
\property Q3ListBox::numRows
3001
\brief the number of rows in the list box.
3003
This is equal to the number of items in the default single-column
3004
layout, but can be different.
3006
\sa columnMode rowMode numColumns
3009
int Q3ListBox::numRows() const
3013
if (d->rowModeWins && d->rowMode == FixedNumber)
3016
return d->rowPos.size()-1;
3021
This function does the hard layout work. You should never need to
3025
void Q3ListBox::doLayout() const
3027
if (!d->layoutDirty || d->resizeTimer->isActive())
3033
// columnMode() is known to be Variable
3034
tryGeometry(d->numRows, (c+d->numRows-1)/d->numRows);
3037
// columnMode() is known to be Variable
3039
// this is basically the FitToWidth code, but edited to use rows.
3041
Q3ListBoxItem * i = d->head;
3043
int h = i->height(this);
3048
int vh = viewportSize(1, 1).height();
3050
int rows = vh / maxh;
3055
if (variableHeight() && rows < c) {
3058
tryGeometry(rows, (c+rows-1)/rows);
3059
} while (rows <= c &&
3060
d->rowPos[(int)d->rowPos.size()-1] <= vh);
3063
tryGeometry(rows, (c+rows-1)/rows);
3064
int nvh = viewportSize(d->columnPos[(int)d->columnPos.size()-1],
3065
d->rowPos[(int)d->rowPos.size()-1]).height();
3068
} while (d->rowPos.size() > 2 &&
3069
vh < d->rowPos[(int)d->rowPos.size()-1]);
3075
if (columnMode() == FixedNumber) {
3076
tryGeometry((count()+d->numColumns-1)/d->numColumns,
3078
} else if (d->head) { // FitToWidth, at least one item
3080
Q3ListBoxItem * i = d->head;
3082
int w = i->width(this);
3087
int vw = viewportSize(1, 1).width();
3089
int cols = vw / maxw;
3094
if (variableWidth() && cols < c) {
3097
tryGeometry((c+cols-1)/cols, cols);
3098
} while (cols <= c &&
3099
d->columnPos[(int)d->columnPos.size()-1] <= vw);
3102
tryGeometry((c+cols-1)/cols, cols);
3103
int nvw = viewportSize(d->columnPos[(int)d->columnPos.size()-1],
3104
d->rowPos[(int)d->rowPos.size()-1]).width();
3107
} while (d->columnPos.size() > 2 &&
3108
vw < d->columnPos[(int)d->columnPos.size()-1]);
3115
d->layoutDirty = false;
3116
int w = d->columnPos[(int)d->columnPos.size()-1];
3117
int h = d->rowPos[(int)d->rowPos.size()-1];
3118
QSize s(viewportSize(w, h));
3119
w = qMax(w, s.width());
3121
d->columnPosOne = d->columnPos[1];
3122
// extend the column for simple single-column listboxes
3123
if (columnMode() == FixedNumber && d->numColumns == 1 &&
3124
d->columnPos[1] < w)
3125
d->columnPos[1] = w;
3126
((Q3ListBox *)this)->resizeContents(w, h);
3131
Lay the items out in a \a columns by \a rows array. The array may
3132
be too big: doLayout() is expected to call this with the right
3136
void Q3ListBox::tryGeometry(int rows, int columns) const
3140
d->columnPos.resize(columns+1);
3144
d->rowPos.resize(rows+1);
3146
// funky hack I: dump the height/width of each column/row in
3147
// {column,row}Pos for later conversion to positions.
3149
for(c=0; c<=columns; c++)
3150
d->columnPos[c] = 0;
3152
for(r=0; r<=rows; r++)
3155
Q3ListBoxItem * i = d->head;
3156
while (i && c < columns) {
3157
if (i == d->current) {
3159
d->currentColumn = c;
3162
int w = i->width(this);
3163
if (d->columnPos[c] < w)
3164
d->columnPos[c] = w;
3165
int h = i->height(this);
3166
if (d->rowPos[r] < h)
3175
// funky hack II: if not variable {width,height}, unvariablify it.
3176
if (!variableWidth()) {
3178
for(c=0; c<columns; c++)
3179
if (w < d->columnPos[c])
3180
w = d->columnPos[c];
3181
for(c=0; c<columns; c++)
3182
d->columnPos[c] = w;
3184
if (!variableHeight()) {
3186
for(r=0; r<rows; r++)
3187
if (h < d->rowPos[r])
3189
for(r=0; r<rows; r++)
3192
// repair the hacking.
3194
for(c=0; c<=columns; c++) {
3195
int w = d->columnPos[c];
3196
d->columnPos[c] = x;
3200
for(r=0; r<=rows; r++) {
3201
int h = d->rowPos[r];
3209
Returns the row index of the current item, or -1 if no item is the
3213
int Q3ListBox::currentRow() const
3217
if (d->currentRow < 0)
3218
d->layoutDirty = true;
3221
return d->currentRow;
3226
Returns the column index of the current item, or -1 if no item is
3230
int Q3ListBox::currentColumn() const
3234
if (d->currentColumn < 0)
3235
d->layoutDirty = true;
3238
return d->currentColumn;
3242
void Q3ListBox::setTopItem(int index)
3244
if (index >= (int)count() || count() == 0)
3246
int col = index / numRows();
3247
int y = d->rowPos[index-col*numRows()];
3248
if (d->columnPos[col] >= contentsX() &&
3249
d->columnPos[col+1] <= contentsX() + visibleWidth())
3250
setContentsPos(contentsX(), y);
3252
setContentsPos(d->columnPos[col], y);
3256
Scrolls the list box so the item at position \a index in the list
3257
is displayed in the bottom row of the list box.
3262
void Q3ListBox::setBottomItem(int index)
3264
if (index >= (int)count() || count() == 0)
3266
int col = index / numRows();
3267
int y = d->rowPos[1+index-col*numRows()] - visibleHeight();
3270
if (d->columnPos[col] >= contentsX() &&
3271
d->columnPos[col+1] <= contentsX() + visibleWidth())
3272
setContentsPos(contentsX(), y);
3274
setContentsPos(d->columnPos[col], y);
3279
Returns the item at point \a p, which is in on-screen coordinates,
3280
or a 0 if there is no item at \a p.
3283
Q3ListBoxItem * Q3ListBox::itemAt(const QPoint& p) const
3289
np -= viewport()->pos();
3290
if (!viewport()->rect().contains(np))
3293
// take into account contents position
3294
np = viewportToContents(np);
3299
// return 0 when y is below the last row
3300
if (y > d->rowPos[numRows()])
3303
int col = columnAt(x);
3306
Q3ListBoxItem *i = item(col * numRows() + row);
3307
if (i && numColumns() > 1) {
3308
if (d->columnPos[col] + i->width(this) >= x)
3311
if (d->columnPos[col + 1] >= x)
3319
Ensures that the current item is visible.
3322
void Q3ListBox::ensureCurrentVisible()
3329
int row = currentRow();
3330
int column = currentColumn();
3331
int w = (d->columnPos[column+1] - d->columnPos[column]) / 2;
3332
int h = (d->rowPos[row+1] - d->rowPos[row]) / 2;
3333
// next four lines are Bad. they mean that for pure left-to-right
3334
// languages, textual list box items are displayed better than
3335
// before when there is little space. for non-textual items, or
3336
// other languages, it means... that you really should have enough
3337
// space in the first place :)
3338
if (numColumns() == 1)
3340
if (w*2 > viewport()->width())
3341
w = viewport()->width()/2;
3343
ensureVisible(d->columnPos[column] + w, d->rowPos[row] + h, w, h);
3349
void Q3ListBox::doAutoScroll()
3351
if (d->scrollPos.x() < 0) {
3353
int x = contentsX() - horizontalScrollBar()->singleStep();
3356
if (x != contentsX()) {
3357
d->mouseMoveColumn = columnAt(x);
3359
if (x < contentsX())
3360
setContentsPos(x, contentsY());
3362
} else if (d->scrollPos.x() > 0) {
3364
int x = contentsX() + horizontalScrollBar()->singleStep();
3365
if (x + visibleWidth() > contentsWidth())
3366
x = contentsWidth() - visibleWidth();
3367
if (x != contentsX()) {
3368
d->mouseMoveColumn = columnAt(x + visibleWidth() - 1);
3370
if (x > contentsX())
3371
setContentsPos(x, contentsY());
3375
if (d->scrollPos.y() < 0) {
3377
int y = contentsY() - verticalScrollBar()->singleStep();
3380
if (y != contentsY()) {
3381
y = contentsY() - verticalScrollBar()->singleStep();
3382
d->mouseMoveRow = rowAt(y);
3385
} else if (d->scrollPos.y() > 0) {
3387
int y = contentsY() + verticalScrollBar()->singleStep();
3388
if (y + visibleHeight() > contentsHeight())
3389
y = contentsHeight() - visibleHeight();
3390
if (y != contentsY()) {
3391
y = contentsY() + verticalScrollBar()->singleStep();
3392
d->mouseMoveRow = rowAt(y + visibleHeight() - 1);
3397
if (d->scrollPos == QPoint(0, 0)) {
3398
delete d->scrollTimer;
3405
\property Q3ListBox::topItem
3406
\brief the index of an item at the top of the screen.
3408
When getting this property and the listbox has multiple columns,
3409
an arbitrary item is selected and returned.
3411
When setting this property, the list box is scrolled so the item
3412
at position \e index in the list is displayed in the top row of
3416
int Q3ListBox::topItem() const
3420
// move rightwards to the best column
3421
int col = columnAt(contentsX());
3422
int row = rowAt(contentsY());
3423
return col * numRows() + row;
3428
\property Q3ListBox::variableHeight
3429
\brief whether this list box has variable-height rows
3431
When the list box has variable-height rows (the default), each row
3432
is as high as the highest item in that row. When it has same-sized
3433
rows, all rows are as high as the highest item in the list box.
3438
bool Q3ListBox::variableHeight() const
3440
return d->variableHeight;
3444
void Q3ListBox::setVariableHeight(bool enable)
3446
if ((bool)d->variableHeight == enable)
3449
d->variableHeight = enable;
3450
triggerUpdate(true);
3455
\property Q3ListBox::variableWidth
3456
\brief whether this list box has variable-width columns
3458
When the list box has variable-width columns, each column is as
3459
wide as the widest item in that column. When it has same-sized
3460
columns (the default), all columns are as wide as the widest item
3466
bool Q3ListBox::variableWidth() const
3468
return d->variableWidth;
3472
void Q3ListBox::setVariableWidth(bool enable)
3474
if ((bool)d->variableWidth == enable)
3477
d->variableWidth = enable;
3478
triggerUpdate(true);
3483
Repaints only what really needs to be repainted.
3485
void Q3ListBox::refreshSlot()
3487
if (d->mustPaintAll ||
3489
d->mustPaintAll = false;
3490
bool currentItemVisible = itemVisible(currentItem());
3493
currentItemVisible &&
3494
d->currentColumn >= 0 &&
3495
d->currentRow >= 0 &&
3496
(d->columnPos[d->currentColumn] < contentsX() ||
3497
d->columnPos[d->currentColumn+1]>contentsX()+visibleWidth() ||
3498
d->rowPos[d->currentRow] < contentsY() ||
3499
d->rowPos[d->currentRow+1] > contentsY()+visibleHeight()))
3500
ensureCurrentVisible();
3501
viewport()->repaint();
3506
int x = contentsX();
3507
int y = contentsY();
3508
int col = columnAt(x);
3511
while(col < (int)d->columnPos.size()-1 && d->columnPos[col+1] < x)
3513
while(top < (int)d->rowPos.size()-1 && d->rowPos[top+1] < y)
3515
Q3ListBoxItem * i = item(col * numRows() + row);
3517
while (i && (int)col < numColumns() &&
3518
d->columnPos[col] < x + visibleWidth() ) {
3519
int cw = d->columnPos[col+1] - d->columnPos[col];
3520
while (i && row < numRows() && d->rowPos[row] <
3521
y + visibleHeight()) {
3523
r = r.unite(QRect(d->columnPos[col] - x, d->rowPos[row] - y,
3524
cw, d->rowPos[row+1] - d->rowPos[row]));
3529
if (numColumns() > 1) {
3531
i = item(col * numRows() + row);
3536
viewport()->repaint();
3538
viewport()->repaint(r);
3544
void Q3ListBox::viewportPaintEvent(QPaintEvent * e)
3547
QWidget* vp = viewport();
3549
QRegion r = e->region();
3553
// this stuff has been useful enough times that from now I'm
3554
// leaving it in the source.
3556
qDebug("%s/%s: %i rects", className(), name(), r.rects().size());
3557
while(i < r.rects().size()) {
3558
qDebug("rect %d: %d, %d, %d, %d", i,
3559
r.rects()[i].left(), r.rects()[i].top(),
3560
r.rects()[i].width(), r.rects()[i].height());
3567
int x = contentsX();
3568
int y = contentsY();
3569
int w = vp->width();
3570
int h = vp->height();
3572
int col = columnAt(x);
3576
Q3ListBoxItem * i = item(col*numRows() + row);
3578
const QPalette &pal = palette();
3579
p.setPen(pal.text().color());
3580
p.setBackground(palette().brush(backgroundRole()).color());
3581
while (i && (int)col < numColumns() && d->columnPos[col] < x + w) {
3582
int cw = d->columnPos[col+1] - d->columnPos[col];
3583
while (i && (int)row < numRows() && d->rowPos[row] < y + h) {
3584
int ch = d->rowPos[row+1] - d->rowPos[row];
3585
QRect itemRect(d->columnPos[col]-x, d->rowPos[row]-y, cw, ch);
3586
QRegion tempRegion(itemRect);
3587
QRegion itemPaintRegion(tempRegion.intersect(r ));
3588
if (!itemPaintRegion.isEmpty()) {
3590
p.setClipRegion(itemPaintRegion);
3591
p.translate(d->columnPos[col]-x, d->rowPos[row]-y);
3592
paintCell(&p, row, col);
3594
r = r.subtract(itemPaintRegion);
3598
// reset dirty flag only if the entire item was painted
3599
if (itemPaintRegion == QRegion(itemRect))
3605
if (numColumns() > 1) {
3607
i = item(col * numRows() + row);
3614
p.fillRect(0, 0, w, h, viewport()->palette().brush(viewport()->backgroundRole()));
3619
Returns the height in pixels of the item with index \a index. \a
3620
index defaults to 0.
3622
If \a index is too large, this function returns 0.
3625
int Q3ListBox::itemHeight(int index) const
3627
if (index >= (int)count() || index < 0)
3629
int r = index % numRows();
3630
return d->rowPos[r+1] - d->rowPos[r];
3635
Returns the index of the column at \a x, which is in the listbox's
3636
coordinates, not in on-screen coordinates.
3638
If there is no column that spans \a x, columnAt() returns -1.
3641
int Q3ListBox::columnAt(int x) const
3645
if (!d->columnPos.size())
3647
if (x >= d->columnPos[(int)d->columnPos.size()-1])
3648
return numColumns() - 1;
3651
while(col < (int)d->columnPos.size()-1 && d->columnPos[col+1] < x)
3658
Returns the index of the row at \a y, which is in the listbox's
3659
coordinates, not in on-screen coordinates.
3661
If there is no row that spans \a y, rowAt() returns -1.
3664
int Q3ListBox::rowAt(int y) const
3669
// find the top item, use bsearch for speed
3671
int r = d->rowPos.size() - 2;
3674
if (l <= d->rowPosCache && d->rowPosCache <= r) {
3675
if (d->rowPos[qMax(l, d->rowPosCache - 10)] <= y
3676
&& y <= d->rowPos[qMin(r, d->rowPosCache + 10)]) {
3677
l = qMax(l, d->rowPosCache - 10);
3678
r = qMin(r, d->rowPosCache + 10);
3681
int i = ((l+r+1) / 2);
3683
if (d->rowPos[i] > y)
3690
if (d->rowPos[i] <= y && y <= d->rowPos[i+1] )
3693
return d->count - 1;
3698
Returns the rectangle on the screen that \a item occupies in
3699
viewport()'s coordinates, or an invalid rectangle if \a item is 0
3700
or is not currently visible.
3703
QRect Q3ListBox::itemRect(Q3ListBoxItem *item) const
3705
if (d->resizeTimer->isActive())
3706
return QRect(0, 0, -1, -1);
3708
return QRect(0, 0, -1, -1);
3710
int i = index(item);
3711
int col = i / numRows();
3712
int row = i % numRows();
3714
int x = d->columnPos[col] - contentsX();
3715
int y = d->rowPos[row] - contentsY();
3717
QRect r(x, y, d->columnPos[col + 1] - d->columnPos[col],
3718
d->rowPos[row + 1] - d->rowPos[row]);
3719
if (r.intersects(QRect(0, 0, visibleWidth(), visibleHeight())))
3721
return QRect(0, 0, -1, -1);
3726
Using this method is quite inefficient. We suggest to use insertItem()
3727
for inserting and sort() afterwards.
3729
Inserts \a lbi at its sorted position in the list box and returns the
3732
All items must be inserted with inSort() to maintain the sorting
3733
order. inSort() treats any pixmap (or user-defined type) as
3734
lexicographically less than any string.
3736
\sa insertItem(), sort()
3738
int Q3ListBox::inSort(const Q3ListBoxItem * lbi)
3743
Q3ListBoxItem * i = d->head;
3746
while(i && i->text() < lbi->text()) {
3756
Using this method is quite inefficient. We suggest to use insertItem()
3757
for inserting and sort() afterwards.
3759
Inserts a new item of \a text at its sorted position in the list box and
3760
returns the position.
3762
All items must be inserted with inSort() to maintain the sorting
3763
order. inSort() treats any pixmap (or user-defined type) as
3764
lexicographically less than any string.
3766
\sa insertItem(), sort()
3768
int Q3ListBox::inSort(const QString& text)
3770
Q3ListBoxItem *lbi = new Q3ListBoxText(text);
3772
Q3ListBoxItem * i = d->head;
3775
while(i && i->text() < lbi->text()) {
3786
void Q3ListBox::resizeEvent(QResizeEvent *e)
3788
d->layoutDirty = (d->layoutDirty ||
3789
rowMode() == FitToHeight ||
3790
columnMode() == FitToWidth);
3792
if (!d->layoutDirty && columnMode() == FixedNumber &&
3793
d->numColumns == 1) {
3794
int w = d->columnPosOne;
3795
QSize s(viewportSize(w, contentsHeight()));
3796
w = qMax(w, s.width());
3797
d->columnPos[1] = qMax(w, d->columnPosOne);
3798
resizeContents(d->columnPos[1], contentsHeight());
3801
if (d->resizeTimer->isActive())
3802
d->resizeTimer->stop();
3803
if (d->rowMode == FixedNumber && d->columnMode == FixedNumber) {
3804
bool currentItemVisible = itemVisible(currentItem());
3806
Q3ScrollView::resizeEvent(e);
3807
if (currentItemVisible)
3808
ensureCurrentVisible();
3810
viewport()->repaint(itemRect(d->current));
3811
} else if ((d->columnMode == FitToWidth || d->rowMode == FitToHeight) && !(isVisible())) {
3812
Q3ScrollView::resizeEvent(e);
3813
} else if (d->layoutDirty) {
3814
d->resizeTimer->start(100, true);
3815
resizeContents(contentsWidth() - (e->oldSize().width() - e->size().width()),
3816
contentsHeight() - (e->oldSize().height() - e->size().height()));
3817
Q3ScrollView::resizeEvent(e);
3819
Q3ScrollView::resizeEvent(e);
3827
void Q3ListBox::adjustItems()
3829
triggerUpdate(true);
3830
ensureCurrentVisible();
3835
Provided for compatibility with the old Q3ListBox. We recommend
3836
using Q3ListBoxItem::paint() instead.
3838
Repaints the cell at \a row, \a col using painter \a p.
3841
void Q3ListBox::paintCell(QPainter * p, int row, int col)
3843
bool drawActiveSelection = hasFocus() || d->inMenuMode ||
3844
!style()->styleHint(QStyle::SH_ItemView_ChangeHighlightOnFocus, 0, this);
3845
QPalette pal = palette();
3846
if(!drawActiveSelection)
3847
pal.setCurrentColorGroup(QPalette::Inactive);
3849
int cw = d->columnPos[col+1] - d->columnPos[col];
3850
int ch = d->rowPos[row+1] - d->rowPos[row];
3851
Q3ListBoxItem * i = item(col*numRows()+row);
3854
if (i->custom_highlight) {
3855
p->fillRect(0, 0, cw, ch, pal.brush(viewport()->foregroundRole()));
3856
p->setPen(pal.highlightedText().color());
3857
p->setBackground(pal.highlight());
3858
} else if (numColumns() == 1) {
3859
p->fillRect(0, 0, cw, ch, pal.brush(QPalette::Highlight));
3860
p->setPen(pal.highlightedText().color());
3861
p->setBackground(pal.highlight());
3863
int iw = i->width(this);
3864
p->fillRect(0, 0, iw, ch, pal.brush(QPalette::Highlight));
3865
p->fillRect(iw, 0, cw - iw + 1, ch, viewport()->palette().brush(viewport()->backgroundRole()));
3866
p->setPen(pal.highlightedText().color());
3867
p->setBackground(pal.highlight());
3870
p->fillRect(0, 0, cw, ch, viewport()->palette().brush(viewport()->backgroundRole()));
3875
if (d->current == i && hasFocus() && !i->custom_highlight) {
3876
if (numColumns() > 1)
3877
cw = i->width(this);
3878
QStyleOptionFocusRect opt;
3879
opt.rect.setRect(0, 0, cw, ch);
3881
opt.state = QStyle::State_FocusAtBorder;
3882
if (i->isSelected())
3883
opt.backgroundColor = pal.highlight().color();
3885
opt.backgroundColor = pal.base().color();
3886
style()->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, p, this);
3893
Returns the width of the widest item in the list box.
3896
long Q3ListBox::maxItemWidth() const
3901
int i = d->columnPos.size();
3903
if (m < d->columnPos[i])
3904
m = d->columnPos[i];
3911
void Q3ListBox::showEvent(QShowEvent *)
3913
d->ignoreMoves = false;
3914
d->mousePressRow = -1;
3915
d->mousePressColumn = -1;
3916
d->mustPaintAll = false;
3917
ensureCurrentVisible();
3921
\fn bool Q3ListBoxItem::isSelected() const
3923
Returns true if the item is selected; otherwise returns false.
3925
\sa Q3ListBox::isSelected(), isCurrent()
3929
Returns true if the item is the current item; otherwise returns
3932
\sa Q3ListBox::currentItem(), Q3ListBox::item(), isSelected()
3934
bool Q3ListBoxItem::isCurrent() const
3936
return listBox() && listBox()->hasFocus() &&
3937
listBox()->item(listBox()->currentItem()) == this;
3941
\fn void Q3ListBox::centerCurrentItem()
3943
If there is a current item, the list box is scrolled so that this
3944
item is displayed centered.
3946
\sa Q3ListBox::ensureCurrentVisible()
3950
Returns a pointer to the list box containing this item.
3953
Q3ListBox * Q3ListBoxItem::listBox() const
3960
Removes \a item from the list box and causes an update of the
3961
screen display. The item is not deleted. You should normally not
3962
need to call this function because Q3ListBoxItem::~Q3ListBoxItem()
3963
calls it. The normal way to delete an item is with \c delete.
3965
\sa Q3ListBox::insertItem()
3967
void Q3ListBox::takeItem(const Q3ListBoxItem * item)
3969
if (!item || d->clearing)
3973
if (item == d->last)
3974
d->last = d->last->p;
3975
if (item->p && item->p->n == item)
3976
item->p->n = item->n;
3977
if (item->n && item->n->p == item)
3978
item->n->p = item->p;
3979
if (d->head == item) {
3981
d->currentColumn = d->currentRow = -1;
3984
if (d->current == item) {
3985
d->current = item->n ? item->n : item->p;
3986
Q3ListBoxItem *i = d->current;
3990
int tmp2 = index(i);
3991
emit highlighted(i);
3993
emit highlighted(tmp);
3994
emit highlighted(tmp2);
3995
emit currentChanged(i);
3998
if (d->selectAnchor == item)
3999
d->selectAnchor = d->current;
4002
emit selectionChanged();
4003
((Q3ListBoxItem *)item)->lbox = 0;
4004
triggerUpdate(true);
4009
Finds the next item after start beginning with \a text.
4012
int Q3ListBoxPrivate::findItemByName(int start, const QString &text)
4014
if (start < 0 || (uint)start >= listBox->count())
4016
QString match = text.toLower();
4017
if (match.length() < 1)
4022
curText = listBox->text(item).toLower();
4023
if (curText.startsWith(match))
4026
if ((uint)item == listBox->count())
4028
} while (item != start);
4036
void Q3ListBox::clearInputString()
4038
d->currInputString.clear();
4042
Finds the first list box item that has the text \a text and
4043
returns it, or returns 0 of no such item could be found. If \c
4044
ComparisonFlags are specified in \a compare then these flags
4045
are used, otherwise the default is a case-insensitive, "begins
4049
Q3ListBoxItem *Q3ListBox::findItem(const QString &text, ComparisonFlags compare) const
4054
if (compare == CaseSensitive || compare == 0)
4055
compare |= ExactMatch;
4058
QString comtxt = text;
4059
if (!(compare & CaseSensitive))
4060
comtxt = text.toLower();
4062
Q3ListBoxItem *item;
4068
Q3ListBoxItem *beginsWithItem = 0;
4069
Q3ListBoxItem *endsWithItem = 0;
4070
Q3ListBoxItem *containsItem = 0;
4073
for (; item; item = item->n) {
4074
if (!(compare & CaseSensitive))
4075
itmtxt = item->text().toLower();
4077
itmtxt = item->text();
4079
if ((compare & ExactMatch)==ExactMatch && itmtxt == comtxt)
4081
if (compare & BeginsWith && !beginsWithItem && itmtxt.startsWith(comtxt))
4082
beginsWithItem = containsItem = item;
4083
if (compare & EndsWith && !endsWithItem && itmtxt.endsWith(comtxt))
4084
endsWithItem = containsItem = item;
4085
if ((compare & ExactMatch)==0 && !containsItem && itmtxt.contains(comtxt))
4086
containsItem = item;
4089
if (d->current && d->head) {
4091
for (; item && item != d->current; item = item->n) {
4092
if (!(compare & CaseSensitive))
4093
itmtxt = item->text().toLower();
4095
itmtxt = item->text();
4097
if ((compare & ExactMatch)==ExactMatch && itmtxt == comtxt)
4099
if (compare & BeginsWith && !beginsWithItem && itmtxt.startsWith(comtxt))
4100
beginsWithItem = containsItem = item;
4101
if (compare & EndsWith && !endsWithItem && itmtxt.endsWith(comtxt))
4102
endsWithItem = containsItem = item;
4103
if ((compare & ExactMatch)==0 && !containsItem && itmtxt.contains(comtxt))
4104
containsItem = item;
4109
// Obey the priorities
4111
return beginsWithItem;
4112
else if (endsWithItem)
4113
return endsWithItem;
4114
else if (containsItem)
4115
return containsItem;
4123
void Q3ListBox::drawRubber()
4127
if (!d->rubber->width() && !d->rubber->height())
4129
QPainter p(viewport());
4130
// p.setRasterOp(NotROP); // ### fix - use qrubberband instead
4131
QStyleOptionRubberBand opt;
4132
opt.rect = d->rubber->normalized();
4133
opt.palette = palette();
4134
opt.shape = QRubberBand::Rectangle;
4136
style()->drawControl(QStyle::CE_RubberBand, &opt, &p, this);
4144
void Q3ListBox::doRubberSelection(const QRect &old, const QRect &rubber)
4146
Q3ListBoxItem *i = d->head;
4148
bool changed = false;
4149
for (; i; i = i->n) {
4151
if (ir == QRect(0, 0, -1, -1))
4153
if (i->isSelected() && !ir.intersects(rubber) && ir.intersects(old)) {
4157
} else if (!i->isSelected() && ir.intersects(rubber)) {
4158
if (i->isSelectable()) {
4166
emit selectionChanged();
4167
#ifndef QT_NO_ACCESSIBILITY
4168
QAccessible::updateAccessibility(viewport(), 0, QAccessible::Selection);
4171
viewport()->repaint(pr);
4176
Returns true if the user is selecting items using a rubber band
4177
rectangle; otherwise returns false.
4180
bool Q3ListBox::isRubberSelecting() const
4182
return d->rubber != 0;
4187
Returns the item that comes after this in the list box. If this is
4188
the last item, 0 is returned.
4193
Q3ListBoxItem *Q3ListBoxItem::next() const
4199
Returns the item which comes before this in the list box. If this
4200
is the first item, 0 is returned.
4205
Q3ListBoxItem *Q3ListBoxItem::prev() const
4211
Returns the first item in this list box. If the list box is empty,
4215
Q3ListBoxItem *Q3ListBox::firstItem() const
4220
#if defined(Q_C_CALLBACKS)
4225
static int _cdecl cmpListBoxItems(const void *n1, const void *n2)
4227
static int cmpListBoxItems(const void *n1, const void *n2)
4233
Q3ListBoxPrivate::SortableItem *i1 = (Q3ListBoxPrivate::SortableItem *)n1;
4234
Q3ListBoxPrivate::SortableItem *i2 = (Q3ListBoxPrivate::SortableItem *)n2;
4236
return i1->item->text().localeAwareCompare(i2->item->text());
4239
#if defined(Q_C_CALLBACKS)
4244
If \a ascending is true sorts the items in ascending order;
4245
otherwise sorts in descending order.
4247
To compare the items, the text (Q3ListBoxItem::text()) of the items
4251
void Q3ListBox::sort(bool ascending)
4258
Q3ListBoxPrivate::SortableItem *items = new Q3ListBoxPrivate::SortableItem[count()];
4260
Q3ListBoxItem *item = d->head;
4262
for (; item; item = item->n)
4263
items[i++].item = item;
4265
qsort(items, count(), sizeof(Q3ListBoxPrivate::SortableItem), cmpListBoxItems);
4267
Q3ListBoxItem *prev = 0;
4270
for (i = 0; i < (int)count(); ++i) {
4271
item = items[i].item;
4284
for (i = (int)count() - 1; i >= 0 ; --i) {
4285
item = items[i].item;
4293
if (i == (int)count() - 1)
4302
// We have to update explicitly in case the current "vieport" overlaps the
4303
// new viewport we set (starting at (0,0)).
4304
bool haveToUpdate = contentsX() < visibleWidth() || contentsY() < visibleHeight();
4305
setContentsPos(0, 0);
4307
updateContents(0, 0, visibleWidth(), visibleHeight());
4310
void Q3ListBox::handleItemChange(Q3ListBoxItem *old, bool shift, bool control)
4312
if (d->selectionMode == Single) {
4314
} else if (d->selectionMode == Extended) {
4316
selectRange(d->selectAnchor ? d->selectAnchor : old,
4317
d->current, false, true, (d->selectAnchor && !control) ? true : false);
4318
} else if (!control) {
4319
bool block = signalsBlocked();
4322
blockSignals(block);
4323
setSelected(d->current, true);
4325
} else if (d->selectionMode == Multi) {
4327
selectRange(old, d->current, true, false);
4331
void Q3ListBox::selectRange(Q3ListBoxItem *from, Q3ListBoxItem *to, bool invert, bool includeFirst, bool clearSel)
4335
if (from == to && !includeFirst)
4337
Q3ListBoxItem *i = 0;
4339
int f_idx = -1, t_idx = -1;
4340
for (i = d->head; i; i = i->n, index++) {
4345
if (f_idx != -1 && t_idx != -1)
4348
if (f_idx > t_idx) {
4356
from = from->next();
4359
bool changed = false;
4361
for (i = d->head; i && i != from; i = i->n) {
4368
for (i = to->n; i; i = i->n) {
4377
for (i = from; i; i = i->next()) {
4379
if (!i->s && i->isSelectable()) {
4386
if ((bool)i->s != sel && sel && i->isSelectable() || !sel) {
4396
emit selectionChanged();
4397
#ifndef QT_NO_ACCESSIBILITY
4398
QAccessible::updateAccessibility(viewport(), 0, QAccessible::Selection);
4404
void Q3ListBox::changeEvent(QEvent *ev)
4406
if (ev->type() == QEvent::ActivationChange) {
4407
if (!isActiveWindow() && d->scrollTimer)
4408
d->scrollTimer->stop();
4409
if (!palette().isEqual(QPalette::Active, QPalette::Inactive))
4410
viewport()->update();
4412
Q3ScrollView::changeEvent(ev);
4414
if (ev->type() == QEvent::ApplicationFontChange || ev->type() == QEvent::FontChange)
4415
triggerUpdate(true);
4421
Make your derived classes return their own values for rtti(), and
4422
you can distinguish between listbox items. You should use values
4423
greater than 1000 preferably a large random number, to allow for
4424
extensions to this class.
4427
int Q3ListBoxItem::rtti() const
4433
\fn bool Q3ListBox::dragSelect() const
4435
Returns true. Dragging always selects.
4439
\fn void Q3ListBox::setDragSelect(bool b)
4441
Does nothing. Dragging always selects. The \a b parameter is ignored.
4445
\fn bool Q3ListBox::autoScroll() const
4447
Use dragAutoScroll() instead;
4451
\fn void Q3ListBox::setAutoScroll(bool b)
4453
Use setDragAutoScroll(\a b) instead.
4457
\fn bool Q3ListBox::autoScrollBar() const
4459
Use vScrollBarMode() instead.
4463
\fn void Q3ListBox::setAutoScrollBar(bool enable)
4465
Use setVScrollBarMode() instead.
4467
If \a enable is true, pass \c Auto as the argument to
4468
setVScrollBarMode(); otherwise, pass \c AlwaysOff.
4472
\fn bool Q3ListBox::scrollBar() const
4474
Use vScrollBarMode() instead.
4478
\fn void Q3ListBox::setScrollBar(bool enable)
4480
Use setVScrollBarMode() instead.
4482
If \a enable is true, pass \c AlwaysOn as the argument to
4483
setVScrollBarMode(); otherwise, pass \c AlwaysOff.
4487
\fn bool Q3ListBox::autoBottomScrollBar() const
4489
Use hScrollBarMode() instead.
4493
\fn void Q3ListBox::setAutoBottomScrollBar(bool enable)
4495
Use setHScrollBarMode() instead.
4497
If \a enable is true, pass \c Auto as the argument to
4498
setHScrollBarMode(); otherwise, pass \c AlwaysOff.
4502
\fn bool Q3ListBox::bottomScrollBar() const
4504
Use hScrollBarMode() instead.
4508
\fn void Q3ListBox::setBottomScrollBar(bool enable)
4510
Use setHScrollBarMode() instead.
4512
If \a enable is true, pass \c AlwaysOn as the argument to
4513
setHScrollBarMode(); otherwise, pass \c AlwaysOff.
4517
\fn bool Q3ListBox::smoothScrolling() const
4519
Returns false. Qt always scrolls smoothly.
4523
\fn void Q3ListBox::setSmoothScrolling(bool b)
4525
Does nothing. Qt always scrolls smoothly. The \a b parameter is
4530
\fn bool Q3ListBox::autoUpdate() const
4532
Returns true. Qt always updates automatically.
4536
\fn void Q3ListBox::setAutoUpdate(bool b)
4538
Does nothing. Qt always updates automatically. The \a b parameter
4543
\fn void Q3ListBox::setFixedVisibleLines(int lines)
4545
Use setRowMode(\a lines) instead.
4549
\fn int Q3ListBox::cellHeight(int i) const
4551
Use itemHeight(\a i) instead.
4555
\fn int Q3ListBox::cellHeight() const
4557
Use itemHeight() instead.
4561
\fn int Q3ListBox::cellWidth() const
4563
Use maxItemWidth() instead.
4567
\fn int Q3ListBox::cellWidth(int i) const
4569
Use maxItemWidth(\a i) instead.
4573
\fn int Q3ListBox::numCols() const
4575
Use numColumns() instead.
4579
\fn void Q3ListBox::updateCellWidth()
4581
Does nothing. Qt automatically updates.
4585
\fn int Q3ListBox::totalWidth() const
4587
Use contentsWidth() instead.
4591
\fn int Q3ListBox::totalHeight() const
4593
Use contentsHeight() instead.
4597
\fn int Q3ListBox::findItem(int yPos) const
4599
Use index(itemAt(\a yPos)) instead.
4603
\fn bool Q3ListBoxItem::selected() const
4605
Use isSelected() instead.
4609
\fn bool Q3ListBoxItem::current() const
4611
Use isCurrent() instead.
4616
\enum Q3ListBox::StringComparisonMode
4618
This enum type is used to set the string comparison mode when
4619
searching for an item. We'll refer to the string being searched
4620
as the 'target' string.
4622
\value CaseSensitive The strings must match case sensitively.
4623
\value ExactMatch The target and search strings must match exactly.
4624
\value BeginsWith The target string begins with the search string.
4625
\value EndsWith The target string ends with the search string.
4626
\value Contains The target string contains the search string.
4628
If you OR these flags together (excluding \c CaseSensitive), the
4629
search criteria be applied in the following order: \c ExactMatch,
4630
\c BeginsWith, \c EndsWith, \c Contains.
4632
Matching is case-insensitive unless \c CaseSensitive is set. \c
4633
CaseSensitive can be OR-ed with any combination of the other
4640
\typedef Q3ListBox::ComparisonFlags
4642
This typedef is used in Q3IconView's API for values that are OR'd
4643
combinations of \l StringComparisonMode values.
4645
\sa StringComparisonMode
4648
#endif // QT_NO_LISTBOX