Isis 3 Programmer Reference
WorkOrder.cpp
1
7/* SPDX-License-Identifier: CC0-1.0 */
8
9#include "WorkOrder.h"
10
11#include <QDebug>
12#include <QFutureWatcher>
13#include <QMutex>
14#include <QMutexLocker>
15#include <QtConcurrentRun>
16#include <QTimer>
17#include <QXmlStreamWriter>
18
19#include "ControlList.h"
20#include "IException.h"
21#include "ImageList.h"
22#include "IString.h"
23#include "ProgressBar.h"
24#include "Project.h"
25#include "ProjectItem.h"
26#include "ShapeList.h"
27#include "Template.h"
28
29
30namespace Isis {
38 WorkOrder::WorkOrder(Project *project) : QAction(project) {
40
41 m_context = NoContext;
42 m_data = "";
43 m_imageList = new ImageList;
44 m_shapeList = new ShapeList;
45 m_controlList = NULL;
46 m_correlationMatrix = CorrelationMatrix();
49 m_template = NULL;
51
52 m_isUndoable = true;
53 m_isSavedToHistory = true;
54 m_isSynchronous = true;
55
56 m_createsCleanState = false;
57 m_modifiesDiskState = false;
58 m_status = WorkOrderNotStarted;
59 m_queuedAction = NoQueuedAction;
61 m_elapsedTimer = NULL;
62
63 m_futureWatcher = new QFutureWatcher<void>;
64 m_transparentConstMutex = new QMutex;
65
69
70 m_secondsElapsed = 0.0;
71
72 if (!m_project) {
74 tr("Work orders cannot be created without a project."), _FILEINFO_);
75 }
76
77 connect(this, SIGNAL(triggered()),
78 this, SLOT(addCloneToProject()));
79 connect(m_futureWatcher, SIGNAL(finished()),
80 this, SLOT(executionFinished()));
81 }
82
83
91 QAction(other.icon(), ((QAction &)other).text(), other.parentWidget()),
92 QUndoCommand(((QUndoCommand &)other).text()) {
93 // Copy the action's what's this and tool tip (hover text).
94 QAction::setWhatsThis(other.whatsThis());
95 QAction::setToolTip(other.toolTip());
96
98 m_elapsedTimer = NULL;
99 m_project = other.project();
100 m_context = other.m_context;
101 m_imageIds = other.m_imageIds;
102 m_imageList = new ImageList(*other.m_imageList);
103 m_shapeIds = other.m_shapeIds;
104 m_shapeList = new ShapeList(*other.m_shapeList);
105 m_correlationMatrix = other.m_correlationMatrix;
106 m_controlList = other.m_controlList;
107 m_guiCamera = other.m_guiCamera;
108 m_targetBody = other.m_targetBody;
109 m_fileItem = other.m_fileItem;
110 m_internalData = other.m_internalData;
111 m_template = other.m_template;
112
113 m_isUndoable = other.m_isUndoable;
114 m_isSavedToHistory = other.m_isSavedToHistory;
115 m_isSynchronous = other.m_isSynchronous;
116
117 m_createsCleanState = other.m_createsCleanState;
118 m_modifiesDiskState = other.m_modifiesDiskState;
119
120 m_executionTime = other.m_executionTime;
121
122 m_status = other.m_status;
123 m_queuedAction = other.m_queuedAction;
124
125 m_secondsElapsed = other.m_secondsElapsed;
126
127 m_progressRangeMinValue = other.m_progressRangeMinValue;
128 m_progressRangeMaxValue = other.m_progressRangeMaxValue;
129 m_progressValue = other.m_progressValue;
130
131 m_futureWatcher = new QFutureWatcher<void>;
132 m_transparentConstMutex = new QMutex;
133
134 if (!other.isInStableState()) {
136 tr("Can not copy work order [%1] because it is currently running")
137 .arg(((QUndoCommand &)other).text()),
138 _FILEINFO_);
139 }
140
141 connect(this, SIGNAL(triggered()),
142 this, SLOT(addCloneToProject()));
143 connect(m_futureWatcher, SIGNAL(finished()),
144 this, SLOT(executionFinished()));
145
148 }
149
150
155
156 delete m_imageList;
157 delete m_shapeList;
158 delete m_futureWatcher;
162
163 m_nextWorkOrder = NULL;
164 m_previousWorkOrder = NULL;
165 m_project = NULL;
167 }
168
169
180 return false;
181 }
182
183
194 return false;
195 }
196
197
208 return false;
209 }
210
211
219//bool WorkOrder::isExecutable(Control *control) {
220// return false;
221//}
222
223
232 return false;
233 }
234
235
236 bool WorkOrder::isExecutable(CorrelationMatrix correlationMatrix) {
237 return false;
238 }
239
240
246 m_context = context;
247 }
248
249 void WorkOrder::setData(QString data) {
250 m_data = data;
251 }
252
253
259 m_imageIds.clear();
260 delete m_imageList;
261
262 m_imageList = new ImageList(*images);
264 }
265
266
272 m_shapeIds.clear();
273 delete m_shapeList;
274
275 m_shapeList = new ShapeList(*shapes);
277 }
278
279
284//void WorkOrder::setData(Control *control) {
285// m_control = control;
286//}
287
288
295 m_controlList = controls;
296 }
297
298
303 void WorkOrder::setData(CorrelationMatrix correlationMatrix) {
304 m_correlationMatrix = correlationMatrix;
305 }
306
307
308
309
317
318
323 void WorkOrder::setData(Template *currentTemplate) {
324 m_template = currentTemplate;
325 }
326
327
334 }
335
336
343 }
344
345
351 if ( item->isProject() ) {
352 setData( ProjectContext );
353 }
354 else if ( item->isImageList() ) {
355 setData( item->imageList() );
356 }
357 else if ( item->isImage() ) {
358 ImageList *imageList = new ImageList(this);
359 imageList->append( item->image() );
361 }
362 else if ( item->isShapeList() ) {
363 setData( item->shapeList() );
364 }
365 else if ( item->isShape() ) {
366 ShapeList *shapeList = new ShapeList(this);
367 shapeList->append( item->shape() );
369 }
370 else if (item->isControlList()) {
371 setData( item->controlList() );
372 }
373 else if ( item->isControl() ) {
375 controlList->append( item->control() );
377// //setData(*controlList);
378 }
379 else if ( item->isCorrelationMatrix() ) {
380 setData( item->correlationMatrix() );
381 }
382 else if ( item->isTargetBody() ) {
383 setData( item->targetBody() );
384 }
385 else if ( item->isGuiCamera() ) {
386 setData( item->guiCamera() );
387 }
388 else if ( item->isFileItem() ) {
389 setData( item->fileItem() );
390 }
391 else if ( item->isTemplate() ) {
392 setData( item->getTemplate() );
393 }
394 }
395
396
397
398
399
408 return false;
409 }
410
411
419 bool WorkOrder::isExecutable(Template *currentTemplate) {
420 return false;
421 }
422
423
432 return false;
433 }
434
435
444 return false;
445 }
446
447
456 if ( !item ) {
457 return false;
458 }
459 else if ( item->isProject() ) {
460 return isExecutable( ProjectContext );
461 }
462 else if ( item->isImageList() ) {
463 return isExecutable( item->imageList() );
464 }
465 else if ( item->isImage() ) {
467 imageList->append( item->image() );
468 bool ret = isExecutable(imageList);
469 imageList->deleteLater();
470 return ret;
471 }
472 else if ( item->isShapeList() ) {
473 return isExecutable( item->shapeList() );
474 }
475 else if ( item->isShape() ) {
477 shapeList->append( item->shape() );
478 bool ret = isExecutable(shapeList);
479 shapeList->deleteLater();
480 return ret;
481 }
482 else if ( item->isControlList() ) {
483 return isExecutable (item -> controlList() );
484 }
485 else if ( item->isControl() ) {
487 controlList->append( item->control() );
488 bool ret = isExecutable(controlList);
489 controlList->deleteLater();
490 return ret;
491 }
492 else if ( item->isCorrelationMatrix() ) {
493 return isExecutable( item->correlationMatrix() );
494 }
495 else if ( item->isTargetBody() ) {
496 //return isExecutable( item->targetBody() ) || isExecutable( item->targetBody().data() );
497 return isExecutable(item->targetBody());
498 }
499 else if ( item->isGuiCamera() ) {
500 //return isExecutable( item->guiCamera() ) || isExecutable( item->guiCamera().data() );
501 return isExecutable( item->guiCamera() );
502 }
503 else if ( item->isFileItem() ) {
504 return isExecutable( item->fileItem() );
505 }
506 else if ( item->isTemplate() ) {
507 return isExecutable( item->getTemplate() );
508 }
509
510 return false;
511 }
512
532 void WorkOrder::save(QXmlStreamWriter &stream) const {
533 if (!isInStableState()) {
535 tr("Can not store an unstable work order. The work order [%1] is currently "
536 "working").arg(bestText()),
537 _FILEINFO_);
538 }
539
540 stream.writeStartElement("workOrder");
541
542 stream.writeAttribute("actionText", QAction::text());
543 stream.writeAttribute("undoText", QUndoCommand::text());
544 stream.writeAttribute("executionTime", m_executionTime.toString());
545 stream.writeAttribute("type", metaObject()->className());
546 stream.writeAttribute("status", toString(m_status));
547
548 if (m_imageIds.count()) {
549 stream.writeStartElement("images");
550
551 foreach (QString imageId, m_imageIds) {
552 stream.writeStartElement("image");
553 stream.writeAttribute("id", imageId);
554 stream.writeEndElement();
555 }
556
557 stream.writeEndElement();
558 }
559
560 if (m_shapeIds.count()) {
561 stream.writeStartElement("shapes");
562
563 foreach (QString shapeId, m_shapeIds) {
564 stream.writeStartElement("shape");
565 stream.writeAttribute("id", shapeId);
566 stream.writeEndElement();
567 }
568
569 stream.writeEndElement();
570 }
571
572 if (m_internalData.count()) {
573 stream.writeStartElement("internalDataValues");
574
575 foreach (QString str, m_internalData) {
576 stream.writeStartElement("dataValue");
577 stream.writeAttribute("value", str);
578 stream.writeEndElement();
579 }
580
581 stream.writeEndElement();
582 }
583
584 if (m_context != NoContext) {
585 stream.writeStartElement("context");
586
587 QString contextStr = "ProjectContext";
588 stream.writeAttribute("value", contextStr);
589
590 stream.writeEndElement();
591 }
592
593 stream.writeEndElement();
594 }
595
596
601 void WorkOrder::setNext(WorkOrder *nextWorkOrder) {
602 m_nextWorkOrder = nextWorkOrder;
603 }
604
605
610 void WorkOrder::setPrevious(WorkOrder *previousWorkOrder) {
611 m_previousWorkOrder = previousWorkOrder;
612 }
613
614
620 QMutexLocker locker(project()->workOrderMutex());
621 if (!m_imageList) {
622 bool anyImagesAreNull = false;
623
624 m_imageList = new ImageList;
625
626 foreach (QString id, m_imageIds) {
627 Image *image = project()->image(id);
628 m_imageList->append(image);
629
630 if (!image) {
631 anyImagesAreNull = true;
632 }
633 }
634
635 if (anyImagesAreNull) {
636 delete m_imageList;
637 }
638 else {
640 }
641 }
642
643 return m_imageList;
644 }
645
646
652 QMutexLocker locker(project()->workOrderMutex());
653 if (!m_shapeList) {
654 bool anyShapesAreNull = false;
655
656 m_shapeList = new ShapeList;
657
658 foreach (QString id, m_shapeIds) {
659 Shape *shape = project()->shape(id);
660 m_shapeList->append(shape);
661
662 if (!shape) {
663 anyShapesAreNull = true;
664 }
665 }
666
667 if (anyShapesAreNull) {
668 delete m_shapeList;
669 }
670 else {
672 }
673 }
674
675 return
676 m_shapeList;
677 }
678
679
685 QMutexLocker locker(project()->workOrderMutex());
686 return m_correlationMatrix;
687 }
688
689
694 QPointer<ControlList> WorkOrder::controlList() {
695 QMutexLocker locker(project()->workOrderMutex());
696 return m_controlList;
697 }
698
699
705 QMutexLocker lock(m_transparentConstMutex);
706 return const_cast<WorkOrder *>(this)->imageList();
707 }
708
709
715 QMutexLocker lock(m_transparentConstMutex);
716 return const_cast<WorkOrder *>(this)->shapeList();
717 }
718
719
725 QMutexLocker locker(project()->workOrderMutex());
726 return m_template;
727 }
728
729
735 QMutexLocker locker(project()->workOrderMutex());
736 return m_targetBody;
737 }
738
739
745 QMutexLocker locker(project()->workOrderMutex());
746 return m_guiCamera;
747 }
748
749
755 QMutexLocker locker(project()->workOrderMutex());
756 return m_fileItem;
757 }
758
759
770 return true;
771 }
772
773
783 QString WorkOrder::bestText() const {
784 QString result = QUndoCommand::text().remove("&").remove("...");
785
786 // if the QUndoCommand has no text, create a warning
787 if (result.isEmpty()) {
788 // get the name of the work order
789 result = QString(metaObject()->className()).remove("Isis::").remove("WorkOrder")
790 .replace(QRegExp("([a-z0-9])([A-Z])"), "\\1 \\2");
791 qWarning() << QString("WorkOrder::bestText(): Work order [%1] has no QUndoCommand text")
792 .arg(result);
793 }
794
795 return result;
796 }
797
798
808 QMutexLocker locker(project()->workOrderMutex());
809 return m_isUndoable;
810 }
811
812
819 QMutexLocker locker(project()->workOrderMutex());
820 return m_isSavedToHistory;
821 }
822
823
830 QMutexLocker locker(project()->workOrderMutex());
831 return m_isSynchronous;
832 }
833
834
843 QMutexLocker locker(project()->workOrderMutex());
844 return m_createsCleanState;
845 }
846
847
852 QDateTime WorkOrder::executionTime() const {
853 QMutexLocker locker(project()->workOrderMutex());
854 return m_executionTime;
855 }
856
857
863 return m_status == WorkOrderFinished;
864 }
865
866
871 bool WorkOrder::isRedoing() const {
872 QMutexLocker locker(project()->workOrderMutex());
873 return m_status == WorkOrderRedoing;
874 }
875
876
881 bool WorkOrder::isRedone() const {
882 QMutexLocker locker(project()->workOrderMutex());
883 return m_status == WorkOrderRedone;
884 }
885
886
891 bool WorkOrder::isUndoing() const {
892 QMutexLocker locker(project()->workOrderMutex());
893 return m_status == WorkOrderUndoing;
894 }
895
896
901 bool WorkOrder::isUndone() const {
902 QMutexLocker locker(project()->workOrderMutex());
903 return m_status == WorkOrderUndone;
904 }
905
906
913 QMutexLocker locker(project()->workOrderMutex());
914 return m_modifiesDiskState;
915 }
916
917
923 QMutexLocker locker(project()->workOrderMutex());
924 return m_nextWorkOrder;
925 }
926
927
933 QMutexLocker locker(project()->workOrderMutex());
934 return m_previousWorkOrder;
935 }
936
937
942 QString WorkOrder::statusText() const {
943 QMutexLocker locker(project()->workOrderMutex());
944 QString result = toString(m_status);
945
946 if (m_secondsElapsed) {
947 // QTime can't format in the way that I want (0-n minutes, 00-59 seconds, no hours
948 // displayed)... so do it manually.
949 // Expected output format examples: 0:01, 0:55, 1:30, 55:55, 90:00, 100:12
950 int seconds = qRound(m_secondsElapsed) % 60;
951 int minutes = qRound(m_secondsElapsed) / 60;
952 result += tr(" (elapsed: %1:%2)").arg(minutes).arg(seconds, 2, 10, QChar('0'));
953 }
954
955 return result;
956 }
957
958
964 QMutexLocker locker(project()->workOrderMutex());
965 return m_progressBar;
966 }
967
968
977 statusString = statusString.toUpper();
978 WorkOrderStatus result = WorkOrderUnknownStatus;
979
980 for (WorkOrderStatus possibleResult = WorkOrderUnknownStatus;
981 possibleResult <= WorkOrderLastStatus;
982 possibleResult = (WorkOrderStatus)(possibleResult + 1)) {
983 if (statusString == toString(possibleResult).toUpper()) {
984 result = possibleResult;
985 }
986 }
987
988 return result;
989 }
990
991
998 QString result;
999
1000 switch (status) {
1001 case WorkOrderUnknownStatus:
1002 result = tr("Unknown");
1003 break;
1004 case WorkOrderNotStarted:
1005 result = tr("Not Started");
1006 break;
1007 case WorkOrderRedoing:
1008 result = tr("In Progress");
1009 break;
1010 case WorkOrderRedone:
1011 result = tr("Completed");
1012 break;
1013 case WorkOrderUndoing:
1014 result = tr("Undoing");
1015 break;
1016 case WorkOrderUndone:
1017 result = tr("Undone");
1018 break;
1019 case WorkOrderFinished:
1020 result = tr("Finished");
1021 break;
1022 }
1023
1024 return result;
1025 }
1026
1027
1032 if (!isInStableState()) {
1033 m_queuedAction = RedoQueuedAction;
1034 }
1035
1036 if (!isRedone()) {
1037 bool mustQueueThisRedo = false;
1038
1039 WorkOrder *dependency = NULL;
1040 WorkOrder *current = this;
1041 while (current->previous() && !dependency) {
1042 if (!current->previous()->isRedone() && !current->previous()->isFinished()) {
1043 WorkOrder *possibleDependency = current->previous();
1044
1045 if (dependsOn(possibleDependency)) {
1046 connect(possibleDependency, SIGNAL(finished(WorkOrder *)),
1047 this, SLOT(attemptQueuedAction()));
1048 dependency = possibleDependency;
1049 mustQueueThisRedo = true;
1050 }
1051 }
1052
1053 current = current->previous();
1054 }
1055
1056 if (!imageList()) {
1057 connect(project(), SIGNAL(imagesAdded(ImageList *)),
1058 this, SLOT(attemptQueuedAction()));
1059 mustQueueThisRedo = true;
1060 }
1061
1062 if (!shapeList()) {
1063 connect(project(), SIGNAL(shapesAdded(ShapeList *)),
1064 this, SLOT(attemptQueuedAction()));
1065 mustQueueThisRedo = true;
1066 }
1067
1068 if (mustQueueThisRedo && !isUndoing() && !isRedoing()) {
1069
1070 m_queuedAction = RedoQueuedAction;
1071
1072 QString queueStatusText;
1073
1074 if (dependency) {
1075 QString dependencyText = dependency->bestText();
1076
1077 if (dependencyText.count() > 5) {
1078 dependencyText = dependencyText.mid(0, 5) + "...";
1079 }
1080
1081 queueStatusText = tr("Wait for [%1]").arg(dependencyText);
1082 }
1083 else if (!imageList()) {
1084 queueStatusText = tr("Wait for images");
1085 }
1086 else if (!shapeList()) {
1087 queueStatusText = tr("Wait for shapes");
1088 }
1089
1091 m_progressBar->setValue(m_progressBar->minimum());
1092 m_progressBar->setText(queueStatusText);
1093 m_progressBar->update();
1094 }
1095
1096 if (m_queuedAction == NoQueuedAction) {
1097 m_status = WorkOrderRedoing;
1098 emit statusChanged(this);
1099
1101 m_progressBar->setText("Starting...");
1102 m_progressBar->update();
1103
1104 delete m_elapsedTimer;
1105 m_elapsedTimer = new QElapsedTimer;
1106 m_elapsedTimer->start();
1107
1108 if (isSynchronous()) {
1109 execute();
1111 }
1112 else {
1113 m_progressBar->setText("Running...");
1114 m_progressBar->update();
1115 // queue the workorder for asynchronous execution
1116 QFuture<void> future = QtConcurrent::run(this, &WorkOrder::execute);
1117 // executionFinished() is called via the finished signal. The
1118 // connection is setup in the constructor.
1119 m_futureWatcher->setFuture(future);
1120 }
1121 }
1122 }
1123 else {
1125 }
1126 }
1127
1128
1135 if (!isInStableState()) {
1136 m_queuedAction = UndoQueuedAction;
1137 }
1138
1139 if (!isUndone() && m_status != WorkOrderNotStarted) {
1140 WorkOrder *dependency = NULL;
1141 WorkOrder *current = this;
1142 while (current->next() && !dependency) {
1143 if (!current->next()->isUndone() && !current->next()->isFinished() &&
1144 current->next()->m_status != WorkOrderNotStarted) {
1145 connect(current->next(), SIGNAL(finished(WorkOrder *)),
1146 this, SLOT(attemptQueuedAction()));
1147 m_queuedAction = UndoQueuedAction;
1148 dependency = current->next();
1149 }
1150
1151 current = current->next();
1152 }
1153
1154 if (dependency && !isUndoing() && !isRedoing()) {
1155 QString prevText = dependency->bestText();
1156
1157 if (prevText.count() > 5) {
1158 prevText = prevText.mid(0, 5) + "...";
1159 }
1160
1162 m_progressBar->setValue(m_progressBar->minimum());
1163 m_progressBar->setText(tr("Undo after [%1]").arg(prevText));
1164 m_progressBar->update();
1165 }
1166
1167 if (m_queuedAction == NoQueuedAction) {
1168 m_status = WorkOrderUndoing;
1169 emit statusChanged(this);
1170
1172 m_progressBar->setText("Starting Undo...");
1173 m_progressBar->update();
1174
1175 delete m_elapsedTimer;
1176 m_elapsedTimer = new QElapsedTimer;
1177 m_elapsedTimer->start();
1178
1179 if (isSynchronous()) {
1180 undoExecution();
1182 }
1183 else {
1184 m_progressBar->setText("Undoing...");
1185 m_progressBar->update();
1186 // queue the workorder for asynchronous execution
1187 QFuture<void> future = QtConcurrent::run(this, &WorkOrder::undoExecution);
1188 // executionFinished() is called via the finished signal. The
1189 // connection is setup in the constructor.
1190 m_futureWatcher->setFuture(future);
1191 }
1192 }
1193 }
1194 else {
1196 }
1197 }
1198
1207 setEnabled(true);
1208 }
1209
1210
1219 setEnabled(false);
1220 }
1221
1222
1250 // We're finished at this point if we save/open a project, we're not finished if we need to do
1251 // redo()
1252 if (createsCleanState() || !isUndoable()) {
1253 m_status = WorkOrderFinished;
1254
1255 emit statusChanged(this);
1256 }
1257
1258 m_executionTime = QDateTime::currentDateTime();
1259
1261
1262 if (createsCleanState() || !isUndoable()) {
1264 }
1265 else {
1266 m_progressBar->setText("Initializing...");
1267 }
1268
1269 return true;
1270 }
1271
1272
1279 return project()->directory();
1280 }
1281
1282
1289 if (!m_project) {
1291 "This work order no longer has a project.", _FILEINFO_);
1292 }
1293
1294 return m_project;
1295 }
1296
1297
1309
1310
1316 QMutexLocker locker(project()->workOrderMutex());
1318 }
1319
1320
1326 QMutexLocker locker(project()->workOrderMutex());
1328 }
1329
1330
1336 QMutexLocker locker(project()->workOrderMutex());
1337 return m_progressValue;
1338 }
1339
1340
1346 void WorkOrder::setProgressRange(int minValue, int maxValue) {
1347 m_progressRangeMinValue = minValue;
1348 m_progressRangeMaxValue = maxValue;
1349 }
1350
1351
1357 m_progressValue = value;
1358 }
1359
1360
1366 QMutexLocker locker(project()->workOrderMutex());
1367 return m_internalData;
1368 }
1369
1370
1392 }
1393
1394
1404
1405
1424
1425
1435
1436
1441 if (project()) {
1442 project()->addToProject(clone());
1443 }
1444 }
1445
1446
1452 bool result = true;
1453
1454 if (isRedoing() || isUndoing() || m_queuedAction != NoQueuedAction) {
1455 result = false;
1456 }
1457
1458 return result;
1459 }
1460
1461
1468 m_imageIds.clear();
1469 foreach (Image *image, *m_imageList) {
1470 if (image) {
1471 m_imageIds.append(image->id());
1472
1473 // If we lose any images, destroy the entire list. This will let us know that we need to
1474 // rebuild it, if needed, when requested.
1475 connect(image, SIGNAL(destroyed(QObject *)),
1476 this, SLOT(clearImageList()));
1477 }
1478 }
1479 }
1480
1481
1491 m_shapeIds.clear();
1492 foreach (Shape *shape, *m_shapeList) {
1493 if (shape) {
1494 m_shapeIds.append(shape->id());
1495
1496 // If we lose any shapes, destroy the entire list. This will let us know that we need to
1497 // rebuild it, if needed, when requested.
1498 connect(shape, SIGNAL(destroyed(QObject *)),
1499 this, SLOT(clearShapeList()));
1500 }
1501 }
1502 }
1503
1504
1510
1511 if (!m_progressBar) {
1513 emit creatingProgress(this);
1514 }
1515
1517 m_progressBarUpdateTimer = new QTimer;
1518 connect(m_progressBarUpdateTimer, SIGNAL(timeout()),
1519 this, SLOT(updateProgress()));
1520 m_progressBarUpdateTimer->start(100);
1521 }
1522
1525 m_progressValue = 0;
1526 }
1527
1528
1533 if (m_progressBar) {
1534 if (isRedone()) {
1535 m_progressBar->setText(tr("Finished"));
1536 }
1537 else if (isUndone() || m_status == WorkOrderNotStarted) {
1538 m_progressBar->setText(tr("Undone"));
1539 }
1540
1541 if (m_progressBar->minimum() != 0 || m_progressBar->maximum() != 0) {
1542 m_progressBar->setValue(m_progressBar->maximum());
1543 }
1544 else {
1545 m_progressBar->setRange(0, 100);
1546 m_progressBar->setValue(100);
1547 }
1548
1550 m_progressBarDeletionTimer = new QTimer;
1551 m_progressBarDeletionTimer->setSingleShot(true);
1552
1553 m_progressBarDeletionTimer->start(5 * 1000); // 5 seconds
1554
1555 m_progressBar->update();
1556 }
1557 }
1558
1559
1564 QueuedWorkOrderAction queued = m_queuedAction;
1565 m_queuedAction = NoQueuedAction;
1566
1567 if (queued == RedoQueuedAction && m_status != WorkOrderRedone) {
1568 redo();
1569 }
1570 else if (queued == UndoQueuedAction && m_status != WorkOrderUndone) {
1571 undo();
1572 }
1573 }
1574
1575
1582
1583 WorkOrderStatus finishedStatus = WorkOrderRedone;
1584 void (WorkOrder::*postMethod)() = &WorkOrder::postExecution;
1585
1586 if (isUndoing()) {
1587 finishedStatus = WorkOrderUndone;
1588 postMethod = &WorkOrder::postUndoExecution;
1589 }
1590
1591 (this->*postMethod)();
1592
1593 m_status = finishedStatus;
1594
1595 m_secondsElapsed = m_elapsedTimer->elapsed() / 1000.0;
1596
1597 delete m_elapsedTimer;
1598 m_elapsedTimer = NULL;
1599
1600 emit statusChanged(this);
1602 emit finished(this);
1603
1605 }
1606
1607
1612 delete m_imageList;
1613 }
1614
1615
1620 delete m_shapeList;
1621 }
1622
1623
1633
1634
1639 }
1640
1641
1651 void WorkOrder::setCreatesCleanState(bool createsCleanState) {
1653 }
1654
1655
1662 void WorkOrder::setModifiesDiskState(bool changesProjectOnDisk) {
1663 m_modifiesDiskState = changesProjectOnDisk;
1664 }
1665}
Maintains a list of Controls so that control nets can easily be copied from one Project to another,...
Definition ControlList.h:42
This is a container for the correlation matrix that comes from a bundle adjust.
Isis exception class.
Definition IException.h:91
@ Unknown
A type of error that cannot be classified as any of the other error types.
Definition IException.h:118
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition IException.h:146
This represents a cube in a project-based GUI interface.
Definition Image.h:105
QString id() const
Get a unique, identifying string associated with this image.
Definition Image.cpp:420
Internalizes a list of images and allows for operations on the entire list.
Definition ImageList.h:53
void append(Image *const &value)
Appends an image to the image list.
The main project for ipce.
Definition Project.h:287
Shape * shape(QString id)
Return a shape given its id.
Definition Project.cpp:1600
void addToProject(WorkOrder *)
This executes the WorkOrder and stores it in the project.
Definition Project.cpp:2659
Directory * directory() const
Returns the directory associated with this Project.
Definition Project.cpp:1226
Image * image(QString id)
Return an image given its id.
Definition Project.cpp:1570
Represents an item of a ProjectItemModel in Qt's model-view framework.
TargetBodyQsp targetBody() const
Returns the TargetBodyQsp stored in the data of the item.
bool isShape() const
Returns true if an Shape is stored in the data of the item.
Template * getTemplate() const
Returns the Template stored in the data of the item.
bool isProject() const
Returns true if a Project is stored in the data of the item.
FileItemQsp fileItem() const
Returns the FileItemQsp stored in the data of the item.
ShapeList * shapeList() const
Returns the ShapeList stored in the data of the item.
bool isControl() const
Returns true if a Control is stored in the data of the item.
bool isControlList() const
Returns true if a ControlList is stored in the data of the item.
bool isShapeList() const
Returns true if an ShapeList is stored in the data of the item.
CorrelationMatrix correlationMatrix() const
Returns the CorrelationMatrix stored the item.
Shape * shape() const
Returns the Shape 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.
bool isFileItem() const
Returns true if a FileItemQsp is stored in the data of the item.
Control * control() const
Returns the Control stored in the data of the item.
Image * image() const
Returns the Image stored in the data of the item.
ControlList * controlList() const
Returns the ControlList stored in the data of the item.
bool isImage() const
Returns true if an Image is stored in the data of the item.
GuiCameraQsp guiCamera() const
Returns the GuiCameraQsp stored in the data of the item.
bool isGuiCamera() const
Returns true if a GuiCameraQsp is stored in the data of the item.
bool isCorrelationMatrix() const
Returns true if a CorrelationMatrix is stored in the data of the item.
bool isTargetBody() const
Returns true if a TargetBodyQsp is stored in the data of the item.
This represents a shape in a project-based GUI interface.
Definition Shape.h:66
QString id() const
Get a unique, identifying string associated with this shape.
Definition Shape.cpp:443
Internalizes a list of shapes and allows for operations on the entire list.
Definition ShapeList.h:31
void append(Shape *const &value)
Appends an shape to the shape list.
Provide Undo/redo abilities, serialization, and history for an operation.
Definition WorkOrder.h:311
void enableWorkOrder()
Enables the work order.
QPointer< QTimer > m_progressBarUpdateTimer
A pointer to the QTimer which updates the ProgressBar.
Definition WorkOrder.h:640
QStringList m_imageIds
A QStringList of unique image identifiers for all of the images this WorkOrder is dealing with.
Definition WorkOrder.h:584
void setNext(WorkOrder *nextWorkOrder)
Sets the next WorkOrder in the sequence.
void updateProgress()
Updates the progress bar.
ShapeList * shapeList()
@briefReturns a pointer to the ShapeList for this WorkOrder.
bool m_isSavedToHistory
Set the work order to be shown in the HistoryTreeWidget.
Definition WorkOrder.h:511
QueuedWorkOrderAction
This enum describes the current state of a Queued WorkOrder.
Definition WorkOrder.h:482
void setProgressRange(int, int)
Sets the progress range of the WorkOrder.
int progressMax() const
Gets the maximum value of the progress range of the WorkOrder.
QStringList m_shapeIds
A QStringList of unique shape identifiers for all of the shapes this WorkOrder is dealing with.
Definition WorkOrder.h:590
virtual void setData(Context)
Sets the context data for this WorkOrder.
WorkOrder * next() const
Gets the next WorkOrder.
bool modifiesDiskState() const
Returns the modified disk state.
bool m_isSynchronous
This is defaulted to true.
Definition WorkOrder.h:504
bool isUndoing() const
Returns the WorkOrderUndoing state.
void attemptQueuedAction()
Attempts to execute an action on the action queue.
virtual void undoExecution()
Execute the steps necessary to undo this workorder.
virtual void postUndoExecution()
Perform any steps necessary after an undo of a workorder.
Template * getTemplate()
WorkOrder::getTemplate.
Template * m_template
A QSharedPointer to the Template (A Template object but encapsulated within a Gui framework.
Definition WorkOrder.h:564
void save(QXmlStreamWriter &stream) const
: Saves a WorkOrder to a data stream.
void clearShapeList()
Clears the list of shapes.
bool isRedone() const
Returns the WorkOrder redone status.
void executionFinished()
Signals the Project that the WorkOrder is finished, deletes the update time for the Progress bar,...
virtual void redo()
Starts (or enqueues) a redo.
WorkOrderStatus
This enumeration is used by other functions to set and retrieve the current state of the WorkOrder.
Definition WorkOrder.h:321
@ WorkOrderFinished
This is used for work orders that will not undo or redo (See createsCleanState())
Definition WorkOrder.h:331
virtual void undo()
Starts (or enqueues) an undo.
int progressMin() const
Gets the minimum value of the progress range of the WorkOrder.
bool isUndoable() const
Returns true if this work order is undoable, otherwise false.
WorkOrder * previous() const
Gets the previous WorkOrder.
bool m_isUndoable
Set the workorder to be undoable/redoable This is defaulted to true - his will allow the workorder to...
Definition WorkOrder.h:497
void setProgressValue(int)
Sets the current progress value for the WorkOrder.
static QString toString(WorkOrderStatus)
Gets the current status of the WorkOrder.
bool isUndone() const
Returns the WorkOrder undo status.
virtual bool setupExecution()
This sets up the state for the work order.
void setProgressToFinalText()
Sets the ProgressBar to display the final status of the operation.
QDateTime m_executionTime
This is the date/time that setupExecution() was called.
Definition WorkOrder.h:621
bool m_createsCleanState
This is defaulted to false.
Definition WorkOrder.h:523
bool isSavedToHistory() const
Returns true if this work order is to be shown in History, otherwise false.
bool isInStableState() const
Determines if the WorkOrder is in a stable state, or if it's busy doing something.
GuiCameraQsp m_guiCamera
A QSharedPointer to the GuiCamera (the Camera object but encapsulated within a Gui framework.
Definition WorkOrder.h:557
QPointer< WorkOrder > m_previousWorkOrder
A pointer to the previous WorkOrder in the queue.
Definition WorkOrder.h:605
static WorkOrderStatus fromStatusString(QString)
Attempts to query the current status of the WorkOrder.
bool isRedoing() const
Returns the redoing status of this WorkOrder.
int m_progressRangeMaxValue
The maximum value of the Progess Bar.
Definition WorkOrder.h:541
QStringList internalData() const
Gets the internal data for this WorkOrder.
QPointer< ControlList > controlList()
Returns the Control List for this WorkOrder (a list of control networks).
Directory * directory() const
return the workorder project directory Returns the Directory object of the Project this WorkOrder is ...
int m_progressValue
The current value of the Progress Bar.
Definition WorkOrder.h:545
GuiCameraQsp guiCamera()
WorkOrder::guiCamera.
void setCreatesCleanState(bool createsCleanState)
Declare that this work order is saving the project.
QString statusText() const
WorkOrder::statusText.
QDateTime executionTime() const
Gets the execution time of this WorkOrder.
virtual void execute()
Execute the workorder.
void setModifiesDiskState(bool changesProjectOnDisk)
QPointer< ProgressBar > m_progressBar
A pointer to the ProgressBar.
Definition WorkOrder.h:635
void setPrevious(WorkOrder *previousWorkOrder)
Sets the previous WorkOrder in the sequence.
void listenForShapeDestruction()
Checks to see if we have lost any shapes in the ShapeList.
virtual bool isExecutable(Context)
Re-implement this method if your work order utilizes controls for data in order to operate.
void disableWorkOrder()
Disables the work order.
bool createsCleanState() const
Returns the CleanState status (whether the Project has been saved to disk or not).
TargetBodyQsp targetBody()
WorkOrder::targetBody.
double m_secondsElapsed
The seconds that have elapsed since the WorkOrder started executing.
Definition WorkOrder.h:656
void setInternalData(QStringList data)
Sets the internal data for this WorkOrder.
int m_progressRangeMinValue
The miniumum value of the Progess Bar.
Definition WorkOrder.h:537
virtual bool dependsOn(WorkOrder *other) const
Indicate workorder dependency This is a virtual function whose role in child classes is to determine ...
QElapsedTimer * m_elapsedTimer
A QElapsedTimer object holding the excecution time of the WorkOrder.
Definition WorkOrder.h:651
Project * project() const
Returns the Project this WorkOrder is attached to.
void clearImageList()
Clears the list of images.
QPointer< Project > m_project
A pointer to the Project this WorkOrder is attached to.
Definition WorkOrder.h:610
virtual ~WorkOrder()
The Destructor.
ProgressBar * progressBar()
Returns the ProgressBar.
QStringList m_internalData
A QStringList of internal properties for this WorkOrder.
Definition WorkOrder.h:595
bool m_modifiesDiskState
This is defaulted to false.
Definition WorkOrder.h:530
QMutex * m_transparentConstMutex
This is used to protect the integrity of data the WorkOrder is working on so that only one thread at ...
Definition WorkOrder.h:616
QPointer< WorkOrder > m_nextWorkOrder
A pointer to the next WorkOrder in the queue.
Definition WorkOrder.h:600
void addCloneToProject()
Runs a copy of the current WorkOrder and stores it in the project.
void startRedo()
WorkOrder::startRedo This function is currently empty.
void resetProgressBar()
Resets the ProgressBar.
FileItemQsp m_fileItem
A QSharedPointer to the FileItem.
Definition WorkOrder.h:577
ImageList * imageList()
Returns a pointer to the ImageList for this WorkOrder.
bool isSynchronous() const
Returns true if this work order is run synchronously, otherwise false.
Context
This enumeration is for recording the context of the current Workorder (whether it is part of a proje...
Definition WorkOrder.h:339
QString bestText() const
Generate unique action names We don't use action text anymore because Directory likes to rename our a...
int progressValue() const
Gets the current progress value of the WorkOrder.
bool isFinished() const
Returns the finished state of this WorkOrder.
virtual void postExecution()
Perform any necessary actions after execution of a workorder.
QPointer< QFutureWatcher< void > > m_futureWatcher
A pointer to a QFutureWatcher object which monitors a QFuture object using signals and slots.
Definition WorkOrder.h:628
CorrelationMatrix correlationMatrix()
Returns the CorrleationMatrix for this WorkOrder.
QPointer< QTimer > m_progressBarDeletionTimer
A pointer to the ProgressBar deletion timer.
Definition WorkOrder.h:645
void listenForImageDestruction()
Checks to see if we have lost any images in the ImageList.
FileItemQsp fileItem()
WorkOrder::fileItem.
WorkOrder(Project *project)
Create a work order that will work with the given project.
Definition WorkOrder.cpp:38
TargetBodyQsp m_targetBody
A QSharedPointer to the TargetBody (A Target object but encapsulated within a Gui framework.
Definition WorkOrder.h:571
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:184
QSharedPointer< FileItem > FileItemQsp
A FileItem smart pointer.
Definition FileItem.h:36