Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / source / core / txtnode / atrref.cxx
blob40848bdaf51b5204292754e6a96df27880af0216
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
25 #include <hints.hxx>
26 #include <txtrfmrk.hxx>
27 #include <unorefmark.hxx>
28 #include <utility>
29 #include <sfx2/viewsh.hxx>
30 #include <tools/json_writer.hxx>
31 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
32 #include <comphelper/lok.hxx>
33 #include <doc.hxx>
34 #include <ndtxt.hxx>
35 #include <pam.hxx>
36 #include <translatehelper.hxx>
37 #include <wrtsh.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)
76 return;
77 auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
78 CallSwClientNotify(rHint);
79 if(RES_REMOVE_UNO_OBJECT == pLegacy->GetWhich())
80 SetXRefMark(nullptr);
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 )
110 , m_pEnd( nullptr )
112 rAttr.m_pTextAttr = this;
113 if ( pEnd )
115 m_nEnd = *pEnd;
116 m_pEnd = & m_nEnd;
118 else
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())
135 return;
137 SfxViewShell* pViewShell = SfxViewShell::Current();
138 if (!pViewShell)
139 return;
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
155 return m_pEnd;
158 void SwTextRefMark::SetEnd(sal_Int32 n)
160 *m_pEnd = n;
161 if (m_pHints)
162 m_pHints->EndPosChanged();
165 void SwTextRefMark::UpdateFieldContent(SwDoc* pDoc, SwWrtShell& rWrtSh, OUString aContent)
167 if (!this->End())
169 return;
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);
208 // Restore flags.
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: */