9 #include "branchitem.h"
10 #include "mainwindow.h"
12 #include "warningdialog.h"
15 extern int statusbarTime;
16 extern Main *mainWindow;
17 extern QString tmpVymDir;
18 extern QString clipboardDir;
19 extern QString clipboardFile;
20 extern bool clipboardEmpty;
23 extern QMenu* branchContextMenu;
24 extern QMenu* branchAddContextMenu;
25 extern QMenu* branchRemoveContextMenu;
26 extern QMenu* branchLinksContextMenu;
27 extern QMenu* branchXLinksContextMenuEdit;
28 extern QMenu* branchXLinksContextMenuFollow;
29 extern QMenu* floatimageContextMenu;
30 extern QMenu* canvasContextMenu;
32 extern Settings settings;
33 extern QString iconPath;
35 ///////////////////////////////////////////////////////////////////////
36 ///////////////////////////////////////////////////////////////////////
37 MapEditor::MapEditor( VymModel *vm)
39 //cout << "Constructor ME "<<this<<endl;
40 mapScene= new QGraphicsScene(NULL);
41 mapScene->setBackgroundBrush (QBrush(Qt::white, Qt::SolidPattern));
43 zoomFactor=zoomFactorTarget=1;
46 model->setScene (mapScene);
47 model->registerEditor(this);
48 // model->addMapCenter(); // FIXME-3 create this in MapEditor until BO and MCO are independent of scene
49 model->makeDefault(); // No changes in model so far
55 // Create bitmap cursors, platform dependant
56 HandOpenCursor=QCursor (QPixmap(iconPath+"cursorhandopen.png"),1,1);
57 PickColorCursor=QCursor ( QPixmap(iconPath+"cursorcolorpicker.png"), 5,27 );
58 CopyCursor=QCursor ( QPixmap(iconPath+"cursorcopy.png"), 1,1 );
59 XLinkCursor=QCursor ( QPixmap(iconPath+"cursorxlink.png"), 1,7 );
61 setFocusPolicy (Qt::StrongFocus);
73 setAcceptDrops (true);
75 //model->reposition(); //FIXME-3 really still needed?
78 // Action to embed LineEdit for heading in Scene
80 lineEdit=new QLineEdit;
82 QGraphicsProxyWidget *pw=scene()->addWidget (lineEdit);
85 QAction *a = new QAction( tr( "Edit heading","MapEditor" ), this);
86 a->setShortcut ( Qt::Key_Return ); //Edit heading
88 connect( a, SIGNAL( triggered() ), this, SLOT( editHeading() ) );
89 a = new QAction( tr( "Edit heading","MapEditor" ), this);
90 a->setShortcut ( Qt::Key_Enter); //Edit heading
92 connect( a, SIGNAL( triggered() ), this, SLOT( editHeading() ) );
95 selectionColor =QColor (255,255,0);
98 // Attributes //FIXME-2 testing only...
101 attrTable= new AttributeTable();
103 ad=attrTable->addKey (k,StringList);
107 sl <<"val 1"<<"val 2"<< "val 3";
108 ad->setValue (QVariant (sl));
110 //attrTable->addValue ("Key A","P 1");
111 //attrTable->addValue ("Key A","P 2");
112 //attrTable->addValue ("Key A","P 3");
113 //attrTable->addValue ("Key A","P 4");
115 ad=attrTable->addKey (k,FreeString);
118 //attrTable->addValue ("Key B","w1");
119 //attrTable->addValue ("Key B","w2");
121 k="C - UniqueString";
122 ad=attrTable->addKey (k,UniqueString);
125 //attrTable->addKey ("Key Prio");
126 //attrTable->addValue ("Key Prio","Prio 1");
127 //attrTable->addValue ("Key Prio","Prio 2");
131 MapEditor::~MapEditor()
133 //cout <<"Destructor MapEditor for "<<model->getMapName().toStdString()<<endl;
134 // No need to remove tmp files:
135 // tmpMapDir is in tmpVymDir,
136 // so it gets removed automagically when vym closes
138 model->unregisterEditor(this);
141 VymModel* MapEditor::getModel()
146 QGraphicsScene * MapEditor::getScene()
151 void MapEditor::setScrollBarPosTarget (const QRectF &rect)
153 // Code copied from Qt sources
157 qreal width = viewport()->width();
158 qreal height = viewport()->height();
159 QRectF viewRect = matrix().mapRect(rect);
161 qreal left = horizontalScrollBar()->value();
162 qreal right = left + width;
163 qreal top = verticalScrollBar()->value();
164 qreal bottom = top + height;
166 if (viewRect.left() <= left + xmargin) {
167 // need to scroll from the left
168 // if (!d->leftIndent)
169 scrollBarPosTarget.setX(int(viewRect.left() - xmargin - 0.5));
171 if (viewRect.right() >= right - xmargin) {
172 // need to scroll from the right
173 // if (!d->leftIndent)
174 scrollBarPosTarget.setX(int(viewRect.right() - width + xmargin + 0.5));
176 if (viewRect.top() <= top + ymargin) {
177 // need to scroll from the top
178 // if (!d->topIndent)
179 scrollBarPosTarget.setY(int(viewRect.top() - ymargin - 0.5));
181 if (viewRect.bottom() >= bottom - ymargin) {
182 // need to scroll from the bottom
183 // if (!d->topIndent)
184 scrollBarPosTarget.setY(int(viewRect.bottom() - height + ymargin + 0.5));
187 if (scrollBarPosAnimation.state()==QtAbstractAnimation::Running)
188 scrollBarPosAnimation.stop();
189 scrollBarPosAnimation.setTargetObject (this);
190 scrollBarPosAnimation.setPropertyName ("scrollBarPos");
191 scrollBarPosAnimation.setDuration(1000);
192 scrollBarPosAnimation.setEasingCurve ( QtEasingCurve::OutQuint);
193 scrollBarPosAnimation.setStartValue(
194 QPointF (horizontalScrollBar()->value() ,
195 verticalScrollBar()->value() ) );
196 scrollBarPosAnimation.setEndValue(scrollBarPosTarget);
197 scrollBarPosAnimation.start();
200 QPointF MapEditor::getScrollBarPosTarget()
202 return scrollBarPosTarget;
206 void MapEditor::setScrollBarPos(const QPointF &p)
209 horizontalScrollBar()->setValue(int(p.x()));
210 verticalScrollBar()->setValue(int(p.y()));
213 QPointF MapEditor::getScrollBarPos()
218 void MapEditor::setZoomFactorTarget (const qreal &zft)
220 zoomFactorTarget=zft;
221 if (zoomAnimation.state()==QtAbstractAnimation::Running)
222 zoomAnimation.stop();
223 //zoomAnimation=QtPropertyAnimation(this, "zoomFactor");
224 zoomAnimation.setTargetObject (this);
225 zoomAnimation.setPropertyName ("zoomFactor");
226 zoomAnimation.setDuration(1000);
227 zoomAnimation.setEasingCurve ( QtEasingCurve::OutQuint);
228 zoomAnimation.setStartValue(zoomFactor);
229 zoomAnimation.setEndValue(zft);
230 zoomAnimation.start();
233 qreal MapEditor::getZoomFactorTarget()
235 return zoomFactorTarget;
239 void MapEditor::setZoomFactor(const qreal &zf)
242 setMatrix (QMatrix(zf, 0, 0, zf, 0, 0),false );
245 qreal MapEditor::getZoomFactor()
250 void MapEditor::print()
254 printer = new QPrinter;
255 printer->setColorMode (QPrinter::Color);
256 printer->setPrinterName (settings.value("/mainwindow/printerName",printer->printerName()).toString());
257 printer->setOutputFormat((QPrinter::OutputFormat)settings.value("/mainwindow/printerFormat",printer->outputFormat()).toInt());
258 printer->setOutputFileName(settings.value("/mainwindow/printerFileName",printer->outputFileName()).toString());
261 QRectF totalBBox=model->getTotalBBox();
263 // Try to set orientation automagically
264 // Note: Interpretation of generated postscript is amibiguous, if
265 // there are problems with landscape mode, see
266 // http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html
268 if (totalBBox.width()>totalBBox.height())
269 // recommend landscape
270 printer->setOrientation (QPrinter::Landscape);
272 // recommend portrait
273 printer->setOrientation (QPrinter::Portrait);
275 if ( printer->setup(this) )
276 // returns false, if printing is canceled
278 QPainter pp(printer);
280 pp.setRenderHint(QPainter::Antialiasing,true);
282 // Don't print the visualisation of selection
285 QRectF mapRect=totalBBox;
286 QGraphicsRectItem *frame=NULL;
290 // Print frame around map
291 mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10,
292 totalBBox.width()+20, totalBBox.height()+20);
293 frame=mapScene->addRect (mapRect, QPen(Qt::black),QBrush(Qt::NoBrush));
299 double paperAspect = (double)printer->width() / (double)printer->height();
300 double mapAspect = (double)mapRect.width() / (double)mapRect.height();
302 if (mapAspect>=paperAspect)
304 // Fit horizontally to paper width
305 //pp.setViewport(0,0, printer->width(),(int)(printer->width()/mapAspect) );
306 viewBottom=(int)(printer->width()/mapAspect);
309 // Fit vertically to paper height
310 //pp.setViewport(0,0,(int)(printer->height()*mapAspect),printer->height());
311 viewBottom=printer->height();
316 // Print footer below map
318 font.setPointSize(10);
320 QRectF footerBox(0,viewBottom,printer->width(),15);
321 // FIXME-3 fileName not any longer available here: pp.drawText ( footerBox,Qt::AlignLeft,"VYM - " +fileName);
322 pp.drawText ( footerBox, Qt::AlignRight, QDate::currentDate().toString(Qt::TextDate));
326 QRectF (0,0,printer->width(),printer->height()-15),
327 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height())
330 // Viewport has paper dimension
331 if (frame) delete (frame);
336 // Save settings in vymrc
337 settings.writeEntry("/mainwindow/printerName",printer->printerName());
338 settings.writeEntry("/mainwindow/printerFormat",printer->outputFormat());
339 settings.writeEntry("/mainwindow/printerFileName",printer->outputFileName());
343 void MapEditor::setAntiAlias (bool b)
345 setRenderHint(QPainter::Antialiasing,b);
348 void MapEditor::setSmoothPixmap(bool b)
350 setRenderHint(QPainter::SmoothPixmapTransform,b);
353 TreeItem* MapEditor::findMapItem (QPointF p,TreeItem *exclude)
355 // Start with mapcenter, no images allowed at rootItem
357 BranchItem *bi=model->getRootItem()->getFirstBranch();
358 TreeItem *found=NULL;
361 found=bi->findMapItem (p, exclude);
362 if (found) return found;
364 bi=model->getRootItem()->getBranchNum(i);
369 AttributeTable* MapEditor::attributeTable()
374 void MapEditor::testFunction1()
377 // Code copied from Qt sources
378 QRectF rect=model->getSelectedBranchObj()->getBBox();
382 qreal width = viewport()->width();
383 qreal height = viewport()->height();
384 QRectF viewRect = matrix().mapRect(rect);
386 qreal left = horizontalScrollBar()->value();
387 qreal right = left + width;
388 qreal top = verticalScrollBar()->value();
389 qreal bottom = top + height;
391 if (viewRect.left() <= left + xmargin) {
392 // need to scroll from the left
393 // if (!d->leftIndent)
394 horizontalScrollBar()->setValue(int(viewRect.left() - xmargin - 0.5));
396 if (viewRect.right() >= right - xmargin) {
397 // need to scroll from the right
398 // if (!d->leftIndent)
399 horizontalScrollBar()->setValue(int(viewRect.right() - width + xmargin + 0.5));
401 if (viewRect.top() <= top + ymargin) {
402 // need to scroll from the top
403 // if (!d->topIndent)
404 verticalScrollBar()->setValue(int(viewRect.top() - ymargin - 0.5));
406 if (viewRect.bottom() >= bottom - ymargin) {
407 // need to scroll from the bottom
408 // if (!d->topIndent)
409 verticalScrollBar()->setValue(int(viewRect.bottom() - height + ymargin + 0.5));
411 cout << "test1: hor="<<horizontalScrollBar()->value()<<endl;
412 cout << "test1: ver="<<verticalScrollBar()->value()<<endl;
415 QtPropertyAnimation *animation=new QtPropertyAnimation(this, "sceneRect");
416 animation->setDuration(5000);
417 //animation->setEasingCurve ( QtEasingCurve::OutElastic);
418 animation->setEasingCurve ( QtEasingCurve::OutQuint);
419 animation->setStartValue(sceneRect() );
420 animation->setEndValue(QRectF(50, 50, 1000, 1000));
425 QDialog *dia= new QDialog (this);
426 dia->setGeometry (50,50,10,10);
431 QtPropertyAnimation *animation=new QtPropertyAnimation(dia, "geometry");
432 animation->setDuration(1000);
433 //animation->setEasingCurve ( QtEasingCurve::OutElastic);
434 animation->setEasingCurve ( QtEasingCurve::OutQuint);
435 animation->setStartValue(QRect(50, 50, 10, 10));
436 animation->setEndValue(QRect(250, 250, 100, 100));
441 /* TODO Hide hidden stuff temporary, maybe add this as regular function somewhere
442 if (hidemode==HideNone)
444 setHideTmpMode (HideExport);
445 mapCenter->calcBBoxSizeWithChilds();
446 QRectF totalBBox=mapCenter->getTotalBBox();
447 QRectF mapRect=totalBBox;
448 QCanvasRectangle *frame=NULL;
450 cout << " map has =("<<totalBBox.x()<<","<<totalBBox.y()<<","<<totalBBox.width()<<","<<totalBBox.height()<<")\n";
452 mapRect.setRect (totalBBox.x(), totalBBox.y(),
453 totalBBox.width(), totalBBox.height());
454 frame=new QCanvasRectangle (mapRect,mapScene);
455 frame->setBrush (QColor(white));
456 frame->setPen (QColor(black));
462 setHideTmpMode (HideNone);
464 cout <<" hidemode="<<hidemode<<endl;
467 void MapEditor::testFunction2()
472 if (hidemode==HideExport)
473 setHideTmpMode (HideNone);
475 setHideTmpMode (HideExport);
479 void MapEditor::editHeading()
483 editHeadingFinished();
486 BranchObj *bo=model->getSelectedBranchObj();
487 BranchItem *bi=model->getSelectedBranchItem();
490 model->setSelectionBlocked(true);
492 lineEdit->setText (bi->getHeading());
493 QPoint p = mapTo (this,bo->getAbsPos().toPoint() );
494 lineEdit->setGeometry(p.x(),p.y(),230,25);
495 lineEdit->selectAll();
497 lineEdit->setFocus();
498 lineEdit->grabKeyboard();
503 void MapEditor::editHeadingFinished()
505 editingHeading=false;
506 lineEdit->releaseKeyboard();
507 model->setHeading (lineEdit->text() );
508 model->setSelectionBlocked(false);
511 // Maybe reselect previous branch
512 mainWindow->editHeadingFinished (model);
516 void MapEditor::contextMenuEvent ( QContextMenuEvent * e )
518 // Lineedits are already closed by preceding
519 // mouseEvent, we don't need to close here.
521 QPointF p = mapToScene(e->pos());
522 TreeItem *ti=findMapItem (p, NULL);
523 LinkableMapObj* lmo=NULL;
524 if (ti) lmo=ti->getLMO(); //FIXME-2 get rid of lmo...
527 { // MapObj was found
528 if (model->getSelectedLMO() != lmo)
534 if (model->getSelectedBranchObj() )
536 // Context Menu on branch or mapcenter
537 //FIXME-3 model->updateActions(); needed?
538 branchContextMenu->popup(e->globalPos() );
541 if (model->getSelectedFloatImage() )
543 // Context Menu on floatimage
544 // model->updateActions(); FIXME-3 needed?
545 floatimageContextMenu->popup(e->globalPos() );
549 { // No MapObj found, we are on the Canvas itself
550 // Context Menu on scene
551 // model->updateActions(); FIXME-3 needed?
553 // Open context menu synchronously to position new mapcenter
554 model->setContextPos (p);
555 canvasContextMenu->exec(e->globalPos() );
556 model->unsetContextPos ();
561 void MapEditor::keyPressEvent(QKeyEvent* e)
563 if (e->modifiers() & Qt::ControlModifier)
565 switch (mainWindow->getModMode())
567 case Main::ModModeColor:
568 setCursor (PickColorCursor);
570 case Main::ModModeCopy:
571 setCursor (CopyCursor);
573 case Main::ModModeXLink:
574 setCursor (XLinkCursor);
577 setCursor (Qt::ArrowCursor);
583 void MapEditor::keyReleaseEvent(QKeyEvent* e)
585 if (!(e->modifiers() & Qt::ControlModifier))
586 setCursor (Qt::ArrowCursor);
589 void MapEditor::mousePressEvent(QMouseEvent* e)
591 // Ignore right clicks, these will go to context menus
592 if (e->button() == Qt::RightButton )
598 //Ignore clicks while editing heading
599 if (model->isSelectionBlocked() )
605 QPointF p = mapToScene(e->pos());
606 TreeItem *ti=findMapItem (p, NULL);
607 LinkableMapObj* lmo=NULL;
608 if (ti) lmo=ti->getLMO(); //FIXME-2 get rid of lmo...
612 //Take care of system flags _or_ modifier modes
614 if (lmo && (typeid(*lmo)==typeid(BranchObj) ||
615 typeid(*lmo)==typeid(MapCenterObj) ))
617 QString foname=((BranchObj*)lmo)->getSystemFlagName(p);
618 if (!foname.isEmpty())
620 // systemFlag clicked
621 model->select (lmo); // FIXME-3 was selectInt
624 if (e->state() & Qt::ControlModifier)
625 mainWindow->editOpenURLTab();
627 mainWindow->editOpenURL();
629 else if (foname=="vymLink")
631 mainWindow->editOpenVymLink();
632 // tabWidget may change, better return now
633 // before segfaulting...
634 } else if (foname=="note")
635 mainWindow->windowToggleNoteEditor();
636 else if (foname=="hideInExport")
637 model->toggleHideExport();
638 // FIXME-3 needed? xelection.update();
642 // No system flag clicked, take care of modmodes (CTRL-Click)
643 if (e->state() & Qt::ControlModifier)
645 if (mainWindow->getModMode()==Main::ModModeColor)
648 setCursor (PickColorCursor);
651 if (mainWindow->getModMode()==Main::ModModeXLink)
653 BranchObj *bo_begin=NULL;
655 bo_begin=(BranchObj*)(lmo);
657 bo_begin=model->getSelectedBranchObj();
661 linkingObj_src=bo_begin;
662 tmpXLink=new XLinkObj (mapScene);
663 tmpXLink->setBegin (bo_begin);
664 tmpXLink->setEnd (p);
665 tmpXLink->setColor(model->getMapDefXLinkColor());
666 tmpXLink->setWidth(model->getMapDefXLinkWidth());
667 tmpXLink->updateXLink();
668 tmpXLink->setVisibility (true);
677 cout << "ME::mouse pressed\n";
678 cout << " lmo="<<lmo<<endl;
679 cout << " h="<<((BranchObj*)lmo)->getHeading().toStdString()<<endl;
681 // Select the clicked object
683 // FIXME-2 VM better let "find" return an index instead of lmo...
684 // Get index of clicked LMO
685 TreeItem *ti=lmo->getTreeItem();
687 cout << " lmo="<<lmo<<" lmo(ti)="<<ti->getLMO()<<endl;
688 cout << " ti ("<<ti->row()<<","<<ti->column()<<") = "<<ti<<endl;
690 //QModelIndex ix=model->index( ti->row(), ti->column(), model->index (0,0,QModelIndex()) );
693 // Left Button Move Branches
694 if (e->button() == Qt::LeftButton )
696 //movingObj_start.setX( p.x() - selection->x() );// TODO replaced selection->lmo here
697 //movingObj_start.setY( p.y() - selection->y() );
698 movingObj_start.setX( p.x() - lmo->x() );
699 movingObj_start.setY( p.y() - lmo->y() );
700 movingObj_orgPos.setX (lmo->x() );
701 movingObj_orgPos.setY (lmo->y() );
703 movingObj_orgRelPos=lmo->getRelPos();
705 // If modMode==copy, then we want to "move" the _new_ object around
706 // then we need the offset from p to the _old_ selection, because of tmp
707 if (mainWindow->getModMode()==Main::ModModeCopy &&
708 e->state() & Qt::ControlModifier)
710 BranchItem *bi=model->getSelectedBranchItem();
714 //FIXME-2 TreeItem::addBranch (BranchItem still missing)
715 //bi->addBranch (model->getSelectedBranchItem());
717 model->select(bi->getLastBranch());
722 movingObj=model->getSelectedLMO();
724 // Middle Button Toggle Scroll
725 // (On Mac OS X this won't work, but we still have
726 // a button in the toolbar)
727 if (e->button() == Qt::MidButton )
728 model->toggleScroll();
729 // model->updateActions(); FIXME-3 needed?
730 // FIXME-3 needed? xelection.update();
732 { // No MapObj found, we are on the scene itself
733 // Left Button move Pos of sceneView
734 if (e->button() == Qt::LeftButton )
736 movingObj=NULL; // move Content not Obj
737 movingObj_start=e->globalPos();
738 movingCont_start=QPointF (
739 horizontalScrollBar()->value(),
740 verticalScrollBar()->value());
741 movingVec=QPointF(0,0);
742 setCursor(HandOpenCursor);
747 void MapEditor::mouseMoveEvent(QMouseEvent* e)
749 QPointF p = mapToScene(e->pos());
750 TreeItem *seli=model->getSelectedItem();
751 LinkableMapObj* lmosel=NULL; //FIXME-2 get rid of lmosel
753 lmosel=seli->getLMO();
755 // Move the selected MapObj
756 if ( lmosel && movingObj)
758 // reset cursor if we are moving and don't copy
759 if (mainWindow->getModMode()!=Main::ModModeCopy)
760 setCursor (Qt::ArrowCursor);
762 // To avoid jumping of the sceneView, only
763 // show selection, if not tmp linked
764 if (!lmosel->hasParObjTmp())
765 model->emitShowSelection();
767 // Now move the selection, but add relative position
768 // (movingObj_start) where selection was chosen with
769 // mousepointer. (This avoids flickering resp. jumping
770 // of selection back to absPos)
772 // Check if we could link
773 TreeItem *dsti=findMapItem (p, seli);
774 LinkableMapObj* dst=NULL;
775 if (dsti) dst=dsti->getLMO(); //FIXME-2 get rid of lmo...
778 FloatObj *fio=model->getSelectedFloatImage();
781 fio->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
783 fio->updateLink(); //no need for reposition, if we update link here
784 model->updateSelection(); // position has changed
786 // Relink float to new mapcenter or branch, if shift is pressed
787 // Only relink, if selection really has a new parent
788 if ( (e->modifiers()==Qt::ShiftModifier) && dst &&
789 ( (typeid(*dst)==typeid(BranchObj)) ||
790 (typeid(*dst)==typeid(MapCenterObj)) ) &&
791 ( dst != fio->getParObj())
794 if (typeid(*fio) == typeid(FloatImageObj) &&
795 ( (typeid(*dst)==typeid(BranchObj) ||
796 typeid(*dst)==typeid(MapCenterObj)) ))
799 // Also save the move which was done so far
800 QString pold=qpointfToString(movingObj_orgRelPos);
801 QString pnow=qpointfToString(fio->getRelPos());
803 fio->getTreeItem(), // FIXME-3
807 QString("Move %1 to relative position %2").arg(model->getObjectName(fio)).arg(pnow));
808 fio->getParObj()->requestReposition();
811 model->linkFloatImageTo (model->getSelectString(dst));
813 //movingObj_orgRelPos=lmosel->getRelPos();
819 { // selection != a FloatObj
820 if (seli->depth()==0) //FIXME-1 also moved mapcenters could be linked, but not working here...
823 if (e->buttons()== Qt::LeftButton && e->modifiers()==Qt::ShiftModifier)
824 ((MapCenterObj*)lmosel)->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
826 lmosel->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
827 model->updateRelPositions();
830 if (seli->depth()==1)
833 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
837 // Move ordinary branch
838 if (lmosel->getOrientation() == LinkableMapObj::LeftOfCenter)
839 // Add width of bbox here, otherwise alignRelTo will cause jumping around
840 lmosel->move(p.x() -movingObj_start.x() , //lmosel->getBBox().width(),
841 p.y()-movingObj_start.y() +lmosel->getTopPad() );
843 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() -lmosel->getTopPad());
847 // Maybe we can relink temporary?
848 if (dsti && (dst!=lmosel) && seli->isBranchLikeType() && dsti->isBranchLikeType() )
850 if (e->modifiers()==Qt::ControlModifier)
852 // Special case: CTRL to link below dst
853 lmosel->setParObjTmp (dst,p,+1);
855 else if (e->modifiers()==Qt::ShiftModifier)
856 lmosel->setParObjTmp (dst,p,-1);
858 lmosel->setParObjTmp (dst,p,0);
861 lmosel->unsetParObjTmp();
863 // reposition subbranch
864 lmosel->reposition();
867 QItemSelection sel=model->getSelectionModel()->selection();
868 updateSelection(sel,sel); // position has changed
870 } // no FloatImageObj
874 } // selection && moving_obj
876 // Draw a link from one branch to another
879 tmpXLink->setEnd (p);
880 tmpXLink->updateXLink();
884 if (!movingObj && !pickingColor &&!drawingLink && e->buttons() == Qt::LeftButton )
886 QPointF p=e->globalPos();
887 movingVec.setX(-p.x() + movingObj_start.x() );
888 movingVec.setY(-p.y() + movingObj_start.y() );
889 horizontalScrollBar()->setSliderPosition((int)( movingCont_start.x()+movingVec.x() ));
890 verticalScrollBar()->setSliderPosition((int)( movingCont_start.y()+movingVec.y() ) );
895 void MapEditor::mouseReleaseEvent(QMouseEvent* e)
897 QPointF p = mapToScene(e->pos());
898 TreeItem *seli=model->getSelectedItem();
900 TreeItem *dsti=findMapItem(p, seli);
901 LinkableMapObj* dst=NULL;
902 if (dsti) dst=dsti->getLMO(); //FIXME-2 get rid of dst...
905 // Have we been picking color?
909 setCursor (Qt::ArrowCursor);
910 // Check if we are over another branch
913 if (e->state() & Qt::ShiftModifier)
914 model->colorBranch (((BranchObj*)dst)->getColor());
916 model->colorSubtree (((BranchObj*)dst)->getColor());
921 // Have we been drawing a link?
925 // Check if we are over another branch
926 if (dsti && seli && dsti->isBranchLikeType() )
928 tmpXLink->setEnd ( ((BranchObj*)(dst)) );
929 tmpXLink->updateXLink();
930 tmpXLink->activate(); //FIXME-2 savestate missing
931 //model->saveStateComplete(QString("Activate xLink from %1 to %2").arg(model->getObjectName(tmpXLink->getBegin())).arg(model->getObjectName(tmpXLink->getEnd())) );
940 // Have we been moving something?
941 if ( seli && movingObj )
948 FloatImageObj *fo=model->getSelectedFloatImage();
951 // Moved FloatObj. Maybe we need to reposition
952 QString pold=qpointfToString(movingObj_orgRelPos);
953 QString pnow=qpointfToString(fo->getRelPos());
955 fo->getTreeItem(), // FIXME-3
957 fo->getTreeItem(), // FIXME-3
959 QString("Move %1 to relative position %2").arg(model->getObjectName(fo)).arg(pnow));
961 fo->getParObj()->requestReposition();
965 // Check if we are over another branch, but ignore
966 // any found LMOs, which are FloatObjs
968 if (dsti && (!dsti->isBranchLikeType() ))
974 BranchItem *bi=model->getSelectedBranchItem();
975 if (bi && bi->depth()==0)
977 if (movingObj_orgPos != bi->getBranchObj()->getAbsPos()) // FIXME-3 check getBO here...
979 QString pold=qpointfToString(movingObj_orgPos);
980 QString pnow=qpointfToString(bi->getBranchObj()->getAbsPos()); // FIXME-3 check getBO here...
987 QString("Move mapcenter %1 to position %2").arg(model->getObjectName(bi)).arg(pnow));
991 if (seli->getType() == TreeItem::Branch )
992 { // A branch was moved
993 LinkableMapObj* lmosel=NULL; //FIXME-2 get rid of lmosel
994 lmosel=seli->getLMO();
996 // save the position in case we link to mapcenter
997 QPointF savePos=QPointF (lmosel->getAbsPos() );
999 // Reset the temporary drawn link to the original one
1000 lmosel->unsetParObjTmp();
1002 // For Redo we may need to save original selection
1003 QString preSelStr=model->getSelectString(lmosel);
1006 if (dsti && dsti->isBranchLikeType() )
1008 // We have a destination, relink to that
1010 BranchObj* bsel=model->getSelectedBranchObj();
1012 QString preParStr=model->getSelectString (bsel->getParObj());
1013 QString preNum=QString::number (seli->num(),10);
1014 QString preDstParStr;
1017 if (e->state() & Qt::ShiftModifier && dst->getParObj())
1019 preDstParStr=model->getSelectString (dst->getParObj());
1020 relinked=model->relinkBranch ((BranchItem*)seli,(BranchItem*)dsti->parent(),((BranchItem*)dsti)->num());
1022 if (e->state() & Qt::ControlModifier && dst->getParObj())
1025 preDstParStr=model->getSelectString (dst->getParObj());
1026 relinked=model->relinkBranch ((BranchItem*)seli,(BranchItem*)dsti->parent(),((BranchItem*)dsti)->num()+1);
1029 preDstParStr=model->getSelectString(dst);
1030 relinked=model->relinkBranch ((BranchItem*)seli,(BranchItem*)dsti);
1031 if (dsti->depth()==0) bsel->move (savePos);
1035 QString postSelStr=model->getSelectString(lmosel);
1036 QString postNum=QString::number (seli->num(),10);
1038 QString undoCom="linkTo (\""+
1039 preParStr+ "\"," + preNum +"," +
1040 QString ("%1,%2").arg(movingObj_orgPos.x()).arg(movingObj_orgPos.y())+ ")";
1042 QString redoCom="linkTo (\""+
1043 preDstParStr + "\"," + postNum + "," +
1044 QString ("%1,%2").arg(savePos.x()).arg(savePos.y())+ ")";
1049 QString("Relink %1 to %2").arg(model->getObjectName(bsel)).arg(model->getObjectName(dst)) );
1054 // No destination, undo temporary move
1056 if (seli->depth()==1)
1058 // The select string might be different _after_ moving around.
1059 // Therefor reposition and then use string of old selection, too
1060 model->reposition();
1062 QPointF rp(lmosel->getRelPos());
1063 if (rp != movingObj_orgRelPos)
1065 QString ps=qpointfToString(rp);
1067 model->getSelectString(lmosel), "moveRel "+qpointfToString(movingObj_orgRelPos),
1068 preSelStr, "moveRel "+ps,
1069 QString("Move %1 to relative position %2").arg(model->getObjectName(lmosel)).arg(ps));
1073 // Draw the original link, before selection was moved around
1074 if (settings.value("/animation/use",false).toBool() && seli->depth()>1)
1076 lmosel->setRelPos(); // calc relPos first for starting point
1077 QPointF dst=bi->getBranchObj()->getParObj()->getChildPos(); // FIXME-3 check getBO here...
1078 // if (lmosel->getOrientation()==LinkableMapObj::LeftOfCenter) dst.setX (dst.x()+lmosel->width() );
1080 model->startAnimation(
1082 lmosel->getRelPos(),
1084 // QPointF (movingObj_orgPos.x() - dst.x(), movingObj_orgPos.y() - dst.y() )
1087 model->reposition();
1090 model->updateSelection(); //FIXME-3 needed? at least not after pos of selection has changed...
1091 // Finally resize scene, if needed
1095 // Just make sure, that actions are still ok,e.g. the move branch up/down buttons...
1096 // model->updateActions(); FIXME-3 neeeded?
1098 // maybe we moved View: set old cursor
1099 setCursor (Qt::ArrowCursor);
1103 void MapEditor::mouseDoubleClickEvent(QMouseEvent* e)
1105 if (model->isSelectionBlocked() )
1111 if (e->button() == Qt::LeftButton )
1113 QPointF p = mapToScene(e->pos());
1114 TreeItem *ti=findMapItem (p, NULL);
1115 if (ti) { // MapObj was found
1116 // First select the MapObj than edit heading
1123 void MapEditor::resizeEvent (QResizeEvent* e)
1125 QGraphicsView::resizeEvent( e );
1128 void MapEditor::dragEnterEvent(QDragEnterEvent *event)
1130 //for (unsigned int i=0;event->format(i);i++) // Debug mime type
1131 // cerr << event->format(i) << endl;
1133 if (event->mimeData()->hasImage())
1134 event->acceptProposedAction();
1136 if (event->mimeData()->hasUrls())
1137 event->acceptProposedAction();
1140 void MapEditor::dragMoveEvent(QDragMoveEvent *)
1144 void MapEditor::dragLeaveEvent(QDragLeaveEvent *event)
1149 void MapEditor::dropEvent(QDropEvent *event)
1151 BranchItem *selbi=model->getSelectedBranchItem();
1155 foreach (QString format,event->mimeData()->formats())
1156 cout << "MapEditor: Dropped format: "<<qPrintable (format)<<endl;
1160 if (event->mimeData()->hasImage())
1162 QVariant imageData = event->mimeData()->imageData();
1163 model->addFloatImage (qvariant_cast<QPixmap>(imageData));
1165 if (event->mimeData()->hasUrls())
1166 uris=event->mimeData()->urls();
1174 for (int i=0; i<uris.count();i++)
1176 // Workaround to avoid adding empty branches
1177 if (!uris.at(i).toString().isEmpty())
1179 bi=model->createBranch();
1183 s=uris.at(i).toLocalFile();
1186 QString file = QDir::fromNativeSeparators(s);
1187 heading = QFileInfo(file).baseName();
1189 if (file.endsWith(".vym", false))
1190 bi->setVymLink(file);
1192 bi->setURL(uris.at(i).toString());
1195 bo->setURL(uris.at(i).toString());
1199 if (!heading.isEmpty())
1200 bi->setHeading(heading);
1202 bi->setHeading(uris.at(i).toString());
1207 model->reposition();
1210 event->acceptProposedAction();
1213 void MapEditor::updateSelection(const QItemSelection &newsel,const QItemSelection &)
1215 // Reduce rectangles
1216 while (newsel.indexes().count() < selboxList.count() )
1217 delete selboxList.takeFirst();
1219 // Add additonal rectangles
1220 QGraphicsRectItem *sb;
1221 while (newsel.indexes().count() > selboxList.count() )
1223 sb = mapScene->addRect(
1225 QPen(selectionColor),
1227 sb->setZValue(Z_SELBOX);
1229 selboxList.append (sb);
1232 // Reposition rectangles
1238 LinkableMapObj *lmo;
1239 foreach (sb,selboxList)
1241 index=newsel.indexes().at(i);
1242 ti= static_cast<TreeItem*>(index.internalPointer());
1244 bbox=lmo->getBBox();
1247 bbox.width(), bbox.height());
1248 sb->setPen (selectionColor);
1249 sb->setBrush (selectionColor);
1254 void MapEditor::updateData (const QModelIndex &sel)
1256 TreeItem *ti= static_cast<TreeItem*>(sel.internalPointer());
1259 cout << "ME::updateData\n";
1261 cout << " ti="<<ti<<endl;
1262 cout << " h="<<ti->getHeading().toStdString()<<endl;
1265 if (ti->isBranchLikeType())
1267 BranchObj *bo=(BranchObj*)ti->getLMO();
1273 void MapEditor::setSelectionColor (QColor col)
1276 QItemSelection sel=model->getSelectionModel()->selection();
1277 updateSelection(sel,sel);
1281 QColor MapEditor::getSelectionColor ()
1283 return selectionColor;