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