diff options
Diffstat (limited to 'src/keys/versetreekey.cpp')
-rw-r--r-- | src/keys/versetreekey.cpp | 238 |
1 files changed, 234 insertions, 4 deletions
diff --git a/src/keys/versetreekey.cpp b/src/keys/versetreekey.cpp index b73672d..edfbcc3 100644 --- a/src/keys/versetreekey.cpp +++ b/src/keys/versetreekey.cpp @@ -1,9 +1,27 @@ /****************************************************************************** * VerseTreeKey.cpp - code for class 'VerseTreeKey'- versekey using treekey * for data retrieval + * + * + * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org) + * CrossWire Bible Society + * P. O. Box 2528 + * Tempe, AZ 85280-2528 + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * */ + #include <versetreekey.h> +#include <ctype.h> SWORD_NAMESPACE_START @@ -20,7 +38,7 @@ SWClass VerseTreeKey::classdef(classes); VerseTreeKey::VerseTreeKey(TreeKey *treeKey, const SWKey *ikey) : VerseKey(ikey) { - this->treeKey = treeKey; + init(treeKey); if (ikey) parse(); } @@ -35,7 +53,7 @@ VerseTreeKey::VerseTreeKey(TreeKey *treeKey, const SWKey *ikey) : VerseKey(ikey) VerseTreeKey::VerseTreeKey(TreeKey *treeKey, const char *ikey) : VerseKey(ikey) { - this->treeKey = treeKey; + init(treeKey); if (ikey) parse(); } @@ -43,13 +61,22 @@ VerseTreeKey::VerseTreeKey(TreeKey *treeKey, const char *ikey) : VerseKey(ikey) VerseTreeKey::VerseTreeKey(VerseTreeKey const &k) : VerseKey(k) { - treeKey = k.treeKey; + init(k.treeKey); } VerseTreeKey::VerseTreeKey(TreeKey *treeKey, const char *min, const char *max) : VerseKey(min, max) { - this->treeKey = treeKey; + init(treeKey); +} + + +void VerseTreeKey::init(TreeKey *treeKey) +{ + myclass = &classdef; + this->treeKey = (TreeKey *)treeKey->clone(); + this->treeKey->setPositionChangeListener(this); + internalPosChange = false; } @@ -59,6 +86,33 @@ SWKey *VerseTreeKey::clone() const } +int VerseTreeKey::getBookAbbrev(const char *iabbr) +{ + int bookno = VerseKey::getBookAbbrev(iabbr); + if (bookno < 0) { +/* + vector<struct sbook>::iterator it = find(books, iabbr); + if (it == books.end()) { + TreeKey *tkey = this->treeKey; + int saveError = tkey->Error(); + long bookmark = tkey->getOffset(); + SWBuf segment; + internalPosChange = true; + do { + segment = (SWBuf)tkey->getLocalName(); + } while (tkey->parent()); + segment << 1; + if (saveError) { + error = saveError; + } + tkey->setOffset(bookmark); + } + books.push_back(sbook(iabbr)); +*/ + } + return bookno; +} + /****************************************************************************** * VerseTreeKey Destructor - cleans up instance of VerseTreeKey * @@ -66,7 +120,183 @@ SWKey *VerseTreeKey::clone() const */ VerseTreeKey::~VerseTreeKey() { + delete treeKey; +} + + +void VerseTreeKey::decrement(int steps) { + int treeError = 0; + if (!error) lastGoodOffset = getTreeKey()->getOffset(); + do { + treeKey->decrement(); + treeError = treeKey->Error(); + // iterate until 3 levels and no versekey parse errors + } while (!treeError && ((treeKey->getLevel() < 3) || error)); + if (error && !treeError) { + int saveError = error; + increment(); + error = saveError; + } + if (treeError) { + treeKey->setOffset(lastGoodOffset); + error = treeError; + } + if (_compare(UpperBound()) > 0) { + positionFrom(UpperBound()); + error = KEYERR_OUTOFBOUNDS; + } + if (_compare(LowerBound()) < 0) { + positionFrom(LowerBound()); + error = KEYERR_OUTOFBOUNDS; + } +} + + +void VerseTreeKey::increment(int steps) { + int treeError = 0; + if (!error) lastGoodOffset = getTreeKey()->getOffset(); + do { + treeKey->increment(); + treeError = treeKey->Error(); + // iterate until 3 levels and no versekey parse errors + } while (!treeError && ((treeKey->getLevel() < 3) || error)); + if (error && !treeError) { + int saveError = error; + decrement(); + error = saveError; + } + if (treeError) { + treeKey->setOffset(lastGoodOffset); + error = treeError; + } + // bounds + if (_compare(UpperBound()) > 0) { + positionFrom(UpperBound()); + error = KEYERR_OUTOFBOUNDS; + } + if (_compare(LowerBound()) < 0) { + positionFrom(LowerBound()); + error = KEYERR_OUTOFBOUNDS; + } } +void VerseTreeKey::positionChanged() { + if (!internalPosChange) { + TreeKey *tkey = this->TreeKey::PositionChangeListener::getTreeKey(); + int saveError = tkey->Error(); + long bookmark = tkey->getOffset(); + SWBuf seg[4]; + internalPosChange = true; + int legs = 0; + do { + seg[legs] = tkey->getLocalName(); + legs++; + } while (tkey->parent() && (legs < 4)); + + legs--; + + if ((legs < 2) && (!seg[0].length() || seg[0] == "/")) { //"[ Module Heading ]"; + testament = 0; + book = 0; + chapter = 0; + setVerse(0); + } + else if ((legs < 2) + && ((!strncmp(seg[0].c_str(), "[ Testament ", 12)) && //"[ Testament n Heading ]"; + (isdigit(seg[0][12])) && + (!strcmp(seg[0].c_str()+13, " Heading ]")))) { + testament = (seg[0][12]-48); + book = 0; + chapter = 0; + setVerse(0); + } //path = "[ Module Heading ]"; + else { + setBookName(seg[--legs]); + chapter = (legs > 0) ? atoi(seg[--legs]) : 0; + setVerse((legs > 0) ? atoi(seg[--legs]) : 0); + } + +// setText(path); + if (saveError) { + error = saveError; + } + tkey->setOffset(bookmark); + tkey->setError(saveError); + internalPosChange = false; + } +} + + +void VerseTreeKey::syncVerseToTree() { + internalPosChange = true; + SWBuf path; + if (!Testament()) path = "/"; // "[ Module Heading ]"; + else if (!Book()) path.setFormatted("/[ Testament %d Heading ]", Testament()); + else path.setFormatted("/%s/%d/%d", getOSISBookName(), getChapter(), getVerse()); + if (getSuffix()) path += getSuffix(); + long bookmark = treeKey->getOffset(); + treeKey->setText(path); + + // if our module has jacked inconsistencies, then let's put our tree back to where it was + if (treeKey->Error()) { + treeKey->setOffset(bookmark); + } + + internalPosChange = false; +} + + +TreeKey *VerseTreeKey::getTreeKey() { + syncVerseToTree(); + return treeKey; +} + +// can autonormalize yet (ever?) +void VerseTreeKey::Normalize(char autocheck) { + error = 0; +} + +long VerseTreeKey::NewIndex() const { + return treeKey->getOffset(); +} + + +void VerseTreeKey::setPosition(SW_POSITION p) { + + if (isBoundSet()) { + return VerseKey::setPosition(p); + } + + switch (p) { + case POS_TOP: + Error(); + treeKey->setPosition(p); + increment(); + decrement(); + Error(); + break; + case POS_BOTTOM: + Error(); + treeKey->setPosition(p); + decrement(); + increment(); + Error(); + break; + case POS_MAXVERSE: + case POS_MAXCHAPTER: + VerseKey::setPosition(p); + break; + } +} + + +/****************************************************************************** + * VerseTreeKey::copyFrom - Equates this VerseTreeKey to another VerseTreeKey + +void VerseTreeKey::copyFrom(const VerseTreeKey &ikey) { + VerseKey::copyFrom(ikey); +} + */ + SWORD_NAMESPACE_END |