1.1 --- a/vymmodel.cpp Wed Jul 16 10:44:44 2008 +0000
1.2 +++ b/vymmodel.cpp Wed Jul 16 10:46:14 2008 +0000
1.3 @@ -1,32 +1,122 @@
1.4 #include <QApplication>
1.5 #include <typeinfo>
1.6
1.7 +#include "vymmodel.h"
1.8 +
1.9 +#include "editxlinkdialog.h"
1.10 +#include "exports.h"
1.11 +#include "exportxhtmldialog.h"
1.12 +#include "file.h"
1.13 #include "geometry.h" // for addBBox
1.14 -#include "vymmodel.h"
1.15 -
1.16 -
1.17 +#include "mainwindow.h"
1.18 +#include "mapcenterobj.h"
1.19 +#include "misc.h"
1.20 +#include "parser.h"
1.21 +#include "selection.h"
1.22 +
1.23 +
1.24 +#include "warningdialog.h"
1.25 +#include "xml-freemind.h"
1.26 +#include "xml-vym.h"
1.27 +
1.28 +
1.29 +extern bool debug;
1.30 +extern Main *mainWindow;
1.31 extern Settings settings;
1.32 +extern QString tmpVymDir;
1.33 +
1.34 +extern TextEditor *textEditor;
1.35 +
1.36 +
1.37 +extern QString clipboardDir;
1.38 +extern QString clipboardFile;
1.39 +extern bool clipboardEmpty;
1.40 +
1.41 +extern ImageIO imageIO;
1.42 +
1.43 +extern QString vymName;
1.44 +extern QString vymVersion;
1.45 +extern QDir vymBaseDir;
1.46 +
1.47 +extern QDir lastImageDir;
1.48 +extern QDir lastFileDir;
1.49 +
1.50 +extern FlagRowObj *standardFlagsDefault;
1.51 +
1.52 +extern Settings settings;
1.53 +
1.54 +
1.55 +
1.56 +int VymModel::mapNum=0; // make instance
1.57
1.58 VymModel::VymModel()
1.59 {
1.60 // cout << "Const VymModel\n";
1.61 + init();
1.62 }
1.63
1.64
1.65 VymModel::~VymModel()
1.66 {
1.67 // cout << "Destr VymModel\n";
1.68 + autosaveTimer->stop();
1.69 + fileChangedTimer->stop();
1.70 + clear();
1.71 }
1.72
1.73 void VymModel::clear()
1.74 {
1.75 + selection.clear();
1.76 +
1.77 while (!mapCenters.isEmpty())
1.78 delete mapCenters.takeFirst();
1.79 }
1.80
1.81 void VymModel::init ()
1.82 {
1.83 - addMapCenter();
1.84 + // We should have at least one map center to start with
1.85 + // addMapCenter(); FIXME create this in MapEditor as long as model is part of that
1.86 +
1.87 + // History
1.88 + mapNum++;
1.89 + mapChanged=false;
1.90 + mapDefault=true;
1.91 + mapUnsaved=false;
1.92 +
1.93 + curStep=0;
1.94 + redosAvail=0;
1.95 + undosAvail=0;
1.96 +
1.97 + stepsTotal=settings.readNumEntry("/history/stepsTotal",100);
1.98 + undoSet.setEntry ("/history/stepsTotal",QString::number(stepsTotal));
1.99 + mainWindow->updateHistory (undoSet);
1.100 +
1.101 + // Create tmp dirs
1.102 + makeTmpDirectories();
1.103 +
1.104 + // Files
1.105 + zipped=true;
1.106 + filePath="";
1.107 + fileName=tr("unnamed");
1.108 + mapName="";
1.109 + blockReposition=false;
1.110 + blockSaveState=false;
1.111 +
1.112 + autosaveTimer=new QTimer (this);
1.113 + connect(autosaveTimer, SIGNAL(timeout()), this, SLOT(autosave()));
1.114 +
1.115 + fileChangedTimer=new QTimer (this);
1.116 + fileChangedTimer->start(3000);
1.117 + connect(fileChangedTimer, SIGNAL(timeout()), this, SLOT(fileChanged()));
1.118 +
1.119 +
1.120 + // selections
1.121 + selection.setModel (this);
1.122 + selection.unselect();
1.123 +
1.124 + // find routine
1.125 + itFind=NULL;
1.126 + EOFind=false;
1.127
1.128 // animations
1.129 animationUse=settings.readBoolEntry("/animation/use",false);
1.130 @@ -36,8 +126,36 @@
1.131 animationTimer=new QTimer (this);
1.132 connect(animationTimer, SIGNAL(timeout()), this, SLOT(animate()));
1.133
1.134 + // View - map
1.135 + defLinkColor=QColor (0,0,255);
1.136 + defXLinkColor=QColor (180,180,180);
1.137 + linkcolorhint=LinkableMapObj::DefaultColor;
1.138 + linkstyle=LinkableMapObj::PolyParabel;
1.139 + defXLinkWidth=1;
1.140 + defXLinkColor=QColor (230,230,230);
1.141 +
1.142 + hidemode=HideNone;
1.143 +
1.144 +
1.145 +
1.146 + // Network
1.147 + netstate=Offline;
1.148 +
1.149 + // Create MapCenter
1.150 + // addMapCenter(); FIXME create this in MapEditor until BO and MCO are independent of scene
1.151 +
1.152 }
1.153
1.154 +void VymModel::makeTmpDirectories()
1.155 +{
1.156 + // Create unique temporary directories
1.157 + tmpMapDir = tmpVymDir+QString("/model-%1").arg(mapNum);
1.158 + histPath = tmpMapDir+"/history";
1.159 + QDir d;
1.160 + d.mkdir (tmpMapDir);
1.161 +}
1.162 +
1.163 +
1.164 void VymModel::setMapEditor(MapEditor *me)
1.165 {
1.166 mapEditor=me;
1.167 @@ -50,76 +168,1183 @@
1.168 return mapEditor;
1.169 }
1.170
1.171 -void VymModel::setVersion (const QString &s)
1.172 +bool VymModel::isRepositionBlocked()
1.173 {
1.174 - version=s;
1.175 + return blockReposition;
1.176 }
1.177
1.178 -void VymModel::setAuthor (const QString &s)
1.179 +void VymModel::updateActions() // FIXME maybe don't update if blockReposition is set
1.180 {
1.181 - author=s;
1.182 + // Tell mainwindow to update states of actions
1.183 + mainWindow->updateActions();
1.184 }
1.185
1.186 -QString VymModel::getAuthor()
1.187 +
1.188 +
1.189 +QString VymModel::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPointF &offset, LinkableMapObj *saveSel)
1.190 {
1.191 - return author;
1.192 + // tmpdir temporary directory to which data will be written
1.193 + // prefix mapname, which will be appended to images etc.
1.194 + // writeflags Only write flags for "real" save of map, not undo
1.195 + // offset offset of bbox of whole map in scene.
1.196 + // Needed for XML export
1.197 +
1.198 + // Save Header
1.199 + QString ls;
1.200 + switch (linkstyle)
1.201 + {
1.202 + case LinkableMapObj::Line:
1.203 + ls="StyleLine";
1.204 + break;
1.205 + case LinkableMapObj::Parabel:
1.206 + ls="StyleParabel";
1.207 + break;
1.208 + case LinkableMapObj::PolyLine:
1.209 + ls="StylePolyLine";
1.210 + break;
1.211 + default:
1.212 + ls="StylePolyParabel";
1.213 + break;
1.214 + }
1.215 +
1.216 + QString s="<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE vymmap>\n";
1.217 + QString colhint="";
1.218 + if (linkcolorhint==LinkableMapObj::HeadingColor)
1.219 + colhint=attribut("linkColorHint","HeadingColor");
1.220 +
1.221 + QString mapAttr=attribut("version",vymVersion);
1.222 + if (!saveSel)
1.223 + mapAttr+= attribut("author",author) +
1.224 + attribut("comment",comment) +
1.225 + attribut("date",getDate()) +
1.226 + attribut("backgroundColor", mapScene->backgroundBrush().color().name() ) +
1.227 + attribut("selectionColor", selection.getColor().name() ) +
1.228 + attribut("linkStyle", ls ) +
1.229 + attribut("linkColor", defLinkColor.name() ) +
1.230 + attribut("defXLinkColor", defXLinkColor.name() ) +
1.231 + attribut("defXLinkWidth", QString().setNum(defXLinkWidth,10) ) +
1.232 + colhint;
1.233 + s+=beginElement("vymmap",mapAttr);
1.234 + incIndent();
1.235 +
1.236 + // Find the used flags while traversing the tree
1.237 + standardFlagsDefault->resetUsedCounter();
1.238 +
1.239 + // Reset the counters before saving
1.240 + // TODO constr. of FIO creates lots of objects, better do this in some other way...
1.241 + FloatImageObj (mapScene).resetSaveCounter();
1.242 +
1.243 + // Build xml recursivly
1.244 + if (!saveSel || typeid (*saveSel) == typeid (MapCenterObj))
1.245 + // Save complete map, if saveSel not set
1.246 + s+=saveToDir(tmpdir,prefix,writeflags,offset);
1.247 + else
1.248 + {
1.249 + if ( typeid(*saveSel) == typeid(BranchObj) )
1.250 + // Save Subtree
1.251 + s+=((BranchObj*)(saveSel))->saveToDir(tmpdir,prefix,offset);
1.252 + else if ( typeid(*saveSel) == typeid(FloatImageObj) )
1.253 + // Save image
1.254 + s+=((FloatImageObj*)(saveSel))->saveToDir(tmpdir,prefix);
1.255 + }
1.256 +
1.257 + // Save local settings
1.258 + s+=settings.getDataXML (destPath);
1.259 +
1.260 + // Save selection
1.261 + if (!selection.isEmpty() && !saveSel )
1.262 + s+=valueElement("select",selection.getSelectString());
1.263 +
1.264 + decIndent();
1.265 + s+=endElement("vymmap");
1.266 +
1.267 + if (writeflags)
1.268 + standardFlagsDefault->saveToDir (tmpdir+"/flags/","",writeflags);
1.269 + return s;
1.270 }
1.271
1.272 -void VymModel::setComment (const QString &s)
1.273 +void VymModel::setFilePath(QString fpath, QString destname)
1.274 {
1.275 - comment=s;
1.276 + if (fpath.isEmpty() || fpath=="")
1.277 + {
1.278 + filePath="";
1.279 + fileName="";
1.280 + destPath="";
1.281 + } else
1.282 + {
1.283 + filePath=fpath; // becomes absolute path
1.284 + fileName=fpath; // gets stripped of path
1.285 + destPath=destname; // needed for vymlinks and during load to reset fileChangedTime
1.286 +
1.287 + // If fpath is not an absolute path, complete it
1.288 + filePath=QDir(fpath).absPath();
1.289 + fileDir=filePath.left (1+filePath.findRev ("/"));
1.290 +
1.291 + // Set short name, too. Search from behind:
1.292 + int i=fileName.findRev("/");
1.293 + if (i>=0) fileName=fileName.remove (0,i+1);
1.294 +
1.295 + // Forget the .vym (or .xml) for name of map
1.296 + mapName=fileName.left(fileName.findRev(".",-1,true) );
1.297 + }
1.298 }
1.299
1.300 -QString VymModel::getComment ()
1.301 +void VymModel::setFilePath(QString fpath)
1.302 {
1.303 - return comment;
1.304 + setFilePath (fpath,fpath);
1.305 }
1.306
1.307 -QString VymModel::getDate ()
1.308 +QString VymModel::getFilePath()
1.309 {
1.310 - return QDate::currentDate().toString ("yyyy-MM-dd");
1.311 + return filePath;
1.312 }
1.313
1.314 -void VymModel::setScene (QGraphicsScene *s)
1.315 +QString VymModel::getFileName()
1.316 {
1.317 - mapScene=s;
1.318 - init(); // Here we have a mapScene set,
1.319 - // which is (still) needed to create MapCenters
1.320 + return fileName;
1.321 }
1.322
1.323 +QString VymModel::getMapName()
1.324 +{
1.325 + return mapName;
1.326 +}
1.327 +
1.328 +QString VymModel::getDestPath()
1.329 +{
1.330 + return destPath;
1.331 +}
1.332 +
1.333 +ErrorCode VymModel::load (QString fname, const LoadMode &lmode, const FileType &ftype)
1.334 +{
1.335 + ErrorCode err=success;
1.336 +
1.337 + parseBaseHandler *handler;
1.338 + fileType=ftype;
1.339 + switch (fileType)
1.340 + {
1.341 + case VymMap: handler=new parseVYMHandler; break;
1.342 + case FreemindMap : handler=new parseFreemindHandler; break;
1.343 + default:
1.344 + QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1.345 + "Unknown FileType in VymModel::load()");
1.346 + return aborted;
1.347 + }
1.348 + if (lmode==NewMap)
1.349 + {
1.350 + selection.clear();
1.351 + // FIXME not needed??? model->setMapEditor(this);
1.352 + // (map state is set later at end of load...)
1.353 + } else
1.354 + {
1.355 + BranchObj *bo=selection.getBranch();
1.356 + if (!bo) return aborted;
1.357 + if (lmode==ImportAdd)
1.358 + saveStateChangingPart(
1.359 + bo,
1.360 + bo,
1.361 + QString("addMapInsert (%1)").arg(fname),
1.362 + QString("Add map %1 to %2").arg(fname).arg(getObjectName(bo)));
1.363 + else
1.364 + saveStateChangingPart(
1.365 + bo,
1.366 + bo,
1.367 + QString("addMapReplace(%1)").arg(fname),
1.368 + QString("Add map %1 to %2").arg(fname).arg(getObjectName(bo)));
1.369 + }
1.370 +
1.371 +
1.372 + // Create temporary directory for packing
1.373 + bool ok;
1.374 + QString tmpZipDir=makeTmpDir (ok,"vym-pack");
1.375 + if (!ok)
1.376 + {
1.377 + QMessageBox::critical( 0, tr( "Critical Load Error" ),
1.378 + tr("Couldn't create temporary directory before load\n"));
1.379 + return aborted;
1.380 + }
1.381 +
1.382 + // Try to unzip file
1.383 + err=unzipDir (tmpZipDir,fname);
1.384 + QString xmlfile;
1.385 + if (err==nozip)
1.386 + {
1.387 + xmlfile=fname;
1.388 + zipped=false;
1.389 + } else
1.390 + {
1.391 + zipped=true;
1.392 +
1.393 + // Look for mapname.xml
1.394 + xmlfile= fname.left(fname.findRev(".",-1,true));
1.395 + xmlfile=xmlfile.section( '/', -1 );
1.396 + QFile mfile( tmpZipDir + "/" + xmlfile + ".xml");
1.397 + if (!mfile.exists() )
1.398 + {
1.399 + // mapname.xml does not exist, well,
1.400 + // maybe someone renamed the mapname.vym file...
1.401 + // Try to find any .xml in the toplevel
1.402 + // directory of the .vym file
1.403 + QStringList flist=QDir (tmpZipDir).entryList("*.xml");
1.404 + if (flist.count()==1)
1.405 + {
1.406 + // Only one entry, take this one
1.407 + xmlfile=tmpZipDir + "/"+flist.first();
1.408 + } else
1.409 + {
1.410 + for ( QStringList::Iterator it = flist.begin(); it != flist.end(); ++it )
1.411 + *it=tmpZipDir + "/" + *it;
1.412 + // TODO Multiple entries, load all (but only the first one into this ME)
1.413 + //mainWindow->fileLoadFromTmp (flist);
1.414 + //returnCode=1; // Silently forget this attempt to load
1.415 + qWarning ("MainWindow::load (fn) multimap found...");
1.416 + }
1.417 +
1.418 + if (flist.isEmpty() )
1.419 + {
1.420 + QMessageBox::critical( 0, tr( "Critical Load Error" ),
1.421 + tr("Couldn't find a map (*.xml) in .vym archive.\n"));
1.422 + err=aborted;
1.423 + }
1.424 + } //file doesn't exist
1.425 + else
1.426 + xmlfile=mfile.name();
1.427 + }
1.428 +
1.429 + QFile file( xmlfile);
1.430 +
1.431 + // I am paranoid: file should exist anyway
1.432 + // according to check in mainwindow.
1.433 + if (!file.exists() )
1.434 + {
1.435 + QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1.436 + tr(QString("Couldn't open map %1").arg(file.name())));
1.437 + err=aborted;
1.438 + } else
1.439 + {
1.440 + bool blockSaveStateOrg=blockSaveState;
1.441 + blockReposition=true;
1.442 + blockSaveState=true;
1.443 + QXmlInputSource source( file);
1.444 + QXmlSimpleReader reader;
1.445 + reader.setContentHandler( handler );
1.446 + reader.setErrorHandler( handler );
1.447 + handler->setModel ( this);
1.448 +
1.449 +
1.450 + // We need to set the tmpDir in order to load files with rel. path
1.451 + QString tmpdir;
1.452 + if (zipped)
1.453 + tmpdir=tmpZipDir;
1.454 + else
1.455 + tmpdir=fname.left(fname.findRev("/",-1));
1.456 + handler->setTmpDir (tmpdir);
1.457 + handler->setInputFile (file.name());
1.458 + handler->setLoadMode (lmode);
1.459 + bool ok = reader.parse( source );
1.460 + blockReposition=false;
1.461 + blockSaveState=blockSaveStateOrg;
1.462 + file.close();
1.463 + if ( ok )
1.464 + {
1.465 + reposition(); // FIXME reposition the view instead...
1.466 + selection.update();
1.467 + if (lmode==NewMap)
1.468 + {
1.469 + mapDefault=false;
1.470 + mapChanged=false;
1.471 + mapUnsaved=false;
1.472 + autosaveTimer->stop();
1.473 + }
1.474 +
1.475 + // Reset timestamp to check for later updates of file
1.476 + fileChangedTime=QFileInfo (destPath).lastModified();
1.477 + } else
1.478 + {
1.479 + QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1.480 + tr( handler->errorProtocol() ) );
1.481 + // returnCode=1;
1.482 + // Still return "success": the map maybe at least
1.483 + // partially read by the parser
1.484 + }
1.485 + }
1.486 +
1.487 + // Delete tmpZipDir
1.488 + removeDir (QDir(tmpZipDir));
1.489 +
1.490 + updateActions();
1.491 +
1.492 + return err;
1.493 +}
1.494 +
1.495 +ErrorCode VymModel::save (const SaveMode &savemode)
1.496 +{
1.497 + QString tmpZipDir;
1.498 + QString mapFileName;
1.499 + QString safeFilePath;
1.500 +
1.501 + ErrorCode err=success;
1.502 +
1.503 + if (zipped)
1.504 + // save as .xml
1.505 + mapFileName=mapName+".xml";
1.506 + else
1.507 + // use name given by user, even if he chooses .doc
1.508 + mapFileName=fileName;
1.509 +
1.510 + // Look, if we should zip the data:
1.511 + if (!zipped)
1.512 + {
1.513 + QMessageBox mb( vymName,
1.514 + tr("The map %1\ndid not use the compressed "
1.515 + "vym file format.\nWriting it uncompressed will also write images \n"
1.516 + "and flags and thus may overwrite files in the "
1.517 + "given directory\n\nDo you want to write the map").arg(filePath),
1.518 + QMessageBox::Warning,
1.519 + QMessageBox::Yes | QMessageBox::Default,
1.520 + QMessageBox::No ,
1.521 + QMessageBox::Cancel | QMessageBox::Escape);
1.522 + mb.setButtonText( QMessageBox::Yes, tr("compressed (vym default)") );
1.523 + mb.setButtonText( QMessageBox::No, tr("uncompressed") );
1.524 + mb.setButtonText( QMessageBox::Cancel, tr("Cancel"));
1.525 + switch( mb.exec() )
1.526 + {
1.527 + case QMessageBox::Yes:
1.528 + // save compressed (default file format)
1.529 + zipped=true;
1.530 + break;
1.531 + case QMessageBox::No:
1.532 + // save uncompressed
1.533 + zipped=false;
1.534 + break;
1.535 + case QMessageBox::Cancel:
1.536 + // do nothing
1.537 + return aborted;
1.538 + break;
1.539 + }
1.540 + }
1.541 +
1.542 + // First backup existing file, we
1.543 + // don't want to add to old zip archives
1.544 + QFile f(destPath);
1.545 + if (f.exists())
1.546 + {
1.547 + if ( settings.value ("/mapeditor/writeBackupFile").toBool())
1.548 + {
1.549 + QString backupFileName(destPath + "~");
1.550 + QFile backupFile(backupFileName);
1.551 + if (backupFile.exists() && !backupFile.remove())
1.552 + {
1.553 + QMessageBox::warning(0, tr("Save Error"),
1.554 + tr("%1\ncould not be removed before saving").arg(backupFileName));
1.555 + }
1.556 + else if (!f.rename(backupFileName))
1.557 + {
1.558 + QMessageBox::warning(0, tr("Save Error"),
1.559 + tr("%1\ncould not be renamed before saving").arg(destPath));
1.560 + }
1.561 + }
1.562 + }
1.563 +
1.564 + if (zipped)
1.565 + {
1.566 + // Create temporary directory for packing
1.567 + bool ok;
1.568 + tmpZipDir=makeTmpDir (ok,"vym-zip");
1.569 + if (!ok)
1.570 + {
1.571 + QMessageBox::critical( 0, tr( "Critical Load Error" ),
1.572 + tr("Couldn't create temporary directory before save\n"));
1.573 + return aborted;
1.574 + }
1.575 +
1.576 + safeFilePath=filePath;
1.577 + setFilePath (tmpZipDir+"/"+ mapName+ ".xml", safeFilePath);
1.578 + } // zipped
1.579 +
1.580 + // Create mapName and fileDir
1.581 + makeSubDirs (fileDir);
1.582 +
1.583 + QString saveFile;
1.584 + if (savemode==CompleteMap || selection.isEmpty())
1.585 + {
1.586 + // Save complete map
1.587 + saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),NULL);
1.588 + mapChanged=false;
1.589 + mapUnsaved=false;
1.590 + autosaveTimer->stop();
1.591 + }
1.592 + else
1.593 + {
1.594 + // Save part of map
1.595 + if (selection.type()==Selection::FloatImage)
1.596 + saveFloatImage();
1.597 + else
1.598 + saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),selection.getBranch());
1.599 + // TODO take care of multiselections
1.600 + }
1.601 +
1.602 + if (!saveStringToDisk(fileDir+mapFileName,saveFile))
1.603 + {
1.604 + err=aborted;
1.605 + qWarning ("ME::saveStringToDisk failed!");
1.606 + }
1.607 +
1.608 + if (zipped)
1.609 + {
1.610 + // zip
1.611 + if (err==success) err=zipDir (tmpZipDir,destPath);
1.612 +
1.613 + // Delete tmpDir
1.614 + removeDir (QDir(tmpZipDir));
1.615 +
1.616 + // Restore original filepath outside of tmp zip dir
1.617 + setFilePath (safeFilePath);
1.618 + }
1.619 +
1.620 + updateActions();
1.621 + fileChangedTime=QFileInfo (destPath).lastModified();
1.622 + return err;
1.623 +}
1.624 +
1.625 +void VymModel::addMapReplaceInt(const QString &undoSel, const QString &path)
1.626 +{
1.627 + QString pathDir=path.left(path.findRev("/"));
1.628 + QDir d(pathDir);
1.629 + QFile file (path);
1.630 +
1.631 + if (d.exists() )
1.632 + {
1.633 + // We need to parse saved XML data
1.634 + parseVYMHandler handler;
1.635 + QXmlInputSource source( file);
1.636 + QXmlSimpleReader reader;
1.637 + reader.setContentHandler( &handler );
1.638 + reader.setErrorHandler( &handler );
1.639 + handler.setModel ( this);
1.640 + handler.setTmpDir ( pathDir ); // needed to load files with rel. path
1.641 + if (undoSel.isEmpty())
1.642 + {
1.643 + unselect();
1.644 + clear();
1.645 + handler.setLoadMode (NewMap);
1.646 + } else
1.647 + {
1.648 + select (undoSel);
1.649 + handler.setLoadMode (ImportReplace);
1.650 + }
1.651 + blockReposition=true;
1.652 + bool ok = reader.parse( source );
1.653 + blockReposition=false;
1.654 + if (! ok )
1.655 + {
1.656 + // This should never ever happen
1.657 + QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
1.658 + handler.errorProtocol());
1.659 + }
1.660 + } else
1.661 + QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
1.662 +}
1.663 +
1.664 +void VymModel::addMapInsertInt (const QString &path, int pos)
1.665 +{
1.666 + BranchObj *sel=selection.getBranch();
1.667 + if (sel)
1.668 + {
1.669 + QString pathDir=path.left(path.findRev("/"));
1.670 + QDir d(pathDir);
1.671 + QFile file (path);
1.672 +
1.673 + if (d.exists() )
1.674 + {
1.675 + // We need to parse saved XML data
1.676 + parseVYMHandler handler;
1.677 + QXmlInputSource source( file);
1.678 + QXmlSimpleReader reader;
1.679 + reader.setContentHandler( &handler );
1.680 + reader.setErrorHandler( &handler );
1.681 + handler.setModel (this);
1.682 + handler.setTmpDir ( pathDir ); // needed to load files with rel. path
1.683 + handler.setLoadMode (ImportAdd);
1.684 + blockReposition=true;
1.685 + bool ok = reader.parse( source );
1.686 + blockReposition=false;
1.687 + if (! ok )
1.688 + {
1.689 + // This should never ever happen
1.690 + QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
1.691 + handler.errorProtocol());
1.692 + }
1.693 + if (sel->getDepth()>0)
1.694 + sel->getLastBranch()->linkTo (sel,pos);
1.695 + } else
1.696 + QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
1.697 + }
1.698 +}
1.699 +
1.700 +FloatImageObj* VymModel::loadFloatImageInt (QString fn)
1.701 +{
1.702 + BranchObj *bo=selection.getBranch();
1.703 + if (bo)
1.704 + {
1.705 + FloatImageObj *fio;
1.706 + bo->addFloatImage();
1.707 + fio=bo->getLastFloatImage();
1.708 + fio->load(fn);
1.709 + reposition();
1.710 + // FIXME needed? scene()->update();
1.711 + return fio;
1.712 + }
1.713 + return NULL;
1.714 +}
1.715 +
1.716 +void VymModel::loadFloatImage ()
1.717 +{
1.718 + BranchObj *bo=selection.getBranch();
1.719 + if (bo)
1.720 + {
1.721 +
1.722 + Q3FileDialog *fd=new Q3FileDialog( NULL);
1.723 + fd->setMode (Q3FileDialog::ExistingFiles);
1.724 + fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
1.725 + ImagePreview *p =new ImagePreview (fd);
1.726 + fd->setContentsPreviewEnabled( TRUE );
1.727 + fd->setContentsPreview( p, p );
1.728 + fd->setPreviewMode( Q3FileDialog::Contents );
1.729 + fd->setCaption(vymName+" - " +tr("Load image"));
1.730 + fd->setDir (lastImageDir);
1.731 + fd->show();
1.732 +
1.733 + if ( fd->exec() == QDialog::Accepted )
1.734 + {
1.735 + // TODO loadFIO in QT4 use: lastImageDir=fd->directory();
1.736 + lastImageDir=QDir (fd->dirPath());
1.737 + QString s;
1.738 + FloatImageObj *fio;
1.739 + for (int j=0; j<fd->selectedFiles().count(); j++)
1.740 + {
1.741 + s=fd->selectedFiles().at(j);
1.742 + fio=loadFloatImageInt (s);
1.743 + if (fio)
1.744 + saveState(
1.745 + (LinkableMapObj*)fio,
1.746 + "delete ()",
1.747 + bo,
1.748 + QString ("loadImage (%1)").arg(s ),
1.749 + QString("Add image %1 to %2").arg(s).arg(getObjectName(bo))
1.750 + );
1.751 + else
1.752 + // TODO loadFIO error handling
1.753 + qWarning ("Failed to load "+s);
1.754 + }
1.755 + }
1.756 + delete (p);
1.757 + delete (fd);
1.758 + }
1.759 +}
1.760 +
1.761 +void VymModel::saveFloatImageInt (FloatImageObj *fio, const QString &type, const QString &fn)
1.762 +{
1.763 + fio->save (fn,type);
1.764 +}
1.765 +
1.766 +void VymModel::saveFloatImage ()
1.767 +{
1.768 + FloatImageObj *fio=selection.getFloatImage();
1.769 + if (fio)
1.770 + {
1.771 + QFileDialog *fd=new QFileDialog( NULL);
1.772 + fd->setFilters (imageIO.getFilters());
1.773 + fd->setCaption(vymName+" - " +tr("Save image"));
1.774 + fd->setFileMode( QFileDialog::AnyFile );
1.775 + fd->setDirectory (lastImageDir);
1.776 +// fd->setSelection (fio->getOriginalFilename());
1.777 + fd->show();
1.778 +
1.779 + QString fn;
1.780 + if ( fd->exec() == QDialog::Accepted && fd->selectedFiles().count()==1)
1.781 + {
1.782 + fn=fd->selectedFiles().at(0);
1.783 + if (QFile (fn).exists() )
1.784 + {
1.785 + QMessageBox mb( vymName,
1.786 + tr("The file %1 exists already.\n"
1.787 + "Do you want to overwrite it?").arg(fn),
1.788 + QMessageBox::Warning,
1.789 + QMessageBox::Yes | QMessageBox::Default,
1.790 + QMessageBox::Cancel | QMessageBox::Escape,
1.791 + QMessageBox::NoButton );
1.792 +
1.793 + mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
1.794 + mb.setButtonText( QMessageBox::No, tr("Cancel"));
1.795 + switch( mb.exec() )
1.796 + {
1.797 + case QMessageBox::Yes:
1.798 + // save
1.799 + break;
1.800 + case QMessageBox::Cancel:
1.801 + // do nothing
1.802 + delete (fd);
1.803 + return;
1.804 + break;
1.805 + }
1.806 + }
1.807 + saveFloatImageInt (fio,fd->selectedFilter(),fn );
1.808 + }
1.809 + delete (fd);
1.810 + }
1.811 +}
1.812 +
1.813 +
1.814 +void VymModel::importDirInt(BranchObj *dst, QDir d)
1.815 +{
1.816 + BranchObj *bo=selection.getBranch();
1.817 + if (bo)
1.818 + {
1.819 + // Traverse directories
1.820 + d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
1.821 + QFileInfoList list = d.entryInfoList();
1.822 + QFileInfo fi;
1.823 +
1.824 + for (int i = 0; i < list.size(); ++i)
1.825 + {
1.826 + fi=list.at(i);
1.827 + if (fi.fileName() != "." && fi.fileName() != ".." )
1.828 + {
1.829 + dst->addBranch();
1.830 + bo=dst->getLastBranch();
1.831 + bo->setHeading (fi.fileName() );
1.832 + bo->setColor (QColor("blue"));
1.833 + bo->toggleScroll();
1.834 + if ( !d.cd(fi.fileName()) )
1.835 + QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory %1").arg(fi.fileName()));
1.836 + else
1.837 + {
1.838 + // Recursively add subdirs
1.839 + importDirInt (bo,d);
1.840 + d.cdUp();
1.841 + }
1.842 + }
1.843 + }
1.844 + // Traverse files
1.845 + d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
1.846 + list = d.entryInfoList();
1.847 +
1.848 + for (int i = 0; i < list.size(); ++i)
1.849 + {
1.850 + fi=list.at(i);
1.851 + dst->addBranch();
1.852 + bo=dst->getLastBranch();
1.853 + bo->setHeading (fi.fileName() );
1.854 + bo->setColor (QColor("black"));
1.855 + if (fi.fileName().right(4) == ".vym" )
1.856 + bo->setVymLink (fi.filePath());
1.857 + }
1.858 + }
1.859 +}
1.860 +
1.861 +void VymModel::importDirInt (const QString &s)
1.862 +{
1.863 + BranchObj *bo=selection.getBranch();
1.864 + if (bo)
1.865 + {
1.866 + saveStateChangingPart (bo,bo,QString ("importDir (\"%1\")").arg(s),QString("Import directory structure from %1").arg(s));
1.867 +
1.868 + QDir d(s);
1.869 + importDirInt (bo,d);
1.870 + }
1.871 +}
1.872 +
1.873 +void VymModel::importDir()
1.874 +{
1.875 + BranchObj *bo=selection.getBranch();
1.876 + if (bo)
1.877 + {
1.878 + QStringList filters;
1.879 + filters <<"VYM map (*.vym)";
1.880 + QFileDialog *fd=new QFileDialog( NULL,vymName+ " - " +tr("Choose directory structure to import"));
1.881 + fd->setMode (QFileDialog::DirectoryOnly);
1.882 + fd->setFilters (filters);
1.883 + fd->setCaption(vymName+" - " +tr("Choose directory structure to import"));
1.884 + fd->show();
1.885 +
1.886 + QString fn;
1.887 + if ( fd->exec() == QDialog::Accepted )
1.888 + {
1.889 + importDirInt (fd->selectedFile() );
1.890 + reposition();
1.891 + //FIXME needed? scene()->update();
1.892 + }
1.893 + }
1.894 +}
1.895 +
1.896 +
1.897 +void VymModel::autosave()
1.898 +{
1.899 + QDateTime now=QDateTime().currentDateTime();
1.900 +
1.901 + // Disable autosave, while we have gone back in history
1.902 + int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1.903 + if (redosAvail>0) return;
1.904 +
1.905 + // Also disable autosave for new map without filename
1.906 + if (filePath.isEmpty()) return;
1.907 +
1.908 +
1.909 + if (mapUnsaved &&mapChanged && settings.value ("/autosave/use",true).toBool() )
1.910 + {
1.911 + if (QFileInfo(filePath).lastModified()<=fileChangedTime)
1.912 + mainWindow->fileSave (this);
1.913 + else
1.914 + if (debug)
1.915 + cout <<" ME::autosave rejected, file on disk is newer than last save.\n";
1.916 +
1.917 + }
1.918 +}
1.919 +
1.920 +void VymModel::fileChanged()
1.921 +{
1.922 + // Check if file on disk has changed meanwhile
1.923 + if (!filePath.isEmpty())
1.924 + {
1.925 + QDateTime tmod=QFileInfo (filePath).lastModified();
1.926 + if (tmod>fileChangedTime)
1.927 + {
1.928 + // FIXME switch to current mapeditor and finish lineedits...
1.929 + QMessageBox mb( vymName,
1.930 + tr("The file of the map on disk has changed:\n\n"
1.931 + " %1\n\nDo you want to reload that map with the new file?").arg(filePath),
1.932 + QMessageBox::Question,
1.933 + QMessageBox::Yes ,
1.934 + QMessageBox::Cancel | QMessageBox::Default,
1.935 + QMessageBox::NoButton );
1.936 +
1.937 + mb.setButtonText( QMessageBox::Yes, tr("Reload"));
1.938 + mb.setButtonText( QMessageBox::No, tr("Ignore"));
1.939 + switch( mb.exec() )
1.940 + {
1.941 + case QMessageBox::Yes:
1.942 + // Reload map
1.943 + load (filePath,NewMap,fileType);
1.944 + case QMessageBox::Cancel:
1.945 + fileChangedTime=tmod; // allow autosave to overwrite newer file!
1.946 + }
1.947 + }
1.948 + }
1.949 +}
1.950 +
1.951 +bool VymModel::isDefault()
1.952 +{
1.953 + return mapDefault;
1.954 +}
1.955 +
1.956 +void VymModel::makeDefault()
1.957 +{
1.958 + mapChanged=false;
1.959 + mapDefault=true;
1.960 +}
1.961 +
1.962 +bool VymModel::hasChanged()
1.963 +{
1.964 + return mapChanged;
1.965 +}
1.966 +
1.967 +void VymModel::setChanged()
1.968 +{
1.969 + if (!mapChanged)
1.970 + autosaveTimer->start(settings.value("/autosave/ms/",300000).toInt());
1.971 + mapChanged=true;
1.972 + mapDefault=false;
1.973 + mapUnsaved=true;
1.974 + findReset();
1.975 +}
1.976 +
1.977 +
1.978 +QString VymModel::getObjectName (const LinkableMapObj *lmo)
1.979 +{
1.980 + QString s;
1.981 + if (!lmo) return QString("Error: NULL has no name!");
1.982 +
1.983 + if ((typeid(*lmo) == typeid(BranchObj) ||
1.984 + typeid(*lmo) == typeid(MapCenterObj)))
1.985 + {
1.986 +
1.987 + s=(((BranchObj*)lmo)->getHeading());
1.988 + if (s=="") s="unnamed";
1.989 + return QString("branch (%1)").arg(s);
1.990 + }
1.991 + if ((typeid(*lmo) == typeid(FloatImageObj) ))
1.992 + return QString ("floatimage [%1]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
1.993 + return QString("Unknown type has no name!");
1.994 +}
1.995 +
1.996 +void VymModel::redo()
1.997 +{
1.998 + // Can we undo at all?
1.999 + if (redosAvail<1) return;
1.1000 +
1.1001 + bool blockSaveStateOrg=blockSaveState;
1.1002 + blockSaveState=true;
1.1003 +
1.1004 + redosAvail--;
1.1005 +
1.1006 + if (undosAvail<stepsTotal) undosAvail++;
1.1007 + curStep++;
1.1008 + if (curStep>stepsTotal) curStep=1;
1.1009 + QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1.1010 + QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1.1011 + QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1.1012 + QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1.1013 + QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1.1014 + QString version=undoSet.readEntry ("/history/version");
1.1015 +
1.1016 + /* TODO Maybe check for version, if we save the history
1.1017 + if (!checkVersion(version))
1.1018 + QMessageBox::warning(0,tr("Warning"),
1.1019 + tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1.1020 + */
1.1021 +
1.1022 + // Find out current undo directory
1.1023 + QString bakMapDir(QString(tmpMapDir+"/undo-%1").arg(curStep));
1.1024 +
1.1025 + if (debug)
1.1026 + {
1.1027 + cout << "VymModel::redo() begin\n";
1.1028 + cout << " undosAvail="<<undosAvail<<endl;
1.1029 + cout << " redosAvail="<<redosAvail<<endl;
1.1030 + cout << " curStep="<<curStep<<endl;
1.1031 + cout << " ---------------------------"<<endl;
1.1032 + cout << " comment="<<comment.toStdString()<<endl;
1.1033 + cout << " undoCom="<<undoCommand.toStdString()<<endl;
1.1034 + cout << " undoSel="<<undoSelection.toStdString()<<endl;
1.1035 + cout << " redoCom="<<redoCommand.toStdString()<<endl;
1.1036 + cout << " redoSel="<<redoSelection.toStdString()<<endl;
1.1037 + cout << " ---------------------------"<<endl<<endl;
1.1038 + }
1.1039 +
1.1040 + // select object before redo
1.1041 + if (!redoSelection.isEmpty())
1.1042 + select (redoSelection);
1.1043 +
1.1044 +
1.1045 + parseAtom (redoCommand);
1.1046 + reposition();
1.1047 +
1.1048 + blockSaveState=blockSaveStateOrg;
1.1049 +
1.1050 + undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1.1051 + undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1.1052 + undoSet.setEntry ("/history/curStep",QString::number(curStep));
1.1053 + undoSet.writeSettings(histPath);
1.1054 +
1.1055 + mainWindow->updateHistory (undoSet);
1.1056 + updateActions();
1.1057 +
1.1058 + /* TODO remove testing
1.1059 + cout << "ME::redo() end\n";
1.1060 + cout << " undosAvail="<<undosAvail<<endl;
1.1061 + cout << " redosAvail="<<redosAvail<<endl;
1.1062 + cout << " curStep="<<curStep<<endl;
1.1063 + cout << " ---------------------------"<<endl<<endl;
1.1064 + */
1.1065 +
1.1066 +
1.1067 +}
1.1068 +
1.1069 +bool VymModel::isRedoAvailable()
1.1070 +{
1.1071 + if (undoSet.readNumEntry("/history/redosAvail",0)>0)
1.1072 + return true;
1.1073 + else
1.1074 + return false;
1.1075 +}
1.1076 +
1.1077 +void VymModel::undo()
1.1078 +{
1.1079 + // Can we undo at all?
1.1080 + if (undosAvail<1) return;
1.1081 +
1.1082 + mainWindow->statusMessage (tr("Autosave disabled during undo."));
1.1083 +
1.1084 + bool blockSaveStateOrg=blockSaveState;
1.1085 + blockSaveState=true;
1.1086 +
1.1087 + QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1.1088 + QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1.1089 + QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1.1090 + QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1.1091 + QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1.1092 + QString version=undoSet.readEntry ("/history/version");
1.1093 +
1.1094 + /* TODO Maybe check for version, if we save the history
1.1095 + if (!checkVersion(version))
1.1096 + QMessageBox::warning(0,tr("Warning"),
1.1097 + tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1.1098 + */
1.1099 +
1.1100 + // Find out current undo directory
1.1101 + QString bakMapDir(QString(tmpMapDir+"/undo-%1").arg(curStep));
1.1102 +
1.1103 + // select object before undo
1.1104 + if (!undoSelection.isEmpty())
1.1105 + select (undoSelection);
1.1106 +
1.1107 + if (debug)
1.1108 + {
1.1109 + cout << "VymModel::undo() begin\n";
1.1110 + cout << " undosAvail="<<undosAvail<<endl;
1.1111 + cout << " redosAvail="<<redosAvail<<endl;
1.1112 + cout << " curStep="<<curStep<<endl;
1.1113 + cout << " ---------------------------"<<endl;
1.1114 + cout << " comment="<<comment.toStdString()<<endl;
1.1115 + cout << " undoCom="<<undoCommand.toStdString()<<endl;
1.1116 + cout << " undoSel="<<undoSelection.toStdString()<<endl;
1.1117 + cout << " redoCom="<<redoCommand.toStdString()<<endl;
1.1118 + cout << " redoSel="<<redoSelection.toStdString()<<endl;
1.1119 + cout << " ---------------------------"<<endl<<endl;
1.1120 + }
1.1121 + parseAtom (undoCommand);
1.1122 + reposition();
1.1123 +
1.1124 + undosAvail--;
1.1125 + curStep--;
1.1126 + if (curStep<1) curStep=stepsTotal;
1.1127 +
1.1128 + redosAvail++;
1.1129 +
1.1130 + blockSaveState=blockSaveStateOrg;
1.1131 +/* TODO remove testing
1.1132 + cout << "VymModel::undo() end\n";
1.1133 + cout << " undosAvail="<<undosAvail<<endl;
1.1134 + cout << " redosAvail="<<redosAvail<<endl;
1.1135 + cout << " curStep="<<curStep<<endl;
1.1136 + cout << " ---------------------------"<<endl<<endl;
1.1137 +*/
1.1138 +
1.1139 + undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1.1140 + undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1.1141 + undoSet.setEntry ("/history/curStep",QString::number(curStep));
1.1142 + undoSet.writeSettings(histPath);
1.1143 +
1.1144 + mainWindow->updateHistory (undoSet);
1.1145 + updateActions();
1.1146 + selection.update();
1.1147 + ensureSelectionVisible();
1.1148 +}
1.1149 +
1.1150 +bool VymModel::isUndoAvailable()
1.1151 +{
1.1152 + if (undoSet.readNumEntry("/history/undosAvail",0)>0)
1.1153 + return true;
1.1154 + else
1.1155 + return false;
1.1156 +}
1.1157 +
1.1158 +void VymModel::gotoHistoryStep (int i)
1.1159 +{
1.1160 + // Restore variables
1.1161 + int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1.1162 + int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1.1163 +
1.1164 + if (i<0) i=undosAvail+redosAvail;
1.1165 +
1.1166 + // Clicking above current step makes us undo things
1.1167 + if (i<undosAvail)
1.1168 + {
1.1169 + for (int j=0; j<undosAvail-i; j++) undo();
1.1170 + return;
1.1171 + }
1.1172 + // Clicking below current step makes us redo things
1.1173 + if (i>undosAvail)
1.1174 + for (int j=undosAvail; j<i; j++)
1.1175 + {
1.1176 + if (debug) cout << "VymModel::gotoHistoryStep redo "<<j<<"/"<<undosAvail<<" i="<<i<<endl;
1.1177 + redo();
1.1178 + }
1.1179 +
1.1180 + // And ignore clicking the current row ;-)
1.1181 +}
1.1182 +
1.1183 +
1.1184 +QString VymModel::getHistoryPath()
1.1185 +{
1.1186 + QString histName(QString("history-%1").arg(curStep));
1.1187 + return (tmpMapDir+"/"+histName);
1.1188 +}
1.1189 +
1.1190 +void VymModel::saveState(const SaveMode &savemode, const QString &undoSelection, const QString &undoCom, const QString &redoSelection, const QString &redoCom, const QString &comment, LinkableMapObj *saveSel)
1.1191 +{
1.1192 + sendData(redoCom); //FIXME testing
1.1193 +
1.1194 + // Main saveState
1.1195 +
1.1196 +
1.1197 + if (blockSaveState) return;
1.1198 +
1.1199 + if (debug) cout << "ME::saveState() for "<<qPrintable (mapName)<<endl;
1.1200 +
1.1201 + // Find out current undo directory
1.1202 + if (undosAvail<stepsTotal) undosAvail++;
1.1203 + curStep++;
1.1204 + if (curStep>stepsTotal) curStep=1;
1.1205 +
1.1206 + QString backupXML="";
1.1207 + QString histDir=getHistoryPath();
1.1208 + QString bakMapPath=histDir+"/map.xml";
1.1209 +
1.1210 + // Create histDir if not available
1.1211 + QDir d(histDir);
1.1212 + if (!d.exists())
1.1213 + makeSubDirs (histDir);
1.1214 +
1.1215 + // Save depending on how much needs to be saved
1.1216 + if (saveSel)
1.1217 + backupXML=saveToDir (histDir,mapName+"-",false, QPointF (),saveSel);
1.1218 +
1.1219 + QString undoCommand="";
1.1220 + if (savemode==UndoCommand)
1.1221 + {
1.1222 + undoCommand=undoCom;
1.1223 + }
1.1224 + else if (savemode==PartOfMap )
1.1225 + {
1.1226 + undoCommand=undoCom;
1.1227 + undoCommand.replace ("PATH",bakMapPath);
1.1228 + }
1.1229 +
1.1230 + if (!backupXML.isEmpty())
1.1231 + // Write XML Data to disk
1.1232 + saveStringToDisk (bakMapPath,backupXML);
1.1233 +
1.1234 + // We would have to save all actions in a tree, to keep track of
1.1235 + // possible redos after a action. Possible, but we are too lazy: forget about redos.
1.1236 + redosAvail=0;
1.1237 +
1.1238 + // Write the current state to disk
1.1239 + undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1.1240 + undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1.1241 + undoSet.setEntry ("/history/curStep",QString::number(curStep));
1.1242 + undoSet.setEntry (QString("/history/step-%1/undoCommand").arg(curStep),undoCommand);
1.1243 + undoSet.setEntry (QString("/history/step-%1/undoSelection").arg(curStep),undoSelection);
1.1244 + undoSet.setEntry (QString("/history/step-%1/redoCommand").arg(curStep),redoCom);
1.1245 + undoSet.setEntry (QString("/history/step-%1/redoSelection").arg(curStep),redoSelection);
1.1246 + undoSet.setEntry (QString("/history/step-%1/comment").arg(curStep),comment);
1.1247 + undoSet.setEntry (QString("/history/version"),vymVersion);
1.1248 + undoSet.writeSettings(histPath);
1.1249 +
1.1250 + if (debug)
1.1251 + {
1.1252 + // TODO remove after testing
1.1253 + //cout << " into="<< histPath.toStdString()<<endl;
1.1254 + cout << " stepsTotal="<<stepsTotal<<
1.1255 + ", undosAvail="<<undosAvail<<
1.1256 + ", redosAvail="<<redosAvail<<
1.1257 + ", curStep="<<curStep<<endl;
1.1258 + cout << " ---------------------------"<<endl;
1.1259 + cout << " comment="<<comment.toStdString()<<endl;
1.1260 + cout << " undoCom="<<undoCommand.toStdString()<<endl;
1.1261 + cout << " undoSel="<<undoSelection.toStdString()<<endl;
1.1262 + cout << " redoCom="<<redoCom.toStdString()<<endl;
1.1263 + cout << " redoSel="<<redoSelection.toStdString()<<endl;
1.1264 + if (saveSel) cout << " saveSel="<<qPrintable (getSelectString(saveSel))<<endl;
1.1265 + cout << " ---------------------------"<<endl;
1.1266 + }
1.1267 +
1.1268 + mainWindow->updateHistory (undoSet);
1.1269 + setChanged();
1.1270 + updateActions();
1.1271 +}
1.1272 +
1.1273 +
1.1274 +void VymModel::saveStateChangingPart(LinkableMapObj *undoSel, LinkableMapObj* redoSel, const QString &rc, const QString &comment)
1.1275 +{
1.1276 + // save the selected part of the map, Undo will replace part of map
1.1277 + QString undoSelection="";
1.1278 + if (undoSel)
1.1279 + undoSelection=getSelectString(undoSel);
1.1280 + else
1.1281 + qWarning ("VymModel::saveStateChangingPart no undoSel given!");
1.1282 + QString redoSelection="";
1.1283 + if (redoSel)
1.1284 + redoSelection=getSelectString(undoSel);
1.1285 + else
1.1286 + qWarning ("VymModel::saveStateChangingPart no redoSel given!");
1.1287 +
1.1288 +
1.1289 + saveState (PartOfMap,
1.1290 + undoSelection, "addMapReplace (\"PATH\")",
1.1291 + redoSelection, rc,
1.1292 + comment,
1.1293 + undoSel);
1.1294 +}
1.1295 +
1.1296 +void VymModel::saveStateRemovingPart(LinkableMapObj *redoSel, const QString &comment)
1.1297 +{
1.1298 + if (!redoSel)
1.1299 + {
1.1300 + qWarning ("VymModel::saveStateRemovingPart no redoSel given!");
1.1301 + return;
1.1302 + }
1.1303 + QString undoSelection=getSelectString (redoSel->getParObj());
1.1304 + QString redoSelection=getSelectString(redoSel);
1.1305 + if (typeid(*redoSel) == typeid(BranchObj) )
1.1306 + {
1.1307 + // save the selected branch of the map, Undo will insert part of map
1.1308 + saveState (PartOfMap,
1.1309 + undoSelection, QString("addMapInsert (\"PATH\",%1)").arg(((BranchObj*)redoSel)->getNum()),
1.1310 + redoSelection, "delete ()",
1.1311 + comment,
1.1312 + redoSel);
1.1313 + }
1.1314 +}
1.1315 +
1.1316 +
1.1317 +void VymModel::saveState(LinkableMapObj *undoSel, const QString &uc, LinkableMapObj *redoSel, const QString &rc, const QString &comment)
1.1318 +{
1.1319 + // "Normal" savestate: save commands, selections and comment
1.1320 + // so just save commands for undo and redo
1.1321 + // and use current selection
1.1322 +
1.1323 + QString redoSelection="";
1.1324 + if (redoSel) redoSelection=getSelectString(redoSel);
1.1325 + QString undoSelection="";
1.1326 + if (undoSel) undoSelection=getSelectString(undoSel);
1.1327 +
1.1328 + saveState (UndoCommand,
1.1329 + undoSelection, uc,
1.1330 + redoSelection, rc,
1.1331 + comment,
1.1332 + NULL);
1.1333 +}
1.1334 +
1.1335 +void VymModel::saveState(const QString &undoSel, const QString &uc, const QString &redoSel, const QString &rc, const QString &comment)
1.1336 +{
1.1337 + // "Normal" savestate: save commands, selections and comment
1.1338 + // so just save commands for undo and redo
1.1339 + // and use current selection
1.1340 + saveState (UndoCommand,
1.1341 + undoSel, uc,
1.1342 + redoSel, rc,
1.1343 + comment,
1.1344 + NULL);
1.1345 +}
1.1346 +
1.1347 +void VymModel::saveState(const QString &uc, const QString &rc, const QString &comment)
1.1348 +{
1.1349 + // "Normal" savestate applied to model (no selection needed):
1.1350 + // save commands and comment
1.1351 + saveState (UndoCommand,
1.1352 + NULL, uc,
1.1353 + NULL, rc,
1.1354 + comment,
1.1355 + NULL);
1.1356 +}
1.1357 +
1.1358 +
1.1359 QGraphicsScene* VymModel::getScene ()
1.1360 {
1.1361 return mapScene;
1.1362 }
1.1363
1.1364 -MapCenterObj* VymModel::addMapCenter()
1.1365 -{
1.1366 - return addMapCenter (QPointF(0,0));
1.1367 -}
1.1368 -
1.1369 -MapCenterObj* VymModel::addMapCenter(QPointF absPos)
1.1370 -{
1.1371 - MapCenterObj *mapCenter = new MapCenterObj(mapScene);
1.1372 - mapCenter->move (absPos);
1.1373 - mapCenter->setVisibility (true);
1.1374 - mapCenter->setHeading (QApplication::translate("Heading of mapcenter in new map", "New map"));
1.1375 - mapCenter->setMapEditor(mapEditor); //FIXME needed to get defLinkStyle, mapLinkColorHint ... for later added objects
1.1376 - mapCenters.append(mapCenter);
1.1377 - return mapCenter;
1.1378 -}
1.1379 -
1.1380 -MapCenterObj *VymModel::removeMapCenter(MapCenterObj* mco)
1.1381 -{
1.1382 - int i=mapCenters.indexOf (mco);
1.1383 - if (i>=0)
1.1384 - {
1.1385 - mapCenters.removeAt (i);
1.1386 - delete (mco);
1.1387 - if (i>0) return mapCenters.at(i-1); // Return previous MCO
1.1388 - }
1.1389 - return NULL;
1.1390 -}
1.1391 -
1.1392 BranchObj* VymModel::first()
1.1393 {
1.1394 if (mapCenters.count()>0)
1.1395 @@ -196,6 +1421,10 @@
1.1396 return NULL;
1.1397 }
1.1398
1.1399 +void VymModel::removeSelection()
1.1400 +{
1.1401 +}
1.1402 +
1.1403 QString VymModel::saveToDir (const QString &tmpdir,const QString &prefix, int verbose, const QPointF &offset)
1.1404 {
1.1405 QString s;
1.1406 @@ -205,11 +1434,2264 @@
1.1407 return s;
1.1408 }
1.1409
1.1410 +//////////////////////////////////////////////
1.1411 +// Interface
1.1412 +//////////////////////////////////////////////
1.1413 +void VymModel::setVersion (const QString &s)
1.1414 +{
1.1415 + version=s;
1.1416 +}
1.1417 +
1.1418 +void VymModel::setAuthor (const QString &s)
1.1419 +{
1.1420 + saveState (
1.1421 + QString ("setMapAuthor (\"%1\")").arg(author),
1.1422 + QString ("setMapAuthor (\"%1\")").arg(s),
1.1423 + QString ("Set author of map to \"%1\"").arg(s)
1.1424 + );
1.1425 +
1.1426 + author=s;
1.1427 +}
1.1428 +
1.1429 +QString VymModel::getAuthor()
1.1430 +{
1.1431 + return author;
1.1432 +}
1.1433 +
1.1434 +void VymModel::setComment (const QString &s)
1.1435 +{
1.1436 + saveState (
1.1437 + QString ("setMapComment (\"%1\")").arg(comment),
1.1438 + QString ("setMapComment (\"%1\")").arg(s),
1.1439 + QString ("Set comment of map")
1.1440 + );
1.1441 +
1.1442 + comment=s;
1.1443 +}
1.1444 +
1.1445 +QString VymModel::getComment ()
1.1446 +{
1.1447 + return comment;
1.1448 +}
1.1449 +
1.1450 +QString VymModel::getDate ()
1.1451 +{
1.1452 + return QDate::currentDate().toString ("yyyy-MM-dd");
1.1453 +}
1.1454 +
1.1455 +void VymModel::setHeading(const QString &s)
1.1456 +{
1.1457 + BranchObj *sel=selection.getBranch();
1.1458 + if (sel)
1.1459 + {
1.1460 + saveState(
1.1461 + sel,
1.1462 + "setHeading (\""+sel->getHeading()+"\")",
1.1463 + sel,
1.1464 + "setHeading (\""+s+"\")",
1.1465 + QString("Set heading of %1 to \"%2\"").arg(getObjectName(sel)).arg(s) );
1.1466 + sel->setHeading(s );
1.1467 + reposition();
1.1468 + selection.update();
1.1469 + ensureSelectionVisible();
1.1470 + }
1.1471 +}
1.1472 +
1.1473 +QString VymModel::getHeading(bool &ok, QPoint &p)
1.1474 +{
1.1475 + BranchObj *bo=selection.getBranch();
1.1476 + if (bo)
1.1477 + {
1.1478 + ok=true;
1.1479 + //p=scene->mapFromScene(bo->getAbsPos()); // FIXME this is view-dependant!!!
1.1480 + return bo->getHeading();
1.1481 + }
1.1482 + ok=false;
1.1483 + return QString();
1.1484 +}
1.1485 +
1.1486 +
1.1487 +void VymModel::setHeadingInt(const QString &s)
1.1488 +{
1.1489 + BranchObj *bo=selection.getBranch();
1.1490 + if (bo)
1.1491 + {
1.1492 + bo->setHeading(s);
1.1493 + reposition();
1.1494 + selection.update();
1.1495 + ensureSelectionVisible();
1.1496 + }
1.1497 +}
1.1498 +
1.1499 +BranchObj* VymModel::findText (QString s, bool cs)
1.1500 +{
1.1501 + QTextDocument::FindFlags flags=0;
1.1502 + if (cs) flags=QTextDocument::FindCaseSensitively;
1.1503 +
1.1504 + if (!itFind)
1.1505 + { // Nothing found or new find process
1.1506 + if (EOFind)
1.1507 + // nothing found, start again
1.1508 + EOFind=false;
1.1509 + itFind=first();
1.1510 + }
1.1511 + bool searching=true;
1.1512 + bool foundNote=false;
1.1513 + while (searching && !EOFind)
1.1514 + {
1.1515 + if (itFind)
1.1516 + {
1.1517 + // Searching in Note
1.1518 + if (itFind->getNote().contains(s,cs))
1.1519 + {
1.1520 + if (selection.single()!=itFind)
1.1521 + {
1.1522 + selection.select(itFind);
1.1523 + ensureSelectionVisible();
1.1524 + }
1.1525 + if (textEditor->findText(s,flags))
1.1526 + {
1.1527 + searching=false;
1.1528 + foundNote=true;
1.1529 + }
1.1530 + }
1.1531 + // Searching in Heading
1.1532 + if (searching && itFind->getHeading().contains (s,cs) )
1.1533 + {
1.1534 + selection.select(itFind);
1.1535 + ensureSelectionVisible();
1.1536 + searching=false;
1.1537 + }
1.1538 + }
1.1539 + if (!foundNote)
1.1540 + {
1.1541 + itFind=next(itFind);
1.1542 + if (!itFind) EOFind=true;
1.1543 + }
1.1544 + //cout <<"still searching... "<<qPrintable( itFind->getHeading())<<endl;
1.1545 + }
1.1546 + if (!searching)
1.1547 + return selection.getBranch();
1.1548 + else
1.1549 + return NULL;
1.1550 +}
1.1551 +
1.1552 +void VymModel::findReset()
1.1553 +{ // Necessary if text to find changes during a find process
1.1554 + itFind=NULL;
1.1555 + EOFind=false;
1.1556 +}
1.1557 +
1.1558 +
1.1559 +
1.1560 +void VymModel::setScene (QGraphicsScene *s)
1.1561 +{
1.1562 + mapScene=s;
1.1563 + init(); // Here we have a mapScene set,
1.1564 + // which is (still) needed to create MapCenters
1.1565 +}
1.1566 +
1.1567 +void VymModel::setURL(const QString &url)
1.1568 +{
1.1569 + BranchObj *bo=selection.getBranch();
1.1570 + if (bo)
1.1571 + {
1.1572 + QString oldurl=bo->getURL();
1.1573 + bo->setURL (url);
1.1574 + saveState (
1.1575 + bo,
1.1576 + QString ("setURL (\"%1\")").arg(oldurl),
1.1577 + bo,
1.1578 + QString ("setURL (\"%1\")").arg(url),
1.1579 + QString ("set URL of %1 to %2").arg(getObjectName(bo)).arg(url)
1.1580 + );
1.1581 + updateActions();
1.1582 + reposition();
1.1583 + selection.update();
1.1584 + ensureSelectionVisible();
1.1585 + }
1.1586 +}
1.1587 +
1.1588 +QString VymModel::getURL()
1.1589 +{
1.1590 + BranchObj *bo=selection.getBranch();
1.1591 + if (bo)
1.1592 + return bo->getURL();
1.1593 + else
1.1594 + return "";
1.1595 +}
1.1596 +
1.1597 +QStringList VymModel::getURLs()
1.1598 +{
1.1599 + QStringList urls;
1.1600 + BranchObj *bo=selection.getBranch();
1.1601 + if (bo)
1.1602 + {
1.1603 + bo=bo->first();
1.1604 + while (bo)
1.1605 + {
1.1606 + if (!bo->getURL().isEmpty()) urls.append( bo->getURL());
1.1607 + bo=bo->next();
1.1608 + }
1.1609 + }
1.1610 + return urls;
1.1611 +}
1.1612 +
1.1613 +void VymModel::linkFloatImageTo(const QString &dstString)
1.1614 +{
1.1615 + FloatImageObj *fio=selection.getFloatImage();
1.1616 + if (fio)
1.1617 + {
1.1618 + BranchObj *dst=(BranchObj*)findObjBySelect(dstString);
1.1619 + if (dst && (typeid(*dst)==typeid (BranchObj) ||
1.1620 + typeid(*dst)==typeid (MapCenterObj)))
1.1621 + {
1.1622 + LinkableMapObj *dstPar=dst->getParObj();
1.1623 + QString parString=getSelectString(dstPar);
1.1624 + QString fioPreSelectString=getSelectString(fio);
1.1625 + QString fioPreParentSelectString=getSelectString (fio->getParObj());
1.1626 + ((BranchObj*)dst)->addFloatImage (fio);
1.1627 + selection.unselect();
1.1628 + ((BranchObj*)(fio->getParObj()))->removeFloatImage (fio);
1.1629 + fio=((BranchObj*)dst)->getLastFloatImage();
1.1630 + fio->setRelPos();
1.1631 + fio->reposition();
1.1632 + selection.select(fio);
1.1633 + saveState(
1.1634 + getSelectString(fio),
1.1635 + QString("linkTo (\"%1\")").arg(fioPreParentSelectString),
1.1636 + fioPreSelectString,
1.1637 + QString ("linkTo (\"%1\")").arg(dstString),
1.1638 + QString ("Link floatimage to %1").arg(getObjectName(dst)));
1.1639 + }
1.1640 + }
1.1641 +}
1.1642 +
1.1643 +
1.1644 +void VymModel::setFrameType(const FrameObj::FrameType &t)
1.1645 +{
1.1646 + BranchObj *bo=selection.getBranch();
1.1647 + if (bo)
1.1648 + {
1.1649 + QString s=bo->getFrameTypeName();
1.1650 + bo->setFrameType (t);
1.1651 + saveState (bo, QString("setFrameType (\"%1\")").arg(s),
1.1652 + bo, QString ("setFrameType (\"%1\")").arg(bo->getFrameTypeName()),QString ("set type of frame to %1").arg(s));
1.1653 + reposition();
1.1654 + bo->updateLink();
1.1655 + }
1.1656 +}
1.1657 +
1.1658 +void VymModel::setFrameType(const QString &s)
1.1659 +{
1.1660 + BranchObj *bo=selection.getBranch();
1.1661 + if (bo)
1.1662 + {
1.1663 + saveState (bo, QString("setFrameType (\"%1\")").arg(bo->getFrameTypeName()),
1.1664 + bo, QString ("setFrameType (\"%1\")").arg(s),QString ("set type of frame to %1").arg(s));
1.1665 + bo->setFrameType (s);
1.1666 + reposition();
1.1667 + bo->updateLink();
1.1668 + }
1.1669 +}
1.1670 +
1.1671 +void VymModel::setFramePenColor(const QColor &c)
1.1672 +{
1.1673 + BranchObj *bo=selection.getBranch();
1.1674 + if (bo)
1.1675 + {
1.1676 + saveState (bo, QString("setFramePenColor (\"%1\")").arg(bo->getFramePenColor().name() ),
1.1677 + bo, QString ("setFramePenColor (\"%1\")").arg(c.name() ),QString ("set pen color of frame to %1").arg(c.name() ));
1.1678 + bo->setFramePenColor (c);
1.1679 + }
1.1680 +}
1.1681 +
1.1682 +void VymModel::setFrameBrushColor(const QColor &c)
1.1683 +{
1.1684 + BranchObj *bo=selection.getBranch();
1.1685 + if (bo)
1.1686 + {
1.1687 + saveState (bo, QString("setFrameBrushColor (\"%1\")").arg(bo->getFrameBrushColor().name() ),
1.1688 + bo, QString ("setFrameBrushColor (\"%1\")").arg(c.name() ),QString ("set brush color of frame to %1").arg(c.name() ));
1.1689 + bo->setFrameBrushColor (c);
1.1690 + }
1.1691 +}
1.1692 +
1.1693 +void VymModel::setFramePadding (const int &i)
1.1694 +{
1.1695 + BranchObj *bo=selection.getBranch();
1.1696 + if (bo)
1.1697 + {
1.1698 + saveState (bo, QString("setFramePadding (\"%1\")").arg(bo->getFramePadding() ),
1.1699 + bo, QString ("setFramePadding (\"%1\")").arg(i),QString ("set brush color of frame to %1").arg(i));
1.1700 + bo->setFramePadding (i);
1.1701 + reposition();
1.1702 + bo->updateLink();
1.1703 + }
1.1704 +}
1.1705 +
1.1706 +void VymModel::setFrameBorderWidth(const int &i)
1.1707 +{
1.1708 + BranchObj *bo=selection.getBranch();
1.1709 + if (bo)
1.1710 + {
1.1711 + saveState (bo, QString("setFrameBorderWidth (\"%1\")").arg(bo->getFrameBorderWidth() ),
1.1712 + bo, QString ("setFrameBorderWidth (\"%1\")").arg(i),QString ("set border width of frame to %1").arg(i));
1.1713 + bo->setFrameBorderWidth (i);
1.1714 + reposition();
1.1715 + bo->updateLink();
1.1716 + }
1.1717 +}
1.1718 +
1.1719 +void VymModel::setIncludeImagesVer(bool b)
1.1720 +{
1.1721 + BranchObj *bo=selection.getBranch();
1.1722 + if (bo)
1.1723 + {
1.1724 + QString u= b ? "false" : "true";
1.1725 + QString r=!b ? "false" : "true";
1.1726 +
1.1727 + saveState(
1.1728 + bo,
1.1729 + QString("setIncludeImagesVertically (%1)").arg(u),
1.1730 + bo,
1.1731 + QString("setIncludeImagesVertically (%1)").arg(r),
1.1732 + QString("Include images vertically in %1").arg(getObjectName(bo))
1.1733 + );
1.1734 + bo->setIncludeImagesVer(b);
1.1735 + reposition();
1.1736 + }
1.1737 +}
1.1738 +
1.1739 +void VymModel::setIncludeImagesHor(bool b)
1.1740 +{
1.1741 + BranchObj *bo=selection.getBranch();
1.1742 + if (bo)
1.1743 + {
1.1744 + QString u= b ? "false" : "true";
1.1745 + QString r=!b ? "false" : "true";
1.1746 +
1.1747 + saveState(
1.1748 + bo,
1.1749 + QString("setIncludeImagesHorizontally (%1)").arg(u),
1.1750 + bo,
1.1751 + QString("setIncludeImagesHorizontally (%1)").arg(r),
1.1752 + QString("Include images horizontally in %1").arg(getObjectName(bo))
1.1753 + );
1.1754 + bo->setIncludeImagesHor(b);
1.1755 + reposition();
1.1756 + }
1.1757 +}
1.1758 +
1.1759 +void VymModel::setHideLinkUnselected (bool b)
1.1760 +{
1.1761 + LinkableMapObj *sel=selection.single();
1.1762 + if (sel &&
1.1763 + (selection.type() == Selection::Branch ||
1.1764 + selection.type() == Selection::MapCenter ||
1.1765 + selection.type() == Selection::FloatImage ))
1.1766 + {
1.1767 + QString u= b ? "false" : "true";
1.1768 + QString r=!b ? "false" : "true";
1.1769 +
1.1770 + saveState(
1.1771 + sel,
1.1772 + QString("setHideLinkUnselected (%1)").arg(u),
1.1773 + sel,
1.1774 + QString("setHideLinkUnselected (%1)").arg(r),
1.1775 + QString("Hide link of %1 if unselected").arg(getObjectName(sel))
1.1776 + );
1.1777 + sel->setHideLinkUnselected(b);
1.1778 + }
1.1779 +}
1.1780 +
1.1781 +void VymModel::setHideExport(bool b)
1.1782 +{
1.1783 + BranchObj *bo=selection.getBranch();
1.1784 + if (bo)
1.1785 + {
1.1786 + bo->setHideInExport (b);
1.1787 + QString u= b ? "false" : "true";
1.1788 + QString r=!b ? "false" : "true";
1.1789 +
1.1790 + saveState(
1.1791 + bo,
1.1792 + QString ("setHideExport (%1)").arg(u),
1.1793 + bo,
1.1794 + QString ("setHideExport (%1)").arg(r),
1.1795 + QString ("Set HideExport flag of %1 to %2").arg(getObjectName(bo)).arg (r)
1.1796 + );
1.1797 + updateActions();
1.1798 + reposition();
1.1799 + selection.update();
1.1800 + // FIXME needed? scene()->update();
1.1801 + }
1.1802 +}
1.1803 +
1.1804 +void VymModel::toggleHideExport()
1.1805 +{
1.1806 + BranchObj *bo=selection.getBranch();
1.1807 + if (bo)
1.1808 + setHideExport ( !bo->hideInExport() );
1.1809 +}
1.1810 +
1.1811 +
1.1812 +void VymModel::copy()
1.1813 +{
1.1814 + LinkableMapObj *sel=selection.single();
1.1815 + if (sel)
1.1816 + {
1.1817 + if (redosAvail == 0)
1.1818 + {
1.1819 + // Copy to history
1.1820 + QString s=getSelectString(sel);
1.1821 + saveState (PartOfMap, s, "nop ()", s, "copy ()","Copy selection to clipboard",sel );
1.1822 + curClipboard=curStep;
1.1823 + }
1.1824 +
1.1825 + // Copy also to global clipboard, because we are at last step in history
1.1826 + QString bakMapName(QString("history-%1").arg(curStep));
1.1827 + QString bakMapDir(tmpMapDir +"/"+bakMapName);
1.1828 + copyDir (bakMapDir,clipboardDir );
1.1829 +
1.1830 + clipboardEmpty=false;
1.1831 + updateActions();
1.1832 + }
1.1833 +}
1.1834 +
1.1835 +
1.1836 +void VymModel::pasteNoSave(const int &n)
1.1837 +{
1.1838 + bool old=blockSaveState;
1.1839 + blockSaveState=true;
1.1840 + bool zippedOrg=zipped;
1.1841 + if (redosAvail > 0 || n!=0)
1.1842 + {
1.1843 + // Use the "historical" buffer
1.1844 + QString bakMapName(QString("history-%1").arg(n));
1.1845 + QString bakMapDir(tmpMapDir +"/"+bakMapName);
1.1846 + load (bakMapDir+"/"+clipboardFile,ImportAdd, VymMap);
1.1847 + } else
1.1848 + // Use the global buffer
1.1849 + load (clipboardDir+"/"+clipboardFile,ImportAdd, VymMap);
1.1850 + zipped=zippedOrg;
1.1851 + blockSaveState=old;
1.1852 +}
1.1853 +
1.1854 +void VymModel::paste()
1.1855 +{
1.1856 + BranchObj *sel=selection.getBranch();
1.1857 + if (sel)
1.1858 + {
1.1859 + saveStateChangingPart(
1.1860 + sel,
1.1861 + sel,
1.1862 + QString ("paste (%1)").arg(curClipboard),
1.1863 + QString("Paste to %1").arg( getObjectName(sel))
1.1864 + );
1.1865 + pasteNoSave(0);
1.1866 + reposition();
1.1867 + }
1.1868 +}
1.1869 +
1.1870 +void VymModel::cut()
1.1871 +{
1.1872 + LinkableMapObj *sel=selection.single();
1.1873 + if ( sel && (selection.type() == Selection::Branch ||
1.1874 + selection.type()==Selection::MapCenter ||
1.1875 + selection.type()==Selection::FloatImage))
1.1876 + {
1.1877 + /* No savestate! savestate is called in cutNoSave
1.1878 + saveStateChangingPart(
1.1879 + sel->getParObj(),
1.1880 + sel,
1.1881 + "cut ()",
1.1882 + QString("Cut %1").arg(getObjectName(sel ))
1.1883 + );
1.1884 + */
1.1885 + copy();
1.1886 + deleteSelection();
1.1887 + reposition();
1.1888 + }
1.1889 +}
1.1890 +
1.1891 +void VymModel::moveBranchUp()
1.1892 +{
1.1893 + BranchObj* bo=selection.getBranch();
1.1894 + BranchObj* par;
1.1895 + if (bo)
1.1896 + {
1.1897 + if (!bo->canMoveBranchUp()) return;
1.1898 + par=(BranchObj*)(bo->getParObj());
1.1899 + BranchObj *obo=par->moveBranchUp (bo); // bo will be the one below selection
1.1900 + saveState (getSelectString(bo),"moveBranchDown ()",getSelectString(obo),"moveBranchUp ()",QString("Move up %1").arg(getObjectName(bo)));
1.1901 + reposition();
1.1902 + //FIXME needed? scene()->update();
1.1903 + selection.update();
1.1904 + ensureSelectionVisible();
1.1905 + }
1.1906 +}
1.1907 +
1.1908 +void VymModel::moveBranchDown()
1.1909 +{
1.1910 + BranchObj* bo=selection.getBranch();
1.1911 + BranchObj* par;
1.1912 + if (bo)
1.1913 + {
1.1914 + if (!bo->canMoveBranchDown()) return;
1.1915 + par=(BranchObj*)(bo->getParObj());
1.1916 + BranchObj *obo=par->moveBranchDown(bo); // bo will be the one above selection
1.1917 + saveState(getSelectString(bo),"moveBranchUp ()",getSelectString(obo),"moveBranchDown ()",QString("Move down %1").arg(getObjectName(bo)));
1.1918 + reposition();
1.1919 + //FIXME needed? scene()->update();
1.1920 + selection.update();
1.1921 + ensureSelectionVisible();
1.1922 + }
1.1923 +}
1.1924 +
1.1925 +void VymModel::sortChildren()
1.1926 +{
1.1927 + BranchObj* bo=selection.getBranch();
1.1928 + if (bo)
1.1929 + {
1.1930 + if(bo->countBranches()>1)
1.1931 + {
1.1932 + saveStateChangingPart(bo,bo, "sortChildren ()",QString("Sort children of %1").arg(getObjectName(bo)));
1.1933 + bo->sortChildren();
1.1934 + reposition();
1.1935 + ensureSelectionVisible();
1.1936 + }
1.1937 + }
1.1938 +}
1.1939 +
1.1940 +MapCenterObj* VymModel::addMapCenter ()
1.1941 +{
1.1942 + MapCenterObj *mco=addMapCenter (QPointF(0,0));
1.1943 + selection.select (mco);
1.1944 + updateActions();
1.1945 + ensureSelectionVisible();
1.1946 + saveState (
1.1947 + mco,
1.1948 + "delete()",
1.1949 + NULL,
1.1950 + // FIXME how to position LineEdit without contextMenuPos ?
1.1951 + // QString ("addMapCenter (%1,%2)").arg (contextMenuPos.x()).arg(contextMenuPos.y()),
1.1952 + // QString ("Adding MapCenter to (%1,%2").arg (contextMenuPos.x()).arg(contextMenuPos.y())
1.1953 + QString ("addMapCenter (%1,%2)").arg (0).arg(0),
1.1954 + QString ("Adding MapCenter to (%1,%2").arg (0).arg(0)
1.1955 + );
1.1956 + return mco;
1.1957 +}
1.1958 +
1.1959 +MapCenterObj* VymModel::addMapCenter(QPointF absPos)
1.1960 +{
1.1961 + MapCenterObj *mapCenter = new MapCenterObj(mapScene);
1.1962 + mapCenter->move (absPos);
1.1963 + mapCenter->setVisibility (true);
1.1964 + mapCenter->setHeading (QApplication::translate("Heading of mapcenter in new map", "New map"));
1.1965 + mapCenter->setMapEditor(mapEditor); //FIXME needed to get defLinkStyle, mapLinkColorHint ... for later added objects
1.1966 + mapCenters.append(mapCenter);
1.1967 + return mapCenter;
1.1968 +}
1.1969 +
1.1970 +MapCenterObj *VymModel::removeMapCenter(MapCenterObj* mco)
1.1971 +{
1.1972 + int i=mapCenters.indexOf (mco);
1.1973 + if (i>=0)
1.1974 + {
1.1975 + mapCenters.removeAt (i);
1.1976 + delete (mco);
1.1977 + if (i>0) return mapCenters.at(i-1); // Return previous MCO
1.1978 + }
1.1979 + return NULL;
1.1980 +}
1.1981 +
1.1982 +
1.1983 +BranchObj* VymModel::addNewBranchInt(int num)
1.1984 +{
1.1985 + // Depending on pos:
1.1986 + // -3 insert in children of parent above selection
1.1987 + // -2 add branch to selection
1.1988 + // -1 insert in children of parent below selection
1.1989 + // 0..n insert in children of parent at pos
1.1990 + BranchObj *newbo=NULL;
1.1991 + BranchObj *bo=selection.getBranch();
1.1992 + if (bo)
1.1993 + {
1.1994 + if (num==-2)
1.1995 + {
1.1996 + // save scroll state. If scrolled, automatically select
1.1997 + // new branch in order to tmp unscroll parent...
1.1998 + newbo=bo->addBranch();
1.1999 +
1.2000 + }else if (num==-1)
1.2001 + {
1.2002 + num=bo->getNum()+1;
1.2003 + bo=(BranchObj*)bo->getParObj();
1.2004 + if (bo) newbo=bo->insertBranch(num);
1.2005 + }else if (num==-3)
1.2006 + {
1.2007 + num=bo->getNum();
1.2008 + bo=(BranchObj*)bo->getParObj();
1.2009 + if (bo) newbo=bo->insertBranch(num);
1.2010 + }
1.2011 + if (!newbo) return NULL;
1.2012 + }
1.2013 + return newbo;
1.2014 +}
1.2015 +
1.2016 +BranchObj* VymModel::addNewBranch(int pos)
1.2017 +{
1.2018 + // Different meaning than num in addNewBranchInt!
1.2019 + // -1 add above
1.2020 + // 0 add as child
1.2021 + // +1 add below
1.2022 + BranchObj *bo = selection.getBranch();
1.2023 + BranchObj *newbo=NULL;
1.2024 +
1.2025 + if (bo)
1.2026 + {
1.2027 + // FIXME do we still need this in model? setCursor (Qt::ArrowCursor);
1.2028 +
1.2029 + newbo=addNewBranchInt (pos-2);
1.2030 +
1.2031 + if (newbo)
1.2032 + {
1.2033 + saveState(
1.2034 + newbo,
1.2035 + "delete ()",
1.2036 + bo,
1.2037 + QString ("addBranch (%1)").arg(pos),
1.2038 + QString ("Add new branch to %1").arg(getObjectName(bo)));
1.2039 +
1.2040 + reposition();
1.2041 + selection.update();
1.2042 + latestSelectionString=getSelectString(newbo);
1.2043 + // In Network mode, the client needs to know where the new branch is,
1.2044 + // so we have to pass on this information via saveState.
1.2045 + // TODO: Get rid of this positioning workaround
1.2046 + QString ps=qpointfToString (newbo->getAbsPos());
1.2047 + sendData ("selectLatestAdded ()");
1.2048 + sendData (QString("move %1").arg(ps));
1.2049 + sendSelection();
1.2050 + }
1.2051 + }
1.2052 + return newbo;
1.2053 +}
1.2054 +
1.2055 +
1.2056 +BranchObj* VymModel::addNewBranchBefore()
1.2057 +{
1.2058 + BranchObj *newbo=NULL;
1.2059 + BranchObj *bo = selection.getBranch();
1.2060 + if (bo && selection.type()==Selection::Branch)
1.2061 + // We accept no MapCenterObj here, so we _have_ a parent
1.2062 + {
1.2063 + QPointF p=bo->getRelPos();
1.2064 +
1.2065 +
1.2066 + BranchObj *parbo=(BranchObj*)(bo->getParObj());
1.2067 +
1.2068 + // add below selection
1.2069 + newbo=parbo->insertBranch(bo->getNum()+1);
1.2070 + if (newbo)
1.2071 + {
1.2072 + newbo->move2RelPos (p);
1.2073 +
1.2074 + // Move selection to new branch
1.2075 + bo->linkTo (newbo,-1);
1.2076 +
1.2077 + saveState (newbo, "deleteKeepChildren ()", newbo, "addBranchBefore ()",
1.2078 + QString ("Add branch before %1").arg(getObjectName(bo)));
1.2079 +
1.2080 + reposition();
1.2081 + selection.update();
1.2082 + }
1.2083 + }
1.2084 + latestSelectionString=selection.getSelectString();
1.2085 + return newbo;
1.2086 +}
1.2087 +
1.2088 +void VymModel::deleteSelection()
1.2089 +{
1.2090 + BranchObj *bo = selection.getBranch();
1.2091 + if (bo && selection.type()==Selection::MapCenter)
1.2092 + {
1.2093 + // BranchObj* par=(BranchObj*)(bo->getParObj());
1.2094 + selection.unselect();
1.2095 + /* FIXME Note: does saveStateRemovingPart work for MCO? (No parent!)
1.2096 + saveStateRemovingPart (bo, QString ("Delete %1").arg(getObjectName(bo)));
1.2097 + */
1.2098 + bo=removeMapCenter ((MapCenterObj*)bo);
1.2099 + if (bo)
1.2100 + {
1.2101 + selection.select (bo);
1.2102 + ensureSelectionVisible();
1.2103 + selection.update();
1.2104 + }
1.2105 + reposition();
1.2106 + return;
1.2107 + }
1.2108 + if (bo && selection.type()==Selection::Branch)
1.2109 + {
1.2110 + BranchObj* par=(BranchObj*)bo->getParObj();
1.2111 + selection.unselect();
1.2112 + saveStateRemovingPart (bo, QString ("Delete %1").arg(getObjectName(bo)));
1.2113 + par->removeBranch(bo);
1.2114 + selection.select (par);
1.2115 + ensureSelectionVisible();
1.2116 + reposition();
1.2117 + selection.update();
1.2118 + return;
1.2119 + }
1.2120 + FloatImageObj *fio=selection.getFloatImage();
1.2121 + if (fio)
1.2122 + {
1.2123 + BranchObj* par=(BranchObj*)fio->getParObj();
1.2124 + saveStateChangingPart(
1.2125 + par,
1.2126 + fio,
1.2127 + "delete ()",
1.2128 + QString("Delete %1").arg(getObjectName(fio))
1.2129 + );
1.2130 + selection.unselect();
1.2131 + par->removeFloatImage(fio);
1.2132 + selection.select (par);
1.2133 + reposition();
1.2134 + selection.update();
1.2135 + ensureSelectionVisible();
1.2136 + return;
1.2137 + }
1.2138 +}
1.2139 +
1.2140 +void VymModel::deleteKeepChildren()
1.2141 +{
1.2142 + BranchObj *bo=selection.getBranch();
1.2143 + BranchObj *par;
1.2144 + if (bo)
1.2145 + {
1.2146 + par=(BranchObj*)(bo->getParObj());
1.2147 + QPointF p=bo->getRelPos();
1.2148 + saveStateChangingPart(
1.2149 + bo->getParObj(),
1.2150 + bo,
1.2151 + "deleteKeepChildren ()",
1.2152 + QString("Remove %1 and keep its children").arg(getObjectName(bo))
1.2153 + );
1.2154 +
1.2155 + QString sel=getSelectString(bo);
1.2156 + unselect();
1.2157 + par->removeBranchHere(bo);
1.2158 + reposition();
1.2159 + select (sel);
1.2160 + selection.getBranch()->move2RelPos (p);
1.2161 + reposition();
1.2162 + }
1.2163 +}
1.2164 +
1.2165 +void VymModel::deleteChildren()
1.2166 +{
1.2167 + BranchObj *bo=selection.getBranch();
1.2168 + if (bo)
1.2169 + {
1.2170 + saveStateChangingPart(
1.2171 + bo,
1.2172 + bo,
1.2173 + "deleteChildren ()",
1.2174 + QString( "Remove children of branch %1").arg(getObjectName(bo))
1.2175 + );
1.2176 + bo->removeChildren();
1.2177 + reposition();
1.2178 + }
1.2179 +}
1.2180 +
1.2181 +
1.2182 +bool VymModel::scrollBranch(BranchObj *bo)
1.2183 +{
1.2184 + if (bo)
1.2185 + {
1.2186 + if (bo->isScrolled()) return false;
1.2187 + if (bo->countBranches()==0) return false;
1.2188 + if (bo->getDepth()==0) return false;
1.2189 + QString u,r;
1.2190 + r="scroll";
1.2191 + u="unscroll";
1.2192 + saveState(
1.2193 + bo,
1.2194 + QString ("%1 ()").arg(u),
1.2195 + bo,
1.2196 + QString ("%1 ()").arg(r),
1.2197 + QString ("%1 %2").arg(r).arg(getObjectName(bo))
1.2198 + );
1.2199 + bo->toggleScroll();
1.2200 + selection.update();
1.2201 + // FIXME needed? scene()->update();
1.2202 + return true;
1.2203 + }
1.2204 + return false;
1.2205 +}
1.2206 +
1.2207 +bool VymModel::unscrollBranch(BranchObj *bo)
1.2208 +{
1.2209 + if (bo)
1.2210 + {
1.2211 + if (!bo->isScrolled()) return false;
1.2212 + if (bo->countBranches()==0) return false;
1.2213 + if (bo->getDepth()==0) return false;
1.2214 + QString u,r;
1.2215 + u="scroll";
1.2216 + r="unscroll";
1.2217 + saveState(
1.2218 + bo,
1.2219 + QString ("%1 ()").arg(u),
1.2220 + bo,
1.2221 + QString ("%1 ()").arg(r),
1.2222 + QString ("%1 %2").arg(r).arg(getObjectName(bo))
1.2223 + );
1.2224 + bo->toggleScroll();
1.2225 + selection.update();
1.2226 + // FIXME needed? scene()->update();
1.2227 + return true;
1.2228 + }
1.2229 + return false;
1.2230 +}
1.2231 +
1.2232 +void VymModel::toggleScroll()
1.2233 +{
1.2234 + BranchObj *bo=selection.getBranch();
1.2235 + if (selection.type()==Selection::Branch )
1.2236 + {
1.2237 + if (bo->isScrolled())
1.2238 + unscrollBranch (bo);
1.2239 + else
1.2240 + scrollBranch (bo);
1.2241 + }
1.2242 +}
1.2243 +
1.2244 +void VymModel::unscrollChildren()
1.2245 +{
1.2246 + BranchObj *bo=selection.getBranch();
1.2247 + if (bo)
1.2248 + {
1.2249 + bo->first();
1.2250 + while (bo)
1.2251 + {
1.2252 + if (bo->isScrolled()) unscrollBranch (bo);
1.2253 + bo=bo->next();
1.2254 + }
1.2255 + }
1.2256 +}
1.2257 +void VymModel::addFloatImage (const QPixmap &img)
1.2258 +{
1.2259 + BranchObj *bo=selection.getBranch();
1.2260 + if (bo)
1.2261 + {
1.2262 + FloatImageObj *fio=bo->addFloatImage();
1.2263 + fio->load(img);
1.2264 + fio->setOriginalFilename("No original filename (image added by dropevent)");
1.2265 + QString s=getSelectString(bo);
1.2266 + saveState (PartOfMap, s, "nop ()", s, "copy ()","Copy dropped image to clipboard",fio );
1.2267 + saveState (fio,"delete ()", bo,QString("paste(%1)").arg(curStep),"Pasting dropped image");
1.2268 + reposition();
1.2269 + // FIXME needed? scene()->update();
1.2270 + }
1.2271 +}
1.2272 +
1.2273 +
1.2274 +void VymModel::colorBranch (QColor c)
1.2275 +{
1.2276 + BranchObj *bo=selection.getBranch();
1.2277 + if (bo)
1.2278 + {
1.2279 + saveState(
1.2280 + bo,
1.2281 + QString ("colorBranch (\"%1\")").arg(bo->getColor().name()),
1.2282 + bo,
1.2283 + QString ("colorBranch (\"%1\")").arg(c.name()),
1.2284 + QString("Set color of %1 to %2").arg(getObjectName(bo)).arg(c.name())
1.2285 + );
1.2286 + bo->setColor(c); // color branch
1.2287 + }
1.2288 +}
1.2289 +
1.2290 +void VymModel::colorSubtree (QColor c)
1.2291 +{
1.2292 + BranchObj *bo=selection.getBranch();
1.2293 + if (bo)
1.2294 + {
1.2295 + saveStateChangingPart(
1.2296 + bo,
1.2297 + bo,
1.2298 + QString ("colorSubtree (\"%1\")").arg(c.name()),
1.2299 + QString ("Set color of %1 and children to %2").arg(getObjectName(bo)).arg(c.name())
1.2300 + );
1.2301 + bo->setColorSubtree (c); // color links, color children
1.2302 + }
1.2303 +}
1.2304 +
1.2305 +QColor VymModel::getCurrentHeadingColor()
1.2306 +{
1.2307 + BranchObj *bo=selection.getBranch();
1.2308 + if (bo) return bo->getColor();
1.2309 +
1.2310 + QMessageBox::warning(0,"Warning","Can't get color of heading,\nthere's no branch selected");
1.2311 + return Qt::black;
1.2312 +}
1.2313 +
1.2314 +
1.2315 +
1.2316 +void VymModel::editURL()
1.2317 +{
1.2318 + BranchObj *bo=selection.getBranch();
1.2319 + if (bo)
1.2320 + {
1.2321 + bool ok;
1.2322 + QString text = QInputDialog::getText(
1.2323 + "VYM", tr("Enter URL:"), QLineEdit::Normal,
1.2324 + bo->getURL(), &ok, NULL);
1.2325 + if ( ok)
1.2326 + // user entered something and pressed OK
1.2327 + setURL(text);
1.2328 + }
1.2329 +}
1.2330 +
1.2331 +void VymModel::editLocalURL()
1.2332 +{
1.2333 + BranchObj *bo=selection.getBranch();
1.2334 + if (bo)
1.2335 + {
1.2336 + QStringList filters;
1.2337 + filters <<"All files (*)";
1.2338 + filters << tr("Text","Filedialog") + " (*.txt)";
1.2339 + filters << tr("Spreadsheet","Filedialog") + " (*.odp,*.sxc)";
1.2340 + filters << tr("Textdocument","Filedialog") +" (*.odw,*.sxw)";
1.2341 + filters << tr("Images","Filedialog") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)";
1.2342 + QFileDialog *fd=new QFileDialog( NULL,vymName+" - " +tr("Set URL to a local file"));
1.2343 + fd->setFilters (filters);
1.2344 + fd->setCaption(vymName+" - " +tr("Set URL to a local file"));
1.2345 + fd->setDirectory (lastFileDir);
1.2346 + if (! bo->getVymLink().isEmpty() )
1.2347 + fd->selectFile( bo->getURL() );
1.2348 + fd->show();
1.2349 +
1.2350 + if ( fd->exec() == QDialog::Accepted )
1.2351 + {
1.2352 + lastFileDir=QDir (fd->directory().path());
1.2353 + setURL (fd->selectedFile() );
1.2354 + }
1.2355 + }
1.2356 +}
1.2357 +
1.2358 +
1.2359 +void VymModel::editHeading2URL()
1.2360 +{
1.2361 + BranchObj *bo=selection.getBranch();
1.2362 + if (bo)
1.2363 + setURL (bo->getHeading());
1.2364 +}
1.2365 +
1.2366 +void VymModel::editBugzilla2URL()
1.2367 +{
1.2368 + BranchObj *bo=selection.getBranch();
1.2369 + if (bo)
1.2370 + {
1.2371 + QString url= "https://bugzilla.novell.com/show_bug.cgi?id="+bo->getHeading();
1.2372 + setURL (url);
1.2373 + }
1.2374 +}
1.2375 +
1.2376 +void VymModel::editFATE2URL()
1.2377 +{
1.2378 + BranchObj *bo=selection.getBranch();
1.2379 + if (bo)
1.2380 + {
1.2381 + QString url= "http://keeper.suse.de:8080/webfate/match/id?value=ID"+bo->getHeading();
1.2382 + saveState(
1.2383 + bo,
1.2384 + "setURL (\""+bo->getURL()+"\")",
1.2385 + bo,
1.2386 + "setURL (\""+url+"\")",
1.2387 + QString("Use heading of %1 as link to FATE").arg(getObjectName(bo))
1.2388 + );
1.2389 + bo->setURL (url);
1.2390 + updateActions();
1.2391 + }
1.2392 +}
1.2393 +
1.2394 +void VymModel::editVymLink()
1.2395 +{
1.2396 + BranchObj *bo=selection.getBranch();
1.2397 + if (bo)
1.2398 + {
1.2399 + QStringList filters;
1.2400 + filters <<"VYM map (*.vym)";
1.2401 + QFileDialog *fd=new QFileDialog( NULL,vymName+" - " +tr("Link to another map"));
1.2402 + fd->setFilters (filters);
1.2403 + fd->setCaption(vymName+" - " +tr("Link to another map"));
1.2404 + fd->setDirectory (lastFileDir);
1.2405 + if (! bo->getVymLink().isEmpty() )
1.2406 + fd->selectFile( bo->getVymLink() );
1.2407 + fd->show();
1.2408 +
1.2409 + QString fn;
1.2410 + if ( fd->exec() == QDialog::Accepted )
1.2411 + {
1.2412 + lastFileDir=QDir (fd->directory().path());
1.2413 + saveState(
1.2414 + bo,
1.2415 + "setVymLink (\""+bo->getVymLink()+"\")",
1.2416 + bo,
1.2417 + "setVymLink (\""+fd->selectedFile()+"\")",
1.2418 + QString("Set vymlink of %1 to %2").arg(getObjectName(bo)).arg(fd->selectedFile())
1.2419 + );
1.2420 + setVymLink (fd->selectedFile() ); // FIXME ok?
1.2421 + }
1.2422 + }
1.2423 +}
1.2424 +
1.2425 +void VymModel::setVymLink (const QString &s)
1.2426 +{
1.2427 + // Internal function, no saveState needed
1.2428 + BranchObj *bo=selection.getBranch();
1.2429 + if (bo)
1.2430 + {
1.2431 + bo->setVymLink(s);
1.2432 + reposition();
1.2433 + updateActions();
1.2434 + selection.update();
1.2435 + ensureSelectionVisible();
1.2436 + }
1.2437 +}
1.2438 +
1.2439 +void VymModel::deleteVymLink()
1.2440 +{
1.2441 + BranchObj *bo=selection.getBranch();
1.2442 + if (bo)
1.2443 + {
1.2444 + saveState(
1.2445 + bo,
1.2446 + "setVymLink (\""+bo->getVymLink()+"\")",
1.2447 + bo,
1.2448 + "setVymLink (\"\")",
1.2449 + QString("Unset vymlink of %1").arg(getObjectName(bo))
1.2450 + );
1.2451 + bo->setVymLink ("" );
1.2452 + updateActions();
1.2453 + reposition();
1.2454 + // FIXME needed? scene()->update();
1.2455 + }
1.2456 +}
1.2457 +
1.2458 +QString VymModel::getVymLink()
1.2459 +{
1.2460 + BranchObj *bo=selection.getBranch();
1.2461 + if (bo)
1.2462 + return bo->getVymLink();
1.2463 + else
1.2464 + return "";
1.2465 +
1.2466 +}
1.2467 +
1.2468 +QStringList VymModel::getVymLinks()
1.2469 +{
1.2470 + QStringList links;
1.2471 + BranchObj *bo=selection.getBranch();
1.2472 + if (bo)
1.2473 + {
1.2474 + bo=bo->first();
1.2475 + while (bo)
1.2476 + {
1.2477 + if (!bo->getVymLink().isEmpty()) links.append( bo->getVymLink());
1.2478 + bo=bo->next();
1.2479 + }
1.2480 + }
1.2481 + return links;
1.2482 +}
1.2483 +
1.2484 +
1.2485 +void VymModel::followXLink(int i)
1.2486 +{
1.2487 + BranchObj *bo=selection.getBranch();
1.2488 + if (bo)
1.2489 + {
1.2490 + bo=bo->XLinkTargetAt(i);
1.2491 + if (bo)
1.2492 + {
1.2493 + selection.select(bo);
1.2494 + ensureSelectionVisible();
1.2495 + }
1.2496 + }
1.2497 +}
1.2498 +
1.2499 +void VymModel::editXLink(int i) // FIXME missing saveState
1.2500 +{
1.2501 + BranchObj *bo=selection.getBranch();
1.2502 + if (bo)
1.2503 + {
1.2504 + XLinkObj *xlo=bo->XLinkAt(i);
1.2505 + if (xlo)
1.2506 + {
1.2507 + EditXLinkDialog dia;
1.2508 + dia.setXLink (xlo);
1.2509 + dia.setSelection(bo);
1.2510 + if (dia.exec() == QDialog::Accepted)
1.2511 + {
1.2512 + if (dia.useSettingsGlobal() )
1.2513 + {
1.2514 + setMapDefXLinkColor (xlo->getColor() );
1.2515 + setMapDefXLinkWidth (xlo->getWidth() );
1.2516 + }
1.2517 + if (dia.deleteXLink())
1.2518 + bo->deleteXLinkAt(i);
1.2519 + }
1.2520 + }
1.2521 + }
1.2522 +}
1.2523 +
1.2524 +
1.2525 +
1.2526 +
1.2527 +
1.2528 +//////////////////////////////////////////////
1.2529 +// Scripting
1.2530 +//////////////////////////////////////////////
1.2531 +
1.2532 +void VymModel::parseAtom(const QString &atom)
1.2533 +{
1.2534 + BranchObj *selb=selection.getBranch();
1.2535 + QString s,t;
1.2536 + double x,y;
1.2537 + int n;
1.2538 + bool b,ok;
1.2539 +
1.2540 + // Split string s into command and parameters
1.2541 + parser.parseAtom (atom);
1.2542 + QString com=parser.getCommand();
1.2543 +
1.2544 + // External commands
1.2545 + /////////////////////////////////////////////////////////////////////
1.2546 + if (com=="addBranch")
1.2547 + {
1.2548 + if (selection.isEmpty())
1.2549 + {
1.2550 + parser.setError (Aborted,"Nothing selected");
1.2551 + } else if (! selb )
1.2552 + {
1.2553 + parser.setError (Aborted,"Type of selection is not a branch");
1.2554 + } else
1.2555 + {
1.2556 + QList <int> pl;
1.2557 + pl << 0 <<1;
1.2558 + if (parser.checkParCount(pl))
1.2559 + {
1.2560 + if (parser.parCount()==0)
1.2561 + addNewBranch (0);
1.2562 + else
1.2563 + {
1.2564 + n=parser.parInt (ok,0);
1.2565 + if (ok ) addNewBranch (n);
1.2566 + }
1.2567 + }
1.2568 + }
1.2569 + /////////////////////////////////////////////////////////////////////
1.2570 + } else if (com=="addBranchBefore")
1.2571 + {
1.2572 + if (selection.isEmpty())
1.2573 + {
1.2574 + parser.setError (Aborted,"Nothing selected");
1.2575 + } else if (! selb )
1.2576 + {
1.2577 + parser.setError (Aborted,"Type of selection is not a branch");
1.2578 + } else
1.2579 + {
1.2580 + if (parser.parCount()==0)
1.2581 + {
1.2582 + addNewBranchBefore ();
1.2583 + }
1.2584 + }
1.2585 + /////////////////////////////////////////////////////////////////////
1.2586 + } else if (com==QString("addMapCenter"))
1.2587 + {
1.2588 + if (parser.checkParCount(2))
1.2589 + {
1.2590 + x=parser.parDouble (ok,0);
1.2591 + if (ok)
1.2592 + {
1.2593 + y=parser.parDouble (ok,1);
1.2594 + if (ok) addMapCenter (QPointF(x,y));
1.2595 + }
1.2596 + }
1.2597 + /////////////////////////////////////////////////////////////////////
1.2598 + } else if (com==QString("addMapReplace"))
1.2599 + {
1.2600 + if (selection.isEmpty())
1.2601 + {
1.2602 + parser.setError (Aborted,"Nothing selected");
1.2603 + } else if (! selb )
1.2604 + {
1.2605 + parser.setError (Aborted,"Type of selection is not a branch");
1.2606 + } else if (parser.checkParCount(1))
1.2607 + {
1.2608 + //s=parser.parString (ok,0); // selection
1.2609 + t=parser.parString (ok,0); // path to map
1.2610 + if (QDir::isRelativePath(t)) t=(tmpMapDir + "/"+t);
1.2611 + addMapReplaceInt(getSelectString(selb),t);
1.2612 + }
1.2613 + /////////////////////////////////////////////////////////////////////
1.2614 + } else if (com==QString("addMapInsert"))
1.2615 + {
1.2616 + if (selection.isEmpty())
1.2617 + {
1.2618 + parser.setError (Aborted,"Nothing selected");
1.2619 + } else if (! selb )
1.2620 + {
1.2621 + parser.setError (Aborted,"Type of selection is not a branch");
1.2622 + } else
1.2623 + {
1.2624 + if (parser.checkParCount(2))
1.2625 + {
1.2626 + t=parser.parString (ok,0); // path to map
1.2627 + n=parser.parInt(ok,1); // position
1.2628 + if (QDir::isRelativePath(t)) t=(tmpMapDir + "/"+t);
1.2629 + addMapInsertInt(t,n);
1.2630 + }
1.2631 + }
1.2632 + /////////////////////////////////////////////////////////////////////
1.2633 + } else if (com=="clearFlags")
1.2634 + {
1.2635 + if (selection.isEmpty() )
1.2636 + {
1.2637 + parser.setError (Aborted,"Nothing selected");
1.2638 + } else if (! selb )
1.2639 + {
1.2640 + parser.setError (Aborted,"Type of selection is not a branch");
1.2641 + } else if (parser.checkParCount(0))
1.2642 + {
1.2643 + selb->clearStandardFlags();
1.2644 + selb->updateFlagsToolbar();
1.2645 + }
1.2646 + /////////////////////////////////////////////////////////////////////
1.2647 + } else if (com=="colorBranch")
1.2648 + {
1.2649 + if (selection.isEmpty())
1.2650 + {
1.2651 + parser.setError (Aborted,"Nothing selected");
1.2652 + } else if (! selb )
1.2653 + {
1.2654 + parser.setError (Aborted,"Type of selection is not a branch");
1.2655 + } else if (parser.checkParCount(1))
1.2656 + {
1.2657 + QColor c=parser.parColor (ok,0);
1.2658 + if (ok) colorBranch (c);
1.2659 + }
1.2660 + /////////////////////////////////////////////////////////////////////
1.2661 + } else if (com=="colorSubtree")
1.2662 + {
1.2663 + if (selection.isEmpty())
1.2664 + {
1.2665 + parser.setError (Aborted,"Nothing selected");
1.2666 + } else if (! selb )
1.2667 + {
1.2668 + parser.setError (Aborted,"Type of selection is not a branch");
1.2669 + } else if (parser.checkParCount(1))
1.2670 + {
1.2671 + QColor c=parser.parColor (ok,0);
1.2672 + if (ok) colorSubtree (c);
1.2673 + }
1.2674 + /////////////////////////////////////////////////////////////////////
1.2675 + } else if (com=="copy")
1.2676 + {
1.2677 + if (selection.isEmpty())
1.2678 + {
1.2679 + parser.setError (Aborted,"Nothing selected");
1.2680 + } else if (! selb )
1.2681 + {
1.2682 + parser.setError (Aborted,"Type of selection is not a branch");
1.2683 + } else if (parser.checkParCount(0))
1.2684 + {
1.2685 + //FIXME missing action for copy
1.2686 + }
1.2687 + /////////////////////////////////////////////////////////////////////
1.2688 + } else if (com=="cut")
1.2689 + {
1.2690 + if (selection.isEmpty())
1.2691 + {
1.2692 + parser.setError (Aborted,"Nothing selected");
1.2693 + } else if ( selection.type()!=Selection::Branch &&
1.2694 + selection.type()!=Selection::MapCenter &&
1.2695 + selection.type()!=Selection::FloatImage )
1.2696 + {
1.2697 + parser.setError (Aborted,"Type of selection is not a branch or floatimage");
1.2698 + } else if (parser.checkParCount(0))
1.2699 + {
1.2700 + cut();
1.2701 + }
1.2702 + /////////////////////////////////////////////////////////////////////
1.2703 + } else if (com=="delete")
1.2704 + {
1.2705 + if (selection.isEmpty())
1.2706 + {
1.2707 + parser.setError (Aborted,"Nothing selected");
1.2708 + }
1.2709 + /*else if (selection.type() != Selection::Branch && selection.type() != Selection::FloatImage )
1.2710 + {
1.2711 + parser.setError (Aborted,"Type of selection is wrong.");
1.2712 + }
1.2713 + */
1.2714 + else if (parser.checkParCount(0))
1.2715 + {
1.2716 + deleteSelection();
1.2717 + }
1.2718 + /////////////////////////////////////////////////////////////////////
1.2719 + } else if (com=="deleteKeepChildren")
1.2720 + {
1.2721 + if (selection.isEmpty())
1.2722 + {
1.2723 + parser.setError (Aborted,"Nothing selected");
1.2724 + } else if (! selb )
1.2725 + {
1.2726 + parser.setError (Aborted,"Type of selection is not a branch");
1.2727 + } else if (parser.checkParCount(0))
1.2728 + {
1.2729 + deleteKeepChildren();
1.2730 + }
1.2731 + /////////////////////////////////////////////////////////////////////
1.2732 + } else if (com=="deleteChildren")
1.2733 + {
1.2734 + if (selection.isEmpty())
1.2735 + {
1.2736 + parser.setError (Aborted,"Nothing selected");
1.2737 + } else if (! selb)
1.2738 + {
1.2739 + parser.setError (Aborted,"Type of selection is not a branch");
1.2740 + } else if (parser.checkParCount(0))
1.2741 + {
1.2742 + deleteChildren();
1.2743 + }
1.2744 + /////////////////////////////////////////////////////////////////////
1.2745 + } else if (com=="exportASCII")
1.2746 + {
1.2747 + QString fname="";
1.2748 + ok=true;
1.2749 + if (parser.parCount()>=1)
1.2750 + // Hey, we even have a filename
1.2751 + fname=parser.parString(ok,0);
1.2752 + if (!ok)
1.2753 + {
1.2754 + parser.setError (Aborted,"Could not read filename");
1.2755 + } else
1.2756 + {
1.2757 + exportASCII (fname,false);
1.2758 + }
1.2759 + /////////////////////////////////////////////////////////////////////
1.2760 + } else if (com=="exportImage")
1.2761 + {
1.2762 + QString fname="";
1.2763 + ok=true;
1.2764 + if (parser.parCount()>=2)
1.2765 + // Hey, we even have a filename
1.2766 + fname=parser.parString(ok,0);
1.2767 + if (!ok)
1.2768 + {
1.2769 + parser.setError (Aborted,"Could not read filename");
1.2770 + } else
1.2771 + {
1.2772 + QString format="PNG";
1.2773 + if (parser.parCount()>=2)
1.2774 + {
1.2775 + format=parser.parString(ok,1);
1.2776 + }
1.2777 + exportImage (fname,false,format);
1.2778 + }
1.2779 + /////////////////////////////////////////////////////////////////////
1.2780 + } else if (com=="exportXHTML")
1.2781 + {
1.2782 + QString fname="";
1.2783 + ok=true;
1.2784 + if (parser.parCount()>=2)
1.2785 + // Hey, we even have a filename
1.2786 + fname=parser.parString(ok,1);
1.2787 + if (!ok)
1.2788 + {
1.2789 + parser.setError (Aborted,"Could not read filename");
1.2790 + } else
1.2791 + {
1.2792 + exportXHTML (fname,false);
1.2793 + }
1.2794 + /////////////////////////////////////////////////////////////////////
1.2795 + } else if (com=="exportXML")
1.2796 + {
1.2797 + QString fname="";
1.2798 + ok=true;
1.2799 + if (parser.parCount()>=2)
1.2800 + // Hey, we even have a filename
1.2801 + fname=parser.parString(ok,1);
1.2802 + if (!ok)
1.2803 + {
1.2804 + parser.setError (Aborted,"Could not read filename");
1.2805 + } else
1.2806 + {
1.2807 + exportXML (fname,false);
1.2808 + }
1.2809 + /////////////////////////////////////////////////////////////////////
1.2810 + } else if (com=="importDir")
1.2811 + {
1.2812 + if (selection.isEmpty())
1.2813 + {
1.2814 + parser.setError (Aborted,"Nothing selected");
1.2815 + } else if (! selb )
1.2816 + {
1.2817 + parser.setError (Aborted,"Type of selection is not a branch");
1.2818 + } else if (parser.checkParCount(1))
1.2819 + {
1.2820 + s=parser.parString(ok,0);
1.2821 + if (ok) importDirInt(s);
1.2822 + }
1.2823 + /////////////////////////////////////////////////////////////////////
1.2824 + } else if (com=="linkTo")
1.2825 + {
1.2826 + if (selection.isEmpty())
1.2827 + {
1.2828 + parser.setError (Aborted,"Nothing selected");
1.2829 + } else if ( selb)
1.2830 + {
1.2831 + if (parser.checkParCount(4))
1.2832 + {
1.2833 + // 0 selectstring of parent
1.2834 + // 1 num in parent (for branches)
1.2835 + // 2,3 x,y of mainbranch or mapcenter
1.2836 + s=parser.parString(ok,0);
1.2837 + LinkableMapObj *dst=findObjBySelect (s);
1.2838 + if (dst)
1.2839 + {
1.2840 + if (typeid(*dst) == typeid(BranchObj) )
1.2841 + {
1.2842 + // Get number in parent
1.2843 + n=parser.parInt (ok,1);
1.2844 + if (ok)
1.2845 + {
1.2846 + selb->linkTo ((BranchObj*)(dst),n);
1.2847 + selection.update();
1.2848 + }
1.2849 + } else if (typeid(*dst) == typeid(MapCenterObj) )
1.2850 + {
1.2851 + selb->linkTo ((BranchObj*)(dst),-1);
1.2852 + // Get coordinates of mainbranch
1.2853 + x=parser.parDouble(ok,2);
1.2854 + if (ok)
1.2855 + {
1.2856 + y=parser.parDouble(ok,3);
1.2857 + if (ok)
1.2858 + {
1.2859 + selb->move (x,y);
1.2860 + selection.update();
1.2861 + }
1.2862 + }
1.2863 + }
1.2864 + }
1.2865 + }
1.2866 + } else if ( selection.type() == Selection::FloatImage)
1.2867 + {
1.2868 + if (parser.checkParCount(1))
1.2869 + {
1.2870 + // 0 selectstring of parent
1.2871 + s=parser.parString(ok,0);
1.2872 + LinkableMapObj *dst=findObjBySelect (s);
1.2873 + if (dst)
1.2874 + {
1.2875 + if (typeid(*dst) == typeid(BranchObj) ||
1.2876 + typeid(*dst) == typeid(MapCenterObj))
1.2877 + linkFloatImageTo (getSelectString(dst));
1.2878 + } else
1.2879 + parser.setError (Aborted,"Destination is not a branch");
1.2880 + }
1.2881 + } else
1.2882 + parser.setError (Aborted,"Type of selection is not a floatimage or branch");
1.2883 + /////////////////////////////////////////////////////////////////////
1.2884 + } else if (com=="loadImage")
1.2885 + {
1.2886 + if (selection.isEmpty())
1.2887 + {
1.2888 + parser.setError (Aborted,"Nothing selected");
1.2889 + } else if (! selb )
1.2890 + {
1.2891 + parser.setError (Aborted,"Type of selection is not a branch");
1.2892 + } else if (parser.checkParCount(1))
1.2893 + {
1.2894 + s=parser.parString(ok,0);
1.2895 + if (ok) loadFloatImageInt (s);
1.2896 + }
1.2897 + /////////////////////////////////////////////////////////////////////
1.2898 + } else if (com=="moveBranchUp")
1.2899 + {
1.2900 + if (selection.isEmpty() )
1.2901 + {
1.2902 + parser.setError (Aborted,"Nothing selected");
1.2903 + } else if (! selb )
1.2904 + {
1.2905 + parser.setError (Aborted,"Type of selection is not a branch");
1.2906 + } else if (parser.checkParCount(0))
1.2907 + {
1.2908 + moveBranchUp();
1.2909 + }
1.2910 + /////////////////////////////////////////////////////////////////////
1.2911 + } else if (com=="moveBranchDown")
1.2912 + {
1.2913 + if (selection.isEmpty() )
1.2914 + {
1.2915 + parser.setError (Aborted,"Nothing selected");
1.2916 + } else if (! selb )
1.2917 + {
1.2918 + parser.setError (Aborted,"Type of selection is not a branch");
1.2919 + } else if (parser.checkParCount(0))
1.2920 + {
1.2921 + moveBranchDown();
1.2922 + }
1.2923 + /////////////////////////////////////////////////////////////////////
1.2924 + } else if (com=="move")
1.2925 + {
1.2926 + if (selection.isEmpty() )
1.2927 + {
1.2928 + parser.setError (Aborted,"Nothing selected");
1.2929 + } else if ( selection.type()!=Selection::Branch &&
1.2930 + selection.type()!=Selection::MapCenter &&
1.2931 + selection.type()!=Selection::FloatImage )
1.2932 + {
1.2933 + parser.setError (Aborted,"Type of selection is not a branch or floatimage");
1.2934 + } else if (parser.checkParCount(2))
1.2935 + {
1.2936 + x=parser.parDouble (ok,0);
1.2937 + if (ok)
1.2938 + {
1.2939 + y=parser.parDouble (ok,1);
1.2940 + if (ok) move (x,y);
1.2941 + }
1.2942 + }
1.2943 + /////////////////////////////////////////////////////////////////////
1.2944 + } else if (com=="moveRel")
1.2945 + {
1.2946 + if (selection.isEmpty() )
1.2947 + {
1.2948 + parser.setError (Aborted,"Nothing selected");
1.2949 + } else if ( selection.type()!=Selection::Branch &&
1.2950 + selection.type()!=Selection::MapCenter &&
1.2951 + selection.type()!=Selection::FloatImage )
1.2952 + {
1.2953 + parser.setError (Aborted,"Type of selection is not a branch or floatimage");
1.2954 + } else if (parser.checkParCount(2))
1.2955 + {
1.2956 + x=parser.parDouble (ok,0);
1.2957 + if (ok)
1.2958 + {
1.2959 + y=parser.parDouble (ok,1);
1.2960 + if (ok) moveRel (x,y);
1.2961 + }
1.2962 + }
1.2963 + /////////////////////////////////////////////////////////////////////
1.2964 + } else if (com=="nop")
1.2965 + {
1.2966 + /////////////////////////////////////////////////////////////////////
1.2967 + } else if (com=="paste")
1.2968 + {
1.2969 + if (selection.isEmpty() )
1.2970 + {
1.2971 + parser.setError (Aborted,"Nothing selected");
1.2972 + } else if (! selb )
1.2973 + {
1.2974 + parser.setError (Aborted,"Type of selection is not a branch");
1.2975 + } else if (parser.checkParCount(1))
1.2976 + {
1.2977 + n=parser.parInt (ok,0);
1.2978 + if (ok) pasteNoSave(n);
1.2979 + }
1.2980 + /////////////////////////////////////////////////////////////////////
1.2981 + } else if (com=="qa")
1.2982 + {
1.2983 + if (selection.isEmpty() )
1.2984 + {
1.2985 + parser.setError (Aborted,"Nothing selected");
1.2986 + } else if (! selb )
1.2987 + {
1.2988 + parser.setError (Aborted,"Type of selection is not a branch");
1.2989 + } else if (parser.checkParCount(4))
1.2990 + {
1.2991 + QString c,u;
1.2992 + c=parser.parString (ok,0);
1.2993 + if (!ok)
1.2994 + {
1.2995 + parser.setError (Aborted,"No comment given");
1.2996 + } else
1.2997 + {
1.2998 + s=parser.parString (ok,1);
1.2999 + if (!ok)
1.3000 + {
1.3001 + parser.setError (Aborted,"First parameter is not a string");
1.3002 + } else
1.3003 + {
1.3004 + t=parser.parString (ok,2);
1.3005 + if (!ok)
1.3006 + {
1.3007 + parser.setError (Aborted,"Condition is not a string");
1.3008 + } else
1.3009 + {
1.3010 + u=parser.parString (ok,3);
1.3011 + if (!ok)
1.3012 + {
1.3013 + parser.setError (Aborted,"Third parameter is not a string");
1.3014 + } else
1.3015 + {
1.3016 + if (s!="heading")
1.3017 + {
1.3018 + parser.setError (Aborted,"Unknown type: "+s);
1.3019 + } else
1.3020 + {
1.3021 + if (! (t=="eq") )
1.3022 + {
1.3023 + parser.setError (Aborted,"Unknown operator: "+t);
1.3024 + } else
1.3025 + {
1.3026 + if (! selb )
1.3027 + {
1.3028 + parser.setError (Aborted,"Type of selection is not a branch");
1.3029 + } else
1.3030 + {
1.3031 + if (selb->getHeading() == u)
1.3032 + {
1.3033 + cout << "PASSED: " << qPrintable (c) << endl;
1.3034 + } else
1.3035 + {
1.3036 + cout << "FAILED: " << qPrintable (c) << endl;
1.3037 + }
1.3038 + }
1.3039 + }
1.3040 + }
1.3041 + }
1.3042 + }
1.3043 + }
1.3044 + }
1.3045 + }
1.3046 + /////////////////////////////////////////////////////////////////////
1.3047 + } else if (com=="saveImage")
1.3048 + {
1.3049 + FloatImageObj *fio=selection.getFloatImage();
1.3050 + if (!fio)
1.3051 + {
1.3052 + parser.setError (Aborted,"Type of selection is not an image");
1.3053 + } else if (parser.checkParCount(2))
1.3054 + {
1.3055 + s=parser.parString(ok,0);
1.3056 + if (ok)
1.3057 + {
1.3058 + t=parser.parString(ok,1);
1.3059 + if (ok) saveFloatImageInt (fio,t,s);
1.3060 + }
1.3061 + }
1.3062 + /////////////////////////////////////////////////////////////////////
1.3063 + } else if (com=="scroll")
1.3064 + {
1.3065 + if (selection.isEmpty() )
1.3066 + {
1.3067 + parser.setError (Aborted,"Nothing selected");
1.3068 + } else if (! selb )
1.3069 + {
1.3070 + parser.setError (Aborted,"Type of selection is not a branch");
1.3071 + } else if (parser.checkParCount(0))
1.3072 + {
1.3073 + if (!scrollBranch (selb))
1.3074 + parser.setError (Aborted,"Could not scroll branch");
1.3075 + }
1.3076 + /////////////////////////////////////////////////////////////////////
1.3077 + } else if (com=="select")
1.3078 + {
1.3079 + if (parser.checkParCount(1))
1.3080 + {
1.3081 + s=parser.parString(ok,0);
1.3082 + if (ok) select (s);
1.3083 + }
1.3084 + /////////////////////////////////////////////////////////////////////
1.3085 + } else if (com=="selectLastBranch")
1.3086 + {
1.3087 + if (selection.isEmpty() )
1.3088 + {
1.3089 + parser.setError (Aborted,"Nothing selected");
1.3090 + } else if (! selb )
1.3091 + {
1.3092 + parser.setError (Aborted,"Type of selection is not a branch");
1.3093 + } else if (parser.checkParCount(0))
1.3094 + {
1.3095 + BranchObj *bo=selb->getLastBranch();
1.3096 + if (!bo)
1.3097 + parser.setError (Aborted,"Could not select last branch");
1.3098 + selectInt (bo);
1.3099 +
1.3100 + }
1.3101 + /////////////////////////////////////////////////////////////////////
1.3102 + } else if (com=="selectLastImage")
1.3103 + {
1.3104 + if (selection.isEmpty() )
1.3105 + {
1.3106 + parser.setError (Aborted,"Nothing selected");
1.3107 + } else if (! selb )
1.3108 + {
1.3109 + parser.setError (Aborted,"Type of selection is not a branch");
1.3110 + } else if (parser.checkParCount(0))
1.3111 + {
1.3112 + FloatImageObj *fio=selb->getLastFloatImage();
1.3113 + if (!fio)
1.3114 + parser.setError (Aborted,"Could not select last image");
1.3115 + selectInt (fio);
1.3116 +
1.3117 + }
1.3118 + /////////////////////////////////////////////////////////////////////
1.3119 + } else if (com=="selectLatestAdded")
1.3120 + {
1.3121 + if (latestSelectionString.isEmpty() )
1.3122 + {
1.3123 + parser.setError (Aborted,"No latest added object");
1.3124 + } else
1.3125 + {
1.3126 + if (!select (latestSelectionString))
1.3127 + parser.setError (Aborted,"Could not select latest added object "+latestSelectionString);
1.3128 + }
1.3129 + /////////////////////////////////////////////////////////////////////
1.3130 + } else if (com=="setFrameType")
1.3131 + {
1.3132 + if ( selection.type()!=Selection::Branch && selection.type()!= Selection::MapCenter && selection.type()!=Selection::FloatImage)
1.3133 + {
1.3134 + parser.setError (Aborted,"Type of selection does not allow setting frame type");
1.3135 + }
1.3136 + else if (parser.checkParCount(1))
1.3137 + {
1.3138 + s=parser.parString(ok,0);
1.3139 + if (ok) setFrameType (s);
1.3140 + }
1.3141 + /////////////////////////////////////////////////////////////////////
1.3142 + } else if (com=="setFramePenColor")
1.3143 + {
1.3144 + if ( selection.type()!=Selection::Branch && selection.type()!= Selection::MapCenter && selection.type()!=Selection::FloatImage)
1.3145 + {
1.3146 + parser.setError (Aborted,"Type of selection does not allow setting of pen color");
1.3147 + }
1.3148 + else if (parser.checkParCount(1))
1.3149 + {
1.3150 + QColor c=parser.parColor(ok,0);
1.3151 + if (ok) setFramePenColor (c);
1.3152 + }
1.3153 + /////////////////////////////////////////////////////////////////////
1.3154 + } else if (com=="setFrameBrushColor")
1.3155 + {
1.3156 + if ( selection.type()!=Selection::Branch && selection.type()!= Selection::MapCenter && selection.type()!=Selection::FloatImage)
1.3157 + {
1.3158 + parser.setError (Aborted,"Type of selection does not allow setting brush color");
1.3159 + }
1.3160 + else if (parser.checkParCount(1))
1.3161 + {
1.3162 + QColor c=parser.parColor(ok,0);
1.3163 + if (ok) setFrameBrushColor (c);
1.3164 + }
1.3165 + /////////////////////////////////////////////////////////////////////
1.3166 + } else if (com=="setFramePadding")
1.3167 + {
1.3168 + if ( selection.type()!=Selection::Branch && selection.type()!= Selection::MapCenter && selection.type()!=Selection::FloatImage)
1.3169 + {
1.3170 + parser.setError (Aborted,"Type of selection does not allow setting frame padding");
1.3171 + }
1.3172 + else if (parser.checkParCount(1))
1.3173 + {
1.3174 + n=parser.parInt(ok,0);
1.3175 + if (ok) setFramePadding(n);
1.3176 + }
1.3177 + /////////////////////////////////////////////////////////////////////
1.3178 + } else if (com=="setFrameBorderWidth")
1.3179 + {
1.3180 + if ( selection.type()!=Selection::Branch && selection.type()!= Selection::MapCenter && selection.type()!=Selection::FloatImage)
1.3181 + {
1.3182 + parser.setError (Aborted,"Type of selection does not allow setting frame border width");
1.3183 + }
1.3184 + else if (parser.checkParCount(1))
1.3185 + {
1.3186 + n=parser.parInt(ok,0);
1.3187 + if (ok) setFrameBorderWidth (n);
1.3188 + }
1.3189 + /////////////////////////////////////////////////////////////////////
1.3190 + } else if (com=="setMapAuthor")
1.3191 + {
1.3192 + if (parser.checkParCount(1))
1.3193 + {
1.3194 + s=parser.parString(ok,0);
1.3195 + if (ok) setAuthor (s);
1.3196 + }
1.3197 + /////////////////////////////////////////////////////////////////////
1.3198 + } else if (com=="setMapComment")
1.3199 + {
1.3200 + if (parser.checkParCount(1))
1.3201 + {
1.3202 + s=parser.parString(ok,0);
1.3203 + if (ok) setComment(s);
1.3204 + }
1.3205 + /////////////////////////////////////////////////////////////////////
1.3206 + } else if (com=="setMapBackgroundColor")
1.3207 + {
1.3208 + if (selection.isEmpty() )
1.3209 + {
1.3210 + parser.setError (Aborted,"Nothing selected");
1.3211 + } else if (! selection.getBranch() )
1.3212 + {
1.3213 + parser.setError (Aborted,"Type of selection is not a branch");
1.3214 + } else if (parser.checkParCount(1))
1.3215 + {
1.3216 + QColor c=parser.parColor (ok,0);
1.3217 + if (ok) setMapBackgroundColor (c);
1.3218 + }
1.3219 + /////////////////////////////////////////////////////////////////////
1.3220 + } else if (com=="setMapDefLinkColor")
1.3221 + {
1.3222 + if (selection.isEmpty() )
1.3223 + {
1.3224 + parser.setError (Aborted,"Nothing selected");
1.3225 + } else if (! selb )
1.3226 + {
1.3227 + parser.setError (Aborted,"Type of selection is not a branch");
1.3228 + } else if (parser.checkParCount(1))
1.3229 + {
1.3230 + QColor c=parser.parColor (ok,0);
1.3231 + if (ok) setMapDefLinkColor (c);
1.3232 + }
1.3233 + /////////////////////////////////////////////////////////////////////
1.3234 + } else if (com=="setMapLinkStyle")
1.3235 + {
1.3236 + if (parser.checkParCount(1))
1.3237 + {
1.3238 + s=parser.parString (ok,0);
1.3239 + if (ok) setMapLinkStyle(s);
1.3240 + }
1.3241 + /////////////////////////////////////////////////////////////////////
1.3242 + } else if (com=="setHeading")
1.3243 + {
1.3244 + if (selection.isEmpty() )
1.3245 + {
1.3246 + parser.setError (Aborted,"Nothing selected");
1.3247 + } else if (! selb )
1.3248 + {
1.3249 + parser.setError (Aborted,"Type of selection is not a branch");
1.3250 + } else if (parser.checkParCount(1))
1.3251 + {
1.3252 + s=parser.parString (ok,0);
1.3253 + if (ok)
1.3254 + setHeading (s);
1.3255 + }
1.3256 + /////////////////////////////////////////////////////////////////////
1.3257 + } else if (com=="setHideExport")
1.3258 + {
1.3259 + if (selection.isEmpty() )
1.3260 + {
1.3261 + parser.setError (Aborted,"Nothing selected");
1.3262 + } else if (selection.type()!=Selection::Branch && selection.type() != Selection::MapCenter &&selection.type()!=Selection::FloatImage)
1.3263 + {
1.3264 + parser.setError (Aborted,"Type of selection is not a branch or floatimage");
1.3265 + } else if (parser.checkParCount(1))
1.3266 + {
1.3267 + b=parser.parBool(ok,0);
1.3268 + if (ok) setHideExport (b);
1.3269 + }
1.3270 + /////////////////////////////////////////////////////////////////////
1.3271 + } else if (com=="setIncludeImagesHorizontally")
1.3272 + {
1.3273 + if (selection.isEmpty() )
1.3274 + {
1.3275 + parser.setError (Aborted,"Nothing selected");
1.3276 + } else if (! selb)
1.3277 + {
1.3278 + parser.setError (Aborted,"Type of selection is not a branch");
1.3279 + } else if (parser.checkParCount(1))
1.3280 + {
1.3281 + b=parser.parBool(ok,0);
1.3282 + if (ok) setIncludeImagesHor(b);
1.3283 + }
1.3284 + /////////////////////////////////////////////////////////////////////
1.3285 + } else if (com=="setIncludeImagesVertically")
1.3286 + {
1.3287 + if (selection.isEmpty() )
1.3288 + {
1.3289 + parser.setError (Aborted,"Nothing selected");
1.3290 + } else if (! selb)
1.3291 + {
1.3292 + parser.setError (Aborted,"Type of selection is not a branch");
1.3293 + } else if (parser.checkParCount(1))
1.3294 + {
1.3295 + b=parser.parBool(ok,0);
1.3296 + if (ok) setIncludeImagesVer(b);
1.3297 + }
1.3298 + /////////////////////////////////////////////////////////////////////
1.3299 + } else if (com=="setHideLinkUnselected")
1.3300 + {
1.3301 + if (selection.isEmpty() )
1.3302 + {
1.3303 + parser.setError (Aborted,"Nothing selected");
1.3304 + } else if ( selection.type()!=Selection::Branch && selection.type()!= Selection::MapCenter && selection.type()!=Selection::FloatImage)
1.3305 + {
1.3306 + parser.setError (Aborted,"Type of selection does not allow hiding the link");
1.3307 + } else if (parser.checkParCount(1))
1.3308 + {
1.3309 + b=parser.parBool(ok,0);
1.3310 + if (ok) setHideLinkUnselected(b);
1.3311 + }
1.3312 + /////////////////////////////////////////////////////////////////////
1.3313 + } else if (com=="setSelectionColor")
1.3314 + {
1.3315 + if (parser.checkParCount(1))
1.3316 + {
1.3317 + QColor c=parser.parColor (ok,0);
1.3318 + if (ok) setSelectionColorInt (c);
1.3319 + }
1.3320 + /////////////////////////////////////////////////////////////////////
1.3321 + } else if (com=="setURL")
1.3322 + {
1.3323 + if (selection.isEmpty() )
1.3324 + {
1.3325 + parser.setError (Aborted,"Nothing selected");
1.3326 + } else if (! selb )
1.3327 + {
1.3328 + parser.setError (Aborted,"Type of selection is not a branch");
1.3329 + } else if (parser.checkParCount(1))
1.3330 + {
1.3331 + s=parser.parString (ok,0);
1.3332 + if (ok) setURL(s);
1.3333 + }
1.3334 + /////////////////////////////////////////////////////////////////////
1.3335 + } else if (com=="setVymLink")
1.3336 + {
1.3337 + if (selection.isEmpty() )
1.3338 + {
1.3339 + parser.setError (Aborted,"Nothing selected");
1.3340 + } else if (! selb )
1.3341 + {
1.3342 + parser.setError (Aborted,"Type of selection is not a branch");
1.3343 + } else if (parser.checkParCount(1))
1.3344 + {
1.3345 + s=parser.parString (ok,0);
1.3346 + if (ok) setVymLink(s);
1.3347 + }
1.3348 + }
1.3349 + /////////////////////////////////////////////////////////////////////
1.3350 + else if (com=="setFlag")
1.3351 + {
1.3352 + if (selection.isEmpty() )
1.3353 + {
1.3354 + parser.setError (Aborted,"Nothing selected");
1.3355 + } else if (! selb )
1.3356 + {
1.3357 + parser.setError (Aborted,"Type of selection is not a branch");
1.3358 + } else if (parser.checkParCount(1))
1.3359 + {
1.3360 + s=parser.parString(ok,0);
1.3361 + if (ok)
1.3362 + {
1.3363 + selb->activateStandardFlag(s);
1.3364 + selb->updateFlagsToolbar();
1.3365 + }
1.3366 + }
1.3367 + /////////////////////////////////////////////////////////////////////
1.3368 + } else if (com=="setFrameType")
1.3369 + {
1.3370 + if (selection.isEmpty() )
1.3371 + {
1.3372 + parser.setError (Aborted,"Nothing selected");
1.3373 + } else if (! selb )
1.3374 + {
1.3375 + parser.setError (Aborted,"Type of selection is not a branch");
1.3376 + } else if (parser.checkParCount(1))
1.3377 + {
1.3378 + s=parser.parString(ok,0);
1.3379 + if (ok)
1.3380 + setFrameType (s);
1.3381 + }
1.3382 + /////////////////////////////////////////////////////////////////////
1.3383 + } else if (com=="sortChildren")
1.3384 + {
1.3385 + if (selection.isEmpty() )
1.3386 + {
1.3387 + parser.setError (Aborted,"Nothing selected");
1.3388 + } else if (! selb )
1.3389 + {
1.3390 + parser.setError (Aborted,"Type of selection is not a branch");
1.3391 + } else if (parser.checkParCount(0))
1.3392 + {
1.3393 + sortChildren();
1.3394 + }
1.3395 + /////////////////////////////////////////////////////////////////////
1.3396 + } else if (com=="toggleFlag")
1.3397 + {
1.3398 + if (selection.isEmpty() )
1.3399 + {
1.3400 + parser.setError (Aborted,"Nothing selected");
1.3401 + } else if (! selb )
1.3402 + {
1.3403 + parser.setError (Aborted,"Type of selection is not a branch");
1.3404 + } else if (parser.checkParCount(1))
1.3405 + {
1.3406 + s=parser.parString(ok,0);
1.3407 + if (ok)
1.3408 + {
1.3409 + selb->toggleStandardFlag(s);
1.3410 + selb->updateFlagsToolbar();
1.3411 + }
1.3412 + }
1.3413 + /////////////////////////////////////////////////////////////////////
1.3414 + } else if (com=="unscroll")
1.3415 + {
1.3416 + if (selection.isEmpty() )
1.3417 + {
1.3418 + parser.setError (Aborted,"Nothing selected");
1.3419 + } else if (! selb )
1.3420 + {
1.3421 + parser.setError (Aborted,"Type of selection is not a branch");
1.3422 + } else if (parser.checkParCount(0))
1.3423 + {
1.3424 + if (!unscrollBranch (selb))
1.3425 + parser.setError (Aborted,"Could not unscroll branch");
1.3426 + }
1.3427 + /////////////////////////////////////////////////////////////////////
1.3428 + } else if (com=="unscrollChildren")
1.3429 + {
1.3430 + if (selection.isEmpty() )
1.3431 + {
1.3432 + parser.setError (Aborted,"Nothing selected");
1.3433 + } else if (! selb )
1.3434 + {
1.3435 + parser.setError (Aborted,"Type of selection is not a branch");
1.3436 + } else if (parser.checkParCount(0))
1.3437 + {
1.3438 + unscrollChildren ();
1.3439 + }
1.3440 + /////////////////////////////////////////////////////////////////////
1.3441 + } else if (com=="unsetFlag")
1.3442 + {
1.3443 + if (selection.isEmpty() )
1.3444 + {
1.3445 + parser.setError (Aborted,"Nothing selected");
1.3446 + } else if (! selb )
1.3447 + {
1.3448 + parser.setError (Aborted,"Type of selection is not a branch");
1.3449 + } else if (parser.checkParCount(1))
1.3450 + {
1.3451 + s=parser.parString(ok,0);
1.3452 + if (ok)
1.3453 + {
1.3454 + selb->deactivateStandardFlag(s);
1.3455 + selb->updateFlagsToolbar();
1.3456 + }
1.3457 + }
1.3458 + } else
1.3459 + parser.setError (Aborted,"Unknown command");
1.3460 +
1.3461 + // Any errors?
1.3462 + if (parser.errorLevel()==NoError)
1.3463 + {
1.3464 + // setChanged(); FIXME should not be called e.g. for export?!
1.3465 + reposition();
1.3466 + }
1.3467 + else
1.3468 + {
1.3469 + // TODO Error handling
1.3470 + qWarning("VymModel::parseAtom: Error!");
1.3471 + qWarning(parser.errorMessage());
1.3472 + }
1.3473 +}
1.3474 +
1.3475 +void VymModel::runScript (QString script)
1.3476 +{
1.3477 + parser.setScript (script);
1.3478 + parser.runScript();
1.3479 + while (parser.next() )
1.3480 + parseAtom(parser.getAtom());
1.3481 +}
1.3482 +
1.3483 +void VymModel::setExportMode (bool b)
1.3484 +{
1.3485 + // should be called before and after exports
1.3486 + // depending on the settings
1.3487 + if (b && settings.value("/export/useHideExport","true")=="true")
1.3488 + setHideTmpMode (HideExport);
1.3489 + else
1.3490 + setHideTmpMode (HideNone);
1.3491 +}
1.3492 +
1.3493 +void VymModel::exportImage(QString fname, bool askName, QString format)
1.3494 +{
1.3495 + if (fname=="")
1.3496 + {
1.3497 + fname=getMapName()+".png";
1.3498 + format="PNG";
1.3499 + }
1.3500 +
1.3501 + if (askName)
1.3502 + {
1.3503 + QStringList fl;
1.3504 + QFileDialog *fd=new QFileDialog (NULL);
1.3505 + fd->setCaption (tr("Export map as image"));
1.3506 + fd->setDirectory (lastImageDir);
1.3507 + fd->setFileMode(QFileDialog::AnyFile);
1.3508 + fd->setFilters (imageIO.getFilters() );
1.3509 + if (fd->exec())
1.3510 + {
1.3511 + fl=fd->selectedFiles();
1.3512 + fname=fl.first();
1.3513 + format=imageIO.getType(fd->selectedFilter());
1.3514 + }
1.3515 + }
1.3516 +
1.3517 + setExportMode (true);
1.3518 + QPixmap pix (getPixmap());
1.3519 + pix.save(fname, format);
1.3520 + setExportMode (false);
1.3521 +}
1.3522 +
1.3523 +
1.3524 +void VymModel::exportXML(QString dir, bool askForName)
1.3525 +{
1.3526 + if (askForName)
1.3527 + {
1.3528 + dir=browseDirectory(NULL,tr("Export XML to directory"));
1.3529 + if (dir =="" && !reallyWriteDirectory(dir) )
1.3530 + return;
1.3531 + }
1.3532 +
1.3533 + // Hide stuff during export, if settings want this
1.3534 + setExportMode (true);
1.3535 +
1.3536 + // Create subdirectories
1.3537 + makeSubDirs (dir);
1.3538 +
1.3539 + // write to directory
1.3540 + QString saveFile=saveToDir (dir,mapName+"-",true,getTotalBBox().topLeft() ,NULL);
1.3541 + QFile file;
1.3542 +
1.3543 + file.setName ( dir + "/"+mapName+".xml");
1.3544 + if ( !file.open( QIODevice::WriteOnly ) )
1.3545 + {
1.3546 + // This should neverever happen
1.3547 + QMessageBox::critical (0,tr("Critical Export Error"),tr("VymModel::exportXML couldn't open %1").arg(file.name()));
1.3548 + return;
1.3549 + }
1.3550 +
1.3551 + // Write it finally, and write in UTF8, no matter what
1.3552 + QTextStream ts( &file );
1.3553 + ts.setEncoding (QTextStream::UnicodeUTF8);
1.3554 + ts << saveFile;
1.3555 + file.close();
1.3556 +
1.3557 + // Now write image, too
1.3558 + exportImage (dir+"/images/"+mapName+".png",false,"PNG");
1.3559 +
1.3560 + setExportMode (false);
1.3561 +}
1.3562 +
1.3563 +void VymModel::exportASCII(QString fname,bool askName)
1.3564 +{
1.3565 + ExportASCII ex;
1.3566 + ex.setModel (this);
1.3567 + if (fname=="")
1.3568 + ex.setFile (mapName+".txt");
1.3569 + else
1.3570 + ex.setFile (fname);
1.3571 +
1.3572 + if (askName)
1.3573 + {
1.3574 + //ex.addFilter ("TXT (*.txt)");
1.3575 + ex.setDir(lastImageDir);
1.3576 + //ex.setCaption(vymName+ " -" +tr("Export as ASCII")+" "+tr("(still experimental)"));
1.3577 + ex.execDialog() ;
1.3578 + }
1.3579 + if (!ex.canceled())
1.3580 + {
1.3581 + setExportMode(true);
1.3582 + ex.doExport();
1.3583 + setExportMode(false);
1.3584 + }
1.3585 +}
1.3586 +
1.3587 +void VymModel::exportXHTML (const QString &dir, bool askForName)
1.3588 +{
1.3589 + ExportXHTMLDialog dia(NULL);
1.3590 + dia.setFilePath (filePath );
1.3591 + dia.setMapName (mapName );
1.3592 + dia.readSettings();
1.3593 + if (dir!="") dia.setDir (dir);
1.3594 +
1.3595 + bool ok=true;
1.3596 +
1.3597 + if (askForName)
1.3598 + {
1.3599 + if (dia.exec()!=QDialog::Accepted)
1.3600 + ok=false;
1.3601 + else
1.3602 + {
1.3603 + QDir d (dia.getDir());
1.3604 + // Check, if warnings should be used before overwriting
1.3605 + // the output directory
1.3606 + if (d.exists() && d.count()>0)
1.3607 + {
1.3608 + WarningDialog warn;
1.3609 + warn.showCancelButton (true);
1.3610 + warn.setText(QString(
1.3611 + "The directory %1 is not empty.\n"
1.3612 + "Do you risk to overwrite some of its contents?").arg(d.path() ));
1.3613 + warn.setCaption("Warning: Directory not empty");
1.3614 + warn.setShowAgainName("mainwindow/overwrite-dir-xhtml");
1.3615 +
1.3616 + if (warn.exec()!=QDialog::Accepted) ok=false;
1.3617 + }
1.3618 + }
1.3619 + }
1.3620 +
1.3621 + if (ok)
1.3622 + {
1.3623 + exportXML (dia.getDir(),false );
1.3624 + dia.doExport(mapName );
1.3625 + //if (dia.hasChanged()) setChanged();
1.3626 + }
1.3627 +}
1.3628 +
1.3629 +void VymModel::exportOOPresentation(const QString &fn, const QString &cf)
1.3630 +{
1.3631 + ExportOO ex;
1.3632 + ex.setFile (fn);
1.3633 + ex.setModel (this);
1.3634 + if (ex.setConfigFile(cf))
1.3635 + {
1.3636 + setExportMode (true);
1.3637 + ex.exportPresentation();
1.3638 + setExportMode (false);
1.3639 + }
1.3640 +}
1.3641 +
1.3642 +
1.3643 +
1.3644
1.3645 //////////////////////////////////////////////
1.3646 // View related
1.3647 //////////////////////////////////////////////
1.3648
1.3649 +void VymModel::registerEditor(QWidget *)
1.3650 +{
1.3651 +}
1.3652 +
1.3653 +void VymModel::unregisterEditor(QWidget *)
1.3654 +{
1.3655 +}
1.3656 +
1.3657 +void VymModel::updateNoteFlag()
1.3658 +{
1.3659 + setChanged();
1.3660 + BranchObj *bo=selection.getBranch();
1.3661 + if (bo)
1.3662 + {
1.3663 + bo->updateNoteFlag();
1.3664 + mainWindow->updateActions();
1.3665 + }
1.3666 +}
1.3667 +
1.3668 void VymModel::updateRelPositions()
1.3669 {
1.3670 for (int i=0; i<mapCenters.count(); i++)
1.3671 @@ -284,6 +3766,261 @@
1.3672 }
1.3673 }
1.3674
1.3675 +QPixmap VymModel::getPixmap()
1.3676 +{
1.3677 + QRectF mapRect=getTotalBBox();
1.3678 + QPixmap pix((int)mapRect.width()+2,(int)mapRect.height()+1);
1.3679 + QPainter pp (&pix);
1.3680 +
1.3681 + pp.setRenderHints(mapEditor->renderHints());
1.3682 +
1.3683 + // Don't print the visualisation of selection
1.3684 + selection.unselect();
1.3685 +
1.3686 + mapScene->render ( &pp,
1.3687 + QRectF(0,0,mapRect.width()+2,mapRect.height()+2),
1.3688 + QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height() ));
1.3689 +
1.3690 + // Restore selection
1.3691 + selection.reselect();
1.3692 +
1.3693 + return pix;
1.3694 +}
1.3695 +
1.3696 +
1.3697 +void VymModel::setMapLinkStyle (const QString & s)
1.3698 +{
1.3699 + QString snow;
1.3700 + if (linkstyle==LinkableMapObj::Line)
1.3701 + snow="StyleLine";
1.3702 + else if (linkstyle==LinkableMapObj::Parabel)
1.3703 + snow="StyleParabel";
1.3704 + else if (linkstyle==LinkableMapObj::PolyLine)
1.3705 + snow="StylePolyLine";
1.3706 + else if (linkstyle==LinkableMapObj::PolyParabel)
1.3707 + snow="StyleParabel";
1.3708 +
1.3709 + saveState (
1.3710 + QString("setMapLinkStyle (\"%1\")").arg(s),
1.3711 + QString("setMapLinkStyle (\"%1\")").arg(snow),
1.3712 + QString("Set map link style (\"%1\")").arg(s)
1.3713 + );
1.3714 +
1.3715 + if (s=="StyleLine")
1.3716 + linkstyle=LinkableMapObj::Line;
1.3717 + else if (s=="StyleParabel")
1.3718 + linkstyle=LinkableMapObj::Parabel;
1.3719 + else if (s=="StylePolyLine")
1.3720 + linkstyle=LinkableMapObj::PolyLine;
1.3721 + else
1.3722 + linkstyle=LinkableMapObj::PolyParabel;
1.3723 +
1.3724 + BranchObj *bo;
1.3725 + bo=first();
1.3726 + bo=next(bo);
1.3727 + while (bo)
1.3728 + {
1.3729 + bo->setLinkStyle(bo->getDefLinkStyle());
1.3730 + bo=next(bo);
1.3731 + }
1.3732 + reposition();
1.3733 +}
1.3734 +
1.3735 +LinkableMapObj::Style VymModel::getMapLinkStyle ()
1.3736 +{
1.3737 + return linkstyle;
1.3738 +}
1.3739 +
1.3740 +void VymModel::setMapDefLinkColor(QColor col)
1.3741 +{
1.3742 + if ( !col.isValid() ) return;
1.3743 + saveState (
1.3744 + QString("setMapDefLinkColor (\"%1\")").arg(getMapDefLinkColor().name()),
1.3745 + QString("setMapDefLinkColor (\"%1\")").arg(col.name()),
1.3746 + QString("Set map link color to %1").arg(col.name())
1.3747 + );
1.3748 +
1.3749 + defLinkColor=col;
1.3750 + BranchObj *bo;
1.3751 + bo=first();
1.3752 + while (bo)
1.3753 + {
1.3754 + bo->setLinkColor();
1.3755 + bo=next(bo);
1.3756 + }
1.3757 + updateActions();
1.3758 +}
1.3759 +
1.3760 +void VymModel::setMapLinkColorHintInt()
1.3761 +{
1.3762 + // called from setMapLinkColorHint(lch) or at end of parse
1.3763 + BranchObj *bo;
1.3764 + bo=first();
1.3765 + while (bo)
1.3766 + {
1.3767 + bo->setLinkColor();
1.3768 + bo=next(bo);
1.3769 + }
1.3770 +}
1.3771 +
1.3772 +void VymModel::setMapLinkColorHint(LinkableMapObj::ColorHint lch)
1.3773 +{
1.3774 + linkcolorhint=lch;
1.3775 + setMapLinkColorHintInt();
1.3776 +}
1.3777 +
1.3778 +void VymModel::toggleMapLinkColorHint()
1.3779 +{
1.3780 + if (linkcolorhint==LinkableMapObj::HeadingColor)
1.3781 + linkcolorhint=LinkableMapObj::DefaultColor;
1.3782 + else
1.3783 + linkcolorhint=LinkableMapObj::HeadingColor;
1.3784 + BranchObj *bo;
1.3785 + bo=first();
1.3786 + while (bo)
1.3787 + {
1.3788 + bo->setLinkColor();
1.3789 + bo=next(bo);
1.3790 + }
1.3791 +}
1.3792 +
1.3793 +void VymModel::selectMapBackgroundImage ()
1.3794 +{
1.3795 + Q3FileDialog *fd=new Q3FileDialog( NULL);
1.3796 + fd->setMode (Q3FileDialog::ExistingFile);
1.3797 + fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
1.3798 + ImagePreview *p =new ImagePreview (fd);
1.3799 + fd->setContentsPreviewEnabled( TRUE );
1.3800 + fd->setContentsPreview( p, p );
1.3801 + fd->setPreviewMode( Q3FileDialog::Contents );
1.3802 + fd->setCaption(vymName+" - " +tr("Load background image"));
1.3803 + fd->setDir (lastImageDir);
1.3804 + fd->show();
1.3805 +
1.3806 + if ( fd->exec() == QDialog::Accepted )
1.3807 + {
1.3808 + // TODO selectMapBackgroundImg in QT4 use: lastImageDir=fd->directory();
1.3809 + lastImageDir=QDir (fd->dirPath());
1.3810 + setMapBackgroundImage (fd->selectedFile());
1.3811 + }
1.3812 +}
1.3813 +
1.3814 +void VymModel::setMapBackgroundImage (const QString &fn) //FIXME missing savestate
1.3815 +{
1.3816 + QColor oldcol=mapScene->backgroundBrush().color();
1.3817 + /*
1.3818 + saveState(
1.3819 + selection,
1.3820 + QString ("setMapBackgroundImage (%1)").arg(oldcol.name()),
1.3821 + selection,
1.3822 + QString ("setMapBackgroundImage (%1)").arg(col.name()),
1.3823 + QString("Set background color of map to %1").arg(col.name()));
1.3824 + */
1.3825 + QBrush brush;
1.3826 + brush.setTextureImage (QPixmap (fn));
1.3827 + mapScene->setBackgroundBrush(brush);
1.3828 +}
1.3829 +
1.3830 +void VymModel::selectMapBackgroundColor()
1.3831 +{
1.3832 + QColor col = QColorDialog::getColor( mapScene->backgroundBrush().color(), NULL);
1.3833 + if ( !col.isValid() ) return;
1.3834 + setMapBackgroundColor( col );
1.3835 +}
1.3836 +
1.3837 +
1.3838 +void VymModel::setMapBackgroundColor(QColor col)
1.3839 +{
1.3840 + QColor oldcol=mapScene->backgroundBrush().color();
1.3841 + saveState(
1.3842 + QString ("setMapBackgroundColor (\"%1\")").arg(oldcol.name()),
1.3843 + QString ("setMapBackgroundColor (\"%1\")").arg(col.name()),
1.3844 + QString("Set background color of map to %1").arg(col.name()));
1.3845 + mapScene->setBackgroundBrush(col);
1.3846 +}
1.3847 +
1.3848 +QColor VymModel::getMapBackgroundColor()
1.3849 +{
1.3850 + return mapScene->backgroundBrush().color();
1.3851 +}
1.3852 +
1.3853 +
1.3854 +LinkableMapObj::ColorHint VymModel::getMapLinkColorHint()
1.3855 +{
1.3856 + return linkcolorhint;
1.3857 +}
1.3858 +
1.3859 +QColor VymModel::getMapDefLinkColor()
1.3860 +{
1.3861 + return defLinkColor;
1.3862 +}
1.3863 +
1.3864 +void VymModel::setMapDefXLinkColor(QColor col)
1.3865 +{
1.3866 + defXLinkColor=col;
1.3867 +}
1.3868 +
1.3869 +QColor VymModel::getMapDefXLinkColor()
1.3870 +{
1.3871 + return defXLinkColor;
1.3872 +}
1.3873 +
1.3874 +void VymModel::setMapDefXLinkWidth (int w)
1.3875 +{
1.3876 + defXLinkWidth=w;
1.3877 +}
1.3878 +
1.3879 +int VymModel::getMapDefXLinkWidth()
1.3880 +{
1.3881 + return defXLinkWidth;
1.3882 +}
1.3883 +
1.3884 +void VymModel::move(const double &x, const double &y)
1.3885 +{
1.3886 + LinkableMapObj *sel=selection.single();
1.3887 + if (sel)
1.3888 + {
1.3889 + QPointF ap(sel->getAbsPos());
1.3890 + QPointF to(x, y);
1.3891 + if (ap != to)
1.3892 + {
1.3893 + QString ps=qpointfToString(ap);
1.3894 + QString s=selection.getSelectString();
1.3895 + saveState(
1.3896 + s, "move "+ps,
1.3897 + s, "move "+qpointfToString(to),
1.3898 + QString("Move %1 to %2").arg(getObjectName(sel)).arg(ps));
1.3899 + sel->move(x,y);
1.3900 + reposition();
1.3901 + selection.update();
1.3902 + }
1.3903 + }
1.3904 +}
1.3905 +
1.3906 +void VymModel::moveRel (const double &x, const double &y)
1.3907 +{
1.3908 + LinkableMapObj *sel=selection.single();
1.3909 + if (sel)
1.3910 + {
1.3911 + QPointF rp(sel->getRelPos());
1.3912 + QPointF to(x, y);
1.3913 + if (rp != to)
1.3914 + {
1.3915 + QString ps=qpointfToString (sel->getRelPos());
1.3916 + QString s=getSelectString(sel);
1.3917 + saveState(
1.3918 + s, "moveRel "+ps,
1.3919 + s, "moveRel "+qpointfToString(to),
1.3920 + QString("Move %1 to relative position %2").arg(getObjectName(sel)).arg(ps));
1.3921 + ((OrnamentedObj*)sel)->move2RelPos (x,y);
1.3922 + reposition();
1.3923 + sel->updateLink();
1.3924 + selection.update();
1.3925 + }
1.3926 + }
1.3927 +}
1.3928 +
1.3929 +
1.3930 void VymModel::animate()
1.3931 {
1.3932 animationTimer->stop();
1.3933 @@ -294,7 +4031,11 @@
1.3934 bo=(BranchObj*)animObjList.at(i);
1.3935 if (!bo->animate())
1.3936 {
1.3937 - if (i>=0) animObjList.removeAt(i);
1.3938 + if (i>=0)
1.3939 + {
1.3940 + animObjList.removeAt(i);
1.3941 + i--;
1.3942 + }
1.3943 }
1.3944 bo->reposition();
1.3945 i++;
1.3946 @@ -322,26 +4063,640 @@
1.3947 }
1.3948 }
1.3949
1.3950 +void VymModel::sendSelection()
1.3951 +{
1.3952 + if (netstate!=Server) return;
1.3953 + sendData (QString("select (\"%1\")").arg(selection.getSelectString()) );
1.3954 +}
1.3955 +
1.3956 +void VymModel::newServer()
1.3957 +{
1.3958 + port=54321;
1.3959 + sendCounter=0;
1.3960 + tcpServer = new QTcpServer(this);
1.3961 + if (!tcpServer->listen(QHostAddress::Any,port)) {
1.3962 + QMessageBox::critical(NULL, "vym server",
1.3963 + QString("Unable to start the server: %1.").arg(tcpServer->errorString()));
1.3964 + //FIXME needed? we are no widget any longer... close();
1.3965 + return;
1.3966 + }
1.3967 + connect(tcpServer, SIGNAL(newConnection()), this, SLOT(newClient()));
1.3968 + netstate=Server;
1.3969 + cout<<"Server is running on port "<<tcpServer->serverPort()<<endl;
1.3970 +}
1.3971 +
1.3972 +void VymModel::connectToServer()
1.3973 +{
1.3974 + port=54321;
1.3975 + server="salam.suse.de";
1.3976 + server="localhost";
1.3977 + clientSocket = new QTcpSocket (this);
1.3978 + clientSocket->abort();
1.3979 + clientSocket->connectToHost(server ,port);
1.3980 + connect(clientSocket, SIGNAL(readyRead()), this, SLOT(readData()));
1.3981 + connect(clientSocket, SIGNAL(error(QAbstractSocket::SocketError)),
1.3982 + this, SLOT(displayNetworkError(QAbstractSocket::SocketError)));
1.3983 + netstate=Client;
1.3984 + cout<<"connected to "<<qPrintable (server)<<" port "<<port<<endl;
1.3985 +
1.3986 +
1.3987 +}
1.3988 +
1.3989 +void VymModel::newClient()
1.3990 +{
1.3991 + QTcpSocket *newClient = tcpServer->nextPendingConnection();
1.3992 + connect(newClient, SIGNAL(disconnected()),
1.3993 + newClient, SLOT(deleteLater()));
1.3994 +
1.3995 + cout <<"ME::newClient at "<<qPrintable( newClient->peerAddress().toString() )<<endl;
1.3996 +
1.3997 + clientList.append (newClient);
1.3998 +}
1.3999 +
1.4000 +
1.4001 +void VymModel::sendData(const QString &s)
1.4002 +{
1.4003 + if (clientList.size()==0) return;
1.4004 +
1.4005 + // Create bytearray to send
1.4006 + QByteArray block;
1.4007 + QDataStream out(&block, QIODevice::WriteOnly);
1.4008 + out.setVersion(QDataStream::Qt_4_0);
1.4009 +
1.4010 + // Reserve some space for blocksize
1.4011 + out << (quint16)0;
1.4012 +
1.4013 + // Write sendCounter
1.4014 + out << sendCounter++;
1.4015 +
1.4016 + // Write data
1.4017 + out << s;
1.4018 +
1.4019 + // Go back and write blocksize so far
1.4020 + out.device()->seek(0);
1.4021 + quint16 bs=(quint16)(block.size() - 2*sizeof(quint16));
1.4022 + out << bs;
1.4023 +
1.4024 + if (debug)
1.4025 + cout << "ME::sendData bs="<<bs<<" counter="<<sendCounter<<" s="<<qPrintable(s)<<endl;
1.4026 +
1.4027 + for (int i=0; i<clientList.size(); ++i)
1.4028 + {
1.4029 + //cout << "Sending \""<<qPrintable (s)<<"\" to "<<qPrintable (clientList.at(i)->peerAddress().toString())<<endl;
1.4030 + clientList.at(i)->write (block);
1.4031 + }
1.4032 +}
1.4033 +
1.4034 +void VymModel::readData ()
1.4035 +{
1.4036 + while (clientSocket->bytesAvailable() >=(int)sizeof(quint16) )
1.4037 + {
1.4038 + if (debug)
1.4039 + cout <<"readData bytesAvail="<<clientSocket->bytesAvailable();
1.4040 + quint16 recCounter;
1.4041 + quint16 blockSize;
1.4042 +
1.4043 + QDataStream in(clientSocket);
1.4044 + in.setVersion(QDataStream::Qt_4_0);
1.4045 +
1.4046 + in >> blockSize;
1.4047 + in >> recCounter;
1.4048 +
1.4049 + QString t;
1.4050 + in >>t;
1.4051 + if (debug)
1.4052 + cout << " t="<<qPrintable (t)<<endl;
1.4053 + parseAtom (t);
1.4054 + }
1.4055 + return;
1.4056 +}
1.4057 +
1.4058 +void VymModel::displayNetworkError(QAbstractSocket::SocketError socketError)
1.4059 +{
1.4060 + switch (socketError) {
1.4061 + case QAbstractSocket::RemoteHostClosedError:
1.4062 + break;
1.4063 + case QAbstractSocket::HostNotFoundError:
1.4064 + QMessageBox::information(NULL, vymName +" Network client",
1.4065 + "The host was not found. Please check the "
1.4066 + "host name and port settings.");
1.4067 + break;
1.4068 + case QAbstractSocket::ConnectionRefusedError:
1.4069 + QMessageBox::information(NULL, vymName + " Network client",
1.4070 + "The connection was refused by the peer. "
1.4071 + "Make sure the fortune server is running, "
1.4072 + "and check that the host name and port "
1.4073 + "settings are correct.");
1.4074 + break;
1.4075 + default:
1.4076 + QMessageBox::information(NULL, vymName + " Network client",
1.4077 + QString("The following error occurred: %1.")
1.4078 + .arg(clientSocket->errorString()));
1.4079 + }
1.4080 +}
1.4081 +
1.4082 +
1.4083 +
1.4084 +
1.4085 +void VymModel::selectMapSelectionColor()
1.4086 +{
1.4087 + QColor col = QColorDialog::getColor( defLinkColor, NULL);
1.4088 + setSelectionColor (col);
1.4089 +}
1.4090 +
1.4091 +void VymModel::setSelectionColorInt (QColor col)
1.4092 +{
1.4093 + if ( !col.isValid() ) return;
1.4094 + saveState (
1.4095 + QString("setSelectionColor (%1)").arg(selection.getColor().name()),
1.4096 + QString("setSelectionColor (%1)").arg(col.name()),
1.4097 + QString("Set color of selection box to %1").arg(col.name())
1.4098 + );
1.4099 +
1.4100 + selection.setColor (col);
1.4101 +}
1.4102 +
1.4103 +void VymModel::updateSelection()
1.4104 +{
1.4105 + selection.update();
1.4106 +}
1.4107 +
1.4108 +void VymModel::setSelectionColor(QColor col)
1.4109 +{
1.4110 + if ( !col.isValid() ) return;
1.4111 + saveState (
1.4112 + QString("setSelectionColor (%1)").arg(selection.getColor().name()),
1.4113 + QString("setSelectionColor (%1)").arg(col.name()),
1.4114 + QString("Set color of selection box to %1").arg(col.name())
1.4115 + );
1.4116 + setSelectionColorInt (col);
1.4117 +}
1.4118 +
1.4119 +QColor VymModel::getSelectionColor()
1.4120 +{
1.4121 + return selection.getColor();
1.4122 +}
1.4123 +
1.4124 +void VymModel::setHideTmpMode (HideTmpMode mode)
1.4125 +{
1.4126 + hidemode=mode;
1.4127 + for (int i=0;i<mapCenters.count(); i++)
1.4128 + mapCenters.at(i)->setHideTmp (mode);
1.4129 + reposition();
1.4130 + // FIXME needed? scene()->update();
1.4131 +}
1.4132 +
1.4133 +
1.4134 +QRectF VymModel::getTotalBBox()
1.4135 +{
1.4136 + QRectF r;
1.4137 + for (int i=0;i<mapCenters.count(); i++)
1.4138 + r=addBBox (mapCenters.at(i)->getTotalBBox(), r);
1.4139 + return r;
1.4140 +}
1.4141
1.4142 //////////////////////////////////////////////
1.4143 // Selection related
1.4144 //////////////////////////////////////////////
1.4145
1.4146 -
1.4147 -// Only as long as we dont have Model/View yet
1.4148 +void VymModel::setSelectionBlocked (bool b)
1.4149 +{
1.4150 + if (b)
1.4151 + selection.block();
1.4152 + else
1.4153 + selection.unblock();
1.4154 +}
1.4155 +
1.4156 +bool VymModel::isSelectionBlocked()
1.4157 +{
1.4158 + return selection.isBlocked();
1.4159 +}
1.4160 +
1.4161 +bool VymModel::select (const QString &s)
1.4162 +{
1.4163 + if (selection.select(s))
1.4164 + {
1.4165 + selection.update();
1.4166 + ensureSelectionVisible();
1.4167 + sendSelection ();
1.4168 + return true;
1.4169 + }
1.4170 + return false;
1.4171 +
1.4172 +}
1.4173 +
1.4174 +bool VymModel::select (LinkableMapObj *lmo)
1.4175 +{
1.4176 + if (selection.select(lmo))
1.4177 + {
1.4178 + selection.update();
1.4179 + ensureSelectionVisible();
1.4180 + sendSelection ();
1.4181 + return true;
1.4182 + }
1.4183 + return false;
1.4184 +}
1.4185 +
1.4186 +void VymModel::unselect()
1.4187 +{
1.4188 + selection.unselect();
1.4189 +}
1.4190 +
1.4191 +void VymModel::reselect()
1.4192 +{
1.4193 + selection.reselect();
1.4194 +}
1.4195 +
1.4196 +void VymModel::ensureSelectionVisible()
1.4197 +{
1.4198 + LinkableMapObj *lmo=selection.single();
1.4199 + if (lmo &&mapEditor) mapEditor->ensureVisible (lmo->getBBox() );
1.4200 +
1.4201 +}
1.4202 +
1.4203 +void VymModel::selectInt (LinkableMapObj *lmo)
1.4204 +{
1.4205 + if (selection.select(lmo))
1.4206 + {
1.4207 + selection.update();
1.4208 + sendSelection ();
1.4209 + }
1.4210 +}
1.4211 +
1.4212 +
1.4213 +void VymModel::selectNextBranchInt()
1.4214 +{
1.4215 + // Increase number of branch
1.4216 + LinkableMapObj *sel=selection.single();
1.4217 + if (sel)
1.4218 + {
1.4219 + QString s=selection.getSelectString();
1.4220 + QString part;
1.4221 + QString typ;
1.4222 + QString num;
1.4223 +
1.4224 + // Where am I?
1.4225 + part=s.section(",",-1);
1.4226 + typ=part.left (3);
1.4227 + num=part.right(part.length() - 3);
1.4228 +
1.4229 + s=s.left (s.length() -num.length());
1.4230 +
1.4231 + // Go to next lmo
1.4232 + num=QString ("%1").arg(num.toUInt()+1);
1.4233 +
1.4234 + s=s+num;
1.4235 +
1.4236 + // Try to select this one
1.4237 + if (select (s)) return;
1.4238 +
1.4239 + // We have no direct successor,
1.4240 + // try to increase the parental number in order to
1.4241 + // find a successor with same depth
1.4242 +
1.4243 + int d=selection.single()->getDepth();
1.4244 + int oldDepth=d;
1.4245 + int i;
1.4246 + bool found=false;
1.4247 + bool b;
1.4248 + while (!found && d>0)
1.4249 + {
1.4250 + s=s.section (",",0,d-1);
1.4251 + // replace substring of current depth in s with "1"
1.4252 + part=s.section(",",-1);
1.4253 + typ=part.left (3);
1.4254 + num=part.right(part.length() - 3);
1.4255 +
1.4256 + if (d>1)
1.4257 + {
1.4258 + // increase number of parent
1.4259 + num=QString ("%1").arg(num.toUInt()+1);
1.4260 + s=s.section (",",0,d-2) + ","+ typ+num;
1.4261 + } else
1.4262 + {
1.4263 + // Special case, look at orientation
1.4264 + if (selection.single()->getOrientation()==LinkableMapObj::RightOfCenter)
1.4265 + num=QString ("%1").arg(num.toUInt()+1);
1.4266 + else
1.4267 + num=QString ("%1").arg(num.toUInt()-1);
1.4268 + s=typ+num;
1.4269 + }
1.4270 +
1.4271 + if (select (s))
1.4272 + // pad to oldDepth, select the first branch for each depth
1.4273 + for (i=d;i<oldDepth;i++)
1.4274 + {
1.4275 + b=select (s);
1.4276 + if (b)
1.4277 + {
1.4278 + if ( selection.getBranch()->countBranches()>0)
1.4279 + s+=",bo:0";
1.4280 + else
1.4281 + break;
1.4282 + } else
1.4283 + break;
1.4284 + }
1.4285 +
1.4286 + // try to select the freshly built string
1.4287 + found=select(s);
1.4288 + d--;
1.4289 + }
1.4290 + return;
1.4291 + }
1.4292 +}
1.4293 +
1.4294 +void VymModel::selectPrevBranchInt()
1.4295 +{
1.4296 + // Decrease number of branch
1.4297 + BranchObj *bo=selection.getBranch();
1.4298 + if (bo)
1.4299 + {
1.4300 + QString s=selection.getSelectString();
1.4301 + QString part;
1.4302 + QString typ;
1.4303 + QString num;
1.4304 +
1.4305 + // Where am I?
1.4306 + part=s.section(",",-1);
1.4307 + typ=part.left (3);
1.4308 + num=part.right(part.length() - 3);
1.4309 +
1.4310 + s=s.left (s.length() -num.length());
1.4311 +
1.4312 + int n=num.toInt()-1;
1.4313 +
1.4314 + // Go to next lmo
1.4315 + num=QString ("%1").arg(n);
1.4316 + s=s+num;
1.4317 +
1.4318 + // Try to select this one
1.4319 + if (n>=0 && select (s)) return;
1.4320 +
1.4321 + // We have no direct precessor,
1.4322 + // try to decrease the parental number in order to
1.4323 + // find a precessor with same depth
1.4324 +
1.4325 + int d=selection.single()->getDepth();
1.4326 + int oldDepth=d;
1.4327 + int i;
1.4328 + bool found=false;
1.4329 + bool b;
1.4330 + while (!found && d>0)
1.4331 + {
1.4332 + s=s.section (",",0,d-1);
1.4333 + // replace substring of current depth in s with "1"
1.4334 + part=s.section(",",-1);
1.4335 + typ=part.left (3);
1.4336 + num=part.right(part.length() - 3);
1.4337 +
1.4338 + if (d>1)
1.4339 + {
1.4340 + // decrease number of parent
1.4341 + num=QString ("%1").arg(num.toInt()-1);
1.4342 + s=s.section (",",0,d-2) + ","+ typ+num;
1.4343 + } else
1.4344 + {
1.4345 + // Special case, look at orientation
1.4346 + if (selection.single()->getOrientation()==LinkableMapObj::RightOfCenter)
1.4347 + num=QString ("%1").arg(num.toInt()-1);
1.4348 + else
1.4349 + num=QString ("%1").arg(num.toInt()+1);
1.4350 + s=typ+num;
1.4351 + }
1.4352 +
1.4353 + if (select(s))
1.4354 + // pad to oldDepth, select the last branch for each depth
1.4355 + for (i=d;i<oldDepth;i++)
1.4356 + {
1.4357 + b=select (s);
1.4358 + if (b)
1.4359 + if ( selection.getBranch()->countBranches()>0)
1.4360 + s+=",bo:"+ QString ("%1").arg( selection.getBranch()->countBranches()-1 );
1.4361 + else
1.4362 + break;
1.4363 + else
1.4364 + break;
1.4365 + }
1.4366 +
1.4367 + // try to select the freshly built string
1.4368 + found=select(s);
1.4369 + d--;
1.4370 + }
1.4371 + return;
1.4372 + }
1.4373 +}
1.4374 +
1.4375 +void VymModel::selectUpperBranch()
1.4376 +{
1.4377 + if (selection.isBlocked() ) return;
1.4378 +
1.4379 + BranchObj *bo=selection.getBranch();
1.4380 + if (bo && selection.type()==Selection::Branch)
1.4381 + {
1.4382 + if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
1.4383 + selectPrevBranchInt();
1.4384 + else
1.4385 + if (bo->getDepth()==1)
1.4386 + selectNextBranchInt();
1.4387 + else
1.4388 + selectPrevBranchInt();
1.4389 + }
1.4390 +}
1.4391 +
1.4392 +void VymModel::selectLowerBranch()
1.4393 +{
1.4394 + if (selection.isBlocked() ) return;
1.4395 +
1.4396 + BranchObj *bo=selection.getBranch();
1.4397 + if (bo && selection.type()==Selection::Branch)
1.4398 + {
1.4399 + if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
1.4400 + selectNextBranchInt();
1.4401 + else
1.4402 + if (bo->getDepth()==1)
1.4403 + selectPrevBranchInt();
1.4404 + else
1.4405 + selectNextBranchInt();
1.4406 + }
1.4407 +}
1.4408 +
1.4409 +
1.4410 +void VymModel::selectLeftBranch()
1.4411 +{
1.4412 + if (selection.isBlocked() ) return;
1.4413 +
1.4414 + BranchObj* bo;
1.4415 + BranchObj* par;
1.4416 + LinkableMapObj *sel=selection.single();
1.4417 + if (sel)
1.4418 + {
1.4419 + if (selection.type()== Selection::MapCenter)
1.4420 + {
1.4421 + par=selection.getBranch();
1.4422 + bo=par->getLastSelectedBranch();
1.4423 + if (bo)
1.4424 + {
1.4425 + // Workaround for reselecting on left and right side
1.4426 + if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
1.4427 + bo=par->getLastBranch();
1.4428 + if (bo)
1.4429 + {
1.4430 + bo=par->getLastBranch();
1.4431 + selection.select(bo);
1.4432 + selection.update();
1.4433 + ensureSelectionVisible();
1.4434 + sendSelection();
1.4435 + }
1.4436 + }
1.4437 + } else
1.4438 + {
1.4439 + par=(BranchObj*)(sel->getParObj());
1.4440 + if (sel->getOrientation()==LinkableMapObj::RightOfCenter)
1.4441 + {
1.4442 + if (selection.type() == Selection::Branch ||
1.4443 + selection.type() == Selection::FloatImage)
1.4444 + {
1.4445 + selection.select(par);
1.4446 + selection.update();
1.4447 + ensureSelectionVisible();
1.4448 + sendSelection();
1.4449 + }
1.4450 + } else
1.4451 + {
1.4452 + if (selection.type() == Selection::Branch )
1.4453 + {
1.4454 + bo=selection.getBranch()->getLastSelectedBranch();
1.4455 + if (bo)
1.4456 + {
1.4457 + selection.select(bo);
1.4458 + selection.update();
1.4459 + ensureSelectionVisible();
1.4460 + sendSelection();
1.4461 + }
1.4462 + }
1.4463 + }
1.4464 + }
1.4465 + }
1.4466 +}
1.4467 +
1.4468 +void VymModel::selectRightBranch()
1.4469 +{
1.4470 + if (selection.isBlocked() ) return;
1.4471 +
1.4472 + BranchObj* bo;
1.4473 + BranchObj* par;
1.4474 + LinkableMapObj *sel=selection.single();
1.4475 + if (sel)
1.4476 + {
1.4477 + if (selection.type()==Selection::MapCenter)
1.4478 + {
1.4479 + par=selection.getBranch();
1.4480 + bo=par->getLastSelectedBranch();
1.4481 + if (bo)
1.4482 + {
1.4483 + // Workaround for reselecting on left and right side
1.4484 + if (bo->getOrientation()==LinkableMapObj::LeftOfCenter)
1.4485 + bo=par->getFirstBranch();
1.4486 + if (bo)
1.4487 + {
1.4488 + selection.select(bo);
1.4489 + selection.update();
1.4490 + ensureSelectionVisible();
1.4491 + sendSelection();
1.4492 + }
1.4493 + }
1.4494 + } else
1.4495 + {
1.4496 + par=(BranchObj*)(selection.single()->getParObj());
1.4497 + if (selection.single()->getOrientation()==LinkableMapObj::LeftOfCenter)
1.4498 + {
1.4499 + if (selection.type() == Selection::Branch ||
1.4500 + selection.type() == Selection::FloatImage)
1.4501 + {
1.4502 + selection.select(par);
1.4503 + selection.update();
1.4504 + ensureSelectionVisible();
1.4505 + sendSelection();
1.4506 + }
1.4507 + } else
1.4508 + {
1.4509 + if (selection.type() == Selection::Branch)
1.4510 + {
1.4511 + bo=selection.getBranch()->getLastSelectedBranch();
1.4512 + if (bo)
1.4513 + {
1.4514 + selection.select(bo);
1.4515 + selection.update();
1.4516 + ensureSelectionVisible();
1.4517 + sendSelection();
1.4518 + }
1.4519 + }
1.4520 + }
1.4521 + }
1.4522 + }
1.4523 +}
1.4524 +
1.4525 +void VymModel::selectFirstBranch()
1.4526 +{
1.4527 + BranchObj *bo1=selection.getBranch();
1.4528 + BranchObj *bo2;
1.4529 + BranchObj* par;
1.4530 + if (bo1)
1.4531 + {
1.4532 + par=(BranchObj*)(bo1->getParObj());
1.4533 + if (!par) return;
1.4534 + bo2=par->getFirstBranch();
1.4535 + if (bo2) {
1.4536 + selection.select(bo2);
1.4537 + selection.update();
1.4538 + ensureSelectionVisible();
1.4539 + sendSelection();
1.4540 + }
1.4541 + }
1.4542 +}
1.4543 +
1.4544 +void VymModel::selectLastBranch()
1.4545 +{
1.4546 + BranchObj *bo1=selection.getBranch();
1.4547 + BranchObj *bo2;
1.4548 + BranchObj* par;
1.4549 + if (bo1)
1.4550 + {
1.4551 + par=(BranchObj*)(bo1->getParObj());
1.4552 + if (!par) return;
1.4553 + bo2=par->getLastBranch();
1.4554 + if (bo2)
1.4555 + {
1.4556 + selection.select(bo2);
1.4557 + selection.update();
1.4558 + ensureSelectionVisible();
1.4559 + sendSelection();
1.4560 + }
1.4561 + }
1.4562 +}
1.4563 +
1.4564 +Selection::Type VymModel::selectionType()
1.4565 +{
1.4566 + return selection.type();
1.4567 +}
1.4568 +
1.4569 LinkableMapObj* VymModel::getSelection()
1.4570 {
1.4571 - return mapEditor->getSelection();
1.4572 + return selection.single();
1.4573 }
1.4574 BranchObj* VymModel::getSelectedBranch()
1.4575 {
1.4576 - return mapEditor->getSelectedBranch();
1.4577 + return selection.getBranch();
1.4578 }
1.4579
1.4580 -
1.4581 -bool VymModel::select (const QString &s)
1.4582 +FloatImageObj* VymModel::getSelectedFloatImage()
1.4583 {
1.4584 - return mapEditor->select (s);
1.4585 + return selection.getFloatImage();
1.4586 +}
1.4587 +
1.4588 +QString VymModel::getSelectString ()
1.4589 +{
1.4590 + return selection.getSelectString();
1.4591 }
1.4592
1.4593 QString VymModel::getSelectString (LinkableMapObj *lmo)
1.4594 @@ -368,21 +4723,5 @@
1.4595 }
1.4596 }
1.4597 return s;
1.4598 -
1.4599 }
1.4600
1.4601 -
1.4602 -void VymModel::setHideTmp (HideTmpMode mode)
1.4603 -{
1.4604 - for (int i=0;i<mapCenters.count(); i++)
1.4605 - mapCenters.at(i)->setHideTmp (mode);
1.4606 -}
1.4607 -
1.4608 -QRectF VymModel::getTotalBBox()
1.4609 -{
1.4610 - QRectF r;
1.4611 - for (int i=0;i<mapCenters.count(); i++)
1.4612 - r=addBBox (mapCenters.at(i)->getTotalBBox(), r);
1.4613 - return r;
1.4614 -}
1.4615 -