+++ /dev/null
-#include "mapeditor.h"
-
-#include <QGraphicsProxyWidget>
-#include <QMenuBar>
-#include <QObject>
-#include <QPrinter>
-#include <QPrintDialog>
-#include <QScrollBar>
-
-#include "branchitem.h"
-#include "geometry.h"
-#include "mainwindow.h"
-#include "misc.h"
-#include "shortcuts.h"
-#include "warningdialog.h"
-#include "xlinkitem.h"
-
-
-extern Main *mainWindow;
-extern QString tmpVymDir;
-extern QString clipboardDir;
-extern QString clipboardFile;
-extern bool clipboardEmpty;
-extern bool debug;
-extern QPrinter *printer;
-
-extern QMenu* branchContextMenu;
-extern QMenu* canvasContextMenu;
-extern QMenu* floatimageContextMenu;
-extern QMenu* taskContextMenu;
-
-extern Switchboard switchboard;
-extern Settings settings;
-
-extern QTextStream vout;
-
-///////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////
-MapEditor::MapEditor( VymModel *vm)
-{
- //qDebug() << "Constructor ME "<<this;
-
- QString shortcutScope = tr("Map Editor","Shortcut scope");
- mapScene= new QGraphicsScene(NULL);
- mapScene->setBackgroundBrush (QBrush(Qt::white, Qt::SolidPattern));
-
- zoomFactor=zoomFactorTarget=1;
- angle=angleTarget=0;
-
- model=vm;
- model->registerEditor(this);
- model->makeDefault(); // No changes in model so far
-
- setScene (mapScene);
-
- // Create bitmap cursors, platform dependant
- HandOpenCursor=QCursor (QPixmap(":/cursorhandopen.png"),1,1);
- PickColorCursor=QCursor ( QPixmap(":/cursorcolorpicker.png"), 5,27 );
- CopyCursor=QCursor ( QPixmap(":/cursorcopy.png"), 1,1 );
- XLinkCursor=QCursor ( QPixmap(":/cursorxlink.png"), 1,7 );
-
- editingBO=NULL;
-
- printFrame=true;
- printFooter=true;
-
- setAcceptDrops (true);
-
- // Shortcuts and actions
- QAction *a;
-
- a = new QAction("Select upper branch", this);
- a->setShortcut (Qt::Key_Up );
- a->setShortcutContext (Qt::WidgetShortcut);
- connect( a, SIGNAL( triggered() ), this, SLOT( cursorUp() ) );
- addAction (a);
-
- a = new QAction( "Select lower branch",this);
- a->setShortcut ( Qt::Key_Down );
- a->setShortcutContext (Qt::WidgetShortcut);
- addAction (a);
- connect( a, SIGNAL( triggered() ), this, SLOT( cursorDown() ) );
-
- a = new QAction( "Select left branch", this);
- a->setShortcut (Qt::Key_Left );
-// a->setShortcutContext (Qt::WidgetWithChildrenShortcut);
- addAction (a);
- connect( a, SIGNAL( triggered() ), this, SLOT( cursorLeft() ) );
-
- a = new QAction( "Select child branch", this);
- a->setShortcut (Qt::Key_Right);
-// a->setShortcutContext (Qt::WidgetWithChildrenShortcut);
- addAction (a);
- connect( a, SIGNAL( triggered() ), this, SLOT( cursorRight() ) );
-
- a = new QAction( "Select first branch", this);
- a->setShortcut (Qt::Key_Home );
- a->setShortcutContext (Qt::WidgetWithChildrenShortcut);
- addAction (a);
- connect( a, SIGNAL( triggered() ), this, SLOT( cursorFirst() ) );
-
- a = new QAction( "Select last branch",this);
- a->setShortcut ( Qt::Key_End );
- a->setShortcutContext (Qt::WidgetWithChildrenShortcut);
- addAction (a);
- connect( a, SIGNAL( triggered() ), this, SLOT( cursorLast() ) );
-
- // Action to embed LineEdit for heading in Scene
- lineEdit=NULL;
-
- a = new QAction( tr( "Edit heading","MapEditor" ), this);
- a->setShortcut ( Qt::Key_Return ); //Edit heading
- a->setShortcutContext (Qt::WidgetShortcut);
- addAction (a);
- connect( a, SIGNAL( triggered() ), this, SLOT( editHeading() ) );
- a = new QAction( tr( "Edit heading","MapEditor" ), this);
- a->setShortcut ( Qt::Key_Enter); //Edit heading
- a->setShortcutContext (Qt::WidgetShortcut);
- addAction (a);
- connect( a, SIGNAL( triggered() ), this, SLOT( editHeading() ) );
-
- // Selections
- selectionColor =QColor (255,255,0);
-
- // Panning
- panningTimer=new QTimer (this);
- vPan=QPointF();
- connect (panningTimer, SIGNAL (timeout()), this, SLOT (panView() ));
-
- // Clone actions defined in MainWindow
- foreach (QAction* qa, mainWindow->mapEditorActions)
- {
- a = new QAction( this );
- a->setShortcut( qa->shortcut() );
- a->setShortcutContext( qa->shortcutContext() );
- connect( a, SIGNAL( triggered() ), qa, SLOT( trigger() ) );
- addAction(a);
- }
-
- setState (Neutral);
-
- // Attributes //TODO testing only...
- QString k;
- AttributeDef *ad;
- attrTable= new AttributeTable();
- k="A - StringList";
- ad=attrTable->addKey (k,StringList);
- if (ad)
- {
- QStringList sl;
- sl <<"val 1"<<"val 2"<< "val 3";
- ad->setValue (QVariant (sl));
- }
- //attrTable->addValue ("Key A","P 1");
- //attrTable->addValue ("Key A","P 2");
- //attrTable->addValue ("Key A","P 3");
- //attrTable->addValue ("Key A","P 4");
- k="B - FreeString";
- ad=attrTable->addKey (k,FreeString);
- if (ad)
- {
- //attrTable->addValue ("Key B","w1");
- //attrTable->addValue ("Key B","w2");
- }
- k="C - UniqueString";
- ad=attrTable->addKey (k,UniqueString);
- if (ad)
- {
- //attrTable->addKey ("Key Prio");
- //attrTable->addValue ("Key Prio","Prio 1");
- //attrTable->addValue ("Key Prio","Prio 2");
- }
-
- winter=NULL;
-}
-
-MapEditor::~MapEditor()
-{
- //qDebug ()<<"Destr MapEditor this="<<this;
-}
-
-VymModel* MapEditor::getModel()
-{
- return model;
-}
-
-QGraphicsScene * MapEditor::getScene()
-{
- return mapScene;
-}
-
-void MapEditor::panView()
-{
- if (!vPan.isNull() )
- {
- // Scroll if needed
- // To avoid jumping of the sceneView, only
- // show selection, if not tmp linked
- qreal px=0;
- qreal py=0;
- if (vPan.x()<0)
- px=vPan.x();
- else if (vPan.x()>0 )
- px=width()+vPan.x();
- if (vPan.y()<0)
- py=vPan.y();
- else if (vPan.y()>0 )
- py=height()+vPan.y();
-
- QPointF q=mapToScene (QPoint(px,py));
- QRectF r=QRectF (q,QPointF (q.x()+1,q.y()+1));
-
- // Expand view if necessary
- setScrollBarPosTarget (r);
-
- // Stop possible other animations
- if (scrollBarPosAnimation.state()==QAbstractAnimation::Running)
- scrollBarPosAnimation.stop();
-
- // Do linear animation
- horizontalScrollBar()->setValue(horizontalScrollBar()->value() + vPan.x() );
- verticalScrollBar()->setValue ( verticalScrollBar()->value() + vPan.y() );
-
- // Update currently moving object
- moveObject ();
- }
-}
-
-void MapEditor::scrollTo (const QModelIndex &index)
-{
- if (index.isValid())
- {
- LinkableMapObj* lmo=NULL;
- TreeItem *ti= static_cast<TreeItem*>(index.internalPointer());
- if (ti->getType()==TreeItem::Image ||ti->isBranchLikeType() )
- lmo=((MapItem*)ti)->getLMO();
- if (lmo)
- {
- QRectF r=lmo->getBBox();
- setScrollBarPosTarget (r);
- animateScrollBars();
- }
- }
-}
-
-void MapEditor::setScrollBarPosTarget (QRectF rect)
-{
- // Expand viewport, if rect is not contained
- if (!sceneRect().contains (rect) )
- setSceneRect(sceneRect().united (rect));
-
- int xmargin=0;
- int ymargin=0;
-
- // Prepare scrolling
- qreal width = viewport()->width();
- qreal height = viewport()->height();
- QRectF viewRect = matrix().mapRect(rect);
-
- qreal left = horizontalScrollBar()->value();
- qreal right = left + width;
- qreal top = verticalScrollBar()->value();
- qreal bottom = top + height;
-
- scrollBarPosTarget=getScrollBarPos();
-
- if (viewRect.left() <= left + xmargin) {
- // need to scroll from the left
- scrollBarPosTarget.setX(int(viewRect.left() - xmargin - 0.5));
- }
- if (viewRect.right() >= right - xmargin) {
- // need to scroll from the right
- scrollBarPosTarget.setX(int(viewRect.right() - width + xmargin + 0.5));
- }
- if (viewRect.top() <= top + ymargin) {
- // need to scroll from the top
- scrollBarPosTarget.setY(int(viewRect.top() - ymargin - 0.5));
- }
- if (viewRect.bottom() >= bottom - ymargin) {
- // need to scroll from the bottom
- scrollBarPosTarget.setY(int(viewRect.bottom() - height + ymargin + 0.5));
- }
-
-}
-
-QPointF MapEditor::getScrollBarPosTarget()
-{
- return scrollBarPosTarget;
-}
-
-
-void MapEditor::setScrollBarPos(const QPointF &p)
-{
- scrollBarPos=p;
- horizontalScrollBar()->setValue(int(p.x()));
- verticalScrollBar()->setValue(int(p.y()));
-}
-
-QPointF MapEditor::getScrollBarPos()
-{
- return QPointF (horizontalScrollBar()->value(),verticalScrollBar()->value());
- //return scrollBarPos;
-}
-
-void MapEditor::animateScrollBars()
-{
- if (scrollBarPosAnimation.state()==QAbstractAnimation::Running)
- scrollBarPosAnimation.stop();
-
- if (settings.value ("/animation/use/",true).toBool() )
- {
- scrollBarPosAnimation.setTargetObject (this);
- scrollBarPosAnimation.setPropertyName ("scrollBarPos");
- scrollBarPosAnimation.setDuration(settings.value("/animation/duration/scrollbar",2000).toInt() );
- scrollBarPosAnimation.setEasingCurve ( QEasingCurve::OutQuint);
- scrollBarPosAnimation.setStartValue(
- QPointF (horizontalScrollBar()->value() ,
- verticalScrollBar()->value() ) );
- scrollBarPosAnimation.setEndValue(scrollBarPosTarget);
- scrollBarPosAnimation.start();
- } else
- setScrollBarPos (scrollBarPosTarget);
-}
-
-void MapEditor::setZoomFactorTarget (const qreal &zft)
-{
- zoomFactorTarget=zft;
- if (zoomAnimation.state()==QAbstractAnimation::Running)
- zoomAnimation.stop();
- if (settings.value ("/animation/use/",true).toBool() )
- {
- zoomAnimation.setTargetObject (this);
- zoomAnimation.setPropertyName ("zoomFactor");
- zoomAnimation.setDuration(settings.value("/animation/duration/zoom",2000).toInt() );
- zoomAnimation.setEasingCurve ( QEasingCurve::OutQuint);
- zoomAnimation.setStartValue(zoomFactor);
- zoomAnimation.setEndValue(zft);
- zoomAnimation.start();
- } else
- setZoomFactor (zft);
-}
-
-qreal MapEditor::getZoomFactorTarget()
-{
- return zoomFactorTarget;
-}
-
-
-void MapEditor::setZoomFactor(const qreal &zf)
-{
- zoomFactor=zf;
- updateMatrix();
-}
-
-qreal MapEditor::getZoomFactor()
-{
- return zoomFactor;
-}
-
-void MapEditor::setAngleTarget (const qreal &at)
-{
- angleTarget=at;
- if (rotationAnimation.state()==QAbstractAnimation::Running)
- rotationAnimation.stop();
- if (settings.value ("/animation/use/",true).toBool() )
- {
- rotationAnimation.setTargetObject (this);
- rotationAnimation.setPropertyName ("angle");
- rotationAnimation.setDuration(settings.value("/animation/duration/rotation",2000).toInt() );
- rotationAnimation.setEasingCurve ( QEasingCurve::OutQuint);
- rotationAnimation.setStartValue(angle);
- rotationAnimation.setEndValue(at);
- rotationAnimation.start();
- } else
- setAngle (angleTarget);
-}
-
-qreal MapEditor::getAngleTarget()
-{
- return angleTarget;
-}
-
-
-void MapEditor::setAngle(const qreal &a)
-{
- angle=a;
- updateMatrix();
-}
-
-qreal MapEditor::getAngle()
-{
- return angle;
-}
-
-void MapEditor::setViewCenterTarget (
- const QPointF &p,
- const qreal &zft,
- const qreal &at,
- const int duration,
- const QEasingCurve &easingCurve)
-{
- viewCenterTarget=p;
- zoomFactorTarget=zft;
- angleTarget=at;
-
- viewCenter=mapToScene(viewport()->geometry()).boundingRect().center();
-
- if (viewCenterAnimation.state()==QAbstractAnimation::Running)
- viewCenterAnimation.stop();
- if (rotationAnimation.state()==QAbstractAnimation::Running)
- rotationAnimation.stop();
- if (zoomAnimation.state()==QAbstractAnimation::Running)
- zoomAnimation.stop();
-
- if (settings.value ("/animation/use/",true).toBool() )
- {
- viewCenterAnimation.setTargetObject (this);
- viewCenterAnimation.setPropertyName ("viewCenter");
- viewCenterAnimation.setDuration(
- settings.value("/animation/duration/scrollbar",duration).toInt() );
- viewCenterAnimation.setEasingCurve (easingCurve );
- viewCenterAnimation.setStartValue( viewCenter );
- viewCenterAnimation.setEndValue(viewCenterTarget);
- viewCenterAnimation.start();
-
- rotationAnimation.setTargetObject (this);
- rotationAnimation.setPropertyName ("angle");
- rotationAnimation.setDuration(settings.value("/animation/duration/rotation",duration).toInt() );
- rotationAnimation.setEasingCurve ( easingCurve );
- rotationAnimation.setStartValue(angle);
- rotationAnimation.setEndValue(angleTarget);
- rotationAnimation.start();
-
- zoomAnimation.setTargetObject (this);
- zoomAnimation.setPropertyName ("zoomFactor");
- zoomAnimation.setDuration(settings.value("/animation/duration/zoom",duration).toInt() );
- zoomAnimation.setEasingCurve ( easingCurve );
- zoomAnimation.setStartValue(zoomFactor);
- zoomAnimation.setEndValue(zoomFactorTarget);
- zoomAnimation.start();
-
- } else
- {
- setAngle (angleTarget);
- setZoomFactor (zft);
- setViewCenter (viewCenterTarget);
- }
-}
-
-void MapEditor::setViewCenterTarget ()
-{
- MapItem *selti=(MapItem*)(model->getSelectedItem() );
- if (selti)
- {
- LinkableMapObj *lmo=selti->getLMO();
- if (lmo)
- setViewCenterTarget (lmo->getBBox().center(), 1, 0);
- }
-}
-
-QPointF MapEditor::getViewCenterTarget ()
-{
- return viewCenterTarget;
-}
-
-void MapEditor::setViewCenter (const QPointF &vc)
-{
- centerOn (vc);
-}
-
-QPointF MapEditor::getViewCenter()
-{
- return viewCenter;
-}
-
-void MapEditor::updateMatrix()
-{
- double a = M_PI/180 * angle;
- double sina = sin((double)a);
- double cosa = cos((double)a);
-
- QMatrix zm(zoomFactor, 0, 0, zoomFactor, 0, 0);
- //QMatrix translationMatrix(1, 0, 0, 1, 50.0, 50.0);
- QMatrix rm(cosa, sina, -sina, cosa, 0, 0);
- setMatrix (zm * rm);
-}
-
-void MapEditor::minimizeView()
-{
- setSceneRect( scene()->itemsBoundingRect() );
-}
-
-void MapEditor::print()
-{
- QRectF totalBBox=getTotalBBox();
-
- // Try to set orientation automagically
- // Note: Interpretation of generated postscript is amibiguous, if
- // there are problems with landscape mode, see
- // http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html
-
- if (totalBBox.width()>totalBBox.height())
- // recommend landscape
- printer->setOrientation (QPrinter::Landscape);
- else
- // recommend portrait
- printer->setOrientation (QPrinter::Portrait);
-
- QPrintDialog dialog (printer, this);
- dialog.setWindowTitle(tr("Print vym map","MapEditor"));
- if (dialog.exec() == QDialog::Accepted)
- {
- QPainter pp(printer);
-
- pp.setRenderHint(QPainter::Antialiasing,true);
-
- // Don't print the visualisation of selection
- model->unselectAll();
-
- QRectF mapRect=totalBBox;
- QGraphicsRectItem *frame=NULL;
-
- if (printFrame)
- {
- // Print frame around map
- mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10,
- totalBBox.width()+20, totalBBox.height()+20);
- frame=mapScene->addRect (mapRect, QPen(Qt::black),QBrush(Qt::NoBrush));
- frame->setZValue(0);
- frame->show();
- }
-
-
- double paperAspect = (double)printer->width() / (double)printer->height();
- double mapAspect = (double)mapRect.width() / (double)mapRect.height();
- int viewBottom;
- if (mapAspect>=paperAspect)
- {
- // Fit horizontally to paper width
- //pp.setViewport(0,0, printer->width(),(int)(printer->width()/mapAspect) );
- viewBottom=(int)(printer->width()/mapAspect);
- } else
- {
- // Fit vertically to paper height
- //pp.setViewport(0,0,(int)(printer->height()*mapAspect),printer->height());
- viewBottom=printer->height();
- }
-
- if (printFooter)
- {
- // Print footer below map
- QFont font;
- font.setPointSize(10);
- pp.setFont (font);
- QRectF footerBox(0,viewBottom,printer->width(),15);
- pp.drawText ( footerBox,Qt::AlignLeft,"VYM - " +model->getFileName());
- pp.drawText ( footerBox, Qt::AlignRight, QDate::currentDate().toString(Qt::TextDate));
- }
- mapScene->render (
- &pp,
- QRectF (0,0,printer->width(),printer->height()-15),
- QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height())
- );
-
- // Viewport has paper dimension
- if (frame) delete (frame);
-
- // Restore selection
- model->reselect();
- }
-}
-
-QRectF MapEditor::getTotalBBox()
-{
- minimizeView();
- return sceneRect();
-}
-
-QImage MapEditor::getImage( QPointF &offset)
-{
- QRectF mapRect = getTotalBBox(); // minimized sceneRect
-
- int d = 10; // border
- offset = QPointF( mapRect.x() -d/2, mapRect.y() - d/2 );
- QImage pix( mapRect.width() + d, mapRect.height() + d, QImage::Format_RGB32 );
-
- QPainter pp (&pix);
- pp.setRenderHints(renderHints());
- mapScene->render ( &pp,
- // Destination:
- QRectF( 0, 0, mapRect.width() + d, mapRect.height() + d ),
- // Source in scene:
- QRectF( mapRect.x() - d/2, mapRect.y() -d/2, mapRect.width() + d, mapRect.height() + d));
- return pix;
-}
-
-
-void MapEditor::setAntiAlias (bool b)
-{
- setRenderHint(QPainter::Antialiasing,b);
-}
-
-void MapEditor::setSmoothPixmap(bool b)
-{
- setRenderHint(QPainter::SmoothPixmapTransform,b);
-}
-
-void MapEditor::autoLayout()
-{
- // Create list with all bounding polygons
- QList <LinkableMapObj*> mapobjects;
- QList <ConvexPolygon> polys;
- ConvexPolygon p;
- QList <Vector> vectors;
- QList <Vector> orgpos;
- QStringList headings; //FIXME-3 testing only
- Vector v;
- BranchItem *bi;
- BranchItem *bi2;
- BranchObj *bo;
-
- // Outer loop: Iterate until we no more changes in orientation
- bool orientationChanged=true;
- while (orientationChanged)
- {
- BranchItem *ri=model->getRootItem();
- for (int i=0;i<ri->branchCount();++i)
- {
- bi=ri->getBranchNum (i);
- bo=(BranchObj*)bi->getLMO();
- if (bo)
- {
- mapobjects.append (bo);
- p=bo->getBoundingPolygon();
- p.calcCentroid();
- polys.append(p);
- vectors.append (QPointF(0,0));
- orgpos.append (p.at(0));
- headings.append (bi->getHeadingPlain());
- }
- for (int j=0;j<bi->branchCount();++j)
- {
- bi2=bi->getBranchNum (j);
- bo=(BranchObj*)bi2->getLMO();
- if (bo)
- {
- mapobjects.append (bo);
- p=bo->getBoundingPolygon();
- p.calcCentroid();
- polys.append(p);
- vectors.append (QPointF(0,0));
- orgpos.append (p.at(0));
- headings.append (bi2->getHeadingPlain());
- }
- }
- }
-
- // Iterate moving bounding polygons until we have no more collisions
- int collisions=1;
- while (collisions>0)
- {
- collisions=0;
- for (int i=0; i<polys.size()-1; ++i)
- {
- for (int j=i+1; j<polys.size();++j)
- {
- if (polygonCollision (polys.at(i),polys.at(j), QPointF(0,0)).intersect )
- {
- collisions++;
- if (debug) qDebug() << "Collision: "<<headings[i]<<" - "<<headings[j];
- v=polys.at(j).centroid()-polys.at(i).centroid();
- v.normalize();
- // Add random direction, if only two polygons with identical y or x
- if (v.x()==0 || v.y()==0)
- {
- Vector w (cos (double((int)rand()%1000)),sin(double((int)rand()%1000)));
- w.normalize();
- v=v+w;
- }
-
- // Scale translation vector by area of polygons
- vectors[j]=v*10000/polys.at(j).weight();
- vectors[i]=v*10000/polys.at(i).weight();
- vectors[i].invert();
- //FIXME-3 outer loop, "i" get's changed several times...
- // Better not move away from centroid of 2 colliding polys,
- // but from centroid of _all_
- }
- }
- }
- for (int i=0;i<vectors.size();i++)
- {
- //qDebug() << " v="<<vectors[i]<<" "<<headings[i];
- if (!vectors[i].isNull() )
- polys[i].translate (vectors[i]);
- }
- // if (debug) qDebug()<< "Collisions total: "<<collisions;
- // collisions=0;
- }
-
- // Finally move the real objects and update
- QList <LinkableMapObj::Orientation> orients;
- for (int i=0;i<polys.size();i++)
- {
- Vector v=polys[i].at(0)-orgpos[i];
- orients.append (mapobjects[i]->getOrientation());
- if (!v.isNull())
- {
- if (debug) qDebug()<<" Moving "<<polys.at(i).weight()<<" "<<mapobjects[i]->getAbsPos()<<" -> "<<mapobjects[i]->getAbsPos() + v<<" "<<headings[i];
- //mapobjects[i]->moveBy(v.x(),v.y() );
- //mapobjects[i]->setRelPos();
- model->startAnimation ((BranchObj*)mapobjects[i], v);
- if (debug) qDebug()<<i<< " Weight: "<<polys.at(i).weight()<<" "<<v<<" "<<headings.at(i);
- }
- }
- /*
- model->reposition();
- orientationChanged=false;
- for (int i=0;i<polys.size();i++)
- if (orients[i]!=mapobjects[i]->getOrientation())
- {
- orientationChanged=true;
- break;
- }
- */
-
- break;
-
- //orientationChanged=false;
- } // loop if orientation has changed
-
- model->emitSelectionChanged();
-}
-
-TreeItem* MapEditor::findMapItem (QPointF p,TreeItem *exclude)
-{
- // Search XLinks
- Link *link;
- for (int i=0; i<model->xlinkCount(); i++ )
- {
- link=model->getXLinkNum(i);
- if (link)
- {
- XLinkObj *xlo=link->getXLinkObj();
- if (xlo && xlo->isInClickBox (p))
- {
- // Found XLink, now return the nearest XLinkItem of p
- qreal d0=Geometry::distance(p, xlo->getBeginPos());
- qreal d1=Geometry::distance(p, xlo->getEndPos());
- if (d0>d1)
- return link->getBeginLinkItem();
- else
- return link->getEndLinkItem();
- }
- }
- }
-
- // Search branches (and their childs, e.g. images
- // Start with mapcenter, no images allowed at rootItem
- int i=0;
- BranchItem *bi=model->getRootItem()->getFirstBranch();
- TreeItem *found=NULL;
- while (bi)
- {
- found=bi->findMapItem (p, exclude);
- if (found) return found;
- i++;
- bi=model->getRootItem()->getBranchNum(i);
- }
- return NULL;
-}
-
-AttributeTable* MapEditor::attributeTable()
-{
- return attrTable;
-}
-
-void MapEditor::testFunction1()
-{
-}
-
-void MapEditor::testFunction2()
-{
- autoLayout();
-}
-
-#include "winter.h"
-void MapEditor::toggleWinter()
-{
- if (winter)
- {
- delete winter;
- winter=NULL;
- } else
- {
- winter=new Winter (this);
- QList <QRectF> obstacles;
- BranchObj *bo;
- BranchItem *cur=NULL;
- BranchItem *prev=NULL;
- model->nextBranch(cur,prev);
- while (cur)
- {
- if (!cur->hasHiddenExportParent())
- {
- // Branches
- bo=(BranchObj*)(cur->getLMO());
- if (bo && bo->isVisibleObj())
- obstacles.append(bo->getBBox());
- }
- model->nextBranch(cur,prev);
- }
- winter->setObstacles(obstacles);
- }
-}
-
-BranchItem* MapEditor::getBranchDirectAbove (BranchItem *bi)
-{
- if (bi)
- {
- int i=bi->num();
- if (i>0) return bi->parent()->getBranchNum(i-1);
- }
- return NULL;
-}
-
-BranchItem* MapEditor::getBranchAbove (BranchItem *selbi)
-{
- if (selbi)
- {
- int dz=selbi->depth(); // original depth
- bool invert=false;
- if (selbi->getLMO()->getOrientation()==LinkableMapObj::LeftOfCenter)
- invert=true;
-
- BranchItem *bi;
-
- // Look for branch with same parent but directly above
- if (dz==1 && invert)
- bi=getBranchDirectBelow(selbi);
- else
- bi=getBranchDirectAbove (selbi);
-
- if (bi)
- // direct predecessor
- return bi;
-
- // Go towards center and look for predecessor
- while (selbi->depth()>0)
- {
- selbi=(BranchItem*)(selbi->parent());
- if (selbi->depth()==1 && invert)
- bi=getBranchDirectBelow (selbi);
- else
- bi=getBranchDirectAbove (selbi);
- if (bi)
- {
- // turn
- selbi=bi;
- while (selbi->depth()<dz)
- {
- // try to get back to original depth dz
- bi=selbi->getLastBranch();
- if (!bi)
- {
- return selbi;
- }
- selbi=bi;
- }
- return selbi;
- }
- }
- }
- return NULL;
-}
-
-BranchItem* MapEditor::getBranchDirectBelow(BranchItem *bi)
-{
- if (bi)
- {
- int i=bi->num();
- if (i+1<bi->parent()->branchCount()) return bi->parent()->getBranchNum(i+1);
- }
- return NULL;
-}
-
-BranchItem* MapEditor::getBranchBelow (BranchItem *selbi)
-{
- if (selbi)
- {
- BranchItem *bi;
- int dz=selbi->depth(); // original depth
- bool invert=false;
- if (selbi->getLMO()->getOrientation()==LinkableMapObj::LeftOfCenter)
- invert=true;
-
-
- // Look for branch with same parent but directly below
- if (dz==1 && invert)
- bi=getBranchDirectAbove (selbi);
- else
- bi=getBranchDirectBelow (selbi);
- if (bi)
- // direct successor
- return bi;
-
-
- // Go towards center and look for neighbour
- while (selbi->depth()>0)
- {
- selbi=(BranchItem*)(selbi->parent());
- if (selbi->depth()==1 && invert)
- bi=getBranchDirectAbove (selbi);
- else
- bi=getBranchDirectBelow (selbi);
- if (bi)
- {
- // turn
- selbi=bi;
- while (selbi->depth()<dz)
- {
- // try to get back to original depth dz
- bi=selbi->getFirstBranch();
- if (!bi)
- {
- return selbi;
- }
- selbi=bi;
- }
- return selbi;
- }
- }
- }
- return NULL;
-}
-
-BranchItem* MapEditor::getLeftBranch (BranchItem *bi)
-{
- if (bi)
- {
- if (bi->depth()==0)
- {
- // Special case: use alternative selection index
- BranchItem *newbi=bi->getLastSelectedBranchAlt();
- if (!newbi)
- {
- BranchObj *bo;
- // Try to find a mainbranch left of center
- for (int i=0; i<bi->branchCount(); i++)
- {
- newbi=bi->getBranchNum(i);
- bo=newbi->getBranchObj();
- if (bo && bo->getOrientation()==LinkableMapObj::LeftOfCenter)
- break;
- }
- }
- return newbi;
- }
- if (bi->getBranchObj()->getOrientation()==LinkableMapObj::RightOfCenter)
- // right of center
- return (BranchItem*)(bi->parent());
- else
- // left of center
- if (bi->getType()== TreeItem::Branch )
- return bi->getLastSelectedBranch();
- }
- return NULL;
-}
-
-BranchItem* MapEditor::getRightBranch(BranchItem *bi)
-{
- if (bi)
- {
- if (bi->depth()==0)
- {
- // Special case: use alternative selection index
- BranchItem *newbi=bi->getLastSelectedBranch();
- if (!newbi)
- {
- BranchObj *bo;
- // Try to find a mainbranch right of center
- for (int i=0; i<bi->branchCount(); i++)
- {
- newbi=bi->getBranchNum(i);
- bo=newbi->getBranchObj();
- if (bo && bo->getOrientation()==LinkableMapObj::RightOfCenter)
- qDebug()<<"BI found right: "<<newbi->getHeadingPlain();
- }
- }
- return newbi;
- }
- if (bi->getBranchObj()->getOrientation()==LinkableMapObj::LeftOfCenter)
- // left of center
- return (BranchItem*)(bi->parent());
- else
- // right of center
- if (bi->getType()== TreeItem::Branch )
- return (BranchItem*)bi->getLastSelectedBranch();
- }
- return NULL;
-}
-
-
-
-void MapEditor::cursorUp()
-{
- if (state == MapEditor::EditingHeading) return;
-
- BranchItem *bi=model->getSelectedBranch();
- if (bi) model->select (getBranchAbove(bi));
-}
-
-void MapEditor::cursorDown()
-
-{
- if (state == MapEditor::EditingHeading) return;
-
- BranchItem *bi=model->getSelectedBranch();
- if (bi) model->select (getBranchBelow(bi));
-}
-
-void MapEditor::cursorLeft()
-{
- BranchItem *bi=getLeftBranch (model->getSelectedBranch());
- if (bi) model->select (bi);
-}
-
-void MapEditor::cursorRight()
-{
- BranchItem *bi=getRightBranch (model->getSelectedBranch());
- if (bi) model->select (bi);
-}
-
-void MapEditor::cursorFirst()
-{
- model->selectFirstBranch();
-}
-
-void MapEditor::cursorLast()
-{
- model->selectLastBranch();
-}
-
-
-void MapEditor::editHeading()
-{
- if (state==EditingHeading)
- {
- editHeadingFinished();
- return;
- }
-
- BranchObj *bo=model->getSelectedBranchObj();
- BranchItem *bi=model->getSelectedBranch();
- if (bo && bo)
- {
- VymText heading = bi->getHeading();
- if (heading.isRichText())
- {
- mainWindow->windowShowHeadingEditor();
- return;
- }
- model->setSelectionBlocked(true);
-
- lineEdit=new QLineEdit;
- QGraphicsProxyWidget *pw=mapScene->addWidget (lineEdit);
- pw->setZValue (Z_LINEEDIT);
- lineEdit->setCursor(Qt::IBeamCursor);
- lineEdit->setCursorPosition(1);
-
- QPointF tl=bo->getOrnamentsBBox().topLeft();
- QPointF br=tl + QPointF (230,30);
- QRectF r (tl, br);
- lineEdit->setGeometry(r.toRect() );
-
- setScrollBarPosTarget ( r );
- scene()->update();
-
- // Set focus to MapEditor first
- // To avoid problems with Cursor up/down
- setFocus();
-
- animateScrollBars();
- lineEdit->setText (heading.getTextASCII() );
- lineEdit->setFocus();
- lineEdit->selectAll(); // Hack to enable cursor in lineEdit
- lineEdit->deselect(); // probably a Qt bug...
- setState (EditingHeading);
- }
-}
-
-void MapEditor::editHeadingFinished()
-{
- setState (Neutral);
- //lineEdit->releaseKeyboard();
- lineEdit->clearFocus();
- QString s=lineEdit->text();
- s.replace (QRegExp ("\\n")," "); // Don't paste newline chars
- model->setHeadingPlainText (s);
- model->setSelectionBlocked(false);
- delete (lineEdit);
- lineEdit=NULL;
-
- animateScrollBars();
-
- // Maybe reselect previous branch
- mainWindow->editHeadingFinished (model);
-
- //Autolayout to avoid overlapping branches with longer headings
- if (settings.value("/mainwindow/autoLayout/use","true")=="true")
- autoLayout();
-}
-
-
-void MapEditor::contextMenuEvent ( QContextMenuEvent * e )
-{
- // Lineedits are already closed by preceding
- // mouseEvent, we don't need to close here.
-
- QPointF p = mapToScene(e->pos());
- TreeItem *ti=findMapItem (p, NULL);
-
- if (ti)
- { // MapObj was found
- model->select (ti);
-
- LinkableMapObj* lmo=NULL;
- BranchItem* selbi=model->getSelectedBranch();
- if (ti) lmo=((MapItem*)ti)->getLMO();
-
- // Context Menu
- if (lmo && selbi )
- {
- QString foname=((BranchObj*)lmo)->getSystemFlagName(p);
- if (foname.startsWith ("system-task"))
- taskContextMenu->popup (e->globalPos() );
- else
- // Context Menu on branch or mapcenter
- branchContextMenu->popup(e->globalPos() );
- } else
- {
- if (model->getSelectedImage() )
- {
- // Context Menu on floatimage
- floatimageContextMenu->popup(e->globalPos() );
- } else
- {
- if (model->getSelectedXLink() )
- // Context Menu on XLink
- model->editXLink();
- }
- }
- } else
- { // No MapObj found, we are on the Canvas itself
- // Context Menu on scene
-
- // Open context menu synchronously to position new mapcenter
- model->setContextPos (p);
- canvasContextMenu->exec(e->globalPos() );
- model->unsetContextPos ();
- }
- e->accept();
-}
-
-void MapEditor::keyPressEvent(QKeyEvent* e)
-{
- if (e->key()==Qt::Key_PageUp || e->key()==Qt::Key_PageDown)
- // Ignore PageUP/Down to avoid scrolling with keys
- return;
-
- if (e->modifiers() & Qt::ShiftModifier)
- {
- switch (mainWindow->getModMode())
- {
- case Main::ModModeColor:
- setCursor (PickColorCursor);
- break;
- case Main::ModModeCopy:
- setCursor (CopyCursor);
- break;
- case Main::ModModeXLink:
- setCursor (XLinkCursor);
- break;
- default :
- setCursor (Qt::ArrowCursor);
- break;
- }
- }
- QGraphicsView::keyPressEvent(e);
-}
-
-void MapEditor::keyReleaseEvent(QKeyEvent* e)
-{
- if (!(e->modifiers() & Qt::ControlModifier))
- setCursor (Qt::ArrowCursor);
-}
-
-void MapEditor::mousePressEvent(QMouseEvent* e)
-{
- // Ignore right clicks or wile editing heading
- if (e->button() == Qt::RightButton || model->isSelectionBlocked() )
- {
- e->ignore();
- QGraphicsView::mousePressEvent(e);
- return;
- }
-
- // Check if we need to reset zoomFactor
- if (e->button() == Qt::MidButton && e->modifiers() & Qt::ControlModifier )
- {
- setZoomFactorTarget (1);
- setAngleTarget (0);
- return;
- }
-
- QPointF p = mapToScene(e->pos());
- TreeItem *ti=findMapItem (p, NULL);
- LinkableMapObj* lmo=NULL;
- if (ti) lmo=((MapItem*)ti)->getLMO();
-
- QString sysFlagName;
- if (lmo) sysFlagName=((BranchObj*)lmo)->getSystemFlagName(p);
-
- /*
- qDebug() << "ME::mouse pressed\n";
- qDebug() << " lmo="<<lmo;
- qDebug() << " ti="<<ti;
- if (ti) qDebug() << " ti="<<ti->getHeading();
- qDebug() << " flag="<<sysFlagName;
- */
-
- // Check PickColor modifier (before selecting object!)
- if (ti && (e->modifiers() & Qt::ShiftModifier) &&
- mainWindow->getModMode()==Main::ModModeColor)
- {
- setState (PickingColor);
- mainWindow->setCurrentColor (ti->getHeadingColor() );
- if ((e->modifiers() & Qt::ShiftModifier) && (e->modifiers() & Qt::ControlModifier) )
- model->colorBranch(ti->getHeadingColor());
- else
- model->colorSubtree(ti->getHeadingColor());
- return;
- }
-
- // Check vymlink modifier (before selecting object!)
- if (ti && sysFlagName=="system-vymLink")
- {
- model->select(ti);
- if (e->modifiers() & Qt::ControlModifier)
- mainWindow->editOpenVymLink(true);
- else
- mainWindow->editOpenVymLink(false);
- return;
- }
-
- // Select the clicked object
- if (ti && e->modifiers() & Qt::ControlModifier)
- model->selectToggle (ti);
- else
- model->select (ti);
-
- e->accept();
-
- //Take care of remaining system flags _or_ modifier modes
- if (lmo )
- {
- if (!sysFlagName.isEmpty())
- {
- // systemFlag clicked
- if (sysFlagName.contains("system-url"))
- {
- if (e->modifiers() & Qt::ControlModifier)
- mainWindow->editOpenURLTab();
- else
- mainWindow->editOpenURL();
- }
- else if (sysFlagName=="system-vymLink")
- {
- if (e->modifiers() & Qt::ControlModifier)
- mainWindow->editOpenVymLink(true);
- else
- mainWindow->editOpenVymLink(false);
- // tabWidget may change, better return now
- // before segfaulting...
- } else if (sysFlagName=="system-note")
- mainWindow->windowToggleNoteEditor();
- else if (sysFlagName=="hideInExport")
- model->toggleHideExport();
- else if (sysFlagName.startsWith("system-task-") )
- model->cycleTaskStatus();
- return;
- } else
- {
- // Take care of xLink: Open context menu with targets
- // if clicked near to begin of xlink
- if (ti->xlinkCount()>0 && ti->getType() != TreeItem::MapCenter && lmo->getBBox().width()>30)
- {
- if ((lmo->getOrientation()!=LinkableMapObj::RightOfCenter && p.x() < lmo->getBBox().left()+10) ||
- (lmo->getOrientation()!=LinkableMapObj::LeftOfCenter && p.x() > lmo->getBBox().right()-10) )
- {
- //FIXME-4 similar code in mainwindow::updateActions
- QMenu menu;
- QList <QAction*> alist;
- QList <BranchItem*> blist;
- for (int i=0;i<ti->xlinkCount();i++)
- {
- XLinkItem *xli=ti->getXLinkItemNum(i);
- BranchItem *bit=xli->getPartnerBranch();
- if (bit) alist.append (new QAction(ti->getXLinkItemNum(i)->getPartnerBranch()->getHeadingPlain(),&menu));
- }
- menu.addActions (alist);
- QAction *ra=menu.exec (e->globalPos() );
- if (ra)
- model->select (blist.at( alist.indexOf(ra)));
- while (!alist.isEmpty())
- {
- QAction *a=alist.takeFirst();
- delete a;
- }
- return;
- }
- }
- }
- }
-
- // XLink modifier, create new XLink
- BranchItem* selbi = model->getSelectedBranch();
- if (selbi &&
- mainWindow->getModMode()==Main::ModModeXLink &&
- (e->modifiers() & Qt::ShiftModifier))
- {
- setState (DrawingLink);
- tmpLink=new Link (model);
- tmpLink->setBeginBranch (selbi);
- tmpLink->createMapObj();
- tmpLink->setStyleBegin("None");
- tmpLink->setStyleEnd("None");
- tmpLink->setEndPoint ( mapToScene (e->pos() ) );
- tmpLink->updateLink();
- return;
- }
-
- // Start moving around
- if (lmo)
- {
- // Left Button Move Branches
- if (e->button() == Qt::LeftButton )
- {
- // No system flag clicked, take care of moving copymodes or simply moving
- movingObj_offset.setX( p.x() - lmo->x() );
- movingObj_offset.setY( p.y() - lmo->y() );
- movingObj_orgPos.setX (lmo->x() );
- movingObj_orgPos.setY (lmo->y() );
- if (ti->depth()>0)
- {
- lmo->setRelPos();
- movingObj_orgRelPos=lmo->getRelPos();
- }
-
- // If modMode==copy, then we want to "move" the _new_ object around
- // then we need the offset from p to the _old_ selection, because of tmp
- if (mainWindow->getModMode()==Main::ModModeCopy &&
- e->modifiers() & Qt::ShiftModifier)
- {
- if (selbi)
- {
- setState (CopyingObject);
- model->copy();
- model->paste();
- model->select (selbi->getLastBranch());
- model->reposition();
- }
- } else
- setState (MovingObject);
-
- movingObj=model->getSelectedLMO();
- } else
- // Middle Button Toggle Scroll
- // (On Mac OS X this won't work, but we still have
- // a button in the toolbar)
- if (e->button() == Qt::MidButton )
- model->toggleScroll();
- } else
- { // No lmo found, check XLinks
- if (ti)
- {
- if (ti->getType()==TreeItem::XLink)
- {
- XLinkObj* xlo=(XLinkObj*) ((MapItem*)ti)->getMO() ;
- if (xlo)
- {
- setState (EditingLink);
- int i=xlo->ctrlPointInClickBox(p);
- if (i>=0) xlo->setSelection (i);
- movingObj_offset.setX( p.x() - xlo->x() );
- movingObj_offset.setY( p.y() - xlo->y() );
- movingObj_orgPos.setX (xlo->x() );
- movingObj_orgPos.setY (xlo->y() );
-
- }
- }
- }
- else
- { // No MapObj found, we are on the scene itself
- // Left Button move Pos of sceneView
- if (e->button() == Qt::LeftButton )
- {
- setState (MovingView);
- movingObj=NULL; // move Content not Obj
- movingObj_offset=e->globalPos();
- movingCont_start=QPointF (
- horizontalScrollBar()->value(),
- verticalScrollBar()->value());
- movingVec=QPointF(0,0);
- setCursor(HandOpenCursor);
- }
- }
- }
-}
-
-void MapEditor::mouseMoveEvent(QMouseEvent* e)
-{
- // Show mouse position for debugging in statusBar
- if (debug && e->modifiers() & Qt::ControlModifier )
- mainWindow->statusMessage(
- QString("ME::mousePressEvent Scene: %1 widget: %2").
- arg(qpointFToString(mapToScene (e->pos()))).
- arg(qpointFToString(e->pos())));
-
- TreeItem *seli=model->getSelectedItem();
-
- MapObj* mosel=NULL;
- if (seli )
- mosel=((MapItem*)seli)->getMO();
-
- // Move the selected MapObj
- if ( mosel && (state==MovingObject || state==CopyingObject || state==EditingLink))
- {
- int margin=50;
-
- // Check if we have to scroll
- vPan.setX(0);
- vPan.setY(0);
- if (e->y() >=0 && e->y() <= margin)
- vPan.setY( e->y() - margin );
- else if ( e->y() <= height() && e->y() > height()-margin )
- vPan.setY(e->y() - height() + margin );
- if ( e->x() >=0 && e->x() <= margin)
- vPan.setX( e->x() - margin );
- else if ( e->x() <= width() && e->x() > width()-margin )
- vPan.setX(e->x() - width() + margin );
-
- pointerPos=e->pos();
- pointerMod=e->modifiers();
- moveObject ();
- } // selection && moving_obj
-
- // Draw a link from one branch to another
- if (state==DrawingLink)
- {
- tmpLink->setEndPoint ( mapToScene (e->pos() ) );
- tmpLink->updateLink();
- }
-
- // Move sceneView
- if (state==MovingView && e->buttons() == Qt::LeftButton )
- {
- QPointF p=e->globalPos();
- movingVec.setX(-p.x() + movingObj_offset.x() );
- movingVec.setY(-p.y() + movingObj_offset.y() );
- horizontalScrollBar()->setSliderPosition((int)( movingCont_start.x()+movingVec.x() ));
- verticalScrollBar()->setSliderPosition((int)( movingCont_start.y()+movingVec.y() ) );
- scrollBarPosAnimation.stop(); // Avoid flickering
- }
-}
-
-void MapEditor::moveObject ()
-{
- if (!panningTimer->isActive() )
- panningTimer->start(50);
-
- QPointF p = mapToScene(pointerPos);
- TreeItem *seli=model->getSelectedItem();
- LinkableMapObj* lmosel=NULL;
- if (seli)
- lmosel=((MapItem*)seli)->getLMO();
-
- objectMoved=true;
- // reset cursor if we are moving and don't copy
- if (mainWindow->getModMode()!=Main::ModModeCopy)
- setCursor (Qt::ArrowCursor);
-
- // Check if we could link
- TreeItem *ti=findMapItem (p, seli);
- BranchItem *dsti=NULL;
- LinkableMapObj* dst=NULL;
- if (ti && ti!=seli && ti->isBranchLikeType())
- {
- dsti=(BranchItem*)ti;
- dst=dsti->getLMO();
- } else
- dsti=NULL;
-
- if (lmosel)
- {
- if (seli->getType()==TreeItem::Image)
- {
- FloatImageObj *fio=(FloatImageObj*)lmosel;
- fio->moveCenter (p.x() - movingObj_offset.x(), p.y() - movingObj_offset.y() );
- fio->setRelPos();
- fio->updateLinkGeometry(); //no need for reposition, if we update link here
- model->emitSelectionChanged(); // position has changed
-
- // Relink float to new mapcenter or branch, if shift is pressed
- // Only relink, if selection really has a new parent
- if ( pointerMod==Qt::ShiftModifier && dsti && dsti != seli->parent() )
- {
- // Also save the move which was done so far
- QString pold=qpointFToString(movingObj_orgRelPos);
- QString pnow=qpointFToString(fio->getRelPos());
- model->saveState(
- seli,
- "moveRel "+pold,
- seli,
- "moveRel "+pnow,
- QString("Move %1 to relative position %2").arg(model->getObjectName(lmosel)).arg(pnow));
- model->reposition();
-
- model->relinkImage ((ImageItem*) seli,dsti);
- model->select (seli);
- }
- } else if (seli->isBranchLikeType() )
- { // selection != a FloatObj
- if (seli->depth()==0)
- {
- // Move mapcenter
- lmosel->move (p-movingObj_offset);
- if (pointerMod==Qt::ShiftModifier)
- {
- // Move only mapcenter, leave its children where they are
- QPointF v;
- v=lmosel->getAbsPos();
- for (int i=0; i<seli->branchCount(); ++i)
- {
- seli->getBranchObjNum(i)->setRelPos();
- seli->getBranchObjNum(i)->setOrientation();
- }
- }
- } else
- {
- if (seli->depth()==1)
- {
- // Move mainbranch
- if (!lmosel->hasParObjTmp())
- lmosel->move(p-movingObj_offset);
- lmosel->setRelPos();
- } else
- {
- // d>1, move ordinary branch
- if (lmosel->getOrientation() == LinkableMapObj::LeftOfCenter)
- // Add width of bbox here, otherwise alignRelTo will cause jumping around
- lmosel->move(
- p.x() - movingObj_offset.x(),
- p.y() - movingObj_offset.y() + lmosel->getTopPad() );
- else
- lmosel->move(p.x() - movingObj_offset.x(), p.y() - movingObj_offset.y() - lmosel->getTopPad());
- BranchItem *selbi = ((BranchItem*)seli);
- if ( selbi->parentBranch()->getChildrenLayout() == BranchItem::FreePositioning) lmosel->setRelPos();
- }
-
- } // depth>0
-
- // Maybe we can relink temporary?
- if (dsti)
- {
- if (pointerMod==Qt::ControlModifier)
- {
- // Special case: CTRL to link below dst
- lmosel->setParObjTmp (dst,p,+1);
- } else if (pointerMod==Qt::ShiftModifier)
- lmosel->setParObjTmp (dst,p,-1);
- else
- lmosel->setParObjTmp (dst,p,0);
- } else
- lmosel->unsetParObjTmp();
-
- // reposition subbranch
- lmosel->reposition();
-
- QItemSelection sel=model->getSelectionModel()->selection();
- updateSelection(sel,sel); // position has changed
-
- // In winter mode shake snow from heading
- if (winter) model->emitDataChanged(seli);
- } // Moving branchLikeType
- } // End of lmosel!=NULL
- else if (seli && seli->getType()==TreeItem::XLink)
- {
- // Move XLink control point
- MapObj* mosel=((MapItem*)seli)->getMO();
- if (mosel)
- {
- mosel->move( p-movingObj_offset ); // FIXME-3 Missing savestate
- model->setChanged();
- model->emitSelectionChanged();
- }
- } else
- qWarning("ME::moveObject Huh? I'm confused.");
-
- scene()->update();
-
- return;
-}
-
-void MapEditor::mouseReleaseEvent(QMouseEvent* e)
-{
- QPointF p = mapToScene(e->pos());
- TreeItem *seli=model->getSelectedItem();
-
- TreeItem *dsti=NULL;
- if (seli) dsti=findMapItem(p, seli);
- LinkableMapObj* dst=NULL;
- BranchItem *selbi=model->getSelectedBranch();
- if (dsti && dsti->isBranchLikeType ())
- dst=((MapItem*)dsti)->getLMO();
- else
- dsti=NULL;
-
-
- // Have we been picking color?
- if (state==PickingColor)
- {
- setCursor (Qt::ArrowCursor);
- // Check if we are over another branch
- if (dst)
- {
- if (e->modifiers() & Qt::ShiftModifier)
- model->colorBranch (mainWindow->getCurrentColor());
- else
- model->colorSubtree (mainWindow->getCurrentColor());
- }
- setState (Neutral);
- return;
- }
-
- // Have we been drawing a link?
- if (state==DrawingLink)
- {
- setState (Neutral);
- // Check if we are over another branch
- if (dsti)
- {
- tmpLink->setEndBranch ( ((BranchItem*)dsti) );
- tmpLink->activate();
- tmpLink->updateLink();
- if (model->createLink (tmpLink) )
- {
- model->saveState(
- tmpLink->getBeginLinkItem(),"delete ()",
- seli,QString("addXLink (\"%1\",\"%2\",%3,\"%4\")")
- .arg(model->getSelectString(tmpLink->getBeginBranch()))
- .arg(model->getSelectString(tmpLink->getEndBranch()))
- .arg(tmpLink->getPen().width())
- .arg(tmpLink->getPen().color().name()),
- QString("Adding Link from %1 to %2").arg(model->getObjectName(seli)).arg(model->getObjectName (dsti)));
- return;
- }
- }
- delete (tmpLink);
- tmpLink=NULL;
- return;
- }
-
- // Have we been moving something?
- if ( seli && state==MovingObject)
- {
- panningTimer->stop();
- if (seli->getType()==TreeItem::Image)
- {
- FloatImageObj *fio=(FloatImageObj*)( ((MapItem*)seli)->getLMO());
- if(fio)
- {
- // Moved Image, we need to reposition
- QString pold=qpointFToString(movingObj_orgRelPos);
- QString pnow=qpointFToString(fio->getRelPos());
- model->saveState(
- seli,
- "moveRel " + pold,
- seli,
- "moveRel " + pnow,
- QString("Move %1 to relative position %2").arg(model->getObjectName(seli)).arg(pnow));
-
- model->emitDataChanged(seli->parent()); // Parent of image has changed
- model->reposition();
- }
- }
-
- if (selbi && selbi->depth()==0)
- {
- if (movingObj_orgPos != selbi->getBranchObj()->getAbsPos())
- {
- QString pold=qpointFToString(movingObj_orgPos);
- QString pnow=qpointFToString(selbi->getBranchObj()->getAbsPos());
-
- model->saveState(
- selbi,
- "move "+pold,
- selbi,
- "move "+pnow,
- QString("Move mapcenter %1 to position %2").arg(model->getObjectName(selbi)).arg(pnow));
- }
- }
-
- if (seli->isBranchLikeType() ) //(seli->getType() == TreeItem::Branch )
- { // A branch was moved
- LinkableMapObj* lmosel=NULL;
- lmosel=((MapItem*)seli)->getLMO();
-
- // save the position in case we link to mapcenter
- QPointF savePos=QPointF (lmosel->getAbsPos() );
-
- // Reset the temporary drawn link to the original one
- lmosel->unsetParObjTmp();
-
- // For Redo we may need to save original selection
- QString preSelStr=model->getSelectString(seli);
-
- if (dsti && objectMoved)
- {
- // We have a destination, relink to that
- BranchObj* selbo=model->getSelectedBranchObj();
-
- QString preParStr=model->getSelectString (seli->parent() );
- QString preNum=QString::number (seli->num(),10);
- QString preDstParStr;
-
- if (e->modifiers() & Qt::ShiftModifier && dsti->parent() )
- { // Link above dst
- preDstParStr=model->getSelectString (dsti->parent() );
- model->relinkBranch (
- (BranchItem*)seli,
- (BranchItem*)dsti->parent(),
- ((BranchItem*)dsti)->num(),
- true);
- } else
- if (e->modifiers() & Qt::ControlModifier && dsti->parent() )
- {
- // Link below dst
- preDstParStr=model->getSelectString (dsti->parent() );
- model->relinkBranch (
- (BranchItem*)seli,
- (BranchItem*)dsti->parent(),
- ((BranchItem*)dsti)->num()+1,
- true);
- } else
- { // Append to dst
- preDstParStr=model->getSelectString(dsti);
- model->relinkBranch (
- (BranchItem*)seli,
- (BranchItem*)dsti,
- -1,
- true,
- movingObj_orgPos);
- if (dsti->depth()==0) selbo->move (savePos);
- }
- } else
- {
- // No destination, undo temporary move
-
- if (seli->depth()==1)
- {
- // The select string might be different _after_ moving around.
- // Therefor reposition and then use string of old selection, too
- model->reposition();
-
- QPointF rp(lmosel->getRelPos());
- if (rp != movingObj_orgRelPos)
- {
- QString ps=qpointFToString(rp);
- model->saveState(
- model->getSelectString(lmosel), "moveRel "+qpointFToString(movingObj_orgRelPos),
- preSelStr, "moveRel "+ps,
- QString("Move %1 to relative position %2").arg(model->getObjectName(lmosel)).arg(ps));
- }
- }
-
- if (selbi->parentBranch()->getChildrenLayout() == BranchItem::FreePositioning)
- {
- lmosel->setRelPos();
- model->reposition();
- }else
- {
-
-
- // Draw the original link, before selection was moved around
- if (settings.value("/animation/use",true).toBool()
- && seli->depth()>1
- // && distance (lmosel->getRelPos(),movingObj_orgRelPos)<3
- )
- {
- lmosel->setRelPos(); // calc relPos first for starting point
-
- model->startAnimation(
- (BranchObj*)lmosel,
- lmosel->getRelPos(),
- movingObj_orgRelPos
- );
- } else
- model->reposition();
- }
- }
- }
- // Finally resize scene, if needed
- scene()->update();
- movingObj=NULL;
- objectMoved=false;
- vPan=QPoint ();
- } else
- // maybe we moved View: set old cursor
- setCursor (Qt::ArrowCursor);
-
- if (state!=EditingHeading) setState (Neutral); // Continue editing after double click!
-
- QGraphicsView::mouseReleaseEvent(e);
-}
-
-void MapEditor::mouseDoubleClickEvent(QMouseEvent* e)
-{
- if (e->button() == Qt::LeftButton )
- {
- QPointF p = mapToScene(e->pos());
- TreeItem *ti=findMapItem (p, NULL);
- LinkableMapObj *lmo;
- if (ti)
- {
- if (state==EditingHeading) editHeadingFinished();
- model->select (ti);
- BranchItem* selbi=model->getSelectedBranch();
- if (selbi)
- {
- lmo=((MapItem*)ti)->getLMO();
- QString foname=((BranchObj*)lmo)->getSystemFlagName(p);
- if (!foname.isEmpty()) return; // Don't edit heading when double clicking system flag
-
- }
- e->accept();
- editHeading();
- }
- }
-}
-
-void MapEditor::wheelEvent(QWheelEvent* e)
-{
- if (e->modifiers() & Qt::ControlModifier && e->orientation()==Qt::Vertical)
- {
- if (e->delta()>0)
- setZoomFactorTarget (zoomFactorTarget*1.15);
- else
- setZoomFactorTarget (zoomFactorTarget*0.85);
- } else
- {
- scrollBarPosAnimation.stop();
- QGraphicsView::wheelEvent (e);
- }
-}
-
-void MapEditor::focusOutEvent (QFocusEvent*)
-{
- //qDebug()<<"ME::focusOutEvent"<<e->reason();
- if (state==EditingHeading) editHeadingFinished();
-}
-
-void MapEditor::resizeEvent (QResizeEvent* e)
-{
- QGraphicsView::resizeEvent( e );
-}
-
-void MapEditor::dragEnterEvent(QDragEnterEvent *event)
-{
- //for (unsigned int i=0;event->format(i);i++) // Debug mime type
- // cerr << event->format(i) << endl;
-
- if (event->mimeData()->hasImage())
- event->acceptProposedAction();
- else
- if (event->mimeData()->hasUrls())
- event->acceptProposedAction();
-}
-
-void MapEditor::dragMoveEvent(QDragMoveEvent *)
-{
-}
-
-void MapEditor::dragLeaveEvent(QDragLeaveEvent *event)
-{
- event->accept();
-}
-
-void MapEditor::dropEvent(QDropEvent *event)
-{
- BranchItem *selbi=model->getSelectedBranch();
- if (selbi)
- {
- if (debug)
- {
- foreach (QString format,event->mimeData()->formats())
- qDebug()<< "MapEditor: Dropped format: "<<qPrintable (format);
- foreach (QUrl url,event->mimeData()->urls())
- {
- qDebug()<< " URL-path:" <<url.path();
- qDebug()<< "URL-string:" <<url.toString();
- qDebug()<< " enc:" <<url.toEncoded();
- qDebug()<< " valid:" <<url.isValid();
- }
- qDebug() << "============== mimeData ===================";
- qDebug() << "has-img : " << event->mimeData()->hasImage();
- qDebug() << "has-urls: " << event->mimeData()->hasUrls();
- qDebug() << " text: " << event->mimeData()->text();
- qDebug() << "===========================================";
- }
-
- if (event->mimeData()->hasUrls())
- {
- // Try text representation first, which works on windows, but in
- // Linux only for https, not local images
- QString url = event->mimeData()->text();
- if (url.isEmpty() )
- {
- QByteArray ba = event->mimeData()->urls().first().path().toLatin1();
- QByteArray ba2;
- for (int i = 0; i < ba.count(); i++)
- if (ba.at(i) != 0) ba2.append(ba.at(i));
- url = ba2;
- }
-
-
- BranchItem *bi = NULL;
- // Workaround to avoid adding empty branches
- if (!url.isEmpty())
- {
- if (url.startsWith("file://")) url.remove(0,7);
-
-#if defined(Q_OS_WIN32)
- if (url.startsWith("/")) url.remove(0,1);
-#endif
- if (isImage (url))
- {
- if (debug) qDebug() << "dropped url seems to be image: " << url;
- // Image, try to download or set image from local file
- //model->downloadImage (url);
- model->loadImage(bi, url);
- if (debug) qDebug() << "finished loading image";
- } else
- {
- bi = model->addNewBranch();
- if (bi)
- {
- model->select(bi);
- if (url.endsWith(".vym", Qt::CaseInsensitive))
- model->setVymLink(url);
- else
- {
- model->setURL(url);
- model->setHeadingPlainText(url);
- }
-
- model->select (bi->parent());
- }
- }
- }
- }
- }
- event->acceptProposedAction();
-}
-
-void MapEditor::setState (EditorState s)
-{
- if (state!=Neutral && s!=Neutral)
- qWarning ()<<"MapEditor::setState switching directly from "<<state<<" to "<<s;
- state=s;
- /* if (debug)
- {
- QString s;
- switch (state)
- {
- case Neutral: s="Neutral";break;
- case EditingHeading: s="EditingHeading";break;
- case EditingLink: s="EditingLink";break;
- case MovingObject: s="MovingObject";break;
- case MovingView: s="MovingView";break;
- case PickingColor: s="PickingColor";break;
- case CopyingObject: s="CopyingObject";break;
- case DrawingLink: s="DrawingLink";break;
- }
- qDebug()<<"MapEditor: State "<<s<< " of "<<model->getMapName();
- }
- */
-}
-
-MapEditor::EditorState MapEditor::getState()
-{
- return state;
-}
-
-void MapEditor::updateSelection(QItemSelection nsel,QItemSelection dsel)
-{
- QList <MapItem*> itemsSelected;
- QList <MapItem*> itemsDeselected;
-
- QItemSelection sel=model->getSelectionModel()->selection();
- foreach (QModelIndex ix,sel.indexes() )
- {
- MapItem *mi= static_cast<MapItem*>(ix.internalPointer());
- if (mi->isBranchLikeType()
- ||mi->getType()==TreeItem::Image
- ||mi->getType()==TreeItem::XLink)
- if (!itemsSelected.contains(mi))
- itemsSelected.append (mi);
- }
- foreach (QModelIndex ix,dsel.indexes() )
- {
- MapItem *mi= static_cast<MapItem*>(ix.internalPointer());
- if (mi->isBranchLikeType()
- ||mi->getType()==TreeItem::Image
- ||mi->getType()==TreeItem::XLink)
- if (!itemsDeselected.contains(mi))
- itemsDeselected.append (mi);
- }
-
- // Trim list of selection paths
- while (itemsSelected.count() < selPathList.count() )
- delete selPathList.takeFirst();
-
- // Reduce polygons
- while (itemsSelected.count() < selPathList.count() )
- delete selPathList.takeFirst();
-
- // Add additonal polygons
- QGraphicsPathItem *sp;
- while (itemsSelected.count() > selPathList.count() )
- {
- sp = mapScene->addPath(
- QPainterPath(),
- QPen(selectionColor),
- selectionColor);
- sp->show();
- selPathList.append (sp);
- }
-
-
- // Reposition polygons
- for (int i=0; i<itemsSelected.count();++i)
- {
- MapObj *mo=itemsSelected.at(i)->getMO();
- sp=selPathList.at(i);
- sp->setPath (mo->getClickPath() );
- sp->setPen (selectionColor);
- sp->setBrush (selectionColor);
- sp->setParentItem (mo);
- sp->setZValue (dZ_SELBOX);
-
- // Reposition also LineEdit for heading during animation
- if (lineEdit) lineEdit->move (mo->getAbsPos().toPoint() );
- }
-
- scene()->update();
-}
-
-void MapEditor::updateData (const QModelIndex &sel)
-{
- TreeItem *ti= static_cast<TreeItem*>(sel.internalPointer());
-
-/* testing
- qDebug() << "ME::updateData";
- if (!ti)
- {
- qDebug() << " ti=NULL";
- return;
- }
- qDebug() << " ti="<<ti;
- qDebug() << " h="<<ti->getHeadingPlain();
-*/
-
- if (ti && ti->isBranchLikeType())
- {
- BranchObj *bo=(BranchObj*) ( ((MapItem*)ti)->getLMO());
- bo->updateData();
- }
-
- if (winter)
- {
- QList <QRectF> obstacles;
- BranchObj *bo;
- BranchItem *cur=NULL;
- BranchItem *prev=NULL;
- model->nextBranch(cur,prev);
- while (cur)
- {
- if (!cur->hasHiddenExportParent())
- {
- // Branches
- bo=(BranchObj*)(cur->getLMO());
- if (bo && bo->isVisibleObj())
- obstacles.append(bo->getBBox());
- }
- model->nextBranch(cur,prev);
- }
- winter->setObstacles(obstacles);
- }
-}
-
-void MapEditor::setSelectionColor (QColor col)
-{
- selectionColor=col;
- selectionColor.setAlpha (220);
- QItemSelection sel=model->getSelectionModel()->selection();
- updateSelection(sel,sel);
-}
-
-
-QColor MapEditor::getSelectionColor ()
-{
- return selectionColor;
-}
-
-