1 diff --git desktop/source/app/app.cxx desktop/source/app/app.cxx
2 index 38c3220..d3a3fc8 100644
3 --- desktop/source/app/app.cxx
4 +++ desktop/source/app/app.cxx
5 @@ -1429,6 +1429,9 @@ void Desktop::Main()
9 + if (Migration::checkMigration())
10 + Migration::doMigration();
12 // keep a language options instance...
13 pLanguageOptions.reset( new SvtLanguageOptions(sal_True));
15 diff --git desktop/source/migration/migration.cxx desktop/source/migration/migration.cxx
16 index bc6b168..21ac07d 100644
17 --- desktop/source/migration/migration.cxx
18 +++ desktop/source/migration/migration.cxx
20 #include <com/sun/star/util/XRefreshable.hpp>
21 #include <com/sun/star/util/XChangesBatch.hpp>
22 #include <com/sun/star/util/XStringSubstitution.hpp>
23 +#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
24 +#include <com/sun/star/ui/XAcceleratorConfiguration.hpp>
25 +#include <com/sun/star/awt/Key.hpp>
26 +#include <com/sun/star/awt/KeyEvent.hpp>
30 @@ -71,6 +75,9 @@ using namespace com::sun::star::configuration::backend;
31 using com::sun::star::uno::Exception;
32 using namespace com::sun::star;
34 +#define ascii( asc ) \
35 + ::rtl::OUString::intern( RTL_CONSTASCII_USTRINGPARAM( asc ) )
40 @@ -127,26 +134,154 @@ OUString Migration::getOldVersionName()
41 return getImpl()->getOldVersionName();
44 +MigrationImpl::VersionNumber::VersionNumber() :
45 + mnMajor(0), mnMinor(0), mnMicro(0)
49 +MigrationImpl::VersionNumber::VersionNumber(sal_Int32 nMajor, sal_Int32 nMinor, sal_Int32 nMicro) :
50 + mnMajor(nMajor), mnMinor(nMinor), mnMicro(nMicro)
54 OUString MigrationImpl::getOldVersionName()
56 return m_aInfo.productname;
59 -sal_Bool MigrationImpl::checkMigration()
60 +static bool splitVersionString(const OUString& rVer, MigrationImpl::VersionNumber& rVerNum)
62 - if (m_aInfo.userdata.getLength() > 0 && ! checkMigrationCompleted())
65 + rVerNum.mnMajor = 0;
66 + rVerNum.mnMinor = 0;
67 + rVerNum.mnMicro = 0;
69 + sal_Int32 nLen = rVer.getLength();
70 + const sal_Unicode* pStr = rVer.getStr();
72 + sal_uInt8 nPos = 0; // 0 = major; 1 = minor; 2 = micro
73 + for (sal_Int32 i = 0; i < nLen; ++i)
75 + const sal_Unicode c = pStr[i];
76 + if (c >= sal_Unicode('0') && c <= sal_Unicode('9'))
78 + else if (c == sal_Unicode('.'))
80 + if (buf.getLength() == 0)
84 + sal_Int32 nTmp = buf.makeStringAndClear().toInt32();
85 + if (nTmp < 0 || nTmp > 255)
86 + // only 0 - 255 allowed in a version number.
91 + case 0: rVerNum.mnMajor = static_cast<sal_uInt8>(nTmp); break;
92 + case 1: rVerNum.mnMinor = static_cast<sal_uInt8>(nTmp); break;
93 + case 2: rVerNum.mnMicro = static_cast<sal_uInt8>(nTmp); break;
107 +/** returns -1 if rVer1 < rVer2, 0 if rVer1 == rVer2, or 1 if rVer1 >
109 +static short compareVersion(const MigrationImpl::VersionNumber& rVer1,
110 + const MigrationImpl::VersionNumber& rVer2)
113 + if (rVer1.mnMajor < rVer2.mnMajor)
115 + if (rVer1.mnMajor > rVer2.mnMajor)
119 + if (rVer1.mnMinor < rVer2.mnMinor)
121 + if (rVer1.mnMinor > rVer2.mnMinor)
125 + if (rVer1.mnMicro < rVer2.mnMicro)
127 + if (rVer1.mnMicro > rVer2.mnMicro)
133 +static sal_Bool isMigrationNeeded(const OUString& rConfVerStr, const OUString& rAppVerStr,
134 + MigrationImpl::VersionNumber& rConfVerNum,
135 + MigrationImpl::VersionNumber& rAppVerNum)
137 + if (!splitVersionString(rConfVerStr, rConfVerNum))
140 + if (!splitVersionString(rAppVerStr, rAppVerNum))
143 +#if OSL_DEBUG_LEVEL > 0
144 + fprintf(stdout, "desktop::isMigrationNeeded: config ver = %d.%d.%d\n",
145 + rConfVerNum.mnMajor,rConfVerNum.mnMinor,rConfVerNum.mnMicro);
147 + fprintf(stdout, "desktop::isMigrationNeeded: app ver = %d.%d.%d\n",
148 + rAppVerNum.mnMajor,rAppVerNum.mnMinor,rAppVerNum.mnMicro);
151 + if (compareVersion(rConfVerNum, rAppVerNum) < 0)
157 +sal_Bool MigrationImpl::checkMigration()
159 + if (m_bMigrationCompleted)
160 + // migration is already complete.
165 + uno::Reference< XPropertySet > aPropSet(getConfigAccess("org.openoffice.Setup/Product"), uno::UNO_QUERY_THROW);
166 + uno::Any any = aPropSet->getPropertyValue(ascii("ooSetupVersionAboutBox"));
167 + if (!(any >>= m_aAppVerStr))
168 + // Current version unknown. Don't do migration (this should not happen).
171 + aPropSet.set(getConfigAccess("org.openoffice.Setup/Configuration"), uno::UNO_QUERY_THROW);
172 + any = aPropSet->getPropertyValue(ascii("ooLastVersionTouched"));
173 + OUString aLastVersion;
174 + if (!(any >>= aLastVersion))
176 + // last touched version unknown. Do the migration.
177 + splitVersionString(m_aAppVerStr, m_aAppVerNum);
178 + m_aConfigVerNum.mnMajor = 0;
179 + m_aConfigVerNum.mnMinor = 0;
180 + m_aConfigVerNum.mnMicro = 0;
184 + return isMigrationNeeded(aLastVersion, m_aAppVerStr, m_aConfigVerNum, m_aAppVerNum);
186 + catch (const Exception&)
192 MigrationImpl::MigrationImpl(const uno::Reference< XMultiServiceFactory >& xFactory)
193 - : m_vrVersions(new strings_v)
194 + : m_vrVersions(NULL)
195 , m_xFactory(xFactory)
196 - , m_vrMigrations(readMigrationSteps())
197 - , m_aInfo(findInstallation())
198 - , m_vrFileList(compileFileList())
199 - , m_vrServiceList(compileServiceList())
200 + , m_bMigrationCompleted(false)
204 @@ -157,29 +292,52 @@ MigrationImpl::~MigrationImpl()
206 sal_Bool MigrationImpl::doMigration()
208 - sal_Bool result = sal_False;
212 - // execute the migration items from Setup.xcu
213 - // and refresh the cache
216 +#if OSL_DEBUG_LEVEL > 0
217 + fprintf( stderr, "Migrating user configuration to newer OOo version.\n" );
220 - // execute custom migration services from Setup.xcu
221 - // and refresh the cache
224 + sal_Bool result = sal_True;
228 + if (compareVersion(m_aConfigVerNum, VersionNumber(3,0,0)) < 0)
230 - OString aMsg("An unexpected exception was thrown during migration");
231 - aMsg += "\nOldVersion: " + OUStringToOString(m_aInfo.productname, RTL_TEXTENCODING_ASCII_US);
232 - aMsg += "\nDataPath : " + OUStringToOString(m_aInfo.userdata, RTL_TEXTENCODING_ASCII_US);
233 - OSL_ENSURE(sal_False, aMsg.getStr());
236 + initDirectoryMigration();
240 + // execute the migration items from Setup.xcu
241 + // and refresh the cache
245 + // execute custom migration services from Setup.xcu
246 + // and refresh the cache
253 + OString aMsg("An unexpected exception was thrown during migration");
254 + aMsg += "\nOldVersion: " + OUStringToOString(m_aInfo.productname, RTL_TEXTENCODING_ASCII_US);
255 + aMsg += "\nDataPath : " + OUStringToOString(m_aInfo.userdata, RTL_TEXTENCODING_ASCII_US);
256 + OSL_ENSURE(sal_False, aMsg.getStr());
257 + result = sal_False;
263 + // migrate the configuration values.
264 + transCalcFormulaConfig();
266 + cleanCSVImportCharSet();
270 + result = sal_False;
272 // prevent running the migration multiple times
273 setMigrationCompleted();
275 @@ -196,31 +354,119 @@ void MigrationImpl::refresh()
279 -void MigrationImpl::setMigrationCompleted()
280 +void MigrationImpl::transKeyConfig()
283 - uno::Reference< XPropertySet > aPropertySet(getConfigAccess("org.openoffice.Setup/Office", true), uno::UNO_QUERY_THROW);
284 - aPropertySet->setPropertyValue(OUString::createFromAscii("MigrationCompleted"), uno::makeAny(sal_True));
285 - uno::Reference< XChangesBatch >(aPropertySet, uno::UNO_QUERY_THROW)->commitChanges();
289 + using namespace ::com::sun::star;
290 + using namespace ::com::sun::star::ui;
292 +#if OSL_DEBUG_LEVEL > 0
293 + fprintf(stdout, "MigrationImpl::transKeyConfig: config ver = %ld.%ld.%ld\n",
294 + long(m_aConfigVerNum.mnMajor), long(m_aConfigVerNum.mnMinor), long(m_aConfigVerNum.mnMicro));
296 + fprintf(stdout, "MigrationImpl::transKeyConfig: app ver = %ld.%ld.%ld\n",
297 + long(m_aAppVerNum.mnMajor), long(m_aAppVerNum.mnMinor), long(m_aAppVerNum.mnMicro));
300 + if (compareVersion(m_aConfigVerNum, VersionNumber(2,4,0)) < 0)
302 + // For config versions older than 2.4.0 only.
304 + uno::Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgSupplier(
305 + m_xFactory->createInstance(
306 + ascii("com.sun.star.ui.ModuleUIConfigurationManagerSupplier")), uno::UNO_QUERY_THROW);
308 + // Grab the Calc configuration.
309 + uno::Reference< XUIConfigurationManager > xConfigMgr =
310 + xModuleCfgSupplier->getUIConfigurationManager(
311 + ascii("com.sun.star.sheet.SpreadsheetDocument"));
313 + if (xConfigMgr.is())
315 + uno::Reference< XAcceleratorConfiguration > xScAccel(
316 + xConfigMgr->getShortCutManager(), uno::UNO_QUERY_THROW);
319 + awt::KeyEvent aBackEv;
320 + aBackEv.KeyCode = awt::Key::BACKSPACE;
321 + aBackEv.Modifiers = 0;
322 + xScAccel->setKeyEvent(aBackEv, ascii(".uno:Delete"));
325 + awt::KeyEvent aDeleteEv;
326 + aDeleteEv.KeyCode = awt::Key::DELETE;
327 + aDeleteEv.Modifiers = 0;
328 + xScAccel->setKeyEvent(aDeleteEv, ascii(".uno:ClearContents"));
335 -sal_Bool MigrationImpl::checkMigrationCompleted()
336 +void MigrationImpl::cleanCSVImportCharSet()
338 - sal_Bool bMigrationCompleted = sal_False;
340 - uno::Reference< XPropertySet > aPropertySet(
341 - getConfigAccess("org.openoffice.Setup/Office"), uno::UNO_QUERY_THROW);
342 - aPropertySet->getPropertyValue(
343 - OUString::createFromAscii("MigrationCompleted")) >>= bMigrationCompleted;
344 - } catch (Exception&) {
345 - // just return false...
346 + // Overwrite the character set value for CSV import to -1 (unset) on every
347 + // upgrade, to prevent it from being incorrectly set to Unicode. (n#376473)
349 + uno::Reference< XPropertySet > aPropSet;
350 + aPropSet.set(getConfigAccess("org.openoffice.Office.Calc/Dialogs/CSVImport", true), uno::UNO_QUERY_THROW);
351 + aPropSet->setPropertyValue(ascii("CharSet"), uno::makeAny(static_cast<sal_Int32>(-1)));
352 + uno::Reference< XChangesBatch >(aPropSet, uno::UNO_QUERY_THROW)->commitChanges();
355 +void MigrationImpl::transCalcFormulaConfig()
357 + // Prior to 3.1.0, formula settings were stored in
358 + // Calc/Calculate/FormulaSyntax. Migrate that to
359 + // Calc/Formula/Syntax/Grammar.
361 + if (compareVersion(m_aConfigVerNum, VersionNumber(3,1,0)) >= 0)
366 + uno::Reference<XPropertySet> xPropSet1(
367 + getConfigAccess("org.openoffice.Office.Calc/Calculate/Other", true), uno::UNO_QUERY_THROW);
369 + sal_Int32 nFormulaSyntax = 0;
370 + xPropSet1->getPropertyValue(ascii("FormulaSyntax")) >>= nFormulaSyntax;
372 + uno::Reference<XPropertySet> xPropSet2(
373 + getConfigAccess("org.openoffice.Office.Calc/Formula/Syntax", true), uno::UNO_QUERY_THROW);
374 + xPropSet2->setPropertyValue(ascii("Grammar"), uno::makeAny(nFormulaSyntax));
375 + uno::Reference<XChangesBatch>(xPropSet2, uno::UNO_QUERY_THROW)->commitChanges();
377 + catch (const Exception&)
380 - return bMigrationCompleted;
383 +void MigrationImpl::setMigrationCompleted()
387 + uno::Reference< XPropertySet > aPropSet;
388 + if (m_aAppVerStr.getLength() > 0)
390 + aPropSet.set(getConfigAccess("org.openoffice.Setup/Configuration", true), uno::UNO_QUERY_THROW);
391 + aPropSet->setPropertyValue(ascii("ooLastVersionTouched"), uno::makeAny(m_aAppVerStr));
392 + uno::Reference< XChangesBatch >(aPropSet, uno::UNO_QUERY_THROW)->commitChanges();
395 + m_bMigrationCompleted = true;
397 + catch (const Exception&)
402 +void MigrationImpl::initDirectoryMigration()
404 + m_vrVersions.reset(new strings_v);
405 + m_vrMigrations = readMigrationSteps();
406 + m_aInfo = findInstallation();
407 + m_vrFileList = compileFileList();
408 + m_vrServiceList = compileServiceList();
411 migrations_vr MigrationImpl::readMigrationSteps()
413 diff --git desktop/source/migration/migration_impl.hxx desktop/source/migration/migration_impl.hxx
414 index e07847a..34ba8bd 100644
415 --- desktop/source/migration/migration_impl.hxx
416 +++ desktop/source/migration/migration_impl.hxx
417 @@ -76,6 +76,16 @@ typedef std::auto_ptr< migrations_v > migrations_vr;
422 + struct VersionNumber
428 + explicit VersionNumber();
429 + explicit VersionNumber(sal_Int32 nMajor, sal_Int32 nMinor, sal_Int32 nMicro);
433 strings_vr m_vrVersions;
434 @@ -85,6 +95,12 @@ private:
435 strings_vr m_vrFileList; // final list of files to be copied
436 strings_vr m_vrConfigList; // final list of nodes to be copied
437 strings_vr m_vrServiceList; // final list of services to be called
438 + ::rtl::OUString m_aAppVerStr;
439 + bool m_bMigrationCompleted;
440 + VersionNumber m_aAppVerNum;
441 + VersionNumber m_aConfigVerNum;
443 + void initDirectoryMigration();
445 // initializer functions...
446 migrations_vr readMigrationSteps();
447 @@ -104,9 +120,11 @@ private:
451 + void transKeyConfig();
452 + void cleanCSVImportCharSet();
453 + void transCalcFormulaConfig();
455 void setMigrationCompleted();
456 - sal_Bool checkMigrationCompleted();
459 MigrationImpl(const NS_UNO::Reference< NS_CSS::lang::XMultiServiceFactory >&);
460 diff --git officecfg/registry/schema/org/openoffice/Setup.xcs officecfg/registry/schema/org/openoffice/Setup.xcs
461 index 7572879..339a7a4 100644
462 --- officecfg/registry/schema/org/openoffice/Setup.xcs
463 +++ officecfg/registry/schema/org/openoffice/Setup.xcs
465 <desc>Deprecated</desc>
468 + <prop oor:name="ooLastVersionTouched" oor:type="xs:string">
470 + <author>Kohei Yoshida</author>
471 + <desc>Specifies the version of OOo that touched the configration for the last time. The format must
472 + be in the form of major.minor.micro (e.g. 2.3.1). Note that this value may not always be present if the
473 + last touched version is very old.</desc>
477 <group oor:name="Migration">