configure.ac | 2 connectivity/inc/pch/precompiled_dbase.hxx | 1 connectivity/inc/pch/precompiled_flat.hxx | 1 i18npool/inc/numberformatcode.hxx | 15 - i18npool/source/numberformatcode/numberformatcode.cxx | 77 +++----- include/svl/zforlist.hxx | 4 include/unotools/numberformatcodewrapper.hxx | 61 ------ sc/inc/document.hxx | 7 sc/qa/unit/subsequent_filters-test.cxx | 2 sc/source/core/data/attarray.cxx | 5 sc/source/core/data/bcaslot.cxx | 15 + sc/source/core/data/documen2.cxx | 4 sc/source/core/data/documen7.cxx | 20 ++ sc/source/core/data/document.cxx | 18 +- sc/source/core/inc/bcaslot.hxx | 2 sc/source/core/tool/compiler.cxx | 49 +++++ sc/source/filter/excel/xetable.cxx | 19 +- sc/source/filter/excel/xltools.cxx | 5 sc/source/filter/inc/xetable.hxx | 4 sc/source/filter/inc/xltools.hxx | 1 sc/source/filter/oox/sheetdatabuffer.cxx | 59 +++--- sc/source/filter/oox/stylesbuffer.cxx | 17 + sc/source/filter/oox/worksheethelper.cxx | 3 svl/source/numbers/zforlist.cxx | 37 +--- svl/source/numbers/zforscan.cxx | 14 - svl/source/numbers/zforscan.hxx | 1 svtools/inc/pch/precompiled_svt.hxx | 1 svx/inc/pch/precompiled_svx.hxx | 1 sw/inc/IDocumentSettingAccess.hxx | 1 sw/inc/pch/precompiled_swui.hxx | 1 sw/qa/extras/ooxmlexport/data/protectedform.docx |binary sw/qa/extras/ooxmlexport/data/tdf53856_conflictingStyle.docx |binary sw/qa/extras/ooxmlexport/data/tdf64372_continuousBreaks.docx |binary sw/qa/extras/ooxmlexport/data/tdf81345.docx |binary sw/qa/extras/ooxmlexport/data/tdf92724_continuousBreaksComplex.docx |binary sw/qa/extras/ooxmlexport/data/tdf99090_pgbrkAfterTable.docx |binary sw/qa/extras/ooxmlexport/ooxmlexport.cxx | 19 ++ sw/qa/extras/ooxmlexport/ooxmlexport4.cxx | 29 +++ sw/qa/extras/ooxmlimport/data/image-hyperlink.docx |binary sw/qa/extras/ooxmlimport/data/tdf75573_page1frame.docx |binary sw/qa/extras/ooxmlimport/ooxmlimport.cxx | 20 ++ sw/source/core/doc/DocumentSettingManager.cxx | 6 sw/source/core/doc/docedt.cxx | 3 sw/source/core/inc/DocumentSettingManager.hxx | 1 sw/source/core/layout/flowfrm.cxx | 4 sw/source/core/tox/ToxTextGenerator.cxx | 4 sw/source/filter/ww8/docxexport.cxx | 6 sw/source/filter/ww8/wrtw8sty.cxx | 5 sw/source/uibase/uno/SwXDocumentSettings.cxx | 13 + unotools/Library_utl.mk | 1 unotools/source/i18n/localedatawrapper.cxx | 12 - unotools/source/i18n/numberformatcodewrapper.cxx | 90 ---------- writerfilter/source/dmapper/DomainMapper.cxx | 24 +- writerfilter/source/dmapper/DomainMapper_Impl.cxx | 18 +- writerfilter/source/dmapper/DomainMapper_Impl.hxx | 3 writerfilter/source/dmapper/GraphicImport.cxx | 14 + writerfilter/source/dmapper/PropertyMap.cxx | 26 ++ writerfilter/source/dmapper/SettingsTable.cxx | 13 + writerfilter/source/dmapper/SettingsTable.hxx | 1 writerfilter/source/dmapper/StyleSheetTable.cxx | 6 writerfilter/source/filter/WriterFilter.cxx | 1 writerfilter/source/ooxml/Handler.cxx | 31 +++ writerfilter/source/ooxml/Handler.hxx | 13 + writerfilter/source/ooxml/OOXMLFastContextHandler.cxx | 6 writerfilter/source/ooxml/OOXMLFastContextHandler.hxx | 1 writerfilter/source/ooxml/factoryimpl_ns.py | 2 writerfilter/source/ooxml/model.xml | 11 + 67 files changed, 495 insertions(+), 335 deletions(-)
New commits: commit 3a0ccdc336edb27d28a18da82979ccc707b6dc46 Author: Andras Timar <[email protected]> Date: Mon Oct 10 22:09:51 2016 +0200 Bump version to 5.1-9 Change-Id: Ia6405fffbc84dd11f7b653a97466b53a7d253322 diff --git a/configure.ac b/configure.ac index 6536f9b..b155bd1 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ dnl in order to create a configure script. # several non-alphanumeric characters, those are split off and used only for the # ABOUTBOXPRODUCTVERSIONSUFFIX in openoffice.lst. Why that is necessary, no idea. -AC_INIT([Collabora Office],[5.1.10.8],[],[],[https://collaboraoffice.com/]) +AC_INIT([Collabora Office],[5.1.10.9],[],[],[https://collaboraoffice.com/]) AC_PREREQ([2.59]) commit 5ee0cf887301ea0e994e3ec7299f4958808fc2d8 Author: Maarten Bosmans <[email protected]> Date: Tue Sep 20 20:27:04 2016 +0200 tdf#53698: Cache more than 1 item in NumberFormatCodeMapper In zforlist.cxx the function SvNumberFormatter::GetPreviewStringGuess switches between the system locale and en_US in order to guess the formatting of a number. This results in poor performance, because in the created SvNumberFormat only the last used locale is cached. Caching more than 1 entries improves the load time for the document attached to tdf#53698 from 90s to 60s in case of non en_US locales. Change-Id: Id0eb4447dea6213015e2d958d8303a1e7892487a Reviewed-on: https://gerrit.libreoffice.org/29136 Reviewed-by: Noel Grandin <[email protected]> Tested-by: Noel Grandin <[email protected]> (cherry picked from commit 450a2fd5e2dafd1a0c08e73ef85db978f6b1a927) diff --git a/i18npool/inc/numberformatcode.hxx b/i18npool/inc/numberformatcode.hxx index 9c7d780..48c64c2 100644 --- a/i18npool/inc/numberformatcode.hxx +++ b/i18npool/inc/numberformatcode.hxx @@ -29,6 +29,9 @@ #include <com/sun/star/uno/Sequence.hxx> #include <com/sun/star/lang/XServiceInfo.hpp> +#include <deque> +#include <utility> + class NumberFormatCodeMapper : public cppu::WeakImplHelper < css::i18n::XNumberFormatCode, @@ -55,19 +58,15 @@ public: private: osl::Mutex maMutex; - css::lang::Locale aLocale; - css::uno::Reference < css::uno::XComponentContext > mxContext; - css::uno::Sequence< css::i18n::FormatElement > aFormatSeq; - css::uno::Reference < css::i18n::XLocaleData4 > mxLocaleData; - bool bFormatsValid; + css::uno::Reference < css::i18n::XLocaleData4 > m_xLocaleData; + typedef std::pair< css::lang::Locale, css::uno::Sequence< css::i18n::FormatElement > > FormatElementCacheItem; + std::deque < FormatElementCacheItem > m_aFormatElementCache; - void setupLocale( const css::lang::Locale& rLocale ); - void getFormats( const css::lang::Locale& rLocale ); + const css::uno::Sequence< css::i18n::FormatElement >& getFormats( const css::lang::Locale& rLocale ); static OUString mapElementTypeShortToString(sal_Int16 formatType); static sal_Int16 mapElementTypeStringToShort(const OUString& formatType); static OUString mapElementUsageShortToString(sal_Int16 formatUsage); static sal_Int16 mapElementUsageStringToShort(const OUString& formatUsage); - void createLocaleDataObject(); }; diff --git a/i18npool/source/numberformatcode/numberformatcode.cxx b/i18npool/source/numberformatcode/numberformatcode.cxx index 4a5e147..fe565560 100644 --- a/i18npool/source/numberformatcode/numberformatcode.cxx +++ b/i18npool/source/numberformatcode/numberformatcode.cxx @@ -25,10 +25,8 @@ NumberFormatCodeMapper::NumberFormatCodeMapper( const css::uno::Reference < css::uno::XComponentContext >& rxContext ) - : - mxContext( rxContext ), - bFormatsValid( false ) { + m_xLocaleData.set( css::i18n::LocaleData::create( rxContext ) ); } @@ -45,10 +43,10 @@ NumberFormatCodeMapper::getDefault( sal_Int16 formatType, sal_Int16 formatUsage, OUString elementUsage = mapElementUsageShortToString(formatUsage); osl::MutexGuard g(maMutex); - getFormats( rLocale ); + const css::uno::Sequence< css::i18n::FormatElement > &aFormatSeq = getFormats( rLocale ); - for(sal_Int32 i = 0; i < aFormatSeq.getLength(); i++) { - if(aFormatSeq[i].isDefault && aFormatSeq[i].formatType == elementType && + for (sal_Int32 i = 0; i < aFormatSeq.getLength(); i++) { + if (aFormatSeq[i].isDefault && aFormatSeq[i].formatType == elementType && aFormatSeq[i].formatUsage == elementUsage) { css::i18n::NumberFormatCode anumberFormatCode(formatType, formatUsage, @@ -69,10 +67,10 @@ css::i18n::NumberFormatCode SAL_CALL NumberFormatCodeMapper::getFormatCode( sal_Int16 formatIndex, const css::lang::Locale& rLocale ) throw(css::uno::RuntimeException, std::exception) { osl::MutexGuard g(maMutex); - getFormats( rLocale ); + const css::uno::Sequence< css::i18n::FormatElement > &aFormatSeq = getFormats( rLocale ); - for(sal_Int32 i = 0; i < aFormatSeq.getLength(); i++) { - if(aFormatSeq[i].formatIndex == formatIndex) { + for (sal_Int32 i = 0; i < aFormatSeq.getLength(); i++) { + if (aFormatSeq[i].formatIndex == formatIndex) { css::i18n::NumberFormatCode anumberFormatCode(mapElementTypeStringToShort(aFormatSeq[i].formatType), mapElementUsageStringToShort(aFormatSeq[i].formatUsage), aFormatSeq[i].formatCode, @@ -85,7 +83,6 @@ NumberFormatCodeMapper::getFormatCode( sal_Int16 formatIndex, const css::lang::L } css::i18n::NumberFormatCode defaultNumberFormatCode; return defaultNumberFormatCode; - } @@ -93,21 +90,21 @@ css::uno::Sequence< css::i18n::NumberFormatCode > SAL_CALL NumberFormatCodeMapper::getAllFormatCode( sal_Int16 formatUsage, const css::lang::Locale& rLocale ) throw(css::uno::RuntimeException, std::exception) { osl::MutexGuard g(maMutex); - getFormats( rLocale ); + const css::uno::Sequence< css::i18n::FormatElement > &aFormatSeq = getFormats( rLocale ); sal_Int32 i, count; count = 0; - for(i = 0; i < aFormatSeq.getLength(); i++) { + for (i = 0; i < aFormatSeq.getLength(); i++) { sal_Int16 elementUsage = mapElementUsageStringToShort(aFormatSeq[i].formatUsage); - if( elementUsage == formatUsage) + if ( elementUsage == formatUsage ) count++; } css::uno::Sequence<css::i18n::NumberFormatCode> seq(count); sal_Int32 j = 0; - for(i = 0; i < aFormatSeq.getLength(); i++) { + for (i = 0; i < aFormatSeq.getLength(); i++) { sal_Int16 elementUsage = mapElementUsageStringToShort(aFormatSeq[i].formatUsage); - if( elementUsage == formatUsage) { + if ( elementUsage == formatUsage ) { seq[j] = css::i18n::NumberFormatCode(mapElementTypeStringToShort(aFormatSeq[i].formatType), formatUsage, aFormatSeq[i].formatCode, @@ -119,7 +116,6 @@ NumberFormatCodeMapper::getAllFormatCode( sal_Int16 formatUsage, const css::lang } } return seq; - } @@ -127,10 +123,10 @@ css::uno::Sequence< css::i18n::NumberFormatCode > SAL_CALL NumberFormatCodeMapper::getAllFormatCodes( const css::lang::Locale& rLocale ) throw(css::uno::RuntimeException, std::exception) { osl::MutexGuard g(maMutex); - getFormats( rLocale ); + const css::uno::Sequence< css::i18n::FormatElement > &aFormatSeq = getFormats( rLocale ); css::uno::Sequence<css::i18n::NumberFormatCode> seq(aFormatSeq.getLength()); - for(sal_Int32 i = 0; i < aFormatSeq.getLength(); i++) + for (sal_Int32 i = 0; i < aFormatSeq.getLength(); i++) { seq[i] = css::i18n::NumberFormatCode(mapElementTypeStringToShort(aFormatSeq[i].formatType), mapElementUsageStringToShort(aFormatSeq[i].formatUsage), @@ -146,30 +142,26 @@ NumberFormatCodeMapper::getAllFormatCodes( const css::lang::Locale& rLocale ) th // --- private implementation ----------------------------------------- -void NumberFormatCodeMapper::setupLocale( const css::lang::Locale& rLocale ) +const css::uno::Sequence< css::i18n::FormatElement >& NumberFormatCodeMapper::getFormats( const css::lang::Locale& rLocale ) { - if ( aLocale.Country != rLocale.Country - || aLocale.Language != rLocale.Language - || aLocale.Variant != rLocale.Variant ) + /* Find the FormatElement Sequence in the cache */ + for (const FormatElementCacheItem& item : m_aFormatElementCache) { - bFormatsValid = false; - aLocale = rLocale; + if ( item.first == rLocale ) + return item.second; } -} - -void NumberFormatCodeMapper::getFormats( const css::lang::Locale& rLocale ) -{ - setupLocale( rLocale ); - if ( !bFormatsValid ) - { - createLocaleDataObject(); - if( !mxLocaleData.is() ) - aFormatSeq = css::uno::Sequence< css::i18n::FormatElement > (0); - else - aFormatSeq = mxLocaleData->getAllFormats( aLocale ); - bFormatsValid = true; - } + /* Not found; Get the FormatElement Sequence for the given Locale */ + css::uno::Sequence< css::i18n::FormatElement > aFormatElementSequence; + if ( m_xLocaleData.is() ) + aFormatElementSequence = m_xLocaleData->getAllFormats( rLocale ); + + /* Add the FormatElement Sequence to the cache */ + const int FORMATELEMENTCACHE_SIZE = 3; + if ( m_aFormatElementCache.size() > FORMATELEMENTCACHE_SIZE ) + m_aFormatElementCache.pop_front(); + m_aFormatElementCache.emplace_back( rLocale, aFormatElementSequence ); + return m_aFormatElementCache.back().second; } @@ -252,15 +244,6 @@ NumberFormatCodeMapper::mapElementUsageStringToShort(const OUString& formatUsage } -void -NumberFormatCodeMapper::createLocaleDataObject() { - - if(mxLocaleData.is()) - return; - - mxLocaleData.set( css::i18n::LocaleData::create(mxContext) ); -} - OUString SAL_CALL NumberFormatCodeMapper::getImplementationName() throw( css::uno::RuntimeException, std::exception ) commit df53a5f695b37bdd3eef57203fc0a3f4c95dbeea Author: Maarten Bosmans <[email protected]> Date: Fri Sep 9 21:28:01 2016 +0200 tdf#53698: Add a NumberFormatMapper member to SvNumberformatScan This way the NumberFormatMapper can cache subsequent getFormatCode calls. It improves performance in case LANG=en_US. Change-Id: I81922f219c29a5aa302e5ad3afead107dee463e3 Reviewed-on: https://gerrit.libreoffice.org/29135 Reviewed-by: Noel Grandin <[email protected]> Tested-by: Noel Grandin <[email protected]> (cherry picked from commit 110183572bfe9da0020b4c506d4b458bf69b1e85) diff --git a/svl/source/numbers/zforscan.cxx b/svl/source/numbers/zforscan.cxx index 3172159..807fb63 100644 --- a/svl/source/numbers/zforscan.cxx +++ b/svl/source/numbers/zforscan.cxx @@ -74,6 +74,7 @@ ImpSvNumberformatScan::ImpSvNumberformatScan( SvNumberFormatter* pFormatterP ) , nCurrPos(-1) { pFormatter = pFormatterP; + xNFC = css::i18n::NumberFormatMapper::create( pFormatter->GetComponentContext() ); bConvertMode = false; bConvertSystemToSystem = false; //! All keywords MUST be UPPERCASE! @@ -231,7 +232,6 @@ void ImpSvNumberformatScan::SetDependentKeywords() const LanguageTag& rLoadedLocale = pLocaleData->getLoadedLanguageTag(); LanguageType eLang = rLoadedLocale.getLanguageType( false); - css::uno::Reference< css::i18n::XNumberFormatCode > xNFC = i18n::NumberFormatMapper::create( pFormatter->GetComponentContext() ); i18n::NumberFormatCode aFormat = xNFC->getFormatCode( NF_NUMBER_STANDARD, rLoadedLocale.getLocale() ); sNameStandardFormat = lcl_extractStandardGeneralName( aFormat.Code ); sKeyword[NF_KEY_GENERAL] = pCharClass->uppercase( sNameStandardFormat ); @@ -642,10 +642,7 @@ short ImpSvNumberformatScan::Next_Symbol( const OUString& rStr, sal_Int32& nPos, OUString& sSymbol ) { - if ( bKeywordsNeedInit ) - { - InitKeywords(); - } + InitKeywords(); const CharClass* pChrCls = pFormatter->GetCharClass(); const LocaleDataWrapper* pLoc = pFormatter->GetLocaleData(); short eType = 0; diff --git a/svl/source/numbers/zforscan.hxx b/svl/source/numbers/zforscan.hxx index 82535fd..a94caea 100644 --- a/svl/source/numbers/zforscan.hxx +++ b/svl/source/numbers/zforscan.hxx @@ -154,6 +154,7 @@ private: // Private section OUString sNameStandardFormat; // "Standard" sal_uInt16 nStandardPrec; // Default Precision for Standardformat SvNumberFormatter* pFormatter; // Pointer to the FormatList + css::uno::Reference< css::i18n::XNumberFormatCode > xNFC; OUString sStrArray[NF_MAX_FORMAT_SYMBOLS]; // Array of symbols short nTypeArray[NF_MAX_FORMAT_SYMBOLS]; // Array of infos commit b396a8a328fee64173f9efaedc8f1c17aa5b8f52 Author: Maarten Bosmans <[email protected]> Date: Fri Sep 9 21:11:13 2016 +0200 Remove NumberFormatCodeWrapper This class only adds a level of indirection, without any useful functionality. Reviewed-on: https://gerrit.libreoffice.org/29134 Reviewed-by: Noel Grandin <[email protected]> Tested-by: Noel Grandin <[email protected]> (cherry picked from commit 9df9949cc484ea0ba109e7d41fd03b15afaedb11) Change-Id: I806e1b9241caf025c62c12c93aad3101daac874a diff --git a/connectivity/inc/pch/precompiled_dbase.hxx b/connectivity/inc/pch/precompiled_dbase.hxx index 544fef4..b1913e0 100644 --- a/connectivity/inc/pch/precompiled_dbase.hxx +++ b/connectivity/inc/pch/precompiled_dbase.hxx @@ -204,7 +204,6 @@ #include <unotools/collatorwrapper.hxx> #include <unotools/localedatawrapper.hxx> #include <unotools/nativenumberwrapper.hxx> -#include <unotools/numberformatcodewrapper.hxx> #include <unotools/readwritemutexguard.hxx> #include <unotools/sharedunocomponent.hxx> #include <unotools/syslocale.hxx> diff --git a/connectivity/inc/pch/precompiled_flat.hxx b/connectivity/inc/pch/precompiled_flat.hxx index 197cf67..73daefe 100644 --- a/connectivity/inc/pch/precompiled_flat.hxx +++ b/connectivity/inc/pch/precompiled_flat.hxx @@ -199,7 +199,6 @@ #include <unotools/collatorwrapper.hxx> #include <unotools/localedatawrapper.hxx> #include <unotools/nativenumberwrapper.hxx> -#include <unotools/numberformatcodewrapper.hxx> #include <unotools/readwritemutexguard.hxx> #include <unotools/syslocale.hxx> #include <unotools/transliterationwrapper.hxx> diff --git a/include/svl/zforlist.hxx b/include/svl/zforlist.hxx index 932fd86..e6824366 100644 --- a/include/svl/zforlist.hxx +++ b/include/svl/zforlist.hxx @@ -27,8 +27,8 @@ #include <com/sun/star/lang/Locale.hpp> #include <com/sun/star/i18n/NumberFormatCode.hpp> #include <com/sun/star/util/NumberFormat.hpp> +#include <com/sun/star/i18n/NumberFormatMapper.hpp> #include <unotools/localedatawrapper.hxx> -#include <unotools/numberformatcodewrapper.hxx> #include <tools/link.hxx> #include <svl/ondemand.hxx> #include <svl/nfkeytab.hxx> @@ -827,7 +827,7 @@ private: // Generate additional formats provided by i18n SVL_DLLPRIVATE void ImpGenerateAdditionalFormats( sal_uInt32 CLOffset, - NumberFormatCodeWrapper& rNumberFormatCode, + css::uno::Reference< css::i18n::XNumberFormatCode >& rNumberFormatCode, bool bAfterChangingSystemCL ); SVL_DLLPRIVATE SvNumberformat* ImpInsertFormat( const css::i18n::NumberFormatCode& rCode, diff --git a/include/unotools/numberformatcodewrapper.hxx b/include/unotools/numberformatcodewrapper.hxx deleted file mode 100644 index 08d97fc..0000000 --- a/include/unotools/numberformatcodewrapper.hxx +++ /dev/null @@ -1,61 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_UNOTOOLS_NUMBERFORMATCODEWRAPPER_HXX -#define INCLUDED_UNOTOOLS_NUMBERFORMATCODEWRAPPER_HXX - -#include <com/sun/star/i18n/XNumberFormatCode.hpp> -#include <unotools/unotoolsdllapi.h> - -namespace com { namespace sun { namespace star { - namespace uno { - class XComponentContext; - } -}}} - -class UNOTOOLS_DLLPUBLIC NumberFormatCodeWrapper -{ - css::uno::Reference< css::i18n::XNumberFormatCode > xNFC; - css::lang::Locale aLocale; - - NumberFormatCodeWrapper( const NumberFormatCodeWrapper& ) = delete; - NumberFormatCodeWrapper& operator=( const NumberFormatCodeWrapper& ) = delete; - -public: - NumberFormatCodeWrapper( - const css::uno::Reference< css::uno::XComponentContext > & rxContext, - const css::lang::Locale& rLocale - ); - - ~NumberFormatCodeWrapper(); - - /// set a new Locale - void setLocale( const css::lang::Locale& rLocale ); - - // Wrapper implementations of class NumberFormatCodeMapper - - css::i18n::NumberFormatCode getFormatCode( sal_Int16 nFormatIndex ) const; - css::uno::Sequence< css::i18n::NumberFormatCode > getAllFormatCode( sal_Int16 nFormatUsage ) const; - css::uno::Sequence< css::i18n::NumberFormatCode > getAllFormatCodes() const; - -}; - -#endif // INCLUDED_UNOTOOLS_NUMBERFORMATCODEWRAPPER_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svl/source/numbers/zforlist.cxx b/svl/source/numbers/zforlist.cxx index 48dfe92..2a88586 100644 --- a/svl/source/numbers/zforlist.cxx +++ b/svl/source/numbers/zforlist.cxx @@ -29,7 +29,6 @@ #include <unotools/configmgr.hxx> #include <i18nlangtag/mslangid.hxx> #include <unotools/localedatawrapper.hxx> -#include <unotools/numberformatcodewrapper.hxx> #include <unotools/calendarwrapper.hxx> #include <com/sun/star/i18n/KNumberFormatUsage.hpp> #include <com/sun/star/i18n/KNumberFormatType.hpp> @@ -512,9 +511,8 @@ void SvNumberFormatter::ReplaceSystemCL( LanguageType eOldLanguage ) pStdFormat->SetLastInsertKey( sal_uInt16(nLastKey - nCLOffset) ); // append new system additional formats - NumberFormatCodeWrapper aNumberFormatCode( m_xContext, - GetLanguageTag().getLocale() ); - ImpGenerateAdditionalFormats( nCLOffset, aNumberFormatCode, true ); + css::uno::Reference< css::i18n::XNumberFormatCode > xNFC = i18n::NumberFormatMapper::create( m_xContext ); + ImpGenerateAdditionalFormats( nCLOffset, xNFC, true ); } css::uno::Reference<css::uno::XComponentContext> SvNumberFormatter::GetComponentContext() const @@ -2227,15 +2225,14 @@ void SvNumberFormatter::ImpGenerateFormats( sal_uInt32 CLOffset, bool bNoAdditio pFormatScanner->SetConvertMode(false); // switch off for this function } - NumberFormatCodeWrapper aNumberFormatCode( m_xContext, - GetLanguageTag().getLocale() ); + css::lang::Locale aLocale = GetLanguageTag().getLocale(); + css::uno::Reference< css::i18n::XNumberFormatCode > xNFC = i18n::NumberFormatMapper::create( m_xContext ); SvNumberformat* pNewFormat = nullptr; sal_Int32 nIdx; bool bDefault; // Number - uno::Sequence< i18n::NumberFormatCode > aFormatSeq = - aNumberFormatCode.getAllFormatCode( i18n::KNumberFormatUsage::FIXED_NUMBER ); + uno::Sequence< i18n::NumberFormatCode > aFormatSeq = xNFC->getAllFormatCode( i18n::KNumberFormatUsage::FIXED_NUMBER, aLocale ); ImpAdjustFormatCodeDefault( aFormatSeq.getArray(), aFormatSeq.getLength() ); // General @@ -2321,7 +2318,7 @@ void SvNumberFormatter::ImpGenerateFormats( sal_uInt32 CLOffset, bool bNoAdditio // Percent number - aFormatSeq = aNumberFormatCode.getAllFormatCode( i18n::KNumberFormatUsage::PERCENT_NUMBER ); + aFormatSeq = xNFC->getAllFormatCode( i18n::KNumberFormatUsage::PERCENT_NUMBER, aLocale ); ImpAdjustFormatCodeDefault( aFormatSeq.getArray(), aFormatSeq.getLength() ); // 0% @@ -2337,7 +2334,7 @@ void SvNumberFormatter::ImpGenerateFormats( sal_uInt32 CLOffset, bool bNoAdditio // Currency. NO default standard option! Default is determined of locale // data default currency and format is generated if needed. - aFormatSeq = aNumberFormatCode.getAllFormatCode( i18n::KNumberFormatUsage::CURRENCY ); + aFormatSeq = xNFC->getAllFormatCode( i18n::KNumberFormatUsage::CURRENCY, aLocale ); if (LocaleDataWrapper::areChecksEnabled()) { // though no default desired here, test for correctness of locale data @@ -2394,7 +2391,7 @@ void SvNumberFormatter::ImpGenerateFormats( sal_uInt32 CLOffset, bool bNoAdditio // Date - aFormatSeq = aNumberFormatCode.getAllFormatCode( i18n::KNumberFormatUsage::DATE ); + aFormatSeq = xNFC->getAllFormatCode( i18n::KNumberFormatUsage::DATE, aLocale ); ImpAdjustFormatCodeDefault( aFormatSeq.getArray(), aFormatSeq.getLength() ); // DD.MM.YY System @@ -2504,7 +2501,7 @@ void SvNumberFormatter::ImpGenerateFormats( sal_uInt32 CLOffset, bool bNoAdditio // Time - aFormatSeq = aNumberFormatCode.getAllFormatCode( i18n::KNumberFormatUsage::TIME ); + aFormatSeq = xNFC->getAllFormatCode( i18n::KNumberFormatUsage::TIME, aLocale ); ImpAdjustFormatCodeDefault( aFormatSeq.getArray(), aFormatSeq.getLength() ); // HH:MM @@ -2544,7 +2541,7 @@ void SvNumberFormatter::ImpGenerateFormats( sal_uInt32 CLOffset, bool bNoAdditio // DateTime - aFormatSeq = aNumberFormatCode.getAllFormatCode( i18n::KNumberFormatUsage::DATE_TIME ); + aFormatSeq = xNFC->getAllFormatCode( i18n::KNumberFormatUsage::DATE_TIME, aLocale ); ImpAdjustFormatCodeDefault( aFormatSeq.getArray(), aFormatSeq.getLength() ); // DD.MM.YY HH:MM System @@ -2559,7 +2556,7 @@ void SvNumberFormatter::ImpGenerateFormats( sal_uInt32 CLOffset, bool bNoAdditio // Scientific number - aFormatSeq = aNumberFormatCode.getAllFormatCode( i18n::KNumberFormatUsage::SCIENTIFIC_NUMBER ); + aFormatSeq = xNFC->getAllFormatCode( i18n::KNumberFormatUsage::SCIENTIFIC_NUMBER, aLocale ); ImpAdjustFormatCodeDefault( aFormatSeq.getArray(), aFormatSeq.getLength() ); // 0.00E+000 @@ -2609,7 +2606,7 @@ void SvNumberFormatter::ImpGenerateFormats( sal_uInt32 CLOffset, bool bNoAdditio // changing SystemCL, then they are appended last after user defined. if ( !bNoAdditionalFormats ) { - ImpGenerateAdditionalFormats( CLOffset, aNumberFormatCode, false ); + ImpGenerateAdditionalFormats( CLOffset, xNFC, false ); } if (bOldConvertMode) { @@ -2619,7 +2616,8 @@ void SvNumberFormatter::ImpGenerateFormats( sal_uInt32 CLOffset, bool bNoAdditio void SvNumberFormatter::ImpGenerateAdditionalFormats( sal_uInt32 CLOffset, - NumberFormatCodeWrapper& rNumberFormatCode, bool bAfterChangingSystemCL ) + css::uno::Reference< css::i18n::XNumberFormatCode >& rNumberFormatCode, + bool bAfterChangingSystemCL ) { using namespace ::com::sun::star; @@ -2630,13 +2628,12 @@ void SvNumberFormatter::ImpGenerateAdditionalFormats( sal_uInt32 CLOffset, return ; } sal_uInt32 nPos = CLOffset + pStdFormat->GetLastInsertKey(); - rNumberFormatCode.setLocale( GetLanguageTag().getLocale() ); + css::lang::Locale aLocale = GetLanguageTag().getLocale(); sal_Int32 j; // All currencies, this time with [$...] which was stripped in // ImpGenerateFormats for old "automatic" currency formats. - uno::Sequence< i18n::NumberFormatCode > aFormatSeq = - rNumberFormatCode.getAllFormatCode( i18n::KNumberFormatUsage::CURRENCY ); + uno::Sequence< i18n::NumberFormatCode > aFormatSeq = rNumberFormatCode->getAllFormatCode( i18n::KNumberFormatUsage::CURRENCY, aLocale ); i18n::NumberFormatCode * pFormatArr = aFormatSeq.getArray(); sal_Int32 nCodes = aFormatSeq.getLength(); ImpAdjustFormatCodeDefault( aFormatSeq.getArray(), nCodes ); @@ -2674,7 +2671,7 @@ void SvNumberFormatter::ImpGenerateAdditionalFormats( sal_uInt32 CLOffset, // like it is done for usage groups with ImpAdjustFormatCodeDefault(). // There is no harm though, on first invocation ImpGetDefaultFormat() will // use the first default encountered. - aFormatSeq = rNumberFormatCode.getAllFormatCodes(); + aFormatSeq = rNumberFormatCode->getAllFormatCodes( aLocale ); nCodes = aFormatSeq.getLength(); if ( nCodes ) { diff --git a/svl/source/numbers/zforscan.cxx b/svl/source/numbers/zforscan.cxx index 5803416..3172159 100644 --- a/svl/source/numbers/zforscan.cxx +++ b/svl/source/numbers/zforscan.cxx @@ -25,7 +25,7 @@ #include <i18nlangtag/mslangid.hxx> #include <unotools/charclass.hxx> #include <unotools/localedatawrapper.hxx> -#include <unotools/numberformatcodewrapper.hxx> +#include <com/sun/star/i18n/NumberFormatCode.hpp> #include <rtl/instance.hxx> #include <svl/zforlist.hxx> @@ -230,11 +230,10 @@ void ImpSvNumberformatScan::SetDependentKeywords() // requested Locale, otherwise number format codes might not match const LanguageTag& rLoadedLocale = pLocaleData->getLoadedLanguageTag(); LanguageType eLang = rLoadedLocale.getLanguageType( false); - NumberFormatCodeWrapper aNumberFormatCode( pFormatter->GetComponentContext(), - rLoadedLocale.getLocale() ); - i18n::NumberFormatCode aFormat = aNumberFormatCode.getFormatCode( NF_NUMBER_STANDARD ); - sNameStandardFormat = lcl_extractStandardGeneralName( aFormat.Code); + css::uno::Reference< css::i18n::XNumberFormatCode > xNFC = i18n::NumberFormatMapper::create( pFormatter->GetComponentContext() ); + i18n::NumberFormatCode aFormat = xNFC->getFormatCode( NF_NUMBER_STANDARD, rLoadedLocale.getLocale() ); + sNameStandardFormat = lcl_extractStandardGeneralName( aFormat.Code ); sKeyword[NF_KEY_GENERAL] = pCharClass->uppercase( sNameStandardFormat ); // preset new calendar keywords diff --git a/svtools/inc/pch/precompiled_svt.hxx b/svtools/inc/pch/precompiled_svt.hxx index bb938d8..0cda1cb 100644 --- a/svtools/inc/pch/precompiled_svt.hxx +++ b/svtools/inc/pch/precompiled_svt.hxx @@ -408,7 +408,6 @@ #include <unotools/configmgr.hxx> #include <unotools/localedatawrapper.hxx> #include <unotools/nativenumberwrapper.hxx> -#include <unotools/numberformatcodewrapper.hxx> #include <unotools/options.hxx> #include <unotools/readwritemutexguard.hxx> #include <unotools/streamwrap.hxx> diff --git a/svx/inc/pch/precompiled_svx.hxx b/svx/inc/pch/precompiled_svx.hxx index a040847..47fb148 100644 --- a/svx/inc/pch/precompiled_svx.hxx +++ b/svx/inc/pch/precompiled_svx.hxx @@ -409,7 +409,6 @@ #include <unotools/fontcvt.hxx> #include <unotools/fontdefs.hxx> #include <unotools/localedatawrapper.hxx> -#include <unotools/numberformatcodewrapper.hxx> #include <unotools/options.hxx> #include <unotools/pathoptions.hxx> #include <unotools/unotoolsdllapi.h> diff --git a/sw/inc/pch/precompiled_swui.hxx b/sw/inc/pch/precompiled_swui.hxx index 9d818e9..ee99daa 100644 --- a/sw/inc/pch/precompiled_swui.hxx +++ b/sw/inc/pch/precompiled_swui.hxx @@ -611,7 +611,6 @@ #include <unotools/intlwrapper.hxx> #include <unotools/localedatawrapper.hxx> #include <unotools/nativenumberwrapper.hxx> -#include <unotools/numberformatcodewrapper.hxx> #include <unotools/options.hxx> #include <unotools/pathoptions.hxx> #include <unotools/syslocale.hxx> diff --git a/unotools/Library_utl.mk b/unotools/Library_utl.mk index a3481de..fcb7ba7 100644 --- a/unotools/Library_utl.mk +++ b/unotools/Library_utl.mk @@ -89,7 +89,6 @@ $(eval $(call gb_Library_add_exception_objects,utl,\ unotools/source/i18n/intlwrapper \ unotools/source/i18n/localedatawrapper \ unotools/source/i18n/nativenumberwrapper \ - unotools/source/i18n/numberformatcodewrapper \ unotools/source/i18n/readwritemutexguard \ unotools/source/i18n/textsearch \ unotools/source/i18n/transliterationwrapper \ diff --git a/unotools/source/i18n/localedatawrapper.cxx b/unotools/source/i18n/localedatawrapper.cxx index 84573c7..78c32ef 100644 --- a/unotools/source/i18n/localedatawrapper.cxx +++ b/unotools/source/i18n/localedatawrapper.cxx @@ -23,7 +23,6 @@ #include <sal/log.hxx> #include <unotools/localedatawrapper.hxx> -#include <unotools/numberformatcodewrapper.hxx> #include <unotools/calendarwrapper.hxx> #include <unotools/digitgroupingiterator.hxx> #include <tools/debug.hxx> @@ -35,6 +34,7 @@ #include <com/sun/star/i18n/CalendarFieldIndex.hpp> #include <com/sun/star/i18n/CalendarDisplayIndex.hpp> #include <com/sun/star/i18n/NumberFormatIndex.hpp> +#include <com/sun/star/i18n/NumberFormatMapper.hpp> #include <comphelper/processfactory.hxx> #include <rtl/instance.hxx> @@ -691,9 +691,8 @@ void LocaleDataWrapper::scanCurrFormatImpl( const OUString& rCode, void LocaleDataWrapper::getCurrFormatsImpl() { - NumberFormatCodeWrapper aNumberFormatCode( m_xContext, getMyLocale() ); - uno::Sequence< NumberFormatCode > aFormatSeq - = aNumberFormatCode.getAllFormatCode( KNumberFormatUsage::CURRENCY ); + css::uno::Reference< css::i18n::XNumberFormatCode > xNFC = i18n::NumberFormatMapper::create( m_xContext ); + uno::Sequence< NumberFormatCode > aFormatSeq = xNFC->getAllFormatCode( KNumberFormatUsage::CURRENCY, getMyLocale() ); sal_Int32 nCnt = aFormatSeq.getLength(); if ( !nCnt ) { // bad luck @@ -939,9 +938,8 @@ DateFormat LocaleDataWrapper::scanDateFormatImpl( const OUString& rCode ) void LocaleDataWrapper::getDateFormatsImpl() { - NumberFormatCodeWrapper aNumberFormatCode( m_xContext, getMyLocale() ); - uno::Sequence< NumberFormatCode > aFormatSeq - = aNumberFormatCode.getAllFormatCode( KNumberFormatUsage::DATE ); + css::uno::Reference< css::i18n::XNumberFormatCode > xNFC = i18n::NumberFormatMapper::create( m_xContext ); + uno::Sequence< NumberFormatCode > aFormatSeq = xNFC->getAllFormatCode( KNumberFormatUsage::DATE, getMyLocale() ); sal_Int32 nCnt = aFormatSeq.getLength(); if ( !nCnt ) { // bad luck diff --git a/unotools/source/i18n/numberformatcodewrapper.cxx b/unotools/source/i18n/numberformatcodewrapper.cxx deleted file mode 100644 index 652c757..0000000 --- a/unotools/source/i18n/numberformatcodewrapper.cxx +++ /dev/null @@ -1,90 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <sal/config.h> - -#include <sal/log.hxx> -#include <unotools/numberformatcodewrapper.hxx> -#include <com/sun/star/i18n/NumberFormatMapper.hpp> - -using namespace ::com::sun::star; -using namespace ::com::sun::star::i18n; -using namespace ::com::sun::star::uno; - -NumberFormatCodeWrapper::NumberFormatCodeWrapper( - const Reference< uno::XComponentContext > & rxContext, - const lang::Locale& rLocale - ) -{ - setLocale( rLocale ); - xNFC = i18n::NumberFormatMapper::create( rxContext ); -} - -NumberFormatCodeWrapper::~NumberFormatCodeWrapper() -{ -} - -void NumberFormatCodeWrapper::setLocale( const css::lang::Locale& rLocale ) -{ - aLocale = rLocale; -} - -css::i18n::NumberFormatCode -NumberFormatCodeWrapper::getFormatCode( sal_Int16 formatIndex ) const -{ - try - { - return xNFC->getFormatCode( formatIndex, aLocale ); - } - catch ( const Exception& ) - { - SAL_WARN( "unotools.i18n", "getFormatCode: Exception caught!" ); - } - return css::i18n::NumberFormatCode(); -} - -css::uno::Sequence< css::i18n::NumberFormatCode > -NumberFormatCodeWrapper::getAllFormatCode( sal_Int16 formatUsage ) const -{ - try - { - return xNFC->getAllFormatCode( formatUsage, aLocale ); - } - catch ( const Exception& ) - { - SAL_WARN( "unotools.i18n", "getAllFormatCode: Exception caught!" ); - } - return css::uno::Sequence< css::i18n::NumberFormatCode > (0); -} - -css::uno::Sequence< css::i18n::NumberFormatCode > -NumberFormatCodeWrapper::getAllFormatCodes() const -{ - try - { - return xNFC->getAllFormatCodes( aLocale ); - } - catch ( const Exception& ) - { - SAL_WARN( "unotools.i18n", "getAllFormatCodes: Exception caught!" ); - } - return css::uno::Sequence< css::i18n::NumberFormatCode > (0); -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 346566c1fe76a752757b093a3eaf7d6612a51c94 Author: Maarten Bosmans <[email protected]> Date: Wed Aug 24 21:14:57 2016 +0200 Resolves tdf#100709 Optimize SheetDataBuffer::addColXfStyle The insertion of RowRanges into the sorted set was done by iterating through the set until the correct insertion point was found. By using set.lower_bound(), the complexity goes from O(N) to (log N) for a single insert. Regarding tdf#100709: the import time for the attached example document reduces by 12x. Change-Id: Ifb03d58a0e46a936ab61a5f0b512e956c87e5e2b Reviewed-on: https://gerrit.libreoffice.org/28510 Reviewed-by: Eike Rathke <[email protected]> Tested-by: Jenkins <[email protected]> (cherry picked from commit 4a63c145dcce8411c5707f6b99877cc87a4f6c5d) diff --git a/sc/source/filter/oox/sheetdatabuffer.cxx b/sc/source/filter/oox/sheetdatabuffer.cxx index 830c9c0..e686d72 100644 --- a/sc/source/filter/oox/sheetdatabuffer.cxx +++ b/sc/source/filter/oox/sheetdatabuffer.cxx @@ -368,59 +368,48 @@ void SheetDataBuffer::addColXfStyle( sal_Int32 nXfId, sal_Int32 nFormatId, const maStylesPerColumn[ nCol ].insert( aStyleRows ); else { - RowStyles& rRowStyles = maStylesPerColumn[ nCol ]; + RowStyles& rRowStyles = maStylesPerColumn[ nCol ]; // Reset row range for each column aStyleRows.mnStartRow = rAddress.StartRow; aStyleRows.mnEndRow = rAddress.EndRow; - // If the rowrange style includes rows already - // allocated to a style then we need to split - // the range style Rows into sections ( to - // occupy only rows that have no style definition ) + // If aStyleRows includes rows already allocated to a style + // in rRowStyles, then we need to split it into parts. + // ( to occupy only rows that have no style definition) - // We don't want to set any rowstyle 'rows' - // for rows where there is an existing 'style' ) - std::vector< RowRangeStyle > aRangeRowsSplits; - - RowStyles::iterator rows_it = rRowStyles.begin(); + // Start iterating at the first element that is not completely before aStyleRows + RowStyles::iterator rows_it = rRowStyles.lower_bound(aStyleRows); RowStyles::iterator rows_end = rRowStyles.end(); bool bAddRange = true; for ( ; rows_it != rows_end; ++rows_it ) { const RowRangeStyle& r = *rows_it; - // if row is completely within existing style, discard it - if ( aStyleRows.mnStartRow >= r.mnStartRow && aStyleRows.mnEndRow <= r.mnEndRow ) - bAddRange = false; - else if ( aStyleRows.mnStartRow <= r.mnStartRow ) + + // Add the part of aStyleRows that does not overlap with r + if ( aStyleRows.mnStartRow < r.mnStartRow ) + { + RowRangeStyle aSplit = aStyleRows; + aSplit.mnEndRow = std::min(aStyleRows.mnEndRow, r.mnStartRow - 1); + // Insert with hint that aSplit comes directly before the current position + rRowStyles.insert( rows_it, aSplit ); + } + + // Done if no part of aStyleRows extends beyond r + if ( aStyleRows.mnEndRow <= r.mnEndRow ) { - // not intersecting at all?, if so finish as none left - // to check ( row ranges are in ascending order - if ( aStyleRows.mnEndRow < r.mnStartRow ) - break; - else if ( aStyleRows.mnEndRow <= r.mnEndRow ) - { - aStyleRows.mnEndRow = r.mnStartRow - 1; - break; - } - if ( aStyleRows.mnStartRow < r.mnStartRow ) - { - RowRangeStyle aSplit = aStyleRows; - aSplit.mnEndRow = r.mnStartRow - 1; - aRangeRowsSplits.push_back( aSplit ); - } + bAddRange = false; + break; } - if ( aStyleRows.mnStartRow <= r.mnEndRow && r.mnEndRow < aStyleRows.mnEndRow ) - aStyleRows.mnStartRow = r.mnEndRow + 1; + + // Cut off the part aStyleRows that was handled above + aStyleRows.mnStartRow = r.mnEndRow + 1; } - std::vector< RowRangeStyle >::iterator splits_it = aRangeRowsSplits.begin(); - std::vector< RowRangeStyle >::iterator splits_end = aRangeRowsSplits.end(); - for ( ; splits_it != splits_end; ++splits_it ) - rRowStyles.insert( *splits_it ); if ( bAddRange ) rRowStyles.insert( aStyleRows ); } } } + void SheetDataBuffer::finalizeImport() { // create all array formulas commit 47bb146821998cb5bcade16386e0e20c1d34599f Author: Maarten Bosmans <[email protected]> Date: Thu Aug 25 12:47:26 2016 +0200 Related: tdf#100709 Fix two bugs in SheetDataBuffer::addColXfStyle The addColXfStyle method is supposed to add a formatId to all the cells in a specified CellRange where there is no previously set formatId in the maStylesPerColumn member variable. There where two bugs in this function: - If there is overlap between the row ranges already in maStylesPerColumnBB and the given RowRange, it should be updated to only cover non-overlapping cells. - In the case when the given CellRange spans multiple columns, the RowRange should be applied to all these columns. When the row range given to this method is changed because of earlier set RowRanges in maStylesPerColumn[nCol], the RowRange was not reset to the given method argument for a new column. Change-Id: I4244c4303ca983801c5116cbd26971dd641411ab Reviewed-on: https://gerrit.libreoffice.org/28509 Reviewed-by: Eike Rathke <[email protected]> Tested-by: Jenkins <[email protected]> (cherry picked from commit d16070a30d421098faedd51c4333d1d42163268f) diff --git a/sc/source/filter/oox/sheetdatabuffer.cxx b/sc/source/filter/oox/sheetdatabuffer.cxx index 1c27461..830c9c0 100644 --- a/sc/source/filter/oox/sheetdatabuffer.cxx +++ b/sc/source/filter/oox/sheetdatabuffer.cxx @@ -369,6 +369,10 @@ void SheetDataBuffer::addColXfStyle( sal_Int32 nXfId, sal_Int32 nFormatId, const else { RowStyles& rRowStyles = maStylesPerColumn[ nCol ]; + // Reset row range for each column + aStyleRows.mnStartRow = rAddress.StartRow; + aStyleRows.mnEndRow = rAddress.EndRow; + // If the rowrange style includes rows already // allocated to a style then we need to split // the range style Rows into sections ( to @@ -405,6 +409,8 @@ void SheetDataBuffer::addColXfStyle( sal_Int32 nXfId, sal_Int32 nFormatId, const aRangeRowsSplits.push_back( aSplit ); } } + if ( aStyleRows.mnStartRow <= r.mnEndRow && r.mnEndRow < aStyleRows.mnEndRow ) + aStyleRows.mnStartRow = r.mnEndRow + 1; } std::vector< RowRangeStyle >::iterator splits_it = aRangeRowsSplits.begin(); std::vector< RowRangeStyle >::iterator splits_end = aRangeRowsSplits.end(); commit c265f24e17ca88271a26f7ab2ce85c575dcf3d5a Author: Eike Rathke <[email protected]> Date: Wed Sep 28 13:16:11 2016 +0200 sc-perf: avoid second call to ScAttrArray::Search(), tdf#87101 related In that scenario, of 36791233 calls only 9217 were necessary as most times nRow2 equals nRow1. Change-Id: I14228d065175addee76b9142c98110efe59701e7 (cherry picked from commit e439058541cd02937cf43f399fef8767bd3d4996) diff --git a/sc/source/core/data/attarray.cxx b/sc/source/core/data/attarray.cxx index e326ade..f090213 100644 --- a/sc/source/core/data/attarray.cxx +++ b/sc/source/core/data/attarray.cxx @@ -1198,7 +1198,10 @@ bool ScAttrArray::HasAttrib( SCROW nRow1, SCROW nRow2, sal_uInt16 nMask ) const SCSIZE nStartIndex; SCSIZE nEndIndex; Search( nRow1, nStartIndex ); - Search( nRow2, nEndIndex ); + if (nRow1 != nRow2) + Search( nRow2, nEndIndex ); + else + nEndIndex = nStartIndex; bool bFound = false; for (SCSIZE i=nStartIndex; i<=nEndIndex && !bFound; i++) commit a7dcba36581f8919130dee000467f9c319c886e0 Author: Eike Rathke <[email protected]> Date: Tue Sep 27 21:55:45 2016 +0200 sc-perf: remove one more unnecessary call to TrackFormulas() ... when leaving bulk broadcast. (cherry picked from commit b325f332409ec72d8c5906c64d635e9f083ebfdd) Change-Id: I3d456094ecc7759ed3e58af7901d544126c30b27 diff --git a/sc/source/core/data/bcaslot.cxx b/sc/source/core/data/bcaslot.cxx index a19d28b..cd61d55 100644 --- a/sc/source/core/data/bcaslot.cxx +++ b/sc/source/core/data/bcaslot.cxx @@ -1120,10 +1120,12 @@ void ScBroadcastAreaSlotMachine::LeaveBulkBroadcast() if (--nInBulkBroadcast == 0) { ScBroadcastAreasBulk().swap( aBulkBroadcastAreas); - BulkBroadcastGroupAreas(); + bool bBroadcasted = BulkBroadcastGroupAreas(); // Trigger the "final" tracking. if (pDoc->IsTrackFormulasPending()) pDoc->FinalTrackFormulas(); + else if (bBroadcasted) + pDoc->TrackFormulas(); } } } @@ -1147,10 +1149,10 @@ void ScBroadcastAreaSlotMachine::InsertBulkGroupArea( ScBroadcastArea* pArea, co pSet->set(rRange, true); } -void ScBroadcastAreaSlotMachine::BulkBroadcastGroupAreas() +bool ScBroadcastAreaSlotMachine::BulkBroadcastGroupAreas() { if (maBulkGroupAreas.empty()) - return; + return false; sc::BulkDataHint aHint(*pDoc, nullptr); @@ -1178,8 +1180,8 @@ void ScBroadcastAreaSlotMachine::BulkBroadcastGroupAreas() } maBulkGroupAreas.clear(); - if (bBroadcasted) - pDoc->TrackFormulas(); + + return bBroadcasted; } size_t ScBroadcastAreaSlotMachine::RemoveBulkArea( const ScBroadcastArea* pArea ) diff --git a/sc/source/core/inc/bcaslot.hxx b/sc/source/core/inc/bcaslot.hxx index 3b43a19..e0e54d4 100644 --- a/sc/source/core/inc/bcaslot.hxx +++ b/sc/source/core/inc/bcaslot.hxx @@ -325,7 +325,7 @@ public: void InsertBulkGroupArea( ScBroadcastArea* pArea, const ScRange& rRange ); void RemoveBulkGroupArea( ScBroadcastArea* pArea ); - void BulkBroadcastGroupAreas(); + bool BulkBroadcastGroupAreas(); /// @return: how many removed size_t RemoveBulkArea( const ScBroadcastArea* p ); commit b6702b39d74a23c00ab01e06f782f35d5774d062 Author: Eike Rathke <[email protected]> Date: Tue Sep 27 19:40:31 2016 +0200 sc-perf: avoid repeated TrackFormulas() during bulk broadcast, tdf#87101 rel. Multiple callers involved. Most significantly ScDocument::Broadcast() calls ScDocument::TrackFormulas() individually. Track/collect pending formula cells at the end of the bulk broadcast instead, which gives an instructions read speedup by factor 6 for the broadcast, and an overall speedup in the scenario for inserting the rows by factor ~2 wall clock time. ScDocument::InsertRows() Before, Ir Incl: 282,227,033,656 After, Ir Incl: 66,307,994,805 With cycle detection: ScDocument::TrackFormulas() Before: Ir Incl Ir Self 66,981,644,959 11,913,444,899 After: Ir Incl Ir Self 10,819,556,073 1,973,232,494 (cherry picked from commit 5c841052abdf082b4cbe06784cfdd76f11fafef2) Change-Id: I85fe8b03ecb52cffaa6fa14354b3cc3467ecc111 diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index 70c6b32..39bafdd 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -470,6 +470,9 @@ private: std::unique_ptr<sc::IconSetBitmapMap> m_pIconSetBitmapMap; + bool mbTrackFormulasPending : 1; + bool mbFinalTrackFormulas : 1; + public: bool IsCellInChangeTrack(const ScAddress &cell,Color *pColCellBoder); void GetCellChangeTrackNote(const ScAddress &cell, OUString &strTrackText, bool &pbLeftEdge); @@ -1968,6 +1971,10 @@ public: void AppendToFormulaTrack( ScFormulaCell* pCell ); void RemoveFromFormulaTrack( ScFormulaCell* pCell ); void TrackFormulas( sal_uLong nHintId = SC_HINT_DATACHANGED ); + void SetTrackFormulasPending() { mbTrackFormulasPending = true; } + bool IsTrackFormulasPending() const { return mbTrackFormulasPending; } + void FinalTrackFormulas(); + bool IsFinalTrackFormulas() const { return mbFinalTrackFormulas; } bool IsInFormulaTree( ScFormulaCell* pCell ) const; bool IsInFormulaTrack( ScFormulaCell* pCell ) const; HardRecalcState GetHardRecalcState() { return eHardRecalcState; } diff --git a/sc/source/core/data/bcaslot.cxx b/sc/source/core/data/bcaslot.cxx index 793255f..a19d28b 100644 --- a/sc/source/core/data/bcaslot.cxx +++ b/sc/source/core/data/bcaslot.cxx @@ -1121,6 +1121,9 @@ void ScBroadcastAreaSlotMachine::LeaveBulkBroadcast() { ScBroadcastAreasBulk().swap( aBulkBroadcastAreas); BulkBroadcastGroupAreas(); + // Trigger the "final" tracking. + if (pDoc->IsTrackFormulasPending()) + pDoc->FinalTrackFormulas(); } } } diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx index 832385c..5b701fa 100644 --- a/sc/source/core/data/documen2.cxx +++ b/sc/source/core/data/documen2.cxx @@ -216,7 +216,9 @@ ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) : mbStreamValidLocked( false ), mbUserInteractionEnabled(true), mnNamedRangesLockCount(0), - mbUseEmbedFonts(false) + mbUseEmbedFonts(false), + mbTrackFormulasPending(false), + mbFinalTrackFormulas(false) { SetStorageGrammar( formula::FormulaGrammar::GRAM_STORAGE_DEFAULT); diff --git a/sc/source/core/data/documen7.cxx b/sc/source/core/data/documen7.cxx index 50d8c6a..47423fa 100644 --- a/sc/source/core/data/documen7.cxx +++ b/sc/source/core/data/documen7.cxx @@ -585,6 +585,21 @@ bool ScDocument::IsInFormulaTrack( ScFormulaCell* pCell ) const return pCell->GetPreviousTrack() || pFormulaTrack == pCell; } +void ScDocument::FinalTrackFormulas() +{ + mbTrackFormulasPending = false; + mbFinalTrackFormulas = true; + { + ScBulkBroadcast aBulk( GetBASM()); + // Collect all pending formula cells in bulk. + TrackFormulas(); + } + // A final round not in bulk to track all remaining formula cells and their + // dependents that were collected during ScBulkBroadcast dtor. + TrackFormulas(); + mbFinalTrackFormulas = false; +} + /* The first is broadcasted, the ones that are created through this are appended to the Track by Notify. @@ -593,6 +608,11 @@ bool ScDocument::IsInFormulaTrack( ScFormulaCell* pCell ) const */ void ScDocument::TrackFormulas( sal_uLong nHintId ) { + if (pBASM->IsInBulkBroadcast() && !IsFinalTrackFormulas() && nHintId == SC_HINT_DATACHANGED) + { + SetTrackFormulasPending(); + return; + } if ( pFormulaTrack ) { commit f565919402865237a9410246cc565247d9721964 Author: Eike Rathke <[email protected]> Date: Wed Sep 21 21:42:10 2016 +0200 sc-perf: tdf#87101 add bulk scope for BroadcastRecalcOnRefMove() calls Bulk scope prevents repeated broadcast/notify/track cycles of identical areas during mass broadcasts. Brings insertion time of tdf#87101 bugdoc from 3min30 down to 2min30 Change-Id: I360fd52b622a8a327cdede47ed398260b7e8b4f6 (cherry picked from commit 60d0b992ea3a910be79ae4a8e8b0bb32a358b18a) diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index 088f52a..63b5f3b 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -1240,6 +1240,16 @@ struct BroadcastRecalcOnRefMoveHandler : std::unary_function<ScTable*, void> if (p) p->BroadcastRecalcOnRefMove(); } + + explicit BroadcastRecalcOnRefMoveHandler( ScDocument* pDoc ) : + aSwitch( *pDoc, false), + aBulk( pDoc->GetBASM()) + { + } + +private: + sc::AutoCalcSwitch aSwitch; // first for ctor/dtor order, destroy second + ScBulkBroadcast aBulk; // second for ctor/dtor order, destroy first }; } @@ -1342,7 +1352,7 @@ bool ScDocument::InsertRow( SCCOL nStartCol, SCTAB nStartTab, if (*it) (*it)->SetDirtyIfPostponed(); - std::for_each(maTabs.begin(), maTabs.end(), BroadcastRecalcOnRefMoveHandler()); + std::for_each(maTabs.begin(), maTabs.end(), BroadcastRecalcOnRefMoveHandler( this)); } bRet = true; } @@ -1444,7 +1454,7 @@ void ScDocument::DeleteRow( SCCOL nStartCol, SCTAB nStartTab, if (*it) (*it)->SetDirtyIfPostponed(); - std::for_each(maTabs.begin(), maTabs.end(), BroadcastRecalcOnRefMoveHandler()); + std::for_each(maTabs.begin(), maTabs.end(), BroadcastRecalcOnRefMoveHandler( this)); } pChartListenerCollection->UpdateDirtyCharts(); @@ -1546,7 +1556,7 @@ bool ScDocument::InsertCol( SCROW nStartRow, SCTAB nStartTab, std::for_each(maTabs.begin(), maTabs.end(), SetDirtyIfPostponedHandler()); // Cells containing functions such as CELL, COLUMN or ROW may have // changed their values on relocation. Broadcast them. - std::for_each(maTabs.begin(), maTabs.end(), BroadcastRecalcOnRefMoveHandler()); + std::for_each(maTabs.begin(), maTabs.end(), BroadcastRecalcOnRefMoveHandler( this)); } bRet = true; } @@ -1637,7 +1647,7 @@ void ScDocument::DeleteCol(SCROW nStartRow, SCTAB nStartTab, SCROW nEndRow, SCTA if (*it) (*it)->SetDirtyIfPostponed(); - std::for_each(maTabs.begin(), maTabs.end(), BroadcastRecalcOnRefMoveHandler()); + std::for_each(maTabs.begin(), maTabs.end(), BroadcastRecalcOnRefMoveHandler( this)); } pChartListenerCollection->UpdateDirtyCharts(); commit 46ffad4735129feb0f03df9fda44e0e8f133853f Author: Eike Rathke <[email protected]> Date: Tue Sep 20 22:37:59 2016 +0200 sc-perf: tdf#79023 do not call SvNumberFormatter also for numbers in OOXML Change-Id: Ib565687bff2205da0213f6d523dd2bc42c96ad47 (cherry picked from commit a8a8ff59c5749bbe1f2f58ea8fd42d66e6ae2a81) diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx index f12a199..b51c8f4 100644 --- a/sc/source/core/tool/compiler.cxx +++ b/sc/source/core/tool/compiler.cxx @@ -2783,7 +2783,8 @@ static bool lcl_ParenthesisFollows( const sal_Unicode* p ) bool ScCompiler::IsValue( const OUString& rSym ) { - if (FormulaGrammar::isODFF( GetGrammar())) + const sal_Int32 nFormulaLanguage = FormulaGrammar::extractFormulaLanguage( GetGrammar()); + if (nFormulaLanguage == css::sheet::FormulaLanguage::ODFF || nFormulaLanguage == css::sheet::FormulaLanguage::OOXML) { // Speedup things for ODFF, only well-formed numbers, not locale // dependent nor user input. commit 5a2a22647a7d7f7f9ceaec98460ccce9485781d2 Author: Eike Rathke <[email protected]> Date: Tue Sep 20 21:39:10 2016 +0200 sc-perf: tdf#79023 for ODFF do not call SvNumberFormatter to determine numeric Speedup of this particular function and callees by factor 33 ... 1000 calls for =12345.6789 and =123.456 alternating: Before: Ir Irpc Callee 9859177 9859 ScCompiler::IsValue 6246858 6246 SvNumberFormatter::IsNumberFormat 3496261 3496 SvNumberFormatter::GetStandardIndex After: 298000 298 ScCompiler::IsValue 248000 248 rtl_math_uStringToDouble Change-Id: I36eac8c5fe1b1cbf34dfb480c9e7ca6607769364 (cherry picked from commit 73c7e0921d752df53004ed55735f3e8888cc592f) diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx index 9083dcb..f12a199 100644 --- a/sc/source/core/tool/compiler.cxx +++ b/sc/source/core/tool/compiler.cxx @@ -2774,8 +2774,51 @@ bool ScCompiler::IsOpCode2( const OUString& rName ) return bFound; } +static bool lcl_ParenthesisFollows( const sal_Unicode* p ) +{ + while (*p == ' ') + p++; + return *p == '('; +} + bool ScCompiler::IsValue( const OUString& rSym ) { + if (FormulaGrammar::isODFF( GetGrammar())) + { + // Speedup things for ODFF, only well-formed numbers, not locale + // dependent nor user input. + rtl_math_ConversionStatus eStatus; + sal_Int32 nParseEnd; + double fVal = rtl::math::stringToDouble( rSym, '.', 0, &eStatus, &nParseEnd); + if (nParseEnd != rSym.getLength()) + { + // Not (only) a number. + + if (nParseEnd > 0) + return false; // partially a number => no such thing + + if (lcl_ParenthesisFollows( aFormula.getStr() + nSrcPos)) + return false; // some function name, not a constant + + // Could be TRUE or FALSE constant. + if (rSym.equalsIgnoreAsciiCase("TRUE")) + { + maRawToken.SetDouble( 1.0 ); + return true; + } + if (rSym.equalsIgnoreAsciiCase("FALSE")) + { + maRawToken.SetDouble( 0.0 ); + return true; + } + return false; + } + if (eStatus == rtl_math_ConversionStatus_OutOfRange) + SetError( errIllegalArgument ); + maRawToken.SetDouble( fVal ); + return true; + } + double fVal; sal_uInt32 nIndex = mxSymbols->isEnglish() ? mpFormatter->GetStandardIndex(LANGUAGE_ENGLISH_US) : 0; @@ -2794,10 +2837,7 @@ bool ScCompiler::IsValue( const OUString& rSym ) if (nType == css::util::NumberFormat::LOGICAL) { - const sal_Unicode* p = aFormula.getStr() + nSrcPos; - while( *p == ' ' ) - p++; - if (*p == '(') + if (lcl_ParenthesisFollows( aFormula.getStr() + nSrcPos)) return false; // Boolean function instead. } commit 19cbdad9ee0fd3a98f01d5d09a647cfc14e6bfd5 Author: Justin Luth <[email protected]> Date: Mon Jul 4 18:27:52 2016 +0300 tdf#95367 inherit page style if no new one imported CopyLastHeaderFooter doesn't do much good if the previous section has blank stylenames. (usually because of continuous section breaks). Reviewed-on: https://gerrit.libreoffice.org/26911 Tested-by: Jenkins <[email protected]> Reviewed-by: Justin Luth <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> (cherry picked from commit 1127bed4d943036473dbbda6bcfae1ec0a23ed2e) Change-Id: Ida1e42ab0b650c7c43f06539b3cc058fe5c27919 diff --git a/writerfilter/source/dmapper/PropertyMap.cxx b/writerfilter/source/dmapper/PropertyMap.cxx index fc0f2d5..fe5df46 100644 --- a/writerfilter/source/dmapper/PropertyMap.cxx +++ b/writerfilter/source/dmapper/PropertyMap.cxx @@ -1134,6 +1134,16 @@ throw ( css::beans::UnknownPropertyException, // otherwise apply this section's settings to the new style. // Ensure that FollowPage is inherited first - otherwise GetPageStyle may auto-create a follow when checking FirstPage. SectionPropertyMap* pLastContext = rDM_Impl.GetLastSectionContext(); + if( pLastContext && m_sFirstPageStyleName.isEmpty() ) + m_sFirstPageStyleName = pLastContext->GetPageStyleName( /*bFirst=*/true ); + else + { + HandleMarginsHeaderFooter( /*bFirst=*/true, rDM_Impl ); + GetPageStyle( xPageStyles, xTextFactory, /*bFirst=*/true ); + if( rDM_Impl.IsNewDoc() && m_aFirstPageStyle.is() ) + ApplyProperties_( m_aFirstPageStyle ); + } + if( pLastContext && m_sFollowPageStyleName.isEmpty() ) m_sFollowPageStyleName = pLastContext->GetPageStyleName(); else commit 10fc2022df07b1ee8a29f2ede006b0a720d341cf Author: Justin Luth <[email protected]> Date: Sat Jul 9 07:53:32 2016 +0300 tdf#99090 docx export page-break only inside a paragraph If a paragraph hadn't been started yet, a w:r was being written directly in the /document/body which caused MSWord to complain about a corrupt document. Change-Id: Ie7f629869aab0f3d2405660a033c3f23bbd6baca Reviewed-on: https://gerrit.libreoffice.org/26771 Tested-by: Jenkins <[email protected]> Reviewed-by: Justin Luth <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> (cherry picked from commit 07fb94655f4745eb4e80bf6e8d4cdd95371f23bb) diff --git a/sw/qa/extras/ooxmlexport/data/tdf99090_pgbrkAfterTable.docx b/sw/qa/extras/ooxmlexport/data/tdf99090_pgbrkAfterTable.docx new file mode 100755 index 0000000..c914f35 Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf99090_pgbrkAfterTable.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx index 5dc2f68..c575a6a 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx @@ -953,6 +953,13 @@ DECLARE_OOXMLEXPORT_TEST(testTdf92521, "tdf92521.odt") assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:pPr/w:sectPr", 1); } +DECLARE_OOXMLEXPORT_TEST(testTdf99090_pgbrkAfterTable, "tdf99090_pgbrkAfterTable.docx") +{ + if (xmlDocPtr pXmlDoc = parseExport("word/document.xml")) + // There should be a regular page break that's in the middle of the document: right after the table. + assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/w:br", 1); +} + DECLARE_OOXMLEXPORT_TEST(testTdf96750_landscapeFollow, "tdf96750_landscapeFollow.docx") { uno::Reference<beans::XPropertySet> xStyle(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY); commit 377115804894411b10de93a6e53704ba468a9add Author: Justin Luth <[email protected]> Date: Wed Jul 6 10:04:04 2016 +0300 tdf75573 docx - complete frames before starting alternate streams An unused odd header was set to be discarded. The handling of unregistered frames occurred at the same time, and thus ended up being discarded as well. Since a frame shouldn't encompass both the alternate stream and the current stream, finalize any unfinished frames first. Change-Id: Ie9123769724da461dd265936aa6b97de7f4dfbbc Reviewed-on: https://gerrit.libreoffice.org/26972 Tested-by: Jenkins <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> (cherry picked from commit ecea3431ca761369d8180a74eba2877533050516) diff --git a/sw/qa/extras/ooxmlimport/data/tdf75573_page1frame.docx b/sw/qa/extras/ooxmlimport/data/tdf75573_page1frame.docx new file mode 100644 index 0000000..d6bc29d Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/tdf75573_page1frame.docx differ diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx index 281ae83..c3c4728 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx @@ -1740,6 +1740,13 @@ DECLARE_OOXMLIMPORT_TEST(testfdo76583, "fdo76583.docx") lcl_countTextFrames( mxComponent, 1 ); } +DECLARE_OOXMLIMPORT_TEST(testTdf75573, "tdf75573_page1frame.docx") +{ + // the problem was that an odd header was defined but not used, flagged as + // discardable, and then the unrelated frame was also discarded. + lcl_countTextFrames( mxComponent, 1 ); +} + DECLARE_OOXMLIMPORT_TEST(testFdo43093, "fdo43093.docx") { // The problem was that the direction and alignment are not correct for RTL paragraphs. diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index 28091d6..6ccbb83 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -5279,6 +5279,10 @@ void DomainMapper_Impl::substream(Id rName, appendTableHandler(); getTableManager().startLevel(); + //finalize any waiting frames before starting alternate streams + CheckUnregisteredFrameConversion(); + ExecuteFrameConversion(); + //import of page header/footer switch( rName ) commit 92ff1627e3eef3b838500e058d77d8c198ec9566 Author: Justin Luth <[email protected]> Date: Sat Jul 23 08:23:08 2016 +0300 tdf#75573 allow style to define vAnchor If the default property value is valid, a style is never able to override. oddball default caused by commit 20c1a485774c7586401f6c1821c52f0bc39cb84a Rüdiger Timm <[email protected]> 2008-04-18 11:36:12 (GMT) INTEGRATION: CWS xmlfilter04 (1.22.14); FILE MERGED 2008/03/05 11:07:44 os 1.22.14.3: default vAnchor changed Reviewed-on: https://gerrit.libreoffice.org/27454 Tested-by: Jenkins <[email protected]> Reviewed-by: Justin Luth <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> (cherry picked from commit eb345a155bc9cb92fffd3e5ea0269207b3bac0f1) Change-Id: I665b52ae75a9282d51c79f3351315cf3fed4776c diff --git a/writerfilter/source/dmapper/PropertyMap.cxx b/writerfilter/source/dmapper/PropertyMap.cxx index e1d5987..fc0f2d5 100644 --- a/writerfilter/source/dmapper/PropertyMap.cxx +++ b/writerfilter/source/dmapper/PropertyMap.cxx @@ -1573,7 +1573,7 @@ ParagraphProperties::ParagraphProperties() : m_h(-1), m_nWrap(-1), m_hAnchor(-1), - m_vAnchor(text::RelOrientation::FRAME), + m_vAnchor(-1), m_x(-1), m_bxValid( false ), m_y(-1), @@ -1653,7 +1653,7 @@ void ParagraphProperties::ResetFrameProperties() m_h = -1; m_nWrap = -1; m_hAnchor = -1; - m_vAnchor = text::RelOrientation::FRAME; + m_vAnchor = -1; m_x = -1; m_bxValid = false; m_y = -1; commit a895a7051f2cca37595f755212399843116678c9 Author: Justin Luth <[email protected]> Date: Sat Jul 23 09:10:29 2016 +0300 tdf#75573 - docx don't remove frame anchor paragraph frames anchor to the following paragraph. Don't remove an empty paragraph if it follows a frame or else the frame will jump to the next page. This gets a bit complicated because headers/footers contain paragraphs that aren't really "following" the frame paragraph, and so wouldn't be used as anchor paragraphs. There may be similar sub-paragraphs for comments etc, but exceptions for those can be added when proof documents are found. Reviewed-on: https://gerrit.libreoffice.org/27455 Tested-by: Jenkins <[email protected]> Reviewed-by: Justin Luth <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> (cherry picked from commit 91ad1017b609be6fceccd392006dd9ab60724352) Change-Id: I46988b40abe65e23a5c407dde38a951937978005 diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index ae201aa..5a1bcd9 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -3221,16 +3221,18 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len) bool bSingleParagraph = m_pImpl->GetIsFirstParagraphInSection() && m_pImpl->GetIsLastParagraphInSection(); // If the paragraph contains only the section properties and it has // no runs, we should not create a paragraph for it in Writer, unless that would remove the whole section. - bool bRemove = !m_pImpl->GetParaChanged() && m_pImpl->GetParaSectpr() && !bSingleParagraph && !m_pImpl->GetIsDummyParaAddedForTableInSection(); - PropertyMapPtr xContext = bRemove ? m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH) : PropertyMapPtr(); - if (xContext) + bool bRemove = !m_pImpl->GetParaChanged() && m_pImpl->GetParaSectpr() + && !bSingleParagraph + && !m_pImpl->GetIsDummyParaAddedForTableInSection() + && !m_pImpl->GetIsLastParagraphFramed(); + if (bRemove) { // tdf#97417 delete numbering of the paragraph // it will be deleted anyway, and the numbering would be copied // to the next paragraph in sw SplitNode and then be applied to // every following paragraph - xContext->Erase(PROP_NUMBERING_RULES); - xContext->Erase(PROP_NUMBERING_LEVEL); + m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)->Erase(PROP_NUMBERING_RULES); + m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)->Erase(PROP_NUMBERING_LEVEL); } m_pImpl->SetParaSectpr(false); m_pImpl->finishParagraph(m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)); diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index 83f9d9c..28091d6 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -216,6 +216,7 @@ DomainMapper_Impl::DomainMapper_Impl( m_bIsFirstParaInSection( true ), m_bDummyParaAddedForTableInSection( false ), m_bTextFrameInserted(false), + m_bIsLastParagraphFramed( false ), m_bIsLastParaInSection( false ), m_bIsLastSectionGroup( false ), m_bIsInComments( false ), @@ -1189,6 +1190,16 @@ void DomainMapper_Impl::finishParagraph( PropertyMapPtr pPropertyMap ) } } + if( (pParaContext && pParaContext->IsFrameMode()) + || (IsInHeaderFooter() && GetIsLastParagraphFramed()) ) + { + SetIsLastParagraphFramed(true); + } + else + { + SetIsLastParagraphFramed(false); + } + m_bParaChanged = false; if (!pParaContext || !pParaContext->IsFrameMode()) { // If the paragraph is in a frame, it's not a paragraph of the section itself. diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx index b602a70..7204c59 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx @@ -436,6 +436,7 @@ private: bool m_bIsFirstParaInSection; bool m_bDummyParaAddedForTableInSection; bool m_bTextFrameInserted; + bool m_bIsLastParagraphFramed; bool m_bIsLastParaInSection; bool m_bIsLastSectionGroup; bool m_bIsInComments; @@ -524,6 +525,8 @@ public: bool GetIsDummyParaAddedForTableInSection() { return m_bDummyParaAddedForTableInSection;} void SetIsTextFrameInserted( bool bIsInserted ); bool GetIsTextFrameInserted() { return m_bTextFrameInserted;} + void SetIsLastParagraphFramed( bool bIsFramed ) { m_bIsLastParagraphFramed = bIsFramed; } + bool GetIsLastParagraphFramed() { return m_bIsLastParagraphFramed; } void SetParaSectpr(bool bParaSectpr); bool GetParaSectpr() { return m_bParaSectpr;} commit b77b40eb02a196b0899fecc864c238458bbb7e52 Author: Justin Luth <[email protected]> Date: Sat Jul 23 14:56:55 2016 +0300 tdf#99434 docx enable docprotection only when enforced Change-Id: I9454a34d7b386acffc50e74d5ef6eed1966d572a Reviewed-on: https://gerrit.libreoffice.org/27456 Tested-by: Jenkins <[email protected]> Reviewed-by: Justin Luth <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> (cherry picked from commit d40ed9d0cd3c4a66d4ebf65d3a530f0fc5a8da17) diff --git a/writerfilter/source/dmapper/SettingsTable.cxx b/writerfilter/source/dmapper/SettingsTable.cxx index 572ad4e..8307a01 100644 --- a/writerfilter/source/dmapper/SettingsTable.cxx +++ b/writerfilter/source/dmapper/SettingsTable.cxx @@ -150,8 +150,11 @@ void SettingsTable::lcl_attribute(Id nName, Value & val) m_pImpl->m_pCurrentCompatSetting[2].Value <<= sStringValue; break; case NS_ooxml::LN_CT_DocProtect_edit: - m_pImpl->m_bProtectForm = val.getInt() == NS_ooxml::LN_Value_doc_ST_DocProtect_forms; - break; + m_pImpl->m_bProtectForm = (nIntValue == NS_ooxml::LN_Value_doc_ST_DocProtect_forms); + break; + case NS_ooxml::LN_CT_DocProtect_enforcement: + m_pImpl->m_bProtectForm &= (bool)nIntValue; + break; default: { #ifdef DEBUG_WRITERFILTER commit 1e12fcfcdded86098b661bd391812eff86c79eed Author: Oliver Specht <[email protected]> Date: Mon Apr 25 13:25:39 2016 +0200 tdf#99434: import/export documentProtection-forms from .docx incl. test the setting <w:documentProtection w:edit="forms"> disables editing of content outside of form controls. Change-Id: I0d11373d9010778ed5798598020e453cde06fa0f Reviewed-on: https://gerrit.libreoffice.org/24365 Tested-by: Jenkins <[email protected]> Reviewed-by: Oliver Specht <[email protected]> (cherry picked from commit 523a3d18e98cd51aa8bf76cf76314a22ddc2b2cf) diff --git a/sw/qa/extras/ooxmlexport/data/protectedform.docx b/sw/qa/extras/ooxmlexport/data/protectedform.docx new file mode 100755 index 0000000..a67d880 Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/protectedform.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx index 612e7bf..8f41610 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx @@ -800,6 +800,16 @@ DECLARE_OOXMLEXPORT_TEST(testTdf91594, "tdf91594.docx") CPPUNIT_ASSERT_EQUAL(OUString("Wingdings"), getProperty<OUString>(xRun, "CharFontNameAsian")); CPPUNIT_ASSERT_EQUAL(OUString("Wingdings"), getProperty<OUString>(xRun, "CharFontNameComplex")); } +DECLARE_OOXMLEXPORT_TEST(testTDF99434, "protectedform.docx") +{ + css::uno::Reference<css::lang::XMultiServiceFactory> m_xTextFactory(mxComponent, uno::UNO_QUERY); + uno::Reference< beans::XPropertySet > xSettings(m_xTextFactory->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY); + uno::Any aProtect = xSettings->getPropertyValue("ProtectForm"); + bool bProt = false; + aProtect >>= bProt; + CPPUNIT_ASSERT(bProt); +} + CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx index b7d98fb..e4ea861 100644 --- a/sw/source/filter/ww8/docxexport.cxx +++ b/sw/source/filter/ww8/docxexport.cxx @@ -869,6 +869,12 @@ void DocxExport::WriteSettings() pFS->singleElementNS( XML_w, XML_defaultTabStop, FSNS( XML_w, XML_val ), OString::number( m_aSettings.defaultTabStop).getStr(), FSEND ); + // Protect form + if( m_pDoc->getIDocumentSettingAccess().get( DocumentSettingId::PROTECT_FORM )) + { + pFS->singleElementNS( XML_w, XML_documentProtection, FSNS(XML_w, XML_edit), "forms", FSNS(XML_w, XML_enforcement), "1", FSEND ); + } + // Automatic hyphenation: it's a global setting in Word, it's a paragraph setting in Writer. // Use the setting from the default style. SwTextFormatColl* pColl = m_pDoc->getIDocumentStylePoolAccess().GetTextCollFromPool(RES_POOLCOLL_STANDARD, /*bRegardLanguage=*/false); diff --git a/sw/source/filter/ww8/wrtw8sty.cxx b/sw/source/filter/ww8/wrtw8sty.cxx index 7ef8b1c..75b266a 100644 --- a/sw/source/filter/ww8/wrtw8sty.cxx +++ b/sw/source/filter/ww8/wrtw8sty.cxx @@ -70,6 +70,7 @@ #include "ww8attributeoutput.hxx" #include "docxattributeoutput.hxx" #include "rtfattributeoutput.hxx" +#include <IDocumentSettingAccess.hxx> #include <unordered_set> @@ -1526,7 +1527,9 @@ void MSWordExportBase::SectionProperties( const WW8_SepInfo& rSepInfo, WW8_PdAtt AttrOutput().SectFootnoteEndnotePr(); // forms - AttrOutput().SectionFormProtection( rSepInfo.IsProtected() ); + bool formProtection = m_pDoc->getIDocumentSettingAccess().get( DocumentSettingId::PROTECT_FORM ); + formProtection |= rSepInfo.IsProtected(); + AttrOutput().SectionFormProtection( formProtection ); // line numbers const SwLineNumberInfo& rLnNumInfo = m_pDoc->GetLineNumberInfo(); diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index e0dba9c..83f9d9c 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -5042,10 +5042,11 @@ void DomainMapper_Impl::ApplySettingsTable() if( m_pSettingsTable->GetEmbedSystemFonts()) xSettings->setPropertyValue( getPropertyName( PROP_EMBED_SYSTEM_FONTS ), uno::makeAny(true) ); xSettings->setPropertyValue("AddParaTableSpacing", uno::makeAny(m_pSettingsTable->GetDoNotUseHTMLParagraphAutoSpacing())); - // Web Layout. if (m_pSettingsTable->GetView() == NS_ooxml::LN_Value_doc_ST_View_web) xSettings->setPropertyValue("InBrowseMode", uno::makeAny(true)); + if( m_pSettingsTable->GetProtectForm() ) + xSettings->setPropertyValue("ProtectForm", uno::makeAny( true )); } catch(const uno::Exception&) { diff --git a/writerfilter/source/dmapper/SettingsTable.cxx b/writerfilter/source/dmapper/SettingsTable.cxx index 6aae48d..572ad4e 100644 --- a/writerfilter/source/dmapper/SettingsTable.cxx +++ b/writerfilter/source/dmapper/SettingsTable.cxx @@ -66,6 +66,8 @@ struct SettingsTable_Impl bool m_bWidowControl; bool m_bSplitPgBreakAndParaMark; bool m_bMirrorMargin; + bool m_bProtectForm; + uno::Sequence<beans::PropertyValue> m_pThemeFontLangProps; std::vector<beans::PropertyValue> m_aCompatSettings; @@ -91,6 +93,7 @@ struct SettingsTable_Impl , m_bWidowControl(false) , m_bSplitPgBreakAndParaMark(false) , m_bMirrorMargin(false) + , m_bProtectForm(false) , m_pThemeFontLangProps(3) , m_pCurrentCompatSetting(3) {} @@ -146,6 +149,9 @@ void SettingsTable::lcl_attribute(Id nName, Value & val) m_pImpl->m_pCurrentCompatSetting[2].Name = "val"; m_pImpl->m_pCurrentCompatSetting[2].Value <<= sStringValue; break; + case NS_ooxml::LN_CT_DocProtect_edit: + m_pImpl->m_bProtectForm = val.getInt() == NS_ooxml::LN_Value_doc_ST_DocProtect_forms; + break; default: { #ifdef DEBUG_WRITERFILTER @@ -343,6 +349,10 @@ bool SettingsTable::GetMirrorMarginSettings() const return m_pImpl->m_bMirrorMargin; } +bool SettingsTable::GetProtectForm() const +{ + return m_pImpl->m_bProtectForm; +} uno::Sequence<beans::PropertyValue> SettingsTable::GetThemeFontLangProperties() const { return m_pImpl->m_pThemeFontLangProps; diff --git a/writerfilter/source/dmapper/SettingsTable.hxx b/writerfilter/source/dmapper/SettingsTable.hxx index 5a0d688..e0a000c 100644 --- a/writerfilter/source/dmapper/SettingsTable.hxx +++ b/writerfilter/source/dmapper/SettingsTable.hxx @@ -71,6 +71,7 @@ class SettingsTable : public LoggedProperties, public LoggedTable bool GetSplitPgBreakAndParaMark() const; bool GetMirrorMarginSettings() const; bool GetNoColumnBalance() const; + bool GetProtectForm() const; css::uno::Sequence<css::beans::PropertyValue> GetThemeFontLangProperties() const; commit 958ead3894877de753d1e163f96d3414883e6d42 Author: Bartosz Kosiorek <[email protected]> Date: Tue Jul 19 00:26:54 2016 +0200 tdf#100946 Fix width calculation and add customWidth support (.xlsx) On some MS Excel version (OS X), the column "width" is not applied, if "customWidth" key (in "col") is not set to "true". It means that in case of .xlsx files, exported by LibreOffice, all columns have default width. To resolve that "customWidth" key was added during export into .xlsx file format. During development it appears that Default Column Width is wrongly calculated, and it was done not according to MS documentation. This issue was also fixed. After fix default column width is properly set. MS documentation: https://msdn.microsoft.com/en-us/library/documentformat.openxml.spreadsheet.column.aspx (cherry picked from commit 40d892a2db4d750aaf0562c63004e693c028273c) Change-Id: I0d1944081a5ea445d1e4284db62e9b4d504bf1c0 diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx index cff11cd..adf8702 100644 --- a/sc/qa/unit/subsequent_filters-test.cxx +++ b/sc/qa/unit/subsequent_filters-test.cxx @@ -1622,7 +1622,7 @@ void ScFiltersTest::testChartImportXLS() const SdrOle2Obj* pOleObj = getSingleChartObject(rDoc, 0); CPPUNIT_ASSERT_MESSAGE("Failed to retrieve a chart object from the 2nd sheet.", pOleObj); - CPPUNIT_ASSERT_EQUAL(11148L, pOleObj->GetLogicRect().getWidth()); + CPPUNIT_ASSERT_EQUAL(11137L, pOleObj->GetLogicRect().getWidth()); CPPUNIT_ASSERT(8640L > pOleObj->GetLogicRect().getHeight()); xDocSh->DoClose(); diff --git a/sc/source/filter/excel/xetable.cxx b/sc/source/filter/excel/xetable.cxx index 1dc6dbb..5f75d2e 100644 --- a/sc/source/filter/excel/xetable.cxx +++ b/sc/source/filter/excel/xetable.cxx @@ -1561,20 +1561,28 @@ XclExpDefcolwidth::XclExpDefcolwidth( const XclExpRoot& rRoot ) : bool XclExpDefcolwidth::IsDefWidth( sal_uInt16 nXclColWidth ) const { double fNewColWidth = lclGetCorrectedColWidth( GetRoot(), nXclColWidth ); + // This formula is taking number of characters with GetValue() + // and it is translating it into default column width. 0.5 means half character. + // https://msdn.microsoft.com/en-us/library/documentformat.openxml.spreadsheet.column.aspx + long defaultColumnWidth = static_cast< long >( 256.0 * ( GetValue() + 0.5 ) ); + // exactly matched, if difference is less than 1/16 of a character to the left or to the right - return std::abs( static_cast< long >( GetValue() * 256.0 - fNewColWidth + 0.5 ) ) < 16; + return std::abs( defaultColumnWidth - fNewColWidth ) < 16; } void XclExpDefcolwidth::SetDefWidth( sal_uInt16 nXclColWidth ) { double fNewColWidth = lclGetCorrectedColWidth( GetRoot(), nXclColWidth ); - SetValue( limit_cast< sal_uInt16 >( fNewColWidth / 256.0 + 0.5 ) ); + // This function is taking width and translate it into number of characters + // Next this number of characters are stored. 0.5 means half character. + SetValue( limit_cast< sal_uInt16 >( fNewColWidth / 256.0 - 0.5 ) ); } XclExpColinfo::XclExpColinfo( const XclExpRoot& rRoot, SCCOL nScCol, SCROW nLastScRow, XclExpColOutlineBuffer& rOutlineBfr ) : XclExpRecord( EXC_ID_COLINFO, 12 ), XclExpRoot( rRoot ), + mbCustomWidth( false ), mnWidth( 0 ), mnScWidth( 0 ), mnFlags( 0 ), @@ -1592,9 +1600,14 @@ XclExpColinfo::XclExpColinfo( const XclExpRoot& rRoot, sal_uInt16 nScWidth = rDoc.GetColWidth( nScCol, nScTab ); mnWidth = XclTools::GetXclColumnWidth( nScWidth, GetCharWidth() ); mnScWidth = sc::TwipsToHMM( nScWidth ); + // column flags ::set_flag( mnFlags, EXC_COLINFO_HIDDEN, rDoc.ColHidden(nScCol, nScTab) ); + // TODO Do we need to save customWidth information also for .xls (with mnFlags)? + XclExpDefcolwidth defColWidth = XclExpDefcolwidth( rRoot ); + mbCustomWidth = !defColWidth.IsDefWidth( mnWidth ); + // outline data rOutlineBfr.Update( nScCol ); ::set_flag( mnFlags, EXC_COLINFO_COLLAPSED, rOutlineBfr.IsCollapsed() ); @@ -1650,7 +1663,7 @@ void XclExpColinfo::SaveXml( XclExpXmlStream& rStrm ) rStrm.GetCurrentStream()->singleElement( XML_col, // OOXTODO: XML_bestFit, XML_collapsed, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_COLINFO_COLLAPSED ) ), - // OOXTODO: XML_customWidth, + XML_customWidth, XclXmlUtils::ToPsz( mbCustomWidth ), XML_hidden, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_COLINFO_HIDDEN ) ), XML_max, OString::number( (nLastXclCol+1) ).getStr(), XML_min, OString::number( (mnFirstXclCol+1) ).getStr(), diff --git a/sc/source/filter/excel/xltools.cxx b/sc/source/filter/excel/xltools.cxx index f2a786c..b64d940 100644 --- a/sc/source/filter/excel/xltools.cxx +++ b/sc/source/filter/excel/xltools.cxx @@ -312,13 +312,13 @@ sal_Int32 XclTools::GetHmmFromTwips( sal_Int32 nTwips ) sal_uInt16 XclTools::GetScColumnWidth( sal_uInt16 nXclWidth, long nScCharWidth ) { - double fScWidth = static_cast< double >( nXclWidth ) / 256.0 * nScCharWidth + 0.5; + double fScWidth = static_cast< double >( nXclWidth ) / 256.0 * nScCharWidth - 0.5; return limit_cast< sal_uInt16 >( fScWidth ); } sal_uInt16 XclTools::GetXclColumnWidth( sal_uInt16 nScWidth, long nScCharWidth ) { - double fXclWidth = static_cast< double >( nScWidth ) * 256.0 / nScCharWidth + 0.5; + double fXclWidth = ( static_cast< double >( nScWidth ) + 0.5 ) * 256.0 / nScCharWidth; return limit_cast< sal_uInt16 >( fXclWidth ); } @@ -629,6 +629,7 @@ bool XclTools::GetBuiltInStyleId( sal_uInt8& rnStyleId, sal_uInt8& rnLevel, cons return true; } } + rnStyleId = EXC_STYLE_USERDEF; rnLevel = EXC_STYLE_NOLEVEL; return false; diff --git a/sc/source/filter/inc/xetable.hxx b/sc/source/filter/inc/xetable.hxx index 3a29f35..e6318fd 100644 --- a/sc/source/filter/inc/xetable.hxx +++ b/sc/source/filter/inc/xetable.hxx @@ -683,6 +683,9 @@ private: if the '0' character fits 10 times into a cell in a column with default width. + Half of character width is reserved for non character display. + It is margin padding (two on each side) and padding for the gridlines. + The IsDefWidth() function returns true, if the passed width (measured in 1/256 of the width of the '0' character) could be converted exactly to the default width. If the passed width is rounded up or down to get the default @@ -740,6 +743,7 @@ private: private: XclExpXFId maXFId; /// The XF identifier for column default format. + bool mbCustomWidth; /// True = Column width is different from default width sal_uInt16 mnWidth; /// Excel width of the column. sal_uInt16 mnScWidth; /// Calc width of the column. sal_uInt16 mnFlags; /// Additional column flags. diff --git a/sc/source/filter/inc/xltools.hxx b/sc/source/filter/inc/xltools.hxx index 67c8f3c..c3cf9bc 100644 --- a/sc/source/filter/inc/xltools.hxx +++ b/sc/source/filter/inc/xltools.hxx @@ -135,6 +135,7 @@ public: static sal_Int32 GetHmmFromTwips( sal_Int32 nTwips ); /** Returns the Calc column width (twips) for the passed Excel width. + * Excel Column width is stored as 1/256th of a character. @param nScCharWidth Width of the '0' character in Calc (twips). */ static sal_uInt16 GetScColumnWidth( sal_uInt16 nXclWidth, long nScCharWidth ); /** Returns the Excel column width for the passed Calc width (twips). diff --git a/sc/source/filter/oox/worksheethelper.cxx b/sc/source/filter/oox/worksheethelper.cxx index e817d25..b503235 100644 --- a/sc/source/filter/oox/worksheethelper.cxx +++ b/sc/source/filter/oox/worksheethelper.cxx @@ -1183,11 +1183,10 @@ sal_Int32 getColumnWidth(UnitConverter& rConverter, double nWidth) long nPixel = aDev->LogicToPixel(Point(nCoeff, 0), MapMode(MAP_100TH_MM)).getX(); - // the 1.047 has been experimentally chosen based on measurements with a screen ruler // TODO: fix the display of cells so that it no longer requires this hack // algorithm from OOXML spec part1: 18.3.1.13 - sal_Int32 nColWidthPixel= std::floor(((256*nWidth + std::floor(128.0/nPixel))/256.0)*nPixel) * 1.047; + sal_Int32 nColWidthPixel= std::floor( ( ( 256 * nWidth + std::floor( 128.0 / nPixel ) ) / 256.0 ) * nPixel ) * 1.047; return aDev->PixelToLogic(Point(nColWidthPixel, 0), MapMode(MAP_100TH_MM)).getX(); } commit 9fae9fd2e156dc1c2790dd402787e62d94b96d6e Author: Justin Luth <[email protected]> Date: Mon Jul 4 21:39:37 2016 +0300 tdf#64372 docx import: don't ignore continuous section break If the previous break was also a continuous section break, this break was simply ignored ever since commit 1fdd61db155cf63d5dd55cc2bfb45af33796e131. Thus, the default handler took over and assigned PROP_PAGE_DESC if there was some kind of page style known (either the first page/Standard defaults or any "converted" styles that had been created) which effectively became a new page break. Reviewed-on: https://gerrit.libreoffice.org/26567 Tested-by: Jenkins <[email protected]> Reviewed-by: Justin Luth <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> (cherry picked from commit a60b2f7c227709d27d6294558fd396557a9ffd20) Change-Id: I839570b0330ba274552cc671014e997c42765f4b diff --git a/sw/qa/extras/ooxmlexport/data/tdf64372_continuousBreaks.docx b/sw/qa/extras/ooxmlexport/data/tdf64372_continuousBreaks.docx new file mode 100755 index 0000000..20ad82b Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf64372_continuousBreaks.docx differ diff --git a/sw/qa/extras/ooxmlexport/data/tdf92724_continuousBreaksComplex.docx b/sw/qa/extras/ooxmlexport/data/tdf92724_continuousBreaksComplex.docx new file mode 100755 index 0000000..808d056 Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf92724_continuousBreaksComplex.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx index 9751b2a..5dc2f68 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx @@ -959,6 +959,16 @@ DECLARE_OOXMLEXPORT_TEST(testTdf96750_landscapeFollow, "tdf96750_landscapeFollow CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xStyle, "IsLandscape")); } +DECLARE_OOXMLEXPORT_TEST(testTdf64372_continuousBreaks,"tdf64372_continuousBreaks.docx") +{ + //There are no page breaks, so everything should be on the first page. + uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(xModel->getCurrentController(), uno::UNO_QUERY); + uno::Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(), uno::UNO_QUERY); + xCursor->jumpToLastPage(); + CPPUNIT_ASSERT_EQUAL(sal_Int16(1), xCursor->getPage()); +} + DECLARE_OOXMLEXPORT_TEST(testTdf81345_045Original,"tdf81345.docx") { //Header wasn't replaced and columns were missing because no new style was created. diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx index a9c346e..281ae83 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx @@ -994,6 +994,13 @@ DECLARE_OOXMLIMPORT_TEST(testN780843, "n780843.docx") uno::Reference<beans::XPropertySet> xPageStyle(getStyles("PageStyles")->getByName(aStyleName), uno::UNO_QUERY); uno::Reference<text::XTextRange> xFooter = getProperty< uno::Reference<text::XTextRange> >(xPageStyle, "FooterText"); CPPUNIT_ASSERT_EQUAL(OUString("shown footer"), xFooter->getString()); + + //tdf64372 this document should only have one page break (2 pages, not 3) + uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(xModel->getCurrentController(), uno::UNO_QUERY); + uno::Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(), uno::UNO_QUERY); + xCursor->jumpToLastPage(); + CPPUNIT_ASSERT_EQUAL(sal_Int16(2), xCursor->getPage()); } DECLARE_OOXMLIMPORT_TEST(testShadow, "imgshadow.docx") diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index 0dc8a65..ae201aa 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -1722,17 +1722,9 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext ) OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); if(pSectionContext) { - // Ignore continuous section break at the end of the document, if the previous section had the same type as well - // It makes the importer lose margin settings with no benefit + //continuous break only allowed if it is not the only section break SectionPropertyMap* pLastContext = m_pImpl->GetLastSectionContext(); - int nPrevBreakType = NS_ooxml::LN_Value_ST_SectionMark_continuous; - bool bHasPrevSection = false; - if (pLastContext) - { - bHasPrevSection = true; - nPrevBreakType = pLastContext->GetBreakType(); - } - if (m_pImpl->GetParaSectpr() || nIntValue != static_cast<sal_Int32>(NS_ooxml::LN_Value_ST_SectionMark_continuous) || (bHasPrevSection && nPrevBreakType != nIntValue)) + if ( nIntValue != static_cast<sal_Int32>(NS_ooxml::LN_Value_ST_SectionMark_continuous) || pLastContext || m_pImpl->GetParaSectpr() ) pSectionContext->SetBreakType( nIntValue ); } break; commit 4b2370b41b2e93979979be7f4d0b248174730982 Author: Abhilash Singh <[email protected]> Date: Fri Jul 22 11:48:45 2016 +0530 tdf#44282 fix missing space for numbered lists in TOC Change-Id: I6baa6c775ac6142e4ba4197ce4d164628ef0ba1e Reviewed-on: https://gerrit.libreoffice.org/27423 Tested-by: Jenkins <[email protected]> Reviewed-by: jan iversen <[email protected]> (cherry picked from commit ce95e39f8e952159844e9dc04a1df402bb103634) diff --git a/sw/source/core/tox/ToxTextGenerator.cxx b/sw/source/core/tox/ToxTextGenerator.cxx index cc181de..5c0514f 100644 --- a/sw/source/core/tox/ToxTextGenerator.cxx +++ b/sw/source/core/tox/ToxTextGenerator.cxx @@ -87,6 +87,10 @@ ToxTextGenerator::GetNumStringOfFirstNode( const SwTOXSortTabBase& rBase, bool b sRet = pNd->GetNumString(bUsePrefix, nLevel); } + if(sRet != "") { + sRet += " ";// Makes sure spacing is done only when there is outline numbering + } + return sRet; } commit 82ff907974ad666bb9183f511c391ce2acf00515 Author: Justin Luth <[email protected]> Date: Fri Jul 29 22:03:55 2016 +0300 docx - inherit FollowPage before FirstPage GetPageStyle(bTitlePage == true) will check if the follow exists. If not, it will create a new style - which defeats the purpose of inheriting from the previous section if this section didn't define a new follow. Change-Id: I235bc9b7bc35c9875295733313a6452ba8896c4f Reviewed-on: https://gerrit.libreoffice.org/27700 Tested-by: Jenkins <[email protected]> Reviewed-by: Justin Luth <[email protected]> (cherry picked from commit 4a6329badc9c8679945d1a1ec225e26e15d7bfd2) diff --git a/writerfilter/source/dmapper/PropertyMap.cxx b/writerfilter/source/dmapper/PropertyMap.cxx index 180196e..e1d5987 100644 --- a/writerfilter/source/dmapper/PropertyMap.cxx +++ b/writerfilter/source/dmapper/PropertyMap.cxx @@ -1132,17 +1132,8 @@ throw ( css::beans::UnknownPropertyException, // if no new styles have been created for this section, inherit from the previous section, // otherwise apply this section's settings to the new style. + // Ensure that FollowPage is inherited first - otherwise GetPageStyle may auto-create a follow when checking FirstPage. SectionPropertyMap* pLastContext = rDM_Impl.GetLastSectionContext(); - if( pLastContext && m_sFirstPageStyleName.isEmpty() ) - m_sFirstPageStyleName = pLastContext->GetPageStyleName( /*bFirst=*/true ); - else - { - HandleMarginsHeaderFooter( /*bFirst=*/true, rDM_Impl ); - GetPageStyle( xPageStyles, xTextFactory, /*bFirst=*/true ); - if( rDM_Impl.IsNewDoc() && m_aFirstPageStyle.is() ) - ApplyProperties_( m_aFirstPageStyle ); - } - if( pLastContext && m_sFollowPageStyleName.isEmpty() ) m_sFollowPageStyleName = pLastContext->GetPageStyleName(); else @@ -1153,6 +1144,16 @@ throw ( css::beans::UnknownPropertyException, ApplyProperties_( m_aFollowPageStyle ); } + if( pLastContext && m_sFirstPageStyleName.isEmpty() ) + m_sFirstPageStyleName = pLastContext->GetPageStyleName( /*bFirst=*/true ); + else + { + HandleMarginsHeaderFooter( /*bFirst=*/true, rDM_Impl ); + GetPageStyle( xPageStyles, xTextFactory, /*bFirst=*/true ); + if( rDM_Impl.IsNewDoc() && m_aFirstPageStyle.is() ) + ApplyProperties_( m_aFirstPageStyle ); + } + GetPageStyle( xPageStyles, xTextFactory, /*bFirst=*/true ); // Chain m_aFollowPageStyle to be after m_aFirstPageStyle m_aFirstPageStyle->setPropertyValue( "FollowStyle", uno::makeAny(m_sFollowPageStyleName) ); commit 703735db025347626294926059854e25c228c626 Author: Bartosz Kosiorek <[email protected]> Date: Fri Aug 12 10:51:11 2016 +0200 tdf#70565 Set correct default values to "0" of xfId attribute When xfId is not exist during .xlsx import it must have values set to "0". It is not impacts spreadsheets created with MS Excel, as xfId attribute is always created during export to .xlsx Not setting "0" value is causing wrong .xlsx import by LibreOffice, for spreadsheets created by external applications (ex. SAP BI). Reviewed-on: https://gerrit.libreoffice.org/28069 Tested-by: Jenkins <[email protected]> Reviewed-by: Markus Mohrhard <[email protected]> (cherry picked from commit 9b9bcef5ef1858c63c8708bfae2ecea3d398eeb8) Change-Id: Ia4986236d5e902d0ff6f7a7a8da8f142b2c5061f diff --git a/sc/source/filter/oox/stylesbuffer.cxx b/sc/source/filter/oox/stylesbuffer.cxx index ba3e1a1..cf1c943 100644 --- a/sc/source/filter/oox/stylesbuffer.cxx +++ b/sc/source/filter/oox/stylesbuffer.cxx @@ -2089,12 +2089,27 @@ Xf::Xf( const WorkbookHelper& rHelper ) : void Xf::importXf( const AttributeList& rAttribs, bool bCellXf ) { maModel.mbCellXf = bCellXf; - maModel.mnStyleXfId = rAttribs.getInteger( XML_xfId, -1 ); + // tdf#70565 Set proper default value to "0" of xfId attribute + // When xfId is not exist during .xlsx import + // it must have values set to "0". + // Is is not impacts spreadsheets created with MS Excel, + // as xfId attribute is always created during export to .xlsx + // Not setting "0" value is causing wrong .xlsx import by LibreOffice, + // for spreadsheets created by external applications (ex. SAP BI). + if ( maModel.mbCellXf ) + { + maModel.mnStyleXfId = rAttribs.getInteger( XML_xfId, 0 ); + } + else + { + maModel.mnStyleXfId = rAttribs.getInteger( XML_xfId, -1 ); + } maModel.mnFontId = rAttribs.getInteger( XML_fontId, -1 ); maModel.mnNumFmtId = rAttribs.getInteger( XML_numFmtId, -1 ); maModel.mnBorderId = rAttribs.getInteger( XML_borderId, -1 ); maModel.mnFillId = rAttribs.getInteger( XML_fillId, -1 ); + /* Default value of the apply*** attributes is dependent on context: true in cellStyleXfs element, false in cellXfs element... */ maModel.mbAlignUsed = rAttribs.getBool( XML_applyAlignment, !maModel.mbCellXf ); commit 40e35b10f1179f448e394c28cd78cd77b2729944 Author: Justin Luth <[email protected]> Date: Wed Aug 31 08:55:36 2016 +0300 tdf#76349 writer: make 1column-as-page break a compatibility option Reviewed-on: https://gerrit.libreoffice.org/28501 Reviewed-by: Michael Stahl <[email protected]> master commit: 93d7fc90b57bb08052299c94fa0a28bb8f494a9c Reviewed-on: https://gerrit.libreoffice.org/28534 Tested-by: Jenkins <[email protected]> Reviewed-by: Justin Luth <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> (cherry picked from commit 9de59d3c63a27793ed8afe74f19d7e79bcfedead) Change-Id: I3135565ea6b3463d3854206cd221d73be3650468 diff --git a/sw/inc/IDocumentSettingAccess.hxx b/sw/inc/IDocumentSettingAccess.hxx index e02cbce..f16ae42 100644 --- a/sw/inc/IDocumentSettingAccess.hxx +++ b/sw/inc/IDocumentSettingAccess.hxx @@ -52,6 +52,7 @@ enum class DocumentSettingId ... etc. - the rest is truncated
_______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
