libyui
|
00001 /************************************************************************** 00002 Copyright (C) 2000 - 2010 Novell, Inc. 00003 All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation; either version 2 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License along 00016 with this program; if not, write to the Free Software Foundation, Inc., 00017 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00018 00019 **************************************************************************/ 00020 00021 00022 00023 /*---------------------------------------------------------------------\ 00024 | | 00025 | __ __ ____ _____ ____ | 00026 | \ \ / /_ _/ ___|_ _|___ \ | 00027 | \ V / _` \___ \ | | __) | | 00028 | | | (_| |___) || | / __/ | 00029 | |_|\__,_|____/ |_| |_____| | 00030 | | 00031 | General Utilities | 00032 | (C) SuSE GmbH | 00033 \----------------------------------------------------------------------/ 00034 00035 File: TreeItem.h 00036 00037 Author: Stefan Hundhammer <sh@suse.de> 00038 00039 /-*/ 00040 00041 #ifndef TreeItem_h 00042 #define TreeItem_h 00043 00044 #include <string> 00045 00046 00047 00048 00056 template<class PAYLOAD> class TreeItem 00057 { 00058 public: 00059 00065 TreeItem<PAYLOAD> ( const PAYLOAD & val, 00066 TreeItem<PAYLOAD> * parent = 0 ) 00067 : _value( val ) 00068 , _parent( parent ) 00069 , _next(0) 00070 , _firstChild(0) 00071 { 00072 if ( _parent ) 00073 _parent->addChild( this ); 00074 } 00075 00076 00077 protected: 00078 00085 TreeItem<PAYLOAD> ( PAYLOAD val, 00086 bool autoAddChild, 00087 TreeItem<PAYLOAD> * parent = 0 ) 00088 : _value( val ) 00089 , _parent( parent ) 00090 , _next(0) 00091 , _firstChild(0) 00092 { 00093 if ( _parent && autoAddChild ) 00094 _parent->addChild( this ); 00095 } 00096 00097 00098 private: 00103 TreeItem<PAYLOAD> ( const TreeItem<PAYLOAD> & ) {} 00104 TreeItem<PAYLOAD> & operator= ( const TreeItem<PAYLOAD> & ) {} 00105 00106 00107 public: 00108 00113 virtual ~TreeItem<PAYLOAD> () 00114 { 00115 TreeItem<PAYLOAD> * child = firstChild(); 00116 00117 while ( child ) 00118 { 00119 TreeItem<PAYLOAD> * lastChild = child; 00120 child = child->next(); 00121 delete lastChild; 00122 } 00123 } 00124 00125 00129 const PAYLOAD & value() const { return _value; } 00130 00138 void setValue( PAYLOAD newValue ) { _value = newValue; } 00139 00143 TreeItem<PAYLOAD> * parent() const { return _parent; } 00144 00148 TreeItem<PAYLOAD> * next() const { return _next; } 00149 00153 TreeItem<PAYLOAD> * firstChild() const { return _firstChild; } 00154 00158 void setParent( TreeItem<PAYLOAD> * newParent ) { _parent = newParent; } 00159 00163 void setNext( TreeItem<PAYLOAD> * newNext ) { _next = newNext; } 00164 00168 void setFirstChild( TreeItem<PAYLOAD> * newFirstChild ) 00169 { _firstChild = newFirstChild; } 00170 00171 00181 void addChild( TreeItem<PAYLOAD> * newChild ) 00182 { 00183 if ( newChild ) 00184 { 00185 newChild->setNext( firstChild() ); 00186 setFirstChild( newChild ); 00187 } 00188 } 00189 00190 00191 protected: 00192 00193 PAYLOAD _value; 00194 TreeItem<PAYLOAD> * _parent; 00195 TreeItem<PAYLOAD> * _next; 00196 TreeItem<PAYLOAD> * _firstChild; 00197 }; 00198 00199 00200 00207 template<class PAYLOAD> class SortedTreeItem: public TreeItem<PAYLOAD> 00208 { 00209 public: 00210 00215 SortedTreeItem<PAYLOAD>( PAYLOAD val, 00216 SortedTreeItem<PAYLOAD> * parentItem = 0 ) 00217 : TreeItem<PAYLOAD> ( val, false, parentItem ) 00218 { 00219 if ( parentItem ) 00220 { 00221 // Hopefully we have a SortedTreeItem parent 00222 SortedTreeItem<PAYLOAD> * sortParent = 00223 dynamic_cast<SortedTreeItem<PAYLOAD> *> ( parentItem ); 00224 00225 if ( sortParent ) 00226 sortParent->insertChildSorted( this ); 00227 else // no SortedTreeItem parent - add unsorted 00228 parentItem->addChild( this ); 00229 } 00230 } 00231 00232 00236 virtual ~SortedTreeItem<PAYLOAD> () {} 00237 00238 00243 void insertChildSorted( SortedTreeItem<PAYLOAD> * newChild ) 00244 { 00245 if ( ! newChild ) 00246 return; 00247 00248 if ( ! firstChild() || 00249 newChild->value() < firstChild()->value() ) 00250 { 00251 // Insert as first child 00252 00253 newChild->setNext( firstChild() ); 00254 setFirstChild( newChild ); 00255 } 00256 else 00257 { 00258 // Search correct place to insert 00259 00260 TreeItem<PAYLOAD> * child = firstChild(); 00261 00262 while ( child->next() && 00263 child->next()->value() < newChild->value() ) 00264 { 00265 child = child->next(); 00266 } 00267 00268 00269 // Insert after 'child' 00270 00271 newChild->setNext( child->next() ); 00272 child->setNext( newChild ); 00273 } 00274 } 00275 00276 00280 SortedTreeItem<PAYLOAD> * parent() const 00281 { return ( SortedTreeItem<PAYLOAD> * ) TreeItem<PAYLOAD>::_parent; } 00282 00286 SortedTreeItem<PAYLOAD> * next() const 00287 { return ( SortedTreeItem<PAYLOAD> * ) TreeItem<PAYLOAD>::_next; } 00288 00292 SortedTreeItem<PAYLOAD> * firstChild() const 00293 { return ( SortedTreeItem<PAYLOAD> * ) TreeItem<PAYLOAD>::_firstChild; } 00294 00295 00296 private: 00297 00302 SortedTreeItem<PAYLOAD> ( const SortedTreeItem<PAYLOAD> & ) {} 00303 SortedTreeItem<PAYLOAD> & operator= ( const SortedTreeItem<PAYLOAD> & ) {} 00304 }; 00305 00306 00307 00312 template<class ITEM, class PAYLOAD> inline 00313 ITEM * 00314 findDirectChild( ITEM * item, PAYLOAD searchVal ) 00315 { 00316 TreeItem<PAYLOAD> * child = item->firstChild(); 00317 00318 while ( child ) 00319 { 00320 if ( child->value() == searchVal ) 00321 return dynamic_cast<ITEM *> ( child ); 00322 00323 child = child->next(); 00324 } 00325 00326 return 0; 00327 } 00328 00329 00330 00331 #endif // TreeItem_h