LCOV - code coverage report
Current view: top level - sc/source/filter/html - htmlpars.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 447 1666 26.8 %
Date: 2012-08-25 Functions: 83 159 52.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 354 2370 14.9 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : #include <boost/shared_ptr.hpp>
      31                 :            : #include <comphelper/string.hxx>
      32                 :            : 
      33                 :            : #define SC_HTMLPARS_CXX
      34                 :            : #include "scitems.hxx"
      35                 :            : #include <editeng/eeitem.hxx>
      36                 :            : 
      37                 :            : #include <svtools/htmlcfg.hxx>
      38                 :            : #include <svx/algitem.hxx>
      39                 :            : #include <editeng/colritem.hxx>
      40                 :            : #include <editeng/brshitem.hxx>
      41                 :            : #include <editeng/editeng.hxx>
      42                 :            : #include <editeng/fhgtitem.hxx>
      43                 :            : #include <editeng/fontitem.hxx>
      44                 :            : #include <editeng/postitem.hxx>
      45                 :            : #include <editeng/udlnitem.hxx>
      46                 :            : #include <editeng/wghtitem.hxx>
      47                 :            : #include <editeng/boxitem.hxx>
      48                 :            : #include <editeng/justifyitem.hxx>
      49                 :            : #include <sfx2/objsh.hxx>
      50                 :            : #include <svl/eitem.hxx>
      51                 :            : #include <svl/intitem.hxx>
      52                 :            : #include <svtools/filter.hxx>
      53                 :            : #include <svtools/parhtml.hxx>
      54                 :            : #include <svtools/htmlkywd.hxx>
      55                 :            : #include <svtools/htmltokn.h>
      56                 :            : #include <sfx2/docfile.hxx>
      57                 :            : 
      58                 :            : #include <vcl/svapp.hxx>
      59                 :            : #include <tools/urlobj.hxx>
      60                 :            : #include <tools/tenccvt.hxx>
      61                 :            : 
      62                 :            : #include "htmlpars.hxx"
      63                 :            : #include "global.hxx"
      64                 :            : #include "document.hxx"
      65                 :            : #include "rangelst.hxx"
      66                 :            : 
      67                 :            : #include <orcus/css_parser.hpp>
      68                 :            : 
      69                 :            : #include <com/sun/star/document/XDocumentProperties.hpp>
      70                 :            : #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
      71                 :            : 
      72                 :            : using ::editeng::SvxBorderLine;
      73                 :            : using namespace ::com::sun::star;
      74                 :            : 
      75 [ +  - ][ +  - ]:          3 : ScHTMLStyles::ScHTMLStyles() : maEmpty() {}
      76                 :            : 
      77                 :          0 : void ScHTMLStyles::add(const char* pElemName, size_t nElemName, const char* pClassName, size_t nClassName,
      78                 :            :                        const rtl::OUString& aProp, const rtl::OUString& aValue)
      79                 :            : {
      80         [ #  # ]:          0 :     if (pElemName)
      81                 :            :     {
      82         [ #  # ]:          0 :         rtl::OUString aElem(pElemName, nElemName, RTL_TEXTENCODING_UTF8);
      83                 :          0 :         aElem = aElem.toAsciiLowerCase();
      84         [ #  # ]:          0 :         if (pClassName)
      85                 :            :         {
      86                 :            :             // Both element and class names given.
      87                 :            : 
      88         [ #  # ]:          0 :             ElemsType::iterator itrElem = maElemProps.find(aElem);
      89 [ #  # ][ #  # ]:          0 :             if (itrElem == maElemProps.end())
                 [ #  # ]
      90                 :            :             {
      91                 :            :                 // new element
      92                 :            :                 SAL_WNODEPRECATED_DECLARATIONS_PUSH
      93 [ #  # ][ #  # ]:          0 :                 std::auto_ptr<NamePropsType> p(new NamePropsType);
      94                 :            :                 SAL_WNODEPRECATED_DECLARATIONS_POP
      95 [ #  # ][ #  # ]:          0 :                 std::pair<ElemsType::iterator, bool> r = maElemProps.insert(aElem, p);
      96         [ #  # ]:          0 :                 if (!r.second)
      97                 :            :                     // insertion failed.
      98                 :          0 :                     return;
      99 [ #  # ][ #  # ]:          0 :                 itrElem = r.first;
     100                 :            :             }
     101                 :            : 
     102         [ #  # ]:          0 :             NamePropsType* pClsProps = itrElem->second;
     103         [ #  # ]:          0 :             rtl::OUString aClass(pClassName, nClassName, RTL_TEXTENCODING_UTF8);
     104                 :          0 :             aClass = aClass.toAsciiLowerCase();
     105         [ #  # ]:          0 :             insertProp(*pClsProps, aClass, aProp, aValue);
     106                 :            :         }
     107                 :            :         else
     108                 :            :         {
     109                 :            :             // Element name only. Add it to the element global.
     110         [ #  # ]:          0 :             insertProp(maElemGlobalProps, aElem, aProp, aValue);
     111         [ #  # ]:          0 :         }
     112                 :            :     }
     113                 :            :     else
     114                 :            :     {
     115         [ #  # ]:          0 :         if (pClassName)
     116                 :            :         {
     117                 :            :             // Class name only. Add it to the global.
     118         [ #  # ]:          0 :             rtl::OUString aClass(pClassName, nClassName, RTL_TEXTENCODING_UTF8);
     119                 :          0 :             aClass = aClass.toAsciiLowerCase();
     120         [ #  # ]:          0 :             insertProp(maGlobalProps, aClass, aProp, aValue);
     121                 :            :         }
     122                 :            :     }
     123                 :            : }
     124                 :            : 
     125                 :          0 : const rtl::OUString& ScHTMLStyles::getPropertyValue(
     126                 :            :     const rtl::OUString& rElem, const rtl::OUString& rClass, const rtl::OUString& rPropName) const
     127                 :            : {
     128                 :            :     // First, look into the element-class storage.
     129                 :            :     {
     130         [ #  # ]:          0 :         ElemsType::const_iterator itr = maElemProps.find(rElem);
     131 [ #  # ][ #  # ]:          0 :         if (itr != maElemProps.end())
                 [ #  # ]
     132                 :            :         {
     133         [ #  # ]:          0 :             const NamePropsType* pClasses = itr->second;
     134         [ #  # ]:          0 :             NamePropsType::const_iterator itr2 = pClasses->find(rClass);
     135 [ #  # ][ #  # ]:          0 :             if (itr2 != pClasses->end())
                 [ #  # ]
     136                 :            :             {
     137         [ #  # ]:          0 :                 const PropsType* pProps = itr2->second;
     138         [ #  # ]:          0 :                 PropsType::const_iterator itr3 = pProps->find(rPropName);
     139 [ #  # ][ #  # ]:          0 :                 if (itr3 != pProps->end())
     140         [ #  # ]:          0 :                     return itr3->second;
     141                 :            :             }
     142                 :            :         }
     143                 :            :     }
     144                 :            :     // Next, look into the class global storage.
     145                 :            :     {
     146         [ #  # ]:          0 :         NamePropsType::const_iterator itr = maGlobalProps.find(rClass);
     147 [ #  # ][ #  # ]:          0 :         if (itr != maGlobalProps.end())
                 [ #  # ]
     148                 :            :         {
     149         [ #  # ]:          0 :             const PropsType* pProps = itr->second;
     150         [ #  # ]:          0 :             PropsType::const_iterator itr2 = pProps->find(rPropName);
     151 [ #  # ][ #  # ]:          0 :             if (itr2 != pProps->end())
     152         [ #  # ]:          0 :                 return itr2->second;
     153                 :            :         }
     154                 :            :     }
     155                 :            :     // As the last resort, look into the element global storage.
     156                 :            :     {
     157         [ #  # ]:          0 :         NamePropsType::const_iterator itr = maElemGlobalProps.find(rClass);
     158 [ #  # ][ #  # ]:          0 :         if (itr != maElemGlobalProps.end())
                 [ #  # ]
     159                 :            :         {
     160         [ #  # ]:          0 :             const PropsType* pProps = itr->second;
     161         [ #  # ]:          0 :             PropsType::const_iterator itr2 = pProps->find(rPropName);
     162 [ #  # ][ #  # ]:          0 :             if (itr2 != pProps->end())
     163         [ #  # ]:          0 :                 return itr2->second;
     164                 :            :         }
     165                 :            :     }
     166                 :            : 
     167                 :          0 :     return maEmpty; // nothing found.
     168                 :            : }
     169                 :            : 
     170                 :          0 : void ScHTMLStyles::insertProp(
     171                 :            :     NamePropsType& rStore, const rtl::OUString& aName,
     172                 :            :     const rtl::OUString& aProp, const rtl::OUString& aValue)
     173                 :            : {
     174         [ #  # ]:          0 :     NamePropsType::iterator itr = rStore.find(aName);
     175 [ #  # ][ #  # ]:          0 :     if (itr == rStore.end())
                 [ #  # ]
     176                 :            :     {
     177                 :            :         // new element
     178                 :            :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
     179 [ #  # ][ #  # ]:          0 :         std::auto_ptr<PropsType> p(new PropsType);
     180                 :            :         SAL_WNODEPRECATED_DECLARATIONS_POP
     181 [ #  # ][ #  # ]:          0 :         std::pair<NamePropsType::iterator, bool> r = rStore.insert(aName, p);
     182         [ #  # ]:          0 :         if (!r.second)
     183                 :            :             // insertion failed.
     184                 :          0 :             return;
     185                 :            : 
     186 [ #  # ][ #  # ]:          0 :         itr = r.first;
     187                 :            :     }
     188                 :            : 
     189         [ #  # ]:          0 :     PropsType* pProps = itr->second;
     190         [ #  # ]:          0 :     pProps->insert(PropsType::value_type(aProp, aValue));
     191                 :            : }
     192                 :            : 
     193                 :            : // ============================================================================
     194                 :            : // BASE class for HTML parser classes
     195                 :            : // ============================================================================
     196                 :            : 
     197                 :          3 : ScHTMLParser::ScHTMLParser( EditEngine* pEditEngine, ScDocument* pDoc ) :
     198                 :            :     ScEEParser( pEditEngine ),
     199         [ +  - ]:          3 :     mpDoc( pDoc )
     200                 :            : {
     201         [ +  - ]:          3 :     SvxHtmlOptions& rHtmlOptions = SvxHtmlOptions::Get();
     202         [ +  + ]:         24 :     for( sal_uInt16 nIndex = 0; nIndex < SC_HTML_FONTSIZES; ++nIndex )
     203         [ +  - ]:         21 :         maFontHeights[ nIndex ] = rHtmlOptions.GetFontSize( nIndex ) * 20;
     204                 :          3 : }
     205                 :            : 
     206         [ +  - ]:          3 : ScHTMLParser::~ScHTMLParser()
     207                 :            : {
     208         [ -  + ]:          3 : }
     209                 :            : 
     210                 :          0 : ScHTMLStyles& ScHTMLParser::GetStyles()
     211                 :            : {
     212                 :          0 :     return maStyles;
     213                 :            : }
     214                 :            : 
     215                 :          0 : ScDocument& ScHTMLParser::GetDoc()
     216                 :            : {
     217                 :          0 :     return *mpDoc;
     218                 :            : }
     219                 :            : 
     220                 :            : // ============================================================================
     221                 :            : 
     222                 :          0 : ScHTMLLayoutParser::ScHTMLLayoutParser(
     223                 :            :     EditEngine* pEditP, const String& rBaseURL, const Size& aPageSizeP,
     224                 :            :     ScDocument* pDocP ) :
     225                 :            :         ScHTMLParser( pEditP, pDocP ),
     226                 :            :         aPageSize( aPageSizeP ),
     227                 :            :         aBaseURL( rBaseURL ),
     228         [ #  # ]:          0 :         xLockedList( new ScRangeList ),
     229                 :            :         pTables( NULL ),
     230         [ #  # ]:          0 :         pColOffset( new ScHTMLColOffset ),
     231         [ #  # ]:          0 :         pLocalColOffset( new ScHTMLColOffset ),
     232                 :            :         nFirstTableCell(0),
     233                 :            :         nTableLevel(0),
     234                 :            :         nTable(0),
     235                 :            :         nMaxTable(0),
     236                 :            :         nColCntStart(0),
     237                 :            :         nMaxCol(0),
     238                 :            :         nTableWidth(0),
     239                 :            :         nColOffset(0),
     240                 :            :         nColOffsetStart(0),
     241                 :            :         nMetaCnt(0),
     242                 :            :         nOffsetTolerance( SC_HTML_OFFSET_TOLERANCE_SMALL ),
     243                 :            :         bTabInTabCell( false ),
     244                 :            :         bFirstRow( true ),
     245                 :            :         bInCell( false ),
     246 [ #  # ][ #  # ]:          0 :         bInTitle( false )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     247                 :            : {
     248         [ #  # ]:          0 :     MakeColNoRef( pLocalColOffset, 0, 0, 0, 0 );
     249         [ #  # ]:          0 :     MakeColNoRef( pColOffset, 0, 0, 0, 0 );
     250                 :          0 : }
     251                 :            : 
     252                 :            : 
     253         [ #  # ]:          0 : ScHTMLLayoutParser::~ScHTMLLayoutParser()
     254                 :            : {
     255         [ #  # ]:          0 :     while ( !aTableStack.empty() )
     256                 :            :     {
     257         [ #  # ]:          0 :         ScHTMLTableStackEntry* pS = aTableStack.top();
     258         [ #  # ]:          0 :         aTableStack.pop();
     259                 :            : 
     260                 :          0 :         bool found = false;
     261         [ #  # ]:          0 :         for ( size_t i = 0, nListSize = maList.size(); i < nListSize; ++i )
     262                 :            :         {
     263         [ #  # ]:          0 :             if ( pS->pCellEntry == maList[ i ] )
     264                 :            :             {
     265                 :          0 :                 found = true;
     266                 :          0 :                 break;
     267                 :            :             }
     268                 :            :         }
     269         [ #  # ]:          0 :         if ( !found )
     270 [ #  # ][ #  # ]:          0 :             delete pS->pCellEntry;
     271         [ #  # ]:          0 :         if ( pS->pLocalColOffset != pLocalColOffset )
     272         [ #  # ]:          0 :             delete pS->pLocalColOffset;
     273 [ #  # ][ #  # ]:          0 :         delete pS;
     274                 :            :     }
     275         [ #  # ]:          0 :     if ( pLocalColOffset )
     276         [ #  # ]:          0 :         delete pLocalColOffset;
     277         [ #  # ]:          0 :     if ( pColOffset )
     278         [ #  # ]:          0 :         delete pColOffset;
     279         [ #  # ]:          0 :     if ( pTables )
     280                 :            :     {
     281 [ #  # ][ #  # ]:          0 :         for( OuterMap::const_iterator it = pTables->begin(); it != pTables->end(); ++it)
         [ #  # ][ #  # ]
                 [ #  # ]
     282 [ #  # ][ #  # ]:          0 :             delete it->second;
     283         [ #  # ]:          0 :         delete pTables;
     284                 :            :     }
     285         [ #  # ]:          0 : }
     286                 :            : 
     287                 :            : 
     288                 :          0 : sal_uLong ScHTMLLayoutParser::Read( SvStream& rStream, const String& rBaseURL )
     289                 :            : {
     290         [ #  # ]:          0 :     Link aOldLink = pEdit->GetImportHdl();
     291 [ #  # ][ #  # ]:          0 :     pEdit->SetImportHdl( LINK( this, ScHTMLLayoutParser, HTMLImportHdl ) );
     292                 :            : 
     293                 :          0 :     SfxObjectShell* pObjSh = mpDoc->GetDocumentShell();
     294 [ #  # ][ #  # ]:          0 :     bool bLoading = pObjSh && pObjSh->IsLoading();
                 [ #  # ]
     295                 :            : 
     296                 :          0 :     SvKeyValueIteratorRef xValues;
     297                 :          0 :     SvKeyValueIterator* pAttributes = NULL;
     298         [ #  # ]:          0 :     if ( bLoading )
     299         [ #  # ]:          0 :         pAttributes = pObjSh->GetHeaderAttributes();
     300                 :            :     else
     301                 :            :     {
     302                 :            :         //  When not loading, set up fake http headers to force the SfxHTMLParser to use UTF8
     303                 :            :         //  (used when pasting from clipboard)
     304                 :            : 
     305         [ #  # ]:          0 :         const sal_Char* pCharSet = rtl_getBestMimeCharsetFromTextEncoding( RTL_TEXTENCODING_UTF8 );
     306         [ #  # ]:          0 :         if( pCharSet )
     307                 :            :         {
     308         [ #  # ]:          0 :             String aContentType = rtl::OUString( "text/html; charset=" );
     309         [ #  # ]:          0 :             aContentType.AppendAscii( pCharSet );
     310                 :            : 
     311 [ #  # ][ #  # ]:          0 :             xValues = new SvKeyValueIterator;
                 [ #  # ]
     312 [ #  # ][ #  # ]:          0 :             xValues->Append( SvKeyValue( rtl::OUString( OOO_STRING_SVTOOLS_HTML_META_content_type ), aContentType ) );
         [ #  # ][ #  # ]
                 [ #  # ]
     313         [ #  # ]:          0 :             pAttributes = xValues;
     314                 :            :         }
     315                 :            :     }
     316                 :            : 
     317         [ #  # ]:          0 :     sal_uLong nErr = pEdit->Read( rStream, rBaseURL, EE_FORMAT_HTML, pAttributes );
     318                 :            : 
     319         [ #  # ]:          0 :     pEdit->SetImportHdl( aOldLink );
     320                 :            :     // Spaltenbreiten erzeugen
     321         [ #  # ]:          0 :     Adjust();
     322         [ #  # ]:          0 :     OutputDevice* pDefaultDev = Application::GetDefaultDevice();
     323                 :          0 :     sal_uInt16 nCount = pColOffset->size();
     324         [ #  # ]:          0 :     sal_uLong nOff = (*pColOffset)[0];
     325                 :          0 :     Size aSize;
     326         [ #  # ]:          0 :     for ( sal_uInt16 j = 1; j < nCount; j++ )
     327                 :            :     {
     328         [ #  # ]:          0 :         aSize.Width() = (*pColOffset)[j] - nOff;
     329 [ #  # ][ #  # ]:          0 :         aSize = pDefaultDev->PixelToLogic( aSize, MapMode( MAP_TWIP ) );
                 [ #  # ]
     330         [ #  # ]:          0 :         maColWidths[ j-1 ] = aSize.Width();
     331         [ #  # ]:          0 :         nOff = (*pColOffset)[j];
     332                 :            :     }
     333         [ #  # ]:          0 :     return nErr;
     334                 :            : }
     335                 :            : 
     336                 :            : 
     337                 :          0 : const ScHTMLTable* ScHTMLLayoutParser::GetGlobalTable() const
     338                 :            : {
     339                 :          0 :     return 0;
     340                 :            : }
     341                 :            : 
     342                 :            : 
     343                 :          0 : void ScHTMLLayoutParser::NewActEntry( ScEEParseEntry* pE )
     344                 :            : {
     345                 :          0 :     ScEEParser::NewActEntry( pE );
     346         [ #  # ]:          0 :     if ( pE )
     347                 :            :     {
     348         [ #  # ]:          0 :         if ( !pE->aSel.HasRange() )
     349                 :            :         {   // komplett leer, nachfolgender Text landet im gleichen Absatz!
     350                 :          0 :             pActEntry->aSel.nStartPara = pE->aSel.nEndPara;
     351                 :          0 :             pActEntry->aSel.nStartPos = pE->aSel.nEndPos;
     352                 :            :         }
     353                 :            :     }
     354                 :          0 :     pActEntry->aSel.nEndPara = pActEntry->aSel.nStartPara;
     355                 :          0 :     pActEntry->aSel.nEndPos = pActEntry->aSel.nStartPos;
     356                 :          0 : }
     357                 :            : 
     358                 :            : 
     359                 :          0 : void ScHTMLLayoutParser::EntryEnd( ScEEParseEntry* pE, const ESelection& rSel )
     360                 :            : {
     361         [ #  # ]:          0 :     if ( rSel.nEndPara >= pE->aSel.nStartPara )
     362                 :            :     {
     363                 :          0 :         pE->aSel.nEndPara = rSel.nEndPara;
     364                 :          0 :         pE->aSel.nEndPos = rSel.nEndPos;
     365                 :            :     }
     366 [ #  # ][ #  # ]:          0 :     else if ( rSel.nStartPara == pE->aSel.nStartPara - 1 && !pE->aSel.HasRange() )
     367                 :            :     {   // kein Absatz angehaengt aber leer, nichts tun
     368                 :            :     }
     369                 :            :     else
     370                 :            :     {
     371                 :            :         OSL_FAIL( "EntryEnd: EditEngine ESelection End < Start" );
     372                 :            :     }
     373                 :          0 : }
     374                 :            : 
     375                 :            : 
     376                 :          0 : void ScHTMLLayoutParser::NextRow( ImportInfo* pInfo )
     377                 :            : {
     378         [ #  # ]:          0 :     if ( bInCell )
     379                 :          0 :         CloseEntry( pInfo );
     380         [ #  # ]:          0 :     if ( nRowMax < ++nRowCnt )
     381                 :          0 :         nRowMax = nRowCnt;
     382                 :          0 :     nColCnt = nColCntStart;
     383                 :          0 :     nColOffset = nColOffsetStart;
     384                 :          0 :     bFirstRow = false;
     385                 :          0 : }
     386                 :            : 
     387                 :            : 
     388                 :          0 : bool ScHTMLLayoutParser::SeekOffset( ScHTMLColOffset* pOffset, sal_uInt16 nOffset,
     389                 :            :         SCCOL* pCol, sal_uInt16 nOffsetTol )
     390                 :            : {
     391                 :            :     OSL_ENSURE( pOffset, "ScHTMLLayoutParser::SeekOffset - illegal call" );
     392         [ #  # ]:          0 :     ScHTMLColOffset::const_iterator it = pOffset->find( nOffset );
     393         [ #  # ]:          0 :     bool bFound = it != pOffset->end();
     394         [ #  # ]:          0 :     sal_uInt16 nPos = it - pOffset->end();
     395                 :          0 :     *pCol = static_cast<SCCOL>(nPos);
     396         [ #  # ]:          0 :     if ( bFound )
     397                 :          0 :         return true;
     398                 :          0 :     sal_uInt16 nCount = pOffset->size();
     399         [ #  # ]:          0 :     if ( !nCount )
     400                 :          0 :         return false;
     401                 :            :     // nPos ist Einfuegeposition, da liegt der Naechsthoehere (oder auch nicht)
     402 [ #  # ][ #  # ]:          0 :     if ( nPos < nCount && (((*pOffset)[nPos] - nOffsetTol) <= nOffset) )
         [ #  # ][ #  # ]
     403                 :          0 :         return true;
     404                 :            :     // nicht kleiner als alles andere? dann mit Naechstniedrigerem vergleichen
     405 [ #  # ][ #  # ]:          0 :     else if ( nPos && (((*pOffset)[nPos-1] + nOffsetTol) >= nOffset) )
         [ #  # ][ #  # ]
     406                 :            :     {
     407                 :          0 :         (*pCol)--;
     408                 :          0 :         return true;
     409                 :            :     }
     410                 :          0 :     return false;
     411                 :            : }
     412                 :            : 
     413                 :            : 
     414                 :          0 : void ScHTMLLayoutParser::MakeCol( ScHTMLColOffset* pOffset, sal_uInt16& nOffset,
     415                 :            :         sal_uInt16& nWidth, sal_uInt16 nOffsetTol, sal_uInt16 nWidthTol )
     416                 :            : {
     417                 :            :     OSL_ENSURE( pOffset, "ScHTMLLayoutParser::MakeCol - illegal call" );
     418                 :            :     SCCOL nPos;
     419 [ #  # ][ #  # ]:          0 :     if ( SeekOffset( pOffset, nOffset, &nPos, nOffsetTol ) )
     420         [ #  # ]:          0 :         nOffset = (sal_uInt16)(*pOffset)[nPos];
     421                 :            :     else
     422         [ #  # ]:          0 :         pOffset->insert( nOffset );
     423         [ #  # ]:          0 :     if ( nWidth )
     424                 :            :     {
     425 [ #  # ][ #  # ]:          0 :         if ( SeekOffset( pOffset, nOffset + nWidth, &nPos, nWidthTol ) )
     426         [ #  # ]:          0 :             nWidth = (sal_uInt16)(*pOffset)[nPos] - nOffset;
     427                 :            :         else
     428         [ #  # ]:          0 :             pOffset->insert( nOffset + nWidth );
     429                 :            :     }
     430                 :          0 : }
     431                 :            : 
     432                 :            : 
     433                 :          0 : void ScHTMLLayoutParser::MakeColNoRef( ScHTMLColOffset* pOffset, sal_uInt16 nOffset,
     434                 :            :         sal_uInt16 nWidth, sal_uInt16 nOffsetTol, sal_uInt16 nWidthTol )
     435                 :            : {
     436                 :            :     OSL_ENSURE( pOffset, "ScHTMLLayoutParser::MakeColNoRef - illegal call" );
     437                 :            :     SCCOL nPos;
     438 [ #  # ][ #  # ]:          0 :     if ( SeekOffset( pOffset, nOffset, &nPos, nOffsetTol ) )
     439         [ #  # ]:          0 :         nOffset = (sal_uInt16)(*pOffset)[nPos];
     440                 :            :     else
     441         [ #  # ]:          0 :         pOffset->insert( nOffset );
     442         [ #  # ]:          0 :     if ( nWidth )
     443                 :            :     {
     444 [ #  # ][ #  # ]:          0 :         if ( !SeekOffset( pOffset, nOffset + nWidth, &nPos, nWidthTol ) )
     445         [ #  # ]:          0 :             pOffset->insert( nOffset + nWidth );
     446                 :            :     }
     447                 :          0 : }
     448                 :            : 
     449                 :            : 
     450                 :          0 : void ScHTMLLayoutParser::ModifyOffset( ScHTMLColOffset* pOffset, sal_uInt16& nOldOffset,
     451                 :            :             sal_uInt16& nNewOffset, sal_uInt16 nOffsetTol )
     452                 :            : {
     453                 :            :     OSL_ENSURE( pOffset, "ScHTMLLayoutParser::ModifyOffset - illegal call" );
     454                 :            :     SCCOL nPos;
     455 [ #  # ][ #  # ]:          0 :     if ( !SeekOffset( pOffset, nOldOffset, &nPos, nOffsetTol ) )
     456                 :            :     {
     457 [ #  # ][ #  # ]:          0 :         if ( SeekOffset( pOffset, nNewOffset, &nPos, nOffsetTol ) )
     458         [ #  # ]:          0 :             nNewOffset = (sal_uInt16)(*pOffset)[nPos];
     459                 :            :         else
     460         [ #  # ]:          0 :             pOffset->insert( nNewOffset );
     461                 :            :         return ;
     462                 :            :     }
     463         [ #  # ]:          0 :     nOldOffset = (sal_uInt16)(*pOffset)[nPos];
     464                 :            :     SCCOL nPos2;
     465 [ #  # ][ #  # ]:          0 :     if ( SeekOffset( pOffset, nNewOffset, &nPos2, nOffsetTol ) )
     466                 :            :     {
     467         [ #  # ]:          0 :         nNewOffset = (sal_uInt16)(*pOffset)[nPos2];
     468                 :            :         return ;
     469                 :            :     }
     470                 :          0 :     long nDiff = nNewOffset - nOldOffset;
     471         [ #  # ]:          0 :     if ( nDiff < 0 )
     472                 :            :     {
     473         [ #  # ]:          0 :         do
     474                 :            :         {
     475         [ #  # ]:          0 :             const_cast<sal_uLong&>((*pOffset)[nPos]) += nDiff;
     476                 :            :         } while ( nPos-- );
     477                 :            :     }
     478                 :            :     else
     479                 :            :     {
     480         [ #  # ]:          0 :         do
     481                 :            :         {
     482         [ #  # ]:          0 :             const_cast<sal_uLong&>((*pOffset)[nPos]) += nDiff;
     483                 :          0 :         } while ( ++nPos < (sal_uInt16)pOffset->size() );
     484                 :            :     }
     485                 :            : }
     486                 :            : 
     487                 :            : 
     488                 :          0 : void ScHTMLLayoutParser::SkipLocked( ScEEParseEntry* pE, bool bJoin )
     489                 :            : {
     490         [ #  # ]:          0 :     if ( ValidCol(pE->nCol) )
     491                 :            :     {   // wuerde sonst bei ScAddress falschen Wert erzeugen, evtl. Endlosschleife!
     492                 :          0 :         bool bBadCol = false;
     493                 :            :         bool bAgain;
     494                 :            :         ScRange aRange( pE->nCol, pE->nRow, 0,
     495                 :          0 :             pE->nCol + pE->nColOverlap - 1, pE->nRow + pE->nRowOverlap - 1, 0 );
     496         [ #  # ]:          0 :         do
     497                 :            :         {
     498                 :          0 :             bAgain = false;
     499 [ #  # ][ #  # ]:          0 :             for ( size_t i =  0, nRanges = xLockedList->size(); i < nRanges; ++i )
     500                 :            :             {
     501         [ #  # ]:          0 :                 ScRange* pR = (*xLockedList)[i];
     502 [ #  # ][ #  # ]:          0 :                 if ( pR->Intersects( aRange ) )
     503                 :            :                 {
     504                 :          0 :                     pE->nCol = pR->aEnd.Col() + 1;
     505                 :          0 :                     SCCOL nTmp = pE->nCol + pE->nColOverlap - 1;
     506 [ #  # ][ #  # ]:          0 :                     if ( pE->nCol > MAXCOL || nTmp > MAXCOL )
     507                 :          0 :                         bBadCol = true;
     508                 :            :                     else
     509                 :            :                     {
     510                 :          0 :                         bAgain = true;
     511                 :          0 :                         aRange.aStart.SetCol( pE->nCol );
     512                 :          0 :                         aRange.aEnd.SetCol( nTmp );
     513                 :            :                     }
     514                 :          0 :                     break;
     515                 :            :                 }
     516                 :            :             }
     517                 :            :         } while ( bAgain );
     518 [ #  # ][ #  # ]:          0 :         if ( bJoin && !bBadCol )
     519         [ #  # ]:          0 :             xLockedList->Join( aRange );
     520                 :            :     }
     521                 :          0 : }
     522                 :            : 
     523                 :            : 
     524                 :          0 : void ScHTMLLayoutParser::Adjust()
     525                 :            : {
     526         [ #  # ]:          0 :     xLockedList->RemoveAll();
     527                 :            : 
     528 [ #  # ][ #  # ]:          0 :     ScHTMLAdjustStack aStack;
     529                 :          0 :     ScHTMLAdjustStackEntry* pS = NULL;
     530                 :          0 :     sal_uInt16 nTab = 0;
     531                 :          0 :     SCCOL nLastCol = SCCOL_MAX;
     532                 :          0 :     SCROW nNextRow = 0;
     533                 :          0 :     SCROW nCurRow = 0;
     534                 :          0 :     sal_uInt16 nPageWidth = (sal_uInt16) aPageSize.Width();
     535                 :          0 :     InnerMap* pTab = NULL;
     536         [ #  # ]:          0 :     for ( size_t i = 0, nListSize = maList.size(); i < nListSize; ++i )
     537                 :            :     {
     538                 :          0 :         ScEEParseEntry* pE = maList[ i ];
     539         [ #  # ]:          0 :         if ( pE->nTab < nTab )
     540                 :            :         {   // Table beendet
     541         [ #  # ]:          0 :             if ( !aStack.empty() )
     542                 :            :             {
     543         [ #  # ]:          0 :                 pS = aStack.top();
     544         [ #  # ]:          0 :                 aStack.pop();
     545                 :            : 
     546                 :          0 :                 nLastCol = pS->nLastCol;
     547                 :          0 :                 nNextRow = pS->nNextRow;
     548                 :          0 :                 nCurRow = pS->nCurRow;
     549                 :            :             }
     550                 :          0 :             delete pS;
     551                 :          0 :             pS = NULL;
     552                 :          0 :             nTab = pE->nTab;
     553         [ #  # ]:          0 :             if (pTables)
     554                 :            :             {
     555 [ #  # ][ #  # ]:          0 :                 OuterMap::const_iterator it = pTables->find( nTab );
     556 [ #  # ][ #  # ]:          0 :                 if ( it != pTables->end() )
                 [ #  # ]
     557         [ #  # ]:          0 :                     pTab = it->second;
     558                 :            :             }
     559                 :            : 
     560                 :            :         }
     561                 :          0 :         SCROW nRow = pE->nRow;
     562         [ #  # ]:          0 :         if ( pE->nCol <= nLastCol )
     563                 :            :         {   // naechste Zeile
     564         [ #  # ]:          0 :             if ( pE->nRow < nNextRow )
     565                 :          0 :                 pE->nRow = nCurRow = nNextRow;
     566                 :            :             else
     567                 :          0 :                 nCurRow = nNextRow = pE->nRow;
     568                 :          0 :             SCROW nR = 0;
     569         [ #  # ]:          0 :             if ( pTab )
     570                 :            :             {
     571 [ #  # ][ #  # ]:          0 :                 InnerMap::const_iterator it = pTab->find( nCurRow );
     572 [ #  # ][ #  # ]:          0 :                 if ( it != pTab->end() )
                 [ #  # ]
     573         [ #  # ]:          0 :                     nR = it->second;
     574                 :            :             }
     575         [ #  # ]:          0 :             if ( nR )
     576                 :          0 :                 nNextRow += nR;
     577                 :            :             else
     578                 :          0 :                 nNextRow++;
     579                 :            :         }
     580                 :            :         else
     581                 :          0 :             pE->nRow = nCurRow;
     582                 :          0 :         nLastCol = pE->nCol;    // eingelesene Col
     583         [ #  # ]:          0 :         if ( pE->nTab > nTab )
     584                 :            :         {   // neue Table
     585                 :            :             aStack.push( new ScHTMLAdjustStackEntry(
     586 [ #  # ][ #  # ]:          0 :                 nLastCol, nNextRow, nCurRow ) );
     587                 :          0 :             nTab = pE->nTab;
     588         [ #  # ]:          0 :             if ( pTables )
     589                 :            :             {
     590 [ #  # ][ #  # ]:          0 :                 OuterMap::const_iterator it = pTables->find( nTab );
     591 [ #  # ][ #  # ]:          0 :                 if ( it != pTables->end() )
                 [ #  # ]
     592         [ #  # ]:          0 :                     pTab = it->second;
     593                 :            :             }
     594                 :            :             // neuer Zeilenabstand
     595                 :          0 :             SCROW nR = 0;
     596         [ #  # ]:          0 :             if ( pTab )
     597                 :            :             {
     598 [ #  # ][ #  # ]:          0 :                 InnerMap::const_iterator it = pTab->find( nCurRow );
     599 [ #  # ][ #  # ]:          0 :                 if ( it != pTab->end() )
                 [ #  # ]
     600         [ #  # ]:          0 :                     nR = it->second;
     601                 :            :             }
     602         [ #  # ]:          0 :             if ( nR )
     603                 :          0 :                 nNextRow = nCurRow + nR;
     604                 :            :             else
     605                 :          0 :                 nNextRow = nCurRow + 1;
     606                 :            :         }
     607         [ #  # ]:          0 :         if ( nTab == 0 )
     608                 :          0 :             pE->nWidth = nPageWidth;
     609                 :            :         else
     610                 :            :         {   // echte Table, keine Absaetze auf der Wiese
     611         [ #  # ]:          0 :             if ( pTab )
     612                 :            :             {
     613                 :          0 :                 SCROW nRowSpan = pE->nRowOverlap;
     614         [ #  # ]:          0 :                 for ( SCROW j=0; j < nRowSpan; j++ )
     615                 :            :                 {   // aus merged Zeilen resultierendes RowSpan
     616                 :          0 :                     SCROW nRows = 0;
     617 [ #  # ][ #  # ]:          0 :                     InnerMap::const_iterator it = pTab->find( nRow+j );
     618 [ #  # ][ #  # ]:          0 :                     if ( it != pTab->end() )
                 [ #  # ]
     619         [ #  # ]:          0 :                         nRows = it->second;
     620         [ #  # ]:          0 :                     if ( nRows > 1 )
     621                 :            :                     {
     622                 :          0 :                         pE->nRowOverlap += nRows - 1;
     623         [ #  # ]:          0 :                         if ( j == 0 )
     624                 :            :                         {   // merged Zeilen verschieben die naechste Zeile
     625                 :          0 :                             SCROW nTmp = nCurRow + nRows;
     626         [ #  # ]:          0 :                             if ( nNextRow < nTmp )
     627                 :          0 :                                 nNextRow = nTmp;
     628                 :            :                         }
     629                 :            :                     }
     630                 :            :                 }
     631                 :            :             }
     632                 :            :         }
     633                 :            :         // echte Col
     634         [ #  # ]:          0 :         SeekOffset( pColOffset, pE->nOffset, &pE->nCol, nOffsetTolerance );
     635                 :          0 :         SCCOL nColBeforeSkip = pE->nCol;
     636         [ #  # ]:          0 :         SkipLocked( pE, false );
     637         [ #  # ]:          0 :         if ( pE->nCol != nColBeforeSkip )
     638                 :            :         {
     639                 :          0 :             SCCOL nCount = (SCCOL)pColOffset->size();
     640         [ #  # ]:          0 :             if ( nCount <= pE->nCol )
     641                 :            :             {
     642         [ #  # ]:          0 :                 pE->nOffset = (sal_uInt16) (*pColOffset)[nCount-1];
     643         [ #  # ]:          0 :                 MakeCol( pColOffset, pE->nOffset, pE->nWidth, nOffsetTolerance, nOffsetTolerance );
     644                 :            :             }
     645                 :            :             else
     646                 :            :             {
     647         [ #  # ]:          0 :                 pE->nOffset = (sal_uInt16) (*pColOffset)[pE->nCol];
     648                 :            :             }
     649                 :            :         }
     650                 :            :         SCCOL nPos;
     651 [ #  # ][ #  # ]:          0 :         if ( pE->nWidth && SeekOffset( pColOffset, pE->nOffset + pE->nWidth, &nPos, nOffsetTolerance ) )
         [ #  # ][ #  # ]
     652         [ #  # ]:          0 :             pE->nColOverlap = (nPos > pE->nCol ? nPos - pE->nCol : 1);
     653                 :            :         else
     654                 :            :         {
     655                 :            : //2do: das muss nicht korrekt sein, ist aber..
     656                 :          0 :             pE->nColOverlap = 1;
     657                 :            :         }
     658                 :            :         xLockedList->Join( ScRange( pE->nCol, pE->nRow, 0,
     659         [ #  # ]:          0 :             pE->nCol + pE->nColOverlap - 1, pE->nRow + pE->nRowOverlap - 1, 0 ) );
     660                 :            :         // MaxDimensions mitfuehren
     661                 :          0 :         SCCOL nColTmp = pE->nCol + pE->nColOverlap;
     662         [ #  # ]:          0 :         if ( nColMax < nColTmp )
     663                 :          0 :             nColMax = nColTmp;
     664                 :          0 :         SCROW nRowTmp = pE->nRow + pE->nRowOverlap;
     665         [ #  # ]:          0 :         if ( nRowMax < nRowTmp )
     666                 :          0 :             nRowMax = nRowTmp;
     667                 :            :     }
     668         [ #  # ]:          0 :     while ( !aStack.empty() )
     669                 :            :     {
     670         [ #  # ]:          0 :         delete aStack.top();
     671         [ #  # ]:          0 :         aStack.pop();
     672                 :          0 :     }
     673                 :          0 : }
     674                 :            : 
     675                 :            : 
     676                 :          0 : sal_uInt16 ScHTMLLayoutParser::GetWidth( ScEEParseEntry* pE )
     677                 :            : {
     678         [ #  # ]:          0 :     if ( pE->nWidth )
     679                 :          0 :         return pE->nWidth;
     680                 :            :     sal_Int32 nTmp = ::std::min( static_cast<sal_Int32>( pE->nCol -
     681                 :            :                 nColCntStart + pE->nColOverlap),
     682         [ #  # ]:          0 :             static_cast<sal_Int32>( pLocalColOffset->size() - 1));
     683         [ #  # ]:          0 :     SCCOL nPos = (nTmp < 0 ? 0 : static_cast<SCCOL>(nTmp));
     684                 :          0 :     sal_uInt16 nOff2 = (sal_uInt16) (*pLocalColOffset)[nPos];
     685         [ #  # ]:          0 :     if ( pE->nOffset < nOff2 )
     686                 :          0 :         return nOff2 - pE->nOffset;
     687                 :          0 :     return 0;
     688                 :            : }
     689                 :            : 
     690                 :            : 
     691                 :          0 : void ScHTMLLayoutParser::SetWidths()
     692                 :            : {
     693                 :            :     ScEEParseEntry* pE;
     694                 :            :     SCCOL nCol;
     695         [ #  # ]:          0 :     if ( !nTableWidth )
     696                 :          0 :         nTableWidth = (sal_uInt16) aPageSize.Width();
     697                 :          0 :     SCCOL nColsPerRow = nMaxCol - nColCntStart;
     698         [ #  # ]:          0 :     if ( nColsPerRow <= 0 )
     699                 :          0 :         nColsPerRow = 1;
     700         [ #  # ]:          0 :     if ( pLocalColOffset->size() <= 2 )
     701                 :            :     {   // nur PageSize, es gab keine Width-Angabe
     702                 :          0 :         sal_uInt16 nWidth = nTableWidth / static_cast<sal_uInt16>(nColsPerRow);
     703                 :          0 :         sal_uInt16 nOff = nColOffsetStart;
     704                 :          0 :         pLocalColOffset->clear();
     705         [ #  # ]:          0 :         for ( nCol = 0; nCol <= nColsPerRow; ++nCol, nOff = nOff + nWidth )
     706                 :            :         {
     707                 :          0 :             MakeColNoRef( pLocalColOffset, nOff, 0, 0, 0 );
     708                 :            :         }
     709                 :          0 :         nTableWidth = (sal_uInt16)(pLocalColOffset->back() - pLocalColOffset->front());
     710         [ #  # ]:          0 :         for ( size_t i = nFirstTableCell, nListSize = maList.size(); i < nListSize; ++i )
     711                 :            :         {
     712                 :          0 :             pE = maList[ i ];
     713         [ #  # ]:          0 :             if ( pE->nTab == nTable )
     714                 :            :             {
     715                 :          0 :                 pE->nOffset = (sal_uInt16) (*pLocalColOffset)[pE->nCol - nColCntStart];
     716                 :          0 :                 pE->nWidth = 0;     // to be recalculated later
     717                 :            :             }
     718                 :            :         }
     719                 :            :     }
     720                 :            :     else
     721                 :            :     {   // einige mit einige ohne Width
     722                 :            :         // wieso eigentlich kein pE ?!?
     723         [ #  # ]:          0 :         if ( nFirstTableCell < maList.size() )
     724                 :            :         {
     725                 :          0 :             sal_uInt16* pOffsets = new sal_uInt16[ nColsPerRow+1 ];
     726                 :          0 :             memset( pOffsets, 0, (nColsPerRow+1) * sizeof(sal_uInt16) );
     727                 :          0 :             sal_uInt16* pWidths = new sal_uInt16[ nColsPerRow ];
     728                 :          0 :             memset( pWidths, 0, nColsPerRow * sizeof(sal_uInt16) );
     729                 :          0 :             pOffsets[0] = nColOffsetStart;
     730         [ #  # ]:          0 :             for ( size_t i = nFirstTableCell, nListSize = maList.size(); i < nListSize; ++i )
     731                 :            :             {
     732                 :          0 :                 pE = maList[ i ];
     733 [ #  # ][ #  # ]:          0 :                 if ( pE->nTab == nTable && pE->nWidth )
     734                 :            :                 {
     735                 :          0 :                     nCol = pE->nCol - nColCntStart;
     736         [ #  # ]:          0 :                     if ( nCol < nColsPerRow )
     737                 :            :                     {
     738         [ #  # ]:          0 :                         if ( pE->nColOverlap == 1 )
     739                 :            :                         {
     740         [ #  # ]:          0 :                             if ( pWidths[nCol] < pE->nWidth )
     741                 :          0 :                                 pWidths[nCol] = pE->nWidth;
     742                 :            :                         }
     743                 :            :                         else
     744                 :            :                         {   // try to find a single undefined width
     745                 :          0 :                             sal_uInt16 nTotal = 0;
     746                 :          0 :                             bool bFound = false;
     747                 :          0 :                             SCCOL nHere = 0;
     748                 :          0 :                             SCCOL nStop = Min( static_cast<SCCOL>(nCol + pE->nColOverlap), nColsPerRow );
     749         [ #  # ]:          0 :                             for ( ; nCol < nStop; nCol++ )
     750                 :            :                             {
     751         [ #  # ]:          0 :                                 if ( pWidths[nCol] )
     752                 :          0 :                                     nTotal = nTotal + pWidths[nCol];
     753                 :            :                                 else
     754                 :            :                                 {
     755         [ #  # ]:          0 :                                     if ( bFound )
     756                 :            :                                     {
     757                 :          0 :                                         bFound = false;
     758                 :          0 :                                         break;  // for
     759                 :            :                                     }
     760                 :          0 :                                     bFound = true;
     761                 :          0 :                                     nHere = nCol;
     762                 :            :                                 }
     763                 :            :                             }
     764 [ #  # ][ #  # ]:          0 :                             if ( bFound && pE->nWidth > nTotal )
     765                 :          0 :                                 pWidths[nHere] = pE->nWidth - nTotal;
     766                 :            :                         }
     767                 :            :                     }
     768                 :            :                 }
     769                 :            :             }
     770                 :          0 :             sal_uInt16 nWidths = 0;
     771                 :          0 :             sal_uInt16 nUnknown = 0;
     772         [ #  # ]:          0 :             for ( nCol = 0; nCol < nColsPerRow; nCol++ )
     773                 :            :             {
     774         [ #  # ]:          0 :                 if ( pWidths[nCol] )
     775                 :          0 :                     nWidths = nWidths + pWidths[nCol];
     776                 :            :                 else
     777                 :          0 :                     nUnknown++;
     778                 :            :             }
     779         [ #  # ]:          0 :             if ( nUnknown )
     780                 :            :             {
     781                 :            :                 sal_uInt16 nW = ((nWidths < nTableWidth) ?
     782                 :            :                     ((nTableWidth - nWidths) / nUnknown) :
     783         [ #  # ]:          0 :                     (nTableWidth / nUnknown));
     784         [ #  # ]:          0 :                 for ( nCol = 0; nCol < nColsPerRow; nCol++ )
     785                 :            :                 {
     786         [ #  # ]:          0 :                     if ( !pWidths[nCol] )
     787                 :          0 :                         pWidths[nCol] = nW;
     788                 :            :                 }
     789                 :            :             }
     790         [ #  # ]:          0 :             for ( nCol = 1; nCol <= nColsPerRow; nCol++ )
     791                 :            :             {
     792                 :          0 :                 pOffsets[nCol] = pOffsets[nCol-1] + pWidths[nCol-1];
     793                 :            :             }
     794                 :          0 :             pLocalColOffset->clear();
     795         [ #  # ]:          0 :             for ( nCol = 0; nCol <= nColsPerRow; nCol++ )
     796                 :            :             {
     797                 :          0 :                 MakeColNoRef( pLocalColOffset, pOffsets[nCol], 0, 0, 0 );
     798                 :            :             }
     799                 :          0 :             nTableWidth = pOffsets[nColsPerRow] - pOffsets[0];
     800                 :            : 
     801         [ #  # ]:          0 :             for ( size_t i = nFirstTableCell, nListSize = maList.size(); i < nListSize; ++i )
     802                 :            :             {
     803                 :          0 :                 pE = maList[ i ];
     804         [ #  # ]:          0 :                 if ( pE->nTab == nTable )
     805                 :            :                 {
     806                 :          0 :                     nCol = pE->nCol - nColCntStart;
     807                 :            :                     OSL_ENSURE( nCol < nColsPerRow, "ScHTMLLayoutParser::SetWidths: column overflow" );
     808         [ #  # ]:          0 :                     if ( nCol < nColsPerRow )
     809                 :            :                     {
     810                 :          0 :                         pE->nOffset = pOffsets[nCol];
     811                 :          0 :                         nCol = nCol + pE->nColOverlap;
     812         [ #  # ]:          0 :                         if ( nCol > nColsPerRow )
     813                 :          0 :                             nCol = nColsPerRow;
     814                 :          0 :                         pE->nWidth = pOffsets[nCol] - pE->nOffset;
     815                 :            :                     }
     816                 :            :                 }
     817                 :            :             }
     818                 :            : 
     819         [ #  # ]:          0 :             delete [] pWidths;
     820         [ #  # ]:          0 :             delete [] pOffsets;
     821                 :            :         }
     822                 :            :     }
     823         [ #  # ]:          0 :     if ( !pLocalColOffset->empty() )
     824                 :            :     {
     825                 :          0 :         sal_uInt16 nMax = (sal_uInt16) pLocalColOffset->back();
     826         [ #  # ]:          0 :         if ( aPageSize.Width() < nMax )
     827                 :          0 :             aPageSize.Width() = nMax;
     828                 :            :     }
     829         [ #  # ]:          0 :     for ( size_t i = nFirstTableCell, nListSize = maList.size(); i < nListSize; ++i )
     830                 :            :     {
     831                 :          0 :         pE = maList[ i ];
     832         [ #  # ]:          0 :         if ( pE->nTab == nTable )
     833                 :            :         {
     834         [ #  # ]:          0 :             if ( !pE->nWidth )
     835                 :            :             {
     836                 :          0 :                 pE->nWidth = GetWidth( pE );
     837                 :            :                 OSL_ENSURE( pE->nWidth, "SetWidths: pE->nWidth == 0" );
     838                 :            :             }
     839                 :          0 :             MakeCol( pColOffset, pE->nOffset, pE->nWidth, nOffsetTolerance, nOffsetTolerance );
     840                 :            :         }
     841                 :            :     }
     842                 :          0 : }
     843                 :            : 
     844                 :            : 
     845                 :          0 : void ScHTMLLayoutParser::Colonize( ScEEParseEntry* pE )
     846                 :            : {
     847         [ #  # ]:          0 :     if ( pE->nCol == SCCOL_MAX )
     848                 :          0 :         pE->nCol = nColCnt;
     849         [ #  # ]:          0 :     if ( pE->nRow == SCROW_MAX )
     850                 :          0 :         pE->nRow = nRowCnt;
     851                 :          0 :     SCCOL nCol = pE->nCol;
     852         [ #  # ]:          0 :     SkipLocked( pE );       // Spaltenverdraengung nach rechts
     853                 :            : 
     854         [ #  # ]:          0 :     if ( nCol < pE->nCol )
     855                 :            :     {   // verdraengt
     856                 :          0 :         nCol = pE->nCol - nColCntStart;
     857                 :          0 :         SCCOL nCount = static_cast<SCCOL>(pLocalColOffset->size());
     858         [ #  # ]:          0 :         if ( nCol < nCount )
     859         [ #  # ]:          0 :             nColOffset = (sal_uInt16) (*pLocalColOffset)[nCol];
     860                 :            :         else
     861         [ #  # ]:          0 :             nColOffset = (sal_uInt16) (*pLocalColOffset)[nCount - 1];
     862                 :            :     }
     863                 :          0 :     pE->nOffset = nColOffset;
     864         [ #  # ]:          0 :     sal_uInt16 nWidth = GetWidth( pE );
     865         [ #  # ]:          0 :     MakeCol( pLocalColOffset, pE->nOffset, nWidth, nOffsetTolerance, nOffsetTolerance );
     866         [ #  # ]:          0 :     if ( pE->nWidth )
     867                 :          0 :         pE->nWidth = nWidth;
     868                 :          0 :     nColOffset = pE->nOffset + nWidth;
     869         [ #  # ]:          0 :     if ( nTableWidth < nColOffset - nColOffsetStart )
     870                 :          0 :         nTableWidth = nColOffset - nColOffsetStart;
     871                 :          0 : }
     872                 :            : 
     873                 :            : 
     874                 :          0 : void ScHTMLLayoutParser::CloseEntry( ImportInfo* pInfo )
     875                 :            : {
     876                 :          0 :     bInCell = false;
     877         [ #  # ]:          0 :     if ( bTabInTabCell )
     878                 :            :     {   // in TableOff vom Stack geholt
     879                 :          0 :         bTabInTabCell = false;
     880                 :          0 :         bool found = false;
     881         [ #  # ]:          0 :         for ( size_t i = 0, nListSize = maList.size(); i < nListSize; ++i )
     882                 :            :         {
     883         [ #  # ]:          0 :             if ( pActEntry == maList[ i ] )
     884                 :            :             {
     885                 :          0 :                 found = true;
     886                 :          0 :                 break;
     887                 :            :             }
     888                 :            :         }
     889         [ #  # ]:          0 :         if ( !found )
     890         [ #  # ]:          0 :             delete pActEntry;
     891                 :          0 :         NewActEntry( maList.back() );   // neuer freifliegender pActEntry
     892                 :          0 :         return ;
     893                 :            :     }
     894         [ #  # ]:          0 :     if ( pActEntry->nTab == 0 )
     895                 :          0 :         pActEntry->nWidth = (sal_uInt16) aPageSize.Width();
     896                 :          0 :     Colonize( pActEntry );
     897                 :          0 :     nColCnt = pActEntry->nCol + pActEntry->nColOverlap;
     898         [ #  # ]:          0 :     if ( nMaxCol < nColCnt )
     899                 :          0 :         nMaxCol = nColCnt;          // TableStack MaxCol
     900         [ #  # ]:          0 :     if ( nColMax < nColCnt )
     901                 :          0 :         nColMax = nColCnt;      // globales MaxCol fuer ScEEParser GetDimensions!
     902                 :          0 :     EntryEnd( pActEntry, pInfo->aSelection );
     903                 :          0 :     ESelection& rSel = pActEntry->aSel;
     904   [ #  #  #  # ]:          0 :     while ( rSel.nStartPara < rSel.nEndPara
                 [ #  # ]
     905                 :          0 :             && pEdit->GetTextLen( rSel.nStartPara ) == 0 )
     906                 :            :     {   // vorgehaengte Leerabsaetze strippen
     907                 :          0 :         rSel.nStartPara++;
     908                 :            :     }
     909 [ #  # ][ #  # ]:          0 :     while ( rSel.nEndPos == 0 && rSel.nEndPara > rSel.nStartPara )
                 [ #  # ]
     910                 :            :     {   // angehaengte Leerabsaetze strippen
     911                 :          0 :         rSel.nEndPara--;
     912                 :          0 :         rSel.nEndPos = pEdit->GetTextLen( rSel.nEndPara );
     913                 :            :     }
     914         [ #  # ]:          0 :     if ( rSel.nStartPara > rSel.nEndPara )
     915                 :            :     {   // gibt GPF in CreateTextObject
     916                 :            :         OSL_FAIL( "CloseEntry: EditEngine ESelection Start > End" );
     917                 :          0 :         rSel.nEndPara = rSel.nStartPara;
     918                 :            :     }
     919         [ #  # ]:          0 :     if ( rSel.HasRange() )
     920         [ #  # ]:          0 :         pActEntry->aItemSet.Put( SfxBoolItem( ATTR_LINEBREAK, true ) );
     921                 :          0 :     maList.push_back( pActEntry );
     922                 :          0 :     NewActEntry( pActEntry );   // neuer freifliegender pActEntry
     923                 :            : }
     924                 :            : 
     925                 :            : 
     926                 :          0 : IMPL_LINK( ScHTMLLayoutParser, HTMLImportHdl, ImportInfo*, pInfo )
     927                 :            : {
     928   [ #  #  #  #  :          0 :     switch ( pInfo->eState )
             #  #  #  #  
                      # ]
     929                 :            :     {
     930                 :            :         case HTMLIMP_NEXTTOKEN:
     931                 :          0 :             ProcToken( pInfo );
     932                 :          0 :             break;
     933                 :            :         case HTMLIMP_UNKNOWNATTR:
     934                 :          0 :             ProcToken( pInfo );
     935                 :          0 :             break;
     936                 :            :         case HTMLIMP_START:
     937                 :          0 :             break;
     938                 :            :         case HTMLIMP_END:
     939         [ #  # ]:          0 :             if ( pInfo->aSelection.nEndPos )
     940                 :            :             {
     941                 :            :                 // If text remains: create paragraph, without calling CloseEntry().
     942         [ #  # ]:          0 :                 if( bInCell )   // ...but only in opened table cells.
     943                 :            :                 {
     944                 :          0 :                     bInCell = false;
     945                 :          0 :                     NextRow( pInfo );
     946                 :          0 :                     bInCell = true;
     947                 :            :                 }
     948                 :          0 :                 CloseEntry( pInfo );
     949                 :            :             }
     950         [ #  # ]:          0 :             while ( nTableLevel > 0 )
     951                 :          0 :                 TableOff( pInfo );      // close tables, if </TABLE> missing
     952                 :          0 :             break;
     953                 :            :         case HTMLIMP_SETATTR:
     954                 :          0 :             break;
     955                 :            :         case HTMLIMP_INSERTTEXT:
     956                 :          0 :             break;
     957                 :            :         case HTMLIMP_INSERTPARA:
     958         [ #  # ]:          0 :             if ( nTableLevel < 1 )
     959                 :            :             {
     960                 :          0 :                 CloseEntry( pInfo );
     961                 :          0 :                 NextRow( pInfo );
     962                 :            :             }
     963                 :          0 :             break;
     964                 :            :         case HTMLIMP_INSERTFIELD:
     965                 :          0 :             break;
     966                 :            :         default:
     967                 :            :             OSL_FAIL("HTMLImportHdl: unknown ImportInfo.eState");
     968                 :            :     }
     969                 :          0 :     return 0;
     970                 :            : }
     971                 :            : 
     972                 :            : 
     973                 :            : // Groesster Gemeinsamer Teiler nach Euklid (Kettendivision)
     974                 :            : // Sonderfall: 0 und irgendwas geben 1
     975                 :          0 : SCROW lcl_GGT( SCROW a, SCROW b )
     976                 :            : {
     977 [ #  # ][ #  # ]:          0 :     if ( !a || !b )
     978                 :          0 :         return 1;
     979 [ #  # ][ #  # ]:          0 :     do
                 [ #  # ]
     980                 :            :     {
     981         [ #  # ]:          0 :         if ( a > b )
     982                 :          0 :             a -= SCROW(a / b) * b;
     983                 :            :         else
     984                 :          0 :             b -= SCROW(b / a) * a;
     985                 :            :     } while ( a && b );
     986         [ #  # ]:          0 :     return ((a != 0) ? a : b);
     987                 :            : }
     988                 :            : 
     989                 :            : 
     990                 :            : // Kleinstes Gemeinsames Vielfaches: a * b / GGT(a,b)
     991                 :          0 : SCROW lcl_KGV( SCROW a, SCROW b )
     992                 :            : {
     993         [ #  # ]:          0 :     if ( a > b )    // Ueberlauf unwahrscheinlicher machen
     994                 :          0 :         return (a / lcl_GGT(a,b)) * b;
     995                 :            :     else
     996                 :          0 :         return (b / lcl_GGT(a,b)) * a;
     997                 :            : }
     998                 :            : 
     999                 :            : 
    1000                 :          0 : void ScHTMLLayoutParser::TableDataOn( ImportInfo* pInfo )
    1001                 :            : {
    1002         [ #  # ]:          0 :     if ( bInCell )
    1003                 :          0 :         CloseEntry( pInfo );
    1004         [ #  # ]:          0 :     if ( !nTableLevel )
    1005                 :            :     {
    1006                 :            :         OSL_FAIL( "Dummbatz-Dok! <TH> oder <TD> ohne vorheriges <TABLE>" );
    1007                 :          0 :         TableOn( pInfo );
    1008                 :            :     }
    1009                 :          0 :     bInCell = true;
    1010                 :          0 :     bool bHorJustifyCenterTH = (pInfo->nToken == HTML_TABLEHEADER_ON);
    1011                 :          0 :     const HTMLOptions& rOptions = static_cast<HTMLParser*>(pInfo->pParser)->GetOptions();
    1012         [ #  # ]:          0 :     for (size_t i = 0, n = rOptions.size(); i < n; ++i)
    1013                 :            :     {
    1014                 :          0 :         const HTMLOption& rOption = rOptions[i];
    1015   [ #  #  #  #  :          0 :         switch( rOption.GetToken() )
             #  #  #  #  
                      # ]
    1016                 :            :         {
    1017                 :            :             case HTML_O_COLSPAN:
    1018                 :            :             {
    1019                 :          0 :                 pActEntry->nColOverlap = ( SCCOL ) rOption.GetString().ToInt32();
    1020                 :            :             }
    1021                 :          0 :             break;
    1022                 :            :             case HTML_O_ROWSPAN:
    1023                 :            :             {
    1024                 :          0 :                 pActEntry->nRowOverlap = ( SCROW ) rOption.GetString().ToInt32();
    1025                 :            :             }
    1026                 :          0 :             break;
    1027                 :            :             case HTML_O_ALIGN:
    1028                 :            :             {
    1029                 :          0 :                 bHorJustifyCenterTH = false;
    1030                 :            :                 SvxCellHorJustify eVal;
    1031                 :          0 :                 const String& rOptVal = rOption.GetString();
    1032         [ #  # ]:          0 :                 if ( rOptVal.CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_AL_right ) == COMPARE_EQUAL )
    1033                 :          0 :                     eVal = SVX_HOR_JUSTIFY_RIGHT;
    1034         [ #  # ]:          0 :                 else if ( rOptVal.CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_AL_center ) == COMPARE_EQUAL )
    1035                 :          0 :                     eVal = SVX_HOR_JUSTIFY_CENTER;
    1036         [ #  # ]:          0 :                 else if ( rOptVal.CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_AL_left ) == COMPARE_EQUAL )
    1037                 :          0 :                     eVal = SVX_HOR_JUSTIFY_LEFT;
    1038                 :            :                 else
    1039                 :          0 :                     eVal = SVX_HOR_JUSTIFY_STANDARD;
    1040         [ #  # ]:          0 :                 if ( eVal != SVX_HOR_JUSTIFY_STANDARD )
    1041         [ #  # ]:          0 :                     pActEntry->aItemSet.Put( SvxHorJustifyItem( eVal, ATTR_HOR_JUSTIFY) );
    1042                 :            :             }
    1043                 :          0 :             break;
    1044                 :            :             case HTML_O_VALIGN:
    1045                 :            :             {
    1046                 :            :                 SvxCellVerJustify eVal;
    1047                 :          0 :                 const String& rOptVal = rOption.GetString();
    1048         [ #  # ]:          0 :                 if ( rOptVal.CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_VA_top ) == COMPARE_EQUAL )
    1049                 :          0 :                     eVal = SVX_VER_JUSTIFY_TOP;
    1050         [ #  # ]:          0 :                 else if ( rOptVal.CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_VA_middle ) == COMPARE_EQUAL )
    1051                 :          0 :                     eVal = SVX_VER_JUSTIFY_CENTER;
    1052         [ #  # ]:          0 :                 else if ( rOptVal.CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_VA_bottom ) == COMPARE_EQUAL )
    1053                 :          0 :                     eVal = SVX_VER_JUSTIFY_BOTTOM;
    1054                 :            :                 else
    1055                 :          0 :                     eVal = SVX_VER_JUSTIFY_STANDARD;
    1056         [ #  # ]:          0 :                 pActEntry->aItemSet.Put( SvxVerJustifyItem( eVal, ATTR_VER_JUSTIFY) );
    1057                 :            :             }
    1058                 :          0 :             break;
    1059                 :            :             case HTML_O_WIDTH:
    1060                 :            :             {
    1061                 :          0 :                 pActEntry->nWidth = GetWidthPixel( rOption );
    1062                 :            :             }
    1063                 :          0 :             break;
    1064                 :            :             case HTML_O_BGCOLOR:
    1065                 :            :             {
    1066                 :          0 :                 Color aColor;
    1067         [ #  # ]:          0 :                 rOption.GetColor( aColor );
    1068                 :            :                 pActEntry->aItemSet.Put(
    1069 [ #  # ][ #  # ]:          0 :                     SvxBrushItem( aColor, ATTR_BACKGROUND ) );
                 [ #  # ]
    1070                 :            :             }
    1071                 :          0 :             break;
    1072                 :            :             case HTML_O_SDVAL:
    1073                 :            :             {
    1074         [ #  # ]:          0 :                 pActEntry->pValStr = new rtl::OUString( rOption.GetString() );
    1075                 :            :             }
    1076                 :          0 :             break;
    1077                 :            :             case HTML_O_SDNUM:
    1078                 :            :             {
    1079         [ #  # ]:          0 :                 pActEntry->pNumStr = new rtl::OUString( rOption.GetString() );
    1080                 :            :             }
    1081                 :          0 :             break;
    1082                 :            :         }
    1083                 :            :     }
    1084                 :          0 :     pActEntry->nCol = nColCnt;
    1085                 :          0 :     pActEntry->nRow = nRowCnt;
    1086                 :          0 :     pActEntry->nTab = nTable;
    1087                 :            : 
    1088         [ #  # ]:          0 :     if ( bHorJustifyCenterTH )
    1089                 :            :         pActEntry->aItemSet.Put(
    1090         [ #  # ]:          0 :             SvxHorJustifyItem( SVX_HOR_JUSTIFY_CENTER, ATTR_HOR_JUSTIFY) );
    1091                 :          0 : }
    1092                 :            : 
    1093                 :            : 
    1094                 :          0 : void ScHTMLLayoutParser::TableRowOn( ImportInfo* pInfo )
    1095                 :            : {
    1096         [ #  # ]:          0 :     if ( nColCnt > nColCntStart )
    1097                 :          0 :         NextRow( pInfo );       // das optionale TableRowOff war nicht
    1098                 :          0 :     nColOffset = nColOffsetStart;
    1099                 :          0 : }
    1100                 :            : 
    1101                 :            : 
    1102                 :          0 : void ScHTMLLayoutParser::TableRowOff( ImportInfo* pInfo )
    1103                 :            : {
    1104                 :          0 :     NextRow( pInfo );
    1105                 :          0 : }
    1106                 :            : 
    1107                 :            : 
    1108                 :          0 : void ScHTMLLayoutParser::TableDataOff( ImportInfo* pInfo )
    1109                 :            : {
    1110         [ #  # ]:          0 :     if ( bInCell )
    1111                 :          0 :         CloseEntry( pInfo );    // aber nur wenn's auch eine war
    1112                 :          0 : }
    1113                 :            : 
    1114                 :            : 
    1115                 :          0 : void ScHTMLLayoutParser::TableOn( ImportInfo* pInfo )
    1116                 :            : {
    1117         [ #  # ]:          0 :     String aTabName;
    1118                 :            : 
    1119         [ #  # ]:          0 :     if ( ++nTableLevel > 1 )
    1120                 :            :     {   // Table in Table
    1121                 :          0 :         sal_uInt16 nTmpColOffset = nColOffset;  // wird in Colonize noch angepasst
    1122         [ #  # ]:          0 :         Colonize( pActEntry );
    1123                 :            :         aTableStack.push( new ScHTMLTableStackEntry(
    1124                 :            :             pActEntry, xLockedList, pLocalColOffset, nFirstTableCell,
    1125                 :            :             nColCnt, nRowCnt, nColCntStart, nMaxCol, nTable,
    1126                 :            :             nTableWidth, nColOffset, nColOffsetStart,
    1127 [ #  # ][ #  # ]:          0 :             bFirstRow ) );
                 [ #  # ]
    1128                 :          0 :         sal_uInt16 nLastWidth = nTableWidth;
    1129         [ #  # ]:          0 :         nTableWidth = GetWidth( pActEntry );
    1130 [ #  # ][ #  # ]:          0 :         if ( nTableWidth == nLastWidth && nMaxCol - nColCntStart > 1 )
    1131                 :            :         {   // es muss mehr als einen geben, also kann dieser nicht alles sein
    1132                 :          0 :             nTableWidth = nLastWidth / static_cast<sal_uInt16>((nMaxCol - nColCntStart));
    1133                 :            :         }
    1134                 :          0 :         nLastWidth = nTableWidth;
    1135         [ #  # ]:          0 :         if ( pInfo->nToken == HTML_TABLE_ON )
    1136                 :            :         {   // es kann auch TD oder TH sein, wenn es vorher kein TABLE gab
    1137         [ #  # ]:          0 :             const HTMLOptions& rOptions = static_cast<HTMLParser*>(pInfo->pParser)->GetOptions();
    1138         [ #  # ]:          0 :             for (size_t i = 0, n = rOptions.size(); i < n; ++i)
    1139                 :            :             {
    1140         [ #  # ]:          0 :                 const HTMLOption& rOption = rOptions[i];
    1141   [ #  #  #  # ]:          0 :                 switch( rOption.GetToken() )
    1142                 :            :                 {
    1143                 :            :                     case HTML_O_WIDTH:
    1144                 :            :                     {   // Prozent: von Dokumentbreite bzw. aeusserer Zelle
    1145         [ #  # ]:          0 :                         nTableWidth = GetWidthPixel( rOption );
    1146                 :            :                     }
    1147                 :          0 :                     break;
    1148                 :            :                     case HTML_O_BORDER:
    1149                 :            :                         // Border is: ((pOption->GetString().Len() == 0) || (pOption->GetNumber() != 0));
    1150                 :          0 :                     break;
    1151                 :            :                     case HTML_O_ID:
    1152         [ #  # ]:          0 :                         aTabName.Assign( rOption.GetString() );
    1153                 :          0 :                     break;
    1154                 :            :                 }
    1155                 :            :             }
    1156                 :            :         }
    1157                 :          0 :         bInCell = false;
    1158 [ #  # ][ #  # ]:          0 :         if ( bTabInTabCell && !(nTableWidth < nLastWidth) )
    1159                 :            :         {   // mehrere Tabellen in einer Zelle, untereinander
    1160                 :          0 :             bTabInTabCell = false;
    1161         [ #  # ]:          0 :             NextRow( pInfo );
    1162                 :            :         }
    1163                 :            :         else
    1164                 :            :         {   // in dieser Zelle geht's los, oder nebeneinander
    1165                 :          0 :             bTabInTabCell = false;
    1166                 :          0 :             nColCntStart = nColCnt;
    1167                 :          0 :             nColOffset = nTmpColOffset;
    1168                 :          0 :             nColOffsetStart = nColOffset;
    1169                 :            :         }
    1170                 :            : 
    1171                 :          0 :         ScEEParseEntry* pE = NULL;
    1172         [ #  # ]:          0 :         if (maList.size())
    1173         [ #  # ]:          0 :             pE = maList.back();
    1174         [ #  # ]:          0 :         NewActEntry( pE );      // neuer freifliegender pActEntry
    1175 [ #  # ][ #  # ]:          0 :         xLockedList = new ScRangeList;
                 [ #  # ]
    1176                 :            :     }
    1177                 :            :     else
    1178                 :            :     {   // einfache Table auf Dokumentebene
    1179                 :          0 :         EntryEnd( pActEntry, pInfo->aSelection );
    1180         [ #  # ]:          0 :         if ( pActEntry->aSel.HasRange() )
    1181                 :            :         {   // noch fliegender Text
    1182         [ #  # ]:          0 :             CloseEntry( pInfo );
    1183         [ #  # ]:          0 :             NextRow( pInfo );
    1184                 :            :         }
    1185                 :            :         aTableStack.push( new ScHTMLTableStackEntry(
    1186                 :            :             pActEntry, xLockedList, pLocalColOffset, nFirstTableCell,
    1187                 :            :             nColCnt, nRowCnt, nColCntStart, nMaxCol, nTable,
    1188                 :            :             nTableWidth, nColOffset, nColOffsetStart,
    1189 [ #  # ][ #  # ]:          0 :             bFirstRow ) );
                 [ #  # ]
    1190                 :            :         // As soon as we have multiple tables we need to be tolerant with the offsets.
    1191         [ #  # ]:          0 :         if (nMaxTable > 0)
    1192                 :          0 :             nOffsetTolerance = SC_HTML_OFFSET_TOLERANCE_LARGE;
    1193                 :          0 :         nTableWidth = 0;
    1194         [ #  # ]:          0 :         if ( pInfo->nToken == HTML_TABLE_ON )
    1195                 :            :         {   // es kann auch TD oder TH sein, wenn es vorher kein TABLE gab
    1196         [ #  # ]:          0 :             const HTMLOptions& rOptions = static_cast<HTMLParser*>(pInfo->pParser)->GetOptions();
    1197         [ #  # ]:          0 :             for (size_t i = 0, n = rOptions.size(); i < n; ++i)
    1198                 :            :             {
    1199         [ #  # ]:          0 :                 const HTMLOption& rOption = rOptions[i];
    1200   [ #  #  #  # ]:          0 :                 switch( rOption.GetToken() )
    1201                 :            :                 {
    1202                 :            :                     case HTML_O_WIDTH:
    1203                 :            :                     {   // Prozent: von Dokumentbreite bzw. aeusserer Zelle
    1204         [ #  # ]:          0 :                         nTableWidth = GetWidthPixel( rOption );
    1205                 :            :                     }
    1206                 :          0 :                     break;
    1207                 :            :                     case HTML_O_BORDER:
    1208                 :            :                         //BorderOn is: ((pOption->GetString().Len() == 0) || (pOption->GetNumber() != 0));
    1209                 :          0 :                     break;
    1210                 :            :                     case HTML_O_ID:
    1211         [ #  # ]:          0 :                         aTabName.Assign( rOption.GetString() );
    1212                 :          0 :                     break;
    1213                 :            :                 }
    1214                 :            :             }
    1215                 :            :         }
    1216                 :            :     }
    1217                 :          0 :     nTable = ++nMaxTable;
    1218                 :          0 :     bFirstRow = true;
    1219                 :          0 :     nFirstTableCell = maList.size();
    1220                 :            : 
    1221 [ #  # ][ #  # ]:          0 :     pLocalColOffset = new ScHTMLColOffset;
    1222 [ #  # ][ #  # ]:          0 :     MakeColNoRef( pLocalColOffset, nColOffsetStart, 0, 0, 0 );
    1223                 :          0 : }
    1224                 :            : 
    1225                 :            : 
    1226                 :          0 : void ScHTMLLayoutParser::TableOff( ImportInfo* pInfo )
    1227                 :            : {
    1228         [ #  # ]:          0 :     if ( bInCell )
    1229                 :          0 :         CloseEntry( pInfo );
    1230         [ #  # ]:          0 :     if ( nColCnt > nColCntStart )
    1231                 :          0 :         TableRowOff( pInfo );      // das optionale TableRowOff war nicht
    1232         [ #  # ]:          0 :     if ( !nTableLevel )
    1233                 :            :     {
    1234                 :            :         OSL_FAIL( "Dummbatz-Dok! </TABLE> ohne oeffnendes <TABLE>" );
    1235                 :          0 :         return ;
    1236                 :            :     }
    1237         [ #  # ]:          0 :     if ( --nTableLevel > 0 )
    1238                 :            :     {   // Table in Table beendet
    1239         [ #  # ]:          0 :         if ( !aTableStack.empty() )
    1240                 :            :         {
    1241                 :          0 :             ScHTMLTableStackEntry* pS = aTableStack.top();
    1242                 :          0 :             aTableStack.pop();
    1243                 :            : 
    1244                 :          0 :             ScEEParseEntry* pE = pS->pCellEntry;
    1245                 :          0 :             SCROW nRows = nRowCnt - pS->nRowCnt;
    1246         [ #  # ]:          0 :             if ( nRows > 1 )
    1247                 :            :             {   // Groesse der Tabelle an dieser Position eintragen
    1248                 :          0 :                 SCROW nRow = pS->nRowCnt;
    1249                 :          0 :                 sal_uInt16 nTab = pS->nTable;
    1250         [ #  # ]:          0 :                 if ( !pTables )
    1251 [ #  # ][ #  # ]:          0 :                     pTables = new OuterMap;
    1252                 :            :                 // Hoehen der aeusseren Table
    1253 [ #  # ][ #  # ]:          0 :                 OuterMap::const_iterator it = pTables->find( nTab );
    1254                 :            :                 InnerMap* pTab1;
    1255 [ #  # ][ #  # ]:          0 :                 if ( it == pTables->end() )
                 [ #  # ]
    1256                 :            :                 {
    1257 [ #  # ][ #  # ]:          0 :                     pTab1 = new InnerMap;
    1258         [ #  # ]:          0 :                     (*pTables)[ nTab ] = pTab1;
    1259                 :            :                 }
    1260                 :            :                 else
    1261         [ #  # ]:          0 :                     pTab1 = it->second;
    1262                 :          0 :                 SCROW nRowSpan = pE->nRowOverlap;
    1263                 :            :                 SCROW nRowKGV;
    1264                 :            :                 SCROW nRowsPerRow1;    // aeussere Table
    1265                 :            :                 SCROW nRowsPerRow2;    // innere Table
    1266         [ #  # ]:          0 :                 if ( nRowSpan > 1 )
    1267                 :            :                 {   // KGV auf das sich aussere und innere Zeilen
    1268                 :            :                     // abbilden lassen
    1269                 :          0 :                     nRowKGV = lcl_KGV( nRowSpan, nRows );
    1270                 :          0 :                     nRowsPerRow1 = nRowKGV / nRowSpan;
    1271                 :          0 :                     nRowsPerRow2 = nRowKGV / nRows;
    1272                 :            :                 }
    1273                 :            :                 else
    1274                 :            :                 {
    1275                 :          0 :                     nRowKGV = nRowsPerRow1 = nRows;
    1276                 :          0 :                     nRowsPerRow2 = 1;
    1277                 :            :                 }
    1278                 :          0 :                 InnerMap* pTab2 = NULL;
    1279         [ #  # ]:          0 :                 if ( nRowsPerRow2 > 1 )
    1280                 :            :                 {   // Hoehen der inneren Table
    1281 [ #  # ][ #  # ]:          0 :                     pTab2 = new InnerMap;
    1282         [ #  # ]:          0 :                     (*pTables)[ nTable ] = pTab2;
    1283                 :            :                 }
    1284                 :            :                 // void* Data-Entry der Table-Class fuer das
    1285                 :            :                 // Hoehen-Mapping missbrauchen
    1286         [ #  # ]:          0 :                 if ( nRowKGV > 1 )
    1287                 :            :                 {
    1288         [ #  # ]:          0 :                     if ( nRowsPerRow1 > 1 )
    1289                 :            :                     {   // aussen
    1290         [ #  # ]:          0 :                         for ( SCROW j=0; j < nRowSpan; j++ )
    1291                 :            :                         {
    1292                 :          0 :                             sal_uLong nRowKey = nRow + j;
    1293         [ #  # ]:          0 :                             SCROW nR = (*pTab1)[ nRowKey ];
    1294         [ #  # ]:          0 :                             if ( !nR )
    1295         [ #  # ]:          0 :                                 (*pTab1)[ nRowKey ] = nRowsPerRow1;
    1296         [ #  # ]:          0 :                             else if ( nRowsPerRow1 > nR )
    1297         [ #  # ]:          0 :                                 (*pTab1)[ nRowKey ] = nRowsPerRow1;
    1298                 :            :                                 //2do: wie geht das noch besser?
    1299 [ #  # ][ #  # ]:          0 :                             else if ( nRowsPerRow1 < nR && nRowSpan == 1
                 [ #  # ]
    1300                 :            :                               && nTable == nMaxTable )
    1301                 :            :                             {   // Platz uebrig, evtl. besser mergen
    1302                 :          0 :                                 SCROW nAdd = nRowsPerRow1 - (nR % nRowsPerRow1);
    1303                 :          0 :                                 nR += nAdd;
    1304         [ #  # ]:          0 :                                 if ( (nR % nRows) == 0 )
    1305                 :            :                                 {   // nur wenn abbildbar
    1306         [ #  # ]:          0 :                                     SCROW nR2 = (*pTab1)[ nRowKey+1 ];
    1307         [ #  # ]:          0 :                                     if ( nR2 > nAdd )
    1308                 :            :                                     {   // nur wenn wirklich Platz
    1309         [ #  # ]:          0 :                                         (*pTab1)[ nRowKey ] = nR;
    1310         [ #  # ]:          0 :                                         (*pTab1)[ nRowKey+1 ] = nR2 - nAdd;
    1311                 :          0 :                                         nRowsPerRow2 = nR / nRows;
    1312                 :            :                                     }
    1313                 :            :                                 }
    1314                 :            :                             }
    1315                 :            :                         }
    1316                 :            :                     }
    1317         [ #  # ]:          0 :                     if ( nRowsPerRow2 > 1 )
    1318                 :            :                     {   // innen
    1319         [ #  # ]:          0 :                         if ( !pTab2 )
    1320                 :            :                         {   // nRowsPerRow2 kann erhoeht worden sein
    1321 [ #  # ][ #  # ]:          0 :                             pTab2 = new InnerMap;
    1322         [ #  # ]:          0 :                             (*pTables)[ nTable ] = pTab2;
    1323                 :            :                         }
    1324         [ #  # ]:          0 :                         for ( SCROW j=0; j < nRows; j++ )
    1325                 :            :                         {
    1326                 :          0 :                             sal_uLong nRowKey = nRow + j;
    1327         [ #  # ]:          0 :                             (*pTab2)[ nRowKey ] = nRowsPerRow2;
    1328                 :            :                         }
    1329                 :            :                     }
    1330                 :            :                 }
    1331                 :            :             }
    1332                 :            : 
    1333                 :          0 :             SetWidths();
    1334                 :            : 
    1335         [ #  # ]:          0 :             if ( !pE->nWidth )
    1336                 :          0 :                 pE->nWidth = nTableWidth;
    1337         [ #  # ]:          0 :             else if ( pE->nWidth < nTableWidth )
    1338                 :            :             {
    1339                 :          0 :                 sal_uInt16 nOldOffset = pE->nOffset + pE->nWidth;
    1340                 :          0 :                 sal_uInt16 nNewOffset = pE->nOffset + nTableWidth;
    1341         [ #  # ]:          0 :                 ModifyOffset( pS->pLocalColOffset, nOldOffset, nNewOffset, nOffsetTolerance );
    1342                 :          0 :                 sal_uInt16 nTmp = nNewOffset - pE->nOffset - pE->nWidth;
    1343                 :          0 :                 pE->nWidth = nNewOffset - pE->nOffset;
    1344                 :          0 :                 pS->nTableWidth = pS->nTableWidth + nTmp;
    1345         [ #  # ]:          0 :                 if ( pS->nColOffset >= nOldOffset )
    1346                 :          0 :                     pS->nColOffset = pS->nColOffset + nTmp;
    1347                 :            :             }
    1348                 :            : 
    1349                 :          0 :             nColCnt = pE->nCol + pE->nColOverlap;
    1350                 :          0 :             nRowCnt = pS->nRowCnt;
    1351                 :          0 :             nColCntStart = pS->nColCntStart;
    1352                 :          0 :             nMaxCol = pS->nMaxCol;
    1353                 :          0 :             nTable = pS->nTable;
    1354                 :          0 :             nTableWidth = pS->nTableWidth;
    1355                 :          0 :             nFirstTableCell = pS->nFirstTableCell;
    1356                 :          0 :             nColOffset = pS->nColOffset;
    1357                 :          0 :             nColOffsetStart = pS->nColOffsetStart;
    1358                 :          0 :             bFirstRow = pS->bFirstRow;
    1359                 :          0 :             xLockedList = pS->xLockedList;
    1360         [ #  # ]:          0 :             if ( pLocalColOffset )
    1361         [ #  # ]:          0 :                 delete pLocalColOffset;
    1362                 :          0 :             pLocalColOffset = pS->pLocalColOffset;
    1363         [ #  # ]:          0 :             delete pActEntry;
    1364                 :            :             // pActEntry bleibt erstmal erhalten falls da noch 'ne Table in
    1365                 :            :             // der gleichen Zelle aufgemacht werden sollte (in HTML ist ja
    1366                 :            :             // alles moeglich..) und wird in CloseEntry deleted
    1367                 :          0 :             pActEntry = pE;
    1368         [ #  # ]:          0 :             delete pS;
    1369                 :            :         }
    1370                 :          0 :         bTabInTabCell = true;
    1371                 :          0 :         bInCell = true;
    1372                 :            :     }
    1373                 :            :     else
    1374                 :            :     {   // einfache Table beendet
    1375                 :          0 :         SetWidths();
    1376                 :          0 :         nMaxCol = 0;
    1377                 :          0 :         nTable = 0;
    1378         [ #  # ]:          0 :         if ( !aTableStack.empty() )
    1379                 :            :         {
    1380                 :          0 :             ScHTMLTableStackEntry* pS = aTableStack.top();
    1381                 :          0 :             aTableStack.pop();
    1382         [ #  # ]:          0 :             if ( pLocalColOffset )
    1383         [ #  # ]:          0 :                 delete pLocalColOffset;
    1384                 :          0 :             pLocalColOffset = pS->pLocalColOffset;
    1385         [ #  # ]:          0 :             delete pS;
    1386                 :            :         }
    1387                 :            :     }
    1388                 :            : }
    1389                 :            : 
    1390                 :            : 
    1391                 :          0 : void ScHTMLLayoutParser::Image( ImportInfo* pInfo )
    1392                 :            : {
    1393         [ #  # ]:          0 :     ScHTMLImage* pImage = new ScHTMLImage;
    1394         [ #  # ]:          0 :     pActEntry->maImageList.push_back( pImage );
    1395         [ #  # ]:          0 :     const HTMLOptions& rOptions = static_cast<HTMLParser*>(pInfo->pParser)->GetOptions();
    1396         [ #  # ]:          0 :     for (size_t i = 0, n = rOptions.size(); i < n; ++i)
    1397                 :            :     {
    1398         [ #  # ]:          0 :         const HTMLOption& rOption = rOptions[i];
    1399   [ #  #  #  #  :          0 :         switch( rOption.GetToken() )
                #  #  # ]
    1400                 :            :         {
    1401                 :            :             case HTML_O_SRC:
    1402                 :            :             {
    1403 [ #  # ][ #  # ]:          0 :                 pImage->aURL = INetURLObject::GetAbsURL( aBaseURL, rOption.GetString() );
    1404                 :            :             }
    1405                 :          0 :             break;
    1406                 :            :             case HTML_O_ALT:
    1407                 :            :             {
    1408         [ #  # ]:          0 :                 if ( !pActEntry->bHasGraphic )
    1409                 :            :                 {   // ALT text only if not any image loaded
    1410         [ #  # ]:          0 :                     if (!pActEntry->aAltText.isEmpty())
    1411         [ #  # ]:          0 :                         pActEntry->aAltText += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("; "));
    1412                 :            : 
    1413         [ #  # ]:          0 :                     pActEntry->aAltText += rOption.GetString();
    1414                 :            :                 }
    1415                 :            :             }
    1416                 :          0 :             break;
    1417                 :            :             case HTML_O_WIDTH:
    1418                 :            :             {
    1419         [ #  # ]:          0 :                 pImage->aSize.Width() = (long)rOption.GetNumber();
    1420                 :            :             }
    1421                 :          0 :             break;
    1422                 :            :             case HTML_O_HEIGHT:
    1423                 :            :             {
    1424         [ #  # ]:          0 :                 pImage->aSize.Height() = (long)rOption.GetNumber();
    1425                 :            :             }
    1426                 :          0 :             break;
    1427                 :            :             case HTML_O_HSPACE:
    1428                 :            :             {
    1429         [ #  # ]:          0 :                 pImage->aSpace.X() = (long)rOption.GetNumber();
    1430                 :            :             }
    1431                 :          0 :             break;
    1432                 :            :             case HTML_O_VSPACE:
    1433                 :            :             {
    1434         [ #  # ]:          0 :                 pImage->aSpace.Y() = (long)rOption.GetNumber();
    1435                 :            :             }
    1436                 :          0 :             break;
    1437                 :            :         }
    1438                 :            :     }
    1439         [ #  # ]:          0 :     if (pImage->aURL.isEmpty())
    1440                 :            :     {
    1441                 :            :         OSL_FAIL( "Image: Grafik ohne URL ?!?" );
    1442                 :            :         return ;
    1443                 :            :     }
    1444                 :            : 
    1445                 :            :     sal_uInt16 nFormat;
    1446 [ #  # ][ #  # ]:          0 :     Graphic* pGraphic = new Graphic;
    1447         [ #  # ]:          0 :     GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
    1448         [ #  # ]:          0 :     if ( GRFILTER_OK != GraphicFilter::LoadGraphic( pImage->aURL, pImage->aFilterName,
    1449 [ #  # ][ #  # ]:          0 :             *pGraphic, &rFilter, &nFormat ) )
         [ #  # ][ #  # ]
                 [ #  # ]
    1450                 :            :     {
    1451 [ #  # ][ #  # ]:          0 :         delete pGraphic;
    1452                 :            :         return ;        // dumm gelaufen
    1453                 :            :     }
    1454         [ #  # ]:          0 :     if ( !pActEntry->bHasGraphic )
    1455                 :            :     {   // discard any ALT text in this cell if we have any image
    1456                 :          0 :         pActEntry->bHasGraphic = true;
    1457                 :          0 :         pActEntry->aAltText = rtl::OUString();
    1458                 :            :     }
    1459 [ #  # ][ #  # ]:          0 :     pImage->aFilterName = rFilter.GetImportFormatName( nFormat );
                 [ #  # ]
    1460                 :          0 :     pImage->pGraphic = pGraphic;
    1461 [ #  # ][ #  # ]:          0 :     if ( !(pImage->aSize.Width() && pImage->aSize.Height()) )
                 [ #  # ]
    1462                 :            :     {
    1463         [ #  # ]:          0 :         OutputDevice* pDefaultDev = Application::GetDefaultDevice();
    1464                 :            :         pImage->aSize = pDefaultDev->LogicToPixel( pGraphic->GetPrefSize(),
    1465 [ #  # ][ #  # ]:          0 :             pGraphic->GetPrefMapMode() );
         [ #  # ][ #  # ]
    1466                 :            :     }
    1467         [ #  # ]:          0 :     if ( pActEntry->maImageList.size() > 0 )
    1468                 :            :     {
    1469                 :          0 :         long nWidth = 0;
    1470         [ #  # ]:          0 :         for ( sal_uInt32 i=0; i < pActEntry->maImageList.size(); ++i )
    1471                 :            :         {
    1472         [ #  # ]:          0 :             ScHTMLImage* pI = &pActEntry->maImageList[ i ];
    1473         [ #  # ]:          0 :             if ( pI->nDir & nHorizontal )
    1474                 :          0 :                 nWidth += pI->aSize.Width() + 2 * pI->aSpace.X();
    1475                 :            :             else
    1476                 :          0 :                 nWidth = 0;
    1477                 :            :         }
    1478   [ #  #  #  # ]:          0 :         if ( pActEntry->nWidth
                 [ #  # ]
    1479                 :          0 :           && (nWidth + pImage->aSize.Width() + 2 * pImage->aSpace.X()
    1480                 :            :                 >= pActEntry->nWidth) )
    1481         [ #  # ]:          0 :             pActEntry->maImageList.back().nDir = nVertical;
    1482                 :            :     }
    1483                 :            : }
    1484                 :            : 
    1485                 :            : 
    1486                 :          0 : void ScHTMLLayoutParser::ColOn( ImportInfo* pInfo )
    1487                 :            : {
    1488                 :          0 :     const HTMLOptions& rOptions = static_cast<HTMLParser*>(pInfo->pParser)->GetOptions();
    1489         [ #  # ]:          0 :     for (size_t i = 0, n = rOptions.size(); i < n; ++i)
    1490                 :            :     {
    1491                 :          0 :         const HTMLOption& rOption = rOptions[i];
    1492         [ #  # ]:          0 :         switch( rOption.GetToken() )
    1493                 :            :         {
    1494                 :            :             case HTML_O_WIDTH:
    1495                 :            :             {
    1496         [ #  # ]:          0 :                 sal_uInt16 nVal = GetWidthPixel( rOption );
    1497         [ #  # ]:          0 :                 MakeCol( pLocalColOffset, nColOffset, nVal, 0, 0 );
    1498                 :          0 :                 nColOffset = nColOffset + nVal;
    1499                 :            :             }
    1500                 :          0 :             break;
    1501                 :            :         }
    1502                 :            :     }
    1503                 :          0 : }
    1504                 :            : 
    1505                 :            : 
    1506                 :          0 : sal_uInt16 ScHTMLLayoutParser::GetWidthPixel( const HTMLOption& rOption )
    1507                 :            : {
    1508                 :          0 :     const String& rOptVal = rOption.GetString();
    1509         [ #  # ]:          0 :     if ( rOptVal.Search('%') != STRING_NOTFOUND )
    1510                 :            :     {   // Prozent
    1511         [ #  # ]:          0 :         sal_uInt16 nW = (nTableWidth ? nTableWidth : (sal_uInt16) aPageSize.Width());
    1512                 :          0 :         return (sal_uInt16)((rOption.GetNumber() * nW) / 100);
    1513                 :            :     }
    1514                 :            :     else
    1515                 :            :     {
    1516         [ #  # ]:          0 :         if ( rOptVal.Search('*') != STRING_NOTFOUND )
    1517                 :            :         {   // relativ zu was?!?
    1518                 :            :             //todo: ColArray aller relativen Werte sammeln und dann MakeCol
    1519                 :          0 :             return 0;
    1520                 :            :         }
    1521                 :            :         else
    1522                 :          0 :             return (sal_uInt16)rOption.GetNumber();    // Pixel
    1523                 :            :     }
    1524                 :            : }
    1525                 :            : 
    1526                 :            : 
    1527                 :          0 : void ScHTMLLayoutParser::AnchorOn( ImportInfo* pInfo )
    1528                 :            : {
    1529                 :          0 :     const HTMLOptions& rOptions = static_cast<HTMLParser*>(pInfo->pParser)->GetOptions();
    1530         [ #  # ]:          0 :     for (size_t i = 0, n = rOptions.size(); i < n; ++i)
    1531                 :            :     {
    1532                 :          0 :         const HTMLOption& rOption = rOptions[i];
    1533         [ #  # ]:          0 :         switch( rOption.GetToken() )
    1534                 :            :         {
    1535                 :            :             case HTML_O_NAME:
    1536                 :            :             {
    1537         [ #  # ]:          0 :                 pActEntry->pName = new rtl::OUString(rOption.GetString());
    1538                 :            :             }
    1539                 :          0 :             break;
    1540                 :            :         }
    1541                 :            :     }
    1542                 :          0 : }
    1543                 :            : 
    1544                 :            : 
    1545                 :          0 : bool ScHTMLLayoutParser::IsAtBeginningOfText( ImportInfo* pInfo )
    1546                 :            : {
    1547                 :          0 :     ESelection& rSel = pActEntry->aSel;
    1548                 :            :     return rSel.nStartPara == rSel.nEndPara &&
    1549                 :            :         rSel.nStartPara <= pInfo->aSelection.nEndPara &&
    1550 [ #  # ][ #  # ]:          0 :         pEdit->GetTextLen( rSel.nStartPara ) == 0;
                 [ #  # ]
    1551                 :            : }
    1552                 :            : 
    1553                 :            : 
    1554                 :          0 : void ScHTMLLayoutParser::FontOn( ImportInfo* pInfo )
    1555                 :            : {
    1556         [ #  # ]:          0 :     if ( IsAtBeginningOfText( pInfo ) )
    1557                 :            :     {   // nur am Anfang des Textes, gilt dann fuer gesamte Zelle
    1558                 :          0 :         const HTMLOptions& rOptions = static_cast<HTMLParser*>(pInfo->pParser)->GetOptions();
    1559         [ #  # ]:          0 :         for (size_t i = 0, n = rOptions.size(); i < n; ++i)
    1560                 :            :         {
    1561                 :          0 :             const HTMLOption& rOption = rOptions[i];
    1562   [ #  #  #  # ]:          0 :             switch( rOption.GetToken() )
    1563                 :            :             {
    1564                 :            :                 case HTML_O_FACE :
    1565                 :            :                 {
    1566                 :          0 :                     const String& rFace = rOption.GetString();
    1567         [ #  # ]:          0 :                     String aFontName;
    1568                 :          0 :                     xub_StrLen nPos = 0;
    1569         [ #  # ]:          0 :                     while( nPos != STRING_NOTFOUND )
    1570                 :            :                     {
    1571                 :            :                         // Fontliste, VCL: Semikolon als Separator, HTML: Komma
    1572         [ #  # ]:          0 :                         String aFName = rFace.GetToken( 0, ',', nPos );
    1573 [ #  # ][ #  # ]:          0 :                         aFName = comphelper::string::strip(aFName, ' ');
                 [ #  # ]
    1574         [ #  # ]:          0 :                         if( aFontName.Len() )
    1575         [ #  # ]:          0 :                             aFontName += ';';
    1576         [ #  # ]:          0 :                         aFontName += aFName;
    1577         [ #  # ]:          0 :                     }
    1578         [ #  # ]:          0 :                     if ( aFontName.Len() )
    1579                 :            :                         pActEntry->aItemSet.Put( SvxFontItem( FAMILY_DONTKNOW,
    1580         [ #  # ]:          0 :                             aFontName, EMPTY_STRING, PITCH_DONTKNOW,
    1581 [ #  # ][ #  # ]:          0 :                             RTL_TEXTENCODING_DONTKNOW, ATTR_FONT ) );
         [ #  # ][ #  # ]
    1582                 :            :                 }
    1583                 :          0 :                 break;
    1584                 :            :                 case HTML_O_SIZE :
    1585                 :            :                 {
    1586                 :          0 :                     sal_uInt16 nSize = (sal_uInt16) rOption.GetNumber();
    1587         [ #  # ]:          0 :                     if ( nSize == 0 )
    1588                 :          0 :                         nSize = 1;
    1589         [ #  # ]:          0 :                     else if ( nSize > SC_HTML_FONTSIZES )
    1590                 :          0 :                         nSize = SC_HTML_FONTSIZES;
    1591                 :            :                     pActEntry->aItemSet.Put( SvxFontHeightItem(
    1592         [ #  # ]:          0 :                         maFontHeights[nSize-1], 100, ATTR_FONT_HEIGHT ) );
    1593                 :            :                 }
    1594                 :          0 :                 break;
    1595                 :            :                 case HTML_O_COLOR :
    1596                 :            :                 {
    1597                 :          0 :                     Color aColor;
    1598         [ #  # ]:          0 :                     rOption.GetColor( aColor );
    1599 [ #  # ][ #  # ]:          0 :                     pActEntry->aItemSet.Put( SvxColorItem( aColor, ATTR_FONT_COLOR ) );
                 [ #  # ]
    1600                 :            :                 }
    1601                 :          0 :                 break;
    1602                 :            :             }
    1603                 :            :         }
    1604                 :            :     }
    1605                 :          0 : }
    1606                 :            : 
    1607                 :            : 
    1608                 :          0 : void ScHTMLLayoutParser::ProcToken( ImportInfo* pInfo )
    1609                 :            : {
    1610                 :          0 :     bool bSetLastToken = true;
    1611   [ #  #  #  #  :          0 :     switch ( pInfo->nToken )
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    1612                 :            :     {
    1613                 :            :         case HTML_META:
    1614                 :            :         {
    1615                 :          0 :             HTMLParser* pParser = static_cast<HTMLParser*>(pInfo->pParser);
    1616                 :            :             uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
    1617 [ #  # ][ #  # ]:          0 :                 mpDoc->GetDocumentShell()->GetModel(), uno::UNO_QUERY_THROW);
    1618                 :            :             pParser->ParseMetaOptions(
    1619         [ #  # ]:          0 :                 xDPS->getDocumentProperties(),
    1620 [ #  # ][ #  # ]:          0 :                 mpDoc->GetDocumentShell()->GetHeaderAttributes() );
                 [ #  # ]
    1621                 :            :         }
    1622                 :          0 :         break;
    1623                 :            :         case HTML_TITLE_ON:
    1624                 :            :         {
    1625                 :          0 :             bInTitle = true;
    1626                 :          0 :             aString = rtl::OUString();
    1627                 :            :         }
    1628                 :          0 :         break;
    1629                 :            :         case HTML_TITLE_OFF:
    1630                 :            :         {
    1631 [ #  # ][ #  # ]:          0 :             if ( bInTitle && !aString.isEmpty() )
                 [ #  # ]
    1632                 :            :             {
    1633                 :            :                 // Leerzeichen von Zeilenumbruechen raus
    1634                 :          0 :                 aString = aString.trim();
    1635                 :            :                 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
    1636                 :            :                     mpDoc->GetDocumentShell()->GetModel(),
    1637 [ #  # ][ #  # ]:          0 :                     uno::UNO_QUERY_THROW);
    1638 [ #  # ][ #  # ]:          0 :                 xDPS->getDocumentProperties()->setTitle(aString);
         [ #  # ][ #  # ]
    1639                 :            :             }
    1640                 :          0 :             bInTitle = false;
    1641                 :            :         }
    1642                 :          0 :         break;
    1643                 :            :         case HTML_TABLE_ON:
    1644                 :            :         {
    1645                 :          0 :             TableOn( pInfo );
    1646                 :            :         }
    1647                 :          0 :         break;
    1648                 :            :         case HTML_COL_ON:
    1649                 :            :         {
    1650                 :          0 :             ColOn( pInfo );
    1651                 :            :         }
    1652                 :          0 :         break;
    1653                 :            :         case HTML_TABLEHEADER_ON:       // oeffnet Zelle
    1654                 :            :         {
    1655         [ #  # ]:          0 :             if ( bInCell )
    1656                 :          0 :                 CloseEntry( pInfo );
    1657                 :            :             // bInCell nicht true setzen, das macht TableDataOn
    1658                 :            :             pActEntry->aItemSet.Put(
    1659         [ #  # ]:          0 :                 SvxWeightItem( WEIGHT_BOLD, ATTR_FONT_WEIGHT) );
    1660                 :            :         }   // fall thru
    1661                 :            :         case HTML_TABLEDATA_ON:         // oeffnet Zelle
    1662                 :            :         {
    1663                 :          0 :             TableDataOn( pInfo );
    1664                 :            :         }
    1665                 :          0 :         break;
    1666                 :            :         case HTML_TABLEHEADER_OFF:
    1667                 :            :         case HTML_TABLEDATA_OFF:        // schliesst Zelle
    1668                 :            :         {
    1669                 :          0 :             TableDataOff( pInfo );
    1670                 :            :         }
    1671                 :          0 :         break;
    1672                 :            :         case HTML_TABLEROW_ON:          // vor erster Zelle in Row
    1673                 :            :         {
    1674                 :          0 :             TableRowOn( pInfo );
    1675                 :            :         }
    1676                 :          0 :         break;
    1677                 :            :         case HTML_TABLEROW_OFF:         // nach letzter Zelle in Row
    1678                 :            :         {
    1679                 :          0 :             TableRowOff( pInfo );
    1680                 :            :         }
    1681                 :          0 :         break;
    1682                 :            :         case HTML_TABLE_OFF:
    1683                 :            :         {
    1684                 :          0 :             TableOff( pInfo );
    1685                 :            :         }
    1686                 :          0 :         break;
    1687                 :            :         case HTML_IMAGE:
    1688                 :            :         {
    1689                 :          0 :             Image( pInfo );
    1690                 :            :         }
    1691                 :          0 :         break;
    1692                 :            :         case HTML_PARABREAK_OFF:
    1693                 :            :         {   // nach einem Image geht es vertikal weiter
    1694         [ #  # ]:          0 :             if ( pActEntry->maImageList.size() > 0 )
    1695                 :          0 :                 pActEntry->maImageList.back().nDir = nVertical;
    1696                 :            :         }
    1697                 :          0 :         break;
    1698                 :            :         case HTML_ANCHOR_ON:
    1699                 :            :         {
    1700                 :          0 :             AnchorOn( pInfo );
    1701                 :            :         }
    1702                 :          0 :         break;
    1703                 :            :         case HTML_FONT_ON :
    1704                 :            :         {
    1705                 :          0 :             FontOn( pInfo );
    1706                 :            :         }
    1707                 :          0 :         break;
    1708                 :            :         case HTML_BIGPRINT_ON :
    1709                 :            :         {
    1710                 :            :             //tpdo: aktuelle Fontgroesse merken und einen groesser
    1711         [ #  # ]:          0 :             if ( IsAtBeginningOfText( pInfo ) )
    1712                 :            :                 pActEntry->aItemSet.Put( SvxFontHeightItem(
    1713         [ #  # ]:          0 :                     maFontHeights[3], 100, ATTR_FONT_HEIGHT ) );
    1714                 :            :         }
    1715                 :          0 :         break;
    1716                 :            :         case HTML_SMALLPRINT_ON :
    1717                 :            :         {
    1718                 :            :             //todo: aktuelle Fontgroesse merken und einen kleiner
    1719         [ #  # ]:          0 :             if ( IsAtBeginningOfText( pInfo ) )
    1720                 :            :                 pActEntry->aItemSet.Put( SvxFontHeightItem(
    1721         [ #  # ]:          0 :                     maFontHeights[0], 100, ATTR_FONT_HEIGHT ) );
    1722                 :            :         }
    1723                 :          0 :         break;
    1724                 :            :         case HTML_BOLD_ON :
    1725                 :            :         case HTML_STRONG_ON :
    1726                 :            :         {
    1727         [ #  # ]:          0 :             if ( IsAtBeginningOfText( pInfo ) )
    1728                 :            :                 pActEntry->aItemSet.Put( SvxWeightItem( WEIGHT_BOLD,
    1729         [ #  # ]:          0 :                     ATTR_FONT_WEIGHT ) );
    1730                 :            :         }
    1731                 :          0 :         break;
    1732                 :            :         case HTML_ITALIC_ON :
    1733                 :            :         case HTML_EMPHASIS_ON :
    1734                 :            :         case HTML_ADDRESS_ON :
    1735                 :            :         case HTML_BLOCKQUOTE_ON :
    1736                 :            :         case HTML_BLOCKQUOTE30_ON :
    1737                 :            :         case HTML_CITIATION_ON :
    1738                 :            :         case HTML_VARIABLE_ON :
    1739                 :            :         {
    1740         [ #  # ]:          0 :             if ( IsAtBeginningOfText( pInfo ) )
    1741                 :            :                 pActEntry->aItemSet.Put( SvxPostureItem( ITALIC_NORMAL,
    1742         [ #  # ]:          0 :                     ATTR_FONT_POSTURE ) );
    1743                 :            :         }
    1744                 :          0 :         break;
    1745                 :            :         case HTML_DEFINSTANCE_ON :
    1746                 :            :         {
    1747         [ #  # ]:          0 :             if ( IsAtBeginningOfText( pInfo ) )
    1748                 :            :             {
    1749                 :            :                 pActEntry->aItemSet.Put( SvxWeightItem( WEIGHT_BOLD,
    1750         [ #  # ]:          0 :                     ATTR_FONT_WEIGHT ) );
    1751                 :            :                 pActEntry->aItemSet.Put( SvxPostureItem( ITALIC_NORMAL,
    1752         [ #  # ]:          0 :                     ATTR_FONT_POSTURE ) );
    1753                 :            :             }
    1754                 :            :         }
    1755                 :          0 :         break;
    1756                 :            :         case HTML_UNDERLINE_ON :
    1757                 :            :         {
    1758         [ #  # ]:          0 :             if ( IsAtBeginningOfText( pInfo ) )
    1759                 :            :                 pActEntry->aItemSet.Put( SvxUnderlineItem( UNDERLINE_SINGLE,
    1760         [ #  # ]:          0 :                     ATTR_FONT_UNDERLINE ) );
    1761                 :            :         }
    1762                 :          0 :         break;
    1763                 :            :         case HTML_TEXTTOKEN:
    1764                 :            :         {
    1765         [ #  # ]:          0 :             if ( bInTitle )
    1766                 :          0 :                 aString += pInfo->aText;
    1767                 :            :         }
    1768                 :          0 :         break;
    1769                 :            :         default:
    1770                 :            :         {   // nLastToken nicht setzen!
    1771                 :          0 :             bSetLastToken = false;
    1772                 :            :         }
    1773                 :            :     }
    1774         [ #  # ]:          0 :     if ( bSetLastToken )
    1775                 :          0 :         nLastToken = pInfo->nToken;
    1776                 :          0 : }
    1777                 :            : 
    1778                 :            : 
    1779                 :            : 
    1780                 :            : // ============================================================================
    1781                 :            : // HTML DATA QUERY PARSER
    1782                 :            : // ============================================================================
    1783                 :            : 
    1784                 :            : template< typename Type >
    1785                 :          0 : inline Type getLimitedValue( const Type& rValue, const Type& rMin, const Type& rMax )
    1786                 :          0 : { return ::std::max( ::std::min( rValue, rMax ), rMin ); }
    1787                 :            : 
    1788                 :         84 : ScHTMLEntry::ScHTMLEntry( const SfxItemSet& rItemSet, ScHTMLTableId nTableId ) :
    1789                 :            :     ScEEParseEntry( rItemSet ),
    1790                 :         84 :     mbImportAlways( false )
    1791                 :            : {
    1792                 :         84 :     nTab = nTableId;
    1793                 :         84 :     bEntirePara = false;
    1794                 :         84 : }
    1795                 :            : 
    1796                 :        120 : bool ScHTMLEntry::HasContents() const
    1797                 :            : {
    1798 [ +  - ][ +  + ]:        120 :      return mbImportAlways || aSel.HasRange() || !aAltText.isEmpty() || IsTable();
         [ +  - ][ +  + ]
    1799                 :            : }
    1800                 :            : 
    1801                 :         21 : void ScHTMLEntry::AdjustStart( const ImportInfo& rInfo )
    1802                 :            : {
    1803                 :            :     // set start position
    1804                 :         21 :     aSel.nStartPara = rInfo.aSelection.nStartPara;
    1805                 :         21 :     aSel.nStartPos = rInfo.aSelection.nStartPos;
    1806                 :            :     // adjust end position
    1807 [ +  - ][ +  - ]:         21 :     if( (aSel.nEndPara < aSel.nStartPara) || ((aSel.nEndPara == aSel.nStartPara) && (aSel.nEndPos < aSel.nStartPos)) )
                 [ -  + ]
    1808                 :            :     {
    1809                 :          0 :         aSel.nEndPara = aSel.nStartPara;
    1810                 :          0 :         aSel.nEndPos = aSel.nStartPos;
    1811                 :            :     }
    1812                 :         21 : }
    1813                 :            : 
    1814                 :         96 : void ScHTMLEntry::AdjustEnd( const ImportInfo& rInfo )
    1815                 :            : {
    1816                 :            :     OSL_ENSURE( (aSel.nEndPara < rInfo.aSelection.nEndPara) ||
    1817                 :            :                 ((aSel.nEndPara == rInfo.aSelection.nEndPara) && (aSel.nEndPos <= rInfo.aSelection.nEndPos)),
    1818                 :            :                 "ScHTMLQueryParser::AdjustEntryEnd - invalid end position" );
    1819                 :            :     // set end position
    1820                 :         96 :     aSel.nEndPara = rInfo.aSelection.nEndPara;
    1821                 :         96 :     aSel.nEndPos = rInfo.aSelection.nEndPos;
    1822                 :         96 : }
    1823                 :            : 
    1824                 :         78 : void ScHTMLEntry::Strip( const EditEngine& rEditEngine )
    1825                 :            : {
    1826                 :            :     // strip leading empty paragraphs
    1827 [ +  + ][ +  - ]:         96 :     while( (aSel.nStartPara < aSel.nEndPara) && (rEditEngine.GetTextLen( aSel.nStartPara ) <= aSel.nStartPos) )
                 [ +  + ]
    1828                 :            :     {
    1829                 :         18 :         ++aSel.nStartPara;
    1830                 :         18 :         aSel.nStartPos = 0;
    1831                 :            :     }
    1832                 :            :     // strip trailing empty paragraphs
    1833 [ -  + ][ #  # ]:         78 :     while( (aSel.nStartPara < aSel.nEndPara) && (aSel.nEndPos == 0) )
                 [ -  + ]
    1834                 :            :     {
    1835                 :          0 :         --aSel.nEndPara;
    1836                 :          0 :         aSel.nEndPos = rEditEngine.GetTextLen( aSel.nEndPara );
    1837                 :            :     }
    1838                 :         78 : }
    1839                 :            : 
    1840                 :            : // ============================================================================
    1841                 :            : 
    1842                 :            : /** A map of ScHTMLTable objects.
    1843                 :            : 
    1844                 :            :     Organizes the tables with a unique table key. Stores nested tables inside
    1845                 :            :     the parent table and forms in this way a tree structure of tables. An
    1846                 :            :     instance of this class ownes the contained table objects and deletes them
    1847                 :            :     on destruction.
    1848                 :            :  */
    1849                 :            : class ScHTMLTableMap
    1850                 :            : {
    1851                 :            : private:
    1852                 :            :     typedef ::boost::shared_ptr< ScHTMLTable >          ScHTMLTablePtr;
    1853                 :            :     typedef ::std::map< ScHTMLTableId, ScHTMLTablePtr > ScHTMLTableStdMap;
    1854                 :            : 
    1855                 :            : public:
    1856                 :            :     typedef ScHTMLTableStdMap::iterator             iterator;
    1857                 :            :     typedef ScHTMLTableStdMap::const_iterator       const_iterator;
    1858                 :            : 
    1859                 :            : private:
    1860                 :            :     ScHTMLTable&        mrParentTable;      /// Reference to parent table.
    1861                 :            :     ScHTMLTableStdMap   maTables;           /// Container for all table objects.
    1862                 :            :     mutable ScHTMLTable* mpCurrTable;       /// Current table, used for fast search.
    1863                 :            : 
    1864                 :            : public:
    1865                 :            :     explicit            ScHTMLTableMap( ScHTMLTable& rParentTable );
    1866                 :            :     virtual             ~ScHTMLTableMap();
    1867                 :            : 
    1868                 :            :     inline iterator     begin() { return maTables.begin(); }
    1869                 :         12 :     inline const_iterator begin() const { return maTables.begin(); }
    1870                 :            :     inline iterator     end() { return maTables.end(); }
    1871                 :         12 :     inline const_iterator end() const { return maTables.end(); }
    1872                 :            :     inline bool         empty() const { return maTables.empty(); }
    1873                 :            : 
    1874                 :            :     /** Returns the specified table.
    1875                 :            :         @param nTableId  Unique identifier of the table.
    1876                 :            :         @param bDeep  true = searches deep in all nested table; false = only in this container. */
    1877                 :            :     ScHTMLTable*        FindTable( ScHTMLTableId nTableId, bool bDeep = true ) const;
    1878                 :            : 
    1879                 :            :     /** Inserts a new table into the container. This container owns the created table.
    1880                 :            :         @param bPreFormText  true = New table is based on preformatted text (<pre> tag). */
    1881                 :            :     ScHTMLTable*        CreateTable( const ImportInfo& rInfo, bool bPreFormText );
    1882                 :            : 
    1883                 :            : private:
    1884                 :            :     /** Sets a working table with its index for search optimization. */
    1885                 :         15 :     inline void         SetCurrTable( ScHTMLTable* pTable ) const
    1886         [ +  + ]:         15 :                             { if( pTable ) mpCurrTable = pTable; }
    1887                 :            : };
    1888                 :            : 
    1889                 :            : // ----------------------------------------------------------------------------
    1890                 :            : 
    1891                 :          3 : ScHTMLTableMap::ScHTMLTableMap( ScHTMLTable& rParentTable ) :
    1892                 :            :     mrParentTable(rParentTable),
    1893                 :          3 :     mpCurrTable(NULL)
    1894                 :            : {
    1895                 :          3 : }
    1896                 :            : 
    1897                 :          3 : ScHTMLTableMap::~ScHTMLTableMap()
    1898                 :            : {
    1899         [ -  + ]:          6 : }
    1900                 :            : 
    1901                 :         12 : ScHTMLTable* ScHTMLTableMap::FindTable( ScHTMLTableId nTableId, bool bDeep ) const
    1902                 :            : {
    1903                 :         12 :     ScHTMLTable* pResult = 0;
    1904 [ +  - ][ +  + ]:         12 :     if( mpCurrTable && (nTableId == mpCurrTable->GetTableId()) )
                 [ +  + ]
    1905                 :          9 :         pResult = mpCurrTable;              // cached table
    1906                 :            :     else
    1907                 :            :     {
    1908         [ +  - ]:          3 :         const_iterator aFind = maTables.find( nTableId );
    1909         [ -  + ]:          3 :         if( aFind != maTables.end() )
    1910                 :          3 :             pResult = aFind->second.get();  // table from this container
    1911                 :            :     }
    1912                 :            : 
    1913                 :            :     // not found -> search deep in nested tables
    1914 [ +  + ][ +  - ]:         12 :     if( !pResult && bDeep )
    1915 [ +  - ][ +  + ]:          6 :         for( const_iterator aIter = begin(), aEnd = end(); !pResult && (aIter != aEnd); ++aIter )
                 [ +  + ]
    1916         [ +  - ]:          3 :             pResult = aIter->second->FindNestedTable( nTableId );
    1917                 :            : 
    1918                 :         12 :     SetCurrTable( pResult );
    1919                 :         12 :     return pResult;
    1920                 :            : }
    1921                 :            : 
    1922                 :          3 : ScHTMLTable* ScHTMLTableMap::CreateTable( const ImportInfo& rInfo, bool bPreFormText )
    1923                 :            : {
    1924         [ +  - ]:          3 :     ScHTMLTable* pTable = new ScHTMLTable( mrParentTable, rInfo, bPreFormText );
    1925 [ +  - ][ +  - ]:          3 :     maTables[ pTable->GetTableId() ].reset( pTable );
    1926                 :          3 :     SetCurrTable( pTable );
    1927                 :          3 :     return pTable;
    1928                 :            : }
    1929                 :            : 
    1930                 :            : // ----------------------------------------------------------------------------
    1931                 :            : 
    1932                 :            : /** Simplified forward iterator for convenience.
    1933                 :            : 
    1934                 :            :     Before the iterator can be dereferenced, it must be tested with the is()
    1935                 :            :     method. The iterator may be invalid directly after construction (e.g. empty
    1936                 :            :     container).
    1937                 :            :  */
    1938                 :            : class ScHTMLTableIterator
    1939                 :            : {
    1940                 :            : public:
    1941                 :            :     /** Constructs the iterator for the passed table map.
    1942                 :            :         @param pTableMap  Pointer to the table map (is allowed to be NULL). */
    1943                 :            :     explicit            ScHTMLTableIterator( const ScHTMLTableMap* pTableMap );
    1944                 :            : 
    1945 [ +  + ][ +  + ]:         27 :     inline bool         is() const { return mpTableMap && maIter != maEnd; }
    1946                 :          9 :     inline ScHTMLTable* operator->() { return maIter->second.get(); }
    1947                 :            :     inline ScHTMLTable& operator*() { return *maIter->second; }
    1948                 :          9 :     inline ScHTMLTableIterator& operator++() { ++maIter; return *this; }
    1949                 :            : 
    1950                 :            : private:
    1951                 :            :     ScHTMLTableMap::const_iterator maIter;
    1952                 :            :     ScHTMLTableMap::const_iterator maEnd;
    1953                 :            :     const ScHTMLTableMap* mpTableMap;
    1954                 :            : };
    1955                 :            : 
    1956                 :         18 : ScHTMLTableIterator::ScHTMLTableIterator( const ScHTMLTableMap* pTableMap ) :
    1957                 :         18 :     mpTableMap(pTableMap)
    1958                 :            : {
    1959         [ +  + ]:         18 :     if( pTableMap )
    1960                 :            :     {
    1961                 :          9 :         maIter = pTableMap->begin();
    1962                 :          9 :         maEnd = pTableMap->end();
    1963                 :            :     }
    1964                 :         18 : }
    1965                 :            : 
    1966                 :            : // ============================================================================
    1967                 :            : 
    1968                 :          6 : ScHTMLTableAutoId::ScHTMLTableAutoId( ScHTMLTableId& rnUnusedId ) :
    1969                 :            :     mnTableId( rnUnusedId ),
    1970                 :          6 :     mrnUnusedId( rnUnusedId )
    1971                 :            : {
    1972                 :          6 :     ++mrnUnusedId;
    1973                 :          6 : }
    1974                 :            : 
    1975                 :            : // ----------------------------------------------------------------------------
    1976                 :            : 
    1977                 :          3 : ScHTMLTable::ScHTMLTable( ScHTMLTable& rParentTable, const ImportInfo& rInfo, bool bPreFormText ) :
    1978                 :            :     mpParentTable( &rParentTable ),
    1979                 :            :     maTableId( rParentTable.maTableId.mrnUnusedId ),
    1980                 :          3 :     maTableItemSet( rParentTable.GetCurrItemSet() ),
    1981                 :            :     mrEditEngine( rParentTable.mrEditEngine ),
    1982                 :            :     mrEEParseList( rParentTable.mrEEParseList ),
    1983                 :            :     mpCurrEntryList( 0 ),
    1984                 :            :     maSize( 1, 1 ),
    1985                 :            :     mpParser(rParentTable.mpParser),
    1986                 :            :     mbBorderOn( false ),
    1987                 :            :     mbPreFormText( bPreFormText ),
    1988                 :            :     mbRowOn( false ),
    1989                 :            :     mbDataOn( false ),
    1990 [ +  - ][ +  - ]:         12 :     mbPushEmptyLine( false )
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  + ]
           [ #  #  #  # ]
    1991                 :            : {
    1992         [ -  + ]:          3 :     if( mbPreFormText )
    1993                 :            :     {
    1994         [ #  # ]:          0 :         ImplRowOn();
    1995         [ #  # ]:          0 :         ImplDataOn( ScHTMLSize( 1, 1 ) );
    1996                 :            :     }
    1997                 :            :     else
    1998                 :            :     {
    1999         [ +  - ]:          3 :         ProcessFormatOptions( maTableItemSet, rInfo );
    2000         [ +  - ]:          3 :         const HTMLOptions& rOptions = static_cast<HTMLParser*>(rInfo.pParser)->GetOptions();
    2001 [ +  - ][ +  - ]:          3 :         HTMLOptions::const_iterator itr = rOptions.begin(), itrEnd = rOptions.end();
    2002 [ #  # ][ +  - ]:          3 :         for (; itr != itrEnd; ++itr)
                 [ -  + ]
    2003                 :            :         {
    2004         [ #  # ]:          0 :             switch( itr->GetToken() )
              [ #  #  # ]
    2005                 :            :             {
    2006                 :            :                 case HTML_O_BORDER:
    2007 [ #  # ][ #  # ]:          0 :                     mbBorderOn = ((itr->GetString().Len() == 0) || (itr->GetNumber() != 0));
         [ #  # ][ #  # ]
                 [ #  # ]
    2008                 :          0 :                 break;
    2009                 :            :                 case HTML_O_ID:
    2010 [ #  # ][ #  # ]:          0 :                     maTableName = itr->GetString();
    2011                 :          0 :                 break;
    2012                 :            :             }
    2013                 :            :         }
    2014                 :            :     }
    2015                 :            : 
    2016         [ +  - ]:          3 :     CreateNewEntry( rInfo );
    2017   [ #  #  #  # ]:          3 : }
    2018                 :            : 
    2019                 :          3 : ScHTMLTable::ScHTMLTable(
    2020                 :            :     SfxItemPool& rPool,
    2021                 :            :     EditEngine& rEditEngine,
    2022                 :            :     ::std::vector< ScEEParseEntry* >& rEEParseList,
    2023                 :            :     ScHTMLTableId& rnUnusedId, ScHTMLParser* pParser
    2024                 :            : ) :
    2025                 :            :     mpParentTable( 0 ),
    2026                 :            :     maTableId( rnUnusedId ),
    2027                 :            :     maTableItemSet( rPool ),
    2028                 :            :     mrEditEngine( rEditEngine ),
    2029                 :            :     mrEEParseList( rEEParseList ),
    2030                 :            :     mpCurrEntryList( 0 ),
    2031                 :            :     maSize( 1, 1 ),
    2032                 :            :     mpParser(pParser),
    2033                 :            :     mbBorderOn( false ),
    2034                 :            :     mbPreFormText( false ),
    2035                 :            :     mbRowOn( false ),
    2036                 :            :     mbDataOn( false ),
    2037 [ +  - ][ +  - ]:          9 :     mbPushEmptyLine( false )
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  + ]
           [ #  #  #  # ]
    2038                 :            : {
    2039                 :            :     // open the first "cell" of the document
    2040         [ +  - ]:          3 :     ImplRowOn();
    2041         [ +  - ]:          3 :     ImplDataOn( ScHTMLSize( 1, 1 ) );
    2042 [ +  - ][ +  - ]:          3 :     mxCurrEntry = CreateEntry();
    2043   [ #  #  #  # ]:          3 : }
    2044                 :            : 
    2045 [ +  - ][ +  - ]:         18 : ScHTMLTable::~ScHTMLTable()
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
    2046                 :            : {
    2047         [ +  - ]:         27 : }
           [ +  +  -  + ]
    2048                 :            : 
    2049                 :         84 : const SfxItemSet& ScHTMLTable::GetCurrItemSet() const
    2050                 :            : {
    2051                 :            :     // first try cell item set, then row item set, then table item set
    2052 [ +  + ][ +  + ]:         84 :     return mxDataItemSet.get() ? *mxDataItemSet : (mxRowItemSet.get() ? *mxRowItemSet : maTableItemSet);
    2053                 :            : }
    2054                 :            : 
    2055                 :         63 : ScHTMLSize ScHTMLTable::GetSpan( const ScHTMLPos& rCellPos ) const
    2056                 :            : {
    2057                 :         63 :     ScHTMLSize aSpan( 1, 1 );
    2058                 :         63 :     const ScRange* pRange = NULL;
    2059   [ +  -  +  - ]:        189 :     if(  ( (pRange = maVMergedCells.Find( rCellPos.MakeAddr() ) ) != 0)
         [ -  + ][ +  - ]
           [ -  +  #  # ]
                 [ +  - ]
    2060 [ +  - ][ #  # ]:        126 :       || ( (pRange = maHMergedCells.Find( rCellPos.MakeAddr() ) ) != 0)
    2061                 :            :       )
    2062                 :          0 :         aSpan.Set( pRange->aEnd.Col() - pRange->aStart.Col() + 1, pRange->aEnd.Row() - pRange->aStart.Row() + 1 );
    2063                 :         63 :     return aSpan;
    2064                 :            : }
    2065                 :            : 
    2066                 :          9 : ScHTMLTable* ScHTMLTable::FindNestedTable( ScHTMLTableId nTableId ) const
    2067                 :            : {
    2068         [ +  + ]:          9 :     return mxNestedTables.get() ? mxNestedTables->FindTable( nTableId, true ) : 0;
    2069                 :            : }
    2070                 :            : 
    2071                 :          0 : void ScHTMLTable::PutItem( const SfxPoolItem& rItem )
    2072                 :            : {
    2073                 :            :     OSL_ENSURE( mxCurrEntry.get(), "ScHTMLTable::PutItem - no current entry" );
    2074 [ #  # ][ #  # ]:          0 :     if( mxCurrEntry.get() && mxCurrEntry->IsEmpty() )
                 [ #  # ]
    2075                 :          0 :         mxCurrEntry->GetItemSet().Put( rItem );
    2076                 :          0 : }
    2077                 :            : 
    2078                 :         39 : void ScHTMLTable::PutText( const ImportInfo& rInfo )
    2079                 :            : {
    2080                 :            :     OSL_ENSURE( mxCurrEntry.get(), "ScHTMLTable::PutText - no current entry" );
    2081         [ +  - ]:         39 :     if( mxCurrEntry.get() )
    2082                 :            :     {
    2083 [ +  - ][ +  + ]:         39 :         if( !mxCurrEntry->HasContents() && IsSpaceCharInfo( rInfo ) )
                 [ +  + ]
    2084                 :         21 :             mxCurrEntry->AdjustStart( rInfo );
    2085                 :            :         else
    2086                 :         18 :             mxCurrEntry->AdjustEnd( rInfo );
    2087                 :            :     }
    2088                 :         39 : }
    2089                 :            : 
    2090                 :         18 : void ScHTMLTable::InsertPara( const ImportInfo& rInfo )
    2091                 :            : {
    2092 [ +  - ][ +  - ]:         18 :     if( mxCurrEntry.get() && mbDataOn && !IsEmptyCell() )
         [ -  + ][ -  + ]
    2093                 :          0 :         mxCurrEntry->SetImportAlways();
    2094                 :         18 :     PushEntry( rInfo );
    2095                 :         18 :     CreateNewEntry( rInfo );
    2096                 :         18 :     InsertLeadingEmptyLine();
    2097                 :         18 : }
    2098                 :            : 
    2099                 :          0 : void ScHTMLTable::BreakOn()
    2100                 :            : {
    2101                 :            :     // empty line, if <br> is at start of cell
    2102 [ #  # ][ #  # ]:          0 :     mbPushEmptyLine = !mbPreFormText && mbDataOn && IsEmptyCell();
                 [ #  # ]
    2103                 :          0 : }
    2104                 :            : 
    2105                 :          0 : void ScHTMLTable::HeadingOn()
    2106                 :            : {
    2107                 :            :     // call directly, InsertPara() has not been called before
    2108                 :          0 :     InsertLeadingEmptyLine();
    2109                 :          0 : }
    2110                 :            : 
    2111                 :         18 : void ScHTMLTable::InsertLeadingEmptyLine()
    2112                 :            : {
    2113                 :            :     // empty line, if <p>, </p>, <h?>, or </h*> are not at start of cell
    2114 [ +  - ][ +  - ]:         18 :     mbPushEmptyLine = !mbPreFormText && mbDataOn && !IsEmptyCell();
                 [ +  - ]
    2115                 :         18 : }
    2116                 :            : 
    2117                 :          0 : void ScHTMLTable::AnchorOn()
    2118                 :            : {
    2119                 :            :     OSL_ENSURE( mxCurrEntry.get(), "ScHTMLTable::AnchorOn - no current entry" );
    2120                 :            :     // don't skip entries with single hyperlinks
    2121         [ #  # ]:          0 :     if( mxCurrEntry.get() )
    2122                 :          0 :         mxCurrEntry->SetImportAlways();
    2123                 :          0 : }
    2124                 :            : 
    2125                 :          3 : ScHTMLTable* ScHTMLTable::TableOn( const ImportInfo& rInfo )
    2126                 :            : {
    2127                 :          3 :     PushEntry( rInfo );
    2128                 :          3 :     return InsertNestedTable( rInfo, false );
    2129                 :            : }
    2130                 :            : 
    2131                 :          3 : ScHTMLTable* ScHTMLTable::TableOff( const ImportInfo& rInfo )
    2132                 :            : {
    2133         [ -  + ]:          3 :     return mbPreFormText ? this : CloseTable( rInfo );
    2134                 :            : }
    2135                 :            : 
    2136                 :          0 : ScHTMLTable* ScHTMLTable::PreOn( const ImportInfo& rInfo )
    2137                 :            : {
    2138                 :          0 :     PushEntry( rInfo );
    2139                 :          0 :     return InsertNestedTable( rInfo, true );
    2140                 :            : }
    2141                 :            : 
    2142                 :          0 : ScHTMLTable* ScHTMLTable::PreOff( const ImportInfo& rInfo )
    2143                 :            : {
    2144         [ #  # ]:          0 :     return mbPreFormText ? CloseTable( rInfo ) : this;
    2145                 :            : }
    2146                 :            : 
    2147                 :          6 : void ScHTMLTable::RowOn( const ImportInfo& rInfo )
    2148                 :            : {
    2149                 :          6 :     PushEntry( rInfo, true );
    2150 [ +  - ][ +  - ]:          6 :     if( mpParentTable && !mbPreFormText )   // no rows allowed in global and preformatted tables
    2151                 :            :     {
    2152                 :          6 :         ImplRowOn();
    2153                 :          6 :         ProcessFormatOptions( *mxRowItemSet, rInfo );
    2154                 :            :     }
    2155                 :          6 :     CreateNewEntry( rInfo );
    2156                 :          6 : }
    2157                 :            : 
    2158                 :          6 : void ScHTMLTable::RowOff( const ImportInfo& rInfo )
    2159                 :            : {
    2160                 :          6 :     PushEntry( rInfo, true );
    2161 [ +  - ][ +  - ]:          6 :     if( mpParentTable && !mbPreFormText )   // no rows allowed in global and preformatted tables
    2162                 :          6 :         ImplRowOff();
    2163                 :          6 :     CreateNewEntry( rInfo );
    2164                 :          6 : }
    2165                 :            : 
    2166                 :            : namespace {
    2167                 :            : 
    2168                 :            : /**
    2169                 :            :  * Decode a numbert format string stored in Excel-generated HTML's CSS
    2170                 :            :  * region.
    2171                 :            :  */
    2172                 :          0 : rtl::OUString decodeNumberFormat(const rtl::OUString& rFmt)
    2173                 :            : {
    2174                 :          0 :     rtl::OUStringBuffer aBuf;
    2175                 :          0 :     const sal_Unicode* p = rFmt.getStr();
    2176                 :          0 :     sal_Int32 n = rFmt.getLength();
    2177         [ #  # ]:          0 :     for (sal_Int32 i = 0; i < n; ++i, ++p)
    2178                 :            :     {
    2179         [ #  # ]:          0 :         if (*p == '\\')
    2180                 :            :         {
    2181                 :            :             // Skip '\'.
    2182                 :          0 :             ++i;
    2183                 :          0 :             ++p;
    2184                 :            : 
    2185                 :            :             // Parse all subsequent digits until first non-digit is found.
    2186                 :          0 :             sal_Int32 nDigitCount = 0;
    2187                 :          0 :             const sal_Unicode* p1 = p;
    2188         [ #  # ]:          0 :             for (; i < n; ++i, ++p, ++nDigitCount)
    2189                 :            :             {
    2190 [ #  # ][ #  # ]:          0 :                 if (*p < '0' || '9' < *p)
    2191                 :            :                 {
    2192                 :          0 :                     --i;
    2193                 :          0 :                     --p;
    2194                 :          0 :                     break;
    2195                 :            :                 }
    2196                 :            : 
    2197                 :            :             }
    2198         [ #  # ]:          0 :             if (nDigitCount)
    2199                 :            :             {
    2200                 :          0 :                 sal_Int32 nVal = rtl::OUString(p1, nDigitCount).toInt32(16);
    2201         [ #  # ]:          0 :                 aBuf.append(static_cast<sal_Unicode>(nVal));
    2202                 :            :             }
    2203                 :            :         }
    2204                 :            :         else
    2205         [ #  # ]:          0 :             aBuf.append(*p);
    2206                 :            :     }
    2207         [ #  # ]:          0 :     return aBuf.makeStringAndClear();
    2208                 :            : }
    2209                 :            : 
    2210                 :            : }
    2211                 :            : 
    2212                 :         18 : void ScHTMLTable::DataOn( const ImportInfo& rInfo )
    2213                 :            : {
    2214                 :         18 :     PushEntry( rInfo, true );
    2215 [ +  - ][ +  - ]:         18 :     if( mpParentTable && !mbPreFormText )   // no cells allowed in global and preformatted tables
    2216                 :            :     {
    2217                 :            :         // read needed options from the <td> tag
    2218                 :         18 :         ScHTMLSize aSpanSize( 1, 1 );
    2219                 :            :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
    2220                 :         18 :         ::std::auto_ptr<rtl::OUString> pValStr, pNumStr;
    2221                 :            :         SAL_WNODEPRECATED_DECLARATIONS_POP
    2222         [ +  - ]:         18 :         const HTMLOptions& rOptions = static_cast<HTMLParser*>(rInfo.pParser)->GetOptions();
    2223 [ +  - ][ +  - ]:         18 :         HTMLOptions::const_iterator itr = rOptions.begin(), itrEnd = rOptions.end();
    2224                 :         18 :         sal_uInt32 nNumberFormat = NUMBERFORMAT_ENTRY_NOT_FOUND;
    2225 [ #  # ][ +  - ]:         18 :         for (; itr != itrEnd; ++itr)
                 [ -  + ]
    2226                 :            :         {
    2227 [ #  # ][ #  #  :          0 :             switch (itr->GetToken())
             #  #  #  # ]
    2228                 :            :             {
    2229                 :            :                 case HTML_O_COLSPAN:
    2230 [ #  # ][ #  # ]:          0 :                     aSpanSize.mnCols = static_cast<SCCOL>( getLimitedValue<sal_Int32>( itr->GetString().ToInt32(), 1, 256 ) );
                 [ #  # ]
    2231                 :          0 :                 break;
    2232                 :            :                 case HTML_O_ROWSPAN:
    2233 [ #  # ][ #  # ]:          0 :                     aSpanSize.mnRows = static_cast<SCROW>( getLimitedValue<sal_Int32>( itr->GetString().ToInt32(), 1, 256 ) );
                 [ #  # ]
    2234                 :          0 :                 break;
    2235                 :            :                 case HTML_O_SDVAL:
    2236 [ #  # ][ #  # ]:          0 :                     pValStr.reset(new rtl::OUString(itr->GetString()));
                 [ #  # ]
    2237                 :          0 :                 break;
    2238                 :            :                 case HTML_O_SDNUM:
    2239 [ #  # ][ #  # ]:          0 :                     pNumStr.reset(new rtl::OUString(itr->GetString()));
                 [ #  # ]
    2240                 :          0 :                 break;
    2241                 :            :                 case HTML_O_CLASS:
    2242                 :            :                 {
    2243                 :            :                     // Pick up the number format associated with this class (if
    2244                 :            :                     // any).
    2245         [ #  # ]:          0 :                     rtl::OUString aElem(RTL_CONSTASCII_USTRINGPARAM("td"));
    2246 [ #  # ][ #  # ]:          0 :                     rtl::OUString aClass = itr->GetString();
    2247         [ #  # ]:          0 :                     rtl::OUString aProp(RTL_CONSTASCII_USTRINGPARAM("mso-number-format"));
    2248                 :          0 :                     const ScHTMLStyles& rStyles = mpParser->GetStyles();
    2249         [ #  # ]:          0 :                     const rtl::OUString& rVal = rStyles.getPropertyValue(aElem, aClass, aProp);
    2250         [ #  # ]:          0 :                     rtl::OUString aNumFmt = decodeNumberFormat(rVal);
    2251                 :            : 
    2252 [ #  # ][ #  # ]:          0 :                     nNumberFormat = GetFormatTable()->GetEntryKey(aNumFmt);
         [ #  # ][ #  # ]
    2253         [ #  # ]:          0 :                     if (nNumberFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
    2254                 :            :                     {
    2255                 :          0 :                         xub_StrLen nErrPos  = 0;
    2256                 :            :                         short nDummy;
    2257 [ #  # ][ #  # ]:          0 :                         bool bValidFmt = GetFormatTable()->PutEntry(aNumFmt, nErrPos, nDummy, nNumberFormat);
    2258         [ #  # ]:          0 :                         if (!bValidFmt)
    2259                 :          0 :                             nNumberFormat = NUMBERFORMAT_ENTRY_NOT_FOUND;
    2260                 :          0 :                     }
    2261                 :            :                 }
    2262                 :          0 :                 break;
    2263                 :            :             }
    2264                 :            :         }
    2265                 :            : 
    2266         [ +  - ]:         18 :         ImplDataOn( aSpanSize );
    2267                 :            : 
    2268         [ -  + ]:         18 :         if (nNumberFormat != NUMBERFORMAT_ENTRY_NOT_FOUND)
    2269 [ #  # ][ #  # ]:          0 :             mxDataItemSet->Put( SfxUInt32Item(ATTR_VALUE_FORMAT, nNumberFormat) );
                 [ #  # ]
    2270                 :            : 
    2271         [ +  - ]:         18 :         ProcessFormatOptions( *mxDataItemSet, rInfo );
    2272         [ +  - ]:         18 :         CreateNewEntry( rInfo );
    2273                 :         18 :         mxCurrEntry->pValStr = pValStr.release();
    2274                 :         18 :         mxCurrEntry->pNumStr = pNumStr.release();
    2275                 :            :     }
    2276                 :            :     else
    2277                 :          0 :         CreateNewEntry( rInfo );
    2278                 :         18 : }
    2279                 :            : 
    2280                 :         18 : void ScHTMLTable::DataOff( const ImportInfo& rInfo )
    2281                 :            : {
    2282                 :         18 :     PushEntry( rInfo, true );
    2283 [ +  - ][ +  - ]:         18 :     if( mpParentTable && !mbPreFormText )   // no cells allowed in global and preformatted tables
    2284                 :         18 :         ImplDataOff();
    2285                 :         18 :     CreateNewEntry( rInfo );
    2286                 :         18 : }
    2287                 :            : 
    2288                 :          3 : void ScHTMLTable::BodyOn( const ImportInfo& rInfo )
    2289                 :            : {
    2290                 :          3 :     bool bPushed = PushEntry( rInfo );
    2291         [ +  - ]:          3 :     if( !mpParentTable )
    2292                 :            :     {
    2293                 :            :         // do not start new row, if nothing (no title) precedes the body.
    2294 [ +  - ][ -  + ]:          3 :         if( bPushed || !mbRowOn )
    2295                 :          0 :             ImplRowOn();
    2296 [ +  - ][ -  + ]:          3 :         if( bPushed || !mbDataOn )
    2297         [ #  # ]:          0 :             ImplDataOn( ScHTMLSize( 1, 1 ) );
    2298                 :          3 :         ProcessFormatOptions( *mxDataItemSet, rInfo );
    2299                 :            :     }
    2300                 :          3 :     CreateNewEntry( rInfo );
    2301                 :          3 : }
    2302                 :            : 
    2303                 :          3 : void ScHTMLTable::BodyOff( const ImportInfo& rInfo )
    2304                 :            : {
    2305                 :          3 :     PushEntry( rInfo );
    2306         [ +  - ]:          3 :     if( !mpParentTable )
    2307                 :            :     {
    2308                 :          3 :         ImplDataOff();
    2309                 :          3 :         ImplRowOff();
    2310                 :            :     }
    2311                 :          3 :     CreateNewEntry( rInfo );
    2312                 :          3 : }
    2313                 :            : 
    2314                 :          3 : ScHTMLTable* ScHTMLTable::CloseTable( const ImportInfo& rInfo )
    2315                 :            : {
    2316         [ +  - ]:          3 :     if( mpParentTable )     // not allowed to close global table
    2317                 :            :     {
    2318                 :          3 :         PushEntry( rInfo, mbDataOn );
    2319                 :          3 :         ImplDataOff();
    2320                 :          3 :         ImplRowOff();
    2321                 :          3 :         mpParentTable->PushTableEntry( GetTableId() );
    2322                 :          3 :         mpParentTable->CreateNewEntry( rInfo );
    2323         [ -  + ]:          3 :         if( mbPreFormText ) // enclose preformatted table with empty lines in parent table
    2324                 :          0 :             mpParentTable->InsertLeadingEmptyLine();
    2325                 :          3 :         return mpParentTable;
    2326                 :            :     }
    2327                 :          3 :     return this;
    2328                 :            : }
    2329                 :            : 
    2330                 :          0 : SCCOLROW ScHTMLTable::GetDocSize( ScHTMLOrient eOrient, SCCOLROW nCellPos ) const
    2331                 :            : {
    2332                 :          0 :     const ScSizeVec& rSizes = maCumSizes[ eOrient ];
    2333                 :          0 :     size_t nIndex = static_cast< size_t >( nCellPos );
    2334         [ #  # ]:          0 :     if( nIndex >= rSizes.size() ) return 0;
    2335         [ #  # ]:          0 :     return (nIndex == 0) ? rSizes.front() : (rSizes[ nIndex ] - rSizes[ nIndex - 1 ]);
    2336                 :            : }
    2337                 :            : 
    2338                 :         84 : SCCOLROW ScHTMLTable::GetDocSize( ScHTMLOrient eOrient, SCCOLROW nCellBegin, SCCOLROW nCellEnd ) const
    2339                 :            : {
    2340                 :         84 :     const ScSizeVec& rSizes = maCumSizes[ eOrient ];
    2341         [ +  - ]:         84 :     size_t nBeginIdx = static_cast< size_t >( ::std::max< SCCOLROW >( nCellBegin, 0 ) );
    2342         [ +  - ]:         84 :     size_t nEndIdx = static_cast< size_t >( ::std::min< SCCOLROW >( nCellEnd, static_cast< SCCOLROW >( rSizes.size() ) ) );
    2343         [ +  + ]:         84 :     if (nBeginIdx >= nEndIdx ) return 0;
    2344         [ +  + ]:         84 :     return rSizes[ nEndIdx - 1 ] - ((nBeginIdx == 0) ? 0 : rSizes[ nBeginIdx - 1 ]);
    2345                 :            : }
    2346                 :            : 
    2347                 :         27 : SCCOLROW ScHTMLTable::GetDocSize( ScHTMLOrient eOrient ) const
    2348                 :            : {
    2349                 :         27 :     const ScSizeVec& rSizes = maCumSizes[ eOrient ];
    2350         [ -  + ]:         27 :     return rSizes.empty() ? 0 : rSizes.back();
    2351                 :            : }
    2352                 :            : 
    2353                 :         21 : ScHTMLSize ScHTMLTable::GetDocSize( const ScHTMLPos& rCellPos ) const
    2354                 :            : {
    2355         [ +  - ]:         21 :     ScHTMLSize aCellSpan = GetSpan( rCellPos );
    2356                 :            :     return ScHTMLSize(
    2357         [ +  - ]:         21 :         static_cast< SCCOL >( GetDocSize( tdCol, rCellPos.mnCol, rCellPos.mnCol + aCellSpan.mnCols ) ),
    2358         [ +  - ]:         42 :         static_cast< SCROW >( GetDocSize( tdRow, rCellPos.mnRow, rCellPos.mnRow + aCellSpan.mnRows ) ) );
    2359                 :            : }
    2360                 :            : 
    2361                 :         42 : SCCOLROW ScHTMLTable::GetDocPos( ScHTMLOrient eOrient, SCCOLROW nCellPos ) const
    2362                 :            : {
    2363                 :         42 :     return maDocBasePos.Get( eOrient ) + GetDocSize( eOrient, 0, nCellPos );
    2364                 :            : }
    2365                 :            : 
    2366                 :         21 : ScHTMLPos ScHTMLTable::GetDocPos( const ScHTMLPos& rCellPos ) const
    2367                 :            : {
    2368                 :            :     return ScHTMLPos(
    2369                 :         21 :         static_cast< SCCOL >( GetDocPos( tdCol, rCellPos.mnCol ) ),
    2370                 :         42 :         static_cast< SCROW >( GetDocPos( tdRow, rCellPos.mnRow ) ) );
    2371                 :            : }
    2372                 :            : 
    2373                 :          3 : void ScHTMLTable::GetDocRange( ScRange& rRange ) const
    2374                 :            : {
    2375                 :          3 :     rRange.aStart = rRange.aEnd = maDocBasePos.MakeAddr();
    2376                 :          3 :     rRange.aEnd.Move( static_cast< SCsCOL >( GetDocSize( tdCol ) ) - 1, static_cast< SCsROW >( GetDocSize( tdRow ) ) - 1, 0 );
    2377                 :          3 : }
    2378                 :            : 
    2379                 :          6 : void ScHTMLTable::ApplyCellBorders( ScDocument* pDoc, const ScAddress& rFirstPos ) const
    2380                 :            : {
    2381                 :            :     OSL_ENSURE( pDoc, "ScHTMLTable::ApplyCellBorders - no document" );
    2382 [ +  - ][ -  + ]:          6 :     if( pDoc && mbBorderOn )
    2383                 :            :     {
    2384                 :          0 :         const SCCOL nLastCol = maSize.mnCols - 1;
    2385                 :          0 :         const SCROW nLastRow = maSize.mnRows - 1;
    2386                 :          0 :         const long nOuterLine = DEF_LINE_WIDTH_2;
    2387                 :          0 :         const long nInnerLine = DEF_LINE_WIDTH_0;
    2388         [ #  # ]:          0 :         SvxBorderLine aOuterLine(0, nOuterLine, table::BorderLineStyle::SOLID);
    2389         [ #  # ]:          0 :         SvxBorderLine aInnerLine(0, nInnerLine, table::BorderLineStyle::SOLID);
    2390         [ #  # ]:          0 :         SvxBoxItem aBorderItem( ATTR_BORDER );
    2391                 :            : 
    2392         [ #  # ]:          0 :         for( SCCOL nCol = 0; nCol <= nLastCol; ++nCol )
    2393                 :            :         {
    2394         [ #  # ]:          0 :             SvxBorderLine* pLeftLine = (nCol == 0) ? &aOuterLine : &aInnerLine;
    2395         [ #  # ]:          0 :             SvxBorderLine* pRightLine = (nCol == nLastCol) ? &aOuterLine : &aInnerLine;
    2396         [ #  # ]:          0 :             SCCOL nCellCol1 = static_cast< SCCOL >( GetDocPos( tdCol, nCol ) ) + rFirstPos.Col();
    2397         [ #  # ]:          0 :             SCCOL nCellCol2 = nCellCol1 + static_cast< SCCOL >( GetDocSize( tdCol, nCol ) ) - 1;
    2398         [ #  # ]:          0 :             for( SCROW nRow = 0; nRow <= nLastRow; ++nRow )
    2399                 :            :             {
    2400         [ #  # ]:          0 :                 SvxBorderLine* pTopLine = (nRow == 0) ? &aOuterLine : &aInnerLine;
    2401         [ #  # ]:          0 :                 SvxBorderLine* pBottomLine = (nRow == nLastRow) ? &aOuterLine : &aInnerLine;
    2402         [ #  # ]:          0 :                 SCROW nCellRow1 = GetDocPos( tdRow, nRow ) + rFirstPos.Row();
    2403         [ #  # ]:          0 :                 SCROW nCellRow2 = nCellRow1 + GetDocSize( tdRow, nRow ) - 1;
    2404         [ #  # ]:          0 :                 for( SCCOL nCellCol = nCellCol1; nCellCol <= nCellCol2; ++nCellCol )
    2405                 :            :                 {
    2406 [ #  # ][ #  # ]:          0 :                     aBorderItem.SetLine( (nCellCol == nCellCol1) ? pLeftLine : 0, BOX_LINE_LEFT );
    2407 [ #  # ][ #  # ]:          0 :                     aBorderItem.SetLine( (nCellCol == nCellCol2) ? pRightLine : 0, BOX_LINE_RIGHT );
    2408         [ #  # ]:          0 :                     for( SCROW nCellRow = nCellRow1; nCellRow <= nCellRow2; ++nCellRow )
    2409                 :            :                     {
    2410 [ #  # ][ #  # ]:          0 :                         aBorderItem.SetLine( (nCellRow == nCellRow1) ? pTopLine : 0, BOX_LINE_TOP );
    2411 [ #  # ][ #  # ]:          0 :                         aBorderItem.SetLine( (nCellRow == nCellRow2) ? pBottomLine : 0, BOX_LINE_BOTTOM );
    2412         [ #  # ]:          0 :                         pDoc->ApplyAttr( nCellCol, nCellRow, rFirstPos.Tab(), aBorderItem );
    2413                 :            :                     }
    2414                 :            :                 }
    2415                 :            :             }
    2416         [ #  # ]:          0 :         }
    2417                 :            :     }
    2418                 :            : 
    2419 [ +  - ][ +  - ]:          9 :     for( ScHTMLTableIterator aIter( mxNestedTables.get() ); aIter.is(); ++aIter )
         [ +  - ][ +  + ]
    2420 [ +  - ][ +  - ]:          3 :         aIter->ApplyCellBorders( pDoc, rFirstPos );
    2421                 :          6 : }
    2422                 :            : 
    2423                 :          0 : SvNumberFormatter* ScHTMLTable::GetFormatTable()
    2424                 :            : {
    2425                 :          0 :     return mpParser->GetDoc().GetFormatTable();
    2426                 :            : }
    2427                 :            : 
    2428                 :            : // ----------------------------------------------------------------------------
    2429                 :            : 
    2430                 :         84 : bool ScHTMLTable::IsEmptyCell() const
    2431                 :            : {
    2432 [ +  + ][ +  + ]:         84 :     return mpCurrEntryList && mpCurrEntryList->empty();
    2433                 :            : }
    2434                 :            : 
    2435                 :         39 : bool ScHTMLTable::IsSpaceCharInfo( const ImportInfo& rInfo )
    2436                 :            : {
    2437 [ +  - ][ +  + ]:         39 :     return (rInfo.nToken == HTML_TEXTTOKEN) && (rInfo.aText.Len() == 1) && (rInfo.aText.GetChar( 0 ) == ' ');
                 [ +  - ]
    2438                 :            : }
    2439                 :            : 
    2440                 :         81 : ScHTMLTable::ScHTMLEntryPtr ScHTMLTable::CreateEntry() const
    2441                 :            : {
    2442         [ +  - ]:         81 :     return ScHTMLEntryPtr( new ScHTMLEntry( GetCurrItemSet() ) );
    2443                 :            : }
    2444                 :            : 
    2445                 :         78 : void ScHTMLTable::CreateNewEntry( const ImportInfo& rInfo )
    2446                 :            : {
    2447                 :            :     OSL_ENSURE( !mxCurrEntry.get(), "ScHTMLTable::CreateNewEntry - old entry still present" );
    2448                 :         78 :     mxCurrEntry = CreateEntry();
    2449                 :         78 :     mxCurrEntry->aSel = rInfo.aSelection;
    2450                 :         78 : }
    2451                 :            : 
    2452                 :            : SAL_WNODEPRECATED_DECLARATIONS_PUSH
    2453                 :         21 : void ScHTMLTable::ImplPushEntryToList( ScHTMLEntryList& rEntryList, ScHTMLEntryPtr& rxEntry )
    2454                 :            : {
    2455                 :            :     // HTML entry list does not own the entries
    2456         [ +  - ]:         21 :     rEntryList.push_back( rxEntry.get() );
    2457                 :            :     // mrEEParseList (reference to member of ScEEParser) owns the entries
    2458         [ +  - ]:         21 :     mrEEParseList.push_back( rxEntry.release() );
    2459                 :         21 : }
    2460                 :            : SAL_WNODEPRECATED_DECLARATIONS_POP
    2461                 :            : 
    2462                 :            : SAL_WNODEPRECATED_DECLARATIONS_PUSH
    2463                 :         81 : bool ScHTMLTable::PushEntry( ScHTMLEntryPtr& rxEntry )
    2464                 :            : {
    2465                 :         81 :     bool bPushed = false;
    2466 [ +  - ][ +  + ]:         81 :     if( rxEntry.get() && rxEntry->HasContents() )
                 [ +  + ]
    2467                 :            :     {
    2468         [ +  - ]:         21 :         if( mpCurrEntryList )
    2469                 :            :         {
    2470         [ -  + ]:         21 :             if( mbPushEmptyLine )
    2471                 :            :             {
    2472 [ #  # ][ #  # ]:          0 :                 ScHTMLEntryPtr xEmptyEntry = CreateEntry();
    2473         [ #  # ]:          0 :                 ImplPushEntryToList( *mpCurrEntryList, xEmptyEntry );
    2474         [ #  # ]:          0 :                 mbPushEmptyLine = false;
    2475                 :            :             }
    2476                 :         21 :             ImplPushEntryToList( *mpCurrEntryList, rxEntry );
    2477                 :         21 :             bPushed = true;
    2478                 :            :         }
    2479         [ #  # ]:          0 :         else if( mpParentTable )
    2480                 :            :         {
    2481                 :          0 :             bPushed = mpParentTable->PushEntry( rxEntry );
    2482                 :            :         }
    2483                 :            :         else
    2484                 :            :         {
    2485                 :            :             OSL_FAIL( "ScHTMLTable::PushEntry - cannot push entry, no parent found" );
    2486                 :            :         }
    2487                 :            :     }
    2488                 :         81 :     return bPushed;
    2489                 :            : }
    2490                 :            : SAL_WNODEPRECATED_DECLARATIONS_POP
    2491                 :            : 
    2492                 :         78 : bool ScHTMLTable::PushEntry( const ImportInfo& rInfo, bool bLastInCell )
    2493                 :            : {
    2494                 :            :     OSL_ENSURE( mxCurrEntry.get(), "ScHTMLTable::PushEntry - no current entry" );
    2495                 :         78 :     bool bPushed = false;
    2496         [ +  - ]:         78 :     if( mxCurrEntry.get() )
    2497                 :            :     {
    2498                 :         78 :         mxCurrEntry->AdjustEnd( rInfo );
    2499                 :         78 :         mxCurrEntry->Strip( mrEditEngine );
    2500                 :            : 
    2501                 :            :         // import entry always, if it is the last in cell, and cell is still empty
    2502 [ -  + ][ -  + ]:         78 :         if( bLastInCell && IsEmptyCell() )
                 [ +  + ]
    2503                 :            :         {
    2504                 :          0 :             mxCurrEntry->SetImportAlways();
    2505                 :            :             // don't insert empty lines before single empty entries
    2506         [ #  # ]:          0 :             if( mxCurrEntry->IsEmpty() )
    2507                 :          0 :                 mbPushEmptyLine = false;
    2508                 :            :         }
    2509                 :            : 
    2510                 :         78 :         bPushed = PushEntry( mxCurrEntry );
    2511                 :         78 :         mxCurrEntry.reset();
    2512                 :            :     }
    2513                 :         78 :     return bPushed;
    2514                 :            : }
    2515                 :            : 
    2516                 :          3 : bool ScHTMLTable::PushTableEntry( ScHTMLTableId nTableId )
    2517                 :            : {
    2518                 :            :     OSL_ENSURE( nTableId != SC_HTML_GLOBAL_TABLE, "ScHTMLTable::PushTableEntry - cannot push global table" );
    2519                 :          3 :     bool bPushed = false;
    2520         [ +  - ]:          3 :     if( nTableId != SC_HTML_GLOBAL_TABLE )
    2521                 :            :     {
    2522 [ +  - ][ +  - ]:          3 :         ScHTMLEntryPtr xEntry( new ScHTMLEntry( maTableItemSet, nTableId ) );
    2523 [ +  - ][ +  - ]:          3 :         bPushed = PushEntry( xEntry );
    2524                 :            :     }
    2525                 :          3 :     return bPushed;
    2526                 :            : }
    2527                 :            : 
    2528                 :         42 : ScHTMLTable* ScHTMLTable::GetExistingTable( ScHTMLTableId nTableId ) const
    2529                 :            : {
    2530                 :          6 :     ScHTMLTable* pTable = ((nTableId != SC_HTML_GLOBAL_TABLE) && mxNestedTables.get()) ?
    2531   [ +  +  +  - ]:         48 :         mxNestedTables->FindTable( nTableId, false ) : 0;
    2532                 :            :     OSL_ENSURE( pTable || (nTableId == SC_HTML_GLOBAL_TABLE), "ScHTMLTable::GetExistingTable - table not found" );
    2533                 :         42 :     return pTable;
    2534                 :            : }
    2535                 :            : 
    2536                 :          3 : ScHTMLTable* ScHTMLTable::InsertNestedTable( const ImportInfo& rInfo, bool bPreFormText )
    2537                 :            : {
    2538         [ +  - ]:          3 :     if( !mxNestedTables.get() )
    2539         [ +  - ]:          3 :         mxNestedTables.reset( new ScHTMLTableMap( *this ) );
    2540         [ -  + ]:          3 :     if( bPreFormText )      // enclose new preformatted table with empty lines
    2541                 :          0 :         InsertLeadingEmptyLine();
    2542                 :          3 :     return mxNestedTables->CreateTable( rInfo, bPreFormText );
    2543                 :            : }
    2544                 :            : 
    2545                 :         21 : void ScHTMLTable::InsertNewCell( const ScHTMLSize& rSpanSize )
    2546                 :            : {
    2547                 :            :     ScRange* pRange;
    2548                 :            : 
    2549                 :            :     /*  Find an unused cell by skipping all merged ranges that cover the
    2550                 :            :         current cell position stored in maCurrCell. */
    2551 [ +  - ][ +  - ]:         21 :     while( ((pRange = maVMergedCells.Find( maCurrCell.MakeAddr() )) != 0) || ((pRange = maHMergedCells.Find( maCurrCell.MakeAddr() )) != 0) )
         [ +  - ][ -  + ]
         [ +  - ][ +  - ]
           [ -  +  #  #  
                   #  # ]
    2552                 :          0 :         maCurrCell.mnCol = pRange->aEnd.Col() + 1;
    2553         [ +  - ]:         21 :     mpCurrEntryList = &maEntryMap[ maCurrCell ];
    2554                 :            : 
    2555                 :            :     /*  If the new cell is merged horizontally, try to find collisions with
    2556                 :            :         other vertically merged ranges. In this case, shrink existing
    2557                 :            :         vertically merged ranges (do not shrink the new cell). */
    2558                 :         21 :     SCCOL nColEnd = maCurrCell.mnCol + rSpanSize.mnCols;
    2559 [ +  - ][ +  + ]:         42 :     for( ScAddress aAddr( maCurrCell.MakeAddr() ); aAddr.Col() < nColEnd; aAddr.IncCol() )
    2560 [ +  - ][ -  + ]:         21 :         if( (pRange = maVMergedCells.Find( aAddr )) != 0 )
    2561                 :          0 :             pRange->aEnd.SetRow( maCurrCell.mnRow - 1 );
    2562                 :            : 
    2563                 :            :     // insert the new range into the cell lists
    2564                 :         21 :     ScRange aNewRange( maCurrCell.MakeAddr() );
    2565         [ +  - ]:         21 :     aNewRange.aEnd.Move( rSpanSize.mnCols - 1, rSpanSize.mnRows - 1, 0 );
    2566         [ -  + ]:         21 :     if( rSpanSize.mnRows > 1 )
    2567                 :            :     {
    2568         [ #  # ]:          0 :         maVMergedCells.Append( aNewRange );
    2569                 :            :         /*  Do not insert vertically merged ranges into maUsedCells yet,
    2570                 :            :             because they may be shrunken (see above). The final vertically
    2571                 :            :             merged ranges are inserted in FillEmptyCells(). */
    2572                 :            :     }
    2573                 :            :     else
    2574                 :            :     {
    2575         [ -  + ]:         21 :         if( rSpanSize.mnCols > 1 )
    2576         [ #  # ]:          0 :             maHMergedCells.Append( aNewRange );
    2577                 :            :         /*  Insert horizontally merged ranges and single cells into
    2578                 :            :             maUsedCells, they will not be changed anymore. */
    2579         [ +  - ]:         21 :         maUsedCells.Join( aNewRange );
    2580                 :            :     }
    2581                 :            : 
    2582                 :            :     // adjust table size
    2583         [ +  - ]:         21 :     maSize.mnCols = ::std::max< SCCOL >( maSize.mnCols, aNewRange.aEnd.Col() + 1 );
    2584         [ +  - ]:         21 :     maSize.mnRows = ::std::max< SCROW >( maSize.mnRows, aNewRange.aEnd.Row() + 1 );
    2585                 :         21 : }
    2586                 :            : 
    2587                 :          9 : void ScHTMLTable::ImplRowOn()
    2588                 :            : {
    2589         [ -  + ]:          9 :     if( mbRowOn )
    2590                 :          0 :         ImplRowOff();
    2591         [ +  - ]:          9 :     mxRowItemSet.reset( new SfxItemSet( maTableItemSet ) );
    2592                 :          9 :     maCurrCell.mnCol = 0;
    2593                 :          9 :     mbRowOn = true;
    2594                 :          9 :     mbDataOn = false;
    2595                 :          9 : }
    2596                 :            : 
    2597                 :         12 : void ScHTMLTable::ImplRowOff()
    2598                 :            : {
    2599         [ -  + ]:         12 :     if( mbDataOn )
    2600                 :          0 :         ImplDataOff();
    2601         [ +  + ]:         12 :     if( mbRowOn )
    2602                 :            :     {
    2603                 :          9 :         mxRowItemSet.reset();
    2604                 :          9 :         ++maCurrCell.mnRow;
    2605                 :          9 :         mbRowOn = mbDataOn = false;
    2606                 :            :     }
    2607                 :         12 : }
    2608                 :            : 
    2609                 :         21 : void ScHTMLTable::ImplDataOn( const ScHTMLSize& rSpanSize )
    2610                 :            : {
    2611         [ -  + ]:         21 :     if( mbDataOn )
    2612                 :          0 :         ImplDataOff();
    2613         [ -  + ]:         21 :     if( !mbRowOn )
    2614                 :          0 :         ImplRowOn();
    2615         [ +  - ]:         21 :     mxDataItemSet.reset( new SfxItemSet( *mxRowItemSet ) );
    2616                 :         21 :     InsertNewCell( rSpanSize );
    2617                 :         21 :     mbDataOn = true;
    2618                 :         21 :     mbPushEmptyLine = false;
    2619                 :         21 : }
    2620                 :            : 
    2621                 :         24 : void ScHTMLTable::ImplDataOff()
    2622                 :            : {
    2623         [ +  + ]:         24 :     if( mbDataOn )
    2624                 :            :     {
    2625                 :         21 :         mxDataItemSet.reset();
    2626                 :         21 :         ++maCurrCell.mnCol;
    2627                 :         21 :         mpCurrEntryList = 0;
    2628                 :         21 :         mbDataOn = false;
    2629                 :            :     }
    2630                 :         24 : }
    2631                 :            : 
    2632                 :         30 : void ScHTMLTable::ProcessFormatOptions( SfxItemSet& rItemSet, const ImportInfo& rInfo )
    2633                 :            : {
    2634                 :            :     // special handling for table header cells
    2635         [ -  + ]:         30 :     if( rInfo.nToken == HTML_TABLEHEADER_ON )
    2636                 :            :     {
    2637 [ #  # ][ #  # ]:          0 :         rItemSet.Put( SvxWeightItem( WEIGHT_BOLD, ATTR_FONT_WEIGHT ) );
                 [ #  # ]
    2638 [ #  # ][ #  # ]:          0 :         rItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_CENTER, ATTR_HOR_JUSTIFY ) );
                 [ #  # ]
    2639                 :            :     }
    2640                 :            : 
    2641         [ +  - ]:         30 :     const HTMLOptions& rOptions = static_cast<HTMLParser*>(rInfo.pParser)->GetOptions();
    2642 [ +  - ][ +  - ]:         30 :     HTMLOptions::const_iterator itr = rOptions.begin(), itrEnd = rOptions.end();
    2643 [ #  # ][ +  - ]:         30 :     for (; itr != itrEnd; ++itr)
                 [ -  + ]
    2644                 :            :     {
    2645         [ #  # ]:          0 :         switch( itr->GetToken() )
           [ #  #  #  # ]
    2646                 :            :         {
    2647                 :            :             case HTML_O_ALIGN:
    2648                 :            :             {
    2649                 :          0 :                 SvxCellHorJustify eVal = SVX_HOR_JUSTIFY_STANDARD;
    2650         [ #  # ]:          0 :                 const String& rOptVal = itr->GetString();
    2651 [ #  # ][ #  # ]:          0 :                 if( rOptVal.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_AL_right ) )
    2652                 :          0 :                     eVal = SVX_HOR_JUSTIFY_RIGHT;
    2653 [ #  # ][ #  # ]:          0 :                 else if( rOptVal.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_AL_center ) )
    2654                 :          0 :                     eVal = SVX_HOR_JUSTIFY_CENTER;
    2655 [ #  # ][ #  # ]:          0 :                 else if( rOptVal.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_AL_left ) )
    2656                 :          0 :                     eVal = SVX_HOR_JUSTIFY_LEFT;
    2657         [ #  # ]:          0 :                 if( eVal != SVX_HOR_JUSTIFY_STANDARD )
    2658 [ #  # ][ #  # ]:          0 :                     rItemSet.Put( SvxHorJustifyItem( eVal, ATTR_HOR_JUSTIFY ) );
                 [ #  # ]
    2659                 :            :             }
    2660                 :          0 :             break;
    2661                 :            : 
    2662                 :            :             case HTML_O_VALIGN:
    2663                 :            :             {
    2664                 :          0 :                 SvxCellVerJustify eVal = SVX_VER_JUSTIFY_STANDARD;
    2665         [ #  # ]:          0 :                 const String& rOptVal = itr->GetString();
    2666 [ #  # ][ #  # ]:          0 :                 if( rOptVal.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_VA_top ) )
    2667                 :          0 :                     eVal = SVX_VER_JUSTIFY_TOP;
    2668 [ #  # ][ #  # ]:          0 :                 else if( rOptVal.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_VA_middle ) )
    2669                 :          0 :                     eVal = SVX_VER_JUSTIFY_CENTER;
    2670 [ #  # ][ #  # ]:          0 :                 else if( rOptVal.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_VA_bottom ) )
    2671                 :          0 :                     eVal = SVX_VER_JUSTIFY_BOTTOM;
    2672         [ #  # ]:          0 :                 if( eVal != SVX_VER_JUSTIFY_STANDARD )
    2673 [ #  # ][ #  # ]:          0 :                     rItemSet.Put( SvxVerJustifyItem( eVal, ATTR_VER_JUSTIFY ) );
                 [ #  # ]
    2674                 :            :             }
    2675                 :          0 :             break;
    2676                 :            : 
    2677                 :            :             case HTML_O_BGCOLOR:
    2678                 :            :             {
    2679                 :          0 :                 Color aColor;
    2680 [ #  # ][ #  # ]:          0 :                 itr->GetColor( aColor );
    2681 [ #  # ][ #  # ]:          0 :                 rItemSet.Put( SvxBrushItem( aColor, ATTR_BACKGROUND ) );
                 [ #  # ]
    2682                 :            :             }
    2683                 :          0 :             break;
    2684                 :            :         }
    2685                 :            :     }
    2686                 :         30 : }
    2687                 :            : 
    2688                 :         42 : void ScHTMLTable::SetDocSize( ScHTMLOrient eOrient, SCCOLROW nCellPos, SCCOLROW nSize )
    2689                 :            : {
    2690                 :            :     OSL_ENSURE( nCellPos >= 0, "ScHTMLTable::SetDocSize - unexpected negative position" );
    2691                 :         42 :     ScSizeVec& rSizes = maCumSizes[ eOrient ];
    2692                 :         42 :     size_t nIndex = static_cast< size_t >( nCellPos );
    2693                 :            :     // expand with height/width == 1
    2694         [ +  + ]:         63 :     while( nIndex >= rSizes.size() )
    2695 [ +  + ][ +  - ]:         21 :         rSizes.push_back( rSizes.empty() ? 1 : (rSizes.back() + 1) );
    2696                 :            :     // update size of passed position and all following
    2697                 :            :     // #i109987# only grow, don't shrink - use the largest needed size
    2698         [ +  + ]:         42 :     SCsCOLROW nDiff = nSize - ((nIndex == 0) ? rSizes.front() : (rSizes[ nIndex ] - rSizes[ nIndex - 1 ]));
    2699         [ +  + ]:         42 :     if( nDiff > 0 )
    2700 [ +  - ][ +  - ]:         12 :         for( ScSizeVec::iterator aIt = rSizes.begin() + nIndex, aEnd = rSizes.end(); aIt != aEnd; ++aIt )
         [ +  - ][ +  + ]
    2701         [ +  - ]:          6 :             *aIt += nDiff;
    2702                 :         42 : }
    2703                 :            : 
    2704                 :         42 : void ScHTMLTable::CalcNeededDocSize(
    2705                 :            :         ScHTMLOrient eOrient, SCCOLROW nCellPos, SCCOLROW nCellSpan, SCCOLROW nRealDocSize )
    2706                 :            : {
    2707                 :         42 :     SCCOLROW nDiffSize = 0;
    2708                 :            :     // in merged columns/rows: reduce needed size by size of leading columns
    2709         [ -  + ]:         42 :     while( nCellSpan > 1 )
    2710                 :            :     {
    2711         [ #  # ]:          0 :         nDiffSize += GetDocSize( eOrient, nCellPos );
    2712                 :          0 :         --nCellSpan;
    2713                 :          0 :         ++nCellPos;
    2714                 :            :     }
    2715                 :            :     // set remaining needed size to last column/row
    2716         [ +  - ]:         42 :     nRealDocSize -= ::std::min< SCCOLROW >( nRealDocSize - 1, nDiffSize );
    2717         [ +  - ]:         42 :     SetDocSize( eOrient, nCellPos, nRealDocSize );
    2718                 :         42 : }
    2719                 :            : 
    2720                 :            : // ----------------------------------------------------------------------------
    2721                 :            : 
    2722                 :          6 : void ScHTMLTable::FillEmptyCells()
    2723                 :            : {
    2724 [ +  - ][ +  - ]:          9 :     for( ScHTMLTableIterator aIter( mxNestedTables.get() ); aIter.is(); ++aIter )
         [ +  - ][ +  + ]
    2725 [ +  - ][ +  - ]:          3 :         aIter->FillEmptyCells();
    2726                 :            : 
    2727                 :            :     // insert the final vertically merged ranges into maUsedCells
    2728         [ -  + ]:          6 :     for ( size_t i = 0, nRanges = maVMergedCells.size(); i < nRanges; ++i )
    2729                 :            :     {
    2730                 :          0 :         ScRange* pRange = maVMergedCells[ i ];
    2731                 :          0 :         maUsedCells.Join( *pRange );
    2732                 :            :     }
    2733                 :            : 
    2734 [ +  - ][ +  + ]:         15 :     for( ScAddress aAddr; aAddr.Row() < maSize.mnRows; aAddr.IncRow() )
    2735                 :            :     {
    2736 [ +  - ][ +  + ]:         30 :         for( aAddr.SetCol( 0 ); aAddr.Col() < maSize.mnCols; aAddr.IncCol() )
    2737                 :            :         {
    2738 [ +  - ][ -  + ]:         21 :             if( !maUsedCells.Find( aAddr ) )
    2739                 :            :             {
    2740                 :            :                 // create a range for the lock list (used to calc. cell span)
    2741                 :          0 :                 ScRange aRange( aAddr );
    2742 [ #  # ][ #  # ]:          0 :                 do
                 [ #  # ]
    2743                 :            :                 {
    2744         [ #  # ]:          0 :                     aRange.aEnd.IncCol();
    2745                 :            :                 }
    2746         [ #  # ]:          0 :                 while( (aRange.aEnd.Col() < maSize.mnCols) && !maUsedCells.Find( aRange.aEnd ) );
    2747         [ #  # ]:          0 :                 aRange.aEnd.IncCol( -1 );
    2748         [ #  # ]:          0 :                 maUsedCells.Join( aRange );
    2749                 :            : 
    2750                 :            :                 // insert a dummy entry
    2751 [ #  # ][ #  # ]:          0 :                 ScHTMLEntryPtr xEntry = CreateEntry();
    2752 [ #  # ][ #  # ]:          0 :                 ImplPushEntryToList( maEntryMap[ ScHTMLPos( aAddr ) ], xEntry );
         [ #  # ][ #  # ]
    2753                 :            :             }
    2754                 :            :         }
    2755                 :            :     }
    2756                 :          6 : }
    2757                 :            : 
    2758                 :          6 : void ScHTMLTable::RecalcDocSize()
    2759                 :            : {
    2760                 :            :     // recalc table sizes recursively from inner to outer
    2761 [ +  - ][ +  - ]:          9 :     for( ScHTMLTableIterator aIter( mxNestedTables.get() ); aIter.is(); ++aIter )
         [ +  - ][ +  + ]
    2762 [ +  - ][ +  - ]:          3 :         aIter->RecalcDocSize();
    2763                 :            : 
    2764                 :            :     /*  Two passes: first calculates the sizes of single columns/rows, then
    2765                 :            :         the sizes of spanned columns/rows. This allows to fill nested tables
    2766                 :            :         into merged cells optimally. */
    2767                 :            :     static const sal_uInt16 PASS_SINGLE = 0;
    2768                 :            :     static const sal_uInt16 PASS_SPANNED = 1;
    2769         [ +  + ]:         18 :     for( sal_uInt16 nPass = PASS_SINGLE; nPass <= PASS_SPANNED; ++nPass )
    2770                 :            :     {
    2771                 :            :         // iterate through every table cell
    2772                 :         12 :         ScHTMLEntryMap::const_iterator aMapIterEnd = maEntryMap.end();
    2773         [ +  + ]:         54 :         for( ScHTMLEntryMap::const_iterator aMapIter = maEntryMap.begin(); aMapIter != aMapIterEnd; ++aMapIter )
    2774                 :            :         {
    2775                 :         42 :             const ScHTMLPos& rCellPos = aMapIter->first;
    2776         [ +  - ]:         42 :             ScHTMLSize aCellSpan = GetSpan( rCellPos );
    2777                 :            : 
    2778                 :         42 :             const ScHTMLEntryList& rEntryList = aMapIter->second;
    2779                 :         42 :             ScHTMLEntryList::const_iterator aListIter;
    2780                 :         42 :             ScHTMLEntryList::const_iterator aListIterEnd = rEntryList.end();
    2781                 :            : 
    2782                 :            :             // process the dimension of the current cell in this pass?
    2783                 :            :             // (pass is single and span is 1) or (pass is not single and span is not 1)
    2784                 :         42 :             bool bProcessColWidth = ((nPass == PASS_SINGLE) == (aCellSpan.mnCols == 1));
    2785                 :         42 :             bool bProcessRowHeight = ((nPass == PASS_SINGLE) == (aCellSpan.mnRows == 1));
    2786 [ -  + ][ +  + ]:         42 :             if( bProcessColWidth || bProcessRowHeight )
    2787                 :            :             {
    2788                 :         21 :                 ScHTMLSize aDocSize( 1, 0 );    // resulting size of the cell in document
    2789                 :            : 
    2790                 :            :                 // expand the cell size for each cell parse entry
    2791         [ +  + ]:         42 :                 for( aListIter = rEntryList.begin(); aListIter != aListIterEnd; ++aListIter )
    2792                 :            :                 {
    2793         [ +  - ]:         21 :                     ScHTMLTable* pTable = GetExistingTable( (*aListIter)->GetTableId() );
    2794                 :            :                     // find entry with maximum width
    2795 [ +  - ][ +  + ]:         21 :                     if( bProcessColWidth && pTable )
    2796 [ +  - ][ +  - ]:          3 :                         aDocSize.mnCols = ::std::max( aDocSize.mnCols, static_cast< SCCOL >( pTable->GetDocSize( tdCol ) ) );
    2797                 :            :                     // add up height of each entry
    2798         [ +  - ]:         21 :                     if( bProcessRowHeight )
    2799 [ +  + ][ +  - ]:         21 :                         aDocSize.mnRows += pTable ? pTable->GetDocSize( tdRow ) : 1;
    2800                 :            :                 }
    2801         [ -  + ]:         21 :                 if( !aDocSize.mnRows )
    2802                 :          0 :                     aDocSize.mnRows = 1;
    2803                 :            : 
    2804         [ +  - ]:         21 :                 if( bProcessColWidth )
    2805         [ +  - ]:         21 :                     CalcNeededDocSize( tdCol, rCellPos.mnCol, aCellSpan.mnCols, aDocSize.mnCols );
    2806         [ +  - ]:         21 :                 if( bProcessRowHeight )
    2807         [ +  - ]:         21 :                     CalcNeededDocSize( tdRow, rCellPos.mnRow, aCellSpan.mnRows, aDocSize.mnRows );
    2808                 :            :             }
    2809                 :            :         }
    2810                 :            :     }
    2811                 :          6 : }
    2812                 :            : 
    2813                 :          6 : void ScHTMLTable::RecalcDocPos( const ScHTMLPos& rBasePos )
    2814                 :            : {
    2815                 :          6 :     maDocBasePos = rBasePos;
    2816                 :            :     // after the previous assignment it is allowed to call GetDocPos() methods
    2817                 :            : 
    2818                 :            :     // iterate through every table cell
    2819                 :          6 :     ScHTMLEntryMap::iterator aMapIterEnd = maEntryMap.end();
    2820         [ +  + ]:         27 :     for( ScHTMLEntryMap::iterator aMapIter = maEntryMap.begin(); aMapIter != aMapIterEnd; ++aMapIter )
    2821                 :            :     {
    2822                 :            :         // fixed doc position of the entire cell (first entry)
    2823         [ +  - ]:         21 :         const ScHTMLPos aCellDocPos( GetDocPos( aMapIter->first ) );
    2824                 :            :         // fixed doc size of the entire cell
    2825         [ +  - ]:         21 :         const ScHTMLSize aCellDocSize( GetDocSize( aMapIter->first ) );
    2826                 :            : 
    2827                 :            :         // running doc position for single entries
    2828                 :         21 :         ScHTMLPos aEntryDocPos( aCellDocPos );
    2829                 :            : 
    2830                 :         21 :         ScHTMLEntryList& rEntryList = aMapIter->second;
    2831                 :         21 :         ScHTMLEntry* pEntry = 0;
    2832                 :         21 :         ScHTMLEntryList::iterator aListIterEnd = rEntryList.end();
    2833         [ +  + ]:         42 :         for( ScHTMLEntryList::iterator aListIter = rEntryList.begin(); aListIter != aListIterEnd; ++aListIter )
    2834                 :            :         {
    2835                 :         21 :             pEntry = *aListIter;
    2836 [ +  + ][ +  - ]:         21 :             if( ScHTMLTable* pTable = GetExistingTable( pEntry->GetTableId() ) )
    2837                 :            :             {
    2838         [ +  - ]:          3 :                 pTable->RecalcDocPos( aEntryDocPos );   // recalc nested table
    2839                 :          3 :                 pEntry->nCol = SCCOL_MAX;
    2840                 :          3 :                 pEntry->nRow = SCROW_MAX;
    2841         [ +  - ]:          3 :                 SCROW nTableRows = static_cast< SCROW >( pTable->GetDocSize( tdRow ) );
    2842                 :            : 
    2843                 :            :                 // use this entry to pad empty space right of table
    2844         [ -  + ]:          3 :                 if( mpParentTable )     // ... but not in global table
    2845                 :            :                 {
    2846         [ #  # ]:          0 :                     SCCOL nStartCol = aEntryDocPos.mnCol + static_cast< SCCOL >( pTable->GetDocSize( tdCol ) );
    2847                 :          0 :                     SCCOL nNextCol = aEntryDocPos.mnCol + aCellDocSize.mnCols;
    2848         [ #  # ]:          0 :                     if( nStartCol < nNextCol )
    2849                 :            :                     {
    2850                 :          0 :                         pEntry->nCol = nStartCol;
    2851                 :          0 :                         pEntry->nRow = aEntryDocPos.mnRow;
    2852                 :          0 :                         pEntry->nColOverlap = nNextCol - nStartCol;
    2853                 :          0 :                         pEntry->nRowOverlap = nTableRows;
    2854                 :            :                     }
    2855                 :            :                 }
    2856                 :          3 :                 aEntryDocPos.mnRow += nTableRows;
    2857                 :            :             }
    2858                 :            :             else
    2859                 :            :             {
    2860                 :         18 :                 pEntry->nCol = aEntryDocPos.mnCol;
    2861                 :         18 :                 pEntry->nRow = aEntryDocPos.mnRow;
    2862         [ +  - ]:         18 :                 if( mpParentTable )    // do not merge in global table
    2863                 :         18 :                     pEntry->nColOverlap = aCellDocSize.mnCols;
    2864                 :         18 :                 ++aEntryDocPos.mnRow;
    2865                 :            :             }
    2866                 :            :         }
    2867                 :            : 
    2868                 :            :         // pEntry points now to last entry.
    2869         [ +  - ]:         21 :         if( pEntry )
    2870                 :            :         {
    2871 [ +  - ][ +  + ]:         21 :             if( (pEntry == rEntryList.front()) && (pEntry->GetTableId() == SC_HTML_NO_TABLE) )
                 [ +  + ]
    2872                 :            :             {
    2873                 :            :                 // pEntry is the only entry in this cell - merge rows of cell with single non-table entry.
    2874                 :         18 :                 pEntry->nRowOverlap = aCellDocSize.mnRows;
    2875                 :            :             }
    2876                 :            :             else
    2877                 :            :             {
    2878                 :            :                 // fill up incomplete entry lists
    2879                 :          3 :                 SCROW nFirstUnusedRow = aCellDocPos.mnRow + aCellDocSize.mnRows;
    2880         [ -  + ]:          3 :                 while( aEntryDocPos.mnRow < nFirstUnusedRow )
    2881                 :            :                 {
    2882 [ #  # ][ #  # ]:          0 :                     ScHTMLEntryPtr xDummyEntry( new ScHTMLEntry( pEntry->GetItemSet() ) );
    2883                 :          0 :                     xDummyEntry->nCol = aEntryDocPos.mnCol;
    2884                 :          0 :                     xDummyEntry->nRow = aEntryDocPos.mnRow;
    2885                 :          0 :                     xDummyEntry->nColOverlap = aCellDocSize.mnCols;
    2886         [ #  # ]:          0 :                     ImplPushEntryToList( rEntryList, xDummyEntry );
    2887                 :          0 :                     ++aEntryDocPos.mnRow;
    2888         [ #  # ]:          0 :                 }
    2889                 :            :             }
    2890                 :            :         }
    2891                 :            :     }
    2892                 :          6 : }
    2893                 :            : 
    2894                 :            : // ============================================================================
    2895                 :            : 
    2896                 :          3 : ScHTMLGlobalTable::ScHTMLGlobalTable(
    2897                 :            :     SfxItemPool& rPool,
    2898                 :            :     EditEngine& rEditEngine,
    2899                 :            :     ::std::vector< ScEEParseEntry* >& rEEParseList,
    2900                 :            :     ScHTMLTableId& rnUnusedId,
    2901                 :            :     ScHTMLParser* pParser
    2902                 :            : ) :
    2903                 :          3 :     ScHTMLTable( rPool, rEditEngine, rEEParseList, rnUnusedId, pParser )
    2904                 :            : {
    2905                 :          3 : }
    2906                 :            : 
    2907                 :          3 : ScHTMLGlobalTable::~ScHTMLGlobalTable()
    2908                 :            : {
    2909         [ -  + ]:          6 : }
    2910                 :            : 
    2911                 :          3 : void ScHTMLGlobalTable::Recalc()
    2912                 :            : {
    2913                 :            :     // Fills up empty cells with a dummy entry. */
    2914                 :          3 :     FillEmptyCells();
    2915                 :            :     // recalc table sizes of all nested tables and this table
    2916                 :          3 :     RecalcDocSize();
    2917                 :            :     // recalc document positions of all entries in this table and in nested tables
    2918                 :          3 :     RecalcDocPos( GetDocPos() );
    2919                 :          3 : }
    2920                 :            : 
    2921                 :            : // ============================================================================
    2922                 :            : 
    2923                 :          3 : ScHTMLQueryParser::ScHTMLQueryParser( EditEngine* pEditEngine, ScDocument* pDoc ) :
    2924                 :            :     ScHTMLParser( pEditEngine, pDoc ),
    2925                 :            :     mnUnusedId( SC_HTML_GLOBAL_TABLE ),
    2926                 :          3 :     mbTitleOn( false )
    2927                 :            : {
    2928                 :            :     mxGlobTable.reset(
    2929 [ +  - ][ +  - ]:          3 :         new ScHTMLGlobalTable(*pPool, *pEdit, maList, mnUnusedId, this));
    2930                 :          3 :     mpCurrTable = mxGlobTable.get();
    2931                 :          3 : }
    2932                 :            : 
    2933         [ +  - ]:          3 : ScHTMLQueryParser::~ScHTMLQueryParser()
    2934                 :            : {
    2935         [ -  + ]:          6 : }
    2936                 :            : 
    2937                 :          3 : sal_uLong ScHTMLQueryParser::Read( SvStream& rStrm, const String& rBaseURL  )
    2938                 :            : {
    2939                 :          3 :     SvKeyValueIteratorRef xValues;
    2940                 :          3 :     SvKeyValueIterator* pAttributes = 0;
    2941                 :            : 
    2942                 :          3 :     SfxObjectShell* pObjSh = mpDoc->GetDocumentShell();
    2943 [ +  - ][ +  - ]:          3 :     if( pObjSh && pObjSh->IsLoading() )
         [ +  - ][ +  - ]
    2944                 :            :     {
    2945         [ +  - ]:          3 :         pAttributes = pObjSh->GetHeaderAttributes();
    2946                 :            :     }
    2947                 :            :     else
    2948                 :            :     {
    2949                 :            :         /*  When not loading, set up fake HTTP headers to force the SfxHTMLParser
    2950                 :            :             to use UTF8 (used when pasting from clipboard) */
    2951         [ #  # ]:          0 :         const sal_Char* pCharSet = rtl_getBestMimeCharsetFromTextEncoding( RTL_TEXTENCODING_UTF8 );
    2952         [ #  # ]:          0 :         if( pCharSet )
    2953                 :            :         {
    2954         [ #  # ]:          0 :             String aContentType = rtl::OUString( "text/html; charset=" );
    2955         [ #  # ]:          0 :             aContentType.AppendAscii( pCharSet );
    2956                 :            : 
    2957 [ #  # ][ #  # ]:          0 :             xValues = new SvKeyValueIterator;
                 [ #  # ]
    2958 [ #  # ][ #  # ]:          0 :             xValues->Append( SvKeyValue( rtl::OUString( OOO_STRING_SVTOOLS_HTML_META_content_type ), aContentType ) );
         [ #  # ][ #  # ]
                 [ #  # ]
    2959         [ #  # ]:          0 :             pAttributes = xValues;
    2960                 :            :         }
    2961                 :            :     }
    2962                 :            : 
    2963         [ +  - ]:          3 :     Link aOldLink = pEdit->GetImportHdl();
    2964 [ +  - ][ +  - ]:          3 :     pEdit->SetImportHdl( LINK( this, ScHTMLQueryParser, HTMLImportHdl ) );
    2965         [ +  - ]:          3 :     sal_uLong nErr = pEdit->Read( rStrm, rBaseURL, EE_FORMAT_HTML, pAttributes );
    2966         [ +  - ]:          3 :     pEdit->SetImportHdl( aOldLink );
    2967                 :            : 
    2968         [ +  - ]:          3 :     mxGlobTable->Recalc();
    2969         [ +  - ]:          3 :     nColMax = static_cast< SCCOL >( mxGlobTable->GetDocSize( tdCol ) - 1 );
    2970         [ +  - ]:          3 :     nRowMax = static_cast< SCROW >( mxGlobTable->GetDocSize( tdRow ) - 1 );
    2971                 :            : 
    2972         [ +  - ]:          3 :     return nErr;
    2973                 :            : }
    2974                 :            : 
    2975                 :          3 : const ScHTMLTable* ScHTMLQueryParser::GetGlobalTable() const
    2976                 :            : {
    2977                 :          3 :     return mxGlobTable.get();
    2978                 :            : }
    2979                 :            : 
    2980                 :        102 : void ScHTMLQueryParser::ProcessToken( const ImportInfo& rInfo )
    2981                 :            : {
    2982   [ -  -  -  -  :        102 :     switch( rInfo.nToken )
          -  +  +  +  -  
          -  -  +  +  +  
          +  +  +  -  -  
          -  -  -  -  -  
                -  -  + ]
    2983                 :            :     {
    2984                 :            : // --- meta data ---
    2985                 :          0 :         case HTML_META:             MetaOn( rInfo );                break;  // <meta>
    2986                 :            : 
    2987                 :            : // --- title handling ---
    2988                 :          0 :         case HTML_TITLE_ON:         TitleOn( rInfo );               break;  // <title>
    2989                 :          0 :         case HTML_TITLE_OFF:        TitleOff( rInfo );              break;  // </title>
    2990                 :            : 
    2991                 :          0 :         case HTML_STYLE_ON:                                         break;
    2992         [ #  # ]:          0 :         case HTML_STYLE_OFF:        ParseStyle(rInfo.aText);        break;
    2993                 :            : 
    2994                 :            : // --- body handling ---
    2995                 :          3 :         case HTML_BODY_ON:          mpCurrTable->BodyOn( rInfo );   break;  // <body>
    2996                 :          3 :         case HTML_BODY_OFF:         mpCurrTable->BodyOff( rInfo );  break;  // </body>
    2997                 :            : 
    2998                 :            : // --- insert text ---
    2999                 :         39 :         case HTML_TEXTTOKEN:        InsertText( rInfo );            break;  // any text
    3000                 :          0 :         case HTML_LINEBREAK:        mpCurrTable->BreakOn();         break;  // <br>
    3001                 :            :         case HTML_HEAD1_ON:                                                 // <h1>
    3002                 :            :         case HTML_HEAD2_ON:                                                 // <h2>
    3003                 :            :         case HTML_HEAD3_ON:                                                 // <h3>
    3004                 :            :         case HTML_HEAD4_ON:                                                 // <h4>
    3005                 :            :         case HTML_HEAD5_ON:                                                 // <h5>
    3006                 :            :         case HTML_HEAD6_ON:                                                 // <h6>
    3007                 :          0 :         case HTML_PARABREAK_ON:     mpCurrTable->HeadingOn();       break;  // <p>
    3008                 :            : 
    3009                 :            : // --- misc. contents ---
    3010                 :          0 :         case HTML_ANCHOR_ON:        mpCurrTable->AnchorOn();        break;  // <a>
    3011                 :            : 
    3012                 :            : // --- table handling ---
    3013                 :          3 :         case HTML_TABLE_ON:         TableOn( rInfo );               break;  // <table>
    3014                 :          3 :         case HTML_TABLE_OFF:        TableOff( rInfo );              break;  // </table>
    3015                 :          6 :         case HTML_TABLEROW_ON:      mpCurrTable->RowOn( rInfo );    break;  // <tr>
    3016                 :          6 :         case HTML_TABLEROW_OFF:     mpCurrTable->RowOff( rInfo );   break;  // </tr>
    3017                 :            :         case HTML_TABLEHEADER_ON:                                           // <th>
    3018                 :         18 :         case HTML_TABLEDATA_ON:     mpCurrTable->DataOn( rInfo );   break;  // <td>
    3019                 :            :         case HTML_TABLEHEADER_OFF:                                          // </th>
    3020                 :         18 :         case HTML_TABLEDATA_OFF:    mpCurrTable->DataOff( rInfo );  break;  // </td>
    3021                 :          0 :         case HTML_PREFORMTXT_ON:    PreOn( rInfo );                 break;  // <pre>
    3022                 :          0 :         case HTML_PREFORMTXT_OFF:   PreOff( rInfo );                break;  // </pre>
    3023                 :            : 
    3024                 :            : // --- formatting ---
    3025                 :          0 :         case HTML_FONT_ON:          FontOn( rInfo );                break;  // <font>
    3026                 :            : 
    3027                 :            :         case HTML_BIGPRINT_ON:      // <big>
    3028                 :            :             //! TODO: store current font size, use following size
    3029         [ #  # ]:          0 :             mpCurrTable->PutItem( SvxFontHeightItem( maFontHeights[ 3 ], 100, ATTR_FONT_HEIGHT ) );
    3030                 :          0 :         break;
    3031                 :            :         case HTML_SMALLPRINT_ON:    // <small>
    3032                 :            :             //! TODO: store current font size, use preceding size
    3033         [ #  # ]:          0 :             mpCurrTable->PutItem( SvxFontHeightItem( maFontHeights[ 0 ], 100, ATTR_FONT_HEIGHT ) );
    3034                 :          0 :         break;
    3035                 :            : 
    3036                 :            :         case HTML_BOLD_ON:          // <b>
    3037                 :            :         case HTML_STRONG_ON:        // <strong>
    3038         [ #  # ]:          0 :             mpCurrTable->PutItem( SvxWeightItem( WEIGHT_BOLD, ATTR_FONT_WEIGHT ) );
    3039                 :          0 :         break;
    3040                 :            : 
    3041                 :            :         case HTML_ITALIC_ON:        // <i>
    3042                 :            :         case HTML_EMPHASIS_ON:      // <em>
    3043                 :            :         case HTML_ADDRESS_ON:       // <address>
    3044                 :            :         case HTML_BLOCKQUOTE_ON:    // <blockquote>
    3045                 :            :         case HTML_BLOCKQUOTE30_ON:  // <bq>
    3046                 :            :         case HTML_CITIATION_ON:     // <cite>
    3047                 :            :         case HTML_VARIABLE_ON:      // <var>
    3048         [ #  # ]:          0 :             mpCurrTable->PutItem( SvxPostureItem( ITALIC_NORMAL, ATTR_FONT_POSTURE ) );
    3049                 :          0 :         break;
    3050                 :            : 
    3051                 :            :         case HTML_DEFINSTANCE_ON:   // <dfn>
    3052         [ #  # ]:          0 :             mpCurrTable->PutItem( SvxWeightItem( WEIGHT_BOLD, ATTR_FONT_WEIGHT ) );
    3053         [ #  # ]:          0 :             mpCurrTable->PutItem( SvxPostureItem( ITALIC_NORMAL, ATTR_FONT_POSTURE ) );
    3054                 :          0 :         break;
    3055                 :            : 
    3056                 :            :         case HTML_UNDERLINE_ON:     // <u>
    3057         [ #  # ]:          0 :             mpCurrTable->PutItem( SvxUnderlineItem( UNDERLINE_SINGLE, ATTR_FONT_UNDERLINE ) );
    3058                 :          0 :         break;
    3059                 :            :     }
    3060                 :        102 : }
    3061                 :            : 
    3062                 :         39 : void ScHTMLQueryParser::InsertText( const ImportInfo& rInfo )
    3063                 :            : {
    3064                 :         39 :     mpCurrTable->PutText( rInfo );
    3065         [ -  + ]:         39 :     if( mbTitleOn )
    3066         [ #  # ]:          0 :         maTitle.append(rInfo.aText);
    3067                 :         39 : }
    3068                 :            : 
    3069                 :          0 : void ScHTMLQueryParser::FontOn( const ImportInfo& rInfo )
    3070                 :            : {
    3071         [ #  # ]:          0 :     const HTMLOptions& rOptions = static_cast<HTMLParser*>(rInfo.pParser)->GetOptions();
    3072 [ #  # ][ #  # ]:          0 :     HTMLOptions::const_iterator itr = rOptions.begin(), itrEnd = rOptions.end();
    3073 [ #  # ][ #  # ]:          0 :     for (; itr != itrEnd; ++itr)
                 [ #  # ]
    3074                 :            :     {
    3075         [ #  # ]:          0 :         switch( itr->GetToken() )
           [ #  #  #  # ]
    3076                 :            :         {
    3077                 :            :             case HTML_O_FACE :
    3078                 :            :             {
    3079         [ #  # ]:          0 :                 const String& rFace = itr->GetString();
    3080         [ #  # ]:          0 :                 String aFontName;
    3081                 :          0 :                 xub_StrLen nPos = 0;
    3082         [ #  # ]:          0 :                 while( nPos != STRING_NOTFOUND )
    3083                 :            :                 {
    3084                 :            :                     // font list separator: VCL = ';' HTML = ','
    3085 [ #  # ][ #  # ]:          0 :                     String aFName = comphelper::string::strip(rFace.GetToken(0, ',', nPos), ' ');
         [ #  # ][ #  # ]
                 [ #  # ]
    3086         [ #  # ]:          0 :                     ScGlobal::AddToken( aFontName, aFName, ';' );
    3087         [ #  # ]:          0 :                 }
    3088         [ #  # ]:          0 :                 if ( aFontName.Len() )
    3089                 :            :                     mpCurrTable->PutItem( SvxFontItem( FAMILY_DONTKNOW,
    3090         [ #  # ]:          0 :                         aFontName, EMPTY_STRING, PITCH_DONTKNOW,
    3091 [ #  # ][ #  # ]:          0 :                         RTL_TEXTENCODING_DONTKNOW, ATTR_FONT ) );
         [ #  # ][ #  # ]
    3092                 :            :             }
    3093                 :          0 :             break;
    3094                 :            :             case HTML_O_SIZE :
    3095                 :            :             {
    3096 [ #  # ][ #  # ]:          0 :                 sal_uInt32 nSize = getLimitedValue< sal_uInt32 >( itr->GetNumber(), 1, SC_HTML_FONTSIZES );
                 [ #  # ]
    3097 [ #  # ][ #  # ]:          0 :                 mpCurrTable->PutItem( SvxFontHeightItem( maFontHeights[ nSize - 1 ], 100, ATTR_FONT_HEIGHT ) );
                 [ #  # ]
    3098                 :            :             }
    3099                 :          0 :             break;
    3100                 :            :             case HTML_O_COLOR :
    3101                 :            :             {
    3102                 :          0 :                 Color aColor;
    3103 [ #  # ][ #  # ]:          0 :                 itr->GetColor( aColor );
    3104 [ #  # ][ #  # ]:          0 :                 mpCurrTable->PutItem( SvxColorItem( aColor, ATTR_FONT_COLOR ) );
                 [ #  # ]
    3105                 :            :             }
    3106                 :          0 :             break;
    3107                 :            :         }
    3108                 :            :     }
    3109                 :          0 : }
    3110                 :            : 
    3111                 :          0 : void ScHTMLQueryParser::MetaOn( const ImportInfo& rInfo )
    3112                 :            : {
    3113         [ #  # ]:          0 :     if( mpDoc->GetDocumentShell() )
    3114                 :            :     {
    3115                 :          0 :         HTMLParser* pParser = static_cast< HTMLParser* >( rInfo.pParser );
    3116                 :            : 
    3117                 :            :         uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
    3118 [ #  # ][ #  # ]:          0 :             mpDoc->GetDocumentShell()->GetModel(), uno::UNO_QUERY_THROW);
    3119                 :            :         pParser->ParseMetaOptions(
    3120         [ #  # ]:          0 :             xDPS->getDocumentProperties(),
    3121 [ #  # ][ #  # ]:          0 :             mpDoc->GetDocumentShell()->GetHeaderAttributes() );
                 [ #  # ]
    3122                 :            :     }
    3123                 :          0 : }
    3124                 :            : 
    3125                 :          0 : void ScHTMLQueryParser::TitleOn( const ImportInfo& /*rInfo*/ )
    3126                 :            : {
    3127                 :          0 :     mbTitleOn = true;
    3128                 :          0 :     maTitle.makeStringAndClear();
    3129                 :          0 : }
    3130                 :            : 
    3131                 :          0 : void ScHTMLQueryParser::TitleOff( const ImportInfo& rInfo )
    3132                 :            : {
    3133         [ #  # ]:          0 :     if( mbTitleOn )
    3134                 :            :     {
    3135         [ #  # ]:          0 :         rtl::OUString aTitle = maTitle.makeStringAndClear().trim();
    3136 [ #  # ][ #  # ]:          0 :         if (!aTitle.isEmpty() && mpDoc->GetDocumentShell())
                 [ #  # ]
    3137                 :            :         {
    3138                 :            :             uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
    3139 [ #  # ][ #  # ]:          0 :                 mpDoc->GetDocumentShell()->GetModel(), uno::UNO_QUERY_THROW);
    3140                 :            : 
    3141 [ #  # ][ #  # ]:          0 :             xDPS->getDocumentProperties()->setTitle(aTitle);
         [ #  # ][ #  # ]
    3142                 :            :         }
    3143         [ #  # ]:          0 :         InsertText( rInfo );
    3144                 :          0 :         mbTitleOn = false;
    3145                 :            :     }
    3146                 :          0 : }
    3147                 :            : 
    3148                 :          3 : void ScHTMLQueryParser::TableOn( const ImportInfo& rInfo )
    3149                 :            : {
    3150                 :          3 :     mpCurrTable = mpCurrTable->TableOn( rInfo );
    3151                 :          3 : }
    3152                 :            : 
    3153                 :          3 : void ScHTMLQueryParser::TableOff( const ImportInfo& rInfo )
    3154                 :            : {
    3155                 :          3 :     mpCurrTable = mpCurrTable->TableOff( rInfo );
    3156                 :          3 : }
    3157                 :            : 
    3158                 :          0 : void ScHTMLQueryParser::PreOn( const ImportInfo& rInfo )
    3159                 :            : {
    3160                 :          0 :     mpCurrTable = mpCurrTable->PreOn( rInfo );
    3161                 :          0 : }
    3162                 :            : 
    3163                 :          0 : void ScHTMLQueryParser::PreOff( const ImportInfo& rInfo )
    3164                 :            : {
    3165                 :          0 :     mpCurrTable = mpCurrTable->PreOff( rInfo );
    3166                 :          0 : }
    3167                 :            : 
    3168                 :          0 : void ScHTMLQueryParser::CloseTable( const ImportInfo& rInfo )
    3169                 :            : {
    3170                 :          0 :     mpCurrTable = mpCurrTable->CloseTable( rInfo );
    3171                 :          0 : }
    3172                 :            : 
    3173                 :            : namespace {
    3174                 :            : 
    3175                 :            : /**
    3176                 :            :  * Handler class for the CSS parser.
    3177                 :            :  */
    3178                 :          0 : class CSSHandler
    3179                 :            : {
    3180                 :            :     struct MemStr
    3181                 :            :     {
    3182                 :            :         const char* mp;
    3183                 :            :         size_t      mn;
    3184                 :            : 
    3185                 :          0 :         MemStr() : mp(NULL), mn(0) {}
    3186                 :          0 :         MemStr(const char* p, size_t n) : mp(p), mn(n) {}
    3187                 :          0 :         MemStr(const MemStr& r) : mp(r.mp), mn(r.mn) {}
    3188                 :          0 :         MemStr& operator=(const MemStr& r)
    3189                 :            :         {
    3190                 :          0 :             mp = r.mp;
    3191                 :          0 :             mn = r.mn;
    3192                 :          0 :             return *this;
    3193                 :            :         }
    3194                 :            :     };
    3195                 :            : 
    3196                 :            :     typedef std::pair<MemStr, MemStr> SelectorName; // element : class
    3197                 :            :     typedef std::vector<SelectorName> SelectorNames;
    3198                 :            :     SelectorNames maSelectorNames; /// current selector names.
    3199                 :            :     MemStr maPropName;  /// current property name.
    3200                 :            :     MemStr maPropValue; /// current property value.
    3201                 :            : 
    3202                 :            :     ScHTMLStyles& mrStyles;
    3203                 :            : public:
    3204                 :          0 :     CSSHandler(ScHTMLStyles& rStyles) : mrStyles(rStyles) {}
    3205                 :            : 
    3206                 :          0 :     void at_rule_name(const char* /*p*/, size_t /*n*/)
    3207                 :            :     {
    3208                 :            :         // For now, we ignore at-rule properties.
    3209                 :          0 :     }
    3210                 :            : 
    3211                 :          0 :     void selector_name(const char* p_elem, size_t n_elem, const char* p_class, size_t n_class)
    3212                 :            :     {
    3213                 :          0 :         MemStr aElem(p_elem, n_elem), aClass(p_class, n_class);
    3214                 :          0 :         SelectorName aName(aElem, aClass);
    3215         [ #  # ]:          0 :         maSelectorNames.push_back(aName);
    3216                 :          0 :     }
    3217                 :            : 
    3218                 :          0 :     void property_name(const char* p, size_t n)
    3219                 :            :     {
    3220                 :          0 :         maPropName = MemStr(p, n);
    3221                 :          0 :     }
    3222                 :            : 
    3223                 :          0 :     void value(const char* p, size_t n)
    3224                 :            :     {
    3225                 :          0 :         maPropValue = MemStr(p, n);
    3226                 :          0 :     }
    3227                 :            : 
    3228                 :          0 :     void begin_parse() {}
    3229                 :            : 
    3230                 :          0 :     void end_parse() {}
    3231                 :            : 
    3232                 :          0 :     void begin_block() {}
    3233                 :            : 
    3234                 :          0 :     void end_block()
    3235                 :            :     {
    3236                 :          0 :         maSelectorNames.clear();
    3237                 :          0 :     }
    3238                 :            : 
    3239                 :          0 :     void begin_property() {}
    3240                 :            : 
    3241                 :          0 :     void end_property()
    3242                 :            :     {
    3243 [ #  # ][ #  # ]:          0 :         SelectorNames::const_iterator itr = maSelectorNames.begin(), itrEnd = maSelectorNames.end();
    3244 [ #  # ][ #  # ]:          0 :         for (; itr != itrEnd; ++itr)
    3245                 :            :         {
    3246                 :            :             // Add this property to the collection for each selector.
    3247                 :          0 :             const SelectorName& rSelName = *itr;
    3248                 :          0 :             const MemStr& rElem = rSelName.first;
    3249                 :          0 :             const MemStr& rClass = rSelName.second;
    3250         [ #  # ]:          0 :             rtl::OUString aName(maPropName.mp, maPropName.mn, RTL_TEXTENCODING_UTF8);
    3251         [ #  # ]:          0 :             rtl::OUString aValue(maPropValue.mp, maPropValue.mn, RTL_TEXTENCODING_UTF8);
    3252         [ #  # ]:          0 :             mrStyles.add(rElem.mp, rElem.mn, rClass.mp, rClass.mn, aName, aValue);
    3253                 :          0 :         }
    3254                 :          0 :         maPropName = MemStr();
    3255                 :          0 :         maPropValue = MemStr();
    3256                 :          0 :     }
    3257                 :            : };
    3258                 :            : 
    3259                 :            : }
    3260                 :            : 
    3261                 :          0 : void ScHTMLQueryParser::ParseStyle(const rtl::OUString& rStrm)
    3262                 :            : {
    3263         [ #  # ]:          0 :     rtl::OString aStr = rtl::OUStringToOString(rStrm, RTL_TEXTENCODING_UTF8);
    3264         [ #  # ]:          0 :     CSSHandler aHdl(GetStyles());
    3265                 :          0 :     orcus::css_parser<CSSHandler> aParser(aStr.getStr(), aStr.getLength(), aHdl);
    3266                 :            :     try
    3267                 :            :     {
    3268         [ #  # ]:          0 :         aParser.parse();
    3269                 :            :     }
    3270                 :          0 :     catch (const orcus::css_parse_error&)
    3271                 :            :     {
    3272                 :            :         // Parsing of CSS failed.  Do nothing for now.
    3273                 :          0 :     }
    3274         [ #  # ]:          0 : }
    3275                 :            : 
    3276                 :            : // ----------------------------------------------------------------------------
    3277                 :            : 
    3278                 :        165 : IMPL_LINK( ScHTMLQueryParser, HTMLImportHdl, const ImportInfo*, pInfo )
    3279                 :            : {
    3280   [ +  +  +  +  :        165 :     switch( pInfo->eState )
                   +  - ]
    3281                 :            :     {
    3282                 :            :         case HTMLIMP_START:
    3283                 :          3 :         break;
    3284                 :            : 
    3285                 :            :         case HTMLIMP_NEXTTOKEN:
    3286                 :            :         case HTMLIMP_UNKNOWNATTR:
    3287                 :        102 :             ProcessToken( *pInfo );
    3288                 :        102 :         break;
    3289                 :            : 
    3290                 :            :         case HTMLIMP_INSERTPARA:
    3291                 :         18 :             mpCurrTable->InsertPara( *pInfo );
    3292                 :         18 :         break;
    3293                 :            : 
    3294                 :            :         case HTMLIMP_SETATTR:
    3295                 :            :         case HTMLIMP_INSERTTEXT:
    3296                 :            :         case HTMLIMP_INSERTFIELD:
    3297                 :         39 :         break;
    3298                 :            : 
    3299                 :            :         case HTMLIMP_END:
    3300         [ -  + ]:          3 :             while( mpCurrTable->GetTableId() != SC_HTML_GLOBAL_TABLE )
    3301                 :          0 :                 CloseTable( *pInfo );
    3302                 :          3 :         break;
    3303                 :            : 
    3304                 :            :         default:
    3305                 :            :             OSL_FAIL( "ScHTMLQueryParser::HTMLImportHdl - unknown ImportInfo::eState" );
    3306                 :            :     }
    3307                 :        165 :     return 0;
    3308                 :            : }
    3309                 :            : 
    3310                 :            : // ============================================================================
    3311                 :            : 
    3312                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10