[Libreoffice-commits] core.git: sw/inc sw/source

Ashod Nakashian ashod.nakashian at collabora.co.uk
Tue Sep 26 11:54:32 UTC 2017


 sw/inc/UndoParagraphSignature.hxx |   60 +++++++++++++++++
 sw/inc/editsh.hxx                 |   12 +++
 sw/source/core/edit/edfcol.cxx    |  130 +++++++++++++++++++++++++-------------
 sw/source/core/edit/edws.cxx      |    4 -
 sw/source/core/txtnode/ndtxt.cxx  |    2 
 5 files changed, 161 insertions(+), 47 deletions(-)

New commits:
commit 7032d7b3060d8187acc39a4faa095c48fe8d17b4
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Thu Sep 21 22:59:26 2017 -0400

    sw: improve undo handling of Paragraph Signature
    
    Change-Id: I46f395d5f9105d1d3dac6d2af6e9b43ae95ec78e
    Reviewed-on: https://gerrit.libreoffice.org/42733
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>

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)


More information about the Libreoffice-commits mailing list