LCOV - code coverage report
Current view: top level - sc/source/core/data - documen8.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 234 647 36.2 %
Date: 2015-06-13 12:38:46 Functions: 33 65 50.8 %
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 "scitems.hxx"
      21             : #include <editeng/eeitem.hxx>
      22             : 
      23             : #include <tools/urlobj.hxx>
      24             : #include <editeng/editobj.hxx>
      25             : #include <editeng/editstat.hxx>
      26             : #include <editeng/frmdiritem.hxx>
      27             : #include <editeng/langitem.hxx>
      28             : #include <sfx2/linkmgr.hxx>
      29             : #include <editeng/scripttypeitem.hxx>
      30             : #include <editeng/unolingu.hxx>
      31             : #include <sfx2/bindings.hxx>
      32             : #include <sfx2/objsh.hxx>
      33             : #include <sfx2/printer.hxx>
      34             : #include <sfx2/viewfrm.hxx>
      35             : #include <sfx2/viewsh.hxx>
      36             : #include <svl/flagitem.hxx>
      37             : #include <svl/intitem.hxx>
      38             : #include <svl/zforlist.hxx>
      39             : #include <svl/zformat.hxx>
      40             : #include <unotools/misccfg.hxx>
      41             : #include <sfx2/app.hxx>
      42             : #include <unotools/transliterationwrapper.hxx>
      43             : #include <unotools/securityoptions.hxx>
      44             : 
      45             : #include <vcl/virdev.hxx>
      46             : #include <vcl/msgbox.hxx>
      47             : 
      48             : #include <com/sun/star/i18n/TransliterationModulesExtra.hpp>
      49             : 
      50             : #include "inputopt.hxx"
      51             : #include "global.hxx"
      52             : #include "table.hxx"
      53             : #include "column.hxx"
      54             : #include "poolhelp.hxx"
      55             : #include "docpool.hxx"
      56             : #include "stlpool.hxx"
      57             : #include "stlsheet.hxx"
      58             : #include "docoptio.hxx"
      59             : #include "viewopti.hxx"
      60             : #include "scextopt.hxx"
      61             : #include "rechead.hxx"
      62             : #include "ddelink.hxx"
      63             : #include "scmatrix.hxx"
      64             : #include "arealink.hxx"
      65             : #include "dociter.hxx"
      66             : #include "patattr.hxx"
      67             : #include "hints.hxx"
      68             : #include "editutil.hxx"
      69             : #include "progress.hxx"
      70             : #include "document.hxx"
      71             : #include "chartlis.hxx"
      72             : #include "chartlock.hxx"
      73             : #include "refupdat.hxx"
      74             : #include "validat.hxx"
      75             : #include "markdata.hxx"
      76             : #include "scmod.hxx"
      77             : #include "printopt.hxx"
      78             : #include "externalrefmgr.hxx"
      79             : #include "globstr.hrc"
      80             : #include "sc.hrc"
      81             : #include "charthelper.hxx"
      82             : #include "macromgr.hxx"
      83             : #include "dpobject.hxx"
      84             : #include "docuno.hxx"
      85             : #include "scresid.hxx"
      86             : #include "columniterator.hxx"
      87             : #include "globalnames.hxx"
      88             : #include "stringutil.hxx"
      89             : #include <documentlinkmgr.hxx>
      90             : #include <scopetools.hxx>
      91             : 
      92             : #include <boost/scoped_ptr.hpp>
      93             : 
      94             : using namespace com::sun::star;
      95             : 
      96             : // STATIC DATA -----------------------------------------------------------
      97             : 
      98             : namespace {
      99             : 
     100         244 : inline sal_uInt16 getScaleValue(SfxStyleSheetBase& rStyle, sal_uInt16 nWhich)
     101             : {
     102         244 :     return static_cast<const SfxUInt16Item&>(rStyle.GetItemSet().Get(nWhich)).GetValue();
     103             : }
     104             : 
     105             : }
     106             : 
     107        2320 : void ScDocument::ImplCreateOptions()
     108             : {
     109        2320 :     pDocOptions  = new ScDocOptions();
     110        2320 :     pViewOptions = new ScViewOptions();
     111        2320 : }
     112             : 
     113        2287 : void ScDocument::ImplDeleteOptions()
     114             : {
     115        2287 :     delete pDocOptions;
     116        2287 :     delete pViewOptions;
     117        2287 :     delete pExtDocOptions;
     118        2287 : }
     119             : 
     120        5060 : SfxPrinter* ScDocument::GetPrinter(bool bCreateIfNotExist)
     121             : {
     122        5060 :     if ( !pPrinter && bCreateIfNotExist )
     123             :     {
     124             :         SfxItemSet* pSet =
     125         183 :             new SfxItemSet( *xPoolHelper->GetDocPool(),
     126             :                             SID_PRINTER_NOTFOUND_WARN,  SID_PRINTER_NOTFOUND_WARN,
     127             :                             SID_PRINTER_CHANGESTODOC,   SID_PRINTER_CHANGESTODOC,
     128             :                             SID_PRINT_SELECTEDSHEET,    SID_PRINT_SELECTEDSHEET,
     129             :                             SID_SCPRINTOPTIONS,         SID_SCPRINTOPTIONS,
     130         183 :                             NULL );
     131             : 
     132         183 :         ::utl::MiscCfg aMisc;
     133         183 :         SfxPrinterChangeFlags nFlags = SfxPrinterChangeFlags::NONE;
     134         183 :         if ( aMisc.IsPaperOrientationWarning() )
     135           0 :             nFlags |= SfxPrinterChangeFlags::CHG_ORIENTATION;
     136         183 :         if ( aMisc.IsPaperSizeWarning() )
     137           0 :             nFlags |= SfxPrinterChangeFlags::CHG_SIZE;
     138         183 :         pSet->Put( SfxFlagItem( SID_PRINTER_CHANGESTODOC, static_cast<int>(nFlags) ) );
     139         183 :         pSet->Put( SfxBoolItem( SID_PRINTER_NOTFOUND_WARN, aMisc.IsNotFoundWarning() ) );
     140             : 
     141         183 :         pPrinter = VclPtr<SfxPrinter>::Create( pSet );
     142         183 :         pPrinter->SetMapMode( MAP_100TH_MM );
     143         183 :         UpdateDrawPrinter();
     144         183 :         pPrinter->SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
     145             :     }
     146             : 
     147        5060 :     return pPrinter;
     148             : }
     149             : 
     150         108 : void ScDocument::SetPrinter( SfxPrinter* pNewPrinter )
     151             : {
     152         108 :     if ( pNewPrinter == pPrinter.get() )
     153             :     {
     154             :         //  #i6706# SetPrinter is called with the same printer again if
     155             :         //  the JobSetup has changed. In that case just call UpdateDrawPrinter
     156             :         //  (SetRefDevice for drawing layer) because of changed text sizes.
     157           0 :         UpdateDrawPrinter();
     158             :     }
     159             :     else
     160             :     {
     161         108 :         ScopedVclPtr<SfxPrinter> pOld( pPrinter );
     162         108 :         pPrinter = pNewPrinter;
     163         108 :         UpdateDrawPrinter();
     164         108 :         pPrinter->SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
     165             :     }
     166         108 :     InvalidateTextWidth(NULL, NULL, false);     // in both cases
     167         108 : }
     168             : 
     169         216 : void ScDocument::SetPrintOptions()
     170             : {
     171         216 :     if ( !pPrinter ) GetPrinter(); // this sets pPrinter
     172             :     OSL_ENSURE( pPrinter, "Error in printer creation :-/" );
     173             : 
     174         216 :     if ( pPrinter )
     175             :     {
     176         216 :         ::utl::MiscCfg aMisc;
     177         432 :         SfxItemSet aOptSet( pPrinter->GetOptions() );
     178             : 
     179         216 :         SfxPrinterChangeFlags nFlags = SfxPrinterChangeFlags::NONE;
     180         216 :         if ( aMisc.IsPaperOrientationWarning() )
     181           0 :             nFlags |= SfxPrinterChangeFlags::CHG_ORIENTATION;
     182         216 :         if ( aMisc.IsPaperSizeWarning() )
     183           0 :             nFlags |= SfxPrinterChangeFlags::CHG_SIZE;
     184         216 :         aOptSet.Put( SfxFlagItem( SID_PRINTER_CHANGESTODOC, static_cast<int>(nFlags) ) );
     185         216 :         aOptSet.Put( SfxBoolItem( SID_PRINTER_NOTFOUND_WARN, aMisc.IsNotFoundWarning() ) );
     186             : 
     187         432 :         pPrinter->SetOptions( aOptSet );
     188             :     }
     189         216 : }
     190             : 
     191        5111 : VirtualDevice* ScDocument::GetVirtualDevice_100th_mm()
     192             : {
     193        5111 :     if (!pVirtualDevice_100th_mm)
     194             :     {
     195             : #ifdef IOS
     196             :         pVirtualDevice_100th_mm = VclPtr<VirtualDevice>::Create( 8 );
     197             : #else
     198         614 :         pVirtualDevice_100th_mm = VclPtr<VirtualDevice>::Create( 1 );
     199             : #endif
     200         614 :         pVirtualDevice_100th_mm->SetReferenceDevice(VirtualDevice::REFDEV_MODE_MSO1);
     201         614 :         MapMode aMapMode( pVirtualDevice_100th_mm->GetMapMode() );
     202         614 :         aMapMode.SetMapUnit( MAP_100TH_MM );
     203         614 :         pVirtualDevice_100th_mm->SetMapMode( aMapMode );
     204             :     }
     205        5111 :     return pVirtualDevice_100th_mm;
     206             : }
     207             : 
     208        5123 : OutputDevice* ScDocument::GetRefDevice()
     209             : {
     210             :     // Create printer like ref device, see Writer...
     211        5123 :     OutputDevice* pRefDevice = NULL;
     212        5123 :     if ( SC_MOD()->GetInputOptions().GetTextWysiwyg() )
     213          12 :         pRefDevice = GetPrinter();
     214             :     else
     215        5111 :         pRefDevice = GetVirtualDevice_100th_mm();
     216        5123 :     return pRefDevice;
     217             : }
     218             : 
     219           0 : void ScDocument::ModifyStyleSheet( SfxStyleSheetBase& rStyleSheet,
     220             :                                    const SfxItemSet&  rChanges )
     221             : {
     222           0 :     SfxItemSet& rSet = rStyleSheet.GetItemSet();
     223             : 
     224           0 :     switch ( rStyleSheet.GetFamily() )
     225             :     {
     226             :         case SFX_STYLE_FAMILY_PAGE:
     227             :             {
     228           0 :                 const sal_uInt16 nOldScale = getScaleValue(rStyleSheet, ATTR_PAGE_SCALE);
     229           0 :                 const sal_uInt16 nOldScaleToPages = getScaleValue(rStyleSheet, ATTR_PAGE_SCALETOPAGES);
     230           0 :                 rSet.Put( rChanges );
     231           0 :                 const sal_uInt16 nNewScale        = getScaleValue(rStyleSheet, ATTR_PAGE_SCALE);
     232           0 :                 const sal_uInt16 nNewScaleToPages = getScaleValue(rStyleSheet, ATTR_PAGE_SCALETOPAGES);
     233             : 
     234           0 :                 if ( (nOldScale != nNewScale) || (nOldScaleToPages != nNewScaleToPages) )
     235           0 :                     InvalidateTextWidth( rStyleSheet.GetName() );
     236             : 
     237           0 :                 if( SvtLanguageOptions().IsCTLFontEnabled() )
     238             :                 {
     239           0 :                     const SfxPoolItem *pItem = NULL;
     240           0 :                     if( rChanges.GetItemState(ATTR_WRITINGDIR, true, &pItem ) == SfxItemState::SET )
     241           0 :                         ScChartHelper::DoUpdateAllCharts( this );
     242             :                 }
     243             :             }
     244           0 :             break;
     245             : 
     246             :         case SFX_STYLE_FAMILY_PARA:
     247             :             {
     248             :                 bool bNumFormatChanged;
     249           0 :                 if ( ScGlobal::CheckWidthInvalidate( bNumFormatChanged,
     250             :                         rSet, rChanges ) )
     251           0 :                     InvalidateTextWidth( NULL, NULL, bNumFormatChanged );
     252             : 
     253           0 :                 for (SCTAB nTab=0; nTab<=MAXTAB; ++nTab)
     254           0 :                     if (maTabs[nTab] && maTabs[nTab]->IsStreamValid())
     255           0 :                         maTabs[nTab]->SetStreamValid( false );
     256             : 
     257             :                 sal_uLong nOldFormat =
     258             :                     static_cast<const SfxUInt32Item*>(&rSet.Get(
     259           0 :                     ATTR_VALUE_FORMAT ))->GetValue();
     260             :                 sal_uLong nNewFormat =
     261             :                     static_cast<const SfxUInt32Item*>(&rChanges.Get(
     262           0 :                     ATTR_VALUE_FORMAT ))->GetValue();
     263             :                 LanguageType eNewLang, eOldLang;
     264           0 :                 eNewLang = eOldLang = LANGUAGE_DONTKNOW;
     265           0 :                 if ( nNewFormat != nOldFormat )
     266             :                 {
     267           0 :                     SvNumberFormatter* pFormatter = GetFormatTable();
     268           0 :                     eOldLang = pFormatter->GetEntry( nOldFormat )->GetLanguage();
     269           0 :                     eNewLang = pFormatter->GetEntry( nNewFormat )->GetLanguage();
     270             :                 }
     271             : 
     272             :                 // Explanation to Items in rChanges:
     273             :                 //  Set Item        - take over change
     274             :                 //  Dontcare        - Set Default
     275             :                 //  Default         - No change
     276             :                 // ("no change" is not possible with PutExtended, thus the loop)
     277           0 :                 for (sal_uInt16 nWhich = ATTR_PATTERN_START; nWhich <= ATTR_PATTERN_END; nWhich++)
     278             :                 {
     279             :                     const SfxPoolItem* pItem;
     280           0 :                     SfxItemState eState = rChanges.GetItemState( nWhich, false, &pItem );
     281           0 :                     if ( eState == SfxItemState::SET )
     282           0 :                         rSet.Put( *pItem );
     283           0 :                     else if ( eState == SfxItemState::DONTCARE )
     284           0 :                         rSet.ClearItem( nWhich );
     285             :                     // when Default nothing
     286             :                 }
     287             : 
     288           0 :                 if ( eNewLang != eOldLang )
     289             :                     rSet.Put(
     290           0 :                         SvxLanguageItem( eNewLang, ATTR_LANGUAGE_FORMAT ) );
     291             :             }
     292           0 :             break;
     293             :         default:
     294             :         {
     295             :             // added to avoid warnings
     296             :         }
     297             :     }
     298           0 : }
     299             : 
     300           0 : void ScDocument::CopyStdStylesFrom( ScDocument* pSrcDoc )
     301             : {
     302             :     // number format exchange list has to be handled here, too
     303           0 :     NumFmtMergeHandler aNumFmtMergeHdl(this, pSrcDoc);
     304           0 :     xPoolHelper->GetStylePool()->CopyStdStylesFrom( pSrcDoc->xPoolHelper->GetStylePool() );
     305           0 : }
     306             : 
     307           0 : void ScDocument::InvalidateTextWidth( const OUString& rStyleName )
     308             : {
     309           0 :     const SCTAB nCount = GetTableCount();
     310           0 :     for ( SCTAB i=0; i<nCount && maTabs[i]; i++ )
     311           0 :         if ( maTabs[i]->GetPageStyle() == rStyleName )
     312           0 :             InvalidateTextWidth( i );
     313           0 : }
     314             : 
     315           0 : void ScDocument::InvalidateTextWidth( SCTAB nTab )
     316             : {
     317           0 :     ScAddress aAdrFrom( 0,    0,        nTab );
     318           0 :     ScAddress aAdrTo  ( MAXCOL, MAXROW, nTab );
     319           0 :     InvalidateTextWidth( &aAdrFrom, &aAdrTo, false );
     320           0 : }
     321             : 
     322           0 : bool ScDocument::IsPageStyleInUse( const OUString& rStrPageStyle, SCTAB* pInTab )
     323             : {
     324           0 :     bool         bInUse = false;
     325           0 :     const SCTAB nCount = GetTableCount();
     326             :     SCTAB i;
     327             : 
     328           0 :     for ( i = 0; !bInUse && i < nCount && maTabs[i]; i++ )
     329           0 :         bInUse = ( maTabs[i]->GetPageStyle() == rStrPageStyle );
     330             : 
     331           0 :     if ( pInTab )
     332           0 :         *pInTab = i-1;
     333             : 
     334           0 :     return bInUse;
     335             : }
     336             : 
     337           0 : bool ScDocument::RemovePageStyleInUse( const OUString& rStyle )
     338             : {
     339           0 :     bool bWasInUse = false;
     340           0 :     const SCTAB nCount = GetTableCount();
     341             : 
     342           0 :     for ( SCTAB i=0; i<nCount && maTabs[i]; i++ )
     343           0 :         if ( maTabs[i]->GetPageStyle() == rStyle )
     344             :         {
     345           0 :             bWasInUse = true;
     346           0 :             maTabs[i]->SetPageStyle( ScGlobal::GetRscString(STR_STYLENAME_STANDARD) );
     347             :         }
     348             : 
     349           0 :     return bWasInUse;
     350             : }
     351             : 
     352           0 : bool ScDocument::RenamePageStyleInUse( const OUString& rOld, const OUString& rNew )
     353             : {
     354           0 :     bool bWasInUse = false;
     355           0 :     const SCTAB nCount = GetTableCount();
     356             : 
     357           0 :     for ( SCTAB i=0; i<nCount && maTabs[i]; i++ )
     358           0 :         if ( maTabs[i]->GetPageStyle() == rOld )
     359             :         {
     360           0 :             bWasInUse = true;
     361           0 :             maTabs[i]->SetPageStyle( rNew );
     362             :         }
     363             : 
     364           0 :     return bWasInUse;
     365             : }
     366             : 
     367       19478 : sal_uInt8 ScDocument::GetEditTextDirection(SCTAB nTab) const
     368             : {
     369       19478 :     EEHorizontalTextDirection eRet = EE_HTEXTDIR_DEFAULT;
     370             : 
     371       19478 :     OUString aStyleName = GetPageStyle( nTab );
     372       19478 :     SfxStyleSheetBase* pStyle = xPoolHelper->GetStylePool()->Find( aStyleName, SFX_STYLE_FAMILY_PAGE );
     373       19478 :     if ( pStyle )
     374             :     {
     375       19478 :         SfxItemSet& rStyleSet = pStyle->GetItemSet();
     376             :         SvxFrameDirection eDirection = (SvxFrameDirection)
     377       19478 :             static_cast<const SvxFrameDirectionItem&>(rStyleSet.Get( ATTR_WRITINGDIR )).GetValue();
     378             : 
     379       19478 :         if ( eDirection == FRMDIR_HORI_LEFT_TOP )
     380       19421 :             eRet = EE_HTEXTDIR_L2R;
     381          57 :         else if ( eDirection == FRMDIR_HORI_RIGHT_TOP )
     382           0 :             eRet = EE_HTEXTDIR_R2L;
     383             :         // else (invalid for EditEngine): keep "default"
     384             :     }
     385             : 
     386       19478 :     return sal::static_int_cast<sal_uInt8>(eRet);
     387             : }
     388             : 
     389           2 : ScMacroManager* ScDocument::GetMacroManager()
     390             : {
     391           2 :     if (!mpMacroMgr.get())
     392           2 :         mpMacroMgr.reset(new ScMacroManager(this));
     393           2 :     return mpMacroMgr.get();
     394             : }
     395             : 
     396         224 : void ScDocument::FillMatrix(
     397             :     ScMatrix& rMat, SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const
     398             : {
     399         224 :     const ScTable* pTab = FetchTable(nTab);
     400         224 :     if (!pTab)
     401           0 :         return;
     402             : 
     403         224 :     if (nCol1 > nCol2 || nRow1 > nRow2)
     404           0 :         return;
     405             : 
     406             :     SCSIZE nC, nR;
     407         224 :     rMat.GetDimensions(nC, nR);
     408         224 :     if (static_cast<SCROW>(nR) != nRow2 - nRow1 + 1 || static_cast<SCCOL>(nC) != nCol2 - nCol1 + 1)
     409           0 :         return;
     410             : 
     411         224 :     pTab->FillMatrix(rMat, nCol1, nRow1, nCol2, nRow2);
     412             : }
     413             : 
     414           0 : void ScDocument::SetFormulaResults( const ScAddress& rTopPos, const double* pResults, size_t nLen )
     415             : {
     416           0 :     ScTable* pTab = FetchTable(rTopPos.Tab());
     417           0 :     if (!pTab)
     418           0 :         return;
     419             : 
     420           0 :     pTab->SetFormulaResults(rTopPos.Col(), rTopPos.Row(), pResults, nLen);
     421             : }
     422             : 
     423           0 : void ScDocument::SetFormulaResults(
     424             :     const ScAddress& rTopPos, const formula::FormulaTokenRef* pResults, size_t nLen )
     425             : {
     426           0 :     ScTable* pTab = FetchTable(rTopPos.Tab());
     427           0 :     if (!pTab)
     428           0 :         return;
     429             : 
     430           0 :     pTab->SetFormulaResults(rTopPos.Col(), rTopPos.Row(), pResults, nLen);
     431             : }
     432             : 
     433       12330 : void ScDocument::InvalidateTextWidth( const ScAddress* pAdrFrom, const ScAddress* pAdrTo,
     434             :                                       bool bNumFormatChanged )
     435             : {
     436       12330 :     bool bBroadcast = (bNumFormatChanged && GetDocOptions().IsCalcAsShown() && !IsImportingXML() && !IsClipboard());
     437       12330 :     if ( pAdrFrom && !pAdrTo )
     438             :     {
     439           0 :         const SCTAB nTab = pAdrFrom->Tab();
     440             : 
     441           0 :         if (nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
     442           0 :             maTabs[nTab]->InvalidateTextWidth( pAdrFrom, NULL, bNumFormatChanged, bBroadcast );
     443             :     }
     444             :     else
     445             :     {
     446       12330 :         const SCTAB nTabStart = pAdrFrom ? pAdrFrom->Tab() : 0;
     447       12330 :         const SCTAB nTabEnd   = pAdrTo   ? pAdrTo->Tab()   : MAXTAB;
     448             : 
     449       24660 :         for ( SCTAB nTab=nTabStart; nTab<=nTabEnd && nTab < static_cast<SCTAB>(maTabs.size()); nTab++ )
     450       12330 :             if ( maTabs[nTab] )
     451       12330 :                 maTabs[nTab]->InvalidateTextWidth( pAdrFrom, pAdrTo, bNumFormatChanged, bBroadcast );
     452             :     }
     453       12330 : }
     454             : 
     455             : #define CALCMAX                 1000    // Calculations
     456             : 
     457             : namespace {
     458             : 
     459             : class IdleCalcTextWidthScope
     460             : {
     461             :     ScDocument& mrDoc;
     462             :     ScAddress& mrCalcPos;
     463             :     MapMode maOldMapMode;
     464             :     sal_uInt64 mnStartTime;
     465             :     ScStyleSheetPool* mpStylePool;
     466             :     sal_uInt16 mnOldSearchMask;
     467             :     SfxStyleFamily meOldFamily;
     468             :     bool mbNeedMore;
     469             :     bool mbProgress;
     470             : 
     471             : public:
     472         244 :     IdleCalcTextWidthScope(ScDocument& rDoc, ScAddress& rCalcPos) :
     473             :         mrDoc(rDoc),
     474             :         mrCalcPos(rCalcPos),
     475         244 :         mnStartTime(tools::Time::GetSystemTicks()),
     476         244 :         mpStylePool(rDoc.GetStyleSheetPool()),
     477         244 :         mnOldSearchMask(mpStylePool->GetSearchMask()),
     478         244 :         meOldFamily(mpStylePool->GetSearchFamily()),
     479             :         mbNeedMore(false),
     480        1220 :         mbProgress(false)
     481             :     {
     482             :         // The old search mask / family flags must be restored so that e.g.
     483             :         // the styles dialog shows correct listing when it's opened in-between
     484             :         // the calls.
     485             : 
     486         244 :         mrDoc.EnableIdle(false);
     487         244 :         mpStylePool->SetSearchMask(SFX_STYLE_FAMILY_PAGE, SFXSTYLEBIT_ALL);
     488         244 :     }
     489             : 
     490         244 :     ~IdleCalcTextWidthScope()
     491         244 :     {
     492         244 :         SfxPrinter* pDev = mrDoc.GetPrinter();
     493         244 :         if (pDev)
     494         244 :             pDev->SetMapMode(maOldMapMode);
     495             : 
     496         244 :         if (mbProgress)
     497           0 :             ScProgress::DeleteInterpretProgress();
     498             : 
     499         244 :         mpStylePool->SetSearchMask(meOldFamily, mnOldSearchMask);
     500         244 :         mrDoc.EnableIdle(true);
     501         244 :     }
     502             : 
     503         764 :     SCTAB Tab() const { return mrCalcPos.Tab(); }
     504         244 :     SCCOL Col() const { return mrCalcPos.Col(); }
     505         244 :     SCROW Row() const { return mrCalcPos.Row(); }
     506             : 
     507         212 :     void setTab(SCTAB nTab) { mrCalcPos.SetTab(nTab); }
     508           0 :     void setCol(SCCOL nCol) { mrCalcPos.SetCol(nCol); }
     509           0 :     void setRow(SCROW nRow) { mrCalcPos.SetRow(nRow); }
     510             : 
     511         244 :     void incTab(SCTAB nInc=1) { mrCalcPos.IncTab(nInc); }
     512           0 :     void incCol(SCCOL nInc=1) { mrCalcPos.IncCol(nInc); }
     513             : 
     514           0 :     void setOldMapMode(const MapMode& rOldMapMode) { maOldMapMode = rOldMapMode; }
     515             : 
     516           0 :     void setNeedMore(bool b) { mbNeedMore = b; }
     517           0 :     bool getNeedMore() const { return mbNeedMore; }
     518             : 
     519           0 :     sal_uInt64 getStartTime() const { return mnStartTime; }
     520             : 
     521           0 :     void createProgressBar()
     522             :     {
     523           0 :         ScProgress::CreateInterpretProgress(&mrDoc, false);
     524           0 :         mbProgress = true;
     525           0 :     }
     526             : 
     527           0 :     bool hasProgressBar() const { return mbProgress; }
     528             : 
     529         244 :     ScStyleSheetPool* getStylePool() { return mpStylePool; }
     530             : };
     531             : 
     532             : }
     533             : 
     534        2027 : bool ScDocument::IdleCalcTextWidth()            // true = try next again
     535             : {
     536             :     // #i75610# if a printer hasn't been set or created yet, don't create one for this
     537        2027 :     if (!mbIdleEnabled || IsInLinkUpdate() || GetPrinter(false) == NULL)
     538        1783 :         return false;
     539             : 
     540         244 :     IdleCalcTextWidthScope aScope(*this, aCurTextWidthCalcPos);
     541             : 
     542         244 :     if (!ValidRow(aScope.Row()))
     543             :     {
     544           0 :         aScope.setRow(0);
     545           0 :         aScope.incCol(-1);
     546             :     }
     547             : 
     548         244 :     if (aScope.Col() < 0)
     549             :     {
     550           0 :         aScope.setCol(MAXCOL);
     551           0 :         aScope.incTab();
     552             :     }
     553             : 
     554         244 :     if (!ValidTab(aScope.Tab()) || aScope.Tab() >= static_cast<SCTAB>(maTabs.size()) || !maTabs[aScope.Tab()])
     555         212 :         aScope.setTab(0);
     556             : 
     557         244 :     ScTable* pTab = maTabs[aScope.Tab()];
     558         244 :     ScStyleSheet* pStyle = static_cast<ScStyleSheet*>(aScope.getStylePool()->Find(pTab->aPageStyle, SFX_STYLE_FAMILY_PAGE));
     559             :     OSL_ENSURE( pStyle, "Missing StyleSheet :-/" );
     560             : 
     561         244 :     if (!pStyle || getScaleValue(*pStyle, ATTR_PAGE_SCALETOPAGES) == 0)
     562             :     {
     563             :         // Move to the next sheet as the current one has scale-to-pages set,
     564             :         // and bail out.
     565         244 :         aScope.incTab();
     566         244 :         return false;
     567             :     }
     568             : 
     569           0 :     sal_uInt16 nZoom = getScaleValue(*pStyle, ATTR_PAGE_SCALE);
     570           0 :     Fraction aZoomFract(nZoom, 100);
     571             : 
     572             :     // Start at specified cell position (nCol, nRow, nTab).
     573           0 :     ScColumn* pCol  = &pTab->aCol[aScope.Col()];
     574           0 :     boost::scoped_ptr<ScColumnTextWidthIterator> pColIter(new ScColumnTextWidthIterator(*pCol, aScope.Row(), MAXROW));
     575             : 
     576           0 :     OutputDevice* pDev = NULL;
     577           0 :     sal_uInt16 nRestart = 0;
     578           0 :     sal_uInt16 nCount = 0;
     579           0 :     while ( (nZoom > 0) && (nCount < CALCMAX) && (nRestart < 2) )
     580             :     {
     581           0 :         if (pColIter->hasCell())
     582             :         {
     583             :             // More cell in this column.
     584           0 :             SCROW nRow = pColIter->getPos();
     585           0 :             aScope.setRow(nRow);
     586             : 
     587           0 :             if (pColIter->getValue() == TEXTWIDTH_DIRTY)
     588             :             {
     589             :                 // Calculate text width for this cell.
     590           0 :                 double nPPTX = 0.0;
     591           0 :                 double nPPTY = 0.0;
     592           0 :                 if (!pDev)
     593             :                 {
     594           0 :                     pDev = GetPrinter();
     595           0 :                     aScope.setOldMapMode(pDev->GetMapMode());
     596           0 :                     pDev->SetMapMode( MAP_PIXEL );  // Important for GetNeededSize
     597             : 
     598           0 :                     Point aPix1000 = pDev->LogicToPixel( Point(1000,1000), MAP_TWIP );
     599           0 :                     nPPTX = aPix1000.X() / 1000.0;
     600           0 :                     nPPTY = aPix1000.Y() / 1000.0;
     601             :                 }
     602             : 
     603           0 :                 if (!aScope.hasProgressBar() && pCol->IsFormulaDirty(nRow))
     604           0 :                     aScope.createProgressBar();
     605             : 
     606             :                 sal_uInt16 nNewWidth = (sal_uInt16)GetNeededSize(
     607           0 :                     aScope.Col(), aScope.Row(), aScope.Tab(),
     608           0 :                     pDev, nPPTX, nPPTY, aZoomFract,aZoomFract, true, true);   // bTotalSize
     609             : 
     610           0 :                 pColIter->setValue(nNewWidth);
     611           0 :                 aScope.setNeedMore(true);
     612             :             }
     613           0 :             pColIter->next();
     614             :         }
     615             :         else
     616             :         {
     617             :             // No more cell in this column.  Move to the left column and start at row 0.
     618             : 
     619           0 :             bool bNewTab = false;
     620             : 
     621           0 :             aScope.setRow(0);
     622           0 :             aScope.incCol(-1);
     623             : 
     624           0 :             if (aScope.Col() < 0)
     625             :             {
     626             :                 // No more column to the left.  Move to the right-most column of the next sheet.
     627           0 :                 aScope.setCol(MAXCOL);
     628           0 :                 aScope.incTab();
     629           0 :                 bNewTab = true;
     630             :             }
     631             : 
     632           0 :             if (!ValidTab(aScope.Tab()) || aScope.Tab() >= static_cast<SCTAB>(maTabs.size()) || !maTabs[aScope.Tab()] )
     633             :             {
     634             :                 // Sheet doesn't exist at specified sheet position.  Restart at sheet 0.
     635           0 :                 aScope.setTab(0);
     636           0 :                 nRestart++;
     637           0 :                 bNewTab = true;
     638             :             }
     639             : 
     640           0 :             if ( nRestart < 2 )
     641             :             {
     642           0 :                 if ( bNewTab )
     643             :                 {
     644           0 :                     pTab = maTabs[aScope.Tab()];
     645           0 :                     pStyle = static_cast<ScStyleSheet*>(aScope.getStylePool()->Find(
     646           0 :                         pTab->aPageStyle, SFX_STYLE_FAMILY_PAGE));
     647             : 
     648           0 :                     if ( pStyle )
     649             :                     {
     650             :                         // Check if the scale-to-pages setting is set. If
     651             :                         // set, we exit the loop.  If not, get the page
     652             :                         // scale factor of the new sheet.
     653           0 :                         if (getScaleValue(*pStyle, ATTR_PAGE_SCALETOPAGES) == 0)
     654             :                         {
     655           0 :                             nZoom = getScaleValue(*pStyle, ATTR_PAGE_SCALE);
     656           0 :                             aZoomFract = Fraction(nZoom, 100);
     657             :                         }
     658             :                         else
     659           0 :                             nZoom = 0;
     660             :                     }
     661             :                     else
     662             :                     {
     663             :                         OSL_FAIL( "Missing StyleSheet :-/" );
     664             :                     }
     665             :                 }
     666             : 
     667           0 :                 if ( nZoom > 0 )
     668             :                 {
     669           0 :                     pCol  = &pTab->aCol[aScope.Col()];
     670           0 :                     pColIter.reset(new ScColumnTextWidthIterator(*pCol, aScope.Row(), MAXROW));
     671             :                 }
     672             :                 else
     673             :                 {
     674           0 :                     aScope.incTab(); // Move to the next sheet as the current one has scale-to-pages set.
     675           0 :                     return false;
     676             :                 }
     677             :             }
     678             :         }
     679             : 
     680           0 :         ++nCount;
     681             : 
     682             :         // Quit if either 1) its duration exceeds 50 ms, or 2) there is any
     683             :         // pending event after processing 32 cells.
     684           0 :         VclInputFlags ABORT_EVENTS = VCL_INPUT_ANY;
     685           0 :         ABORT_EVENTS &= ~VclInputFlags::TIMER;
     686           0 :         ABORT_EVENTS &= ~VclInputFlags::OTHER;
     687           0 :         if ((50L < tools::Time::GetSystemTicks() - aScope.getStartTime()) || (nCount > 31 && Application::AnyInput(ABORT_EVENTS)))
     688           0 :             nCount = CALCMAX;
     689             :     }
     690             : 
     691         244 :     return aScope.getNeedMore();
     692             : }
     693             : 
     694        6957 : void ScDocument::RepaintRange( const ScRange& rRange )
     695             : {
     696        6957 :     if ( bIsVisible && pShell )
     697             :     {
     698         171 :         ScModelObj* pModel = ScModelObj::getImplementation( pShell->GetModel() );
     699         171 :         if ( pModel )
     700         171 :             pModel->RepaintRange( rRange );     // locked repaints are checked there
     701             :     }
     702        6957 : }
     703             : 
     704           0 : void ScDocument::RepaintRange( const ScRangeList& rRange )
     705             : {
     706           0 :     if ( bIsVisible && pShell )
     707             :     {
     708           0 :         ScModelObj* pModel = ScModelObj::getImplementation( pShell->GetModel() );
     709           0 :         if ( pModel )
     710           0 :             pModel->RepaintRange( rRange );     // locked repaints are checked there
     711             :     }
     712           0 : }
     713             : 
     714           0 : void ScDocument::SaveDdeLinks(SvStream& rStream) const
     715             : {
     716             :     //  when 4.0-Export, remove all with mode != DEFAULT
     717           0 :     bool bExport40 = ( rStream.GetVersion() <= SOFFICE_FILEFORMAT_40 );
     718             : 
     719           0 :     const ::sfx2::SvBaseLinks& rLinks = GetLinkManager()->GetLinks();
     720           0 :     sal_uInt16 nCount = rLinks.size();
     721             : 
     722             :     // Count them first
     723             : 
     724           0 :     sal_uInt16 nDdeCount = 0;
     725             :     sal_uInt16 i;
     726           0 :     for (i=0; i<nCount; i++)
     727             :     {
     728           0 :         ::sfx2::SvBaseLink* pBase = *rLinks[i];
     729           0 :         if (pBase->ISA(ScDdeLink))
     730           0 :             if ( !bExport40 || static_cast<ScDdeLink*>(pBase)->GetMode() == SC_DDE_DEFAULT )
     731           0 :                 ++nDdeCount;
     732             :     }
     733             : 
     734             :     //  Header
     735             : 
     736           0 :     ScMultipleWriteHeader aHdr( rStream );
     737           0 :     rStream.WriteUInt16( nDdeCount );
     738             : 
     739             :     // Save links
     740             : 
     741           0 :     for (i=0; i<nCount; i++)
     742             :     {
     743           0 :         ::sfx2::SvBaseLink* pBase = *rLinks[i];
     744           0 :         if (pBase->ISA(ScDdeLink))
     745             :         {
     746           0 :             ScDdeLink* pLink = static_cast<ScDdeLink*>(pBase);
     747           0 :             if ( !bExport40 || pLink->GetMode() == SC_DDE_DEFAULT )
     748           0 :                 pLink->Store( rStream, aHdr );
     749             :         }
     750           0 :     }
     751           0 : }
     752             : 
     753           0 : void ScDocument::LoadDdeLinks(SvStream& rStream)
     754             : {
     755           0 :     sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(bAutoCalc);
     756           0 :     if (!pMgr)
     757           0 :         return;
     758             : 
     759           0 :     ScMultipleReadHeader aHdr( rStream );
     760             : 
     761           0 :     sal_uInt16 nCount(0);
     762           0 :     rStream.ReadUInt16( nCount );
     763             : 
     764           0 :     const rtl_TextEncoding eCharSet = rStream.GetStreamCharSet();
     765           0 :     const size_t nMinStringSize = eCharSet == RTL_TEXTENCODING_UNICODE ? sizeof(sal_uInt32) : sizeof(sal_uInt16);
     766           0 :     const size_t nMinRecordSize = 1 + nMinStringSize*3;
     767           0 :     const size_t nMaxRecords = rStream.remainingSize() / nMinRecordSize;
     768           0 :     if (nCount > nMaxRecords)
     769             :     {
     770             :         SAL_WARN("sc", "Parsing error: " << nMaxRecords <<
     771             :                  " max possible entries, but " << nCount << " claimed, truncating");
     772           0 :         nCount = nMaxRecords;
     773             :     }
     774             : 
     775           0 :     for (sal_uInt16 i=0; i<nCount; ++i)
     776             :     {
     777           0 :         ScDdeLink* pLink = new ScDdeLink( this, rStream, aHdr );
     778           0 :         pMgr->InsertDDELink(pLink, pLink->GetAppl(), pLink->GetTopic(), pLink->GetItem());
     779           0 :     }
     780             : }
     781             : 
     782          12 : void ScDocument::SetInLinkUpdate(bool bSet)
     783             : {
     784             :     //  called from TableLink and AreaLink
     785             : 
     786             :     OSL_ENSURE( bInLinkUpdate != bSet, "SetInLinkUpdate twice" );
     787          12 :     bInLinkUpdate = bSet;
     788          12 : }
     789             : 
     790        2016 : bool ScDocument::IsInLinkUpdate() const
     791             : {
     792        2016 :     return bInLinkUpdate || IsInDdeLinkUpdate();
     793             : }
     794             : 
     795           0 : void ScDocument::UpdateExternalRefLinks(vcl::Window* pWin)
     796             : {
     797           0 :     if (!pExternalRefMgr.get())
     798           0 :         return;
     799             : 
     800           0 :     sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(bAutoCalc);
     801           0 :     if (!pMgr)
     802           0 :         return;
     803             : 
     804           0 :     const ::sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
     805           0 :     sal_uInt16 nCount = rLinks.size();
     806             : 
     807           0 :     bool bAny = false;
     808             : 
     809             :     // Collect all the external ref links first.
     810           0 :     std::vector<ScExternalRefLink*> aRefLinks;
     811           0 :     for (sal_uInt16 i = 0; i < nCount; ++i)
     812             :     {
     813           0 :         ::sfx2::SvBaseLink* pBase = *rLinks[i];
     814           0 :         ScExternalRefLink* pRefLink = dynamic_cast<ScExternalRefLink*>(pBase);
     815           0 :         if (pRefLink)
     816           0 :             aRefLinks.push_back(pRefLink);
     817             :     }
     818             : 
     819           0 :     sc::WaitPointerSwitch aWaitSwitch(pWin);
     820             : 
     821           0 :     pExternalRefMgr->enableDocTimer(false);
     822           0 :     ScProgress aProgress(GetDocumentShell(), ScResId(SCSTR_UPDATE_EXTDOCS).toString(), aRefLinks.size());
     823           0 :     for (size_t i = 0, n = aRefLinks.size(); i < n; ++i)
     824             :     {
     825           0 :         aProgress.SetState(i+1);
     826             : 
     827           0 :         ScExternalRefLink* pRefLink = aRefLinks[i];
     828           0 :         if (pRefLink->Update())
     829             :         {
     830           0 :             bAny = true;
     831           0 :             continue;
     832             :         }
     833             : 
     834             :         // Update failed.  Notify the user.
     835             : 
     836           0 :         OUString aFile;
     837           0 :         sfx2::LinkManager::GetDisplayNames(pRefLink, NULL, &aFile, NULL, NULL);
     838             :         // Decode encoded URL for display friendliness.
     839           0 :         INetURLObject aUrl(aFile,INetURLObject::WAS_ENCODED);
     840           0 :         aFile = aUrl.GetMainURL(INetURLObject::DECODE_UNAMBIGUOUS);
     841             : 
     842           0 :         OUStringBuffer aBuf;
     843           0 :         aBuf.append(OUString(ScResId(SCSTR_EXTDOC_NOT_LOADED)));
     844           0 :         aBuf.appendAscii("\n\n");
     845           0 :         aBuf.append(aFile);
     846           0 :         ScopedVclPtrInstance< MessageDialog > aBox(pWin, aBuf.makeStringAndClear());
     847           0 :         aBox->Execute();
     848           0 :     }
     849             : 
     850           0 :     pExternalRefMgr->enableDocTimer(true);
     851             : 
     852           0 :     if (bAny)
     853             :     {
     854           0 :         TrackFormulas();
     855           0 :         pShell->Broadcast( SfxSimpleHint(FID_DATACHANGED) );
     856             : 
     857             :         // #i101960# set document modified, as in TrackTimeHdl for DDE links
     858           0 :         if (!pShell->IsModified())
     859             :         {
     860           0 :             pShell->SetModified( true );
     861           0 :             SfxBindings* pBindings = GetViewBindings();
     862           0 :             if (pBindings)
     863             :             {
     864           0 :                 pBindings->Invalidate( SID_SAVEDOC );
     865           0 :                 pBindings->Invalidate( SID_DOC_MODIFIED );
     866             :             }
     867             :         }
     868           0 :     }
     869             : }
     870             : 
     871           0 : void ScDocument::CopyDdeLinks( ScDocument* pDestDoc ) const
     872             : {
     873           0 :     if (bIsClip)        // Create from Stream
     874             :     {
     875           0 :         if (pClipData)
     876             :         {
     877           0 :             pClipData->Seek(0);
     878           0 :             pDestDoc->LoadDdeLinks(*pClipData);
     879             :         }
     880             : 
     881           0 :         return;
     882             :     }
     883             : 
     884           0 :     const sfx2::LinkManager* pMgr = GetDocLinkManager().getExistingLinkManager();
     885           0 :     if (!pMgr)
     886           0 :         return;
     887             : 
     888           0 :     sfx2::LinkManager* pDestMgr = pDestDoc->GetDocLinkManager().getLinkManager(pDestDoc->bAutoCalc);
     889           0 :     if (!pDestMgr)
     890           0 :         return;
     891             : 
     892           0 :     const sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
     893           0 :     for (size_t i = 0, n = rLinks.size(); i < n; ++i)
     894             :     {
     895           0 :         const sfx2::SvBaseLink* pBase = *rLinks[i];
     896           0 :         if (pBase->ISA(ScDdeLink))
     897             :         {
     898           0 :             const ScDdeLink* p = static_cast<const ScDdeLink*>(pBase);
     899           0 :             ScDdeLink* pNew = new ScDdeLink(pDestDoc, *p);
     900             :             pDestMgr->InsertDDELink(
     901           0 :                 pNew, pNew->GetAppl(), pNew->GetTopic(), pNew->GetItem());
     902             :         }
     903             :     }
     904             : }
     905             : 
     906             : namespace {
     907             : 
     908             : /** Tries to find the specified DDE link.
     909             :     @param pnDdePos  (out-param) if not 0, the index of the DDE link is returned here
     910             :                      (does not include other links from link manager).
     911             :     @return  The DDE link, if it exists, otherwise 0. */
     912           0 : ScDdeLink* lclGetDdeLink(
     913             :         const sfx2::LinkManager* pLinkManager,
     914             :         const OUString& rAppl, const OUString& rTopic, const OUString& rItem, sal_uInt8 nMode,
     915             :         size_t* pnDdePos = NULL )
     916             : {
     917           0 :     if( pLinkManager )
     918             :     {
     919           0 :         const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
     920           0 :         size_t nCount = rLinks.size();
     921           0 :         if( pnDdePos ) *pnDdePos = 0;
     922           0 :         for( size_t nIndex = 0; nIndex < nCount; ++nIndex )
     923             :         {
     924           0 :             ::sfx2::SvBaseLink* pLink = *rLinks[ nIndex ];
     925           0 :             if( ScDdeLink* pDdeLink = PTR_CAST( ScDdeLink, pLink ) )
     926             :             {
     927           0 :                 if( (OUString(pDdeLink->GetAppl()) == rAppl) &&
     928           0 :                     (OUString(pDdeLink->GetTopic()) == rTopic) &&
     929           0 :                     (OUString(pDdeLink->GetItem()) == rItem) &&
     930           0 :                     ((nMode == SC_DDE_IGNOREMODE) || (nMode == pDdeLink->GetMode())) )
     931           0 :                     return pDdeLink;
     932           0 :                 if( pnDdePos ) ++*pnDdePos;
     933             :             }
     934             :         }
     935             :     }
     936           0 :     return NULL;
     937             : }
     938             : 
     939             : /** Returns a pointer to the specified DDE link.
     940             :     @param nDdePos  Index of the DDE link (does not include other links from link manager).
     941             :     @return  The DDE link, if it exists, otherwise 0. */
     942          13 : ScDdeLink* lclGetDdeLink( const sfx2::LinkManager* pLinkManager, size_t nDdePos )
     943             : {
     944          13 :     if( pLinkManager )
     945             :     {
     946          13 :         const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
     947          13 :         size_t nCount = rLinks.size();
     948          13 :         size_t nDdeIndex = 0;       // counts only the DDE links
     949          15 :         for( size_t nIndex = 0; nIndex < nCount; ++nIndex )
     950             :         {
     951          13 :             ::sfx2::SvBaseLink* pLink = *rLinks[ nIndex ];
     952          13 :             if( ScDdeLink* pDdeLink = PTR_CAST( ScDdeLink, pLink ) )
     953             :             {
     954          13 :                 if( nDdeIndex == nDdePos )
     955          11 :                     return pDdeLink;
     956           2 :                 ++nDdeIndex;
     957             :             }
     958             :         }
     959             :     }
     960           2 :     return NULL;
     961             : }
     962             : 
     963             : } // namespace
     964             : 
     965           0 : bool ScDocument::FindDdeLink( const OUString& rAppl, const OUString& rTopic, const OUString& rItem,
     966             :         sal_uInt8 nMode, size_t& rnDdePos )
     967             : {
     968           0 :     return lclGetDdeLink( GetLinkManager(), rAppl, rTopic, rItem, nMode, &rnDdePos ) != NULL;
     969             : }
     970             : 
     971          13 : bool ScDocument::GetDdeLinkData( size_t nDdePos, OUString& rAppl, OUString& rTopic, OUString& rItem ) const
     972             : {
     973          13 :     if( const ScDdeLink* pDdeLink = lclGetDdeLink( GetLinkManager(), nDdePos ) )
     974             :     {
     975          11 :         rAppl  = pDdeLink->GetAppl();
     976          11 :         rTopic = pDdeLink->GetTopic();
     977          11 :         rItem  = pDdeLink->GetItem();
     978          11 :         return true;
     979             :     }
     980           2 :     return false;
     981             : }
     982             : 
     983           0 : bool ScDocument::GetDdeLinkMode( size_t nDdePos, sal_uInt8& rnMode ) const
     984             : {
     985           0 :     if( const ScDdeLink* pDdeLink = lclGetDdeLink( GetLinkManager(), nDdePos ) )
     986             :     {
     987           0 :         rnMode = pDdeLink->GetMode();
     988           0 :         return true;
     989             :     }
     990           0 :     return false;
     991             : }
     992             : 
     993           0 : const ScMatrix* ScDocument::GetDdeLinkResultMatrix( size_t nDdePos ) const
     994             : {
     995           0 :     const ScDdeLink* pDdeLink = lclGetDdeLink( GetLinkManager(), nDdePos );
     996           0 :     return pDdeLink ? pDdeLink->GetResult() : NULL;
     997             : }
     998             : 
     999           0 : bool ScDocument::CreateDdeLink( const OUString& rAppl, const OUString& rTopic, const OUString& rItem, sal_uInt8 nMode, ScMatrixRef pResults )
    1000             : {
    1001             :     /*  Create a DDE link without updating it (i.e. for Excel import), to prevent
    1002             :         unwanted connections. First try to find existing link. Set result array
    1003             :         on existing and new links. */
    1004             :     //TODO: store DDE links additionally at document (for efficiency)?
    1005             :     OSL_ENSURE( nMode != SC_DDE_IGNOREMODE, "ScDocument::CreateDdeLink - SC_DDE_IGNOREMODE not allowed here" );
    1006             : 
    1007           0 :     sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(bAutoCalc);
    1008           0 :     if (!pMgr)
    1009           0 :         return false;
    1010             : 
    1011           0 :     if (nMode != SC_DDE_IGNOREMODE)
    1012             :     {
    1013           0 :         ScDdeLink* pDdeLink = lclGetDdeLink(pMgr, rAppl, rTopic, rItem, nMode);
    1014           0 :         if( !pDdeLink )
    1015             :         {
    1016             :             // create a new DDE link, but without TryUpdate
    1017           0 :             pDdeLink = new ScDdeLink( this, rAppl, rTopic, rItem, nMode );
    1018           0 :             pMgr->InsertDDELink(pDdeLink, rAppl, rTopic, rItem);
    1019             :         }
    1020             : 
    1021             :         // insert link results
    1022           0 :         if( pResults )
    1023           0 :             pDdeLink->SetResult( pResults );
    1024             : 
    1025           0 :         return true;
    1026             :     }
    1027           0 :     return false;
    1028             : }
    1029             : 
    1030           0 : bool ScDocument::SetDdeLinkResultMatrix( size_t nDdePos, ScMatrixRef pResults )
    1031             : {
    1032           0 :     if( ScDdeLink* pDdeLink = lclGetDdeLink( GetLinkManager(), nDdePos ) )
    1033             :     {
    1034           0 :         pDdeLink->SetResult( pResults );
    1035           0 :         return true;
    1036             :     }
    1037           0 :     return false;
    1038             : }
    1039             : 
    1040         347 : bool ScDocument::HasAreaLinks() const
    1041             : {
    1042         347 :     const sfx2::LinkManager* pMgr = GetDocLinkManager().getExistingLinkManager();
    1043         347 :     if (!pMgr)
    1044         187 :         return false;
    1045             : 
    1046         160 :     const ::sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
    1047         160 :     sal_uInt16 nCount = rLinks.size();
    1048         161 :     for (sal_uInt16 i=0; i<nCount; i++)
    1049           1 :         if ((*rLinks[i])->ISA(ScAreaLink))
    1050           0 :             return true;
    1051             : 
    1052         160 :     return false;
    1053             : }
    1054             : 
    1055           0 : void ScDocument::UpdateAreaLinks()
    1056             : {
    1057           0 :     sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(false);
    1058           0 :     if (!pMgr)
    1059           0 :         return;
    1060             : 
    1061           0 :     const ::sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
    1062           0 :     for (size_t i=0; i<rLinks.size(); i++)
    1063             :     {
    1064           0 :         ::sfx2::SvBaseLink* pBase = *rLinks[i];
    1065           0 :         if (pBase->ISA(ScAreaLink))
    1066           0 :             pBase->Update();
    1067             :     }
    1068             : }
    1069             : 
    1070         103 : void ScDocument::DeleteAreaLinksOnTab( SCTAB nTab )
    1071             : {
    1072         103 :     sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(false);
    1073         103 :     if (!pMgr)
    1074         178 :         return;
    1075             : 
    1076          28 :     const ::sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
    1077          28 :     sal_uInt16 nPos = 0;
    1078          56 :     while ( nPos < rLinks.size() )
    1079             :     {
    1080           0 :         const ::sfx2::SvBaseLink* pBase = *rLinks[nPos];
    1081           0 :         if ( pBase->ISA(ScAreaLink) &&
    1082           0 :              static_cast<const ScAreaLink*>(pBase)->GetDestArea().aStart.Tab() == nTab )
    1083           0 :             pMgr->Remove(nPos);
    1084             :         else
    1085           0 :             ++nPos;
    1086             :     }
    1087             : }
    1088             : 
    1089         362 : void ScDocument::UpdateRefAreaLinks( UpdateRefMode eUpdateRefMode,
    1090             :                              const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
    1091             : {
    1092         362 :     sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(false);
    1093         362 :     if (!pMgr)
    1094         575 :         return;
    1095             : 
    1096         149 :     bool bAnyUpdate = false;
    1097             : 
    1098         149 :     const ::sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
    1099         149 :     sal_uInt16 nCount = rLinks.size();
    1100         152 :     for (sal_uInt16 i=0; i<nCount; i++)
    1101             :     {
    1102           3 :         ::sfx2::SvBaseLink* pBase = *rLinks[i];
    1103           3 :         if (pBase->ISA(ScAreaLink))
    1104             :         {
    1105           0 :             ScAreaLink* pLink = static_cast<ScAreaLink*>(pBase);
    1106           0 :             ScRange aOutRange = pLink->GetDestArea();
    1107             : 
    1108           0 :             SCCOL nCol1 = aOutRange.aStart.Col();
    1109           0 :             SCROW nRow1 = aOutRange.aStart.Row();
    1110           0 :             SCTAB nTab1 = aOutRange.aStart.Tab();
    1111           0 :             SCCOL nCol2 = aOutRange.aEnd.Col();
    1112           0 :             SCROW nRow2 = aOutRange.aEnd.Row();
    1113           0 :             SCTAB nTab2 = aOutRange.aEnd.Tab();
    1114             : 
    1115             :             ScRefUpdateRes eRes =
    1116             :                 ScRefUpdate::Update( this, eUpdateRefMode,
    1117           0 :                     rRange.aStart.Col(), rRange.aStart.Row(), rRange.aStart.Tab(),
    1118           0 :                     rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aEnd.Tab(), nDx, nDy, nDz,
    1119           0 :                     nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
    1120           0 :             if ( eRes != UR_NOTHING )
    1121             :             {
    1122           0 :                 pLink->SetDestArea( ScRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ) );
    1123           0 :                 bAnyUpdate = true;
    1124             :             }
    1125             :         }
    1126             :     }
    1127             : 
    1128         149 :     if ( bAnyUpdate )
    1129             :     {
    1130             :         // #i52120# Look for duplicates (after updating all positions).
    1131             :         // If several links start at the same cell, the one with the lower index is removed
    1132             :         // (file format specifies only one link definition for a cell).
    1133             : 
    1134           0 :         sal_uInt16 nFirstIndex = 0;
    1135           0 :         while ( nFirstIndex < nCount )
    1136             :         {
    1137           0 :             bool bFound = false;
    1138           0 :             ::sfx2::SvBaseLink* pFirst = *rLinks[nFirstIndex];
    1139           0 :             if ( pFirst->ISA(ScAreaLink) )
    1140             :             {
    1141           0 :                 ScAddress aFirstPos = static_cast<ScAreaLink*>(pFirst)->GetDestArea().aStart;
    1142           0 :                 for ( sal_uInt16 nSecondIndex = nFirstIndex + 1; nSecondIndex < nCount && !bFound; ++nSecondIndex )
    1143             :                 {
    1144           0 :                     ::sfx2::SvBaseLink* pSecond = *rLinks[nSecondIndex];
    1145           0 :                     if ( pSecond->ISA(ScAreaLink) &&
    1146           0 :                          static_cast<ScAreaLink*>(pSecond)->GetDestArea().aStart == aFirstPos )
    1147             :                     {
    1148             :                         // remove the first link, exit the inner loop, don't increment nFirstIndex
    1149           0 :                         pMgr->Remove(pFirst);
    1150           0 :                         nCount = rLinks.size();
    1151           0 :                         bFound = true;
    1152             :                     }
    1153             :                 }
    1154             :             }
    1155           0 :             if (!bFound)
    1156           0 :                 ++nFirstIndex;
    1157             :         }
    1158             :     }
    1159             : }
    1160             : 
    1161             : // TimerDelays etc.
    1162           0 : void ScDocument::KeyInput( const KeyEvent& )
    1163             : {
    1164           0 :     if ( pChartListenerCollection->hasListeners() )
    1165           0 :         pChartListenerCollection->StartTimer();
    1166           0 :     if( apTemporaryChartLock.get() )
    1167           0 :         apTemporaryChartLock->StartOrContinueLocking();
    1168           0 : }
    1169             : 
    1170           0 : bool ScDocument::CheckMacroWarn()
    1171             : {
    1172             :     //  The check for macro configuration, macro warning and disabling is now handled
    1173             :     //  in SfxObjectShell::AdjustMacroMode, called by SfxObjectShell::CallBasic.
    1174             : 
    1175           0 :     return true;
    1176             : }
    1177             : 
    1178           6 : SfxBindings* ScDocument::GetViewBindings()
    1179             : {
    1180             :     //  used to invalidate slots after changes to this document
    1181             : 
    1182           6 :     if ( !pShell )
    1183           0 :         return NULL;        // no ObjShell -> no view
    1184             : 
    1185             :     //  first check current view
    1186           6 :     SfxViewFrame* pViewFrame = SfxViewFrame::Current();
    1187           6 :     if ( pViewFrame && pViewFrame->GetObjectShell() != pShell )     // wrong document?
    1188           6 :         pViewFrame = NULL;
    1189             : 
    1190             :     //  otherwise use first view for this doc
    1191           6 :     if ( !pViewFrame )
    1192           6 :         pViewFrame = SfxViewFrame::GetFirst( pShell );
    1193             : 
    1194           6 :     if (pViewFrame)
    1195           3 :         return &pViewFrame->GetBindings();
    1196             :     else
    1197           3 :         return NULL;
    1198             : }
    1199             : 
    1200           2 : void ScDocument::TransliterateText( const ScMarkData& rMultiMark, sal_Int32 nType )
    1201             : {
    1202             :     OSL_ENSURE( rMultiMark.IsMultiMarked(), "TransliterateText: no selection" );
    1203             : 
    1204           2 :     utl::TransliterationWrapper aTransliterationWrapper( comphelper::getProcessComponentContext(), nType );
    1205           2 :     bool bConsiderLanguage = aTransliterationWrapper.needLanguageForTheMode();
    1206           2 :     sal_uInt16 nLanguage = LANGUAGE_SYSTEM;
    1207             : 
    1208           4 :     boost::scoped_ptr<ScEditEngineDefaulter> pEngine;        // not using pEditEngine member because of defaults
    1209             : 
    1210           2 :     SCTAB nCount = GetTableCount();
    1211           2 :     ScMarkData::const_iterator itr = rMultiMark.begin(), itrEnd = rMultiMark.end();
    1212           4 :     for (; itr != itrEnd && *itr < nCount; ++itr)
    1213           2 :         if ( maTabs[*itr] )
    1214             :         {
    1215           2 :             SCTAB nTab = *itr;
    1216           2 :             SCCOL nCol = 0;
    1217           2 :             SCROW nRow = 0;
    1218             : 
    1219           2 :             bool bFound = rMultiMark.IsCellMarked( nCol, nRow );
    1220           2 :             if (!bFound)
    1221           0 :                 bFound = GetNextMarkedCell( nCol, nRow, nTab, rMultiMark );
    1222             : 
    1223          10 :             while (bFound)
    1224             :             {
    1225           6 :                 ScRefCellValue aCell;
    1226           6 :                 aCell.assign(*this, ScAddress(nCol, nRow, nTab));
    1227             : 
    1228             :                 // fdo#32786 TITLE_CASE/SENTENCE_CASE need the extra handling in EditEngine (loop over words/sentences).
    1229             :                 // Still use TransliterationWrapper directly for text cells with other transliteration types,
    1230             :                 // for performance reasons.
    1231          12 :                 if (aCell.meType == CELLTYPE_EDIT ||
    1232          12 :                     (aCell.meType == CELLTYPE_STRING &&
    1233           6 :                      ( nType == i18n::TransliterationModulesExtra::SENTENCE_CASE || nType == i18n::TransliterationModulesExtra::TITLE_CASE)))
    1234             :                 {
    1235           0 :                     if (!pEngine)
    1236           0 :                         pEngine.reset(new ScFieldEditEngine(this, GetEnginePool(), GetEditPool()));
    1237             : 
    1238             :                     // defaults from cell attributes must be set so right language is used
    1239           0 :                     const ScPatternAttr* pPattern = GetPattern( nCol, nRow, nTab );
    1240           0 :                     SfxItemSet* pDefaults = new SfxItemSet( pEngine->GetEmptyItemSet() );
    1241           0 :                     if ( ScStyleSheet* pPreviewStyle = GetPreviewCellStyle( nCol, nRow, nTab ) )
    1242             :                     {
    1243           0 :                         boost::scoped_ptr<ScPatternAttr> pPreviewPattern(new ScPatternAttr( *pPattern ));
    1244           0 :                         pPreviewPattern->SetStyleSheet(pPreviewStyle);
    1245           0 :                         pPreviewPattern->FillEditItemSet( pDefaults );
    1246             :                     }
    1247             :                     else
    1248             :                     {
    1249           0 :                         SfxItemSet* pFontSet = GetPreviewFont( nCol, nRow, nTab );
    1250           0 :                         pPattern->FillEditItemSet( pDefaults, pFontSet );
    1251             :                     }
    1252           0 :                     pEngine->SetDefaults( pDefaults,  true );
    1253           0 :                     if (aCell.meType == CELLTYPE_STRING)
    1254           0 :                         pEngine->SetText(aCell.mpString->getString());
    1255           0 :                     else if (aCell.mpEditText)
    1256           0 :                         pEngine->SetText(*aCell.mpEditText);
    1257             : 
    1258           0 :                     pEngine->ClearModifyFlag();
    1259             : 
    1260           0 :                     sal_Int32 nLastPar = pEngine->GetParagraphCount();
    1261           0 :                     if (nLastPar)
    1262           0 :                         --nLastPar;
    1263           0 :                     sal_Int32 nTxtLen = pEngine->GetTextLen(nLastPar);
    1264           0 :                     ESelection aSelAll( 0, 0, nLastPar, nTxtLen );
    1265             : 
    1266           0 :                     pEngine->TransliterateText( aSelAll, nType );
    1267             : 
    1268           0 :                     if ( pEngine->IsModified() )
    1269             :                     {
    1270           0 :                         ScEditAttrTester aTester( pEngine.get() );
    1271           0 :                         if ( aTester.NeedsObject() )
    1272             :                         {
    1273             :                             // remove defaults (paragraph attributes) before creating text object
    1274           0 :                             SfxItemSet* pEmpty = new SfxItemSet( pEngine->GetEmptyItemSet() );
    1275           0 :                             pEngine->SetDefaults( pEmpty, true );
    1276             : 
    1277             :                             // The cell will take ownership of the text object instance.
    1278           0 :                             SetEditText(ScAddress(nCol,nRow,nTab), pEngine->CreateTextObject());
    1279             :                         }
    1280             :                         else
    1281             :                         {
    1282           0 :                             ScSetStringParam aParam;
    1283           0 :                             aParam.setTextInput();
    1284           0 :                             SetString(ScAddress(nCol,nRow,nTab), pEngine->GetText(), &aParam);
    1285           0 :                         }
    1286           0 :                     }
    1287             :                 }
    1288             : 
    1289           6 :                 else if (aCell.meType == CELLTYPE_STRING)
    1290             :                 {
    1291           6 :                     OUString aOldStr = aCell.mpString->getString();
    1292           6 :                     sal_Int32 nOldLen = aOldStr.getLength();
    1293             : 
    1294           6 :                     if ( bConsiderLanguage )
    1295             :                     {
    1296           6 :                         SvtScriptType nScript = GetStringScriptType( aOldStr );        //TODO: cell script type?
    1297             :                         sal_uInt16 nWhich = ( nScript == SvtScriptType::ASIAN ) ? ATTR_CJK_FONT_LANGUAGE :
    1298             :                                         ( ( nScript == SvtScriptType::COMPLEX ) ? ATTR_CTL_FONT_LANGUAGE :
    1299           6 :                                                                                 ATTR_FONT_LANGUAGE );
    1300           6 :                         nLanguage = static_cast<const SvxLanguageItem*>(GetAttr( nCol, nRow, nTab, nWhich ))->GetValue();
    1301             :                     }
    1302             : 
    1303          12 :                     uno::Sequence<sal_Int32> aOffsets;
    1304          12 :                     OUString aNewStr = aTransliterationWrapper.transliterate( aOldStr, nLanguage, 0, nOldLen, &aOffsets );
    1305             : 
    1306           6 :                     if ( aNewStr != aOldStr )
    1307             :                     {
    1308           6 :                         ScSetStringParam aParam;
    1309           6 :                         aParam.setTextInput();
    1310           6 :                         SetString(ScAddress(nCol,nRow,nTab), aNewStr, &aParam);
    1311           6 :                     }
    1312             :                 }
    1313           6 :                 bFound = GetNextMarkedCell( nCol, nRow, nTab, rMultiMark );
    1314           6 :             }
    1315           2 :         }
    1316         158 : }
    1317             : 
    1318             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11