27#include <QApplication>
34#include <QFutureWatcher>
37#include <QMutexLocker>
38#include <QProgressBar>
39#include <QRegularExpression>
45#include <QXmlStreamWriter>
46#include <QXmlStreamReader>
48#include "BundleSettings.h"
49#include "BundleSolutionInfo.h"
52#include "ControlList.h"
53#include "ControlNet.h"
54#include "CorrelationMatrix.h"
57#include "Environment.h"
60#include "GuiCameraList.h"
62#include "ImageReader.h"
63#include "IException.h"
64#include "ProgressBar.h"
65#include "ProjectItem.h"
66#include "ProjectItemModel.h"
67#include "SerialNumberList.h"
72#include "ShapeReader.h"
74#include "TargetBodyList.h"
76#include "TemplateList.h"
78#include "WorkOrderFactory.h"
87 m_bundleSettings = NULL;
93 m_idToImageMap = NULL;
94 m_idToShapeMap = NULL;
95 m_idToTargetBodyMap = NULL;
96 m_idToGuiCameraMap = NULL;
101 m_mapTemplates = NULL;
102 m_regTemplates = NULL;
104 m_workOrderHistory = NULL;
105 m_isTemporaryProject =
true;
108 m_activeControl = NULL;
109 m_activeImageList = NULL;
114 m_workOrderMutex = NULL;
115 m_imageReadingMutex = NULL;
117 m_numShapesCurrentlyReading = 0;
119 m_shapeReadingMutex = NULL;
131 QDir tempDir = QDir::temp();
134 QApplication::applicationName() +
"_*");
135 tempDir.setNameFilters(nameFilters);
137 QStringList existingProjects = tempDir.entryList();
138 bool crashedPreviously =
false;
140 foreach (QString existingProject, existingProjects) {
141 FileName existingProjectFileName(tempDir.absolutePath() +
"/" + existingProject);
142 QString pidString = QString(existingProject).replace(QRegularExpression(
".*_"),
"");
143 int otherPid = pidString.toInt();
146 if ( !QFile::exists(
"/proc/" + pidString) ) {
147 crashedPreviously =
true;
148 int status = system( (
"rm -rf '" +
149 existingProjectFileName.expanded() +
"' &").toLatin1().data() );
151 QString msg =
"Executing command [rm -rf" + existingProjectFileName.expanded() +
152 "' &] failed with return status [" +
toString(status) +
"]";
153 throw IException(IException::Programmer, msg, _FILEINFO_);
159 if (crashedPreviously &&
false) {
160 QMessageBox::information( NULL,
161 QObject::tr(
"Crashed"),
162 QObject::tr(
"It appears %1 crashed. We're sorry.").
163 arg( QApplication::applicationName() ) );
166 QCoreApplication* ipce_app =
static_cast<QCoreApplication *
>(
directory.parent());
169 QString tmpFolder = QDir::temp().absolutePath() +
"/"
171 + QApplication::applicationName() +
"_" + QString::number( getpid() );
172 QDir temp(tmpFolder +
"/tmpProject");
173 m_projectRoot =
new QDir(temp);
175 if (ipce_app->arguments().count() == 1) {
179 catch (IException &e) {
180 throw IException(e, IException::Programmer,
"Error creating project folders.", _FILEINFO_);
182 catch (std::exception &e) {
184 throw IException(IException::Programmer,
185 tr(
"Error creating project folders [%1]").arg( e.what() ), _FILEINFO_);
189 m_mutex =
new QMutex;
190 m_workOrderMutex =
new QMutex;
205 connect(m_directory, SIGNAL(cleanProject(
bool)),
211 m_shapeMutex =
new QMutex;
213 m_shapeReader =
new ShapeReader(m_shapeMutex,
false);
215 connect( m_shapeReader, SIGNAL( shapesReady(
ShapeList) ),
235 m_imageReadingMutex =
new QMutex;
237 m_shapeReadingMutex =
new QMutex;
298 if (m_mapTemplates) {
300 foreach (
Template *templateFile, *templateList) {
307 delete m_mapTemplates;
308 m_mapTemplates = NULL;
312 if (m_regTemplates) {
314 foreach (
Template *templateFile, *templateList) {
321 delete m_regTemplates;
322 m_regTemplates = NULL;
326 m_activeControl = NULL;
327 m_activeImageList = NULL;
329 if (m_bundleSolutionInfo) {
334 delete m_bundleSolutionInfo;
335 m_bundleSolutionInfo = NULL;
341 delete m_idToImageMap;
342 m_idToImageMap = NULL;
344 delete m_idToShapeMap;
345 m_idToShapeMap = NULL;
347 delete m_idToTargetBodyMap;
348 m_idToTargetBodyMap = NULL;
350 delete m_idToGuiCameraMap;
351 m_idToGuiCameraMap = NULL;
353 delete m_idToBundleSolutionInfoMap;
354 m_idToBundleSolutionInfoMap = NULL;
358 delete m_projectRoot;
359 m_projectRoot = NULL;
364 delete m_imageReader;
365 delete m_shapeReader;
370 m_workOrderHistory->removeAll(QPointer<WorkOrder>());
371 delete m_workOrderHistory;
372 m_workOrderHistory = NULL;
374 delete m_bundleSettings;
375 m_bundleSettings = NULL;
384 if ( !dir.mkpath( m_projectRoot->path() ) ) {
385 warn(
"Cannot create project directory.");
386 throw IException(IException::Io,
387 tr(
"Unable to create folder [%1] when trying to initialize project")
388 .arg(m_projectRoot->path() ),
394 QString msg = QString(
"Unable to create folder [%1] when trying to initialize project")
397 throw IException(IException::Io, msg, _FILEINFO_);
401 QString msg = QString(
"Unable to create folder [%1] when trying to initialize project")
404 throw IException(IException::Io, msg, _FILEINFO_);
408 QString msg = QString(
"Unable to create folder [%1] when trying to initialize project")
411 throw IException(IException::Io, msg, _FILEINFO_);
415 QString msg = QString(
"Unable to create folder [%1] when trying to initialize project")
418 throw IException(IException::Io, msg, _FILEINFO_);
421 QString msg = QString(
"Unable to create folder [%1] when trying to initialize project")
424 throw IException(IException::Io, msg, _FILEINFO_);
427 QString msg = QString(
"Unable to create folder [%1] when trying to initialize project")
430 throw IException(IException::Io, msg, _FILEINFO_);
433 QString msg = QString(
"Unable to create folder [%1] when trying to initialize project")
436 throw IException(IException::Io, msg, _FILEINFO_);
438 if ( !dir.mkdir(
templateRoot() +
"/registrations" ) ) {
439 QString msg = QString(
"Unable to create folder [%1] when trying to initialize project")
442 throw IException(IException::Io, msg, _FILEINFO_);
446 warn(
"Failed to create project directory structure");
472 bool bundles =
false;
475 if (projectXml.open(QIODevice::ReadOnly)) {
476 QTextStream projectXmlInput(&projectXml);
478 while (!projectXmlInput.atEnd() ) {
480 QString line = projectXmlInput.readLine();
482 if (
controls || line.contains(
"<controlNets>") ) {
485 if (line.contains(
"</controlNets>") ) {
489 else if (!line.contains(
"<controlNets>") ) {
490 cnetDirList.append(line.split(
'"').at(3));
494 else if (
images || line.contains(
"<imageLists>") ) {
497 if (line.contains(
"</imageLists>")) {
501 else if (!line.contains(
"<imageLists>") ) {
502 imageDirList.append(line.split(
'"').at(3).simplified());
506 else if (shapes || line.contains(
"<shapeLists>")) {
509 if (line.contains(
"</shapeLists>") ) {
513 else if (!line.contains(
"<shapeLists>") ) {
514 shapeDirList.append(line.split(
'"').at(3));
518 else if (
mapTemplates || line.contains(
"<mapTemplateLists>") ) {
521 if (line.contains(
"</mapTemplateLists>") ) {
525 else if (!line.contains(
"<mapTemplateLists>") ) {
527 mapTemplateDirList.append(components.at(5));
531 else if (
regTemplates || line.contains(
"<regTemplateLists>") ) {
534 if (line.contains(
"</regTemplateLists>") ) {
538 else if (!line.contains(
"<regTemplateLists>") ) {
540 regTemplateDirList.append(components.at(5));
544 else if (bundles || line.contains(
"<bundleSolutionInfo>") ) {
547 if (line.contains(
"</bundleSolutionInfo>") ) {
551 else if (line.contains(
"<runTime>") ) {
552 bundleDirList.append(line.split(
'>').at(1).split(
'<').at(0));
557 QDir cnetsDir(m_projectRoot->path() +
"/cnets/");
558 cnetsDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
560 foreach (QString dir, cnetsList) {
561 dir = dir.simplified();
563 if ( !cnetDirList.contains(dir) ) {
564 QDir tempDir(cnetsDir.path() +
"/" + dir);
565 tempDir.removeRecursively();
569 QDir imagesDir(m_projectRoot->path() +
"/images/");
570 imagesDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
572 foreach (QString dir, imagesList) {
573 dir = dir.simplified();
575 if ( !imageDirList.contains(dir) ) {
576 QDir tempDir(imagesDir.path() +
"/" + dir);
577 tempDir.removeRecursively();
581 QDir shapesDir(m_projectRoot->path() +
"/shapes/");
582 shapesDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
584 foreach (QString dir, shapesList) {
585 dir = dir.simplified();
587 if ( !shapeDirList.contains(dir) ) {
588 QDir tempDir(shapesDir.path() +
"/" + dir);
589 tempDir.removeRecursively();
593 QDir mapTemplatesDir(m_projectRoot->path() +
"/templates/maps");
594 mapTemplatesDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
595 QStringList mapTemplatesList = mapTemplatesDir.entryList();
596 foreach (QString dir, mapTemplatesList) {
597 dir = dir.simplified();
599 if ( !mapTemplateDirList.contains(
"maps/" + dir) ) {
600 QDir tempDir(mapTemplatesDir.path() +
"/" + dir);
601 tempDir.removeRecursively();
605 QDir regTemplatesDir(m_projectRoot->path() +
"/templates/registrations");
606 regTemplatesDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
607 QStringList regTemplatesList = regTemplatesDir.entryList();
608 foreach (QString dir, regTemplatesList) {
609 dir = dir.simplified();
611 if ( !regTemplateDirList.contains(
"registrations/" + dir)) {
612 QDir tempDir(regTemplatesDir.path() +
"/" + dir);
613 tempDir.removeRecursively();
617 QDir bundlesDir(m_projectRoot->path() +
"/results/bundle/");
618 bundlesDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
620 foreach (QString dir, bundleList) {
621 dir = dir.simplified();
623 if ( !bundleDirList.contains(dir) ) {
624 QDir tempDir(bundlesDir.path() +
"/" + dir);
625 tempDir.removeRecursively();
633 QString tmpFolder = QDir::temp().absolutePath() +
"/"
635 + QApplication::applicationName() +
"_" + QString::number( getpid() );
636 QDir temp(tmpFolder +
"/tmpProject");
637 m_projectRoot =
new QDir(temp);
640 catch (IException &e) {
641 throw IException(e, IException::Programmer,
"Error creating project folders.", _FILEINFO_);
644 catch (std::exception &e) {
645 throw IException(IException::Programmer,
646 tr(
"Error creating project folders [%1]").arg( e.what() ), _FILEINFO_);
652 m_mapTemplates->clear();
653 m_regTemplates->clear();
655 m_guiCameras->clear();
656 m_bundleSolutionInfo->clear();
657 m_workOrderHistory->clear();
664 bool Project::clearing() {
669 ImageList *Project::createOrRetrieveImageList(QString name, QString path) {
682 connect( result, SIGNAL( destroyed(QObject *) ),
684 m_images->append(result);
690 ShapeList *Project::createOrRetrieveShapeList(QString name, QString path) {
693 result =
new ShapeList;
703 connect( result, SIGNAL( destroyed(QObject *) ),
705 m_shapes->append(result);
725 stream.writeStartElement(
"project");
727 stream.writeAttribute(
"name", m_name);
729 if ( !m_controls->isEmpty() ) {
730 stream.writeStartElement(
"controlNets");
732 for (
int i = 0; i < m_controls->count(); i++) {
736 stream.writeEndElement();
739 if ( !m_images->isEmpty() ) {
740 stream.writeStartElement(
"imageLists");
741 for (
int i = 0; i < m_images->count(); i++) {
745 stream.writeEndElement();
748 if ( !m_shapes->isEmpty() ) {
749 stream.writeStartElement(
"shapeLists");
751 for (
int i = 0; i < m_shapes->count(); i++) {
755 stream.writeEndElement();
758 if ( !m_mapTemplates->isEmpty() ) {
759 stream.writeStartElement(
"mapTemplateLists");
761 for (
int i = 0; i < m_mapTemplates->count(); i++) {
765 stream.writeEndElement();
768 if ( !m_regTemplates->isEmpty() ) {
769 stream.writeStartElement(
"regTemplateLists");
771 for (
int i = 0; i < m_regTemplates->count(); i++) {
775 stream.writeEndElement();
808 if ( !m_bundleSolutionInfo->isEmpty() ) {
809 stream.writeStartElement(
"results");
811 for (
int i = 0; i < m_bundleSolutionInfo->count(); i++) {
815 stream.writeEndElement();
818 if (m_activeImageList) {
819 stream.writeStartElement(
"activeImageList");
820 stream.writeAttribute(
"displayName", m_activeImageList->name());
821 stream.writeEndElement();
824 if (m_activeControl) {
825 stream.writeStartElement(
"activeControl");
826 stream.writeAttribute(
"displayName", m_activeControl->displayProperties()->displayName());
827 stream.writeEndElement();
830 stream.writeEndElement();
850 stream.writeStartElement(
"history");
852 foreach (
WorkOrder *workOrder, *m_workOrderHistory) {
854 workOrder->
save(stream);
858 stream.writeEndElement();
873 stream.writeStartElement(
"warnings");
875 foreach (QString warning, *m_warnings) {
876 stream.writeStartElement(
"warning");
877 stream.writeAttribute(
"text", warning);
878 stream.writeEndElement();
881 stream.writeEndElement();
896 foreach (QString fileName, fileNames) {
899 result.append(fileName);
901 catch (IException &) {
927 int prefixCounter = 0;
929 QString numberedPrefix;
932 numberedPrefix = prefix.arg( QString::number(prefixCounter) );
934 while ( cnetFolder.exists(numberedPrefix) );
936 if ( !cnetFolder.mkpath(numberedPrefix) ) {
937 throw IException(IException::Io,
938 tr(
"Could not create control network directory [%1] in [%2].")
939 .arg(numberedPrefix).arg( cnetFolder.absolutePath() ),
943 cnetFolder.cd(numberedPrefix);
945 m_currentCnetFolder = cnetFolder;
963 createOrRetrieveControlList( FileName(
control->fileName() ).dir().dirName(),
"" )->append(
control);
971 ControlList *Project::createOrRetrieveControlList(QString name, QString path) {
985 connect( result, SIGNAL( destroyed(QObject *) ),
988 m_controls->append(result);
1004 int prefixCounter = 0;
1006 QString numberedPrefix;
1009 numberedPrefix = prefix.arg( QString::number(prefixCounter) );
1011 while ( imageFolder.exists(numberedPrefix) );
1013 if ( !imageFolder.mkpath(numberedPrefix) ) {
1014 throw IException(IException::Io,
1015 tr(
"Could not create image directory [%1] in [%2].")
1016 .arg(numberedPrefix).arg( imageFolder.absolutePath() ),
1020 imageFolder.cd(numberedPrefix);
1032 m_imageReadingMutex->lock();
1036 m_imageReader->read(imageFiles);
1061 int prefixCounter = 0;
1063 QString numberedPrefix;
1066 numberedPrefix = prefix.arg( QString::number(prefixCounter) );
1068 while ( shapeFolder.exists(numberedPrefix) );
1070 if ( !shapeFolder.mkpath(numberedPrefix) ) {
1071 throw IException(IException::Io,
1072 tr(
"Could not create shape directory [%1] in [%2].")
1073 .arg(numberedPrefix).arg( shapeFolder.absolutePath() ),
1077 shapeFolder.cd(numberedPrefix);
1088 if (m_numShapesCurrentlyReading == 0) {
1089 m_shapeReadingMutex->lock();
1092 m_numShapesCurrentlyReading += shapeFiles.count();
1093 m_shapeReader->read(shapeFiles);
1102 shapesReady(newShapes);
1112 foreach (
Template *templateFile, *templateList) {
1114 templateFile, SLOT( updateFileName(
Project *) ) );
1116 if (templateList->
type() ==
"maps") {
1117 m_mapTemplates->append(templateList);
1119 else if (templateList->
type() ==
"registrations") {
1120 m_regTemplates->append(templateList);
1123 emit templatesAdded(templateList);
1135 int prefixCounter = 0;
1136 QString numberedPrefix;
1140 numberedPrefix = prefix.arg( QString::number(prefixCounter) );
1142 while ( templateFolder.exists(numberedPrefix) );
1144 if ( !templateFolder.mkpath(numberedPrefix) ) {
1145 throw IException(IException::Io,
1146 tr(
"Could not create template directory [%1] in [%2].")
1147 .arg(numberedPrefix).arg( templateFolder.absolutePath() ),
1151 templateFolder.cd(numberedPrefix);
1153 return templateFolder;
1175 if (!bundleSolutionInfoFolder.mkpath(folder)) {
1176 throw IException(IException::Io,
1177 tr(
"Could not create bundle results directory [%1] in [%2].")
1178 .arg(folder).arg(bundleSolutionInfoFolder.absolutePath()),
1182 bundleSolutionInfoFolder.cd(folder);
1183 return bundleSolutionInfoFolder;
1232 void Project::writeSettings() {
1234 QString appName = QApplication::applicationName();
1237 QSettings globalSettings(
1238 FileName(
"$HOME/.Isis/" + appName +
"/" + appName +
"_" +
"Project.config")
1240 QSettings::NativeFormat);
1242 globalSettings.beginGroup(
"recent_projects");
1246 foreach (QString key,keys) {
1248 recentProjects[key]=globalSettings.value(key).toString();
1254 if (keys.count() >= m_maxRecentProjects) {
1257 globalSettings.remove(
"");
1263 if (!this->
projectRoot().contains(
"tmpProject") && !projectPaths.contains(this->projectRoot()) ) {
1264 QString s=keys.first();
1265 recentProjects.remove( s );
1271 if (projectPaths.contains(this->projectRoot())) {
1272 QString key = recentProjects.key(this->
projectRoot());
1273 recentProjects.remove(key);
1276 QMap<QString,QString>::iterator i;
1279 for (i=recentProjects.begin();i!=recentProjects.end();i++) {
1281 globalSettings.setValue(i.key(),i.value());
1286 long t0 = QDateTime::currentMSecsSinceEpoch();
1287 QString projName = this->
name();
1289 QString t0String=QString::number(t0);
1292 if (!this->
projectRoot().contains(
"tmpProject") ) {
1293 globalSettings.setValue(t0String+
"%%%%%"+projName,this->
projectRoot());
1303 globalSettings.remove(
"");
1304 if (projectPaths.contains(this->projectRoot())) {
1305 QString key = recentProjects.key(this->
projectRoot());
1306 recentProjects.remove(key);
1308 QMap<QString,QString>::iterator i;
1311 for ( i=recentProjects.begin(); i!=recentProjects.end(); i++ ) {
1312 globalSettings.setValue(i.key(),i.value());
1315 long t0 = QDateTime::currentMSecsSinceEpoch();
1316 QString projName = this->
name();
1317 QString t0String=QString::number(t0);
1320 if (!this->
projectRoot().contains(
"tmpProject") ) {
1321 globalSettings.setValue(t0String+
"%%%%%"+projName,this->
projectRoot());
1327 globalSettings.endGroup();
1345 QString projectAbsolutePathStr = QDir(projectPathStr).absolutePath();
1347 QString projectXmlPath = projectAbsolutePathStr +
"/project.xml";
1348 QFile file(projectXmlPath);
1350 if ( !file.open(QFile::ReadOnly) ) {
1351 throw IException(IException::Io,
1352 QString(
"Unable to open [%1] with read access")
1353 .arg(projectXmlPath),
1357 QString projectXmlHistoryPath = projectAbsolutePathStr +
"/history.xml";
1358 QFile historyFile(projectXmlHistoryPath);
1360 if ( !historyFile.open(QFile::ReadOnly) ) {
1361 throw IException(IException::Io,
1362 QString(
"Unable to open [%1] with read access")
1363 .arg(projectXmlHistoryPath),
1367 QString projectXmlWarningsPath = projectAbsolutePathStr +
"/warnings.xml";
1368 QFile warningsFile(projectXmlWarningsPath);
1370 if (!warningsFile.open(QFile::ReadOnly)) {
1371 throw IException(IException::Io,
1372 QString(
"Unable to open [%1] with read access")
1373 .arg(projectXmlWarningsPath),
1377 QString directoryXmlPath = projectAbsolutePathStr +
"/directory.xml";
1378 QFile directoryFile(directoryXmlPath);
1380 if (!directoryFile.open(QFile::ReadOnly)) {
1381 throw IException(IException::Io,
1382 QString(
"Unable to open [%1] with read access")
1383 .arg(directoryXmlPath),
1391 m_isTemporaryProject =
false;
1393 QDir oldProjectRoot(*m_projectRoot);
1394 *m_projectRoot = QDir(projectAbsolutePathStr);
1396 QXmlStreamReader projectXmlReader(&file);
1402 readProjectXml(&projectXmlReader);
1404 catch (IException &e) {
1406 .arg(projectAbsolutePathStr));
1409 catch (std::exception &e) {
1411 .arg(projectAbsolutePathStr));
1415 QXmlStreamReader reader2(&historyFile);
1418 while (!reader2.atEnd()) {
1423 catch (IException &e) {
1425 .arg(projectAbsolutePathStr));
1428 catch (std::exception &e) {
1430 .arg(projectAbsolutePathStr));
1434 QXmlStreamReader reader3(&warningsFile);
1436 while (!reader3.atEnd()) {
1439 if (reader3.hasError()) {
1440 warn(tr(
"Failed to read warnings from project [%1]").arg(projectAbsolutePathStr));
1443 QXmlStreamReader reader4(&directoryFile);
1446 while (!reader4.atEnd()) {
1450 catch (IException &e) {
1452 .arg(projectAbsolutePathStr));
1456 catch (std::exception &e) {
1458 .arg(projectAbsolutePathStr));
1463 if (bundleRoot.exists()) {
1465 bundleRoot.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
1467 QFileInfoList bundleDirs = bundleRoot.entryInfoList();
1469 for (
int dirListIndex = 0; dirListIndex < bundleDirs.size(); dirListIndex++) {
1472 QDir bundleSolutionDir(bundleDirs[dirListIndex].absoluteFilePath());
1473 bundleSolutionDir.setFilter(QDir::Files | QDir::NoSymLinks);
1493 void Project::readProjectXml(QXmlStreamReader *xmlReader) {
1494 if (xmlReader->readNextStartElement()) {
1495 if (xmlReader->name() ==
"project") {
1496 QStringView
name = xmlReader->attributes().value(
"name");
1497 if (!
name.isEmpty()) {
1501 else if (xmlReader->name() ==
"controlNets") {
1504 else if (xmlReader->name() ==
"imageList") {
1507 else if (xmlReader->name() ==
"shapeList") {
1510 else if (xmlReader->name() ==
"mapTemplateList") {
1513 else if (xmlReader->name() ==
"regTemplateList") {
1517 else if (xmlReader->name() ==
"workOrder") {
1518 QString type = xmlReader->attributes().value(
"type").toString();
1525 else if (xmlReader->name() ==
"warning") {
1526 QString warningText = xmlReader->attributes().value(
"text").toString();
1528 if (!warningText.isEmpty())
1530 m_project->warn(warningText);
1533 else if (xmlReader->name() ==
"directory") {
1536 else if (xmlReader->name() ==
"dockRestore") {
1542 else if (xmlReader->name() ==
"bundleSolutionInfo") {
1543 m_bundleSolutionInfos.append(
new BundleSolutionInfo(m_project, xmlReader));
1545 else if (xmlReader->name() ==
"activeImageList") {
1546 QString displayName = xmlReader->attributes().value(
"displayName").toString();
1547 m_project->setActiveImageList(displayName);
1549 else if (xmlReader->name() ==
"activeControl") {
1551 QString displayName = xmlReader->attributes().value(
"displayName").toString();
1552 m_project->setActiveControl(displayName);
1556 xmlReader->raiseError(QObject::tr(
"Incorrect file"));
1561 QProgressBar *Project::progress() {
1562 return m_imageReader->progress();
1573 return (*m_idToImageMap)[id];
1583 QListIterator<ImageList *> it(*m_images);
1586 while (it.hasNext() && !result) {
1589 if (list->
name() ==
name) result = list;
1602 return (*m_idToShapeMap)[id];
1612 QListIterator<ShapeList *> it(*m_shapes);
1615 while (it.hasNext() && !result) {
1618 if (list->
name() ==
name) result = list;
1630 return m_isTemporaryProject;
1659 m_undoStack.cleanChanged(value);
1669 QListIterator< QPointer<WorkOrder> > it(*m_workOrderHistory);
1672 while ( !result && it.hasPrevious() ) {
1698 QListIterator< QPointer<WorkOrder> > it(*m_workOrderHistory);
1701 while ( !result && it.hasPrevious() ) {
1729 return m_projectRoot->path();
1738 return m_newProjectRoot;
1757 return &m_undoStack;
1761 QString Project::nextImageListGroupName() {
1762 int numLists = m_images->size();
1763 QString maxName =
"";
1764 QString newGroupName =
"Group";
1768 if ( !
name.contains(
"Group") )
continue;
1769 if ( maxName.isEmpty() ) {
1772 else if (
name > maxName) {
1777 if ( maxName.isEmpty() ) {
1778 newGroupName += QString::number(numLists+1);
1781 int maxNum = maxName.remove(
"Group").toInt();
1784 newGroupName += QString::number(maxNum);
1786 return newGroupName;
1795 QMutexLocker locker(m_imageReadingMutex);
1803 QMutexLocker locker(m_shapeReadingMutex);
1812 foreach (
WorkOrder *workOrder, *m_workOrderHistory) {
1813 result.append(workOrder);
1830 if (m_activeControl && m_activeImageList) {
1882 Control *previousControl = m_activeControl;
1883 if (m_activeControl) {
1887 if (m_activeControl->isModified()) {
1889 msgBox.setText(
"Save current active control");
1890 msgBox.setInformativeText(
"The current active control has been modified. Do you want "
1891 "to save before setting a new active control?");
1892 msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
1893 msgBox.setDefaultButton(QMessageBox::Save);
1894 int ret = msgBox.exec();
1897 case QMessageBox::Save:
1898 m_activeControl->write();
1901 case QMessageBox::Discard:
1903 m_activeControl->closeControlNet();
1904 m_activeControl->openControlNet();
1905 emit discardActiveControlEdits();
1908 case QMessageBox::Cancel:
1914 displayProperties()->displayName(), Qt::DisplayRole);
1915 item->setTextColor(Qt::black);
1917 if (!
directory()->controlUsedInCnetEditorWidget(m_activeControl)) {
1918 m_activeControl->closeControlNet();
1924 m_activeControl = item->
control();
1927 m_activeControl->controlNet()->SetImages(*(
activeImageList()->serialNumberList()));
1928 item->setTextColor(Qt::darkGreen);
1930 catch(IException &e){
1931 if (previousControl) {
1932 m_activeControl = previousControl;
1934 displayProperties()->displayName(), Qt::DisplayRole);
1935 item->setTextColor(Qt::darkGreen);
1936 m_activeControl->controlNet()->SetImages(*(
activeImageList()->serialNumberList()));
1939 m_activeControl = NULL;
1941 throw IException(e);
1967 if (!m_activeControl && (m_controls->count() == 1 && m_controls->at(0)->count() ==1)) {
1970 QString controlName = m_controls->at(0)->at(0)->displayProperties()->displayName();
1975 return m_activeControl;
1987 if (m_activeControl && m_activeControl->isModified()) {
2018 ImageList *previousImageList = m_activeImageList;
2019 if (m_activeImageList) {
2021 name(), Qt::DisplayRole);
2022 item->setTextColor(Qt::black);
2028 if (m_activeControl) {
2032 catch(IException &e){
2033 if (previousImageList) {
2034 m_activeImageList = previousImageList;
2036 name(), Qt::DisplayRole);
2037 item->setTextColor(Qt::darkGreen);
2041 m_activeImageList = NULL;
2043 throw IException(e);
2046 item->setTextColor(Qt::darkGreen);
2067 if (!m_activeImageList && m_images->count() == 1) {
2068 QString
imageList = m_images->at(0)->name();
2072 return m_activeImageList;
2092 return cnetRoot( m_projectRoot->path() );
2111 QListIterator< ControlList * > it(*m_controls);
2114 while (it.hasNext() && !result) {
2117 if (list->
name() ==
name) result = list;
2209 return allTemplates;
2219 return *m_mapTemplates;
2229 return *m_regTemplates;
2286 return *m_bundleSolutionInfo;
2320 foreach (
ImageList *imagesInAFolder, *m_images) {
2325 warn( tr(
"Did not properly clean up images folder [%1] in project").arg(
imageDataRoot() ) );
2328 foreach (
ShapeList *shapesInAFolder, *m_shapes) {
2333 warn( tr(
"Did not properly clean up shapes folder [%1] in project").
2337 foreach (
ControlList *controlsInAFolder, *m_controls) {
2341 if ( !m_projectRoot->rmdir(
cnetRoot() ) ) {
2342 warn( tr(
"Did not properly clean up control network folder [%1] in project")
2346 if ( !(QDir(
resultsRoot()).removeRecursively()) ) {
2347 warn( tr(
"Did not properly clean up results folder [%1] in project")
2352 warn( tr(
"Did not properly clean up templates folder [%1] in project")
2356 if ( !m_projectRoot->rmpath( m_projectRoot->path() ) ) {
2357 warn( tr(
"Did not properly clean up project in [%1]").arg( m_projectRoot->path() ) );
2388 bool saveDialogCompleted =
true;
2390 if (m_isTemporaryProject) {
2391 QString newDestination = QFileDialog::getSaveFileName(NULL,
2392 QString(
"Project Location"),
2395 if ( !newDestination.isEmpty() ) {
2396 m_isTemporaryProject =
false;
2397 save( QFileInfo(newDestination +
"/").absolutePath() );
2407 open(newDestination);
2411 saveDialogCompleted =
false;
2425 save(m_projectRoot->absolutePath(),
false);
2429 return saveDialogCompleted;
2535 if ( verifyPathDoesntExist && QFile::exists( newPath.toString() ) ) {
2536 throw IException(IException::Io,
2537 QString(
"Projects may not be saved to an existing path [%1]; "
2538 "please select a new path or delete the current folder")
2539 .arg(newPath.original()),
2544 if (!dir.mkpath(newPath.toString())) {
2545 throw IException(IException::Io,
2546 QString(
"Unable to save project at [%1] "
2547 "because we could not create the folder")
2548 .arg(newPath.original()),
2556 m_newProjectRoot = newPath.toString();
2561 m_name = newPath.name();
2563 QFile projectSettingsFile(newPath.toString() +
"/project.xml");
2564 if (!projectSettingsFile.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
2565 throw IException(IException::Io,
2566 QString(
"Unable to save project at [%1] because the file [%2] "
2567 "could not be opened for writing")
2568 .arg(newPath.original()).arg(projectSettingsFile.fileName()),
2572 QXmlStreamWriter writer(&projectSettingsFile);
2573 writer.setAutoFormatting(
true);
2575 writer.writeStartDocument();
2578 save(writer, newPath);
2580 writer.writeEndDocument();
2582 QFile projectHistoryFile(newPath.toString() +
"/history.xml");
2583 if (!projectHistoryFile.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
2584 throw IException(IException::Io,
2585 QString(
"Unable to save project at [%1] because the file [%2] "
2586 "could not be opened for writing")
2587 .arg(newPath.original()).arg(projectHistoryFile.fileName()),
2591 QXmlStreamWriter historyWriter(&projectHistoryFile);
2592 historyWriter.setAutoFormatting(
true);
2594 historyWriter.writeStartDocument();
2596 historyWriter.writeEndDocument();
2598 QFile projectWarningsFile(newPath.toString() +
"/warnings.xml");
2599 if (!projectWarningsFile.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
2600 throw IException(IException::Io,
2601 QString(
"Unable to save project at [%1] because the file [%2] could not be "
2602 "opened for writing")
2603 .arg(newPath.original()).arg(projectWarningsFile.fileName()),
2607 QXmlStreamWriter warningsWriter(&projectWarningsFile);
2608 warningsWriter.setAutoFormatting(
true);
2610 warningsWriter.writeStartDocument();
2612 warningsWriter.writeEndDocument();
2615 QFile directoryStateFile(newPath.toString() +
"/directory.xml");
2616 if (!directoryStateFile.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
2617 throw IException(IException::Io,
2618 QString(
"Unable to save project at [%1] because the file [%2] could not be "
2619 "opened for writing")
2620 .arg(newPath.original()).arg(directoryStateFile.fileName()),
2624 QXmlStreamWriter directoryStateWriter(&directoryStateFile);
2625 directoryStateWriter.setAutoFormatting(
true);
2627 directoryStateWriter.writeStartDocument();
2634 m_directory->save(directoryStateWriter, newPath);
2636 directoryStateWriter.writeEndDocument();
2662 connect(workOrder, SIGNAL(finished(
WorkOrder *)),
2670 m_workOrderHistory->append(workOrder);
2679 m_undoStack.setClean();
2686 m_undoStack.push(workOrder);
2695 m_workOrderHistory->removeAll(QPointer<WorkOrder>());
2705 template<
typename Data>
void Project::warn(QString text, Data relevantData) {
2706 storeWarning(text, relevantData);
2711 void Project::warn(QString text) {
2712 foreach (QString line, text.split(
"\n")) {
2719 void Project::storeWarning(QString text) {
2720 m_warnings->append(text);
2739 if (
images.name() !=
"") {
2743 createOrRetrieveImageList(FileName(
images[0]->fileName()).dir().dirName(),
"")->append(
image);
2751 QMutexLocker lock(m_mutex);
2755 foreach (openImage,
images) {
2766 m_imageReadingMutex->unlock();
2779 if (QString::compare(targetBody->targetName(),
id, Qt::CaseInsensitive) == 0) {
2796 m_targets->append(targetBody);
2810 if (QString::compare(camera->instrumentId(),
id, Qt::CaseInsensitive) == 0) {
2827 m_guiCameras->append(guiCamera);
2848 void Project::removeImages(
ImageList &imageList) {
2854 m_images->removeOne(list);
2865 QMutableListIterator<ImageList *> it(*m_images);
2866 while (it.hasNext()) {
2869 int foundElement = list->indexOf((
Image *)imageObj);
2871 if (foundElement != -1) {
2876 m_idToImageMap->remove(m_idToImageMap->key((
Image *)imageObj));
2885 int indexToRemove = m_images->indexOf(
static_cast<ImageList *
>(imageListObj));
2886 if (indexToRemove != -1) {
2887 m_images->removeAt(indexToRemove);
2904 int indexToRemove = m_controls->indexOf(
static_cast<ControlList *
>(controlListObj));
2905 if (indexToRemove != -1) {
2906 m_controls->removeAt(indexToRemove);
2919 int indexToRemove = m_shapes->indexOf(
static_cast<ShapeList *
>(shapeListObj));
2920 if (indexToRemove != -1) {
2921 m_shapes->removeAt(indexToRemove);
2930 QMutableListIterator<BundleSolutionInfo *> it(*m_bundleSolutionInfo);
2931 while (it.hasNext()) {
2937 int foundElement = m_bundleSolutionInfo->indexOf(
2940 if (foundElement != -1) {
2941 m_bundleSolutionInfo->removeAt(foundElement);
2945 m_idToBundleSolutionInfoMap->remove(
2975 void Project::shapesReady(
ShapeList shapes) {
2977 m_numShapesCurrentlyReading -=
shapes.count();
2986 if (
shapes.name() !=
"") {
2990 createOrRetrieveShapeList(FileName(
shapes[0]->fileName()).dir().dirName(),
"")->
append(
shape);
2999 QMutexLocker lock(m_shapeMutex);
3003 foreach (openShape, shapes) {
3007 if (m_numShapesCurrentlyReading == 0) {
3008 m_shapeReadingMutex->unlock();
3017 QMutableListIterator<ShapeList *> it(*m_shapes);
3018 while (it.hasNext()) {
3021 int foundElement = list->indexOf((
Shape *)imageObj);
3023 if (foundElement != -1) {
3028 m_idToShapeMap->remove(m_idToShapeMap->key((
Shape *)imageObj));
3042 return m_workOrderMutex;
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
Container class for BundleAdjustment results.
This represents an ISIS control net in a project-based GUI interface.
ControlNet * controlNet()
Open and return a pointer to the ControlNet for this Control.
Maintains a list of Controls so that control nets can easily be copied from one Project to another,...
void deleteFromDisk(Project *project)
Delete all of the contained Controls from disk.
QString name() const
Get the human-readable name of this control list.
void setName(QString newName)
Set the human-readable name of this control list.
void setPath(QString newPath)
Set the relative path (from the project root) to this control list's folder.
void SetImages(const QString &imageListFile)
Creates the ControlNet's image cameras based on an input file.
IO Handler for Isis Cubes.
void clean()
Cleans directory of everything to do with the current project.
void showWarning(QString text)
Displays a Warning.
ProjectItemModel * model()
Gets the ProjectItemModel for this directory.
static QString userName()
@Returns the user name.
Container class for GuiCamera.
List of GuiCameras saved as QSharedPointers.
@ FootprintViewProperties
Every display property for footprint views, provided for convenience.
This represents a cube in a project-based GUI interface.
void closeCube()
Cleans up the Cube pointer.
Internalizes a list of images and allows for operations on the entire list.
void deleteFromDisk(Project *project)
Delete all of the contained Images from disk.
void setPath(QString newPath)
Set the relative path (from the project root) to this image list's folder.
void removeAt(int i)
Removes the image at an index.
void setName(QString newName)
Set the human-readable name of this image list.
QString name() const
Get the human-readable name of this image list.
The main project for ipce.
void activeControlSet(bool boolean)
Emitted when an active control is set.
void setActiveImageList(QString displayName)
Set the Active ImageList from the displayName which is saved in project.xml.
void imageListDeleted(QObject *imageList)
An image list is being deleted from the project.
void addBundleSolutionInfo(BundleSolutionInfo *bundleSolutionInfo)
Add the given BundleSolutionInfo to the current project.
void checkActiveControlAndImageList()
Checks if both an active control and active image list have been set.
static QString cnetRoot(QString projectRoot)
Appends the root directory name 'cnets' to the project.
void activeImageListSet()
Emitted when an active image list is set.
Shape * shape(QString id)
Return a shape given its id.
QString targetBodyRoot() const
Accessor for the root directory of the target body data.
static QString templateRoot(QString projectRoot)
Appends the root directory name 'templates' to the project .
QMutex * mutex()
Return mutex used for Naif calls.
ImageList * imageList(QString name)
Return an imagelist given its name.
void workOrderStarting(WorkOrder *)
Emitted when work order starts.
QList< TemplateList * > templates()
Return all template FileNames.
bool isTemporaryProject() const
Returns if the project is a temp project or not.
void bundleSolutionInfoAdded(BundleSolutionInfo *bundleSolutionInfo)
Emitted when new BundleSolutionInfo available from jigsaw receivers: ProjectTreeWidget (TODO: should ...
void imagesReady(ImageList)
Prepare new images for opening.
void targetBodyClosed(QObject *targetBodyObj)
A target body is being deleted from the project.
void setName(QString newName)
Change the project's name (GUI only, doesn't affect location on disk).
void imageClosed(QObject *image)
An image is being deleted from the project.
void imagesAdded(ImageList *images)
Emitted when new images are available.
void projectSaved(Project *)
Emitted when project is saved.
QDir addCnetFolder(QString prefix)
Create and return the name of a folder for placing control networks.
void controlListAdded(ControlList *controls)
apparently not used?
void addControl(Control *control)
Add the given Control's to the current project.
WorkOrder * lastNotUndoneWorkOrder()
Return the last not undone workorder.
QDir addTemplateFolder(QString prefix)
Create and navigate to the appropriate template type folder in the project directory.
void allControlsRemoved()
Emitted when all controls have been removed from the Project.
QString bundleSolutionInfoRoot() const
Accessor for the root directory of the results data.
void projectRelocated(Project *)
Emitted when project location moved receivers: Control, BundleSolutionInfo, Image,...
void shapeListDeleted(QObject *shapeList)
A shape model list is being deleted from the project.
static QString bundleSolutionInfoRoot(QString projectRoot)
Appends the root directory name 'bundle' to the project results directory.
void deleteAllProjectFiles()
Delete all of the files, that this project stores, from disk.
QString newProjectRoot() const
Get the top-level folder of the new project.
void setActiveControl(QString displayName)
Set the Active Control (control network)
QDir addBundleSolutionInfoFolder(QString folder)
Create and return the name of a folder for placing BundleSolutionInfo.
void controlClosed(QObject *control)
A control is being deleted from the project.
QList< TemplateList * > regTemplates()
Return registration template FileNames.
void projectLoaded(Project *)
Emitted when project loaded receivers: IpceMainWindow, Directory, HistoryTreeWidget.
QString templateRoot() const
Accessor for the root directory of the template data.
QUndoStack * undoStack()
Returns the Projects stack of QUndoCommands.
void workOrderFinished(WorkOrder *)
Emitted when work order ends.
bool hasCamera(QString id)
This method checks for the existence of a camera based on InstrumentId.
QList< WorkOrder * > workOrderHistory()
Get the entire list of work orders that have executed.
QString resultsRoot() const
Accessor for the root directory of the results data.
static QString shapeDataRoot(QString projectRoot)
Appends the root directory name 'shapes' to the project .
void addImagesToIdMap(ImageList images)
Add images to the id map which are not under the projects main data area, the Images node on the proj...
bool m_isClean
used to determine whether a project is currently open
void waitForShapeReaderFinished()
Locks program if another spot in code is still running and called this function.
TargetBodyList targetBodies()
Return TargetBodyList in Project.
void waitForImageReaderFinished()
Locks program if another spot in code is still running and called this function.
ShapeList * shapeList(QString name)
Return a shapelist given its name.
bool hasTarget(QString id)
This method checks for the existence of a target based on TargetName.
void controlAdded(Control *control)
Emitted when new Control added to Project receivers: ProjectTreeWidget.
void shapeClosed(QObject *shape)
A shape model is being deleted from the project.
QList< ShapeList * > shapes()
Return the projects shapelist.
QMutex * workOrderMutex()
This function returns a QMutex.
~Project()
Clean up the project.
QList< QAction * > userPreferenceActions()
Get a list of configuration/settings actions related to reading images into this Project.
void saveHistory(QXmlStreamWriter &stream) const
Serialize the work orders into the given XML.
void clear()
Function to clear out all values in a project essentially making it a new project object.
void addToProject(WorkOrder *)
This executes the WorkOrder and stores it in the project.
void activeControlAndImageListSet()
Emitted when both an active control and active image list have been set.
void activeControlModified()
Emmited in cnetModified() when the actice control is modified.
void addTarget(Target *target)
Adds a new target to the project.
QList< TemplateList * > mapTemplates()
Return map template FileNames.
Control * control(QString id)
Accessor for if the project is clearing or not.
void createFolders()
This creates the project root, image root, and control net root directories.
static QString resultsRoot(QString projectRoot)
Appends the root directory name 'results' to the project.
void cnetModified()
When a cnet is modified, set the project state to not clean.
void guiCamerasAdded(GuiCameraList *targets)
Emitted when new GuiCamera objects added to project receivers: Directory.
QString imageDataRoot() const
Accessor for the root directory of the image data.
void bundleSolutionInfoClosed(QObject *bundleSolutionInfo)
A BundleSolutionInfo object is being deleted from the project.
void shapesAdded(ShapeList *shapes)
Emitted when new shape model images are available.
static QStringList images(QStringList)
Verify that the input fileNames are image files.
void cnetSaved(bool value)
Emmited in save() when the project is being saved Connected to Directory so that ControlPointEditWidg...
QString cnetRoot() const
Get where control networks ought to be stored inside the project.
void checkControlsAndImagesAvailable()
Checks if at least one control and image have been added to the project.
QList< ControlList * > controls()
Return controls in project.
QMap< QString, Control * > * m_idToControlMap
This variable will probably go away when we add the bundle results object because it will be under: B...
bool m_clearing
used to determine whether a project's changes are unsaved
Directory * directory() const
Returns the directory associated with this Project.
int m_numImagesCurrentlyReading
used to negate segfaults happening in post undos when clearning project
void targetsAdded(TargetBodyList *targets)
Emitted when new TargetBody objects added to project receivers: Directory.
bool isClean()
Accessor to determine whether the current project is Unsaved.
void open(QString)
Open the project at the given path.
ImageList * activeImageList()
Returns the active ImageList.
QList< BundleSolutionInfo * > bundleSolutionInfo()
Return BundleSolutionInfo objects in Project.
QString projectRoot() const
Get the top-level folder of the project.
QString name() const
Get the project's GUI name.
void setClean(bool value)
Function to change the clean state of the project.
Control * activeControl()
Return the Active Control (control network)
void loadBundleSolutionInfo(BundleSolutionInfo *bundleSolutionInfo)
Loads bundle solution info into project.
void addCamera(Camera *camera)
Adds a new camera to the project.
QDir addImageFolder(QString prefix)
Create and return the name of a folder for placing images.
void nameChanged(QString newName)
Emitted when project name is changed receivers: ProjectTreeWidget.
void saveWarnings(QXmlStreamWriter &stream) const
Serialize the warnings into the given XML.
void relocateProjectRoot(QString newRoot)
This is called when the project is moved.
void controlListDeleted(QObject *controlList)
An control list is being deleted from the project.
QString shapeDataRoot() const
Accessor for the root directory of the shape model data.
bool isOpen()
Accessor to determine whether a current project is Open.
QList< ImageList * > images()
Return projects imagelist.
static QString imageDataRoot(QString projectRoot)
Appends the root directory name 'images' to the project .
void controlsAndImagesAvailable()
Emitted when at least one cnet and image have been added to the project.
Image * image(QString id)
Return an image given its id.
void addTemplates(TemplateList *templateFiles)
Add new templates to m_mapTemplates or m_regTemplates and update project item model.
void addShapes(QStringList shapeFiles)
Read the given shape model cube file names as Images and add them to the project.
Project(Directory &directory, QObject *parent=0)
Create a new Project.
void addImages(QStringList imageFiles)
Read the given cube file names as Images and add them to the project.
bool save()
Generic save method to save the state of the project.
QDir addShapeFolder(QString prefix)
Create and return the name of a folder for placing shape models.
ControlList * controlList(QString name)
Return controlslist matching name in Project.
Represents an item of a ProjectItemModel in Qt's model-view framework.
bool isControl() const
Returns true if a Control is stored in the data of the item.
bool isImageList() const
Returns true if an ImageList is stored in the data of the item.
ImageList * imageList() const
Returns the ImageList stored in the data of the item.
Control * control() const
Returns the Control stored in the data of the item.
ProjectItem * findItemData(const QVariant &data, int role=Qt::UserRole+1)
Returns the first item found that contains the given data in the given role or a null pointer if no i...
This represents a shape in a project-based GUI interface.
void closeCube()
Cleans up the Cube *.
QString id() const
Get a unique, identifying string associated with this shape.
Internalizes a list of shapes and allows for operations on the entire list.
void append(Shape *const &value)
Appends an shape to the shape list.
void deleteFromDisk(Project *project)
Delete all of the contained Shapes from disk.
void removeAt(int i)
Removes the shape at an index.
void setName(QString newName)
Set the human-readable name of this shape list.
QString name() const
Get the human-readable name of this shape list.
void setPath(QString newPath)
Set the relative path (from the project root) to this shape list's folder.
Container class for TargetBody.
List for holding TargetBodies.
This class is used to create and store valid Isis targets.
QString type() const
Get the type of template in this TemplateList.
static WorkOrder * create(Project *project, QString type)
This instantiates a work order given a project and a type name (class name in a string).
Provide Undo/redo abilities, serialization, and history for an operation.
void setNext(WorkOrder *nextWorkOrder)
Sets the next WorkOrder in the sequence.
bool isUndoing() const
Returns the WorkOrderUndoing state.
void save(QXmlStreamWriter &stream) const
: Saves a WorkOrder to a data stream.
virtual void redo()
Starts (or enqueues) a redo.
bool isUndoable() const
Returns true if this work order is undoable, otherwise false.
WorkOrder * previous() const
Gets the previous WorkOrder.
bool isUndone() const
Returns the WorkOrder undo status.
virtual bool setupExecution()
This sets up the state for the work order.
bool isSavedToHistory() const
Returns true if this work order is to be shown in History, otherwise false.
virtual void execute()
Execute the workorder.
void setPrevious(WorkOrder *previousWorkOrder)
Sets the previous WorkOrder in the sequence.
bool createsCleanState() const
Returns the CleanState status (whether the Project has been saved to disk or not).
This is free and unencumbered software released into the public domain.
This is free and unencumbered software released into the public domain.
This is free and unencumbered software released into the public domain.
QSharedPointer< GuiCamera > GuiCameraQsp
GuiCameraQsp Represents a smart pointer to a GuiCamera object.
QSharedPointer< TargetBody > TargetBodyQsp
Defines A smart pointer to a TargetBody obj.
QString toString(const LinearAlgebra::Vector &vector, int precision)
A global function to format LinearAlgebra::Vector as a QString with the given precision.