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