summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMichael Stahl <Michael.Stahl@cib.de>2019-03-04 13:12:09 +0100
committerMichael Stahl <Michael.Stahl@cib.de>2019-03-05 12:12:58 +0100
commit405661a98f01416c596083262691cedd941733a1 (patch)
treea8f6d81a0f0ae4df03aca6cc6272e5dc91a709cb /sw
parent191f85df5851473af270be486f95f940e3091fef (diff)
tdf#123446 sw_redlinehide: fix crash on Redo of ToX
The problem is that the ToX must be updated with the same layout redline setting as it was originally created, so that subsequent Redo actions see the expected node indexes. Unfortunately it's not enough to just pass a flag to the ToX update functions, because they check GetTextNodeForParaProps() so we need a layout corresponding to the layout setting; if there isn't one, the existing one is temporarily toggled. This could be much better if the MergedPara would be independent of the layout and always exist, but with the various SwModify design issues that looks tricky to do... (regression from 80cedb5dcb6a7dd6c01349b93fab49ecee5f6594) Change-Id: Ibdc5b4ace54ace27e5223a25ecaf39bb493fb69b Reviewed-on: https://gerrit.libreoffice.org/68704 Reviewed-by: Michael Stahl <Michael.Stahl@cib.de> Tested-by: Michael Stahl <Michael.Stahl@cib.de>
Diffstat (limited to 'sw')
-rw-r--r--sw/inc/doc.hxx3
-rw-r--r--sw/source/core/doc/doctxm.cxx7
-rw-r--r--sw/source/core/docnode/ndsect.cxx5
-rw-r--r--sw/source/core/inc/UndoSection.hxx9
-rw-r--r--sw/source/core/inc/rootfrm.hxx7
-rw-r--r--sw/source/core/undo/unsect.cxx41
6 files changed, 62 insertions, 10 deletions
diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index b32263289b2b..e0b38cbf51f8 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -139,6 +139,7 @@ namespace sw { namespace mark {
class MarkManager;
}}
namespace sw {
+ enum class RedlineMode;
class MetaFieldManager;
class UndoManager;
class IShellCursorSupplier;
@@ -1315,7 +1316,7 @@ public:
// insert section (the ODF kind of section, not the nodesarray kind)
SwSection * InsertSwSection(SwPaM const& rRange, SwSectionData &,
- SwTOXBase const*const pTOXBase,
+ std::pair<SwTOXBase const*, sw::RedlineMode> const* pTOXBase,
SfxItemSet const*const pAttr, bool const bUpdate = true);
static sal_uInt16 IsInsRegionAvailable( const SwPaM& rRange,
const SwNode** ppSttNd = nullptr );
diff --git a/sw/source/core/doc/doctxm.cxx b/sw/source/core/doc/doctxm.cxx
index 8b0aa6a15cb0..a601054b963e 100644
--- a/sw/source/core/doc/doctxm.cxx
+++ b/sw/source/core/doc/doctxm.cxx
@@ -365,8 +365,13 @@ SwTOXBaseSection* SwDoc::InsertTableOf( const SwPaM& aPam,
OUString sSectNm = GetUniqueTOXBaseName( *rTOX.GetTOXType(), rTOX.GetTOXName() );
SwSectionData aSectionData( TOX_CONTENT_SECTION, sSectNm );
+
+ std::pair<SwTOXBase const*, sw::RedlineMode> const tmp(&rTOX,
+ pLayout && pLayout->IsHideRedlines()
+ ? sw::RedlineMode::Hidden
+ : sw::RedlineMode::Shown);
SwTOXBaseSection *const pNewSection = dynamic_cast<SwTOXBaseSection *>(
- InsertSwSection( aPam, aSectionData, & rTOX, pSet, false ));
+ InsertSwSection(aPam, aSectionData, & tmp, pSet, false));
if (pNewSection)
{
SwSectionNode *const pSectNd = pNewSection->GetFormat()->GetSectionNode();
diff --git a/sw/source/core/docnode/ndsect.cxx b/sw/source/core/docnode/ndsect.cxx
index e418d4ccbfb1..16c26f4befa1 100644
--- a/sw/source/core/docnode/ndsect.cxx
+++ b/sw/source/core/docnode/ndsect.cxx
@@ -152,7 +152,7 @@ static void lcl_CheckEmptyLayFrame( SwNodes const & rNds, SwSectionData& rSectio
SwSection *
SwDoc::InsertSwSection(SwPaM const& rRange, SwSectionData & rNewData,
- SwTOXBase const*const pTOXBase,
+ std::pair<SwTOXBase const*, sw::RedlineMode> const*const pTOXBaseAndMode,
SfxItemSet const*const pAttr, bool const bUpdate)
{
const SwNode* pPrvNd = nullptr;
@@ -185,7 +185,7 @@ SwDoc::InsertSwSection(SwPaM const& rRange, SwSectionData & rNewData,
bool const bUndo(GetIDocumentUndoRedo().DoesUndo());
if (bUndo)
{
- pUndoInsSect = new SwUndoInsSection(rRange, rNewData, pAttr, pTOXBase);
+ pUndoInsSect = new SwUndoInsSection(rRange, rNewData, pAttr, pTOXBaseAndMode);
GetIDocumentUndoRedo().AppendUndo( std::unique_ptr<SwUndo>(pUndoInsSect) );
GetIDocumentUndoRedo().DoUndo(false);
}
@@ -196,6 +196,7 @@ SwDoc::InsertSwSection(SwPaM const& rRange, SwSectionData & rNewData,
pFormat->SetFormatAttr( *pAttr );
}
+ SwTOXBase const*const pTOXBase(pTOXBaseAndMode ? pTOXBaseAndMode->first : nullptr);
SwSectionNode* pNewSectNode = nullptr;
RedlineFlags eOld = getIDocumentRedlineAccess().GetRedlineFlags();
diff --git a/sw/source/core/inc/UndoSection.hxx b/sw/source/core/inc/UndoSection.hxx
index c221d79b3145..ef8847dae1e0 100644
--- a/sw/source/core/inc/UndoSection.hxx
+++ b/sw/source/core/inc/UndoSection.hxx
@@ -30,11 +30,15 @@ class SwSectionData;
class SwSectionFormat;
class SwTOXBase;
+namespace sw {
+ enum class RedlineMode;
+};
+
class SwUndoInsSection : public SwUndo, private SwUndRng
{
private:
const std::unique_ptr<SwSectionData> m_pSectionData;
- const std::unique_ptr<SwTOXBase> m_pTOXBase; /// set iff section is TOX
+ const std::unique_ptr<std::pair<SwTOXBase *, sw::RedlineMode>> m_pTOXBase; /// set iff section is TOX
const std::unique_ptr<SfxItemSet> m_pAttrSet;
std::unique_ptr<SwHistory> m_pHistory;
std::unique_ptr<SwRedlineData> m_pRedlData;
@@ -48,7 +52,8 @@ private:
public:
SwUndoInsSection(SwPaM const&, SwSectionData const&,
- SfxItemSet const*const pSet, SwTOXBase const*const pTOXBase);
+ SfxItemSet const* pSet,
+ std::pair<SwTOXBase const*, sw::RedlineMode> const* pTOXBase);
virtual ~SwUndoInsSection() override;
diff --git a/sw/source/core/inc/rootfrm.hxx b/sw/source/core/inc/rootfrm.hxx
index e0dfd88f919b..d9893e6e31f9 100644
--- a/sw/source/core/inc/rootfrm.hxx
+++ b/sw/source/core/inc/rootfrm.hxx
@@ -41,6 +41,13 @@ class SwSelectionList;
struct SwPosition;
struct SwCursorMoveState;
+namespace sw {
+ enum class RedlineMode
+ {
+ Shown, Hidden
+ };
+};
+
enum class SwInvalidateFlags
{
Size = 0x01,
diff --git a/sw/source/core/undo/unsect.cxx b/sw/source/core/undo/unsect.cxx
index 1b5dc8e359cf..d00c29ef868a 100644
--- a/sw/source/core/undo/unsect.cxx
+++ b/sw/source/core/undo/unsect.cxx
@@ -21,12 +21,14 @@
#include <UndoSection.hxx>
#include <osl/diagnose.h>
+#include <comphelper/scopeguard.hxx>
#include <sfx2/linkmgr.hxx>
#include <fmtcntnt.hxx>
#include <doc.hxx>
#include <IDocumentLinksAdministration.hxx>
#include <IDocumentRedlineAccess.hxx>
#include <IDocumentFieldsAccess.hxx>
+#include <IDocumentLayoutAccess.hxx>
#include <docary.hxx>
#include <swundo.hxx>
#include <pam.hxx>
@@ -37,6 +39,7 @@
#include <redline.hxx>
#include <doctxm.hxx>
#include <ftnidx.hxx>
+#include <rootfrm.hxx>
#include <editsh.hxx>
/// OD 04.10.2002 #102894#
/// class Calc needed for calculation of the hidden condition of a section.
@@ -70,10 +73,14 @@ static std::unique_ptr<SfxItemSet> lcl_GetAttrSet( const SwSection& rSect )
SwUndoInsSection::SwUndoInsSection(
SwPaM const& rPam, SwSectionData const& rNewData,
- SfxItemSet const*const pSet, SwTOXBase const*const pTOXBase)
+ SfxItemSet const*const pSet,
+ std::pair<SwTOXBase const*, sw::RedlineMode> const*const pTOXBase)
: SwUndo( SwUndoId::INSSECTION, rPam.GetDoc() ), SwUndRng( rPam )
, m_pSectionData(new SwSectionData(rNewData))
- , m_pTOXBase( pTOXBase ? new SwTOXBase(*pTOXBase) : nullptr )
+ , m_pTOXBase( pTOXBase
+ ? std::make_unique<std::pair<SwTOXBase *, sw::RedlineMode>>(
+ new SwTOXBase(*pTOXBase->first), pTOXBase->second)
+ : nullptr )
, m_pAttrSet( (pSet && pSet->Count()) ? new SfxItemSet( *pSet ) : nullptr )
, m_nSectionNodePos(0)
, m_bSplitAtStart(false)
@@ -172,8 +179,32 @@ void SwUndoInsSection::RedoImpl(::sw::UndoRedoContext & rContext)
const SwTOXBaseSection* pUpdateTOX = nullptr;
if (m_pTOXBase)
{
+ SwRootFrame const* pLayout(nullptr);
+ SwRootFrame * pLayoutToReset(nullptr);
+ comphelper::ScopeGuard g([&]() {
+ if (pLayoutToReset)
+ {
+ pLayoutToReset->SetHideRedlines(m_pTOXBase->second == sw::RedlineMode::Shown);
+ }
+ });
+ std::set<SwRootFrame *> layouts(rDoc.GetAllLayouts());
+ for (SwRootFrame const*const p : layouts)
+ {
+ if ((m_pTOXBase->second == sw::RedlineMode::Hidden) == p->IsHideRedlines())
+ {
+ pLayout = p;
+ break;
+ }
+ }
+ if (!pLayout)
+ {
+ assert(!layouts.empty()); // must have one layout
+ pLayoutToReset = *layouts.begin();
+ pLayoutToReset->SetHideRedlines(m_pTOXBase->second == sw::RedlineMode::Hidden);
+ pLayout = pLayoutToReset;
+ }
pUpdateTOX = rDoc.InsertTableOf( *rPam.GetPoint(),
- *m_pTOXBase, m_pAttrSet.get(), true);
+ *m_pTOXBase->first, m_pAttrSet.get(), true, pLayout);
}
else
{
@@ -222,7 +253,8 @@ void SwUndoInsSection::RepeatImpl(::sw::RepeatContext & rContext)
if (m_pTOXBase)
{
rDoc.InsertTableOf(*rContext.GetRepeatPaM().GetPoint(),
- *m_pTOXBase, m_pAttrSet.get(), true);
+ *m_pTOXBase->first, m_pAttrSet.get(), true,
+ rDoc.getIDocumentLayoutAccess().GetCurrentLayout()); // TODO add shell to RepeatContext?
}
else
{
@@ -320,6 +352,7 @@ void SwUndoDelSection::UndoImpl(::sw::UndoRedoContext & rContext)
if (m_pTOXBase)
{
+ // sw_redlinehide: this should work as-is; there will be another undo for the update
rDoc.InsertTableOf(m_nStartNode, m_nEndNode-2, *m_pTOXBase,
m_pAttrSet.get());
}