1 #include <QApplication>
6 #include "attributeitem.h"
8 #include "branchitem.h"
10 #include "editxlinkdialog.h"
12 #include "exporthtmldialog.h"
14 #include "findresultmodel.h"
15 #include "mainwindow.h"
20 #include "xlinkitem.h"
22 #include "xml-freemind.h"
28 extern Main *mainWindow;
29 extern QDBusConnection dbusConnection;
31 extern Settings settings;
32 extern QString tmpVymDir;
34 extern TextEditor *textEditor;
35 extern FlagRow *standardFlagsMaster;
37 extern QString clipboardDir;
38 extern QString clipboardFile;
39 extern bool clipboardEmpty;
41 extern ImageIO imageIO;
43 extern QString vymName;
44 extern QString vymVersion;
45 extern QDir vymBaseDir;
47 extern QDir lastImageDir;
48 extern QDir lastFileDir;
50 extern Settings settings;
52 uint VymModel::idLast=0; // make instance
56 //qDebug()<< "Const VymModel";
58 rootItem->setModel (this);
64 //qDebug() << "Destr VymModel begin this="<<this;
65 autosaveTimer->stop();
66 fileChangedTimer->stop();
67 //qApp->processEvents(); // Update view (scene()->update() is not enough)
68 //qDebug() << "Destr VymModel end this="<<this;
71 void VymModel::clear()
73 while (rootItem->childCount() >0)
75 //qDebug()<<"VM::clear ri="<<rootItem<<" ri->count()="<<rootItem->childCount();
76 deleteItem (rootItem->getChildNum(0) );
80 void VymModel::init ()
85 // Also no scene yet (should not be needed anyway) FIXME-3 VM
103 fileName=tr("unnamed");
105 blockReposition=false;
106 blockSaveState=false;
108 autosaveTimer=new QTimer (this);
109 connect(autosaveTimer, SIGNAL(timeout()), this, SLOT(autosave()));
111 fileChangedTimer=new QTimer (this);
112 fileChangedTimer->start(3000);
113 connect(fileChangedTimer, SIGNAL(timeout()), this, SLOT(fileChanged()));
118 selectionBlocked=false;
123 // animations // FIXME-4 switch to new animation system
124 animationUse=settings.readBoolEntry("/animation/use",false); // FIXME-4 add options to control _what_ is animated
125 animationTicks=settings.readNumEntry("/animation/ticks",10);
126 animationInterval=settings.readNumEntry("/animation/interval",50);
128 animationTimer=new QTimer (this);
129 connect(animationTimer, SIGNAL(timeout()), this, SLOT(animate()));
132 defLinkColor=QColor (0,0,255);
133 defXLinkColor=QColor (180,180,180);
134 linkcolorhint=LinkableMapObj::DefaultColor;
135 linkstyle=LinkableMapObj::PolyParabel;
137 defXLinkColor=QColor (230,230,230);
140 hidemode=TreeItem::HideNone;
142 // Avoid recursions later
143 cleaningUpLinks=false;
148 //Initialize DBUS object
149 adaptorModel=new AdaptorModel(this); // Created and not deleted as documented in Qt
150 if (!dbusConnection.registerObject (QString("/vymmodel_%1").arg(mapID),this))
151 qWarning ("VymModel: Couldn't register DBUS object!");
154 void VymModel::makeTmpDirectories()
156 // Create unique temporary directories
157 tmpMapDir = tmpVymDir+QString("/model-%1").arg(mapID);
158 histPath = tmpMapDir+"/history";
164 MapEditor* VymModel::getMapEditor() // FIXME-3 VM better return favourite editor here
169 bool VymModel::isRepositionBlocked()
171 return blockReposition;
174 void VymModel::updateActions() // FIXME-4 maybe don't update if blockReposition is set
176 //cout << "VM::updateActions \n";
177 // Tell mainwindow to update states of actions
178 mainWindow->updateActions();
183 QString VymModel::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPointF &offset, TreeItem *saveSel)
185 // tmpdir temporary directory to which data will be written
186 // prefix mapname, which will be appended to images etc.
187 // writeflags Only write flags for "real" save of map, not undo
188 // offset offset of bbox of whole map in scene.
189 // Needed for XML export
198 case LinkableMapObj::Line:
201 case LinkableMapObj::Parabel:
204 case LinkableMapObj::PolyLine:
208 ls="StylePolyParabel";
212 QString s="<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE vymmap>\n";
214 if (linkcolorhint==LinkableMapObj::HeadingColor)
215 colhint=xml.attribut("linkColorHint","HeadingColor");
217 QString mapAttr=xml.attribut("version",vymVersion);
219 mapAttr+= xml.attribut("author",author) +
220 xml.attribut("comment",comment) +
221 xml.attribut("date",getDate()) +
222 xml.attribut("branchCount", QString().number(branchCount())) +
223 xml.attribut("backgroundColor", mapScene->backgroundBrush().color().name() ) +
224 xml.attribut("selectionColor", mapEditor->getSelectionColor().name() ) +
225 xml.attribut("linkStyle", ls ) +
226 xml.attribut("linkColor", defLinkColor.name() ) +
227 xml.attribut("defXLinkColor", defXLinkColor.name() ) +
228 xml.attribut("defXLinkWidth", QString().setNum(defXLinkWidth,10) ) +
229 xml.attribut("mapZoomFactor", QString().setNum(mapEditor->getZoomFactorTarget()) ) +
231 s+=xml.beginElement("vymmap",mapAttr);
234 // Find the used flags while traversing the tree // FIXME-3 this can be done local to vymmodel maybe...
235 standardFlagsMaster->resetUsedCounter();
238 // Temporary list of links
239 QList <Link*> tmpLinks;
241 // Build xml recursivly
244 // Save all mapcenters as complete map, if saveSel not set
245 s+=saveTreeToDir(tmpdir,prefix,offset,tmpLinks);
247 // Save local settings
248 s+=settings.getDataXML (destPath);
251 if (getSelectedItem() && !saveSel )
252 s+=xml.valueElement("select",getSelectString());
256 switch (saveSel->getType())
258 case TreeItem::Branch:
260 s+=((BranchItem*)saveSel)->saveToDir(tmpdir,prefix,offset,tmpLinks);
262 case TreeItem::MapCenter:
264 s+=((BranchItem*)saveSel)->saveToDir(tmpdir,prefix,offset,tmpLinks);
266 case TreeItem::Image:
268 s+=((ImageItem*)saveSel)->saveToDir(tmpdir,prefix);
271 // other types shouldn't be safed directly...
277 for (int i=0; i<tmpLinks.count();++i)
279 s+=tmpLinks.at(i)->saveToDir();
283 s+=xml.endElement("vymmap");
285 //cout << s.toStdString() << endl;
287 if (writeflags) standardFlagsMaster->saveToDir (tmpdir+"/flags/","",writeflags);
291 QString VymModel::saveTreeToDir (const QString &tmpdir,const QString &prefix, const QPointF &offset, QList <Link*> &tmpLinks)
294 for (int i=0; i<rootItem->branchCount(); i++)
295 s+=rootItem->getBranchNum(i)->saveToDir (tmpdir,prefix,offset,tmpLinks);
299 void VymModel::setFilePath(QString fpath, QString destname)
301 if (fpath.isEmpty() || fpath=="")
308 filePath=fpath; // becomes absolute path
309 fileName=fpath; // gets stripped of path
310 destPath=destname; // needed for vymlinks and during load to reset fileChangedTime
312 // If fpath is not an absolute path, complete it
313 filePath=QDir(fpath).absPath();
314 fileDir=filePath.left (1+filePath.findRev ("/"));
316 // Set short name, too. Search from behind:
317 int i=fileName.findRev("/");
318 if (i>=0) fileName=fileName.remove (0,i+1);
320 // Forget the .vym (or .xml) for name of map
321 mapName=fileName.left(fileName.findRev(".",-1,true) );
325 void VymModel::setFilePath(QString fpath)
327 setFilePath (fpath,fpath);
330 QString VymModel::getFilePath()
335 QString VymModel::getFileName()
340 QString VymModel::getMapName()
345 QString VymModel::getDestPath()
350 ErrorCode VymModel::loadMap (
352 const LoadMode &lmode,
354 const FileType &ftype,
357 ErrorCode err=success;
359 // Get updated zoomFactor, before applying one read from file in the end
360 if (mapEditor) zoomFactor=mapEditor->getZoomFactorTarget();
362 // For ImportReplace let's insert a new branch and replace that
363 BranchItem *selbi=getSelectedBranch();
364 BranchItem *newbi=NULL;
366 parseBaseHandler *handler;
370 case VymMap: handler=new parseVYMHandler; break;
371 case FreemindMap : handler=new parseFreemindHandler; break;
373 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
374 "Unknown FileType in VymModel::load()");
378 bool zipped_org=zipped;
382 selModel->clearSelection();
385 if (!selbi) return aborted;
386 if (lmode==ImportAdd)
387 if (saveStateFlag) saveStateChangingPart(
390 QString("addMapInsert (%1)").arg(fname),
391 QString("Add map %1 to %2").arg(fname).arg(getObjectName(selbi)));
392 if (lmode==ImportReplace)
394 if (saveStateFlag) saveStateChangingPart(
397 QString("addMapReplace(%1)").arg(fname),
398 QString("Add map %1 to %2").arg(fname).arg(getObjectName(selbi)));
399 newbi=addNewBranchInt (selbi,-1); // Add below selection
405 // Create temporary directory for packing
407 QString tmpZipDir=makeTmpDir (ok,"vym-pack");
410 QMessageBox::critical( 0, tr( "Critical Load Error" ),
411 tr("Couldn't create temporary directory before load\n"));
416 err=unzipDir (tmpZipDir,fname);
426 // Look for mapname.xml
427 xmlfile= fname.left(fname.findRev(".",-1,true));
428 xmlfile=xmlfile.section( '/', -1 );
429 QFile mfile( tmpZipDir + "/" + xmlfile + ".xml");
430 if (!mfile.exists() )
432 // mapname.xml does not exist, well,
433 // maybe someone renamed the mapname.vym file...
434 // Try to find any .xml in the toplevel
435 // directory of the .vym file
436 QStringList flist=QDir (tmpZipDir).entryList("*.xml");
437 if (flist.count()==1)
439 // Only one entry, take this one
440 xmlfile=tmpZipDir + "/"+flist.first();
443 for ( QStringList::Iterator it = flist.begin(); it != flist.end(); ++it )
444 *it=tmpZipDir + "/" + *it;
445 // TODO Multiple entries, load all (but only the first one into this ME)
446 //mainWindow->fileLoadFromTmp (flist);
447 //returnCode=1; // Silently forget this attempt to load
448 qWarning ("MainWindow::load (fn) multimap found...");
451 if (flist.isEmpty() )
453 QMessageBox::critical( 0, tr( "Critical Load Error" ),
454 tr("Couldn't find a map (*.xml) in .vym archive.\n"));
457 } //file doesn't exist
459 xmlfile=mfile.name();
462 QFile file( xmlfile);
464 // I am paranoid: file should exist anyway
465 // according to check in mainwindow.
468 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
469 tr(QString("Couldn't open map %1").arg(file.name())));
473 bool blockSaveStateOrg=blockSaveState;
474 blockReposition=true;
476 mapEditor->setViewportUpdateMode (QGraphicsView::NoViewportUpdate);
477 QXmlInputSource source( file);
478 QXmlSimpleReader reader;
479 reader.setContentHandler( handler );
480 reader.setErrorHandler( handler );
481 handler->setModel ( this);
484 // We need to set the tmpDir in order to load files with rel. path
489 tmpdir=fname.left(fname.findRev("/",-1));
490 handler->setTmpDir (tmpdir);
491 handler->setInputFile (file.name());
492 if (lmode==ImportReplace)
493 handler->setLoadMode (ImportAdd,pos);
495 handler->setLoadMode (lmode,pos);
497 bool ok = reader.parse( source );
498 blockReposition=false;
499 blockSaveState=blockSaveStateOrg;
500 mapEditor->setViewportUpdateMode (QGraphicsView::MinimalViewportUpdate);
509 autosaveTimer->stop();
511 // Reset timestamp to check for later updates of file
512 fileChangedTime=QFileInfo (destPath).lastModified();
519 if (lmode==ImportReplace)
523 deleteKeepChildren (false);
526 emitSelectionChanged();
529 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
530 tr( handler->errorProtocol() ) );
532 // Still return "success": the map maybe at least
533 // partially read by the parser
538 removeDir (QDir(tmpZipDir));
540 // Restore original zip state
545 if (mapEditor) mapEditor->setZoomFactorTarget (zoomFactor);
547 //Update view (scene()->update() is not enough)
548 qApp->processEvents(); // Update view (scene()->update() is not enough)
552 ErrorCode VymModel::save (const SaveMode &savemode)
556 QString safeFilePath;
558 ErrorCode err=success;
562 mapFileName=mapName+".xml";
564 // use name given by user, even if he chooses .doc
565 mapFileName=fileName;
567 // Look, if we should zip the data:
570 QMessageBox mb( vymName,
571 tr("The map %1\ndid not use the compressed "
572 "vym file format.\nWriting it uncompressed will also write images \n"
573 "and flags and thus may overwrite files in the "
574 "given directory\n\nDo you want to write the map").arg(filePath),
575 QMessageBox::Warning,
576 QMessageBox::Yes | QMessageBox::Default,
578 QMessageBox::Cancel | QMessageBox::Escape);
579 mb.setButtonText( QMessageBox::Yes, tr("compressed (vym default)") );
580 mb.setButtonText( QMessageBox::No, tr("uncompressed") );
581 mb.setButtonText( QMessageBox::Cancel, tr("Cancel"));
584 case QMessageBox::Yes:
585 // save compressed (default file format)
588 case QMessageBox::No:
592 case QMessageBox::Cancel:
599 // First backup existing file, we
600 // don't want to add to old zip archives
604 if ( settings.value ("/mapeditor/writeBackupFile").toBool())
606 QString backupFileName(destPath + "~");
607 QFile backupFile(backupFileName);
608 if (backupFile.exists() && !backupFile.remove())
610 QMessageBox::warning(0, tr("Save Error"),
611 tr("%1\ncould not be removed before saving").arg(backupFileName));
613 else if (!f.rename(backupFileName))
615 QMessageBox::warning(0, tr("Save Error"),
616 tr("%1\ncould not be renamed before saving").arg(destPath));
623 // Create temporary directory for packing
625 tmpZipDir=makeTmpDir (ok,"vym-zip");
628 QMessageBox::critical( 0, tr( "Critical Load Error" ),
629 tr("Couldn't create temporary directory before save\n"));
633 safeFilePath=filePath;
634 setFilePath (tmpZipDir+"/"+ mapName+ ".xml", safeFilePath);
637 // Create mapName and fileDir
638 makeSubDirs (fileDir);
641 if (savemode==CompleteMap || selModel->selection().isEmpty())
644 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),NULL);
647 autosaveTimer->stop();
652 if (selectionType()==TreeItem::Image)
655 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),getSelectedBranch());
656 // TODO take care of multiselections
659 if (!saveStringToDisk(fileDir+mapFileName,saveFile))
662 qWarning ("ME::saveStringToDisk failed!");
668 if (err==success) err=zipDir (tmpZipDir,destPath);
671 removeDir (QDir(tmpZipDir));
673 // Restore original filepath outside of tmp zip dir
674 setFilePath (safeFilePath);
678 fileChangedTime=QFileInfo (destPath).lastModified();
682 ImageItem* VymModel::loadFloatImageInt (BranchItem *dst,QString fn)
684 ImageItem *ii=createImage(dst);
694 void VymModel::loadFloatImage ()
696 BranchItem *selbi=getSelectedBranch();
700 Q3FileDialog *fd=new Q3FileDialog( NULL); // FIXME-4 get rid of Q3FileDialog
701 fd->setMode (Q3FileDialog::ExistingFiles);
702 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
703 ImagePreview *p =new ImagePreview (fd);
704 fd->setContentsPreviewEnabled( TRUE );
705 fd->setContentsPreview( p, p );
706 fd->setPreviewMode( Q3FileDialog::Contents );
707 fd->setCaption(vymName+" - " +tr("Load image"));
708 fd->setDir (lastImageDir);
711 if ( fd->exec() == QDialog::Accepted )
713 // TODO loadFIO in QT4 use: lastImageDir=fd->directory();
714 lastImageDir=QDir (fd->dirPath());
717 for (int j=0; j<fd->selectedFiles().count(); j++)
719 s=fd->selectedFiles().at(j);
720 ii=loadFloatImageInt (selbi,s);
721 //FIXME-3 check savestate for loadImage
727 QString ("loadImage (%1)").arg(s ),
728 QString("Add image %1 to %2").arg(s).arg(getObjectName(selbi))
731 // TODO loadFIO error handling
732 qWarning ("Failed to load "+s);
740 void VymModel::saveFloatImageInt (ImageItem *ii, const QString &type, const QString &fn)
745 void VymModel::saveFloatImage ()
747 ImageItem *ii=getSelectedImage();
750 QFileDialog *fd=new QFileDialog( NULL);
751 fd->setFilters (imageIO.getFilters());
752 fd->setCaption(vymName+" - " +tr("Save image"));
753 fd->setFileMode( QFileDialog::AnyFile );
754 fd->setDirectory (lastImageDir);
755 // fd->setSelection (fio->getOriginalFilename());
759 if ( fd->exec() == QDialog::Accepted && fd->selectedFiles().count()==1)
761 fn=fd->selectedFiles().at(0);
762 if (QFile (fn).exists() )
764 QMessageBox mb( vymName,
765 tr("The file %1 exists already.\n"
766 "Do you want to overwrite it?").arg(fn),
767 QMessageBox::Warning,
768 QMessageBox::Yes | QMessageBox::Default,
769 QMessageBox::Cancel | QMessageBox::Escape,
770 QMessageBox::NoButton );
772 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
773 mb.setButtonText( QMessageBox::No, tr("Cancel"));
776 case QMessageBox::Yes:
779 case QMessageBox::Cancel:
786 saveFloatImageInt (ii,fd->selectedFilter(),fn );
793 void VymModel::importDirInt(BranchItem *dst, QDir d)
795 BranchItem *selbi=getSelectedBranch();
799 // Traverse directories
800 d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
801 QFileInfoList list = d.entryInfoList();
804 for (int i = 0; i < list.size(); ++i)
807 if (fi.fileName() != "." && fi.fileName() != ".." )
809 bi=addNewBranchInt(dst,-2);
810 bi->setHeading (fi.fileName() ); // FIXME-3 check this
811 bi->setHeadingColor (QColor("blue"));
813 if ( !d.cd(fi.fileName()) )
814 QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory %1").arg(fi.fileName()));
817 // Recursively add subdirs
824 d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
825 list = d.entryInfoList();
827 for (int i = 0; i < list.size(); ++i)
830 bi=addNewBranchInt (dst,-2);
831 bi->setHeading (fi.fileName() );
832 bi->setHeadingColor (QColor("black"));
833 if (fi.fileName().right(4) == ".vym" )
834 bi->setVymLink (fi.filePath());
839 void VymModel::importDirInt (const QString &s)
841 BranchItem *selbi=getSelectedBranch();
844 saveStateChangingPart (selbi,selbi,QString ("importDir (\"%1\")").arg(s),QString("Import directory structure from %1").arg(s));
847 importDirInt (selbi,d);
851 void VymModel::importDir() //FIXME-3 check me... (not tested yet)
853 BranchItem *selbi=getSelectedBranch();
857 filters <<"VYM map (*.vym)";
858 QFileDialog *fd=new QFileDialog( NULL,vymName+ " - " +tr("Choose directory structure to import"));
859 fd->setMode (QFileDialog::DirectoryOnly);
860 fd->setFilters (filters);
861 fd->setCaption(vymName+" - " +tr("Choose directory structure to import"));
865 if ( fd->exec() == QDialog::Accepted )
867 importDirInt (fd->selectedFile() );
869 //FIXME-3 VM needed? scene()->update();
875 void VymModel::autosave()
880 cout << "VymModel::autosave rejected due to missing filePath\n";
883 QDateTime now=QDateTime().currentDateTime();
885 // Disable autosave, while we have gone back in history
886 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
887 if (redosAvail>0) return;
889 // Also disable autosave for new map without filename
890 if (filePath.isEmpty()) return;
893 if (mapUnsaved &&mapChanged && settings.value ("/mainwindow/autosave/use",true).toBool() )
895 if (QFileInfo(filePath).lastModified()<=fileChangedTime)
896 mainWindow->fileSave (this);
899 cout <<" ME::autosave rejected, file on disk is newer than last save.\n";
904 void VymModel::fileChanged()
906 // Check if file on disk has changed meanwhile
907 if (!filePath.isEmpty())
909 QDateTime tmod=QFileInfo (filePath).lastModified();
910 if (tmod>fileChangedTime)
912 // FIXME-3 VM switch to current mapeditor and finish lineedits...
913 QMessageBox mb( vymName,
914 tr("The file of the map on disk has changed:\n\n"
915 " %1\n\nDo you want to reload that map with the new file?").arg(filePath),
916 QMessageBox::Question,
918 QMessageBox::Cancel | QMessageBox::Default,
919 QMessageBox::NoButton );
921 mb.setButtonText( QMessageBox::Yes, tr("Reload"));
922 mb.setButtonText( QMessageBox::No, tr("Ignore"));
925 case QMessageBox::Yes:
928 case QMessageBox::Cancel:
929 fileChangedTime=tmod; // allow autosave to overwrite newer file!
935 bool VymModel::isDefault()
940 void VymModel::makeDefault()
946 bool VymModel::hasChanged()
951 void VymModel::setChanged()
954 autosaveTimer->start(settings.value("/mainwindow/autosave/ms/",300000).toInt());
958 latestAddedItem=NULL;
962 QString VymModel::getObjectName (LinkableMapObj *lmo) // FIXME-3 should be obsolete
964 if (!lmo || !lmo->getTreeItem() ) return QString();
965 return getObjectName (lmo->getTreeItem() );
969 QString VymModel::getObjectName (TreeItem *ti)
972 if (!ti) return QString("Error: NULL has no name!");
974 if (s=="") s="unnamed";
976 return QString ("%1 (%2)").arg(ti->getTypeName()).arg(s);
979 void VymModel::redo()
981 // Can we undo at all?
982 if (redosAvail<1) return;
984 bool blockSaveStateOrg=blockSaveState;
989 if (undosAvail<stepsTotal) undosAvail++;
991 if (curStep>stepsTotal) curStep=1;
992 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
993 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
994 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
995 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
996 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
997 QString version=undoSet.readEntry ("/history/version");
999 /* TODO Maybe check for version, if we save the history
1000 if (!checkVersion(version))
1001 QMessageBox::warning(0,tr("Warning"),
1002 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1005 // Find out current undo directory
1006 QString bakMapDir(QString(tmpMapDir+"/undo-%1").arg(curStep));
1010 cout << "VymModel::redo() begin\n";
1011 cout << " undosAvail="<<undosAvail<<endl;
1012 cout << " redosAvail="<<redosAvail<<endl;
1013 cout << " curStep="<<curStep<<endl;
1014 cout << " ---------------------------"<<endl;
1015 cout << " comment="<<comment.toStdString()<<endl;
1016 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1017 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1018 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1019 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1020 cout << " ---------------------------"<<endl<<endl;
1023 // select object before redo
1024 if (!redoSelection.isEmpty())
1025 select (redoSelection);
1030 parseAtom (redoCommand,noErr,errMsg);
1032 blockSaveState=blockSaveStateOrg;
1034 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1035 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1036 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1037 undoSet.writeSettings(histPath);
1039 mainWindow->updateHistory (undoSet);
1042 /* TODO remove testing
1043 cout << "ME::redo() end\n";
1044 cout << " undosAvail="<<undosAvail<<endl;
1045 cout << " redosAvail="<<redosAvail<<endl;
1046 cout << " curStep="<<curStep<<endl;
1047 cout << " ---------------------------"<<endl<<endl;
1053 bool VymModel::isRedoAvailable()
1055 if (undoSet.readNumEntry("/history/redosAvail",0)>0)
1061 void VymModel::undo()
1063 // Can we undo at all?
1064 if (undosAvail<1) return;
1066 mainWindow->statusMessage (tr("Autosave disabled during undo."));
1068 bool blockSaveStateOrg=blockSaveState;
1069 blockSaveState=true;
1071 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1072 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1073 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1074 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1075 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1076 QString version=undoSet.readEntry ("/history/version");
1078 /* TODO Maybe check for version, if we save the history
1079 if (!checkVersion(version))
1080 QMessageBox::warning(0,tr("Warning"),
1081 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1084 // Find out current undo directory
1085 QString bakMapDir(QString(tmpMapDir+"/undo-%1").arg(curStep));
1087 // select object before undo
1088 if (!select (undoSelection))
1090 qWarning ("VymModel::undo() Could not select object for undo");
1097 cout << "VymModel::undo() begin\n";
1098 cout << " undosAvail="<<undosAvail<<endl;
1099 cout << " redosAvail="<<redosAvail<<endl;
1100 cout << " curStep="<<curStep<<endl;
1101 cout << " ---------------------------"<<endl;
1102 cout << " comment="<<comment.toStdString()<<endl;
1103 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1104 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1105 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1106 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1107 cout << " ---------------------------"<<endl<<endl;
1112 parseAtom (undoCommand,noErr,errMsg);
1116 if (curStep<1) curStep=stepsTotal;
1120 blockSaveState=blockSaveStateOrg;
1122 cout << "VymModel::undo() end\n";
1123 cout << " undosAvail="<<undosAvail<<endl;
1124 cout << " redosAvail="<<redosAvail<<endl;
1125 cout << " curStep="<<curStep<<endl;
1126 cout << " ---------------------------"<<endl<<endl;
1129 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1130 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1131 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1132 undoSet.writeSettings(histPath);
1134 mainWindow->updateHistory (undoSet);
1136 //emitSelectionChanged();
1139 bool VymModel::isUndoAvailable()
1141 if (undoSet.readNumEntry("/history/undosAvail",0)>0)
1147 void VymModel::gotoHistoryStep (int i)
1149 // Restore variables
1150 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1151 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1153 if (i<0) i=undosAvail+redosAvail;
1155 // Clicking above current step makes us undo things
1158 for (int j=0; j<undosAvail-i; j++) undo();
1161 // Clicking below current step makes us redo things
1163 for (int j=undosAvail; j<i; j++)
1165 if (debug) cout << "VymModel::gotoHistoryStep redo "<<j<<"/"<<undosAvail<<" i="<<i<<endl;
1169 // And ignore clicking the current row ;-)
1173 QString VymModel::getHistoryPath()
1175 QString histName(QString("history-%1").arg(curStep));
1176 return (tmpMapDir+"/"+histName);
1179 void VymModel::resetHistory()
1185 stepsTotal=settings.readNumEntry("/history/stepsTotal",100);
1186 undoSet.setEntry ("/history/stepsTotal",QString::number(stepsTotal));
1187 mainWindow->updateHistory (undoSet);
1190 void VymModel::saveState(const SaveMode &savemode, const QString &undoSelection, const QString &undoCom, const QString &redoSelection, const QString &redoCom, const QString &comment, TreeItem *saveSel)
1192 sendData(redoCom); //FIXME-3 testing
1197 if (blockSaveState) return;
1199 if (debug) cout << "VM::saveState() for "<<qPrintable (mapName)<<endl;
1201 // Find out current undo directory
1202 if (undosAvail<stepsTotal) undosAvail++;
1204 if (curStep>stepsTotal) curStep=1;
1206 QString backupXML="";
1207 QString histDir=getHistoryPath();
1208 QString bakMapPath=histDir+"/map.xml";
1210 // Create histDir if not available
1213 makeSubDirs (histDir);
1215 // Save depending on how much needs to be saved
1216 QList <Link*> tmpLinks;
1218 backupXML=saveToDir (histDir,mapName+"-",false, QPointF (),saveSel);
1220 QString undoCommand="";
1221 if (savemode==UndoCommand)
1223 undoCommand=undoCom;
1225 else if (savemode==PartOfMap )
1227 undoCommand=undoCom;
1228 undoCommand.replace ("PATH",bakMapPath);
1232 if (!backupXML.isEmpty())
1233 // Write XML Data to disk
1234 saveStringToDisk (bakMapPath,backupXML);
1236 // We would have to save all actions in a tree, to keep track of
1237 // possible redos after a action. Possible, but we are too lazy: forget about redos.
1240 // Write the current state to disk
1241 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1242 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1243 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1244 undoSet.setEntry (QString("/history/step-%1/undoCommand").arg(curStep),undoCommand);
1245 undoSet.setEntry (QString("/history/step-%1/undoSelection").arg(curStep),undoSelection);
1246 undoSet.setEntry (QString("/history/step-%1/redoCommand").arg(curStep),redoCom);
1247 undoSet.setEntry (QString("/history/step-%1/redoSelection").arg(curStep),redoSelection);
1248 undoSet.setEntry (QString("/history/step-%1/comment").arg(curStep),comment);
1249 undoSet.setEntry (QString("/history/version"),vymVersion);
1250 undoSet.writeSettings(histPath);
1254 // TODO remove after testing
1255 //cout << " into="<< histPath.toStdString()<<endl;
1256 cout << " stepsTotal="<<stepsTotal<<
1257 ", undosAvail="<<undosAvail<<
1258 ", redosAvail="<<redosAvail<<
1259 ", curStep="<<curStep<<endl;
1260 cout << " ---------------------------"<<endl;
1261 cout << " comment="<<comment.toStdString()<<endl;
1262 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1263 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1264 cout << " redoCom="<<redoCom.toStdString()<<endl;
1265 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1266 if (saveSel) cout << " saveSel="<<qPrintable (getSelectString(saveSel))<<endl;
1267 cout << " ---------------------------"<<endl;
1270 mainWindow->updateHistory (undoSet);
1276 void VymModel::saveStateChangingPart(TreeItem *undoSel, TreeItem* redoSel, const QString &rc, const QString &comment)
1278 // save the selected part of the map, Undo will replace part of map
1279 QString undoSelection="";
1281 undoSelection=getSelectString(undoSel);
1283 qWarning ("VymModel::saveStateChangingPart no undoSel given!");
1284 QString redoSelection="";
1286 redoSelection=getSelectString(undoSel);
1288 qWarning ("VymModel::saveStateChangingPart no redoSel given!");
1291 saveState (PartOfMap,
1292 undoSelection, "addMapReplace (\"PATH\")",
1298 void VymModel::saveStateRemovingPart(TreeItem* redoSel, const QString &comment)
1302 qWarning ("VymModel::saveStateRemovingPart no redoSel given!");
1305 QString undoSelection;
1306 QString redoSelection=getSelectString(redoSel);
1307 if (redoSel->getType()==TreeItem::Branch)
1309 undoSelection=getSelectString (redoSel->parent());
1310 // save the selected branch of the map, Undo will insert part of map
1311 saveState (PartOfMap,
1312 undoSelection, QString("addMapInsert (\"PATH\",%1)").arg(redoSel->num()),
1313 redoSelection, "delete ()",
1317 if (redoSel->getType()==TreeItem::MapCenter)
1319 // save the selected branch of the map, Undo will insert part of map
1320 saveState (PartOfMap,
1321 undoSelection, QString("addMapInsert (\"PATH\")"),
1322 redoSelection, "delete ()",
1329 void VymModel::saveState(TreeItem *undoSel, const QString &uc, TreeItem *redoSel, const QString &rc, const QString &comment)
1331 // "Normal" savestate: save commands, selections and comment
1332 // so just save commands for undo and redo
1333 // and use current selection
1335 QString redoSelection="";
1336 if (redoSel) redoSelection=getSelectString(redoSel);
1337 QString undoSelection="";
1338 if (undoSel) undoSelection=getSelectString(undoSel);
1340 saveState (UndoCommand,
1347 void VymModel::saveState(const QString &undoSel, const QString &uc, const QString &redoSel, const QString &rc, const QString &comment)
1349 // "Normal" savestate: save commands, selections and comment
1350 // so just save commands for undo and redo
1351 // and use current selection
1352 saveState (UndoCommand,
1359 void VymModel::saveState(const QString &uc, const QString &rc, const QString &comment)
1361 // "Normal" savestate applied to model (no selection needed):
1362 // save commands and comment
1363 saveState (UndoCommand,
1371 QGraphicsScene* VymModel::getScene ()
1376 TreeItem* VymModel::findBySelectString(QString s)
1378 if (s.isEmpty() ) return NULL;
1380 // Old maps don't have multiple mapcenters and don't save full path
1381 if (s.left(2) !="mc")
1384 QStringList parts=s.split (",");
1387 TreeItem *ti=rootItem;
1389 while (!parts.isEmpty() )
1391 typ=parts.first().left(2);
1392 n=parts.first().right(parts.first().length() - 3).toInt();
1393 parts.removeFirst();
1394 if (typ=="mc" || typ=="bo")
1395 ti=ti->getBranchNum (n);
1397 ti=ti->getImageNum (n);
1399 ti=ti->getAttributeNum (n);
1401 ti=ti->getXLinkNum (n);
1402 if(!ti) return NULL;
1407 TreeItem* VymModel::findID (const uint &i) //FIXME-3 Search also other types...
1409 BranchItem *cur=NULL;
1410 BranchItem *prev=NULL;
1411 nextBranch(cur,prev);
1414 if (i==cur->getID() ) return cur;
1415 nextBranch(cur,prev);
1420 //////////////////////////////////////////////
1422 //////////////////////////////////////////////
1423 void VymModel::setVersion (const QString &s)
1428 QString VymModel::getVersion()
1433 void VymModel::setAuthor (const QString &s)
1436 QString ("setMapAuthor (\"%1\")").arg(author),
1437 QString ("setMapAuthor (\"%1\")").arg(s),
1438 QString ("Set author of map to \"%1\"").arg(s)
1443 QString VymModel::getAuthor()
1448 void VymModel::setComment (const QString &s)
1451 QString ("setMapComment (\"%1\")").arg(comment),
1452 QString ("setMapComment (\"%1\")").arg(s),
1453 QString ("Set comment of map")
1458 QString VymModel::getComment ()
1463 QString VymModel::getDate ()
1465 return QDate::currentDate().toString ("yyyy-MM-dd");
1468 int VymModel::branchCount()
1471 BranchItem *cur=NULL;
1472 BranchItem *prev=NULL;
1473 nextBranch(cur,prev);
1477 nextBranch(cur,prev);
1482 void VymModel::setSortFilter (const QString &s)
1485 emit (sortFilterChanged (sortFilter));
1488 QString VymModel::getSortFilter ()
1493 void VymModel::setHeading(const QString &s)
1495 BranchItem *selbi=getSelectedBranch();
1500 "setHeading (\""+selbi->getHeading()+"\")",
1502 "setHeading (\""+s+"\")",
1503 QString("Set heading of %1 to \"%2\"").arg(getObjectName(selbi)).arg(s) );
1504 selbi->setHeading(s );
1505 emitDataHasChanged ( selbi); //FIXME-4 maybe emit signal from TreeItem?
1507 emitSelectionChanged();
1511 QString VymModel::getHeading()
1513 TreeItem *selti=getSelectedItem();
1515 return selti->getHeading();
1520 void VymModel::setNote(const QString &s)
1522 TreeItem *selti=getSelectedItem();
1527 "setNote (\""+selti->getNote()+"\")",
1529 "setNote (\""+s+"\")",
1530 QString("Set note of %1 ").arg(getObjectName(selti)) );
1533 emitNoteHasChanged(selti);
1534 emitDataHasChanged(selti);
1537 QString VymModel::getNote()
1539 TreeItem *selti=getSelectedItem();
1541 return selti->getNote();
1546 void VymModel::loadNote (const QString &fn)
1548 BranchItem *selbi=getSelectedBranch();
1552 if (!loadStringFromDisk (fn,n))
1553 qWarning ()<<"VymModel::loadNote Couldn't load "<<fn;
1557 qWarning ("VymModel::loadNote no branch selected");
1560 void VymModel::saveNote (const QString &fn)
1562 BranchItem *selbi=getSelectedBranch();
1565 QString n=selbi->getNote();
1567 qWarning ()<<"VymModel::saveNote note is empty, won't save to "<<fn;
1570 if (!saveStringToDisk (fn,n))
1571 qWarning ()<<"VymModel::saveNote Couldn't save "<<fn;
1576 qWarning ("VymModel::saveNote no branch selected");
1579 void VymModel::findDuplicateURLs() // FIXME-3 needs GUI
1581 // Generate map containing _all_ URLs and branches
1583 QMap <QString,BranchItem*> map;
1584 BranchItem *cur=NULL;
1585 BranchItem *prev=NULL;
1586 nextBranch(cur,prev);
1591 map.insertMulti (u,cur);
1592 nextBranch(cur,prev);
1595 // Extract duplicate URLs
1596 QMap <QString, BranchItem*>::const_iterator i=map.constBegin();
1597 QMap <QString, BranchItem*>::const_iterator firstdup=map.constEnd(); //invalid
1598 while (i != map.constEnd())
1600 if (i!=map.constBegin() && i.key()==firstdup.key())
1602 if ( i-1==firstdup )
1604 cout << firstdup.key().toStdString() << endl;
1605 cout << " - "<< firstdup.value() <<" - "<<firstdup.value()->getHeadingStd()<<endl;
1607 cout << " - "<< i.value() <<" - "<<i.value()->getHeadingStd()<<endl;
1615 void VymModel::findAll (FindResultModel *rmodel, QString s, Qt::CaseSensitivity cs)
1618 rmodel->setSearchString (s);
1619 rmodel->setSearchFlags (0); //FIXME-3 translate cs to QTextDocument::FindFlag
1620 BranchItem *cur=NULL;
1621 BranchItem *prev=NULL;
1622 nextBranch(cur,prev);
1624 FindResultItem *lastParent=NULL;
1628 if (cur->getHeading().contains (s,cs))
1629 lastParent=rmodel->addItem (cur);
1630 QString n=cur->getNoteASCII();
1635 i=n.indexOf (s,i,cs);
1638 // If not there yet, add "parent" item
1641 lastParent=rmodel->addItem (cur);
1643 qWarning()<<"VymModel::findAll still no lastParent?!";
1646 lastParent->setSelectable (false);
1650 // save index of occurence
1651 rmodel->addSubItem (lastParent,QString(tr("Note","FindAll in VymModel")+" "+s),cur,j);
1656 nextBranch(cur,prev);
1660 BranchItem* VymModel::findText (QString s,Qt::CaseSensitivity cs)
1662 if (!s.isEmpty() && s!=findString)
1668 QTextDocument::FindFlags flags=0;
1669 if (cs==Qt::CaseSensitive) flags=QTextDocument::FindCaseSensitively;
1672 { // Nothing found or new find process
1674 // nothing found, start again
1678 nextBranch (findCurrent,findPrevious);
1680 bool searching=true;
1681 bool foundNote=false;
1682 while (searching && !EOFind)
1686 // Searching in Note
1687 if (findCurrent->getNote().contains(findString,cs))
1689 select (findCurrent);
1690 if (textEditor->findText(findString,flags))
1696 // Searching in Heading
1697 if (searching && findCurrent->getHeading().contains (findString,cs) )
1699 select(findCurrent);
1705 if (!nextBranch(findCurrent,findPrevious) )
1710 return getSelectedBranch();
1715 void VymModel::findReset()
1716 { // Necessary if text to find changes during a find process
1723 void VymModel::setScene (QGraphicsScene *s)
1728 void VymModel::setURL(const QString &url)
1730 TreeItem *selti=getSelectedItem();
1733 QString oldurl=selti->getURL();
1734 selti->setURL (url);
1737 QString ("setURL (\"%1\")").arg(oldurl),
1739 QString ("setURL (\"%1\")").arg(url),
1740 QString ("set URL of %1 to %2").arg(getObjectName(selti)).arg(url)
1742 emitDataHasChanged (selti);
1744 emitSelectionChanged();
1748 QString VymModel::getURL()
1750 TreeItem *selti=getSelectedItem();
1752 return selti->getURL();
1757 QStringList VymModel::getURLs(bool ignoreScrolled)
1760 BranchItem *selbi=getSelectedBranch();
1761 BranchItem *cur=selbi;
1762 BranchItem *prev=NULL;
1765 if (!cur->getURL().isEmpty() && !(ignoreScrolled && cur->hasScrolledParent(cur) ))
1766 urls.append( cur->getURL());
1767 cur=nextBranch (cur,prev,true,selbi);
1773 void VymModel::setFrameType(const FrameObj::FrameType &t) //FIXME-4 not saved if there is no LMO
1775 BranchItem *bi=getSelectedBranch();
1778 BranchObj *bo=(BranchObj*)(bi->getLMO());
1781 QString s=bo->getFrameTypeName();
1782 bo->setFrameType (t);
1783 saveState (bi, QString("setFrameType (\"%1\")").arg(s),
1784 bi, QString ("setFrameType (\"%1\")").arg(bo->getFrameTypeName()),QString ("set type of frame to %1").arg(s));
1786 bo->updateLinkGeometry();
1791 void VymModel::setFrameType(const QString &s) //FIXME-4 not saved if there is no LMO
1793 BranchItem *bi=getSelectedBranch();
1796 BranchObj *bo=(BranchObj*)(bi->getLMO());
1799 saveState (bi, QString("setFrameType (\"%1\")").arg(bo->getFrameTypeName()),
1800 bi, QString ("setFrameType (\"%1\")").arg(s),QString ("set type of frame to %1").arg(s));
1801 bo->setFrameType (s);
1803 bo->updateLinkGeometry();
1808 void VymModel::setFramePenColor(const QColor &c) //FIXME-4 not saved if there is no LMO
1811 BranchItem *bi=getSelectedBranch();
1814 BranchObj *bo=(BranchObj*)(bi->getLMO());
1817 saveState (bi, QString("setFramePenColor (\"%1\")").arg(bo->getFramePenColor().name() ),
1818 bi, QString ("setFramePenColor (\"%1\")").arg(c.name() ),QString ("set pen color of frame to %1").arg(c.name() ));
1819 bo->setFramePenColor (c);
1824 void VymModel::setFrameBrushColor(const QColor &c) //FIXME-4 not saved if there is no LMO
1826 BranchItem *bi=getSelectedBranch();
1829 BranchObj *bo=(BranchObj*)(bi->getLMO());
1832 saveState (bi, QString("setFrameBrushColor (\"%1\")").arg(bo->getFrameBrushColor().name() ),
1833 bi, QString ("setFrameBrushColor (\"%1\")").arg(c.name() ),QString ("set brush color of frame to %1").arg(c.name() ));
1834 bo->setFrameBrushColor (c);
1839 void VymModel::setFramePadding (const int &i) //FIXME-4 not saved if there is no LMO
1841 BranchItem *bi=getSelectedBranch();
1844 BranchObj *bo=(BranchObj*)(bi->getLMO());
1847 saveState (bi, QString("setFramePadding (\"%1\")").arg(bo->getFramePadding() ),
1848 bi, QString ("setFramePadding (\"%1\")").arg(i),QString ("set brush color of frame to %1").arg(i));
1849 bo->setFramePadding (i);
1851 bo->updateLinkGeometry();
1856 void VymModel::setFrameBorderWidth(const int &i) //FIXME-4 not saved if there is no LMO
1858 BranchItem *bi=getSelectedBranch();
1861 BranchObj *bo=(BranchObj*)(bi->getLMO());
1864 saveState (bi, QString("setFrameBorderWidth (\"%1\")").arg(bo->getFrameBorderWidth() ),
1865 bi, QString ("setFrameBorderWidth (\"%1\")").arg(i),QString ("set border width of frame to %1").arg(i));
1866 bo->setFrameBorderWidth (i);
1868 bo->updateLinkGeometry();
1873 void VymModel::setIncludeImagesVer(bool b)
1875 BranchItem *bi=getSelectedBranch();
1878 QString u= b ? "false" : "true";
1879 QString r=!b ? "false" : "true";
1883 QString("setIncludeImagesVertically (%1)").arg(u),
1885 QString("setIncludeImagesVertically (%1)").arg(r),
1886 QString("Include images vertically in %1").arg(getObjectName(bi))
1888 bi->setIncludeImagesVer(b);
1889 emitDataHasChanged ( bi);
1894 void VymModel::setIncludeImagesHor(bool b)
1896 BranchItem *bi=getSelectedBranch();
1899 QString u= b ? "false" : "true";
1900 QString r=!b ? "false" : "true";
1904 QString("setIncludeImagesHorizontally (%1)").arg(u),
1906 QString("setIncludeImagesHorizontally (%1)").arg(r),
1907 QString("Include images horizontally in %1").arg(getObjectName(bi))
1909 bi->setIncludeImagesHor(b);
1910 emitDataHasChanged ( bi);
1915 void VymModel::setHideLinkUnselected (bool b)
1917 TreeItem *ti=getSelectedItem();
1918 if (ti && (ti->getType()==TreeItem::Image ||ti->isBranchLikeType()))
1920 QString u= b ? "false" : "true";
1921 QString r=!b ? "false" : "true";
1925 QString("setHideLinkUnselected (%1)").arg(u),
1927 QString("setHideLinkUnselected (%1)").arg(r),
1928 QString("Hide link of %1 if unselected").arg(getObjectName(ti))
1930 ((MapItem*)ti)->setHideLinkUnselected(b);
1934 void VymModel::setHideExport(bool b)
1936 TreeItem *ti=getSelectedItem();
1938 (ti->getType()==TreeItem::Image ||ti->isBranchLikeType()))
1940 ti->setHideInExport (b);
1941 QString u= b ? "false" : "true";
1942 QString r=!b ? "false" : "true";
1946 QString ("setHideExport (%1)").arg(u),
1948 QString ("setHideExport (%1)").arg(r),
1949 QString ("Set HideExport flag of %1 to %2").arg(getObjectName(ti)).arg (r)
1951 emitDataHasChanged(ti);
1952 emitSelectionChanged();
1955 // emitSelectionChanged();
1956 // FIXME-3 VM needed? scene()->update();
1960 void VymModel::toggleHideExport()
1962 TreeItem *selti=getSelectedItem();
1964 setHideExport ( !selti->hideInExport() );
1967 void VymModel::addTimestamp() //FIXME-3 new function, localize
1969 BranchItem *selbi=addNewBranch();
1972 QDate today=QDate::currentDate();
1974 selbi->setHeading (QString ("%1-%2-%3")
1975 .arg(today.year(),4,10,c)
1976 .arg(today.month(),2,10,c)
1977 .arg(today.day(),2,10,c));
1978 emitDataHasChanged ( selbi); //FIXME-3 maybe emit signal from TreeItem?
1985 void VymModel::copy()
1987 TreeItem *selti=getSelectedItem();
1989 (selti->getType() == TreeItem::Branch ||
1990 selti->getType() == TreeItem::MapCenter ||
1991 selti->getType() == TreeItem::Image ))
1993 if (redosAvail == 0)
1996 QString s=getSelectString(selti);
1997 saveState (PartOfMap, s, "nop ()", s, "copy ()","Copy selection to clipboard",selti );
1998 curClipboard=curStep;
2001 // Copy also to global clipboard, because we are at last step in history
2002 QString bakMapName(QString("history-%1").arg(curStep));
2003 QString bakMapDir(tmpMapDir +"/"+bakMapName);
2004 copyDir (bakMapDir,clipboardDir );
2006 clipboardEmpty=false;
2012 void VymModel::pasteNoSave(const int &n)
2014 bool zippedOrg=zipped;
2015 if (redosAvail > 0 || n!=0)
2017 // Use the "historical" buffer
2018 QString bakMapName(QString("history-%1").arg(n));
2019 QString bakMapDir(tmpMapDir +"/"+bakMapName);
2020 loadMap (bakMapDir+"/"+clipboardFile,ImportAdd, false);
2022 // Use the global buffer
2023 loadMap (clipboardDir+"/"+clipboardFile,ImportAdd, false);
2027 void VymModel::paste()
2029 BranchItem *selbi=getSelectedBranch();
2032 saveStateChangingPart(
2035 QString ("paste (%1)").arg(curClipboard),
2036 QString("Paste to %1").arg( getObjectName(selbi))
2043 void VymModel::cut()
2045 TreeItem *selti=getSelectedItem();
2046 if ( selti && (selti->isBranchLikeType() ||selti->getType()==TreeItem::Image))
2054 bool VymModel::moveUp(BranchItem *bi)
2056 if (bi && bi->canMoveUp())
2057 return relinkBranch (bi,(BranchItem*)bi->parent(),bi->num()-1);
2062 void VymModel::moveUp()
2064 BranchItem *selbi=getSelectedBranch();
2067 QString oldsel=getSelectString();
2070 getSelectString(),"moveDown ()",
2072 QString("Move up %1").arg(getObjectName(selbi)));
2076 bool VymModel::moveDown(BranchItem *bi)
2078 if (bi && bi->canMoveDown())
2079 return relinkBranch (bi,(BranchItem*)bi->parent(),bi->num()+1);
2084 void VymModel::moveDown()
2086 BranchItem *selbi=getSelectedBranch();
2089 QString oldsel=getSelectString();
2090 if ( moveDown(selbi))
2092 getSelectString(),"moveUp ()",
2093 oldsel,"moveDown ()",
2094 QString("Move down %1").arg(getObjectName(selbi)));
2098 void VymModel::detach()
2100 BranchItem *selbi=getSelectedBranch();
2101 if (selbi && selbi->depth()>0)
2103 // if no relPos have been set before, try to use current rel positions
2104 if (selbi->getLMO())
2105 for (int i=0; i<selbi->branchCount();++i)
2106 selbi->getBranchNum(i)->getBranchObj()->setRelPos();
2108 QString oldsel=getSelectString();
2111 BranchObj *bo=selbi->getBranchObj();
2112 if (bo) p=bo->getAbsPos();
2113 QString parsel=getSelectString(selbi->parent());
2114 if ( relinkBranch (selbi,rootItem,-1) )
2116 getSelectString (selbi),
2117 QString("relinkTo (\"%1\",%2,%3,%4)").arg(parsel).arg(n).arg(p.x()).arg(p.y()),
2120 QString("Detach %1").arg(getObjectName(selbi))
2125 void VymModel::sortChildren(bool inverse)
2127 BranchItem* selbi=getSelectedBranch();
2130 if(selbi->branchCount()>1)
2134 saveStateChangingPart(
2135 selbi,selbi, "sortChildren ()",
2136 QString("Sort children of %1").arg(getObjectName(selbi)));
2138 selbi->sortChildren(inverse);
2140 emitShowSelection();
2145 BranchItem* VymModel::createMapCenter()
2147 BranchItem *newbi=addMapCenter (QPointF (0,0) );
2151 BranchItem* VymModel::createBranch(BranchItem *dst)
2154 return addNewBranchInt (dst,-2);
2159 ImageItem* VymModel::createImage(BranchItem *dst)
2166 QList<QVariant> cData;
2167 cData << "new" << "undef";
2169 ImageItem *newii=new ImageItem(cData) ;
2170 //newii->setHeading (QApplication::translate("Heading of new image in map", "new image"));
2172 emit (layoutAboutToBeChanged() );
2175 if (!parix.isValid()) cout << "VM::createII invalid index\n";
2176 n=dst->getRowNumAppend(newii);
2177 beginInsertRows (parix,n,n);
2178 dst->appendChild (newii);
2181 emit (layoutChanged() );
2183 // save scroll state. If scrolled, automatically select
2184 // new branch in order to tmp unscroll parent...
2185 newii->createMapObj(mapScene);
2192 bool VymModel::createLink(Link *link, bool createMO)
2194 BranchItem *begin=link->getBeginBranch();
2195 BranchItem *end =link->getEndBranch();
2199 qWarning ()<<"VM::createXLinkNew part of XLink is NULL";
2207 QList<QVariant> cData;
2209 cData << "new Link begin"<<"undef";
2210 XLinkItem *newli=new XLinkItem(cData) ;
2211 newli->setLink (link);
2212 link->setBeginLinkItem (newli);
2214 emit (layoutAboutToBeChanged() );
2217 n=begin->getRowNumAppend(newli);
2218 beginInsertRows (parix,n,n);
2219 begin->appendChild (newli);
2223 cData << "new Link end"<<"undef";
2224 newli=new XLinkItem(cData) ;
2225 newli->setLink (link);
2226 link->setEndLinkItem (newli);
2229 n=end->getRowNumAppend(newli);
2230 beginInsertRows (parix,n,n);
2231 end->appendChild (newli);
2234 emit (layoutChanged() );
2236 xlinks.append (link);
2241 link->createMapObj(mapScene);
2249 AttributeItem* VymModel::addAttribute()
2251 BranchItem *selbi=getSelectedBranch();
2254 QList<QVariant> cData;
2255 cData << "new attribute" << "undef";
2256 AttributeItem *a=new AttributeItem (cData);
2257 if (addAttribute (a)) return a;
2262 AttributeItem* VymModel::addAttribute(AttributeItem *ai) // FIXME-3 savestate missing
2264 BranchItem *selbi=getSelectedBranch();
2267 emit (layoutAboutToBeChanged() );
2269 QModelIndex parix=index(selbi);
2270 int n=selbi->getRowNumAppend (ai);
2271 beginInsertRows (parix,n,n);
2272 selbi->appendChild (ai);
2275 emit (layoutChanged() );
2277 ai->createMapObj(mapScene); //FIXME-3 check that...
2284 BranchItem* VymModel::addMapCenter (bool saveStateFlag)
2286 BranchItem *bi=addMapCenter (contextPos);
2288 emitShowSelection();
2289 if (saveStateFlag) saveState (
2293 QString ("addMapCenter (%1,%2)").arg (contextPos.x()).arg(contextPos.y()),
2294 QString ("Adding MapCenter to (%1,%2)").arg (contextPos.x()).arg(contextPos.y())
2300 BranchItem* VymModel::addMapCenter(QPointF absPos)
2301 // createMapCenter could then probably be merged with createBranch
2305 QModelIndex parix=index(rootItem);
2307 QList<QVariant> cData;
2308 cData << "VM:addMapCenter" << "undef";
2309 BranchItem *newbi=new BranchItem (cData,rootItem);
2310 newbi->setHeading (QApplication::translate("Heading of mapcenter in new map", "New map"));
2311 int n=rootItem->getRowNumAppend (newbi);
2313 emit (layoutAboutToBeChanged() );
2314 beginInsertRows (parix,n,n);
2316 rootItem->appendChild (newbi);
2319 emit (layoutChanged() );
2322 newbi->setPositionMode (MapItem::Absolute);
2323 BranchObj *bo=newbi->createMapObj(mapScene);
2324 if (bo) bo->move (absPos);
2329 BranchItem* VymModel::addNewBranchInt(BranchItem *dst,int num)
2331 // Depending on pos:
2332 // -3 insert in children of parent above selection
2333 // -2 add branch to selection
2334 // -1 insert in children of parent below selection
2335 // 0..n insert in children of parent at pos
2338 QList<QVariant> cData;
2339 cData << "" << "undef";
2344 BranchItem *newbi=new BranchItem (cData);
2345 //newbi->setHeading (QApplication::translate("Heading of new branch in map", "new"));
2347 emit (layoutAboutToBeChanged() );
2353 n=parbi->getRowNumAppend (newbi);
2354 beginInsertRows (parix,n,n);
2355 parbi->appendChild (newbi);
2357 }else if (num==-1 || num==-3)
2359 // insert below selection
2360 parbi=(BranchItem*)dst->parent();
2363 n=dst->childNumber() + (3+num)/2; //-1 |-> 1;-3 |-> 0
2364 beginInsertRows (parix,n,n);
2365 parbi->insertBranch(n,newbi);
2368 emit (layoutChanged() );
2370 // Set color of heading to that of parent
2371 newbi->setHeadingColor (parbi->getHeadingColor());
2373 // save scroll state. If scrolled, automatically select
2374 // new branch in order to tmp unscroll parent...
2375 newbi->createMapObj(mapScene);
2380 BranchItem* VymModel::addNewBranch(int pos)
2382 // Different meaning than num in addNewBranchInt!
2386 BranchItem *newbi=NULL;
2387 BranchItem *selbi=getSelectedBranch();
2391 // FIXME-3 setCursor (Qt::ArrowCursor); //Still needed?
2393 newbi=addNewBranchInt (selbi,pos-2);
2401 QString ("addBranch (%1)").arg(pos),
2402 QString ("Add new branch to %1").arg(getObjectName(selbi)));
2405 // emitSelectionChanged(); FIXME-3
2406 latestAddedItem=newbi;
2407 // In Network mode, the client needs to know where the new branch is,
2408 // so we have to pass on this information via saveState.
2409 // TODO: Get rid of this positioning workaround
2410 /* FIXME-4 network problem: QString ps=qpointfToString (newbo->getAbsPos());
2411 sendData ("selectLatestAdded ()");
2412 sendData (QString("move %1").arg(ps));
2421 BranchItem* VymModel::addNewBranchBefore()
2423 BranchItem *newbi=NULL;
2424 BranchItem *selbi=getSelectedBranch();
2425 if (selbi && selbi->getType()==TreeItem::Branch)
2426 // We accept no MapCenter here, so we _have_ a parent
2428 //QPointF p=bo->getRelPos();
2431 // add below selection
2432 newbi=addNewBranchInt (selbi,-1);
2436 //newbi->move2RelPos (p);
2438 // Move selection to new branch
2439 relinkBranch (selbi,newbi,0);
2441 saveState (newbi, "deleteKeepChildren ()", newbi, "addBranchBefore ()",
2442 QString ("Add branch before %1").arg(getObjectName(selbi)));
2444 // FIXME-3 needed? reposition();
2445 // emitSelectionChanged(); FIXME-3
2451 bool VymModel::relinkBranch (BranchItem *branch, BranchItem *dst, int pos)
2457 // Do we need to update frame type?
2458 bool keepFrame=false;
2461 emit (layoutAboutToBeChanged() );
2462 BranchItem *branchpi=(BranchItem*)branch->parent();
2463 // Remove at current position
2464 int n=branch->childNum();
2466 /* FIXME-4 seg since 20091207, if ModelTest active. strange.
2467 // error occured if relinking branch to empty mainbranch
2468 cout<<"VM::relinkBranch:\n";
2469 cout<<" b="<<branch->getHeadingStd()<<endl;
2470 cout<<" dst="<<dst->getHeadingStd()<<endl;
2471 cout<<" pos="<<pos<<endl;
2472 cout<<" n1="<<n<<endl;
2474 beginRemoveRows (index(branchpi),n,n);
2475 branchpi->removeChild (n);
2478 if (pos<0 ||pos>dst->branchCount() ) pos=dst->branchCount();
2480 // Append as last branch to dst
2481 if (dst->branchCount()==0)
2484 n=dst->getFirstBranch()->childNumber();
2485 beginInsertRows (index(dst),n+pos,n+pos);
2486 dst->insertBranch (pos,branch);
2489 // Correct type if necessesary
2490 if (branch->getType()==TreeItem::MapCenter)
2491 branch->setType(TreeItem::Branch);
2493 // reset parObj, fonts, frame, etc in related LMO or other view-objects
2494 branch->updateStyles(keepFrame);
2496 emit (layoutChanged() );
2497 reposition(); // both for moveUp/Down and relinking
2498 if (dst->isScrolled() )
2501 branch->updateVisibility();
2510 bool VymModel::relinkImage (ImageItem *image, BranchItem *dst)
2514 emit (layoutAboutToBeChanged() );
2516 BranchItem *pi=(BranchItem*)(image->parent());
2517 QString oldParString=getSelectString (pi);
2518 // Remove at current position
2519 int n=image->childNum();
2520 beginRemoveRows (index(pi),n,n);
2521 pi->removeChild (n);
2525 QModelIndex dstix=index(dst);
2526 n=dst->getRowNumAppend (image);
2527 beginInsertRows (dstix,n,n+1);
2528 dst->appendChild (image);
2531 // Set new parent also for lmo
2532 if (image->getLMO() && dst->getLMO() )
2533 image->getLMO()->setParObj (dst->getLMO() );
2535 emit (layoutChanged() );
2538 QString("relinkTo (\"%1\")").arg(oldParString),
2540 QString ("relinkTo (\"%1\")").arg(getSelectString (dst)),
2541 QString ("Relink floatimage to %1").arg(getObjectName(dst)));
2547 void VymModel::cleanupLinks()
2549 // This probably could be done more elegant from destructor of a Link,
2550 // but somehow this resulted in strange segfaults deep in Qt and glibc...
2551 //qDebug ()<<"VM::cleanupLinks begin"<< "CUL="<<cleaningUpLinks;
2552 cleaningUpLinks=true;
2555 while (!xlinks_obsolete.isEmpty())
2557 l=xlinks_obsolete.takeFirst();
2558 xli=l->getBeginLinkItem();
2559 //qDebug()<<"VM::cleanupLinks a) l="<<l<<" xli="<<xli;
2560 if (xli) deleteItem (xli);
2561 xli=l->getEndLinkItem();
2562 //qDebug()<<"VM::cleanupLinks b) l="<<l<<" xli="<<xli;
2563 if (xli) deleteItem (xli);
2566 cleaningUpLinks=false;
2567 //qDebug ()<<"VM::cleanupLinks end";
2570 void VymModel::deleteSelection()
2572 BranchItem *selbi=getSelectedBranch();
2577 saveStateRemovingPart (selbi, QString ("Delete %1").arg(getObjectName(selbi)));
2579 BranchItem *pi=(BranchItem*)(deleteItem (selbi));
2582 if (pi->isScrolled() && pi->branchCount()==0)
2585 emitDataHasChanged(pi);
2588 emitShowSelection();
2593 TreeItem *ti=getSelectedItem();
2596 { // Delete other item
2597 TreeItem *pi=ti->parent();
2599 if (ti->getType()==TreeItem::Image || ti->getType()==TreeItem::Attribute||ti->getType()==TreeItem::XLink)
2601 saveStateChangingPart(
2605 QString("Delete %1").arg(getObjectName(ti))
2609 emitDataHasChanged (pi);
2612 emitShowSelection();
2614 qWarning ("VymmModel::deleteSelection() unknown type?!");
2618 void VymModel::deleteKeepChildren(bool saveStateFlag) //FIXME-3 does not work yet for mapcenters
2621 BranchItem *selbi=getSelectedBranch();
2625 // Don't use this on mapcenter
2626 if (selbi->depth()<2) return;
2628 pi=(BranchItem*)(selbi->parent());
2629 // Check if we have children at all to keep
2630 if (selbi->branchCount()==0)
2637 if (selbi->getLMO()) p=selbi->getLMO()->getRelPos();
2638 if (saveStateFlag) saveStateChangingPart(
2641 "deleteKeepChildren ()",
2642 QString("Remove %1 and keep its children").arg(getObjectName(selbi))
2645 QString sel=getSelectString(selbi);
2647 int pos=selbi->num();
2648 BranchItem *bi=selbi->getFirstBranch();
2651 relinkBranch (bi,pi,pos);
2652 bi=selbi->getFirstBranch();
2658 BranchObj *bo=getSelectedBranchObj();
2661 bo->move2RelPos (p);
2667 void VymModel::deleteChildren()
2670 BranchItem *selbi=getSelectedBranch();
2673 saveStateChangingPart(
2676 "deleteChildren ()",
2677 QString( "Remove children of branch %1").arg(getObjectName(selbi))
2679 emit (layoutAboutToBeChanged() );
2681 QModelIndex ix=index (selbi);
2682 int n=selbi->branchCount()-1;
2683 beginRemoveRows (ix,0,n);
2684 removeRows (0,n+1,ix);
2686 if (selbi->isScrolled()) selbi->unScroll();
2687 emit (layoutChanged() );
2692 TreeItem* VymModel::deleteItem (TreeItem *ti)
2696 TreeItem *pi=ti->parent();
2697 //qDebug()<<"VM::deleteItem start ti="<<ti<<" "<<ti->getHeading()<<" pi="<<pi<<"="<<pi->getHeading();
2698 QModelIndex parentIndex=index(pi);
2700 emit (layoutAboutToBeChanged() );
2702 int n=ti->childNum();
2703 beginRemoveRows (parentIndex,n,n);
2704 removeRows (n,1,parentIndex);
2708 emit (layoutChanged() );
2709 //qDebug()<<"VM::deleteItem end ti="<<ti;
2710 if (!cleaningUpLinks) cleanupLinks();
2711 if (pi->depth()>=0) return pi;
2716 void VymModel::deleteLink(Link* l)
2718 int i=xlinks.indexOf(l);
2719 if (i>-1) xlinks_obsolete.append (xlinks.takeAt (i));
2722 void VymModel::clearItem (TreeItem *ti)
2726 QModelIndex parentIndex=index(ti);
2727 if (!parentIndex.isValid()) return;
2729 int n=ti->childCount();
2732 emit (layoutAboutToBeChanged() );
2734 beginRemoveRows (parentIndex,0,n-1);
2735 removeRows (0,n,parentIndex);
2739 emit (layoutChanged() );
2745 bool VymModel::scrollBranch(BranchItem *bi)
2749 if (bi->isScrolled()) return false;
2750 if (bi->branchCount()==0) return false;
2751 if (bi->depth()==0) return false;
2752 if (bi->toggleScroll())
2760 QString ("%1 ()").arg(u),
2762 QString ("%1 ()").arg(r),
2763 QString ("%1 %2").arg(r).arg(getObjectName(bi))
2765 emitDataHasChanged(bi);
2766 emitSelectionChanged();
2767 mapScene->update(); //Needed for _quick_ update, even in 1.13.x
2774 bool VymModel::unscrollBranch(BranchItem *bi)
2778 if (!bi->isScrolled()) return false;
2779 if (bi->branchCount()==0) return false;
2780 if (bi->depth()==0) return false;
2781 if (bi->toggleScroll())
2789 QString ("%1 ()").arg(u),
2791 QString ("%1 ()").arg(r),
2792 QString ("%1 %2").arg(r).arg(getObjectName(bi))
2794 emitDataHasChanged(bi);
2795 emitSelectionChanged();
2796 mapScene->update(); //Needed for _quick_ update, even in 1.13.x
2803 void VymModel::toggleScroll()
2805 BranchItem *bi=(BranchItem*)getSelectedBranch();
2806 if (bi && bi->isBranchLikeType() )
2808 if (bi->isScrolled())
2809 unscrollBranch (bi);
2813 // saveState & reposition are called in above functions
2816 void VymModel::unscrollChildren()
2818 BranchItem *selbi=getSelectedBranch();
2819 BranchItem *prev=NULL;
2820 BranchItem *cur=selbi;
2823 saveStateChangingPart(
2826 QString ("unscrollChildren ()"),
2827 QString ("unscroll all children of %1").arg(getObjectName(selbi))
2831 if (cur->isScrolled())
2833 cur->toggleScroll();
2834 emitDataHasChanged (cur);
2836 cur=nextBranch (cur,prev,true,selbi);
2843 void VymModel::emitExpandAll()
2845 emit (expandAll() );
2848 void VymModel::emitExpandOneLevel()
2850 emit (expandOneLevel () );
2853 void VymModel::emitCollapseOneLevel()
2855 emit (collapseOneLevel () );
2858 void VymModel::toggleStandardFlag (const QString &name, FlagRow *master)
2860 BranchItem *bi=getSelectedBranch();
2864 if (bi->isActiveStandardFlag(name))
2876 QString("%1 (\"%2\")").arg(u).arg(name),
2878 QString("%1 (\"%2\")").arg(r).arg(name),
2879 QString("Toggling standard flag \"%1\" of %2").arg(name).arg(getObjectName(bi)));
2880 bi->toggleStandardFlag (name, master);
2882 emitSelectionChanged();
2886 void VymModel::addFloatImage (const QPixmap &img)
2888 BranchItem *selbi=getSelectedBranch();
2891 ImageItem *ii=createImage (selbi);
2893 ii->setOriginalFilename("No original filename (image added by dropevent)");
2894 QString s=getSelectString(selbi);
2895 saveState (PartOfMap, s, "nop ()", s, "copy ()","Copy dropped image to clipboard",ii );
2896 saveState (ii,"delete ()", selbi,QString("paste(%1)").arg(curStep),"Pasting dropped image");
2898 // FIXME-3 VM needed? scene()->update();
2903 void VymModel::colorBranch (QColor c)
2905 BranchItem *selbi=getSelectedBranch();
2910 QString ("colorBranch (\"%1\")").arg(selbi->getHeadingColor().name()),
2912 QString ("colorBranch (\"%1\")").arg(c.name()),
2913 QString("Set color of %1 to %2").arg(getObjectName(selbi)).arg(c.name())
2915 selbi->setHeadingColor(c); // color branch
2920 void VymModel::colorSubtree (QColor c)
2922 BranchItem *selbi=getSelectedBranch();
2925 saveStateChangingPart(
2928 QString ("colorSubtree (\"%1\")").arg(c.name()),
2929 QString ("Set color of %1 and children to %2").arg(getObjectName(selbi)).arg(c.name())
2931 BranchItem *prev=NULL;
2932 BranchItem *cur=selbi;
2935 cur->setHeadingColor(c); // color links, color children
2936 cur=nextBranch (cur,prev,true,selbi);
2942 QColor VymModel::getCurrentHeadingColor()
2944 BranchItem *selbi=getSelectedBranch();
2945 if (selbi) return selbi->getHeadingColor();
2947 QMessageBox::warning(0,"Warning","Can't get color of heading,\nthere's no branch selected");
2953 void VymModel::editURL()
2955 TreeItem *selti=getSelectedItem();
2959 QString text = QInputDialog::getText(
2960 "VYM", tr("Enter URL:"), QLineEdit::Normal,
2961 selti->getURL(), &ok, NULL);
2963 // user entered something and pressed OK
2968 void VymModel::editLocalURL()
2970 TreeItem *selti=getSelectedItem();
2973 QStringList filters;
2974 filters <<"All files (*)";
2975 filters << tr("Text","Filedialog") + " (*.txt)";
2976 filters << tr("Spreadsheet","Filedialog") + " (*.odp,*.sxc)";
2977 filters << tr("Textdocument","Filedialog") +" (*.odw,*.sxw)";
2978 filters << tr("Images","Filedialog") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)";
2979 QFileDialog *fd=new QFileDialog( NULL,vymName+" - " +tr("Set URL to a local file"));
2980 fd->setFilters (filters);
2981 fd->setCaption(vymName+" - " +tr("Set URL to a local file"));
2982 fd->setDirectory (lastFileDir);
2983 if (! selti->getVymLink().isEmpty() )
2984 fd->selectFile( selti->getURL() );
2987 if ( fd->exec() == QDialog::Accepted )
2989 lastFileDir=QDir (fd->directory().path());
2990 setURL (fd->selectedFile() );
2996 void VymModel::editHeading2URL()
2998 TreeItem *selti=getSelectedItem();
3000 setURL (selti->getHeading());
3003 void VymModel::editBugzilla2URL()
3005 TreeItem *selti=getSelectedItem();
3008 QString h=selti->getHeading();
3009 QRegExp rx("^(\\d+)");
3010 if (rx.indexIn(h) !=-1)
3011 setURL ("https://bugzilla.novell.com/show_bug.cgi?id="+rx.cap(1) );
3015 void VymModel::getBugzillaData()
3017 BranchItem *selbi=getSelectedBranch();
3020 QString url=selbi->getURL();
3023 QRegExp rx("(\\d+)");
3024 if (rx.indexIn(url) !=-1)
3026 QString bugID=rx.cap(1);
3027 qDebug()<< "VM::getBugzillaData bug="<<bugID;
3029 new BugAgent (selbi,bugID);
3035 void VymModel::editFATE2URL()
3037 TreeItem *selti=getSelectedItem();
3040 QString url= "http://keeper.suse.de:8080/webfate/match/id?value=ID"+selti->getHeading();
3043 "setURL (\""+selti->getURL()+"\")",
3045 "setURL (\""+url+"\")",
3046 QString("Use heading of %1 as link to FATE").arg(getObjectName(selti))
3048 selti->setURL (url);
3049 // FIXME-4 updateActions();
3053 void VymModel::editVymLink()
3055 BranchItem *bi=getSelectedBranch();
3058 QStringList filters;
3059 filters <<"VYM map (*.vym)";
3060 QFileDialog *fd=new QFileDialog( NULL,vymName+" - " +tr("Link to another map"));
3061 fd->setFilters (filters);
3062 fd->setCaption(vymName+" - " +tr("Link to another map"));
3063 fd->setDirectory (lastFileDir);
3064 if (! bi->getVymLink().isEmpty() )
3065 fd->selectFile( bi->getVymLink() );
3069 if ( fd->exec() == QDialog::Accepted )
3071 lastFileDir=QDir (fd->directory().path());
3074 "setVymLink (\""+bi->getVymLink()+"\")",
3076 "setVymLink (\""+fd->selectedFile()+"\")",
3077 QString("Set vymlink of %1 to %2").arg(getObjectName(bi)).arg(fd->selectedFile())
3079 setVymLink (fd->selectedFile() );
3084 void VymModel::setVymLink (const QString &s)
3086 // Internal function, no saveState needed
3087 TreeItem *selti=getSelectedItem();
3090 selti->setVymLink(s);
3092 emitDataHasChanged (selti);
3093 emitShowSelection();
3097 void VymModel::deleteVymLink()
3099 BranchItem *bi=getSelectedBranch();
3104 "setVymLink (\""+bi->getVymLink()+"\")",
3106 "setVymLink (\"\")",
3107 QString("Unset vymlink of %1").arg(getObjectName(bi))
3109 bi->setVymLink ("" );
3115 QString VymModel::getVymLink()
3117 BranchItem *bi=getSelectedBranch();
3119 return bi->getVymLink();
3125 QStringList VymModel::getVymLinks()
3128 BranchItem *selbi=getSelectedBranch();
3129 BranchItem *cur=selbi;
3130 BranchItem *prev=NULL;
3133 if (!cur->getVymLink().isEmpty()) links.append( cur->getVymLink());
3134 cur=nextBranch (cur,prev,true,selbi);
3140 void VymModel::followXLink(int i)
3143 BranchItem *selbi=getSelectedBranch();
3146 selbi=selbi->getXLinkNum(i)->getPartnerBranch();
3147 if (selbi) select (selbi);
3151 void VymModel::editXLink(int i)
3153 BranchItem *selbi=getSelectedBranch();
3156 Link *l=selbi->getXLinkNum(i)->getLink();
3159 EditXLinkDialog dia;
3161 dia.setSelection(selbi);
3162 if (dia.exec() == QDialog::Accepted)
3164 if (dia.useSettingsGlobal() )
3166 setMapDefXLinkColor (l->getColor() );
3167 setMapDefXLinkWidth (l->getWidth() );
3169 if (dia.deleteXLink()) delete (l);
3175 //////////////////////////////////////////////
3177 //////////////////////////////////////////////
3179 QVariant VymModel::parseAtom(const QString &atom, bool &noErr, QString &errorMsg)
3181 TreeItem* selti=getSelectedItem();
3182 BranchItem *selbi=getSelectedBranch();
3187 QVariant returnValue="";
3189 // Split string s into command and parameters
3190 parser.parseAtom (atom);
3191 QString com=parser.getCommand();
3193 // External commands
3194 /////////////////////////////////////////////////////////////////////
3195 if (com=="addBranch")
3199 parser.setError (Aborted,"Nothing selected");
3200 } else if (! selbi )
3202 parser.setError (Aborted,"Type of selection is not a branch");
3207 if (parser.checkParCount(pl))
3209 if (parser.parCount()==0)
3213 n=parser.parInt (ok,0);
3214 if (ok ) addNewBranch (n);
3218 /////////////////////////////////////////////////////////////////////
3219 } else if (com=="addBranchBefore")
3223 parser.setError (Aborted,"Nothing selected");
3224 } else if (! selbi )
3226 parser.setError (Aborted,"Type of selection is not a branch");
3229 if (parser.parCount()==0)
3231 addNewBranchBefore ();
3234 /////////////////////////////////////////////////////////////////////
3235 } else if (com==QString("addMapCenter"))
3237 if (parser.checkParCount(2))
3239 x=parser.parDouble (ok,0);
3242 y=parser.parDouble (ok,1);
3243 if (ok) addMapCenter (QPointF(x,y));
3246 /////////////////////////////////////////////////////////////////////
3247 } else if (com==QString("addMapReplace"))
3251 parser.setError (Aborted,"Nothing selected");
3252 } else if (! selbi )
3254 parser.setError (Aborted,"Type of selection is not a branch");
3255 } else if (parser.checkParCount(1))
3257 //s=parser.parString (ok,0); // selection
3258 t=parser.parString (ok,0); // path to map
3259 if (QDir::isRelativePath(t)) t=(tmpMapDir + "/"+t);
3260 loadMap (t,ImportReplace,false,VymMap,n);
3262 /////////////////////////////////////////////////////////////////////
3263 } else if (com==QString("addMapInsert"))
3265 if (parser.parCount()==2)
3270 parser.setError (Aborted,"Nothing selected");
3271 } else if (! selbi )
3273 parser.setError (Aborted,"Type of selection is not a branch");
3276 t=parser.parString (ok,0); // path to map
3277 n=parser.parInt(ok,1); // position
3278 if (QDir::isRelativePath(t)) t=(tmpMapDir + "/"+t);
3279 loadMap (t,ImportAdd,false,VymMap,n);
3281 } else if (parser.parCount()==1)
3283 t=parser.parString (ok,0); // path to map
3284 if (QDir::isRelativePath(t)) t=(tmpMapDir + "/"+t);
3285 loadMap (t,ImportAdd,false);
3287 parser.setError (Aborted,"Wrong number of parameters");
3288 /////////////////////////////////////////////////////////////////////
3289 } else if (com==QString("addXLink"))
3291 if (parser.parCount()>1)
3293 s=parser.parString (ok,0); // begin
3294 t=parser.parString (ok,1); // end
3295 BranchItem *begin=(BranchItem*)findBySelectString(s);
3296 BranchItem *end=(BranchItem*)findBySelectString(t);
3299 if (begin->isBranchLikeType() && end->isBranchLikeType())
3301 Link *li=new Link (this);
3302 li->setBeginBranch ( (BranchItem*)begin );
3303 li->setEndBranch ( (BranchItem*)end);
3305 createLink (li,true); // create MO by default
3308 parser.setError (Aborted,"begin or end of xLink are not branch or mapcenter");
3311 parser.setError (Aborted,"Couldn't select begin or end of xLink");
3313 parser.setError (Aborted,"Need at least 2 parameters for begin and end");
3314 /////////////////////////////////////////////////////////////////////
3315 } else if (com=="clearFlags")
3319 parser.setError (Aborted,"Nothing selected");
3320 } else if (! selbi )
3322 parser.setError (Aborted,"Type of selection is not a branch");
3323 } else if (parser.checkParCount(0))
3325 selbi->deactivateAllStandardFlags();
3327 emitDataHasChanged(selbi);
3328 emitSelectionChanged();
3331 /////////////////////////////////////////////////////////////////////
3332 } else if (com=="colorBranch")
3336 parser.setError (Aborted,"Nothing selected");
3337 } else if (! selbi )
3339 parser.setError (Aborted,"Type of selection is not a branch");
3340 } else if (parser.checkParCount(1))
3342 QColor c=parser.parColor (ok,0);
3343 if (ok) colorBranch (c);
3345 /////////////////////////////////////////////////////////////////////
3346 } else if (com=="colorSubtree")
3350 parser.setError (Aborted,"Nothing selected");
3351 } else if (! selbi )
3353 parser.setError (Aborted,"Type of selection is not a branch");
3354 } else if (parser.checkParCount(1))
3356 QColor c=parser.parColor (ok,0);
3357 if (ok) colorSubtree (c);
3359 /////////////////////////////////////////////////////////////////////
3360 } else if (com=="copy")
3364 parser.setError (Aborted,"Nothing selected");
3365 } else if ( selectionType()!=TreeItem::Branch &&
3366 selectionType()!=TreeItem::MapCenter &&
3367 selectionType()!=TreeItem::Image )
3369 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
3370 } else if (parser.checkParCount(0))
3374 /////////////////////////////////////////////////////////////////////
3375 } else if (com=="cut")
3379 parser.setError (Aborted,"Nothing selected");
3380 } else if ( selectionType()!=TreeItem::Branch &&
3381 selectionType()!=TreeItem::MapCenter &&
3382 selectionType()!=TreeItem::Image )
3384 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
3385 } else if (parser.checkParCount(0))
3389 /////////////////////////////////////////////////////////////////////
3390 } else if (com=="delete")
3394 parser.setError (Aborted,"Nothing selected");
3396 /*else if (selectionType() != TreeItem::Branch && selectionType() != TreeItem::Image )
3398 parser.setError (Aborted,"Type of selection is wrong.");
3401 else if (parser.checkParCount(0))
3405 /////////////////////////////////////////////////////////////////////
3406 } else if (com=="deleteKeepChildren")
3410 parser.setError (Aborted,"Nothing selected");
3411 } else if (! selbi )
3413 parser.setError (Aborted,"Type of selection is not a branch");
3414 } else if (parser.checkParCount(0))
3416 deleteKeepChildren();
3418 /////////////////////////////////////////////////////////////////////
3419 } else if (com=="deleteChildren")
3423 parser.setError (Aborted,"Nothing selected");
3426 parser.setError (Aborted,"Type of selection is not a branch");
3427 } else if (parser.checkParCount(0))
3431 /////////////////////////////////////////////////////////////////////
3432 } else if (com=="exportAO")
3436 if (parser.parCount()>=1)
3437 // Hey, we even have a filename
3438 fname=parser.parString(ok,0);
3441 parser.setError (Aborted,"Could not read filename");
3444 exportAO (fname,false);
3446 /////////////////////////////////////////////////////////////////////
3447 } else if (com=="exportASCII")
3451 if (parser.parCount()>=1)
3452 // Hey, we even have a filename
3453 fname=parser.parString(ok,0);
3456 parser.setError (Aborted,"Could not read filename");
3459 exportASCII (fname,false);
3461 /////////////////////////////////////////////////////////////////////
3462 } else if (com=="exportImage")
3466 if (parser.parCount()>=2)
3467 // Hey, we even have a filename
3468 fname=parser.parString(ok,0);
3471 parser.setError (Aborted,"Could not read filename");
3474 QString format="PNG";
3475 if (parser.parCount()>=2)
3477 format=parser.parString(ok,1);
3479 exportImage (fname,false,format);
3481 /////////////////////////////////////////////////////////////////////
3482 } else if (com=="exportXML")
3486 if (parser.parCount()>=2)
3487 // Hey, we even have a filename
3488 fname=parser.parString(ok,1);
3491 parser.setError (Aborted,"Could not read filename");
3494 exportXML (fname,false);
3496 /////////////////////////////////////////////////////////////////////
3497 } else if (com=="getHeading")
3501 parser.setError (Aborted,"Nothing selected");
3502 } else if (parser.checkParCount(0))
3503 returnValue=selti->getHeading();
3504 /////////////////////////////////////////////////////////////////////
3505 } else if (com=="importDir")
3509 parser.setError (Aborted,"Nothing selected");
3510 } else if (! selbi )
3512 parser.setError (Aborted,"Type of selection is not a branch");
3513 } else if (parser.checkParCount(1))
3515 s=parser.parString(ok,0);
3516 if (ok) importDirInt(s);
3518 /////////////////////////////////////////////////////////////////////
3519 } else if (com=="relinkTo")
3523 parser.setError (Aborted,"Nothing selected");
3526 if (parser.checkParCount(4))
3528 // 0 selectstring of parent
3529 // 1 num in parent (for branches)
3530 // 2,3 x,y of mainbranch or mapcenter
3531 s=parser.parString(ok,0);
3532 TreeItem *dst=findBySelectString (s);
3535 if (dst->getType()==TreeItem::Branch)
3537 // Get number in parent
3538 n=parser.parInt (ok,1);
3541 relinkBranch (selbi,(BranchItem*)dst,n);
3542 emitSelectionChanged();
3544 } else if (dst->getType()==TreeItem::MapCenter)
3546 relinkBranch (selbi,(BranchItem*)dst);
3547 // Get coordinates of mainbranch
3548 x=parser.parDouble(ok,2);
3551 y=parser.parDouble(ok,3);
3554 if (selbi->getLMO()) selbi->getLMO()->move (x,y);
3555 emitSelectionChanged();
3561 } else if ( selti->getType() == TreeItem::Image)
3563 if (parser.checkParCount(1))
3565 // 0 selectstring of parent
3566 s=parser.parString(ok,0);
3567 TreeItem *dst=findBySelectString (s);
3570 if (dst->isBranchLikeType())
3571 relinkImage ( ((ImageItem*)selti),(BranchItem*)dst);
3573 parser.setError (Aborted,"Destination is not a branch");
3576 parser.setError (Aborted,"Type of selection is not a floatimage or branch");
3577 /////////////////////////////////////////////////////////////////////
3578 } else if (com=="loadImage")
3582 parser.setError (Aborted,"Nothing selected");
3583 } else if (! selbi )
3585 parser.setError (Aborted,"Type of selection is not a branch");
3586 } else if (parser.checkParCount(1))
3588 s=parser.parString(ok,0);
3589 if (ok) loadFloatImageInt (selbi,s);
3591 /////////////////////////////////////////////////////////////////////
3592 } else if (com=="loadNote")
3596 parser.setError (Aborted,"Nothing selected");
3597 } else if (! selbi )
3599 parser.setError (Aborted,"Type of selection is not a branch");
3600 } else if (parser.checkParCount(1))
3602 s=parser.parString(ok,0);
3603 if (ok) loadNote (s);
3605 /////////////////////////////////////////////////////////////////////
3606 } else if (com=="moveUp")
3610 parser.setError (Aborted,"Nothing selected");
3611 } else if (! selbi )
3613 parser.setError (Aborted,"Type of selection is not a branch");
3614 } else if (parser.checkParCount(0))
3618 /////////////////////////////////////////////////////////////////////
3619 } else if (com=="moveDown")
3623 parser.setError (Aborted,"Nothing selected");
3624 } else if (! selbi )
3626 parser.setError (Aborted,"Type of selection is not a branch");
3627 } else if (parser.checkParCount(0))
3631 /////////////////////////////////////////////////////////////////////
3632 } else if (com=="move")
3636 parser.setError (Aborted,"Nothing selected");
3637 } else if ( selectionType()!=TreeItem::Branch &&
3638 selectionType()!=TreeItem::MapCenter &&
3639 selectionType()!=TreeItem::Image )
3641 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
3642 } else if (parser.checkParCount(2))
3644 x=parser.parDouble (ok,0);
3647 y=parser.parDouble (ok,1);
3651 /////////////////////////////////////////////////////////////////////
3652 } else if (com=="moveRel")
3656 parser.setError (Aborted,"Nothing selected");
3657 } else if ( selectionType()!=TreeItem::Branch &&
3658 selectionType()!=TreeItem::MapCenter &&
3659 selectionType()!=TreeItem::Image )
3661 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
3662 } else if (parser.checkParCount(2))
3664 x=parser.parDouble (ok,0);
3667 y=parser.parDouble (ok,1);
3668 if (ok) moveRel (x,y);
3671 /////////////////////////////////////////////////////////////////////
3672 } else if (com=="nop")
3674 /////////////////////////////////////////////////////////////////////
3675 } else if (com=="paste")
3679 parser.setError (Aborted,"Nothing selected");
3680 } else if (! selbi )
3682 parser.setError (Aborted,"Type of selection is not a branch");
3683 } else if (parser.checkParCount(1))
3685 n=parser.parInt (ok,0);
3686 if (ok) pasteNoSave(n);
3688 /////////////////////////////////////////////////////////////////////
3689 } else if (com=="qa")
3693 parser.setError (Aborted,"Nothing selected");
3694 } else if (! selbi )
3696 parser.setError (Aborted,"Type of selection is not a branch");
3697 } else if (parser.checkParCount(4))
3700 c=parser.parString (ok,0);
3703 parser.setError (Aborted,"No comment given");
3706 s=parser.parString (ok,1);
3709 parser.setError (Aborted,"First parameter is not a string");
3712 t=parser.parString (ok,2);
3715 parser.setError (Aborted,"Condition is not a string");
3718 u=parser.parString (ok,3);
3721 parser.setError (Aborted,"Third parameter is not a string");
3726 parser.setError (Aborted,"Unknown type: "+s);
3731 parser.setError (Aborted,"Unknown operator: "+t);
3736 parser.setError (Aborted,"Type of selection is not a branch");
3739 if (selbi->getHeading() == u)
3741 cout << "PASSED: " << qPrintable (c) << endl;
3744 cout << "FAILED: " << qPrintable (c) << endl;
3754 /////////////////////////////////////////////////////////////////////
3755 } else if (com=="saveImage")
3757 ImageItem *ii=getSelectedImage();
3760 parser.setError (Aborted,"No image selected");
3761 } else if (parser.checkParCount(2))
3763 s=parser.parString(ok,0);
3766 t=parser.parString(ok,1);
3767 if (ok) saveFloatImageInt (ii,t,s);
3770 /////////////////////////////////////////////////////////////////////
3771 } else if (com=="saveNote")
3775 parser.setError (Aborted,"Nothing selected");
3776 } else if (! selbi )
3778 parser.setError (Aborted,"Type of selection is not a branch");
3779 } else if (parser.checkParCount(1))
3781 s=parser.parString(ok,0);
3782 if (ok) saveNote (s);
3784 /////////////////////////////////////////////////////////////////////
3785 } else if (com=="scroll")
3789 parser.setError (Aborted,"Nothing selected");
3790 } else if (! selbi )
3792 parser.setError (Aborted,"Type of selection is not a branch");
3793 } else if (parser.checkParCount(0))
3795 if (!scrollBranch (selbi))
3796 parser.setError (Aborted,"Could not scroll branch");
3798 /////////////////////////////////////////////////////////////////////
3799 } else if (com=="select")
3801 if (parser.checkParCount(1))
3803 s=parser.parString(ok,0);
3806 /////////////////////////////////////////////////////////////////////
3807 } else if (com=="selectLastBranch")
3811 parser.setError (Aborted,"Nothing selected");
3812 } else if (! selbi )
3814 parser.setError (Aborted,"Type of selection is not a branch");
3815 } else if (parser.checkParCount(0))
3817 BranchItem *bi=selbi->getLastBranch();
3819 parser.setError (Aborted,"Could not select last branch");
3820 select (bi); // FIXME-3 was selectInt
3823 /////////////////////////////////////////////////////////////////////
3824 } else /* FIXME-2 if (com=="selectLastImage")
3828 parser.setError (Aborted,"Nothing selected");
3829 } else if (! selbi )
3831 parser.setError (Aborted,"Type of selection is not a branch");
3832 } else if (parser.checkParCount(0))
3834 FloatImageObj *fio=selb->getLastFloatImage();
3836 parser.setError (Aborted,"Could not select last image");
3837 select (fio); // FIXME-3 was selectInt
3840 /////////////////////////////////////////////////////////////////////
3841 } else */ if (com=="selectLatestAdded")
3843 if (!latestAddedItem)
3845 parser.setError (Aborted,"No latest added object");
3848 if (!select (latestAddedItem))
3849 parser.setError (Aborted,"Could not select latest added object ");
3851 /////////////////////////////////////////////////////////////////////
3852 } else if (com=="setFlag")
3856 parser.setError (Aborted,"Nothing selected");
3857 } else if (! selbi )
3859 parser.setError (Aborted,"Type of selection is not a branch");
3860 } else if (parser.checkParCount(1))
3862 s=parser.parString(ok,0);
3864 selbi->activateStandardFlag(s);
3866 /////////////////////////////////////////////////////////////////////
3867 } else if (com=="setFrameType")
3869 if ( selectionType()!=TreeItem::Branch && selectionType()!= TreeItem::MapCenter && selectionType()!=TreeItem::Image)
3871 parser.setError (Aborted,"Type of selection does not allow setting frame type");
3873 else if (parser.checkParCount(1))
3875 s=parser.parString(ok,0);
3876 if (ok) setFrameType (s);
3878 /////////////////////////////////////////////////////////////////////
3879 } else if (com=="setFramePenColor")
3881 if ( selectionType()!=TreeItem::Branch && selectionType()!= TreeItem::MapCenter && selectionType()!=TreeItem::Image)
3883 parser.setError (Aborted,"Type of selection does not allow setting of pen color");
3885 else if (parser.checkParCount(1))
3887 QColor c=parser.parColor(ok,0);
3888 if (ok) setFramePenColor (c);
3890 /////////////////////////////////////////////////////////////////////
3891 } else if (com=="setFrameBrushColor")
3893 if ( selectionType()!=TreeItem::Branch && selectionType()!= TreeItem::MapCenter && selectionType()!=TreeItem::Image)
3895 parser.setError (Aborted,"Type of selection does not allow setting brush color");
3897 else if (parser.checkParCount(1))
3899 QColor c=parser.parColor(ok,0);
3900 if (ok) setFrameBrushColor (c);
3902 /////////////////////////////////////////////////////////////////////
3903 } else if (com=="setFramePadding")
3905 if ( selectionType()!=TreeItem::Branch && selectionType()!= TreeItem::MapCenter && selectionType()!=TreeItem::Image)
3907 parser.setError (Aborted,"Type of selection does not allow setting frame padding");
3909 else if (parser.checkParCount(1))
3911 n=parser.parInt(ok,0);
3912 if (ok) setFramePadding(n);
3914 /////////////////////////////////////////////////////////////////////
3915 } else if (com=="setFrameBorderWidth")
3917 if ( selectionType()!=TreeItem::Branch && selectionType()!= TreeItem::MapCenter && selectionType()!=TreeItem::Image)
3919 parser.setError (Aborted,"Type of selection does not allow setting frame border width");
3921 else if (parser.checkParCount(1))
3923 n=parser.parInt(ok,0);
3924 if (ok) setFrameBorderWidth (n);
3926 /////////////////////////////////////////////////////////////////////
3927 /* FIXME-2 else if (com=="setFrameType")
3931 parser.setError (Aborted,"Nothing selected");
3934 parser.setError (Aborted,"Type of selection is not a branch");
3935 } else if (parser.checkParCount(1))
3937 s=parser.parString(ok,0);
3941 /////////////////////////////////////////////////////////////////////
3943 /////////////////////////////////////////////////////////////////////
3944 } else if (com=="setHeading")
3948 parser.setError (Aborted,"Nothing selected");
3949 } else if (! selbi )
3951 parser.setError (Aborted,"Type of selection is not a branch");
3952 } else if (parser.checkParCount(1))
3954 s=parser.parString (ok,0);
3958 /////////////////////////////////////////////////////////////////////
3959 } else if (com=="setHideExport")
3963 parser.setError (Aborted,"Nothing selected");
3964 } else if (selectionType()!=TreeItem::Branch && selectionType() != TreeItem::MapCenter &&selectionType()!=TreeItem::Image)
3966 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
3967 } else if (parser.checkParCount(1))
3969 b=parser.parBool(ok,0);
3970 if (ok) setHideExport (b);
3972 /////////////////////////////////////////////////////////////////////
3973 } else if (com=="setIncludeImagesHorizontally")
3977 parser.setError (Aborted,"Nothing selected");
3980 parser.setError (Aborted,"Type of selection is not a branch");
3981 } else if (parser.checkParCount(1))
3983 b=parser.parBool(ok,0);
3984 if (ok) setIncludeImagesHor(b);
3986 /////////////////////////////////////////////////////////////////////
3987 } else if (com=="setIncludeImagesVertically")
3991 parser.setError (Aborted,"Nothing selected");
3994 parser.setError (Aborted,"Type of selection is not a branch");
3995 } else if (parser.checkParCount(1))
3997 b=parser.parBool(ok,0);
3998 if (ok) setIncludeImagesVer(b);
4000 /////////////////////////////////////////////////////////////////////
4001 } else if (com=="setHideLinkUnselected")
4005 parser.setError (Aborted,"Nothing selected");
4006 } else if ( selectionType()!=TreeItem::Branch && selectionType()!= TreeItem::MapCenter && selectionType()!=TreeItem::Image)
4008 parser.setError (Aborted,"Type of selection does not allow hiding the link");
4009 } else if (parser.checkParCount(1))
4011 b=parser.parBool(ok,0);
4012 if (ok) setHideLinkUnselected(b);
4014 /////////////////////////////////////////////////////////////////////
4015 } else if (com=="setMapAuthor")
4017 if (parser.checkParCount(1))
4019 s=parser.parString(ok,0);
4020 if (ok) setAuthor (s);
4022 /////////////////////////////////////////////////////////////////////
4023 } else if (com=="setMapComment")
4025 if (parser.checkParCount(1))
4027 s=parser.parString(ok,0);
4028 if (ok) setComment(s);
4030 /////////////////////////////////////////////////////////////////////
4031 } else if (com=="setMapBackgroundColor")
4035 parser.setError (Aborted,"Nothing selected");
4036 } else if (! selbi )
4038 parser.setError (Aborted,"Type of selection is not a branch");
4039 } else if (parser.checkParCount(1))
4041 QColor c=parser.parColor (ok,0);
4042 if (ok) setMapBackgroundColor (c);
4044 /////////////////////////////////////////////////////////////////////
4045 } else if (com=="setMapDefLinkColor")
4049 parser.setError (Aborted,"Nothing selected");
4050 } else if (! selbi )
4052 parser.setError (Aborted,"Type of selection is not a branch");
4053 } else if (parser.checkParCount(1))
4055 QColor c=parser.parColor (ok,0);
4056 if (ok) setMapDefLinkColor (c);
4058 /////////////////////////////////////////////////////////////////////
4059 } else if (com=="setMapLinkStyle")
4061 if (parser.checkParCount(1))
4063 s=parser.parString (ok,0);
4064 if (ok) setMapLinkStyle(s);
4066 /////////////////////////////////////////////////////////////////////
4067 } else if (com=="setNote")
4071 parser.setError (Aborted,"Nothing selected");
4072 } else if (! selbi )
4074 parser.setError (Aborted,"Type of selection is not a branch");
4075 } else if (parser.checkParCount(1))
4077 s=parser.parString (ok,0);
4081 /////////////////////////////////////////////////////////////////////
4082 } else if (com=="setSelectionColor")
4084 if (parser.checkParCount(1))
4086 QColor c=parser.parColor (ok,0);
4087 if (ok) setSelectionColorInt (c);
4089 /////////////////////////////////////////////////////////////////////
4090 } else if (com=="setURL")
4094 parser.setError (Aborted,"Nothing selected");
4095 } else if (! selbi )
4097 parser.setError (Aborted,"Type of selection is not a branch");
4098 } else if (parser.checkParCount(1))
4100 s=parser.parString (ok,0);
4103 /////////////////////////////////////////////////////////////////////
4104 } else if (com=="setVymLink")
4108 parser.setError (Aborted,"Nothing selected");
4109 } else if (! selbi )
4111 parser.setError (Aborted,"Type of selection is not a branch");
4112 } else if (parser.checkParCount(1))
4114 s=parser.parString (ok,0);
4115 if (ok) setVymLink(s);
4117 } else if (com=="sortChildren")
4121 parser.setError (Aborted,"Nothing selected");
4122 } else if (! selbi )
4124 parser.setError (Aborted,"Type of selection is not a branch");
4125 } else if (parser.checkParCount(0))
4128 } else if (parser.checkParCount(1))
4130 b=parser.parBool(ok,0);
4131 if (ok) sortChildren(b);
4133 /////////////////////////////////////////////////////////////////////
4134 } else if (com=="toggleFlag")
4138 parser.setError (Aborted,"Nothing selected");
4139 } else if (! selbi )
4141 parser.setError (Aborted,"Type of selection is not a branch");
4142 } else if (parser.checkParCount(1))
4144 s=parser.parString(ok,0);
4146 selbi->toggleStandardFlag(s);
4148 /////////////////////////////////////////////////////////////////////
4149 } else if (com=="unscroll")
4153 parser.setError (Aborted,"Nothing selected");
4154 } else if (! selbi )
4156 parser.setError (Aborted,"Type of selection is not a branch");
4157 } else if (parser.checkParCount(0))
4159 if (!unscrollBranch (selbi))
4160 parser.setError (Aborted,"Could not unscroll branch");
4162 /////////////////////////////////////////////////////////////////////
4163 } else if (com=="unscrollChildren")
4167 parser.setError (Aborted,"Nothing selected");
4168 } else if (! selbi )
4170 parser.setError (Aborted,"Type of selection is not a branch");
4171 } else if (parser.checkParCount(0))
4173 unscrollChildren ();
4175 /////////////////////////////////////////////////////////////////////
4176 } else if (com=="unsetFlag")
4180 parser.setError (Aborted,"Nothing selected");
4181 } else if (! selbi )
4183 parser.setError (Aborted,"Type of selection is not a branch");
4184 } else if (parser.checkParCount(1))
4186 s=parser.parString(ok,0);
4188 selbi->deactivateStandardFlag(s);
4191 parser.setError (Aborted,"Unknown command");
4194 if (parser.errorLevel()==NoError)
4202 // TODO Error handling
4203 qWarning("VymModel::parseAtom: Error!");
4205 qWarning(parser.errorMessage());
4207 errorMsg=parser.errorMessage();
4208 returnValue=errorMsg;
4213 QVariant VymModel::runScript (const QString &script)
4215 parser.setScript (script);
4220 while (parser.next() && noErr)
4222 r=parseAtom(parser.getAtom(),noErr,errMsg);
4223 if (!noErr) //FIXME-3 need dialog box here
4224 cout << "VM::runScript aborted:\n"<<errMsg.toStdString()<<endl;
4229 void VymModel::setExportMode (bool b)
4231 // should be called before and after exports
4232 // depending on the settings
4233 if (b && settings.value("/export/useHideExport","true")=="true")
4234 setHideTmpMode (TreeItem::HideExport);
4236 setHideTmpMode (TreeItem::HideNone);
4239 void VymModel::exportImage(QString fname, bool askName, QString format)
4243 fname=getMapName()+".png";
4250 QFileDialog *fd=new QFileDialog (NULL);
4251 fd->setCaption (tr("Export map as image"));
4252 fd->setDirectory (lastImageDir);
4253 fd->setFileMode(QFileDialog::AnyFile);
4254 fd->setFilters (imageIO.getFilters() );
4257 fl=fd->selectedFiles();
4259 format=imageIO.getType(fd->selectedFilter());
4263 setExportMode (true);
4264 mapEditor->getScene()->update(); // FIXME-3 check this...
4265 QImage img (mapEditor->getImage()); //FIXME-3 calls getTotalBBox, but also in ExportHTML::doExport()
4266 img.save(fname, format);
4267 setExportMode (false);
4271 void VymModel::exportXML(QString dir, bool askForName)
4275 dir=browseDirectory(NULL,tr("Export XML to directory"));
4276 if (dir =="" && !reallyWriteDirectory(dir) )
4280 // Hide stuff during export, if settings want this
4281 setExportMode (true);
4283 // Create subdirectories
4286 // write to directory //FIXME-4 check totalBBox here...
4287 QString saveFile=saveToDir (dir,mapName+"-",true,mapEditor->getTotalBBox().topLeft() ,NULL);
4290 file.setName ( dir + "/"+mapName+".xml");
4291 if ( !file.open( QIODevice::WriteOnly ) )
4293 // This should neverever happen
4294 QMessageBox::critical (0,tr("Critical Export Error"),tr("VymModel::exportXML couldn't open %1").arg(file.name()));
4298 // Write it finally, and write in UTF8, no matter what
4299 QTextStream ts( &file );
4300 ts.setEncoding (QTextStream::UnicodeUTF8);
4304 // Now write image, too
4305 exportImage (dir+"/images/"+mapName+".png",false,"PNG");
4307 setExportMode (false);
4310 void VymModel::exportAO (QString fname,bool askName)
4315 ex.setFile (mapName+".txt");
4321 //ex.addFilter ("TXT (*.txt)");
4322 ex.setDir(lastImageDir);
4323 //ex.setCaption(vymName+ " -" +tr("Export as A&O report")+" "+tr("(still experimental)"));
4328 setExportMode(true);
4330 setExportMode(false);
4334 void VymModel::exportASCII(QString fname,bool askName)
4339 ex.setFile (mapName+".txt");
4345 //ex.addFilter ("TXT (*.txt)");
4346 ex.setDir(lastImageDir);
4347 //ex.setCaption(vymName+ " -" +tr("Export as ASCII")+" "+tr("(still experimental)"));
4352 setExportMode(true);
4354 setExportMode(false);
4358 void VymModel::exportHTML (const QString &dir, bool useDialog)
4360 ExportHTML ex (this);
4362 ex.doExport(useDialog);
4365 void VymModel::exportOOPresentation(const QString &fn, const QString &cf)
4370 if (ex.setConfigFile(cf))
4372 setExportMode (true);
4373 ex.exportPresentation();
4374 setExportMode (false);
4381 //////////////////////////////////////////////
4383 //////////////////////////////////////////////
4385 void VymModel::registerEditor(QWidget *me)
4387 mapEditor=(MapEditor*)me;
4390 void VymModel::unregisterEditor(QWidget *)
4395 void VymModel::setMapZoomFactor (const double &d)
4400 void VymModel::setContextPos(QPointF p)
4405 void VymModel::unsetContextPos()
4407 contextPos=QPointF();
4410 void VymModel::updateNoteFlag()
4412 TreeItem *selti=getSelectedItem();
4421 if (textEditor->isEmpty())
4424 selti->setNote (textEditor->getText());
4425 emitDataHasChanged(selti);
4429 void VymModel::reposition() //FIXME-4 VM should have no need to reposition, but the views...
4431 //cout << "VM::reposition blocked="<<blockReposition<<endl;
4432 if (blockReposition) return;
4435 for (int i=0;i<rootItem->branchCount(); i++)
4437 bo=rootItem->getBranchObjNum(i);
4439 bo->reposition(); // for positioning heading
4441 qDebug()<<"VM::reposition bo=0";
4443 //emitSelectionChanged();
4447 void VymModel::setMapLinkStyle (const QString & s)
4452 case LinkableMapObj::Line :
4455 case LinkableMapObj::Parabel:
4456 snow="StyleParabel";
4458 case LinkableMapObj::PolyLine:
4459 snow="StylePolyLine";
4461 case LinkableMapObj::PolyParabel:
4462 snow="StylePolyParabel";
4465 snow="UndefinedStyle";
4470 QString("setMapLinkStyle (\"%1\")").arg(s),
4471 QString("setMapLinkStyle (\"%1\")").arg(snow),
4472 QString("Set map link style (\"%1\")").arg(s)
4476 linkstyle=LinkableMapObj::Line;
4477 else if (s=="StyleParabel")
4478 linkstyle=LinkableMapObj::Parabel;
4479 else if (s=="StylePolyLine")
4480 linkstyle=LinkableMapObj::PolyLine;
4481 else if (s=="StylePolyParabel")
4482 linkstyle=LinkableMapObj::PolyParabel;
4484 linkstyle=LinkableMapObj::UndefinedStyle;
4486 BranchItem *cur=NULL;
4487 BranchItem *prev=NULL;
4489 nextBranch (cur,prev);
4492 bo=(BranchObj*)(cur->getLMO() );
4493 bo->setLinkStyle(bo->getDefLinkStyle(cur->parent() )); //FIXME-3 better emit dataCHanged and leave the changes to View
4494 cur=nextBranch(cur,prev);
4499 LinkableMapObj::Style VymModel::getMapLinkStyle ()
4504 uint VymModel::getID()
4509 void VymModel::setMapDefLinkColor(QColor col)
4511 if ( !col.isValid() ) return;
4513 QString("setMapDefLinkColor (\"%1\")").arg(getMapDefLinkColor().name()),
4514 QString("setMapDefLinkColor (\"%1\")").arg(col.name()),
4515 QString("Set map link color to %1").arg(col.name())
4519 BranchItem *cur=NULL;
4520 BranchItem *prev=NULL;
4522 cur=nextBranch(cur,prev);
4525 bo=(BranchObj*)(cur->getLMO() );
4527 nextBranch(cur,prev);
4532 void VymModel::setMapLinkColorHintInt()
4534 // called from setMapLinkColorHint(lch) or at end of parse
4535 BranchItem *cur=NULL;
4536 BranchItem *prev=NULL;
4538 cur=nextBranch(cur,prev);
4541 bo=(BranchObj*)(cur->getLMO() );
4543 cur=nextBranch(cur,prev);
4547 void VymModel::setMapLinkColorHint(LinkableMapObj::ColorHint lch)
4550 setMapLinkColorHintInt();
4553 void VymModel::toggleMapLinkColorHint()
4555 if (linkcolorhint==LinkableMapObj::HeadingColor)
4556 linkcolorhint=LinkableMapObj::DefaultColor;
4558 linkcolorhint=LinkableMapObj::HeadingColor;
4559 BranchItem *cur=NULL;
4560 BranchItem *prev=NULL;
4562 cur=nextBranch(cur,prev);
4565 bo=(BranchObj*)(cur->getLMO() );
4567 nextBranch(cur,prev);
4571 void VymModel::selectMapBackgroundImage () // FIXME-3 for using background image: view.setCacheMode(QGraphicsView::CacheBackground); Also this belongs into ME
4573 Q3FileDialog *fd=new Q3FileDialog( NULL);
4574 fd->setMode (Q3FileDialog::ExistingFile);
4575 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
4576 ImagePreview *p =new ImagePreview (fd);
4577 fd->setContentsPreviewEnabled( TRUE );
4578 fd->setContentsPreview( p, p );
4579 fd->setPreviewMode( Q3FileDialog::Contents );
4580 fd->setCaption(vymName+" - " +tr("Load background image"));
4581 fd->setDir (lastImageDir);
4584 if ( fd->exec() == QDialog::Accepted )
4586 // TODO selectMapBackgroundImg in QT4 use: lastImageDir=fd->directory();
4587 lastImageDir=QDir (fd->dirPath());
4588 setMapBackgroundImage (fd->selectedFile());
4592 void VymModel::setMapBackgroundImage (const QString &fn) //FIXME-3 missing savestate, move to ME
4594 QColor oldcol=mapScene->backgroundBrush().color();
4598 QString ("setMapBackgroundImage (%1)").arg(oldcol.name()),
4600 QString ("setMapBackgroundImage (%1)").arg(col.name()),
4601 QString("Set background color of map to %1").arg(col.name()));
4604 brush.setTextureImage (QPixmap (fn));
4605 mapScene->setBackgroundBrush(brush);
4608 void VymModel::selectMapBackgroundColor() // FIXME-3 move to ME
4610 QColor col = QColorDialog::getColor( mapScene->backgroundBrush().color(), NULL);
4611 if ( !col.isValid() ) return;
4612 setMapBackgroundColor( col );
4616 void VymModel::setMapBackgroundColor(QColor col) // FIXME-3 move to ME
4618 QColor oldcol=mapScene->backgroundBrush().color();
4620 QString ("setMapBackgroundColor (\"%1\")").arg(oldcol.name()),
4621 QString ("setMapBackgroundColor (\"%1\")").arg(col.name()),
4622 QString("Set background color of map to %1").arg(col.name()));
4623 mapScene->setBackgroundBrush(col);
4626 QColor VymModel::getMapBackgroundColor() // FIXME-3 move to ME
4628 return mapScene->backgroundBrush().color();
4632 LinkableMapObj::ColorHint VymModel::getMapLinkColorHint() // FIXME-3 move to ME
4634 return linkcolorhint;
4637 QColor VymModel::getMapDefLinkColor() // FIXME-3 move to ME
4639 return defLinkColor;
4642 void VymModel::setMapDefXLinkColor(QColor col) // FIXME-3 move to ME
4647 QColor VymModel::getMapDefXLinkColor() // FIXME-3 move to ME
4649 return defXLinkColor;
4652 void VymModel::setMapDefXLinkWidth (int w) // FIXME-3 move to ME
4657 int VymModel::getMapDefXLinkWidth() // FIXME-3 move to ME
4659 return defXLinkWidth;
4662 void VymModel::move(const double &x, const double &y)
4665 MapItem *seli = (MapItem*)getSelectedItem();
4666 if (seli && (seli->isBranchLikeType() || seli->getType()==TreeItem::Image))
4668 LinkableMapObj *lmo=seli->getLMO();
4671 QPointF ap(lmo->getAbsPos());
4675 QString ps=qpointFToString(ap);
4676 QString s=getSelectString(seli);
4679 s, "move "+qpointFToString(to),
4680 QString("Move %1 to %2").arg(getObjectName(seli)).arg(ps));
4683 emitSelectionChanged();
4689 void VymModel::moveRel (const double &x, const double &y)
4692 MapItem *seli = (MapItem*)getSelectedItem();
4693 if (seli && (seli->isBranchLikeType() || seli->getType()==TreeItem::Image))
4695 LinkableMapObj *lmo=seli->getLMO();
4698 QPointF rp(lmo->getRelPos());
4702 QString ps=qpointFToString (lmo->getRelPos());
4703 QString s=getSelectString(seli);
4706 s, "moveRel "+qpointFToString(to),
4707 QString("Move %1 to relative position %2").arg(getObjectName(seli)).arg(ps));
4708 ((OrnamentedObj*)lmo)->move2RelPos (x,y);
4710 lmo->updateLinkGeometry();
4711 emitSelectionChanged();
4718 void VymModel::animate()
4720 animationTimer->stop();
4723 while (i<animObjList.size() )
4725 bo=(BranchObj*)animObjList.at(i);
4730 animObjList.removeAt(i);
4737 QItemSelection sel=selModel->selection();
4738 emit (selectionChanged(sel,sel));
4741 if (!animObjList.isEmpty()) animationTimer->start();
4745 void VymModel::startAnimation(BranchObj *bo, const QPointF &v)
4749 if (bo->getUseRelPos())
4750 startAnimation (bo,bo->getRelPos(),bo->getRelPos()+v);
4752 startAnimation (bo,bo->getAbsPos(),bo->getAbsPos()+v);
4755 void VymModel::startAnimation(BranchObj *bo, const QPointF &start, const QPointF &dest)
4757 if (start==dest) return;
4758 if (bo && bo->getTreeItem()->depth()>=0)
4761 ap.setStart (start);
4763 ap.setTicks (animationTicks);
4764 ap.setAnimated (true);
4765 bo->setAnimation (ap);
4766 if (!animObjList.contains(bo))
4767 animObjList.append( bo );
4768 animationTimer->setSingleShot (true);
4769 animationTimer->start(animationInterval);
4773 void VymModel::stopAnimation (MapObj *mo)
4775 int i=animObjList.indexOf(mo);
4777 animObjList.removeAt (i);
4780 void VymModel::stopAllAnimation ()
4784 while (i<animObjList.size() )
4786 bo=(BranchObj*)animObjList.at(i);
4787 bo->stopAnimation();
4788 bo->requestReposition();
4794 void VymModel::sendSelection()
4796 if (netstate!=Server) return;
4797 sendData (QString("select (\"%1\")").arg(getSelectString()) );
4800 void VymModel::newServer()
4804 tcpServer = new QTcpServer(this);
4805 if (!tcpServer->listen(QHostAddress::Any,port)) {
4806 QMessageBox::critical(NULL, "vym server",
4807 QString("Unable to start the server: %1.").arg(tcpServer->errorString()));
4808 //FIXME-3 needed? we are no widget any longer... close();
4811 connect(tcpServer, SIGNAL(newConnection()), this, SLOT(newClient()));
4813 cout<<"Server is running on port "<<tcpServer->serverPort()<<endl;
4816 void VymModel::connectToServer()
4819 server="salam.suse.de";
4821 clientSocket = new QTcpSocket (this);
4822 clientSocket->abort();
4823 clientSocket->connectToHost(server ,port);
4824 connect(clientSocket, SIGNAL(readyRead()), this, SLOT(readData()));
4825 connect(clientSocket, SIGNAL(error(QAbstractSocket::SocketError)),
4826 this, SLOT(displayNetworkError(QAbstractSocket::SocketError)));
4828 cout<<"connected to "<<qPrintable (server)<<" port "<<port<<endl;
4833 void VymModel::newClient()
4835 QTcpSocket *newClient = tcpServer->nextPendingConnection();
4836 connect(newClient, SIGNAL(disconnected()),
4837 newClient, SLOT(deleteLater()));
4839 cout <<"ME::newClient at "<<qPrintable( newClient->peerAddress().toString() )<<endl;
4841 clientList.append (newClient);
4845 void VymModel::sendData(const QString &s)
4847 if (clientList.size()==0) return;
4849 // Create bytearray to send
4851 QDataStream out(&block, QIODevice::WriteOnly);
4852 out.setVersion(QDataStream::Qt_4_0);
4854 // Reserve some space for blocksize
4857 // Write sendCounter
4858 out << sendCounter++;
4863 // Go back and write blocksize so far
4864 out.device()->seek(0);
4865 quint16 bs=(quint16)(block.size() - 2*sizeof(quint16));
4869 cout << "ME::sendData bs="<<bs<<" counter="<<sendCounter<<" s="<<qPrintable(s)<<endl;
4871 for (int i=0; i<clientList.size(); ++i)
4873 //cout << "Sending \""<<qPrintable (s)<<"\" to "<<qPrintable (clientList.at(i)->peerAddress().toString())<<endl;
4874 clientList.at(i)->write (block);
4878 void VymModel::readData ()
4880 while (clientSocket->bytesAvailable() >=(int)sizeof(quint16) )
4883 cout <<"readData bytesAvail="<<clientSocket->bytesAvailable();
4887 QDataStream in(clientSocket);
4888 in.setVersion(QDataStream::Qt_4_0);
4896 cout << "VymModel::readData command="<<qPrintable (t)<<endl;
4899 parseAtom (t,noErr,errMsg);
4905 void VymModel::displayNetworkError(QAbstractSocket::SocketError socketError)
4907 switch (socketError) {
4908 case QAbstractSocket::RemoteHostClosedError:
4910 case QAbstractSocket::HostNotFoundError:
4911 QMessageBox::information(NULL, vymName +" Network client",
4912 "The host was not found. Please check the "
4913 "host name and port settings.");
4915 case QAbstractSocket::ConnectionRefusedError:
4916 QMessageBox::information(NULL, vymName + " Network client",
4917 "The connection was refused by the peer. "
4918 "Make sure the fortune server is running, "
4919 "and check that the host name and port "
4920 "settings are correct.");
4923 QMessageBox::information(NULL, vymName + " Network client",
4924 QString("The following error occurred: %1.")
4925 .arg(clientSocket->errorString()));
4929 /* FIXME-3 Playing with DBUS...
4930 QDBusVariant VymModel::query (const QString &query)
4932 TreeItem *selti=getSelectedItem();
4934 return QDBusVariant (selti->getHeading());
4936 return QDBusVariant ("Nothing selected.");
4940 void VymModel::testslot() //FIXME-3 Playing with DBUS
4942 cout << "VM::testslot called\n";
4945 void VymModel::selectMapSelectionColor()
4947 QColor col = QColorDialog::getColor( defLinkColor, NULL);
4948 setSelectionColor (col);
4951 void VymModel::setSelectionColorInt (QColor col)
4953 if ( !col.isValid() ) return;
4955 QString("setSelectionColor (%1)").arg(mapEditor->getSelectionColor().name()),
4956 QString("setSelectionColor (%1)").arg(col.name()),
4957 QString("Set color of selection box to %1").arg(col.name())
4960 mapEditor->setSelectionColor (col);
4963 void VymModel::emitSelectionChanged(const QItemSelection &newsel)
4965 emit (selectionChanged(newsel,newsel)); // needed e.g. to update geometry in editor
4966 //FIXME-3 emitShowSelection();
4970 void VymModel::emitSelectionChanged()
4972 QItemSelection newsel=selModel->selection();
4973 emitSelectionChanged (newsel);
4976 void VymModel::setSelectionColor(QColor col)
4978 if ( !col.isValid() ) return;
4980 QString("setSelectionColor (%1)").arg(mapEditor->getSelectionColor().name()),
4981 QString("setSelectionColor (%1)").arg(col.name()),
4982 QString("Set color of selection box to %1").arg(col.name())
4984 setSelectionColorInt (col);
4987 QColor VymModel::getSelectionColor()
4989 return mapEditor->getSelectionColor();
4992 void VymModel::setHideTmpMode (TreeItem::HideTmpMode mode)
4995 for (int i=0;i<rootItem->branchCount();i++)
4996 rootItem->getBranchNum(i)->setHideTmp (mode);
4998 if (mode==TreeItem::HideExport)
5004 //////////////////////////////////////////////
5005 // Selection related
5006 //////////////////////////////////////////////
5008 void VymModel::setSelectionModel (QItemSelectionModel *sm)
5013 QItemSelectionModel* VymModel::getSelectionModel()
5018 void VymModel::setSelectionBlocked (bool b)
5023 bool VymModel::isSelectionBlocked()
5025 return selectionBlocked;
5028 bool VymModel::select ()
5030 return select (selModel->selectedIndexes().first()); // TODO no multiselections yet
5033 bool VymModel::select (const QString &s)
5040 TreeItem *ti=findBySelectString(s);
5041 if (ti) return select (index(ti));
5045 bool VymModel::select (LinkableMapObj *lmo)
5047 QItemSelection oldsel=selModel->selection();
5050 return select (index (lmo->getTreeItem()) );
5055 bool VymModel::select (TreeItem *ti)
5057 if (ti) return select (index(ti));
5061 bool VymModel::select (TreeItem *ti, int i)
5063 if (!ti || i<0) return false;
5064 if (select (index(ti)))
5066 qDebug ()<<"VM::select with index: "<<i<<" Trying to find text in note ";
5067 QTextCursor c=textEditor->getTextCursor();
5068 c.setPosition (i-1,QTextCursor::MoveAnchor);
5069 textEditor->setTextCursor (c);
5071 qDebug ()<<"VM::select with index: "<<i<<" Giving up to find text in note ";
5075 bool VymModel::select (const QModelIndex &index)
5077 if (index.isValid() )
5079 selModel->select (index,QItemSelectionModel::ClearAndSelect );
5080 BranchItem *bi=getSelectedBranch();
5081 if (bi) bi->setLastSelectedBranch();
5087 void VymModel::unselect()
5089 if (!selModel->selectedIndexes().isEmpty())
5091 lastSelectString=getSelectString();
5092 selModel->clearSelection();
5096 bool VymModel::reselect()
5098 return select (lastSelectString);
5101 void VymModel::emitShowSelection()
5103 if (!blockReposition)
5104 emit (showSelection() );
5107 void VymModel::emitNoteHasChanged (TreeItem *ti)
5109 QModelIndex ix=index(ti);
5110 emit (noteHasChanged (ix) );
5113 void VymModel::emitDataHasChanged (TreeItem *ti)
5115 QModelIndex ix=index(ti);
5116 emit (dataChanged (ix,ix) );
5119 void VymModel::emitUpdateLayout()
5121 if (settings.value("/mainwindow/autoLayout/use","true")=="true")
5122 emit (updateLayout());
5125 bool VymModel::selectFirstBranch()
5127 TreeItem *ti=getSelectedBranch();
5130 TreeItem *par=ti->parent();
5133 TreeItem *ti2=par->getFirstBranch();
5134 if (ti2) return select(ti2);
5140 bool VymModel::selectLastBranch()
5142 TreeItem *ti=getSelectedBranch();
5145 TreeItem *par=ti->parent();
5148 TreeItem *ti2=par->getLastBranch();
5149 if (ti2) return select(ti2);
5155 bool VymModel::selectLastSelectedBranch()
5157 BranchItem *bi=getSelectedBranch();
5160 bi=bi->getLastSelectedBranch();
5161 if (bi) return select (bi);
5166 bool VymModel::selectLastImage()
5168 TreeItem *ti=getSelectedBranch();
5171 TreeItem *par=ti->parent();
5174 TreeItem *ti2=par->getLastImage();
5175 if (ti2) return select(ti2);
5181 bool VymModel::selectParent()
5183 TreeItem *ti=getSelectedItem();
5194 TreeItem::Type VymModel::selectionType()
5196 QModelIndexList list=selModel->selectedIndexes();
5197 if (list.isEmpty()) return TreeItem::Undefined;
5198 TreeItem *ti = getItem (list.first() );
5199 return ti->getType();
5203 LinkableMapObj* VymModel::getSelectedLMO()
5205 QModelIndexList list=selModel->selectedIndexes();
5206 if (!list.isEmpty() )
5208 TreeItem *ti = getItem (list.first() );
5209 TreeItem::Type type=ti->getType();
5210 if (type ==TreeItem::Branch || type==TreeItem::MapCenter || type==TreeItem::Image)
5211 return ((MapItem*)ti)->getLMO();
5216 BranchObj* VymModel::getSelectedBranchObj() // FIXME-3 this should not be needed in the end!!!
5218 TreeItem *ti = getSelectedBranch();
5220 return (BranchObj*)( ((MapItem*)ti)->getLMO());
5225 BranchItem* VymModel::getSelectedBranch()
5227 QModelIndexList list=selModel->selectedIndexes();
5228 if (!list.isEmpty() )
5230 TreeItem *ti = getItem (list.first() );
5231 TreeItem::Type type=ti->getType();
5232 if (type ==TreeItem::Branch || type==TreeItem::MapCenter)
5233 return (BranchItem*)ti;
5238 ImageItem* VymModel::getSelectedImage()
5240 QModelIndexList list=selModel->selectedIndexes();
5241 if (!list.isEmpty())
5243 TreeItem *ti=getItem (list.first());
5244 if (ti && ti->getType()==TreeItem::Image)
5245 return (ImageItem*)ti;
5250 AttributeItem* VymModel::getSelectedAttribute()
5252 QModelIndexList list=selModel->selectedIndexes();
5253 if (!list.isEmpty() )
5255 TreeItem *ti = getItem (list.first() );
5256 TreeItem::Type type=ti->getType();
5257 if (type ==TreeItem::Attribute)
5258 return (AttributeItem*)ti;
5263 TreeItem* VymModel::getSelectedItem()
5265 QModelIndexList list=selModel->selectedIndexes();
5266 if (!list.isEmpty() )
5267 return getItem (list.first() );
5272 QModelIndex VymModel::getSelectedIndex()
5274 QModelIndexList list=selModel->selectedIndexes();
5275 if (list.isEmpty() )
5276 return QModelIndex();
5278 return list.first();
5281 QString VymModel::getSelectString ()
5283 return getSelectString (getSelectedItem());
5286 QString VymModel::getSelectString (LinkableMapObj *lmo) // only for convenience. Used in MapEditor
5288 if (!lmo) return QString();
5289 return getSelectString (lmo->getTreeItem() );
5292 QString VymModel::getSelectString (TreeItem *ti)
5296 switch (ti->getType())
5298 case TreeItem::MapCenter: s="mc:"; break;
5299 case TreeItem::Branch: s="bo:";break;
5300 case TreeItem::Image: s="fi:";break;
5301 case TreeItem::Attribute: s="ai:";break;
5302 case TreeItem::XLink: s="xl:";break;
5304 s="unknown type in VymModel::getSelectString()";
5307 s= s + QString("%1").arg(ti->num());
5309 // call myself recursively
5310 s= getSelectString(ti->parent()) +","+s;
5315 QString VymModel::getSelectString (BranchItem *bi)
5317 return getSelectString ((TreeItem*)bi);