Isis 3 Programmer Reference
WorkOrder.cpp
Go to the documentation of this file.
1 
23 #include "IsisDebug.h"
24 
25 #include "WorkOrder.h"
26 
27 #include <QDebug>
28 #include <QFutureWatcher>
29 #include <QMutex>
30 #include <QMutexLocker>
31 #include <QtConcurrentRun>
32 #include <QTimer>
33 #include <QXmlStreamWriter>
34 
35 #include "ControlList.h"
36 #include "IException.h"
37 #include "ImageList.h"
38 #include "IString.h"
39 #include "ProgressBar.h"
40 #include "Project.h"
41 #include "ProjectItem.h"
42 #include "ShapeList.h"
43 #include "Template.h"
44 #include "XmlStackedHandlerReader.h"
45 
46 
47 namespace Isis {
55  WorkOrder::WorkOrder(Project *project) : QAction(project) {
57 
58  m_context = NoContext;
59  m_data = "";
60  m_imageList = new ImageList;
61  m_shapeList = new ShapeList;
62  m_controlList = NULL;
63  m_correlationMatrix = CorrelationMatrix();
66  m_template = NULL;
68 
69  m_isUndoable = true;
70  m_isSavedToHistory = true;
71  m_isSynchronous = true;
72 
73  m_createsCleanState = false;
74  m_modifiesDiskState = false;
75  m_status = WorkOrderNotStarted;
76  m_queuedAction = NoQueuedAction;
78  m_elapsedTimer = NULL;
79 
81  m_transparentConstMutex = new QMutex;
82 
85  m_progressValue = 0;
86 
87  m_secondsElapsed = 0.0;
88 
89  if (!m_project) {
91  tr("Work orders cannot be created without a project."), _FILEINFO_);
92  }
93 
94  connect(this, SIGNAL(triggered()),
95  this, SLOT(addCloneToProject()));
96  connect(m_futureWatcher, SIGNAL(finished()),
97  this, SLOT(executionFinished()));
98  }
99 
100 
108  QAction(other.icon(), ((QAction &)other).text(), other.parentWidget()),
109  QUndoCommand(((QUndoCommand &)other).text()) {
110  // Copy the action's what's this and tool tip (hover text).
111  QAction::setWhatsThis(other.whatsThis());
112  QAction::setToolTip(other.toolTip());
113 
115  m_elapsedTimer = NULL;
116  m_project = other.project();
117  m_context = other.m_context;
118  m_imageIds = other.m_imageIds;
119  m_imageList = new ImageList(*other.m_imageList);
120  m_shapeIds = other.m_shapeIds;
121  m_shapeList = new ShapeList(*other.m_shapeList);
122  m_correlationMatrix = other.m_correlationMatrix;
123  m_controlList = other.m_controlList;
124  m_guiCamera = other.m_guiCamera;
125  m_targetBody = other.m_targetBody;
126  m_fileItem = other.m_fileItem;
128  m_template = other.m_template;
129 
130  m_isUndoable = other.m_isUndoable;
133 
136 
138 
139  m_status = other.m_status;
140  m_queuedAction = other.m_queuedAction;
141 
143 
147 
149  m_transparentConstMutex = new QMutex;
150 
151  if (!other.isInStableState()) {
153  tr("Can not copy work order [%1] because it is currently running")
154  .arg(((QUndoCommand &)other).text()),
155  _FILEINFO_);
156  }
157 
158  connect(this, SIGNAL(triggered()),
159  this, SLOT(addCloneToProject()));
160  connect(m_futureWatcher, SIGNAL(finished()),
161  this, SLOT(executionFinished()));
162 
165  }
166 
167 
172 
173  delete m_imageList;
174  delete m_shapeList;
175  delete m_futureWatcher;
179 
180  m_nextWorkOrder = NULL;
181  m_previousWorkOrder = NULL;
182  m_project = NULL;
184  }
185 
186 
197  return false;
198  }
199 
200 
211  return false;
212  }
213 
214 
225  return false;
226  }
227 
228 
236 //bool WorkOrder::isExecutable(Control *control) {
237 // return false;
238 //}
239 
240 
249  return false;
250  }
251 
252 
253  bool WorkOrder::isExecutable(CorrelationMatrix correlationMatrix) {
254  return false;
255  }
256 
257 
262  void WorkOrder::setData(Context context) {
263  m_context = context;
264  }
265 
266  void WorkOrder::setData(QString data) {
267  m_data = data;
268  }
269 
270 
276  m_imageIds.clear();
277  delete m_imageList;
278 
279  m_imageList = new ImageList(*images);
281  }
282 
283 
289  m_shapeIds.clear();
290  delete m_shapeList;
291 
292  m_shapeList = new ShapeList(*shapes);
294  }
295 
296 
301 //void WorkOrder::setData(Control *control) {
302 // m_control = control;
303 //}
304 
305 
311  void WorkOrder::setData(ControlList *controls) {
312  m_controlList = controls;
313  }
314 
315 
320  void WorkOrder::setData(CorrelationMatrix correlationMatrix) {
321  m_correlationMatrix = correlationMatrix;
322  }
323 
324 
325 
326 
333  }
334 
335 
340  void WorkOrder::setData(Template *currentTemplate) {
341  m_template = currentTemplate;
342  }
343 
344 
351  }
352 
353 
360  }
361 
362 
368  if ( item->isProject() ) {
369  setData( ProjectContext );
370  }
371  else if ( item->isImageList() ) {
372  setData( item->imageList() );
373  }
374  else if ( item->isImage() ) {
375  ImageList *imageList = new ImageList(this);
376  imageList->append( item->image() );
378  }
379  else if ( item->isShapeList() ) {
380  setData( item->shapeList() );
381  }
382  else if ( item->isShape() ) {
383  ShapeList *shapeList = new ShapeList(this);
384  shapeList->append( item->shape() );
386  }
387  else if (item->isControlList()) {
388  setData( item->controlList() );
389  }
390  else if ( item->isControl() ) {
391  ControlList *controlList = new ControlList(this);
392  controlList->append( item->control() );
394 // //setData(*controlList);
395  }
396  else if ( item->isCorrelationMatrix() ) {
397  setData( item->correlationMatrix() );
398  }
399  else if ( item->isTargetBody() ) {
400  setData( item->targetBody() );
401  }
402  else if ( item->isGuiCamera() ) {
403  setData( item->guiCamera() );
404  }
405  else if ( item->isFileItem() ) {
406  setData( item->fileItem() );
407  }
408  else if ( item->isTemplate() ) {
409  setData( item->getTemplate() );
410  }
411  }
412 
413 
414 
415 
416 
425  return false;
426  }
427 
428 
436  bool WorkOrder::isExecutable(Template *currentTemplate) {
437  return false;
438  }
439 
440 
449  return false;
450  }
451 
452 
461  return false;
462  }
463 
464 
473  if ( !item ) {
474  return false;
475  }
476  else if ( item->isProject() ) {
477  return isExecutable( ProjectContext );
478  }
479  else if ( item->isImageList() ) {
480  return isExecutable( item->imageList() );
481  }
482  else if ( item->isImage() ) {
483  ImageList *imageList = new ImageList();
484  imageList->append( item->image() );
485  bool ret = isExecutable(imageList);
486  imageList->deleteLater();
487  return ret;
488  }
489  else if ( item->isShapeList() ) {
490  return isExecutable( item->shapeList() );
491  }
492  else if ( item->isShape() ) {
493  ShapeList *shapeList = new ShapeList();
494  shapeList->append( item->shape() );
495  bool ret = isExecutable(shapeList);
496  shapeList->deleteLater();
497  return ret;
498  }
499  else if ( item->isControlList() ) {
500  return isExecutable (item -> controlList() );
501  }
502  else if ( item->isControl() ) {
504  controlList->append( item->control() );
505  bool ret = isExecutable(controlList);
506  controlList->deleteLater();
507  return ret;
508  }
509  else if ( item->isCorrelationMatrix() ) {
510  return isExecutable( item->correlationMatrix() );
511  }
512  else if ( item->isTargetBody() ) {
513  //return isExecutable( item->targetBody() ) || isExecutable( item->targetBody().data() );
514  return isExecutable(item->targetBody());
515  }
516  else if ( item->isGuiCamera() ) {
517  //return isExecutable( item->guiCamera() ) || isExecutable( item->guiCamera().data() );
518  return isExecutable( item->guiCamera() );
519  }
520  else if ( item->isFileItem() ) {
521  return isExecutable( item->fileItem() );
522  }
523  else if ( item->isTemplate() ) {
524  return isExecutable( item->getTemplate() );
525  }
526 
527  return false;
528  }
529 
530 
535  xmlReader->pushContentHandler(new XmlHandler(this));
536  }
537 
538 
558  void WorkOrder::save(QXmlStreamWriter &stream) const {
559  if (!isInStableState()) {
561  tr("Can not store an unstable work order. The work order [%1] is currently "
562  "working").arg(bestText()),
563  _FILEINFO_);
564  }
565 
566  stream.writeStartElement("workOrder");
567 
568  stream.writeAttribute("actionText", QAction::text());
569  stream.writeAttribute("undoText", QUndoCommand::text());
570  stream.writeAttribute("executionTime", m_executionTime.toString());
571  stream.writeAttribute("type", metaObject()->className());
572  stream.writeAttribute("status", toString(m_status));
573 
574  if (m_imageIds.count()) {
575  stream.writeStartElement("images");
576 
577  foreach (QString imageId, m_imageIds) {
578  stream.writeStartElement("image");
579  stream.writeAttribute("id", imageId);
580  stream.writeEndElement();
581  }
582 
583  stream.writeEndElement();
584  }
585 
586  if (m_shapeIds.count()) {
587  stream.writeStartElement("shapes");
588 
589  foreach (QString shapeId, m_shapeIds) {
590  stream.writeStartElement("shape");
591  stream.writeAttribute("id", shapeId);
592  stream.writeEndElement();
593  }
594 
595  stream.writeEndElement();
596  }
597 
598  if (m_internalData.count()) {
599  stream.writeStartElement("internalDataValues");
600 
601  foreach (QString str, m_internalData) {
602  stream.writeStartElement("dataValue");
603  stream.writeAttribute("value", str);
604  stream.writeEndElement();
605  }
606 
607  stream.writeEndElement();
608  }
609 
610  if (m_context != NoContext) {
611  stream.writeStartElement("context");
612 
613  QString contextStr = "ProjectContext";
614  stream.writeAttribute("value", contextStr);
615 
616  stream.writeEndElement();
617  }
618 
619  stream.writeEndElement();
620  }
621 
622 
627  void WorkOrder::setNext(WorkOrder *nextWorkOrder) {
628  m_nextWorkOrder = nextWorkOrder;
629  }
630 
631 
636  void WorkOrder::setPrevious(WorkOrder *previousWorkOrder) {
637  m_previousWorkOrder = previousWorkOrder;
638  }
639 
640 
646  QMutexLocker locker(project()->workOrderMutex());
647  if (!m_imageList) {
648  bool anyImagesAreNull = false;
649 
650  m_imageList = new ImageList;
651 
652  foreach (QString id, m_imageIds) {
653  Image *image = project()->image(id);
654  m_imageList->append(image);
655 
656  if (!image) {
657  anyImagesAreNull = true;
658  }
659  }
660 
661  if (anyImagesAreNull) {
662  delete m_imageList;
663  }
664  else {
666  }
667  }
668 
669  return m_imageList;
670  }
671 
672 
678  QMutexLocker locker(project()->workOrderMutex());
679  if (!m_shapeList) {
680  bool anyShapesAreNull = false;
681 
682  m_shapeList = new ShapeList;
683 
684  foreach (QString id, m_shapeIds) {
685  Shape *shape = project()->shape(id);
686  m_shapeList->append(shape);
687 
688  if (!shape) {
689  anyShapesAreNull = true;
690  }
691  }
692 
693  if (anyShapesAreNull) {
694  delete m_shapeList;
695  }
696  else {
698  }
699  }
700 
701  return
702  m_shapeList;
703  }
704 
705 
711  QMutexLocker locker(project()->workOrderMutex());
712  return m_correlationMatrix;
713  }
714 
715 
720  QPointer<ControlList> WorkOrder::controlList() {
721  QMutexLocker locker(project()->workOrderMutex());
722  return m_controlList;
723  }
724 
725 
731  QMutexLocker lock(m_transparentConstMutex);
732  return const_cast<WorkOrder *>(this)->imageList();
733  }
734 
735 
741  QMutexLocker lock(m_transparentConstMutex);
742  return const_cast<WorkOrder *>(this)->shapeList();
743  }
744 
745 
751  QMutexLocker locker(project()->workOrderMutex());
752  return m_template;
753  }
754 
755 
761  QMutexLocker locker(project()->workOrderMutex());
762  return m_targetBody;
763  }
764 
765 
771  QMutexLocker locker(project()->workOrderMutex());
772  return m_guiCamera;
773  }
774 
775 
781  QMutexLocker locker(project()->workOrderMutex());
782  return m_fileItem;
783  }
784 
785 
796  return true;
797  }
798 
799 
809  QString WorkOrder::bestText() const {
810  QString result = QUndoCommand::text().remove("&").remove("...");
811 
812  // if the QUndoCommand has no text, create a warning
813  if (result.isEmpty()) {
814  // get the name of the work order
815  result = QString(metaObject()->className()).remove("Isis::").remove("WorkOrder")
816  .replace(QRegExp("([a-z0-9])([A-Z])"), "\\1 \\2");
817  qWarning() << QString("WorkOrder::bestText(): Work order [%1] has no QUndoCommand text")
818  .arg(result);
819  }
820 
821  return result;
822  }
823 
824 
833  bool WorkOrder::isUndoable() const {
834  QMutexLocker locker(project()->workOrderMutex());
835  return m_isUndoable;
836  }
837 
838 
845  QMutexLocker locker(project()->workOrderMutex());
846  return m_isSavedToHistory;
847  }
848 
849 
856  QMutexLocker locker(project()->workOrderMutex());
857  return m_isSynchronous;
858  }
859 
860 
869  QMutexLocker locker(project()->workOrderMutex());
870  return m_createsCleanState;
871  }
872 
873 
878  QDateTime WorkOrder::executionTime() const {
879  QMutexLocker locker(project()->workOrderMutex());
880  return m_executionTime;
881  }
882 
883 
888  bool WorkOrder::isFinished() const {
889  return m_status == WorkOrderFinished;
890  }
891 
892 
897  bool WorkOrder::isRedoing() const {
898  QMutexLocker locker(project()->workOrderMutex());
899  return m_status == WorkOrderRedoing;
900  }
901 
902 
907  bool WorkOrder::isRedone() const {
908  QMutexLocker locker(project()->workOrderMutex());
909  return m_status == WorkOrderRedone;
910  }
911 
912 
917  bool WorkOrder::isUndoing() const {
918  QMutexLocker locker(project()->workOrderMutex());
919  return m_status == WorkOrderUndoing;
920  }
921 
922 
927  bool WorkOrder::isUndone() const {
928  QMutexLocker locker(project()->workOrderMutex());
929  return m_status == WorkOrderUndone;
930  }
931 
932 
939  QMutexLocker locker(project()->workOrderMutex());
940  return m_modifiesDiskState;
941  }
942 
943 
949  QMutexLocker locker(project()->workOrderMutex());
950  return m_nextWorkOrder;
951  }
952 
953 
959  QMutexLocker locker(project()->workOrderMutex());
960  return m_previousWorkOrder;
961  }
962 
963 
968  QString WorkOrder::statusText() const {
969  QMutexLocker locker(project()->workOrderMutex());
970  QString result = toString(m_status);
971 
972  if (m_secondsElapsed) {
973  // QTime can't format in the way that I want (0-n minutes, 00-59 seconds, no hours
974  // displayed)... so do it manually.
975  // Expected output format examples: 0:01, 0:55, 1:30, 55:55, 90:00, 100:12
976  int seconds = qRound(m_secondsElapsed) % 60;
977  int minutes = qRound(m_secondsElapsed) / 60;
978  result += tr(" (elapsed: %1:%2)").arg(minutes).arg(seconds, 2, 10, QChar('0'));
979  }
980 
981  return result;
982  }
983 
984 
990  QMutexLocker locker(project()->workOrderMutex());
991  return m_progressBar;
992  }
993 
994 
1003  statusString = statusString.toUpper();
1004  WorkOrderStatus result = WorkOrderUnknownStatus;
1005 
1006  for (WorkOrderStatus possibleResult = WorkOrderUnknownStatus;
1007  possibleResult <= WorkOrderLastStatus;
1008  possibleResult = (WorkOrderStatus)(possibleResult + 1)) {
1009  if (statusString == toString(possibleResult).toUpper()) {
1010  result = possibleResult;
1011  }
1012  }
1013 
1014  return result;
1015  }
1016 
1017 
1024  QString result;
1025 
1026  switch (status) {
1027  case WorkOrderUnknownStatus:
1028  result = tr("Unknown");
1029  break;
1030  case WorkOrderNotStarted:
1031  result = tr("Not Started");
1032  break;
1033  case WorkOrderRedoing:
1034  result = tr("In Progress");
1035  break;
1036  case WorkOrderRedone:
1037  result = tr("Completed");
1038  break;
1039  case WorkOrderUndoing:
1040  result = tr("Undoing");
1041  break;
1042  case WorkOrderUndone:
1043  result = tr("Undone");
1044  break;
1045  case WorkOrderFinished:
1046  result = tr("Finished");
1047  break;
1048  }
1049 
1050  return result;
1051  }
1052 
1053 
1058  if (!isInStableState()) {
1059  m_queuedAction = RedoQueuedAction;
1060  }
1061 
1062  if (!isRedone()) {
1063  bool mustQueueThisRedo = false;
1064 
1065  WorkOrder *dependency = NULL;
1066  WorkOrder *current = this;
1067  while (current->previous() && !dependency) {
1068  if (!current->previous()->isRedone() && !current->previous()->isFinished()) {
1069  WorkOrder *possibleDependency = current->previous();
1070 
1071  if (dependsOn(possibleDependency)) {
1072  connect(possibleDependency, SIGNAL(finished(WorkOrder *)),
1073  this, SLOT(attemptQueuedAction()));
1074  dependency = possibleDependency;
1075  mustQueueThisRedo = true;
1076  }
1077  }
1078 
1079  current = current->previous();
1080  }
1081 
1082  if (!imageList()) {
1083  connect(project(), SIGNAL(imagesAdded(ImageList *)),
1084  this, SLOT(attemptQueuedAction()));
1085  mustQueueThisRedo = true;
1086  }
1087 
1088  if (!shapeList()) {
1089  connect(project(), SIGNAL(shapesAdded(ShapeList *)),
1090  this, SLOT(attemptQueuedAction()));
1091  mustQueueThisRedo = true;
1092  }
1093 
1094  if (mustQueueThisRedo && !isUndoing() && !isRedoing()) {
1095 
1096  m_queuedAction = RedoQueuedAction;
1097 
1098  QString queueStatusText;
1099 
1100  if (dependency) {
1101  QString dependencyText = dependency->bestText();
1102 
1103  if (dependencyText.count() > 5) {
1104  dependencyText = dependencyText.mid(0, 5) + "...";
1105  }
1106 
1107  queueStatusText = tr("Wait for [%1]").arg(dependencyText);
1108  }
1109  else if (!imageList()) {
1110  queueStatusText = tr("Wait for images");
1111  }
1112  else if (!shapeList()) {
1113  queueStatusText = tr("Wait for shapes");
1114  }
1115 
1116  resetProgressBar();
1117  m_progressBar->setValue(m_progressBar->minimum());
1118  m_progressBar->setText(queueStatusText);
1119  m_progressBar->update();
1120  }
1121 
1122  if (m_queuedAction == NoQueuedAction) {
1123  m_status = WorkOrderRedoing;
1124  emit statusChanged(this);
1125 
1126  resetProgressBar();
1127  m_progressBar->setText("Starting...");
1128  m_progressBar->update();
1129 
1130  delete m_elapsedTimer;
1131  m_elapsedTimer = new QTime;
1132  m_elapsedTimer->start();
1133 
1134  if (isSynchronous()) {
1135  execute();
1137  }
1138  else {
1139  m_progressBar->setText("Running...");
1140  m_progressBar->update();
1141  // queue the workorder for asynchronous execution
1142  QFuture<void> future = QtConcurrent::run(this, &WorkOrder::execute);
1143  // executionFinished() is called via the finished signal. The
1144  // connection is setup in the constructor.
1145  m_futureWatcher->setFuture(future);
1146  }
1147  }
1148  }
1149  else {
1151  }
1152  }
1153 
1154 
1161  if (!isInStableState()) {
1162  m_queuedAction = UndoQueuedAction;
1163  }
1164 
1165  if (!isUndone() && m_status != WorkOrderNotStarted) {
1166  WorkOrder *dependency = NULL;
1167  WorkOrder *current = this;
1168  while (current->next() && !dependency) {
1169  if (!current->next()->isUndone() && !current->next()->isFinished() &&
1170  current->next()->m_status != WorkOrderNotStarted) {
1171  connect(current->next(), SIGNAL(finished(WorkOrder *)),
1172  this, SLOT(attemptQueuedAction()));
1173  m_queuedAction = UndoQueuedAction;
1174  dependency = current->next();
1175  }
1176 
1177  current = current->next();
1178  }
1179 
1180  if (dependency && !isUndoing() && !isRedoing()) {
1181  QString prevText = dependency->bestText();
1182 
1183  if (prevText.count() > 5) {
1184  prevText = prevText.mid(0, 5) + "...";
1185  }
1186 
1187  resetProgressBar();
1188  m_progressBar->setValue(m_progressBar->minimum());
1189  m_progressBar->setText(tr("Undo after [%1]").arg(prevText));
1190  m_progressBar->update();
1191  }
1192 
1193  if (m_queuedAction == NoQueuedAction) {
1194  m_status = WorkOrderUndoing;
1195  emit statusChanged(this);
1196 
1197  resetProgressBar();
1198  m_progressBar->setText("Starting Undo...");
1199  m_progressBar->update();
1200 
1201  delete m_elapsedTimer;
1202  m_elapsedTimer = new QTime;
1203  m_elapsedTimer->start();
1204 
1205  if (isSynchronous()) {
1206  undoExecution();
1208  }
1209  else {
1210  m_progressBar->setText("Undoing...");
1211  m_progressBar->update();
1212  // queue the workorder for asynchronous execution
1213  QFuture<void> future = QtConcurrent::run(this, &WorkOrder::undoExecution);
1214  // executionFinished() is called via the finished signal. The
1215  // connection is setup in the constructor.
1216  m_futureWatcher->setFuture(future);
1217  }
1218  }
1219  }
1220  else {
1222  }
1223  }
1224 
1233  setEnabled(true);
1234  }
1235 
1236 
1245  setEnabled(false);
1246  }
1247 
1248 
1276  // We're finished at this point if we save/open a project, we're not finished if we need to do
1277  // redo()
1278  if (createsCleanState() || !isUndoable()) {
1279  m_status = WorkOrderFinished;
1280 
1281  emit statusChanged(this);
1282  }
1283 
1284  m_executionTime = QDateTime::currentDateTime();
1285 
1286  resetProgressBar();
1287 
1288  if (createsCleanState() || !isUndoable()) {
1290  }
1291  else {
1292  m_progressBar->setText("Initializing...");
1293  }
1294 
1295  return true;
1296  }
1297 
1298 
1305  return project()->directory();
1306  }
1307 
1308 
1315  if (!m_project) {
1317  "This work order no longer has a project.", _FILEINFO_);
1318  }
1319 
1320  return m_project;
1321  }
1322 
1323 
1333  m_internalData = data;
1334  }
1335 
1336 
1342  QMutexLocker locker(project()->workOrderMutex());
1343  return m_progressRangeMinValue;
1344  }
1345 
1346 
1352  QMutexLocker locker(project()->workOrderMutex());
1353  return m_progressRangeMaxValue;
1354  }
1355 
1356 
1362  QMutexLocker locker(project()->workOrderMutex());
1363  return m_progressValue;
1364  }
1365 
1366 
1372  void WorkOrder::setProgressRange(int minValue, int maxValue) {
1373  m_progressRangeMinValue = minValue;
1374  m_progressRangeMaxValue = maxValue;
1375  }
1376 
1377 
1383  m_progressValue = value;
1384  }
1385 
1386 
1392  QMutexLocker locker(project()->workOrderMutex());
1393  return m_internalData;
1394  }
1395 
1396 
1418  }
1419 
1420 
1429  }
1430 
1431 
1449  }
1450 
1451 
1460  }
1461 
1462 
1467  if (project()) {
1468  project()->addToProject(clone());
1469  }
1470  }
1471 
1472 
1478  bool result = true;
1479 
1480  if (isRedoing() || isUndoing() || m_queuedAction != NoQueuedAction) {
1481  result = false;
1482  }
1483 
1484  return result;
1485  }
1486 
1487 
1494  m_imageIds.clear();
1495  foreach (Image *image, *m_imageList) {
1496  if (image) {
1497  m_imageIds.append(image->id());
1498 
1499  // If we lose any images, destroy the entire list. This will let us know that we need to
1500  // rebuild it, if needed, when requested.
1501  connect(image, SIGNAL(destroyed(QObject *)),
1502  this, SLOT(clearImageList()));
1503  }
1504  }
1505  }
1506 
1507 
1517  m_shapeIds.clear();
1518  foreach (Shape *shape, *m_shapeList) {
1519  if (shape) {
1520  m_shapeIds.append(shape->id());
1521 
1522  // If we lose any shapes, destroy the entire list. This will let us know that we need to
1523  // rebuild it, if needed, when requested.
1524  connect(shape, SIGNAL(destroyed(QObject *)),
1525  this, SLOT(clearShapeList()));
1526  }
1527  }
1528  }
1529 
1530 
1536 
1537  if (!m_progressBar) {
1538  m_progressBar = new ProgressBar;
1539  emit creatingProgress(this);
1540  }
1541 
1542  if (!m_progressBarUpdateTimer) {
1543  m_progressBarUpdateTimer = new QTimer;
1544  connect(m_progressBarUpdateTimer, SIGNAL(timeout()),
1545  this, SLOT(updateProgress()));
1546  m_progressBarUpdateTimer->start(100);
1547  }
1548 
1551  m_progressValue = 0;
1552  }
1553 
1554 
1559  if (m_progressBar) {
1560  if (isRedone()) {
1561  m_progressBar->setText(tr("Finished"));
1562  }
1563  else if (isUndone() || m_status == WorkOrderNotStarted) {
1564  m_progressBar->setText(tr("Undone"));
1565  }
1566 
1567  if (m_progressBar->minimum() != 0 || m_progressBar->maximum() != 0) {
1568  m_progressBar->setValue(m_progressBar->maximum());
1569  }
1570  else {
1571  m_progressBar->setRange(0, 100);
1572  m_progressBar->setValue(100);
1573  }
1574 
1576  m_progressBarDeletionTimer = new QTimer;
1577  m_progressBarDeletionTimer->setSingleShot(true);
1578 
1579  m_progressBarDeletionTimer->start(5 * 1000); // 5 seconds
1580 
1581  m_progressBar->update();
1582  }
1583  }
1584 
1585 
1590  QueuedWorkOrderAction queued = m_queuedAction;
1591  m_queuedAction = NoQueuedAction;
1592 
1593  if (queued == RedoQueuedAction && m_status != WorkOrderRedone) {
1594  redo();
1595  }
1596  else if (queued == UndoQueuedAction && m_status != WorkOrderUndone) {
1597  undo();
1598  }
1599  }
1600 
1601 
1607  delete m_progressBarUpdateTimer;
1608 
1609  WorkOrderStatus finishedStatus = WorkOrderRedone;
1610  void (WorkOrder::*postMethod)() = &WorkOrder::postExecution;
1611 
1612  if (isUndoing()) {
1613  finishedStatus = WorkOrderUndone;
1614  postMethod = &WorkOrder::postUndoExecution;
1615  }
1616 
1617  (this->*postMethod)();
1618 
1619  m_status = finishedStatus;
1620 
1621  m_secondsElapsed = m_elapsedTimer->elapsed() / 1000.0;
1622 
1623  delete m_elapsedTimer;
1624  m_elapsedTimer = NULL;
1625 
1626  emit statusChanged(this);
1628  emit finished(this);
1629 
1631  }
1632 
1633 
1638  delete m_imageList;
1639  }
1640 
1641 
1646  delete m_shapeList;
1647  }
1648 
1649 
1654  if (m_progressBar && (isRedoing() || isUndoing())) {
1656  m_progressBar->setValue(m_progressValue);
1657  }
1658  }
1659 
1660 
1665  }
1666 
1667 
1677  void WorkOrder::setCreatesCleanState(bool createsCleanState) {
1679  }
1680 
1681 
1688  void WorkOrder::setModifiesDiskState(bool changesProjectOnDisk) {
1689  m_modifiesDiskState = changesProjectOnDisk;
1690  }
1691 
1692 
1698  m_workOrder = workOrder;
1699  }
1700 
1701 
1716  bool WorkOrder::XmlHandler::startElement(const QString &namespaceURI, const QString &localName,
1717  const QString &qName, const QXmlAttributes &atts) {
1718  if (XmlStackedHandler::startElement(namespaceURI, localName, qName, atts)) {
1719  if (localName == "workOrder") {
1720  QString actionText = atts.value("actionText");
1721  QString undoText = atts.value("undoText");
1722  QString executionTime = atts.value("executionTime");
1723  QString statusStr = atts.value("status");
1724 
1725  if (!actionText.isEmpty()) {
1726  ((QAction *)m_workOrder)->setText(actionText);
1727  }
1728 
1729  if (!undoText.isEmpty()) {
1730  ((QUndoCommand *)m_workOrder)->setText(undoText);
1731  }
1732 
1733  if (!executionTime.isEmpty()) {
1734  m_workOrder->m_executionTime = QDateTime::fromString(executionTime);
1735  }
1736 
1737  if (!statusStr.isEmpty()) {
1738  m_workOrder->m_status = fromStatusString(statusStr);
1739  }
1740  else {
1741  if (m_workOrder->createsCleanState()) {
1742  m_workOrder->m_status = WorkOrderFinished;
1743  }
1744  else {
1745  m_workOrder->m_status = WorkOrderRedone;
1746  }
1747  }
1748  }
1749  else if (localName == "dataValue") {
1750  m_workOrder->m_internalData.append(atts.value("value"));
1751  }
1752  else if (localName == "context") {
1753  if (atts.value("value") == "ProjectContext") {
1754  m_workOrder->m_context = ProjectContext;
1755  }
1756  }
1757  }
1758 
1759  return true;
1760  }
1761 }
Internalizes a list of shapes and allows for operations on the entire list.
Definition: ShapeList.h:33
bool isFileItem() const
Returns true if a FileItemQsp is stored in the data of the item.
QString bestText() const
Generate unique action names We don&#39;t use action text anymore because Directory likes to rename our a...
Definition: WorkOrder.cpp:809
bool isImageList() const
Returns true if an ImageList is stored in the data of the item.
bool isSynchronous() const
Returns true if this work order is run synchronously, otherwise false.
Definition: WorkOrder.cpp:855
bool isInStableState() const
Determines if the WorkOrder is in a stable state, or if it&#39;s busy doing something.
Definition: WorkOrder.cpp:1477
void setProgressValue(int)
Sets the current progress value for the WorkOrder.
Definition: WorkOrder.cpp:1382
bool isShapeList() const
Returns true if an ShapeList is stored in the data of the item.
Internalizes a list of images and allows for operations on the entire list.
Definition: ImageList.h:55
bool m_modifiesDiskState
This is defaulted to false.
Definition: WorkOrder.h:567
GuiCameraQsp guiCamera() const
Returns the GuiCameraQsp stored in the data of the item.
The main project for ipce.
Definition: Project.h:289
bool isImage() const
Returns true if an Image is stored in the data of the item.
virtual void postExecution()
Perform any necessary actions after execution of a workorder.
Definition: WorkOrder.cpp:1428
XmlHandler(WorkOrder *workOrder)
Passes a pointer to a WorkOrder to the WorkOrder::XmlHandler class.
Definition: WorkOrder.cpp:1697
This is a container for the correlation matrix that comes from a bundle adjust.
QSharedPointer< FileItem > FileItemQsp
A FileItem smart pointer.
Definition: FileItem.h:48
void attemptQueuedAction()
Attempts to execute an action on the action queue.
Definition: WorkOrder.cpp:1589
ControlList * controlList() const
Returns the ControlList stored in the data of the item.
bool modifiesDiskState() const
Returns the modified disk state.
Definition: WorkOrder.cpp:938
virtual bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &atts)
The XML reader invokes this method at the start of every element in the XML document.
Definition: WorkOrder.cpp:1716
FileItemQsp fileItem() const
Returns the FileItemQsp stored in the data of the item.
void updateProgress()
Updates the progress bar.
Definition: WorkOrder.cpp:1653
QPointer< QTimer > m_progressBarUpdateTimer
A pointer to the QTimer which updates the ProgressBar.
Definition: WorkOrder.h:677
int progressMax() const
Gets the maximum value of the progress range of the WorkOrder.
Definition: WorkOrder.cpp:1351
bool isRedoing() const
Returns the redoing status of this WorkOrder.
Definition: WorkOrder.cpp:897
Shape * shape(QString id)
Return a shape given its id.
Definition: Project.cpp:1539
Maintains a list of Controls so that control nets can easily be copied from one Project to another...
Definition: ControlList.h:36
virtual bool setupExecution()
This sets up the state for the work order.
Definition: WorkOrder.cpp:1275
void read(XmlStackedHandlerReader *xmlReader)
Read this work order&#39;s data from disk.
Definition: WorkOrder.cpp:534
bool isProject() const
Returns true if a Project is stored in the data of the item.
int m_progressRangeMinValue
The miniumum value of the Progess Bar.
Definition: WorkOrder.h:574
WorkOrder * next() const
Gets the next WorkOrder.
Definition: WorkOrder.cpp:948
QPointer< WorkOrder > m_previousWorkOrder
A pointer to the previous WorkOrder in the queue.
Definition: WorkOrder.h:642
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:162
bool isRedone() const
Returns the WorkOrder redone status.
Definition: WorkOrder.cpp:907
ImageList * imageList() const
Returns the ImageList stored in the data of the item.
TargetBodyQsp targetBody()
WorkOrder::targetBody.
Definition: WorkOrder.cpp:760
ShapeList * shapeList()
a pointer to the ShapeList for this WorkOrder.
Definition: WorkOrder.cpp:677
virtual void redo()
Starts (or enqueues) a redo.
Definition: WorkOrder.cpp:1057
QPointer< ProgressBar > m_progressBar
A pointer to the ProgressBar.
Definition: WorkOrder.h:672
virtual bool isExecutable(Context)
Re-implement this method if your work order utilizes controls for data in order to operate...
Definition: WorkOrder.cpp:196
QTime * m_elapsedTimer
A QTime object holding the excecution time of the WorkOrder.
Definition: WorkOrder.h:688
QDateTime m_executionTime
This is the date/time that setupExecution() was called.
Definition: WorkOrder.h:658
WorkOrder(Project *project)
Create a work order that will work with the given project.
Definition: WorkOrder.cpp:55
Template * getTemplate() const
Returns the Template stored in the data of the item.
void disableWorkOrder()
Disables the work order.
Definition: WorkOrder.cpp:1244
Directory * directory() const
Returns the directory associated with this Project.
Definition: Project.cpp:1229
virtual void undo()
Starts (or enqueues) an undo.
Definition: WorkOrder.cpp:1160
void listenForShapeDestruction()
Checks to see if we have lost any shapes in the ShapeList.
Definition: WorkOrder.cpp:1516
int progressMin() const
Gets the minimum value of the progress range of the WorkOrder.
Definition: WorkOrder.cpp:1341
static QString toString(WorkOrderStatus)
Gets the current status of the WorkOrder.
Definition: WorkOrder.cpp:1023
QPointer< QTimer > m_progressBarDeletionTimer
A pointer to the ProgressBar deletion timer.
Definition: WorkOrder.h:682
void addToProject(WorkOrder *)
This executes the WorkOrder and stores it in the project.
Definition: Project.cpp:2598
Provide Undo/redo abilities, serialization, and history for an operation.
Definition: WorkOrder.h:322
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
bool isSavedToHistory() const
Returns true if this work order is to be shown in History, otherwise false.
Definition: WorkOrder.cpp:844
int m_progressValue
The current value of the Progress Bar.
Definition: WorkOrder.h:582
QSharedPointer< TargetBody > TargetBodyQsp
Defines A smart pointer to a TargetBody obj.
Definition: TargetBody.h:231
TargetBodyQsp targetBody() const
Returns the TargetBodyQsp stored in the data of the item.
bool createsCleanState() const
Returns the CleanState status (whether the Project has been saved to disk or not).
Definition: WorkOrder.cpp:868
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
void append(Shape *const &value)
Appends an shape to the shape list.
Definition: ShapeList.cpp:147
WorkOrderStatus
This enumeration is used by other functions to set and retrieve the current state of the WorkOrder...
Definition: WorkOrder.h:332
QStringList m_internalData
A QStringList of internal properties for this WorkOrder.
Definition: WorkOrder.h:632
virtual void pushContentHandler(XmlStackedHandler *newHandler)
Push a contentHandler and maybe continue parsing...
A type of error that cannot be classified as any of the other error types.
Definition: IException.h:134
virtual void execute()
Execute the workorder.
Definition: WorkOrder.cpp:1417
void setPrevious(WorkOrder *previousWorkOrder)
Sets the previous WorkOrder in the sequence.
Definition: WorkOrder.cpp:636
Template * getTemplate()
WorkOrder::getTemplate.
Definition: WorkOrder.cpp:750
QPointer< WorkOrder > m_nextWorkOrder
A pointer to the next WorkOrder in the queue.
Definition: WorkOrder.h:637
This represents a cube in a project-based GUI interface.
Definition: Image.h:107
bool m_isSynchronous
This is defaulted to true.
Definition: WorkOrder.h:541
int progressValue() const
Gets the current progress value of the WorkOrder.
Definition: WorkOrder.cpp:1361
WorkOrder * previous() const
Gets the previous WorkOrder.
Definition: WorkOrder.cpp:958
Image * image() const
Returns the Image stored in the data of the item.
bool m_isUndoable
Set the workorder to be undoable/redoable This is defaulted to true - his will allow the workorder to...
Definition: WorkOrder.h:534
bool m_createsCleanState
This is defaulted to false.
Definition: WorkOrder.h:560
QString id() const
Get a unique, identifying string associated with this shape.
Definition: Shape.cpp:460
virtual void setData(Context)
Sets the context data for this WorkOrder.
Definition: WorkOrder.cpp:262
void clearShapeList()
Clears the list of shapes.
Definition: WorkOrder.cpp:1645
void append(Image *const &value)
Appends an image to the image list.
Definition: ImageList.cpp:153
bool isGuiCamera() const
Returns true if a GuiCameraQsp is stored in the data of the item.
Template * m_template
A QSharedPointer to the Template (A Template object but encapsulated within a Gui framework...
Definition: WorkOrder.h:601
Image * image(QString id)
Return an image given its id.
Definition: Project.cpp:1509
int m_progressRangeMaxValue
The maximum value of the Progess Bar.
Definition: WorkOrder.h:578
void resetProgressBar()
Resets the ProgressBar.
Definition: WorkOrder.cpp:1534
bool isFinished() const
Returns the finished state of this WorkOrder.
Definition: WorkOrder.cpp:888
bool isTargetBody() const
Returns true if a TargetBodyQsp is stored in the data of the item.
void executionFinished()
Signals the Project that the WorkOrder is finished, deletes the update time for the Progress bar...
Definition: WorkOrder.cpp:1606
void setProgressRange(int, int)
Sets the progress range of the WorkOrder.
Definition: WorkOrder.cpp:1372
virtual ~WorkOrder()
The Destructor.
Definition: WorkOrder.cpp:171
bool isUndoing() const
Returns the WorkOrderUndoing state.
Definition: WorkOrder.cpp:917
TargetBodyQsp m_targetBody
A QSharedPointer to the TargetBody (A Target object but encapsulated within a Gui framework...
Definition: WorkOrder.h:608
bool isControl() const
Returns true if a Control is stored in the data of the item.
double m_secondsElapsed
The seconds that have elapsed since the WorkOrder started executing.
Definition: WorkOrder.h:693
void setModifiesDiskState(bool changesProjectOnDisk)
Definition: WorkOrder.cpp:1688
CorrelationMatrix correlationMatrix() const
Returns the CorrelationMatrix stored the item.
QPointer< QFutureWatcher< void > > m_futureWatcher
A pointer to a QFutureWatcher object which monitors a QFuture object using signals and slots...
Definition: WorkOrder.h:665
QSharedPointer< GuiCamera > GuiCameraQsp
GuiCameraQsp Represents a smart pointer to a GuiCamera object.
Definition: GuiCamera.h:186
QueuedWorkOrderAction
This enum describes the current state of a Queued WorkOrder.
Definition: WorkOrder.h:494
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:653
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
This represents a shape in a project-based GUI interface.
Definition: Shape.h:78
Shape * shape() const
Returns the Shape stored in the data of the item.
Control * control() const
Returns the Control stored in the data of the item.
void listenForImageDestruction()
Checks to see if we have lost any images in the ImageList.
Definition: WorkOrder.cpp:1493
void setProgressToFinalText()
Sets the ProgressBar to display the final status of the operation.
Definition: WorkOrder.cpp:1558
bool isControlList() const
Returns true if a ControlList is stored in the data of the item.
Context
This enumeration is for recording the context of the current Workorder (whether it is part of a proje...
Definition: WorkOrder.h:350
static WorkOrderStatus fromStatusString(QString)
Attempts to query the current status of the WorkOrder.
Definition: WorkOrder.cpp:1002
QString id() const
Get a unique, identifying string associated with this image.
Definition: Image.cpp:445
QString statusText() const
WorkOrder::statusText.
Definition: WorkOrder.cpp:968
Represents an item of a ProjectItemModel in Qt&#39;s model-view framework.
Definition: ProjectItem.h:146
FileItemQsp fileItem()
WorkOrder::fileItem.
Definition: WorkOrder.cpp:780
bool isUndone() const
Returns the WorkOrder undo status.
Definition: WorkOrder.cpp:927
Isis exception class.
Definition: IException.h:107
QDateTime executionTime() const
Gets the execution time of this WorkOrder.
Definition: WorkOrder.cpp:878
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
virtual void postUndoExecution()
Perform any steps necessary after an undo of a workorder.
Definition: WorkOrder.cpp:1459
bool isCorrelationMatrix() const
Returns true if a CorrelationMatrix is stored in the data of the item.
CorrelationMatrix correlationMatrix()
Returns the CorrleationMatrix for this WorkOrder.
Definition: WorkOrder.cpp:710
bool isShape() const
Returns true if an Shape is stored in the data of the item.
void setNext(WorkOrder *nextWorkOrder)
Sets the next WorkOrder in the sequence.
Definition: WorkOrder.cpp:627
void enableWorkOrder()
Enables the work order.
Definition: WorkOrder.cpp:1232
This is used for work orders that will not undo or redo (See createsCleanState()) ...
Definition: WorkOrder.h:342
This class is used for processing an XML file containing information about a WorkOrder.
Definition: WorkOrder.h:508
Project * project() const
Returns the Project this WorkOrder is attached to.
Definition: WorkOrder.cpp:1314
virtual void undoExecution()
Execute the steps necessary to undo this workorder.
Definition: WorkOrder.cpp:1448
GuiCameraQsp m_guiCamera
A QSharedPointer to the GuiCamera (the Camera object but encapsulated within a Gui framework...
Definition: WorkOrder.h:594
GuiCameraQsp guiCamera()
WorkOrder::guiCamera.
Definition: WorkOrder.cpp:770
QPointer< ControlList > controlList()
Returns the Control List for this WorkOrder (a list of control networks).
Definition: WorkOrder.cpp:720
ProgressBar * progressBar()
Returns the ProgressBar.
Definition: WorkOrder.cpp:989
ImageList * imageList()
Returns a pointer to the ImageList for this WorkOrder.
Definition: WorkOrder.cpp:645
Manage a stack of content handlers for reading XML files.
void addCloneToProject()
Runs a copy of the current WorkOrder and stores it in the project.
Definition: WorkOrder.cpp:1466
bool m_isSavedToHistory
Set the work order to be shown in the HistoryTreeWidget.
Definition: WorkOrder.h:548
QStringList m_shapeIds
A QStringList of unique shape identifiers for all of the shapes this WorkOrder is dealing with...
Definition: WorkOrder.h:627
QStringList internalData() const
Gets the internal data for this WorkOrder.
Definition: WorkOrder.cpp:1391
bool isUndoable() const
Returns true if this work order is undoable, otherwise false.
Definition: WorkOrder.cpp:833
virtual bool dependsOn(WorkOrder *other) const
Indicate workorder dependency This is a virtual function whose role in child classes is to determine ...
Definition: WorkOrder.cpp:795
FileItemQsp m_fileItem
A QSharedPointer to the FileItem.
Definition: WorkOrder.h:614
void clearImageList()
Clears the list of images.
Definition: WorkOrder.cpp:1637
void setInternalData(QStringList data)
Sets the internal data for this WorkOrder.
Definition: WorkOrder.cpp:1332
void startRedo()
WorkOrder::startRedo This function is currently empty.
Definition: WorkOrder.cpp:1664
void setCreatesCleanState(bool createsCleanState)
Declare that this work order is saving the project.
Definition: WorkOrder.cpp:1677
QPointer< Project > m_project
A pointer to the Project this WorkOrder is attached to.
Definition: WorkOrder.h:647
void save(QXmlStreamWriter &stream) const
: Saves a WorkOrder to a data stream.
Definition: WorkOrder.cpp:558
Directory * directory() const
return the workorder project directory Returns the Directory object of the Project this WorkOrder is ...
Definition: WorkOrder.cpp:1304
QStringList m_imageIds
A QStringList of unique image identifiers for all of the images this WorkOrder is dealing with...
Definition: WorkOrder.h:621
WorkOrder * m_workOrder
This is a pointer to the WorkOrder the XmlHandler is filling with information it parses from an XML f...
Definition: WorkOrder.h:522
ShapeList * shapeList() const
Returns the ShapeList stored in the data of the item.