23 #include "IsisDebug.h"
28 #include <QApplication>
33 #include <QFileDialog>
35 #include <QFutureWatcher>
36 #include <QMessageBox>
38 #include <QMutexLocker>
39 #include <QProgressBar>
42 #include <QStringList>
44 #include <QTextStream>
46 #include <QXmlStreamWriter>
48 #include "BundleSettings.h"
49 #include "BundleSolutionInfo.h"
52 #include "ControlList.h"
53 #include "ControlNet.h"
54 #include "CorrelationMatrix.h"
56 #include "Directory.h"
57 #include "Environment.h"
60 #include "GuiCameraList.h"
61 #include "ImageList.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"
71 #include "ShapeList.h"
72 #include "ShapeReader.h"
74 #include "TargetBodyList.h"
76 #include "TemplateList.h"
77 #include "WorkOrder.h"
78 #include "WorkOrderFactory.h"
79 #include "XmlStackedHandlerReader.h"
90 m_bundleSettings = NULL;
96 m_idToImageMap = NULL;
97 m_idToShapeMap = NULL;
98 m_idToTargetBodyMap = NULL;
99 m_idToGuiCameraMap = NULL;
101 m_imageReader = NULL;
102 m_shapeReader = NULL;
104 m_mapTemplates = NULL;
105 m_regTemplates = NULL;
107 m_workOrderHistory = NULL;
108 m_isTemporaryProject =
true;
111 m_activeControl = NULL;
112 m_activeImageList = NULL;
117 m_workOrderMutex = NULL;
118 m_imageReadingMutex = NULL;
120 m_numShapesCurrentlyReading = 0;
122 m_shapeReadingMutex = NULL;
134 QDir tempDir = QDir::temp();
137 QApplication::applicationName() +
"_*");
138 tempDir.setNameFilters(nameFilters);
140 QStringList existingProjects = tempDir.entryList();
141 bool crashedPreviously =
false;
143 foreach (QString existingProject, existingProjects) {
144 FileName existingProjectFileName(tempDir.absolutePath() +
"/" + existingProject);
145 QString pidString = QString(existingProject).replace(QRegExp(
".*_"),
"");
146 int otherPid = pidString.toInt();
149 if ( !QFile::exists(
"/proc/" + pidString) ) {
150 crashedPreviously =
true;
151 int status = system( (
"rm -rf '" +
152 existingProjectFileName.
expanded() +
"' &").toLatin1().data() );
154 QString msg =
"Executing command [rm -rf" + existingProjectFileName.
expanded() +
155 "' &] failed with return status [" +
toString(status) +
"]";
162 if (crashedPreviously &&
false) {
163 QMessageBox::information( NULL,
164 QObject::tr(
"Crashed"),
165 QObject::tr(
"It appears %1 crashed. We're sorry.").
166 arg( QApplication::applicationName() ) );
169 QCoreApplication* ipce_app =
static_cast<QCoreApplication *
>(
directory.parent());
172 QString tmpFolder = QDir::temp().absolutePath() +
"/"
174 + QApplication::applicationName() +
"_" + QString::number( getpid() );
175 QDir temp(tmpFolder +
"/tmpProject");
176 m_projectRoot =
new QDir(temp);
178 if (ipce_app->arguments().count() == 1) {
185 catch (std::exception &e) {
188 tr(
"Error creating project folders [%1]").arg( e.what() ), _FILEINFO_);
192 m_mutex =
new QMutex;
193 m_workOrderMutex =
new QMutex;
208 connect(m_directory, SIGNAL(cleanProject(
bool)),
214 m_shapeMutex =
new QMutex;
216 m_shapeReader =
new ShapeReader(m_shapeMutex,
false);
218 connect( m_shapeReader, SIGNAL( shapesReady(
ShapeList) ),
238 m_imageReadingMutex =
new QMutex;
240 m_shapeReadingMutex =
new QMutex;
301 if (m_mapTemplates) {
303 foreach (
Template *templateFile, *templateList) {
310 delete m_mapTemplates;
311 m_mapTemplates = NULL;
315 if (m_regTemplates) {
317 foreach (
Template *templateFile, *templateList) {
324 delete m_regTemplates;
325 m_regTemplates = NULL;
329 m_activeControl = NULL;
330 m_activeImageList = NULL;
332 if (m_bundleSolutionInfo) {
337 delete m_bundleSolutionInfo;
338 m_bundleSolutionInfo = NULL;
344 delete m_idToImageMap;
345 m_idToImageMap = NULL;
347 delete m_idToShapeMap;
348 m_idToShapeMap = NULL;
350 delete m_idToTargetBodyMap;
351 m_idToTargetBodyMap = NULL;
353 delete m_idToGuiCameraMap;
354 m_idToGuiCameraMap = NULL;
356 delete m_idToBundleSolutionInfoMap;
357 m_idToBundleSolutionInfoMap = NULL;
361 delete m_projectRoot;
362 m_projectRoot = NULL;
367 delete m_imageReader;
368 delete m_shapeReader;
373 m_workOrderHistory->removeAll(NULL);
374 m_workOrderHistory = NULL;
376 delete m_bundleSettings;
377 m_bundleSettings = NULL;
386 if ( !dir.mkpath( m_projectRoot->path() ) ) {
387 warn(
"Cannot create project directory.");
389 tr(
"Unable to create folder [%1] when trying to initialize project")
390 .arg(m_projectRoot->path() ),
396 QString msg = QString(
"Unable to create folder [%1] when trying to initialize project")
403 QString msg = QString(
"Unable to create folder [%1] when trying to initialize project")
410 QString msg = QString(
"Unable to create folder [%1] when trying to initialize project")
417 QString msg = QString(
"Unable to create folder [%1] when trying to initialize project")
423 QString msg = QString(
"Unable to create folder [%1] when trying to initialize project")
429 QString msg = QString(
"Unable to create folder [%1] when trying to initialize project")
435 QString msg = QString(
"Unable to create folder [%1] when trying to initialize project")
440 if ( !dir.mkdir(
templateRoot() +
"/registrations" ) ) {
441 QString msg = QString(
"Unable to create folder [%1] when trying to initialize project")
448 warn(
"Failed to create project directory structure");
474 bool bundles =
false;
477 if (projectXml.open(QIODevice::ReadOnly)) {
478 QTextStream projectXmlInput(&projectXml);
480 while (!projectXmlInput.atEnd() ) {
482 QString line = projectXmlInput.readLine();
484 if (
controls || line.contains(
"<controlNets>") ) {
487 if (line.contains(
"</controlNets>") ) {
491 else if (!line.contains(
"<controlNets>") ) {
492 cnetDirList.append(line.split(
'"').at(3));
496 else if (
images || line.contains(
"<imageLists>") ) {
499 if (line.contains(
"</imageLists>")) {
503 else if (!line.contains(
"<imageLists>") ) {
504 imageDirList.append(line.split(
'"').at(3).simplified());
508 else if (
shapes || line.contains(
"<shapeLists>")) {
511 if (line.contains(
"</shapeLists>") ) {
515 else if (!line.contains(
"<shapeLists>") ) {
516 shapeDirList.append(line.split(
'"').at(3));
520 else if (
mapTemplates || line.contains(
"<mapTemplateLists>") ) {
523 if (line.contains(
"</mapTemplateLists>") ) {
527 else if (!line.contains(
"<mapTemplateLists>") ) {
529 mapTemplateDirList.append(components.at(5));
533 else if (
regTemplates || line.contains(
"<regTemplateLists>") ) {
536 if (line.contains(
"</regTemplateLists>") ) {
540 else if (!line.contains(
"<regTemplateLists>") ) {
542 regTemplateDirList.append(components.at(5));
546 else if (bundles || line.contains(
"<bundleSolutionInfo>") ) {
549 if (line.contains(
"</bundleSolutionInfo>") ) {
553 else if (line.contains(
"<runTime>") ) {
554 bundleDirList.append(line.split(
'>').at(1).split(
'<').at(0));
559 QDir cnetsDir(m_projectRoot->path() +
"/cnets/");
560 cnetsDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
562 foreach (QString dir, cnetsList) {
563 dir = dir.simplified();
565 if ( !cnetDirList.contains(dir) ) {
566 QDir tempDir(cnetsDir.path() +
"/" + dir);
567 tempDir.removeRecursively();
571 QDir imagesDir(m_projectRoot->path() +
"/images/");
572 imagesDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
574 foreach (QString dir, imagesList) {
575 dir = dir.simplified();
577 if ( !imageDirList.contains(dir) ) {
578 QDir tempDir(imagesDir.path() +
"/" + dir);
579 tempDir.removeRecursively();
583 QDir shapesDir(m_projectRoot->path() +
"/shapes/");
584 shapesDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
586 foreach (QString dir, shapesList) {
587 dir = dir.simplified();
589 if ( !shapeDirList.contains(dir) ) {
590 QDir tempDir(shapesDir.path() +
"/" + dir);
591 tempDir.removeRecursively();
595 QDir mapTemplatesDir(m_projectRoot->path() +
"/templates/maps");
596 mapTemplatesDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
597 QStringList mapTemplatesList = mapTemplatesDir.entryList();
598 foreach (QString dir, mapTemplatesList) {
599 dir = dir.simplified();
601 if ( !mapTemplateDirList.contains(
"maps/" + dir) ) {
602 QDir tempDir(mapTemplatesDir.path() +
"/" + dir);
603 tempDir.removeRecursively();
607 QDir regTemplatesDir(m_projectRoot->path() +
"/templates/registrations");
608 regTemplatesDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
609 QStringList regTemplatesList = regTemplatesDir.entryList();
610 foreach (QString dir, regTemplatesList) {
611 dir = dir.simplified();
613 if ( !regTemplateDirList.contains(
"registrations/" + dir)) {
614 QDir tempDir(regTemplatesDir.path() +
"/" + dir);
615 tempDir.removeRecursively();
619 QDir bundlesDir(m_projectRoot->path() +
"/results/bundle/");
620 bundlesDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
622 foreach (QString dir, bundleList) {
623 dir = dir.simplified();
625 if ( !bundleDirList.contains(dir) ) {
626 QDir tempDir(bundlesDir.path() +
"/" + dir);
627 tempDir.removeRecursively();
635 QString tmpFolder = QDir::temp().absolutePath() +
"/"
637 + QApplication::applicationName() +
"_" + QString::number( getpid() );
638 QDir temp(tmpFolder +
"/tmpProject");
639 m_projectRoot =
new QDir(temp);
646 catch (std::exception &e) {
648 tr(
"Error creating project folders [%1]").arg( e.what() ), _FILEINFO_);
654 m_mapTemplates->clear();
655 m_regTemplates->clear();
657 m_guiCameras->
clear();
658 m_bundleSolutionInfo->clear();
659 m_workOrderHistory->clear();
666 bool Project::clearing() {
671 ImageList *Project::createOrRetrieveImageList(QString name, QString path) {
684 connect( result, SIGNAL( destroyed(
QObject *) ),
686 m_images->append(result);
692 ShapeList *Project::createOrRetrieveShapeList(QString name, QString path) {
705 connect( result, SIGNAL( destroyed(
QObject *) ),
707 m_shapes->append(result);
727 stream.writeStartElement(
"project");
729 stream.writeAttribute(
"name", m_name);
731 if ( !m_controls->isEmpty() ) {
732 stream.writeStartElement(
"controlNets");
734 for (
int i = 0; i < m_controls->count(); i++) {
738 stream.writeEndElement();
741 if ( !m_images->isEmpty() ) {
742 stream.writeStartElement(
"imageLists");
743 for (
int i = 0; i < m_images->count(); i++) {
747 stream.writeEndElement();
750 if ( !m_shapes->isEmpty() ) {
751 stream.writeStartElement(
"shapeLists");
753 for (
int i = 0; i < m_shapes->count(); i++) {
757 stream.writeEndElement();
760 if ( !m_mapTemplates->isEmpty() ) {
761 stream.writeStartElement(
"mapTemplateLists");
763 for (
int i = 0; i < m_mapTemplates->count(); i++) {
767 stream.writeEndElement();
770 if ( !m_regTemplates->isEmpty() ) {
771 stream.writeStartElement(
"regTemplateLists");
773 for (
int i = 0; i < m_regTemplates->count(); i++) {
777 stream.writeEndElement();
810 if ( !m_bundleSolutionInfo->isEmpty() ) {
811 stream.writeStartElement(
"results");
813 for (
int i = 0; i < m_bundleSolutionInfo->count(); i++) {
817 stream.writeEndElement();
820 if (m_activeImageList) {
821 stream.writeStartElement(
"activeImageList");
822 stream.writeAttribute(
"displayName", m_activeImageList->name());
823 stream.writeEndElement();
826 if (m_activeControl) {
827 stream.writeStartElement(
"activeControl");
828 stream.writeAttribute(
"displayName", m_activeControl->displayProperties()->displayName());
829 stream.writeEndElement();
832 stream.writeEndElement();
852 stream.writeStartElement(
"history");
854 foreach (
WorkOrder *workOrder, *m_workOrderHistory) {
856 workOrder->
save(stream);
860 stream.writeEndElement();
875 stream.writeStartElement(
"warnings");
877 foreach (QString warning, *m_warnings) {
878 stream.writeStartElement(
"warning");
879 stream.writeAttribute(
"text", warning);
880 stream.writeEndElement();
883 stream.writeEndElement();
898 foreach (QString fileName, fileNames) {
901 result.append(fileName);
929 int prefixCounter = 0;
931 QString numberedPrefix;
934 numberedPrefix = prefix.arg( QString::number(prefixCounter) );
936 while ( cnetFolder.exists(numberedPrefix) );
938 if ( !cnetFolder.mkpath(numberedPrefix) ) {
940 tr(
"Could not create control network directory [%1] in [%2].")
941 .arg(numberedPrefix).arg( cnetFolder.absolutePath() ),
945 cnetFolder.cd(numberedPrefix);
947 m_currentCnetFolder = cnetFolder;
973 ControlList *Project::createOrRetrieveControlList(QString name, QString path) {
987 connect( result, SIGNAL( destroyed(
QObject *) ),
990 m_controls->append(result);
1006 int prefixCounter = 0;
1008 QString numberedPrefix;
1011 numberedPrefix = prefix.arg( QString::number(prefixCounter) );
1013 while ( imageFolder.exists(numberedPrefix) );
1015 if ( !imageFolder.mkpath(numberedPrefix) ) {
1017 tr(
"Could not create image directory [%1] in [%2].")
1018 .arg(numberedPrefix).arg( imageFolder.absolutePath() ),
1022 imageFolder.cd(numberedPrefix);
1034 m_imageReadingMutex->lock();
1038 m_imageReader->read(imageFiles);
1063 int prefixCounter = 0;
1065 QString numberedPrefix;
1068 numberedPrefix = prefix.arg( QString::number(prefixCounter) );
1070 while ( shapeFolder.exists(numberedPrefix) );
1072 if ( !shapeFolder.mkpath(numberedPrefix) ) {
1074 tr(
"Could not create shape directory [%1] in [%2].")
1075 .arg(numberedPrefix).arg( shapeFolder.absolutePath() ),
1079 shapeFolder.cd(numberedPrefix);
1090 if (m_numShapesCurrentlyReading == 0) {
1091 m_shapeReadingMutex->lock();
1094 m_numShapesCurrentlyReading += shapeFiles.count();
1095 m_shapeReader->read(shapeFiles);
1104 shapesReady(newShapes);
1114 foreach (
Template *templateFile, *templateList) {
1116 templateFile, SLOT( updateFileName(
Project *) ) );
1118 if (templateList->
type() ==
"maps") {
1119 m_mapTemplates->append(templateList);
1121 else if (templateList->
type() ==
"registrations") {
1122 m_regTemplates->append(templateList);
1125 emit templatesAdded(templateList);
1137 int prefixCounter = 0;
1138 QString numberedPrefix;
1142 numberedPrefix = prefix.arg( QString::number(prefixCounter) );
1144 while ( templateFolder.exists(numberedPrefix) );
1146 if ( !templateFolder.mkpath(numberedPrefix) ) {
1148 tr(
"Could not create template directory [%1] in [%2].")
1149 .arg(numberedPrefix).arg( templateFolder.absolutePath() ),
1153 templateFolder.cd(numberedPrefix);
1155 return templateFolder;
1177 if (!bundleSolutionInfoFolder.mkpath(folder)) {
1179 tr(
"Could not create bundle results directory [%1] in [%2].")
1180 .arg(folder).arg(bundleSolutionInfoFolder.absolutePath()),
1184 bundleSolutionInfoFolder.cd(folder);
1185 return bundleSolutionInfoFolder;
1234 void Project::writeSettings() {
1236 QString appName = QApplication::applicationName();
1239 QSettings globalSettings(
1240 FileName(
"$HOME/.Isis/" + appName +
"/" + appName +
"_" +
"Project.config")
1242 QSettings::NativeFormat);
1244 globalSettings.beginGroup(
"recent_projects");
1248 foreach (QString key,keys) {
1250 recentProjects[key]=globalSettings.value(key).toString();
1256 if (keys.count() >= m_maxRecentProjects) {
1259 globalSettings.remove(
"");
1265 if (!this->
projectRoot().contains(
"tmpProject") && !projectPaths.contains(this->projectRoot()) ) {
1266 QString s=keys.first();
1267 recentProjects.remove( s );
1273 if (projectPaths.contains(this->projectRoot())) {
1274 QString key = recentProjects.key(this->
projectRoot());
1275 recentProjects.remove(key);
1281 for (i=recentProjects.begin();i!=recentProjects.end();i++) {
1283 globalSettings.setValue(i.key(),i.value());
1288 long t0 = QDateTime::currentMSecsSinceEpoch();
1289 QString projName = this->
name();
1291 QString t0String=QString::number(t0);
1294 if (!this->
projectRoot().contains(
"tmpProject") ) {
1295 globalSettings.setValue(t0String+
"%%%%%"+projName,this->
projectRoot());
1305 globalSettings.remove(
"");
1306 if (projectPaths.contains(this->projectRoot())) {
1307 QString key = recentProjects.key(this->
projectRoot());
1308 recentProjects.remove(key);
1313 for ( i=recentProjects.begin(); i!=recentProjects.end(); i++ ) {
1314 globalSettings.setValue(i.key(),i.value());
1317 long t0 = QDateTime::currentMSecsSinceEpoch();
1318 QString projName = this->
name();
1319 QString t0String=QString::number(t0);
1322 if (!this->
projectRoot().contains(
"tmpProject") ) {
1323 globalSettings.setValue(t0String+
"%%%%%"+projName,this->
projectRoot());
1329 globalSettings.endGroup();
1347 QString projectAbsolutePathStr = QDir(projectPathStr).absolutePath();
1349 QString projectXmlPath = projectAbsolutePathStr +
"/project.xml";
1350 QFile file(projectXmlPath);
1352 if ( !file.open(QFile::ReadOnly) ) {
1354 QString(
"Unable to open [%1] with read access")
1355 .arg(projectXmlPath),
1359 QString projectXmlHistoryPath = projectAbsolutePathStr +
"/history.xml";
1360 QFile historyFile(projectXmlHistoryPath);
1362 if ( !historyFile.open(QFile::ReadOnly) ) {
1364 QString(
"Unable to open [%1] with read access")
1365 .arg(projectXmlHistoryPath),
1369 QString projectXmlWarningsPath = projectAbsolutePathStr +
"/warnings.xml";
1370 QFile warningsFile(projectXmlWarningsPath);
1372 if (!warningsFile.open(QFile::ReadOnly)) {
1374 QString(
"Unable to open [%1] with read access")
1375 .arg(projectXmlWarningsPath),
1379 QString directoryXmlPath = projectAbsolutePathStr +
"/directory.xml";
1380 QFile directoryFile(directoryXmlPath);
1382 if (!directoryFile.open(QFile::ReadOnly)) {
1384 QString(
"Unable to open [%1] with read access")
1385 .arg(directoryXmlPath),
1393 m_isTemporaryProject =
false;
1399 reader.setErrorHandler(&handler);
1401 QDir oldProjectRoot(*m_projectRoot);
1402 *m_projectRoot = QDir(projectAbsolutePathStr);
1404 QXmlInputSource xmlInputSource(&file);
1410 reader.parse(xmlInputSource);
1414 .arg(projectAbsolutePathStr));
1417 catch (std::exception &e) {
1419 .arg(projectAbsolutePathStr));
1424 QXmlInputSource xmlHistoryInputSource(&historyFile);
1427 reader.parse(xmlHistoryInputSource);
1432 .arg(projectAbsolutePathStr));
1435 catch (std::exception &e) {
1437 .arg(projectAbsolutePathStr));
1443 QXmlInputSource xmlWarningsInputSource(&warningsFile);
1445 if (!reader.parse(xmlWarningsInputSource)) {
1446 warn(tr(
"Failed to read warnings from project [%1]").arg(projectAbsolutePathStr));
1451 QXmlInputSource xmlDirectoryInputSource(&directoryFile);
1454 reader.parse(xmlDirectoryInputSource);
1458 .arg(projectAbsolutePathStr));
1462 catch (std::exception &e) {
1464 .arg(projectAbsolutePathStr));
1469 if (bundleRoot.exists()) {
1471 bundleRoot.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
1473 QFileInfoList bundleDirs = bundleRoot.entryInfoList();
1475 for (
int dirListIndex = 0; dirListIndex < bundleDirs.size(); dirListIndex++) {
1478 QDir bundleSolutionDir(bundleDirs[dirListIndex].absoluteFilePath());
1479 bundleSolutionDir.setFilter(QDir::Files | QDir::NoSymLinks);
1500 return m_imageReader->progress();
1511 return (*m_idToImageMap)[id];
1521 QListIterator<ImageList *> it(*m_images);
1524 while (it.hasNext() && !result) {
1527 if (list->
name() ==
name) result = list;
1540 return (*m_idToShapeMap)[id];
1550 QListIterator<ShapeList *> it(*m_shapes);
1553 while (it.hasNext() && !result) {
1556 if (list->
name() ==
name) result = list;
1568 return m_isTemporaryProject;
1597 m_undoStack.cleanChanged(value);
1607 QListIterator< QPointer<WorkOrder> > it(*m_workOrderHistory);
1610 while ( !result && it.hasPrevious() ) {
1636 QListIterator< QPointer<WorkOrder> > it(*m_workOrderHistory);
1639 while ( !result && it.hasPrevious() ) {
1667 return m_projectRoot->path();
1676 return m_newProjectRoot;
1695 return &m_undoStack;
1699 QString Project::nextImageListGroupName() {
1700 int numLists = m_images->size();
1701 QString maxName =
"";
1702 QString newGroupName =
"Group";
1706 if ( !
name.contains(
"Group") )
continue;
1707 if ( maxName.isEmpty() ) {
1710 else if (
name > maxName) {
1715 if ( maxName.isEmpty() ) {
1716 newGroupName += QString::number(numLists+1);
1719 int maxNum = maxName.remove(
"Group").toInt();
1722 newGroupName += QString::number(maxNum);
1724 return newGroupName;
1733 QMutexLocker locker(m_imageReadingMutex);
1741 QMutexLocker locker(m_shapeReadingMutex);
1750 foreach (
WorkOrder *workOrder, *m_workOrderHistory) {
1751 result.append(workOrder);
1768 if (m_activeControl && m_activeImageList) {
1820 Control *previousControl = m_activeControl;
1821 if (m_activeControl) {
1825 if (m_activeControl->isModified()) {
1827 msgBox.setText(
"Save current active control");
1828 msgBox.setInformativeText(
"The current active control has been modified. Do you want "
1829 "to save before setting a new active control?");
1830 msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
1831 msgBox.setDefaultButton(QMessageBox::Save);
1832 int ret = msgBox.exec();
1835 case QMessageBox::Save:
1836 m_activeControl->write();
1839 case QMessageBox::Discard:
1841 m_activeControl->closeControlNet();
1842 m_activeControl->openControlNet();
1843 emit discardActiveControlEdits();
1846 case QMessageBox::Cancel:
1852 displayProperties()->displayName(), Qt::DisplayRole);
1853 item->setTextColor(Qt::black);
1855 if (!
directory()->controlUsedInCnetEditorWidget(m_activeControl)) {
1856 m_activeControl->closeControlNet();
1862 m_activeControl = item->
control();
1865 m_activeControl->controlNet()->SetImages(*(
activeImageList()->serialNumberList()));
1866 item->setTextColor(Qt::darkGreen);
1869 if (previousControl) {
1870 m_activeControl = previousControl;
1872 displayProperties()->displayName(), Qt::DisplayRole);
1873 item->setTextColor(Qt::darkGreen);
1874 m_activeControl->controlNet()->SetImages(*(
activeImageList()->serialNumberList()));
1877 m_activeControl = NULL;
1905 if (!m_activeControl && (m_controls->count() == 1 && m_controls->at(0)->count() ==1)) {
1908 QString controlName = m_controls->at(0)->at(0)->displayProperties()->displayName();
1913 return m_activeControl;
1925 if (m_activeControl && m_activeControl->isModified()) {
1956 ImageList *previousImageList = m_activeImageList;
1957 if (m_activeImageList) {
1959 name(), Qt::DisplayRole);
1960 item->setTextColor(Qt::black);
1966 if (m_activeControl) {
1971 if (previousImageList) {
1972 m_activeImageList = previousImageList;
1974 name(), Qt::DisplayRole);
1975 item->setTextColor(Qt::darkGreen);
1979 m_activeImageList = NULL;
1984 item->setTextColor(Qt::darkGreen);
2005 if (!m_activeImageList && m_images->count() == 1) {
2006 QString
imageList = m_images->at(0)->name();
2010 return m_activeImageList;
2030 return cnetRoot( m_projectRoot->path() );
2049 QListIterator< ControlList * > it(*m_controls);
2052 while (it.hasNext() && !result) {
2055 if (list->
name() ==
name) result = list;
2147 return allTemplates;
2157 return *m_mapTemplates;
2167 return *m_regTemplates;
2224 return *m_bundleSolutionInfo;
2258 foreach (
ImageList *imagesInAFolder, *m_images) {
2263 warn( tr(
"Did not properly clean up images folder [%1] in project").arg(
imageDataRoot() ) );
2266 foreach (
ShapeList *shapesInAFolder, *m_shapes) {
2271 warn( tr(
"Did not properly clean up shapes folder [%1] in project").
2275 foreach (
ControlList *controlsInAFolder, *m_controls) {
2279 if ( !m_projectRoot->rmdir(
cnetRoot() ) ) {
2280 warn( tr(
"Did not properly clean up control network folder [%1] in project")
2284 if ( !(QDir(
resultsRoot()).removeRecursively()) ) {
2285 warn( tr(
"Did not properly clean up results folder [%1] in project")
2290 warn( tr(
"Did not properly clean up templates folder [%1] in project")
2294 if ( !m_projectRoot->rmpath( m_projectRoot->path() ) ) {
2295 warn( tr(
"Did not properly clean up project in [%1]").arg( m_projectRoot->path() ) );
2326 bool saveDialogCompleted =
true;
2328 if (m_isTemporaryProject) {
2329 QString newDestination = QFileDialog::getSaveFileName(NULL,
2330 QString(
"Project Location"),
2333 if ( !newDestination.isEmpty() ) {
2334 m_isTemporaryProject =
false;
2335 save( QFileInfo(newDestination +
"/").absolutePath() );
2345 open(newDestination);
2349 saveDialogCompleted =
false;
2363 save(m_projectRoot->absolutePath(),
false);
2367 return saveDialogCompleted;
2473 if ( verifyPathDoesntExist && QFile::exists( newPath.
toString() ) ) {
2475 QString(
"Projects may not be saved to an existing path [%1]; "
2476 "please select a new path or delete the current folder")
2482 if (!dir.mkpath(newPath.
toString())) {
2484 QString(
"Unable to save project at [%1] "
2485 "because we could not create the folder")
2494 m_newProjectRoot = newPath.
toString();
2499 m_name = newPath.
name();
2501 QFile projectSettingsFile(newPath.
toString() +
"/project.xml");
2502 if (!projectSettingsFile.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
2504 QString(
"Unable to save project at [%1] because the file [%2] "
2505 "could not be opened for writing")
2506 .arg(newPath.
original()).arg(projectSettingsFile.fileName()),
2510 QXmlStreamWriter writer(&projectSettingsFile);
2511 writer.setAutoFormatting(
true);
2513 writer.writeStartDocument();
2516 save(writer, newPath);
2518 writer.writeEndDocument();
2520 QFile projectHistoryFile(newPath.
toString() +
"/history.xml");
2521 if (!projectHistoryFile.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
2523 QString(
"Unable to save project at [%1] because the file [%2] "
2524 "could not be opened for writing")
2525 .arg(newPath.
original()).arg(projectHistoryFile.fileName()),
2529 QXmlStreamWriter historyWriter(&projectHistoryFile);
2530 historyWriter.setAutoFormatting(
true);
2532 historyWriter.writeStartDocument();
2534 historyWriter.writeEndDocument();
2536 QFile projectWarningsFile(newPath.
toString() +
"/warnings.xml");
2537 if (!projectWarningsFile.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
2539 QString(
"Unable to save project at [%1] because the file [%2] could not be "
2540 "opened for writing")
2541 .arg(newPath.
original()).arg(projectWarningsFile.fileName()),
2545 QXmlStreamWriter warningsWriter(&projectWarningsFile);
2546 warningsWriter.setAutoFormatting(
true);
2548 warningsWriter.writeStartDocument();
2550 warningsWriter.writeEndDocument();
2553 QFile directoryStateFile(newPath.
toString() +
"/directory.xml");
2554 if (!directoryStateFile.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
2556 QString(
"Unable to save project at [%1] because the file [%2] could not be "
2557 "opened for writing")
2558 .arg(newPath.
original()).arg(directoryStateFile.fileName()),
2562 QXmlStreamWriter directoryStateWriter(&directoryStateFile);
2563 directoryStateWriter.setAutoFormatting(
true);
2565 directoryStateWriter.writeStartDocument();
2572 m_directory->save(directoryStateWriter, newPath);
2574 directoryStateWriter.writeEndDocument();
2600 connect(workOrder, SIGNAL(finished(
WorkOrder *)),
2608 m_workOrderHistory->append(workOrder);
2617 m_undoStack.setClean();
2624 m_undoStack.push(workOrder);
2633 m_workOrderHistory->removeAll(NULL);
2643 template<
typename Data>
void Project::warn(QString text, Data relevantData) {
2644 storeWarning(text, relevantData);
2649 void Project::warn(QString text) {
2650 foreach (QString line, text.split(
"\n")) {
2657 void Project::storeWarning(QString text) {
2658 m_warnings->append(text);
2677 if (
images.name() !=
"") {
2689 QMutexLocker lock(m_mutex);
2693 foreach (openImage,
images) {
2704 m_imageReadingMutex->unlock();
2717 if (QString::compare(targetBody->targetName(),
id, Qt::CaseInsensitive) == 0) {
2734 m_targets->
append(targetBody);
2748 if (QString::compare(camera->instrumentId(),
id, Qt::CaseInsensitive) == 0) {
2765 m_guiCameras->
append(guiCamera);
2786 void Project::removeImages(
ImageList &imageList) {
2792 m_images->removeOne(list);
2803 QMutableListIterator<ImageList *> it(*m_images);
2804 while (it.hasNext()) {
2807 int foundElement = list->indexOf((
Image *)imageObj);
2809 if (foundElement != -1) {
2814 m_idToImageMap->remove(m_idToImageMap->key((
Image *)imageObj));
2823 int indexToRemove = m_images->indexOf(
static_cast<ImageList *
>(imageListObj));
2824 if (indexToRemove != -1) {
2825 m_images->removeAt(indexToRemove);
2842 int indexToRemove = m_controls->indexOf(
static_cast<ControlList *
>(controlListObj));
2843 if (indexToRemove != -1) {
2844 m_controls->removeAt(indexToRemove);
2857 int indexToRemove = m_shapes->indexOf(
static_cast<ShapeList *
>(shapeListObj));
2858 if (indexToRemove != -1) {
2859 m_shapes->removeAt(indexToRemove);
2868 QMutableListIterator<BundleSolutionInfo *> it(*m_bundleSolutionInfo);
2869 while (it.hasNext()) {
2875 int foundElement = m_bundleSolutionInfo->indexOf(
2878 if (foundElement != -1) {
2879 m_bundleSolutionInfo->removeAt(foundElement);
2883 m_idToBundleSolutionInfoMap->remove(
2913 void Project::shapesReady(
ShapeList shapes) {
2915 m_numShapesCurrentlyReading -=
shapes.count();
2924 if (
shapes.name() !=
"") {
2937 QMutexLocker lock(m_shapeMutex);
2941 foreach (openShape,
shapes) {
2945 if (m_numShapesCurrentlyReading == 0) {
2946 m_shapeReadingMutex->unlock();
2955 QMutableListIterator<ShapeList *> it(*m_shapes);
2956 while (it.hasNext()) {
2959 int foundElement = list->indexOf((
Shape *)imageObj);
2961 if (foundElement != -1) {
2966 m_idToShapeMap->remove(m_idToShapeMap->key((
Shape *)imageObj));
2970 Project::XmlHandler::XmlHandler(
Project *project) {
2971 m_project = project;
2987 return m_workOrderMutex;
2991 bool Project::XmlHandler::startElement(
const QString &namespaceURI,
const QString &localName,
2992 const QString &qName,
const QXmlAttributes &atts) {
2993 if (XmlStackedHandler::startElement(namespaceURI, localName, qName, atts)) {
2995 if (localName ==
"project") {
2996 QString
name = atts.value(
"name");
2997 if (!
name.isEmpty()) {
2998 m_project->setName(
name);
3001 else if (localName ==
"controlNets") {
3002 m_controls.append(
new ControlList(m_project, reader()));
3004 else if (localName ==
"imageList") {
3005 m_imageLists.append(
new ImageList(m_project, reader()));
3007 else if (localName ==
"shapeList") {
3008 m_shapeLists.append(
new ShapeList(m_project, reader()));
3010 else if (localName ==
"mapTemplateList") {
3011 m_mapTemplateLists.append(
new TemplateList(m_project, reader()));
3013 else if (localName ==
"regTemplateList") {
3014 m_regTemplateLists.append(
new TemplateList(m_project, reader()));
3017 else if (localName ==
"workOrder") {
3018 QString type = atts.value(
"type");
3021 ASSERT(m_workOrder->metaObject()->className() == type);
3023 m_workOrder->read(reader());
3026 else if (localName ==
"warning") {
3027 QString warningText = atts.value(
"text");
3029 if (!warningText.isEmpty()) {
3030 m_project->warn(warningText);
3033 else if (localName ==
"directory") {
3034 m_project->directory()->load(reader());
3036 else if (localName ==
"dockRestore") {
3043 else if (localName ==
"bundleSolutionInfo") {
3046 else if (localName ==
"activeImageList") {
3047 QString displayName = atts.value(
"displayName");
3048 m_project->setActiveImageList(displayName);
3050 else if (localName ==
"activeControl") {
3052 QString displayName = atts.value(
"displayName");
3053 m_project->setActiveControl(displayName);
3073 const QString &qName) {
3074 if (localName ==
"imageLists") {
3079 else if (localName ==
"shapeLists") {
3085 else if (localName ==
"mapTemplateLists") {
3086 foreach (
TemplateList *templateList, m_mapTemplateLists) {
3087 m_project->addTemplates(templateList);
3090 else if (localName ==
"regTemplateLists") {
3091 foreach (
TemplateList *templateList, m_regTemplateLists) {
3092 m_project->addTemplates(templateList);
3095 else if (localName ==
"workOrder") {
3096 m_project->m_workOrderHistory->append(m_workOrder);
3099 else if (localName ==
"controlNets") {
3102 m_project->addControl(
control);
3108 else if (localName ==
"results") {
3110 m_project->addBundleSolutionInfo(bundleInfo);
3115 m_project->addImagesToIdMap(*adjustedImageList);
3120 return XmlStackedHandler::endElement(namespaceURI, localName, qName);