1 /*---------------------------------------------------------------------\
3 | __ __ ____ _____ ____ |
4 | \ \ / /_ _/ ___|_ _|___ \ |
5 | \ V / _` \___ \ | | __) | |
6 | | | (_| |___) || | / __/ |
7 | |_|\__,_|____/ |_| |_____| |
11 \----------------------------------------------------------------------/
13 File: YQSelectionBox.cc
15 Author: Stefan Hundhammer <sh@suse.de>
23 #include <qnamespace.h>
24 #define y2log_component "qt-ui"
25 #include <ycp/y2log.h>
32 #include "YQSelectionBox.h"
33 #include "YQSignalBlocker.h"
35 #include "YUIException.h"
36 #include "YQWidgetCaption.h"
38 #define VERBOSE_SELECTION 1
40 #define DEFAULT_VISIBLE_LINES 5
41 #define SHRINKABLE_VISIBLE_LINES 2
44 YQSelectionBox::YQSelectionBox( YWidget * parent, const string & label )
45 : QVBox( (QWidget *) parent->widgetRep() )
46 , YSelectionBox( parent, label )
50 setSpacing( YQWidgetSpacing );
51 setMargin ( YQWidgetMargin );
53 _caption = new YQWidgetCaption( this, label );
54 YUI_CHECK_NEW( _caption );
56 _qt_listBox = new QListBox( this );
57 YUI_CHECK_NEW( _qt_listBox );
59 _qt_listBox->installEventFilter( this );
60 _qt_listBox->setVariableHeight( false );
61 _qt_listBox->setSizePolicy( QSizePolicy( QSizePolicy::Expanding,
62 QSizePolicy::Expanding ) );
63 _qt_listBox->setTopItem(0);
64 _caption->setBuddy( _qt_listBox );
66 connect( _qt_listBox, SIGNAL( highlighted ( int ) ),
67 this, SLOT ( slotSelected( int ) ) );
69 connect( _qt_listBox, SIGNAL( doubleClicked( QListBoxItem * ) ),
70 this, SLOT ( slotActivated( QListBoxItem * ) ) );
72 connect( &_timer, SIGNAL( timeout() ),
73 this, SLOT ( returnImmediately() ) );
77 YQSelectionBox::~YQSelectionBox()
83 void YQSelectionBox::setLabel( const string & label )
85 _caption->setText( label );
86 YSelectionBox::setLabel( label );
90 void YQSelectionBox::addItem( YItem * item )
92 YSelectionBox::addItem( item );
95 if ( item->hasIconName() )
97 string iconName = iconFullPath( item );
98 icon = QPixmap( iconName.c_str() );
101 y2warning( "Can't load icon %s", iconName.c_str() );
105 _qt_listBox->insertItem( fromUTF8( item->label() ) );
107 _qt_listBox->insertItem( icon, fromUTF8( item->label() ) );
109 if ( item->selected() )
111 YQSignalBlocker sigBlocker( _qt_listBox );
112 _qt_listBox->setCurrentItem( item->index() );
117 void YQSelectionBox::selectItem( YItem * item, bool selected )
119 YQSignalBlocker sigBlocker( _qt_listBox );
121 YSelectionBox::selectItem( item, selected );
122 _qt_listBox->setCurrentItem( selected ? item->index() : -1 );
126 void YQSelectionBox::selectItem( int index )
128 YSelectionBox::deselectAllItems();
129 YItem * item = YSelectionBox::itemAt( index );
133 #ifdef VERBOSE_SELECTION
134 y2debug( "%s \"%s\": Selecting item \"%s\"",
136 debugLabel().c_str(),
137 item->label().c_str() );
140 item->setSelected( true );
143 YUI_THROW( YUIException( "Can't find selected item" ) );
147 void YQSelectionBox::deselectAllItems()
149 YSelectionBox::deselectAllItems();
150 _qt_listBox->clearSelection();
152 if ( _qt_listBox->currentItem() > -1 )
154 // Some item is selected after all; the Qt documtation says this
155 // happens if the QListBox is in single selection mode (which it is)
156 // and has the keyboard focus.
158 // Synchronize internal "selected" flags with what the QListBox
159 // displays. This has a small performance penalty because it calls
160 // YSelectionBox::deselectAllItems() again which again iterates over
162 selectItem( _qt_listBox->currentItem() );
167 void YQSelectionBox::deleteAllItems()
169 YQSignalBlocker sigBlocker( _qt_listBox );
171 _qt_listBox->clear();
172 YSelectionBox::deleteAllItems();
177 int YQSelectionBox::preferredWidth()
179 int hintWidth = _caption->isShown() ?
180 _caption->sizeHint().width() + frameWidth() : 0;
182 return max( 80, hintWidth );
186 int YQSelectionBox::preferredHeight()
188 int hintHeight = _caption->isShown() ? _caption->sizeHint().height() : 0;
189 int visibleLines = shrinkable() ? SHRINKABLE_VISIBLE_LINES : DEFAULT_VISIBLE_LINES;
190 hintHeight += visibleLines * _qt_listBox->fontMetrics().lineSpacing();
191 hintHeight += _qt_listBox->frameWidth() * 2;
193 return max( 80, hintHeight );
197 void YQSelectionBox::setSize( int newWidth, int newHeight )
199 resize( newWidth, newHeight );
203 void YQSelectionBox::setEnabled( bool enabled )
205 _caption->setEnabled( enabled );
206 _qt_listBox->setEnabled( enabled );
207 _qt_listBox->triggerUpdate( true );
208 YWidget::setEnabled( enabled );
212 bool YQSelectionBox::setKeyboardFocus()
214 _qt_listBox->setFocus();
220 bool YQSelectionBox::eventFilter( QObject * obj, QEvent * ev )
222 if ( ev->type() == QEvent::KeyPress )
224 QKeyEvent * event = ( QKeyEvent * ) ev;
226 if ( ( event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter ) &&
227 ( event->state() == 0 || event->state() == Qt::Keypad ) )
229 YQDialog * dia = (YQDialog *) findDialog();
233 ( void ) dia->activateDefaultButton();
238 else if ( ev->type() == QEvent::MouseButtonRelease )
240 QMouseEvent * mouseEvent = dynamic_cast<QMouseEvent *> (ev);
242 if ( mouseEvent && mouseEvent->button() == Qt::RightButton )
244 y2milestone( "Right click in selecton box detected" );
245 YQUI::ui()->maybeLeftHandedUser();
249 return QWidget::eventFilter( obj, ev );
253 void YQSelectionBox::slotSelected( int index )
259 if ( immediateMode() )
263 if ( ! YQUI::ui()->eventsBlocked() )
265 // Delayed event delivery - only if events are to be delivered
268 // An event block that is in effect right now may or may not
269 // affect events after the timer delay is expired.
271 // This may create nasty side effects such as bug #32510: When
272 // an item is initially selected, that initial selection event
273 // gets through even though (!) events are blocked during
283 void YQSelectionBox::slotActivated( QListBoxItem * qItem )
285 selectItem( _qt_listBox->index( qItem ) );
288 YQUI::ui()->sendEvent( new YWidgetEvent( this, YEvent::Activated ) );
292 void YQSelectionBox::returnImmediately()
294 if ( ! YQUI::ui()->eventPendingFor( this ) )
296 // Avoid overwriting a (more important) Activated event with a
297 // SelectionChanged event
299 y2debug( "sending selbox event" );
300 YQUI::ui()->sendEvent( new YWidgetEvent( this, YEvent::SelectionChanged ) );
305 void YQSelectionBox::returnDelayed()
307 y2debug( "Starting selbox timer" );
308 _timer.start( 250, true ); // millisec, singleShot
313 #include "YQSelectionBox.moc"