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