merge the formfield patch from ooo-build
[ooovba.git] / sc / source / ui / docshell / servobj.cxx
blobb87a862c102d9dc3a04c87e42561dfee31917fe1
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: servobj.cxx,v $
10 * $Revision: 1.11.10.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"
33 // System - Includes -----------------------------------------------------
37 #include <sot/formats.hxx>
38 #include <sfx2/app.hxx>
39 #include <svx/linkmgr.hxx>
40 #include "servobj.hxx"
41 #include "docsh.hxx"
42 #include "impex.hxx"
43 #include "brdcst.hxx"
44 #include "rangenam.hxx"
45 #include "sc.hrc" // SC_HINT_AREAS_CHANGED
47 // -----------------------------------------------------------------------
49 BOOL lcl_FillRangeFromName( ScRange& rRange, ScDocShell* pDocSh, const String& rName )
51 if (pDocSh)
53 ScDocument* pDoc = pDocSh->GetDocument();
54 ScRangeName* pNames = pDoc->GetRangeName();
55 if (pNames)
57 USHORT nPos;
58 if( pNames->SearchName( rName, nPos ) )
60 ScRangeData* pData = (*pNames)[ nPos ];
61 if ( pData->IsValidReference( rRange ) )
62 return TRUE;
66 return FALSE;
69 ScServerObjectSvtListenerForwarder::ScServerObjectSvtListenerForwarder(
70 ScServerObject* pObjP)
71 : pObj(pObjP)
75 ScServerObjectSvtListenerForwarder::~ScServerObjectSvtListenerForwarder()
77 //! do NOT access pObj
80 void ScServerObjectSvtListenerForwarder::Notify( SvtBroadcaster& /* rBC */, const SfxHint& rHint)
82 pObj->Notify( aBroadcaster, rHint);
85 ScServerObject::ScServerObject( ScDocShell* pShell, const String& rItem ) :
86 aForwarder( this ),
87 pDocSh( pShell ),
88 bRefreshListener( FALSE )
90 // parse item string
92 if ( lcl_FillRangeFromName( aRange, pDocSh, rItem ) )
94 aItemStr = rItem; // must be parsed again on ref update
96 else
98 // parse ref
99 ScDocument* pDoc = pDocSh->GetDocument();
100 SCTAB nTab = pDocSh->GetCurTab();
101 aRange.aStart.SetTab( nTab );
103 if ( aRange.Parse( rItem, pDoc ) & SCA_VALID )
105 // area reference
107 else if ( aRange.aStart.Parse( rItem, pDoc, pDoc->GetAddressConvention() ) & SCA_VALID )
109 // cell reference
110 aRange.aEnd = aRange.aStart;
112 else
114 DBG_ERROR("ScServerObject: invalid item");
118 pDocSh->GetDocument()->GetLinkManager()->InsertServer( this );
119 pDocSh->GetDocument()->StartListeningArea( aRange, &aForwarder );
121 StartListening(*pDocSh); // um mitzubekommen, wenn die DocShell geloescht wird
122 StartListening(*SFX_APP()); // for SC_HINT_AREAS_CHANGED
125 __EXPORT ScServerObject::~ScServerObject()
127 Clear();
130 void ScServerObject::Clear()
132 if (pDocSh)
134 ScDocShell* pTemp = pDocSh;
135 pDocSh = NULL;
137 pTemp->GetDocument()->EndListeningArea( aRange, &aForwarder );
138 pTemp->GetDocument()->GetLinkManager()->RemoveServer( this );
139 EndListening(*pTemp);
140 EndListening(*SFX_APP());
144 void ScServerObject::EndListeningAll()
146 aForwarder.EndListeningAll();
147 SfxListener::EndListeningAll();
150 BOOL __EXPORT ScServerObject::GetData(
151 ::com::sun::star::uno::Any & rData /*out param*/,
152 const String & rMimeType, BOOL /* bSynchron */ )
154 if (!pDocSh)
155 return FALSE;
157 // named ranges may have changed -> update aRange
158 if ( aItemStr.Len() )
160 ScRange aNew;
161 if ( lcl_FillRangeFromName( aNew, pDocSh, aItemStr ) && aNew != aRange )
163 aRange = aNew;
164 bRefreshListener = TRUE;
168 if ( bRefreshListener )
170 // refresh the listeners now (this is called from a timer)
172 EndListeningAll();
173 pDocSh->GetDocument()->StartListeningArea( aRange, &aForwarder );
174 StartListening(*pDocSh);
175 StartListening(*SFX_APP());
176 bRefreshListener = FALSE;
179 String aDdeTextFmt = pDocSh->GetDdeTextFmt();
180 ScDocument* pDoc = pDocSh->GetDocument();
182 if( FORMAT_STRING == SotExchange::GetFormatIdFromMimeType( rMimeType ))
184 ScImportExport aObj( pDoc, aRange );
185 if( aDdeTextFmt.GetChar(0) == 'F' )
186 aObj.SetFormulas( TRUE );
187 if( aDdeTextFmt.EqualsAscii( "SYLK" ) ||
188 aDdeTextFmt.EqualsAscii( "FSYLK" ) )
190 ByteString aByteData;
191 if( aObj.ExportByteString( aByteData, gsl_getSystemTextEncoding(), SOT_FORMATSTR_ID_SYLK ) )
193 rData <<= ::com::sun::star::uno::Sequence< sal_Int8 >(
194 (sal_Int8*)aByteData.GetBuffer(),
195 aByteData.Len() + 1 );
196 return 1;
198 return 0;
200 if( aDdeTextFmt.EqualsAscii( "CSV" ) ||
201 aDdeTextFmt.EqualsAscii( "FCSV" ) )
202 aObj.SetSeparator( ',' );
203 aObj.SetExportTextOptions( ScExportTextOptions( ScExportTextOptions::ToSpace, ' ', false ) );
204 return aObj.ExportData( rMimeType, rData ) ? 1 : 0;
207 ScImportExport aObj( pDoc, aRange );
208 aObj.SetExportTextOptions( ScExportTextOptions( ScExportTextOptions::ToSpace, ' ', false ) );
209 if( aObj.IsRef() )
210 return aObj.ExportData( rMimeType, rData ) ? 1 : 0;
211 return 0;
214 void __EXPORT ScServerObject::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
216 BOOL bDataChanged = FALSE;
218 // DocShell can't be tested via type info, because SFX_HINT_DYING comes from the dtor
219 if ( &rBC == pDocSh )
221 // from DocShell, only SFX_HINT_DYING is interesting
222 if ( rHint.ISA(SfxSimpleHint) && ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
224 pDocSh = NULL;
225 EndListening(*SFX_APP());
226 // don't access DocShell anymore for EndListening etc.
229 else if (rBC.ISA(SfxApplication))
231 if ( aItemStr.Len() && rHint.ISA(SfxSimpleHint) &&
232 ((const SfxSimpleHint&)rHint).GetId() == SC_HINT_AREAS_CHANGED )
234 // check if named range was modified
235 ScRange aNew;
236 if ( lcl_FillRangeFromName( aNew, pDocSh, aItemStr ) && aNew != aRange )
237 bDataChanged = TRUE;
240 else
242 // must be from Area broadcasters
244 const ScHint* pScHint = PTR_CAST( ScHint, &rHint );
245 if( pScHint && (pScHint->GetId() & (SC_HINT_DATACHANGED | SC_HINT_DYING)) )
246 bDataChanged = TRUE;
247 else if (rHint.ISA(ScAreaChangedHint)) // position of broadcaster changed
249 ScRange aNewRange = ((const ScAreaChangedHint&)rHint).GetRange();
250 if ( aRange != aNewRange )
252 bRefreshListener = TRUE;
253 bDataChanged = TRUE;
256 else if (rHint.ISA(SfxSimpleHint))
258 ULONG nId = ((const SfxSimpleHint&)rHint).GetId();
259 if (nId == SFX_HINT_DYING)
261 // If the range is being deleted, listening must be restarted
262 // after the deletion is complete (done in GetData)
263 bRefreshListener = TRUE;
264 bDataChanged = TRUE;
269 if ( bDataChanged && HasDataLinks() )
270 SvLinkSource::NotifyDataChanged();