Skip to content

Commit

Permalink
Add the ability to import multiple files
Browse files Browse the repository at this point in the history
  • Loading branch information
iljukhaput committed Jan 22, 2025
1 parent c9a2781 commit 7656d8f
Show file tree
Hide file tree
Showing 39 changed files with 1,038 additions and 367 deletions.
2 changes: 2 additions & 0 deletions src/core/core.pro
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ SOURCES += \
ui/export/script_export_dialog.cpp \
ui/export/simple_text_export_dialog.cpp \
ui/export/stageplay_export_dialog.cpp \
ui/import/file_name_delegate.cpp \
ui/import/import_dialog.cpp \
ui/menu_view.cpp \
ui/notifications/credits_view.cpp \
Expand Down Expand Up @@ -195,6 +196,7 @@ HEADERS += \
ui/export/script_export_dialog.h \
ui/export/simple_text_export_dialog.h \
ui/export/stageplay_export_dialog.h \
ui/import/file_name_delegate.h \
ui/import/import_dialog.h \
ui/menu_view.h \
ui/notifications/credits_view.h \
Expand Down
174 changes: 107 additions & 67 deletions src/core/management_layer/content/import/import_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
#include <business_layer/import/stageplay/stageplay_fountain_importer.h>
#include <data_layer/storage/settings_storage.h>
#include <data_layer/storage/storage_facade.h>
#include <ui/design_system/design_system.h>
#include <ui/import/import_dialog.h>
#include <ui/widgets/dialog/dialog.h>
#include <ui/widgets/dialog/standard_dialog.h>
#include <utils/helpers/dialog_helper.h>
#include <utils/helpers/extension_helper.h>
Expand All @@ -30,18 +32,18 @@ class ImportManager::Implementation
explicit Implementation(ImportManager* _parent, QWidget* _topLevelWidget);

/**
* @brief Показать диалог импорта для заданного файла
* @brief Показать диалог импорта для заданных файлов
*/
void showImportDialogFor(const QString& _path);
void showImportDialogFor(const QStringList& _paths);

/**
* @brief Импортировать данные документа из заданного файла
*/
void importAudioplay(const BusinessLayer::ImportOptions& _options);
void importComicBook(const BusinessLayer::ImportOptions& _options);
void importNovel(const BusinessLayer::ImportOptions& _options);
void importScreenplay(const BusinessLayer::ScreenplayImportOptions& _options);
void importStageplay(const BusinessLayer::ImportOptions& _options);
void importAudioplay(const BusinessLayer::ImportOptions* _options);
void importComicBook(const BusinessLayer::ImportOptions* _options);
void importNovel(const BusinessLayer::ImportOptions* _options);
void importScreenplay(const BusinessLayer::ScreenplayImportOptions* _options);
void importStageplay(const BusinessLayer::ImportOptions* _options);

//
// Данные
Expand All @@ -60,54 +62,67 @@ ImportManager::Implementation::Implementation(ImportManager* _parent, QWidget* _
{
}

void ImportManager::Implementation::showImportDialogFor(const QString& _path)
void ImportManager::Implementation::showImportDialogFor(const QStringList& _paths)
{
//
// Формат MS DOC не поддерживается, он отображается только для того, чтобы пользователи
// не теряли свои файлы
//
if (_path.toLower().endsWith(ExtensionHelper::msOfficeBinary())) {
QStringList docFiles;
QStringList filesToImport;
for (const auto& path : _paths) {
if (path.toLower().endsWith(ExtensionHelper::msOfficeBinary())) {
docFiles.append(path);
} else {
filesToImport.append(path);
}
}

if (!docFiles.isEmpty() && filesToImport.isEmpty()) {
StandardDialog::information(topLevelWidget, tr("File format not supported"),
tr("Importing from DOC files is not supported. You need to "
"save the file in DOCX format and repeat the import."));
return;
}

//
// Создаем диалог импорта
//
if (importDialog == nullptr) {
importDialog = new Ui::ImportDialog(_path, topLevelWidget);
importDialog = new Ui::ImportDialog(filesToImport, topLevelWidget);
connect(importDialog, &Ui::ImportDialog::importRequested, importDialog, [this] {
const auto importOptions = importDialog->importOptions();
switch (importOptions.documentType) {
default:
case Domain::DocumentObjectType::Undefined: {
break;
}
case Domain::DocumentObjectType::Audioplay: {
importDialog->hideDialog();
importAudioplay(importOptions);
break;
}
case Domain::DocumentObjectType::ComicBook: {
importDialog->hideDialog();
importComicBook(importOptions);
break;
}
case Domain::DocumentObjectType::Novel: {
importDialog->hideDialog();
importNovel(importOptions);
break;
}
case Domain::DocumentObjectType::Screenplay: {
const auto screenplayImportOptions = importDialog->screenplayImportOptions();
importDialog->hideDialog();
importScreenplay(screenplayImportOptions);
break;
}
case Domain::DocumentObjectType::Stageplay: {
importDialog->hideDialog();
importStageplay(importOptions);
break;
}
const auto optionsList = importDialog->importOptions();
importDialog->hideDialog();
for (const auto& importOptions : optionsList) {
switch (importOptions->documentType) {
default:
case Domain::DocumentObjectType::Undefined: {
break;
}
case Domain::DocumentObjectType::Audioplay: {
importAudioplay(importOptions.get());
break;
}
case Domain::DocumentObjectType::ComicBook: {
importComicBook(importOptions.get());
break;
}
case Domain::DocumentObjectType::Novel: {
importNovel(importOptions.get());
break;
}
case Domain::DocumentObjectType::Screenplay: {
const auto screenplayImportOptions
= static_cast<const BusinessLayer::ScreenplayImportOptions*>(
importOptions.get());
importScreenplay(screenplayImportOptions);
break;
}
case Domain::DocumentObjectType::Stageplay: {
importStageplay(importOptions.get());
break;
}
}
}
});
connect(importDialog, &Ui::ImportDialog::canceled, importDialog,
Expand All @@ -118,17 +133,42 @@ void ImportManager::Implementation::showImportDialogFor(const QString& _path)
});
}

importDialog->showDialog();
//
// Прежде чем показать диалог импорта, выведем предупреждение, если нужно
//
if (!docFiles.isEmpty() && !filesToImport.isEmpty()) {
QString filesList;
for (const auto& file : docFiles) {
QFileInfo fileInfo(file);
filesList += fileInfo.fileName() + "\n";
}
QString title("File format not supported");
QString text(tr("Importing from DOC files is not supported. You need to "
"save the file in DOCX format and repeat the import.\n\nThe "
"following files will not be imported:\n")
+ filesList);
auto dialog = new Dialog(topLevelWidget);
dialog->setContentMaximumWidth(Ui::DesignSystem::dialog().maximumWidth());
dialog->showDialog(title, text,
{ { 0, StandardDialog::generateOkTerm(), Dialog::RejectButton } });
QObject::connect(dialog, &Dialog::finished, dialog, [this, dialog]() {
dialog->hideDialog();
importDialog->showDialog();
});
QObject::connect(dialog, &Dialog::disappeared, dialog, &Dialog::deleteLater);
} else {
importDialog->showDialog();
}
}

void ImportManager::Implementation::importAudioplay(const BusinessLayer::ImportOptions& _options)
void ImportManager::Implementation::importAudioplay(const BusinessLayer::ImportOptions* _options)
{
//
// Определим нужный импортер
//
QScopedPointer<BusinessLayer::AbstractAudioplayImporter> importer;
{
const auto importFilePath = _options.filePath.toLower();
const auto importFilePath = _options->filePath.toLower();
if (importFilePath.endsWith(ExtensionHelper::fountain())
|| importFilePath.endsWith(ExtensionHelper::plainText())) {
importer.reset(new BusinessLayer::AudioplayFountainImporter);
Expand All @@ -149,18 +189,18 @@ void ImportManager::Implementation::importAudioplay(const BusinessLayer::ImportO
const auto audioplay = importer->importAudioplay(_options);
const auto audioplayName = !audioplay.name.isEmpty()
? audioplay.name
: QFileInfo(_options.filePath).completeBaseName();
: QFileInfo(_options->filePath).completeBaseName();
emit q->audioplayImported(audioplayName, audioplay.titlePage, audioplay.text);
}

void ImportManager::Implementation::importComicBook(const BusinessLayer::ImportOptions& _options)
void ImportManager::Implementation::importComicBook(const BusinessLayer::ImportOptions* _options)
{
//
// Определим нужный импортер
//
QScopedPointer<BusinessLayer::AbstractComicBookImporter> importer;
{
const auto importFilePath = _options.filePath.toLower();
const auto importFilePath = _options->filePath.toLower();
if (importFilePath.endsWith(ExtensionHelper::fountain())
|| importFilePath.endsWith(ExtensionHelper::plainText())) {
importer.reset(new BusinessLayer::ComicBookFountainImporter);
Expand All @@ -181,18 +221,18 @@ void ImportManager::Implementation::importComicBook(const BusinessLayer::ImportO
const auto comicbook = importer->importComicBook(_options);
const auto comicbookName = !comicbook.name.isEmpty()
? comicbook.name
: QFileInfo(_options.filePath).completeBaseName();
: QFileInfo(_options->filePath).completeBaseName();
emit q->comicbookImported(comicbookName, comicbook.titlePage, comicbook.text);
}

void ImportManager::Implementation::importNovel(const BusinessLayer::ImportOptions& _options)
void ImportManager::Implementation::importNovel(const BusinessLayer::ImportOptions* _options)
{
//
// Определим нужный импортер
//
QScopedPointer<BusinessLayer::AbstractNovelImporter> importer;
{
const auto importFilePath = _options.filePath.toLower();
const auto importFilePath = _options->filePath.toLower();
if (importFilePath.endsWith(ExtensionHelper::markdown())
|| importFilePath.endsWith(ExtensionHelper::plainText())) {
importer.reset(new BusinessLayer::NovelMarkdownImporter);
Expand All @@ -204,19 +244,19 @@ void ImportManager::Implementation::importNovel(const BusinessLayer::ImportOptio
//
const auto novel = importer->importNovel(_options);
const auto novelName
= !novel.name.isEmpty() ? novel.name : QFileInfo(_options.filePath).completeBaseName();
= !novel.name.isEmpty() ? novel.name : QFileInfo(_options->filePath).completeBaseName();
emit q->novelImported(novelName, novel.text);
}

void ImportManager::Implementation::importScreenplay(
const BusinessLayer::ScreenplayImportOptions& _importOptions)
const BusinessLayer::ScreenplayImportOptions* _importOptions)
{
//
// Определим нужный импортер
//
QScopedPointer<BusinessLayer::AbstractScreenplayImporter> importer;
{
const auto importFilePath = _importOptions.filePath.toLower();
const auto importFilePath = _importOptions->filePath.toLower();
if (importFilePath.endsWith(ExtensionHelper::kitScenarist())) {
importer.reset(new BusinessLayer::ScreenplayKitScenaristImporter);
} else if (importFilePath.endsWith(ExtensionHelper::finalDraft())
Expand Down Expand Up @@ -258,20 +298,20 @@ void ImportManager::Implementation::importScreenplay(
for (const auto& screenplay : screenplays) {
const auto screenplayName = !screenplay.name.isEmpty()
? screenplay.name
: QFileInfo(_importOptions.filePath).completeBaseName();
: QFileInfo(_importOptions->filePath).completeBaseName();
emit q->screenplayImported(screenplayName, screenplay.titlePage, screenplay.synopsis,
screenplay.treatment, screenplay.text);
}
}

void ImportManager::Implementation::importStageplay(const BusinessLayer::ImportOptions& _options)
void ImportManager::Implementation::importStageplay(const BusinessLayer::ImportOptions* _options)
{
//
// Определим нужный импортер
//
QScopedPointer<BusinessLayer::AbstractStageplayImporter> importer;
{
const auto importFilePath = _options.filePath.toLower();
const auto importFilePath = _options->filePath.toLower();
if (importFilePath.endsWith(ExtensionHelper::fountain())
|| importFilePath.endsWith(ExtensionHelper::plainText())) {
importer.reset(new BusinessLayer::StageplayFountainImporter);
Expand All @@ -292,7 +332,7 @@ void ImportManager::Implementation::importStageplay(const BusinessLayer::ImportO
const auto stageplay = importer->importStageplay(_options);
const auto stageplayName = !stageplay.name.isEmpty()
? stageplay.name
: QFileInfo(_options.filePath).completeBaseName();
: QFileInfo(_options->filePath).completeBaseName();
emit q->stageplayImported(stageplayName, stageplay.titlePage, stageplay.text);
}

Expand All @@ -317,24 +357,24 @@ void ImportManager::import()
//
const auto projectImportFolder
= settingsValue(DataStorageLayer::kProjectImportFolderKey).toString();
const auto importFilePath
= QFileDialog::getOpenFileName(d->topLevelWidget, tr("Choose the file to import"),
projectImportFolder, DialogHelper::filtersForImport());
if (importFilePath.isEmpty()) {
const auto importFilePaths
= QFileDialog::getOpenFileNames(d->topLevelWidget, tr("Choose files to import"),
projectImportFolder, DialogHelper::filtersForImport());
if (importFilePaths.isEmpty()) {
return;
}

//
// Если файл был выбран
// Если файлы были выбраны
//
// ... обновим папку, откуда в следующий раз он предположительно опять будет импортировать
// проекты
//
setSettingsValue(DataStorageLayer::kProjectImportFolderKey, importFilePath);
setSettingsValue(DataStorageLayer::kProjectImportFolderKey, importFilePaths.last());
//
// ... и переходим к подготовке импорта
//
d->showImportDialogFor(importFilePath);
d->showImportDialogFor(importFilePaths);
}

void ImportManager::importScreenplay(const QString& _filePath, bool _importDocuments)
Expand All @@ -345,15 +385,15 @@ void ImportManager::importScreenplay(const QString& _filePath, bool _importDocum
options.importCharacters = _importDocuments;
options.importLocations = _importDocuments;
options.importResearch = _importDocuments;
d->importScreenplay(options);
d->importScreenplay(&options);
}

void ImportManager::importNovel(const QString& _filePath)
{
BusinessLayer::ImportOptions options;
options.filePath = _filePath;
options.documentType = Domain::DocumentObjectType::Novel;
d->importNovel(options);
d->importNovel(&options);
}

} // namespace ManagementLayer
Loading

0 comments on commit 7656d8f

Please sign in to comment.