1 /*---------------------------------------------------------------------\
3 | __ __ ____ _____ ____ |
4 | \ \ / /_ _/ ___|_ _|___ \ |
5 | \ V / _` \___ \ | | __) | |
6 | | | (_| |___) || | / __/ |
7 | |_|\__,_|____/ |_| |_____| |
11 \----------------------------------------------------------------------/
13 File: YQMultiSelectionBox.cc
15 Author: Stefan Hundhammer <sh@suse.de>
24 #include <QVBoxLayout>
26 #define y2log_component "qt-ui"
27 #include <ycp/y2log.h>
34 #include "YQMultiSelectionBox.h"
35 #include "YQSignalBlocker.h"
36 #include "YQWidgetCaption.h"
38 #define DEFAULT_VISIBLE_LINES 5
39 #define SHRINKABLE_VISIBLE_LINES 2
42 YQMultiSelectionBox::YQMultiSelectionBox( YWidget * parent,
43 const string & label )
44 : QFrame( (QWidget *) parent->widgetRep() )
45 , YMultiSelectionBox( parent, label )
47 QVBoxLayout* layout = new QVBoxLayout( this );
52 layout->setSpacing( YQWidgetSpacing );
53 layout->setMargin( YQWidgetMargin );
55 _caption = new YQWidgetCaption( this, label );
56 YUI_CHECK_NEW( _caption );
57 layout->addWidget( _caption );
59 _qt_listView = new Q3ListView( this );
60 YUI_CHECK_NEW( _qt_listView );
61 layout->addWidget( _qt_listView );
63 _qt_listView->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
64 _qt_listView->addColumn( "" ); // QListView doesn't have one single column by default!
65 _qt_listView->setSorting( 0, false );
66 _qt_listView->header()->setStretchEnabled( true );
67 _qt_listView->header()->hide();
68 _caption->setBuddy( _qt_listView );
70 // Very small default size if specified
72 connect( _qt_listView, SIGNAL( selectionChanged() ),
73 this, SLOT ( slotSelected() ) );
75 connect( this, SIGNAL( valueChanged() ),
76 this, SLOT ( slotValueChanged() ) );
80 YQMultiSelectionBox::~YQMultiSelectionBox()
87 YQMultiSelectionBox::setLabel( const string & label )
89 _caption->setText( label );
90 YMultiSelectionBox::setLabel( label );
95 YQMultiSelectionBox::addItem( YItem * yItem )
97 YQSignalBlocker sigBlocker( _qt_listView );
98 YMultiSelectionBox::addItem( yItem ); // will also check for NULL
100 YQMultiSelectionBoxItem * msbItem =
101 new YQMultiSelectionBoxItem( this, _qt_listView, yItem );
103 YUI_CHECK_NEW( msbItem );
105 // Take care of the item's check box
107 if ( yItem->selected() )
108 msbItem->setOn( true );
111 // Take care of the QListView's keyboard focus
113 if ( ! _qt_listView->selectedItem() )
114 _qt_listView->setSelected( msbItem, true );
118 void YQMultiSelectionBox::selectItem( YItem * yItem, bool selected )
120 YMultiSelectionBox::selectItem( yItem, selected );
121 YQMultiSelectionBoxItem * msbItem = findItem( yItem );
124 msbItem->setOn( selected );
129 YQMultiSelectionBox::deselectAllItems()
131 YQSignalBlocker sigBlocker( _qt_listView );
132 YMultiSelectionBox::deselectAllItems();
134 Q3ListViewItemIterator it( _qt_listView );
138 YQMultiSelectionBoxItem * item = dynamic_cast<YQMultiSelectionBoxItem *> (*it);
141 item->setOn( false );
149 YQMultiSelectionBox::deleteAllItems()
151 YQSignalBlocker sigBlocker( _qt_listView );
153 YMultiSelectionBox::deleteAllItems();
154 _qt_listView->clear();
159 YQMultiSelectionBox::currentItem()
161 // QListView::currentItem() is very similar, but not exactly the same as
162 // QListView::selectedItem(), and it is NOT to be confused with an item's
163 // "selected" state in a YQMultiSelectionBox (the item's check box):
165 // QListView::currentItem() is the item that currently has the keyboard
166 // focus. By default, it is displayed with a faint dotted outline.
168 // QListView::selectedItem() is the item that is selected in the QListView
169 // widget. It is displayed in a very visible way with inverted colors
170 // (typically blue backround). If there is a selected item, it is also the
171 // current item. if there is no selected item, there might still be a
172 // current item, though.
174 // The Y(Q)MultiSelectionBox item's "selected" state is completely
175 // independent of all this: It only depends on the item's check
176 // box. QListView::selectedItem() and QListView::currentItem() are just
177 // mechanisms for keyboard navigation to show the user which item's check
178 // box will be toggled when he hits the space bar.
180 // For the purpose of this function, QListView::currentItem() is the
181 // minimum requirement.
183 Q3ListViewItem * currentQItem = _qt_listView->currentItem();
187 YQMultiSelectionBoxItem * item = dynamic_cast<YQMultiSelectionBoxItem *> (currentQItem);
190 return item->yItem();
198 YQMultiSelectionBox::setCurrentItem( YItem * yItem )
200 // See also explanations about QListView::currentItem() vs.
201 // QListView::selectedItem() above
203 // This function uses QListView::selectedItem() for better visibility.
204 // This implicitly also changes QListView::currentItem().
206 YQSignalBlocker sigBlocker( _qt_listView );
210 _qt_listView->clearSelection();
214 YQMultiSelectionBoxItem * msbItem = findItem( yItem );
217 _qt_listView->setSelected( msbItem, true );
219 // This does NOT change the item's check box!
220 // (see explanations in YQMultiSelectionBox::currentItem() avove)
226 YQMultiSelectionBox::setEnabled( bool enabled )
228 _caption->setEnabled( enabled );
229 _qt_listView->setEnabled( enabled );
230 _qt_listView->triggerUpdate();
231 YWidget::setEnabled( enabled );
235 int YQMultiSelectionBox::preferredWidth()
237 int hintWidth = _caption->isShown() ?
238 _caption->sizeHint().width() + frameWidth() : 0;
240 return max( 80, hintWidth );
244 int YQMultiSelectionBox::preferredHeight()
246 int hintHeight = _caption->isShown() ? _caption->sizeHint().height() : 0;
247 int visibleLines = shrinkable() ? SHRINKABLE_VISIBLE_LINES : DEFAULT_VISIBLE_LINES;
248 hintHeight += visibleLines * _qt_listView->fontMetrics().lineSpacing();
249 hintHeight += _qt_listView->frameWidth() * 2;
251 return max( 80, hintHeight );
256 YQMultiSelectionBox::setSize( int newWidth, int newHeight )
258 resize( newWidth, newHeight );
263 YQMultiSelectionBox::setKeyboardFocus()
265 _qt_listView->setFocus();
272 YQMultiSelectionBox::slotSelected()
276 if ( ! YQUI::ui()->eventPendingFor( this ) )
278 // Avoid overwriting a (more important) ValueChanged event with a SelectionChanged event
280 YQUI::ui()->sendEvent( new YWidgetEvent( this, YEvent::SelectionChanged ) );
287 YQMultiSelectionBox::slotValueChanged()
290 YQUI::ui()->sendEvent( new YWidgetEvent( this, YEvent::ValueChanged ) );
295 YQMultiSelectionBox::sendValueChanged()
301 YQMultiSelectionBoxItem *
302 YQMultiSelectionBox::findItem( YItem * wantedItem )
304 // FIXME: Don't search through all items, use the YItem::data() pointer instead
305 Q3ListViewItemIterator it( _qt_listView );
309 YQMultiSelectionBoxItem * item = dynamic_cast<YQMultiSelectionBoxItem *> (*it);
311 if ( item && item->yItem() == wantedItem )
324 int YQMultiSelectionBoxItem::_item_count = 0;
328 YQMultiSelectionBoxItem::YQMultiSelectionBoxItem( YQMultiSelectionBox * parent,
329 Q3ListView * listView,
331 : Q3CheckListItem( listView, fromUTF8( yItem->label() ), Q3CheckListItem::CheckBox )
333 , _multiSelectionBox( parent )
335 YUI_CHECK_PTR( yItem );
337 _serial = _item_count++;
342 YQMultiSelectionBoxItem::stateChange( bool newState )
344 _yItem->setSelected( newState );
345 _multiSelectionBox->sendValueChanged();
346 Q3CheckListItem::stateChange( newState );
351 YQMultiSelectionBoxItem::key( int, bool ) const
354 * Return a sort key that depends on creation (i.e. insertion) order.
357 static QString sortKey;
358 sortKey.sprintf( "%010d", INT_MAX - _serial );
364 #include "YQMultiSelectionBox.moc"