[Libreoffice-commits] .: sw/source

Thorsten Behrens thorsten at kemper.freedesktop.org
Sun Sep 4 02:37:01 PDT 2011


 sw/source/filter/ww8/ww8par3.cxx |  172 ++++++++++++++++-----------------------
 1 file changed, 74 insertions(+), 98 deletions(-)

New commits:
commit 31845d927b1da39123691c769d277cc59d075387
Author: Andor Ertsey <andor.ertsey at muenchen.de>
Date:   Sun Sep 4 11:33:43 2011 +0200

    Fix combobox import bug
    
    This fixes i#100621. The method for reading formula elements from
    binary doc got completely overhauled, based on the MS format docs.
    All fields should now be read correctly, no more second-guessing/
    ignoring of bits. Although support for Word95 was dropped - no big
    loss though, since it never really worked before. ;)

diff --git a/sw/source/filter/ww8/ww8par3.cxx b/sw/source/filter/ww8/ww8par3.cxx
index 93c7a5a..4094d00 100644
--- a/sw/source/filter/ww8/ww8par3.cxx
+++ b/sw/source/filter/ww8/ww8par3.cxx
@@ -2138,118 +2138,86 @@ void WW8FormulaControl::FormulaRead(SwWw8ControlType nWhich,
     SvStream *pDataStream)
 {
     sal_uInt8 nField;
-    sal_uInt8 nHeaderByte;
+    // nHeaderBype == version
+    sal_uInt32 nHeaderByte;
+
+    // The following is a FFData structure as described in
+    // Microsoft's DOC specification (chapter 2.9.78)
 
-    int nType=0;
     *pDataStream >> nHeaderByte;
-    if (nHeaderByte == 0xFF) //Guesswork time, difference between 97 and 95 ?
-    {
-        pDataStream->SeekRel(3);
-        *pDataStream >> nHeaderByte;
-        nType=1;
-    }
-    fUnknown = nHeaderByte & 0x3;
-    fDropdownIndex = (nHeaderByte & 0x7C) >> 2;
-    *pDataStream >> nField;
-    fToolTip = nField & 0x01;
-    fNoMark = (nField & 0x02)>>1;
-    fUseSize = (nField & 0x04)>>2;
-    fNumbersOnly= (nField & 0x08)>>3;
-    fDateOnly = (nField & 0x10)>>4;
-    fUnused = (nField & 0xE0)>>5;
-    *pDataStream >> nSize;
 
-    *pDataStream >> hpsCheckBox;
-    if (nType == 0)
-        pDataStream->SeekRel(2); //Guess
+    // might be better to read the bits as a 16 bit word 
+    // ( like it is in the spec. )
+    sal_uInt8 bits1;
+    *pDataStream >> bits1;
+    sal_uInt8 bits2;
+    *pDataStream >> bits2;
 
-    rtl_TextEncoding eEnc = rRdr.eStructCharSet;
-    sTitle = !nType ? WW8ReadPString(*pDataStream, eEnc, true)
-                    : WW8Read_xstz(*pDataStream, 0, true);
+    sal_uInt8 iType = ( bits1 & 0x3 );
 
-    if (nWhich == WW8_CT_CHECKBOX)
-    {
-        *pDataStream >> nDefaultChecked;
-        nChecked = nDefaultChecked;
+    // we should verify that bits.iType & nWhich concur
+    OSL_ENSURE( iType == nWhich, "something wrong, expect control type read from stream doesn't match nWhich passed in");
+    if ( !( iType == nWhich ) )
+        return; // bail out
 
-        sal_uInt8 iRes = (nHeaderByte >> 2) & 0x1F;
-        switch (iRes)
-        {
-            case 1:  //checked
-                nChecked = true;
-                break;
-            case 25: //undefined, Undefined checkboxes are treated as unchecked
-                     //but it appear that both visually and the value are picked up from the default in that case
-                break;
-            case 0:  //unchecked
-                nChecked = false;
-                break;
-            default:
-                OSL_ENSURE(!this, "unknown option, please report to cmc");
-                break;
-        }
-        if ( nDefaultChecked )
-            sDefault = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("1") );
-        else
-            sDefault = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("0") );
-    }
-    else if (nWhich == WW8_CT_DROPDOWN)
-        *pDataStream >> nChecked;
-    else
-    {
-        sDefault = !nType ? WW8ReadPString(*pDataStream, eEnc, true)
-                          : WW8Read_xstz(*pDataStream, 0, true);
-    }
+    sal_uInt8 iRes = (bits1 & 0x7C) >> 2;
 
-    sFormatting = !nType ? WW8ReadPString(*pDataStream, eEnc, true)
-                         : WW8Read_xstz(*pDataStream, 0, true);
+    sal_uInt16 cch;
+    *pDataStream >> cch;
 
-    sHelp = !nType ? WW8ReadPString(*pDataStream, eEnc, true)
-                   : WW8Read_xstz(*pDataStream, 0, true);
+    sal_uInt16 hps;
+    *pDataStream >> hps;
 
-    if (nWhich == WW8_CT_DROPDOWN)      //is this the case ?
-        fToolTip = true;
+    // xstzName
+    sTitle = WW8Read_xstz(*pDataStream, 0, true);
 
-    if( fToolTip )
+    if (nWhich == WW8_CT_EDIT)
+    {   // Field is a textbox
+        // Default text
+        // xstzTextDef
+        sDefault = WW8Read_xstz(*pDataStream, 0, true);
+    }
+    else
     {
-        sToolTip = !nType ? WW8ReadPString(*pDataStream, eEnc, true)
-                          : WW8Read_xstz(*pDataStream, 0, true);
+        // CheckBox or ComboBox
+        sal_uInt16 wDef = 0;
+        *pDataStream >> wDef;
+        nChecked = wDef; // default
+        if (nWhich == WW8_CT_CHECKBOX)
+        {
+            if ( iRes != 25 )
+                nChecked = iRes;
+            sDefault = ( wDef == 0 ) ? rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("0") ) :  rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("1") );
+        }
     }
+    // xstzTextFormat
+    sFormatting = WW8Read_xstz(*pDataStream, 0, true);
+    // xstzHelpText
+    sHelp = WW8Read_xstz(*pDataStream, 0, true);
+    // xstzStatText
+    sToolTip = WW8Read_xstz(*pDataStream, 0, true);
+
+    String sEntryMacro = WW8Read_xstz(*pDataStream, 0, true);
+    String sExitMcr = WW8Read_xstz(*pDataStream, 0, true);
 
     if (nWhich == WW8_CT_DROPDOWN)
     {
         bool bAllOk = true;
-        pDataStream->SeekRel(4 * (nType ? 2 : 1));
-        sal_uInt16 nDummy;
-        *pDataStream >> nDummy;
-        sal_uInt32 nNoStrings;
-        if (!nType)
-        {
-            sal_uInt16 nWord95NoStrings;
-            *pDataStream >> nWord95NoStrings;
-            nNoStrings = nWord95NoStrings;
-            *pDataStream >> nWord95NoStrings;
-            if (nNoStrings != nWord95NoStrings)
-                bAllOk = false;
-            nNoStrings = nWord95NoStrings;
-            sal_uInt16 nDummy2;
-            *pDataStream >> nDummy2;
-            if (nDummy2 != 0)
-                bAllOk = false;
-            *pDataStream >> nDummy2;
-            if (nDummy2 != 0xA)
-                bAllOk = false;
-            if (!bAllOk)    //Not as expected, don't risk it at all.
-                nNoStrings = 0;
-            for (sal_uInt16 nI = 0; nI < nNoStrings; ++nI)
-                pDataStream->SeekRel(2);
-        }
-        else
-        {
-            if (nDummy != 0xFFFF)
-                bAllOk = false;
-            *pDataStream >> nNoStrings;
-        }
+        // SSTB (see Spec. 2.2.4)
+        sal_uInt16 fExtend;
+        *pDataStream >> fExtend;
+        sal_uInt16 nNoStrings;
+
+        // Isn't it that if fExtend isn't 0xFFFF then fExtend actually
+        // doesn't exist and we really have just read nNoStrings ( or cData )?
+        if (fExtend != 0xFFFF)
+            bAllOk = false;
+        *pDataStream >> nNoStrings;
+
+        // I guess this should be zero ( and we should ensure that )
+        sal_uInt16 cbExtra;
+        *pDataStream >> cbExtra;
+
         OSL_ENSURE(bAllOk,
             "Unknown formfield dropdown list structure. Report to cmc");
         if (!bAllOk)    //Not as expected, don't risk it at all.
@@ -2257,11 +2225,19 @@ void WW8FormulaControl::FormulaRead(SwWw8ControlType nWhich,
         maListEntries.reserve(nNoStrings);
         for (sal_uInt32 nI = 0; nI < nNoStrings; ++nI)
         {
-            String sEntry = !nType ? WW8ReadPString(*pDataStream, eEnc, false)
-                           : WW8Read_xstz(*pDataStream, 0, false);
+            String sEntry =  WW8Read_xstz(*pDataStream, 0, false);
             maListEntries.push_back(sEntry);
         }
     }
+    fDropdownIndex = iRes;
+
+    nField = bits2;
+    fToolTip = nField & 0x01;
+    fNoMark = (nField & 0x02)>>1;
+    fUseSize = (nField & 0x04)>>2;
+    fNumbersOnly= (nField & 0x08)>>3;
+    fDateOnly = (nField & 0x10)>>4;
+    fUnused = (nField & 0xE0)>>5;
 }
 
 WW8FormulaListBox::WW8FormulaListBox(SwWW8ImplReader &rR)


More information about the Libreoffice-commits mailing list