Isis 3 Programmer Reference
Project.cpp
Go to the documentation of this file.
1
23#include "Project.h"
24
25#include <unistd.h>
26
27#include <QApplication>
28#include <QDateTime>
29#include <QDir>
30#include <QDebug>
31#include <QFile>
32#include <QFileDialog>
33#include <QFuture>
34#include <QFutureWatcher>
35#include <QMessageBox>
36#include <QMutex>
37#include <QMutexLocker>
38#include <QProgressBar>
39#include <QRegExp>
40#include <QSettings>
41#include <QStringList>
42#include <QtDebug>
43#include <QTextStream>
44#include <QWidget>
45#include <QXmlStreamWriter>
46#include <QXmlStreamReader>
47
48#include "BundleSettings.h"
49#include "BundleSolutionInfo.h"
50#include "Camera.h"
51#include "Control.h"
52#include "ControlList.h"
53#include "ControlNet.h"
54#include "CorrelationMatrix.h"
55#include "Cube.h"
56#include "Directory.h"
57#include "Environment.h"
58#include "FileName.h"
59#include "GuiCamera.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"
70#include "Shape.h"
71#include "ShapeList.h"
72#include "ShapeReader.h"
73#include "Target.h"
74#include "TargetBodyList.h"
75#include "Template.h"
76#include "TemplateList.h"
77#include "WorkOrder.h"
78#include "WorkOrderFactory.h"
79
80namespace Isis {
81
85 Project::Project(Directory &directory, QObject *parent) :
86 QObject(parent) {
87 m_bundleSettings = NULL;
88 m_clearing = false;
89 m_directory = &directory;
90 m_projectRoot = NULL;
91 m_cnetRoot = NULL;
92 m_idToControlMap = NULL;
93 m_idToImageMap = NULL;
94 m_idToShapeMap = NULL;
95 m_idToTargetBodyMap = NULL;
96 m_idToGuiCameraMap = NULL;
97 m_images = NULL;
98 m_imageReader = NULL;
99 m_shapeReader = NULL;
100 m_shapes = NULL;
101 m_mapTemplates = NULL;
102 m_regTemplates = NULL;
103 m_warnings = NULL;
104 m_workOrderHistory = NULL;
105 m_isTemporaryProject = true;
106 m_isOpen = false;
107 m_isClean = true;
108 m_activeControl = NULL;
109 m_activeImageList = NULL;
110
112
113 m_mutex = NULL;
114 m_workOrderMutex = NULL;
115 m_imageReadingMutex = NULL;
116
117 m_numShapesCurrentlyReading = 0;
118 m_shapeMutex = NULL;
119 m_shapeReadingMutex = NULL;
120
121 m_idToControlMap = new QMap<QString, Control *>;
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 *>;
127
128 m_name = "Project";
129
130 // Look for old projects
131 QDir tempDir = QDir::temp();
132 QStringList nameFilters;
133 nameFilters.append(Environment::userName() + "_" +
134 QApplication::applicationName() + "_*");
135 tempDir.setNameFilters(nameFilters);
136
137 QStringList existingProjects = tempDir.entryList();
138 bool crashedPreviously = false;
139
140 foreach (QString existingProject, existingProjects) {
141 FileName existingProjectFileName(tempDir.absolutePath() + "/" + existingProject);
142 QString pidString = QString(existingProject).replace(QRegExp(".*_"), "");
143 int otherPid = pidString.toInt();
144
145 if (otherPid != 0) {
146 if ( !QFile::exists("/proc/" + pidString) ) {
147 crashedPreviously = true;
148 int status = system( ("rm -rf '" +
149 existingProjectFileName.expanded() + "' &").toLatin1().data() );
150 if (status != 0) {
151 QString msg = "Executing command [rm -rf" + existingProjectFileName.expanded() +
152 "' &] failed with return status [" + toString(status) + "]";
153 throw IException(IException::Programmer, msg, _FILEINFO_);
154 }
155 }
156 }
157 }
158
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() ) );
164 }
165
166 QCoreApplication* ipce_app = static_cast<QCoreApplication *>(directory.parent());
167
168 try {
169 QString tmpFolder = QDir::temp().absolutePath() + "/"
170 + Environment::userName() + "_"
171 + QApplication::applicationName() + "_" + QString::number( getpid() );
172 QDir temp(tmpFolder + "/tmpProject");
173 m_projectRoot = new QDir(temp);
174
175 if (ipce_app->arguments().count() == 1) {
177 }
178 }
179 catch (IException &e) {
180 throw IException(e, IException::Programmer, "Error creating project folders.", _FILEINFO_);
181 }
182 catch (std::exception &e) {
183 // e.what()
185 tr("Error creating project folders [%1]").arg( e.what() ), _FILEINFO_);
186 }
187 // TODO TLS 2016-07-13 This seems to only be used by ControlNet when SetTarget is called.
188 // This needs to be better documented, possibly renamed or redesigned??
189 m_mutex = new QMutex;
190 m_workOrderMutex = new QMutex;
191 // image reader
192 m_imageReader = new ImageReader(m_mutex, true);
193
194 connect( m_imageReader, SIGNAL( imagesReady(ImageList) ),
195 this, SLOT( imagesReady(ImageList) ) );
196
197 // Project will be listening for when both cnets and images have been added.
198 // It will emit a signal, controlsAndImagesAvailable, when this occurs.
199 // Directory sets up a listener on the JigsawWorkOrder clone to enable itself
200 // when it hears this signal.
201 connect(this, SIGNAL(imagesAdded(ImageList *)),
202 this, SLOT(checkControlsAndImagesAvailable()));
203 connect(this, SIGNAL(controlListAdded(ControlList *)),
204 this, SLOT(checkControlsAndImagesAvailable()));
205 connect(m_directory, SIGNAL(cleanProject(bool)),
206 this, SLOT(setClean(bool)));
207
208 m_images = new QList<ImageList *>;
209
210 // Shape reader
211 m_shapeMutex = new QMutex;
212
213 m_shapeReader = new ShapeReader(m_shapeMutex, false);
214
215 connect( m_shapeReader, SIGNAL( shapesReady(ShapeList) ),
216 this, SLOT( shapesReady(ShapeList) ) );
217
218 m_shapes = new QList<ShapeList *>;
219
220 m_controls = new QList<ControlList *>;
221
222 m_targets = new TargetBodyList;
223
224 m_mapTemplates = new QList<TemplateList *>;
225
226 m_regTemplates = new QList<TemplateList *>;
227
228 m_guiCameras = new GuiCameraList;
229
230 m_bundleSolutionInfo = new QList<BundleSolutionInfo *>;
231
232 m_warnings = new QStringList;
233 m_workOrderHistory = new QList< QPointer<WorkOrder> >;
234
235 m_imageReadingMutex = new QMutex;
236
237 m_shapeReadingMutex = new QMutex;
238
239 // Listen for when an active control is set and when an active image list is set.
240 // This is used for enabling the JigsawWorkOrder (the Bundle Adjustment menu action).
241// connect(this, &Project::activeControlSet,
242// this, &Project::checkActiveControlAndImageList);
243// connect(this, &Project::activeImageListSet,
244// this, &Project::checkActiveControlAndImageList);
245 // TODO: ken testing
246// m_bundleSettings = NULL;
247// m_bundleSettings = new BundleSettings();
248 }
249
250
255
256
257 if (m_images) {
258 foreach (ImageList *imageList, *m_images) {
259 foreach (Image *image, *imageList) {
260 delete image;
261 }
262
263 delete imageList;
264 }
265
266 delete m_images;
267 m_images = NULL;
268 }
269
270
271 if (m_shapes) {
272 foreach (ShapeList *shapeList, *m_shapes) {
273 foreach (Shape *shape, *shapeList) {
274 delete shape;
275 }
276
277 delete shapeList;
278 }
279
280 delete m_shapes;
281 m_shapes = NULL;
282 }
283
284
285 if (m_controls) {
286 foreach (ControlList *controlList, *m_controls) {
287 foreach (Control *control, *controlList) {
288 delete control;
289 }
290
291 delete controlList;
292 }
293 delete m_controls;
294 m_controls = NULL;
295 }
296
297
298 if (m_mapTemplates) {
299 foreach (TemplateList *templateList, *m_mapTemplates) {
300 foreach (Template *templateFile, *templateList) {
301 delete templateFile;
302 }
303
304 delete templateList;
305 }
306
307 delete m_mapTemplates;
308 m_mapTemplates = NULL;
309 }
310
311
312 if (m_regTemplates) {
313 foreach (TemplateList *templateList, *m_regTemplates) {
314 foreach (Template *templateFile, *templateList) {
315 delete templateFile;
316 }
317
318 delete templateList;
319 }
320
321 delete m_regTemplates;
322 m_regTemplates = NULL;
323 }
324
325
326 m_activeControl = NULL;
327 m_activeImageList = NULL;
328
329 if (m_bundleSolutionInfo) {
330 foreach (BundleSolutionInfo *bundleSolutionInfo, *m_bundleSolutionInfo) {
331 delete bundleSolutionInfo;
332 }
333
334 delete m_bundleSolutionInfo;
335 m_bundleSolutionInfo = NULL;
336 }
337
338 delete m_idToControlMap;
339 m_idToControlMap = NULL;
340
341 delete m_idToImageMap;
342 m_idToImageMap = NULL;
343
344 delete m_idToShapeMap;
345 m_idToShapeMap = NULL;
346
347 delete m_idToTargetBodyMap;
348 m_idToTargetBodyMap = NULL;
349
350 delete m_idToGuiCameraMap;
351 m_idToGuiCameraMap = NULL;
352
353 delete m_idToBundleSolutionInfoMap;
354 m_idToBundleSolutionInfoMap = NULL;
355
356 m_directory = NULL;
357
358 delete m_projectRoot;
359 m_projectRoot = NULL;
360
361 delete m_cnetRoot;
362 m_cnetRoot = NULL;
363
364 delete m_imageReader;
365 delete m_shapeReader;
366
367 delete m_warnings;
368 m_warnings = NULL;
369
370 m_workOrderHistory->removeAll(NULL);
371 m_workOrderHistory = NULL;
372
373 delete m_bundleSettings;
374 m_bundleSettings = NULL;
375 }
376
377
382 QDir dir;
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() ),
388 _FILEINFO_);
389 }
390
391 try {
392 if ( !dir.mkdir( cnetRoot() ) ) {
393 QString msg = QString("Unable to create folder [%1] when trying to initialize project")
394 .arg( cnetRoot() );
395 warn(msg);
396 throw IException(IException::Io, msg, _FILEINFO_);
397 }
398
399 if ( !dir.mkdir( imageDataRoot() ) ) {
400 QString msg = QString("Unable to create folder [%1] when trying to initialize project")
401 .arg( imageDataRoot() );
402 warn(msg);
403 throw IException(IException::Io, msg, _FILEINFO_);
404 }
405
406 if ( !dir.mkdir( shapeDataRoot() ) ) {
407 QString msg = QString("Unable to create folder [%1] when trying to initialize project")
408 .arg( shapeDataRoot() );
409 warn(msg);
410 throw IException(IException::Io, msg, _FILEINFO_);
411 }
412
413 if ( !dir.mkdir( resultsRoot() ) ) {
414 QString msg = QString("Unable to create folder [%1] when trying to initialize project")
415 .arg( resultsRoot() );
416 warn(msg);
417 throw IException(IException::Io, msg, _FILEINFO_);
418 }
419 if ( !dir.mkdir( bundleSolutionInfoRoot() ) ) {
420 QString msg = QString("Unable to create folder [%1] when trying to initialize project")
421 .arg( bundleSolutionInfoRoot() );
422 warn(msg);
423 throw IException(IException::Io, msg, _FILEINFO_);
424 }
425 if ( !dir.mkdir( templateRoot() ) ) {
426 QString msg = QString("Unable to create folder [%1] when trying to initialize project")
427 .arg( templateRoot() );
428 warn(msg);
429 throw IException(IException::Io, msg, _FILEINFO_);
430 }
431 if ( !dir.mkdir( templateRoot() + "/maps" ) ) {
432 QString msg = QString("Unable to create folder [%1] when trying to initialize project")
433 .arg( templateRoot() + "/maps" );
434 warn(msg);
435 throw IException(IException::Io, msg, _FILEINFO_);
436 }
437 if ( !dir.mkdir( templateRoot() + "/registrations" ) ) {
438 QString msg = QString("Unable to create folder [%1] when trying to initialize project")
439 .arg( templateRoot() + "/registrations" );
440 warn(msg);
441 throw IException(IException::Io, msg, _FILEINFO_);
442 }
443 }
444 catch (...) {
445 warn("Failed to create project directory structure");
446 throw;
447 }
448 }
449
450
457 m_clearing = true;
458
459 // We need to look through the project.xml and remove every directory not in the project
460 QStringList shapeDirList;
461 bool shapes = false;
462 QStringList imageDirList;
463 bool images = false;
464 QStringList cnetDirList;
465 bool controls = false;
466 QStringList mapTemplateDirList;
467 bool mapTemplates = false;
468 QStringList regTemplateDirList;
469 bool regTemplates = false;
470 QStringList bundleDirList;
471 bool bundles = false;
472 QFile projectXml(projectRoot() + "/project.xml");
473
474 if (projectXml.open(QIODevice::ReadOnly)) {
475 QTextStream projectXmlInput(&projectXml);
476
477 while (!projectXmlInput.atEnd() ) {
478
479 QString line = projectXmlInput.readLine();
480
481 if (controls || line.contains("<controlNets>") ) {
482 controls = true;
483
484 if (line.contains("</controlNets>") ) {
485 controls = false;
486 }
487
488 else if (!line.contains("<controlNets>") ) {
489 cnetDirList.append(line.split('"').at(3));
490 }
491 }
492
493 else if (images || line.contains("<imageLists>") ) {
494 images = true;
495
496 if (line.contains("</imageLists>")) {
497 images = false;
498 }
499
500 else if (!line.contains("<imageLists>") ) {
501 imageDirList.append(line.split('"').at(3).simplified());
502 }
503 }
504
505 else if (shapes || line.contains("<shapeLists>")) {
506 shapes = true;
507
508 if (line.contains("</shapeLists>") ) {
509 shapes = false;
510 }
511
512 else if (!line.contains("<shapeLists>") ) {
513 shapeDirList.append(line.split('"').at(3));
514 }
515 }
516
517 else if (mapTemplates || line.contains("<mapTemplateLists>") ) {
518 mapTemplates = true;
519
520 if (line.contains("</mapTemplateLists>") ) {
521 mapTemplates = false;
522 }
523
524 else if (!line.contains("<mapTemplateLists>") ) {
525 QList<QString> components = line.split('"');
526 mapTemplateDirList.append(components.at(5));
527 }
528 }
529
530 else if (regTemplates || line.contains("<regTemplateLists>") ) {
531 regTemplates = true;
532
533 if (line.contains("</regTemplateLists>") ) {
534 regTemplates = false;
535 }
536
537 else if (!line.contains("<regTemplateLists>") ) {
538 QList<QString> components = line.split('"');
539 regTemplateDirList.append(components.at(5));
540 }
541 }
542
543 else if (bundles || line.contains("<bundleSolutionInfo>") ) {
544 bundles = true;
545
546 if (line.contains("</bundleSolutionInfo>") ) {
547 bundles = false;
548 }
549
550 else if (line.contains("<runTime>") ) {
551 bundleDirList.append(line.split('>').at(1).split('<').at(0));
552 }
553 }
554 }
555
556 QDir cnetsDir(m_projectRoot->path() + "/cnets/");
557 cnetsDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
558 QStringList cnetsList = cnetsDir.entryList();
559 foreach (QString dir, cnetsList) {
560 dir = dir.simplified();
561
562 if ( !cnetDirList.contains(dir) ) {
563 QDir tempDir(cnetsDir.path() + "/" + dir);
564 tempDir.removeRecursively();
565 }
566 }
567
568 QDir imagesDir(m_projectRoot->path() + "/images/");
569 imagesDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
570 QStringList imagesList = imagesDir.entryList();
571 foreach (QString dir, imagesList) {
572 dir = dir.simplified();
573
574 if ( !imageDirList.contains(dir) ) {
575 QDir tempDir(imagesDir.path() + "/" + dir);
576 tempDir.removeRecursively();
577 }
578 }
579
580 QDir shapesDir(m_projectRoot->path() + "/shapes/");
581 shapesDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
582 QStringList shapesList = shapesDir.entryList();
583 foreach (QString dir, shapesList) {
584 dir = dir.simplified();
585
586 if ( !shapeDirList.contains(dir) ) {
587 QDir tempDir(shapesDir.path() + "/" + dir);
588 tempDir.removeRecursively();
589 }
590 }
591
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();
597
598 if ( !mapTemplateDirList.contains("maps/" + dir) ) {
599 QDir tempDir(mapTemplatesDir.path() + "/" + dir);
600 tempDir.removeRecursively();
601 }
602 }
603
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();
609
610 if ( !regTemplateDirList.contains("registrations/" + dir)) {
611 QDir tempDir(regTemplatesDir.path() + "/" + dir);
612 tempDir.removeRecursively();
613 }
614 }
615
616 QDir bundlesDir(m_projectRoot->path() + "/results/bundle/");
617 bundlesDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
618 QStringList bundleList = bundlesDir.entryList();
619 foreach (QString dir, bundleList) {
620 dir = dir.simplified();
621
622 if ( !bundleDirList.contains(dir) ) {
623 QDir tempDir(bundlesDir.path() + "/" + dir);
624 tempDir.removeRecursively();
625 }
626 }
627
628 projectXml.close();
629 }
630
631 try {
632 QString tmpFolder = QDir::temp().absolutePath() + "/"
633 + Environment::userName() + "_"
634 + QApplication::applicationName() + "_" + QString::number( getpid() );
635 QDir temp(tmpFolder + "/tmpProject");
636 m_projectRoot = new QDir(temp);
637 }
638
639 catch (IException &e) {
640 throw IException(e, IException::Programmer, "Error creating project folders.", _FILEINFO_);
641 }
642
643 catch (std::exception &e) {
645 tr("Error creating project folders [%1]").arg( e.what() ), _FILEINFO_);
646 }
647
648 m_images->clear();
649 m_shapes->clear();
650 m_controls->clear();
651 m_mapTemplates->clear();
652 m_regTemplates->clear();
653 m_targets->clear();
654 m_guiCameras->clear();
655 m_bundleSolutionInfo->clear();
656 m_workOrderHistory->clear();
657
658 directory()->clean();
659 setClean(true);
660 }
661
662
663 bool Project::clearing() {
664 return m_clearing;
665 }
666
667
668 ImageList *Project::createOrRetrieveImageList(QString name, QString path) {
669 ImageList *result = imageList(name);
670 if (!result) {
671 result = new ImageList;
672
673 result->setName(name);
674 if (path == "") {
675 result->setPath(name);
676 }
677 else {
678 result->setPath(path);
679 }
680
681 connect( result, SIGNAL( destroyed(QObject *) ),
682 this, SLOT( imageListDeleted(QObject *) ) );
683 m_images->append(result);
684 }
685 return result;
686 }
687
688
689 ShapeList *Project::createOrRetrieveShapeList(QString name, QString path) {
690 ShapeList *result = shapeList(name);
691 if (!result) {
692 result = new ShapeList;
693
694 result->setName(name);
695 if (path == "") {
696 result->setPath(name);
697 }
698 else {
699 result->setPath(path);
700 }
701
702 connect( result, SIGNAL( destroyed(QObject *) ),
703 this, SLOT( shapeListDeleted(QObject *) ) );
704 m_shapes->append(result);
705 }
706 return result;
707 }
708
709
723 void Project::save(QXmlStreamWriter &stream, FileName newProjectRoot) const {
724 stream.writeStartElement("project");
725
726 stream.writeAttribute("name", m_name);
727
728 if ( !m_controls->isEmpty() ) {
729 stream.writeStartElement("controlNets");
730
731 for (int i = 0; i < m_controls->count(); i++) {
732 m_controls->at(i)->save(stream, this, newProjectRoot);
733 }
734
735 stream.writeEndElement();
736 }
737
738 if ( !m_images->isEmpty() ) {
739 stream.writeStartElement("imageLists");
740 for (int i = 0; i < m_images->count(); i++) {
741 m_images->at(i)->save(stream, this, newProjectRoot);
742 }
743
744 stream.writeEndElement();
745 }
746
747 if ( !m_shapes->isEmpty() ) {
748 stream.writeStartElement("shapeLists");
749
750 for (int i = 0; i < m_shapes->count(); i++) {
751 m_shapes->at(i)->save(stream, this, newProjectRoot);
752 }
753
754 stream.writeEndElement();
755 }
756
757 if ( !m_mapTemplates->isEmpty() ) {
758 stream.writeStartElement("mapTemplateLists");
759
760 for (int i = 0; i < m_mapTemplates->count(); i++) {
761 m_mapTemplates->at(i)->save(stream, this, newProjectRoot);
762 }
763
764 stream.writeEndElement();
765 }
766
767 if ( !m_regTemplates->isEmpty() ) {
768 stream.writeStartElement("regTemplateLists");
769
770 for (int i = 0; i < m_regTemplates->count(); i++) {
771 m_regTemplates->at(i)->save(stream, this, newProjectRoot);
772 }
773
774 stream.writeEndElement();
775 }
776
777 // TODO: Finish implementing serialization of TargetBody & GuiCameras
778// if (!m_targets->isEmpty()) {
779// stream.writeStartElement("targets");
780//
781// for (int i = 0; i < m_targets->count(); i++) {
782// m_targets->at(i)->save(stream, this, newProjectRoot);
783// }
784//
785// stream.writeEndElement();
786// }
787//
788// if (!m_guiCameras->isEmpty()) {
789// stream.writeStartElement("cameras");
790//
791// for (int i = 0; i < m_guiCameras->count(); i++) {
792// m_guiCameras->at(i)->save(stream, this, newProjectRoot);
793// }
794//
795// stream.writeEndElement();
796// }
797
798// Write general look of gui, including docked widges
799// QVariant geo_data = saveGeometry();
800// QVariant layout_data = saveState();
801//
802// stream.writeStartElement("dockRestore");
803// stream.writeAttribute("geometry", geo_data.toString());
804// stream.writeAttribute("state", layout_data.toString());
805
806
807 if ( !m_bundleSolutionInfo->isEmpty() ) {
808 stream.writeStartElement("results");
809
810 for (int i = 0; i < m_bundleSolutionInfo->count(); i++) {
811 m_bundleSolutionInfo->at(i)->save(stream, this, newProjectRoot);
812 }
813
814 stream.writeEndElement();
815 }
816
817 if (m_activeImageList) {
818 stream.writeStartElement("activeImageList");
819 stream.writeAttribute("displayName", m_activeImageList->name());
820 stream.writeEndElement();
821 }
822
823 if (m_activeControl) {
824 stream.writeStartElement("activeControl");
825 stream.writeAttribute("displayName", m_activeControl->displayProperties()->displayName());
826 stream.writeEndElement();
827 }
828
829 stream.writeEndElement();
830 }
831
832
848 void Project::saveHistory(QXmlStreamWriter &stream) const {
849 stream.writeStartElement("history");
850
851 foreach (WorkOrder *workOrder, *m_workOrderHistory) {
852 if (workOrder) {
853 workOrder->save(stream);
854 }
855 }
856
857 stream.writeEndElement();
858 }
859
871 void Project::saveWarnings(QXmlStreamWriter &stream) const {
872 stream.writeStartElement("warnings");
873
874 foreach (QString warning, *m_warnings) {
875 stream.writeStartElement("warning");
876 stream.writeAttribute("text", warning);
877 stream.writeEndElement();
878 }
879
880 stream.writeEndElement();
881 }
882
883
890 // TODO: thread via ImageReader
892
893 QStringList result;
894
895 foreach (QString fileName, fileNames) {
896 try {
897 Cube tmp(fileName);
898 result.append(fileName);
899 }
900 catch (IException &) {
901 }
902 }
903
904 return result;
905 }
906
907
914 return m_imageReader->actions(ImageDisplayProperties::FootprintViewProperties);
915 }
916
917
923 QDir Project::addCnetFolder(QString prefix) {
924 QDir cnetFolder = cnetRoot();
925 prefix += "%1";
926 int prefixCounter = 0;
927
928 QString numberedPrefix;
929 do {
930 prefixCounter++;
931 numberedPrefix = prefix.arg( QString::number(prefixCounter) );
932 }
933 while ( cnetFolder.exists(numberedPrefix) );
934
935 if ( !cnetFolder.mkpath(numberedPrefix) ) {
937 tr("Could not create control network directory [%1] in [%2].")
938 .arg(numberedPrefix).arg( cnetFolder.absolutePath() ),
939 _FILEINFO_);
940 }
941
942 cnetFolder.cd(numberedPrefix);
943
944 m_currentCnetFolder = cnetFolder;
945
946 return cnetFolder;
947 }
948
949
956
957 connect( control, SIGNAL( destroyed(QObject *) ),
958 this, SLOT( controlClosed(QObject *) ) );
959 connect( this, SIGNAL( projectRelocated(Project *) ),
960 control, SLOT( updateFileName(Project *) ) );
961
962 createOrRetrieveControlList( FileName( control->fileName() ).dir().dirName(), "" )->append(control);
963
964 (*m_idToControlMap)[control->id()] = control;
965
966 emit controlAdded(control);
967 }
968
969
970 ControlList *Project::createOrRetrieveControlList(QString name, QString path) {
971 ControlList *result = controlList(name);
972
973 if (!result) {
974 result = new ControlList;
975
976 result->setName(name);
977 if (path == "") {
978 result->setPath(name);
979 }
980 else {
981 result->setPath(path);
982 }
983
984 connect( result, SIGNAL( destroyed(QObject *) ),
985 this, SLOT( controlListDeleted(QObject *) ) );
986
987 m_controls->append(result);
988 emit controlListAdded(result);
989 }
990
991 return result;
992 }
993
994
1000 QDir Project::addImageFolder(QString prefix) {
1001 QDir imageFolder = imageDataRoot();
1002 prefix += "%1";
1003 int prefixCounter = 0;
1004
1005 QString numberedPrefix;
1006 do {
1007 prefixCounter++;
1008 numberedPrefix = prefix.arg( QString::number(prefixCounter) );
1009 }
1010 while ( imageFolder.exists(numberedPrefix) );
1011
1012 if ( !imageFolder.mkpath(numberedPrefix) ) {
1014 tr("Could not create image directory [%1] in [%2].")
1015 .arg(numberedPrefix).arg( imageFolder.absolutePath() ),
1016 _FILEINFO_);
1017 }
1018
1019 imageFolder.cd(numberedPrefix);
1020
1021 return imageFolder;
1022 }
1023
1024
1030 if (m_numImagesCurrentlyReading == 0) {
1031 m_imageReadingMutex->lock();
1032 }
1033
1034 m_numImagesCurrentlyReading += imageFiles.count();
1035 m_imageReader->read(imageFiles);
1036 }
1037
1038
1044 imagesReady(newImages);
1045
1046 // The each
1047 emit guiCamerasAdded(m_guiCameras);
1048 emit targetsAdded(m_targets);
1049 }
1050
1051
1057 QDir Project::addShapeFolder(QString prefix) {
1058 QDir shapeFolder = shapeDataRoot();
1059 prefix += "%1";
1060 int prefixCounter = 0;
1061
1062 QString numberedPrefix;
1063 do {
1064 prefixCounter++;
1065 numberedPrefix = prefix.arg( QString::number(prefixCounter) );
1066 }
1067 while ( shapeFolder.exists(numberedPrefix) );
1068
1069 if ( !shapeFolder.mkpath(numberedPrefix) ) {
1071 tr("Could not create shape directory [%1] in [%2].")
1072 .arg(numberedPrefix).arg( shapeFolder.absolutePath() ),
1073 _FILEINFO_);
1074 }
1075
1076 shapeFolder.cd(numberedPrefix);
1077
1078 return shapeFolder;
1079 }
1080
1081
1087 if (m_numShapesCurrentlyReading == 0) {
1088 m_shapeReadingMutex->lock();
1089 }
1090
1091 m_numShapesCurrentlyReading += shapeFiles.count();
1092 m_shapeReader->read(shapeFiles);
1093 }
1094
1095
1101 shapesReady(newShapes);
1102 }
1103
1104
1111 foreach (Template *templateFile, *templateList) {
1112 connect( this, SIGNAL( projectRelocated(Project *) ),
1113 templateFile, SLOT( updateFileName(Project *) ) );
1114 }
1115 if (templateList->type() == "maps") {
1116 m_mapTemplates->append(templateList);
1117 }
1118 else if (templateList->type() == "registrations") {
1119 m_regTemplates->append(templateList);
1120 }
1121
1122 emit templatesAdded(templateList);
1123 }
1124
1125
1131 QDir Project::addTemplateFolder(QString prefix) {
1132 QDir templateFolder = templateRoot();
1133 prefix += "%1";
1134 int prefixCounter = 0;
1135 QString numberedPrefix;
1136
1137 do {
1138 prefixCounter++;
1139 numberedPrefix = prefix.arg( QString::number(prefixCounter) );
1140 }
1141 while ( templateFolder.exists(numberedPrefix) );
1142
1143 if ( !templateFolder.mkpath(numberedPrefix) ) {
1145 tr("Could not create template directory [%1] in [%2].")
1146 .arg(numberedPrefix).arg( templateFolder.absolutePath() ),
1147 _FILEINFO_);
1148 }
1149
1150 templateFolder.cd(numberedPrefix);
1151
1152 return templateFolder;
1153 }
1154
1155
1161 return (*m_idToControlMap)[id];
1162 }
1163
1164
1172 QDir bundleSolutionInfoFolder(bundleSolutionInfoRoot());
1173
1174 if (!bundleSolutionInfoFolder.mkpath(folder)) {
1176 tr("Could not create bundle results directory [%1] in [%2].")
1177 .arg(folder).arg(bundleSolutionInfoFolder.absolutePath()),
1178 _FILEINFO_);
1179 }
1180
1181 bundleSolutionInfoFolder.cd(folder);
1182 return bundleSolutionInfoFolder;
1183 }
1184
1185
1192 connect(bundleSolutionInfo, SIGNAL(destroyed(QObject *)),
1193 this, SLOT(bundleSolutionInfoClosed(QObject *)));//???
1194 connect(this, SIGNAL(projectRelocated(Project *)),
1195 bundleSolutionInfo, SLOT(updateFileName(Project *)));//DNE???
1196
1197
1199 }
1200
1201
1208 m_bundleSolutionInfo->append(bundleSolutionInfo);
1209
1210 // add BundleSolutionInfo to project's m_idToBundleSolutionInfoMap
1211 (*m_idToBundleSolutionInfoMap)[bundleSolutionInfo->id()] = bundleSolutionInfo;
1212
1213 // add BundleSolutionInfo's control to project's m_idToControlMap
1214 (*m_idToControlMap)[bundleSolutionInfo->control()->id()] = bundleSolutionInfo->control();
1215
1217 }
1218
1219
1227 return m_directory;
1228 }
1229
1230
1231 void Project::writeSettings() {
1232
1233 QString appName = QApplication::applicationName();
1234
1235
1236 QSettings globalSettings(
1237 FileName("$HOME/.Isis/" + appName + "/" + appName + "_" + "Project.config")
1238 .expanded(),
1239 QSettings::NativeFormat);
1240
1241 globalSettings.beginGroup("recent_projects");
1242 QStringList keys = globalSettings.allKeys();
1243 QMap<QString,QString> recentProjects;
1244
1245 foreach (QString key,keys) {
1246
1247 recentProjects[key]=globalSettings.value(key).toString();
1248
1249 }
1250
1251 QList<QString> projectPaths = recentProjects.values();
1252
1253 if (keys.count() >= m_maxRecentProjects) {
1254
1255 //Clear out the recent projects before repopulating this group
1256 globalSettings.remove("");
1257
1258
1259
1260 //If the currently open project is a project that has been saved and is not within the current
1261 //list of recently open projects, then remove the oldest project from the list.
1262 if (!this->projectRoot().contains("tmpProject") && !projectPaths.contains(this->projectRoot()) ) {
1263 QString s=keys.first();
1264 recentProjects.remove( s );
1265 }
1266
1267 //If the currently open project is already contained within the list,
1268 //then remove the earlier reference.
1269
1270 if (projectPaths.contains(this->projectRoot())) {
1271 QString key = recentProjects.key(this->projectRoot());
1272 recentProjects.remove(key);
1273 }
1274
1276
1277 //Iterate through the recentProjects QMap and set the <key,val> pairs.
1278 for (i=recentProjects.begin();i!=recentProjects.end();i++) {
1279
1280 globalSettings.setValue(i.key(),i.value());
1281
1282 }
1283
1284 //Get a unique time value for generating a key
1285 long t0 = QDateTime::currentMSecsSinceEpoch();
1286 QString projName = this->name();
1287
1288 QString t0String=QString::number(t0);
1289
1290 //Save the project location
1291 if (!this->projectRoot().contains("tmpProject") ) {
1292 globalSettings.setValue(t0String+"%%%%%"+projName,this->projectRoot());
1293
1294 }
1295
1296 }
1297
1298 //The numer of recent open projects is less than m_maxRecentProjects
1299 else {
1300
1301 //Clear out the recent projects before repopulating this group
1302 globalSettings.remove("");
1303 if (projectPaths.contains(this->projectRoot())) {
1304 QString key = recentProjects.key(this->projectRoot());
1305 recentProjects.remove(key);
1306 }
1308
1309 //Iterate through the recentProjects QMap and set the <key,val> pairs.
1310 for ( i=recentProjects.begin(); i!=recentProjects.end(); i++ ) {
1311 globalSettings.setValue(i.key(),i.value());
1312 }
1313
1314 long t0 = QDateTime::currentMSecsSinceEpoch();
1315 QString projName = this->name();
1316 QString t0String=QString::number(t0);
1317
1318 //if (!this->projectRoot().contains("tmpProject") && !projectPaths.contains( this->projectRoot() ) ) {
1319 if (!this->projectRoot().contains("tmpProject") ) {
1320 globalSettings.setValue(t0String+"%%%%%"+projName,this->projectRoot());
1321 }
1322
1323 }
1324
1325
1326 globalSettings.endGroup();
1327 }
1328
1329
1342 void Project::open(QString projectPathStr) {
1343 // Expand projectPathStr to contain absolute path
1344 QString projectAbsolutePathStr = QDir(projectPathStr).absolutePath();
1345
1346 QString projectXmlPath = projectAbsolutePathStr + "/project.xml";
1347 QFile file(projectXmlPath);
1348
1349 if ( !file.open(QFile::ReadOnly) ) {
1351 QString("Unable to open [%1] with read access")
1352 .arg(projectXmlPath),
1353 _FILEINFO_);
1354 }
1355
1356 QString projectXmlHistoryPath = projectAbsolutePathStr + "/history.xml";
1357 QFile historyFile(projectXmlHistoryPath);
1358
1359 if ( !historyFile.open(QFile::ReadOnly) ) {
1361 QString("Unable to open [%1] with read access")
1362 .arg(projectXmlHistoryPath),
1363 _FILEINFO_);
1364 }
1365
1366 QString projectXmlWarningsPath = projectAbsolutePathStr + "/warnings.xml";
1367 QFile warningsFile(projectXmlWarningsPath);
1368
1369 if (!warningsFile.open(QFile::ReadOnly)) {
1371 QString("Unable to open [%1] with read access")
1372 .arg(projectXmlWarningsPath),
1373 _FILEINFO_);
1374 }
1375
1376 QString directoryXmlPath = projectAbsolutePathStr + "/directory.xml";
1377 QFile directoryFile(directoryXmlPath);
1378
1379 if (!directoryFile.open(QFile::ReadOnly)) {
1381 QString("Unable to open [%1] with read access")
1382 .arg(directoryXmlPath),
1383 _FILEINFO_);
1384 }
1385
1386 if (isOpen() || !isClean()) {
1387 clear();
1388 }
1389 m_clearing = false;
1390 m_isTemporaryProject = false;
1391
1392 QDir oldProjectRoot(*m_projectRoot);
1393 *m_projectRoot = QDir(projectAbsolutePathStr);
1394
1395 QXmlStreamReader projectXmlReader(&file);
1396
1397 //This prevents the project from not loading if everything
1398 //can't be loaded, and outputs the warnings/errors to the
1399 //Warnings Tab
1400 try {
1401 readProjectXml(&projectXmlReader);
1402 }
1403 catch (IException &e) {
1404 directory()->showWarning(QString("Failed to open project completely [%1]")
1405 .arg(projectAbsolutePathStr));
1406 directory()->showWarning(e.toString());
1407 }
1408 catch (std::exception &e) {
1409 directory()->showWarning(QString("Failed to open project completely[%1]")
1410 .arg(projectAbsolutePathStr));
1411 directory()->showWarning(e.what());
1412 }
1413
1414 QXmlStreamReader reader2(&historyFile);
1415
1416 try {
1417 while (!reader2.atEnd()) {
1418 reader2.readNext();
1419 }
1420 }
1421
1422 catch (IException &e) {
1423 directory()->showWarning(QString("Failed to read history from project[%1]")
1424 .arg(projectAbsolutePathStr));
1425 directory()->showWarning(e.toString());
1426 }
1427 catch (std::exception &e) {
1428 directory()->showWarning(QString("Failed to read history from project[%1]")
1429 .arg(projectAbsolutePathStr));
1430 directory()->showWarning(e.what());
1431 }
1432
1433 QXmlStreamReader reader3(&warningsFile);
1434
1435 while (!reader3.atEnd()) {
1436 reader3.readNext();
1437 }
1438 if (reader3.hasError()) {
1439 warn(tr("Failed to read warnings from project [%1]").arg(projectAbsolutePathStr));
1440 }
1441
1442 QXmlStreamReader reader4(&directoryFile);
1443
1444 try {
1445 while (!reader4.atEnd()) {
1446 reader4.readNext();
1447 }
1448 }
1449 catch (IException &e) {
1450 directory()->showWarning(QString("Failed to read GUI state from project[%1]")
1451 .arg(projectAbsolutePathStr));
1452 directory()->showWarning(e.toString());
1453
1454 }
1455 catch (std::exception &e) {
1456 directory()->showWarning(QString("Failed to read GUI state from project[%1]")
1457 .arg(projectAbsolutePathStr));
1458 directory()->showWarning(e.what());
1459 }
1460
1461 QDir bundleRoot(bundleSolutionInfoRoot());
1462 if (bundleRoot.exists()) {
1463 // get QFileInfo for each directory in the bundle root
1464 bundleRoot.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::NoSymLinks); // sym links ok???
1465
1466 QFileInfoList bundleDirs = bundleRoot.entryInfoList();
1467
1468 for (int dirListIndex = 0; dirListIndex < bundleDirs.size(); dirListIndex++) {
1469
1470 // get QFileInfo for each file in this directory
1471 QDir bundleSolutionDir(bundleDirs[dirListIndex].absoluteFilePath());
1472 bundleSolutionDir.setFilter(QDir::Files | QDir::NoSymLinks); // sym links ok???
1473
1474// QFileInfoList bundleSolutionFiles = bundleSolutionDir.entryInfoList();
1475// for (int fileListIndex = 0; fileListIndex < bundleSolutionFiles.size(); fileListIndex++) {
1476// // if the file is an hdf file with BundleSolutionInfo object, add it to the project tree
1477// if (bundleSolutionFiles[fileListIndex].fileName().contains("_BundleSolutionInfo.hdf")) {
1478// QString absoluteFileName = bundleSolutionFiles[fileListIndex].absoluteFilePath();
1479// FileName solutionFile(bundleSolutionFiles[fileListIndex].absoluteFilePath());
1480// loadBundleSolutionInfo(new BundleSolutionInfo(solutionFile));
1481// }
1482// }
1483 }
1484 }
1485 m_isOpen = true;
1486
1487 setClean(true);
1488 emit projectLoaded(this);
1489 }
1490
1491
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()) {
1497 m_project->setName(*(name.string()));
1498 }
1499 }
1500 else if (xmlReader->name() == "controlNets") {
1501 // m_controls.append(new ControlList(m_project, xmlReader));
1502 }
1503 else if (xmlReader->name() == "imageList") {
1504 // m_imageLists.append(new ImageList(m_project, xmlReader));
1505 }
1506 else if (xmlReader->name() == "shapeList") {
1507 // m_shapeLists.append(new ShapeList(m_project, xmlReader));
1508 }
1509 else if (xmlReader->name() == "mapTemplateList") {
1510 // m_mapTemplateLists.append(new TemplateList(m_project, xmlReader));
1511 }
1512 else if (xmlReader->name() == "regTemplateList") {
1513 // m_regTemplateLists.append(new TemplateList(m_project, xmlReader));
1514 }
1515 // workOrders are stored in history.xml, using same reader as project.xml
1516 else if (xmlReader->name() == "workOrder") {
1517 QString type = *(xmlReader->attributes().value("type").string());
1518
1519 m_workOrder = WorkOrderFactory::create(m_project, type);
1520
1521 // m_workOrder->read(xmlReader);
1522 }
1523 // warnings stored in warning.xml, using same reader as project.xml
1524 else if (xmlReader->name() == "warning") {
1525 QString warningText = *(xmlReader->attributes().value("text").string());
1526
1527 if (!warningText.isEmpty())
1528 {
1529 m_project->warn(warningText);
1530 }
1531 }
1532 else if (xmlReader->name() == "directory") {
1533 // m_project->directory()->load(xmlReader);
1534 }
1535 else if (xmlReader->name() == "dockRestore") {
1536 // QVariant geo_data = QVariant(atts.value("geometry"));
1537 // restoreGeometry(geo_data);
1538 // QVariant layout_data = QVariant(atts.value("state"));
1539 // restoreState(layout_data);
1540 }
1541 else if (xmlReader->name() == "bundleSolutionInfo") {
1542 m_bundleSolutionInfos.append(new BundleSolutionInfo(m_project, xmlReader));
1543 }
1544 else if (xmlReader->name() == "activeImageList") {
1545 QString displayName = *(xmlReader->attributes().value("displayName").string());
1546 m_project->setActiveImageList(displayName);
1547 }
1548 else if (xmlReader->name() == "activeControl") {
1549 // Find Control
1550 QString displayName = *(xmlReader->attributes().value("displayName").string());
1551 m_project->setActiveControl(displayName);
1552 }
1553 else
1554 {
1555 xmlReader->raiseError(QObject::tr("Incorrect file"));
1556 }
1557 }
1558 }
1559
1560 QProgressBar *Project::progress() {
1561 return m_imageReader->progress();
1562 }
1563
1564
1570 Image *Project::image(QString id) {
1571
1572 return (*m_idToImageMap)[id];
1573 }
1574
1575
1582 QListIterator<ImageList *> it(*m_images);
1583
1584 ImageList *result = NULL;
1585 while (it.hasNext() && !result) {
1586 ImageList *list = it.next();
1587
1588 if (list->name() == name) result = list;
1589 }
1590
1591 return result;
1592 }
1593
1594
1600 Shape *Project::shape(QString id) {
1601 return (*m_idToShapeMap)[id];
1602 }
1603
1604
1611 QListIterator<ShapeList *> it(*m_shapes);
1612
1613 ShapeList *result = NULL;
1614 while (it.hasNext() && !result) {
1615 ShapeList *list = it.next();
1616
1617 if (list->name() == name) result = list;
1618 }
1619
1620 return result;
1621 }
1622
1623
1629 return m_isTemporaryProject;
1630 }
1631
1632
1637 return m_isOpen;
1638 }
1639
1640
1646 return m_isClean;
1647 }
1648
1649
1656 void Project::setClean(bool value) {
1657 m_isClean = value;
1658 m_undoStack.cleanChanged(value);
1659 }
1660
1661
1667 WorkOrder *result = NULL;
1668 QListIterator< QPointer<WorkOrder> > it(*m_workOrderHistory);
1669 it.toBack();
1670
1671 while ( !result && it.hasPrevious() ) {
1672 WorkOrder *workOrder = it.previous();
1673
1674 if ( !workOrder->isUndone() && !workOrder->isUndoing() ) {
1675 result = workOrder;
1676 }
1677 }
1678
1679 return result;
1680 }
1681
1682
1686 QString Project::name() const {
1687 return m_name;
1688 }
1689
1690
1696 const WorkOrder *result = NULL;
1697 QListIterator< QPointer<WorkOrder> > it(*m_workOrderHistory);
1698 it.toBack();
1699
1700 while ( !result && it.hasPrevious() ) {
1701 WorkOrder *workOrder = it.previous();
1702
1703 if ( !workOrder->isUndone() && !workOrder->isUndoing() ) {
1704 result = workOrder;
1705 }
1706 }
1707
1708 return result;
1709 }
1710
1711
1719 QMutex *Project::mutex() {
1720 return m_mutex;
1721 }
1722
1723
1727 QString Project::projectRoot() const {
1728 return m_projectRoot->path();
1729 }
1730
1731
1736 QString Project::newProjectRoot() const {
1737 return m_newProjectRoot;
1738 }
1739
1740
1745 void Project::setName(QString newName) {
1746 m_name = newName;
1747 emit nameChanged(m_name);
1748 }
1749
1750
1755 QUndoStack *Project::undoStack() {
1756 return &m_undoStack;
1757 }
1758
1759
1760 QString Project::nextImageListGroupName() {
1761 int numLists = m_images->size();
1762 QString maxName = "";
1763 QString newGroupName = "Group";
1764
1765 foreach (ImageList *imageList, *m_images) {
1766 QString name = imageList->name();
1767 if ( !name.contains("Group") ) continue;
1768 if ( maxName.isEmpty() ) {
1769 maxName = name;
1770 }
1771 else if (name > maxName) {
1772 maxName = name;
1773 }
1774 }
1775
1776 if ( maxName.isEmpty() ) {
1777 newGroupName += QString::number(numLists+1);
1778 }
1779 else {
1780 int maxNum = maxName.remove("Group").toInt();
1781 maxNum++;
1782
1783 newGroupName += QString::number(maxNum);
1784 }
1785 return newGroupName;
1786
1787 }
1788
1789
1794 QMutexLocker locker(m_imageReadingMutex);
1795 }
1796
1797
1802 QMutexLocker locker(m_shapeReadingMutex);
1803 }
1804
1805
1809 QList<WorkOrder *> Project::workOrderHistory() {
1810 QList<WorkOrder *> result;
1811 foreach (WorkOrder *workOrder, *m_workOrderHistory) {
1812 result.append(workOrder);
1813 }
1814
1815 return result;
1816 }
1817
1818
1829 if (m_activeControl && m_activeImageList) {
1831 }
1832 }
1833
1834
1846 if (controls().count() > 0 && images().count() > 0) {
1848 }
1849 }
1850
1851
1880 void Project::setActiveControl(QString displayName) {
1881 Control *previousControl = m_activeControl;
1882 if (m_activeControl) {
1883
1884 // If the current active control has been modified, ask user if they want to save or discard
1885 // changes.
1886 if (m_activeControl->isModified()) {
1887 QMessageBox msgBox;
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();
1894 switch (ret) {
1895 // Save current active control
1896 case QMessageBox::Save:
1897 m_activeControl->write();
1898 break;
1899 // Discard any changes made to cnet
1900 case QMessageBox::Discard:
1901 // Close, then re-open effectively discarding edits
1902 m_activeControl->closeControlNet();
1903 m_activeControl->openControlNet();
1904 emit discardActiveControlEdits();
1905 break;
1906 // Cancel operation
1907 case QMessageBox::Cancel:
1908 return;
1909 }
1910 }
1911 emit activeControlSet(false);
1912 ProjectItem *item = directory()->model()->findItemData(m_activeControl->
1913 displayProperties()->displayName(), Qt::DisplayRole);
1914 item->setTextColor(Qt::black);
1915 // Make sure active not used in a CnetEditorWidget before closing
1916 if (!directory()->controlUsedInCnetEditorWidget(m_activeControl)) {
1917 m_activeControl->closeControlNet();
1918 }
1919 }
1920
1921 ProjectItem *item = directory()->model()->findItemData(displayName, Qt::DisplayRole);
1922 if (item && item->isControl()) {
1923 m_activeControl = item->control();
1924
1925 try {
1926 m_activeControl->controlNet()->SetImages(*(activeImageList()->serialNumberList()));
1927 item->setTextColor(Qt::darkGreen);
1928 }
1929 catch(IException &e){
1930 if (previousControl) {
1931 m_activeControl = previousControl;
1932 item = directory()->model()->findItemData(m_activeControl->
1933 displayProperties()->displayName(), Qt::DisplayRole);
1934 item->setTextColor(Qt::darkGreen);
1935 m_activeControl->controlNet()->SetImages(*(activeImageList()->serialNumberList()));
1936 }
1937 else {
1938 m_activeControl = NULL;
1939 }
1940 throw IException(e);
1941 }
1942 }
1943 emit activeControlSet(true);
1944 }
1945
1946
1965
1966 if (!m_activeControl && (m_controls->count() == 1 && m_controls->at(0)->count() ==1)) {
1967 // Can only set a default control if an active imageList exists or if a default can be set
1968 if (activeImageList()) {
1969 QString controlName = m_controls->at(0)->at(0)->displayProperties()->displayName();
1970 setActiveControl(controlName);
1971 }
1972 }
1973
1974 return m_activeControl;
1975 }
1976
1977
1986 if (m_activeControl && m_activeControl->isModified()) {
1987 emit activeControlModified();
1988 }
1989 setClean(false);
1990 }
1991
1992
2016 void Project::setActiveImageList(QString displayName) {
2017 ImageList *previousImageList = m_activeImageList;
2018 if (m_activeImageList) {
2019 ProjectItem *item = directory()->model()->findItemData(m_activeImageList->
2020 name(), Qt::DisplayRole);
2021 item->setTextColor(Qt::black);
2022 }
2023 ProjectItem *item = directory()->model()->findItemData(displayName, Qt::DisplayRole);
2024 if (item && item->isImageList()) {
2025 m_activeImageList = item->imageList();
2026
2027 if (m_activeControl) {
2028 try {
2029 activeControl()->controlNet()->SetImages(*(m_activeImageList->serialNumberList()));
2030 }
2031 catch(IException &e){
2032 if (previousImageList) {
2033 m_activeImageList = previousImageList;
2034 item = directory()->model()->findItemData(m_activeImageList->
2035 name(), Qt::DisplayRole);
2036 item->setTextColor(Qt::darkGreen);
2037 activeControl()->controlNet()->SetImages(*(m_activeImageList->serialNumberList()));
2038 }
2039 else {
2040 m_activeImageList = NULL;
2041 }
2042 throw IException(e);
2043 }
2044 }
2045 item->setTextColor(Qt::darkGreen);
2046 emit activeImageListSet();
2047 }
2048 }
2049
2050
2065
2066 if (!m_activeImageList && m_images->count() == 1) {
2067 QString imageList = m_images->at(0)->name();
2068
2070 }
2071 return m_activeImageList;
2072 }
2073
2074
2080 QString Project::cnetRoot(QString projectRoot) {
2081 return projectRoot + "/cnets";
2082 }
2083
2084
2090 QString Project::cnetRoot() const {
2091 return cnetRoot( m_projectRoot->path() );
2092 }
2093
2094
2099 QList<ControlList *> Project::controls() {
2100 return *m_controls;
2101 }
2102
2103
2110 QListIterator< ControlList * > it(*m_controls);
2111
2112 ControlList *result = NULL;
2113 while (it.hasNext() && !result) {
2114 ControlList *list = it.next();
2115
2116 if (list->name() == name) result = list;
2117 }
2118
2119 return result;
2120 }
2121
2122
2128 QString Project::imageDataRoot(QString projectRoot) {
2129 return projectRoot + "/images";
2130 }
2131
2132
2138 QString Project::imageDataRoot() const {
2139 return imageDataRoot( m_projectRoot->path() );
2140 }
2141
2142
2148 QString Project::shapeDataRoot(QString projectRoot) {
2149 return projectRoot + "/shapes";
2150 }
2151
2152
2158 QString Project::shapeDataRoot() const {
2159 return shapeDataRoot( m_projectRoot->path() );
2160 }
2161
2162
2167 QList<ShapeList *> Project::shapes() {
2168 return *m_shapes;
2169 }
2170
2171
2176 QList<ImageList *> Project::images() {
2177 return *m_images;
2178 }
2179
2180
2186 QString Project::templateRoot(QString projectRoot) {
2187 return projectRoot + "/templates";
2188 }
2189
2190
2196 QString Project::templateRoot() const {
2197 return templateRoot( m_projectRoot->path() );
2198 }
2199
2200
2206 QList<TemplateList *> Project::templates() {
2207 QList<TemplateList *> allTemplates = *m_mapTemplates + *m_regTemplates;
2208 return allTemplates;
2209 }
2210
2211
2217 QList<TemplateList *> Project::mapTemplates() {
2218 return *m_mapTemplates;
2219 }
2220
2221
2227 QList<TemplateList *> Project::regTemplates() {
2228 return *m_regTemplates;
2229 }
2230
2231
2237 QString Project::targetBodyRoot(QString projectRoot) {
2238 return projectRoot + "/targets";
2239 }
2240
2241
2247 QString Project::targetBodyRoot() const {
2248 return targetBodyRoot( m_projectRoot->path() );
2249 }
2250
2251
2256 return *m_targets;
2257 }
2258
2259
2265 QString Project::resultsRoot(QString projectRoot) {
2266 return projectRoot + "/results";
2267 }
2268
2269
2275 QString Project::resultsRoot() const {
2276 return resultsRoot( m_projectRoot->path() );
2277 }
2278
2279
2284 QList<BundleSolutionInfo *> Project::bundleSolutionInfo() {
2285 return *m_bundleSolutionInfo;
2286 }
2287
2288
2294 QString Project::bundleSolutionInfoRoot(QString projectRoot) {
2295 return projectRoot + "/results/bundle";
2296 }
2297
2298
2305 return bundleSolutionInfoRoot( m_projectRoot->path() );
2306 }
2307
2308
2313
2314 // Currently the deleteFromDisk methods for Image and Shape delete the Cube if it exists, the
2315 // other objects deleteFromDisk methods simply remove files. This could be achieved easier
2316 // in this method by simply calling QDir::removeRecursively(), but for future functionality
2317 // call each objects deleteFromDisk. Currently there are no cleanup methods for Bundle results
2318 // or templates, so simply remove directory recursively.
2319 foreach (ImageList *imagesInAFolder, *m_images) {
2320 imagesInAFolder->deleteFromDisk(this);
2321 }
2322
2323 if ( !m_projectRoot->rmdir( imageDataRoot() ) ) {
2324 warn( tr("Did not properly clean up images folder [%1] in project").arg( imageDataRoot() ) );
2325 }
2326
2327 foreach (ShapeList *shapesInAFolder, *m_shapes) {
2328 shapesInAFolder->deleteFromDisk(this);
2329 }
2330
2331 if ( !m_projectRoot->rmdir( shapeDataRoot() ) ) {
2332 warn( tr("Did not properly clean up shapes folder [%1] in project").
2333 arg( shapeDataRoot() ) );
2334 }
2335
2336 foreach (ControlList *controlsInAFolder, *m_controls) {
2337 controlsInAFolder->deleteFromDisk(this);
2338 }
2339
2340 if ( !m_projectRoot->rmdir( cnetRoot() ) ) {
2341 warn( tr("Did not properly clean up control network folder [%1] in project")
2342 .arg( cnetRoot() ) );
2343 }
2344
2345 if ( !(QDir(resultsRoot()).removeRecursively()) ) {
2346 warn( tr("Did not properly clean up results folder [%1] in project")
2347 .arg( resultsRoot() ) );
2348 }
2349
2350 if ( !(QDir(templateRoot()).removeRecursively()) ) {
2351 warn( tr("Did not properly clean up templates folder [%1] in project")
2352 .arg( templateRoot() ) );
2353 }
2354
2355 if ( !m_projectRoot->rmpath( m_projectRoot->path() ) ) {
2356 warn( tr("Did not properly clean up project in [%1]").arg( m_projectRoot->path() ) );
2357 }
2358 }
2359
2360
2366 void Project::relocateProjectRoot(QString newProjectRoot) {
2367 m_projectRoot->setPath(newProjectRoot);
2368 emit projectRelocated(this);
2369 }
2370
2371
2386 // Let caller know if the save dialog was cancelled
2387 bool saveDialogCompleted = true;
2388
2389 if (m_isTemporaryProject) {
2390 QString newDestination = QFileDialog::getSaveFileName(NULL,
2391 QString("Project Location"),
2392 QString("."));
2393
2394 if ( !newDestination.isEmpty() ) {
2395 m_isTemporaryProject = false;
2396 save( QFileInfo(newDestination + "/").absolutePath() );
2397
2398 // delete the temporary project
2400 relocateProjectRoot(newDestination);
2401
2402 // 2014-03-14 kle This is a lame kludge because we think that relocateProjectRoot is not
2403 // working properly. For example, when we save a new project and try to view a control net
2404 // the it thinks it's still in the /tmp area
2405 // see ticket #5292
2406 open(newDestination);
2407 }
2408 // Dialog was cancelled
2409 else {
2410 saveDialogCompleted = false;
2411 }
2412 }
2413 else {
2414 // Save all modified controls. If "Save As" is being processed,
2415 // the controls are written in the Control::copyToNewProjectRoot, so the controls in
2416 // current project are not modified.
2417 foreach (ControlList *controlList, *m_controls) {
2418 foreach (Control *control, *controlList) {
2419 if (control->isModified()) {
2420 control->write();
2421 }
2422 }
2423 }
2424 save(m_projectRoot->absolutePath(), false);
2425 emit cnetSaved(true);
2426 }
2427
2428 return saveDialogCompleted;
2429 }
2430
2431
2432
2433
2533 void Project::save(FileName newPath, bool verifyPathDoesntExist) {
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()),
2539 _FILEINFO_);
2540 }
2541
2542 QDir dir;
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()),
2548 _FILEINFO_);
2549 }
2550
2551 // TODO Set newpath member variable. This is used for some of the data copy methods and is not
2552 // the ideal way to handle this. Maybe change the data copy methods to either take the new
2553 // project root in addition to the data root or put the data root in the dataList (ImageList,
2554 // etc.). If performing a "Save", m_newProjectRoot == m_projectRoot
2555 m_newProjectRoot = newPath.toString();
2556
2557 // For now set the member variable rather than calling setName which emits signal and updates
2558 // ProjectItemModel & the project name on the tree. This will be updated when the new project
2559 // is opened.
2560 m_name = newPath.name();
2561
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()),
2568 _FILEINFO_);
2569 }
2570
2571 QXmlStreamWriter writer(&projectSettingsFile);
2572 writer.setAutoFormatting(true);
2573
2574 writer.writeStartDocument();
2575
2576 // Do amazing, fantastical stuff here!!!
2577 save(writer, newPath);
2578
2579 writer.writeEndDocument();
2580
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()),
2587 _FILEINFO_);
2588 }
2589
2590 QXmlStreamWriter historyWriter(&projectHistoryFile);
2591 historyWriter.setAutoFormatting(true);
2592
2593 historyWriter.writeStartDocument();
2594 saveHistory(historyWriter);
2595 historyWriter.writeEndDocument();
2596
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()),
2603 _FILEINFO_);
2604 }
2605
2606 QXmlStreamWriter warningsWriter(&projectWarningsFile);
2607 warningsWriter.setAutoFormatting(true);
2608
2609 warningsWriter.writeStartDocument();
2610 saveWarnings(warningsWriter);
2611 warningsWriter.writeEndDocument();
2612
2613 // Save the Directory structure
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()),
2620 _FILEINFO_);
2621 }
2622
2623 QXmlStreamWriter directoryStateWriter(&directoryStateFile);
2624 directoryStateWriter.setAutoFormatting(true);
2625
2626 directoryStateWriter.writeStartDocument();
2627
2628 /*
2629 * TODO: Does Project need to know about Directory?
2630 * This is the only place that project uses m_directory. This makes me wonder if it is
2631 * necessary for project to have a Directory member variable.
2632 */
2633 m_directory->save(directoryStateWriter, newPath);
2634
2635 directoryStateWriter.writeEndDocument();
2636 m_isOpen = true;
2637
2638 emit projectSaved(this);
2639
2640 }
2641
2642
2660 if (workOrder) {
2661 connect(workOrder, SIGNAL(finished(WorkOrder *)),
2662 this, SIGNAL(workOrderFinished(WorkOrder *)));
2663
2664 workOrder->setPrevious(lastNotUndoneWorkOrder());
2665
2666 if (workOrder->setupExecution()) {
2667 if (workOrder->previous()) workOrder->previous()->setNext(workOrder);
2668
2669 m_workOrderHistory->append(workOrder);
2670
2671 if (workOrder->isSavedToHistory()) {
2672 emit workOrderStarting(workOrder);
2673 }
2674
2675 // Work orders that create clean states (save, save as) don't belong on the undo stack.
2676 // Instead, we tell the undo stack that we're now clean.
2677 if (workOrder->createsCleanState()) {
2678 m_undoStack.setClean();
2679 workOrder->execute();
2680 }
2681 // All other work orders go onto the undo stack, unless specifically told not to
2682 else if (workOrder->isUndoable()) {
2683 // This calls WorkOrder::redo for us through Qt's QUndoStack::push method, redo is only
2684 // implemented in the base class. Child work orders do not implement redo.
2685 m_undoStack.push(workOrder);
2686 }
2687 else {
2688 // If we get this far the WorkOrder is not-undoable therefore we have to call redo by
2689 // hand.
2690
2691 workOrder->redo();
2692 }
2693 // Clean up deleted work orders (the m_undoStack.push() can delete work orders)
2694 m_workOrderHistory->removeAll(NULL);
2695 }
2696 else {
2697 delete workOrder;
2698 workOrder = NULL;
2699 }
2700 }
2701 }
2702
2703
2704 template<typename Data> void Project::warn(QString text, Data relevantData) {
2705 storeWarning(text, relevantData);
2706 directory()->showWarning(text, relevantData);
2707 }
2708
2709
2710 void Project::warn(QString text) {
2711 foreach (QString line, text.split("\n")) {
2712 storeWarning(line);
2713 directory()->showWarning(line);
2714 }
2715 }
2716
2717
2718 void Project::storeWarning(QString text) {
2719 m_warnings->append(text);
2720 }
2721
2722
2728
2730
2731 foreach (Image *image, images) {
2732 connect(image, SIGNAL(destroyed(QObject *)),
2733 this, SLOT(imageClosed(QObject *)));
2734 connect(this, SIGNAL(projectRelocated(Project *)),
2735 image, SLOT(updateFileName(Project *)));
2736
2737 (*m_idToImageMap)[image->id()] = image;
2738 if (images.name() != "") {
2739 createOrRetrieveImageList(images.name(), images.path())->append(image);
2740 }
2741 else {
2742 createOrRetrieveImageList(FileName(images[0]->fileName()).dir().dirName(), "")->append(image);
2743 }
2744 }
2745
2746 // We really can't have all of the cubes in memory before
2747 // the OS stops letting us open more files.
2748 // Assume cameras are being used in other parts of code since it's
2749 // unknown
2750 QMutexLocker lock(m_mutex);
2751 emit imagesAdded(m_images->last());
2752
2753 Image *openImage;
2754 foreach (openImage, images) {
2755 openImage->closeCube();
2756 }
2757
2758// if(m_projectPvl && m_projectPvl->HasObject("MosaicFileList") )
2759// m_fileList->fromPvl(m_projectPvl->FindObject("MosaicFileList") );
2760
2761// if(m_projectPvl && m_projectPvl->HasObject("MosaicScene") )
2762// m_scene->fromPvl(m_projectPvl->FindObject("MosaicScene") );
2763
2764 if (m_numImagesCurrentlyReading == 0) {
2765 m_imageReadingMutex->unlock();
2766 }
2767 }
2768
2769
2776 bool Project::hasTarget(QString id) {
2777 foreach (TargetBodyQsp targetBody, *m_targets) {
2778 if (QString::compare(targetBody->targetName(), id, Qt::CaseInsensitive) == 0) {
2779 return true;
2780 }
2781 }
2782 return false;
2783 }
2784
2785
2792
2793 TargetBodyQsp targetBody = TargetBodyQsp(new TargetBody(target));
2794
2795 m_targets->append(targetBody);
2796
2797 }
2798
2799
2806 bool Project::hasCamera(QString id) {
2807 foreach (GuiCameraQsp camera, *m_guiCameras) {
2808
2809 if (QString::compare(camera->instrumentId(), id, Qt::CaseInsensitive) == 0) {
2810 return true;
2811 }
2812 }
2813 return false;
2814 }
2815
2816
2823
2824 GuiCameraQsp guiCamera = GuiCameraQsp(new GuiCamera(camera));
2825
2826 m_guiCameras->append(guiCamera);
2827
2828 }
2829
2830
2840
2841 foreach (Image *image, images) {
2842 (*m_idToImageMap)[image->id()] = image;
2843 }
2844 }
2845
2846
2847 void Project::removeImages(ImageList &imageList) {
2848 foreach (Image *image, imageList) {
2849 delete image;
2850 }
2851 foreach (ImageList *list, *m_images) {
2852 if (list->name() == imageList.name()) {
2853 m_images->removeOne(list);
2854 }
2855 }
2856 }
2857
2858
2864 QMutableListIterator<ImageList *> it(*m_images);
2865 while (it.hasNext()) {
2866 ImageList *list = it.next();
2867
2868 int foundElement = list->indexOf((Image *)imageObj);
2869
2870 if (foundElement != -1) {
2871 list->removeAt(foundElement);
2872 }
2873 }
2874
2875 m_idToImageMap->remove(m_idToImageMap->key((Image *)imageObj));
2876 }
2877
2878
2884 int indexToRemove = m_images->indexOf(static_cast<ImageList *>(imageListObj));
2885 if (indexToRemove != -1) {
2886 m_images->removeAt(indexToRemove);
2887 }
2888 }
2889
2890
2895 m_idToControlMap->remove(m_idToControlMap->key((Control *)controlObj));
2896 }
2897
2898
2902 void Project::controlListDeleted(QObject *controlListObj) {
2903 int indexToRemove = m_controls->indexOf(static_cast<ControlList *>(controlListObj));
2904 if (indexToRemove != -1) {
2905 m_controls->removeAt(indexToRemove);
2906 }
2907
2908 if (controls().count() == 0) {
2909 emit allControlsRemoved();
2910 }
2911 }
2912
2913
2918 int indexToRemove = m_shapes->indexOf(static_cast<ShapeList *>(shapeListObj));
2919 if (indexToRemove != -1) {
2920 m_shapes->removeAt(indexToRemove);
2921 }
2922 }
2923
2924
2928 void Project::bundleSolutionInfoClosed(QObject *bundleSolutionInfoObj) {
2929 QMutableListIterator<BundleSolutionInfo *> it(*m_bundleSolutionInfo);
2930 while (it.hasNext()) {
2932 if (!bundleSolutionInfo) {
2933 // throw error???
2934 }
2935
2936 int foundElement = m_bundleSolutionInfo->indexOf(
2937 (BundleSolutionInfo *)bundleSolutionInfoObj);
2938
2939 if (foundElement != -1) {
2940 m_bundleSolutionInfo->removeAt(foundElement);
2941 }
2942 }
2943
2944 m_idToBundleSolutionInfoMap->remove(
2945 m_idToBundleSolutionInfoMap->key((BundleSolutionInfo * )bundleSolutionInfoObj));
2946 }
2947
2948
2954 void Project::targetBodyClosed(QObject *targetBodyObj) {
2955// QMutableListIterator<TargetBody *> it(*m_targets);
2956// while ( it.hasNext() ) {
2957// TargetBody *targetBody = it.next();
2958// if (!targetBody) {
2959// // throw error???
2960// }
2961
2962// int foundElement = m_targets->indexOf( (TargetBody *)targetBodyObj );
2963
2964// if (foundElement != -1) {
2965// m_targets->removeAt(foundElement);
2966// }
2967// }
2968
2969// m_idToTargetBodyMap->remove(m_idToTargetBodyMap->key((TargetBody *)targetBodyObj));
2970 }
2971
2972
2973
2974 void Project::shapesReady(ShapeList shapes) {
2975
2976 m_numShapesCurrentlyReading -= shapes.count();
2977
2978 foreach (Shape *shape, shapes) {
2979 connect(shape, SIGNAL(destroyed(QObject *)),
2980 this, SLOT(shapeClosed(QObject *)));
2981 connect(this, SIGNAL(projectRelocated(Project *)),
2982 shape, SLOT(updateFileName(Project *)));
2983
2984 (*m_idToShapeMap)[shape->id()] = shape;
2985 if (shapes.name() != "") {
2986 createOrRetrieveShapeList(shapes.name(), shapes.path())->append(shape);
2987 }
2988 else {
2989 createOrRetrieveShapeList(FileName(shapes[0]->fileName()).dir().dirName(), "")->append(shape);
2990 }
2991
2992 }
2993
2994 // We really can't have all of the cubes in memory before
2995 // the OS stops letting us open more files.
2996 // Assume cameras are being used in other parts of code since it's
2997 // unknown
2998 QMutexLocker lock(m_shapeMutex);
2999 emit shapesAdded(m_shapes->last());
3000
3001 Shape *openShape;
3002 foreach (openShape, shapes) {
3003 openShape->closeCube();
3004 }
3005
3006 if (m_numShapesCurrentlyReading == 0) {
3007 m_shapeReadingMutex->unlock();
3008 }
3009 }
3010
3011
3016 QMutableListIterator<ShapeList *> it(*m_shapes);
3017 while (it.hasNext()) {
3018 ShapeList *list = it.next();
3019
3020 int foundElement = list->indexOf((Shape *)imageObj);
3021
3022 if (foundElement != -1) {
3023 list->removeAt(foundElement);
3024 }
3025 }
3026
3027 m_idToShapeMap->remove(m_idToShapeMap->key((Shape *)imageObj));
3028 }
3029
3041 return m_workOrderMutex;
3042 }
3043}
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.
Definition Control.h:65
QString id() const
Access the unique ID associated with this Control.
Definition Control.cpp:262
ControlNet * controlNet()
Open and return a pointer to the ControlNet for this Control.
Definition Control.cpp:130
bool write()
@description Write control net to disk.
Definition Control.cpp:171
bool isModified()
@description Has this control been modified?
Definition Control.cpp:209
QString fileName() const
Access the name of the control network file associated with this Control.
Definition Control.cpp:252
Maintains a list of Controls so that control nets can easily be copied from one Project to another,...
Definition ControlList.h:42
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.
Definition Cube.h:168
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.
Definition FileName.h:100
QDir dir() const
Returns the path of the file's parent directory as a QDir object.
Definition FileName.cpp:465
Container class for GuiCamera.
Definition GuiCamera.h:70
List of GuiCameras saved as QSharedPointers.
void clear()
Clears the list.
void append(GuiCameraQsp const &value)
Appends a single GuiCamera to the list.
Isis exception class.
Definition IException.h:91
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition IException.h:146
@ Io
A type of error that occurred when performing an actual I/O operation.
Definition IException.h:155
@ FootprintViewProperties
Every display property for footprint views, provided for convenience.
This represents a cube in a project-based GUI interface.
Definition Image.h:105
void closeCube()
Cleans up the Cube pointer.
Definition Image.cpp:282
QString id() const
Get a unique, identifying string associated with this image.
Definition Image.cpp:420
Internalizes a list of images and allows for operations on the entire list.
Definition ImageList.h:53
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.
Definition Project.h:287
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.
Definition Project.cpp:2016
void imageListDeleted(QObject *imageList)
An image list is being deleted from the project.
Definition Project.cpp:2883
void addBundleSolutionInfo(BundleSolutionInfo *bundleSolutionInfo)
Add the given BundleSolutionInfo to the current project.
Definition Project.cpp:1191
void checkActiveControlAndImageList()
Checks if both an active control and active image list have been set.
Definition Project.cpp:1828
void activeImageListSet()
Emitted when an active image list is set.
Shape * shape(QString id)
Return a shape given its id.
Definition Project.cpp:1600
QString targetBodyRoot() const
Accessor for the root directory of the target body data.
Definition Project.cpp:2247
QMutex * mutex()
Return mutex used for Naif calls.
Definition Project.cpp:1719
ImageList * imageList(QString name)
Return an imagelist given its name.
Definition Project.cpp:1581
void workOrderStarting(WorkOrder *)
Emitted when work order starts.
QList< TemplateList * > templates()
Return all template FileNames.
Definition Project.cpp:2206
bool isTemporaryProject() const
Returns if the project is a temp project or not.
Definition Project.cpp:1628
void bundleSolutionInfoAdded(BundleSolutionInfo *bundleSolutionInfo)
Emitted when new BundleSolutionInfo available from jigsaw receivers: ProjectTreeWidget (TODO: should ...
void imagesReady(ImageList)
Prepare new images for opening.
Definition Project.cpp:2727
void targetBodyClosed(QObject *targetBodyObj)
A target body is being deleted from the project.
Definition Project.cpp:2954
void setName(QString newName)
Change the project's name (GUI only, doesn't affect location on disk).
Definition Project.cpp:1745
void imageClosed(QObject *image)
An image is being deleted from the project.
Definition Project.cpp:2863
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.
Definition Project.cpp:923
void controlListAdded(ControlList *controls)
apparently not used?
void addControl(Control *control)
Add the given Control's to the current project.
Definition Project.cpp:955
WorkOrder * lastNotUndoneWorkOrder()
Return the last not undone workorder.
Definition Project.cpp:1666
QDir addTemplateFolder(QString prefix)
Create and navigate to the appropriate template type folder in the project directory.
Definition Project.cpp:1131
void allControlsRemoved()
Emitted when all controls have been removed from the Project.
QString bundleSolutionInfoRoot() const
Accessor for the root directory of the results data.
Definition Project.cpp:2304
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.
Definition Project.cpp:2917
void deleteAllProjectFiles()
Delete all of the files, that this project stores, from disk.
Definition Project.cpp:2312
QString newProjectRoot() const
Get the top-level folder of the new project.
Definition Project.cpp:1736
void setActiveControl(QString displayName)
Set the Active Control (control network)
Definition Project.cpp:1880
QDir addBundleSolutionInfoFolder(QString folder)
Create and return the name of a folder for placing BundleSolutionInfo.
Definition Project.cpp:1171
void controlClosed(QObject *control)
A control is being deleted from the project.
Definition Project.cpp:2894
QList< TemplateList * > regTemplates()
Return registration template FileNames.
Definition Project.cpp:2227
void projectLoaded(Project *)
Emitted when project loaded receivers: IpceMainWindow, Directory, HistoryTreeWidget.
QString templateRoot() const
Accessor for the root directory of the template data.
Definition Project.cpp:2196
QUndoStack * undoStack()
Returns the Projects stack of QUndoCommands.
Definition Project.cpp:1755
void workOrderFinished(WorkOrder *)
Emitted when work order ends.
bool hasCamera(QString id)
This method checks for the existence of a camera based on InstrumentId.
Definition Project.cpp:2806
QList< WorkOrder * > workOrderHistory()
Get the entire list of work orders that have executed.
Definition Project.cpp:1809
QString resultsRoot() const
Accessor for the root directory of the results data.
Definition Project.cpp:2275
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...
Definition Project.cpp:2839
bool m_isClean
used to determine whether a project is currently open
Definition Project.h:638
void waitForShapeReaderFinished()
Locks program if another spot in code is still running and called this function.
Definition Project.cpp:1801
TargetBodyList targetBodies()
Return TargetBodyList in Project.
Definition Project.cpp:2255
void waitForImageReaderFinished()
Locks program if another spot in code is still running and called this function.
Definition Project.cpp:1793
ShapeList * shapeList(QString name)
Return a shapelist given its name.
Definition Project.cpp:1610
bool hasTarget(QString id)
This method checks for the existence of a target based on TargetName.
Definition Project.cpp:2776
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.
Definition Project.cpp:3015
QList< ShapeList * > shapes()
Return the projects shapelist.
Definition Project.cpp:2167
QMutex * workOrderMutex()
This function returns a QMutex.
Definition Project.cpp:3040
~Project()
Clean up the project.
Definition Project.cpp:254
QList< QAction * > userPreferenceActions()
Get a list of configuration/settings actions related to reading images into this Project.
Definition Project.cpp:913
void saveHistory(QXmlStreamWriter &stream) const
Serialize the work orders into the given XML.
Definition Project.cpp:848
void clear()
Function to clear out all values in a project essentially making it a new project object.
Definition Project.cpp:456
void addToProject(WorkOrder *)
This executes the WorkOrder and stores it in the project.
Definition Project.cpp:2659
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.
Definition Project.cpp:2791
QList< TemplateList * > mapTemplates()
Return map template FileNames.
Definition Project.cpp:2217
Control * control(QString id)
Accessor for if the project is clearing or not.
Definition Project.cpp:1160
void createFolders()
This creates the project root, image root, and control net root directories.
Definition Project.cpp:381
void cnetModified()
When a cnet is modified, set the project state to not clean.
Definition Project.cpp:1985
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.
Definition Project.cpp:2138
void bundleSolutionInfoClosed(QObject *bundleSolutionInfo)
A BundleSolutionInfo object is being deleted from the project.
Definition Project.cpp:2928
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.
Definition Project.cpp:2090
void checkControlsAndImagesAvailable()
Checks if at least one control and image have been added to the project.
Definition Project.cpp:1845
QList< ControlList * > controls()
Return controls in project.
Definition Project.cpp:2099
QMap< QString, Control * > * m_idToControlMap
This variable will probably go away when we add the bundle results object because it will be under: B...
Definition Project.h:623
bool m_clearing
used to determine whether a project's changes are unsaved
Definition Project.h:639
Directory * directory() const
Returns the directory associated with this Project.
Definition Project.cpp:1226
int m_numImagesCurrentlyReading
used to negate segfaults happening in post undos when clearning project
Definition Project.h:640
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.
Definition Project.cpp:1645
void open(QString)
Open the project at the given path.
Definition Project.cpp:1342
ImageList * activeImageList()
Returns the active ImageList.
Definition Project.cpp:2064
QList< BundleSolutionInfo * > bundleSolutionInfo()
Return BundleSolutionInfo objects in Project.
Definition Project.cpp:2284
QString projectRoot() const
Get the top-level folder of the project.
Definition Project.cpp:1727
QString name() const
Get the project's GUI name.
Definition Project.cpp:1686
void setClean(bool value)
Function to change the clean state of the project.
Definition Project.cpp:1656
Control * activeControl()
Return the Active Control (control network)
Definition Project.cpp:1964
void loadBundleSolutionInfo(BundleSolutionInfo *bundleSolutionInfo)
Loads bundle solution info into project.
Definition Project.cpp:1207
void addCamera(Camera *camera)
Adds a new camera to the project.
Definition Project.cpp:2822
QDir addImageFolder(QString prefix)
Create and return the name of a folder for placing images.
Definition Project.cpp:1000
void nameChanged(QString newName)
Emitted when project name is changed receivers: ProjectTreeWidget.
void saveWarnings(QXmlStreamWriter &stream) const
Serialize the warnings into the given XML.
Definition Project.cpp:871
void relocateProjectRoot(QString newRoot)
This is called when the project is moved.
Definition Project.cpp:2366
void controlListDeleted(QObject *controlList)
An control list is being deleted from the project.
Definition Project.cpp:2902
QString shapeDataRoot() const
Accessor for the root directory of the shape model data.
Definition Project.cpp:2158
bool isOpen()
Accessor to determine whether a current project is Open.
Definition Project.cpp:1636
QList< ImageList * > images()
Return projects imagelist.
Definition Project.cpp:2176
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.
Definition Project.cpp:1570
void addTemplates(TemplateList *templateFiles)
Add new templates to m_mapTemplates or m_regTemplates and update project item model.
Definition Project.cpp:1110
void addShapes(QStringList shapeFiles)
Read the given shape model cube file names as Images and add them to the project.
Definition Project.cpp:1086
Project(Directory &directory, QObject *parent=0)
Create a new Project.
Definition Project.cpp:85
void addImages(QStringList imageFiles)
Read the given cube file names as Images and add them to the project.
Definition Project.cpp:1029
bool save()
Generic save method to save the state of the project.
Definition Project.cpp:2385
QDir addShapeFolder(QString prefix)
Create and return the name of a folder for placing shape models.
Definition Project.cpp:1057
ControlList * controlList(QString name)
Return controlslist matching name in Project.
Definition Project.cpp:2109
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.
Definition Shape.h:66
void closeCube()
Cleans up the Cube *.
Definition Shape.cpp:326
QString id() const
Get a unique, identifying string associated with this shape.
Definition Shape.cpp:443
Internalizes a list of shapes and allows for operations on the entire list.
Definition ShapeList.h:31
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.
Definition TargetBody.h:63
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.
Definition Target.h:63
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.
Definition WorkOrder.h:311
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.
Definition Apollo.h:16
QSharedPointer< GuiCamera > GuiCameraQsp
GuiCameraQsp Represents a smart pointer to a GuiCamera object.
Definition GuiCamera.h:156
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition IString.cpp:211
QSharedPointer< TargetBody > TargetBodyQsp
Defines A smart pointer to a TargetBody obj.
Definition TargetBody.h:184