Version 7.5.1.1, tag libreoffice-7.5.1.1
[LibreOffice.git] / sc / source / filter / ftools / ftools.cxx
blob5c219e3c3d3a99738c7b30d22f834bf0e733d68a
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 <ftools.hxx>
21 #include <osl/diagnose.h>
22 #include <osl/thread.h>
23 #include <tools/color.hxx>
24 #include <unotools/charclass.hxx>
25 #include <svl/itempool.hxx>
26 #include <svl/itemset.hxx>
27 #include <svl/poolitem.hxx>
28 #include <sot/storage.hxx>
29 #include <o3tl/string_view.hxx>
31 #include <math.h>
32 #include <global.hxx>
33 #include <stlpool.hxx>
34 #include <stlsheet.hxx>
35 #include <compiler.hxx>
37 #include <orcusfiltersimpl.hxx>
40 // ScFilterTools::ReadLongDouble()
42 void ScfTools::ReadLongDouble(SvStream& rStrm, double& fResult)
44 #ifdef __SIMPLE_FUNC // for <=VC 1.5
46 long double fRet;
47 bool bOk = 10 == rStrm.Read(&fRet, 10);
48 if (!bOk)
49 return;
50 fResult = static_cast<double>(fRet);
52 #undef __SIMPLE_FUNC
54 #else // detailed for all others
58 "Mapping - Guide" 10-Byte Intel
60 77777777 77666666 66665555 55555544 44444444 33333333 33222222 22221111 11111100 00000000 x10
61 98765432 10987654 32109876 54321098 76543210 98765432 10987654 32109876 54321098 76543210 Bit-# total
62 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 0 Byte-#
63 76543210 76543210 76543210 76543210 76543210 76543210 76543210 76543210 76543210 76543210 Bit-# in Byte
64 SEEEEEEE EEEEEEEE IMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM Group
65 01111110 00000000 06665555 55555544 44444444 33333333 33222222 22221111 11111100 00000000 x10
66 14321098 76543210 02109876 54321098 76543210 98765432 10987654 32109876 54321098 76543210 Bit in Group
69 long double lfDouble;
70 long double lfFactor = 256.0;
71 sal_uInt8 pDouble10[ 10 ];
73 bool bOk = 10 == rStrm.ReadBytes(pDouble10, 10); // Intel-10 in pDouble10
74 if (!bOk)
75 return;
77 lfDouble = static_cast< long double >( pDouble10[ 7 ] ); // Byte 7
78 lfDouble *= lfFactor;
79 lfDouble += static_cast< long double >( pDouble10[ 6 ] ); // Byte 6
80 lfDouble *= lfFactor;
81 lfDouble += static_cast< long double >( pDouble10[ 5 ] ); // Byte 5
82 lfDouble *= lfFactor;
83 lfDouble += static_cast< long double >( pDouble10[ 4 ] ); // Byte 4
84 lfDouble *= lfFactor;
85 lfDouble += static_cast< long double >( pDouble10[ 3 ] ); // Byte 3
86 lfDouble *= lfFactor;
87 lfDouble += static_cast< long double >( pDouble10[ 2 ] ); // Byte 2
88 lfDouble *= lfFactor;
89 lfDouble += static_cast< long double >( pDouble10[ 1 ] ); // Byte 1
90 lfDouble *= lfFactor;
91 lfDouble += static_cast< long double >( pDouble10[ 0 ] ); // Byte 0
93 // For value 0.0 all bits are zero; pow(2.0,-16446) does not work with CSet compilers
94 if( lfDouble != 0.0 )
96 // exponent
97 sal_Int32 nExp;
98 nExp = pDouble10[ 9 ] & 0x7F;
99 nExp <<= 8;
100 nExp += pDouble10[ 8 ];
101 nExp -= 16446;
103 lfDouble *= pow( 2.0, static_cast< double >( nExp ) );
106 // sign
107 if( pDouble10[ 9 ] & 0x80 )
108 lfDouble *= static_cast< long double >( -1.0 );
110 fResult = static_cast<double>(lfDouble);
112 #endif
114 // *** common methods *** -----------------------------------------------------
116 rtl_TextEncoding ScfTools::GetSystemTextEncoding()
118 return osl_getThreadTextEncoding();
121 OUString ScfTools::GetHexStr( sal_uInt16 nValue )
123 const char pHex[] = "0123456789ABCDEF";
124 OUString aStr = OUStringChar( pHex[ nValue >> 12 ] )
125 + OUStringChar( pHex[ (nValue >> 8) & 0x000F ] )
126 + OUStringChar( pHex[ (nValue >> 4) & 0x000F ] )
127 + OUStringChar( pHex[ nValue & 0x000F ] );
128 return aStr;
131 sal_uInt8 ScfTools::GetMixedColorComp( sal_uInt8 nFore, sal_uInt8 nBack, sal_uInt8 nTrans )
133 sal_Int32 nTemp = ((static_cast< sal_Int32 >( nBack ) - nFore) * nTrans) / 0x80 + nFore;
134 return static_cast< sal_uInt8 >( nTemp );
137 Color ScfTools::GetMixedColor( const Color& rFore, const Color& rBack, sal_uInt8 nTrans )
139 return Color(
140 GetMixedColorComp( rFore.GetRed(), rBack.GetRed(), nTrans ),
141 GetMixedColorComp( rFore.GetGreen(), rBack.GetGreen(), nTrans ),
142 GetMixedColorComp( rFore.GetBlue(), rBack.GetBlue(), nTrans ) );
145 // *** conversion of names *** ------------------------------------------------
147 /* XXX As in sc/source/core/tool/rangenam.cxx ScRangeData::IsValidName() */
149 OUString ScfTools::ConvertToScDefinedName(const OUString& rName )
151 //fdo#37872: we don't allow points in range names any more
152 OUString sName = rName.replace(u'.',
153 u'_');
154 sal_Int32 nLen = sName.getLength();
155 if( nLen && !ScCompiler::IsCharFlagAllConventions( sName, 0, ScCharFlags::CharName ) )
156 sName = sName.replaceAt( 0, 1, u"_" );
157 for( sal_Int32 nPos = 1; nPos < nLen; ++nPos )
158 if( !ScCompiler::IsCharFlagAllConventions( sName, nPos, ScCharFlags::Name ) )
159 sName = sName.replaceAt( nPos, 1, u"_" );
160 return sName;
163 // *** streams and storages *** -----------------------------------------------
165 tools::SvRef<SotStorage> ScfTools::OpenStorageRead( tools::SvRef<SotStorage> const & xStrg, const OUString& rStrgName )
167 tools::SvRef<SotStorage> xSubStrg;
168 if( xStrg.is() && xStrg->IsContained( rStrgName ) )
169 xSubStrg = xStrg->OpenSotStorage( rStrgName, StreamMode::STD_READ );
170 return xSubStrg;
173 tools::SvRef<SotStorage> ScfTools::OpenStorageWrite( tools::SvRef<SotStorage> const & xStrg, const OUString& rStrgName )
175 tools::SvRef<SotStorage> xSubStrg;
176 if( xStrg.is() )
177 xSubStrg = xStrg->OpenSotStorage( rStrgName, StreamMode::STD_WRITE );
178 return xSubStrg;
181 tools::SvRef<SotStorageStream> ScfTools::OpenStorageStreamRead( tools::SvRef<SotStorage> const & xStrg, const OUString& rStrmName )
183 tools::SvRef<SotStorageStream> xStrm;
184 if( xStrg.is() && xStrg->IsContained( rStrmName ) && xStrg->IsStream( rStrmName ) )
185 xStrm = xStrg->OpenSotStream( rStrmName, StreamMode::STD_READ );
186 return xStrm;
189 tools::SvRef<SotStorageStream> ScfTools::OpenStorageStreamWrite( tools::SvRef<SotStorage> const & xStrg, const OUString& rStrmName )
191 OSL_ENSURE( !xStrg.is() || !xStrg->IsContained( rStrmName ), "ScfTools::OpenStorageStreamWrite - stream exists already" );
192 tools::SvRef<SotStorageStream> xStrm;
193 if( xStrg.is() )
194 xStrm = xStrg->OpenSotStream( rStrmName, StreamMode::STD_WRITE | StreamMode::TRUNC );
195 return xStrm;
198 // *** item handling *** ------------------------------------------------------
200 bool ScfTools::CheckItem( const SfxItemSet& rItemSet, sal_uInt16 nWhichId, bool bDeep )
202 return rItemSet.GetItemState( nWhichId, bDeep ) == SfxItemState::SET;
205 bool ScfTools::CheckItems( const SfxItemSet& rItemSet, const sal_uInt16* pnWhichIds, bool bDeep )
207 OSL_ENSURE( pnWhichIds, "ScfTools::CheckItems - no which id list" );
208 for( const sal_uInt16* pnWhichId = pnWhichIds; *pnWhichId != 0; ++pnWhichId )
209 if( CheckItem( rItemSet, *pnWhichId, bDeep ) )
210 return true;
211 return false;
214 void ScfTools::PutItem( SfxItemSet& rItemSet, const SfxPoolItem& rItem, sal_uInt16 nWhichId, bool bSkipPoolDef )
216 if( !bSkipPoolDef || (rItem != rItemSet.GetPool()->GetDefaultItem( nWhichId )) )
218 rItemSet.Put( rItem.CloneSetWhich(nWhichId) );
222 void ScfTools::PutItem( SfxItemSet& rItemSet, const SfxPoolItem& rItem, bool bSkipPoolDef )
224 PutItem( rItemSet, rItem, rItem.Which(), bSkipPoolDef );
227 // *** style sheet handling *** -----------------------------------------------
229 namespace {
231 ScStyleSheet& lclMakeStyleSheet( ScStyleSheetPool& rPool, const OUString& rStyleName, SfxStyleFamily eFamily, bool bForceName )
233 // find an unused name
234 OUString aNewName( rStyleName );
235 sal_Int32 nIndex = 0;
236 SfxStyleSheetBase* pOldStyleSheet = nullptr;
237 while( SfxStyleSheetBase* pStyleSheet = rPool.Find( aNewName, eFamily ) )
239 if( !pOldStyleSheet )
240 pOldStyleSheet = pStyleSheet;
241 aNewName = rStyleName + " " + OUString::number( ++nIndex );
244 // rename existing style
245 if( pOldStyleSheet && bForceName )
247 pOldStyleSheet->SetName( aNewName );
248 aNewName = rStyleName;
251 // create new style sheet
252 return static_cast< ScStyleSheet& >( rPool.Make( aNewName, eFamily, SfxStyleSearchBits::UserDefined ) );
255 } // namespace
257 ScStyleSheet& ScfTools::MakeCellStyleSheet( ScStyleSheetPool& rPool, const OUString& rStyleName, bool bForceName )
259 return lclMakeStyleSheet( rPool, rStyleName, SfxStyleFamily::Para, bForceName );
262 ScStyleSheet& ScfTools::MakePageStyleSheet( ScStyleSheetPool& rPool, const OUString& rStyleName, bool bForceName )
264 return lclMakeStyleSheet( rPool, rStyleName, SfxStyleFamily::Page, bForceName );
267 // *** byte string import operations *** --------------------------------------
269 OString ScfTools::read_zeroTerminated_uInt8s_ToOString(SvStream& rStrm, sal_Int32& rnBytesLeft)
271 OString aRet(::read_zeroTerminated_uInt8s_ToOString(rStrm));
272 rnBytesLeft -= aRet.getLength(); //we read this number of bytes anyway
273 if (rStrm.good()) //if the stream is happy we read the null terminator as well
274 --rnBytesLeft;
275 return aRet;
278 void ScfTools::AppendCString( SvStream& rStrm, OUString& rString, rtl_TextEncoding eTextEnc )
280 rString += ::read_zeroTerminated_uInt8s_ToOUString(rStrm, eTextEnc);
283 // *** HTML table names <-> named range names *** -----------------------------
285 const OUString& ScfTools::GetHTMLDocName()
287 static const OUString saHTMLDoc( "HTML_all" );
288 return saHTMLDoc;
291 const OUString& ScfTools::GetHTMLTablesName()
293 static const OUString saHTMLTables( "HTML_tables" );
294 return saHTMLTables;
297 const OUString& ScfTools::GetHTMLIndexPrefix()
299 static const OUString saHTMLIndexPrefix( "HTML_" );
300 return saHTMLIndexPrefix;
304 const OUString& ScfTools::GetHTMLNamePrefix()
306 static const OUString saHTMLNamePrefix( "HTML__" );
307 return saHTMLNamePrefix;
310 OUString ScfTools::GetNameFromHTMLIndex( sal_uInt32 nIndex )
312 OUString aName = GetHTMLIndexPrefix() +
313 OUString::number( static_cast< sal_Int32 >( nIndex ) );
314 return aName;
317 OUString ScfTools::GetNameFromHTMLName( std::u16string_view rTabName )
319 return GetHTMLNamePrefix() + rTabName;
322 bool ScfTools::IsHTMLDocName( std::u16string_view rSource )
324 return o3tl::equalsIgnoreAsciiCase( rSource, GetHTMLDocName() );
327 bool ScfTools::IsHTMLTablesName( std::u16string_view rSource )
329 return o3tl::equalsIgnoreAsciiCase( rSource, GetHTMLTablesName() );
332 bool ScfTools::GetHTMLNameFromName( const OUString& rSource, OUString& rName )
334 rName.clear();
335 if( rSource.startsWithIgnoreAsciiCase( GetHTMLNamePrefix() ) )
337 rName = rSource.copy( GetHTMLNamePrefix().getLength() );
338 ScGlobal::AddQuotes( rName, '"', false );
340 else if( rSource.startsWithIgnoreAsciiCase( GetHTMLIndexPrefix() ) )
342 OUString aIndex( rSource.copy( GetHTMLIndexPrefix().getLength() ) );
343 if( CharClass::isAsciiNumeric( aIndex ) && (aIndex.toInt32() > 0) )
344 rName = aIndex;
346 return !rName.isEmpty();
349 ScFormatFilterPluginImpl::ScFormatFilterPluginImpl() {}
350 ScFormatFilterPluginImpl::~ScFormatFilterPluginImpl() {}
352 ScOrcusFilters* ScFormatFilterPluginImpl::GetOrcusFilters()
354 static ScOrcusFiltersImpl aImpl;
355 return &aImpl;
358 ScFormatFilterPlugin * ScFilterCreate()
360 return new ScFormatFilterPluginImpl();
363 // implementation class inside the filters
365 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */