X-Git-Url: https://git.sven.stormbind.net/?a=blobdiff_plain;f=src%2Fbranchitem.cpp;fp=src%2Fbranchitem.cpp;h=91a71bef0a5bf9a2e92b9d830277923e4f6dbe99;hb=d483bd8e6523c23c6f1d8908a2e0611c2bc9ff4f;hp=0000000000000000000000000000000000000000;hpb=7dfa3fe589d1722d49681f42cdb0bf1e6efb5223;p=sven%2Fvym.git diff --git a/src/branchitem.cpp b/src/branchitem.cpp new file mode 100644 index 0000000..91a71be --- /dev/null +++ b/src/branchitem.cpp @@ -0,0 +1,574 @@ +#include "branchitem.h" + +#include "attributeitem.h" +#include "branchobj.h" +#include "task.h" +#include "taskmodel.h" +#include "vymmodel.h" +#include "xlink.h" +#include "xlinkitem.h" + +extern TaskModel *taskModel; + +//#include + +BranchItem::BranchItem(TreeItem *parent) + : MapItem(parent) +{ + //qDebug()<< "Constr. BranchItem this=" << this << "parent:" << parent; + + // Set type if parent is known yet + // if not, type is set in insertBranch or TreeItem::appendChild + if (parent == rootItem) + setType(MapCenter); + else + setType(Branch); + + scrolled = false; + tmpUnscrolled = false; + + includeImagesVer = false; + includeImagesHor = false; + includeChildren = false; + childrenLayout = BranchItem::AutoPositioning; + + lastSelectedBranchNum = 0; + lastSelectedBranchNumAlt = 0; + + task = NULL; +} + +BranchItem::~BranchItem() +{ + // qDebug()<< "Destr. BranchItem this="<deleteTask(task); +} + +void BranchItem::copy(BranchItem *other) // TODO lacks most of data... +{ + scrolled = other->scrolled; + tmpUnscrolled = other->tmpUnscrolled; +} + +BranchItem *BranchItem::parentBranch() { return (BranchItem *)parentItem; } + +void BranchItem::insertBranch(int pos, BranchItem *branch) +{ + if (pos < 0) + pos = 0; + if (pos > branchCounter) + pos = branchCounter; + childItems.insert(pos + branchOffset, branch); + branch->parentItem = this; + branch->rootItem = rootItem; + branch->setModel(model); + if (parentItem == rootItem) + setType(MapCenter); + else + setType(Branch); + + if (branchCounter == 0) + branchOffset = childItems.count() - 1; + branchCounter++; +} + +QString BranchItem::saveToDir(const QString &tmpdir, const QString &prefix, + const QPointF &offset, QList &tmpLinks) +{ + // Cloudy stuff can be hidden during exports + if (hidden) + return QString(); + + // Save uuid + QString idAttr = attribut("uuid", uuid.toString()); + + QString s, a; + + // Update of note is usually done while unselecting a branch + + QString scrolledAttr; + if (scrolled) + scrolledAttr = attribut("scrolled", "yes"); + else + scrolledAttr = ""; + + // save area, if not scrolled // not needed if HTML is rewritten... + // also we could check if _any_ of parents is scrolled + QString areaAttr; + if (mo && parentItem->isBranchLikeType() && + !((BranchItem *)parentItem)->isScrolled()) { + qreal x = mo->getAbsPos().x(); + qreal y = mo->getAbsPos().y(); + areaAttr = + attribut("x1", QString().setNum(x - offset.x())) + + attribut("y1", QString().setNum(y - offset.y())) + + attribut("x2", QString().setNum(x + mo->width() - offset.x())) + + attribut("y2", QString().setNum(y + mo->height() - offset.y())); + } + else + areaAttr = ""; + + QString elementName; + if (parentItem == rootItem) + elementName = "mapcenter"; + else + elementName = "branch"; + + // Free positioning of children + QString layoutAttr; + if (childrenLayout == BranchItem::FreePositioning) + layoutAttr += attribut("childrenFreePos", "true"); + + // Save rotation + QString rotAttr; + if (mo && mo->getRotation() != 0) + rotAttr = attribut("rotation", QString().setNum(mo->getRotation())); + + s = beginElement(elementName + getMapAttr() + getGeneralAttr() + + scrolledAttr + getIncludeImageAttr() + rotAttr + + layoutAttr + idAttr); + incIndent(); + + // save heading + s += heading.saveToDir(); + + // save note + if (!note.isEmpty()) + s += note.saveToDir(); + + // Save frame // not saved if there is no MO + if (mo) { + // Avoid saving NoFrame for objects other than MapCenter + if (depth() == 0 || ((OrnamentedObj *)mo)->getFrame()->getFrameType() != + FrameObj::NoFrame) + s += ((OrnamentedObj *)mo)->getFrame()->saveToDir(); + } + + // save names of flags set + s += standardFlags.saveState(); + s += userFlags.saveState(); + + // Save Images + for (int i = 0; i < imageCount(); ++i) + s += getImageNum(i)->saveToDir(tmpdir, prefix); + + // save attributes + for (int i = 0; i < attributeCount(); ++i) + s += getAttributeNum(i)->getDataXML(); + + // save task + if (task) + s += task->saveToDir(); + + // Save branches + int i = 0; + TreeItem *ti = getBranchNum(i); + while (ti) { + s += getBranchNum(i)->saveToDir(tmpdir, prefix, offset, tmpLinks); + i++; + ti = getBranchNum(i); + } + + // Mark Links for save + for (int i = 0; i < xlinkCount(); ++i) { + Link *l = getXLinkItemNum(i)->getLink(); + if (l && !tmpLinks.contains(l)) + tmpLinks.append(l); + } + decIndent(); + s += endElement(elementName); + return s; +} + +void BranchItem::updateVisibility() +{ + // Needed to hide relinked branch, if parent is scrolled + if (mo) { + if (hasScrolledParent(this) || hidden) + mo->setVisibility(false); + else + mo->setVisibility(true); + } +} + +void BranchItem::setHeadingColor(QColor color) +{ + TreeItem::setHeadingColor(color); + if (mo) + ((BranchObj *)mo)->setColor(color); +} + +void BranchItem::updateTaskFlag() +{ + systemFlags.deactivateGroup("system-tasks"); + if (task) { + QString s = "system-" + task->getIconString(); + systemFlags.activate(s); + model->emitDataChanged(this); + } + // else: During initialization the task is not yet attached to branch, + // so ignore it for now +} + +void BranchItem::setTask(Task *t) +{ + task = t; + updateTaskFlag(); +} + +Task *BranchItem::getTask() { return task; } + +void BranchItem::scroll() +{ + if (tmpUnscrolled) + resetTmpUnscroll(); + if (!scrolled) + toggleScroll(); +} +void BranchItem::unScroll() +{ + if (tmpUnscrolled) + resetTmpUnscroll(); + if (scrolled) + toggleScroll(); +} + +bool BranchItem::toggleScroll() +{ + // MapCenters are not scrollable + if (depth() == 0) + return false; + + BranchObj *bo; + if (scrolled) { + scrolled = false; + systemFlags.deactivate(QString("system-scrolledright")); + if (branchCounter > 0) + for (int i = 0; i < branchCounter; ++i) { + bo = (BranchObj *)(getBranchNum(i)->getMO()); + if (bo) + bo->setVisibility(true); // Recursively! + } + } + else { + scrolled = true; + systemFlags.activate(QString("system-scrolledright")); + if (branchCounter > 0) + for (int i = 0; i < branchCounter; ++i) { + bo = (BranchObj *)(getBranchNum(i)->getMO()); + if (bo) + bo->setVisibility(false); // Recursively! + } + } + return true; +} + +bool BranchItem::isScrolled() { return scrolled; } + +bool BranchItem::hasScrolledParent(BranchItem *start) +{ + // Calls parents recursivly to + // find out, if we are scrolled at all. + // But ignore myself, just look at parents. + + if (!start) + start = this; + + if (this != start && scrolled) + return true; + + BranchItem *bi = (BranchItem *)parentItem; + if (bi && bi != rootItem) + return bi->hasScrolledParent(start); + else + return false; +} + +bool BranchItem::tmpUnscroll(BranchItem *start) +{ + bool result = false; + + if (!start) + start = this; + + // Unscroll parent (recursivly) + BranchItem *pi = (BranchItem *)parentItem; + if (pi && pi->isBranchLikeType()) + result = pi->tmpUnscroll(start); + + // Unscroll myself + if (start != this && scrolled) { + tmpUnscrolled = true; + systemFlags.activate(QString("system-tmpUnscrolledRight")); + toggleScroll(); + model->emitDataChanged(this); + result = true; + } + return result; +} + +bool BranchItem::resetTmpUnscroll() +{ + bool result = false; + + // Unscroll parent (recursivly) + BranchItem *pi = (BranchItem *)parentItem; + if (pi && pi->isBranchLikeType()) + result = pi->resetTmpUnscroll(); + + // Unscroll myself + if (tmpUnscrolled) { + tmpUnscrolled = false; + systemFlags.deactivate(QString("system-tmpUnscrolledRight")); + toggleScroll(); + model->emitDataChanged(this); + result = true; + } + return result; +} + +void BranchItem::sortChildren( + bool inverse) // FIXME-4 optimize by not using moveUp/Down +{ + int childCount = branchCounter; + int curChildIndex; + bool madeChanges = false; + do { + madeChanges = false; + for (curChildIndex = 1; curChildIndex < childCount; curChildIndex++) { + BranchItem *curChild = getBranchNum(curChildIndex); + BranchItem *prevChild = getBranchNum(curChildIndex - 1); + if (inverse) { + if (prevChild->getHeadingPlain().compare( + curChild->getHeadingPlain(), Qt::CaseInsensitive) < 0) { + model->moveUp(curChild); + madeChanges = true; + } + } + else if (prevChild->getHeadingPlain().compare( + curChild->getHeadingPlain(), Qt::CaseInsensitive) > + 0) { + model->moveUp(curChild); + madeChanges = true; + } + } + } while (madeChanges); +} + +void BranchItem::setChildrenLayout(BranchItem::LayoutHint layoutHint) +{ + childrenLayout = layoutHint; +} + +BranchItem::LayoutHint BranchItem::getChildrenLayout() +{ + return childrenLayout; +} + +void BranchItem::setIncludeImagesVer(bool b) { includeImagesVer = b; } + +bool BranchItem::getIncludeImagesVer() { return includeImagesVer; } + +void BranchItem::setIncludeImagesHor(bool b) { includeImagesHor = b; } + +bool BranchItem::getIncludeImagesHor() { return includeImagesHor; } + +QString BranchItem::getIncludeImageAttr() +{ + QString a; + if (includeImagesVer) + a = attribut("incImgV", "true"); + if (includeImagesHor) + a += attribut("incImgH", "true"); + return a; +} + +BranchItem *BranchItem::getFramedParentBranch(BranchItem *start) +{ + BranchObj *bo = getBranchObj(); + if (bo && bo->getFrameType() != FrameObj::NoFrame) { + if (bo->getFrame()->getFrameIncludeChildren()) + return this; + if (this == start) + return this; + } + BranchItem *bi = (BranchItem *)parentItem; + if (bi && bi != rootItem) + return bi->getFramedParentBranch(start); + else + return NULL; +} + +void BranchItem::setFrameIncludeChildren(bool b) +{ + includeChildren = b; // FIXME-4 ugly: same information stored in FrameObj + BranchObj *bo = getBranchObj(); + if (bo) + bo->getFrame()->setFrameIncludeChildren(b); +} + +bool BranchItem::getFrameIncludeChildren() +{ + BranchObj *bo = getBranchObj(); + if (bo) + return bo->getFrame()->getFrameIncludeChildren(); + else + return includeChildren; +} + +QColor BranchItem::getBackgroundColor(BranchItem *start, bool checkInnerFrame) +{ + /* + // Determine background color in taskEditor, first try inner frame + if (checkInnerFrame && branchContainer->frameType(true) != FrameContainer::NoFrame) + return branchContainer->frameBrushColor(true); + + // Outer frame + if (branchContainer->frameType(false) != FrameContainer::NoFrame) + return branchContainer->frameBrushColor(false); + + BranchItem *pb = parentBranch(); + if (pb && pb != rootItem) + // Recursively try parents and check for frames there + return pb->getBackgroundColor(start, false); + else + */ + BranchItem *bi = getFramedParentBranch(start); + if (bi) + return bi->getBranchObj()->getFrameBrushColor(); + + // No frame found + return model->getMapBackgroundColor(); +} + +void BranchItem::setLastSelectedBranch() +{ + int d = depth(); + if (d >= 0) { + if (d == 1) + // Hack to save an additional lastSelected for mapcenters in + // MapEditor depending on orientation this allows to go both left + // and right from there + if (mo && ((BranchObj *)mo)->getOrientation() == + LinkableMapObj::LeftOfCenter) { + ((BranchItem *)parentItem)->lastSelectedBranchNumAlt = + parentItem->num(this); + return; + } + ((BranchItem *)parentItem)->lastSelectedBranchNum = + parentItem->num(this); + } +} + +void BranchItem::setLastSelectedBranch(int i) { lastSelectedBranchNum = i; } + +BranchItem *BranchItem::getLastSelectedBranch() +{ + if (lastSelectedBranchNum >= branchCounter) + return getBranchNum(branchCounter - 1); + else + return getBranchNum(lastSelectedBranchNum); +} + +BranchItem *BranchItem::getLastSelectedBranchAlt() +{ + return getBranchNum(lastSelectedBranchNumAlt); +} + +TreeItem *BranchItem::findMapItem(QPointF p, TreeItem *excludeTI) +{ + // Search branches + TreeItem *ti; + for (int i = 0; i < branchCount(); ++i) { + ti = getBranchNum(i)->findMapItem(p, excludeTI); + if (ti != NULL) + return ti; + } + + // Search images + ImageItem *ii; + for (int i = 0; i < imageCount(); ++i) { + ii = getImageNum(i); + MapObj *mo = ii->getMO(); + if (mo && mo->isInClickBox(p) && (ii != excludeTI) && + this != excludeTI && mo->isVisibleObj()) + return ii; + } + + // Search myself + if (getBranchObj()->isInClickBox(p) && (this != excludeTI) && + getBranchObj()->isVisibleObj()) + return this; + + // Search attributes + AttributeItem *ai; + for (int i = 0; i < attributeCount(); ++i) { + ai = getAttributeNum(i); + MapObj *mo = ai->getMO(); + if (mo && mo->isInClickBox(p) && (ai != excludeTI) && + this != excludeTI && mo->isVisibleObj()) + return ai; + } + return NULL; +} + +void BranchItem::updateStyles(const bool &keepFrame) +{ + // Update styles when relinking branches + if (mo) { + BranchObj *bo = getBranchObj(); + if (parentItem != rootItem) + bo->setParObj((LinkableMapObj *)(((MapItem *)parentItem)->getMO())); + else + bo->setParObj(NULL); + bo->setDefAttr(BranchObj::MovedBranch, keepFrame); + } +} + +BranchObj *BranchItem::getBranchObj() { return (BranchObj *)mo; } + +BranchObj *BranchItem::createMapObj(QGraphicsScene *scene) +{ + BranchObj *newbo; + + if (parentItem == rootItem) { + newbo = new BranchObj(NULL, this); + mo = newbo; + scene->addItem(newbo); + } + else { + newbo = new BranchObj(((MapItem *)parentItem)->getMO(), this); + mo = newbo; + // Set visibility depending on parents + if (parentItem != rootItem && + (((BranchItem *)parentItem)->scrolled || + !((MapItem *)parentItem)->getLMO()->isVisibleObj())) + newbo->setVisibility(false); + if (depth() == 1) { + qreal r = 190; + qreal a = + -M_PI_4 + M_PI_2 * (num()) + (M_PI_4 / 2) * (num() / 4 % 4); + QPointF p(r * cos(a), r * sin(a)); + newbo->setRelPos(p); + } + } + newbo->setDefAttr(BranchObj::NewBranch); + initLMO(); + + if (!getHeading().isEmpty()) { + newbo->updateVisuals(); + newbo->setColor(heading.getColor()); + } + + return newbo; +}