1 /*---------------------------------------------------------------------\
3 | __ __ ____ _____ ____ |
4 | \ \ / /_ _/ ___|_ _|___ \ |
5 | \ V / _` \___ \ | | __) | |
6 | | | (_| |___) || | / __/ |
7 | |_|\__,_|____/ |_| |_____| |
11 \----------------------------------------------------------------------/
13 File: YQMultiSelectionBox.cc
15 Author: Stefan Hundhammer <sh@suse.de>
19 //#define QT3_SUPPORT 1
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 QTreeWidget( this );
60 YUI_CHECK_NEW( _qt_listView );
61 layout->addWidget( _qt_listView );
63 _qt_listView->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
64 _qt_listView->setHeaderLabel(""); // QListView doesn't have one single column by default!
65 _qt_listView->sortItems( 0, Qt::AscendingOrder );
66 //FIXME _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 = new YQMultiSelectionBoxItem( this, _qt_listView, yItem );
102 YUI_CHECK_NEW( msbItem );
104 // Take care of the item's check box
106 if ( yItem->selected() )
107 msbItem->setCheckState(0, Qt::Checked);
110 // Take care of the QListView's keyboard focus
112 if ( ! _qt_listView->currentItem() )
113 msbItem->setSelected(true);
117 void YQMultiSelectionBox::selectItem( YItem * yItem, bool selected )
119 YMultiSelectionBox::selectItem( yItem, selected );
120 YQMultiSelectionBoxItem * msbItem = findItem( yItem );
123 msbItem->setCheckState( 1, selected ? Qt::Checked : Qt::Unchecked );
128 YQMultiSelectionBox::deselectAllItems()
130 YQSignalBlocker sigBlocker( _qt_listView );
131 YMultiSelectionBox::deselectAllItems();
133 QTreeWidgetItemIterator it( _qt_listView );
137 YQMultiSelectionBoxItem * item = dynamic_cast<YQMultiSelectionBoxItem *> (*it);
140 item->setCheckState(0, Qt::Checked);
148 YQMultiSelectionBox::deleteAllItems()
150 YQSignalBlocker sigBlocker( _qt_listView );
152 YMultiSelectionBox::deleteAllItems();
153 _qt_listView->clear();
158 YQMultiSelectionBox::currentItem()
160 // QListView::currentItem() is very similar, but not exactly the same as
161 // QListView::selectedItem(), and it is NOT to be confused with an item's
162 // "selected" state in a YQMultiSelectionBox (the item's check box):
164 // QListView::currentItem() is the item that currently has the keyboard
165 // focus. By default, it is displayed with a faint dotted outline.
167 // QListView::selectedItem() is the item that is selected in the QListView
168 // widget. It is displayed in a very visible way with inverted colors
169 // (typically blue backround). If there is a selected item, it is also the
170 // current item. if there is no selected item, there might still be a
171 // current item, though.
173 // The Y(Q)MultiSelectionBox item's "selected" state is completely
174 // independent of all this: It only depends on the item's check
175 // box. QListView::selectedItem() and QListView::currentItem() are just
176 // mechanisms for keyboard navigation to show the user which item's check
177 // box will be toggled when he hits the space bar.
179 // For the purpose of this function, QListView::currentItem() is the
180 // minimum requirement.
182 QTreeWidgetItem * currentQItem = _qt_listView->currentItem();
186 YQMultiSelectionBoxItem * item = dynamic_cast<YQMultiSelectionBoxItem *> (currentQItem);
189 return item->yItem();
197 YQMultiSelectionBox::setCurrentItem( YItem * yItem )
199 // See also explanations about QListView::currentItem() vs.
200 // QListView::selectedItem() above
202 // This function uses QListView::selectedItem() for better visibility.
203 // This implicitly also changes QListView::currentItem().
205 YQSignalBlocker sigBlocker( _qt_listView );
209 _qt_listView->clearSelection();
213 YQMultiSelectionBoxItem * msbItem = findItem( yItem );
216 msbItem->setSelected(true);
218 // This does NOT change the item's check box!
219 // (see explanations in YQMultiSelectionBox::currentItem() avove)
225 YQMultiSelectionBox::setEnabled( bool enabled )
227 _caption->setEnabled( enabled );
228 _qt_listView->setEnabled( enabled );
229 //_qt_listView->triggerUpdate();
230 YWidget::setEnabled( enabled );
234 int YQMultiSelectionBox::preferredWidth()
236 int hintWidth = (!_caption->isHidden()) ?
237 _caption->sizeHint().width() + frameWidth() : 0;
239 return max( 80, hintWidth );
243 int YQMultiSelectionBox::preferredHeight()
245 int hintHeight = (!_caption->isHidden()) ? _caption->sizeHint().height() : 0;
246 int visibleLines = shrinkable() ? SHRINKABLE_VISIBLE_LINES : DEFAULT_VISIBLE_LINES;
247 hintHeight += visibleLines * _qt_listView->fontMetrics().lineSpacing();
248 hintHeight += _qt_listView->frameWidth() * 2;
250 return max( 80, hintHeight );
255 YQMultiSelectionBox::setSize( int newWidth, int newHeight )
257 resize( newWidth, newHeight );
262 YQMultiSelectionBox::setKeyboardFocus()
264 _qt_listView->setFocus();
271 YQMultiSelectionBox::slotSelected()
275 if ( ! YQUI::ui()->eventPendingFor( this ) )
277 // Avoid overwriting a (more important) ValueChanged event with a SelectionChanged event
279 YQUI::ui()->sendEvent( new YWidgetEvent( this, YEvent::SelectionChanged ) );
286 YQMultiSelectionBox::slotValueChanged()
289 YQUI::ui()->sendEvent( new YWidgetEvent( this, YEvent::ValueChanged ) );
294 YQMultiSelectionBox::sendValueChanged()
300 YQMultiSelectionBoxItem *
301 YQMultiSelectionBox::findItem( YItem * wantedItem )
303 // FIXME: Don't search through all items, use the YItem::data() pointer instead
304 QTreeWidgetItemIterator it( _qt_listView );
308 YQMultiSelectionBoxItem * item = dynamic_cast<YQMultiSelectionBoxItem *> (*it);
310 if ( item && item->yItem() == wantedItem )
323 int YQMultiSelectionBoxItem::_item_count = 0;
327 YQMultiSelectionBoxItem::YQMultiSelectionBoxItem( YQMultiSelectionBox * parent,
328 QTreeWidget * listView,
330 : QTreeWidgetItem( listView)
332 , _multiSelectionBox( parent )
334 YUI_CHECK_PTR( yItem );
335 setText(0, fromUTF8( yItem->label() ));
336 setFlags(Qt::ItemIsUserCheckable);
337 _serial = _item_count++;
341 YQMultiSelectionBoxItem::stateChange( bool newState )
343 _yItem->setSelected( newState );
344 _multiSelectionBox->sendValueChanged();
345 QTreeWidgetItem::stateChange( newState );
350 YQMultiSelectionBoxItem::key( int, bool ) const
353 * Return a sort key that depends on creation (i.e. insertion) order.
356 static QString sortKey;
357 sortKey.sprintf( "%010d", INT_MAX - _serial );
363 #include "YQMultiSelectionBox.moc"