1 /*---------------------------------------------------------------------\
3 | __ __ ____ _____ ____ |
4 | \ \ / /_ _/ ___|_ _|___ \ |
5 | \ V / _` \___ \ | | __) | |
6 | | | (_| |___) || | / __/ |
7 | |_|\__,_|____/ |_| |_____| |
11 \----------------------------------------------------------------------/
13 File: YQSelectionBox.cc
15 Author: Stefan Hundhammer <sh@suse.de>
22 #include <q3listbox.h>
23 #include <qnamespace.h>
29 #include <QVBoxLayout>
30 #define y2log_component "qt-ui"
31 #include <ycp/y2log.h>
38 #include "YQSelectionBox.h"
39 #include "YQSignalBlocker.h"
41 #include "YUIException.h"
42 #include "YQWidgetCaption.h"
44 #define VERBOSE_SELECTION 1
46 #define DEFAULT_VISIBLE_LINES 5
47 #define SHRINKABLE_VISIBLE_LINES 2
50 YQSelectionBox::YQSelectionBox( YWidget * parent, const string & label )
51 : QFrame( (QWidget *) parent->widgetRep() )
52 , YSelectionBox( parent, label )
56 QVBoxLayout* layout = new QVBoxLayout( this );
59 layout->setSpacing( YQWidgetSpacing );
60 layout->setMargin ( YQWidgetMargin );
62 _caption = new YQWidgetCaption( this, label );
63 YUI_CHECK_NEW( _caption );
64 layout->addWidget( _caption );
66 _qt_listBox = new Q3ListBox( this );
67 YUI_CHECK_NEW( _qt_listBox );
68 layout->addWidget( _qt_listBox );
70 _qt_listBox->installEventFilter( this );
71 _qt_listBox->setVariableHeight( false );
72 _qt_listBox->setSizePolicy( QSizePolicy( QSizePolicy::Expanding,
73 QSizePolicy::Expanding ) );
74 _qt_listBox->setTopItem(0);
75 _caption->setBuddy( _qt_listBox );
77 connect( _qt_listBox, SIGNAL( highlighted ( int ) ),
78 this, SLOT ( slotSelected( int ) ) );
80 connect( _qt_listBox, SIGNAL( doubleClicked( Q3ListBoxItem * ) ),
81 this, SLOT ( slotActivated( Q3ListBoxItem * ) ) );
83 connect( &_timer, SIGNAL( timeout() ),
84 this, SLOT ( returnImmediately() ) );
88 YQSelectionBox::~YQSelectionBox()
94 void YQSelectionBox::setLabel( const string & label )
96 _caption->setText( label );
97 YSelectionBox::setLabel( label );
101 void YQSelectionBox::addItem( YItem * item )
103 YSelectionBox::addItem( item );
106 if ( item->hasIconName() )
108 string iconName = iconFullPath( item );
109 icon = QPixmap( iconName.c_str() );
112 y2warning( "Can't load icon %s", iconName.c_str() );
116 _qt_listBox->insertItem( fromUTF8( item->label() ) );
118 _qt_listBox->insertItem( icon, fromUTF8( item->label() ) );
120 if ( item->selected() )
122 YQSignalBlocker sigBlocker( _qt_listBox );
123 _qt_listBox->setCurrentItem( item->index() );
128 void YQSelectionBox::selectItem( YItem * item, bool selected )
130 YQSignalBlocker sigBlocker( _qt_listBox );
132 YSelectionBox::selectItem( item, selected );
133 _qt_listBox->setCurrentItem( selected ? item->index() : -1 );
137 void YQSelectionBox::selectItem( int index )
139 YSelectionBox::deselectAllItems();
140 YItem * item = YSelectionBox::itemAt( index );
144 #ifdef VERBOSE_SELECTION
145 y2debug( "%s \"%s\": Selecting item \"%s\"",
147 debugLabel().c_str(),
148 item->label().c_str() );
151 item->setSelected( true );
154 YUI_THROW( YUIException( "Can't find selected item" ) );
158 void YQSelectionBox::deselectAllItems()
160 YSelectionBox::deselectAllItems();
161 _qt_listBox->clearSelection();
163 if ( _qt_listBox->currentItem() > -1 )
165 // Some item is selected after all; the Qt documtation says this
166 // happens if the QListBox is in single selection mode (which it is)
167 // and has the keyboard focus.
169 // Synchronize internal "selected" flags with what the QListBox
170 // displays. This has a small performance penalty because it calls
171 // YSelectionBox::deselectAllItems() again which again iterates over
173 selectItem( _qt_listBox->currentItem() );
178 void YQSelectionBox::deleteAllItems()
180 YQSignalBlocker sigBlocker( _qt_listBox );
182 _qt_listBox->clear();
183 YSelectionBox::deleteAllItems();
188 int YQSelectionBox::preferredWidth()
190 int hintWidth = _caption->isShown() ?
191 _caption->sizeHint().width() + frameWidth() : 0;
193 return max( 80, hintWidth );
197 int YQSelectionBox::preferredHeight()
199 int hintHeight = _caption->isShown() ? _caption->sizeHint().height() : 0;
200 int visibleLines = shrinkable() ? SHRINKABLE_VISIBLE_LINES : DEFAULT_VISIBLE_LINES;
201 hintHeight += visibleLines * _qt_listBox->fontMetrics().lineSpacing();
202 hintHeight += _qt_listBox->frameWidth() * 2;
204 return max( 80, hintHeight );
208 void YQSelectionBox::setSize( int newWidth, int newHeight )
210 resize( newWidth, newHeight );
214 void YQSelectionBox::setEnabled( bool enabled )
216 _caption->setEnabled( enabled );
217 _qt_listBox->setEnabled( enabled );
218 _qt_listBox->triggerUpdate( true );
219 YWidget::setEnabled( enabled );
223 bool YQSelectionBox::setKeyboardFocus()
225 _qt_listBox->setFocus();
231 bool YQSelectionBox::eventFilter( QObject * obj, QEvent * ev )
233 if ( ev->type() == QEvent::KeyPress )
235 QKeyEvent * event = ( QKeyEvent * ) ev;
237 if ( ( event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter ) &&
238 ( event->state() == 0 || event->state() == Qt::Keypad ) )
240 YQDialog * dia = (YQDialog *) findDialog();
244 ( void ) dia->activateDefaultButton();
249 else if ( ev->type() == QEvent::MouseButtonRelease )
251 QMouseEvent * mouseEvent = dynamic_cast<QMouseEvent *> (ev);
253 if ( mouseEvent && mouseEvent->button() == Qt::RightButton )
255 y2milestone( "Right click in selecton box detected" );
256 YQUI::ui()->maybeLeftHandedUser();
260 return QWidget::eventFilter( obj, ev );
264 void YQSelectionBox::slotSelected( int index )
270 if ( immediateMode() )
274 if ( ! YQUI::ui()->eventsBlocked() )
276 // Delayed event delivery - only if events are to be delivered
279 // An event block that is in effect right now may or may not
280 // affect events after the timer delay is expired.
282 // This may create nasty side effects such as bug #32510: When
283 // an item is initially selected, that initial selection event
284 // gets through even though (!) events are blocked during
294 void YQSelectionBox::slotActivated( Q3ListBoxItem * qItem )
296 selectItem( _qt_listBox->index( qItem ) );
299 YQUI::ui()->sendEvent( new YWidgetEvent( this, YEvent::Activated ) );
303 void YQSelectionBox::returnImmediately()
305 if ( ! YQUI::ui()->eventPendingFor( this ) )
307 // Avoid overwriting a (more important) Activated event with a
308 // SelectionChanged event
310 y2debug( "sending selbox event" );
311 YQUI::ui()->sendEvent( new YWidgetEvent( this, YEvent::SelectionChanged ) );
316 void YQSelectionBox::returnDelayed()
318 y2debug( "Starting selbox timer" );
319 _timer.start( 250, true ); // millisec, singleShot
324 #include "YQSelectionBox.moc"