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)
192 Status st = mEditor->importImage(strImgFile);
195 ErrorDialog errorDialog(st.title(), st.description(), st.details().html());
200 imagesImportedSoFar++;
201 progress.setValue(imagesImportedSoFar);
204 if (progress.wasCanceled())
209 for (
int i = 1; i < number; i++)
211 mEditor->scrubForward();
216 emit notifyAnimationLengthChanged();
222 QString strFilePath = getFilePath();
230 QString digit = strFilePath.
mid(slash + 1, dot - slash - 1);
234 for (
int i = digit.
length() - 1; i > 0; i--)
251 digit = strFilePath.
mid(dot - digits, digits);
252 QString prefix = strFilePath.
mid(slash + 1, dot - slash - digits - 1);
257 if (sList.
isEmpty()) {
return setParams; }
262 for (
int i = 0; i < sList.
size(); i++)
264 if (sList[i].startsWith(prefix) &&
265 sList[i].length() == validLength &&
266 sList[i].mid(sList[i].lastIndexOf(
".") - digits, digits).toInt() > 0 &&
267 sList[i].endsWith(suffix))
269 finalList.
append(sList[i]);
272 if (finalList.
isEmpty()) {
return setParams; }
278 for (
QString fileName : finalList) {
279 absolutePaths << path + fileName;
283 setParams.digits = digits;
284 setParams.filenames = finalList;
285 setParams.folderPath = path;
286 setParams.absolutePaths = absolutePaths;
287 setParams.prefix = prefix;
291void ImportImageSeqDialog::importPredefinedSet()
297 hideQuestionMark(progress);
301 int totalImagesToImport = keySet.size();
302 int imagesImportedSoFar = 0;
303 progress.setMaximum(totalImagesToImport);
305 mEditor->layers()->createBitmapLayer(keySet.layerName());
307 for (
int i = 0; i < keySet.size(); i++)
309 const int& frameIndex = keySet.keyFrameIndexAt(i);
310 const QString& filePath = keySet.filePathAt(i);
312 mEditor->scrubTo(frameIndex);
313 Status st = mEditor->importImage(filePath);
316 ErrorDialog errorDialog(st.title(), st.description(), st.details().html());
320 imagesImportedSoFar++;
322 progress.setValue(imagesImportedSoFar);
325 if (progress.wasCanceled())
331 emit notifyAnimationLengthChanged();
336 return ImportExportDialog::getFilePaths();
344 Status status = Status::OK;
346 if (filepaths.
isEmpty()) { status = Status::FAIL; }
348 if (keySet.isEmpty())
350 status = Status::FAIL;
354 if (status == Status::FAIL)
356 status.setTitle(
tr(
"Invalid path"));
357 status.setDescription(
QString(
tr(
"The following file did not meet the criteria: \n%1 \n\nRead the instructions and try again")).arg(failedPathsString));
365 QString failedPathsString =
"";
367 Status status = Status::OK;
369 if (filepaths.
isEmpty()) { status = Status::FAIL; }
371 for (
int i = 0; i < filepaths.
count(); i++)
375 failedPathsString += filepaths.
at(i) +
"\n";
378 if (!failedPathsString.
isEmpty())
380 status = Status::FAIL;
381 status.setTitle(
tr(
"Invalid path"));
382 status.setDescription(
QString(
tr(
"The following file(-s) did not meet the criteria: \n%1")).arg(failedPathsString));
385 if (status == Status::OK)
387 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
QString toLower() const const
int lastIndexOf(QStringView str, int from) const const