insilmaril@0: #include "branchobj.h" insilmaril@0: #include "texteditor.h" insilmaril@0: #include "mapeditor.h" insilmaril@0: #include "mainwindow.h" insilmaril@0: insilmaril@0: extern TextEditor *textEditor; insilmaril@0: extern Main *mainWindow; insilmaril@0: extern FlagRowObj *standardFlagsDefault; insilmaril@0: extern QAction *actionEditOpenURL; insilmaril@0: insilmaril@0: insilmaril@0: ///////////////////////////////////////////////////////////////// insilmaril@0: // BranchObj insilmaril@0: ///////////////////////////////////////////////////////////////// insilmaril@0: insilmaril@0: BranchObj* BranchObj::itLast=NULL; insilmaril@0: insilmaril@0: insilmaril@0: BranchObj::BranchObj () :OrnamentedObj() insilmaril@0: { insilmaril@0: // cout << "Const BranchObj ()\n"; insilmaril@0: setParObj (this); insilmaril@0: init(); insilmaril@0: depth=-1; insilmaril@0: } insilmaril@0: insilmaril@0: BranchObj::BranchObj (QCanvas* c):OrnamentedObj (c) insilmaril@0: { insilmaril@0: // cout << "Const BranchObj (c) called from MapCenterObj (c)\n"; insilmaril@83: parObj=NULL; insilmaril@0: canvas=c; insilmaril@0: } insilmaril@0: insilmaril@0: BranchObj::BranchObj (QCanvas* c, LinkableMapObj* p):OrnamentedObj (c) insilmaril@0: { insilmaril@0: // cout << "Const BranchObj (c,p)\n"; insilmaril@0: canvas=c; insilmaril@0: setParObj (p); insilmaril@0: depth=p->getDepth()+1; insilmaril@0: if (depth==1) insilmaril@0: // Calc angle to mapCenter if I am a mainbranch insilmaril@0: // needed for reordering the mainbranches clockwise insilmaril@0: // around mapcenter insilmaril@0: angle=getAngle (QPoint ((int)(x() - parObj->getChildPos().x() ), insilmaril@0: (int)(y() - parObj->getChildPos().y() ) ) ); insilmaril@0: init(); insilmaril@0: } insilmaril@0: insilmaril@0: BranchObj::~BranchObj () insilmaril@0: { insilmaril@83: // cout << "Destr BranchObj of "<getLastBranch(); insilmaril@0: if (!bo) po->unScroll(); insilmaril@0: } insilmaril@83: clear(); insilmaril@0: } insilmaril@0: insilmaril@0: bool BranchObj::operator< ( const BranchObj & other ) insilmaril@0: { insilmaril@0: return angle < other.angle; insilmaril@0: } insilmaril@0: insilmaril@0: bool BranchObj::operator== ( const BranchObj & other ) insilmaril@0: { insilmaril@0: return angle == other.angle; insilmaril@0: } insilmaril@0: insilmaril@0: int BranchObjPtrList::compareItems ( QPtrCollection::Item i, QPtrCollection::Item j) insilmaril@0: { insilmaril@0: // Make sure PtrList::find works insilmaril@0: if (i==j) return 0; insilmaril@0: insilmaril@0: if ( ((BranchObj*)(i))->angle > ((BranchObj*)(j))->angle ) insilmaril@0: return 1; insilmaril@0: else insilmaril@0: return -1; insilmaril@0: } insilmaril@0: insilmaril@0: void BranchObj::init () insilmaril@0: { insilmaril@83: branch.setAutoDelete (false); insilmaril@0: floatimage.setAutoDelete (true); insilmaril@83: link.setAutoDelete (false); insilmaril@0: insilmaril@83: if (parObj) insilmaril@83: { insilmaril@83: absPos=getRandPos(); insilmaril@83: absPos+=parObj->getChildPos(); insilmaril@83: } insilmaril@0: insilmaril@0: // TODO This should be done in TextObj later insilmaril@0: QFont font("Sans Serif,8,-1,5,50,0,0,0,0,0"); insilmaril@83: heading->setFont(font ); insilmaril@0: insilmaril@0: lastSelectedBranch=-1; insilmaril@0: insilmaril@0: setChildObj(this); insilmaril@0: insilmaril@0: scrolled=false; insilmaril@0: tmpUnscrolled=false; insilmaril@0: insilmaril@0: url=""; insilmaril@0: vymLink=""; insilmaril@0: } insilmaril@0: insilmaril@0: void BranchObj::copy (BranchObj* other) insilmaril@0: { insilmaril@0: OrnamentedObj::copy(other); insilmaril@0: insilmaril@0: branch.clear(); insilmaril@0: BranchObj* b; insilmaril@0: for (b=other->branch.first(); b;b=other->branch.next() ) insilmaril@0: // Make deep copy of b insilmaril@0: // Because addBranch again calls copy for the childs, insilmaril@0: // Those will get a deep copy, too insilmaril@0: addBranch(b); insilmaril@0: insilmaril@0: FloatImageObj *fi; insilmaril@0: for (fi=other->floatimage.first(); fi;fi=other->floatimage.next() ) insilmaril@0: addFloatImage (fi); insilmaril@0: insilmaril@0: scrolled=other->scrolled; insilmaril@0: tmpUnscrolled=other->tmpUnscrolled; insilmaril@0: setVisibility (other->visible); insilmaril@0: insilmaril@0: url=other->url; insilmaril@0: vymLink=other->vymLink; insilmaril@0: insilmaril@0: angle=other->angle; insilmaril@0: insilmaril@0: positionBBox(); insilmaril@0: } insilmaril@0: insilmaril@0: void BranchObj::clear() insilmaril@0: { insilmaril@0: floatimage.clear(); insilmaril@83: while (!link.isEmpty()) insilmaril@83: deleteLink (link.first() ); insilmaril@83: insilmaril@83: BranchObj *bo; insilmaril@83: while (!branch.isEmpty()) insilmaril@83: { insilmaril@83: bo=branch.first(); insilmaril@83: branch.removeFirst(); insilmaril@83: delete (bo); insilmaril@83: } insilmaril@0: } insilmaril@0: insilmaril@0: int BranchObj::getNum() insilmaril@0: { insilmaril@0: if (parObj) insilmaril@0: return ((BranchObj*)(parObj))->getNum ((BranchObj*)(this)); insilmaril@0: else insilmaril@0: return 0; insilmaril@0: } insilmaril@0: insilmaril@0: int BranchObj::getNum(BranchObj *bo) insilmaril@0: { insilmaril@0: return branch.findRef (bo); insilmaril@0: } insilmaril@0: insilmaril@0: int BranchObj::getFloatImageNum(FloatImageObj *fio) insilmaril@0: { insilmaril@0: return floatimage.findRef (fio); insilmaril@0: } insilmaril@0: insilmaril@0: int BranchObj::countBranches() insilmaril@0: { insilmaril@0: return branch.count(); insilmaril@0: } insilmaril@0: insilmaril@0: int BranchObj::countFloatImages() insilmaril@0: { insilmaril@0: return floatimage.count(); insilmaril@0: } insilmaril@0: insilmaril@89: int BranchObj::countLinks() insilmaril@89: { insilmaril@89: return link.count(); insilmaril@89: } insilmaril@89: insilmaril@0: void BranchObj::setParObjTmp(LinkableMapObj* lmo, QPoint m, int off) insilmaril@0: { insilmaril@0: // Temporary link to lmo insilmaril@0: // m is position of mouse pointer insilmaril@0: // offset 0: default 1: below lmo -1 above lmo (if possible) insilmaril@0: insilmaril@0: insilmaril@0: BranchObj* o=(BranchObj*)(lmo); insilmaril@0: if (!parObjTmpBuf) insilmaril@0: parObjTmpBuf=parObj; insilmaril@0: insilmaril@0: // ignore mapcenter and mainbranch insilmaril@0: if (lmo->getDepth()<2) off=0; insilmaril@0: if (off==0) insilmaril@0: { insilmaril@0: link2ParPos=false; insilmaril@93: // parObj=o; insilmaril@0: } insilmaril@0: else insilmaril@0: { insilmaril@0: link2ParPos=true; insilmaril@93: // if (off>0) insilmaril@93: // parObj=o->getParObj(); insilmaril@93: // else insilmaril@93: // parObj=o->getParObj(); insilmaril@93: // parObj=o; insilmaril@0: } insilmaril@93: parObj=o; insilmaril@0: insilmaril@0: depth=parObj->getDepth()+1; insilmaril@0: insilmaril@0: // setLinkStyle calls updateLink, only set it once insilmaril@0: if (style!=getDefLinkStyle() ) setLinkStyle (getDefLinkStyle()); insilmaril@0: insilmaril@0: // Move temporary to new position at destination insilmaril@0: // Usually the positioning would be done by reposition(), insilmaril@0: // but then also the destination branch would "Jump" around... insilmaril@0: // Better just do it approximately insilmaril@0: if (depth==1) insilmaril@0: { // new parent is the mapcenter itself insilmaril@0: insilmaril@0: QPoint p= normalise ( QPoint (m.x() - o->getChildPos().x(), insilmaril@0: m.y() - o->getChildPos().y() )); insilmaril@0: if (p.x()<0) p.setX( p.x()-bbox.width() ); insilmaril@0: move2RelPos (p); insilmaril@0: } else insilmaril@0: { insilmaril@0: int y; insilmaril@0: if (off==0) insilmaril@0: { insilmaril@0: // new parent is just a branch, link to it insilmaril@0: QRect t=o->getBBoxSizeWithChilds(); insilmaril@0: if (o->getLastBranch()) insilmaril@0: y=t.y() + t.height() ; insilmaril@0: else insilmaril@0: y=t.y(); insilmaril@0: insilmaril@0: } else insilmaril@0: { insilmaril@0: if (off<0) insilmaril@0: // we want to link above lmo insilmaril@0: y=o->y() - height() + 5; insilmaril@0: else insilmaril@0: // we want to link below lmo insilmaril@0: // Bottom of sel should be 5 pixels above insilmaril@0: // the bottom of the branch _below_ the target: insilmaril@0: // Don't try to find that branch, guess 12 pixels insilmaril@0: y=o->getChildPos().y() -height() + 12; insilmaril@0: } insilmaril@0: if (o->getOrientation()==OrientLeftOfCenter) insilmaril@0: move ( o->getChildPos().x() - linkwidth, y ); insilmaril@0: else insilmaril@0: move (o->getChildPos().x() + linkwidth, y ); insilmaril@0: } insilmaril@0: insilmaril@0: // updateLink is called implicitly in move insilmaril@0: reposition(); // FIXME shouldn't be this a request? insilmaril@0: } insilmaril@0: insilmaril@0: void BranchObj::unsetParObjTmp() insilmaril@0: { insilmaril@0: if (parObjTmpBuf) insilmaril@0: { insilmaril@0: link2ParPos=false; insilmaril@0: parObj=parObjTmpBuf; insilmaril@0: parObjTmpBuf=NULL; insilmaril@0: depth=parObj->getDepth()+1; insilmaril@0: setLinkStyle (getDefLinkStyle() ); insilmaril@93: updateLink(); insilmaril@0: } insilmaril@0: } insilmaril@0: insilmaril@0: void BranchObj::unScroll() insilmaril@0: { insilmaril@0: if (tmpUnscrolled) resetTmpUnscroll(); insilmaril@0: if (scrolled) toggleScroll(); insilmaril@0: } insilmaril@0: insilmaril@0: void BranchObj::toggleScroll() insilmaril@0: { insilmaril@0: BranchObj *bo; insilmaril@0: if (scrolled) insilmaril@0: { insilmaril@0: scrolled=false; insilmaril@0: systemFlags->deactivate("scrolledright"); insilmaril@0: for (bo=branch.first(); bo; bo=branch.next() ) insilmaril@0: { insilmaril@0: bo->setVisibility(true); insilmaril@0: } insilmaril@0: } else insilmaril@0: { insilmaril@0: scrolled=true; insilmaril@0: systemFlags->activate("scrolledright"); insilmaril@0: for (bo=branch.first(); bo; bo=branch.next() ) insilmaril@0: { insilmaril@0: bo->setVisibility(false); insilmaril@0: } insilmaril@0: } insilmaril@0: calcBBoxSize(); insilmaril@0: positionBBox(); insilmaril@0: move (absPos.x(), absPos.y() ); insilmaril@0: forceReposition(); insilmaril@0: } insilmaril@0: insilmaril@0: bool BranchObj::isScrolled() insilmaril@0: { insilmaril@0: return scrolled; insilmaril@0: } insilmaril@0: insilmaril@0: bool BranchObj::hasScrolledParent(BranchObj *start) insilmaril@0: { insilmaril@0: // Calls parents recursivly to insilmaril@0: // find out, if we are scrolled at all. insilmaril@0: // But ignore myself, just look at parents. insilmaril@0: insilmaril@0: if (this !=start && scrolled) return true; insilmaril@0: insilmaril@0: BranchObj* bo=(BranchObj*)(parObj); insilmaril@0: if (bo) insilmaril@0: return bo->hasScrolledParent(start); insilmaril@0: else insilmaril@0: return false; insilmaril@0: } insilmaril@0: insilmaril@0: void BranchObj::tmpUnscroll() insilmaril@0: { insilmaril@0: // Unscroll parent (recursivly) insilmaril@0: BranchObj* bo=(BranchObj*)(parObj); insilmaril@0: if (bo) bo->tmpUnscroll(); insilmaril@0: insilmaril@0: // Unscroll myself insilmaril@0: if (scrolled) insilmaril@0: { insilmaril@0: tmpUnscrolled=true; insilmaril@0: systemFlags->activate("tmpUnscrolledright"); insilmaril@0: toggleScroll(); insilmaril@0: } insilmaril@0: } insilmaril@0: insilmaril@0: void BranchObj::resetTmpUnscroll() insilmaril@0: { insilmaril@0: // Unscroll parent (recursivly) insilmaril@0: BranchObj* bo=(BranchObj*)(parObj); insilmaril@0: if (bo) insilmaril@0: bo->resetTmpUnscroll(); insilmaril@0: insilmaril@0: // Unscroll myself insilmaril@0: if (tmpUnscrolled) insilmaril@0: { insilmaril@0: tmpUnscrolled=false; insilmaril@0: systemFlags->deactivate("tmpUnscrolledright"); insilmaril@0: toggleScroll(); insilmaril@0: } insilmaril@0: } insilmaril@0: insilmaril@0: void BranchObj::setVisibility(bool v, int toDepth) insilmaril@0: { insilmaril@0: if (depth <= toDepth) insilmaril@0: { insilmaril@0: frame->setVisibility(v); insilmaril@0: heading->setVisibility(v); insilmaril@0: systemFlags->setVisibility(v); insilmaril@0: standardFlags->setVisibility(v); insilmaril@0: LinkableMapObj::setVisibility (v); insilmaril@0: insilmaril@0: if (!scrolled && (depth < toDepth)) insilmaril@0: { insilmaril@0: // Now go recursivly through all childs insilmaril@0: BranchObj* b; insilmaril@0: for (b=branch.first(); b;b=branch.next() ) insilmaril@0: b->setVisibility (v,toDepth); insilmaril@0: FloatImageObj *fio; insilmaril@0: for (fio=floatimage.first(); fio; fio=floatimage.next()) insilmaril@0: fio->setVisibility (v); insilmaril@0: } insilmaril@0: } // depth <= toDepth insilmaril@93: //FIXME move (absPos.x(), absPos.y() ); insilmaril@0: requestReposition(); insilmaril@0: } insilmaril@0: insilmaril@0: void BranchObj::setVisibility(bool v) insilmaril@0: { insilmaril@0: setVisibility (v,MAX_DEPTH); insilmaril@0: } insilmaril@0: insilmaril@0: insilmaril@0: void BranchObj::setLinkColor () insilmaril@0: { insilmaril@0: // Overloaded from LinkableMapObj insilmaril@0: // BranchObj can use color of heading insilmaril@0: insilmaril@0: if (mapEditor->getLinkColorHint()==HeadingColor) insilmaril@0: LinkableMapObj::setLinkColor (heading->getColor() ); insilmaril@0: else insilmaril@0: LinkableMapObj::setLinkColor (); insilmaril@0: } insilmaril@0: insilmaril@0: void BranchObj::setColor (QColor col, bool colorChilds) insilmaril@0: { insilmaril@0: heading->setColor(col); insilmaril@0: setLinkColor(); insilmaril@0: if (colorChilds) insilmaril@0: { insilmaril@0: BranchObj *bo; insilmaril@0: for (bo=branch.first(); bo; bo=branch.next() ) insilmaril@0: bo->setColor(col,colorChilds); insilmaril@0: } insilmaril@0: } insilmaril@0: insilmaril@0: insilmaril@0: BranchObj* BranchObj::first() insilmaril@0: { insilmaril@0: itLast=NULL; insilmaril@0: return this; insilmaril@0: } insilmaril@0: insilmaril@0: BranchObj* BranchObj::next() insilmaril@0: { insilmaril@0: BranchObj *lmo; insilmaril@0: BranchObj *bo=branch.first(); insilmaril@0: BranchObj *po=(BranchObj*)(parObj); insilmaril@0: insilmaril@0: if (!itLast) insilmaril@0: { // We are just beginning at the mapCenter insilmaril@0: if (bo) insilmaril@0: { insilmaril@0: itLast=this; insilmaril@0: return bo; insilmaril@0: } insilmaril@0: else insilmaril@0: { insilmaril@0: itLast=NULL; insilmaril@0: return NULL; insilmaril@0: } insilmaril@0: } insilmaril@0: insilmaril@0: if (itLast==parObj) insilmaril@0: { // We come from above insilmaril@0: if (bo) insilmaril@0: { insilmaril@0: // there are childs, go there insilmaril@0: itLast=this; insilmaril@0: return bo; insilmaril@0: } insilmaril@0: else insilmaril@0: { // no childs, try to go up again insilmaril@0: if (po) insilmaril@0: { insilmaril@0: // go up insilmaril@0: itLast=this; insilmaril@0: lmo=po->next(); insilmaril@0: itLast=this; insilmaril@0: return lmo; insilmaril@0: insilmaril@0: } insilmaril@0: else insilmaril@0: { insilmaril@0: // can't go up, I am mapCenter insilmaril@0: itLast=NULL; insilmaril@0: return NULL; insilmaril@0: } insilmaril@0: } insilmaril@0: } insilmaril@0: insilmaril@0: // Try to find last child, we came from, in my own childs insilmaril@0: bool searching=true; insilmaril@0: while (bo && searching) insilmaril@0: { insilmaril@0: if (itLast==bo) searching=false; insilmaril@0: bo=branch.next(); insilmaril@0: } insilmaril@0: if (!searching) insilmaril@0: { // found lastLMO in my childs insilmaril@0: if (bo) insilmaril@0: { insilmaril@0: // found a brother of lastLMO insilmaril@0: itLast=this; insilmaril@0: return bo; insilmaril@0: } insilmaril@0: else insilmaril@0: { insilmaril@0: if (po) insilmaril@0: { insilmaril@0: // go up insilmaril@0: itLast=this; insilmaril@0: lmo=po->next(); insilmaril@0: itLast=this; insilmaril@0: return lmo; insilmaril@0: } insilmaril@0: else insilmaril@0: { insilmaril@0: // can't go up, I am mapCenter insilmaril@0: itLast=NULL; insilmaril@0: return NULL; insilmaril@0: } insilmaril@0: } insilmaril@0: } insilmaril@0: insilmaril@0: // couldn't find last child, it must be a nephew of mine insilmaril@0: bo=branch.first(); insilmaril@0: if (bo) insilmaril@0: { insilmaril@0: // proceed with my first child insilmaril@0: itLast=this; insilmaril@0: return bo; insilmaril@0: } insilmaril@0: else insilmaril@0: { insilmaril@0: // or go back to my parents insilmaril@0: if (po) insilmaril@0: { insilmaril@0: // go up insilmaril@0: itLast=this; insilmaril@0: lmo=po->next(); insilmaril@0: itLast=this; insilmaril@0: return lmo; insilmaril@0: } insilmaril@0: else insilmaril@0: { insilmaril@0: // can't go up, I am mapCenter insilmaril@0: itLast=NULL; insilmaril@0: return NULL; insilmaril@0: } insilmaril@0: } insilmaril@0: } insilmaril@0: insilmaril@0: BranchObj* BranchObj::getLastIterator() insilmaril@0: { insilmaril@0: return itLast; insilmaril@0: } insilmaril@0: insilmaril@0: void BranchObj::setLastIterator(BranchObj* it) insilmaril@0: { insilmaril@0: itLast=it; insilmaril@0: } insilmaril@0: insilmaril@0: insilmaril@0: void BranchObj::move (double x, double y) insilmaril@0: { insilmaril@0: OrnamentedObj::move (x,y); insilmaril@0: positionBBox(); insilmaril@0: } insilmaril@0: insilmaril@0: void BranchObj::move (QPoint p) insilmaril@0: { insilmaril@0: move (p.x(), p.y()); insilmaril@0: } insilmaril@0: insilmaril@0: void BranchObj::moveBy (double x, double y) insilmaril@0: { insilmaril@0: OrnamentedObj::moveBy (x,y); insilmaril@0: positionBBox(); insilmaril@0: BranchObj* b; insilmaril@0: for (b=branch.first(); b;b=branch.next() ) insilmaril@0: b->moveBy (x,y); insilmaril@0: } insilmaril@83: insilmaril@0: void BranchObj::moveBy (QPoint p) insilmaril@0: { insilmaril@0: moveBy (p.x(), p.y()); insilmaril@0: } insilmaril@0: insilmaril@0: insilmaril@0: void BranchObj::positionBBox() insilmaril@0: { insilmaril@93: // FIXME testing (optimization) insilmaril@83: /* insilmaril@83: QString h=getHeading(); insilmaril@83: if (!h.isEmpty()) insilmaril@83: cout << "BO::positionBBox("<positionBBox(); insilmaril@0: systemFlags->positionBBox(); insilmaril@0: standardFlags->positionBBox(); insilmaril@0: // It seems that setting x,y also affects width,height insilmaril@0: int w_old=bbox.width(); insilmaril@0: int h_old=bbox.height(); insilmaril@0: bbox.setX (absPos.x() ); insilmaril@0: bbox.setY (absPos.y() ); insilmaril@0: bbox.setWidth(w_old); insilmaril@0: bbox.setHeight(h_old); insilmaril@83: insilmaril@0: setSelBox(); insilmaril@0: insilmaril@0: // set the frame insilmaril@0: frame->setRect(QRect(bbox.x(),bbox.y(),bbox.width(),bbox.height() ) ); insilmaril@83: insilmaril@83: // Update links to other branches insilmaril@83: LinkObj *l; insilmaril@83: for (l=link.first(); l; l=link.next() ) insilmaril@83: l->updateLink(); insilmaril@0: } insilmaril@0: insilmaril@0: void BranchObj::calcBBoxSize() insilmaril@0: { insilmaril@0: QSize heading_r=heading->getSize(); insilmaril@0: int heading_w=static_cast (heading_r.width() ); insilmaril@0: int heading_h=static_cast (heading_r.height() ); insilmaril@0: QSize sysflags_r=systemFlags->getSize(); insilmaril@0: int sysflags_h=sysflags_r.height(); insilmaril@0: int sysflags_w=sysflags_r.width(); insilmaril@0: QSize stanflags_r=standardFlags->getSize(); insilmaril@0: int stanflags_h=stanflags_r.height(); insilmaril@0: int stanflags_w=stanflags_r.width(); insilmaril@0: int w; insilmaril@0: int h; insilmaril@0: insilmaril@0: // set width to sum of all widths insilmaril@0: w=heading_w + sysflags_w + stanflags_w; insilmaril@0: // set height to maximum needed height insilmaril@0: h=max (sysflags_h,stanflags_h); insilmaril@0: h=max (h,heading_h); insilmaril@0: insilmaril@0: w+=frame->getBorder(); insilmaril@0: h+=frame->getBorder(); insilmaril@0: bbox.setSize (QSize (w,h)); insilmaril@0: } insilmaril@0: insilmaril@0: LinkableMapObj* BranchObj::findMapObj(QPoint p, LinkableMapObj* excludeLMO) insilmaril@0: { insilmaril@0: // Search branches insilmaril@0: BranchObj *b; insilmaril@0: LinkableMapObj *lmo; insilmaril@0: for (b=branch.first(); b; b=branch.next() ) insilmaril@0: { insilmaril@0: lmo=b->findMapObj(p, excludeLMO); insilmaril@0: if (lmo != NULL) return lmo; insilmaril@0: } insilmaril@0: insilmaril@0: // Search myself insilmaril@0: if (inBBox (p) && (this != excludeLMO) && isVisibleObj() ) insilmaril@0: return this; insilmaril@0: insilmaril@0: // Search float images insilmaril@0: FloatImageObj *foi; insilmaril@0: for (foi=floatimage.first(); foi; foi=floatimage.next() ) insilmaril@0: if (foi->inBBox(p) && (foi != excludeLMO) && foi->getParObj()!= excludeLMO) return foi; insilmaril@0: insilmaril@0: return NULL; insilmaril@0: } insilmaril@0: insilmaril@0: void BranchObj::setHeading(QString s) insilmaril@0: { insilmaril@0: // Adjusting font size insilmaril@0: QFont font=heading->getFont(); insilmaril@0: if (depth==0) insilmaril@0: font.setPointSize(16); insilmaril@0: else insilmaril@0: if (depth>1) insilmaril@0: font.setPointSize(10); insilmaril@0: else insilmaril@0: font.setPointSize(12); insilmaril@0: heading->setFont(font); insilmaril@0: heading->setText(s); // set new heading insilmaril@0: calcBBoxSize(); // recalculate bbox insilmaril@0: positionBBox(); // rearrange contents insilmaril@0: requestReposition(); insilmaril@0: } insilmaril@0: insilmaril@0: void BranchObj::setURL(QString s) insilmaril@0: { insilmaril@0: url=s; insilmaril@0: if (!url.isEmpty()) insilmaril@0: systemFlags->activate("url"); insilmaril@0: else insilmaril@0: systemFlags->deactivate("url"); insilmaril@0: calcBBoxSize(); // recalculate bbox insilmaril@0: positionBBox(); // rearrange contents insilmaril@0: forceReposition(); insilmaril@0: } insilmaril@0: insilmaril@0: QString BranchObj::getURL() insilmaril@0: { insilmaril@0: return url; insilmaril@0: } insilmaril@0: insilmaril@0: void BranchObj::setVymLink(QString s) insilmaril@0: { insilmaril@0: if (!s.isEmpty()) insilmaril@0: { insilmaril@0: // We need the relative (from loading) insilmaril@0: // or absolute path (from User event) insilmaril@0: // and build the absolute path. insilmaril@0: // Note: If we have relative, use path of insilmaril@0: // current map to build absolute path insilmaril@0: QDir d(s); insilmaril@0: if (!d.path().startsWith ("/")) insilmaril@0: { insilmaril@0: QString p=mapEditor->getDestPath(); insilmaril@0: int i=p.findRev("/",-1); insilmaril@0: d.setPath(p.left(i)+"/"+s); insilmaril@0: d.convertToAbs(); insilmaril@0: } insilmaril@0: vymLink=d.path(); insilmaril@0: systemFlags->activate("vymLink"); insilmaril@0: } insilmaril@0: else insilmaril@0: { insilmaril@0: systemFlags->deactivate("vymLink"); insilmaril@0: vymLink=""; insilmaril@0: } insilmaril@0: calcBBoxSize(); // recalculate bbox insilmaril@0: positionBBox(); // rearrange contents insilmaril@0: forceReposition(); insilmaril@0: } insilmaril@0: insilmaril@0: QString BranchObj::getVymLink() insilmaril@0: { insilmaril@0: return vymLink; insilmaril@0: } insilmaril@0: insilmaril@0: QString BranchObj::saveToDir (const QString &tmpdir,const QString &prefix, const QPoint& offset) insilmaril@0: { insilmaril@0: QString s,a; insilmaril@0: QString scrolledAttr; insilmaril@0: if (scrolled) insilmaril@0: scrolledAttr=attribut ("scrolled","yes"); insilmaril@0: else insilmaril@0: scrolledAttr=""; insilmaril@0: insilmaril@0: QString posAttr; insilmaril@0: if (depth<2) posAttr= insilmaril@0: attribut("absPosX",QString().setNum(absPos.x(),10)) + insilmaril@0: attribut("absPosY",QString().setNum(absPos.y(),10)); insilmaril@0: else insilmaril@0: posAttr=""; insilmaril@0: insilmaril@0: QString urlAttr; insilmaril@0: if (!url.isEmpty()) insilmaril@0: urlAttr=attribut ("url",url); insilmaril@0: insilmaril@0: QString vymLinkAttr; insilmaril@0: if (!vymLink.isEmpty()) insilmaril@0: vymLinkAttr=attribut ("vymLink",convertToRel(mapEditor->getDestPath(),vymLink) ); insilmaril@0: insilmaril@0: QString frameAttr; insilmaril@0: if (frame->getFrameType()!=NoFrame) insilmaril@0: frameAttr=attribut ("frameType",frame->getFrameTypeName()); insilmaril@0: else insilmaril@0: frameAttr=""; insilmaril@0: insilmaril@0: // save area, if not scrolled insilmaril@0: QString areaAttr; insilmaril@0: if (!((BranchObj*)(parObj))->isScrolled() ) insilmaril@0: { insilmaril@0: areaAttr= insilmaril@0: attribut("x1",QString().setNum(absPos.x()-offset.x(),10)) + insilmaril@0: attribut("y1",QString().setNum(absPos.y()-offset.y(),10)) + insilmaril@0: attribut("x2",QString().setNum(absPos.x()+width()-offset.x(),10)) + insilmaril@0: attribut("y2",QString().setNum(absPos.y()+height()-offset.y(),10)); insilmaril@0: insilmaril@0: } else insilmaril@0: areaAttr=""; insilmaril@0: insilmaril@93: s=beginElement ("branch" +scrolledAttr +posAttr +urlAttr +vymLinkAttr +frameAttr +areaAttr ); insilmaril@0: incIndent(); insilmaril@0: insilmaril@0: // save heading insilmaril@0: s=s+valueElement("heading", getHeading(), insilmaril@0: attribut ("textColor",QColor(heading->getColor()).name())); insilmaril@0: insilmaril@0: // save names of flags set insilmaril@0: s+=standardFlags->saveToDir(tmpdir,prefix,0); insilmaril@0: insilmaril@0: // save note insilmaril@0: if (!note.isEmpty() ) insilmaril@0: s+=note.saveToDir(); insilmaril@0: insilmaril@0: // Save branches insilmaril@0: BranchObj *bo; insilmaril@0: for (bo=branch.first(); bo; bo=branch.next() ) insilmaril@0: s+=bo->saveToDir(tmpdir,prefix,offset); insilmaril@0: decIndent(); insilmaril@0: insilmaril@0: // Save FloatImages insilmaril@0: FloatImageObj *fio; insilmaril@0: for (fio=floatimage.first(); fio; fio=floatimage.next() ) insilmaril@0: s+=fio->saveToDir (tmpdir,prefix); insilmaril@0: insilmaril@0: s+=endElement ("branch"); insilmaril@0: return s; insilmaril@0: } insilmaril@0: insilmaril@83: void BranchObj::addLink (LinkObj *lo) insilmaril@83: { insilmaril@83: link.append (lo); insilmaril@83: insilmaril@83: } insilmaril@83: insilmaril@83: void BranchObj::removeLink (LinkObj *lo) insilmaril@83: { insilmaril@83: link.remove (lo); insilmaril@83: } insilmaril@83: insilmaril@83: void BranchObj::deleteLink(LinkObj *lo) insilmaril@83: { insilmaril@83: lo->deactivate(); insilmaril@83: if (!lo->isUsed()) delete (lo); insilmaril@83: } insilmaril@83: insilmaril@83: int BranchObj::countLink() insilmaril@83: { insilmaril@83: return link.count(); insilmaril@83: } insilmaril@83: insilmaril@89: BranchObj* BranchObj::linkTargetAt (int i) insilmaril@89: { insilmaril@89: if (link.at(i)) insilmaril@89: return link.at(i)->otherBranch (this); insilmaril@89: else insilmaril@89: return NULL; insilmaril@89: } insilmaril@89: insilmaril@0: LinkableMapObj* BranchObj::addFloatImage () insilmaril@0: { insilmaril@0: FloatImageObj *newfi=new FloatImageObj (canvas,this); insilmaril@0: floatimage.append (newfi); insilmaril@0: if (hasScrolledParent(this) ) insilmaril@0: newfi->setVisibility (false); insilmaril@0: else insilmaril@0: newfi->setVisibility(visible); insilmaril@0: requestReposition(); insilmaril@0: return newfi; insilmaril@0: } insilmaril@0: insilmaril@0: LinkableMapObj* BranchObj::addFloatImage (FloatImageObj *fio) insilmaril@0: { insilmaril@0: FloatImageObj *newfi=new FloatImageObj (canvas,this); insilmaril@0: floatimage.append (newfi); insilmaril@0: newfi->copy (fio); insilmaril@0: if (hasScrolledParent(this) ) insilmaril@0: newfi->setVisibility (false); insilmaril@0: else insilmaril@0: newfi->setVisibility(visible); insilmaril@0: requestReposition(); insilmaril@0: return newfi; insilmaril@0: } insilmaril@0: insilmaril@0: FloatImageObj* BranchObj::getFirstFloatImage () insilmaril@0: { insilmaril@0: return floatimage.first(); insilmaril@0: } insilmaril@0: insilmaril@0: FloatImageObj* BranchObj::getLastFloatImage () insilmaril@0: { insilmaril@0: return floatimage.last(); insilmaril@0: } insilmaril@0: insilmaril@0: FloatImageObj* BranchObj::getFloatImageNum (const uint &i) insilmaril@0: { insilmaril@0: return floatimage.at(i); insilmaril@0: } insilmaril@0: insilmaril@0: void BranchObj::removeFloatImage (FloatImageObj *fio) insilmaril@0: { insilmaril@0: floatimage.remove (fio); insilmaril@0: requestReposition(); insilmaril@0: } insilmaril@0: insilmaril@0: void BranchObj::savePosInAngle () insilmaril@0: { insilmaril@0: // Save position in angle insilmaril@0: BranchObj *b; insilmaril@0: int i=0; insilmaril@0: for (b=branch.first(); b; b=branch.next() ) insilmaril@0: { insilmaril@0: b->angle=i; insilmaril@0: i++; insilmaril@0: } insilmaril@0: } insilmaril@0: insilmaril@0: BranchObj* BranchObj::addBranch() insilmaril@0: { insilmaril@0: BranchObj* newbo=new BranchObj(canvas,this); insilmaril@0: branch.append (newbo); insilmaril@0: newbo->setParObj(this); insilmaril@0: newbo->setColor(getColor(),false); insilmaril@0: newbo->setLinkColor(); insilmaril@0: newbo->setHeading ("new"); insilmaril@0: newbo->setLinkStyle (newbo->getDefLinkStyle()); insilmaril@0: if (scrolled) insilmaril@0: newbo->setVisibility (false); insilmaril@0: else insilmaril@0: newbo->setVisibility(visible); insilmaril@93: newbo->updateLink(); insilmaril@0: requestReposition(); insilmaril@0: return newbo; insilmaril@0: } insilmaril@0: insilmaril@0: BranchObj* BranchObj::addBranch(BranchObj* bo) insilmaril@0: { insilmaril@0: BranchObj* newbo=new BranchObj(canvas,this); insilmaril@0: branch.append (newbo); insilmaril@0: newbo->copy(bo); insilmaril@0: newbo->setParObj(this); insilmaril@0: newbo->setHeading (newbo->getHeading()); // adjust fontsize to depth insilmaril@0: newbo->setLinkStyle (newbo->getDefLinkStyle()); insilmaril@0: if (scrolled) insilmaril@0: newbo->setVisibility (false); insilmaril@0: else insilmaril@0: newbo->setVisibility(bo->visible); insilmaril@93: newbo->updateLink(); insilmaril@0: requestReposition(); insilmaril@0: return newbo; insilmaril@0: } insilmaril@0: insilmaril@83: BranchObj* BranchObj::addBranchPtr(BranchObj* bo) insilmaril@83: { insilmaril@83: branch.append (bo); insilmaril@83: bo->setParObj (this); insilmaril@83: bo->depth=depth+1; insilmaril@83: bo->setLinkStyle (bo->getDefLinkStyle() ); insilmaril@83: if (scrolled) tmpUnscroll(); insilmaril@83: setLastSelectedBranch (bo); insilmaril@83: return bo; insilmaril@83: } insilmaril@83: insilmaril@0: BranchObj* BranchObj::insertBranch(int pos) insilmaril@0: { insilmaril@0: savePosInAngle(); insilmaril@0: // Add new bo and resort branches insilmaril@0: BranchObj *newbo=addBranch (); insilmaril@0: newbo->angle=pos-0.5; insilmaril@0: branch.sort(); insilmaril@0: return newbo; insilmaril@0: } insilmaril@0: insilmaril@0: BranchObj* BranchObj::insertBranch(BranchObj* bo, int pos) insilmaril@0: { insilmaril@0: savePosInAngle(); insilmaril@0: // Add new bo and resort branches insilmaril@0: bo->angle=pos-0.5; insilmaril@0: BranchObj *newbo=addBranch (bo); insilmaril@0: branch.sort(); insilmaril@0: return newbo; insilmaril@0: } insilmaril@0: insilmaril@83: BranchObj* BranchObj::insertBranchPtr (BranchObj* bo, int pos) insilmaril@83: { insilmaril@83: savePosInAngle(); insilmaril@83: // Add new bo and resort branches insilmaril@83: bo->angle=pos-0.5; insilmaril@83: branch.append (bo); insilmaril@83: bo->setParObj (this); insilmaril@83: bo->depth=depth+1; insilmaril@83: bo->setLinkStyle (bo->getDefLinkStyle() ); insilmaril@83: if (scrolled) tmpUnscroll(); insilmaril@83: setLastSelectedBranch (bo); insilmaril@83: branch.sort(); insilmaril@83: return bo; insilmaril@83: } insilmaril@83: insilmaril@0: void BranchObj::removeBranch(BranchObj* bo) insilmaril@0: { insilmaril@0: // if bo is not in branch remove returns false, we insilmaril@0: // don't care... insilmaril@83: insilmaril@83: if (branch.remove (bo)) insilmaril@83: delete (bo); insilmaril@83: else insilmaril@83: qWarning ("BranchObj::removeBranch tried to remove non existing branch?!\n"); insilmaril@83: requestReposition(); insilmaril@83: } insilmaril@83: insilmaril@83: void BranchObj::removeBranchPtr(BranchObj* bo) insilmaril@83: { insilmaril@83: branch.remove (bo); insilmaril@0: requestReposition(); insilmaril@0: } insilmaril@0: insilmaril@0: void BranchObj::setLastSelectedBranch (BranchObj* bo) insilmaril@0: { insilmaril@0: lastSelectedBranch=branch.find(bo); insilmaril@0: } insilmaril@0: insilmaril@0: BranchObj* BranchObj::getLastSelectedBranch () insilmaril@0: { insilmaril@0: if (lastSelectedBranch>=0) insilmaril@0: { insilmaril@0: BranchObj* bo=branch.at(lastSelectedBranch); insilmaril@0: if (bo) return bo; insilmaril@0: } insilmaril@0: return branch.first(); insilmaril@0: } insilmaril@0: insilmaril@0: BranchObj* BranchObj::getFirstBranch () insilmaril@0: { insilmaril@0: return branch.first(); insilmaril@0: } insilmaril@0: insilmaril@0: BranchObj* BranchObj::getLastBranch () insilmaril@0: { insilmaril@0: return branch.last(); insilmaril@0: } insilmaril@0: insilmaril@0: BranchObj* BranchObj::getBranchNum (const uint &i) insilmaril@0: { insilmaril@0: return branch.at(i); insilmaril@0: } insilmaril@0: insilmaril@0: insilmaril@0: BranchObj* BranchObj::moveBranchUp(BranchObj* bo1) // move a branch up (modify myself) insilmaril@0: { insilmaril@0: savePosInAngle(); insilmaril@0: int i=branch.find(bo1); insilmaril@0: if (i>0) insilmaril@0: { // -1 if bo1 not found insilmaril@0: branch.at(i)->angle--; insilmaril@0: branch.at(i-1)->angle++; insilmaril@0: branch.sort(); insilmaril@0: return branch.at(i-1); insilmaril@0: } else insilmaril@0: return branch.at(i); insilmaril@0: } insilmaril@0: insilmaril@0: BranchObj* BranchObj::moveBranchDown(BranchObj* bo1) insilmaril@0: { insilmaril@0: savePosInAngle(); insilmaril@0: int i=branch.find(bo1); insilmaril@0: int j; insilmaril@0: if (branch.next()) insilmaril@0: { insilmaril@0: j = branch.at(); insilmaril@0: branch.at(i)->angle++; insilmaril@0: branch.at(j)->angle--; insilmaril@0: branch.sort(); insilmaril@0: return branch.at(j); insilmaril@0: } else insilmaril@0: return branch.at(i); insilmaril@0: } insilmaril@0: insilmaril@83: BranchObj* BranchObj::moveBranchTo (BranchObj* dst, int pos) insilmaril@83: { insilmaril@83: // Find current parent and insilmaril@83: // remove pointer to myself there insilmaril@83: BranchObj *par=(BranchObj*)(parObj); insilmaril@83: if (par) insilmaril@83: par->removeBranchPtr (this); insilmaril@83: else insilmaril@83: return NULL; insilmaril@83: insilmaril@83: if (pos<0) insilmaril@83: { insilmaril@83: // links adds myself as last branch at dst insilmaril@83: dst->addBranchPtr (this); insilmaril@83: return this; insilmaril@83: } else insilmaril@83: { insilmaril@83: // inserts me at pos in parent of dst insilmaril@83: par=(BranchObj*)(dst->getParObj()); insilmaril@83: if (par) insilmaril@83: return par->insertBranchPtr (this,pos); insilmaril@83: else insilmaril@83: return NULL; insilmaril@83: } insilmaril@83: } insilmaril@83: insilmaril@0: void BranchObj::alignRelativeTo (QPoint ref) insilmaril@0: { insilmaril@0: /* FIXME testing insilmaril@0: if (!getHeading().isEmpty()) insilmaril@0: cout << "BO::alignRelTo "<reposition(); insilmaril@0: insilmaril@0: if (scrolled) return; insilmaril@0: insilmaril@0: // Set reference point for alignment of childs insilmaril@0: QPoint ref2; insilmaril@0: if (orientation==OrientLeftOfCenter) insilmaril@0: ref2.setX(childPos.x() - linkwidth); insilmaril@0: else insilmaril@0: ref2.setX(childPos.x() + linkwidth); insilmaril@0: insilmaril@0: if (depth==1) insilmaril@0: ref2.setY(absPos.y()-(bboxTotal.height()-bbox.height())/2); insilmaril@0: else insilmaril@0: ref2.setY(ref.y() ); insilmaril@0: insilmaril@0: // Align the childs depending on reference point insilmaril@0: BranchObj *b; insilmaril@0: for (b=branch.first(); b; b=branch.next() ) insilmaril@0: { insilmaril@0: b->alignRelativeTo (ref2); insilmaril@0: ref2.setY(ref2.y() + b->getBBoxSizeWithChilds().height() ); insilmaril@0: } insilmaril@0: } insilmaril@0: insilmaril@0: insilmaril@0: void BranchObj::reposition() insilmaril@0: { insilmaril@0: /* FIXME testing insilmaril@0: if (!getHeading().isEmpty()) insilmaril@0: cout << "BO::reposition "<getTotalBBox(),r); insilmaril@0: insilmaril@0: FloatImageObj* fio; insilmaril@0: for (fio=floatimage.first();fio ;fio=floatimage.next() ) insilmaril@0: r=addBBox(fio->getTotalBBox(),r); insilmaril@0: insilmaril@0: return r; insilmaril@0: } insilmaril@0: insilmaril@0: QRect BranchObj::getBBoxSizeWithChilds() insilmaril@0: { insilmaril@0: return bboxTotal; insilmaril@0: } insilmaril@0: insilmaril@0: void BranchObj::calcBBoxSizeWithChilds() insilmaril@0: { insilmaril@0: // This is called only from reposition and insilmaril@0: // and only for mapcenter. So it won't be insilmaril@0: // called more than once for a single user insilmaril@0: // action insilmaril@0: insilmaril@0: // Calculate size of LMO including all childs (to align them later) insilmaril@0: insilmaril@0: bboxTotal.setX(bbox.x() ); insilmaril@0: bboxTotal.setY(bbox.y() ); insilmaril@0: insilmaril@0: // if branch is scrolled, ignore childs, but still consider floatimages insilmaril@0: if (scrolled) insilmaril@0: { insilmaril@0: bboxTotal.setWidth (bbox.width()); insilmaril@0: bboxTotal.setHeight(bbox.height()); insilmaril@0: return; insilmaril@0: } insilmaril@0: insilmaril@0: QRect r(0,0,0,0); insilmaril@0: QRect br; insilmaril@0: // Now calculate recursivly insilmaril@0: // sum of heights insilmaril@0: // maximum of widths insilmaril@0: // minimum of y insilmaril@0: BranchObj* b; insilmaril@0: for (b=branch.first();b ;b=branch.next() ) insilmaril@0: { insilmaril@0: b->calcBBoxSizeWithChilds(); insilmaril@0: br=b->getBBoxSizeWithChilds(); insilmaril@0: r.setWidth( max (br.width(), r.width() )); insilmaril@0: r.setHeight(br.height() + r.height() ); insilmaril@0: if (br.y()setRect(QRect(bbox.x(),bbox.y(),bbox.width(),bbox.height() ) ); insilmaril@0: } insilmaril@0: insilmaril@0: void BranchObj::select() insilmaril@0: { insilmaril@0: LinkableMapObj::select(); insilmaril@0: // Tell parent that I am selected now: insilmaril@0: BranchObj* po=(BranchObj*)(parObj); insilmaril@0: if (po) // TODO Try to get rid of this cast... insilmaril@0: po->setLastSelectedBranch(this); insilmaril@0: insilmaril@0: // temporary unscroll, if we have scrolled parents somewhere insilmaril@0: if (parObj) ((BranchObj*)(parObj))->tmpUnscroll(); insilmaril@0: insilmaril@0: // set Text in Editor insilmaril@0: textEditor->setText(note.getNote() ); insilmaril@0: textEditor->setFilename(note.getFilenameHint() ); insilmaril@0: textEditor->setFontHint (note.getFontHint() ); insilmaril@0: connect (textEditor, SIGNAL (textHasChanged() ), this, SLOT (updateNoteFlag() ) ); insilmaril@0: connect (textEditor, SIGNAL (fontSizeHasChanged() ), this, SLOT (updateNoteFlag() ) ); insilmaril@0: insilmaril@0: // Show URL and link in statusbar insilmaril@0: QString status; insilmaril@0: if (!url.isEmpty()) status+="URL: "+url+" "; insilmaril@0: if (!vymLink.isEmpty()) status+="Link: "+vymLink; insilmaril@0: if (!status.isEmpty()) mainWindow->statusMessage (status); insilmaril@0: insilmaril@0: // Update Toolbar insilmaril@0: standardFlags->updateToolBar(); insilmaril@0: insilmaril@0: // Update Browserbutton insilmaril@0: if (!url.isEmpty()) insilmaril@0: actionEditOpenURL->setEnabled (true); insilmaril@0: else insilmaril@0: actionEditOpenURL->setEnabled (false); insilmaril@0: insilmaril@0: // Update actions in mapeditor insilmaril@0: mapEditor->updateActions(); insilmaril@0: } insilmaril@0: insilmaril@0: void BranchObj::unselect() insilmaril@0: { insilmaril@0: LinkableMapObj::unselect(); insilmaril@0: // Delete any messages like vymLink in StatusBar insilmaril@0: mainWindow->statusMessage (""); insilmaril@0: insilmaril@0: // save note from editor and set flag insilmaril@0: // text is done by updateNoteFlag(), just save insilmaril@0: // filename here insilmaril@0: note.setFilenameHint (textEditor->getFilename()); insilmaril@0: insilmaril@0: // reset temporary unscroll, if we have scrolled parents somewhere insilmaril@0: if (parObj) ((BranchObj*)(parObj))->resetTmpUnscroll(); insilmaril@0: insilmaril@0: // Disconnect textEditor from this LMO insilmaril@0: disconnect( textEditor, SIGNAL(textHasChanged()), 0, 0 ); insilmaril@0: disconnect( textEditor, SIGNAL (fontSizeHasChanged()),0,0 ); insilmaril@0: insilmaril@0: // Erase content of editor insilmaril@0: textEditor->setInactive(); insilmaril@0: insilmaril@0: // unselect all buttons in toolbar insilmaril@0: standardFlagsDefault->updateToolBar(); insilmaril@0: } insilmaril@0: insilmaril@0: QString BranchObj::getSelectString() insilmaril@0: { insilmaril@0: QString s; insilmaril@0: if (parObj) insilmaril@0: { insilmaril@0: if (parObj->getDepth()==0) insilmaril@0: s= "bo:" + QString("%1").arg(getNum()); insilmaril@0: else insilmaril@0: s= ((BranchObj*)(parObj))->getSelectString() + ",bo:" + QString("%1").arg(getNum()); insilmaril@0: } else insilmaril@0: { insilmaril@0: s="mc:"; insilmaril@0: } insilmaril@0: insilmaril@0: return s; insilmaril@0: } insilmaril@0: