Initial import.
2 #include "texteditor.h"
4 #include "mainwindow.h"
6 extern TextEditor *textEditor;
7 extern Main *mainWindow;
8 extern FlagRowObj *standardFlagsDefault;
9 extern QAction *actionEditOpenURL;
12 /////////////////////////////////////////////////////////////////
14 /////////////////////////////////////////////////////////////////
16 BranchObj* BranchObj::itLast=NULL;
19 BranchObj::BranchObj () :OrnamentedObj()
21 // cout << "Const BranchObj ()\n";
27 BranchObj::BranchObj (QCanvas* c):OrnamentedObj (c)
29 // cout << "Const BranchObj (c) called from MapCenterObj (c)\n";
33 BranchObj::BranchObj (QCanvas* c, LinkableMapObj* p):OrnamentedObj (c)
35 // cout << "Const BranchObj (c,p)\n";
38 depth=p->getDepth()+1;
40 // Calc angle to mapCenter if I am a mainbranch
41 // needed for reordering the mainbranches clockwise
43 angle=getAngle (QPoint ((int)(x() - parObj->getChildPos().x() ),
44 (int)(y() - parObj->getChildPos().y() ) ) );
48 BranchObj::~BranchObj ()
50 //cout << "Destr BranchObj\n";
51 // Check, if this branch was the last child to be deleted
52 // If so, unset the scrolled flags
54 BranchObj *po=(BranchObj*)(parObj);
57 BranchObj *bo=((BranchObj*)(parObj))->getLastBranch();
58 if (!bo) po->unScroll();
62 bool BranchObj::operator< ( const BranchObj & other )
64 return angle < other.angle;
67 bool BranchObj::operator== ( const BranchObj & other )
69 return angle == other.angle;
72 int BranchObjPtrList::compareItems ( QPtrCollection::Item i, QPtrCollection::Item j)
74 // Make sure PtrList::find works
77 if ( ((BranchObj*)(i))->angle > ((BranchObj*)(j))->angle )
83 void BranchObj::init ()
85 branch.setAutoDelete (true);
86 floatimage.setAutoDelete (true);
89 absPos+=parObj->getChildPos();
91 // TODO This should be done in TextObj later
92 QFont font("Sans Serif,8,-1,5,50,0,0,0,0,0");
93 // font.setPointSize(12);
94 heading->setFont(font );
95 // heading->setText(QObject::tr("new branch"));
97 lastSelectedBranch=-1;
108 void BranchObj::copy (BranchObj* other)
110 OrnamentedObj::copy(other);
114 for (b=other->branch.first(); b;b=other->branch.next() )
115 // Make deep copy of b
116 // Because addBranch again calls copy for the childs,
117 // Those will get a deep copy, too
121 for (fi=other->floatimage.first(); fi;fi=other->floatimage.next() )
124 scrolled=other->scrolled;
125 tmpUnscrolled=other->tmpUnscrolled;
126 setVisibility (other->visible);
129 vymLink=other->vymLink;
136 void BranchObj::clear()
142 int BranchObj::getNum()
145 return ((BranchObj*)(parObj))->getNum ((BranchObj*)(this));
150 int BranchObj::getNum(BranchObj *bo)
152 return branch.findRef (bo);
155 int BranchObj::getFloatImageNum(FloatImageObj *fio)
157 return floatimage.findRef (fio);
160 int BranchObj::countBranches()
162 return branch.count();
165 int BranchObj::countFloatImages()
167 return floatimage.count();
170 void BranchObj::setParObjTmp(LinkableMapObj* lmo, QPoint m, int off)
172 // Temporary link to lmo
173 // m is position of mouse pointer
174 // offset 0: default 1: below lmo -1 above lmo (if possible)
177 BranchObj* o=(BranchObj*)(lmo);
181 // ignore mapcenter and mainbranch
182 if (lmo->getDepth()<2) off=0;
192 parObj=o->getParObj();
194 parObj=o->getParObj();
198 depth=parObj->getDepth()+1;
200 // setLinkStyle calls updateLink, only set it once
201 if (style!=getDefLinkStyle() ) setLinkStyle (getDefLinkStyle());
203 // Move temporary to new position at destination
204 // Usually the positioning would be done by reposition(),
205 // but then also the destination branch would "Jump" around...
206 // Better just do it approximately
208 { // new parent is the mapcenter itself
210 QPoint p= normalise ( QPoint (m.x() - o->getChildPos().x(),
211 m.y() - o->getChildPos().y() ));
212 if (p.x()<0) p.setX( p.x()-bbox.width() );
219 // new parent is just a branch, link to it
220 QRect t=o->getBBoxSizeWithChilds();
221 if (o->getLastBranch())
222 y=t.y() + t.height() ;
229 // we want to link above lmo
230 y=o->y() - height() + 5;
232 // we want to link below lmo
233 // Bottom of sel should be 5 pixels above
234 // the bottom of the branch _below_ the target:
235 // Don't try to find that branch, guess 12 pixels
236 y=o->getChildPos().y() -height() + 12;
238 if (o->getOrientation()==OrientLeftOfCenter)
239 move ( o->getChildPos().x() - linkwidth, y );
241 move (o->getChildPos().x() + linkwidth, y );
244 // updateLink is called implicitly in move
245 reposition(); // FIXME shouldn't be this a request?
248 void BranchObj::unsetParObjTmp()
255 depth=parObj->getDepth()+1;
256 setLinkStyle (getDefLinkStyle() );
260 void BranchObj::unScroll()
262 if (tmpUnscrolled) resetTmpUnscroll();
263 if (scrolled) toggleScroll();
266 void BranchObj::toggleScroll()
272 systemFlags->deactivate("scrolledright");
273 for (bo=branch.first(); bo; bo=branch.next() )
275 bo->setVisibility(true);
280 systemFlags->activate("scrolledright");
281 for (bo=branch.first(); bo; bo=branch.next() )
283 bo->setVisibility(false);
288 move (absPos.x(), absPos.y() );
292 bool BranchObj::isScrolled()
297 bool BranchObj::hasScrolledParent(BranchObj *start)
299 // Calls parents recursivly to
300 // find out, if we are scrolled at all.
301 // But ignore myself, just look at parents.
303 if (this !=start && scrolled) return true;
305 BranchObj* bo=(BranchObj*)(parObj);
307 return bo->hasScrolledParent(start);
312 void BranchObj::tmpUnscroll()
314 // Unscroll parent (recursivly)
315 BranchObj* bo=(BranchObj*)(parObj);
316 if (bo) bo->tmpUnscroll();
322 systemFlags->activate("tmpUnscrolledright");
327 void BranchObj::resetTmpUnscroll()
329 // Unscroll parent (recursivly)
330 BranchObj* bo=(BranchObj*)(parObj);
332 bo->resetTmpUnscroll();
338 systemFlags->deactivate("tmpUnscrolledright");
343 void BranchObj::setVisibility(bool v, int toDepth)
345 if (depth <= toDepth)
347 frame->setVisibility(v);
348 heading->setVisibility(v);
349 systemFlags->setVisibility(v);
350 standardFlags->setVisibility(v);
351 LinkableMapObj::setVisibility (v);
353 if (!scrolled && (depth < toDepth))
355 // Now go recursivly through all childs
357 for (b=branch.first(); b;b=branch.next() )
358 b->setVisibility (v,toDepth);
360 for (fio=floatimage.first(); fio; fio=floatimage.next())
361 fio->setVisibility (v);
363 } // depth <= toDepth
364 move (absPos.x(), absPos.y() );
368 void BranchObj::setVisibility(bool v)
370 setVisibility (v,MAX_DEPTH);
374 void BranchObj::setLinkColor ()
376 // Overloaded from LinkableMapObj
377 // BranchObj can use color of heading
379 if (mapEditor->getLinkColorHint()==HeadingColor)
380 LinkableMapObj::setLinkColor (heading->getColor() );
382 LinkableMapObj::setLinkColor ();
385 void BranchObj::setColor (QColor col, bool colorChilds)
387 heading->setColor(col);
392 for (bo=branch.first(); bo; bo=branch.next() )
393 bo->setColor(col,colorChilds);
398 BranchObj* BranchObj::first()
404 BranchObj* BranchObj::next()
407 BranchObj *bo=branch.first();
408 BranchObj *po=(BranchObj*)(parObj);
411 { // We are just beginning at the mapCenter
425 { // We come from above
428 // there are childs, go there
433 { // no childs, try to go up again
445 // can't go up, I am mapCenter
452 // Try to find last child, we came from, in my own childs
454 while (bo && searching)
456 if (itLast==bo) searching=false;
460 { // found lastLMO in my childs
463 // found a brother of lastLMO
479 // can't go up, I am mapCenter
486 // couldn't find last child, it must be a nephew of mine
490 // proceed with my first child
496 // or go back to my parents
507 // can't go up, I am mapCenter
514 BranchObj* BranchObj::getLastIterator()
519 void BranchObj::setLastIterator(BranchObj* it)
525 void BranchObj::move (double x, double y)
527 OrnamentedObj::move (x,y);
531 void BranchObj::move (QPoint p)
536 void BranchObj::moveBy (double x, double y)
538 OrnamentedObj::moveBy (x,y);
541 for (b=branch.first(); b;b=branch.next() )
545 void BranchObj::moveBy (QPoint p)
547 moveBy (p.x(), p.y());
551 void BranchObj::positionBBox()
554 heading->positionBBox();
555 systemFlags->positionBBox();
556 standardFlags->positionBBox();
557 // It seems that setting x,y also affects width,height
558 int w_old=bbox.width();
559 int h_old=bbox.height();
560 bbox.setX (absPos.x() );
561 bbox.setY (absPos.y() );
562 bbox.setWidth(w_old);
563 bbox.setHeight(h_old);
569 frame->setRect(QRect(bbox.x(),bbox.y(),bbox.width(),bbox.height() ) );
572 void BranchObj::calcBBoxSize()
574 QSize heading_r=heading->getSize();
575 int heading_w=static_cast <int> (heading_r.width() );
576 int heading_h=static_cast <int> (heading_r.height() );
577 QSize sysflags_r=systemFlags->getSize();
578 int sysflags_h=sysflags_r.height();
579 int sysflags_w=sysflags_r.width();
580 QSize stanflags_r=standardFlags->getSize();
581 int stanflags_h=stanflags_r.height();
582 int stanflags_w=stanflags_r.width();
586 // set width to sum of all widths
587 w=heading_w + sysflags_w + stanflags_w;
588 // set height to maximum needed height
589 h=max (sysflags_h,stanflags_h);
592 w+=frame->getBorder();
593 h+=frame->getBorder();
594 bbox.setSize (QSize (w,h));
597 LinkableMapObj* BranchObj::findMapObj(QPoint p, LinkableMapObj* excludeLMO)
602 for (b=branch.first(); b; b=branch.next() )
604 lmo=b->findMapObj(p, excludeLMO);
605 if (lmo != NULL) return lmo;
609 if (inBBox (p) && (this != excludeLMO) && isVisibleObj() )
612 // Search float images
614 for (foi=floatimage.first(); foi; foi=floatimage.next() )
615 if (foi->inBBox(p) && (foi != excludeLMO) && foi->getParObj()!= excludeLMO) return foi;
620 void BranchObj::setHeading(QString s)
622 // Adjusting font size
623 QFont font=heading->getFont();
625 font.setPointSize(16);
628 font.setPointSize(10);
630 font.setPointSize(12);
631 heading->setFont(font);
632 heading->setText(s); // set new heading
633 calcBBoxSize(); // recalculate bbox
634 positionBBox(); // rearrange contents
638 void BranchObj::setURL(QString s)
642 systemFlags->activate("url");
644 systemFlags->deactivate("url");
645 calcBBoxSize(); // recalculate bbox
646 positionBBox(); // rearrange contents
650 QString BranchObj::getURL()
655 void BranchObj::setVymLink(QString s)
659 // We need the relative (from loading)
660 // or absolute path (from User event)
661 // and build the absolute path.
662 // Note: If we have relative, use path of
663 // current map to build absolute path
665 if (!d.path().startsWith ("/"))
667 QString p=mapEditor->getDestPath();
668 int i=p.findRev("/",-1);
669 d.setPath(p.left(i)+"/"+s);
673 systemFlags->activate("vymLink");
677 systemFlags->deactivate("vymLink");
680 calcBBoxSize(); // recalculate bbox
681 positionBBox(); // rearrange contents
685 QString BranchObj::getVymLink()
690 QString BranchObj::saveToDir (const QString &tmpdir,const QString &prefix, const QPoint& offset)
693 QString scrolledAttr;
695 scrolledAttr=attribut ("scrolled","yes");
700 if (depth<2) posAttr=
701 attribut("absPosX",QString().setNum(absPos.x(),10)) +
702 attribut("absPosY",QString().setNum(absPos.y(),10));
708 urlAttr=attribut ("url",url);
711 if (!vymLink.isEmpty())
712 vymLinkAttr=attribut ("vymLink",convertToRel(mapEditor->getDestPath(),vymLink) );
715 if (frame->getFrameType()!=NoFrame)
716 frameAttr=attribut ("frameType",frame->getFrameTypeName());
720 // save area, if not scrolled
722 if (!((BranchObj*)(parObj))->isScrolled() )
725 attribut("x1",QString().setNum(absPos.x()-offset.x(),10)) +
726 attribut("y1",QString().setNum(absPos.y()-offset.y(),10)) +
727 attribut("x2",QString().setNum(absPos.x()+width()-offset.x(),10)) +
728 attribut("y2",QString().setNum(absPos.y()+height()-offset.y(),10));
733 s=beginElement ("branch" +scrolledAttr +posAttr +urlAttr +vymLinkAttr +frameAttr +areaAttr);
737 s=s+valueElement("heading", getHeading(),
738 attribut ("textColor",QColor(heading->getColor()).name()));
740 // save names of flags set
741 s+=standardFlags->saveToDir(tmpdir,prefix,0);
744 if (!note.isEmpty() )
749 for (bo=branch.first(); bo; bo=branch.next() )
750 s+=bo->saveToDir(tmpdir,prefix,offset);
755 for (fio=floatimage.first(); fio; fio=floatimage.next() )
756 s+=fio->saveToDir (tmpdir,prefix);
758 s+=endElement ("branch");
762 LinkableMapObj* BranchObj::addFloatImage ()
764 FloatImageObj *newfi=new FloatImageObj (canvas,this);
765 floatimage.append (newfi);
766 if (hasScrolledParent(this) )
767 newfi->setVisibility (false);
769 newfi->setVisibility(visible);
774 LinkableMapObj* BranchObj::addFloatImage (FloatImageObj *fio)
776 FloatImageObj *newfi=new FloatImageObj (canvas,this);
777 floatimage.append (newfi);
779 if (hasScrolledParent(this) )
780 newfi->setVisibility (false);
782 newfi->setVisibility(visible);
787 FloatImageObj* BranchObj::getFirstFloatImage ()
789 return floatimage.first();
792 FloatImageObj* BranchObj::getLastFloatImage ()
794 return floatimage.last();
797 FloatImageObj* BranchObj::getFloatImageNum (const uint &i)
799 return floatimage.at(i);
802 void BranchObj::removeFloatImage (FloatImageObj *fio)
804 floatimage.remove (fio);
808 void BranchObj::savePosInAngle ()
810 // Save position in angle
813 for (b=branch.first(); b; b=branch.next() )
820 BranchObj* BranchObj::addBranch()
822 BranchObj* newbo=new BranchObj(canvas,this);
823 branch.append (newbo);
824 newbo->setParObj(this);
825 newbo->setColor(getColor(),false);
826 newbo->setLinkColor();
827 newbo->setHeading ("new");
828 newbo->setLinkStyle (newbo->getDefLinkStyle());
830 newbo->setVisibility (false);
832 newbo->setVisibility(visible);
837 BranchObj* BranchObj::addBranch(BranchObj* bo)
839 BranchObj* newbo=new BranchObj(canvas,this);
840 branch.append (newbo);
842 newbo->setParObj(this);
843 newbo->setHeading (newbo->getHeading()); // adjust fontsize to depth
844 newbo->setLinkStyle (newbo->getDefLinkStyle());
846 newbo->setVisibility (false);
848 newbo->setVisibility(bo->visible);
853 BranchObj* BranchObj::insertBranch(int pos)
856 // Add new bo and resort branches
857 BranchObj *newbo=addBranch ();
858 newbo->angle=pos-0.5;
863 BranchObj* BranchObj::insertBranch(BranchObj* bo, int pos)
866 // Add new bo and resort branches
868 BranchObj *newbo=addBranch (bo);
873 void BranchObj::removeBranch(BranchObj* bo)
875 // if bo is not in branch remove returns false, we
881 void BranchObj::setLastSelectedBranch (BranchObj* bo)
883 lastSelectedBranch=branch.find(bo);
886 BranchObj* BranchObj::getLastSelectedBranch ()
888 if (lastSelectedBranch>=0)
890 BranchObj* bo=branch.at(lastSelectedBranch);
893 return branch.first();
896 BranchObj* BranchObj::getFirstBranch ()
898 return branch.first();
901 BranchObj* BranchObj::getLastBranch ()
903 return branch.last();
906 BranchObj* BranchObj::getBranchNum (const uint &i)
912 BranchObj* BranchObj::moveBranchUp(BranchObj* bo1) // move a branch up (modify myself)
915 int i=branch.find(bo1);
917 { // -1 if bo1 not found
918 branch.at(i)->angle--;
919 branch.at(i-1)->angle++;
921 return branch.at(i-1);
926 BranchObj* BranchObj::moveBranchDown(BranchObj* bo1)
929 int i=branch.find(bo1);
934 branch.at(i)->angle++;
935 branch.at(j)->angle--;
942 void BranchObj::alignRelativeTo (QPoint ref)
945 if (!getHeading().isEmpty())
946 cout << "BO::alignRelTo "<<getHeading()<<endl;
948 cout << "BO::alignRelTo ???"<<endl;
949 cout << " d="<<depth<<endl;
951 int th = bboxTotal.height();
953 // If I am the mapcenter or a mainbranch, reposition heading
956 move (absPos.x(),absPos.y());
959 // Calc angle to mapCenter if I am a mainbranch
960 // needed for reordering the mainbranches clockwise
962 angle=getAngle (QPoint ((int)(x() - parObj->getChildPos().x() ),
963 (int)(y() - parObj->getChildPos().y() ) ) );
968 // Align myself depending on orientation and parent, but
969 // only if I am not the mainbranch or mapcenter itself
972 case OrientLeftOfCenter:
973 move (ref.x()-bbox.width(), ref.y() + (th-bbox.height())/2 );
975 case OrientRightOfCenter:
976 move (ref.x(), ref.y() + (th-bbox.height())/2 );
979 cout <<"LMO::alignRelativeTo: oops, no orientation given...\n";
985 for (fio=floatimage.first(); fio; fio=floatimage.next() )
988 if (scrolled) return;
990 // Set reference point for alignment of childs
992 if (orientation==OrientLeftOfCenter)
993 ref2.setX(childPos.x() - linkwidth);
995 ref2.setX(childPos.x() + linkwidth);
998 ref2.setY(absPos.y()-(bboxTotal.height()-bbox.height())/2);
1000 ref2.setY(ref.y() );
1002 // Align the childs depending on reference point
1004 for (b=branch.first(); b; b=branch.next() )
1006 b->alignRelativeTo (ref2);
1007 ref2.setY(ref2.y() + b->getBBoxSizeWithChilds().height() );
1012 void BranchObj::reposition()
1015 if (!getHeading().isEmpty())
1016 cout << "BO::reposition "<<getHeading()<<endl;
1018 cout << "BO::reposition ???"<<endl;
1022 // only calculate the sizes once. If the deepest LMO
1023 // changes its height,
1024 // all upper LMOs have to change, too.
1025 calcBBoxSizeWithChilds();
1026 alignRelativeTo ( QPoint (absPos.x(),
1027 absPos.y()-(bboxTotal.height()-bbox.height())/2) );
1031 // This is only important for moving branches:
1032 // For editing a branch it isn't called...
1033 alignRelativeTo ( QPoint (absPos.x(),
1034 absPos.y()-(bboxTotal.height()-bbox.height())/2) );
1039 QRect BranchObj::getTotalBBox()
1043 if (scrolled) return r;
1046 for (b=branch.first();b ;b=branch.next() )
1047 r=addBBox(b->getTotalBBox(),r);
1050 for (fio=floatimage.first();fio ;fio=floatimage.next() )
1051 r=addBBox(fio->getTotalBBox(),r);
1056 QRect BranchObj::getBBoxSizeWithChilds()
1061 void BranchObj::calcBBoxSizeWithChilds()
1063 // This is called only from reposition and
1064 // and only for mapcenter. So it won't be
1065 // called more than once for a single user
1068 // Calculate size of LMO including all childs (to align them later)
1070 bboxTotal.setX(bbox.x() );
1071 bboxTotal.setY(bbox.y() );
1073 // if branch is scrolled, ignore childs, but still consider floatimages
1076 bboxTotal.setWidth (bbox.width());
1077 bboxTotal.setHeight(bbox.height());
1083 // Now calculate recursivly
1085 // maximum of widths
1088 for (b=branch.first();b ;b=branch.next() )
1090 b->calcBBoxSizeWithChilds();
1091 br=b->getBBoxSizeWithChilds();
1092 r.setWidth( max (br.width(), r.width() ));
1093 r.setHeight(br.height() + r.height() );
1094 if (br.y()<bboxTotal.y()) bboxTotal.setY(br.y());
1096 // Add myself and also
1097 // add width of link to sum if necessary
1098 if (branch.isEmpty())
1099 bboxTotal.setWidth (bbox.width() + r.width() );
1101 bboxTotal.setWidth (bbox.width() + r.width() + linkwidth);
1102 bboxTotal.setHeight(max (r.height(), bbox.height() ) );
1103 // frame->setRect(QRect(bbox.x(),bbox.y(),bbox.width(),bbox.height() ) );
1106 void BranchObj::select()
1108 LinkableMapObj::select();
1109 // Tell parent that I am selected now:
1110 BranchObj* po=(BranchObj*)(parObj);
1111 if (po) // TODO Try to get rid of this cast...
1112 po->setLastSelectedBranch(this);
1114 // temporary unscroll, if we have scrolled parents somewhere
1115 if (parObj) ((BranchObj*)(parObj))->tmpUnscroll();
1117 // set Text in Editor
1118 textEditor->setText(note.getNote() );
1119 textEditor->setFilename(note.getFilenameHint() );
1120 textEditor->setFontHint (note.getFontHint() );
1121 connect (textEditor, SIGNAL (textHasChanged() ), this, SLOT (updateNoteFlag() ) );
1122 connect (textEditor, SIGNAL (fontSizeHasChanged() ), this, SLOT (updateNoteFlag() ) );
1124 // Show URL and link in statusbar
1126 if (!url.isEmpty()) status+="URL: "+url+" ";
1127 if (!vymLink.isEmpty()) status+="Link: "+vymLink;
1128 if (!status.isEmpty()) mainWindow->statusMessage (status);
1131 standardFlags->updateToolBar();
1133 // Update Browserbutton
1135 actionEditOpenURL->setEnabled (true);
1137 actionEditOpenURL->setEnabled (false);
1139 // Update actions in mapeditor
1140 mapEditor->updateActions();
1143 void BranchObj::unselect()
1145 LinkableMapObj::unselect();
1146 // Delete any messages like vymLink in StatusBar
1147 mainWindow->statusMessage ("");
1149 // save note from editor and set flag
1150 // text is done by updateNoteFlag(), just save
1152 note.setFilenameHint (textEditor->getFilename());
1154 // reset temporary unscroll, if we have scrolled parents somewhere
1155 if (parObj) ((BranchObj*)(parObj))->resetTmpUnscroll();
1157 // Disconnect textEditor from this LMO
1158 disconnect( textEditor, SIGNAL(textHasChanged()), 0, 0 );
1159 disconnect( textEditor, SIGNAL (fontSizeHasChanged()),0,0 );
1161 // Erase content of editor
1162 textEditor->setInactive();
1164 // unselect all buttons in toolbar
1165 standardFlagsDefault->updateToolBar();
1168 QString BranchObj::getSelectString()
1173 if (parObj->getDepth()==0)
1174 s= "bo:" + QString("%1").arg(getNum());
1176 s= ((BranchObj*)(parObj))->getSelectString() + ",bo:" + QString("%1").arg(getNum());