LCOV - code coverage report
Current view: top level - sc/source/filter/excel - xihelper.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 291 437 66.6 %
Date: 2015-06-13 12:38:46 Functions: 32 41 78.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "xihelper.hxx"
      21             : #include <svl/itemset.hxx>
      22             : #include <svl/sharedstringpool.hxx>
      23             : #include <editeng/editobj.hxx>
      24             : #include <tools/urlobj.hxx>
      25             : #include "scitems.hxx"
      26             : #include <editeng/eeitem.hxx>
      27             : #include <editeng/flditem.hxx>
      28             : #include "document.hxx"
      29             : #include "rangelst.hxx"
      30             : #include "editutil.hxx"
      31             : #include "attrib.hxx"
      32             : #include "xltracer.hxx"
      33             : #include "xistream.hxx"
      34             : #include "xistyle.hxx"
      35             : #include "excform.hxx"
      36             : #include "stringutil.hxx"
      37             : #include "scmatrix.hxx"
      38             : #include "documentimport.hxx"
      39             : 
      40             : // Excel->Calc cell address/range conversion ==================================
      41             : 
      42             : namespace {
      43             : 
      44             : /** Fills the passed Calc address with the passed Excel cell coordinates without checking any limits. */
      45      332500 : inline void lclFillAddress( ScAddress& rScPos, sal_uInt16 nXclCol, sal_uInt32 nXclRow, SCTAB nScTab )
      46             : {
      47      332500 :     rScPos.SetCol( static_cast< SCCOL >( nXclCol ) );
      48      332500 :     rScPos.SetRow( static_cast< SCROW >( nXclRow ) );
      49      332500 :     rScPos.SetTab( nScTab );
      50      332500 : }
      51             : 
      52             : } // namespace
      53             : 
      54          84 : XclImpAddressConverter::XclImpAddressConverter( const XclImpRoot& rRoot ) :
      55          84 :     XclAddressConverterBase( rRoot.GetTracer(), rRoot.GetScMaxPos() )
      56             : {
      57          84 : }
      58             : 
      59             : // cell address ---------------------------------------------------------------
      60             : 
      61      338400 : bool XclImpAddressConverter::CheckAddress( const XclAddress& rXclPos, bool bWarn )
      62             : {
      63      338400 :     bool bValidCol = rXclPos.mnCol <= mnMaxCol;
      64      338400 :     bool bValidRow = rXclPos.mnRow <= mnMaxRow;
      65      338400 :     bool bValid = bValidCol && bValidRow;
      66      338400 :     if( !bValid && bWarn )
      67             :     {
      68        5899 :         mbColTrunc |= !bValidCol;
      69        5899 :         mbRowTrunc |= !bValidRow;
      70             :         mrTracer.TraceInvalidAddress( ScAddress(
      71        5899 :             static_cast< SCCOL >( rXclPos.mnCol ), static_cast< SCROW >( rXclPos.mnRow ), 0 ), maMaxPos );
      72             :     }
      73      338400 :     return bValid;
      74             : }
      75             : 
      76      335967 : bool XclImpAddressConverter::ConvertAddress( ScAddress& rScPos,
      77             :         const XclAddress& rXclPos, SCTAB nScTab, bool bWarn )
      78             : {
      79      335967 :     bool bValid = CheckAddress( rXclPos, bWarn );
      80      335967 :     if( bValid )
      81      330068 :         lclFillAddress( rScPos, rXclPos.mnCol, rXclPos.mnRow, nScTab );
      82      335967 :     return bValid;
      83             : }
      84             : 
      85         668 : ScAddress XclImpAddressConverter::CreateValidAddress(
      86             :         const XclAddress& rXclPos, SCTAB nScTab, bool bWarn )
      87             : {
      88         668 :     ScAddress aScPos( ScAddress::UNINITIALIZED );
      89         668 :     if( !ConvertAddress( aScPos, rXclPos, nScTab, bWarn ) )
      90             :     {
      91           0 :         aScPos.SetCol( static_cast< SCCOL >( ::std::min( rXclPos.mnCol, mnMaxCol ) ) );
      92           0 :         aScPos.SetRow( static_cast< SCROW >( ::std::min( rXclPos.mnRow, mnMaxRow ) ) );
      93           0 :         aScPos.SetTab( limit_cast< SCTAB >( nScTab, 0, maMaxPos.Tab() ) );
      94             :     }
      95         668 :     return aScPos;
      96             : }
      97             : 
      98             : // cell range -----------------------------------------------------------------
      99             : 
     100        1217 : bool XclImpAddressConverter::ConvertRange( ScRange& rScRange,
     101             :         const XclRange& rXclRange, SCTAB nScTab1, SCTAB nScTab2, bool bWarn )
     102             : {
     103             :     // check start position
     104        1217 :     bool bValidStart = CheckAddress( rXclRange.maFirst, bWarn );
     105        1217 :     if( bValidStart )
     106             :     {
     107        1216 :         lclFillAddress( rScRange.aStart, rXclRange.maFirst.mnCol, rXclRange.maFirst.mnRow, nScTab1 );
     108             : 
     109             :         // check & correct end position
     110        1216 :         sal_uInt16 nXclCol2 = rXclRange.maLast.mnCol;
     111        1216 :         sal_uInt32 nXclRow2 = rXclRange.maLast.mnRow;
     112        1216 :         if( !CheckAddress( rXclRange.maLast, bWarn ) )
     113             :         {
     114           0 :             nXclCol2 = ::std::min( nXclCol2, mnMaxCol );
     115           0 :             nXclRow2 = ::std::min( nXclRow2, mnMaxRow );
     116             :         }
     117        1216 :         lclFillAddress( rScRange.aEnd, nXclCol2, nXclRow2, nScTab2 );
     118             :     }
     119        1217 :     return bValidStart;
     120             : }
     121             : 
     122             : // cell range list ------------------------------------------------------------
     123             : 
     124         230 : void XclImpAddressConverter::ConvertRangeList( ScRangeList& rScRanges,
     125             :         const XclRangeList& rXclRanges, SCTAB nScTab, bool bWarn )
     126             : {
     127         230 :     rScRanges.RemoveAll();
     128         472 :     for( XclRangeVector::const_iterator aIt = rXclRanges.begin(), aEnd = rXclRanges.end(); aIt != aEnd; ++aIt )
     129             :     {
     130         242 :         ScRange aScRange( ScAddress::UNINITIALIZED );
     131         242 :         if( ConvertRange( aScRange, *aIt, nScTab, nScTab, bWarn ) )
     132         242 :             rScRanges.Append( aScRange );
     133             :     }
     134         230 : }
     135             : 
     136             : // String->EditEngine conversion ==============================================
     137             : 
     138             : namespace {
     139             : 
     140       77310 : EditTextObject* lclCreateTextObject( const XclImpRoot& rRoot,
     141             :         const XclImpString& rString, XclFontItemType eType, sal_uInt16 nXFIndex )
     142             : {
     143       77310 :     EditTextObject* pTextObj = 0;
     144             : 
     145       77310 :     const XclImpXFBuffer& rXFBuffer = rRoot.GetXFBuffer();
     146       77310 :     const XclImpFont* pFirstFont = rXFBuffer.GetFont( nXFIndex );
     147       77310 :     bool bFirstEscaped = pFirstFont && pFirstFont->HasEscapement();
     148             : 
     149       77310 :     if( rString.IsRich() || bFirstEscaped )
     150             :     {
     151          54 :         const XclImpFontBuffer& rFontBuffer = rRoot.GetFontBuffer();
     152          54 :         const XclFormatRunVec& rFormats = rString.GetFormats();
     153             : 
     154             :         ScEditEngineDefaulter& rEE = (eType == EXC_FONTITEM_NOTE) ?
     155          54 :             static_cast< ScEditEngineDefaulter& >( rRoot.GetDoc().GetNoteEngine() ) : rRoot.GetEditEngine();
     156          54 :         rEE.SetText( rString.GetText() );
     157             : 
     158          54 :         SfxItemSet aItemSet( rEE.GetEmptyItemSet() );
     159          54 :         if( bFirstEscaped )
     160           0 :             rFontBuffer.FillToItemSet( aItemSet, eType, rXFBuffer.GetFontIndex( nXFIndex ) );
     161          54 :         ESelection aSelection;
     162             : 
     163          54 :         XclFormatRun aNextRun;
     164          54 :         XclFormatRunVec::const_iterator aIt = rFormats.begin();
     165          54 :         XclFormatRunVec::const_iterator aEnd = rFormats.end();
     166             : 
     167          54 :         if( aIt != aEnd )
     168          54 :             aNextRun = *aIt++;
     169             :         else
     170           0 :             aNextRun.mnChar = 0xFFFF;
     171             : 
     172          54 :         sal_Int32 nLen = rString.GetText().getLength();
     173        3173 :         for( sal_Int32 nChar = 0; nChar < nLen; ++nChar )
     174             :         {
     175             :             // reached new different formatted text portion
     176        3119 :             if( nChar >= aNextRun.mnChar )
     177             :             {
     178             :                 // send items to edit engine
     179         105 :                 rEE.QuickSetAttribs( aItemSet, aSelection );
     180             : 
     181             :                 // start new item set
     182         105 :                 aItemSet.ClearItem();
     183         105 :                 rFontBuffer.FillToItemSet( aItemSet, eType, aNextRun.mnFontIdx );
     184             : 
     185             :                 // read new formatting information
     186         105 :                 if( aIt != aEnd )
     187          65 :                     aNextRun = *aIt++;
     188             :                 else
     189          40 :                     aNextRun.mnChar = 0xFFFF;
     190             : 
     191             :                 // reset selection start to current position
     192         105 :                 aSelection.nStartPara = aSelection.nEndPara;
     193         105 :                 aSelection.nStartPos = aSelection.nEndPos;
     194             :             }
     195             : 
     196             :             // set end of selection to current position
     197        3119 :             if( rString.GetText()[ nChar ] == '\n' )
     198             :             {
     199           1 :                 ++aSelection.nEndPara;
     200           1 :                 aSelection.nEndPos = 0;
     201             :             }
     202             :             else
     203        3118 :                 ++aSelection.nEndPos;
     204             :         }
     205             : 
     206             :         // send items of last text portion to edit engine
     207          54 :         rEE.QuickSetAttribs( aItemSet, aSelection );
     208             : 
     209          54 :         pTextObj = rEE.CreateTextObject();
     210             :     }
     211             : 
     212       77310 :     return pTextObj;
     213             : }
     214             : 
     215             : } // namespace
     216             : 
     217          14 : EditTextObject* XclImpStringHelper::CreateTextObject(
     218             :         const XclImpRoot& rRoot, const XclImpString& rString )
     219             : {
     220          14 :     return lclCreateTextObject( rRoot, rString, EXC_FONTITEM_EDITENG, 0 );
     221             : }
     222             : 
     223       77296 : void XclImpStringHelper::SetToDocument(
     224             :         ScDocumentImport& rDoc, const ScAddress& rPos, const XclImpRoot& rRoot,
     225             :         const XclImpString& rString, sal_uInt16 nXFIndex )
     226             : {
     227       77296 :     if (rString.GetText().isEmpty())
     228       77296 :         return;
     229             : 
     230       77296 :     ::std::unique_ptr< EditTextObject > pTextObj( lclCreateTextObject( rRoot, rString, EXC_FONTITEM_EDITENG, nXFIndex ) );
     231             : 
     232       77296 :     if (pTextObj.get())
     233             :     {
     234          40 :         rDoc.setEditCell(rPos, pTextObj.release());
     235             :     }
     236             :     else
     237             :     {
     238       77256 :         OUString aStr = rString.GetText();
     239       77256 :         if (aStr.indexOf('\n') != -1 || aStr.indexOf(CHAR_CR) != -1)
     240             :         {
     241             :             // Multiline content.
     242          13 :             ScFieldEditEngine& rEngine = rDoc.getDoc().GetEditEngine();
     243          13 :             rEngine.SetText(aStr);
     244          13 :             rDoc.setEditCell(rPos, rEngine.CreateTextObject());
     245             :         }
     246             :         else
     247             :         {
     248             :             // Normal text cell.
     249       77243 :             rDoc.setStringCell(rPos, aStr);
     250       77256 :         }
     251       77296 :     }
     252             : }
     253             : 
     254             : // Header/footer conversion ===================================================
     255             : 
     256         216 : XclImpHFConverter::XclImpHFPortionInfo::XclImpHFPortionInfo() :
     257             :     mnHeight( 0 ),
     258         216 :     mnMaxLineHt( 0 )
     259             : {
     260         216 :     maSel.nStartPara = maSel.nEndPara = 0;
     261         216 :     maSel.nStartPos = maSel.nEndPos = 0;
     262         216 : }
     263             : 
     264         224 : XclImpHFConverter::XclImpHFConverter( const XclImpRoot& rRoot ) :
     265             :     XclImpRoot( rRoot ),
     266         224 :     mrEE( rRoot.GetHFEditEngine() ),
     267         224 :     mxFontData( new XclFontData ),
     268         672 :     meCurrObj( EXC_HF_CENTER )
     269             : {
     270         224 : }
     271             : 
     272         224 : XclImpHFConverter::~XclImpHFConverter()
     273             : {
     274         224 : }
     275             : 
     276          72 : void XclImpHFConverter::ParseString( const OUString& rHFString )
     277             : {
     278             :     // edit engine objects
     279          72 :     mrEE.SetText( EMPTY_OUSTRING );
     280          72 :     maInfos.clear();
     281          72 :     maInfos.resize( EXC_HF_PORTION_COUNT );
     282          72 :     meCurrObj = EXC_HF_CENTER;
     283             : 
     284             :     // parser temporaries
     285          72 :     maCurrText.clear();
     286          72 :     OUString aReadFont;           // current font name
     287         144 :     OUString aReadStyle;          // current font style
     288          72 :     sal_uInt16 nReadHeight = 0; // current font height
     289          72 :     ResetFontData();
     290             : 
     291             :     /** State of the parser. */
     292             :     enum XclHFParserState
     293             :     {
     294             :         xlPSText,           /// Read text, search for functions.
     295             :         xlPSFunc,           /// Read function (token following a '&').
     296             :         xlPSFont,           /// Read font name ('&' is followed by '"', reads until next '"' or ',').
     297             :         xlPSFontStyle,      /// Read font style name (font part after ',', reads until next '"').
     298             :         xlPSHeight          /// Read font height ('&' is followed by num. digits, reads until non-digit).
     299          72 :     } eState = xlPSText;
     300             : 
     301          72 :     const sal_Unicode* pChar = rHFString.getStr();
     302          72 :     const sal_Unicode* pNull = pChar + rHFString.getLength(); // pointer to teminating null char
     303        1203 :     while( *pChar )
     304             :     {
     305        1059 :         switch( eState )
     306             :         {
     307             : 
     308             : // --- read text character ---
     309             : 
     310             :             case xlPSText:
     311             :             {
     312         464 :                 switch( *pChar )
     313             :                 {
     314             :                     case '&':           // new command
     315         175 :                         InsertText();
     316         175 :                         eState = xlPSFunc;
     317         175 :                     break;
     318             :                     case '\n':          // line break
     319           0 :                         InsertText();
     320           0 :                         InsertLineBreak();
     321           0 :                     break;
     322             :                     default:
     323         289 :                         maCurrText += OUString(*pChar);
     324             :                 }
     325             :             }
     326         464 :             break;
     327             : 
     328             : // --- read control sequence ---
     329             : 
     330             :             case xlPSFunc:
     331             :             {
     332         175 :                 eState = xlPSText;
     333         175 :                 switch( *pChar )
     334             :                 {
     335           0 :                     case '&':   maCurrText += "&";  break;  // the '&' character
     336             : 
     337           6 :                     case 'L':   SetNewPortion( EXC_HF_LEFT );   break;  // Left portion
     338          59 :                     case 'C':   SetNewPortion( EXC_HF_CENTER ); break;  // Center portion
     339           6 :                     case 'R':   SetNewPortion( EXC_HF_RIGHT );  break;  // Right portion
     340             : 
     341          33 :                     case 'P':   InsertField( SvxFieldItem( SvxPageField(), EE_FEATURE_FIELD ) );      break;  // page
     342           0 :                     case 'N':   InsertField( SvxFieldItem( SvxPagesField(), EE_FEATURE_FIELD ) );     break;  // page count
     343           3 :                     case 'D':   InsertField( SvxFieldItem( SvxDateField(), EE_FEATURE_FIELD ) );      break;  // date
     344           0 :                     case 'T':   InsertField( SvxFieldItem( SvxTimeField(), EE_FEATURE_FIELD ) );      break;  // time
     345          33 :                     case 'A':   InsertField( SvxFieldItem( SvxTableField(), EE_FEATURE_FIELD ) );     break;  // table name
     346             : 
     347             :                     case 'Z':           // file path
     348           0 :                         InsertField( SvxFieldItem( SvxExtFileField(), EE_FEATURE_FIELD ) );   // convert to full name
     349           0 :                         if( (pNull - pChar >= 2) && (*(pChar + 1) == '&') && (*(pChar + 2) == 'F') )
     350             :                         {
     351             :                             // &Z&F found - ignore the &F part
     352           0 :                             pChar += 2;
     353             :                         }
     354           0 :                     break;
     355             :                     case 'F':           // file name
     356           1 :                         InsertField( SvxFieldItem( SvxExtFileField( EMPTY_OUSTRING, SVXFILETYPE_VAR, SVXFILEFORMAT_NAME_EXT ), EE_FEATURE_FIELD ) );
     357           1 :                     break;
     358             : 
     359             :                     case 'U':           // underline
     360           0 :                         SetAttribs();
     361           0 :                         mxFontData->mnUnderline = (mxFontData->mnUnderline == EXC_FONTUNDERL_SINGLE) ?
     362           0 :                             EXC_FONTUNDERL_NONE : EXC_FONTUNDERL_SINGLE;
     363           0 :                     break;
     364             :                     case 'E':           // double underline
     365           0 :                         SetAttribs();
     366           0 :                         mxFontData->mnUnderline = (mxFontData->mnUnderline == EXC_FONTUNDERL_DOUBLE) ?
     367           0 :                             EXC_FONTUNDERL_NONE : EXC_FONTUNDERL_DOUBLE;
     368           0 :                     break;
     369             :                     case 'S':           // strikeout
     370           0 :                         SetAttribs();
     371           0 :                         mxFontData->mbStrikeout = !mxFontData->mbStrikeout;
     372           0 :                     break;
     373             :                     case 'X':           // superscript
     374           0 :                         SetAttribs();
     375           0 :                         mxFontData->mnEscapem = (mxFontData->mnEscapem == EXC_FONTESC_SUPER) ?
     376           0 :                             EXC_FONTESC_NONE : EXC_FONTESC_SUPER;
     377           0 :                     break;
     378             :                     case 'Y':           // subsrcipt
     379           0 :                         SetAttribs();
     380           0 :                         mxFontData->mnEscapem = (mxFontData->mnEscapem == EXC_FONTESC_SUB) ?
     381           0 :                             EXC_FONTESC_NONE : EXC_FONTESC_SUB;
     382           0 :                     break;
     383             : 
     384             :                     case '\"':          // font name
     385          16 :                         aReadFont.clear();
     386          16 :                         aReadStyle.clear();
     387          16 :                         eState = xlPSFont;
     388          16 :                     break;
     389             :                     default:
     390          18 :                         if( ('0' <= *pChar) && (*pChar <= '9') )    // font size
     391             :                         {
     392          18 :                             nReadHeight = *pChar - '0';
     393          18 :                             eState = xlPSHeight;
     394             :                         }
     395             :                 }
     396             :             }
     397         175 :             break;
     398             : 
     399             : // --- read font name ---
     400             : 
     401             :             case xlPSFont:
     402             :             {
     403         256 :                 switch( *pChar )
     404             :                 {
     405             :                     case '\"':
     406           0 :                         --pChar;
     407             :                         // run through
     408             :                     case ',':
     409          16 :                         eState = xlPSFontStyle;
     410          16 :                     break;
     411             :                     default:
     412         240 :                         aReadFont += OUString(*pChar);
     413             :                 }
     414             :             }
     415         256 :             break;
     416             : 
     417             : // --- read font style ---
     418             : 
     419             :             case xlPSFontStyle:
     420             :             {
     421         128 :                 switch( *pChar )
     422             :                 {
     423             :                     case '\"':
     424          16 :                         SetAttribs();
     425          16 :                         if( !aReadFont.isEmpty() )
     426          16 :                             mxFontData->maName = aReadFont;
     427          16 :                         mxFontData->maStyle = aReadStyle;
     428          16 :                         eState = xlPSText;
     429          16 :                     break;
     430             :                     default:
     431         112 :                         aReadStyle += OUString(*pChar);
     432             :                 }
     433             :             }
     434         128 :             break;
     435             : 
     436             : // --- read font height ---
     437             : 
     438             :             case xlPSHeight:
     439             :             {
     440          36 :                 if( ('0' <= *pChar) && (*pChar <= '9') )
     441             :                 {
     442          36 :                     if( nReadHeight != 0xFFFF )
     443             :                     {
     444          18 :                         nReadHeight *= 10;
     445          18 :                         nReadHeight += (*pChar - '0');
     446          18 :                         if( nReadHeight > 1600 )    // max 1600pt = 32000twips
     447           0 :                             nReadHeight = 0xFFFF;
     448             :                     }
     449             :                 }
     450             :                 else
     451             :                 {
     452          18 :                     if( (nReadHeight != 0) && (nReadHeight != 0xFFFF) )
     453             :                     {
     454          18 :                         SetAttribs();
     455          18 :                         mxFontData->mnHeight = nReadHeight * 20;
     456             :                     }
     457          18 :                     --pChar;
     458          18 :                     eState = xlPSText;
     459             :                 }
     460             :             }
     461          36 :             break;
     462             :         }
     463        1059 :         ++pChar;
     464             :     }
     465             : 
     466             :     // finalize
     467          72 :     CreateCurrObject();
     468          72 :     maInfos[ EXC_HF_LEFT   ].mnHeight += GetMaxLineHeight( EXC_HF_LEFT );
     469          72 :     maInfos[ EXC_HF_CENTER ].mnHeight += GetMaxLineHeight( EXC_HF_CENTER );
     470         144 :     maInfos[ EXC_HF_RIGHT  ].mnHeight += GetMaxLineHeight( EXC_HF_RIGHT );
     471          72 : }
     472             : 
     473         144 : void XclImpHFConverter::FillToItemSet( SfxItemSet& rItemSet, sal_uInt16 nWhichId ) const
     474             : {
     475         144 :     ScPageHFItem aHFItem( nWhichId );
     476         144 :     if( maInfos[ EXC_HF_LEFT ].mxObj.get() )
     477          12 :         aHFItem.SetLeftArea( *maInfos[ EXC_HF_LEFT ].mxObj );
     478         144 :     if( maInfos[ EXC_HF_CENTER ].mxObj.get() )
     479         144 :         aHFItem.SetCenterArea( *maInfos[ EXC_HF_CENTER ].mxObj );
     480         144 :     if( maInfos[ EXC_HF_RIGHT ].mxObj.get() )
     481          12 :         aHFItem.SetRightArea( *maInfos[ EXC_HF_RIGHT ].mxObj );
     482         144 :     rItemSet.Put( aHFItem );
     483         144 : }
     484             : 
     485          72 : sal_Int32 XclImpHFConverter::GetTotalHeight() const
     486             : {
     487          72 :     return ::std::max( maInfos[ EXC_HF_LEFT ].mnHeight,
     488         144 :         ::std::max( maInfos[ EXC_HF_CENTER ].mnHeight, maInfos[ EXC_HF_RIGHT ].mnHeight ) );
     489             : }
     490             : 
     491             : // private --------------------------------------------------------------------
     492             : 
     493         216 : sal_uInt16 XclImpHFConverter::GetMaxLineHeight( XclImpHFPortion ePortion ) const
     494             : {
     495         216 :     sal_uInt16 nMaxHt = maInfos[ ePortion ].mnMaxLineHt;
     496         216 :     return (nMaxHt == 0) ? mxFontData->mnHeight : nMaxHt;
     497             : }
     498             : 
     499           0 : sal_uInt16 XclImpHFConverter::GetCurrMaxLineHeight() const
     500             : {
     501           0 :     return GetMaxLineHeight( meCurrObj );
     502             : }
     503             : 
     504         114 : void XclImpHFConverter::UpdateMaxLineHeight( XclImpHFPortion ePortion )
     505             : {
     506         114 :     sal_uInt16& rnMaxHt = maInfos[ ePortion ].mnMaxLineHt;
     507         114 :     rnMaxHt = ::std::max( rnMaxHt, mxFontData->mnHeight );
     508         114 : }
     509             : 
     510         114 : void XclImpHFConverter::UpdateCurrMaxLineHeight()
     511             : {
     512         114 :     UpdateMaxLineHeight( meCurrObj );
     513         114 : }
     514             : 
     515         122 : void XclImpHFConverter::SetAttribs()
     516             : {
     517         122 :     ESelection& rSel = GetCurrSel();
     518         122 :     if( (rSel.nStartPara != rSel.nEndPara) || (rSel.nStartPos != rSel.nEndPos) )
     519             :     {
     520          82 :         SfxItemSet aItemSet( mrEE.GetEmptyItemSet() );
     521         164 :         XclImpFont aFont( GetRoot(), *mxFontData );
     522          82 :         aFont.FillToItemSet( aItemSet, EXC_FONTITEM_HF );
     523          82 :         mrEE.QuickSetAttribs( aItemSet, rSel );
     524          82 :         rSel.nStartPara = rSel.nEndPara;
     525         164 :         rSel.nStartPos = rSel.nEndPos;
     526             :     }
     527         122 : }
     528             : 
     529          88 : void XclImpHFConverter::ResetFontData()
     530             : {
     531          88 :     if( const XclImpFont* pFirstFont = GetFontBuffer().GetFont( EXC_FONT_APP ) )
     532          88 :         *mxFontData = pFirstFont->GetFontData();
     533             :     else
     534             :     {
     535           0 :         mxFontData->Clear();
     536           0 :         mxFontData->mnHeight = 200;
     537             :     }
     538          88 : }
     539             : 
     540         263 : void XclImpHFConverter::InsertText()
     541             : {
     542         263 :     if( !maCurrText.isEmpty() )
     543             :     {
     544          44 :         ESelection& rSel = GetCurrSel();
     545          44 :         mrEE.QuickInsertText( maCurrText, ESelection( rSel.nEndPara, rSel.nEndPos, rSel.nEndPara, rSel.nEndPos ) );
     546          44 :         rSel.nEndPos = rSel.nEndPos + maCurrText.getLength();
     547          44 :         maCurrText.clear();
     548          44 :         UpdateCurrMaxLineHeight();
     549             :     }
     550         263 : }
     551             : 
     552          70 : void XclImpHFConverter::InsertField( const SvxFieldItem& rFieldItem )
     553             : {
     554          70 :     ESelection& rSel = GetCurrSel();
     555          70 :     mrEE.QuickInsertField( rFieldItem, ESelection( rSel.nEndPara, rSel.nEndPos, rSel.nEndPara, rSel.nEndPos ) );
     556          70 :     ++rSel.nEndPos;
     557          70 :     UpdateCurrMaxLineHeight();
     558          70 : }
     559             : 
     560           0 : void XclImpHFConverter::InsertLineBreak()
     561             : {
     562           0 :     ESelection& rSel = GetCurrSel();
     563           0 :     mrEE.QuickInsertText( OUString('\n'), ESelection( rSel.nEndPara, rSel.nEndPos, rSel.nEndPara, rSel.nEndPos ) );
     564           0 :     ++rSel.nEndPara;
     565           0 :     rSel.nEndPos = 0;
     566           0 :     GetCurrInfo().mnHeight += GetCurrMaxLineHeight();
     567           0 :     GetCurrInfo().mnMaxLineHt = 0;
     568           0 : }
     569             : 
     570          88 : void XclImpHFConverter::CreateCurrObject()
     571             : {
     572          88 :     InsertText();
     573          88 :     SetAttribs();
     574          88 :     GetCurrObj().reset( mrEE.CreateTextObject() );
     575          88 : }
     576             : 
     577          71 : void XclImpHFConverter::SetNewPortion( XclImpHFPortion eNew )
     578             : {
     579          71 :     if( eNew != meCurrObj )
     580             :     {
     581          16 :         CreateCurrObject();
     582          16 :         meCurrObj = eNew;
     583          16 :         if( GetCurrObj().get() )
     584           4 :             mrEE.SetText( *GetCurrObj() );
     585             :         else
     586          12 :             mrEE.SetText( EMPTY_OUSTRING );
     587          16 :         ResetFontData();
     588             :     }
     589          71 : }
     590             : 
     591             : // URL conversion =============================================================
     592             : 
     593             : namespace {
     594             : 
     595          60 : void lclAppendUrlChar( OUString& rUrl, sal_Unicode cChar )
     596             : {
     597             :     // encode special characters
     598          60 :     switch( cChar )
     599             :     {
     600           0 :         case '#':   rUrl += "%23";  break;
     601           0 :         case '%':   rUrl += "%25";  break;
     602          60 :         default:    rUrl += OUString( cChar );
     603             :     }
     604          60 : }
     605             : 
     606             : } // namespace
     607             : 
     608           8 : void XclImpUrlHelper::DecodeUrl(
     609             :         OUString& rUrl, OUString& rTabName, bool& rbSameWb,
     610             :         const XclImpRoot& rRoot, const OUString& rEncodedUrl )
     611             : {
     612             :     enum
     613             :     {
     614             :         xlUrlInit,              /// Initial state, read string mode character.
     615             :         xlUrlPath,              /// Read URL path.
     616             :         xlUrlFileName,          /// Read file name.
     617             :         xlUrlSheetName,         /// Read sheet name.
     618             :         xlUrlRaw                /// Raw mode. No control characters will occur.
     619           8 :     } eState = xlUrlInit;
     620             : 
     621           8 :     bool bEncoded = true;
     622           8 :     rbSameWb = false;
     623             : 
     624           8 :     sal_Unicode cCurrDrive = 0;
     625           8 :     OUString aDosBase( INetURLObject( rRoot.GetBasePath() ).getFSysPath( INetURLObject::FSYS_DOS ) );
     626           8 :     if (!aDosBase.isEmpty() && aDosBase.match(":\\", 1))
     627           0 :         cCurrDrive = aDosBase[0];
     628             : 
     629           8 :     const sal_Unicode* pChar = rEncodedUrl.getStr();
     630         112 :     while( *pChar )
     631             :     {
     632          96 :         switch( eState )
     633             :         {
     634             : 
     635             : // --- first character ---
     636             : 
     637             :             case xlUrlInit:
     638             :             {
     639           8 :                 switch( *pChar )
     640             :                 {
     641             :                     case EXC_URLSTART_ENCODED:
     642           2 :                         eState = xlUrlPath;
     643           2 :                     break;
     644             :                     case EXC_URLSTART_SELF:
     645             :                     case EXC_URLSTART_SELFENCODED:
     646           6 :                         rbSameWb = true;
     647           6 :                         eState = xlUrlSheetName;
     648           6 :                     break;
     649             :                     case '[':
     650           0 :                         bEncoded = false;
     651           0 :                         eState = xlUrlFileName;
     652           0 :                     break;
     653             :                     default:
     654           0 :                         bEncoded = false;
     655           0 :                         lclAppendUrlChar( rUrl, *pChar );
     656           0 :                         eState = xlUrlPath;
     657             :                 }
     658             :             }
     659           8 :             break;
     660             : 
     661             : // --- URL path ---
     662             : 
     663             :             case xlUrlPath:
     664             :             {
     665          68 :                 switch( *pChar )
     666             :                 {
     667             :                     case EXC_URL_DOSDRIVE:
     668             :                     {
     669           0 :                         if( *(pChar + 1) )
     670             :                         {
     671           0 :                             ++pChar;
     672           0 :                             if( *pChar == '@' )
     673           0 :                                 rUrl += "\\\\";
     674             :                             else
     675             :                             {
     676           0 :                                 lclAppendUrlChar( rUrl, *pChar );
     677           0 :                                 rUrl += ":\\";
     678             :                             }
     679             :                         }
     680             :                         else
     681           0 :                             rUrl += "<NULL-DRIVE!>";
     682             :                     }
     683           0 :                     break;
     684             :                     case EXC_URL_DRIVEROOT:
     685           2 :                         if( cCurrDrive )
     686             :                         {
     687           0 :                             lclAppendUrlChar( rUrl, cCurrDrive );
     688           0 :                             rUrl += ":";
     689             :                         }
     690             :                         // run through
     691             :                     case EXC_URL_SUBDIR:
     692           8 :                         if( bEncoded )
     693           8 :                             rUrl += "\\";
     694             :                         else    // control character in raw name -> DDE link
     695             :                         {
     696           0 :                             rUrl += OUString( EXC_DDE_DELIM );
     697           0 :                             eState = xlUrlRaw;
     698             :                         }
     699           8 :                     break;
     700             :                     case EXC_URL_PARENTDIR:
     701           0 :                         rUrl += "..\\";
     702           0 :                     break;
     703             :                     case EXC_URL_RAW:
     704             :                     {
     705           0 :                         if( *(pChar + 1) )
     706             :                         {
     707           0 :                             sal_Int32 nLen = *++pChar;
     708           0 :                             for( sal_Int32 nChar = 0; (nChar < nLen) && *(pChar + 1); ++nChar )
     709           0 :                                 lclAppendUrlChar( rUrl, *++pChar );
     710             : //                            rUrl.Append( ':' );
     711             :                         }
     712             :                     }
     713           0 :                     break;
     714             :                     case '[':
     715           0 :                         eState = xlUrlFileName;
     716           0 :                     break;
     717             :                     default:
     718          60 :                         lclAppendUrlChar( rUrl, *pChar );
     719             :                 }
     720             :             }
     721          68 :             break;
     722             : 
     723             : // --- file name ---
     724             : 
     725             :             case xlUrlFileName:
     726             :             {
     727           0 :                 switch( *pChar )
     728             :                 {
     729           0 :                     case ']':   eState = xlUrlSheetName;    break;
     730           0 :                     default:    lclAppendUrlChar( rUrl, *pChar );
     731             :                 }
     732             :             }
     733           0 :             break;
     734             : 
     735             : // --- sheet name ---
     736             : 
     737             :             case xlUrlSheetName:
     738          20 :                 rTabName += OUString( *pChar );
     739          20 :             break;
     740             : 
     741             : // --- raw read mode ---
     742             : 
     743             :             case xlUrlRaw:
     744           0 :                 lclAppendUrlChar( rUrl, *pChar );
     745           0 :             break;
     746             :         }
     747             : 
     748          96 :         ++pChar;
     749           8 :     }
     750           8 : }
     751             : 
     752           2 : void XclImpUrlHelper::DecodeUrl(
     753             :     OUString& rUrl, bool& rbSameWb, const XclImpRoot& rRoot, const OUString& rEncodedUrl )
     754             : {
     755           2 :     OUString aTabName;
     756           4 :     OUString aUrl;
     757           2 :     DecodeUrl( aUrl, aTabName, rbSameWb, rRoot, rEncodedUrl );
     758           2 :     rUrl = aUrl;
     759           2 :     OSL_ENSURE( aTabName.isEmpty(), "XclImpUrlHelper::DecodeUrl - sheet name ignored" );
     760           2 : }
     761             : 
     762           0 : bool XclImpUrlHelper::DecodeLink( OUString& rApplic, OUString& rTopic, const OUString& rEncUrl )
     763             : {
     764           0 :     sal_Int32 nPos = rEncUrl.indexOf( EXC_DDE_DELIM );
     765           0 :     if( (nPos > 0) && (nPos + 1 < rEncUrl.getLength()) )
     766             :     {
     767           0 :         rApplic = rEncUrl.copy( 0, nPos );
     768           0 :         rTopic = rEncUrl.copy( nPos + 1 );
     769           0 :         return true;
     770             :     }
     771           0 :     return false;
     772             : }
     773             : 
     774             : // Cached Values ==============================================================
     775             : 
     776           2 : XclImpCachedValue::XclImpCachedValue( XclImpStream& rStrm ) :
     777             :     mfValue( 0.0 ),
     778           2 :     mnBoolErr( 0 )
     779             : {
     780           2 :     mnType = rStrm.ReaduInt8();
     781           2 :     switch( mnType )
     782             :     {
     783             :         case EXC_CACHEDVAL_EMPTY:
     784           0 :             rStrm.Ignore( 8 );
     785           0 :         break;
     786             :         case EXC_CACHEDVAL_DOUBLE:
     787           0 :             mfValue = rStrm.ReadDouble();
     788           0 :         break;
     789             :         case EXC_CACHEDVAL_STRING:
     790           2 :             maStr = rStrm.ReadUniString();
     791           2 :         break;
     792             :         case EXC_CACHEDVAL_BOOL:
     793             :         case EXC_CACHEDVAL_ERROR:
     794             :         {
     795             :             double fVal;
     796           0 :             mnBoolErr = rStrm.ReaduInt8();
     797           0 :             rStrm.Ignore( 7 );
     798             : 
     799           0 :             const ScTokenArray* pScTokArr = rStrm.GetRoot().GetOldFmlaConverter().GetBoolErr(
     800           0 :                 XclTools::ErrorToEnum( fVal, mnType == EXC_CACHEDVAL_ERROR, mnBoolErr ) );
     801           0 :             if( pScTokArr )
     802           0 :                 mxTokArr.reset( pScTokArr->Clone() );
     803             :         }
     804           0 :         break;
     805             :         default:
     806             :             OSL_FAIL( "XclImpCachedValue::XclImpCachedValue - unknown data type" );
     807             :     }
     808           2 : }
     809             : 
     810           2 : XclImpCachedValue::~XclImpCachedValue()
     811             : {
     812           2 : }
     813             : 
     814           0 : sal_uInt16 XclImpCachedValue::GetScError() const
     815             : {
     816           0 :     return (mnType == EXC_CACHEDVAL_ERROR) ? XclTools::GetScErrorCode( mnBoolErr ) : 0;
     817             : }
     818             : 
     819             : // Matrix Cached Values ==============================================================
     820             : 
     821           0 : XclImpCachedMatrix::XclImpCachedMatrix( XclImpStream& rStrm ) :
     822             :     mnScCols( 0 ),
     823           0 :     mnScRows( 0 )
     824             : {
     825           0 :     mnScCols = rStrm.ReaduInt8();
     826           0 :     mnScRows = rStrm.ReaduInt16();
     827             : 
     828           0 :     if( rStrm.GetRoot().GetBiff() <= EXC_BIFF5 )
     829             :     {
     830             :         // in BIFF2-BIFF7: 256 columns represented by 0 columns
     831           0 :         if( mnScCols == 0 )
     832           0 :             mnScCols = 256;
     833             :     }
     834             :     else
     835             :     {
     836             :         // in BIFF8: columns and rows decreaed by 1
     837           0 :         ++mnScCols;
     838           0 :         ++mnScRows;
     839             :     }
     840             : 
     841             :     //assuming worse case scenario of unknown types
     842           0 :     const size_t nMinRecordSize = 1;
     843           0 :     const size_t nMaxRows = rStrm.GetRecLeft() / (nMinRecordSize * mnScCols);
     844           0 :     if (mnScRows > nMaxRows)
     845             :     {
     846             :         SAL_WARN("sc", "Parsing error: " << nMaxRows <<
     847             :                  " max possible rows, but " << mnScRows << " claimed, truncating");
     848           0 :         mnScRows = nMaxRows;
     849             :     }
     850             : 
     851           0 :     for( SCSIZE nScRow = 0; nScRow < mnScRows; ++nScRow )
     852           0 :         for( SCSIZE nScCol = 0; nScCol < mnScCols; ++nScCol )
     853           0 :             maValueList.push_back( new XclImpCachedValue( rStrm ) );
     854           0 : }
     855             : 
     856           0 : XclImpCachedMatrix::~XclImpCachedMatrix()
     857             : {
     858           0 : }
     859             : 
     860           0 : ScMatrixRef XclImpCachedMatrix::CreateScMatrix( svl::SharedStringPool& rPool ) const
     861             : {
     862           0 :     ScMatrixRef xScMatrix;
     863             :     OSL_ENSURE( mnScCols * mnScRows == maValueList.size(), "XclImpCachedMatrix::CreateScMatrix - element count mismatch" );
     864           0 :     if( mnScCols && mnScRows && static_cast< sal_uLong >( mnScCols * mnScRows ) <= maValueList.size() )
     865             :     {
     866           0 :         xScMatrix = new ScMatrix(mnScCols, mnScRows, 0.0);
     867           0 :         XclImpValueList::const_iterator itValue = maValueList.begin();
     868           0 :         for( SCSIZE nScRow = 0; nScRow < mnScRows; ++nScRow )
     869             :         {
     870           0 :             for( SCSIZE nScCol = 0; nScCol < mnScCols; ++nScCol )
     871             :             {
     872           0 :                 switch( itValue->GetType() )
     873             :                 {
     874             :                     case EXC_CACHEDVAL_EMPTY:
     875             :                         // Excel shows 0.0 here, not an empty cell
     876           0 :                         xScMatrix->PutEmpty( nScCol, nScRow );
     877           0 :                     break;
     878             :                     case EXC_CACHEDVAL_DOUBLE:
     879           0 :                         xScMatrix->PutDouble( itValue->GetValue(), nScCol, nScRow );
     880           0 :                     break;
     881             :                     case EXC_CACHEDVAL_STRING:
     882           0 :                         xScMatrix->PutString(rPool.intern(itValue->GetString()), nScCol, nScRow);
     883           0 :                     break;
     884             :                     case EXC_CACHEDVAL_BOOL:
     885           0 :                         xScMatrix->PutBoolean( itValue->GetBool(), nScCol, nScRow );
     886           0 :                     break;
     887             :                     case EXC_CACHEDVAL_ERROR:
     888           0 :                         xScMatrix->PutError( itValue->GetScError(), nScCol, nScRow );
     889           0 :                     break;
     890             :                     default:
     891             :                         OSL_FAIL( "XclImpCachedMatrix::CreateScMatrix - unknown value type" );
     892           0 :                         xScMatrix->PutEmpty( nScCol, nScRow );
     893             :                 }
     894           0 :                 ++itValue;
     895             :             }
     896             :         }
     897             :     }
     898           0 :     return xScMatrix;
     899          30 : }
     900             : 
     901             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11