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