LanguageTool: don't crash if REST protocol isn't set
[LibreOffice.git] / sc / source / filter / excel / xlroot.cxx
blobbac3ca1b3f59eafcddf86f15e16d41a26441ac15
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <memory>
21 #include <xlroot.hxx>
22 #include <sal/log.hxx>
23 #include <com/sun/star/awt/XDevice.hpp>
24 #include <com/sun/star/frame/Desktop.hpp>
25 #include <com/sun/star/frame/XFrame.hpp>
26 #include <com/sun/star/i18n/ScriptType.hpp>
27 #include <comphelper/processfactory.hxx>
28 #include <comphelper/servicehelper.hxx>
29 #include <sot/storage.hxx>
30 #include <vcl/svapp.hxx>
31 #include <svl/numformat.hxx>
32 #include <svl/stritem.hxx>
33 #include <svl/languageoptions.hxx>
34 #include <sfx2/objsh.hxx>
35 #include <sfx2/docfile.hxx>
36 #include <sfx2/sfxsids.hrc>
37 #include <vcl/font.hxx>
38 #include <vcl/settings.hxx>
39 #include <tools/diagnose_ex.h>
41 #include <editeng/editstat.hxx>
42 #include <scitems.hxx>
43 #include <editeng/eeitem.hxx>
44 #include <editeng/fhgtitem.hxx>
45 #include <document.hxx>
46 #include <docpool.hxx>
47 #include <docuno.hxx>
48 #include <editutil.hxx>
49 #include <drwlayer.hxx>
50 #include <scextopt.hxx>
51 #include <patattr.hxx>
52 #include <fapihelper.hxx>
53 #include <xlconst.hxx>
54 #include <xlstyle.hxx>
55 #include <xlchart.hxx>
56 #include <xltracer.hxx>
57 #include <xltools.hxx>
58 #include <unotools/configmgr.hxx>
59 #include <unotools/useroptions.hxx>
60 #include <root.hxx>
62 namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
64 using ::com::sun::star::uno::Exception;
65 using ::com::sun::star::uno::Reference;
66 using ::com::sun::star::uno::UNO_QUERY_THROW;
67 using ::com::sun::star::uno::UNO_SET_THROW;
68 using ::com::sun::star::awt::XDevice;
69 using ::com::sun::star::awt::DeviceInfo;
70 using ::com::sun::star::frame::XFrame;
72 using namespace ::com::sun::star;
74 // Global data ================================================================
76 #ifdef DBG_UTIL
77 XclDebugObjCounter::~XclDebugObjCounter()
79 OSL_ENSURE( mnObjCnt == 0, "XclDebugObjCounter::~XclDebugObjCounter - wrong root object count" );
81 #endif
83 XclRootData::XclRootData( XclBiff eBiff, SfxMedium& rMedium,
84 tools::SvRef<SotStorage> const & xRootStrg, ScDocument& rDoc, rtl_TextEncoding eTextEnc, bool bExport ) :
85 meBiff( eBiff ),
86 meOutput( EXC_OUTPUT_BINARY ),
87 mrMedium( rMedium ),
88 mxRootStrg( xRootStrg ),
89 mrDoc( rDoc ),
90 meTextEnc( eTextEnc ),
91 meSysLang( Application::GetSettings().GetLanguageTag().getLanguageType() ),
92 meDocLang( Application::GetSettings().GetLanguageTag().getLanguageType() ),
93 meUILang( Application::GetSettings().GetUILanguageTag().getLanguageType() ),
94 mnDefApiScript( ApiScriptType::LATIN ),
95 maScMaxPos( mrDoc.MaxCol(), mrDoc.MaxRow(), MAXTAB ),
96 maXclMaxPos( EXC_MAXCOL2, EXC_MAXROW2, EXC_MAXTAB2 ),
97 maMaxPos( EXC_MAXCOL2, EXC_MAXROW2, EXC_MAXTAB2 ),
98 mxFontPropSetHlp( std::make_shared<XclFontPropSetHelper>() ),
99 mxChPropSetHlp( std::make_shared<XclChPropSetHelper>() ),
100 mxRD( std::make_shared<RootData>() ),
101 mfScreenPixelX( 50.0 ),
102 mfScreenPixelY( 50.0 ),
103 mnCharWidth( 110 ),
104 mnSpaceWidth(45),
105 mnScTab( 0 ),
106 mbExport( bExport )
108 if (!utl::ConfigManager::IsFuzzing())
109 maUserName = SvtUserOptions().GetLastName();
110 if (maUserName.isEmpty())
111 maUserName = "Calc";
113 switch( ScGlobal::GetDefaultScriptType() )
115 case SvtScriptType::LATIN: mnDefApiScript = ApiScriptType::LATIN; break;
116 case SvtScriptType::ASIAN: mnDefApiScript = ApiScriptType::ASIAN; break;
117 case SvtScriptType::COMPLEX: mnDefApiScript = ApiScriptType::COMPLEX; break;
118 default: SAL_WARN( "sc", "XclRootData::XclRootData - unknown script type" );
121 // maximum cell position
122 switch( meBiff )
124 case EXC_BIFF2: maXclMaxPos.Set( EXC_MAXCOL2, EXC_MAXROW2, EXC_MAXTAB2 ); break;
125 case EXC_BIFF3: maXclMaxPos.Set( EXC_MAXCOL3, EXC_MAXROW3, EXC_MAXTAB3 ); break;
126 case EXC_BIFF4: maXclMaxPos.Set( EXC_MAXCOL4, EXC_MAXROW4, EXC_MAXTAB4 ); break;
127 case EXC_BIFF5: maXclMaxPos.Set( EXC_MAXCOL5, EXC_MAXROW5, EXC_MAXTAB5 ); break;
128 case EXC_BIFF8: maXclMaxPos.Set( EXC_MAXCOL8, EXC_MAXROW8, EXC_MAXTAB8 ); break;
129 default: DBG_ERROR_BIFF();
131 maMaxPos.SetCol( ::std::min( maScMaxPos.Col(), maXclMaxPos.Col() ) );
132 maMaxPos.SetRow( ::std::min( maScMaxPos.Row(), maXclMaxPos.Row() ) );
133 maMaxPos.SetTab( ::std::min( maScMaxPos.Tab(), maXclMaxPos.Tab() ) );
135 // document URL and path
136 if( const SfxItemSet* pItemSet = mrMedium.GetItemSet() )
137 if( const SfxStringItem* pItem = pItemSet->GetItem<SfxStringItem>( SID_FILE_NAME ) )
138 maDocUrl = pItem->GetValue();
139 maBasePath = maDocUrl.copy( 0, maDocUrl.lastIndexOf( '/' ) + 1 );
141 // extended document options - always own object, try to copy existing data from document
142 if( const ScExtDocOptions* pOldDocOpt = mrDoc.GetExtDocOptions() )
143 mxExtDocOpt = std::make_shared<ScExtDocOptions>( *pOldDocOpt );
144 else
145 mxExtDocOpt = std::make_shared<ScExtDocOptions>();
147 // screen pixel size
150 Reference< frame::XDesktop2 > xFramesSupp = frame::Desktop::create( ::comphelper::getProcessComponentContext() );
151 Reference< XFrame > xFrame( xFramesSupp->getActiveFrame(), UNO_SET_THROW );
152 Reference< XDevice > xDevice( xFrame->getContainerWindow(), UNO_QUERY_THROW );
153 DeviceInfo aDeviceInfo = xDevice->getInfo();
154 mfScreenPixelX = (aDeviceInfo.PixelPerMeterX > 0) ? (100000.0 / aDeviceInfo.PixelPerMeterX) : 50.0;
155 mfScreenPixelY = (aDeviceInfo.PixelPerMeterY > 0) ? (100000.0 / aDeviceInfo.PixelPerMeterY) : 50.0;
157 catch( const Exception&)
159 TOOLS_WARN_EXCEPTION( "sc", "XclRootData::XclRootData - cannot get output device info");
163 XclRootData::~XclRootData()
167 XclRoot::XclRoot( XclRootData& rRootData ) :
168 mrData( rRootData )
170 #if defined(DBG_UTIL) && OSL_DEBUG_LEVEL > 0
171 ++mrData.mnObjCnt;
172 #endif
174 // filter tracer
175 mrData.mxTracer = std::make_shared<XclTracer>( GetDocUrl() );
178 XclRoot::XclRoot( const XclRoot& rRoot ) :
179 mrData( rRoot.mrData )
181 #if defined(DBG_UTIL) && OSL_DEBUG_LEVEL > 0
182 ++mrData.mnObjCnt;
183 #endif
186 XclRoot::~XclRoot()
188 #if defined(DBG_UTIL) && OSL_DEBUG_LEVEL > 0
189 --mrData.mnObjCnt;
190 #endif
193 XclRoot& XclRoot::operator=( const XclRoot& rRoot )
195 (void)rRoot; // avoid compiler warning
196 // allowed for assignment in derived classes - but test if the same root data is used
197 OSL_ENSURE( &mrData == &rRoot.mrData, "XclRoot::operator= - incompatible root data" );
198 return *this;
201 void XclRoot::SetTextEncoding( rtl_TextEncoding eTextEnc )
203 if( eTextEnc != RTL_TEXTENCODING_DONTKNOW )
204 mrData.meTextEnc = eTextEnc;
207 void XclRoot::SetCharWidth( const XclFontData& rFontData )
209 mrData.mnCharWidth = 0;
210 if( OutputDevice* pPrinter = GetPrinter() )
212 vcl::Font aFont( rFontData.maName, Size( 0, rFontData.mnHeight ) );
213 aFont.SetFamily( rFontData.GetScFamily( GetTextEncoding() ) );
214 aFont.SetCharSet( rFontData.GetFontEncoding() );
215 aFont.SetWeight( rFontData.GetScWeight() );
216 pPrinter->SetFont( aFont );
217 // Usually digits have the same width, but in some fonts they don't ...
218 // Match the import in sc/source/filter/oox/unitconverter.cxx
219 // UnitConverter::finalizeImport()
220 for (sal_Unicode cChar = '0'; cChar <= '9'; ++cChar)
221 mrData.mnCharWidth = std::max( pPrinter->GetTextWidth( OUString(cChar)), mrData.mnCharWidth);
223 // Set the width of space ' ' character.
224 mrData.mnSpaceWidth = pPrinter->GetTextWidth(OUString(' '));
226 if( mrData.mnCharWidth <= 0 )
228 // #i48717# Win98 with HP LaserJet returns 0
229 SAL_WARN( "sc", "XclRoot::SetCharWidth - invalid character width (no printer?)" );
230 mrData.mnCharWidth = 11 * rFontData.mnHeight / 20;
232 if (mrData.mnSpaceWidth <= 0)
234 SAL_WARN( "sc", "XclRoot::SetCharWidth - invalid character width (no printer?)" );
235 mrData.mnSpaceWidth = 45;
239 sal_Int32 XclRoot::GetHmmFromPixelX( double fPixelX ) const
241 return static_cast< sal_Int32 >( fPixelX * mrData.mfScreenPixelX + 0.5 );
244 sal_Int32 XclRoot::GetHmmFromPixelY( double fPixelY ) const
246 return static_cast< sal_Int32 >( fPixelY * mrData.mfScreenPixelY + 0.5 );
249 uno::Sequence< beans::NamedValue > XclRoot::RequestEncryptionData( ::comphelper::IDocPasswordVerifier& rVerifier ) const
251 ::std::vector< OUString > aDefaultPasswords { XclRootData::gaDefPassword };
252 return ScfApiHelper::QueryEncryptionDataForMedium( mrData.mrMedium, rVerifier, &aDefaultPasswords );
255 bool XclRoot::HasVbaStorage() const
257 tools::SvRef<SotStorage> xRootStrg = GetRootStorage();
258 return xRootStrg.is() && xRootStrg->IsContained( EXC_STORAGE_VBA_PROJECT );
261 tools::SvRef<SotStorage> XclRoot::OpenStorage( tools::SvRef<SotStorage> const & xStrg, const OUString& rStrgName ) const
263 return mrData.mbExport ?
264 ScfTools::OpenStorageWrite( xStrg, rStrgName ) :
265 ScfTools::OpenStorageRead( xStrg, rStrgName );
268 tools::SvRef<SotStorage> XclRoot::OpenStorage( const OUString& rStrgName ) const
270 return OpenStorage( GetRootStorage(), rStrgName );
273 tools::SvRef<SotStorageStream> XclRoot::OpenStream( tools::SvRef<SotStorage> const & xStrg, const OUString& rStrmName ) const
275 return mrData.mbExport ?
276 ScfTools::OpenStorageStreamWrite( xStrg, rStrmName ) :
277 ScfTools::OpenStorageStreamRead( xStrg, rStrmName );
280 tools::SvRef<SotStorageStream> XclRoot::OpenStream( const OUString& rStrmName ) const
282 return OpenStream( GetRootStorage(), rStrmName );
285 ScDocument& XclRoot::GetDoc() const
287 return mrData.mrDoc;
290 SfxObjectShell* XclRoot::GetDocShell() const
292 return GetDoc().GetDocumentShell();
295 ScModelObj* XclRoot::GetDocModelObj() const
297 SfxObjectShell* pDocShell = GetDocShell();
298 return pDocShell ? comphelper::getFromUnoTunnel<ScModelObj>( pDocShell->GetModel() ) : nullptr;
301 OutputDevice* XclRoot::GetPrinter() const
303 return GetDoc().GetRefDevice();
306 ScStyleSheetPool& XclRoot::GetStyleSheetPool() const
308 return *GetDoc().GetStyleSheetPool();
311 ScRangeName& XclRoot::GetNamedRanges() const
313 return *GetDoc().GetRangeName();
316 SdrPage* XclRoot::GetSdrPage( SCTAB nScTab ) const
318 return ((nScTab >= 0) && GetDoc().GetDrawLayer()) ?
319 GetDoc().GetDrawLayer()->GetPage( static_cast< sal_uInt16 >( nScTab ) ) : nullptr;
322 SvNumberFormatter& XclRoot::GetFormatter() const
324 return *GetDoc().GetFormatTable();
327 DateTime XclRoot::GetNullDate() const
329 return GetFormatter().GetNullDate();
332 sal_uInt16 XclRoot::GetBaseYear() const
334 // return 1904 for 1904-01-01, and 1900 for 1899-12-30
335 return (GetNullDate().GetYear() == 1904) ? 1904 : 1900;
338 const DateTime theOurCompatNullDate( Date( 30, 12, 1899 ));
339 const DateTime theExcelCutOverDate( Date( 1, 3, 1900 ));
341 double XclRoot::GetDoubleFromDateTime( const DateTime& rDateTime ) const
343 double fValue = rDateTime - GetNullDate();
344 // adjust dates before 1900-03-01 to get correct time values in the range [0.0,1.0)
345 /* XXX: this is only used when reading BIFF, otherwise we'd have to check
346 * for dateCompatibility==true as mentioned below. */
347 if( rDateTime < theExcelCutOverDate && GetNullDate() == theOurCompatNullDate )
348 fValue -= 1.0;
349 return fValue;
352 DateTime XclRoot::GetDateTimeFromDouble( double fValue ) const
354 DateTime aDateTime = GetNullDate() + fValue;
355 // adjust dates before 1900-03-01 to get correct time values
356 /* FIXME: correction should only be done when writing BIFF or OOXML
357 * transitional with dateCompatibility==true (or absent for default true),
358 * but not if strict ISO/IEC 29500 which does not have the Excel error
359 * compatibility and the null date is the same 1899-12-30 as ours. */
360 if( aDateTime < theExcelCutOverDate && GetNullDate() == theOurCompatNullDate )
361 aDateTime.AddDays(1);
362 return aDateTime;
365 ScEditEngineDefaulter& XclRoot::GetEditEngine() const
367 if( !mrData.mxEditEngine )
369 mrData.mxEditEngine = std::make_shared<ScEditEngineDefaulter>( GetDoc().GetEnginePool() );
370 ScEditEngineDefaulter& rEE = *mrData.mxEditEngine;
371 rEE.SetRefMapMode(MapMode(MapUnit::Map100thMM));
372 rEE.SetEditTextObjectPool( GetDoc().GetEditPool() );
373 rEE.SetUpdateLayout( false );
374 rEE.EnableUndo( false );
375 rEE.SetControlWord( rEE.GetControlWord() & ~EEControlBits::ALLOWBIGOBJS );
377 return *mrData.mxEditEngine;
380 ScHeaderEditEngine& XclRoot::GetHFEditEngine() const
382 if( !mrData.mxHFEditEngine )
384 mrData.mxHFEditEngine = std::make_shared<ScHeaderEditEngine>( EditEngine::CreatePool().get() );
385 ScHeaderEditEngine& rEE = *mrData.mxHFEditEngine;
386 rEE.SetRefMapMode(MapMode(MapUnit::MapTwip)); // headers/footers use twips as default metric
387 rEE.SetUpdateLayout( false );
388 rEE.EnableUndo( false );
389 rEE.SetControlWord( rEE.GetControlWord() & ~EEControlBits::ALLOWBIGOBJS );
391 // set Calc header/footer defaults
392 auto pEditSet = std::make_unique<SfxItemSet>( rEE.GetEmptyItemSet() );
393 SfxItemSetFixed<ATTR_PATTERN_START, ATTR_PATTERN_END> aItemSet( *GetDoc().GetPool() );
394 ScPatternAttr::FillToEditItemSet( *pEditSet, aItemSet );
395 // FillToEditItemSet() adjusts font height to 1/100th mm, we need twips
396 pEditSet->Put( aItemSet.Get( ATTR_FONT_HEIGHT ).CloneSetWhich(EE_CHAR_FONTHEIGHT) );
397 pEditSet->Put( aItemSet.Get( ATTR_CJK_FONT_HEIGHT ).CloneSetWhich(EE_CHAR_FONTHEIGHT_CJK) );
398 pEditSet->Put( aItemSet.Get( ATTR_CTL_FONT_HEIGHT ).CloneSetWhich(EE_CHAR_FONTHEIGHT_CTL) );
399 rEE.SetDefaults( std::move(pEditSet) ); // takes ownership
401 return *mrData.mxHFEditEngine;
404 EditEngine& XclRoot::GetDrawEditEngine() const
406 if( !mrData.mxDrawEditEng )
408 mrData.mxDrawEditEng = std::make_shared<EditEngine>( &GetDoc().GetDrawLayer()->GetItemPool() );
409 EditEngine& rEE = *mrData.mxDrawEditEng;
410 rEE.SetRefMapMode(MapMode(MapUnit::Map100thMM));
411 rEE.SetUpdateLayout( false );
412 rEE.EnableUndo( false );
413 rEE.SetControlWord( rEE.GetControlWord() & ~EEControlBits::ALLOWBIGOBJS );
415 return *mrData.mxDrawEditEng;
418 XclFontPropSetHelper& XclRoot::GetFontPropSetHelper() const
420 return *mrData.mxFontPropSetHlp;
423 XclChPropSetHelper& XclRoot::GetChartPropSetHelper() const
425 return *mrData.mxChPropSetHlp;
428 ScExtDocOptions& XclRoot::GetExtDocOptions() const
430 return *mrData.mxExtDocOpt;
433 XclTracer& XclRoot::GetTracer() const
435 return *mrData.mxTracer;
438 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */