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