[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