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 :
22 : #include <sfx2/app.hxx>
23 : #include <editeng/editobj.hxx>
24 : #include <sfx2/linkmgr.hxx>
25 : #include <sfx2/bindings.hxx>
26 : #include <vcl/msgbox.hxx>
27 : #include <vcl/virdev.hxx>
28 : #include <vcl/waitobj.hxx>
29 : #include <svl/PasswordHelper.hxx>
30 :
31 : #include <com/sun/star/container/XNameContainer.hpp>
32 : #include <com/sun/star/script/ModuleType.hpp>
33 : #include <com/sun/star/script/XLibraryContainer.hpp>
34 : #include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
35 :
36 : #include "docfunc.hxx"
37 :
38 : #include "sc.hrc"
39 :
40 : #include "arealink.hxx"
41 : #include "attrib.hxx"
42 : #include "dociter.hxx"
43 : #include "autoform.hxx"
44 : #include "formulacell.hxx"
45 : #include "cellmergeoption.hxx"
46 : #include "detdata.hxx"
47 : #include "detfunc.hxx"
48 : #include "docpool.hxx"
49 : #include "docsh.hxx"
50 : #include "drwlayer.hxx"
51 : #include "editutil.hxx"
52 : #include "globstr.hrc"
53 : #include "globalnames.hxx"
54 : #include "olinetab.hxx"
55 : #include "patattr.hxx"
56 : #include "rangenam.hxx"
57 : #include "rangeutl.hxx"
58 : #include "refundo.hxx"
59 : #include "scresid.hxx"
60 : #include "stlpool.hxx"
61 : #include "stlsheet.hxx"
62 : #include "tablink.hxx"
63 : #include "tabvwsh.hxx"
64 : #include "uiitems.hxx"
65 : #include "undoblk.hxx"
66 : #include "undocell.hxx"
67 : #include "undodraw.hxx"
68 : #include "undotab.hxx"
69 : #include "waitoff.hxx"
70 : #include "sizedev.hxx"
71 : #include "scmod.hxx"
72 : #include "inputhdl.hxx"
73 : #include "inputwin.hxx"
74 : #include "editable.hxx"
75 : #include "compiler.hxx"
76 : #include "scui_def.hxx"
77 : #include "tabprotection.hxx"
78 : #include "clipparam.hxx"
79 : #include "externalrefmgr.hxx"
80 : #include "undorangename.hxx"
81 : #include "progress.hxx"
82 : #include "dpobject.hxx"
83 : #include "stringutil.hxx"
84 : #include "cellvalue.hxx"
85 : #include "tokenarray.hxx"
86 :
87 : #include <memory>
88 : #include <basic/basmgr.hxx>
89 : #include <boost/scoped_ptr.hpp>
90 : #include <set>
91 : #include <vector>
92 :
93 : using namespace com::sun::star;
94 : using ::com::sun::star::uno::Sequence;
95 : using ::std::vector;
96 :
97 :
98 : // STATIC DATA -----------------------------------------------------------
99 :
100 : //========================================================================
101 :
102 94 : IMPL_LINK( ScDocFunc, NotifyDrawUndo, SdrUndoAction*, pUndoAction )
103 : {
104 : // #i101118# if drawing layer collects the undo actions, add it there
105 47 : ScDrawLayer* pDrawLayer = rDocShell.GetDocument()->GetDrawLayer();
106 47 : if( pDrawLayer && pDrawLayer->IsRecording() )
107 0 : pDrawLayer->AddCalcUndo( pUndoAction );
108 : else
109 47 : rDocShell.GetUndoManager()->AddUndoAction( new ScUndoDraw( pUndoAction, &rDocShell ) );
110 47 : rDocShell.SetDrawModified();
111 :
112 : // the affected sheet isn't known, so all stream positions are invalidated
113 47 : ScDocument* pDoc = rDocShell.GetDocument();
114 47 : SCTAB nTabCount = pDoc->GetTableCount();
115 168 : for (SCTAB nTab=0; nTab<nTabCount; nTab++)
116 121 : if (pDoc->IsStreamValid(nTab))
117 0 : pDoc->SetStreamValid(nTab, false);
118 :
119 47 : return 0;
120 : }
121 :
122 : //------------------------------------------------------------------------
123 :
124 : // Zeile ueber dem Range painten (fuer Linien nach AdjustRowHeight)
125 :
126 21 : static void lcl_PaintAbove( ScDocShell& rDocShell, const ScRange& rRange )
127 : {
128 21 : SCROW nRow = rRange.aStart.Row();
129 21 : if ( nRow > 0 )
130 : {
131 5 : SCTAB nTab = rRange.aStart.Tab(); //! alle?
132 5 : --nRow;
133 5 : rDocShell.PostPaint( ScRange(0,nRow,nTab, MAXCOL,nRow,nTab), PAINT_GRID );
134 : }
135 21 : }
136 :
137 : //------------------------------------------------------------------------
138 :
139 1435 : sal_Bool ScDocFunc::AdjustRowHeight( const ScRange& rRange, sal_Bool bPaint )
140 : {
141 1435 : ScDocument* pDoc = rDocShell.GetDocument();
142 1435 : if ( pDoc->IsImportingXML() )
143 : {
144 : // for XML import, all row heights are updated together after importing
145 674 : return false;
146 : }
147 761 : if ( !pDoc->IsAdjustHeightEnabled() )
148 : {
149 107 : return false;
150 : }
151 :
152 654 : SCTAB nTab = rRange.aStart.Tab();
153 654 : SCROW nStartRow = rRange.aStart.Row();
154 654 : SCROW nEndRow = rRange.aEnd.Row();
155 :
156 654 : ScSizeDeviceProvider aProv( &rDocShell );
157 654 : Fraction aOne(1,1);
158 :
159 : sal_Bool bChanged = pDoc->SetOptimalHeight( nStartRow, nEndRow, nTab, 0, aProv.GetDevice(),
160 654 : aProv.GetPPTX(), aProv.GetPPTY(), aOne, aOne, false );
161 :
162 654 : if ( bPaint && bChanged )
163 : rDocShell.PostPaint(ScRange(0, nStartRow, nTab, MAXCOL, MAXROW, nTab),
164 103 : PAINT_GRID | PAINT_LEFT);
165 :
166 654 : return bChanged;
167 : }
168 :
169 :
170 : //------------------------------------------------------------------------
171 :
172 1 : sal_Bool ScDocFunc::DetectiveAddPred(const ScAddress& rPos)
173 : {
174 1 : ScDocShellModificator aModificator( rDocShell );
175 :
176 1 : rDocShell.MakeDrawLayer();
177 1 : ScDocument* pDoc = rDocShell.GetDocument();
178 1 : bool bUndo (pDoc->IsUndoEnabled());
179 1 : ScDrawLayer* pModel = pDoc->GetDrawLayer();
180 1 : SCCOL nCol = rPos.Col();
181 1 : SCROW nRow = rPos.Row();
182 1 : SCTAB nTab = rPos.Tab();
183 :
184 1 : if (bUndo)
185 1 : pModel->BeginCalcUndo(false);
186 1 : sal_Bool bDone = ScDetectiveFunc( pDoc,nTab ).ShowPred( nCol, nRow );
187 1 : SdrUndoGroup* pUndo = NULL;
188 1 : if (bUndo)
189 1 : pUndo = pModel->GetCalcUndo();
190 1 : if (bDone)
191 : {
192 1 : ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_ADDPRED );
193 1 : pDoc->AddDetectiveOperation( aOperation );
194 1 : if (bUndo)
195 : {
196 1 : rDocShell.GetUndoManager()->AddUndoAction(
197 1 : new ScUndoDetective( &rDocShell, pUndo, &aOperation ) );
198 : }
199 1 : aModificator.SetDocumentModified();
200 1 : SfxBindings* pBindings = rDocShell.GetViewBindings();
201 1 : if (pBindings)
202 1 : pBindings->Invalidate( SID_DETECTIVE_REFRESH );
203 : }
204 : else
205 0 : delete pUndo;
206 :
207 1 : return bDone;
208 : }
209 :
210 0 : sal_Bool ScDocFunc::DetectiveDelPred(const ScAddress& rPos)
211 : {
212 0 : ScDocument* pDoc = rDocShell.GetDocument();
213 :
214 0 : bool bUndo(pDoc->IsUndoEnabled());
215 0 : ScDrawLayer* pModel = pDoc->GetDrawLayer();
216 0 : if (!pModel)
217 0 : return false;
218 :
219 0 : ScDocShellModificator aModificator( rDocShell );
220 :
221 0 : SCCOL nCol = rPos.Col();
222 0 : SCROW nRow = rPos.Row();
223 0 : SCTAB nTab = rPos.Tab();
224 :
225 0 : if (bUndo)
226 0 : pModel->BeginCalcUndo(false);
227 0 : sal_Bool bDone = ScDetectiveFunc( pDoc,nTab ).DeletePred( nCol, nRow );
228 0 : SdrUndoGroup* pUndo = NULL;
229 0 : if (bUndo)
230 0 : pUndo = pModel->GetCalcUndo();
231 0 : if (bDone)
232 : {
233 0 : ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_DELPRED );
234 0 : pDoc->AddDetectiveOperation( aOperation );
235 0 : if (bUndo)
236 : {
237 0 : rDocShell.GetUndoManager()->AddUndoAction(
238 0 : new ScUndoDetective( &rDocShell, pUndo, &aOperation ) );
239 : }
240 0 : aModificator.SetDocumentModified();
241 0 : SfxBindings* pBindings = rDocShell.GetViewBindings();
242 0 : if (pBindings)
243 0 : pBindings->Invalidate( SID_DETECTIVE_REFRESH );
244 : }
245 : else
246 0 : delete pUndo;
247 :
248 0 : return bDone;
249 : }
250 :
251 0 : sal_Bool ScDocFunc::DetectiveAddSucc(const ScAddress& rPos)
252 : {
253 0 : ScDocShellModificator aModificator( rDocShell );
254 :
255 0 : rDocShell.MakeDrawLayer();
256 0 : ScDocument* pDoc = rDocShell.GetDocument();
257 :
258 0 : bool bUndo(pDoc->IsUndoEnabled());
259 0 : ScDrawLayer* pModel = pDoc->GetDrawLayer();
260 0 : SCCOL nCol = rPos.Col();
261 0 : SCROW nRow = rPos.Row();
262 0 : SCTAB nTab = rPos.Tab();
263 :
264 0 : if (bUndo)
265 0 : pModel->BeginCalcUndo(false);
266 0 : sal_Bool bDone = ScDetectiveFunc( pDoc,nTab ).ShowSucc( nCol, nRow );
267 0 : SdrUndoGroup* pUndo = NULL;
268 0 : if (bUndo)
269 0 : pUndo = pModel->GetCalcUndo();
270 0 : if (bDone)
271 : {
272 0 : ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_ADDSUCC );
273 0 : pDoc->AddDetectiveOperation( aOperation );
274 0 : if (bUndo)
275 : {
276 0 : rDocShell.GetUndoManager()->AddUndoAction(
277 0 : new ScUndoDetective( &rDocShell, pUndo, &aOperation ) );
278 : }
279 0 : aModificator.SetDocumentModified();
280 0 : SfxBindings* pBindings = rDocShell.GetViewBindings();
281 0 : if (pBindings)
282 0 : pBindings->Invalidate( SID_DETECTIVE_REFRESH );
283 : }
284 : else
285 0 : delete pUndo;
286 :
287 0 : return bDone;
288 : }
289 :
290 0 : sal_Bool ScDocFunc::DetectiveDelSucc(const ScAddress& rPos)
291 : {
292 0 : ScDocument* pDoc = rDocShell.GetDocument();
293 :
294 0 : bool bUndo (pDoc->IsUndoEnabled());
295 0 : ScDrawLayer* pModel = pDoc->GetDrawLayer();
296 0 : if (!pModel)
297 0 : return false;
298 :
299 0 : ScDocShellModificator aModificator( rDocShell );
300 :
301 0 : SCCOL nCol = rPos.Col();
302 0 : SCROW nRow = rPos.Row();
303 0 : SCTAB nTab = rPos.Tab();
304 :
305 0 : if (bUndo)
306 0 : pModel->BeginCalcUndo(false);
307 0 : sal_Bool bDone = ScDetectiveFunc( pDoc,nTab ).DeleteSucc( nCol, nRow );
308 0 : SdrUndoGroup* pUndo = NULL;
309 0 : if (bUndo)
310 0 : pUndo = pModel->GetCalcUndo();
311 0 : if (bDone)
312 : {
313 0 : ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_DELSUCC );
314 0 : pDoc->AddDetectiveOperation( aOperation );
315 0 : if (bUndo)
316 : {
317 0 : rDocShell.GetUndoManager()->AddUndoAction(
318 0 : new ScUndoDetective( &rDocShell, pUndo, &aOperation ) );
319 : }
320 0 : aModificator.SetDocumentModified();
321 0 : SfxBindings* pBindings = rDocShell.GetViewBindings();
322 0 : if (pBindings)
323 0 : pBindings->Invalidate( SID_DETECTIVE_REFRESH );
324 : }
325 : else
326 0 : delete pUndo;
327 :
328 0 : return bDone;
329 : }
330 :
331 0 : sal_Bool ScDocFunc::DetectiveAddError(const ScAddress& rPos)
332 : {
333 0 : ScDocShellModificator aModificator( rDocShell );
334 :
335 0 : rDocShell.MakeDrawLayer();
336 0 : ScDocument* pDoc = rDocShell.GetDocument();
337 :
338 0 : bool bUndo (pDoc->IsUndoEnabled());
339 0 : ScDrawLayer* pModel = pDoc->GetDrawLayer();
340 0 : SCCOL nCol = rPos.Col();
341 0 : SCROW nRow = rPos.Row();
342 0 : SCTAB nTab = rPos.Tab();
343 :
344 0 : if (bUndo)
345 0 : pModel->BeginCalcUndo(false);
346 0 : sal_Bool bDone = ScDetectiveFunc( pDoc,nTab ).ShowError( nCol, nRow );
347 0 : SdrUndoGroup* pUndo = NULL;
348 0 : if (bUndo)
349 0 : pUndo = pModel->GetCalcUndo();
350 0 : if (bDone)
351 : {
352 0 : ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_ADDERROR );
353 0 : pDoc->AddDetectiveOperation( aOperation );
354 0 : if (bUndo)
355 : {
356 0 : rDocShell.GetUndoManager()->AddUndoAction(
357 0 : new ScUndoDetective( &rDocShell, pUndo, &aOperation ) );
358 : }
359 0 : aModificator.SetDocumentModified();
360 0 : SfxBindings* pBindings = rDocShell.GetViewBindings();
361 0 : if (pBindings)
362 0 : pBindings->Invalidate( SID_DETECTIVE_REFRESH );
363 : }
364 : else
365 0 : delete pUndo;
366 :
367 0 : return bDone;
368 : }
369 :
370 0 : sal_Bool ScDocFunc::DetectiveMarkInvalid(SCTAB nTab)
371 : {
372 0 : ScDocShellModificator aModificator( rDocShell );
373 :
374 0 : rDocShell.MakeDrawLayer();
375 0 : ScDocument* pDoc = rDocShell.GetDocument();
376 :
377 0 : bool bUndo (pDoc->IsUndoEnabled());
378 0 : ScDrawLayer* pModel = pDoc->GetDrawLayer();
379 :
380 0 : Window* pWaitWin = rDocShell.GetActiveDialogParent();
381 0 : if (pWaitWin)
382 0 : pWaitWin->EnterWait();
383 0 : if (bUndo)
384 0 : pModel->BeginCalcUndo(false);
385 : sal_Bool bOverflow;
386 0 : sal_Bool bDone = ScDetectiveFunc( pDoc,nTab ).MarkInvalid( bOverflow );
387 0 : SdrUndoGroup* pUndo = NULL;
388 0 : if (bUndo)
389 0 : pUndo = pModel->GetCalcUndo();
390 0 : if (pWaitWin)
391 0 : pWaitWin->LeaveWait();
392 0 : if (bDone)
393 : {
394 0 : if (pUndo && bUndo)
395 : {
396 0 : pUndo->SetComment( ScGlobal::GetRscString( STR_UNDO_DETINVALID ) );
397 0 : rDocShell.GetUndoManager()->AddUndoAction( pUndo );
398 : }
399 0 : aModificator.SetDocumentModified();
400 0 : if ( bOverflow )
401 : {
402 : InfoBox( NULL,
403 0 : ScGlobal::GetRscString( STR_DETINVALID_OVERFLOW ) ).Execute();
404 : }
405 : }
406 : else
407 0 : delete pUndo;
408 :
409 0 : return bDone;
410 : }
411 :
412 0 : sal_Bool ScDocFunc::DetectiveDelAll(SCTAB nTab)
413 : {
414 0 : ScDocument* pDoc = rDocShell.GetDocument();
415 :
416 0 : bool bUndo (pDoc->IsUndoEnabled());
417 0 : ScDrawLayer* pModel = pDoc->GetDrawLayer();
418 0 : if (!pModel)
419 0 : return false;
420 :
421 0 : ScDocShellModificator aModificator( rDocShell );
422 :
423 0 : if (bUndo)
424 0 : pModel->BeginCalcUndo(false);
425 0 : sal_Bool bDone = ScDetectiveFunc( pDoc,nTab ).DeleteAll( SC_DET_DETECTIVE );
426 0 : SdrUndoGroup* pUndo = NULL;
427 0 : if (bUndo)
428 0 : pUndo = pModel->GetCalcUndo();
429 0 : if (bDone)
430 : {
431 0 : ScDetOpList* pOldList = pDoc->GetDetOpList();
432 0 : ScDetOpList* pUndoList = NULL;
433 0 : if (bUndo)
434 0 : pUndoList = pOldList ? new ScDetOpList(*pOldList) : NULL;
435 :
436 0 : pDoc->ClearDetectiveOperations();
437 :
438 0 : if (bUndo)
439 : {
440 0 : rDocShell.GetUndoManager()->AddUndoAction(
441 0 : new ScUndoDetective( &rDocShell, pUndo, NULL, pUndoList ) );
442 : }
443 0 : aModificator.SetDocumentModified();
444 0 : SfxBindings* pBindings = rDocShell.GetViewBindings();
445 0 : if (pBindings)
446 0 : pBindings->Invalidate( SID_DETECTIVE_REFRESH );
447 : }
448 : else
449 0 : delete pUndo;
450 :
451 0 : return bDone;
452 : }
453 :
454 88 : sal_Bool ScDocFunc::DetectiveRefresh( sal_Bool bAutomatic )
455 : {
456 88 : sal_Bool bDone = false;
457 88 : ScDocument* pDoc = rDocShell.GetDocument();
458 :
459 88 : bool bUndo (pDoc->IsUndoEnabled());
460 88 : ScDetOpList* pList = pDoc->GetDetOpList();
461 88 : if ( pList && pList->Count() )
462 : {
463 14 : rDocShell.MakeDrawLayer();
464 14 : ScDrawLayer* pModel = pDoc->GetDrawLayer();
465 14 : if (bUndo)
466 14 : pModel->BeginCalcUndo(false);
467 :
468 : // Loeschen auf allen Tabellen
469 :
470 14 : SCTAB nTabCount = pDoc->GetTableCount();
471 42 : for (SCTAB nTab=0; nTab<nTabCount; nTab++)
472 28 : ScDetectiveFunc( pDoc,nTab ).DeleteAll( SC_DET_ARROWS ); // don't remove circles
473 :
474 : // Wiederholen
475 :
476 14 : size_t nCount = pList->Count();
477 28 : for (size_t i=0; i < nCount; ++i)
478 : {
479 14 : const ScDetOpData* pData = pList->GetObject(i);
480 14 : if (pData)
481 : {
482 14 : ScAddress aPos = pData->GetPos();
483 14 : ScDetectiveFunc aFunc( pDoc, aPos.Tab() );
484 14 : SCCOL nCol = aPos.Col();
485 14 : SCROW nRow = aPos.Row();
486 14 : switch (pData->GetOperation())
487 : {
488 : case SCDETOP_ADDSUCC:
489 0 : aFunc.ShowSucc( nCol, nRow );
490 0 : break;
491 : case SCDETOP_DELSUCC:
492 0 : aFunc.DeleteSucc( nCol, nRow );
493 0 : break;
494 : case SCDETOP_ADDPRED:
495 14 : aFunc.ShowPred( nCol, nRow );
496 14 : break;
497 : case SCDETOP_DELPRED:
498 0 : aFunc.DeletePred( nCol, nRow );
499 0 : break;
500 : case SCDETOP_ADDERROR:
501 0 : aFunc.ShowError( nCol, nRow );
502 0 : break;
503 : default:
504 : OSL_FAIL("falsche Op bei DetectiveRefresh");
505 : }
506 : }
507 : }
508 :
509 14 : if (bUndo)
510 : {
511 14 : SdrUndoGroup* pUndo = pModel->GetCalcUndo();
512 14 : if (pUndo)
513 : {
514 14 : pUndo->SetComment( ScGlobal::GetRscString( STR_UNDO_DETREFRESH ) );
515 : // wenn automatisch, an letzte Aktion anhaengen
516 14 : rDocShell.GetUndoManager()->AddUndoAction(
517 14 : new ScUndoDraw( pUndo, &rDocShell ),
518 28 : bAutomatic );
519 : }
520 : }
521 14 : rDocShell.SetDrawModified();
522 14 : bDone = sal_True;
523 : }
524 88 : return bDone;
525 : }
526 :
527 3 : static void lcl_collectAllPredOrSuccRanges(
528 : const ScRangeList& rSrcRanges, vector<ScTokenRef>& rRefTokens, ScDocShell& rDocShell,
529 : bool bPred)
530 : {
531 3 : ScDocument* pDoc = rDocShell.GetDocument();
532 3 : vector<ScTokenRef> aRefTokens;
533 6 : ScRangeList aSrcRanges(rSrcRanges);
534 3 : if (aSrcRanges.empty())
535 3 : return;
536 3 : ScRange* p = aSrcRanges.front();
537 3 : ScDetectiveFunc aDetFunc(pDoc, p->aStart.Tab());
538 6 : ScRangeList aDestRanges;
539 6 : for (size_t i = 0, n = aSrcRanges.size(); i < n; ++i)
540 : {
541 3 : p = aSrcRanges[i];
542 3 : if (bPred)
543 : {
544 : aDetFunc.GetAllPreds(
545 2 : p->aStart.Col(), p->aStart.Row(), p->aEnd.Col(), p->aEnd.Row(), aRefTokens);
546 : }
547 : else
548 : {
549 : aDetFunc.GetAllSuccs(
550 1 : p->aStart.Col(), p->aStart.Row(), p->aEnd.Col(), p->aEnd.Row(), aRefTokens);
551 : }
552 : }
553 6 : rRefTokens.swap(aRefTokens);
554 : }
555 :
556 2 : void ScDocFunc::DetectiveCollectAllPreds(const ScRangeList& rSrcRanges, vector<ScTokenRef>& rRefTokens)
557 : {
558 2 : lcl_collectAllPredOrSuccRanges(rSrcRanges, rRefTokens, rDocShell, true);
559 2 : }
560 :
561 1 : void ScDocFunc::DetectiveCollectAllSuccs(const ScRangeList& rSrcRanges, vector<ScTokenRef>& rRefTokens)
562 : {
563 1 : lcl_collectAllPredOrSuccRanges(rSrcRanges, rRefTokens, rDocShell, false);
564 1 : }
565 :
566 : //------------------------------------------------------------------------
567 :
568 76 : sal_Bool ScDocFunc::DeleteContents( const ScMarkData& rMark, sal_uInt16 nFlags,
569 : sal_Bool bRecord, sal_Bool bApi )
570 : {
571 76 : ScDocShellModificator aModificator( rDocShell );
572 :
573 76 : if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
574 : {
575 : OSL_FAIL("ScDocFunc::DeleteContents ohne Markierung");
576 0 : return false;
577 : }
578 :
579 76 : ScDocument* pDoc = rDocShell.GetDocument();
580 :
581 76 : if (bRecord && !pDoc->IsUndoEnabled())
582 0 : bRecord = false;
583 :
584 76 : ScEditableTester aTester( pDoc, rMark );
585 76 : if (!aTester.IsEditable())
586 : {
587 0 : if (!bApi)
588 0 : rDocShell.ErrorMessage(aTester.GetMessageId());
589 0 : return false;
590 : }
591 :
592 76 : ScRange aMarkRange;
593 76 : sal_Bool bSimple = false;
594 :
595 152 : ScMarkData aMultiMark = rMark;
596 76 : aMultiMark.SetMarking(false); // fuer MarkToMulti
597 :
598 76 : ScDocument* pUndoDoc = NULL;
599 76 : sal_Bool bMulti = !bSimple && aMultiMark.IsMultiMarked();
600 76 : if (!bSimple)
601 : {
602 76 : aMultiMark.MarkToMulti();
603 76 : aMultiMark.GetMultiMarkArea( aMarkRange );
604 : }
605 76 : ScRange aExtendedRange(aMarkRange);
606 76 : if (!bSimple)
607 : {
608 76 : if ( pDoc->ExtendMerge( aExtendedRange, sal_True ) )
609 0 : bMulti = false;
610 : }
611 :
612 : // keine Objekte auf geschuetzten Tabellen
613 76 : sal_Bool bObjects = false;
614 76 : if ( nFlags & IDF_OBJECTS )
615 : {
616 1 : bObjects = sal_True;
617 1 : SCTAB nTabCount = pDoc->GetTableCount();
618 1 : ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
619 2 : for (; itr != itrEnd && *itr < nTabCount; ++itr)
620 1 : if (pDoc->IsTabProtected(*itr))
621 0 : bObjects = false;
622 : }
623 :
624 76 : sal_uInt16 nExtFlags = 0; // extra flags are needed only if attributes are deleted
625 76 : if ( nFlags & IDF_ATTRIB )
626 58 : rDocShell.UpdatePaintExt( nExtFlags, aMarkRange );
627 :
628 : // Reihenfolge:
629 : // 1) BeginDrawUndo
630 : // 2) Objekte loeschen (DrawUndo wird gefuellt)
631 : // 3) Inhalte fuer Undo kopieren und Undo-Aktion anlegen
632 : // 4) Inhalte loeschen
633 :
634 76 : bool bDrawUndo = bObjects || (nFlags & IDF_NOTE);
635 76 : if (bRecord && bDrawUndo)
636 3 : pDoc->BeginDrawUndo();
637 :
638 76 : if (bObjects)
639 : {
640 1 : if (bMulti)
641 0 : pDoc->DeleteObjectsInSelection( aMultiMark );
642 : else
643 1 : pDoc->DeleteObjectsInArea( aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
644 1 : aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(),
645 3 : aMultiMark );
646 : }
647 :
648 76 : if ( bRecord )
649 : {
650 75 : pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
651 75 : pUndoDoc->InitUndo( pDoc, aMarkRange.aStart.Tab(), aMarkRange.aEnd.Tab() );
652 :
653 : // bei "Format/Standard" alle Attribute kopieren, weil CopyToDocument
654 : // nur mit IDF_HARDATTR zu langsam ist:
655 75 : sal_uInt16 nUndoDocFlags = nFlags;
656 75 : if (nFlags & IDF_ATTRIB)
657 57 : nUndoDocFlags |= IDF_ATTRIB;
658 75 : if (nFlags & IDF_EDITATTR) // Edit-Engine-Attribute
659 2 : nUndoDocFlags |= IDF_STRING; // -> Zellen werden geaendert
660 75 : if (nFlags & IDF_NOTE)
661 3 : nUndoDocFlags |= IDF_CONTENTS; // copy all cells with their notes
662 : // note captions are handled in drawing undo
663 75 : nUndoDocFlags |= IDF_NOCAPTIONS;
664 75 : pDoc->CopyToDocument( aExtendedRange, nUndoDocFlags, bMulti, pUndoDoc, &aMultiMark );
665 : }
666 :
667 : //! HideAllCursors(); // falls Zusammenfassung aufgehoben wird
668 76 : if (bSimple)
669 0 : pDoc->DeleteArea( aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
670 0 : aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(),
671 0 : aMultiMark, nFlags );
672 : else
673 : {
674 76 : pDoc->DeleteSelection( nFlags, aMultiMark );
675 : }
676 :
677 : // add undo action after drawing undo is complete (objects and note captions)
678 76 : if( bRecord )
679 75 : rDocShell.GetUndoManager()->AddUndoAction(
680 : new ScUndoDeleteContents( &rDocShell, aMultiMark, aExtendedRange,
681 75 : pUndoDoc, bMulti, nFlags, bDrawUndo ) );
682 :
683 76 : if (!AdjustRowHeight( aExtendedRange ))
684 42 : rDocShell.PostPaint( aExtendedRange, PAINT_GRID, nExtFlags );
685 34 : else if (nExtFlags & SC_PF_LINES)
686 0 : lcl_PaintAbove( rDocShell, aExtendedRange ); // fuer Linien ueber dem Bereich
687 :
688 76 : aModificator.SetDocumentModified();
689 :
690 152 : return sal_True;
691 : }
692 :
693 : //------------------------------------------------------------------------
694 :
695 0 : sal_Bool ScDocFunc::TransliterateText( const ScMarkData& rMark, sal_Int32 nType,
696 : sal_Bool bRecord, sal_Bool bApi )
697 : {
698 0 : ScDocShellModificator aModificator( rDocShell );
699 :
700 0 : ScDocument* pDoc = rDocShell.GetDocument();
701 0 : if (bRecord && !pDoc->IsUndoEnabled())
702 0 : bRecord = false;
703 :
704 0 : ScEditableTester aTester( pDoc, rMark );
705 0 : if (!aTester.IsEditable())
706 : {
707 0 : if (!bApi)
708 0 : rDocShell.ErrorMessage(aTester.GetMessageId());
709 0 : return false;
710 : }
711 :
712 0 : ScRange aMarkRange;
713 0 : ScMarkData aMultiMark = rMark;
714 0 : aMultiMark.SetMarking(false); // for MarkToMulti
715 0 : aMultiMark.MarkToMulti();
716 0 : aMultiMark.GetMultiMarkArea( aMarkRange );
717 :
718 0 : if (bRecord)
719 : {
720 0 : SCTAB nStartTab = aMarkRange.aStart.Tab();
721 0 : SCTAB nTabCount = pDoc->GetTableCount();
722 :
723 0 : ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
724 0 : pUndoDoc->InitUndo( pDoc, nStartTab, nStartTab );
725 0 : ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
726 0 : for (; itr != itrEnd && *itr < nTabCount; ++itr)
727 0 : if (*itr != nStartTab)
728 0 : pUndoDoc->AddUndoTab( *itr, *itr );
729 :
730 0 : ScRange aCopyRange = aMarkRange;
731 0 : aCopyRange.aStart.SetTab(0);
732 0 : aCopyRange.aEnd.SetTab(nTabCount-1);
733 0 : pDoc->CopyToDocument( aCopyRange, IDF_CONTENTS, sal_True, pUndoDoc, &aMultiMark );
734 :
735 0 : rDocShell.GetUndoManager()->AddUndoAction(
736 0 : new ScUndoTransliterate( &rDocShell, aMultiMark, pUndoDoc, nType ) );
737 : }
738 :
739 0 : pDoc->TransliterateText( aMultiMark, nType );
740 :
741 0 : if (!AdjustRowHeight( aMarkRange ))
742 0 : rDocShell.PostPaint( aMarkRange, PAINT_GRID );
743 :
744 0 : aModificator.SetDocumentModified();
745 :
746 0 : return sal_True;
747 : }
748 :
749 : //------------------------------------------------------------------------
750 :
751 2062 : sal_Bool ScDocFunc::SetNormalString( bool& o_rbNumFmtSet, const ScAddress& rPos, const String& rText, sal_Bool bApi )
752 : {
753 2062 : ScDocShellModificator aModificator( rDocShell );
754 2062 : ScDocument* pDoc = rDocShell.GetDocument();
755 :
756 2062 : bool bUndo(pDoc->IsUndoEnabled());
757 2062 : ScEditableTester aTester( pDoc, rPos.Tab(), rPos.Col(),rPos.Row(), rPos.Col(),rPos.Row() );
758 2062 : if (!aTester.IsEditable())
759 : {
760 0 : if (!bApi)
761 0 : rDocShell.ErrorMessage(aTester.GetMessageId());
762 0 : return false;
763 : }
764 :
765 2062 : bool bEditDeleted = (pDoc->GetCellType(rPos) == CELLTYPE_EDIT);
766 4124 : ScUndoEnterData::ValuesType aOldValues;
767 :
768 2062 : if (bUndo)
769 : {
770 2062 : ScUndoEnterData::Value aOldValue;
771 :
772 2062 : aOldValue.mnTab = rPos.Tab();
773 2062 : aOldValue.maCell.assign(*pDoc, rPos);
774 :
775 : const SfxPoolItem* pItem;
776 2062 : const ScPatternAttr* pPattern = pDoc->GetPattern( rPos.Col(),rPos.Row(),rPos.Tab() );
777 4124 : if ( SFX_ITEM_SET == pPattern->GetItemSet().GetItemState(
778 2062 : ATTR_VALUE_FORMAT,false,&pItem) )
779 : {
780 2 : aOldValue.mbHasFormat = true;
781 2 : aOldValue.mnFormat = ((const SfxUInt32Item*)pItem)->GetValue();
782 : }
783 : else
784 2060 : aOldValue.mbHasFormat = false;
785 :
786 2062 : aOldValues.push_back(aOldValue);
787 : }
788 :
789 2062 : o_rbNumFmtSet = pDoc->SetString( rPos.Col(), rPos.Row(), rPos.Tab(), rText );
790 :
791 2062 : if (bUndo)
792 : {
793 : // wegen ChangeTracking darf UndoAction erst nach SetString angelegt werden
794 2062 : rDocShell.GetUndoManager()->AddUndoAction(
795 2062 : new ScUndoEnterData(&rDocShell, rPos, aOldValues, rText, NULL));
796 : }
797 :
798 2062 : if ( bEditDeleted || pDoc->HasAttrib( ScRange(rPos), HASATTR_NEEDHEIGHT ) )
799 6 : AdjustRowHeight( ScRange(rPos) );
800 :
801 2062 : rDocShell.PostPaintCell( rPos );
802 2062 : aModificator.SetDocumentModified();
803 :
804 : // notify input handler here the same way as in PutCell
805 2062 : if (bApi)
806 2062 : NotifyInputHandler( rPos );
807 :
808 4124 : return sal_True;
809 : }
810 :
811 3553 : bool ScDocFunc::SetValueCell( const ScAddress& rPos, double fVal, bool bInteraction )
812 : {
813 3553 : ScDocShellModificator aModificator( rDocShell );
814 3553 : ScDocument* pDoc = rDocShell.GetDocument();
815 3553 : bool bUndo = pDoc->IsUndoEnabled();
816 :
817 3553 : bool bHeight = pDoc->HasAttrib(rPos, HASATTR_NEEDHEIGHT);
818 :
819 7106 : ScCellValue aOldVal;
820 3553 : if (bUndo)
821 3553 : aOldVal.assign(*pDoc, rPos);
822 :
823 3553 : pDoc->SetValue(rPos, fVal);
824 :
825 3553 : if (bUndo)
826 : {
827 3553 : svl::IUndoManager* pUndoMgr = rDocShell.GetUndoManager();
828 3553 : ScCellValue aNewVal;
829 3553 : aNewVal.assign(*pDoc, rPos);
830 3553 : pUndoMgr->AddUndoAction(new ScUndoSetCell(&rDocShell, rPos, aOldVal, aNewVal));
831 : }
832 :
833 3553 : if (bHeight)
834 5 : AdjustRowHeight(rPos);
835 :
836 3553 : aModificator.SetDocumentModified();
837 :
838 : // #103934#; notify editline and cell in edit mode
839 3553 : if (!bInteraction)
840 3553 : NotifyInputHandler( rPos );
841 :
842 7106 : return true;
843 : }
844 :
845 1198 : bool ScDocFunc::SetStringCell( const ScAddress& rPos, const OUString& rStr, bool bInteraction )
846 : {
847 1198 : ScDocShellModificator aModificator( rDocShell );
848 1198 : ScDocument* pDoc = rDocShell.GetDocument();
849 1198 : bool bUndo = pDoc->IsUndoEnabled();
850 :
851 1198 : bool bHeight = pDoc->HasAttrib(rPos, HASATTR_NEEDHEIGHT);
852 :
853 2396 : ScCellValue aOldVal;
854 1198 : if (bUndo)
855 1198 : aOldVal.assign(*pDoc, rPos);
856 :
857 1198 : ScSetStringParam aParam;
858 1198 : aParam.setTextInput();
859 1198 : pDoc->SetString(rPos, rStr, &aParam);
860 :
861 1198 : if (bUndo)
862 : {
863 1198 : svl::IUndoManager* pUndoMgr = rDocShell.GetUndoManager();
864 1198 : ScCellValue aNewVal;
865 1198 : aNewVal.assign(*pDoc, rPos);
866 1198 : pUndoMgr->AddUndoAction(new ScUndoSetCell(&rDocShell, rPos, aOldVal, aNewVal));
867 : }
868 :
869 1198 : if (bHeight)
870 53 : AdjustRowHeight(rPos);
871 :
872 1198 : aModificator.SetDocumentModified();
873 :
874 : // #103934#; notify editline and cell in edit mode
875 1198 : if (!bInteraction)
876 1198 : NotifyInputHandler( rPos );
877 :
878 2396 : return true;
879 : }
880 :
881 162 : bool ScDocFunc::SetEditCell( const ScAddress& rPos, const EditTextObject& rStr, bool bInteraction )
882 : {
883 162 : ScDocShellModificator aModificator( rDocShell );
884 162 : ScDocument* pDoc = rDocShell.GetDocument();
885 162 : bool bUndo = pDoc->IsUndoEnabled();
886 :
887 162 : bool bHeight = pDoc->HasAttrib(rPos, HASATTR_NEEDHEIGHT);
888 :
889 324 : ScCellValue aOldVal;
890 162 : if (bUndo)
891 162 : aOldVal.assign(*pDoc, rPos);
892 :
893 162 : pDoc->SetEditText(rPos, rStr.Clone());
894 :
895 162 : if (bUndo)
896 : {
897 162 : svl::IUndoManager* pUndoMgr = rDocShell.GetUndoManager();
898 162 : ScCellValue aNewVal;
899 162 : aNewVal.assign(*pDoc, rPos);
900 162 : pUndoMgr->AddUndoAction(new ScUndoSetCell(&rDocShell, rPos, aOldVal, aNewVal));
901 : }
902 :
903 162 : if (bHeight)
904 1 : AdjustRowHeight(rPos);
905 :
906 162 : aModificator.SetDocumentModified();
907 :
908 : // #103934#; notify editline and cell in edit mode
909 162 : if (!bInteraction)
910 162 : NotifyInputHandler( rPos );
911 :
912 324 : return true;
913 : }
914 :
915 1152 : bool ScDocFunc::SetStringOrEditCell( const ScAddress& rPos, const OUString& rStr, bool bInteraction )
916 : {
917 1152 : ScDocument* pDoc = rDocShell.GetDocument();
918 :
919 1152 : if (ScStringUtil::isMultiline(rStr))
920 : {
921 3 : ScFieldEditEngine& rEngine = pDoc->GetEditEngine();
922 3 : rEngine.SetText(rStr);
923 3 : boost::scoped_ptr<EditTextObject> pEditText(rEngine.CreateTextObject());
924 3 : return SetEditCell(rPos, *pEditText, bInteraction);
925 : }
926 : else
927 1149 : return SetStringCell(rPos, rStr, bInteraction);
928 : }
929 :
930 129 : bool ScDocFunc::SetFormulaCell( const ScAddress& rPos, ScFormulaCell* pCell, bool bInteraction )
931 : {
932 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
933 129 : std::auto_ptr<ScFormulaCell> xCell(pCell);
934 : SAL_WNODEPRECATED_DECLARATIONS_POP
935 :
936 258 : ScDocShellModificator aModificator( rDocShell );
937 129 : ScDocument* pDoc = rDocShell.GetDocument();
938 129 : bool bUndo = pDoc->IsUndoEnabled();
939 :
940 129 : bool bHeight = pDoc->HasAttrib(rPos, HASATTR_NEEDHEIGHT);
941 :
942 258 : ScCellValue aOldVal;
943 129 : if (bUndo)
944 129 : aOldVal.assign(*pDoc, rPos);
945 :
946 129 : pDoc->SetFormulaCell(rPos, xCell.release());
947 :
948 129 : if (bUndo)
949 : {
950 129 : svl::IUndoManager* pUndoMgr = rDocShell.GetUndoManager();
951 129 : ScCellValue aNewVal;
952 129 : aNewVal.assign(*pDoc, rPos);
953 129 : pUndoMgr->AddUndoAction(new ScUndoSetCell(&rDocShell, rPos, aOldVal, aNewVal));
954 : }
955 :
956 129 : if (bHeight)
957 0 : AdjustRowHeight(rPos);
958 :
959 129 : aModificator.SetDocumentModified();
960 :
961 : // #103934#; notify editline and cell in edit mode
962 129 : if (!bInteraction)
963 129 : NotifyInputHandler( rPos );
964 :
965 258 : return true;
966 : }
967 :
968 7104 : void ScDocFunc::NotifyInputHandler( const ScAddress& rPos )
969 : {
970 7104 : ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
971 7104 : if ( pViewSh && pViewSh->GetViewData()->GetDocShell() == &rDocShell )
972 : {
973 7062 : ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
974 7062 : if ( pInputHdl && pInputHdl->GetCursorPos() == rPos )
975 : {
976 88 : sal_Bool bIsEditMode(pInputHdl->IsEditMode());
977 :
978 : // set modified if in editmode, because so the string is not set in the InputWindow like in the cell
979 : // (the cell shows the same like the InputWindow)
980 88 : if (bIsEditMode)
981 0 : pInputHdl->SetModified();
982 88 : pViewSh->UpdateInputHandler(false, !bIsEditMode);
983 : }
984 : }
985 7104 : }
986 :
987 162 : struct ScMyRememberItem
988 : {
989 : sal_Int32 nIndex;
990 : SfxItemSet aItemSet;
991 :
992 162 : ScMyRememberItem(const SfxItemSet& rItemSet, sal_Int32 nTempIndex) :
993 162 : nIndex(nTempIndex), aItemSet(rItemSet) {}
994 : };
995 :
996 : typedef ::std::list<ScMyRememberItem*> ScMyRememberItemList;
997 :
998 209 : bool ScDocFunc::PutData( const ScAddress& rPos, ScEditEngineDefaulter& rEngine, bool bApi )
999 : {
1000 : // PutData ruft PutCell oder SetNormalString
1001 :
1002 209 : sal_Bool bRet = false;
1003 209 : ScDocument* pDoc = rDocShell.GetDocument();
1004 209 : ScEditAttrTester aTester( &rEngine );
1005 209 : sal_Bool bEditCell = aTester.NeedsObject();
1006 209 : if ( bEditCell )
1007 : {
1008 : // #i61702# With bLoseContent set, the content of rEngine isn't restored
1009 : // (used in loading XML, where after the removeActionLock call the API obejct's
1010 : // EditEngine isn't accessed again.
1011 159 : sal_Bool bLoseContent = pDoc->IsImportingXML();
1012 :
1013 159 : sal_Bool bUpdateMode(rEngine.GetUpdateMode());
1014 159 : if (bUpdateMode)
1015 159 : rEngine.SetUpdateMode(false);
1016 :
1017 159 : ScMyRememberItemList aRememberItems;
1018 159 : ScMyRememberItem* pRememberItem = NULL;
1019 :
1020 : // All paragraph attributes must be removed before calling CreateTextObject,
1021 : // not only alignment, so the object doesn't contain the cell attributes as
1022 : // paragraph attributes. Before remove the attributes store they in a list to
1023 : // set they back to the EditEngine.
1024 159 : sal_Int32 nCount = rEngine.GetParagraphCount();
1025 321 : for (sal_Int32 i=0; i<nCount; i++)
1026 : {
1027 162 : const SfxItemSet& rOld = rEngine.GetParaAttribs( i );
1028 162 : if ( rOld.Count() )
1029 : {
1030 162 : if ( !bLoseContent )
1031 : {
1032 162 : pRememberItem = new ScMyRememberItem(rEngine.GetParaAttribs(i), i);
1033 162 : aRememberItems.push_back(pRememberItem);
1034 : }
1035 162 : rEngine.SetParaAttribs( i, SfxItemSet( *rOld.GetPool(), rOld.GetRanges() ) );
1036 : }
1037 : }
1038 :
1039 : // A copy of pNewData will be stored in the cell.
1040 318 : boost::scoped_ptr<EditTextObject> pNewData(rEngine.CreateTextObject());
1041 159 : bRet = SetEditCell(rPos, *pNewData, !bApi);
1042 :
1043 : // Set the paragraph attributes back to the EditEngine.
1044 159 : if (!aRememberItems.empty())
1045 : {
1046 159 : ScMyRememberItemList::iterator aItr = aRememberItems.begin();
1047 480 : while (aItr != aRememberItems.end())
1048 : {
1049 162 : pRememberItem = *aItr;
1050 162 : rEngine.SetParaAttribs(pRememberItem->nIndex, pRememberItem->aItemSet);
1051 162 : delete pRememberItem;
1052 162 : aItr = aRememberItems.erase(aItr);
1053 : }
1054 : }
1055 :
1056 : // #i61702# if the content isn't accessed, there's no need to set the UpdateMode again
1057 159 : if ( bUpdateMode && !bLoseContent )
1058 318 : rEngine.SetUpdateMode(sal_True);
1059 : }
1060 : else
1061 : {
1062 50 : OUString aText = rEngine.GetText();
1063 50 : if (aText.isEmpty())
1064 : {
1065 1 : bool bNumFmtSet = false;
1066 1 : bRet = SetNormalString( bNumFmtSet, rPos, aText, bApi );
1067 : }
1068 : else
1069 49 : bRet = SetStringCell(rPos, aText, !bApi);
1070 : }
1071 :
1072 209 : if ( bRet && aTester.NeedsCellAttr() )
1073 : {
1074 165 : const SfxItemSet& rEditAttr = aTester.GetAttribs();
1075 165 : ScPatternAttr aPattern( pDoc->GetPool() );
1076 165 : aPattern.GetFromEditItemSet( &rEditAttr );
1077 165 : aPattern.DeleteUnchanged( pDoc->GetPattern( rPos.Col(), rPos.Row(), rPos.Tab() ) );
1078 165 : aPattern.GetItemSet().ClearItem( ATTR_HOR_JUSTIFY ); // wasn't removed above if no edit object
1079 165 : if ( aPattern.GetItemSet().Count() > 0 )
1080 : {
1081 113 : ScMarkData aMark;
1082 113 : aMark.SelectTable( rPos.Tab(), sal_True );
1083 113 : aMark.SetMarkArea( ScRange( rPos ) );
1084 113 : ApplyAttributes( aMark, aPattern, sal_True, bApi );
1085 165 : }
1086 : }
1087 :
1088 209 : return bRet;
1089 : }
1090 :
1091 :
1092 0 : static ScTokenArray* lcl_ScDocFunc_CreateTokenArrayXML( const String& rText, const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
1093 : {
1094 0 : ScTokenArray* pCode = new ScTokenArray;
1095 0 : pCode->AddStringXML( rText );
1096 0 : if( (eGrammar == formula::FormulaGrammar::GRAM_EXTERNAL) && (rFormulaNmsp.Len() > 0) )
1097 0 : pCode->AddStringXML( rFormulaNmsp );
1098 0 : return pCode;
1099 : }
1100 :
1101 2061 : bool ScDocFunc::SetCellText(
1102 : const ScAddress& rPos, const OUString& rText, bool bInterpret, bool bEnglish, bool bApi,
1103 : const formula::FormulaGrammar::Grammar eGrammar )
1104 : {
1105 2061 : if ( bInterpret )
1106 : {
1107 883 : if ( bEnglish )
1108 : {
1109 881 : ScDocument* pDoc = rDocShell.GetDocument();
1110 :
1111 881 : ::boost::scoped_ptr<ScExternalRefManager::ApiGuard> pExtRefGuard;
1112 881 : if (bApi)
1113 881 : pExtRefGuard.reset(new ScExternalRefManager::ApiGuard(pDoc));
1114 :
1115 : ScInputStringType aRes =
1116 1762 : ScStringUtil::parseInputString(*pDoc->GetFormatTable(), rText, LANGUAGE_ENGLISH_US);
1117 :
1118 881 : switch (aRes.meType)
1119 : {
1120 : case ScInputStringType::Formula:
1121 128 : SetFormulaCell(rPos, new ScFormulaCell(pDoc, rPos, aRes.maText, eGrammar), !bApi);
1122 128 : break;
1123 : case ScInputStringType::Number:
1124 0 : SetValueCell(rPos, aRes.mfValue, !bApi);
1125 0 : break;
1126 : case ScInputStringType::Text:
1127 751 : SetStringOrEditCell(rPos, aRes.maText, !bApi);
1128 751 : break;
1129 : default:
1130 : ;
1131 881 : }
1132 : }
1133 : // sonst Null behalten -> SetString mit lokalen Formeln/Zahlformat
1134 : }
1135 1178 : else if (!rText.isEmpty())
1136 : {
1137 18 : SetStringOrEditCell(rPos, rText, !bApi);
1138 : }
1139 :
1140 2061 : bool bNumFmtSet = false;
1141 2061 : return SetNormalString( bNumFmtSet, rPos, rText, bApi );
1142 : }
1143 :
1144 : //------------------------------------------------------------------------
1145 :
1146 2 : bool ScDocFunc::ShowNote( const ScAddress& rPos, bool bShow )
1147 : {
1148 2 : ScDocument& rDoc = *rDocShell.GetDocument();
1149 2 : ScPostIt* pNote = rDoc.GetNotes( rPos.Tab() )->findByAddress( rPos );
1150 2 : if( !pNote || (bShow == pNote->IsCaptionShown()) ) return false;
1151 :
1152 : // move the caption to internal or hidden layer and create undo action
1153 1 : pNote->ShowCaption( rPos, bShow );
1154 1 : if( rDoc.IsUndoEnabled() )
1155 1 : rDocShell.GetUndoManager()->AddUndoAction( new ScUndoShowHideNote( rDocShell, rPos, bShow ) );
1156 :
1157 1 : if (rDoc.IsStreamValid(rPos.Tab()))
1158 1 : rDoc.SetStreamValid(rPos.Tab(), false);
1159 :
1160 1 : rDocShell.SetDocumentModified();
1161 :
1162 1 : return true;
1163 : }
1164 :
1165 : //------------------------------------------------------------------------
1166 :
1167 0 : bool ScDocFunc::SetNoteText( const ScAddress& rPos, const String& rText, sal_Bool bApi )
1168 : {
1169 0 : ScDocShellModificator aModificator( rDocShell );
1170 :
1171 0 : ScDocument* pDoc = rDocShell.GetDocument();
1172 0 : ScEditableTester aTester( pDoc, rPos.Tab(), rPos.Col(),rPos.Row(), rPos.Col(),rPos.Row() );
1173 0 : if (!aTester.IsEditable())
1174 : {
1175 0 : if (!bApi)
1176 0 : rDocShell.ErrorMessage(aTester.GetMessageId());
1177 0 : return false;
1178 : }
1179 :
1180 0 : String aNewText = convertLineEnd(rText, GetSystemLineEnd()); //! ist das noetig ???
1181 :
1182 0 : if( ScPostIt* pNote = (aNewText.Len() > 0) ? pDoc->GetNotes(rPos.Tab())->GetOrCreateNote( rPos ) : pDoc->GetNotes( rPos.Tab() )->findByAddress(rPos) )
1183 0 : pNote->SetText( rPos, aNewText );
1184 :
1185 : //! Undo !!!
1186 :
1187 0 : if (pDoc->IsStreamValid(rPos.Tab()))
1188 0 : pDoc->SetStreamValid(rPos.Tab(), false);
1189 :
1190 0 : rDocShell.PostPaintCell( rPos );
1191 0 : aModificator.SetDocumentModified();
1192 :
1193 0 : return true;
1194 : }
1195 :
1196 : //------------------------------------------------------------------------
1197 :
1198 7 : bool ScDocFunc::ReplaceNote( const ScAddress& rPos, const OUString& rNoteText, const OUString* pAuthor, const OUString* pDate, sal_Bool bApi )
1199 : {
1200 7 : bool bDone = false;
1201 :
1202 7 : ScDocShellModificator aModificator( rDocShell );
1203 7 : ScDocument& rDoc = *rDocShell.GetDocument();
1204 7 : ScEditableTester aTester( &rDoc, rPos.Tab(), rPos.Col(),rPos.Row(), rPos.Col(),rPos.Row() );
1205 7 : if (aTester.IsEditable())
1206 : {
1207 7 : ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
1208 7 : ::svl::IUndoManager* pUndoMgr = (pDrawLayer && rDoc.IsUndoEnabled()) ? rDocShell.GetUndoManager() : 0;
1209 :
1210 7 : ScNoteData aOldData;
1211 7 : ScPostIt* pOldNote = rDoc.GetNotes(rPos.Tab())->ReleaseNote( rPos );
1212 7 : if( pOldNote )
1213 : {
1214 : // ensure existing caption object before draw undo tracking starts
1215 0 : pOldNote->GetOrCreateCaption( rPos );
1216 : // rescue note data for undo
1217 0 : aOldData = pOldNote->GetNoteData();
1218 : }
1219 :
1220 : // collect drawing undo actions for deleting/inserting caption obejcts
1221 7 : if( pUndoMgr )
1222 6 : pDrawLayer->BeginCalcUndo(false);
1223 :
1224 : // delete the note (creates drawing undo action for the caption object)
1225 7 : delete pOldNote;
1226 :
1227 : // create new note (creates drawing undo action for the new caption object)
1228 14 : ScNoteData aNewData;
1229 7 : if( ScPostIt* pNewNote = ScNoteUtil::CreateNoteFromString( rDoc, rPos, rNoteText, false, true ) )
1230 : {
1231 7 : if( pAuthor ) pNewNote->SetAuthor( *pAuthor );
1232 7 : if( pDate ) pNewNote->SetDate( *pDate );
1233 : // rescue note data for undo
1234 7 : aNewData = pNewNote->GetNoteData();
1235 : }
1236 :
1237 : // create the undo action
1238 7 : if( pUndoMgr && (aOldData.mpCaption || aNewData.mpCaption) )
1239 6 : pUndoMgr->AddUndoAction( new ScUndoReplaceNote( rDocShell, rPos, aOldData, aNewData, pDrawLayer->GetCalcUndo() ) );
1240 :
1241 : // repaint cell (to make note marker visible)
1242 7 : rDocShell.PostPaintCell( rPos );
1243 :
1244 7 : if (rDoc.IsStreamValid(rPos.Tab()))
1245 1 : rDoc.SetStreamValid(rPos.Tab(), false);
1246 :
1247 7 : aModificator.SetDocumentModified();
1248 14 : bDone = true;
1249 : }
1250 0 : else if (!bApi)
1251 : {
1252 0 : rDocShell.ErrorMessage(aTester.GetMessageId());
1253 : }
1254 :
1255 7 : return bDone;
1256 : }
1257 :
1258 : //------------------------------------------------------------------------
1259 :
1260 698 : sal_Bool ScDocFunc::ApplyAttributes( const ScMarkData& rMark, const ScPatternAttr& rPattern,
1261 : sal_Bool bRecord, sal_Bool bApi )
1262 : {
1263 698 : ScDocument* pDoc = rDocShell.GetDocument();
1264 698 : if ( bRecord && !pDoc->IsUndoEnabled() )
1265 228 : bRecord = false;
1266 :
1267 698 : bool bImportingXML = pDoc->IsImportingXML();
1268 : // Cell formats can still be set if the range isn't editable only because of matrix formulas.
1269 : // #i62483# When loading XML, the check can be skipped altogether.
1270 : bool bOnlyNotBecauseOfMatrix;
1271 1898 : if ( !bImportingXML && !pDoc->IsSelectionEditable( rMark, &bOnlyNotBecauseOfMatrix )
1272 698 : && !bOnlyNotBecauseOfMatrix )
1273 : {
1274 0 : if (!bApi)
1275 0 : rDocShell.ErrorMessage(STR_PROTECTIONERR);
1276 0 : return false;
1277 : }
1278 :
1279 698 : ScDocShellModificator aModificator( rDocShell );
1280 :
1281 : //! Umrandung
1282 :
1283 698 : ScRange aMultiRange;
1284 698 : sal_Bool bMulti = rMark.IsMultiMarked();
1285 698 : if ( bMulti )
1286 66 : rMark.GetMultiMarkArea( aMultiRange );
1287 : else
1288 632 : rMark.GetMarkArea( aMultiRange );
1289 :
1290 698 : if ( bRecord )
1291 : {
1292 470 : ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
1293 470 : pUndoDoc->InitUndo( pDoc, aMultiRange.aStart.Tab(), aMultiRange.aEnd.Tab() );
1294 470 : pDoc->CopyToDocument( aMultiRange, IDF_ATTRIB, bMulti, pUndoDoc, &rMark );
1295 :
1296 470 : rDocShell.GetUndoManager()->AddUndoAction(
1297 : new ScUndoSelectionAttr(
1298 : &rDocShell, rMark,
1299 940 : aMultiRange.aStart.Col(), aMultiRange.aStart.Row(), aMultiRange.aStart.Tab(),
1300 940 : aMultiRange.aEnd.Col(), aMultiRange.aEnd.Row(), aMultiRange.aEnd.Tab(),
1301 2350 : pUndoDoc, bMulti, &rPattern ) );
1302 : }
1303 :
1304 : // While loading XML it is not necessary to ask HasAttrib. It needs too much time.
1305 698 : sal_uInt16 nExtFlags = 0;
1306 698 : if ( !bImportingXML )
1307 502 : rDocShell.UpdatePaintExt( nExtFlags, aMultiRange ); // content before the change
1308 698 : pDoc->ApplySelectionPattern( rPattern, rMark );
1309 698 : if ( !bImportingXML )
1310 502 : rDocShell.UpdatePaintExt( nExtFlags, aMultiRange ); // content after the change
1311 :
1312 698 : if (!AdjustRowHeight( aMultiRange ))
1313 645 : rDocShell.PostPaint( aMultiRange, PAINT_GRID, nExtFlags );
1314 53 : else if (nExtFlags & SC_PF_LINES)
1315 20 : lcl_PaintAbove( rDocShell, aMultiRange ); // fuer Linien ueber dem Bereich
1316 :
1317 698 : aModificator.SetDocumentModified();
1318 :
1319 698 : return sal_True;
1320 : }
1321 :
1322 :
1323 556 : sal_Bool ScDocFunc::ApplyStyle( const ScMarkData& rMark, const String& rStyleName,
1324 : sal_Bool bRecord, sal_Bool bApi )
1325 : {
1326 556 : ScDocument* pDoc = rDocShell.GetDocument();
1327 556 : if ( bRecord && !pDoc->IsUndoEnabled() )
1328 553 : bRecord = false;
1329 :
1330 556 : bool bImportingXML = pDoc->IsImportingXML();
1331 : // Cell formats can still be set if the range isn't editable only because of matrix formulas.
1332 : // #i62483# When loading XML, the check can be skipped altogether.
1333 : bool bOnlyNotBecauseOfMatrix;
1334 1190 : if ( !bImportingXML && !pDoc->IsSelectionEditable( rMark, &bOnlyNotBecauseOfMatrix )
1335 556 : && !bOnlyNotBecauseOfMatrix )
1336 : {
1337 0 : if (!bApi)
1338 0 : rDocShell.ErrorMessage(STR_PROTECTIONERR);
1339 0 : return false;
1340 : }
1341 :
1342 556 : ScStyleSheet* pStyleSheet = (ScStyleSheet*) pDoc->GetStyleSheetPool()->Find(
1343 556 : rStyleName, SFX_STYLE_FAMILY_PARA );
1344 556 : if (!pStyleSheet)
1345 3 : return false;
1346 :
1347 553 : ScDocShellModificator aModificator( rDocShell );
1348 :
1349 553 : ScRange aMultiRange;
1350 553 : sal_Bool bMulti = rMark.IsMultiMarked();
1351 553 : if ( bMulti )
1352 107 : rMark.GetMultiMarkArea( aMultiRange );
1353 : else
1354 446 : rMark.GetMarkArea( aMultiRange );
1355 :
1356 553 : if ( bRecord )
1357 : {
1358 0 : ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
1359 0 : SCTAB nStartTab = aMultiRange.aStart.Tab();
1360 0 : SCTAB nTabCount = pDoc->GetTableCount();
1361 0 : pUndoDoc->InitUndo( pDoc, nStartTab, nStartTab );
1362 0 : ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
1363 0 : for (; itr != itrEnd && *itr < nTabCount; ++itr)
1364 0 : if (*itr != nStartTab)
1365 0 : pUndoDoc->AddUndoTab( *itr, *itr );
1366 :
1367 0 : ScRange aCopyRange = aMultiRange;
1368 0 : aCopyRange.aStart.SetTab(0);
1369 0 : aCopyRange.aEnd.SetTab(nTabCount-1);
1370 0 : pDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, bMulti, pUndoDoc, &rMark );
1371 :
1372 0 : rDocShell.GetUndoManager()->AddUndoAction(
1373 : new ScUndoSelectionStyle(
1374 0 : &rDocShell, rMark, aMultiRange, rStyleName, pUndoDoc ) );
1375 :
1376 : }
1377 :
1378 553 : pDoc->ApplySelectionStyle( (ScStyleSheet&)*pStyleSheet, rMark );
1379 :
1380 553 : sal_uInt16 nExtFlags = 0;
1381 553 : if (!AdjustRowHeight( aMultiRange ))
1382 553 : rDocShell.PostPaint( aMultiRange, PAINT_GRID, nExtFlags );
1383 0 : else if (nExtFlags & SC_PF_LINES)
1384 0 : lcl_PaintAbove( rDocShell, aMultiRange ); // fuer Linien ueber dem Bereich
1385 :
1386 553 : aModificator.SetDocumentModified();
1387 :
1388 553 : return sal_True;
1389 : }
1390 :
1391 : namespace {
1392 :
1393 : /**
1394 : * Check if this insertion attempt would end up cutting one or more pivot
1395 : * tables in half, which is not desirable.
1396 : *
1397 : * @return true if this insertion can be done safely without shearing any
1398 : * existing pivot tables, false otherwise.
1399 : */
1400 6 : bool canInsertCellsByPivot(const ScRange& rRange, const ScMarkData& rMarkData, InsCellCmd eCmd, const ScDocument* pDoc)
1401 : {
1402 6 : if (!pDoc->HasPivotTable())
1403 : // This document has no pivot tables.
1404 6 : return true;
1405 :
1406 0 : const ScDPCollection* pDPs = pDoc->GetDPCollection();
1407 0 : ScMarkData::const_iterator itBeg = rMarkData.begin(), itEnd = rMarkData.end();
1408 :
1409 0 : ScRange aRange(rRange); // local copy
1410 0 : switch (eCmd)
1411 : {
1412 : case INS_INSROWS:
1413 : {
1414 0 : aRange.aStart.SetCol(0);
1415 0 : aRange.aEnd.SetCol(MAXCOL);
1416 : // Continue below.
1417 : }
1418 : case INS_CELLSDOWN:
1419 : {
1420 0 : for (ScMarkData::const_iterator it = itBeg; it != itEnd; ++it)
1421 : {
1422 0 : if (pDPs->IntersectsTableByColumns(aRange.aStart.Col(), aRange.aEnd.Col(), aRange.aStart.Row(), *it))
1423 : // This column range cuts through at least one pivot table. Not good.
1424 0 : return false;
1425 : }
1426 :
1427 : // Start row must be either at the top or above any pivot tables.
1428 0 : if (aRange.aStart.Row() < 0)
1429 : // I don't know how to handle this case.
1430 0 : return false;
1431 :
1432 0 : if (aRange.aStart.Row() == 0)
1433 : // First row is always allowed.
1434 0 : return true;
1435 :
1436 0 : ScRange aTest(aRange);
1437 0 : aTest.aStart.IncRow(-1); // Test one row up.
1438 0 : aTest.aEnd.SetRow(aTest.aStart.Row());
1439 0 : for (ScMarkData::const_iterator it = itBeg; it != itEnd; ++it)
1440 : {
1441 0 : aTest.aStart.SetTab(*it);
1442 0 : aTest.aEnd.SetTab(*it);
1443 0 : if (pDPs->HasTable(aTest))
1444 0 : return false;
1445 : }
1446 : }
1447 0 : break;
1448 : case INS_INSCOLS:
1449 : {
1450 0 : aRange.aStart.SetRow(0);
1451 0 : aRange.aEnd.SetRow(MAXROW);
1452 : // Continue below.
1453 : }
1454 : case INS_CELLSRIGHT:
1455 : {
1456 0 : for (ScMarkData::const_iterator it = itBeg; it != itEnd; ++it)
1457 : {
1458 0 : if (pDPs->IntersectsTableByRows(aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Row(), *it))
1459 : // This column range cuts through at least one pivot table. Not good.
1460 0 : return false;
1461 : }
1462 :
1463 : // Start row must be either at the top or above any pivot tables.
1464 0 : if (aRange.aStart.Col() < 0)
1465 : // I don't know how to handle this case.
1466 0 : return false;
1467 :
1468 0 : if (aRange.aStart.Col() == 0)
1469 : // First row is always allowed.
1470 0 : return true;
1471 :
1472 0 : ScRange aTest(aRange);
1473 0 : aTest.aStart.IncCol(-1); // Test one column to the left.
1474 0 : aTest.aEnd.SetCol(aTest.aStart.Col());
1475 0 : for (ScMarkData::const_iterator it = itBeg; it != itEnd; ++it)
1476 : {
1477 0 : aTest.aStart.SetTab(*it);
1478 0 : aTest.aEnd.SetTab(*it);
1479 0 : if (pDPs->HasTable(aTest))
1480 0 : return false;
1481 : }
1482 : }
1483 0 : break;
1484 : default:
1485 : ;
1486 : }
1487 0 : return true;
1488 : }
1489 :
1490 : /**
1491 : * Check if this deletion attempt would end up cutting one or more pivot
1492 : * tables in half, which is not desirable.
1493 : *
1494 : * @return true if this deletion can be done safely without shearing any
1495 : * existing pivot tables, false otherwise.
1496 : */
1497 7 : bool canDeleteCellsByPivot(const ScRange& rRange, const ScMarkData& rMarkData, DelCellCmd eCmd, const ScDocument* pDoc)
1498 : {
1499 7 : if (!pDoc->HasPivotTable())
1500 : // This document has no pivot tables.
1501 7 : return true;
1502 :
1503 0 : const ScDPCollection* pDPs = pDoc->GetDPCollection();
1504 0 : ScMarkData::const_iterator itBeg = rMarkData.begin(), itEnd = rMarkData.end();
1505 :
1506 0 : ScRange aRange(rRange); // local copy
1507 :
1508 0 : switch (eCmd)
1509 : {
1510 : case DEL_DELROWS:
1511 : {
1512 0 : aRange.aStart.SetCol(0);
1513 0 : aRange.aEnd.SetCol(MAXCOL);
1514 : // Continue below.
1515 : }
1516 : case DEL_CELLSUP:
1517 : {
1518 0 : for (ScMarkData::const_iterator it = itBeg; it != itEnd; ++it)
1519 : {
1520 0 : if (pDPs->IntersectsTableByColumns(aRange.aStart.Col(), aRange.aEnd.Col(), aRange.aStart.Row(), *it))
1521 : // This column range cuts through at least one pivot table. Not good.
1522 0 : return false;
1523 : }
1524 :
1525 0 : ScRange aTest(aRange);
1526 0 : for (ScMarkData::const_iterator it = itBeg; it != itEnd; ++it)
1527 : {
1528 0 : aTest.aStart.SetTab(*it);
1529 0 : aTest.aEnd.SetTab(*it);
1530 0 : if (pDPs->HasTable(aTest))
1531 0 : return false;
1532 : }
1533 : }
1534 0 : break;
1535 : case DEL_DELCOLS:
1536 : {
1537 0 : aRange.aStart.SetRow(0);
1538 0 : aRange.aEnd.SetRow(MAXROW);
1539 : // Continue below.
1540 : }
1541 : case DEL_CELLSLEFT:
1542 : {
1543 0 : for (ScMarkData::const_iterator it = itBeg; it != itEnd; ++it)
1544 : {
1545 0 : if (pDPs->IntersectsTableByRows(aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Row(), *it))
1546 : // This column range cuts through at least one pivot table. Not good.
1547 0 : return false;
1548 : }
1549 :
1550 0 : ScRange aTest(aRange);
1551 0 : for (ScMarkData::const_iterator it = itBeg; it != itEnd; ++it)
1552 : {
1553 0 : aTest.aStart.SetTab(*it);
1554 0 : aTest.aEnd.SetTab(*it);
1555 0 : if (pDPs->HasTable(aTest))
1556 0 : return false;
1557 : }
1558 : }
1559 0 : break;
1560 : default:
1561 : ;
1562 : }
1563 0 : return true;
1564 : }
1565 :
1566 : }
1567 :
1568 6 : bool ScDocFunc::InsertCells( const ScRange& rRange, const ScMarkData* pTabMark, InsCellCmd eCmd,
1569 : bool bRecord, bool bApi, bool bPartOfPaste )
1570 : {
1571 6 : ScDocShellModificator aModificator( rDocShell );
1572 :
1573 6 : SCCOL nStartCol = rRange.aStart.Col();
1574 6 : SCROW nStartRow = rRange.aStart.Row();
1575 6 : SCTAB nStartTab = rRange.aStart.Tab();
1576 6 : SCCOL nEndCol = rRange.aEnd.Col();
1577 6 : SCROW nEndRow = rRange.aEnd.Row();
1578 6 : SCTAB nEndTab = rRange.aEnd.Tab();
1579 :
1580 6 : if ( !ValidRow(nStartRow) || !ValidRow(nEndRow) )
1581 : {
1582 : OSL_FAIL("invalid row in InsertCells");
1583 0 : return false;
1584 : }
1585 :
1586 6 : ScDocument* pDoc = rDocShell.GetDocument();
1587 6 : SCTAB nTabCount = pDoc->GetTableCount();
1588 6 : SCCOL nPaintStartCol = nStartCol;
1589 6 : SCROW nPaintStartRow = nStartRow;
1590 6 : SCCOL nPaintEndCol = nEndCol;
1591 6 : SCROW nPaintEndRow = nEndRow;
1592 6 : sal_uInt16 nPaintFlags = PAINT_GRID;
1593 : bool bSuccess;
1594 : SCTAB i;
1595 :
1596 6 : ScTabViewShell* pViewSh = rDocShell.GetBestViewShell(); //preserve current cursor position
1597 6 : SCCOL nCursorCol = 0;
1598 6 : SCROW nCursorRow = 0;
1599 6 : if( pViewSh )
1600 : {
1601 5 : nCursorCol = pViewSh->GetViewData()->GetCurX();
1602 5 : nCursorRow = pViewSh->GetViewData()->GetCurY();
1603 : }
1604 :
1605 6 : if (bRecord && !pDoc->IsUndoEnabled())
1606 0 : bRecord = false;
1607 :
1608 12 : ScMarkData aMark;
1609 6 : if (pTabMark)
1610 1 : aMark = *pTabMark;
1611 : else
1612 : {
1613 5 : SCTAB nCount = 0;
1614 5 : for( i=0; i<nTabCount; i++ )
1615 : {
1616 5 : if( !pDoc->IsScenario(i) )
1617 : {
1618 5 : nCount++;
1619 5 : if( nCount == nEndTab+1 )
1620 : {
1621 5 : aMark.SelectTable( i, true );
1622 5 : break;
1623 : }
1624 : }
1625 : }
1626 : }
1627 :
1628 12 : ScMarkData aFullMark( aMark ); // including scenario sheets
1629 6 : ScMarkData::iterator itr = aMark.begin(), itrEnd = aMark.end();
1630 12 : for (; itr != itrEnd && *itr < nTabCount; ++itr)
1631 6 : for( SCTAB j = *itr+1; j<nTabCount && pDoc->IsScenario(j); j++ )
1632 0 : aFullMark.SelectTable( j, true );
1633 :
1634 6 : SCTAB nSelCount = aMark.GetSelectCount();
1635 :
1636 : // zugehoerige Szenarien auch anpassen
1637 : // Test zusammengefasste
1638 :
1639 6 : SCCOL nMergeTestStartCol = nStartCol;
1640 6 : SCROW nMergeTestStartRow = nStartRow;
1641 6 : SCCOL nMergeTestEndCol = nEndCol;
1642 6 : SCROW nMergeTestEndRow = nEndRow;
1643 :
1644 6 : ScRange aExtendMergeRange( rRange );
1645 :
1646 6 : if( rRange.aStart == rRange.aEnd && pDoc->HasAttrib(rRange, HASATTR_MERGED) )
1647 : {
1648 0 : pDoc->ExtendMerge( aExtendMergeRange );
1649 0 : pDoc->ExtendOverlapped( aExtendMergeRange );
1650 0 : nMergeTestEndCol = aExtendMergeRange.aEnd.Col();
1651 0 : nMergeTestEndRow = aExtendMergeRange.aEnd.Row();
1652 0 : nPaintEndCol = nMergeTestEndCol;
1653 0 : nPaintEndRow = nMergeTestEndRow;
1654 : }
1655 :
1656 6 : if ( eCmd == INS_INSROWS )
1657 : {
1658 2 : nMergeTestStartCol = 0;
1659 2 : nMergeTestEndCol = MAXCOL;
1660 : }
1661 6 : if ( eCmd == INS_INSCOLS )
1662 : {
1663 3 : nMergeTestStartRow = 0;
1664 3 : nMergeTestEndRow = MAXROW;
1665 : }
1666 6 : if ( eCmd == INS_CELLSDOWN )
1667 0 : nMergeTestEndRow = MAXROW;
1668 6 : if ( eCmd == INS_CELLSRIGHT )
1669 1 : nMergeTestEndCol = MAXCOL;
1670 :
1671 6 : bool bNeedRefresh = false;
1672 :
1673 6 : SCCOL nEditTestEndCol = (eCmd==INS_INSCOLS) ? MAXCOL : nMergeTestEndCol;
1674 6 : SCROW nEditTestEndRow = (eCmd==INS_INSROWS) ? MAXROW : nMergeTestEndRow;
1675 6 : ScEditableTester aTester( pDoc, nMergeTestStartCol, nMergeTestStartRow, nEditTestEndCol, nEditTestEndRow, aMark );
1676 6 : if (!aTester.IsEditable())
1677 : {
1678 0 : if (!bApi)
1679 0 : rDocShell.ErrorMessage(aTester.GetMessageId());
1680 0 : return false;
1681 : }
1682 :
1683 : // Check if this insertion is allowed with respect to pivot table.
1684 6 : if (!canInsertCellsByPivot(rRange, aMark, eCmd, pDoc))
1685 : {
1686 0 : if (!bApi)
1687 0 : rDocShell.ErrorMessage(STR_NO_INSERT_DELETE_OVER_PIVOT_TABLE);
1688 0 : return false;
1689 : }
1690 :
1691 12 : WaitObject aWait( rDocShell.GetActiveDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference
1692 :
1693 6 : ScDocument* pRefUndoDoc = NULL;
1694 6 : ScRefUndoData* pUndoData = NULL;
1695 6 : if ( bRecord )
1696 : {
1697 6 : pRefUndoDoc = new ScDocument( SCDOCMODE_UNDO );
1698 6 : pRefUndoDoc->InitUndo( pDoc, 0, nTabCount-1, false, false );
1699 :
1700 : // pRefUndoDoc is filled in InsertCol / InsertRow
1701 :
1702 6 : pUndoData = new ScRefUndoData( pDoc );
1703 :
1704 6 : pDoc->BeginDrawUndo();
1705 : }
1706 :
1707 : // #i8302 : we unmerge overwhelming ranges, before insertion all the actions are put in the same ListAction
1708 : // the patch comes from mloiseleur and maoyg
1709 6 : bool bInsertMerge = false;
1710 12 : std::vector<ScRange> qIncreaseRange;
1711 12 : String aUndo = ScGlobal::GetRscString( STR_UNDO_INSERTCELLS );
1712 6 : if (bRecord)
1713 6 : rDocShell.GetUndoManager()->EnterListAction( aUndo, aUndo );
1714 :
1715 6 : itr = aMark.begin();
1716 12 : for (; itr != itrEnd && nTabCount; ++itr)
1717 : {
1718 6 : pDoc->InitializeNoteCaptions(*itr);
1719 :
1720 6 : i = *itr;
1721 6 : if( pDoc->HasAttrib( nMergeTestStartCol, nMergeTestStartRow, i, nMergeTestEndCol, nMergeTestEndRow, i, HASATTR_MERGED | HASATTR_OVERLAPPED ) )
1722 : {
1723 1 : if (eCmd==INS_CELLSRIGHT)
1724 0 : bNeedRefresh = true;
1725 :
1726 1 : SCCOL nMergeStartCol = nMergeTestStartCol;
1727 1 : SCROW nMergeStartRow = nMergeTestStartRow;
1728 1 : SCCOL nMergeEndCol = nMergeTestEndCol;
1729 1 : SCROW nMergeEndRow = nMergeTestEndRow;
1730 :
1731 1 : pDoc->ExtendMerge( nMergeStartCol, nMergeStartRow, nMergeEndCol, nMergeEndRow, i );
1732 1 : pDoc->ExtendOverlapped( nMergeStartCol, nMergeStartRow, nMergeEndCol, nMergeEndRow, i );
1733 :
1734 1 : if(( eCmd == INS_CELLSDOWN && ( nMergeStartCol != nMergeTestStartCol || nMergeEndCol != nMergeTestEndCol )) ||
1735 0 : (eCmd == INS_CELLSRIGHT && ( nMergeStartRow != nMergeTestStartRow || nMergeEndRow != nMergeTestEndRow )) )
1736 : {
1737 0 : if (!bApi)
1738 0 : rDocShell.ErrorMessage(STR_MSSG_INSERTCELLS_0);
1739 0 : rDocShell.GetUndoManager()->LeaveListAction();
1740 0 : delete pUndoData;
1741 0 : return false;
1742 : }
1743 :
1744 1 : SCCOL nTestCol = -1;
1745 1 : SCROW nTestRow1 = -1;
1746 1 : SCROW nTestRow2 = -1;
1747 :
1748 1 : ScDocAttrIterator aTestIter( pDoc, i, nMergeTestStartCol, nMergeTestStartRow, nMergeTestEndCol, nMergeTestEndRow );
1749 1 : ScRange aExtendRange( nMergeTestStartCol, nMergeTestStartRow, i, nMergeTestEndCol, nMergeTestEndRow, i );
1750 1 : const ScPatternAttr* pPattern = NULL;
1751 1 : const ScMergeAttr* pMergeFlag = NULL;
1752 1 : const ScMergeFlagAttr* pMergeFlagAttr = NULL;
1753 1026 : while ( ( pPattern = aTestIter.GetNext( nTestCol, nTestRow1, nTestRow2 ) ) != NULL )
1754 : {
1755 1024 : pMergeFlag = (const ScMergeAttr*) &pPattern->GetItem(ATTR_MERGE);
1756 1024 : pMergeFlagAttr = (const ScMergeFlagAttr*) &pPattern->GetItem(ATTR_MERGE_FLAG);
1757 1024 : sal_Int16 nNewFlags = pMergeFlagAttr->GetValue() & ( SC_MF_HOR | SC_MF_VER );
1758 1024 : if( ( pMergeFlag && pMergeFlag->IsMerged() ) || nNewFlags == SC_MF_HOR || nNewFlags == SC_MF_VER )
1759 : {
1760 1 : ScRange aRange( nTestCol, nTestRow1, i );
1761 1 : pDoc->ExtendOverlapped(aRange);
1762 1 : pDoc->ExtendMerge(aRange, true);
1763 :
1764 1 : if( nTestRow1 < nTestRow2 && nNewFlags == SC_MF_HOR )
1765 : {
1766 0 : for( SCROW nTestRow = nTestRow1; nTestRow <= nTestRow2; nTestRow++ )
1767 : {
1768 0 : ScRange aTestRange( nTestCol, nTestRow, i );
1769 0 : pDoc->ExtendOverlapped( aTestRange );
1770 0 : pDoc->ExtendMerge( aTestRange, true);
1771 0 : ScRange aMergeRange( aTestRange.aStart.Col(),aTestRange.aStart.Row(), i );
1772 0 : if( !aExtendRange.In( aMergeRange ) )
1773 : {
1774 0 : qIncreaseRange.push_back( aTestRange );
1775 0 : bInsertMerge = true;
1776 : }
1777 0 : }
1778 : }
1779 : else
1780 : {
1781 1 : ScRange aMergeRange( aRange.aStart.Col(),aRange.aStart.Row(), i );
1782 1 : if( !aExtendRange.In( aMergeRange ) )
1783 : {
1784 1 : qIncreaseRange.push_back( aRange );
1785 : }
1786 1 : bInsertMerge = true;
1787 : }
1788 : }
1789 : }
1790 :
1791 1 : if( bInsertMerge )
1792 : {
1793 1 : if( eCmd == INS_INSROWS || eCmd == INS_CELLSDOWN )
1794 : {
1795 1 : nStartRow = aExtendMergeRange.aStart.Row();
1796 1 : nEndRow = aExtendMergeRange.aEnd.Row();
1797 :
1798 2 : if( eCmd == INS_CELLSDOWN )
1799 0 : nEndCol = nMergeTestEndCol;
1800 : else
1801 : {
1802 1 : nStartCol = 0;
1803 1 : nEndCol = MAXCOL;
1804 : }
1805 : }
1806 0 : else if( eCmd == INS_CELLSRIGHT || eCmd == INS_INSCOLS )
1807 : {
1808 :
1809 0 : nStartCol = aExtendMergeRange.aStart.Col();
1810 0 : nEndCol = aExtendMergeRange.aEnd.Col();
1811 0 : if( eCmd == INS_CELLSRIGHT )
1812 : {
1813 0 : nEndRow = nMergeTestEndRow;
1814 : }
1815 : else
1816 : {
1817 0 : nStartRow = 0;
1818 0 : nEndRow = MAXROW;
1819 : }
1820 : }
1821 :
1822 1 : if( !qIncreaseRange.empty() )
1823 : {
1824 2 : for( ::std::vector<ScRange>::const_iterator iIter( qIncreaseRange.begin()); iIter != qIncreaseRange.end(); ++iIter )
1825 : {
1826 1 : ScRange aRange( *iIter );
1827 1 : if( pDoc->HasAttrib( aRange, HASATTR_OVERLAPPED | HASATTR_MERGED ) )
1828 : {
1829 1 : UnmergeCells( aRange, true );
1830 : }
1831 : }
1832 : }
1833 : }
1834 : else
1835 : {
1836 0 : if (!bApi)
1837 0 : rDocShell.ErrorMessage(STR_MSSG_INSERTCELLS_0);
1838 0 : rDocShell.GetUndoManager()->LeaveListAction();
1839 0 : delete pUndoData;
1840 0 : return false;
1841 1 : }
1842 : }
1843 : }
1844 :
1845 6 : switch (eCmd)
1846 : {
1847 : case INS_CELLSDOWN:
1848 0 : bSuccess = pDoc->InsertRow( nStartCol, 0, nEndCol, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, &aFullMark );
1849 0 : nPaintEndRow = MAXROW;
1850 0 : break;
1851 : case INS_INSROWS:
1852 2 : bSuccess = pDoc->InsertRow( 0, 0, MAXCOL, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, &aFullMark );
1853 2 : nPaintStartCol = 0;
1854 2 : nPaintEndCol = MAXCOL;
1855 2 : nPaintEndRow = MAXROW;
1856 2 : nPaintFlags |= PAINT_LEFT;
1857 2 : break;
1858 : case INS_CELLSRIGHT:
1859 1 : bSuccess = pDoc->InsertCol( nStartRow, 0, nEndRow, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &aFullMark );
1860 1 : nPaintEndCol = MAXCOL;
1861 1 : break;
1862 : case INS_INSCOLS:
1863 3 : bSuccess = pDoc->InsertCol( 0, 0, MAXROW, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &aFullMark );
1864 3 : nPaintStartRow = 0;
1865 3 : nPaintEndRow = MAXROW;
1866 3 : nPaintEndCol = MAXCOL;
1867 3 : nPaintFlags |= PAINT_TOP;
1868 3 : break;
1869 : default:
1870 : OSL_FAIL("Falscher Code beim Einfuegen");
1871 0 : bSuccess = false;
1872 0 : break;
1873 : }
1874 :
1875 6 : if ( bSuccess )
1876 : {
1877 6 : SCTAB* pTabs = NULL;
1878 6 : SCTAB* pScenarios = NULL;
1879 6 : SCTAB nUndoPos = 0;
1880 :
1881 6 : if ( bRecord )
1882 : {
1883 6 : pTabs = new SCTAB[nSelCount];
1884 6 : pScenarios = new SCTAB[nSelCount];
1885 6 : nUndoPos = 0;
1886 6 : itr = aMark.begin();
1887 12 : for (; itr != itrEnd && *itr < nTabCount; ++itr)
1888 : {
1889 6 : SCTAB nCount = 0;
1890 6 : for( SCTAB j=*itr+1; j<nTabCount && pDoc->IsScenario(j); j++ )
1891 0 : nCount ++;
1892 :
1893 6 : pScenarios[nUndoPos] = nCount;
1894 6 : pTabs[nUndoPos] = *itr;
1895 6 : nUndoPos ++;
1896 : }
1897 :
1898 6 : if( !bInsertMerge )
1899 : {
1900 5 : rDocShell.GetUndoManager()->LeaveListAction();
1901 : }
1902 :
1903 6 : rDocShell.GetUndoManager()->AddUndoAction( new ScUndoInsertCells(
1904 : &rDocShell, ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab ),
1905 6 : nUndoPos, pTabs, pScenarios, eCmd, pRefUndoDoc, pUndoData, bPartOfPaste ) );
1906 : }
1907 :
1908 : // #i8302 : we remerge growing ranges, with the new part inserted
1909 :
1910 13 : while( !qIncreaseRange.empty() )
1911 : {
1912 1 : ScRange aRange = qIncreaseRange.back();
1913 1 : if( !pDoc->HasAttrib( aRange, HASATTR_OVERLAPPED | HASATTR_MERGED ) )
1914 : {
1915 1 : switch (eCmd)
1916 : {
1917 : case INS_CELLSDOWN:
1918 : case INS_INSROWS:
1919 1 : aRange.aEnd.IncRow(static_cast<SCsCOL>(nEndRow-nStartRow+1));
1920 1 : break;
1921 : case INS_CELLSRIGHT:
1922 : case INS_INSCOLS:
1923 0 : aRange.aEnd.IncCol(static_cast<SCsCOL>(nEndCol-nStartCol+1));
1924 0 : break;
1925 : default:
1926 0 : break;
1927 : }
1928 : ScCellMergeOption aMergeOption(
1929 1 : aRange.aStart.Col(), aRange.aStart.Row(),
1930 2 : aRange.aEnd.Col(), aRange.aEnd.Row() );
1931 1 : aMergeOption.maTabs.insert(aRange.aStart.Tab());
1932 1 : MergeCells(aMergeOption, false, true, true);
1933 : }
1934 1 : qIncreaseRange.pop_back();
1935 : }
1936 :
1937 6 : if( bInsertMerge )
1938 1 : rDocShell.GetUndoManager()->LeaveListAction();
1939 :
1940 6 : itr = aMark.begin();
1941 12 : for (; itr != itrEnd && *itr < nTabCount; ++itr)
1942 : {
1943 6 : i = *itr;
1944 6 : pDoc->SetDrawPageSize(i);
1945 :
1946 6 : if (bNeedRefresh)
1947 0 : pDoc->ExtendMerge( nMergeTestStartCol, nMergeTestStartRow, nMergeTestEndCol, nMergeTestEndRow, i, true );
1948 : else
1949 6 : pDoc->RefreshAutoFilter( nMergeTestStartCol, nMergeTestStartRow, nMergeTestEndCol, nMergeTestEndRow, i );
1950 :
1951 6 : if ( eCmd == INS_INSROWS || eCmd == INS_INSCOLS )
1952 5 : pDoc->UpdatePageBreaks( i );
1953 :
1954 6 : sal_uInt16 nExtFlags = 0;
1955 6 : rDocShell.UpdatePaintExt( nExtFlags, nPaintStartCol, nPaintStartRow, i, nPaintEndCol, nPaintEndRow, i );
1956 :
1957 6 : SCTAB nScenarioCount = 0;
1958 :
1959 6 : for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
1960 0 : nScenarioCount ++;
1961 :
1962 12 : bool bAdjusted = ( eCmd == INS_INSROWS ) ? AdjustRowHeight(ScRange(0, nStartRow, i, MAXCOL, nEndRow, i+nScenarioCount )) :
1963 14 : AdjustRowHeight(ScRange(0, nPaintStartRow, i, MAXCOL, nPaintEndRow, i+nScenarioCount ));
1964 6 : if (bAdjusted)
1965 : {
1966 : // paint only what is not done by AdjustRowHeight
1967 3 : if (nPaintFlags & PAINT_TOP)
1968 1 : rDocShell.PostPaint( nPaintStartCol, nPaintStartRow, i, nPaintEndCol, nPaintEndRow, i+nScenarioCount, PAINT_TOP );
1969 : }
1970 : else
1971 3 : rDocShell.PostPaint( nPaintStartCol, nPaintStartRow, i, nPaintEndCol, nPaintEndRow, i+nScenarioCount, nPaintFlags, nExtFlags );
1972 : }
1973 : }
1974 : else
1975 : {
1976 0 : if( bInsertMerge )
1977 : {
1978 0 : while( !qIncreaseRange.empty() )
1979 : {
1980 0 : ScRange aRange = qIncreaseRange.back();
1981 : ScCellMergeOption aMergeOption(
1982 0 : aRange.aStart.Col(), aRange.aStart.Row(),
1983 0 : aRange.aEnd.Col(), aRange.aEnd.Row() );
1984 0 : MergeCells(aMergeOption, false, true, true);
1985 0 : qIncreaseRange.pop_back();
1986 0 : }
1987 :
1988 0 : if( pViewSh )
1989 : {
1990 0 : pViewSh->MarkRange( rRange, false );
1991 0 : pViewSh->SetCursor( nCursorCol, nCursorRow );
1992 : }
1993 : }
1994 :
1995 0 : rDocShell.GetUndoManager()->LeaveListAction();
1996 0 : rDocShell.GetUndoManager()->RemoveLastUndoAction();
1997 :
1998 0 : delete pRefUndoDoc;
1999 0 : delete pUndoData;
2000 0 : if (!bApi)
2001 0 : rDocShell.ErrorMessage(STR_INSERT_FULL); // Spalte/Zeile voll
2002 : }
2003 :
2004 6 : aModificator.SetDocumentModified();
2005 :
2006 6 : SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
2007 12 : return bSuccess;
2008 : }
2009 :
2010 7 : bool ScDocFunc::DeleteCells( const ScRange& rRange, const ScMarkData* pTabMark, DelCellCmd eCmd,
2011 : bool bRecord, bool bApi )
2012 : {
2013 7 : ScDocShellModificator aModificator( rDocShell );
2014 :
2015 7 : SCCOL nStartCol = rRange.aStart.Col();
2016 7 : SCROW nStartRow = rRange.aStart.Row();
2017 7 : SCTAB nStartTab = rRange.aStart.Tab();
2018 7 : SCCOL nEndCol = rRange.aEnd.Col();
2019 7 : SCROW nEndRow = rRange.aEnd.Row();
2020 7 : SCTAB nEndTab = rRange.aEnd.Tab();
2021 :
2022 7 : if ( !ValidRow(nStartRow) || !ValidRow(nEndRow) )
2023 : {
2024 : OSL_FAIL("invalid row in DeleteCells");
2025 0 : return false;
2026 : }
2027 :
2028 7 : ScDocument* pDoc = rDocShell.GetDocument();
2029 7 : SCTAB nTabCount = pDoc->GetTableCount();
2030 7 : SCCOL nPaintStartCol = nStartCol;
2031 7 : SCROW nPaintStartRow = nStartRow;
2032 7 : SCCOL nPaintEndCol = nEndCol;
2033 7 : SCROW nPaintEndRow = nEndRow;
2034 7 : sal_uInt16 nPaintFlags = PAINT_GRID;
2035 :
2036 7 : if (bRecord && !pDoc->IsUndoEnabled())
2037 0 : bRecord = false;
2038 :
2039 14 : ScMarkData aMark;
2040 7 : if (pTabMark)
2041 0 : aMark = *pTabMark;
2042 : else
2043 : {
2044 7 : SCTAB nCount = 0;
2045 7 : for(SCTAB i=0; i<nTabCount; i++ )
2046 : {
2047 7 : if( !pDoc->IsScenario(i) )
2048 : {
2049 7 : nCount++;
2050 7 : if( nCount == nEndTab+1 )
2051 : {
2052 7 : aMark.SelectTable(i, true);
2053 7 : break;
2054 : }
2055 : }
2056 : }
2057 : }
2058 :
2059 14 : ScMarkData aFullMark( aMark ); // including scenario sheets
2060 7 : ScMarkData::iterator itr = aMark.begin(), itrEnd = aMark.end();
2061 14 : for (; itr != itrEnd && *itr < nTabCount; ++itr)
2062 7 : for( SCTAB j = *itr+1; j<nTabCount && pDoc->IsScenario(j); j++ )
2063 0 : aFullMark.SelectTable( j, true );
2064 :
2065 7 : SCTAB nSelCount = aMark.GetSelectCount();
2066 :
2067 7 : SCCOL nUndoStartCol = nStartCol;
2068 7 : SCROW nUndoStartRow = nStartRow;
2069 7 : SCCOL nUndoEndCol = nEndCol;
2070 7 : SCROW nUndoEndRow = nEndRow;
2071 :
2072 7 : ScRange aExtendMergeRange( rRange );
2073 :
2074 7 : if( rRange.aStart == rRange.aEnd && pDoc->HasAttrib(rRange, HASATTR_MERGED) )
2075 : {
2076 0 : pDoc->ExtendMerge( aExtendMergeRange );
2077 0 : pDoc->ExtendOverlapped( aExtendMergeRange );
2078 0 : nUndoEndCol = aExtendMergeRange.aEnd.Col();
2079 0 : nUndoEndRow = aExtendMergeRange.aEnd.Row();
2080 0 : nPaintEndCol = nUndoEndCol;
2081 0 : nPaintEndRow = nUndoEndRow;
2082 : }
2083 :
2084 7 : if (eCmd==DEL_DELROWS)
2085 : {
2086 1 : nUndoStartCol = 0;
2087 1 : nUndoEndCol = MAXCOL;
2088 : }
2089 7 : if (eCmd==DEL_DELCOLS)
2090 : {
2091 3 : nUndoStartRow = 0;
2092 3 : nUndoEndRow = MAXROW;
2093 : }
2094 : // Test Zellschutz
2095 :
2096 7 : SCCOL nEditTestEndX = nUndoEndCol;
2097 7 : if ( eCmd==DEL_DELCOLS || eCmd==DEL_CELLSLEFT )
2098 5 : nEditTestEndX = MAXCOL;
2099 7 : SCROW nEditTestEndY = nUndoEndRow;
2100 7 : if ( eCmd==DEL_DELROWS || eCmd==DEL_CELLSUP )
2101 2 : nEditTestEndY = MAXROW;
2102 7 : ScEditableTester aTester( pDoc, nUndoStartCol, nUndoStartRow, nEditTestEndX, nEditTestEndY, aMark );
2103 7 : if (!aTester.IsEditable())
2104 : {
2105 0 : if (!bApi)
2106 0 : rDocShell.ErrorMessage(aTester.GetMessageId());
2107 0 : return false;
2108 : }
2109 :
2110 7 : if (!canDeleteCellsByPivot(rRange, aMark, eCmd, pDoc))
2111 : {
2112 0 : if (!bApi)
2113 0 : rDocShell.ErrorMessage(STR_NO_INSERT_DELETE_OVER_PIVOT_TABLE);
2114 0 : return false;
2115 : }
2116 : // Test zusammengefasste
2117 :
2118 7 : SCCOL nMergeTestEndCol = (eCmd==DEL_CELLSLEFT) ? MAXCOL : nUndoEndCol;
2119 7 : SCROW nMergeTestEndRow = (eCmd==DEL_CELLSUP) ? MAXROW : nUndoEndRow;
2120 7 : SCCOL nExtendStartCol = nUndoStartCol;
2121 7 : SCROW nExtendStartRow = nUndoStartRow;
2122 7 : bool bNeedRefresh = false;
2123 :
2124 : //Issue 8302 want to be able to insert into the middle of merged cells
2125 : //the patch comes from maoyg
2126 14 : ::std::vector<ScRange> qDecreaseRange;
2127 7 : bool bDeletingMerge = false;
2128 14 : String aUndo = ScGlobal::GetRscString( STR_UNDO_DELETECELLS );
2129 7 : if (bRecord)
2130 7 : rDocShell.GetUndoManager()->EnterListAction( aUndo, aUndo );
2131 :
2132 7 : itr = aMark.begin();
2133 14 : for (; itr != itrEnd && *itr < nTabCount; ++itr)
2134 : {
2135 7 : pDoc->InitializeNoteCaptions(*itr);
2136 :
2137 7 : SCTAB i = *itr;
2138 7 : if ( pDoc->HasAttrib( nUndoStartCol, nUndoStartRow, i, nMergeTestEndCol, nMergeTestEndRow, i, HASATTR_MERGED | HASATTR_OVERLAPPED ))
2139 : {
2140 0 : SCCOL nMergeStartCol = nUndoStartCol;
2141 0 : SCROW nMergeStartRow = nUndoStartRow;
2142 0 : SCCOL nMergeEndCol = nMergeTestEndCol;
2143 0 : SCROW nMergeEndRow = nMergeTestEndRow;
2144 :
2145 0 : pDoc->ExtendMerge( nMergeStartCol, nMergeStartRow, nMergeEndCol, nMergeEndRow, i );
2146 0 : pDoc->ExtendOverlapped( nMergeStartCol, nMergeStartRow, nMergeEndCol, nMergeEndRow, i );
2147 0 : if( ( eCmd == DEL_CELLSUP && ( nMergeStartCol != nUndoStartCol || nMergeEndCol != nMergeTestEndCol))||
2148 0 : ( eCmd == DEL_CELLSLEFT && ( nMergeStartRow != nUndoStartRow || nMergeEndRow != nMergeTestEndRow)))
2149 : {
2150 0 : if (!bApi)
2151 0 : rDocShell.ErrorMessage(STR_MSSG_DELETECELLS_0);
2152 0 : rDocShell.GetUndoManager()->LeaveListAction();
2153 0 : return false;
2154 : }
2155 :
2156 0 : nExtendStartCol = nMergeStartCol;
2157 0 : nExtendStartRow = nMergeStartRow;
2158 0 : SCCOL nTestCol = -1;
2159 0 : SCROW nTestRow1 = -1;
2160 0 : SCROW nTestRow2 = -1;
2161 :
2162 0 : ScDocAttrIterator aTestIter( pDoc, i, nUndoStartCol, nUndoStartRow, nMergeTestEndCol, nMergeTestEndRow );
2163 0 : ScRange aExtendRange( nUndoStartCol, nUndoStartRow, i, nMergeTestEndCol, nMergeTestEndRow, i );
2164 0 : const ScPatternAttr* pPattern = NULL;
2165 0 : const ScMergeAttr* pMergeFlag = NULL;
2166 0 : const ScMergeFlagAttr* pMergeFlagAttr = NULL;
2167 0 : while ( ( pPattern = aTestIter.GetNext( nTestCol, nTestRow1, nTestRow2 ) ) != NULL )
2168 : {
2169 0 : pMergeFlag = (const ScMergeAttr*) &pPattern->GetItem( ATTR_MERGE );
2170 0 : pMergeFlagAttr = (const ScMergeFlagAttr*) &pPattern->GetItem( ATTR_MERGE_FLAG );
2171 0 : sal_Int16 nNewFlags = pMergeFlagAttr->GetValue() & ( SC_MF_HOR | SC_MF_VER );
2172 0 : if( ( pMergeFlag && pMergeFlag->IsMerged() ) || nNewFlags == SC_MF_HOR || nNewFlags == SC_MF_VER )
2173 : {
2174 0 : ScRange aRange( nTestCol, nTestRow1, i );
2175 0 : pDoc->ExtendOverlapped( aRange );
2176 0 : pDoc->ExtendMerge( aRange, true );
2177 :
2178 0 : if( nTestRow1 < nTestRow2 && nNewFlags == SC_MF_HOR )
2179 : {
2180 0 : for( SCROW nTestRow = nTestRow1; nTestRow <= nTestRow2; nTestRow++ )
2181 : {
2182 0 : ScRange aTestRange( nTestCol, nTestRow, i );
2183 0 : pDoc->ExtendOverlapped( aTestRange );
2184 0 : pDoc->ExtendMerge( aTestRange, true );
2185 0 : ScRange aMergeRange( aTestRange.aStart.Col(),aTestRange.aStart.Row(), i );
2186 0 : if( !aExtendRange.In( aMergeRange ) )
2187 : {
2188 0 : qDecreaseRange.push_back( aTestRange );
2189 0 : bDeletingMerge = true;
2190 : }
2191 0 : }
2192 : }
2193 : else
2194 : {
2195 0 : ScRange aMergeRange( aRange.aStart.Col(),aRange.aStart.Row(), i );
2196 0 : if( !aExtendRange.In( aMergeRange ) )
2197 : {
2198 0 : qDecreaseRange.push_back( aRange );
2199 : }
2200 0 : bDeletingMerge = true;
2201 : }
2202 : }
2203 : }
2204 :
2205 0 : if( bDeletingMerge )
2206 : {
2207 :
2208 0 : if( eCmd == DEL_DELROWS || eCmd == DEL_CELLSUP )
2209 : {
2210 0 : nStartRow = aExtendMergeRange.aStart.Row();
2211 0 : nEndRow = aExtendMergeRange.aEnd.Row();
2212 0 : bNeedRefresh = true;
2213 :
2214 0 : if( eCmd == DEL_CELLSUP )
2215 : {
2216 0 : nEndCol = aExtendMergeRange.aEnd.Col();
2217 : }
2218 : else
2219 : {
2220 0 : nStartCol = 0;
2221 0 : nEndCol = MAXCOL;
2222 : }
2223 : }
2224 0 : else if( eCmd == DEL_CELLSLEFT || eCmd == DEL_DELCOLS )
2225 : {
2226 :
2227 0 : nStartCol = aExtendMergeRange.aStart.Col();
2228 0 : nEndCol = aExtendMergeRange.aEnd.Col();
2229 0 : if( eCmd == DEL_CELLSLEFT )
2230 : {
2231 0 : nEndRow = aExtendMergeRange.aEnd.Row();
2232 0 : bNeedRefresh = true;
2233 : }
2234 : else
2235 : {
2236 0 : nStartRow = 0;
2237 0 : nEndRow = MAXROW;
2238 : }
2239 : }
2240 :
2241 0 : if( !qDecreaseRange.empty() )
2242 : {
2243 0 : for( ::std::vector<ScRange>::const_iterator iIter( qDecreaseRange.begin()); iIter != qDecreaseRange.end(); ++iIter )
2244 : {
2245 0 : ScRange aRange( *iIter );
2246 0 : if( pDoc->HasAttrib( aRange, HASATTR_OVERLAPPED | HASATTR_MERGED ) )
2247 : {
2248 0 : UnmergeCells( aRange, true );
2249 : }
2250 : }
2251 : }
2252 : }
2253 : else
2254 : {
2255 0 : if (!bApi)
2256 0 : rDocShell.ErrorMessage(STR_MSSG_DELETECELLS_0);
2257 0 : rDocShell.GetUndoManager()->LeaveListAction();
2258 0 : return false;
2259 0 : }
2260 : }
2261 : }
2262 :
2263 : //
2264 : // ausfuehren
2265 : //
2266 :
2267 14 : WaitObject aWait( rDocShell.GetActiveDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference
2268 :
2269 7 : ScDocument* pUndoDoc = NULL;
2270 7 : ScDocument* pRefUndoDoc = NULL;
2271 7 : ScRefUndoData* pUndoData = NULL;
2272 7 : if ( bRecord )
2273 : {
2274 : // With the fix for #101329#, UpdateRef always puts cells into pRefUndoDoc at their old position,
2275 : // so it's no longer necessary to copy more than the deleted range into pUndoDoc.
2276 :
2277 7 : pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
2278 7 : pUndoDoc->InitUndo( pDoc, 0, nTabCount-1, (eCmd==DEL_DELCOLS), (eCmd==DEL_DELROWS) );
2279 7 : itr = aMark.begin();
2280 14 : for (; itr != itrEnd && *itr < nTabCount; ++itr)
2281 : {
2282 7 : SCTAB nScenarioCount = 0;
2283 :
2284 7 : for( SCTAB j = *itr+1; j<nTabCount && pDoc->IsScenario(j); j++ )
2285 0 : nScenarioCount ++;
2286 :
2287 14 : pDoc->CopyToDocument( nUndoStartCol, nUndoStartRow, *itr, nUndoEndCol, nUndoEndRow, *itr+nScenarioCount,
2288 14 : IDF_ALL | IDF_NOCAPTIONS, false, pUndoDoc );
2289 : }
2290 :
2291 7 : pRefUndoDoc = new ScDocument( SCDOCMODE_UNDO );
2292 7 : pRefUndoDoc->InitUndo( pDoc, 0, nTabCount-1, false, false );
2293 :
2294 7 : pUndoData = new ScRefUndoData( pDoc );
2295 :
2296 7 : pDoc->BeginDrawUndo();
2297 : }
2298 :
2299 7 : sal_uInt16 nExtFlags = 0;
2300 7 : itr = aMark.begin();
2301 14 : for (; itr != itrEnd && *itr < nTabCount; ++itr)
2302 : {
2303 7 : rDocShell.UpdatePaintExt( nExtFlags, nStartCol, nStartRow, *itr, nEndCol, nEndRow, *itr );
2304 : }
2305 :
2306 7 : bool bUndoOutline = false;
2307 7 : switch (eCmd)
2308 : {
2309 : case DEL_CELLSUP:
2310 1 : pDoc->DeleteRow( nStartCol, 0, nEndCol, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, NULL, &aFullMark );
2311 1 : nPaintEndRow = MAXROW;
2312 1 : break;
2313 : case DEL_DELROWS:
2314 1 : pDoc->DeleteRow( 0, 0, MAXCOL, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, &bUndoOutline, &aFullMark );
2315 1 : nPaintStartCol = 0;
2316 1 : nPaintEndCol = MAXCOL;
2317 1 : nPaintEndRow = MAXROW;
2318 1 : nPaintFlags |= PAINT_LEFT;
2319 1 : break;
2320 : case DEL_CELLSLEFT:
2321 2 : pDoc->DeleteCol( nStartRow, 0, nEndRow, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, NULL, &aFullMark );
2322 2 : nPaintEndCol = MAXCOL;
2323 2 : break;
2324 : case DEL_DELCOLS:
2325 3 : pDoc->DeleteCol( 0, 0, MAXROW, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &bUndoOutline, &aFullMark );
2326 3 : nPaintStartRow = 0;
2327 3 : nPaintEndRow = MAXROW;
2328 3 : nPaintEndCol = MAXCOL;
2329 3 : nPaintFlags |= PAINT_TOP;
2330 3 : break;
2331 : default:
2332 : OSL_FAIL("Falscher Code beim Loeschen");
2333 0 : break;
2334 : }
2335 :
2336 : //! Test, ob Outline in Groesse geaendert
2337 :
2338 7 : if ( bRecord )
2339 : {
2340 7 : itr = aFullMark.begin(), itrEnd = aFullMark.end();
2341 14 : for (; itr != itrEnd && *itr < nTabCount; ++itr)
2342 7 : pRefUndoDoc->DeleteAreaTab(nUndoStartCol,nUndoStartRow,nUndoEndCol,nUndoEndRow, *itr, IDF_ALL);
2343 :
2344 : // alle Tabellen anlegen, damit Formeln kopiert werden koennen:
2345 7 : pUndoDoc->AddUndoTab( 0, nTabCount-1, false, false );
2346 :
2347 : // kopieren mit bColRowFlags=false (#54194#)
2348 7 : pRefUndoDoc->CopyToDocument(0,0,0,MAXCOL,MAXROW,MAXTAB,IDF_FORMULA,false,pUndoDoc,NULL,false);
2349 7 : delete pRefUndoDoc;
2350 :
2351 7 : SCTAB* pTabs = new SCTAB[nSelCount];
2352 7 : SCTAB* pScenarios = new SCTAB[nSelCount];
2353 7 : SCTAB nUndoPos = 0;
2354 :
2355 7 : itr = aMark.begin(), itrEnd = aMark.end();
2356 14 : for (; itr != itrEnd && *itr < nTabCount; ++itr)
2357 : {
2358 7 : SCTAB nCount = 0;
2359 7 : for( SCTAB j=*itr+1; j<nTabCount && pDoc->IsScenario(j); j++ )
2360 0 : nCount ++;
2361 :
2362 7 : pScenarios[nUndoPos] = nCount;
2363 7 : pTabs[nUndoPos] = *itr;
2364 7 : nUndoPos ++;
2365 : }
2366 :
2367 7 : if( !bDeletingMerge )
2368 : {
2369 7 : rDocShell.GetUndoManager()->LeaveListAction();
2370 : }
2371 :
2372 7 : rDocShell.GetUndoManager()->AddUndoAction( new ScUndoDeleteCells(
2373 : &rDocShell, ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab ),nUndoPos, pTabs, pScenarios,
2374 7 : eCmd, pUndoDoc, pUndoData ) );
2375 : }
2376 :
2377 : // #i8302 want to be able to insert into the middle of merged cells
2378 : // the patch comes from maoyg
2379 :
2380 14 : while( !qDecreaseRange.empty() )
2381 : {
2382 0 : ScRange aRange = qDecreaseRange.back();
2383 :
2384 0 : long nDecreaseRowCount = 0;
2385 0 : long nDecreaseColCount = 0;
2386 0 : if( eCmd == DEL_CELLSUP || eCmd == DEL_DELROWS )
2387 : {
2388 0 : if( nStartRow >= aRange.aStart.Row() && nStartRow <= aRange.aEnd.Row() && nEndRow>= aRange.aStart.Row() && nEndRow <= aRange.aEnd.Row() )
2389 0 : nDecreaseRowCount = nEndRow-nStartRow+1;
2390 0 : else if( nStartRow >= aRange.aStart.Row() && nStartRow <= aRange.aEnd.Row() && nEndRow >= aRange.aStart.Row() && nEndRow >= aRange.aEnd.Row() )
2391 0 : nDecreaseRowCount = aRange.aEnd.Row()-nStartRow+1;
2392 0 : else if( nStartRow >= aRange.aStart.Row() && nStartRow >= aRange.aEnd.Row() && nEndRow>= aRange.aStart.Row() && nEndRow <= aRange.aEnd.Row() )
2393 0 : nDecreaseRowCount = aRange.aEnd.Row()-nEndRow+1;
2394 : }
2395 0 : else if( eCmd == DEL_CELLSLEFT || eCmd == DEL_DELCOLS )
2396 : {
2397 0 : if( nStartCol >= aRange.aStart.Col() && nStartCol <= aRange.aEnd.Col() && nEndCol>= aRange.aStart.Col() && nEndCol <= aRange.aEnd.Col() )
2398 0 : nDecreaseColCount = nEndCol-nStartCol+1;
2399 0 : else if( nStartCol >= aRange.aStart.Col() && nStartCol <= aRange.aEnd.Col() && nEndCol >= aRange.aStart.Col() && nEndCol >= aRange.aEnd.Col() )
2400 0 : nDecreaseColCount = aRange.aEnd.Col()-nStartCol+1;
2401 0 : else if( nStartCol >= aRange.aStart.Col() && nStartCol >= aRange.aEnd.Col() && nEndCol>= aRange.aStart.Col() && nEndCol <= aRange.aEnd.Col() )
2402 0 : nDecreaseColCount = aRange.aEnd.Col()-nEndCol+1;
2403 : }
2404 :
2405 0 : switch (eCmd)
2406 : {
2407 : case DEL_CELLSUP:
2408 : case DEL_DELROWS:
2409 0 : aRange.aEnd.SetRow(static_cast<SCsCOL>( aRange.aEnd.Row()-nDecreaseRowCount));
2410 0 : break;
2411 : case DEL_CELLSLEFT:
2412 : case DEL_DELCOLS:
2413 0 : aRange.aEnd.SetCol(static_cast<SCsCOL>( aRange.aEnd.Col()-nDecreaseColCount));
2414 0 : break;
2415 : default:
2416 0 : break;
2417 : }
2418 :
2419 0 : if( !pDoc->HasAttrib( aRange, HASATTR_OVERLAPPED | HASATTR_MERGED ) )
2420 : {
2421 0 : ScCellMergeOption aMergeOption(aRange);
2422 0 : MergeCells( aMergeOption, false, true, true );
2423 : }
2424 0 : qDecreaseRange.pop_back();
2425 : }
2426 :
2427 7 : if( bDeletingMerge )
2428 0 : rDocShell.GetUndoManager()->LeaveListAction();
2429 :
2430 7 : if ( bNeedRefresh )
2431 : {
2432 : // #i51445# old merge flag attributes must be deleted also for single cells,
2433 : // not only for whole columns/rows
2434 :
2435 0 : if ( eCmd==DEL_DELCOLS || eCmd==DEL_CELLSLEFT )
2436 0 : nMergeTestEndCol = MAXCOL;
2437 0 : if ( eCmd==DEL_DELROWS || eCmd==DEL_CELLSUP )
2438 0 : nMergeTestEndRow = MAXROW;
2439 0 : ScPatternAttr aPattern( pDoc->GetPool() );
2440 0 : aPattern.GetItemSet().Put( ScMergeFlagAttr() );
2441 :
2442 0 : pDoc->ApplyPatternArea( nExtendStartCol, nExtendStartRow, nMergeTestEndCol, nMergeTestEndRow, aMark, aPattern );
2443 :
2444 0 : itr = aMark.begin(), itrEnd = aMark.end();
2445 0 : for (; itr != itrEnd && *itr < nTabCount; ++itr)
2446 : {
2447 0 : SCTAB nScenarioCount = 0;
2448 :
2449 0 : for( SCTAB j = *itr+1; j<nTabCount && pDoc->IsScenario(j); j++ )
2450 0 : nScenarioCount ++;
2451 :
2452 0 : ScRange aMergedRange( nExtendStartCol, nExtendStartRow, *itr, nMergeTestEndCol, nMergeTestEndRow, *itr+nScenarioCount );
2453 0 : pDoc->ExtendMerge( aMergedRange, true );
2454 0 : }
2455 : }
2456 :
2457 7 : itr = aMark.begin(), itrEnd = aMark.end();
2458 14 : for (; itr != itrEnd && *itr < nTabCount; ++itr)
2459 : {
2460 7 : pDoc->SetDrawPageSize(*itr);
2461 :
2462 7 : if ( eCmd == DEL_DELCOLS || eCmd == DEL_DELROWS )
2463 4 : pDoc->UpdatePageBreaks( *itr );
2464 :
2465 7 : rDocShell.UpdatePaintExt( nExtFlags, nPaintStartCol, nPaintStartRow, *itr, nPaintEndCol, nPaintEndRow, *itr );
2466 :
2467 7 : SCTAB nScenarioCount = 0;
2468 :
2469 7 : for( SCTAB j = *itr+1; j<nTabCount && pDoc->IsScenario(j); j++ )
2470 0 : nScenarioCount ++;
2471 :
2472 : // ganze Zeilen loeschen: nichts anpassen
2473 7 : if ( eCmd == DEL_DELROWS || !AdjustRowHeight(ScRange( 0, nPaintStartRow, *itr, MAXCOL, nPaintEndRow, *itr+nScenarioCount )) )
2474 6 : rDocShell.PostPaint( nPaintStartCol, nPaintStartRow, *itr, nPaintEndCol, nPaintEndRow, *itr+nScenarioCount, nPaintFlags, nExtFlags );
2475 : else
2476 : {
2477 : // paint only what is not done by AdjustRowHeight
2478 1 : if (nExtFlags & SC_PF_LINES)
2479 1 : lcl_PaintAbove( rDocShell, ScRange( nPaintStartCol, nPaintStartRow, *itr, nPaintEndCol, nPaintEndRow, *itr+nScenarioCount) );
2480 1 : if (nPaintFlags & PAINT_TOP)
2481 0 : rDocShell.PostPaint( nPaintStartCol, nPaintStartRow, *itr, nPaintEndCol, nPaintEndRow, *itr+nScenarioCount, PAINT_TOP );
2482 : }
2483 : }
2484 7 : aModificator.SetDocumentModified();
2485 :
2486 7 : SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
2487 :
2488 14 : return true;
2489 : }
2490 :
2491 3 : sal_Bool ScDocFunc::MoveBlock( const ScRange& rSource, const ScAddress& rDestPos,
2492 : sal_Bool bCut, sal_Bool bRecord, sal_Bool bPaint, sal_Bool bApi )
2493 : {
2494 3 : ScDocShellModificator aModificator( rDocShell );
2495 :
2496 3 : SCCOL nStartCol = rSource.aStart.Col();
2497 3 : SCROW nStartRow = rSource.aStart.Row();
2498 3 : SCTAB nStartTab = rSource.aStart.Tab();
2499 3 : SCCOL nEndCol = rSource.aEnd.Col();
2500 3 : SCROW nEndRow = rSource.aEnd.Row();
2501 3 : SCTAB nEndTab = rSource.aEnd.Tab();
2502 3 : SCCOL nDestCol = rDestPos.Col();
2503 3 : SCROW nDestRow = rDestPos.Row();
2504 3 : SCTAB nDestTab = rDestPos.Tab();
2505 :
2506 3 : if ( !ValidRow(nStartRow) || !ValidRow(nEndRow) || !ValidRow(nDestRow) )
2507 : {
2508 : OSL_FAIL("invalid row in MoveBlock");
2509 0 : return false;
2510 : }
2511 :
2512 : // zugehoerige Szenarien auch anpassen - nur wenn innerhalb einer Tabelle verschoben wird!
2513 3 : sal_Bool bScenariosAdded = false;
2514 3 : ScDocument* pDoc = rDocShell.GetDocument();
2515 3 : if (bRecord && !pDoc->IsUndoEnabled())
2516 0 : bRecord = false;
2517 :
2518 3 : SCTAB nTabCount = pDoc->GetTableCount();
2519 3 : if ( nDestTab == nStartTab && !pDoc->IsScenario(nEndTab) )
2520 6 : while ( nEndTab+1 < nTabCount && pDoc->IsScenario(nEndTab+1) )
2521 : {
2522 0 : ++nEndTab;
2523 0 : bScenariosAdded = sal_True;
2524 : }
2525 :
2526 3 : SCTAB nSrcTabCount = nEndTab-nStartTab+1;
2527 3 : SCTAB nDestEndTab = nDestTab+nSrcTabCount-1;
2528 : SCTAB nTab;
2529 :
2530 3 : ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
2531 :
2532 6 : ScMarkData aSourceMark;
2533 6 : for (nTab=nStartTab; nTab<=nEndTab; nTab++)
2534 3 : aSourceMark.SelectTable( nTab, sal_True ); // Source selektieren
2535 3 : aSourceMark.SetMarkArea( rSource );
2536 :
2537 6 : ScDocShellRef aDragShellRef;
2538 3 : if ( pDoc->HasOLEObjectsInArea( rSource ) )
2539 : {
2540 0 : aDragShellRef = new ScDocShell; // DocShell needs a Ref immediately
2541 0 : aDragShellRef->DoInitNew(NULL);
2542 : }
2543 3 : ScDrawLayer::SetGlobalDrawPersist(aDragShellRef);
2544 :
2545 6 : ScClipParam aClipParam(ScRange(nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nStartTab), bCut);
2546 3 : pDoc->CopyToClip(aClipParam, pClipDoc, &aSourceMark, false, bScenariosAdded, true);
2547 :
2548 3 : ScDrawLayer::SetGlobalDrawPersist(NULL);
2549 :
2550 3 : SCCOL nOldEndCol = nEndCol;
2551 3 : SCROW nOldEndRow = nEndRow;
2552 3 : sal_Bool bClipOver = false;
2553 6 : for (nTab=nStartTab; nTab<=nEndTab; nTab++)
2554 : {
2555 3 : SCCOL nTmpEndCol = nOldEndCol;
2556 3 : SCROW nTmpEndRow = nOldEndRow;
2557 3 : if (pDoc->ExtendMerge( nStartCol, nStartRow, nTmpEndCol, nTmpEndRow, nTab ))
2558 0 : bClipOver = sal_True;
2559 3 : if ( nTmpEndCol > nEndCol ) nEndCol = nTmpEndCol;
2560 3 : if ( nTmpEndRow > nEndRow ) nEndRow = nTmpEndRow;
2561 : }
2562 :
2563 3 : SCCOL nDestEndCol = nDestCol + ( nOldEndCol-nStartCol );
2564 3 : SCROW nDestEndRow = nDestRow + ( nOldEndRow-nStartRow );
2565 :
2566 3 : SCCOL nUndoEndCol = nDestCol + ( nEndCol-nStartCol ); // erweitert im Zielblock
2567 3 : SCROW nUndoEndRow = nDestRow + ( nEndRow-nStartRow );
2568 :
2569 3 : sal_Bool bIncludeFiltered = bCut;
2570 3 : if ( !bIncludeFiltered )
2571 : {
2572 : // adjust sizes to include only non-filtered rows
2573 :
2574 : SCCOL nClipX;
2575 : SCROW nClipY;
2576 2 : pClipDoc->GetClipArea( nClipX, nClipY, false );
2577 2 : SCROW nUndoAdd = nUndoEndRow - nDestEndRow;
2578 2 : nDestEndRow = nDestRow + nClipY;
2579 2 : nUndoEndRow = nDestEndRow + nUndoAdd;
2580 : }
2581 :
2582 3 : if (!ValidCol(nUndoEndCol) || !ValidRow(nUndoEndRow))
2583 : {
2584 0 : if (!bApi)
2585 0 : rDocShell.ErrorMessage(STR_PASTE_FULL);
2586 0 : delete pClipDoc;
2587 0 : return false;
2588 : }
2589 :
2590 : // Test auf Zellschutz
2591 :
2592 3 : ScEditableTester aTester;
2593 6 : for (nTab=nDestTab; nTab<=nDestEndTab; nTab++)
2594 3 : aTester.TestBlock( pDoc, nTab, nDestCol,nDestRow, nUndoEndCol,nUndoEndRow );
2595 3 : if (bCut)
2596 2 : for (nTab=nStartTab; nTab<=nEndTab; nTab++)
2597 1 : aTester.TestBlock( pDoc, nTab, nStartCol,nStartRow, nEndCol,nEndRow );
2598 :
2599 3 : if (!aTester.IsEditable())
2600 : {
2601 0 : if (!bApi)
2602 0 : rDocShell.ErrorMessage(aTester.GetMessageId());
2603 0 : delete pClipDoc;
2604 0 : return false;
2605 : }
2606 :
2607 : // Test auf zusammengefasste - beim Verschieben erst nach dem Loeschen
2608 :
2609 3 : if (bClipOver && !bCut)
2610 0 : if (pDoc->HasAttrib( nDestCol,nDestRow,nDestTab, nUndoEndCol,nUndoEndRow,nDestEndTab,
2611 0 : HASATTR_MERGED | HASATTR_OVERLAPPED ))
2612 : { // "Zusammenfassen nicht verschachteln !"
2613 0 : if (!bApi)
2614 0 : rDocShell.ErrorMessage(STR_MSSG_MOVEBLOCKTO_0);
2615 0 : delete pClipDoc;
2616 0 : return false;
2617 : }
2618 :
2619 : // Are there borders in the cells? (for painting)
2620 :
2621 3 : sal_uInt16 nSourceExt = 0;
2622 3 : rDocShell.UpdatePaintExt( nSourceExt, nStartCol,nStartRow,nStartTab, nEndCol,nEndRow,nEndTab );
2623 3 : sal_uInt16 nDestExt = 0;
2624 3 : rDocShell.UpdatePaintExt( nDestExt, nDestCol,nDestRow,nDestTab, nDestEndCol,nDestEndRow,nDestEndTab );
2625 :
2626 : //
2627 : // ausfuehren
2628 : //
2629 :
2630 3 : ScDocument* pUndoDoc = NULL;
2631 3 : ScDocument* pRefUndoDoc = NULL;
2632 3 : ScRefUndoData* pUndoData = NULL;
2633 3 : if (bRecord)
2634 : {
2635 2 : sal_Bool bWholeCols = ( nStartRow == 0 && nEndRow == MAXROW );
2636 2 : sal_Bool bWholeRows = ( nStartCol == 0 && nEndCol == MAXCOL );
2637 2 : sal_uInt16 nUndoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS;
2638 :
2639 2 : pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
2640 2 : pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab, bWholeCols, bWholeRows );
2641 :
2642 2 : if (bCut)
2643 : {
2644 : pDoc->CopyToDocument( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
2645 1 : nUndoFlags, false, pUndoDoc );
2646 1 : pRefUndoDoc = new ScDocument( SCDOCMODE_UNDO );
2647 1 : pRefUndoDoc->InitUndo( pDoc, 0, nTabCount-1, false, false );
2648 : }
2649 :
2650 2 : if ( nDestTab != nStartTab )
2651 0 : pUndoDoc->AddUndoTab( nDestTab, nDestEndTab, bWholeCols, bWholeRows );
2652 : pDoc->CopyToDocument( nDestCol, nDestRow, nDestTab,
2653 : nDestEndCol, nDestEndRow, nDestEndTab,
2654 2 : nUndoFlags, false, pUndoDoc );
2655 :
2656 2 : pUndoData = new ScRefUndoData( pDoc );
2657 :
2658 2 : pDoc->BeginDrawUndo();
2659 : }
2660 :
2661 3 : sal_Bool bSourceHeight = false; // Hoehen angepasst?
2662 3 : if (bCut)
2663 : {
2664 1 : ScMarkData aDelMark; // only for tables
2665 2 : for (nTab=nStartTab; nTab<=nEndTab; nTab++)
2666 : {
2667 1 : pDoc->DeleteAreaTab( nStartCol,nStartRow, nOldEndCol,nOldEndRow, nTab, IDF_ALL );
2668 1 : aDelMark.SelectTable( nTab, sal_True );
2669 : }
2670 1 : pDoc->DeleteObjectsInArea( nStartCol,nStartRow, nOldEndCol,nOldEndRow, aDelMark );
2671 :
2672 : // Test auf zusammengefasste
2673 :
2674 1 : if (bClipOver)
2675 0 : if (pDoc->HasAttrib( nDestCol,nDestRow,nDestTab,
2676 : nUndoEndCol,nUndoEndRow,nDestEndTab,
2677 0 : HASATTR_MERGED | HASATTR_OVERLAPPED ))
2678 : {
2679 0 : pDoc->CopyFromClip( rSource, aSourceMark, IDF_ALL, pRefUndoDoc, pClipDoc );
2680 0 : for (nTab=nStartTab; nTab<=nEndTab; nTab++)
2681 : {
2682 0 : SCCOL nTmpEndCol = nEndCol;
2683 0 : SCROW nTmpEndRow = nEndRow;
2684 0 : pDoc->ExtendMerge( nStartCol, nStartRow, nTmpEndCol, nTmpEndRow, nTab, sal_True );
2685 : }
2686 :
2687 : // Fehlermeldung erst nach dem Wiederherstellen des Inhalts
2688 0 : if (!bApi) // "Zusammenfassen nicht verschachteln !"
2689 0 : rDocShell.ErrorMessage(STR_MSSG_MOVEBLOCKTO_0);
2690 :
2691 0 : delete pUndoDoc;
2692 0 : delete pRefUndoDoc;
2693 0 : delete pUndoData;
2694 0 : delete pClipDoc;
2695 0 : return false;
2696 : }
2697 :
2698 1 : bSourceHeight = AdjustRowHeight( rSource, false );
2699 : }
2700 :
2701 3 : ScRange aPasteDest( nDestCol, nDestRow, nDestTab, nDestEndCol, nDestEndRow, nDestEndTab );
2702 :
2703 6 : ScMarkData aDestMark;
2704 6 : for (nTab=nDestTab; nTab<=nDestEndTab; nTab++)
2705 3 : aDestMark.SelectTable( nTab, sal_True ); // Destination selektieren
2706 3 : aDestMark.SetMarkArea( aPasteDest );
2707 :
2708 : /* Do not copy cell notes and drawing objects here. While pasting, the
2709 : function ScDocument::UpdateReference() is called which calls
2710 : ScDrawLayer::MoveCells() which may move away inserted objects to wrong
2711 : positions (e.g. if source and destination range overlaps). Cell notes
2712 : and drawing objects are pasted below after doing all adjusting. */
2713 : pDoc->CopyFromClip( aPasteDest, aDestMark, IDF_ALL & ~(IDF_NOTE | IDF_OBJECTS),
2714 3 : pRefUndoDoc, pClipDoc, sal_True, false, bIncludeFiltered );
2715 :
2716 : // skipped rows and merged cells don't mix
2717 3 : if ( !bIncludeFiltered && pClipDoc->HasClipFilteredRows() )
2718 0 : UnmergeCells( aPasteDest, false );
2719 :
2720 6 : VirtualDevice aVirtDev;
2721 : sal_Bool bDestHeight = AdjustRowHeight(
2722 : ScRange( 0,nDestRow,nDestTab, MAXCOL,nDestEndRow,nDestEndTab ),
2723 3 : false );
2724 :
2725 : /* Paste cell notes and drawing objects after adjusting formula references
2726 : and row heights. There are no cell notes or drawing objects, if the
2727 : clipdoc does not contain a drawing layer.
2728 : #i102056# Passing IDF_NOTE only would overwrite cell contents with
2729 : empty note cells, therefore the special modifier IDF_ADDNOTES is passed
2730 : here too which changes the behaviour of ScColumn::CopyFromClip() to not
2731 : touch existing cells. */
2732 3 : if ( pClipDoc->GetDrawLayer() )
2733 : pDoc->CopyFromClip( aPasteDest, aDestMark, IDF_NOTE | IDF_ADDNOTES | IDF_OBJECTS,
2734 0 : pRefUndoDoc, pClipDoc, sal_True, false, bIncludeFiltered );
2735 :
2736 3 : if (bRecord)
2737 : {
2738 2 : if (pRefUndoDoc)
2739 : {
2740 : // alle Tabellen anlegen, damit Formeln kopiert werden koennen:
2741 1 : pUndoDoc->AddUndoTab( 0, nTabCount-1, false, false );
2742 :
2743 1 : pRefUndoDoc->DeleteArea( nDestCol, nDestRow, nDestEndCol, nDestEndRow, aSourceMark, IDF_ALL );
2744 : // kopieren mit bColRowFlags=sal_False (#54194#)
2745 : pRefUndoDoc->CopyToDocument( 0, 0, 0, MAXCOL, MAXROW, MAXTAB,
2746 1 : IDF_FORMULA, false, pUndoDoc, NULL, false );
2747 1 : delete pRefUndoDoc;
2748 : }
2749 :
2750 2 : rDocShell.GetUndoManager()->AddUndoAction(
2751 : new ScUndoDragDrop( &rDocShell, ScRange(
2752 : nStartCol, nStartRow, nStartTab,
2753 : nOldEndCol, nOldEndRow, nEndTab ),
2754 : ScAddress( nDestCol, nDestRow, nDestTab ),
2755 2 : bCut, pUndoDoc, pUndoData, bScenariosAdded ) );
2756 : }
2757 :
2758 3 : SCCOL nDestPaintEndCol = nDestEndCol;
2759 3 : SCROW nDestPaintEndRow = nDestEndRow;
2760 6 : for (nTab=nDestTab; nTab<=nDestEndTab; nTab++)
2761 : {
2762 3 : SCCOL nTmpEndCol = nDestEndCol;
2763 3 : SCROW nTmpEndRow = nDestEndRow;
2764 3 : pDoc->ExtendMerge( nDestCol, nDestRow, nTmpEndCol, nTmpEndRow, nTab, sal_True );
2765 3 : if (nTmpEndCol > nDestPaintEndCol) nDestPaintEndCol = nTmpEndCol;
2766 3 : if (nTmpEndRow > nDestPaintEndRow) nDestPaintEndRow = nTmpEndRow;
2767 : }
2768 :
2769 3 : if (bCut)
2770 2 : for (nTab=nStartTab; nTab<=nEndTab; nTab++)
2771 1 : pDoc->RefreshAutoFilter( nStartCol, nStartRow, nEndCol, nEndRow, nTab );
2772 :
2773 3 : if (bPaint)
2774 : {
2775 : // Zielbereich:
2776 :
2777 2 : SCCOL nPaintStartX = nDestCol;
2778 2 : SCROW nPaintStartY = nDestRow;
2779 2 : SCCOL nPaintEndX = nDestPaintEndCol;
2780 2 : SCROW nPaintEndY = nDestPaintEndRow;
2781 2 : sal_uInt16 nFlags = PAINT_GRID;
2782 :
2783 2 : if ( nStartRow==0 && nEndRow==MAXROW ) // Breiten mitkopiert?
2784 : {
2785 0 : nPaintEndX = MAXCOL;
2786 0 : nPaintStartY = 0;
2787 0 : nPaintEndY = MAXROW;
2788 0 : nFlags |= PAINT_TOP;
2789 : }
2790 2 : if ( bDestHeight || ( nStartCol == 0 && nEndCol == MAXCOL ) )
2791 : {
2792 0 : nPaintEndY = MAXROW;
2793 0 : nPaintStartX = 0;
2794 0 : nPaintEndX = MAXCOL;
2795 0 : nFlags |= PAINT_LEFT;
2796 : }
2797 2 : if ( bScenariosAdded )
2798 : {
2799 0 : nPaintStartX = 0;
2800 0 : nPaintStartY = 0;
2801 0 : nPaintEndX = MAXCOL;
2802 0 : nPaintEndY = MAXROW;
2803 : }
2804 :
2805 : rDocShell.PostPaint( nPaintStartX,nPaintStartY,nDestTab,
2806 2 : nPaintEndX,nPaintEndY,nDestEndTab, nFlags, nSourceExt | nDestExt );
2807 :
2808 2 : if ( bCut )
2809 : {
2810 : // Quellbereich:
2811 :
2812 1 : nPaintStartX = nStartCol;
2813 1 : nPaintStartY = nStartRow;
2814 1 : nPaintEndX = nEndCol;
2815 1 : nPaintEndY = nEndRow;
2816 1 : nFlags = PAINT_GRID;
2817 :
2818 1 : if ( bSourceHeight )
2819 : {
2820 0 : nPaintEndY = MAXROW;
2821 0 : nPaintStartX = 0;
2822 0 : nPaintEndX = MAXCOL;
2823 0 : nFlags |= PAINT_LEFT;
2824 : }
2825 1 : if ( bScenariosAdded )
2826 : {
2827 0 : nPaintStartX = 0;
2828 0 : nPaintStartY = 0;
2829 0 : nPaintEndX = MAXCOL;
2830 0 : nPaintEndY = MAXROW;
2831 : }
2832 :
2833 : rDocShell.PostPaint( nPaintStartX,nPaintStartY,nStartTab,
2834 1 : nPaintEndX,nPaintEndY,nEndTab, nFlags, nSourceExt );
2835 : }
2836 : }
2837 :
2838 3 : aModificator.SetDocumentModified();
2839 :
2840 3 : SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
2841 :
2842 3 : delete pClipDoc;
2843 6 : return sal_True;
2844 : }
2845 :
2846 : //------------------------------------------------------------------------
2847 0 : uno::Reference< uno::XInterface > GetDocModuleObject( SfxObjectShell& rDocSh, String& sCodeName )
2848 : {
2849 0 : uno::Reference< lang::XMultiServiceFactory> xSF(rDocSh.GetModel(), uno::UNO_QUERY);
2850 0 : uno::Reference< container::XNameAccess > xVBACodeNamedObjectAccess;
2851 0 : uno::Reference< uno::XInterface > xDocModuleApiObject;
2852 0 : if ( xSF.is() )
2853 : {
2854 0 : xVBACodeNamedObjectAccess.set( xSF->createInstance("ooo.vba.VBAObjectModuleObjectProvider"), uno::UNO_QUERY );
2855 0 : xDocModuleApiObject.set( xVBACodeNamedObjectAccess->getByName( sCodeName ), uno::UNO_QUERY );
2856 : }
2857 0 : return xDocModuleApiObject;
2858 :
2859 : }
2860 :
2861 0 : static script::ModuleInfo lcl_InitModuleInfo( SfxObjectShell& rDocSh, String& sModule )
2862 : {
2863 0 : script::ModuleInfo sModuleInfo;
2864 0 : sModuleInfo.ModuleType = script::ModuleType::DOCUMENT;
2865 0 : sModuleInfo.ModuleObject = GetDocModuleObject( rDocSh, sModule );
2866 0 : return sModuleInfo;
2867 : }
2868 :
2869 0 : void VBA_InsertModule( ScDocument& rDoc, SCTAB nTab, const OUString& sModuleName, const OUString& sSource )
2870 : {
2871 0 : SfxObjectShell& rDocSh = *rDoc.GetDocumentShell();
2872 0 : uno::Reference< script::XLibraryContainer > xLibContainer = rDocSh.GetBasicContainer();
2873 : OSL_ENSURE( xLibContainer.is(), "No BasicContainer!" );
2874 :
2875 0 : uno::Reference< container::XNameContainer > xLib;
2876 0 : if( xLibContainer.is() )
2877 : {
2878 0 : String aLibName( "Standard" );
2879 0 : if ( rDocSh.GetBasicManager() && !rDocSh.GetBasicManager()->GetName().isEmpty() )
2880 : {
2881 0 : aLibName = rDocSh.GetBasicManager()->GetName();
2882 : }
2883 0 : uno::Any aLibAny = xLibContainer->getByName( aLibName );
2884 0 : aLibAny >>= xLib;
2885 : }
2886 0 : if( xLib.is() )
2887 : {
2888 : // if the Module with codename exists then find a new name
2889 0 : sal_Int32 nNum = 0;
2890 0 : String genModuleName;
2891 0 : if ( !sModuleName.isEmpty() )
2892 0 : genModuleName = sModuleName;
2893 : else
2894 : {
2895 0 : genModuleName = OUString( "Sheet1" );
2896 0 : nNum = 1;
2897 : }
2898 0 : while( xLib->hasByName( genModuleName ) )
2899 0 : genModuleName = OUString( "Sheet") + OUString::valueOf( ++nNum );
2900 :
2901 0 : uno::Any aSourceAny;
2902 0 : OUString sTmpSource = sSource;
2903 0 : if ( sTmpSource.isEmpty() )
2904 0 : sTmpSource = OUString( "Rem Attribute VBA_ModuleType=VBADocumentModule\nOption VBASupport 1\n" );
2905 0 : aSourceAny <<= sTmpSource;
2906 0 : uno::Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY );
2907 0 : if ( xVBAModuleInfo.is() )
2908 : {
2909 0 : rDoc.SetCodeName( nTab, genModuleName );
2910 0 : script::ModuleInfo sModuleInfo = lcl_InitModuleInfo( rDocSh, genModuleName );
2911 0 : xVBAModuleInfo->insertModuleInfo( genModuleName, sModuleInfo );
2912 0 : xLib->insertByName( genModuleName, aSourceAny );
2913 0 : }
2914 :
2915 0 : }
2916 0 : }
2917 :
2918 0 : void VBA_DeleteModule( ScDocShell& rDocSh, const OUString& sModuleName )
2919 : {
2920 0 : uno::Reference< script::XLibraryContainer > xLibContainer = rDocSh.GetBasicContainer();
2921 : OSL_ENSURE( xLibContainer.is(), "No BasicContainer!" );
2922 :
2923 0 : uno::Reference< container::XNameContainer > xLib;
2924 0 : if( xLibContainer.is() )
2925 : {
2926 0 : String aLibName( "Standard" );
2927 0 : if ( rDocSh.GetBasicManager() && !rDocSh.GetBasicManager()->GetName().isEmpty() )
2928 : {
2929 0 : aLibName = rDocSh.GetBasicManager()->GetName();
2930 : }
2931 0 : uno::Any aLibAny = xLibContainer->getByName( aLibName );
2932 0 : aLibAny >>= xLib;
2933 : }
2934 0 : if( xLib.is() )
2935 : {
2936 0 : uno::Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY );
2937 0 : if( xLib->hasByName( sModuleName ) )
2938 0 : xLib->removeByName( sModuleName );
2939 0 : if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo(sModuleName) )
2940 0 : xVBAModuleInfo->removeModuleInfo( sModuleName );
2941 :
2942 0 : }
2943 0 : }
2944 :
2945 :
2946 58 : sal_Bool ScDocFunc::InsertTable( SCTAB nTab, const String& rName, sal_Bool bRecord, sal_Bool bApi )
2947 : {
2948 58 : sal_Bool bSuccess = false;
2949 58 : WaitObject aWait( rDocShell.GetActiveDialogParent() );
2950 :
2951 116 : ScDocShellModificator aModificator( rDocShell );
2952 :
2953 58 : ScDocument* pDoc = rDocShell.GetDocument();
2954 :
2955 :
2956 : // Strange loop, also basic is loaded too early ( InsertTable )
2957 : // is called via the xml import for sheets in described in ODF
2958 58 : sal_Bool bInsertDocModule = false;
2959 :
2960 58 : if( !rDocShell.GetDocument()->IsImportingXML() )
2961 : {
2962 58 : bInsertDocModule = pDoc ? pDoc->IsInVBAMode() : false;
2963 : }
2964 58 : if ( bInsertDocModule || ( bRecord && !pDoc->IsUndoEnabled() ) )
2965 22 : bRecord = false;
2966 :
2967 58 : if (bRecord)
2968 36 : pDoc->BeginDrawUndo(); // InsertTab erzeugt ein SdrUndoNewPage
2969 :
2970 58 : SCTAB nTabCount = pDoc->GetTableCount();
2971 58 : sal_Bool bAppend = ( nTab >= nTabCount );
2972 58 : if ( bAppend )
2973 30 : nTab = nTabCount; // wichtig fuer Undo
2974 :
2975 58 : if (pDoc->InsertTab( nTab, rName ))
2976 : {
2977 58 : if (bRecord)
2978 36 : rDocShell.GetUndoManager()->AddUndoAction(
2979 36 : new ScUndoInsertTab( &rDocShell, nTab, bAppend, rName));
2980 : // Views updaten:
2981 : // Only insert vba modules if vba mode ( and not currently importing XML )
2982 58 : if( bInsertDocModule )
2983 : {
2984 0 : OUString sSource, sCodeName;
2985 0 : VBA_InsertModule( *pDoc, nTab, sCodeName, sSource );
2986 : }
2987 58 : rDocShell.Broadcast( ScTablesHint( SC_TAB_INSERTED, nTab ) );
2988 :
2989 58 : rDocShell.PostPaintExtras();
2990 58 : aModificator.SetDocumentModified();
2991 58 : SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2992 58 : bSuccess = sal_True;
2993 : }
2994 0 : else if (!bApi)
2995 0 : rDocShell.ErrorMessage(STR_TABINSERT_ERROR);
2996 :
2997 116 : return bSuccess;
2998 : }
2999 :
3000 18 : sal_Bool ScDocFunc::DeleteTable( SCTAB nTab, sal_Bool bRecord, sal_Bool /* bApi */ )
3001 : {
3002 18 : WaitObject aWait( rDocShell.GetActiveDialogParent() );
3003 :
3004 36 : ScDocShellModificator aModificator( rDocShell );
3005 :
3006 18 : sal_Bool bSuccess = false;
3007 18 : ScDocument* pDoc = rDocShell.GetDocument();
3008 18 : sal_Bool bVbaEnabled = pDoc ? pDoc->IsInVBAMode() : false;
3009 18 : if (bRecord && !pDoc->IsUndoEnabled())
3010 0 : bRecord = false;
3011 18 : if ( bVbaEnabled )
3012 0 : bRecord = false;
3013 18 : sal_Bool bWasLinked = pDoc->IsLinked(nTab);
3014 18 : ScDocument* pUndoDoc = NULL;
3015 18 : ScRefUndoData* pUndoData = NULL;
3016 18 : if (bRecord)
3017 : {
3018 18 : pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
3019 18 : SCTAB nCount = pDoc->GetTableCount();
3020 :
3021 18 : pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True ); // nur nTab mit Flags
3022 18 : pUndoDoc->AddUndoTab( 0, nCount-1 ); // alle Tabs fuer Referenzen
3023 :
3024 18 : pDoc->CopyToDocument(0,0,nTab, MAXCOL,MAXROW,nTab, IDF_ALL,false, pUndoDoc );
3025 18 : OUString aOldName;
3026 18 : pDoc->GetName( nTab, aOldName );
3027 18 : pUndoDoc->RenameTab( nTab, aOldName, false );
3028 18 : if (bWasLinked)
3029 0 : pUndoDoc->SetLink( nTab, pDoc->GetLinkMode(nTab), pDoc->GetLinkDoc(nTab),
3030 : pDoc->GetLinkFlt(nTab), pDoc->GetLinkOpt(nTab),
3031 : pDoc->GetLinkTab(nTab),
3032 0 : pDoc->GetLinkRefreshDelay(nTab) );
3033 :
3034 18 : if ( pDoc->IsScenario(nTab) )
3035 : {
3036 0 : pUndoDoc->SetScenario( nTab, sal_True );
3037 0 : OUString aComment;
3038 0 : Color aColor;
3039 : sal_uInt16 nScenFlags;
3040 0 : pDoc->GetScenarioData( nTab, aComment, aColor, nScenFlags );
3041 0 : pUndoDoc->SetScenarioData( nTab, aComment, aColor, nScenFlags );
3042 0 : sal_Bool bActive = pDoc->IsActiveScenario( nTab );
3043 0 : pUndoDoc->SetActiveScenario( nTab, bActive );
3044 : }
3045 18 : pUndoDoc->SetVisible( nTab, pDoc->IsVisible( nTab ) );
3046 18 : pUndoDoc->SetTabBgColor( nTab, pDoc->GetTabBgColor(nTab) );
3047 18 : pUndoDoc->SetSheetEvents( nTab, pDoc->GetSheetEvents( nTab ) );
3048 :
3049 : // Drawing-Layer muss sein Undo selbst in der Hand behalten !!!
3050 18 : pDoc->BeginDrawUndo(); // DeleteTab erzeugt ein SdrUndoDelPage
3051 :
3052 18 : pUndoData = new ScRefUndoData( pDoc );
3053 : }
3054 :
3055 18 : if (pDoc->DeleteTab( nTab, pUndoDoc ))
3056 : {
3057 18 : if (bRecord)
3058 : {
3059 18 : vector<SCTAB> theTabs;
3060 18 : theTabs.push_back(nTab);
3061 18 : rDocShell.GetUndoManager()->AddUndoAction(
3062 18 : new ScUndoDeleteTab( &rDocShell, theTabs, pUndoDoc, pUndoData ));
3063 : }
3064 : // Views updaten:
3065 18 : if( bVbaEnabled )
3066 : {
3067 0 : OUString sCodeName;
3068 0 : if( pDoc->GetCodeName( nTab, sCodeName ) )
3069 : {
3070 0 : VBA_DeleteModule( rDocShell, sCodeName );
3071 0 : }
3072 : }
3073 18 : rDocShell.Broadcast( ScTablesHint( SC_TAB_DELETED, nTab ) );
3074 :
3075 18 : if (bWasLinked)
3076 : {
3077 0 : rDocShell.UpdateLinks(); // Link-Manager updaten
3078 0 : SfxBindings* pBindings = rDocShell.GetViewBindings();
3079 0 : if (pBindings)
3080 0 : pBindings->Invalidate(SID_LINKS);
3081 : }
3082 :
3083 18 : rDocShell.PostPaintExtras();
3084 18 : aModificator.SetDocumentModified();
3085 :
3086 18 : SfxApplication* pSfxApp = SFX_APP(); // Navigator
3087 18 : pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
3088 18 : pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
3089 18 : pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
3090 :
3091 18 : bSuccess = sal_True;
3092 : }
3093 : else
3094 : {
3095 0 : delete pUndoDoc;
3096 0 : delete pUndoData;
3097 : }
3098 36 : return bSuccess;
3099 : }
3100 :
3101 234 : sal_Bool ScDocFunc::SetTableVisible( SCTAB nTab, bool bVisible, sal_Bool bApi )
3102 : {
3103 234 : ScDocument* pDoc = rDocShell.GetDocument();
3104 234 : bool bUndo(pDoc->IsUndoEnabled());
3105 234 : if ( pDoc->IsVisible( nTab ) == bVisible )
3106 232 : return sal_True; // nichts zu tun - ok
3107 :
3108 2 : if ( !pDoc->IsDocEditable() )
3109 : {
3110 0 : if (!bApi)
3111 0 : rDocShell.ErrorMessage(STR_PROTECTIONERR);
3112 0 : return false;
3113 : }
3114 :
3115 2 : ScDocShellModificator aModificator( rDocShell );
3116 :
3117 2 : if ( !bVisible && !pDoc->IsImportingXML() ) // #i57869# allow hiding in any order for loading
3118 : {
3119 : // nicht alle Tabellen ausblenden
3120 :
3121 1 : sal_uInt16 nVisCount = 0;
3122 1 : SCTAB nCount = pDoc->GetTableCount();
3123 3 : for (SCTAB i=0; i<nCount && nVisCount<2; i++)
3124 2 : if (pDoc->IsVisible(i))
3125 2 : ++nVisCount;
3126 :
3127 1 : if (nVisCount <= 1)
3128 : {
3129 0 : if (!bApi)
3130 0 : rDocShell.ErrorMessage(STR_PROTECTIONERR); //! eigene Meldung?
3131 0 : return false;
3132 : }
3133 : }
3134 :
3135 2 : pDoc->SetVisible( nTab, bVisible );
3136 2 : if (bUndo)
3137 : {
3138 2 : std::vector<SCTAB> undoTabs;
3139 2 : undoTabs.push_back(nTab);
3140 2 : rDocShell.GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( &rDocShell, undoTabs, bVisible ) );
3141 : }
3142 :
3143 : // Views updaten:
3144 2 : if (!bVisible)
3145 1 : rDocShell.Broadcast( ScTablesHint( SC_TAB_HIDDEN, nTab ) );
3146 :
3147 2 : SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
3148 2 : rDocShell.PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
3149 2 : aModificator.SetDocumentModified();
3150 :
3151 2 : return sal_True;
3152 : }
3153 :
3154 157 : sal_Bool ScDocFunc::SetLayoutRTL( SCTAB nTab, bool bRTL, sal_Bool /* bApi */ )
3155 : {
3156 157 : ScDocument* pDoc = rDocShell.GetDocument();
3157 157 : bool bUndo(pDoc->IsUndoEnabled());
3158 157 : if ( pDoc->IsLayoutRTL( nTab ) == bRTL )
3159 153 : return sal_True; // nothing to do - ok
3160 :
3161 : //! protection (sheet or document?)
3162 :
3163 4 : ScDocShellModificator aModificator( rDocShell );
3164 :
3165 4 : pDoc->SetLayoutRTL( nTab, bRTL );
3166 :
3167 4 : if (bUndo)
3168 : {
3169 4 : rDocShell.GetUndoManager()->AddUndoAction( new ScUndoLayoutRTL( &rDocShell, nTab, bRTL ) );
3170 : }
3171 :
3172 4 : rDocShell.PostPaint( 0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_ALL );
3173 4 : aModificator.SetDocumentModified();
3174 :
3175 4 : SfxBindings* pBindings = rDocShell.GetViewBindings();
3176 4 : if (pBindings)
3177 : {
3178 4 : pBindings->Invalidate( FID_TAB_RTL );
3179 4 : pBindings->Invalidate( SID_ATTR_SIZE );
3180 : }
3181 :
3182 4 : return sal_True;
3183 : }
3184 :
3185 6 : sal_Bool ScDocFunc::RenameTable( SCTAB nTab, const String& rName, sal_Bool bRecord, sal_Bool bApi )
3186 : {
3187 6 : ScDocument* pDoc = rDocShell.GetDocument();
3188 6 : if (bRecord && !pDoc->IsUndoEnabled())
3189 1 : bRecord = false;
3190 6 : if ( !pDoc->IsDocEditable() )
3191 : {
3192 0 : if (!bApi)
3193 0 : rDocShell.ErrorMessage(STR_PROTECTIONERR);
3194 0 : return false;
3195 : }
3196 :
3197 6 : ScDocShellModificator aModificator( rDocShell );
3198 :
3199 6 : sal_Bool bSuccess = false;
3200 12 : OUString sOldName;
3201 6 : pDoc->GetName(nTab, sOldName);
3202 6 : if (pDoc->RenameTab( nTab, rName ))
3203 : {
3204 5 : if (bRecord)
3205 : {
3206 2 : rDocShell.GetUndoManager()->AddUndoAction(
3207 2 : new ScUndoRenameTab( &rDocShell, nTab, sOldName, rName));
3208 : }
3209 5 : rDocShell.PostPaintExtras();
3210 5 : aModificator.SetDocumentModified();
3211 5 : SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
3212 :
3213 5 : bSuccess = sal_True;
3214 : }
3215 12 : return bSuccess;
3216 : }
3217 :
3218 2 : bool ScDocFunc::SetTabBgColor( SCTAB nTab, const Color& rColor, bool bRecord, bool bApi )
3219 : {
3220 :
3221 2 : ScDocument* pDoc = rDocShell.GetDocument();
3222 2 : if (bRecord && !pDoc->IsUndoEnabled())
3223 0 : bRecord = false;
3224 2 : if ( !pDoc->IsDocEditable() || pDoc->IsTabProtected(nTab) )
3225 : {
3226 0 : if (!bApi)
3227 0 : rDocShell.ErrorMessage(STR_PROTECTIONERR); //TODO Check to see what this string is...
3228 0 : return false;
3229 : }
3230 :
3231 2 : Color aOldTabBgColor;
3232 2 : aOldTabBgColor = pDoc->GetTabBgColor(nTab);
3233 :
3234 2 : bool bSuccess = false;
3235 2 : pDoc->SetTabBgColor(nTab, rColor);
3236 2 : if ( pDoc->GetTabBgColor(nTab) == rColor)
3237 2 : bSuccess = true;
3238 2 : if (bSuccess)
3239 : {
3240 2 : if (bRecord)
3241 : {
3242 0 : rDocShell.GetUndoManager()->AddUndoAction(
3243 0 : new ScUndoTabColor( &rDocShell, nTab, aOldTabBgColor, rColor));
3244 : }
3245 2 : rDocShell.PostPaintExtras();
3246 2 : ScDocShellModificator aModificator( rDocShell );
3247 2 : aModificator.SetDocumentModified();
3248 2 : SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
3249 :
3250 2 : bSuccess = true;
3251 : }
3252 2 : return bSuccess;
3253 : }
3254 :
3255 0 : bool ScDocFunc::SetTabBgColor(
3256 : ScUndoTabColorInfo::List& rUndoTabColorList, bool bRecord, bool bApi )
3257 : {
3258 0 : ScDocument* pDoc = rDocShell.GetDocument();
3259 0 : if (bRecord && !pDoc->IsUndoEnabled())
3260 0 : bRecord = false;
3261 :
3262 0 : if ( !pDoc->IsDocEditable() )
3263 : {
3264 0 : if (!bApi)
3265 0 : rDocShell.ErrorMessage(STR_PROTECTIONERR); //TODO Get a better String Error...
3266 0 : return false;
3267 : }
3268 :
3269 : sal_uInt16 nTab;
3270 0 : Color aNewTabBgColor;
3271 0 : bool bSuccess = true;
3272 0 : size_t nTabProtectCount = 0;
3273 0 : size_t nTabListCount = rUndoTabColorList.size();
3274 0 : for ( size_t i = 0; i < nTabListCount; ++i )
3275 : {
3276 0 : ScUndoTabColorInfo& rInfo = rUndoTabColorList[i];
3277 0 : nTab = rInfo.mnTabId;
3278 0 : if ( !pDoc->IsTabProtected(nTab) )
3279 : {
3280 0 : aNewTabBgColor = rInfo.maNewTabBgColor;
3281 0 : rInfo.maOldTabBgColor = pDoc->GetTabBgColor(nTab);
3282 0 : pDoc->SetTabBgColor(nTab, aNewTabBgColor);
3283 0 : if ( pDoc->GetTabBgColor(nTab) != aNewTabBgColor)
3284 : {
3285 0 : bSuccess = false;
3286 0 : break;
3287 : }
3288 : }
3289 : else
3290 : {
3291 0 : nTabProtectCount++;
3292 : }
3293 : }
3294 :
3295 0 : if ( nTabProtectCount == nTabListCount )
3296 : {
3297 0 : if (!bApi)
3298 0 : rDocShell.ErrorMessage(STR_PROTECTIONERR); //TODO Get a better String Error...
3299 0 : return false;
3300 : }
3301 :
3302 0 : if (bSuccess)
3303 : {
3304 0 : if (bRecord)
3305 : {
3306 0 : rDocShell.GetUndoManager()->AddUndoAction(
3307 0 : new ScUndoTabColor( &rDocShell, rUndoTabColorList));
3308 : }
3309 0 : rDocShell.PostPaintExtras();
3310 0 : ScDocShellModificator aModificator( rDocShell );
3311 0 : aModificator.SetDocumentModified();
3312 : }
3313 0 : return bSuccess;
3314 : }
3315 :
3316 : //------------------------------------------------------------------------
3317 :
3318 : //! SetWidthOrHeight - noch doppelt zu ViewFunc !!!!!!
3319 : //! Probleme:
3320 : //! - Optimale Hoehe fuer Edit-Zellen ist unterschiedlich zwischen Drucker und Bildschirm
3321 : //! - Optimale Breite braucht Selektion, um evtl. nur selektierte Zellen zu beruecksichtigen
3322 :
3323 8 : static sal_uInt16 lcl_GetOptimalColWidth( ScDocShell& rDocShell, SCCOL nCol, SCTAB nTab, sal_Bool bFormula )
3324 : {
3325 8 : ScSizeDeviceProvider aProv(&rDocShell);
3326 8 : OutputDevice* pDev = aProv.GetDevice(); // has pixel MapMode
3327 8 : double nPPTX = aProv.GetPPTX();
3328 8 : double nPPTY = aProv.GetPPTY();
3329 :
3330 8 : ScDocument* pDoc = rDocShell.GetDocument();
3331 8 : Fraction aOne(1,1);
3332 : sal_uInt16 nTwips = pDoc->GetOptimalColWidth( nCol, nTab, pDev, nPPTX, nPPTY, aOne, aOne,
3333 8 : bFormula, NULL );
3334 :
3335 8 : return nTwips;
3336 : }
3337 :
3338 567 : sal_Bool ScDocFunc::SetWidthOrHeight( sal_Bool bWidth, SCCOLROW nRangeCnt, SCCOLROW* pRanges, SCTAB nTab,
3339 : ScSizeMode eMode, sal_uInt16 nSizeTwips,
3340 : sal_Bool bRecord, sal_Bool bApi )
3341 : {
3342 567 : ScDocShellModificator aModificator( rDocShell );
3343 :
3344 567 : if (!nRangeCnt)
3345 0 : return sal_True;
3346 :
3347 567 : ScDocument* pDoc = rDocShell.GetDocument();
3348 567 : if ( bRecord && !pDoc->IsUndoEnabled() )
3349 535 : bRecord = false;
3350 :
3351 : // import into read-only document is possible
3352 567 : if ( !pDoc->IsChangeReadOnlyEnabled() && !rDocShell.IsEditable() )
3353 : {
3354 0 : if (!bApi)
3355 0 : rDocShell.ErrorMessage(STR_PROTECTIONERR); //! eigene Meldung?
3356 0 : return false;
3357 : }
3358 :
3359 567 : sal_Bool bSuccess = false;
3360 567 : SCCOLROW nStart = pRanges[0];
3361 567 : SCCOLROW nEnd = pRanges[2*nRangeCnt-1];
3362 :
3363 567 : sal_Bool bFormula = false;
3364 : if ( eMode == SC_SIZE_OPTIMAL )
3365 : {
3366 : //! Option "Formeln anzeigen" - woher nehmen?
3367 : }
3368 :
3369 567 : ScDocument* pUndoDoc = NULL;
3370 567 : ScOutlineTable* pUndoTab = NULL;
3371 567 : SCCOLROW* pUndoRanges = NULL;
3372 :
3373 567 : if ( bRecord )
3374 : {
3375 32 : pDoc->BeginDrawUndo(); // Drawing Updates
3376 :
3377 32 : pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
3378 32 : if (bWidth)
3379 : {
3380 16 : pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, false );
3381 16 : pDoc->CopyToDocument( static_cast<SCCOL>(nStart), 0, nTab, static_cast<SCCOL>(nEnd), MAXROW, nTab, IDF_NONE, false, pUndoDoc );
3382 : }
3383 : else
3384 : {
3385 16 : pUndoDoc->InitUndo( pDoc, nTab, nTab, false, sal_True );
3386 16 : pDoc->CopyToDocument( 0, static_cast<SCROW>(nStart), nTab, MAXCOL, static_cast<SCROW>(nEnd), nTab, IDF_NONE, false, pUndoDoc );
3387 : }
3388 :
3389 32 : pUndoRanges = new SCCOLROW[ 2*nRangeCnt ];
3390 32 : memcpy( pUndoRanges, pRanges, 2*nRangeCnt*sizeof(SCCOLROW) );
3391 :
3392 32 : ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
3393 32 : if (pTable)
3394 27 : pUndoTab = new ScOutlineTable( *pTable );
3395 : }
3396 :
3397 567 : sal_Bool bShow = nSizeTwips > 0 || eMode != SC_SIZE_DIRECT;
3398 567 : sal_Bool bOutline = false;
3399 :
3400 567 : pDoc->InitializeNoteCaptions(nTab);
3401 1134 : for (SCCOLROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
3402 : {
3403 567 : SCCOLROW nStartNo = *(pRanges++);
3404 567 : SCCOLROW nEndNo = *(pRanges++);
3405 :
3406 567 : if ( !bWidth ) // Hoehen immer blockweise
3407 : {
3408 33 : if ( eMode==SC_SIZE_OPTIMAL || eMode==SC_SIZE_VISOPT )
3409 : {
3410 2 : sal_Bool bAll = ( eMode==SC_SIZE_OPTIMAL );
3411 2 : if (!bAll)
3412 : {
3413 : // fuer alle eingeblendeten CR_MANUALSIZE loeschen,
3414 : // dann SetOptimalHeight mit bShrink = FALSE
3415 0 : for (SCROW nRow=nStartNo; nRow<=nEndNo; nRow++)
3416 : {
3417 0 : sal_uInt8 nOld = pDoc->GetRowFlags(nRow,nTab);
3418 0 : SCROW nLastRow = -1;
3419 0 : bool bHidden = pDoc->RowHidden(nRow, nTab, NULL, &nLastRow);
3420 0 : if ( !bHidden && ( nOld & CR_MANUALSIZE ) )
3421 0 : pDoc->SetRowFlags( nRow, nTab, nOld & ~CR_MANUALSIZE );
3422 : }
3423 : }
3424 :
3425 2 : ScSizeDeviceProvider aProv( &rDocShell );
3426 2 : Fraction aOne(1,1);
3427 : pDoc->SetOptimalHeight( nStartNo, nEndNo, nTab, 0, aProv.GetDevice(),
3428 2 : aProv.GetPPTX(), aProv.GetPPTY(), aOne, aOne, bAll );
3429 :
3430 2 : if (bAll)
3431 2 : pDoc->ShowRows( nStartNo, nEndNo, nTab, sal_True );
3432 :
3433 : // Manual-Flag wird bei bAll=sal_True schon in SetOptimalHeight gesetzt
3434 : // (an bei Extra-Height, sonst aus).
3435 : }
3436 31 : else if ( eMode==SC_SIZE_DIRECT || eMode==SC_SIZE_ORIGINAL )
3437 : {
3438 26 : if (nSizeTwips)
3439 : {
3440 4 : pDoc->SetRowHeightRange( nStartNo, nEndNo, nTab, nSizeTwips );
3441 4 : pDoc->SetManualHeight( nStartNo, nEndNo, nTab, sal_True ); // height was set manually
3442 : }
3443 52 : if ( eMode != SC_SIZE_ORIGINAL )
3444 22 : pDoc->ShowRows( nStartNo, nEndNo, nTab, nSizeTwips != 0 );
3445 : }
3446 5 : else if ( eMode==SC_SIZE_SHOW )
3447 : {
3448 5 : pDoc->ShowRows( nStartNo, nEndNo, nTab, sal_True );
3449 : }
3450 : }
3451 : else // Spaltenbreiten
3452 : {
3453 13562 : for (SCCOL nCol=static_cast<SCCOL>(nStartNo); nCol<=static_cast<SCCOL>(nEndNo); nCol++)
3454 : {
3455 13028 : if ( eMode != SC_SIZE_VISOPT || !pDoc->ColHidden(nCol, nTab) )
3456 : {
3457 13028 : sal_uInt16 nThisSize = nSizeTwips;
3458 :
3459 13028 : if ( eMode==SC_SIZE_OPTIMAL || eMode==SC_SIZE_VISOPT )
3460 : nThisSize = nSizeTwips +
3461 8 : lcl_GetOptimalColWidth( rDocShell, nCol, nTab, bFormula );
3462 13028 : if ( nThisSize )
3463 6517 : pDoc->SetColWidth( nCol, nTab, nThisSize );
3464 :
3465 13028 : if ( eMode != SC_SIZE_ORIGINAL )
3466 6529 : pDoc->ShowCol( nCol, nTab, bShow );
3467 : }
3468 : }
3469 : }
3470 :
3471 : // adjust outlines
3472 :
3473 567 : if ( eMode != SC_SIZE_ORIGINAL )
3474 : {
3475 304 : if (bWidth)
3476 550 : bOutline = bOutline || pDoc->UpdateOutlineCol(
3477 : static_cast<SCCOL>(nStartNo),
3478 550 : static_cast<SCCOL>(nEndNo), nTab, bShow );
3479 : else
3480 58 : bOutline = bOutline || pDoc->UpdateOutlineRow(
3481 : static_cast<SCROW>(nStartNo),
3482 58 : static_cast<SCROW>(nEndNo), nTab, bShow );
3483 : }
3484 : }
3485 567 : pDoc->SetDrawPageSize(nTab);
3486 :
3487 567 : if (!bOutline)
3488 567 : DELETEZ(pUndoTab);
3489 :
3490 567 : if (bRecord)
3491 : {
3492 32 : ScMarkData aMark;
3493 32 : aMark.SelectOneTable( nTab );
3494 32 : rDocShell.GetUndoManager()->AddUndoAction(
3495 : new ScUndoWidthOrHeight( &rDocShell, aMark,
3496 : nStart, nTab, nEnd, nTab,
3497 : pUndoDoc, nRangeCnt, pUndoRanges,
3498 32 : pUndoTab, eMode, nSizeTwips, bWidth ) );
3499 : }
3500 :
3501 567 : pDoc->UpdatePageBreaks( nTab );
3502 :
3503 567 : rDocShell.PostPaint(0,0,nTab,MAXCOL,MAXROW,nTab,PAINT_ALL);
3504 567 : aModificator.SetDocumentModified();
3505 :
3506 567 : return bSuccess;
3507 : }
3508 :
3509 :
3510 2 : sal_Bool ScDocFunc::InsertPageBreak( sal_Bool bColumn, const ScAddress& rPos,
3511 : sal_Bool bRecord, sal_Bool bSetModified, sal_Bool /* bApi */ )
3512 : {
3513 2 : ScDocShellModificator aModificator( rDocShell );
3514 :
3515 2 : ScDocument* pDoc = rDocShell.GetDocument();
3516 2 : if (bRecord && !pDoc->IsUndoEnabled())
3517 0 : bRecord = false;
3518 2 : SCTAB nTab = rPos.Tab();
3519 2 : SfxBindings* pBindings = rDocShell.GetViewBindings();
3520 :
3521 1 : SCCOLROW nPos = bColumn ? static_cast<SCCOLROW>(rPos.Col()) :
3522 3 : static_cast<SCCOLROW>(rPos.Row());
3523 2 : if (nPos == 0)
3524 0 : return false; // erste Spalte / Zeile
3525 :
3526 : ScBreakType nBreak = bColumn ?
3527 1 : pDoc->HasColBreak(static_cast<SCCOL>(nPos), nTab) :
3528 3 : pDoc->HasRowBreak(static_cast<SCROW>(nPos), nTab);
3529 2 : if (nBreak & BREAK_MANUAL)
3530 0 : return true;
3531 :
3532 2 : if (bRecord)
3533 2 : rDocShell.GetUndoManager()->AddUndoAction(
3534 2 : new ScUndoPageBreak( &rDocShell, rPos.Col(), rPos.Row(), nTab, bColumn, sal_True ) );
3535 :
3536 2 : if (bColumn)
3537 1 : pDoc->SetColBreak(static_cast<SCCOL>(nPos), nTab, false, true);
3538 : else
3539 1 : pDoc->SetRowBreak(static_cast<SCROW>(nPos), nTab, false, true);
3540 :
3541 2 : pDoc->InvalidatePageBreaks(nTab);
3542 2 : pDoc->UpdatePageBreaks( nTab );
3543 :
3544 2 : if (pDoc->IsStreamValid(nTab))
3545 0 : pDoc->SetStreamValid(nTab, false);
3546 :
3547 2 : if (bColumn)
3548 : {
3549 1 : rDocShell.PostPaint( static_cast<SCCOL>(nPos)-1, 0, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID );
3550 1 : if (pBindings)
3551 : {
3552 1 : pBindings->Invalidate( FID_INS_COLBRK );
3553 1 : pBindings->Invalidate( FID_DEL_COLBRK );
3554 : }
3555 : }
3556 : else
3557 : {
3558 1 : rDocShell.PostPaint( 0, static_cast<SCROW>(nPos)-1, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID );
3559 1 : if (pBindings)
3560 : {
3561 1 : pBindings->Invalidate( FID_INS_ROWBRK );
3562 1 : pBindings->Invalidate( FID_DEL_ROWBRK );
3563 : }
3564 : }
3565 2 : if (pBindings)
3566 2 : pBindings->Invalidate( FID_DEL_MANUALBREAKS );
3567 :
3568 2 : if (bSetModified)
3569 2 : aModificator.SetDocumentModified();
3570 :
3571 2 : return sal_True;
3572 : }
3573 :
3574 6501 : sal_Bool ScDocFunc::RemovePageBreak( sal_Bool bColumn, const ScAddress& rPos,
3575 : sal_Bool bRecord, sal_Bool bSetModified, sal_Bool /* bApi */ )
3576 : {
3577 6501 : ScDocShellModificator aModificator( rDocShell );
3578 :
3579 6501 : ScDocument* pDoc = rDocShell.GetDocument();
3580 6501 : if (bRecord && !pDoc->IsUndoEnabled())
3581 6499 : bRecord = false;
3582 6501 : SCTAB nTab = rPos.Tab();
3583 6501 : SfxBindings* pBindings = rDocShell.GetViewBindings();
3584 :
3585 6500 : SCCOLROW nPos = bColumn ? static_cast<SCCOLROW>(rPos.Col()) :
3586 13001 : static_cast<SCCOLROW>(rPos.Row());
3587 :
3588 : ScBreakType nBreak;
3589 6501 : if (bColumn)
3590 6500 : nBreak = pDoc->HasColBreak(static_cast<SCCOL>(nPos), nTab);
3591 : else
3592 1 : nBreak = pDoc->HasRowBreak(static_cast<SCROW>(nPos), nTab);
3593 6501 : if ((nBreak & BREAK_MANUAL) == 0)
3594 : // There is no manual break.
3595 6499 : return false;
3596 :
3597 2 : if (bRecord)
3598 2 : rDocShell.GetUndoManager()->AddUndoAction(
3599 2 : new ScUndoPageBreak( &rDocShell, rPos.Col(), rPos.Row(), nTab, bColumn, false ) );
3600 :
3601 2 : if (bColumn)
3602 1 : pDoc->RemoveColBreak(static_cast<SCCOL>(nPos), nTab, false, true);
3603 : else
3604 1 : pDoc->RemoveRowBreak(static_cast<SCROW>(nPos), nTab, false, true);
3605 :
3606 2 : pDoc->UpdatePageBreaks( nTab );
3607 :
3608 2 : if (pDoc->IsStreamValid(nTab))
3609 0 : pDoc->SetStreamValid(nTab, false);
3610 :
3611 2 : if (bColumn)
3612 : {
3613 1 : rDocShell.PostPaint( static_cast<SCCOL>(nPos)-1, 0, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID );
3614 1 : if (pBindings)
3615 : {
3616 1 : pBindings->Invalidate( FID_INS_COLBRK );
3617 1 : pBindings->Invalidate( FID_DEL_COLBRK );
3618 : }
3619 : }
3620 : else
3621 : {
3622 1 : rDocShell.PostPaint( 0, nPos-1, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID );
3623 1 : if (pBindings)
3624 : {
3625 1 : pBindings->Invalidate( FID_INS_ROWBRK );
3626 1 : pBindings->Invalidate( FID_DEL_ROWBRK );
3627 : }
3628 : }
3629 2 : if (pBindings)
3630 2 : pBindings->Invalidate( FID_DEL_MANUALBREAKS );
3631 :
3632 2 : if (bSetModified)
3633 2 : aModificator.SetDocumentModified();
3634 :
3635 2 : return sal_True;
3636 : }
3637 :
3638 : //------------------------------------------------------------------------
3639 :
3640 0 : void ScDocFunc::ProtectSheet( SCTAB nTab, const ScTableProtection& rProtect )
3641 : {
3642 0 : ScDocument* pDoc = rDocShell.GetDocument();
3643 :
3644 0 : pDoc->SetTabProtection(nTab, &rProtect);
3645 0 : if (pDoc->IsUndoEnabled())
3646 : {
3647 0 : ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
3648 : OSL_ENSURE(pProtect, "ScDocFunc::Unprotect: ScTableProtection pointer is NULL!");
3649 0 : if (pProtect)
3650 : {
3651 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
3652 0 : ::std::auto_ptr<ScTableProtection> p(new ScTableProtection(*pProtect));
3653 : SAL_WNODEPRECATED_DECLARATIONS_POP
3654 0 : p->setProtected(true); // just in case ...
3655 0 : rDocShell.GetUndoManager()->AddUndoAction(
3656 0 : new ScUndoTabProtect(&rDocShell, nTab, p) );
3657 :
3658 : // ownership of auto_ptr now transferred to ScUndoTabProtect.
3659 : }
3660 : }
3661 :
3662 0 : rDocShell.PostPaintGridAll();
3663 0 : ScDocShellModificator aModificator(rDocShell);
3664 0 : aModificator.SetDocumentModified();
3665 0 : }
3666 :
3667 1 : sal_Bool ScDocFunc::Protect( SCTAB nTab, const String& rPassword, sal_Bool /*bApi*/ )
3668 : {
3669 1 : ScDocument* pDoc = rDocShell.GetDocument();
3670 1 : if (nTab == TABLEID_DOC)
3671 : {
3672 : // document protection
3673 1 : ScDocProtection aProtection;
3674 1 : aProtection.setProtected(true);
3675 1 : aProtection.setPassword(rPassword);
3676 1 : pDoc->SetDocProtection(&aProtection);
3677 1 : if (pDoc->IsUndoEnabled())
3678 : {
3679 1 : ScDocProtection* pProtect = pDoc->GetDocProtection();
3680 : OSL_ENSURE(pProtect, "ScDocFunc::Unprotect: ScDocProtection pointer is NULL!");
3681 1 : if (pProtect)
3682 : {
3683 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
3684 1 : ::std::auto_ptr<ScDocProtection> p(new ScDocProtection(*pProtect));
3685 : SAL_WNODEPRECATED_DECLARATIONS_POP
3686 1 : p->setProtected(true); // just in case ...
3687 1 : rDocShell.GetUndoManager()->AddUndoAction(
3688 1 : new ScUndoDocProtect(&rDocShell, p) );
3689 : // ownership of auto_ptr is transferred to ScUndoDocProtect.
3690 : }
3691 1 : }
3692 : }
3693 : else
3694 : {
3695 : // sheet protection
3696 :
3697 0 : ScTableProtection aProtection;
3698 0 : aProtection.setProtected(true);
3699 0 : aProtection.setPassword(rPassword);
3700 0 : pDoc->SetTabProtection(nTab, &aProtection);
3701 0 : if (pDoc->IsUndoEnabled())
3702 : {
3703 0 : ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
3704 : OSL_ENSURE(pProtect, "ScDocFunc::Unprotect: ScTableProtection pointer is NULL!");
3705 0 : if (pProtect)
3706 : {
3707 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
3708 0 : ::std::auto_ptr<ScTableProtection> p(new ScTableProtection(*pProtect));
3709 : SAL_WNODEPRECATED_DECLARATIONS_POP
3710 0 : p->setProtected(true); // just in case ...
3711 0 : rDocShell.GetUndoManager()->AddUndoAction(
3712 0 : new ScUndoTabProtect(&rDocShell, nTab, p) );
3713 : // ownership of auto_ptr now transferred to ScUndoTabProtect.
3714 : }
3715 0 : }
3716 : }
3717 :
3718 1 : rDocShell.PostPaintGridAll();
3719 1 : ScDocShellModificator aModificator( rDocShell );
3720 1 : aModificator.SetDocumentModified();
3721 :
3722 1 : return true;
3723 : }
3724 :
3725 2 : sal_Bool ScDocFunc::Unprotect( SCTAB nTab, const String& rPassword, sal_Bool bApi )
3726 : {
3727 2 : ScDocument* pDoc = rDocShell.GetDocument();
3728 :
3729 2 : if (nTab == TABLEID_DOC)
3730 : {
3731 : // document protection
3732 :
3733 2 : ScDocProtection* pDocProtect = pDoc->GetDocProtection();
3734 2 : if (!pDocProtect || !pDocProtect->isProtected())
3735 : // already unprotected (should not happen)!
3736 1 : return true;
3737 :
3738 : // save the protection state before unprotect (for undo).
3739 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
3740 2 : ::std::auto_ptr<ScDocProtection> pProtectCopy(new ScDocProtection(*pDocProtect));
3741 : SAL_WNODEPRECATED_DECLARATIONS_POP
3742 :
3743 2 : if (!pDocProtect->verifyPassword(rPassword))
3744 : {
3745 1 : if (!bApi)
3746 : {
3747 0 : InfoBox aBox( rDocShell.GetActiveDialogParent(), String( ScResId( SCSTR_WRONGPASSWORD ) ) );
3748 0 : aBox.Execute();
3749 : }
3750 1 : return false;
3751 : }
3752 :
3753 1 : pDoc->SetDocProtection(NULL);
3754 1 : if (pDoc->IsUndoEnabled())
3755 : {
3756 1 : pProtectCopy->setProtected(false);
3757 1 : rDocShell.GetUndoManager()->AddUndoAction(
3758 1 : new ScUndoDocProtect(&rDocShell, pProtectCopy) );
3759 : // ownership of auto_ptr now transferred to ScUndoDocProtect.
3760 1 : }
3761 : }
3762 : else
3763 : {
3764 : // sheet protection
3765 :
3766 0 : ScTableProtection* pTabProtect = pDoc->GetTabProtection(nTab);
3767 0 : if (!pTabProtect || !pTabProtect->isProtected())
3768 : // already unprotected (should not happen)!
3769 0 : return true;
3770 :
3771 : // save the protection state before unprotect (for undo).
3772 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
3773 0 : ::std::auto_ptr<ScTableProtection> pProtectCopy(new ScTableProtection(*pTabProtect));
3774 : SAL_WNODEPRECATED_DECLARATIONS_POP
3775 0 : if (!pTabProtect->verifyPassword(rPassword))
3776 : {
3777 0 : if (!bApi)
3778 : {
3779 0 : InfoBox aBox( rDocShell.GetActiveDialogParent(), String( ScResId( SCSTR_WRONGPASSWORD ) ) );
3780 0 : aBox.Execute();
3781 : }
3782 0 : return false;
3783 : }
3784 :
3785 0 : pDoc->SetTabProtection(nTab, NULL);
3786 0 : if (pDoc->IsUndoEnabled())
3787 : {
3788 0 : pProtectCopy->setProtected(false);
3789 0 : rDocShell.GetUndoManager()->AddUndoAction(
3790 0 : new ScUndoTabProtect(&rDocShell, nTab, pProtectCopy) );
3791 : // ownership of auto_ptr now transferred to ScUndoTabProtect.
3792 0 : }
3793 : }
3794 :
3795 1 : rDocShell.PostPaintGridAll();
3796 1 : ScDocShellModificator aModificator( rDocShell );
3797 1 : aModificator.SetDocumentModified();
3798 :
3799 1 : return true;
3800 : }
3801 :
3802 : //------------------------------------------------------------------------
3803 :
3804 0 : sal_Bool ScDocFunc::ClearItems( const ScMarkData& rMark, const sal_uInt16* pWhich, sal_Bool bApi )
3805 : {
3806 0 : ScDocShellModificator aModificator( rDocShell );
3807 :
3808 0 : ScDocument* pDoc = rDocShell.GetDocument();
3809 0 : bool bUndo (pDoc->IsUndoEnabled());
3810 0 : ScEditableTester aTester( pDoc, rMark );
3811 0 : if (!aTester.IsEditable())
3812 : {
3813 0 : if (!bApi)
3814 0 : rDocShell.ErrorMessage(aTester.GetMessageId());
3815 0 : return false;
3816 : }
3817 :
3818 : // #i12940# ClearItems is called (from setPropertyToDefault) directly with uno object's cached
3819 : // MarkData (GetMarkData), so rMark must be changed to multi selection for ClearSelectionItems
3820 : // here.
3821 :
3822 0 : ScRange aMarkRange;
3823 0 : ScMarkData aMultiMark = rMark;
3824 0 : aMultiMark.SetMarking(false); // for MarkToMulti
3825 0 : aMultiMark.MarkToMulti();
3826 0 : aMultiMark.GetMultiMarkArea( aMarkRange );
3827 :
3828 0 : if (bUndo)
3829 : {
3830 0 : SCTAB nStartTab = aMarkRange.aStart.Tab();
3831 0 : SCTAB nEndTab = aMarkRange.aEnd.Tab();
3832 :
3833 0 : ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
3834 0 : pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab );
3835 0 : pDoc->CopyToDocument( aMarkRange, IDF_ATTRIB, sal_True, pUndoDoc, (ScMarkData*)&aMultiMark );
3836 :
3837 0 : rDocShell.GetUndoManager()->AddUndoAction(
3838 0 : new ScUndoClearItems( &rDocShell, aMultiMark, pUndoDoc, pWhich ) );
3839 : }
3840 :
3841 0 : pDoc->ClearSelectionItems( pWhich, aMultiMark );
3842 :
3843 0 : rDocShell.PostPaint( aMarkRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
3844 0 : aModificator.SetDocumentModified();
3845 :
3846 : //! Bindings-Invalidate etc.?
3847 :
3848 0 : return sal_True;
3849 : }
3850 :
3851 6 : sal_Bool ScDocFunc::ChangeIndent( const ScMarkData& rMark, sal_Bool bIncrement, sal_Bool bApi )
3852 : {
3853 6 : ScDocShellModificator aModificator( rDocShell );
3854 :
3855 6 : ScDocument* pDoc = rDocShell.GetDocument();
3856 6 : bool bUndo(pDoc->IsUndoEnabled());
3857 6 : ScEditableTester aTester( pDoc, rMark );
3858 6 : if (!aTester.IsEditable())
3859 : {
3860 0 : if (!bApi)
3861 0 : rDocShell.ErrorMessage(aTester.GetMessageId());
3862 0 : return false;
3863 : }
3864 :
3865 6 : ScRange aMarkRange;
3866 6 : rMark.GetMultiMarkArea( aMarkRange );
3867 :
3868 6 : if (bUndo)
3869 : {
3870 6 : SCTAB nStartTab = aMarkRange.aStart.Tab();
3871 6 : SCTAB nTabCount = pDoc->GetTableCount();
3872 :
3873 6 : ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
3874 6 : pUndoDoc->InitUndo( pDoc, nStartTab, nStartTab );
3875 6 : ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
3876 12 : for (; itr != itrEnd && *itr < nTabCount; ++itr)
3877 6 : if (*itr != nStartTab)
3878 0 : pUndoDoc->AddUndoTab( *itr, *itr );
3879 :
3880 6 : ScRange aCopyRange = aMarkRange;
3881 6 : aCopyRange.aStart.SetTab(0);
3882 6 : aCopyRange.aEnd.SetTab(nTabCount-1);
3883 6 : pDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, sal_True, pUndoDoc, (ScMarkData*)&rMark );
3884 :
3885 6 : rDocShell.GetUndoManager()->AddUndoAction(
3886 6 : new ScUndoIndent( &rDocShell, rMark, pUndoDoc, bIncrement ) );
3887 : }
3888 :
3889 6 : pDoc->ChangeSelectionIndent( bIncrement, rMark );
3890 :
3891 6 : rDocShell.PostPaint( aMarkRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
3892 6 : aModificator.SetDocumentModified();
3893 :
3894 6 : SfxBindings* pBindings = rDocShell.GetViewBindings();
3895 6 : if (pBindings)
3896 : {
3897 6 : pBindings->Invalidate( SID_ALIGNLEFT ); // ChangeIndent setzt auf links
3898 6 : pBindings->Invalidate( SID_ALIGNRIGHT );
3899 6 : pBindings->Invalidate( SID_ALIGNBLOCK );
3900 6 : pBindings->Invalidate( SID_ALIGNCENTERHOR );
3901 6 : pBindings->Invalidate( SID_ATTR_LRSPACE );
3902 6 : pBindings->Invalidate( SID_ATTR_PARA_ADJUST_LEFT );
3903 6 : pBindings->Invalidate( SID_ATTR_PARA_ADJUST_RIGHT );
3904 6 : pBindings->Invalidate( SID_ATTR_PARA_ADJUST_BLOCK );
3905 6 : pBindings->Invalidate( SID_ATTR_PARA_ADJUST_CENTER);
3906 : // pseudo slots for Format menu
3907 6 : pBindings->Invalidate( SID_ALIGN_ANY_HDEFAULT );
3908 6 : pBindings->Invalidate( SID_ALIGN_ANY_LEFT );
3909 6 : pBindings->Invalidate( SID_ALIGN_ANY_HCENTER );
3910 6 : pBindings->Invalidate( SID_ALIGN_ANY_RIGHT );
3911 6 : pBindings->Invalidate( SID_ALIGN_ANY_JUSTIFIED );
3912 : }
3913 :
3914 6 : return sal_True;
3915 : }
3916 :
3917 0 : bool ScDocFunc::AutoFormat( const ScRange& rRange, const ScMarkData* pTabMark,
3918 : sal_uInt16 nFormatNo, bool bRecord, bool bApi )
3919 : {
3920 0 : ScDocShellModificator aModificator( rDocShell );
3921 :
3922 0 : sal_Bool bSuccess = false;
3923 0 : ScDocument* pDoc = rDocShell.GetDocument();
3924 0 : SCCOL nStartCol = rRange.aStart.Col();
3925 0 : SCROW nStartRow = rRange.aStart.Row();
3926 0 : SCTAB nStartTab = rRange.aStart.Tab();
3927 0 : SCCOL nEndCol = rRange.aEnd.Col();
3928 0 : SCROW nEndRow = rRange.aEnd.Row();
3929 0 : SCTAB nEndTab = rRange.aEnd.Tab();
3930 :
3931 0 : if (bRecord && !pDoc->IsUndoEnabled())
3932 0 : bRecord = false;
3933 0 : ScMarkData aMark;
3934 0 : if (pTabMark)
3935 0 : aMark = *pTabMark;
3936 : else
3937 : {
3938 0 : for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
3939 0 : aMark.SelectTable( nTab, sal_True );
3940 : }
3941 :
3942 0 : ScAutoFormat* pAutoFormat = ScGlobal::GetOrCreateAutoFormat();
3943 0 : ScEditableTester aTester( pDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
3944 0 : if ( nFormatNo < pAutoFormat->size() && aTester.IsEditable() )
3945 : {
3946 0 : WaitObject aWait( rDocShell.GetActiveDialogParent() );
3947 :
3948 0 : bool bSize = pAutoFormat->findByIndex(nFormatNo)->GetIncludeWidthHeight();
3949 :
3950 0 : SCTAB nTabCount = pDoc->GetTableCount();
3951 0 : ScDocument* pUndoDoc = NULL;
3952 0 : if ( bRecord )
3953 : {
3954 0 : pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
3955 0 : pUndoDoc->InitUndo( pDoc, nStartTab, nStartTab, bSize, bSize );
3956 0 : ScMarkData::iterator itr = aMark.begin(), itrEnd = aMark.end();
3957 0 : for (; itr != itrEnd && *itr < nTabCount; ++itr)
3958 0 : if (*itr != nStartTab)
3959 0 : pUndoDoc->AddUndoTab( *itr, *itr, bSize, bSize );
3960 :
3961 0 : ScRange aCopyRange = rRange;
3962 0 : aCopyRange.aStart.SetTab(0);
3963 0 : aCopyRange.aStart.SetTab(nTabCount-1);
3964 0 : pDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, false, pUndoDoc, &aMark );
3965 0 : if (bSize)
3966 : {
3967 : pDoc->CopyToDocument( nStartCol,0,0, nEndCol,MAXROW,nTabCount-1,
3968 0 : IDF_NONE, false, pUndoDoc, &aMark );
3969 : pDoc->CopyToDocument( 0,nStartRow,0, MAXCOL,nEndRow,nTabCount-1,
3970 0 : IDF_NONE, false, pUndoDoc, &aMark );
3971 : }
3972 0 : pDoc->BeginDrawUndo();
3973 : }
3974 :
3975 0 : pDoc->AutoFormat( nStartCol, nStartRow, nEndCol, nEndRow, nFormatNo, aMark );
3976 :
3977 0 : if (bSize)
3978 : {
3979 0 : SCCOLROW nCols[2] = { nStartCol, nEndCol };
3980 0 : SCCOLROW nRows[2] = { nStartRow, nEndRow };
3981 :
3982 0 : ScMarkData::iterator itr = aMark.begin(), itrEnd = aMark.end();
3983 0 : for (; itr != itrEnd && *itr < nTabCount; ++itr)
3984 : {
3985 0 : SetWidthOrHeight( sal_True, 1,nCols, *itr, SC_SIZE_VISOPT, STD_EXTRA_WIDTH, false, sal_True);
3986 0 : SetWidthOrHeight( false,1,nRows, *itr, SC_SIZE_VISOPT, 0, false, false);
3987 0 : rDocShell.PostPaint( 0,0,*itr, MAXCOL,MAXROW,*itr,
3988 0 : PAINT_GRID | PAINT_LEFT | PAINT_TOP );
3989 : }
3990 : }
3991 : else
3992 : {
3993 0 : ScMarkData::iterator itr = aMark.begin(), itrEnd = aMark.end();
3994 0 : for (; itr != itrEnd && *itr < nTabCount; ++itr)
3995 : {
3996 0 : sal_Bool bAdj = AdjustRowHeight( ScRange(nStartCol, nStartRow, *itr,
3997 0 : nEndCol, nEndRow, *itr), false );
3998 0 : if (bAdj)
3999 0 : rDocShell.PostPaint( 0,nStartRow,*itr, MAXCOL,MAXROW,*itr,
4000 0 : PAINT_GRID | PAINT_LEFT );
4001 : else
4002 0 : rDocShell.PostPaint( nStartCol, nStartRow, *itr,
4003 0 : nEndCol, nEndRow, *itr, PAINT_GRID );
4004 : }
4005 : }
4006 :
4007 0 : if ( bRecord ) // Draw-Undo erst jetzt verfuegbar
4008 : {
4009 0 : rDocShell.GetUndoManager()->AddUndoAction(
4010 0 : new ScUndoAutoFormat( &rDocShell, rRange, pUndoDoc, aMark, bSize, nFormatNo ) );
4011 : }
4012 :
4013 0 : aModificator.SetDocumentModified();
4014 : }
4015 0 : else if (!bApi)
4016 0 : rDocShell.ErrorMessage(aTester.GetMessageId());
4017 :
4018 0 : return bSuccess;
4019 : }
4020 :
4021 : //------------------------------------------------------------------------
4022 :
4023 1 : sal_Bool ScDocFunc::EnterMatrix( const ScRange& rRange, const ScMarkData* pTabMark,
4024 : const ScTokenArray* pTokenArray, const String& rString, sal_Bool bApi, sal_Bool bEnglish,
4025 : const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
4026 : {
4027 1 : ScDocShellModificator aModificator( rDocShell );
4028 :
4029 1 : sal_Bool bSuccess = false;
4030 1 : ScDocument* pDoc = rDocShell.GetDocument();
4031 1 : SCCOL nStartCol = rRange.aStart.Col();
4032 1 : SCROW nStartRow = rRange.aStart.Row();
4033 1 : SCTAB nStartTab = rRange.aStart.Tab();
4034 1 : SCCOL nEndCol = rRange.aEnd.Col();
4035 1 : SCROW nEndRow = rRange.aEnd.Row();
4036 1 : SCTAB nEndTab = rRange.aEnd.Tab();
4037 :
4038 1 : bool bUndo(pDoc->IsUndoEnabled());
4039 :
4040 2 : ScMarkData aMark;
4041 1 : if (pTabMark)
4042 0 : aMark = *pTabMark;
4043 : else
4044 : {
4045 2 : for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
4046 1 : aMark.SelectTable( nTab, sal_True );
4047 : }
4048 :
4049 1 : ScEditableTester aTester( pDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
4050 1 : if ( aTester.IsEditable() )
4051 : {
4052 1 : WaitObject aWait( rDocShell.GetActiveDialogParent() );
4053 :
4054 1 : ScDocument* pUndoDoc = NULL;
4055 :
4056 1 : if (bUndo)
4057 : {
4058 : //! auch bei Undo selektierte Tabellen beruecksichtigen
4059 1 : pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
4060 1 : pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab );
4061 1 : pDoc->CopyToDocument( rRange, IDF_ALL & ~IDF_NOTE, false, pUndoDoc );
4062 : }
4063 :
4064 : // use TokenArray if given, string (and flags) otherwise
4065 1 : if ( pTokenArray )
4066 : {
4067 : pDoc->InsertMatrixFormula( nStartCol, nStartRow, nEndCol, nEndRow,
4068 0 : aMark, EMPTY_STRING, pTokenArray, eGrammar);
4069 : }
4070 1 : else if ( pDoc->IsImportingXML() )
4071 : {
4072 0 : ScTokenArray* pCode = lcl_ScDocFunc_CreateTokenArrayXML( rString, rFormulaNmsp, eGrammar );
4073 : pDoc->InsertMatrixFormula( nStartCol, nStartRow, nEndCol, nEndRow,
4074 0 : aMark, EMPTY_STRING, pCode, eGrammar);
4075 0 : delete pCode;
4076 0 : pDoc->IncXMLImportedFormulaCount( rString.Len() );
4077 : }
4078 1 : else if (bEnglish)
4079 : {
4080 1 : ScCompiler aComp( pDoc, rRange.aStart);
4081 1 : aComp.SetGrammar(eGrammar);
4082 1 : ScTokenArray* pCode = aComp.CompileString( rString );
4083 : pDoc->InsertMatrixFormula( nStartCol, nStartRow, nEndCol, nEndRow,
4084 1 : aMark, EMPTY_STRING, pCode, eGrammar);
4085 1 : delete pCode;
4086 : }
4087 : else
4088 : pDoc->InsertMatrixFormula( nStartCol, nStartRow, nEndCol, nEndRow,
4089 0 : aMark, rString, NULL, eGrammar);
4090 :
4091 1 : if (bUndo)
4092 : {
4093 : //! auch bei Undo selektierte Tabellen beruecksichtigen
4094 1 : rDocShell.GetUndoManager()->AddUndoAction(
4095 1 : new ScUndoEnterMatrix( &rDocShell, rRange, pUndoDoc, rString ) );
4096 : }
4097 :
4098 : // Err522 beim Paint von DDE-Formeln werden jetzt beim Interpretieren abgefangen
4099 1 : rDocShell.PostPaint( nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab, PAINT_GRID );
4100 1 : aModificator.SetDocumentModified();
4101 :
4102 1 : bSuccess = sal_True;
4103 : }
4104 0 : else if (!bApi)
4105 0 : rDocShell.ErrorMessage(aTester.GetMessageId());
4106 :
4107 2 : return bSuccess;
4108 : }
4109 :
4110 : //------------------------------------------------------------------------
4111 :
4112 3 : sal_Bool ScDocFunc::TabOp( const ScRange& rRange, const ScMarkData* pTabMark,
4113 : const ScTabOpParam& rParam, sal_Bool bRecord, sal_Bool bApi )
4114 : {
4115 3 : ScDocShellModificator aModificator( rDocShell );
4116 :
4117 3 : sal_Bool bSuccess = false;
4118 3 : ScDocument* pDoc = rDocShell.GetDocument();
4119 3 : SCCOL nStartCol = rRange.aStart.Col();
4120 3 : SCROW nStartRow = rRange.aStart.Row();
4121 3 : SCTAB nStartTab = rRange.aStart.Tab();
4122 3 : SCCOL nEndCol = rRange.aEnd.Col();
4123 3 : SCROW nEndRow = rRange.aEnd.Row();
4124 3 : SCTAB nEndTab = rRange.aEnd.Tab();
4125 :
4126 3 : if (bRecord && !pDoc->IsUndoEnabled())
4127 0 : bRecord = false;
4128 :
4129 6 : ScMarkData aMark;
4130 3 : if (pTabMark)
4131 0 : aMark = *pTabMark;
4132 : else
4133 : {
4134 6 : for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
4135 3 : aMark.SelectTable( nTab, sal_True );
4136 : }
4137 :
4138 3 : ScEditableTester aTester( pDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
4139 3 : if ( aTester.IsEditable() )
4140 : {
4141 3 : WaitObject aWait( rDocShell.GetActiveDialogParent() );
4142 3 : pDoc->SetDirty( rRange );
4143 3 : if ( bRecord )
4144 : {
4145 : //! auch bei Undo selektierte Tabellen beruecksichtigen
4146 3 : ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
4147 3 : pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab );
4148 3 : pDoc->CopyToDocument( rRange, IDF_ALL & ~IDF_NOTE, false, pUndoDoc );
4149 :
4150 3 : rDocShell.GetUndoManager()->AddUndoAction(
4151 : new ScUndoTabOp( &rDocShell,
4152 : nStartCol, nStartRow, nStartTab,
4153 : nEndCol, nEndRow, nEndTab, pUndoDoc,
4154 : rParam.aRefFormulaCell,
4155 : rParam.aRefFormulaEnd,
4156 : rParam.aRefRowCell,
4157 : rParam.aRefColCell,
4158 3 : rParam.nMode) );
4159 : }
4160 3 : pDoc->InsertTableOp(rParam, nStartCol, nStartRow, nEndCol, nEndRow, aMark);
4161 3 : rDocShell.PostPaintGridAll();
4162 3 : aModificator.SetDocumentModified();
4163 3 : bSuccess = sal_True;
4164 : }
4165 0 : else if (!bApi)
4166 0 : rDocShell.ErrorMessage(aTester.GetMessageId());
4167 :
4168 6 : return bSuccess;
4169 : }
4170 :
4171 : //------------------------------------------------------------------------
4172 :
4173 13 : inline ScDirection DirFromFillDir( FillDir eDir )
4174 : {
4175 13 : if (eDir==FILL_TO_BOTTOM)
4176 4 : return DIR_BOTTOM;
4177 9 : else if (eDir==FILL_TO_RIGHT)
4178 5 : return DIR_RIGHT;
4179 4 : else if (eDir==FILL_TO_TOP)
4180 2 : return DIR_TOP;
4181 : else // if (eDir==FILL_TO_LEFT)
4182 2 : return DIR_LEFT;
4183 : }
4184 :
4185 : namespace {
4186 :
4187 : /**
4188 : * Expand the fill range as necessary, to allow copying of adjacent cell(s)
4189 : * even when those cells are not in the original range.
4190 : */
4191 0 : void adjustFillRangeForAdjacentCopy(ScRange& rRange, FillDir eDir)
4192 : {
4193 0 : switch (eDir)
4194 : {
4195 : case FILL_TO_BOTTOM:
4196 : {
4197 0 : if (rRange.aStart.Row() == 0)
4198 0 : return;
4199 :
4200 0 : if (rRange.aStart.Row() != rRange.aEnd.Row())
4201 0 : return;
4202 :
4203 : // Include the above row.
4204 0 : ScAddress& s = rRange.aStart;
4205 0 : s.SetRow(s.Row()-1);
4206 : }
4207 0 : break;
4208 : case FILL_TO_TOP:
4209 : {
4210 0 : if (rRange.aStart.Row() == MAXROW)
4211 0 : return;
4212 :
4213 0 : if (rRange.aStart.Row() != rRange.aEnd.Row())
4214 0 : return;
4215 :
4216 : // Include the row below.
4217 0 : ScAddress& e = rRange.aEnd;
4218 0 : e.SetRow(e.Row()+1);
4219 : }
4220 0 : break;
4221 : case FILL_TO_LEFT:
4222 : {
4223 0 : if (rRange.aStart.Col() == MAXCOL)
4224 0 : return;
4225 :
4226 0 : if (rRange.aStart.Col() != rRange.aEnd.Col())
4227 0 : return;
4228 :
4229 : // Include the column to the right.
4230 0 : ScAddress& e = rRange.aEnd;
4231 0 : e.SetCol(e.Col()+1);
4232 : }
4233 0 : break;
4234 : case FILL_TO_RIGHT:
4235 : {
4236 0 : if (rRange.aStart.Col() == 0)
4237 0 : return;
4238 :
4239 0 : if (rRange.aStart.Col() != rRange.aEnd.Col())
4240 0 : return;
4241 :
4242 : // Include the column to the left.
4243 0 : ScAddress& s = rRange.aStart;
4244 0 : s.SetCol(s.Col()-1);
4245 : }
4246 0 : break;
4247 : default:
4248 : ;
4249 : }
4250 : }
4251 :
4252 : }
4253 :
4254 0 : bool ScDocFunc::FillSimple( const ScRange& rRange, const ScMarkData* pTabMark,
4255 : FillDir eDir, bool bRecord, bool bApi )
4256 : {
4257 0 : ScDocShellModificator aModificator( rDocShell );
4258 0 : ScDocument* pDoc = rDocShell.GetDocument();
4259 :
4260 0 : bool bSuccess = false;
4261 0 : ScRange aRange = rRange;
4262 0 : adjustFillRangeForAdjacentCopy(aRange, eDir);
4263 :
4264 0 : SCCOL nStartCol = aRange.aStart.Col();
4265 0 : SCROW nStartRow = aRange.aStart.Row();
4266 0 : SCTAB nStartTab = aRange.aStart.Tab();
4267 0 : SCCOL nEndCol = aRange.aEnd.Col();
4268 0 : SCROW nEndRow = aRange.aEnd.Row();
4269 0 : SCTAB nEndTab = aRange.aEnd.Tab();
4270 :
4271 0 : if (bRecord && !pDoc->IsUndoEnabled())
4272 0 : bRecord = false;
4273 :
4274 0 : ScMarkData aMark;
4275 0 : if (pTabMark)
4276 0 : aMark = *pTabMark;
4277 : else
4278 : {
4279 0 : for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
4280 0 : aMark.SelectTable( nTab, sal_True );
4281 : }
4282 :
4283 0 : ScEditableTester aTester( pDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
4284 0 : if ( aTester.IsEditable() )
4285 : {
4286 0 : WaitObject aWait( rDocShell.GetActiveDialogParent() );
4287 :
4288 0 : ScRange aSourceArea = aRange;
4289 0 : ScRange aDestArea = aRange;
4290 :
4291 0 : SCCOLROW nCount = 0;
4292 0 : switch (eDir)
4293 : {
4294 : case FILL_TO_BOTTOM:
4295 0 : nCount = aSourceArea.aEnd.Row()-aSourceArea.aStart.Row();
4296 0 : aSourceArea.aEnd.SetRow( aSourceArea.aStart.Row() );
4297 0 : break;
4298 : case FILL_TO_RIGHT:
4299 0 : nCount = aSourceArea.aEnd.Col()-aSourceArea.aStart.Col();
4300 0 : aSourceArea.aEnd.SetCol( aSourceArea.aStart.Col() );
4301 0 : break;
4302 : case FILL_TO_TOP:
4303 0 : nCount = aSourceArea.aEnd.Row()-aSourceArea.aStart.Row();
4304 0 : aSourceArea.aStart.SetRow( aSourceArea.aEnd.Row() );
4305 0 : break;
4306 : case FILL_TO_LEFT:
4307 0 : nCount = aSourceArea.aEnd.Col()-aSourceArea.aStart.Col();
4308 0 : aSourceArea.aStart.SetCol( aSourceArea.aEnd.Col() );
4309 0 : break;
4310 : }
4311 :
4312 0 : ScDocument* pUndoDoc = NULL;
4313 0 : if ( bRecord )
4314 : {
4315 0 : SCTAB nTabCount = pDoc->GetTableCount();
4316 0 : SCTAB nDestStartTab = aDestArea.aStart.Tab();
4317 :
4318 0 : pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
4319 0 : pUndoDoc->InitUndo( pDoc, nDestStartTab, nDestStartTab );
4320 0 : ScMarkData::iterator itr = aMark.begin(), itrEnd = aMark.end();
4321 0 : for (; itr != itrEnd && *itr < nTabCount; ++itr)
4322 0 : if (*itr != nDestStartTab)
4323 0 : pUndoDoc->AddUndoTab( *itr, *itr );
4324 :
4325 0 : ScRange aCopyRange = aDestArea;
4326 0 : aCopyRange.aStart.SetTab(0);
4327 0 : aCopyRange.aEnd.SetTab(nTabCount-1);
4328 0 : pDoc->CopyToDocument( aCopyRange, IDF_AUTOFILL, false, pUndoDoc, &aMark );
4329 : }
4330 :
4331 : sal_uLong nProgCount;
4332 0 : if (eDir == FILL_TO_BOTTOM || eDir == FILL_TO_TOP)
4333 0 : nProgCount = aSourceArea.aEnd.Col() - aSourceArea.aStart.Col() + 1;
4334 : else
4335 0 : nProgCount = aSourceArea.aEnd.Row() - aSourceArea.aStart.Row() + 1;
4336 0 : nProgCount *= nCount;
4337 : ScProgress aProgress( pDoc->GetDocumentShell(),
4338 0 : ScGlobal::GetRscString(STR_FILL_SERIES_PROGRESS), nProgCount );
4339 :
4340 0 : pDoc->Fill( aSourceArea.aStart.Col(), aSourceArea.aStart.Row(),
4341 0 : aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), &aProgress,
4342 0 : aMark, nCount, eDir, FILL_SIMPLE );
4343 0 : AdjustRowHeight(aRange);
4344 :
4345 0 : if ( bRecord ) // Draw-Undo erst jetzt verfuegbar
4346 : {
4347 0 : rDocShell.GetUndoManager()->AddUndoAction(
4348 : new ScUndoAutoFill( &rDocShell, aDestArea, aSourceArea, pUndoDoc, aMark,
4349 0 : eDir, FILL_SIMPLE, FILL_DAY, MAXDOUBLE, 1.0, 1e307) );
4350 : }
4351 :
4352 0 : rDocShell.PostPaintGridAll();
4353 0 : aModificator.SetDocumentModified();
4354 :
4355 0 : bSuccess = true;
4356 : }
4357 0 : else if (!bApi)
4358 0 : rDocShell.ErrorMessage(aTester.GetMessageId());
4359 :
4360 0 : return bSuccess;
4361 : }
4362 :
4363 13 : sal_Bool ScDocFunc::FillSeries( const ScRange& rRange, const ScMarkData* pTabMark,
4364 : FillDir eDir, FillCmd eCmd, FillDateCmd eDateCmd,
4365 : double fStart, double fStep, double fMax,
4366 : sal_Bool bRecord, sal_Bool bApi )
4367 : {
4368 13 : ScDocShellModificator aModificator( rDocShell );
4369 :
4370 13 : sal_Bool bSuccess = false;
4371 13 : ScDocument* pDoc = rDocShell.GetDocument();
4372 13 : SCCOL nStartCol = rRange.aStart.Col();
4373 13 : SCROW nStartRow = rRange.aStart.Row();
4374 13 : SCTAB nStartTab = rRange.aStart.Tab();
4375 13 : SCCOL nEndCol = rRange.aEnd.Col();
4376 13 : SCROW nEndRow = rRange.aEnd.Row();
4377 13 : SCTAB nEndTab = rRange.aEnd.Tab();
4378 :
4379 13 : if (bRecord && !pDoc->IsUndoEnabled())
4380 0 : bRecord = false;
4381 :
4382 26 : ScMarkData aMark;
4383 13 : if (pTabMark)
4384 0 : aMark = *pTabMark;
4385 : else
4386 : {
4387 26 : for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
4388 13 : aMark.SelectTable( nTab, sal_True );
4389 : }
4390 :
4391 13 : ScEditableTester aTester( pDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
4392 13 : if ( aTester.IsEditable() )
4393 : {
4394 13 : WaitObject aWait( rDocShell.GetActiveDialogParent() );
4395 :
4396 13 : ScRange aSourceArea = rRange;
4397 13 : ScRange aDestArea = rRange;
4398 :
4399 : SCSIZE nCount = pDoc->GetEmptyLinesInBlock(
4400 26 : aSourceArea.aStart.Col(), aSourceArea.aStart.Row(), aSourceArea.aStart.Tab(),
4401 26 : aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), aSourceArea.aEnd.Tab(),
4402 65 : DirFromFillDir(eDir) );
4403 :
4404 : // mindestens eine Zeile/Spalte als Quellbereich behalten:
4405 9 : SCSIZE nTotLines = ( eDir == FILL_TO_BOTTOM || eDir == FILL_TO_TOP ) ?
4406 6 : static_cast<SCSIZE>( aSourceArea.aEnd.Row() - aSourceArea.aStart.Row() + 1 ) :
4407 19 : static_cast<SCSIZE>( aSourceArea.aEnd.Col() - aSourceArea.aStart.Col() + 1 );
4408 13 : if ( nCount >= nTotLines )
4409 1 : nCount = nTotLines - 1;
4410 :
4411 13 : switch (eDir)
4412 : {
4413 : case FILL_TO_BOTTOM:
4414 4 : aSourceArea.aEnd.SetRow( sal::static_int_cast<SCROW>( aSourceArea.aEnd.Row() - nCount ) );
4415 4 : break;
4416 : case FILL_TO_RIGHT:
4417 5 : aSourceArea.aEnd.SetCol( sal::static_int_cast<SCCOL>( aSourceArea.aEnd.Col() - nCount ) );
4418 5 : break;
4419 : case FILL_TO_TOP:
4420 2 : aSourceArea.aStart.SetRow( sal::static_int_cast<SCROW>( aSourceArea.aStart.Row() + nCount ) );
4421 2 : break;
4422 : case FILL_TO_LEFT:
4423 2 : aSourceArea.aStart.SetCol( sal::static_int_cast<SCCOL>( aSourceArea.aStart.Col() + nCount ) );
4424 2 : break;
4425 : }
4426 :
4427 13 : ScDocument* pUndoDoc = NULL;
4428 13 : if ( bRecord )
4429 : {
4430 13 : SCTAB nTabCount = pDoc->GetTableCount();
4431 13 : SCTAB nDestStartTab = aDestArea.aStart.Tab();
4432 :
4433 13 : pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
4434 13 : pUndoDoc->InitUndo( pDoc, nDestStartTab, nDestStartTab );
4435 13 : ScMarkData::iterator itr = aMark.begin(), itrEnd = aMark.end();
4436 26 : for (; itr != itrEnd && *itr < nTabCount; ++itr)
4437 13 : if (*itr != nDestStartTab)
4438 0 : pUndoDoc->AddUndoTab( *itr, *itr );
4439 :
4440 : pDoc->CopyToDocument(
4441 13 : aDestArea.aStart.Col(), aDestArea.aStart.Row(), 0,
4442 13 : aDestArea.aEnd.Col(), aDestArea.aEnd.Row(), nTabCount-1,
4443 39 : IDF_AUTOFILL, false, pUndoDoc, &aMark );
4444 : }
4445 :
4446 26 : if (aDestArea.aStart.Col() <= aDestArea.aEnd.Col() &&
4447 13 : aDestArea.aStart.Row() <= aDestArea.aEnd.Row())
4448 : {
4449 13 : if ( fStart != MAXDOUBLE )
4450 : {
4451 0 : SCCOL nValX = (eDir == FILL_TO_LEFT) ? aDestArea.aEnd.Col() : aDestArea.aStart.Col();
4452 0 : SCROW nValY = (eDir == FILL_TO_TOP ) ? aDestArea.aEnd.Row() : aDestArea.aStart.Row();
4453 0 : SCTAB nTab = aDestArea.aStart.Tab();
4454 0 : pDoc->SetValue( nValX, nValY, nTab, fStart );
4455 : }
4456 :
4457 : sal_uLong nProgCount;
4458 13 : if (eDir == FILL_TO_BOTTOM || eDir == FILL_TO_TOP)
4459 6 : nProgCount = aSourceArea.aEnd.Col() - aSourceArea.aStart.Col() + 1;
4460 : else
4461 7 : nProgCount = aSourceArea.aEnd.Row() - aSourceArea.aStart.Row() + 1;
4462 13 : nProgCount *= nCount;
4463 : ScProgress aProgress( pDoc->GetDocumentShell(),
4464 13 : ScGlobal::GetRscString(STR_FILL_SERIES_PROGRESS), nProgCount );
4465 :
4466 13 : pDoc->Fill( aSourceArea.aStart.Col(), aSourceArea.aStart.Row(),
4467 13 : aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), &aProgress,
4468 39 : aMark, nCount, eDir, eCmd, eDateCmd, fStep, fMax );
4469 13 : AdjustRowHeight(rRange);
4470 :
4471 13 : rDocShell.PostPaintGridAll();
4472 13 : aModificator.SetDocumentModified();
4473 : }
4474 :
4475 13 : if ( bRecord ) // Draw-Undo erst jetzt verfuegbar
4476 : {
4477 13 : rDocShell.GetUndoManager()->AddUndoAction(
4478 : new ScUndoAutoFill( &rDocShell, aDestArea, aSourceArea, pUndoDoc, aMark,
4479 13 : eDir, eCmd, eDateCmd, fStart, fStep, fMax) );
4480 : }
4481 :
4482 13 : bSuccess = sal_True;
4483 : }
4484 0 : else if (!bApi)
4485 0 : rDocShell.ErrorMessage(aTester.GetMessageId());
4486 :
4487 26 : return bSuccess;
4488 : }
4489 :
4490 2 : sal_Bool ScDocFunc::FillAuto( ScRange& rRange, const ScMarkData* pTabMark,
4491 : FillDir eDir, sal_uLong nCount, sal_Bool bRecord, sal_Bool bApi )
4492 : {
4493 2 : double fStep = 1.0;
4494 2 : double fMax = MAXDOUBLE;
4495 2 : return FillAuto( rRange, pTabMark, eDir, FILL_AUTO, FILL_DAY, nCount, fStep, fMax, bRecord, bApi );
4496 : }
4497 :
4498 2 : sal_Bool ScDocFunc::FillAuto( ScRange& rRange, const ScMarkData* pTabMark, FillDir eDir, FillCmd eCmd, FillDateCmd eDateCmd, sal_uLong nCount, double fStep, double fMax, sal_Bool bRecord, sal_Bool bApi )
4499 : {
4500 2 : ScDocShellModificator aModificator( rDocShell );
4501 :
4502 2 : ScDocument* pDoc = rDocShell.GetDocument();
4503 2 : SCCOL nStartCol = rRange.aStart.Col();
4504 2 : SCROW nStartRow = rRange.aStart.Row();
4505 2 : SCTAB nStartTab = rRange.aStart.Tab();
4506 2 : SCCOL nEndCol = rRange.aEnd.Col();
4507 2 : SCROW nEndRow = rRange.aEnd.Row();
4508 2 : SCTAB nEndTab = rRange.aEnd.Tab();
4509 :
4510 2 : if (bRecord && !pDoc->IsUndoEnabled())
4511 0 : bRecord = false;
4512 :
4513 4 : ScMarkData aMark;
4514 2 : if (pTabMark)
4515 0 : aMark = *pTabMark;
4516 : else
4517 : {
4518 4 : for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
4519 2 : aMark.SelectTable( nTab, sal_True );
4520 : }
4521 :
4522 2 : ScRange aSourceArea = rRange;
4523 2 : ScRange aDestArea = rRange;
4524 :
4525 :
4526 2 : switch (eDir)
4527 : {
4528 : case FILL_TO_BOTTOM:
4529 1 : aDestArea.aEnd.SetRow( sal::static_int_cast<SCROW>( aSourceArea.aEnd.Row() + nCount ) );
4530 1 : break;
4531 : case FILL_TO_TOP:
4532 0 : if (nCount > sal::static_int_cast<sal_uLong>( aSourceArea.aStart.Row() ))
4533 : {
4534 : OSL_FAIL("FillAuto: Row < 0");
4535 0 : nCount = aSourceArea.aStart.Row();
4536 : }
4537 0 : aDestArea.aStart.SetRow( sal::static_int_cast<SCROW>( aSourceArea.aStart.Row() - nCount ) );
4538 0 : break;
4539 : case FILL_TO_RIGHT:
4540 1 : aDestArea.aEnd.SetCol( sal::static_int_cast<SCCOL>( aSourceArea.aEnd.Col() + nCount ) );
4541 1 : break;
4542 : case FILL_TO_LEFT:
4543 0 : if (nCount > sal::static_int_cast<sal_uLong>( aSourceArea.aStart.Col() ))
4544 : {
4545 : OSL_FAIL("FillAuto: Col < 0");
4546 0 : nCount = aSourceArea.aStart.Col();
4547 : }
4548 0 : aDestArea.aStart.SetCol( sal::static_int_cast<SCCOL>( aSourceArea.aStart.Col() - nCount ) );
4549 0 : break;
4550 : default:
4551 : OSL_FAIL("Falsche Richtung bei FillAuto");
4552 0 : break;
4553 : }
4554 :
4555 : // Zellschutz testen
4556 : //! Quellbereich darf geschuetzt sein !!!
4557 : //! aber kein Matrixfragment enthalten !!!
4558 :
4559 2 : ScEditableTester aTester( pDoc, aDestArea );
4560 2 : if ( !aTester.IsEditable() )
4561 : {
4562 0 : if (!bApi)
4563 0 : rDocShell.ErrorMessage(aTester.GetMessageId());
4564 0 : return false;
4565 : }
4566 :
4567 2 : if ( pDoc->HasSelectedBlockMatrixFragment( nStartCol, nStartRow,
4568 2 : nEndCol, nEndRow, aMark ) )
4569 : {
4570 0 : if (!bApi)
4571 0 : rDocShell.ErrorMessage(STR_MATRIXFRAGMENTERR);
4572 0 : return false;
4573 : }
4574 :
4575 2 : WaitObject aWait( rDocShell.GetActiveDialogParent() );
4576 :
4577 2 : ScDocument* pUndoDoc = NULL;
4578 2 : if ( bRecord )
4579 : {
4580 2 : SCTAB nTabCount = pDoc->GetTableCount();
4581 2 : SCTAB nDestStartTab = aDestArea.aStart.Tab();
4582 :
4583 2 : pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
4584 2 : pUndoDoc->InitUndo( pDoc, nDestStartTab, nDestStartTab );
4585 2 : ScMarkData::iterator itr = aMark.begin(), itrEnd = aMark.end();
4586 4 : for (; itr != itrEnd && nTabCount; ++itr)
4587 2 : if (*itr != nDestStartTab)
4588 0 : pUndoDoc->AddUndoTab( *itr, *itr );
4589 :
4590 : // do not clone note captions in undo document
4591 : pDoc->CopyToDocument(
4592 2 : aDestArea.aStart.Col(), aDestArea.aStart.Row(), 0,
4593 2 : aDestArea.aEnd.Col(), aDestArea.aEnd.Row(), nTabCount-1,
4594 6 : IDF_AUTOFILL, false, pUndoDoc, &aMark );
4595 : }
4596 :
4597 : sal_uLong nProgCount;
4598 2 : if (eDir == FILL_TO_BOTTOM || eDir == FILL_TO_TOP)
4599 1 : nProgCount = aSourceArea.aEnd.Col() - aSourceArea.aStart.Col() + 1;
4600 : else
4601 1 : nProgCount = aSourceArea.aEnd.Row() - aSourceArea.aStart.Row() + 1;
4602 2 : nProgCount *= nCount;
4603 : ScProgress aProgress( pDoc->GetDocumentShell(),
4604 4 : ScGlobal::GetRscString(STR_FILL_SERIES_PROGRESS), nProgCount );
4605 :
4606 2 : pDoc->Fill( aSourceArea.aStart.Col(), aSourceArea.aStart.Row(),
4607 2 : aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), &aProgress,
4608 6 : aMark, nCount, eDir, eCmd, eDateCmd, fStep, fMax );
4609 :
4610 2 : AdjustRowHeight(aDestArea);
4611 :
4612 2 : if ( bRecord ) // Draw-Undo erst jetzt verfuegbar
4613 : {
4614 2 : rDocShell.GetUndoManager()->AddUndoAction(
4615 : new ScUndoAutoFill( &rDocShell, aDestArea, aSourceArea, pUndoDoc, aMark,
4616 2 : eDir, eCmd, eDateCmd, MAXDOUBLE, fStep, fMax) );
4617 : }
4618 :
4619 2 : rDocShell.PostPaintGridAll();
4620 2 : aModificator.SetDocumentModified();
4621 :
4622 2 : rRange = aDestArea; // Zielbereich zurueckgeben (zum Markieren)
4623 6 : return sal_True;
4624 : }
4625 :
4626 : //------------------------------------------------------------------------
4627 :
4628 6 : sal_Bool ScDocFunc::MergeCells( const ScCellMergeOption& rOption, sal_Bool bContents, sal_Bool bRecord, sal_Bool bApi )
4629 : {
4630 : using ::std::set;
4631 :
4632 6 : ScDocShellModificator aModificator( rDocShell );
4633 :
4634 6 : SCCOL nStartCol = rOption.mnStartCol;
4635 6 : SCROW nStartRow = rOption.mnStartRow;
4636 6 : SCCOL nEndCol = rOption.mnEndCol;
4637 6 : SCROW nEndRow = rOption.mnEndRow;
4638 6 : if ((nStartCol == nEndCol && nStartRow == nEndRow) || rOption.maTabs.empty())
4639 : {
4640 : // Nothing to do. Bail out quick.
4641 2 : return true;
4642 : }
4643 :
4644 4 : ScDocument* pDoc = rDocShell.GetDocument();
4645 4 : set<SCTAB>::const_iterator itrBeg = rOption.maTabs.begin(), itrEnd = rOption.maTabs.end();
4646 4 : SCTAB nTab1 = *itrBeg, nTab2 = *rOption.maTabs.rbegin();
4647 :
4648 4 : if (bRecord && !pDoc->IsUndoEnabled())
4649 0 : bRecord = false;
4650 :
4651 16 : for (set<SCTAB>::const_iterator itr = itrBeg; itr != itrEnd; ++itr)
4652 : {
4653 4 : ScEditableTester aTester( pDoc, *itr, nStartCol, nStartRow, nEndCol, nEndRow );
4654 4 : if (!aTester.IsEditable())
4655 : {
4656 0 : if (!bApi)
4657 0 : rDocShell.ErrorMessage(aTester.GetMessageId());
4658 0 : return false;
4659 : }
4660 :
4661 12 : if ( pDoc->HasAttrib( nStartCol, nStartRow, *itr, nEndCol, nEndRow, *itr,
4662 8 : HASATTR_MERGED | HASATTR_OVERLAPPED ) )
4663 : {
4664 : // "Zusammenfassen nicht verschachteln !"
4665 0 : if (!bApi)
4666 0 : rDocShell.ErrorMessage(STR_MSSG_MERGECELLS_0);
4667 0 : return false;
4668 : }
4669 : }
4670 :
4671 4 : ScDocument* pUndoDoc = NULL;
4672 4 : bool bNeedContentsUndo = false;
4673 8 : for (set<SCTAB>::const_iterator itr = itrBeg; itr != itrEnd; ++itr)
4674 : {
4675 4 : SCTAB nTab = *itr;
4676 4 : bool bNeedContents = bContents &&
4677 0 : ( !pDoc->IsBlockEmpty( nTab, nStartCol,nStartRow+1, nStartCol,nEndRow, true ) ||
4678 4 : !pDoc->IsBlockEmpty( nTab, nStartCol+1,nStartRow, nEndCol,nEndRow, true ) );
4679 :
4680 4 : if (bRecord)
4681 : {
4682 : // test if the range contains other notes which also implies that we need an undo document
4683 4 : bool bHasNotes = false;
4684 14 : for( ScAddress aPos( nStartCol, nStartRow, nTab ); !bHasNotes && (aPos.Col() <= nEndCol); aPos.IncCol() )
4685 47 : for( aPos.SetRow( nStartRow ); !bHasNotes && (aPos.Row() <= nEndRow); aPos.IncRow() )
4686 37 : bHasNotes = ((aPos.Col() != nStartCol) || (aPos.Row() != nStartRow)) && (pDoc->GetNotes( aPos.Tab() )->findByAddress(aPos) != 0);
4687 :
4688 4 : if (!pUndoDoc)
4689 : {
4690 4 : pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
4691 4 : pUndoDoc->InitUndo(pDoc, nTab1, nTab2);
4692 : }
4693 : // note captions are collected by drawing undo
4694 : pDoc->CopyToDocument( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab,
4695 4 : IDF_ALL|IDF_NOCAPTIONS, false, pUndoDoc );
4696 4 : if( bHasNotes )
4697 0 : pDoc->BeginDrawUndo();
4698 : }
4699 :
4700 4 : if (bNeedContents)
4701 0 : pDoc->DoMergeContents( nTab, nStartCol,nStartRow, nEndCol,nEndRow );
4702 4 : pDoc->DoMerge( nTab, nStartCol,nStartRow, nEndCol,nEndRow );
4703 :
4704 4 : if (rOption.mbCenter)
4705 : {
4706 0 : pDoc->ApplyAttr( nStartCol, nStartRow, nTab, SvxHorJustifyItem( SVX_HOR_JUSTIFY_CENTER, ATTR_HOR_JUSTIFY ) );
4707 0 : pDoc->ApplyAttr( nStartCol, nStartRow, nTab, SvxVerJustifyItem( SVX_VER_JUSTIFY_CENTER, ATTR_VER_JUSTIFY ) );
4708 : }
4709 :
4710 4 : if ( !AdjustRowHeight( ScRange( 0,nStartRow,nTab, MAXCOL,nEndRow,nTab ) ) )
4711 : rDocShell.PostPaint( nStartCol, nStartRow, nTab,
4712 3 : nEndCol, nEndRow, nTab, PAINT_GRID );
4713 4 : if (bNeedContents || rOption.mbCenter)
4714 : {
4715 0 : ScRange aRange(nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab);
4716 0 : pDoc->SetDirty(aRange);
4717 : }
4718 :
4719 4 : bNeedContentsUndo |= bNeedContents;
4720 : }
4721 :
4722 4 : if (pUndoDoc)
4723 : {
4724 4 : SdrUndoGroup* pDrawUndo = pDoc->GetDrawLayer() ? pDoc->GetDrawLayer()->GetCalcUndo() : NULL;
4725 4 : rDocShell.GetUndoManager()->AddUndoAction(
4726 4 : new ScUndoMerge(&rDocShell, rOption, bNeedContentsUndo, pUndoDoc, pDrawUndo) );
4727 : }
4728 :
4729 4 : aModificator.SetDocumentModified();
4730 :
4731 4 : SfxBindings* pBindings = rDocShell.GetViewBindings();
4732 4 : if (pBindings)
4733 : {
4734 3 : pBindings->Invalidate( FID_MERGE_ON );
4735 3 : pBindings->Invalidate( FID_MERGE_OFF );
4736 3 : pBindings->Invalidate( FID_MERGE_TOGGLE );
4737 : }
4738 :
4739 4 : return sal_True;
4740 : }
4741 :
4742 1 : sal_Bool ScDocFunc::UnmergeCells( const ScRange& rRange, sal_Bool bRecord )
4743 : {
4744 1 : ScCellMergeOption aOption(rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row());
4745 1 : SCTAB nTab1 = rRange.aStart.Tab(), nTab2 = rRange.aEnd.Tab();
4746 2 : for (SCTAB i = nTab1; i <= nTab2; ++i)
4747 1 : aOption.maTabs.insert(i);
4748 :
4749 1 : return UnmergeCells(aOption, bRecord);
4750 : }
4751 :
4752 6 : bool ScDocFunc::UnmergeCells( const ScCellMergeOption& rOption, sal_Bool bRecord )
4753 : {
4754 : using ::std::set;
4755 :
4756 6 : if (rOption.maTabs.empty())
4757 : // Nothing to unmerge.
4758 0 : return true;
4759 :
4760 6 : ScDocShellModificator aModificator( rDocShell );
4761 6 : ScDocument* pDoc = rDocShell.GetDocument();
4762 :
4763 6 : if (bRecord && !pDoc->IsUndoEnabled())
4764 0 : bRecord = false;
4765 :
4766 6 : ScDocument* pUndoDoc = NULL;
4767 12 : for (set<SCTAB>::const_iterator itr = rOption.maTabs.begin(), itrEnd = rOption.maTabs.end();
4768 : itr != itrEnd; ++itr)
4769 : {
4770 6 : SCTAB nTab = *itr;
4771 6 : ScRange aRange = rOption.getSingleRange(nTab);
4772 6 : if ( !pDoc->HasAttrib(aRange, HASATTR_MERGED) )
4773 2 : continue;
4774 :
4775 4 : ScRange aExtended = aRange;
4776 4 : pDoc->ExtendMerge(aExtended);
4777 4 : ScRange aRefresh = aExtended;
4778 4 : pDoc->ExtendOverlapped(aRefresh);
4779 :
4780 4 : if (bRecord)
4781 : {
4782 4 : if (!pUndoDoc)
4783 : {
4784 4 : pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
4785 4 : pUndoDoc->InitUndo(pDoc, *rOption.maTabs.begin(), *rOption.maTabs.rbegin());
4786 : }
4787 4 : pDoc->CopyToDocument(aExtended, IDF_ATTRIB, false, pUndoDoc);
4788 : }
4789 :
4790 4 : const SfxPoolItem& rDefAttr = pDoc->GetPool()->GetDefaultItem( ATTR_MERGE );
4791 4 : ScPatternAttr aPattern( pDoc->GetPool() );
4792 4 : aPattern.GetItemSet().Put( rDefAttr );
4793 4 : pDoc->ApplyPatternAreaTab( aRange.aStart.Col(), aRange.aStart.Row(),
4794 4 : aRange.aEnd.Col(), aRange.aEnd.Row(), nTab,
4795 12 : aPattern );
4796 :
4797 4 : pDoc->RemoveFlagsTab( aExtended.aStart.Col(), aExtended.aStart.Row(),
4798 4 : aExtended.aEnd.Col(), aExtended.aEnd.Row(), nTab,
4799 12 : SC_MF_HOR | SC_MF_VER );
4800 :
4801 4 : pDoc->ExtendMerge( aRefresh, sal_True );
4802 :
4803 4 : if ( !AdjustRowHeight( aExtended ) )
4804 3 : rDocShell.PostPaint( aExtended, PAINT_GRID );
4805 4 : }
4806 :
4807 6 : if (bRecord)
4808 : {
4809 6 : rDocShell.GetUndoManager()->AddUndoAction(
4810 6 : new ScUndoRemoveMerge( &rDocShell, rOption, pUndoDoc ) );
4811 : }
4812 6 : aModificator.SetDocumentModified();
4813 :
4814 6 : return sal_True;
4815 : }
4816 :
4817 : //------------------------------------------------------------------------
4818 :
4819 2 : bool ScDocFunc::ModifyRangeNames( const ScRangeName& rNewRanges, SCTAB nTab )
4820 : {
4821 2 : return SetNewRangeNames( new ScRangeName(rNewRanges), true, nTab );
4822 : }
4823 :
4824 31 : bool ScDocFunc::SetNewRangeNames( ScRangeName* pNewRanges, bool bModifyDoc, SCTAB nTab ) // takes ownership of pNewRanges
4825 : {
4826 31 : ScDocShellModificator aModificator( rDocShell );
4827 :
4828 : OSL_ENSURE( pNewRanges, "pNewRanges is 0" );
4829 31 : ScDocument* pDoc = rDocShell.GetDocument();
4830 31 : bool bUndo(pDoc->IsUndoEnabled());
4831 :
4832 31 : if (bUndo)
4833 : {
4834 : ScRangeName* pOld;
4835 31 : if (nTab >=0)
4836 : {
4837 0 : pOld = pDoc->GetRangeName(nTab);
4838 : }
4839 : else
4840 : {
4841 31 : pOld = pDoc->GetRangeName();
4842 : }
4843 31 : ScRangeName* pUndoRanges = new ScRangeName(*pOld);
4844 31 : ScRangeName* pRedoRanges = new ScRangeName(*pNewRanges);
4845 31 : rDocShell.GetUndoManager()->AddUndoAction(
4846 31 : new ScUndoRangeNames( &rDocShell, pUndoRanges, pRedoRanges, nTab ) );
4847 : }
4848 :
4849 : // #i55926# While loading XML, formula cells only have a single string token,
4850 : // so CompileNameFormula would never find any name (index) tokens, and would
4851 : // unnecessarily loop through all cells.
4852 31 : sal_Bool bCompile = ( !pDoc->IsImportingXML() && pDoc->GetNamedRangesLockCount() == 0 );
4853 :
4854 31 : if ( bCompile )
4855 31 : pDoc->CompileNameFormula( sal_True ); // CreateFormulaString
4856 31 : if (nTab >= 0)
4857 0 : pDoc->SetRangeName( nTab, pNewRanges ); // takes ownership
4858 : else
4859 31 : pDoc->SetRangeName( pNewRanges ); // takes ownership
4860 31 : if ( bCompile )
4861 31 : pDoc->CompileNameFormula( false ); // CompileFormulaString
4862 :
4863 31 : if (bModifyDoc)
4864 : {
4865 31 : aModificator.SetDocumentModified();
4866 31 : SFX_APP()->Broadcast( SfxSimpleHint(SC_HINT_AREAS_CHANGED) );
4867 : }
4868 :
4869 31 : return true;
4870 : }
4871 :
4872 0 : void ScDocFunc::ModifyAllRangeNames( const boost::ptr_map<OUString, ScRangeName>& rRangeMap )
4873 : {
4874 0 : ScDocShellModificator aModificator(rDocShell);
4875 0 : ScDocument* pDoc = rDocShell.GetDocument();
4876 :
4877 0 : if (pDoc->IsUndoEnabled())
4878 : {
4879 0 : std::map<OUString, ScRangeName*> aOldRangeMap;
4880 0 : pDoc->GetRangeNameMap(aOldRangeMap);
4881 0 : rDocShell.GetUndoManager()->AddUndoAction(
4882 0 : new ScUndoAllRangeNames(&rDocShell, aOldRangeMap, rRangeMap));
4883 : }
4884 :
4885 0 : pDoc->CompileNameFormula(true);
4886 :
4887 : // set all range names
4888 0 : pDoc->SetAllRangeNames(rRangeMap);
4889 :
4890 0 : pDoc->CompileNameFormula(false);
4891 :
4892 0 : aModificator.SetDocumentModified();
4893 0 : SFX_APP()->Broadcast(SfxSimpleHint(SC_HINT_AREAS_CHANGED));
4894 0 : }
4895 :
4896 : //------------------------------------------------------------------------
4897 :
4898 8 : void ScDocFunc::CreateOneName( ScRangeName& rList,
4899 : SCCOL nPosX, SCROW nPosY, SCTAB nTab,
4900 : SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
4901 : sal_Bool& rCancel, sal_Bool bApi )
4902 : {
4903 8 : if (rCancel)
4904 8 : return;
4905 :
4906 8 : ScDocument* pDoc = rDocShell.GetDocument();
4907 8 : if (!pDoc->HasValueData( nPosX, nPosY, nTab ))
4908 : {
4909 8 : String aName = pDoc->GetString(nPosX, nPosY, nTab);
4910 8 : ScRangeData::MakeValidName(aName);
4911 8 : if (aName.Len())
4912 : {
4913 6 : String aContent;
4914 6 : ScRange( nX1, nY1, nTab, nX2, nY2, nTab ).Format( aContent, SCR_ABS_3D, pDoc );
4915 :
4916 6 : bool bInsert = false;
4917 6 : ScRangeData* pOld = rList.findByUpperName(ScGlobal::pCharClass->uppercase(aName));
4918 6 : if (pOld)
4919 : {
4920 0 : String aOldStr;
4921 0 : pOld->GetSymbol( aOldStr );
4922 0 : if (aOldStr != aContent)
4923 : {
4924 0 : if (bApi)
4925 0 : bInsert = sal_True; // per API nicht nachfragen
4926 : else
4927 : {
4928 0 : String aTemplate = ScGlobal::GetRscString( STR_CREATENAME_REPLACE );
4929 :
4930 0 : String aMessage = aTemplate.GetToken( 0, '#' );
4931 0 : aMessage += aName;
4932 0 : aMessage += aTemplate.GetToken( 1, '#' );
4933 :
4934 : short nResult = QueryBox( rDocShell.GetActiveDialogParent(),
4935 : WinBits(WB_YES_NO_CANCEL | WB_DEF_YES),
4936 0 : aMessage ).Execute();
4937 0 : if ( nResult == RET_YES )
4938 : {
4939 0 : rList.erase(*pOld);
4940 0 : bInsert = true;
4941 : }
4942 0 : else if ( nResult == RET_CANCEL )
4943 0 : rCancel = sal_True;
4944 : }
4945 0 : }
4946 : }
4947 : else
4948 6 : bInsert = true;
4949 :
4950 6 : if (bInsert)
4951 : {
4952 : ScRangeData* pData = new ScRangeData( pDoc, aName, aContent,
4953 6 : ScAddress( nPosX, nPosY, nTab));
4954 6 : if (!rList.insert(pData))
4955 : {
4956 : OSL_FAIL("nanu?");
4957 : }
4958 6 : }
4959 8 : }
4960 : }
4961 : }
4962 :
4963 2 : sal_Bool ScDocFunc::CreateNames( const ScRange& rRange, sal_uInt16 nFlags, sal_Bool bApi, SCTAB aTab )
4964 : {
4965 2 : if (!nFlags)
4966 0 : return false; // war nix
4967 :
4968 2 : ScDocShellModificator aModificator( rDocShell );
4969 :
4970 2 : sal_Bool bDone = false;
4971 2 : SCCOL nStartCol = rRange.aStart.Col();
4972 2 : SCROW nStartRow = rRange.aStart.Row();
4973 2 : SCCOL nEndCol = rRange.aEnd.Col();
4974 2 : SCROW nEndRow = rRange.aEnd.Row();
4975 2 : SCTAB nTab = rRange.aStart.Tab();
4976 : OSL_ENSURE(rRange.aEnd.Tab() == nTab, "CreateNames: mehrere Tabellen geht nicht");
4977 :
4978 2 : sal_Bool bValid = sal_True;
4979 2 : if ( nFlags & ( NAME_TOP | NAME_BOTTOM ) )
4980 1 : if ( nStartRow == nEndRow )
4981 0 : bValid = false;
4982 2 : if ( nFlags & ( NAME_LEFT | NAME_RIGHT ) )
4983 1 : if ( nStartCol == nEndCol )
4984 0 : bValid = false;
4985 :
4986 2 : if (bValid)
4987 : {
4988 2 : ScDocument* pDoc = rDocShell.GetDocument();
4989 : ScRangeName* pNames;
4990 2 : if (aTab >=0)
4991 0 : pNames = pDoc->GetRangeName(nTab);
4992 : else
4993 2 : pNames = pDoc->GetRangeName();
4994 :
4995 2 : if (!pNames)
4996 0 : return false; // soll nicht sein
4997 2 : ScRangeName aNewRanges( *pNames );
4998 :
4999 2 : sal_Bool bTop = ( ( nFlags & NAME_TOP ) != 0 );
5000 2 : sal_Bool bLeft = ( ( nFlags & NAME_LEFT ) != 0 );
5001 2 : sal_Bool bBottom = ( ( nFlags & NAME_BOTTOM ) != 0 );
5002 2 : sal_Bool bRight = ( ( nFlags & NAME_RIGHT ) != 0 );
5003 :
5004 2 : SCCOL nContX1 = nStartCol;
5005 2 : SCROW nContY1 = nStartRow;
5006 2 : SCCOL nContX2 = nEndCol;
5007 2 : SCROW nContY2 = nEndRow;
5008 :
5009 2 : if ( bTop )
5010 1 : ++nContY1;
5011 2 : if ( bLeft )
5012 1 : ++nContX1;
5013 2 : if ( bBottom )
5014 0 : --nContY2;
5015 2 : if ( bRight )
5016 0 : --nContX2;
5017 :
5018 2 : sal_Bool bCancel = false;
5019 : SCCOL i;
5020 : SCROW j;
5021 :
5022 2 : if ( bTop )
5023 5 : for (i=nContX1; i<=nContX2; i++)
5024 4 : CreateOneName( aNewRanges, i,nStartRow,nTab, i,nContY1,i,nContY2, bCancel, bApi );
5025 2 : if ( bLeft )
5026 5 : for (j=nContY1; j<=nContY2; j++)
5027 4 : CreateOneName( aNewRanges, nStartCol,j,nTab, nContX1,j,nContX2,j, bCancel, bApi );
5028 2 : if ( bBottom )
5029 0 : for (i=nContX1; i<=nContX2; i++)
5030 0 : CreateOneName( aNewRanges, i,nEndRow,nTab, i,nContY1,i,nContY2, bCancel, bApi );
5031 2 : if ( bRight )
5032 0 : for (j=nContY1; j<=nContY2; j++)
5033 0 : CreateOneName( aNewRanges, nEndCol,j,nTab, nContX1,j,nContX2,j, bCancel, bApi );
5034 :
5035 2 : if ( bTop && bLeft )
5036 0 : CreateOneName( aNewRanges, nStartCol,nStartRow,nTab, nContX1,nContY1,nContX2,nContY2, bCancel, bApi );
5037 2 : if ( bTop && bRight )
5038 0 : CreateOneName( aNewRanges, nEndCol,nStartRow,nTab, nContX1,nContY1,nContX2,nContY2, bCancel, bApi );
5039 2 : if ( bBottom && bLeft )
5040 0 : CreateOneName( aNewRanges, nStartCol,nEndRow,nTab, nContX1,nContY1,nContX2,nContY2, bCancel, bApi );
5041 2 : if ( bBottom && bRight )
5042 0 : CreateOneName( aNewRanges, nEndCol,nEndRow,nTab, nContX1,nContY1,nContX2,nContY2, bCancel, bApi );
5043 :
5044 2 : bDone = ModifyRangeNames( aNewRanges, aTab );
5045 :
5046 2 : aModificator.SetDocumentModified();
5047 2 : SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
5048 : }
5049 :
5050 2 : return bDone;
5051 : }
5052 :
5053 : //------------------------------------------------------------------------
5054 :
5055 4 : sal_Bool ScDocFunc::InsertNameList( const ScAddress& rStartPos, sal_Bool bApi )
5056 : {
5057 4 : ScDocShellModificator aModificator( rDocShell );
5058 :
5059 4 : sal_Bool bDone = false;
5060 4 : ScDocument* pDoc = rDocShell.GetDocument();
5061 4 : const bool bRecord = pDoc->IsUndoEnabled();
5062 4 : SCTAB nTab = rStartPos.Tab();
5063 4 : ScDocument* pUndoDoc = NULL;
5064 :
5065 : //local names have higher priority than global names
5066 4 : ScRangeName* pLocalList = pDoc->GetRangeName(nTab);
5067 4 : sal_uInt16 nValidCount = 0;
5068 4 : ScRangeName::iterator itrLocalBeg = pLocalList->begin(), itrLocalEnd = pLocalList->end();
5069 4 : for (ScRangeName::iterator itr = itrLocalBeg; itr != itrLocalEnd; ++itr)
5070 : {
5071 0 : const ScRangeData& r = *itr->second;
5072 0 : if (!r.HasType(RT_DATABASE) && !r.HasType(RT_SHARED))
5073 0 : ++nValidCount;
5074 : }
5075 4 : ScRangeName* pList = pDoc->GetRangeName();
5076 4 : ScRangeName::iterator itrBeg = pList->begin(), itrEnd = pList->end();
5077 22 : for (ScRangeName::iterator itr = itrBeg; itr != itrEnd; ++itr)
5078 : {
5079 18 : const ScRangeData& r = *itr->second;
5080 18 : if (!r.HasType(RT_DATABASE) && !r.HasType(RT_SHARED) && !pLocalList->findByUpperName(r.GetUpperName()))
5081 18 : ++nValidCount;
5082 : }
5083 :
5084 4 : if (nValidCount)
5085 : {
5086 4 : SCCOL nStartCol = rStartPos.Col();
5087 4 : SCROW nStartRow = rStartPos.Row();
5088 4 : SCCOL nEndCol = nStartCol + 1;
5089 4 : SCROW nEndRow = nStartRow + static_cast<SCROW>(nValidCount) - 1;
5090 :
5091 4 : ScEditableTester aTester( pDoc, nTab, nStartCol,nStartRow, nEndCol,nEndRow );
5092 4 : if (aTester.IsEditable())
5093 : {
5094 4 : if (bRecord)
5095 : {
5096 4 : pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
5097 4 : pUndoDoc->InitUndo( pDoc, nTab, nTab );
5098 : pDoc->CopyToDocument( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab,
5099 4 : IDF_ALL, false, pUndoDoc );
5100 :
5101 4 : pDoc->BeginDrawUndo(); // wegen Hoehenanpassung
5102 : }
5103 :
5104 4 : ScRangeData** ppSortArray = new ScRangeData* [ nValidCount ];
5105 4 : sal_uInt16 j = 0;
5106 4 : for (ScRangeName::iterator itr = itrLocalBeg; itr != itrLocalEnd; ++itr)
5107 : {
5108 0 : ScRangeData& r = *itr->second;
5109 0 : if (!r.HasType(RT_DATABASE) && !r.HasType(RT_SHARED))
5110 0 : ppSortArray[j++] = &r;
5111 : }
5112 22 : for (ScRangeName::iterator itr = itrBeg; itr != itrEnd; ++itr)
5113 : {
5114 18 : ScRangeData& r = *itr->second;
5115 18 : if (!r.HasType(RT_DATABASE) && !r.HasType(RT_SHARED) && !pLocalList->findByUpperName(itr->first))
5116 18 : ppSortArray[j++] = &r;
5117 : }
5118 : #ifndef ICC
5119 : qsort( (void*)ppSortArray, nValidCount, sizeof(ScRangeData*),
5120 4 : &ScRangeData_QsortNameCompare );
5121 : #else
5122 : qsort( (void*)ppSortArray, nValidCount, sizeof(ScRangeData*),
5123 : ICCQsortNameCompare );
5124 : #endif
5125 4 : OUString aName;
5126 8 : OUStringBuffer aContent;
5127 8 : String aFormula;
5128 4 : SCROW nOutRow = nStartRow;
5129 22 : for (j=0; j<nValidCount; j++)
5130 : {
5131 18 : ScRangeData* pData = ppSortArray[j];
5132 18 : pData->GetName(aName);
5133 : // relative Referenzen Excel-konform auf die linke Spalte anpassen:
5134 18 : pData->UpdateSymbol(aContent, ScAddress( nStartCol, nOutRow, nTab ));
5135 18 : aFormula = '=';
5136 18 : aFormula += aContent.toString();
5137 18 : ScSetStringParam aParam;
5138 18 : aParam.setTextInput();
5139 18 : pDoc->SetString(ScAddress(nStartCol,nOutRow,nTab), aName, &aParam);
5140 18 : pDoc->SetString(ScAddress(nEndCol,nOutRow,nTab), aFormula, &aParam);
5141 18 : ++nOutRow;
5142 : }
5143 :
5144 4 : delete [] ppSortArray;
5145 :
5146 4 : if (bRecord)
5147 : {
5148 4 : ScDocument* pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
5149 4 : pRedoDoc->InitUndo( pDoc, nTab, nTab );
5150 : pDoc->CopyToDocument( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab,
5151 4 : IDF_ALL, false, pRedoDoc );
5152 :
5153 4 : rDocShell.GetUndoManager()->AddUndoAction(
5154 : new ScUndoListNames( &rDocShell,
5155 : ScRange( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab ),
5156 4 : pUndoDoc, pRedoDoc ) );
5157 : }
5158 :
5159 4 : if (!AdjustRowHeight(ScRange(0,nStartRow,nTab,MAXCOL,nEndRow,nTab)))
5160 0 : rDocShell.PostPaint( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab, PAINT_GRID );
5161 :
5162 4 : aModificator.SetDocumentModified();
5163 8 : bDone = sal_True;
5164 : }
5165 0 : else if (!bApi)
5166 0 : rDocShell.ErrorMessage(aTester.GetMessageId());
5167 : }
5168 4 : return bDone;
5169 : }
5170 :
5171 : //------------------------------------------------------------------------
5172 :
5173 0 : sal_Bool ScDocFunc::ResizeMatrix( const ScRange& rOldRange, const ScAddress& rNewEnd, sal_Bool bApi )
5174 : {
5175 0 : ScDocument* pDoc = rDocShell.GetDocument();
5176 0 : SCCOL nStartCol = rOldRange.aStart.Col();
5177 0 : SCROW nStartRow = rOldRange.aStart.Row();
5178 0 : SCTAB nTab = rOldRange.aStart.Tab();
5179 :
5180 0 : bool bUndo(pDoc->IsUndoEnabled());
5181 :
5182 0 : sal_Bool bRet = false;
5183 :
5184 0 : String aFormula;
5185 0 : pDoc->GetFormula( nStartCol, nStartRow, nTab, aFormula );
5186 0 : if ( aFormula.GetChar(0) == '{' && aFormula.GetChar(aFormula.Len()-1) == '}' )
5187 : {
5188 0 : String aUndo = ScGlobal::GetRscString( STR_UNDO_RESIZEMATRIX );
5189 0 : if (bUndo)
5190 0 : rDocShell.GetUndoManager()->EnterListAction( aUndo, aUndo );
5191 :
5192 0 : aFormula.Erase(0,1);
5193 0 : aFormula.Erase(aFormula.Len()-1,1);
5194 :
5195 0 : ScMarkData aMark;
5196 0 : aMark.SetMarkArea( rOldRange );
5197 0 : aMark.SelectTable( nTab, sal_True );
5198 0 : ScRange aNewRange( rOldRange.aStart, rNewEnd );
5199 :
5200 0 : if ( DeleteContents( aMark, IDF_CONTENTS, sal_True, bApi ) )
5201 : {
5202 : // GRAM_PODF_A1 for API compatibility.
5203 0 : bRet = EnterMatrix( aNewRange, &aMark, NULL, aFormula, bApi, false, EMPTY_STRING, formula::FormulaGrammar::GRAM_PODF_A1 );
5204 0 : if (!bRet)
5205 : {
5206 : // versuchen, alten Zustand wiederherzustellen
5207 0 : EnterMatrix( rOldRange, &aMark, NULL, aFormula, bApi, false, EMPTY_STRING, formula::FormulaGrammar::GRAM_PODF_A1 );
5208 : }
5209 : }
5210 :
5211 0 : if (bUndo)
5212 0 : rDocShell.GetUndoManager()->LeaveListAction();
5213 : }
5214 :
5215 0 : return bRet;
5216 : }
5217 :
5218 : //------------------------------------------------------------------------
5219 :
5220 16 : sal_Bool ScDocFunc::InsertAreaLink( const String& rFile, const String& rFilter,
5221 : const String& rOptions, const String& rSource,
5222 : const ScRange& rDestRange, sal_uLong nRefresh,
5223 : sal_Bool bFitBlock, sal_Bool bApi )
5224 : {
5225 16 : ScDocument* pDoc = rDocShell.GetDocument();
5226 16 : sal_Bool bUndo (pDoc->IsUndoEnabled());
5227 :
5228 16 : sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
5229 :
5230 : // #i52120# if other area links exist at the same start position,
5231 : // remove them first (file format specifies only one link definition
5232 : // for a cell)
5233 :
5234 16 : sal_uInt16 nLinkCount = pLinkManager->GetLinks().size();
5235 16 : sal_uInt16 nRemoved = 0;
5236 16 : sal_uInt16 nLinkPos = 0;
5237 32 : while (nLinkPos<nLinkCount)
5238 : {
5239 0 : ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[nLinkPos];
5240 0 : if ( pBase->ISA(ScAreaLink) &&
5241 0 : static_cast<ScAreaLink*>(pBase)->GetDestArea().aStart == rDestRange.aStart )
5242 : {
5243 0 : if ( bUndo )
5244 : {
5245 0 : if ( !nRemoved )
5246 : {
5247 : // group all remove and the insert action
5248 0 : String aUndo = ScGlobal::GetRscString( STR_UNDO_INSERTAREALINK );
5249 0 : rDocShell.GetUndoManager()->EnterListAction( aUndo, aUndo );
5250 : }
5251 :
5252 0 : ScAreaLink* pOldArea = static_cast<ScAreaLink*>(pBase);
5253 0 : rDocShell.GetUndoManager()->AddUndoAction(
5254 : new ScUndoRemoveAreaLink( &rDocShell,
5255 : pOldArea->GetFile(), pOldArea->GetFilter(), pOldArea->GetOptions(),
5256 0 : pOldArea->GetSource(), pOldArea->GetDestArea(), pOldArea->GetRefreshDelay() ) );
5257 : }
5258 0 : pLinkManager->Remove( pBase );
5259 0 : nLinkCount = pLinkManager->GetLinks().size();
5260 0 : ++nRemoved;
5261 : }
5262 : else
5263 0 : ++nLinkPos;
5264 : }
5265 :
5266 16 : OUString aFilterName = rFilter;
5267 32 : OUString aNewOptions = rOptions;
5268 16 : if (aFilterName.isEmpty())
5269 3 : ScDocumentLoader::GetFilterName( rFile, aFilterName, aNewOptions, true, !bApi );
5270 :
5271 : // remove application prefix from filter name here, so the filter options
5272 : // aren't reset when the filter name is changed in ScAreaLink::DataChanged
5273 16 : ScDocumentLoader::RemoveAppPrefix( aFilterName );
5274 :
5275 : ScAreaLink* pLink = new ScAreaLink( &rDocShell, rFile, aFilterName,
5276 16 : aNewOptions, rSource, rDestRange, nRefresh );
5277 32 : String aTmp = aFilterName;
5278 16 : pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, rFile, &aTmp, &rSource );
5279 :
5280 : // Undo fuer den leeren Link
5281 :
5282 16 : if (bUndo)
5283 : {
5284 16 : rDocShell.GetUndoManager()->AddUndoAction( new ScUndoInsertAreaLink( &rDocShell,
5285 : rFile, aFilterName, aNewOptions,
5286 16 : rSource, rDestRange, nRefresh ) );
5287 16 : if ( nRemoved )
5288 0 : rDocShell.GetUndoManager()->LeaveListAction(); // undo for link update is still separate
5289 : }
5290 :
5291 : // Update hat sein eigenes Undo
5292 16 : if (pDoc->IsExecuteLinkEnabled())
5293 : {
5294 16 : pLink->SetDoInsert(bFitBlock); // beim ersten Update ggf. nichts einfuegen
5295 16 : pLink->Update(); // kein SetInCreate -> Update ausfuehren
5296 : }
5297 16 : pLink->SetDoInsert(sal_True); // Default = sal_True
5298 :
5299 16 : SfxBindings* pBindings = rDocShell.GetViewBindings();
5300 16 : if (pBindings)
5301 16 : pBindings->Invalidate( SID_LINKS );
5302 :
5303 16 : SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) ); // Navigator
5304 :
5305 32 : return sal_True;
5306 : }
5307 :
5308 : namespace {
5309 :
5310 0 : void RemoveCondFormatAttributes(ScDocument* pDoc, const ScConditionalFormat* pFormat, SCTAB nTab)
5311 : {
5312 0 : const ScRangeList& rRangeList = pFormat->GetRange();
5313 0 : pDoc->RemoveCondFormatData( rRangeList, nTab, pFormat->GetKey() );
5314 0 : }
5315 :
5316 8 : void SetConditionalFormatAttributes(ScDocument* pDoc, const ScRangeList& rRanges, sal_uLong nIndex, SCTAB nTab)
5317 : {
5318 8 : pDoc->AddCondFormatData( rRanges, nTab, nIndex );
5319 8 : }
5320 :
5321 : }
5322 :
5323 8 : void ScDocFunc::ReplaceConditionalFormat( sal_uLong nOldFormat, ScConditionalFormat* pFormat, SCTAB nTab, const ScRangeList& rRanges )
5324 : {
5325 8 : ScDocShellModificator aModificator(rDocShell);
5326 8 : ScDocument* pDoc = rDocShell.GetDocument();
5327 8 : if(pDoc->IsTabProtected(nTab))
5328 8 : return;
5329 :
5330 16 : boost::scoped_ptr<ScRange> pRepaintRange;
5331 8 : if(nOldFormat)
5332 : {
5333 0 : ScConditionalFormat* pOldFormat = pDoc->GetCondFormList(nTab)->GetFormat(nOldFormat);
5334 0 : if(pOldFormat)
5335 : {
5336 0 : pRepaintRange.reset(new ScRange( pOldFormat->GetRange().Combine() ));
5337 0 : RemoveCondFormatAttributes(pDoc, pOldFormat, nTab);
5338 : }
5339 :
5340 0 : pDoc->DeleteConditionalFormat(nOldFormat, nTab);
5341 0 : pDoc->SetStreamValid(nTab, false);
5342 : }
5343 8 : if(pFormat)
5344 : {
5345 8 : if(pRepaintRange)
5346 0 : pRepaintRange->ExtendTo(rRanges.Combine());
5347 : else
5348 8 : pRepaintRange.reset(new ScRange(rRanges.Combine()));
5349 :
5350 8 : sal_uLong nIndex = pDoc->AddCondFormat(pFormat, nTab);
5351 :
5352 8 : SetConditionalFormatAttributes(pDoc, rRanges, nIndex, nTab);
5353 8 : pDoc->SetStreamValid(nTab, false);
5354 : }
5355 :
5356 8 : if(pRepaintRange)
5357 8 : rDocShell.PostPaint(*pRepaintRange, PAINT_GRID);
5358 :
5359 8 : aModificator.SetDocumentModified();
5360 16 : SFX_APP()->Broadcast(SfxSimpleHint(SC_HINT_AREAS_CHANGED));
5361 : }
5362 :
5363 0 : void ScDocFunc::SetConditionalFormatList( ScConditionalFormatList* pList, SCTAB nTab )
5364 : {
5365 0 : ScDocShellModificator aModificator(rDocShell);
5366 0 : ScDocument* pDoc = rDocShell.GetDocument();
5367 0 : if(pDoc->IsTabProtected(nTab))
5368 0 : return;
5369 :
5370 : // first remove all old entries
5371 0 : ScConditionalFormatList* pOldList = pDoc->GetCondFormList(nTab);
5372 0 : for(ScConditionalFormatList::const_iterator itr = pOldList->begin(), itrEnd = pOldList->end(); itr != itrEnd; ++itr)
5373 : {
5374 0 : RemoveCondFormatAttributes(pDoc, &(*itr), nTab);
5375 : }
5376 :
5377 : // then set new entries
5378 0 : for(ScConditionalFormatList::iterator itr = pList->begin(); itr != pList->end(); ++itr)
5379 : {
5380 0 : sal_uLong nIndex = itr->GetKey();
5381 0 : const ScRangeList& rRange = itr->GetRange();
5382 0 : SetConditionalFormatAttributes(pDoc, rRange, nIndex, nTab);
5383 : }
5384 :
5385 0 : pDoc->SetCondFormList(pList, nTab);
5386 0 : rDocShell.PostPaintGridAll();
5387 :
5388 0 : pDoc->SetStreamValid(nTab, false);
5389 0 : aModificator.SetDocumentModified();
5390 0 : SFX_APP()->Broadcast(SfxSimpleHint(SC_HINT_AREAS_CHANGED));
5391 : }
5392 :
5393 0 : void ScDocFunc::EnterListAction( sal_uInt16 nNameResId )
5394 : {
5395 0 : String aUndo( ScGlobal::GetRscString( nNameResId ) );
5396 0 : rDocShell.GetUndoManager()->EnterListAction( aUndo, aUndo );
5397 0 : }
5398 :
5399 0 : void ScDocFunc::EndListAction()
5400 : {
5401 0 : rDocShell.GetUndoManager()->LeaveListAction();
5402 93 : }
5403 :
5404 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|