insilmaril@815: #include "mapeditor.h" insilmaril@0: insilmaril@0: #include insilmaril@95: #include insilmaril@0: #include insilmaril@0: insilmaril@720: #include insilmaril@720: insilmaril@750: #include "branchitem.h" insilmaril@792: #include "geometry.h" insilmaril@175: #include "mainwindow.h" insilmaril@175: #include "misc.h" insilmaril@314: #include "warningdialog.h" insilmaril@790: #include "xlinkitem.h" insilmaril@0: insilmaril@0: insilmaril@0: extern int statusbarTime; insilmaril@0: extern Main *mainWindow; insilmaril@164: extern QString tmpVymDir; insilmaril@166: extern QString clipboardDir; insilmaril@491: extern QString clipboardFile; insilmaril@166: extern bool clipboardEmpty; insilmaril@473: extern bool debug; insilmaril@0: insilmaril@366: extern QMenu* branchContextMenu; insilmaril@366: extern QMenu* floatimageContextMenu; insilmaril@366: extern QMenu* canvasContextMenu; insilmaril@366: insilmaril@0: extern Settings settings; insilmaril@269: extern QString iconPath; insilmaril@0: insilmaril@0: /////////////////////////////////////////////////////////////////////// insilmaril@0: /////////////////////////////////////////////////////////////////////// insilmaril@720: MapEditor::MapEditor( VymModel *vm) insilmaril@0: { insilmaril@0: //cout << "Constructor ME "<setBackgroundBrush (QBrush(Qt::white, Qt::SolidPattern)); insilmaril@408: insilmaril@767: zoomFactor=zoomFactorTarget=1; insilmaril@767: insilmaril@720: model=vm; insilmaril@645: model->setScene (mapScene); insilmaril@720: model->registerEditor(this); insilmaril@727: model->makeDefault(); // No changes in model so far insilmaril@408: insilmaril@408: setScene (mapScene); insilmaril@0: insilmaril@0: printer=NULL; insilmaril@0: insilmaril@366: // Create bitmap cursors, platform dependant insilmaril@404: HandOpenCursor=QCursor (QPixmap(iconPath+"cursorhandopen.png"),1,1); insilmaril@404: PickColorCursor=QCursor ( QPixmap(iconPath+"cursorcolorpicker.png"), 5,27 ); insilmaril@404: CopyCursor=QCursor ( QPixmap(iconPath+"cursorcopy.png"), 1,1 ); insilmaril@404: XLinkCursor=QCursor ( QPixmap(iconPath+"cursorxlink.png"), 1,7 ); insilmaril@398: insilmaril@769: //setFocusPolicy (Qt::StrongFocus); //FIXME-3 insilmaril@0: insilmaril@0: pickingColor=false; insilmaril@91: drawingLink=false; insilmaril@93: copyingObj=false; insilmaril@798: objectMoved=false; insilmaril@0: insilmaril@0: editingBO=NULL; insilmaril@0: movingObj=NULL; insilmaril@0: insilmaril@0: printFrame=true; insilmaril@0: printFooter=true; insilmaril@0: insilmaril@417: setAcceptDrops (true); insilmaril@0: insilmaril@746: //model->reposition(); //FIXME-3 really still needed? insilmaril@381: insilmaril@531: insilmaril@769: // Shortcuts and actions insilmaril@769: QAction *a; insilmaril@769: a = new QAction("Select upper branch", this); insilmaril@769: a->setShortcut (Qt::Key_Up ); insilmaril@769: a->setShortcutContext (Qt::WidgetShortcut); insilmaril@769: addAction (a); insilmaril@769: connect( a, SIGNAL( triggered() ), this, SLOT( cursorUp() ) ); insilmaril@769: insilmaril@769: a = new QAction( "Select lower branch",this); insilmaril@769: a->setShortcut ( Qt::Key_Down ); insilmaril@769: a->setShortcutContext (Qt::WidgetShortcut); insilmaril@769: addAction (a); insilmaril@769: connect( a, SIGNAL( triggered() ), this, SLOT( cursorDown() ) ); insilmaril@769: insilmaril@769: a = new QAction( "Select left branch", this); insilmaril@769: a->setShortcut (Qt::Key_Left ); insilmaril@769: // a->setShortcutContext (Qt::WindowShortcut); insilmaril@769: a->setShortcutContext (Qt::WidgetWithChildrenShortcut); insilmaril@769: addAction (a); insilmaril@769: connect( a, SIGNAL( triggered() ), this, SLOT( cursorLeft() ) ); insilmaril@769: insilmaril@769: a = new QAction( "Select child branch", this); insilmaril@769: a->setShortcut (Qt::Key_Right); insilmaril@769: a->setShortcutContext (Qt::WidgetWithChildrenShortcut); insilmaril@769: addAction (a); insilmaril@769: connect( a, SIGNAL( triggered() ), this, SLOT( cursorRight() ) ); insilmaril@769: insilmaril@769: a = new QAction( "Select first branch", this); insilmaril@769: a->setShortcut (Qt::Key_Home ); insilmaril@769: a->setShortcutContext (Qt::WidgetWithChildrenShortcut); insilmaril@769: addAction (a); insilmaril@769: connect( a, SIGNAL( triggered() ), this, SLOT( cursorFirst() ) ); insilmaril@769: insilmaril@769: a = new QAction( "Select last branch",this); insilmaril@769: a->setShortcut ( Qt::Key_End ); insilmaril@769: a->setShortcutContext (Qt::WidgetWithChildrenShortcut); insilmaril@769: addAction (a); insilmaril@769: connect( a, SIGNAL( triggered() ), this, SLOT( cursorLast() ) ); insilmaril@769: insilmaril@720: // Action to embed LineEdit for heading in Scene insilmaril@720: editingHeading=false; insilmaril@720: lineEdit=new QLineEdit; insilmaril@720: lineEdit->hide(); insilmaril@720: QGraphicsProxyWidget *pw=scene()->addWidget (lineEdit); insilmaril@772: pw->setZValue (Z_LINEEDIT); insilmaril@676: insilmaril@769: a = new QAction( tr( "Edit heading","MapEditor" ), this); insilmaril@720: a->setShortcut ( Qt::Key_Return ); //Edit heading insilmaril@810: a->setShortcutContext (Qt::WidgetShortcut); insilmaril@720: addAction (a); insilmaril@720: connect( a, SIGNAL( triggered() ), this, SLOT( editHeading() ) ); insilmaril@720: a = new QAction( tr( "Edit heading","MapEditor" ), this); insilmaril@720: a->setShortcut ( Qt::Key_Enter); //Edit heading insilmaril@720: addAction (a); insilmaril@720: connect( a, SIGNAL( triggered() ), this, SLOT( editHeading() ) ); insilmaril@628: insilmaril@728: // Selections insilmaril@728: selectionColor =QColor (255,255,0); insilmaril@728: insilmaril@728: insilmaril@746: // Attributes //FIXME-2 testing only... insilmaril@638: QString k; insilmaril@638: AttributeDef *ad; insilmaril@628: attrTable= new AttributeTable(); insilmaril@638: k="A - StringList"; insilmaril@638: ad=attrTable->addKey (k,StringList); insilmaril@638: if (ad) insilmaril@638: { insilmaril@638: QStringList sl; insilmaril@638: sl <<"val 1"<<"val 2"<< "val 3"; insilmaril@638: ad->setValue (QVariant (sl)); insilmaril@638: } insilmaril@638: //attrTable->addValue ("Key A","P 1"); insilmaril@638: //attrTable->addValue ("Key A","P 2"); insilmaril@638: //attrTable->addValue ("Key A","P 3"); insilmaril@638: //attrTable->addValue ("Key A","P 4"); insilmaril@638: k="B - FreeString"; insilmaril@638: ad=attrTable->addKey (k,FreeString); insilmaril@638: if (ad) insilmaril@638: { insilmaril@638: //attrTable->addValue ("Key B","w1"); insilmaril@638: //attrTable->addValue ("Key B","w2"); insilmaril@638: } insilmaril@638: k="C - UniqueString"; insilmaril@638: ad=attrTable->addKey (k,UniqueString); insilmaril@638: if (ad) insilmaril@638: { insilmaril@638: //attrTable->addKey ("Key Prio"); insilmaril@638: //attrTable->addValue ("Key Prio","Prio 1"); insilmaril@638: //attrTable->addValue ("Key Prio","Prio 2"); insilmaril@638: } insilmaril@0: } insilmaril@0: insilmaril@0: MapEditor::~MapEditor() insilmaril@0: { insilmaril@746: //cout <<"Destructor MapEditor for "<getMapName().toStdString()<unregisterEditor(this); insilmaril@0: } insilmaril@0: insilmaril@645: VymModel* MapEditor::getModel() insilmaril@0: { insilmaril@645: return model; insilmaril@0: } insilmaril@0: insilmaril@408: QGraphicsScene * MapEditor::getScene() insilmaril@0: { insilmaril@408: return mapScene; insilmaril@0: } insilmaril@0: insilmaril@802: void MapEditor::scrollTo (const QModelIndex &index) insilmaril@772: { insilmaril@772: if (index.isValid()) insilmaril@772: { insilmaril@776: LinkableMapObj* lmo=NULL; insilmaril@776: TreeItem *ti= static_cast(index.internalPointer()); insilmaril@776: if (ti->getType()==TreeItem::Image ||ti->isBranchLikeType() ) insilmaril@779: lmo=((MapItem*)ti)->getLMO(); insilmaril@798: if (lmo) insilmaril@798: { insilmaril@798: QRectF r=lmo->getBBox(); insilmaril@802: setScrollBarPosTarget (r); insilmaril@798: } insilmaril@772: } insilmaril@772: } insilmaril@772: insilmaril@767: void MapEditor::setScrollBarPosTarget (const QRectF &rect) insilmaril@767: { insilmaril@767: // Code copied from Qt sources insilmaril@767: int xmargin=50; insilmaril@767: int ymargin=50; insilmaril@767: insilmaril@767: qreal width = viewport()->width(); insilmaril@767: qreal height = viewport()->height(); insilmaril@767: QRectF viewRect = matrix().mapRect(rect); insilmaril@767: insilmaril@767: qreal left = horizontalScrollBar()->value(); insilmaril@767: qreal right = left + width; insilmaril@767: qreal top = verticalScrollBar()->value(); insilmaril@767: qreal bottom = top + height; insilmaril@767: insilmaril@802: scrollBarPosTarget=getScrollBarPos(); insilmaril@802: insilmaril@767: if (viewRect.left() <= left + xmargin) { insilmaril@767: // need to scroll from the left insilmaril@767: // if (!d->leftIndent) insilmaril@767: scrollBarPosTarget.setX(int(viewRect.left() - xmargin - 0.5)); insilmaril@767: } insilmaril@767: if (viewRect.right() >= right - xmargin) { insilmaril@767: // need to scroll from the right insilmaril@767: // if (!d->leftIndent) insilmaril@767: scrollBarPosTarget.setX(int(viewRect.right() - width + xmargin + 0.5)); insilmaril@767: } insilmaril@767: if (viewRect.top() <= top + ymargin) { insilmaril@767: // need to scroll from the top insilmaril@767: // if (!d->topIndent) insilmaril@767: scrollBarPosTarget.setY(int(viewRect.top() - ymargin - 0.5)); insilmaril@767: } insilmaril@767: if (viewRect.bottom() >= bottom - ymargin) { insilmaril@767: // need to scroll from the bottom insilmaril@767: // if (!d->topIndent) insilmaril@767: scrollBarPosTarget.setY(int(viewRect.bottom() - height + ymargin + 0.5)); insilmaril@767: } insilmaril@767: insilmaril@802: if (scrollBarPosTarget==getScrollBarPos()) return; insilmaril@802: insilmaril@767: if (scrollBarPosAnimation.state()==QtAbstractAnimation::Running) insilmaril@767: scrollBarPosAnimation.stop(); insilmaril@802: insilmaril@802: if (settings.value ("/animation/use/",true).toBool() ) insilmaril@802: { insilmaril@802: scrollBarPosAnimation.setTargetObject (this); insilmaril@802: scrollBarPosAnimation.setPropertyName ("scrollBarPos"); insilmaril@802: scrollBarPosAnimation.setDuration(1000); insilmaril@802: scrollBarPosAnimation.setEasingCurve ( QtEasingCurve::OutQuint); insilmaril@802: scrollBarPosAnimation.setStartValue( insilmaril@802: QPointF (horizontalScrollBar()->value() , insilmaril@802: verticalScrollBar()->value() ) ); insilmaril@802: scrollBarPosAnimation.setEndValue(scrollBarPosTarget); insilmaril@802: scrollBarPosAnimation.start(); insilmaril@802: } else insilmaril@802: setScrollBarPos (scrollBarPosTarget); insilmaril@767: } insilmaril@767: insilmaril@767: QPointF MapEditor::getScrollBarPosTarget() insilmaril@767: { insilmaril@767: return scrollBarPosTarget; insilmaril@767: } insilmaril@767: insilmaril@767: insilmaril@767: void MapEditor::setScrollBarPos(const QPointF &p) insilmaril@767: { insilmaril@767: scrollBarPos=p; insilmaril@767: horizontalScrollBar()->setValue(int(p.x())); insilmaril@767: verticalScrollBar()->setValue(int(p.y())); insilmaril@767: } insilmaril@767: insilmaril@767: QPointF MapEditor::getScrollBarPos() insilmaril@767: { insilmaril@802: return QPointF (horizontalScrollBar()->value(),verticalScrollBar()->value()); insilmaril@802: //return scrollBarPos; insilmaril@767: } insilmaril@767: insilmaril@767: void MapEditor::setZoomFactorTarget (const qreal &zft) insilmaril@767: { insilmaril@767: zoomFactorTarget=zft; insilmaril@767: if (zoomAnimation.state()==QtAbstractAnimation::Running) insilmaril@767: zoomAnimation.stop(); insilmaril@802: if (settings.value ("/animation/use/",true).toBool() ) insilmaril@802: { insilmaril@815: //zoomAnimation=QPropertyAnimation(this, "zoomFactor"); insilmaril@802: zoomAnimation.setTargetObject (this); insilmaril@802: zoomAnimation.setPropertyName ("zoomFactor"); insilmaril@802: zoomAnimation.setDuration(1000); insilmaril@802: zoomAnimation.setEasingCurve ( QtEasingCurve::OutQuint); insilmaril@802: zoomAnimation.setStartValue(zoomFactor); insilmaril@802: zoomAnimation.setEndValue(zft); insilmaril@802: zoomAnimation.start(); insilmaril@802: } else insilmaril@802: setZoomFactor (zft); insilmaril@767: } insilmaril@767: insilmaril@767: qreal MapEditor::getZoomFactorTarget() insilmaril@767: { insilmaril@767: return zoomFactorTarget; insilmaril@767: } insilmaril@767: insilmaril@767: insilmaril@767: void MapEditor::setZoomFactor(const qreal &zf) insilmaril@767: { insilmaril@767: zoomFactor=zf; insilmaril@767: setMatrix (QMatrix(zf, 0, 0, zf, 0, 0),false ); insilmaril@767: } insilmaril@767: insilmaril@767: qreal MapEditor::getZoomFactor() insilmaril@767: { insilmaril@767: return zoomFactor; insilmaril@767: } insilmaril@767: insilmaril@0: void MapEditor::print() insilmaril@0: { insilmaril@0: if ( !printer ) insilmaril@0: { insilmaril@0: printer = new QPrinter; insilmaril@0: printer->setColorMode (QPrinter::Color); insilmaril@366: printer->setPrinterName (settings.value("/mainwindow/printerName",printer->printerName()).toString()); insilmaril@412: printer->setOutputFormat((QPrinter::OutputFormat)settings.value("/mainwindow/printerFormat",printer->outputFormat()).toInt()); insilmaril@412: printer->setOutputFileName(settings.value("/mainwindow/printerFileName",printer->outputFileName()).toString()); insilmaril@0: } insilmaril@0: insilmaril@782: QRectF totalBBox=getTotalBBox(); insilmaril@0: insilmaril@0: // Try to set orientation automagically insilmaril@0: // Note: Interpretation of generated postscript is amibiguous, if insilmaril@0: // there are problems with landscape mode, see insilmaril@0: // http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html insilmaril@0: insilmaril@0: if (totalBBox.width()>totalBBox.height()) insilmaril@0: // recommend landscape insilmaril@0: printer->setOrientation (QPrinter::Landscape); insilmaril@0: else insilmaril@0: // recommend portrait insilmaril@0: printer->setOrientation (QPrinter::Portrait); insilmaril@0: insilmaril@0: if ( printer->setup(this) ) insilmaril@0: // returns false, if printing is canceled insilmaril@0: { insilmaril@0: QPainter pp(printer); insilmaril@0: insilmaril@412: pp.setRenderHint(QPainter::Antialiasing,true); insilmaril@412: insilmaril@0: // Don't print the visualisation of selection insilmaril@720: model->unselect(); insilmaril@0: insilmaril@408: QRectF mapRect=totalBBox; insilmaril@411: QGraphicsRectItem *frame=NULL; insilmaril@412: insilmaril@417: if (printFrame) insilmaril@0: { insilmaril@417: // Print frame around map insilmaril@417: mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10, insilmaril@417: totalBBox.width()+20, totalBBox.height()+20); insilmaril@417: frame=mapScene->addRect (mapRect, QPen(Qt::black),QBrush(Qt::NoBrush)); insilmaril@417: frame->setZValue(0); insilmaril@417: frame->show(); insilmaril@417: } insilmaril@417: insilmaril@417: insilmaril@412: double paperAspect = (double)printer->width() / (double)printer->height(); insilmaril@412: double mapAspect = (double)mapRect.width() / (double)mapRect.height(); insilmaril@417: int viewBottom; insilmaril@0: if (mapAspect>=paperAspect) insilmaril@0: { insilmaril@0: // Fit horizontally to paper width insilmaril@417: //pp.setViewport(0,0, printer->width(),(int)(printer->width()/mapAspect) ); insilmaril@417: viewBottom=(int)(printer->width()/mapAspect); insilmaril@0: } else insilmaril@0: { insilmaril@0: // Fit vertically to paper height insilmaril@417: //pp.setViewport(0,0,(int)(printer->height()*mapAspect),printer->height()); insilmaril@417: viewBottom=printer->height(); insilmaril@0: } insilmaril@417: insilmaril@417: if (printFooter) insilmaril@417: { insilmaril@417: // Print footer below map insilmaril@417: QFont font; insilmaril@417: font.setPointSize(10); insilmaril@417: pp.setFont (font); insilmaril@417: QRectF footerBox(0,viewBottom,printer->width(),15); insilmaril@746: // FIXME-3 fileName not any longer available here: pp.drawText ( footerBox,Qt::AlignLeft,"VYM - " +fileName); insilmaril@417: pp.drawText ( footerBox, Qt::AlignRight, QDate::currentDate().toString(Qt::TextDate)); insilmaril@417: } insilmaril@412: mapScene->render ( insilmaril@412: &pp, insilmaril@412: QRectF (0,0,printer->width(),printer->height()-15), insilmaril@412: QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height()) insilmaril@412: ); insilmaril@412: insilmaril@412: // Viewport has paper dimension insilmaril@412: if (frame) delete (frame); insilmaril@0: insilmaril@0: // Restore selection insilmaril@720: model->reselect(); insilmaril@119: insilmaril@119: // Save settings in vymrc insilmaril@366: settings.writeEntry("/mainwindow/printerName",printer->printerName()); insilmaril@412: settings.writeEntry("/mainwindow/printerFormat",printer->outputFormat()); insilmaril@412: settings.writeEntry("/mainwindow/printerFileName",printer->outputFileName()); insilmaril@0: } insilmaril@0: } insilmaril@0: insilmaril@782: QRectF MapEditor::getTotalBBox() //FIXME-2 needed e.g. for image export insilmaril@782: { insilmaril@782: QRectF r; insilmaril@782: /* insilmaril@782: for (int i=0;ibranchCount(); i++) insilmaril@782: r=addBBox (rootItem->getBranchNum(i)->getTotalBBox(), r); insilmaril@782: */ insilmaril@782: return r; insilmaril@782: } insilmaril@782: insilmaril@782: insilmaril@782: QPixmap MapEditor::getPixmap() insilmaril@782: { insilmaril@782: QRectF mapRect=getTotalBBox(); insilmaril@782: QPixmap pix((int)mapRect.width()+2,(int)mapRect.height()+1); insilmaril@782: QPainter pp (&pix); insilmaril@782: insilmaril@782: pp.setRenderHints(renderHints()); insilmaril@782: insilmaril@782: // Don't print the visualisation of selection insilmaril@782: model->unselect(); insilmaril@782: insilmaril@782: mapScene->render ( &pp, insilmaril@782: QRectF(0,0,mapRect.width()+2,mapRect.height()+2), insilmaril@782: QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height() )); insilmaril@782: insilmaril@782: // Restore selection insilmaril@782: model->reselect(); insilmaril@782: insilmaril@782: return pix; insilmaril@782: } insilmaril@782: insilmaril@782: insilmaril@408: void MapEditor::setAntiAlias (bool b) insilmaril@408: { insilmaril@408: setRenderHint(QPainter::Antialiasing,b); insilmaril@408: } insilmaril@408: insilmaril@408: void MapEditor::setSmoothPixmap(bool b) insilmaril@408: { insilmaril@408: setRenderHint(QPainter::SmoothPixmapTransform,b); insilmaril@408: } insilmaril@408: insilmaril@754: TreeItem* MapEditor::findMapItem (QPointF p,TreeItem *exclude) insilmaril@754: { insilmaril@754: // Start with mapcenter, no images allowed at rootItem insilmaril@754: int i=0; insilmaril@754: BranchItem *bi=model->getRootItem()->getFirstBranch(); insilmaril@754: TreeItem *found=NULL; insilmaril@754: while (bi) insilmaril@754: { insilmaril@754: found=bi->findMapItem (p, exclude); insilmaril@754: if (found) return found; insilmaril@754: i++; insilmaril@754: bi=model->getRootItem()->getBranchNum(i); insilmaril@754: } insilmaril@754: return NULL; insilmaril@754: } insilmaril@754: insilmaril@628: AttributeTable* MapEditor::attributeTable() insilmaril@628: { insilmaril@628: return attrTable; insilmaril@628: } insilmaril@628: insilmaril@527: void MapEditor::testFunction1() insilmaril@0: { insilmaril@795: cout << "ME::test1 selected TI="<getSelectedItem()<addNewBranch(); insilmaril@798: insilmaril@788: /* insilmaril@767: // Code copied from Qt sources insilmaril@767: QRectF rect=model->getSelectedBranchObj()->getBBox(); insilmaril@767: int xmargin=50; insilmaril@767: int ymargin=50; insilmaril@741: insilmaril@767: qreal width = viewport()->width(); insilmaril@767: qreal height = viewport()->height(); insilmaril@767: QRectF viewRect = matrix().mapRect(rect); insilmaril@741: insilmaril@767: qreal left = horizontalScrollBar()->value(); insilmaril@767: qreal right = left + width; insilmaril@767: qreal top = verticalScrollBar()->value(); insilmaril@767: qreal bottom = top + height; insilmaril@723: insilmaril@767: if (viewRect.left() <= left + xmargin) { insilmaril@767: // need to scroll from the left insilmaril@767: // if (!d->leftIndent) insilmaril@767: horizontalScrollBar()->setValue(int(viewRect.left() - xmargin - 0.5)); insilmaril@767: } insilmaril@767: if (viewRect.right() >= right - xmargin) { insilmaril@767: // need to scroll from the right insilmaril@767: // if (!d->leftIndent) insilmaril@767: horizontalScrollBar()->setValue(int(viewRect.right() - width + xmargin + 0.5)); insilmaril@767: } insilmaril@767: if (viewRect.top() <= top + ymargin) { insilmaril@767: // need to scroll from the top insilmaril@767: // if (!d->topIndent) insilmaril@767: verticalScrollBar()->setValue(int(viewRect.top() - ymargin - 0.5)); insilmaril@767: } insilmaril@767: if (viewRect.bottom() >= bottom - ymargin) { insilmaril@767: // need to scroll from the bottom insilmaril@767: // if (!d->topIndent) insilmaril@767: verticalScrollBar()->setValue(int(viewRect.bottom() - height + ymargin + 0.5)); insilmaril@767: } insilmaril@767: cout << "test1: hor="<value()<setDuration(5000); insilmaril@767: //animation->setEasingCurve ( QtEasingCurve::OutElastic); insilmaril@767: animation->setEasingCurve ( QtEasingCurve::OutQuint); insilmaril@767: animation->setStartValue(sceneRect() ); insilmaril@767: animation->setEndValue(QRectF(50, 50, 1000, 1000)); insilmaril@740: insilmaril@767: animation->start(); insilmaril@767: */ insilmaril@767: /* insilmaril@767: QDialog *dia= new QDialog (this); insilmaril@767: dia->setGeometry (50,50,10,10); insilmaril@723: insilmaril@767: dia->show(); insilmaril@767: dia ->raise(); insilmaril@767: insilmaril@767: QtPropertyAnimation *animation=new QtPropertyAnimation(dia, "geometry"); insilmaril@767: animation->setDuration(1000); insilmaril@767: //animation->setEasingCurve ( QtEasingCurve::OutElastic); insilmaril@767: animation->setEasingCurve ( QtEasingCurve::OutQuint); insilmaril@767: animation->setStartValue(QRect(50, 50, 10, 10)); insilmaril@767: animation->setEndValue(QRect(250, 250, 100, 100)); insilmaril@767: insilmaril@767: animation->start(); insilmaril@767: */ insilmaril@723: insilmaril@791: /* FIXME-4 Hide hidden stuff temporary, maybe add this as regular function somewhere insilmaril@260: if (hidemode==HideNone) insilmaril@185: { insilmaril@260: setHideTmpMode (HideExport); insilmaril@260: mapCenter->calcBBoxSizeWithChilds(); insilmaril@408: QRectF totalBBox=mapCenter->getTotalBBox(); insilmaril@408: QRectF mapRect=totalBBox; insilmaril@260: QCanvasRectangle *frame=NULL; insilmaril@260: insilmaril@260: cout << " map has =("<setBrush (QColor(white)); insilmaril@260: frame->setPen (QColor(black)); insilmaril@408: frame->setZValue(0); insilmaril@260: frame->show(); insilmaril@260: } insilmaril@260: else insilmaril@260: { insilmaril@260: setHideTmpMode (HideNone); insilmaril@260: } insilmaril@260: cout <<" hidemode="< mapobjects; insilmaril@792: QList polys; insilmaril@793: ConvexPolygon p; insilmaril@792: QList vectors; insilmaril@792: QList orgpos; insilmaril@793: QStringList headings; //FIXME-3 testing only insilmaril@793: Vector v; insilmaril@792: BranchItem *bi; insilmaril@793: BranchItem *bi2; insilmaril@792: BranchObj *bo; insilmaril@794: insilmaril@794: // Outer loop: Iterate until we no more changes in orientation insilmaril@794: bool orientationChanged=true; insilmaril@794: while (orientationChanged) insilmaril@792: { insilmaril@794: BranchItem *ri=model->getRootItem(); insilmaril@794: for (int i=0;ibranchCount();++i) insilmaril@792: { insilmaril@794: bi=ri->getBranchNum (i); insilmaril@794: bo=(BranchObj*)bi->getLMO(); insilmaril@793: if (bo) insilmaril@793: { insilmaril@793: mapobjects.append (bo); insilmaril@793: p=bo->getBoundingPolygon(); insilmaril@793: p.calcCentroid(); insilmaril@793: polys.append(p); insilmaril@793: vectors.append (QPointF(0,0)); insilmaril@793: orgpos.append (p.at(0)); insilmaril@794: headings.append (bi->getHeading()); insilmaril@794: } insilmaril@794: for (int j=0;jbranchCount();++j) insilmaril@792: { insilmaril@794: bi2=bi->getBranchNum (j); insilmaril@794: bo=(BranchObj*)bi2->getLMO(); insilmaril@794: if (bo) insilmaril@792: { insilmaril@794: mapobjects.append (bo); insilmaril@794: p=bo->getBoundingPolygon(); insilmaril@794: p.calcCentroid(); insilmaril@794: polys.append(p); insilmaril@794: vectors.append (QPointF(0,0)); insilmaril@794: orgpos.append (p.at(0)); insilmaril@794: headings.append (bi2->getHeading()); insilmaril@794: } insilmaril@792: } insilmaril@792: } insilmaril@794: insilmaril@794: // Iterate moving bounding polygons until we have no more collisions insilmaril@794: int collisions=1; insilmaril@794: while (collisions>0) insilmaril@793: { insilmaril@794: collisions=0; insilmaril@794: for (int i=0; i orients; insilmaril@794: for (int i=0;igetOrientation()); insilmaril@794: mapobjects[i]->moveBy(v.x(),v.y() ); insilmaril@798: mapobjects[i]->setRelPos(); insilmaril@794: } insilmaril@794: model->reposition(); insilmaril@794: orientationChanged=false; insilmaril@794: for (int i=0;igetOrientation()) insilmaril@794: { insilmaril@794: orientationChanged=true; insilmaril@794: break; insilmaril@794: } insilmaril@794: cout << "Final: orientChanged="<emitSelectionChanged(); insilmaril@105: } insilmaril@105: insilmaril@787: BranchItem* MapEditor::getBranchDirectAbove (BranchItem *bi) insilmaril@787: { insilmaril@787: if (bi) insilmaril@787: { insilmaril@787: int i=bi->num(); insilmaril@787: if (i>0) return bi->parent()->getBranchNum(i-1); insilmaril@787: } insilmaril@787: return NULL; insilmaril@787: } insilmaril@787: insilmaril@787: BranchItem* MapEditor::getBranchAbove (BranchItem *selbi) insilmaril@787: { insilmaril@787: if (selbi) insilmaril@787: { insilmaril@787: int dz=selbi->depth(); // original depth insilmaril@787: bool invert=false; insilmaril@787: if (selbi->getLMO()->getOrientation()==LinkableMapObj::LeftOfCenter) insilmaril@787: invert=true; insilmaril@787: insilmaril@787: BranchItem *bi; insilmaril@787: insilmaril@787: // Look for branch with same parent but directly above insilmaril@787: if (dz==1 && invert) insilmaril@787: bi=getBranchDirectBelow(selbi); insilmaril@787: else insilmaril@787: bi=getBranchDirectAbove (selbi); insilmaril@787: insilmaril@787: if (bi) insilmaril@787: // direct predecessor insilmaril@787: return bi; insilmaril@787: insilmaril@787: // Go towards center and look for predecessor insilmaril@787: while (selbi->depth()>0) insilmaril@787: { insilmaril@787: selbi=(BranchItem*)(selbi->parent()); insilmaril@787: if (selbi->depth()==1 && invert) insilmaril@787: bi=getBranchDirectBelow (selbi); insilmaril@787: else insilmaril@787: bi=getBranchDirectAbove (selbi); insilmaril@787: if (bi) insilmaril@787: { insilmaril@787: // turn insilmaril@787: selbi=bi; insilmaril@787: while (selbi->depth()getLastBranch(); insilmaril@787: if (!bi) insilmaril@787: { insilmaril@787: return selbi; insilmaril@787: } insilmaril@787: selbi=bi; insilmaril@787: } insilmaril@787: return selbi; insilmaril@787: } insilmaril@787: } insilmaril@787: } insilmaril@787: return NULL; insilmaril@787: } insilmaril@787: insilmaril@787: BranchItem* MapEditor::getBranchDirectBelow(BranchItem *bi) insilmaril@787: { insilmaril@787: if (bi) insilmaril@787: { insilmaril@787: int i=bi->num(); insilmaril@787: if (i+1parent()->branchCount()) return bi->parent()->getBranchNum(i+1); insilmaril@787: } insilmaril@787: return NULL; insilmaril@787: } insilmaril@787: insilmaril@787: BranchItem* MapEditor::getBranchBelow (BranchItem *selbi) insilmaril@787: { insilmaril@787: if (selbi) insilmaril@787: { insilmaril@787: BranchItem *bi; insilmaril@787: int dz=selbi->depth(); // original depth insilmaril@787: bool invert=false; insilmaril@787: if (selbi->getLMO()->getOrientation()==LinkableMapObj::LeftOfCenter) insilmaril@787: invert=true; insilmaril@787: insilmaril@787: insilmaril@787: // Look for branch with same parent but directly below insilmaril@787: if (dz==1 && invert) insilmaril@787: bi=getBranchDirectAbove (selbi); insilmaril@787: else insilmaril@787: bi=getBranchDirectBelow (selbi); insilmaril@787: if (bi) insilmaril@787: // direct successor insilmaril@787: return bi; insilmaril@787: insilmaril@787: insilmaril@787: // Go towards center and look for neighbour insilmaril@787: while (selbi->depth()>0) insilmaril@787: { insilmaril@787: selbi=(BranchItem*)(selbi->parent()); insilmaril@787: if (selbi->depth()==1 && invert) insilmaril@787: bi=getBranchDirectAbove (selbi); insilmaril@787: else insilmaril@787: bi=getBranchDirectBelow (selbi); insilmaril@787: if (bi) insilmaril@787: { insilmaril@787: // turn insilmaril@787: selbi=bi; insilmaril@787: while (selbi->depth()getFirstBranch(); insilmaril@787: if (!bi) insilmaril@787: { insilmaril@787: return selbi; insilmaril@787: } insilmaril@787: selbi=bi; insilmaril@787: } insilmaril@787: return selbi; insilmaril@787: } insilmaril@787: } insilmaril@787: } insilmaril@787: return NULL; insilmaril@787: } insilmaril@787: insilmaril@787: BranchItem* MapEditor::getLeftBranch (BranchItem *bi) insilmaril@787: { insilmaril@787: if (bi) insilmaril@787: { insilmaril@787: if (bi->depth()==0) insilmaril@787: // Special case: use alternative selection index insilmaril@787: return bi->getLastSelectedBranchAlt(); insilmaril@787: if (bi->getBranchObj()->getOrientation()==LinkableMapObj::RightOfCenter) insilmaril@787: // right of center insilmaril@787: return (BranchItem*)(bi->parent()); insilmaril@787: else insilmaril@787: // left of center insilmaril@787: if (bi->getType()== TreeItem::Branch ) insilmaril@787: return bi->getLastSelectedBranch(); insilmaril@787: } insilmaril@787: return NULL; insilmaril@787: } insilmaril@787: insilmaril@787: BranchItem* MapEditor::getRightBranch(BranchItem *bi) insilmaril@787: { insilmaril@787: if (bi) insilmaril@787: { insilmaril@787: if (bi->depth()==0) return bi->getLastSelectedBranch(); insilmaril@787: if (bi->getBranchObj()->getOrientation()==LinkableMapObj::LeftOfCenter) insilmaril@787: // left of center insilmaril@787: return (BranchItem*)(bi->parent()); insilmaril@787: else insilmaril@787: // right of center insilmaril@787: if (bi->getType()== TreeItem::Branch ) insilmaril@787: return (BranchItem*)bi->getLastSelectedBranch(); insilmaril@787: } insilmaril@787: return NULL; insilmaril@787: } insilmaril@787: insilmaril@787: insilmaril@787: insilmaril@769: void MapEditor::cursorUp() insilmaril@769: { insilmaril@787: BranchItem *bi=model->getSelectedBranch(); insilmaril@787: if (bi) model->select (getBranchAbove(bi)); insilmaril@769: } insilmaril@769: insilmaril@769: void MapEditor::cursorDown() insilmaril@769: insilmaril@769: { insilmaril@787: BranchItem *bi=model->getSelectedBranch(); insilmaril@787: if (bi) model->select (getBranchBelow(bi)); insilmaril@769: } insilmaril@769: insilmaril@769: void MapEditor::cursorLeft() insilmaril@769: { insilmaril@787: BranchItem *bi=getLeftBranch (model->getSelectedBranch()); insilmaril@787: if (bi) model->select (bi); insilmaril@769: } insilmaril@769: insilmaril@769: void MapEditor::cursorRight() insilmaril@769: { insilmaril@787: BranchItem *bi=getRightBranch (model->getSelectedBranch()); insilmaril@787: if (bi) model->select (bi); insilmaril@769: } insilmaril@769: insilmaril@769: void MapEditor::cursorFirst() insilmaril@769: { insilmaril@769: model->selectFirstBranch(); insilmaril@769: } insilmaril@769: insilmaril@769: void MapEditor::cursorLast() insilmaril@769: { insilmaril@769: model->selectLastBranch(); insilmaril@769: } insilmaril@769: insilmaril@769: insilmaril@720: void MapEditor::editHeading() insilmaril@720: { insilmaril@720: if (editingHeading) insilmaril@720: { insilmaril@720: editHeadingFinished(); insilmaril@720: return; insilmaril@720: } insilmaril@753: BranchObj *bo=model->getSelectedBranchObj(); insilmaril@787: BranchItem *bi=model->getSelectedBranch(); insilmaril@773: if (bo) insilmaril@720: { insilmaril@720: model->setSelectionBlocked(true); insilmaril@720: insilmaril@753: lineEdit->setText (bi->getHeading()); insilmaril@720: QPoint p = mapTo (this,bo->getAbsPos().toPoint() ); insilmaril@720: lineEdit->setGeometry(p.x(),p.y(),230,25); insilmaril@804: //lineEdit->selectAll(); insilmaril@804: //lineEdit->setCursorPosition (1); insilmaril@720: lineEdit->show(); insilmaril@720: lineEdit->setFocus(); insilmaril@720: lineEdit->grabKeyboard(); insilmaril@720: editingHeading=true; insilmaril@720: } insilmaril@720: insilmaril@720: } insilmaril@720: void MapEditor::editHeadingFinished() insilmaril@720: { insilmaril@720: editingHeading=false; insilmaril@720: lineEdit->releaseKeyboard(); insilmaril@720: model->setHeading (lineEdit->text() ); insilmaril@720: model->setSelectionBlocked(false); insilmaril@720: lineEdit->hide(); insilmaril@720: insilmaril@720: // Maybe reselect previous branch insilmaril@720: mainWindow->editHeadingFinished (model); insilmaril@720: } insilmaril@720: insilmaril@720: insilmaril@408: void MapEditor::contextMenuEvent ( QContextMenuEvent * e ) insilmaril@0: { insilmaril@0: // Lineedits are already closed by preceding insilmaril@0: // mouseEvent, we don't need to close here. insilmaril@0: insilmaril@408: QPointF p = mapToScene(e->pos()); insilmaril@754: TreeItem *ti=findMapItem (p, NULL); insilmaril@754: LinkableMapObj* lmo=NULL; insilmaril@779: if (ti) lmo=((MapItem*)ti)->getLMO(); insilmaril@0: insilmaril@0: if (lmo) insilmaril@0: { // MapObj was found insilmaril@735: if (model->getSelectedLMO() != lmo) insilmaril@0: { insilmaril@0: // select the MapObj insilmaril@720: model->select(lmo); insilmaril@0: } insilmaril@0: // Context Menu insilmaril@753: if (model->getSelectedBranchObj() ) insilmaril@0: { insilmaril@424: // Context Menu on branch or mapcenter insilmaril@424: branchContextMenu->popup(e->globalPos() ); insilmaril@424: } else insilmaril@424: { insilmaril@787: if (model->getSelectedImage() ) insilmaril@0: { insilmaril@0: // Context Menu on floatimage insilmaril@0: floatimageContextMenu->popup(e->globalPos() ); insilmaril@0: } insilmaril@0: } insilmaril@0: } else insilmaril@0: { // No MapObj found, we are on the Canvas itself insilmaril@408: // Context Menu on scene insilmaril@723: insilmaril@723: // Open context menu synchronously to position new mapcenter insilmaril@723: model->setContextPos (p); insilmaril@723: canvasContextMenu->exec(e->globalPos() ); insilmaril@723: model->unsetContextPos (); insilmaril@0: } insilmaril@329: e->accept(); insilmaril@0: } insilmaril@0: insilmaril@398: void MapEditor::keyPressEvent(QKeyEvent* e) insilmaril@398: { insilmaril@411: if (e->modifiers() & Qt::ControlModifier) insilmaril@398: { insilmaril@398: switch (mainWindow->getModMode()) insilmaril@398: { insilmaril@473: case Main::ModModeColor: insilmaril@398: setCursor (PickColorCursor); insilmaril@398: break; insilmaril@473: case Main::ModModeCopy: insilmaril@398: setCursor (CopyCursor); insilmaril@398: break; insilmaril@473: case Main::ModModeXLink: insilmaril@398: setCursor (XLinkCursor); insilmaril@398: break; insilmaril@398: default : insilmaril@398: setCursor (Qt::ArrowCursor); insilmaril@398: break; insilmaril@398: } insilmaril@398: } insilmaril@398: } insilmaril@398: insilmaril@398: void MapEditor::keyReleaseEvent(QKeyEvent* e) insilmaril@398: { insilmaril@411: if (!(e->modifiers() & Qt::ControlModifier)) insilmaril@398: setCursor (Qt::ArrowCursor); insilmaril@398: } insilmaril@398: insilmaril@408: void MapEditor::mousePressEvent(QMouseEvent* e) insilmaril@0: { insilmaril@807: //cout << "ME::mousePressed\n"; //FIXME-3 insilmaril@329: // Ignore right clicks, these will go to context menus insilmaril@366: if (e->button() == Qt::RightButton ) insilmaril@329: { insilmaril@807: //cout << " ME::ignoring right mouse event...\n"; insilmaril@329: e->ignore(); insilmaril@329: return; insilmaril@329: } insilmaril@329: insilmaril@491: //Ignore clicks while editing heading insilmaril@720: if (model->isSelectionBlocked() ) insilmaril@491: { insilmaril@807: //cout << " ME::ignoring other mouse event...\n"; insilmaril@491: e->ignore(); insilmaril@491: return; insilmaril@491: } insilmaril@491: insilmaril@408: QPointF p = mapToScene(e->pos()); insilmaril@754: TreeItem *ti=findMapItem (p, NULL); insilmaril@754: LinkableMapObj* lmo=NULL; insilmaril@779: if (ti) lmo=((MapItem*)ti)->getLMO(); insilmaril@0: insilmaril@790: insilmaril@329: e->accept(); insilmaril@329: insilmaril@442: //Take care of system flags _or_ modifier modes insilmaril@267: // insilmaril@773: if (lmo && ti->isBranchLikeType() ) insilmaril@267: { insilmaril@267: QString foname=((BranchObj*)lmo)->getSystemFlagName(p); insilmaril@267: if (!foname.isEmpty()) insilmaril@267: { insilmaril@267: // systemFlag clicked insilmaril@798: model->select (lmo); insilmaril@798: if (foname=="system-url") insilmaril@267: { insilmaril@366: if (e->state() & Qt::ControlModifier) insilmaril@267: mainWindow->editOpenURLTab(); insilmaril@267: else insilmaril@267: mainWindow->editOpenURL(); insilmaril@267: } insilmaril@780: else if (foname=="system-vymLink") insilmaril@267: { insilmaril@267: mainWindow->editOpenVymLink(); insilmaril@267: // tabWidget may change, better return now insilmaril@267: // before segfaulting... insilmaril@814: } else if (foname=="system-note") insilmaril@267: mainWindow->windowToggleNoteEditor(); insilmaril@267: else if (foname=="hideInExport") insilmaril@720: model->toggleHideExport(); insilmaril@746: // FIXME-3 needed? xelection.update(); insilmaril@267: return; insilmaril@814: } else insilmaril@814: { insilmaril@814: // Take care of xLink insilmaril@814: if (ti->xlinkCount()>0 && lmo->getBBox().width()>30) insilmaril@814: { insilmaril@817: if ((lmo->getOrientation()!=LinkableMapObj::RightOfCenter && p.x() < lmo->getBBox().left()+20) || insilmaril@817: (lmo->getOrientation()!=LinkableMapObj::LeftOfCenter && p.x() > lmo->getBBox().right()-20) ) insilmaril@814: { insilmaril@817: // FIXME-4 if (ti->xlinkCount()>1) insilmaril@817: if (true) insilmaril@814: { insilmaril@814: QMenu menu; insilmaril@814: QList alist; insilmaril@814: for (int i=0;ixlinkCount();i++) insilmaril@814: alist.append (new QAction(ti->getXLinkNum(i)->getOtherBranch(ti)->getHeading(),&menu)); insilmaril@814: menu.addActions (alist); insilmaril@814: QAction *ra=menu.exec (e->globalPos() ); insilmaril@814: if (ra) insilmaril@814: model->select (ti->getXLinkNum(alist.indexOf(ra))->getOtherBranch (ti)); insilmaril@814: while (!alist.isEmpty()) insilmaril@814: { insilmaril@814: QAction *a=alist.takeFirst(); insilmaril@814: delete a; insilmaril@814: } insilmaril@814: return; insilmaril@814: } else insilmaril@814: { insilmaril@814: model->select (ti->getXLinkNum(0)->getOtherBranch (ti)); insilmaril@814: return; insilmaril@814: } insilmaril@814: } insilmaril@814: } insilmaril@814: } insilmaril@720: } insilmaril@814: insilmaril@442: // No system flag clicked, take care of modmodes (CTRL-Click) insilmaril@366: if (e->state() & Qt::ControlModifier) insilmaril@0: { insilmaril@473: if (mainWindow->getModMode()==Main::ModModeColor) insilmaril@83: { insilmaril@83: pickingColor=true; insilmaril@398: setCursor (PickColorCursor); insilmaril@83: return; insilmaril@83: } insilmaril@473: if (mainWindow->getModMode()==Main::ModModeXLink) insilmaril@83: { insilmaril@790: BranchItem *bi_begin=model->getSelectedBranch(); insilmaril@790: if (bi_begin) insilmaril@83: { insilmaril@83: drawingLink=true; insilmaril@790: tmpXLink=model->createXLink(bi_begin,true); insilmaril@720: tmpXLink->setColor(model->getMapDefXLinkColor()); insilmaril@720: tmpXLink->setWidth(model->getMapDefXLinkWidth()); insilmaril@790: tmpXLink->setEnd (p); insilmaril@95: tmpXLink->updateXLink(); insilmaril@83: return; insilmaril@89: } insilmaril@267: } insilmaril@442: } // End of modmodes insilmaril@442: insilmaril@0: if (lmo) insilmaril@267: { insilmaril@738: /* insilmaril@729: cout << "ME::mouse pressed\n"; insilmaril@729: cout << " lmo="<getModMode()==Main::ModModeCopy && insilmaril@366: e->state() & Qt::ControlModifier) insilmaril@93: { insilmaril@787: BranchItem *bi=model->getSelectedBranch(); insilmaril@750: if (bi) insilmaril@93: { insilmaril@93: copyingObj=true; insilmaril@750: //FIXME-2 TreeItem::addBranch (BranchItem still missing) insilmaril@787: //bi->addBranch (model->getSelectedBranch()); insilmaril@720: model->unselect(); insilmaril@750: model->select(bi->getLastBranch()); insilmaril@645: model->reposition(); insilmaril@93: } insilmaril@421: } insilmaril@421: insilmaril@735: movingObj=model->getSelectedLMO(); insilmaril@0: } else insilmaril@0: // Middle Button Toggle Scroll insilmaril@0: // (On Mac OS X this won't work, but we still have insilmaril@0: // a button in the toolbar) insilmaril@366: if (e->button() == Qt::MidButton ) insilmaril@720: model->toggleScroll(); insilmaril@746: // model->updateActions(); FIXME-3 needed? insilmaril@746: // FIXME-3 needed? xelection.update(); insilmaril@0: } else insilmaril@408: { // No MapObj found, we are on the scene itself insilmaril@408: // Left Button move Pos of sceneView insilmaril@366: if (e->button() == Qt::LeftButton ) insilmaril@0: { insilmaril@0: movingObj=NULL; // move Content not Obj insilmaril@0: movingObj_start=e->globalPos(); insilmaril@408: movingCont_start=QPointF ( insilmaril@408: horizontalScrollBar()->value(), insilmaril@408: verticalScrollBar()->value()); insilmaril@408: movingVec=QPointF(0,0); insilmaril@398: setCursor(HandOpenCursor); insilmaril@0: } insilmaril@0: } insilmaril@0: } insilmaril@0: insilmaril@408: void MapEditor::mouseMoveEvent(QMouseEvent* e) insilmaril@0: { insilmaril@408: QPointF p = mapToScene(e->pos()); insilmaril@754: TreeItem *seli=model->getSelectedItem(); insilmaril@777: LinkableMapObj* lmosel=NULL; insilmaril@776: if (seli && (seli->isBranchLikeType() ||seli->getType()==TreeItem::Image)) insilmaril@779: lmosel=((MapItem*)seli)->getLMO(); insilmaril@83: insilmaril@0: // Move the selected MapObj insilmaril@424: if ( lmosel && movingObj) insilmaril@0: { insilmaril@798: objectMoved=true; insilmaril@421: // reset cursor if we are moving and don't copy insilmaril@473: if (mainWindow->getModMode()!=Main::ModModeCopy) insilmaril@421: setCursor (Qt::ArrowCursor); insilmaril@421: insilmaril@408: // To avoid jumping of the sceneView, only insilmaril@763: // show selection, if not tmp linked insilmaril@798: /* FIXME-2 if (!lmosel->hasParObjTmp()) insilmaril@763: model->emitShowSelection(); insilmaril@798: */ insilmaril@0: insilmaril@83: // Now move the selection, but add relative position insilmaril@83: // (movingObj_start) where selection was chosen with insilmaril@83: // mousepointer. (This avoids flickering resp. jumping insilmaril@0: // of selection back to absPos) insilmaril@0: insilmaril@0: // Check if we could link insilmaril@777: TreeItem *ti=findMapItem (p, seli); insilmaril@777: BranchItem *dsti=NULL; insilmaril@754: LinkableMapObj* dst=NULL; insilmaril@777: if (ti && ti!=seli && ti->isBranchLikeType()) insilmaril@777: { insilmaril@777: dsti=(BranchItem*)ti; insilmaril@777: dst=dsti->getLMO(); insilmaril@777: } else insilmaril@772: dsti=NULL; insilmaril@0: insilmaril@0: insilmaril@777: if (lmosel && seli->getType()==TreeItem::Image) insilmaril@0: { insilmaril@776: FloatObj *fio=(FloatImageObj*)lmosel; insilmaril@424: fio->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() ); insilmaril@424: fio->setRelPos(); insilmaril@779: fio->updateLinkGeometry(); //no need for reposition, if we update link here insilmaril@775: model->emitSelectionChanged(); // position has changed insilmaril@0: insilmaril@0: // Relink float to new mapcenter or branch, if shift is pressed insilmaril@0: // Only relink, if selection really has a new parent insilmaril@777: if ( e->modifiers()==Qt::ShiftModifier && dsti && dsti != seli->parent() ) insilmaril@0: { insilmaril@773: // Also save the move which was done so far insilmaril@792: QString pold=qpointFToString(movingObj_orgRelPos); insilmaril@792: QString pnow=qpointFToString(fio->getRelPos()); insilmaril@773: model->saveState( insilmaril@777: seli, insilmaril@773: "moveRel "+pold, insilmaril@777: seli, insilmaril@773: "moveRel "+pnow, insilmaril@773: QString("Move %1 to relative position %2").arg(model->getObjectName(fio)).arg(pnow)); insilmaril@773: fio->getParObj()->requestReposition(); insilmaril@773: model->reposition(); insilmaril@420: insilmaril@777: model->relinkImage ((ImageItem*) seli,dsti); insilmaril@777: model->select (seli); insilmaril@777: //movingObj=lmosel; //FIXME-3 insilmaril@773: //movingObj_orgRelPos=lmosel->getRelPos(); insilmaril@420: insilmaril@773: model->reposition(); insilmaril@0: } insilmaril@388: } else insilmaril@388: { // selection != a FloatObj insilmaril@798: if (seli->depth()==0) insilmaril@0: { insilmaril@814: // Move mapcenter insilmaril@796: lmosel->move (p-movingObj_start); insilmaril@388: if (e->buttons()== Qt::LeftButton && e->modifiers()==Qt::ShiftModifier) insilmaril@796: { insilmaril@814: // Move only mapcenter, leave its children where they are insilmaril@796: QPointF v; insilmaril@796: v=lmosel->getAbsPos(); insilmaril@796: for (int i=0; ibranchCount(); ++i) insilmaril@796: { insilmaril@796: seli->getBranchObjNum(i)->setRelPos(); insilmaril@796: seli->getBranchObjNum(i)->setOrientation(); insilmaril@796: } insilmaril@796: } insilmaril@0: } else insilmaril@0: { insilmaril@755: if (seli->depth()==1) insilmaril@0: { insilmaril@388: // Move mainbranch insilmaril@814: if (!lmosel->hasParObjTmp()) insilmaril@814: lmosel->move(p-movingObj_start); insilmaril@388: lmosel->setRelPos(); insilmaril@0: } else insilmaril@0: { insilmaril@388: // Move ordinary branch insilmaril@473: if (lmosel->getOrientation() == LinkableMapObj::LeftOfCenter) insilmaril@0: // Add width of bbox here, otherwise alignRelTo will cause jumping around insilmaril@720: lmosel->move(p.x() -movingObj_start.x() , //lmosel->getBBox().width(), insilmaril@175: p.y()-movingObj_start.y() +lmosel->getTopPad() ); insilmaril@0: else insilmaril@175: lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() -lmosel->getTopPad()); insilmaril@720: lmosel->setRelPos(); insilmaril@0: } insilmaril@0: insilmaril@794: } // depth>0 insilmaril@431: // Maybe we can relink temporary? insilmaril@796: if (dsti) // FIXME-1 check if dsti is ancestor of myself! insilmaril@0: { insilmaril@388: if (e->modifiers()==Qt::ControlModifier) insilmaril@0: { insilmaril@754: // Special case: CTRL to link below dst insilmaril@754: lmosel->setParObjTmp (dst,p,+1); insilmaril@814: } else if (e->modifiers()==Qt::ShiftModifier) insilmaril@754: lmosel->setParObjTmp (dst,p,-1); insilmaril@0: else insilmaril@754: lmosel->setParObjTmp (dst,p,0); insilmaril@0: } else insilmaril@0: { insilmaril@93: lmosel->unsetParObjTmp(); insilmaril@0: } insilmaril@428: // reposition subbranch insilmaril@428: lmosel->reposition(); insilmaril@0: insilmaril@732: QItemSelection sel=model->getSelectionModel()->selection(); insilmaril@735: updateSelection(sel,sel); // position has changed insilmaril@732: insilmaril@0: } // no FloatImageObj insilmaril@0: insilmaril@408: scene()->update(); insilmaril@0: return; insilmaril@0: } // selection && moving_obj insilmaril@0: insilmaril@83: // Draw a link from one branch to another insilmaril@83: if (drawingLink) insilmaril@83: { insilmaril@95: tmpXLink->setEnd (p); insilmaril@95: tmpXLink->updateXLink(); insilmaril@83: } insilmaril@83: insilmaril@408: // Move sceneView insilmaril@411: if (!movingObj && !pickingColor &&!drawingLink && e->buttons() == Qt::LeftButton ) insilmaril@0: { insilmaril@408: QPointF p=e->globalPos(); insilmaril@0: movingVec.setX(-p.x() + movingObj_start.x() ); insilmaril@0: movingVec.setY(-p.y() + movingObj_start.y() ); insilmaril@408: horizontalScrollBar()->setSliderPosition((int)( movingCont_start.x()+movingVec.x() )); insilmaril@408: verticalScrollBar()->setSliderPosition((int)( movingCont_start.y()+movingVec.y() ) ); insilmaril@0: } insilmaril@0: } insilmaril@0: insilmaril@0: insilmaril@408: void MapEditor::mouseReleaseEvent(QMouseEvent* e) insilmaril@0: { insilmaril@408: QPointF p = mapToScene(e->pos()); insilmaril@754: TreeItem *seli=model->getSelectedItem(); insilmaril@754: insilmaril@772: TreeItem *dsti=NULL; insilmaril@772: if (seli) dsti=findMapItem(p, seli); insilmaril@755: LinkableMapObj* dst=NULL; insilmaril@772: if (dsti && dsti->isBranchLikeType ()) insilmaril@779: dst=((MapItem*)dsti)->getLMO(); insilmaril@772: else insilmaril@772: dsti=NULL; insilmaril@754: insilmaril@754: insilmaril@0: // Have we been picking color? insilmaril@0: if (pickingColor) insilmaril@0: { insilmaril@0: pickingColor=false; insilmaril@366: setCursor (Qt::ArrowCursor); insilmaril@0: // Check if we are over another branch insilmaril@772: if (dst) insilmaril@0: { insilmaril@366: if (e->state() & Qt::ShiftModifier) insilmaril@720: model->colorBranch (((BranchObj*)dst)->getColor()); insilmaril@0: else insilmaril@720: model->colorSubtree (((BranchObj*)dst)->getColor()); insilmaril@0: } insilmaril@0: return; insilmaril@0: } insilmaril@83: insilmaril@83: // Have we been drawing a link? insilmaril@491: if (drawingLink) insilmaril@83: { insilmaril@83: drawingLink=false; insilmaril@83: // Check if we are over another branch insilmaril@772: if (dsti) insilmaril@83: { insilmaril@790: tmpXLink->setEnd ( ((BranchItem*)dsti) ); insilmaril@95: tmpXLink->updateXLink(); insilmaril@790: tmpXLink->activate(); insilmaril@794: model->saveState( insilmaril@794: tmpXLink,QString("delete ()"), insilmaril@794: dsti,QString("addXLink (\"%1\",\"%2\")").arg(model->getSelectString(tmpXLink->getBegin())).arg(model->getSelectString(dsti)), insilmaril@794: QString("Add xLink from %1 to %2").arg(model->getObjectName(tmpXLink->getBegin())).arg(model->getObjectName(dsti)) insilmaril@794: ); insilmaril@83: } else insilmaril@83: { insilmaril@790: model->deleteItem(tmpXLink); insilmaril@95: tmpXLink=NULL; insilmaril@83: } insilmaril@83: return; insilmaril@83: } insilmaril@83: insilmaril@0: // Have we been moving something? insilmaril@754: if ( seli && movingObj ) insilmaril@0: { insilmaril@776: if (seli->getType()==TreeItem::Image) insilmaril@175: { insilmaril@779: FloatImageObj *fio=(FloatImageObj*)( ((MapItem*)seli)->getLMO()); insilmaril@776: if(fio) insilmaril@776: { insilmaril@776: // Moved FloatObj. Maybe we need to reposition insilmaril@792: QString pold=qpointFToString(movingObj_orgRelPos); insilmaril@792: QString pnow=qpointFToString(fio->getRelPos()); insilmaril@776: model->saveState( insilmaril@776: seli, insilmaril@776: "moveRel "+pold, insilmaril@776: seli, insilmaril@776: "moveRel "+pnow, insilmaril@776: QString("Move %1 to relative position %2").arg(model->getObjectName(seli)).arg(pnow)); insilmaril@424: insilmaril@785: cout << "ME::release mouse\n"; insilmaril@776: fio->getParObj()->requestReposition(); insilmaril@776: model->reposition(); insilmaril@776: } insilmaril@776: } insilmaril@175: insilmaril@787: BranchItem *bi=model->getSelectedBranch(); insilmaril@753: if (bi && bi->depth()==0) insilmaril@497: { insilmaril@753: if (movingObj_orgPos != bi->getBranchObj()->getAbsPos()) // FIXME-3 check getBO here... insilmaril@625: { insilmaril@792: QString pold=qpointFToString(movingObj_orgPos); insilmaril@792: QString pnow=qpointFToString(bi->getBranchObj()->getAbsPos()); // FIXME-3 check getBO here... insilmaril@753: insilmaril@720: model->saveState( insilmaril@753: bi, insilmaril@625: "move "+pold, insilmaril@753: bi, insilmaril@625: "move "+pnow, insilmaril@753: QString("Move mapcenter %1 to position %2").arg(model->getObjectName(bi)).arg(pnow)); insilmaril@625: } insilmaril@388: } insilmaril@645: insilmaril@773: if (seli->isBranchLikeType() ) //(seli->getType() == TreeItem::Branch ) insilmaril@388: { // A branch was moved insilmaril@777: LinkableMapObj* lmosel=NULL; insilmaril@779: lmosel=((MapItem*)seli)->getLMO(); insilmaril@760: insilmaril@0: // save the position in case we link to mapcenter insilmaril@424: QPointF savePos=QPointF (lmosel->getAbsPos() ); insilmaril@0: insilmaril@0: // Reset the temporary drawn link to the original one insilmaril@424: lmosel->unsetParObjTmp(); insilmaril@0: insilmaril@366: // For Redo we may need to save original selection insilmaril@773: QString preSelStr=model->getSelectString(seli); insilmaril@93: insilmaril@94: copyingObj=false; insilmaril@798: if (dsti && objectMoved) insilmaril@93: { insilmaril@691: // We have a destination, relink to that insilmaril@691: insilmaril@753: BranchObj* bsel=model->getSelectedBranchObj(); insilmaril@366: insilmaril@684: QString preParStr=model->getSelectString (bsel->getParObj()); insilmaril@755: QString preNum=QString::number (seli->num(),10); insilmaril@366: QString preDstParStr; insilmaril@767: bool relinked; insilmaril@366: insilmaril@366: if (e->state() & Qt::ShiftModifier && dst->getParObj()) insilmaril@366: { // Link above dst insilmaril@684: preDstParStr=model->getSelectString (dst->getParObj()); insilmaril@767: relinked=model->relinkBranch ((BranchItem*)seli,(BranchItem*)dsti->parent(),((BranchItem*)dsti)->num()); insilmaril@366: } else insilmaril@366: if (e->state() & Qt::ControlModifier && dst->getParObj()) insilmaril@366: { insilmaril@366: // Link below dst insilmaril@684: preDstParStr=model->getSelectString (dst->getParObj()); insilmaril@767: relinked=model->relinkBranch ((BranchItem*)seli,(BranchItem*)dsti->parent(),((BranchItem*)dsti)->num()+1); insilmaril@366: } else insilmaril@366: { // Append to dst insilmaril@684: preDstParStr=model->getSelectString(dst); insilmaril@767: relinked=model->relinkBranch ((BranchItem*)seli,(BranchItem*)dsti); insilmaril@755: if (dsti->depth()==0) bsel->move (savePos); insilmaril@366: } insilmaril@767: if (relinked) insilmaril@767: { insilmaril@767: QString postSelStr=model->getSelectString(lmosel); insilmaril@767: QString postNum=QString::number (seli->num(),10); insilmaril@366: insilmaril@776: QString undoCom="relinkTo (\""+ insilmaril@767: preParStr+ "\"," + preNum +"," + insilmaril@767: QString ("%1,%2").arg(movingObj_orgPos.x()).arg(movingObj_orgPos.y())+ ")"; insilmaril@366: insilmaril@776: QString redoCom="relinkTo (\""+ insilmaril@767: preDstParStr + "\"," + postNum + "," + insilmaril@767: QString ("%1,%2").arg(savePos.x()).arg(savePos.y())+ ")"; insilmaril@366: insilmaril@767: model->saveState ( insilmaril@767: postSelStr,undoCom, insilmaril@767: preSelStr, redoCom, insilmaril@767: QString("Relink %1 to %2").arg(model->getObjectName(bsel)).arg(model->getObjectName(dst)) ); insilmaril@691: insilmaril@767: } insilmaril@163: } else insilmaril@691: { insilmaril@815: // No destination, undo temporary move insilmaril@691: insilmaril@755: if (seli->depth()==1) insilmaril@366: { insilmaril@366: // The select string might be different _after_ moving around. insilmaril@366: // Therefor reposition and then use string of old selection, too insilmaril@645: model->reposition(); insilmaril@366: insilmaril@625: QPointF rp(lmosel->getRelPos()); insilmaril@625: if (rp != movingObj_orgRelPos) insilmaril@625: { insilmaril@792: QString ps=qpointFToString(rp); insilmaril@720: model->saveState( insilmaril@792: model->getSelectString(lmosel), "moveRel "+qpointFToString(movingObj_orgRelPos), insilmaril@625: preSelStr, "moveRel "+ps, insilmaril@726: QString("Move %1 to relative position %2").arg(model->getObjectName(lmosel)).arg(ps)); insilmaril@625: } insilmaril@366: } insilmaril@691: insilmaril@691: // Draw the original link, before selection was moved around insilmaril@815: if (settings.value("/animation/use",true).toBool() && seli->depth()>1) insilmaril@691: { insilmaril@720: lmosel->setRelPos(); // calc relPos first for starting point insilmaril@720: insilmaril@691: model->startAnimation( insilmaril@723: (BranchObj*)lmosel, insilmaril@691: lmosel->getRelPos(), insilmaril@720: movingObj_orgRelPos insilmaril@691: ); insilmaril@691: } else insilmaril@691: model->reposition(); insilmaril@691: } insilmaril@0: } insilmaril@775: model->emitSelectionChanged(); //FIXME-3 needed? at least not after pos of selection has changed... insilmaril@408: // Finally resize scene, if needed insilmaril@408: scene()->update(); insilmaril@0: movingObj=NULL; insilmaril@798: objectMoved=false; insilmaril@366: insilmaril@0: } else insilmaril@83: // maybe we moved View: set old cursor insilmaril@366: setCursor (Qt::ArrowCursor); insilmaril@83: insilmaril@0: } insilmaril@0: insilmaril@408: void MapEditor::mouseDoubleClickEvent(QMouseEvent* e) insilmaril@0: { insilmaril@802: if (debug) insilmaril@802: { insilmaril@802: cout << "ME p="<pos())<<" scrollBarPos="< uris; insilmaril@417: if (event->mimeData()->hasImage()) insilmaril@128: { insilmaril@417: QVariant imageData = event->mimeData()->imageData(); insilmaril@720: model->addFloatImage (qvariant_cast(imageData)); insilmaril@417: } else insilmaril@417: if (event->mimeData()->hasUrls()) insilmaril@417: uris=event->mimeData()->urls(); insilmaril@417: insilmaril@417: if (uris.count()>0) insilmaril@128: { insilmaril@417: QStringList files; insilmaril@417: QString s; insilmaril@417: QString heading; insilmaril@753: BranchItem *bi; insilmaril@428: for (int i=0; iaddNewBranch(); insilmaril@753: if (bi) insilmaril@417: { insilmaril@753: /* FIXME-2 insilmaril@428: s=uris.at(i).toLocalFile(); insilmaril@428: if (!s.isEmpty()) insilmaril@428: { insilmaril@625: QString file = QDir::fromNativeSeparators(s); insilmaril@428: heading = QFileInfo(file).baseName(); insilmaril@428: files.append(file); insilmaril@428: if (file.endsWith(".vym", false)) insilmaril@753: bi->setVymLink(file); insilmaril@428: else insilmaril@753: bi->setURL(uris.at(i).toString()); insilmaril@428: } else insilmaril@428: { insilmaril@428: bo->setURL(uris.at(i).toString()); insilmaril@428: } insilmaril@753: */ insilmaril@428: insilmaril@428: if (!heading.isEmpty()) insilmaril@753: bi->setHeading(heading); insilmaril@428: else insilmaril@753: bi->setHeading(uris.at(i).toString()); insilmaril@753: insilmaril@428: } insilmaril@417: } insilmaril@417: } insilmaril@645: model->reposition(); insilmaril@417: } insilmaril@417: } insilmaril@417: event->acceptProposedAction(); insilmaril@417: } insilmaril@417: insilmaril@776: void MapEditor::updateSelection(QItemSelection newsel,QItemSelection oldsel) insilmaril@728: { insilmaril@779: // Note: Here we are prepared for multiple selections, though this insilmaril@779: // is not yet implemented elsewhere insilmaril@779: insilmaril@776: // Here in MapEditor we can only select Branches and Images insilmaril@786: QList treeItemsNew; insilmaril@786: QList treeItemsOld; insilmaril@786: insilmaril@807: QModelIndex newIndex; insilmaril@807: insilmaril@796: bool do_reposition=false; insilmaril@796: insilmaril@776: QModelIndex ix; insilmaril@776: foreach (ix,newsel.indexes() ) insilmaril@776: { insilmaril@776: TreeItem *ti= static_cast(ix.internalPointer()); insilmaril@787: if (ti->isBranchLikeType() || ti->getType()==TreeItem::Image ) insilmaril@786: if (!treeItemsNew.contains(ti)) treeItemsNew.append (ti); insilmaril@786: } insilmaril@786: foreach (ix,oldsel.indexes() ) insilmaril@786: { insilmaril@786: TreeItem *ti= static_cast(ix.internalPointer()); insilmaril@787: if (ti->isBranchLikeType() || ti->getType()==TreeItem::Image ) insilmaril@786: if (!treeItemsOld.contains(ti)) treeItemsOld.append (ti); insilmaril@776: } insilmaril@776: insilmaril@779: // Trim list of selection rectangles insilmaril@786: while (treeItemsNew.count() < selboxList.count() ) insilmaril@776: delete selboxList.takeFirst(); insilmaril@776: insilmaril@775: // Take care to tmp scroll/unscroll insilmaril@775: if (!oldsel.isEmpty()) insilmaril@775: { insilmaril@775: QModelIndex ix=oldsel.indexes().first(); insilmaril@775: if (ix.isValid() ) insilmaril@775: { insilmaril@775: TreeItem *ti= static_cast(ix.internalPointer()); insilmaril@779: if (ti) insilmaril@775: { insilmaril@779: if (ti->isBranchLikeType() ) insilmaril@779: { insilmaril@779: // reset tmp scrolled branches insilmaril@779: BranchItem *bi=(BranchItem*)ti; insilmaril@796: if (bi->resetTmpUnscroll() ) insilmaril@796: do_reposition=true; insilmaril@779: } insilmaril@779: if (ti->isBranchLikeType() || ti->getType()==TreeItem::Image) insilmaril@779: // Hide link if not needed insilmaril@779: ((MapItem*)ti)->getLMO()->updateVisibility(); insilmaril@775: } insilmaril@775: } insilmaril@775: } insilmaril@775: insilmaril@786: if (!treeItemsNew.isEmpty()) insilmaril@775: { insilmaril@775: QModelIndex ix=newsel.indexes().first(); insilmaril@775: if (ix.isValid() ) insilmaril@775: { insilmaril@807: newIndex=ix; insilmaril@807: insilmaril@775: // Temporary unscroll if necessary insilmaril@775: TreeItem *ti= static_cast(ix.internalPointer()); insilmaril@775: if (ti->isBranchLikeType() ) insilmaril@775: { insilmaril@775: BranchItem *bi=(BranchItem*)ti; insilmaril@775: if (bi->hasScrolledParent(bi) ) insilmaril@796: { insilmaril@796: if (bi->parentBranch()->tmpUnscroll() ) insilmaril@796: do_reposition=true; insilmaril@796: } insilmaril@775: } insilmaril@779: if (ti->isBranchLikeType() || ti->getType()==TreeItem::Image) insilmaril@779: // Show link if needed insilmaril@779: ((MapItem*)ti)->getLMO()->updateVisibility(); insilmaril@775: } insilmaril@775: } insilmaril@796: if (do_reposition) model->reposition(); insilmaril@775: insilmaril@731: // Reduce rectangles insilmaril@786: while (treeItemsNew.count() < selboxList.count() ) insilmaril@731: delete selboxList.takeFirst(); insilmaril@731: insilmaril@731: // Add additonal rectangles insilmaril@731: QGraphicsRectItem *sb; insilmaril@786: while (treeItemsNew.count() > selboxList.count() ) insilmaril@728: { insilmaril@731: sb = mapScene->addRect( insilmaril@731: QRectF(0,0,0,0), insilmaril@731: QPen(selectionColor), insilmaril@731: selectionColor); insilmaril@731: sb->setZValue(Z_SELBOX); insilmaril@731: sb->show(); insilmaril@731: selboxList.append (sb); insilmaril@728: } insilmaril@731: insilmaril@731: // Reposition rectangles insilmaril@731: QRectF bbox; insilmaril@732: QModelIndex index; insilmaril@732: insilmaril@732: LinkableMapObj *lmo; insilmaril@786: for (int i=0; igetLMO(); insilmaril@731: bbox=lmo->getBBox(); insilmaril@786: sb=selboxList.at(i); insilmaril@731: sb->setRect ( insilmaril@731: bbox.x(),bbox.y(), insilmaril@731: bbox.width(), bbox.height()); insilmaril@731: sb->setPen (selectionColor); insilmaril@731: sb->setBrush (selectionColor); insilmaril@731: i++; insilmaril@731: } insilmaril@775: insilmaril@804: scene()->update(); insilmaril@729: } insilmaril@728: insilmaril@753: void MapEditor::updateData (const QModelIndex &sel) insilmaril@729: { insilmaril@753: TreeItem *ti= static_cast(sel.internalPointer()); insilmaril@732: insilmaril@746: /* testing insilmaril@753: cout << "ME::updateData\n"; insilmaril@732: insilmaril@753: cout << " ti="<updating...\n"; insilmaril@779: BranchObj *bo=(BranchObj*) ( ((MapItem*)ti)->getLMO()); insilmaril@767: bo->updateData(); insilmaril@753: } insilmaril@726: } insilmaril@412: insilmaril@728: void MapEditor::setSelectionColor (QColor col) insilmaril@728: { insilmaril@728: selectionColor=col; insilmaril@732: QItemSelection sel=model->getSelectionModel()->selection(); insilmaril@732: updateSelection(sel,sel); insilmaril@728: } insilmaril@728: insilmaril@753: insilmaril@728: QColor MapEditor::getSelectionColor () insilmaril@728: { insilmaril@728: return selectionColor; insilmaril@728: } insilmaril@728: insilmaril@728: