1 /*---------------------------------------------------------------------\
3 | __ __ ____ _____ ____ |
4 | \ \ / /_ _/ ___|_ _|___ \ |
5 | \ V / _` \___ \ | | __) | |
6 | | | (_| |___) || | / __/ |
7 | |_|\__,_|____/ |_| |_____| |
11 \----------------------------------------------------------------------/
13 File: YQMultiSelectionBox.cc
15 Author: Stefan Hundhammer <sh@suse.de>
22 #include <QVBoxLayout>
23 #include <QHeaderView>
24 #define y2log_component "qt-ui"
25 #include <ycp/y2log.h>
32 #include "YQMultiSelectionBox.h"
33 #include "YQSignalBlocker.h"
34 #include "YQWidgetCaption.h"
36 #define DEFAULT_VISIBLE_LINES 5
37 #define SHRINKABLE_VISIBLE_LINES 2
40 YQMultiSelectionBox::YQMultiSelectionBox( YWidget * parent,
41 const string & label )
42 : QFrame( (QWidget *) parent->widgetRep() )
43 , YMultiSelectionBox( parent, label )
45 QVBoxLayout* layout = new QVBoxLayout( this );
50 layout->setSpacing( YQWidgetSpacing );
51 layout->setMargin( YQWidgetMargin );
53 _caption = new YQWidgetCaption( this, label );
54 YUI_CHECK_NEW( _caption );
55 layout->addWidget( _caption );
57 _qt_listView = new QTreeWidget( this );
58 YUI_CHECK_NEW( _qt_listView );
59 layout->addWidget( _qt_listView );
61 _qt_listView->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
62 _qt_listView->setHeaderLabel(""); // QListView doesn't have one single column by default!
63 _qt_listView->sortItems( 0, Qt::AscendingOrder );
64 //FIXME _qt_listView->header()->setStretchEnabled( true );
65 _qt_listView->header()->hide();
66 _qt_listView->setRootIsDecorated ( false );
67 _caption->setBuddy( _qt_listView );
69 // Very small default size if specified
71 connect( _qt_listView, SIGNAL( selectionChanged() ),
72 this, SLOT ( slotSelected() ) );
74 connect( this, SIGNAL( valueChanged() ),
75 this, SLOT ( slotValueChanged() ) );
79 YQMultiSelectionBox::~YQMultiSelectionBox()
86 YQMultiSelectionBox::setLabel( const string & label )
88 _caption->setText( label );
89 YMultiSelectionBox::setLabel( label );
94 YQMultiSelectionBox::addItem( YItem * yItem )
96 YQSignalBlocker sigBlocker( _qt_listView );
97 YMultiSelectionBox::addItem( yItem ); // will also check for NULL
99 YQMultiSelectionBoxItem * msbItem = new YQMultiSelectionBoxItem( this, _qt_listView, yItem );
101 YUI_CHECK_NEW( msbItem );
103 // Take care of the item's check box
105 if ( yItem->selected() )
106 msbItem->setCheckState(0, Qt::Checked);
109 // Take care of the QListView's keyboard focus
111 if ( ! _qt_listView->currentItem() )
112 msbItem->setSelected(true);
116 void YQMultiSelectionBox::selectItem( YItem * yItem, bool selected )
118 YMultiSelectionBox::selectItem( yItem, selected );
119 YQMultiSelectionBoxItem * msbItem = findItem( yItem );
122 msbItem->setCheckState( 1, selected ? Qt::Checked : Qt::Unchecked );
127 YQMultiSelectionBox::deselectAllItems()
129 YQSignalBlocker sigBlocker( _qt_listView );
130 YMultiSelectionBox::deselectAllItems();
132 QTreeWidgetItemIterator it( _qt_listView );
136 YQMultiSelectionBoxItem * item = dynamic_cast<YQMultiSelectionBoxItem *> (*it);
139 item->setCheckState(0, Qt::Checked);
147 YQMultiSelectionBox::deleteAllItems()
149 YQSignalBlocker sigBlocker( _qt_listView );
151 YMultiSelectionBox::deleteAllItems();
152 _qt_listView->clear();
157 YQMultiSelectionBox::currentItem()
159 // QListView::currentItem() is very similar, but not exactly the same as
160 // QListView::selectedItem(), and it is NOT to be confused with an item's
161 // "selected" state in a YQMultiSelectionBox (the item's check box):
163 // QListView::currentItem() is the item that currently has the keyboard
164 // focus. By default, it is displayed with a faint dotted outline.
166 // QListView::selectedItem() is the item that is selected in the QListView
167 // widget. It is displayed in a very visible way with inverted colors
168 // (typically blue backround). If there is a selected item, it is also the
169 // current item. if there is no selected item, there might still be a
170 // current item, though.
172 // The Y(Q)MultiSelectionBox item's "selected" state is completely
173 // independent of all this: It only depends on the item's check
174 // box. QListView::selectedItem() and QListView::currentItem() are just
175 // mechanisms for keyboard navigation to show the user which item's check
176 // box will be toggled when he hits the space bar.
178 // For the purpose of this function, QListView::currentItem() is the
179 // minimum requirement.
181 QTreeWidgetItem * currentQItem = _qt_listView->currentItem();
185 YQMultiSelectionBoxItem * item = dynamic_cast<YQMultiSelectionBoxItem *> (currentQItem);
188 return item->yItem();
196 YQMultiSelectionBox::setCurrentItem( YItem * yItem )
198 // See also explanations about QListView::currentItem() vs.
199 // QListView::selectedItem() above
201 // This function uses QListView::selectedItem() for better visibility.
202 // This implicitly also changes QListView::currentItem().
204 YQSignalBlocker sigBlocker( _qt_listView );
208 _qt_listView->clearSelection();
212 YQMultiSelectionBoxItem * msbItem = findItem( yItem );
215 msbItem->setSelected(true);
217 // This does NOT change the item's check box!
218 // (see explanations in YQMultiSelectionBox::currentItem() avove)
224 YQMultiSelectionBox::setEnabled( bool enabled )
226 _caption->setEnabled( enabled );
227 _qt_listView->setEnabled( enabled );
228 //_qt_listView->triggerUpdate();
229 YWidget::setEnabled( enabled );
233 int YQMultiSelectionBox::preferredWidth()
235 int hintWidth = (!_caption->isHidden()) ?
236 _caption->sizeHint().width() + frameWidth() : 0;
238 return max( 80, hintWidth );
242 int YQMultiSelectionBox::preferredHeight()
244 int hintHeight = (!_caption->isHidden()) ? _caption->sizeHint().height() : 0;
245 int visibleLines = shrinkable() ? SHRINKABLE_VISIBLE_LINES : DEFAULT_VISIBLE_LINES;
246 hintHeight += visibleLines * _qt_listView->fontMetrics().lineSpacing();
247 hintHeight += _qt_listView->frameWidth() * 2;
249 return max( 80, hintHeight );
254 YQMultiSelectionBox::setSize( int newWidth, int newHeight )
256 resize( newWidth, newHeight );
261 YQMultiSelectionBox::setKeyboardFocus()
263 _qt_listView->setFocus();
270 YQMultiSelectionBox::slotSelected()
274 if ( ! YQUI::ui()->eventPendingFor( this ) )
276 // Avoid overwriting a (more important) ValueChanged event with a SelectionChanged event
278 YQUI::ui()->sendEvent( new YWidgetEvent( this, YEvent::SelectionChanged ) );
285 YQMultiSelectionBox::slotValueChanged()
288 YQUI::ui()->sendEvent( new YWidgetEvent( this, YEvent::ValueChanged ) );
293 YQMultiSelectionBox::sendValueChanged()
299 YQMultiSelectionBoxItem *
300 YQMultiSelectionBox::findItem( YItem * wantedItem )
302 // FIXME: Don't search through all items, use the YItem::data() pointer instead
303 QTreeWidgetItemIterator it( _qt_listView );
307 YQMultiSelectionBoxItem * item = dynamic_cast<YQMultiSelectionBoxItem *> (*it);
309 if ( item && item->yItem() == wantedItem )
322 int YQMultiSelectionBoxItem::_item_count = 0;
326 YQMultiSelectionBoxItem::YQMultiSelectionBoxItem( YQMultiSelectionBox * parent,
327 QTreeWidget * listView,
329 : QTreeWidgetItem( listView)
331 , _multiSelectionBox( parent )
333 YUI_CHECK_PTR( yItem );
334 setFlags( Qt::ItemIsUserCheckable );
335 setCheckState( 0, Qt::Unchecked );
336 setText(0, fromUTF8( yItem->label() ));
337 setFlags(Qt::ItemIsUserCheckable);
338 _serial = _item_count++;
342 YQMultiSelectionBoxItem::stateChange( bool newState )
344 _yItem->setSelected( newState );
345 _multiSelectionBox->sendValueChanged();
346 //QTreeWidgetItem::stateChange( newState );
347 // FIXME checked or selected state?
348 QTreeWidgetItem::setCheckState( 0, newState ? Qt::Checked : Qt::Unchecked );
353 YQMultiSelectionBoxItem::key( int, bool ) const
356 * Return a sort key that depends on creation (i.e. insertion) order.
359 static QString sortKey;
360 sortKey.sprintf( "%010d", INT_MAX - _serial );
366 #include "YQMultiSelectionBox.moc"