update dev300-m57
[ooovba.git] / sc / source / core / tool / ddelink.cxx
blob67bd6a884b74fbb5659c24c3b429ddeab313486a
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ddelink.cxx,v $
10 * $Revision: 1.16.32.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 // INCLUDE ---------------------------------------------------------------
37 #include <tools/list.hxx>
38 #include <svx/linkmgr.hxx>
39 #include <sfx2/bindings.hxx>
40 #include <svtools/zforlist.hxx>
42 #include "ddelink.hxx"
43 #include "brdcst.hxx"
44 #include "document.hxx"
45 #include "scmatrix.hxx"
46 #include "patattr.hxx"
47 #include "rechead.hxx"
48 #include "rangeseq.hxx"
49 #include "sc.hrc"
50 #include "hints.hxx"
52 TYPEINIT2(ScDdeLink,::sfx2::SvBaseLink,SfxBroadcaster);
54 #define DDE_TXT_ENCODING gsl_getSystemTextEncoding()
56 BOOL ScDdeLink::bIsInUpdate = FALSE;
58 //------------------------------------------------------------------------
60 ScDdeLink::ScDdeLink( ScDocument* pD, const String& rA, const String& rT, const String& rI,
61 BYTE nM ) :
62 ::sfx2::SvBaseLink(sfx2::LINKUPDATE_ALWAYS,FORMAT_STRING),
63 pDoc( pD ),
64 aAppl( rA ),
65 aTopic( rT ),
66 aItem( rI ),
67 nMode( nM ),
68 bNeedUpdate( FALSE ),
69 pResult( NULL )
73 __EXPORT ScDdeLink::~ScDdeLink()
75 // Verbindung aufheben
77 // pResult is refcounted
80 ScDdeLink::ScDdeLink( ScDocument* pD, const ScDdeLink& rOther ) :
81 ::sfx2::SvBaseLink(sfx2::LINKUPDATE_ALWAYS,FORMAT_STRING),
82 pDoc ( pD ),
83 aAppl ( rOther.aAppl ),
84 aTopic ( rOther.aTopic ),
85 aItem ( rOther.aItem ),
86 nMode ( rOther.nMode ),
87 bNeedUpdate( FALSE ),
88 pResult ( NULL )
90 if (rOther.pResult)
91 pResult = rOther.pResult->Clone();
94 ScDdeLink::ScDdeLink( ScDocument* pD, SvStream& rStream, ScMultipleReadHeader& rHdr ) :
95 ::sfx2::SvBaseLink(sfx2::LINKUPDATE_ALWAYS,FORMAT_STRING),
96 pDoc( pD ),
97 bNeedUpdate( FALSE ),
98 pResult( NULL )
100 rHdr.StartEntry();
102 rtl_TextEncoding eCharSet = rStream.GetStreamCharSet();
103 rStream.ReadByteString( aAppl, eCharSet );
104 rStream.ReadByteString( aTopic, eCharSet );
105 rStream.ReadByteString( aItem, eCharSet );
107 BOOL bHasValue;
108 rStream >> bHasValue;
109 if ( bHasValue )
110 pResult = new ScMatrix( rStream );
112 if (rHdr.BytesLeft()) // neu in 388b und der 364w (RealTime-Client) Version
113 rStream >> nMode;
114 else
115 nMode = SC_DDE_DEFAULT;
117 rHdr.EndEntry();
120 void ScDdeLink::Store( SvStream& rStream, ScMultipleWriteHeader& rHdr ) const
122 rHdr.StartEntry();
124 rtl_TextEncoding eCharSet = rStream.GetStreamCharSet();
125 rStream.WriteByteString( aAppl, eCharSet );
126 rStream.WriteByteString( aTopic, eCharSet );
127 rStream.WriteByteString( aItem, eCharSet );
129 BOOL bHasValue = ( pResult != NULL );
130 rStream << bHasValue;
131 if (bHasValue)
132 pResult->Store( rStream );
134 if( rStream.GetVersion() > SOFFICE_FILEFORMAT_40 ) // nicht bei 4.0 Export
135 rStream << nMode; // seit 388b
137 // Links mit Mode != SC_DDE_DEFAULT werden bei 4.0 Export komplett weggelassen
138 // (aus ScDocument::SaveDdeLinks)
140 rHdr.EndEntry();
143 void __EXPORT ScDdeLink::DataChanged( const String& rMimeType,
144 const ::com::sun::star::uno::Any & rValue )
146 // wir koennen nur Strings...
147 if ( FORMAT_STRING != SotExchange::GetFormatIdFromMimeType( rMimeType ))
148 return;
150 String aLinkStr;
151 ScByteSequenceToString::GetString( aLinkStr, rValue, DDE_TXT_ENCODING );
152 aLinkStr.ConvertLineEnd(LINEEND_LF);
154 // wenn String mit Zeilenende aufhoert, streichen:
156 xub_StrLen nLen = aLinkStr.Len();
157 if (nLen && aLinkStr.GetChar(nLen-1) == '\n')
158 aLinkStr.Erase(nLen-1);
160 String aLine;
161 SCSIZE nCols = 1; // Leerstring -> eine leere Zelle
162 SCSIZE nRows = 1;
163 if (aLinkStr.Len())
165 nRows = static_cast<SCSIZE>(aLinkStr.GetTokenCount( '\n' ));
166 aLine = aLinkStr.GetToken( 0, '\n' );
167 if (aLine.Len())
168 nCols = static_cast<SCSIZE>(aLine.GetTokenCount( '\t' ));
171 if (!nRows || !nCols) // keine Daten
173 pResult.Clear();
175 else // Daten aufteilen
177 // Matrix immer neu anlegen, damit bIsString nicht durcheinanderkommt
178 pResult = new ScMatrix( nCols, nRows );
180 SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
182 // nMode bestimmt, wie der Text interpretiert wird (#44455#/#49783#):
183 // SC_DDE_DEFAULT - Zahlformat aus Zellvorlage "Standard"
184 // SC_DDE_ENGLISH - Standard-Zahlformat fuer English/US
185 // SC_DDE_TEXT - ohne NumberFormatter direkt als String
186 ULONG nStdFormat = 0;
187 if ( nMode == SC_DDE_DEFAULT )
189 ScPatternAttr* pDefPattern = pDoc->GetDefPattern(); // enthaelt Standard-Vorlage
190 if ( pDefPattern )
191 nStdFormat = pDefPattern->GetNumberFormat( pFormatter );
193 else if ( nMode == SC_DDE_ENGLISH )
194 nStdFormat = pFormatter->GetStandardIndex(LANGUAGE_ENGLISH_US);
196 String aEntry;
197 for (SCSIZE nR=0; nR<nRows; nR++)
199 aLine = aLinkStr.GetToken( (xub_StrLen) nR, '\n' );
200 for (SCSIZE nC=0; nC<nCols; nC++)
202 aEntry = aLine.GetToken( (xub_StrLen) nC, '\t' );
203 sal_uInt32 nIndex = nStdFormat;
204 double fVal;
205 if ( nMode != SC_DDE_TEXT && pFormatter->IsNumberFormat( aEntry, nIndex, fVal ) )
206 pResult->PutDouble( fVal, nC, nR );
207 else
208 pResult->PutString( aEntry, nC, nR );
213 // Es hat sich was getan...
215 if (HasListeners())
217 Broadcast( ScHint( SC_HINT_DATACHANGED, ScAddress(), NULL ) );
218 pDoc->TrackFormulas(); // muss sofort passieren
219 pDoc->StartTrackTimer();
221 // StartTrackTimer ruft asynchron TrackFormulas, Broadcast(FID_DATACHANGED),
222 // ResetChanged, SetModified und Invalidate(SID_SAVEDOC/SID_DOC_MODIFIED)
223 // TrackFormulas zusaetzlich nochmal sofort, damit nicht z.B. durch IdleCalc
224 // eine Formel berechnet wird, die noch im FormulaTrack steht (#61676#)
226 // notify Uno objects (for XRefreshListener)
227 // must be after TrackFormulas
228 //! do this asynchronously?
229 ScLinkRefreshedHint aHint;
230 aHint.SetDdeLink( aAppl, aTopic, aItem, nMode );
231 pDoc->BroadcastUno( aHint );
235 void ScDdeLink::ResetValue()
237 pResult.Clear();
239 // Es hat sich was getan...
240 // Tracking, FID_DATACHANGED etc. passiert von aussen
242 if (HasListeners())
243 Broadcast( ScHint( SC_HINT_DATACHANGED, ScAddress(), NULL ) );
246 void __EXPORT ScDdeLink::ListenersGone()
248 BOOL bWas = bIsInUpdate;
249 bIsInUpdate = TRUE; // Remove() kann Reschedule ausloesen??!?
251 ScDocument* pStackDoc = pDoc; // member pDoc can't be used after removing the link
253 SvxLinkManager* pLinkMgr = pDoc->GetLinkManager();
254 pLinkMgr->Remove( this); // deletes this
256 if ( !pLinkMgr->GetLinks().Count() ) // letzten geloescht ?
258 SfxBindings* pBindings = pStackDoc->GetViewBindings(); // don't use member pDoc!
259 if (pBindings)
260 pBindings->Invalidate( SID_LINKS );
263 bIsInUpdate = bWas;
266 void ScDdeLink::TryUpdate()
268 if (bIsInUpdate)
269 bNeedUpdate = TRUE; // kann jetzt nicht ausgefuehrt werden
270 else
272 bIsInUpdate = TRUE;
273 //Application::Reschedule(); //! OS/2-Simulation
274 pDoc->IncInDdeLinkUpdate();
275 Update();
276 pDoc->DecInDdeLinkUpdate();
277 bIsInUpdate = FALSE;
278 bNeedUpdate = FALSE;