LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sc/source/core/data - documen8.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 346 826 41.9 %
Date: 2013-07-09 Functions: 43 80 53.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/string.hxx>
      24             : #include <tools/urlobj.hxx>
      25             : #include <editeng/editobj.hxx>
      26             : #include <editeng/editstat.hxx>
      27             : #include <editeng/frmdiritem.hxx>
      28             : #include <editeng/langitem.hxx>
      29             : #include <sfx2/linkmgr.hxx>
      30             : #include <editeng/scripttypeitem.hxx>
      31             : #include <editeng/unolingu.hxx>
      32             : #include <sfx2/bindings.hxx>
      33             : #include <sfx2/objsh.hxx>
      34             : #include <sfx2/printer.hxx>
      35             : #include <sfx2/viewfrm.hxx>
      36             : #include <sfx2/viewsh.hxx>
      37             : #include <svl/flagitem.hxx>
      38             : #include <svl/intitem.hxx>
      39             : #include <svl/zforlist.hxx>
      40             : #include <svl/zformat.hxx>
      41             : #include <unotools/misccfg.hxx>
      42             : #include <sfx2/app.hxx>
      43             : #include <unotools/transliterationwrapper.hxx>
      44             : #include <unotools/securityoptions.hxx>
      45             : 
      46             : #include <vcl/virdev.hxx>
      47             : #include <vcl/msgbox.hxx>
      48             : 
      49             : #include <com/sun/star/i18n/TransliterationModulesExtra.hpp>
      50             : 
      51             : #include "inputopt.hxx"
      52             : #include "global.hxx"
      53             : #include "table.hxx"
      54             : #include "column.hxx"
      55             : #include "poolhelp.hxx"
      56             : #include "docpool.hxx"
      57             : #include "stlpool.hxx"
      58             : #include "stlsheet.hxx"
      59             : #include "docoptio.hxx"
      60             : #include "viewopti.hxx"
      61             : #include "scextopt.hxx"
      62             : #include "rechead.hxx"
      63             : #include "ddelink.hxx"
      64             : #include "scmatrix.hxx"
      65             : #include "arealink.hxx"
      66             : #include "dociter.hxx"
      67             : #include "patattr.hxx"
      68             : #include "hints.hxx"
      69             : #include "editutil.hxx"
      70             : #include "progress.hxx"
      71             : #include "document.hxx"
      72             : #include "chartlis.hxx"
      73             : #include "chartlock.hxx"
      74             : #include "refupdat.hxx"
      75             : #include "validat.hxx"      // fuer HasMacroCalls
      76             : #include "markdata.hxx"
      77             : #include "scmod.hxx"
      78             : #include "printopt.hxx"
      79             : #include "externalrefmgr.hxx"
      80             : #include "globstr.hrc"
      81             : #include "sc.hrc"
      82             : #include "charthelper.hxx"
      83             : #include "macromgr.hxx"
      84             : #include "dpobject.hxx"
      85             : #include "docuno.hxx"
      86             : #include "scresid.hxx"
      87             : #include "columniterator.hxx"
      88             : #include "globalnames.hxx"
      89             : #include "stringutil.hxx"
      90             : 
      91             : #include <memory>
      92             : #include <boost/scoped_ptr.hpp>
      93             : 
      94             : //  states for online spelling in the visible range (0 is set initially)
      95             : #define VSPL_START  0
      96             : #define VSPL_DONE   1
      97             : 
      98             : using namespace com::sun::star;
      99             : 
     100             : // STATIC DATA -----------------------------------------------------------
     101             : 
     102             : namespace {
     103             : 
     104         314 : inline sal_uInt16 getScaleValue(SfxStyleSheetBase& rStyle, sal_uInt16 nWhich)
     105             : {
     106         314 :     return static_cast<const SfxUInt16Item&>(rStyle.GetItemSet().Get(nWhich)).GetValue();
     107             : }
     108             : 
     109             : }
     110             : 
     111        1455 : void ScDocument::ImplCreateOptions()
     112             : {
     113        1455 :     pDocOptions  = new ScDocOptions();
     114        1455 :     pViewOptions = new ScViewOptions();
     115        1455 : }
     116             : 
     117             : //------------------------------------------------------------------------
     118             : 
     119        1340 : void ScDocument::ImplDeleteOptions()
     120             : {
     121        1340 :     delete pDocOptions;
     122        1340 :     delete pViewOptions;
     123        1340 :     delete pExtDocOptions;
     124        1340 : }
     125             : 
     126             : //------------------------------------------------------------------------
     127             : 
     128        3562 : SfxPrinter* ScDocument::GetPrinter(bool bCreateIfNotExist)
     129             : {
     130        3562 :     if ( !pPrinter && bCreateIfNotExist )
     131             :     {
     132             :         SfxItemSet* pSet =
     133         112 :             new SfxItemSet( *xPoolHelper->GetDocPool(),
     134             :                             SID_PRINTER_NOTFOUND_WARN,  SID_PRINTER_NOTFOUND_WARN,
     135             :                             SID_PRINTER_CHANGESTODOC,   SID_PRINTER_CHANGESTODOC,
     136             :                             SID_PRINT_SELECTEDSHEET,    SID_PRINT_SELECTEDSHEET,
     137             :                             SID_SCPRINTOPTIONS,         SID_SCPRINTOPTIONS,
     138         112 :                             NULL );
     139             : 
     140         112 :         ::utl::MiscCfg aMisc;
     141         112 :         sal_uInt16 nFlags = 0;
     142         112 :         if ( aMisc.IsPaperOrientationWarning() )
     143           0 :             nFlags |= SFX_PRINTER_CHG_ORIENTATION;
     144         112 :         if ( aMisc.IsPaperSizeWarning() )
     145           0 :             nFlags |= SFX_PRINTER_CHG_SIZE;
     146         112 :         pSet->Put( SfxFlagItem( SID_PRINTER_CHANGESTODOC, nFlags ) );
     147         112 :         pSet->Put( SfxBoolItem( SID_PRINTER_NOTFOUND_WARN, aMisc.IsNotFoundWarning() ) );
     148             : 
     149         112 :         pPrinter = new SfxPrinter( pSet );
     150         112 :         pPrinter->SetMapMode( MAP_100TH_MM );
     151         112 :         UpdateDrawPrinter();
     152         112 :         pPrinter->SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
     153             :     }
     154             : 
     155        3562 :     return pPrinter;
     156             : }
     157             : 
     158             : //------------------------------------------------------------------------
     159             : 
     160          38 : void ScDocument::SetPrinter( SfxPrinter* pNewPrinter )
     161             : {
     162          38 :     if ( pNewPrinter == pPrinter )
     163             :     {
     164             :         //  #i6706# SetPrinter is called with the same printer again if
     165             :         //  the JobSetup has changed. In that case just call UpdateDrawPrinter
     166             :         //  (SetRefDevice for drawing layer) because of changed text sizes.
     167           0 :         UpdateDrawPrinter();
     168             :     }
     169             :     else
     170             :     {
     171          38 :         SfxPrinter* pOld = pPrinter;
     172          38 :         pPrinter = pNewPrinter;
     173          38 :         UpdateDrawPrinter();
     174          38 :         pPrinter->SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
     175          38 :         delete pOld;
     176             :     }
     177          38 :     InvalidateTextWidth(NULL, NULL, false);     // in both cases
     178          38 : }
     179             : 
     180             : //------------------------------------------------------------------------
     181             : 
     182          76 : void ScDocument::SetPrintOptions()
     183             : {
     184          76 :     if ( !pPrinter ) GetPrinter(); // setzt pPrinter
     185             :     OSL_ENSURE( pPrinter, "Error in printer creation :-/" );
     186             : 
     187          76 :     if ( pPrinter )
     188             :     {
     189          76 :         ::utl::MiscCfg aMisc;
     190         152 :         SfxItemSet aOptSet( pPrinter->GetOptions() );
     191             : 
     192          76 :         sal_uInt16 nFlags = 0;
     193          76 :         if ( aMisc.IsPaperOrientationWarning() )
     194           0 :             nFlags |= SFX_PRINTER_CHG_ORIENTATION;
     195          76 :         if ( aMisc.IsPaperSizeWarning() )
     196           0 :             nFlags |= SFX_PRINTER_CHG_SIZE;
     197          76 :         aOptSet.Put( SfxFlagItem( SID_PRINTER_CHANGESTODOC, nFlags ) );
     198          76 :         aOptSet.Put( SfxBoolItem( SID_PRINTER_NOTFOUND_WARN, aMisc.IsNotFoundWarning() ) );
     199             : 
     200         152 :         pPrinter->SetOptions( aOptSet );
     201             :     }
     202          76 : }
     203             : 
     204             : //------------------------------------------------------------------------
     205             : 
     206        2615 : VirtualDevice* ScDocument::GetVirtualDevice_100th_mm()
     207             : {
     208        2615 :     if (!pVirtualDevice_100th_mm)
     209             :     {
     210             : #ifdef IOS
     211             :         pVirtualDevice_100th_mm = new VirtualDevice( 8 );
     212             : #else
     213         290 :         pVirtualDevice_100th_mm = new VirtualDevice( 1 );
     214             : #endif
     215         290 :         pVirtualDevice_100th_mm->SetReferenceDevice(VirtualDevice::REFDEV_MODE_MSO1);
     216         290 :         MapMode aMapMode( pVirtualDevice_100th_mm->GetMapMode() );
     217         290 :         aMapMode.SetMapUnit( MAP_100TH_MM );
     218         290 :         pVirtualDevice_100th_mm->SetMapMode( aMapMode );
     219             :     }
     220        2615 :     return pVirtualDevice_100th_mm;
     221             : }
     222             : 
     223        2693 : OutputDevice* ScDocument::GetRefDevice()
     224             : {
     225             :     // Create printer like ref device, see Writer...
     226        2693 :     OutputDevice* pRefDevice = NULL;
     227        2693 :     if ( SC_MOD()->GetInputOptions().GetTextWysiwyg() )
     228          78 :         pRefDevice = GetPrinter();
     229             :     else
     230        2615 :         pRefDevice = GetVirtualDevice_100th_mm();
     231        2693 :     return pRefDevice;
     232             : }
     233             : 
     234             : //------------------------------------------------------------------------
     235             : 
     236           0 : void ScDocument::ModifyStyleSheet( SfxStyleSheetBase& rStyleSheet,
     237             :                                    const SfxItemSet&  rChanges )
     238             : {
     239           0 :     SfxItemSet& rSet = rStyleSheet.GetItemSet();
     240             : 
     241           0 :     switch ( rStyleSheet.GetFamily() )
     242             :     {
     243             :         case SFX_STYLE_FAMILY_PAGE:
     244             :             {
     245           0 :                 const sal_uInt16 nOldScale = getScaleValue(rStyleSheet, ATTR_PAGE_SCALE);
     246           0 :                 const sal_uInt16 nOldScaleToPages = getScaleValue(rStyleSheet, ATTR_PAGE_SCALETOPAGES);
     247           0 :                 rSet.Put( rChanges );
     248           0 :                 const sal_uInt16 nNewScale        = getScaleValue(rStyleSheet, ATTR_PAGE_SCALE);
     249           0 :                 const sal_uInt16 nNewScaleToPages = getScaleValue(rStyleSheet, ATTR_PAGE_SCALETOPAGES);
     250             : 
     251           0 :                 if ( (nOldScale != nNewScale) || (nOldScaleToPages != nNewScaleToPages) )
     252           0 :                     InvalidateTextWidth( rStyleSheet.GetName() );
     253             : 
     254           0 :                 if( SvtLanguageOptions().IsCTLFontEnabled() )
     255             :                 {
     256           0 :                     const SfxPoolItem *pItem = NULL;
     257           0 :                     if( rChanges.GetItemState(ATTR_WRITINGDIR, true, &pItem ) == SFX_ITEM_SET )
     258           0 :                         ScChartHelper::DoUpdateAllCharts( this );
     259             :                 }
     260             :             }
     261           0 :             break;
     262             : 
     263             :         case SFX_STYLE_FAMILY_PARA:
     264             :             {
     265             :                 bool bNumFormatChanged;
     266           0 :                 if ( ScGlobal::CheckWidthInvalidate( bNumFormatChanged,
     267           0 :                         rSet, rChanges ) )
     268           0 :                     InvalidateTextWidth( NULL, NULL, bNumFormatChanged );
     269             : 
     270           0 :                 for (SCTAB nTab=0; nTab<=MAXTAB; ++nTab)
     271           0 :                     if (maTabs[nTab] && maTabs[nTab]->IsStreamValid())
     272           0 :                         maTabs[nTab]->SetStreamValid( false );
     273             : 
     274             :                 sal_uLong nOldFormat =
     275             :                     ((const SfxUInt32Item*)&rSet.Get(
     276           0 :                     ATTR_VALUE_FORMAT ))->GetValue();
     277             :                 sal_uLong nNewFormat =
     278             :                     ((const SfxUInt32Item*)&rChanges.Get(
     279           0 :                     ATTR_VALUE_FORMAT ))->GetValue();
     280             :                 LanguageType eNewLang, eOldLang;
     281           0 :                 eNewLang = eOldLang = LANGUAGE_DONTKNOW;
     282           0 :                 if ( nNewFormat != nOldFormat )
     283             :                 {
     284           0 :                     SvNumberFormatter* pFormatter = GetFormatTable();
     285           0 :                     eOldLang = pFormatter->GetEntry( nOldFormat )->GetLanguage();
     286           0 :                     eNewLang = pFormatter->GetEntry( nNewFormat )->GetLanguage();
     287             :                 }
     288             : 
     289             :                 // Bedeutung der Items in rChanges:
     290             :                 //  Item gesetzt    - Aenderung uebernehmen
     291             :                 //  Dontcare        - Default setzen
     292             :                 //  Default         - keine Aenderung
     293             :                 // ("keine Aenderung" geht nicht mit PutExtended, darum Schleife)
     294           0 :                 for (sal_uInt16 nWhich = ATTR_PATTERN_START; nWhich <= ATTR_PATTERN_END; nWhich++)
     295             :                 {
     296             :                     const SfxPoolItem* pItem;
     297           0 :                     SfxItemState eState = rChanges.GetItemState( nWhich, false, &pItem );
     298           0 :                     if ( eState == SFX_ITEM_SET )
     299           0 :                         rSet.Put( *pItem );
     300           0 :                     else if ( eState == SFX_ITEM_DONTCARE )
     301           0 :                         rSet.ClearItem( nWhich );
     302             :                     // bei Default nichts
     303             :                 }
     304             : 
     305           0 :                 if ( eNewLang != eOldLang )
     306             :                     rSet.Put(
     307           0 :                         SvxLanguageItem( eNewLang, ATTR_LANGUAGE_FORMAT ) );
     308             :             }
     309           0 :             break;
     310             :         default:
     311             :         {
     312             :             // added to avoid warnings
     313             :         }
     314             :     }
     315           0 : }
     316             : 
     317             : //------------------------------------------------------------------------
     318             : 
     319           0 : void ScDocument::CopyStdStylesFrom( ScDocument* pSrcDoc )
     320             : {
     321             :     // number format exchange list has to be handled here, too
     322           0 :     NumFmtMergeHandler aNumFmtMergeHdl(this, pSrcDoc);
     323           0 :     xPoolHelper->GetStylePool()->CopyStdStylesFrom( pSrcDoc->xPoolHelper->GetStylePool() );
     324           0 : }
     325             : 
     326             : //------------------------------------------------------------------------
     327             : 
     328           0 : void ScDocument::InvalidateTextWidth( const OUString& rStyleName )
     329             : {
     330           0 :     const SCTAB nCount = GetTableCount();
     331           0 :     for ( SCTAB i=0; i<nCount && maTabs[i]; i++ )
     332           0 :         if ( maTabs[i]->GetPageStyle() == rStyleName )
     333           0 :             InvalidateTextWidth( i );
     334           0 : }
     335             : 
     336             : //------------------------------------------------------------------------
     337             : 
     338           0 : void ScDocument::InvalidateTextWidth( SCTAB nTab )
     339             : {
     340           0 :     ScAddress aAdrFrom( 0,    0,        nTab );
     341           0 :     ScAddress aAdrTo  ( MAXCOL, MAXROW, nTab );
     342           0 :     InvalidateTextWidth( &aAdrFrom, &aAdrTo, false );
     343           0 : }
     344             : 
     345             : //------------------------------------------------------------------------
     346             : 
     347           0 : bool ScDocument::IsPageStyleInUse( const OUString& rStrPageStyle, SCTAB* pInTab )
     348             : {
     349           0 :     bool         bInUse = false;
     350           0 :     const SCTAB nCount = GetTableCount();
     351             :     SCTAB i;
     352             : 
     353           0 :     for ( i = 0; !bInUse && i < nCount && maTabs[i]; i++ )
     354           0 :         bInUse = ( maTabs[i]->GetPageStyle() == rStrPageStyle );
     355             : 
     356           0 :     if ( pInTab )
     357           0 :         *pInTab = i-1;
     358             : 
     359           0 :     return bInUse;
     360             : }
     361             : 
     362             : //------------------------------------------------------------------------
     363             : 
     364           0 : bool ScDocument::RemovePageStyleInUse( const OUString& rStyle )
     365             : {
     366           0 :     bool bWasInUse = false;
     367           0 :     const SCTAB nCount = GetTableCount();
     368             : 
     369           0 :     for ( SCTAB i=0; i<nCount && maTabs[i]; i++ )
     370           0 :         if ( maTabs[i]->GetPageStyle() == rStyle )
     371             :         {
     372           0 :             bWasInUse = true;
     373           0 :             maTabs[i]->SetPageStyle( ScGlobal::GetRscString(STR_STYLENAME_STANDARD) );
     374             :         }
     375             : 
     376           0 :     return bWasInUse;
     377             : }
     378             : 
     379           0 : bool ScDocument::RenamePageStyleInUse( const OUString& rOld, const OUString& rNew )
     380             : {
     381           0 :     bool bWasInUse = false;
     382           0 :     const SCTAB nCount = GetTableCount();
     383             : 
     384           0 :     for ( SCTAB i=0; i<nCount && maTabs[i]; i++ )
     385           0 :         if ( maTabs[i]->GetPageStyle() == rOld )
     386             :         {
     387           0 :             bWasInUse = true;
     388           0 :             maTabs[i]->SetPageStyle( rNew );
     389             :         }
     390             : 
     391           0 :     return bWasInUse;
     392             : }
     393             : 
     394             : //------------------------------------------------------------------------
     395             : 
     396       13940 : sal_uInt8 ScDocument::GetEditTextDirection(SCTAB nTab) const
     397             : {
     398       13940 :     EEHorizontalTextDirection eRet = EE_HTEXTDIR_DEFAULT;
     399             : 
     400       13940 :     OUString aStyleName = GetPageStyle( nTab );
     401       13940 :     SfxStyleSheetBase* pStyle = xPoolHelper->GetStylePool()->Find( aStyleName, SFX_STYLE_FAMILY_PAGE );
     402       13940 :     if ( pStyle )
     403             :     {
     404       13940 :         SfxItemSet& rStyleSet = pStyle->GetItemSet();
     405             :         SvxFrameDirection eDirection = (SvxFrameDirection)
     406       13940 :             ((const SvxFrameDirectionItem&)rStyleSet.Get( ATTR_WRITINGDIR )).GetValue();
     407             : 
     408       13940 :         if ( eDirection == FRMDIR_HORI_LEFT_TOP )
     409       13878 :             eRet = EE_HTEXTDIR_L2R;
     410          62 :         else if ( eDirection == FRMDIR_HORI_RIGHT_TOP )
     411           0 :             eRet = EE_HTEXTDIR_R2L;
     412             :         // else (invalid for EditEngine): keep "default"
     413             :     }
     414             : 
     415       13940 :     return sal::static_int_cast<sal_uInt8>(eRet);
     416             : }
     417             : 
     418           1 : ScMacroManager* ScDocument::GetMacroManager()
     419             : {
     420           1 :     if (!mpMacroMgr.get())
     421           1 :         mpMacroMgr.reset(new ScMacroManager(this));
     422           1 :     return mpMacroMgr.get();
     423             : }
     424             : 
     425           0 : bool ScDocument::IsEmptyData( SCTAB nTab, SCCOL nCol ) const
     426             : {
     427           0 :     const ScTable* pTab = FetchTable(nTab);
     428           0 :     if (!pTab)
     429           0 :         return true;
     430             : 
     431           0 :     return pTab->IsEmptyData(nCol);
     432             : }
     433             : 
     434          20 : void ScDocument::FillMatrix(
     435             :     ScMatrix& rMat, SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const
     436             : {
     437          20 :     const ScTable* pTab = FetchTable(nTab);
     438          20 :     if (!pTab)
     439           0 :         return;
     440             : 
     441          20 :     if (nCol1 > nCol2 || nRow1 > nRow2)
     442           0 :         return;
     443             : 
     444             :     SCSIZE nC, nR;
     445          20 :     rMat.GetDimensions(nC, nR);
     446          20 :     if (static_cast<SCROW>(nR) != nRow2 - nRow1 + 1 || static_cast<SCCOL>(nC) != nCol2 - nCol1 + 1)
     447           0 :         return;
     448             : 
     449          20 :     pTab->FillMatrix(rMat, nCol1, nRow1, nCol2, nRow2);
     450             : }
     451             : 
     452           0 : void ScDocument::SetFormulaResults( const ScAddress& rTopPos, const double* pResults, size_t nLen )
     453             : {
     454           0 :     ScTable* pTab = FetchTable(rTopPos.Tab());
     455           0 :     if (!pTab)
     456           0 :         return;
     457             : 
     458           0 :     pTab->SetFormulaResults(rTopPos.Col(), rTopPos.Row(), pResults, nLen);
     459             : }
     460             : 
     461             : 
     462             : //------------------------------------------------------------------------
     463             : 
     464        5665 : void ScDocument::InvalidateTextWidth( const ScAddress* pAdrFrom, const ScAddress* pAdrTo,
     465             :                                       bool bNumFormatChanged )
     466             : {
     467        5665 :     bool bBroadcast = (bNumFormatChanged && GetDocOptions().IsCalcAsShown() && !IsImportingXML() && !IsClipboard());
     468        5665 :     if ( pAdrFrom && !pAdrTo )
     469             :     {
     470           0 :         const SCTAB nTab = pAdrFrom->Tab();
     471             : 
     472           0 :         if (nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
     473           0 :             maTabs[nTab]->InvalidateTextWidth( pAdrFrom, NULL, bNumFormatChanged, bBroadcast );
     474             :     }
     475             :     else
     476             :     {
     477        5665 :         const SCTAB nTabStart = pAdrFrom ? pAdrFrom->Tab() : 0;
     478        5665 :         const SCTAB nTabEnd   = pAdrTo   ? pAdrTo->Tab()   : MAXTAB;
     479             : 
     480       11330 :         for ( SCTAB nTab=nTabStart; nTab<=nTabEnd && nTab < static_cast<SCTAB>(maTabs.size()); nTab++ )
     481        5665 :             if ( maTabs[nTab] )
     482        5665 :                 maTabs[nTab]->InvalidateTextWidth( pAdrFrom, pAdrTo, bNumFormatChanged, bBroadcast );
     483             :     }
     484        5665 : }
     485             : 
     486             : //------------------------------------------------------------------------
     487             : 
     488             : #define CALCMAX                 1000    // Berechnungen
     489             : #define ABORT_EVENTS            (VCL_INPUT_ANY & ~VCL_INPUT_TIMER & ~VCL_INPUT_OTHER)
     490             : 
     491             : namespace {
     492             : 
     493             : class IdleCalcTextWidthScope
     494             : {
     495             :     ScDocument& mrDoc;
     496             :     ScAddress& mrCalcPos;
     497             :     MapMode maOldMapMode;
     498             :     sal_uLong mnStartTime;
     499             :     ScStyleSheetPool* mpStylePool;
     500             :     sal_uInt16 mnOldSearchMask;
     501             :     SfxStyleFamily meOldFamily;
     502             :     bool mbNeedMore;
     503             :     bool mbProgress;
     504             : 
     505             : public:
     506         314 :     IdleCalcTextWidthScope(ScDocument& rDoc, ScAddress& rCalcPos) :
     507             :         mrDoc(rDoc),
     508             :         mrCalcPos(rCalcPos),
     509         314 :         mnStartTime(Time::GetSystemTicks()),
     510         314 :         mpStylePool(rDoc.GetStyleSheetPool()),
     511         314 :         mnOldSearchMask(mpStylePool->GetSearchMask()),
     512         314 :         meOldFamily(mpStylePool->GetSearchFamily()),
     513             :         mbNeedMore(false),
     514        1570 :         mbProgress(false)
     515             :     {
     516             :         // The old search mask / family flags must be restored so that e.g.
     517             :         // the styles dialog shows correct listing when it's opened in-between
     518             :         // the calls.
     519             : 
     520         314 :         mrDoc.EnableIdle(false);
     521         314 :         mpStylePool->SetSearchMask(SFX_STYLE_FAMILY_PAGE, SFXSTYLEBIT_ALL);
     522         314 :     }
     523             : 
     524         314 :     ~IdleCalcTextWidthScope()
     525         314 :     {
     526         314 :         SfxPrinter* pDev = mrDoc.GetPrinter();
     527         314 :         if (pDev)
     528         314 :             pDev->SetMapMode(maOldMapMode);
     529             : 
     530         314 :         if (mbProgress)
     531           0 :             ScProgress::DeleteInterpretProgress();
     532             : 
     533         314 :         mpStylePool->SetSearchMask(meOldFamily, mnOldSearchMask);
     534         314 :         mrDoc.EnableIdle(true);
     535         314 :     }
     536             : 
     537         998 :     SCTAB Tab() const { return mrCalcPos.Tab(); }
     538         314 :     SCCOL Col() const { return mrCalcPos.Col(); }
     539         314 :     SCROW Row() const { return mrCalcPos.Row(); }
     540             : 
     541             :     const ScAddress& Pos() const { return mrCalcPos; }
     542             : 
     543         258 :     void setTab(SCTAB nTab) { mrCalcPos.SetTab(nTab); }
     544           0 :     void setCol(SCCOL nCol) { mrCalcPos.SetCol(nCol); }
     545           0 :     void setRow(SCROW nRow) { mrCalcPos.SetRow(nRow); }
     546             : 
     547         314 :     void incTab(SCTAB nInc=1) { mrCalcPos.IncTab(nInc); }
     548           0 :     void incCol(SCCOL nInc=1) { mrCalcPos.IncCol(nInc); }
     549             :     void incRow(SCROW nInc=1) { mrCalcPos.IncRow(nInc); }
     550             : 
     551           0 :     void setOldMapMode(const MapMode& rOldMapMode) { maOldMapMode = rOldMapMode; }
     552             : 
     553           0 :     void setNeedMore(bool b) { mbNeedMore = b; }
     554           0 :     bool getNeedMore() const { return mbNeedMore; }
     555             : 
     556           0 :     sal_uLong getStartTime() const { return mnStartTime; }
     557             : 
     558           0 :     void createProgressBar()
     559             :     {
     560           0 :         ScProgress::CreateInterpretProgress(&mrDoc, false);
     561           0 :         mbProgress = true;
     562           0 :     }
     563             : 
     564           0 :     bool hasProgressBar() const { return mbProgress; }
     565             : 
     566         314 :     ScStyleSheetPool* getStylePool() { return mpStylePool; }
     567             : };
     568             : 
     569             : }
     570             : 
     571        1590 : bool ScDocument::IdleCalcTextWidth()            // true = demnaechst wieder versuchen
     572             : {
     573             :     // #i75610# if a printer hasn't been set or created yet, don't create one for this
     574        1590 :     if (!mbIdleEnabled || IsInLinkUpdate() || GetPrinter(false) == NULL)
     575        1276 :         return false;
     576             : 
     577         314 :     IdleCalcTextWidthScope aScope(*this, aCurTextWidthCalcPos);
     578             : 
     579         314 :     if (!ValidRow(aScope.Row()))
     580             :     {
     581           0 :         aScope.setRow(0);
     582           0 :         aScope.incCol(-1);
     583             :     }
     584             : 
     585         314 :     if (aScope.Col() < 0)
     586             :     {
     587           0 :         aScope.setCol(MAXCOL);
     588           0 :         aScope.incTab();
     589             :     }
     590             : 
     591         314 :     if (!ValidTab(aScope.Tab()) || aScope.Tab() >= static_cast<SCTAB>(maTabs.size()) || !maTabs[aScope.Tab()])
     592         258 :         aScope.setTab(0);
     593             : 
     594         314 :     ScTable* pTab = maTabs[aScope.Tab()];
     595         314 :     ScStyleSheet* pStyle = (ScStyleSheet*)aScope.getStylePool()->Find(pTab->aPageStyle, SFX_STYLE_FAMILY_PAGE);
     596             :     OSL_ENSURE( pStyle, "Missing StyleSheet :-/" );
     597             : 
     598         314 :     if (!pStyle || getScaleValue(*pStyle, ATTR_PAGE_SCALETOPAGES) == 0)
     599             :     {
     600             :         // Move to the next sheet as the current one has scale-to-pages set,
     601             :         // and bail out.
     602         314 :         aScope.incTab();
     603         314 :         return false;
     604             :     }
     605             : 
     606           0 :     sal_uInt16 nZoom = getScaleValue(*pStyle, ATTR_PAGE_SCALE);
     607           0 :     Fraction aZoomFract(nZoom, 100);
     608             : 
     609             :     // Start at specified cell position (nCol, nRow, nTab).
     610           0 :     ScColumn* pCol  = &pTab->aCol[aScope.Col()];
     611           0 :     boost::scoped_ptr<ScColumnTextWidthIterator> pColIter(new ScColumnTextWidthIterator(*pCol, aScope.Row(), MAXROW));
     612             : 
     613           0 :     OutputDevice* pDev = NULL;
     614           0 :     sal_uInt16 nRestart = 0;
     615           0 :     sal_uInt16 nCount = 0;
     616           0 :     while ( (nZoom > 0) && (nCount < CALCMAX) && (nRestart < 2) )
     617             :     {
     618           0 :         if (pColIter->hasCell())
     619             :         {
     620             :             // More cell in this column.
     621           0 :             SCROW nRow = pColIter->getPos();
     622           0 :             aScope.setRow(nRow);
     623             : 
     624           0 :             if (pColIter->getValue() == TEXTWIDTH_DIRTY)
     625             :             {
     626             :                 // Calculate text width for this cell.
     627           0 :                 double nPPTX = 0.0;
     628           0 :                 double nPPTY = 0.0;
     629           0 :                 if (!pDev)
     630             :                 {
     631           0 :                     pDev = GetPrinter();
     632           0 :                     aScope.setOldMapMode(pDev->GetMapMode());
     633           0 :                     pDev->SetMapMode( MAP_PIXEL );  // wichtig fuer GetNeededSize
     634             : 
     635           0 :                     Point aPix1000 = pDev->LogicToPixel( Point(1000,1000), MAP_TWIP );
     636           0 :                     nPPTX = aPix1000.X() / 1000.0;
     637           0 :                     nPPTY = aPix1000.Y() / 1000.0;
     638             :                 }
     639             : 
     640           0 :                 if (!aScope.hasProgressBar() && pCol->IsFormulaDirty(nRow))
     641           0 :                     aScope.createProgressBar();
     642             : 
     643             :                 sal_uInt16 nNewWidth = (sal_uInt16)GetNeededSize(
     644           0 :                     aScope.Col(), aScope.Row(), aScope.Tab(),
     645           0 :                     pDev, nPPTX, nPPTY, aZoomFract,aZoomFract, true, true);   // bTotalSize
     646             : 
     647           0 :                 pColIter->setValue(nNewWidth);
     648           0 :                 aScope.setNeedMore(true);
     649             :             }
     650           0 :             pColIter->next();
     651             :         }
     652             :         else
     653             :         {
     654             :             // No more cell in this column.  Move to the left column and start at row 0.
     655             : 
     656           0 :             bool bNewTab = false;
     657             : 
     658           0 :             aScope.setRow(0);
     659           0 :             aScope.incCol(-1);
     660             : 
     661           0 :             if (aScope.Col() < 0)
     662             :             {
     663             :                 // No more column to the left.  Move to the right-most column of the next sheet.
     664           0 :                 aScope.setCol(MAXCOL);
     665           0 :                 aScope.incTab();
     666           0 :                 bNewTab = true;
     667             :             }
     668             : 
     669           0 :             if (!ValidTab(aScope.Tab()) || aScope.Tab() >= static_cast<SCTAB>(maTabs.size()) || !maTabs[aScope.Tab()] )
     670             :             {
     671             :                 // Sheet doesn't exist at specified sheet position.  Restart at sheet 0.
     672           0 :                 aScope.setTab(0);
     673           0 :                 nRestart++;
     674           0 :                 bNewTab = true;
     675             :             }
     676             : 
     677           0 :             if ( nRestart < 2 )
     678             :             {
     679           0 :                 if ( bNewTab )
     680             :                 {
     681           0 :                     pTab = maTabs[aScope.Tab()];
     682           0 :                     pStyle = (ScStyleSheet*)aScope.getStylePool()->Find(
     683           0 :                         pTab->aPageStyle, SFX_STYLE_FAMILY_PAGE);
     684             : 
     685           0 :                     if ( pStyle )
     686             :                     {
     687             :                         // Check if the scale-to-pages setting is set. If
     688             :                         // set, we exit the loop.  If not, get the page
     689             :                         // scale factor of the new sheet.
     690           0 :                         if (getScaleValue(*pStyle, ATTR_PAGE_SCALETOPAGES) == 0)
     691             :                         {
     692           0 :                             nZoom = getScaleValue(*pStyle, ATTR_PAGE_SCALE);
     693           0 :                             aZoomFract = Fraction(nZoom, 100);
     694             :                         }
     695             :                         else
     696           0 :                             nZoom = 0;
     697             :                     }
     698             :                     else
     699             :                     {
     700             :                         OSL_FAIL( "Missing StyleSheet :-/" );
     701             :                     }
     702             :                 }
     703             : 
     704           0 :                 if ( nZoom > 0 )
     705             :                 {
     706           0 :                     pCol  = &pTab->aCol[aScope.Col()];
     707           0 :                     pColIter.reset(new ScColumnTextWidthIterator(*pCol, aScope.Row(), MAXROW));
     708             :                 }
     709             :                 else
     710             :                 {
     711           0 :                     aScope.incTab(); // Move to the next sheet as the current one has scale-to-pages set.
     712           0 :                     return false;
     713             :                 }
     714             :             }
     715             :         }
     716             : 
     717           0 :         ++nCount;
     718             : 
     719             :         // Quit if either 1) its duration exceeds 50 ms, or 2) there is any
     720             :         // pending event after processing 32 cells.
     721           0 :         if ((50L < Time::GetSystemTicks() - aScope.getStartTime()) || (nCount > 31 && Application::AnyInput(ABORT_EVENTS)))
     722           0 :             nCount = CALCMAX;
     723             :     }
     724             : 
     725         314 :     return aScope.getNeedMore();
     726             : }
     727             : 
     728             : //------------------------------------------------------------------------
     729             : 
     730             : class ScSpellStatus
     731             : {
     732             : public:
     733             :     bool    bModified;
     734             : 
     735        3668 :     ScSpellStatus() : bModified(false) {};
     736             : 
     737             :     DECL_LINK (EventHdl, EditStatus*);
     738             : };
     739             : 
     740        4392 : IMPL_LINK( ScSpellStatus, EventHdl, EditStatus *, pStatus )
     741             : {
     742        2196 :     sal_uLong nStatus = pStatus->GetStatusWord();
     743        2196 :     if ( nStatus & EE_STAT_WRONGWORDCHANGED )
     744         159 :         bModified = true;
     745             : 
     746        2196 :     return 0;
     747             : }
     748             : 
     749             : //  SPELL_MAXCELLS muss mindestens 256 sein, solange am Iterator keine
     750             : //  Start-Spalte gesetzt werden kann
     751             : 
     752             : //! SPELL_MAXTEST fuer Timer und Idle unterschiedlich ???
     753             : 
     754             : //  SPELL_MAXTEST now divided between visible and rest of document
     755             : 
     756             : #define SPELL_MAXTEST_VIS   1
     757             : #define SPELL_MAXTEST_ALL   3
     758             : #define SPELL_MAXCELLS      256
     759             : 
     760        3668 : bool ScDocument::OnlineSpellInRange( const ScRange& rSpellRange, ScAddress& rSpellPos,
     761             :                                      sal_uInt16 nMaxTest )
     762             : {
     763        3668 :     ScEditEngineDefaulter* pEngine = NULL;              //! am Dokument speichern
     764        3668 :     SfxItemSet* pDefaults = NULL;
     765        3668 :     ScSpellStatus aStatus;
     766             : 
     767        3668 :     sal_uInt16 nCellCount = 0;          // Zellen insgesamt
     768        3668 :     sal_uInt16 nTestCount = 0;          // Aufrufe Spelling
     769        3668 :     bool bChanged = false;          // Aenderungen?
     770             : 
     771        3668 :     SCCOL nCol = rSpellRange.aStart.Col();      // iterator always starts on the left edge
     772        3668 :     SCROW nRow = rSpellPos.Row();
     773        3668 :     SCTAB nTab = rSpellPos.Tab();
     774        3668 :     if ( nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab] )                           // sheet deleted?
     775             :     {
     776           3 :         nTab = rSpellRange.aStart.Tab();
     777           3 :         nRow = rSpellRange.aStart.Row();
     778           3 :         if ( nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab] )
     779             :         {
     780             :             //  may happen for visible range
     781           0 :             return false;
     782             :         }
     783             :     }
     784             : 
     785        3668 :     ScRangeList aPivotRanges;
     786        3668 :     if (pDPCollection)
     787         526 :         aPivotRanges = pDPCollection->GetAllTableRanges(nTab);
     788             : 
     789             :     ScHorizontalCellIterator aIter( this, nTab,
     790        3668 :                                     rSpellRange.aStart.Col(), nRow,
     791       11004 :                                     rSpellRange.aEnd.Col(), rSpellRange.aEnd.Row() );
     792        3668 :     ScRefCellValue* pCell = aIter.GetNext( nCol, nRow );
     793             :     //  skip everything left of rSpellPos:
     794       10006 :     while ( pCell && nRow == rSpellPos.Row() && nCol < rSpellPos.Col() )
     795        2670 :         pCell = aIter.GetNext( nCol, nRow );
     796             : 
     797       13368 :     for (; pCell; pCell = aIter.GetNext(nCol, nRow))
     798             :     {
     799       11061 :         if (!aPivotRanges.empty() && aPivotRanges.In(ScAddress(nCol, nRow, nTab)))
     800             :             // Don't spell check within pivot tables.
     801         188 :             continue;
     802             : 
     803       10873 :         CellType eType = pCell->meType;
     804       10873 :         if ( eType == CELLTYPE_STRING || eType == CELLTYPE_EDIT )
     805             :         {
     806        2732 :             if (!pEngine)
     807             :             {
     808             :                 //  ScTabEditEngine is needed
     809             :                 //  because MapMode must be set for some old documents
     810        1771 :                 pEngine = new ScTabEditEngine( this );
     811        1771 :                 pEngine->SetControlWord( pEngine->GetControlWord() |
     812        1771 :                             ( EE_CNTRL_ONLINESPELLING | EE_CNTRL_ALLOWBIGOBJS ) );
     813        1771 :                 pEngine->SetStatusEventHdl( LINK( &aStatus, ScSpellStatus, EventHdl ) );
     814             :                 //  Delimiters hier wie in inputhdl.cxx !!!
     815             :                 pEngine->SetWordDelimiters(
     816        1771 :                             ScEditUtil::ModifyDelimiters( pEngine->GetWordDelimiters() ) );
     817        1771 :                 pDefaults = new SfxItemSet( pEngine->GetEmptyItemSet() );
     818             : 
     819        1771 :                 com::sun::star::uno::Reference<com::sun::star::linguistic2::XSpellChecker1> xXSpellChecker1( LinguMgr::GetSpellChecker() );
     820             : 
     821        1771 :                 pEngine->SetSpeller( xXSpellChecker1 );
     822             :             }
     823             : 
     824        2732 :             const ScPatternAttr* pPattern = GetPattern( nCol, nRow, nTab );
     825        2732 :             pPattern->FillEditItemSet( pDefaults );
     826        2732 :             pEngine->SetDefaults( pDefaults, false );               //! noetig ?
     827             : 
     828             :             sal_uInt16 nCellLang = ((const SvxLanguageItem&)
     829        2732 :                                     pPattern->GetItem(ATTR_FONT_LANGUAGE)).GetValue();
     830        2732 :             if ( nCellLang == LANGUAGE_SYSTEM )
     831           0 :                 nCellLang = Application::GetSettings().GetLanguageTag().getLanguageType();   // never use SYSTEM for spelling
     832        2732 :             pEngine->SetDefaultLanguage( nCellLang );
     833             : 
     834        2732 :             if ( eType == CELLTYPE_STRING )
     835             :             {
     836        2470 :                 pEngine->SetText(*pCell->mpString);
     837             :             }
     838         262 :             else if (pCell->mpEditText)
     839         262 :                 pEngine->SetText(*pCell->mpEditText);
     840             :             else
     841           0 :                 pEngine->SetText(EMPTY_OUSTRING);
     842             : 
     843        2732 :             aStatus.bModified = false;
     844        2732 :             pEngine->CompleteOnlineSpelling();
     845        2732 :             if ( aStatus.bModified )                // Fehler dazu oder weggekommen?
     846             :             {
     847         159 :                 bool bNeedEdit = true;                      //  Test auf einfachen Text
     848         159 :                 if ( !pEngine->HasOnlineSpellErrors() )
     849             :                 {
     850           0 :                     ScEditAttrTester aTester( pEngine );
     851           0 :                     bNeedEdit = aTester.NeedsObject();
     852             :                 }
     853             : 
     854         159 :                 if ( bNeedEdit )
     855             :                 {
     856             :                     // The cell will take ownership of pNewData.
     857         159 :                     SetEditText(ScAddress(nCol,nRow,nTab), pEngine->CreateTextObject());
     858         159 :                     aIter.RehashCol(nCol);
     859             :                 }
     860             :                 else
     861             :                 {
     862           0 :                     ScSetStringParam aParam;
     863           0 :                     aParam.setTextInput();
     864           0 :                     SetString(ScAddress(nCol,nRow,nTab), pEngine->GetText(), &aParam);
     865           0 :                     aIter.RehashCol(nCol);
     866             :                 }
     867             : 
     868             :                 //  Paint
     869         159 :                 if (pShell)
     870             :                 {
     871             :                     //  Seitenvorschau ist davon nicht betroffen
     872             :                     //  (sollte jedenfalls nicht)
     873         159 :                     ScPaintHint aHint( ScRange( nCol, nRow, nTab ), PAINT_GRID );
     874         159 :                     aHint.SetPrintFlag( false );
     875         159 :                     pShell->Broadcast( aHint );
     876             :                 }
     877             : 
     878         159 :                 bChanged = true;
     879             :             }
     880             : 
     881        2732 :             if ( ++nTestCount >= nMaxTest )             // checked enough text?
     882        1355 :                 break;
     883             :         }
     884             : 
     885        9518 :         if ( ++nCellCount >= SPELL_MAXCELLS )           // seen enough cells?
     886           6 :             break;
     887             :     }
     888             : 
     889        3668 :     if ( pCell )
     890             :     {
     891        1361 :         ++nCol;                                         // continue after last cell
     892        1361 :         if ( nCol > rSpellRange.aEnd.Col() )
     893             :         {
     894          18 :             nCol = rSpellRange.aStart.Col();
     895          18 :             ++nRow;
     896          18 :             if ( nRow > rSpellRange.aEnd.Row() )
     897           0 :                 pCell = NULL;
     898             :         }
     899             :     }
     900             : 
     901        3668 :     if (!pCell)         // end of range reached -> next sheet
     902             :     {
     903        2307 :         ++nTab;
     904        2307 :         if ( nTab > rSpellRange.aEnd.Tab() || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab] )
     905        2157 :             nTab = rSpellRange.aStart.Tab();
     906        2307 :         nCol = rSpellRange.aStart.Col();
     907        2307 :         nRow = rSpellRange.aStart.Row();
     908             : 
     909        2307 :         nVisSpellState = VSPL_DONE;     //! only if this is for the visible range
     910             :     }
     911        3668 :     rSpellPos.Set( nCol, nRow, nTab );
     912             : 
     913        3668 :     delete pDefaults;
     914        3668 :     delete pEngine;         // bevor aStatus out of scope geht
     915             : 
     916        7336 :     return bChanged;
     917             : }
     918             : 
     919             : 
     920        1856 : bool ScDocument::ContinueOnlineSpelling()
     921             : {
     922        1856 :     if (!mbIdleEnabled || !pDocOptions->IsAutoSpell() || (pShell && pShell->IsReadOnly()))
     923          22 :         return false;
     924             : 
     925             :     // #i48433# set bInsertingFromOtherDoc flag so there are no broadcasts when PutCell is called
     926             :     // (same behavior as in RemoveAutoSpellObj: just transfer the broadcaster)
     927        1834 :     bool bOldInserting = IsInsertingFromOtherDoc();
     928        1834 :     SetInsertingFromOtherDoc( true );
     929             : 
     930             :     //! use one EditEngine for both calls
     931             : 
     932             :     //  first check visible range
     933        1834 :     bool bResult = OnlineSpellInRange( aVisSpellRange, aVisSpellPos, SPELL_MAXTEST_VIS );
     934             : 
     935             :     //  during first pass through visible range, always continue
     936        1834 :     if ( nVisSpellState == VSPL_START )
     937         213 :         bResult = true;
     938             : 
     939        1834 :     if (bResult)
     940             :     {
     941             :         //  if errors found, continue there
     942         345 :         OnlineSpellInRange( aVisSpellRange, aVisSpellPos, SPELL_MAXTEST_ALL );
     943             :     }
     944             :     else
     945             :     {
     946             :         //  if nothing found there, continue with rest of document
     947        1489 :         ScRange aTotalRange( 0,0,0, MAXCOL,MAXROW,MAXTAB );
     948        1489 :         bResult = OnlineSpellInRange( aTotalRange, aOnlineSpellPos, SPELL_MAXTEST_ALL );
     949             :     }
     950             : 
     951        1834 :     SetInsertingFromOtherDoc( bOldInserting );
     952             : 
     953        1834 :     return bResult;
     954             : }
     955             : 
     956             : 
     957           0 : void ScDocument::SetOnlineSpellPos( const ScAddress& rPos )
     958             : {
     959           0 :     aOnlineSpellPos = rPos;
     960             : 
     961             :     //  skip visible area for aOnlineSpellPos
     962           0 :     if ( aVisSpellRange.In( aOnlineSpellPos ) )
     963           0 :         aOnlineSpellPos = aVisSpellRange.aEnd;
     964           0 : }
     965             : 
     966        1362 : bool ScDocument::SetVisibleSpellRange( const ScRange& rNewRange )
     967             : {
     968        1362 :     bool bChange = ( aVisSpellRange != rNewRange );
     969        1362 :     if (bChange)
     970             :     {
     971             :         //  continue spelling through visible range when scrolling down
     972        1032 :         bool bContDown = ( nVisSpellState == VSPL_START && rNewRange.In( aVisSpellPos ) &&
     973         240 :                             rNewRange.aStart.Row() >  aVisSpellRange.aStart.Row() &&
     974         486 :                             rNewRange.aStart.Col() == aVisSpellRange.aStart.Col() &&
     975         485 :                             rNewRange.aEnd.Col()   == aVisSpellRange.aEnd.Col() );
     976             : 
     977         485 :         aVisSpellRange = rNewRange;
     978             : 
     979         485 :         if ( !bContDown )
     980             :         {
     981         485 :             aVisSpellPos = aVisSpellRange.aStart;
     982         485 :             nVisSpellState = VSPL_START;
     983             :         }
     984             : 
     985             :         //  skip visible area for aOnlineSpellPos
     986         485 :         if ( aVisSpellRange.In( aOnlineSpellPos ) )
     987         240 :             aOnlineSpellPos = aVisSpellRange.aEnd;
     988             :     }
     989        1362 :     return bChange;
     990             : }
     991             : 
     992           0 : void ScDocument::RemoveAutoSpellObj()
     993             : {
     994             :     //  alle Spelling-Informationen entfernen
     995             : 
     996           0 :     for (SCTAB nTab=0; nTab< static_cast<SCTAB>(maTabs.size()) && maTabs[nTab]; nTab++)
     997           0 :         maTabs[nTab]->RemoveAutoSpellObj();
     998           0 : }
     999             : 
    1000        3778 : void ScDocument::RepaintRange( const ScRange& rRange )
    1001             : {
    1002        3778 :     if ( bIsVisible && pShell )
    1003             :     {
    1004         160 :         ScModelObj* pModel = ScModelObj::getImplementation( pShell->GetModel() );
    1005         160 :         if ( pModel )
    1006         160 :             pModel->RepaintRange( rRange );     // locked repaints are checked there
    1007             :     }
    1008        3778 : }
    1009             : 
    1010           0 : void ScDocument::RepaintRange( const ScRangeList& rRange )
    1011             : {
    1012           0 :     if ( bIsVisible && pShell )
    1013             :     {
    1014           0 :         ScModelObj* pModel = ScModelObj::getImplementation( pShell->GetModel() );
    1015           0 :         if ( pModel )
    1016           0 :             pModel->RepaintRange( rRange );     // locked repaints are checked there
    1017             :     }
    1018           0 : }
    1019             : 
    1020             : //------------------------------------------------------------------------
    1021             : 
    1022        1590 : bool ScDocument::IdleCheckLinks()           // true = demnaechst wieder versuchen
    1023             : {
    1024        1590 :     bool bAnyLeft = false;
    1025             : 
    1026        1590 :     if (GetLinkManager())
    1027             :     {
    1028        1590 :         const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
    1029        1590 :         sal_uInt16 nCount = rLinks.size();
    1030        1604 :         for (sal_uInt16 i=0; i<nCount; i++)
    1031             :         {
    1032          14 :             ::sfx2::SvBaseLink* pBase = *rLinks[i];
    1033          14 :             if (pBase->ISA(ScDdeLink))
    1034             :             {
    1035           0 :                 ScDdeLink* pDdeLink = (ScDdeLink*)pBase;
    1036           0 :                 if (pDdeLink->NeedsUpdate())
    1037             :                 {
    1038           0 :                     pDdeLink->TryUpdate();
    1039           0 :                     if (pDdeLink->NeedsUpdate())        // war nix?
    1040           0 :                         bAnyLeft = true;
    1041             :                 }
    1042             :             }
    1043             :         }
    1044             :     }
    1045             : 
    1046        1590 :     return bAnyLeft;
    1047             : }
    1048             : 
    1049           0 : void ScDocument::SaveDdeLinks(SvStream& rStream) const
    1050             : {
    1051             :     //  bei 4.0-Export alle mit Modus != DEFAULT weglassen
    1052           0 :     bool bExport40 = ( rStream.GetVersion() <= SOFFICE_FILEFORMAT_40 );
    1053             : 
    1054           0 :     const ::sfx2::SvBaseLinks& rLinks = GetLinkManager()->GetLinks();
    1055           0 :     sal_uInt16 nCount = rLinks.size();
    1056             : 
    1057             :     //  erstmal zaehlen...
    1058             : 
    1059           0 :     sal_uInt16 nDdeCount = 0;
    1060             :     sal_uInt16 i;
    1061           0 :     for (i=0; i<nCount; i++)
    1062             :     {
    1063           0 :         ::sfx2::SvBaseLink* pBase = *rLinks[i];
    1064           0 :         if (pBase->ISA(ScDdeLink))
    1065           0 :             if ( !bExport40 || ((ScDdeLink*)pBase)->GetMode() == SC_DDE_DEFAULT )
    1066           0 :                 ++nDdeCount;
    1067             :     }
    1068             : 
    1069             :     //  Header
    1070             : 
    1071           0 :     ScMultipleWriteHeader aHdr( rStream );
    1072           0 :     rStream << nDdeCount;
    1073             : 
    1074             :     //  Links speichern
    1075             : 
    1076           0 :     for (i=0; i<nCount; i++)
    1077             :     {
    1078           0 :         ::sfx2::SvBaseLink* pBase = *rLinks[i];
    1079           0 :         if (pBase->ISA(ScDdeLink))
    1080             :         {
    1081           0 :             ScDdeLink* pLink = (ScDdeLink*)pBase;
    1082           0 :             if ( !bExport40 || pLink->GetMode() == SC_DDE_DEFAULT )
    1083           0 :                 pLink->Store( rStream, aHdr );
    1084             :         }
    1085           0 :     }
    1086           0 : }
    1087             : 
    1088           0 : void ScDocument::LoadDdeLinks(SvStream& rStream)
    1089             : {
    1090           0 :     ScMultipleReadHeader aHdr( rStream );
    1091             : 
    1092           0 :     GetLinkManager();
    1093             :     sal_uInt16 nCount;
    1094           0 :     rStream >> nCount;
    1095           0 :     for (sal_uInt16 i=0; i<nCount; i++)
    1096             :     {
    1097           0 :         ScDdeLink* pLink = new ScDdeLink( this, rStream, aHdr );
    1098             :         pLinkManager->InsertDDELink( pLink,
    1099           0 :                             pLink->GetAppl(), pLink->GetTopic(), pLink->GetItem() );
    1100           0 :     }
    1101           0 : }
    1102             : 
    1103         238 : bool ScDocument::HasDdeLinks() const
    1104             : {
    1105         238 :     if (GetLinkManager())           // Clipboard z.B. hat keinen LinkManager
    1106             :     {
    1107         238 :         const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
    1108         238 :         sal_uInt16 nCount = rLinks.size();
    1109         238 :         for (sal_uInt16 i=0; i<nCount; i++)
    1110           0 :             if ((*rLinks[i])->ISA(ScDdeLink))
    1111           0 :                 return true;
    1112             :     }
    1113             : 
    1114         238 :     return false;
    1115             : }
    1116             : 
    1117          12 : void ScDocument::SetInLinkUpdate(bool bSet)
    1118             : {
    1119             :     //  called from TableLink and AreaLink
    1120             : 
    1121             :     OSL_ENSURE( bInLinkUpdate != bSet, "SetInLinkUpdate twice" );
    1122          12 :     bInLinkUpdate = bSet;
    1123          12 : }
    1124             : 
    1125        1579 : bool ScDocument::IsInLinkUpdate() const
    1126             : {
    1127        1579 :     return bInLinkUpdate || IsInDdeLinkUpdate();
    1128             : }
    1129             : 
    1130           0 : void ScDocument::UpdateExternalRefLinks(Window* pWin)
    1131             : {
    1132           0 :     if (!GetLinkManager())
    1133           0 :         return;
    1134             : 
    1135           0 :     const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
    1136           0 :     sal_uInt16 nCount = rLinks.size();
    1137             : 
    1138           0 :     bool bAny = false;
    1139           0 :     for (sal_uInt16 i = 0; i < nCount; ++i)
    1140             :     {
    1141           0 :         ::sfx2::SvBaseLink* pBase = *rLinks[i];
    1142           0 :         ScExternalRefLink* pRefLink = dynamic_cast<ScExternalRefLink*>(pBase);
    1143           0 :         if (pRefLink)
    1144             :         {
    1145           0 :             if (pRefLink->Update())
    1146           0 :                 bAny = true;
    1147             :             else
    1148             :             {
    1149             :                 // Update failed.  Notify the user.
    1150             : 
    1151           0 :                 OUString aFile;
    1152           0 :                 pLinkManager->GetDisplayNames(pRefLink, NULL, &aFile, NULL, NULL);
    1153             :                 // Decode encoded URL for display friendliness.
    1154           0 :                 INetURLObject aUrl(aFile,INetURLObject::WAS_ENCODED);
    1155           0 :                 aFile = aUrl.GetMainURL(INetURLObject::DECODE_UNAMBIGUOUS);
    1156             : 
    1157           0 :                 OUStringBuffer aBuf;
    1158           0 :                 aBuf.append(String(ScResId(SCSTR_EXTDOC_NOT_LOADED)));
    1159           0 :                 aBuf.appendAscii("\n\n");
    1160           0 :                 aBuf.append(aFile);
    1161           0 :                 ErrorBox aBox(pWin, WB_OK, aBuf.makeStringAndClear());
    1162           0 :                 aBox.Execute();
    1163             :             }
    1164             :         }
    1165             :     }
    1166           0 :     if (bAny)
    1167             :     {
    1168           0 :         TrackFormulas();
    1169           0 :         pShell->Broadcast( SfxSimpleHint(FID_DATACHANGED) );
    1170             : 
    1171             :         // #i101960# set document modified, as in TrackTimeHdl for DDE links
    1172           0 :         if (!pShell->IsModified())
    1173             :         {
    1174           0 :             pShell->SetModified( true );
    1175           0 :             SfxBindings* pBindings = GetViewBindings();
    1176           0 :             if (pBindings)
    1177             :             {
    1178           0 :                 pBindings->Invalidate( SID_SAVEDOC );
    1179           0 :                 pBindings->Invalidate( SID_DOC_MODIFIED );
    1180             :             }
    1181             :         }
    1182             :     }
    1183             : }
    1184             : 
    1185           0 : void ScDocument::UpdateDdeLinks(Window* pWin)
    1186             : {
    1187           0 :     if (GetLinkManager())
    1188             :     {
    1189           0 :         const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
    1190           0 :         sal_uInt16 nCount = rLinks.size();
    1191             :         sal_uInt16 i;
    1192             : 
    1193             :         //  falls das Updaten laenger dauert, erstmal alle Werte
    1194             :         //  zuruecksetzen, damit nichts altes (falsches) stehen bleibt
    1195           0 :         bool bAny = false;
    1196           0 :         for (i=0; i<nCount; i++)
    1197             :         {
    1198           0 :             ::sfx2::SvBaseLink* pBase = *rLinks[i];
    1199           0 :             ScDdeLink* pDdeLink = dynamic_cast<ScDdeLink*>(pBase);
    1200           0 :             if (pDdeLink)
    1201             :             {
    1202           0 :                 if (pDdeLink->Update())
    1203           0 :                     bAny = true;
    1204             :                 else
    1205             :                 {
    1206             :                     // Update failed.  Notify the user.
    1207           0 :                     OUString aFile = pDdeLink->GetTopic();
    1208           0 :                     OUString aElem = pDdeLink->GetItem();
    1209           0 :                     OUString aType = pDdeLink->GetAppl();
    1210             : 
    1211           0 :                     OUStringBuffer aBuf;
    1212           0 :                     aBuf.append(String(ScResId(SCSTR_DDEDOC_NOT_LOADED)));
    1213           0 :                     aBuf.appendAscii("\n\n");
    1214           0 :                     aBuf.appendAscii("Source : ");
    1215           0 :                     aBuf.append(aFile);
    1216           0 :                     aBuf.appendAscii("\nElement : ");
    1217           0 :                     aBuf.append(aElem);
    1218           0 :                     aBuf.appendAscii("\nType : ");
    1219           0 :                     aBuf.append(aType);
    1220           0 :                     ErrorBox aBox(pWin, WB_OK, aBuf.makeStringAndClear());
    1221           0 :                     aBox.Execute();
    1222             :                 }
    1223             :             }
    1224             :         }
    1225           0 :         if (bAny)
    1226             :         {
    1227             :             //  Formeln berechnen und painten wie im TrackTimeHdl
    1228           0 :             TrackFormulas();
    1229           0 :             pShell->Broadcast( SfxSimpleHint( FID_DATACHANGED ) );
    1230             : 
    1231             :             //  wenn FID_DATACHANGED irgendwann mal asynchron werden sollte
    1232             :             //  (z.B. mit Invalidate am Window), muss hier ein Update erzwungen werden.
    1233             :         }
    1234             : 
    1235           0 :         pLinkManager->CloseCachedComps();
    1236             :     }
    1237           0 : }
    1238             : 
    1239           2 : bool ScDocument::UpdateDdeLink( const OUString& rAppl, const OUString& rTopic, const OUString& rItem )
    1240             : {
    1241             :     //  fuer refresh() per StarOne Api
    1242             :     //  ResetValue() fuer einzelnen Link nicht noetig
    1243             :     //! wenn's mal alles asynchron wird, aber auch hier
    1244             : 
    1245           2 :     bool bFound = false;
    1246           2 :     if (GetLinkManager())
    1247             :     {
    1248           2 :         const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
    1249           2 :         sal_uInt16 nCount = rLinks.size();
    1250           4 :         for (sal_uInt16 i=0; i<nCount; i++)
    1251             :         {
    1252           2 :             ::sfx2::SvBaseLink* pBase = *rLinks[i];
    1253           2 :             if (pBase->ISA(ScDdeLink))
    1254             :             {
    1255           2 :                 ScDdeLink* pDdeLink = (ScDdeLink*)pBase;
    1256          12 :                 if ( OUString(pDdeLink->GetAppl()) == rAppl &&
    1257          14 :                      OUString(pDdeLink->GetTopic()) == rTopic &&
    1258           6 :                      OUString(pDdeLink->GetItem()) == rItem )
    1259             :                 {
    1260           2 :                     pDdeLink->TryUpdate();
    1261           2 :                     bFound = true;          // koennen theoretisch mehrere sein (Mode), darum weitersuchen
    1262             :                 }
    1263             :             }
    1264             :         }
    1265           2 :         pLinkManager->CloseCachedComps();
    1266             :     }
    1267           2 :     return bFound;
    1268             : }
    1269             : 
    1270           0 : void ScDocument::DisconnectDdeLinks()
    1271             : {
    1272           0 :     if (GetLinkManager())
    1273             :     {
    1274           0 :         const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
    1275           0 :         sal_uInt16 nCount = rLinks.size();
    1276           0 :         for (sal_uInt16 i=0; i<nCount; i++)
    1277             :         {
    1278           0 :             ::sfx2::SvBaseLink* pBase = *rLinks[i];
    1279           0 :             if (pBase->ISA(ScDdeLink))
    1280           0 :                 pBase->Disconnect();            // bleibt im LinkManager eingetragen
    1281             :         }
    1282             :     }
    1283           0 : }
    1284             : 
    1285           0 : void ScDocument::CopyDdeLinks( ScDocument* pDestDoc ) const
    1286             : {
    1287           0 :     if (bIsClip)        // aus Stream erzeugen
    1288             :     {
    1289           0 :         if (pClipData)
    1290             :         {
    1291           0 :             pClipData->Seek(0);
    1292           0 :             pDestDoc->LoadDdeLinks(*pClipData);
    1293             :         }
    1294             :     }
    1295           0 :     else if (GetLinkManager())              // Links direkt kopieren
    1296             :     {
    1297           0 :         const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
    1298           0 :         size_t nCount = rLinks.size();
    1299           0 :         for (size_t i=0; i<nCount; i++)
    1300             :         {
    1301           0 :             ::sfx2::SvBaseLink* pBase = *rLinks[i];
    1302           0 :             if (pBase->ISA(ScDdeLink))
    1303             :             {
    1304           0 :                 ScDdeLink* pNew = new ScDdeLink( pDestDoc, *(ScDdeLink*)pBase );
    1305             : 
    1306             :                 pDestDoc->pLinkManager->InsertDDELink( pNew,
    1307           0 :                                 pNew->GetAppl(), pNew->GetTopic(), pNew->GetItem() );
    1308             :             }
    1309             :         }
    1310             :     }
    1311           0 : }
    1312             : 
    1313          19 : size_t ScDocument::GetDdeLinkCount() const
    1314             : {
    1315          19 :     size_t nDdeCount = 0;
    1316          19 :     if (GetLinkManager())
    1317             :     {
    1318          19 :         const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
    1319          19 :         size_t nCount = rLinks.size();
    1320          30 :         for (size_t i=0; i<nCount; i++)
    1321          11 :             if ((*rLinks[i])->ISA(ScDdeLink))
    1322          11 :                 ++nDdeCount;
    1323             :     }
    1324          19 :     return nDdeCount;
    1325             : }
    1326             : 
    1327             : // ----------------------------------------------------------------------------
    1328             : 
    1329             : namespace {
    1330             : 
    1331             : /** Tries to find the specified DDE link.
    1332             :     @param pnDdePos  (out-param) if not 0, the index of the DDE link is returned here
    1333             :                      (does not include other links from link manager).
    1334             :     @return  The DDE link, if it exists, otherwise 0. */
    1335           0 : ScDdeLink* lclGetDdeLink(
    1336             :         const sfx2::LinkManager* pLinkManager,
    1337             :         const OUString& rAppl, const OUString& rTopic, const OUString& rItem, sal_uInt8 nMode,
    1338             :         size_t* pnDdePos = NULL )
    1339             : {
    1340           0 :     if( pLinkManager )
    1341             :     {
    1342           0 :         const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
    1343           0 :         size_t nCount = rLinks.size();
    1344           0 :         if( pnDdePos ) *pnDdePos = 0;
    1345           0 :         for( size_t nIndex = 0; nIndex < nCount; ++nIndex )
    1346             :         {
    1347           0 :             ::sfx2::SvBaseLink* pLink = *rLinks[ nIndex ];
    1348           0 :             if( ScDdeLink* pDdeLink = PTR_CAST( ScDdeLink, pLink ) )
    1349             :             {
    1350           0 :                 if( (OUString(pDdeLink->GetAppl()) == rAppl) &&
    1351           0 :                     (OUString(pDdeLink->GetTopic()) == rTopic) &&
    1352           0 :                     (OUString(pDdeLink->GetItem()) == rItem) &&
    1353           0 :                     ((nMode == SC_DDE_IGNOREMODE) || (nMode == pDdeLink->GetMode())) )
    1354           0 :                     return pDdeLink;
    1355           0 :                 if( pnDdePos ) ++*pnDdePos;
    1356             :             }
    1357             :         }
    1358             :     }
    1359           0 :     return NULL;
    1360             : }
    1361             : 
    1362             : /** Returns a pointer to the specified DDE link.
    1363             :     @param nDdePos  Index of the DDE link (does not include other links from link manager).
    1364             :     @return  The DDE link, if it exists, otherwise 0. */
    1365          13 : ScDdeLink* lclGetDdeLink( const sfx2::LinkManager* pLinkManager, size_t nDdePos )
    1366             : {
    1367          13 :     if( pLinkManager )
    1368             :     {
    1369          13 :         const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
    1370          13 :         size_t nCount = rLinks.size();
    1371          13 :         size_t nDdeIndex = 0;       // counts only the DDE links
    1372          15 :         for( size_t nIndex = 0; nIndex < nCount; ++nIndex )
    1373             :         {
    1374          13 :             ::sfx2::SvBaseLink* pLink = *rLinks[ nIndex ];
    1375          13 :             if( ScDdeLink* pDdeLink = PTR_CAST( ScDdeLink, pLink ) )
    1376             :             {
    1377          13 :                 if( nDdeIndex == nDdePos )
    1378          11 :                     return pDdeLink;
    1379           2 :                 ++nDdeIndex;
    1380             :             }
    1381             :         }
    1382             :     }
    1383           2 :     return NULL;
    1384             : }
    1385             : 
    1386             : } // namespace
    1387             : 
    1388             : // ----------------------------------------------------------------------------
    1389             : 
    1390           0 : bool ScDocument::FindDdeLink( const OUString& rAppl, const OUString& rTopic, const OUString& rItem,
    1391             :         sal_uInt8 nMode, size_t& rnDdePos )
    1392             : {
    1393           0 :     return lclGetDdeLink( GetLinkManager(), rAppl, rTopic, rItem, nMode, &rnDdePos ) != NULL;
    1394             : }
    1395             : 
    1396          13 : bool ScDocument::GetDdeLinkData( size_t nDdePos, OUString& rAppl, OUString& rTopic, OUString& rItem ) const
    1397             : {
    1398          13 :     if( const ScDdeLink* pDdeLink = lclGetDdeLink( GetLinkManager(), nDdePos ) )
    1399             :     {
    1400          11 :         rAppl  = pDdeLink->GetAppl();
    1401          11 :         rTopic = pDdeLink->GetTopic();
    1402          11 :         rItem  = pDdeLink->GetItem();
    1403          11 :         return true;
    1404             :     }
    1405           2 :     return false;
    1406             : }
    1407             : 
    1408           0 : bool ScDocument::GetDdeLinkMode( size_t nDdePos, sal_uInt8& rnMode ) const
    1409             : {
    1410           0 :     if( const ScDdeLink* pDdeLink = lclGetDdeLink( GetLinkManager(), nDdePos ) )
    1411             :     {
    1412           0 :         rnMode = pDdeLink->GetMode();
    1413           0 :         return true;
    1414             :     }
    1415           0 :     return false;
    1416             : }
    1417             : 
    1418           0 : const ScMatrix* ScDocument::GetDdeLinkResultMatrix( size_t nDdePos ) const
    1419             : {
    1420           0 :     const ScDdeLink* pDdeLink = lclGetDdeLink( GetLinkManager(), nDdePos );
    1421           0 :     return pDdeLink ? pDdeLink->GetResult() : NULL;
    1422             : }
    1423             : 
    1424           0 : bool ScDocument::CreateDdeLink( const OUString& rAppl, const OUString& rTopic, const OUString& rItem, sal_uInt8 nMode, ScMatrixRef pResults )
    1425             : {
    1426             :     /*  Create a DDE link without updating it (i.e. for Excel import), to prevent
    1427             :         unwanted connections. First try to find existing link. Set result array
    1428             :         on existing and new links. */
    1429             :     //! store DDE links additionally at document (for efficiency)?
    1430             :     OSL_ENSURE( nMode != SC_DDE_IGNOREMODE, "ScDocument::CreateDdeLink - SC_DDE_IGNOREMODE not allowed here" );
    1431           0 :     if( GetLinkManager() && (nMode != SC_DDE_IGNOREMODE) )
    1432             :     {
    1433           0 :         ScDdeLink* pDdeLink = lclGetDdeLink( pLinkManager, rAppl, rTopic, rItem, nMode );
    1434           0 :         if( !pDdeLink )
    1435             :         {
    1436             :             // create a new DDE link, but without TryUpdate
    1437           0 :             pDdeLink = new ScDdeLink( this, rAppl, rTopic, rItem, nMode );
    1438           0 :             pLinkManager->InsertDDELink( pDdeLink, rAppl, rTopic, rItem );
    1439             :         }
    1440             : 
    1441             :         // insert link results
    1442           0 :         if( pResults )
    1443           0 :             pDdeLink->SetResult( pResults );
    1444             : 
    1445           0 :         return true;
    1446             :     }
    1447           0 :     return false;
    1448             : }
    1449             : 
    1450           0 : bool ScDocument::SetDdeLinkResultMatrix( size_t nDdePos, ScMatrixRef pResults )
    1451             : {
    1452           0 :     if( ScDdeLink* pDdeLink = lclGetDdeLink( GetLinkManager(), nDdePos ) )
    1453             :     {
    1454           0 :         pDdeLink->SetResult( pResults );
    1455           0 :         return true;
    1456             :     }
    1457           0 :     return false;
    1458             : }
    1459             : 
    1460             : //------------------------------------------------------------------------
    1461             : 
    1462         202 : bool ScDocument::HasAreaLinks() const
    1463             : {
    1464         202 :     if (GetLinkManager())           // Clipboard z.B. hat keinen LinkManager
    1465             :     {
    1466         202 :         const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
    1467         202 :         sal_uInt16 nCount = rLinks.size();
    1468         202 :         for (sal_uInt16 i=0; i<nCount; i++)
    1469           0 :             if ((*rLinks[i])->ISA(ScAreaLink))
    1470           0 :                 return true;
    1471             :     }
    1472             : 
    1473         202 :     return false;
    1474             : }
    1475             : 
    1476           0 : void ScDocument::UpdateAreaLinks()
    1477             : {
    1478           0 :     if (GetLinkManager())
    1479             :     {
    1480           0 :         const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
    1481           0 :         for (sal_uInt16 i=0; i<rLinks.size(); i++)
    1482             :         {
    1483           0 :             ::sfx2::SvBaseLink* pBase = *rLinks[i];
    1484           0 :             if (pBase->ISA(ScAreaLink))
    1485           0 :                 pBase->Update();
    1486             :         }
    1487             :     }
    1488           0 : }
    1489             : 
    1490          54 : void ScDocument::DeleteAreaLinksOnTab( SCTAB nTab )
    1491             : {
    1492          54 :     if (GetLinkManager())
    1493             :     {
    1494          54 :         const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
    1495          54 :         sal_uInt16 nPos = 0;
    1496         108 :         while ( nPos < rLinks.size() )
    1497             :         {
    1498           0 :             const ::sfx2::SvBaseLink* pBase = *rLinks[nPos];
    1499           0 :             if ( pBase->ISA(ScAreaLink) &&
    1500           0 :                  static_cast<const ScAreaLink*>(pBase)->GetDestArea().aStart.Tab() == nTab )
    1501           0 :                 pLinkManager->Remove( nPos );
    1502             :             else
    1503           0 :                 ++nPos;
    1504             :         }
    1505             :     }
    1506          54 : }
    1507             : 
    1508         144 : void ScDocument::UpdateRefAreaLinks( UpdateRefMode eUpdateRefMode,
    1509             :                              const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
    1510             : {
    1511         144 :     if (GetLinkManager())
    1512             :     {
    1513         144 :         bool bAnyUpdate = false;
    1514             : 
    1515         144 :         const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
    1516         144 :         sal_uInt16 nCount = rLinks.size();
    1517         144 :         for (sal_uInt16 i=0; i<nCount; i++)
    1518             :         {
    1519           0 :             ::sfx2::SvBaseLink* pBase = *rLinks[i];
    1520           0 :             if (pBase->ISA(ScAreaLink))
    1521             :             {
    1522           0 :                 ScAreaLink* pLink = (ScAreaLink*) pBase;
    1523           0 :                 ScRange aOutRange = pLink->GetDestArea();
    1524             : 
    1525           0 :                 SCCOL nCol1 = aOutRange.aStart.Col();
    1526           0 :                 SCROW nRow1 = aOutRange.aStart.Row();
    1527           0 :                 SCTAB nTab1 = aOutRange.aStart.Tab();
    1528           0 :                 SCCOL nCol2 = aOutRange.aEnd.Col();
    1529           0 :                 SCROW nRow2 = aOutRange.aEnd.Row();
    1530           0 :                 SCTAB nTab2 = aOutRange.aEnd.Tab();
    1531             : 
    1532             :                 ScRefUpdateRes eRes =
    1533             :                     ScRefUpdate::Update( this, eUpdateRefMode,
    1534           0 :                         rRange.aStart.Col(), rRange.aStart.Row(), rRange.aStart.Tab(),
    1535           0 :                         rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aEnd.Tab(), nDx, nDy, nDz,
    1536           0 :                         nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
    1537           0 :                 if ( eRes != UR_NOTHING )
    1538             :                 {
    1539           0 :                     pLink->SetDestArea( ScRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ) );
    1540           0 :                     bAnyUpdate = true;
    1541             :                 }
    1542             :             }
    1543             :         }
    1544             : 
    1545         144 :         if ( bAnyUpdate )
    1546             :         {
    1547             :             // #i52120# Look for duplicates (after updating all positions).
    1548             :             // If several links start at the same cell, the one with the lower index is removed
    1549             :             // (file format specifies only one link definition for a cell).
    1550             : 
    1551           0 :             sal_uInt16 nFirstIndex = 0;
    1552           0 :             while ( nFirstIndex < nCount )
    1553             :             {
    1554           0 :                 bool bFound = false;
    1555           0 :                 ::sfx2::SvBaseLink* pFirst = *rLinks[nFirstIndex];
    1556           0 :                 if ( pFirst->ISA(ScAreaLink) )
    1557             :                 {
    1558           0 :                     ScAddress aFirstPos = static_cast<ScAreaLink*>(pFirst)->GetDestArea().aStart;
    1559           0 :                     for ( sal_uInt16 nSecondIndex = nFirstIndex + 1; nSecondIndex < nCount && !bFound; ++nSecondIndex )
    1560             :                     {
    1561           0 :                         ::sfx2::SvBaseLink* pSecond = *rLinks[nSecondIndex];
    1562           0 :                         if ( pSecond->ISA(ScAreaLink) &&
    1563           0 :                              static_cast<ScAreaLink*>(pSecond)->GetDestArea().aStart == aFirstPos )
    1564             :                         {
    1565             :                             // remove the first link, exit the inner loop, don't increment nFirstIndex
    1566           0 :                             pLinkManager->Remove( pFirst );
    1567           0 :                             nCount = rLinks.size();
    1568           0 :                             bFound = true;
    1569             :                         }
    1570             :                     }
    1571             :                 }
    1572           0 :                 if (!bFound)
    1573           0 :                     ++nFirstIndex;
    1574             :             }
    1575             :         }
    1576             :     }
    1577         144 : }
    1578             : 
    1579             : //------------------------------------------------------------------------
    1580             : 
    1581             : // TimerDelays etc.
    1582           0 : void ScDocument::KeyInput( const KeyEvent& )
    1583             : {
    1584           0 :     if ( pChartListenerCollection->hasListeners() )
    1585           0 :         pChartListenerCollection->StartTimer();
    1586           0 :     if( apTemporaryChartLock.get() )
    1587           0 :         apTemporaryChartLock->StartOrContinueLocking();
    1588           0 : }
    1589             : 
    1590             : //  ----------------------------------------------------------------------------
    1591             : 
    1592           0 : bool ScDocument::CheckMacroWarn()
    1593             : {
    1594             :     //  The check for macro configuration, macro warning and disabling is now handled
    1595             :     //  in SfxObjectShell::AdjustMacroMode, called by SfxObjectShell::CallBasic.
    1596             : 
    1597           0 :     return true;
    1598             : }
    1599             : 
    1600             : //------------------------------------------------------------------------
    1601             : 
    1602           9 : SfxBindings* ScDocument::GetViewBindings()
    1603             : {
    1604             :     //  used to invalidate slots after changes to this document
    1605             : 
    1606           9 :     if ( !pShell )
    1607           0 :         return NULL;        // no ObjShell -> no view
    1608             : 
    1609             :     //  first check current view
    1610           9 :     SfxViewFrame* pViewFrame = SfxViewFrame::Current();
    1611           9 :     if ( pViewFrame && pViewFrame->GetObjectShell() != pShell )     // wrong document?
    1612           9 :         pViewFrame = NULL;
    1613             : 
    1614             :     //  otherwise use first view for this doc
    1615           9 :     if ( !pViewFrame )
    1616           9 :         pViewFrame = SfxViewFrame::GetFirst( pShell );
    1617             : 
    1618           9 :     if (pViewFrame)
    1619           9 :         return &pViewFrame->GetBindings();
    1620             :     else
    1621           0 :         return NULL;
    1622             : }
    1623             : 
    1624       13342 : ScDrawLayer* ScDocument::GetDrawLayer()
    1625             : {
    1626       13342 :     return pDrawLayer;
    1627             : }
    1628             : 
    1629             : //------------------------------------------------------------------------
    1630             : 
    1631           0 : void ScDocument::TransliterateText( const ScMarkData& rMultiMark, sal_Int32 nType )
    1632             : {
    1633             :     OSL_ENSURE( rMultiMark.IsMultiMarked(), "TransliterateText: no selection" );
    1634             : 
    1635           0 :     utl::TransliterationWrapper aTranslitarationWrapper( comphelper::getProcessComponentContext(), nType );
    1636           0 :     bool bConsiderLanguage = aTranslitarationWrapper.needLanguageForTheMode();
    1637           0 :     sal_uInt16 nLanguage = LANGUAGE_SYSTEM;
    1638             : 
    1639           0 :     ScEditEngineDefaulter* pEngine = NULL;        // not using pEditEngine member because of defaults
    1640             : 
    1641           0 :     SCTAB nCount = GetTableCount();
    1642           0 :     ScMarkData::const_iterator itr = rMultiMark.begin(), itrEnd = rMultiMark.end();
    1643           0 :     for (; itr != itrEnd && *itr < nCount; ++itr)
    1644           0 :         if ( maTabs[*itr] )
    1645             :         {
    1646           0 :             SCTAB nTab = *itr;
    1647           0 :             SCCOL nCol = 0;
    1648           0 :             SCROW nRow = 0;
    1649             : 
    1650           0 :             bool bFound = rMultiMark.IsCellMarked( nCol, nRow );
    1651           0 :             if (!bFound)
    1652           0 :                 bFound = GetNextMarkedCell( nCol, nRow, nTab, rMultiMark );
    1653             : 
    1654           0 :             while (bFound)
    1655             :             {
    1656           0 :                 ScRefCellValue aCell;
    1657           0 :                 aCell.assign(*this, ScAddress(nCol, nRow, nTab));
    1658             : 
    1659             :                 // fdo#32786 TITLE_CASE/SENTENCE_CASE need the extra handling in EditEngine (loop over words/sentences).
    1660             :                 // Still use TransliterationWrapper directly for text cells with other transliteration types,
    1661             :                 // for performance reasons.
    1662           0 :                 if (aCell.meType == CELLTYPE_EDIT ||
    1663           0 :                     (aCell.meType == CELLTYPE_STRING &&
    1664           0 :                      ( nType == i18n::TransliterationModulesExtra::SENTENCE_CASE || nType == i18n::TransliterationModulesExtra::TITLE_CASE)))
    1665             :                 {
    1666           0 :                     if (!pEngine)
    1667           0 :                         pEngine = new ScFieldEditEngine(this, GetEnginePool(), GetEditPool());
    1668             : 
    1669             :                     // defaults from cell attributes must be set so right language is used
    1670           0 :                     const ScPatternAttr* pPattern = GetPattern( nCol, nRow, nTab );
    1671           0 :                     SfxItemSet* pDefaults = new SfxItemSet( pEngine->GetEmptyItemSet() );
    1672           0 :                     pPattern->FillEditItemSet( pDefaults );
    1673           0 :                     pEngine->SetDefaults( pDefaults, true );
    1674             : 
    1675           0 :                     if (aCell.meType == CELLTYPE_STRING)
    1676           0 :                         pEngine->SetText(*aCell.mpString);
    1677           0 :                     else if (aCell.mpEditText)
    1678           0 :                         pEngine->SetText(*aCell.mpEditText);
    1679             : 
    1680           0 :                     pEngine->ClearModifyFlag();
    1681             : 
    1682           0 :                     sal_Int32 nLastPar = pEngine->GetParagraphCount();
    1683           0 :                     if (nLastPar)
    1684           0 :                         --nLastPar;
    1685           0 :                     xub_StrLen nTxtLen = pEngine->GetTextLen(nLastPar);
    1686           0 :                     ESelection aSelAll( 0, 0, nLastPar, nTxtLen );
    1687             : 
    1688           0 :                     pEngine->TransliterateText( aSelAll, nType );
    1689             : 
    1690           0 :                     if ( pEngine->IsModified() )
    1691             :                     {
    1692           0 :                         ScEditAttrTester aTester( pEngine );
    1693           0 :                         if ( aTester.NeedsObject() )
    1694             :                         {
    1695             :                             // remove defaults (paragraph attributes) before creating text object
    1696           0 :                             SfxItemSet* pEmpty = new SfxItemSet( pEngine->GetEmptyItemSet() );
    1697           0 :                             pEngine->SetDefaults( pEmpty, true );
    1698             : 
    1699             :                             // The cell will take ownership of the text object instance.
    1700           0 :                             SetEditText(ScAddress(nCol,nRow,nTab), pEngine->CreateTextObject());
    1701             :                         }
    1702             :                         else
    1703             :                         {
    1704           0 :                             ScSetStringParam aParam;
    1705           0 :                             aParam.setTextInput();
    1706           0 :                             SetString(ScAddress(nCol,nRow,nTab), pEngine->GetText(), &aParam);
    1707           0 :                         }
    1708           0 :                     }
    1709             :                 }
    1710             : 
    1711           0 :                 else if (aCell.meType == CELLTYPE_STRING)
    1712             :                 {
    1713           0 :                     OUString aOldStr = *aCell.mpString;
    1714           0 :                     sal_Int32 nOldLen = aOldStr.getLength();
    1715             : 
    1716           0 :                     if ( bConsiderLanguage )
    1717             :                     {
    1718           0 :                         sal_uInt8 nScript = GetStringScriptType( aOldStr );        //! cell script type?
    1719             :                         sal_uInt16 nWhich = ( nScript == SCRIPTTYPE_ASIAN ) ? ATTR_CJK_FONT_LANGUAGE :
    1720             :                                         ( ( nScript == SCRIPTTYPE_COMPLEX ) ? ATTR_CTL_FONT_LANGUAGE :
    1721           0 :                                                                                 ATTR_FONT_LANGUAGE );
    1722           0 :                         nLanguage = ((const SvxLanguageItem*)GetAttr( nCol, nRow, nTab, nWhich ))->GetValue();
    1723             :                     }
    1724             : 
    1725           0 :                     uno::Sequence<sal_Int32> aOffsets;
    1726           0 :                     OUString aNewStr = aTranslitarationWrapper.transliterate( aOldStr, nLanguage, 0, nOldLen, &aOffsets );
    1727             : 
    1728           0 :                     if ( aNewStr != aOldStr )
    1729             :                     {
    1730           0 :                         ScSetStringParam aParam;
    1731           0 :                         aParam.setTextInput();
    1732           0 :                         SetString(ScAddress(nCol,nRow,nTab), aNewStr, &aParam);
    1733           0 :                     }
    1734             :                 }
    1735           0 :                 bFound = GetNextMarkedCell( nCol, nRow, nTab, rMultiMark );
    1736           0 :             }
    1737             :         }
    1738           0 :     delete pEngine;
    1739          93 : }
    1740             : 
    1741             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10