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