00001 #include <iostream>
00002 using namespace std;
00003
00004 #include "generictree.h"
00005
00006 class SortableGenericTreeList : public QPtrList<GenericTree>
00007 {
00008 public:
00009 void SetSortType(int stype) { sort_type = stype; }
00010 void SetOrderingIndex(int oindex)
00011 { ordering_index = (oindex >= 0) ? oindex : 0; }
00012
00013 int compareItems(QPtrCollection::Item item1, QPtrCollection::Item item2)
00014 {
00015 GenericTree *one = (GenericTree *)item1;
00016 GenericTree *two = (GenericTree *)item2;
00017
00018 if (sort_type == 0)
00019 {
00020 int onea = one->getAttribute(ordering_index);
00021 int twoa = two->getAttribute(ordering_index);
00022
00023 if (onea == twoa)
00024 return 0;
00025 else if (onea < twoa)
00026 return -1;
00027 else
00028 return 1;
00029 }
00030 else if (sort_type == 1)
00031 {
00032 QString ones = one->getString().lower();
00033 QString twos = two->getString().lower();
00034 return QString::localeAwareCompare(ones, twos);
00035 }
00036 else if (sort_type == 2)
00037 {
00038 bool onesel = one->isSelectable();
00039 bool twosel = two->isSelectable();
00040
00041 if (onesel == twosel)
00042 return 0;
00043 else if (onesel && !twosel)
00044 return 1;
00045 else
00046 return -1;
00047 }
00048 if (sort_type == 3)
00049 {
00050
00051
00052
00053
00054
00055 int onea = one->getAttribute(ordering_index);
00056 int twoa = two->getAttribute(ordering_index);
00057
00058 if (onea == twoa)
00059 {
00060 QString ones = one->getString().lower();
00061 QString twos = two->getString().lower();
00062 return QString::localeAwareCompare(ones, twos);
00063 }
00064 else if (onea < twoa)
00065 return -1;
00066 else
00067 return 1;
00068 }
00069 else
00070 {
00071 cerr << "generictree.o: SortableGenericTreeList was asked to "
00072 << "compare items (probably inside a sort()), but the "
00073 << "sort_type is not set to anything recognizable"
00074 << endl;
00075 return 0;
00076 }
00077 }
00078
00079 private:
00080 int sort_type;
00081
00082
00083
00084 int ordering_index;
00085 };
00086
00087 GenericTree::GenericTree(const QString &a_string, int an_int,
00088 bool selectable_flag)
00089 {
00090 m_subnodes = new SortableGenericTreeList;
00091 m_ordered_subnodes = new SortableGenericTreeList;
00092 m_flatened_subnodes = new SortableGenericTreeList;
00093
00094 m_subnodes->setAutoDelete(true);
00095
00096 m_parent = NULL;
00097 m_selected_subnode = NULL;
00098 m_current_ordering_index = -1;
00099
00100
00101 m_attributes = new IntVector(6);
00102
00103 m_string = a_string;
00104 m_int = an_int;
00105 m_selectable = selectable_flag;
00106 }
00107
00108 GenericTree::~GenericTree()
00109 {
00110 delete m_subnodes;
00111 delete m_ordered_subnodes;
00112 delete m_flatened_subnodes;
00113 delete m_attributes;
00114 }
00115
00116 GenericTree* GenericTree::addNode(const QString &a_string, int an_int,
00117 bool selectable_flag)
00118 {
00119 GenericTree *new_node = new GenericTree(a_string.stripWhiteSpace(),
00120 an_int, selectable_flag);
00121
00122 return addNode(new_node);
00123 }
00124
00125 GenericTree *GenericTree::addNode(GenericTree *child)
00126 {
00127 child->setParent(this);
00128 m_subnodes->append(child);
00129 m_ordered_subnodes->append(child);
00130
00131 return child;
00132 }
00133
00134 void GenericTree::removeNode(GenericTree *child)
00135 {
00136 if (m_selected_subnode == child)
00137 m_selected_subnode = NULL;
00138
00139 m_ordered_subnodes->removeRef(child);
00140 m_flatened_subnodes->removeRef(child);
00141 m_subnodes->removeRef(child);
00142 }
00143
00144 int GenericTree::calculateDepth(int start)
00145 {
00146 int current_depth;
00147 int found_depth;
00148 current_depth = start + 1;
00149 QPtrListIterator<GenericTree> it(*m_subnodes);
00150 GenericTree *child;
00151
00152 while ((child = it.current()) != 0)
00153 {
00154 found_depth = child->calculateDepth(start + 1);
00155 if (found_depth > current_depth)
00156 current_depth = found_depth;
00157 ++it;
00158 }
00159
00160 return current_depth;
00161 }
00162
00163 GenericTree* GenericTree::findLeaf(int ordering_index)
00164 {
00165 if (m_subnodes->count() > 0)
00166 {
00167 if (ordering_index == -1)
00168 return m_subnodes->getFirst()->findLeaf();
00169
00170 GenericTree *first_child = getChildAt(0, ordering_index);
00171
00172 return first_child->findLeaf(ordering_index);
00173 }
00174
00175 return this;
00176 }
00177
00178 GenericTree* GenericTree::findNode(QValueList<int> route_of_branches)
00179 {
00180
00181
00182
00183
00184
00185
00186
00187
00188 return recursiveNodeFinder(route_of_branches);
00189 }
00190
00191 GenericTree* GenericTree::recursiveNodeFinder(QValueList<int> route_of_branches)
00192 {
00193 if (checkNode(route_of_branches))
00194 return this;
00195 else
00196 {
00197 QPtrListIterator<GenericTree> it(*m_subnodes);
00198 GenericTree *child;
00199
00200 while ((child = it.current()) != 0)
00201 {
00202 GenericTree *sub_checker;
00203 sub_checker = child->recursiveNodeFinder(route_of_branches);
00204 if (sub_checker)
00205 return sub_checker;
00206 else
00207 ++it;
00208 }
00209 }
00210
00211 return NULL;
00212 }
00213
00214 bool GenericTree::checkNode(QValueList<int> route_of_branches)
00215 {
00216 bool found_it = true;
00217 GenericTree *parent_finder = this;
00218
00219
00220
00221 for (int i = route_of_branches.count() - 1; i > -1 && found_it; --i)
00222 {
00223 if (!(parent_finder->getInt() == (*route_of_branches.at(i))))
00224 found_it = false;
00225
00226 if (i > 0)
00227 {
00228 if (parent_finder->getParent())
00229 parent_finder = parent_finder->getParent();
00230 else
00231 found_it = false;
00232 }
00233 }
00234
00235 return found_it;
00236 }
00237
00238 int GenericTree::getChildPosition(GenericTree *child, int ordering_index)
00239 {
00240 if (ordering_index == -1)
00241 return m_subnodes->findRef(child);
00242
00243 if (m_current_ordering_index != ordering_index)
00244 {
00245 reorderSubnodes(ordering_index);
00246 m_current_ordering_index = ordering_index;
00247 }
00248
00249 return m_ordered_subnodes->findRef(child);
00250 }
00251
00252 int GenericTree::getPosition()
00253 {
00254 if (m_parent)
00255 return m_parent->getChildPosition(this);
00256 return 0;
00257 }
00258
00259 int GenericTree::getPosition(int ordering_index)
00260 {
00261 if (m_parent)
00262 return m_parent->getChildPosition(this, ordering_index);
00263 return 0;
00264 }
00265
00266 int GenericTree::childCount(void)
00267 {
00268 return m_subnodes->count();
00269 }
00270
00271 int GenericTree::siblingCount(void)
00272 {
00273 if (m_parent)
00274 return m_parent->childCount();
00275 return 1;
00276 }
00277
00278 QPtrList<GenericTree> *GenericTree::getAllChildren(int ordering_index)
00279 {
00280 if (ordering_index == -1)
00281 return m_subnodes;
00282
00283 return m_ordered_subnodes;
00284 }
00285
00286 GenericTree* GenericTree::getChildAt(uint reference, int ordering_index)
00287 {
00288 if (reference >= m_ordered_subnodes->count())
00289 {
00290
00291 return NULL;
00292 }
00293
00294 if (ordering_index == -1)
00295 return m_subnodes->at(reference);
00296
00297 if (ordering_index != m_current_ordering_index)
00298 {
00299 reorderSubnodes(ordering_index);
00300 m_current_ordering_index = ordering_index;
00301 }
00302
00303 return m_ordered_subnodes->at(reference);
00304 }
00305
00306 GenericTree* GenericTree::getSelectedChild(int ordering_index)
00307 {
00308 if (m_selected_subnode)
00309 return m_selected_subnode;
00310 return getChildAt(0, ordering_index);
00311 }
00312
00313 void GenericTree::becomeSelectedChild()
00314 {
00315 if (m_parent)
00316 m_parent->setSelectedChild(this);
00317 else
00318 cerr << "Top level can't become selected child\n";
00319 }
00320
00321 GenericTree* GenericTree::prevSibling(int number_up, int ordering_index)
00322 {
00323 if (!m_parent)
00324 {
00325
00326 return NULL;
00327 }
00328
00329 int position = m_parent->getChildPosition(this, ordering_index);
00330
00331 if (position < number_up)
00332 {
00333
00334 return NULL;
00335 }
00336
00337 return m_parent->getChildAt(position - number_up, ordering_index);
00338 }
00339
00340 GenericTree* GenericTree::nextSibling(int number_down, int ordering_index)
00341 {
00342 if (!m_parent)
00343 {
00344
00345 return NULL;
00346 }
00347
00348 int position = m_parent->getChildPosition(this, ordering_index);
00349
00350 if (position + number_down >= m_parent->childCount())
00351 {
00352
00353 return NULL;
00354 }
00355
00356 return m_parent->getChildAt(position + number_down, ordering_index);
00357 }
00358
00359 QPtrListIterator<GenericTree> GenericTree::getFirstChildIterator(int ordering)
00360 {
00361 if (ordering == -1)
00362 return QPtrListIterator<GenericTree>(*m_subnodes);
00363
00364 if (ordering != m_current_ordering_index)
00365 {
00366 reorderSubnodes(ordering);
00367 m_current_ordering_index = ordering;
00368 }
00369
00370 return QPtrListIterator<GenericTree>(*m_ordered_subnodes);
00371 }
00372
00373 GenericTree* GenericTree::getParent()
00374 {
00375 if (m_parent)
00376 return m_parent;
00377 return NULL;
00378 }
00379
00380 void GenericTree::setAttribute(uint attribute_position, int value_of_attribute)
00381 {
00382
00383
00384
00385
00386 if (m_attributes->size() < attribute_position + 1)
00387 m_attributes->resize(attribute_position + 1, -1);
00388 m_attributes->at(attribute_position) = value_of_attribute;
00389 }
00390
00391 int GenericTree::getAttribute(uint which_one)
00392 {
00393 if (m_attributes->size() < which_one + 1)
00394 {
00395 cerr << "asked a GenericTree node for a nonexistant attribute\n";
00396 return 0;
00397 }
00398
00399 return m_attributes->at(which_one);
00400 }
00401
00402 void GenericTree::reorderSubnodes(int ordering_index)
00403 {
00404
00405
00406
00407 m_ordered_subnodes->SetSortType(0);
00408 m_ordered_subnodes->SetOrderingIndex(ordering_index);
00409
00410 m_ordered_subnodes->sort();
00411 }
00412
00413 void GenericTree::addYourselfIfSelectable(QPtrList<GenericTree> *flat_list)
00414 {
00415 if (m_selectable)
00416 flat_list->append(this);
00417
00418 QPtrListIterator<GenericTree> it(*m_subnodes);
00419 GenericTree *child;
00420 while ((child = it.current()) != 0)
00421 {
00422 child->addYourselfIfSelectable(flat_list);
00423 ++it;
00424 }
00425 }
00426
00427 void GenericTree::buildFlatListOfSubnodes(int ordering_index,
00428 bool scrambled_parents)
00429 {
00430
00431
00432
00433 m_flatened_subnodes->clear();
00434
00435 QPtrListIterator<GenericTree> it(*m_subnodes);
00436 GenericTree *child;
00437 while ((child = it.current()) != 0)
00438 {
00439 child->addYourselfIfSelectable(m_flatened_subnodes);
00440 ++it;
00441 }
00442
00443 if (scrambled_parents)
00444 {
00445
00446 m_flatened_subnodes->SetSortType(0);
00447 m_flatened_subnodes->SetOrderingIndex(ordering_index);
00448 m_flatened_subnodes->sort();
00449 }
00450 }
00451
00452 GenericTree* GenericTree::nextPrevFromFlatList(bool forward_or_backward,
00453 bool wrap_around,
00454 GenericTree *active)
00455 {
00456 int i = m_flatened_subnodes->findRef(active);
00457 if (i < 0)
00458 {
00459 cerr << "Can't find active item on flatened list\n";
00460 return NULL;
00461 }
00462
00463 if (forward_or_backward)
00464 {
00465 ++i;
00466 if (i >= (int)m_flatened_subnodes->count())
00467 {
00468 if (wrap_around)
00469 i = 0;
00470 else
00471 return NULL;
00472 }
00473 }
00474 else
00475 {
00476 --i;
00477 if (i < 0)
00478 {
00479 if (wrap_around)
00480 i = m_flatened_subnodes->count() - 1;
00481 else
00482 return NULL;
00483 }
00484 }
00485
00486 return m_flatened_subnodes->at(i);
00487 }
00488
00489 GenericTree* GenericTree::getChildByName(const QString &a_name)
00490 {
00491 QPtrListIterator<GenericTree> it(*m_subnodes);
00492 GenericTree *child;
00493 while ((child = it.current()) != 0)
00494 {
00495 if (child->getString() == a_name)
00496 return child;
00497 ++it;
00498 }
00499 return NULL;
00500 }
00501
00502 GenericTree* GenericTree::getChildByInt(int an_int)
00503 {
00504 QPtrListIterator<GenericTree> it(*m_subnodes);
00505 GenericTree *child;
00506 while ((child = it.current()) != 0)
00507 {
00508 if (child->getInt() == an_int)
00509 return child;
00510 ++it;
00511 }
00512 return NULL;
00513 }
00514
00515
00516
00517 void GenericTree::sortByString()
00518 {
00519 m_ordered_subnodes->SetSortType(1);
00520 m_ordered_subnodes->sort();
00521
00522 QPtrListIterator<GenericTree> it(*m_subnodes);
00523 GenericTree *child;
00524 while ((child = it.current()) != 0)
00525 {
00526 child->sortByString();
00527 ++it;
00528 }
00529 }
00530
00531 void GenericTree::sortByAttributeThenByString(int which_attribute)
00532 {
00533 m_ordered_subnodes->SetSortType(3);
00534 m_ordered_subnodes->SetOrderingIndex(which_attribute);
00535 m_ordered_subnodes->sort();
00536
00537 QPtrListIterator<GenericTree> it(*m_subnodes);
00538 GenericTree *child;
00539 while ((child = it.current()) != 0)
00540 {
00541 child->sortByAttributeThenByString(which_attribute);
00542 ++it;
00543 }
00544 }
00545
00546 void GenericTree::sortBySelectable()
00547 {
00548 m_ordered_subnodes->SetSortType(2);
00549 m_ordered_subnodes->sort();
00550
00551 QPtrListIterator<GenericTree> it(*m_subnodes);
00552 GenericTree *child;
00553 while ((child = it.current()) != 0)
00554 {
00555 child->sortBySelectable();
00556 ++it;
00557 }
00558 }
00559
00560 void GenericTree::deleteAllChildren()
00561 {
00562 m_flatened_subnodes->clear();
00563 m_ordered_subnodes->clear();
00564 m_selected_subnode = NULL;
00565 m_current_ordering_index = -1;
00566 m_subnodes->clear();
00567 }
00568
00569 void GenericTree::pruneAllChildren()
00570 {
00571
00572
00573
00574
00575
00576
00577 m_subnodes->setAutoDelete(false);
00578 deleteAllChildren();
00579 m_subnodes->setAutoDelete(true);
00580 }
00581
00582 void GenericTree::reOrderAsSorted()
00583 {
00584
00585
00586
00587
00588
00589 if (m_subnodes->count() != m_ordered_subnodes->count())
00590 {
00591 cerr << "generictree.o: Can't reOrderAsSorted(), because the number "
00592 << "of subnodes is different than the number of ordered subnodes"
00593 << endl;
00594 return;
00595 }
00596
00597 m_subnodes->setAutoDelete(false);
00598 m_subnodes->clear();
00599 m_subnodes->setAutoDelete(true);
00600 m_current_ordering_index = -1;
00601
00602
00603 QPtrListIterator<GenericTree> it(*m_ordered_subnodes);
00604 GenericTree *child;
00605 while ((child = it.current()) != 0)
00606 {
00607 m_subnodes->append(child);
00608 child->reOrderAsSorted();
00609 ++it;
00610 }
00611 }
00612
00613 void GenericTree::MoveItemUpDown(GenericTree *item, bool flag)
00614 {
00615 if (item == m_subnodes->getFirst() && flag)
00616 return;
00617 if (item == m_subnodes->getLast() && !flag)
00618 return;
00619
00620 int num = m_subnodes->findRef(item);
00621
00622 int insertat = 0;
00623 if (flag)
00624 insertat = num - 1;
00625 else
00626 insertat = num + 1;
00627
00628 m_subnodes->take();
00629 m_subnodes->insert(insertat, item);
00630 }
00631