Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "xlroot.hxx"
21 : #include <rtl/strbuf.hxx>
22 : #include <com/sun/star/awt/XDevice.hpp>
23 : #include <com/sun/star/frame/Desktop.hpp>
24 : #include <com/sun/star/frame/XFrame.hpp>
25 : #include <com/sun/star/frame/XFramesSupplier.hpp>
26 : #include <com/sun/star/i18n/ScriptType.hpp>
27 : #include <comphelper/processfactory.hxx>
28 : #include <vcl/svapp.hxx>
29 : #include <svl/stritem.hxx>
30 : #include <svl/languageoptions.hxx>
31 : #include <sfx2/objsh.hxx>
32 : #include <sfx2/printer.hxx>
33 : #include <sfx2/docfile.hxx>
34 : #include <vcl/font.hxx>
35 : #include <vcl/settings.hxx>
36 :
37 : #include <editeng/editstat.hxx>
38 : #include "scitems.hxx"
39 : #include <editeng/eeitem.hxx>
40 : #include "document.hxx"
41 : #include "docpool.hxx"
42 : #include "docuno.hxx"
43 : #include "editutil.hxx"
44 : #include "drwlayer.hxx"
45 : #include "scextopt.hxx"
46 : #include "patattr.hxx"
47 : #include "fapihelper.hxx"
48 : #include "xlconst.hxx"
49 : #include "xlstyle.hxx"
50 : #include "xlchart.hxx"
51 : #include "xltracer.hxx"
52 : #include <unotools/useroptions.hxx>
53 : #include "root.hxx"
54 :
55 : namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
56 :
57 : using ::com::sun::star::uno::Exception;
58 : using ::com::sun::star::uno::Reference;
59 : using ::com::sun::star::uno::UNO_QUERY_THROW;
60 : using ::com::sun::star::uno::UNO_SET_THROW;
61 : using ::com::sun::star::awt::XDevice;
62 : using ::com::sun::star::awt::DeviceInfo;
63 : using ::com::sun::star::frame::XFrame;
64 : using ::com::sun::star::frame::XFramesSupplier;
65 : using ::com::sun::star::lang::XMultiServiceFactory;
66 :
67 : using namespace ::com::sun::star;
68 :
69 : // Global data ================================================================
70 :
71 : #ifdef DBG_UTIL
72 : XclDebugObjCounter::~XclDebugObjCounter()
73 : {
74 : OSL_ENSURE( mnObjCnt == 0, "XclDebugObjCounter::~XclDebugObjCounter - wrong root object count" );
75 : }
76 : #endif
77 :
78 156 : XclRootData::XclRootData( XclBiff eBiff, SfxMedium& rMedium,
79 : tools::SvRef<SotStorage> xRootStrg, ScDocument& rDoc, rtl_TextEncoding eTextEnc, bool bExport ) :
80 : meBiff( eBiff ),
81 : meOutput( EXC_OUTPUT_BINARY ),
82 : mrMedium( rMedium ),
83 : mxRootStrg( xRootStrg ),
84 : mrDoc( rDoc ),
85 : maDocImport(mrDoc),
86 : maDefPassword( "VelvetSweatshop" ),
87 : meTextEnc( eTextEnc ),
88 156 : meSysLang( Application::GetSettings().GetLanguageTag().getLanguageType() ),
89 156 : meDocLang( Application::GetSettings().GetLanguageTag().getLanguageType() ),
90 156 : meUILang( Application::GetSettings().GetUILanguageTag().getLanguageType() ),
91 : mnDefApiScript( ApiScriptType::LATIN ),
92 : maScMaxPos( MAXCOL, MAXROW, MAXTAB ),
93 : maXclMaxPos( EXC_MAXCOL2, EXC_MAXROW2, EXC_MAXTAB2 ),
94 : maMaxPos( EXC_MAXCOL2, EXC_MAXROW2, EXC_MAXTAB2 ),
95 156 : mxFontPropSetHlp( new XclFontPropSetHelper ),
96 156 : mxChPropSetHlp( new XclChPropSetHelper ),
97 156 : mxRD( new RootData ),
98 : mfScreenPixelX( 50.0 ),
99 : mfScreenPixelY( 50.0 ),
100 : mnCharWidth( 110 ),
101 : mnScTab( 0 ),
102 1092 : mbExport( bExport )
103 : {
104 156 : maUserName = SvtUserOptions().GetLastName();
105 156 : if( maUserName.isEmpty() )
106 112 : maUserName = "Calc";
107 :
108 156 : switch( ScGlobal::GetDefaultScriptType() )
109 : {
110 156 : case SvtScriptType::LATIN: mnDefApiScript = ApiScriptType::LATIN; break;
111 0 : case SvtScriptType::ASIAN: mnDefApiScript = ApiScriptType::ASIAN; break;
112 0 : case SvtScriptType::COMPLEX: mnDefApiScript = ApiScriptType::COMPLEX; break;
113 : default: SAL_WARN( "sc", "XclRootData::XclRootData - unknown script type" );
114 : }
115 :
116 : // maximum cell position
117 156 : switch( meBiff )
118 : {
119 0 : case EXC_BIFF2: maXclMaxPos.Set( EXC_MAXCOL2, EXC_MAXROW2, EXC_MAXTAB2 ); break;
120 0 : case EXC_BIFF3: maXclMaxPos.Set( EXC_MAXCOL3, EXC_MAXROW3, EXC_MAXTAB3 ); break;
121 0 : case EXC_BIFF4: maXclMaxPos.Set( EXC_MAXCOL4, EXC_MAXROW4, EXC_MAXTAB4 ); break;
122 3 : case EXC_BIFF5: maXclMaxPos.Set( EXC_MAXCOL5, EXC_MAXROW5, EXC_MAXTAB5 ); break;
123 153 : case EXC_BIFF8: maXclMaxPos.Set( EXC_MAXCOL8, EXC_MAXROW8, EXC_MAXTAB8 ); break;
124 : default: DBG_ERROR_BIFF();
125 : }
126 156 : maMaxPos.SetCol( ::std::min( maScMaxPos.Col(), maXclMaxPos.Col() ) );
127 156 : maMaxPos.SetRow( ::std::min( maScMaxPos.Row(), maXclMaxPos.Row() ) );
128 156 : maMaxPos.SetTab( ::std::min( maScMaxPos.Tab(), maXclMaxPos.Tab() ) );
129 :
130 : // document URL and path
131 156 : if( const SfxItemSet* pItemSet = mrMedium.GetItemSet() )
132 156 : if( const SfxStringItem* pItem = static_cast< const SfxStringItem* >( pItemSet->GetItem( SID_FILE_NAME ) ) )
133 156 : maDocUrl = pItem->GetValue();
134 156 : maBasePath = maDocUrl.copy( 0, maDocUrl.lastIndexOf( '/' ) + 1 );
135 :
136 : // extended document options - always own object, try to copy existing data from document
137 156 : if( const ScExtDocOptions* pOldDocOpt = mrDoc.GetExtDocOptions() )
138 9 : mxExtDocOpt.reset( new ScExtDocOptions( *pOldDocOpt ) );
139 : else
140 147 : mxExtDocOpt.reset( new ScExtDocOptions );
141 :
142 : // screen pixel size
143 : try
144 : {
145 156 : Reference< frame::XDesktop2 > xFramesSupp = frame::Desktop::create( ::comphelper::getProcessComponentContext() );
146 312 : Reference< XFrame > xFrame( xFramesSupp->getActiveFrame(), UNO_SET_THROW );
147 50 : Reference< XDevice > xDevice( xFrame->getContainerWindow(), UNO_QUERY_THROW );
148 25 : DeviceInfo aDeviceInfo = xDevice->getInfo();
149 25 : mfScreenPixelX = (aDeviceInfo.PixelPerMeterX > 0) ? (100000.0 / aDeviceInfo.PixelPerMeterX) : 50.0;
150 181 : mfScreenPixelY = (aDeviceInfo.PixelPerMeterY > 0) ? (100000.0 / aDeviceInfo.PixelPerMeterY) : 50.0;
151 : }
152 131 : catch( const Exception& e)
153 : {
154 : SAL_WARN( "sc", "XclRootData::XclRootData - cannot get output device info: " << e.Message );
155 : }
156 156 : }
157 :
158 156 : XclRootData::~XclRootData()
159 : {
160 156 : }
161 :
162 156 : XclRoot::XclRoot( XclRootData& rRootData ) :
163 156 : mrData( rRootData )
164 : {
165 : #if defined(DBG_UTIL) && OSL_DEBUG_LEVEL > 0
166 : ++mrData.mnObjCnt;
167 : #endif
168 :
169 : // filter tracer
170 156 : mrData.mxTracer.reset( new XclTracer( GetDocUrl() ) );
171 156 : }
172 :
173 129751 : XclRoot::XclRoot( const XclRoot& rRoot ) :
174 129751 : mrData( rRoot.mrData )
175 : {
176 : #if defined(DBG_UTIL) && OSL_DEBUG_LEVEL > 0
177 : ++mrData.mnObjCnt;
178 : #endif
179 129751 : }
180 :
181 129900 : XclRoot::~XclRoot()
182 : {
183 : #if defined(DBG_UTIL) && OSL_DEBUG_LEVEL > 0
184 : --mrData.mnObjCnt;
185 : #endif
186 129900 : }
187 :
188 0 : XclRoot& XclRoot::operator=( const XclRoot& rRoot )
189 : {
190 : (void)rRoot; // avoid compiler warning
191 : // allowed for assignment in derived classes - but test if the same root data is used
192 : OSL_ENSURE( &mrData == &rRoot.mrData, "XclRoot::operator= - incompatible root data" );
193 0 : return *this;
194 : }
195 :
196 1582 : void XclRoot::SetTextEncoding( rtl_TextEncoding eTextEnc )
197 : {
198 1582 : if( eTextEnc != RTL_TEXTENCODING_DONTKNOW )
199 1504 : mrData.meTextEnc = eTextEnc;
200 1582 : }
201 :
202 238 : void XclRoot::SetCharWidth( const XclFontData& rFontData )
203 : {
204 238 : mrData.mnCharWidth = 0;
205 238 : if( OutputDevice* pPrinter = GetPrinter() )
206 : {
207 238 : vcl::Font aFont( rFontData.maName, Size( 0, rFontData.mnHeight ) );
208 238 : aFont.SetFamily( rFontData.GetScFamily( GetTextEncoding() ) );
209 238 : aFont.SetCharSet( rFontData.GetFontEncoding() );
210 238 : aFont.SetWeight( rFontData.GetScWeight() );
211 238 : pPrinter->SetFont( aFont );
212 238 : mrData.mnCharWidth = pPrinter->GetTextWidth( OUString('0') );
213 : }
214 238 : if( mrData.mnCharWidth <= 0 )
215 : {
216 : // #i48717# Win98 with HP LaserJet returns 0
217 : SAL_WARN( "sc", "XclRoot::SetCharWidth - invalid character width (no printer?)" );
218 0 : mrData.mnCharWidth = 11 * rFontData.mnHeight / 20;
219 : }
220 238 : }
221 :
222 72 : sal_Int32 XclRoot::GetHmmFromPixelX( double fPixelX ) const
223 : {
224 72 : return static_cast< sal_Int32 >( fPixelX * mrData.mfScreenPixelX + 0.5 );
225 : }
226 :
227 72 : sal_Int32 XclRoot::GetHmmFromPixelY( double fPixelY ) const
228 : {
229 72 : return static_cast< sal_Int32 >( fPixelY * mrData.mfScreenPixelY + 0.5 );
230 : }
231 :
232 0 : uno::Sequence< beans::NamedValue > XclRoot::RequestEncryptionData( ::comphelper::IDocPasswordVerifier& rVerifier ) const
233 : {
234 0 : ::std::vector< OUString > aDefaultPasswords;
235 0 : aDefaultPasswords.push_back( mrData.maDefPassword );
236 0 : return ScfApiHelper::QueryEncryptionDataForMedium( mrData.mrMedium, rVerifier, &aDefaultPasswords );
237 : }
238 :
239 46 : bool XclRoot::HasVbaStorage() const
240 : {
241 46 : tools::SvRef<SotStorage> xRootStrg = GetRootStorage();
242 46 : return xRootStrg.Is() && xRootStrg->IsContained( EXC_STORAGE_VBA_PROJECT );
243 : }
244 :
245 2 : tools::SvRef<SotStorage> XclRoot::OpenStorage( tools::SvRef<SotStorage> xStrg, const OUString& rStrgName ) const
246 : {
247 : return mrData.mbExport ?
248 : ScfTools::OpenStorageWrite( xStrg, rStrgName ) :
249 2 : ScfTools::OpenStorageRead( xStrg, rStrgName );
250 : }
251 :
252 2 : tools::SvRef<SotStorage> XclRoot::OpenStorage( const OUString& rStrgName ) const
253 : {
254 2 : return OpenStorage( GetRootStorage(), rStrgName );
255 : }
256 :
257 129 : tools::SvRef<SotStorageStream> XclRoot::OpenStream( tools::SvRef<SotStorage> xStrg, const OUString& rStrmName ) const
258 : {
259 : return mrData.mbExport ?
260 : ScfTools::OpenStorageStreamWrite( xStrg, rStrmName ) :
261 129 : ScfTools::OpenStorageStreamRead( xStrg, rStrmName );
262 : }
263 :
264 127 : tools::SvRef<SotStorageStream> XclRoot::OpenStream( const OUString& rStrmName ) const
265 : {
266 127 : return OpenStream( GetRootStorage(), rStrmName );
267 : }
268 :
269 368169 : ScDocument& XclRoot::GetDoc() const
270 : {
271 368169 : return mrData.mrDoc;
272 : }
273 :
274 640 : ScDocument* XclRoot::GetDocPtr() const
275 : {
276 640 : return &mrData.mrDoc;
277 : }
278 :
279 1074 : SfxObjectShell* XclRoot::GetDocShell() const
280 : {
281 1074 : return GetDoc().GetDocumentShell();
282 : }
283 :
284 87 : ScModelObj* XclRoot::GetDocModelObj() const
285 : {
286 87 : SfxObjectShell* pDocShell = GetDocShell();
287 87 : return pDocShell ? ScModelObj::getImplementation( pDocShell->GetModel() ) : 0;
288 : }
289 :
290 1422 : OutputDevice* XclRoot::GetPrinter() const
291 : {
292 1422 : return GetDoc().GetRefDevice();
293 : }
294 :
295 1435 : ScStyleSheetPool& XclRoot::GetStyleSheetPool() const
296 : {
297 1435 : return *GetDoc().GetStyleSheetPool();
298 : }
299 :
300 72 : ScRangeName& XclRoot::GetNamedRanges() const
301 : {
302 72 : return *GetDoc().GetRangeName();
303 : }
304 :
305 219 : SdrPage* XclRoot::GetSdrPage( SCTAB nScTab ) const
306 : {
307 219 : return ((nScTab >= 0) && GetDoc().GetDrawLayer()) ?
308 436 : GetDoc().GetDrawLayer()->GetPage( static_cast< sal_uInt16 >( nScTab ) ) : 0;
309 : }
310 :
311 2198 : SvNumberFormatter& XclRoot::GetFormatter() const
312 : {
313 2198 : return *GetDoc().GetFormatTable();
314 : }
315 :
316 1 : DateTime XclRoot::GetNullDate() const
317 : {
318 1 : return *GetFormatter().GetNullDate();
319 : }
320 :
321 0 : sal_uInt16 XclRoot::GetBaseYear() const
322 : {
323 : // return 1904 for 1904-01-01, and 1900 for 1899-12-30
324 0 : return (GetNullDate().GetYear() == 1904) ? 1904 : 1900;
325 : }
326 :
327 0 : double XclRoot::GetDoubleFromDateTime( const DateTime& rDateTime ) const
328 : {
329 0 : double fValue = rDateTime - GetNullDate();
330 : // adjust dates before 1900-03-01 to get correct time values in the range [0.0,1.0)
331 0 : if( rDateTime < DateTime( Date( 1, 3, 1900 ) ) )
332 0 : fValue -= 1.0;
333 0 : return fValue;
334 : }
335 :
336 1 : DateTime XclRoot::GetDateTimeFromDouble( double fValue ) const
337 : {
338 1 : DateTime aDateTime = GetNullDate() + fValue;
339 : // adjust dates before 1900-03-01 to get correct time values
340 1 : if( aDateTime < DateTime( Date( 1, 3, 1900 ) ) )
341 1 : aDateTime += 1L;
342 1 : return aDateTime;
343 : }
344 :
345 65 : ScEditEngineDefaulter& XclRoot::GetEditEngine() const
346 : {
347 65 : if( !mrData.mxEditEngine.get() )
348 : {
349 9 : mrData.mxEditEngine.reset( new ScEditEngineDefaulter( GetDoc().GetEnginePool() ) );
350 9 : ScEditEngineDefaulter& rEE = *mrData.mxEditEngine;
351 9 : rEE.SetRefMapMode( MAP_100TH_MM );
352 9 : rEE.SetEditTextObjectPool( GetDoc().GetEditPool() );
353 9 : rEE.SetUpdateMode( false );
354 9 : rEE.EnableUndo( false );
355 9 : rEE.SetControlWord( rEE.GetControlWord() & ~EEControlBits::ALLOWBIGOBJS );
356 : }
357 65 : return *mrData.mxEditEngine;
358 : }
359 :
360 353 : ScHeaderEditEngine& XclRoot::GetHFEditEngine() const
361 : {
362 353 : if( !mrData.mxHFEditEngine.get() )
363 : {
364 154 : mrData.mxHFEditEngine.reset( new ScHeaderEditEngine( EditEngine::CreatePool(), true ) );
365 154 : ScHeaderEditEngine& rEE = *mrData.mxHFEditEngine;
366 154 : rEE.SetRefMapMode( MAP_TWIP ); // headers/footers use twips as default metric
367 154 : rEE.SetUpdateMode( false );
368 154 : rEE.EnableUndo( false );
369 154 : rEE.SetControlWord( rEE.GetControlWord() & ~EEControlBits::ALLOWBIGOBJS );
370 :
371 : // set Calc header/footer defaults
372 154 : SfxItemSet* pEditSet = new SfxItemSet( rEE.GetEmptyItemSet() );
373 154 : SfxItemSet aItemSet( *GetDoc().GetPool(), ATTR_PATTERN_START, ATTR_PATTERN_END );
374 154 : ScPatternAttr::FillToEditItemSet( *pEditSet, aItemSet );
375 : // FillToEditItemSet() adjusts font height to 1/100th mm, we need twips
376 154 : pEditSet->Put( aItemSet.Get( ATTR_FONT_HEIGHT ), EE_CHAR_FONTHEIGHT );
377 154 : pEditSet->Put( aItemSet.Get( ATTR_CJK_FONT_HEIGHT ), EE_CHAR_FONTHEIGHT_CJK );
378 154 : pEditSet->Put( aItemSet.Get( ATTR_CTL_FONT_HEIGHT ), EE_CHAR_FONTHEIGHT_CTL );
379 154 : rEE.SetDefaults( pEditSet ); // takes ownership
380 : }
381 353 : return *mrData.mxHFEditEngine;
382 : }
383 :
384 15 : EditEngine& XclRoot::GetDrawEditEngine() const
385 : {
386 15 : if( !mrData.mxDrawEditEng.get() )
387 : {
388 10 : mrData.mxDrawEditEng.reset( new EditEngine( &GetDoc().GetDrawLayer()->GetItemPool() ) );
389 10 : EditEngine& rEE = *mrData.mxDrawEditEng;
390 10 : rEE.SetRefMapMode( MAP_100TH_MM );
391 10 : rEE.SetUpdateMode( false );
392 10 : rEE.EnableUndo( false );
393 10 : rEE.SetControlWord( rEE.GetControlWord() & ~EEControlBits::ALLOWBIGOBJS );
394 : }
395 15 : return *mrData.mxDrawEditEng;
396 : }
397 :
398 302 : XclFontPropSetHelper& XclRoot::GetFontPropSetHelper() const
399 : {
400 302 : return *mrData.mxFontPropSetHlp;
401 : }
402 :
403 980 : XclChPropSetHelper& XclRoot::GetChartPropSetHelper() const
404 : {
405 980 : return *mrData.mxChPropSetHlp;
406 : }
407 :
408 1627 : ScExtDocOptions& XclRoot::GetExtDocOptions() const
409 : {
410 1627 : return *mrData.mxExtDocOpt;
411 : }
412 :
413 3521 : XclTracer& XclRoot::GetTracer() const
414 : {
415 3521 : return *mrData.mxTracer;
416 30 : }
417 :
418 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|