1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "scitems.hxx"
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>
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>
36 #include "docfunc.hxx"
40 #include "arealink.hxx"
42 #include "dociter.hxx"
43 #include "autoform.hxx"
44 #include "formulacell.hxx"
45 #include "cellmergeoption.hxx"
46 #include "detdata.hxx"
47 #include "detfunc.hxx"
48 #include "docpool.hxx"
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"
72 #include "inputhdl.hxx"
73 #include "inputwin.hxx"
74 #include "editable.hxx"
75 #include "compiler.hxx"
76 #include "scui_def.hxx"
77 #include "tabprotection.hxx"
78 #include "clipparam.hxx"
79 #include "externalrefmgr.hxx"
80 #include "undorangename.hxx"
81 #include "progress.hxx"
82 #include "dpobject.hxx"
83 #include "stringutil.hxx"
84 #include "cellvalue.hxx"
85 #include "tokenarray.hxx"
88 #include <basic/basmgr.hxx>
89 #include <boost/scoped_ptr.hpp>
93 using namespace com::sun::star
;
94 using ::com::sun::star::uno::Sequence
;
98 // STATIC DATA -----------------------------------------------------------
100 //========================================================================
102 IMPL_LINK( ScDocFunc
, NotifyDrawUndo
, SdrUndoAction
*, pUndoAction
)
104 // #i101118# if drawing layer collects the undo actions, add it there
105 ScDrawLayer
* pDrawLayer
= rDocShell
.GetDocument()->GetDrawLayer();
106 if( pDrawLayer
&& pDrawLayer
->IsRecording() )
107 pDrawLayer
->AddCalcUndo( pUndoAction
);
109 rDocShell
.GetUndoManager()->AddUndoAction( new ScUndoDraw( pUndoAction
, &rDocShell
) );
110 rDocShell
.SetDrawModified();
112 // the affected sheet isn't known, so all stream positions are invalidated
113 ScDocument
* pDoc
= rDocShell
.GetDocument();
114 SCTAB nTabCount
= pDoc
->GetTableCount();
115 for (SCTAB nTab
=0; nTab
<nTabCount
; nTab
++)
116 if (pDoc
->IsStreamValid(nTab
))
117 pDoc
->SetStreamValid(nTab
, false);
122 //------------------------------------------------------------------------
124 // Zeile ueber dem Range painten (fuer Linien nach AdjustRowHeight)
126 static void lcl_PaintAbove( ScDocShell
& rDocShell
, const ScRange
& rRange
)
128 SCROW nRow
= rRange
.aStart
.Row();
131 SCTAB nTab
= rRange
.aStart
.Tab(); //! alle?
133 rDocShell
.PostPaint( ScRange(0,nRow
,nTab
, MAXCOL
,nRow
,nTab
), PAINT_GRID
);
137 //------------------------------------------------------------------------
139 sal_Bool
ScDocFunc::AdjustRowHeight( const ScRange
& rRange
, sal_Bool bPaint
)
141 ScDocument
* pDoc
= rDocShell
.GetDocument();
142 if ( pDoc
->IsImportingXML() )
144 // for XML import, all row heights are updated together after importing
147 if ( !pDoc
->IsAdjustHeightEnabled() )
152 SCTAB nTab
= rRange
.aStart
.Tab();
153 SCROW nStartRow
= rRange
.aStart
.Row();
154 SCROW nEndRow
= rRange
.aEnd
.Row();
156 ScSizeDeviceProvider
aProv( &rDocShell
);
159 sal_Bool bChanged
= pDoc
->SetOptimalHeight( nStartRow
, nEndRow
, nTab
, 0, aProv
.GetDevice(),
160 aProv
.GetPPTX(), aProv
.GetPPTY(), aOne
, aOne
, false );
162 if ( bPaint
&& bChanged
)
163 rDocShell
.PostPaint(ScRange(0, nStartRow
, nTab
, MAXCOL
, MAXROW
, nTab
),
164 PAINT_GRID
| PAINT_LEFT
);
170 //------------------------------------------------------------------------
172 sal_Bool
ScDocFunc::DetectiveAddPred(const ScAddress
& rPos
)
174 ScDocShellModificator
aModificator( rDocShell
);
176 rDocShell
.MakeDrawLayer();
177 ScDocument
* pDoc
= rDocShell
.GetDocument();
178 bool bUndo (pDoc
->IsUndoEnabled());
179 ScDrawLayer
* pModel
= pDoc
->GetDrawLayer();
180 SCCOL nCol
= rPos
.Col();
181 SCROW nRow
= rPos
.Row();
182 SCTAB nTab
= rPos
.Tab();
185 pModel
->BeginCalcUndo(false);
186 sal_Bool bDone
= ScDetectiveFunc( pDoc
,nTab
).ShowPred( nCol
, nRow
);
187 SdrUndoGroup
* pUndo
= NULL
;
189 pUndo
= pModel
->GetCalcUndo();
192 ScDetOpData
aOperation( ScAddress(nCol
,nRow
,nTab
), SCDETOP_ADDPRED
);
193 pDoc
->AddDetectiveOperation( aOperation
);
196 rDocShell
.GetUndoManager()->AddUndoAction(
197 new ScUndoDetective( &rDocShell
, pUndo
, &aOperation
) );
199 aModificator
.SetDocumentModified();
200 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
202 pBindings
->Invalidate( SID_DETECTIVE_REFRESH
);
210 sal_Bool
ScDocFunc::DetectiveDelPred(const ScAddress
& rPos
)
212 ScDocument
* pDoc
= rDocShell
.GetDocument();
214 bool bUndo(pDoc
->IsUndoEnabled());
215 ScDrawLayer
* pModel
= pDoc
->GetDrawLayer();
219 ScDocShellModificator
aModificator( rDocShell
);
221 SCCOL nCol
= rPos
.Col();
222 SCROW nRow
= rPos
.Row();
223 SCTAB nTab
= rPos
.Tab();
226 pModel
->BeginCalcUndo(false);
227 sal_Bool bDone
= ScDetectiveFunc( pDoc
,nTab
).DeletePred( nCol
, nRow
);
228 SdrUndoGroup
* pUndo
= NULL
;
230 pUndo
= pModel
->GetCalcUndo();
233 ScDetOpData
aOperation( ScAddress(nCol
,nRow
,nTab
), SCDETOP_DELPRED
);
234 pDoc
->AddDetectiveOperation( aOperation
);
237 rDocShell
.GetUndoManager()->AddUndoAction(
238 new ScUndoDetective( &rDocShell
, pUndo
, &aOperation
) );
240 aModificator
.SetDocumentModified();
241 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
243 pBindings
->Invalidate( SID_DETECTIVE_REFRESH
);
251 sal_Bool
ScDocFunc::DetectiveAddSucc(const ScAddress
& rPos
)
253 ScDocShellModificator
aModificator( rDocShell
);
255 rDocShell
.MakeDrawLayer();
256 ScDocument
* pDoc
= rDocShell
.GetDocument();
258 bool bUndo(pDoc
->IsUndoEnabled());
259 ScDrawLayer
* pModel
= pDoc
->GetDrawLayer();
260 SCCOL nCol
= rPos
.Col();
261 SCROW nRow
= rPos
.Row();
262 SCTAB nTab
= rPos
.Tab();
265 pModel
->BeginCalcUndo(false);
266 sal_Bool bDone
= ScDetectiveFunc( pDoc
,nTab
).ShowSucc( nCol
, nRow
);
267 SdrUndoGroup
* pUndo
= NULL
;
269 pUndo
= pModel
->GetCalcUndo();
272 ScDetOpData
aOperation( ScAddress(nCol
,nRow
,nTab
), SCDETOP_ADDSUCC
);
273 pDoc
->AddDetectiveOperation( aOperation
);
276 rDocShell
.GetUndoManager()->AddUndoAction(
277 new ScUndoDetective( &rDocShell
, pUndo
, &aOperation
) );
279 aModificator
.SetDocumentModified();
280 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
282 pBindings
->Invalidate( SID_DETECTIVE_REFRESH
);
290 sal_Bool
ScDocFunc::DetectiveDelSucc(const ScAddress
& rPos
)
292 ScDocument
* pDoc
= rDocShell
.GetDocument();
294 bool bUndo (pDoc
->IsUndoEnabled());
295 ScDrawLayer
* pModel
= pDoc
->GetDrawLayer();
299 ScDocShellModificator
aModificator( rDocShell
);
301 SCCOL nCol
= rPos
.Col();
302 SCROW nRow
= rPos
.Row();
303 SCTAB nTab
= rPos
.Tab();
306 pModel
->BeginCalcUndo(false);
307 sal_Bool bDone
= ScDetectiveFunc( pDoc
,nTab
).DeleteSucc( nCol
, nRow
);
308 SdrUndoGroup
* pUndo
= NULL
;
310 pUndo
= pModel
->GetCalcUndo();
313 ScDetOpData
aOperation( ScAddress(nCol
,nRow
,nTab
), SCDETOP_DELSUCC
);
314 pDoc
->AddDetectiveOperation( aOperation
);
317 rDocShell
.GetUndoManager()->AddUndoAction(
318 new ScUndoDetective( &rDocShell
, pUndo
, &aOperation
) );
320 aModificator
.SetDocumentModified();
321 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
323 pBindings
->Invalidate( SID_DETECTIVE_REFRESH
);
331 sal_Bool
ScDocFunc::DetectiveAddError(const ScAddress
& rPos
)
333 ScDocShellModificator
aModificator( rDocShell
);
335 rDocShell
.MakeDrawLayer();
336 ScDocument
* pDoc
= rDocShell
.GetDocument();
338 bool bUndo (pDoc
->IsUndoEnabled());
339 ScDrawLayer
* pModel
= pDoc
->GetDrawLayer();
340 SCCOL nCol
= rPos
.Col();
341 SCROW nRow
= rPos
.Row();
342 SCTAB nTab
= rPos
.Tab();
345 pModel
->BeginCalcUndo(false);
346 sal_Bool bDone
= ScDetectiveFunc( pDoc
,nTab
).ShowError( nCol
, nRow
);
347 SdrUndoGroup
* pUndo
= NULL
;
349 pUndo
= pModel
->GetCalcUndo();
352 ScDetOpData
aOperation( ScAddress(nCol
,nRow
,nTab
), SCDETOP_ADDERROR
);
353 pDoc
->AddDetectiveOperation( aOperation
);
356 rDocShell
.GetUndoManager()->AddUndoAction(
357 new ScUndoDetective( &rDocShell
, pUndo
, &aOperation
) );
359 aModificator
.SetDocumentModified();
360 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
362 pBindings
->Invalidate( SID_DETECTIVE_REFRESH
);
370 sal_Bool
ScDocFunc::DetectiveMarkInvalid(SCTAB nTab
)
372 ScDocShellModificator
aModificator( rDocShell
);
374 rDocShell
.MakeDrawLayer();
375 ScDocument
* pDoc
= rDocShell
.GetDocument();
377 bool bUndo (pDoc
->IsUndoEnabled());
378 ScDrawLayer
* pModel
= pDoc
->GetDrawLayer();
380 Window
* pWaitWin
= rDocShell
.GetActiveDialogParent();
382 pWaitWin
->EnterWait();
384 pModel
->BeginCalcUndo(false);
386 sal_Bool bDone
= ScDetectiveFunc( pDoc
,nTab
).MarkInvalid( bOverflow
);
387 SdrUndoGroup
* pUndo
= NULL
;
389 pUndo
= pModel
->GetCalcUndo();
391 pWaitWin
->LeaveWait();
396 pUndo
->SetComment( ScGlobal::GetRscString( STR_UNDO_DETINVALID
) );
397 rDocShell
.GetUndoManager()->AddUndoAction( pUndo
);
399 aModificator
.SetDocumentModified();
403 ScGlobal::GetRscString( STR_DETINVALID_OVERFLOW
) ).Execute();
412 sal_Bool
ScDocFunc::DetectiveDelAll(SCTAB nTab
)
414 ScDocument
* pDoc
= rDocShell
.GetDocument();
416 bool bUndo (pDoc
->IsUndoEnabled());
417 ScDrawLayer
* pModel
= pDoc
->GetDrawLayer();
421 ScDocShellModificator
aModificator( rDocShell
);
424 pModel
->BeginCalcUndo(false);
425 sal_Bool bDone
= ScDetectiveFunc( pDoc
,nTab
).DeleteAll( SC_DET_DETECTIVE
);
426 SdrUndoGroup
* pUndo
= NULL
;
428 pUndo
= pModel
->GetCalcUndo();
431 ScDetOpList
* pOldList
= pDoc
->GetDetOpList();
432 ScDetOpList
* pUndoList
= NULL
;
434 pUndoList
= pOldList
? new ScDetOpList(*pOldList
) : NULL
;
436 pDoc
->ClearDetectiveOperations();
440 rDocShell
.GetUndoManager()->AddUndoAction(
441 new ScUndoDetective( &rDocShell
, pUndo
, NULL
, pUndoList
) );
443 aModificator
.SetDocumentModified();
444 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
446 pBindings
->Invalidate( SID_DETECTIVE_REFRESH
);
454 sal_Bool
ScDocFunc::DetectiveRefresh( sal_Bool bAutomatic
)
456 sal_Bool bDone
= false;
457 ScDocument
* pDoc
= rDocShell
.GetDocument();
459 bool bUndo (pDoc
->IsUndoEnabled());
460 ScDetOpList
* pList
= pDoc
->GetDetOpList();
461 if ( pList
&& pList
->Count() )
463 rDocShell
.MakeDrawLayer();
464 ScDrawLayer
* pModel
= pDoc
->GetDrawLayer();
466 pModel
->BeginCalcUndo(false);
468 // Loeschen auf allen Tabellen
470 SCTAB nTabCount
= pDoc
->GetTableCount();
471 for (SCTAB nTab
=0; nTab
<nTabCount
; nTab
++)
472 ScDetectiveFunc( pDoc
,nTab
).DeleteAll( SC_DET_ARROWS
); // don't remove circles
476 size_t nCount
= pList
->Count();
477 for (size_t i
=0; i
< nCount
; ++i
)
479 const ScDetOpData
* pData
= pList
->GetObject(i
);
482 ScAddress aPos
= pData
->GetPos();
483 ScDetectiveFunc
aFunc( pDoc
, aPos
.Tab() );
484 SCCOL nCol
= aPos
.Col();
485 SCROW nRow
= aPos
.Row();
486 switch (pData
->GetOperation())
488 case SCDETOP_ADDSUCC
:
489 aFunc
.ShowSucc( nCol
, nRow
);
491 case SCDETOP_DELSUCC
:
492 aFunc
.DeleteSucc( nCol
, nRow
);
494 case SCDETOP_ADDPRED
:
495 aFunc
.ShowPred( nCol
, nRow
);
497 case SCDETOP_DELPRED
:
498 aFunc
.DeletePred( nCol
, nRow
);
500 case SCDETOP_ADDERROR
:
501 aFunc
.ShowError( nCol
, nRow
);
504 OSL_FAIL("falsche Op bei DetectiveRefresh");
511 SdrUndoGroup
* pUndo
= pModel
->GetCalcUndo();
514 pUndo
->SetComment( ScGlobal::GetRscString( STR_UNDO_DETREFRESH
) );
515 // wenn automatisch, an letzte Aktion anhaengen
516 rDocShell
.GetUndoManager()->AddUndoAction(
517 new ScUndoDraw( pUndo
, &rDocShell
),
521 rDocShell
.SetDrawModified();
527 static void lcl_collectAllPredOrSuccRanges(
528 const ScRangeList
& rSrcRanges
, vector
<ScTokenRef
>& rRefTokens
, ScDocShell
& rDocShell
,
531 ScDocument
* pDoc
= rDocShell
.GetDocument();
532 vector
<ScTokenRef
> aRefTokens
;
533 ScRangeList
aSrcRanges(rSrcRanges
);
534 if (aSrcRanges
.empty())
536 ScRange
* p
= aSrcRanges
.front();
537 ScDetectiveFunc
aDetFunc(pDoc
, p
->aStart
.Tab());
538 ScRangeList aDestRanges
;
539 for (size_t i
= 0, n
= aSrcRanges
.size(); i
< n
; ++i
)
544 aDetFunc
.GetAllPreds(
545 p
->aStart
.Col(), p
->aStart
.Row(), p
->aEnd
.Col(), p
->aEnd
.Row(), aRefTokens
);
549 aDetFunc
.GetAllSuccs(
550 p
->aStart
.Col(), p
->aStart
.Row(), p
->aEnd
.Col(), p
->aEnd
.Row(), aRefTokens
);
553 rRefTokens
.swap(aRefTokens
);
556 void ScDocFunc::DetectiveCollectAllPreds(const ScRangeList
& rSrcRanges
, vector
<ScTokenRef
>& rRefTokens
)
558 lcl_collectAllPredOrSuccRanges(rSrcRanges
, rRefTokens
, rDocShell
, true);
561 void ScDocFunc::DetectiveCollectAllSuccs(const ScRangeList
& rSrcRanges
, vector
<ScTokenRef
>& rRefTokens
)
563 lcl_collectAllPredOrSuccRanges(rSrcRanges
, rRefTokens
, rDocShell
, false);
566 //------------------------------------------------------------------------
568 sal_Bool
ScDocFunc::DeleteContents( const ScMarkData
& rMark
, sal_uInt16 nFlags
,
569 sal_Bool bRecord
, sal_Bool bApi
)
571 ScDocShellModificator
aModificator( rDocShell
);
573 if ( !rMark
.IsMarked() && !rMark
.IsMultiMarked() )
575 OSL_FAIL("ScDocFunc::DeleteContents ohne Markierung");
579 ScDocument
* pDoc
= rDocShell
.GetDocument();
581 if (bRecord
&& !pDoc
->IsUndoEnabled())
584 ScEditableTester
aTester( pDoc
, rMark
);
585 if (!aTester
.IsEditable())
588 rDocShell
.ErrorMessage(aTester
.GetMessageId());
593 sal_Bool bSimple
= false;
595 ScMarkData aMultiMark
= rMark
;
596 aMultiMark
.SetMarking(false); // fuer MarkToMulti
598 ScDocument
* pUndoDoc
= NULL
;
599 sal_Bool bMulti
= !bSimple
&& aMultiMark
.IsMultiMarked();
602 aMultiMark
.MarkToMulti();
603 aMultiMark
.GetMultiMarkArea( aMarkRange
);
605 ScRange
aExtendedRange(aMarkRange
);
608 if ( pDoc
->ExtendMerge( aExtendedRange
, sal_True
) )
612 // keine Objekte auf geschuetzten Tabellen
613 sal_Bool bObjects
= false;
614 if ( nFlags
& IDF_OBJECTS
)
617 SCTAB nTabCount
= pDoc
->GetTableCount();
618 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
619 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
620 if (pDoc
->IsTabProtected(*itr
))
624 sal_uInt16 nExtFlags
= 0; // extra flags are needed only if attributes are deleted
625 if ( nFlags
& IDF_ATTRIB
)
626 rDocShell
.UpdatePaintExt( nExtFlags
, aMarkRange
);
630 // 2) Objekte loeschen (DrawUndo wird gefuellt)
631 // 3) Inhalte fuer Undo kopieren und Undo-Aktion anlegen
632 // 4) Inhalte loeschen
634 bool bDrawUndo
= bObjects
|| (nFlags
& IDF_NOTE
);
635 if (bRecord
&& bDrawUndo
)
636 pDoc
->BeginDrawUndo();
641 pDoc
->DeleteObjectsInSelection( aMultiMark
);
643 pDoc
->DeleteObjectsInArea( aMarkRange
.aStart
.Col(), aMarkRange
.aStart
.Row(),
644 aMarkRange
.aEnd
.Col(), aMarkRange
.aEnd
.Row(),
650 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
651 pUndoDoc
->InitUndo( pDoc
, aMarkRange
.aStart
.Tab(), aMarkRange
.aEnd
.Tab() );
653 // bei "Format/Standard" alle Attribute kopieren, weil CopyToDocument
654 // nur mit IDF_HARDATTR zu langsam ist:
655 sal_uInt16 nUndoDocFlags
= nFlags
;
656 if (nFlags
& IDF_ATTRIB
)
657 nUndoDocFlags
|= IDF_ATTRIB
;
658 if (nFlags
& IDF_EDITATTR
) // Edit-Engine-Attribute
659 nUndoDocFlags
|= IDF_STRING
; // -> Zellen werden geaendert
660 if (nFlags
& IDF_NOTE
)
661 nUndoDocFlags
|= IDF_CONTENTS
; // copy all cells with their notes
662 // note captions are handled in drawing undo
663 nUndoDocFlags
|= IDF_NOCAPTIONS
;
664 pDoc
->CopyToDocument( aExtendedRange
, nUndoDocFlags
, bMulti
, pUndoDoc
, &aMultiMark
);
667 //! HideAllCursors(); // falls Zusammenfassung aufgehoben wird
669 pDoc
->DeleteArea( aMarkRange
.aStart
.Col(), aMarkRange
.aStart
.Row(),
670 aMarkRange
.aEnd
.Col(), aMarkRange
.aEnd
.Row(),
671 aMultiMark
, nFlags
);
674 pDoc
->DeleteSelection( nFlags
, aMultiMark
);
677 // add undo action after drawing undo is complete (objects and note captions)
679 rDocShell
.GetUndoManager()->AddUndoAction(
680 new ScUndoDeleteContents( &rDocShell
, aMultiMark
, aExtendedRange
,
681 pUndoDoc
, bMulti
, nFlags
, bDrawUndo
) );
683 if (!AdjustRowHeight( aExtendedRange
))
684 rDocShell
.PostPaint( aExtendedRange
, PAINT_GRID
, nExtFlags
);
685 else if (nExtFlags
& SC_PF_LINES
)
686 lcl_PaintAbove( rDocShell
, aExtendedRange
); // fuer Linien ueber dem Bereich
688 aModificator
.SetDocumentModified();
693 //------------------------------------------------------------------------
695 sal_Bool
ScDocFunc::TransliterateText( const ScMarkData
& rMark
, sal_Int32 nType
,
696 sal_Bool bRecord
, sal_Bool bApi
)
698 ScDocShellModificator
aModificator( rDocShell
);
700 ScDocument
* pDoc
= rDocShell
.GetDocument();
701 if (bRecord
&& !pDoc
->IsUndoEnabled())
704 ScEditableTester
aTester( pDoc
, rMark
);
705 if (!aTester
.IsEditable())
708 rDocShell
.ErrorMessage(aTester
.GetMessageId());
713 ScMarkData aMultiMark
= rMark
;
714 aMultiMark
.SetMarking(false); // for MarkToMulti
715 aMultiMark
.MarkToMulti();
716 aMultiMark
.GetMultiMarkArea( aMarkRange
);
720 SCTAB nStartTab
= aMarkRange
.aStart
.Tab();
721 SCTAB nTabCount
= pDoc
->GetTableCount();
723 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
724 pUndoDoc
->InitUndo( pDoc
, nStartTab
, nStartTab
);
725 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
726 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
727 if (*itr
!= nStartTab
)
728 pUndoDoc
->AddUndoTab( *itr
, *itr
);
730 ScRange aCopyRange
= aMarkRange
;
731 aCopyRange
.aStart
.SetTab(0);
732 aCopyRange
.aEnd
.SetTab(nTabCount
-1);
733 pDoc
->CopyToDocument( aCopyRange
, IDF_CONTENTS
, sal_True
, pUndoDoc
, &aMultiMark
);
735 rDocShell
.GetUndoManager()->AddUndoAction(
736 new ScUndoTransliterate( &rDocShell
, aMultiMark
, pUndoDoc
, nType
) );
739 pDoc
->TransliterateText( aMultiMark
, nType
);
741 if (!AdjustRowHeight( aMarkRange
))
742 rDocShell
.PostPaint( aMarkRange
, PAINT_GRID
);
744 aModificator
.SetDocumentModified();
749 //------------------------------------------------------------------------
751 sal_Bool
ScDocFunc::SetNormalString( bool& o_rbNumFmtSet
, const ScAddress
& rPos
, const OUString
& rText
, sal_Bool bApi
)
753 ScDocShellModificator
aModificator( rDocShell
);
754 ScDocument
* pDoc
= rDocShell
.GetDocument();
756 bool bUndo(pDoc
->IsUndoEnabled());
757 ScEditableTester
aTester( pDoc
, rPos
.Tab(), rPos
.Col(),rPos
.Row(), rPos
.Col(),rPos
.Row() );
758 if (!aTester
.IsEditable())
761 rDocShell
.ErrorMessage(aTester
.GetMessageId());
765 bool bEditDeleted
= (pDoc
->GetCellType(rPos
) == CELLTYPE_EDIT
);
766 ScUndoEnterData::ValuesType aOldValues
;
770 ScUndoEnterData::Value aOldValue
;
772 aOldValue
.mnTab
= rPos
.Tab();
773 aOldValue
.maCell
.assign(*pDoc
, rPos
);
775 const SfxPoolItem
* pItem
;
776 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( rPos
.Col(),rPos
.Row(),rPos
.Tab() );
777 if ( SFX_ITEM_SET
== pPattern
->GetItemSet().GetItemState(
778 ATTR_VALUE_FORMAT
,false,&pItem
) )
780 aOldValue
.mbHasFormat
= true;
781 aOldValue
.mnFormat
= ((const SfxUInt32Item
*)pItem
)->GetValue();
784 aOldValue
.mbHasFormat
= false;
786 aOldValues
.push_back(aOldValue
);
789 o_rbNumFmtSet
= pDoc
->SetString( rPos
.Col(), rPos
.Row(), rPos
.Tab(), rText
);
793 // wegen ChangeTracking darf UndoAction erst nach SetString angelegt werden
794 rDocShell
.GetUndoManager()->AddUndoAction(
795 new ScUndoEnterData(&rDocShell
, rPos
, aOldValues
, rText
, NULL
));
798 if ( bEditDeleted
|| pDoc
->HasAttrib( ScRange(rPos
), HASATTR_NEEDHEIGHT
) )
799 AdjustRowHeight( ScRange(rPos
) );
801 rDocShell
.PostPaintCell( rPos
);
802 aModificator
.SetDocumentModified();
804 // notify input handler here the same way as in PutCell
806 NotifyInputHandler( rPos
);
811 bool ScDocFunc::SetValueCell( const ScAddress
& rPos
, double fVal
, bool bInteraction
)
813 ScDocShellModificator
aModificator( rDocShell
);
814 ScDocument
* pDoc
= rDocShell
.GetDocument();
815 bool bUndo
= pDoc
->IsUndoEnabled();
817 bool bHeight
= pDoc
->HasAttrib(rPos
, HASATTR_NEEDHEIGHT
);
821 aOldVal
.assign(*pDoc
, rPos
);
823 pDoc
->SetValue(rPos
, fVal
);
827 svl::IUndoManager
* pUndoMgr
= rDocShell
.GetUndoManager();
829 aNewVal
.assign(*pDoc
, rPos
);
830 pUndoMgr
->AddUndoAction(new ScUndoSetCell(&rDocShell
, rPos
, aOldVal
, aNewVal
));
834 AdjustRowHeight(rPos
);
836 rDocShell
.PostPaintCell( rPos
);
837 aModificator
.SetDocumentModified();
839 // #103934#; notify editline and cell in edit mode
841 NotifyInputHandler( rPos
);
846 bool ScDocFunc::SetStringCell( const ScAddress
& rPos
, const OUString
& rStr
, bool bInteraction
)
848 ScDocShellModificator
aModificator( rDocShell
);
849 ScDocument
* pDoc
= rDocShell
.GetDocument();
850 bool bUndo
= pDoc
->IsUndoEnabled();
852 bool bHeight
= pDoc
->HasAttrib(rPos
, HASATTR_NEEDHEIGHT
);
856 aOldVal
.assign(*pDoc
, rPos
);
858 ScSetStringParam aParam
;
859 aParam
.setTextInput();
860 pDoc
->SetString(rPos
, rStr
, &aParam
);
864 svl::IUndoManager
* pUndoMgr
= rDocShell
.GetUndoManager();
866 aNewVal
.assign(*pDoc
, rPos
);
867 pUndoMgr
->AddUndoAction(new ScUndoSetCell(&rDocShell
, rPos
, aOldVal
, aNewVal
));
871 AdjustRowHeight(rPos
);
873 rDocShell
.PostPaintCell( rPos
);
874 aModificator
.SetDocumentModified();
876 // #103934#; notify editline and cell in edit mode
878 NotifyInputHandler( rPos
);
883 bool ScDocFunc::SetEditCell( const ScAddress
& rPos
, const EditTextObject
& rStr
, bool bInteraction
)
885 ScDocShellModificator
aModificator( rDocShell
);
886 ScDocument
* pDoc
= rDocShell
.GetDocument();
887 bool bUndo
= pDoc
->IsUndoEnabled();
889 bool bHeight
= pDoc
->HasAttrib(rPos
, HASATTR_NEEDHEIGHT
);
893 aOldVal
.assign(*pDoc
, rPos
);
895 pDoc
->SetEditText(rPos
, rStr
.Clone());
899 svl::IUndoManager
* pUndoMgr
= rDocShell
.GetUndoManager();
901 aNewVal
.assign(*pDoc
, rPos
);
902 pUndoMgr
->AddUndoAction(new ScUndoSetCell(&rDocShell
, rPos
, aOldVal
, aNewVal
));
906 AdjustRowHeight(rPos
);
908 rDocShell
.PostPaintCell( rPos
);
909 aModificator
.SetDocumentModified();
911 // #103934#; notify editline and cell in edit mode
913 NotifyInputHandler( rPos
);
918 bool ScDocFunc::SetStringOrEditCell( const ScAddress
& rPos
, const OUString
& rStr
, bool bInteraction
)
920 ScDocument
* pDoc
= rDocShell
.GetDocument();
922 if (ScStringUtil::isMultiline(rStr
))
924 ScFieldEditEngine
& rEngine
= pDoc
->GetEditEngine();
925 rEngine
.SetText(rStr
);
926 boost::scoped_ptr
<EditTextObject
> pEditText(rEngine
.CreateTextObject());
927 return SetEditCell(rPos
, *pEditText
, bInteraction
);
930 return SetStringCell(rPos
, rStr
, bInteraction
);
933 bool ScDocFunc::SetFormulaCell( const ScAddress
& rPos
, ScFormulaCell
* pCell
, bool bInteraction
)
935 SAL_WNODEPRECATED_DECLARATIONS_PUSH
936 std::auto_ptr
<ScFormulaCell
> xCell(pCell
);
937 SAL_WNODEPRECATED_DECLARATIONS_POP
939 ScDocShellModificator
aModificator( rDocShell
);
940 ScDocument
* pDoc
= rDocShell
.GetDocument();
941 bool bUndo
= pDoc
->IsUndoEnabled();
943 bool bHeight
= pDoc
->HasAttrib(rPos
, HASATTR_NEEDHEIGHT
);
947 aOldVal
.assign(*pDoc
, rPos
);
949 pCell
= pDoc
->SetFormulaCell(rPos
, xCell
.release());
951 // For performance reasons API calls may disable calculation while
952 // operating and recalculate once when done. If through user interaction
953 // and AutoCalc is disabled, calculate the formula (without its
954 // dependencies) once so the result matches the current document's content.
955 if (bInteraction
&& !pDoc
->GetAutoCalc() && pCell
)
957 // calculate just the cell once and set Dirty again
959 pCell
->SetDirtyVar();
960 pDoc
->PutInFormulaTree( pCell
);
965 svl::IUndoManager
* pUndoMgr
= rDocShell
.GetUndoManager();
967 aNewVal
.assign(*pDoc
, rPos
);
968 pUndoMgr
->AddUndoAction(new ScUndoSetCell(&rDocShell
, rPos
, aOldVal
, aNewVal
));
972 AdjustRowHeight(rPos
);
974 rDocShell
.PostPaintCell( rPos
);
975 aModificator
.SetDocumentModified();
977 // #103934#; notify editline and cell in edit mode
979 NotifyInputHandler( rPos
);
984 void ScDocFunc::NotifyInputHandler( const ScAddress
& rPos
)
986 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
987 if ( pViewSh
&& pViewSh
->GetViewData()->GetDocShell() == &rDocShell
)
989 ScInputHandler
* pInputHdl
= SC_MOD()->GetInputHdl();
990 if ( pInputHdl
&& pInputHdl
->GetCursorPos() == rPos
)
992 sal_Bool
bIsEditMode(pInputHdl
->IsEditMode());
994 // set modified if in editmode, because so the string is not set in the InputWindow like in the cell
995 // (the cell shows the same like the InputWindow)
997 pInputHdl
->SetModified();
998 pViewSh
->UpdateInputHandler(false, !bIsEditMode
);
1003 struct ScMyRememberItem
1006 SfxItemSet aItemSet
;
1008 ScMyRememberItem(const SfxItemSet
& rItemSet
, sal_Int32 nTempIndex
) :
1009 nIndex(nTempIndex
), aItemSet(rItemSet
) {}
1012 typedef ::std::list
<ScMyRememberItem
*> ScMyRememberItemList
;
1014 bool ScDocFunc::PutData( const ScAddress
& rPos
, ScEditEngineDefaulter
& rEngine
, bool bApi
)
1016 // PutData ruft PutCell oder SetNormalString
1018 sal_Bool bRet
= false;
1019 ScDocument
* pDoc
= rDocShell
.GetDocument();
1020 ScEditAttrTester
aTester( &rEngine
);
1021 sal_Bool bEditCell
= aTester
.NeedsObject();
1024 // #i61702# With bLoseContent set, the content of rEngine isn't restored
1025 // (used in loading XML, where after the removeActionLock call the API obejct's
1026 // EditEngine isn't accessed again.
1027 sal_Bool bLoseContent
= pDoc
->IsImportingXML();
1029 sal_Bool
bUpdateMode(rEngine
.GetUpdateMode());
1031 rEngine
.SetUpdateMode(false);
1033 ScMyRememberItemList aRememberItems
;
1034 ScMyRememberItem
* pRememberItem
= NULL
;
1036 // All paragraph attributes must be removed before calling CreateTextObject,
1037 // not only alignment, so the object doesn't contain the cell attributes as
1038 // paragraph attributes. Before remove the attributes store they in a list to
1039 // set they back to the EditEngine.
1040 sal_Int32 nCount
= rEngine
.GetParagraphCount();
1041 for (sal_Int32 i
=0; i
<nCount
; i
++)
1043 const SfxItemSet
& rOld
= rEngine
.GetParaAttribs( i
);
1046 if ( !bLoseContent
)
1048 pRememberItem
= new ScMyRememberItem(rEngine
.GetParaAttribs(i
), i
);
1049 aRememberItems
.push_back(pRememberItem
);
1051 rEngine
.SetParaAttribs( i
, SfxItemSet( *rOld
.GetPool(), rOld
.GetRanges() ) );
1055 // A copy of pNewData will be stored in the cell.
1056 boost::scoped_ptr
<EditTextObject
> pNewData(rEngine
.CreateTextObject());
1057 bRet
= SetEditCell(rPos
, *pNewData
, !bApi
);
1059 // Set the paragraph attributes back to the EditEngine.
1060 if (!aRememberItems
.empty())
1062 ScMyRememberItemList::iterator aItr
= aRememberItems
.begin();
1063 while (aItr
!= aRememberItems
.end())
1065 pRememberItem
= *aItr
;
1066 rEngine
.SetParaAttribs(pRememberItem
->nIndex
, pRememberItem
->aItemSet
);
1067 delete pRememberItem
;
1068 aItr
= aRememberItems
.erase(aItr
);
1072 // #i61702# if the content isn't accessed, there's no need to set the UpdateMode again
1073 if ( bUpdateMode
&& !bLoseContent
)
1074 rEngine
.SetUpdateMode(sal_True
);
1078 OUString aText
= rEngine
.GetText();
1079 if (aText
.isEmpty())
1081 bool bNumFmtSet
= false;
1082 bRet
= SetNormalString( bNumFmtSet
, rPos
, aText
, bApi
);
1085 bRet
= SetStringCell(rPos
, aText
, !bApi
);
1088 if ( bRet
&& aTester
.NeedsCellAttr() )
1090 const SfxItemSet
& rEditAttr
= aTester
.GetAttribs();
1091 ScPatternAttr
aPattern( pDoc
->GetPool() );
1092 aPattern
.GetFromEditItemSet( &rEditAttr
);
1093 aPattern
.DeleteUnchanged( pDoc
->GetPattern( rPos
.Col(), rPos
.Row(), rPos
.Tab() ) );
1094 aPattern
.GetItemSet().ClearItem( ATTR_HOR_JUSTIFY
); // wasn't removed above if no edit object
1095 if ( aPattern
.GetItemSet().Count() > 0 )
1098 aMark
.SelectTable( rPos
.Tab(), sal_True
);
1099 aMark
.SetMarkArea( ScRange( rPos
) );
1100 ApplyAttributes( aMark
, aPattern
, sal_True
, bApi
);
1108 static ScTokenArray
* lcl_ScDocFunc_CreateTokenArrayXML( const OUString
& rText
, const OUString
& rFormulaNmsp
, const formula::FormulaGrammar::Grammar eGrammar
)
1110 ScTokenArray
* pCode
= new ScTokenArray
;
1111 pCode
->AddStringXML( rText
);
1112 if( (eGrammar
== formula::FormulaGrammar::GRAM_EXTERNAL
) && (!rFormulaNmsp
.isEmpty()) )
1113 pCode
->AddStringXML( rFormulaNmsp
);
1117 bool ScDocFunc::SetCellText(
1118 const ScAddress
& rPos
, const OUString
& rText
, bool bInterpret
, bool bEnglish
, bool bApi
,
1119 const formula::FormulaGrammar::Grammar eGrammar
)
1126 ScDocument
* pDoc
= rDocShell
.GetDocument();
1128 ::boost::scoped_ptr
<ScExternalRefManager::ApiGuard
> pExtRefGuard
;
1130 pExtRefGuard
.reset(new ScExternalRefManager::ApiGuard(pDoc
));
1132 ScInputStringType aRes
=
1133 ScStringUtil::parseInputString(*pDoc
->GetFormatTable(), rText
, LANGUAGE_ENGLISH_US
);
1135 switch (aRes
.meType
)
1137 case ScInputStringType::Formula
:
1138 bSet
= SetFormulaCell(rPos
, new ScFormulaCell(pDoc
, rPos
, aRes
.maText
, eGrammar
), !bApi
);
1140 case ScInputStringType::Number
:
1141 bSet
= SetValueCell(rPos
, aRes
.mfValue
, !bApi
);
1143 case ScInputStringType::Text
:
1144 bSet
= SetStringOrEditCell(rPos
, aRes
.maText
, !bApi
);
1150 // sonst Null behalten -> SetString mit lokalen Formeln/Zahlformat
1152 else if (!rText
.isEmpty())
1154 bSet
= SetStringOrEditCell(rPos
, rText
, !bApi
);
1159 bool bNumFmtSet
= false;
1160 bSet
= SetNormalString( bNumFmtSet
, rPos
, rText
, bApi
);
1165 //------------------------------------------------------------------------
1167 bool ScDocFunc::ShowNote( const ScAddress
& rPos
, bool bShow
)
1169 ScDocument
& rDoc
= *rDocShell
.GetDocument();
1170 ScPostIt
* pNote
= rDoc
.GetNote( rPos
);
1171 if( !pNote
|| (bShow
== pNote
->IsCaptionShown()) ) return false;
1173 // move the caption to internal or hidden layer and create undo action
1174 pNote
->ShowCaption( rPos
, bShow
);
1175 if( rDoc
.IsUndoEnabled() )
1176 rDocShell
.GetUndoManager()->AddUndoAction( new ScUndoShowHideNote( rDocShell
, rPos
, bShow
) );
1178 if (rDoc
.IsStreamValid(rPos
.Tab()))
1179 rDoc
.SetStreamValid(rPos
.Tab(), false);
1181 rDocShell
.SetDocumentModified();
1186 //------------------------------------------------------------------------
1188 bool ScDocFunc::SetNoteText( const ScAddress
& rPos
, const OUString
& rText
, sal_Bool bApi
)
1190 ScDocShellModificator
aModificator( rDocShell
);
1192 ScDocument
* pDoc
= rDocShell
.GetDocument();
1193 ScEditableTester
aTester( pDoc
, rPos
.Tab(), rPos
.Col(),rPos
.Row(), rPos
.Col(),rPos
.Row() );
1194 if (!aTester
.IsEditable())
1197 rDocShell
.ErrorMessage(aTester
.GetMessageId());
1201 OUString aNewText
= convertLineEnd(rText
, GetSystemLineEnd()); //! ist das noetig ???
1203 if( ScPostIt
* pNote
= (!aNewText
.isEmpty()) ? pDoc
->GetOrCreateNote( rPos
) : pDoc
->GetNote(rPos
) )
1204 pNote
->SetText( rPos
, aNewText
);
1208 if (pDoc
->IsStreamValid(rPos
.Tab()))
1209 pDoc
->SetStreamValid(rPos
.Tab(), false);
1211 rDocShell
.PostPaintCell( rPos
);
1212 aModificator
.SetDocumentModified();
1217 //------------------------------------------------------------------------
1219 bool ScDocFunc::ReplaceNote( const ScAddress
& rPos
, const OUString
& rNoteText
, const OUString
* pAuthor
, const OUString
* pDate
, sal_Bool bApi
)
1223 ScDocShellModificator
aModificator( rDocShell
);
1224 ScDocument
& rDoc
= *rDocShell
.GetDocument();
1225 ScEditableTester
aTester( &rDoc
, rPos
.Tab(), rPos
.Col(),rPos
.Row(), rPos
.Col(),rPos
.Row() );
1226 if (aTester
.IsEditable())
1228 ScDrawLayer
* pDrawLayer
= rDoc
.GetDrawLayer();
1229 ::svl::IUndoManager
* pUndoMgr
= (pDrawLayer
&& rDoc
.IsUndoEnabled()) ? rDocShell
.GetUndoManager() : 0;
1231 ScNoteData aOldData
;
1232 ScPostIt
* pOldNote
= rDoc
.ReleaseNote( rPos
);
1235 // ensure existing caption object before draw undo tracking starts
1236 pOldNote
->GetOrCreateCaption( rPos
);
1237 // rescue note data for undo
1238 aOldData
= pOldNote
->GetNoteData();
1241 // collect drawing undo actions for deleting/inserting caption obejcts
1243 pDrawLayer
->BeginCalcUndo(false);
1245 // delete the note (creates drawing undo action for the caption object)
1248 // create new note (creates drawing undo action for the new caption object)
1249 ScNoteData aNewData
;
1250 if( ScPostIt
* pNewNote
= ScNoteUtil::CreateNoteFromString( rDoc
, rPos
, rNoteText
, false, true ) )
1252 if( pAuthor
) pNewNote
->SetAuthor( *pAuthor
);
1253 if( pDate
) pNewNote
->SetDate( *pDate
);
1254 // rescue note data for undo
1255 aNewData
= pNewNote
->GetNoteData();
1258 // create the undo action
1259 if( pUndoMgr
&& (aOldData
.mpCaption
|| aNewData
.mpCaption
) )
1260 pUndoMgr
->AddUndoAction( new ScUndoReplaceNote( rDocShell
, rPos
, aOldData
, aNewData
, pDrawLayer
->GetCalcUndo() ) );
1262 // repaint cell (to make note marker visible)
1263 rDocShell
.PostPaintCell( rPos
);
1265 if (rDoc
.IsStreamValid(rPos
.Tab()))
1266 rDoc
.SetStreamValid(rPos
.Tab(), false);
1268 aModificator
.SetDocumentModified();
1273 rDocShell
.ErrorMessage(aTester
.GetMessageId());
1279 //------------------------------------------------------------------------
1281 sal_Bool
ScDocFunc::ApplyAttributes( const ScMarkData
& rMark
, const ScPatternAttr
& rPattern
,
1282 sal_Bool bRecord
, sal_Bool bApi
)
1284 ScDocument
* pDoc
= rDocShell
.GetDocument();
1285 if ( bRecord
&& !pDoc
->IsUndoEnabled() )
1288 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 if ( !bImportingXML
&& !pDoc
->IsSelectionEditable( rMark
, &bOnlyNotBecauseOfMatrix
)
1293 && !bOnlyNotBecauseOfMatrix
)
1296 rDocShell
.ErrorMessage(STR_PROTECTIONERR
);
1300 ScDocShellModificator
aModificator( rDocShell
);
1304 ScRange aMultiRange
;
1305 sal_Bool bMulti
= rMark
.IsMultiMarked();
1307 rMark
.GetMultiMarkArea( aMultiRange
);
1309 rMark
.GetMarkArea( aMultiRange
);
1313 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1314 pUndoDoc
->InitUndo( pDoc
, aMultiRange
.aStart
.Tab(), aMultiRange
.aEnd
.Tab() );
1315 pDoc
->CopyToDocument( aMultiRange
, IDF_ATTRIB
, bMulti
, pUndoDoc
, &rMark
);
1317 rDocShell
.GetUndoManager()->AddUndoAction(
1318 new ScUndoSelectionAttr(
1320 aMultiRange
.aStart
.Col(), aMultiRange
.aStart
.Row(), aMultiRange
.aStart
.Tab(),
1321 aMultiRange
.aEnd
.Col(), aMultiRange
.aEnd
.Row(), aMultiRange
.aEnd
.Tab(),
1322 pUndoDoc
, bMulti
, &rPattern
) );
1325 // While loading XML it is not necessary to ask HasAttrib. It needs too much time.
1326 sal_uInt16 nExtFlags
= 0;
1327 if ( !bImportingXML
)
1328 rDocShell
.UpdatePaintExt( nExtFlags
, aMultiRange
); // content before the change
1329 pDoc
->ApplySelectionPattern( rPattern
, rMark
);
1330 if ( !bImportingXML
)
1331 rDocShell
.UpdatePaintExt( nExtFlags
, aMultiRange
); // content after the change
1333 if (!AdjustRowHeight( aMultiRange
))
1334 rDocShell
.PostPaint( aMultiRange
, PAINT_GRID
, nExtFlags
);
1335 else if (nExtFlags
& SC_PF_LINES
)
1336 lcl_PaintAbove( rDocShell
, aMultiRange
); // fuer Linien ueber dem Bereich
1338 aModificator
.SetDocumentModified();
1344 sal_Bool
ScDocFunc::ApplyStyle( const ScMarkData
& rMark
, const OUString
& rStyleName
,
1345 sal_Bool bRecord
, sal_Bool bApi
)
1347 ScDocument
* pDoc
= rDocShell
.GetDocument();
1348 if ( bRecord
&& !pDoc
->IsUndoEnabled() )
1351 bool bImportingXML
= pDoc
->IsImportingXML();
1352 // Cell formats can still be set if the range isn't editable only because of matrix formulas.
1353 // #i62483# When loading XML, the check can be skipped altogether.
1354 bool bOnlyNotBecauseOfMatrix
;
1355 if ( !bImportingXML
&& !pDoc
->IsSelectionEditable( rMark
, &bOnlyNotBecauseOfMatrix
)
1356 && !bOnlyNotBecauseOfMatrix
)
1359 rDocShell
.ErrorMessage(STR_PROTECTIONERR
);
1363 ScStyleSheet
* pStyleSheet
= (ScStyleSheet
*) pDoc
->GetStyleSheetPool()->Find(
1364 rStyleName
, SFX_STYLE_FAMILY_PARA
);
1368 ScDocShellModificator
aModificator( rDocShell
);
1370 ScRange aMultiRange
;
1371 sal_Bool bMulti
= rMark
.IsMultiMarked();
1373 rMark
.GetMultiMarkArea( aMultiRange
);
1375 rMark
.GetMarkArea( aMultiRange
);
1379 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1380 SCTAB nStartTab
= aMultiRange
.aStart
.Tab();
1381 SCTAB nTabCount
= pDoc
->GetTableCount();
1382 pUndoDoc
->InitUndo( pDoc
, nStartTab
, nStartTab
);
1383 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
1384 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
1385 if (*itr
!= nStartTab
)
1386 pUndoDoc
->AddUndoTab( *itr
, *itr
);
1388 ScRange aCopyRange
= aMultiRange
;
1389 aCopyRange
.aStart
.SetTab(0);
1390 aCopyRange
.aEnd
.SetTab(nTabCount
-1);
1391 pDoc
->CopyToDocument( aCopyRange
, IDF_ATTRIB
, bMulti
, pUndoDoc
, &rMark
);
1393 rDocShell
.GetUndoManager()->AddUndoAction(
1394 new ScUndoSelectionStyle(
1395 &rDocShell
, rMark
, aMultiRange
, rStyleName
, pUndoDoc
) );
1399 pDoc
->ApplySelectionStyle( (ScStyleSheet
&)*pStyleSheet
, rMark
);
1401 sal_uInt16 nExtFlags
= 0;
1402 if (!AdjustRowHeight( aMultiRange
))
1403 rDocShell
.PostPaint( aMultiRange
, PAINT_GRID
, nExtFlags
);
1404 else if (nExtFlags
& SC_PF_LINES
)
1405 lcl_PaintAbove( rDocShell
, aMultiRange
); // fuer Linien ueber dem Bereich
1407 aModificator
.SetDocumentModified();
1415 * Check if this insertion attempt would end up cutting one or more pivot
1416 * tables in half, which is not desirable.
1418 * @return true if this insertion can be done safely without shearing any
1419 * existing pivot tables, false otherwise.
1421 bool canInsertCellsByPivot(const ScRange
& rRange
, const ScMarkData
& rMarkData
, InsCellCmd eCmd
, const ScDocument
* pDoc
)
1423 if (!pDoc
->HasPivotTable())
1424 // This document has no pivot tables.
1427 const ScDPCollection
* pDPs
= pDoc
->GetDPCollection();
1428 ScMarkData::const_iterator itBeg
= rMarkData
.begin(), itEnd
= rMarkData
.end();
1430 ScRange
aRange(rRange
); // local copy
1435 aRange
.aStart
.SetCol(0);
1436 aRange
.aEnd
.SetCol(MAXCOL
);
1441 for (ScMarkData::const_iterator it
= itBeg
; it
!= itEnd
; ++it
)
1443 if (pDPs
->IntersectsTableByColumns(aRange
.aStart
.Col(), aRange
.aEnd
.Col(), aRange
.aStart
.Row(), *it
))
1444 // This column range cuts through at least one pivot table. Not good.
1448 // Start row must be either at the top or above any pivot tables.
1449 if (aRange
.aStart
.Row() < 0)
1450 // I don't know how to handle this case.
1453 if (aRange
.aStart
.Row() == 0)
1454 // First row is always allowed.
1457 ScRange
aTest(aRange
);
1458 aTest
.aStart
.IncRow(-1); // Test one row up.
1459 aTest
.aEnd
.SetRow(aTest
.aStart
.Row());
1460 for (ScMarkData::const_iterator it
= itBeg
; it
!= itEnd
; ++it
)
1462 aTest
.aStart
.SetTab(*it
);
1463 aTest
.aEnd
.SetTab(*it
);
1464 if (pDPs
->HasTable(aTest
))
1471 aRange
.aStart
.SetRow(0);
1472 aRange
.aEnd
.SetRow(MAXROW
);
1475 case INS_CELLSRIGHT
:
1477 for (ScMarkData::const_iterator it
= itBeg
; it
!= itEnd
; ++it
)
1479 if (pDPs
->IntersectsTableByRows(aRange
.aStart
.Col(), aRange
.aStart
.Row(), aRange
.aEnd
.Row(), *it
))
1480 // This column range cuts through at least one pivot table. Not good.
1484 // Start row must be either at the top or above any pivot tables.
1485 if (aRange
.aStart
.Col() < 0)
1486 // I don't know how to handle this case.
1489 if (aRange
.aStart
.Col() == 0)
1490 // First row is always allowed.
1493 ScRange
aTest(aRange
);
1494 aTest
.aStart
.IncCol(-1); // Test one column to the left.
1495 aTest
.aEnd
.SetCol(aTest
.aStart
.Col());
1496 for (ScMarkData::const_iterator it
= itBeg
; it
!= itEnd
; ++it
)
1498 aTest
.aStart
.SetTab(*it
);
1499 aTest
.aEnd
.SetTab(*it
);
1500 if (pDPs
->HasTable(aTest
))
1512 * Check if this deletion attempt would end up cutting one or more pivot
1513 * tables in half, which is not desirable.
1515 * @return true if this deletion can be done safely without shearing any
1516 * existing pivot tables, false otherwise.
1518 bool canDeleteCellsByPivot(const ScRange
& rRange
, const ScMarkData
& rMarkData
, DelCellCmd eCmd
, const ScDocument
* pDoc
)
1520 if (!pDoc
->HasPivotTable())
1521 // This document has no pivot tables.
1524 const ScDPCollection
* pDPs
= pDoc
->GetDPCollection();
1525 ScMarkData::const_iterator itBeg
= rMarkData
.begin(), itEnd
= rMarkData
.end();
1527 ScRange
aRange(rRange
); // local copy
1533 aRange
.aStart
.SetCol(0);
1534 aRange
.aEnd
.SetCol(MAXCOL
);
1539 for (ScMarkData::const_iterator it
= itBeg
; it
!= itEnd
; ++it
)
1541 if (pDPs
->IntersectsTableByColumns(aRange
.aStart
.Col(), aRange
.aEnd
.Col(), aRange
.aStart
.Row(), *it
))
1542 // This column range cuts through at least one pivot table. Not good.
1546 ScRange
aTest(aRange
);
1547 for (ScMarkData::const_iterator it
= itBeg
; it
!= itEnd
; ++it
)
1549 aTest
.aStart
.SetTab(*it
);
1550 aTest
.aEnd
.SetTab(*it
);
1551 if (pDPs
->HasTable(aTest
))
1558 aRange
.aStart
.SetRow(0);
1559 aRange
.aEnd
.SetRow(MAXROW
);
1564 for (ScMarkData::const_iterator it
= itBeg
; it
!= itEnd
; ++it
)
1566 if (pDPs
->IntersectsTableByRows(aRange
.aStart
.Col(), aRange
.aStart
.Row(), aRange
.aEnd
.Row(), *it
))
1567 // This column range cuts through at least one pivot table. Not good.
1571 ScRange
aTest(aRange
);
1572 for (ScMarkData::const_iterator it
= itBeg
; it
!= itEnd
; ++it
)
1574 aTest
.aStart
.SetTab(*it
);
1575 aTest
.aEnd
.SetTab(*it
);
1576 if (pDPs
->HasTable(aTest
))
1589 bool ScDocFunc::InsertCells( const ScRange
& rRange
, const ScMarkData
* pTabMark
, InsCellCmd eCmd
,
1590 bool bRecord
, bool bApi
, bool bPartOfPaste
)
1592 ScDocShellModificator
aModificator( rDocShell
);
1594 SCCOL nStartCol
= rRange
.aStart
.Col();
1595 SCROW nStartRow
= rRange
.aStart
.Row();
1596 SCTAB nStartTab
= rRange
.aStart
.Tab();
1597 SCCOL nEndCol
= rRange
.aEnd
.Col();
1598 SCROW nEndRow
= rRange
.aEnd
.Row();
1599 SCTAB nEndTab
= rRange
.aEnd
.Tab();
1601 if ( !ValidRow(nStartRow
) || !ValidRow(nEndRow
) )
1603 OSL_FAIL("invalid row in InsertCells");
1607 ScDocument
* pDoc
= rDocShell
.GetDocument();
1608 SCTAB nTabCount
= pDoc
->GetTableCount();
1609 SCCOL nPaintStartCol
= nStartCol
;
1610 SCROW nPaintStartRow
= nStartRow
;
1611 SCCOL nPaintEndCol
= nEndCol
;
1612 SCROW nPaintEndRow
= nEndRow
;
1613 sal_uInt16 nPaintFlags
= PAINT_GRID
;
1617 ScTabViewShell
* pViewSh
= rDocShell
.GetBestViewShell(); //preserve current cursor position
1618 SCCOL nCursorCol
= 0;
1619 SCROW nCursorRow
= 0;
1622 nCursorCol
= pViewSh
->GetViewData()->GetCurX();
1623 nCursorRow
= pViewSh
->GetViewData()->GetCurY();
1626 if (bRecord
&& !pDoc
->IsUndoEnabled())
1635 for( i
=0; i
<nTabCount
; i
++ )
1637 if( !pDoc
->IsScenario(i
) )
1640 if( nCount
== nEndTab
+1 )
1642 aMark
.SelectTable( i
, true );
1649 ScMarkData
aFullMark( aMark
); // including scenario sheets
1650 ScMarkData::iterator itr
= aMark
.begin(), itrEnd
= aMark
.end();
1651 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
1652 for( SCTAB j
= *itr
+1; j
<nTabCount
&& pDoc
->IsScenario(j
); j
++ )
1653 aFullMark
.SelectTable( j
, true );
1655 SCTAB nSelCount
= aMark
.GetSelectCount();
1657 // zugehoerige Szenarien auch anpassen
1658 // Test zusammengefasste
1660 SCCOL nMergeTestStartCol
= nStartCol
;
1661 SCROW nMergeTestStartRow
= nStartRow
;
1662 SCCOL nMergeTestEndCol
= nEndCol
;
1663 SCROW nMergeTestEndRow
= nEndRow
;
1665 ScRange
aExtendMergeRange( rRange
);
1667 if( rRange
.aStart
== rRange
.aEnd
&& pDoc
->HasAttrib(rRange
, HASATTR_MERGED
) )
1669 pDoc
->ExtendMerge( aExtendMergeRange
);
1670 pDoc
->ExtendOverlapped( aExtendMergeRange
);
1671 nMergeTestEndCol
= aExtendMergeRange
.aEnd
.Col();
1672 nMergeTestEndRow
= aExtendMergeRange
.aEnd
.Row();
1673 nPaintEndCol
= nMergeTestEndCol
;
1674 nPaintEndRow
= nMergeTestEndRow
;
1677 if ( eCmd
== INS_INSROWS
)
1679 nMergeTestStartCol
= 0;
1680 nMergeTestEndCol
= MAXCOL
;
1682 if ( eCmd
== INS_INSCOLS
)
1684 nMergeTestStartRow
= 0;
1685 nMergeTestEndRow
= MAXROW
;
1687 if ( eCmd
== INS_CELLSDOWN
)
1688 nMergeTestEndRow
= MAXROW
;
1689 if ( eCmd
== INS_CELLSRIGHT
)
1690 nMergeTestEndCol
= MAXCOL
;
1692 bool bNeedRefresh
= false;
1694 SCCOL nEditTestEndCol
= (eCmd
==INS_INSCOLS
) ? MAXCOL
: nMergeTestEndCol
;
1695 SCROW nEditTestEndRow
= (eCmd
==INS_INSROWS
) ? MAXROW
: nMergeTestEndRow
;
1696 ScEditableTester
aTester( pDoc
, nMergeTestStartCol
, nMergeTestStartRow
, nEditTestEndCol
, nEditTestEndRow
, aMark
);
1697 if (!aTester
.IsEditable())
1700 rDocShell
.ErrorMessage(aTester
.GetMessageId());
1704 // Check if this insertion is allowed with respect to pivot table.
1705 if (!canInsertCellsByPivot(rRange
, aMark
, eCmd
, pDoc
))
1708 rDocShell
.ErrorMessage(STR_NO_INSERT_DELETE_OVER_PIVOT_TABLE
);
1712 WaitObject
aWait( rDocShell
.GetActiveDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference
1714 ScDocument
* pRefUndoDoc
= NULL
;
1715 ScRefUndoData
* pUndoData
= NULL
;
1718 pRefUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1719 pRefUndoDoc
->InitUndo( pDoc
, 0, nTabCount
-1, false, false );
1721 // pRefUndoDoc is filled in InsertCol / InsertRow
1723 pUndoData
= new ScRefUndoData( pDoc
);
1725 pDoc
->BeginDrawUndo();
1728 // #i8302 : we unmerge overwhelming ranges, before insertion all the actions are put in the same ListAction
1729 // the patch comes from mloiseleur and maoyg
1730 bool bInsertMerge
= false;
1731 std::vector
<ScRange
> qIncreaseRange
;
1732 OUString aUndo
= ScGlobal::GetRscString( STR_UNDO_INSERTCELLS
);
1734 rDocShell
.GetUndoManager()->EnterListAction( aUndo
, aUndo
);
1736 itr
= aMark
.begin();
1737 for (; itr
!= itrEnd
&& nTabCount
; ++itr
)
1740 if( pDoc
->HasAttrib( nMergeTestStartCol
, nMergeTestStartRow
, i
, nMergeTestEndCol
, nMergeTestEndRow
, i
, HASATTR_MERGED
| HASATTR_OVERLAPPED
) )
1742 if (eCmd
==INS_CELLSRIGHT
)
1743 bNeedRefresh
= true;
1745 SCCOL nMergeStartCol
= nMergeTestStartCol
;
1746 SCROW nMergeStartRow
= nMergeTestStartRow
;
1747 SCCOL nMergeEndCol
= nMergeTestEndCol
;
1748 SCROW nMergeEndRow
= nMergeTestEndRow
;
1750 pDoc
->ExtendMerge( nMergeStartCol
, nMergeStartRow
, nMergeEndCol
, nMergeEndRow
, i
);
1751 pDoc
->ExtendOverlapped( nMergeStartCol
, nMergeStartRow
, nMergeEndCol
, nMergeEndRow
, i
);
1753 if(( eCmd
== INS_CELLSDOWN
&& ( nMergeStartCol
!= nMergeTestStartCol
|| nMergeEndCol
!= nMergeTestEndCol
)) ||
1754 (eCmd
== INS_CELLSRIGHT
&& ( nMergeStartRow
!= nMergeTestStartRow
|| nMergeEndRow
!= nMergeTestEndRow
)) )
1757 rDocShell
.ErrorMessage(STR_MSSG_INSERTCELLS_0
);
1758 rDocShell
.GetUndoManager()->LeaveListAction();
1763 SCCOL nTestCol
= -1;
1764 SCROW nTestRow1
= -1;
1765 SCROW nTestRow2
= -1;
1767 ScDocAttrIterator
aTestIter( pDoc
, i
, nMergeTestStartCol
, nMergeTestStartRow
, nMergeTestEndCol
, nMergeTestEndRow
);
1768 ScRange
aExtendRange( nMergeTestStartCol
, nMergeTestStartRow
, i
, nMergeTestEndCol
, nMergeTestEndRow
, i
);
1769 const ScPatternAttr
* pPattern
= NULL
;
1770 const ScMergeAttr
* pMergeFlag
= NULL
;
1771 const ScMergeFlagAttr
* pMergeFlagAttr
= NULL
;
1772 while ( ( pPattern
= aTestIter
.GetNext( nTestCol
, nTestRow1
, nTestRow2
) ) != NULL
)
1774 pMergeFlag
= (const ScMergeAttr
*) &pPattern
->GetItem(ATTR_MERGE
);
1775 pMergeFlagAttr
= (const ScMergeFlagAttr
*) &pPattern
->GetItem(ATTR_MERGE_FLAG
);
1776 sal_Int16 nNewFlags
= pMergeFlagAttr
->GetValue() & ( SC_MF_HOR
| SC_MF_VER
);
1777 if( ( pMergeFlag
&& pMergeFlag
->IsMerged() ) || nNewFlags
== SC_MF_HOR
|| nNewFlags
== SC_MF_VER
)
1779 ScRange
aRange( nTestCol
, nTestRow1
, i
);
1780 pDoc
->ExtendOverlapped(aRange
);
1781 pDoc
->ExtendMerge(aRange
, true);
1783 if( nTestRow1
< nTestRow2
&& nNewFlags
== SC_MF_HOR
)
1785 for( SCROW nTestRow
= nTestRow1
; nTestRow
<= nTestRow2
; nTestRow
++ )
1787 ScRange
aTestRange( nTestCol
, nTestRow
, i
);
1788 pDoc
->ExtendOverlapped( aTestRange
);
1789 pDoc
->ExtendMerge( aTestRange
, true);
1790 ScRange
aMergeRange( aTestRange
.aStart
.Col(),aTestRange
.aStart
.Row(), i
);
1791 if( !aExtendRange
.In( aMergeRange
) )
1793 qIncreaseRange
.push_back( aTestRange
);
1794 bInsertMerge
= true;
1800 ScRange
aMergeRange( aRange
.aStart
.Col(),aRange
.aStart
.Row(), i
);
1801 if( !aExtendRange
.In( aMergeRange
) )
1803 qIncreaseRange
.push_back( aRange
);
1805 bInsertMerge
= true;
1812 if( eCmd
== INS_INSROWS
|| eCmd
== INS_CELLSDOWN
)
1814 nStartRow
= aExtendMergeRange
.aStart
.Row();
1815 nEndRow
= aExtendMergeRange
.aEnd
.Row();
1817 if( eCmd
== INS_CELLSDOWN
)
1818 nEndCol
= nMergeTestEndCol
;
1825 else if( eCmd
== INS_CELLSRIGHT
|| eCmd
== INS_INSCOLS
)
1828 nStartCol
= aExtendMergeRange
.aStart
.Col();
1829 nEndCol
= aExtendMergeRange
.aEnd
.Col();
1830 if( eCmd
== INS_CELLSRIGHT
)
1832 nEndRow
= nMergeTestEndRow
;
1841 if( !qIncreaseRange
.empty() )
1843 for( ::std::vector
<ScRange
>::const_iterator
iIter( qIncreaseRange
.begin()); iIter
!= qIncreaseRange
.end(); ++iIter
)
1845 ScRange
aRange( *iIter
);
1846 if( pDoc
->HasAttrib( aRange
, HASATTR_OVERLAPPED
| HASATTR_MERGED
) )
1848 UnmergeCells( aRange
, true );
1856 rDocShell
.ErrorMessage(STR_MSSG_INSERTCELLS_0
);
1857 rDocShell
.GetUndoManager()->LeaveListAction();
1867 bSuccess
= pDoc
->InsertRow( nStartCol
, 0, nEndCol
, MAXTAB
, nStartRow
, static_cast<SCSIZE
>(nEndRow
-nStartRow
+1), pRefUndoDoc
, &aFullMark
);
1868 nPaintEndRow
= MAXROW
;
1871 bSuccess
= pDoc
->InsertRow( 0, 0, MAXCOL
, MAXTAB
, nStartRow
, static_cast<SCSIZE
>(nEndRow
-nStartRow
+1), pRefUndoDoc
, &aFullMark
);
1873 nPaintEndCol
= MAXCOL
;
1874 nPaintEndRow
= MAXROW
;
1875 nPaintFlags
|= PAINT_LEFT
;
1877 case INS_CELLSRIGHT
:
1878 bSuccess
= pDoc
->InsertCol( nStartRow
, 0, nEndRow
, MAXTAB
, nStartCol
, static_cast<SCSIZE
>(nEndCol
-nStartCol
+1), pRefUndoDoc
, &aFullMark
);
1879 nPaintEndCol
= MAXCOL
;
1882 bSuccess
= pDoc
->InsertCol( 0, 0, MAXROW
, MAXTAB
, nStartCol
, static_cast<SCSIZE
>(nEndCol
-nStartCol
+1), pRefUndoDoc
, &aFullMark
);
1884 nPaintEndRow
= MAXROW
;
1885 nPaintEndCol
= MAXCOL
;
1886 nPaintFlags
|= PAINT_TOP
;
1889 OSL_FAIL("Falscher Code beim Einfuegen");
1896 SCTAB
* pTabs
= NULL
;
1897 SCTAB
* pScenarios
= NULL
;
1902 pTabs
= new SCTAB
[nSelCount
];
1903 pScenarios
= new SCTAB
[nSelCount
];
1905 itr
= aMark
.begin();
1906 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
1909 for( SCTAB j
=*itr
+1; j
<nTabCount
&& pDoc
->IsScenario(j
); j
++ )
1912 pScenarios
[nUndoPos
] = nCount
;
1913 pTabs
[nUndoPos
] = *itr
;
1919 rDocShell
.GetUndoManager()->LeaveListAction();
1922 rDocShell
.GetUndoManager()->AddUndoAction( new ScUndoInsertCells(
1923 &rDocShell
, ScRange( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
),
1924 nUndoPos
, pTabs
, pScenarios
, eCmd
, pRefUndoDoc
, pUndoData
, bPartOfPaste
) );
1927 // #i8302 : we remerge growing ranges, with the new part inserted
1929 while( !qIncreaseRange
.empty() )
1931 ScRange aRange
= qIncreaseRange
.back();
1932 if( !pDoc
->HasAttrib( aRange
, HASATTR_OVERLAPPED
| HASATTR_MERGED
) )
1938 aRange
.aEnd
.IncRow(static_cast<SCsCOL
>(nEndRow
-nStartRow
+1));
1940 case INS_CELLSRIGHT
:
1942 aRange
.aEnd
.IncCol(static_cast<SCsCOL
>(nEndCol
-nStartCol
+1));
1947 ScCellMergeOption
aMergeOption(
1948 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
1949 aRange
.aEnd
.Col(), aRange
.aEnd
.Row() );
1950 aMergeOption
.maTabs
.insert(aRange
.aStart
.Tab());
1951 MergeCells(aMergeOption
, false, true, true);
1953 qIncreaseRange
.pop_back();
1957 rDocShell
.GetUndoManager()->LeaveListAction();
1959 itr
= aMark
.begin();
1960 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
1963 pDoc
->SetDrawPageSize(i
);
1966 pDoc
->ExtendMerge( nMergeTestStartCol
, nMergeTestStartRow
, nMergeTestEndCol
, nMergeTestEndRow
, i
, true );
1968 pDoc
->RefreshAutoFilter( nMergeTestStartCol
, nMergeTestStartRow
, nMergeTestEndCol
, nMergeTestEndRow
, i
);
1970 if ( eCmd
== INS_INSROWS
|| eCmd
== INS_INSCOLS
)
1971 pDoc
->UpdatePageBreaks( i
);
1973 sal_uInt16 nExtFlags
= 0;
1974 rDocShell
.UpdatePaintExt( nExtFlags
, nPaintStartCol
, nPaintStartRow
, i
, nPaintEndCol
, nPaintEndRow
, i
);
1976 SCTAB nScenarioCount
= 0;
1978 for( SCTAB j
= i
+1; j
<nTabCount
&& pDoc
->IsScenario(j
); j
++ )
1981 bool bAdjusted
= ( eCmd
== INS_INSROWS
) ? AdjustRowHeight(ScRange(0, nStartRow
, i
, MAXCOL
, nEndRow
, i
+nScenarioCount
)) :
1982 AdjustRowHeight(ScRange(0, nPaintStartRow
, i
, MAXCOL
, nPaintEndRow
, i
+nScenarioCount
));
1985 // paint only what is not done by AdjustRowHeight
1986 if (nPaintFlags
& PAINT_TOP
)
1987 rDocShell
.PostPaint( nPaintStartCol
, nPaintStartRow
, i
, nPaintEndCol
, nPaintEndRow
, i
+nScenarioCount
, PAINT_TOP
);
1990 rDocShell
.PostPaint( nPaintStartCol
, nPaintStartRow
, i
, nPaintEndCol
, nPaintEndRow
, i
+nScenarioCount
, nPaintFlags
, nExtFlags
);
1997 while( !qIncreaseRange
.empty() )
1999 ScRange aRange
= qIncreaseRange
.back();
2000 ScCellMergeOption
aMergeOption(
2001 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
2002 aRange
.aEnd
.Col(), aRange
.aEnd
.Row() );
2003 MergeCells(aMergeOption
, false, true, true);
2004 qIncreaseRange
.pop_back();
2009 pViewSh
->MarkRange( rRange
, false );
2010 pViewSh
->SetCursor( nCursorCol
, nCursorRow
);
2014 rDocShell
.GetUndoManager()->LeaveListAction();
2015 rDocShell
.GetUndoManager()->RemoveLastUndoAction();
2020 rDocShell
.ErrorMessage(STR_INSERT_FULL
); // Spalte/Zeile voll
2023 aModificator
.SetDocumentModified();
2025 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED
) );
2029 bool ScDocFunc::DeleteCells( const ScRange
& rRange
, const ScMarkData
* pTabMark
, DelCellCmd eCmd
,
2030 bool bRecord
, bool bApi
)
2032 ScDocShellModificator
aModificator( rDocShell
);
2034 SCCOL nStartCol
= rRange
.aStart
.Col();
2035 SCROW nStartRow
= rRange
.aStart
.Row();
2036 SCTAB nStartTab
= rRange
.aStart
.Tab();
2037 SCCOL nEndCol
= rRange
.aEnd
.Col();
2038 SCROW nEndRow
= rRange
.aEnd
.Row();
2039 SCTAB nEndTab
= rRange
.aEnd
.Tab();
2041 if ( !ValidRow(nStartRow
) || !ValidRow(nEndRow
) )
2043 OSL_FAIL("invalid row in DeleteCells");
2047 ScDocument
* pDoc
= rDocShell
.GetDocument();
2048 SCTAB nTabCount
= pDoc
->GetTableCount();
2049 SCCOL nPaintStartCol
= nStartCol
;
2050 SCROW nPaintStartRow
= nStartRow
;
2051 SCCOL nPaintEndCol
= nEndCol
;
2052 SCROW nPaintEndRow
= nEndRow
;
2053 sal_uInt16 nPaintFlags
= PAINT_GRID
;
2055 if (bRecord
&& !pDoc
->IsUndoEnabled())
2064 for(SCTAB i
=0; i
<nTabCount
; i
++ )
2066 if( !pDoc
->IsScenario(i
) )
2069 if( nCount
== nEndTab
+1 )
2071 aMark
.SelectTable(i
, true);
2078 ScMarkData
aFullMark( aMark
); // including scenario sheets
2079 ScMarkData::iterator itr
= aMark
.begin(), itrEnd
= aMark
.end();
2080 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
2081 for( SCTAB j
= *itr
+1; j
<nTabCount
&& pDoc
->IsScenario(j
); j
++ )
2082 aFullMark
.SelectTable( j
, true );
2084 SCTAB nSelCount
= aMark
.GetSelectCount();
2086 SCCOL nUndoStartCol
= nStartCol
;
2087 SCROW nUndoStartRow
= nStartRow
;
2088 SCCOL nUndoEndCol
= nEndCol
;
2089 SCROW nUndoEndRow
= nEndRow
;
2091 ScRange
aExtendMergeRange( rRange
);
2093 if( rRange
.aStart
== rRange
.aEnd
&& pDoc
->HasAttrib(rRange
, HASATTR_MERGED
) )
2095 pDoc
->ExtendMerge( aExtendMergeRange
);
2096 pDoc
->ExtendOverlapped( aExtendMergeRange
);
2097 nUndoEndCol
= aExtendMergeRange
.aEnd
.Col();
2098 nUndoEndRow
= aExtendMergeRange
.aEnd
.Row();
2099 nPaintEndCol
= nUndoEndCol
;
2100 nPaintEndRow
= nUndoEndRow
;
2103 if (eCmd
==DEL_DELROWS
)
2106 nUndoEndCol
= MAXCOL
;
2108 if (eCmd
==DEL_DELCOLS
)
2111 nUndoEndRow
= MAXROW
;
2115 SCCOL nEditTestEndX
= nUndoEndCol
;
2116 if ( eCmd
==DEL_DELCOLS
|| eCmd
==DEL_CELLSLEFT
)
2117 nEditTestEndX
= MAXCOL
;
2118 SCROW nEditTestEndY
= nUndoEndRow
;
2119 if ( eCmd
==DEL_DELROWS
|| eCmd
==DEL_CELLSUP
)
2120 nEditTestEndY
= MAXROW
;
2121 ScEditableTester
aTester( pDoc
, nUndoStartCol
, nUndoStartRow
, nEditTestEndX
, nEditTestEndY
, aMark
);
2122 if (!aTester
.IsEditable())
2125 rDocShell
.ErrorMessage(aTester
.GetMessageId());
2129 if (!canDeleteCellsByPivot(rRange
, aMark
, eCmd
, pDoc
))
2132 rDocShell
.ErrorMessage(STR_NO_INSERT_DELETE_OVER_PIVOT_TABLE
);
2135 // Test zusammengefasste
2137 SCCOL nMergeTestEndCol
= (eCmd
==DEL_CELLSLEFT
) ? MAXCOL
: nUndoEndCol
;
2138 SCROW nMergeTestEndRow
= (eCmd
==DEL_CELLSUP
) ? MAXROW
: nUndoEndRow
;
2139 SCCOL nExtendStartCol
= nUndoStartCol
;
2140 SCROW nExtendStartRow
= nUndoStartRow
;
2141 bool bNeedRefresh
= false;
2143 //Issue 8302 want to be able to insert into the middle of merged cells
2144 //the patch comes from maoyg
2145 ::std::vector
<ScRange
> qDecreaseRange
;
2146 bool bDeletingMerge
= false;
2147 OUString aUndo
= ScGlobal::GetRscString( STR_UNDO_DELETECELLS
);
2149 rDocShell
.GetUndoManager()->EnterListAction( aUndo
, aUndo
);
2151 itr
= aMark
.begin();
2152 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
2155 if ( pDoc
->HasAttrib( nUndoStartCol
, nUndoStartRow
, i
, nMergeTestEndCol
, nMergeTestEndRow
, i
, HASATTR_MERGED
| HASATTR_OVERLAPPED
))
2157 SCCOL nMergeStartCol
= nUndoStartCol
;
2158 SCROW nMergeStartRow
= nUndoStartRow
;
2159 SCCOL nMergeEndCol
= nMergeTestEndCol
;
2160 SCROW nMergeEndRow
= nMergeTestEndRow
;
2162 pDoc
->ExtendMerge( nMergeStartCol
, nMergeStartRow
, nMergeEndCol
, nMergeEndRow
, i
);
2163 pDoc
->ExtendOverlapped( nMergeStartCol
, nMergeStartRow
, nMergeEndCol
, nMergeEndRow
, i
);
2164 if( ( eCmd
== DEL_CELLSUP
&& ( nMergeStartCol
!= nUndoStartCol
|| nMergeEndCol
!= nMergeTestEndCol
))||
2165 ( eCmd
== DEL_CELLSLEFT
&& ( nMergeStartRow
!= nUndoStartRow
|| nMergeEndRow
!= nMergeTestEndRow
)))
2168 rDocShell
.ErrorMessage(STR_MSSG_DELETECELLS_0
);
2169 rDocShell
.GetUndoManager()->LeaveListAction();
2173 nExtendStartCol
= nMergeStartCol
;
2174 nExtendStartRow
= nMergeStartRow
;
2175 SCCOL nTestCol
= -1;
2176 SCROW nTestRow1
= -1;
2177 SCROW nTestRow2
= -1;
2179 ScDocAttrIterator
aTestIter( pDoc
, i
, nUndoStartCol
, nUndoStartRow
, nMergeTestEndCol
, nMergeTestEndRow
);
2180 ScRange
aExtendRange( nUndoStartCol
, nUndoStartRow
, i
, nMergeTestEndCol
, nMergeTestEndRow
, i
);
2181 const ScPatternAttr
* pPattern
= NULL
;
2182 const ScMergeAttr
* pMergeFlag
= NULL
;
2183 const ScMergeFlagAttr
* pMergeFlagAttr
= NULL
;
2184 while ( ( pPattern
= aTestIter
.GetNext( nTestCol
, nTestRow1
, nTestRow2
) ) != NULL
)
2186 pMergeFlag
= (const ScMergeAttr
*) &pPattern
->GetItem( ATTR_MERGE
);
2187 pMergeFlagAttr
= (const ScMergeFlagAttr
*) &pPattern
->GetItem( ATTR_MERGE_FLAG
);
2188 sal_Int16 nNewFlags
= pMergeFlagAttr
->GetValue() & ( SC_MF_HOR
| SC_MF_VER
);
2189 if( ( pMergeFlag
&& pMergeFlag
->IsMerged() ) || nNewFlags
== SC_MF_HOR
|| nNewFlags
== SC_MF_VER
)
2191 ScRange
aRange( nTestCol
, nTestRow1
, i
);
2192 pDoc
->ExtendOverlapped( aRange
);
2193 pDoc
->ExtendMerge( aRange
, true );
2195 if( nTestRow1
< nTestRow2
&& nNewFlags
== SC_MF_HOR
)
2197 for( SCROW nTestRow
= nTestRow1
; nTestRow
<= nTestRow2
; nTestRow
++ )
2199 ScRange
aTestRange( nTestCol
, nTestRow
, i
);
2200 pDoc
->ExtendOverlapped( aTestRange
);
2201 pDoc
->ExtendMerge( aTestRange
, true );
2202 ScRange
aMergeRange( aTestRange
.aStart
.Col(),aTestRange
.aStart
.Row(), i
);
2203 if( !aExtendRange
.In( aMergeRange
) )
2205 qDecreaseRange
.push_back( aTestRange
);
2206 bDeletingMerge
= true;
2212 ScRange
aMergeRange( aRange
.aStart
.Col(),aRange
.aStart
.Row(), i
);
2213 if( !aExtendRange
.In( aMergeRange
) )
2215 qDecreaseRange
.push_back( aRange
);
2217 bDeletingMerge
= true;
2222 if( bDeletingMerge
)
2225 if( eCmd
== DEL_DELROWS
|| eCmd
== DEL_CELLSUP
)
2227 nStartRow
= aExtendMergeRange
.aStart
.Row();
2228 nEndRow
= aExtendMergeRange
.aEnd
.Row();
2229 bNeedRefresh
= true;
2231 if( eCmd
== DEL_CELLSUP
)
2233 nEndCol
= aExtendMergeRange
.aEnd
.Col();
2241 else if( eCmd
== DEL_CELLSLEFT
|| eCmd
== DEL_DELCOLS
)
2244 nStartCol
= aExtendMergeRange
.aStart
.Col();
2245 nEndCol
= aExtendMergeRange
.aEnd
.Col();
2246 if( eCmd
== DEL_CELLSLEFT
)
2248 nEndRow
= aExtendMergeRange
.aEnd
.Row();
2249 bNeedRefresh
= true;
2258 if( !qDecreaseRange
.empty() )
2260 for( ::std::vector
<ScRange
>::const_iterator
iIter( qDecreaseRange
.begin()); iIter
!= qDecreaseRange
.end(); ++iIter
)
2262 ScRange
aRange( *iIter
);
2263 if( pDoc
->HasAttrib( aRange
, HASATTR_OVERLAPPED
| HASATTR_MERGED
) )
2265 UnmergeCells( aRange
, true );
2273 rDocShell
.ErrorMessage(STR_MSSG_DELETECELLS_0
);
2274 rDocShell
.GetUndoManager()->LeaveListAction();
2284 WaitObject
aWait( rDocShell
.GetActiveDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference
2286 ScDocument
* pUndoDoc
= NULL
;
2287 ScDocument
* pRefUndoDoc
= NULL
;
2288 ScRefUndoData
* pUndoData
= NULL
;
2291 // With the fix for #101329#, UpdateRef always puts cells into pRefUndoDoc at their old position,
2292 // so it's no longer necessary to copy more than the deleted range into pUndoDoc.
2294 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
2295 pUndoDoc
->InitUndo( pDoc
, 0, nTabCount
-1, (eCmd
==DEL_DELCOLS
), (eCmd
==DEL_DELROWS
) );
2296 itr
= aMark
.begin();
2297 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
2299 SCTAB nScenarioCount
= 0;
2301 for( SCTAB j
= *itr
+1; j
<nTabCount
&& pDoc
->IsScenario(j
); j
++ )
2304 pDoc
->CopyToDocument( nUndoStartCol
, nUndoStartRow
, *itr
, nUndoEndCol
, nUndoEndRow
, *itr
+nScenarioCount
,
2305 IDF_ALL
| IDF_NOCAPTIONS
, false, pUndoDoc
);
2308 pRefUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
2309 pRefUndoDoc
->InitUndo( pDoc
, 0, nTabCount
-1, false, false );
2311 pUndoData
= new ScRefUndoData( pDoc
);
2313 pDoc
->BeginDrawUndo();
2316 sal_uInt16 nExtFlags
= 0;
2317 itr
= aMark
.begin();
2318 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
2320 rDocShell
.UpdatePaintExt( nExtFlags
, nStartCol
, nStartRow
, *itr
, nEndCol
, nEndRow
, *itr
);
2323 bool bUndoOutline
= false;
2327 pDoc
->DeleteRow( nStartCol
, 0, nEndCol
, MAXTAB
, nStartRow
, static_cast<SCSIZE
>(nEndRow
-nStartRow
+1), pRefUndoDoc
, NULL
, &aFullMark
);
2328 nPaintEndRow
= MAXROW
;
2331 pDoc
->DeleteRow( 0, 0, MAXCOL
, MAXTAB
, nStartRow
, static_cast<SCSIZE
>(nEndRow
-nStartRow
+1), pRefUndoDoc
, &bUndoOutline
, &aFullMark
);
2333 nPaintEndCol
= MAXCOL
;
2334 nPaintEndRow
= MAXROW
;
2335 nPaintFlags
|= PAINT_LEFT
;
2338 pDoc
->DeleteCol( nStartRow
, 0, nEndRow
, MAXTAB
, nStartCol
, static_cast<SCSIZE
>(nEndCol
-nStartCol
+1), pRefUndoDoc
, NULL
, &aFullMark
);
2339 nPaintEndCol
= MAXCOL
;
2342 pDoc
->DeleteCol( 0, 0, MAXROW
, MAXTAB
, nStartCol
, static_cast<SCSIZE
>(nEndCol
-nStartCol
+1), pRefUndoDoc
, &bUndoOutline
, &aFullMark
);
2344 nPaintEndRow
= MAXROW
;
2345 nPaintEndCol
= MAXCOL
;
2346 nPaintFlags
|= PAINT_TOP
;
2349 OSL_FAIL("Falscher Code beim Loeschen");
2353 //! Test, ob Outline in Groesse geaendert
2357 itr
= aFullMark
.begin(), itrEnd
= aFullMark
.end();
2358 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
2359 pRefUndoDoc
->DeleteAreaTab(nUndoStartCol
,nUndoStartRow
,nUndoEndCol
,nUndoEndRow
, *itr
, IDF_ALL
);
2361 // alle Tabellen anlegen, damit Formeln kopiert werden koennen:
2362 pUndoDoc
->AddUndoTab( 0, nTabCount
-1, false, false );
2364 // kopieren mit bColRowFlags=false (#54194#)
2365 pRefUndoDoc
->CopyToDocument(0,0,0,MAXCOL
,MAXROW
,MAXTAB
,IDF_FORMULA
,false,pUndoDoc
,NULL
,false);
2368 SCTAB
* pTabs
= new SCTAB
[nSelCount
];
2369 SCTAB
* pScenarios
= new SCTAB
[nSelCount
];
2372 itr
= aMark
.begin(), itrEnd
= aMark
.end();
2373 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
2376 for( SCTAB j
=*itr
+1; j
<nTabCount
&& pDoc
->IsScenario(j
); j
++ )
2379 pScenarios
[nUndoPos
] = nCount
;
2380 pTabs
[nUndoPos
] = *itr
;
2384 if( !bDeletingMerge
)
2386 rDocShell
.GetUndoManager()->LeaveListAction();
2389 rDocShell
.GetUndoManager()->AddUndoAction( new ScUndoDeleteCells(
2390 &rDocShell
, ScRange( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
),nUndoPos
, pTabs
, pScenarios
,
2391 eCmd
, pUndoDoc
, pUndoData
) );
2394 // #i8302 want to be able to insert into the middle of merged cells
2395 // the patch comes from maoyg
2397 while( !qDecreaseRange
.empty() )
2399 ScRange aRange
= qDecreaseRange
.back();
2401 long nDecreaseRowCount
= 0;
2402 long nDecreaseColCount
= 0;
2403 if( eCmd
== DEL_CELLSUP
|| eCmd
== DEL_DELROWS
)
2405 if( nStartRow
>= aRange
.aStart
.Row() && nStartRow
<= aRange
.aEnd
.Row() && nEndRow
>= aRange
.aStart
.Row() && nEndRow
<= aRange
.aEnd
.Row() )
2406 nDecreaseRowCount
= nEndRow
-nStartRow
+1;
2407 else if( nStartRow
>= aRange
.aStart
.Row() && nStartRow
<= aRange
.aEnd
.Row() && nEndRow
>= aRange
.aStart
.Row() && nEndRow
>= aRange
.aEnd
.Row() )
2408 nDecreaseRowCount
= aRange
.aEnd
.Row()-nStartRow
+1;
2409 else if( nStartRow
>= aRange
.aStart
.Row() && nStartRow
>= aRange
.aEnd
.Row() && nEndRow
>= aRange
.aStart
.Row() && nEndRow
<= aRange
.aEnd
.Row() )
2410 nDecreaseRowCount
= aRange
.aEnd
.Row()-nEndRow
+1;
2412 else if( eCmd
== DEL_CELLSLEFT
|| eCmd
== DEL_DELCOLS
)
2414 if( nStartCol
>= aRange
.aStart
.Col() && nStartCol
<= aRange
.aEnd
.Col() && nEndCol
>= aRange
.aStart
.Col() && nEndCol
<= aRange
.aEnd
.Col() )
2415 nDecreaseColCount
= nEndCol
-nStartCol
+1;
2416 else if( nStartCol
>= aRange
.aStart
.Col() && nStartCol
<= aRange
.aEnd
.Col() && nEndCol
>= aRange
.aStart
.Col() && nEndCol
>= aRange
.aEnd
.Col() )
2417 nDecreaseColCount
= aRange
.aEnd
.Col()-nStartCol
+1;
2418 else if( nStartCol
>= aRange
.aStart
.Col() && nStartCol
>= aRange
.aEnd
.Col() && nEndCol
>= aRange
.aStart
.Col() && nEndCol
<= aRange
.aEnd
.Col() )
2419 nDecreaseColCount
= aRange
.aEnd
.Col()-nEndCol
+1;
2426 aRange
.aEnd
.SetRow(static_cast<SCsCOL
>( aRange
.aEnd
.Row()-nDecreaseRowCount
));
2430 aRange
.aEnd
.SetCol(static_cast<SCsCOL
>( aRange
.aEnd
.Col()-nDecreaseColCount
));
2436 if( !pDoc
->HasAttrib( aRange
, HASATTR_OVERLAPPED
| HASATTR_MERGED
) )
2438 ScCellMergeOption
aMergeOption(aRange
);
2439 MergeCells( aMergeOption
, false, true, true );
2441 qDecreaseRange
.pop_back();
2444 if( bDeletingMerge
)
2445 rDocShell
.GetUndoManager()->LeaveListAction();
2449 // #i51445# old merge flag attributes must be deleted also for single cells,
2450 // not only for whole columns/rows
2452 if ( eCmd
==DEL_DELCOLS
|| eCmd
==DEL_CELLSLEFT
)
2453 nMergeTestEndCol
= MAXCOL
;
2454 if ( eCmd
==DEL_DELROWS
|| eCmd
==DEL_CELLSUP
)
2455 nMergeTestEndRow
= MAXROW
;
2456 ScPatternAttr
aPattern( pDoc
->GetPool() );
2457 aPattern
.GetItemSet().Put( ScMergeFlagAttr() );
2459 pDoc
->ApplyPatternArea( nExtendStartCol
, nExtendStartRow
, nMergeTestEndCol
, nMergeTestEndRow
, aMark
, aPattern
);
2461 itr
= aMark
.begin(), itrEnd
= aMark
.end();
2462 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
2464 SCTAB nScenarioCount
= 0;
2466 for( SCTAB j
= *itr
+1; j
<nTabCount
&& pDoc
->IsScenario(j
); j
++ )
2469 ScRange
aMergedRange( nExtendStartCol
, nExtendStartRow
, *itr
, nMergeTestEndCol
, nMergeTestEndRow
, *itr
+nScenarioCount
);
2470 pDoc
->ExtendMerge( aMergedRange
, true );
2474 itr
= aMark
.begin(), itrEnd
= aMark
.end();
2475 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
2477 pDoc
->SetDrawPageSize(*itr
);
2479 if ( eCmd
== DEL_DELCOLS
|| eCmd
== DEL_DELROWS
)
2480 pDoc
->UpdatePageBreaks( *itr
);
2482 rDocShell
.UpdatePaintExt( nExtFlags
, nPaintStartCol
, nPaintStartRow
, *itr
, nPaintEndCol
, nPaintEndRow
, *itr
);
2484 SCTAB nScenarioCount
= 0;
2486 for( SCTAB j
= *itr
+1; j
<nTabCount
&& pDoc
->IsScenario(j
); j
++ )
2489 // ganze Zeilen loeschen: nichts anpassen
2490 if ( eCmd
== DEL_DELROWS
|| !AdjustRowHeight(ScRange( 0, nPaintStartRow
, *itr
, MAXCOL
, nPaintEndRow
, *itr
+nScenarioCount
)) )
2491 rDocShell
.PostPaint( nPaintStartCol
, nPaintStartRow
, *itr
, nPaintEndCol
, nPaintEndRow
, *itr
+nScenarioCount
, nPaintFlags
, nExtFlags
);
2494 // paint only what is not done by AdjustRowHeight
2495 if (nExtFlags
& SC_PF_LINES
)
2496 lcl_PaintAbove( rDocShell
, ScRange( nPaintStartCol
, nPaintStartRow
, *itr
, nPaintEndCol
, nPaintEndRow
, *itr
+nScenarioCount
) );
2497 if (nPaintFlags
& PAINT_TOP
)
2498 rDocShell
.PostPaint( nPaintStartCol
, nPaintStartRow
, *itr
, nPaintEndCol
, nPaintEndRow
, *itr
+nScenarioCount
, PAINT_TOP
);
2502 aModificator
.SetDocumentModified();
2504 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED
) );
2509 sal_Bool
ScDocFunc::MoveBlock( const ScRange
& rSource
, const ScAddress
& rDestPos
,
2510 sal_Bool bCut
, sal_Bool bRecord
, sal_Bool bPaint
, sal_Bool bApi
)
2512 ScDocShellModificator
aModificator( rDocShell
);
2514 SCCOL nStartCol
= rSource
.aStart
.Col();
2515 SCROW nStartRow
= rSource
.aStart
.Row();
2516 SCTAB nStartTab
= rSource
.aStart
.Tab();
2517 SCCOL nEndCol
= rSource
.aEnd
.Col();
2518 SCROW nEndRow
= rSource
.aEnd
.Row();
2519 SCTAB nEndTab
= rSource
.aEnd
.Tab();
2520 SCCOL nDestCol
= rDestPos
.Col();
2521 SCROW nDestRow
= rDestPos
.Row();
2522 SCTAB nDestTab
= rDestPos
.Tab();
2524 if ( !ValidRow(nStartRow
) || !ValidRow(nEndRow
) || !ValidRow(nDestRow
) )
2526 OSL_FAIL("invalid row in MoveBlock");
2530 // zugehoerige Szenarien auch anpassen - nur wenn innerhalb einer Tabelle verschoben wird!
2531 sal_Bool bScenariosAdded
= false;
2532 ScDocument
* pDoc
= rDocShell
.GetDocument();
2533 if (bRecord
&& !pDoc
->IsUndoEnabled())
2536 SCTAB nTabCount
= pDoc
->GetTableCount();
2537 if ( nDestTab
== nStartTab
&& !pDoc
->IsScenario(nEndTab
) )
2538 while ( nEndTab
+1 < nTabCount
&& pDoc
->IsScenario(nEndTab
+1) )
2541 bScenariosAdded
= sal_True
;
2544 SCTAB nSrcTabCount
= nEndTab
-nStartTab
+1;
2545 SCTAB nDestEndTab
= nDestTab
+nSrcTabCount
-1;
2548 ScDocument
* pClipDoc
= new ScDocument( SCDOCMODE_CLIP
);
2550 ScMarkData aSourceMark
;
2551 for (nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
2552 aSourceMark
.SelectTable( nTab
, sal_True
); // Source selektieren
2553 aSourceMark
.SetMarkArea( rSource
);
2555 ScDocShellRef aDragShellRef
;
2556 if ( pDoc
->HasOLEObjectsInArea( rSource
) )
2558 aDragShellRef
= new ScDocShell
; // DocShell needs a Ref immediately
2559 aDragShellRef
->DoInitNew(NULL
);
2561 ScDrawLayer::SetGlobalDrawPersist(aDragShellRef
);
2563 ScClipParam
aClipParam(ScRange(nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nStartTab
), bCut
);
2564 pDoc
->CopyToClip(aClipParam
, pClipDoc
, &aSourceMark
, false, bScenariosAdded
, true);
2566 ScDrawLayer::SetGlobalDrawPersist(NULL
);
2568 SCCOL nOldEndCol
= nEndCol
;
2569 SCROW nOldEndRow
= nEndRow
;
2570 sal_Bool bClipOver
= false;
2571 for (nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
2573 SCCOL nTmpEndCol
= nOldEndCol
;
2574 SCROW nTmpEndRow
= nOldEndRow
;
2575 if (pDoc
->ExtendMerge( nStartCol
, nStartRow
, nTmpEndCol
, nTmpEndRow
, nTab
))
2576 bClipOver
= sal_True
;
2577 if ( nTmpEndCol
> nEndCol
) nEndCol
= nTmpEndCol
;
2578 if ( nTmpEndRow
> nEndRow
) nEndRow
= nTmpEndRow
;
2581 SCCOL nDestEndCol
= nDestCol
+ ( nOldEndCol
-nStartCol
);
2582 SCROW nDestEndRow
= nDestRow
+ ( nOldEndRow
-nStartRow
);
2584 SCCOL nUndoEndCol
= nDestCol
+ ( nEndCol
-nStartCol
); // erweitert im Zielblock
2585 SCROW nUndoEndRow
= nDestRow
+ ( nEndRow
-nStartRow
);
2587 sal_Bool bIncludeFiltered
= bCut
;
2588 if ( !bIncludeFiltered
)
2590 // adjust sizes to include only non-filtered rows
2594 pClipDoc
->GetClipArea( nClipX
, nClipY
, false );
2595 SCROW nUndoAdd
= nUndoEndRow
- nDestEndRow
;
2596 nDestEndRow
= nDestRow
+ nClipY
;
2597 nUndoEndRow
= nDestEndRow
+ nUndoAdd
;
2600 if (!ValidCol(nUndoEndCol
) || !ValidRow(nUndoEndRow
))
2603 rDocShell
.ErrorMessage(STR_PASTE_FULL
);
2608 // Test auf Zellschutz
2610 ScEditableTester aTester
;
2611 for (nTab
=nDestTab
; nTab
<=nDestEndTab
; nTab
++)
2612 aTester
.TestBlock( pDoc
, nTab
, nDestCol
,nDestRow
, nUndoEndCol
,nUndoEndRow
);
2614 for (nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
2615 aTester
.TestBlock( pDoc
, nTab
, nStartCol
,nStartRow
, nEndCol
,nEndRow
);
2617 if (!aTester
.IsEditable())
2620 rDocShell
.ErrorMessage(aTester
.GetMessageId());
2625 // Test auf zusammengefasste - beim Verschieben erst nach dem Loeschen
2627 if (bClipOver
&& !bCut
)
2628 if (pDoc
->HasAttrib( nDestCol
,nDestRow
,nDestTab
, nUndoEndCol
,nUndoEndRow
,nDestEndTab
,
2629 HASATTR_MERGED
| HASATTR_OVERLAPPED
))
2630 { // "Zusammenfassen nicht verschachteln !"
2632 rDocShell
.ErrorMessage(STR_MSSG_MOVEBLOCKTO_0
);
2637 // Are there borders in the cells? (for painting)
2639 sal_uInt16 nSourceExt
= 0;
2640 rDocShell
.UpdatePaintExt( nSourceExt
, nStartCol
,nStartRow
,nStartTab
, nEndCol
,nEndRow
,nEndTab
);
2641 sal_uInt16 nDestExt
= 0;
2642 rDocShell
.UpdatePaintExt( nDestExt
, nDestCol
,nDestRow
,nDestTab
, nDestEndCol
,nDestEndRow
,nDestEndTab
);
2648 ScDocument
* pUndoDoc
= NULL
;
2649 ScDocument
* pRefUndoDoc
= NULL
;
2650 ScRefUndoData
* pUndoData
= NULL
;
2653 sal_Bool bWholeCols
= ( nStartRow
== 0 && nEndRow
== MAXROW
);
2654 sal_Bool bWholeRows
= ( nStartCol
== 0 && nEndCol
== MAXCOL
);
2655 sal_uInt16 nUndoFlags
= (IDF_ALL
& ~IDF_OBJECTS
) | IDF_NOCAPTIONS
;
2657 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
2658 pUndoDoc
->InitUndo( pDoc
, nStartTab
, nEndTab
, bWholeCols
, bWholeRows
);
2662 pDoc
->CopyToDocument( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
,
2663 nUndoFlags
, false, pUndoDoc
);
2664 pRefUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
2665 pRefUndoDoc
->InitUndo( pDoc
, 0, nTabCount
-1, false, false );
2668 if ( nDestTab
!= nStartTab
)
2669 pUndoDoc
->AddUndoTab( nDestTab
, nDestEndTab
, bWholeCols
, bWholeRows
);
2670 pDoc
->CopyToDocument( nDestCol
, nDestRow
, nDestTab
,
2671 nDestEndCol
, nDestEndRow
, nDestEndTab
,
2672 nUndoFlags
, false, pUndoDoc
);
2674 pUndoData
= new ScRefUndoData( pDoc
);
2676 pDoc
->BeginDrawUndo();
2679 sal_Bool bSourceHeight
= false; // Hoehen angepasst?
2682 ScMarkData aDelMark
; // only for tables
2683 for (nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
2685 pDoc
->DeleteAreaTab( nStartCol
,nStartRow
, nOldEndCol
,nOldEndRow
, nTab
, IDF_ALL
);
2686 aDelMark
.SelectTable( nTab
, sal_True
);
2688 pDoc
->DeleteObjectsInArea( nStartCol
,nStartRow
, nOldEndCol
,nOldEndRow
, aDelMark
);
2690 // Test auf zusammengefasste
2693 if (pDoc
->HasAttrib( nDestCol
,nDestRow
,nDestTab
,
2694 nUndoEndCol
,nUndoEndRow
,nDestEndTab
,
2695 HASATTR_MERGED
| HASATTR_OVERLAPPED
))
2697 pDoc
->CopyFromClip( rSource
, aSourceMark
, IDF_ALL
, pRefUndoDoc
, pClipDoc
);
2698 for (nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
2700 SCCOL nTmpEndCol
= nEndCol
;
2701 SCROW nTmpEndRow
= nEndRow
;
2702 pDoc
->ExtendMerge( nStartCol
, nStartRow
, nTmpEndCol
, nTmpEndRow
, nTab
, sal_True
);
2705 // Fehlermeldung erst nach dem Wiederherstellen des Inhalts
2706 if (!bApi
) // "Zusammenfassen nicht verschachteln !"
2707 rDocShell
.ErrorMessage(STR_MSSG_MOVEBLOCKTO_0
);
2716 bSourceHeight
= AdjustRowHeight( rSource
, false );
2719 ScRange
aPasteDest( nDestCol
, nDestRow
, nDestTab
, nDestEndCol
, nDestEndRow
, nDestEndTab
);
2721 ScMarkData aDestMark
;
2722 for (nTab
=nDestTab
; nTab
<=nDestEndTab
; nTab
++)
2723 aDestMark
.SelectTable( nTab
, sal_True
); // Destination selektieren
2724 aDestMark
.SetMarkArea( aPasteDest
);
2726 /* Do not drawing objects here. While pasting, the
2727 function ScDocument::UpdateReference() is called which calls
2728 ScDrawLayer::MoveCells() which may move away inserted objects to wrong
2729 positions (e.g. if source and destination range overlaps).*/
2730 pDoc
->CopyFromClip( aPasteDest
, aDestMark
, IDF_ALL
& ~(IDF_OBJECTS
),
2731 pRefUndoDoc
, pClipDoc
, sal_True
, false, bIncludeFiltered
);
2734 // skipped rows and merged cells don't mix
2735 if ( !bIncludeFiltered
&& pClipDoc
->HasClipFilteredRows() )
2736 UnmergeCells( aPasteDest
, false );
2738 VirtualDevice aVirtDev
;
2739 sal_Bool bDestHeight
= AdjustRowHeight(
2740 ScRange( 0,nDestRow
,nDestTab
, MAXCOL
,nDestEndRow
,nDestEndTab
),
2743 /* Paste drawing objects after adjusting formula references
2744 and row heights. There are no cell notes or drawing objects, if the
2745 clipdoc does not contain a drawing layer.*/
2746 if ( pClipDoc
->GetDrawLayer() )
2747 pDoc
->CopyFromClip( aPasteDest
, aDestMark
, IDF_OBJECTS
,
2748 pRefUndoDoc
, pClipDoc
, sal_True
, false, bIncludeFiltered
);
2754 // alle Tabellen anlegen, damit Formeln kopiert werden koennen:
2755 pUndoDoc
->AddUndoTab( 0, nTabCount
-1, false, false );
2757 pRefUndoDoc
->DeleteArea( nDestCol
, nDestRow
, nDestEndCol
, nDestEndRow
, aSourceMark
, IDF_ALL
);
2758 // kopieren mit bColRowFlags=sal_False (#54194#)
2759 pRefUndoDoc
->CopyToDocument( 0, 0, 0, MAXCOL
, MAXROW
, MAXTAB
,
2760 IDF_FORMULA
, false, pUndoDoc
, NULL
, false );
2764 rDocShell
.GetUndoManager()->AddUndoAction(
2765 new ScUndoDragDrop( &rDocShell
, ScRange(
2766 nStartCol
, nStartRow
, nStartTab
,
2767 nOldEndCol
, nOldEndRow
, nEndTab
),
2768 ScAddress( nDestCol
, nDestRow
, nDestTab
),
2769 bCut
, pUndoDoc
, pUndoData
, bScenariosAdded
) );
2772 SCCOL nDestPaintEndCol
= nDestEndCol
;
2773 SCROW nDestPaintEndRow
= nDestEndRow
;
2774 for (nTab
=nDestTab
; nTab
<=nDestEndTab
; nTab
++)
2776 SCCOL nTmpEndCol
= nDestEndCol
;
2777 SCROW nTmpEndRow
= nDestEndRow
;
2778 pDoc
->ExtendMerge( nDestCol
, nDestRow
, nTmpEndCol
, nTmpEndRow
, nTab
, sal_True
);
2779 if (nTmpEndCol
> nDestPaintEndCol
) nDestPaintEndCol
= nTmpEndCol
;
2780 if (nTmpEndRow
> nDestPaintEndRow
) nDestPaintEndRow
= nTmpEndRow
;
2784 for (nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
2785 pDoc
->RefreshAutoFilter( nStartCol
, nStartRow
, nEndCol
, nEndRow
, nTab
);
2791 SCCOL nPaintStartX
= nDestCol
;
2792 SCROW nPaintStartY
= nDestRow
;
2793 SCCOL nPaintEndX
= nDestPaintEndCol
;
2794 SCROW nPaintEndY
= nDestPaintEndRow
;
2795 sal_uInt16 nFlags
= PAINT_GRID
;
2797 if ( nStartRow
==0 && nEndRow
==MAXROW
) // Breiten mitkopiert?
2799 nPaintEndX
= MAXCOL
;
2801 nPaintEndY
= MAXROW
;
2802 nFlags
|= PAINT_TOP
;
2804 if ( bDestHeight
|| ( nStartCol
== 0 && nEndCol
== MAXCOL
) )
2806 nPaintEndY
= MAXROW
;
2808 nPaintEndX
= MAXCOL
;
2809 nFlags
|= PAINT_LEFT
;
2811 if ( bScenariosAdded
)
2815 nPaintEndX
= MAXCOL
;
2816 nPaintEndY
= MAXROW
;
2819 rDocShell
.PostPaint( nPaintStartX
,nPaintStartY
,nDestTab
,
2820 nPaintEndX
,nPaintEndY
,nDestEndTab
, nFlags
, nSourceExt
| nDestExt
);
2826 nPaintStartX
= nStartCol
;
2827 nPaintStartY
= nStartRow
;
2828 nPaintEndX
= nEndCol
;
2829 nPaintEndY
= nEndRow
;
2830 nFlags
= PAINT_GRID
;
2832 if ( bSourceHeight
)
2834 nPaintEndY
= MAXROW
;
2836 nPaintEndX
= MAXCOL
;
2837 nFlags
|= PAINT_LEFT
;
2839 if ( bScenariosAdded
)
2843 nPaintEndX
= MAXCOL
;
2844 nPaintEndY
= MAXROW
;
2847 rDocShell
.PostPaint( nPaintStartX
,nPaintStartY
,nStartTab
,
2848 nPaintEndX
,nPaintEndY
,nEndTab
, nFlags
, nSourceExt
);
2852 aModificator
.SetDocumentModified();
2854 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED
) );
2860 //------------------------------------------------------------------------
2861 uno::Reference
< uno::XInterface
> GetDocModuleObject( SfxObjectShell
& rDocSh
, OUString
& sCodeName
)
2863 uno::Reference
< lang::XMultiServiceFactory
> xSF(rDocSh
.GetModel(), uno::UNO_QUERY
);
2864 uno::Reference
< container::XNameAccess
> xVBACodeNamedObjectAccess
;
2865 uno::Reference
< uno::XInterface
> xDocModuleApiObject
;
2868 xVBACodeNamedObjectAccess
.set( xSF
->createInstance("ooo.vba.VBAObjectModuleObjectProvider"), uno::UNO_QUERY
);
2869 xDocModuleApiObject
.set( xVBACodeNamedObjectAccess
->getByName( sCodeName
), uno::UNO_QUERY
);
2871 return xDocModuleApiObject
;
2875 static script::ModuleInfo
lcl_InitModuleInfo( SfxObjectShell
& rDocSh
, OUString
& sModule
)
2877 script::ModuleInfo sModuleInfo
;
2878 sModuleInfo
.ModuleType
= script::ModuleType::DOCUMENT
;
2879 sModuleInfo
.ModuleObject
= GetDocModuleObject( rDocSh
, sModule
);
2883 void VBA_InsertModule( ScDocument
& rDoc
, SCTAB nTab
, const OUString
& sModuleName
, const OUString
& sSource
)
2885 SfxObjectShell
& rDocSh
= *rDoc
.GetDocumentShell();
2886 uno::Reference
< script::XLibraryContainer
> xLibContainer
= rDocSh
.GetBasicContainer();
2887 OSL_ENSURE( xLibContainer
.is(), "No BasicContainer!" );
2889 uno::Reference
< container::XNameContainer
> xLib
;
2890 if( xLibContainer
.is() )
2892 OUString
aLibName( "Standard" );
2893 if ( rDocSh
.GetBasicManager() && !rDocSh
.GetBasicManager()->GetName().isEmpty() )
2895 aLibName
= rDocSh
.GetBasicManager()->GetName();
2897 uno::Any aLibAny
= xLibContainer
->getByName( aLibName
);
2902 // if the Module with codename exists then find a new name
2904 OUString genModuleName
;
2905 if ( !sModuleName
.isEmpty() )
2906 genModuleName
= sModuleName
;
2909 genModuleName
= "Sheet1";
2912 while( xLib
->hasByName( genModuleName
) )
2913 genModuleName
= "Sheet" + OUString::number( ++nNum
);
2915 uno::Any aSourceAny
;
2916 OUString sTmpSource
= sSource
;
2917 if ( sTmpSource
.isEmpty() )
2918 sTmpSource
= "Rem Attribute VBA_ModuleType=VBADocumentModule\nOption VBASupport 1\n";
2919 aSourceAny
<<= sTmpSource
;
2920 uno::Reference
< script::vba::XVBAModuleInfo
> xVBAModuleInfo( xLib
, uno::UNO_QUERY
);
2921 if ( xVBAModuleInfo
.is() )
2923 rDoc
.SetCodeName( nTab
, genModuleName
);
2924 script::ModuleInfo sModuleInfo
= lcl_InitModuleInfo( rDocSh
, genModuleName
);
2925 xVBAModuleInfo
->insertModuleInfo( genModuleName
, sModuleInfo
);
2926 xLib
->insertByName( genModuleName
, aSourceAny
);
2932 void VBA_DeleteModule( ScDocShell
& rDocSh
, const OUString
& sModuleName
)
2934 uno::Reference
< script::XLibraryContainer
> xLibContainer
= rDocSh
.GetBasicContainer();
2935 OSL_ENSURE( xLibContainer
.is(), "No BasicContainer!" );
2937 uno::Reference
< container::XNameContainer
> xLib
;
2938 if( xLibContainer
.is() )
2940 OUString
aLibName( "Standard" );
2941 if ( rDocSh
.GetBasicManager() && !rDocSh
.GetBasicManager()->GetName().isEmpty() )
2943 aLibName
= rDocSh
.GetBasicManager()->GetName();
2945 uno::Any aLibAny
= xLibContainer
->getByName( aLibName
);
2950 uno::Reference
< script::vba::XVBAModuleInfo
> xVBAModuleInfo( xLib
, uno::UNO_QUERY
);
2951 if( xLib
->hasByName( sModuleName
) )
2952 xLib
->removeByName( sModuleName
);
2953 if ( xVBAModuleInfo
.is() && xVBAModuleInfo
->hasModuleInfo(sModuleName
) )
2954 xVBAModuleInfo
->removeModuleInfo( sModuleName
);
2960 sal_Bool
ScDocFunc::InsertTable( SCTAB nTab
, const OUString
& rName
, sal_Bool bRecord
, sal_Bool bApi
)
2962 sal_Bool bSuccess
= false;
2963 WaitObject
aWait( rDocShell
.GetActiveDialogParent() );
2965 ScDocShellModificator
aModificator( rDocShell
);
2967 ScDocument
* pDoc
= rDocShell
.GetDocument();
2970 // Strange loop, also basic is loaded too early ( InsertTable )
2971 // is called via the xml import for sheets in described in ODF
2972 sal_Bool bInsertDocModule
= false;
2974 if( !rDocShell
.GetDocument()->IsImportingXML() )
2976 bInsertDocModule
= pDoc
? pDoc
->IsInVBAMode() : false;
2978 if ( bInsertDocModule
|| ( bRecord
&& !pDoc
->IsUndoEnabled() ) )
2982 pDoc
->BeginDrawUndo(); // InsertTab erzeugt ein SdrUndoNewPage
2984 SCTAB nTabCount
= pDoc
->GetTableCount();
2985 sal_Bool bAppend
= ( nTab
>= nTabCount
);
2987 nTab
= nTabCount
; // wichtig fuer Undo
2989 if (pDoc
->InsertTab( nTab
, rName
))
2992 rDocShell
.GetUndoManager()->AddUndoAction(
2993 new ScUndoInsertTab( &rDocShell
, nTab
, bAppend
, rName
));
2995 // Only insert vba modules if vba mode ( and not currently importing XML )
2996 if( bInsertDocModule
)
2998 OUString sSource
, sCodeName
;
2999 VBA_InsertModule( *pDoc
, nTab
, sCodeName
, sSource
);
3001 rDocShell
.Broadcast( ScTablesHint( SC_TAB_INSERTED
, nTab
) );
3003 rDocShell
.PostPaintExtras();
3004 aModificator
.SetDocumentModified();
3005 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
3006 bSuccess
= sal_True
;
3009 rDocShell
.ErrorMessage(STR_TABINSERT_ERROR
);
3014 sal_Bool
ScDocFunc::DeleteTable( SCTAB nTab
, sal_Bool bRecord
, sal_Bool
/* bApi */ )
3016 WaitObject
aWait( rDocShell
.GetActiveDialogParent() );
3018 ScDocShellModificator
aModificator( rDocShell
);
3020 sal_Bool bSuccess
= false;
3021 ScDocument
* pDoc
= rDocShell
.GetDocument();
3022 sal_Bool bVbaEnabled
= pDoc
? pDoc
->IsInVBAMode() : false;
3023 if (bRecord
&& !pDoc
->IsUndoEnabled())
3027 sal_Bool bWasLinked
= pDoc
->IsLinked(nTab
);
3028 ScDocument
* pUndoDoc
= NULL
;
3029 ScRefUndoData
* pUndoData
= NULL
;
3032 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
3033 SCTAB nCount
= pDoc
->GetTableCount();
3035 pUndoDoc
->InitUndo( pDoc
, nTab
, nTab
, sal_True
, sal_True
); // nur nTab mit Flags
3036 pUndoDoc
->AddUndoTab( 0, nCount
-1 ); // alle Tabs fuer Referenzen
3038 pDoc
->CopyToDocument(0,0,nTab
, MAXCOL
,MAXROW
,nTab
, IDF_ALL
,false, pUndoDoc
);
3040 pDoc
->GetName( nTab
, aOldName
);
3041 pUndoDoc
->RenameTab( nTab
, aOldName
, false );
3043 pUndoDoc
->SetLink( nTab
, pDoc
->GetLinkMode(nTab
), pDoc
->GetLinkDoc(nTab
),
3044 pDoc
->GetLinkFlt(nTab
), pDoc
->GetLinkOpt(nTab
),
3045 pDoc
->GetLinkTab(nTab
),
3046 pDoc
->GetLinkRefreshDelay(nTab
) );
3048 if ( pDoc
->IsScenario(nTab
) )
3050 pUndoDoc
->SetScenario( nTab
, sal_True
);
3053 sal_uInt16 nScenFlags
;
3054 pDoc
->GetScenarioData( nTab
, aComment
, aColor
, nScenFlags
);
3055 pUndoDoc
->SetScenarioData( nTab
, aComment
, aColor
, nScenFlags
);
3056 sal_Bool bActive
= pDoc
->IsActiveScenario( nTab
);
3057 pUndoDoc
->SetActiveScenario( nTab
, bActive
);
3059 pUndoDoc
->SetVisible( nTab
, pDoc
->IsVisible( nTab
) );
3060 pUndoDoc
->SetTabBgColor( nTab
, pDoc
->GetTabBgColor(nTab
) );
3061 pUndoDoc
->SetSheetEvents( nTab
, pDoc
->GetSheetEvents( nTab
) );
3063 // Drawing-Layer muss sein Undo selbst in der Hand behalten !!!
3064 pDoc
->BeginDrawUndo(); // DeleteTab erzeugt ein SdrUndoDelPage
3066 pUndoData
= new ScRefUndoData( pDoc
);
3069 if (pDoc
->DeleteTab(nTab
))
3073 vector
<SCTAB
> theTabs
;
3074 theTabs
.push_back(nTab
);
3075 rDocShell
.GetUndoManager()->AddUndoAction(
3076 new ScUndoDeleteTab( &rDocShell
, theTabs
, pUndoDoc
, pUndoData
));
3082 if( pDoc
->GetCodeName( nTab
, sCodeName
) )
3084 VBA_DeleteModule( rDocShell
, sCodeName
);
3087 rDocShell
.Broadcast( ScTablesHint( SC_TAB_DELETED
, nTab
) );
3091 rDocShell
.UpdateLinks(); // Link-Manager updaten
3092 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
3094 pBindings
->Invalidate(SID_LINKS
);
3097 rDocShell
.PostPaintExtras();
3098 aModificator
.SetDocumentModified();
3100 SfxApplication
* pSfxApp
= SFX_APP(); // Navigator
3101 pSfxApp
->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
3102 pSfxApp
->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED
) );
3103 pSfxApp
->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED
) );
3105 bSuccess
= sal_True
;
3115 sal_Bool
ScDocFunc::SetTableVisible( SCTAB nTab
, bool bVisible
, sal_Bool bApi
)
3117 ScDocument
* pDoc
= rDocShell
.GetDocument();
3118 bool bUndo(pDoc
->IsUndoEnabled());
3119 if ( pDoc
->IsVisible( nTab
) == bVisible
)
3120 return sal_True
; // nichts zu tun - ok
3122 if ( !pDoc
->IsDocEditable() )
3125 rDocShell
.ErrorMessage(STR_PROTECTIONERR
);
3129 ScDocShellModificator
aModificator( rDocShell
);
3131 if ( !bVisible
&& !pDoc
->IsImportingXML() ) // #i57869# allow hiding in any order for loading
3133 // nicht alle Tabellen ausblenden
3135 sal_uInt16 nVisCount
= 0;
3136 SCTAB nCount
= pDoc
->GetTableCount();
3137 for (SCTAB i
=0; i
<nCount
&& nVisCount
<2; i
++)
3138 if (pDoc
->IsVisible(i
))
3144 rDocShell
.ErrorMessage(STR_PROTECTIONERR
); //! eigene Meldung?
3149 pDoc
->SetVisible( nTab
, bVisible
);
3152 std::vector
<SCTAB
> undoTabs
;
3153 undoTabs
.push_back(nTab
);
3154 rDocShell
.GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( &rDocShell
, undoTabs
, bVisible
) );
3159 rDocShell
.Broadcast( ScTablesHint( SC_TAB_HIDDEN
, nTab
) );
3161 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
3162 rDocShell
.PostPaint(0,0,0,MAXCOL
,MAXROW
,MAXTAB
, PAINT_EXTRAS
);
3163 aModificator
.SetDocumentModified();
3168 sal_Bool
ScDocFunc::SetLayoutRTL( SCTAB nTab
, bool bRTL
, sal_Bool
/* bApi */ )
3170 ScDocument
* pDoc
= rDocShell
.GetDocument();
3171 bool bUndo(pDoc
->IsUndoEnabled());
3172 if ( pDoc
->IsLayoutRTL( nTab
) == bRTL
)
3173 return sal_True
; // nothing to do - ok
3175 //! protection (sheet or document?)
3177 ScDocShellModificator
aModificator( rDocShell
);
3179 pDoc
->SetLayoutRTL( nTab
, bRTL
);
3183 rDocShell
.GetUndoManager()->AddUndoAction( new ScUndoLayoutRTL( &rDocShell
, nTab
, bRTL
) );
3186 rDocShell
.PostPaint( 0,0,0,MAXCOL
,MAXROW
,MAXTAB
, PAINT_ALL
);
3187 aModificator
.SetDocumentModified();
3189 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
3192 pBindings
->Invalidate( FID_TAB_RTL
);
3193 pBindings
->Invalidate( SID_ATTR_SIZE
);
3199 sal_Bool
ScDocFunc::RenameTable( SCTAB nTab
, const OUString
& rName
, sal_Bool bRecord
, sal_Bool bApi
)
3201 ScDocument
* pDoc
= rDocShell
.GetDocument();
3202 if (bRecord
&& !pDoc
->IsUndoEnabled())
3204 if ( !pDoc
->IsDocEditable() )
3207 rDocShell
.ErrorMessage(STR_PROTECTIONERR
);
3211 ScDocShellModificator
aModificator( rDocShell
);
3213 sal_Bool bSuccess
= false;
3215 pDoc
->GetName(nTab
, sOldName
);
3216 if (pDoc
->RenameTab( nTab
, rName
))
3220 rDocShell
.GetUndoManager()->AddUndoAction(
3221 new ScUndoRenameTab( &rDocShell
, nTab
, sOldName
, rName
));
3223 rDocShell
.PostPaintExtras();
3224 aModificator
.SetDocumentModified();
3225 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
3227 bSuccess
= sal_True
;
3232 bool ScDocFunc::SetTabBgColor( SCTAB nTab
, const Color
& rColor
, bool bRecord
, bool bApi
)
3235 ScDocument
* pDoc
= rDocShell
.GetDocument();
3236 if (bRecord
&& !pDoc
->IsUndoEnabled())
3238 if ( !pDoc
->IsDocEditable() || pDoc
->IsTabProtected(nTab
) )
3241 rDocShell
.ErrorMessage(STR_PROTECTIONERR
); //TODO Check to see what this string is...
3245 Color aOldTabBgColor
;
3246 aOldTabBgColor
= pDoc
->GetTabBgColor(nTab
);
3248 bool bSuccess
= false;
3249 pDoc
->SetTabBgColor(nTab
, rColor
);
3250 if ( pDoc
->GetTabBgColor(nTab
) == rColor
)
3256 rDocShell
.GetUndoManager()->AddUndoAction(
3257 new ScUndoTabColor( &rDocShell
, nTab
, aOldTabBgColor
, rColor
));
3259 rDocShell
.PostPaintExtras();
3260 ScDocShellModificator
aModificator( rDocShell
);
3261 aModificator
.SetDocumentModified();
3262 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
3269 bool ScDocFunc::SetTabBgColor(
3270 ScUndoTabColorInfo::List
& rUndoTabColorList
, bool bRecord
, bool bApi
)
3272 ScDocument
* pDoc
= rDocShell
.GetDocument();
3273 if (bRecord
&& !pDoc
->IsUndoEnabled())
3276 if ( !pDoc
->IsDocEditable() )
3279 rDocShell
.ErrorMessage(STR_PROTECTIONERR
); //TODO Get a better String Error...
3284 Color aNewTabBgColor
;
3285 bool bSuccess
= true;
3286 size_t nTabProtectCount
= 0;
3287 size_t nTabListCount
= rUndoTabColorList
.size();
3288 for ( size_t i
= 0; i
< nTabListCount
; ++i
)
3290 ScUndoTabColorInfo
& rInfo
= rUndoTabColorList
[i
];
3291 nTab
= rInfo
.mnTabId
;
3292 if ( !pDoc
->IsTabProtected(nTab
) )
3294 aNewTabBgColor
= rInfo
.maNewTabBgColor
;
3295 rInfo
.maOldTabBgColor
= pDoc
->GetTabBgColor(nTab
);
3296 pDoc
->SetTabBgColor(nTab
, aNewTabBgColor
);
3297 if ( pDoc
->GetTabBgColor(nTab
) != aNewTabBgColor
)
3309 if ( nTabProtectCount
== nTabListCount
)
3312 rDocShell
.ErrorMessage(STR_PROTECTIONERR
); //TODO Get a better String Error...
3320 rDocShell
.GetUndoManager()->AddUndoAction(
3321 new ScUndoTabColor( &rDocShell
, rUndoTabColorList
));
3323 rDocShell
.PostPaintExtras();
3324 ScDocShellModificator
aModificator( rDocShell
);
3325 aModificator
.SetDocumentModified();
3330 //------------------------------------------------------------------------
3332 //! SetWidthOrHeight - noch doppelt zu ViewFunc !!!!!!
3334 //! - Optimale Hoehe fuer Edit-Zellen ist unterschiedlich zwischen Drucker und Bildschirm
3335 //! - Optimale Breite braucht Selektion, um evtl. nur selektierte Zellen zu beruecksichtigen
3337 static sal_uInt16
lcl_GetOptimalColWidth( ScDocShell
& rDocShell
, SCCOL nCol
, SCTAB nTab
, sal_Bool bFormula
)
3339 ScSizeDeviceProvider
aProv(&rDocShell
);
3340 OutputDevice
* pDev
= aProv
.GetDevice(); // has pixel MapMode
3341 double nPPTX
= aProv
.GetPPTX();
3342 double nPPTY
= aProv
.GetPPTY();
3344 ScDocument
* pDoc
= rDocShell
.GetDocument();
3346 sal_uInt16 nTwips
= pDoc
->GetOptimalColWidth( nCol
, nTab
, pDev
, nPPTX
, nPPTY
, aOne
, aOne
,
3352 sal_Bool
ScDocFunc::SetWidthOrHeight( sal_Bool bWidth
, SCCOLROW nRangeCnt
, SCCOLROW
* pRanges
, SCTAB nTab
,
3353 ScSizeMode eMode
, sal_uInt16 nSizeTwips
,
3354 sal_Bool bRecord
, sal_Bool bApi
)
3356 ScDocShellModificator
aModificator( rDocShell
);
3361 ScDocument
* pDoc
= rDocShell
.GetDocument();
3362 if ( bRecord
&& !pDoc
->IsUndoEnabled() )
3365 // import into read-only document is possible
3366 if ( !pDoc
->IsChangeReadOnlyEnabled() && !rDocShell
.IsEditable() )
3369 rDocShell
.ErrorMessage(STR_PROTECTIONERR
); //! eigene Meldung?
3373 sal_Bool bSuccess
= false;
3374 SCCOLROW nStart
= pRanges
[0];
3375 SCCOLROW nEnd
= pRanges
[2*nRangeCnt
-1];
3377 sal_Bool bFormula
= false;
3378 if ( eMode
== SC_SIZE_OPTIMAL
)
3380 //! Option "Formeln anzeigen" - woher nehmen?
3383 ScDocument
* pUndoDoc
= NULL
;
3384 ScOutlineTable
* pUndoTab
= NULL
;
3385 SCCOLROW
* pUndoRanges
= NULL
;
3389 pDoc
->BeginDrawUndo(); // Drawing Updates
3391 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
3394 pUndoDoc
->InitUndo( pDoc
, nTab
, nTab
, sal_True
, false );
3395 pDoc
->CopyToDocument( static_cast<SCCOL
>(nStart
), 0, nTab
, static_cast<SCCOL
>(nEnd
), MAXROW
, nTab
, IDF_NONE
, false, pUndoDoc
);
3399 pUndoDoc
->InitUndo( pDoc
, nTab
, nTab
, false, sal_True
);
3400 pDoc
->CopyToDocument( 0, static_cast<SCROW
>(nStart
), nTab
, MAXCOL
, static_cast<SCROW
>(nEnd
), nTab
, IDF_NONE
, false, pUndoDoc
);
3403 pUndoRanges
= new SCCOLROW
[ 2*nRangeCnt
];
3404 memcpy( pUndoRanges
, pRanges
, 2*nRangeCnt
*sizeof(SCCOLROW
) );
3406 ScOutlineTable
* pTable
= pDoc
->GetOutlineTable( nTab
);
3408 pUndoTab
= new ScOutlineTable( *pTable
);
3411 sal_Bool bShow
= nSizeTwips
> 0 || eMode
!= SC_SIZE_DIRECT
;
3412 sal_Bool bOutline
= false;
3414 for (SCCOLROW nRangeNo
=0; nRangeNo
<nRangeCnt
; nRangeNo
++)
3416 SCCOLROW nStartNo
= *(pRanges
++);
3417 SCCOLROW nEndNo
= *(pRanges
++);
3419 if ( !bWidth
) // Hoehen immer blockweise
3421 if ( eMode
==SC_SIZE_OPTIMAL
|| eMode
==SC_SIZE_VISOPT
)
3423 sal_Bool bAll
= ( eMode
==SC_SIZE_OPTIMAL
);
3426 // fuer alle eingeblendeten CR_MANUALSIZE loeschen,
3427 // dann SetOptimalHeight mit bShrink = FALSE
3428 for (SCROW nRow
=nStartNo
; nRow
<=nEndNo
; nRow
++)
3430 sal_uInt8 nOld
= pDoc
->GetRowFlags(nRow
,nTab
);
3431 SCROW nLastRow
= -1;
3432 bool bHidden
= pDoc
->RowHidden(nRow
, nTab
, NULL
, &nLastRow
);
3433 if ( !bHidden
&& ( nOld
& CR_MANUALSIZE
) )
3434 pDoc
->SetRowFlags( nRow
, nTab
, nOld
& ~CR_MANUALSIZE
);
3438 ScSizeDeviceProvider
aProv( &rDocShell
);
3440 pDoc
->SetOptimalHeight( nStartNo
, nEndNo
, nTab
, 0, aProv
.GetDevice(),
3441 aProv
.GetPPTX(), aProv
.GetPPTY(), aOne
, aOne
, bAll
);
3444 pDoc
->ShowRows( nStartNo
, nEndNo
, nTab
, sal_True
);
3446 // Manual-Flag wird bei bAll=sal_True schon in SetOptimalHeight gesetzt
3447 // (an bei Extra-Height, sonst aus).
3449 else if ( eMode
==SC_SIZE_DIRECT
|| eMode
==SC_SIZE_ORIGINAL
)
3453 pDoc
->SetRowHeightRange( nStartNo
, nEndNo
, nTab
, nSizeTwips
);
3454 pDoc
->SetManualHeight( nStartNo
, nEndNo
, nTab
, sal_True
); // height was set manually
3456 if ( eMode
!= SC_SIZE_ORIGINAL
)
3457 pDoc
->ShowRows( nStartNo
, nEndNo
, nTab
, nSizeTwips
!= 0 );
3459 else if ( eMode
==SC_SIZE_SHOW
)
3461 pDoc
->ShowRows( nStartNo
, nEndNo
, nTab
, sal_True
);
3464 else // Spaltenbreiten
3466 for (SCCOL nCol
=static_cast<SCCOL
>(nStartNo
); nCol
<=static_cast<SCCOL
>(nEndNo
); nCol
++)
3468 if ( eMode
!= SC_SIZE_VISOPT
|| !pDoc
->ColHidden(nCol
, nTab
) )
3470 sal_uInt16 nThisSize
= nSizeTwips
;
3472 if ( eMode
==SC_SIZE_OPTIMAL
|| eMode
==SC_SIZE_VISOPT
)
3473 nThisSize
= nSizeTwips
+
3474 lcl_GetOptimalColWidth( rDocShell
, nCol
, nTab
, bFormula
);
3476 pDoc
->SetColWidth( nCol
, nTab
, nThisSize
);
3478 if ( eMode
!= SC_SIZE_ORIGINAL
)
3479 pDoc
->ShowCol( nCol
, nTab
, bShow
);
3486 if ( eMode
!= SC_SIZE_ORIGINAL
)
3489 bOutline
= bOutline
|| pDoc
->UpdateOutlineCol(
3490 static_cast<SCCOL
>(nStartNo
),
3491 static_cast<SCCOL
>(nEndNo
), nTab
, bShow
);
3493 bOutline
= bOutline
|| pDoc
->UpdateOutlineRow(
3494 static_cast<SCROW
>(nStartNo
),
3495 static_cast<SCROW
>(nEndNo
), nTab
, bShow
);
3498 pDoc
->SetDrawPageSize(nTab
);
3506 aMark
.SelectOneTable( nTab
);
3507 rDocShell
.GetUndoManager()->AddUndoAction(
3508 new ScUndoWidthOrHeight( &rDocShell
, aMark
,
3509 nStart
, nTab
, nEnd
, nTab
,
3510 pUndoDoc
, nRangeCnt
, pUndoRanges
,
3511 pUndoTab
, eMode
, nSizeTwips
, bWidth
) );
3514 pDoc
->UpdatePageBreaks( nTab
);
3516 rDocShell
.PostPaint(0,0,nTab
,MAXCOL
,MAXROW
,nTab
,PAINT_ALL
);
3517 aModificator
.SetDocumentModified();
3523 sal_Bool
ScDocFunc::InsertPageBreak( sal_Bool bColumn
, const ScAddress
& rPos
,
3524 sal_Bool bRecord
, sal_Bool bSetModified
, sal_Bool
/* bApi */ )
3526 ScDocShellModificator
aModificator( rDocShell
);
3528 ScDocument
* pDoc
= rDocShell
.GetDocument();
3529 if (bRecord
&& !pDoc
->IsUndoEnabled())
3531 SCTAB nTab
= rPos
.Tab();
3532 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
3534 SCCOLROW nPos
= bColumn
? static_cast<SCCOLROW
>(rPos
.Col()) :
3535 static_cast<SCCOLROW
>(rPos
.Row());
3537 return false; // erste Spalte / Zeile
3539 ScBreakType nBreak
= bColumn
?
3540 pDoc
->HasColBreak(static_cast<SCCOL
>(nPos
), nTab
) :
3541 pDoc
->HasRowBreak(static_cast<SCROW
>(nPos
), nTab
);
3542 if (nBreak
& BREAK_MANUAL
)
3546 rDocShell
.GetUndoManager()->AddUndoAction(
3547 new ScUndoPageBreak( &rDocShell
, rPos
.Col(), rPos
.Row(), nTab
, bColumn
, sal_True
) );
3550 pDoc
->SetColBreak(static_cast<SCCOL
>(nPos
), nTab
, false, true);
3552 pDoc
->SetRowBreak(static_cast<SCROW
>(nPos
), nTab
, false, true);
3554 pDoc
->InvalidatePageBreaks(nTab
);
3555 pDoc
->UpdatePageBreaks( nTab
);
3557 if (pDoc
->IsStreamValid(nTab
))
3558 pDoc
->SetStreamValid(nTab
, false);
3562 rDocShell
.PostPaint( static_cast<SCCOL
>(nPos
)-1, 0, nTab
, MAXCOL
, MAXROW
, nTab
, PAINT_GRID
);
3565 pBindings
->Invalidate( FID_INS_COLBRK
);
3566 pBindings
->Invalidate( FID_DEL_COLBRK
);
3571 rDocShell
.PostPaint( 0, static_cast<SCROW
>(nPos
)-1, nTab
, MAXCOL
, MAXROW
, nTab
, PAINT_GRID
);
3574 pBindings
->Invalidate( FID_INS_ROWBRK
);
3575 pBindings
->Invalidate( FID_DEL_ROWBRK
);
3579 pBindings
->Invalidate( FID_DEL_MANUALBREAKS
);
3582 aModificator
.SetDocumentModified();
3587 sal_Bool
ScDocFunc::RemovePageBreak( sal_Bool bColumn
, const ScAddress
& rPos
,
3588 sal_Bool bRecord
, sal_Bool bSetModified
, sal_Bool
/* bApi */ )
3590 ScDocShellModificator
aModificator( rDocShell
);
3592 ScDocument
* pDoc
= rDocShell
.GetDocument();
3593 if (bRecord
&& !pDoc
->IsUndoEnabled())
3595 SCTAB nTab
= rPos
.Tab();
3596 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
3598 SCCOLROW nPos
= bColumn
? static_cast<SCCOLROW
>(rPos
.Col()) :
3599 static_cast<SCCOLROW
>(rPos
.Row());
3603 nBreak
= pDoc
->HasColBreak(static_cast<SCCOL
>(nPos
), nTab
);
3605 nBreak
= pDoc
->HasRowBreak(static_cast<SCROW
>(nPos
), nTab
);
3606 if ((nBreak
& BREAK_MANUAL
) == 0)
3607 // There is no manual break.
3611 rDocShell
.GetUndoManager()->AddUndoAction(
3612 new ScUndoPageBreak( &rDocShell
, rPos
.Col(), rPos
.Row(), nTab
, bColumn
, false ) );
3615 pDoc
->RemoveColBreak(static_cast<SCCOL
>(nPos
), nTab
, false, true);
3617 pDoc
->RemoveRowBreak(static_cast<SCROW
>(nPos
), nTab
, false, true);
3619 pDoc
->UpdatePageBreaks( nTab
);
3621 if (pDoc
->IsStreamValid(nTab
))
3622 pDoc
->SetStreamValid(nTab
, false);
3626 rDocShell
.PostPaint( static_cast<SCCOL
>(nPos
)-1, 0, nTab
, MAXCOL
, MAXROW
, nTab
, PAINT_GRID
);
3629 pBindings
->Invalidate( FID_INS_COLBRK
);
3630 pBindings
->Invalidate( FID_DEL_COLBRK
);
3635 rDocShell
.PostPaint( 0, nPos
-1, nTab
, MAXCOL
, MAXROW
, nTab
, PAINT_GRID
);
3638 pBindings
->Invalidate( FID_INS_ROWBRK
);
3639 pBindings
->Invalidate( FID_DEL_ROWBRK
);
3643 pBindings
->Invalidate( FID_DEL_MANUALBREAKS
);
3646 aModificator
.SetDocumentModified();
3651 //------------------------------------------------------------------------
3653 void ScDocFunc::ProtectSheet( SCTAB nTab
, const ScTableProtection
& rProtect
)
3655 ScDocument
* pDoc
= rDocShell
.GetDocument();
3657 pDoc
->SetTabProtection(nTab
, &rProtect
);
3658 if (pDoc
->IsUndoEnabled())
3660 ScTableProtection
* pProtect
= pDoc
->GetTabProtection(nTab
);
3661 OSL_ENSURE(pProtect
, "ScDocFunc::Unprotect: ScTableProtection pointer is NULL!");
3664 SAL_WNODEPRECATED_DECLARATIONS_PUSH
3665 ::std::auto_ptr
<ScTableProtection
> p(new ScTableProtection(*pProtect
));
3666 SAL_WNODEPRECATED_DECLARATIONS_POP
3667 p
->setProtected(true); // just in case ...
3668 rDocShell
.GetUndoManager()->AddUndoAction(
3669 new ScUndoTabProtect(&rDocShell
, nTab
, p
) );
3671 // ownership of auto_ptr now transferred to ScUndoTabProtect.
3675 rDocShell
.PostPaintGridAll();
3676 ScDocShellModificator
aModificator(rDocShell
);
3677 aModificator
.SetDocumentModified();
3680 sal_Bool
ScDocFunc::Protect( SCTAB nTab
, const OUString
& rPassword
, sal_Bool
/*bApi*/ )
3682 ScDocument
* pDoc
= rDocShell
.GetDocument();
3683 if (nTab
== TABLEID_DOC
)
3685 // document protection
3686 ScDocProtection aProtection
;
3687 aProtection
.setProtected(true);
3688 aProtection
.setPassword(rPassword
);
3689 pDoc
->SetDocProtection(&aProtection
);
3690 if (pDoc
->IsUndoEnabled())
3692 ScDocProtection
* pProtect
= pDoc
->GetDocProtection();
3693 OSL_ENSURE(pProtect
, "ScDocFunc::Unprotect: ScDocProtection pointer is NULL!");
3696 SAL_WNODEPRECATED_DECLARATIONS_PUSH
3697 ::std::auto_ptr
<ScDocProtection
> p(new ScDocProtection(*pProtect
));
3698 SAL_WNODEPRECATED_DECLARATIONS_POP
3699 p
->setProtected(true); // just in case ...
3700 rDocShell
.GetUndoManager()->AddUndoAction(
3701 new ScUndoDocProtect(&rDocShell
, p
) );
3702 // ownership of auto_ptr is transferred to ScUndoDocProtect.
3710 ScTableProtection aProtection
;
3711 aProtection
.setProtected(true);
3712 aProtection
.setPassword(rPassword
);
3713 pDoc
->SetTabProtection(nTab
, &aProtection
);
3714 if (pDoc
->IsUndoEnabled())
3716 ScTableProtection
* pProtect
= pDoc
->GetTabProtection(nTab
);
3717 OSL_ENSURE(pProtect
, "ScDocFunc::Unprotect: ScTableProtection pointer is NULL!");
3720 SAL_WNODEPRECATED_DECLARATIONS_PUSH
3721 ::std::auto_ptr
<ScTableProtection
> p(new ScTableProtection(*pProtect
));
3722 SAL_WNODEPRECATED_DECLARATIONS_POP
3723 p
->setProtected(true); // just in case ...
3724 rDocShell
.GetUndoManager()->AddUndoAction(
3725 new ScUndoTabProtect(&rDocShell
, nTab
, p
) );
3726 // ownership of auto_ptr now transferred to ScUndoTabProtect.
3731 rDocShell
.PostPaintGridAll();
3732 ScDocShellModificator
aModificator( rDocShell
);
3733 aModificator
.SetDocumentModified();
3738 sal_Bool
ScDocFunc::Unprotect( SCTAB nTab
, const OUString
& rPassword
, sal_Bool bApi
)
3740 ScDocument
* pDoc
= rDocShell
.GetDocument();
3742 if (nTab
== TABLEID_DOC
)
3744 // document protection
3746 ScDocProtection
* pDocProtect
= pDoc
->GetDocProtection();
3747 if (!pDocProtect
|| !pDocProtect
->isProtected())
3748 // already unprotected (should not happen)!
3751 // save the protection state before unprotect (for undo).
3752 SAL_WNODEPRECATED_DECLARATIONS_PUSH
3753 ::std::auto_ptr
<ScDocProtection
> pProtectCopy(new ScDocProtection(*pDocProtect
));
3754 SAL_WNODEPRECATED_DECLARATIONS_POP
3756 if (!pDocProtect
->verifyPassword(rPassword
))
3760 InfoBox
aBox( rDocShell
.GetActiveDialogParent(), OUString( ScResId( SCSTR_WRONGPASSWORD
) ) );
3766 pDoc
->SetDocProtection(NULL
);
3767 if (pDoc
->IsUndoEnabled())
3769 pProtectCopy
->setProtected(false);
3770 rDocShell
.GetUndoManager()->AddUndoAction(
3771 new ScUndoDocProtect(&rDocShell
, pProtectCopy
) );
3772 // ownership of auto_ptr now transferred to ScUndoDocProtect.
3779 ScTableProtection
* pTabProtect
= pDoc
->GetTabProtection(nTab
);
3780 if (!pTabProtect
|| !pTabProtect
->isProtected())
3781 // already unprotected (should not happen)!
3784 // save the protection state before unprotect (for undo).
3785 SAL_WNODEPRECATED_DECLARATIONS_PUSH
3786 ::std::auto_ptr
<ScTableProtection
> pProtectCopy(new ScTableProtection(*pTabProtect
));
3787 SAL_WNODEPRECATED_DECLARATIONS_POP
3788 if (!pTabProtect
->verifyPassword(rPassword
))
3792 InfoBox
aBox( rDocShell
.GetActiveDialogParent(), OUString( ScResId( SCSTR_WRONGPASSWORD
) ) );
3798 pDoc
->SetTabProtection(nTab
, NULL
);
3799 if (pDoc
->IsUndoEnabled())
3801 pProtectCopy
->setProtected(false);
3802 rDocShell
.GetUndoManager()->AddUndoAction(
3803 new ScUndoTabProtect(&rDocShell
, nTab
, pProtectCopy
) );
3804 // ownership of auto_ptr now transferred to ScUndoTabProtect.
3808 rDocShell
.PostPaintGridAll();
3809 ScDocShellModificator
aModificator( rDocShell
);
3810 aModificator
.SetDocumentModified();
3815 //------------------------------------------------------------------------
3817 sal_Bool
ScDocFunc::ClearItems( const ScMarkData
& rMark
, const sal_uInt16
* pWhich
, sal_Bool bApi
)
3819 ScDocShellModificator
aModificator( rDocShell
);
3821 ScDocument
* pDoc
= rDocShell
.GetDocument();
3822 bool bUndo (pDoc
->IsUndoEnabled());
3823 ScEditableTester
aTester( pDoc
, rMark
);
3824 if (!aTester
.IsEditable())
3827 rDocShell
.ErrorMessage(aTester
.GetMessageId());
3831 // #i12940# ClearItems is called (from setPropertyToDefault) directly with uno object's cached
3832 // MarkData (GetMarkData), so rMark must be changed to multi selection for ClearSelectionItems
3836 ScMarkData aMultiMark
= rMark
;
3837 aMultiMark
.SetMarking(false); // for MarkToMulti
3838 aMultiMark
.MarkToMulti();
3839 aMultiMark
.GetMultiMarkArea( aMarkRange
);
3843 SCTAB nStartTab
= aMarkRange
.aStart
.Tab();
3844 SCTAB nEndTab
= aMarkRange
.aEnd
.Tab();
3846 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
3847 pUndoDoc
->InitUndo( pDoc
, nStartTab
, nEndTab
);
3848 pDoc
->CopyToDocument( aMarkRange
, IDF_ATTRIB
, sal_True
, pUndoDoc
, (ScMarkData
*)&aMultiMark
);
3850 rDocShell
.GetUndoManager()->AddUndoAction(
3851 new ScUndoClearItems( &rDocShell
, aMultiMark
, pUndoDoc
, pWhich
) );
3854 pDoc
->ClearSelectionItems( pWhich
, aMultiMark
);
3856 rDocShell
.PostPaint( aMarkRange
, PAINT_GRID
, SC_PF_LINES
| SC_PF_TESTMERGE
);
3857 aModificator
.SetDocumentModified();
3859 //! Bindings-Invalidate etc.?
3864 sal_Bool
ScDocFunc::ChangeIndent( const ScMarkData
& rMark
, sal_Bool bIncrement
, sal_Bool bApi
)
3866 ScDocShellModificator
aModificator( rDocShell
);
3868 ScDocument
* pDoc
= rDocShell
.GetDocument();
3869 bool bUndo(pDoc
->IsUndoEnabled());
3870 ScEditableTester
aTester( pDoc
, rMark
);
3871 if (!aTester
.IsEditable())
3874 rDocShell
.ErrorMessage(aTester
.GetMessageId());
3879 rMark
.GetMultiMarkArea( aMarkRange
);
3883 SCTAB nStartTab
= aMarkRange
.aStart
.Tab();
3884 SCTAB nTabCount
= pDoc
->GetTableCount();
3886 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
3887 pUndoDoc
->InitUndo( pDoc
, nStartTab
, nStartTab
);
3888 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
3889 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
3890 if (*itr
!= nStartTab
)
3891 pUndoDoc
->AddUndoTab( *itr
, *itr
);
3893 ScRange aCopyRange
= aMarkRange
;
3894 aCopyRange
.aStart
.SetTab(0);
3895 aCopyRange
.aEnd
.SetTab(nTabCount
-1);
3896 pDoc
->CopyToDocument( aCopyRange
, IDF_ATTRIB
, sal_True
, pUndoDoc
, (ScMarkData
*)&rMark
);
3898 rDocShell
.GetUndoManager()->AddUndoAction(
3899 new ScUndoIndent( &rDocShell
, rMark
, pUndoDoc
, bIncrement
) );
3902 pDoc
->ChangeSelectionIndent( bIncrement
, rMark
);
3904 rDocShell
.PostPaint( aMarkRange
, PAINT_GRID
, SC_PF_LINES
| SC_PF_TESTMERGE
);
3905 aModificator
.SetDocumentModified();
3907 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
3910 pBindings
->Invalidate( SID_ALIGNLEFT
); // ChangeIndent setzt auf links
3911 pBindings
->Invalidate( SID_ALIGNRIGHT
);
3912 pBindings
->Invalidate( SID_ALIGNBLOCK
);
3913 pBindings
->Invalidate( SID_ALIGNCENTERHOR
);
3914 pBindings
->Invalidate( SID_ATTR_LRSPACE
);
3915 pBindings
->Invalidate( SID_ATTR_PARA_ADJUST_LEFT
);
3916 pBindings
->Invalidate( SID_ATTR_PARA_ADJUST_RIGHT
);
3917 pBindings
->Invalidate( SID_ATTR_PARA_ADJUST_BLOCK
);
3918 pBindings
->Invalidate( SID_ATTR_PARA_ADJUST_CENTER
);
3919 // pseudo slots for Format menu
3920 pBindings
->Invalidate( SID_ALIGN_ANY_HDEFAULT
);
3921 pBindings
->Invalidate( SID_ALIGN_ANY_LEFT
);
3922 pBindings
->Invalidate( SID_ALIGN_ANY_HCENTER
);
3923 pBindings
->Invalidate( SID_ALIGN_ANY_RIGHT
);
3924 pBindings
->Invalidate( SID_ALIGN_ANY_JUSTIFIED
);
3930 bool ScDocFunc::AutoFormat( const ScRange
& rRange
, const ScMarkData
* pTabMark
,
3931 sal_uInt16 nFormatNo
, bool bRecord
, bool bApi
)
3933 ScDocShellModificator
aModificator( rDocShell
);
3935 sal_Bool bSuccess
= false;
3936 ScDocument
* pDoc
= rDocShell
.GetDocument();
3937 SCCOL nStartCol
= rRange
.aStart
.Col();
3938 SCROW nStartRow
= rRange
.aStart
.Row();
3939 SCTAB nStartTab
= rRange
.aStart
.Tab();
3940 SCCOL nEndCol
= rRange
.aEnd
.Col();
3941 SCROW nEndRow
= rRange
.aEnd
.Row();
3942 SCTAB nEndTab
= rRange
.aEnd
.Tab();
3944 if (bRecord
&& !pDoc
->IsUndoEnabled())
3951 for (SCTAB nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
3952 aMark
.SelectTable( nTab
, sal_True
);
3955 ScAutoFormat
* pAutoFormat
= ScGlobal::GetOrCreateAutoFormat();
3956 ScEditableTester
aTester( pDoc
, nStartCol
,nStartRow
, nEndCol
,nEndRow
, aMark
);
3957 if ( nFormatNo
< pAutoFormat
->size() && aTester
.IsEditable() )
3959 WaitObject
aWait( rDocShell
.GetActiveDialogParent() );
3961 bool bSize
= pAutoFormat
->findByIndex(nFormatNo
)->GetIncludeWidthHeight();
3963 SCTAB nTabCount
= pDoc
->GetTableCount();
3964 ScDocument
* pUndoDoc
= NULL
;
3967 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
3968 pUndoDoc
->InitUndo( pDoc
, nStartTab
, nStartTab
, bSize
, bSize
);
3969 ScMarkData::iterator itr
= aMark
.begin(), itrEnd
= aMark
.end();
3970 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
3971 if (*itr
!= nStartTab
)
3972 pUndoDoc
->AddUndoTab( *itr
, *itr
, bSize
, bSize
);
3974 ScRange aCopyRange
= rRange
;
3975 aCopyRange
.aStart
.SetTab(0);
3976 aCopyRange
.aStart
.SetTab(nTabCount
-1);
3977 pDoc
->CopyToDocument( aCopyRange
, IDF_ATTRIB
, false, pUndoDoc
, &aMark
);
3980 pDoc
->CopyToDocument( nStartCol
,0,0, nEndCol
,MAXROW
,nTabCount
-1,
3981 IDF_NONE
, false, pUndoDoc
, &aMark
);
3982 pDoc
->CopyToDocument( 0,nStartRow
,0, MAXCOL
,nEndRow
,nTabCount
-1,
3983 IDF_NONE
, false, pUndoDoc
, &aMark
);
3985 pDoc
->BeginDrawUndo();
3988 pDoc
->AutoFormat( nStartCol
, nStartRow
, nEndCol
, nEndRow
, nFormatNo
, aMark
);
3992 SCCOLROW nCols
[2] = { nStartCol
, nEndCol
};
3993 SCCOLROW nRows
[2] = { nStartRow
, nEndRow
};
3995 ScMarkData::iterator itr
= aMark
.begin(), itrEnd
= aMark
.end();
3996 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
3998 SetWidthOrHeight( sal_True
, 1,nCols
, *itr
, SC_SIZE_VISOPT
, STD_EXTRA_WIDTH
, false, sal_True
);
3999 SetWidthOrHeight( false,1,nRows
, *itr
, SC_SIZE_VISOPT
, 0, false, false);
4000 rDocShell
.PostPaint( 0,0,*itr
, MAXCOL
,MAXROW
,*itr
,
4001 PAINT_GRID
| PAINT_LEFT
| PAINT_TOP
);
4006 ScMarkData::iterator itr
= aMark
.begin(), itrEnd
= aMark
.end();
4007 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
4009 sal_Bool bAdj
= AdjustRowHeight( ScRange(nStartCol
, nStartRow
, *itr
,
4010 nEndCol
, nEndRow
, *itr
), false );
4012 rDocShell
.PostPaint( 0,nStartRow
,*itr
, MAXCOL
,MAXROW
,*itr
,
4013 PAINT_GRID
| PAINT_LEFT
);
4015 rDocShell
.PostPaint( nStartCol
, nStartRow
, *itr
,
4016 nEndCol
, nEndRow
, *itr
, PAINT_GRID
);
4020 if ( bRecord
) // Draw-Undo erst jetzt verfuegbar
4022 rDocShell
.GetUndoManager()->AddUndoAction(
4023 new ScUndoAutoFormat( &rDocShell
, rRange
, pUndoDoc
, aMark
, bSize
, nFormatNo
) );
4026 aModificator
.SetDocumentModified();
4029 rDocShell
.ErrorMessage(aTester
.GetMessageId());
4034 //------------------------------------------------------------------------
4036 sal_Bool
ScDocFunc::EnterMatrix( const ScRange
& rRange
, const ScMarkData
* pTabMark
,
4037 const ScTokenArray
* pTokenArray
, const OUString
& rString
, sal_Bool bApi
, sal_Bool bEnglish
,
4038 const OUString
& rFormulaNmsp
, const formula::FormulaGrammar::Grammar eGrammar
)
4040 ScDocShellModificator
aModificator( rDocShell
);
4042 sal_Bool bSuccess
= false;
4043 ScDocument
* pDoc
= rDocShell
.GetDocument();
4044 SCCOL nStartCol
= rRange
.aStart
.Col();
4045 SCROW nStartRow
= rRange
.aStart
.Row();
4046 SCTAB nStartTab
= rRange
.aStart
.Tab();
4047 SCCOL nEndCol
= rRange
.aEnd
.Col();
4048 SCROW nEndRow
= rRange
.aEnd
.Row();
4049 SCTAB nEndTab
= rRange
.aEnd
.Tab();
4051 bool bUndo(pDoc
->IsUndoEnabled());
4058 for (SCTAB nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
4059 aMark
.SelectTable( nTab
, sal_True
);
4062 ScEditableTester
aTester( pDoc
, nStartCol
,nStartRow
, nEndCol
,nEndRow
, aMark
);
4063 if ( aTester
.IsEditable() )
4065 WaitObject
aWait( rDocShell
.GetActiveDialogParent() );
4067 ScDocument
* pUndoDoc
= NULL
;
4071 //! auch bei Undo selektierte Tabellen beruecksichtigen
4072 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
4073 pUndoDoc
->InitUndo( pDoc
, nStartTab
, nEndTab
);
4074 pDoc
->CopyToDocument( rRange
, IDF_ALL
& ~IDF_NOTE
, false, pUndoDoc
);
4077 // use TokenArray if given, string (and flags) otherwise
4080 pDoc
->InsertMatrixFormula( nStartCol
, nStartRow
, nEndCol
, nEndRow
,
4081 aMark
, EMPTY_OUSTRING
, pTokenArray
, eGrammar
);
4083 else if ( pDoc
->IsImportingXML() )
4085 ScTokenArray
* pCode
= lcl_ScDocFunc_CreateTokenArrayXML( rString
, rFormulaNmsp
, eGrammar
);
4086 pDoc
->InsertMatrixFormula( nStartCol
, nStartRow
, nEndCol
, nEndRow
,
4087 aMark
, EMPTY_OUSTRING
, pCode
, eGrammar
);
4089 pDoc
->IncXMLImportedFormulaCount( rString
.getLength() );
4093 ScCompiler
aComp( pDoc
, rRange
.aStart
);
4094 aComp
.SetGrammar(eGrammar
);
4095 ScTokenArray
* pCode
= aComp
.CompileString( rString
);
4096 pDoc
->InsertMatrixFormula( nStartCol
, nStartRow
, nEndCol
, nEndRow
,
4097 aMark
, EMPTY_OUSTRING
, pCode
, eGrammar
);
4101 pDoc
->InsertMatrixFormula( nStartCol
, nStartRow
, nEndCol
, nEndRow
,
4102 aMark
, rString
, NULL
, eGrammar
);
4106 //! auch bei Undo selektierte Tabellen beruecksichtigen
4107 rDocShell
.GetUndoManager()->AddUndoAction(
4108 new ScUndoEnterMatrix( &rDocShell
, rRange
, pUndoDoc
, rString
) );
4111 // Err522 beim Paint von DDE-Formeln werden jetzt beim Interpretieren abgefangen
4112 rDocShell
.PostPaint( nStartCol
,nStartRow
,nStartTab
,nEndCol
,nEndRow
,nEndTab
, PAINT_GRID
);
4113 aModificator
.SetDocumentModified();
4115 bSuccess
= sal_True
;
4118 rDocShell
.ErrorMessage(aTester
.GetMessageId());
4123 //------------------------------------------------------------------------
4125 sal_Bool
ScDocFunc::TabOp( const ScRange
& rRange
, const ScMarkData
* pTabMark
,
4126 const ScTabOpParam
& rParam
, sal_Bool bRecord
, sal_Bool bApi
)
4128 ScDocShellModificator
aModificator( rDocShell
);
4130 sal_Bool bSuccess
= false;
4131 ScDocument
* pDoc
= rDocShell
.GetDocument();
4132 SCCOL nStartCol
= rRange
.aStart
.Col();
4133 SCROW nStartRow
= rRange
.aStart
.Row();
4134 SCTAB nStartTab
= rRange
.aStart
.Tab();
4135 SCCOL nEndCol
= rRange
.aEnd
.Col();
4136 SCROW nEndRow
= rRange
.aEnd
.Row();
4137 SCTAB nEndTab
= rRange
.aEnd
.Tab();
4139 if (bRecord
&& !pDoc
->IsUndoEnabled())
4147 for (SCTAB nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
4148 aMark
.SelectTable( nTab
, sal_True
);
4151 ScEditableTester
aTester( pDoc
, nStartCol
,nStartRow
, nEndCol
,nEndRow
, aMark
);
4152 if ( aTester
.IsEditable() )
4154 WaitObject
aWait( rDocShell
.GetActiveDialogParent() );
4155 pDoc
->SetDirty( rRange
);
4158 //! auch bei Undo selektierte Tabellen beruecksichtigen
4159 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
4160 pUndoDoc
->InitUndo( pDoc
, nStartTab
, nEndTab
);
4161 pDoc
->CopyToDocument( rRange
, IDF_ALL
& ~IDF_NOTE
, false, pUndoDoc
);
4163 rDocShell
.GetUndoManager()->AddUndoAction(
4164 new ScUndoTabOp( &rDocShell
,
4165 nStartCol
, nStartRow
, nStartTab
,
4166 nEndCol
, nEndRow
, nEndTab
, pUndoDoc
,
4167 rParam
.aRefFormulaCell
,
4168 rParam
.aRefFormulaEnd
,
4173 pDoc
->InsertTableOp(rParam
, nStartCol
, nStartRow
, nEndCol
, nEndRow
, aMark
);
4174 rDocShell
.PostPaintGridAll();
4175 aModificator
.SetDocumentModified();
4176 bSuccess
= sal_True
;
4179 rDocShell
.ErrorMessage(aTester
.GetMessageId());
4184 //------------------------------------------------------------------------
4186 inline ScDirection
DirFromFillDir( FillDir eDir
)
4188 if (eDir
==FILL_TO_BOTTOM
)
4190 else if (eDir
==FILL_TO_RIGHT
)
4192 else if (eDir
==FILL_TO_TOP
)
4194 else // if (eDir==FILL_TO_LEFT)
4201 * Expand the fill range as necessary, to allow copying of adjacent cell(s)
4202 * even when those cells are not in the original range.
4204 void adjustFillRangeForAdjacentCopy(ScRange
& rRange
, FillDir eDir
)
4208 case FILL_TO_BOTTOM
:
4210 if (rRange
.aStart
.Row() == 0)
4213 if (rRange
.aStart
.Row() != rRange
.aEnd
.Row())
4216 // Include the above row.
4217 ScAddress
& s
= rRange
.aStart
;
4218 s
.SetRow(s
.Row()-1);
4223 if (rRange
.aStart
.Row() == MAXROW
)
4226 if (rRange
.aStart
.Row() != rRange
.aEnd
.Row())
4229 // Include the row below.
4230 ScAddress
& e
= rRange
.aEnd
;
4231 e
.SetRow(e
.Row()+1);
4236 if (rRange
.aStart
.Col() == MAXCOL
)
4239 if (rRange
.aStart
.Col() != rRange
.aEnd
.Col())
4242 // Include the column to the right.
4243 ScAddress
& e
= rRange
.aEnd
;
4244 e
.SetCol(e
.Col()+1);
4249 if (rRange
.aStart
.Col() == 0)
4252 if (rRange
.aStart
.Col() != rRange
.aEnd
.Col())
4255 // Include the column to the left.
4256 ScAddress
& s
= rRange
.aStart
;
4257 s
.SetCol(s
.Col()-1);
4267 bool ScDocFunc::FillSimple( const ScRange
& rRange
, const ScMarkData
* pTabMark
,
4268 FillDir eDir
, bool bRecord
, bool bApi
)
4270 ScDocShellModificator
aModificator( rDocShell
);
4271 ScDocument
* pDoc
= rDocShell
.GetDocument();
4273 bool bSuccess
= false;
4274 ScRange aRange
= rRange
;
4275 adjustFillRangeForAdjacentCopy(aRange
, eDir
);
4277 SCCOL nStartCol
= aRange
.aStart
.Col();
4278 SCROW nStartRow
= aRange
.aStart
.Row();
4279 SCTAB nStartTab
= aRange
.aStart
.Tab();
4280 SCCOL nEndCol
= aRange
.aEnd
.Col();
4281 SCROW nEndRow
= aRange
.aEnd
.Row();
4282 SCTAB nEndTab
= aRange
.aEnd
.Tab();
4284 if (bRecord
&& !pDoc
->IsUndoEnabled())
4292 for (SCTAB nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
4293 aMark
.SelectTable( nTab
, sal_True
);
4296 ScEditableTester
aTester( pDoc
, nStartCol
,nStartRow
, nEndCol
,nEndRow
, aMark
);
4297 if ( aTester
.IsEditable() )
4299 WaitObject
aWait( rDocShell
.GetActiveDialogParent() );
4301 ScRange aSourceArea
= aRange
;
4302 ScRange aDestArea
= aRange
;
4304 SCCOLROW nCount
= 0;
4307 case FILL_TO_BOTTOM
:
4308 nCount
= aSourceArea
.aEnd
.Row()-aSourceArea
.aStart
.Row();
4309 aSourceArea
.aEnd
.SetRow( aSourceArea
.aStart
.Row() );
4312 nCount
= aSourceArea
.aEnd
.Col()-aSourceArea
.aStart
.Col();
4313 aSourceArea
.aEnd
.SetCol( aSourceArea
.aStart
.Col() );
4316 nCount
= aSourceArea
.aEnd
.Row()-aSourceArea
.aStart
.Row();
4317 aSourceArea
.aStart
.SetRow( aSourceArea
.aEnd
.Row() );
4320 nCount
= aSourceArea
.aEnd
.Col()-aSourceArea
.aStart
.Col();
4321 aSourceArea
.aStart
.SetCol( aSourceArea
.aEnd
.Col() );
4325 ScDocument
* pUndoDoc
= NULL
;
4328 SCTAB nTabCount
= pDoc
->GetTableCount();
4329 SCTAB nDestStartTab
= aDestArea
.aStart
.Tab();
4331 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
4332 pUndoDoc
->InitUndo( pDoc
, nDestStartTab
, nDestStartTab
);
4333 ScMarkData::iterator itr
= aMark
.begin(), itrEnd
= aMark
.end();
4334 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
4335 if (*itr
!= nDestStartTab
)
4336 pUndoDoc
->AddUndoTab( *itr
, *itr
);
4338 ScRange aCopyRange
= aDestArea
;
4339 aCopyRange
.aStart
.SetTab(0);
4340 aCopyRange
.aEnd
.SetTab(nTabCount
-1);
4341 pDoc
->CopyToDocument( aCopyRange
, IDF_AUTOFILL
, false, pUndoDoc
, &aMark
);
4344 sal_uLong nProgCount
;
4345 if (eDir
== FILL_TO_BOTTOM
|| eDir
== FILL_TO_TOP
)
4346 nProgCount
= aSourceArea
.aEnd
.Col() - aSourceArea
.aStart
.Col() + 1;
4348 nProgCount
= aSourceArea
.aEnd
.Row() - aSourceArea
.aStart
.Row() + 1;
4349 nProgCount
*= nCount
;
4350 ScProgress
aProgress( pDoc
->GetDocumentShell(),
4351 ScGlobal::GetRscString(STR_FILL_SERIES_PROGRESS
), nProgCount
);
4353 pDoc
->Fill( aSourceArea
.aStart
.Col(), aSourceArea
.aStart
.Row(),
4354 aSourceArea
.aEnd
.Col(), aSourceArea
.aEnd
.Row(), &aProgress
,
4355 aMark
, nCount
, eDir
, FILL_SIMPLE
);
4356 AdjustRowHeight(aRange
);
4358 if ( bRecord
) // Draw-Undo erst jetzt verfuegbar
4360 rDocShell
.GetUndoManager()->AddUndoAction(
4361 new ScUndoAutoFill( &rDocShell
, aDestArea
, aSourceArea
, pUndoDoc
, aMark
,
4362 eDir
, FILL_SIMPLE
, FILL_DAY
, MAXDOUBLE
, 1.0, 1e307
) );
4365 rDocShell
.PostPaintGridAll();
4366 aModificator
.SetDocumentModified();
4371 rDocShell
.ErrorMessage(aTester
.GetMessageId());
4376 sal_Bool
ScDocFunc::FillSeries( const ScRange
& rRange
, const ScMarkData
* pTabMark
,
4377 FillDir eDir
, FillCmd eCmd
, FillDateCmd eDateCmd
,
4378 double fStart
, double fStep
, double fMax
,
4379 sal_Bool bRecord
, sal_Bool bApi
)
4381 ScDocShellModificator
aModificator( rDocShell
);
4383 sal_Bool bSuccess
= false;
4384 ScDocument
* pDoc
= rDocShell
.GetDocument();
4385 SCCOL nStartCol
= rRange
.aStart
.Col();
4386 SCROW nStartRow
= rRange
.aStart
.Row();
4387 SCTAB nStartTab
= rRange
.aStart
.Tab();
4388 SCCOL nEndCol
= rRange
.aEnd
.Col();
4389 SCROW nEndRow
= rRange
.aEnd
.Row();
4390 SCTAB nEndTab
= rRange
.aEnd
.Tab();
4392 if (bRecord
&& !pDoc
->IsUndoEnabled())
4400 for (SCTAB nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
4401 aMark
.SelectTable( nTab
, sal_True
);
4404 ScEditableTester
aTester( pDoc
, nStartCol
,nStartRow
, nEndCol
,nEndRow
, aMark
);
4405 if ( aTester
.IsEditable() )
4407 WaitObject
aWait( rDocShell
.GetActiveDialogParent() );
4409 ScRange aSourceArea
= rRange
;
4410 ScRange aDestArea
= rRange
;
4412 SCSIZE nCount
= pDoc
->GetEmptyLinesInBlock(
4413 aSourceArea
.aStart
.Col(), aSourceArea
.aStart
.Row(), aSourceArea
.aStart
.Tab(),
4414 aSourceArea
.aEnd
.Col(), aSourceArea
.aEnd
.Row(), aSourceArea
.aEnd
.Tab(),
4415 DirFromFillDir(eDir
) );
4417 // mindestens eine Zeile/Spalte als Quellbereich behalten:
4418 SCSIZE nTotLines
= ( eDir
== FILL_TO_BOTTOM
|| eDir
== FILL_TO_TOP
) ?
4419 static_cast<SCSIZE
>( aSourceArea
.aEnd
.Row() - aSourceArea
.aStart
.Row() + 1 ) :
4420 static_cast<SCSIZE
>( aSourceArea
.aEnd
.Col() - aSourceArea
.aStart
.Col() + 1 );
4421 if ( nCount
>= nTotLines
)
4422 nCount
= nTotLines
- 1;
4426 case FILL_TO_BOTTOM
:
4427 aSourceArea
.aEnd
.SetRow( sal::static_int_cast
<SCROW
>( aSourceArea
.aEnd
.Row() - nCount
) );
4430 aSourceArea
.aEnd
.SetCol( sal::static_int_cast
<SCCOL
>( aSourceArea
.aEnd
.Col() - nCount
) );
4433 aSourceArea
.aStart
.SetRow( sal::static_int_cast
<SCROW
>( aSourceArea
.aStart
.Row() + nCount
) );
4436 aSourceArea
.aStart
.SetCol( sal::static_int_cast
<SCCOL
>( aSourceArea
.aStart
.Col() + nCount
) );
4440 ScDocument
* pUndoDoc
= NULL
;
4443 SCTAB nTabCount
= pDoc
->GetTableCount();
4444 SCTAB nDestStartTab
= aDestArea
.aStart
.Tab();
4446 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
4447 pUndoDoc
->InitUndo( pDoc
, nDestStartTab
, nDestStartTab
);
4448 ScMarkData::iterator itr
= aMark
.begin(), itrEnd
= aMark
.end();
4449 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
4450 if (*itr
!= nDestStartTab
)
4451 pUndoDoc
->AddUndoTab( *itr
, *itr
);
4453 pDoc
->CopyToDocument(
4454 aDestArea
.aStart
.Col(), aDestArea
.aStart
.Row(), 0,
4455 aDestArea
.aEnd
.Col(), aDestArea
.aEnd
.Row(), nTabCount
-1,
4456 IDF_AUTOFILL
, false, pUndoDoc
, &aMark
);
4459 if (aDestArea
.aStart
.Col() <= aDestArea
.aEnd
.Col() &&
4460 aDestArea
.aStart
.Row() <= aDestArea
.aEnd
.Row())
4462 if ( fStart
!= MAXDOUBLE
)
4464 SCCOL nValX
= (eDir
== FILL_TO_LEFT
) ? aDestArea
.aEnd
.Col() : aDestArea
.aStart
.Col();
4465 SCROW nValY
= (eDir
== FILL_TO_TOP
) ? aDestArea
.aEnd
.Row() : aDestArea
.aStart
.Row();
4466 SCTAB nTab
= aDestArea
.aStart
.Tab();
4467 pDoc
->SetValue( nValX
, nValY
, nTab
, fStart
);
4470 sal_uLong nProgCount
;
4471 if (eDir
== FILL_TO_BOTTOM
|| eDir
== FILL_TO_TOP
)
4472 nProgCount
= aSourceArea
.aEnd
.Col() - aSourceArea
.aStart
.Col() + 1;
4474 nProgCount
= aSourceArea
.aEnd
.Row() - aSourceArea
.aStart
.Row() + 1;
4475 nProgCount
*= nCount
;
4476 ScProgress
aProgress( pDoc
->GetDocumentShell(),
4477 ScGlobal::GetRscString(STR_FILL_SERIES_PROGRESS
), nProgCount
);
4479 pDoc
->Fill( aSourceArea
.aStart
.Col(), aSourceArea
.aStart
.Row(),
4480 aSourceArea
.aEnd
.Col(), aSourceArea
.aEnd
.Row(), &aProgress
,
4481 aMark
, nCount
, eDir
, eCmd
, eDateCmd
, fStep
, fMax
);
4482 AdjustRowHeight(rRange
);
4484 rDocShell
.PostPaintGridAll();
4485 aModificator
.SetDocumentModified();
4488 if ( bRecord
) // Draw-Undo erst jetzt verfuegbar
4490 rDocShell
.GetUndoManager()->AddUndoAction(
4491 new ScUndoAutoFill( &rDocShell
, aDestArea
, aSourceArea
, pUndoDoc
, aMark
,
4492 eDir
, eCmd
, eDateCmd
, fStart
, fStep
, fMax
) );
4495 bSuccess
= sal_True
;
4498 rDocShell
.ErrorMessage(aTester
.GetMessageId());
4503 sal_Bool
ScDocFunc::FillAuto( ScRange
& rRange
, const ScMarkData
* pTabMark
,
4504 FillDir eDir
, sal_uLong nCount
, sal_Bool bRecord
, sal_Bool bApi
)
4507 double fMax
= MAXDOUBLE
;
4508 return FillAuto( rRange
, pTabMark
, eDir
, FILL_AUTO
, FILL_DAY
, nCount
, fStep
, fMax
, bRecord
, bApi
);
4511 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
)
4513 ScDocShellModificator
aModificator( rDocShell
);
4515 ScDocument
* pDoc
= rDocShell
.GetDocument();
4516 SCCOL nStartCol
= rRange
.aStart
.Col();
4517 SCROW nStartRow
= rRange
.aStart
.Row();
4518 SCTAB nStartTab
= rRange
.aStart
.Tab();
4519 SCCOL nEndCol
= rRange
.aEnd
.Col();
4520 SCROW nEndRow
= rRange
.aEnd
.Row();
4521 SCTAB nEndTab
= rRange
.aEnd
.Tab();
4523 if (bRecord
&& !pDoc
->IsUndoEnabled())
4531 for (SCTAB nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
4532 aMark
.SelectTable( nTab
, sal_True
);
4535 ScRange aSourceArea
= rRange
;
4536 ScRange aDestArea
= rRange
;
4541 case FILL_TO_BOTTOM
:
4542 aDestArea
.aEnd
.SetRow( sal::static_int_cast
<SCROW
>( aSourceArea
.aEnd
.Row() + nCount
) );
4545 if (nCount
> sal::static_int_cast
<sal_uLong
>( aSourceArea
.aStart
.Row() ))
4547 OSL_FAIL("FillAuto: Row < 0");
4548 nCount
= aSourceArea
.aStart
.Row();
4550 aDestArea
.aStart
.SetRow( sal::static_int_cast
<SCROW
>( aSourceArea
.aStart
.Row() - nCount
) );
4553 aDestArea
.aEnd
.SetCol( sal::static_int_cast
<SCCOL
>( aSourceArea
.aEnd
.Col() + nCount
) );
4556 if (nCount
> sal::static_int_cast
<sal_uLong
>( aSourceArea
.aStart
.Col() ))
4558 OSL_FAIL("FillAuto: Col < 0");
4559 nCount
= aSourceArea
.aStart
.Col();
4561 aDestArea
.aStart
.SetCol( sal::static_int_cast
<SCCOL
>( aSourceArea
.aStart
.Col() - nCount
) );
4564 OSL_FAIL("Falsche Richtung bei FillAuto");
4568 // Zellschutz testen
4569 //! Quellbereich darf geschuetzt sein !!!
4570 //! aber kein Matrixfragment enthalten !!!
4572 ScEditableTester
aTester( pDoc
, aDestArea
);
4573 if ( !aTester
.IsEditable() )
4576 rDocShell
.ErrorMessage(aTester
.GetMessageId());
4580 if ( pDoc
->HasSelectedBlockMatrixFragment( nStartCol
, nStartRow
,
4581 nEndCol
, nEndRow
, aMark
) )
4584 rDocShell
.ErrorMessage(STR_MATRIXFRAGMENTERR
);
4588 WaitObject
aWait( rDocShell
.GetActiveDialogParent() );
4590 ScDocument
* pUndoDoc
= NULL
;
4593 SCTAB nTabCount
= pDoc
->GetTableCount();
4594 SCTAB nDestStartTab
= aDestArea
.aStart
.Tab();
4596 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
4597 pUndoDoc
->InitUndo( pDoc
, nDestStartTab
, nDestStartTab
);
4598 ScMarkData::iterator itr
= aMark
.begin(), itrEnd
= aMark
.end();
4599 for (; itr
!= itrEnd
&& nTabCount
; ++itr
)
4600 if (*itr
!= nDestStartTab
)
4601 pUndoDoc
->AddUndoTab( *itr
, *itr
);
4603 // do not clone note captions in undo document
4604 pDoc
->CopyToDocument(
4605 aDestArea
.aStart
.Col(), aDestArea
.aStart
.Row(), 0,
4606 aDestArea
.aEnd
.Col(), aDestArea
.aEnd
.Row(), nTabCount
-1,
4607 IDF_AUTOFILL
, false, pUndoDoc
, &aMark
);
4610 sal_uLong nProgCount
;
4611 if (eDir
== FILL_TO_BOTTOM
|| eDir
== FILL_TO_TOP
)
4612 nProgCount
= aSourceArea
.aEnd
.Col() - aSourceArea
.aStart
.Col() + 1;
4614 nProgCount
= aSourceArea
.aEnd
.Row() - aSourceArea
.aStart
.Row() + 1;
4615 nProgCount
*= nCount
;
4616 ScProgress
aProgress( pDoc
->GetDocumentShell(),
4617 ScGlobal::GetRscString(STR_FILL_SERIES_PROGRESS
), nProgCount
);
4619 pDoc
->Fill( aSourceArea
.aStart
.Col(), aSourceArea
.aStart
.Row(),
4620 aSourceArea
.aEnd
.Col(), aSourceArea
.aEnd
.Row(), &aProgress
,
4621 aMark
, nCount
, eDir
, eCmd
, eDateCmd
, fStep
, fMax
);
4623 AdjustRowHeight(aDestArea
);
4625 if ( bRecord
) // Draw-Undo erst jetzt verfuegbar
4627 rDocShell
.GetUndoManager()->AddUndoAction(
4628 new ScUndoAutoFill( &rDocShell
, aDestArea
, aSourceArea
, pUndoDoc
, aMark
,
4629 eDir
, eCmd
, eDateCmd
, MAXDOUBLE
, fStep
, fMax
) );
4632 rDocShell
.PostPaintGridAll();
4633 aModificator
.SetDocumentModified();
4635 rRange
= aDestArea
; // Zielbereich zurueckgeben (zum Markieren)
4639 //------------------------------------------------------------------------
4641 sal_Bool
ScDocFunc::MergeCells( const ScCellMergeOption
& rOption
, sal_Bool bContents
, sal_Bool bRecord
, sal_Bool bApi
)
4645 ScDocShellModificator
aModificator( rDocShell
);
4647 SCCOL nStartCol
= rOption
.mnStartCol
;
4648 SCROW nStartRow
= rOption
.mnStartRow
;
4649 SCCOL nEndCol
= rOption
.mnEndCol
;
4650 SCROW nEndRow
= rOption
.mnEndRow
;
4651 if ((nStartCol
== nEndCol
&& nStartRow
== nEndRow
) || rOption
.maTabs
.empty())
4653 // Nothing to do. Bail out quick.
4657 ScDocument
* pDoc
= rDocShell
.GetDocument();
4658 set
<SCTAB
>::const_iterator itrBeg
= rOption
.maTabs
.begin(), itrEnd
= rOption
.maTabs
.end();
4659 SCTAB nTab1
= *itrBeg
, nTab2
= *rOption
.maTabs
.rbegin();
4661 if (bRecord
&& !pDoc
->IsUndoEnabled())
4664 for (set
<SCTAB
>::const_iterator itr
= itrBeg
; itr
!= itrEnd
; ++itr
)
4666 ScEditableTester
aTester( pDoc
, *itr
, nStartCol
, nStartRow
, nEndCol
, nEndRow
);
4667 if (!aTester
.IsEditable())
4670 rDocShell
.ErrorMessage(aTester
.GetMessageId());
4674 if ( pDoc
->HasAttrib( nStartCol
, nStartRow
, *itr
, nEndCol
, nEndRow
, *itr
,
4675 HASATTR_MERGED
| HASATTR_OVERLAPPED
) )
4677 // "Zusammenfassen nicht verschachteln !"
4679 rDocShell
.ErrorMessage(STR_MSSG_MERGECELLS_0
);
4684 ScDocument
* pUndoDoc
= NULL
;
4685 bool bNeedContentsUndo
= false;
4686 for (set
<SCTAB
>::const_iterator itr
= itrBeg
; itr
!= itrEnd
; ++itr
)
4689 bool bNeedContents
= bContents
&&
4690 ( !pDoc
->IsBlockEmpty( nTab
, nStartCol
,nStartRow
+1, nStartCol
,nEndRow
, true ) ||
4691 !pDoc
->IsBlockEmpty( nTab
, nStartCol
+1,nStartRow
, nEndCol
,nEndRow
, true ) );
4695 // test if the range contains other notes which also implies that we need an undo document
4696 bool bHasNotes
= false;
4697 for( ScAddress
aPos( nStartCol
, nStartRow
, nTab
); !bHasNotes
&& (aPos
.Col() <= nEndCol
); aPos
.IncCol() )
4698 for( aPos
.SetRow( nStartRow
); !bHasNotes
&& (aPos
.Row() <= nEndRow
); aPos
.IncRow() )
4699 bHasNotes
= ((aPos
.Col() != nStartCol
) || (aPos
.Row() != nStartRow
)) && (pDoc
->HasNote(aPos
));
4703 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
4704 pUndoDoc
->InitUndo(pDoc
, nTab1
, nTab2
);
4706 // note captions are collected by drawing undo
4707 pDoc
->CopyToDocument( nStartCol
, nStartRow
, nTab
, nEndCol
, nEndRow
, nTab
,
4708 IDF_ALL
|IDF_NOCAPTIONS
, false, pUndoDoc
);
4710 pDoc
->BeginDrawUndo();
4714 pDoc
->DoMergeContents( nTab
, nStartCol
,nStartRow
, nEndCol
,nEndRow
);
4715 pDoc
->DoMerge( nTab
, nStartCol
,nStartRow
, nEndCol
,nEndRow
);
4717 if (rOption
.mbCenter
)
4719 pDoc
->ApplyAttr( nStartCol
, nStartRow
, nTab
, SvxHorJustifyItem( SVX_HOR_JUSTIFY_CENTER
, ATTR_HOR_JUSTIFY
) );
4720 pDoc
->ApplyAttr( nStartCol
, nStartRow
, nTab
, SvxVerJustifyItem( SVX_VER_JUSTIFY_CENTER
, ATTR_VER_JUSTIFY
) );
4723 if ( !AdjustRowHeight( ScRange( 0,nStartRow
,nTab
, MAXCOL
,nEndRow
,nTab
) ) )
4724 rDocShell
.PostPaint( nStartCol
, nStartRow
, nTab
,
4725 nEndCol
, nEndRow
, nTab
, PAINT_GRID
);
4726 if (bNeedContents
|| rOption
.mbCenter
)
4728 ScRange
aRange(nStartCol
, nStartRow
, nTab
, nEndCol
, nEndRow
, nTab
);
4729 pDoc
->SetDirty(aRange
);
4732 bNeedContentsUndo
|= bNeedContents
;
4737 SdrUndoGroup
* pDrawUndo
= pDoc
->GetDrawLayer() ? pDoc
->GetDrawLayer()->GetCalcUndo() : NULL
;
4738 rDocShell
.GetUndoManager()->AddUndoAction(
4739 new ScUndoMerge(&rDocShell
, rOption
, bNeedContentsUndo
, pUndoDoc
, pDrawUndo
) );
4742 aModificator
.SetDocumentModified();
4744 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
4747 pBindings
->Invalidate( FID_MERGE_ON
);
4748 pBindings
->Invalidate( FID_MERGE_OFF
);
4749 pBindings
->Invalidate( FID_MERGE_TOGGLE
);
4755 sal_Bool
ScDocFunc::UnmergeCells( const ScRange
& rRange
, sal_Bool bRecord
)
4757 ScCellMergeOption
aOption(rRange
.aStart
.Col(), rRange
.aStart
.Row(), rRange
.aEnd
.Col(), rRange
.aEnd
.Row());
4758 SCTAB nTab1
= rRange
.aStart
.Tab(), nTab2
= rRange
.aEnd
.Tab();
4759 for (SCTAB i
= nTab1
; i
<= nTab2
; ++i
)
4760 aOption
.maTabs
.insert(i
);
4762 return UnmergeCells(aOption
, bRecord
);
4765 bool ScDocFunc::UnmergeCells( const ScCellMergeOption
& rOption
, sal_Bool bRecord
)
4769 if (rOption
.maTabs
.empty())
4770 // Nothing to unmerge.
4773 ScDocShellModificator
aModificator( rDocShell
);
4774 ScDocument
* pDoc
= rDocShell
.GetDocument();
4776 if (bRecord
&& !pDoc
->IsUndoEnabled())
4779 ScDocument
* pUndoDoc
= NULL
;
4780 for (set
<SCTAB
>::const_iterator itr
= rOption
.maTabs
.begin(), itrEnd
= rOption
.maTabs
.end();
4781 itr
!= itrEnd
; ++itr
)
4784 ScRange aRange
= rOption
.getSingleRange(nTab
);
4785 if ( !pDoc
->HasAttrib(aRange
, HASATTR_MERGED
) )
4788 ScRange aExtended
= aRange
;
4789 pDoc
->ExtendMerge(aExtended
);
4790 ScRange aRefresh
= aExtended
;
4791 pDoc
->ExtendOverlapped(aRefresh
);
4797 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
4798 pUndoDoc
->InitUndo(pDoc
, *rOption
.maTabs
.begin(), *rOption
.maTabs
.rbegin());
4800 pDoc
->CopyToDocument(aExtended
, IDF_ATTRIB
, false, pUndoDoc
);
4803 const SfxPoolItem
& rDefAttr
= pDoc
->GetPool()->GetDefaultItem( ATTR_MERGE
);
4804 ScPatternAttr
aPattern( pDoc
->GetPool() );
4805 aPattern
.GetItemSet().Put( rDefAttr
);
4806 pDoc
->ApplyPatternAreaTab( aRange
.aStart
.Col(), aRange
.aStart
.Row(),
4807 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), nTab
,
4810 pDoc
->RemoveFlagsTab( aExtended
.aStart
.Col(), aExtended
.aStart
.Row(),
4811 aExtended
.aEnd
.Col(), aExtended
.aEnd
.Row(), nTab
,
4812 SC_MF_HOR
| SC_MF_VER
);
4814 pDoc
->ExtendMerge( aRefresh
, sal_True
);
4816 if ( !AdjustRowHeight( aExtended
) )
4817 rDocShell
.PostPaint( aExtended
, PAINT_GRID
);
4822 rDocShell
.GetUndoManager()->AddUndoAction(
4823 new ScUndoRemoveMerge( &rDocShell
, rOption
, pUndoDoc
) );
4825 aModificator
.SetDocumentModified();
4830 //------------------------------------------------------------------------
4832 bool ScDocFunc::ModifyRangeNames( const ScRangeName
& rNewRanges
, SCTAB nTab
)
4834 return SetNewRangeNames( new ScRangeName(rNewRanges
), true, nTab
);
4837 bool ScDocFunc::SetNewRangeNames( ScRangeName
* pNewRanges
, bool bModifyDoc
, SCTAB nTab
) // takes ownership of pNewRanges
4839 ScDocShellModificator
aModificator( rDocShell
);
4841 OSL_ENSURE( pNewRanges
, "pNewRanges is 0" );
4842 ScDocument
* pDoc
= rDocShell
.GetDocument();
4843 bool bUndo(pDoc
->IsUndoEnabled());
4850 pOld
= pDoc
->GetRangeName(nTab
);
4854 pOld
= pDoc
->GetRangeName();
4856 ScRangeName
* pUndoRanges
= new ScRangeName(*pOld
);
4857 ScRangeName
* pRedoRanges
= new ScRangeName(*pNewRanges
);
4858 rDocShell
.GetUndoManager()->AddUndoAction(
4859 new ScUndoRangeNames( &rDocShell
, pUndoRanges
, pRedoRanges
, nTab
) );
4862 // #i55926# While loading XML, formula cells only have a single string token,
4863 // so CompileNameFormula would never find any name (index) tokens, and would
4864 // unnecessarily loop through all cells.
4865 sal_Bool bCompile
= ( !pDoc
->IsImportingXML() && pDoc
->GetNamedRangesLockCount() == 0 );
4868 pDoc
->CompileNameFormula( sal_True
); // CreateFormulaString
4870 pDoc
->SetRangeName( nTab
, pNewRanges
); // takes ownership
4872 pDoc
->SetRangeName( pNewRanges
); // takes ownership
4874 pDoc
->CompileNameFormula( false ); // CompileFormulaString
4878 aModificator
.SetDocumentModified();
4879 SFX_APP()->Broadcast( SfxSimpleHint(SC_HINT_AREAS_CHANGED
) );
4885 void ScDocFunc::ModifyAllRangeNames( const boost::ptr_map
<OUString
, ScRangeName
>& rRangeMap
)
4887 ScDocShellModificator
aModificator(rDocShell
);
4888 ScDocument
* pDoc
= rDocShell
.GetDocument();
4890 if (pDoc
->IsUndoEnabled())
4892 std::map
<OUString
, ScRangeName
*> aOldRangeMap
;
4893 pDoc
->GetRangeNameMap(aOldRangeMap
);
4894 rDocShell
.GetUndoManager()->AddUndoAction(
4895 new ScUndoAllRangeNames(&rDocShell
, aOldRangeMap
, rRangeMap
));
4898 pDoc
->CompileNameFormula(true);
4900 // set all range names
4901 pDoc
->SetAllRangeNames(rRangeMap
);
4903 pDoc
->CompileNameFormula(false);
4905 aModificator
.SetDocumentModified();
4906 SFX_APP()->Broadcast(SfxSimpleHint(SC_HINT_AREAS_CHANGED
));
4909 //------------------------------------------------------------------------
4911 void ScDocFunc::CreateOneName( ScRangeName
& rList
,
4912 SCCOL nPosX
, SCROW nPosY
, SCTAB nTab
,
4913 SCCOL nX1
, SCROW nY1
, SCCOL nX2
, SCROW nY2
,
4914 sal_Bool
& rCancel
, sal_Bool bApi
)
4919 ScDocument
* pDoc
= rDocShell
.GetDocument();
4920 if (!pDoc
->HasValueData( nPosX
, nPosY
, nTab
))
4922 OUString aName
= pDoc
->GetString(nPosX
, nPosY
, nTab
);
4923 ScRangeData::MakeValidName(aName
);
4924 if (!aName
.isEmpty())
4926 OUString
aContent(ScRange( nX1
, nY1
, nTab
, nX2
, nY2
, nTab
).Format(SCR_ABS_3D
, pDoc
));
4928 bool bInsert
= false;
4929 ScRangeData
* pOld
= rList
.findByUpperName(ScGlobal::pCharClass
->uppercase(aName
));
4933 pOld
->GetSymbol( aOldStr
);
4934 if (aOldStr
!= aContent
)
4937 bInsert
= sal_True
; // per API nicht nachfragen
4940 OUString aTemplate
= ScGlobal::GetRscString( STR_CREATENAME_REPLACE
);
4942 OUString aMessage
= aTemplate
.getToken( 0, '#' );
4944 aMessage
+= aTemplate
.getToken( 1, '#' );
4946 short nResult
= QueryBox( rDocShell
.GetActiveDialogParent(),
4947 WinBits(WB_YES_NO_CANCEL
| WB_DEF_YES
),
4948 aMessage
).Execute();
4949 if ( nResult
== RET_YES
)
4954 else if ( nResult
== RET_CANCEL
)
4964 ScRangeData
* pData
= new ScRangeData( pDoc
, aName
, aContent
,
4965 ScAddress( nPosX
, nPosY
, nTab
));
4966 if (!rList
.insert(pData
))
4975 sal_Bool
ScDocFunc::CreateNames( const ScRange
& rRange
, sal_uInt16 nFlags
, sal_Bool bApi
, SCTAB aTab
)
4978 return false; // war nix
4980 ScDocShellModificator
aModificator( rDocShell
);
4982 sal_Bool bDone
= false;
4983 SCCOL nStartCol
= rRange
.aStart
.Col();
4984 SCROW nStartRow
= rRange
.aStart
.Row();
4985 SCCOL nEndCol
= rRange
.aEnd
.Col();
4986 SCROW nEndRow
= rRange
.aEnd
.Row();
4987 SCTAB nTab
= rRange
.aStart
.Tab();
4988 OSL_ENSURE(rRange
.aEnd
.Tab() == nTab
, "CreateNames: mehrere Tabellen geht nicht");
4990 sal_Bool bValid
= sal_True
;
4991 if ( nFlags
& ( NAME_TOP
| NAME_BOTTOM
) )
4992 if ( nStartRow
== nEndRow
)
4994 if ( nFlags
& ( NAME_LEFT
| NAME_RIGHT
) )
4995 if ( nStartCol
== nEndCol
)
5000 ScDocument
* pDoc
= rDocShell
.GetDocument();
5001 ScRangeName
* pNames
;
5003 pNames
= pDoc
->GetRangeName(nTab
);
5005 pNames
= pDoc
->GetRangeName();
5008 return false; // soll nicht sein
5009 ScRangeName
aNewRanges( *pNames
);
5011 sal_Bool bTop
= ( ( nFlags
& NAME_TOP
) != 0 );
5012 sal_Bool bLeft
= ( ( nFlags
& NAME_LEFT
) != 0 );
5013 sal_Bool bBottom
= ( ( nFlags
& NAME_BOTTOM
) != 0 );
5014 sal_Bool bRight
= ( ( nFlags
& NAME_RIGHT
) != 0 );
5016 SCCOL nContX1
= nStartCol
;
5017 SCROW nContY1
= nStartRow
;
5018 SCCOL nContX2
= nEndCol
;
5019 SCROW nContY2
= nEndRow
;
5030 sal_Bool bCancel
= false;
5035 for (i
=nContX1
; i
<=nContX2
; i
++)
5036 CreateOneName( aNewRanges
, i
,nStartRow
,nTab
, i
,nContY1
,i
,nContY2
, bCancel
, bApi
);
5038 for (j
=nContY1
; j
<=nContY2
; j
++)
5039 CreateOneName( aNewRanges
, nStartCol
,j
,nTab
, nContX1
,j
,nContX2
,j
, bCancel
, bApi
);
5041 for (i
=nContX1
; i
<=nContX2
; i
++)
5042 CreateOneName( aNewRanges
, i
,nEndRow
,nTab
, i
,nContY1
,i
,nContY2
, bCancel
, bApi
);
5044 for (j
=nContY1
; j
<=nContY2
; j
++)
5045 CreateOneName( aNewRanges
, nEndCol
,j
,nTab
, nContX1
,j
,nContX2
,j
, bCancel
, bApi
);
5047 if ( bTop
&& bLeft
)
5048 CreateOneName( aNewRanges
, nStartCol
,nStartRow
,nTab
, nContX1
,nContY1
,nContX2
,nContY2
, bCancel
, bApi
);
5049 if ( bTop
&& bRight
)
5050 CreateOneName( aNewRanges
, nEndCol
,nStartRow
,nTab
, nContX1
,nContY1
,nContX2
,nContY2
, bCancel
, bApi
);
5051 if ( bBottom
&& bLeft
)
5052 CreateOneName( aNewRanges
, nStartCol
,nEndRow
,nTab
, nContX1
,nContY1
,nContX2
,nContY2
, bCancel
, bApi
);
5053 if ( bBottom
&& bRight
)
5054 CreateOneName( aNewRanges
, nEndCol
,nEndRow
,nTab
, nContX1
,nContY1
,nContX2
,nContY2
, bCancel
, bApi
);
5056 bDone
= ModifyRangeNames( aNewRanges
, aTab
);
5058 aModificator
.SetDocumentModified();
5059 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED
) );
5065 //------------------------------------------------------------------------
5067 sal_Bool
ScDocFunc::InsertNameList( const ScAddress
& rStartPos
, sal_Bool bApi
)
5069 ScDocShellModificator
aModificator( rDocShell
);
5071 sal_Bool bDone
= false;
5072 ScDocument
* pDoc
= rDocShell
.GetDocument();
5073 const bool bRecord
= pDoc
->IsUndoEnabled();
5074 SCTAB nTab
= rStartPos
.Tab();
5075 ScDocument
* pUndoDoc
= NULL
;
5077 //local names have higher priority than global names
5078 ScRangeName
* pLocalList
= pDoc
->GetRangeName(nTab
);
5079 sal_uInt16 nValidCount
= 0;
5080 ScRangeName::iterator itrLocalBeg
= pLocalList
->begin(), itrLocalEnd
= pLocalList
->end();
5081 for (ScRangeName::iterator itr
= itrLocalBeg
; itr
!= itrLocalEnd
; ++itr
)
5083 const ScRangeData
& r
= *itr
->second
;
5084 if (!r
.HasType(RT_DATABASE
))
5087 ScRangeName
* pList
= pDoc
->GetRangeName();
5088 ScRangeName::iterator itrBeg
= pList
->begin(), itrEnd
= pList
->end();
5089 for (ScRangeName::iterator itr
= itrBeg
; itr
!= itrEnd
; ++itr
)
5091 const ScRangeData
& r
= *itr
->second
;
5092 if (!r
.HasType(RT_DATABASE
) && !pLocalList
->findByUpperName(r
.GetUpperName()))
5098 SCCOL nStartCol
= rStartPos
.Col();
5099 SCROW nStartRow
= rStartPos
.Row();
5100 SCCOL nEndCol
= nStartCol
+ 1;
5101 SCROW nEndRow
= nStartRow
+ static_cast<SCROW
>(nValidCount
) - 1;
5103 ScEditableTester
aTester( pDoc
, nTab
, nStartCol
,nStartRow
, nEndCol
,nEndRow
);
5104 if (aTester
.IsEditable())
5108 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
5109 pUndoDoc
->InitUndo( pDoc
, nTab
, nTab
);
5110 pDoc
->CopyToDocument( nStartCol
,nStartRow
,nTab
, nEndCol
,nEndRow
,nTab
,
5111 IDF_ALL
, false, pUndoDoc
);
5113 pDoc
->BeginDrawUndo(); // wegen Hoehenanpassung
5116 ScRangeData
** ppSortArray
= new ScRangeData
* [ nValidCount
];
5118 for (ScRangeName::iterator itr
= itrLocalBeg
; itr
!= itrLocalEnd
; ++itr
)
5120 ScRangeData
& r
= *itr
->second
;
5121 if (!r
.HasType(RT_DATABASE
))
5122 ppSortArray
[j
++] = &r
;
5124 for (ScRangeName::iterator itr
= itrBeg
; itr
!= itrEnd
; ++itr
)
5126 ScRangeData
& r
= *itr
->second
;
5127 if (!r
.HasType(RT_DATABASE
) && !pLocalList
->findByUpperName(itr
->first
))
5128 ppSortArray
[j
++] = &r
;
5130 qsort( (void*)ppSortArray
, nValidCount
, sizeof(ScRangeData
*),
5131 &ScRangeData_QsortNameCompare
);
5133 OUStringBuffer aContent
;
5135 SCROW nOutRow
= nStartRow
;
5136 for (j
=0; j
<nValidCount
; j
++)
5138 ScRangeData
* pData
= ppSortArray
[j
];
5139 pData
->GetName(aName
);
5140 // relative Referenzen Excel-konform auf die linke Spalte anpassen:
5141 pData
->UpdateSymbol(aContent
, ScAddress( nStartCol
, nOutRow
, nTab
));
5142 aFormula
= "=" + aContent
.toString();
5143 ScSetStringParam aParam
;
5144 aParam
.setTextInput();
5145 pDoc
->SetString(ScAddress(nStartCol
,nOutRow
,nTab
), aName
, &aParam
);
5146 pDoc
->SetString(ScAddress(nEndCol
,nOutRow
,nTab
), aFormula
, &aParam
);
5150 delete [] ppSortArray
;
5154 ScDocument
* pRedoDoc
= new ScDocument( SCDOCMODE_UNDO
);
5155 pRedoDoc
->InitUndo( pDoc
, nTab
, nTab
);
5156 pDoc
->CopyToDocument( nStartCol
,nStartRow
,nTab
, nEndCol
,nEndRow
,nTab
,
5157 IDF_ALL
, false, pRedoDoc
);
5159 rDocShell
.GetUndoManager()->AddUndoAction(
5160 new ScUndoListNames( &rDocShell
,
5161 ScRange( nStartCol
,nStartRow
,nTab
, nEndCol
,nEndRow
,nTab
),
5162 pUndoDoc
, pRedoDoc
) );
5165 if (!AdjustRowHeight(ScRange(0,nStartRow
,nTab
,MAXCOL
,nEndRow
,nTab
)))
5166 rDocShell
.PostPaint( nStartCol
,nStartRow
,nTab
, nEndCol
,nEndRow
,nTab
, PAINT_GRID
);
5168 aModificator
.SetDocumentModified();
5172 rDocShell
.ErrorMessage(aTester
.GetMessageId());
5177 //------------------------------------------------------------------------
5179 sal_Bool
ScDocFunc::ResizeMatrix( const ScRange
& rOldRange
, const ScAddress
& rNewEnd
, sal_Bool bApi
)
5181 ScDocument
* pDoc
= rDocShell
.GetDocument();
5182 SCCOL nStartCol
= rOldRange
.aStart
.Col();
5183 SCROW nStartRow
= rOldRange
.aStart
.Row();
5184 SCTAB nTab
= rOldRange
.aStart
.Tab();
5186 bool bUndo(pDoc
->IsUndoEnabled());
5188 sal_Bool bRet
= false;
5191 pDoc
->GetFormula( nStartCol
, nStartRow
, nTab
, aFormula
);
5192 if ( aFormula
.startsWith("{") && aFormula
.endsWith("}") )
5194 OUString aUndo
= ScGlobal::GetRscString( STR_UNDO_RESIZEMATRIX
);
5196 rDocShell
.GetUndoManager()->EnterListAction( aUndo
, aUndo
);
5198 aFormula
= aFormula
.copy(1, aFormula
.getLength()-2);
5201 aMark
.SetMarkArea( rOldRange
);
5202 aMark
.SelectTable( nTab
, sal_True
);
5203 ScRange
aNewRange( rOldRange
.aStart
, rNewEnd
);
5205 if ( DeleteContents( aMark
, IDF_CONTENTS
, sal_True
, bApi
) )
5207 // GRAM_PODF_A1 for API compatibility.
5208 bRet
= EnterMatrix( aNewRange
, &aMark
, NULL
, aFormula
, bApi
, false, EMPTY_OUSTRING
, formula::FormulaGrammar::GRAM_PODF_A1
);
5211 // versuchen, alten Zustand wiederherzustellen
5212 EnterMatrix( rOldRange
, &aMark
, NULL
, aFormula
, bApi
, false, EMPTY_OUSTRING
, formula::FormulaGrammar::GRAM_PODF_A1
);
5217 rDocShell
.GetUndoManager()->LeaveListAction();
5223 //------------------------------------------------------------------------
5225 sal_Bool
ScDocFunc::InsertAreaLink( const OUString
& rFile
, const OUString
& rFilter
,
5226 const OUString
& rOptions
, const OUString
& rSource
,
5227 const ScRange
& rDestRange
, sal_uLong nRefresh
,
5228 sal_Bool bFitBlock
, sal_Bool bApi
)
5230 ScDocument
* pDoc
= rDocShell
.GetDocument();
5231 sal_Bool
bUndo (pDoc
->IsUndoEnabled());
5233 sfx2::LinkManager
* pLinkManager
= pDoc
->GetLinkManager();
5235 // #i52120# if other area links exist at the same start position,
5236 // remove them first (file format specifies only one link definition
5239 sal_uInt16 nLinkCount
= pLinkManager
->GetLinks().size();
5240 sal_uInt16 nRemoved
= 0;
5241 sal_uInt16 nLinkPos
= 0;
5242 while (nLinkPos
<nLinkCount
)
5244 ::sfx2::SvBaseLink
* pBase
= *pLinkManager
->GetLinks()[nLinkPos
];
5245 if ( pBase
->ISA(ScAreaLink
) &&
5246 static_cast<ScAreaLink
*>(pBase
)->GetDestArea().aStart
== rDestRange
.aStart
)
5252 // group all remove and the insert action
5253 OUString aUndo
= ScGlobal::GetRscString( STR_UNDO_INSERTAREALINK
);
5254 rDocShell
.GetUndoManager()->EnterListAction( aUndo
, aUndo
);
5257 ScAreaLink
* pOldArea
= static_cast<ScAreaLink
*>(pBase
);
5258 rDocShell
.GetUndoManager()->AddUndoAction(
5259 new ScUndoRemoveAreaLink( &rDocShell
,
5260 pOldArea
->GetFile(), pOldArea
->GetFilter(), pOldArea
->GetOptions(),
5261 pOldArea
->GetSource(), pOldArea
->GetDestArea(), pOldArea
->GetRefreshDelay() ) );
5263 pLinkManager
->Remove( pBase
);
5264 nLinkCount
= pLinkManager
->GetLinks().size();
5271 OUString aFilterName
= rFilter
;
5272 OUString aNewOptions
= rOptions
;
5273 if (aFilterName
.isEmpty())
5274 ScDocumentLoader::GetFilterName( rFile
, aFilterName
, aNewOptions
, true, !bApi
);
5276 // remove application prefix from filter name here, so the filter options
5277 // aren't reset when the filter name is changed in ScAreaLink::DataChanged
5278 ScDocumentLoader::RemoveAppPrefix( aFilterName
);
5280 ScAreaLink
* pLink
= new ScAreaLink( &rDocShell
, rFile
, aFilterName
,
5281 aNewOptions
, rSource
, rDestRange
, nRefresh
);
5282 OUString aTmp
= aFilterName
;
5283 pLinkManager
->InsertFileLink( *pLink
, OBJECT_CLIENT_FILE
, rFile
, &aTmp
, &rSource
);
5285 // Undo fuer den leeren Link
5289 rDocShell
.GetUndoManager()->AddUndoAction( new ScUndoInsertAreaLink( &rDocShell
,
5290 rFile
, aFilterName
, aNewOptions
,
5291 rSource
, rDestRange
, nRefresh
) );
5293 rDocShell
.GetUndoManager()->LeaveListAction(); // undo for link update is still separate
5296 // Update hat sein eigenes Undo
5297 if (pDoc
->IsExecuteLinkEnabled())
5299 pLink
->SetDoInsert(bFitBlock
); // beim ersten Update ggf. nichts einfuegen
5300 pLink
->Update(); // kein SetInCreate -> Update ausfuehren
5302 pLink
->SetDoInsert(sal_True
); // Default = sal_True
5304 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
5306 pBindings
->Invalidate( SID_LINKS
);
5308 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED
) ); // Navigator
5315 void RemoveCondFormatAttributes(ScDocument
* pDoc
, const ScConditionalFormat
* pFormat
, SCTAB nTab
)
5317 const ScRangeList
& rRangeList
= pFormat
->GetRange();
5318 pDoc
->RemoveCondFormatData( rRangeList
, nTab
, pFormat
->GetKey() );
5321 void SetConditionalFormatAttributes(ScDocument
* pDoc
, const ScRangeList
& rRanges
, sal_uLong nIndex
, SCTAB nTab
)
5323 pDoc
->AddCondFormatData( rRanges
, nTab
, nIndex
);
5328 void ScDocFunc::ReplaceConditionalFormat( sal_uLong nOldFormat
, ScConditionalFormat
* pFormat
, SCTAB nTab
, const ScRangeList
& rRanges
)
5330 ScDocShellModificator
aModificator(rDocShell
);
5331 ScDocument
* pDoc
= rDocShell
.GetDocument();
5332 if(pDoc
->IsTabProtected(nTab
))
5335 boost::scoped_ptr
<ScRange
> pRepaintRange
;
5338 ScConditionalFormat
* pOldFormat
= pDoc
->GetCondFormList(nTab
)->GetFormat(nOldFormat
);
5341 pRepaintRange
.reset(new ScRange( pOldFormat
->GetRange().Combine() ));
5342 RemoveCondFormatAttributes(pDoc
, pOldFormat
, nTab
);
5345 pDoc
->DeleteConditionalFormat(nOldFormat
, nTab
);
5346 pDoc
->SetStreamValid(nTab
, false);
5351 pRepaintRange
->ExtendTo(rRanges
.Combine());
5353 pRepaintRange
.reset(new ScRange(rRanges
.Combine()));
5355 sal_uLong nIndex
= pDoc
->AddCondFormat(pFormat
, nTab
);
5357 SetConditionalFormatAttributes(pDoc
, rRanges
, nIndex
, nTab
);
5358 pDoc
->SetStreamValid(nTab
, false);
5362 rDocShell
.PostPaint(*pRepaintRange
, PAINT_GRID
);
5364 aModificator
.SetDocumentModified();
5365 SFX_APP()->Broadcast(SfxSimpleHint(SC_HINT_AREAS_CHANGED
));
5368 void ScDocFunc::SetConditionalFormatList( ScConditionalFormatList
* pList
, SCTAB nTab
)
5370 ScDocShellModificator
aModificator(rDocShell
);
5371 ScDocument
* pDoc
= rDocShell
.GetDocument();
5372 if(pDoc
->IsTabProtected(nTab
))
5375 // first remove all old entries
5376 ScConditionalFormatList
* pOldList
= pDoc
->GetCondFormList(nTab
);
5377 for(ScConditionalFormatList::const_iterator itr
= pOldList
->begin(), itrEnd
= pOldList
->end(); itr
!= itrEnd
; ++itr
)
5379 RemoveCondFormatAttributes(pDoc
, &(*itr
), nTab
);
5382 // then set new entries
5383 for(ScConditionalFormatList::iterator itr
= pList
->begin(); itr
!= pList
->end(); ++itr
)
5385 sal_uLong nIndex
= itr
->GetKey();
5386 const ScRangeList
& rRange
= itr
->GetRange();
5387 SetConditionalFormatAttributes(pDoc
, rRange
, nIndex
, nTab
);
5390 pDoc
->SetCondFormList(pList
, nTab
);
5391 rDocShell
.PostPaintGridAll();
5393 pDoc
->SetStreamValid(nTab
, false);
5394 aModificator
.SetDocumentModified();
5395 SFX_APP()->Broadcast(SfxSimpleHint(SC_HINT_AREAS_CHANGED
));
5398 void ScDocFunc::EnterListAction( sal_uInt16 nNameResId
)
5400 OUString
aUndo( ScGlobal::GetRscString( nNameResId
) );
5401 rDocShell
.GetUndoManager()->EnterListAction( aUndo
, aUndo
);
5404 void ScDocFunc::EndListAction()
5406 rDocShell
.GetUndoManager()->LeaveListAction();
5409 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */