diff -r f0fe7c36ec5c -r 43268373032d vymmodel.cpp --- a/vymmodel.cpp Fri Apr 09 14:24:04 2010 +0000 +++ b/vymmodel.cpp Wed Jun 09 13:14:08 2010 +0000 @@ -12,14 +12,13 @@ #include "exporthtmldialog.h" #include "file.h" #include "findresultmodel.h" -#include "geometry.h" // for addBBox #include "mainwindow.h" #include "misc.h" #include "parser.h" #include "process.h" -#include "warningdialog.h" #include "xlinkitem.h" +#include "xlinkobj.h" #include "xml-freemind.h" #include "xmlobj.h" #include "xml-vym.h" @@ -54,7 +53,7 @@ VymModel::VymModel() { - //cout << "Const VymModel\n"; + //qDebug()<< "Const VymModel"; init(); rootItem->setModel (this); } @@ -62,18 +61,20 @@ VymModel::~VymModel() { - //cout << "Destr VymModel\n"; + //qDebug() << "Destr VymModel begin this="<stop(); fileChangedTimer->stop(); - clear(); - if (mapEditor) delete (mapEditor); + //qApp->processEvents(); // Update view (scene()->update() is not enough) + //qDebug() << "Destr VymModel end this="<childCount() >0) + { + //qDebug()<<"VM::clear ri="<count()="<childCount(); deleteItem (rootItem->getChildNum(0) ); + } } void VymModel::init () @@ -125,11 +126,11 @@ // find routine findReset(); - // animations // FIXME-3 switch to new animation system - animationUse=settings.readBoolEntry("/animation/use",false); // FIXME-3 add options to control _what_ is animated + // animations // FIXME-4 switch to new animation system + animationUse=settings.readBoolEntry("/animation/use",false); // FIXME-4 add options to control _what_ is animated animationTicks=settings.readNumEntry("/animation/ticks",10); animationInterval=settings.readNumEntry("/animation/interval",50); - animObjList.clear(); + animObjList.clear(); animationTimer=new QTimer (this); connect(animationTimer, SIGNAL(timeout()), this, SLOT(animate())); @@ -144,6 +145,9 @@ hidemode=TreeItem::HideNone; + // Avoid recursions later + cleaningUpLinks=false; + // Network netstate=Offline; @@ -236,21 +240,34 @@ // Find the used flags while traversing the tree // FIXME-3 this can be done local to vymmodel maybe... standardFlagsMaster->resetUsedCounter(); + + // Temporary list of links + QList tmpLinks; + // Build xml recursivly if (!saveSel) + { // Save all mapcenters as complete map, if saveSel not set - s+=saveTreeToDir(tmpdir,prefix,offset); - else + s+=saveTreeToDir(tmpdir,prefix,offset,tmpLinks); + + // Save local settings + s+=settings.getDataXML (destPath); + + // Save selection + if (getSelectedItem() && !saveSel ) + s+=xml.valueElement("select",getSelectString()); + + } else { switch (saveSel->getType()) { case TreeItem::Branch: // Save Subtree - s+=((BranchItem*)saveSel)->saveToDir(tmpdir,prefix,offset); + s+=((BranchItem*)saveSel)->saveToDir(tmpdir,prefix,offset,tmpLinks); break; case TreeItem::MapCenter: // Save Subtree - s+=((BranchItem*)saveSel)->saveToDir(tmpdir,prefix,offset); + s+=((BranchItem*)saveSel)->saveToDir(tmpdir,prefix,offset,tmpLinks); break; case TreeItem::Image: // Save Image @@ -262,12 +279,11 @@ } } - // Save local settings - s+=settings.getDataXML (destPath); - - // Save selection - if (getSelectedItem() && !saveSel ) - s+=xml.valueElement("select",getSelectString()); + // Save XLinks + for (int i=0; isaveToDir(); + } xml.decIndent(); s+=xml.endElement("vymmap"); @@ -278,12 +294,11 @@ return s; } -QString VymModel::saveTreeToDir (const QString &tmpdir,const QString &prefix, const QPointF &offset) +QString VymModel::saveTreeToDir (const QString &tmpdir,const QString &prefix, const QPointF &offset, QList &tmpLinks) { QString s; - for (int i=0; ibranchCount(); i++) - s+=rootItem->getBranchNum(i)->saveToDir (tmpdir,prefix,offset); + s+=rootItem->getBranchNum(i)->saveToDir (tmpdir,prefix,offset,tmpLinks); return s; } @@ -338,10 +353,22 @@ return destPath; } -ErrorCode VymModel::load (QString fname, const LoadMode &lmode, const FileType &ftype) +ErrorCode VymModel::loadMap ( + QString fname, + const LoadMode &lmode, + bool saveStateFlag, + const FileType &ftype, + int pos) { ErrorCode err=success; + // Get updated zoomFactor, before applying one read from file in the end + if (mapEditor) zoomFactor=mapEditor->getZoomFactorTarget(); + + // For ImportReplace let's insert a new branch and replace that + BranchItem *selbi=getSelectedBranch(); + BranchItem *newbi=NULL; + parseBaseHandler *handler; fileType=ftype; switch (fileType) @@ -361,20 +388,23 @@ selModel->clearSelection(); } else { - BranchItem *bi=getSelectedBranch(); - if (!bi) return aborted; + if (!selbi) return aborted; if (lmode==ImportAdd) - saveStateChangingPart( - bi, - bi, + if (saveStateFlag) saveStateChangingPart( + selbi, + selbi, QString("addMapInsert (%1)").arg(fname), - QString("Add map %1 to %2").arg(fname).arg(getObjectName(bi))); - else - saveStateChangingPart( - bi, - bi, + QString("Add map %1 to %2").arg(fname).arg(getObjectName(selbi))); + if (lmode==ImportReplace) + { + if (saveStateFlag) saveStateChangingPart( + selbi, + selbi, QString("addMapReplace(%1)").arg(fname), - QString("Add map %1 to %2").arg(fname).arg(getObjectName(bi))); + QString("Add map %1 to %2").arg(fname).arg(getObjectName(selbi))); + newbi=addNewBranchInt (selbi,-1); // Add below selection + select (newbi); + } } @@ -465,7 +495,11 @@ tmpdir=fname.left(fname.findRev("/",-1)); handler->setTmpDir (tmpdir); handler->setInputFile (file.name()); - handler->setLoadMode (lmode); + if (lmode==ImportReplace) + handler->setLoadMode (ImportAdd,pos); + else + handler->setLoadMode (lmode,pos); + bool ok = reader.parse( source ); blockReposition=false; blockSaveState=blockSaveStateOrg; @@ -473,18 +507,27 @@ file.close(); if ( ok ) { - reposition(); - emitSelectionChanged(); if (lmode==NewMap) { mapDefault=false; mapChanged=false; mapUnsaved=false; autosaveTimer->stop(); + + // Reset timestamp to check for later updates of file + fileChangedTime=QFileInfo (destPath).lastModified(); } - // Reset timestamp to check for later updates of file - fileChangedTime=QFileInfo (destPath).lastModified(); + + + if (lmode==ImportReplace) + { + deleteItem (selbi); + select (newbi); + deleteKeepChildren (false); + } + reposition(); + emitSelectionChanged(); } else { QMessageBox::critical( 0, tr( "Critical Parse Error" ), @@ -640,96 +683,6 @@ return err; } -void VymModel::addMapReplaceInt(const QString &undoSel, const QString &path) -{ - QString pathDir=path.left(path.findRev("/")); - QDir d(pathDir); - QFile file (path); - - if (d.exists() ) - { - // We need to parse saved XML data - parseVYMHandler handler; - QXmlInputSource source( file); - QXmlSimpleReader reader; - reader.setContentHandler( &handler ); - reader.setErrorHandler( &handler ); - handler.setModel ( this); - handler.setTmpDir ( pathDir ); // needed to load files with rel. path - if (undoSel.isEmpty()) - { - unselect(); - clear(); - handler.setLoadMode (NewMap); - } else - { - select (undoSel); - handler.setLoadMode (ImportReplace); - } - blockReposition=true; - bool ok = reader.parse( source ); - blockReposition=false; - if (! ok ) - { - // This should never ever happen - QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path), - handler.errorProtocol()); - } - } else - QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path)); -} - -bool VymModel::addMapInsertInt (const QString &path) -{ - QString pathDir=path.left(path.findRev("/")); - QDir d(pathDir); - QFile file (path); - - if (d.exists() ) - { - // We need to parse saved XML data - parseVYMHandler handler; - QXmlInputSource source( file); - QXmlSimpleReader reader; - reader.setContentHandler( &handler ); - reader.setErrorHandler( &handler ); - handler.setModel (this); - handler.setTmpDir ( pathDir ); // needed to load files with rel. path - handler.setLoadMode (ImportAdd); - blockReposition=true; - bool ok = reader.parse( source ); - blockReposition=false; - if ( ok ) return true; - { - // This should never ever happen - QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path), - handler.errorProtocol()); - } - } else - QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path)); - return false; -} - -bool VymModel::addMapInsertInt (const QString &path, int pos) -{ - BranchItem *selbi=getSelectedBranch(); - if (selbi) - { - if (addMapInsertInt (path)) - { - if (selbi->depth()>0) - relinkBranch (selbi->getLastBranch(), selbi,pos); - return true; - } else - { - QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path)); - return false; - } - } - qWarning ("ME::addMapInsertInt nothing selected"); - return false; -} - ImageItem* VymModel::loadFloatImageInt (BranchItem *dst,QString fn) { ImageItem *ii=createImage(dst); @@ -975,7 +928,7 @@ { case QMessageBox::Yes: // Reload map - load (filePath,NewMap,fileType); + loadMap (filePath); case QMessageBox::Cancel: fileChangedTime=tmod; // allow autosave to overwrite newer file! } @@ -1109,7 +1062,7 @@ return false; } -void VymModel::undo() +void VymModel::undo() //FIXME-1 segfault when trying to undo in a brandnew map { // Can we undo at all? if (undosAvail<1) return; @@ -1253,6 +1206,7 @@ makeSubDirs (histDir); // Save depending on how much needs to be saved + QList tmpLinks; if (saveSel) backupXML=saveToDir (histDir,mapName+"-",false, QPointF (),saveSel); @@ -1529,7 +1483,7 @@ return sortFilter; } -void VymModel::setHeading(const QString &s) +void VymModel::setHeading(const QString &s) { BranchItem *selbi=getSelectedBranch(); if (selbi) @@ -1541,7 +1495,7 @@ "setHeading (\""+s+"\")", QString("Set heading of %1 to \"%2\"").arg(getObjectName(selbi)).arg(s) ); selbi->setHeading(s ); - emitDataHasChanged ( selbi); //FIXME-3 maybe emit signal from TreeItem? + emitDataHasChanged ( selbi); //FIXME-4 maybe emit signal from TreeItem? reposition(); emitSelectionChanged(); } @@ -1655,7 +1609,7 @@ { rmodel->clear(); rmodel->setSearchString (s); - rmodel->setSearchFlags (0); //FIXME-2 translate cs to QTextDocument::FindFlag + rmodel->setSearchFlags (0); //FIXME-3 translate cs to QTextDocument::FindFlag BranchItem *cur=NULL; BranchItem *prev=NULL; nextBranch(cur,prev); @@ -1671,7 +1625,7 @@ int j=0; while ( i>=0) { - i=n.indexOf (s,i,cs); //FIXME-2 add subitems to rmodel + i=n.indexOf (s,i,cs); if (i>=0) { // If not there yet, add "parent" item @@ -2050,20 +2004,17 @@ void VymModel::pasteNoSave(const int &n) { - bool old=blockSaveState; - blockSaveState=true; bool zippedOrg=zipped; if (redosAvail > 0 || n!=0) { // Use the "historical" buffer QString bakMapName(QString("history-%1").arg(n)); QString bakMapDir(tmpMapDir +"/"+bakMapName); - load (bakMapDir+"/"+clipboardFile,ImportAdd, VymMap); + loadMap (bakMapDir+"/"+clipboardFile,ImportAdd, false); } else // Use the global buffer - load (clipboardDir+"/"+clipboardFile,ImportAdd, VymMap); + loadMap (clipboardDir+"/"+clipboardFile,ImportAdd, false); zipped=zippedOrg; - blockSaveState=old; } void VymModel::paste() @@ -2231,39 +2182,61 @@ return NULL; } -XLinkItem* VymModel::createXLink(BranchItem *bi,bool createMO) -{ - if (bi) - { +bool VymModel::createLink(Link *link, bool createMO) +{ + BranchItem *begin=link->getBeginBranch(); + BranchItem *end =link->getEndBranch(); + + if (!begin || !end) + { + qWarning ()<<"VM::createXLinkNew part of XLink is NULL"; + return false; + } + + QModelIndex parix; int n; QList cData; - cData << "new xLink"<<"undef"; - - XLinkItem *newxli=new XLinkItem(cData) ; - newxli->setBegin (bi); + + cData << "new Link begin"<<"undef"; + XLinkItem *newli=new XLinkItem(cData) ; + newli->setLink (link); + link->setBeginLinkItem (newli); emit (layoutAboutToBeChanged() ); - parix=index(bi); - n=bi->getRowNumAppend(newxli); + parix=index(begin); + n=begin->getRowNumAppend(newli); beginInsertRows (parix,n,n); - bi->appendChild (newxli); + begin->appendChild (newli); endInsertRows (); + cData.clear(); + cData << "new Link end"<<"undef"; + newli=new XLinkItem(cData) ; + newli->setLink (link); + link->setEndLinkItem (newli); + + parix=index(end); + n=end->getRowNumAppend(newli); + beginInsertRows (parix,n,n); + end->appendChild (newli); + endInsertRows (); + emit (layoutChanged() ); - // save scroll state. If scrolled, automatically select - // new branch in order to tmp unscroll parent... + xlinks.append (link); + link->activate(); + if (createMO) { - newxli->createMapObj(mapScene); + link->createMapObj(mapScene); reposition(); } - return newxli; - } - return NULL; +// } + //return newli; + return true; } AttributeItem* VymModel::addAttribute() @@ -2279,7 +2252,7 @@ return NULL; } -AttributeItem* VymModel::addAttribute(AttributeItem *ai) // FIXME-2 savestate missing +AttributeItem* VymModel::addAttribute(AttributeItem *ai) // FIXME-3 savestate missing { BranchItem *selbi=getSelectedBranch(); if (selbi) @@ -2294,7 +2267,7 @@ emit (layoutChanged() ); - ai->createMapObj(mapScene); //FIXME-2 check that... + ai->createMapObj(mapScene); //FIXME-3 check that... reposition(); return ai; } @@ -2564,7 +2537,30 @@ return false; } -void VymModel::deleteSelection() //FIXME-2 xLinks in a deleted subtree are not restored on undo +void VymModel::cleanupLinks() +{ + // This probably could be done more elegant from destructor of a Link, + // but somehow this resulted in strange segfaults deep in Qt and glibc... + //qDebug ()<<"VM::cleanupLinks begin"<< "CUL="<getBeginLinkItem(); + //qDebug()<<"VM::cleanupLinks a) l="<parent(); if (!pi) return; - if (ti->getType()==TreeItem::Image || ti->getType()==TreeItem::Attribute) + if (ti->getType()==TreeItem::Image || ti->getType()==TreeItem::Attribute||ti->getType()==TreeItem::XLink) { saveStateChangingPart( pi, @@ -2605,16 +2603,12 @@ select (pi); reposition(); emitShowSelection(); - } else if (ti->getType()==TreeItem::XLink) - { - //FIXME-2 savestate for deleting xlink missing - deleteItem (ti); } else qWarning ("VymmModel::deleteSelection() unknown type?!"); } } -void VymModel::deleteKeepChildren() //FIXME-3 does not work yet for mapcenters +void VymModel::deleteKeepChildren(bool saveStateFlag) //FIXME-3 does not work yet for mapcenters { BranchItem *selbi=getSelectedBranch(); @@ -2634,7 +2628,7 @@ QPointF p; if (selbi->getLMO()) p=selbi->getLMO()->getRelPos(); - saveStateChangingPart( + if (saveStateFlag) saveStateChangingPart( pi, selbi, "deleteKeepChildren ()", @@ -2693,6 +2687,7 @@ if (ti) { TreeItem *pi=ti->parent(); + //qDebug()<<"VM::deleteItem start ti="<getHeading()<<" pi="<getHeading(); QModelIndex parentIndex=index(pi); emit (layoutAboutToBeChanged() ); @@ -2704,11 +2699,19 @@ reposition(); emit (layoutChanged() ); + //qDebug()<<"VM::deleteItem end ti="<depth()>=0) return pi; } return NULL; } +void VymModel::deleteLink(Link* l) +{ + int i=xlinks.indexOf(l); + if (i>-1) xlinks_obsolete.append (xlinks.takeAt (i)); +} + void VymModel::clearItem (TreeItem *ti) { if (ti) @@ -3138,35 +3141,30 @@ } } -void VymModel::editXLink(int i) -{ - i=0; +void VymModel::editXLink(int i) +{ BranchItem *selbi=getSelectedBranch(); if (selbi) { - XLinkItem *xli=selbi->getXLinkNum(i); - if (xli) + Link *l=selbi->getXLinkNum(i)->getLink(); + if (l) { EditXLinkDialog dia; - dia.setXLink (xli); + dia.setLink (l); dia.setSelection(selbi); if (dia.exec() == QDialog::Accepted) { if (dia.useSettingsGlobal() ) { - setMapDefXLinkColor (xli->getColor() ); - setMapDefXLinkWidth (xli->getWidth() ); + setMapDefXLinkColor (l->getColor() ); + setMapDefXLinkWidth (l->getWidth() ); } - if (dia.deleteXLink()) deleteItem (xli); + if (dia.deleteXLink()) delete (l); } } } } - - - - ////////////////////////////////////////////// // Scripting ////////////////////////////////////////////// @@ -3252,7 +3250,7 @@ //s=parser.parString (ok,0); // selection t=parser.parString (ok,0); // path to map if (QDir::isRelativePath(t)) t=(tmpMapDir + "/"+t); - addMapReplaceInt(getSelectString(selbi),t); + loadMap (t,ImportReplace,false,VymMap,n); } ///////////////////////////////////////////////////////////////////// } else if (com==QString("addMapInsert")) @@ -3271,18 +3269,19 @@ t=parser.parString (ok,0); // path to map n=parser.parInt(ok,1); // position if (QDir::isRelativePath(t)) t=(tmpMapDir + "/"+t); - addMapInsertInt(t,n); + loadMap (t,ImportAdd,false,VymMap,n); } } else if (parser.parCount()==1) { t=parser.parString (ok,0); // path to map if (QDir::isRelativePath(t)) t=(tmpMapDir + "/"+t); - addMapInsertInt(t); + loadMap (t,ImportAdd,false); } else parser.setError (Aborted,"Wrong number of parameters"); ///////////////////////////////////////////////////////////////////// - } else if (com==QString("addXLink")) - { + } else if (com==QString("addXLink")) //FIXME-2 not ported yet to Link + { + /* if (parser.parCount()>1) { s=parser.parString (ok,0); // begin @@ -3308,6 +3307,7 @@ parser.setError (Aborted,"Couldn't select begin or end of xLink"); } else parser.setError (Aborted,"Need at least 2 parameters for begin and end"); + */ ///////////////////////////////////////////////////////////////////// } else if (com=="clearFlags") { @@ -4424,8 +4424,15 @@ //cout << "VM::reposition blocked="<branchCount(); i++) - rootItem->getBranchObjNum(i)->reposition(); // for positioning heading + { + bo=rootItem->getBranchObjNum(i); + if (bo) + bo->reposition(); // for positioning heading + else + qDebug()<<"VM::reposition bo=0"; + } //emitSelectionChanged(); } @@ -4763,6 +4770,20 @@ animObjList.removeAt (i); } +void VymModel::stopAllAnimation () +{ + BranchObj *bo; + int i=0; + while (istopAnimation(); + bo->requestReposition(); + i++; + } + reposition(); +} + void VymModel::sendSelection() { if (netstate!=Server) return; @@ -5269,3 +5290,8 @@ return s; } +QString VymModel::getSelectString (BranchItem *bi) +{ + return getSelectString ((TreeItem*)bi); +} +