Isis 3.0 Programmer Reference
Back | Home
ImportShapesWorkOrder.cpp
Go to the documentation of this file.
1 
23 #include "ImportShapesWorkOrder.h"
24 
25 #include <QDebug>
26 #include <QFileDialog>
27 #include <QMessageBox>
28 #include <QtConcurrentMap>
29 
30 #include "Cube.h"
31 #include "CubeAttribute.h"
32 #include "FileName.h"
33 #include "Project.h"
34 #include "SaveProjectWorkOrder.h"
35 #include "TextFile.h"
36 
37 namespace Isis {
38 
39  ImportShapesWorkOrder::ImportShapesWorkOrder(Project *project) :
40  WorkOrder(project) {
41  m_newShapes = NULL;
42 
43  QAction::setText(tr("Import &Shape Models..."));
44  QUndoCommand::setText(tr("Import Shape Models"));
46  }
47 
48 
49  ImportShapesWorkOrder::ImportShapesWorkOrder(const ImportShapesWorkOrder &other) :
50  WorkOrder(other) {
51  m_newShapes = NULL;
52  }
53 
54 
55  ImportShapesWorkOrder::~ImportShapesWorkOrder() {
56  delete m_newShapes;
57  m_newShapes = NULL;
58  }
59 
60 
61  ImportShapesWorkOrder *ImportShapesWorkOrder::clone() const {
62  return new ImportShapesWorkOrder(*this);
63  }
64 
65 
68 
69  QStringList fileNames = QFileDialog::getOpenFileNames(
70  qobject_cast<QWidget *>(parent()),
71  tr("Import Shape Model Images"), "",
72  tr("Isis cubes and list files (*.cub *.lis);;All Files (*)"));
73 
74  QStringList stateToSave;
75 
76  if (!fileNames.isEmpty()) {
77  foreach (FileName fileName, fileNames) {
78  if (fileName.extension() == "lis") {
79  TextFile listFile(fileName.expanded());
80  QString lineOfListFile;
81 
82  while (listFile.GetLine(lineOfListFile)) {
83  stateToSave.append(lineOfListFile);
84  }
85  }
86  else {
87  stateToSave.append(fileName.original());
88  }
89  }
90  }
91 
92  QMessageBox::StandardButton copyImagesAnswer = QMessageBox::No;
93  if (!fileNames.isEmpty()) {
94  copyImagesAnswer = QMessageBox::question(qobject_cast<QWidget *>(parent()),
95  tr("Copy Shape Model Cubes into Project"),
96  tr("Should images (DN data) be copied into project?"),
97  QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
98  QMessageBox::Yes);
99  }
100 
101  bool copyDnData = (copyImagesAnswer == QMessageBox::Yes);
102 
103  stateToSave.prepend(copyDnData? "copy" : "nocopy");
104 
105  if (fileNames.count() > 1) {
106  QUndoCommand::setText(tr("Import %1 Shape Model Images").arg(stateToSave.count() - 1));
107  }
108  else if (fileNames.count() == 1) {
109  QUndoCommand::setText(tr("Import %1").arg(fileNames.first()));
110  }
111 
112  setInternalData(stateToSave);
113 
114  bool doImport = fileNames.count() > 0 && copyImagesAnswer != QMessageBox::Cancel;
115 
116  return doImport;
117  }
118 
119 
120 
122  project()->waitForShapeReaderFinished();
123  project()->shapes().last()->deleteFromDisk(project());
124  }
125 
126 
128  QPointer<ShapeList> shapesWeAdded = project()->shapes().last();
129 
130  foreach (Shape *shape, *shapesWeAdded) {
131  delete shape;
132  }
133  delete shapesWeAdded;
134  }
135 
136 
138  if (internalData().count() > 0) {
139  importConfirmedShapes(internalData().mid(1), (internalData()[0] == "copy"));
140  }
141  }
142 
143 
145  if (!m_newShapes->isEmpty()) {
146  project()->addShapes(*m_newShapes);
147 
148  delete m_newShapes;
149  m_newShapes = NULL;
150  }
151 
152  if (m_warning != "") {
153  project()->warn(m_warning);
154  }
155  }
156 
157 
158  ImportShapesWorkOrder::OriginalFileToProjectCubeFunctor::OriginalFileToProjectCubeFunctor(
159  QThread *guiThread, QDir destinationFolder, bool copyDnData) : m_errors(new IException),
160  m_numErrors(new int(0)) {
161  m_destinationFolder = destinationFolder;
162  m_copyDnData = copyDnData;
163  m_guiThread = guiThread;
164  }
165 
166 
167  ImportShapesWorkOrder::OriginalFileToProjectCubeFunctor::OriginalFileToProjectCubeFunctor(
168  const OriginalFileToProjectCubeFunctor &other) : m_errors(other.m_errors),
169  m_numErrors(other.m_numErrors) {
170  m_destinationFolder = other.m_destinationFolder;
171  m_copyDnData = other.m_copyDnData;
172  m_guiThread = other.m_guiThread;
173  }
174 
175 
176  ImportShapesWorkOrder::OriginalFileToProjectCubeFunctor::~OriginalFileToProjectCubeFunctor() {
177  m_destinationFolder = QDir();
178  m_copyDnData = false;
179  m_guiThread = NULL;
180  }
181 
182 
183  Cube *ImportShapesWorkOrder::OriginalFileToProjectCubeFunctor::operator()(
184  const FileName &original) {
185  Cube *result = NULL;
186 
187  if (*m_numErrors < 20) {
188  try {
189  QString destination = QFileInfo(m_destinationFolder, original.name())
190  .absoluteFilePath();
191  Cube *input = new Cube(original, "r");
192 
193  if (m_copyDnData) {
194  Cube *copiedCube = input->copy(destination, CubeAttributeOutput());
195  delete input;
196  input = copiedCube;
197  }
198 
199  FileName externalLabelFile(destination);
200  externalLabelFile = externalLabelFile.setExtension("ecub");
201 
202  Cube *projectShape = input->copy(externalLabelFile, CubeAttributeOutput("+External"));
203 
204  if (m_copyDnData) {
205  // Make sure the external label has a fully relative path to the DN data
206  projectShape->relocateDnData(FileName(destination).name());
207  }
208 
209  delete input;
210 
211  result = projectShape;
212  }
213  catch (IException &e) {
214  m_errorsLock.lock();
215 
216  m_errors->append(e);
217  (*m_numErrors)++;
218 
219  m_errorsLock.unlock();
220  }
221  }
222 
223  return result;
224  }
225 
226 
227  IException ImportShapesWorkOrder::OriginalFileToProjectCubeFunctor::errors() const {
228  IException result;
229 
230  result.append(*m_errors);
231 
232  if (*m_numErrors >= 20) {
233  result.append(
234  IException(IException::Unknown,
235  tr("Aborted import shapes due to a high number of errors"),
236  _FILEINFO_));
237  }
238  return result;
239  }
240 
241 
260  bool copyDnData) {
261  if (!confirmedShapes.isEmpty()) {
262  QDir folder = project()->addShapeFolder("import");
263 
264  setProgressRange(0, confirmedShapes.count());
265 
266  m_newShapes = new ShapeList;
267  m_newShapes->reserve(confirmedShapes.count());
268 
269  QStringList confirmedShapesFileNames;
270  QStringList confirmedShapesIds;
271 
272  foreach (QString confirmedShape, confirmedShapes) {
273  QStringList fileNameAndId = confirmedShape.split(",");
274 
275  confirmedShapesFileNames.append(fileNameAndId.first());
276 
277  if (fileNameAndId.count() == 2) {
278  confirmedShapesIds.append(fileNameAndId.last());
279  }
280  else {
281  confirmedShapesIds.append(QString());
282  }
283  }
284 
285  OriginalFileToProjectCubeFunctor functor(thread(), folder, copyDnData);
286  QFuture<Cube *> future = QtConcurrent::mapped(confirmedShapesFileNames, functor);
287 
288  QStringList newInternalData;
289  newInternalData.append(internalData().first());
290 
291  QThreadPool::globalInstance()->releaseThread();
292  for (int i = 0; i < confirmedShapes.count(); i++) {
293  setProgressValue(i);
294 
295  Cube *cube = future.resultAt(i);
296 
297  if (cube) {
298  Shape *newShape = new Shape(future.resultAt(i));
299 
300  if (confirmedShapesIds[i].isEmpty()) {
301  confirmedShapesIds[i] = newShape->id();
302  }
303  else {
304  newShape->setId(confirmedShapesIds[i]);
305  }
306 
307  QStringList ShapeInternalData;
308  ShapeInternalData.append(confirmedShapesFileNames[i]);
309  ShapeInternalData.append(confirmedShapesIds[i]);
310 
311  newInternalData.append(ShapeInternalData.join(","));
312 
313  m_newShapes->append(newShape);
314 
315  newShape->moveToThread(thread());
316  newShape->displayProperties()->moveToThread(thread());
317 
318  newShape->closeCube();
319  }
320  }
321  QThreadPool::globalInstance()->reserveThread();
322 
323  m_warning = functor.errors().toString();
324 
325  m_newShapes->moveToThread(thread());
326 
327  setInternalData(newInternalData);
328  }
329  }
330 }
Internalizes a list of shapes and allows for operations on the entire list.
Definition: ShapeList.h:33
This copies the given shape model cube(s) into the project.
void postSyncUndo()
This method is designed to be implemented by children work orders.
void setProgressValue(int)
Sets the current progress value for the WorkOrder.
Definition: WorkOrder.cpp:1177
void closeCube()
Cleans up the Cube *.
Definition: Shape.cpp:300
void postSyncRedo()
This method is designed to be implemented by children work orders.
File name manipulation and expansion.
Definition: FileName.h:111
Project * project() const
Returns the Project this WorkOrder is attached to.
Definition: WorkOrder.cpp:1116
ShapeDisplayProperties * displayProperties()
Get the display (GUI) properties (information) associated with this shape.
Definition: Shape.cpp:313
void importConfirmedShapes(QStringList confirmedShapes, bool copyDnData)
Creates a project shape folder and copies the shape cubes into it.
QStringList internalData() const
Gets the internal data for this WorkOrder.
Definition: WorkOrder.cpp:1186
bool execute()
The (child) implementation of this method should prompt the user/gather state by any means necessary...
WorkOrder(Project *project)
Create a work order that will work with the given project.
Definition: WorkOrder.cpp:55
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:38
A type of error that cannot be classified as any of the other error types.
Definition: IException.h:126
QString id() const
Get a unique, identifying string associated with this shape.
Definition: Shape.cpp:417
void addShapes(QStringList shapeFiles)
Read the given shape model cube file names as Images and add them to the project. ...
Definition: Project.cpp:764
void setProgressRange(int, int)
Sets the progress range of the WorkOrder.
Definition: WorkOrder.cpp:1167
void asyncUndo()
This method is designed to be implemented by children work orders.
QDir addShapeFolder(QString prefix)
Create and return the name of a folder for placing shape models.
Definition: Project.cpp:736
void setId(QString id)
Override the automatically generated ID with the given ID.
Definition: Shape.cpp:360
void setModifiesDiskState(bool changesProjectOnDisk)
.
Definition: WorkOrder.cpp:1531
Provides access to sequential ASCII stream I/O.
Definition: TextFile.h:54
This represents a shape in a project-based GUI interface.
Definition: Shape.h:70
QString toString() const
Returns a string representation of this exception.
Definition: IException.cpp:553
Isis exception class.
Definition: IException.h:99
void asyncRedo()
This method is designed to be implemented by children work orders.
virtual bool execute()
The (child) implementation of this method should prompt the user/gather state by any means necessary...
Definition: WorkOrder.cpp:1078
void setInternalData(QStringList data)
Sets the internal data for this WorkOrder.
Definition: WorkOrder.cpp:1130
IO Handler for Isis Cubes.
Definition: Cube.h:158

U.S. Department of the Interior | U.S. Geological Survey
ISIS | Privacy & Disclaimers | Astrogeology Research Program
To contact us, please post comments and questions on the ISIS Support Center
File Modified: 07/12/2023 23:20:28