1 /*---------------------------------------------------------------------\
3 | __ __ ____ _____ ____ |
4 | \ \ / /_ _/ ___|_ _|___ \ |
5 | \ V / _` \___ \ | | __) | |
6 | | | (_| |___) || | / __/ |
7 | |_|\__,_|____/ |_| |_____| |
11 \----------------------------------------------------------------------/
13 File: YQMultiSelectionBox.cc
15 Author: Stefan Hundhammer <sh@suse.de>
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 : QVBox( (QWidget *) parent->widgetRep() )
43 , YMultiSelectionBox( parent, label )
47 setSpacing( YQWidgetSpacing );
48 setMargin( YQWidgetMargin );
50 _caption = new YQWidgetCaption( this, label );
51 YUI_CHECK_NEW( _caption );
53 _qt_listView = new QListView( this );
54 YUI_CHECK_NEW( _qt_listView );
56 _qt_listView->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
57 _qt_listView->addColumn( "" ); // QListView doesn't have one single column by default!
58 _qt_listView->setSorting( 0, false );
59 _qt_listView->header()->setStretchEnabled( true );
60 _qt_listView->header()->hide();
61 _caption->setBuddy( _qt_listView );
63 // Very small default size if specified
65 connect( _qt_listView, SIGNAL( selectionChanged() ),
66 this, SLOT ( slotSelected() ) );
68 connect( this, SIGNAL( valueChanged() ),
69 this, SLOT ( slotValueChanged() ) );
73 YQMultiSelectionBox::~YQMultiSelectionBox()
80 YQMultiSelectionBox::setLabel( const string & label )
82 _caption->setText( label );
83 YMultiSelectionBox::setLabel( label );
88 YQMultiSelectionBox::addItem( YItem * yItem )
90 YQSignalBlocker sigBlocker( _qt_listView );
91 YMultiSelectionBox::addItem( yItem ); // will also check for NULL
93 YQMultiSelectionBoxItem * msbItem =
94 new YQMultiSelectionBoxItem( this, _qt_listView, yItem );
96 YUI_CHECK_NEW( msbItem );
98 // Take care of the item's check box
100 if ( yItem->selected() )
101 msbItem->setOn( true );
104 // Take care of the QListView's keyboard focus
106 if ( ! _qt_listView->selectedItem() )
107 _qt_listView->setSelected( msbItem, true );
111 void YQMultiSelectionBox::selectItem( YItem * yItem, bool selected )
113 YMultiSelectionBox::selectItem( yItem, selected );
114 YQMultiSelectionBoxItem * msbItem = findItem( yItem );
117 msbItem->setOn( selected );
122 YQMultiSelectionBox::deselectAllItems()
124 YQSignalBlocker sigBlocker( _qt_listView );
125 YMultiSelectionBox::deselectAllItems();
127 QListViewItemIterator it( _qt_listView );
131 YQMultiSelectionBoxItem * item = dynamic_cast<YQMultiSelectionBoxItem *> (*it);
134 item->setOn( false );
142 YQMultiSelectionBox::deleteAllItems()
144 YQSignalBlocker sigBlocker( _qt_listView );
146 YMultiSelectionBox::deleteAllItems();
147 _qt_listView->clear();
152 YQMultiSelectionBox::currentItem()
154 // QListView::currentItem() is very similar, but not exactly the same as
155 // QListView::selectedItem(), and it is NOT to be confused with an item's
156 // "selected" state in a YQMultiSelectionBox (the item's check box):
158 // QListView::currentItem() is the item that currently has the keyboard
159 // focus. By default, it is displayed with a faint dotted outline.
161 // QListView::selectedItem() is the item that is selected in the QListView
162 // widget. It is displayed a very visible with inverted colors (typically
163 // blue backround). If there is a selected item, it is also the current
164 // item. if there is no selected item, there might still be a current item,
167 // The Y(Q)MultiSelectionBox item's "selected" state is completely
168 // independent of all this: It only depends on the item's check
169 // box. QListView::selectedItem() and QListView::currentItem() are just
170 // mechanisms for keyboard navigation to show the user which item's check
171 // box will be toggled when he hits the space bar.
173 // For the purpose of this function, QListView::currentItem() is the
174 // minimum requirement.
176 QListViewItem * currentQItem = _qt_listView->currentItem();
180 YQMultiSelectionBoxItem * item = dynamic_cast<YQMultiSelectionBoxItem *> (currentQItem);
183 return item->yItem();
191 YQMultiSelectionBox::setCurrentItem( YItem * yItem )
193 // See also explanations about QListView::currentItem() vs.
194 // QListView::selectedItem() above
196 // This function uses QListView::selectedItem() for better visibility.
197 // This implicitly also changes QListView::currentItem().
199 YQSignalBlocker sigBlocker( _qt_listView );
203 _qt_listView->clearSelection();
207 YQMultiSelectionBoxItem * msbItem = findItem( yItem );
210 _qt_listView->setSelected( msbItem, true );
212 // This does NOT change the item's check box!
213 // (see explanations in YQMultiSelectionBox::currentItem() avove)
219 YQMultiSelectionBox::setEnabled( bool enabled )
221 _caption->setEnabled( enabled );
222 _qt_listView->setEnabled( enabled );
223 _qt_listView->triggerUpdate();
224 YWidget::setEnabled( enabled );
228 int YQMultiSelectionBox::preferredWidth()
230 int hintWidth = _caption->isShown() ?
231 _caption->sizeHint().width() + frameWidth() : 0;
233 return max( 80, hintWidth );
237 int YQMultiSelectionBox::preferredHeight()
239 int hintHeight = _caption->isShown() ? _caption->sizeHint().height() : 0;
240 int visibleLines = shrinkable() ? SHRINKABLE_VISIBLE_LINES : DEFAULT_VISIBLE_LINES;
241 hintHeight += visibleLines * _qt_listView->fontMetrics().lineSpacing();
242 hintHeight += _qt_listView->frameWidth() * 2;
244 return max( 80, hintHeight );
249 YQMultiSelectionBox::setSize( int newWidth, int newHeight )
251 resize( newWidth, newHeight );
256 YQMultiSelectionBox::setKeyboardFocus()
258 _qt_listView->setFocus();
265 YQMultiSelectionBox::slotSelected()
269 if ( ! YQUI::ui()->eventPendingFor( this ) )
271 // Avoid overwriting a (more important) ValueChanged event with a SelectionChanged event
273 YQUI::ui()->sendEvent( new YWidgetEvent( this, YEvent::SelectionChanged ) );
280 YQMultiSelectionBox::slotValueChanged()
283 YQUI::ui()->sendEvent( new YWidgetEvent( this, YEvent::ValueChanged ) );
288 YQMultiSelectionBox::sendValueChanged()
294 YQMultiSelectionBoxItem *
295 YQMultiSelectionBox::findItem( YItem * wantedItem )
297 // FIXME: Don't search through all items, use the YItem::data() pointer instead
299 QListViewItemIterator it( _qt_listView );
303 YQMultiSelectionBoxItem * item = dynamic_cast<YQMultiSelectionBoxItem *> (*it);
305 if ( item && item->yItem() == wantedItem )
318 int YQMultiSelectionBoxItem::_item_count = 0;
322 YQMultiSelectionBoxItem::YQMultiSelectionBoxItem( YQMultiSelectionBox * parent,
323 QListView * listView,
325 : QCheckListItem( listView, fromUTF8( yItem->label() ), QCheckListItem::CheckBox )
327 , _multiSelectionBox( parent )
329 YUI_CHECK_PTR( yItem );
331 _serial = _item_count++;
336 YQMultiSelectionBoxItem::stateChange( bool newState )
338 _yItem->setSelected( newState );
339 _multiSelectionBox->sendValueChanged();
340 QCheckListItem::stateChange( newState );
345 YQMultiSelectionBoxItem::key( int, bool ) const
348 * Return a sort key that depends on creation (i.e. insertion) order.
351 static QString sortKey;
352 sortKey.sprintf( "%010d", INT_MAX - _serial );
358 #include "YQMultiSelectionBox.moc"