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