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
47#include "BundleSettings.h"
48#include "BundleSolutionInfo.h"
49#include "Camera.h"
50#include "Control.h"
51#include "ControlList.h"
52#include "ControlNet.h"
53#include "CorrelationMatrix.h"
54#include "Cube.h"
55#include "Directory.h"
56#include "Environment.h"
57#include "FileName.h"
58#include "GuiCamera.h"
59#include "GuiCameraList.h"
60#include "ImageList.h"
61#include "ImageReader.h"
62#include "IException.h"
63#include "ProgressBar.h"
64#include "ProjectItem.h"
65#include "ProjectItemModel.h"
66#include "SerialNumberList.h"
69#include "Shape.h"
70#include "ShapeList.h"
71#include "ShapeReader.h"
72#include "Target.h"
73#include "TargetBodyList.h"
74#include "Template.h"
75#include "TemplateList.h"
76#include "WorkOrder.h"
77#include "WorkOrderFactory.h"
78#include "XmlStackedHandlerReader.h"
79
80namespace Isis {
81
82
83
87 Project::Project(Directory &directory, QObject *parent) :
88 QObject(parent) {
89 m_bundleSettings = NULL;
90 m_clearing = false;
91 m_directory = &directory;
92 m_projectRoot = NULL;
93 m_cnetRoot = NULL;
94 m_idToControlMap = NULL;
95 m_idToImageMap = NULL;
96 m_idToShapeMap = NULL;
97 m_idToTargetBodyMap = NULL;
98 m_idToGuiCameraMap = NULL;
99 m_images = NULL;
100 m_imageReader = NULL;
101 m_shapeReader = NULL;
102 m_shapes = NULL;
103 m_mapTemplates = NULL;
104 m_regTemplates = NULL;
105 m_warnings = NULL;
106 m_workOrderHistory = NULL;
107 m_isTemporaryProject = true;
108 m_isOpen = false;
109 m_isClean = true;
110 m_activeControl = NULL;
111 m_activeImageList = NULL;
112
114
115 m_mutex = NULL;
116 m_workOrderMutex = NULL;
117 m_imageReadingMutex = NULL;
118
119 m_numShapesCurrentlyReading = 0;
120 m_shapeMutex = NULL;
121 m_shapeReadingMutex = NULL;
122
123 m_idToControlMap = new QMap<QString, Control *>;
124 m_idToImageMap = new QMap<QString, Image *>;
125 m_idToShapeMap = new QMap<QString, Shape *>;
126 m_idToTargetBodyMap = new QMap<QString, TargetBody *>;
127 m_idToGuiCameraMap = new QMap<QString, GuiCamera *>;
128 m_idToBundleSolutionInfoMap = new QMap<QString, BundleSolutionInfo *>;
129
130 m_name = "Project";
131
132 // Look for old projects
133 QDir tempDir = QDir::temp();
134 QStringList nameFilters;
135 nameFilters.append(Environment::userName() + "_" +
136 QApplication::applicationName() + "_*");
137 tempDir.setNameFilters(nameFilters);
138
139 QStringList existingProjects = tempDir.entryList();
140 bool crashedPreviously = false;
141
142 foreach (QString existingProject, existingProjects) {
143 FileName existingProjectFileName(tempDir.absolutePath() + "/" + existingProject);
144 QString pidString = QString(existingProject).replace(QRegExp(".*_"), "");
145 int otherPid = pidString.toInt();
146
147 if (otherPid != 0) {
148 if ( !QFile::exists("/proc/" + pidString) ) {
149 crashedPreviously = true;
150 int status = system( ("rm -rf '" +
151 existingProjectFileName.expanded() + "' &").toLatin1().data() );
152 if (status != 0) {
153 QString msg = "Executing command [rm -rf" + existingProjectFileName.expanded() +
154 "' &] failed with return status [" + toString(status) + "]";
155 throw IException(IException::Programmer, msg, _FILEINFO_);
156 }
157 }
158 }
159 }
160
161 if (crashedPreviously && false) {
162 QMessageBox::information( NULL,
163 QObject::tr("Crashed"),
164 QObject::tr("It appears %1 crashed. We're sorry.").
165 arg( QApplication::applicationName() ) );
166 }
167
168 QCoreApplication* ipce_app = static_cast<QCoreApplication *>(directory.parent());
169
170 try {
171 QString tmpFolder = QDir::temp().absolutePath() + "/"
172 + Environment::userName() + "_"
173 + QApplication::applicationName() + "_" + QString::number( getpid() );
174 QDir temp(tmpFolder + "/tmpProject");
175 m_projectRoot = new QDir(temp);
176
177 if (ipce_app->arguments().count() == 1) {
179 }
180 }
181 catch (IException &e) {
182 throw IException(e, IException::Programmer, "Error creating project folders.", _FILEINFO_);
183 }
184 catch (std::exception &e) {
185 // e.what()
187 tr("Error creating project folders [%1]").arg( e.what() ), _FILEINFO_);
188 }
189 // TODO TLS 2016-07-13 This seems to only be used by ControlNet when SetTarget is called.
190 // This needs to be better documented, possibly renamed or redesigned??
191 m_mutex = new QMutex;
192 m_workOrderMutex = new QMutex;
193 // image reader
194 m_imageReader = new ImageReader(m_mutex, true);
195
196 connect( m_imageReader, SIGNAL( imagesReady(ImageList) ),
197 this, SLOT( imagesReady(ImageList) ) );
198
199 // Project will be listening for when both cnets and images have been added.
200 // It will emit a signal, controlsAndImagesAvailable, when this occurs.
201 // Directory sets up a listener on the JigsawWorkOrder clone to enable itself
202 // when it hears this signal.
203 connect(this, SIGNAL(imagesAdded(ImageList *)),
204 this, SLOT(checkControlsAndImagesAvailable()));
205 connect(this, SIGNAL(controlListAdded(ControlList *)),
206 this, SLOT(checkControlsAndImagesAvailable()));
207 connect(m_directory, SIGNAL(cleanProject(bool)),
208 this, SLOT(setClean(bool)));
209
210 m_images = new QList<ImageList *>;
211
212 // Shape reader
213 m_shapeMutex = new QMutex;
214
215 m_shapeReader = new ShapeReader(m_shapeMutex, false);
216
217 connect( m_shapeReader, SIGNAL( shapesReady(ShapeList) ),
218 this, SLOT( shapesReady(ShapeList) ) );
219
220 m_shapes = new QList<ShapeList *>;
221
222 m_controls = new QList<ControlList *>;
223
224 m_targets = new TargetBodyList;
225
226 m_mapTemplates = new QList<TemplateList *>;
227
228 m_regTemplates = new QList<TemplateList *>;
229
230 m_guiCameras = new GuiCameraList;
231
232 m_bundleSolutionInfo = new QList<BundleSolutionInfo *>;
233
234 m_warnings = new QStringList;
235 m_workOrderHistory = new QList< QPointer<WorkOrder> >;
236
237 m_imageReadingMutex = new QMutex;
238
239 m_shapeReadingMutex = new QMutex;
240
241 // Listen for when an active control is set and when an active image list is set.
242 // This is used for enabling the JigsawWorkOrder (the Bundle Adjustment menu action).
243// connect(this, &Project::activeControlSet,
244// this, &Project::checkActiveControlAndImageList);
245// connect(this, &Project::activeImageListSet,
246// this, &Project::checkActiveControlAndImageList);
247 // TODO: ken testing
248// m_bundleSettings = NULL;
249// m_bundleSettings = new BundleSettings();
250 }
251
252
257
258
259 if (m_images) {
260 foreach (ImageList *imageList, *m_images) {
261 foreach (Image *image, *imageList) {
262 delete image;
263 }
264
265 delete imageList;
266 }
267
268 delete m_images;
269 m_images = NULL;
270 }
271
272
273 if (m_shapes) {
274 foreach (ShapeList *shapeList, *m_shapes) {
275 foreach (Shape *shape, *shapeList) {
276 delete shape;
277 }
278
279 delete shapeList;
280 }
281
282 delete m_shapes;
283 m_shapes = NULL;
284 }
285
286
287 if (m_controls) {
288 foreach (ControlList *controlList, *m_controls) {
289 foreach (Control *control, *controlList) {
290 delete control;
291 }
292
293 delete controlList;
294 }
295 delete m_controls;
296 m_controls = NULL;
297 }
298
299
300 if (m_mapTemplates) {
301 foreach (TemplateList *templateList, *m_mapTemplates) {
302 foreach (Template *templateFile, *templateList) {
303 delete templateFile;
304 }
305
306 delete templateList;
307 }
308
309 delete m_mapTemplates;
310 m_mapTemplates = NULL;
311 }
312
313
314 if (m_regTemplates) {
315 foreach (TemplateList *templateList, *m_regTemplates) {
316 foreach (Template *templateFile, *templateList) {
317 delete templateFile;
318 }
319
320 delete templateList;
321 }
322
323 delete m_regTemplates;
324 m_regTemplates = NULL;
325 }
326
327
328 m_activeControl = NULL;
329 m_activeImageList = NULL;
330
331 if (m_bundleSolutionInfo) {
332 foreach (BundleSolutionInfo *bundleSolutionInfo, *m_bundleSolutionInfo) {
333 delete bundleSolutionInfo;
334 }
335
336 delete m_bundleSolutionInfo;
337 m_bundleSolutionInfo = NULL;
338 }
339
340 delete m_idToControlMap;
341 m_idToControlMap = NULL;
342
343 delete m_idToImageMap;
344 m_idToImageMap = NULL;
345
346 delete m_idToShapeMap;
347 m_idToShapeMap = NULL;
348
349 delete m_idToTargetBodyMap;
350 m_idToTargetBodyMap = NULL;
351
352 delete m_idToGuiCameraMap;
353 m_idToGuiCameraMap = NULL;
354
355 delete m_idToBundleSolutionInfoMap;
356 m_idToBundleSolutionInfoMap = NULL;
357
358 m_directory = NULL;
359
360 delete m_projectRoot;
361 m_projectRoot = NULL;
362
363 delete m_cnetRoot;
364 m_cnetRoot = NULL;
365
366 delete m_imageReader;
367 delete m_shapeReader;
368
369 delete m_warnings;
370 m_warnings = NULL;
371
372 m_workOrderHistory->removeAll(NULL);
373 m_workOrderHistory = NULL;
374
375 delete m_bundleSettings;
376 m_bundleSettings = NULL;
377 }
378
379
384 QDir dir;
385 if ( !dir.mkpath( m_projectRoot->path() ) ) {
386 warn("Cannot create project directory.");
388 tr("Unable to create folder [%1] when trying to initialize project")
389 .arg(m_projectRoot->path() ),
390 _FILEINFO_);
391 }
392
393 try {
394 if ( !dir.mkdir( cnetRoot() ) ) {
395 QString msg = QString("Unable to create folder [%1] when trying to initialize project")
396 .arg( cnetRoot() );
397 warn(msg);
398 throw IException(IException::Io, msg, _FILEINFO_);
399 }
400
401 if ( !dir.mkdir( imageDataRoot() ) ) {
402 QString msg = QString("Unable to create folder [%1] when trying to initialize project")
403 .arg( imageDataRoot() );
404 warn(msg);
405 throw IException(IException::Io, msg, _FILEINFO_);
406 }
407
408 if ( !dir.mkdir( shapeDataRoot() ) ) {
409 QString msg = QString("Unable to create folder [%1] when trying to initialize project")
410 .arg( shapeDataRoot() );
411 warn(msg);
412 throw IException(IException::Io, msg, _FILEINFO_);
413 }
414
415 if ( !dir.mkdir( resultsRoot() ) ) {
416 QString msg = QString("Unable to create folder [%1] when trying to initialize project")
417 .arg( resultsRoot() );
418 warn(msg);
419 throw IException(IException::Io, msg, _FILEINFO_);
420 }
421 if ( !dir.mkdir( bundleSolutionInfoRoot() ) ) {
422 QString msg = QString("Unable to create folder [%1] when trying to initialize project")
423 .arg( bundleSolutionInfoRoot() );
424 warn(msg);
425 throw IException(IException::Io, msg, _FILEINFO_);
426 }
427 if ( !dir.mkdir( templateRoot() ) ) {
428 QString msg = QString("Unable to create folder [%1] when trying to initialize project")
429 .arg( templateRoot() );
430 warn(msg);
431 throw IException(IException::Io, msg, _FILEINFO_);
432 }
433 if ( !dir.mkdir( templateRoot() + "/maps" ) ) {
434 QString msg = QString("Unable to create folder [%1] when trying to initialize project")
435 .arg( templateRoot() + "/maps" );
436 warn(msg);
437 throw IException(IException::Io, msg, _FILEINFO_);
438 }
439 if ( !dir.mkdir( templateRoot() + "/registrations" ) ) {
440 QString msg = QString("Unable to create folder [%1] when trying to initialize project")
441 .arg( templateRoot() + "/registrations" );
442 warn(msg);
443 throw IException(IException::Io, msg, _FILEINFO_);
444 }
445 }
446 catch (...) {
447 warn("Failed to create project directory structure");
448 throw;
449 }
450 }
451
452
459 m_clearing = true;
460
461 // We need to look through the project.xml and remove every directory not in the project
462 QStringList shapeDirList;
463 bool shapes = false;
464 QStringList imageDirList;
465 bool images = false;
466 QStringList cnetDirList;
467 bool controls = false;
468 QStringList mapTemplateDirList;
469 bool mapTemplates = false;
470 QStringList regTemplateDirList;
471 bool regTemplates = false;
472 QStringList bundleDirList;
473 bool bundles = false;
474 QFile projectXml(projectRoot() + "/project.xml");
475
476 if (projectXml.open(QIODevice::ReadOnly)) {
477 QTextStream projectXmlInput(&projectXml);
478
479 while (!projectXmlInput.atEnd() ) {
480
481 QString line = projectXmlInput.readLine();
482
483 if (controls || line.contains("<controlNets>") ) {
484 controls = true;
485
486 if (line.contains("</controlNets>") ) {
487 controls = false;
488 }
489
490 else if (!line.contains("<controlNets>") ) {
491 cnetDirList.append(line.split('"').at(3));
492 }
493 }
494
495 else if (images || line.contains("<imageLists>") ) {
496 images = true;
497
498 if (line.contains("</imageLists>")) {
499 images = false;
500 }
501
502 else if (!line.contains("<imageLists>") ) {
503 imageDirList.append(line.split('"').at(3).simplified());
504 }
505 }
506
507 else if (shapes || line.contains("<shapeLists>")) {
508 shapes = true;
509
510 if (line.contains("</shapeLists>") ) {
511 shapes = false;
512 }
513
514 else if (!line.contains("<shapeLists>") ) {
515 shapeDirList.append(line.split('"').at(3));
516 }
517 }
518
519 else if (mapTemplates || line.contains("<mapTemplateLists>") ) {
520 mapTemplates = true;
521
522 if (line.contains("</mapTemplateLists>") ) {
523 mapTemplates = false;
524 }
525
526 else if (!line.contains("<mapTemplateLists>") ) {
527 QList<QString> components = line.split('"');
528 mapTemplateDirList.append(components.at(5));
529 }
530 }
531
532 else if (regTemplates || line.contains("<regTemplateLists>") ) {
533 regTemplates = true;
534
535 if (line.contains("</regTemplateLists>") ) {
536 regTemplates = false;
537 }
538
539 else if (!line.contains("<regTemplateLists>") ) {
540 QList<QString> components = line.split('"');
541 regTemplateDirList.append(components.at(5));
542 }
543 }
544
545 else if (bundles || line.contains("<bundleSolutionInfo>") ) {
546 bundles = true;
547
548 if (line.contains("</bundleSolutionInfo>") ) {
549 bundles = false;
550 }
551
552 else if (line.contains("<runTime>") ) {
553 bundleDirList.append(line.split('>').at(1).split('<').at(0));
554 }
555 }
556 }
557
558 QDir cnetsDir(m_projectRoot->path() + "/cnets/");
559 cnetsDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
560 QStringList cnetsList = cnetsDir.entryList();
561 foreach (QString dir, cnetsList) {
562 dir = dir.simplified();
563
564 if ( !cnetDirList.contains(dir) ) {
565 QDir tempDir(cnetsDir.path() + "/" + dir);
566 tempDir.removeRecursively();
567 }
568 }
569
570 QDir imagesDir(m_projectRoot->path() + "/images/");
571 imagesDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
572 QStringList imagesList = imagesDir.entryList();
573 foreach (QString dir, imagesList) {
574 dir = dir.simplified();
575
576 if ( !imageDirList.contains(dir) ) {
577 QDir tempDir(imagesDir.path() + "/" + dir);
578 tempDir.removeRecursively();
579 }
580 }
581
582 QDir shapesDir(m_projectRoot->path() + "/shapes/");
583 shapesDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
584 QStringList shapesList = shapesDir.entryList();
585 foreach (QString dir, shapesList) {
586 dir = dir.simplified();
587
588 if ( !shapeDirList.contains(dir) ) {
589 QDir tempDir(shapesDir.path() + "/" + dir);
590 tempDir.removeRecursively();
591 }
592 }
593
594 QDir mapTemplatesDir(m_projectRoot->path() + "/templates/maps");
595 mapTemplatesDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
596 QStringList mapTemplatesList = mapTemplatesDir.entryList();
597 foreach (QString dir, mapTemplatesList) {
598 dir = dir.simplified();
599
600 if ( !mapTemplateDirList.contains("maps/" + dir) ) {
601 QDir tempDir(mapTemplatesDir.path() + "/" + dir);
602 tempDir.removeRecursively();
603 }
604 }
605
606 QDir regTemplatesDir(m_projectRoot->path() + "/templates/registrations");
607 regTemplatesDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
608 QStringList regTemplatesList = regTemplatesDir.entryList();
609 foreach (QString dir, regTemplatesList) {
610 dir = dir.simplified();
611
612 if ( !regTemplateDirList.contains("registrations/" + dir)) {
613 QDir tempDir(regTemplatesDir.path() + "/" + dir);
614 tempDir.removeRecursively();
615 }
616 }
617
618 QDir bundlesDir(m_projectRoot->path() + "/results/bundle/");
619 bundlesDir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
620 QStringList bundleList = bundlesDir.entryList();
621 foreach (QString dir, bundleList) {
622 dir = dir.simplified();
623
624 if ( !bundleDirList.contains(dir) ) {
625 QDir tempDir(bundlesDir.path() + "/" + dir);
626 tempDir.removeRecursively();
627 }
628 }
629
630 projectXml.close();
631 }
632
633 try {
634 QString tmpFolder = QDir::temp().absolutePath() + "/"
635 + Environment::userName() + "_"
636 + QApplication::applicationName() + "_" + QString::number( getpid() );
637 QDir temp(tmpFolder + "/tmpProject");
638 m_projectRoot = new QDir(temp);
639 }
640
641 catch (IException &e) {
642 throw IException(e, IException::Programmer, "Error creating project folders.", _FILEINFO_);
643 }
644
645 catch (std::exception &e) {
647 tr("Error creating project folders [%1]").arg( e.what() ), _FILEINFO_);
648 }
649
650 m_images->clear();
651 m_shapes->clear();
652 m_controls->clear();
653 m_mapTemplates->clear();
654 m_regTemplates->clear();
655 m_targets->clear();
656 m_guiCameras->clear();
657 m_bundleSolutionInfo->clear();
658 m_workOrderHistory->clear();
659
660 directory()->clean();
661 setClean(true);
662 }
663
664
665 bool Project::clearing() {
666 return m_clearing;
667 }
668
669
670 ImageList *Project::createOrRetrieveImageList(QString name, QString path) {
671 ImageList *result = imageList(name);
672 if (!result) {
673 result = new ImageList;
674
675 result->setName(name);
676 if (path == "") {
677 result->setPath(name);
678 }
679 else {
680 result->setPath(path);
681 }
682
683 connect( result, SIGNAL( destroyed(QObject *) ),
684 this, SLOT( imageListDeleted(QObject *) ) );
685 m_images->append(result);
686 }
687 return result;
688 }
689
690
691 ShapeList *Project::createOrRetrieveShapeList(QString name, QString path) {
692 ShapeList *result = shapeList(name);
693 if (!result) {
694 result = new ShapeList;
695
696 result->setName(name);
697 if (path == "") {
698 result->setPath(name);
699 }
700 else {
701 result->setPath(path);
702 }
703
704 connect( result, SIGNAL( destroyed(QObject *) ),
705 this, SLOT( shapeListDeleted(QObject *) ) );
706 m_shapes->append(result);
707 }
708 return result;
709 }
710
711
725 void Project::save(QXmlStreamWriter &stream, FileName newProjectRoot) const {
726 stream.writeStartElement("project");
727
728 stream.writeAttribute("name", m_name);
729
730 if ( !m_controls->isEmpty() ) {
731 stream.writeStartElement("controlNets");
732
733 for (int i = 0; i < m_controls->count(); i++) {
734 m_controls->at(i)->save(stream, this, newProjectRoot);
735 }
736
737 stream.writeEndElement();
738 }
739
740 if ( !m_images->isEmpty() ) {
741 stream.writeStartElement("imageLists");
742 for (int i = 0; i < m_images->count(); i++) {
743 m_images->at(i)->save(stream, this, newProjectRoot);
744 }
745
746 stream.writeEndElement();
747 }
748
749 if ( !m_shapes->isEmpty() ) {
750 stream.writeStartElement("shapeLists");
751
752 for (int i = 0; i < m_shapes->count(); i++) {
753 m_shapes->at(i)->save(stream, this, newProjectRoot);
754 }
755
756 stream.writeEndElement();
757 }
758
759 if ( !m_mapTemplates->isEmpty() ) {
760 stream.writeStartElement("mapTemplateLists");
761
762 for (int i = 0; i < m_mapTemplates->count(); i++) {
763 m_mapTemplates->at(i)->save(stream, this, newProjectRoot);
764 }
765
766 stream.writeEndElement();
767 }
768
769 if ( !m_regTemplates->isEmpty() ) {
770 stream.writeStartElement("regTemplateLists");
771
772 for (int i = 0; i < m_regTemplates->count(); i++) {
773 m_regTemplates->at(i)->save(stream, this, newProjectRoot);
774 }
775
776 stream.writeEndElement();
777 }
778
779 // TODO: Finish implementing serialization of TargetBody & GuiCameras
780// if (!m_targets->isEmpty()) {
781// stream.writeStartElement("targets");
782//
783// for (int i = 0; i < m_targets->count(); i++) {
784// m_targets->at(i)->save(stream, this, newProjectRoot);
785// }
786//
787// stream.writeEndElement();
788// }
789//
790// if (!m_guiCameras->isEmpty()) {
791// stream.writeStartElement("cameras");
792//
793// for (int i = 0; i < m_guiCameras->count(); i++) {
794// m_guiCameras->at(i)->save(stream, this, newProjectRoot);
795// }
796//
797// stream.writeEndElement();
798// }
799
800// Write general look of gui, including docked widges
801// QVariant geo_data = saveGeometry();
802// QVariant layout_data = saveState();
803//
804// stream.writeStartElement("dockRestore");
805// stream.writeAttribute("geometry", geo_data.toString());
806// stream.writeAttribute("state", layout_data.toString());
807
808
809 if ( !m_bundleSolutionInfo->isEmpty() ) {
810 stream.writeStartElement("results");
811
812 for (int i = 0; i < m_bundleSolutionInfo->count(); i++) {
813 m_bundleSolutionInfo->at(i)->save(stream, this, newProjectRoot);
814 }
815
816 stream.writeEndElement();
817 }
818
819 if (m_activeImageList) {
820 stream.writeStartElement("activeImageList");
821 stream.writeAttribute("displayName", m_activeImageList->name());
822 stream.writeEndElement();
823 }
824
825 if (m_activeControl) {
826 stream.writeStartElement("activeControl");
827 stream.writeAttribute("displayName", m_activeControl->displayProperties()->displayName());
828 stream.writeEndElement();
829 }
830
831 stream.writeEndElement();
832 }
833
834
850 void Project::saveHistory(QXmlStreamWriter &stream) const {
851 stream.writeStartElement("history");
852
853 foreach (WorkOrder *workOrder, *m_workOrderHistory) {
854 if (workOrder) {
855 workOrder->save(stream);
856 }
857 }
858
859 stream.writeEndElement();
860 }
861
873 void Project::saveWarnings(QXmlStreamWriter &stream) const {
874 stream.writeStartElement("warnings");
875
876 foreach (QString warning, *m_warnings) {
877 stream.writeStartElement("warning");
878 stream.writeAttribute("text", warning);
879 stream.writeEndElement();
880 }
881
882 stream.writeEndElement();
883 }
884
885
892 // TODO: thread via ImageReader
894
895 QStringList result;
896
897 foreach (QString fileName, fileNames) {
898 try {
899 Cube tmp(fileName);
900 result.append(fileName);
901 }
902 catch (IException &) {
903 }
904 }
905
906 return result;
907 }
908
909
916 return m_imageReader->actions(ImageDisplayProperties::FootprintViewProperties);
917 }
918
919
925 QDir Project::addCnetFolder(QString prefix) {
926 QDir cnetFolder = cnetRoot();
927 prefix += "%1";
928 int prefixCounter = 0;
929
930 QString numberedPrefix;
931 do {
932 prefixCounter++;
933 numberedPrefix = prefix.arg( QString::number(prefixCounter) );
934 }
935 while ( cnetFolder.exists(numberedPrefix) );
936
937 if ( !cnetFolder.mkpath(numberedPrefix) ) {
939 tr("Could not create control network directory [%1] in [%2].")
940 .arg(numberedPrefix).arg( cnetFolder.absolutePath() ),
941 _FILEINFO_);
942 }
943
944 cnetFolder.cd(numberedPrefix);
945
946 m_currentCnetFolder = cnetFolder;
947
948 return cnetFolder;
949 }
950
951
958
959 connect( control, SIGNAL( destroyed(QObject *) ),
960 this, SLOT( controlClosed(QObject *) ) );
961 connect( this, SIGNAL( projectRelocated(Project *) ),
962 control, SLOT( updateFileName(Project *) ) );
963
964 createOrRetrieveControlList( FileName( control->fileName() ).dir().dirName(), "" )->append(control);
965
966 (*m_idToControlMap)[control->id()] = control;
967
968 emit controlAdded(control);
969 }
970
971
972 ControlList *Project::createOrRetrieveControlList(QString name, QString path) {
973 ControlList *result = controlList(name);
974
975 if (!result) {
976 result = new ControlList;
977
978 result->setName(name);
979 if (path == "") {
980 result->setPath(name);
981 }
982 else {
983 result->setPath(path);
984 }
985
986 connect( result, SIGNAL( destroyed(QObject *) ),
987 this, SLOT( controlListDeleted(QObject *) ) );
988
989 m_controls->append(result);
990 emit controlListAdded(result);
991 }
992
993 return result;
994 }
995
996
1002 QDir Project::addImageFolder(QString prefix) {
1003 QDir imageFolder = imageDataRoot();
1004 prefix += "%1";
1005 int prefixCounter = 0;
1006
1007 QString numberedPrefix;
1008 do {
1009 prefixCounter++;
1010 numberedPrefix = prefix.arg( QString::number(prefixCounter) );
1011 }
1012 while ( imageFolder.exists(numberedPrefix) );
1013
1014 if ( !imageFolder.mkpath(numberedPrefix) ) {
1016 tr("Could not create image directory [%1] in [%2].")
1017 .arg(numberedPrefix).arg( imageFolder.absolutePath() ),
1018 _FILEINFO_);
1019 }
1020
1021 imageFolder.cd(numberedPrefix);
1022
1023 return imageFolder;
1024 }
1025
1026
1032 if (m_numImagesCurrentlyReading == 0) {
1033 m_imageReadingMutex->lock();
1034 }
1035
1036 m_numImagesCurrentlyReading += imageFiles.count();
1037 m_imageReader->read(imageFiles);
1038 }
1039
1040
1046 imagesReady(newImages);
1047
1048 // The each
1049 emit guiCamerasAdded(m_guiCameras);
1050 emit targetsAdded(m_targets);
1051 }
1052
1053
1059 QDir Project::addShapeFolder(QString prefix) {
1060 QDir shapeFolder = shapeDataRoot();
1061 prefix += "%1";
1062 int prefixCounter = 0;
1063
1064 QString numberedPrefix;
1065 do {
1066 prefixCounter++;
1067 numberedPrefix = prefix.arg( QString::number(prefixCounter) );
1068 }
1069 while ( shapeFolder.exists(numberedPrefix) );
1070
1071 if ( !shapeFolder.mkpath(numberedPrefix) ) {
1073 tr("Could not create shape directory [%1] in [%2].")
1074 .arg(numberedPrefix).arg( shapeFolder.absolutePath() ),
1075 _FILEINFO_);
1076 }
1077
1078 shapeFolder.cd(numberedPrefix);
1079
1080 return shapeFolder;
1081 }
1082
1083
1089 if (m_numShapesCurrentlyReading == 0) {
1090 m_shapeReadingMutex->lock();
1091 }
1092
1093 m_numShapesCurrentlyReading += shapeFiles.count();
1094 m_shapeReader->read(shapeFiles);
1095 }
1096
1097
1103 shapesReady(newShapes);
1104 }
1105
1106
1113 foreach (Template *templateFile, *templateList) {
1114 connect( this, SIGNAL( projectRelocated(Project *) ),
1115 templateFile, SLOT( updateFileName(Project *) ) );
1116 }
1117 if (templateList->type() == "maps") {
1118 m_mapTemplates->append(templateList);
1119 }
1120 else if (templateList->type() == "registrations") {
1121 m_regTemplates->append(templateList);
1122 }
1123
1124 emit templatesAdded(templateList);
1125 }
1126
1127
1133 QDir Project::addTemplateFolder(QString prefix) {
1134 QDir templateFolder = templateRoot();
1135 prefix += "%1";
1136 int prefixCounter = 0;
1137 QString numberedPrefix;
1138
1139 do {
1140 prefixCounter++;
1141 numberedPrefix = prefix.arg( QString::number(prefixCounter) );
1142 }
1143 while ( templateFolder.exists(numberedPrefix) );
1144
1145 if ( !templateFolder.mkpath(numberedPrefix) ) {
1147 tr("Could not create template directory [%1] in [%2].")
1148 .arg(numberedPrefix).arg( templateFolder.absolutePath() ),
1149 _FILEINFO_);
1150 }
1151
1152 templateFolder.cd(numberedPrefix);
1153
1154 return templateFolder;
1155 }
1156
1157
1163 return (*m_idToControlMap)[id];
1164 }
1165
1166
1174 QDir bundleSolutionInfoFolder(bundleSolutionInfoRoot());
1175
1176 if (!bundleSolutionInfoFolder.mkpath(folder)) {
1178 tr("Could not create bundle results directory [%1] in [%2].")
1179 .arg(folder).arg(bundleSolutionInfoFolder.absolutePath()),
1180 _FILEINFO_);
1181 }
1182
1183 bundleSolutionInfoFolder.cd(folder);
1184 return bundleSolutionInfoFolder;
1185 }
1186
1187
1194 connect(bundleSolutionInfo, SIGNAL(destroyed(QObject *)),
1195 this, SLOT(bundleSolutionInfoClosed(QObject *)));//???
1196 connect(this, SIGNAL(projectRelocated(Project *)),
1197 bundleSolutionInfo, SLOT(updateFileName(Project *)));//DNE???
1198
1199
1201 }
1202
1203
1210 m_bundleSolutionInfo->append(bundleSolutionInfo);
1211
1212 // add BundleSolutionInfo to project's m_idToBundleSolutionInfoMap
1213 (*m_idToBundleSolutionInfoMap)[bundleSolutionInfo->id()] = bundleSolutionInfo;
1214
1215 // add BundleSolutionInfo's control to project's m_idToControlMap
1216 (*m_idToControlMap)[bundleSolutionInfo->control()->id()] = bundleSolutionInfo->control();
1217
1219 }
1220
1221
1229 return m_directory;
1230 }
1231
1232
1233 void Project::writeSettings() {
1234
1235 QString appName = QApplication::applicationName();
1236
1237
1238 QSettings globalSettings(
1239 FileName("$HOME/.Isis/" + appName + "/" + appName + "_" + "Project.config")
1240 .expanded(),
1241 QSettings::NativeFormat);
1242
1243 globalSettings.beginGroup("recent_projects");
1244 QStringList keys = globalSettings.allKeys();
1245 QMap<QString,QString> recentProjects;
1246
1247 foreach (QString key,keys) {
1248
1249 recentProjects[key]=globalSettings.value(key).toString();
1250
1251 }
1252
1253 QList<QString> projectPaths = recentProjects.values();
1254
1255 if (keys.count() >= m_maxRecentProjects) {
1256
1257 //Clear out the recent projects before repopulating this group
1258 globalSettings.remove("");
1259
1260
1261
1262 //If the currently open project is a project that has been saved and is not within the current
1263 //list of recently open projects, then remove the oldest project from the list.
1264 if (!this->projectRoot().contains("tmpProject") && !projectPaths.contains(this->projectRoot()) ) {
1265 QString s=keys.first();
1266 recentProjects.remove( s );
1267 }
1268
1269 //If the currently open project is already contained within the list,
1270 //then remove the earlier reference.
1271
1272 if (projectPaths.contains(this->projectRoot())) {
1273 QString key = recentProjects.key(this->projectRoot());
1274 recentProjects.remove(key);
1275 }
1276
1278
1279 //Iterate through the recentProjects QMap and set the <key,val> pairs.
1280 for (i=recentProjects.begin();i!=recentProjects.end();i++) {
1281
1282 globalSettings.setValue(i.key(),i.value());
1283
1284 }
1285
1286 //Get a unique time value for generating a key
1287 long t0 = QDateTime::currentMSecsSinceEpoch();
1288 QString projName = this->name();
1289
1290 QString t0String=QString::number(t0);
1291
1292 //Save the project location
1293 if (!this->projectRoot().contains("tmpProject") ) {
1294 globalSettings.setValue(t0String+"%%%%%"+projName,this->projectRoot());
1295
1296 }
1297
1298 }
1299
1300 //The numer of recent open projects is less than m_maxRecentProjects
1301 else {
1302
1303 //Clear out the recent projects before repopulating this group
1304 globalSettings.remove("");
1305 if (projectPaths.contains(this->projectRoot())) {
1306 QString key = recentProjects.key(this->projectRoot());
1307 recentProjects.remove(key);
1308 }
1310
1311 //Iterate through the recentProjects QMap and set the <key,val> pairs.
1312 for ( i=recentProjects.begin(); i!=recentProjects.end(); i++ ) {
1313 globalSettings.setValue(i.key(),i.value());
1314 }
1315
1316 long t0 = QDateTime::currentMSecsSinceEpoch();
1317 QString projName = this->name();
1318 QString t0String=QString::number(t0);
1319
1320 //if (!this->projectRoot().contains("tmpProject") && !projectPaths.contains( this->projectRoot() ) ) {
1321 if (!this->projectRoot().contains("tmpProject") ) {
1322 globalSettings.setValue(t0String+"%%%%%"+projName,this->projectRoot());
1323 }
1324
1325 }
1326
1327
1328 globalSettings.endGroup();
1329 }
1330
1331
1344 void Project::open(QString projectPathStr) {
1345 // Expand projectPathStr to contain absolute path
1346 QString projectAbsolutePathStr = QDir(projectPathStr).absolutePath();
1347
1348 QString projectXmlPath = projectAbsolutePathStr + "/project.xml";
1349 QFile file(projectXmlPath);
1350
1351 if ( !file.open(QFile::ReadOnly) ) {
1353 QString("Unable to open [%1] with read access")
1354 .arg(projectXmlPath),
1355 _FILEINFO_);
1356 }
1357
1358 QString projectXmlHistoryPath = projectAbsolutePathStr + "/history.xml";
1359 QFile historyFile(projectXmlHistoryPath);
1360
1361 if ( !historyFile.open(QFile::ReadOnly) ) {
1363 QString("Unable to open [%1] with read access")
1364 .arg(projectXmlHistoryPath),
1365 _FILEINFO_);
1366 }
1367
1368 QString projectXmlWarningsPath = projectAbsolutePathStr + "/warnings.xml";
1369 QFile warningsFile(projectXmlWarningsPath);
1370
1371 if (!warningsFile.open(QFile::ReadOnly)) {
1373 QString("Unable to open [%1] with read access")
1374 .arg(projectXmlWarningsPath),
1375 _FILEINFO_);
1376 }
1377
1378 QString directoryXmlPath = projectAbsolutePathStr + "/directory.xml";
1379 QFile directoryFile(directoryXmlPath);
1380
1381 if (!directoryFile.open(QFile::ReadOnly)) {
1383 QString("Unable to open [%1] with read access")
1384 .arg(directoryXmlPath),
1385 _FILEINFO_);
1386 }
1387
1388 if (isOpen() || !isClean()) {
1389 clear();
1390 }
1391 m_clearing = false;
1392 m_isTemporaryProject = false;
1393
1394 XmlHandler handler(this);
1395
1397 reader.pushContentHandler(&handler);
1398 reader.setErrorHandler(&handler);
1399
1400 QDir oldProjectRoot(*m_projectRoot);
1401 *m_projectRoot = QDir(projectAbsolutePathStr);
1402
1403 QXmlInputSource xmlInputSource(&file);
1404
1405 //This prevents the project from not loading if everything
1406 //can't be loaded, and outputs the warnings/errors to the
1407 //Warnings Tab
1408 try {
1409 reader.parse(xmlInputSource);
1410 }
1411 catch (IException &e) {
1412 directory()->showWarning(QString("Failed to open project completely [%1]")
1413 .arg(projectAbsolutePathStr));
1414 directory()->showWarning(e.toString());
1415 }
1416 catch (std::exception &e) {
1417 directory()->showWarning(QString("Failed to open project completely[%1]")
1418 .arg(projectAbsolutePathStr));
1419 directory()->showWarning(e.what());
1420 }
1421
1422 reader.pushContentHandler(&handler);
1423 QXmlInputSource xmlHistoryInputSource(&historyFile);
1424
1425 try {
1426 reader.parse(xmlHistoryInputSource);
1427 }
1428
1429 catch (IException &e) {
1430 directory()->showWarning(QString("Failed to read history from project[%1]")
1431 .arg(projectAbsolutePathStr));
1432 directory()->showWarning(e.toString());
1433 }
1434 catch (std::exception &e) {
1435 directory()->showWarning(QString("Failed to read history from project[%1]")
1436 .arg(projectAbsolutePathStr));
1437 directory()->showWarning(e.what());
1438 }
1439
1440 reader.pushContentHandler(&handler);
1441
1442 QXmlInputSource xmlWarningsInputSource(&warningsFile);
1443
1444 if (!reader.parse(xmlWarningsInputSource)) {
1445 warn(tr("Failed to read warnings from project [%1]").arg(projectAbsolutePathStr));
1446 }
1447
1448 reader.pushContentHandler(&handler);
1449
1450 QXmlInputSource xmlDirectoryInputSource(&directoryFile);
1451
1452 try {
1453 reader.parse(xmlDirectoryInputSource);
1454 }
1455 catch (IException &e) {
1456 directory()->showWarning(QString("Failed to read GUI state from project[%1]")
1457 .arg(projectAbsolutePathStr));
1458 directory()->showWarning(e.toString());
1459
1460 }
1461 catch (std::exception &e) {
1462 directory()->showWarning(QString("Failed to read GUI state from project[%1]")
1463 .arg(projectAbsolutePathStr));
1464 directory()->showWarning(e.what());
1465 }
1466
1467 QDir bundleRoot(bundleSolutionInfoRoot());
1468 if (bundleRoot.exists()) {
1469 // get QFileInfo for each directory in the bundle root
1470 bundleRoot.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::NoSymLinks); // sym links ok???
1471
1472 QFileInfoList bundleDirs = bundleRoot.entryInfoList();
1473
1474 for (int dirListIndex = 0; dirListIndex < bundleDirs.size(); dirListIndex++) {
1475
1476 // get QFileInfo for each file in this directory
1477 QDir bundleSolutionDir(bundleDirs[dirListIndex].absoluteFilePath());
1478 bundleSolutionDir.setFilter(QDir::Files | QDir::NoSymLinks); // sym links ok???
1479
1480// QFileInfoList bundleSolutionFiles = bundleSolutionDir.entryInfoList();
1481// for (int fileListIndex = 0; fileListIndex < bundleSolutionFiles.size(); fileListIndex++) {
1482// // if the file is an hdf file with BundleSolutionInfo object, add it to the project tree
1483// if (bundleSolutionFiles[fileListIndex].fileName().contains("_BundleSolutionInfo.hdf")) {
1484// QString absoluteFileName = bundleSolutionFiles[fileListIndex].absoluteFilePath();
1485// FileName solutionFile(bundleSolutionFiles[fileListIndex].absoluteFilePath());
1486// loadBundleSolutionInfo(new BundleSolutionInfo(solutionFile));
1487// }
1488// }
1489 }
1490 }
1491 m_isOpen = true;
1492
1493 setClean(true);
1494 emit projectLoaded(this);
1495 }
1496
1497
1498 QProgressBar *Project::progress() {
1499 return m_imageReader->progress();
1500 }
1501
1502
1508 Image *Project::image(QString id) {
1509
1510 return (*m_idToImageMap)[id];
1511 }
1512
1513
1520 QListIterator<ImageList *> it(*m_images);
1521
1522 ImageList *result = NULL;
1523 while (it.hasNext() && !result) {
1524 ImageList *list = it.next();
1525
1526 if (list->name() == name) result = list;
1527 }
1528
1529 return result;
1530 }
1531
1532
1538 Shape *Project::shape(QString id) {
1539 return (*m_idToShapeMap)[id];
1540 }
1541
1542
1549 QListIterator<ShapeList *> it(*m_shapes);
1550
1551 ShapeList *result = NULL;
1552 while (it.hasNext() && !result) {
1553 ShapeList *list = it.next();
1554
1555 if (list->name() == name) result = list;
1556 }
1557
1558 return result;
1559 }
1560
1561
1567 return m_isTemporaryProject;
1568 }
1569
1570
1575 return m_isOpen;
1576 }
1577
1578
1584 return m_isClean;
1585 }
1586
1587
1594 void Project::setClean(bool value) {
1595 m_isClean = value;
1596 m_undoStack.cleanChanged(value);
1597 }
1598
1599
1605 WorkOrder *result = NULL;
1606 QListIterator< QPointer<WorkOrder> > it(*m_workOrderHistory);
1607 it.toBack();
1608
1609 while ( !result && it.hasPrevious() ) {
1610 WorkOrder *workOrder = it.previous();
1611
1612 if ( !workOrder->isUndone() && !workOrder->isUndoing() ) {
1613 result = workOrder;
1614 }
1615 }
1616
1617 return result;
1618 }
1619
1620
1624 QString Project::name() const {
1625 return m_name;
1626 }
1627
1628
1634 const WorkOrder *result = NULL;
1635 QListIterator< QPointer<WorkOrder> > it(*m_workOrderHistory);
1636 it.toBack();
1637
1638 while ( !result && it.hasPrevious() ) {
1639 WorkOrder *workOrder = it.previous();
1640
1641 if ( !workOrder->isUndone() && !workOrder->isUndoing() ) {
1642 result = workOrder;
1643 }
1644 }
1645
1646 return result;
1647 }
1648
1649
1657 QMutex *Project::mutex() {
1658 return m_mutex;
1659 }
1660
1661
1665 QString Project::projectRoot() const {
1666 return m_projectRoot->path();
1667 }
1668
1669
1674 QString Project::newProjectRoot() const {
1675 return m_newProjectRoot;
1676 }
1677
1678
1683 void Project::setName(QString newName) {
1684 m_name = newName;
1685 emit nameChanged(m_name);
1686 }
1687
1688
1693 QUndoStack *Project::undoStack() {
1694 return &m_undoStack;
1695 }
1696
1697
1698 QString Project::nextImageListGroupName() {
1699 int numLists = m_images->size();
1700 QString maxName = "";
1701 QString newGroupName = "Group";
1702
1703 foreach (ImageList *imageList, *m_images) {
1704 QString name = imageList->name();
1705 if ( !name.contains("Group") ) continue;
1706 if ( maxName.isEmpty() ) {
1707 maxName = name;
1708 }
1709 else if (name > maxName) {
1710 maxName = name;
1711 }
1712 }
1713
1714 if ( maxName.isEmpty() ) {
1715 newGroupName += QString::number(numLists+1);
1716 }
1717 else {
1718 int maxNum = maxName.remove("Group").toInt();
1719 maxNum++;
1720
1721 newGroupName += QString::number(maxNum);
1722 }
1723 return newGroupName;
1724
1725 }
1726
1727
1732 QMutexLocker locker(m_imageReadingMutex);
1733 }
1734
1735
1740 QMutexLocker locker(m_shapeReadingMutex);
1741 }
1742
1743
1747 QList<WorkOrder *> Project::workOrderHistory() {
1748 QList<WorkOrder *> result;
1749 foreach (WorkOrder *workOrder, *m_workOrderHistory) {
1750 result.append(workOrder);
1751 }
1752
1753 return result;
1754 }
1755
1756
1767 if (m_activeControl && m_activeImageList) {
1769 }
1770 }
1771
1772
1784 if (controls().count() > 0 && images().count() > 0) {
1786 }
1787 }
1788
1789
1818 void Project::setActiveControl(QString displayName) {
1819 Control *previousControl = m_activeControl;
1820 if (m_activeControl) {
1821
1822 // If the current active control has been modified, ask user if they want to save or discard
1823 // changes.
1824 if (m_activeControl->isModified()) {
1825 QMessageBox msgBox;
1826 msgBox.setText("Save current active control");
1827 msgBox.setInformativeText("The current active control has been modified. Do you want "
1828 "to save before setting a new active control?");
1829 msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
1830 msgBox.setDefaultButton(QMessageBox::Save);
1831 int ret = msgBox.exec();
1832 switch (ret) {
1833 // Save current active control
1834 case QMessageBox::Save:
1835 m_activeControl->write();
1836 break;
1837 // Discard any changes made to cnet
1838 case QMessageBox::Discard:
1839 // Close, then re-open effectively discarding edits
1840 m_activeControl->closeControlNet();
1841 m_activeControl->openControlNet();
1842 emit discardActiveControlEdits();
1843 break;
1844 // Cancel operation
1845 case QMessageBox::Cancel:
1846 return;
1847 }
1848 }
1849 emit activeControlSet(false);
1850 ProjectItem *item = directory()->model()->findItemData(m_activeControl->
1851 displayProperties()->displayName(), Qt::DisplayRole);
1852 item->setTextColor(Qt::black);
1853 // Make sure active not used in a CnetEditorWidget before closing
1854 if (!directory()->controlUsedInCnetEditorWidget(m_activeControl)) {
1855 m_activeControl->closeControlNet();
1856 }
1857 }
1858
1859 ProjectItem *item = directory()->model()->findItemData(displayName, Qt::DisplayRole);
1860 if (item && item->isControl()) {
1861 m_activeControl = item->control();
1862
1863 try {
1864 m_activeControl->controlNet()->SetImages(*(activeImageList()->serialNumberList()));
1865 item->setTextColor(Qt::darkGreen);
1866 }
1867 catch(IException &e){
1868 if (previousControl) {
1869 m_activeControl = previousControl;
1870 item = directory()->model()->findItemData(m_activeControl->
1871 displayProperties()->displayName(), Qt::DisplayRole);
1872 item->setTextColor(Qt::darkGreen);
1873 m_activeControl->controlNet()->SetImages(*(activeImageList()->serialNumberList()));
1874 }
1875 else {
1876 m_activeControl = NULL;
1877 }
1878 throw IException(e);
1879 }
1880 }
1881 emit activeControlSet(true);
1882 }
1883
1884
1903
1904 if (!m_activeControl && (m_controls->count() == 1 && m_controls->at(0)->count() ==1)) {
1905 // Can only set a default control if an active imageList exists or if a default can be set
1906 if (activeImageList()) {
1907 QString controlName = m_controls->at(0)->at(0)->displayProperties()->displayName();
1908 setActiveControl(controlName);
1909 }
1910 }
1911
1912 return m_activeControl;
1913 }
1914
1915
1924 if (m_activeControl && m_activeControl->isModified()) {
1925 emit activeControlModified();
1926 }
1927 setClean(false);
1928 }
1929
1930
1954 void Project::setActiveImageList(QString displayName) {
1955 ImageList *previousImageList = m_activeImageList;
1956 if (m_activeImageList) {
1957 ProjectItem *item = directory()->model()->findItemData(m_activeImageList->
1958 name(), Qt::DisplayRole);
1959 item->setTextColor(Qt::black);
1960 }
1961 ProjectItem *item = directory()->model()->findItemData(displayName, Qt::DisplayRole);
1962 if (item && item->isImageList()) {
1963 m_activeImageList = item->imageList();
1964
1965 if (m_activeControl) {
1966 try {
1967 activeControl()->controlNet()->SetImages(*(m_activeImageList->serialNumberList()));
1968 }
1969 catch(IException &e){
1970 if (previousImageList) {
1971 m_activeImageList = previousImageList;
1972 item = directory()->model()->findItemData(m_activeImageList->
1973 name(), Qt::DisplayRole);
1974 item->setTextColor(Qt::darkGreen);
1975 activeControl()->controlNet()->SetImages(*(m_activeImageList->serialNumberList()));
1976 }
1977 else {
1978 m_activeImageList = NULL;
1979 }
1980 throw IException(e);
1981 }
1982 }
1983 item->setTextColor(Qt::darkGreen);
1984 emit activeImageListSet();
1985 }
1986 }
1987
1988
2003
2004 if (!m_activeImageList && m_images->count() == 1) {
2005 QString imageList = m_images->at(0)->name();
2006
2008 }
2009 return m_activeImageList;
2010 }
2011
2012
2018 QString Project::cnetRoot(QString projectRoot) {
2019 return projectRoot + "/cnets";
2020 }
2021
2022
2028 QString Project::cnetRoot() const {
2029 return cnetRoot( m_projectRoot->path() );
2030 }
2031
2032
2037 QList<ControlList *> Project::controls() {
2038 return *m_controls;
2039 }
2040
2041
2048 QListIterator< ControlList * > it(*m_controls);
2049
2050 ControlList *result = NULL;
2051 while (it.hasNext() && !result) {
2052 ControlList *list = it.next();
2053
2054 if (list->name() == name) result = list;
2055 }
2056
2057 return result;
2058 }
2059
2060
2066 QString Project::imageDataRoot(QString projectRoot) {
2067 return projectRoot + "/images";
2068 }
2069
2070
2076 QString Project::imageDataRoot() const {
2077 return imageDataRoot( m_projectRoot->path() );
2078 }
2079
2080
2086 QString Project::shapeDataRoot(QString projectRoot) {
2087 return projectRoot + "/shapes";
2088 }
2089
2090
2096 QString Project::shapeDataRoot() const {
2097 return shapeDataRoot( m_projectRoot->path() );
2098 }
2099
2100
2105 QList<ShapeList *> Project::shapes() {
2106 return *m_shapes;
2107 }
2108
2109
2114 QList<ImageList *> Project::images() {
2115 return *m_images;
2116 }
2117
2118
2124 QString Project::templateRoot(QString projectRoot) {
2125 return projectRoot + "/templates";
2126 }
2127
2128
2134 QString Project::templateRoot() const {
2135 return templateRoot( m_projectRoot->path() );
2136 }
2137
2138
2144 QList<TemplateList *> Project::templates() {
2145 QList<TemplateList *> allTemplates = *m_mapTemplates + *m_regTemplates;
2146 return allTemplates;
2147 }
2148
2149
2155 QList<TemplateList *> Project::mapTemplates() {
2156 return *m_mapTemplates;
2157 }
2158
2159
2165 QList<TemplateList *> Project::regTemplates() {
2166 return *m_regTemplates;
2167 }
2168
2169
2175 QString Project::targetBodyRoot(QString projectRoot) {
2176 return projectRoot + "/targets";
2177 }
2178
2179
2185 QString Project::targetBodyRoot() const {
2186 return targetBodyRoot( m_projectRoot->path() );
2187 }
2188
2189
2194 return *m_targets;
2195 }
2196
2197
2203 QString Project::resultsRoot(QString projectRoot) {
2204 return projectRoot + "/results";
2205 }
2206
2207
2213 QString Project::resultsRoot() const {
2214 return resultsRoot( m_projectRoot->path() );
2215 }
2216
2217
2222 QList<BundleSolutionInfo *> Project::bundleSolutionInfo() {
2223 return *m_bundleSolutionInfo;
2224 }
2225
2226
2232 QString Project::bundleSolutionInfoRoot(QString projectRoot) {
2233 return projectRoot + "/results/bundle";
2234 }
2235
2236
2243 return bundleSolutionInfoRoot( m_projectRoot->path() );
2244 }
2245
2246
2251
2252 // Currently the deleteFromDisk methods for Image and Shape delete the Cube if it exists, the
2253 // other objects deleteFromDisk methods simply remove files. This could be achieved easier
2254 // in this method by simply calling QDir::removeRecursively(), but for future functionality
2255 // call each objects deleteFromDisk. Currently there are no cleanup methods for Bundle results
2256 // or templates, so simply remove directory recursively.
2257 foreach (ImageList *imagesInAFolder, *m_images) {
2258 imagesInAFolder->deleteFromDisk(this);
2259 }
2260
2261 if ( !m_projectRoot->rmdir( imageDataRoot() ) ) {
2262 warn( tr("Did not properly clean up images folder [%1] in project").arg( imageDataRoot() ) );
2263 }
2264
2265 foreach (ShapeList *shapesInAFolder, *m_shapes) {
2266 shapesInAFolder->deleteFromDisk(this);
2267 }
2268
2269 if ( !m_projectRoot->rmdir( shapeDataRoot() ) ) {
2270 warn( tr("Did not properly clean up shapes folder [%1] in project").
2271 arg( shapeDataRoot() ) );
2272 }
2273
2274 foreach (ControlList *controlsInAFolder, *m_controls) {
2275 controlsInAFolder->deleteFromDisk(this);
2276 }
2277
2278 if ( !m_projectRoot->rmdir( cnetRoot() ) ) {
2279 warn( tr("Did not properly clean up control network folder [%1] in project")
2280 .arg( cnetRoot() ) );
2281 }
2282
2283 if ( !(QDir(resultsRoot()).removeRecursively()) ) {
2284 warn( tr("Did not properly clean up results folder [%1] in project")
2285 .arg( resultsRoot() ) );
2286 }
2287
2288 if ( !(QDir(templateRoot()).removeRecursively()) ) {
2289 warn( tr("Did not properly clean up templates folder [%1] in project")
2290 .arg( templateRoot() ) );
2291 }
2292
2293 if ( !m_projectRoot->rmpath( m_projectRoot->path() ) ) {
2294 warn( tr("Did not properly clean up project in [%1]").arg( m_projectRoot->path() ) );
2295 }
2296 }
2297
2298
2304 void Project::relocateProjectRoot(QString newProjectRoot) {
2305 *m_projectRoot = newProjectRoot;
2306 emit projectRelocated(this);
2307 }
2308
2309
2324 // Let caller know if the save dialog was cancelled
2325 bool saveDialogCompleted = true;
2326
2327 if (m_isTemporaryProject) {
2328 QString newDestination = QFileDialog::getSaveFileName(NULL,
2329 QString("Project Location"),
2330 QString("."));
2331
2332 if ( !newDestination.isEmpty() ) {
2333 m_isTemporaryProject = false;
2334 save( QFileInfo(newDestination + "/").absolutePath() );
2335
2336 // delete the temporary project
2338 relocateProjectRoot(newDestination);
2339
2340 // 2014-03-14 kle This is a lame kludge because we think that relocateProjectRoot is not
2341 // working properly. For example, when we save a new project and try to view a control net
2342 // the it thinks it's still in the /tmp area
2343 // see ticket #5292
2344 open(newDestination);
2345 }
2346 // Dialog was cancelled
2347 else {
2348 saveDialogCompleted = false;
2349 }
2350 }
2351 else {
2352 // Save all modified controls. If "Save As" is being processed,
2353 // the controls are written in the Control::copyToNewProjectRoot, so the controls in
2354 // current project are not modified.
2355 foreach (ControlList *controlList, *m_controls) {
2356 foreach (Control *control, *controlList) {
2357 if (control->isModified()) {
2358 control->write();
2359 }
2360 }
2361 }
2362 save(m_projectRoot->absolutePath(), false);
2363 emit cnetSaved(true);
2364 }
2365
2366 return saveDialogCompleted;
2367 }
2368
2369
2370
2371
2471 void Project::save(FileName newPath, bool verifyPathDoesntExist) {
2472 if ( verifyPathDoesntExist && QFile::exists( newPath.toString() ) ) {
2474 QString("Projects may not be saved to an existing path [%1]; "
2475 "please select a new path or delete the current folder")
2476 .arg(newPath.original()),
2477 _FILEINFO_);
2478 }
2479
2480 QDir dir;
2481 if (!dir.mkpath(newPath.toString())) {
2483 QString("Unable to save project at [%1] "
2484 "because we could not create the folder")
2485 .arg(newPath.original()),
2486 _FILEINFO_);
2487 }
2488
2489 // TODO Set newpath member variable. This is used for some of the data copy methods and is not
2490 // the ideal way to handle this. Maybe change the data copy methods to either take the new
2491 // project root in addition to the data root or put the data root in the dataList (ImageList,
2492 // etc.). If performing a "Save", m_newProjectRoot == m_projectRoot
2493 m_newProjectRoot = newPath.toString();
2494
2495 // For now set the member variable rather than calling setName which emits signal and updates
2496 // ProjectItemModel & the project name on the tree. This will be updated when the new project
2497 // is opened.
2498 m_name = newPath.name();
2499
2500 QFile projectSettingsFile(newPath.toString() + "/project.xml");
2501 if (!projectSettingsFile.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
2503 QString("Unable to save project at [%1] because the file [%2] "
2504 "could not be opened for writing")
2505 .arg(newPath.original()).arg(projectSettingsFile.fileName()),
2506 _FILEINFO_);
2507 }
2508
2509 QXmlStreamWriter writer(&projectSettingsFile);
2510 writer.setAutoFormatting(true);
2511
2512 writer.writeStartDocument();
2513
2514 // Do amazing, fantastical stuff here!!!
2515 save(writer, newPath);
2516
2517 writer.writeEndDocument();
2518
2519 QFile projectHistoryFile(newPath.toString() + "/history.xml");
2520 if (!projectHistoryFile.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
2522 QString("Unable to save project at [%1] because the file [%2] "
2523 "could not be opened for writing")
2524 .arg(newPath.original()).arg(projectHistoryFile.fileName()),
2525 _FILEINFO_);
2526 }
2527
2528 QXmlStreamWriter historyWriter(&projectHistoryFile);
2529 historyWriter.setAutoFormatting(true);
2530
2531 historyWriter.writeStartDocument();
2532 saveHistory(historyWriter);
2533 historyWriter.writeEndDocument();
2534
2535 QFile projectWarningsFile(newPath.toString() + "/warnings.xml");
2536 if (!projectWarningsFile.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
2538 QString("Unable to save project at [%1] because the file [%2] could not be "
2539 "opened for writing")
2540 .arg(newPath.original()).arg(projectWarningsFile.fileName()),
2541 _FILEINFO_);
2542 }
2543
2544 QXmlStreamWriter warningsWriter(&projectWarningsFile);
2545 warningsWriter.setAutoFormatting(true);
2546
2547 warningsWriter.writeStartDocument();
2548 saveWarnings(warningsWriter);
2549 warningsWriter.writeEndDocument();
2550
2551 // Save the Directory structure
2552 QFile directoryStateFile(newPath.toString() + "/directory.xml");
2553 if (!directoryStateFile.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
2555 QString("Unable to save project at [%1] because the file [%2] could not be "
2556 "opened for writing")
2557 .arg(newPath.original()).arg(directoryStateFile.fileName()),
2558 _FILEINFO_);
2559 }
2560
2561 QXmlStreamWriter directoryStateWriter(&directoryStateFile);
2562 directoryStateWriter.setAutoFormatting(true);
2563
2564 directoryStateWriter.writeStartDocument();
2565
2566 /*
2567 * TODO: Does Project need to know about Directory?
2568 * This is the only place that project uses m_directory. This makes me wonder if it is
2569 * necessary for project to have a Directory member variable.
2570 */
2571 m_directory->save(directoryStateWriter, newPath);
2572
2573 directoryStateWriter.writeEndDocument();
2574 m_isOpen = true;
2575
2576 emit projectSaved(this);
2577
2578 }
2579
2580
2598 if (workOrder) {
2599 connect(workOrder, SIGNAL(finished(WorkOrder *)),
2600 this, SIGNAL(workOrderFinished(WorkOrder *)));
2601
2602 workOrder->setPrevious(lastNotUndoneWorkOrder());
2603
2604 if (workOrder->setupExecution()) {
2605 if (workOrder->previous()) workOrder->previous()->setNext(workOrder);
2606
2607 m_workOrderHistory->append(workOrder);
2608
2609 if (workOrder->isSavedToHistory()) {
2610 emit workOrderStarting(workOrder);
2611 }
2612
2613 // Work orders that create clean states (save, save as) don't belong on the undo stack.
2614 // Instead, we tell the undo stack that we're now clean.
2615 if (workOrder->createsCleanState()) {
2616 m_undoStack.setClean();
2617 workOrder->execute();
2618 }
2619 // All other work orders go onto the undo stack, unless specifically told not to
2620 else if (workOrder->isUndoable()) {
2621 // This calls WorkOrder::redo for us through Qt's QUndoStack::push method, redo is only
2622 // implemented in the base class. Child work orders do not implement redo.
2623 m_undoStack.push(workOrder);
2624 }
2625 else {
2626 // If we get this far the WorkOrder is not-undoable therefore we have to call redo by
2627 // hand.
2628
2629 workOrder->redo();
2630 }
2631 // Clean up deleted work orders (the m_undoStack.push() can delete work orders)
2632 m_workOrderHistory->removeAll(NULL);
2633 }
2634 else {
2635 delete workOrder;
2636 workOrder = NULL;
2637 }
2638 }
2639 }
2640
2641
2642 template<typename Data> void Project::warn(QString text, Data relevantData) {
2643 storeWarning(text, relevantData);
2644 directory()->showWarning(text, relevantData);
2645 }
2646
2647
2648 void Project::warn(QString text) {
2649 foreach (QString line, text.split("\n")) {
2650 storeWarning(line);
2651 directory()->showWarning(line);
2652 }
2653 }
2654
2655
2656 void Project::storeWarning(QString text) {
2657 m_warnings->append(text);
2658 }
2659
2660
2666
2668
2669 foreach (Image *image, images) {
2670 connect(image, SIGNAL(destroyed(QObject *)),
2671 this, SLOT(imageClosed(QObject *)));
2672 connect(this, SIGNAL(projectRelocated(Project *)),
2673 image, SLOT(updateFileName(Project *)));
2674
2675 (*m_idToImageMap)[image->id()] = image;
2676 if (images.name() != "") {
2677 createOrRetrieveImageList(images.name(), images.path())->append(image);
2678 }
2679 else {
2680 createOrRetrieveImageList(FileName(images[0]->fileName()).dir().dirName(), "")->append(image);
2681 }
2682 }
2683
2684 // We really can't have all of the cubes in memory before
2685 // the OS stops letting us open more files.
2686 // Assume cameras are being used in other parts of code since it's
2687 // unknown
2688 QMutexLocker lock(m_mutex);
2689 emit imagesAdded(m_images->last());
2690
2691 Image *openImage;
2692 foreach (openImage, images) {
2693 openImage->closeCube();
2694 }
2695
2696// if(m_projectPvl && m_projectPvl->HasObject("MosaicFileList") )
2697// m_fileList->fromPvl(m_projectPvl->FindObject("MosaicFileList") );
2698
2699// if(m_projectPvl && m_projectPvl->HasObject("MosaicScene") )
2700// m_scene->fromPvl(m_projectPvl->FindObject("MosaicScene") );
2701
2702 if (m_numImagesCurrentlyReading == 0) {
2703 m_imageReadingMutex->unlock();
2704 }
2705 }
2706
2707
2714 bool Project::hasTarget(QString id) {
2715 foreach (TargetBodyQsp targetBody, *m_targets) {
2716 if (QString::compare(targetBody->targetName(), id, Qt::CaseInsensitive) == 0) {
2717 return true;
2718 }
2719 }
2720 return false;
2721 }
2722
2723
2730
2731 TargetBodyQsp targetBody = TargetBodyQsp(new TargetBody(target));
2732
2733 m_targets->append(targetBody);
2734
2735 }
2736
2737
2744 bool Project::hasCamera(QString id) {
2745 foreach (GuiCameraQsp camera, *m_guiCameras) {
2746
2747 if (QString::compare(camera->instrumentId(), id, Qt::CaseInsensitive) == 0) {
2748 return true;
2749 }
2750 }
2751 return false;
2752 }
2753
2754
2761
2762 GuiCameraQsp guiCamera = GuiCameraQsp(new GuiCamera(camera));
2763
2764 m_guiCameras->append(guiCamera);
2765
2766 }
2767
2768
2778
2779 foreach (Image *image, images) {
2780 (*m_idToImageMap)[image->id()] = image;
2781 }
2782 }
2783
2784
2785 void Project::removeImages(ImageList &imageList) {
2786 foreach (Image *image, imageList) {
2787 delete image;
2788 }
2789 foreach (ImageList *list, *m_images) {
2790 if (list->name() == imageList.name()) {
2791 m_images->removeOne(list);
2792 }
2793 }
2794 }
2795
2796
2802 QMutableListIterator<ImageList *> it(*m_images);
2803 while (it.hasNext()) {
2804 ImageList *list = it.next();
2805
2806 int foundElement = list->indexOf((Image *)imageObj);
2807
2808 if (foundElement != -1) {
2809 list->removeAt(foundElement);
2810 }
2811 }
2812
2813 m_idToImageMap->remove(m_idToImageMap->key((Image *)imageObj));
2814 }
2815
2816
2822 int indexToRemove = m_images->indexOf(static_cast<ImageList *>(imageListObj));
2823 if (indexToRemove != -1) {
2824 m_images->removeAt(indexToRemove);
2825 }
2826 }
2827
2828
2833 m_idToControlMap->remove(m_idToControlMap->key((Control *)controlObj));
2834 }
2835
2836
2840 void Project::controlListDeleted(QObject *controlListObj) {
2841 int indexToRemove = m_controls->indexOf(static_cast<ControlList *>(controlListObj));
2842 if (indexToRemove != -1) {
2843 m_controls->removeAt(indexToRemove);
2844 }
2845
2846 if (controls().count() == 0) {
2847 emit allControlsRemoved();
2848 }
2849 }
2850
2851
2856 int indexToRemove = m_shapes->indexOf(static_cast<ShapeList *>(shapeListObj));
2857 if (indexToRemove != -1) {
2858 m_shapes->removeAt(indexToRemove);
2859 }
2860 }
2861
2862
2866 void Project::bundleSolutionInfoClosed(QObject *bundleSolutionInfoObj) {
2867 QMutableListIterator<BundleSolutionInfo *> it(*m_bundleSolutionInfo);
2868 while (it.hasNext()) {
2870 if (!bundleSolutionInfo) {
2871 // throw error???
2872 }
2873
2874 int foundElement = m_bundleSolutionInfo->indexOf(
2875 (BundleSolutionInfo *)bundleSolutionInfoObj);
2876
2877 if (foundElement != -1) {
2878 m_bundleSolutionInfo->removeAt(foundElement);
2879 }
2880 }
2881
2882 m_idToBundleSolutionInfoMap->remove(
2883 m_idToBundleSolutionInfoMap->key((BundleSolutionInfo * )bundleSolutionInfoObj));
2884 }
2885
2886
2892 void Project::targetBodyClosed(QObject *targetBodyObj) {
2893// QMutableListIterator<TargetBody *> it(*m_targets);
2894// while ( it.hasNext() ) {
2895// TargetBody *targetBody = it.next();
2896// if (!targetBody) {
2897// // throw error???
2898// }
2899
2900// int foundElement = m_targets->indexOf( (TargetBody *)targetBodyObj );
2901
2902// if (foundElement != -1) {
2903// m_targets->removeAt(foundElement);
2904// }
2905// }
2906
2907// m_idToTargetBodyMap->remove(m_idToTargetBodyMap->key((TargetBody *)targetBodyObj));
2908 }
2909
2910
2911
2912 void Project::shapesReady(ShapeList shapes) {
2913
2914 m_numShapesCurrentlyReading -= shapes.count();
2915
2916 foreach (Shape *shape, shapes) {
2917 connect(shape, SIGNAL(destroyed(QObject *)),
2918 this, SLOT(shapeClosed(QObject *)));
2919 connect(this, SIGNAL(projectRelocated(Project *)),
2920 shape, SLOT(updateFileName(Project *)));
2921
2922 (*m_idToShapeMap)[shape->id()] = shape;
2923 if (shapes.name() != "") {
2924 createOrRetrieveShapeList(shapes.name(), shapes.path())->append(shape);
2925 }
2926 else {
2927 createOrRetrieveShapeList(FileName(shapes[0]->fileName()).dir().dirName(), "")->append(shape);
2928 }
2929
2930 }
2931
2932 // We really can't have all of the cubes in memory before
2933 // the OS stops letting us open more files.
2934 // Assume cameras are being used in other parts of code since it's
2935 // unknown
2936 QMutexLocker lock(m_shapeMutex);
2937 emit shapesAdded(m_shapes->last());
2938
2939 Shape *openShape;
2940 foreach (openShape, shapes) {
2941 openShape->closeCube();
2942 }
2943
2944 if (m_numShapesCurrentlyReading == 0) {
2945 m_shapeReadingMutex->unlock();
2946 }
2947 }
2948
2949
2954 QMutableListIterator<ShapeList *> it(*m_shapes);
2955 while (it.hasNext()) {
2956 ShapeList *list = it.next();
2957
2958 int foundElement = list->indexOf((Shape *)imageObj);
2959
2960 if (foundElement != -1) {
2961 list->removeAt(foundElement);
2962 }
2963 }
2964
2965 m_idToShapeMap->remove(m_idToShapeMap->key((Shape *)imageObj));
2966 }
2967
2968
2969 Project::XmlHandler::XmlHandler(Project *project) {
2970 m_project = project;
2971 m_workOrder = NULL;
2972 }
2973
2974
2986 return m_workOrderMutex;
2987 }
2988
2989
2990 bool Project::XmlHandler::startElement(const QString &namespaceURI, const QString &localName,
2991 const QString &qName, const QXmlAttributes &atts) {
2992 if (XmlStackedHandler::startElement(namespaceURI, localName, qName, atts)) {
2993
2994 if (localName == "project") {
2995 QString name = atts.value("name");
2996 if (!name.isEmpty()) {
2997 m_project->setName(name);
2998 }
2999 }
3000 else if (localName == "controlNets") {
3001 m_controls.append(new ControlList(m_project, reader()));
3002 }
3003 else if (localName == "imageList") {
3004 m_imageLists.append(new ImageList(m_project, reader()));
3005 }
3006 else if (localName == "shapeList") {
3007 m_shapeLists.append(new ShapeList(m_project, reader()));
3008 }
3009 else if (localName == "mapTemplateList") {
3010 m_mapTemplateLists.append( new TemplateList(m_project, reader()));
3011 }
3012 else if (localName == "regTemplateList") {
3013 m_regTemplateLists.append( new TemplateList(m_project, reader()));
3014 }
3015 // workOrders are stored in history.xml, using same reader as project.xml
3016 else if (localName == "workOrder") {
3017 QString type = atts.value("type");
3018
3019 m_workOrder = WorkOrderFactory::create(m_project, type);
3020
3021 m_workOrder->read(reader());
3022 }
3023 // warnings stored in warning.xml, using same reader as project.xml
3024 else if (localName == "warning") {
3025 QString warningText = atts.value("text");
3026
3027 if (!warningText.isEmpty()) {
3028 m_project->warn(warningText);
3029 }
3030 }
3031 else if (localName == "directory") {
3032 m_project->directory()->load(reader());
3033 }
3034 else if (localName == "dockRestore") {
3035// QVariant geo_data = QVariant(atts.value("geometry"));
3036// restoreGeometry(geo_data);
3037// QVariant layout_data = QVariant(atts.value("state"));
3038// restoreState(layout_data);
3039 }
3040
3041 else if (localName == "bundleSolutionInfo") {
3042 m_bundleSolutionInfos.append(new BundleSolutionInfo(m_project, reader()));
3043 }
3044 else if (localName == "activeImageList") {
3045 QString displayName = atts.value("displayName");
3046 m_project->setActiveImageList(displayName);
3047 }
3048 else if (localName == "activeControl") {
3049 // Find Control
3050 QString displayName = atts.value("displayName");
3051 m_project->setActiveControl(displayName);
3052 }
3053 }
3054
3055 return true;
3056 }
3057
3058
3070 bool Project::XmlHandler::endElement(const QString &namespaceURI, const QString &localName,
3071 const QString &qName) {
3072 if (localName == "imageLists") {
3073 foreach (ImageList *imageList, m_imageLists) {
3074 m_project->imagesReady(*imageList);
3075 }
3076 }
3077 else if (localName == "shapeLists") {
3078 // TODO does this go here under project or should it be under shapes?
3079 foreach (ShapeList *shapeList, m_shapeLists) {
3080 m_project->shapesReady(*shapeList);
3081 }
3082 }
3083 else if (localName == "mapTemplateLists") {
3084 foreach (TemplateList *templateList, m_mapTemplateLists) {
3085 m_project->addTemplates(templateList);
3086 }
3087 }
3088 else if (localName == "regTemplateLists") {
3089 foreach (TemplateList *templateList, m_regTemplateLists) {
3090 m_project->addTemplates(templateList);
3091 }
3092 }
3093 else if (localName == "workOrder") {
3094 m_project->m_workOrderHistory->append(m_workOrder);
3095 m_workOrder = NULL;
3096 }
3097 else if (localName == "controlNets") {
3098 foreach (ControlList *list, m_controls) {
3099 foreach (Control *control, *list) {
3100 m_project->addControl(control);
3101 }
3102 delete list;
3103 }
3104 m_controls.clear();
3105 }
3106 else if (localName == "results") {
3107 foreach (BundleSolutionInfo *bundleInfo, m_bundleSolutionInfos) {
3108 m_project->addBundleSolutionInfo(bundleInfo);
3109
3110 // If BundleSolutionInfo contains adjusted images, add to the project id map.
3111 if (bundleInfo->adjustedImages().count()) {
3112 foreach (ImageList *adjustedImageList, bundleInfo->adjustedImages()) {
3113 m_project->addImagesToIdMap(*adjustedImageList);
3114 }
3115 }
3116 }
3117 }
3118 return XmlStackedHandler::endElement(namespaceURI, localName, qName);
3119 }
3120}
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:66
QString id() const
Access the unique ID associated with this Control.
Definition Control.cpp:282
ControlNet * controlNet()
Open and return a pointer to the ControlNet for this Control.
Definition Control.cpp:150
bool write()
@description Write control net to disk.
Definition Control.cpp:191
bool isModified()
@description Has this control been modified?
Definition Control.cpp:229
QString fileName() const
Access the name of the control network file associated with this Control.
Definition Control.cpp:272
Maintains a list of Controls so that control nets can easily be copied from one Project to another,...
Definition ControlList.h:44
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:72
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:107
void closeCube()
Cleans up the Cube pointer.
Definition Image.cpp:307
QString id() const
Get a unique, identifying string associated with this image.
Definition Image.cpp:445
Internalizes a list of images and allows for operations on the entire list.
Definition ImageList.h:55
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.
virtual bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName)
The xml parser for ending tags.
Definition Project.cpp:3070
The main project for ipce.
Definition Project.h:289
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:1954
void imageListDeleted(QObject *imageList)
An image list is being deleted from the project.
Definition Project.cpp:2821
void addBundleSolutionInfo(BundleSolutionInfo *bundleSolutionInfo)
Add the given BundleSolutionInfo to the current project.
Definition Project.cpp:1193
void checkActiveControlAndImageList()
Checks if both an active control and active image list have been set.
Definition Project.cpp:1766
void activeImageListSet()
Emitted when an active image list is set.
Shape * shape(QString id)
Return a shape given its id.
Definition Project.cpp:1538
QString targetBodyRoot() const
Accessor for the root directory of the target body data.
Definition Project.cpp:2185
QMutex * mutex()
Return mutex used for Naif calls.
Definition Project.cpp:1657
ImageList * imageList(QString name)
Return an imagelist given its name.
Definition Project.cpp:1519
void workOrderStarting(WorkOrder *)
Emitted when work order starts.
QList< TemplateList * > templates()
Return all template FileNames.
Definition Project.cpp:2144
bool isTemporaryProject() const
Returns if the project is a temp project or not.
Definition Project.cpp:1566
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:2665
void targetBodyClosed(QObject *targetBodyObj)
A target body is being deleted from the project.
Definition Project.cpp:2892
void setName(QString newName)
Change the project's name (GUI only, doesn't affect location on disk).
Definition Project.cpp:1683
void imageClosed(QObject *image)
An image is being deleted from the project.
Definition Project.cpp:2801
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:925
void controlListAdded(ControlList *controls)
apparently not used?
void addControl(Control *control)
Add the given Control's to the current project.
Definition Project.cpp:957
WorkOrder * lastNotUndoneWorkOrder()
Return the last not undone workorder.
Definition Project.cpp:1604
QDir addTemplateFolder(QString prefix)
Create and navigate to the appropriate template type folder in the project directory.
Definition Project.cpp:1133
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:2242
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:2855
void deleteAllProjectFiles()
Delete all of the files, that this project stores, from disk.
Definition Project.cpp:2250
QString newProjectRoot() const
Get the top-level folder of the new project.
Definition Project.cpp:1674
void setActiveControl(QString displayName)
Set the Active Control (control network)
Definition Project.cpp:1818
QDir addBundleSolutionInfoFolder(QString folder)
Create and return the name of a folder for placing BundleSolutionInfo.
Definition Project.cpp:1173
void controlClosed(QObject *control)
A control is being deleted from the project.
Definition Project.cpp:2832
QList< TemplateList * > regTemplates()
Return registration template FileNames.
Definition Project.cpp:2165
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:2134
QUndoStack * undoStack()
Returns the Projects stack of QUndoCommands.
Definition Project.cpp:1693
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:2744
QList< WorkOrder * > workOrderHistory()
Get the entire list of work orders that have executed.
Definition Project.cpp:1747
QString resultsRoot() const
Accessor for the root directory of the results data.
Definition Project.cpp:2213
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:2777
bool m_isClean
used to determine whether a project is currently open
Definition Project.h:666
void waitForShapeReaderFinished()
Locks program if another spot in code is still running and called this function.
Definition Project.cpp:1739
TargetBodyList targetBodies()
Return TargetBodyList in Project.
Definition Project.cpp:2193
void waitForImageReaderFinished()
Locks program if another spot in code is still running and called this function.
Definition Project.cpp:1731
ShapeList * shapeList(QString name)
Return a shapelist given its name.
Definition Project.cpp:1548
bool hasTarget(QString id)
This method checks for the existence of a target based on TargetName.
Definition Project.cpp:2714
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:2953
QList< ShapeList * > shapes()
Return the projects shapelist.
Definition Project.cpp:2105
QMutex * workOrderMutex()
This function returns a QMutex.
Definition Project.cpp:2985
~Project()
Clean up the project.
Definition Project.cpp:256
QList< QAction * > userPreferenceActions()
Get a list of configuration/settings actions related to reading images into this Project.
Definition Project.cpp:915
void saveHistory(QXmlStreamWriter &stream) const
Serialize the work orders into the given XML.
Definition Project.cpp:850
void clear()
Function to clear out all values in a project essentially making it a new project object.
Definition Project.cpp:458
void addToProject(WorkOrder *)
This executes the WorkOrder and stores it in the project.
Definition Project.cpp:2597
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:2729
QList< TemplateList * > mapTemplates()
Return map template FileNames.
Definition Project.cpp:2155
Control * control(QString id)
Accessor for if the project is clearing or not.
Definition Project.cpp:1162
void createFolders()
This creates the project root, image root, and control net root directories.
Definition Project.cpp:383
void cnetModified()
When a cnet is modified, set the project state to not clean.
Definition Project.cpp:1923
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:2076
void bundleSolutionInfoClosed(QObject *bundleSolutionInfo)
A BundleSolutionInfo object is being deleted from the project.
Definition Project.cpp:2866
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:2028
void checkControlsAndImagesAvailable()
Checks if at least one control and image have been added to the project.
Definition Project.cpp:1783
QList< ControlList * > controls()
Return controls in project.
Definition Project.cpp:2037
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:651
bool m_clearing
used to determine whether a project's changes are unsaved
Definition Project.h:667
Directory * directory() const
Returns the directory associated with this Project.
Definition Project.cpp:1228
int m_numImagesCurrentlyReading
used to negate segfaults happening in post undos when clearning project
Definition Project.h:668
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:1583
void open(QString)
Open the project at the given path.
Definition Project.cpp:1344
ImageList * activeImageList()
Returns the active ImageList.
Definition Project.cpp:2002
QList< BundleSolutionInfo * > bundleSolutionInfo()
Return BundleSolutionInfo objects in Project.
Definition Project.cpp:2222
QString projectRoot() const
Get the top-level folder of the project.
Definition Project.cpp:1665
QString name() const
Get the project's GUI name.
Definition Project.cpp:1624
void setClean(bool value)
Function to change the clean state of the project.
Definition Project.cpp:1594
Control * activeControl()
Return the Active Control (control network)
Definition Project.cpp:1902
void loadBundleSolutionInfo(BundleSolutionInfo *bundleSolutionInfo)
Loads bundle solution info into project.
Definition Project.cpp:1209
void addCamera(Camera *camera)
Adds a new camera to the project.
Definition Project.cpp:2760
QDir addImageFolder(QString prefix)
Create and return the name of a folder for placing images.
Definition Project.cpp:1002
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:873
void relocateProjectRoot(QString newRoot)
This is called when the project is moved.
Definition Project.cpp:2304
void controlListDeleted(QObject *controlList)
An control list is being deleted from the project.
Definition Project.cpp:2840
QString shapeDataRoot() const
Accessor for the root directory of the shape model data.
Definition Project.cpp:2096
bool isOpen()
Accessor to determine whether a current project is Open.
Definition Project.cpp:1574
QList< ImageList * > images()
Return projects imagelist.
Definition Project.cpp:2114
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:1508
void addTemplates(TemplateList *templateFiles)
Add new templates to m_mapTemplates or m_regTemplates and update project item model.
Definition Project.cpp:1112
void addShapes(QStringList shapeFiles)
Read the given shape model cube file names as Images and add them to the project.
Definition Project.cpp:1088
Project(Directory &directory, QObject *parent=0)
Create a new Project.
Definition Project.cpp:87
void addImages(QStringList imageFiles)
Read the given cube file names as Images and add them to the project.
Definition Project.cpp:1031
bool save()
Generic save method to save the state of the project.
Definition Project.cpp:2323
QDir addShapeFolder(QString prefix)
Create and return the name of a folder for placing shape models.
Definition Project.cpp:1059
ControlList * controlList(QString name)
Return controlslist matching name in Project.
Definition Project.cpp:2047
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:68
void closeCube()
Cleans up the Cube *.
Definition Shape.cpp:342
QString id() const
Get a unique, identifying string associated with this shape.
Definition Shape.cpp:459
Internalizes a list of shapes and allows for operations on the entire list.
Definition ShapeList.h:33
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:65
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.
Manage a stack of content handlers for reading XML files.
virtual void pushContentHandler(XmlStackedHandler *newHandler)
Push a contentHandler and maybe continue parsing...
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:186
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:216