|  |  |  | @@ -188,37 +188,11 @@ QString EditorPlugin::getPluginMenuName() const | 
		
	
		
			
				|  |  |  |  |     return tr("Edi&tor"); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | bool EditorPlugin::save() | 
		
	
		
			
				|  |  |  |  | bool EditorPlugin::updatePageContent(pdf::PDFInteger pageIndex, | 
		
	
		
			
				|  |  |  |  |                                      const std::vector<const pdf::PDFPageContentElement*>& elements, | 
		
	
		
			
				|  |  |  |  |                                      pdf::PDFDocumentBuilder* builder) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     pdf::PDFTemporaryValueChange guard(&m_isSaving, true); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     auto answer = QMessageBox::question(m_dataExchangeInterface->getMainWindow(), tr("Confirm Changes"), tr("The changes to the page content will be written to the document. Do you want to continue?"), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, QMessageBox::Cancel); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     if (answer == QMessageBox::Cancel) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         return false; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     if (answer == QMessageBox::Yes) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         pdf::PDFDocumentModifier modifier(m_document); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     pdf::PDFColorConvertor convertor; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |         std::set<pdf::PDFInteger> pageIndices; | 
		
	
		
			
				|  |  |  |  |         for (const auto& item : m_editedPageContent) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             pageIndices.insert(item.first); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |         auto elementsByPage = m_scene.getElementsByPage(); | 
		
	
		
			
				|  |  |  |  |         for (pdf::PDFInteger pageIndex : pageIndices) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             if (m_editedPageContent.count(pageIndex) == 0) | 
		
	
		
			
				|  |  |  |  |             { | 
		
	
		
			
				|  |  |  |  |                 continue; | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     const pdf::PDFPage* page = m_document->getCatalog()->getPage(pageIndex); | 
		
	
		
			
				|  |  |  |  |     const pdf::PDFEditedPageContent& editedPageContent = m_editedPageContent.at(pageIndex); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
	
		
			
				
					
					|  |  |  | @@ -228,10 +202,7 @@ bool EditorPlugin::save() | 
		
	
		
			
				|  |  |  |  |     pdf::PDFPageContentEditorContentStreamBuilder contentStreamBuilder(m_document); | 
		
	
		
			
				|  |  |  |  |     contentStreamBuilder.setFontDictionary(editedPageContent.getFontDictionary()); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |             auto it = elementsByPage.find(pageIndex); | 
		
	
		
			
				|  |  |  |  |             if (it != elementsByPage.cend()) | 
		
	
		
			
				|  |  |  |  |             { | 
		
	
		
			
				|  |  |  |  |                 for (const pdf::PDFPageContentElement* element : it->second) | 
		
	
		
			
				|  |  |  |  |     for (const pdf::PDFPageContentElement* element : elements) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         const pdf::PDFPageContentElementEdited* editedElement = element->asElementEdited(); | 
		
	
		
			
				|  |  |  |  |         const pdf::PDFPageContentElementRectangle* elementRectangle = element->asElementRectangle(); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -322,7 +293,6 @@ bool EditorPlugin::save() | 
		
	
		
			
				|  |  |  |  |             elementTextBox->drawPage(&painter, &m_scene, pageIndex, nullptr, textLayoutGetter, QTransform(), convertor, errors); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     QStringList errors = contentStreamBuilder.getErrors(); | 
		
	
		
			
				|  |  |  |  |     contentStreamBuilder.clearErrors(); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -342,8 +312,6 @@ bool EditorPlugin::save() | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |             pdf::PDFDocumentBuilder* builder = modifier.getBuilder(); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     pdf::PDFDictionary fontDictionary = contentStreamBuilder.getFontDictionary(); | 
		
	
		
			
				|  |  |  |  |     pdf::PDFDictionary xobjectDictionary = contentStreamBuilder.getXObjectDictionary(); | 
		
	
		
			
				|  |  |  |  |     pdf::PDFDictionary graphicStateDictionary = contentStreamBuilder.getGraphicStateDictionary(); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -402,6 +370,51 @@ bool EditorPlugin::save() | 
		
	
		
			
				|  |  |  |  |     pageObject = pdf::PDFObjectManipulator::merge(pageObject, factory.takeObject(), pdf::PDFObjectManipulator::RemoveNullObjects); | 
		
	
		
			
				|  |  |  |  |     builder->setObject(page->getPageReference(), std::move(pageObject)); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     return true; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | bool EditorPlugin::save() | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     pdf::PDFTemporaryValueChange guard(&m_isSaving, true); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     auto answer = QMessageBox::question(m_dataExchangeInterface->getMainWindow(), tr("Confirm Changes"), tr("The changes to the page content will be written to the document. Do you want to continue?"), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, QMessageBox::Cancel); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     if (answer == QMessageBox::Cancel) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         return false; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     if (answer == QMessageBox::Yes) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         pdf::PDFDocumentModifier modifier(m_document); | 
		
	
		
			
				|  |  |  |  |         pdf::PDFDocumentBuilder* builder = modifier.getBuilder(); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |         std::set<pdf::PDFInteger> pageIndices; | 
		
	
		
			
				|  |  |  |  |         for (const auto& item : m_editedPageContent) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             pageIndices.insert(item.first); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |         std::map<pdf::PDFInteger, std::vector<const pdf::PDFPageContentElement*>> elementsByPage = m_scene.getElementsByPage(); | 
		
	
		
			
				|  |  |  |  |         for (pdf::PDFInteger pageIndex : pageIndices) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             if (m_editedPageContent.count(pageIndex) == 0) | 
		
	
		
			
				|  |  |  |  |             { | 
		
	
		
			
				|  |  |  |  |                 continue; | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |             std::vector<const pdf::PDFPageContentElement*> elements; | 
		
	
		
			
				|  |  |  |  |             auto it = elementsByPage.find(pageIndex); | 
		
	
		
			
				|  |  |  |  |             if (it != elementsByPage.cend()) | 
		
	
		
			
				|  |  |  |  |             { | 
		
	
		
			
				|  |  |  |  |                 elements = std::move(it->second); | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |             if (!updatePageContent(pageIndex, elements, builder)) | 
		
	
		
			
				|  |  |  |  |             { | 
		
	
		
			
				|  |  |  |  |                 return false; | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |             modifier.markReset(); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
	
		
			
				
					
					|  |  |  | @@ -517,6 +530,15 @@ void EditorPlugin::onSceneEditElement(const std::set<pdf::PDFInteger>& elements) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     if (pdf::PDFPageContentEditorStyleSettings::showEditElementStyleDialog(m_dataExchangeInterface->getMainWindow(), element)) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         if (element->asElementEdited()) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             pdf::PDFPageContentElementEdited* editedElement = dynamic_cast<pdf::PDFPageContentElementEdited*>(element); | 
		
	
		
			
				|  |  |  |  |             if (editedElement->getElement()->asText()) | 
		
	
		
			
				|  |  |  |  |             { | 
		
	
		
			
				|  |  |  |  |                 updateTextElement(editedElement); | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |         updateGraphics(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
	
		
			
				
					
					|  |  |  | @@ -751,6 +773,55 @@ void EditorPlugin::updateEditedPages() | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | bool EditorPlugin::updateTextElement(pdf::PDFPageContentElementEdited* element) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     pdf::PDFPageContentElementEdited* elementEdited = dynamic_cast<pdf::PDFPageContentElementEdited*>(element); | 
		
	
		
			
				|  |  |  |  |     pdf::PDFEditedPageContentElementText* targetTextElement = elementEdited->getElement()->asText(); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     if (!targetTextElement) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         return false; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     pdf::PDFDocumentModifier modifier(m_document); | 
		
	
		
			
				|  |  |  |  |     pdf::PDFDocumentBuilder* builder = modifier.getBuilder(); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     if (!updatePageContent(element->getPageIndex(), { element }, builder)) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         return false; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     if (modifier.finalize()) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         pdf::PDFDocument* document = modifier.getDocument().get(); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |         const pdf::PDFPage* page = document->getCatalog()->getPage(element->getPageIndex()); | 
		
	
		
			
				|  |  |  |  |         auto cms = m_widget->getDrawWidgetProxy()->getCMSManager()->getCurrentCMS(); | 
		
	
		
			
				|  |  |  |  |         pdf::PDFFontCache fontCache(64, 64); | 
		
	
		
			
				|  |  |  |  |         pdf::PDFOptionalContentActivity activity(document, pdf::OCUsage::View, nullptr); | 
		
	
		
			
				|  |  |  |  |         fontCache.setDocument(pdf::PDFModifiedDocument(document, &activity)); | 
		
	
		
			
				|  |  |  |  |         pdf::PDFPageContentEditorProcessor processor(page, document, &fontCache, cms.data(), &activity, QTransform(), pdf::PDFMeshQualitySettings()); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |         QList<pdf::PDFRenderError> errors = processor.processContents(); | 
		
	
		
			
				|  |  |  |  |         Q_UNUSED(errors); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |         pdf::PDFEditedPageContent content = processor.takeEditedPageContent(); | 
		
	
		
			
				|  |  |  |  |         if (content.getElementCount() == 1) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             pdf::PDFEditedPageContentElement* sourceElement = content.getElement(0); | 
		
	
		
			
				|  |  |  |  |             pdf::PDFEditedPageContentElementText* sourceElementText = sourceElement->asText(); | 
		
	
		
			
				|  |  |  |  |             targetTextElement->setState(sourceElementText->getState()); | 
		
	
		
			
				|  |  |  |  |             targetTextElement->setTextPath(sourceElementText->getTextPath()); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         else | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             return false; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     return true; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | void EditorPlugin::onDrawSpaceChanged() | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     updateEditedPages(); | 
		
	
	
		
			
				
					
					|  |  |  |   |