1 /*---------------------------------------------------------------------\
3 | __ __ ____ _____ ____ |
4 | \ \ / /_ _/ ___|_ _|___ \ |
5 | \ V / _` \___ \ | | __) | |
6 | | | (_| |___) || | / __/ |
7 | |_|\__,_|____/ |_| |_____| |
11 \----------------------------------------------------------------------/
13 File: YQSelectionBox.cc
15 Author: Stefan Hundhammer <sh@suse.de>
21 #include <QListWidget>
22 #include <qnamespace.h>
25 #include <QVBoxLayout>
26 #define y2log_component "qt-ui"
27 #include <ycp/y2log.h>
34 #include "YQSelectionBox.h"
35 #include "YQSignalBlocker.h"
37 #include "YUIException.h"
38 #include "YQWidgetCaption.h"
40 #define VERBOSE_SELECTION 1
42 #define DEFAULT_VISIBLE_LINES 5
43 #define SHRINKABLE_VISIBLE_LINES 2
46 YQSelectionBox::YQSelectionBox( YWidget * parent, const string & label )
47 : QFrame( (QWidget *) parent->widgetRep() )
48 , YSelectionBox( parent, label )
52 QVBoxLayout* layout = new QVBoxLayout( this );
55 layout->setSpacing( YQWidgetSpacing );
56 layout->setMargin ( YQWidgetMargin );
58 _caption = new YQWidgetCaption( this, label );
59 YUI_CHECK_NEW( _caption );
60 layout->addWidget( _caption );
62 _qt_listBox = new QListWidget( this );
63 YUI_CHECK_NEW( _qt_listBox );
64 layout->addWidget( _qt_listBox );
66 _qt_listBox->installEventFilter( this );
67 //FIXME _qt_listBox->setVariableHeight( false );
68 _qt_listBox->setSizePolicy( QSizePolicy( QSizePolicy::Expanding,
69 QSizePolicy::Expanding ) );
70 //FIXME _qt_listBox->setTopItem(0);
71 _caption->setBuddy( _qt_listBox );
73 connect( _qt_listBox, SIGNAL( highlighted ( int ) ),
74 this, SLOT ( slotSelected( int ) ) );
76 connect( _qt_listBox, SIGNAL( doubleClicked( QListWidgetItem * ) ),
77 this, SLOT ( slotActivated( QListWidgetItem * ) ) );
79 connect( &_timer, SIGNAL( timeout() ),
80 this, SLOT ( returnImmediately() ) );
84 YQSelectionBox::~YQSelectionBox()
90 void YQSelectionBox::setLabel( const string & label )
92 _caption->setText( label );
93 YSelectionBox::setLabel( label );
97 void YQSelectionBox::addItem( YItem * item )
99 YSelectionBox::addItem( item );
102 if ( item->hasIconName() )
104 string iconName = iconFullPath( item );
105 icon = QPixmap( iconName.c_str() );
108 y2warning( "Can't load icon %s", iconName.c_str() );
113 _qt_listBox->addItem( fromUTF8( item->label() ) );
117 QListWidgetItem *i = new QListWidgetItem(_qt_listBox);
118 i->setData(Qt::DisplayRole, fromUTF8( item->label() ) );
119 i->setData(Qt::DecorationRole, icon );
120 _qt_listBox->addItem( i );
123 if ( item->selected() )
125 YQSignalBlocker sigBlocker( _qt_listBox );
126 _qt_listBox->setCurrentItem( _qt_listBox->item( item->index() ) );
131 void YQSelectionBox::selectItem( YItem * item, bool selected )
133 YQSignalBlocker sigBlocker( _qt_listBox );
135 YSelectionBox::selectItem( item, selected );
136 _qt_listBox->setCurrentRow( selected ? item->index() : -1 );
140 void YQSelectionBox::selectItem( int index )
142 YSelectionBox::deselectAllItems();
143 YItem * item = YSelectionBox::itemAt( index );
147 #ifdef VERBOSE_SELECTION
148 y2debug( "%s \"%s\": Selecting item \"%s\"",
150 debugLabel().c_str(),
151 item->label().c_str() );
154 item->setSelected( true );
157 YUI_THROW( YUIException( "Can't find selected item" ) );
161 void YQSelectionBox::deselectAllItems()
163 YSelectionBox::deselectAllItems();
164 _qt_listBox->clearSelection();
166 if ( _qt_listBox->currentRow() > -1 )
168 // Some item is selected after all; the Qt documtation says this
169 // happens if the QListBox is in single selection mode (which it is)
170 // and has the keyboard focus.
172 // Synchronize internal "selected" flags with what the QListBox
173 // displays. This has a small performance penalty because it calls
174 // YSelectionBox::deselectAllItems() again which again iterates over
176 selectItem( _qt_listBox->row(_qt_listBox->currentItem()) );
181 void YQSelectionBox::deleteAllItems()
183 YQSignalBlocker sigBlocker( _qt_listBox );
185 _qt_listBox->clear();
186 YSelectionBox::deleteAllItems();
191 int YQSelectionBox::preferredWidth()
193 int hintWidth = !_caption->isHidden() ?
194 _caption->sizeHint().width() + frameWidth() : 0;
196 return max( 80, hintWidth );
200 int YQSelectionBox::preferredHeight()
202 int hintHeight = !_caption->isHidden() ? _caption->sizeHint().height() : 0;
203 int visibleLines = shrinkable() ? SHRINKABLE_VISIBLE_LINES : DEFAULT_VISIBLE_LINES;
204 hintHeight += visibleLines * _qt_listBox->fontMetrics().lineSpacing();
205 hintHeight += _qt_listBox->frameWidth() * 2;
207 return max( 80, hintHeight );
211 void YQSelectionBox::setSize( int newWidth, int newHeight )
213 resize( newWidth, newHeight );
217 void YQSelectionBox::setEnabled( bool enabled )
219 _caption->setEnabled( enabled );
220 _qt_listBox->setEnabled( enabled );
221 //FIXME needed? _qt_listBox->triggerUpdate( true );
222 YWidget::setEnabled( enabled );
226 bool YQSelectionBox::setKeyboardFocus()
228 _qt_listBox->setFocus();
234 bool YQSelectionBox::eventFilter( QObject * obj, QEvent * ev )
236 if ( ev->type() == QEvent::KeyPress )
238 QKeyEvent * event = ( QKeyEvent * ) ev;
240 if ( ( event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter ) &&
241 ( (event->modifiers() & Qt::NoModifier) || (event->modifiers() & Qt::KeypadModifier) ) )
243 YQDialog * dia = (YQDialog *) findDialog();
247 ( void ) dia->activateDefaultButton();
252 else if ( ev->type() == QEvent::MouseButtonRelease )
254 QMouseEvent * mouseEvent = dynamic_cast<QMouseEvent *> (ev);
256 if ( mouseEvent && mouseEvent->button() == Qt::RightButton )
258 y2milestone( "Right click in selecton box detected" );
259 YQUI::ui()->maybeLeftHandedUser();
263 return QWidget::eventFilter( obj, ev );
267 void YQSelectionBox::slotSelected( int index )
273 if ( immediateMode() )
277 if ( ! YQUI::ui()->eventsBlocked() )
279 // Delayed event delivery - only if events are to be delivered
282 // An event block that is in effect right now may or may not
283 // affect events after the timer delay is expired.
285 // This may create nasty side effects such as bug #32510: When
286 // an item is initially selected, that initial selection event
287 // gets through even though (!) events are blocked during
297 void YQSelectionBox::slotActivated( QListWidgetItem * qItem )
299 selectItem( _qt_listBox->row( qItem ) );
302 YQUI::ui()->sendEvent( new YWidgetEvent( this, YEvent::Activated ) );
306 void YQSelectionBox::returnImmediately()
308 if ( ! YQUI::ui()->eventPendingFor( this ) )
310 // Avoid overwriting a (more important) Activated event with a
311 // SelectionChanged event
313 y2debug( "sending selbox event" );
314 YQUI::ui()->sendEvent( new YWidgetEvent( this, YEvent::SelectionChanged ) );
319 void YQSelectionBox::returnDelayed()
321 y2debug( "Starting selbox timer" );
322 _timer.setSingleShot( true );
323 _timer.start( 250 ); // millisec
328 #include "YQSelectionBox.moc"