Skip to content

Commit

Permalink
Add import of review marks from PDF
Browse files Browse the repository at this point in the history
  • Loading branch information
iljukhaput authored and dimkanovikov committed Oct 14, 2024
1 parent 09e0831 commit d382266
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 5 deletions.
97 changes: 94 additions & 3 deletions src/corelib/business_layer/import/abstract_document_importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,91 @@ const QRegularExpression NOISE_AT_START("^" + NOISE);
*/
const QRegularExpression NOISE_AT_END(NOISE + "$");

/**
* @brief Очистить блок от лишних пробельных символов
* @note Аналог QString::simplified(), только при этом форматы символов остаются на своих местах
*/
void simplifyTextBlock(QTextCursor& _cursor)
{
auto findEndPosition = [&_cursor]() {
const int currentPosition = _cursor.position();
_cursor.movePosition(QTextCursor::EndOfBlock);
const int end = _cursor.position();
_cursor.setPosition(currentPosition);
return end;
};

int endPosition = findEndPosition();
_cursor.movePosition(QTextCursor::StartOfBlock);
while (true) {
Q_ASSERT(_cursor.position() < endPosition);
_cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);

//
// Удаляем пробельные символы
//
while (_cursor.selectedText().simplified().isEmpty()) {
_cursor.removeSelectedText();
endPosition = findEndPosition();
if (_cursor.position() == endPosition) {
break;
}
_cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
}

//
// Если конец, выходим из цикла
//
if (_cursor.position() == endPosition) {
break;
}

//
// Перемещаем anchor на позицию курсора
//
_cursor.movePosition(QTextCursor::NextCharacter);

//
// Пропускаем непробельные символы
//
_cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
while (_cursor.position() != endPosition
&& !_cursor.selectedText().simplified().isEmpty()) {
//
// Перемещаем anchor на позицию курсора
//
_cursor.movePosition(QTextCursor::NextCharacter);

_cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
}

//
// Если конец, выходим из цикла
//
if (_cursor.position() == endPosition) {
break;
} else {
//
// ... если не конец, вставляем пробел после слова
//
const auto format = _cursor.charFormat();
_cursor.removeSelectedText();
_cursor.insertText(QString(QChar::Space), format);
}
}

//
// В конце мог остаться пробельный символ
//
_cursor.movePosition(QTextCursor::EndOfBlock);
_cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor);
if (_cursor.selectedText().simplified().isEmpty()) {
_cursor.removeSelectedText();
}

_cursor.movePosition(QTextCursor::EndOfBlock);
}

} // namespace


Expand Down Expand Up @@ -129,7 +214,13 @@ AbstractImporter::Documents AbstractDocumentImporter::importDocuments(
//
const auto blockType
= typeForTextCursor(cursor, lastBlockType, emptyLines, minLeftMargin);
QString paragraphText = cursor.block().text().simplified();

//
// ... удаляем лишние пробельные символы
//
simplifyTextBlock(cursor);

QString paragraphText = cursor.block().text();

//
// Если текущий тип "Время и место", то удалим номер сцены
Expand Down Expand Up @@ -285,8 +376,8 @@ QString AbstractDocumentImporter::parseDocument(const ImportOptions& _options,
//
// Выполняем корректировки
//
const auto paragraphText
= clearBlockText(blockType, cursor.block().text().simplified());
simplifyTextBlock(cursor);
const auto paragraphText = clearBlockText(blockType, cursor.block().text());

//
// Формируем блок сценария
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@
#include "screenplay_import_options.h"

#include <business_layer/model/screenplay/text/screenplay_text_block_parser.h>
#include <business_layer/model/text/text_model_xml.h>
#include <data_layer/storage/settings_storage.h>
#include <data_layer/storage/storage_facade.h>

#include <QFileInfo>
#include <QTextBlock>
#include <QTextDocument>
#include <QXmlStreamWriter>


namespace BusinessLayer {
Expand Down Expand Up @@ -46,7 +51,7 @@ bool ScreenplayPdfImporter::documentForImport(const QString& _filePath,
QFile documentFile(_filePath);
if (documentFile.open(QIODevice::ReadOnly)) {
//
// Используем TableExtraction, чтобы извлечь не только текст, но и линии
// Используем TableExtraction, чтобы извлечь не только текст, но и линии.
//
TableExtraction tableExtractor;
tableExtractor.ExtractTables(_filePath.toStdString(), 0, -1, true);
Expand All @@ -56,6 +61,44 @@ bool ScreenplayPdfImporter::documentForImport(const QString& _filePath,
return false;
}

void ScreenplayPdfImporter::writeReviewMarks(QXmlStreamWriter& _writer, QTextCursor& _cursor) const
{
const QTextBlock currentBlock = _cursor.block();
if (!currentBlock.textFormats().isEmpty()) {
_writer.writeStartElement(xml::kReviewMarksTag);
for (const auto& range : currentBlock.textFormats()) {
if (range.format.hasProperty(QTextFormat::BackgroundBrush)
|| range.format.hasProperty(QTextFormat::BackgroundBrush)) {
_writer.writeStartElement(xml::kReviewMarkTag);
_writer.writeAttribute(xml::kFromAttribute, QString::number(range.start));
_writer.writeAttribute(xml::kLengthAttribute, QString::number(range.length));
if (range.format.hasProperty(QTextFormat::ForegroundBrush)) {
_writer.writeAttribute(xml::kColorAttribute,
range.format.foreground().color().name());
}
if (range.format.hasProperty(QTextFormat::BackgroundBrush)) {
_writer.writeAttribute(xml::kBackgroundColorAttribute,
range.format.background().color().name());
}
//
// Пишем пустой комментарий
//
_writer.writeStartElement(xml::kCommentTag);
_writer.writeAttribute(
xml::kAuthorAttribute,
DataStorageLayer::StorageFacade::settingsStorage()->accountName());
_writer.writeAttribute(xml::kDateAttribute,
QDateTime::currentDateTime().toString(Qt::ISODate));
_writer.writeCDATA(QString());
_writer.writeEndElement(); // comment
//
_writer.writeEndElement(); // review mark
}
}
_writer.writeEndElement(); // review marks
}
}

bool ScreenplayPdfImporter::shouldKeepSceneNumbers(const ImportOptions& _options) const
{
const auto& options = static_cast<const ScreenplayImportOptions&>(_options);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ class CORE_LIBRARY_EXPORT ScreenplayPdfImporter : public AbstractScreenplayImpor
*/
bool documentForImport(const QString& _filePath, QTextDocument& _document) const override;

/**
* @brief Записать редакторские заметки
*/
void writeReviewMarks(QXmlStreamWriter& _writer, QTextCursor& _cursor) const override;

/**
* @brief Следует ли сохранять номера сцен
*/
Expand Down

0 comments on commit d382266

Please sign in to comment.