LCOV - code coverage report
Current view: top level - sc/source/core/data - documen8.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 236 627 37.6 %
Date: 2014-04-11 Functions: 34 66 51.5 %
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             : 
      91             : #include <boost/scoped_ptr.hpp>
      92             : 
      93             : using namespace com::sun::star;
      94             : 
      95             : // STATIC DATA -----------------------------------------------------------
      96             : 
      97             : namespace {
      98             : 
      99         335 : inline sal_uInt16 getScaleValue(SfxStyleSheetBase& rStyle, sal_uInt16 nWhich)
     100             : {
     101         335 :     return static_cast<const SfxUInt16Item&>(rStyle.GetItemSet().Get(nWhich)).GetValue();
     102             : }
     103             : 
     104             : }
     105             : 
     106        1899 : void ScDocument::ImplCreateOptions()
     107             : {
     108        1899 :     pDocOptions  = new ScDocOptions();
     109        1899 :     pViewOptions = new ScViewOptions();
     110        1899 : }
     111             : 
     112        1710 : void ScDocument::ImplDeleteOptions()
     113             : {
     114        1710 :     delete pDocOptions;
     115        1710 :     delete pViewOptions;
     116        1710 :     delete pExtDocOptions;
     117        1710 : }
     118             : 
     119        4394 : SfxPrinter* ScDocument::GetPrinter(bool bCreateIfNotExist)
     120             : {
     121        4394 :     if ( !pPrinter && bCreateIfNotExist )
     122             :     {
     123             :         SfxItemSet* pSet =
     124         144 :             new SfxItemSet( *xPoolHelper->GetDocPool(),
     125             :                             SID_PRINTER_NOTFOUND_WARN,  SID_PRINTER_NOTFOUND_WARN,
     126             :                             SID_PRINTER_CHANGESTODOC,   SID_PRINTER_CHANGESTODOC,
     127             :                             SID_PRINT_SELECTEDSHEET,    SID_PRINT_SELECTEDSHEET,
     128             :                             SID_SCPRINTOPTIONS,         SID_SCPRINTOPTIONS,
     129         144 :                             NULL );
     130             : 
     131         144 :         ::utl::MiscCfg aMisc;
     132         144 :         sal_uInt16 nFlags = 0;
     133         144 :         if ( aMisc.IsPaperOrientationWarning() )
     134           0 :             nFlags |= SFX_PRINTER_CHG_ORIENTATION;
     135         144 :         if ( aMisc.IsPaperSizeWarning() )
     136           0 :             nFlags |= SFX_PRINTER_CHG_SIZE;
     137         144 :         pSet->Put( SfxFlagItem( SID_PRINTER_CHANGESTODOC, nFlags ) );
     138         144 :         pSet->Put( SfxBoolItem( SID_PRINTER_NOTFOUND_WARN, aMisc.IsNotFoundWarning() ) );
     139             : 
     140         144 :         pPrinter = new SfxPrinter( pSet );
     141         144 :         pPrinter->SetMapMode( MAP_100TH_MM );
     142         144 :         UpdateDrawPrinter();
     143         144 :         pPrinter->SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
     144             :     }
     145             : 
     146        4394 :     return pPrinter;
     147             : }
     148             : 
     149          64 : void ScDocument::SetPrinter( SfxPrinter* pNewPrinter )
     150             : {
     151          64 :     if ( pNewPrinter == pPrinter )
     152             :     {
     153             :         //  #i6706# SetPrinter is called with the same printer again if
     154             :         //  the JobSetup has changed. In that case just call UpdateDrawPrinter
     155             :         //  (SetRefDevice for drawing layer) because of changed text sizes.
     156           0 :         UpdateDrawPrinter();
     157             :     }
     158             :     else
     159             :     {
     160          64 :         SfxPrinter* pOld = pPrinter;
     161          64 :         pPrinter = pNewPrinter;
     162          64 :         UpdateDrawPrinter();
     163          64 :         pPrinter->SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
     164          64 :         delete pOld;
     165             :     }
     166          64 :     InvalidateTextWidth(NULL, NULL, false);     // in both cases
     167          64 : }
     168             : 
     169         128 : void ScDocument::SetPrintOptions()
     170             : {
     171         128 :     if ( !pPrinter ) GetPrinter(); // setzt pPrinter
     172             :     OSL_ENSURE( pPrinter, "Error in printer creation :-/" );
     173             : 
     174         128 :     if ( pPrinter )
     175             :     {
     176         128 :         ::utl::MiscCfg aMisc;
     177         256 :         SfxItemSet aOptSet( pPrinter->GetOptions() );
     178             : 
     179         128 :         sal_uInt16 nFlags = 0;
     180         128 :         if ( aMisc.IsPaperOrientationWarning() )
     181           0 :             nFlags |= SFX_PRINTER_CHG_ORIENTATION;
     182         128 :         if ( aMisc.IsPaperSizeWarning() )
     183           0 :             nFlags |= SFX_PRINTER_CHG_SIZE;
     184         128 :         aOptSet.Put( SfxFlagItem( SID_PRINTER_CHANGESTODOC, nFlags ) );
     185         128 :         aOptSet.Put( SfxBoolItem( SID_PRINTER_NOTFOUND_WARN, aMisc.IsNotFoundWarning() ) );
     186             : 
     187         256 :         pPrinter->SetOptions( aOptSet );
     188             :     }
     189         128 : }
     190             : 
     191        3188 : VirtualDevice* ScDocument::GetVirtualDevice_100th_mm()
     192             : {
     193        3188 :     if (!pVirtualDevice_100th_mm)
     194             :     {
     195             : #ifdef IOS
     196             :         pVirtualDevice_100th_mm = new VirtualDevice( 8 );
     197             : #else
     198         368 :         pVirtualDevice_100th_mm = new VirtualDevice( 1 );
     199             : #endif
     200         368 :         pVirtualDevice_100th_mm->SetReferenceDevice(VirtualDevice::REFDEV_MODE_MSO1);
     201         368 :         MapMode aMapMode( pVirtualDevice_100th_mm->GetMapMode() );
     202         368 :         aMapMode.SetMapUnit( MAP_100TH_MM );
     203         368 :         pVirtualDevice_100th_mm->SetMapMode( aMapMode );
     204             :     }
     205        3188 :     return pVirtualDevice_100th_mm;
     206             : }
     207             : 
     208        3266 : OutputDevice* ScDocument::GetRefDevice()
     209             : {
     210             :     // Create printer like ref device, see Writer...
     211        3266 :     OutputDevice* pRefDevice = NULL;
     212        3266 :     if ( SC_MOD()->GetInputOptions().GetTextWysiwyg() )
     213          78 :         pRefDevice = GetPrinter();
     214             :     else
     215        3188 :         pRefDevice = GetVirtualDevice_100th_mm();
     216        3266 :     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 ) == SFX_ITEM_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             :                     ((const SfxUInt32Item*)&rSet.Get(
     259           0 :                     ATTR_VALUE_FORMAT ))->GetValue();
     260             :                 sal_uLong nNewFormat =
     261             :                     ((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             :                 // Bedeutung der Items in rChanges:
     273             :                 //  Item gesetzt    - Aenderung uebernehmen
     274             :                 //  Dontcare        - Default setzen
     275             :                 //  Default         - keine Aenderung
     276             :                 // ("keine Aenderung" geht nicht mit PutExtended, darum Schleife)
     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 == SFX_ITEM_SET )
     282           0 :                         rSet.Put( *pItem );
     283           0 :                     else if ( eState == SFX_ITEM_DONTCARE )
     284           0 :                         rSet.ClearItem( nWhich );
     285             :                     // bei Default nichts
     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       14402 : sal_uInt8 ScDocument::GetEditTextDirection(SCTAB nTab) const
     368             : {
     369       14402 :     EEHorizontalTextDirection eRet = EE_HTEXTDIR_DEFAULT;
     370             : 
     371       14402 :     OUString aStyleName = GetPageStyle( nTab );
     372       14402 :     SfxStyleSheetBase* pStyle = xPoolHelper->GetStylePool()->Find( aStyleName, SFX_STYLE_FAMILY_PAGE );
     373       14402 :     if ( pStyle )
     374             :     {
     375       14402 :         SfxItemSet& rStyleSet = pStyle->GetItemSet();
     376             :         SvxFrameDirection eDirection = (SvxFrameDirection)
     377       14402 :             ((const SvxFrameDirectionItem&)rStyleSet.Get( ATTR_WRITINGDIR )).GetValue();
     378             : 
     379       14402 :         if ( eDirection == FRMDIR_HORI_LEFT_TOP )
     380       14342 :             eRet = EE_HTEXTDIR_L2R;
     381          60 :         else if ( eDirection == FRMDIR_HORI_RIGHT_TOP )
     382           0 :             eRet = EE_HTEXTDIR_R2L;
     383             :         // else (invalid for EditEngine): keep "default"
     384             :     }
     385             : 
     386       14402 :     return sal::static_int_cast<sal_uInt8>(eRet);
     387             : }
     388             : 
     389           1 : ScMacroManager* ScDocument::GetMacroManager()
     390             : {
     391           1 :     if (!mpMacroMgr.get())
     392           1 :         mpMacroMgr.reset(new ScMacroManager(this));
     393           1 :     return mpMacroMgr.get();
     394             : }
     395             : 
     396          46 : void ScDocument::FillMatrix(
     397             :     ScMatrix& rMat, SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const
     398             : {
     399          46 :     const ScTable* pTab = FetchTable(nTab);
     400          46 :     if (!pTab)
     401           0 :         return;
     402             : 
     403          46 :     if (nCol1 > nCol2 || nRow1 > nRow2)
     404           0 :         return;
     405             : 
     406             :     SCSIZE nC, nR;
     407          46 :     rMat.GetDimensions(nC, nR);
     408          46 :     if (static_cast<SCROW>(nR) != nRow2 - nRow1 + 1 || static_cast<SCCOL>(nC) != nCol2 - nCol1 + 1)
     409           0 :         return;
     410             : 
     411          46 :     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       10639 : void ScDocument::InvalidateTextWidth( const ScAddress* pAdrFrom, const ScAddress* pAdrTo,
     434             :                                       bool bNumFormatChanged )
     435             : {
     436       10639 :     bool bBroadcast = (bNumFormatChanged && GetDocOptions().IsCalcAsShown() && !IsImportingXML() && !IsClipboard());
     437       10639 :     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       10639 :         const SCTAB nTabStart = pAdrFrom ? pAdrFrom->Tab() : 0;
     447       10639 :         const SCTAB nTabEnd   = pAdrTo   ? pAdrTo->Tab()   : MAXTAB;
     448             : 
     449       21278 :         for ( SCTAB nTab=nTabStart; nTab<=nTabEnd && nTab < static_cast<SCTAB>(maTabs.size()); nTab++ )
     450       10639 :             if ( maTabs[nTab] )
     451       10639 :                 maTabs[nTab]->InvalidateTextWidth( pAdrFrom, pAdrTo, bNumFormatChanged, bBroadcast );
     452             :     }
     453       10639 : }
     454             : 
     455             : #define CALCMAX                 1000    // Berechnungen
     456             : #define ABORT_EVENTS            (VCL_INPUT_ANY & ~VCL_INPUT_TIMER & ~VCL_INPUT_OTHER)
     457             : 
     458             : namespace {
     459             : 
     460             : class IdleCalcTextWidthScope
     461             : {
     462             :     ScDocument& mrDoc;
     463             :     ScAddress& mrCalcPos;
     464             :     MapMode maOldMapMode;
     465             :     sal_uLong mnStartTime;
     466             :     ScStyleSheetPool* mpStylePool;
     467             :     sal_uInt16 mnOldSearchMask;
     468             :     SfxStyleFamily meOldFamily;
     469             :     bool mbNeedMore;
     470             :     bool mbProgress;
     471             : 
     472             : public:
     473         335 :     IdleCalcTextWidthScope(ScDocument& rDoc, ScAddress& rCalcPos) :
     474             :         mrDoc(rDoc),
     475             :         mrCalcPos(rCalcPos),
     476         335 :         mnStartTime(Time::GetSystemTicks()),
     477         335 :         mpStylePool(rDoc.GetStyleSheetPool()),
     478         335 :         mnOldSearchMask(mpStylePool->GetSearchMask()),
     479         335 :         meOldFamily(mpStylePool->GetSearchFamily()),
     480             :         mbNeedMore(false),
     481        1675 :         mbProgress(false)
     482             :     {
     483             :         // The old search mask / family flags must be restored so that e.g.
     484             :         // the styles dialog shows correct listing when it's opened in-between
     485             :         // the calls.
     486             : 
     487         335 :         mrDoc.EnableIdle(false);
     488         335 :         mpStylePool->SetSearchMask(SFX_STYLE_FAMILY_PAGE, SFXSTYLEBIT_ALL);
     489         335 :     }
     490             : 
     491         335 :     ~IdleCalcTextWidthScope()
     492         335 :     {
     493         335 :         SfxPrinter* pDev = mrDoc.GetPrinter();
     494         335 :         if (pDev)
     495         335 :             pDev->SetMapMode(maOldMapMode);
     496             : 
     497         335 :         if (mbProgress)
     498           0 :             ScProgress::DeleteInterpretProgress();
     499             : 
     500         335 :         mpStylePool->SetSearchMask(meOldFamily, mnOldSearchMask);
     501         335 :         mrDoc.EnableIdle(true);
     502         335 :     }
     503             : 
     504        1063 :     SCTAB Tab() const { return mrCalcPos.Tab(); }
     505         335 :     SCCOL Col() const { return mrCalcPos.Col(); }
     506         335 :     SCROW Row() const { return mrCalcPos.Row(); }
     507             : 
     508         277 :     void setTab(SCTAB nTab) { mrCalcPos.SetTab(nTab); }
     509           0 :     void setCol(SCCOL nCol) { mrCalcPos.SetCol(nCol); }
     510           0 :     void setRow(SCROW nRow) { mrCalcPos.SetRow(nRow); }
     511             : 
     512         335 :     void incTab(SCTAB nInc=1) { mrCalcPos.IncTab(nInc); }
     513           0 :     void incCol(SCCOL nInc=1) { mrCalcPos.IncCol(nInc); }
     514             : 
     515           0 :     void setOldMapMode(const MapMode& rOldMapMode) { maOldMapMode = rOldMapMode; }
     516             : 
     517           0 :     void setNeedMore(bool b) { mbNeedMore = b; }
     518           0 :     bool getNeedMore() const { return mbNeedMore; }
     519             : 
     520           0 :     sal_uLong getStartTime() const { return mnStartTime; }
     521             : 
     522           0 :     void createProgressBar()
     523             :     {
     524           0 :         ScProgress::CreateInterpretProgress(&mrDoc, false);
     525           0 :         mbProgress = true;
     526           0 :     }
     527             : 
     528           0 :     bool hasProgressBar() const { return mbProgress; }
     529             : 
     530         335 :     ScStyleSheetPool* getStylePool() { return mpStylePool; }
     531             : };
     532             : 
     533             : }
     534             : 
     535        1785 : bool ScDocument::IdleCalcTextWidth()            // true = demnaechst wieder versuchen
     536             : {
     537             :     // #i75610# if a printer hasn't been set or created yet, don't create one for this
     538        1785 :     if (!mbIdleEnabled || IsInLinkUpdate() || GetPrinter(false) == NULL)
     539        1450 :         return false;
     540             : 
     541         335 :     IdleCalcTextWidthScope aScope(*this, aCurTextWidthCalcPos);
     542             : 
     543         335 :     if (!ValidRow(aScope.Row()))
     544             :     {
     545           0 :         aScope.setRow(0);
     546           0 :         aScope.incCol(-1);
     547             :     }
     548             : 
     549         335 :     if (aScope.Col() < 0)
     550             :     {
     551           0 :         aScope.setCol(MAXCOL);
     552           0 :         aScope.incTab();
     553             :     }
     554             : 
     555         335 :     if (!ValidTab(aScope.Tab()) || aScope.Tab() >= static_cast<SCTAB>(maTabs.size()) || !maTabs[aScope.Tab()])
     556         277 :         aScope.setTab(0);
     557             : 
     558         335 :     ScTable* pTab = maTabs[aScope.Tab()];
     559         335 :     ScStyleSheet* pStyle = (ScStyleSheet*)aScope.getStylePool()->Find(pTab->aPageStyle, SFX_STYLE_FAMILY_PAGE);
     560             :     OSL_ENSURE( pStyle, "Missing StyleSheet :-/" );
     561             : 
     562         335 :     if (!pStyle || getScaleValue(*pStyle, ATTR_PAGE_SCALETOPAGES) == 0)
     563             :     {
     564             :         // Move to the next sheet as the current one has scale-to-pages set,
     565             :         // and bail out.
     566         335 :         aScope.incTab();
     567         335 :         return false;
     568             :     }
     569             : 
     570           0 :     sal_uInt16 nZoom = getScaleValue(*pStyle, ATTR_PAGE_SCALE);
     571           0 :     Fraction aZoomFract(nZoom, 100);
     572             : 
     573             :     // Start at specified cell position (nCol, nRow, nTab).
     574           0 :     ScColumn* pCol  = &pTab->aCol[aScope.Col()];
     575           0 :     boost::scoped_ptr<ScColumnTextWidthIterator> pColIter(new ScColumnTextWidthIterator(*pCol, aScope.Row(), MAXROW));
     576             : 
     577           0 :     OutputDevice* pDev = NULL;
     578           0 :     sal_uInt16 nRestart = 0;
     579           0 :     sal_uInt16 nCount = 0;
     580           0 :     while ( (nZoom > 0) && (nCount < CALCMAX) && (nRestart < 2) )
     581             :     {
     582           0 :         if (pColIter->hasCell())
     583             :         {
     584             :             // More cell in this column.
     585           0 :             SCROW nRow = pColIter->getPos();
     586           0 :             aScope.setRow(nRow);
     587             : 
     588           0 :             if (pColIter->getValue() == TEXTWIDTH_DIRTY)
     589             :             {
     590             :                 // Calculate text width for this cell.
     591           0 :                 double nPPTX = 0.0;
     592           0 :                 double nPPTY = 0.0;
     593           0 :                 if (!pDev)
     594             :                 {
     595           0 :                     pDev = GetPrinter();
     596           0 :                     aScope.setOldMapMode(pDev->GetMapMode());
     597           0 :                     pDev->SetMapMode( MAP_PIXEL );  // wichtig fuer GetNeededSize
     598             : 
     599           0 :                     Point aPix1000 = pDev->LogicToPixel( Point(1000,1000), MAP_TWIP );
     600           0 :                     nPPTX = aPix1000.X() / 1000.0;
     601           0 :                     nPPTY = aPix1000.Y() / 1000.0;
     602             :                 }
     603             : 
     604           0 :                 if (!aScope.hasProgressBar() && pCol->IsFormulaDirty(nRow))
     605           0 :                     aScope.createProgressBar();
     606             : 
     607             :                 sal_uInt16 nNewWidth = (sal_uInt16)GetNeededSize(
     608           0 :                     aScope.Col(), aScope.Row(), aScope.Tab(),
     609           0 :                     pDev, nPPTX, nPPTY, aZoomFract,aZoomFract, true, true);   // bTotalSize
     610             : 
     611           0 :                 pColIter->setValue(nNewWidth);
     612           0 :                 aScope.setNeedMore(true);
     613             :             }
     614           0 :             pColIter->next();
     615             :         }
     616             :         else
     617             :         {
     618             :             // No more cell in this column.  Move to the left column and start at row 0.
     619             : 
     620           0 :             bool bNewTab = false;
     621             : 
     622           0 :             aScope.setRow(0);
     623           0 :             aScope.incCol(-1);
     624             : 
     625           0 :             if (aScope.Col() < 0)
     626             :             {
     627             :                 // No more column to the left.  Move to the right-most column of the next sheet.
     628           0 :                 aScope.setCol(MAXCOL);
     629           0 :                 aScope.incTab();
     630           0 :                 bNewTab = true;
     631             :             }
     632             : 
     633           0 :             if (!ValidTab(aScope.Tab()) || aScope.Tab() >= static_cast<SCTAB>(maTabs.size()) || !maTabs[aScope.Tab()] )
     634             :             {
     635             :                 // Sheet doesn't exist at specified sheet position.  Restart at sheet 0.
     636           0 :                 aScope.setTab(0);
     637           0 :                 nRestart++;
     638           0 :                 bNewTab = true;
     639             :             }
     640             : 
     641           0 :             if ( nRestart < 2 )
     642             :             {
     643           0 :                 if ( bNewTab )
     644             :                 {
     645           0 :                     pTab = maTabs[aScope.Tab()];
     646           0 :                     pStyle = (ScStyleSheet*)aScope.getStylePool()->Find(
     647           0 :                         pTab->aPageStyle, SFX_STYLE_FAMILY_PAGE);
     648             : 
     649           0 :                     if ( pStyle )
     650             :                     {
     651             :                         // Check if the scale-to-pages setting is set. If
     652             :                         // set, we exit the loop.  If not, get the page
     653             :                         // scale factor of the new sheet.
     654           0 :                         if (getScaleValue(*pStyle, ATTR_PAGE_SCALETOPAGES) == 0)
     655             :                         {
     656           0 :                             nZoom = getScaleValue(*pStyle, ATTR_PAGE_SCALE);
     657           0 :                             aZoomFract = Fraction(nZoom, 100);
     658             :                         }
     659             :                         else
     660           0 :                             nZoom = 0;
     661             :                     }
     662             :                     else
     663             :                     {
     664             :                         OSL_FAIL( "Missing StyleSheet :-/" );
     665             :                     }
     666             :                 }
     667             : 
     668           0 :                 if ( nZoom > 0 )
     669             :                 {
     670           0 :                     pCol  = &pTab->aCol[aScope.Col()];
     671           0 :                     pColIter.reset(new ScColumnTextWidthIterator(*pCol, aScope.Row(), MAXROW));
     672             :                 }
     673             :                 else
     674             :                 {
     675           0 :                     aScope.incTab(); // Move to the next sheet as the current one has scale-to-pages set.
     676           0 :                     return false;
     677             :                 }
     678             :             }
     679             :         }
     680             : 
     681           0 :         ++nCount;
     682             : 
     683             :         // Quit if either 1) its duration exceeds 50 ms, or 2) there is any
     684             :         // pending event after processing 32 cells.
     685           0 :         if ((50L < Time::GetSystemTicks() - aScope.getStartTime()) || (nCount > 31 && Application::AnyInput(ABORT_EVENTS)))
     686           0 :             nCount = CALCMAX;
     687             :     }
     688             : 
     689         335 :     return aScope.getNeedMore();
     690             : }
     691             : 
     692        4649 : void ScDocument::RepaintRange( const ScRange& rRange )
     693             : {
     694        4649 :     if ( bIsVisible && pShell )
     695             :     {
     696         159 :         ScModelObj* pModel = ScModelObj::getImplementation( pShell->GetModel() );
     697         159 :         if ( pModel )
     698         159 :             pModel->RepaintRange( rRange );     // locked repaints are checked there
     699             :     }
     700        4649 : }
     701             : 
     702           0 : void ScDocument::RepaintRange( const ScRangeList& rRange )
     703             : {
     704           0 :     if ( bIsVisible && pShell )
     705             :     {
     706           0 :         ScModelObj* pModel = ScModelObj::getImplementation( pShell->GetModel() );
     707           0 :         if ( pModel )
     708           0 :             pModel->RepaintRange( rRange );     // locked repaints are checked there
     709             :     }
     710           0 : }
     711             : 
     712           0 : void ScDocument::SaveDdeLinks(SvStream& rStream) const
     713             : {
     714             :     //  bei 4.0-Export alle mit Modus != DEFAULT weglassen
     715           0 :     bool bExport40 = ( rStream.GetVersion() <= SOFFICE_FILEFORMAT_40 );
     716             : 
     717           0 :     const ::sfx2::SvBaseLinks& rLinks = GetLinkManager()->GetLinks();
     718           0 :     sal_uInt16 nCount = rLinks.size();
     719             : 
     720             :     //  erstmal zaehlen...
     721             : 
     722           0 :     sal_uInt16 nDdeCount = 0;
     723             :     sal_uInt16 i;
     724           0 :     for (i=0; i<nCount; i++)
     725             :     {
     726           0 :         ::sfx2::SvBaseLink* pBase = *rLinks[i];
     727           0 :         if (pBase->ISA(ScDdeLink))
     728           0 :             if ( !bExport40 || ((ScDdeLink*)pBase)->GetMode() == SC_DDE_DEFAULT )
     729           0 :                 ++nDdeCount;
     730             :     }
     731             : 
     732             :     //  Header
     733             : 
     734           0 :     ScMultipleWriteHeader aHdr( rStream );
     735           0 :     rStream.WriteUInt16( nDdeCount );
     736             : 
     737             :     //  Links speichern
     738             : 
     739           0 :     for (i=0; i<nCount; i++)
     740             :     {
     741           0 :         ::sfx2::SvBaseLink* pBase = *rLinks[i];
     742           0 :         if (pBase->ISA(ScDdeLink))
     743             :         {
     744           0 :             ScDdeLink* pLink = (ScDdeLink*)pBase;
     745           0 :             if ( !bExport40 || pLink->GetMode() == SC_DDE_DEFAULT )
     746           0 :                 pLink->Store( rStream, aHdr );
     747             :         }
     748           0 :     }
     749           0 : }
     750             : 
     751           0 : void ScDocument::LoadDdeLinks(SvStream& rStream)
     752             : {
     753           0 :     sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(bAutoCalc);
     754           0 :     if (!pMgr)
     755           0 :         return;
     756             : 
     757           0 :     ScMultipleReadHeader aHdr( rStream );
     758             : 
     759             :     sal_uInt16 nCount;
     760           0 :     rStream.ReadUInt16( nCount );
     761           0 :     for (sal_uInt16 i=0; i<nCount; i++)
     762             :     {
     763           0 :         ScDdeLink* pLink = new ScDdeLink( this, rStream, aHdr );
     764           0 :         pMgr->InsertDDELink(pLink, pLink->GetAppl(), pLink->GetTopic(), pLink->GetItem());
     765           0 :     }
     766             : }
     767             : 
     768          12 : void ScDocument::SetInLinkUpdate(bool bSet)
     769             : {
     770             :     //  called from TableLink and AreaLink
     771             : 
     772             :     OSL_ENSURE( bInLinkUpdate != bSet, "SetInLinkUpdate twice" );
     773          12 :     bInLinkUpdate = bSet;
     774          12 : }
     775             : 
     776        1772 : bool ScDocument::IsInLinkUpdate() const
     777             : {
     778        1772 :     return bInLinkUpdate || IsInDdeLinkUpdate();
     779             : }
     780             : 
     781           0 : void ScDocument::UpdateExternalRefLinks(Window* pWin)
     782             : {
     783           0 :     sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(bAutoCalc);
     784           0 :     if (!pMgr)
     785           0 :         return;
     786             : 
     787           0 :     const ::sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
     788           0 :     sal_uInt16 nCount = rLinks.size();
     789             : 
     790           0 :     bool bAny = false;
     791           0 :     for (sal_uInt16 i = 0; i < nCount; ++i)
     792             :     {
     793           0 :         ::sfx2::SvBaseLink* pBase = *rLinks[i];
     794           0 :         ScExternalRefLink* pRefLink = dynamic_cast<ScExternalRefLink*>(pBase);
     795           0 :         if (pRefLink)
     796             :         {
     797           0 :             if (pRefLink->Update())
     798           0 :                 bAny = true;
     799             :             else
     800             :             {
     801             :                 // Update failed.  Notify the user.
     802             : 
     803           0 :                 OUString aFile;
     804           0 :                 pMgr->GetDisplayNames(pRefLink, NULL, &aFile, NULL, NULL);
     805             :                 // Decode encoded URL for display friendliness.
     806           0 :                 INetURLObject aUrl(aFile,INetURLObject::WAS_ENCODED);
     807           0 :                 aFile = aUrl.GetMainURL(INetURLObject::DECODE_UNAMBIGUOUS);
     808             : 
     809           0 :                 OUStringBuffer aBuf;
     810           0 :                 aBuf.append(OUString(ScResId(SCSTR_EXTDOC_NOT_LOADED)));
     811           0 :                 aBuf.appendAscii("\n\n");
     812           0 :                 aBuf.append(aFile);
     813           0 :                 ErrorBox aBox(pWin, WB_OK, aBuf.makeStringAndClear());
     814           0 :                 aBox.Execute();
     815             :             }
     816             :         }
     817             :     }
     818           0 :     if (bAny)
     819             :     {
     820           0 :         TrackFormulas();
     821           0 :         pShell->Broadcast( SfxSimpleHint(FID_DATACHANGED) );
     822             : 
     823             :         // #i101960# set document modified, as in TrackTimeHdl for DDE links
     824           0 :         if (!pShell->IsModified())
     825             :         {
     826           0 :             pShell->SetModified( true );
     827           0 :             SfxBindings* pBindings = GetViewBindings();
     828           0 :             if (pBindings)
     829             :             {
     830           0 :                 pBindings->Invalidate( SID_SAVEDOC );
     831           0 :                 pBindings->Invalidate( SID_DOC_MODIFIED );
     832             :             }
     833             :         }
     834             :     }
     835             : }
     836             : 
     837           0 : void ScDocument::CopyDdeLinks( ScDocument* pDestDoc ) const
     838             : {
     839           0 :     if (bIsClip)        // aus Stream erzeugen
     840             :     {
     841           0 :         if (pClipData)
     842             :         {
     843           0 :             pClipData->Seek(0);
     844           0 :             pDestDoc->LoadDdeLinks(*pClipData);
     845             :         }
     846             : 
     847           0 :         return;
     848             :     }
     849             : 
     850           0 :     const sfx2::LinkManager* pMgr = GetDocLinkManager().getExistingLinkManager();
     851           0 :     if (!pMgr)
     852           0 :         return;
     853             : 
     854           0 :     sfx2::LinkManager* pDestMgr = pDestDoc->GetDocLinkManager().getLinkManager(pDestDoc->bAutoCalc);
     855           0 :     if (!pDestMgr)
     856           0 :         return;
     857             : 
     858           0 :     const sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
     859           0 :     for (size_t i = 0, n = rLinks.size(); i < n; ++i)
     860             :     {
     861           0 :         const sfx2::SvBaseLink* pBase = *rLinks[i];
     862           0 :         if (pBase->ISA(ScDdeLink))
     863             :         {
     864           0 :             const ScDdeLink* p = static_cast<const ScDdeLink*>(pBase);
     865           0 :             ScDdeLink* pNew = new ScDdeLink(pDestDoc, *p);
     866             :             pDestMgr->InsertDDELink(
     867           0 :                 pNew, pNew->GetAppl(), pNew->GetTopic(), pNew->GetItem());
     868             :         }
     869             :     }
     870             : }
     871             : 
     872             : namespace {
     873             : 
     874             : /** Tries to find the specified DDE link.
     875             :     @param pnDdePos  (out-param) if not 0, the index of the DDE link is returned here
     876             :                      (does not include other links from link manager).
     877             :     @return  The DDE link, if it exists, otherwise 0. */
     878           0 : ScDdeLink* lclGetDdeLink(
     879             :         const sfx2::LinkManager* pLinkManager,
     880             :         const OUString& rAppl, const OUString& rTopic, const OUString& rItem, sal_uInt8 nMode,
     881             :         size_t* pnDdePos = NULL )
     882             : {
     883           0 :     if( pLinkManager )
     884             :     {
     885           0 :         const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
     886           0 :         size_t nCount = rLinks.size();
     887           0 :         if( pnDdePos ) *pnDdePos = 0;
     888           0 :         for( size_t nIndex = 0; nIndex < nCount; ++nIndex )
     889             :         {
     890           0 :             ::sfx2::SvBaseLink* pLink = *rLinks[ nIndex ];
     891           0 :             if( ScDdeLink* pDdeLink = PTR_CAST( ScDdeLink, pLink ) )
     892             :             {
     893           0 :                 if( (OUString(pDdeLink->GetAppl()) == rAppl) &&
     894           0 :                     (OUString(pDdeLink->GetTopic()) == rTopic) &&
     895           0 :                     (OUString(pDdeLink->GetItem()) == rItem) &&
     896           0 :                     ((nMode == SC_DDE_IGNOREMODE) || (nMode == pDdeLink->GetMode())) )
     897           0 :                     return pDdeLink;
     898           0 :                 if( pnDdePos ) ++*pnDdePos;
     899             :             }
     900             :         }
     901             :     }
     902           0 :     return NULL;
     903             : }
     904             : 
     905             : /** Returns a pointer to the specified DDE link.
     906             :     @param nDdePos  Index of the DDE link (does not include other links from link manager).
     907             :     @return  The DDE link, if it exists, otherwise 0. */
     908          13 : ScDdeLink* lclGetDdeLink( const sfx2::LinkManager* pLinkManager, size_t nDdePos )
     909             : {
     910          13 :     if( pLinkManager )
     911             :     {
     912          13 :         const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
     913          13 :         size_t nCount = rLinks.size();
     914          13 :         size_t nDdeIndex = 0;       // counts only the DDE links
     915          15 :         for( size_t nIndex = 0; nIndex < nCount; ++nIndex )
     916             :         {
     917          13 :             ::sfx2::SvBaseLink* pLink = *rLinks[ nIndex ];
     918          13 :             if( ScDdeLink* pDdeLink = PTR_CAST( ScDdeLink, pLink ) )
     919             :             {
     920          13 :                 if( nDdeIndex == nDdePos )
     921          11 :                     return pDdeLink;
     922           2 :                 ++nDdeIndex;
     923             :             }
     924             :         }
     925             :     }
     926           2 :     return NULL;
     927             : }
     928             : 
     929             : } // namespace
     930             : 
     931           0 : bool ScDocument::FindDdeLink( const OUString& rAppl, const OUString& rTopic, const OUString& rItem,
     932             :         sal_uInt8 nMode, size_t& rnDdePos )
     933             : {
     934           0 :     return lclGetDdeLink( GetLinkManager(), rAppl, rTopic, rItem, nMode, &rnDdePos ) != NULL;
     935             : }
     936             : 
     937          13 : bool ScDocument::GetDdeLinkData( size_t nDdePos, OUString& rAppl, OUString& rTopic, OUString& rItem ) const
     938             : {
     939          13 :     if( const ScDdeLink* pDdeLink = lclGetDdeLink( GetLinkManager(), nDdePos ) )
     940             :     {
     941          11 :         rAppl  = pDdeLink->GetAppl();
     942          11 :         rTopic = pDdeLink->GetTopic();
     943          11 :         rItem  = pDdeLink->GetItem();
     944          11 :         return true;
     945             :     }
     946           2 :     return false;
     947             : }
     948             : 
     949           0 : bool ScDocument::GetDdeLinkMode( size_t nDdePos, sal_uInt8& rnMode ) const
     950             : {
     951           0 :     if( const ScDdeLink* pDdeLink = lclGetDdeLink( GetLinkManager(), nDdePos ) )
     952             :     {
     953           0 :         rnMode = pDdeLink->GetMode();
     954           0 :         return true;
     955             :     }
     956           0 :     return false;
     957             : }
     958             : 
     959           0 : const ScMatrix* ScDocument::GetDdeLinkResultMatrix( size_t nDdePos ) const
     960             : {
     961           0 :     const ScDdeLink* pDdeLink = lclGetDdeLink( GetLinkManager(), nDdePos );
     962           0 :     return pDdeLink ? pDdeLink->GetResult() : NULL;
     963             : }
     964             : 
     965           0 : bool ScDocument::CreateDdeLink( const OUString& rAppl, const OUString& rTopic, const OUString& rItem, sal_uInt8 nMode, ScMatrixRef pResults )
     966             : {
     967             :     /*  Create a DDE link without updating it (i.e. for Excel import), to prevent
     968             :         unwanted connections. First try to find existing link. Set result array
     969             :         on existing and new links. */
     970             :     //! store DDE links additionally at document (for efficiency)?
     971             :     OSL_ENSURE( nMode != SC_DDE_IGNOREMODE, "ScDocument::CreateDdeLink - SC_DDE_IGNOREMODE not allowed here" );
     972             : 
     973           0 :     sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(bAutoCalc);
     974           0 :     if (!pMgr)
     975           0 :         return false;
     976             : 
     977           0 :     if (nMode != SC_DDE_IGNOREMODE)
     978             :     {
     979           0 :         ScDdeLink* pDdeLink = lclGetDdeLink(pMgr, rAppl, rTopic, rItem, nMode);
     980           0 :         if( !pDdeLink )
     981             :         {
     982             :             // create a new DDE link, but without TryUpdate
     983           0 :             pDdeLink = new ScDdeLink( this, rAppl, rTopic, rItem, nMode );
     984           0 :             pMgr->InsertDDELink(pDdeLink, rAppl, rTopic, rItem);
     985             :         }
     986             : 
     987             :         // insert link results
     988           0 :         if( pResults )
     989           0 :             pDdeLink->SetResult( pResults );
     990             : 
     991           0 :         return true;
     992             :     }
     993           0 :     return false;
     994             : }
     995             : 
     996           0 : bool ScDocument::SetDdeLinkResultMatrix( size_t nDdePos, ScMatrixRef pResults )
     997             : {
     998           0 :     if( ScDdeLink* pDdeLink = lclGetDdeLink( GetLinkManager(), nDdePos ) )
     999             :     {
    1000           0 :         pDdeLink->SetResult( pResults );
    1001           0 :         return true;
    1002             :     }
    1003           0 :     return false;
    1004             : }
    1005             : 
    1006         221 : bool ScDocument::HasAreaLinks() const
    1007             : {
    1008         221 :     const sfx2::LinkManager* pMgr = GetDocLinkManager().getExistingLinkManager();
    1009         221 :     if (!pMgr)
    1010         153 :         return false;
    1011             : 
    1012          68 :     const ::sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
    1013          68 :     sal_uInt16 nCount = rLinks.size();
    1014          68 :     for (sal_uInt16 i=0; i<nCount; i++)
    1015           0 :         if ((*rLinks[i])->ISA(ScAreaLink))
    1016           0 :             return true;
    1017             : 
    1018          68 :     return false;
    1019             : }
    1020             : 
    1021           0 : void ScDocument::UpdateAreaLinks()
    1022             : {
    1023           0 :     sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(false);
    1024           0 :     if (!pMgr)
    1025           0 :         return;
    1026             : 
    1027           0 :     const ::sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
    1028           0 :     for (sal_uInt16 i=0; i<rLinks.size(); i++)
    1029             :     {
    1030           0 :         ::sfx2::SvBaseLink* pBase = *rLinks[i];
    1031           0 :         if (pBase->ISA(ScAreaLink))
    1032           0 :             pBase->Update();
    1033             :     }
    1034             : }
    1035             : 
    1036          81 : void ScDocument::DeleteAreaLinksOnTab( SCTAB nTab )
    1037             : {
    1038          81 :     sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(false);
    1039          81 :     if (!pMgr)
    1040         137 :         return;
    1041             : 
    1042          25 :     const ::sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
    1043          25 :     sal_uInt16 nPos = 0;
    1044          50 :     while ( nPos < rLinks.size() )
    1045             :     {
    1046           0 :         const ::sfx2::SvBaseLink* pBase = *rLinks[nPos];
    1047           0 :         if ( pBase->ISA(ScAreaLink) &&
    1048           0 :              static_cast<const ScAreaLink*>(pBase)->GetDestArea().aStart.Tab() == nTab )
    1049           0 :             pMgr->Remove(nPos);
    1050             :         else
    1051           0 :             ++nPos;
    1052             :     }
    1053             : }
    1054             : 
    1055         269 : void ScDocument::UpdateRefAreaLinks( UpdateRefMode eUpdateRefMode,
    1056             :                              const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
    1057             : {
    1058         269 :     sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(false);
    1059         269 :     if (!pMgr)
    1060         441 :         return;
    1061             : 
    1062          97 :     bool bAnyUpdate = false;
    1063             : 
    1064          97 :     const ::sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
    1065          97 :     sal_uInt16 nCount = rLinks.size();
    1066         100 :     for (sal_uInt16 i=0; i<nCount; i++)
    1067             :     {
    1068           3 :         ::sfx2::SvBaseLink* pBase = *rLinks[i];
    1069           3 :         if (pBase->ISA(ScAreaLink))
    1070             :         {
    1071           0 :             ScAreaLink* pLink = (ScAreaLink*) pBase;
    1072           0 :             ScRange aOutRange = pLink->GetDestArea();
    1073             : 
    1074           0 :             SCCOL nCol1 = aOutRange.aStart.Col();
    1075           0 :             SCROW nRow1 = aOutRange.aStart.Row();
    1076           0 :             SCTAB nTab1 = aOutRange.aStart.Tab();
    1077           0 :             SCCOL nCol2 = aOutRange.aEnd.Col();
    1078           0 :             SCROW nRow2 = aOutRange.aEnd.Row();
    1079           0 :             SCTAB nTab2 = aOutRange.aEnd.Tab();
    1080             : 
    1081             :             ScRefUpdateRes eRes =
    1082             :                 ScRefUpdate::Update( this, eUpdateRefMode,
    1083           0 :                     rRange.aStart.Col(), rRange.aStart.Row(), rRange.aStart.Tab(),
    1084           0 :                     rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aEnd.Tab(), nDx, nDy, nDz,
    1085           0 :                     nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
    1086           0 :             if ( eRes != UR_NOTHING )
    1087             :             {
    1088           0 :                 pLink->SetDestArea( ScRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ) );
    1089           0 :                 bAnyUpdate = true;
    1090             :             }
    1091             :         }
    1092             :     }
    1093             : 
    1094          97 :     if ( bAnyUpdate )
    1095             :     {
    1096             :         // #i52120# Look for duplicates (after updating all positions).
    1097             :         // If several links start at the same cell, the one with the lower index is removed
    1098             :         // (file format specifies only one link definition for a cell).
    1099             : 
    1100           0 :         sal_uInt16 nFirstIndex = 0;
    1101           0 :         while ( nFirstIndex < nCount )
    1102             :         {
    1103           0 :             bool bFound = false;
    1104           0 :             ::sfx2::SvBaseLink* pFirst = *rLinks[nFirstIndex];
    1105           0 :             if ( pFirst->ISA(ScAreaLink) )
    1106             :             {
    1107           0 :                 ScAddress aFirstPos = static_cast<ScAreaLink*>(pFirst)->GetDestArea().aStart;
    1108           0 :                 for ( sal_uInt16 nSecondIndex = nFirstIndex + 1; nSecondIndex < nCount && !bFound; ++nSecondIndex )
    1109             :                 {
    1110           0 :                     ::sfx2::SvBaseLink* pSecond = *rLinks[nSecondIndex];
    1111           0 :                     if ( pSecond->ISA(ScAreaLink) &&
    1112           0 :                          static_cast<ScAreaLink*>(pSecond)->GetDestArea().aStart == aFirstPos )
    1113             :                     {
    1114             :                         // remove the first link, exit the inner loop, don't increment nFirstIndex
    1115           0 :                         pMgr->Remove(pFirst);
    1116           0 :                         nCount = rLinks.size();
    1117           0 :                         bFound = true;
    1118             :                     }
    1119             :                 }
    1120             :             }
    1121           0 :             if (!bFound)
    1122           0 :                 ++nFirstIndex;
    1123             :         }
    1124             :     }
    1125             : }
    1126             : 
    1127             : // TimerDelays etc.
    1128           0 : void ScDocument::KeyInput( const KeyEvent& )
    1129             : {
    1130           0 :     if ( pChartListenerCollection->hasListeners() )
    1131           0 :         pChartListenerCollection->StartTimer();
    1132           0 :     if( apTemporaryChartLock.get() )
    1133           0 :         apTemporaryChartLock->StartOrContinueLocking();
    1134           0 : }
    1135             : 
    1136           0 : bool ScDocument::CheckMacroWarn()
    1137             : {
    1138             :     //  The check for macro configuration, macro warning and disabling is now handled
    1139             :     //  in SfxObjectShell::AdjustMacroMode, called by SfxObjectShell::CallBasic.
    1140             : 
    1141           0 :     return true;
    1142             : }
    1143             : 
    1144           6 : SfxBindings* ScDocument::GetViewBindings()
    1145             : {
    1146             :     //  used to invalidate slots after changes to this document
    1147             : 
    1148           6 :     if ( !pShell )
    1149           0 :         return NULL;        // no ObjShell -> no view
    1150             : 
    1151             :     //  first check current view
    1152           6 :     SfxViewFrame* pViewFrame = SfxViewFrame::Current();
    1153           6 :     if ( pViewFrame && pViewFrame->GetObjectShell() != pShell )     // wrong document?
    1154           6 :         pViewFrame = NULL;
    1155             : 
    1156             :     //  otherwise use first view for this doc
    1157           6 :     if ( !pViewFrame )
    1158           6 :         pViewFrame = SfxViewFrame::GetFirst( pShell );
    1159             : 
    1160           6 :     if (pViewFrame)
    1161           3 :         return &pViewFrame->GetBindings();
    1162             :     else
    1163           3 :         return NULL;
    1164             : }
    1165             : 
    1166       18252 : ScDrawLayer* ScDocument::GetDrawLayer()
    1167             : {
    1168       18252 :     return pDrawLayer;
    1169             : }
    1170             : 
    1171           2 : void ScDocument::TransliterateText( const ScMarkData& rMultiMark, sal_Int32 nType )
    1172             : {
    1173             :     OSL_ENSURE( rMultiMark.IsMultiMarked(), "TransliterateText: no selection" );
    1174             : 
    1175           2 :     utl::TransliterationWrapper aTranslitarationWrapper( comphelper::getProcessComponentContext(), nType );
    1176           2 :     bool bConsiderLanguage = aTranslitarationWrapper.needLanguageForTheMode();
    1177           2 :     sal_uInt16 nLanguage = LANGUAGE_SYSTEM;
    1178             : 
    1179           2 :     ScEditEngineDefaulter* pEngine = NULL;        // not using pEditEngine member because of defaults
    1180             : 
    1181           2 :     SCTAB nCount = GetTableCount();
    1182           2 :     ScMarkData::const_iterator itr = rMultiMark.begin(), itrEnd = rMultiMark.end();
    1183           4 :     for (; itr != itrEnd && *itr < nCount; ++itr)
    1184           2 :         if ( maTabs[*itr] )
    1185             :         {
    1186           2 :             SCTAB nTab = *itr;
    1187           2 :             SCCOL nCol = 0;
    1188           2 :             SCROW nRow = 0;
    1189             : 
    1190           2 :             bool bFound = rMultiMark.IsCellMarked( nCol, nRow );
    1191           2 :             if (!bFound)
    1192           0 :                 bFound = GetNextMarkedCell( nCol, nRow, nTab, rMultiMark );
    1193             : 
    1194          10 :             while (bFound)
    1195             :             {
    1196           6 :                 ScRefCellValue aCell;
    1197           6 :                 aCell.assign(*this, ScAddress(nCol, nRow, nTab));
    1198             : 
    1199             :                 // fdo#32786 TITLE_CASE/SENTENCE_CASE need the extra handling in EditEngine (loop over words/sentences).
    1200             :                 // Still use TransliterationWrapper directly for text cells with other transliteration types,
    1201             :                 // for performance reasons.
    1202          12 :                 if (aCell.meType == CELLTYPE_EDIT ||
    1203          12 :                     (aCell.meType == CELLTYPE_STRING &&
    1204           6 :                      ( nType == i18n::TransliterationModulesExtra::SENTENCE_CASE || nType == i18n::TransliterationModulesExtra::TITLE_CASE)))
    1205             :                 {
    1206           0 :                     if (!pEngine)
    1207           0 :                         pEngine = new ScFieldEditEngine(this, GetEnginePool(), GetEditPool());
    1208             : 
    1209             :                     // defaults from cell attributes must be set so right language is used
    1210           0 :                     const ScPatternAttr* pPattern = GetPattern( nCol, nRow, nTab );
    1211           0 :                     SfxItemSet* pDefaults = new SfxItemSet( pEngine->GetEmptyItemSet() );
    1212           0 :                     if ( ScStyleSheet* pPreviewStyle = GetPreviewCellStyle( nCol, nRow, nTab ) )
    1213             :                     {
    1214           0 :                         ScPatternAttr* pPreviewPattern = new ScPatternAttr( *pPattern );
    1215           0 :                         pPreviewPattern->SetStyleSheet(pPreviewStyle);
    1216           0 :                         pPreviewPattern->FillEditItemSet( pDefaults );
    1217           0 :                         delete pPreviewPattern;
    1218             :                     }
    1219             :                     else
    1220             :                     {
    1221           0 :                         SfxItemSet* pFontSet = GetPreviewFont( nCol, nRow, nTab );
    1222           0 :                         pPattern->FillEditItemSet( pDefaults, pFontSet );
    1223             :                     }
    1224           0 :                     pEngine->SetDefaults( pDefaults,  true );
    1225           0 :                     if (aCell.meType == CELLTYPE_STRING)
    1226           0 :                         pEngine->SetText(aCell.mpString->getString());
    1227           0 :                     else if (aCell.mpEditText)
    1228           0 :                         pEngine->SetText(*aCell.mpEditText);
    1229             : 
    1230           0 :                     pEngine->ClearModifyFlag();
    1231             : 
    1232           0 :                     sal_Int32 nLastPar = pEngine->GetParagraphCount();
    1233           0 :                     if (nLastPar)
    1234           0 :                         --nLastPar;
    1235           0 :                     sal_Int32 nTxtLen = pEngine->GetTextLen(nLastPar);
    1236           0 :                     ESelection aSelAll( 0, 0, nLastPar, nTxtLen );
    1237             : 
    1238           0 :                     pEngine->TransliterateText( aSelAll, nType );
    1239             : 
    1240           0 :                     if ( pEngine->IsModified() )
    1241             :                     {
    1242           0 :                         ScEditAttrTester aTester( pEngine );
    1243           0 :                         if ( aTester.NeedsObject() )
    1244             :                         {
    1245             :                             // remove defaults (paragraph attributes) before creating text object
    1246           0 :                             SfxItemSet* pEmpty = new SfxItemSet( pEngine->GetEmptyItemSet() );
    1247           0 :                             pEngine->SetDefaults( pEmpty, true );
    1248             : 
    1249             :                             // The cell will take ownership of the text object instance.
    1250           0 :                             SetEditText(ScAddress(nCol,nRow,nTab), pEngine->CreateTextObject());
    1251             :                         }
    1252             :                         else
    1253             :                         {
    1254           0 :                             ScSetStringParam aParam;
    1255           0 :                             aParam.setTextInput();
    1256           0 :                             SetString(ScAddress(nCol,nRow,nTab), pEngine->GetText(), &aParam);
    1257           0 :                         }
    1258           0 :                     }
    1259             :                 }
    1260             : 
    1261           6 :                 else if (aCell.meType == CELLTYPE_STRING)
    1262             :                 {
    1263           6 :                     OUString aOldStr = aCell.mpString->getString();
    1264           6 :                     sal_Int32 nOldLen = aOldStr.getLength();
    1265             : 
    1266           6 :                     if ( bConsiderLanguage )
    1267             :                     {
    1268           6 :                         sal_uInt8 nScript = GetStringScriptType( aOldStr );        //! cell script type?
    1269             :                         sal_uInt16 nWhich = ( nScript == SCRIPTTYPE_ASIAN ) ? ATTR_CJK_FONT_LANGUAGE :
    1270             :                                         ( ( nScript == SCRIPTTYPE_COMPLEX ) ? ATTR_CTL_FONT_LANGUAGE :
    1271           6 :                                                                                 ATTR_FONT_LANGUAGE );
    1272           6 :                         nLanguage = ((const SvxLanguageItem*)GetAttr( nCol, nRow, nTab, nWhich ))->GetValue();
    1273             :                     }
    1274             : 
    1275          12 :                     uno::Sequence<sal_Int32> aOffsets;
    1276          12 :                     OUString aNewStr = aTranslitarationWrapper.transliterate( aOldStr, nLanguage, 0, nOldLen, &aOffsets );
    1277             : 
    1278           6 :                     if ( aNewStr != aOldStr )
    1279             :                     {
    1280           6 :                         ScSetStringParam aParam;
    1281           6 :                         aParam.setTextInput();
    1282           6 :                         SetString(ScAddress(nCol,nRow,nTab), aNewStr, &aParam);
    1283           6 :                     }
    1284             :                 }
    1285           6 :                 bFound = GetNextMarkedCell( nCol, nRow, nTab, rMultiMark );
    1286           6 :             }
    1287             :         }
    1288           2 :     delete pEngine;
    1289         104 : }
    1290             : 
    1291             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10