LibreOffice Module sc (master) 1
ddelink.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
21#include <comphelper/string.hxx>
22#include <osl/thread.h>
23#include <sot/exchange.hxx>
24#include <sfx2/linkmgr.hxx>
25#include <sfx2/bindings.hxx>
26#include <svl/numformat.hxx>
28#include <o3tl/string_view.hxx>
29
30#include <ddelink.hxx>
31#include <brdcst.hxx>
32#include <document.hxx>
33#include <scmatrix.hxx>
34#include <patattr.hxx>
35#include <rechead.hxx>
36#include <rangeseq.hxx>
37#include <sc.hrc>
38#include <hints.hxx>
39#include <utility>
40
41
42bool ScDdeLink::bIsInUpdate = false;
43
44ScDdeLink::ScDdeLink( ScDocument& rD, OUString aA, OUString aT, OUString aI,
45 sal_uInt8 nM ) :
47 rDoc( rD ),
48 aAppl(std::move( aA )),
49 aTopic(std::move( aT )),
50 aItem(std::move( aI )),
51 nMode( nM ),
52 bNeedUpdate( false ),
53 pResult( nullptr )
54{
55}
56
58{
59 // cancel connection
60
61 // pResult is refcounted
62}
63
66 rDoc ( rD ),
67 aAppl ( rOther.aAppl ),
68 aTopic ( rOther.aTopic ),
69 aItem ( rOther.aItem ),
70 nMode ( rOther.nMode ),
71 bNeedUpdate( false ),
72 pResult ( nullptr )
73{
74 if (rOther.pResult)
75 pResult = rOther.pResult->Clone();
76}
77
80 rDoc( rD ),
81 bNeedUpdate( false ),
82 pResult( nullptr )
83{
84 rHdr.StartEntry();
85
86 rtl_TextEncoding eCharSet = rStream.GetStreamCharSet();
87 aAppl = rStream.ReadUniOrByteString( eCharSet );
88 aTopic = rStream.ReadUniOrByteString( eCharSet );
89 aItem = rStream.ReadUniOrByteString( eCharSet );
90
91 bool bHasValue;
92 rStream.ReadCharAsBool( bHasValue );
93 if ( bHasValue )
94 pResult = new ScMatrix(0, 0);
95
96 if (rHdr.BytesLeft()) // new in 388b and the 364w (RealTime Client) version
97 rStream.ReadUChar( nMode );
98 else
100
101 rHdr.EndEntry();
102}
103
105{
106 rHdr.StartEntry();
107
108 rtl_TextEncoding eCharSet = rStream.GetStreamCharSet();
109 rStream.WriteUniOrByteString( aAppl, eCharSet );
110 rStream.WriteUniOrByteString( aTopic, eCharSet );
111 rStream.WriteUniOrByteString( aItem, eCharSet );
112
113 bool bHasValue = ( pResult != nullptr );
114 rStream.WriteBool( bHasValue );
115
116 if( rStream.GetVersion() > SOFFICE_FILEFORMAT_40 ) // not with 4.0 Export
117 rStream.WriteUChar( nMode ); // since 388b
118
119 // links with Mode != SC_DDE_DEFAULT are completely omitted in 4.0 Export
120 // (from ScDocument::SaveDdeLinks)
121
122 rHdr.EndEntry();
123}
124
126 const OUString& rMimeType, const css::uno::Any & rValue )
127{
128 // we only master strings...
129 if ( SotClipboardFormatId::STRING != SotExchange::GetFormatIdFromMimeType( rMimeType ))
130 return SUCCESS;
131
132 OUString aLinkStr;
133 ScByteSequenceToString::GetString( aLinkStr, rValue );
134 aLinkStr = convertLineEnd(aLinkStr, LINEEND_LF);
135
136 // if string ends with line end, discard:
137
138 sal_Int32 nLen = aLinkStr.getLength();
139 if (nLen && aLinkStr[nLen-1] == '\n')
140 aLinkStr = aLinkStr.copy(0, nLen-1);
141
142 SCSIZE nCols = 1; // empty string -> an empty line
143 SCSIZE nRows = 1;
144 if (!aLinkStr.isEmpty())
145 {
146 nRows = static_cast<SCSIZE>(comphelper::string::getTokenCount(aLinkStr, '\n'));
147 std::u16string_view aLine = o3tl::getToken(aLinkStr, 0, '\n' );
148 if (!aLine.empty())
149 nCols = static_cast<SCSIZE>(comphelper::string::getTokenCount(aLine, '\t'));
150 }
151
152 if (!nRows || !nCols) // no data
153 {
154 pResult.reset();
155 }
156 else // split data
157 {
158 // always newly re-create matrix, so that bIsString doesn't get mixed up
159 pResult = new ScMatrix(nCols, nRows, 0.0);
160
161 SvNumberFormatter* pFormatter = rDoc.GetFormatTable();
163
164 // nMode determines how the text is interpreted (#44455#/#49783#):
165 // SC_DDE_DEFAULT - number format from cell template "Standard"
166 // SC_DDE_ENGLISH - standard number format for English/US
167 // SC_DDE_TEXT - without NumberFormatter directly as string
168 sal_uLong nStdFormat = 0;
169 if ( nMode == SC_DDE_DEFAULT )
170 {
171 ScPatternAttr* pDefPattern = rDoc.GetDefPattern(); // contains standard template
172 if ( pDefPattern )
173 nStdFormat = pDefPattern->GetNumberFormat( pFormatter );
174 }
175 else if ( nMode == SC_DDE_ENGLISH )
176 nStdFormat = pFormatter->GetStandardIndex(LANGUAGE_ENGLISH_US);
177
178 for (SCSIZE nR=0; nR<nRows; nR++)
179 {
180 std::u16string_view aLine = o3tl::getToken(aLinkStr, static_cast<sal_Int32>(nR), '\n' );
181 for (SCSIZE nC=0; nC<nCols; nC++)
182 {
183 OUString aEntry( o3tl::getToken(aLine, static_cast<sal_Int32>(nC), '\t' ) );
184 sal_uInt32 nIndex = nStdFormat;
185 double fVal = double();
186 if ( nMode != SC_DDE_TEXT && pFormatter->IsNumberFormat( aEntry, nIndex, fVal ) )
187 pResult->PutDouble( fVal, nC, nR );
188 else if (aEntry.isEmpty())
189 // empty cell
190 pResult->PutEmpty(nC, nR);
191 else
192 pResult->PutString(rPool.intern(aEntry), nC, nR);
193 }
194 }
195 }
196
197 // Something happened...
198
199 if (HasListeners())
200 {
201 Broadcast(ScHint(SfxHintId::ScDataChanged, ScAddress()));
202 rDoc.TrackFormulas(); // must happen immediately
204
205 // StartTrackTimer asynchronously calls TrackFormulas, Broadcast(FID_DATACHANGED),
206 // ResetChanged, SetModified and Invalidate(SID_SAVEDOC/SID_DOC_MODIFIED)
207 // TrackFormulas additionally once again immediately, so that, e.g., a formula still
208 // located in the FormulaTrack doesn't get calculated by IdleCalc (#61676#)
209
210 // notify Uno objects (for XRefreshListener)
211 // must be after TrackFormulas
212 //TODO: do this asynchronously?
214 aHint.SetDdeLink( aAppl, aTopic, aItem );
215 rDoc.BroadcastUno( aHint );
216 }
217
218 return SUCCESS;
219}
220
222{
223 bool bWas = bIsInUpdate;
224 bIsInUpdate = true; // Remove() can trigger reschedule??!?
225
226 ScDocument& rStackDoc = rDoc; // member rDoc can't be used after removing the link
227
229 pLinkMgr->Remove( this); // deletes this
230
231 if ( pLinkMgr->GetLinks().empty() ) // deleted the last one ?
232 {
233 SfxBindings* pBindings = rStackDoc.GetViewBindings(); // don't use member rDoc!
234 if (pBindings)
235 pBindings->Invalidate( SID_LINKS );
236 }
237
238 bIsInUpdate = bWas;
239}
240
242{
243 return pResult.get();
244}
245
247{
248 pResult = pRes;
249}
250
252{
253 if (bIsInUpdate)
254 bNeedUpdate = true; // cannot be executed now
255 else
256 {
257 bIsInUpdate = true;
259 Update();
261 bIsInUpdate = false;
262 bNeedUpdate = false;
263 }
264}
265
266/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
size_t SCSIZE
size_t typedef to be able to find places where code was changed from USHORT to size_t and is used to ...
Definition: address.hxx:44
static bool GetString(OUString &rString, const css::uno::Any &rAny)
Definition: rangeseq.cxx:433
void TrackFormulas(SfxHintId nHintId=SfxHintId::ScDataChanged)
Definition: documen7.cxx:524
SC_DLLPUBLIC ScPatternAttr * GetDefPattern() const
Definition: document.cxx:6045
void IncInDdeLinkUpdate()
Definition: document.hxx:1043
SfxBindings * GetViewBindings()
Definition: documen8.cxx:1183
void StartTrackTimer()
Definition: documen2.cxx:332
SC_DLLPUBLIC svl::SharedStringPool & GetSharedStringPool()
Definition: documen2.cxx:601
SC_DLLPUBLIC SvNumberFormatter * GetFormatTable() const
Definition: documen2.cxx:467
SC_DLLPUBLIC sfx2::LinkManager * GetLinkManager()
Definition: documen2.cxx:231
void DecInDdeLinkUpdate()
Definition: document.hxx:1044
void BroadcastUno(const SfxHint &rHint)
Definition: documen3.cxx:952
void SetDdeLink(const OUString &rA, const OUString &rT, const OUString &rI)
Definition: hints.cxx:68
Matrix data type that can store values of mixed types.
Definition: scmatrix.hxx:101
sal_uInt64 BytesLeft() const
Definition: rechead.cxx:97
sal_uInt32 GetNumberFormat(SvNumberFormatter *) const
Definition: patattr.cxx:1398
void Invalidate(sal_uInt16 nId)
static SotClipboardFormatId GetFormatIdFromMimeType(std::u16string_view rMimeType)
sal_uInt32 GetStandardIndex(LanguageType eLnge=LANGUAGE_DONTKNOW)
bool IsNumberFormat(const OUString &sString, sal_uInt32 &F_Index, double &fOutNumber, SvNumInputOptions eInputOptions=SvNumInputOptions::NONE)
SvStream & ReadCharAsBool(bool &rBool)
SvStream & WriteUniOrByteString(std::u16string_view rStr, rtl_TextEncoding eDestCharSet)
OUString ReadUniOrByteString(rtl_TextEncoding eSrcCharSet)
SvStream & WriteBool(bool b)
SvStream & WriteUChar(unsigned char nChar)
sal_Int32 GetVersion() const
rtl_TextEncoding GetStreamCharSet() const
SvStream & ReadUChar(unsigned char &rChar)
bool HasListeners() const
void Broadcast(const SfxHint &rHint)
void Remove(SvBaseLink const *pLink)
const SvBaseLinks & GetLinks() const
SharedString intern(const OUString &rStr)
const sal_uInt8 SC_DDE_TEXT
Definition: document.hxx:303
const sal_uInt8 SC_DDE_DEFAULT
Definition: document.hxx:301
const sal_uInt8 SC_DDE_ENGLISH
Definition: document.hxx:302
#define SOFFICE_FILEFORMAT_40
SotClipboardFormatId
STRING
sal_Int32 nIndex
#define LANGUAGE_ENGLISH_US
LINEEND_LF
TOOLS_DLLPUBLIC OString convertLineEnd(const OString &rIn, LineEnd eLineEnd)
SfxLinkUpdateMode
sal_Int32 getTokenCount(std::string_view rIn, char cTok)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
sal_uIntPtr sal_uLong
unsigned char sal_uInt8
::boost::intrusive_ptr< ScMatrix > ScMatrixRef
Definition: types.hxx:25