Official websites use .gov
A .gov website belongs to an official government organization in the United States.

Secure .gov websites use HTTPS
A lock ( ) or https:// means you’ve safely connected to the .gov website. Share sensitive information only on official, secure websites.

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 <QRegularExpression>
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
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
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(QRegularExpression(".*_"), "");
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()
184 throw IException(IException::Programmer,
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(QPointer<WorkOrder>());
371 delete m_workOrderHistory;
372 m_workOrderHistory = NULL;
373
374 delete m_bundleSettings;
375 m_bundleSettings = NULL;
376 }
377
378
383 QDir dir;
384 if ( !dir.mkpath( m_projectRoot->path() ) ) {
385 warn("Cannot create project directory.");
386 throw IException(IException::Io,
387 tr("Unable to create folder [%1] when trying to initialize project")
388 .arg(m_projectRoot->path() ),
389 _FILEINFO_);
390 }
391
392 try {
393 if ( !dir.mkdir( cnetRoot() ) ) {
394 QString msg = QString("Unable to create folder [%1] when trying to initialize project")
395 .arg( cnetRoot() );
396 warn(msg);
397 throw IException(IException::Io, msg, _FILEINFO_);
398 }
399
400 if ( !dir.mkdir( imageDataRoot() ) ) {
401 QString msg = QString("Unable to create folder [%1] when trying to initialize project")
402 .arg( imageDataRoot() );
403 warn(msg);
404 throw IException(IException::Io, msg, _FILEINFO_);
405 }
406
407 if ( !dir.mkdir( shapeDataRoot() ) ) {
408 QString msg = QString("Unable to create folder [%1] when trying to initialize project")
409 .arg( shapeDataRoot() );
410 warn(msg);
411 throw IException(IException::Io, msg, _FILEINFO_);
412 }
413
414 if ( !dir.mkdir( resultsRoot() ) ) {
415 QString msg = QString("Unable to create folder [%1] when trying to initialize project")
416 .arg( resultsRoot() );
417 warn(msg);
418 throw IException(IException::Io, msg, _FILEINFO_);
419 }
420 if ( !dir.mkdir( bundleSolutionInfoRoot() ) ) {
421 QString msg = QString("Unable to create folder [%1] when trying to initialize project")
422 .arg( bundleSolutionInfoRoot() );
423 warn(msg);
424 throw IException(IException::Io, msg, _FILEINFO_);
425 }
426 if ( !dir.mkdir( templateRoot() ) ) {
427 QString msg = QString("Unable to create folder [%1] when trying to initialize project")
428 .arg( templateRoot() );
429 warn(msg);
430 throw IException(IException::Io, msg, _FILEINFO_);
431 }
432 if ( !dir.mkdir( templateRoot() + "/maps" ) ) {
433 QString msg = QString("Unable to create folder [%1] when trying to initialize project")
434 .arg( templateRoot() + "/maps" );
435 warn(msg);
436 throw IException(IException::Io, msg, _FILEINFO_);
437 }
438 if ( !dir.mkdir( templateRoot() + "/registrations" ) ) {
439 QString msg = QString("Unable to create folder [%1] when trying to initialize project")
440 .arg( templateRoot() + "/registrations" );
441 warn(msg);
442 throw IException(IException::Io, msg, _FILEINFO_);
443 }
444 }
445 catch (...) {
446 warn("Failed to create project directory structure");
447 throw;
448 }
449 }
450
451
458 m_clearing = true;
459
460 // We need to look through the project.xml and remove every directory not in the project
461 QStringList shapeDirList;
462 bool shapes = false;
463 QStringList imageDirList;
464 bool images = false;
465 QStringList cnetDirList;
466 bool controls = false;
467 QStringList mapTemplateDirList;
468 bool mapTemplates = false;
469 QStringList regTemplateDirList;
470 bool regTemplates = false;
471 QStringList bundleDirList;
472 bool bundles = false;
473 QFile projectXml(projectRoot() + "/project.xml");
474
475 if (projectXml.open(QIODevice::ReadOnly)) {
476 QTextStream projectXmlInput(&projectXml);
477
478 while (!projectXmlInput.atEnd() ) {
479
480 QString line = projectXmlInput.readLine();
481
482 if (controls || line.contains("<controlNets>") ) {
483 controls = true;
484
485 if (line.contains("</controlNets>") ) {
486 controls = false;
487 }
488
489 else if (!line.contains("<controlNets>") ) {
490 cnetDirList.append(line.split('"').at(3));
491 }
492 }
493
494 else if (images || line.contains("<imageLists>") ) {
495 images = true;
496
497 if (line.contains("</imageLists>")) {
498 images = false;
499 }
500
501 else if (!line.contains("<imageLists>") ) {
502 imageDirList.append(line.split('"').at(3).simplified());
503 }
504 }
505
506 else if (shapes || line.contains("<shapeLists>")) {
507 shapes = true;
508
509 if (line.contains("</shapeLists>") ) {
510 shapes = false;
511 }
512
513 else if (!line.contains("<shapeLists>") ) {
514 shapeDirList.append(line.split('"').at(3));
515 }
516 }
517
518 else if (mapTemplates || line.contains("<mapTemplateLists>") ) {
519 mapTemplates = true;
520
521 if (line.contains("</mapTemplateLists>") ) {
522 mapTemplates = false;
523 }
524
525 else if (!line.contains("<mapTemplateLists>") ) {
526 QList<QString> components = line.split('"');
527 mapTemplateDirList.append(components.at(5));
528 }
529 }
530
531 else if (regTemplates || line.contains("<regTemplateLists>") ) {
532 regTemplates = true;
533
534 if (line.contains("</regTemplateLists>") ) {
535 regTemplates = false;
536 }
537
538 else if (!line.contains("<regTemplateLists>") ) {
539 QList<QString> components = line.split('"');
540 regTemplateDirList.append(components.at(5));
541 }
542 }
543
544 else if (bundles || line.contains("<bundleSolutionInfo>") ) {
545 bundles = true;
546
547 if (line.contains("</bundleSolutionInfo>") ) {
548 bundles = false;
549 }
550
551 else if (line.contains("<runTime>") ) {
552 bundleDirList.append(line.split('>').at(1).split('<').at(0));
553 }
554 }
555 }
556
557 QDir cnetsDir(m_projectRoot->path() + "/cnets/");
558 cnetsDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
559 QStringList cnetsList = cnetsDir.entryList();
560 foreach (QString dir, cnetsList) {
561 dir = dir.simplified();
562
563 if ( !cnetDirList.contains(dir) ) {
564 QDir tempDir(cnetsDir.path() + "/" + dir);
565 tempDir.removeRecursively();
566 }
567 }
568
569 QDir imagesDir(m_projectRoot->path() + "/images/");
570 imagesDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
571 QStringList imagesList = imagesDir.entryList();
572 foreach (QString dir, imagesList) {
573 dir = dir.simplified();
574
575 if ( !imageDirList.contains(dir) ) {
576 QDir tempDir(imagesDir.path() + "/" + dir);
577 tempDir.removeRecursively();
578 }
579 }
580
581 QDir shapesDir(m_projectRoot->path() + "/shapes/");
582 shapesDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
583 QStringList shapesList = shapesDir.entryList();
584 foreach (QString dir, shapesList) {
585 dir = dir.simplified();
586
587 if ( !shapeDirList.contains(dir) ) {
588 QDir tempDir(shapesDir.path() + "/" + dir);
589 tempDir.removeRecursively();
590 }
591 }
592
593 QDir mapTemplatesDir(m_projectRoot->path() + "/templates/maps");
594 mapTemplatesDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
595 QStringList mapTemplatesList = mapTemplatesDir.entryList();
596 foreach (QString dir, mapTemplatesList) {
597 dir = dir.simplified();
598
599 if ( !mapTemplateDirList.contains("maps/" + dir) ) {
600 QDir tempDir(mapTemplatesDir.path() + "/" + dir);
601 tempDir.removeRecursively();
602 }
603 }
604
605 QDir regTemplatesDir(m_projectRoot->path() + "/templates/registrations");
606 regTemplatesDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
607 QStringList regTemplatesList = regTemplatesDir.entryList();
608 foreach (QString dir, regTemplatesList) {
609 dir = dir.simplified();
610
611 if ( !regTemplateDirList.contains("registrations/" + dir)) {
612 QDir tempDir(regTemplatesDir.path() + "/" + dir);
613 tempDir.removeRecursively();
614 }
615 }
616
617 QDir bundlesDir(m_projectRoot->path() + "/results/bundle/");
618 bundlesDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
619 QStringList bundleList = bundlesDir.entryList();
620 foreach (QString dir, bundleList) {
621 dir = dir.simplified();
622
623 if ( !bundleDirList.contains(dir) ) {
624 QDir tempDir(bundlesDir.path() + "/" + dir);
625 tempDir.removeRecursively();
626 }
627 }
628
629 projectXml.close();
630 }
631
632 try {
633 QString tmpFolder = QDir::temp().absolutePath() + "/"
634 + Environment::userName() + "_"
635 + QApplication::applicationName() + "_" + QString::number( getpid() );
636 QDir temp(tmpFolder + "/tmpProject");
637 m_projectRoot = new QDir(temp);
638 }
639
640 catch (IException &e) {
641 throw IException(e, IException::Programmer, "Error creating project folders.", _FILEINFO_);
642 }
643
644 catch (std::exception &e) {
645 throw IException(IException::Programmer,
646 tr("Error creating project folders [%1]").arg( e.what() ), _FILEINFO_);
647 }
648
649 m_images->clear();
650 m_shapes->clear();
651 m_controls->clear();
652 m_mapTemplates->clear();
653 m_regTemplates->clear();
654 m_targets->clear();
655 m_guiCameras->clear();
656 m_bundleSolutionInfo->clear();
657 m_workOrderHistory->clear();
658
659 directory()->clean();
660 setClean(true);
661 }
662
663
664 bool Project::clearing() {
665 return m_clearing;
666 }
667
668
669 ImageList *Project::createOrRetrieveImageList(QString name, QString path) {
670 ImageList *result = imageList(name);
671 if (!result) {
672 result = new ImageList;
673
674 result->setName(name);
675 if (path == "") {
676 result->setPath(name);
677 }
678 else {
679 result->setPath(path);
680 }
681
682 connect( result, SIGNAL( destroyed(QObject *) ),
683 this, SLOT( imageListDeleted(QObject *) ) );
684 m_images->append(result);
685 }
686 return result;
687 }
688
689
690 ShapeList *Project::createOrRetrieveShapeList(QString name, QString path) {
691 ShapeList *result = shapeList(name);
692 if (!result) {
693 result = new ShapeList;
694
695 result->setName(name);
696 if (path == "") {
697 result->setPath(name);
698 }
699 else {
700 result->setPath(path);
701 }
702
703 connect( result, SIGNAL( destroyed(QObject *) ),
704 this, SLOT( shapeListDeleted(QObject *) ) );
705 m_shapes->append(result);
706 }
707 return result;
708 }
709
710
724 void Project::save(QXmlStreamWriter &stream, FileName newProjectRoot) const {
725 stream.writeStartElement("project");
726
727 stream.writeAttribute("name", m_name);
728
729 if ( !m_controls->isEmpty() ) {
730 stream.writeStartElement("controlNets");
731
732 for (int i = 0; i < m_controls->count(); i++) {
733 m_controls->at(i)->save(stream, this, newProjectRoot);
734 }
735
736 stream.writeEndElement();
737 }
738
739 if ( !m_images->isEmpty() ) {
740 stream.writeStartElement("imageLists");
741 for (int i = 0; i < m_images->count(); i++) {
742 m_images->at(i)->save(stream, this, newProjectRoot);
743 }
744
745 stream.writeEndElement();
746 }
747
748 if ( !m_shapes->isEmpty() ) {
749 stream.writeStartElement("shapeLists");
750
751 for (int i = 0; i < m_shapes->count(); i++) {
752 m_shapes->at(i)->save(stream, this, newProjectRoot);
753 }
754
755 stream.writeEndElement();
756 }
757
758 if ( !m_mapTemplates->isEmpty() ) {
759 stream.writeStartElement("mapTemplateLists");
760
761 for (int i = 0; i < m_mapTemplates->count(); i++) {
762 m_mapTemplates->at(i)->save(stream, this, newProjectRoot);
763 }
764
765 stream.writeEndElement();
766 }
767
768 if ( !m_regTemplates->isEmpty() ) {
769 stream.writeStartElement("regTemplateLists");
770
771 for (int i = 0; i < m_regTemplates->count(); i++) {
772 m_regTemplates->at(i)->save(stream, this, newProjectRoot);
773 }
774
775 stream.writeEndElement();
776 }
777
778 // TODO: Finish implementing serialization of TargetBody & GuiCameras
779// if (!m_targets->isEmpty()) {
780// stream.writeStartElement("targets");
781//
782// for (int i = 0; i < m_targets->count(); i++) {
783// m_targets->at(i)->save(stream, this, newProjectRoot);
784// }
785//
786// stream.writeEndElement();
787// }
788//
789// if (!m_guiCameras->isEmpty()) {
790// stream.writeStartElement("cameras");
791//
792// for (int i = 0; i < m_guiCameras->count(); i++) {
793// m_guiCameras->at(i)->save(stream, this, newProjectRoot);
794// }
795//
796// stream.writeEndElement();
797// }
798
799// Write general look of gui, including docked widges
800// QVariant geo_data = saveGeometry();
801// QVariant layout_data = saveState();
802//
803// stream.writeStartElement("dockRestore");
804// stream.writeAttribute("geometry", geo_data.toString());
805// stream.writeAttribute("state", layout_data.toString());
806
807
808 if ( !m_bundleSolutionInfo->isEmpty() ) {
809 stream.writeStartElement("results");
810
811 for (int i = 0; i < m_bundleSolutionInfo->count(); i++) {
812 m_bundleSolutionInfo->at(i)->save(stream, this, newProjectRoot);
813 }
814
815 stream.writeEndElement();
816 }
817
818 if (m_activeImageList) {
819 stream.writeStartElement("activeImageList");
820 stream.writeAttribute("displayName", m_activeImageList->name());
821 stream.writeEndElement();
822 }
823
824 if (m_activeControl) {
825 stream.writeStartElement("activeControl");
826 stream.writeAttribute("displayName", m_activeControl->displayProperties()->displayName());
827 stream.writeEndElement();
828 }
829
830 stream.writeEndElement();
831 }
832
833
849 void Project::saveHistory(QXmlStreamWriter &stream) const {
850 stream.writeStartElement("history");
851
852 foreach (WorkOrder *workOrder, *m_workOrderHistory) {
853 if (workOrder) {
854 workOrder->save(stream);
855 }
856 }
857
858 stream.writeEndElement();
859 }
860
872 void Project::saveWarnings(QXmlStreamWriter &stream) const {
873 stream.writeStartElement("warnings");
874
875 foreach (QString warning, *m_warnings) {
876 stream.writeStartElement("warning");
877 stream.writeAttribute("text", warning);
878 stream.writeEndElement();
879 }
880
881 stream.writeEndElement();
882 }
883
884
891 // TODO: thread via ImageReader
893
894 QStringList result;
895
896 foreach (QString fileName, fileNames) {
897 try {
898 Cube tmp(fileName);
899 result.append(fileName);
900 }
901 catch (IException &) {
902 }
903 }
904
905 return result;
906 }
907
908
917
918
924 QDir Project::addCnetFolder(QString prefix) {
925 QDir cnetFolder = cnetRoot();
926 prefix += "%1";
927 int prefixCounter = 0;
928
929 QString numberedPrefix;
930 do {
931 prefixCounter++;
932 numberedPrefix = prefix.arg( QString::number(prefixCounter) );
933 }
934 while ( cnetFolder.exists(numberedPrefix) );
935
936 if ( !cnetFolder.mkpath(numberedPrefix) ) {
937 throw IException(IException::Io,
938 tr("Could not create control network directory [%1] in [%2].")
939 .arg(numberedPrefix).arg( cnetFolder.absolutePath() ),
940 _FILEINFO_);
941 }
942
943 cnetFolder.cd(numberedPrefix);
944
945 m_currentCnetFolder = cnetFolder;
946
947 return cnetFolder;
948 }
949
950
957
958 connect( control, SIGNAL( destroyed(QObject *) ),
959 this, SLOT( controlClosed(QObject *) ) );
960 connect( this, SIGNAL( projectRelocated(Project *) ),
961 control, SLOT( updateFileName(Project *) ) );
962
963 createOrRetrieveControlList( FileName( control->fileName() ).dir().dirName(), "" )->append(control);
964
965 (*m_idToControlMap)[control->id()] = control;
966
967 emit controlAdded(control);
968 }
969
970
971 ControlList *Project::createOrRetrieveControlList(QString name, QString path) {
972 ControlList *result = controlList(name);
973
974 if (!result) {
975 result = new ControlList;
976
977 result->setName(name);
978 if (path == "") {
979 result->setPath(name);
980 }
981 else {
982 result->setPath(path);
983 }
984
985 connect( result, SIGNAL( destroyed(QObject *) ),
986 this, SLOT( controlListDeleted(QObject *) ) );
987
988 m_controls->append(result);
989 emit controlListAdded(result);
990 }
991
992 return result;
993 }
994
995
1001 QDir Project::addImageFolder(QString prefix) {
1002 QDir imageFolder = imageDataRoot();
1003 prefix += "%1";
1004 int prefixCounter = 0;
1005
1006 QString numberedPrefix;
1007 do {
1008 prefixCounter++;
1009 numberedPrefix = prefix.arg( QString::number(prefixCounter) );
1010 }
1011 while ( imageFolder.exists(numberedPrefix) );
1012
1013 if ( !imageFolder.mkpath(numberedPrefix) ) {
1014 throw IException(IException::Io,
1015 tr("Could not create image directory [%1] in [%2].")
1016 .arg(numberedPrefix).arg( imageFolder.absolutePath() ),
1017 _FILEINFO_);
1018 }
1019
1020 imageFolder.cd(numberedPrefix);
1021
1022 return imageFolder;
1023 }
1024
1025
1031 if (m_numImagesCurrentlyReading == 0) {
1032 m_imageReadingMutex->lock();
1033 }
1034
1035 m_numImagesCurrentlyReading += imageFiles.count();
1036 m_imageReader->read(imageFiles);
1037 }
1038
1039
1045 imagesReady(newImages);
1046
1047 // The each
1048 emit guiCamerasAdded(m_guiCameras);
1049 emit targetsAdded(m_targets);
1050 }
1051
1052
1058 QDir Project::addShapeFolder(QString prefix) {
1059 QDir shapeFolder = shapeDataRoot();
1060 prefix += "%1";
1061 int prefixCounter = 0;
1062
1063 QString numberedPrefix;
1064 do {
1065 prefixCounter++;
1066 numberedPrefix = prefix.arg( QString::number(prefixCounter) );
1067 }
1068 while ( shapeFolder.exists(numberedPrefix) );
1069
1070 if ( !shapeFolder.mkpath(numberedPrefix) ) {
1071 throw IException(IException::Io,
1072 tr("Could not create shape directory [%1] in [%2].")
1073 .arg(numberedPrefix).arg( shapeFolder.absolutePath() ),
1074 _FILEINFO_);
1075 }
1076
1077 shapeFolder.cd(numberedPrefix);
1078
1079 return shapeFolder;
1080 }
1081
1082
1088 if (m_numShapesCurrentlyReading == 0) {
1089 m_shapeReadingMutex->lock();
1090 }
1091
1092 m_numShapesCurrentlyReading += shapeFiles.count();
1093 m_shapeReader->read(shapeFiles);
1094 }
1095
1096
1102 shapesReady(newShapes);
1103 }
1104
1105
1112 foreach (Template *templateFile, *templateList) {
1113 connect( this, SIGNAL( projectRelocated(Project *) ),
1114 templateFile, SLOT( updateFileName(Project *) ) );
1115 }
1116 if (templateList->type() == "maps") {
1117 m_mapTemplates->append(templateList);
1118 }
1119 else if (templateList->type() == "registrations") {
1120 m_regTemplates->append(templateList);
1121 }
1122
1123 emit templatesAdded(templateList);
1124 }
1125
1126
1132 QDir Project::addTemplateFolder(QString prefix) {
1133 QDir templateFolder = templateRoot();
1134 prefix += "%1";
1135 int prefixCounter = 0;
1136 QString numberedPrefix;
1137
1138 do {
1139 prefixCounter++;
1140 numberedPrefix = prefix.arg( QString::number(prefixCounter) );
1141 }
1142 while ( templateFolder.exists(numberedPrefix) );
1143
1144 if ( !templateFolder.mkpath(numberedPrefix) ) {
1145 throw IException(IException::Io,
1146 tr("Could not create template directory [%1] in [%2].")
1147 .arg(numberedPrefix).arg( templateFolder.absolutePath() ),
1148 _FILEINFO_);
1149 }
1150
1151 templateFolder.cd(numberedPrefix);
1152
1153 return templateFolder;
1154 }
1155
1156
1162 return (*m_idToControlMap)[id];
1163 }
1164
1165
1173 QDir bundleSolutionInfoFolder(bundleSolutionInfoRoot());
1174
1175 if (!bundleSolutionInfoFolder.mkpath(folder)) {
1176 throw IException(IException::Io,
1177 tr("Could not create bundle results directory [%1] in [%2].")
1178 .arg(folder).arg(bundleSolutionInfoFolder.absolutePath()),
1179 _FILEINFO_);
1180 }
1181
1182 bundleSolutionInfoFolder.cd(folder);
1183 return bundleSolutionInfoFolder;
1184 }
1185
1186
1193 connect(bundleSolutionInfo, SIGNAL(destroyed(QObject *)),
1194 this, SLOT(bundleSolutionInfoClosed(QObject *)));//???
1195 connect(this, SIGNAL(projectRelocated(Project *)),
1196 bundleSolutionInfo, SLOT(updateFileName(Project *)));//DNE???
1197
1198
1200 }
1201
1202
1209 m_bundleSolutionInfo->append(bundleSolutionInfo);
1210
1211 // add BundleSolutionInfo to project's m_idToBundleSolutionInfoMap
1212 (*m_idToBundleSolutionInfoMap)[bundleSolutionInfo->id()] = bundleSolutionInfo;
1213
1214 // add BundleSolutionInfo's control to project's m_idToControlMap
1215 (*m_idToControlMap)[bundleSolutionInfo->control()->id()] = bundleSolutionInfo->control();
1216
1218 }
1219
1220
1228 return m_directory;
1229 }
1230
1231
1232 void Project::writeSettings() {
1233
1234 QString appName = QApplication::applicationName();
1235
1236
1237 QSettings globalSettings(
1238 FileName("$HOME/.Isis/" + appName + "/" + appName + "_" + "Project.config")
1239 .expanded(),
1240 QSettings::NativeFormat);
1241
1242 globalSettings.beginGroup("recent_projects");
1243 QStringList keys = globalSettings.allKeys();
1244 QMap<QString,QString> recentProjects;
1245
1246 foreach (QString key,keys) {
1247
1248 recentProjects[key]=globalSettings.value(key).toString();
1249
1250 }
1251
1252 QList<QString> projectPaths = recentProjects.values();
1253
1254 if (keys.count() >= m_maxRecentProjects) {
1255
1256 //Clear out the recent projects before repopulating this group
1257 globalSettings.remove("");
1258
1259
1260
1261 //If the currently open project is a project that has been saved and is not within the current
1262 //list of recently open projects, then remove the oldest project from the list.
1263 if (!this->projectRoot().contains("tmpProject") && !projectPaths.contains(this->projectRoot()) ) {
1264 QString s=keys.first();
1265 recentProjects.remove( s );
1266 }
1267
1268 //If the currently open project is already contained within the list,
1269 //then remove the earlier reference.
1270
1271 if (projectPaths.contains(this->projectRoot())) {
1272 QString key = recentProjects.key(this->projectRoot());
1273 recentProjects.remove(key);
1274 }
1275
1276 QMap<QString,QString>::iterator i;
1277
1278 //Iterate through the recentProjects QMap and set the <key,val> pairs.
1279 for (i=recentProjects.begin();i!=recentProjects.end();i++) {
1280
1281 globalSettings.setValue(i.key(),i.value());
1282
1283 }
1284
1285 //Get a unique time value for generating a key
1286 long t0 = QDateTime::currentMSecsSinceEpoch();
1287 QString projName = this->name();
1288
1289 QString t0String=QString::number(t0);
1290
1291 //Save the project location
1292 if (!this->projectRoot().contains("tmpProject") ) {
1293 globalSettings.setValue(t0String+"%%%%%"+projName,this->projectRoot());
1294
1295 }
1296
1297 }
1298
1299 //The numer of recent open projects is less than m_maxRecentProjects
1300 else {
1301
1302 //Clear out the recent projects before repopulating this group
1303 globalSettings.remove("");
1304 if (projectPaths.contains(this->projectRoot())) {
1305 QString key = recentProjects.key(this->projectRoot());
1306 recentProjects.remove(key);
1307 }
1308 QMap<QString,QString>::iterator i;
1309
1310 //Iterate through the recentProjects QMap and set the <key,val> pairs.
1311 for ( i=recentProjects.begin(); i!=recentProjects.end(); i++ ) {
1312 globalSettings.setValue(i.key(),i.value());
1313 }
1314
1315 long t0 = QDateTime::currentMSecsSinceEpoch();
1316 QString projName = this->name();
1317 QString t0String=QString::number(t0);
1318
1319 //if (!this->projectRoot().contains("tmpProject") && !projectPaths.contains( this->projectRoot() ) ) {
1320 if (!this->projectRoot().contains("tmpProject") ) {
1321 globalSettings.setValue(t0String+"%%%%%"+projName,this->projectRoot());
1322 }
1323
1324 }
1325
1326
1327 globalSettings.endGroup();
1328 }
1329
1330
1343 void Project::open(QString projectPathStr) {
1344 // Expand projectPathStr to contain absolute path
1345 QString projectAbsolutePathStr = QDir(projectPathStr).absolutePath();
1346
1347 QString projectXmlPath = projectAbsolutePathStr + "/project.xml";
1348 QFile file(projectXmlPath);
1349
1350 if ( !file.open(QFile::ReadOnly) ) {
1351 throw IException(IException::Io,
1352 QString("Unable to open [%1] with read access")
1353 .arg(projectXmlPath),
1354 _FILEINFO_);
1355 }
1356
1357 QString projectXmlHistoryPath = projectAbsolutePathStr + "/history.xml";
1358 QFile historyFile(projectXmlHistoryPath);
1359
1360 if ( !historyFile.open(QFile::ReadOnly) ) {
1361 throw IException(IException::Io,
1362 QString("Unable to open [%1] with read access")
1363 .arg(projectXmlHistoryPath),
1364 _FILEINFO_);
1365 }
1366
1367 QString projectXmlWarningsPath = projectAbsolutePathStr + "/warnings.xml";
1368 QFile warningsFile(projectXmlWarningsPath);
1369
1370 if (!warningsFile.open(QFile::ReadOnly)) {
1371 throw IException(IException::Io,
1372 QString("Unable to open [%1] with read access")
1373 .arg(projectXmlWarningsPath),
1374 _FILEINFO_);
1375 }
1376
1377 QString directoryXmlPath = projectAbsolutePathStr + "/directory.xml";
1378 QFile directoryFile(directoryXmlPath);
1379
1380 if (!directoryFile.open(QFile::ReadOnly)) {
1381 throw IException(IException::Io,
1382 QString("Unable to open [%1] with read access")
1383 .arg(directoryXmlPath),
1384 _FILEINFO_);
1385 }
1386
1387 if (isOpen() || !isClean()) {
1388 clear();
1389 }
1390 m_clearing = false;
1391 m_isTemporaryProject = false;
1392
1393 QDir oldProjectRoot(*m_projectRoot);
1394 *m_projectRoot = QDir(projectAbsolutePathStr);
1395
1396 QXmlStreamReader projectXmlReader(&file);
1397
1398 //This prevents the project from not loading if everything
1399 //can't be loaded, and outputs the warnings/errors to the
1400 //Warnings Tab
1401 try {
1402 readProjectXml(&projectXmlReader);
1403 }
1404 catch (IException &e) {
1405 directory()->showWarning(QString("Failed to open project completely [%1]")
1406 .arg(projectAbsolutePathStr));
1407 directory()->showWarning(e.toString());
1408 }
1409 catch (std::exception &e) {
1410 directory()->showWarning(QString("Failed to open project completely[%1]")
1411 .arg(projectAbsolutePathStr));
1412 directory()->showWarning(e.what());
1413 }
1414
1415 QXmlStreamReader reader2(&historyFile);
1416
1417 try {
1418 while (!reader2.atEnd()) {
1419 reader2.readNext();
1420 }
1421 }
1422
1423 catch (IException &e) {
1424 directory()->showWarning(QString("Failed to read history from project[%1]")
1425 .arg(projectAbsolutePathStr));
1426 directory()->showWarning(e.toString());
1427 }
1428 catch (std::exception &e) {
1429 directory()->showWarning(QString("Failed to read history from project[%1]")
1430 .arg(projectAbsolutePathStr));
1431 directory()->showWarning(e.what());
1432 }
1433
1434 QXmlStreamReader reader3(&warningsFile);
1435
1436 while (!reader3.atEnd()) {
1437 reader3.readNext();
1438 }
1439 if (reader3.hasError()) {
1440 warn(tr("Failed to read warnings from project [%1]").arg(projectAbsolutePathStr));
1441 }
1442
1443 QXmlStreamReader reader4(&directoryFile);
1444
1445 try {
1446 while (!reader4.atEnd()) {
1447 reader4.readNext();
1448 }
1449 }
1450 catch (IException &e) {
1451 directory()->showWarning(QString("Failed to read GUI state from project[%1]")
1452 .arg(projectAbsolutePathStr));
1453 directory()->showWarning(e.toString());
1454
1455 }
1456 catch (std::exception &e) {
1457 directory()->showWarning(QString("Failed to read GUI state from project[%1]")
1458 .arg(projectAbsolutePathStr));
1459 directory()->showWarning(e.what());
1460 }
1461
1462 QDir bundleRoot(bundleSolutionInfoRoot());
1463 if (bundleRoot.exists()) {
1464 // get QFileInfo for each directory in the bundle root
1465 bundleRoot.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::NoSymLinks); // sym links ok???
1466
1467 QFileInfoList bundleDirs = bundleRoot.entryInfoList();
1468
1469 for (int dirListIndex = 0; dirListIndex < bundleDirs.size(); dirListIndex++) {
1470
1471 // get QFileInfo for each file in this directory
1472 QDir bundleSolutionDir(bundleDirs[dirListIndex].absoluteFilePath());
1473 bundleSolutionDir.setFilter(QDir::Files | QDir::NoSymLinks); // sym links ok???
1474
1475// QFileInfoList bundleSolutionFiles = bundleSolutionDir.entryInfoList();
1476// for (int fileListIndex = 0; fileListIndex < bundleSolutionFiles.size(); fileListIndex++) {
1477// // if the file is an hdf file with BundleSolutionInfo object, add it to the project tree
1478// if (bundleSolutionFiles[fileListIndex].fileName().contains("_BundleSolutionInfo.hdf")) {
1479// QString absoluteFileName = bundleSolutionFiles[fileListIndex].absoluteFilePath();
1480// FileName solutionFile(bundleSolutionFiles[fileListIndex].absoluteFilePath());
1481// loadBundleSolutionInfo(new BundleSolutionInfo(solutionFile));
1482// }
1483// }
1484 }
1485 }
1486 m_isOpen = true;
1487
1488 setClean(true);
1489 emit projectLoaded(this);
1490 }
1491
1492
1493 void Project::readProjectXml(QXmlStreamReader *xmlReader) {
1494 if (xmlReader->readNextStartElement()) {
1495 if (xmlReader->name() == "project") {
1496 QStringView name = xmlReader->attributes().value("name");
1497 if (!name.isEmpty()) {
1498 m_project->setName(name.toString());
1499 }
1500 }
1501 else if (xmlReader->name() == "controlNets") {
1502 // m_controls.append(new ControlList(m_project, xmlReader));
1503 }
1504 else if (xmlReader->name() == "imageList") {
1505 // m_imageLists.append(new ImageList(m_project, xmlReader));
1506 }
1507 else if (xmlReader->name() == "shapeList") {
1508 // m_shapeLists.append(new ShapeList(m_project, xmlReader));
1509 }
1510 else if (xmlReader->name() == "mapTemplateList") {
1511 // m_mapTemplateLists.append(new TemplateList(m_project, xmlReader));
1512 }
1513 else if (xmlReader->name() == "regTemplateList") {
1514 // m_regTemplateLists.append(new TemplateList(m_project, xmlReader));
1515 }
1516 // workOrders are stored in history.xml, using same reader as project.xml
1517 else if (xmlReader->name() == "workOrder") {
1518 QString type = xmlReader->attributes().value("type").toString();
1519
1520 m_workOrder = WorkOrderFactory::create(m_project, type);
1521
1522 // m_workOrder->read(xmlReader);
1523 }
1524 // warnings stored in warning.xml, using same reader as project.xml
1525 else if (xmlReader->name() == "warning") {
1526 QString warningText = xmlReader->attributes().value("text").toString();
1527
1528 if (!warningText.isEmpty())
1529 {
1530 m_project->warn(warningText);
1531 }
1532 }
1533 else if (xmlReader->name() == "directory") {
1534 // m_project->directory()->load(xmlReader);
1535 }
1536 else if (xmlReader->name() == "dockRestore") {
1537 // QVariant geo_data = QVariant(atts.value("geometry"));
1538 // restoreGeometry(geo_data);
1539 // QVariant layout_data = QVariant(atts.value("state"));
1540 // restoreState(layout_data);
1541 }
1542 else if (xmlReader->name() == "bundleSolutionInfo") {
1543 m_bundleSolutionInfos.append(new BundleSolutionInfo(m_project, xmlReader));
1544 }
1545 else if (xmlReader->name() == "activeImageList") {
1546 QString displayName = xmlReader->attributes().value("displayName").toString();
1547 m_project->setActiveImageList(displayName);
1548 }
1549 else if (xmlReader->name() == "activeControl") {
1550 // Find Control
1551 QString displayName = xmlReader->attributes().value("displayName").toString();
1552 m_project->setActiveControl(displayName);
1553 }
1554 else
1555 {
1556 xmlReader->raiseError(QObject::tr("Incorrect file"));
1557 }
1558 }
1559 }
1560
1561 QProgressBar *Project::progress() {
1562 return m_imageReader->progress();
1563 }
1564
1565
1571 Image *Project::image(QString id) {
1572
1573 return (*m_idToImageMap)[id];
1574 }
1575
1576
1583 QListIterator<ImageList *> it(*m_images);
1584
1585 ImageList *result = NULL;
1586 while (it.hasNext() && !result) {
1587 ImageList *list = it.next();
1588
1589 if (list->name() == name) result = list;
1590 }
1591
1592 return result;
1593 }
1594
1595
1601 Shape *Project::shape(QString id) {
1602 return (*m_idToShapeMap)[id];
1603 }
1604
1605
1612 QListIterator<ShapeList *> it(*m_shapes);
1613
1614 ShapeList *result = NULL;
1615 while (it.hasNext() && !result) {
1616 ShapeList *list = it.next();
1617
1618 if (list->name() == name) result = list;
1619 }
1620
1621 return result;
1622 }
1623
1624
1630 return m_isTemporaryProject;
1631 }
1632
1633
1638 return m_isOpen;
1639 }
1640
1641
1647 return m_isClean;
1648 }
1649
1650
1657 void Project::setClean(bool value) {
1658 m_isClean = value;
1659 m_undoStack.cleanChanged(value);
1660 }
1661
1662
1668 WorkOrder *result = NULL;
1669 QListIterator< QPointer<WorkOrder> > it(*m_workOrderHistory);
1670 it.toBack();
1671
1672 while ( !result && it.hasPrevious() ) {
1673 WorkOrder *workOrder = it.previous();
1674
1675 if ( !workOrder->isUndone() && !workOrder->isUndoing() ) {
1676 result = workOrder;
1677 }
1678 }
1679
1680 return result;
1681 }
1682
1683
1687 QString Project::name() const {
1688 return m_name;
1689 }
1690
1691
1697 const WorkOrder *result = NULL;
1698 QListIterator< QPointer<WorkOrder> > it(*m_workOrderHistory);
1699 it.toBack();
1700
1701 while ( !result && it.hasPrevious() ) {
1702 WorkOrder *workOrder = it.previous();
1703
1704 if ( !workOrder->isUndone() && !workOrder->isUndoing() ) {
1705 result = workOrder;
1706 }
1707 }
1708
1709 return result;
1710 }
1711
1712
1720 QMutex *Project::mutex() {
1721 return m_mutex;
1722 }
1723
1724
1728 QString Project::projectRoot() const {
1729 return m_projectRoot->path();
1730 }
1731
1732
1737 QString Project::newProjectRoot() const {
1738 return m_newProjectRoot;
1739 }
1740
1741
1745
1746 void Project::setName(QString newName) {
1747 m_name = newName;
1748 emit nameChanged(m_name);
1749 }
1750
1751
1756 QUndoStack *Project::undoStack() {
1757 return &m_undoStack;
1758 }
1759
1760
1761 QString Project::nextImageListGroupName() {
1762 int numLists = m_images->size();
1763 QString maxName = "";
1764 QString newGroupName = "Group";
1765
1766 foreach (ImageList *imageList, *m_images) {
1767 QString name = imageList->name();
1768 if ( !name.contains("Group") ) continue;
1769 if ( maxName.isEmpty() ) {
1770 maxName = name;
1771 }
1772 else if (name > maxName) {
1773 maxName = name;
1774 }
1775 }
1776
1777 if ( maxName.isEmpty() ) {
1778 newGroupName += QString::number(numLists+1);
1779 }
1780 else {
1781 int maxNum = maxName.remove("Group").toInt();
1782 maxNum++;
1783
1784 newGroupName += QString::number(maxNum);
1785 }
1786 return newGroupName;
1787
1788 }
1789
1790
1795 QMutexLocker locker(m_imageReadingMutex);
1796 }
1797
1798
1803 QMutexLocker locker(m_shapeReadingMutex);
1804 }
1805
1806
1811 QList<WorkOrder *> result;
1812 foreach (WorkOrder *workOrder, *m_workOrderHistory) {
1813 result.append(workOrder);
1814 }
1815
1816 return result;
1817 }
1818
1819
1830 if (m_activeControl && m_activeImageList) {
1832 }
1833 }
1834
1835
1847 if (controls().count() > 0 && images().count() > 0) {
1849 }
1850 }
1851
1852
1881 void Project::setActiveControl(QString displayName) {
1882 Control *previousControl = m_activeControl;
1883 if (m_activeControl) {
1884
1885 // If the current active control has been modified, ask user if they want to save or discard
1886 // changes.
1887 if (m_activeControl->isModified()) {
1888 QMessageBox msgBox;
1889 msgBox.setText("Save current active control");
1890 msgBox.setInformativeText("The current active control has been modified. Do you want "
1891 "to save before setting a new active control?");
1892 msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
1893 msgBox.setDefaultButton(QMessageBox::Save);
1894 int ret = msgBox.exec();
1895 switch (ret) {
1896 // Save current active control
1897 case QMessageBox::Save:
1898 m_activeControl->write();
1899 break;
1900 // Discard any changes made to cnet
1901 case QMessageBox::Discard:
1902 // Close, then re-open effectively discarding edits
1903 m_activeControl->closeControlNet();
1904 m_activeControl->openControlNet();
1905 emit discardActiveControlEdits();
1906 break;
1907 // Cancel operation
1908 case QMessageBox::Cancel:
1909 return;
1910 }
1911 }
1912 emit activeControlSet(false);
1913 ProjectItem *item = directory()->model()->findItemData(m_activeControl->
1914 displayProperties()->displayName(), Qt::DisplayRole);
1915 item->setTextColor(Qt::black);
1916 // Make sure active not used in a CnetEditorWidget before closing
1917 if (!directory()->controlUsedInCnetEditorWidget(m_activeControl)) {
1918 m_activeControl->closeControlNet();
1919 }
1920 }
1921
1922 ProjectItem *item = directory()->model()->findItemData(displayName, Qt::DisplayRole);
1923 if (item && item->isControl()) {
1924 m_activeControl = item->control();
1925
1926 try {
1927 m_activeControl->controlNet()->SetImages(*(activeImageList()->serialNumberList()));
1928 item->setTextColor(Qt::darkGreen);
1929 }
1930 catch(IException &e){
1931 if (previousControl) {
1932 m_activeControl = previousControl;
1933 item = directory()->model()->findItemData(m_activeControl->
1934 displayProperties()->displayName(), Qt::DisplayRole);
1935 item->setTextColor(Qt::darkGreen);
1936 m_activeControl->controlNet()->SetImages(*(activeImageList()->serialNumberList()));
1937 }
1938 else {
1939 m_activeControl = NULL;
1940 }
1941 throw IException(e);
1942 }
1943 }
1944 emit activeControlSet(true);
1945 }
1946
1947
1966
1967 if (!m_activeControl && (m_controls->count() == 1 && m_controls->at(0)->count() ==1)) {
1968 // Can only set a default control if an active imageList exists or if a default can be set
1969 if (activeImageList()) {
1970 QString controlName = m_controls->at(0)->at(0)->displayProperties()->displayName();
1971 setActiveControl(controlName);
1972 }
1973 }
1974
1975 return m_activeControl;
1976 }
1977
1978
1987 if (m_activeControl && m_activeControl->isModified()) {
1988 emit activeControlModified();
1989 }
1990 setClean(false);
1991 }
1992
1993
2017 void Project::setActiveImageList(QString displayName) {
2018 ImageList *previousImageList = m_activeImageList;
2019 if (m_activeImageList) {
2020 ProjectItem *item = directory()->model()->findItemData(m_activeImageList->
2021 name(), Qt::DisplayRole);
2022 item->setTextColor(Qt::black);
2023 }
2024 ProjectItem *item = directory()->model()->findItemData(displayName, Qt::DisplayRole);
2025 if (item && item->isImageList()) {
2026 m_activeImageList = item->imageList();
2027
2028 if (m_activeControl) {
2029 try {
2030 activeControl()->controlNet()->SetImages(*(m_activeImageList->serialNumberList()));
2031 }
2032 catch(IException &e){
2033 if (previousImageList) {
2034 m_activeImageList = previousImageList;
2035 item = directory()->model()->findItemData(m_activeImageList->
2036 name(), Qt::DisplayRole);
2037 item->setTextColor(Qt::darkGreen);
2038 activeControl()->controlNet()->SetImages(*(m_activeImageList->serialNumberList()));
2039 }
2040 else {
2041 m_activeImageList = NULL;
2042 }
2043 throw IException(e);
2044 }
2045 }
2046 item->setTextColor(Qt::darkGreen);
2047 emit activeImageListSet();
2048 }
2049 }
2050
2051
2066
2067 if (!m_activeImageList && m_images->count() == 1) {
2068 QString imageList = m_images->at(0)->name();
2069
2071 }
2072 return m_activeImageList;
2073 }
2074
2075
2082 return projectRoot + "/cnets";
2083 }
2084
2085
2091 QString Project::cnetRoot() const {
2092 return cnetRoot( m_projectRoot->path() );
2093 }
2094
2095
2101 return *m_controls;
2102 }
2103
2104
2111 QListIterator< ControlList * > it(*m_controls);
2112
2113 ControlList *result = NULL;
2114 while (it.hasNext() && !result) {
2115 ControlList *list = it.next();
2116
2117 if (list->name() == name) result = list;
2118 }
2119
2120 return result;
2121 }
2122
2123
2130 return projectRoot + "/images";
2131 }
2132
2133
2139 QString Project::imageDataRoot() const {
2140 return imageDataRoot( m_projectRoot->path() );
2141 }
2142
2143
2150 return projectRoot + "/shapes";
2151 }
2152
2153
2159 QString Project::shapeDataRoot() const {
2160 return shapeDataRoot( m_projectRoot->path() );
2161 }
2162
2163
2169 return *m_shapes;
2170 }
2171
2172
2178 return *m_images;
2179 }
2180
2181
2188 return projectRoot + "/templates";
2189 }
2190
2191
2197 QString Project::templateRoot() const {
2198 return templateRoot( m_projectRoot->path() );
2199 }
2200
2201
2208 QList<TemplateList *> allTemplates = *m_mapTemplates + *m_regTemplates;
2209 return allTemplates;
2210 }
2211
2212
2219 return *m_mapTemplates;
2220 }
2221
2222
2229 return *m_regTemplates;
2230 }
2231
2232
2239 return projectRoot + "/targets";
2240 }
2241
2242
2248 QString Project::targetBodyRoot() const {
2249 return targetBodyRoot( m_projectRoot->path() );
2250 }
2251
2252
2257 return *m_targets;
2258 }
2259
2260
2267 return projectRoot + "/results";
2268 }
2269
2270
2276 QString Project::resultsRoot() const {
2277 return resultsRoot( m_projectRoot->path() );
2278 }
2279
2280
2286 return *m_bundleSolutionInfo;
2287 }
2288
2289
2296 return projectRoot + "/results/bundle";
2297 }
2298
2299
2306 return bundleSolutionInfoRoot( m_projectRoot->path() );
2307 }
2308
2309
2314
2315 // Currently the deleteFromDisk methods for Image and Shape delete the Cube if it exists, the
2316 // other objects deleteFromDisk methods simply remove files. This could be achieved easier
2317 // in this method by simply calling QDir::removeRecursively(), but for future functionality
2318 // call each objects deleteFromDisk. Currently there are no cleanup methods for Bundle results
2319 // or templates, so simply remove directory recursively.
2320 foreach (ImageList *imagesInAFolder, *m_images) {
2321 imagesInAFolder->deleteFromDisk(this);
2322 }
2323
2324 if ( !m_projectRoot->rmdir( imageDataRoot() ) ) {
2325 warn( tr("Did not properly clean up images folder [%1] in project").arg( imageDataRoot() ) );
2326 }
2327
2328 foreach (ShapeList *shapesInAFolder, *m_shapes) {
2329 shapesInAFolder->deleteFromDisk(this);
2330 }
2331
2332 if ( !m_projectRoot->rmdir( shapeDataRoot() ) ) {
2333 warn( tr("Did not properly clean up shapes folder [%1] in project").
2334 arg( shapeDataRoot() ) );
2335 }
2336
2337 foreach (ControlList *controlsInAFolder, *m_controls) {
2338 controlsInAFolder->deleteFromDisk(this);
2339 }
2340
2341 if ( !m_projectRoot->rmdir( cnetRoot() ) ) {
2342 warn( tr("Did not properly clean up control network folder [%1] in project")
2343 .arg( cnetRoot() ) );
2344 }
2345
2346 if ( !(QDir(resultsRoot()).removeRecursively()) ) {
2347 warn( tr("Did not properly clean up results folder [%1] in project")
2348 .arg( resultsRoot() ) );
2349 }
2350
2351 if ( !(QDir(templateRoot()).removeRecursively()) ) {
2352 warn( tr("Did not properly clean up templates folder [%1] in project")
2353 .arg( templateRoot() ) );
2354 }
2355
2356 if ( !m_projectRoot->rmpath( m_projectRoot->path() ) ) {
2357 warn( tr("Did not properly clean up project in [%1]").arg( m_projectRoot->path() ) );
2358 }
2359 }
2360
2361
2368 m_projectRoot->setPath(newProjectRoot);
2369 emit projectRelocated(this);
2370 }
2371
2372
2387 // Let caller know if the save dialog was cancelled
2388 bool saveDialogCompleted = true;
2389
2390 if (m_isTemporaryProject) {
2391 QString newDestination = QFileDialog::getSaveFileName(NULL,
2392 QString("Project Location"),
2393 QString("."));
2394
2395 if ( !newDestination.isEmpty() ) {
2396 m_isTemporaryProject = false;
2397 save( QFileInfo(newDestination + "/").absolutePath() );
2398
2399 // delete the temporary project
2401 relocateProjectRoot(newDestination);
2402
2403 // 2014-03-14 kle This is a lame kludge because we think that relocateProjectRoot is not
2404 // working properly. For example, when we save a new project and try to view a control net
2405 // the it thinks it's still in the /tmp area
2406 // see ticket #5292
2407 open(newDestination);
2408 }
2409 // Dialog was cancelled
2410 else {
2411 saveDialogCompleted = false;
2412 }
2413 }
2414 else {
2415 // Save all modified controls. If "Save As" is being processed,
2416 // the controls are written in the Control::copyToNewProjectRoot, so the controls in
2417 // current project are not modified.
2418 foreach (ControlList *controlList, *m_controls) {
2419 foreach (Control *control, *controlList) {
2420 if (control->isModified()) {
2421 control->write();
2422 }
2423 }
2424 }
2425 save(m_projectRoot->absolutePath(), false);
2426 emit cnetSaved(true);
2427 }
2428
2429 return saveDialogCompleted;
2430 }
2431
2432
2433
2434
2534 void Project::save(FileName newPath, bool verifyPathDoesntExist) {
2535 if ( verifyPathDoesntExist && QFile::exists( newPath.toString() ) ) {
2536 throw IException(IException::Io,
2537 QString("Projects may not be saved to an existing path [%1]; "
2538 "please select a new path or delete the current folder")
2539 .arg(newPath.original()),
2540 _FILEINFO_);
2541 }
2542
2543 QDir dir;
2544 if (!dir.mkpath(newPath.toString())) {
2545 throw IException(IException::Io,
2546 QString("Unable to save project at [%1] "
2547 "because we could not create the folder")
2548 .arg(newPath.original()),
2549 _FILEINFO_);
2550 }
2551
2552 // TODO Set newpath member variable. This is used for some of the data copy methods and is not
2553 // the ideal way to handle this. Maybe change the data copy methods to either take the new
2554 // project root in addition to the data root or put the data root in the dataList (ImageList,
2555 // etc.). If performing a "Save", m_newProjectRoot == m_projectRoot
2556 m_newProjectRoot = newPath.toString();
2557
2558 // For now set the member variable rather than calling setName which emits signal and updates
2559 // ProjectItemModel & the project name on the tree. This will be updated when the new project
2560 // is opened.
2561 m_name = newPath.name();
2562
2563 QFile projectSettingsFile(newPath.toString() + "/project.xml");
2564 if (!projectSettingsFile.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
2565 throw IException(IException::Io,
2566 QString("Unable to save project at [%1] because the file [%2] "
2567 "could not be opened for writing")
2568 .arg(newPath.original()).arg(projectSettingsFile.fileName()),
2569 _FILEINFO_);
2570 }
2571
2572 QXmlStreamWriter writer(&projectSettingsFile);
2573 writer.setAutoFormatting(true);
2574
2575 writer.writeStartDocument();
2576
2577 // Do amazing, fantastical stuff here!!!
2578 save(writer, newPath);
2579
2580 writer.writeEndDocument();
2581
2582 QFile projectHistoryFile(newPath.toString() + "/history.xml");
2583 if (!projectHistoryFile.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
2584 throw IException(IException::Io,
2585 QString("Unable to save project at [%1] because the file [%2] "
2586 "could not be opened for writing")
2587 .arg(newPath.original()).arg(projectHistoryFile.fileName()),
2588 _FILEINFO_);
2589 }
2590
2591 QXmlStreamWriter historyWriter(&projectHistoryFile);
2592 historyWriter.setAutoFormatting(true);
2593
2594 historyWriter.writeStartDocument();
2595 saveHistory(historyWriter);
2596 historyWriter.writeEndDocument();
2597
2598 QFile projectWarningsFile(newPath.toString() + "/warnings.xml");
2599 if (!projectWarningsFile.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
2600 throw IException(IException::Io,
2601 QString("Unable to save project at [%1] because the file [%2] could not be "
2602 "opened for writing")
2603 .arg(newPath.original()).arg(projectWarningsFile.fileName()),
2604 _FILEINFO_);
2605 }
2606
2607 QXmlStreamWriter warningsWriter(&projectWarningsFile);
2608 warningsWriter.setAutoFormatting(true);
2609
2610 warningsWriter.writeStartDocument();
2611 saveWarnings(warningsWriter);
2612 warningsWriter.writeEndDocument();
2613
2614 // Save the Directory structure
2615 QFile directoryStateFile(newPath.toString() + "/directory.xml");
2616 if (!directoryStateFile.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
2617 throw IException(IException::Io,
2618 QString("Unable to save project at [%1] because the file [%2] could not be "
2619 "opened for writing")
2620 .arg(newPath.original()).arg(directoryStateFile.fileName()),
2621 _FILEINFO_);
2622 }
2623
2624 QXmlStreamWriter directoryStateWriter(&directoryStateFile);
2625 directoryStateWriter.setAutoFormatting(true);
2626
2627 directoryStateWriter.writeStartDocument();
2628
2629 /*
2630 * TODO: Does Project need to know about Directory?
2631 * This is the only place that project uses m_directory. This makes me wonder if it is
2632 * necessary for project to have a Directory member variable.
2633 */
2634 m_directory->save(directoryStateWriter, newPath);
2635
2636 directoryStateWriter.writeEndDocument();
2637 m_isOpen = true;
2638
2639 emit projectSaved(this);
2640
2641 }
2642
2643
2661 if (workOrder) {
2662 connect(workOrder, SIGNAL(finished(WorkOrder *)),
2663 this, SIGNAL(workOrderFinished(WorkOrder *)));
2664
2665 workOrder->setPrevious(lastNotUndoneWorkOrder());
2666
2667 if (workOrder->setupExecution()) {
2668 if (workOrder->previous()) workOrder->previous()->setNext(workOrder);
2669
2670 m_workOrderHistory->append(workOrder);
2671
2672 if (workOrder->isSavedToHistory()) {
2673 emit workOrderStarting(workOrder);
2674 }
2675
2676 // Work orders that create clean states (save, save as) don't belong on the undo stack.
2677 // Instead, we tell the undo stack that we're now clean.
2678 if (workOrder->createsCleanState()) {
2679 m_undoStack.setClean();
2680 workOrder->execute();
2681 }
2682 // All other work orders go onto the undo stack, unless specifically told not to
2683 else if (workOrder->isUndoable()) {
2684 // This calls WorkOrder::redo for us through Qt's QUndoStack::push method, redo is only
2685 // implemented in the base class. Child work orders do not implement redo.
2686 m_undoStack.push(workOrder);
2687 }
2688 else {
2689 // If we get this far the WorkOrder is not-undoable therefore we have to call redo by
2690 // hand.
2691
2692 workOrder->redo();
2693 }
2694 // Clean up deleted work orders (the m_undoStack.push() can delete work orders)
2695 m_workOrderHistory->removeAll(QPointer<WorkOrder>());
2696 }
2697 else {
2698 delete workOrder;
2699 workOrder = NULL;
2700 }
2701 }
2702 }
2703
2704
2705 template<typename Data> void Project::warn(QString text, Data relevantData) {
2706 storeWarning(text, relevantData);
2707 directory()->showWarning(text, relevantData);
2708 }
2709
2710
2711 void Project::warn(QString text) {
2712 foreach (QString line, text.split("\n")) {
2713 storeWarning(line);
2714 directory()->showWarning(line);
2715 }
2716 }
2717
2718
2719 void Project::storeWarning(QString text) {
2720 m_warnings->append(text);
2721 }
2722
2723
2729
2731
2732 foreach (Image *image, images) {
2733 connect(image, SIGNAL(destroyed(QObject *)),
2734 this, SLOT(imageClosed(QObject *)));
2735 connect(this, SIGNAL(projectRelocated(Project *)),
2736 image, SLOT(updateFileName(Project *)));
2737
2738 (*m_idToImageMap)[image->id()] = image;
2739 if (images.name() != "") {
2740 createOrRetrieveImageList(images.name(), images.path())->append(image);
2741 }
2742 else {
2743 createOrRetrieveImageList(FileName(images[0]->fileName()).dir().dirName(), "")->append(image);
2744 }
2745 }
2746
2747 // We really can't have all of the cubes in memory before
2748 // the OS stops letting us open more files.
2749 // Assume cameras are being used in other parts of code since it's
2750 // unknown
2751 QMutexLocker lock(m_mutex);
2752 emit imagesAdded(m_images->last());
2753
2754 Image *openImage;
2755 foreach (openImage, images) {
2756 openImage->closeCube();
2757 }
2758
2759// if(m_projectPvl && m_projectPvl->HasObject("MosaicFileList") )
2760// m_fileList->fromPvl(m_projectPvl->FindObject("MosaicFileList") );
2761
2762// if(m_projectPvl && m_projectPvl->HasObject("MosaicScene") )
2763// m_scene->fromPvl(m_projectPvl->FindObject("MosaicScene") );
2764
2765 if (m_numImagesCurrentlyReading == 0) {
2766 m_imageReadingMutex->unlock();
2767 }
2768 }
2769
2770
2777 bool Project::hasTarget(QString id) {
2778 foreach (TargetBodyQsp targetBody, *m_targets) {
2779 if (QString::compare(targetBody->targetName(), id, Qt::CaseInsensitive) == 0) {
2780 return true;
2781 }
2782 }
2783 return false;
2784 }
2785
2786
2793
2794 TargetBodyQsp targetBody = TargetBodyQsp(new TargetBody(target));
2795
2796 m_targets->append(targetBody);
2797
2798 }
2799
2800
2807 bool Project::hasCamera(QString id) {
2808 foreach (GuiCameraQsp camera, *m_guiCameras) {
2809
2810 if (QString::compare(camera->instrumentId(), id, Qt::CaseInsensitive) == 0) {
2811 return true;
2812 }
2813 }
2814 return false;
2815 }
2816
2817
2824
2825 GuiCameraQsp guiCamera = GuiCameraQsp(new GuiCamera(camera));
2826
2827 m_guiCameras->append(guiCamera);
2828
2829 }
2830
2831
2841
2842 foreach (Image *image, images) {
2843 (*m_idToImageMap)[image->id()] = image;
2844 }
2845 }
2846
2847
2848 void Project::removeImages(ImageList &imageList) {
2849 foreach (Image *image, imageList) {
2850 delete image;
2851 }
2852 foreach (ImageList *list, *m_images) {
2853 if (list->name() == imageList.name()) {
2854 m_images->removeOne(list);
2855 }
2856 }
2857 }
2858
2859
2865 QMutableListIterator<ImageList *> it(*m_images);
2866 while (it.hasNext()) {
2867 ImageList *list = it.next();
2868
2869 int foundElement = list->indexOf((Image *)imageObj);
2870
2871 if (foundElement != -1) {
2872 list->removeAt(foundElement);
2873 }
2874 }
2875
2876 m_idToImageMap->remove(m_idToImageMap->key((Image *)imageObj));
2877 }
2878
2879
2885 int indexToRemove = m_images->indexOf(static_cast<ImageList *>(imageListObj));
2886 if (indexToRemove != -1) {
2887 m_images->removeAt(indexToRemove);
2888 }
2889 }
2890
2891
2896 m_idToControlMap->remove(m_idToControlMap->key((Control *)controlObj));
2897 }
2898
2899
2903 void Project::controlListDeleted(QObject *controlListObj) {
2904 int indexToRemove = m_controls->indexOf(static_cast<ControlList *>(controlListObj));
2905 if (indexToRemove != -1) {
2906 m_controls->removeAt(indexToRemove);
2907 }
2908
2909 if (controls().count() == 0) {
2910 emit allControlsRemoved();
2911 }
2912 }
2913
2914
2919 int indexToRemove = m_shapes->indexOf(static_cast<ShapeList *>(shapeListObj));
2920 if (indexToRemove != -1) {
2921 m_shapes->removeAt(indexToRemove);
2922 }
2923 }
2924
2925
2929 void Project::bundleSolutionInfoClosed(QObject *bundleSolutionInfoObj) {
2930 QMutableListIterator<BundleSolutionInfo *> it(*m_bundleSolutionInfo);
2931 while (it.hasNext()) {
2933 if (!bundleSolutionInfo) {
2934 // throw error???
2935 }
2936
2937 int foundElement = m_bundleSolutionInfo->indexOf(
2938 (BundleSolutionInfo *)bundleSolutionInfoObj);
2939
2940 if (foundElement != -1) {
2941 m_bundleSolutionInfo->removeAt(foundElement);
2942 }
2943 }
2944
2945 m_idToBundleSolutionInfoMap->remove(
2946 m_idToBundleSolutionInfoMap->key((BundleSolutionInfo * )bundleSolutionInfoObj));
2947 }
2948
2949
2955 void Project::targetBodyClosed(QObject *targetBodyObj) {
2956// QMutableListIterator<TargetBody *> it(*m_targets);
2957// while ( it.hasNext() ) {
2958// TargetBody *targetBody = it.next();
2959// if (!targetBody) {
2960// // throw error???
2961// }
2962
2963// int foundElement = m_targets->indexOf( (TargetBody *)targetBodyObj );
2964
2965// if (foundElement != -1) {
2966// m_targets->removeAt(foundElement);
2967// }
2968// }
2969
2970// m_idToTargetBodyMap->remove(m_idToTargetBodyMap->key((TargetBody *)targetBodyObj));
2971 }
2972
2973
2974
2975 void Project::shapesReady(ShapeList shapes) {
2976
2977 m_numShapesCurrentlyReading -= shapes.count();
2978
2979 foreach (Shape *shape, shapes) {
2980 connect(shape, SIGNAL(destroyed(QObject *)),
2981 this, SLOT(shapeClosed(QObject *)));
2982 connect(this, SIGNAL(projectRelocated(Project *)),
2983 shape, SLOT(updateFileName(Project *)));
2984
2985 (*m_idToShapeMap)[shape->id()] = shape;
2986 if (shapes.name() != "") {
2987 createOrRetrieveShapeList(shapes.name(), shapes.path())->append(shape);
2988 }
2989 else {
2990 createOrRetrieveShapeList(FileName(shapes[0]->fileName()).dir().dirName(), "")->append(shape);
2991 }
2992
2993 }
2994
2995 // We really can't have all of the cubes in memory before
2996 // the OS stops letting us open more files.
2997 // Assume cameras are being used in other parts of code since it's
2998 // unknown
2999 QMutexLocker lock(m_shapeMutex);
3000 emit shapesAdded(m_shapes->last());
3001
3002 Shape *openShape;
3003 foreach (openShape, shapes) {
3004 openShape->closeCube();
3005 }
3006
3007 if (m_numShapesCurrentlyReading == 0) {
3008 m_shapeReadingMutex->unlock();
3009 }
3010 }
3011
3012
3017 QMutableListIterator<ShapeList *> it(*m_shapes);
3018 while (it.hasNext()) {
3019 ShapeList *list = it.next();
3020
3021 int foundElement = list->indexOf((Shape *)imageObj);
3022
3023 if (foundElement != -1) {
3024 list->removeAt(foundElement);
3025 }
3026 }
3027
3028 m_idToShapeMap->remove(m_idToShapeMap->key((Shape *)imageObj));
3029 }
3030
3042 return m_workOrderMutex;
3043 }
3044}
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
ControlNet * controlNet()
Open and return a pointer to the ControlNet for this Control.
Definition Control.cpp:131
Maintains a list of Controls so that control nets can easily be copied from one Project to another,...
Definition ControlList.h:41
void deleteFromDisk(Project *project)
Delete all of the contained Controls from disk.
QString name() const
Get the human-readable name of this control list.
void setName(QString newName)
Set the human-readable name of this control list.
void setPath(QString newPath)
Set the relative path (from the project root) to this control list's folder.
void SetImages(const QString &imageListFile)
Creates the ControlNet's image cameras based on an input file.
IO Handler for Isis Cubes.
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.
Container class for GuiCamera.
Definition GuiCamera.h:70
List of GuiCameras saved as QSharedPointers.
@ FootprintViewProperties
Every display property for footprint views, provided for convenience.
This represents a cube in a project-based GUI interface.
Definition Image.h:105
void closeCube()
Cleans up the Cube pointer.
Definition Image.cpp:283
Internalizes a list of images and allows for operations on the entire list.
Definition ImageList.h:52
void deleteFromDisk(Project *project)
Delete all of the contained Images from disk.
void setPath(QString newPath)
Set the relative path (from the project root) to this image list's folder.
void removeAt(int i)
Removes the image at an index.
void setName(QString newName)
Set the human-readable name of this image list.
QString name() const
Get the human-readable name of this image list.
The main project for ipce.
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:2017
void imageListDeleted(QObject *imageList)
An image list is being deleted from the project.
Definition Project.cpp:2884
void addBundleSolutionInfo(BundleSolutionInfo *bundleSolutionInfo)
Add the given BundleSolutionInfo to the current project.
Definition Project.cpp:1192
void checkActiveControlAndImageList()
Checks if both an active control and active image list have been set.
Definition Project.cpp:1829
static QString cnetRoot(QString projectRoot)
Appends the root directory name 'cnets' to the project.
Definition Project.cpp:2081
void activeImageListSet()
Emitted when an active image list is set.
Shape * shape(QString id)
Return a shape given its id.
Definition Project.cpp:1601
QString targetBodyRoot() const
Accessor for the root directory of the target body data.
Definition Project.cpp:2248
static QString templateRoot(QString projectRoot)
Appends the root directory name 'templates' to the project .
Definition Project.cpp:2187
QMutex * mutex()
Return mutex used for Naif calls.
Definition Project.cpp:1720
ImageList * imageList(QString name)
Return an imagelist given its name.
Definition Project.cpp:1582
void workOrderStarting(WorkOrder *)
Emitted when work order starts.
QList< TemplateList * > templates()
Return all template FileNames.
Definition Project.cpp:2207
bool isTemporaryProject() const
Returns if the project is a temp project or not.
Definition Project.cpp:1629
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:2728
void targetBodyClosed(QObject *targetBodyObj)
A target body is being deleted from the project.
Definition Project.cpp:2955
void setName(QString newName)
Change the project's name (GUI only, doesn't affect location on disk).
Definition Project.cpp:1746
void imageClosed(QObject *image)
An image is being deleted from the project.
Definition Project.cpp:2864
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:924
void controlListAdded(ControlList *controls)
apparently not used?
void addControl(Control *control)
Add the given Control's to the current project.
Definition Project.cpp:956
WorkOrder * lastNotUndoneWorkOrder()
Return the last not undone workorder.
Definition Project.cpp:1667
QDir addTemplateFolder(QString prefix)
Create and navigate to the appropriate template type folder in the project directory.
Definition Project.cpp:1132
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:2305
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:2918
static QString bundleSolutionInfoRoot(QString projectRoot)
Appends the root directory name 'bundle' to the project results directory.
Definition Project.cpp:2295
void deleteAllProjectFiles()
Delete all of the files, that this project stores, from disk.
Definition Project.cpp:2313
QString newProjectRoot() const
Get the top-level folder of the new project.
Definition Project.cpp:1737
void setActiveControl(QString displayName)
Set the Active Control (control network)
Definition Project.cpp:1881
QDir addBundleSolutionInfoFolder(QString folder)
Create and return the name of a folder for placing BundleSolutionInfo.
Definition Project.cpp:1172
void controlClosed(QObject *control)
A control is being deleted from the project.
Definition Project.cpp:2895
QList< TemplateList * > regTemplates()
Return registration template FileNames.
Definition Project.cpp:2228
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:2197
QUndoStack * undoStack()
Returns the Projects stack of QUndoCommands.
Definition Project.cpp:1756
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:2807
QList< WorkOrder * > workOrderHistory()
Get the entire list of work orders that have executed.
Definition Project.cpp:1810
QString resultsRoot() const
Accessor for the root directory of the results data.
Definition Project.cpp:2276
static QString shapeDataRoot(QString projectRoot)
Appends the root directory name 'shapes' to the project .
Definition Project.cpp:2149
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:2840
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:1802
TargetBodyList targetBodies()
Return TargetBodyList in Project.
Definition Project.cpp:2256
void waitForImageReaderFinished()
Locks program if another spot in code is still running and called this function.
Definition Project.cpp:1794
ShapeList * shapeList(QString name)
Return a shapelist given its name.
Definition Project.cpp:1611
bool hasTarget(QString id)
This method checks for the existence of a target based on TargetName.
Definition Project.cpp:2777
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:3016
QList< ShapeList * > shapes()
Return the projects shapelist.
Definition Project.cpp:2168
QMutex * workOrderMutex()
This function returns a QMutex.
Definition Project.cpp:3041
~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:914
void saveHistory(QXmlStreamWriter &stream) const
Serialize the work orders into the given XML.
Definition Project.cpp:849
void clear()
Function to clear out all values in a project essentially making it a new project object.
Definition Project.cpp:457
void addToProject(WorkOrder *)
This executes the WorkOrder and stores it in the project.
Definition Project.cpp:2660
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:2792
QList< TemplateList * > mapTemplates()
Return map template FileNames.
Definition Project.cpp:2218
Control * control(QString id)
Accessor for if the project is clearing or not.
Definition Project.cpp:1161
void createFolders()
This creates the project root, image root, and control net root directories.
Definition Project.cpp:382
static QString resultsRoot(QString projectRoot)
Appends the root directory name 'results' to the project.
Definition Project.cpp:2266
void cnetModified()
When a cnet is modified, set the project state to not clean.
Definition Project.cpp:1986
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:2139
void bundleSolutionInfoClosed(QObject *bundleSolutionInfo)
A BundleSolutionInfo object is being deleted from the project.
Definition Project.cpp:2929
void shapesAdded(ShapeList *shapes)
Emitted when new shape model images are available.
static QStringList images(QStringList)
Verify that the input fileNames are image files.
Definition Project.cpp:892
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:2091
void checkControlsAndImagesAvailable()
Checks if at least one control and image have been added to the project.
Definition Project.cpp:1846
QList< ControlList * > controls()
Return controls in project.
Definition Project.cpp:2100
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:1227
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:1646
void open(QString)
Open the project at the given path.
Definition Project.cpp:1343
ImageList * activeImageList()
Returns the active ImageList.
Definition Project.cpp:2065
QList< BundleSolutionInfo * > bundleSolutionInfo()
Return BundleSolutionInfo objects in Project.
Definition Project.cpp:2285
QString projectRoot() const
Get the top-level folder of the project.
Definition Project.cpp:1728
QString name() const
Get the project's GUI name.
Definition Project.cpp:1687
void setClean(bool value)
Function to change the clean state of the project.
Definition Project.cpp:1657
Control * activeControl()
Return the Active Control (control network)
Definition Project.cpp:1965
void loadBundleSolutionInfo(BundleSolutionInfo *bundleSolutionInfo)
Loads bundle solution info into project.
Definition Project.cpp:1208
void addCamera(Camera *camera)
Adds a new camera to the project.
Definition Project.cpp:2823
QDir addImageFolder(QString prefix)
Create and return the name of a folder for placing images.
Definition Project.cpp:1001
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:872
void relocateProjectRoot(QString newRoot)
This is called when the project is moved.
Definition Project.cpp:2367
void controlListDeleted(QObject *controlList)
An control list is being deleted from the project.
Definition Project.cpp:2903
QString shapeDataRoot() const
Accessor for the root directory of the shape model data.
Definition Project.cpp:2159
bool isOpen()
Accessor to determine whether a current project is Open.
Definition Project.cpp:1637
QList< ImageList * > images()
Return projects imagelist.
Definition Project.cpp:2177
static QString imageDataRoot(QString projectRoot)
Appends the root directory name 'images' to the project .
Definition Project.cpp:2129
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:1571
void addTemplates(TemplateList *templateFiles)
Add new templates to m_mapTemplates or m_regTemplates and update project item model.
Definition Project.cpp:1111
void addShapes(QStringList shapeFiles)
Read the given shape model cube file names as Images and add them to the project.
Definition Project.cpp:1087
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:1030
bool save()
Generic save method to save the state of the project.
Definition Project.cpp:2386
QDir addShapeFolder(QString prefix)
Create and return the name of a folder for placing shape models.
Definition Project.cpp:1058
ControlList * controlList(QString name)
Return controlslist matching name in Project.
Definition Project.cpp:2110
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:327
QString id() const
Get a unique, identifying string associated with this shape.
Definition Shape.cpp:444
Internalizes a list of shapes and allows for operations on the entire list.
Definition ShapeList.h:30
void append(Shape *const &value)
Appends an shape to the shape list.
void deleteFromDisk(Project *project)
Delete all of the contained Shapes from disk.
void removeAt(int i)
Removes the shape at an index.
void setName(QString newName)
Set the human-readable name of this shape list.
QString name() const
Get the human-readable name of this shape list.
void setPath(QString newPath)
Set the relative path (from the project root) to this shape list's folder.
Container class for TargetBody.
Definition TargetBody.h:61
List for holding TargetBodies.
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
void setNext(WorkOrder *nextWorkOrder)
Sets the next WorkOrder in the sequence.
bool isUndoing() const
Returns the WorkOrderUndoing state.
void save(QXmlStreamWriter &stream) const
: Saves a WorkOrder to a data stream.
virtual void redo()
Starts (or enqueues) a redo.
bool isUndoable() const
Returns true if this work order is undoable, otherwise false.
WorkOrder * previous() const
Gets the previous WorkOrder.
bool isUndone() const
Returns the WorkOrder undo status.
virtual bool setupExecution()
This sets up the state for the work order.
bool isSavedToHistory() const
Returns true if this work order is to be shown in History, otherwise false.
virtual void execute()
Execute the workorder.
void setPrevious(WorkOrder *previousWorkOrder)
Sets the previous WorkOrder in the sequence.
bool createsCleanState() const
Returns the CleanState status (whether the Project has been saved to disk or not).
This is free and unencumbered software released into the public domain.
This is free and unencumbered software released into the public domain.
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
QSharedPointer< GuiCamera > GuiCameraQsp
GuiCameraQsp Represents a smart pointer to a GuiCamera object.
Definition GuiCamera.h:156
QSharedPointer< TargetBody > TargetBodyQsp
Defines A smart pointer to a TargetBody obj.
Definition TargetBody.h:182
QString toString(const LinearAlgebra::Vector &vector, int precision)
A global function to format LinearAlgebra::Vector as a QString with the given precision.