18#include "importimageseqdialog.h"
19#include "ui_importimageseqoptions.h"
20#include "ui_importimageseqpreview.h"
25#include "errordialog.h"
26#include "predefinedsetmodel.h"
27#include "layermanager.h"
28#include "viewmanager.h"
30#include <QProgressDialog>
34#include <QDialogButtonBox>
37ImportImageSeqDialog::ImportImageSeqDialog(
QWidget* parent, Mode mode, FileType fileType, ImportCriteria importCriteria) :
38 ImportExportDialog(parent, mode, fileType), mParent(parent), mImportCriteria(importCriteria), mFileType(fileType)
41 uiOptionsBox =
new Ui::ImportImageSeqOptions;
42 uiOptionsBox->
setupUi(getOptionsGroupBox());
44 uiGroupBoxPreview =
new Ui::ImportImageSeqPreviewGroupBox;
45 uiGroupBoxPreview->setupUi(getPreviewGroupBox());
47 if (importCriteria == ImportCriteria::PredefinedSet) {
48 setupPredefinedLayout();
53 getDialogButtonBox()->button(QDialogButtonBox::StandardButton::Ok)->setEnabled(
false);
56void ImportImageSeqDialog::setupLayout()
59 hideInstructionsLabel(
true);
66 case FileType::IMAGE_SEQUENCE:
74 connect(
this, &ImportImageSeqDialog::filePathsChanged,
this, &ImportImageSeqDialog::validateFiles);
77void ImportImageSeqDialog::setupPredefinedLayout()
80 setInstructionsLabel(
tr(
"Select an image that matches the criteria: MyFile000.png, eg. Joe001.png \n"
81 "The importer will search and find images matching the same criteria. You can see the result in the preview box below."));
82 hideOptionsGroupBox(
true);
83 hidePreviewGroupBox(
false);
85 connect(
this, &ImportImageSeqDialog::filePathsChanged,
this, &ImportImageSeqDialog::updatePreviewList);
88ImportImageSeqDialog::~ImportImageSeqDialog()
93 if (uiGroupBoxPreview) {
94 delete uiGroupBoxPreview;
98int ImportImageSeqDialog::getSpace()
100 return uiOptionsBox->spaceSpinBox->value();
103void ImportImageSeqDialog::updatePreviewList(
const QStringList& list)
106 if (mImportCriteria == ImportCriteria::PredefinedSet)
110 Status status = Status::OK;
111 status = validateKeySet(keySet, list);
113 QPushButton* okButton = getDialogButtonBox()->
button(QDialogButtonBox::StandardButton::Ok);
114 if (status == Status::FAIL)
118 status.description(),
125 setPreviewModel(keySet);
129const PredefinedKeySet ImportImageSeqDialog::generatePredefinedKeySet()
const
134 const QStringList& filenames = setParams.filenames;
135 const int& digits = setParams.digits;
136 const QString& folderPath = setParams.folderPath;
138 for (
int i = 0; i < filenames.
size(); i++)
140 const int& frameIndex = filenames[i].
mid(setParams.dot - digits, digits).toInt();
141 const QString& absolutePath = folderPath + filenames[i];
143 keySet.insert(frameIndex, absolutePath);
145 keySet.setLayerName(setParams.prefix);
152 uiGroupBoxPreview->tableView->setModel(previewModel);
153 uiGroupBoxPreview->tableView->setColumnWidth(0, 500);
154 uiGroupBoxPreview->tableView->setColumnWidth(1, 100);
157ImportExportDialog::Mode ImportImageSeqDialog::getMode()
159 return ImportExportDialog::Import;
162FileType ImportImageSeqDialog::getFileType()
167void ImportImageSeqDialog::setSpace(
int number)
170 uiOptionsBox->spaceSpinBox->setValue(number);
173void ImportImageSeqDialog::importArbitrarySequence()
176 int number = getSpace();
180 hideQuestionMark(progress);
184 int totalImagesToImport = files.
count();
185 int imagesImportedSoFar = 0;
186 progress.setMaximum(totalImagesToImport);
188 for (
const QString& strImgFile : files)
190 Status st = mEditor->importImage(strImgFile);
193 ErrorDialog errorDialog(st.title(), st.description(), st.details().html());
198 imagesImportedSoFar++;
199 progress.setValue(imagesImportedSoFar);
202 if (progress.wasCanceled())
207 for (
int i = 1; i < number; i++)
209 mEditor->scrubForward();
214 emit notifyAnimationLengthChanged();
220 QString strFilePath = getFilePath();
227 QString digit = strFilePath.
mid(slash + 1, dot - slash - 1);
231 for (
int i = digit.
length() - 1; i > 0; i--)
248 digit = strFilePath.
mid(dot - digits, digits);
249 QString prefix = strFilePath.
mid(slash + 1, dot - slash - digits - 1);
254 if (sList.
isEmpty()) {
return setParams; }
259 for (
int i = 0; i < sList.
size(); i++)
261 if (sList[i].startsWith(prefix) &&
262 sList[i].length() == validLength &&
263 sList[i].mid(sList[i].lastIndexOf(
".") - digits, digits).toInt() > 0 &&
264 sList[i].endsWith(suffix))
266 finalList.
append(sList[i]);
269 if (finalList.
isEmpty()) {
return setParams; }
275 for (
const QString& fileName : finalList) {
276 absolutePaths << path + fileName;
280 setParams.digits = digits;
281 setParams.filenames = finalList;
282 setParams.folderPath = path;
283 setParams.absolutePaths = absolutePaths;
284 setParams.prefix = prefix;
288void ImportImageSeqDialog::importPredefinedSet()
294 hideQuestionMark(progress);
298 int totalImagesToImport = keySet.size();
299 int imagesImportedSoFar = 0;
300 progress.setMaximum(totalImagesToImport);
302 mEditor->layers()->createBitmapLayer(keySet.layerName());
304 for (
int i = 0; i < keySet.size(); i++)
306 const int& frameIndex = keySet.keyFrameIndexAt(i);
307 const QString& filePath = keySet.filePathAt(i);
309 mEditor->scrubTo(frameIndex);
310 Status st = mEditor->importImage(filePath);
313 ErrorDialog errorDialog(st.title(), st.description(), st.details().html());
317 imagesImportedSoFar++;
319 progress.setValue(imagesImportedSoFar);
322 if (progress.wasCanceled())
328 emit notifyAnimationLengthChanged();
333 return ImportExportDialog::getFilePaths();
340 Status status = Status::OK;
342 if (filepaths.
isEmpty()) { status = Status::FAIL; }
344 if (keySet.isEmpty())
346 status = Status::FAIL;
350 if (status == Status::FAIL)
352 status.setTitle(
tr(
"Invalid path"));
353 status.setDescription(
QString(
tr(
"The following file did not meet the criteria: \n%1 \n\nRead the instructions and try again")).arg(failedPathsString));
361 QString failedPathsString =
"";
363 Status status = Status::OK;
365 if (filepaths.
isEmpty()) { status = Status::FAIL; }
367 for (
int i = 0; i < filepaths.
count(); i++)
371 failedPathsString += filepaths.
at(i) +
"\n";
374 if (!failedPathsString.
isEmpty())
376 status = Status::FAIL;
377 status.setTitle(
tr(
"Invalid path"));
378 status.setDescription(
QString(
tr(
"The following file(-s) did not meet the criteria: \n%1")).arg(failedPathsString));
381 if (status == Status::OK)
383 getDialogButtonBox()->
button(QDialogButtonBox::StandardButton::Ok)->
setEnabled(
true);
bool isDigit() const const
void processEvents(QEventLoop::ProcessEventsFlags flags)
QStringList entryList(QDir::Filters filters, QDir::SortFlags sort) const const
void append(const T &value)
const T & at(int i) const const
int count(const T &value) const const
bool isEmpty() const const
QList< T > mid(int pos, int length) const const
QString createSeparatedList(const QStringList &list) const const
QMessageBox::StandardButton warning(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QString tr(const char *sourceText, const char *disambiguation, int n)
const QChar at(int position) const const
bool isEmpty() const const
int lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const const
QString left(int n) const const
QString mid(int position, int n) const const
int lastIndexOf(QStringView str, int from) const const