[Libreoffice-commits] core.git: 2 commits - i18npool/source officecfg/registry sc/qa sc/source
Tor Lillqvist (via logerrit)
logerrit at kemper.freedesktop.org
Wed May 6 21:48:06 UTC 2020
i18npool/source/collator/collator_unicode.cxx | 26 ++-
officecfg/registry/schema/org/openoffice/Office/Calc.xcs | 17 +
sc/qa/unit/data/ods/tdf79998.ods |binary
sc/qa/unit/filters-test.cxx | 20 ++
sc/source/filter/excel/xestream.cxx | 129 +++++++++++++++
sc/source/filter/inc/xestream.hxx | 5
6 files changed, 193 insertions(+), 4 deletions(-)
New commits:
commit df283b12a95d80a82aa2c2c9b8d32888a4d4039e
Author: Tor Lillqvist <tml at collabora.com>
AuthorDate: Tue May 5 19:18:56 2020 +0300
Commit: Tor Lillqvist <tml at collabora.com>
CommitDate: Wed May 6 23:47:39 2020 +0200
Throw exceptions with useful messages
Change-Id: Ic8e09d31db97c0cf2e1aaf006c96481d12deb2d8
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93506
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
Reviewed-by: Tor Lillqvist <tml at collabora.com>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93592
Tested-by: Jenkins
diff --git a/i18npool/source/collator/collator_unicode.cxx b/i18npool/source/collator/collator_unicode.cxx
index 609ef0f20351..673f5c35d3c7 100644
--- a/i18npool/source/collator/collator_unicode.cxx
+++ b/i18npool/source/collator/collator_unicode.cxx
@@ -19,6 +19,8 @@
#include <config_locales.h>
+#include <sal/log.hxx>
+
#include <lrl_include.hxx>
#include <rtl/ustrbuf.hxx>
@@ -141,7 +143,11 @@ Collator_Unicode::loadCollatorAlgorithm(const OUString& rAlgorithm, const lang::
OUString rule = LocaleDataImpl::get()->getCollatorRuleByAlgorithm(rLocale, rAlgorithm);
if (!rule.isEmpty()) {
collator.reset( new icu::RuleBasedCollator(reinterpret_cast<const UChar *>(rule.getStr()), status) );
- if (! U_SUCCESS(status)) throw RuntimeException();
+ if (! U_SUCCESS(status)) {
+ OUString message = "icu::RuleBasedCollator ctor failed: " + OUString::createFromAscii(u_errorName(status));
+ SAL_WARN("i18npool", message);
+ throw RuntimeException(message);
+ }
}
if (!collator && OUString(LOCAL_RULE_LANGS).indexOf(rLocale.Language) >= 0) {
const sal_uInt8* (*func)() = nullptr;
@@ -359,10 +365,18 @@ Collator_Unicode::loadCollatorAlgorithm(const OUString& rAlgorithm, const lang::
uca_base.reset( static_cast<icu::RuleBasedCollator*>(icu::Collator::createInstance(
icu::Locale::getRoot(), status)) );
#endif
- if (! U_SUCCESS(status)) throw RuntimeException();
+ if (! U_SUCCESS(status)) {
+ OUString message = "icu::Collator::createInstance() failed: " + OUString::createFromAscii(u_errorName(status));
+ SAL_WARN("i18npool", message);
+ throw RuntimeException(message);
+ }
collator.reset( new icu::RuleBasedCollator(
reinterpret_cast<const uint8_t*>(ruleImage), ruleImageSize, uca_base.get(), status) );
- if (! U_SUCCESS(status)) throw RuntimeException();
+ if (! U_SUCCESS(status)) {
+ OUString message = "icu::RuleBasedCollator ctor failed: " + OUString::createFromAscii(u_errorName(status));
+ SAL_WARN("i18npool", message);
+ throw RuntimeException(message);
+ }
}
}
if (!collator) {
@@ -383,7 +397,11 @@ Collator_Unicode::loadCollatorAlgorithm(const OUString& rAlgorithm, const lang::
// load ICU collator
collator.reset( static_cast<icu::RuleBasedCollator*>( icu::Collator::createInstance(icuLocale, status) ) );
- if (! U_SUCCESS(status)) throw RuntimeException();
+ if (! U_SUCCESS(status)) {
+ OUString message = "icu::Collator::createInstance() failed: " + OUString::createFromAscii(u_errorName(status));
+ SAL_WARN("i18npool", message);
+ throw RuntimeException(message);
+ }
}
}
commit 6b75874386b7b1ec44f7acc49cd3556a56108ed8
Author: Serge Krot <Serge.Krot at cib.de>
AuthorDate: Thu Apr 16 15:42:33 2020 +0200
Commit: Eike Rathke <erack at redhat.com>
CommitDate: Wed May 6 23:47:31 2020 +0200
tdf#79998 FILESAVE: XLSX export with long sheet names (length > 31 characters)
Change-Id: If18e3b751486144f3477b6e0c2615751f57e5565
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/92372
Tested-by: Jenkins
Reviewed-by: Eike Rathke <erack at redhat.com>
diff --git a/officecfg/registry/schema/org/openoffice/Office/Calc.xcs b/officecfg/registry/schema/org/openoffice/Office/Calc.xcs
index 8cd789e9a9ad..0762279bf3db 100644
--- a/officecfg/registry/schema/org/openoffice/Office/Calc.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/Calc.xcs
@@ -1830,6 +1830,23 @@
</prop>
</group>
</group>
+ <group oor:name="Export">
+ <info>
+ <desc>Contains settings for export filters.</desc>
+ </info>
+ <group oor:name="MS_Excel">
+ <info>
+ <desc>Contains settings for MS Excel export.</desc>
+ </info>
+ <prop oor:name="TruncateLongSheetNames" oor:type="xs:boolean" oor:nillable="false">
+ <info>
+ <desc>Indicates whether sheet names should be truncated to 31 characters.</desc>
+ <label>Truncate long sheet names</label>
+ </info>
+ <value>true</value>
+ </prop>
+ </group>
+ </group>
</group>
<group oor:name="Print">
<info>
diff --git a/sc/qa/unit/data/ods/tdf79998.ods b/sc/qa/unit/data/ods/tdf79998.ods
new file mode 100644
index 000000000000..201cca140585
Binary files /dev/null and b/sc/qa/unit/data/ods/tdf79998.ods differ
diff --git a/sc/qa/unit/filters-test.cxx b/sc/qa/unit/filters-test.cxx
index dc097180cbbd..43c3483bb281 100644
--- a/sc/qa/unit/filters-test.cxx
+++ b/sc/qa/unit/filters-test.cxx
@@ -70,6 +70,7 @@ public:
void testSharedFormulaXLSX();
void testSharedFormulaRefUpdateXLSX();
void testSheetNamesXLSX();
+ void testTdf79998();
void testLegacyCellAnchoredRotatedShape();
void testEnhancedProtectionXLS();
void testEnhancedProtectionXLSX();
@@ -96,6 +97,7 @@ public:
CPPUNIT_TEST(testSharedFormulaXLSX);
CPPUNIT_TEST(testSharedFormulaRefUpdateXLSX);
CPPUNIT_TEST(testSheetNamesXLSX);
+ CPPUNIT_TEST(testTdf79998);
CPPUNIT_TEST(testLegacyCellAnchoredRotatedShape);
CPPUNIT_TEST(testEnhancedProtectionXLS);
CPPUNIT_TEST(testEnhancedProtectionXLSX);
@@ -468,6 +470,24 @@ void ScFiltersTest::testSheetNamesXLSX()
xDocSh->DoClose();
}
+// FILESAVE: XLSX export with long sheet names (length > 31 characters)
+void ScFiltersTest::testTdf79998()
+{
+ // check: original document has tab name > 31 characters
+ ScDocShellRef xDocSh = loadDoc("tdf79998.", FORMAT_ODS);
+ ScDocument& rDoc1 = xDocSh->GetDocument();
+ const std::vector<OUString> aTabNames1 = rDoc1.GetAllTableNames();
+ CPPUNIT_ASSERT_EQUAL(OUString("Utilities (FX Kurse, Kreditkarten etc)"), aTabNames1[1]);
+
+ // check: saved XLSX document has truncated tab name
+ xDocSh = saveAndReload( &(*xDocSh), FORMAT_XLSX);
+ ScDocument& rDoc2 = xDocSh->GetDocument();
+ const std::vector<OUString> aTabNames2 = rDoc2.GetAllTableNames();
+ CPPUNIT_ASSERT_EQUAL(OUString("Utilities (FX Kurse, Kreditkart"), aTabNames2[1]);
+
+ xDocSh->DoClose();
+}
+
static void impl_testLegacyCellAnchoredRotatedShape( ScDocument& rDoc, const tools::Rectangle& aRect, const ScDrawObjData& aAnchor, long TOLERANCE = 30 /* 30 hmm */ )
{
ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
diff --git a/sc/source/filter/excel/xestream.cxx b/sc/source/filter/excel/xestream.cxx
index 51b11ebaf029..b3f96aa46b5c 100644
--- a/sc/source/filter/excel/xestream.cxx
+++ b/sc/source/filter/excel/xestream.cxx
@@ -32,6 +32,7 @@
#include <tools/urlobj.hxx>
#include <vcl/svapp.hxx>
#include <vcl/settings.hxx>
+#include <officecfg/Office/Calc.hxx>
#include <docuno.hxx>
#include <xestream.hxx>
@@ -49,6 +50,7 @@
#include <globstr.hrc>
#include <scresid.hxx>
#include <root.hxx>
+#include <sfx2/app.hxx>
#include <docsh.hxx>
#include <viewdata.hxx>
@@ -1002,6 +1004,13 @@ bool XclExpXmlStream::exportDocument()
ScDocument& rDoc = pShell->GetDocument();
ScRefreshTimerProtector aProt(rDoc.GetRefreshTimerControlAddress());
+ const bool bValidateTabNames = officecfg::Office::Calc::Filter::Export::MS_Excel::TruncateLongSheetNames::get();
+ std::vector<OUString> aOriginalTabNames;
+ if (bValidateTabNames)
+ {
+ validateTabNames(aOriginalTabNames);
+ }
+
uno::Reference<task::XStatusIndicator> xStatusIndicator = getStatusIndicator();
if (xStatusIndicator.is())
@@ -1103,6 +1112,11 @@ bool XclExpXmlStream::exportDocument()
commitStorage();
+ if (bValidateTabNames)
+ {
+ restoreTabNames(aOriginalTabNames);
+ }
+
if (xStatusIndicator.is())
xStatusIndicator->end();
mpRoot = nullptr;
@@ -1119,4 +1133,119 @@ OUString XclExpXmlStream::getImplementationName()
return "TODO";
}
+void XclExpXmlStream::validateTabNames(std::vector<OUString>& aOriginalTabNames)
+{
+ const int MAX_TAB_NAME_LENGTH = 31;
+
+ ScDocShell* pShell = getDocShell();
+ ScDocument& rDoc = pShell->GetDocument();
+
+ // get original names
+ aOriginalTabNames.resize(rDoc.GetTableCount());
+ for (SCTAB nTab=0; nTab < rDoc.GetTableCount(); nTab++)
+ {
+ rDoc.GetName(nTab, aOriginalTabNames[nTab]);
+ }
+
+ // new tab names
+ std::vector<OUString> aNewTabNames;
+ aNewTabNames.reserve(rDoc.GetTableCount());
+
+ // check and rename
+ for (SCTAB nTab=0; nTab < rDoc.GetTableCount(); nTab++)
+ {
+ const OUString& rOriginalName = aOriginalTabNames[nTab];
+ if (rOriginalName.getLength() > MAX_TAB_NAME_LENGTH)
+ {
+ OUString aNewName;
+
+ // let's try just truncate "<first 31 chars>"
+ if (aNewName.isEmpty())
+ {
+ aNewName = rOriginalName.copy(0, MAX_TAB_NAME_LENGTH);
+ if (aNewTabNames.end() != std::find(aNewTabNames.begin(), aNewTabNames.end(), aNewName) ||
+ aOriginalTabNames.end() != std::find(aOriginalTabNames.begin(), aOriginalTabNames.end(), aNewName))
+ {
+ // was found => let's use another tab name
+ aNewName.clear();
+ }
+ }
+
+ // let's try "<first N chars>-XXX" template
+ for (int digits=1; digits<10 && aNewName.isEmpty(); digits++)
+ {
+ const int rangeStart = pow(10, digits - 1);
+ const int rangeEnd = pow(10, digits);
+
+ for (int i=rangeStart; i<rangeEnd && aNewName.isEmpty(); i++)
+ {
+ aNewName = rOriginalName.copy(0, MAX_TAB_NAME_LENGTH - 1 - digits).concat("-").concat(OUString::number(i));
+ if (aNewTabNames.end() != std::find(aNewTabNames.begin(), aNewTabNames.end(), aNewName) ||
+ aOriginalTabNames.end() != std::find(aOriginalTabNames.begin(), aOriginalTabNames.end(), aNewName))
+ {
+ // was found => let's use another tab name
+ aNewName.clear();
+ }
+ }
+ }
+
+ if (!aNewName.isEmpty())
+ {
+ // new name was created => rename
+ renameTab(nTab, aNewName);
+ aNewTabNames.push_back(aNewName);
+ }
+ else
+ {
+ // default: do not rename
+ aNewTabNames.push_back(rOriginalName);
+ }
+ }
+ else
+ {
+ // default: do not rename
+ aNewTabNames.push_back(rOriginalName);
+ }
+ }
+}
+
+void XclExpXmlStream::restoreTabNames(const std::vector<OUString>& aOriginalTabNames)
+{
+ ScDocShell* pShell = getDocShell();
+ ScDocument& rDoc = pShell->GetDocument();
+
+ for (SCTAB nTab=0; nTab < rDoc.GetTableCount(); nTab++)
+ {
+ const OUString& rOriginalName = aOriginalTabNames[nTab];
+
+ OUString rModifiedName;
+ rDoc.GetName(nTab, rModifiedName);
+
+ if (rOriginalName != rModifiedName)
+ {
+ renameTab(nTab, rOriginalName);
+ }
+ }
+}
+
+void XclExpXmlStream::renameTab(SCTAB aTab, OUString aNewName)
+{
+ ScDocShell* pShell = getDocShell();
+ ScDocument& rDoc = pShell->GetDocument();
+
+ bool bAutoCalcShellDisabled = rDoc.IsAutoCalcShellDisabled();
+ bool bIdleEnabled = rDoc.IsIdleEnabled();
+
+ rDoc.SetAutoCalcShellDisabled( true );
+ rDoc.EnableIdle(false);
+
+ if (rDoc.RenameTab(aTab, aNewName))
+ {
+ SfxGetpApp()->Broadcast(SfxHint(SfxHintId::ScTablesChanged));
+ }
+
+ rDoc.SetAutoCalcShellDisabled( bAutoCalcShellDisabled );
+ rDoc.EnableIdle(bIdleEnabled);
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xestream.hxx b/sc/source/filter/inc/xestream.hxx
index 3aaebd7ce776..5701039418ab 100644
--- a/sc/source/filter/inc/xestream.hxx
+++ b/sc/source/filter/inc/xestream.hxx
@@ -29,6 +29,7 @@
#include <tools/stream.hxx>
#include <formula/errorcodes.hxx>
#include "ftools.hxx"
+#include <types.hxx>
#include <filter/msfilter/mscodec.hxx>
#include <vector>
@@ -338,6 +339,10 @@ private:
WriteAttribute(nAttr, OUString(sVal, strlen(sVal), RTL_TEXTENCODING_UTF8));
}
+ void validateTabNames(std::vector<OUString>& aOriginalTabNames);
+ void restoreTabNames(const std::vector<OUString>& aOriginalTabNames);
+ void renameTab(SCTAB aTab, OUString aNewName);
+
typedef std::map< OUString,
std::pair< OUString,
sax_fastparser::FSHelperPtr > > XclExpXmlPathToStateMap;
More information about the Libreoffice-commits
mailing list