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