From ba78cbff1aaf295fcd17814c82fd8fca5687188f Mon Sep 17 00:00:00 2001 From: dimkanovikov Date: Mon, 12 Dec 2022 13:54:24 +0300 Subject: [PATCH] Fix issues with inserting mime data with tables --- .../business_layer/model/text/text_model.cpp | 72 ++++++++++++++++++- .../model/text/text_model_splitter_item.cpp | 3 + 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/src/corelib/business_layer/model/text/text_model.cpp b/src/corelib/business_layer/model/text/text_model.cpp index e609d97bd..6c08be4e3 100644 --- a/src/corelib/business_layer/model/text/text_model.cpp +++ b/src/corelib/business_layer/model/text/text_model.cpp @@ -1201,6 +1201,7 @@ int TextModel::insertFromMime(const QModelIndex& _index, int _positionInBlock, contentReader.readNextStartElement(); // document contentReader.readNextStartElement(); bool isFirstTextItemHandled = false; + bool isSplitterStartWasCreated = false; TextModelItem* lastItem = item; TextModelItem* insertAfterItem = lastItem; QVector itemsToInsert; @@ -1291,17 +1292,82 @@ int TextModel::insertFromMime(const QModelIndex& _index, int _positionInBlock, } groupItem = static_cast(insertAfterItem); - }; + } } newItem = newGroupItem; } else if (currentTag == xml::kSplitterTag) { - increaseMimeLength(); - newItem = createSplitterItem(contentReader); + const auto previousItemType + = insertAfterItem != nullptr ? insertAfterItem->type() : TextModelItemType::Folder; + switch (previousItemType) { + case TextModelItemType::Text: { + QScopedPointer newSplitterItem( + createSplitterItem(contentReader)); + const auto textItem = static_cast(insertAfterItem); + + // + // Если предыдущий элемент уже в таблице, то не нужно ничего создавать тут + // + if (textItem->isInFirstColumn().has_value()) { + break; + } + // + // Если создаётся открывающий элемент, запоним этот нюанс + // + if (newSplitterItem->splitterType() == TextModelSplitterItemType::Start) { + isSplitterStartWasCreated = true; + } + // + // Если создаётся закрывающий элемент, то позволяем этому свершиться, + // только если был создал открывающий, иначе пропускаем его + // + else { + if (!isSplitterStartWasCreated) { + break; + } + // + // ... сбрасываем статус создания открывающего элемента для следующего прохода + // + isSplitterStartWasCreated = false; + } + + // + // Если всё прошло успешно, добавляем созданный разделитель + // + increaseMimeLength(); + newItem = createSplitterItem(); + newItem->copyFrom(newSplitterItem.data()); + break; + } + + default: { + Q_ASSERT(false); + break; + } + } } else { auto newTextItem = createTextItem(contentReader); increaseMimeLength(newTextItem->text().length()); // + // Смотрим на положение в таблице предыдущего элемента + // + if (insertAfterItem != nullptr && insertAfterItem->type() == TextModelItemType::Text) { + const auto textItem = static_cast(insertAfterItem); + // + // ... если он в таблице, то помещаем добавляемый элемент в ту же колонку + // + if (textItem->isInFirstColumn().has_value()) { + newTextItem->setInFirstColumn(textItem->isInFirstColumn()); + } + // + // ... если не в таблице, и при вставке не было добавлено таблицы, + // то удаляем информацию о таблице в новом текстовом элементе + // + else if (!isSplitterStartWasCreated) { + newTextItem->setInFirstColumn({}); + } + } + // // Если вставляется текстовый элемент внутрь уже существующего элемента // if (!isFirstTextItemHandled) { diff --git a/src/corelib/business_layer/model/text/text_model_splitter_item.cpp b/src/corelib/business_layer/model/text/text_model_splitter_item.cpp index 9740d5b87..bbe6b5986 100644 --- a/src/corelib/business_layer/model/text/text_model_splitter_item.cpp +++ b/src/corelib/business_layer/model/text/text_model_splitter_item.cpp @@ -86,6 +86,9 @@ void TextModelSplitterItem::copyFrom(TextModelItem* _item) Q_ASSERT(false); return; } + + const auto splitterItem = static_cast(_item); + d->splitterType = splitterItem->splitterType(); } bool TextModelSplitterItem::isEqual(TextModelItem* _item) const