/**************************************************************
 * 
 * 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
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */


#include <svl/itemiter.hxx>
#include <vcl/svapp.hxx>
#include <vcl/outdev.hxx>

#include <toolkit/helper/vclunohelper.hxx>
#include <com/sun/star/form/XFormsSupplier.hpp>
#include <com/sun/star/form/XForm.hpp>
#include <com/sun/star/form/XImageProducerSupplier.hpp>
#include <com/sun/star/form/XFormController.hpp>
#include <com/sun/star/frame/XStorable.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/drawing/XConnectableShape.hpp>
#include <com/sun/star/drawing/XConnectorShape.hpp>
#include <com/sun/star/drawing/XShape.hpp>
#include <com/sun/star/drawing/XControlShape.hpp>
#include <com/sun/star/drawing/XShapeAligner.hpp>
#include <com/sun/star/drawing/XShapeGroup.hpp>
#include <com/sun/star/drawing/XUniversalShapeDescriptor.hpp>
#include <com/sun/star/drawing/XShapeMirror.hpp>
#include <com/sun/star/drawing/XShapeArranger.hpp>
#include <com/sun/star/drawing/XDrawPage.hpp>
#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#include <com/sun/star/container/XIndexContainer.hpp>
#include <com/sun/star/text/VertOrientation.hpp>
#include <com/sun/star/text/TextContentAnchorType.hpp>
#include <comphelper/extract.hxx>
#include <comphelper/stlunosequence.hxx>
#include <com/sun/star/beans/XPropertyContainer.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>

#include <algorithm>
#include <functional>
#include <hintids.hxx>
#include <editeng/fontitem.hxx>
#include <editeng/lrspitem.hxx>
#include <editeng/fhgtitem.hxx>
#include <editeng/colritem.hxx>
#include <editeng/wghtitem.hxx>
#include <editeng/crsditem.hxx>
#include <editeng/udlnitem.hxx>
#include <editeng/postitem.hxx>
#include <filter/msfilter/msocximex.hxx>
#include <errhdl.hxx>
#include <unotextrange.hxx>
#include <doc.hxx>
#include <docary.hxx>
#include <docsh.hxx>
#include <numrule.hxx>
#include <paratr.hxx>
#include <charatr.hxx>
#include <charfmt.hxx>
#include <ndtxt.hxx>
#include <expfld.hxx>
#include <fmtfld.hxx>
#include <flddropdown.hxx>
#include "writerhelper.hxx"
#include "writerwordglue.hxx"
#include "ww8par.hxx"
#include "ww8par2.hxx"  // wg. Listen-Attributen in Styles

#include <IMark.hxx>
#include <unotools/fltrcfg.hxx>
#include <xmloff/odffields.hxx>

#include <stdio.h>
#include <algorithm>

using namespace com::sun::star;
using namespace sw::util;
using namespace sw::types;
using namespace sw::mark;

//-----------------------------------------
//            UNO-Controls
//-----------------------------------------

//cmc, OCX i.e. word 97 form controls
eF_ResT SwWW8ImplReader::Read_F_OCX( WW8FieldDesc*, String& )
{
    if( bObj && nPicLocFc )
        nObjLocFc = nPicLocFc;
    bEmbeddObj = true;
    return FLD_TEXT;
}

eF_ResT SwWW8ImplReader::Read_F_FormTextBox( WW8FieldDesc* pF, String& rStr )
{
    WW8FormulaEditBox aFormula(*this);

    if (0x01 == rStr.GetChar(writer_cast<xub_StrLen>(pF->nLCode-1))) {
        ImportFormulaControl(aFormula,pF->nSCode+pF->nLCode-1, WW8_CT_EDIT);
    }

    /* #80205#
    Here we have a small complication. This formula control contains
    the default text that is displayed if you edit the form field in
    the "default text" area. But MSOffice does not display that
    information, instead it display the result of the field,
    MSOffice just uses the default text of the control as its
    initial value for the displayed default text. So we will swap in
    the field result into the formula here in place of the default
    text.
    */

    const SvtFilterOptions* pOpt = SvtFilterOptions::Get();
    const sal_Bool bUseEnhFields=(pOpt && pOpt->IsUseEnhancedFields());

    if (!bUseEnhFields)
    {
        aFormula.sDefault = GetFieldResult(pF);

#if 0 // why not? (flr)
        //substituting Unicode spacing 0x2002 with double space for layout
        aFormula.sDefault.SearchAndReplaceAll(
            String(static_cast< sal_Unicode >(0x2002)),
            CREATE_CONST_ASC("  "));
#endif

        SwInputField aFld(
            static_cast<SwInputFieldType*>(rDoc.GetSysFldType( RES_INPUTFLD )),
            aFormula.sDefault,
            aFormula.sTitle,
            INP_TXT,
            0 );
        aFld.SetHelp(aFormula.sHelp);
        aFld.SetToolTip(aFormula.sToolTip);

        rDoc.InsertPoolItem( *pPaM, SwFmtFld(aFld), 0 );
        return FLD_OK;
    }
    else
    {
        WW8PLCFx_Book* pB = pPlcxMan->GetBook();
        String aBookmarkName;
        if (pB!=NULL) {
            WW8_CP currentCP=pF->nSCode;
            WW8_CP currentLen=pF->nLen;

            sal_uInt16 bkmFindIdx;
            String aBookmarkFind=pB->GetBookmark(currentCP-1, currentCP+currentLen-1, bkmFindIdx);

            if (aBookmarkFind.Len()>0) {
                pB->SetStatus(bkmFindIdx, BOOK_FIELD); // mark bookmark as consumed, such that tl'll not get inserted as a "normal" bookmark again
                if (aBookmarkFind.Len()>0) {
                    aBookmarkName=aBookmarkFind;
                }
            }
        }

        if (pB!=NULL && aBookmarkName.Len()==0) {
            aBookmarkName=pB->GetUniqueBookmarkName(aFormula.sTitle);
        }


        if (aBookmarkName.Len()>0) {
            maFieldStack.back().SetBookmarkName(aBookmarkName);
            maFieldStack.back().SetBookmarkType(::rtl::OUString::createFromAscii(ODF_FORMTEXT));
            maFieldStack.back().getParameters()[::rtl::OUString::createFromAscii("Description")] = uno::makeAny(::rtl::OUString(aFormula.sToolTip));
            maFieldStack.back().getParameters()[::rtl::OUString::createFromAscii("Name")] = uno::makeAny(::rtl::OUString(aFormula.sTitle));
        }
        return FLD_TEXT;
    }
}

eF_ResT SwWW8ImplReader::Read_F_FormCheckBox( WW8FieldDesc* pF, String& rStr )
{
    WW8FormulaCheckBox aFormula(*this);

    if (!pFormImpl)
        pFormImpl = new SwMSConvertControls(mpDocShell, pPaM);

    if (0x01 == rStr.GetChar(writer_cast<xub_StrLen>(pF->nLCode-1)))
        ImportFormulaControl(aFormula,pF->nSCode+pF->nLCode-1, WW8_CT_CHECKBOX);
    const SvtFilterOptions* pOpt = SvtFilterOptions::Get();
    sal_Bool bUseEnhFields=(pOpt && pOpt->IsUseEnhancedFields());

    if (!bUseEnhFields)
    {
        pFormImpl->InsertFormula(aFormula);
        return FLD_OK;
    }
    else
    {
        String aBookmarkName;
        WW8PLCFx_Book* pB = pPlcxMan->GetBook();
        if (pB!=NULL) {
            WW8_CP currentCP=pF->nSCode;
            WW8_CP currentLen=pF->nLen;

            sal_uInt16 bkmFindIdx;
            String aBookmarkFind=pB->GetBookmark(currentCP-1, currentCP+currentLen-1, bkmFindIdx);

            if (aBookmarkFind.Len()>0) {
                pB->SetStatus(bkmFindIdx, BOOK_FIELD); // mark as consumed by field
                if (aBookmarkFind.Len()>0) {
                    aBookmarkName=aBookmarkFind;
                }
            }
        }

        if (pB!=NULL && aBookmarkName.Len()==0) {
            aBookmarkName=pB->GetUniqueBookmarkName(aFormula.sTitle);
        }

        if (aBookmarkName.Len()>0)
        {
            IDocumentMarkAccess* pMarksAccess = rDoc.getIDocumentMarkAccess( );
            IFieldmark* pFieldmark = dynamic_cast<IFieldmark*>( pMarksAccess->makeNoTextFieldBookmark(
                *pPaM, aBookmarkName,
                rtl::OUString::createFromAscii( ODF_FORMCHECKBOX ) ) );
            ASSERT(pFieldmark!=NULL, "hmmm; why was the bookmark not created?");
            if (pFieldmark!=NULL) {
                IFieldmark::parameter_map_t* const pParameters = pFieldmark->GetParameters();
                ICheckboxFieldmark* pCheckboxFm = dynamic_cast<ICheckboxFieldmark*>(pFieldmark);
                (*pParameters)[::rtl::OUString::createFromAscii(ODF_FORMCHECKBOX_NAME)] = uno::makeAny(::rtl::OUString(aFormula.sTitle));
                (*pParameters)[::rtl::OUString::createFromAscii(ODF_FORMCHECKBOX_HELPTEXT)] = uno::makeAny(::rtl::OUString(aFormula.sToolTip));
                if(pCheckboxFm)
                    pCheckboxFm->SetChecked(aFormula.nChecked);
                // set field data here...
            }
        }
        return FLD_OK;
    }
}

eF_ResT SwWW8ImplReader::Read_F_FormListBox( WW8FieldDesc* pF, String& rStr)
{
    WW8FormulaListBox aFormula(*this);

    if (0x01 == rStr.GetChar(writer_cast<xub_StrLen>(pF->nLCode-1)))
        ImportFormulaControl(aFormula,pF->nSCode+pF->nLCode-1, WW8_CT_DROPDOWN);

    const SvtFilterOptions* pOpt = SvtFilterOptions::Get();
    sal_Bool bUseEnhFields=(pOpt && pOpt->IsUseEnhancedFields());

    if (!bUseEnhFields)
    {
        SwDropDownField aFld((SwDropDownFieldType*)rDoc.GetSysFldType(RES_DROPDOWN));

        aFld.SetName(aFormula.sTitle);
        aFld.SetHelp(aFormula.sHelp);
        aFld.SetToolTip(aFormula.sToolTip);

        if (!aFormula.maListEntries.empty())
        {
            aFld.SetItems(aFormula.maListEntries);
            int nIndex = aFormula.fDropdownIndex  < aFormula.maListEntries.size() ? aFormula.fDropdownIndex : 0;
            aFld.SetSelectedItem(aFormula.maListEntries[nIndex]);
        }

        rDoc.InsertPoolItem(*pPaM, SwFmtFld(aFld), 0);
        return FLD_OK;
    }
    else
    {
        // TODO: review me
        String aBookmarkName;
        WW8PLCFx_Book* pB = pPlcxMan->GetBook();
        if (pB!=NULL)
        {
            WW8_CP currentCP=pF->nSCode;
            WW8_CP currentLen=pF->nLen;

            sal_uInt16 bkmFindIdx;
            String aBookmarkFind=pB->GetBookmark(currentCP-1, currentCP+currentLen-1, bkmFindIdx);

            if (aBookmarkFind.Len()>0)
            {
                pB->SetStatus(bkmFindIdx, BOOK_FIELD); // mark as consumed by field
                if (aBookmarkFind.Len()>0)
                    aBookmarkName=aBookmarkFind;
            }
        }

        if (pB!=NULL && aBookmarkName.Len()==0)
            aBookmarkName=pB->GetUniqueBookmarkName(aFormula.sTitle);

        if (aBookmarkName.Len()>0)
        {
            IDocumentMarkAccess* pMarksAccess = rDoc.getIDocumentMarkAccess( );
            IFieldmark *pFieldmark = dynamic_cast<IFieldmark*>(
                    pMarksAccess->makeNoTextFieldBookmark( *pPaM, aBookmarkName,
                           ::rtl::OUString::createFromAscii( ODF_FORMDROPDOWN ) ) );
            ASSERT(pFieldmark!=NULL, "hmmm; why was the bookmark not created?");
            if ( pFieldmark != NULL )
            {
                uno::Sequence< ::rtl::OUString > vListEntries(aFormula.maListEntries.size());
                ::std::copy(aFormula.maListEntries.begin(), aFormula.maListEntries.end(), ::comphelper::stl_begin(vListEntries));
                (*pFieldmark->GetParameters())[::rtl::OUString::createFromAscii(ODF_FORMDROPDOWN_LISTENTRY)] = uno::makeAny(vListEntries);
                sal_Int32 nIndex = aFormula.fDropdownIndex  < aFormula.maListEntries.size() ? aFormula.fDropdownIndex : 0;
                (*pFieldmark->GetParameters())[::rtl::OUString::createFromAscii(ODF_FORMDROPDOWN_RESULT)] = uno::makeAny(nIndex);
                // set field data here...
            }
        }

        return FLD_OK;
    }
}

void SwWW8ImplReader::DeleteFormImpl()
{
    delete pFormImpl, pFormImpl = 0;
}

//----------------------------------------------------------------------------
//          WW8ListManager          oeffentliche Methoden stehen ganz am Ende
//------------------------- ============ --------------- ============ --------



// Hilfs-Deklarationen ///////////////////////////////////////////////////////
//
// Style Id's for each level
typedef sal_uInt16 WW8aIdSty[WW8ListManager::nMaxLevel];
// Zeichenattribute aus GrpprlChpx
typedef SfxItemSet* WW8aISet[WW8ListManager::nMaxLevel];
// Zeichen Style Pointer
typedef SwCharFmt* WW8aCFmt[WW8ListManager::nMaxLevel];

struct WW8LST   // nur DIE Eintraege, die WIR benoetigen!
{
    WW8aIdSty aIdSty;     // Style Id's for each level,
                            //   nIStDNil if no style linked
    sal_uInt32 nIdLst;     // Unique List ID
    sal_uInt32 nTplC;      // Unique template code - Was ist das bloss?
    sal_uInt8 bSimpleList:1; // Flag: Liste hat nur EINEN Level
    sal_uInt8 bRestartHdn:1; // WW6-Kompatibilitaets-Flag:
                                                        //   true if the list should start numbering over
};                                                      //   at the beginning of each section

struct WW8LFO   // nur DIE Eintraege, die WIR benoetigen!
{
    SwNumRule*      pNumRule;   // Parent NumRule
    sal_uInt32      nIdLst;     // Unique List ID
    sal_uInt8       nLfoLvl;    // count of levels whose format is overridden
    bool bSimpleList;
};

struct WW8LVL   // nur DIE Eintraege, die WIR benoetigen!
{
    long    nStartAt;       // start at value for this value
    long    nV6DxaSpace;// Ver6-Compatible: min Space between Num anf text::Paragraph
    long    nV6Indent;  // Ver6-Compatible: Breite des Prefix Textes; ggfs. zur
                        // Definition d. Erstzl.einzug nutzen!
    // Absatzattribute aus GrpprlPapx
    sal_uInt16  nDxaLeft;               // linker Einzug
    short   nDxaLeft1;          // Erstzeilen-Einzug

    sal_uInt8   nNFC;               // number format code
    // Offset der Feldkodes im Num-X-String
    sal_uInt8   aOfsNumsXCH[WW8ListManager::nMaxLevel];
    sal_uInt8   nLenGrpprlChpx; // length, in bytes, of the LVL's grpprlChpx
    sal_uInt8   nLenGrpprlPapx; // length, in bytes, of the LVL's grpprlPapx
    sal_uInt8   nAlign: 2;  // alignment (left, right, centered) of the number
    sal_uInt8 bLegal:    1;  // egal
    sal_uInt8 bNoRest:1; // egal
    sal_uInt8 bV6Prev:1; // Ver6-Compatible: number will include previous levels
    sal_uInt8 bV6PrSp:1; // Ver6-Compatible: egal
    sal_uInt8 bV6:       1;  // falls true , beachte die V6-Compatible Eintraege!
    sal_uInt8   bDummy: 1;  // (macht das Byte voll)

};

struct WW8LFOLVL
{
    long nStartAt;          // start-at value if bFormat==false and bStartAt == true
                                            // (if bFormat==true, the start-at is stored in the LVL)
    sal_uInt8 nLevel;               // the level to be overridden
    // dieses Byte ist _absichtlich_ nicht in das folgende Byte hineingepackt   !!
    // (siehe Kommentar unten bei struct WW8LFOInfo)

    sal_uInt8 bStartAt :1;       // true if the start-at value is overridden
    sal_uInt8 bFormat :1;        // true if the formatting is overriden

    WW8LFOLVL() :
        nStartAt(1), nLevel(0), bStartAt(1), bFormat(0) {}
};

// in den ListenInfos zu speichernde Daten ///////////////////////////////////
//
struct WW8LSTInfo   // sortiert nach nIdLst (in WW8 verwendete Listen-Id)
{
    std::vector<ww::bytes> maParaSprms;
    WW8aIdSty   aIdSty;          // Style Id's for each level
    WW8aISet    aItemSet;        // Zeichenattribute aus GrpprlChpx
    WW8aCFmt    aCharFmt;        // Zeichen Style Pointer

    SwNumRule*  pNumRule;        // Zeiger auf entsprechende Listenvorlage im Writer
    sal_uInt32      nIdLst;          // WW8Id dieser Liste
    sal_uInt8 bSimpleList:1;// Flag, ob diese NumRule nur einen Level verwendet
    sal_uInt8 bUsedInDoc :1;// Flag, ob diese NumRule im Doc verwendet wird,
                                                     //   oder beim Reader-Ende geloescht werden sollte

    WW8LSTInfo(SwNumRule* pNumRule_, WW8LST& aLST)
        : pNumRule(pNumRule_), nIdLst(aLST.nIdLst),
        bSimpleList(aLST.bSimpleList), bUsedInDoc(0)
    {
        memcpy( aIdSty, aLST.aIdSty, sizeof( aIdSty   ));
        memset(&aItemSet, 0,  sizeof( aItemSet ));
        memset(&aCharFmt, 0,  sizeof( aCharFmt ));
    }

};

// in den ListenFormatOverrideInfos zu speichernde Daten /////////////////////
//
struct WW8LFOInfo   // unsortiert, d.h. Reihenfolge genau wie im WW8 Stream
{
    std::vector<ww::bytes> maParaSprms;
    std::vector<WW8LFOLVL> maOverrides;
    SwNumRule* pNumRule;         // Zeiger auf entsprechende Listenvorlage im Writer
                                                     // entweder: Liste in LSTInfos oder eigene Liste
                                                     // (im Ctor erstmal die aus den LSTInfos merken)

    sal_uInt32  nIdLst;          // WW8-Id der betreffenden Liste
    sal_uInt8   nLfoLvl;             // count of levels whose format is overridden
    // Ja, ich natuerlich koennten wir nLfoLvl (mittels :4) noch in das folgende
    // Byte mit hineinpacken, doch waere das eine ziemliche Fehlerquelle,
    // an dem Tag, wo MS ihr Listenformat auf mehr als 15 Level aufbohren.

    sal_uInt8 bOverride  :1;// Flag, ob die NumRule nicht in maLSTInfos steht,
                                                     //   sondern fuer pLFOInfos NEU angelegt wurde
    sal_uInt8 bSimpleList:1;// Flag, ob diese NumRule nur einen Level verwendet
    sal_uInt8 bUsedInDoc :1;// Flag, ob diese NumRule im Doc verwendet wird,
                                                     //   oder beim Reader-Ende geloescht werden sollte
    sal_uInt8 bLSTbUIDSet    :1;// Flag, ob bUsedInDoc in maLSTInfos gesetzt wurde,
                                                     //   und nicht nochmals gesetzt zu werden braucht
    WW8LFOInfo(const WW8LFO& rLFO);
};

WW8LFOInfo::WW8LFOInfo(const WW8LFO& rLFO)
    : maParaSprms(WW8ListManager::nMaxLevel)
    , maOverrides(WW8ListManager::nMaxLevel)
    , pNumRule(rLFO.pNumRule)
    , nIdLst(rLFO.nIdLst)
    , nLfoLvl(rLFO.nLfoLvl)
    , bOverride(rLFO.nLfoLvl ? true : false)
    , bSimpleList(rLFO.bSimpleList)
    , bUsedInDoc(0)
    , bLSTbUIDSet(0)
{
}

SV_IMPL_PTRARR( WW8LFOInfos, WW8LFOInfo_Ptr );


// Hilfs-Methoden ////////////////////////////////////////////////////////////
//

// finden der Sprm-Parameter-Daten, falls Sprm im Grpprl enthalten
sal_uInt8* WW8ListManager::GrpprlHasSprm(sal_uInt16 nId, sal_uInt8& rSprms,
    sal_uInt8 nLen)
{
    sal_uInt8* pSprms = &rSprms;
    sal_uInt16 i=0;
    while (i < nLen)
    {
        sal_uInt16 nAktId = maSprmParser.GetSprmId(pSprms);
        if( nAktId == nId ) // Sprm found
            return pSprms + maSprmParser.DistanceToData(nId);

        // gib Zeiger auf Daten
        sal_uInt16 x = maSprmParser.GetSprmSize(nAktId, pSprms);
        i = i + x;
        pSprms += x;
    }
    return 0;                           // Sprm not found
}

class ListWithId : public std::unary_function<const WW8LSTInfo *, bool>
{
private:
    sal_uInt32 mnIdLst;
public:
    explicit ListWithId(sal_uInt32 nIdLst) : mnIdLst(nIdLst) {}
    bool operator() (const WW8LSTInfo *pEntry) const
        { return (pEntry->nIdLst == mnIdLst); }
};

// Zugriff ueber die List-Id des LST Eintrags
WW8LSTInfo* WW8ListManager::GetLSTByListId( sal_uInt32 nIdLst ) const
{
    std::vector<WW8LSTInfo *>::const_iterator aResult =
        std::find_if(maLSTInfos.begin(),maLSTInfos.end(),ListWithId(nIdLst));
    if (aResult == maLSTInfos.end())
        return 0;
    return *aResult;
}

void lcl_CopyGreaterEight(String &rDest, String &rSrc,
    xub_StrLen nStart, xub_StrLen nLen = STRING_LEN)
{
    if (nLen == STRING_LEN)
        nLen = rSrc.Len();
    for (xub_StrLen nI = nStart; nI < nLen; ++nI)
    {
        sal_Unicode nChar = rSrc.GetChar(nI);
        if (nChar > WW8ListManager::nMaxLevel)
            rDest.Append(nChar);
    }
}

bool WW8ListManager::ReadLVL(
    SwNumFmt& rNumFmt,
    SfxItemSet*& rpItemSet,
    sal_uInt16 nLevelStyle,
    bool bSetStartNo,
    std::deque< bool > &rNotReallyThere,
    sal_uInt16 nLevel,
    ww::bytes &rParaSprms )
{
    sal_uInt8       aBits1;
    sal_uInt16      nStartNo    = 0;    // Start-Nr. fuer den Writer
    SvxExtNumType   eType;              // Writer-Num-Typ
    SvxAdjust       eAdj;               // Ausrichtung (Links/rechts/zent.)
    sal_Unicode     cBullet(0x2190);    // default safe bullet

    sal_Unicode     cGrfBulletCP(USHRT_MAX); 

    String          sPrefix;
    String          sPostfix;
    WW8LVL          aLVL;
    //
    // 1. LVLF einlesen
    //
    memset(&aLVL, 0, sizeof( aLVL ));
    rSt >> aLVL.nStartAt;
    rSt >> aLVL.nNFC;
    rSt >> aBits1;
    if( 0 != rSt.GetError() ) return false;
    aLVL.nAlign = (aBits1 & 0x03);
    if( aBits1 & 0x10 ) aLVL.bV6Prev    = true;
    if( aBits1 & 0x20 ) aLVL.bV6PrSp    = true;
    if( aBits1 & 0x40 ) aLVL.bV6        = true;
    bool bLVLOkB = true;
    sal_uInt8 nLevelB = 0;
    for(nLevelB = 0; nLevelB < nMaxLevel; ++nLevelB)
    {
        rSt >> aLVL.aOfsNumsXCH[ nLevelB ];
        if( 0 != rSt.GetError() )
        {
            bLVLOkB = false;
            break;
        }
    }

    if( !bLVLOkB )
        return false;

    sal_uInt8 ixchFollow;
    rSt >> ixchFollow;
    if (ixchFollow == 0)
        rReader.maTracer.Log(sw::log::eTabInNumbering);
    rSt >> aLVL.nV6DxaSpace;
    rSt >> aLVL.nV6Indent;
    rSt >> aLVL.nLenGrpprlChpx;
    rSt >> aLVL.nLenGrpprlPapx;
    rSt.SeekRel( 2 );
    if( 0 != rSt.GetError()) return false;

    //
    // 2. ggfs. PAPx einlesen und nach Einzug-Werten suchen
    //
    // --> OD 2008-06-04 #i86652# - read tab setting
    short nTabPos = 0;
    // <--
    if( aLVL.nLenGrpprlPapx )
    {
        sal_uInt8 aGrpprlPapx[ 255 ];
        if(aLVL.nLenGrpprlPapx != rSt.Read(&aGrpprlPapx,aLVL.nLenGrpprlPapx))
            return false;
        // "sprmPDxaLeft"  pap.dxaLeft;dxa;word;
        sal_uInt8* pSprm;
        if (
            (0 != (pSprm = GrpprlHasSprm(0x840F,aGrpprlPapx[0],aLVL.nLenGrpprlPapx))) ||
            (0 != (pSprm = GrpprlHasSprm(0x845E,aGrpprlPapx[0],aLVL.nLenGrpprlPapx)))
            )
        {
            sal_uInt8 *pBegin = pSprm-2;
            for(int i=0;i<4;++i)
                rParaSprms.push_back(*pBegin++);
            short nDxaLeft = SVBT16ToShort( pSprm );
            aLVL.nDxaLeft = (0 < nDxaLeft) ? (sal_uInt16)nDxaLeft
                            : (sal_uInt16)(-nDxaLeft);
        }

        // "sprmPDxaLeft1" pap.dxaLeft1;dxa;word;
        if (
            (0 != (pSprm = GrpprlHasSprm(0x8411,aGrpprlPapx[0],aLVL.nLenGrpprlPapx)) ) ||
            (0 != (pSprm = GrpprlHasSprm(0x8460,aGrpprlPapx[0],aLVL.nLenGrpprlPapx)) )
            )
        {
            sal_uInt8 *pBegin = pSprm-2;
            for(int i=0;i<4;++i)
                rParaSprms.push_back(*pBegin++);
            aLVL.nDxaLeft1 = SVBT16ToShort(  pSprm );
        }

        // --> OD 2008-06-04 #i86652# - read tab setting
        if(0 != (pSprm = GrpprlHasSprm(0xC615,aGrpprlPapx[0],aLVL.nLenGrpprlPapx)) )
        {
            bool bDone = false;
            if (*(pSprm-1) == 5)
            {
                if (*pSprm++ == 0) //nDel
                {
                    if (*pSprm++ == 1) //nIns
                    {
                        nTabPos = SVBT16ToShort(pSprm);
                        pSprm+=2;
                        if (*pSprm == 6) //type
                        {
                            bDone = true;
                        }
                    }
                }
            }
            ASSERT(bDone, "tab setting in numbering is "
                "of unexpected configuration");
        }
        if ( rNumFmt.GetPositionAndSpaceMode() ==
                                  SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
        {
            // If there is a tab setting with a larger value, then use that.
            // Ideally we would allow tabs to be used in numbering fields and set
            // this on the containing paragraph which would make it actually work
            // most of the time.
            if ( nTabPos != 0 )
            {
                const sal_uInt16 nDesired = aLVL.nDxaLeft + aLVL.nDxaLeft1;

                bool bDoAdjust = false;
                if ( nDesired < aLVL.nDxaLeft )
                {
                    if ( nDesired < nTabPos && nTabPos < aLVL.nDxaLeft )
                    {
                        bDoAdjust = true;
                    }
                }
                else
                {
                    if ( aLVL.nDxaLeft < nTabPos && nTabPos < nDesired )
                    {
                        bDoAdjust = true;
                    }
                }

                if (bDoAdjust)
                {
                    aLVL.nDxaLeft = (0 < nTabPos)
                                    ? (sal_uInt16)nTabPos
                                    : (sal_uInt16)(-nTabPos);

                    aLVL.nDxaLeft1 = nDesired - aLVL.nDxaLeft;
                }
            }
        }
        // <--
    }
    //
    // 3. ggfs. CHPx einlesen und
    //
	sal_uInt16 nWitchPicIsBullet = USHRT_MAX;
	bool bIsPicBullet = false;
	
    if( aLVL.nLenGrpprlChpx )
    {
        sal_uInt8 aGrpprlChpx[ 255 ];
        memset(&aGrpprlChpx, 0, sizeof( aGrpprlChpx ));
        if(aLVL.nLenGrpprlChpx != rSt.Read(&aGrpprlChpx, aLVL.nLenGrpprlChpx))
            return false;
		
	//For i120928,parse the graphic info of bullets
	sal_uInt8 *pSprmWhichPis = GrpprlHasSprm(0x6887,aGrpprlChpx[0],aLVL.nLenGrpprlChpx);
	sal_uInt8 *pSprmIsPicBullet = GrpprlHasSprm(0x4888,aGrpprlChpx[0],aLVL.nLenGrpprlChpx);	
	if (pSprmWhichPis)
	{
		nWitchPicIsBullet = *pSprmWhichPis;
	}
	if (pSprmIsPicBullet)
	{
		bIsPicBullet = (*pSprmIsPicBullet) & 0x0001;
	}
	
        // neues ItemSet fuer die Zeichenattribute anlegen
        rpItemSet = new SfxItemSet( rDoc.GetAttrPool(), RES_CHRATR_BEGIN,
            RES_CHRATR_END - 1 );

        // Reader-ItemSet-Pointer darauf zeigen lassen
        rReader.SetAktItemSet( rpItemSet );
        // Reader-Style auf den Style dieses Levels setzen
        sal_uInt16 nOldColl = rReader.GetNAktColl();
        sal_uInt16 nNewColl = nLevelStyle;
        if (ww::stiNil == nNewColl)
            nNewColl = 0;
        rReader.SetNAktColl( nNewColl );

        // Nun den GrpprlChpx einfach durchnudeln: die Read_xy() Methoden
        // in WW8PAR6.CXX rufen ganz normal ihr NewAttr() oder GetFmtAttr()
        // und diese merken am besetzten Reader-ItemSet-Pointer, dass dieser
        // spezielle ItemSet relevant ist - und nicht ein Stack oder Style!
        sal_uInt16 nOldFlags1 = rReader.GetToggleAttrFlags();
        sal_uInt16 nOldFlags2 = rReader.GetToggleBiDiAttrFlags();
        short nLen      = aLVL.nLenGrpprlChpx;
        sal_uInt8* pSprms1  = &aGrpprlChpx[0];
        while (0 < nLen)
        {
            sal_uInt16 nL1 = rReader.ImportSprm( pSprms1 );
            nLen       = nLen - nL1;
            pSprms1   += nL1;
        }
        // Reader-ItemSet-Pointer und Reader-Style zuruecksetzen
        rReader.SetAktItemSet( 0 );
        rReader.SetNAktColl( nOldColl );
        rReader.SetToggleAttrFlags(nOldFlags1);
        rReader.SetToggleBiDiAttrFlags(nOldFlags2);
    }
    //
    // 4. den Nummerierungsstring einlesen: ergibt Prefix und Postfix
    //
    String sNumString(WW8Read_xstz(rSt, 0, false));

    //
    // 5. gelesene Werte in Writer Syntax umwandeln
    //
    if( 0 <= aLVL.nStartAt )
        nStartNo = (sal_uInt16)aLVL.nStartAt;

    switch( aLVL.nNFC )
    {
        case 0:
            eType = SVX_NUM_ARABIC;
            break;
        case 1:
            eType = SVX_NUM_ROMAN_UPPER;
            break;
        case 2:
            eType = SVX_NUM_ROMAN_LOWER;
            break;
        case 3:
            eType = SVX_NUM_CHARS_UPPER_LETTER_N;
            break;
        case 4:
            eType = SVX_NUM_CHARS_LOWER_LETTER_N;
            break;
        case 5:
            // eigentlich: ORDINAL
            eType = SVX_NUM_ARABIC;
            break;
        case 23:
        case 25:    //#114412#
            eType = SVX_NUM_CHAR_SPECIAL;
			//For i120928,type info
			if (bIsPicBullet)
			{
				eType = SVX_NUM_BITMAP;
			}

            break;
        case 255:
            eType = SVX_NUM_NUMBER_NONE;
            break;
         default:
            // take default
            eType = SVX_NUM_ARABIC;
            break;
    }

    //If a number level is not going to be used, then record this fact
    if (SVX_NUM_NUMBER_NONE == eType)
        rNotReallyThere[nLevel] = true;

    /*
     If a number level was not used (i.e. is in NotReallyThere), and that
     number level appears at one of the positions in the display string of the
     list, then it effectively is not there at all. So remove that level entry
     from a copy of the aOfsNumsXCH.
    */
    std::vector<sal_uInt8> aOfsNumsXCH;
    typedef std::vector<sal_uInt8>::iterator myIter;
    aOfsNumsXCH.reserve(nMaxLevel);

    for(nLevelB = 0; nLevelB < nMaxLevel; ++nLevelB)
        aOfsNumsXCH.push_back(aLVL.aOfsNumsXCH[nLevelB]);

    for(nLevelB = 0; nLevelB <= nLevel; ++nLevelB)
    {
        sal_uInt8 nPos = aOfsNumsXCH[nLevelB];
        if (nPos && sNumString.GetChar(nPos-1) < nMaxLevel)
        {
            if (rNotReallyThere[nLevelB])
                aOfsNumsXCH[nLevelB] = 0;
        }
    }
    myIter aIter = std::remove(aOfsNumsXCH.begin(), aOfsNumsXCH.end(), 0);
    myIter aEnd = aOfsNumsXCH.end();
    // --> OD 2006-01-16 #i60633# - suppress access on <aOfsNumsXCH.end()>
    if ( aIter != aEnd )
    {
        // Somehow the first removed vector element, at which <aIter>
        // points to, isn't reset to zero.
        // Investigation is needed to clarify why. It seems that only
        // special arrays are handled correctly by this code.
        ++aIter;
        while (aIter != aEnd)
        {
            (*aIter) = 0;
            ++aIter;
        }
    }
    // <--

    sal_uInt8 nUpperLevel = 0;  // akt. Anzeigetiefe fuer den Writer
    for(nLevelB = 0; nLevelB < nMaxLevel; ++nLevelB)
    {
        if (!nUpperLevel && !aOfsNumsXCH[nLevelB])
            nUpperLevel = nLevelB;
    }

    // falls kein NULL als Terminierungs-Char kam,
    // ist die Liste voller Indices, d.h. alle Plaetze sind besetzt,
    // also sind alle Level anzuzeigen
    if (!nUpperLevel)
        nUpperLevel = nMaxLevel;

    if (SVX_NUM_CHAR_SPECIAL == eType)
    {
        cBullet = sNumString.Len() ? sNumString.GetChar(0) : 0x2190;

        if (!cBullet)  // unsave control code?
            cBullet = 0x2190;
    }	else if (SVX_NUM_BITMAP == eType)	//For i120928,position index info of graphic
	{
		cGrfBulletCP = nWitchPicIsBullet;       // This is a bullet picture ID	
	} else
    {
        /*
        #83154#, #82192#, #i173#, #109158#
        Our aOfsNumsXCH seems generally to be an array that contains the
        offset into sNumString of locations where the numbers should be
        filled in, so if the first "fill in a number" slot is greater than
        1 there is a "prefix" before the number
        */
        //First number appears at
        sal_uInt8 nOneBasedFirstNoIndex = aOfsNumsXCH[0];
        xub_StrLen nFirstNoIndex =
            nOneBasedFirstNoIndex > 0 ? nOneBasedFirstNoIndex -1 : STRING_LEN;
        lcl_CopyGreaterEight(sPrefix, sNumString, 0, nFirstNoIndex);

        //Next number appears at
        if (nUpperLevel)
        {
            sal_uInt8 nOneBasedNextNoIndex = aOfsNumsXCH[nUpperLevel-1];
            xub_StrLen nNextNoIndex =
                nOneBasedNextNoIndex > 0 ? nOneBasedNextNoIndex -1 : STRING_LEN;
            if (nNextNoIndex != STRING_LEN)
                ++nNextNoIndex;
            if (sNumString.Len() > nNextNoIndex)
                lcl_CopyGreaterEight(sPostfix, sNumString, nNextNoIndex);
        }

        /*
         We use lcl_CopyGreaterEight because once if we have removed unused
         number indexes from the aOfsNumsXCH then placeholders remain in
         sNumString which must not be copied into the final numbering strings
        */
    }

    switch( aLVL.nAlign )
    {
        case 0:
            eAdj = SVX_ADJUST_LEFT;
            break;
        case 1:
            eAdj = SVX_ADJUST_CENTER;
            break;
        case 2:
            eAdj = SVX_ADJUST_RIGHT;
            break;
        case 3:
            // Writer here cannot do block justification
            eAdj = SVX_ADJUST_LEFT;
            break;
         default:
            // undefied value
            ASSERT( !this, "Value of aLVL.nAlign is not supported" );
            // take default
            eAdj = SVX_ADJUST_LEFT;
            break;
    }

    // 6. entsprechendes NumFmt konfigurieren
    if( bSetStartNo )
        rNumFmt.SetStart( nStartNo );
    rNumFmt.SetNumberingType( static_cast< sal_Int16 >(eType) );
    rNumFmt.SetNumAdjust( eAdj );

    if( SVX_NUM_CHAR_SPECIAL == eType )
    {
        // first character of the Prefix-Text is the Bullet
        rNumFmt.SetBulletChar(cBullet);
        // Don't forget: unten, nach dem Bauen eventueller Styles auch noch
        // SetBulletFont() rufen !!!
    }
	//For i120928,position index info
	else if (SVX_NUM_BITMAP == eType)	
	{
		rNumFmt.SetGrfBulletCP(cGrfBulletCP);
	}
    else
    {
        // reminder: Garnix ist default Prefix
        if( sPrefix.Len() )
            rNumFmt.SetPrefix( sPrefix );
        // reminder: Point is default Postfix
        rNumFmt.SetSuffix( sPostfix );
        rNumFmt.SetIncludeUpperLevels( nUpperLevel );
    }

    // --> OD 2008-06-04 #i89181#
    if ( rNumFmt.GetPositionAndSpaceMode() ==
                              SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
    {
        if (eAdj == SVX_ADJUST_RIGHT)
        {
            rNumFmt.SetAbsLSpace(aLVL.nDxaLeft);
            rNumFmt.SetFirstLineOffset(-aLVL.nDxaLeft);
            rNumFmt.SetCharTextDistance(-aLVL.nDxaLeft1);
        }
        else
        {
            rNumFmt.SetAbsLSpace( aLVL.nDxaLeft );
            rNumFmt.SetFirstLineOffset(aLVL.nDxaLeft1);
        }
    }
    else
    {
        rNumFmt.SetIndentAt( aLVL.nDxaLeft );
        rNumFmt.SetFirstLineIndent(aLVL.nDxaLeft1);
        rNumFmt.SetListtabPos( nTabPos );
        SvxNumberFormat::SvxNumLabelFollowedBy eNumLabelFollowedBy = SvxNumberFormat::LISTTAB;
        switch ( ixchFollow )
        {
            case 0:
            {
                eNumLabelFollowedBy = SvxNumberFormat::LISTTAB;
            }
            break;
            case 1:
            {
                eNumLabelFollowedBy = SvxNumberFormat::SPACE;
            }
            break;
            case 2:
            {
                eNumLabelFollowedBy = SvxNumberFormat::NOTHING;
            }
            break;
        }
        rNumFmt.SetLabelFollowedBy( eNumLabelFollowedBy );
    }

    return true;
}

void WW8ListManager::AdjustLVL( sal_uInt8 nLevel, SwNumRule& rNumRule,
    WW8aISet& rListItemSet, WW8aCFmt& rCharFmt, bool& bNewCharFmtCreated,
    String sPrefix )
{
    bNewCharFmtCreated = false;
    SfxItemSet* pThisLevelItemSet;
    SfxItemSet* pLowerLevelItemSet;
    sal_uInt8        nIdenticalItemSetLevel;
    const SfxPoolItem* pItem;

    SwNumFmt aNumFmt  = rNumRule.Get( nLevel );

    pThisLevelItemSet = rListItemSet[ nLevel ];

    if( pThisLevelItemSet && pThisLevelItemSet->Count())
    {
        nIdenticalItemSetLevel = nMaxLevel;
        SfxItemIter aIter( *pThisLevelItemSet );
        for (sal_uInt8 nLowerLevel = 0; nLowerLevel < nLevel; ++nLowerLevel)
        {
            pLowerLevelItemSet = rListItemSet[ nLowerLevel ];
            if(     pLowerLevelItemSet
                && (pLowerLevelItemSet->Count() == pThisLevelItemSet->Count()) )
            {
                nIdenticalItemSetLevel = nLowerLevel;
                sal_uInt16 nWhich = aIter.GetCurItem()->Which();
                while (true)
                {
                    if(  // ggfs. passenden pItem im pLowerLevelItemSet finden
                         (SFX_ITEM_SET != pLowerLevelItemSet->GetItemState(
                                            nWhich, false, &pItem ) )
                        || // virtuellen "!=" Operator anwenden
                         (*pItem != *aIter.GetCurItem() ) )
                    // falls kein Item mit gleicher nWhich gefunden oder Werte
                    // der Items ungleich, Ungleichheit merken und abbrechen!
                    {
                        nIdenticalItemSetLevel = nMaxLevel;
                        break;
                    }
                    if( aIter.IsAtEnd() )
                        break;
                    nWhich = aIter.NextItem()->Which();
                }

                if( nIdenticalItemSetLevel != nMaxLevel )
                    break;
            }
        }

        SwCharFmt* pFmt;
        if (nMaxLevel == nIdenticalItemSetLevel)
        {
            // Style definieren
            String aName( sPrefix.Len() ? sPrefix : rNumRule.GetName() );
            (aName += 'z') += String::CreateFromInt32( nLevel );

            // const Wegcasten
            pFmt = rDoc.MakeCharFmt(aName, (SwCharFmt*)rDoc.GetDfltCharFmt());
            bNewCharFmtCreated = true;
            // Attribute reinsetzen
            pFmt->SetFmtAttr( *pThisLevelItemSet );
        }
        else
        {
            // passenden Style hier anhaengen
            pFmt = rCharFmt[ nIdenticalItemSetLevel ];
        }

        // merken
        rCharFmt[ nLevel ] = pFmt;

        //
        // Style an das NumFormat haengen
        //
        aNumFmt.SetCharFmt( pFmt );
    }	
	//Modify for #119405 by chengjh, 2012-08-16
	//Ensure the default char fmt is initialized for any level of num ruler if no customized attr
	else
	{
		SwCharFmt* pFmt = aNumFmt.GetCharFmt();
		if ( !pFmt)
		{
			String aName( sPrefix.Len() ? sPrefix : rNumRule.GetName() );
	            	(aName += 'z') += String::CreateFromInt32( nLevel );
	            	
	            	pFmt = rDoc.MakeCharFmt(aName, (SwCharFmt*)rDoc.GetDfltCharFmt());
	            	bNewCharFmtCreated = true;
			rCharFmt[ nLevel ] = pFmt;
			aNumFmt.SetCharFmt( pFmt );
		}
	}
	//End
    //
    // ggfs. Bullet Font an das NumFormat haengen
    //
    if( SVX_NUM_CHAR_SPECIAL == aNumFmt.GetNumberingType() )
    {
        SwCharFmt* pFmt = aNumFmt.GetCharFmt();
        Font aFont;
        if( !pFmt )
        {
            // --> OD 2006-06-27 #b6440955#
//            aFont = SwNumRule::GetDefBulletFont();
            aFont = numfunc::GetDefBulletFont();
            // <--
        }
        else
        {
            const SvxFontItem& rFontItem = pFmt->GetFont();
            aFont.SetFamily(    rFontItem.GetFamily()     );
            aFont.SetName(      rFontItem.GetFamilyName() );
            aFont.SetStyleName( rFontItem.GetStyleName()  );
            aFont.SetPitch(     rFontItem.GetPitch()      );
            aFont.SetCharSet(   rFontItem.GetCharSet()    );
        }
        aNumFmt.SetBulletFont( &aFont );
    }
    //
    // und wieder rein in die NumRule
    //
    rNumRule.Set(nLevel, aNumFmt);
}

SwNumRule* WW8ListManager::CreateNextRule(bool bSimple)
{
    // wird erstmal zur Bildung des Style Namens genommen
    String sPrefix(CREATE_CONST_ASC("WW8Num"));
    sPrefix += String::CreateFromInt32(nUniqueList++);
    // --> OD 2008-06-04 #i86652#
//    sal_uInt16 nRul = rDoc.MakeNumRule(rDoc.GetUniqueNumRuleName(&sPrefix));
    sal_uInt16 nRul =
            rDoc.MakeNumRule( rDoc.GetUniqueNumRuleName(&sPrefix), 0, sal_False,
                              SvxNumberFormat::LABEL_ALIGNMENT );
    // <--
    SwNumRule* pMyNumRule = rDoc.GetNumRuleTbl()[nRul];
    pMyNumRule->SetAutoRule(false);
    pMyNumRule->SetContinusNum(bSimple);
    return pMyNumRule;
}

SwNumRule* WW8ListManager::GetNumRule(sal_uInt16 i)
{
	if ( i < maLSTInfos.size() )
		return maLSTInfos[i]->pNumRule;
	else
		return 0;
}

// oeffentliche Methoden /////////////////////////////////////////////////////
//
WW8ListManager::WW8ListManager(
    SvStream& rSt_,
    SwWW8ImplReader& rReader_ )
    : maSprmParser( rReader_.GetFib().GetFIBVersion() )
    , rReader(rReader_)
    , rDoc(rReader.GetDoc())
    , rFib(rReader.GetFib())
    , rSt(rSt_)
    , maLSTInfos()
    , pLFOInfos( NULL )
    , nUniqueList( 1 )
    , maStyleInList()
{
    // LST und LFO gibts erst ab WW8
    if(    ( 8 > rFib.nVersion )
            || ( rFib.fcPlcfLst == rFib.fcPlfLfo )
            || ( !rFib.lcbPlcfLst )
            || ( !rFib.lcbPlfLfo ) ) return; // offensichtlich keine Listen da

    // Arrays anlegen
    pLFOInfos = new WW8LFOInfos;
    bool bLVLOk = true;
    sal_uInt8  aBits1;

    nLastLFOPosition = USHRT_MAX;
    long nOriginalPos = rSt.Tell();
    //
    // 1. PLCF LST auslesen und die Listen Vorlagen im Writer anlegen
    //
    rSt.Seek( rFib.fcPlcfLst );
    sal_uInt16 nListCount;
    rSt >> nListCount;
    bool bOk = 0 < nListCount;
    if( bOk )
    {
        WW8LST aLST;
        //
        // 1.1 alle LST einlesen
        //
        for (sal_uInt16 nList=0; nList < nListCount; ++nList)
        {
            bOk = false;
            memset(&aLST, 0, sizeof( aLST ));
            sal_uInt16 nLevel;
            //
            // 1.1.1 Daten einlesen
            //
            rSt >> aLST.nIdLst;
            rSt >> aLST.nTplC;
            for (nLevel = 0; nLevel < nMaxLevel; ++nLevel)
                rSt >> aLST.aIdSty[ nLevel ];


            rSt >> aBits1;

            rSt.SeekRel( 1 );

            if (rSt.GetError())
                break;

            if( aBits1 & 0x01 )
                aLST.bSimpleList = true;
            if( aBits1 & 0x02 )
                aLST.bRestartHdn = true;

            // 1.1.2 new NumRule inserted in Doc and  WW8LSTInfo marked

            /*
            #i1869#
            In word 2000 microsoft got rid of creating new "simple lists" with
            only 1 level, all new lists are created with 9 levels. To hack it
            so that the list types formerly known as simple lists still have
            their own tab page to themselves one of the reserved bits is used
            to show that a given list is to be in the simple list tabpage.
            This has now nothing to do with the actual number of list level a
            list has, only how many will be shown in the user interface.

            i.e. create a simple list in 2000 and open it in 97 and 97 will
            claim (correctly) that it is an outline list. We can set our
            continuous flag in these lists to store this information.
            */
            SwNumRule* pMyNumRule = CreateNextRule(
                aLST.bSimpleList || (aBits1 & 0x10));

            WW8LSTInfo* pLSTInfo = new WW8LSTInfo(pMyNumRule, aLST);
            maLSTInfos.push_back(pLSTInfo);
            bOk = true;
        }
    }

    if( bOk )
    {
        //
        // 1.2 alle LVL aller aLST einlesen
        //
        sal_uInt8 nLevel;
        sal_uInt16 nLSTInfos = static_cast< sal_uInt16 >(maLSTInfos.size());
        for (sal_uInt16 nList = 0; nList < nLSTInfos; ++nList)
        {
            bOk = false;
            WW8LSTInfo* pListInfo = maLSTInfos[nList];
            if( !pListInfo || !pListInfo->pNumRule ) break;
            SwNumRule& rMyNumRule = *pListInfo->pNumRule;
            //
            // 1.2.1 betreffende(n) LVL(s) fuer diese aLST einlesen
            //
            sal_uInt16 nLvlCount = static_cast< sal_uInt16 >(pListInfo->bSimpleList ? nMinLevel : nMaxLevel);
            std::deque<bool> aNotReallyThere;
            aNotReallyThere.resize(nMaxLevel);
            pListInfo->maParaSprms.resize(nMaxLevel);
            for (nLevel = 0; nLevel < nLvlCount; ++nLevel)
            {
                SwNumFmt aNumFmt( rMyNumRule.Get( nLevel ) );
                // LVLF einlesen
                bLVLOk = ReadLVL( aNumFmt, pListInfo->aItemSet[nLevel],
                    pListInfo->aIdSty[nLevel], true, aNotReallyThere, nLevel,
                    pListInfo->maParaSprms[nLevel]);
                if( !bLVLOk )
                    break;
                // und in die rMyNumRule aufnehmen
                rMyNumRule.Set( nLevel, aNumFmt );
            }
            if( !bLVLOk )
                break;
            //
            // 1.2.2 die ItemPools mit den CHPx Einstellungen der verschiedenen
            //       Level miteinander vergleichen und ggfs. Style(s) erzeugen
            //
            bool bDummy;
            for (nLevel = 0; nLevel < nLvlCount; ++nLevel)
            {
                AdjustLVL( nLevel, rMyNumRule, pListInfo->aItemSet,
                                               pListInfo->aCharFmt, bDummy );
            }
            //
            // 1.2.3 ItemPools leeren und loeschen
            //
            for (nLevel = 0; nLevel < nLvlCount; ++nLevel)
                delete pListInfo->aItemSet[ nLevel ];
            bOk = true;
        }
    }
    if( !bOk )
    {
        // Fehler aufgetreten - LSTInfos abraeumen !!!

        ;
    }

    //
    // 2. PLF LFO auslesen und speichern
    //
    long nLfoCount(0);
    if (bOk)
    {
        rSt.Seek(rFib.fcPlfLfo);
        rSt >> nLfoCount;
        if (0 >= nLfoCount)
            bOk = false;
    }

    if(bOk)
    {
        WW8LFO aLFO;
        //
        // 2.1 alle LFO einlesen
        //
        for (sal_uInt16 nLfo = 0; nLfo < nLfoCount; ++nLfo)
        {
            bOk = false;
            memset(&aLFO, 0, sizeof( aLFO ));
            rSt >> aLFO.nIdLst;
            rSt.SeekRel( 8 );
            rSt >> aLFO.nLfoLvl;
            rSt.SeekRel( 3 );
            // soviele Overrides existieren
            if ((nMaxLevel < aLFO.nLfoLvl) || rSt.GetError())
                break;

            // die Parent NumRule der entsprechenden Liste ermitteln
            WW8LSTInfo* pParentListInfo = GetLSTByListId(aLFO.nIdLst);
            if (pParentListInfo)
            {
                // hier, im ersten Schritt, erst mal diese NumRule festhalten
                aLFO.pNumRule = pParentListInfo->pNumRule;

                // hat die Liste mehrere Level ?
                aLFO.bSimpleList = pParentListInfo->bSimpleList;
            }
            // und rein ins Merk-Array mit dem Teil
            WW8LFOInfo* pLFOInfo = new WW8LFOInfo(aLFO);
            if ( pParentListInfo != NULL )
            {
                //Copy the basic paragraph properties for each level from the
                //original list into the list format override levels.
                int nMaxSize = pParentListInfo->maParaSprms.size();
                pLFOInfo->maParaSprms.resize(nMaxSize);
                for (int i = 0; i < nMaxSize; ++i)
                {
                    pLFOInfo->maParaSprms[i] = pParentListInfo->maParaSprms[i];
                }

                const sal_uInt16 nLFOInfoArrayPos = pLFOInfos->Count();
                for ( sal_uInt8 j = 0 ; j < nMaxLevel; ++j )
                {
                    maStyleInList[pParentListInfo->aIdSty[j]] = nLFOInfoArrayPos;
                }
            }
            pLFOInfos->Insert( pLFOInfo, pLFOInfos->Count() );
            bOk = true;
        }
    }
    if( bOk )
    {
        //
        // 2.2 fuer alle LFO die zugehoerigen LFOLVL einlesen
        //
        sal_uInt16 nLFOInfos = pLFOInfos ? pLFOInfos->Count() : 0;
        for (sal_uInt16 nLfo = 0; nLfo < nLFOInfos; ++nLfo)
        {
            bOk = false;
            WW8LFOInfo* pLFOInfo = pLFOInfos->GetObject( nLfo );
            if (!pLFOInfo)
                break;
            // stehen hierfuer ueberhaupt LFOLVL an ?
            if( pLFOInfo->bOverride )
            {
                WW8LSTInfo* pParentListInfo = GetLSTByListId(pLFOInfo->nIdLst);
                if (!pParentListInfo) //e.g. #112324#
                    break;
                //
                // 2.2.1 eine neue NumRule fuer diese Liste anlegen
                //
                SwNumRule* pParentNumRule = pLFOInfo->pNumRule;
                ASSERT(pParentNumRule, "ww: Impossible lists, please report");
                if( !pParentNumRule )
                    break;
                // Nauemsprefix aufbauen: fuer NumRule-Name (eventuell)
                // und (falls vorhanden) fuer Style-Name (dann auf jeden Fall)
                String sPrefix(CREATE_CONST_ASC( "WW8NumSt" ));
                sPrefix += String::CreateFromInt32( nLfo + 1 );
                // jetzt dem pNumRule seinen RICHTIGEN Wert zuweisen !!!
                // (bis dahin war hier die Parent NumRule vermerkt )
                //
                // Dazu erst mal nachsehen, ob ein Style diesen LFO
                // referenziert:
                if( USHRT_MAX > rReader.StyleUsingLFO( nLfo ) )
                {
                    sal_uInt16 nRul = rDoc.MakeNumRule(
                        rDoc.GetUniqueNumRuleName( &sPrefix ), pParentNumRule);
                    pLFOInfo->pNumRule = rDoc.GetNumRuleTbl()[ nRul ];
                    pLFOInfo->pNumRule->SetAutoRule(false);
                }
                else
                {
                    sal_uInt16 nRul = rDoc.MakeNumRule(
                        rDoc.GetUniqueNumRuleName(), pParentNumRule);
                    pLFOInfo->pNumRule = rDoc.GetNumRuleTbl()[ nRul ];
                    pLFOInfo->pNumRule->SetAutoRule(true);  // = default
                }
                //
                // 2.2.2 alle LFOLVL (und ggfs. LVL) fuer die neue NumRule
                // einlesen
                //
                WW8aISet aItemSet;       // Zeichenattribute aus GrpprlChpx
                WW8aCFmt aCharFmt;       // Zeichen Style Pointer
                memset(&aItemSet, 0,  sizeof( aItemSet ));
                memset(&aCharFmt, 0,  sizeof( aCharFmt ));

                //2.2.2.0 skip inter-group of override header ?
                //See #i25438# for why I moved this here, compare
                //that original bugdoc's binary to what it looks like
                //when resaved with word, i.e. there is always a
                //4 byte header, there might be more than one if
                //that header was 0xFFFFFFFF, e.g. #114412# ?
                sal_uInt32 nTest;
                rSt >> nTest;
                do
                    rSt >> nTest;
                while (nTest == 0xFFFFFFFF);
                rSt.SeekRel(-4);

                std::deque<bool> aNotReallyThere(WW8ListManager::nMaxLevel);
                sal_uInt8 nLevel = 0;
                for (nLevel = 0; nLevel < pLFOInfo->nLfoLvl; ++nLevel)
                {
                    WW8LFOLVL aLFOLVL;
                    bLVLOk = false;

                    //
                    // 2.2.2.1 den LFOLVL einlesen
                    //
                    rSt >> aLFOLVL.nStartAt;
                    rSt >> aBits1;
                    rSt.SeekRel( 3 );
                    if (rSt.GetError())
                        break;

                    // beachte: Die Witzbolde bei MS quetschen die
                    // Override-Level-Nummer in vier Bits hinein, damit sie
                    // wieder einen Grund haben, ihr Dateiformat zu aendern,
                    // falls ihnen einfaellt, dass sie eigentlich doch gerne
                    // bis zu 16 Listen-Level haetten.  Wir tun das *nicht*
                    // (siehe Kommentar oben bei "struct
                    // WW8LFOInfo")
                    aLFOLVL.nLevel = aBits1 & 0x0F;
                    if( (0xFF > aBits1) &&
                        (nMaxLevel > aLFOLVL.nLevel) )
                    {
                        if (aBits1 & 0x10)
                            aLFOLVL.bStartAt = true;
                        else
                            aLFOLVL.bStartAt = false;
                        //
                        // 2.2.2.2 eventuell auch den zugehoerigen LVL einlesen
                        //
                        SwNumFmt aNumFmt(
                            pLFOInfo->pNumRule->Get(aLFOLVL.nLevel));
                        if (aBits1 & 0x20)
                        {
                            aLFOLVL.bFormat = true;
                            // falls bStartup true, hier den Startup-Level
                            // durch den im LVL vermerkten ersetzen LVLF
                            // einlesen
                            bLVLOk = ReadLVL(aNumFmt, aItemSet[nLevel],
                                pParentListInfo->aIdSty[nLevel],
                                aLFOLVL.bStartAt, aNotReallyThere, nLevel,
                                pLFOInfo->maParaSprms[nLevel]);

                            if (!bLVLOk)
                                break;
                        }
                        else if (aLFOLVL.bStartAt)
                        {
                            aNumFmt.SetStart(
                                writer_cast<sal_uInt16>(aLFOLVL.nStartAt));
                        }
                        //
                        // 2.2.2.3 das NumFmt in die NumRule aufnehmen
                        //
                        pLFOInfo->pNumRule->Set(aLFOLVL.nLevel, aNumFmt);
                    }
                    bLVLOk = true;

                    if (nMaxLevel > aLFOLVL.nLevel)
                        pLFOInfo->maOverrides[aLFOLVL.nLevel] = aLFOLVL;
                }
                if( !bLVLOk )
                    break;
                //
                // 2.2.3 die LVL der neuen NumRule anpassen
                //
                sal_uInt16 aFlagsNewCharFmt = 0;
                bool bNewCharFmtCreated = false;
                for (nLevel = 0; nLevel < pLFOInfo->nLfoLvl; ++nLevel)
                {
                    AdjustLVL( nLevel, *pLFOInfo->pNumRule, aItemSet, aCharFmt,
                        bNewCharFmtCreated, sPrefix );
                    if( bNewCharFmtCreated )
                        aFlagsNewCharFmt += (1 << nLevel);
                }
                //
                // 2.2.4 ItemPools leeren und loeschen
                //
                for (nLevel = 0; nLevel < pLFOInfo->nLfoLvl; ++nLevel)
                    delete aItemSet[ nLevel ];
                bOk = true;
            }
        }
    }
    if( !bOk )
    {
        // Fehler aufgetreten - LSTInfos und LFOInfos abraeumen !!!
        ;
    }
    // und schon sind wir fertig!
    rSt.Seek( nOriginalPos );
}

WW8ListManager::~WW8ListManager()
{
    /*
    named lists remain in doc!!!
    unnamed lists are deleted when unused
    pLFOInfos are in any case destructed
    */
    for(std::vector<WW8LSTInfo *>::iterator aIter = maLSTInfos.begin();
        aIter != maLSTInfos.end(); ++aIter)
    {
        if ((*aIter)->pNumRule && !(*aIter)->bUsedInDoc &&
            (*aIter)->pNumRule->IsAutoRule())
        {
            rDoc.DelNumRule((*aIter)->pNumRule->GetName());
        }
        delete *aIter;
    }

    if (pLFOInfos)
    {
        for(sal_uInt16 nInfo = pLFOInfos->Count(); nInfo; )
        {
            WW8LFOInfo *pActInfo = pLFOInfos->GetObject(--nInfo);
            if (pActInfo->bOverride && pActInfo->pNumRule
                && !pActInfo->bUsedInDoc && pActInfo->pNumRule->IsAutoRule())
            {
                rDoc.DelNumRule( pActInfo->pNumRule->GetName() );
            }
        }
        delete pLFOInfos;
    }
}

sal_uInt16 WW8ListManager::GetPossibleLFOPosition(
    const sal_uInt16 nStyleID,
    const sal_uInt8 nGivenListLevel )
{
    sal_uInt16 nPossibleLFOPosition = USHRT_MAX;

    StyleInList::iterator aItr = maStyleInList.find( nStyleID );
    if ( aItr != maStyleInList.end()
         && aItr->second < pLFOInfos->Count() )
    {
        WW8LFOInfo* pLFOInfo = pLFOInfos->GetObject( aItr->second );
        WW8LSTInfo* pParentListInfo = GetLSTByListId( pLFOInfo->nIdLst );
        if ( pParentListInfo != NULL
             && pParentListInfo->aIdSty[nGivenListLevel] == nStyleID )
        {
            nPossibleLFOPosition = aItr->second;
        }
    }

    return nPossibleLFOPosition;
}


bool IsEqualFormatting(const SwNumRule &rOne, const SwNumRule &rTwo)
{
    bool bRet =
        (
          rOne.GetRuleType() == rTwo.GetRuleType() &&
          rOne.IsContinusNum() == rTwo.IsContinusNum() &&
          rOne.IsAbsSpaces() == rTwo.IsAbsSpaces() &&
          rOne.GetPoolFmtId() == rTwo.GetPoolFmtId() &&
          rOne.GetPoolHelpId() == rTwo.GetPoolHelpId() &&
          rTwo.GetPoolHlpFileId() == rTwo.GetPoolHlpFileId()
        );

    if (bRet)
    {
        for (sal_uInt8 n = 0; n < MAXLEVEL; ++n )
        {
            //The SvxNumberFormat compare, not the SwNumFmt compare
            const SvxNumberFormat &rO = rOne.Get(n);
            const SvxNumberFormat &rT = rTwo.Get(n);
            if (!(rO == rT))
            {
                bRet = false;
                break;
            }
        }
    }
    return bRet;
}

SwNumRule* WW8ListManager::GetNumRuleForActivation(sal_uInt16 nLFOPosition,
    const sal_uInt8 nLevel, std::vector<sal_uInt8> &rParaSprms, SwTxtNode *pNode)
{
    sal_uInt16 nLFOInfos = pLFOInfos ? pLFOInfos->Count() : 0;
    if( nLFOInfos <= nLFOPosition )
        return 0;

    WW8LFOInfo* pLFOInfo = pLFOInfos->GetObject( nLFOPosition );

    if( !pLFOInfo )
        return 0;

    bool bFirstUse = !pLFOInfo->bUsedInDoc;
    pLFOInfo->bUsedInDoc = true;

    if( !pLFOInfo->pNumRule )
        return 0;

    // #i25545#
    // --> OD 2009-03-12 #i100132# - a number format does not have to exist on given list level
//    SwNumFmt pFmt(*(pLFOInfo->pNumRule->GetNumFmt(nLevel)));
    SwNumFmt pFmt(pLFOInfo->pNumRule->Get(nLevel));
    // <--
    if (rReader.IsRightToLeft() && nLastLFOPosition != nLFOPosition) {
        if ( pFmt.GetNumAdjust() == SVX_ADJUST_RIGHT)
            pFmt.SetNumAdjust(SVX_ADJUST_LEFT);
        else if ( pFmt.GetNumAdjust() == SVX_ADJUST_LEFT)
            pFmt.SetNumAdjust(SVX_ADJUST_RIGHT);
        pLFOInfo->pNumRule->Set(nLevel, pFmt);
    }
    nLastLFOPosition = nLFOPosition;
    /*
    #i1869#
    If this list has had its bits set in word 2000 to pretend that it is a
    simple list from the point of view of the user, then it is almost
    certainly a simple continuous list, and we will try to keep it like that.
    Otherwise when we save again it will be shown as the true outline list
    that it is, confusing the user that just wanted what they thought was a
    simple list. On the otherhand it is possible that some of the other levels
    were used by the user, in which case we will not pretend anymore that it
    is a simple list. Something that word 2000 does anyway, that 97 didn't, to
    my bewilderment.
    */
    if (nLevel && pLFOInfo->pNumRule->IsContinusNum())
        pLFOInfo->pNumRule->SetContinusNum(false);

    if( (!pLFOInfo->bOverride) && (!pLFOInfo->bLSTbUIDSet) )
    {
        WW8LSTInfo* pParentListInfo = GetLSTByListId( pLFOInfo->nIdLst );
        if( pParentListInfo )
            pParentListInfo->bUsedInDoc = true;
        pLFOInfo->bLSTbUIDSet = true;
    }

    if (pLFOInfo->maParaSprms.size() > nLevel)
        rParaSprms = pLFOInfo->maParaSprms[nLevel];

    SwNumRule *pRet = pLFOInfo->pNumRule;

    bool bRestart(false);
    sal_uInt16 nStart(0);
    bool bNewstart(false);
    /*
      Note: If you fiddle with this then you have to make sure that #i18322#
      #i13833#, #i20095# and #112466# continue to work

      Check if there were overrides for this level
    */
    if (pLFOInfo->bOverride && nLevel < pLFOInfo->nLfoLvl)
    {
        WW8LSTInfo* pParentListInfo = GetLSTByListId(pLFOInfo->nIdLst);
        ASSERT(pParentListInfo, "ww: Impossible lists, please report");
        if (pParentListInfo && pParentListInfo->pNumRule)
        {
            const WW8LFOLVL &rOverride = pLFOInfo->maOverrides[nLevel];
            bool bNoChangeFromParent =
                IsEqualFormatting(*pRet, *(pParentListInfo->pNumRule));

            //If so then I think word still uses the parent (maybe)
            if (bNoChangeFromParent)
            {
                pRet = pParentListInfo->pNumRule;

                //did it not affect start at value ?
                if (bFirstUse)
                {
                    if (rOverride.bStartAt)
                    {
                        const SwNumFmt &rFmt =
                            pParentListInfo->pNumRule->Get(nLevel);
                        if (
                             rFmt.GetStart() ==
                             pLFOInfo->maOverrides[nLevel].nStartAt
                           )
                        {
                            bRestart = true;
                        }
                        else
                        {
                            bNewstart = true;
                            nStart = writer_cast<sal_uInt16>
                                (pLFOInfo->maOverrides[nLevel].nStartAt);
                        }
                    }
                }

                pParentListInfo->bUsedInDoc = true;
            }
        }
    }

    if (pNode)
    {
        pNode->SetAttrListLevel(nLevel);

        if (bRestart || bNewstart)   //#112466# (I think)
            pNode->SetListRestart(true);
        if (bNewstart)
            pNode->SetAttrListRestartValue(nStart);
    }
    return pRet;
}


//----------------------------------------------------------------------------
//          SwWW8ImplReader:  anhaengen einer Liste an einen Style oder Absatz
//----------------------------------------------------------------------------
bool SwWW8ImplReader::SetTxtFmtCollAndListLevel(
    const SwPaM& rRg,
    SwWW8StyInf& rStyleInfo)
{
    bool bRes = true;
    if( rStyleInfo.pFmt && rStyleInfo.bColl )
    {
        bRes = rDoc.SetTxtFmtColl(rRg, (SwTxtFmtColl*)rStyleInfo.pFmt) ? true : false;
        SwTxtNode* pTxtNode = pPaM->GetNode()->GetTxtNode();
        ASSERT( pTxtNode != NULL, "No Text-Node at PaM-Position" );
        if ( pTxtNode == NULL )
        {
            // make code robust
            return bRes;
        }

        const SwNumRule * pNumRule = pTxtNode->GetNumRule(); // #i27610#

        if( !IsInvalidOrToBeMergedTabCell()
            && ! (pNumRule && pNumRule->IsOutlineRule()) ) // #i27610#
        {
            pTxtNode->ResetAttr( RES_PARATR_NUMRULE );
        }

        if ( USHRT_MAX > rStyleInfo.nLFOIndex
             && WW8ListManager::nMaxLevel > rStyleInfo.nListLevel )
        {
            const bool bApplyListStyle = false;
            RegisterNumFmtOnTxtNode( rStyleInfo.nLFOIndex, rStyleInfo.nListLevel, bApplyListStyle );
        }
    }
    return bRes;
}

void UseListIndent(SwWW8StyInf &rStyle, const SwNumFmt &rFmt)
{
    if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
    {
        const long nAbsLSpace = rFmt.GetAbsLSpace();
        const long nListFirstLineIndent = GetListFirstLineIndent(rFmt);
        SvxLRSpaceItem aLR(ItemGet<SvxLRSpaceItem>(*rStyle.pFmt, RES_LR_SPACE));
        aLR.SetTxtLeft(nAbsLSpace);
        aLR.SetTxtFirstLineOfst(writer_cast<short>(nListFirstLineIndent));
        rStyle.pFmt->SetFmtAttr(aLR);
        rStyle.bListReleventIndentSet = true;
    }
}

void SetStyleIndent(SwWW8StyInf &rStyle, const SwNumFmt &rFmt)
{
    if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
    {
        SvxLRSpaceItem aLR(ItemGet<SvxLRSpaceItem>(*rStyle.pFmt, RES_LR_SPACE));
        if (rStyle.bListReleventIndentSet)
        {
            SyncIndentWithList( aLR, rFmt, false, false );
        }
        else
        {
            aLR.SetTxtLeft(0);
            aLR.SetTxtFirstLineOfst(0);
        }
        rStyle.pFmt->SetFmtAttr(aLR);
    }
}

void SwWW8ImplReader::SetStylesList(
    sal_uInt16 nStyle,
    sal_uInt16 nActLFO,
    sal_uInt8 nActLevel)
{
    SwWW8StyInf &rStyleInf = pCollA[nStyle];
    if (rStyleInf.bValid)
    {
        ASSERT(pAktColl, "Cannot be called outside of style import");
        // Phase 1: Nummerierungsattribute beim Einlesen einer StyleDef
        if( pAktColl )
        {
            // jetzt nur die Parameter vermerken: die tatsaechliche Liste wird
            // spaeter drangehaengt, wenn die Listendefinitionen gelesen sind...
            if (
                 (USHRT_MAX > nActLFO) &&
                 (WW8ListManager::nMaxLevel > nActLevel)
               )
            {
                rStyleInf.nLFOIndex  = nActLFO;
                rStyleInf.nListLevel = nActLevel;

                if (
                    (USHRT_MAX > nActLFO) &&
                    (WW8ListManager::nMaxLevel > nActLevel)
                   )
                {
                    std::vector<sal_uInt8> aParaSprms;
                    SwNumRule *pNmRule =
                        pLstManager->GetNumRuleForActivation(nActLFO,
                            nActLevel, aParaSprms);
                    if (pNmRule)
                        UseListIndent(rStyleInf, pNmRule->Get(nActLevel));
                }
            }
        }
    }
}

void SwWW8ImplReader::RegisterNumFmtOnStyle( sal_uInt16 nStyle )
{
    SwWW8StyInf &rStyleInf = pCollA[nStyle];
    if (rStyleInf.bValid && rStyleInf.pFmt)
    {
        //Save old pre-list modified indent, which are the word indent values
        rStyleInf.maWordLR =
            ItemGet<SvxLRSpaceItem>(*rStyleInf.pFmt, RES_LR_SPACE);

        // Phase 2: aktualisieren der StyleDef nach einlesen aller Listen
        SwNumRule* pNmRule = 0;
        const sal_uInt16 nLFO = rStyleInf.nLFOIndex;
        const sal_uInt8  nLevel = rStyleInf.nListLevel;
        if (
             (USHRT_MAX > nLFO) &&
             (WW8ListManager::nMaxLevel > nLevel)
           )
        {
            std::vector<sal_uInt8> aParaSprms;
            pNmRule =
                pLstManager->GetNumRuleForActivation( nLFO, nLevel, aParaSprms );

            if ( pNmRule != NULL )
            {
                if ( rStyleInf.IsWW8BuiltInHeadingStyle()
                     && rStyleInf.HasWW8OutlineLevel() )
                {
                    rStyleInf.pOutlineNumrule = pNmRule;
                }
                else
                {
                    rStyleInf.pFmt->SetFmtAttr( SwNumRuleItem( pNmRule->GetName() ) );
                    rStyleInf.bHasStyNumRule = true;
                }
            }
        }

        if (pNmRule)
            SetStyleIndent(rStyleInf, pNmRule->Get(nLevel));
    }
}

void SwWW8ImplReader::RegisterNumFmtOnTxtNode(
    sal_uInt16 nActLFO,
    sal_uInt8 nActLevel,
    const bool bSetAttr)
{
    // beachte: die Methode haengt die NumRule an den Text Node, falls
    // bSetAttr (dann muessen natuerlich vorher die Listen gelesen sein)
    // stellt sie NUR den Level ein, im Vertrauen darauf, dass am STYLE eine
    // NumRule haengt - dies wird NICHT ueberprueft !!!

    if (pLstManager) // sind die Listendeklarationen gelesen?
    {
        std::vector<sal_uInt8> aParaSprms;
        SwTxtNode* pTxtNd = pPaM->GetNode()->GetTxtNode();
        ASSERT(pTxtNd, "Kein Text-Node an PaM-Position");

        const SwNumRule* pRule =
            bSetAttr
            ? pLstManager->GetNumRuleForActivation( nActLFO, nActLevel, aParaSprms, pTxtNd)
            : 0;

        if ( pRule != NULL || !bSetAttr)
        {
            if ( bSetAttr
                 && pTxtNd->GetNumRule() != pRule
                 && pTxtNd->GetNumRule() != rDoc.GetOutlineNumRule() )
            {
                pTxtNd->SetAttr( SwNumRuleItem( pRule->GetName() ) );
            }

            pTxtNd->SetAttrListLevel(nActLevel);
            // - <IsCounted()> state of text node has to be adjusted accordingly.
            if ( /*nActLevel >= 0 &&*/ nActLevel < MAXLEVEL )
            {
                pTxtNd->SetCountedInList( true );
            }

            // Direct application of the list level formatting no longer
            // needed for list levels of mode LABEL_ALIGNMENT
            bool bApplyListLevelIndentDirectlyAtPara( true );
            {
                if ( pTxtNd->GetNumRule() && nActLevel < MAXLEVEL )
                {
                    const SwNumFmt& rFmt = pTxtNd->GetNumRule()->Get( nActLevel );
                    if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
                    {
                        bApplyListLevelIndentDirectlyAtPara = false;
                    }
                }
            }
            if ( bApplyListLevelIndentDirectlyAtPara )
            {
                SfxItemSet aListIndent(rDoc.GetAttrPool(), RES_LR_SPACE,
                        RES_LR_SPACE);
                const SvxLRSpaceItem *pItem = (const SvxLRSpaceItem*)(
                    GetFmtAttr(RES_LR_SPACE));
                ASSERT(pItem, "impossible");
                if (pItem)
                    aListIndent.Put(*pItem);

                /*
                 Take the original paragraph sprms attached to this list level
                 formatting and apply them to the paragraph. I'm convinced that
                 this is exactly what word does.
                */
                if (short nLen = static_cast< short >(aParaSprms.size()))
                {
                    SfxItemSet* pOldAktItemSet = pAktItemSet;
                    SetAktItemSet(&aListIndent);

                    sal_uInt8* pSprms1  = &aParaSprms[0];
                    while (0 < nLen)
                    {
                        sal_uInt16 nL1 = ImportSprm(pSprms1);
                        nLen = nLen - nL1;
                        pSprms1 += nL1;
                    }

                    SetAktItemSet(pOldAktItemSet);
                }

                const SvxLRSpaceItem *pLR =
                    HasItem<SvxLRSpaceItem>(aListIndent, RES_LR_SPACE);
                ASSERT(pLR, "Impossible");
                if (pLR)
                {
                    pCtrlStck->NewAttr(*pPaM->GetPoint(), *pLR);
                    pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_LR_SPACE);
                }
            }
        }
    }
}

void SwWW8ImplReader::RegisterNumFmt(sal_uInt16 nActLFO, sal_uInt8 nActLevel)
{
    // sind wir erst beim Einlesen der StyleDef ?
    if (pAktColl)
        SetStylesList( nAktColl , nActLFO, nActLevel);
    else
        RegisterNumFmtOnTxtNode(nActLFO, nActLevel);
}

void SwWW8ImplReader::Read_ListLevel(sal_uInt16, const sal_uInt8* pData,
    short nLen)
{
    if (pPlcxMan && pPlcxMan->GetDoingDrawTextBox())
        return;

    if( nLen < 0 )
    {
        // aktuelle Liste ist hier zu Ende, was ist zu tun ???
        nListLevel = WW8ListManager::nMaxLevel;
        if (pStyles && !bVer67)
            pStyles->nWwNumLevel = 0;
    }
    else
    {
        // Sicherheitspruefung auf NIL Pointer
        if( !pData ) return;
        // die Streamdaten sind hier Null basiert, so wie wir es brauchen
        nListLevel = *pData;

        if (pStyles && !bVer67)
        {
            /*
            #94672#
            if this is the case, then if the numbering is actually stored in
            winword 6 format, and its likely that sprmPIlvl has been abused
            to set the ww6 list level information which we will need when we
            reach the true ww6 list def.  So set it now
            */
            pStyles->nWwNumLevel = nListLevel;
        }

        if (WW8ListManager::nMaxLevel <= nListLevel )
        {
            // handle invalid list level value by reseting it
            nListLevel = WW8ListManager::nMaxLevel;
        }
        else if ( nLFOPosition < USHRT_MAX
                  && nListLevel < WW8ListManager::nMaxLevel )
        {
            RegisterNumFmt( nLFOPosition, nListLevel );
            // reset kept list attributes
            nLFOPosition = USHRT_MAX;
            nListLevel  = WW8ListManager::nMaxLevel;
        }
        else if ( pLstManager != NULL
                  && pAktColl != NULL )
        {
            const sal_uInt16 nPossibleLFOPosition =
                pLstManager->GetPossibleLFOPosition( nAktColl, nListLevel );
            if ( nPossibleLFOPosition < USHRT_MAX )
            {
                // temporary register Style without reseting kept list attributes
                RegisterNumFmt( nPossibleLFOPosition, nListLevel );
            }
        }
    }
}

void SwWW8ImplReader::Read_LFOPosition(
    sal_uInt16,
    const sal_uInt8* pData,
    short nLen)
{
    if (pPlcxMan && pPlcxMan->GetDoingDrawTextBox())
        return;

    if( nLen < 0 )
    {
        // aktueller Level ist hier zu Ende, was ist zu tun ???
        nLFOPosition = USHRT_MAX;
        nListLevel = WW8ListManager::nMaxLevel;
    }
    else
    {
        // Sicherheitspruefung auf NIL Pointer
        if( !pData )
            return;
        short nData = SVBT16ToShort( pData );
        if( 0 >= nData )
        {
            /*
            #94672# discussion
            If you have a paragraph in word with left and/or hanging indent
            and remove its numbering, then the indentation appears to get
            reset, but not back to the base style, instead its goes to a blank
            setting.
            Unless its a broken ww6 list in 97 in which case more hackery is
            required, some more details about that in
            ww8par6.cxx#SwWW8ImplReader::Read_LR
            */

            if (pAktColl)
            {
                pAktColl->SetFmtAttr(*GetDfltAttr( RES_PARATR_NUMRULE));
                pAktColl->SetFmtAttr(SvxLRSpaceItem(RES_LR_SPACE));    //#94672#
            }
            else if (SwTxtNode* pTxtNode = pPaM->GetNode()->GetTxtNode())
            {
                pTxtNode->ResetAttr( RES_PARATR_NUMRULE );
                pTxtNode->SetCountedInList(false);

                /*
                #i24553#
                Hmm, I can't remove outline numbering on a per txtnode basis,
                but I can set some normal numbering, and that overrides outline
                numbering, and then I can say when I come to say that I want no
                number on the normal numbering rule, that should all work out

                #115901#
                No special outline number in textnode any more
                */
                if (pTxtNode->IsOutline())
                {
                    // Assure that the numbering rule, which is retrieved at
                    // the paragraph is the outline numbering rule, instead of
                    // incorrectly setting the chosen outline rule.
                    // Note: The chosen outline rule doesn't have to correspond
                    //       to the outline rule
                    if ( pTxtNode->GetNumRule() != rDoc.GetOutlineNumRule() )
                    {
                        pTxtNode->SetAttr(
                            SwNumRuleItem( rDoc.GetOutlineNumRule()->GetName() ) );
                    }
                }

                //#94672#
                pCtrlStck->NewAttr(*pPaM->GetPoint(), SvxLRSpaceItem(RES_LR_SPACE));
                pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_LR_SPACE);
            }
            nLFOPosition = USHRT_MAX;
        }
        else
        {
            nLFOPosition = (sal_uInt16)nData-1;
            /*
            #94672#
            If we are a ww8+ style with ww7- style lists then there is a
            bizarre broken word bug where when the list is removed from a para
            the ww6 list first line indent still affects the first line
            indentation.  Setting this flag will allow us to recover from this
            braindeadness
            */
            if ( pAktColl
                 && (nLFOPosition == 2047-1) )
            {
                pCollA[nAktColl].bHasBrokenWW6List = true;
            }

            // die Streamdaten sind hier 1 basiert, wir ziehen EINS ab
            if (USHRT_MAX > nLFOPosition)
            {
                if (nLFOPosition != 2047-1) //Normal ww8+ list behaviour
                {
                    if ( nListLevel == WW8ListManager::nMaxLevel )
                    {
                        nListLevel = 0;
                        if ( pAktColl != NULL )
                        {
                            // temporary register Style without reseting kept list attributes
                            RegisterNumFmt( nLFOPosition, nListLevel );
                        }
                    }
                    else if (WW8ListManager::nMaxLevel > nListLevel)
                    {
                        RegisterNumFmt(nLFOPosition, nListLevel);
                        // reset kept list attributes
                        nLFOPosition = USHRT_MAX;
                        nListLevel = WW8ListManager::nMaxLevel;
                    }
                }
                else if (pPlcxMan && pPlcxMan->HasParaSprm(0xC63E))
                {
                    /*
                     #i8114# Horrific backwards compatible ww7- lists in ww8+ docs
                    */
                    Read_ANLevelNo(13 /*equiv ww7- sprm no*/, &nListLevel, 1);
                }
            }
        }
    }
}

// -------------------------------------------------------------------
// ------------------------- Reading Controls ------------------------
// -------------------------------------------------------------------

bool SwWW8ImplReader::ImportFormulaControl(WW8FormulaControl &aFormula,
    WW8_CP nStart, SwWw8ControlType nWhich )
{
    bool bRet=false;
    /*
     * Save the reader state and process the sprms for this anchor cp.
     * Doing so will set the nPicLocFc to the offset to find the hypertext
     * data in the data stream.
     */
    WW8_CP nEndCp = nStart+1; //Only interested in the single 0x01 character

    WW8ReaderSave aSave(this,nStart);

    WW8PLCFManResult aRes;
    nStart = pPlcxMan->Where();
    while(nStart <= nEndCp)
    {
        if ( pPlcxMan->Get(&aRes)
            && aRes.pMemPos && aRes.nSprmId )
        {
            //only interested in sprms which would set nPicLocFc
            if ( (68 == aRes.nSprmId) || (0x6A03 == aRes.nSprmId) )
            {
                Read_PicLoc( aRes.nSprmId, aRes.pMemPos +
                    mpSprmParser->DistanceToData(aRes.nSprmId), 4);
                break;
            }
        }
        (*pPlcxMan)++;
        nStart = pPlcxMan->Where();
    }
    sal_uLong nOffset = nPicLocFc;
    aSave.Restore(this);

    sal_uLong nOldPos = pDataStream->Tell();
    WW8_PIC aPic;
    pDataStream->Seek( nOffset);
    PicRead( pDataStream, &aPic, bVer67);

    if((aPic.lcb > 0x3A) && !pDataStream->GetError() )
    {
        aFormula.FormulaRead(nWhich,pDataStream);
        bRet = true;
    }

    /*
     There is a problem with aPic, the WW8_PIC is always used even though it
     is too big for the WW95 files, it needs to be modified to check the
     version C.
     */
    pDataStream->Seek( nOldPos );
    return(bRet);
}

sal_Bool SwMSConvertControls::InsertFormula(WW8FormulaControl &rFormula)
{
    sal_Bool bRet = sal_False;

    const uno::Reference< lang::XMultiServiceFactory > & rServiceFactory =
        GetServiceFactory();

    if(!rServiceFactory.is())
        return sal_False;

    awt::Size aSz;
    uno::Reference< form::XFormComponent> xFComp;

    if (sal_True == (bRet = rFormula.Import(rServiceFactory, xFComp, aSz)))
    {
        uno::Reference <drawing::XShape> xShapeRef;
        if (sal_True == (bRet = InsertControl(xFComp, aSz, &xShapeRef, false)))
            GetShapes()->add(xShapeRef);
    }
    return bRet;
}

void WW8FormulaControl::FormulaRead(SwWw8ControlType nWhich,
    SvStream *pDataStream)
{
    sal_uInt8 nField;
    sal_uInt8 nHeaderByte;

    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

    rtl_TextEncoding eEnc = rRdr.eStructCharSet;
    sTitle = !nType ? WW8ReadPString(*pDataStream, eEnc, true)
                    : WW8Read_xstz(*pDataStream, 0, true);

    if (nWhich == WW8_CT_CHECKBOX)
    {
        *pDataStream >> nDefaultChecked;
        nChecked = nDefaultChecked;

        sal_uInt8 iRes = (nHeaderByte >> 2) & 0x1F;
        switch (iRes)
        {
            case 1:  //checked
                nChecked = true;
                break;
            case 25: //undefined, Undefined checkboxes are treated as unchecked
            case 0:  //unchecked
                nChecked = false;
                break;
            default:
                ASSERT(!this, "unknown option, please report to cmc");
                break;
        }
    }
    else if (nWhich == WW8_CT_DROPDOWN)
        *pDataStream >> nChecked;
    else
    {
        sDefault = !nType ? WW8ReadPString(*pDataStream, eEnc, true)
                          : WW8Read_xstz(*pDataStream, 0, true);
    }

    sFormatting = !nType ? WW8ReadPString(*pDataStream, eEnc, true)
                         : WW8Read_xstz(*pDataStream, 0, true);

    sHelp = !nType ? WW8ReadPString(*pDataStream, eEnc, true)
                   : WW8Read_xstz(*pDataStream, 0, true);

    if (nWhich == WW8_CT_DROPDOWN)      //is this the case ?
        fToolTip = true;

    if( fToolTip )
    {
        sToolTip = !nType ? WW8ReadPString(*pDataStream, eEnc, true)
                          : 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;
        }
        ASSERT(bAllOk,
            "Unknown formfield dropdown list structure. Report to cmc");
        if (!bAllOk)    //Not as expected, don't risk it at all.
            nNoStrings = 0;
        maListEntries.reserve(nNoStrings);
        for (sal_uInt32 nI = 0; nI < nNoStrings; ++nI)
        {
            String sEntry = !nType ? WW8ReadPString(*pDataStream, eEnc, false)
                           : WW8Read_xstz(*pDataStream, 0, false);
            maListEntries.push_back(sEntry);
        }
    }
}

WW8FormulaListBox::WW8FormulaListBox(SwWW8ImplReader &rR)
    : WW8FormulaControl( CREATE_CONST_ASC(SL::aListBox), rR)
{
}

//Miserable hack to get a hardcoded guesstimate of the size of a list dropdown
//box's first entry to set as the lists default size
awt::Size SwWW8ImplReader::MiserableDropDownFormHack(const String &rString,
    uno::Reference<beans::XPropertySet>& rPropSet)
{
    awt::Size aRet;
    struct CtrlFontMapEntry
    {
        sal_uInt16 nWhichId;
        const sal_Char* pPropNm;
    };
    const CtrlFontMapEntry aMapTable[] =
    {
        { RES_CHRATR_COLOR,           "TextColor" },
        { RES_CHRATR_FONT,            "FontName" },
        { RES_CHRATR_FONTSIZE,        "FontHeight" },
        { RES_CHRATR_WEIGHT,          "FontWeight" },
        { RES_CHRATR_UNDERLINE,       "FontUnderline" },
        { RES_CHRATR_CROSSEDOUT,      "FontStrikeout" },
        { RES_CHRATR_POSTURE,         "FontSlant" },
        { 0,                          0 }
    };

    Font aFont;
    uno::Reference< beans::XPropertySetInfo > xPropSetInfo =
        rPropSet->getPropertySetInfo();

    uno::Any aTmp;
    for (const CtrlFontMapEntry* pMap = aMapTable; pMap->nWhichId; ++pMap)
    {
        bool bSet = true;
        const SfxPoolItem* pItem = GetFmtAttr( pMap->nWhichId );
        ASSERT(pItem, "Impossible");
        if (!pItem)
            continue;

        switch ( pMap->nWhichId )
        {
        case RES_CHRATR_COLOR:
            {
                String pNm;
                if (xPropSetInfo->hasPropertyByName(pNm = C2U("TextColor")))
                {
                    aTmp <<= (sal_Int32)((SvxColorItem*)pItem)->GetValue().GetColor();
                    rPropSet->setPropertyValue(pNm, aTmp);
                }
            }
            aFont.SetColor(((SvxColorItem*)pItem)->GetValue());
            break;
        case RES_CHRATR_FONT:
            {
                const SvxFontItem *pFontItem = (SvxFontItem *)pItem;
                String pNm;
                if (xPropSetInfo->hasPropertyByName(pNm = C2U("FontStyleName")))
                {
                    aTmp <<= rtl::OUString( pFontItem->GetStyleName());
                    rPropSet->setPropertyValue( pNm, aTmp );
                }
                if (xPropSetInfo->hasPropertyByName(pNm = C2U("FontFamily")))
                {
                    aTmp <<= (sal_Int16)pFontItem->GetFamily();
                    rPropSet->setPropertyValue( pNm, aTmp );
                }
                if (xPropSetInfo->hasPropertyByName(pNm = C2U("FontCharset")))
                {
                    aTmp <<= (sal_Int16)pFontItem->GetCharSet();
                    rPropSet->setPropertyValue( pNm, aTmp );
                }
                if (xPropSetInfo->hasPropertyByName(pNm = C2U("FontPitch")))
                {
                    aTmp <<= (sal_Int16)pFontItem->GetPitch();
                    rPropSet->setPropertyValue( pNm, aTmp );
                }

                aTmp <<= rtl::OUString( pFontItem->GetFamilyName());
                aFont.SetName( pFontItem->GetFamilyName() );
                aFont.SetStyleName( pFontItem->GetStyleName() );
                aFont.SetFamily( pFontItem->GetFamily() );
                aFont.SetCharSet( pFontItem->GetCharSet() );
                aFont.SetPitch( pFontItem->GetPitch() );
            }
            break;

        case RES_CHRATR_FONTSIZE:
            {
                Size aSize( aFont.GetSize().Width(),
                            ((SvxFontHeightItem*)pItem)->GetHeight() );
                aTmp <<= ((float)aSize.Height()) / 20.0;

                aFont.SetSize(OutputDevice::LogicToLogic(aSize, MAP_TWIP,
                    MAP_100TH_MM));
            }
            break;

        case RES_CHRATR_WEIGHT:
            aTmp <<= (float)VCLUnoHelper::ConvertFontWeight(
                                        ((SvxWeightItem*)pItem)->GetWeight() );
            aFont.SetWeight( ((SvxWeightItem*)pItem)->GetWeight() );
            break;

        case RES_CHRATR_UNDERLINE:
            aTmp <<= (sal_Int16)(((SvxUnderlineItem*)pItem)->GetLineStyle());
            aFont.SetUnderline(((SvxUnderlineItem*)pItem)->GetLineStyle());
            break;

        case RES_CHRATR_CROSSEDOUT:
            aTmp <<= (sal_Int16)( ((SvxCrossedOutItem*)pItem)->GetStrikeout() );
            aFont.SetStrikeout( ((SvxCrossedOutItem*)pItem)->GetStrikeout() );
            break;

        case RES_CHRATR_POSTURE:
            aTmp <<= (sal_Int16)( ((SvxPostureItem*)pItem)->GetPosture() );
            aFont.SetItalic( ((SvxPostureItem*)pItem)->GetPosture() );
            break;

        default:
            bSet = false;
            break;
        }

        if (bSet && xPropSetInfo->hasPropertyByName(C2U(pMap->pPropNm)))
            rPropSet->setPropertyValue(C2U(pMap->pPropNm), aTmp);
    }
    // now calculate the size of the control
    OutputDevice* pOut = Application::GetDefaultDevice();
    ASSERT(pOut, "Impossible");
    if (pOut)
    {
        pOut->Push( PUSH_FONT | PUSH_MAPMODE );
        pOut->SetMapMode( MapMode( MAP_100TH_MM ));
        pOut->SetFont( aFont );
        aRet.Width  = pOut->GetTextWidth(rString);
        aRet.Width += 500; //plus size of button, total hack territory
        aRet.Height = pOut->GetTextHeight();
        pOut->Pop();
    }
    return aRet;
}

sal_Bool WW8FormulaListBox::Import(const uno::Reference <
    lang::XMultiServiceFactory> &rServiceFactory,
    uno::Reference <form::XFormComponent> &rFComp,awt::Size &rSz )
{
    uno::Reference<uno::XInterface> xCreate = rServiceFactory->createInstance(
        C2U("com.sun.star.form.component.ComboBox"));
    if( !xCreate.is() )
        return sal_False;

    rFComp = uno::Reference<form::XFormComponent>(xCreate, uno::UNO_QUERY);
    if( !rFComp.is() )
        return sal_False;

    uno::Reference<beans::XPropertySet> xPropSet(xCreate, uno::UNO_QUERY);

    uno::Any aTmp;
    if (sTitle.Len())
        aTmp <<= rtl::OUString(sTitle);
    else
        aTmp <<= rtl::OUString(sName);
    xPropSet->setPropertyValue(C2U("Name"), aTmp );

    if (sToolTip.Len())
    {
        aTmp <<= rtl::OUString(sToolTip);
        xPropSet->setPropertyValue(C2U("HelpText"), aTmp );
    }

    sal_Bool bDropDown(sal_True);
    xPropSet->setPropertyValue(C2U("Dropdown"), cppu::bool2any(bDropDown));

    if (!maListEntries.empty())
    {
        sal_uInt32 nLen = maListEntries.size();
        uno::Sequence< ::rtl::OUString > aListSource(nLen);
        for (sal_uInt32 nI = 0; nI < nLen; ++nI)
            aListSource[nI] = rtl::OUString(maListEntries[nI]);
        aTmp <<= aListSource;
        xPropSet->setPropertyValue(C2U("StringItemList"), aTmp );

        if (fDropdownIndex < nLen)
        {
            aTmp <<= aListSource[fDropdownIndex];
        }
        else
        {
            aTmp <<= aListSource[0];
        }

        xPropSet->setPropertyValue(C2U("DefaultText"), aTmp );

        rSz = rRdr.MiserableDropDownFormHack(maListEntries[0], xPropSet);
    }
    else
    {
        static const sal_Unicode aBlank[] =
        {
            0x2002,0x2002,0x2002,0x2002,0x2002
        };
        rSz = rRdr.MiserableDropDownFormHack(String(aBlank), xPropSet);
    }

    return sal_True;
}

WW8FormulaCheckBox::WW8FormulaCheckBox(SwWW8ImplReader &rR)
    : WW8FormulaControl( CREATE_CONST_ASC(SL::aCheckBox), rR)
{
}

static void lcl_AddToPropertyContainer
(uno::Reference<beans::XPropertySet> xPropSet,
 const rtl::OUString & rPropertyName, const rtl::OUString & rValue)
{
    uno::Reference<beans::XPropertySetInfo> xPropSetInfo =
        xPropSet->getPropertySetInfo();
    if (xPropSetInfo.is() &&
        ! xPropSetInfo->hasPropertyByName(rPropertyName))
    {
        uno::Reference<beans::XPropertyContainer>
            xPropContainer(xPropSet, uno::UNO_QUERY);
        uno::Any aAny(C2U(""));
        xPropContainer->addProperty
            (rPropertyName,
             static_cast<sal_Int16>(beans::PropertyAttribute::BOUND |
                                    beans::PropertyAttribute::REMOVABLE),
             aAny);
    }

    uno::Any aAnyValue(rValue);
    xPropSet->setPropertyValue(rPropertyName, aAnyValue );
}

sal_Bool WW8FormulaCheckBox::Import(const uno::Reference <
    lang::XMultiServiceFactory> &rServiceFactory,
    uno::Reference <form::XFormComponent> &rFComp,awt::Size &rSz )
{
    uno::Reference< uno::XInterface > xCreate = rServiceFactory->createInstance(
        C2U("com.sun.star.form.component.CheckBox"));
    if( !xCreate.is() )
        return sal_False;

    rFComp = uno::Reference< form::XFormComponent >( xCreate, uno::UNO_QUERY );
    if( !rFComp.is() )
        return sal_False;

    uno::Reference< beans::XPropertySet > xPropSet( xCreate, uno::UNO_QUERY );

    rSz.Width = 16 * hpsCheckBox;
    rSz.Height = 16 * hpsCheckBox;

    uno::Any aTmp;
    if (sTitle.Len())
        aTmp <<= rtl::OUString(sTitle);
    else
        aTmp <<= rtl::OUString(sName);
    xPropSet->setPropertyValue(C2U("Name"), aTmp );

    aTmp <<= (sal_Int16)nChecked;
    xPropSet->setPropertyValue(C2U("DefaultState"), aTmp);

    if( sToolTip.Len() )
        lcl_AddToPropertyContainer(xPropSet, C2U("HelpText"), sToolTip);

    if( sHelp.Len() )
        lcl_AddToPropertyContainer(xPropSet, C2U("HelpF1Text"), sHelp);

    return sal_True;

}

WW8FormulaEditBox::WW8FormulaEditBox(SwWW8ImplReader &rR)
    : WW8FormulaControl( CREATE_CONST_ASC(SL::aTextField) ,rR)
{
}

sal_Bool SwMSConvertControls::InsertControl(
    const uno::Reference< form::XFormComponent > & rFComp,
    const awt::Size& rSize, uno::Reference< drawing::XShape > *pShape,
    sal_Bool bFloatingCtrl)
{
    const uno::Reference< container::XIndexContainer > &rComps = GetFormComps();
    uno::Any aTmp( &rFComp, ::getCppuType((const uno::Reference<
        form::XFormComponent >*)0) );
    rComps->insertByIndex( rComps->getCount(), aTmp );

    const uno::Reference< lang::XMultiServiceFactory > &rServiceFactory =
        GetServiceFactory();
    if( !rServiceFactory.is() )
        return sal_False;

    uno::Reference< uno::XInterface > xCreate = rServiceFactory->createInstance(
        C2U("com.sun.star.drawing.ControlShape"));
    if( !xCreate.is() )
        return sal_False;

    uno::Reference< drawing::XShape > xShape =
        uno::Reference< drawing::XShape >(xCreate, uno::UNO_QUERY);

    DBG_ASSERT(xShape.is(), "XShape nicht erhalten");
    xShape->setSize(rSize);

    uno::Reference< beans::XPropertySet > xShapePropSet(
        xCreate, uno::UNO_QUERY );

    //I lay a small bet that this will change to
    //sal_Int16 nTemp=TextContentAnchorType::AS_CHARACTER;
    sal_Int16 nTemp;
    if (bFloatingCtrl)
        nTemp= text::TextContentAnchorType_AT_PARAGRAPH;
    else
        nTemp= text::TextContentAnchorType_AS_CHARACTER;

    aTmp <<= nTemp;
    xShapePropSet->setPropertyValue(C2U("AnchorType"), aTmp );

    nTemp= text::VertOrientation::TOP;
    aTmp <<= nTemp;
    xShapePropSet->setPropertyValue(C2U("VertOrient"), aTmp );

    uno::Reference< text::XText >  xDummyTxtRef;
    uno::Reference< text::XTextRange >  xTxtRg =
        new SwXTextRange( *pPaM, xDummyTxtRef );

    aTmp.setValue(&xTxtRg,::getCppuType((
        uno::Reference< text::XTextRange >*)0));
    xShapePropSet->setPropertyValue(C2U("TextRange"), aTmp );

    // Das Control-Model am Control-Shape setzen
    uno::Reference< drawing::XControlShape >  xControlShape( xShape,
        uno::UNO_QUERY );
    uno::Reference< awt::XControlModel >  xControlModel( rFComp,
        uno::UNO_QUERY );
    xControlShape->setControl( xControlModel );

    if (pShape)
        *pShape = xShape;

    return sal_True;
}

/* vi:set tabstop=4 shiftwidth=4 expandtab: */



