Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "scitems.hxx"
21 : #include <editeng/eeitem.hxx>
22 :
23 : #include <tools/urlobj.hxx>
24 : #include <editeng/editobj.hxx>
25 : #include <editeng/editstat.hxx>
26 : #include <editeng/frmdiritem.hxx>
27 : #include <editeng/langitem.hxx>
28 : #include <sfx2/linkmgr.hxx>
29 : #include <editeng/scripttypeitem.hxx>
30 : #include <editeng/unolingu.hxx>
31 : #include <sfx2/bindings.hxx>
32 : #include <sfx2/objsh.hxx>
33 : #include <sfx2/printer.hxx>
34 : #include <sfx2/viewfrm.hxx>
35 : #include <sfx2/viewsh.hxx>
36 : #include <svl/flagitem.hxx>
37 : #include <svl/intitem.hxx>
38 : #include <svl/zforlist.hxx>
39 : #include <svl/zformat.hxx>
40 : #include <unotools/misccfg.hxx>
41 : #include <sfx2/app.hxx>
42 : #include <unotools/transliterationwrapper.hxx>
43 : #include <unotools/securityoptions.hxx>
44 :
45 : #include <vcl/virdev.hxx>
46 : #include <vcl/msgbox.hxx>
47 :
48 : #include <com/sun/star/i18n/TransliterationModulesExtra.hpp>
49 :
50 : #include "inputopt.hxx"
51 : #include "global.hxx"
52 : #include "table.hxx"
53 : #include "column.hxx"
54 : #include "poolhelp.hxx"
55 : #include "docpool.hxx"
56 : #include "stlpool.hxx"
57 : #include "stlsheet.hxx"
58 : #include "docoptio.hxx"
59 : #include "viewopti.hxx"
60 : #include "scextopt.hxx"
61 : #include "rechead.hxx"
62 : #include "ddelink.hxx"
63 : #include "scmatrix.hxx"
64 : #include "arealink.hxx"
65 : #include "dociter.hxx"
66 : #include "patattr.hxx"
67 : #include "hints.hxx"
68 : #include "editutil.hxx"
69 : #include "progress.hxx"
70 : #include "document.hxx"
71 : #include "chartlis.hxx"
72 : #include "chartlock.hxx"
73 : #include "refupdat.hxx"
74 : #include "validat.hxx"
75 : #include "markdata.hxx"
76 : #include "scmod.hxx"
77 : #include "printopt.hxx"
78 : #include "externalrefmgr.hxx"
79 : #include "globstr.hrc"
80 : #include "sc.hrc"
81 : #include "charthelper.hxx"
82 : #include "macromgr.hxx"
83 : #include "dpobject.hxx"
84 : #include "docuno.hxx"
85 : #include "scresid.hxx"
86 : #include "columniterator.hxx"
87 : #include "globalnames.hxx"
88 : #include "stringutil.hxx"
89 : #include <documentlinkmgr.hxx>
90 : #include <scopetools.hxx>
91 :
92 : #include <boost/scoped_ptr.hpp>
93 :
94 : using namespace com::sun::star;
95 :
96 : // STATIC DATA -----------------------------------------------------------
97 :
98 : namespace {
99 :
100 400 : inline sal_uInt16 getScaleValue(SfxStyleSheetBase& rStyle, sal_uInt16 nWhich)
101 : {
102 400 : return static_cast<const SfxUInt16Item&>(rStyle.GetItemSet().Get(nWhich)).GetValue();
103 : }
104 :
105 : }
106 :
107 4242 : void ScDocument::ImplCreateOptions()
108 : {
109 4242 : pDocOptions = new ScDocOptions();
110 4242 : pViewOptions = new ScViewOptions();
111 4242 : }
112 :
113 4192 : void ScDocument::ImplDeleteOptions()
114 : {
115 4192 : delete pDocOptions;
116 4192 : delete pViewOptions;
117 4192 : delete pExtDocOptions;
118 4192 : }
119 :
120 6345 : SfxPrinter* ScDocument::GetPrinter(bool bCreateIfNotExist)
121 : {
122 6345 : if ( !pPrinter && bCreateIfNotExist )
123 : {
124 : SfxItemSet* pSet =
125 340 : new SfxItemSet( *xPoolHelper->GetDocPool(),
126 : SID_PRINTER_NOTFOUND_WARN, SID_PRINTER_NOTFOUND_WARN,
127 : SID_PRINTER_CHANGESTODOC, SID_PRINTER_CHANGESTODOC,
128 : SID_PRINT_SELECTEDSHEET, SID_PRINT_SELECTEDSHEET,
129 : SID_SCPRINTOPTIONS, SID_SCPRINTOPTIONS,
130 340 : NULL );
131 :
132 340 : ::utl::MiscCfg aMisc;
133 340 : sal_uInt16 nFlags = 0;
134 340 : if ( aMisc.IsPaperOrientationWarning() )
135 0 : nFlags |= SFX_PRINTER_CHG_ORIENTATION;
136 340 : if ( aMisc.IsPaperSizeWarning() )
137 0 : nFlags |= SFX_PRINTER_CHG_SIZE;
138 340 : pSet->Put( SfxFlagItem( SID_PRINTER_CHANGESTODOC, nFlags ) );
139 340 : pSet->Put( SfxBoolItem( SID_PRINTER_NOTFOUND_WARN, aMisc.IsNotFoundWarning() ) );
140 :
141 340 : pPrinter = new SfxPrinter( pSet );
142 340 : pPrinter->SetMapMode( MAP_100TH_MM );
143 340 : UpdateDrawPrinter();
144 340 : pPrinter->SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
145 : }
146 :
147 6345 : return pPrinter;
148 : }
149 :
150 160 : void ScDocument::SetPrinter( SfxPrinter* pNewPrinter )
151 : {
152 160 : if ( pNewPrinter == pPrinter )
153 : {
154 : // #i6706# SetPrinter is called with the same printer again if
155 : // the JobSetup has changed. In that case just call UpdateDrawPrinter
156 : // (SetRefDevice for drawing layer) because of changed text sizes.
157 0 : UpdateDrawPrinter();
158 : }
159 : else
160 : {
161 160 : SfxPrinter* pOld = pPrinter;
162 160 : pPrinter = pNewPrinter;
163 160 : UpdateDrawPrinter();
164 160 : pPrinter->SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
165 160 : delete pOld;
166 : }
167 160 : InvalidateTextWidth(NULL, NULL, false); // in both cases
168 160 : }
169 :
170 320 : void ScDocument::SetPrintOptions()
171 : {
172 320 : if ( !pPrinter ) GetPrinter(); // setzt pPrinter
173 : OSL_ENSURE( pPrinter, "Error in printer creation :-/" );
174 :
175 320 : if ( pPrinter )
176 : {
177 320 : ::utl::MiscCfg aMisc;
178 640 : SfxItemSet aOptSet( pPrinter->GetOptions() );
179 :
180 320 : sal_uInt16 nFlags = 0;
181 320 : if ( aMisc.IsPaperOrientationWarning() )
182 0 : nFlags |= SFX_PRINTER_CHG_ORIENTATION;
183 320 : if ( aMisc.IsPaperSizeWarning() )
184 0 : nFlags |= SFX_PRINTER_CHG_SIZE;
185 320 : aOptSet.Put( SfxFlagItem( SID_PRINTER_CHANGESTODOC, nFlags ) );
186 320 : aOptSet.Put( SfxBoolItem( SID_PRINTER_NOTFOUND_WARN, aMisc.IsNotFoundWarning() ) );
187 :
188 640 : pPrinter->SetOptions( aOptSet );
189 : }
190 320 : }
191 :
192 7686 : VirtualDevice* ScDocument::GetVirtualDevice_100th_mm()
193 : {
194 7686 : if (!pVirtualDevice_100th_mm)
195 : {
196 : #ifdef IOS
197 : pVirtualDevice_100th_mm = new VirtualDevice( 8 );
198 : #else
199 916 : pVirtualDevice_100th_mm = new VirtualDevice( 1 );
200 : #endif
201 916 : pVirtualDevice_100th_mm->SetReferenceDevice(VirtualDevice::REFDEV_MODE_MSO1);
202 916 : MapMode aMapMode( pVirtualDevice_100th_mm->GetMapMode() );
203 916 : aMapMode.SetMapUnit( MAP_100TH_MM );
204 916 : pVirtualDevice_100th_mm->SetMapMode( aMapMode );
205 : }
206 7686 : return pVirtualDevice_100th_mm;
207 : }
208 :
209 7842 : OutputDevice* ScDocument::GetRefDevice()
210 : {
211 : // Create printer like ref device, see Writer...
212 7842 : OutputDevice* pRefDevice = NULL;
213 7842 : if ( SC_MOD()->GetInputOptions().GetTextWysiwyg() )
214 156 : pRefDevice = GetPrinter();
215 : else
216 7686 : pRefDevice = GetVirtualDevice_100th_mm();
217 7842 : return pRefDevice;
218 : }
219 :
220 0 : void ScDocument::ModifyStyleSheet( SfxStyleSheetBase& rStyleSheet,
221 : const SfxItemSet& rChanges )
222 : {
223 0 : SfxItemSet& rSet = rStyleSheet.GetItemSet();
224 :
225 0 : switch ( rStyleSheet.GetFamily() )
226 : {
227 : case SFX_STYLE_FAMILY_PAGE:
228 : {
229 0 : const sal_uInt16 nOldScale = getScaleValue(rStyleSheet, ATTR_PAGE_SCALE);
230 0 : const sal_uInt16 nOldScaleToPages = getScaleValue(rStyleSheet, ATTR_PAGE_SCALETOPAGES);
231 0 : rSet.Put( rChanges );
232 0 : const sal_uInt16 nNewScale = getScaleValue(rStyleSheet, ATTR_PAGE_SCALE);
233 0 : const sal_uInt16 nNewScaleToPages = getScaleValue(rStyleSheet, ATTR_PAGE_SCALETOPAGES);
234 :
235 0 : if ( (nOldScale != nNewScale) || (nOldScaleToPages != nNewScaleToPages) )
236 0 : InvalidateTextWidth( rStyleSheet.GetName() );
237 :
238 0 : if( SvtLanguageOptions().IsCTLFontEnabled() )
239 : {
240 0 : const SfxPoolItem *pItem = NULL;
241 0 : if( rChanges.GetItemState(ATTR_WRITINGDIR, true, &pItem ) == SfxItemState::SET )
242 0 : ScChartHelper::DoUpdateAllCharts( this );
243 : }
244 : }
245 0 : break;
246 :
247 : case SFX_STYLE_FAMILY_PARA:
248 : {
249 : bool bNumFormatChanged;
250 0 : if ( ScGlobal::CheckWidthInvalidate( bNumFormatChanged,
251 : rSet, rChanges ) )
252 0 : InvalidateTextWidth( NULL, NULL, bNumFormatChanged );
253 :
254 0 : for (SCTAB nTab=0; nTab<=MAXTAB; ++nTab)
255 0 : if (maTabs[nTab] && maTabs[nTab]->IsStreamValid())
256 0 : maTabs[nTab]->SetStreamValid( false );
257 :
258 : sal_uLong nOldFormat =
259 : static_cast<const SfxUInt32Item*>(&rSet.Get(
260 0 : ATTR_VALUE_FORMAT ))->GetValue();
261 : sal_uLong nNewFormat =
262 : static_cast<const SfxUInt32Item*>(&rChanges.Get(
263 0 : ATTR_VALUE_FORMAT ))->GetValue();
264 : LanguageType eNewLang, eOldLang;
265 0 : eNewLang = eOldLang = LANGUAGE_DONTKNOW;
266 0 : if ( nNewFormat != nOldFormat )
267 : {
268 0 : SvNumberFormatter* pFormatter = GetFormatTable();
269 0 : eOldLang = pFormatter->GetEntry( nOldFormat )->GetLanguage();
270 0 : eNewLang = pFormatter->GetEntry( nNewFormat )->GetLanguage();
271 : }
272 :
273 : // Bedeutung der Items in rChanges:
274 : // Item gesetzt - Aenderung uebernehmen
275 : // Dontcare - Default setzen
276 : // Default - keine Aenderung
277 : // ("keine Aenderung" geht nicht mit PutExtended, darum Schleife)
278 0 : for (sal_uInt16 nWhich = ATTR_PATTERN_START; nWhich <= ATTR_PATTERN_END; nWhich++)
279 : {
280 : const SfxPoolItem* pItem;
281 0 : SfxItemState eState = rChanges.GetItemState( nWhich, false, &pItem );
282 0 : if ( eState == SfxItemState::SET )
283 0 : rSet.Put( *pItem );
284 0 : else if ( eState == SfxItemState::DONTCARE )
285 0 : rSet.ClearItem( nWhich );
286 : // bei Default nichts
287 : }
288 :
289 0 : if ( eNewLang != eOldLang )
290 : rSet.Put(
291 0 : SvxLanguageItem( eNewLang, ATTR_LANGUAGE_FORMAT ) );
292 : }
293 0 : break;
294 : default:
295 : {
296 : // added to avoid warnings
297 : }
298 : }
299 0 : }
300 :
301 0 : void ScDocument::CopyStdStylesFrom( ScDocument* pSrcDoc )
302 : {
303 : // number format exchange list has to be handled here, too
304 0 : NumFmtMergeHandler aNumFmtMergeHdl(this, pSrcDoc);
305 0 : xPoolHelper->GetStylePool()->CopyStdStylesFrom( pSrcDoc->xPoolHelper->GetStylePool() );
306 0 : }
307 :
308 0 : void ScDocument::InvalidateTextWidth( const OUString& rStyleName )
309 : {
310 0 : const SCTAB nCount = GetTableCount();
311 0 : for ( SCTAB i=0; i<nCount && maTabs[i]; i++ )
312 0 : if ( maTabs[i]->GetPageStyle() == rStyleName )
313 0 : InvalidateTextWidth( i );
314 0 : }
315 :
316 0 : void ScDocument::InvalidateTextWidth( SCTAB nTab )
317 : {
318 0 : ScAddress aAdrFrom( 0, 0, nTab );
319 0 : ScAddress aAdrTo ( MAXCOL, MAXROW, nTab );
320 0 : InvalidateTextWidth( &aAdrFrom, &aAdrTo, false );
321 0 : }
322 :
323 0 : bool ScDocument::IsPageStyleInUse( const OUString& rStrPageStyle, SCTAB* pInTab )
324 : {
325 0 : bool bInUse = false;
326 0 : const SCTAB nCount = GetTableCount();
327 : SCTAB i;
328 :
329 0 : for ( i = 0; !bInUse && i < nCount && maTabs[i]; i++ )
330 0 : bInUse = ( maTabs[i]->GetPageStyle() == rStrPageStyle );
331 :
332 0 : if ( pInTab )
333 0 : *pInTab = i-1;
334 :
335 0 : return bInUse;
336 : }
337 :
338 0 : bool ScDocument::RemovePageStyleInUse( const OUString& rStyle )
339 : {
340 0 : bool bWasInUse = false;
341 0 : const SCTAB nCount = GetTableCount();
342 :
343 0 : for ( SCTAB i=0; i<nCount && maTabs[i]; i++ )
344 0 : if ( maTabs[i]->GetPageStyle() == rStyle )
345 : {
346 0 : bWasInUse = true;
347 0 : maTabs[i]->SetPageStyle( ScGlobal::GetRscString(STR_STYLENAME_STANDARD) );
348 : }
349 :
350 0 : return bWasInUse;
351 : }
352 :
353 0 : bool ScDocument::RenamePageStyleInUse( const OUString& rOld, const OUString& rNew )
354 : {
355 0 : bool bWasInUse = false;
356 0 : const SCTAB nCount = GetTableCount();
357 :
358 0 : for ( SCTAB i=0; i<nCount && maTabs[i]; i++ )
359 0 : if ( maTabs[i]->GetPageStyle() == rOld )
360 : {
361 0 : bWasInUse = true;
362 0 : maTabs[i]->SetPageStyle( rNew );
363 : }
364 :
365 0 : return bWasInUse;
366 : }
367 :
368 23080 : sal_uInt8 ScDocument::GetEditTextDirection(SCTAB nTab) const
369 : {
370 23080 : EEHorizontalTextDirection eRet = EE_HTEXTDIR_DEFAULT;
371 :
372 23080 : OUString aStyleName = GetPageStyle( nTab );
373 23080 : SfxStyleSheetBase* pStyle = xPoolHelper->GetStylePool()->Find( aStyleName, SFX_STYLE_FAMILY_PAGE );
374 23080 : if ( pStyle )
375 : {
376 23080 : SfxItemSet& rStyleSet = pStyle->GetItemSet();
377 : SvxFrameDirection eDirection = (SvxFrameDirection)
378 23080 : static_cast<const SvxFrameDirectionItem&>(rStyleSet.Get( ATTR_WRITINGDIR )).GetValue();
379 :
380 23080 : if ( eDirection == FRMDIR_HORI_LEFT_TOP )
381 22966 : eRet = EE_HTEXTDIR_L2R;
382 114 : else if ( eDirection == FRMDIR_HORI_RIGHT_TOP )
383 0 : eRet = EE_HTEXTDIR_R2L;
384 : // else (invalid for EditEngine): keep "default"
385 : }
386 :
387 23080 : return sal::static_int_cast<sal_uInt8>(eRet);
388 : }
389 :
390 4 : ScMacroManager* ScDocument::GetMacroManager()
391 : {
392 4 : if (!mpMacroMgr.get())
393 4 : mpMacroMgr.reset(new ScMacroManager(this));
394 4 : return mpMacroMgr.get();
395 : }
396 :
397 160 : void ScDocument::FillMatrix(
398 : ScMatrix& rMat, SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const
399 : {
400 160 : const ScTable* pTab = FetchTable(nTab);
401 160 : if (!pTab)
402 0 : return;
403 :
404 160 : if (nCol1 > nCol2 || nRow1 > nRow2)
405 0 : return;
406 :
407 : SCSIZE nC, nR;
408 160 : rMat.GetDimensions(nC, nR);
409 160 : if (static_cast<SCROW>(nR) != nRow2 - nRow1 + 1 || static_cast<SCCOL>(nC) != nCol2 - nCol1 + 1)
410 0 : return;
411 :
412 160 : pTab->FillMatrix(rMat, nCol1, nRow1, nCol2, nRow2);
413 : }
414 :
415 0 : void ScDocument::SetFormulaResults( const ScAddress& rTopPos, const double* pResults, size_t nLen )
416 : {
417 0 : ScTable* pTab = FetchTable(rTopPos.Tab());
418 0 : if (!pTab)
419 0 : return;
420 :
421 0 : pTab->SetFormulaResults(rTopPos.Col(), rTopPos.Row(), pResults, nLen);
422 : }
423 :
424 0 : void ScDocument::SetFormulaResults(
425 : const ScAddress& rTopPos, const formula::FormulaTokenRef* pResults, size_t nLen )
426 : {
427 0 : ScTable* pTab = FetchTable(rTopPos.Tab());
428 0 : if (!pTab)
429 0 : return;
430 :
431 0 : pTab->SetFormulaResults(rTopPos.Col(), rTopPos.Row(), pResults, nLen);
432 : }
433 :
434 24564 : void ScDocument::InvalidateTextWidth( const ScAddress* pAdrFrom, const ScAddress* pAdrTo,
435 : bool bNumFormatChanged )
436 : {
437 24564 : bool bBroadcast = (bNumFormatChanged && GetDocOptions().IsCalcAsShown() && !IsImportingXML() && !IsClipboard());
438 24564 : if ( pAdrFrom && !pAdrTo )
439 : {
440 0 : const SCTAB nTab = pAdrFrom->Tab();
441 :
442 0 : if (nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
443 0 : maTabs[nTab]->InvalidateTextWidth( pAdrFrom, NULL, bNumFormatChanged, bBroadcast );
444 : }
445 : else
446 : {
447 24564 : const SCTAB nTabStart = pAdrFrom ? pAdrFrom->Tab() : 0;
448 24564 : const SCTAB nTabEnd = pAdrTo ? pAdrTo->Tab() : MAXTAB;
449 :
450 49128 : for ( SCTAB nTab=nTabStart; nTab<=nTabEnd && nTab < static_cast<SCTAB>(maTabs.size()); nTab++ )
451 24564 : if ( maTabs[nTab] )
452 24564 : maTabs[nTab]->InvalidateTextWidth( pAdrFrom, pAdrTo, bNumFormatChanged, bBroadcast );
453 : }
454 24564 : }
455 :
456 : #define CALCMAX 1000 // Berechnungen
457 : #define ABORT_EVENTS (VCL_INPUT_ANY & ~VCL_INPUT_TIMER & ~VCL_INPUT_OTHER)
458 :
459 : namespace {
460 :
461 : class IdleCalcTextWidthScope
462 : {
463 : ScDocument& mrDoc;
464 : ScAddress& mrCalcPos;
465 : MapMode maOldMapMode;
466 : sal_uLong mnStartTime;
467 : ScStyleSheetPool* mpStylePool;
468 : sal_uInt16 mnOldSearchMask;
469 : SfxStyleFamily meOldFamily;
470 : bool mbNeedMore;
471 : bool mbProgress;
472 :
473 : public:
474 400 : IdleCalcTextWidthScope(ScDocument& rDoc, ScAddress& rCalcPos) :
475 : mrDoc(rDoc),
476 : mrCalcPos(rCalcPos),
477 400 : mnStartTime(tools::Time::GetSystemTicks()),
478 400 : mpStylePool(rDoc.GetStyleSheetPool()),
479 400 : mnOldSearchMask(mpStylePool->GetSearchMask()),
480 400 : meOldFamily(mpStylePool->GetSearchFamily()),
481 : mbNeedMore(false),
482 2000 : mbProgress(false)
483 : {
484 : // The old search mask / family flags must be restored so that e.g.
485 : // the styles dialog shows correct listing when it's opened in-between
486 : // the calls.
487 :
488 400 : mrDoc.EnableIdle(false);
489 400 : mpStylePool->SetSearchMask(SFX_STYLE_FAMILY_PAGE, SFXSTYLEBIT_ALL);
490 400 : }
491 :
492 400 : ~IdleCalcTextWidthScope()
493 400 : {
494 400 : SfxPrinter* pDev = mrDoc.GetPrinter();
495 400 : if (pDev)
496 400 : pDev->SetMapMode(maOldMapMode);
497 :
498 400 : if (mbProgress)
499 0 : ScProgress::DeleteInterpretProgress();
500 :
501 400 : mpStylePool->SetSearchMask(meOldFamily, mnOldSearchMask);
502 400 : mrDoc.EnableIdle(true);
503 400 : }
504 :
505 1281 : SCTAB Tab() const { return mrCalcPos.Tab(); }
506 400 : SCCOL Col() const { return mrCalcPos.Col(); }
507 400 : SCROW Row() const { return mrCalcPos.Row(); }
508 :
509 319 : void setTab(SCTAB nTab) { mrCalcPos.SetTab(nTab); }
510 0 : void setCol(SCCOL nCol) { mrCalcPos.SetCol(nCol); }
511 0 : void setRow(SCROW nRow) { mrCalcPos.SetRow(nRow); }
512 :
513 400 : void incTab(SCTAB nInc=1) { mrCalcPos.IncTab(nInc); }
514 0 : void incCol(SCCOL nInc=1) { mrCalcPos.IncCol(nInc); }
515 :
516 0 : void setOldMapMode(const MapMode& rOldMapMode) { maOldMapMode = rOldMapMode; }
517 :
518 0 : void setNeedMore(bool b) { mbNeedMore = b; }
519 0 : bool getNeedMore() const { return mbNeedMore; }
520 :
521 0 : sal_uLong getStartTime() const { return mnStartTime; }
522 :
523 0 : void createProgressBar()
524 : {
525 0 : ScProgress::CreateInterpretProgress(&mrDoc, false);
526 0 : mbProgress = true;
527 0 : }
528 :
529 0 : bool hasProgressBar() const { return mbProgress; }
530 :
531 400 : ScStyleSheetPool* getStylePool() { return mpStylePool; }
532 : };
533 :
534 : }
535 :
536 1325 : bool ScDocument::IdleCalcTextWidth() // true = demnaechst wieder versuchen
537 : {
538 : // #i75610# if a printer hasn't been set or created yet, don't create one for this
539 1325 : if (!mbIdleEnabled || IsInLinkUpdate() || GetPrinter(false) == NULL)
540 925 : return false;
541 :
542 400 : IdleCalcTextWidthScope aScope(*this, aCurTextWidthCalcPos);
543 :
544 400 : if (!ValidRow(aScope.Row()))
545 : {
546 0 : aScope.setRow(0);
547 0 : aScope.incCol(-1);
548 : }
549 :
550 400 : if (aScope.Col() < 0)
551 : {
552 0 : aScope.setCol(MAXCOL);
553 0 : aScope.incTab();
554 : }
555 :
556 400 : if (!ValidTab(aScope.Tab()) || aScope.Tab() >= static_cast<SCTAB>(maTabs.size()) || !maTabs[aScope.Tab()])
557 319 : aScope.setTab(0);
558 :
559 400 : ScTable* pTab = maTabs[aScope.Tab()];
560 400 : ScStyleSheet* pStyle = static_cast<ScStyleSheet*>(aScope.getStylePool()->Find(pTab->aPageStyle, SFX_STYLE_FAMILY_PAGE));
561 : OSL_ENSURE( pStyle, "Missing StyleSheet :-/" );
562 :
563 400 : if (!pStyle || getScaleValue(*pStyle, ATTR_PAGE_SCALETOPAGES) == 0)
564 : {
565 : // Move to the next sheet as the current one has scale-to-pages set,
566 : // and bail out.
567 400 : aScope.incTab();
568 400 : return false;
569 : }
570 :
571 0 : sal_uInt16 nZoom = getScaleValue(*pStyle, ATTR_PAGE_SCALE);
572 0 : Fraction aZoomFract(nZoom, 100);
573 :
574 : // Start at specified cell position (nCol, nRow, nTab).
575 0 : ScColumn* pCol = &pTab->aCol[aScope.Col()];
576 0 : boost::scoped_ptr<ScColumnTextWidthIterator> pColIter(new ScColumnTextWidthIterator(*pCol, aScope.Row(), MAXROW));
577 :
578 0 : OutputDevice* pDev = NULL;
579 0 : sal_uInt16 nRestart = 0;
580 0 : sal_uInt16 nCount = 0;
581 0 : while ( (nZoom > 0) && (nCount < CALCMAX) && (nRestart < 2) )
582 : {
583 0 : if (pColIter->hasCell())
584 : {
585 : // More cell in this column.
586 0 : SCROW nRow = pColIter->getPos();
587 0 : aScope.setRow(nRow);
588 :
589 0 : if (pColIter->getValue() == TEXTWIDTH_DIRTY)
590 : {
591 : // Calculate text width for this cell.
592 0 : double nPPTX = 0.0;
593 0 : double nPPTY = 0.0;
594 0 : if (!pDev)
595 : {
596 0 : pDev = GetPrinter();
597 0 : aScope.setOldMapMode(pDev->GetMapMode());
598 0 : pDev->SetMapMode( MAP_PIXEL ); // wichtig fuer GetNeededSize
599 :
600 0 : Point aPix1000 = pDev->LogicToPixel( Point(1000,1000), MAP_TWIP );
601 0 : nPPTX = aPix1000.X() / 1000.0;
602 0 : nPPTY = aPix1000.Y() / 1000.0;
603 : }
604 :
605 0 : if (!aScope.hasProgressBar() && pCol->IsFormulaDirty(nRow))
606 0 : aScope.createProgressBar();
607 :
608 : sal_uInt16 nNewWidth = (sal_uInt16)GetNeededSize(
609 0 : aScope.Col(), aScope.Row(), aScope.Tab(),
610 0 : pDev, nPPTX, nPPTY, aZoomFract,aZoomFract, true, true); // bTotalSize
611 :
612 0 : pColIter->setValue(nNewWidth);
613 0 : aScope.setNeedMore(true);
614 : }
615 0 : pColIter->next();
616 : }
617 : else
618 : {
619 : // No more cell in this column. Move to the left column and start at row 0.
620 :
621 0 : bool bNewTab = false;
622 :
623 0 : aScope.setRow(0);
624 0 : aScope.incCol(-1);
625 :
626 0 : if (aScope.Col() < 0)
627 : {
628 : // No more column to the left. Move to the right-most column of the next sheet.
629 0 : aScope.setCol(MAXCOL);
630 0 : aScope.incTab();
631 0 : bNewTab = true;
632 : }
633 :
634 0 : if (!ValidTab(aScope.Tab()) || aScope.Tab() >= static_cast<SCTAB>(maTabs.size()) || !maTabs[aScope.Tab()] )
635 : {
636 : // Sheet doesn't exist at specified sheet position. Restart at sheet 0.
637 0 : aScope.setTab(0);
638 0 : nRestart++;
639 0 : bNewTab = true;
640 : }
641 :
642 0 : if ( nRestart < 2 )
643 : {
644 0 : if ( bNewTab )
645 : {
646 0 : pTab = maTabs[aScope.Tab()];
647 0 : pStyle = static_cast<ScStyleSheet*>(aScope.getStylePool()->Find(
648 0 : pTab->aPageStyle, SFX_STYLE_FAMILY_PAGE));
649 :
650 0 : if ( pStyle )
651 : {
652 : // Check if the scale-to-pages setting is set. If
653 : // set, we exit the loop. If not, get the page
654 : // scale factor of the new sheet.
655 0 : if (getScaleValue(*pStyle, ATTR_PAGE_SCALETOPAGES) == 0)
656 : {
657 0 : nZoom = getScaleValue(*pStyle, ATTR_PAGE_SCALE);
658 0 : aZoomFract = Fraction(nZoom, 100);
659 : }
660 : else
661 0 : nZoom = 0;
662 : }
663 : else
664 : {
665 : OSL_FAIL( "Missing StyleSheet :-/" );
666 : }
667 : }
668 :
669 0 : if ( nZoom > 0 )
670 : {
671 0 : pCol = &pTab->aCol[aScope.Col()];
672 0 : pColIter.reset(new ScColumnTextWidthIterator(*pCol, aScope.Row(), MAXROW));
673 : }
674 : else
675 : {
676 0 : aScope.incTab(); // Move to the next sheet as the current one has scale-to-pages set.
677 0 : return false;
678 : }
679 : }
680 : }
681 :
682 0 : ++nCount;
683 :
684 : // Quit if either 1) its duration exceeds 50 ms, or 2) there is any
685 : // pending event after processing 32 cells.
686 0 : if ((50L < tools::Time::GetSystemTicks() - aScope.getStartTime()) || (nCount > 31 && Application::AnyInput(ABORT_EVENTS)))
687 0 : nCount = CALCMAX;
688 : }
689 :
690 400 : return aScope.getNeedMore();
691 : }
692 :
693 11264 : void ScDocument::RepaintRange( const ScRange& rRange )
694 : {
695 11264 : if ( bIsVisible && pShell )
696 : {
697 342 : ScModelObj* pModel = ScModelObj::getImplementation( pShell->GetModel() );
698 342 : if ( pModel )
699 342 : pModel->RepaintRange( rRange ); // locked repaints are checked there
700 : }
701 11264 : }
702 :
703 0 : void ScDocument::RepaintRange( const ScRangeList& rRange )
704 : {
705 0 : if ( bIsVisible && pShell )
706 : {
707 0 : ScModelObj* pModel = ScModelObj::getImplementation( pShell->GetModel() );
708 0 : if ( pModel )
709 0 : pModel->RepaintRange( rRange ); // locked repaints are checked there
710 : }
711 0 : }
712 :
713 0 : void ScDocument::SaveDdeLinks(SvStream& rStream) const
714 : {
715 : // bei 4.0-Export alle mit Modus != DEFAULT weglassen
716 0 : bool bExport40 = ( rStream.GetVersion() <= SOFFICE_FILEFORMAT_40 );
717 :
718 0 : const ::sfx2::SvBaseLinks& rLinks = GetLinkManager()->GetLinks();
719 0 : sal_uInt16 nCount = rLinks.size();
720 :
721 : // erstmal zaehlen...
722 :
723 0 : sal_uInt16 nDdeCount = 0;
724 : sal_uInt16 i;
725 0 : for (i=0; i<nCount; i++)
726 : {
727 0 : ::sfx2::SvBaseLink* pBase = *rLinks[i];
728 0 : if (pBase->ISA(ScDdeLink))
729 0 : if ( !bExport40 || static_cast<ScDdeLink*>(pBase)->GetMode() == SC_DDE_DEFAULT )
730 0 : ++nDdeCount;
731 : }
732 :
733 : // Header
734 :
735 0 : ScMultipleWriteHeader aHdr( rStream );
736 0 : rStream.WriteUInt16( nDdeCount );
737 :
738 : // Links speichern
739 :
740 0 : for (i=0; i<nCount; i++)
741 : {
742 0 : ::sfx2::SvBaseLink* pBase = *rLinks[i];
743 0 : if (pBase->ISA(ScDdeLink))
744 : {
745 0 : ScDdeLink* pLink = static_cast<ScDdeLink*>(pBase);
746 0 : if ( !bExport40 || pLink->GetMode() == SC_DDE_DEFAULT )
747 0 : pLink->Store( rStream, aHdr );
748 : }
749 0 : }
750 0 : }
751 :
752 0 : void ScDocument::LoadDdeLinks(SvStream& rStream)
753 : {
754 0 : sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(bAutoCalc);
755 0 : if (!pMgr)
756 0 : return;
757 :
758 0 : ScMultipleReadHeader aHdr( rStream );
759 :
760 : sal_uInt16 nCount;
761 0 : rStream.ReadUInt16( nCount );
762 0 : for (sal_uInt16 i=0; i<nCount; i++)
763 : {
764 0 : ScDdeLink* pLink = new ScDdeLink( this, rStream, aHdr );
765 0 : pMgr->InsertDDELink(pLink, pLink->GetAppl(), pLink->GetTopic(), pLink->GetItem());
766 0 : }
767 : }
768 :
769 24 : void ScDocument::SetInLinkUpdate(bool bSet)
770 : {
771 : // called from TableLink and AreaLink
772 :
773 : OSL_ENSURE( bInLinkUpdate != bSet, "SetInLinkUpdate twice" );
774 24 : bInLinkUpdate = bSet;
775 24 : }
776 :
777 1313 : bool ScDocument::IsInLinkUpdate() const
778 : {
779 1313 : return bInLinkUpdate || IsInDdeLinkUpdate();
780 : }
781 :
782 0 : void ScDocument::UpdateExternalRefLinks(vcl::Window* pWin)
783 : {
784 0 : if (!pExternalRefMgr.get())
785 0 : return;
786 :
787 0 : sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(bAutoCalc);
788 0 : if (!pMgr)
789 0 : return;
790 :
791 0 : const ::sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
792 0 : sal_uInt16 nCount = rLinks.size();
793 :
794 0 : bool bAny = false;
795 :
796 : // Collect all the external ref links first.
797 0 : std::vector<ScExternalRefLink*> aRefLinks;
798 0 : for (sal_uInt16 i = 0; i < nCount; ++i)
799 : {
800 0 : ::sfx2::SvBaseLink* pBase = *rLinks[i];
801 0 : ScExternalRefLink* pRefLink = dynamic_cast<ScExternalRefLink*>(pBase);
802 0 : if (pRefLink)
803 0 : aRefLinks.push_back(pRefLink);
804 : }
805 :
806 0 : sc::WaitPointerSwitch aWaitSwitch(pWin);
807 :
808 0 : pExternalRefMgr->enableDocTimer(false);
809 0 : ScProgress aProgress(GetDocumentShell(), ScResId(SCSTR_UPDATE_EXTDOCS).toString(), aRefLinks.size());
810 0 : for (size_t i = 0, n = aRefLinks.size(); i < n; ++i)
811 : {
812 0 : aProgress.SetState(i+1);
813 :
814 0 : ScExternalRefLink* pRefLink = aRefLinks[i];
815 0 : if (pRefLink->Update())
816 : {
817 0 : bAny = true;
818 0 : continue;
819 : }
820 :
821 : // Update failed. Notify the user.
822 :
823 0 : OUString aFile;
824 0 : pMgr->GetDisplayNames(pRefLink, NULL, &aFile, NULL, NULL);
825 : // Decode encoded URL for display friendliness.
826 0 : INetURLObject aUrl(aFile,INetURLObject::WAS_ENCODED);
827 0 : aFile = aUrl.GetMainURL(INetURLObject::DECODE_UNAMBIGUOUS);
828 :
829 0 : OUStringBuffer aBuf;
830 0 : aBuf.append(OUString(ScResId(SCSTR_EXTDOC_NOT_LOADED)));
831 0 : aBuf.appendAscii("\n\n");
832 0 : aBuf.append(aFile);
833 0 : MessageDialog aBox(pWin, aBuf.makeStringAndClear());
834 0 : aBox.Execute();
835 0 : }
836 :
837 0 : pExternalRefMgr->enableDocTimer(true);
838 :
839 0 : if (bAny)
840 : {
841 0 : TrackFormulas();
842 0 : pShell->Broadcast( SfxSimpleHint(FID_DATACHANGED) );
843 :
844 : // #i101960# set document modified, as in TrackTimeHdl for DDE links
845 0 : if (!pShell->IsModified())
846 : {
847 0 : pShell->SetModified( true );
848 0 : SfxBindings* pBindings = GetViewBindings();
849 0 : if (pBindings)
850 : {
851 0 : pBindings->Invalidate( SID_SAVEDOC );
852 0 : pBindings->Invalidate( SID_DOC_MODIFIED );
853 : }
854 : }
855 0 : }
856 : }
857 :
858 0 : void ScDocument::CopyDdeLinks( ScDocument* pDestDoc ) const
859 : {
860 0 : if (bIsClip) // aus Stream erzeugen
861 : {
862 0 : if (pClipData)
863 : {
864 0 : pClipData->Seek(0);
865 0 : pDestDoc->LoadDdeLinks(*pClipData);
866 : }
867 :
868 0 : return;
869 : }
870 :
871 0 : const sfx2::LinkManager* pMgr = GetDocLinkManager().getExistingLinkManager();
872 0 : if (!pMgr)
873 0 : return;
874 :
875 0 : sfx2::LinkManager* pDestMgr = pDestDoc->GetDocLinkManager().getLinkManager(pDestDoc->bAutoCalc);
876 0 : if (!pDestMgr)
877 0 : return;
878 :
879 0 : const sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
880 0 : for (size_t i = 0, n = rLinks.size(); i < n; ++i)
881 : {
882 0 : const sfx2::SvBaseLink* pBase = *rLinks[i];
883 0 : if (pBase->ISA(ScDdeLink))
884 : {
885 0 : const ScDdeLink* p = static_cast<const ScDdeLink*>(pBase);
886 0 : ScDdeLink* pNew = new ScDdeLink(pDestDoc, *p);
887 : pDestMgr->InsertDDELink(
888 0 : pNew, pNew->GetAppl(), pNew->GetTopic(), pNew->GetItem());
889 : }
890 : }
891 : }
892 :
893 : namespace {
894 :
895 : /** Tries to find the specified DDE link.
896 : @param pnDdePos (out-param) if not 0, the index of the DDE link is returned here
897 : (does not include other links from link manager).
898 : @return The DDE link, if it exists, otherwise 0. */
899 0 : ScDdeLink* lclGetDdeLink(
900 : const sfx2::LinkManager* pLinkManager,
901 : const OUString& rAppl, const OUString& rTopic, const OUString& rItem, sal_uInt8 nMode,
902 : size_t* pnDdePos = NULL )
903 : {
904 0 : if( pLinkManager )
905 : {
906 0 : const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
907 0 : size_t nCount = rLinks.size();
908 0 : if( pnDdePos ) *pnDdePos = 0;
909 0 : for( size_t nIndex = 0; nIndex < nCount; ++nIndex )
910 : {
911 0 : ::sfx2::SvBaseLink* pLink = *rLinks[ nIndex ];
912 0 : if( ScDdeLink* pDdeLink = PTR_CAST( ScDdeLink, pLink ) )
913 : {
914 0 : if( (OUString(pDdeLink->GetAppl()) == rAppl) &&
915 0 : (OUString(pDdeLink->GetTopic()) == rTopic) &&
916 0 : (OUString(pDdeLink->GetItem()) == rItem) &&
917 0 : ((nMode == SC_DDE_IGNOREMODE) || (nMode == pDdeLink->GetMode())) )
918 0 : return pDdeLink;
919 0 : if( pnDdePos ) ++*pnDdePos;
920 : }
921 : }
922 : }
923 0 : return NULL;
924 : }
925 :
926 : /** Returns a pointer to the specified DDE link.
927 : @param nDdePos Index of the DDE link (does not include other links from link manager).
928 : @return The DDE link, if it exists, otherwise 0. */
929 26 : ScDdeLink* lclGetDdeLink( const sfx2::LinkManager* pLinkManager, size_t nDdePos )
930 : {
931 26 : if( pLinkManager )
932 : {
933 26 : const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
934 26 : size_t nCount = rLinks.size();
935 26 : size_t nDdeIndex = 0; // counts only the DDE links
936 30 : for( size_t nIndex = 0; nIndex < nCount; ++nIndex )
937 : {
938 26 : ::sfx2::SvBaseLink* pLink = *rLinks[ nIndex ];
939 26 : if( ScDdeLink* pDdeLink = PTR_CAST( ScDdeLink, pLink ) )
940 : {
941 26 : if( nDdeIndex == nDdePos )
942 22 : return pDdeLink;
943 4 : ++nDdeIndex;
944 : }
945 : }
946 : }
947 4 : return NULL;
948 : }
949 :
950 : } // namespace
951 :
952 0 : bool ScDocument::FindDdeLink( const OUString& rAppl, const OUString& rTopic, const OUString& rItem,
953 : sal_uInt8 nMode, size_t& rnDdePos )
954 : {
955 0 : return lclGetDdeLink( GetLinkManager(), rAppl, rTopic, rItem, nMode, &rnDdePos ) != NULL;
956 : }
957 :
958 26 : bool ScDocument::GetDdeLinkData( size_t nDdePos, OUString& rAppl, OUString& rTopic, OUString& rItem ) const
959 : {
960 26 : if( const ScDdeLink* pDdeLink = lclGetDdeLink( GetLinkManager(), nDdePos ) )
961 : {
962 22 : rAppl = pDdeLink->GetAppl();
963 22 : rTopic = pDdeLink->GetTopic();
964 22 : rItem = pDdeLink->GetItem();
965 22 : return true;
966 : }
967 4 : return false;
968 : }
969 :
970 0 : bool ScDocument::GetDdeLinkMode( size_t nDdePos, sal_uInt8& rnMode ) const
971 : {
972 0 : if( const ScDdeLink* pDdeLink = lclGetDdeLink( GetLinkManager(), nDdePos ) )
973 : {
974 0 : rnMode = pDdeLink->GetMode();
975 0 : return true;
976 : }
977 0 : return false;
978 : }
979 :
980 0 : const ScMatrix* ScDocument::GetDdeLinkResultMatrix( size_t nDdePos ) const
981 : {
982 0 : const ScDdeLink* pDdeLink = lclGetDdeLink( GetLinkManager(), nDdePos );
983 0 : return pDdeLink ? pDdeLink->GetResult() : NULL;
984 : }
985 :
986 0 : bool ScDocument::CreateDdeLink( const OUString& rAppl, const OUString& rTopic, const OUString& rItem, sal_uInt8 nMode, ScMatrixRef pResults )
987 : {
988 : /* Create a DDE link without updating it (i.e. for Excel import), to prevent
989 : unwanted connections. First try to find existing link. Set result array
990 : on existing and new links. */
991 : //! store DDE links additionally at document (for efficiency)?
992 : OSL_ENSURE( nMode != SC_DDE_IGNOREMODE, "ScDocument::CreateDdeLink - SC_DDE_IGNOREMODE not allowed here" );
993 :
994 0 : sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(bAutoCalc);
995 0 : if (!pMgr)
996 0 : return false;
997 :
998 0 : if (nMode != SC_DDE_IGNOREMODE)
999 : {
1000 0 : ScDdeLink* pDdeLink = lclGetDdeLink(pMgr, rAppl, rTopic, rItem, nMode);
1001 0 : if( !pDdeLink )
1002 : {
1003 : // create a new DDE link, but without TryUpdate
1004 0 : pDdeLink = new ScDdeLink( this, rAppl, rTopic, rItem, nMode );
1005 0 : pMgr->InsertDDELink(pDdeLink, rAppl, rTopic, rItem);
1006 : }
1007 :
1008 : // insert link results
1009 0 : if( pResults )
1010 0 : pDdeLink->SetResult( pResults );
1011 :
1012 0 : return true;
1013 : }
1014 0 : return false;
1015 : }
1016 :
1017 0 : bool ScDocument::SetDdeLinkResultMatrix( size_t nDdePos, ScMatrixRef pResults )
1018 : {
1019 0 : if( ScDdeLink* pDdeLink = lclGetDdeLink( GetLinkManager(), nDdePos ) )
1020 : {
1021 0 : pDdeLink->SetResult( pResults );
1022 0 : return true;
1023 : }
1024 0 : return false;
1025 : }
1026 :
1027 544 : bool ScDocument::HasAreaLinks() const
1028 : {
1029 544 : const sfx2::LinkManager* pMgr = GetDocLinkManager().getExistingLinkManager();
1030 544 : if (!pMgr)
1031 364 : return false;
1032 :
1033 180 : const ::sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
1034 180 : sal_uInt16 nCount = rLinks.size();
1035 180 : for (sal_uInt16 i=0; i<nCount; i++)
1036 0 : if ((*rLinks[i])->ISA(ScAreaLink))
1037 0 : return true;
1038 :
1039 180 : return false;
1040 : }
1041 :
1042 0 : void ScDocument::UpdateAreaLinks()
1043 : {
1044 0 : sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(false);
1045 0 : if (!pMgr)
1046 0 : return;
1047 :
1048 0 : const ::sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
1049 0 : for (sal_uInt16 i=0; i<rLinks.size(); i++)
1050 : {
1051 0 : ::sfx2::SvBaseLink* pBase = *rLinks[i];
1052 0 : if (pBase->ISA(ScAreaLink))
1053 0 : pBase->Update();
1054 : }
1055 : }
1056 :
1057 178 : void ScDocument::DeleteAreaLinksOnTab( SCTAB nTab )
1058 : {
1059 178 : sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(false);
1060 178 : if (!pMgr)
1061 302 : return;
1062 :
1063 54 : const ::sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
1064 54 : sal_uInt16 nPos = 0;
1065 108 : while ( nPos < rLinks.size() )
1066 : {
1067 0 : const ::sfx2::SvBaseLink* pBase = *rLinks[nPos];
1068 0 : if ( pBase->ISA(ScAreaLink) &&
1069 0 : static_cast<const ScAreaLink*>(pBase)->GetDestArea().aStart.Tab() == nTab )
1070 0 : pMgr->Remove(nPos);
1071 : else
1072 0 : ++nPos;
1073 : }
1074 : }
1075 :
1076 666 : void ScDocument::UpdateRefAreaLinks( UpdateRefMode eUpdateRefMode,
1077 : const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
1078 : {
1079 666 : sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(false);
1080 666 : if (!pMgr)
1081 1056 : return;
1082 :
1083 276 : bool bAnyUpdate = false;
1084 :
1085 276 : const ::sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
1086 276 : sal_uInt16 nCount = rLinks.size();
1087 282 : for (sal_uInt16 i=0; i<nCount; i++)
1088 : {
1089 6 : ::sfx2::SvBaseLink* pBase = *rLinks[i];
1090 6 : if (pBase->ISA(ScAreaLink))
1091 : {
1092 0 : ScAreaLink* pLink = static_cast<ScAreaLink*>(pBase);
1093 0 : ScRange aOutRange = pLink->GetDestArea();
1094 :
1095 0 : SCCOL nCol1 = aOutRange.aStart.Col();
1096 0 : SCROW nRow1 = aOutRange.aStart.Row();
1097 0 : SCTAB nTab1 = aOutRange.aStart.Tab();
1098 0 : SCCOL nCol2 = aOutRange.aEnd.Col();
1099 0 : SCROW nRow2 = aOutRange.aEnd.Row();
1100 0 : SCTAB nTab2 = aOutRange.aEnd.Tab();
1101 :
1102 : ScRefUpdateRes eRes =
1103 : ScRefUpdate::Update( this, eUpdateRefMode,
1104 0 : rRange.aStart.Col(), rRange.aStart.Row(), rRange.aStart.Tab(),
1105 0 : rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aEnd.Tab(), nDx, nDy, nDz,
1106 0 : nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
1107 0 : if ( eRes != UR_NOTHING )
1108 : {
1109 0 : pLink->SetDestArea( ScRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ) );
1110 0 : bAnyUpdate = true;
1111 : }
1112 : }
1113 : }
1114 :
1115 276 : if ( bAnyUpdate )
1116 : {
1117 : // #i52120# Look for duplicates (after updating all positions).
1118 : // If several links start at the same cell, the one with the lower index is removed
1119 : // (file format specifies only one link definition for a cell).
1120 :
1121 0 : sal_uInt16 nFirstIndex = 0;
1122 0 : while ( nFirstIndex < nCount )
1123 : {
1124 0 : bool bFound = false;
1125 0 : ::sfx2::SvBaseLink* pFirst = *rLinks[nFirstIndex];
1126 0 : if ( pFirst->ISA(ScAreaLink) )
1127 : {
1128 0 : ScAddress aFirstPos = static_cast<ScAreaLink*>(pFirst)->GetDestArea().aStart;
1129 0 : for ( sal_uInt16 nSecondIndex = nFirstIndex + 1; nSecondIndex < nCount && !bFound; ++nSecondIndex )
1130 : {
1131 0 : ::sfx2::SvBaseLink* pSecond = *rLinks[nSecondIndex];
1132 0 : if ( pSecond->ISA(ScAreaLink) &&
1133 0 : static_cast<ScAreaLink*>(pSecond)->GetDestArea().aStart == aFirstPos )
1134 : {
1135 : // remove the first link, exit the inner loop, don't increment nFirstIndex
1136 0 : pMgr->Remove(pFirst);
1137 0 : nCount = rLinks.size();
1138 0 : bFound = true;
1139 : }
1140 : }
1141 : }
1142 0 : if (!bFound)
1143 0 : ++nFirstIndex;
1144 : }
1145 : }
1146 : }
1147 :
1148 : // TimerDelays etc.
1149 0 : void ScDocument::KeyInput( const KeyEvent& )
1150 : {
1151 0 : if ( pChartListenerCollection->hasListeners() )
1152 0 : pChartListenerCollection->StartTimer();
1153 0 : if( apTemporaryChartLock.get() )
1154 0 : apTemporaryChartLock->StartOrContinueLocking();
1155 0 : }
1156 :
1157 0 : bool ScDocument::CheckMacroWarn()
1158 : {
1159 : // The check for macro configuration, macro warning and disabling is now handled
1160 : // in SfxObjectShell::AdjustMacroMode, called by SfxObjectShell::CallBasic.
1161 :
1162 0 : return true;
1163 : }
1164 :
1165 12 : SfxBindings* ScDocument::GetViewBindings()
1166 : {
1167 : // used to invalidate slots after changes to this document
1168 :
1169 12 : if ( !pShell )
1170 0 : return NULL; // no ObjShell -> no view
1171 :
1172 : // first check current view
1173 12 : SfxViewFrame* pViewFrame = SfxViewFrame::Current();
1174 12 : if ( pViewFrame && pViewFrame->GetObjectShell() != pShell ) // wrong document?
1175 12 : pViewFrame = NULL;
1176 :
1177 : // otherwise use first view for this doc
1178 12 : if ( !pViewFrame )
1179 12 : pViewFrame = SfxViewFrame::GetFirst( pShell );
1180 :
1181 12 : if (pViewFrame)
1182 6 : return &pViewFrame->GetBindings();
1183 : else
1184 6 : return NULL;
1185 : }
1186 :
1187 4 : void ScDocument::TransliterateText( const ScMarkData& rMultiMark, sal_Int32 nType )
1188 : {
1189 : OSL_ENSURE( rMultiMark.IsMultiMarked(), "TransliterateText: no selection" );
1190 :
1191 4 : utl::TransliterationWrapper aTranslitarationWrapper( comphelper::getProcessComponentContext(), nType );
1192 4 : bool bConsiderLanguage = aTranslitarationWrapper.needLanguageForTheMode();
1193 4 : sal_uInt16 nLanguage = LANGUAGE_SYSTEM;
1194 :
1195 8 : boost::scoped_ptr<ScEditEngineDefaulter> pEngine; // not using pEditEngine member because of defaults
1196 :
1197 4 : SCTAB nCount = GetTableCount();
1198 4 : ScMarkData::const_iterator itr = rMultiMark.begin(), itrEnd = rMultiMark.end();
1199 8 : for (; itr != itrEnd && *itr < nCount; ++itr)
1200 4 : if ( maTabs[*itr] )
1201 : {
1202 4 : SCTAB nTab = *itr;
1203 4 : SCCOL nCol = 0;
1204 4 : SCROW nRow = 0;
1205 :
1206 4 : bool bFound = rMultiMark.IsCellMarked( nCol, nRow );
1207 4 : if (!bFound)
1208 0 : bFound = GetNextMarkedCell( nCol, nRow, nTab, rMultiMark );
1209 :
1210 20 : while (bFound)
1211 : {
1212 12 : ScRefCellValue aCell;
1213 12 : aCell.assign(*this, ScAddress(nCol, nRow, nTab));
1214 :
1215 : // fdo#32786 TITLE_CASE/SENTENCE_CASE need the extra handling in EditEngine (loop over words/sentences).
1216 : // Still use TransliterationWrapper directly for text cells with other transliteration types,
1217 : // for performance reasons.
1218 24 : if (aCell.meType == CELLTYPE_EDIT ||
1219 24 : (aCell.meType == CELLTYPE_STRING &&
1220 12 : ( nType == i18n::TransliterationModulesExtra::SENTENCE_CASE || nType == i18n::TransliterationModulesExtra::TITLE_CASE)))
1221 : {
1222 0 : if (!pEngine)
1223 0 : pEngine.reset(new ScFieldEditEngine(this, GetEnginePool(), GetEditPool()));
1224 :
1225 : // defaults from cell attributes must be set so right language is used
1226 0 : const ScPatternAttr* pPattern = GetPattern( nCol, nRow, nTab );
1227 0 : SfxItemSet* pDefaults = new SfxItemSet( pEngine->GetEmptyItemSet() );
1228 0 : if ( ScStyleSheet* pPreviewStyle = GetPreviewCellStyle( nCol, nRow, nTab ) )
1229 : {
1230 0 : boost::scoped_ptr<ScPatternAttr> pPreviewPattern(new ScPatternAttr( *pPattern ));
1231 0 : pPreviewPattern->SetStyleSheet(pPreviewStyle);
1232 0 : pPreviewPattern->FillEditItemSet( pDefaults );
1233 : }
1234 : else
1235 : {
1236 0 : SfxItemSet* pFontSet = GetPreviewFont( nCol, nRow, nTab );
1237 0 : pPattern->FillEditItemSet( pDefaults, pFontSet );
1238 : }
1239 0 : pEngine->SetDefaults( pDefaults, true );
1240 0 : if (aCell.meType == CELLTYPE_STRING)
1241 0 : pEngine->SetText(aCell.mpString->getString());
1242 0 : else if (aCell.mpEditText)
1243 0 : pEngine->SetText(*aCell.mpEditText);
1244 :
1245 0 : pEngine->ClearModifyFlag();
1246 :
1247 0 : sal_Int32 nLastPar = pEngine->GetParagraphCount();
1248 0 : if (nLastPar)
1249 0 : --nLastPar;
1250 0 : sal_Int32 nTxtLen = pEngine->GetTextLen(nLastPar);
1251 0 : ESelection aSelAll( 0, 0, nLastPar, nTxtLen );
1252 :
1253 0 : pEngine->TransliterateText( aSelAll, nType );
1254 :
1255 0 : if ( pEngine->IsModified() )
1256 : {
1257 0 : ScEditAttrTester aTester( pEngine.get() );
1258 0 : if ( aTester.NeedsObject() )
1259 : {
1260 : // remove defaults (paragraph attributes) before creating text object
1261 0 : SfxItemSet* pEmpty = new SfxItemSet( pEngine->GetEmptyItemSet() );
1262 0 : pEngine->SetDefaults( pEmpty, true );
1263 :
1264 : // The cell will take ownership of the text object instance.
1265 0 : SetEditText(ScAddress(nCol,nRow,nTab), pEngine->CreateTextObject());
1266 : }
1267 : else
1268 : {
1269 0 : ScSetStringParam aParam;
1270 0 : aParam.setTextInput();
1271 0 : SetString(ScAddress(nCol,nRow,nTab), pEngine->GetText(), &aParam);
1272 0 : }
1273 0 : }
1274 : }
1275 :
1276 12 : else if (aCell.meType == CELLTYPE_STRING)
1277 : {
1278 12 : OUString aOldStr = aCell.mpString->getString();
1279 12 : sal_Int32 nOldLen = aOldStr.getLength();
1280 :
1281 12 : if ( bConsiderLanguage )
1282 : {
1283 12 : sal_uInt8 nScript = GetStringScriptType( aOldStr ); //! cell script type?
1284 : sal_uInt16 nWhich = ( nScript == SCRIPTTYPE_ASIAN ) ? ATTR_CJK_FONT_LANGUAGE :
1285 : ( ( nScript == SCRIPTTYPE_COMPLEX ) ? ATTR_CTL_FONT_LANGUAGE :
1286 12 : ATTR_FONT_LANGUAGE );
1287 12 : nLanguage = static_cast<const SvxLanguageItem*>(GetAttr( nCol, nRow, nTab, nWhich ))->GetValue();
1288 : }
1289 :
1290 24 : uno::Sequence<sal_Int32> aOffsets;
1291 24 : OUString aNewStr = aTranslitarationWrapper.transliterate( aOldStr, nLanguage, 0, nOldLen, &aOffsets );
1292 :
1293 12 : if ( aNewStr != aOldStr )
1294 : {
1295 12 : ScSetStringParam aParam;
1296 12 : aParam.setTextInput();
1297 12 : SetString(ScAddress(nCol,nRow,nTab), aNewStr, &aParam);
1298 12 : }
1299 : }
1300 12 : bFound = GetNextMarkedCell( nCol, nRow, nTab, rMultiMark );
1301 12 : }
1302 4 : }
1303 232 : }
1304 :
1305 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|