1 /*---------------------------------------------------------------------\
3 | __ __ ____ _____ ____ |
4 | \ \ / /_ _/ ___|_ _|___ \ |
5 | \ V / _` \___ \ | | __) | |
6 | | | (_| |___) || | / __/ |
7 | |_|\__,_|____/ |_| |_____| |
11 \----------------------------------------------------------------------/
13 File: YQSelectionBox.cc
15 Author: Stefan Hundhammer <sh@suse.de>
23 #include <q3listbox.h>
24 #include <qnamespace.h>
30 #include <QVBoxLayout>
31 #define y2log_component "qt-ui"
32 #include <ycp/y2log.h>
39 #include "YQSelectionBox.h"
40 #include "YQSignalBlocker.h"
42 #include "YUIException.h"
43 #include "YQWidgetCaption.h"
45 #define VERBOSE_SELECTION 1
47 #define DEFAULT_VISIBLE_LINES 5
48 #define SHRINKABLE_VISIBLE_LINES 2
51 YQSelectionBox::YQSelectionBox( YWidget * parent, const string & label )
52 : QFrame( (QWidget *) parent->widgetRep() )
53 , YSelectionBox( parent, label )
57 QVBoxLayout* layout = new QVBoxLayout( this );
60 layout->setSpacing( YQWidgetSpacing );
61 layout->setMargin ( YQWidgetMargin );
63 _caption = new YQWidgetCaption( this, label );
64 YUI_CHECK_NEW( _caption );
65 layout->addWidget( _caption );
67 _qt_listBox = new Q3ListBox( this );
68 YUI_CHECK_NEW( _qt_listBox );
69 layout->addWidget( _qt_listBox );
71 _qt_listBox->installEventFilter( this );
72 _qt_listBox->setVariableHeight( false );
73 _qt_listBox->setSizePolicy( QSizePolicy( QSizePolicy::Expanding,
74 QSizePolicy::Expanding ) );
75 _qt_listBox->setTopItem(0);
76 _caption->setBuddy( _qt_listBox );
78 connect( _qt_listBox, SIGNAL( highlighted ( int ) ),
79 this, SLOT ( slotSelected( int ) ) );
81 connect( _qt_listBox, SIGNAL( doubleClicked( Q3ListBoxItem * ) ),
82 this, SLOT ( slotActivated( Q3ListBoxItem * ) ) );
84 connect( &_timer, SIGNAL( timeout() ),
85 this, SLOT ( returnImmediately() ) );
89 YQSelectionBox::~YQSelectionBox()
95 void YQSelectionBox::setLabel( const string & label )
97 _caption->setText( label );
98 YSelectionBox::setLabel( label );
102 void YQSelectionBox::addItem( YItem * item )
104 YSelectionBox::addItem( item );
107 if ( item->hasIconName() )
109 string iconName = iconFullPath( item );
110 icon = QPixmap( iconName.c_str() );
113 y2warning( "Can't load icon %s", iconName.c_str() );
117 _qt_listBox->insertItem( fromUTF8( item->label() ) );
119 _qt_listBox->insertItem( icon, fromUTF8( item->label() ) );
121 if ( item->selected() )
123 YQSignalBlocker sigBlocker( _qt_listBox );
124 _qt_listBox->setCurrentItem( item->index() );
129 void YQSelectionBox::selectItem( YItem * item, bool selected )
131 YQSignalBlocker sigBlocker( _qt_listBox );
133 YSelectionBox::selectItem( item, selected );
134 _qt_listBox->setCurrentItem( selected ? item->index() : -1 );
138 void YQSelectionBox::selectItem( int index )
140 YSelectionBox::deselectAllItems();
141 YItem * item = YSelectionBox::itemAt( index );
145 #ifdef VERBOSE_SELECTION
146 y2debug( "%s \"%s\": Selecting item \"%s\"",
148 debugLabel().c_str(),
149 item->label().c_str() );
152 item->setSelected( true );
155 YUI_THROW( YUIException( "Can't find selected item" ) );
159 void YQSelectionBox::deselectAllItems()
161 YSelectionBox::deselectAllItems();
162 _qt_listBox->clearSelection();
164 if ( _qt_listBox->currentItem() > -1 )
166 // Some item is selected after all; the Qt documtation says this
167 // happens if the QListBox is in single selection mode (which it is)
168 // and has the keyboard focus.
170 // Synchronize internal "selected" flags with what the QListBox
171 // displays. This has a small performance penalty because it calls
172 // YSelectionBox::deselectAllItems() again which again iterates over
174 selectItem( _qt_listBox->currentItem() );
179 void YQSelectionBox::deleteAllItems()
181 YQSignalBlocker sigBlocker( _qt_listBox );
183 _qt_listBox->clear();
184 YSelectionBox::deleteAllItems();
189 int YQSelectionBox::preferredWidth()
191 int hintWidth = !_caption->isHidden() ?
192 _caption->sizeHint().width() + frameWidth() : 0;
194 return max( 80, hintWidth );
198 int YQSelectionBox::preferredHeight()
200 int hintHeight = !_caption->isHidden() ? _caption->sizeHint().height() : 0;
201 int visibleLines = shrinkable() ? SHRINKABLE_VISIBLE_LINES : DEFAULT_VISIBLE_LINES;
202 hintHeight += visibleLines * _qt_listBox->fontMetrics().lineSpacing();
203 hintHeight += _qt_listBox->frameWidth() * 2;
205 return max( 80, hintHeight );
209 void YQSelectionBox::setSize( int newWidth, int newHeight )
211 resize( newWidth, newHeight );
215 void YQSelectionBox::setEnabled( bool enabled )
217 _caption->setEnabled( enabled );
218 _qt_listBox->setEnabled( enabled );
219 _qt_listBox->triggerUpdate( true );
220 YWidget::setEnabled( enabled );
224 bool YQSelectionBox::setKeyboardFocus()
226 _qt_listBox->setFocus();
232 bool YQSelectionBox::eventFilter( QObject * obj, QEvent * ev )
234 if ( ev->type() == QEvent::KeyPress )
236 QKeyEvent * event = ( QKeyEvent * ) ev;
238 if ( ( event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter ) &&
239 ( event->state() == 0 || event->state() == Qt::Keypad ) )
241 YQDialog * dia = (YQDialog *) findDialog();
245 ( void ) dia->activateDefaultButton();
250 else if ( ev->type() == QEvent::MouseButtonRelease )
252 QMouseEvent * mouseEvent = dynamic_cast<QMouseEvent *> (ev);
254 if ( mouseEvent && mouseEvent->button() == Qt::RightButton )
256 y2milestone( "Right click in selecton box detected" );
257 YQUI::ui()->maybeLeftHandedUser();
261 return QWidget::eventFilter( obj, ev );
265 void YQSelectionBox::slotSelected( int index )
271 if ( immediateMode() )
275 if ( ! YQUI::ui()->eventsBlocked() )
277 // Delayed event delivery - only if events are to be delivered
280 // An event block that is in effect right now may or may not
281 // affect events after the timer delay is expired.
283 // This may create nasty side effects such as bug #32510: When
284 // an item is initially selected, that initial selection event
285 // gets through even though (!) events are blocked during
295 void YQSelectionBox::slotActivated( Q3ListBoxItem * qItem )
297 selectItem( _qt_listBox->index( qItem ) );
300 YQUI::ui()->sendEvent( new YWidgetEvent( this, YEvent::Activated ) );
304 void YQSelectionBox::returnImmediately()
306 if ( ! YQUI::ui()->eventPendingFor( this ) )
308 // Avoid overwriting a (more important) Activated event with a
309 // SelectionChanged event
311 y2debug( "sending selbox event" );
312 YQUI::ui()->sendEvent( new YWidgetEvent( this, YEvent::SelectionChanged ) );
317 void YQSelectionBox::returnDelayed()
319 y2debug( "Starting selbox timer" );
320 _timer.setSingleShot( true );
321 _timer.start( 250 ); // millisec
326 #include "YQSelectionBox.moc"