1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <fmtrfmrk.hxx>
22 #include <libxml/xmlwriter.h>
24 #include <hintids.hxx>
26 #include <txtrfmrk.hxx>
27 #include <unorefmark.hxx>
29 #include <sfx2/viewsh.hxx>
30 #include <tools/json_writer.hxx>
31 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
32 #include <comphelper/lok.hxx>
36 #include <translatehelper.hxx>
39 SwFormatRefMark::~SwFormatRefMark( )
43 SwFormatRefMark::SwFormatRefMark( OUString aName
)
44 : SfxPoolItem(RES_TXTATR_REFMARK
)
45 , sw::BroadcastingModify()
46 , m_pTextAttr(nullptr)
47 , m_aRefName(std::move(aName
))
51 SwFormatRefMark::SwFormatRefMark( const SwFormatRefMark
& rAttr
)
52 : SfxPoolItem(RES_TXTATR_REFMARK
)
53 , sw::BroadcastingModify()
54 , m_pTextAttr(nullptr)
55 , m_aRefName(rAttr
.m_aRefName
)
59 void SwFormatRefMark::SetXRefMark(rtl::Reference
<SwXReferenceMark
> const& xMark
)
60 { m_wXReferenceMark
= xMark
.get(); }
62 bool SwFormatRefMark::operator==( const SfxPoolItem
& rAttr
) const
64 assert(SfxPoolItem::operator==(rAttr
));
65 return m_aRefName
== static_cast<const SwFormatRefMark
&>(rAttr
).m_aRefName
;
68 SwFormatRefMark
* SwFormatRefMark::Clone( SfxItemPool
* ) const
70 return new SwFormatRefMark( *this );
73 void SwFormatRefMark::SwClientNotify(const SwModify
&, const SfxHint
& rHint
)
75 if (rHint
.GetId() != SfxHintId::SwLegacyModify
)
77 auto pLegacy
= static_cast<const sw::LegacyModifyHint
*>(&rHint
);
78 CallSwClientNotify(rHint
);
79 if(RES_REMOVE_UNO_OBJECT
== pLegacy
->GetWhich())
83 void SwFormatRefMark::InvalidateRefMark()
85 SwPtrMsgPoolItem
const item(RES_REMOVE_UNO_OBJECT
,
86 &static_cast<sw::BroadcastingModify
&>(*this)); // cast to base class (void*)
87 CallSwClientNotify(sw::LegacyModifyHint(&item
, &item
));
90 void SwFormatRefMark::dumpAsXml(xmlTextWriterPtr pWriter
) const
92 (void)xmlTextWriterStartElement(pWriter
, BAD_CAST("SwFormatRefMark"));
93 (void)xmlTextWriterWriteFormatAttribute(pWriter
, BAD_CAST("ptr"), "%p", this);
94 (void)xmlTextWriterWriteFormatAttribute(pWriter
, BAD_CAST("m_pTextAttr"), "%p", m_pTextAttr
);
95 (void)xmlTextWriterWriteAttribute(pWriter
, BAD_CAST("ref-name"),
96 BAD_CAST(m_aRefName
.toUtf8().getStr()));
97 SfxPoolItem::dumpAsXml(pWriter
);
100 (void)xmlTextWriterEndElement(pWriter
);
103 // attribute for content references in the text
105 SwTextRefMark::SwTextRefMark( SwFormatRefMark
& rAttr
,
106 sal_Int32
const nStartPos
, sal_Int32
const*const pEnd
)
107 : SwTextAttr(rAttr
, nStartPos
)
108 , SwTextAttrEnd( rAttr
, nStartPos
, nStartPos
)
109 , m_pTextNode( nullptr )
112 rAttr
.m_pTextAttr
= this;
120 SetHasDummyChar(true);
122 SetDontMoveAttr( true );
123 SetOverlapAllowedAttr( true );
124 /* FIXME: Setting the DontExpand flag would solve tdf#81720,
125 * but old behavior was restored due to regressions; see tdf#157287.
126 * After applying a proper fix, remember to restore testDontExpandRefmark!
127 *SetDontExpand( true ); // like hyperlinks, reference markers shouldn't expand
128 *SetLockExpandFlag( true ); // protect the flag
132 SwTextRefMark::~SwTextRefMark()
134 if (!comphelper::LibreOfficeKit::isActive() || GetTextNode().GetDoc().IsClipBoard())
137 SfxViewShell
* pViewShell
= SfxViewShell::Current();
141 OUString fieldCommand
= GetRefMark().GetRefName();
142 tools::JsonWriter aJson
;
143 aJson
.put("commandName", ".uno:DeleteField");
144 aJson
.put("success", true);
146 auto result
= aJson
.startNode("result");
147 aJson
.put("DeleteField", fieldCommand
);
150 pViewShell
->libreOfficeKitViewCallback(LOK_CALLBACK_UNO_COMMAND_RESULT
, aJson
.finishAndGetAsOString());
153 const sal_Int32
* SwTextRefMark::GetEnd() const
158 void SwTextRefMark::SetEnd(sal_Int32 n
)
162 m_pHints
->EndPosChanged();
165 void SwTextRefMark::UpdateFieldContent(SwDoc
* pDoc
, SwWrtShell
& rWrtSh
, OUString aContent
)
172 // Insert markers to remember where the paste positions are.
173 const SwTextNode
& rTextNode
= this->GetTextNode();
174 SwPaM
aMarkers(SwPosition(rTextNode
, *this->End()));
175 IDocumentContentOperations
& rIDCO
= pDoc
->getIDocumentContentOperations();
176 /* FIXME: see above re: expanding behavior
177 *this->SetLockExpandFlag(false);
178 *this->SetDontExpand(false);
180 if (rIDCO
.InsertString(aMarkers
, "XY"))
182 SwPaM
aPasteEnd(SwPosition(rTextNode
, *this->End()));
183 aPasteEnd
.Move(fnMoveBackward
, GoInContent
);
185 // Paste HTML content.
186 SwPaM
* pCursorPos
= rWrtSh
.GetCursor();
187 *pCursorPos
= aPasteEnd
;
188 SwTranslateHelper::PasteHTMLToPaM(rWrtSh
, pCursorPos
, aContent
.toUtf8(), true);
190 // Update the refmark to point to the new content.
191 sal_Int32 nOldStart
= this->GetStart();
192 sal_Int32 nNewStart
= *this->End();
193 // First grow it to include text till the end of the paste position.
194 this->SetEnd(aPasteEnd
.GetPoint()->GetContentIndex());
195 // Then shrink it to only start at the paste start: we know that the refmark was
196 // truncated to the paste start, as the refmark has to stay inside a single text node
197 this->SetStart(nNewStart
);
198 rTextNode
.GetSwpHints().SortIfNeedBe();
199 SwPaM
aEndMarker(*aPasteEnd
.GetPoint());
200 aEndMarker
.SetMark();
201 aEndMarker
.GetMark()->AdjustContent(1);
202 SwPaM
aStartMarker(SwPosition(rTextNode
, nOldStart
), SwPosition(rTextNode
, nNewStart
));
204 // Remove markers. The start marker includes the old content as well.
205 rIDCO
.DeleteAndJoin(aStartMarker
);
206 rIDCO
.DeleteAndJoin(aEndMarker
);
209 /* FIXME: see above re: expanding behavior
210 *this->SetDontExpand(true);
211 *this->SetLockExpandFlag(true);
216 void SwTextRefMark::dumpAsXml(xmlTextWriterPtr pWriter
) const
218 (void)xmlTextWriterStartElement(pWriter
, BAD_CAST("SwTextRefMark"));
219 (void)xmlTextWriterWriteFormatAttribute(pWriter
, BAD_CAST("ptr"), "%p", this);
220 SwTextAttr::dumpAsXml(pWriter
);
222 (void)xmlTextWriterEndElement(pWriter
);
225 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */