LCOV - code coverage report
Current view: top level - libreoffice/sc/source/filter/excel - excimp8.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 248 399 62.2 %
Date: 2012-12-27 Functions: 35 49 71.4 %
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 "excimp8.hxx"
      21             : 
      22             : #include <boost/bind.hpp>
      23             : 
      24             : #include <scitems.hxx>
      25             : #include <comphelper/processfactory.hxx>
      26             : #include <comphelper/mediadescriptor.hxx>
      27             : #include <unotools/fltrcfg.hxx>
      28             : 
      29             : #include <svtools/wmf.hxx>
      30             : 
      31             : #include <editeng/eeitem.hxx>
      32             : 
      33             : #include <sfx2/docfile.hxx>
      34             : #include <sfx2/objsh.hxx>
      35             : #include <sfx2/request.hxx>
      36             : #include <sfx2/app.hxx>
      37             : #include <sfx2/docinf.hxx>
      38             : #include <sfx2/frame.hxx>
      39             : 
      40             : #include <editeng/brshitem.hxx>
      41             : #include <editeng/editdata.hxx>
      42             : #include <editeng/editeng.hxx>
      43             : #include <editeng/editobj.hxx>
      44             : #include <editeng/editstat.hxx>
      45             : #include <editeng/colritem.hxx>
      46             : #include <editeng/udlnitem.hxx>
      47             : #include <editeng/wghtitem.hxx>
      48             : #include <editeng/postitem.hxx>
      49             : #include <editeng/crsditem.hxx>
      50             : #include <editeng/flditem.hxx>
      51             : #include <svx/xflclit.hxx>
      52             : 
      53             : #include <vcl/graph.hxx>
      54             : #include <vcl/bmpacc.hxx>
      55             : #include <sot/exchange.hxx>
      56             : 
      57             : #include <svl/stritem.hxx>
      58             : 
      59             : #include <tools/string.hxx>
      60             : #include <rtl/math.hxx>
      61             : #include <unotools/localedatawrapper.hxx>
      62             : #include <unotools/charclass.hxx>
      63             : #include <drwlayer.hxx>
      64             : 
      65             : #include <boost/scoped_array.hpp>
      66             : 
      67             : #include "cell.hxx"
      68             : #include "document.hxx"
      69             : #include "patattr.hxx"
      70             : #include "docpool.hxx"
      71             : #include "attrib.hxx"
      72             : #include "conditio.hxx"
      73             : #include "dbdata.hxx"
      74             : #include "globalnames.hxx"
      75             : #include "editutil.hxx"
      76             : #include "markdata.hxx"
      77             : #include "rangenam.hxx"
      78             : #include "docoptio.hxx"
      79             : #include "globstr.hrc"
      80             : #include "fprogressbar.hxx"
      81             : #include "xltracer.hxx"
      82             : #include "xihelper.hxx"
      83             : #include "xipage.hxx"
      84             : #include "xicontent.hxx"
      85             : #include "xilink.hxx"
      86             : #include "xiescher.hxx"
      87             : #include "xipivot.hxx"
      88             : 
      89             : #include "excform.hxx"
      90             : #include "scextopt.hxx"
      91             : #include "stlpool.hxx"
      92             : #include "stlsheet.hxx"
      93             : #include "detfunc.hxx"
      94             : #include "macromgr.hxx"
      95             : #include "queryentry.hxx"
      96             : 
      97             : #include <com/sun/star/document/XDocumentProperties.hpp>
      98             : #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
      99             : #include <com/sun/star/script/ModuleInfo.hpp>
     100             : #include <com/sun/star/container/XIndexContainer.hpp>
     101             : #include <cppuhelper/component_context.hxx>
     102             : #include "xltoolbar.hxx"
     103             : #include <oox/ole/vbaproject.hxx>
     104             : #include <oox/ole/olestorage.hxx>
     105             : #include <unotools/streamwrap.hxx>
     106             : #include <comphelper/processfactory.hxx>
     107             : 
     108             : using namespace com::sun::star;
     109             : using namespace ::comphelper;
     110             : using ::rtl::OUString;
     111             : 
     112             : //OleNameOverrideContainer
     113             : 
     114             : typedef ::cppu::WeakImplHelper1< container::XNameContainer > OleNameOverrideContainer_BASE;
     115             : 
     116           9 : class OleNameOverrideContainer : public OleNameOverrideContainer_BASE
     117             : {
     118             : private:
     119             :     typedef boost::unordered_map< rtl::OUString, uno::Reference< container::XIndexContainer >, ::rtl::OUStringHash,
     120             :        ::std::equal_to< ::rtl::OUString > > NamedIndexToOleName;
     121             :     NamedIndexToOleName  IdToOleNameHash;
     122             :     ::osl::Mutex m_aMutex;
     123             : public:
     124             :     // XElementAccess
     125           0 :     virtual uno::Type SAL_CALL getElementType(  ) throw (uno::RuntimeException) { return  container::XIndexContainer::static_type(0); }
     126           0 :     virtual ::sal_Bool SAL_CALL hasElements(  ) throw (uno::RuntimeException)
     127             :     {
     128           0 :         ::osl::MutexGuard aGuard( m_aMutex );
     129           0 :         return ( IdToOleNameHash.size() > 0 );
     130             :     }
     131             :     // XNameAcess
     132           0 :     virtual uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
     133             :     {
     134           0 :         ::osl::MutexGuard aGuard( m_aMutex );
     135           0 :         if ( !hasByName(aName) )
     136           0 :             throw container::NoSuchElementException();
     137           0 :         return uno::makeAny( IdToOleNameHash[ aName ] );
     138             :     }
     139           0 :     virtual uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames(  ) throw (uno::RuntimeException)
     140             :     {
     141           0 :         ::osl::MutexGuard aGuard( m_aMutex );
     142           0 :         uno::Sequence< ::rtl::OUString > aResult( IdToOleNameHash.size() );
     143           0 :         NamedIndexToOleName::iterator it = IdToOleNameHash.begin();
     144           0 :         NamedIndexToOleName::iterator it_end = IdToOleNameHash.end();
     145           0 :         rtl::OUString* pName = aResult.getArray();
     146           0 :         for (; it != it_end; ++it, ++pName )
     147           0 :             *pName = it->first;
     148           0 :         return aResult;
     149             :     }
     150           9 :     virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (uno::RuntimeException)
     151             :     {
     152           9 :         ::osl::MutexGuard aGuard( m_aMutex );
     153           9 :         return ( IdToOleNameHash.find( aName ) != IdToOleNameHash.end() );
     154             :     }
     155             : 
     156             :     // XElementAccess
     157           0 :     virtual ::sal_Int32 SAL_CALL getCount(  ) throw (uno::RuntimeException)
     158             :     {
     159           0 :         ::osl::MutexGuard aGuard( m_aMutex );
     160           0 :         return IdToOleNameHash.size();
     161             :     }
     162             :     // XNameContainer
     163           0 :     virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const uno::Any& aElement ) throw(lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, uno::RuntimeException)
     164             :     {
     165           0 :         ::osl::MutexGuard aGuard( m_aMutex );
     166           0 :         if ( hasByName( aName ) )
     167           0 :             throw container::ElementExistException();
     168           0 :         uno::Reference< container::XIndexContainer > xElement;
     169           0 :         if ( ! ( aElement >>= xElement ) )
     170           0 :             throw lang::IllegalArgumentException();
     171           0 :        IdToOleNameHash[ aName ] = xElement;
     172           0 :     }
     173           0 :     virtual void SAL_CALL removeByName( const ::rtl::OUString& aName ) throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
     174             :     {
     175           0 :         ::osl::MutexGuard aGuard( m_aMutex );
     176           0 :         if ( !hasByName( aName ) )
     177           0 :             throw container::NoSuchElementException();
     178           0 :         IdToOleNameHash.erase( IdToOleNameHash.find( aName ) );
     179           0 :     }
     180           0 :     virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const uno::Any& aElement ) throw(lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
     181             :     {
     182           0 :         ::osl::MutexGuard aGuard( m_aMutex );
     183           0 :         if ( !hasByName( aName ) )
     184           0 :             throw container::NoSuchElementException();
     185           0 :         uno::Reference< container::XIndexContainer > xElement;
     186           0 :         if ( ! ( aElement >>= xElement ) )
     187           0 :             throw lang::IllegalArgumentException();
     188           0 :         IdToOleNameHash[ aName ] = xElement;
     189           0 :     }
     190             : };
     191             : 
     192          20 : ImportExcel8::ImportExcel8( XclImpRootData& rImpData, SvStream& rStrm ) :
     193          20 :     ImportExcel( rImpData, rStrm )
     194             : {
     195             :     // replace BIFF2-BIFF5 formula importer with BIFF8 formula importer
     196          20 :     delete pFormConv;
     197          20 :     pFormConv = pExcRoot->pFmlaConverter = new ExcelToSc8( GetRoot() );
     198          20 : }
     199             : 
     200             : 
     201          40 : ImportExcel8::~ImportExcel8()
     202             : {
     203          40 : }
     204             : 
     205             : 
     206          58 : void ImportExcel8::Calccount( void )
     207             : {
     208          58 :     ScDocOptions    aOpt = pD->GetDocOptions();
     209          58 :     aOpt.SetIterCount( aIn.ReaduInt16() );
     210          58 :     pD->SetDocOptions( aOpt );
     211          58 : }
     212             : 
     213             : 
     214          17 : void ImportExcel8::Precision( void )
     215             : {
     216          17 :     ScDocOptions aOpt = pD->GetDocOptions();
     217          17 :     aOpt.SetCalcAsShown( aIn.ReaduInt16() == 0 );
     218          17 :     pD->SetDocOptions( aOpt );
     219          17 : }
     220             : 
     221             : 
     222          73 : void ImportExcel8::Delta( void )
     223             : {
     224          73 :     ScDocOptions    aOpt = pD->GetDocOptions();
     225          73 :     aOpt.SetIterEps( aIn.ReadDouble() );
     226          73 :     pD->SetDocOptions( aOpt );
     227          73 : }
     228             : 
     229             : 
     230          73 : void ImportExcel8::Iteration( void )
     231             : {
     232          73 :     ScDocOptions    aOpt = pD->GetDocOptions();
     233          73 :     aOpt.SetIter( aIn.ReaduInt16() == 1 );
     234          73 :     pD->SetDocOptions( aOpt );
     235          73 : }
     236             : 
     237             : 
     238          76 : void ImportExcel8::Boundsheet( void )
     239             : {
     240             :     sal_uInt8           nLen;
     241             :     sal_uInt16          nGrbit;
     242             : 
     243          76 :     aIn.DisableDecryption();
     244          76 :     maSheetOffsets.push_back( aIn.ReaduInt32() );
     245          76 :     aIn.EnableDecryption();
     246          76 :     aIn >> nGrbit >> nLen;
     247             : 
     248          76 :     rtl::OUString aName( aIn.ReadUniString( nLen ) );
     249          76 :     GetTabInfo().AppendXclTabName( aName, nBdshtTab );
     250             : 
     251          76 :     SCTAB nScTab = static_cast< SCTAB >( nBdshtTab );
     252          76 :     if( nScTab > 0 )
     253             :     {
     254             :         OSL_ENSURE( !pD->HasTable( nScTab ), "ImportExcel8::Boundsheet - sheet exists already" );
     255          58 :         pD->MakeTable( nScTab );
     256             :     }
     257             : 
     258          76 :     if( ( nGrbit & 0x0001 ) || ( nGrbit & 0x0002 ) )
     259           9 :         pD->SetVisible( nScTab, false );
     260             : 
     261          76 :     if( !pD->RenameTab( nScTab, aName ) )
     262             :     {
     263           0 :         pD->CreateValidTabName( aName );
     264           0 :         pD->RenameTab( nScTab, aName );
     265             :     }
     266             : 
     267          76 :     nBdshtTab++;
     268          76 : }
     269             : 
     270             : 
     271           0 : void ImportExcel8::Scenman( void )
     272             : {
     273             :     sal_uInt16              nLastDispl;
     274             : 
     275           0 :     aIn.Ignore( 4 );
     276           0 :     aIn >> nLastDispl;
     277             : 
     278           0 :     maScenList.nLastScenario = nLastDispl;
     279           0 : }
     280             : 
     281             : 
     282           0 : void ImportExcel8::Scenario( void )
     283             : {
     284           0 :     maScenList.aEntries.push_back( new ExcScenario( aIn, *pExcRoot ) );
     285           0 : }
     286             : 
     287             : 
     288       10470 : void ImportExcel8::Labelsst( void )
     289             : {
     290       10470 :     XclAddress aXclPos;
     291             :     sal_uInt16 nXF;
     292             :     sal_uInt32  nSst;
     293             : 
     294       10470 :     aIn >> aXclPos >> nXF >> nSst;
     295             : 
     296       10470 :     ScAddress aScPos( ScAddress::UNINITIALIZED );
     297       10470 :     if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
     298             :     {
     299       10470 :         GetXFRangeBuffer().SetXF( aScPos, nXF );
     300       10470 :         if( ScBaseCell* pCell = GetSst().CreateCell( nSst, nXF ) )
     301       10470 :             GetDoc().PutCell( aScPos.Col(), aScPos.Row(), aScPos.Tab(), pCell );
     302             :     }
     303       10470 : }
     304             : 
     305             : 
     306          50 : void ImportExcel8::SheetProtection( void )
     307             : {
     308          50 :     GetSheetProtectBuffer().ReadOptions( aIn, GetCurrScTab() );
     309          50 : }
     310             : 
     311           3 : void ImportExcel8::ReadBasic( void )
     312             : {
     313           3 :     SfxObjectShell* pShell = GetDocShell();
     314           3 :     SotStorageRef xRootStrg = GetRootStorage();
     315           3 :     const SvtFilterOptions& rFilterOpt = SvtFilterOptions::Get();
     316           3 :     if( pShell && xRootStrg.Is() ) try
     317             :     {
     318             :         // #FIXME need to get rid of this, we can also do this from within oox
     319             :         // via the "ooo.vba.VBAGlobals" service
     320           6 :         if( ( rFilterOpt.IsLoadExcelBasicCode() ||
     321           0 :               rFilterOpt.IsLoadExcelBasicStorage() ) &&
     322           3 :             rFilterOpt.IsLoadExcelBasicExecutable() )
     323             :         {
     324             :             // see if we have the XCB stream
     325           3 :             SvStorageStreamRef xXCB = xRootStrg->OpenSotStream( String( RTL_CONSTASCII_USTRINGPARAM( "XCB" ) ), STREAM_STD_READ | STREAM_NOCREATE  );
     326           3 :             if ( xXCB.Is()|| SVSTREAM_OK == xXCB->GetError() )
     327             :             {
     328           3 :                 ScCTBWrapper wrapper;
     329           3 :                 if ( wrapper.Read( *xXCB ) )
     330             :                 {
     331             : #if OSL_DEBUG_LEVEL > 1
     332             :                     wrapper.Print( stderr );
     333             : #endif
     334           3 :                     wrapper.ImportCustomToolBar( *pShell );
     335           3 :                 }
     336           3 :             }
     337             :         }
     338             :         try
     339             :         {
     340           3 :             uno::Reference< uno::XComponentContext > aCtx( ::comphelper::getProcessComponentContext() );
     341           3 :             SfxMedium& rMedium = GetMedium();
     342           3 :             uno::Reference< io::XInputStream > xIn = rMedium.GetInputStream();
     343           3 :             oox::ole::OleStorage root( aCtx, xIn, false );
     344           3 :             oox::StorageRef vbaStg = root.openSubStorage( "_VBA_PROJECT_CUR", false );
     345           3 :             if ( vbaStg.get() )
     346             :             {
     347           3 :                 oox::ole::VbaProject aVbaPrj( aCtx, pShell->GetModel(), "Calc" );
     348             :                 // collect names of embedded form controls, as specified in the VBA project
     349           3 :                 uno::Reference< container::XNameContainer > xOleNameOverrideSink( new OleNameOverrideContainer );
     350           3 :                 aVbaPrj.setOleOverridesSink( xOleNameOverrideSink );
     351           3 :                 aVbaPrj.importVbaProject( *vbaStg );
     352           3 :                 GetObjectManager().SetOleNameOverrideInfo( xOleNameOverrideSink );
     353           3 :             }
     354             :         }
     355           0 :         catch( uno::Exception& )
     356             :         {
     357             :         }
     358             :     }
     359           0 :     catch( uno::Exception& )
     360             :     {
     361           3 :     }
     362           3 : }
     363             : 
     364             : 
     365          75 : void ImportExcel8::EndSheet( void )
     366             : {
     367          75 :     ImportExcel::EndSheet();
     368          75 :     GetCondFormatManager().Apply();
     369          75 :     GetValidationManager().Apply();
     370          75 : }
     371             : 
     372             : 
     373          20 : void ImportExcel8::PostDocLoad( void )
     374             : {
     375             : #ifndef DISABLE_SCRIPTING
     376             :     // reading basic has been delayed until sheet objects (codenames etc.) are read
     377          20 :     if( HasBasic() )
     378           3 :         ReadBasic();
     379             : #endif
     380             :     // #i11776# filtered ranges before outlines and hidden rows
     381          20 :     if( pExcRoot->pAutoFilterBuffer )
     382          20 :         pExcRoot->pAutoFilterBuffer->Apply();
     383             : 
     384          20 :     GetWebQueryBuffer().Apply();    //! test if extant
     385          20 :     GetSheetProtectBuffer().Apply();
     386          20 :     GetDocProtectBuffer().Apply();
     387             : 
     388          20 :     ImportExcel::PostDocLoad();
     389             : 
     390             :     // Scenarien bemachen! ACHTUNG: Hier wird Tabellen-Anzahl im Dokument erhoeht!!
     391          20 :     if( !pD->IsClipboard() && maScenList.aEntries.size() )
     392             :     {
     393           0 :         pD->UpdateChartListenerCollection();    // references in charts must be updated
     394             : 
     395           0 :         maScenList.Apply( GetRoot() );
     396             :     }
     397             : 
     398             :     // read doc info (no docshell while pasting from clipboard)
     399          20 :     LoadDocumentProperties();
     400             : 
     401             :     // #i45843# Pivot tables are now handled outside of PostDocLoad, so they are available
     402             :     // when formula cells are calculated, for the GETPIVOTDATA function.
     403          20 : }
     404             : 
     405          20 : void ImportExcel8::LoadDocumentProperties()
     406             : {
     407             :     // no docshell while pasting from clipboard
     408          20 :     if( SfxObjectShell* pShell = GetDocShell() )
     409             :     {
     410             :         // BIFF5+ without storage is possible
     411          20 :         SotStorageRef xRootStrg = GetRootStorage();
     412          20 :         if( xRootStrg.Is() ) try
     413             :         {
     414          20 :             uno::Reference< document::XDocumentPropertiesSupplier > xDPS( pShell->GetModel(), uno::UNO_QUERY_THROW );
     415          20 :             uno::Reference< document::XDocumentProperties > xDocProps( xDPS->getDocumentProperties(), uno::UNO_SET_THROW );
     416          20 :             sfx2::LoadOlePropertySet( xDocProps, xRootStrg );
     417             :         }
     418           0 :         catch( uno::Exception& )
     419             :         {
     420          20 :         }
     421             :     }
     422          20 : }
     423             : 
     424             : //___________________________________________________________________
     425             : // autofilter
     426             : 
     427           5 : void ImportExcel8::FilterMode( void )
     428             : {
     429             :     // The FilterMode record exists: if either the AutoFilter
     430             :     // record exists or an Advanced Filter is saved and stored
     431             :     // in the sheet. Thus if the FilterMode records only exists
     432             :     // then the latter is true..
     433          10 :     if( !pExcRoot->pAutoFilterBuffer ) return;
     434             : 
     435           5 :     XclImpAutoFilterData* pData = pExcRoot->pAutoFilterBuffer->GetByTab( GetCurrScTab() );
     436           5 :     if( pData )
     437           5 :         pData->SetAutoOrAdvanced();
     438             : }
     439             : 
     440           7 : void ImportExcel8::AutoFilterInfo( void )
     441             : {
     442          14 :     if( !pExcRoot->pAutoFilterBuffer ) return;
     443             : 
     444           7 :     XclImpAutoFilterData* pData = pExcRoot->pAutoFilterBuffer->GetByTab( GetCurrScTab() );
     445           7 :     if( pData )
     446             :     {
     447           7 :         pData->SetAdvancedRange( NULL );
     448           7 :         pData->Activate();
     449             :     }
     450             : }
     451             : 
     452           5 : void ImportExcel8::AutoFilter( void )
     453             : {
     454          10 :     if( !pExcRoot->pAutoFilterBuffer ) return;
     455             : 
     456           5 :     XclImpAutoFilterData* pData = pExcRoot->pAutoFilterBuffer->GetByTab( GetCurrScTab() );
     457           5 :     if( pData )
     458           5 :         pData->ReadAutoFilter( aIn );
     459             : }
     460             : 
     461             : 
     462             : 
     463          23 : XclImpAutoFilterData::XclImpAutoFilterData( RootData* pRoot, const ScRange& rRange ) :
     464             :         ExcRoot( pRoot ),
     465             :         pCurrDBData(NULL),
     466             :         bActive( false ),
     467             :         bCriteria( false ),
     468          23 :         bAutoOrAdvanced(false)
     469             : {
     470          23 :     aParam.nCol1 = rRange.aStart.Col();
     471          23 :     aParam.nRow1 = rRange.aStart.Row();
     472          23 :     aParam.nTab = rRange.aStart.Tab();
     473          23 :     aParam.nCol2 = rRange.aEnd.Col();
     474          23 :     aParam.nRow2 = rRange.aEnd.Row();
     475             : 
     476          23 :     aParam.bInplace = sal_True;
     477             : 
     478          23 : }
     479             : 
     480           1 : void XclImpAutoFilterData::CreateFromDouble( rtl::OUString& rStr, double fVal )
     481             : {
     482             :     rStr += ::rtl::math::doubleToUString(fVal,
     483             :                 rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max,
     484           1 :                 ScGlobal::pLocaleData->getNumDecimalSep()[0], true);
     485           1 : }
     486             : 
     487           7 : void XclImpAutoFilterData::SetCellAttribs()
     488             : {
     489           7 :     ScDocument& rDoc = pExcRoot->pIR->GetDoc();
     490          27 :     for ( SCCOL nCol = StartCol(); nCol <= EndCol(); nCol++ )
     491             :     {
     492          20 :         sal_Int16 nFlag = ((ScMergeFlagAttr*) rDoc.GetAttr( nCol, StartRow(), Tab(), ATTR_MERGE_FLAG ))->GetValue();
     493          20 :         rDoc.ApplyAttr( nCol, StartRow(), Tab(), ScMergeFlagAttr( nFlag | SC_MF_AUTO) );
     494             :     }
     495           7 : }
     496             : 
     497           7 : void XclImpAutoFilterData::InsertQueryParam()
     498             : {
     499           7 :     if (pCurrDBData)
     500             :     {
     501           7 :         ScRange aAdvRange;
     502           7 :         sal_Bool    bHasAdv = pCurrDBData->GetAdvancedQuerySource( aAdvRange );
     503           7 :         if( bHasAdv )
     504           0 :             pExcRoot->pIR->GetDoc().CreateQueryParam( aAdvRange.aStart.Col(),
     505           0 :                 aAdvRange.aStart.Row(), aAdvRange.aEnd.Col(), aAdvRange.aEnd.Row(),
     506           0 :                 aAdvRange.aStart.Tab(), aParam );
     507             : 
     508           7 :         pCurrDBData->SetQueryParam( aParam );
     509           7 :         if( bHasAdv )
     510           0 :             pCurrDBData->SetAdvancedQuerySource( &aAdvRange );
     511             :         else
     512             :         {
     513           7 :             pCurrDBData->SetAutoFilter( sal_True );
     514           7 :             SetCellAttribs();
     515             :         }
     516             :     }
     517           7 : }
     518             : 
     519           4 : static void ExcelQueryToOooQuery( ScQueryEntry& rEntry )
     520             : {
     521           4 :     if (rEntry.eOp != SC_EQUAL && rEntry.eOp != SC_NOT_EQUAL)
     522           4 :         return;
     523             : 
     524           4 :     String aStr = rEntry.GetQueryItem().maString;
     525           4 :     xub_StrLen nLen = aStr.Len();
     526           4 :     sal_Unicode nStart = aStr.GetChar( 0 );
     527           4 :     sal_Unicode nEnd   = aStr.GetChar( nLen-1 );
     528           4 :     if( nLen >2 && nStart == '*' && nEnd == '*' )
     529             :     {
     530           0 :         aStr.Erase( nLen-1, 1 );
     531           0 :         aStr.Erase( 0, 1 );
     532           0 :         rEntry.eOp = ( rEntry.eOp == SC_EQUAL ) ? SC_CONTAINS : SC_DOES_NOT_CONTAIN;
     533             :     }
     534           4 :     else if( nLen > 1 && nStart == '*' && nEnd != '*' )
     535             :     {
     536           0 :         aStr.Erase( 0, 1 );
     537           0 :         rEntry.eOp = ( rEntry.eOp == SC_EQUAL ) ? SC_ENDS_WITH : SC_DOES_NOT_END_WITH;
     538             :     }
     539           4 :     else if( nLen > 1 && nStart != '*' && nEnd == '*' )
     540             :     {
     541           0 :         aStr.Erase( nLen-1, 1 );
     542           0 :         rEntry.eOp = ( rEntry.eOp == SC_EQUAL ) ? SC_BEGINS_WITH : SC_DOES_NOT_BEGIN_WITH;
     543             :     }
     544           4 :     else if( nLen == 2 && nStart == '*' && nEnd == '*' )
     545             :     {
     546           0 :         aStr.Erase( 0, 1 );
     547             :     }
     548           4 :     rEntry.GetQueryItem().maString = aStr;
     549             : }
     550             : 
     551           5 : void XclImpAutoFilterData::ReadAutoFilter( XclImpStream& rStrm )
     552             : {
     553             :     sal_uInt16 nCol, nFlags;
     554           5 :     rStrm >> nCol >> nFlags;
     555             : 
     556           5 :     ScQueryConnect eConn = ::get_flagvalue( nFlags, EXC_AFFLAG_ANDORMASK, SC_OR, SC_AND );
     557           5 :     bool bSimple1    = ::get_flag(nFlags, EXC_AFFLAG_SIMPLE1);
     558           5 :     bool bSimple2    = ::get_flag(nFlags, EXC_AFFLAG_SIMPLE2);
     559           5 :     bool bTop10      = ::get_flag(nFlags, EXC_AFFLAG_TOP10);
     560           5 :     bool bTopOfTop10 = ::get_flag(nFlags, EXC_AFFLAG_TOP10TOP);
     561           5 :     bool bPercent    = ::get_flag(nFlags, EXC_AFFLAG_TOP10PERC);
     562           5 :     sal_uInt16 nCntOfTop10 = nFlags >> 7;
     563             : 
     564           5 :     if( bTop10 )
     565             :     {
     566           0 :         ScQueryEntry& aEntry = aParam.AppendEntry();
     567           0 :         ScQueryEntry::Item& rItem = aEntry.GetQueryItem();
     568           0 :         aEntry.bDoQuery = true;
     569           0 :         aEntry.nField = static_cast<SCCOLROW>(StartCol() + static_cast<SCCOL>(nCol));
     570             :         aEntry.eOp = bTopOfTop10 ?
     571           0 :             (bPercent ? SC_TOPPERC : SC_TOPVAL) : (bPercent ? SC_BOTPERC : SC_BOTVAL);
     572           0 :         aEntry.eConnect = SC_AND;
     573             : 
     574           0 :         rItem.meType = ScQueryEntry::ByString;
     575           0 :         rItem.maString = rtl::OUString::valueOf(static_cast<sal_Int32>(nCntOfTop10));
     576             : 
     577           0 :         rStrm.Ignore(20);
     578           5 :         return;
     579             :     }
     580             : 
     581             :     sal_uInt8   nType, nOper, nBoolErr, nVal;
     582             :     sal_Int32   nRK;
     583             :     double  fVal;
     584             :     bool bIgnore;
     585             : 
     586           5 :     sal_uInt8 nStrLen[2] = { 0, 0 };
     587          15 :     ScQueryEntry aEntries[2];
     588             : 
     589          15 :     for (size_t nE = 0; nE < 2; ++nE)
     590             :     {
     591          10 :         ScQueryEntry& rEntry = aEntries[nE];
     592          10 :         ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
     593          10 :         bIgnore = false;
     594             : 
     595          10 :         rStrm >> nType >> nOper;
     596          10 :         switch( nOper )
     597             :         {
     598             :             case EXC_AFOPER_LESS:
     599           0 :                 rEntry.eOp = SC_LESS;
     600           0 :             break;
     601             :             case EXC_AFOPER_EQUAL:
     602           6 :                 rEntry.eOp = SC_EQUAL;
     603           6 :             break;
     604             :             case EXC_AFOPER_LESSEQUAL:
     605           0 :                 rEntry.eOp = SC_LESS_EQUAL;
     606           0 :             break;
     607             :             case EXC_AFOPER_GREATER:
     608           0 :                 rEntry.eOp = SC_GREATER;
     609           0 :             break;
     610             :             case EXC_AFOPER_NOTEQUAL:
     611           0 :                 rEntry.eOp = SC_NOT_EQUAL;
     612           0 :             break;
     613             :             case EXC_AFOPER_GREATEREQUAL:
     614           0 :                 rEntry.eOp = SC_GREATER_EQUAL;
     615           0 :             break;
     616             :             default:
     617           4 :                 rEntry.eOp = SC_EQUAL;
     618             :         }
     619             : 
     620          10 :         rtl::OUString aStr;
     621             : 
     622          10 :         switch( nType )
     623             :         {
     624             :             case EXC_AFTYPE_RK:
     625           0 :                 rStrm >> nRK;
     626           0 :                 rStrm.Ignore( 4 );
     627             :                 CreateFromDouble(
     628           0 :                     rItem.maString, XclTools::GetDoubleFromRK(nRK));
     629           0 :             break;
     630             :             case EXC_AFTYPE_DOUBLE:
     631           1 :                 rStrm >> fVal;
     632           1 :                 CreateFromDouble(rItem.maString, fVal);
     633           1 :             break;
     634             :             case EXC_AFTYPE_STRING:
     635           4 :                 rStrm.Ignore( 4 );
     636           4 :                 rStrm >> nStrLen[ nE ];
     637           4 :                 rStrm.Ignore( 3 );
     638           4 :                 rItem.maString = rtl::OUString();
     639           4 :             break;
     640             :             case EXC_AFTYPE_BOOLERR:
     641           0 :                 rStrm >> nBoolErr >> nVal;
     642           0 :                 rStrm.Ignore( 6 );
     643           0 :                 rItem.maString = rtl::OUString::valueOf(static_cast<sal_Int32>(nVal));
     644           0 :                 bIgnore = (nBoolErr != 0);
     645           0 :             break;
     646             :             case EXC_AFTYPE_EMPTY:
     647           0 :                 rEntry.SetQueryByEmpty();
     648           0 :             break;
     649             :             case EXC_AFTYPE_NOTEMPTY:
     650           0 :                 rEntry.SetQueryByNonEmpty();
     651           0 :             break;
     652             :             default:
     653           5 :                 rStrm.Ignore( 8 );
     654           5 :                 bIgnore = true;
     655             :         }
     656             : 
     657          10 :         if (!bIgnore)
     658             :         {
     659           5 :             rEntry.bDoQuery = true;
     660           5 :             rItem.meType = ScQueryEntry::ByString;
     661           5 :             rEntry.nField = static_cast<SCCOLROW>(StartCol() + static_cast<SCCOL>(nCol));
     662           5 :             rEntry.eConnect = nE ? eConn : SC_AND;
     663             :         }
     664          10 :     }
     665             : 
     666           5 :     if (eConn == SC_AND)
     667             :     {
     668          15 :         for (size_t nE = 0; nE < 2; ++nE)
     669             :         {
     670          10 :             if (nStrLen[nE] && aEntries[nE].bDoQuery)
     671             :             {
     672           4 :                 aEntries[nE].GetQueryItem().maString = rStrm.ReadUniString(nStrLen[nE]);
     673           4 :                 ExcelQueryToOooQuery(aEntries[nE]);
     674           4 :                 aParam.AppendEntry() = aEntries[nE];
     675             :             }
     676             :         }
     677             :     }
     678             :     else
     679             :     {
     680             :         OSL_ASSERT(eConn == SC_OR);
     681             :         // Import only when both conditions are for simple equality, else
     682             :         // import only the 1st condition due to conflict with the ordering of
     683             :         // conditions. #i39464#.
     684             :         //
     685             :         // Example: Let A1 be a condition of column A, and B1 and B2
     686             :         // conditions of column B, connected with OR. Excel performs 'A1 AND
     687             :         // (B1 OR B2)' in this case, but Calc would do '(A1 AND B1) OR B2'
     688             :         // instead.
     689             : 
     690           0 :         if (bSimple1 && bSimple2 && nStrLen[0] && nStrLen[1])
     691             :         {
     692             :             // Two simple OR'ed equal conditions.  We can import this correctly.
     693           0 :             ScQueryEntry& rEntry = aParam.AppendEntry();
     694           0 :             rEntry.bDoQuery = true;
     695           0 :             rEntry.eOp = SC_EQUAL;
     696           0 :             rEntry.eConnect = SC_AND;
     697           0 :             ScQueryEntry::QueryItemsType aItems;
     698           0 :             aItems.reserve(2);
     699           0 :             ScQueryEntry::Item aItem1, aItem2;
     700           0 :             aItem1.maString = rStrm.ReadUniString(nStrLen[0]);
     701           0 :             aItem1.meType = ScQueryEntry::ByString;
     702           0 :             aItem2.maString = rStrm.ReadUniString(nStrLen[1]);
     703           0 :             aItem2.meType = ScQueryEntry::ByString;
     704           0 :             aItems.push_back(aItem1);
     705           0 :             aItems.push_back(aItem2);
     706           0 :             rEntry.GetQueryItems().swap(aItems);
     707             :         }
     708           0 :         else if (nStrLen[0] && aEntries[0].bDoQuery)
     709             :         {
     710             :             // Due to conflict, we can import only the first condition.
     711           0 :             aEntries[0].GetQueryItem().maString = rStrm.ReadUniString(nStrLen[0]);
     712           0 :             ExcelQueryToOooQuery(aEntries[0]);
     713           0 :             aParam.AppendEntry() = aEntries[0];
     714             :         }
     715          15 :     }
     716             : }
     717             : 
     718           7 : void XclImpAutoFilterData::SetAdvancedRange( const ScRange* pRange )
     719             : {
     720           7 :     if (pRange)
     721             :     {
     722           0 :         aCriteriaRange = *pRange;
     723           0 :         bCriteria = true;
     724             :     }
     725             :     else
     726           7 :         bCriteria = false;
     727           7 : }
     728             : 
     729           0 : void XclImpAutoFilterData::SetExtractPos( const ScAddress& rAddr )
     730             : {
     731           0 :     aParam.nDestCol = rAddr.Col();
     732           0 :     aParam.nDestRow = rAddr.Row();
     733           0 :     aParam.nDestTab = rAddr.Tab();
     734           0 :     aParam.bInplace = false;
     735           0 :     aParam.bDestPers = sal_True;
     736           0 : }
     737             : 
     738          23 : void XclImpAutoFilterData::Apply()
     739             : {
     740          23 :     CreateScDBData();
     741             : 
     742          23 :     if( bActive )
     743             :     {
     744           7 :         InsertQueryParam();
     745             : 
     746             :         // #i38093# rows hidden by filter need extra flag, but CR_FILTERED is not set here yet
     747             : //        SCROW nRow1 = StartRow();
     748             : //        SCROW nRow2 = EndRow();
     749             : //        size_t nRows = nRow2 - nRow1 + 1;
     750             : //        boost::scoped_array<sal_uInt8> pFlags( new sal_uInt8[nRows]);
     751             : //        pExcRoot->pDoc->GetRowFlagsArray( Tab()).FillDataArray( nRow1, nRow2,
     752             : //                pFlags.get());
     753             : //        for (size_t j=0; j<nRows; ++j)
     754             : //        {
     755             : //            if ((pFlags[j] & CR_HIDDEN) && !(pFlags[j] & CR_FILTERED))
     756             : //                pExcRoot->pDoc->SetRowFlags( nRow1 + j, Tab(),
     757             : //                        pFlags[j] | CR_FILTERED );
     758             : //        }
     759             :     }
     760          23 : }
     761             : 
     762          23 : void XclImpAutoFilterData::CreateScDBData()
     763             : {
     764             : 
     765             :     // Create the ScDBData() object if the AutoFilter is activated
     766             :     // or if we need to create the Advanced Filter.
     767          23 :     if( bActive || bCriteria)
     768             :     {
     769           7 :         ScDocument* pDoc = pExcRoot->pIR->GetDocPtr();
     770           7 :         String aNewName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(STR_DB_LOCAL_NONAME));
     771           7 :         pCurrDBData = new ScDBData(aNewName , Tab(),
     772          14 :                                 StartCol(),StartRow(), EndCol(),EndRow() );
     773           7 :         if(bCriteria)
     774             :         {
     775           0 :             EnableRemoveFilter();
     776             : 
     777           0 :             pCurrDBData->SetQueryParam( aParam );
     778           0 :             pCurrDBData->SetAdvancedQuerySource(&aCriteriaRange);
     779             :         }
     780             :         else
     781           7 :             pCurrDBData->SetAdvancedQuerySource(NULL);
     782           7 :         pDoc->SetAnonymousDBData(Tab(), pCurrDBData);
     783             :     }
     784             : 
     785          23 : }
     786             : 
     787           0 : void XclImpAutoFilterData::EnableRemoveFilter()
     788             : {
     789             :     // only if this is a saved Advanced filter
     790           0 :     if( !bActive && bAutoOrAdvanced )
     791             :     {
     792           0 :         ScQueryEntry& aEntry = aParam.AppendEntry();
     793           0 :         aEntry.bDoQuery = true;
     794             :     }
     795             : 
     796             :     // TBD: force the automatic activation of the
     797             :     // "Remove Filter" by setting a virtual mouse click
     798             :     // inside the advanced range
     799           0 : }
     800             : 
     801          23 : void XclImpAutoFilterBuffer::Insert( RootData* pRoot, const ScRange& rRange)
     802             : {
     803          23 :     if( !GetByTab( rRange.aStart.Tab() ) )
     804          23 :         maFilters.push_back( new XclImpAutoFilterData( pRoot, rRange) );
     805          23 : }
     806             : 
     807           0 : void XclImpAutoFilterBuffer::AddAdvancedRange( const ScRange& rRange )
     808             : {
     809           0 :     XclImpAutoFilterData* pData = GetByTab( rRange.aStart.Tab() );
     810           0 :     if( pData )
     811           0 :         pData->SetAdvancedRange( &rRange );
     812           0 : }
     813             : 
     814           0 : void XclImpAutoFilterBuffer::AddExtractPos( const ScRange& rRange )
     815             : {
     816           0 :     XclImpAutoFilterData* pData = GetByTab( rRange.aStart.Tab() );
     817           0 :     if( pData )
     818           0 :         pData->SetExtractPos( rRange.aStart );
     819           0 : }
     820             : 
     821          20 : void XclImpAutoFilterBuffer::Apply()
     822             : {
     823             :     std::for_each(maFilters.begin(),maFilters.end(),
     824          20 :         boost::bind(&XclImpAutoFilterData::Apply,_1));
     825          20 : }
     826             : 
     827         115 : XclImpAutoFilterData* XclImpAutoFilterBuffer::GetByTab( SCTAB nTab )
     828             : {
     829         115 :     boost::ptr_vector<XclImpAutoFilterData>::iterator it;
     830         328 :     for( it = maFilters.begin(); it != maFilters.end(); ++it )
     831             :     {
     832         253 :         if( it->Tab() == nTab )
     833          40 :             return const_cast<XclImpAutoFilterData*>(&(*it));
     834             :     }
     835          75 :     return NULL;
     836           9 : }
     837             : 
     838             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10