26 #include <QFileDialog>
27 #include <QMessageBox>
28 #include <QtConcurrentMap>
39 ImportImagesWorkOrder::ImportImagesWorkOrder(Project *project) :
43 QAction::setText(tr(
"Import &Images..."));
44 QUndoCommand::setText(tr(
"Import Images"));
45 setModifiesDiskState(
true);
49 ImportImagesWorkOrder::ImportImagesWorkOrder(
const ImportImagesWorkOrder &other) :
55 ImportImagesWorkOrder::~ImportImagesWorkOrder() {
61 ImportImagesWorkOrder *ImportImagesWorkOrder::clone()
const {
62 return new ImportImagesWorkOrder(*
this);
69 QStringList fileNames = QFileDialog::getOpenFileNames(
70 qobject_cast<QWidget *>(parent()),
71 tr(
"Import Images"),
"",
72 tr(
"Isis cubes and list files (*.cub *.lis);;All Files (*)"));
76 if (!fileNames.isEmpty()) {
77 foreach (
FileName fileName, fileNames) {
78 if (fileName.extension() ==
"lis") {
79 TextFile listFile(fileName.expanded());
80 QString lineOfListFile;
82 while (listFile.GetLine(lineOfListFile)) {
83 stateToSave.append(lineOfListFile);
87 stateToSave.append(fileName.original());
92 QMessageBox::StandardButton saveProjectAnswer = QMessageBox::No;
93 if (stateToSave.count() >= 100 && project()->isTemporaryProject()) {
94 saveProjectAnswer = QMessageBox::question(qobject_cast<QWidget *>(parent()),
95 tr(
"Save Project Before Importing Images"),
96 tr(
"Would you like to save your project <b>before</b> importing images? It can be "
97 "slow to save your project after these images have been loaded if you do not "
99 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
103 if (saveProjectAnswer == QMessageBox::Yes) {
105 saveWorkOrder.trigger();
108 QMessageBox::StandardButton copyImagesAnswer = QMessageBox::No;
109 if (!fileNames.isEmpty() && saveProjectAnswer != QMessageBox::Cancel) {
110 copyImagesAnswer = QMessageBox::question(qobject_cast<QWidget *>(parent()),
111 tr(
"Copy Images into Project"),
112 tr(
"Should images (DN data) be copied into project?"),
113 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
117 bool copyDnData = (copyImagesAnswer == QMessageBox::Yes);
119 stateToSave.prepend(copyDnData?
"copy" :
"nocopy");
121 if (fileNames.count() > 1) {
122 QUndoCommand::setText(tr(
"Import %1 Images").arg(stateToSave.count() - 1));
124 else if (fileNames.count() == 1) {
125 QUndoCommand::setText(tr(
"Import %1").arg(fileNames.first()));
128 setInternalData(stateToSave);
130 bool doImport = fileNames.count() > 0 && saveProjectAnswer != QMessageBox::Cancel &&
131 copyImagesAnswer != QMessageBox::Cancel;
138 project()->waitForImageReaderFinished();
139 project()->images().last()->deleteFromDisk(project());
144 QPointer<ImageList> imagesWeAdded = project()->images().last();
146 foreach (
Image *image, *imagesWeAdded) {
149 delete imagesWeAdded;
154 if (internalData().count() > 0) {
155 importConfirmedImages(internalData().mid(1), (internalData()[0] ==
"copy"));
161 if (!m_newImages->isEmpty()) {
162 project()->addImages(*m_newImages);
168 if (m_warning !=
"") {
169 project()->warn(m_warning);
174 ImportImagesWorkOrder::OriginalFileToProjectCubeFunctor::OriginalFileToProjectCubeFunctor(
175 QThread *guiThread, QDir destinationFolder,
bool copyDnData) : m_errors(new
IException),
176 m_numErrors(new int(0)) {
177 m_destinationFolder = destinationFolder;
178 m_copyDnData = copyDnData;
179 m_guiThread = guiThread;
183 ImportImagesWorkOrder::OriginalFileToProjectCubeFunctor::OriginalFileToProjectCubeFunctor(
184 const OriginalFileToProjectCubeFunctor &other) : m_errors(other.m_errors),
185 m_numErrors(other.m_numErrors) {
186 m_destinationFolder = other.m_destinationFolder;
187 m_copyDnData = other.m_copyDnData;
188 m_guiThread = other.m_guiThread;
192 ImportImagesWorkOrder::OriginalFileToProjectCubeFunctor::~OriginalFileToProjectCubeFunctor() {
193 m_destinationFolder = QDir();
194 m_copyDnData =
false;
199 Cube *ImportImagesWorkOrder::OriginalFileToProjectCubeFunctor::operator()(
200 const FileName &original) {
203 if (*m_numErrors < 20) {
205 QString destination = QFileInfo(m_destinationFolder, original.name())
207 Cube *input =
new Cube(original,
"r");
210 Cube *copiedCube = input->copy(destination, CubeAttributeOutput());
215 FileName externalLabelFile(destination);
216 externalLabelFile = externalLabelFile.setExtension(
"ecub");
218 Cube *projectImage = input->copy(externalLabelFile, CubeAttributeOutput(
"+External"));
222 projectImage->relocateDnData(FileName(destination).name());
227 result = projectImage;
229 catch (IException &e) {
235 m_errorsLock.unlock();
243 IException ImportImagesWorkOrder::OriginalFileToProjectCubeFunctor::errors()
const {
246 result.append(*m_errors);
248 if (*m_numErrors >= 20) {
251 tr(
"Aborted import images due to a high number of errors"),
275 if (!confirmedImages.isEmpty()) {
276 QDir folder = project()->addImageFolder(
"import");
278 setProgressRange(0, confirmedImages.count());
281 m_newImages->reserve(confirmedImages.count());
286 foreach (QString confirmedImage, confirmedImages) {
287 QStringList fileNameAndId = confirmedImage.split(
",");
289 confirmedImagesFileNames.append(fileNameAndId.first());
291 if (fileNameAndId.count() == 2) {
292 confirmedImagesIds.append(fileNameAndId.last());
295 confirmedImagesIds.append(QString());
300 QFuture<Cube *> future = QtConcurrent::mapped(confirmedImagesFileNames, functor);
303 newInternalData.append(internalData().first());
305 QThreadPool::globalInstance()->releaseThread();
306 for (
int i = 0; i < confirmedImages.count(); i++) {
309 Cube *cube = future.resultAt(i);
312 Image *newImage =
new Image(future.resultAt(i));
314 if (confirmedImagesIds[i].isEmpty()) {
315 confirmedImagesIds[i] = newImage->
id();
318 newImage->
setId(confirmedImagesIds[i]);
322 imageInternalData.append(confirmedImagesFileNames[i]);
323 imageInternalData.append(confirmedImagesIds[i]);
325 newInternalData.append(imageInternalData.join(
","));
327 m_newImages->append(newImage);
329 newImage->moveToThread(thread());
335 QThreadPool::globalInstance()->reserveThread();
337 m_warning = functor.errors().
toString();
339 m_newImages->moveToThread(thread());
341 setInternalData(newInternalData);