00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef TREEITEM_H
00028 #define TREEITEM_H
00029
00030 #include <stdlib.h>
00031
00032 #include <cwidget/curses++.h>
00033 #include <cwidget/style.h>
00034
00035 #include "minibuf_win.h"
00036
00037 namespace cwidget
00038 {
00039 namespace widgets
00040 {
00041 class tree;
00042 class treeitem;
00043 class sortpolicy;
00044
00045 class tree_levelref
00046
00047
00048 {
00049 tree_levelref *parent;
00050 public:
00051 tree_levelref():parent(NULL) {}
00052 tree_levelref(const tree_levelref &x)
00053 :parent(x.parent?x.parent->clone():NULL) {}
00054 virtual ~tree_levelref() {}
00055
00056 virtual treeitem *get_item()=0;
00057 virtual void advance_next()=0;
00058 virtual void return_prev()=0;
00059
00060
00061 virtual bool is_begin()=0;
00062
00063
00064 virtual bool is_end()=0;
00065
00066
00067 virtual tree_levelref *clone() const=0;
00068
00069 friend class treeiterator;
00070 };
00071
00072 class tree_root_iterator:public tree_levelref
00073
00074
00075 {
00076 treeitem *val;
00077 treeitem *prevval;
00078
00079 treeitem *get_item() {return val;}
00080 public:
00081 tree_root_iterator(treeitem *_val):val(_val), prevval(NULL) {}
00082 tree_root_iterator(const tree_root_iterator &x):tree_levelref(x), val(x.val), prevval(x.prevval) {}
00083
00084 void advance_next() {if(val) { prevval=val; val=NULL;} }
00085 void return_prev() {if(prevval) {val=prevval; prevval=NULL;} }
00086
00087 tree_root_iterator *clone() const {return new tree_root_iterator(*this);}
00088
00089 bool is_end() {return !val;}
00090 bool is_begin() {return prevval==NULL;}
00091
00092
00093 tree_root_iterator *end()
00094 {
00095 tree_root_iterator *rval=new tree_root_iterator(*this);
00096 rval->advance_next();
00097 return rval;
00098 }
00099 };
00100
00101 class treeitem
00102
00103
00104
00105 {
00106 int depth;
00107 bool selectable;
00108 protected:
00109 virtual void set_depth(int _depth) {depth=_depth;}
00110 virtual void set_selectable(bool _selectable) {selectable=_selectable;}
00111 public:
00112 treeitem(bool _selectable=true):depth(0),selectable(_selectable) {}
00113
00126 virtual void paint(tree *win, int y, bool hierarchical,
00127 const style &st)=0;
00128
00138 void paint(tree *win, int y, bool hierarchical,
00139 const std::wstring &str, int depth_shift=2);
00140
00141 virtual const wchar_t *tag()=0;
00142
00143
00144 virtual const wchar_t *label()=0;
00145
00146
00147 int get_depth() {return depth;}
00148 bool get_selectable() {return selectable;}
00149
00150 virtual style get_normal_style() {return style();}
00151 virtual style get_highlight_style() {return get_normal_style()+style_attrs_flip(A_REVERSE);}
00152
00153 virtual void sort(sortpolicy &sort_method) {}
00154
00155
00156 virtual void sort() {}
00157
00158
00159
00169
00171 sigc::signal1<void, bool> highlighted_changed;
00172
00174
00175 virtual bool dispatch_key(const config::key &k, tree *owner) {return false;}
00176
00177
00178
00179
00180 virtual void dispatch_mouse(short id, int x, mmask_t bstate, tree *owner)
00181 {
00182 }
00183
00184
00185
00186 virtual tree_levelref *begin() {return NULL;}
00187 virtual tree_levelref *end() {return NULL;}
00188
00189
00190
00191 virtual bool has_visible_children() {return false;}
00192 virtual bool has_children() {return false;}
00193
00194 virtual bool matches(const std::wstring &s) const {return false;}
00195
00196
00197
00198 virtual void expand() {}
00199 virtual void expand_all() {}
00200 virtual void collapse_all() {}
00201
00202 template<class childtype, class sorter>
00203 friend class subtree;
00204
00205 virtual ~treeitem() {}
00206 };
00207
00208 class treeiterator
00209 {
00210 tree_levelref *curr;
00211 bool ignore_collapsed;
00212
00213 public:
00214 treeiterator(tree_levelref *_curr, bool _ignore_collapsed=false):curr(_curr),ignore_collapsed(_ignore_collapsed) {}
00215 treeiterator(const treeiterator &x):curr(x.curr?x.curr->clone():NULL),ignore_collapsed(x.ignore_collapsed) {}
00216 treeiterator(const treeiterator &x, bool _ignore_collapsed):curr(x.curr?x.curr->clone():NULL),ignore_collapsed(_ignore_collapsed) {}
00217
00218 bool is_root() {return curr->parent==NULL;}
00219
00220 treeiterator get_up()
00221 {
00222 return treeiterator(curr->parent->clone());
00223 }
00224
00225 void expand()
00226 {
00227 if(curr && curr->get_item())
00228 curr->get_item()->expand();
00229 }
00230
00231 treeitem &operator*() {return *curr->get_item();}
00232 const treeitem &operator*() const {return *curr->get_item();}
00233 treeitem *operator->() {return curr->get_item();}
00234 const treeitem *operator->() const {return curr->get_item();}
00235
00236 bool operator==(const treeiterator &x)
00237 {
00238 if(!curr)
00239 return !x.curr;
00240 else if(!x.curr)
00241 return false;
00242 else if(curr->is_end())
00243 return x.curr->is_end() && curr->parent == x.curr->parent;
00244 else if(x.curr->is_end())
00245 return false;
00246 else
00247 return curr->get_item()==x.curr->get_item();
00248 }
00249 bool operator!=(const treeiterator &x)
00250 {return !(*this==x);}
00251
00252 treeiterator &operator=(const treeiterator &x)
00253 {
00254 while(curr)
00255 {
00256 tree_levelref *old=curr;
00257 curr=curr->parent;
00258 delete old;
00259 }
00260
00261 curr=x.curr?x.curr->clone():NULL;
00262
00263 return *this;
00264 }
00265
00266 treeiterator &operator++()
00267 {
00268 if(curr->get_item() &&
00269 (ignore_collapsed?curr->get_item()->has_children():curr->get_item()->has_visible_children()))
00270 {
00271 tree_levelref *newref=curr->get_item()->begin();
00272 newref->parent=curr;
00273 curr=newref;
00274 }
00275 else
00276 {
00277 curr->advance_next();
00278
00279 while(curr->is_end() && curr->parent)
00280 {
00281 tree_levelref *old=curr;
00282 curr=curr->parent;
00283 curr->advance_next();
00284 delete old;
00285 }
00286 }
00287
00288 return *this;
00289 }
00290 treeiterator operator++(int)
00291 {
00292 treeiterator oldval(curr?curr->clone():NULL);
00293
00294 ++*this;
00295
00296 return oldval;
00297 }
00298
00299 treeiterator &operator--()
00300 {
00301 if(curr->is_begin())
00302 {
00303 if(curr->parent)
00304 {
00305 tree_levelref *old=curr;
00306 curr=curr->parent;
00307 delete old;
00308 }
00309 }
00310 else
00311 {
00312 curr->return_prev();
00313 while(curr->get_item() &&
00314 (ignore_collapsed?curr->get_item()->has_children():curr->get_item()->has_visible_children()))
00315 {
00316 tree_levelref *newref=curr->get_item()->end();
00317
00318 newref->parent=curr;
00319 newref->return_prev();
00320 curr=newref;
00321 }
00322 }
00323 return *this;
00324 }
00325
00326 treeiterator operator--(int)
00327 {
00328 treeiterator oldval(curr?curr->clone():NULL);
00329
00330 --*this;
00331
00332 return oldval;
00333 }
00334
00335 void move_forward_level()
00336 {
00337 if(!curr->is_end())
00338 {
00339 tree_levelref *old=curr->clone();
00340 curr->advance_next();
00341
00342 if(curr->is_end())
00343 {
00344 delete curr;
00345 curr=old;
00346 }
00347 else
00348 delete old;
00349 }
00350 }
00351
00352 void move_backward_level()
00353 {
00354 if(!curr->is_begin())
00355 curr->return_prev();
00356 }
00357
00358 ~treeiterator()
00359 {
00360 while(curr)
00361 {
00362 tree_levelref *old=curr;
00363 curr=curr->parent;
00364 delete old;
00365 }
00366 }
00367 };
00368
00369
00370
00371
00372 class sortpolicy
00373 {
00374 public:
00375 sortpolicy() {}
00376
00377 virtual bool operator()(treeitem *item1,
00378 treeitem *item2)=0;
00379
00380 virtual ~sortpolicy() {}
00381 };
00382
00383
00384
00385 class tag_sort_policy:public sortpolicy
00386 {
00387 public:
00388 bool operator()(treeitem *item1, treeitem *item2)
00389 {
00390 return (wcscmp(item1->tag(), item2->tag())<0);
00391 }
00392 };
00393
00394
00395
00396
00397
00398
00399 class sortpolicy_wrapper
00400 {
00401 sortpolicy &real_policy;
00402 public:
00403 sortpolicy_wrapper(sortpolicy &_real_policy):real_policy(_real_policy)
00404 {
00405 }
00406
00407 inline bool operator()(treeitem *item1,
00408 treeitem *item2) const
00409 {
00410 return real_policy(item1, item2);
00411 }
00412 };
00413 }
00414 }
00415
00416 #endif