Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "xecontent.hxx"
30 : :
31 : : #include <list>
32 : : #include <algorithm>
33 : : #include <com/sun/star/container/XIndexAccess.hpp>
34 : : #include <com/sun/star/frame/XModel.hpp>
35 : : #include <com/sun/star/sheet/XAreaLinks.hpp>
36 : : #include <com/sun/star/sheet/XAreaLink.hpp>
37 : : #include <comphelper/string.hxx>
38 : : #include <sfx2/objsh.hxx>
39 : : #include <tools/urlobj.hxx>
40 : : #include <svl/itemset.hxx>
41 : : #include <formula/grammar.hxx>
42 : : #include "scitems.hxx"
43 : : #include <editeng/eeitem.hxx>
44 : : #include <editeng/flditem.hxx>
45 : : #include "document.hxx"
46 : : #include "validat.hxx"
47 : : #include "unonames.hxx"
48 : : #include "convuno.hxx"
49 : : #include "rangenam.hxx"
50 : : #include "tokenarray.hxx"
51 : : #include "stlpool.hxx"
52 : : #include "patattr.hxx"
53 : : #include "fapihelper.hxx"
54 : : #include "xehelper.hxx"
55 : : #include "xestyle.hxx"
56 : : #include "xename.hxx"
57 : :
58 : : using namespace ::oox;
59 : :
60 : : using ::com::sun::star::uno::Reference;
61 : : using ::com::sun::star::uno::Any;
62 : : using ::com::sun::star::uno::UNO_QUERY;
63 : : using ::com::sun::star::beans::XPropertySet;
64 : : using ::com::sun::star::container::XIndexAccess;
65 : : using ::com::sun::star::frame::XModel;
66 : : using ::com::sun::star::table::CellRangeAddress;
67 : : using ::com::sun::star::sheet::XAreaLinks;
68 : : using ::com::sun::star::sheet::XAreaLink;
69 : : using ::rtl::OString;
70 : : using ::rtl::OUString;
71 : : using ::rtl::OUStringBuffer;
72 : :
73 : : // Shared string table ========================================================
74 : :
75 : : /** A single string entry in the hash table. */
76 : : struct XclExpHashEntry
77 : : {
78 : : const XclExpString* mpString; /// Pointer to the string (no ownership).
79 : : sal_uInt32 mnSstIndex; /// The SST index of this string.
80 : 0 : inline explicit XclExpHashEntry( const XclExpString* pString = 0, sal_uInt32 nSstIndex = 0 ) :
81 : 0 : mpString( pString ), mnSstIndex( nSstIndex ) {}
82 : : };
83 : :
84 : : /** Function object for strict weak ordering. */
85 : : struct XclExpHashEntrySWO
86 : : {
87 : 0 : inline bool operator()( const XclExpHashEntry& rLeft, const XclExpHashEntry& rRight ) const
88 : 0 : { return *rLeft.mpString < *rRight.mpString; }
89 : : };
90 : :
91 : : // ----------------------------------------------------------------------------
92 : :
93 : : /** Implementation of the SST export.
94 : : @descr Stores all passed strings in a hash table and prevents repeated
95 : : insertion of equal strings. */
96 : 0 : class XclExpSstImpl
97 : : {
98 : : public:
99 : : explicit XclExpSstImpl();
100 : :
101 : : /** Inserts the passed string, if not already inserted, and returns the unique SST index. */
102 : : sal_uInt32 Insert( XclExpStringRef xString );
103 : :
104 : : /** Writes the complete SST and EXTSST records. */
105 : : void Save( XclExpStream& rStrm );
106 : : void SaveXml( XclExpXmlStream& rStrm );
107 : :
108 : : private:
109 : : typedef ::std::list< XclExpStringRef > XclExpStringList;
110 : : typedef ::std::vector< XclExpHashEntry > XclExpHashVec;
111 : : typedef ::std::vector< XclExpHashVec > XclExpHashTab;
112 : :
113 : : XclExpStringList maStringList; /// List of unique strings (in SST ID order).
114 : : XclExpHashTab maHashTab; /// Hashed table that manages string pointers.
115 : : sal_uInt32 mnTotal; /// Total count of strings (including doubles).
116 : : sal_uInt32 mnSize; /// Size of the SST (count of unique strings).
117 : : };
118 : :
119 : : // ----------------------------------------------------------------------------
120 : :
121 : : const sal_uInt32 EXC_SST_HASHTABLE_SIZE = 2048;
122 : :
123 : 0 : XclExpSstImpl::XclExpSstImpl() :
124 : : maHashTab( EXC_SST_HASHTABLE_SIZE ),
125 : : mnTotal( 0 ),
126 [ # # ]: 0 : mnSize( 0 )
127 : : {
128 : 0 : }
129 : :
130 : 0 : sal_uInt32 XclExpSstImpl::Insert( XclExpStringRef xString )
131 : : {
132 : : OSL_ENSURE( xString.get(), "XclExpSstImpl::Insert - empty pointer not allowed" );
133 [ # # ]: 0 : if( !xString.get() )
134 [ # # ][ # # ]: 0 : xString.reset( new XclExpString );
[ # # ]
135 : :
136 : 0 : ++mnTotal;
137 : 0 : sal_uInt32 nSstIndex = 0;
138 : :
139 : : // calculate hash value in range [0,EXC_SST_HASHTABLE_SIZE)
140 [ # # ]: 0 : sal_uInt16 nHash = xString->GetHash();
141 : 0 : (nHash ^= (nHash / EXC_SST_HASHTABLE_SIZE)) %= EXC_SST_HASHTABLE_SIZE;
142 : :
143 : 0 : XclExpHashVec& rVec = maHashTab[ nHash ];
144 : 0 : XclExpHashEntry aEntry( xString.get(), mnSize );
145 [ # # ]: 0 : XclExpHashVec::iterator aIt = ::std::lower_bound( rVec.begin(), rVec.end(), aEntry, XclExpHashEntrySWO() );
146 [ # # ][ # # ]: 0 : if( (aIt == rVec.end()) || (*aIt->mpString != *xString) )
[ # # ][ # # ]
[ # # ]
[ # # # # ]
147 : : {
148 : 0 : nSstIndex = mnSize;
149 [ # # ]: 0 : maStringList.push_back( xString );
150 [ # # ]: 0 : rVec.insert( aIt, aEntry );
151 : 0 : ++mnSize;
152 : : }
153 : : else
154 : : {
155 : 0 : nSstIndex = aIt->mnSstIndex;
156 : : }
157 : :
158 : 0 : return nSstIndex;
159 : : }
160 : :
161 : 0 : void XclExpSstImpl::Save( XclExpStream& rStrm )
162 : : {
163 [ # # ]: 0 : if( maStringList.empty() )
164 : 0 : return;
165 : :
166 [ # # ]: 0 : SvMemoryStream aExtSst( 8192 );
167 : :
168 : 0 : sal_uInt32 nBucket = mnSize;
169 [ # # ]: 0 : while( nBucket > 0x0100 )
170 : 0 : nBucket /= 2;
171 : :
172 [ # # ]: 0 : sal_uInt16 nPerBucket = llimit_cast< sal_uInt16 >( nBucket, 8 );
173 : 0 : sal_uInt16 nBucketIndex = 0;
174 : :
175 : : // *** write the SST record ***
176 : :
177 [ # # ]: 0 : rStrm.StartRecord( EXC_ID_SST, 8 );
178 : :
179 [ # # ][ # # ]: 0 : rStrm << mnTotal << mnSize;
180 [ # # ]: 0 : for( XclExpStringList::const_iterator aIt = maStringList.begin(), aEnd = maStringList.end(); aIt != aEnd; ++aIt )
181 : : {
182 [ # # ]: 0 : if( !nBucketIndex )
183 : : {
184 : : // write bucket info before string to get correct record position
185 : 0 : sal_uInt32 nStrmPos = static_cast< sal_uInt32 >( rStrm.GetSvStreamPos() );
186 : 0 : sal_uInt16 nRecPos = rStrm.GetRawRecPos() + 4;
187 [ # # ]: 0 : aExtSst << nStrmPos // stream position
188 [ # # ]: 0 : << nRecPos // position from start of SST or CONTINUE
189 [ # # ]: 0 : << sal_uInt16( 0 ); // reserved
190 : : }
191 : :
192 [ # # ]: 0 : rStrm << **aIt;
193 : :
194 [ # # ]: 0 : if( ++nBucketIndex == nPerBucket )
195 : 0 : nBucketIndex = 0;
196 : : }
197 : :
198 [ # # ]: 0 : rStrm.EndRecord();
199 : :
200 : : // *** write the EXTSST record ***
201 : :
202 [ # # ]: 0 : rStrm.StartRecord( EXC_ID_EXTSST, 0 );
203 : :
204 [ # # ]: 0 : rStrm << nPerBucket;
205 [ # # ]: 0 : rStrm.SetSliceSize( 8 ); // size of one bucket info
206 [ # # ]: 0 : aExtSst.Seek( STREAM_SEEK_TO_BEGIN );
207 [ # # ]: 0 : rStrm.CopyFromStream( aExtSst );
208 : :
209 [ # # ][ # # ]: 0 : rStrm.EndRecord();
210 : : }
211 : :
212 : 0 : void XclExpSstImpl::SaveXml( XclExpXmlStream& rStrm )
213 : : {
214 [ # # ]: 0 : if( maStringList.empty() )
215 : 0 : return;
216 : :
217 : : sax_fastparser::FSHelperPtr pSst = rStrm.CreateOutputStream(
218 : : OUString(RTL_CONSTASCII_USTRINGPARAM( "xl/sharedStrings.xml") ),
219 : : OUString(RTL_CONSTASCII_USTRINGPARAM( "sharedStrings.xml" )),
220 [ # # ]: 0 : rStrm.GetCurrentStream()->getOutputStream(),
221 : : "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml",
222 [ # # ][ # # ]: 0 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings" );
[ # # ][ # # ]
223 [ # # ][ # # ]: 0 : rStrm.PushStream( pSst );
[ # # ]
224 : :
225 : : pSst->startElement( XML_sst,
226 : : XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
227 : : XML_count, OString::valueOf( (sal_Int32) mnTotal ).getStr(),
228 : : XML_uniqueCount, OString::valueOf( (sal_Int32) mnSize ).getStr(),
229 [ # # ]: 0 : FSEND );
230 : :
231 [ # # ]: 0 : for( XclExpStringList::const_iterator aIt = maStringList.begin(), aEnd = maStringList.end(); aIt != aEnd; ++aIt )
232 : : {
233 [ # # ]: 0 : pSst->startElement( XML_si, FSEND );
234 [ # # ]: 0 : (*aIt)->WriteXml( rStrm );
235 [ # # ]: 0 : pSst->endElement( XML_si );
236 : : }
237 : :
238 [ # # ]: 0 : pSst->endElement( XML_sst );
239 : :
240 [ # # ][ # # ]: 0 : rStrm.PopStream();
241 : : }
242 : :
243 : : // ----------------------------------------------------------------------------
244 : :
245 : 0 : XclExpSst::XclExpSst() :
246 [ # # ][ # # ]: 0 : mxImpl( new XclExpSstImpl )
247 : : {
248 : 0 : }
249 : :
250 [ # # ]: 0 : XclExpSst::~XclExpSst()
251 : : {
252 [ # # ]: 0 : }
253 : :
254 : 0 : sal_uInt32 XclExpSst::Insert( XclExpStringRef xString )
255 : : {
256 [ # # ]: 0 : return mxImpl->Insert( xString );
257 : : }
258 : :
259 : 0 : void XclExpSst::Save( XclExpStream& rStrm )
260 : : {
261 : 0 : mxImpl->Save( rStrm );
262 : 0 : }
263 : :
264 : 0 : void XclExpSst::SaveXml( XclExpXmlStream& rStrm )
265 : : {
266 : 0 : mxImpl->SaveXml( rStrm );
267 : 0 : }
268 : :
269 : : // Merged cells ===============================================================
270 : :
271 : 0 : XclExpMergedcells::XclExpMergedcells( const XclExpRoot& rRoot ) :
272 [ # # ][ # # ]: 0 : XclExpRoot( rRoot )
[ # # ]
273 : : {
274 : 0 : }
275 : :
276 : 0 : void XclExpMergedcells::AppendRange( const ScRange& rRange, sal_uInt32 nBaseXFId )
277 : : {
278 [ # # ]: 0 : if( GetBiff() == EXC_BIFF8 )
279 : : {
280 : 0 : maMergedRanges.Append( rRange );
281 : 0 : maBaseXFIds.push_back( nBaseXFId );
282 : : }
283 : 0 : }
284 : :
285 : 0 : sal_uInt32 XclExpMergedcells::GetBaseXFId( const ScAddress& rPos ) const
286 : : {
287 : : OSL_ENSURE( maBaseXFIds.size() == maMergedRanges.size(), "XclExpMergedcells::GetBaseXFId - invalid lists" );
288 : 0 : ScfUInt32Vec::const_iterator aIt = maBaseXFIds.begin();
289 : 0 : ScRangeList& rNCRanges = const_cast< ScRangeList& >( maMergedRanges );
290 [ # # ][ # # ]: 0 : for ( size_t i = 0, nRanges = rNCRanges.size(); i < nRanges; ++i, ++aIt )
[ # # ]
291 : : {
292 [ # # ]: 0 : const ScRange* pScRange = rNCRanges[ i ];
293 [ # # ]: 0 : if( pScRange->In( rPos ) )
294 [ # # ]: 0 : return *aIt;
295 : : }
296 : 0 : return EXC_XFID_NOTFOUND;
297 : : }
298 : :
299 : 0 : void XclExpMergedcells::Save( XclExpStream& rStrm )
300 : : {
301 [ # # ]: 0 : if( GetBiff() == EXC_BIFF8 )
302 : : {
303 [ # # ]: 0 : XclRangeList aXclRanges;
304 [ # # ][ # # ]: 0 : GetAddressConverter().ConvertRangeList( aXclRanges, maMergedRanges, true );
305 : 0 : size_t nFirstRange = 0;
306 : 0 : size_t nRemainingRanges = aXclRanges.size();
307 [ # # ]: 0 : while( nRemainingRanges > 0 )
308 : : {
309 [ # # ]: 0 : size_t nRangeCount = ::std::min< size_t >( nRemainingRanges, EXC_MERGEDCELLS_MAXCOUNT );
310 [ # # ]: 0 : rStrm.StartRecord( EXC_ID_MERGEDCELLS, 2 + 8 * nRangeCount );
311 [ # # ]: 0 : aXclRanges.WriteSubList( rStrm, nFirstRange, nRangeCount );
312 [ # # ]: 0 : rStrm.EndRecord();
313 : 0 : nFirstRange += nRangeCount;
314 : 0 : nRemainingRanges -= nRangeCount;
315 : 0 : }
316 : : }
317 : 0 : }
318 : :
319 : 0 : void XclExpMergedcells::SaveXml( XclExpXmlStream& rStrm )
320 : : {
321 : 0 : size_t nCount = maMergedRanges.size();
322 [ # # ]: 0 : if( !nCount )
323 : 0 : return;
324 : 0 : sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
325 : : rWorksheet->startElement( XML_mergeCells,
326 : : XML_count, OString::valueOf( (sal_Int32) nCount ).getStr(),
327 [ # # ]: 0 : FSEND );
328 [ # # ]: 0 : for( size_t i = 0; i < nCount; ++i )
329 : : {
330 [ # # ]: 0 : if( const ScRange* pRange = maMergedRanges[ i ] )
331 : : {
332 : : rWorksheet->singleElement( XML_mergeCell,
333 : : XML_ref, XclXmlUtils::ToOString( *pRange ).getStr(),
334 [ # # ]: 0 : FSEND );
335 : : }
336 : : }
337 : 0 : rWorksheet->endElement( XML_mergeCells );
338 : : }
339 : :
340 : : // Hyperlinks =================================================================
341 : :
342 : 0 : XclExpHyperlink::XclExpHyperlink( const XclExpRoot& rRoot, const SvxURLField& rUrlField, const ScAddress& rScPos ) :
343 : : XclExpRecord( EXC_ID_HLINK ),
344 : : maScPos( rScPos ),
345 [ # # ]: 0 : mxVarData( new SvMemoryStream ),
346 [ # # ][ # # ]: 0 : mnFlags( 0 )
347 : : {
348 [ # # ]: 0 : const String& rUrl = rUrlField.GetURL();
349 [ # # ]: 0 : const String& rRepr = rUrlField.GetRepresentation();
350 [ # # ][ # # ]: 0 : INetURLObject aUrlObj( rUrl );
351 : 0 : const INetProtocol eProtocol = aUrlObj.GetProtocol();
352 : 0 : bool bWithRepr = rRepr.Len() > 0;
353 [ # # ]: 0 : XclExpStream aXclStrm( *mxVarData, rRoot ); // using in raw write mode.
354 : :
355 : : // description
356 [ # # ]: 0 : if( bWithRepr )
357 : : {
358 [ # # ]: 0 : XclExpString aDescr( rRepr, EXC_STR_FORCEUNICODE, 255 );
359 [ # # ]: 0 : aXclStrm << sal_uInt32( aDescr.Len() + 1 ); // string length + 1 trailing zero word
360 [ # # ]: 0 : aDescr.WriteBuffer( aXclStrm ); // NO flags
361 [ # # ]: 0 : aXclStrm << sal_uInt16( 0 );
362 : :
363 : 0 : mnFlags |= EXC_HLINK_DESCR;
364 [ # # ][ # # ]: 0 : mxRepr.reset( new String( rRepr ) );
[ # # ]
365 : : }
366 : :
367 : : // file link or URL
368 [ # # ][ # # ]: 0 : if( eProtocol == INET_PROT_FILE || eProtocol == INET_PROT_SMB )
369 : : {
370 : : sal_uInt16 nLevel;
371 : : bool bRel;
372 [ # # ]: 0 : String aFileName( BuildFileName( nLevel, bRel, rUrl, rRoot ) );
373 : :
374 [ # # ]: 0 : if( eProtocol == INET_PROT_SMB )
375 : : {
376 : : // #n382718# (and #n261623#) Convert smb notation to '\\'
377 [ # # ][ # # ]: 0 : aFileName = aUrlObj.GetMainURL( INetURLObject::NO_DECODE );
378 [ # # ]: 0 : aFileName = rtl::OUString( aFileName.GetBuffer() + 4 ); // skip the 'smb:' part
379 [ # # ]: 0 : aFileName.SearchAndReplaceAll( '/', '\\' );
380 : : }
381 : :
382 [ # # ]: 0 : if( !bRel )
383 : 0 : mnFlags |= EXC_HLINK_ABS;
384 : 0 : mnFlags |= EXC_HLINK_BODY;
385 : :
386 : : rtl::OString aAsciiLink(rtl::OUStringToOString(aFileName,
387 [ # # ][ # # ]: 0 : rRoot.GetTextEncoding()));
388 [ # # ]: 0 : XclExpString aLink( aFileName, EXC_STR_FORCEUNICODE, 255 );
389 [ # # ]: 0 : aXclStrm << XclTools::maGuidFileMoniker
390 [ # # ]: 0 : << nLevel
391 [ # # ]: 0 : << sal_uInt32( aAsciiLink.getLength() + 1 ); // string length + 1 trailing zero byte
392 [ # # ]: 0 : aXclStrm.Write( aAsciiLink.getStr(), aAsciiLink.getLength() );
393 [ # # ]: 0 : aXclStrm << sal_uInt8( 0 )
394 [ # # ]: 0 : << sal_uInt32( 0xDEADFFFF );
395 [ # # ]: 0 : aXclStrm.WriteZeroBytes( 20 );
396 [ # # ][ # # ]: 0 : aXclStrm << sal_uInt32( aLink.GetBufferSize() + 6 )
397 [ # # ][ # # ]: 0 : << sal_uInt32( aLink.GetBufferSize() ) // byte count, not string length
398 [ # # ]: 0 : << sal_uInt16( 0x0003 );
399 [ # # ]: 0 : aLink.WriteBuffer( aXclStrm ); // NO flags
400 : :
401 [ # # ]: 0 : if( !mxRepr.get() )
402 [ # # ][ # # ]: 0 : mxRepr.reset( new String( aFileName ) );
[ # # ]
403 : :
404 [ # # ][ # # ]: 0 : msTarget = XclXmlUtils::ToOUString( aLink );
405 : : }
406 [ # # ]: 0 : else if( eProtocol != INET_PROT_NOT_VALID )
407 : : {
408 [ # # ][ # # ]: 0 : XclExpString aUrl( aUrlObj.GetURLNoMark(), EXC_STR_FORCEUNICODE, 255 );
409 [ # # ]: 0 : aXclStrm << XclTools::maGuidUrlMoniker
410 [ # # ][ # # ]: 0 : << sal_uInt32( aUrl.GetBufferSize() + 2 ); // byte count + 1 trailing zero word
411 [ # # ]: 0 : aUrl.WriteBuffer( aXclStrm ); // NO flags
412 [ # # ]: 0 : aXclStrm << sal_uInt16( 0 );
413 : :
414 : 0 : mnFlags |= EXC_HLINK_BODY | EXC_HLINK_ABS;
415 [ # # ]: 0 : if( !mxRepr.get() )
416 [ # # ][ # # ]: 0 : mxRepr.reset( new String( rUrl ) );
[ # # ]
417 : :
418 [ # # ]: 0 : msTarget = XclXmlUtils::ToOUString( aUrl );
419 : : }
420 [ # # ]: 0 : else if( rUrl.GetChar( 0 ) == '#' ) // hack for #89066#
421 : : {
422 [ # # ]: 0 : String aTextMark( rUrl.Copy( 1 ) );
423 : :
424 [ # # ]: 0 : xub_StrLen nSepPos = aTextMark.SearchAndReplace( '.', '!' );
425 [ # # ]: 0 : String aSheetName( aTextMark.Copy(0, nSepPos));
426 : :
427 [ # # ][ # # ]: 0 : if ( aSheetName.Search(' ') != STRING_NOTFOUND && aSheetName.GetChar(0) != '\'')
[ # # ][ # # ]
428 : : {
429 [ # # ]: 0 : aTextMark.Insert('\'', nSepPos);
430 [ # # ]: 0 : aTextMark.Insert('\'', 0);
431 : : }
432 : :
433 [ # # ][ # # ]: 0 : mxTextMark.reset( new XclExpString( aTextMark, EXC_STR_FORCEUNICODE, 255 ) );
[ # # ][ # # ]
[ # # ]
434 : : }
435 : :
436 : : // text mark
437 [ # # ][ # # ]: 0 : if( !mxTextMark.get() && aUrlObj.HasMark() )
[ # # ][ # # ]
438 [ # # ][ # # ]: 0 : mxTextMark.reset( new XclExpString( aUrlObj.GetMark(), EXC_STR_FORCEUNICODE, 255 ) );
[ # # ][ # # ]
439 : :
440 [ # # ]: 0 : if( mxTextMark.get() )
441 : : {
442 [ # # ]: 0 : aXclStrm << sal_uInt32( mxTextMark->Len() + 1 ); // string length + 1 trailing zero word
443 [ # # ]: 0 : mxTextMark->WriteBuffer( aXclStrm ); // NO flags
444 [ # # ]: 0 : aXclStrm << sal_uInt16( 0 );
445 : :
446 : 0 : mnFlags |= EXC_HLINK_MARK;
447 : : }
448 : :
449 [ # # ][ # # ]: 0 : SetRecSize( 32 + mxVarData->Tell() );
[ # # ][ # # ]
450 : 0 : }
451 : :
452 [ # # ][ # # ]: 0 : XclExpHyperlink::~XclExpHyperlink()
[ # # ]
453 : : {
454 [ # # ]: 0 : }
455 : :
456 : 0 : String XclExpHyperlink::BuildFileName(
457 : : sal_uInt16& rnLevel, bool& rbRel, const String& rUrl, const XclExpRoot& rRoot ) const
458 : : {
459 [ # # ][ # # ]: 0 : String aDosName( INetURLObject( rUrl ).getFSysPath( INetURLObject::FSYS_DOS ) );
[ # # ][ # # ]
460 : 0 : rnLevel = 0;
461 : 0 : rbRel = rRoot.IsRelUrl();
462 : :
463 [ # # ]: 0 : if( rbRel )
464 : : {
465 : : // try to convert to relative file name
466 [ # # ]: 0 : String aTmpName( aDosName );
467 : 0 : aDosName = INetURLObject::GetRelURL( rRoot.GetBasePath(), rUrl,
468 [ # # # # ]: 0 : INetURLObject::WAS_ENCODED, INetURLObject::DECODE_WITH_CHARSET );
[ # # ][ # # ]
469 : :
470 [ # # ][ # # ]: 0 : if( aDosName.SearchAscii( INET_FILE_SCHEME ) == 0 )
471 : : {
472 : : // not converted to rel -> back to old, return absolute flag
473 [ # # ]: 0 : aDosName = aTmpName;
474 : 0 : rbRel = false;
475 : : }
476 [ # # ][ # # ]: 0 : else if( aDosName.SearchAscii( "./" ) == 0 )
477 : : {
478 [ # # ]: 0 : aDosName.Erase( 0, 2 );
479 : : }
480 : : else
481 : : {
482 [ # # ][ # # ]: 0 : while( aDosName.SearchAndReplaceAscii( "../", EMPTY_STRING ) == 0 )
[ # # ]
483 : 0 : ++rnLevel;
484 [ # # ]: 0 : }
485 : : }
486 : 0 : return aDosName;
487 : : }
488 : :
489 : 0 : void XclExpHyperlink::WriteBody( XclExpStream& rStrm )
490 : : {
491 : 0 : sal_uInt16 nXclCol = static_cast< sal_uInt16 >( maScPos.Col() );
492 : 0 : sal_uInt16 nXclRow = static_cast< sal_uInt16 >( maScPos.Row() );
493 : 0 : rStrm << nXclRow << nXclRow << nXclCol << nXclCol;
494 : 0 : WriteEmbeddedData( rStrm );
495 : 0 : }
496 : :
497 : 0 : void XclExpHyperlink::WriteEmbeddedData( XclExpStream& rStrm )
498 : : {
499 : 0 : rStrm << XclTools::maGuidStdLink
500 : 0 : << sal_uInt32( 2 )
501 : 0 : << mnFlags;
502 : :
503 : 0 : mxVarData->Seek( STREAM_SEEK_TO_BEGIN );
504 : 0 : rStrm.CopyFromStream( *mxVarData );
505 : 0 : }
506 : :
507 : 0 : void XclExpHyperlink::SaveXml( XclExpXmlStream& rStrm )
508 : : {
509 [ # # ]: 0 : OUString sId = !msTarget.isEmpty() ? rStrm.addRelation( rStrm.GetCurrentStream()->getOutputStream(),
510 : : XclXmlUtils::ToOUString( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" ),
511 [ # # ][ # # ]: 0 : msTarget, true ) : OUString();
[ # # ][ # # ]
[ # # ]
[ # # # # ]
[ # # ]
512 [ # # ]: 0 : rStrm.GetCurrentStream()->singleElement( XML_hyperlink,
513 : : XML_ref, XclXmlUtils::ToOString( maScPos ).getStr(),
514 : 0 : FSNS( XML_r, XML_id ), !sId.isEmpty()
515 [ # # # # ]: 0 : ? XclXmlUtils::ToOString( sId ).getStr()
[ # # ]
516 : : : NULL,
517 : 0 : XML_location, mxTextMark.get() != NULL
518 [ # # ][ # # ]: 0 : ? XclXmlUtils::ToOString( *mxTextMark ).getStr()
[ # # ]
519 : : : NULL,
520 : : // OOXTODO: XML_tooltip, from record HLinkTooltip 800h wzTooltip
521 : 0 : XML_display, XclXmlUtils::ToOString( *mxRepr ).getStr(),
522 [ # # ][ # # ]: 0 : FSEND );
[ # # ][ # # ]
[ # # ]
523 : 0 : }
524 : :
525 : : // Label ranges ===============================================================
526 : :
527 : 0 : XclExpLabelranges::XclExpLabelranges( const XclExpRoot& rRoot ) :
528 [ # # ][ # # ]: 0 : XclExpRoot( rRoot )
[ # # ]
529 : : {
530 : 0 : SCTAB nScTab = GetCurrScTab();
531 : : // row label ranges
532 [ # # ][ # # ]: 0 : FillRangeList( maRowRanges, rRoot.GetDoc().GetRowNameRangesRef(), nScTab );
533 : : // row labels only over 1 column (restriction of Excel97/2000/XP)
534 [ # # ][ # # ]: 0 : for ( size_t i = 0, nRanges = maRowRanges.size(); i < nRanges; ++i )
535 : : {
536 [ # # ]: 0 : ScRange* pScRange = maRowRanges[ i ];
537 [ # # ]: 0 : if( pScRange->aStart.Col() != pScRange->aEnd.Col() )
538 : 0 : pScRange->aEnd.SetCol( pScRange->aStart.Col() );
539 : : }
540 : : // col label ranges
541 [ # # ][ # # ]: 0 : FillRangeList( maColRanges, rRoot.GetDoc().GetColNameRangesRef(), nScTab );
542 : 0 : }
543 : :
544 : 0 : void XclExpLabelranges::FillRangeList( ScRangeList& rScRanges,
545 : : ScRangePairListRef xLabelRangesRef, SCTAB nScTab )
546 : : {
547 [ # # ]: 0 : for ( size_t i = 0, nPairs = xLabelRangesRef->size(); i < nPairs; ++i )
548 : : {
549 : 0 : ScRangePair* pRangePair = (*xLabelRangesRef)[i];
550 : 0 : const ScRange& rScRange = pRangePair->GetRange( 0 );
551 [ # # ]: 0 : if( rScRange.aStart.Tab() == nScTab )
552 : 0 : rScRanges.Append( rScRange );
553 : : }
554 : 0 : }
555 : :
556 : 0 : void XclExpLabelranges::Save( XclExpStream& rStrm )
557 : : {
558 [ # # ]: 0 : XclExpAddressConverter& rAddrConv = GetAddressConverter();
559 [ # # ][ # # ]: 0 : XclRangeList aRowXclRanges, aColXclRanges;
560 [ # # ]: 0 : rAddrConv.ConvertRangeList( aRowXclRanges, maRowRanges, false );
561 [ # # ]: 0 : rAddrConv.ConvertRangeList( aColXclRanges, maColRanges, false );
562 [ # # ][ # # ]: 0 : if( !aRowXclRanges.empty() || !aColXclRanges.empty() )
[ # # ]
563 : : {
564 [ # # ]: 0 : rStrm.StartRecord( EXC_ID_LABELRANGES, 4 + 8 * (aRowXclRanges.size() + aColXclRanges.size()) );
565 [ # # ][ # # ]: 0 : rStrm << aRowXclRanges << aColXclRanges;
566 [ # # ]: 0 : rStrm.EndRecord();
567 : 0 : }
568 : 0 : }
569 : :
570 : : // Conditional formatting ====================================================
571 : :
572 : : /** Represents a CF record that contains one condition of a conditional format. */
573 [ # # ][ # # ]: 0 : class XclExpCFImpl : protected XclExpRoot
[ # # ][ # # ]
574 : : {
575 : : public:
576 : : explicit XclExpCFImpl( const XclExpRoot& rRoot, const ScCondFormatEntry& rFormatEntry, sal_Int32 nPriority = 0 );
577 : :
578 : : /** Writes the body of the CF record. */
579 : : void WriteBody( XclExpStream& rStrm );
580 : : void SaveXml( XclExpXmlStream& rStrm );
581 : :
582 : : private:
583 : : const ScCondFormatEntry& mrFormatEntry; /// Calc conditional format entry.
584 : : XclFontData maFontData; /// Font formatting attributes.
585 : : XclExpCellBorder maBorder; /// Border formatting attributes.
586 : : XclExpCellArea maArea; /// Pattern formatting attributes.
587 : : XclTokenArrayRef mxTokArr1; /// Formula for first condition.
588 : : XclTokenArrayRef mxTokArr2; /// Formula for second condition.
589 : : sal_uInt32 mnFontColorId; /// Font color ID.
590 : : sal_uInt8 mnType; /// Type of the condition (cell/formula).
591 : : sal_uInt8 mnOperator; /// Comparison operator for cell type.
592 : : sal_Int32 mnPriority; /// Priority of this entry; needed for oox export
593 : : bool mbFontUsed; /// true = Any font attribute used.
594 : : bool mbHeightUsed; /// true = Font height used.
595 : : bool mbWeightUsed; /// true = Font weight used.
596 : : bool mbColorUsed; /// true = Font color used.
597 : : bool mbUnderlUsed; /// true = Font underline type used.
598 : : bool mbItalicUsed; /// true = Font posture used.
599 : : bool mbStrikeUsed; /// true = Font strikeout used.
600 : : bool mbBorderUsed; /// true = Border attribute used.
601 : : bool mbPattUsed; /// true = Pattern attribute used.
602 : : };
603 : :
604 : : // ----------------------------------------------------------------------------
605 : :
606 : 0 : XclExpCFImpl::XclExpCFImpl( const XclExpRoot& rRoot, const ScCondFormatEntry& rFormatEntry, sal_Int32 nPriority ) :
607 : : XclExpRoot( rRoot ),
608 : : mrFormatEntry( rFormatEntry ),
609 : : mnFontColorId( 0 ),
610 : : mnType( EXC_CF_TYPE_CELL ),
611 : : mnOperator( EXC_CF_CMP_NONE ),
612 : : mnPriority( nPriority ),
613 : : mbFontUsed( false ),
614 : : mbHeightUsed( false ),
615 : : mbWeightUsed( false ),
616 : : mbColorUsed( false ),
617 : : mbUnderlUsed( false ),
618 : : mbItalicUsed( false ),
619 : : mbStrikeUsed( false ),
620 : : mbBorderUsed( false ),
621 [ # # ][ # # ]: 0 : mbPattUsed( false )
[ # # ][ # # ]
[ # # ]
622 : : {
623 : : /* Get formatting attributes here, and not in WriteBody(). This is needed to
624 : : correctly insert all colors into the palette. */
625 : :
626 [ # # ][ # # ]: 0 : if( SfxStyleSheetBase* pStyleSheet = GetDoc().GetStyleSheetPool()->Find( mrFormatEntry.GetStyle(), SFX_STYLE_FAMILY_PARA ) )
[ # # ]
627 : : {
628 [ # # ]: 0 : const SfxItemSet& rItemSet = pStyleSheet->GetItemSet();
629 : :
630 : : // font
631 [ # # ]: 0 : mbHeightUsed = ScfTools::CheckItem( rItemSet, ATTR_FONT_HEIGHT, true );
632 [ # # ]: 0 : mbWeightUsed = ScfTools::CheckItem( rItemSet, ATTR_FONT_WEIGHT, true );
633 [ # # ]: 0 : mbColorUsed = ScfTools::CheckItem( rItemSet, ATTR_FONT_COLOR, true );
634 [ # # ]: 0 : mbUnderlUsed = ScfTools::CheckItem( rItemSet, ATTR_FONT_UNDERLINE, true );
635 [ # # ]: 0 : mbItalicUsed = ScfTools::CheckItem( rItemSet, ATTR_FONT_POSTURE, true );
636 [ # # ]: 0 : mbStrikeUsed = ScfTools::CheckItem( rItemSet, ATTR_FONT_CROSSEDOUT, true );
637 [ # # ][ # # ]: 0 : mbFontUsed = mbHeightUsed || mbWeightUsed || mbColorUsed || mbUnderlUsed || mbItalicUsed || mbStrikeUsed;
[ # # ][ # # ]
[ # # ][ # # ]
638 [ # # ]: 0 : if( mbFontUsed )
639 : : {
640 [ # # ]: 0 : Font aFont;
641 [ # # ]: 0 : ScPatternAttr::GetFont( aFont, rItemSet, SC_AUTOCOL_RAW );
642 [ # # ]: 0 : maFontData.FillFromVclFont( aFont );
643 [ # # ][ # # ]: 0 : mnFontColorId = GetPalette().InsertColor( maFontData.maColor, EXC_COLOR_CELLTEXT );
[ # # ]
644 : : }
645 : :
646 : : // border
647 [ # # ]: 0 : mbBorderUsed = ScfTools::CheckItem( rItemSet, ATTR_BORDER, true );
648 [ # # ]: 0 : if( mbBorderUsed )
649 [ # # ][ # # ]: 0 : maBorder.FillFromItemSet( rItemSet, GetPalette(), GetBiff() );
650 : :
651 : : // pattern
652 [ # # ]: 0 : mbPattUsed = ScfTools::CheckItem( rItemSet, ATTR_BACKGROUND, true );
653 [ # # ]: 0 : if( mbPattUsed )
654 [ # # ][ # # ]: 0 : maArea.FillFromItemSet( rItemSet, GetPalette(), GetBiff() );
655 : : }
656 : :
657 : : // *** mode and comparison operator ***
658 : :
659 : 0 : bool bFmla2 = false;
660 [ # # # # : 0 : switch( rFormatEntry.GetOperation() )
# # # # #
# # ]
661 : : {
662 : 0 : case SC_COND_NONE: mnType = EXC_CF_TYPE_NONE; break;
663 : 0 : case SC_COND_BETWEEN: mnOperator = EXC_CF_CMP_BETWEEN; bFmla2 = true; break;
664 : 0 : case SC_COND_NOTBETWEEN: mnOperator = EXC_CF_CMP_NOT_BETWEEN; bFmla2 = true; break;
665 : 0 : case SC_COND_EQUAL: mnOperator = EXC_CF_CMP_EQUAL; break;
666 : 0 : case SC_COND_NOTEQUAL: mnOperator = EXC_CF_CMP_NOT_EQUAL; break;
667 : 0 : case SC_COND_GREATER: mnOperator = EXC_CF_CMP_GREATER; break;
668 : 0 : case SC_COND_LESS: mnOperator = EXC_CF_CMP_LESS; break;
669 : 0 : case SC_COND_EQGREATER: mnOperator = EXC_CF_CMP_GREATER_EQUAL; break;
670 : 0 : case SC_COND_EQLESS: mnOperator = EXC_CF_CMP_LESS_EQUAL; break;
671 : 0 : case SC_COND_DIRECT: mnType = EXC_CF_TYPE_FMLA; break;
672 : 0 : default: mnType = EXC_CF_TYPE_NONE;
673 : : OSL_FAIL( "XclExpCF::WriteBody - unknown condition type" );
674 : : }
675 : :
676 : : // *** formulas ***
677 : :
678 [ # # ]: 0 : XclExpFormulaCompiler& rFmlaComp = GetFormulaCompiler();
679 : :
680 [ # # ]: 0 : boost::scoped_ptr< ScTokenArray > xScTokArr( mrFormatEntry.CreateTokenArry( 0 ) );
681 [ # # ][ # # ]: 0 : mxTokArr1 = rFmlaComp.CreateFormula( EXC_FMLATYPE_CONDFMT, *xScTokArr );
[ # # ]
682 : :
683 [ # # ]: 0 : if( bFmla2 )
684 : : {
685 [ # # ][ # # ]: 0 : xScTokArr.reset( mrFormatEntry.CreateTokenArry( 1 ) );
686 [ # # ][ # # ]: 0 : mxTokArr2 = rFmlaComp.CreateFormula( EXC_FMLATYPE_CONDFMT, *xScTokArr );
[ # # ]
687 [ # # ]: 0 : }
688 : 0 : }
689 : :
690 : 0 : void XclExpCFImpl::WriteBody( XclExpStream& rStrm )
691 : : {
692 : : // *** mode and comparison operator ***
693 : :
694 : 0 : rStrm << mnType << mnOperator;
695 : :
696 : : // *** formula sizes ***
697 : :
698 [ # # ]: 0 : sal_uInt16 nFmlaSize1 = mxTokArr1.get() ? mxTokArr1->GetSize() : 0;
699 [ # # ]: 0 : sal_uInt16 nFmlaSize2 = mxTokArr2.get() ? mxTokArr2->GetSize() : 0;
700 : 0 : rStrm << nFmlaSize1 << nFmlaSize2;
701 : :
702 : : // *** formatting blocks ***
703 : :
704 [ # # ][ # # ]: 0 : if( mbFontUsed || mbBorderUsed || mbPattUsed )
[ # # ]
705 : : {
706 : 0 : sal_uInt32 nFlags = EXC_CF_ALLDEFAULT;
707 : :
708 : 0 : ::set_flag( nFlags, EXC_CF_BLOCK_FONT, mbFontUsed );
709 : 0 : ::set_flag( nFlags, EXC_CF_BLOCK_BORDER, mbBorderUsed );
710 : 0 : ::set_flag( nFlags, EXC_CF_BLOCK_AREA, mbPattUsed );
711 : :
712 : : // attributes used -> set flags to 0.
713 : 0 : ::set_flag( nFlags, EXC_CF_BORDER_ALL, !mbBorderUsed );
714 : 0 : ::set_flag( nFlags, EXC_CF_AREA_ALL, !mbPattUsed );
715 : :
716 [ # # ][ # # ]: 0 : rStrm << nFlags << sal_uInt16( 0 );
717 : :
718 [ # # ]: 0 : if( mbFontUsed )
719 : : {
720 : : // font height, 0xFFFFFFFF indicates unused
721 [ # # ]: 0 : sal_uInt32 nHeight = mbHeightUsed ? maFontData.mnHeight : 0xFFFFFFFF;
722 : : // font style: italic and strikeout
723 : 0 : sal_uInt32 nStyle = 0;
724 : 0 : ::set_flag( nStyle, EXC_CF_FONT_STYLE, maFontData.mbItalic );
725 : 0 : ::set_flag( nStyle, EXC_CF_FONT_STRIKEOUT, maFontData.mbStrikeout );
726 : : // font color, 0xFFFFFFFF indicates unused
727 [ # # ][ # # ]: 0 : sal_uInt32 nColor = mbColorUsed ? GetPalette().GetColorIndex( mnFontColorId ) : 0xFFFFFFFF;
[ # # ]
728 : : // font used flags for italic, weight, and strikeout -> 0 = used, 1 = default
729 : 0 : sal_uInt32 nFontFlags1 = EXC_CF_FONT_ALLDEFAULT;
730 [ # # ][ # # ]: 0 : ::set_flag( nFontFlags1, EXC_CF_FONT_STYLE, !(mbItalicUsed || mbWeightUsed) );
731 : 0 : ::set_flag( nFontFlags1, EXC_CF_FONT_STRIKEOUT, !mbStrikeUsed );
732 : : // font used flag for underline -> 0 = used, 1 = default
733 [ # # ]: 0 : sal_uInt32 nFontFlags3 = mbUnderlUsed ? 0 : EXC_CF_FONT_UNDERL;
734 : :
735 [ # # ]: 0 : rStrm.WriteZeroBytesToRecord( 64 );
736 [ # # ]: 0 : rStrm << nHeight
737 [ # # ]: 0 : << nStyle
738 [ # # ]: 0 : << maFontData.mnWeight
739 [ # # ]: 0 : << EXC_FONTESC_NONE
740 [ # # ]: 0 : << maFontData.mnUnderline;
741 [ # # ]: 0 : rStrm.WriteZeroBytesToRecord( 3 );
742 [ # # ]: 0 : rStrm << nColor
743 [ # # ]: 0 : << sal_uInt32( 0 )
744 [ # # ]: 0 : << nFontFlags1
745 [ # # ]: 0 : << EXC_CF_FONT_ESCAPEM // escapement never used -> set the flag
746 [ # # ]: 0 : << nFontFlags3;
747 [ # # ]: 0 : rStrm.WriteZeroBytesToRecord( 16 );
748 [ # # ]: 0 : rStrm << sal_uInt16( 1 ); // must be 1
749 : : }
750 : :
751 [ # # ]: 0 : if( mbBorderUsed )
752 : : {
753 : 0 : sal_uInt16 nLineStyle = 0;
754 : 0 : sal_uInt32 nLineColor = 0;
755 [ # # ][ # # ]: 0 : maBorder.SetFinalColors( GetPalette() );
756 [ # # ]: 0 : maBorder.FillToCF8( nLineStyle, nLineColor );
757 [ # # ][ # # ]: 0 : rStrm << nLineStyle << nLineColor << sal_uInt16( 0 );
[ # # ]
758 : : }
759 : :
760 [ # # ]: 0 : if( mbPattUsed )
761 : : {
762 : 0 : sal_uInt16 nPattern = 0, nColor = 0;
763 [ # # ][ # # ]: 0 : maArea.SetFinalColors( GetPalette() );
764 [ # # ]: 0 : maArea.FillToCF8( nPattern, nColor );
765 [ # # ][ # # ]: 0 : rStrm << nPattern << nColor;
766 : 0 : }
767 : : }
768 : : else
769 : : {
770 : : // no data blocks at all
771 : 0 : rStrm << sal_uInt32( 0 ) << sal_uInt16( 0 );
772 : : }
773 : :
774 : : // *** formulas ***
775 : :
776 [ # # ]: 0 : if( mxTokArr1.get() )
777 : 0 : mxTokArr1->WriteArray( rStrm );
778 [ # # ]: 0 : if( mxTokArr2.get() )
779 : 0 : mxTokArr2->WriteArray( rStrm );
780 : 0 : }
781 : :
782 : : namespace {
783 : :
784 : 0 : const char* GetOperatorString(ScConditionMode eMode, bool& bFrmla2)
785 : : {
786 : 0 : const char *pRet = "";
787 [ # # # # : 0 : switch(eMode)
# # # # #
# # # ]
788 : : {
789 : : case SC_COND_EQUAL:
790 : 0 : pRet = "equal";
791 : 0 : break;
792 : : case SC_COND_LESS:
793 : 0 : pRet = "lessThan";
794 : 0 : break;
795 : : case SC_COND_GREATER:
796 : 0 : pRet = "greaterThan";
797 : 0 : break;
798 : : case SC_COND_EQLESS:
799 : 0 : pRet = "lessThanOrEqual";
800 : 0 : break;
801 : : case SC_COND_EQGREATER:
802 : 0 : pRet = "greaterThanOrEqual";
803 : 0 : break;
804 : : case SC_COND_NOTEQUAL:
805 : 0 : pRet = "notEqual";
806 : 0 : break;
807 : : case SC_COND_BETWEEN:
808 : 0 : bFrmla2 = true;
809 : 0 : pRet = "between";
810 : 0 : break;
811 : : case SC_COND_NOTBETWEEN:
812 : 0 : bFrmla2 = true;
813 : 0 : pRet = "notBetween";
814 : 0 : break;
815 : : case SC_COND_DUPLICATE:
816 : 0 : pRet = "duplicateValues";
817 : 0 : break;
818 : : case SC_COND_NOTDUPLICATE:
819 : 0 : pRet = "uniqueValues";
820 : 0 : break;
821 : : case SC_COND_DIRECT:
822 : 0 : pRet = "expression";
823 : 0 : break;
824 : : case SC_COND_NONE:
825 : : default:
826 : 0 : pRet = "";
827 : 0 : break;
828 : : }
829 : 0 : return pRet;
830 : : }
831 : :
832 : 0 : const char* GetTypeString(ScConditionMode eMode)
833 : : {
834 [ # # ]: 0 : if (eMode == SC_COND_DIRECT)
835 : 0 : return "expression";
836 : 0 : return "cellIs";
837 : : }
838 : :
839 : : }
840 : :
841 : 0 : void XclExpCFImpl::SaveXml( XclExpXmlStream& rStrm )
842 : : {
843 : 0 : bool bFmla2 = false;
844 [ # # ]: 0 : sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
845 : : rWorksheet->startElement( XML_cfRule,
846 : : XML_type, GetTypeString( mrFormatEntry.GetOperation() ),
847 : : XML_priority, OString::valueOf( mnPriority + 1 ).getStr(),
848 : : XML_operator, GetOperatorString( mrFormatEntry.GetOperation(), bFmla2 ),
849 [ # # ]: 0 : XML_dxfId, OString::valueOf( GetDxfs().GetDxfId( mrFormatEntry.GetStyle() ) ).getStr(),
850 [ # # ][ # # ]: 0 : FSEND );
[ # # ]
851 [ # # ]: 0 : rWorksheet->startElement( XML_formula, FSEND );
852 [ # # ][ # # ]: 0 : rWorksheet->write(XclXmlUtils::ToOUString( GetRoot().GetDoc(), mrFormatEntry.GetValidSrcPos(), mrFormatEntry.CreateTokenArry( 0 ) ));
[ # # ][ # # ]
853 [ # # ]: 0 : rWorksheet->endElement( XML_formula );
854 [ # # ]: 0 : if (bFmla2)
855 : : {
856 [ # # ]: 0 : rWorksheet->startElement( XML_formula, FSEND );
857 [ # # ][ # # ]: 0 : rWorksheet->write(XclXmlUtils::ToOUString( GetRoot().GetDoc(), mrFormatEntry.GetValidSrcPos(), mrFormatEntry.CreateTokenArry( 1 ) ));
[ # # ][ # # ]
858 [ # # ]: 0 : rWorksheet->endElement( XML_formula );
859 : : }
860 : : // OOXTODO: XML_extLst
861 [ # # ]: 0 : rWorksheet->endElement( XML_cfRule );
862 : 0 : }
863 : :
864 : : // ----------------------------------------------------------------------------
865 : :
866 : 0 : XclExpCF::XclExpCF( const XclExpRoot& rRoot, const ScCondFormatEntry& rFormatEntry, sal_Int32 nPriority = 0 ) :
867 : : XclExpRecord( EXC_ID_CF ),
868 : : XclExpRoot( rRoot ),
869 [ # # ][ # # ]: 0 : mxImpl( new XclExpCFImpl( rRoot, rFormatEntry, nPriority ) )
[ # # ]
870 : : {
871 : 0 : }
872 : :
873 [ # # ][ # # ]: 0 : XclExpCF::~XclExpCF()
874 : : {
875 [ # # ]: 0 : }
876 : :
877 : 0 : void XclExpCF::WriteBody( XclExpStream& rStrm )
878 : : {
879 : 0 : mxImpl->WriteBody( rStrm );
880 : 0 : }
881 : :
882 : 0 : void XclExpCF::SaveXml( XclExpXmlStream& rStrm )
883 : : {
884 : 0 : mxImpl->SaveXml( rStrm );
885 : 0 : }
886 : :
887 : 0 : XclExpCfvo::XclExpCfvo(const XclExpRoot& rRoot, const ScColorScaleEntry& rEntry, const ScAddress& rAddr):
888 : : XclExpRecord(),
889 : : XclExpRoot( rRoot ),
890 : : mrEntry(rEntry),
891 [ # # ]: 0 : maSrcPos(rAddr)
892 : : {
893 : 0 : }
894 : :
895 : : namespace {
896 : :
897 : 0 : rtl::OString getColorScaleType( const ScColorScaleEntry& rEntry )
898 : : {
899 [ # # # # : 0 : switch(rEntry.GetType())
# # # # ]
900 : : {
901 : : case COLORSCALE_MIN:
902 : 0 : return "min";
903 : : case COLORSCALE_MAX:
904 : 0 : return "max";
905 : : case COLORSCALE_PERCENT:
906 : 0 : return "percent";
907 : : case COLORSCALE_FORMULA:
908 : 0 : return "formula";
909 : : case COLORSCALE_AUTOMIN:
910 : 0 : return "min";
911 : : case COLORSCALE_AUTOMAX:
912 : 0 : return "max";
913 : : case COLORSCALE_PERCENTILE:
914 : 0 : return "percentile";
915 : : default:
916 : 0 : break;
917 : : }
918 : :
919 : 0 : return "num";
920 : : }
921 : :
922 : : }
923 : :
924 : 0 : void XclExpCfvo::SaveXml( XclExpXmlStream& rStrm )
925 : : {
926 [ # # ]: 0 : sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
927 : :
928 : 0 : rtl::OString aValue;
929 [ # # ][ # # ]: 0 : if(mrEntry.GetType() == COLORSCALE_FORMULA)
930 : : {
931 [ # # ][ # # ]: 0 : rtl::OUString aFormula = XclXmlUtils::ToOUString( GetRoot().GetDoc(), maSrcPos, mrEntry.GetFormula()->Clone() );
[ # # ]
932 [ # # ]: 0 : aValue = rtl::OUStringToOString(aFormula, RTL_TEXTENCODING_UTF8 );
933 : : }
934 : : else
935 : : {
936 [ # # ]: 0 : aValue = OString::valueOf( mrEntry.GetValue() );
937 : : }
938 : :
939 : : rWorksheet->startElement( XML_cfvo,
940 : : XML_type, getColorScaleType(mrEntry).getStr(),
941 : : XML_val, aValue.getStr(),
942 [ # # ][ # # ]: 0 : FSEND );
943 : :
944 [ # # ]: 0 : rWorksheet->endElement( XML_cfvo );
945 : 0 : }
946 : :
947 : 0 : XclExpColScaleCol::XclExpColScaleCol( const XclExpRoot& rRoot, const Color& rColor ):
948 : : XclExpRecord(),
949 : : XclExpRoot( rRoot ),
950 [ # # ]: 0 : mrColor( rColor )
951 : : {
952 : 0 : }
953 : :
954 [ # # ]: 0 : XclExpColScaleCol::~XclExpColScaleCol()
955 : : {
956 [ # # ]: 0 : }
957 : :
958 : 0 : void XclExpColScaleCol::SaveXml( XclExpXmlStream& rStrm )
959 : : {
960 : 0 : sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
961 : :
962 : : rWorksheet->startElement( XML_color,
963 : : XML_rgb, XclXmlUtils::ToOString( mrColor ).getStr(),
964 [ # # ]: 0 : FSEND );
965 : :
966 : 0 : rWorksheet->endElement( XML_color );
967 : 0 : }
968 : :
969 : : // ----------------------------------------------------------------------------
970 : :
971 : 0 : XclExpCondfmt::XclExpCondfmt( const XclExpRoot& rRoot, const ScConditionalFormat& rCondFormat, XclExtLstRef xExtLst ) :
972 : : XclExpRecord( EXC_ID_CONDFMT ),
973 [ # # ][ # # ]: 0 : XclExpRoot( rRoot )
[ # # ][ # # ]
974 : : {
975 [ # # ]: 0 : ScRangeList aScRanges;
976 [ # # ]: 0 : GetDoc().FindConditionalFormat( rCondFormat.GetKey(), aScRanges, GetCurrScTab() );
977 [ # # ][ # # ]: 0 : GetAddressConverter().ConvertRangeList( maXclRanges, aScRanges, true );
978 [ # # ]: 0 : if( !maXclRanges.empty() )
979 : : {
980 [ # # ][ # # ]: 0 : for( size_t nIndex = 0, nCount = rCondFormat.size(); nIndex < nCount; ++nIndex )
981 [ # # ][ # # ]: 0 : if( const ScFormatEntry* pFormatEntry = rCondFormat.GetEntry( nIndex ) )
982 : : {
983 [ # # ][ # # ]: 0 : if(pFormatEntry->GetType() == condformat::CONDITION)
984 [ # # ][ # # ]: 0 : maCFList.AppendNewRecord( new XclExpCF( GetRoot(), static_cast<const ScCondFormatEntry&>(*pFormatEntry), nIndex ) );
[ # # ]
985 [ # # ][ # # ]: 0 : else if(pFormatEntry->GetType() == condformat::COLORSCALE)
986 [ # # ][ # # ]: 0 : maCFList.AppendNewRecord( new XclExpColorScale( GetRoot(), static_cast<const ScColorScaleFormat&>(*pFormatEntry), nIndex ) );
[ # # ]
987 [ # # ][ # # ]: 0 : else if(pFormatEntry->GetType() == condformat::DATABAR)
988 [ # # ][ # # ]: 0 : maCFList.AppendNewRecord( new XclExpDataBar( GetRoot(), static_cast<const ScDataBarFormat&>(*pFormatEntry), nIndex, xExtLst ) );
[ # # ][ # # ]
[ # # ]
989 : : }
990 [ # # ]: 0 : aScRanges.Format( msSeqRef, SCA_VALID, NULL, formula::FormulaGrammar::CONV_XL_A1 );
991 [ # # ]: 0 : }
992 : 0 : }
993 : :
994 [ # # ][ # # ]: 0 : XclExpCondfmt::~XclExpCondfmt()
[ # # ]
995 : : {
996 [ # # ]: 0 : }
997 : :
998 : 0 : bool XclExpCondfmt::IsValid() const
999 : : {
1000 [ # # ][ # # ]: 0 : return !maCFList.IsEmpty() && !maXclRanges.empty();
1001 : : }
1002 : :
1003 : 0 : void XclExpCondfmt::Save( XclExpStream& rStrm )
1004 : : {
1005 [ # # ]: 0 : if( IsValid() )
1006 : : {
1007 : 0 : XclExpRecord::Save( rStrm );
1008 : 0 : maCFList.Save( rStrm );
1009 : : }
1010 : 0 : }
1011 : :
1012 : 0 : void XclExpCondfmt::WriteBody( XclExpStream& rStrm )
1013 : : {
1014 : : OSL_ENSURE( !maCFList.IsEmpty(), "XclExpCondfmt::WriteBody - no CF records to write" );
1015 : : OSL_ENSURE( !maXclRanges.empty(), "XclExpCondfmt::WriteBody - no cell ranges found" );
1016 : :
1017 [ # # ]: 0 : rStrm << static_cast< sal_uInt16 >( maCFList.GetSize() )
1018 [ # # ]: 0 : << sal_uInt16( 1 )
1019 [ # # ]: 0 : << maXclRanges.GetEnclosingRange()
1020 [ # # ]: 0 : << maXclRanges;
1021 : 0 : }
1022 : :
1023 : 0 : void XclExpCondfmt::SaveXml( XclExpXmlStream& rStrm )
1024 : : {
1025 [ # # ]: 0 : if( !IsValid() )
1026 : 0 : return;
1027 : :
1028 : 0 : sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
1029 : : rWorksheet->startElement( XML_conditionalFormatting,
1030 : : XML_sqref, XclXmlUtils::ToOString( msSeqRef ).getStr(),
1031 : : // OOXTODO: XML_pivot,
1032 [ # # ]: 0 : FSEND );
1033 : :
1034 : 0 : maCFList.SaveXml( rStrm );
1035 : :
1036 : : // OOXTODO: XML_extLst
1037 : 0 : rWorksheet->endElement( XML_conditionalFormatting );
1038 : : }
1039 : :
1040 : : // ----------------------------------------------------------------------------
1041 : :
1042 : 0 : XclExpColorScale::XclExpColorScale( const XclExpRoot& rRoot, const ScColorScaleFormat& rFormat, sal_Int32 nPriority ):
1043 : : XclExpRecord(),
1044 : : XclExpRoot( rRoot ),
1045 : : mrFormat( rFormat ),
1046 [ # # ][ # # ]: 0 : mnPriority( nPriority )
[ # # ]
1047 : : {
1048 [ # # ][ # # ]: 0 : const ScRange* pRange = rFormat.GetRange().front();
1049 : 0 : ScAddress aAddr = pRange->aStart;
1050 [ # # ][ # # ]: 0 : for(ScColorScaleFormat::const_iterator itr = rFormat.begin();
[ # # ][ # # ]
1051 [ # # ]: 0 : itr != rFormat.end(); ++itr)
1052 : : {
1053 : : // exact position is not important, we allow only absolute refs
1054 : :
1055 [ # # ][ # # ]: 0 : XclExpCfvoList::RecordRefType xCfvo( new XclExpCfvo( GetRoot(), *itr, aAddr ) );
[ # # ][ # # ]
1056 [ # # ][ # # ]: 0 : maCfvoList.AppendRecord( xCfvo );
[ # # ]
1057 [ # # ][ # # ]: 0 : XclExpColScaleColList::RecordRefType xClo( new XclExpColScaleCol( GetRoot(), itr->GetColor() ) );
[ # # ][ # # ]
[ # # ]
1058 [ # # ][ # # ]: 0 : maColList.AppendRecord( xClo );
[ # # ]
1059 [ # # ][ # # ]: 0 : }
1060 : 0 : }
1061 : :
1062 : 0 : void XclExpColorScale::SaveXml( XclExpXmlStream& rStrm )
1063 : : {
1064 : 0 : sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
1065 : :
1066 : : rWorksheet->startElement( XML_cfRule,
1067 : : XML_type, "colorScale",
1068 : : XML_priority, OString::valueOf( mnPriority + 1 ).getStr(),
1069 [ # # ]: 0 : FSEND );
1070 : :
1071 : 0 : rWorksheet->startElement( XML_colorScale, FSEND );
1072 : :
1073 : 0 : maCfvoList.SaveXml(rStrm);
1074 : 0 : maColList.SaveXml(rStrm);
1075 : :
1076 : 0 : rWorksheet->endElement( XML_colorScale );
1077 : :
1078 : 0 : rWorksheet->endElement( XML_cfRule );
1079 : :
1080 : : // OOXTODO: XML_extLst
1081 : 0 : }
1082 : :
1083 : 0 : XclExpDataBar::XclExpDataBar( const XclExpRoot& rRoot, const ScDataBarFormat& rFormat, sal_Int32 nPriority, XclExtLstRef xExtLst ):
1084 : : XclExpRecord(),
1085 : : XclExpRoot( rRoot ),
1086 : : mrFormat( rFormat ),
1087 [ # # ]: 0 : mnPriority( nPriority )
1088 : : {
1089 [ # # ][ # # ]: 0 : const ScRange* pRange = rFormat.GetRange().front();
1090 : 0 : ScAddress aAddr = pRange->aStart;
1091 : : // exact position is not important, we allow only absolute refs
1092 [ # # ][ # # ]: 0 : mpCfvoLowerLimit.reset( new XclExpCfvo( GetRoot(), *mrFormat.GetDataBarData()->mpLowerLimit.get(), aAddr ) );
[ # # ][ # # ]
1093 [ # # ][ # # ]: 0 : mpCfvoUpperLimit.reset( new XclExpCfvo( GetRoot(), *mrFormat.GetDataBarData()->mpUpperLimit.get(), aAddr ) );
[ # # ][ # # ]
1094 : :
1095 [ # # ][ # # ]: 0 : mpCol.reset( new XclExpColScaleCol( GetRoot(), mrFormat.GetDataBarData()->maPositiveColor ) );
[ # # ][ # # ]
1096 [ # # ]: 0 : if(xExtLst.get())
1097 : : {
1098 [ # # ]: 0 : XclExpExtRef pParent = xExtLst->GetItem( XclExpExtDataBarType );
1099 [ # # ]: 0 : if( !pParent.get() )
1100 : : {
1101 [ # # ][ # # ]: 0 : xExtLst->AddRecord( XclExpExtRef(new XclExpExtCondFormat( *xExtLst.get() )) );
[ # # ][ # # ]
[ # # ]
1102 [ # # ][ # # ]: 0 : pParent = xExtLst->GetItem( XclExpExtDataBarType );
[ # # ]
1103 : : }
1104 [ # # ][ # # ]: 0 : static_cast<XclExpExtCondFormat*>(xExtLst->GetItem( XclExpExtDataBarType ).get())->AddRecord( XclExpExtConditionalFormattingRef(new XclExpExtConditionalFormatting( *pParent, rFormat, aAddr, rtl::OString("{64A12B6B-50E9-436E-8939-DBE15E5BE1DC}") )) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
1105 : : }
1106 : 0 : }
1107 : :
1108 : 0 : void XclExpDataBar::SaveXml( XclExpXmlStream& rStrm )
1109 : : {
1110 : 0 : sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
1111 : :
1112 : : rWorksheet->startElement( XML_cfRule,
1113 : : XML_type, "dataBar",
1114 : : XML_priority, OString::valueOf( mnPriority + 1 ).getStr(),
1115 [ # # ]: 0 : FSEND );
1116 : :
1117 : 0 : rWorksheet->startElement( XML_dataBar, FSEND );
1118 : :
1119 : 0 : mpCfvoLowerLimit->SaveXml(rStrm);
1120 : 0 : mpCfvoUpperLimit->SaveXml(rStrm);
1121 : 0 : mpCol->SaveXml(rStrm);
1122 : :
1123 : 0 : rWorksheet->endElement( XML_dataBar );
1124 : :
1125 : : // extLst entries for Excel 2010 and 2013
1126 : 0 : rWorksheet->startElement( XML_extLst, FSEND );
1127 : : rWorksheet->startElement( XML_ext,
1128 : : FSNS( XML_xmlns, XML_x14 ), "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main",
1129 : : XML_uri, "{B025F937-C7B1-47D3-B67F-A62EFF666E3E}",
1130 : 0 : FSEND );
1131 : :
1132 : 0 : rWorksheet->startElementNS( XML_x14, XML_id, FSEND );
1133 : 0 : rWorksheet->write( "{64A12B6B-50E9-436E-8939-DBE15E5BE1DC}" );
1134 : 0 : rWorksheet->endElementNS( XML_x14, XML_id );
1135 : :
1136 : 0 : rWorksheet->endElement( XML_ext );
1137 : 0 : rWorksheet->endElement( XML_extLst );
1138 : :
1139 : 0 : rWorksheet->endElement( XML_cfRule );
1140 : :
1141 : : // OOXTODO: XML_extLst
1142 : :
1143 : 0 : }
1144 : :
1145 : : // ----------------------------------------------------------------------------
1146 : :
1147 : 0 : XclExpCondFormatBuffer::XclExpCondFormatBuffer( const XclExpRoot& rRoot, XclExtLstRef xExtLst ) :
1148 [ # # ][ # # ]: 0 : XclExpRoot( rRoot )
1149 : : {
1150 [ # # ][ # # ]: 0 : if( const ScConditionalFormatList* pCondFmtList = GetDoc().GetCondFormList(GetCurrScTab()) )
1151 : : {
1152 [ # # ][ # # ]: 0 : for( ScConditionalFormatList::const_iterator itr = pCondFmtList->begin();
[ # # ][ # # ]
1153 [ # # ]: 0 : itr != pCondFmtList->end(); ++itr)
1154 : : {
1155 [ # # ][ # # ]: 0 : XclExpCondfmtList::RecordRefType xCondfmtRec( new XclExpCondfmt( GetRoot(), *itr, xExtLst ) );
[ # # ][ # # ]
[ # # ][ # # ]
1156 [ # # ][ # # ]: 0 : if( xCondfmtRec->IsValid() )
1157 [ # # ][ # # ]: 0 : maCondfmtList.AppendRecord( xCondfmtRec );
[ # # ]
1158 [ # # ]: 0 : }
1159 : : }
1160 : 0 : }
1161 : :
1162 : 0 : void XclExpCondFormatBuffer::Save( XclExpStream& rStrm )
1163 : : {
1164 : 0 : maCondfmtList.Save( rStrm );
1165 : 0 : }
1166 : :
1167 : 0 : void XclExpCondFormatBuffer::SaveXml( XclExpXmlStream& rStrm )
1168 : : {
1169 : 0 : maCondfmtList.SaveXml( rStrm );
1170 : 0 : }
1171 : :
1172 : : // Validation =================================================================
1173 : :
1174 : : namespace {
1175 : :
1176 : : /** Writes a formula for the DV record. */
1177 : 0 : void lclWriteDvFormula( XclExpStream& rStrm, const XclTokenArray* pXclTokArr )
1178 : : {
1179 [ # # ]: 0 : sal_uInt16 nFmlaSize = pXclTokArr ? pXclTokArr->GetSize() : 0;
1180 : 0 : rStrm << nFmlaSize << sal_uInt16( 0 );
1181 [ # # ]: 0 : if( pXclTokArr )
1182 : 0 : pXclTokArr->WriteArray( rStrm );
1183 : 0 : }
1184 : :
1185 : : /** Writes a formula for the DV record, based on a single string. */
1186 : 0 : void lclWriteDvFormula( XclExpStream& rStrm, const XclExpString& rString )
1187 : : {
1188 : : // fake a formula with a single tStr token
1189 : 0 : rStrm << static_cast< sal_uInt16 >( rString.GetSize() + 1 )
1190 : 0 : << sal_uInt16( 0 )
1191 : 0 : << EXC_TOKID_STR
1192 : 0 : << rString;
1193 : 0 : }
1194 : :
1195 : 0 : const char* lcl_GetValidationType( sal_uInt32 nFlags )
1196 : : {
1197 [ # # # # : 0 : switch( nFlags & EXC_DV_MODE_MASK )
# # # #
# ]
1198 : : {
1199 : 0 : case EXC_DV_MODE_ANY: return "none";
1200 : 0 : case EXC_DV_MODE_WHOLE: return "whole";
1201 : 0 : case EXC_DV_MODE_DECIMAL: return "decimal";
1202 : 0 : case EXC_DV_MODE_LIST: return "list";
1203 : 0 : case EXC_DV_MODE_DATE: return "date";
1204 : 0 : case EXC_DV_MODE_TIME: return "time";
1205 : 0 : case EXC_DV_MODE_TEXTLEN: return "textLength";
1206 : 0 : case EXC_DV_MODE_CUSTOM: return "custom";
1207 : : }
1208 : 0 : return NULL;
1209 : : }
1210 : :
1211 : 0 : const char* lcl_GetOperatorType( sal_uInt32 nFlags )
1212 : : {
1213 [ # # # # : 0 : switch( nFlags & EXC_DV_COND_MASK )
# # # #
# ]
1214 : : {
1215 : 0 : case EXC_DV_COND_BETWEEN: return "between";
1216 : 0 : case EXC_DV_COND_NOTBETWEEN: return "notBetween";
1217 : 0 : case EXC_DV_COND_EQUAL: return "equal";
1218 : 0 : case EXC_DV_COND_NOTEQUAL: return "notEqual";
1219 : 0 : case EXC_DV_COND_GREATER: return "greaterThan";
1220 : 0 : case EXC_DV_COND_LESS: return "lessThan";
1221 : 0 : case EXC_DV_COND_EQGREATER: return "greaterThanOrEqual";
1222 : 0 : case EXC_DV_COND_EQLESS: return "lessThanOrEqual";
1223 : : }
1224 : 0 : return NULL;
1225 : : }
1226 : :
1227 : : } // namespace
1228 : :
1229 : : // ----------------------------------------------------------------------------
1230 : :
1231 : 0 : XclExpDV::XclExpDV( const XclExpRoot& rRoot, sal_uLong nScHandle ) :
1232 : : XclExpRecord( EXC_ID_DV ),
1233 : : XclExpRoot( rRoot ),
1234 : : mnFlags( 0 ),
1235 [ # # ][ # # ]: 0 : mnScHandle( nScHandle )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
1236 : : {
1237 [ # # ][ # # ]: 0 : if( const ScValidationData* pValData = GetDoc().GetValidationEntry( mnScHandle ) )
1238 : : {
1239 : : // prompt box - empty string represented by single NUL character
1240 [ # # ][ # # ]: 0 : String aTitle, aText;
1241 [ # # ]: 0 : bool bShowPrompt = (pValData->GetInput( aTitle, aText ) == sal_True);
1242 [ # # ]: 0 : if( aTitle.Len() )
1243 [ # # ]: 0 : maPromptTitle.Assign( aTitle );
1244 : : else
1245 [ # # ]: 0 : maPromptTitle.Assign( '\0' );
1246 [ # # ]: 0 : if( aText.Len() )
1247 [ # # ]: 0 : maPromptText.Assign( aText );
1248 : : else
1249 [ # # ]: 0 : maPromptText.Assign( '\0' );
1250 : :
1251 : : // error box - empty string represented by single NUL character
1252 : : ScValidErrorStyle eScErrorStyle;
1253 [ # # ]: 0 : bool bShowError = (pValData->GetErrMsg( aTitle, aText, eScErrorStyle ) == sal_True);
1254 [ # # ]: 0 : if( aTitle.Len() )
1255 [ # # ]: 0 : maErrorTitle.Assign( aTitle );
1256 : : else
1257 [ # # ]: 0 : maErrorTitle.Assign( '\0' );
1258 [ # # ]: 0 : if( aText.Len() )
1259 [ # # ]: 0 : maErrorText.Assign( aText );
1260 : : else
1261 [ # # ]: 0 : maErrorText.Assign( '\0' );
1262 : :
1263 : : // flags
1264 [ # # # # : 0 : switch( pValData->GetDataMode() )
# # # #
# ]
1265 : : {
1266 : 0 : case SC_VALID_ANY: mnFlags |= EXC_DV_MODE_ANY; break;
1267 : 0 : case SC_VALID_WHOLE: mnFlags |= EXC_DV_MODE_WHOLE; break;
1268 : 0 : case SC_VALID_DECIMAL: mnFlags |= EXC_DV_MODE_DECIMAL; break;
1269 : 0 : case SC_VALID_LIST: mnFlags |= EXC_DV_MODE_LIST; break;
1270 : 0 : case SC_VALID_DATE: mnFlags |= EXC_DV_MODE_DATE; break;
1271 : 0 : case SC_VALID_TIME: mnFlags |= EXC_DV_MODE_TIME; break;
1272 : 0 : case SC_VALID_TEXTLEN: mnFlags |= EXC_DV_MODE_TEXTLEN; break;
1273 : 0 : case SC_VALID_CUSTOM: mnFlags |= EXC_DV_MODE_CUSTOM; break;
1274 : : default: OSL_FAIL( "XclExpDV::XclExpDV - unknown mode" );
1275 : : }
1276 : :
1277 [ # # # # : 0 : switch( pValData->GetOperation() )
# # # #
# ]
1278 : : {
1279 : : case SC_COND_NONE:
1280 : 0 : case SC_COND_EQUAL: mnFlags |= EXC_DV_COND_EQUAL; break;
1281 : 0 : case SC_COND_LESS: mnFlags |= EXC_DV_COND_LESS; break;
1282 : 0 : case SC_COND_GREATER: mnFlags |= EXC_DV_COND_GREATER; break;
1283 : 0 : case SC_COND_EQLESS: mnFlags |= EXC_DV_COND_EQLESS; break;
1284 : 0 : case SC_COND_EQGREATER: mnFlags |= EXC_DV_COND_EQGREATER; break;
1285 : 0 : case SC_COND_NOTEQUAL: mnFlags |= EXC_DV_COND_NOTEQUAL; break;
1286 : 0 : case SC_COND_BETWEEN: mnFlags |= EXC_DV_COND_BETWEEN; break;
1287 : 0 : case SC_COND_NOTBETWEEN: mnFlags |= EXC_DV_COND_NOTBETWEEN; break;
1288 : : default: OSL_FAIL( "XclExpDV::XclExpDV - unknown condition" );
1289 : : }
1290 [ # # # # : 0 : switch( eScErrorStyle )
# ]
1291 : : {
1292 : 0 : case SC_VALERR_STOP: mnFlags |= EXC_DV_ERROR_STOP; break;
1293 : 0 : case SC_VALERR_WARNING: mnFlags |= EXC_DV_ERROR_WARNING; break;
1294 : 0 : case SC_VALERR_INFO: mnFlags |= EXC_DV_ERROR_INFO; break;
1295 : : case SC_VALERR_MACRO:
1296 : : // set INFO for validity with macro call, delete title
1297 : 0 : mnFlags |= EXC_DV_ERROR_INFO;
1298 [ # # ]: 0 : maErrorTitle.Assign( '\0' ); // contains macro name
1299 : 0 : break;
1300 : : default: OSL_FAIL( "XclExpDV::XclExpDV - unknown error style" );
1301 : : }
1302 : 0 : ::set_flag( mnFlags, EXC_DV_IGNOREBLANK, pValData->IsIgnoreBlank() );
1303 : 0 : ::set_flag( mnFlags, EXC_DV_SUPPRESSDROPDOWN, pValData->GetListType() == ValidListType::INVISIBLE );
1304 : 0 : ::set_flag( mnFlags, EXC_DV_SHOWPROMPT, bShowPrompt );
1305 : 0 : ::set_flag( mnFlags, EXC_DV_SHOWERROR, bShowError );
1306 : :
1307 : : // formulas
1308 [ # # ]: 0 : XclExpFormulaCompiler& rFmlaComp = GetFormulaCompiler();
1309 : 0 : boost::scoped_ptr< ScTokenArray > xScTokArr;
1310 : :
1311 : : // first formula
1312 [ # # ][ # # ]: 0 : xScTokArr.reset( pValData->CreateTokenArry( 0 ) );
1313 [ # # ]: 0 : if( xScTokArr.get() )
1314 : : {
1315 [ # # ]: 0 : if( pValData->GetDataMode() == SC_VALID_LIST )
1316 : : {
1317 [ # # ]: 0 : String aString;
1318 [ # # ][ # # ]: 0 : if( XclTokenArrayHelper::GetStringList( aString, *xScTokArr, '\n' ) )
1319 : : {
1320 : 0 : OUStringBuffer sFormulaBuf;
1321 [ # # ]: 0 : sFormulaBuf.append( (sal_Unicode) '"' );
1322 : : /* Formula is a list of string tokens -> build the Excel string.
1323 : : Data validity is BIFF8 only (important for the XclExpString object).
1324 : : Excel uses the NUL character as string list separator. */
1325 [ # # ][ # # ]: 0 : mxString1.reset( new XclExpString( EXC_STR_8BITLENGTH ) );
[ # # ]
1326 [ # # ][ # # ]: 0 : xub_StrLen nTokenCnt = comphelper::string::getTokenCount(aString, '\n');
1327 : 0 : xub_StrLen nStringIx = 0;
1328 [ # # ]: 0 : for( xub_StrLen nToken = 0; nToken < nTokenCnt; ++nToken )
1329 : : {
1330 [ # # ]: 0 : String aToken( aString.GetToken( 0, '\n', nStringIx ) );
1331 [ # # ]: 0 : if( nToken > 0 )
1332 : : {
1333 [ # # ][ # # ]: 0 : mxString1->Append(rtl::OUString(static_cast<sal_Unicode>('\0')));
[ # # ]
1334 [ # # ]: 0 : sFormulaBuf.append( (sal_Unicode) ',' );
1335 : : }
1336 [ # # ]: 0 : mxString1->Append( aToken );
1337 [ # # ][ # # ]: 0 : sFormulaBuf.append( XclXmlUtils::ToOUString( aToken ) );
1338 [ # # ]: 0 : }
1339 : 0 : ::set_flag( mnFlags, EXC_DV_STRINGLIST );
1340 : :
1341 [ # # ]: 0 : sFormulaBuf.append( (sal_Unicode) '"' );
1342 [ # # ]: 0 : msFormula1 = sFormulaBuf.makeStringAndClear();
1343 : : }
1344 : : else
1345 : : {
1346 : : /* All other formulas in validation are stored like conditional
1347 : : formatting formulas (with tRefN/tAreaN tokens as value or
1348 : : array class). But NOT the cell references and defined names
1349 : : in list validation - they are stored as reference class
1350 : : tokens... Example:
1351 : : 1) Cell must be equal to A1 -> formula is =A1 -> writes tRefNV token
1352 : : 2) List is taken from A1 -> formula is =A1 -> writes tRefNR token
1353 : : Formula compiler supports this by offering two different functions
1354 : : CreateDataValFormula() and CreateListValFormula(). */
1355 [ # # ][ # # ]: 0 : mxTokArr1 = rFmlaComp.CreateFormula( EXC_FMLATYPE_LISTVAL, *xScTokArr );
[ # # ]
1356 [ # # ]: 0 : msFormula1 = XclXmlUtils::ToOUString( GetDoc(), pValData->GetSrcPos(), xScTokArr.get() );
1357 [ # # ]: 0 : }
1358 : : }
1359 : : else
1360 : : {
1361 : : // no list validation -> convert the formula
1362 [ # # ][ # # ]: 0 : mxTokArr1 = rFmlaComp.CreateFormula( EXC_FMLATYPE_DATAVAL, *xScTokArr );
[ # # ]
1363 [ # # ]: 0 : msFormula1 = XclXmlUtils::ToOUString( GetDoc(), pValData->GetSrcPos(), xScTokArr.get() );
1364 : : }
1365 : : }
1366 : :
1367 : : // second formula
1368 [ # # ][ # # ]: 0 : xScTokArr.reset( pValData->CreateTokenArry( 1 ) );
1369 [ # # ]: 0 : if( xScTokArr.get() )
1370 : : {
1371 [ # # ][ # # ]: 0 : mxTokArr2 = rFmlaComp.CreateFormula( EXC_FMLATYPE_DATAVAL, *xScTokArr );
[ # # ]
1372 [ # # ]: 0 : msFormula2 = XclXmlUtils::ToOUString( GetDoc(), pValData->GetSrcPos(), xScTokArr.get() );
1373 [ # # ][ # # ]: 0 : }
[ # # ]
1374 : : }
1375 : : else
1376 : : {
1377 : : OSL_FAIL( "XclExpDV::XclExpDV - missing core data" );
1378 : 0 : mnScHandle = ULONG_MAX;
1379 : : }
1380 : 0 : }
1381 : :
1382 [ # # ][ # # ]: 0 : XclExpDV::~XclExpDV()
[ # # ][ # # ]
[ # # ]
1383 : : {
1384 [ # # ]: 0 : }
1385 : :
1386 : 0 : void XclExpDV::InsertCellRange( const ScRange& rRange )
1387 : : {
1388 : 0 : maScRanges.Join( rRange );
1389 : 0 : }
1390 : :
1391 : 0 : bool XclExpDV::Finalize()
1392 : : {
1393 : 0 : GetAddressConverter().ConvertRangeList( maXclRanges, maScRanges, true );
1394 [ # # ][ # # ]: 0 : return (mnScHandle != ULONG_MAX) && !maXclRanges.empty();
1395 : : }
1396 : :
1397 : 0 : void XclExpDV::WriteBody( XclExpStream& rStrm )
1398 : : {
1399 : : // flags and strings
1400 : 0 : rStrm << mnFlags << maPromptTitle << maErrorTitle << maPromptText << maErrorText;
1401 : : // condition formulas
1402 [ # # ]: 0 : if( mxString1.get() )
1403 : 0 : lclWriteDvFormula( rStrm, *mxString1 );
1404 : : else
1405 : 0 : lclWriteDvFormula( rStrm, mxTokArr1.get() );
1406 : 0 : lclWriteDvFormula( rStrm, mxTokArr2.get() );
1407 : : // cell ranges
1408 : 0 : rStrm << maXclRanges;
1409 : 0 : }
1410 : :
1411 : 0 : void XclExpDV::SaveXml( XclExpXmlStream& rStrm )
1412 : : {
1413 : 0 : sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
1414 : : rWorksheet->startElement( XML_dataValidation,
1415 : 0 : XML_allowBlank, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_DV_IGNOREBLANK ) ),
1416 [ # # ][ # # ]: 0 : XML_error, XESTRING_TO_PSZ( maErrorText ),
[ # # ][ # # ]
1417 : : // OOXTODO: XML_errorStyle,
1418 [ # # ][ # # ]: 0 : XML_errorTitle, XESTRING_TO_PSZ( maErrorTitle ),
[ # # ][ # # ]
1419 : : // OOXTODO: XML_imeMode,
1420 : : XML_operator, lcl_GetOperatorType( mnFlags ),
1421 [ # # ][ # # ]: 0 : XML_prompt, XESTRING_TO_PSZ( maPromptText ),
[ # # ][ # # ]
1422 [ # # ][ # # ]: 0 : XML_promptTitle, XESTRING_TO_PSZ( maPromptTitle ),
[ # # ][ # # ]
1423 : : // showDropDown should have been showNoDropDown - check oox/xlsx import for details
1424 : 0 : XML_showDropDown, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_DV_SUPPRESSDROPDOWN ) ),
1425 : 0 : XML_showErrorMessage, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_DV_SHOWERROR ) ),
1426 : 0 : XML_showInputMessage, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_DV_SHOWPROMPT ) ),
1427 : : XML_sqref, XclXmlUtils::ToOString( maScRanges ).getStr(),
1428 : : XML_type, lcl_GetValidationType( mnFlags ),
1429 [ # # ][ # # ]: 0 : FSEND );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # #
# ]
1430 [ # # ]: 0 : if( !msFormula1.isEmpty() )
1431 : : {
1432 : 0 : rWorksheet->startElement( XML_formula1, FSEND );
1433 : 0 : rWorksheet->writeEscaped( msFormula1 );
1434 : 0 : rWorksheet->endElement( XML_formula1 );
1435 : : }
1436 [ # # ]: 0 : if( !msFormula2.isEmpty() )
1437 : : {
1438 : 0 : rWorksheet->startElement( XML_formula2, FSEND );
1439 : 0 : rWorksheet->writeEscaped( msFormula2 );
1440 : 0 : rWorksheet->endElement( XML_formula2 );
1441 : : }
1442 : 0 : rWorksheet->endElement( XML_dataValidation );
1443 : 0 : }
1444 : :
1445 : : // ----------------------------------------------------------------------------
1446 : :
1447 : 0 : XclExpDval::XclExpDval( const XclExpRoot& rRoot ) :
1448 : : XclExpRecord( EXC_ID_DVAL, 18 ),
1449 [ # # ][ # # ]: 0 : XclExpRoot( rRoot )
[ # # ]
1450 : : {
1451 : 0 : }
1452 : :
1453 [ # # ][ # # ]: 0 : XclExpDval::~XclExpDval()
[ # # ]
1454 : : {
1455 [ # # ]: 0 : }
1456 : :
1457 : 0 : void XclExpDval::InsertCellRange( const ScRange& rRange, sal_uLong nScHandle )
1458 : : {
1459 [ # # ]: 0 : if( GetBiff() == EXC_BIFF8 )
1460 : : {
1461 : 0 : XclExpDV& rDVRec = SearchOrCreateDv( nScHandle );
1462 : 0 : rDVRec.InsertCellRange( rRange );
1463 : : }
1464 : 0 : }
1465 : :
1466 : 0 : void XclExpDval::Save( XclExpStream& rStrm )
1467 : : {
1468 : : // check all records
1469 : 0 : size_t nPos = maDVList.GetSize();
1470 [ # # ]: 0 : while( nPos )
1471 : : {
1472 : 0 : --nPos; // backwards to keep nPos valid
1473 [ # # ]: 0 : XclExpDVRef xDVRec = maDVList.GetRecord( nPos );
1474 [ # # ][ # # ]: 0 : if( !xDVRec->Finalize() )
1475 [ # # ]: 0 : maDVList.RemoveRecord( nPos );
1476 [ # # ]: 0 : }
1477 : :
1478 : : // write the DVAL and the DV's
1479 [ # # ]: 0 : if( !maDVList.IsEmpty() )
1480 : : {
1481 : 0 : XclExpRecord::Save( rStrm );
1482 : 0 : maDVList.Save( rStrm );
1483 : : }
1484 : 0 : }
1485 : :
1486 : 0 : void XclExpDval::SaveXml( XclExpXmlStream& rStrm )
1487 : : {
1488 [ # # ]: 0 : if( maDVList.IsEmpty() )
1489 : 0 : return;
1490 : :
1491 : 0 : sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
1492 : : rWorksheet->startElement( XML_dataValidations,
1493 : 0 : XML_count, OString::valueOf( (sal_Int32) maDVList.GetSize() ).getStr(),
1494 : : // OOXTODO: XML_disablePrompts,
1495 : : // OOXTODO: XML_xWindow,
1496 : : // OOXTODO: XML_yWindow,
1497 [ # # ]: 0 : FSEND );
1498 : 0 : maDVList.SaveXml( rStrm );
1499 : 0 : rWorksheet->endElement( XML_dataValidations );
1500 : : }
1501 : :
1502 : 0 : XclExpDV& XclExpDval::SearchOrCreateDv( sal_uLong nScHandle )
1503 : : {
1504 : : // test last found record
1505 [ # # ][ # # ]: 0 : if( mxLastFoundDV.get() && (mxLastFoundDV->GetScHandle() == nScHandle) )
[ # # ]
1506 : 0 : return *mxLastFoundDV;
1507 : :
1508 : : // binary search
1509 : 0 : size_t nCurrPos = 0;
1510 [ # # ]: 0 : if( !maDVList.IsEmpty() )
1511 : : {
1512 : 0 : size_t nFirstPos = 0;
1513 : 0 : size_t nLastPos = maDVList.GetSize() - 1;
1514 : 0 : bool bLoop = true;
1515 : 0 : sal_uLong nCurrScHandle = ::std::numeric_limits< sal_uLong >::max();
1516 [ # # ][ # # ]: 0 : while( (nFirstPos <= nLastPos) && bLoop )
[ # # ]
1517 : : {
1518 : 0 : nCurrPos = (nFirstPos + nLastPos) / 2;
1519 [ # # ]: 0 : mxLastFoundDV = maDVList.GetRecord( nCurrPos );
1520 : 0 : nCurrScHandle = mxLastFoundDV->GetScHandle();
1521 [ # # ]: 0 : if( nCurrScHandle == nScHandle )
1522 : 0 : bLoop = false;
1523 [ # # ]: 0 : else if( nCurrScHandle < nScHandle )
1524 : 0 : nFirstPos = nCurrPos + 1;
1525 [ # # ]: 0 : else if( nCurrPos )
1526 : 0 : nLastPos = nCurrPos - 1;
1527 : : else // special case for nLastPos = -1
1528 : 0 : bLoop = false;
1529 : : }
1530 [ # # ]: 0 : if( nCurrScHandle == nScHandle )
1531 : 0 : return *mxLastFoundDV;
1532 [ # # ]: 0 : else if( nCurrScHandle < nScHandle )
1533 : 0 : ++nCurrPos;
1534 : : }
1535 : :
1536 : : // create new DV record
1537 [ # # ]: 0 : mxLastFoundDV.reset( new XclExpDV( *this, nScHandle ) );
1538 [ # # ]: 0 : maDVList.InsertRecord( mxLastFoundDV, nCurrPos );
1539 : 0 : return *mxLastFoundDV;
1540 : : }
1541 : :
1542 : 0 : void XclExpDval::WriteBody( XclExpStream& rStrm )
1543 : : {
1544 : 0 : rStrm.WriteZeroBytes( 10 );
1545 : 0 : rStrm << EXC_DVAL_NOOBJ << static_cast< sal_uInt32 >( maDVList.GetSize() );
1546 : 0 : }
1547 : :
1548 : : // Web Queries ================================================================
1549 : :
1550 : 0 : XclExpWebQuery::XclExpWebQuery(
1551 : : const String& rRangeName,
1552 : : const String& rUrl,
1553 : : const String& rSource,
1554 : : sal_Int32 nRefrSecs ) :
1555 : : maDestRange( rRangeName ),
1556 : : maUrl( rUrl ),
1557 : : // refresh delay time: seconds -> minutes
1558 [ # # ]: 0 : mnRefresh( ulimit_cast< sal_Int16 >( (nRefrSecs + 59L) / 60L ) ),
1559 [ # # ][ # # ]: 0 : mbEntireDoc( false )
[ # # ]
1560 : : {
1561 : : // comma separated list of HTML table names or indexes
1562 [ # # ][ # # ]: 0 : xub_StrLen nTokenCnt = comphelper::string::getTokenCount(rSource, ';');
1563 [ # # ][ # # ]: 0 : String aNewTables, aAppendTable;
1564 : 0 : xub_StrLen nStringIx = 0;
1565 : 0 : bool bExitLoop = false;
1566 [ # # ][ # # ]: 0 : for( xub_StrLen nToken = 0; (nToken < nTokenCnt) && !bExitLoop; ++nToken )
[ # # ]
1567 : : {
1568 [ # # ]: 0 : String aToken( rSource.GetToken( 0, ';', nStringIx ) );
1569 [ # # ]: 0 : mbEntireDoc = ScfTools::IsHTMLDocName( aToken );
1570 [ # # ][ # # ]: 0 : bExitLoop = mbEntireDoc || ScfTools::IsHTMLTablesName( aToken );
[ # # ]
1571 [ # # ][ # # ]: 0 : if( !bExitLoop && ScfTools::GetHTMLNameFromName( aToken, aAppendTable ) )
[ # # ][ # # ]
1572 [ # # ]: 0 : ScGlobal::AddToken( aNewTables, aAppendTable, ',' );
1573 [ # # ]: 0 : }
1574 : :
1575 [ # # ]: 0 : if( !bExitLoop ) // neither HTML_all nor HTML_tables found
1576 : : {
1577 [ # # ]: 0 : if( aNewTables.Len() )
1578 [ # # ][ # # ]: 0 : mxQryTables.reset( new XclExpString( aNewTables ) );
[ # # ]
1579 : : else
1580 : 0 : mbEntireDoc = true;
1581 [ # # ][ # # ]: 0 : }
1582 : 0 : }
1583 : :
1584 [ # # ]: 0 : XclExpWebQuery::~XclExpWebQuery()
1585 : : {
1586 [ # # ]: 0 : }
1587 : :
1588 : 0 : void XclExpWebQuery::Save( XclExpStream& rStrm )
1589 : : {
1590 : : OSL_ENSURE( !mbEntireDoc || !mxQryTables.get(), "XclExpWebQuery::Save - illegal mode" );
1591 : : sal_uInt16 nFlags;
1592 : :
1593 : : // QSI record
1594 [ # # ][ # # ]: 0 : rStrm.StartRecord( EXC_ID_QSI, 10 + maDestRange.GetSize() );
1595 [ # # ]: 0 : rStrm << EXC_QSI_DEFAULTFLAGS
1596 [ # # ]: 0 : << sal_uInt16( 0x0010 )
1597 [ # # ]: 0 : << sal_uInt16( 0x0012 )
1598 [ # # ]: 0 : << sal_uInt32( 0x00000000 )
1599 [ # # ]: 0 : << maDestRange;
1600 [ # # ]: 0 : rStrm.EndRecord();
1601 : :
1602 : : // PARAMQRY record
1603 : 0 : nFlags = 0;
1604 : 0 : ::insert_value( nFlags, EXC_PQRYTYPE_WEBQUERY, 0, 3 );
1605 : 0 : ::set_flag( nFlags, EXC_PQRY_WEBQUERY );
1606 : 0 : ::set_flag( nFlags, EXC_PQRY_TABLES, !mbEntireDoc );
1607 [ # # ]: 0 : rStrm.StartRecord( EXC_ID_PQRY, 12 );
1608 [ # # ]: 0 : rStrm << nFlags
1609 [ # # ]: 0 : << sal_uInt16( 0x0000 )
1610 [ # # ]: 0 : << sal_uInt16( 0x0001 );
1611 [ # # ]: 0 : rStrm.WriteZeroBytes( 6 );
1612 [ # # ]: 0 : rStrm.EndRecord();
1613 : :
1614 : : // WQSTRING record
1615 [ # # ][ # # ]: 0 : rStrm.StartRecord( EXC_ID_WQSTRING, maUrl.GetSize() );
1616 [ # # ]: 0 : rStrm << maUrl;
1617 [ # # ]: 0 : rStrm.EndRecord();
1618 : :
1619 : : // unknown record 0x0802
1620 [ # # ][ # # ]: 0 : rStrm.StartRecord( EXC_ID_0802, 16 + maDestRange.GetSize() );
1621 [ # # ]: 0 : rStrm << EXC_ID_0802; // repeated record id ?!?
1622 [ # # ]: 0 : rStrm.WriteZeroBytes( 6 );
1623 [ # # ]: 0 : rStrm << sal_uInt16( 0x0003 )
1624 [ # # ]: 0 : << sal_uInt32( 0x00000000 )
1625 [ # # ]: 0 : << sal_uInt16( 0x0010 )
1626 [ # # ]: 0 : << maDestRange;
1627 [ # # ]: 0 : rStrm.EndRecord();
1628 : :
1629 : : // WEBQRYSETTINGS record
1630 [ # # ]: 0 : nFlags = mxQryTables.get() ? EXC_WQSETT_SPECTABLES : EXC_WQSETT_ALL;
1631 [ # # ]: 0 : rStrm.StartRecord( EXC_ID_WQSETT, 28 );
1632 [ # # ]: 0 : rStrm << EXC_ID_WQSETT // repeated record id ?!?
1633 [ # # ]: 0 : << sal_uInt16( 0x0000 )
1634 [ # # ]: 0 : << sal_uInt16( 0x0004 )
1635 [ # # ]: 0 : << sal_uInt16( 0x0000 )
1636 [ # # ]: 0 : << EXC_WQSETT_DEFAULTFLAGS
1637 [ # # ]: 0 : << nFlags;
1638 [ # # ]: 0 : rStrm.WriteZeroBytes( 10 );
1639 [ # # ]: 0 : rStrm << mnRefresh // refresh delay in minutes
1640 [ # # ]: 0 : << EXC_WQSETT_FORMATFULL
1641 [ # # ]: 0 : << sal_uInt16( 0x0000 );
1642 [ # # ]: 0 : rStrm.EndRecord();
1643 : :
1644 : : // WEBQRYTABLES record
1645 [ # # ]: 0 : if( mxQryTables.get() )
1646 : : {
1647 [ # # ][ # # ]: 0 : rStrm.StartRecord( EXC_ID_WQTABLES, 4 + mxQryTables->GetSize() );
1648 [ # # ]: 0 : rStrm << EXC_ID_WQTABLES // repeated record id ?!?
1649 [ # # ]: 0 : << sal_uInt16( 0x0000 )
1650 [ # # ]: 0 : << *mxQryTables; // comma separated list of source tables
1651 [ # # ]: 0 : rStrm.EndRecord();
1652 : : }
1653 : 0 : }
1654 : :
1655 : : // ----------------------------------------------------------------------------
1656 : :
1657 : 0 : XclExpWebQueryBuffer::XclExpWebQueryBuffer( const XclExpRoot& rRoot )
1658 : : {
1659 : 0 : SCTAB nScTab = rRoot.GetCurrScTab();
1660 [ # # ]: 0 : SfxObjectShell* pShell = rRoot.GetDocShell();
1661 [ # # ]: 0 : if( !pShell ) return;
1662 [ # # ][ # # ]: 0 : ScfPropertySet aModelProp( pShell->GetModel() );
1663 [ # # ]: 0 : if( !aModelProp.Is() ) return;
1664 : :
1665 : 0 : Reference< XAreaLinks > xAreaLinks;
1666 [ # # ][ # # ]: 0 : aModelProp.GetProperty( xAreaLinks, CREATE_OUSTRING( SC_UNO_AREALINKS ) );
1667 [ # # ]: 0 : Reference< XIndexAccess > xLinksIA( xAreaLinks, UNO_QUERY );
1668 [ # # ]: 0 : if( !xLinksIA.is() ) return;
1669 : :
1670 [ # # ][ # # ]: 0 : for( sal_Int32 nIndex = 0, nCount = xLinksIA->getCount(); nIndex < nCount; ++nIndex )
[ # # ]
1671 : : {
1672 [ # # ][ # # ]: 0 : Reference< XAreaLink > xAreaLink( xLinksIA->getByIndex( nIndex ), UNO_QUERY );
[ # # ]
1673 [ # # ]: 0 : if( xAreaLink.is() )
1674 : : {
1675 [ # # ][ # # ]: 0 : CellRangeAddress aDestRange( xAreaLink->getDestArea() );
1676 [ # # ]: 0 : if( static_cast< SCTAB >( aDestRange.Sheet ) == nScTab )
1677 : : {
1678 [ # # ]: 0 : ScfPropertySet aLinkProp( xAreaLink );
1679 : 0 : OUString aFilter;
1680 [ # # ]: 0 : if( aLinkProp.GetProperty( aFilter, CREATE_OUSTRING( SC_UNONAME_FILTER ) ) &&
[ # # # # ]
[ # # ]
[ # # # # ]
[ # # ]
1681 [ # # ][ # # ]: 0 : (aFilter == CREATE_OUSTRING( EXC_WEBQRY_FILTER )) )
[ # # ]
1682 : : {
1683 : : // get properties
1684 : 0 : OUString /*aFilterOpt,*/ aUrl;
1685 : 0 : sal_Int32 nRefresh = 0;
1686 : :
1687 : : // aLinkProp.GetProperty( aFilterOpt, CREATE_OUSTRING( SC_UNONAME_FILTOPT ) );
1688 [ # # ][ # # ]: 0 : aLinkProp.GetProperty( aUrl, CREATE_OUSTRING( SC_UNONAME_LINKURL ) );
1689 [ # # ][ # # ]: 0 : aLinkProp.GetProperty( nRefresh, CREATE_OUSTRING( SC_UNONAME_REFDELAY ) );
1690 : :
1691 [ # # ][ # # ]: 0 : String aAbsDoc( ScGlobal::GetAbsDocName( aUrl, pShell ) );
[ # # ]
1692 [ # # ][ # # ]: 0 : INetURLObject aUrlObj( aAbsDoc );
1693 [ # # ][ # # ]: 0 : String aWebQueryUrl( aUrlObj.getFSysPath( INetURLObject::FSYS_DOS ) );
1694 [ # # ]: 0 : if( !aWebQueryUrl.Len() )
1695 [ # # ]: 0 : aWebQueryUrl = aAbsDoc;
1696 : :
1697 : : // find range or create a new range
1698 [ # # ]: 0 : String aRangeName;
1699 : 0 : ScRange aScDestRange;
1700 : 0 : ScUnoConversion::FillScRange( aScDestRange, aDestRange );
1701 [ # # ][ # # ]: 0 : if( const ScRangeData* pRangeData = rRoot.GetNamedRanges().findByRange( aScDestRange ) )
[ # # ]
1702 : : {
1703 [ # # ]: 0 : aRangeName = pRangeData->GetName();
1704 : : }
1705 : : else
1706 : : {
1707 [ # # ]: 0 : XclExpFormulaCompiler& rFmlaComp = rRoot.GetFormulaCompiler();
1708 [ # # ]: 0 : XclExpNameManager& rNameMgr = rRoot.GetNameManager();
1709 : :
1710 : : // create a new unique defined name containing the range
1711 [ # # ]: 0 : XclTokenArrayRef xTokArr = rFmlaComp.CreateFormula( EXC_FMLATYPE_WQUERY, aScDestRange );
1712 [ # # ][ # # ]: 0 : sal_uInt16 nNameIdx = rNameMgr.InsertUniqueName( aUrlObj.getBase(), xTokArr, nScTab );
[ # # ][ # # ]
[ # # ][ # # ]
1713 [ # # ][ # # ]: 0 : aRangeName = rNameMgr.GetOrigName( nNameIdx );
[ # # ]
1714 : : }
1715 : :
1716 : : // create and store the web query record
1717 [ # # ]: 0 : if( aRangeName.Len() )
1718 : : AppendNewRecord( new XclExpWebQuery(
1719 [ # # ][ # # ]: 0 : aRangeName, aWebQueryUrl, xAreaLink->getSourceArea(), nRefresh ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1720 [ # # ]: 0 : }
1721 : : }
1722 : : }
1723 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
1724 [ + - ][ + - ]: 24 : }
1725 : :
1726 : : // ============================================================================
1727 : :
1728 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|