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