]> icculus.org git repositories - duncan/yast2-qt4.git/blob - src/YQMultiSelectionBox.cc
remove so grep does not find it
[duncan/yast2-qt4.git] / src / YQMultiSelectionBox.cc
1 /*---------------------------------------------------------------------\
2 |                                                                      |
3 |                      __   __    ____ _____ ____                      |
4 |                      \ \ / /_ _/ ___|_   _|___ \                     |
5 |                       \ V / _` \___ \ | |   __) |                    |
6 |                        | | (_| |___) || |  / __/                     |
7 |                        |_|\__,_|____/ |_| |_____|                    |
8 |                                                                      |
9 |                               core system                            |
10 |                                                        (C) SuSE GmbH |
11 \----------------------------------------------------------------------/
12
13   File:       YQMultiSelectionBox.cc
14
15   Author:     Stefan Hundhammer <sh@suse.de>
16
17 /-*/
18
19 #include <limits.h>
20 #include <QString>
21 #include <QLabel>
22 #include <QVBoxLayout>
23 #include <QHeaderView>
24 #define y2log_component "qt-ui"
25 #include <ycp/y2log.h>
26
27 using std::max;
28
29 #include "utf8.h"
30 #include "YQUI.h"
31 #include "YEvent.h"
32 #include "YQMultiSelectionBox.h"
33 #include "YQSignalBlocker.h"
34 #include "YQWidgetCaption.h"
35
36 #define DEFAULT_VISIBLE_LINES           5
37 #define SHRINKABLE_VISIBLE_LINES        2
38
39
40 YQMultiSelectionBox::YQMultiSelectionBox( YWidget *             parent,
41                                           const string &        label )
42     : QFrame( (QWidget *) parent->widgetRep() )
43     , YMultiSelectionBox( parent, label )
44 {
45     QVBoxLayout* layout = new QVBoxLayout( this );
46     setLayout( layout );
47
48     setWidgetRep( this );
49
50     layout->setSpacing( YQWidgetSpacing );
51     layout->setMargin( YQWidgetMargin );
52
53     _caption = new YQWidgetCaption( this, label );
54     YUI_CHECK_NEW( _caption );
55     layout->addWidget( _caption );
56
57     _qt_listView = new QTreeWidget( this );
58     YUI_CHECK_NEW( _qt_listView );
59     layout->addWidget( _qt_listView );
60
61     _qt_listView->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
62     _qt_listView->setHeaderLabel("");   // QListView doesn't have one single column by default!
63     _qt_listView->sortItems( 0, Qt::AscendingOrder );
64     //FIXME _qt_listView->header()->setStretchEnabled( true );
65     _qt_listView->header()->hide();
66     _qt_listView->setRootIsDecorated ( false );
67     _caption->setBuddy( _qt_listView );
68
69     // Very small default size if specified
70
71     connect( _qt_listView,      SIGNAL( selectionChanged()      ),
72              this,              SLOT  ( slotSelected()          ) );
73
74     connect( this,              SIGNAL( valueChanged()          ),
75              this,              SLOT  ( slotValueChanged()      ) );
76 }
77
78
79 YQMultiSelectionBox::~YQMultiSelectionBox()
80 {
81     // NOP
82 }
83
84
85 void
86 YQMultiSelectionBox::setLabel( const string & label )
87 {
88     _caption->setText( label );
89     YMultiSelectionBox::setLabel( label );
90 }
91
92
93 void
94 YQMultiSelectionBox::addItem( YItem * yItem )
95 {
96     YQSignalBlocker sigBlocker( _qt_listView );
97     YMultiSelectionBox::addItem( yItem ); // will also check for NULL
98
99     YQMultiSelectionBoxItem * msbItem = new YQMultiSelectionBoxItem( this, _qt_listView, yItem );
100
101     YUI_CHECK_NEW( msbItem );
102
103     // Take care of the item's check box
104
105     if ( yItem->selected() )
106       msbItem->setCheckState(0, Qt::Checked);
107
108
109     // Take care of the QListView's keyboard focus
110
111     if ( ! _qt_listView->currentItem() )
112       msbItem->setSelected(true);
113 }
114
115
116 void YQMultiSelectionBox::selectItem( YItem * yItem, bool selected )
117 {
118     YMultiSelectionBox::selectItem( yItem, selected );
119     YQMultiSelectionBoxItem * msbItem = findItem( yItem );
120
121     if ( msbItem )
122       msbItem->setCheckState( 1, selected ? Qt::Checked : Qt::Unchecked );
123 }
124
125
126 void
127 YQMultiSelectionBox::deselectAllItems()
128 {
129     YQSignalBlocker sigBlocker( _qt_listView );
130     YMultiSelectionBox::deselectAllItems();
131
132     QTreeWidgetItemIterator it( _qt_listView );
133
134     while ( *it )
135     {
136       YQMultiSelectionBoxItem * item = dynamic_cast<YQMultiSelectionBoxItem *> (*it);
137
138       if ( item )
139         item->setCheckState(0, Qt::Checked);
140
141       ++it;
142     }
143 }
144
145
146 void
147 YQMultiSelectionBox::deleteAllItems()
148 {
149     YQSignalBlocker sigBlocker( _qt_listView );
150
151     YMultiSelectionBox::deleteAllItems();
152     _qt_listView->clear();
153 }
154
155
156 YItem *
157 YQMultiSelectionBox::currentItem()
158 {
159     // QListView::currentItem() is very similar, but not exactly the same as
160     // QListView::selectedItem(), and it is NOT to be confused with an item's
161     // "selected" state in a YQMultiSelectionBox (the item's check box):
162     //
163     // QListView::currentItem() is the item that currently has the keyboard
164     // focus. By default, it is displayed with a faint dotted outline.
165     //
166     // QListView::selectedItem() is the item that is selected in the QListView
167     // widget. It is displayed in a very visible way with inverted colors
168     // (typically blue backround). If there is a selected item, it is also the
169     // current item. if there is no selected item, there might still be a
170     // current item, though.
171     //
172     // The Y(Q)MultiSelectionBox item's "selected" state is completely
173     // independent of all this: It only depends on the item's check
174     // box. QListView::selectedItem() and QListView::currentItem() are just
175     // mechanisms for keyboard navigation to show the user which item's check
176     // box will be toggled when he hits the space bar.
177     //
178     // For the purpose of this function, QListView::currentItem() is the
179     // minimum requirement.
180
181     QTreeWidgetItem * currentQItem = _qt_listView->currentItem();
182
183     if ( currentQItem )
184     {
185         YQMultiSelectionBoxItem * item = dynamic_cast<YQMultiSelectionBoxItem *> (currentQItem);
186
187         if ( item )
188             return item->yItem();
189     }
190
191     return 0;
192 }
193
194
195 void
196 YQMultiSelectionBox::setCurrentItem( YItem * yItem )
197 {
198     // See also explanations about QListView::currentItem() vs.
199     // QListView::selectedItem() above
200     //
201     // This function uses QListView::selectedItem() for better visibility.
202     // This implicitly also changes QListView::currentItem().
203
204     YQSignalBlocker sigBlocker( _qt_listView );
205
206     if ( ! yItem )
207     {
208         _qt_listView->clearSelection();
209     }
210     else
211     {
212         YQMultiSelectionBoxItem * msbItem = findItem( yItem );
213
214         if ( msbItem )
215             msbItem->setSelected(true);
216
217         // This does NOT change the item's check box!
218         // (see explanations in YQMultiSelectionBox::currentItem() avove)
219     }
220 }
221
222
223 void
224 YQMultiSelectionBox::setEnabled( bool enabled )
225 {
226     _caption->setEnabled( enabled );
227     _qt_listView->setEnabled( enabled );
228     //_qt_listView->triggerUpdate();
229     YWidget::setEnabled( enabled );
230 }
231
232
233 int YQMultiSelectionBox::preferredWidth()
234 {
235     int hintWidth = (!_caption->isHidden()) ?
236                      _caption->sizeHint().width() + frameWidth() : 0;
237
238     return max( 80, hintWidth );
239 }
240
241
242 int YQMultiSelectionBox::preferredHeight()
243 {
244     int hintHeight       = (!_caption->isHidden()) ? _caption->sizeHint().height() : 0;
245     int visibleLines     = shrinkable() ? SHRINKABLE_VISIBLE_LINES : DEFAULT_VISIBLE_LINES;
246     hintHeight          += visibleLines * _qt_listView->fontMetrics().lineSpacing();
247     hintHeight          += _qt_listView->frameWidth() * 2;
248
249     return max( 80, hintHeight );
250 }
251
252
253 void
254 YQMultiSelectionBox::setSize( int newWidth, int newHeight )
255 {
256     resize( newWidth, newHeight );
257 }
258
259
260 bool
261 YQMultiSelectionBox::setKeyboardFocus()
262 {
263     _qt_listView->setFocus();
264
265     return true;
266 }
267
268
269 void
270 YQMultiSelectionBox::slotSelected()
271 {
272     if ( notify() )
273     {
274         if ( ! YQUI::ui()->eventPendingFor( this ) )
275         {
276             // Avoid overwriting a (more important) ValueChanged event with a SelectionChanged event
277
278             YQUI::ui()->sendEvent( new YWidgetEvent( this, YEvent::SelectionChanged ) );
279         }
280     }
281 }
282
283
284 void
285 YQMultiSelectionBox::slotValueChanged()
286 {
287     if ( notify() )
288         YQUI::ui()->sendEvent( new YWidgetEvent( this, YEvent::ValueChanged ) );
289 }
290
291
292 void
293 YQMultiSelectionBox::sendValueChanged()
294 {
295     emit valueChanged();
296 }
297
298
299 YQMultiSelectionBoxItem *
300 YQMultiSelectionBox::findItem( YItem * wantedItem )
301 {
302     // FIXME: Don't search through all items, use the YItem::data() pointer instead
303     QTreeWidgetItemIterator it( _qt_listView );
304
305     while ( *it )
306     {
307         YQMultiSelectionBoxItem * item = dynamic_cast<YQMultiSelectionBoxItem *> (*it);
308
309         if ( item && item->yItem() == wantedItem )
310             return item;
311
312         ++it;
313     }
314
315     return 0;
316 }
317
318
319
320
321
322 int YQMultiSelectionBoxItem::_item_count = 0;
323
324
325
326 YQMultiSelectionBoxItem::YQMultiSelectionBoxItem( YQMultiSelectionBox * parent,
327                                                   QTreeWidget *                 listView,
328                                                   YItem *               yItem )
329     : QTreeWidgetItem( listView)
330     , _yItem( yItem )
331     , _multiSelectionBox( parent )
332 {
333     YUI_CHECK_PTR( yItem );
334     setFlags( Qt::ItemIsUserCheckable );
335     setCheckState( 0, Qt::Unchecked );
336     setText(0, fromUTF8( yItem->label() ));
337     setFlags(Qt::ItemIsUserCheckable);
338     _serial = _item_count++;
339 }
340
341 void
342 YQMultiSelectionBoxItem::stateChange( bool newState )
343 {
344     _yItem->setSelected( newState );
345     _multiSelectionBox->sendValueChanged();
346     //QTreeWidgetItem::stateChange( newState );
347     // FIXME checked or selected state?
348     QTreeWidgetItem::setCheckState( 0, newState ? Qt::Checked : Qt::Unchecked );
349 }
350
351
352 QString
353 YQMultiSelectionBoxItem::key( int, bool ) const
354 {
355     /*
356      * Return a sort key that depends on creation (i.e. insertion) order.
357      */
358
359     static QString sortKey;
360     sortKey.sprintf( "%010d", INT_MAX - _serial );
361
362     return sortKey;
363 }
364
365
366 #include "YQMultiSelectionBox.moc"