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