insilmaril@0: #include "mapeditor.h" insilmaril@0: insilmaril@0: #include insilmaril@95: #include insilmaril@0: #include insilmaril@0: insilmaril@720: #include insilmaril@720: insilmaril@175: #include "mainwindow.h" insilmaril@175: #include "misc.h" insilmaril@314: #include "warningdialog.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: extern FlagRowObj *standardFlagsDefault; insilmaril@0: insilmaril@366: extern QMenu* branchContextMenu; insilmaril@366: extern QMenu* branchAddContextMenu; insilmaril@366: extern QMenu* branchRemoveContextMenu; insilmaril@366: extern QMenu* branchLinksContextMenu; insilmaril@366: extern QMenu* branchXLinksContextMenuEdit; insilmaril@366: extern QMenu* branchXLinksContextMenuFollow; 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@720: model=vm; insilmaril@645: model->setScene (mapScene); insilmaril@720: model->registerEditor(this); insilmaril@720: model->addMapCenter(); // FIXME create this in MapEditor until BO and MCO are independent of scene insilmaril@720: model->makeDefault(); 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@398: setFocusPolicy (Qt::StrongFocus); insilmaril@0: insilmaril@0: pickingColor=false; insilmaril@91: drawingLink=false; insilmaril@93: copyingObj=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@723: //model->reposition(); //FIXME really still needed? insilmaril@381: insilmaril@531: 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@720: pw->setZValue (100); insilmaril@676: insilmaril@720: QAction *a = new QAction( tr( "Edit heading","MapEditor" ), this); insilmaril@720: a->setShortcut ( Qt::Key_Return ); //Edit heading insilmaril@720: //a->setShortcutContext (Qt::WindowShortcut); 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: //a->setShortcutContext (Qt::WindowShortcut); insilmaril@720: addAction (a); insilmaril@720: connect( a, SIGNAL( triggered() ), this, SLOT( editHeading() ) ); insilmaril@628: insilmaril@638: // Attributes //FIXME 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@0: //cout <<"Destructor MapEditor\n"; insilmaril@625: // tmpMapDir is in tmpVymDir, so it gets removed automagically when vym closes insilmaril@625: insilmaril@720: //removeDir(QDir(tmpMapDir)); // FIXME check?!? insilmaril@720: model->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@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@645: QRectF totalBBox=model->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@720: // FIXME 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@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@0: void MapEditor::toggleStandardFlag(QString f) insilmaril@0: { insilmaril@720: BranchObj *bo=model->getSelectedBranch(); insilmaril@424: if (bo) insilmaril@0: { insilmaril@424: QString u,r; insilmaril@424: if (bo->isSetStandardFlag(f)) insilmaril@366: { insilmaril@424: r="unsetFlag"; insilmaril@424: u="setFlag"; insilmaril@424: } insilmaril@424: else insilmaril@424: { insilmaril@424: u="unsetFlag"; insilmaril@424: r="setFlag"; insilmaril@424: } insilmaril@720: model->saveState( insilmaril@424: bo, insilmaril@424: QString("%1 (\"%2\")").arg(u).arg(f), insilmaril@424: bo, insilmaril@424: QString("%1 (\"%2\")").arg(r).arg(f), insilmaril@424: QString("Toggling standard flag \"%1\" of %2").arg(f).arg(getName(bo))); insilmaril@424: bo->toggleStandardFlag (f,mainWindow->useFlagGroups()); insilmaril@720: model->updateSelection(); insilmaril@424: } insilmaril@0: } insilmaril@0: insilmaril@442: void MapEditor::updateSelection() insilmaril@442: { insilmaril@442: // Tell selection to update geometries insilmaril@720: model->updateSelection(); insilmaril@94: } insilmaril@94: insilmaril@628: AttributeTable* MapEditor::attributeTable() insilmaril@628: { insilmaril@628: return attrTable; insilmaril@628: } insilmaril@628: insilmaril@527: void MapEditor::testFunction1() insilmaril@0: { insilmaril@723: //BranchObj *bo=model->getSelectedBranch(); insilmaril@720: //if (bo) model->moveAway (bo); insilmaril@723: //if (bo) bo->setLinkStyle (LinkableMapObj::Line); insilmaril@432: insilmaril@723: insilmaril@723: // Displacement and animation of all non-mainbranches insilmaril@723: QPointF p; insilmaril@723: QPointF q; insilmaril@723: BranchObj *bo; insilmaril@723: bo=model->first(); insilmaril@723: while (bo) insilmaril@723: { insilmaril@723: if (bo->getDepth() >0 && !bo->hasScrolledParent(bo) ) insilmaril@723: { insilmaril@723: p=QPointF (qrand() %600-300, qrand () %600-300); insilmaril@723: bo->setRelPos(); insilmaril@723: q=bo->getRelPos(); insilmaril@723: model->startAnimation (bo,p, q); insilmaril@723: } insilmaril@723: bo=model->next(bo); insilmaril@723: } insilmaril@723: insilmaril@723: insilmaril@723: insilmaril@420: /* TODO 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="<getSelectedBranch(); insilmaril@720: if (bo) insilmaril@720: { insilmaril@720: model->setSelectionBlocked(true); insilmaril@720: insilmaril@720: lineEdit->setText (bo->getHeading()); insilmaril@720: QPoint p = mapTo (this,bo->getAbsPos().toPoint() ); insilmaril@720: lineEdit->setGeometry(p.x(),p.y(),230,25); insilmaril@720: lineEdit->selectAll(); 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@645: LinkableMapObj* lmo=model->findMapObj(p, NULL); insilmaril@0: insilmaril@0: if (lmo) insilmaril@0: { // MapObj was found insilmaril@720: if (model->getSelection() != lmo) insilmaril@0: { insilmaril@0: // select the MapObj insilmaril@720: model->select(lmo); insilmaril@0: } insilmaril@0: // Context Menu insilmaril@720: if (model->getSelectedBranch() ) insilmaril@0: { insilmaril@424: // Context Menu on branch or mapcenter insilmaril@720: model->updateActions(); insilmaril@424: branchContextMenu->popup(e->globalPos() ); insilmaril@424: } else insilmaril@424: { insilmaril@720: if (model->getSelectedFloatImage() ) insilmaril@0: { insilmaril@0: // Context Menu on floatimage insilmaril@720: model->updateActions(); 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@720: model->updateActions(); 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@329: // Ignore right clicks, these will go to context menus insilmaril@366: if (e->button() == Qt::RightButton ) insilmaril@329: { 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@491: e->ignore(); insilmaril@491: return; insilmaril@491: } insilmaril@491: insilmaril@408: QPointF p = mapToScene(e->pos()); insilmaril@645: LinkableMapObj* lmo=model->findMapObj(p, NULL); insilmaril@0: insilmaril@329: e->accept(); insilmaril@329: insilmaril@442: //Take care of system flags _or_ modifier modes insilmaril@267: // insilmaril@267: if (lmo && (typeid(*lmo)==typeid(BranchObj) || insilmaril@267: typeid(*lmo)==typeid(MapCenterObj) )) insilmaril@267: { insilmaril@267: QString foname=((BranchObj*)lmo)->getSystemFlagName(p); insilmaril@267: if (!foname.isEmpty()) insilmaril@267: { insilmaril@267: // systemFlag clicked insilmaril@720: model->selectInt (lmo); insilmaril@267: if (foname=="url") insilmaril@267: { insilmaril@366: if (e->state() & Qt::ControlModifier) insilmaril@267: mainWindow->editOpenURLTab(); insilmaril@267: else insilmaril@267: mainWindow->editOpenURL(); insilmaril@267: } insilmaril@267: else if (foname=="vymLink") insilmaril@267: { insilmaril@267: mainWindow->editOpenVymLink(); insilmaril@267: // tabWidget may change, better return now insilmaril@267: // before segfaulting... insilmaril@267: } else if (foname=="note") insilmaril@267: mainWindow->windowToggleNoteEditor(); insilmaril@267: else if (foname=="hideInExport") insilmaril@720: model->toggleHideExport(); insilmaril@720: // FIXME needed? xelection.update(); insilmaril@267: return; insilmaril@267: } insilmaril@720: } 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@90: BranchObj *bo_begin=NULL; insilmaril@90: if (lmo) insilmaril@90: bo_begin=(BranchObj*)(lmo); insilmaril@90: else insilmaril@720: bo_begin=model->getSelectedBranch(); insilmaril@90: if (bo_begin) insilmaril@83: { insilmaril@83: drawingLink=true; insilmaril@90: linkingObj_src=bo_begin; insilmaril@408: tmpXLink=new XLinkObj (mapScene); insilmaril@95: tmpXLink->setBegin (bo_begin); insilmaril@95: tmpXLink->setEnd (p); insilmaril@720: tmpXLink->setColor(model->getMapDefXLinkColor()); insilmaril@720: tmpXLink->setWidth(model->getMapDefXLinkWidth()); insilmaril@95: tmpXLink->updateXLink(); insilmaril@95: tmpXLink->setVisibility (true); insilmaril@83: return; insilmaril@89: } insilmaril@267: } insilmaril@442: } // End of modmodes insilmaril@442: insilmaril@0: if (lmo) insilmaril@267: { insilmaril@442: // Select the clicked object insilmaril@720: model->selectInt (lmo); insilmaril@442: insilmaril@0: // Left Button Move Branches insilmaril@366: if (e->button() == Qt::LeftButton ) insilmaril@0: { insilmaril@424: //movingObj_start.setX( p.x() - selection->x() );// TODO replaced selection->lmo here insilmaril@424: //movingObj_start.setY( p.y() - selection->y() ); insilmaril@424: movingObj_start.setX( p.x() - lmo->x() ); insilmaril@424: movingObj_start.setY( p.y() - lmo->y() ); insilmaril@129: movingObj_orgPos.setX (lmo->x() ); insilmaril@129: movingObj_orgPos.setY (lmo->y() ); insilmaril@720: lmo->setRelPos(); insilmaril@366: movingObj_orgRelPos=lmo->getRelPos(); insilmaril@129: insilmaril@93: // If modMode==copy, then we want to "move" the _new_ object around insilmaril@93: // then we need the offset from p to the _old_ selection, because of tmp insilmaril@473: if (mainWindow->getModMode()==Main::ModModeCopy && insilmaril@366: e->state() & Qt::ControlModifier) insilmaril@93: { insilmaril@720: BranchObj *bo=model->getSelectedBranch(); insilmaril@645: if (bo) insilmaril@93: { insilmaril@93: copyingObj=true; insilmaril@720: bo->addBranch ((BranchObj*)model->getSelection()); insilmaril@720: model->unselect(); insilmaril@720: model->select(bo->getLastBranch()); insilmaril@645: model->reposition(); insilmaril@93: } insilmaril@421: } insilmaril@421: insilmaril@720: movingObj=model->getSelection(); 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@720: model->updateActions(); insilmaril@720: // FIXME 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@720: LinkableMapObj *lmosel=model->getSelection(); insilmaril@83: insilmaril@0: // Move the selected MapObj insilmaril@424: if ( lmosel && movingObj) insilmaril@0: { 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@164: // ensureSelectionVisible, if not tmp linked insilmaril@424: if (!lmosel->hasParObjTmp()) insilmaril@720: model->ensureSelectionVisible (); 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@645: LinkableMapObj* lmo=model->findMapObj(p, lmosel); insilmaril@0: insilmaril@0: insilmaril@720: FloatObj *fio=model->getSelectedFloatImage(); insilmaril@424: if (fio) insilmaril@0: { insilmaril@424: fio->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() ); insilmaril@424: fio->setRelPos(); insilmaril@424: fio->updateLink(); //no need for reposition, if we update link here insilmaril@720: model->updateSelection(); 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@388: if ( (e->modifiers()==Qt::ShiftModifier) && lmo && insilmaril@0: ( (typeid(*lmo)==typeid(BranchObj)) || insilmaril@0: (typeid(*lmo)==typeid(MapCenterObj)) ) && insilmaril@424: ( lmo != fio->getParObj()) insilmaril@0: ) insilmaril@0: { insilmaril@424: if (typeid(*fio) == typeid(FloatImageObj) && insilmaril@420: ( (typeid(*lmo)==typeid(BranchObj) || insilmaril@420: typeid(*lmo)==typeid(MapCenterObj)) )) insilmaril@0: { insilmaril@420: insilmaril@420: // Also save the move which was done so far insilmaril@420: QString pold=qpointfToString(movingObj_orgRelPos); insilmaril@420: QString pnow=qpointfToString(fio->getRelPos()); insilmaril@720: model->saveState( insilmaril@424: fio, insilmaril@420: "moveRel "+pold, insilmaril@424: fio, insilmaril@420: "moveRel "+pnow, insilmaril@625: QString("Move %1 to relative position %2").arg(getName(fio)).arg(pnow)); insilmaril@420: fio->getParObj()->requestReposition(); insilmaril@645: model->reposition(); insilmaril@420: insilmaril@720: model->linkFloatImageTo (model->getSelectString(lmo)); insilmaril@442: //movingObj=lmosel; insilmaril@442: //movingObj_orgRelPos=lmosel->getRelPos(); insilmaril@420: insilmaril@645: model->reposition(); insilmaril@0: } insilmaril@0: } insilmaril@388: } else insilmaril@388: { // selection != a FloatObj insilmaril@0: if (lmosel->getDepth()==0) insilmaril@0: { insilmaril@388: // Move MapCenter insilmaril@388: if (e->buttons()== Qt::LeftButton && e->modifiers()==Qt::ShiftModifier) insilmaril@645: ((MapCenterObj*)lmosel)->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() ); insilmaril@0: else insilmaril@645: lmosel->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() ); insilmaril@645: model->updateRelPositions(); insilmaril@0: } else insilmaril@0: { insilmaril@0: if (lmosel->getDepth()==1) insilmaril@0: { insilmaril@388: // Move mainbranch insilmaril@0: lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() ); 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@431: // Maybe we can relink temporary? insilmaril@720: if (lmo && (lmo!=lmosel) && model->getSelectedBranch() && insilmaril@431: (typeid(*lmo)==typeid(BranchObj) || insilmaril@431: typeid(*lmo)==typeid(MapCenterObj)) ) insilmaril@431: insilmaril@0: { insilmaril@388: if (e->modifiers()==Qt::ControlModifier) insilmaril@0: { insilmaril@0: // Special case: CTRL to link below lmo insilmaril@0: lmosel->setParObjTmp (lmo,p,+1); insilmaril@0: } insilmaril@388: else if (e->modifiers()==Qt::ShiftModifier) insilmaril@0: lmosel->setParObjTmp (lmo,p,-1); insilmaril@0: else insilmaril@0: lmosel->setParObjTmp (lmo,p,0); insilmaril@0: } else insilmaril@0: { insilmaril@93: lmosel->unsetParObjTmp(); insilmaril@0: } insilmaril@428: // reposition subbranch insilmaril@428: lmosel->reposition(); insilmaril@0: } // depth>0 insilmaril@0: insilmaril@720: model->updateSelection();// FIXME needed? 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@0: LinkableMapObj *dst; insilmaril@720: LinkableMapObj *lmosel=model->getSelection(); 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@645: dst=model->findMapObj(p, NULL); insilmaril@424: if (dst && lmosel) 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@645: dst=model->findMapObj(p, NULL); insilmaril@424: if (dst && lmosel) insilmaril@83: { insilmaril@95: tmpXLink->setEnd ( ((BranchObj*)(dst)) ); insilmaril@95: tmpXLink->updateXLink(); insilmaril@491: tmpXLink->activate(); //FIXME savestate missing insilmaril@720: //model->saveStateComplete(QString("Activate xLink from %1 to %2").arg(getName(tmpXLink->getBegin())).arg(getName(tmpXLink->getEnd())) ); insilmaril@83: } else insilmaril@83: { insilmaril@95: delete(tmpXLink); insilmaril@95: tmpXLink=NULL; insilmaril@83: } insilmaril@83: return; insilmaril@83: } insilmaril@83: insilmaril@0: // Have we been moving something? insilmaril@424: if ( lmosel && movingObj ) insilmaril@0: { insilmaril@720: FloatImageObj *fo=model->getSelectedFloatImage(); insilmaril@424: if(fo) insilmaril@175: { insilmaril@388: // Moved FloatObj. Maybe we need to reposition insilmaril@408: QString pold=qpointfToString(movingObj_orgRelPos); insilmaril@408: QString pnow=qpointfToString(fo->getRelPos()); insilmaril@720: model->saveState( insilmaril@424: fo, insilmaril@366: "moveRel "+pold, insilmaril@424: fo, insilmaril@366: "moveRel "+pnow, insilmaril@625: QString("Move %1 to relative position %2").arg(getName(fo)).arg(pnow)); insilmaril@424: insilmaril@424: fo->getParObj()->requestReposition(); insilmaril@645: model->reposition(); insilmaril@175: } insilmaril@175: insilmaril@0: // Check if we are over another branch, but ignore insilmaril@0: // any found LMOs, which are FloatObjs insilmaril@645: dst=model->findMapObj(mapToScene(e->pos() ), lmosel); insilmaril@0: insilmaril@336: if (dst && (typeid(*dst)!=typeid(BranchObj) && typeid(*dst)!=typeid(MapCenterObj))) insilmaril@0: dst=NULL; insilmaril@0: insilmaril@720: BranchObj *bo=model->getSelectedBranch(); insilmaril@645: if (bo && bo->getDepth()==0) insilmaril@497: { insilmaril@645: if (movingObj_orgPos != bo->getAbsPos()) insilmaril@625: { insilmaril@625: QString pold=qpointfToString(movingObj_orgPos); insilmaril@645: QString pnow=qpointfToString(bo->getAbsPos()); insilmaril@720: model->saveState( insilmaril@723: bo, insilmaril@625: "move "+pold, insilmaril@723: bo, insilmaril@625: "move "+pnow, insilmaril@645: QString("Move mapcenter %1 to position %2").arg(getName(bo)).arg(pnow)); insilmaril@625: } insilmaril@388: } insilmaril@645: insilmaril@720: if (model->selectionType() == Selection::Branch ) insilmaril@388: { // A branch was moved insilmaril@388: 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@684: QString preSelStr=model->getSelectString(lmosel); insilmaril@93: insilmaril@94: copyingObj=false; insilmaril@129: if (dst ) insilmaril@93: { insilmaril@691: // We have a destination, relink to that insilmaril@691: insilmaril@720: BranchObj* bsel=model->getSelectedBranch(); insilmaril@366: BranchObj* bdst=(BranchObj*)dst; insilmaril@366: insilmaril@684: QString preParStr=model->getSelectString (bsel->getParObj()); insilmaril@366: QString preNum=QString::number (bsel->getNum(),10); insilmaril@366: QString preDstParStr; insilmaril@366: insilmaril@366: if (e->state() & Qt::ShiftModifier && dst->getParObj()) insilmaril@366: { // Link above dst insilmaril@684: preDstParStr=model->getSelectString (dst->getParObj()); insilmaril@421: bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum()); 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@421: bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum()+1); insilmaril@366: } else insilmaril@366: { // Append to dst insilmaril@684: preDstParStr=model->getSelectString(dst); insilmaril@421: bsel->linkTo (bdst,-1); insilmaril@366: if (dst->getDepth()==0) bsel->move (savePos); insilmaril@366: } insilmaril@684: QString postSelStr=model->getSelectString(lmosel); insilmaril@366: QString postNum=QString::number (bsel->getNum(),10); insilmaril@366: insilmaril@421: QString undoCom="linkTo (\""+ insilmaril@366: preParStr+ "\"," + preNum +"," + insilmaril@366: QString ("%1,%2").arg(movingObj_orgPos.x()).arg(movingObj_orgPos.y())+ ")"; insilmaril@366: insilmaril@421: QString redoCom="linkTo (\""+ insilmaril@366: preDstParStr + "\"," + postNum + "," + insilmaril@366: QString ("%1,%2").arg(savePos.x()).arg(savePos.y())+ ")"; insilmaril@366: insilmaril@720: model->saveState ( insilmaril@366: postSelStr,undoCom, insilmaril@366: preSelStr, redoCom, insilmaril@366: QString("Relink %1 to %2").arg(getName(bsel)).arg(getName(dst)) ); insilmaril@691: insilmaril@691: model->reposition(); // not necessary if we undo temporary move below insilmaril@163: } else insilmaril@691: { insilmaril@691: // No destination, undo temporary move insilmaril@691: insilmaril@424: if (lmosel->getDepth()==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@625: QString ps=qpointfToString(rp); insilmaril@720: model->saveState( insilmaril@684: model->getSelectString(lmosel), "moveRel "+qpointfToString(movingObj_orgRelPos), insilmaril@625: preSelStr, "moveRel "+ps, insilmaril@625: QString("Move %1 to relative position %2").arg(getName(lmosel)).arg(ps)); insilmaril@625: } insilmaril@366: } insilmaril@691: insilmaril@691: // Draw the original link, before selection was moved around insilmaril@691: if (settings.value("/animation/use",false).toBool() && lmosel->getDepth()>1) insilmaril@691: { insilmaril@720: lmosel->setRelPos(); // calc relPos first for starting point insilmaril@720: QPointF dst=bo->getParObj()->getChildPos(); insilmaril@720: // if (lmosel->getOrientation()==LinkableMapObj::LeftOfCenter) dst.setX (dst.x()+lmosel->width() ); insilmaril@720: insilmaril@691: model->startAnimation( insilmaril@723: (BranchObj*)lmosel, insilmaril@691: lmosel->getRelPos(), insilmaril@720: movingObj_orgRelPos insilmaril@720: // QPointF (movingObj_orgPos.x() - dst.x(), movingObj_orgPos.y() - dst.y() ) insilmaril@691: ); insilmaril@691: } else insilmaril@691: model->reposition(); insilmaril@691: } insilmaril@0: } insilmaril@720: model->updateSelection(); insilmaril@408: // Finally resize scene, if needed insilmaril@408: scene()->update(); insilmaril@0: movingObj=NULL; insilmaril@366: insilmaril@366: // Just make sure, that actions are still ok,e.g. the move branch up/down buttons... insilmaril@720: model->updateActions(); 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@720: if (model->isSelectionBlocked() ) insilmaril@491: { insilmaril@491: e->ignore(); insilmaril@491: return; insilmaril@491: } insilmaril@491: insilmaril@366: if (e->button() == Qt::LeftButton ) insilmaril@0: { insilmaril@408: QPointF p = mapToScene(e->pos()); insilmaril@645: LinkableMapObj *lmo=model->findMapObj(p, NULL); insilmaril@0: if (lmo) { // MapObj was found insilmaril@0: // First select the MapObj than edit heading insilmaril@720: model->select (lmo); insilmaril@720: editHeading(); insilmaril@0: } insilmaril@0: } insilmaril@0: } insilmaril@0: insilmaril@0: void MapEditor::resizeEvent (QResizeEvent* e) insilmaril@0: { insilmaril@408: QGraphicsView::resizeEvent( e ); insilmaril@0: } insilmaril@0: insilmaril@412: void MapEditor::dragEnterEvent(QDragEnterEvent *event) insilmaril@119: { insilmaril@417: //for (unsigned int i=0;event->format(i);i++) // Debug mime type insilmaril@417: // cerr << event->format(i) << endl; insilmaril@417: insilmaril@417: if (event->mimeData()->hasImage()) insilmaril@417: event->acceptProposedAction(); insilmaril@417: else insilmaril@417: if (event->mimeData()->hasUrls()) insilmaril@417: event->acceptProposedAction(); insilmaril@417: } insilmaril@417: insilmaril@531: void MapEditor::dragMoveEvent(QDragMoveEvent *) insilmaril@417: { insilmaril@417: } insilmaril@417: insilmaril@417: void MapEditor::dragLeaveEvent(QDragLeaveEvent *event) insilmaril@417: { insilmaril@417: event->accept(); insilmaril@119: } insilmaril@129: insilmaril@412: void MapEditor::dropEvent(QDropEvent *event) insilmaril@129: { insilmaril@720: BranchObj *sel=model->getSelectedBranch(); insilmaril@424: if (sel) insilmaril@128: { insilmaril@505: if (debug) insilmaril@505: foreach (QString format,event->mimeData()->formats()) insilmaril@658: cout << "MapEditor: Dropped format: "< 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@417: BranchObj *bo; insilmaril@428: for (int i=0; iaddBranch(); insilmaril@428: if (bo) insilmaril@417: { 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@428: bo->setVymLink(file); insilmaril@428: else insilmaril@428: bo->setURL(uris.at(i).toString()); insilmaril@428: } else insilmaril@428: { insilmaril@428: bo->setURL(uris.at(i).toString()); insilmaril@428: } insilmaril@428: insilmaril@428: if (!heading.isEmpty()) insilmaril@428: bo->setHeading(heading); insilmaril@428: else insilmaril@428: bo->setHeading(uris.at(i).toString()); insilmaril@428: } insilmaril@417: } insilmaril@417: } insilmaril@645: model->reposition(); insilmaril@417: } insilmaril@417: } insilmaril@417: event->acceptProposedAction(); insilmaril@417: } insilmaril@417: insilmaril@528: insilmaril@412: insilmaril@412: bool isUnicode16(const QByteArray &d) insilmaril@412: { insilmaril@412: // TODO: make more precise check for unicode 16. insilmaril@412: // Guess unicode16 if any of second bytes are zero insilmaril@412: unsigned int length = max(0,d.size()-2)/2; insilmaril@412: for (unsigned int i = 0; i