1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: documen8.cxx,v $
10 * $Revision: 1.52.32.3 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
35 #define _ZFORLIST_DECLARE_TABLE
36 #include "scitems.hxx"
37 #include <svx/eeitem.hxx>
39 #include <tools/string.hxx>
40 #include <svx/editobj.hxx>
41 #include <svx/editstat.hxx>
42 #include <svx/frmdiritem.hxx>
43 #include <svx/langitem.hxx>
44 #include <svx/linkmgr.hxx>
45 #include <svx/scripttypeitem.hxx>
46 #include <svx/unolingu.hxx>
47 #include <sfx2/bindings.hxx>
48 #include <sfx2/objsh.hxx>
49 #include <sfx2/printer.hxx>
50 #include <sfx2/viewfrm.hxx>
51 #include <sfx2/viewsh.hxx>
52 #include <svtools/flagitem.hxx>
53 #include <svtools/intitem.hxx>
54 #define _SVSTDARR_USHORTS
55 #include <svtools/svstdarr.hxx>
56 #include <svtools/zforlist.hxx>
57 #include <svtools/zformat.hxx>
58 #include <svtools/misccfg.hxx>
59 #include <sfx2/app.hxx>
60 #include <unotools/transliterationwrapper.hxx>
61 #include <svtools/securityoptions.hxx>
63 #include <vcl/virdev.hxx>
64 #include <vcl/msgbox.hxx>
66 #include "inputopt.hxx"
71 #include "poolhelp.hxx"
72 #include "docpool.hxx"
73 #include "stlpool.hxx"
74 #include "stlsheet.hxx"
75 #include "docoptio.hxx"
76 #include "viewopti.hxx"
77 #include "scextopt.hxx"
78 #include "rechead.hxx"
79 #include "ddelink.hxx"
80 #include "scmatrix.hxx"
81 #include "arealink.hxx"
82 #include "dociter.hxx"
83 #include "patattr.hxx"
85 #include "editutil.hxx"
86 #include "progress.hxx"
87 #include "document.hxx"
88 #include "chartlis.hxx"
89 #include "chartlock.hxx"
90 #include "refupdat.hxx"
91 #include "validat.hxx" // fuer HasMacroCalls
92 #include "markdata.hxx"
94 #include "printopt.hxx"
95 #include "externalrefmgr.hxx"
96 #include "globstr.hrc"
98 #include "charthelper.hxx"
99 #include "dpobject.hxx"
100 #include "macromgr.hxx"
102 #define GET_SCALEVALUE(set,id) ((const SfxUInt16Item&)(set.Get( id ))).GetValue()
104 // states for online spelling in the visible range (0 is set initially)
109 // STATIC DATA -----------------------------------------------------------
111 //------------------------------------------------------------------------
113 void ScDocument::ImplCreateOptions()
115 pDocOptions
= new ScDocOptions();
116 pViewOptions
= new ScViewOptions();
119 //------------------------------------------------------------------------
121 void ScDocument::ImplDeleteOptions()
125 delete pExtDocOptions
;
128 //------------------------------------------------------------------------
130 SfxPrinter
* ScDocument::GetPrinter(BOOL bCreateIfNotExist
)
132 if ( !pPrinter
&& bCreateIfNotExist
)
135 new SfxItemSet( *xPoolHelper
->GetDocPool(),
136 SID_PRINTER_NOTFOUND_WARN
, SID_PRINTER_NOTFOUND_WARN
,
137 SID_PRINTER_CHANGESTODOC
, SID_PRINTER_CHANGESTODOC
,
138 SID_PRINT_SELECTEDSHEET
, SID_PRINT_SELECTEDSHEET
,
139 SID_SCPRINTOPTIONS
, SID_SCPRINTOPTIONS
,
142 SfxMiscCfg
* pOffCfg
= SFX_APP()->GetMiscConfig();
146 if ( pOffCfg
->IsPaperOrientationWarning() )
147 nFlags
|= SFX_PRINTER_CHG_ORIENTATION
;
148 if ( pOffCfg
->IsPaperSizeWarning() )
149 nFlags
|= SFX_PRINTER_CHG_SIZE
;
150 pSet
->Put( SfxFlagItem( SID_PRINTER_CHANGESTODOC
, nFlags
) );
151 pSet
->Put( SfxBoolItem( SID_PRINTER_NOTFOUND_WARN
, pOffCfg
->IsNotFoundWarning() ) );
154 pPrinter
= new SfxPrinter( pSet
);
155 pPrinter
->SetMapMode( MAP_100TH_MM
);
157 pPrinter
->SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
163 //------------------------------------------------------------------------
165 void ScDocument::SetPrinter( SfxPrinter
* pNewPrinter
)
167 if ( pNewPrinter
== pPrinter
)
169 // #i6706# SetPrinter is called with the same printer again if
170 // the JobSetup has changed. In that case just call UpdateDrawPrinter
171 // (SetRefDevice for drawing layer) because of changed text sizes.
176 SfxPrinter
* pOld
= pPrinter
;
177 pPrinter
= pNewPrinter
;
179 pPrinter
->SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
182 InvalidateTextWidth(NULL
, NULL
, FALSE
); // in both cases
185 //------------------------------------------------------------------------
187 void ScDocument::SetPrintOptions()
189 if ( !pPrinter
) GetPrinter(); // setzt pPrinter
190 DBG_ASSERT( pPrinter
, "Error in printer creation :-/" );
194 SfxMiscCfg
* pOffCfg
= SFX_APP()->GetMiscConfig();
197 SfxItemSet
aOptSet( pPrinter
->GetOptions() );
200 if ( pOffCfg
->IsPaperOrientationWarning() )
201 nFlags
|= SFX_PRINTER_CHG_ORIENTATION
;
202 if ( pOffCfg
->IsPaperSizeWarning() )
203 nFlags
|= SFX_PRINTER_CHG_SIZE
;
204 aOptSet
.Put( SfxFlagItem( SID_PRINTER_CHANGESTODOC
, nFlags
) );
205 aOptSet
.Put( SfxBoolItem( SID_PRINTER_NOTFOUND_WARN
, pOffCfg
->IsNotFoundWarning() ) );
207 pPrinter
->SetOptions( aOptSet
);
212 //------------------------------------------------------------------------
214 VirtualDevice
* ScDocument::GetVirtualDevice_100th_mm()
216 if (!pVirtualDevice_100th_mm
)
218 // pVirtualDevice_100th_mm = new VirtualDevice;
219 // pVirtualDevice_100th_mm->SetMapMode( MAP_100TH_MM );
221 pVirtualDevice_100th_mm
= new VirtualDevice( 1 );
222 pVirtualDevice_100th_mm
->SetReferenceDevice(VirtualDevice::REFDEV_MODE_MSO1
);
223 MapMode
aMapMode( pVirtualDevice_100th_mm
->GetMapMode() );
224 aMapMode
.SetMapUnit( MAP_100TH_MM
);
225 pVirtualDevice_100th_mm
->SetMapMode( aMapMode
);
227 return pVirtualDevice_100th_mm
;
230 OutputDevice
* ScDocument::GetRefDevice()
232 // Create printer like ref device, see Writer...
233 OutputDevice
* pRefDevice
= NULL
;
234 if ( SC_MOD()->GetInputOptions().GetTextWysiwyg() )
235 pRefDevice
= GetPrinter();
237 pRefDevice
= GetVirtualDevice_100th_mm();
241 //------------------------------------------------------------------------
243 void ScDocument::ModifyStyleSheet( SfxStyleSheetBase
& rStyleSheet
,
244 const SfxItemSet
& rChanges
)
246 SfxItemSet
& rSet
= rStyleSheet
.GetItemSet();
248 switch ( rStyleSheet
.GetFamily() )
250 case SFX_STYLE_FAMILY_PAGE
:
252 const USHORT nOldScale
= GET_SCALEVALUE(rSet
,ATTR_PAGE_SCALE
);
253 const USHORT nOldScaleToPages
= GET_SCALEVALUE(rSet
,ATTR_PAGE_SCALETOPAGES
);
254 rSet
.Put( rChanges
);
255 const USHORT nNewScale
= GET_SCALEVALUE(rSet
,ATTR_PAGE_SCALE
);
256 const USHORT nNewScaleToPages
= GET_SCALEVALUE(rSet
,ATTR_PAGE_SCALETOPAGES
);
258 if ( (nOldScale
!= nNewScale
) || (nOldScaleToPages
!= nNewScaleToPages
) )
259 InvalidateTextWidth( rStyleSheet
.GetName() );
261 if( SvtLanguageOptions().IsCTLFontEnabled() )
263 const SfxPoolItem
*pItem
= NULL
;
264 if( rChanges
.GetItemState(ATTR_WRITINGDIR
, TRUE
, &pItem
) == SFX_ITEM_SET
)
265 ScChartHelper::DoUpdateAllCharts( this );
270 case SFX_STYLE_FAMILY_PARA
:
272 BOOL bNumFormatChanged
;
273 if ( ScGlobal::CheckWidthInvalidate( bNumFormatChanged
,
275 InvalidateTextWidth( NULL
, NULL
, bNumFormatChanged
);
277 for (SCTAB nTab
=0; nTab
<=MAXTAB
; ++nTab
)
278 if (pTab
[nTab
] && pTab
[nTab
]->IsStreamValid())
279 pTab
[nTab
]->SetStreamValid( FALSE
);
282 ((const SfxUInt32Item
*)&rSet
.Get(
283 ATTR_VALUE_FORMAT
))->GetValue();
285 ((const SfxUInt32Item
*)&rChanges
.Get(
286 ATTR_VALUE_FORMAT
))->GetValue();
287 LanguageType eNewLang
, eOldLang
;
288 eNewLang
= eOldLang
= LANGUAGE_DONTKNOW
;
289 if ( nNewFormat
!= nOldFormat
)
291 SvNumberFormatter
* pFormatter
= GetFormatTable();
292 eOldLang
= pFormatter
->GetEntry( nOldFormat
)->GetLanguage();
293 eNewLang
= pFormatter
->GetEntry( nNewFormat
)->GetLanguage();
296 // Bedeutung der Items in rChanges:
297 // Item gesetzt - Aenderung uebernehmen
298 // Dontcare - Default setzen
299 // Default - keine Aenderung
300 // ("keine Aenderung" geht nicht mit PutExtended, darum Schleife)
301 for (USHORT nWhich
= ATTR_PATTERN_START
; nWhich
<= ATTR_PATTERN_END
; nWhich
++)
303 const SfxPoolItem
* pItem
;
304 SfxItemState eState
= rChanges
.GetItemState( nWhich
, FALSE
, &pItem
);
305 if ( eState
== SFX_ITEM_SET
)
307 else if ( eState
== SFX_ITEM_DONTCARE
)
308 rSet
.ClearItem( nWhich
);
309 // bei Default nichts
312 if ( eNewLang
!= eOldLang
)
314 SvxLanguageItem( eNewLang
, ATTR_LANGUAGE_FORMAT
) );
319 // added to avoid warnings
324 //------------------------------------------------------------------------
326 void ScDocument::CopyStdStylesFrom( ScDocument
* pSrcDoc
)
328 // #b5017505# number format exchange list has to be handled here, too
329 NumFmtMergeHandler
aNumFmtMergeHdl(this, pSrcDoc
);
330 xPoolHelper
->GetStylePool()->CopyStdStylesFrom( pSrcDoc
->xPoolHelper
->GetStylePool() );
333 //------------------------------------------------------------------------
335 void ScDocument::InvalidateTextWidth( const String
& rStyleName
)
337 const SCTAB nCount
= GetTableCount();
338 for ( SCTAB i
=0; i
<nCount
&& pTab
[i
]; i
++ )
339 if ( pTab
[i
]->GetPageStyle() == rStyleName
)
340 InvalidateTextWidth( i
);
343 //------------------------------------------------------------------------
345 void ScDocument::InvalidateTextWidth( SCTAB nTab
)
347 ScAddress
aAdrFrom( 0, 0, nTab
);
348 ScAddress
aAdrTo ( MAXCOL
, MAXROW
, nTab
);
349 InvalidateTextWidth( &aAdrFrom
, &aAdrTo
, FALSE
);
352 //------------------------------------------------------------------------
354 BOOL
ScDocument::IsPageStyleInUse( const String
& rStrPageStyle
, SCTAB
* pInTab
)
357 const SCTAB nCount
= GetTableCount();
360 for ( i
= 0; !bInUse
&& i
< nCount
&& pTab
[i
]; i
++ )
361 bInUse
= ( pTab
[i
]->GetPageStyle() == rStrPageStyle
);
369 //------------------------------------------------------------------------
371 BOOL
ScDocument::RemovePageStyleInUse( const String
& rStyle
)
373 BOOL bWasInUse
= FALSE
;
374 const SCTAB nCount
= GetTableCount();
376 for ( SCTAB i
=0; i
<nCount
&& pTab
[i
]; i
++ )
377 if ( pTab
[i
]->GetPageStyle() == rStyle
)
380 pTab
[i
]->SetPageStyle( ScGlobal::GetRscString(STR_STYLENAME_STANDARD
) );
386 BOOL
ScDocument::RenamePageStyleInUse( const String
& rOld
, const String
& rNew
)
388 BOOL bWasInUse
= FALSE
;
389 const SCTAB nCount
= GetTableCount();
391 for ( SCTAB i
=0; i
<nCount
&& pTab
[i
]; i
++ )
392 if ( pTab
[i
]->GetPageStyle() == rOld
)
395 pTab
[i
]->SetPageStyle( rNew
);
401 //------------------------------------------------------------------------
403 BYTE
ScDocument::GetEditTextDirection(SCTAB nTab
) const
405 EEHorizontalTextDirection eRet
= EE_HTEXTDIR_DEFAULT
;
407 String aStyleName
= GetPageStyle( nTab
);
408 SfxStyleSheetBase
* pStyle
= xPoolHelper
->GetStylePool()->Find( aStyleName
, SFX_STYLE_FAMILY_PAGE
);
411 SfxItemSet
& rStyleSet
= pStyle
->GetItemSet();
412 SvxFrameDirection eDirection
= (SvxFrameDirection
)
413 ((const SvxFrameDirectionItem
&)rStyleSet
.Get( ATTR_WRITINGDIR
)).GetValue();
415 if ( eDirection
== FRMDIR_HORI_LEFT_TOP
)
416 eRet
= EE_HTEXTDIR_L2R
;
417 else if ( eDirection
== FRMDIR_HORI_RIGHT_TOP
)
418 eRet
= EE_HTEXTDIR_R2L
;
419 // else (invalid for EditEngine): keep "default"
422 return sal::static_int_cast
<BYTE
>(eRet
);
425 ScMacroManager
* ScDocument::GetMacroManager()
427 if (!mpMacroMgr
.get())
428 mpMacroMgr
.reset(new ScMacroManager(this));
429 return mpMacroMgr
.get();
432 //------------------------------------------------------------------------
434 void ScDocument::InvalidateTextWidth( const ScAddress
* pAdrFrom
, const ScAddress
* pAdrTo
,
435 BOOL bNumFormatChanged
)
437 BOOL bBroadcast
= (bNumFormatChanged
&& GetDocOptions().IsCalcAsShown() && !IsImportingXML() && !IsClipboard());
438 if ( pAdrFrom
&& !pAdrTo
)
440 const SCTAB nTab
= pAdrFrom
->Tab();
443 pTab
[nTab
]->InvalidateTextWidth( pAdrFrom
, NULL
, bNumFormatChanged
, bBroadcast
);
447 const SCTAB nTabStart
= pAdrFrom
? pAdrFrom
->Tab() : 0;
448 const SCTAB nTabEnd
= pAdrTo
? pAdrTo
->Tab() : MAXTAB
;
450 for ( SCTAB nTab
=nTabStart
; nTab
<=nTabEnd
; nTab
++ )
452 pTab
[nTab
]->InvalidateTextWidth( pAdrFrom
, pAdrTo
, bNumFormatChanged
, bBroadcast
);
456 //------------------------------------------------------------------------
458 #define CALCMAX 1000 // Berechnungen
459 #define ABORT_EVENTS (INPUT_ANY & ~INPUT_TIMER & ~INPUT_OTHER)
461 BOOL
ScDocument::IdleCalcTextWidth() // TRUE = demnaechst wieder versuchen
463 // #i75610# if a printer hasn't been set or created yet, don't create one for this
464 if ( bIdleDisabled
|| IsInLinkUpdate() || GetPrinter(FALSE
) == NULL
)
466 bIdleDisabled
= TRUE
;
471 const ULONG nStart
= Time::GetSystemTicks();
474 OutputDevice
* pDev
= NULL
;
476 ScStyleSheet
* pStyle
= NULL
;
477 ScColumnIterator
* pColIter
= NULL
;
478 ScTable
* pTable
= NULL
;
479 ScColumn
* pColumn
= NULL
;
480 ScBaseCell
* pCell
= NULL
;
481 SCTAB nTab
= aCurTextWidthCalcPos
.Tab();
482 SCROW nRow
= aCurTextWidthCalcPos
.Row();
483 SCsCOL nCol
= aCurTextWidthCalcPos
.Col();
486 BOOL bNeedMore
= FALSE
;
488 if ( !ValidRow(nRow
) )
491 nCol
= MAXCOL
, nTab
++;
492 if ( !ValidTab(nTab
) || !pTab
[nTab
] )
495 // DBG_ERROR( String("Start = ") + String(nTab) + String(',') + String(nCol) + String(',') + String(nRow) );
497 // SearchMask/Family muss gemerkt werden,
498 // damit z.B. der Organizer nicht durcheinanderkommt, wenn zwischendurch eine
499 // Query-Box aufgemacht wird !!!
501 ScStyleSheetPool
* pStylePool
= xPoolHelper
->GetStylePool();
502 USHORT nOldMask
= pStylePool
->GetSearchMask();
503 SfxStyleFamily eOldFam
= pStylePool
->GetSearchFamily();
506 pStylePool
->SetSearchMask( SFX_STYLE_FAMILY_PAGE
, SFXSTYLEBIT_ALL
);
507 pStyle
= (ScStyleSheet
*)pStylePool
->Find( pTable
->aPageStyle
,
508 SFX_STYLE_FAMILY_PAGE
);
510 DBG_ASSERT( pStyle
, "Missing StyleSheet :-/" );
512 BOOL bProgress
= FALSE
;
513 if ( pStyle
&& 0 == GET_SCALEVALUE(pStyle
->GetItemSet(),ATTR_PAGE_SCALETOPAGES
) )
517 nZoom
= GET_SCALEVALUE(pStyle
->GetItemSet(),ATTR_PAGE_SCALE
);
518 Fraction
aZoomFract( nZoom
, 100 );
519 pColumn
= &pTable
->aCol
[nCol
];
520 pColIter
= new ScColumnIterator( pColumn
, nRow
, MAXROW
);
522 while ( (nZoom
> 0) && (nCount
< CALCMAX
) && (nRestart
< 2) )
524 if ( pColIter
->Next( nRow
, pCell
) )
526 if ( TEXTWIDTH_DIRTY
== pCell
->GetTextWidth() )
531 aOldMap
= pDev
->GetMapMode();
532 pDev
->SetMapMode( MAP_PIXEL
); // wichtig fuer GetNeededSize
534 Point aPix1000
= pDev
->LogicToPixel( Point(1000,1000), MAP_TWIP
);
535 nPPTX
= aPix1000
.X() / 1000.0;
536 nPPTY
= aPix1000
.Y() / 1000.0;
538 if ( !bProgress
&& pCell
->GetCellType() == CELLTYPE_FORMULA
539 && ((ScFormulaCell
*)pCell
)->GetDirty() )
541 ScProgress::CreateInterpretProgress( this, FALSE
);
545 // DBG_ERROR( String("t,c,r = ") + String(nTab) + String(',') + String(nCol) + String(',') + String(nRow) );
546 // DBG_ERROR( String("nOldWidth = ") + String(pCell->GetTextWidth()) );
548 USHORT nNewWidth
= (USHORT
)GetNeededSize( nCol
, nRow
, nTab
,
550 aZoomFract
,aZoomFract
, TRUE
,
551 TRUE
); // bTotalSize
553 // DBG_ERROR( String("nNewWidth = ") + String(nNewWidth) );
555 pCell
->SetTextWidth( nNewWidth
);
562 BOOL bNewTab
= FALSE
;
574 if ( !ValidTab(nTab
) || !pTab
[nTab
] )
586 pStyle
= (ScStyleSheet
*)pStylePool
->Find( pTable
->aPageStyle
,
587 SFX_STYLE_FAMILY_PAGE
);
591 SfxItemSet
& rSet
= pStyle
->GetItemSet();
592 if ( GET_SCALEVALUE( rSet
, ATTR_PAGE_SCALETOPAGES
) == 0 )
593 nZoom
= GET_SCALEVALUE(rSet
, ATTR_PAGE_SCALE
);
599 DBG_ERROR( "Missing StyleSheet :-/" );
607 pColumn
= &pTable
->aCol
[nCol
];
608 pColIter
= new ScColumnIterator( pColumn
, nRow
, MAXROW
);
611 nTab
++; // Tabelle nicht mit absolutem Zoom -> naechste
619 // Idle Berechnung abbrechen, wenn Berechnungen laenger als
620 // 50ms dauern, oder nach 32 Berechnungen mal nachschauen, ob
621 // bestimmte Events anstehen, die Beachtung wuenschen:
623 // nMs = SysTicksToMs( GetSysTicks() - nStart );
625 if ( ( 50L < Time::GetSystemTicks() - nStart
)
626 || ( !(nCount
&31) && Application::AnyInput( ABORT_EVENTS
) ) )
631 nTab
++; // Tabelle nicht mit absolutem Zoom -> naechste
634 ScProgress::DeleteInterpretProgress();
638 // DBG_ERROR( String(nCount) + String(" End = ") + String(nTab) + String(',') + String(nCol) + String(',') + String(nRow) );
641 pDev
->SetMapMode(aOldMap
);
643 aCurTextWidthCalcPos
.SetTab( nTab
);
644 aCurTextWidthCalcPos
.SetRow( nRow
);
645 aCurTextWidthCalcPos
.SetCol( (SCCOL
)nCol
);
647 // DBG_ERROR( String(nMs) + String(" ms (") + String(nIter) + String(')') );
649 pStylePool
->SetSearchMask( eOldFam
, nOldMask
);
650 bIdleDisabled
= FALSE
;
655 //------------------------------------------------------------------------
662 ScSpellStatus() : bModified(FALSE
) {};
664 DECL_LINK (EventHdl
, EditStatus
*);
667 IMPL_LINK( ScSpellStatus
, EventHdl
, EditStatus
*, pStatus
)
669 ULONG nStatus
= pStatus
->GetStatusWord();
670 if ( nStatus
& EE_STAT_WRONGWORDCHANGED
)
676 // SPELL_MAXCELLS muss mindestens 256 sein, solange am Iterator keine
677 // Start-Spalte gesetzt werden kann
679 //! SPELL_MAXTEST fuer Timer und Idle unterschiedlich ???
681 // SPELL_MAXTEST now divided between visible and rest of document
683 #define SPELL_MAXTEST_VIS 1
684 #define SPELL_MAXTEST_ALL 3
685 #define SPELL_MAXCELLS 256
687 BOOL
ScDocument::OnlineSpellInRange( const ScRange
& rSpellRange
, ScAddress
& rSpellPos
,
690 ScEditEngineDefaulter
* pEngine
= NULL
; //! am Dokument speichern
691 SfxItemSet
* pDefaults
= NULL
;
692 ScSpellStatus aStatus
;
694 USHORT nCellCount
= 0; // Zellen insgesamt
695 USHORT nTestCount
= 0; // Aufrufe Spelling
696 BOOL bChanged
= FALSE
; // Aenderungen?
698 SCCOL nCol
= rSpellRange
.aStart
.Col(); // iterator always starts on the left edge
699 SCROW nRow
= rSpellPos
.Row();
700 SCTAB nTab
= rSpellPos
.Tab();
701 if ( !pTab
[nTab
] ) // sheet deleted?
703 nTab
= rSpellRange
.aStart
.Tab();
704 nRow
= rSpellRange
.aStart
.Row();
707 // may happen for visible range
711 ScHorizontalCellIterator
aIter( this, nTab
,
712 rSpellRange
.aStart
.Col(), nRow
,
713 rSpellRange
.aEnd
.Col(), rSpellRange
.aEnd
.Row() );
714 ScBaseCell
* pCell
= aIter
.GetNext( nCol
, nRow
);
715 // skip everything left of rSpellPos:
716 while ( pCell
&& nRow
== rSpellPos
.Row() && nCol
< rSpellPos
.Col() )
717 pCell
= aIter
.GetNext( nCol
, nRow
);
719 for (; pCell
; pCell
= aIter
.GetNext(nCol
, nRow
))
721 if (pDPCollection
&& pDPCollection
->HasDPTable(nCol
, nRow
, nTab
))
722 // Don't spell check within datapilot table.
725 CellType eType
= pCell
->GetCellType();
726 if ( eType
== CELLTYPE_STRING
|| eType
== CELLTYPE_EDIT
)
730 // #71154# ScTabEditEngine is needed
731 // because MapMode must be set for some old documents
732 pEngine
= new ScTabEditEngine( this );
733 pEngine
->SetControlWord( pEngine
->GetControlWord() |
734 ( EE_CNTRL_ONLINESPELLING
| EE_CNTRL_ALLOWBIGOBJS
) );
735 pEngine
->SetStatusEventHdl( LINK( &aStatus
, ScSpellStatus
, EventHdl
) );
736 // Delimiters hier wie in inputhdl.cxx !!!
737 pEngine
->SetWordDelimiters(
738 ScEditUtil::ModifyDelimiters( pEngine
->GetWordDelimiters() ) );
739 pDefaults
= new SfxItemSet( pEngine
->GetEmptyItemSet() );
741 com::sun::star::uno::Reference
<com::sun::star::linguistic2::XSpellChecker1
> xXSpellChecker1( LinguMgr::GetSpellChecker() );
743 pEngine
->SetSpeller( xXSpellChecker1
);
746 const ScPatternAttr
* pPattern
= GetPattern( nCol
, nRow
, nTab
);
747 pPattern
->FillEditItemSet( pDefaults
);
748 pEngine
->SetDefaults( pDefaults
, FALSE
); //! noetig ?
750 USHORT nCellLang
= ((const SvxLanguageItem
&)
751 pPattern
->GetItem(ATTR_FONT_LANGUAGE
)).GetValue();
752 if ( nCellLang
== LANGUAGE_SYSTEM
)
753 nCellLang
= Application::GetSettings().GetLanguage(); // never use SYSTEM for spelling
754 pEngine
->SetDefaultLanguage( nCellLang
);
756 if ( eType
== CELLTYPE_STRING
)
759 ((ScStringCell
*)pCell
)->GetString(aText
);
760 pEngine
->SetText( aText
);
763 pEngine
->SetText( *((ScEditCell
*)pCell
)->GetData() );
765 aStatus
.bModified
= FALSE
;
766 pEngine
->CompleteOnlineSpelling();
767 if ( aStatus
.bModified
) // Fehler dazu oder weggekommen?
769 BOOL bNeedEdit
= TRUE
; // Test auf einfachen Text
770 if ( !pEngine
->HasOnlineSpellErrors() )
772 ScEditAttrTester
aTester( pEngine
);
773 bNeedEdit
= aTester
.NeedsObject();
778 EditTextObject
* pNewData
= pEngine
->CreateTextObject();
779 if ( eType
== CELLTYPE_EDIT
)
780 ((ScEditCell
*)pCell
)->SetData( pNewData
,
781 pEngine
->GetEditTextObjectPool() );
783 PutCell( nCol
, nRow
, nTab
, new ScEditCell( pNewData
,
784 this, pEngine
->GetEditTextObjectPool() ) );
787 else // einfacher String
788 PutCell( nCol
, nRow
, nTab
, new ScStringCell( pEngine
->GetText() ) );
793 // #47751# Seitenvorschau ist davon nicht betroffen
794 // (sollte jedenfalls nicht)
795 ScPaintHint
aHint( ScRange( nCol
, nRow
, nTab
), PAINT_GRID
);
796 aHint
.SetPrintFlag( FALSE
);
797 pShell
->Broadcast( aHint
);
803 if ( ++nTestCount
>= nMaxTest
) // checked enough text?
807 if ( ++nCellCount
>= SPELL_MAXCELLS
) // seen enough cells?
813 ++nCol
; // continue after last cell
814 if ( nCol
> rSpellRange
.aEnd
.Col() )
816 nCol
= rSpellRange
.aStart
.Col();
818 if ( nRow
> rSpellRange
.aEnd
.Row() )
823 if (!pCell
) // end of range reached -> next sheet
826 if ( nTab
> rSpellRange
.aEnd
.Tab() || !pTab
[nTab
] )
827 nTab
= rSpellRange
.aStart
.Tab();
828 nCol
= rSpellRange
.aStart
.Col();
829 nRow
= rSpellRange
.aStart
.Row();
831 nVisSpellState
= VSPL_DONE
; //! only if this is for the visible range
833 rSpellPos
.Set( nCol
, nRow
, nTab
);
836 delete pEngine
; // bevor aStatus out of scope geht
842 BOOL
ScDocument::ContinueOnlineSpelling()
844 if ( bIdleDisabled
|| !pDocOptions
->IsAutoSpell() || (pShell
&& pShell
->IsReadOnly()) )
847 // #i48433# set bInsertingFromOtherDoc flag so there are no broadcasts when PutCell is called
848 // (same behavior as in RemoveAutoSpellObj: just transfer the broadcaster)
849 BOOL bOldInserting
= IsInsertingFromOtherDoc();
850 SetInsertingFromOtherDoc( TRUE
);
852 //! use one EditEngine for both calls
854 // #41504# first check visible range
855 BOOL bResult
= OnlineSpellInRange( aVisSpellRange
, aVisSpellPos
, SPELL_MAXTEST_VIS
);
857 // during first pass through visible range, always continue
858 if ( nVisSpellState
== VSPL_START
)
863 // if errors found, continue there
864 OnlineSpellInRange( aVisSpellRange
, aVisSpellPos
, SPELL_MAXTEST_ALL
);
868 // if nothing found there, continue with rest of document
869 ScRange
aTotalRange( 0,0,0, MAXCOL
,MAXROW
,MAXTAB
);
870 bResult
= OnlineSpellInRange( aTotalRange
, aOnlineSpellPos
, SPELL_MAXTEST_ALL
);
873 SetInsertingFromOtherDoc( bOldInserting
);
879 void ScDocument::SetOnlineSpellPos( const ScAddress
& rPos
)
881 aOnlineSpellPos
= rPos
;
883 // skip visible area for aOnlineSpellPos
884 if ( aVisSpellRange
.In( aOnlineSpellPos
) )
885 aOnlineSpellPos
= aVisSpellRange
.aEnd
;
888 BOOL
ScDocument::SetVisibleSpellRange( const ScRange
& rNewRange
)
890 BOOL bChange
= ( aVisSpellRange
!= rNewRange
);
893 // continue spelling through visible range when scrolling down
894 BOOL bContDown
= ( nVisSpellState
== VSPL_START
&& rNewRange
.In( aVisSpellPos
) &&
895 rNewRange
.aStart
.Row() > aVisSpellRange
.aStart
.Row() &&
896 rNewRange
.aStart
.Col() == aVisSpellRange
.aStart
.Col() &&
897 rNewRange
.aEnd
.Col() == aVisSpellRange
.aEnd
.Col() );
899 aVisSpellRange
= rNewRange
;
903 aVisSpellPos
= aVisSpellRange
.aStart
;
904 nVisSpellState
= VSPL_START
;
907 // skip visible area for aOnlineSpellPos
908 if ( aVisSpellRange
.In( aOnlineSpellPos
) )
909 aOnlineSpellPos
= aVisSpellRange
.aEnd
;
914 void ScDocument::RemoveAutoSpellObj()
916 // alle Spelling-Informationen entfernen
918 for (SCTAB nTab
=0; nTab
<=MAXTAB
&& pTab
[nTab
]; nTab
++)
919 pTab
[nTab
]->RemoveAutoSpellObj();
922 //------------------------------------------------------------------------
924 BOOL
ScDocument::IdleCheckLinks() // TRUE = demnaechst wieder versuchen
926 BOOL bAnyLeft
= FALSE
;
928 if (GetLinkManager())
930 const ::sfx2::SvBaseLinks
& rLinks
= pLinkManager
->GetLinks();
931 USHORT nCount
= rLinks
.Count();
932 for (USHORT i
=0; i
<nCount
; i
++)
934 ::sfx2::SvBaseLink
* pBase
= *rLinks
[i
];
935 if (pBase
->ISA(ScDdeLink
))
937 ScDdeLink
* pDdeLink
= (ScDdeLink
*)pBase
;
938 if (pDdeLink
->NeedsUpdate())
940 pDdeLink
->TryUpdate();
941 if (pDdeLink
->NeedsUpdate()) // war nix?
951 void ScDocument::SaveDdeLinks(SvStream
& rStream
) const
953 // bei 4.0-Export alle mit Modus != DEFAULT weglassen
954 BOOL bExport40
= ( rStream
.GetVersion() <= SOFFICE_FILEFORMAT_40
);
956 const ::sfx2::SvBaseLinks
& rLinks
= GetLinkManager()->GetLinks();
957 USHORT nCount
= rLinks
.Count();
959 // erstmal zaehlen...
961 USHORT nDdeCount
= 0;
963 for (i
=0; i
<nCount
; i
++)
965 ::sfx2::SvBaseLink
* pBase
= *rLinks
[i
];
966 if (pBase
->ISA(ScDdeLink
))
967 if ( !bExport40
|| ((ScDdeLink
*)pBase
)->GetMode() == SC_DDE_DEFAULT
)
973 ScMultipleWriteHeader
aHdr( rStream
);
974 rStream
<< nDdeCount
;
978 for (i
=0; i
<nCount
; i
++)
980 ::sfx2::SvBaseLink
* pBase
= *rLinks
[i
];
981 if (pBase
->ISA(ScDdeLink
))
983 ScDdeLink
* pLink
= (ScDdeLink
*)pBase
;
984 if ( !bExport40
|| pLink
->GetMode() == SC_DDE_DEFAULT
)
985 pLink
->Store( rStream
, aHdr
);
990 void ScDocument::LoadDdeLinks(SvStream
& rStream
)
992 ScMultipleReadHeader
aHdr( rStream
);
997 for (USHORT i
=0; i
<nCount
; i
++)
999 ScDdeLink
* pLink
= new ScDdeLink( this, rStream
, aHdr
);
1000 pLinkManager
->InsertDDELink( pLink
,
1001 pLink
->GetAppl(), pLink
->GetTopic(), pLink
->GetItem() );
1005 BOOL
ScDocument::HasDdeLinks() const
1007 if (GetLinkManager()) // Clipboard z.B. hat keinen LinkManager
1009 const ::sfx2::SvBaseLinks
& rLinks
= pLinkManager
->GetLinks();
1010 USHORT nCount
= rLinks
.Count();
1011 for (USHORT i
=0; i
<nCount
; i
++)
1012 if ((*rLinks
[i
])->ISA(ScDdeLink
))
1019 void ScDocument::SetInLinkUpdate(BOOL bSet
)
1021 // called from TableLink and AreaLink
1023 DBG_ASSERT( bInLinkUpdate
!= bSet
, "SetInLinkUpdate twice" );
1024 bInLinkUpdate
= bSet
;
1027 BOOL
ScDocument::IsInLinkUpdate() const
1029 return bInLinkUpdate
|| IsInDdeLinkUpdate();
1032 void ScDocument::UpdateExternalRefLinks()
1034 if (!GetLinkManager())
1037 const ::sfx2::SvBaseLinks
& rLinks
= pLinkManager
->GetLinks();
1038 USHORT nCount
= rLinks
.Count();
1041 for (USHORT i
= 0; i
< nCount
; ++i
)
1043 ::sfx2::SvBaseLink
* pBase
= *rLinks
[i
];
1044 ScExternalRefLink
* pRefLink
= dynamic_cast<ScExternalRefLink
*>(pBase
);
1054 pShell
->Broadcast( SfxSimpleHint(FID_DATACHANGED
) );
1055 ResetChanged( ScRange(0, 0, 0, MAXCOL
, MAXROW
, MAXTAB
) );
1057 // #i101960# set document modified, as in TrackTimeHdl for DDE links
1058 if (!pShell
->IsModified())
1060 pShell
->SetModified( TRUE
);
1061 SfxBindings
* pBindings
= GetViewBindings();
1064 pBindings
->Invalidate( SID_SAVEDOC
);
1065 pBindings
->Invalidate( SID_DOC_MODIFIED
);
1071 void ScDocument::UpdateDdeLinks()
1073 if (GetLinkManager())
1075 const ::sfx2::SvBaseLinks
& rLinks
= pLinkManager
->GetLinks();
1076 USHORT nCount
= rLinks
.Count();
1079 // #49226# falls das Updaten laenger dauert, erstmal alle Werte
1080 // zuruecksetzen, damit nichts altes (falsches) stehen bleibt
1082 for (i
=0; i
<nCount
; i
++)
1084 ::sfx2::SvBaseLink
* pBase
= *rLinks
[i
];
1085 if (pBase
->ISA(ScDdeLink
))
1087 ((ScDdeLink
*)pBase
)->ResetValue();
1093 // Formeln berechnen und painten wie im TrackTimeHdl
1095 pShell
->Broadcast( SfxSimpleHint( FID_DATACHANGED
) );
1096 ResetChanged( ScRange(0,0,0,MAXCOL
,MAXROW
,MAXTAB
) );
1098 // wenn FID_DATACHANGED irgendwann mal asynchron werden sollte
1099 // (z.B. mit Invalidate am Window), muss hier ein Update erzwungen werden.
1102 // nun wirklich updaten...
1103 for (i
=0; i
<nCount
; i
++)
1105 ::sfx2::SvBaseLink
* pBase
= *rLinks
[i
];
1106 if (pBase
->ISA(ScDdeLink
))
1107 ((ScDdeLink
*)pBase
)->TryUpdate(); // bei DDE-Links TryUpdate statt Update
1112 BOOL
ScDocument::UpdateDdeLink( const String
& rAppl
, const String
& rTopic
, const String
& rItem
)
1114 // fuer refresh() per StarOne Api
1115 // ResetValue() fuer einzelnen Link nicht noetig
1116 //! wenn's mal alles asynchron wird, aber auch hier
1118 BOOL bFound
= FALSE
;
1119 if (GetLinkManager())
1121 const ::sfx2::SvBaseLinks
& rLinks
= pLinkManager
->GetLinks();
1122 USHORT nCount
= rLinks
.Count();
1123 for (USHORT i
=0; i
<nCount
; i
++)
1125 ::sfx2::SvBaseLink
* pBase
= *rLinks
[i
];
1126 if (pBase
->ISA(ScDdeLink
))
1128 ScDdeLink
* pDdeLink
= (ScDdeLink
*)pBase
;
1129 if ( pDdeLink
->GetAppl() == rAppl
&&
1130 pDdeLink
->GetTopic() == rTopic
&&
1131 pDdeLink
->GetItem() == rItem
)
1133 pDdeLink
->TryUpdate();
1134 bFound
= TRUE
; // koennen theoretisch mehrere sein (Mode), darum weitersuchen
1142 void ScDocument::DisconnectDdeLinks()
1144 if (GetLinkManager())
1146 const ::sfx2::SvBaseLinks
& rLinks
= pLinkManager
->GetLinks();
1147 USHORT nCount
= rLinks
.Count();
1148 for (USHORT i
=0; i
<nCount
; i
++)
1150 ::sfx2::SvBaseLink
* pBase
= *rLinks
[i
];
1151 if (pBase
->ISA(ScDdeLink
))
1152 pBase
->Disconnect(); // bleibt im LinkManager eingetragen
1157 void ScDocument::CopyDdeLinks( ScDocument
* pDestDoc
) const
1159 if (bIsClip
) // aus Stream erzeugen
1164 pDestDoc
->LoadDdeLinks(*pClipData
);
1167 else if (GetLinkManager()) // Links direkt kopieren
1169 const ::sfx2::SvBaseLinks
& rLinks
= pLinkManager
->GetLinks();
1170 USHORT nCount
= rLinks
.Count();
1171 for (USHORT i
=0; i
<nCount
; i
++)
1173 ::sfx2::SvBaseLink
* pBase
= *rLinks
[i
];
1174 if (pBase
->ISA(ScDdeLink
))
1176 ScDdeLink
* pNew
= new ScDdeLink( pDestDoc
, *(ScDdeLink
*)pBase
);
1178 pDestDoc
->pLinkManager
->InsertDDELink( pNew
,
1179 pNew
->GetAppl(), pNew
->GetTopic(), pNew
->GetItem() );
1185 USHORT
ScDocument::GetDdeLinkCount() const
1187 USHORT nDdeCount
= 0;
1188 if (GetLinkManager())
1190 const ::sfx2::SvBaseLinks
& rLinks
= pLinkManager
->GetLinks();
1191 USHORT nCount
= rLinks
.Count();
1192 for (USHORT i
=0; i
<nCount
; i
++)
1193 if ((*rLinks
[i
])->ISA(ScDdeLink
))
1199 // ----------------------------------------------------------------------------
1203 /** Tries to find the specified DDE link.
1204 @param pnDdePos (out-param) if not 0, the index of the DDE link is returned here
1205 (does not include other links from link manager).
1206 @return The DDE link, if it exists, otherwise 0. */
1207 ScDdeLink
* lclGetDdeLink(
1208 const SvxLinkManager
* pLinkManager
,
1209 const String
& rAppl
, const String
& rTopic
, const String
& rItem
, BYTE nMode
,
1210 USHORT
* pnDdePos
= NULL
)
1214 const ::sfx2::SvBaseLinks
& rLinks
= pLinkManager
->GetLinks();
1215 USHORT nCount
= rLinks
.Count();
1216 if( pnDdePos
) *pnDdePos
= 0;
1217 for( USHORT nIndex
= 0; nIndex
< nCount
; ++nIndex
)
1219 ::sfx2::SvBaseLink
* pLink
= *rLinks
[ nIndex
];
1220 if( ScDdeLink
* pDdeLink
= PTR_CAST( ScDdeLink
, pLink
) )
1222 if( (pDdeLink
->GetAppl() == rAppl
) &&
1223 (pDdeLink
->GetTopic() == rTopic
) &&
1224 (pDdeLink
->GetItem() == rItem
) &&
1225 ((nMode
== SC_DDE_IGNOREMODE
) || (nMode
== pDdeLink
->GetMode())) )
1227 if( pnDdePos
) ++*pnDdePos
;
1234 /** Returns a pointer to the specified DDE link.
1235 @param nDdePos Index of the DDE link (does not include other links from link manager).
1236 @return The DDE link, if it exists, otherwise 0. */
1237 ScDdeLink
* lclGetDdeLink( const SvxLinkManager
* pLinkManager
, USHORT nDdePos
)
1241 const ::sfx2::SvBaseLinks
& rLinks
= pLinkManager
->GetLinks();
1242 USHORT nCount
= rLinks
.Count();
1243 USHORT nDdeIndex
= 0; // counts only the DDE links
1244 for( USHORT nIndex
= 0; nIndex
< nCount
; ++nIndex
)
1246 ::sfx2::SvBaseLink
* pLink
= *rLinks
[ nIndex
];
1247 if( ScDdeLink
* pDdeLink
= PTR_CAST( ScDdeLink
, pLink
) )
1249 if( nDdeIndex
== nDdePos
)
1260 // ----------------------------------------------------------------------------
1262 bool ScDocument::FindDdeLink( const String
& rAppl
, const String
& rTopic
, const String
& rItem
, BYTE nMode
, USHORT
& rnDdePos
)
1264 return lclGetDdeLink( GetLinkManager(), rAppl
, rTopic
, rItem
, nMode
, &rnDdePos
) != NULL
;
1267 bool ScDocument::GetDdeLinkData( USHORT nDdePos
, String
& rAppl
, String
& rTopic
, String
& rItem
) const
1269 if( const ScDdeLink
* pDdeLink
= lclGetDdeLink( GetLinkManager(), nDdePos
) )
1271 rAppl
= pDdeLink
->GetAppl();
1272 rTopic
= pDdeLink
->GetTopic();
1273 rItem
= pDdeLink
->GetItem();
1279 bool ScDocument::GetDdeLinkMode( USHORT nDdePos
, BYTE
& rnMode
) const
1281 if( const ScDdeLink
* pDdeLink
= lclGetDdeLink( GetLinkManager(), nDdePos
) )
1283 rnMode
= pDdeLink
->GetMode();
1289 const ScMatrix
* ScDocument::GetDdeLinkResultMatrix( USHORT nDdePos
) const
1291 const ScDdeLink
* pDdeLink
= lclGetDdeLink( GetLinkManager(), nDdePos
);
1292 return pDdeLink
? pDdeLink
->GetResult() : NULL
;
1295 bool ScDocument::CreateDdeLink( const String
& rAppl
, const String
& rTopic
, const String
& rItem
, BYTE nMode
, ScMatrix
* pResults
)
1297 /* Create a DDE link without updating it (i.e. for Excel import), to prevent
1298 unwanted connections. First try to find existing link. Set result array
1299 on existing and new links. */
1300 //! store DDE links additionally at document (for efficiency)?
1301 DBG_ASSERT( nMode
!= SC_DDE_IGNOREMODE
, "ScDocument::CreateDdeLink - SC_DDE_IGNOREMODE not allowed here" );
1302 if( GetLinkManager() && (nMode
!= SC_DDE_IGNOREMODE
) )
1304 ScDdeLink
* pDdeLink
= lclGetDdeLink( pLinkManager
, rAppl
, rTopic
, rItem
, nMode
);
1307 // create a new DDE link, but without TryUpdate
1308 pDdeLink
= new ScDdeLink( this, rAppl
, rTopic
, rItem
, nMode
);
1309 pLinkManager
->InsertDDELink( pDdeLink
, rAppl
, rTopic
, rItem
);
1312 // insert link results
1314 pDdeLink
->SetResult( pResults
);
1321 bool ScDocument::SetDdeLinkResultMatrix( USHORT nDdePos
, ScMatrix
* pResults
)
1323 if( ScDdeLink
* pDdeLink
= lclGetDdeLink( GetLinkManager(), nDdePos
) )
1325 pDdeLink
->SetResult( pResults
);
1331 //------------------------------------------------------------------------
1333 BOOL
ScDocument::HasAreaLinks() const
1335 if (GetLinkManager()) // Clipboard z.B. hat keinen LinkManager
1337 const ::sfx2::SvBaseLinks
& rLinks
= pLinkManager
->GetLinks();
1338 USHORT nCount
= rLinks
.Count();
1339 for (USHORT i
=0; i
<nCount
; i
++)
1340 if ((*rLinks
[i
])->ISA(ScAreaLink
))
1347 void ScDocument::UpdateAreaLinks()
1349 if (GetLinkManager())
1351 const ::sfx2::SvBaseLinks
& rLinks
= pLinkManager
->GetLinks();
1352 USHORT nCount
= rLinks
.Count();
1353 for (USHORT i
=0; i
<nCount
; i
++)
1355 ::sfx2::SvBaseLink
* pBase
= *rLinks
[i
];
1356 if (pBase
->ISA(ScAreaLink
))
1362 void ScDocument::DeleteAreaLinksOnTab( SCTAB nTab
)
1364 if (GetLinkManager())
1366 const ::sfx2::SvBaseLinks
& rLinks
= pLinkManager
->GetLinks();
1368 while ( nPos
< rLinks
.Count() )
1370 const ::sfx2::SvBaseLink
* pBase
= *rLinks
[nPos
];
1371 if ( pBase
->ISA(ScAreaLink
) &&
1372 static_cast<const ScAreaLink
*>(pBase
)->GetDestArea().aStart
.Tab() == nTab
)
1373 pLinkManager
->Remove( nPos
);
1380 void ScDocument::UpdateRefAreaLinks( UpdateRefMode eUpdateRefMode
,
1381 const ScRange
& rRange
, SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
)
1383 if (GetLinkManager())
1385 bool bAnyUpdate
= false;
1387 const ::sfx2::SvBaseLinks
& rLinks
= pLinkManager
->GetLinks();
1388 USHORT nCount
= rLinks
.Count();
1389 for (USHORT i
=0; i
<nCount
; i
++)
1391 ::sfx2::SvBaseLink
* pBase
= *rLinks
[i
];
1392 if (pBase
->ISA(ScAreaLink
))
1394 ScAreaLink
* pLink
= (ScAreaLink
*) pBase
;
1395 ScRange aOutRange
= pLink
->GetDestArea();
1397 SCCOL nCol1
= aOutRange
.aStart
.Col();
1398 SCROW nRow1
= aOutRange
.aStart
.Row();
1399 SCTAB nTab1
= aOutRange
.aStart
.Tab();
1400 SCCOL nCol2
= aOutRange
.aEnd
.Col();
1401 SCROW nRow2
= aOutRange
.aEnd
.Row();
1402 SCTAB nTab2
= aOutRange
.aEnd
.Tab();
1404 ScRefUpdateRes eRes
=
1405 ScRefUpdate::Update( this, eUpdateRefMode
,
1406 rRange
.aStart
.Col(), rRange
.aStart
.Row(), rRange
.aStart
.Tab(),
1407 rRange
.aEnd
.Col(), rRange
.aEnd
.Row(), rRange
.aEnd
.Tab(), nDx
, nDy
, nDz
,
1408 nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
);
1409 if ( eRes
!= UR_NOTHING
)
1411 pLink
->SetDestArea( ScRange( nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
) );
1419 // #i52120# Look for duplicates (after updating all positions).
1420 // If several links start at the same cell, the one with the lower index is removed
1421 // (file format specifies only one link definition for a cell).
1423 USHORT nFirstIndex
= 0;
1424 while ( nFirstIndex
< nCount
)
1426 bool bFound
= false;
1427 ::sfx2::SvBaseLink
* pFirst
= *rLinks
[nFirstIndex
];
1428 if ( pFirst
->ISA(ScAreaLink
) )
1430 ScAddress aFirstPos
= static_cast<ScAreaLink
*>(pFirst
)->GetDestArea().aStart
;
1431 for ( USHORT nSecondIndex
= nFirstIndex
+ 1; nSecondIndex
< nCount
&& !bFound
; ++nSecondIndex
)
1433 ::sfx2::SvBaseLink
* pSecond
= *rLinks
[nSecondIndex
];
1434 if ( pSecond
->ISA(ScAreaLink
) &&
1435 static_cast<ScAreaLink
*>(pSecond
)->GetDestArea().aStart
== aFirstPos
)
1437 // remove the first link, exit the inner loop, don't increment nFirstIndex
1438 pLinkManager
->Remove( pFirst
);
1439 nCount
= rLinks
.Count();
1451 //------------------------------------------------------------------------
1454 void ScDocument::KeyInput( const KeyEvent
& )
1456 if ( pChartListenerCollection
->GetCount() )
1457 pChartListenerCollection
->StartTimer();
1458 if( apTemporaryChartLock
.get() )
1459 apTemporaryChartLock
->StartOrContinueLocking();
1462 // ----------------------------------------------------------------------------
1464 BOOL
ScDocument::CheckMacroWarn()
1466 // The check for macro configuration, macro warning and disabling is now handled
1467 // in SfxObjectShell::AdjustMacroMode, called by SfxObjectShell::CallBasic.
1472 //------------------------------------------------------------------------
1474 SfxBindings
* ScDocument::GetViewBindings()
1476 // used to invalidate slots after changes to this document
1479 return NULL
; // no ObjShell -> no view
1481 // first check current view
1482 SfxViewFrame
* pViewFrame
= SfxViewFrame::Current();
1483 if ( pViewFrame
&& pViewFrame
->GetObjectShell() != pShell
) // wrong document?
1486 // otherwise use first view for this doc
1488 pViewFrame
= SfxViewFrame::GetFirst( pShell
);
1491 return &pViewFrame
->GetBindings();
1496 //------------------------------------------------------------------------
1498 void lcl_TransliterateEditEngine( ScEditEngineDefaulter
& rEngine
,
1499 utl::TransliterationWrapper
& rTranslitarationWrapper
,
1500 BOOL bConsiderLanguage
, ScDocument
* pDoc
)
1502 //! should use TransliterateText method of EditEngine instead, when available!
1504 sal_uInt16 nLanguage
= LANGUAGE_SYSTEM
;
1506 USHORT nParCount
= rEngine
.GetParagraphCount();
1507 for (USHORT nPar
=0; nPar
<nParCount
; nPar
++)
1509 SvUShorts aPortions
;
1510 rEngine
.GetPortions( (USHORT
)nPar
, aPortions
);
1512 for ( USHORT nPos
= aPortions
.Count(); nPos
; )
1515 USHORT nEnd
= aPortions
.GetObject( nPos
);
1516 USHORT nStart
= nPos
? aPortions
.GetObject( nPos
- 1 ) : 0;
1518 ESelection
aSel( nPar
, nStart
, nPar
, nEnd
);
1519 String aOldStr
= rEngine
.GetText( aSel
);
1520 SfxItemSet aAttr
= rEngine
.GetAttribs( aSel
);
1522 if ( aAttr
.GetItemState( EE_FEATURE_FIELD
) != SFX_ITEM_ON
) // fields are not touched
1524 if ( bConsiderLanguage
)
1526 BYTE nScript
= pDoc
->GetStringScriptType( aOldStr
);
1527 USHORT nWhich
= ( nScript
== SCRIPTTYPE_ASIAN
) ? EE_CHAR_LANGUAGE_CJK
:
1528 ( ( nScript
== SCRIPTTYPE_COMPLEX
) ? EE_CHAR_LANGUAGE_CTL
:
1530 nLanguage
= ((const SvxLanguageItem
&)aAttr
.Get(nWhich
)).GetValue();
1533 com::sun::star::uno::Sequence
<sal_Int32
> aOffsets
;
1534 String aNewStr
= rTranslitarationWrapper
.transliterate( aOldStr
, nLanguage
, 0, aOldStr
.Len(), &aOffsets
);
1536 if ( aNewStr
!= aOldStr
)
1538 // replace string, keep attributes
1540 rEngine
.QuickInsertText( aNewStr
, aSel
);
1541 aSel
.nEndPos
= aSel
.nStartPos
+ aNewStr
.Len();
1542 rEngine
.QuickSetAttribs( aAttr
, aSel
);
1549 void ScDocument::TransliterateText( const ScMarkData
& rMultiMark
, sal_Int32 nType
)
1551 DBG_ASSERT( rMultiMark
.IsMultiMarked(), "TransliterateText: no selection" );
1553 utl::TransliterationWrapper
aTranslitarationWrapper( xServiceManager
, nType
);
1554 BOOL bConsiderLanguage
= aTranslitarationWrapper
.needLanguageForTheMode();
1555 sal_uInt16 nLanguage
= LANGUAGE_SYSTEM
;
1557 ScEditEngineDefaulter
* pEngine
= NULL
; // not using pEditEngine member because of defaults
1559 SCTAB nCount
= GetTableCount();
1560 for (SCTAB nTab
= 0; nTab
< nCount
; nTab
++)
1561 if ( pTab
[nTab
] && rMultiMark
.GetTableSelect(nTab
) )
1566 BOOL bFound
= rMultiMark
.IsCellMarked( nCol
, nRow
);
1568 bFound
= GetNextMarkedCell( nCol
, nRow
, nTab
, rMultiMark
);
1572 const ScBaseCell
* pCell
= GetCell( ScAddress( nCol
, nRow
, nTab
) );
1573 CellType eType
= pCell
? pCell
->GetCellType() : CELLTYPE_NONE
;
1575 if ( eType
== CELLTYPE_STRING
)
1578 ((const ScStringCell
*)pCell
)->GetString(aOldStr
);
1579 xub_StrLen nOldLen
= aOldStr
.Len();
1581 if ( bConsiderLanguage
)
1583 BYTE nScript
= GetStringScriptType( aOldStr
); //! cell script type?
1584 USHORT nWhich
= ( nScript
== SCRIPTTYPE_ASIAN
) ? ATTR_CJK_FONT_LANGUAGE
:
1585 ( ( nScript
== SCRIPTTYPE_COMPLEX
) ? ATTR_CTL_FONT_LANGUAGE
:
1586 ATTR_FONT_LANGUAGE
);
1587 nLanguage
= ((const SvxLanguageItem
*)GetAttr( nCol
, nRow
, nTab
, nWhich
))->GetValue();
1590 com::sun::star::uno::Sequence
<sal_Int32
> aOffsets
;
1591 String aNewStr
= aTranslitarationWrapper
.transliterate( aOldStr
, nLanguage
, 0, nOldLen
, &aOffsets
);
1593 if ( aNewStr
!= aOldStr
)
1594 PutCell( nCol
, nRow
, nTab
, new ScStringCell( aNewStr
) );
1596 else if ( eType
== CELLTYPE_EDIT
)
1599 pEngine
= new ScFieldEditEngine( GetEnginePool(), GetEditPool() );
1601 // defaults from cell attributes must be set so right language is used
1602 const ScPatternAttr
* pPattern
= GetPattern( nCol
, nRow
, nTab
);
1603 SfxItemSet
* pDefaults
= new SfxItemSet( pEngine
->GetEmptyItemSet() );
1604 pPattern
->FillEditItemSet( pDefaults
);
1605 pEngine
->SetDefaults( pDefaults
, TRUE
);
1607 const EditTextObject
* pData
= ((const ScEditCell
*)pCell
)->GetData();
1608 pEngine
->SetText( *pData
);
1610 pEngine
->ClearModifyFlag();
1612 lcl_TransliterateEditEngine( *pEngine
, aTranslitarationWrapper
, bConsiderLanguage
, this );
1614 if ( pEngine
->IsModified() )
1616 ScEditAttrTester
aTester( pEngine
);
1617 if ( aTester
.NeedsObject() )
1619 // remove defaults (paragraph attributes) before creating text object
1620 SfxItemSet
* pEmpty
= new SfxItemSet( pEngine
->GetEmptyItemSet() );
1621 pEngine
->SetDefaults( pEmpty
, TRUE
);
1623 EditTextObject
* pNewData
= pEngine
->CreateTextObject();
1624 PutCell( nCol
, nRow
, nTab
,
1625 new ScEditCell( pNewData
, this, pEngine
->GetEditTextObjectPool() ) );
1630 String aNewStr
= pEngine
->GetText();
1631 PutCell( nCol
, nRow
, nTab
, new ScStringCell( aNewStr
) );
1636 bFound
= GetNextMarkedCell( nCol
, nRow
, nTab
, rMultiMark
);