Re: ANNOUNCE: ooo-build-3.2.0.99.3 released (3.2.1-beta3) => feature freeze

Petr Mladek <[email protected]>
Newsgroups gmane.comp.gnome.ximian.openoffice
Message-ID <[email protected]>
On Friday 23 April 2010, Petr Mladek wrote:
> Hi,
>
> It was a big fight but we made it in the end ;-)
>
> I am happy to announce 3.2.1-beta3 release of ooo-build master branch. You
> might find it at
>
> 	http://download.go-oo.org/OOO320/ooo-build-3.2.0.99.3.tar.gz
> 	http://download.go-oo.org/OOO320/ooo-build-3.2.0.99.3.tar.gz.md5

IMPORTANT: There is a bug in the migration code. It causes that OOo does not 
start with fresh user configuration. It is visible "only" when it is not able 
to migrate an older (ooo-2.0) configuration, see
http://bugzilla.novell.com/show_bug.cgi?id=599590

I have just fixed in in ooo-build master. Please, put the attached diff to 
ooo-build-3.2.0.99.3/patches/hotfixes directory for your beta3 builds.

I am sorry for the troubles and inconvenience. I should have tested more 
scenarios after I ported the diff for ooo320-m14... :-(


-- 
Best Regards,

Petr Mladek
software developer
---------------------------------------------------------------------  
SUSE LINUX, s. r. o.                        e-mail: [email protected]
Lihovarská 1060/12                          tel: +420 284 028 952
190 00 Prague 9                             fax: +420 284 028 951
Czech Republic                              http://www.suse.cz/
desktop-config-migration.diff (text/x-diff, 16.5 KB)
--- desktop/source/app/app.cxx.old	2010-04-13 14:30:50.000000000 +0200
+++ desktop/source/app/app.cxx	2010-04-13 15:30:18.000000000 +0200
@@ -1457,6 +1457,9 @@ void Desktop::Main()
         }
 #endif
 
+        if (Migration::checkMigration())
+            Migration::doMigration();
+
 		// keep a language options instance...
 		pLanguageOptions.reset( new SvtLanguageOptions(sal_True));
 
--- desktop/source/migration/migration.cxx.old	2010-04-14 17:20:22.000000000 +0200
+++ desktop/source/migration/migration.cxx	2010-04-26 15:00:50.000000000 +0200
@@ -55,6 +55,10 @@
 #include <com/sun/star/util/XRefreshable.hpp>
 #include <com/sun/star/util/XChangesBatch.hpp>
 #include <com/sun/star/util/XStringSubstitution.hpp>
+#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/XAcceleratorConfiguration.hpp>
+#include <com/sun/star/awt/Key.hpp>
+#include <com/sun/star/awt/KeyEvent.hpp>
 
 using namespace rtl;
 using namespace osl;
@@ -69,6 +73,9 @@ using namespace com::sun::star::configur
 using com::sun::star::uno::Exception;
 using namespace com::sun::star;
 
+#define ascii( asc ) \
+    ::rtl::OUString::intern( RTL_CONSTASCII_USTRINGPARAM( asc ) )
+
 namespace desktop {
 
 
@@ -124,27 +131,155 @@ OUString Migration::getOldVersionName()
     return getImpl()->getOldVersionName();
 }
 
+MigrationImpl::VersionNumber::VersionNumber() :
+    mnMajor(0), mnMinor(0), mnMicro(0)
+{
+}
+
+MigrationImpl::VersionNumber::VersionNumber(sal_Int32 nMajor, sal_Int32 nMinor, sal_Int32 nMicro) :
+    mnMajor(nMajor), mnMinor(nMinor), mnMicro(nMicro)
+{
+}
+
 OUString MigrationImpl::getOldVersionName()
 {
     return m_aInfo.productname;
 }
 
-sal_Bool MigrationImpl::checkMigration()
+static bool splitVersionString(const OUString& rVer, MigrationImpl::VersionNumber& rVerNum)
 {
-    if (m_aInfo.userdata.getLength() > 0 && ! checkMigrationCompleted())
-        return sal_True;
-    else
+    rVerNum.mnMajor = 0;
+    rVerNum.mnMinor = 0;
+    rVerNum.mnMicro = 0;
+
+    sal_Int32 nLen = rVer.getLength();
+    const sal_Unicode* pStr = rVer.getStr();
+    OUStringBuffer buf;
+    sal_uInt8 nPos = 0; // 0 = major; 1 = minor; 2 = micro
+    for (sal_Int32 i = 0; i < nLen; ++i)
+    {
+        const sal_Unicode c = pStr[i];
+        if (c >= sal_Unicode('0') && c <= sal_Unicode('9'))
+            buf.append(c);
+        else if (c == sal_Unicode('.'))
+        {
+            if (buf.getLength() == 0)
+                // no numbers.
+                return false;
+
+            sal_Int32 nTmp = buf.makeStringAndClear().toInt32();
+            if (nTmp < 0 || nTmp > 255)
+                // only 0 - 255 allowed in a version number.
+                return false;
+
+            switch (nPos)
+            {
+                case 0: rVerNum.mnMajor = static_cast<sal_uInt8>(nTmp); break;
+                case 1: rVerNum.mnMinor = static_cast<sal_uInt8>(nTmp); break;
+                case 2: rVerNum.mnMicro = static_cast<sal_uInt8>(nTmp); break;
+            }
+
+            nPos += 1;
+            if (nPos > 2)
+                return true;
+        }
+        else
+            return false;
+    }
+
+    return true;
+}
+
+/** returns -1 if rVer1 < rVer2, 0 if rVer1 == rVer2, or 1 if rVer1 >
+    rVer2. */
+static short compareVersion(const MigrationImpl::VersionNumber& rVer1, 
+                            const MigrationImpl::VersionNumber& rVer2)
+{
+    // major version
+    if (rVer1.mnMajor < rVer2.mnMajor)
+        return -1;
+    if (rVer1.mnMajor > rVer2.mnMajor)
+        return 1;
+
+    // minor version
+    if (rVer1.mnMinor < rVer2.mnMinor)
+        return -1;
+    if (rVer1.mnMinor > rVer2.mnMinor)
+        return 1;
+
+    // micro version
+    if (rVer1.mnMicro < rVer2.mnMicro)
+        return -1;
+    if (rVer1.mnMicro > rVer2.mnMicro)
+        return 1;
+
+    return 0;
+}
+
+static sal_Bool isMigrationNeeded(const OUString& rConfVerStr, const OUString& rAppVerStr, 
+                                  MigrationImpl::VersionNumber& rConfVerNum, 
+                                  MigrationImpl::VersionNumber& rAppVerNum)
+{
+    if (!splitVersionString(rConfVerStr, rConfVerNum))
         return sal_False;
+
+    if (!splitVersionString(rAppVerStr, rAppVerNum))
+        return sal_False;
+
+#if OSL_DEBUG_LEVEL > 0
+    fprintf(stdout, "desktop::isMigrationNeeded: config ver = %d.%d.%d\n", 
+            rConfVerNum.mnMajor,rConfVerNum.mnMinor,rConfVerNum.mnMicro);
+
+    fprintf(stdout, "desktop::isMigrationNeeded: app ver = %d.%d.%d\n", 
+            rAppVerNum.mnMajor,rAppVerNum.mnMinor,rAppVerNum.mnMicro);
+#endif    
+
+    if (compareVersion(rConfVerNum, rAppVerNum) < 0)
+        return sal_True;
+
+    return sal_False;
 }
 
+sal_Bool MigrationImpl::checkMigration()
+{
+    if (m_bMigrationCompleted)
+        // migration is already complete.
+        return sal_False;
+
+    try
+    {
+        uno::Reference< XPropertySet > aPropSet(getConfigAccess("org.openoffice.Setup/Product"), uno::UNO_QUERY_THROW);
+        uno::Any any = aPropSet->getPropertyValue(ascii("ooSetupVersionAboutBox"));
+        if (!(any >>= m_aAppVerStr))
+            // Current version unknown.  Don't do migration (this should not happen).
+            return sal_False;
+
+        aPropSet.set(getConfigAccess("org.openoffice.Setup/Configuration"), uno::UNO_QUERY_THROW);    
+        any = aPropSet->getPropertyValue(ascii("ooLastVersionTouched"));
+        OUString aLastVersion;
+        if (!(any >>= aLastVersion))
+        {
+            // last touched version unknown.  Do the migration.
+            splitVersionString(m_aAppVerStr, m_aAppVerNum);
+            m_aConfigVerNum.mnMajor = 0;
+            m_aConfigVerNum.mnMinor = 0;
+            m_aConfigVerNum.mnMicro = 0;
+            return sal_True;
+        }
+
+        return isMigrationNeeded(aLastVersion, m_aAppVerStr, m_aConfigVerNum, m_aAppVerNum);
+    }
+    catch (const Exception&)
+    {
+    }
+    return sal_True;
+}
+ 
 MigrationImpl::MigrationImpl(const uno::Reference< XMultiServiceFactory >& xFactory)
-    : m_vrVersions(new strings_v)
+    : m_vrVersions(NULL)
     , m_xFactory(xFactory)
+    , m_bMigrationCompleted(false)
 {
-    readAvailableMigrations(m_vMigrationsAvailable);
-    sal_Int32 nIndex = findPreferedMigrationProcess(m_vMigrationsAvailable);
-    if ( nIndex >= 0 )
-        m_vrMigrations = readMigrationSteps(m_vMigrationsAvailable[nIndex].name);
 }
 
 MigrationImpl::~MigrationImpl()
@@ -154,33 +289,52 @@ MigrationImpl::~MigrationImpl()
 
 sal_Bool MigrationImpl::doMigration()
 {
-    // compile file and service list for migration
-    m_vrFileList    = compileFileList();
-    m_vrServiceList = compileServiceList();
+#if OSL_DEBUG_LEVEL > 0
+    fprintf( stderr, "Migrating user configuration to newer OOo version.\n" );
+#endif
+
+    sal_Bool result = sal_True;
+
+    if (compareVersion(m_aConfigVerNum, VersionNumber(3,0,0)) < 0)
+    {
+        try
+        {
+            if (initDirectoryMigration())
+            {
+                copyFiles();
     
-    sal_Bool result = sal_False;
-    try{
-        copyFiles();
-
-        // execute the migration items from Setup.xcu
-        // and refresh the cache
-        copyConfig();
-        refresh();
-
-        // execute custom migration services from Setup.xcu
-        // and refresh the cache
-        runServices();
-        refresh();
-
-        result = sal_True;
-    } catch (...)
-    {
-        OString aMsg("An unexpected exception was thrown during migration");
-        aMsg += "\nOldVersion: " + OUStringToOString(m_aInfo.productname, RTL_TEXTENCODING_ASCII_US);
-        aMsg += "\nDataPath  : " + OUStringToOString(m_aInfo.userdata, RTL_TEXTENCODING_ASCII_US);
-        OSL_ENSURE(sal_False, aMsg.getStr());
+                // execute the migration items from Setup.xcu
+                // and refresh the cache
+                copyConfig();
+                refresh();
+    
+                // execute custom migration services from Setup.xcu
+                // and refresh the cache
+                runServices();
+                refresh();
+            }
+        }
+        catch (...)
+        {
+            OString aMsg("An unexpected exception was thrown during migration");
+            aMsg += "\nOldVersion: " + OUStringToOString(m_aInfo.productname, RTL_TEXTENCODING_ASCII_US);
+            aMsg += "\nDataPath  : " + OUStringToOString(m_aInfo.userdata, RTL_TEXTENCODING_ASCII_US);
+            OSL_ENSURE(sal_False, aMsg.getStr());
+            result = sal_False;
+        }
     }
 
+    try
+    {
+        // migrate the configuration values.
+        transCalcFormulaConfig();
+        transKeyConfig();
+        cleanCSVImportCharSet();
+    }
+    catch (...)
+    {
+        result = sal_False;
+    }
     // prevent running the migration multiple times
     setMigrationCompleted();
     return result;
@@ -197,31 +351,126 @@ void MigrationImpl::refresh()
 
 }
 
-void MigrationImpl::setMigrationCompleted()
+void MigrationImpl::transKeyConfig()
 {
-    try {
-        uno::Reference< XPropertySet > aPropertySet(getConfigAccess("org.openoffice.Setup/Office", true), uno::UNO_QUERY_THROW);
-        aPropertySet->setPropertyValue(OUString::createFromAscii("MigrationCompleted"), uno::makeAny(sal_True));
-        uno::Reference< XChangesBatch >(aPropertySet, uno::UNO_QUERY_THROW)->commitChanges();
-    } catch (...) {
-        // fail silently
+    using namespace ::com::sun::star;
+    using namespace ::com::sun::star::ui;
+
+#if OSL_DEBUG_LEVEL > 0
+    fprintf(stdout, "MigrationImpl::transKeyConfig:   config ver = %ld.%ld.%ld\n",
+            long(m_aConfigVerNum.mnMajor), long(m_aConfigVerNum.mnMinor), long(m_aConfigVerNum.mnMicro));
+
+    fprintf(stdout, "MigrationImpl::transKeyConfig:   app ver = %ld.%ld.%ld\n",
+            long(m_aAppVerNum.mnMajor), long(m_aAppVerNum.mnMinor), long(m_aAppVerNum.mnMicro));
+#endif
+
+    if (compareVersion(m_aConfigVerNum, VersionNumber(2,4,0)) < 0)
+    {
+        // For config versions older than 2.4.0 only.
+
+        uno::Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgSupplier(
+            m_xFactory->createInstance(
+                ascii("com.sun.star.ui.ModuleUIConfigurationManagerSupplier")), uno::UNO_QUERY_THROW);
+    
+        // Grab the Calc configuration.
+        uno::Reference< XUIConfigurationManager > xConfigMgr = 
+            xModuleCfgSupplier->getUIConfigurationManager(
+                ascii("com.sun.star.sheet.SpreadsheetDocument"));
+    
+        if (xConfigMgr.is())
+        {
+            uno::Reference< XAcceleratorConfiguration > xScAccel(
+                xConfigMgr->getShortCutManager(), uno::UNO_QUERY_THROW);
+        
+            // Backsapce key
+            awt::KeyEvent aBackEv;
+            aBackEv.KeyCode = awt::Key::BACKSPACE;
+            aBackEv.Modifiers = 0;
+            xScAccel->setKeyEvent(aBackEv, ascii(".uno:Delete"));
+        
+            // Delete key
+            awt::KeyEvent aDeleteEv;
+            aDeleteEv.KeyCode = awt::Key::DELETE;
+            aDeleteEv.Modifiers = 0;
+            xScAccel->setKeyEvent(aDeleteEv, ascii(".uno:ClearContents"));
+        
+            xScAccel->store();
+        }
     }
 }
 
-sal_Bool MigrationImpl::checkMigrationCompleted()
+void MigrationImpl::cleanCSVImportCharSet()
 {
-    sal_Bool bMigrationCompleted = sal_False;
-    try {
-        uno::Reference< XPropertySet > aPropertySet(
-            getConfigAccess("org.openoffice.Setup/Office"), uno::UNO_QUERY_THROW);
-        aPropertySet->getPropertyValue(
-            OUString::createFromAscii("MigrationCompleted")) >>= bMigrationCompleted;
-    } catch (Exception&) {
-        // just return false...
+    // Overwrite the character set value for CSV import to -1 (unset) on every 
+    // upgrade, to prevent it from being incorrectly set to Unicode. (n#376473)
+
+    uno::Reference< XPropertySet > aPropSet;
+    aPropSet.set(getConfigAccess("org.openoffice.Office.Calc/Dialogs/CSVImport", true), uno::UNO_QUERY_THROW);
+    aPropSet->setPropertyValue(ascii("CharSet"), uno::makeAny(static_cast<sal_Int32>(-1)));
+    uno::Reference< XChangesBatch >(aPropSet, uno::UNO_QUERY_THROW)->commitChanges();
+}
+
+void MigrationImpl::transCalcFormulaConfig()
+{
+    // Prior to 3.1.0, formula settings were stored in
+    // Calc/Calculate/FormulaSyntax.  Migrate that to
+    // Calc/Formula/Syntax/Grammar.
+
+    if (compareVersion(m_aConfigVerNum, VersionNumber(3,1,0)) >= 0)
+        return;
+
+    try
+    {
+        uno::Reference<XPropertySet> xPropSet1(
+            getConfigAccess("org.openoffice.Office.Calc/Calculate/Other", true), uno::UNO_QUERY_THROW);
+
+        sal_Int32 nFormulaSyntax = 0;
+        xPropSet1->getPropertyValue(ascii("FormulaSyntax")) >>= nFormulaSyntax;
+
+        uno::Reference<XPropertySet> xPropSet2(
+            getConfigAccess("org.openoffice.Office.Calc/Formula/Syntax", true), uno::UNO_QUERY_THROW);
+        xPropSet2->setPropertyValue(ascii("Grammar"), uno::makeAny(nFormulaSyntax));
+        uno::Reference<XChangesBatch>(xPropSet2, uno::UNO_QUERY_THROW)->commitChanges();
+    }
+    catch (const Exception&)
+    {
     }
-    return bMigrationCompleted;
 }
 
+void MigrationImpl::setMigrationCompleted()
+{
+    try
+    {
+        uno::Reference< XPropertySet > aPropSet;
+        if (m_aAppVerStr.getLength() > 0)
+        {
+            aPropSet.set(getConfigAccess("org.openoffice.Setup/Configuration", true), uno::UNO_QUERY_THROW);
+            aPropSet->setPropertyValue(ascii("ooLastVersionTouched"), uno::makeAny(m_aAppVerStr));
+            uno::Reference< XChangesBatch >(aPropSet, uno::UNO_QUERY_THROW)->commitChanges();
+        }
+
+        m_bMigrationCompleted = true;
+    } 
+    catch (const Exception&)
+    {
+    }
+}
+
+bool MigrationImpl::initDirectoryMigration()
+{
+    m_vrVersions.reset(new strings_v);
+    readAvailableMigrations(m_vMigrationsAvailable);
+    sal_Int32 nIndex = findPreferedMigrationProcess(m_vMigrationsAvailable);
+    if ( nIndex >= 0 )
+    {
+        m_vrMigrations = readMigrationSteps(m_vMigrationsAvailable[nIndex].name);
+        // compile file and service list for migration
+        m_vrFileList = compileFileList();
+        m_vrServiceList = compileServiceList();
+        return true;
+    }
+    return false;
+}
 static void insertSorted(migrations_available& rAvailableMigrations, supported_migration& aSupportedMigration)
 {
     bool                           bInserted( false );
--- desktop/source/migration/migration_impl.hxx.old	2010-04-01 16:31:14.000000000 +0200
+++ desktop/source/migration/migration_impl.hxx	2010-04-13 15:30:18.000000000 +0200
@@ -83,6 +83,16 @@ typedef std::vector< supported_migration
 
 class MigrationImpl
 {
+public:
+    struct VersionNumber
+    {
+        sal_Int32 mnMajor;
+        sal_Int32 mnMinor;
+        sal_Int32 mnMicro;
+
+        explicit VersionNumber();
+        explicit VersionNumber(sal_Int32 nMajor, sal_Int32 nMinor, sal_Int32 nMicro);
+    };
 
 private:
     strings_vr m_vrVersions;
@@ -94,6 +104,12 @@ private:
     strings_vr           m_vrFileList;           // final list of files to be copied
     strings_vr           m_vrConfigList;         // final list of nodes to be copied
     strings_vr           m_vrServiceList;        // final list of services to be called
+    ::rtl::OUString m_aAppVerStr;
+    bool m_bMigrationCompleted;
+    VersionNumber m_aAppVerNum;
+    VersionNumber m_aConfigVerNum;
+
+    bool initDirectoryMigration();
 
     // functions to control the migration process
     bool          readAvailableMigrations(migrations_available&);
@@ -115,9 +131,11 @@ private:
     void copyConfig();
     void runServices();
     void refresh();
+    void transKeyConfig();
+    void cleanCSVImportCharSet();
+    void transCalcFormulaConfig();
 
     void setMigrationCompleted();
-    sal_Bool checkMigrationCompleted();
     
 public:
     MigrationImpl(const NS_UNO::Reference< NS_CSS::lang::XMultiServiceFactory >&);
--- officecfg/registry/schema/org/openoffice/Setup.xcs.old	2010-04-01 16:35:33.000000000 +0200
+++ officecfg/registry/schema/org/openoffice/Setup.xcs	2010-04-13 15:30:18.000000000 +0200
@@ -446,6 +446,14 @@
           <desc>Deprecated</desc>
 				</info>
 			</prop>
+            <prop oor:name="ooLastVersionTouched" oor:type="xs:string">
+                <info>
+                    <author>Kohei Yoshida</author>
+                    <desc>Specifies the version of OOo that touched the configration for the last time.  The format must 
+                    be in the form of major.minor.micro (e.g. 2.3.1).  Note that this value may not always be present if the 
+                    last touched version is very old.</desc>
+                </info>
+            </prop>
 		</group>
     <group oor:name="Migration">
       <info>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.