]> icculus.org git repositories - duncan/yast2-qt4.git/blob - src/YQTree.cc
compiles, YQMultiSelectionBoxItem looks like it should, same as YQTree
[duncan/yast2-qt4.git] / src / YQTree.cc
1 /*---------------------------------------------------------------------\
2 |                                                                      |
3 |                      __   __    ____ _____ ____                      |
4 |                      \ \ / /_ _/ ___|_   _|___ \                     |
5 |                       \ V / _` \___ \ | |   __) |                    |
6 |                        | | (_| |___) || |  / __/                     |
7 |                        |_|\__,_|____/ |_| |_____|                    |
8 |                                                                      |
9 |                               core system                            |
10 |                                                        (C) SuSE GmbH |
11 \----------------------------------------------------------------------/
12
13   File:       YQTree.cc
14
15   Author:     Stefan Hundhammer <sh@suse.de>
16
17 /-*/
18
19 //#define QT3_SUPPORT
20 #include <QColorGroup>
21 #include <QHeaderView>
22 #include <QLabel>
23 #include <QTreeWidget>
24 #include <QVBoxLayout>
25 #include <QString>
26 //Added by qt3to4:
27 #include <QPixmap>
28 #define y2log_component "qt-ui"
29 #include <ycp/y2log.h>
30
31 using std::min;
32 using std::max;
33
34 #include "YQUI.h"
35 #include "YEvent.h"
36 #include "utf8.h"
37 #include "YQTree.h"
38 #include "YTreeItem.h"
39 #include "YQSignalBlocker.h"
40 #include "YQWidgetCaption.h"
41
42 #define VERBOSE_TREE_ITEMS      0
43
44
45 YQTree::YQTree( YWidget * parent, const string & label )
46     : QFrame( (QWidget *) parent->widgetRep() )
47     , YTree( parent, label )
48 {
49     QVBoxLayout* layout = new QVBoxLayout( this );
50     setLayout( layout );
51
52     setWidgetRep( this );
53
54     layout->setSpacing( YQWidgetSpacing );
55     layout->setMargin ( YQWidgetMargin  );
56
57     _nextSerialNo = 0;
58
59     _caption     = new YQWidgetCaption( this, label );
60     YUI_CHECK_NEW( _caption );
61     layout->addWidget( _caption );
62
63     _qt_listView = new QTreeWidget( this );
64     YUI_CHECK_NEW( _qt_listView );
65     layout->addWidget( _qt_listView );
66
67      //_qt_listView->setHeaderLabel("");
68 //     _qt_listView->addColumn( "" );
69      _qt_listView->header()->hide();
70      // _qt_listView->setHeader(0L);
71      _qt_listView->setRootIsDecorated ( true );
72
73     _caption->setBuddy ( _qt_listView );
74
75     connect( _qt_listView,      SIGNAL( selectionChanged ( QTreeWidgetItem *    ) ),
76              this,              SLOT  ( slotSelected     ( QTreeWidgetItem *    ) ) );
77
78     connect( _qt_listView,      SIGNAL( spacePressed     ( QTreeWidgetItem *    ) ),
79              this,              SLOT  ( slotActivated    ( QTreeWidgetItem *    ) ) );
80
81     connect( _qt_listView,      SIGNAL( doubleClicked    ( QTreeWidgetItem *    ) ),
82              this,              SLOT  ( slotActivated    ( QTreeWidgetItem *    ) ) );
83 }
84
85
86 YQTree::~YQTree()
87 {
88     // NOP
89 }
90
91
92 void YQTree::setLabel( const string & label )
93 {
94     _caption->setText( label );
95     YTree::setLabel( label );
96 }
97
98
99 void YQTree::rebuildTree()
100 {
101     // y2debug( "Rebuilding tree" );
102
103     YQSignalBlocker sigBlocker( _qt_listView );
104     _qt_listView->clear();
105
106     buildDisplayTree( 0, itemsBegin(), itemsEnd() );
107 }
108
109
110 void YQTree::buildDisplayTree( YQTreeItem * parentItem, YItemIterator begin, YItemIterator end )
111 {
112     for ( YItemIterator it = begin; it < end; ++it )
113     {
114         YTreeItem * orig = dynamic_cast<YTreeItem *> (*it);
115         YUI_CHECK_PTR( orig );
116
117         YQTreeItem * clone;
118
119         if ( parentItem )
120             clone = new YQTreeItem( this, parentItem, orig, _nextSerialNo++ );
121         else
122             clone = new YQTreeItem( this, _qt_listView, orig, _nextSerialNo++ );
123
124         YUI_CHECK_NEW( clone );
125
126         if ( orig->hasChildren() )
127             buildDisplayTree( clone, orig->childrenBegin(), orig->childrenEnd() );
128     }
129 }
130
131
132 void YQTree::selectItem( YItem * yItem, bool selected )
133 {
134     YQSignalBlocker sigBlocker( _qt_listView );
135
136     YTreeItem * treeItem = dynamic_cast<YTreeItem *> (yItem);
137     YUI_CHECK_PTR( treeItem );
138
139     YQTreeItem * yqTreeItem = (YQTreeItem *) treeItem->data();
140     YUI_CHECK_PTR( yqTreeItem );
141
142     if ( ! selected && yqTreeItem == _qt_listView->currentItem() )
143     {
144         deselectAllItems();
145     }
146     else
147     {
148         yqTreeItem->setSelected( true );
149         openBranch( yqTreeItem );
150         YTree::selectItem( treeItem, selected );
151     }
152 }
153
154
155 void YQTree::selectItem( YQTreeItem * item )
156 {
157     if ( item )
158     {
159         YQSignalBlocker sigBlocker( _qt_listView );
160
161         item->setSelected( true );
162         openBranch( item );
163         YTree::selectItem( item->origItem(), true );
164
165         y2debug( "selected item: \"%s\"", item->origItem()->label().c_str() );
166     }
167 }
168
169
170 void YQTree::openBranch( QTreeWidgetItem * item )
171 {
172     while ( item )
173     {
174       item->setExpanded( true ); // Takes care of origItem()->setOpen()
175       item = item->parent();
176     }
177 }
178
179
180 void YQTree::deselectAllItems()
181 {
182     YQSignalBlocker sigBlocker( _qt_listView );
183
184     YTree::deselectAllItems();
185     _qt_listView->clearSelection();
186 }
187
188
189 void YQTree::deleteAllItems()
190 {
191     YQSignalBlocker sigBlocker( _qt_listView );
192
193     _qt_listView->clear();
194     YTree::deleteAllItems();
195 }
196
197
198 void YQTree::slotSelected( QTreeWidgetItem * qItem )
199 {
200     selectItem( dynamic_cast<YQTreeItem *> (qItem) );
201
202     if ( notify() && ! YQUI::ui()->eventPendingFor( this ) )
203         YQUI::ui()->sendEvent( new YWidgetEvent( this, YEvent::SelectionChanged ) );
204 }
205
206
207 void YQTree::slotActivated( QTreeWidgetItem * qItem )
208 {
209     selectItem( dynamic_cast<YQTreeItem *> (qItem) );
210
211     if ( notify() )
212         YQUI::ui()->sendEvent( new YWidgetEvent( this, YEvent::Activated ) );
213 }
214
215
216 int YQTree::preferredWidth()
217 {
218     int hintWidth = !_caption->isHidden() ? _caption->sizeHint().width() : 0;
219     return max( 200, hintWidth );
220 }
221
222
223 int YQTree::preferredHeight()
224 {
225     // 300 is an arbitrary value.  Use a MinSize or MinHeight widget to set a
226     // size that is useful for the application.
227
228     int hintHeight = !_caption->isHidden() ? _caption->sizeHint().height() : 0;
229
230     return 300 + hintHeight;
231 }
232
233
234 void YQTree::setSize( int newWidth, int newHeight )
235 {
236     resize( newWidth, newHeight );
237 }
238
239
240 void YQTree::setEnabled( bool enabled )
241 {
242     _caption->setEnabled( enabled );
243     _qt_listView->setEnabled( enabled );
244     YWidget::setEnabled( enabled );
245 }
246
247
248 bool YQTree::setKeyboardFocus()
249 {
250     _qt_listView->setFocus();
251
252     return true;
253 }
254
255
256 /*============================================================================*/
257
258
259
260 YQTreeItem::YQTreeItem( YQTree  *       tree,
261                         QTreeWidget *   listView,
262                         YTreeItem *     orig,
263                         int             serial )
264     : QTreeWidgetItem( listView )
265 {
266     init( tree, orig, serial );
267
268 #if VERBOSE_TREE_ITEMS
269     y2debug( "Creating toplevel tree item \"%s\"", orig->label().c_str() );
270 #endif
271 }
272
273
274 YQTreeItem::YQTreeItem( YQTree  *       tree,
275                         YQTreeItem *    parentItem,
276                         YTreeItem *     orig,
277                         int             serial )
278     : QTreeWidgetItem( parentItem )
279 {
280     init( tree, orig, serial );
281 #if VERBOSE_TREE_ITEMS
282     y2debug( "Creating tree item \"%s\" as child of \"%s\"",
283              orig->label().c_str(),
284              parentItem->origItem()->label().c_str() );
285 #endif
286 }
287
288
289 void YQTreeItem::init( YQTree *         tree,
290                        YTreeItem *      orig,
291                        int              serial )
292 {
293     YUI_CHECK_PTR( tree );
294     YUI_CHECK_PTR( orig );
295
296     _tree       = tree;
297     _serialNo   = serial;
298     _origItem   = orig;
299
300     _origItem->setData( this );
301
302     setText( 0, fromUTF8 ( _origItem->label() ) );
303     setOpen( _origItem->isOpen() );
304
305     if ( _origItem->hasIconName() )
306     {
307         string iconName = _tree->iconFullPath( _origItem );
308         QPixmap icon( iconName.c_str() );
309
310         if ( icon.isNull() )
311             y2warning( "Can't load icon %s", iconName.c_str() );
312         else
313             setData( 0, Qt::DecorationRole, icon );
314     }
315 }
316
317
318 void
319 YQTreeItem::setOpen( bool open )
320 {
321     QTreeWidgetItem::setExpanded( open );
322     _origItem->setOpen( open );
323 }
324
325
326
327 QString
328 YQTreeItem::key( int column, bool ascending ) const
329 {
330     /*
331      * Sorting key for QListView internal sorting:
332      *
333      * Always sort tree items by insertion order. The tree widget
334      * cannot maintain a meaningful sorting order of its own: All it
335      * could do is sort by names (ASCII sort). Better let the (YCP)
336      * application handle this.
337      */
338
339     QString strKey;
340     strKey.sprintf( "%08d", _serialNo );
341
342     return strKey;
343 }
344
345
346 #include "YQTree.moc"