diff options
author | Ashod Nakashian <ashod.nakashian@collabora.co.uk> | 2017-09-21 22:59:26 -0400 |
---|---|---|
committer | Ashod Nakashian <ashnakash@gmail.com> | 2017-09-26 13:54:09 +0200 |
commit | 7032d7b3060d8187acc39a4faa095c48fe8d17b4 (patch) | |
tree | a15f0cb3a99c9b9f51a395cdbfb0d8af4964b95d /sw | |
parent | 9679fb26558ea42e47ac9936cef329115a8fdf65 (diff) |
sw: improve undo handling of Paragraph Signature
Change-Id: I46f395d5f9105d1d3dac6d2af6e9b43ae95ec78e
Reviewed-on: https://gerrit.libreoffice.org/42733
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/inc/UndoParagraphSignature.hxx | 60 | ||||
-rw-r--r-- | sw/inc/editsh.hxx | 12 | ||||
-rw-r--r-- | sw/source/core/edit/edfcol.cxx | 130 | ||||
-rw-r--r-- | sw/source/core/edit/edws.cxx | 4 | ||||
-rw-r--r-- | sw/source/core/txtnode/ndtxt.cxx | 2 |
5 files changed, 161 insertions, 47 deletions
diff --git a/sw/inc/UndoParagraphSignature.hxx b/sw/inc/UndoParagraphSignature.hxx new file mode 100644 index 000000000000..e0f1613d91df --- /dev/null +++ b/sw/inc/UndoParagraphSignature.hxx @@ -0,0 +1,60 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_SW_INC_UNDOPARAGRAPHSIGNATURE_HXX +#define INCLUDED_SW_INC_UNDOPARAGRAPHSIGNATURE_HXX + +#include <undobj.hxx> +#include <rtl/ustring.hxx> + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/text/XTextContent.hpp> +#include <com/sun/star/text/XTextField.hpp> + +struct SwPosition; +class SwDoc; + +/// Undo/Redo Paragraph Signature. +class SwUndoParagraphSigning : public SwUndo +{ +private: + SwDoc* m_pDoc; + uno::Reference<text::XTextField> m_xField; + uno::Reference<text::XTextContent> m_xParent; + OUString m_signature; + OUString m_display; + const bool m_bRemove; + +public: + SwUndoParagraphSigning(const SwPosition& rPos, + const uno::Reference<text::XTextField>& xField, + const uno::Reference<text::XTextContent>& xParent, + const bool bRemove); + + virtual void UndoImpl(::sw::UndoRedoContext&) override; + virtual void RedoImpl(::sw::UndoRedoContext&) override; + virtual void RepeatImpl(::sw::RepeatContext&) override; + +private: + void Insert(); + void Remove(); +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/inc/editsh.hxx b/sw/inc/editsh.hxx index bda5d3216a48..9ca6bb683941 100644 --- a/sw/inc/editsh.hxx +++ b/sw/inc/editsh.hxx @@ -946,6 +946,16 @@ public: OUString DeleteExtTextInput( bool bInsText = true); void SetExtTextInputData( const CommandExtTextInputData& ); + /// Returns true iff paragraph signature validation is enabled. + bool IsParagraphSignatureValidationEnabled() const { return m_bDoParagraphSignatureValidation; } + /// Enable/Disable paragraph signature validation and return the previous value. + bool SetParagraphSignatureValidation(const bool bEnable) + { + const bool bOldFlag = m_bDoParagraphSignatureValidation; + m_bDoParagraphSignatureValidation = bEnable; + return bOldFlag; + } + /// Interface for access to AutoComplete-list. static SwAutoCompleteWord& GetAutoCompleteWords(); @@ -975,7 +985,7 @@ private: * the existing nb-space will be removed. Bear this in mind if that problem * arises. */ bool m_bNbspRunNext; ///< NO-BREAK SPACE state flag passed to and maintained by SvxAutoCorrect::DoAutoCorrect() - bool m_bIsValidatingParagraphSignature; ///< Prevent nested calls of ValidateParagraphSignatures. + bool m_bDoParagraphSignatureValidation; ///< Prevent nested calls of ValidateParagraphSignatures. }; inline const sfx2::LinkManager& SwEditShell::GetLinkManager() const diff --git a/sw/source/core/edit/edfcol.cxx b/sw/source/core/edit/edfcol.cxx index 99853acf09de..c9c0b1c77ebf 100644 --- a/sw/source/core/edit/edfcol.cxx +++ b/sw/source/core/edit/edfcol.cxx @@ -32,6 +32,7 @@ #include <com/sun/star/text/TextContentAnchorType.hpp> #include <com/sun/star/text/VertOrientation.hpp> #include <com/sun/star/text/WrapTextMode.hpp> +#include <com/sun/star/text/XTextContent.hpp> #include <com/sun/star/text/XTextField.hpp> #include <com/sun/star/text/XTextRange.hpp> #include <com/sun/star/xml/crypto/SEInitializer.hpp> @@ -77,6 +78,7 @@ #include <modeltoviewhelper.hxx> #include <strings.hrc> #include <undobj.hxx> +#include <UndoParagraphSignature.hxx> #include <officecfg/Office/Common.hxx> #include <com/sun/star/beans/PropertyAttribute.hpp> @@ -257,10 +259,18 @@ lcl_MakeParagraphSignatureFieldText(const uno::Reference<frame::XModel>& xModel, } /// Updates the signature field text if changed and returns true only iff updated. -bool lcl_UpdateParagraphSignatureField(const uno::Reference<frame::XModel>& xModel, +bool lcl_UpdateParagraphSignatureField(SwDoc* pDoc, + const uno::Reference<frame::XModel>& xModel, const uno::Reference<css::text::XTextField>& xField, const OString& utf8Text) { + // Disable undo to avoid introducing noise when we edit the metadata field. + const bool isUndoEnabled = pDoc->GetIDocumentUndoRedo().DoesUndo(); + pDoc->GetIDocumentUndoRedo().DoUndo(false); + comphelper::ScopeGuard const g([pDoc, isUndoEnabled] () { + pDoc->GetIDocumentUndoRedo().DoUndo(isUndoEnabled); + }); + const std::pair<bool, OUString> res = lcl_MakeParagraphSignatureFieldText(xModel, xField, utf8Text); uno::Reference<css::text::XTextRange> xText(xField, uno::UNO_QUERY); const OUString curText = xText->getString(); @@ -924,32 +934,15 @@ void SwEditShell::SetWatermark(const SfxWatermarkItem& rWatermark) } } -class SwUndoParagraphSigning : public SwUndo -{ -private: - SwDoc* m_pDoc; - uno::Reference<text::XTextField> m_xField; - uno::Reference<text::XTextContent> m_xParent; - OUString m_signature; - OUString m_display; - -public: - SwUndoParagraphSigning(const SwPosition& rPos, - const uno::Reference<text::XTextField>& xField, - const uno::Reference<text::XTextContent>& xParent); - - virtual void UndoImpl(::sw::UndoRedoContext&) override; - virtual void RedoImpl(::sw::UndoRedoContext&) override; - virtual void RepeatImpl(::sw::RepeatContext&) override; -}; - SwUndoParagraphSigning::SwUndoParagraphSigning(const SwPosition& rPos, const uno::Reference<text::XTextField>& xField, - const uno::Reference<text::XTextContent>& xParent) + const uno::Reference<text::XTextContent>& xParent, + const bool bRemove) : SwUndo(SwUndoId::PARA_SIGN_ADD, rPos.GetDoc()), m_pDoc(rPos.GetDoc()), m_xField(xField), - m_xParent(xParent) + m_xParent(xParent), + m_bRemove(bRemove) { // Save the metadata and field content to undo/redo. static const OUString metaNS("urn:bails"); @@ -966,11 +959,39 @@ SwUndoParagraphSigning::SwUndoParagraphSigning(const SwPosition& rPos, void SwUndoParagraphSigning::UndoImpl(::sw::UndoRedoContext&) { - lcl_RemoveParagraphSignatureField(m_xField); + if (m_bRemove) + Remove(); + else + Insert(); } void SwUndoParagraphSigning::RedoImpl(::sw::UndoRedoContext&) { + if (m_bRemove) + Insert(); + else + Remove(); +} + +void SwUndoParagraphSigning::RepeatImpl(::sw::RepeatContext&) +{ +} + +void SwUndoParagraphSigning::Insert() +{ + // Disable undo to avoid introducing noise when we edit the metadata field. + const bool isUndoEnabled = m_pDoc->GetIDocumentUndoRedo().DoesUndo(); + m_pDoc->GetIDocumentUndoRedo().DoUndo(false); + + // Prevent validation since this will trigger a premature validation + // upon inserting, but before seting the metadata. + SwEditShell* pEditSh = m_pDoc->GetEditShell(); + const bool bOldValidationFlag = pEditSh->SetParagraphSignatureValidation(false); + comphelper::ScopeGuard const g([&] () { + pEditSh->SetParagraphSignatureValidation(bOldValidationFlag); + m_pDoc->GetIDocumentUndoRedo().DoUndo(isUndoEnabled); + }); + static const OUString metaFile("bails.rdf"); static const OUString metaNS("urn:bails"); const OUString name = "loext:signature:signature"; @@ -987,8 +1008,22 @@ void SwUndoParagraphSigning::RedoImpl(::sw::UndoRedoContext&) xText->setString(m_display); } -void SwUndoParagraphSigning::RepeatImpl(::sw::RepeatContext&) +void SwUndoParagraphSigning::Remove() { + // Disable undo to avoid introducing noise when we edit the metadata field. + const bool isUndoEnabled = m_pDoc->GetIDocumentUndoRedo().DoesUndo(); + m_pDoc->GetIDocumentUndoRedo().DoUndo(false); + + // Prevent validation since this will trigger a premature validation + // upon removing. + SwEditShell* pEditSh = m_pDoc->GetEditShell(); + const bool bOldValidationFlag = pEditSh->SetParagraphSignatureValidation(false); + comphelper::ScopeGuard const g([&] () { + pEditSh->SetParagraphSignatureValidation(bOldValidationFlag); + m_pDoc->GetIDocumentUndoRedo().DoUndo(isUndoEnabled); + }); + + lcl_RemoveParagraphSignatureField(m_xField); } void SwEditShell::SignParagraph(SwPaM* pPaM) @@ -1034,6 +1069,13 @@ void SwEditShell::SignParagraph(SwPaM* pPaM) static const OUString metaNS("urn:bails"); static const OUString metaFile("bails.rdf"); + // Prevent validation since this will trigger a premature validation + // upon inserting, but before seting the metadata. + const bool bOldValidationFlag = SetParagraphSignatureValidation(false); + comphelper::ScopeGuard const g([this, bOldValidationFlag] () { + SetParagraphSignatureValidation(bOldValidationFlag); + }); + uno::Reference<frame::XModel> xModel = pDocShell->GetBaseModel(); uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(xModel, uno::UNO_QUERY); uno::Reference<css::text::XTextField> xField(xMultiServiceFactory->createInstance("com.sun.star.text.textfield.MetadataField"), uno::UNO_QUERY); @@ -1051,7 +1093,7 @@ void SwEditShell::SignParagraph(SwPaM* pPaM) // Disable undo to avoid introducing noise when we edit the metadata field. const bool isUndoEnabled = GetDoc()->GetIDocumentUndoRedo().DoesUndo(); GetDoc()->GetIDocumentUndoRedo().DoUndo(false); - comphelper::ScopeGuard const g([&] () { + comphelper::ScopeGuard const g2([&] () { GetDoc()->GetIDocumentUndoRedo().DoUndo(isUndoEnabled); }); @@ -1060,7 +1102,7 @@ void SwEditShell::SignParagraph(SwPaM* pPaM) xText->setString(res.second + " "); } - SwUndoParagraphSigning* pUndo = new SwUndoParagraphSigning(SwPosition(*pNode), xField, xParent); + SwUndoParagraphSigning* pUndo = new SwUndoParagraphSigning(SwPosition(*pNode), xField, xParent, true); GetDoc()->GetIDocumentUndoRedo().AppendUndo(pUndo); GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::PARA_SIGN_ADD, nullptr); @@ -1069,7 +1111,7 @@ void SwEditShell::SignParagraph(SwPaM* pPaM) void SwEditShell::ValidateParagraphSignatures(bool updateDontRemove) { SwDocShell* pDocShell = GetDoc()->GetDocShell(); - if (!pDocShell || m_bIsValidatingParagraphSignature) + if (!pDocShell || !IsParagraphSignatureValidationEnabled()) return; SwPaM* pPaM = GetCursor(); @@ -1078,14 +1120,8 @@ void SwEditShell::ValidateParagraphSignatures(bool updateDontRemove) if (!pNode) return; - const uno::Reference<text::XTextContent> xParent = SwXParagraph::CreateXParagraph(*pNode->GetDoc(), pNode); - - // 1. Get the text (without fields). - const OString utf8Text = lcl_getParagraphBodyText(xParent); - if (utf8Text.isEmpty()) - return; - // 2. For each signature field, update it. + const uno::Reference<text::XTextContent> xParent = SwXParagraph::CreateXParagraph(*pNode->GetDoc(), pNode); uno::Reference<container::XEnumerationAccess> xTextPortionEnumerationAccess(xParent, uno::UNO_QUERY); if (!xTextPortionEnumerationAccess.is()) return; @@ -1094,16 +1130,16 @@ void SwEditShell::ValidateParagraphSignatures(bool updateDontRemove) uno::Reference<container::XEnumeration> xTextPortions = xTextPortionEnumerationAccess->createEnumeration(); // Prevent recursive validation since this is triggered on node updates, which we do below. - m_bIsValidatingParagraphSignature = true; - // Disable undo to avoid introducing noise when we edit the metadata field. - const bool isUndoEnabled = GetDoc()->GetIDocumentUndoRedo().DoesUndo(); - GetDoc()->GetIDocumentUndoRedo().DoUndo(false); - - comphelper::ScopeGuard const g([this, isUndoEnabled] () { - m_bIsValidatingParagraphSignature = false; - GetDoc()->GetIDocumentUndoRedo().DoUndo(isUndoEnabled); + const bool bOldValidationFlag = SetParagraphSignatureValidation(false); + comphelper::ScopeGuard const g([this, bOldValidationFlag] () { + SetParagraphSignatureValidation(bOldValidationFlag); }); + // 2. Get the text (without fields). + const OString utf8Text = lcl_getParagraphBodyText(xParent); + if (utf8Text.isEmpty()) + return; + while (xTextPortions->hasMoreElements()) { uno::Reference<beans::XPropertySet> xTextPortion(xTextPortions->nextElement(), uno::UNO_QUERY); @@ -1120,9 +1156,17 @@ void SwEditShell::ValidateParagraphSignatures(bool updateDontRemove) uno::Reference<text::XTextField> xContent(xTextField, uno::UNO_QUERY); if (updateDontRemove) - lcl_UpdateParagraphSignatureField(xModel, xContent, utf8Text); + { + lcl_UpdateParagraphSignatureField(GetDoc(), xModel, xContent, utf8Text); + } else if (!lcl_MakeParagraphSignatureFieldText(xModel, xContent, utf8Text).first) + { + GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::PARA_SIGN_ADD, nullptr); + SwUndoParagraphSigning* pUndo = new SwUndoParagraphSigning(SwPosition(*pNode), xContent, xParent, false); + GetDoc()->GetIDocumentUndoRedo().AppendUndo(pUndo); lcl_RemoveParagraphSignatureField(xContent); + GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::PARA_SIGN_ADD, nullptr); + } } } diff --git a/sw/source/core/edit/edws.cxx b/sw/source/core/edit/edws.cxx index 5c5c0f658e85..6e0b62b7950f 100644 --- a/sw/source/core/edit/edws.cxx +++ b/sw/source/core/edit/edws.cxx @@ -37,14 +37,14 @@ SwEditShell::SwEditShell( SwEditShell& rEdSH, vcl::Window *pWindow ) : SwCursorShell( rEdSH, pWindow ) , m_bNbspRunNext(false) // TODO: would copying that make sense? only if editing continues - , m_bIsValidatingParagraphSignature(false) + , m_bDoParagraphSignatureValidation(true) { } SwEditShell::SwEditShell( SwDoc& rDoc, vcl::Window *pWindow, const SwViewOption *pOptions ) : SwCursorShell( rDoc, pWindow, pOptions ) , m_bNbspRunNext(false) - , m_bIsValidatingParagraphSignature(false) + , m_bDoParagraphSignatureValidation(true) { if (!utl::ConfigManager::IsAvoidConfig() && 0 < officecfg::Office::Common::Undo::Steps::get()) { diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx index b7d5f3dc4e80..c50dbc1630a9 100644 --- a/sw/source/core/txtnode/ndtxt.cxx +++ b/sw/source/core/txtnode/ndtxt.cxx @@ -1214,7 +1214,7 @@ void SwTextNode::Update( // Update the paragraph signatures. if (SwEditShell* pEditShell = GetDoc()->GetEditShell()) { - pEditShell->ValidateParagraphSignatures(false); + pEditShell->ValidateParagraphSignatures(true); } // Inform LOK clients about change in position of redlines (if any) |