fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / core / tool / ddelink.cxx
blobbf7770cd7680092a5dfa3d4b1a60ee4d94d61f4b
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 <comphelper/string.hxx>
21 #include <osl/thread.h>
22 #include <sfx2/linkmgr.hxx>
23 #include <sfx2/bindings.hxx>
24 #include <svl/zforlist.hxx>
25 #include <svl/sharedstringpool.hxx>
27 #include "ddelink.hxx"
28 #include "brdcst.hxx"
29 #include "document.hxx"
30 #include "scmatrix.hxx"
31 #include "patattr.hxx"
32 #include "rechead.hxx"
33 #include "rangeseq.hxx"
34 #include "sc.hrc"
35 #include "hints.hxx"
37 TYPEINIT2(ScDdeLink,::sfx2::SvBaseLink,SfxBroadcaster);
39 #define DDE_TXT_ENCODING osl_getThreadTextEncoding()
41 bool ScDdeLink::bIsInUpdate = false;
43 ScDdeLink::ScDdeLink( ScDocument* pD, const OUString& rA, const OUString& rT, const OUString& rI,
44 sal_uInt8 nM ) :
45 ::sfx2::SvBaseLink(SfxLinkUpdateMode::ALWAYS,SotClipboardFormatId::STRING),
46 pDoc( pD ),
47 aAppl( rA ),
48 aTopic( rT ),
49 aItem( rI ),
50 nMode( nM ),
51 bNeedUpdate( false ),
52 pResult( NULL )
56 ScDdeLink::~ScDdeLink()
58 // Verbindung aufheben
60 // pResult is refcounted
63 ScDdeLink::ScDdeLink( ScDocument* pD, const ScDdeLink& rOther ) :
64 ::sfx2::SvBaseLink(SfxLinkUpdateMode::ALWAYS,SotClipboardFormatId::STRING),
65 pDoc ( pD ),
66 aAppl ( rOther.aAppl ),
67 aTopic ( rOther.aTopic ),
68 aItem ( rOther.aItem ),
69 nMode ( rOther.nMode ),
70 bNeedUpdate( false ),
71 pResult ( NULL )
73 if (rOther.pResult)
74 pResult = rOther.pResult->Clone();
77 ScDdeLink::ScDdeLink( ScDocument* pD, SvStream& rStream, ScMultipleReadHeader& rHdr ) :
78 ::sfx2::SvBaseLink(SfxLinkUpdateMode::ALWAYS,SotClipboardFormatId::STRING),
79 pDoc( pD ),
80 bNeedUpdate( false ),
81 pResult( NULL )
83 rHdr.StartEntry();
85 rtl_TextEncoding eCharSet = rStream.GetStreamCharSet();
86 aAppl = rStream.ReadUniOrByteString( eCharSet );
87 aTopic = rStream.ReadUniOrByteString( eCharSet );
88 aItem = rStream.ReadUniOrByteString( eCharSet );
90 bool bHasValue;
91 rStream.ReadCharAsBool( bHasValue );
92 if ( bHasValue )
93 pResult = new ScMatrix(0, 0);
95 if (rHdr.BytesLeft()) // neu in 388b und der 364w (RealTime-Client) Version
96 rStream.ReadUChar( nMode );
97 else
98 nMode = SC_DDE_DEFAULT;
100 rHdr.EndEntry();
103 void ScDdeLink::Store( SvStream& rStream, ScMultipleWriteHeader& rHdr ) const
105 rHdr.StartEntry();
107 rtl_TextEncoding eCharSet = rStream.GetStreamCharSet();
108 rStream.WriteUniOrByteString( aAppl, eCharSet );
109 rStream.WriteUniOrByteString( aTopic, eCharSet );
110 rStream.WriteUniOrByteString( aItem, eCharSet );
112 bool bHasValue = ( pResult != 0 );
113 rStream.WriteBool( bHasValue );
115 if( rStream.GetVersion() > SOFFICE_FILEFORMAT_40 ) // nicht bei 4.0 Export
116 rStream.WriteUChar( nMode ); // seit 388b
118 // Links mit Mode != SC_DDE_DEFAULT werden bei 4.0 Export komplett weggelassen
119 // (aus ScDocument::SaveDdeLinks)
121 rHdr.EndEntry();
124 sfx2::SvBaseLink::UpdateResult ScDdeLink::DataChanged(
125 const OUString& rMimeType, const ::com::sun::star::uno::Any & rValue )
127 // wir koennen nur Strings...
128 if ( SotClipboardFormatId::STRING != SotExchange::GetFormatIdFromMimeType( rMimeType ))
129 return SUCCESS;
131 OUString aLinkStr;
132 ScByteSequenceToString::GetString( aLinkStr, rValue, DDE_TXT_ENCODING );
133 aLinkStr = convertLineEnd(aLinkStr, LINEEND_LF);
135 // wenn String mit Zeilenende aufhoert, streichen:
137 sal_Int32 nLen = aLinkStr.getLength();
138 if (nLen && aLinkStr[nLen-1] == '\n')
139 aLinkStr = aLinkStr.copy(0, nLen-1);
141 OUString aLine;
142 SCSIZE nCols = 1; // Leerstring -> eine leere Zelle
143 SCSIZE nRows = 1;
144 if (!aLinkStr.isEmpty())
146 nRows = static_cast<SCSIZE>(comphelper::string::getTokenCount(aLinkStr, '\n'));
147 aLine = aLinkStr.getToken( 0, '\n' );
148 if (!aLine.isEmpty())
149 nCols = static_cast<SCSIZE>(comphelper::string::getTokenCount(aLine, '\t'));
152 if (!nRows || !nCols) // keine Daten
154 pResult.reset();
156 else // Daten aufteilen
158 // Matrix immer neu anlegen, damit bIsString nicht durcheinanderkommt
159 pResult = new ScMatrix(nCols, nRows, 0.0);
161 SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
162 svl::SharedStringPool& rPool = pDoc->GetSharedStringPool();
164 // nMode bestimmt, wie der Text interpretiert wird (#44455#/#49783#):
165 // SC_DDE_DEFAULT - Zahlformat aus Zellvorlage "Standard"
166 // SC_DDE_ENGLISH - Standard-Zahlformat fuer English/US
167 // SC_DDE_TEXT - ohne NumberFormatter direkt als String
168 sal_uLong nStdFormat = 0;
169 if ( nMode == SC_DDE_DEFAULT )
171 ScPatternAttr* pDefPattern = pDoc->GetDefPattern(); // enthaelt Standard-Vorlage
172 if ( pDefPattern )
173 nStdFormat = pDefPattern->GetNumberFormat( pFormatter );
175 else if ( nMode == SC_DDE_ENGLISH )
176 nStdFormat = pFormatter->GetStandardIndex(LANGUAGE_ENGLISH_US);
178 OUString aEntry;
179 for (SCSIZE nR=0; nR<nRows; nR++)
181 aLine = aLinkStr.getToken( (sal_Int32) nR, '\n' );
182 for (SCSIZE nC=0; nC<nCols; nC++)
184 aEntry = aLine.getToken( (sal_Int32) nC, '\t' );
185 sal_uInt32 nIndex = nStdFormat;
186 double fVal = double();
187 if ( nMode != SC_DDE_TEXT && pFormatter->IsNumberFormat( aEntry, nIndex, fVal ) )
188 pResult->PutDouble( fVal, nC, nR );
189 else if (aEntry.isEmpty())
190 // empty cell
191 pResult->PutEmpty(nC, nR);
192 else
193 pResult->PutString(rPool.intern(aEntry), nC, nR);
198 // Es hat sich was getan...
200 if (HasListeners())
202 Broadcast(ScHint(SC_HINT_DATACHANGED, ScAddress()));
203 pDoc->TrackFormulas(); // muss sofort passieren
204 pDoc->StartTrackTimer();
206 // StartTrackTimer ruft asynchron TrackFormulas, Broadcast(FID_DATACHANGED),
207 // ResetChanged, SetModified und Invalidate(SID_SAVEDOC/SID_DOC_MODIFIED)
208 // TrackFormulas zusaetzlich nochmal sofort, damit nicht z.B. durch IdleCalc
209 // eine Formel berechnet wird, die noch im FormulaTrack steht (#61676#)
211 // notify Uno objects (for XRefreshListener)
212 // must be after TrackFormulas
213 //TODO: do this asynchronously?
214 ScLinkRefreshedHint aHint;
215 aHint.SetDdeLink( aAppl, aTopic, aItem, nMode );
216 pDoc->BroadcastUno( aHint );
219 return SUCCESS;
222 void ScDdeLink::ListenersGone()
224 bool bWas = bIsInUpdate;
225 bIsInUpdate = true; // Remove() kann Reschedule ausloesen??!?
227 ScDocument* pStackDoc = pDoc; // member pDoc can't be used after removing the link
229 sfx2::LinkManager* pLinkMgr = pDoc->GetLinkManager();
230 pLinkMgr->Remove( this); // deletes this
232 if ( pLinkMgr->GetLinks().empty() ) // letzten geloescht ?
234 SfxBindings* pBindings = pStackDoc->GetViewBindings(); // don't use member pDoc!
235 if (pBindings)
236 pBindings->Invalidate( SID_LINKS );
239 bIsInUpdate = bWas;
242 const ScMatrix* ScDdeLink::GetResult() const
244 return pResult.get();
247 void ScDdeLink::SetResult( const ScMatrixRef& pRes )
249 pResult = pRes;
252 void ScDdeLink::TryUpdate()
254 if (bIsInUpdate)
255 bNeedUpdate = true; // kann jetzt nicht ausgefuehrt werden
256 else
258 bIsInUpdate = true;
259 pDoc->IncInDdeLinkUpdate();
260 Update();
261 pDoc->DecInDdeLinkUpdate();
262 bIsInUpdate = false;
263 bNeedUpdate = false;
267 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */