27#include <QApplication>
34#include <QFutureWatcher>
37#include <QMutexLocker>
38#include <QProgressBar>
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;
122 m_idToImageMap =
new QMap<QString, Image *>;
123 m_idToShapeMap =
new QMap<QString, Shape *>;
124 m_idToTargetBodyMap =
new QMap<QString, TargetBody *>;
125 m_idToGuiCameraMap =
new QMap<QString, GuiCamera *>;
126 m_idToBundleSolutionInfoMap =
new QMap<QString, BundleSolutionInfo *>;
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(QRegExp(
".*_"),
"");
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) +
"]";
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) {
182 catch (std::exception &e) {
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)),
208 m_images =
new QList<ImageList *>;
211 m_shapeMutex =
new QMutex;
213 m_shapeReader =
new ShapeReader(m_shapeMutex,
false);
215 connect( m_shapeReader, SIGNAL( shapesReady(
ShapeList) ),
218 m_shapes =
new QList<ShapeList *>;
220 m_controls =
new QList<ControlList *>;
224 m_mapTemplates =
new QList<TemplateList *>;
226 m_regTemplates =
new QList<TemplateList *>;
230 m_bundleSolutionInfo =
new QList<BundleSolutionInfo *>;
233 m_workOrderHistory =
new QList< QPointer<WorkOrder> >;
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(NULL);
371 m_workOrderHistory = NULL;
373 delete m_bundleSettings;
374 m_bundleSettings = NULL;
383 if ( !dir.mkpath( m_projectRoot->path() ) ) {
384 warn(
"Cannot create project directory.");
386 tr(
"Unable to create folder [%1] when trying to initialize project")
387 .arg(m_projectRoot->path() ),
393 QString msg = QString(
"Unable to create folder [%1] when trying to initialize project")
400 QString msg = QString(
"Unable to create folder [%1] when trying to initialize project")
407 QString msg = QString(
"Unable to create folder [%1] when trying to initialize project")
414 QString msg = QString(
"Unable to create folder [%1] when trying to initialize project")
420 QString msg = QString(
"Unable to create folder [%1] when trying to initialize project")
426 QString msg = QString(
"Unable to create folder [%1] when trying to initialize project")
432 QString msg = QString(
"Unable to create folder [%1] when trying to initialize project")
437 if ( !dir.mkdir(
templateRoot() +
"/registrations" ) ) {
438 QString msg = QString(
"Unable to create folder [%1] when trying to initialize project")
445 warn(
"Failed to create project directory structure");
471 bool bundles =
false;
474 if (projectXml.open(QIODevice::ReadOnly)) {
475 QTextStream projectXmlInput(&projectXml);
477 while (!projectXmlInput.atEnd() ) {
479 QString line = projectXmlInput.readLine();
481 if (
controls || line.contains(
"<controlNets>") ) {
484 if (line.contains(
"</controlNets>") ) {
488 else if (!line.contains(
"<controlNets>") ) {
489 cnetDirList.append(line.split(
'"').at(3));
493 else if (
images || line.contains(
"<imageLists>") ) {
496 if (line.contains(
"</imageLists>")) {
500 else if (!line.contains(
"<imageLists>") ) {
501 imageDirList.append(line.split(
'"').at(3).simplified());
505 else if (
shapes || line.contains(
"<shapeLists>")) {
508 if (line.contains(
"</shapeLists>") ) {
512 else if (!line.contains(
"<shapeLists>") ) {
513 shapeDirList.append(line.split(
'"').at(3));
517 else if (
mapTemplates || line.contains(
"<mapTemplateLists>") ) {
520 if (line.contains(
"</mapTemplateLists>") ) {
524 else if (!line.contains(
"<mapTemplateLists>") ) {
525 QList<QString> components = line.split(
'"');
526 mapTemplateDirList.append(components.at(5));
530 else if (
regTemplates || line.contains(
"<regTemplateLists>") ) {
533 if (line.contains(
"</regTemplateLists>") ) {
537 else if (!line.contains(
"<regTemplateLists>") ) {
538 QList<QString> components = line.split(
'"');
539 regTemplateDirList.append(components.at(5));
543 else if (bundles || line.contains(
"<bundleSolutionInfo>") ) {
546 if (line.contains(
"</bundleSolutionInfo>") ) {
550 else if (line.contains(
"<runTime>") ) {
551 bundleDirList.append(line.split(
'>').at(1).split(
'<').at(0));
556 QDir cnetsDir(m_projectRoot->path() +
"/cnets/");
557 cnetsDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
559 foreach (QString dir, cnetsList) {
560 dir = dir.simplified();
562 if ( !cnetDirList.contains(dir) ) {
563 QDir tempDir(cnetsDir.path() +
"/" + dir);
564 tempDir.removeRecursively();
568 QDir imagesDir(m_projectRoot->path() +
"/images/");
569 imagesDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
571 foreach (QString dir, imagesList) {
572 dir = dir.simplified();
574 if ( !imageDirList.contains(dir) ) {
575 QDir tempDir(imagesDir.path() +
"/" + dir);
576 tempDir.removeRecursively();
580 QDir shapesDir(m_projectRoot->path() +
"/shapes/");
581 shapesDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
583 foreach (QString dir, shapesList) {
584 dir = dir.simplified();
586 if ( !shapeDirList.contains(dir) ) {
587 QDir tempDir(shapesDir.path() +
"/" + dir);
588 tempDir.removeRecursively();
592 QDir mapTemplatesDir(m_projectRoot->path() +
"/templates/maps");
593 mapTemplatesDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
594 QStringList mapTemplatesList = mapTemplatesDir.entryList();
595 foreach (QString dir, mapTemplatesList) {
596 dir = dir.simplified();
598 if ( !mapTemplateDirList.contains(
"maps/" + dir) ) {
599 QDir tempDir(mapTemplatesDir.path() +
"/" + dir);
600 tempDir.removeRecursively();
604 QDir regTemplatesDir(m_projectRoot->path() +
"/templates/registrations");
605 regTemplatesDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
606 QStringList regTemplatesList = regTemplatesDir.entryList();
607 foreach (QString dir, regTemplatesList) {
608 dir = dir.simplified();
610 if ( !regTemplateDirList.contains(
"registrations/" + dir)) {
611 QDir tempDir(regTemplatesDir.path() +
"/" + dir);
612 tempDir.removeRecursively();
616 QDir bundlesDir(m_projectRoot->path() +
"/results/bundle/");
617 bundlesDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
619 foreach (QString dir, bundleList) {
620 dir = dir.simplified();
622 if ( !bundleDirList.contains(dir) ) {
623 QDir tempDir(bundlesDir.path() +
"/" + dir);
624 tempDir.removeRecursively();
632 QString tmpFolder = QDir::temp().absolutePath() +
"/"
634 + QApplication::applicationName() +
"_" + QString::number( getpid() );
635 QDir temp(tmpFolder +
"/tmpProject");
636 m_projectRoot =
new QDir(temp);
643 catch (std::exception &e) {
645 tr(
"Error creating project folders [%1]").arg( e.what() ), _FILEINFO_);
651 m_mapTemplates->clear();
652 m_regTemplates->clear();
654 m_guiCameras->
clear();
655 m_bundleSolutionInfo->clear();
656 m_workOrderHistory->clear();
663 bool Project::clearing() {
668 ImageList *Project::createOrRetrieveImageList(QString name, QString path) {
681 connect( result, SIGNAL( destroyed(
QObject *) ),
683 m_images->append(result);
689 ShapeList *Project::createOrRetrieveShapeList(QString name, QString path) {
702 connect( result, SIGNAL( destroyed(
QObject *) ),
704 m_shapes->append(result);
724 stream.writeStartElement(
"project");
726 stream.writeAttribute(
"name", m_name);
728 if ( !m_controls->isEmpty() ) {
729 stream.writeStartElement(
"controlNets");
731 for (
int i = 0; i < m_controls->count(); i++) {
735 stream.writeEndElement();
738 if ( !m_images->isEmpty() ) {
739 stream.writeStartElement(
"imageLists");
740 for (
int i = 0; i < m_images->count(); i++) {
744 stream.writeEndElement();
747 if ( !m_shapes->isEmpty() ) {
748 stream.writeStartElement(
"shapeLists");
750 for (
int i = 0; i < m_shapes->count(); i++) {
754 stream.writeEndElement();
757 if ( !m_mapTemplates->isEmpty() ) {
758 stream.writeStartElement(
"mapTemplateLists");
760 for (
int i = 0; i < m_mapTemplates->count(); i++) {
764 stream.writeEndElement();
767 if ( !m_regTemplates->isEmpty() ) {
768 stream.writeStartElement(
"regTemplateLists");
770 for (
int i = 0; i < m_regTemplates->count(); i++) {
774 stream.writeEndElement();
807 if ( !m_bundleSolutionInfo->isEmpty() ) {
808 stream.writeStartElement(
"results");
810 for (
int i = 0; i < m_bundleSolutionInfo->count(); i++) {
814 stream.writeEndElement();
817 if (m_activeImageList) {
818 stream.writeStartElement(
"activeImageList");
819 stream.writeAttribute(
"displayName", m_activeImageList->name());
820 stream.writeEndElement();
823 if (m_activeControl) {
824 stream.writeStartElement(
"activeControl");
825 stream.writeAttribute(
"displayName", m_activeControl->displayProperties()->displayName());
826 stream.writeEndElement();
829 stream.writeEndElement();
849 stream.writeStartElement(
"history");
851 foreach (
WorkOrder *workOrder, *m_workOrderHistory) {
853 workOrder->save(stream);
857 stream.writeEndElement();
872 stream.writeStartElement(
"warnings");
874 foreach (QString warning, *m_warnings) {
875 stream.writeStartElement(
"warning");
876 stream.writeAttribute(
"text", warning);
877 stream.writeEndElement();
880 stream.writeEndElement();
895 foreach (QString fileName, fileNames) {
898 result.append(fileName);
926 int prefixCounter = 0;
928 QString numberedPrefix;
931 numberedPrefix = prefix.arg( QString::number(prefixCounter) );
933 while ( cnetFolder.exists(numberedPrefix) );
935 if ( !cnetFolder.mkpath(numberedPrefix) ) {
937 tr(
"Could not create control network directory [%1] in [%2].")
938 .arg(numberedPrefix).arg( cnetFolder.absolutePath() ),
942 cnetFolder.cd(numberedPrefix);
944 m_currentCnetFolder = cnetFolder;
970 ControlList *Project::createOrRetrieveControlList(QString name, QString path) {
984 connect( result, SIGNAL( destroyed(
QObject *) ),
987 m_controls->append(result);
1003 int prefixCounter = 0;
1005 QString numberedPrefix;
1008 numberedPrefix = prefix.arg( QString::number(prefixCounter) );
1010 while ( imageFolder.exists(numberedPrefix) );
1012 if ( !imageFolder.mkpath(numberedPrefix) ) {
1014 tr(
"Could not create image directory [%1] in [%2].")
1015 .arg(numberedPrefix).arg( imageFolder.absolutePath() ),
1019 imageFolder.cd(numberedPrefix);
1031 m_imageReadingMutex->lock();
1035 m_imageReader->read(imageFiles);
1060 int prefixCounter = 0;
1062 QString numberedPrefix;
1065 numberedPrefix = prefix.arg( QString::number(prefixCounter) );
1067 while ( shapeFolder.exists(numberedPrefix) );
1069 if ( !shapeFolder.mkpath(numberedPrefix) ) {
1071 tr(
"Could not create shape directory [%1] in [%2].")
1072 .arg(numberedPrefix).arg( shapeFolder.absolutePath() ),
1076 shapeFolder.cd(numberedPrefix);
1087 if (m_numShapesCurrentlyReading == 0) {
1088 m_shapeReadingMutex->lock();
1091 m_numShapesCurrentlyReading += shapeFiles.count();
1092 m_shapeReader->read(shapeFiles);
1101 shapesReady(newShapes);
1111 foreach (
Template *templateFile, *templateList) {
1113 templateFile, SLOT( updateFileName(
Project *) ) );
1115 if (templateList->
type() ==
"maps") {
1116 m_mapTemplates->append(templateList);
1118 else if (templateList->
type() ==
"registrations") {
1119 m_regTemplates->append(templateList);
1122 emit templatesAdded(templateList);
1134 int prefixCounter = 0;
1135 QString numberedPrefix;
1139 numberedPrefix = prefix.arg( QString::number(prefixCounter) );
1141 while ( templateFolder.exists(numberedPrefix) );
1143 if ( !templateFolder.mkpath(numberedPrefix) ) {
1145 tr(
"Could not create template directory [%1] in [%2].")
1146 .arg(numberedPrefix).arg( templateFolder.absolutePath() ),
1150 templateFolder.cd(numberedPrefix);
1152 return templateFolder;
1174 if (!bundleSolutionInfoFolder.mkpath(folder)) {
1176 tr(
"Could not create bundle results directory [%1] in [%2].")
1177 .arg(folder).arg(bundleSolutionInfoFolder.absolutePath()),
1181 bundleSolutionInfoFolder.cd(folder);
1182 return bundleSolutionInfoFolder;
1231 void Project::writeSettings() {
1233 QString appName = QApplication::applicationName();
1236 QSettings globalSettings(
1237 FileName(
"$HOME/.Isis/" + appName +
"/" + appName +
"_" +
"Project.config")
1239 QSettings::NativeFormat);
1241 globalSettings.beginGroup(
"recent_projects");
1243 QMap<QString,QString> recentProjects;
1245 foreach (QString key,keys) {
1247 recentProjects[key]=globalSettings.value(key).toString();
1251 QList<QString> projectPaths = recentProjects.values();
1253 if (keys.count() >= m_maxRecentProjects) {
1256 globalSettings.remove(
"");
1262 if (!this->
projectRoot().contains(
"tmpProject") && !projectPaths.contains(this->projectRoot()) ) {
1263 QString s=keys.first();
1264 recentProjects.remove( s );
1270 if (projectPaths.contains(this->projectRoot())) {
1271 QString key = recentProjects.key(this->
projectRoot());
1272 recentProjects.remove(key);
1278 for (i=recentProjects.begin();i!=recentProjects.end();i++) {
1280 globalSettings.setValue(i.key(),i.value());
1285 long t0 = QDateTime::currentMSecsSinceEpoch();
1286 QString projName = this->
name();
1288 QString t0String=QString::number(t0);
1291 if (!this->
projectRoot().contains(
"tmpProject") ) {
1292 globalSettings.setValue(t0String+
"%%%%%"+projName,this->
projectRoot());
1302 globalSettings.remove(
"");
1303 if (projectPaths.contains(this->projectRoot())) {
1304 QString key = recentProjects.key(this->
projectRoot());
1305 recentProjects.remove(key);
1310 for ( i=recentProjects.begin(); i!=recentProjects.end(); i++ ) {
1311 globalSettings.setValue(i.key(),i.value());
1314 long t0 = QDateTime::currentMSecsSinceEpoch();
1315 QString projName = this->
name();
1316 QString t0String=QString::number(t0);
1319 if (!this->
projectRoot().contains(
"tmpProject") ) {
1320 globalSettings.setValue(t0String+
"%%%%%"+projName,this->
projectRoot());
1326 globalSettings.endGroup();
1344 QString projectAbsolutePathStr = QDir(projectPathStr).absolutePath();
1346 QString projectXmlPath = projectAbsolutePathStr +
"/project.xml";
1347 QFile file(projectXmlPath);
1349 if ( !file.open(QFile::ReadOnly) ) {
1351 QString(
"Unable to open [%1] with read access")
1352 .arg(projectXmlPath),
1356 QString projectXmlHistoryPath = projectAbsolutePathStr +
"/history.xml";
1357 QFile historyFile(projectXmlHistoryPath);
1359 if ( !historyFile.open(QFile::ReadOnly) ) {
1361 QString(
"Unable to open [%1] with read access")
1362 .arg(projectXmlHistoryPath),
1366 QString projectXmlWarningsPath = projectAbsolutePathStr +
"/warnings.xml";
1367 QFile warningsFile(projectXmlWarningsPath);
1369 if (!warningsFile.open(QFile::ReadOnly)) {
1371 QString(
"Unable to open [%1] with read access")
1372 .arg(projectXmlWarningsPath),
1376 QString directoryXmlPath = projectAbsolutePathStr +
"/directory.xml";
1377 QFile directoryFile(directoryXmlPath);
1379 if (!directoryFile.open(QFile::ReadOnly)) {
1381 QString(
"Unable to open [%1] with read access")
1382 .arg(directoryXmlPath),
1390 m_isTemporaryProject =
false;
1392 QDir oldProjectRoot(*m_projectRoot);
1393 *m_projectRoot = QDir(projectAbsolutePathStr);
1395 QXmlStreamReader projectXmlReader(&file);
1401 readProjectXml(&projectXmlReader);
1405 .arg(projectAbsolutePathStr));
1408 catch (std::exception &e) {
1410 .arg(projectAbsolutePathStr));
1414 QXmlStreamReader reader2(&historyFile);
1417 while (!reader2.atEnd()) {
1424 .arg(projectAbsolutePathStr));
1427 catch (std::exception &e) {
1429 .arg(projectAbsolutePathStr));
1433 QXmlStreamReader reader3(&warningsFile);
1435 while (!reader3.atEnd()) {
1438 if (reader3.hasError()) {
1439 warn(tr(
"Failed to read warnings from project [%1]").arg(projectAbsolutePathStr));
1442 QXmlStreamReader reader4(&directoryFile);
1445 while (!reader4.atEnd()) {
1451 .arg(projectAbsolutePathStr));
1455 catch (std::exception &e) {
1457 .arg(projectAbsolutePathStr));
1462 if (bundleRoot.exists()) {
1464 bundleRoot.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
1466 QFileInfoList bundleDirs = bundleRoot.entryInfoList();
1468 for (
int dirListIndex = 0; dirListIndex < bundleDirs.size(); dirListIndex++) {
1471 QDir bundleSolutionDir(bundleDirs[dirListIndex].absoluteFilePath());
1472 bundleSolutionDir.setFilter(QDir::Files | QDir::NoSymLinks);
1492 void Project::readProjectXml(QXmlStreamReader *xmlReader) {
1493 if (xmlReader->readNextStartElement()) {
1494 if (xmlReader->name() ==
"project") {
1495 QStringRef
name = xmlReader->attributes().value(
"name");
1496 if (!
name.isEmpty()) {
1500 else if (xmlReader->name() ==
"controlNets") {
1503 else if (xmlReader->name() ==
"imageList") {
1506 else if (xmlReader->name() ==
"shapeList") {
1509 else if (xmlReader->name() ==
"mapTemplateList") {
1512 else if (xmlReader->name() ==
"regTemplateList") {
1516 else if (xmlReader->name() ==
"workOrder") {
1517 QString type = *(xmlReader->attributes().value(
"type").string());
1524 else if (xmlReader->name() ==
"warning") {
1525 QString warningText = *(xmlReader->attributes().value(
"text").string());
1527 if (!warningText.isEmpty())
1529 m_project->warn(warningText);
1532 else if (xmlReader->name() ==
"directory") {
1535 else if (xmlReader->name() ==
"dockRestore") {
1541 else if (xmlReader->name() ==
"bundleSolutionInfo") {
1544 else if (xmlReader->name() ==
"activeImageList") {
1545 QString displayName = *(xmlReader->attributes().value(
"displayName").string());
1548 else if (xmlReader->name() ==
"activeControl") {
1550 QString displayName = *(xmlReader->attributes().value(
"displayName").string());
1555 xmlReader->raiseError(QObject::tr(
"Incorrect file"));
1561 return m_imageReader->progress();
1572 return (*m_idToImageMap)[id];
1582 QListIterator<ImageList *> it(*m_images);
1585 while (it.hasNext() && !result) {
1588 if (list->
name() ==
name) result = list;
1601 return (*m_idToShapeMap)[id];
1611 QListIterator<ShapeList *> it(*m_shapes);
1614 while (it.hasNext() && !result) {
1617 if (list->
name() ==
name) result = list;
1629 return m_isTemporaryProject;
1658 m_undoStack.cleanChanged(value);
1668 QListIterator< QPointer<WorkOrder> > it(*m_workOrderHistory);
1671 while ( !result && it.hasPrevious() ) {
1674 if ( !workOrder->isUndone() && !workOrder->isUndoing() ) {
1697 QListIterator< QPointer<WorkOrder> > it(*m_workOrderHistory);
1700 while ( !result && it.hasPrevious() ) {
1703 if ( !workOrder->isUndone() && !workOrder->isUndoing() ) {
1728 return m_projectRoot->path();
1737 return m_newProjectRoot;
1756 return &m_undoStack;
1760 QString Project::nextImageListGroupName() {
1761 int numLists = m_images->size();
1762 QString maxName =
"";
1763 QString newGroupName =
"Group";
1767 if ( !
name.contains(
"Group") )
continue;
1768 if ( maxName.isEmpty() ) {
1771 else if (
name > maxName) {
1776 if ( maxName.isEmpty() ) {
1777 newGroupName += QString::number(numLists+1);
1780 int maxNum = maxName.remove(
"Group").toInt();
1783 newGroupName += QString::number(maxNum);
1785 return newGroupName;
1794 QMutexLocker locker(m_imageReadingMutex);
1802 QMutexLocker locker(m_shapeReadingMutex);
1810 QList<WorkOrder *> result;
1811 foreach (
WorkOrder *workOrder, *m_workOrderHistory) {
1812 result.append(workOrder);
1829 if (m_activeControl && m_activeImageList) {
1881 Control *previousControl = m_activeControl;
1882 if (m_activeControl) {
1886 if (m_activeControl->isModified()) {
1888 msgBox.setText(
"Save current active control");
1889 msgBox.setInformativeText(
"The current active control has been modified. Do you want "
1890 "to save before setting a new active control?");
1891 msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
1892 msgBox.setDefaultButton(QMessageBox::Save);
1893 int ret = msgBox.exec();
1896 case QMessageBox::Save:
1897 m_activeControl->write();
1900 case QMessageBox::Discard:
1902 m_activeControl->closeControlNet();
1903 m_activeControl->openControlNet();
1904 emit discardActiveControlEdits();
1907 case QMessageBox::Cancel:
1913 displayProperties()->displayName(), Qt::DisplayRole);
1914 item->setTextColor(Qt::black);
1916 if (!
directory()->controlUsedInCnetEditorWidget(m_activeControl)) {
1917 m_activeControl->closeControlNet();
1923 m_activeControl = item->
control();
1926 m_activeControl->controlNet()->SetImages(*(
activeImageList()->serialNumberList()));
1927 item->setTextColor(Qt::darkGreen);
1930 if (previousControl) {
1931 m_activeControl = previousControl;
1933 displayProperties()->displayName(), Qt::DisplayRole);
1934 item->setTextColor(Qt::darkGreen);
1935 m_activeControl->controlNet()->SetImages(*(
activeImageList()->serialNumberList()));
1938 m_activeControl = NULL;
1966 if (!m_activeControl && (m_controls->count() == 1 && m_controls->at(0)->count() ==1)) {
1969 QString controlName = m_controls->at(0)->at(0)->displayProperties()->displayName();
1974 return m_activeControl;
1986 if (m_activeControl && m_activeControl->isModified()) {
2017 ImageList *previousImageList = m_activeImageList;
2018 if (m_activeImageList) {
2020 name(), Qt::DisplayRole);
2021 item->setTextColor(Qt::black);
2027 if (m_activeControl) {
2032 if (previousImageList) {
2033 m_activeImageList = previousImageList;
2035 name(), Qt::DisplayRole);
2036 item->setTextColor(Qt::darkGreen);
2040 m_activeImageList = NULL;
2045 item->setTextColor(Qt::darkGreen);
2066 if (!m_activeImageList && m_images->count() == 1) {
2067 QString
imageList = m_images->at(0)->name();
2071 return m_activeImageList;
2091 return cnetRoot( m_projectRoot->path() );
2110 QListIterator< ControlList * > it(*m_controls);
2113 while (it.hasNext() && !result) {
2116 if (list->
name() ==
name) result = list;
2207 QList<TemplateList *> allTemplates = *m_mapTemplates + *m_regTemplates;
2208 return allTemplates;
2218 return *m_mapTemplates;
2228 return *m_regTemplates;
2285 return *m_bundleSolutionInfo;
2319 foreach (
ImageList *imagesInAFolder, *m_images) {
2320 imagesInAFolder->deleteFromDisk(
this);
2324 warn( tr(
"Did not properly clean up images folder [%1] in project").arg(
imageDataRoot() ) );
2327 foreach (
ShapeList *shapesInAFolder, *m_shapes) {
2328 shapesInAFolder->deleteFromDisk(
this);
2332 warn( tr(
"Did not properly clean up shapes folder [%1] in project").
2336 foreach (
ControlList *controlsInAFolder, *m_controls) {
2337 controlsInAFolder->deleteFromDisk(
this);
2340 if ( !m_projectRoot->rmdir(
cnetRoot() ) ) {
2341 warn( tr(
"Did not properly clean up control network folder [%1] in project")
2345 if ( !(QDir(
resultsRoot()).removeRecursively()) ) {
2346 warn( tr(
"Did not properly clean up results folder [%1] in project")
2351 warn( tr(
"Did not properly clean up templates folder [%1] in project")
2355 if ( !m_projectRoot->rmpath( m_projectRoot->path() ) ) {
2356 warn( tr(
"Did not properly clean up project in [%1]").arg( m_projectRoot->path() ) );
2387 bool saveDialogCompleted =
true;
2389 if (m_isTemporaryProject) {
2390 QString newDestination = QFileDialog::getSaveFileName(NULL,
2391 QString(
"Project Location"),
2394 if ( !newDestination.isEmpty() ) {
2395 m_isTemporaryProject =
false;
2396 save( QFileInfo(newDestination +
"/").absolutePath() );
2406 open(newDestination);
2410 saveDialogCompleted =
false;
2424 save(m_projectRoot->absolutePath(),
false);
2428 return saveDialogCompleted;
2534 if ( verifyPathDoesntExist && QFile::exists( newPath.toString() ) ) {
2536 QString(
"Projects may not be saved to an existing path [%1]; "
2537 "please select a new path or delete the current folder")
2538 .arg(newPath.original()),
2543 if (!dir.mkpath(newPath.toString())) {
2545 QString(
"Unable to save project at [%1] "
2546 "because we could not create the folder")
2547 .arg(newPath.original()),
2555 m_newProjectRoot = newPath.toString();
2560 m_name = newPath.name();
2562 QFile projectSettingsFile(newPath.toString() +
"/project.xml");
2563 if (!projectSettingsFile.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
2565 QString(
"Unable to save project at [%1] because the file [%2] "
2566 "could not be opened for writing")
2567 .arg(newPath.original()).arg(projectSettingsFile.fileName()),
2571 QXmlStreamWriter writer(&projectSettingsFile);
2572 writer.setAutoFormatting(
true);
2574 writer.writeStartDocument();
2577 save(writer, newPath);
2579 writer.writeEndDocument();
2581 QFile projectHistoryFile(newPath.toString() +
"/history.xml");
2582 if (!projectHistoryFile.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
2584 QString(
"Unable to save project at [%1] because the file [%2] "
2585 "could not be opened for writing")
2586 .arg(newPath.original()).arg(projectHistoryFile.fileName()),
2590 QXmlStreamWriter historyWriter(&projectHistoryFile);
2591 historyWriter.setAutoFormatting(
true);
2593 historyWriter.writeStartDocument();
2595 historyWriter.writeEndDocument();
2597 QFile projectWarningsFile(newPath.toString() +
"/warnings.xml");
2598 if (!projectWarningsFile.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
2600 QString(
"Unable to save project at [%1] because the file [%2] could not be "
2601 "opened for writing")
2602 .arg(newPath.original()).arg(projectWarningsFile.fileName()),
2606 QXmlStreamWriter warningsWriter(&projectWarningsFile);
2607 warningsWriter.setAutoFormatting(
true);
2609 warningsWriter.writeStartDocument();
2611 warningsWriter.writeEndDocument();
2614 QFile directoryStateFile(newPath.toString() +
"/directory.xml");
2615 if (!directoryStateFile.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
2617 QString(
"Unable to save project at [%1] because the file [%2] could not be "
2618 "opened for writing")
2619 .arg(newPath.original()).arg(directoryStateFile.fileName()),
2623 QXmlStreamWriter directoryStateWriter(&directoryStateFile);
2624 directoryStateWriter.setAutoFormatting(
true);
2626 directoryStateWriter.writeStartDocument();
2633 m_directory->save(directoryStateWriter, newPath);
2635 directoryStateWriter.writeEndDocument();
2661 connect(workOrder, SIGNAL(finished(
WorkOrder *)),
2666 if (workOrder->setupExecution()) {
2667 if (workOrder->previous()) workOrder->previous()->setNext(workOrder);
2669 m_workOrderHistory->append(workOrder);
2671 if (workOrder->isSavedToHistory()) {
2677 if (workOrder->createsCleanState()) {
2678 m_undoStack.setClean();
2679 workOrder->execute();
2682 else if (workOrder->isUndoable()) {
2685 m_undoStack.push(workOrder);
2694 m_workOrderHistory->removeAll(NULL);
2704 template<
typename Data>
void Project::warn(QString text, Data relevantData) {
2705 storeWarning(text, relevantData);
2710 void Project::warn(QString text) {
2711 foreach (QString line, text.split(
"\n")) {
2718 void Project::storeWarning(QString text) {
2719 m_warnings->append(text);
2738 if (
images.name() !=
"") {
2750 QMutexLocker lock(m_mutex);
2754 foreach (openImage,
images) {
2765 m_imageReadingMutex->unlock();
2778 if (QString::compare(targetBody->targetName(),
id, Qt::CaseInsensitive) == 0) {
2795 m_targets->
append(targetBody);
2809 if (QString::compare(camera->instrumentId(),
id, Qt::CaseInsensitive) == 0) {
2826 m_guiCameras->
append(guiCamera);
2847 void Project::removeImages(
ImageList &imageList) {
2853 m_images->removeOne(list);
2864 QMutableListIterator<ImageList *> it(*m_images);
2865 while (it.hasNext()) {
2868 int foundElement = list->indexOf((
Image *)imageObj);
2870 if (foundElement != -1) {
2875 m_idToImageMap->remove(m_idToImageMap->key((
Image *)imageObj));
2884 int indexToRemove = m_images->indexOf(
static_cast<ImageList *
>(imageListObj));
2885 if (indexToRemove != -1) {
2886 m_images->removeAt(indexToRemove);
2903 int indexToRemove = m_controls->indexOf(
static_cast<ControlList *
>(controlListObj));
2904 if (indexToRemove != -1) {
2905 m_controls->removeAt(indexToRemove);
2918 int indexToRemove = m_shapes->indexOf(
static_cast<ShapeList *
>(shapeListObj));
2919 if (indexToRemove != -1) {
2920 m_shapes->removeAt(indexToRemove);
2929 QMutableListIterator<BundleSolutionInfo *> it(*m_bundleSolutionInfo);
2930 while (it.hasNext()) {
2936 int foundElement = m_bundleSolutionInfo->indexOf(
2939 if (foundElement != -1) {
2940 m_bundleSolutionInfo->removeAt(foundElement);
2944 m_idToBundleSolutionInfoMap->remove(
2974 void Project::shapesReady(
ShapeList shapes) {
2976 m_numShapesCurrentlyReading -=
shapes.count();
2985 if (
shapes.name() !=
"") {
2998 QMutexLocker lock(m_shapeMutex);
3002 foreach (openShape,
shapes) {
3006 if (m_numShapesCurrentlyReading == 0) {
3007 m_shapeReadingMutex->unlock();
3016 QMutableListIterator<ShapeList *> it(*m_shapes);
3017 while (it.hasNext()) {
3020 int foundElement = list->indexOf((
Shape *)imageObj);
3022 if (foundElement != -1) {
3027 m_idToShapeMap->remove(m_idToShapeMap->key((
Shape *)imageObj));
3041 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.
QString id() const
Access the unique ID associated with this Control.
ControlNet * controlNet()
Open and return a pointer to the ControlNet for this Control.
bool write()
@description Write control net to disk.
bool isModified()
@description Has this control been modified?
QString fileName() const
Access the name of the control network file associated with this Control.
Maintains a list of Controls so that control nets can easily be copied from one Project to another,...
void append(Control *const &value)
Appends a control pointer to the control list.
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.
File name manipulation and expansion.
QDir dir() const
Returns the path of the file's parent directory as a QDir object.
Container class for GuiCamera.
List of GuiCameras saved as QSharedPointers.
void clear()
Clears the list.
void append(GuiCameraQsp const &value)
Appends a single GuiCamera to the list.
@ Programmer
This error is for when a programmer made an API call that was illegal.
@ Io
A type of error that occurred when performing an actual I/O operation.
@ 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.
QString id() const
Get a unique, identifying string associated with this image.
Internalizes a list of images and allows for operations on the entire list.
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 append(Image *const &value)
Appends an image to the image list.
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.
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.
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.
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.
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.
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.
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.
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 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.
void append(TargetBodyQsp const &value)
Appends a TargetBody to the list.
void clear()
clears the list.
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.
WorkOrder * previous() const
Gets the previous WorkOrder.
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.
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
QSharedPointer< TargetBody > TargetBodyQsp
Defines A smart pointer to a TargetBody obj.