Isis 3 Programmer Reference
ImportShapesWorkOrder.cpp
Go to the documentation of this file.
1 
21 #include "ImportShapesWorkOrder.h"
22 
23 #include <QDebug>
24 #include <QFileDialog>
25 #include <QMessageBox>
26 #include <QtConcurrentMap>
27 
28 #include "Cube.h"
29 #include "CubeAttribute.h"
30 #include "FileName.h"
31 #include "IException.h"
32 #include "Project.h"
33 #include "ProjectItem.h"
34 #include "ProjectItemModel.h"
35 #include "SaveProjectWorkOrder.h"
36 #include "TextFile.h"
37 
38 namespace Isis {
39 
46  WorkOrder(project) {
47  // This workorder is synchronous and undoable.
48  m_isUndoable = true;
49  m_isSynchronous = false;
50  m_newShapes = NULL;
51  m_list = NULL;
52 
53  QAction::setText(tr("Import &Shape Models and Ground source..."));
54  QUndoCommand::setText(tr("Import Shape Models and Ground source"));
56  }
57 
58 
65  WorkOrder(other) {
66  m_newShapes = NULL;
67  m_list = other.m_list;
68  }
69 
70 
75  delete m_newShapes;
76  m_newShapes = NULL;
77 
78  delete m_list;
79  m_list = NULL;
80  }
81 
82 
89  return new ImportShapesWorkOrder(*this);
90  }
91 
92 
103  if (item) {
104  return (item->text() == "Shapes");
105  }
106 
107  return false;
108  }
109 
110 
128 
129  QStringList fileNames = QFileDialog::getOpenFileNames(
130  qobject_cast<QWidget *>(parent()),
131  tr("Import Shape Model Images"), "",
132  tr("Isis cubes and list files (*.cub *.lis);;All Files (*)"));
133 
134  QStringList stateToSave;
135 
136  if (!fileNames.isEmpty()) {
137  foreach (FileName fileName, fileNames) {
138  if (fileName.extension() == "lis") {
139  TextFile listFile(fileName.expanded());
140  QString path = fileName.path();
141  QString lineOfListFile;
142 
143  while (listFile.GetLine(lineOfListFile)) {
144  if (lineOfListFile.contains(path)){
145  stateToSave.append(lineOfListFile);
146  }
147  else {
148  stateToSave.append(path + "/" + lineOfListFile);
149  }
150  }
151  }
152  else {
153  stateToSave.append(fileName.original());
154  }
155  }
156  }
157 
158  QMessageBox::StandardButton copyImagesAnswer = QMessageBox::No;
159  if (!fileNames.isEmpty()) {
160  copyImagesAnswer = QMessageBox::question(qobject_cast<QWidget *>(parent()),
161  tr("Copy Shape Model Cubes into Project"),
162  tr("Should images (DN data) be copied into project?"),
163  QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
164  QMessageBox::Yes);
165  }
166 
167  bool copyDnData = (copyImagesAnswer == QMessageBox::Yes);
168 
169  stateToSave.prepend(copyDnData? "copy" : "nocopy");
170 
171  if (fileNames.count() > 1) {
172  QUndoCommand::setText(tr("Import %1 Shape Model Images").arg(stateToSave.count() - 1));
173  }
174  else if (fileNames.count() == 1) {
175  QUndoCommand::setText(tr("Import %1").arg(fileNames.first()));
176  }
177 
178  setInternalData(stateToSave);
179 
180  bool doImport = fileNames.count() > 0 && copyImagesAnswer != QMessageBox::Cancel;
181 
182  return doImport;
183  }
184 
185 
192  if (m_list && project()->shapes().size() > 0 ) {
194  // Remove the shapes from disk.
196  // Remove the shapes from the model, which updates the tree view.
197  ProjectItem *currentItem =
198  project()->directory()->model()->findItemData( QVariant::fromValue(m_list) );
199  project()->directory()->model()->removeItem(currentItem);
200  }
201  }
202 
207  if (m_list && project()->shapes().size() > 0 ) {
208  foreach (Shape *shape, *m_list) {
209  delete shape;
210  }
211  delete m_list;
212  }
213  }
214 
220  if (internalData().count() > 0) {
221  importConfirmedShapes(internalData().mid(1), (internalData()[0] == "copy"));
222  project()->setClean(false);
223  }
224  }
225 
232  if (m_newShapes && !m_newShapes->isEmpty()) {
234  m_list = project()->shapes().last();
235 
236  delete m_newShapes;
237  m_newShapes = NULL;
238  }
239  else {
240  project()->undoStack()->undo();
241  }
242 
243  if (m_warning != "") {
244  project()->warn(m_warning);
245  }
246  }
247 
248 
257  QThread *guiThread, QDir destinationFolder, bool copyDnData) : m_errors(new IException),
258  m_numErrors(new int(0)) {
259  m_destinationFolder = destinationFolder;
260  m_copyDnData = copyDnData;
261  m_guiThread = guiThread;
262  }
263 
264 
271  const OriginalFileToProjectCubeFunctor &other) : m_errors(other.m_errors),
272  m_numErrors(other.m_numErrors) {
274  m_copyDnData = other.m_copyDnData;
275  m_guiThread = other.m_guiThread;
276  }
277 
278 
283  m_destinationFolder = QDir();
284  m_copyDnData = false;
285  m_guiThread = NULL;
286  }
287 
288 
297  const FileName &original) {
298  Cube *result = NULL;
299 
300  if (*m_numErrors < 20) {
301  try {
302  QString destination = QFileInfo(m_destinationFolder, original.name())
303  .absoluteFilePath();
304  Cube *input = new Cube(original, "r");
305 
306  if (m_copyDnData) {
307  Cube *copiedCube = input->copy(destination, CubeAttributeOutput());
308  delete input;
309  input = copiedCube;
310  }
311 
312  FileName externalLabelFile(destination);
313  externalLabelFile = externalLabelFile.setExtension("ecub");
314 
315  Cube *projectShape = input->copy(externalLabelFile, CubeAttributeOutput("+External"));
316 
317  if (m_copyDnData) {
318  // Make sure the external label has a fully relative path to the DN data
319  projectShape->relocateDnData(FileName(destination).name());
320  }
321 
322  // Set new ecub to readOnly. When closing cube, the labels were being re-written because
323  // the cube was read/write. This caused a segfault when imported large number of images
324  // because of a label template file being opened too many times.
325  projectShape->reopen();
326 
327  delete input;
328 
329  result = projectShape;
330  }
331  catch (IException &e) {
332  m_errorsLock.lock();
333 
334  m_errors->append(e);
335  (*m_numErrors)++;
336 
337  m_errorsLock.unlock();
338  }
339  }
340 
341  return result;
342  }
343 
344 
351  IException result;
352 
353  result.append(*m_errors);
354 
355  if (*m_numErrors >= 20) {
356  result.append(
358  tr("Aborted import shapes due to a high number of errors"),
359  _FILEINFO_));
360  }
361  return result;
362  }
363 
364 
383  bool copyDnData) {
384  try {
385  if (!confirmedShapes.isEmpty()) {
386  QDir folder = project()->addShapeFolder("import");
387 
388  setProgressRange(0, confirmedShapes.count());
389 
390  m_newShapes = new ShapeList;
391  m_newShapes->reserve(confirmedShapes.count());
392 
393  QStringList confirmedShapesFileNames;
394  QStringList confirmedShapesIds;
395 
396  foreach (QString confirmedShape, confirmedShapes) {
397  QStringList fileNameAndId = confirmedShape.split(",");
398 
399  confirmedShapesFileNames.append(fileNameAndId.first());
400 
401  if (fileNameAndId.count() == 2) {
402  confirmedShapesIds.append(fileNameAndId.last());
403  }
404  else {
405  confirmedShapesIds.append(QString());
406  }
407  }
408 
409  OriginalFileToProjectCubeFunctor functor(thread(), folder, copyDnData);
410  QFuture<Cube *> future = QtConcurrent::mapped(confirmedShapesFileNames, functor);
411 
412  QStringList newInternalData;
413  newInternalData.append(internalData().first());
414 
415  QThreadPool::globalInstance()->releaseThread();
416  for (int i = 0; i < confirmedShapes.count(); i++) {
417  setProgressValue(i);
418 
419  Cube *cube = future.resultAt(i);
420 
421  if (cube) {
422  Shape *newShape = new Shape(future.resultAt(i));
423 
424  if (confirmedShapesIds[i].isEmpty()) {
425  confirmedShapesIds[i] = newShape->id();
426  }
427  else {
428  newShape->setId(confirmedShapesIds[i]);
429  }
430 
431  QStringList ShapeInternalData;
432  ShapeInternalData.append(confirmedShapesFileNames[i]);
433  ShapeInternalData.append(confirmedShapesIds[i]);
434 
435  newInternalData.append(ShapeInternalData.join(","));
436 
437  m_newShapes->append(newShape);
438 
439  newShape->moveToThread(thread());
440  newShape->displayProperties()->moveToThread(thread());
441 
442  newShape->closeCube();
443  }
444  }
445  QThreadPool::globalInstance()->reserveThread();
446 
447  m_warning = functor.errors().toString();
448 
449  m_newShapes->moveToThread(thread());
450 
451  setInternalData(newInternalData);
452  }
453  }
454  catch (IException &e) {
455  QMessageBox::critical(NULL, tr("Error"), tr(e.what()));
456  }
457  }
458 }
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.
QString path() const
Returns the path of the file name.
Definition: FileName.cpp:119
const char * what() const
Returns a string representation of this exception in its current state.
Definition: IException.cpp:391
$Date$ $Revision$
void setProgressValue(int)
Sets the current progress value for the WorkOrder.
Definition: WorkOrder.cpp:1382
The main project for ipce.
Definition: Project.h:289
void closeCube()
Cleans up the Cube *.
Definition: Shape.cpp:343
File name manipulation and expansion.
Definition: FileName.h:116
void deleteFromDisk(Project *project)
Delete all of the contained Shapes from disk.
Definition: ShapeList.cpp:592
Cube * operator()(const FileName &original)
Creates ecubs and copies the DN data of the cubes, if m_copyDnData is true.
virtual bool setupExecution()
This sets up the state for the work order.
Definition: WorkOrder.cpp:1275
Add shape model cubes to a project.
void append(const IException &exceptionSource)
Appends the given exception (and its list of previous exceptions) to this exception&#39;s causational exc...
Definition: IException.cpp:425
void execute()
Creates a project shape folder and copies the shape cubes into it.
QString name() const
Returns the name of the file excluding the path and the attributes in the file name.
Definition: FileName.cpp:178
QUndoStack * undoStack()
Returns the Projects stack of QUndoCommands.
Definition: Project.cpp:1694
ShapeDisplayProperties * displayProperties()
Get the display (GUI) properties (information) associated with this shape.
Definition: Shape.cpp:356
void importConfirmedShapes(QStringList confirmedShapes, bool copyDnData)
Creates a project shape folder and copies the shape cubes into it.
void postExecution()
Add the imported shapes into the project.
virtual ImportShapesWorkOrder * clone() const
This method clones the current ImportShapesWorkOrder and returns it.
QDir m_destinationFolder
Directory where the DN data is going to be stored.
void waitForShapeReaderFinished()
Locks program if another spot in code is still running and called this function.
Definition: Project.cpp:1740
void reopen(QString access="r")
This method will reopen an isis sube for reading or reading/writing.
Definition: Cube.cpp:691
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...
QString m_warning
QString of warning text.
IException errors() const
Returns the errors from importing.
void undoExecution()
delete the imported shapes from the disk.
Directory * directory() const
Returns the directory associated with this Project.
Definition: Project.cpp:1229
ProjectItemModel * model()
Gets the ProjectItemModel for this directory.
Definition: Directory.cpp:1105
Provide Undo/redo abilities, serialization, and history for an operation.
Definition: WorkOrder.h:322
ShapeList * m_list
List of shapes this workorder added to the project.
#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
ImportShapesWorkOrder(Project *project)
Creates a work order to import a shape model.
ShapeList * m_newShapes
List of shapes.
Manipulate and parse attributes of output cube filenames.
A type of error that cannot be classified as any of the other error types.
Definition: IException.h:134
virtual void removeItem(ProjectItem *item)
Removes an item and its children from the model.
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
Definition: FileName.cpp:212
QString original() const
Returns the full file name including the file path.
Definition: FileName.cpp:228
bool m_isSynchronous
This is defaulted to true.
Definition: WorkOrder.h:541
Cube * copy(FileName newFile, const CubeAttributeOutput &newFileAttributes)
Copies the cube to the new fileName.
Definition: Cube.cpp:193
bool setupExecution()
Prompt the user for shape files to import and whether to copy DN data in to project.
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
QString id() const
Get a unique, identifying string associated with this shape.
Definition: Shape.cpp:460
void addShapes(QStringList shapeFiles)
Read the given shape model cube file names as Images and add them to the project. ...
Definition: Project.cpp:1089
void postUndoExecution()
delete the imported shapes from the project.
void setProgressRange(int, int)
Sets the progress range of the WorkOrder.
Definition: WorkOrder.cpp:1372
QDir addShapeFolder(QString prefix)
Create and return the name of a folder for placing shape models.
Definition: Project.cpp:1060
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
void setId(QString id)
Override the automatically generated ID with the given ID.
Definition: Shape.cpp:403
OriginalFileToProjectCubeFunctor(QThread *guiThread, QDir destinationFolder, bool copyDnData)
OriginalFileToProjectFunctor constructor.
void setModifiesDiskState(bool changesProjectOnDisk)
Definition: WorkOrder.cpp:1688
Provides access to sequential ASCII stream I/O.
Definition: TextFile.h:54
QString toString() const
Returns a string representation of this exception.
Definition: IException.cpp:553
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
Represents an item of a ProjectItemModel in Qt&#39;s model-view framework.
Definition: ProjectItem.h:146
void relocateDnData(FileName dnDataFile)
Relocates the DN data for a cube to an external cube label file.
Definition: Cube.cpp:1081
Isis exception class.
Definition: IException.h:107
FileName setExtension(const QString &extension) const
Sets all current file extensions to a new extension in the file name.
Definition: FileName.cpp:281
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
QString extension() const
Returns the last extension of the file name.
Definition: FileName.cpp:194
virtual bool isExecutable(ProjectItem *item)
This method returns true if the user clicked on a project tree node with the text "Shapes"...
Project * project() const
Returns the Project this WorkOrder is attached to.
Definition: WorkOrder.cpp:1314
QStringList internalData() const
Gets the internal data for this WorkOrder.
Definition: WorkOrder.cpp:1391
bool m_copyDnData
Stores if the user wants to copy the DN data or not.
void setInternalData(QStringList data)
Sets the internal data for this WorkOrder.
Definition: WorkOrder.cpp:1332
void setClean(bool value)
Function to change the clean state of the project.
Definition: Project.cpp:1595
IO Handler for Isis Cubes.
Definition: Cube.h:170