branchobj.cpp
changeset 82 920e6ed5889b
parent 0 7a96bd401351
child 2 608f976aa7bb
child 40 394b2f297e1d
child 83 e90f5bef70c8
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/branchobj.cpp	Sun Jan 30 12:59:10 2005 +0000
     1.3 @@ -0,0 +1,1184 @@
     1.4 +#include "branchobj.h"
     1.5 +#include "texteditor.h"
     1.6 +#include "mapeditor.h"
     1.7 +#include "mainwindow.h"
     1.8 +
     1.9 +extern TextEditor *textEditor;
    1.10 +extern Main *mainWindow;
    1.11 +extern FlagRowObj *standardFlagsDefault;
    1.12 +extern QAction *actionEditOpenURL;
    1.13 +
    1.14 +
    1.15 +/////////////////////////////////////////////////////////////////
    1.16 +// BranchObj
    1.17 +/////////////////////////////////////////////////////////////////
    1.18 +
    1.19 +BranchObj* BranchObj::itLast=NULL;
    1.20 +
    1.21 +
    1.22 +BranchObj::BranchObj () :OrnamentedObj()
    1.23 +{
    1.24 +//    cout << "Const BranchObj ()\n";
    1.25 +    setParObj (this);	
    1.26 +    init();
    1.27 +    depth=-1;
    1.28 +}
    1.29 +
    1.30 +BranchObj::BranchObj (QCanvas* c):OrnamentedObj (c)
    1.31 +{
    1.32 +//    cout << "Const BranchObj (c)  called from MapCenterObj (c)\n";
    1.33 +    canvas=c;
    1.34 +}
    1.35 +
    1.36 +BranchObj::BranchObj (QCanvas* c, LinkableMapObj* p):OrnamentedObj (c)
    1.37 +{
    1.38 +//    cout << "Const BranchObj (c,p)\n";
    1.39 +    canvas=c;
    1.40 +    setParObj (p);	
    1.41 +    depth=p->getDepth()+1;
    1.42 +	if (depth==1)
    1.43 +		// Calc angle to mapCenter if I am a mainbranch
    1.44 +		// needed for reordering the mainbranches clockwise 
    1.45 +		// around mapcenter 
    1.46 +		angle=getAngle (QPoint ((int)(x() - parObj->getChildPos().x() ), 
    1.47 +								(int)(y() - parObj->getChildPos().y() ) ) );
    1.48 +    init();
    1.49 +}
    1.50 +
    1.51 +BranchObj::~BranchObj ()
    1.52 +{
    1.53 +    //cout << "Destr BranchObj\n";
    1.54 +	// Check, if this branch was the last child to be deleted
    1.55 +	// If so, unset the scrolled flags
    1.56 +
    1.57 +	BranchObj *po=(BranchObj*)(parObj);
    1.58 +	if (po)
    1.59 +	{
    1.60 +		BranchObj *bo=((BranchObj*)(parObj))->getLastBranch();
    1.61 +		if (!bo) po->unScroll();
    1.62 +	}
    1.63 +}
    1.64 +
    1.65 +bool BranchObj::operator< ( const BranchObj & other )
    1.66 +{
    1.67 +    return  angle < other.angle;
    1.68 +}
    1.69 +
    1.70 +bool BranchObj::operator== ( const BranchObj & other )
    1.71 +{
    1.72 +    return angle == other.angle;
    1.73 +}
    1.74 +
    1.75 +int BranchObjPtrList::compareItems ( QPtrCollection::Item i, QPtrCollection::Item j)
    1.76 +{
    1.77 +	// Make sure PtrList::find works
    1.78 +	if (i==j) return 0;
    1.79 +
    1.80 +	if ( ((BranchObj*)(i))->angle > ((BranchObj*)(j))->angle )
    1.81 +		return 1;
    1.82 +	else
    1.83 +		return -1;
    1.84 +}
    1.85 +
    1.86 +void BranchObj::init () 
    1.87 +{
    1.88 +    branch.setAutoDelete (true);
    1.89 +    floatimage.setAutoDelete (true);
    1.90 +
    1.91 +	absPos=getRandPos();
    1.92 +	absPos+=parObj->getChildPos();
    1.93 +
    1.94 +    // TODO This should be done in TextObj later
    1.95 +    QFont font("Sans Serif,8,-1,5,50,0,0,0,0,0");
    1.96 +//    font.setPointSize(12);
    1.97 +   heading->setFont(font );
    1.98 +//    heading->setText(QObject::tr("new branch"));
    1.99 +
   1.100 +    lastSelectedBranch=-1;
   1.101 +
   1.102 +    setChildObj(this);
   1.103 +
   1.104 +	scrolled=false;
   1.105 +	tmpUnscrolled=false;
   1.106 +
   1.107 +	url="";
   1.108 +	vymLink="";
   1.109 +}
   1.110 +
   1.111 +void BranchObj::copy (BranchObj* other)
   1.112 +{
   1.113 +    OrnamentedObj::copy(other);
   1.114 +
   1.115 +	branch.clear();
   1.116 +    BranchObj* b;
   1.117 +    for (b=other->branch.first(); b;b=other->branch.next() ) 
   1.118 +		// Make deep copy of b
   1.119 +		// Because addBranch again calls copy for the childs,
   1.120 +		// Those will get a deep copy, too
   1.121 +		addBranch(b);	
   1.122 +
   1.123 +	FloatImageObj *fi;
   1.124 +	for (fi=other->floatimage.first(); fi;fi=other->floatimage.next() )
   1.125 +		addFloatImage (fi);
   1.126 +
   1.127 +	scrolled=other->scrolled;
   1.128 +	tmpUnscrolled=other->tmpUnscrolled;
   1.129 +	setVisibility (other->visible);
   1.130 +
   1.131 +	url=other->url;
   1.132 +	vymLink=other->vymLink;
   1.133 +
   1.134 +	angle=other->angle;
   1.135 +
   1.136 +    positionBBox();
   1.137 +}
   1.138 +
   1.139 +void BranchObj::clear() 
   1.140 +{
   1.141 +	branch.clear();
   1.142 +	floatimage.clear();
   1.143 +}
   1.144 +
   1.145 +int BranchObj::getNum()
   1.146 +{
   1.147 +	if (parObj)
   1.148 +		return ((BranchObj*)(parObj))->getNum ((BranchObj*)(this));
   1.149 +	else
   1.150 +		return 0;
   1.151 +}
   1.152 +
   1.153 +int BranchObj::getNum(BranchObj *bo)
   1.154 +{
   1.155 +	return branch.findRef (bo);
   1.156 +}
   1.157 +
   1.158 +int BranchObj::getFloatImageNum(FloatImageObj *fio)
   1.159 +{
   1.160 +	return floatimage.findRef (fio);
   1.161 +}
   1.162 +
   1.163 +int BranchObj::countBranches()
   1.164 +{
   1.165 +	return branch.count();
   1.166 +}
   1.167 +
   1.168 +int BranchObj::countFloatImages()
   1.169 +{
   1.170 +	return floatimage.count();
   1.171 +}
   1.172 +
   1.173 +void BranchObj::setParObjTmp(LinkableMapObj* lmo, QPoint m, int off)
   1.174 +{
   1.175 +	// Temporary link to lmo
   1.176 +	// m is position of mouse pointer 
   1.177 +	// offset 0: default 1: below lmo   -1 above lmo  (if possible)
   1.178 +
   1.179 +
   1.180 +	BranchObj* o=(BranchObj*)(lmo);
   1.181 +	if (!parObjTmpBuf) 
   1.182 +		parObjTmpBuf=parObj;
   1.183 +
   1.184 +	// ignore mapcenter and mainbranch
   1.185 +	if (lmo->getDepth()<2) off=0;
   1.186 +	if (off==0)
   1.187 +	{
   1.188 +		link2ParPos=false;
   1.189 +		parObj=o;
   1.190 +	}	
   1.191 +	else
   1.192 +	{	
   1.193 +		link2ParPos=true;
   1.194 +		if (off>0)
   1.195 +			parObj=o->getParObj();
   1.196 +		else	
   1.197 +			parObj=o->getParObj();
   1.198 +		parObj=o;
   1.199 +	}		
   1.200 +
   1.201 +	depth=parObj->getDepth()+1;
   1.202 +
   1.203 +	// setLinkStyle calls updateLink, only set it once
   1.204 +	if (style!=getDefLinkStyle() ) setLinkStyle (getDefLinkStyle());
   1.205 +
   1.206 +	// Move temporary to new position at destination
   1.207 +	// Usually the positioning would be done by reposition(),
   1.208 +	// but then also the destination branch would "Jump" around...
   1.209 +	// Better just do it approximately
   1.210 +	if (depth==1)
   1.211 +	{	// new parent is the mapcenter itself
   1.212 +
   1.213 +		QPoint p= normalise ( QPoint (m.x() - o->getChildPos().x(),
   1.214 +									  m.y() - o->getChildPos().y() ));
   1.215 +		if (p.x()<0) p.setX( p.x()-bbox.width() );
   1.216 +		move2RelPos (p);
   1.217 +	} else
   1.218 +	{	
   1.219 +		int y;
   1.220 +		if (off==0)
   1.221 +		{
   1.222 +			// new parent is just a branch, link to it
   1.223 +			QRect t=o->getBBoxSizeWithChilds();
   1.224 +			if (o->getLastBranch())
   1.225 +				y=t.y() + t.height() ;
   1.226 +			else
   1.227 +				y=t.y();
   1.228 +
   1.229 +		} else
   1.230 +		{
   1.231 +			if (off<0)
   1.232 +				// we want to link above lmo
   1.233 +				y=o->y() - height() + 5;
   1.234 +			else	
   1.235 +				// we want to link below lmo
   1.236 +				// Bottom of sel should be 5 pixels above
   1.237 +				// the bottom of the branch _below_ the target:
   1.238 +				// Don't try to find that branch, guess 12 pixels
   1.239 +				y=o->getChildPos().y()  -height() + 12; 
   1.240 +		}	
   1.241 +		if (o->getOrientation()==OrientLeftOfCenter)
   1.242 +			move ( o->getChildPos().x() - linkwidth, y );
   1.243 +		else	
   1.244 +			move (o->getChildPos().x() + linkwidth, y );
   1.245 +	}	
   1.246 +
   1.247 +	// updateLink is called implicitly in move
   1.248 +	reposition();	// FIXME shouldn't be this a request?
   1.249 +}
   1.250 +
   1.251 +void BranchObj::unsetParObjTmp()
   1.252 +{
   1.253 +	if (parObjTmpBuf) 
   1.254 +	{
   1.255 +		link2ParPos=false;
   1.256 +		parObj=parObjTmpBuf;
   1.257 +		parObjTmpBuf=NULL;
   1.258 +		depth=parObj->getDepth()+1;
   1.259 +		setLinkStyle (getDefLinkStyle() );
   1.260 +	}		
   1.261 +}
   1.262 +
   1.263 +void BranchObj::unScroll()
   1.264 +{
   1.265 +	if (tmpUnscrolled) resetTmpUnscroll();
   1.266 +	if (scrolled) toggleScroll();
   1.267 +}
   1.268 +
   1.269 +void BranchObj::toggleScroll()
   1.270 +{
   1.271 +	BranchObj *bo;
   1.272 +	if (scrolled)
   1.273 +	{
   1.274 +		scrolled=false;
   1.275 +		systemFlags->deactivate("scrolledright");
   1.276 +		for (bo=branch.first(); bo; bo=branch.next() )
   1.277 +		{
   1.278 +			bo->setVisibility(true);
   1.279 +		}
   1.280 +	} else
   1.281 +	{
   1.282 +		scrolled=true;
   1.283 +		systemFlags->activate("scrolledright");
   1.284 +		for (bo=branch.first(); bo; bo=branch.next() )
   1.285 +		{
   1.286 +			bo->setVisibility(false);
   1.287 +		}
   1.288 +	}
   1.289 +	calcBBoxSize();
   1.290 +	positionBBox();	
   1.291 +	move (absPos.x(), absPos.y() );
   1.292 +	forceReposition();
   1.293 +}
   1.294 +
   1.295 +bool BranchObj::isScrolled()
   1.296 +{
   1.297 +	return scrolled;
   1.298 +}
   1.299 +
   1.300 +bool BranchObj::hasScrolledParent(BranchObj *start)
   1.301 +{
   1.302 +	// Calls parents recursivly to
   1.303 +	// find out, if we are scrolled at all.
   1.304 +	// But ignore myself, just look at parents.
   1.305 +
   1.306 +	if (this !=start && scrolled) return true;
   1.307 +
   1.308 +	BranchObj* bo=(BranchObj*)(parObj);
   1.309 +	if (bo) 
   1.310 +		return bo->hasScrolledParent(start);
   1.311 +	else
   1.312 +		return false;
   1.313 +}
   1.314 +
   1.315 +void BranchObj::tmpUnscroll()
   1.316 +{
   1.317 +	// Unscroll parent (recursivly)
   1.318 +	BranchObj* bo=(BranchObj*)(parObj);
   1.319 +	if (bo) bo->tmpUnscroll();
   1.320 +		
   1.321 +	// Unscroll myself
   1.322 +	if (scrolled)
   1.323 +	{
   1.324 +		tmpUnscrolled=true;
   1.325 +		systemFlags->activate("tmpUnscrolledright");
   1.326 +		toggleScroll();
   1.327 +	}	
   1.328 +}
   1.329 +
   1.330 +void BranchObj::resetTmpUnscroll()
   1.331 +{
   1.332 +	// Unscroll parent (recursivly)
   1.333 +	BranchObj* bo=(BranchObj*)(parObj);
   1.334 +	if (bo)
   1.335 +		bo->resetTmpUnscroll();
   1.336 +		
   1.337 +	// Unscroll myself
   1.338 +	if (tmpUnscrolled)
   1.339 +	{
   1.340 +		tmpUnscrolled=false;
   1.341 +		systemFlags->deactivate("tmpUnscrolledright");
   1.342 +		toggleScroll();
   1.343 +	}	
   1.344 +}
   1.345 +
   1.346 +void BranchObj::setVisibility(bool v, int toDepth)
   1.347 +{
   1.348 +    if (depth <= toDepth)
   1.349 +    {
   1.350 +		frame->setVisibility(v);
   1.351 +		heading->setVisibility(v);
   1.352 +		systemFlags->setVisibility(v);
   1.353 +		standardFlags->setVisibility(v);
   1.354 +		LinkableMapObj::setVisibility (v);
   1.355 +		
   1.356 +		if (!scrolled && (depth < toDepth))
   1.357 +		{
   1.358 +			// Now go recursivly through all childs
   1.359 +			BranchObj* b;
   1.360 +			for (b=branch.first(); b;b=branch.next() ) 
   1.361 +				b->setVisibility (v,toDepth);	
   1.362 +			FloatImageObj *fio;
   1.363 +			for (fio=floatimage.first(); fio; fio=floatimage.next())
   1.364 +				fio->setVisibility (v);
   1.365 +		}
   1.366 +    } // depth <= toDepth	
   1.367 +	move (absPos.x(), absPos.y() );
   1.368 +	requestReposition();
   1.369 +}	
   1.370 +
   1.371 +void BranchObj::setVisibility(bool v)
   1.372 +{
   1.373 +    setVisibility (v,MAX_DEPTH);
   1.374 +}
   1.375 +
   1.376 +
   1.377 +void BranchObj::setLinkColor ()
   1.378 +{
   1.379 +	// Overloaded from LinkableMapObj
   1.380 +	// BranchObj can use color of heading
   1.381 +
   1.382 +	if (mapEditor->getLinkColorHint()==HeadingColor)
   1.383 +		LinkableMapObj::setLinkColor (heading->getColor() );
   1.384 +	else	
   1.385 +		LinkableMapObj::setLinkColor ();
   1.386 +}
   1.387 +
   1.388 +void BranchObj::setColor (QColor col, bool colorChilds)
   1.389 +{
   1.390 +    heading->setColor(col);
   1.391 +	setLinkColor();
   1.392 +    if (colorChilds) 
   1.393 +    {
   1.394 +		BranchObj *bo;
   1.395 +		for (bo=branch.first(); bo; bo=branch.next() )
   1.396 +			bo->setColor(col,colorChilds);
   1.397 +    }	
   1.398 +}
   1.399 +
   1.400 +
   1.401 +BranchObj* BranchObj::first()
   1.402 +{
   1.403 +	itLast=NULL;	
   1.404 +	return this; 
   1.405 +}
   1.406 +	
   1.407 +BranchObj* BranchObj::next()
   1.408 +{
   1.409 +	BranchObj *lmo;
   1.410 +	BranchObj *bo=branch.first();
   1.411 +	BranchObj *po=(BranchObj*)(parObj);
   1.412 +
   1.413 +	if (!itLast)
   1.414 +	{	// We are just beginning at the mapCenter
   1.415 +		if (bo) 
   1.416 +		{
   1.417 +			itLast=this;
   1.418 +			return bo;
   1.419 +		}	
   1.420 +		else
   1.421 +		{
   1.422 +			itLast=NULL;
   1.423 +			return NULL;
   1.424 +		}	
   1.425 +	}
   1.426 +
   1.427 +	if (itLast==parObj)
   1.428 +	{	// We come from above
   1.429 +		if (bo)
   1.430 +		{
   1.431 +			// there are childs, go there
   1.432 +			itLast=this;
   1.433 +			return bo;
   1.434 +		}	
   1.435 +		else
   1.436 +		{	// no childs, try to go up again
   1.437 +			if (po)
   1.438 +			{
   1.439 +				// go up
   1.440 +				itLast=this;
   1.441 +				lmo=po->next();
   1.442 +				itLast=this;
   1.443 +				return lmo;
   1.444 +
   1.445 +			}	
   1.446 +			else
   1.447 +			{
   1.448 +				// can't go up, I am mapCenter
   1.449 +				itLast=NULL;
   1.450 +				return NULL;
   1.451 +			}	
   1.452 +		}
   1.453 +	}
   1.454 +
   1.455 +	// Try to find last child, we came from, in my own childs
   1.456 +	bool searching=true;
   1.457 +	while (bo && searching)
   1.458 +	{
   1.459 +		if (itLast==bo) searching=false;
   1.460 +		bo=branch.next();
   1.461 +	}
   1.462 +	if (!searching)
   1.463 +	{	// found lastLMO in my childs
   1.464 +		if (bo)
   1.465 +		{
   1.466 +			// found a brother of lastLMO 
   1.467 +			itLast=this;
   1.468 +			return bo;
   1.469 +		}	
   1.470 +		else
   1.471 +		{
   1.472 +			if (po)
   1.473 +			{
   1.474 +				// go up
   1.475 +				itLast=this;
   1.476 +				lmo=po->next();
   1.477 +				itLast=this;
   1.478 +				return lmo;
   1.479 +			}
   1.480 +			else
   1.481 +			{
   1.482 +				// can't go up, I am mapCenter
   1.483 +				itLast=NULL;
   1.484 +				return NULL;
   1.485 +			}	
   1.486 +		}
   1.487 +	}
   1.488 +
   1.489 +	// couldn't find last child, it must be a nephew of mine
   1.490 +	bo=branch.first();
   1.491 +	if (bo)
   1.492 +	{
   1.493 +		// proceed with my first child
   1.494 +		itLast=this;	
   1.495 +		return bo;
   1.496 +	}	
   1.497 +	else
   1.498 +	{
   1.499 +		// or go back to my parents
   1.500 +		if (po)
   1.501 +		{
   1.502 +			// go up
   1.503 +			itLast=this;
   1.504 +			lmo=po->next();
   1.505 +			itLast=this;
   1.506 +			return lmo;
   1.507 +		}	
   1.508 +		else
   1.509 +		{
   1.510 +			// can't go up, I am mapCenter
   1.511 +			itLast=NULL;
   1.512 +			return NULL;
   1.513 +		}	
   1.514 +	}	
   1.515 +}
   1.516 +
   1.517 +BranchObj* BranchObj::getLastIterator()
   1.518 +{
   1.519 +	return itLast;
   1.520 +}
   1.521 +
   1.522 +void BranchObj::setLastIterator(BranchObj* it)
   1.523 +{
   1.524 +	itLast=it;
   1.525 +}
   1.526 +
   1.527 +
   1.528 +void BranchObj::move (double x, double y)
   1.529 +{
   1.530 +	OrnamentedObj::move (x,y);
   1.531 +    positionBBox();
   1.532 +}
   1.533 +
   1.534 +void BranchObj::move (QPoint p)
   1.535 +{
   1.536 +	move (p.x(), p.y());
   1.537 +}
   1.538 +
   1.539 +void BranchObj::moveBy (double x, double y)
   1.540 +{
   1.541 +	OrnamentedObj::moveBy (x,y);
   1.542 +    positionBBox();
   1.543 +    BranchObj* b;
   1.544 +    for (b=branch.first(); b;b=branch.next() ) 
   1.545 +		b->moveBy (x,y);
   1.546 +}
   1.547 +
   1.548 +void BranchObj::moveBy (QPoint p)
   1.549 +{
   1.550 +	moveBy (p.x(), p.y());
   1.551 +}
   1.552 +
   1.553 +
   1.554 +void BranchObj::positionBBox()
   1.555 +{
   1.556 +
   1.557 +    heading->positionBBox();
   1.558 +	systemFlags->positionBBox();
   1.559 +	standardFlags->positionBBox();
   1.560 +	// It seems that setting x,y also affects width,height
   1.561 +	int w_old=bbox.width();
   1.562 +	int h_old=bbox.height();
   1.563 +    bbox.setX (absPos.x() );
   1.564 +	bbox.setY (absPos.y() );
   1.565 +	bbox.setWidth(w_old);
   1.566 +	bbox.setHeight(h_old);
   1.567 +
   1.568 +
   1.569 +	setSelBox();
   1.570 +
   1.571 +	// set the frame
   1.572 +	frame->setRect(QRect(bbox.x(),bbox.y(),bbox.width(),bbox.height() ) );
   1.573 +}
   1.574 +
   1.575 +void BranchObj::calcBBoxSize()
   1.576 +{
   1.577 +    QSize heading_r=heading->getSize();
   1.578 +    int heading_w=static_cast <int> (heading_r.width() );
   1.579 +    int heading_h=static_cast <int> (heading_r.height() );
   1.580 +    QSize sysflags_r=systemFlags->getSize();
   1.581 +	int sysflags_h=sysflags_r.height();
   1.582 +	int sysflags_w=sysflags_r.width();
   1.583 +    QSize stanflags_r=standardFlags->getSize();
   1.584 +	int stanflags_h=stanflags_r.height();
   1.585 +	int stanflags_w=stanflags_r.width();
   1.586 +    int w;
   1.587 +    int h;
   1.588 +
   1.589 +	// set width to sum of all widths
   1.590 +	w=heading_w + sysflags_w + stanflags_w;
   1.591 +	// set height to maximum needed height
   1.592 +	h=max (sysflags_h,stanflags_h);
   1.593 +	h=max (h,heading_h);
   1.594 +
   1.595 +    w+=frame->getBorder();
   1.596 +    h+=frame->getBorder();
   1.597 +    bbox.setSize (QSize (w,h));
   1.598 +}
   1.599 +
   1.600 +LinkableMapObj* BranchObj::findMapObj(QPoint p, LinkableMapObj* excludeLMO)
   1.601 +{
   1.602 +	// Search branches
   1.603 +    BranchObj *b;
   1.604 +    LinkableMapObj *lmo;
   1.605 +    for (b=branch.first(); b; b=branch.next() )
   1.606 +    {	
   1.607 +		lmo=b->findMapObj(p, excludeLMO);
   1.608 +		if (lmo != NULL) return lmo;
   1.609 +    }
   1.610 +	
   1.611 +	// Search myself
   1.612 +    if (inBBox (p) && (this != excludeLMO) && isVisibleObj() ) 
   1.613 +		return this;
   1.614 +
   1.615 +	// Search float images
   1.616 +	FloatImageObj *foi;
   1.617 +    for (foi=floatimage.first(); foi; foi=floatimage.next() )
   1.618 +		if (foi->inBBox(p) && (foi != excludeLMO) && foi->getParObj()!= excludeLMO) return foi;
   1.619 +
   1.620 +    return NULL;
   1.621 +}
   1.622 +
   1.623 +void BranchObj::setHeading(QString s)
   1.624 +{
   1.625 +    // Adjusting font size
   1.626 +    QFont font=heading->getFont();
   1.627 +	if (depth==0)
   1.628 +		font.setPointSize(16);
   1.629 +	else	
   1.630 +		if (depth>1) 
   1.631 +			font.setPointSize(10);
   1.632 +		else
   1.633 +			font.setPointSize(12);
   1.634 +    heading->setFont(font);
   1.635 +    heading->setText(s);	// set new heading
   1.636 +	calcBBoxSize();			// recalculate bbox
   1.637 +    positionBBox();			// rearrange contents
   1.638 +	requestReposition();
   1.639 +}
   1.640 +
   1.641 +void BranchObj::setURL(QString s)
   1.642 +{
   1.643 +	url=s;
   1.644 +	if (!url.isEmpty())
   1.645 +		systemFlags->activate("url");
   1.646 +	else	
   1.647 +		systemFlags->deactivate("url");
   1.648 +	calcBBoxSize();			// recalculate bbox
   1.649 +    positionBBox();			// rearrange contents
   1.650 +	forceReposition();
   1.651 +}
   1.652 +
   1.653 +QString BranchObj::getURL()
   1.654 +{
   1.655 +	return url;
   1.656 +}
   1.657 +
   1.658 +void BranchObj::setVymLink(QString s)
   1.659 +{
   1.660 +	if (!s.isEmpty())
   1.661 +	{
   1.662 +		// We need the relative (from loading) 
   1.663 +		// or absolute path (from User event)
   1.664 +		// and build the absolute path.
   1.665 +		// Note: If we have relative, use path of
   1.666 +		// current map to build absolute path
   1.667 +		QDir d(s);
   1.668 +		if (!d.path().startsWith ("/"))
   1.669 +		{
   1.670 +			QString p=mapEditor->getDestPath();
   1.671 +			int i=p.findRev("/",-1);
   1.672 +			d.setPath(p.left(i)+"/"+s);
   1.673 +			d.convertToAbs();
   1.674 +		}
   1.675 +		vymLink=d.path();
   1.676 +		systemFlags->activate("vymLink");
   1.677 +	}	
   1.678 +	else	
   1.679 +	{
   1.680 +		systemFlags->deactivate("vymLink");
   1.681 +		vymLink="";
   1.682 +	}	
   1.683 +	calcBBoxSize();			// recalculate bbox
   1.684 +    positionBBox();			// rearrange contents
   1.685 +	forceReposition();
   1.686 +}
   1.687 +
   1.688 +QString BranchObj::getVymLink()
   1.689 +{
   1.690 +	return vymLink;
   1.691 +}
   1.692 +
   1.693 +QString BranchObj::saveToDir (const QString &tmpdir,const QString &prefix, const QPoint& offset)
   1.694 +{
   1.695 +    QString s,a;
   1.696 +	QString scrolledAttr;
   1.697 +	if (scrolled) 
   1.698 +		scrolledAttr=attribut ("scrolled","yes");
   1.699 +	else
   1.700 +		scrolledAttr="";
   1.701 +
   1.702 +	QString posAttr;
   1.703 +	if (depth<2) posAttr=
   1.704 +		attribut("absPosX",QString().setNum(absPos.x(),10)) +
   1.705 +		attribut("absPosY",QString().setNum(absPos.y(),10)); 
   1.706 +	else
   1.707 +		posAttr="";
   1.708 +
   1.709 +	QString urlAttr;
   1.710 +	if (!url.isEmpty())
   1.711 +		urlAttr=attribut ("url",url);
   1.712 +
   1.713 +	QString vymLinkAttr;
   1.714 +	if (!vymLink.isEmpty())
   1.715 +		vymLinkAttr=attribut ("vymLink",convertToRel(mapEditor->getDestPath(),vymLink) );
   1.716 +
   1.717 +	QString frameAttr;
   1.718 +	if (frame->getFrameType()!=NoFrame)
   1.719 +		frameAttr=attribut ("frameType",frame->getFrameTypeName());
   1.720 +	else
   1.721 +		frameAttr="";
   1.722 +
   1.723 +	// save area, if not scrolled
   1.724 +	QString areaAttr;
   1.725 +	if (!((BranchObj*)(parObj))->isScrolled() )
   1.726 +	{
   1.727 +		areaAttr=
   1.728 +			attribut("x1",QString().setNum(absPos.x()-offset.x(),10)) +
   1.729 +			attribut("y1",QString().setNum(absPos.y()-offset.y(),10)) +
   1.730 +			attribut("x2",QString().setNum(absPos.x()+width()-offset.x(),10)) +
   1.731 +			attribut("y2",QString().setNum(absPos.y()+height()-offset.y(),10));
   1.732 +
   1.733 +	} else
   1.734 +		areaAttr="";
   1.735 +	
   1.736 +    s=beginElement ("branch" +scrolledAttr +posAttr +urlAttr +vymLinkAttr +frameAttr +areaAttr);
   1.737 +    incIndent();
   1.738 +
   1.739 +	// save heading
   1.740 +    s=s+valueElement("heading", getHeading(),
   1.741 +		attribut ("textColor",QColor(heading->getColor()).name()));
   1.742 +
   1.743 +	// save names of flags set
   1.744 +	s+=standardFlags->saveToDir(tmpdir,prefix,0);
   1.745 +	
   1.746 +	// save note
   1.747 +	if (!note.isEmpty() )
   1.748 +		s+=note.saveToDir();
   1.749 +	
   1.750 +	// Save branches
   1.751 +    BranchObj *bo;
   1.752 +    for (bo=branch.first(); bo; bo=branch.next() )
   1.753 +		s+=bo->saveToDir(tmpdir,prefix,offset);
   1.754 +    decIndent();
   1.755 +
   1.756 +	// Save FloatImages
   1.757 +	FloatImageObj *fio;
   1.758 +	for (fio=floatimage.first(); fio; fio=floatimage.next() )
   1.759 +		s+=fio->saveToDir (tmpdir,prefix);
   1.760 +
   1.761 +    s+=endElement   ("branch");
   1.762 +    return s;
   1.763 +}
   1.764 +
   1.765 +LinkableMapObj* BranchObj::addFloatImage ()
   1.766 +{
   1.767 +	FloatImageObj *newfi=new FloatImageObj (canvas,this);
   1.768 +	floatimage.append (newfi);
   1.769 +	if (hasScrolledParent(this) )
   1.770 +		newfi->setVisibility (false);
   1.771 +	else	
   1.772 +		newfi->setVisibility(visible);
   1.773 +	requestReposition();
   1.774 +	return newfi;
   1.775 +}
   1.776 +
   1.777 +LinkableMapObj* BranchObj::addFloatImage (FloatImageObj *fio)
   1.778 +{
   1.779 +	FloatImageObj *newfi=new FloatImageObj (canvas,this);
   1.780 +	floatimage.append (newfi);
   1.781 +	newfi->copy (fio);
   1.782 +	if (hasScrolledParent(this) )
   1.783 +		newfi->setVisibility (false);
   1.784 +	else	
   1.785 +		newfi->setVisibility(visible);
   1.786 +	requestReposition();
   1.787 +	return newfi;
   1.788 +}
   1.789 +
   1.790 +FloatImageObj* BranchObj::getFirstFloatImage ()
   1.791 +{
   1.792 +    return floatimage.first();
   1.793 +}
   1.794 +
   1.795 +FloatImageObj* BranchObj::getLastFloatImage ()
   1.796 +{
   1.797 +    return floatimage.last();
   1.798 +}
   1.799 +
   1.800 +FloatImageObj* BranchObj::getFloatImageNum (const uint &i)
   1.801 +{
   1.802 +    return floatimage.at(i);
   1.803 +}
   1.804 +
   1.805 +void BranchObj::removeFloatImage (FloatImageObj *fio)
   1.806 +{
   1.807 +	floatimage.remove (fio);
   1.808 +	requestReposition();
   1.809 +}
   1.810 +
   1.811 +void BranchObj::savePosInAngle ()
   1.812 +{
   1.813 +	// Save position in angle
   1.814 +    BranchObj *b;
   1.815 +	int i=0;
   1.816 +    for (b=branch.first(); b; b=branch.next() )
   1.817 +	{
   1.818 +		b->angle=i;
   1.819 +		i++;
   1.820 +	}
   1.821 +}
   1.822 +
   1.823 +BranchObj* BranchObj::addBranch()
   1.824 +{
   1.825 +    BranchObj* newbo=new BranchObj(canvas,this);
   1.826 +    branch.append (newbo);
   1.827 +    newbo->setParObj(this);
   1.828 +    newbo->setColor(getColor(),false);	
   1.829 +    newbo->setLinkColor();	
   1.830 +    newbo->setHeading ("new");
   1.831 +	newbo->setLinkStyle (newbo->getDefLinkStyle());
   1.832 +	if (scrolled)
   1.833 +		newbo->setVisibility (false);
   1.834 +	else	
   1.835 +		newbo->setVisibility(visible);
   1.836 +	requestReposition();
   1.837 +	return newbo;
   1.838 +}
   1.839 +
   1.840 +BranchObj* BranchObj::addBranch(BranchObj* bo)
   1.841 +{
   1.842 +    BranchObj* newbo=new BranchObj(canvas,this);
   1.843 +    branch.append (newbo);
   1.844 +    newbo->copy(bo);
   1.845 +    newbo->setParObj(this);
   1.846 +	newbo->setHeading (newbo->getHeading());	// adjust fontsize to depth
   1.847 +	newbo->setLinkStyle (newbo->getDefLinkStyle());
   1.848 +	if (scrolled)
   1.849 +		newbo->setVisibility (false);
   1.850 +	else	
   1.851 +		newbo->setVisibility(bo->visible);
   1.852 +	requestReposition();
   1.853 +	return newbo;
   1.854 +}
   1.855 +
   1.856 +BranchObj* BranchObj::insertBranch(int pos)
   1.857 +{
   1.858 +	savePosInAngle();
   1.859 +	// Add new bo and resort branches
   1.860 +	BranchObj *newbo=addBranch ();
   1.861 +	newbo->angle=pos-0.5;
   1.862 +	branch.sort();
   1.863 +	return newbo;
   1.864 +}
   1.865 +
   1.866 +BranchObj* BranchObj::insertBranch(BranchObj* bo, int pos)
   1.867 +{
   1.868 +	savePosInAngle();
   1.869 +	// Add new bo and resort branches
   1.870 +	bo->angle=pos-0.5;
   1.871 +	BranchObj *newbo=addBranch (bo);
   1.872 +	branch.sort();
   1.873 +	return newbo;
   1.874 +}
   1.875 +
   1.876 +void BranchObj::removeBranch(BranchObj* bo)
   1.877 +{
   1.878 +    // if bo is not in branch remove returns false, we
   1.879 +    // don't care...
   1.880 +    branch.remove (bo);
   1.881 +	requestReposition();
   1.882 +}
   1.883 +
   1.884 +void BranchObj::setLastSelectedBranch (BranchObj* bo)
   1.885 +{
   1.886 +    lastSelectedBranch=branch.find(bo);
   1.887 +}
   1.888 +
   1.889 +BranchObj* BranchObj::getLastSelectedBranch ()
   1.890 +{
   1.891 +    if (lastSelectedBranch>=0) 
   1.892 +	{
   1.893 +		BranchObj* bo=branch.at(lastSelectedBranch);
   1.894 +		if (bo) return bo;
   1.895 +    }	
   1.896 +    return branch.first();
   1.897 +}
   1.898 +
   1.899 +BranchObj* BranchObj::getFirstBranch ()
   1.900 +{
   1.901 +    return branch.first();
   1.902 +}
   1.903 +
   1.904 +BranchObj* BranchObj::getLastBranch ()
   1.905 +{
   1.906 +    return branch.last();
   1.907 +}
   1.908 +
   1.909 +BranchObj* BranchObj::getBranchNum (const uint &i)
   1.910 +{
   1.911 +    return branch.at(i);
   1.912 +}
   1.913 +
   1.914 +
   1.915 +BranchObj* BranchObj::moveBranchUp(BranchObj* bo1) // move a branch up (modify myself)
   1.916 +{
   1.917 +	savePosInAngle();
   1.918 +    int i=branch.find(bo1);
   1.919 +    if (i>0) 
   1.920 +	{	// -1 if bo1 not found 
   1.921 +		branch.at(i)->angle--;
   1.922 +		branch.at(i-1)->angle++;
   1.923 +		branch.sort();
   1.924 +		return branch.at(i-1);
   1.925 +	} else
   1.926 +		return branch.at(i);
   1.927 +}
   1.928 +
   1.929 +BranchObj* BranchObj::moveBranchDown(BranchObj* bo1)
   1.930 +{
   1.931 +	savePosInAngle();
   1.932 +    int i=branch.find(bo1);
   1.933 +	int j;
   1.934 +	if (branch.next())
   1.935 +	{
   1.936 +		j = branch.at();
   1.937 +		branch.at(i)->angle++;
   1.938 +		branch.at(j)->angle--;
   1.939 +		branch.sort();
   1.940 +		return branch.at(j);
   1.941 +	} else
   1.942 +		return branch.at(i);
   1.943 +}
   1.944 +
   1.945 +void BranchObj::alignRelativeTo (QPoint ref)
   1.946 +{
   1.947 +/* FIXME testing
   1.948 +	if (!getHeading().isEmpty())
   1.949 +		cout << "BO::alignRelTo "<<getHeading()<<endl;
   1.950 +	else	
   1.951 +		cout << "BO::alignRelTo  ???"<<endl;
   1.952 +	cout << "  d="<<depth<<endl;
   1.953 +*/	
   1.954 +	int th = bboxTotal.height();	
   1.955 +
   1.956 +	// If I am the mapcenter or a mainbranch, reposition heading
   1.957 +	if (depth<2)
   1.958 +	{
   1.959 +		move (absPos.x(),absPos.y());
   1.960 +		if (depth==1)
   1.961 +		{
   1.962 +			// Calc angle to mapCenter if I am a mainbranch
   1.963 +			// needed for reordering the mainbranches clockwise 
   1.964 +			// around mapcenter 
   1.965 +			angle=getAngle (QPoint ((int)(x() - parObj->getChildPos().x() ), 
   1.966 +									(int)(y() - parObj->getChildPos().y() ) ) );
   1.967 +		}	
   1.968 +	} 
   1.969 +	else
   1.970 +    {
   1.971 +		// Align myself depending on orientation and parent, but
   1.972 +		// only if I am not the mainbranch or mapcenter itself
   1.973 +		switch (orientation) 
   1.974 +		{
   1.975 +			case OrientLeftOfCenter:
   1.976 +				move (ref.x()-bbox.width(), ref.y() + (th-bbox.height())/2 );
   1.977 +			break;
   1.978 +			case OrientRightOfCenter:	
   1.979 +				move (ref.x(), ref.y() + (th-bbox.height())/2 );
   1.980 +			break;
   1.981 +			default:
   1.982 +				cout <<"LMO::alignRelativeTo: oops, no orientation given...\n";
   1.983 +			break;
   1.984 +		}		
   1.985 +    }		
   1.986 +
   1.987 +	FloatImageObj *fio;
   1.988 +    for (fio=floatimage.first(); fio; fio=floatimage.next() )
   1.989 +		fio->reposition();
   1.990 +
   1.991 +	if (scrolled) return;
   1.992 +
   1.993 +    // Set reference point for alignment of childs
   1.994 +    QPoint ref2;
   1.995 +    if (orientation==OrientLeftOfCenter)
   1.996 +		ref2.setX(childPos.x() - linkwidth);
   1.997 +    else	
   1.998 +		ref2.setX(childPos.x() + linkwidth);
   1.999 +
  1.1000 +	if (depth==1)
  1.1001 +		ref2.setY(absPos.y()-(bboxTotal.height()-bbox.height())/2);
  1.1002 +	else	
  1.1003 +		ref2.setY(ref.y() );	
  1.1004 +
  1.1005 +    // Align the childs depending on reference point 
  1.1006 +    BranchObj *b;
  1.1007 +    for (b=branch.first(); b; b=branch.next() )
  1.1008 +    {	
  1.1009 +		b->alignRelativeTo (ref2);
  1.1010 +		ref2.setY(ref2.y() + b->getBBoxSizeWithChilds().height() );
  1.1011 +    }
  1.1012 +}
  1.1013 +
  1.1014 +
  1.1015 +void BranchObj::reposition()
  1.1016 +{	
  1.1017 +/* FIXME testing
  1.1018 +	if (!getHeading().isEmpty())
  1.1019 +		cout << "BO::reposition  "<<getHeading()<<endl;
  1.1020 +	else	
  1.1021 +		cout << "BO::reposition  ???"<<endl;
  1.1022 +*/		
  1.1023 +	if (depth==0)
  1.1024 +	{
  1.1025 +		// only calculate the sizes once. If the deepest LMO 
  1.1026 +		// changes its height,
  1.1027 +		// all upper LMOs have to change, too.
  1.1028 +		calcBBoxSizeWithChilds();
  1.1029 +	    alignRelativeTo ( QPoint (absPos.x(),
  1.1030 +			absPos.y()-(bboxTotal.height()-bbox.height())/2) );
  1.1031 +		branch.sort();	
  1.1032 +	} else
  1.1033 +	{
  1.1034 +		// This is only important for moving branches:
  1.1035 +		// For editing a branch it isn't called...
  1.1036 +	    alignRelativeTo ( QPoint (absPos.x(),
  1.1037 +							absPos.y()-(bboxTotal.height()-bbox.height())/2) );
  1.1038 +	}
  1.1039 +}
  1.1040 +
  1.1041 +
  1.1042 +QRect BranchObj::getTotalBBox()
  1.1043 +{
  1.1044 +	QRect r=bbox;
  1.1045 +
  1.1046 +	if (scrolled) return r;
  1.1047 +
  1.1048 +	BranchObj* b;
  1.1049 +	for (b=branch.first();b ;b=branch.next() )
  1.1050 +		r=addBBox(b->getTotalBBox(),r);
  1.1051 +
  1.1052 +	FloatImageObj* fio;
  1.1053 +	for (fio=floatimage.first();fio ;fio=floatimage.next() )
  1.1054 +		r=addBBox(fio->getTotalBBox(),r);
  1.1055 +		
  1.1056 +	return r;
  1.1057 +}
  1.1058 +
  1.1059 +QRect BranchObj::getBBoxSizeWithChilds()
  1.1060 +{
  1.1061 +	return bboxTotal;
  1.1062 +}
  1.1063 +
  1.1064 +void BranchObj::calcBBoxSizeWithChilds()
  1.1065 +{
  1.1066 +	// This is called only from reposition and
  1.1067 +	// and only for mapcenter. So it won't be
  1.1068 +	// called more than once for a single user 
  1.1069 +	// action
  1.1070 +	
  1.1071 +	// Calculate size of LMO including all childs (to align them later)
  1.1072 +
  1.1073 +	bboxTotal.setX(bbox.x() );
  1.1074 +	bboxTotal.setY(bbox.y() );
  1.1075 +
  1.1076 +	// if branch is scrolled, ignore childs, but still consider floatimages
  1.1077 +	if (scrolled)
  1.1078 +	{
  1.1079 +		bboxTotal.setWidth (bbox.width());
  1.1080 +		bboxTotal.setHeight(bbox.height());
  1.1081 +		return;
  1.1082 +	}
  1.1083 +	
  1.1084 +	QRect r(0,0,0,0);
  1.1085 +	QRect br;
  1.1086 +	// Now calculate recursivly
  1.1087 +	// sum of heights 
  1.1088 +	// maximum of widths 
  1.1089 +	// minimum of y
  1.1090 +	BranchObj* b;
  1.1091 +	for (b=branch.first();b ;b=branch.next() )
  1.1092 +	{
  1.1093 +		b->calcBBoxSizeWithChilds();
  1.1094 +		br=b->getBBoxSizeWithChilds();
  1.1095 +		r.setWidth( max (br.width(), r.width() ));
  1.1096 +		r.setHeight(br.height() + r.height() );
  1.1097 +		if (br.y()<bboxTotal.y()) bboxTotal.setY(br.y());
  1.1098 +	}
  1.1099 +	// Add myself and also
  1.1100 +	// add width of link to sum if necessary
  1.1101 +	if (branch.isEmpty())
  1.1102 +		bboxTotal.setWidth (bbox.width() + r.width() );
  1.1103 +	else	
  1.1104 +		bboxTotal.setWidth (bbox.width() + r.width() + linkwidth);
  1.1105 +	bboxTotal.setHeight(max (r.height(),  bbox.height() ) );
  1.1106 +//	frame->setRect(QRect(bbox.x(),bbox.y(),bbox.width(),bbox.height() ) );
  1.1107 +}
  1.1108 +
  1.1109 +void BranchObj::select()
  1.1110 +{
  1.1111 +    LinkableMapObj::select();
  1.1112 +	// Tell parent that I am selected now:
  1.1113 +	BranchObj* po=(BranchObj*)(parObj);
  1.1114 +    if (po)	// TODO	    Try to get rid of this cast...
  1.1115 +        po->setLastSelectedBranch(this);
  1.1116 +		
  1.1117 +	// temporary unscroll, if we have scrolled parents somewhere
  1.1118 +	if (parObj) ((BranchObj*)(parObj))->tmpUnscroll();
  1.1119 +
  1.1120 +	// set Text in Editor	
  1.1121 +	textEditor->setText(note.getNote() );
  1.1122 +	textEditor->setFilename(note.getFilenameHint() );
  1.1123 +	textEditor->setFontHint (note.getFontHint() );
  1.1124 +	connect (textEditor, SIGNAL (textHasChanged() ), this, SLOT (updateNoteFlag() ) ); 
  1.1125 +	connect (textEditor, SIGNAL (fontSizeHasChanged() ), this, SLOT (updateNoteFlag() ) ); 
  1.1126 +
  1.1127 +	// Show URL and link in statusbar
  1.1128 +	QString status;
  1.1129 +	if (!url.isEmpty()) status+="URL: "+url+"  ";
  1.1130 +	if (!vymLink.isEmpty()) status+="Link: "+vymLink;
  1.1131 +	if (!status.isEmpty()) mainWindow->statusMessage (status);
  1.1132 +
  1.1133 +	// Update Toolbar
  1.1134 +	standardFlags->updateToolBar();
  1.1135 +
  1.1136 +	// Update Browserbutton
  1.1137 +	if (!url.isEmpty())
  1.1138 +		actionEditOpenURL->setEnabled (true);
  1.1139 +	else	
  1.1140 +		actionEditOpenURL->setEnabled (false);
  1.1141 +
  1.1142 +	// Update actions in mapeditor
  1.1143 +	mapEditor->updateActions();
  1.1144 +}
  1.1145 +
  1.1146 +void BranchObj::unselect()
  1.1147 +{
  1.1148 +	LinkableMapObj::unselect();
  1.1149 +	// Delete any messages like vymLink in StatusBar
  1.1150 +	mainWindow->statusMessage ("");
  1.1151 +
  1.1152 +	// save note from editor and set flag
  1.1153 +	// text is done by updateNoteFlag(), just save
  1.1154 +	// filename here
  1.1155 +	note.setFilenameHint (textEditor->getFilename());
  1.1156 +
  1.1157 +	// reset temporary unscroll, if we have scrolled parents somewhere
  1.1158 +	if (parObj) ((BranchObj*)(parObj))->resetTmpUnscroll();
  1.1159 +
  1.1160 +	// Disconnect textEditor from this LMO
  1.1161 +	disconnect( textEditor, SIGNAL(textHasChanged()), 0, 0 );
  1.1162 +	disconnect( textEditor, SIGNAL (fontSizeHasChanged()),0,0 ); 
  1.1163 +
  1.1164 +	// Erase content of editor 
  1.1165 +	textEditor->setInactive();
  1.1166 +
  1.1167 +	// unselect all buttons in toolbar
  1.1168 +	standardFlagsDefault->updateToolBar();
  1.1169 +}
  1.1170 +
  1.1171 +QString BranchObj::getSelectString()
  1.1172 +{
  1.1173 +	QString s;
  1.1174 +	if (parObj)
  1.1175 +	{
  1.1176 +		if (parObj->getDepth()==0)
  1.1177 +			s= "bo:" + QString("%1").arg(getNum());
  1.1178 +		else	
  1.1179 +			s= ((BranchObj*)(parObj))->getSelectString() + ",bo:" + QString("%1").arg(getNum());
  1.1180 +	} else
  1.1181 +	{
  1.1182 +		s="mc:";
  1.1183 +	}
  1.1184 +	
  1.1185 +	return s;
  1.1186 +}
  1.1187 +