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"
86 #include <rowheightcontext.hxx>
89 #include <basic/basmgr.hxx>
90 #include <boost/scoped_array.hpp>
91 #include <boost/scoped_ptr.hpp>
95 using namespace com::sun::star
;
96 using ::com::sun::star::uno::Sequence
;
100 // STATIC DATA -----------------------------------------------------------
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 // Zeile ueber dem Range painten (fuer Linien nach AdjustRowHeight)
124 static void lcl_PaintAbove( ScDocShell
& rDocShell
, const ScRange
& rRange
)
126 SCROW nRow
= rRange
.aStart
.Row();
129 SCTAB nTab
= rRange
.aStart
.Tab(); //! alle?
131 rDocShell
.PostPaint( ScRange(0,nRow
,nTab
, MAXCOL
,nRow
,nTab
), PAINT_GRID
);
135 bool ScDocFunc::AdjustRowHeight( const ScRange
& rRange
, bool bPaint
)
137 ScDocument
* pDoc
= rDocShell
.GetDocument();
138 if ( pDoc
->IsImportingXML() )
140 // for XML import, all row heights are updated together after importing
143 if ( !pDoc
->IsAdjustHeightEnabled() )
148 SCTAB nTab
= rRange
.aStart
.Tab();
149 SCROW nStartRow
= rRange
.aStart
.Row();
150 SCROW nEndRow
= rRange
.aEnd
.Row();
152 ScSizeDeviceProvider
aProv( &rDocShell
);
155 sc::RowHeightContext
aCxt(aProv
.GetPPTX(), aProv
.GetPPTY(), aOne
, aOne
, aProv
.GetDevice());
156 bool bChanged
= pDoc
->SetOptimalHeight(aCxt
, nStartRow
, nEndRow
, nTab
);
158 if ( bPaint
&& bChanged
)
159 rDocShell
.PostPaint(ScRange(0, nStartRow
, nTab
, MAXCOL
, MAXROW
, nTab
),
160 PAINT_GRID
| PAINT_LEFT
);
166 bool ScDocFunc::DetectiveAddPred(const ScAddress
& rPos
)
168 ScDocShellModificator
aModificator( rDocShell
);
170 rDocShell
.MakeDrawLayer();
171 ScDocument
* pDoc
= rDocShell
.GetDocument();
172 bool bUndo (pDoc
->IsUndoEnabled());
173 ScDrawLayer
* pModel
= pDoc
->GetDrawLayer();
174 SCCOL nCol
= rPos
.Col();
175 SCROW nRow
= rPos
.Row();
176 SCTAB nTab
= rPos
.Tab();
179 pModel
->BeginCalcUndo(false);
180 bool bDone
= ScDetectiveFunc( pDoc
,nTab
).ShowPred( nCol
, nRow
);
181 SdrUndoGroup
* pUndo
= NULL
;
183 pUndo
= pModel
->GetCalcUndo();
186 ScDetOpData
aOperation( ScAddress(nCol
,nRow
,nTab
), SCDETOP_ADDPRED
);
187 pDoc
->AddDetectiveOperation( aOperation
);
190 rDocShell
.GetUndoManager()->AddUndoAction(
191 new ScUndoDetective( &rDocShell
, pUndo
, &aOperation
) );
193 aModificator
.SetDocumentModified();
194 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
196 pBindings
->Invalidate( SID_DETECTIVE_REFRESH
);
204 bool ScDocFunc::DetectiveDelPred(const ScAddress
& rPos
)
206 ScDocument
* pDoc
= rDocShell
.GetDocument();
208 bool bUndo(pDoc
->IsUndoEnabled());
209 ScDrawLayer
* pModel
= pDoc
->GetDrawLayer();
213 ScDocShellModificator
aModificator( rDocShell
);
215 SCCOL nCol
= rPos
.Col();
216 SCROW nRow
= rPos
.Row();
217 SCTAB nTab
= rPos
.Tab();
220 pModel
->BeginCalcUndo(false);
221 bool bDone
= ScDetectiveFunc( pDoc
,nTab
).DeletePred( nCol
, nRow
);
222 SdrUndoGroup
* pUndo
= NULL
;
224 pUndo
= pModel
->GetCalcUndo();
227 ScDetOpData
aOperation( ScAddress(nCol
,nRow
,nTab
), SCDETOP_DELPRED
);
228 pDoc
->AddDetectiveOperation( aOperation
);
231 rDocShell
.GetUndoManager()->AddUndoAction(
232 new ScUndoDetective( &rDocShell
, pUndo
, &aOperation
) );
234 aModificator
.SetDocumentModified();
235 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
237 pBindings
->Invalidate( SID_DETECTIVE_REFRESH
);
245 bool ScDocFunc::DetectiveAddSucc(const ScAddress
& rPos
)
247 ScDocShellModificator
aModificator( rDocShell
);
249 rDocShell
.MakeDrawLayer();
250 ScDocument
* pDoc
= rDocShell
.GetDocument();
252 bool bUndo(pDoc
->IsUndoEnabled());
253 ScDrawLayer
* pModel
= pDoc
->GetDrawLayer();
254 SCCOL nCol
= rPos
.Col();
255 SCROW nRow
= rPos
.Row();
256 SCTAB nTab
= rPos
.Tab();
259 pModel
->BeginCalcUndo(false);
260 bool bDone
= ScDetectiveFunc( pDoc
,nTab
).ShowSucc( nCol
, nRow
);
261 SdrUndoGroup
* pUndo
= NULL
;
263 pUndo
= pModel
->GetCalcUndo();
266 ScDetOpData
aOperation( ScAddress(nCol
,nRow
,nTab
), SCDETOP_ADDSUCC
);
267 pDoc
->AddDetectiveOperation( aOperation
);
270 rDocShell
.GetUndoManager()->AddUndoAction(
271 new ScUndoDetective( &rDocShell
, pUndo
, &aOperation
) );
273 aModificator
.SetDocumentModified();
274 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
276 pBindings
->Invalidate( SID_DETECTIVE_REFRESH
);
284 bool ScDocFunc::DetectiveDelSucc(const ScAddress
& rPos
)
286 ScDocument
* pDoc
= rDocShell
.GetDocument();
288 bool bUndo (pDoc
->IsUndoEnabled());
289 ScDrawLayer
* pModel
= pDoc
->GetDrawLayer();
293 ScDocShellModificator
aModificator( rDocShell
);
295 SCCOL nCol
= rPos
.Col();
296 SCROW nRow
= rPos
.Row();
297 SCTAB nTab
= rPos
.Tab();
300 pModel
->BeginCalcUndo(false);
301 bool bDone
= ScDetectiveFunc( pDoc
,nTab
).DeleteSucc( nCol
, nRow
);
302 SdrUndoGroup
* pUndo
= NULL
;
304 pUndo
= pModel
->GetCalcUndo();
307 ScDetOpData
aOperation( ScAddress(nCol
,nRow
,nTab
), SCDETOP_DELSUCC
);
308 pDoc
->AddDetectiveOperation( aOperation
);
311 rDocShell
.GetUndoManager()->AddUndoAction(
312 new ScUndoDetective( &rDocShell
, pUndo
, &aOperation
) );
314 aModificator
.SetDocumentModified();
315 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
317 pBindings
->Invalidate( SID_DETECTIVE_REFRESH
);
325 bool ScDocFunc::DetectiveAddError(const ScAddress
& rPos
)
327 ScDocShellModificator
aModificator( rDocShell
);
329 rDocShell
.MakeDrawLayer();
330 ScDocument
* pDoc
= rDocShell
.GetDocument();
332 bool bUndo (pDoc
->IsUndoEnabled());
333 ScDrawLayer
* pModel
= pDoc
->GetDrawLayer();
334 SCCOL nCol
= rPos
.Col();
335 SCROW nRow
= rPos
.Row();
336 SCTAB nTab
= rPos
.Tab();
339 pModel
->BeginCalcUndo(false);
340 bool bDone
= ScDetectiveFunc( pDoc
,nTab
).ShowError( nCol
, nRow
);
341 SdrUndoGroup
* pUndo
= NULL
;
343 pUndo
= pModel
->GetCalcUndo();
346 ScDetOpData
aOperation( ScAddress(nCol
,nRow
,nTab
), SCDETOP_ADDERROR
);
347 pDoc
->AddDetectiveOperation( aOperation
);
350 rDocShell
.GetUndoManager()->AddUndoAction(
351 new ScUndoDetective( &rDocShell
, pUndo
, &aOperation
) );
353 aModificator
.SetDocumentModified();
354 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
356 pBindings
->Invalidate( SID_DETECTIVE_REFRESH
);
364 bool ScDocFunc::DetectiveMarkInvalid(SCTAB nTab
)
366 ScDocShellModificator
aModificator( rDocShell
);
368 rDocShell
.MakeDrawLayer();
369 ScDocument
* pDoc
= rDocShell
.GetDocument();
371 bool bUndo (pDoc
->IsUndoEnabled());
372 ScDrawLayer
* pModel
= pDoc
->GetDrawLayer();
374 Window
* pWaitWin
= rDocShell
.GetActiveDialogParent();
376 pWaitWin
->EnterWait();
378 pModel
->BeginCalcUndo(false);
380 bool bDone
= ScDetectiveFunc( pDoc
,nTab
).MarkInvalid( bOverflow
);
381 SdrUndoGroup
* pUndo
= NULL
;
383 pUndo
= pModel
->GetCalcUndo();
385 pWaitWin
->LeaveWait();
390 pUndo
->SetComment( ScGlobal::GetRscString( STR_UNDO_DETINVALID
) );
391 rDocShell
.GetUndoManager()->AddUndoAction( pUndo
);
393 aModificator
.SetDocumentModified();
397 ScGlobal::GetRscString( STR_DETINVALID_OVERFLOW
) ).Execute();
406 bool ScDocFunc::DetectiveDelAll(SCTAB nTab
)
408 ScDocument
* pDoc
= rDocShell
.GetDocument();
410 bool bUndo (pDoc
->IsUndoEnabled());
411 ScDrawLayer
* pModel
= pDoc
->GetDrawLayer();
415 ScDocShellModificator
aModificator( rDocShell
);
418 pModel
->BeginCalcUndo(false);
419 bool bDone
= ScDetectiveFunc( pDoc
,nTab
).DeleteAll( SC_DET_DETECTIVE
);
420 SdrUndoGroup
* pUndo
= NULL
;
422 pUndo
= pModel
->GetCalcUndo();
425 ScDetOpList
* pOldList
= pDoc
->GetDetOpList();
426 ScDetOpList
* pUndoList
= NULL
;
428 pUndoList
= pOldList
? new ScDetOpList(*pOldList
) : NULL
;
430 pDoc
->ClearDetectiveOperations();
434 rDocShell
.GetUndoManager()->AddUndoAction(
435 new ScUndoDetective( &rDocShell
, pUndo
, NULL
, pUndoList
) );
437 aModificator
.SetDocumentModified();
438 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
440 pBindings
->Invalidate( SID_DETECTIVE_REFRESH
);
448 bool ScDocFunc::DetectiveRefresh( bool bAutomatic
)
451 ScDocument
* pDoc
= rDocShell
.GetDocument();
453 bool bUndo (pDoc
->IsUndoEnabled());
454 ScDetOpList
* pList
= pDoc
->GetDetOpList();
455 if ( pList
&& pList
->Count() )
457 rDocShell
.MakeDrawLayer();
458 ScDrawLayer
* pModel
= pDoc
->GetDrawLayer();
460 pModel
->BeginCalcUndo(false);
462 // Loeschen auf allen Tabellen
464 SCTAB nTabCount
= pDoc
->GetTableCount();
465 for (SCTAB nTab
=0; nTab
<nTabCount
; nTab
++)
466 ScDetectiveFunc( pDoc
,nTab
).DeleteAll( SC_DET_ARROWS
); // don't remove circles
470 size_t nCount
= pList
->Count();
471 for (size_t i
=0; i
< nCount
; ++i
)
473 const ScDetOpData
* pData
= pList
->GetObject(i
);
476 ScAddress aPos
= pData
->GetPos();
477 ScDetectiveFunc
aFunc( pDoc
, aPos
.Tab() );
478 SCCOL nCol
= aPos
.Col();
479 SCROW nRow
= aPos
.Row();
480 switch (pData
->GetOperation())
482 case SCDETOP_ADDSUCC
:
483 aFunc
.ShowSucc( nCol
, nRow
);
485 case SCDETOP_DELSUCC
:
486 aFunc
.DeleteSucc( nCol
, nRow
);
488 case SCDETOP_ADDPRED
:
489 aFunc
.ShowPred( nCol
, nRow
);
491 case SCDETOP_DELPRED
:
492 aFunc
.DeletePred( nCol
, nRow
);
494 case SCDETOP_ADDERROR
:
495 aFunc
.ShowError( nCol
, nRow
);
498 OSL_FAIL("falsche Op bei DetectiveRefresh");
505 SdrUndoGroup
* pUndo
= pModel
->GetCalcUndo();
508 pUndo
->SetComment( ScGlobal::GetRscString( STR_UNDO_DETREFRESH
) );
509 // wenn automatisch, an letzte Aktion anhaengen
510 rDocShell
.GetUndoManager()->AddUndoAction(
511 new ScUndoDraw( pUndo
, &rDocShell
),
515 rDocShell
.SetDrawModified();
521 static void lcl_collectAllPredOrSuccRanges(
522 const ScRangeList
& rSrcRanges
, vector
<ScTokenRef
>& rRefTokens
, ScDocShell
& rDocShell
,
525 ScDocument
* pDoc
= rDocShell
.GetDocument();
526 vector
<ScTokenRef
> aRefTokens
;
527 ScRangeList
aSrcRanges(rSrcRanges
);
528 if (aSrcRanges
.empty())
530 ScRange
* p
= aSrcRanges
.front();
531 ScDetectiveFunc
aDetFunc(pDoc
, p
->aStart
.Tab());
532 ScRangeList aDestRanges
;
533 for (size_t i
= 0, n
= aSrcRanges
.size(); i
< n
; ++i
)
538 aDetFunc
.GetAllPreds(
539 p
->aStart
.Col(), p
->aStart
.Row(), p
->aEnd
.Col(), p
->aEnd
.Row(), aRefTokens
);
543 aDetFunc
.GetAllSuccs(
544 p
->aStart
.Col(), p
->aStart
.Row(), p
->aEnd
.Col(), p
->aEnd
.Row(), aRefTokens
);
547 rRefTokens
.swap(aRefTokens
);
550 void ScDocFunc::DetectiveCollectAllPreds(const ScRangeList
& rSrcRanges
, vector
<ScTokenRef
>& rRefTokens
)
552 lcl_collectAllPredOrSuccRanges(rSrcRanges
, rRefTokens
, rDocShell
, true);
555 void ScDocFunc::DetectiveCollectAllSuccs(const ScRangeList
& rSrcRanges
, vector
<ScTokenRef
>& rRefTokens
)
557 lcl_collectAllPredOrSuccRanges(rSrcRanges
, rRefTokens
, rDocShell
, false);
560 bool ScDocFunc::DeleteContents( const ScMarkData
& rMark
, sal_uInt16 nFlags
,
561 bool bRecord
, bool bApi
)
563 ScDocShellModificator
aModificator( rDocShell
);
565 if ( !rMark
.IsMarked() && !rMark
.IsMultiMarked() )
567 OSL_FAIL("ScDocFunc::DeleteContents ohne Markierung");
571 ScDocument
* pDoc
= rDocShell
.GetDocument();
573 if (bRecord
&& !pDoc
->IsUndoEnabled())
576 ScEditableTester
aTester( pDoc
, rMark
);
577 if (!aTester
.IsEditable())
580 rDocShell
.ErrorMessage(aTester
.GetMessageId());
586 ScMarkData aMultiMark
= rMark
;
587 aMultiMark
.SetMarking(false); // fuer MarkToMulti
589 ScDocument
* pUndoDoc
= NULL
;
590 bool bMulti
= aMultiMark
.IsMultiMarked();
591 aMultiMark
.MarkToMulti();
592 aMultiMark
.GetMultiMarkArea( aMarkRange
);
593 ScRange
aExtendedRange(aMarkRange
);
594 if ( pDoc
->ExtendMerge( aExtendedRange
, true ) )
597 // keine Objekte auf geschuetzten Tabellen
598 bool bObjects
= false;
599 if ( nFlags
& IDF_OBJECTS
)
602 SCTAB nTabCount
= pDoc
->GetTableCount();
603 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
604 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
605 if (pDoc
->IsTabProtected(*itr
))
609 sal_uInt16 nExtFlags
= 0; // extra flags are needed only if attributes are deleted
610 if ( nFlags
& IDF_ATTRIB
)
611 rDocShell
.UpdatePaintExt( nExtFlags
, aMarkRange
);
615 // 2) Objekte loeschen (DrawUndo wird gefuellt)
616 // 3) Inhalte fuer Undo kopieren und Undo-Aktion anlegen
617 // 4) Inhalte loeschen
619 bool bDrawUndo
= bObjects
|| (nFlags
& IDF_NOTE
);
620 if (bRecord
&& bDrawUndo
)
621 pDoc
->BeginDrawUndo();
626 pDoc
->DeleteObjectsInSelection( aMultiMark
);
628 pDoc
->DeleteObjectsInArea( aMarkRange
.aStart
.Col(), aMarkRange
.aStart
.Row(),
629 aMarkRange
.aEnd
.Col(), aMarkRange
.aEnd
.Row(),
635 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
636 pUndoDoc
->InitUndo( pDoc
, aMarkRange
.aStart
.Tab(), aMarkRange
.aEnd
.Tab() );
638 // bei "Format/Standard" alle Attribute kopieren, weil CopyToDocument
639 // nur mit IDF_HARDATTR zu langsam ist:
640 sal_uInt16 nUndoDocFlags
= nFlags
;
641 if (nFlags
& IDF_ATTRIB
)
642 nUndoDocFlags
|= IDF_ATTRIB
;
643 if (nFlags
& IDF_EDITATTR
) // Edit-Engine-Attribute
644 nUndoDocFlags
|= IDF_STRING
; // -> Zellen werden geaendert
645 if (nFlags
& IDF_NOTE
)
646 nUndoDocFlags
|= IDF_CONTENTS
; // copy all cells with their notes
647 // note captions are handled in drawing undo
648 nUndoDocFlags
|= IDF_NOCAPTIONS
;
649 pDoc
->CopyToDocument( aExtendedRange
, nUndoDocFlags
, bMulti
, pUndoDoc
, &aMultiMark
);
652 //! HideAllCursors(); // falls Zusammenfassung aufgehoben wird
653 pDoc
->DeleteSelection( nFlags
, aMultiMark
);
655 // add undo action after drawing undo is complete (objects and note captions)
657 rDocShell
.GetUndoManager()->AddUndoAction(
658 new ScUndoDeleteContents( &rDocShell
, aMultiMark
, aExtendedRange
,
659 pUndoDoc
, bMulti
, nFlags
, bDrawUndo
) );
661 if (!AdjustRowHeight( aExtendedRange
))
662 rDocShell
.PostPaint( aExtendedRange
, PAINT_GRID
, nExtFlags
);
663 else if (nExtFlags
& SC_PF_LINES
)
664 lcl_PaintAbove( rDocShell
, aExtendedRange
); // fuer Linien ueber dem Bereich
666 aModificator
.SetDocumentModified();
671 bool ScDocFunc::TransliterateText( const ScMarkData
& rMark
, sal_Int32 nType
,
672 bool bRecord
, bool bApi
)
674 ScDocShellModificator
aModificator( rDocShell
);
676 ScDocument
* pDoc
= rDocShell
.GetDocument();
677 if (bRecord
&& !pDoc
->IsUndoEnabled())
680 ScEditableTester
aTester( pDoc
, rMark
);
681 if (!aTester
.IsEditable())
684 rDocShell
.ErrorMessage(aTester
.GetMessageId());
689 ScMarkData aMultiMark
= rMark
;
690 aMultiMark
.SetMarking(false); // for MarkToMulti
691 aMultiMark
.MarkToMulti();
692 aMultiMark
.GetMultiMarkArea( aMarkRange
);
696 SCTAB nStartTab
= aMarkRange
.aStart
.Tab();
697 SCTAB nTabCount
= pDoc
->GetTableCount();
699 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
700 pUndoDoc
->InitUndo( pDoc
, nStartTab
, nStartTab
);
701 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
702 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
703 if (*itr
!= nStartTab
)
704 pUndoDoc
->AddUndoTab( *itr
, *itr
);
706 ScRange aCopyRange
= aMarkRange
;
707 aCopyRange
.aStart
.SetTab(0);
708 aCopyRange
.aEnd
.SetTab(nTabCount
-1);
709 pDoc
->CopyToDocument( aCopyRange
, IDF_CONTENTS
, true, pUndoDoc
, &aMultiMark
);
711 rDocShell
.GetUndoManager()->AddUndoAction(
712 new ScUndoTransliterate( &rDocShell
, aMultiMark
, pUndoDoc
, nType
) );
715 pDoc
->TransliterateText( aMultiMark
, nType
);
717 if (!AdjustRowHeight( aMarkRange
))
718 rDocShell
.PostPaint( aMarkRange
, PAINT_GRID
);
720 aModificator
.SetDocumentModified();
725 bool ScDocFunc::SetNormalString( bool& o_rbNumFmtSet
, const ScAddress
& rPos
, const OUString
& rText
, bool bApi
)
727 ScDocShellModificator
aModificator( rDocShell
);
728 ScDocument
* pDoc
= rDocShell
.GetDocument();
730 bool bUndo(pDoc
->IsUndoEnabled());
731 ScEditableTester
aTester( pDoc
, rPos
.Tab(), rPos
.Col(),rPos
.Row(), rPos
.Col(),rPos
.Row() );
732 if (!aTester
.IsEditable())
735 rDocShell
.ErrorMessage(aTester
.GetMessageId());
739 bool bEditDeleted
= (pDoc
->GetCellType(rPos
) == CELLTYPE_EDIT
);
740 ScUndoEnterData::ValuesType aOldValues
;
744 ScUndoEnterData::Value aOldValue
;
746 aOldValue
.mnTab
= rPos
.Tab();
747 aOldValue
.maCell
.assign(*pDoc
, rPos
);
749 const SfxPoolItem
* pItem
;
750 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( rPos
.Col(),rPos
.Row(),rPos
.Tab() );
751 if ( SFX_ITEM_SET
== pPattern
->GetItemSet().GetItemState(
752 ATTR_VALUE_FORMAT
,false,&pItem
) )
754 aOldValue
.mbHasFormat
= true;
755 aOldValue
.mnFormat
= ((const SfxUInt32Item
*)pItem
)->GetValue();
758 aOldValue
.mbHasFormat
= false;
760 aOldValues
.push_back(aOldValue
);
763 o_rbNumFmtSet
= pDoc
->SetString( rPos
.Col(), rPos
.Row(), rPos
.Tab(), rText
);
767 // wegen ChangeTracking darf UndoAction erst nach SetString angelegt werden
768 rDocShell
.GetUndoManager()->AddUndoAction(
769 new ScUndoEnterData(&rDocShell
, rPos
, aOldValues
, rText
, NULL
));
772 if ( bEditDeleted
|| pDoc
->HasAttrib( ScRange(rPos
), HASATTR_NEEDHEIGHT
) )
773 AdjustRowHeight( ScRange(rPos
) );
775 rDocShell
.PostPaintCell( rPos
);
776 aModificator
.SetDocumentModified();
778 // notify input handler here the same way as in PutCell
780 NotifyInputHandler( rPos
);
785 bool ScDocFunc::SetValueCell( const ScAddress
& rPos
, double fVal
, bool bInteraction
)
787 ScDocShellModificator
aModificator( rDocShell
);
788 ScDocument
* pDoc
= rDocShell
.GetDocument();
789 bool bUndo
= pDoc
->IsUndoEnabled();
791 bool bHeight
= pDoc
->HasAttrib(rPos
, HASATTR_NEEDHEIGHT
);
795 aOldVal
.assign(*pDoc
, rPos
);
797 pDoc
->SetValue(rPos
, fVal
);
801 svl::IUndoManager
* pUndoMgr
= rDocShell
.GetUndoManager();
803 aNewVal
.assign(*pDoc
, rPos
);
804 pUndoMgr
->AddUndoAction(new ScUndoSetCell(&rDocShell
, rPos
, aOldVal
, aNewVal
));
808 AdjustRowHeight(rPos
);
810 rDocShell
.PostPaintCell( rPos
);
811 aModificator
.SetDocumentModified();
813 // #103934#; notify editline and cell in edit mode
815 NotifyInputHandler( rPos
);
820 bool ScDocFunc::SetValueCells( const ScAddress
& rPos
, const std::vector
<double>& aVals
, bool bInteraction
)
822 // Check for invalid range.
823 SCROW nLastRow
= rPos
.Row() + aVals
.size() - 1;
824 if (nLastRow
> MAXROW
)
828 ScRange
aRange(rPos
);
829 aRange
.aEnd
.SetRow(nLastRow
);
831 ScDocShellModificator
aModificator(rDocShell
);
832 ScDocument
* pDoc
= rDocShell
.GetDocument();
834 if (pDoc
->IsUndoEnabled())
836 sc::UndoSetCells
* pUndoObj
= new sc::UndoSetCells(&rDocShell
, rPos
);
837 pDoc
->TransferCellValuesTo(rPos
, aVals
.size(), pUndoObj
->GetOldValues());
838 pUndoObj
->SetNewValues(aVals
);
839 svl::IUndoManager
* pUndoMgr
= rDocShell
.GetUndoManager();
840 pUndoMgr
->AddUndoAction(pUndoObj
);
843 pDoc
->SetValues(rPos
, aVals
);
845 rDocShell
.PostPaint(aRange
, PAINT_GRID
);
846 aModificator
.SetDocumentModified();
848 // #103934#; notify editline and cell in edit mode
850 NotifyInputHandler(rPos
);
855 bool ScDocFunc::SetStringCell( const ScAddress
& rPos
, const OUString
& rStr
, bool bInteraction
)
857 ScDocShellModificator
aModificator( rDocShell
);
858 ScDocument
* pDoc
= rDocShell
.GetDocument();
859 bool bUndo
= pDoc
->IsUndoEnabled();
861 bool bHeight
= pDoc
->HasAttrib(rPos
, HASATTR_NEEDHEIGHT
);
865 aOldVal
.assign(*pDoc
, rPos
);
867 ScSetStringParam aParam
;
868 aParam
.setTextInput();
869 pDoc
->SetString(rPos
, rStr
, &aParam
);
873 svl::IUndoManager
* pUndoMgr
= rDocShell
.GetUndoManager();
875 aNewVal
.assign(*pDoc
, rPos
);
876 pUndoMgr
->AddUndoAction(new ScUndoSetCell(&rDocShell
, rPos
, aOldVal
, aNewVal
));
880 AdjustRowHeight(rPos
);
882 rDocShell
.PostPaintCell( rPos
);
883 aModificator
.SetDocumentModified();
885 // #103934#; notify editline and cell in edit mode
887 NotifyInputHandler( rPos
);
892 bool ScDocFunc::SetEditCell( const ScAddress
& rPos
, const EditTextObject
& rStr
, bool bInteraction
)
894 ScDocShellModificator
aModificator( rDocShell
);
895 ScDocument
* pDoc
= rDocShell
.GetDocument();
896 bool bUndo
= pDoc
->IsUndoEnabled();
898 bool bHeight
= pDoc
->HasAttrib(rPos
, HASATTR_NEEDHEIGHT
);
902 aOldVal
.assign(*pDoc
, rPos
);
904 pDoc
->SetEditText(rPos
, rStr
.Clone());
908 svl::IUndoManager
* pUndoMgr
= rDocShell
.GetUndoManager();
910 aNewVal
.assign(*pDoc
, rPos
);
911 pUndoMgr
->AddUndoAction(new ScUndoSetCell(&rDocShell
, rPos
, aOldVal
, aNewVal
));
915 AdjustRowHeight(rPos
);
917 rDocShell
.PostPaintCell( rPos
);
918 aModificator
.SetDocumentModified();
920 // #103934#; notify editline and cell in edit mode
922 NotifyInputHandler( rPos
);
927 bool ScDocFunc::SetStringOrEditCell( const ScAddress
& rPos
, const OUString
& rStr
, bool bInteraction
)
929 ScDocument
* pDoc
= rDocShell
.GetDocument();
931 if (ScStringUtil::isMultiline(rStr
))
933 ScFieldEditEngine
& rEngine
= pDoc
->GetEditEngine();
934 rEngine
.SetText(rStr
);
935 boost::scoped_ptr
<EditTextObject
> pEditText(rEngine
.CreateTextObject());
936 return SetEditCell(rPos
, *pEditText
, bInteraction
);
939 return SetStringCell(rPos
, rStr
, bInteraction
);
942 bool ScDocFunc::SetFormulaCell( const ScAddress
& rPos
, ScFormulaCell
* pCell
, bool bInteraction
)
944 SAL_WNODEPRECATED_DECLARATIONS_PUSH
945 std::auto_ptr
<ScFormulaCell
> xCell(pCell
);
946 SAL_WNODEPRECATED_DECLARATIONS_POP
948 ScDocShellModificator
aModificator( rDocShell
);
949 ScDocument
* pDoc
= rDocShell
.GetDocument();
950 bool bUndo
= pDoc
->IsUndoEnabled();
952 bool bHeight
= pDoc
->HasAttrib(rPos
, HASATTR_NEEDHEIGHT
);
956 aOldVal
.assign(*pDoc
, rPos
);
958 pCell
= pDoc
->SetFormulaCell(rPos
, xCell
.release());
960 // For performance reasons API calls may disable calculation while
961 // operating and recalculate once when done. If through user interaction
962 // and AutoCalc is disabled, calculate the formula (without its
963 // dependencies) once so the result matches the current document's content.
964 if (bInteraction
&& !pDoc
->GetAutoCalc() && pCell
)
966 // calculate just the cell once and set Dirty again
968 pCell
->SetDirtyVar();
969 pDoc
->PutInFormulaTree( pCell
);
974 svl::IUndoManager
* pUndoMgr
= rDocShell
.GetUndoManager();
976 aNewVal
.assign(*pDoc
, rPos
);
977 pUndoMgr
->AddUndoAction(new ScUndoSetCell(&rDocShell
, rPos
, aOldVal
, aNewVal
));
981 AdjustRowHeight(rPos
);
983 rDocShell
.PostPaintCell( rPos
);
984 aModificator
.SetDocumentModified();
986 // #103934#; notify editline and cell in edit mode
988 NotifyInputHandler( rPos
);
993 void ScDocFunc::NotifyInputHandler( const ScAddress
& rPos
)
995 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
996 if ( pViewSh
&& pViewSh
->GetViewData()->GetDocShell() == &rDocShell
)
998 ScInputHandler
* pInputHdl
= SC_MOD()->GetInputHdl();
999 if ( pInputHdl
&& pInputHdl
->GetCursorPos() == rPos
)
1001 bool bIsEditMode(pInputHdl
->IsEditMode());
1003 // set modified if in editmode, because so the string is not set in the InputWindow like in the cell
1004 // (the cell shows the same like the InputWindow)
1006 pInputHdl
->SetModified();
1007 pViewSh
->UpdateInputHandler(false, !bIsEditMode
);
1012 struct ScMyRememberItem
1015 SfxItemSet aItemSet
;
1017 ScMyRememberItem(const SfxItemSet
& rItemSet
, sal_Int32 nTempIndex
) :
1018 nIndex(nTempIndex
), aItemSet(rItemSet
) {}
1021 typedef ::std::list
<ScMyRememberItem
*> ScMyRememberItemList
;
1023 bool ScDocFunc::PutData( const ScAddress
& rPos
, ScEditEngineDefaulter
& rEngine
, bool bApi
)
1025 // PutData ruft PutCell oder SetNormalString
1028 ScDocument
* pDoc
= rDocShell
.GetDocument();
1029 ScEditAttrTester
aTester( &rEngine
);
1030 bool bEditCell
= aTester
.NeedsObject();
1033 // #i61702# With bLoseContent set, the content of rEngine isn't restored
1034 // (used in loading XML, where after the removeActionLock call the API object's
1035 // EditEngine isn't accessed again.
1036 bool bLoseContent
= pDoc
->IsImportingXML();
1038 bool bUpdateMode(rEngine
.GetUpdateMode());
1040 rEngine
.SetUpdateMode(false);
1042 ScMyRememberItemList aRememberItems
;
1043 ScMyRememberItem
* pRememberItem
= NULL
;
1045 // All paragraph attributes must be removed before calling CreateTextObject,
1046 // not only alignment, so the object doesn't contain the cell attributes as
1047 // paragraph attributes. Before remove the attributes store they in a list to
1048 // set they back to the EditEngine.
1049 sal_Int32 nCount
= rEngine
.GetParagraphCount();
1050 for (sal_Int32 i
=0; i
<nCount
; i
++)
1052 const SfxItemSet
& rOld
= rEngine
.GetParaAttribs( i
);
1055 if ( !bLoseContent
)
1057 pRememberItem
= new ScMyRememberItem(rEngine
.GetParaAttribs(i
), i
);
1058 aRememberItems
.push_back(pRememberItem
);
1060 rEngine
.SetParaAttribs( i
, SfxItemSet( *rOld
.GetPool(), rOld
.GetRanges() ) );
1064 // A copy of pNewData will be stored in the cell.
1065 boost::scoped_ptr
<EditTextObject
> pNewData(rEngine
.CreateTextObject());
1066 bRet
= SetEditCell(rPos
, *pNewData
, !bApi
);
1068 // Set the paragraph attributes back to the EditEngine.
1069 if (!aRememberItems
.empty())
1071 ScMyRememberItemList::iterator aItr
= aRememberItems
.begin();
1072 while (aItr
!= aRememberItems
.end())
1074 pRememberItem
= *aItr
;
1075 rEngine
.SetParaAttribs(pRememberItem
->nIndex
, pRememberItem
->aItemSet
);
1076 delete pRememberItem
;
1077 aItr
= aRememberItems
.erase(aItr
);
1081 // #i61702# if the content isn't accessed, there's no need to set the UpdateMode again
1082 if ( bUpdateMode
&& !bLoseContent
)
1083 rEngine
.SetUpdateMode(true);
1087 OUString aText
= rEngine
.GetText();
1088 if (aText
.isEmpty())
1090 bool bNumFmtSet
= false;
1091 bRet
= SetNormalString( bNumFmtSet
, rPos
, aText
, bApi
);
1094 bRet
= SetStringCell(rPos
, aText
, !bApi
);
1097 if ( bRet
&& aTester
.NeedsCellAttr() )
1099 const SfxItemSet
& rEditAttr
= aTester
.GetAttribs();
1100 ScPatternAttr
aPattern( pDoc
->GetPool() );
1101 aPattern
.GetFromEditItemSet( &rEditAttr
);
1102 aPattern
.DeleteUnchanged( pDoc
->GetPattern( rPos
.Col(), rPos
.Row(), rPos
.Tab() ) );
1103 aPattern
.GetItemSet().ClearItem( ATTR_HOR_JUSTIFY
); // wasn't removed above if no edit object
1104 if ( aPattern
.GetItemSet().Count() > 0 )
1107 aMark
.SelectTable( rPos
.Tab(), true );
1108 aMark
.SetMarkArea( ScRange( rPos
) );
1109 ApplyAttributes( aMark
, aPattern
, true, bApi
);
1117 static ScTokenArray
* lcl_ScDocFunc_CreateTokenArrayXML( const OUString
& rText
, const OUString
& rFormulaNmsp
, const formula::FormulaGrammar::Grammar eGrammar
)
1119 ScTokenArray
* pCode
= new ScTokenArray
;
1120 pCode
->AddStringXML( rText
);
1121 if( (eGrammar
== formula::FormulaGrammar::GRAM_EXTERNAL
) && (!rFormulaNmsp
.isEmpty()) )
1122 pCode
->AddStringXML( rFormulaNmsp
);
1126 bool ScDocFunc::SetCellText(
1127 const ScAddress
& rPos
, const OUString
& rText
, bool bInterpret
, bool bEnglish
, bool bApi
,
1128 const formula::FormulaGrammar::Grammar eGrammar
)
1135 ScDocument
* pDoc
= rDocShell
.GetDocument();
1137 ::boost::scoped_ptr
<ScExternalRefManager::ApiGuard
> pExtRefGuard
;
1139 pExtRefGuard
.reset(new ScExternalRefManager::ApiGuard(pDoc
));
1141 ScInputStringType aRes
=
1142 ScStringUtil::parseInputString(*pDoc
->GetFormatTable(), rText
, LANGUAGE_ENGLISH_US
);
1144 switch (aRes
.meType
)
1146 case ScInputStringType::Formula
:
1147 bSet
= SetFormulaCell(rPos
, new ScFormulaCell(pDoc
, rPos
, aRes
.maText
, eGrammar
), !bApi
);
1149 case ScInputStringType::Number
:
1150 bSet
= SetValueCell(rPos
, aRes
.mfValue
, !bApi
);
1152 case ScInputStringType::Text
:
1153 bSet
= SetStringOrEditCell(rPos
, aRes
.maText
, !bApi
);
1159 // sonst Null behalten -> SetString mit lokalen Formeln/Zahlformat
1161 else if (!rText
.isEmpty())
1163 bSet
= SetStringOrEditCell(rPos
, rText
, !bApi
);
1168 bool bNumFmtSet
= false;
1169 bSet
= SetNormalString( bNumFmtSet
, rPos
, rText
, bApi
);
1174 bool ScDocFunc::ShowNote( const ScAddress
& rPos
, bool bShow
)
1176 ScDocument
& rDoc
= *rDocShell
.GetDocument();
1177 ScPostIt
* pNote
= rDoc
.GetNote( rPos
);
1178 if( !pNote
|| (bShow
== pNote
->IsCaptionShown()) ) return false;
1180 // move the caption to internal or hidden layer and create undo action
1181 pNote
->ShowCaption( rPos
, bShow
);
1182 if( rDoc
.IsUndoEnabled() )
1183 rDocShell
.GetUndoManager()->AddUndoAction( new ScUndoShowHideNote( rDocShell
, rPos
, bShow
) );
1185 if (rDoc
.IsStreamValid(rPos
.Tab()))
1186 rDoc
.SetStreamValid(rPos
.Tab(), false);
1188 rDocShell
.SetDocumentModified();
1193 bool ScDocFunc::SetNoteText( const ScAddress
& rPos
, const OUString
& rText
, bool bApi
)
1195 ScDocShellModificator
aModificator( rDocShell
);
1197 ScDocument
* pDoc
= rDocShell
.GetDocument();
1198 ScEditableTester
aTester( pDoc
, rPos
.Tab(), rPos
.Col(),rPos
.Row(), rPos
.Col(),rPos
.Row() );
1199 if (!aTester
.IsEditable())
1202 rDocShell
.ErrorMessage(aTester
.GetMessageId());
1206 OUString aNewText
= convertLineEnd(rText
, GetSystemLineEnd()); //! ist das noetig ???
1208 if( ScPostIt
* pNote
= (!aNewText
.isEmpty()) ? pDoc
->GetOrCreateNote( rPos
) : pDoc
->GetNote(rPos
) )
1209 pNote
->SetText( rPos
, aNewText
);
1213 if (pDoc
->IsStreamValid(rPos
.Tab()))
1214 pDoc
->SetStreamValid(rPos
.Tab(), false);
1216 rDocShell
.PostPaintCell( rPos
);
1217 aModificator
.SetDocumentModified();
1222 bool ScDocFunc::ReplaceNote( const ScAddress
& rPos
, const OUString
& rNoteText
, const OUString
* pAuthor
, const OUString
* pDate
, bool bApi
)
1226 ScDocShellModificator
aModificator( rDocShell
);
1227 ScDocument
& rDoc
= *rDocShell
.GetDocument();
1228 ScEditableTester
aTester( &rDoc
, rPos
.Tab(), rPos
.Col(),rPos
.Row(), rPos
.Col(),rPos
.Row() );
1229 if (aTester
.IsEditable())
1231 ScDrawLayer
* pDrawLayer
= rDoc
.GetDrawLayer();
1232 ::svl::IUndoManager
* pUndoMgr
= (pDrawLayer
&& rDoc
.IsUndoEnabled()) ? rDocShell
.GetUndoManager() : 0;
1234 ScNoteData aOldData
;
1235 ScPostIt
* pOldNote
= rDoc
.ReleaseNote( rPos
);
1238 // ensure existing caption object before draw undo tracking starts
1239 pOldNote
->GetOrCreateCaption( rPos
);
1240 // rescue note data for undo
1241 aOldData
= pOldNote
->GetNoteData();
1244 // collect drawing undo actions for deleting/inserting caption objects
1246 pDrawLayer
->BeginCalcUndo(false);
1248 // delete the note (creates drawing undo action for the caption object)
1251 // create new note (creates drawing undo action for the new caption object)
1252 ScNoteData aNewData
;
1253 if( ScPostIt
* pNewNote
= ScNoteUtil::CreateNoteFromString( rDoc
, rPos
, rNoteText
, false, true ) )
1255 if( pAuthor
) pNewNote
->SetAuthor( *pAuthor
);
1256 if( pDate
) pNewNote
->SetDate( *pDate
);
1257 // rescue note data for undo
1258 aNewData
= pNewNote
->GetNoteData();
1261 // create the undo action
1262 if( pUndoMgr
&& (aOldData
.mpCaption
|| aNewData
.mpCaption
) )
1263 pUndoMgr
->AddUndoAction( new ScUndoReplaceNote( rDocShell
, rPos
, aOldData
, aNewData
, pDrawLayer
->GetCalcUndo() ) );
1265 // repaint cell (to make note marker visible)
1266 rDocShell
.PostPaintCell( rPos
);
1268 if (rDoc
.IsStreamValid(rPos
.Tab()))
1269 rDoc
.SetStreamValid(rPos
.Tab(), false);
1271 aModificator
.SetDocumentModified();
1276 rDocShell
.ErrorMessage(aTester
.GetMessageId());
1282 bool ScDocFunc::ApplyAttributes( const ScMarkData
& rMark
, const ScPatternAttr
& rPattern
,
1283 bool bRecord
, bool bApi
)
1285 ScDocument
* pDoc
= rDocShell
.GetDocument();
1286 if ( bRecord
&& !pDoc
->IsUndoEnabled() )
1289 bool bImportingXML
= pDoc
->IsImportingXML();
1290 // Cell formats can still be set if the range isn't editable only because of matrix formulas.
1291 // #i62483# When loading XML, the check can be skipped altogether.
1292 bool bOnlyNotBecauseOfMatrix
;
1293 if ( !bImportingXML
&& !pDoc
->IsSelectionEditable( rMark
, &bOnlyNotBecauseOfMatrix
)
1294 && !bOnlyNotBecauseOfMatrix
)
1297 rDocShell
.ErrorMessage(STR_PROTECTIONERR
);
1301 ScDocShellModificator
aModificator( rDocShell
);
1305 ScRange aMultiRange
;
1306 bool bMulti
= rMark
.IsMultiMarked();
1308 rMark
.GetMultiMarkArea( aMultiRange
);
1310 rMark
.GetMarkArea( aMultiRange
);
1314 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1315 pUndoDoc
->InitUndo( pDoc
, aMultiRange
.aStart
.Tab(), aMultiRange
.aEnd
.Tab() );
1316 pDoc
->CopyToDocument( aMultiRange
, IDF_ATTRIB
, bMulti
, pUndoDoc
, &rMark
);
1318 rDocShell
.GetUndoManager()->AddUndoAction(
1319 new ScUndoSelectionAttr(
1321 aMultiRange
.aStart
.Col(), aMultiRange
.aStart
.Row(), aMultiRange
.aStart
.Tab(),
1322 aMultiRange
.aEnd
.Col(), aMultiRange
.aEnd
.Row(), aMultiRange
.aEnd
.Tab(),
1323 pUndoDoc
, bMulti
, &rPattern
) );
1326 // While loading XML it is not necessary to ask HasAttrib. It needs too much time.
1327 sal_uInt16 nExtFlags
= 0;
1328 if ( !bImportingXML
)
1329 rDocShell
.UpdatePaintExt( nExtFlags
, aMultiRange
); // content before the change
1330 pDoc
->ApplySelectionPattern( rPattern
, rMark
);
1331 if ( !bImportingXML
)
1332 rDocShell
.UpdatePaintExt( nExtFlags
, aMultiRange
); // content after the change
1334 if (!AdjustRowHeight( aMultiRange
))
1335 rDocShell
.PostPaint( aMultiRange
, PAINT_GRID
, nExtFlags
);
1336 else if (nExtFlags
& SC_PF_LINES
)
1337 lcl_PaintAbove( rDocShell
, aMultiRange
); // fuer Linien ueber dem Bereich
1339 aModificator
.SetDocumentModified();
1345 bool ScDocFunc::ApplyStyle( const ScMarkData
& rMark
, const OUString
& rStyleName
,
1346 bool bRecord
, bool bApi
)
1348 ScDocument
* pDoc
= rDocShell
.GetDocument();
1349 if ( bRecord
&& !pDoc
->IsUndoEnabled() )
1352 bool bImportingXML
= pDoc
->IsImportingXML();
1353 // Cell formats can still be set if the range isn't editable only because of matrix formulas.
1354 // #i62483# When loading XML, the check can be skipped altogether.
1355 bool bOnlyNotBecauseOfMatrix
;
1356 if ( !bImportingXML
&& !pDoc
->IsSelectionEditable( rMark
, &bOnlyNotBecauseOfMatrix
)
1357 && !bOnlyNotBecauseOfMatrix
)
1360 rDocShell
.ErrorMessage(STR_PROTECTIONERR
);
1364 ScStyleSheet
* pStyleSheet
= (ScStyleSheet
*) pDoc
->GetStyleSheetPool()->Find(
1365 rStyleName
, SFX_STYLE_FAMILY_PARA
);
1369 ScDocShellModificator
aModificator( rDocShell
);
1371 ScRange aMultiRange
;
1372 bool bMulti
= rMark
.IsMultiMarked();
1374 rMark
.GetMultiMarkArea( aMultiRange
);
1376 rMark
.GetMarkArea( aMultiRange
);
1380 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1381 SCTAB nStartTab
= aMultiRange
.aStart
.Tab();
1382 SCTAB nTabCount
= pDoc
->GetTableCount();
1383 pUndoDoc
->InitUndo( pDoc
, nStartTab
, nStartTab
);
1384 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
1385 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
1386 if (*itr
!= nStartTab
)
1387 pUndoDoc
->AddUndoTab( *itr
, *itr
);
1389 ScRange aCopyRange
= aMultiRange
;
1390 aCopyRange
.aStart
.SetTab(0);
1391 aCopyRange
.aEnd
.SetTab(nTabCount
-1);
1392 pDoc
->CopyToDocument( aCopyRange
, IDF_ATTRIB
, bMulti
, pUndoDoc
, &rMark
);
1394 rDocShell
.GetUndoManager()->AddUndoAction(
1395 new ScUndoSelectionStyle(
1396 &rDocShell
, rMark
, aMultiRange
, rStyleName
, pUndoDoc
) );
1400 pDoc
->ApplySelectionStyle( (ScStyleSheet
&)*pStyleSheet
, rMark
);
1402 if (!AdjustRowHeight( aMultiRange
))
1403 rDocShell
.PostPaint( aMultiRange
, PAINT_GRID
, 0 );
1405 aModificator
.SetDocumentModified();
1413 * Check if this insertion attempt would end up cutting one or more pivot
1414 * tables in half, which is not desirable.
1416 * @return true if this insertion can be done safely without shearing any
1417 * existing pivot tables, false otherwise.
1419 bool canInsertCellsByPivot(const ScRange
& rRange
, const ScMarkData
& rMarkData
, InsCellCmd eCmd
, const ScDocument
* pDoc
)
1421 if (!pDoc
->HasPivotTable())
1422 // This document has no pivot tables.
1425 const ScDPCollection
* pDPs
= pDoc
->GetDPCollection();
1426 ScMarkData::const_iterator itBeg
= rMarkData
.begin(), itEnd
= rMarkData
.end();
1428 ScRange
aRange(rRange
); // local copy
1433 aRange
.aStart
.SetCol(0);
1434 aRange
.aEnd
.SetCol(MAXCOL
);
1439 for (ScMarkData::const_iterator it
= itBeg
; it
!= itEnd
; ++it
)
1441 if (pDPs
->IntersectsTableByColumns(aRange
.aStart
.Col(), aRange
.aEnd
.Col(), aRange
.aStart
.Row(), *it
))
1442 // This column range cuts through at least one pivot table. Not good.
1446 // Start row must be either at the top or above any pivot tables.
1447 if (aRange
.aStart
.Row() < 0)
1448 // I don't know how to handle this case.
1451 if (aRange
.aStart
.Row() == 0)
1452 // First row is always allowed.
1455 ScRange
aTest(aRange
);
1456 aTest
.aStart
.IncRow(-1); // Test one row up.
1457 aTest
.aEnd
.SetRow(aTest
.aStart
.Row());
1458 for (ScMarkData::const_iterator it
= itBeg
; it
!= itEnd
; ++it
)
1460 aTest
.aStart
.SetTab(*it
);
1461 aTest
.aEnd
.SetTab(*it
);
1462 if (pDPs
->HasTable(aTest
))
1469 aRange
.aStart
.SetRow(0);
1470 aRange
.aEnd
.SetRow(MAXROW
);
1473 case INS_CELLSRIGHT
:
1475 for (ScMarkData::const_iterator it
= itBeg
; it
!= itEnd
; ++it
)
1477 if (pDPs
->IntersectsTableByRows(aRange
.aStart
.Col(), aRange
.aStart
.Row(), aRange
.aEnd
.Row(), *it
))
1478 // This column range cuts through at least one pivot table. Not good.
1482 // Start row must be either at the top or above any pivot tables.
1483 if (aRange
.aStart
.Col() < 0)
1484 // I don't know how to handle this case.
1487 if (aRange
.aStart
.Col() == 0)
1488 // First row is always allowed.
1491 ScRange
aTest(aRange
);
1492 aTest
.aStart
.IncCol(-1); // Test one column to the left.
1493 aTest
.aEnd
.SetCol(aTest
.aStart
.Col());
1494 for (ScMarkData::const_iterator it
= itBeg
; it
!= itEnd
; ++it
)
1496 aTest
.aStart
.SetTab(*it
);
1497 aTest
.aEnd
.SetTab(*it
);
1498 if (pDPs
->HasTable(aTest
))
1510 * Check if this deletion attempt would end up cutting one or more pivot
1511 * tables in half, which is not desirable.
1513 * @return true if this deletion can be done safely without shearing any
1514 * existing pivot tables, false otherwise.
1516 bool canDeleteCellsByPivot(const ScRange
& rRange
, const ScMarkData
& rMarkData
, DelCellCmd eCmd
, const ScDocument
* pDoc
)
1518 if (!pDoc
->HasPivotTable())
1519 // This document has no pivot tables.
1522 const ScDPCollection
* pDPs
= pDoc
->GetDPCollection();
1523 ScMarkData::const_iterator itBeg
= rMarkData
.begin(), itEnd
= rMarkData
.end();
1525 ScRange
aRange(rRange
); // local copy
1531 aRange
.aStart
.SetCol(0);
1532 aRange
.aEnd
.SetCol(MAXCOL
);
1537 for (ScMarkData::const_iterator it
= itBeg
; it
!= itEnd
; ++it
)
1539 if (pDPs
->IntersectsTableByColumns(aRange
.aStart
.Col(), aRange
.aEnd
.Col(), aRange
.aStart
.Row(), *it
))
1540 // This column range cuts through at least one pivot table. Not good.
1544 ScRange
aTest(aRange
);
1545 for (ScMarkData::const_iterator it
= itBeg
; it
!= itEnd
; ++it
)
1547 aTest
.aStart
.SetTab(*it
);
1548 aTest
.aEnd
.SetTab(*it
);
1549 if (pDPs
->HasTable(aTest
))
1556 aRange
.aStart
.SetRow(0);
1557 aRange
.aEnd
.SetRow(MAXROW
);
1562 for (ScMarkData::const_iterator it
= itBeg
; it
!= itEnd
; ++it
)
1564 if (pDPs
->IntersectsTableByRows(aRange
.aStart
.Col(), aRange
.aStart
.Row(), aRange
.aEnd
.Row(), *it
))
1565 // This column range cuts through at least one pivot table. Not good.
1569 ScRange
aTest(aRange
);
1570 for (ScMarkData::const_iterator it
= itBeg
; it
!= itEnd
; ++it
)
1572 aTest
.aStart
.SetTab(*it
);
1573 aTest
.aEnd
.SetTab(*it
);
1574 if (pDPs
->HasTable(aTest
))
1587 bool ScDocFunc::InsertCells( const ScRange
& rRange
, const ScMarkData
* pTabMark
, InsCellCmd eCmd
,
1588 bool bRecord
, bool bApi
, bool bPartOfPaste
)
1590 ScDocShellModificator
aModificator( rDocShell
);
1592 SCCOL nStartCol
= rRange
.aStart
.Col();
1593 SCROW nStartRow
= rRange
.aStart
.Row();
1594 SCTAB nStartTab
= rRange
.aStart
.Tab();
1595 SCCOL nEndCol
= rRange
.aEnd
.Col();
1596 SCROW nEndRow
= rRange
.aEnd
.Row();
1597 SCTAB nEndTab
= rRange
.aEnd
.Tab();
1599 if ( !ValidRow(nStartRow
) || !ValidRow(nEndRow
) )
1601 OSL_FAIL("invalid row in InsertCells");
1605 ScDocument
* pDoc
= rDocShell
.GetDocument();
1606 SCTAB nTabCount
= pDoc
->GetTableCount();
1607 SCCOL nPaintStartCol
= nStartCol
;
1608 SCROW nPaintStartRow
= nStartRow
;
1609 SCCOL nPaintEndCol
= nEndCol
;
1610 SCROW nPaintEndRow
= nEndRow
;
1611 sal_uInt16 nPaintFlags
= PAINT_GRID
;
1615 ScTabViewShell
* pViewSh
= rDocShell
.GetBestViewShell(); //preserve current cursor position
1616 SCCOL nCursorCol
= 0;
1617 SCROW nCursorRow
= 0;
1620 nCursorCol
= pViewSh
->GetViewData()->GetCurX();
1621 nCursorRow
= pViewSh
->GetViewData()->GetCurY();
1624 if (bRecord
&& !pDoc
->IsUndoEnabled())
1633 for( i
=0; i
<nTabCount
; i
++ )
1635 if( !pDoc
->IsScenario(i
) )
1638 if( nCount
== nEndTab
+1 )
1640 aMark
.SelectTable( i
, true );
1647 ScMarkData
aFullMark( aMark
); // including scenario sheets
1648 ScMarkData::iterator itr
= aMark
.begin(), itrEnd
= aMark
.end();
1649 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
1650 for( SCTAB j
= *itr
+1; j
<nTabCount
&& pDoc
->IsScenario(j
); j
++ )
1651 aFullMark
.SelectTable( j
, true );
1653 SCTAB nSelCount
= aMark
.GetSelectCount();
1655 // zugehoerige Szenarien auch anpassen
1656 // Test zusammengefasste
1658 SCCOL nMergeTestStartCol
= nStartCol
;
1659 SCROW nMergeTestStartRow
= nStartRow
;
1660 SCCOL nMergeTestEndCol
= nEndCol
;
1661 SCROW nMergeTestEndRow
= nEndRow
;
1663 ScRange
aExtendMergeRange( rRange
);
1665 if( rRange
.aStart
== rRange
.aEnd
&& pDoc
->HasAttrib(rRange
, HASATTR_MERGED
) )
1667 pDoc
->ExtendMerge( aExtendMergeRange
);
1668 pDoc
->ExtendOverlapped( aExtendMergeRange
);
1669 nMergeTestEndCol
= aExtendMergeRange
.aEnd
.Col();
1670 nMergeTestEndRow
= aExtendMergeRange
.aEnd
.Row();
1671 nPaintEndCol
= nMergeTestEndCol
;
1672 nPaintEndRow
= nMergeTestEndRow
;
1675 if ( eCmd
== INS_INSROWS
)
1677 nMergeTestStartCol
= 0;
1678 nMergeTestEndCol
= MAXCOL
;
1680 if ( eCmd
== INS_INSCOLS
)
1682 nMergeTestStartRow
= 0;
1683 nMergeTestEndRow
= MAXROW
;
1685 if ( eCmd
== INS_CELLSDOWN
)
1686 nMergeTestEndRow
= MAXROW
;
1687 if ( eCmd
== INS_CELLSRIGHT
)
1688 nMergeTestEndCol
= MAXCOL
;
1690 bool bNeedRefresh
= false;
1692 SCCOL nEditTestEndCol
= (eCmd
==INS_INSCOLS
) ? MAXCOL
: nMergeTestEndCol
;
1693 SCROW nEditTestEndRow
= (eCmd
==INS_INSROWS
) ? MAXROW
: nMergeTestEndRow
;
1694 ScEditableTester
aTester( pDoc
, nMergeTestStartCol
, nMergeTestStartRow
, nEditTestEndCol
, nEditTestEndRow
, aMark
);
1695 if (!aTester
.IsEditable())
1698 rDocShell
.ErrorMessage(aTester
.GetMessageId());
1702 // Check if this insertion is allowed with respect to pivot table.
1703 if (!canInsertCellsByPivot(rRange
, aMark
, eCmd
, pDoc
))
1706 rDocShell
.ErrorMessage(STR_NO_INSERT_DELETE_OVER_PIVOT_TABLE
);
1710 WaitObject
aWait( rDocShell
.GetActiveDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference
1712 ScDocument
* pRefUndoDoc
= NULL
;
1713 ScRefUndoData
* pUndoData
= NULL
;
1716 pRefUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1717 pRefUndoDoc
->InitUndo( pDoc
, 0, nTabCount
-1, false, false );
1719 // pRefUndoDoc is filled in InsertCol / InsertRow
1721 pUndoData
= new ScRefUndoData( pDoc
);
1723 pDoc
->BeginDrawUndo();
1726 // #i8302 : we unmerge overwhelming ranges, before insertion all the actions are put in the same ListAction
1727 // the patch comes from mloiseleur and maoyg
1728 bool bInsertMerge
= false;
1729 std::vector
<ScRange
> qIncreaseRange
;
1730 OUString aUndo
= ScGlobal::GetRscString( STR_UNDO_INSERTCELLS
);
1732 rDocShell
.GetUndoManager()->EnterListAction( aUndo
, aUndo
);
1734 itr
= aMark
.begin();
1735 for (; itr
!= itrEnd
&& nTabCount
; ++itr
)
1738 if( pDoc
->HasAttrib( nMergeTestStartCol
, nMergeTestStartRow
, i
, nMergeTestEndCol
, nMergeTestEndRow
, i
, HASATTR_MERGED
| HASATTR_OVERLAPPED
) )
1740 if (eCmd
==INS_CELLSRIGHT
)
1741 bNeedRefresh
= true;
1743 SCCOL nMergeStartCol
= nMergeTestStartCol
;
1744 SCROW nMergeStartRow
= nMergeTestStartRow
;
1745 SCCOL nMergeEndCol
= nMergeTestEndCol
;
1746 SCROW nMergeEndRow
= nMergeTestEndRow
;
1748 pDoc
->ExtendMerge( nMergeStartCol
, nMergeStartRow
, nMergeEndCol
, nMergeEndRow
, i
);
1749 pDoc
->ExtendOverlapped( nMergeStartCol
, nMergeStartRow
, nMergeEndCol
, nMergeEndRow
, i
);
1751 if(( eCmd
== INS_CELLSDOWN
&& ( nMergeStartCol
!= nMergeTestStartCol
|| nMergeEndCol
!= nMergeTestEndCol
)) ||
1752 (eCmd
== INS_CELLSRIGHT
&& ( nMergeStartRow
!= nMergeTestStartRow
|| nMergeEndRow
!= nMergeTestEndRow
)) )
1755 rDocShell
.ErrorMessage(STR_MSSG_INSERTCELLS_0
);
1756 rDocShell
.GetUndoManager()->LeaveListAction();
1761 SCCOL nTestCol
= -1;
1762 SCROW nTestRow1
= -1;
1763 SCROW nTestRow2
= -1;
1765 ScDocAttrIterator
aTestIter( pDoc
, i
, nMergeTestStartCol
, nMergeTestStartRow
, nMergeTestEndCol
, nMergeTestEndRow
);
1766 ScRange
aExtendRange( nMergeTestStartCol
, nMergeTestStartRow
, i
, nMergeTestEndCol
, nMergeTestEndRow
, i
);
1767 const ScPatternAttr
* pPattern
= NULL
;
1768 const ScMergeAttr
* pMergeFlag
= NULL
;
1769 const ScMergeFlagAttr
* pMergeFlagAttr
= NULL
;
1770 while ( ( pPattern
= aTestIter
.GetNext( nTestCol
, nTestRow1
, nTestRow2
) ) != NULL
)
1772 pMergeFlag
= (const ScMergeAttr
*) &pPattern
->GetItem(ATTR_MERGE
);
1773 pMergeFlagAttr
= (const ScMergeFlagAttr
*) &pPattern
->GetItem(ATTR_MERGE_FLAG
);
1774 sal_Int16 nNewFlags
= pMergeFlagAttr
->GetValue() & ( SC_MF_HOR
| SC_MF_VER
);
1775 if( ( pMergeFlag
&& pMergeFlag
->IsMerged() ) || nNewFlags
== SC_MF_HOR
|| nNewFlags
== SC_MF_VER
)
1777 ScRange
aRange( nTestCol
, nTestRow1
, i
);
1778 pDoc
->ExtendOverlapped(aRange
);
1779 pDoc
->ExtendMerge(aRange
, true);
1781 if( nTestRow1
< nTestRow2
&& nNewFlags
== SC_MF_HOR
)
1783 for( SCROW nTestRow
= nTestRow1
; nTestRow
<= nTestRow2
; nTestRow
++ )
1785 ScRange
aTestRange( nTestCol
, nTestRow
, i
);
1786 pDoc
->ExtendOverlapped( aTestRange
);
1787 pDoc
->ExtendMerge( aTestRange
, true);
1788 ScRange
aMergeRange( aTestRange
.aStart
.Col(),aTestRange
.aStart
.Row(), i
);
1789 if( !aExtendRange
.In( aMergeRange
) )
1791 qIncreaseRange
.push_back( aTestRange
);
1792 bInsertMerge
= true;
1798 ScRange
aMergeRange( aRange
.aStart
.Col(),aRange
.aStart
.Row(), i
);
1799 if( !aExtendRange
.In( aMergeRange
) )
1801 qIncreaseRange
.push_back( aRange
);
1803 bInsertMerge
= true;
1810 if( eCmd
== INS_INSROWS
|| eCmd
== INS_CELLSDOWN
)
1812 nStartRow
= aExtendMergeRange
.aStart
.Row();
1813 nEndRow
= aExtendMergeRange
.aEnd
.Row();
1815 if( eCmd
== INS_CELLSDOWN
)
1816 nEndCol
= nMergeTestEndCol
;
1823 else if( eCmd
== INS_CELLSRIGHT
|| eCmd
== INS_INSCOLS
)
1826 nStartCol
= aExtendMergeRange
.aStart
.Col();
1827 nEndCol
= aExtendMergeRange
.aEnd
.Col();
1828 if( eCmd
== INS_CELLSRIGHT
)
1830 nEndRow
= nMergeTestEndRow
;
1839 if( !qIncreaseRange
.empty() )
1841 for( ::std::vector
<ScRange
>::const_iterator
iIter( qIncreaseRange
.begin()); iIter
!= qIncreaseRange
.end(); ++iIter
)
1843 ScRange
aRange( *iIter
);
1844 if( pDoc
->HasAttrib( aRange
, HASATTR_OVERLAPPED
| HASATTR_MERGED
) )
1846 UnmergeCells( aRange
, true );
1854 rDocShell
.ErrorMessage(STR_MSSG_INSERTCELLS_0
);
1855 rDocShell
.GetUndoManager()->LeaveListAction();
1865 bSuccess
= pDoc
->InsertRow( nStartCol
, 0, nEndCol
, MAXTAB
, nStartRow
, static_cast<SCSIZE
>(nEndRow
-nStartRow
+1), pRefUndoDoc
, &aFullMark
);
1866 nPaintEndRow
= MAXROW
;
1869 bSuccess
= pDoc
->InsertRow( 0, 0, MAXCOL
, MAXTAB
, nStartRow
, static_cast<SCSIZE
>(nEndRow
-nStartRow
+1), pRefUndoDoc
, &aFullMark
);
1871 nPaintEndCol
= MAXCOL
;
1872 nPaintEndRow
= MAXROW
;
1873 nPaintFlags
|= PAINT_LEFT
;
1875 case INS_CELLSRIGHT
:
1876 bSuccess
= pDoc
->InsertCol( nStartRow
, 0, nEndRow
, MAXTAB
, nStartCol
, static_cast<SCSIZE
>(nEndCol
-nStartCol
+1), pRefUndoDoc
, &aFullMark
);
1877 nPaintEndCol
= MAXCOL
;
1880 bSuccess
= pDoc
->InsertCol( 0, 0, MAXROW
, MAXTAB
, nStartCol
, static_cast<SCSIZE
>(nEndCol
-nStartCol
+1), pRefUndoDoc
, &aFullMark
);
1882 nPaintEndRow
= MAXROW
;
1883 nPaintEndCol
= MAXCOL
;
1884 nPaintFlags
|= PAINT_TOP
;
1887 OSL_FAIL("Falscher Code beim Einfuegen");
1894 SCTAB
* pTabs
= NULL
;
1895 SCTAB
* pScenarios
= NULL
;
1900 pTabs
= new SCTAB
[nSelCount
];
1901 pScenarios
= new SCTAB
[nSelCount
];
1903 itr
= aMark
.begin();
1904 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
1907 for( SCTAB j
=*itr
+1; j
<nTabCount
&& pDoc
->IsScenario(j
); j
++ )
1910 pScenarios
[nUndoPos
] = nCount
;
1911 pTabs
[nUndoPos
] = *itr
;
1917 rDocShell
.GetUndoManager()->LeaveListAction();
1920 rDocShell
.GetUndoManager()->AddUndoAction( new ScUndoInsertCells(
1921 &rDocShell
, ScRange( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
),
1922 nUndoPos
, pTabs
, pScenarios
, eCmd
, pRefUndoDoc
, pUndoData
, bPartOfPaste
) );
1925 // #i8302 : we remerge growing ranges, with the new part inserted
1927 while( !qIncreaseRange
.empty() )
1929 ScRange aRange
= qIncreaseRange
.back();
1930 if( !pDoc
->HasAttrib( aRange
, HASATTR_OVERLAPPED
| HASATTR_MERGED
) )
1936 aRange
.aEnd
.IncRow(static_cast<SCsCOL
>(nEndRow
-nStartRow
+1));
1938 case INS_CELLSRIGHT
:
1940 aRange
.aEnd
.IncCol(static_cast<SCsCOL
>(nEndCol
-nStartCol
+1));
1945 ScCellMergeOption
aMergeOption(
1946 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
1947 aRange
.aEnd
.Col(), aRange
.aEnd
.Row() );
1948 aMergeOption
.maTabs
.insert(aRange
.aStart
.Tab());
1949 MergeCells(aMergeOption
, false, true, true);
1951 qIncreaseRange
.pop_back();
1955 rDocShell
.GetUndoManager()->LeaveListAction();
1957 itr
= aMark
.begin();
1958 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
1961 pDoc
->SetDrawPageSize(i
);
1964 pDoc
->ExtendMerge( nMergeTestStartCol
, nMergeTestStartRow
, nMergeTestEndCol
, nMergeTestEndRow
, i
, true );
1966 pDoc
->RefreshAutoFilter( nMergeTestStartCol
, nMergeTestStartRow
, nMergeTestEndCol
, nMergeTestEndRow
, i
);
1968 if ( eCmd
== INS_INSROWS
|| eCmd
== INS_INSCOLS
)
1969 pDoc
->UpdatePageBreaks( i
);
1971 sal_uInt16 nExtFlags
= 0;
1972 rDocShell
.UpdatePaintExt( nExtFlags
, nPaintStartCol
, nPaintStartRow
, i
, nPaintEndCol
, nPaintEndRow
, i
);
1974 SCTAB nScenarioCount
= 0;
1976 for( SCTAB j
= i
+1; j
<nTabCount
&& pDoc
->IsScenario(j
); j
++ )
1979 bool bAdjusted
= ( eCmd
== INS_INSROWS
) ? AdjustRowHeight(ScRange(0, nStartRow
, i
, MAXCOL
, nEndRow
, i
+nScenarioCount
)) :
1980 AdjustRowHeight(ScRange(0, nPaintStartRow
, i
, MAXCOL
, nPaintEndRow
, i
+nScenarioCount
));
1983 // paint only what is not done by AdjustRowHeight
1984 if (nPaintFlags
& PAINT_TOP
)
1985 rDocShell
.PostPaint( nPaintStartCol
, nPaintStartRow
, i
, nPaintEndCol
, nPaintEndRow
, i
+nScenarioCount
, PAINT_TOP
);
1988 rDocShell
.PostPaint( nPaintStartCol
, nPaintStartRow
, i
, nPaintEndCol
, nPaintEndRow
, i
+nScenarioCount
, nPaintFlags
, nExtFlags
);
1995 while( !qIncreaseRange
.empty() )
1997 ScRange aRange
= qIncreaseRange
.back();
1998 ScCellMergeOption
aMergeOption(
1999 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
2000 aRange
.aEnd
.Col(), aRange
.aEnd
.Row() );
2001 MergeCells(aMergeOption
, false, true, true);
2002 qIncreaseRange
.pop_back();
2007 pViewSh
->MarkRange( rRange
, false );
2008 pViewSh
->SetCursor( nCursorCol
, nCursorRow
);
2012 rDocShell
.GetUndoManager()->LeaveListAction();
2013 rDocShell
.GetUndoManager()->RemoveLastUndoAction();
2018 rDocShell
.ErrorMessage(STR_INSERT_FULL
); // Spalte/Zeile voll
2021 aModificator
.SetDocumentModified();
2023 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED
) );
2027 bool ScDocFunc::DeleteCells( const ScRange
& rRange
, const ScMarkData
* pTabMark
, DelCellCmd eCmd
,
2028 bool bRecord
, bool bApi
)
2030 ScDocShellModificator
aModificator( rDocShell
);
2032 SCCOL nStartCol
= rRange
.aStart
.Col();
2033 SCROW nStartRow
= rRange
.aStart
.Row();
2034 SCTAB nStartTab
= rRange
.aStart
.Tab();
2035 SCCOL nEndCol
= rRange
.aEnd
.Col();
2036 SCROW nEndRow
= rRange
.aEnd
.Row();
2037 SCTAB nEndTab
= rRange
.aEnd
.Tab();
2039 if ( !ValidRow(nStartRow
) || !ValidRow(nEndRow
) )
2041 OSL_FAIL("invalid row in DeleteCells");
2045 ScDocument
* pDoc
= rDocShell
.GetDocument();
2046 SCTAB nTabCount
= pDoc
->GetTableCount();
2047 SCCOL nPaintStartCol
= nStartCol
;
2048 SCROW nPaintStartRow
= nStartRow
;
2049 SCCOL nPaintEndCol
= nEndCol
;
2050 SCROW nPaintEndRow
= nEndRow
;
2051 sal_uInt16 nPaintFlags
= PAINT_GRID
;
2053 if (bRecord
&& !pDoc
->IsUndoEnabled())
2062 for(SCTAB i
=0; i
<nTabCount
; i
++ )
2064 if( !pDoc
->IsScenario(i
) )
2067 if( nCount
== nEndTab
+1 )
2069 aMark
.SelectTable(i
, true);
2076 ScMarkData
aFullMark( aMark
); // including scenario sheets
2077 ScMarkData::iterator itr
= aMark
.begin(), itrEnd
= aMark
.end();
2078 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
2079 for( SCTAB j
= *itr
+1; j
<nTabCount
&& pDoc
->IsScenario(j
); j
++ )
2080 aFullMark
.SelectTable( j
, true );
2082 SCTAB nSelCount
= aMark
.GetSelectCount();
2084 SCCOL nUndoStartCol
= nStartCol
;
2085 SCROW nUndoStartRow
= nStartRow
;
2086 SCCOL nUndoEndCol
= nEndCol
;
2087 SCROW nUndoEndRow
= nEndRow
;
2089 ScRange
aExtendMergeRange( rRange
);
2091 if( rRange
.aStart
== rRange
.aEnd
&& pDoc
->HasAttrib(rRange
, HASATTR_MERGED
) )
2093 pDoc
->ExtendMerge( aExtendMergeRange
);
2094 pDoc
->ExtendOverlapped( aExtendMergeRange
);
2095 nUndoEndCol
= aExtendMergeRange
.aEnd
.Col();
2096 nUndoEndRow
= aExtendMergeRange
.aEnd
.Row();
2097 nPaintEndCol
= nUndoEndCol
;
2098 nPaintEndRow
= nUndoEndRow
;
2101 if (eCmd
==DEL_DELROWS
)
2104 nUndoEndCol
= MAXCOL
;
2106 if (eCmd
==DEL_DELCOLS
)
2109 nUndoEndRow
= MAXROW
;
2113 SCCOL nEditTestEndX
= nUndoEndCol
;
2114 if ( eCmd
==DEL_DELCOLS
|| eCmd
==DEL_CELLSLEFT
)
2115 nEditTestEndX
= MAXCOL
;
2116 SCROW nEditTestEndY
= nUndoEndRow
;
2117 if ( eCmd
==DEL_DELROWS
|| eCmd
==DEL_CELLSUP
)
2118 nEditTestEndY
= MAXROW
;
2119 ScEditableTester
aTester( pDoc
, nUndoStartCol
, nUndoStartRow
, nEditTestEndX
, nEditTestEndY
, aMark
);
2120 if (!aTester
.IsEditable())
2123 rDocShell
.ErrorMessage(aTester
.GetMessageId());
2127 if (!canDeleteCellsByPivot(rRange
, aMark
, eCmd
, pDoc
))
2130 rDocShell
.ErrorMessage(STR_NO_INSERT_DELETE_OVER_PIVOT_TABLE
);
2133 // Test zusammengefasste
2135 SCCOL nMergeTestEndCol
= (eCmd
==DEL_CELLSLEFT
) ? MAXCOL
: nUndoEndCol
;
2136 SCROW nMergeTestEndRow
= (eCmd
==DEL_CELLSUP
) ? MAXROW
: nUndoEndRow
;
2137 SCCOL nExtendStartCol
= nUndoStartCol
;
2138 SCROW nExtendStartRow
= nUndoStartRow
;
2139 bool bNeedRefresh
= false;
2141 //Issue 8302 want to be able to insert into the middle of merged cells
2142 //the patch comes from maoyg
2143 ::std::vector
<ScRange
> qDecreaseRange
;
2144 bool bDeletingMerge
= false;
2145 OUString aUndo
= ScGlobal::GetRscString( STR_UNDO_DELETECELLS
);
2147 rDocShell
.GetUndoManager()->EnterListAction( aUndo
, aUndo
);
2149 itr
= aMark
.begin();
2150 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
2153 if ( pDoc
->HasAttrib( nUndoStartCol
, nUndoStartRow
, i
, nMergeTestEndCol
, nMergeTestEndRow
, i
, HASATTR_MERGED
| HASATTR_OVERLAPPED
))
2155 SCCOL nMergeStartCol
= nUndoStartCol
;
2156 SCROW nMergeStartRow
= nUndoStartRow
;
2157 SCCOL nMergeEndCol
= nMergeTestEndCol
;
2158 SCROW nMergeEndRow
= nMergeTestEndRow
;
2160 pDoc
->ExtendMerge( nMergeStartCol
, nMergeStartRow
, nMergeEndCol
, nMergeEndRow
, i
);
2161 pDoc
->ExtendOverlapped( nMergeStartCol
, nMergeStartRow
, nMergeEndCol
, nMergeEndRow
, i
);
2162 if( ( eCmd
== DEL_CELLSUP
&& ( nMergeStartCol
!= nUndoStartCol
|| nMergeEndCol
!= nMergeTestEndCol
))||
2163 ( eCmd
== DEL_CELLSLEFT
&& ( nMergeStartRow
!= nUndoStartRow
|| nMergeEndRow
!= nMergeTestEndRow
)))
2166 rDocShell
.ErrorMessage(STR_MSSG_DELETECELLS_0
);
2167 rDocShell
.GetUndoManager()->LeaveListAction();
2171 nExtendStartCol
= nMergeStartCol
;
2172 nExtendStartRow
= nMergeStartRow
;
2173 SCCOL nTestCol
= -1;
2174 SCROW nTestRow1
= -1;
2175 SCROW nTestRow2
= -1;
2177 ScDocAttrIterator
aTestIter( pDoc
, i
, nUndoStartCol
, nUndoStartRow
, nMergeTestEndCol
, nMergeTestEndRow
);
2178 ScRange
aExtendRange( nUndoStartCol
, nUndoStartRow
, i
, nMergeTestEndCol
, nMergeTestEndRow
, i
);
2179 const ScPatternAttr
* pPattern
= NULL
;
2180 const ScMergeAttr
* pMergeFlag
= NULL
;
2181 const ScMergeFlagAttr
* pMergeFlagAttr
= NULL
;
2182 while ( ( pPattern
= aTestIter
.GetNext( nTestCol
, nTestRow1
, nTestRow2
) ) != NULL
)
2184 pMergeFlag
= (const ScMergeAttr
*) &pPattern
->GetItem( ATTR_MERGE
);
2185 pMergeFlagAttr
= (const ScMergeFlagAttr
*) &pPattern
->GetItem( ATTR_MERGE_FLAG
);
2186 sal_Int16 nNewFlags
= pMergeFlagAttr
->GetValue() & ( SC_MF_HOR
| SC_MF_VER
);
2187 if( ( pMergeFlag
&& pMergeFlag
->IsMerged() ) || nNewFlags
== SC_MF_HOR
|| nNewFlags
== SC_MF_VER
)
2189 ScRange
aRange( nTestCol
, nTestRow1
, i
);
2190 pDoc
->ExtendOverlapped( aRange
);
2191 pDoc
->ExtendMerge( aRange
, true );
2193 if( nTestRow1
< nTestRow2
&& nNewFlags
== SC_MF_HOR
)
2195 for( SCROW nTestRow
= nTestRow1
; nTestRow
<= nTestRow2
; nTestRow
++ )
2197 ScRange
aTestRange( nTestCol
, nTestRow
, i
);
2198 pDoc
->ExtendOverlapped( aTestRange
);
2199 pDoc
->ExtendMerge( aTestRange
, true );
2200 ScRange
aMergeRange( aTestRange
.aStart
.Col(),aTestRange
.aStart
.Row(), i
);
2201 if( !aExtendRange
.In( aMergeRange
) )
2203 qDecreaseRange
.push_back( aTestRange
);
2204 bDeletingMerge
= true;
2210 ScRange
aMergeRange( aRange
.aStart
.Col(),aRange
.aStart
.Row(), i
);
2211 if( !aExtendRange
.In( aMergeRange
) )
2213 qDecreaseRange
.push_back( aRange
);
2215 bDeletingMerge
= true;
2220 if( bDeletingMerge
)
2223 if( eCmd
== DEL_DELROWS
|| eCmd
== DEL_CELLSUP
)
2225 nStartRow
= aExtendMergeRange
.aStart
.Row();
2226 nEndRow
= aExtendMergeRange
.aEnd
.Row();
2227 bNeedRefresh
= true;
2229 if( eCmd
== DEL_CELLSUP
)
2231 nEndCol
= aExtendMergeRange
.aEnd
.Col();
2239 else if( eCmd
== DEL_CELLSLEFT
|| eCmd
== DEL_DELCOLS
)
2242 nStartCol
= aExtendMergeRange
.aStart
.Col();
2243 nEndCol
= aExtendMergeRange
.aEnd
.Col();
2244 if( eCmd
== DEL_CELLSLEFT
)
2246 nEndRow
= aExtendMergeRange
.aEnd
.Row();
2247 bNeedRefresh
= true;
2256 if( !qDecreaseRange
.empty() )
2258 for( ::std::vector
<ScRange
>::const_iterator
iIter( qDecreaseRange
.begin()); iIter
!= qDecreaseRange
.end(); ++iIter
)
2260 ScRange
aRange( *iIter
);
2261 if( pDoc
->HasAttrib( aRange
, HASATTR_OVERLAPPED
| HASATTR_MERGED
) )
2263 UnmergeCells( aRange
, true );
2271 rDocShell
.ErrorMessage(STR_MSSG_DELETECELLS_0
);
2272 rDocShell
.GetUndoManager()->LeaveListAction();
2282 WaitObject
aWait( rDocShell
.GetActiveDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference
2284 ScDocument
* pUndoDoc
= NULL
;
2285 ScDocument
* pRefUndoDoc
= NULL
;
2286 ScRefUndoData
* pUndoData
= NULL
;
2289 // With the fix for #101329#, UpdateRef always puts cells into pRefUndoDoc at their old position,
2290 // so it's no longer necessary to copy more than the deleted range into pUndoDoc.
2292 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
2293 pUndoDoc
->InitUndo( pDoc
, 0, nTabCount
-1, (eCmd
==DEL_DELCOLS
), (eCmd
==DEL_DELROWS
) );
2294 itr
= aMark
.begin();
2295 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
2297 SCTAB nScenarioCount
= 0;
2299 for( SCTAB j
= *itr
+1; j
<nTabCount
&& pDoc
->IsScenario(j
); j
++ )
2302 pDoc
->CopyToDocument( nUndoStartCol
, nUndoStartRow
, *itr
, nUndoEndCol
, nUndoEndRow
, *itr
+nScenarioCount
,
2303 IDF_ALL
| IDF_NOCAPTIONS
, false, pUndoDoc
);
2306 pRefUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
2307 pRefUndoDoc
->InitUndo( pDoc
, 0, nTabCount
-1, false, false );
2309 pUndoData
= new ScRefUndoData( pDoc
);
2311 pDoc
->BeginDrawUndo();
2314 sal_uInt16 nExtFlags
= 0;
2315 itr
= aMark
.begin();
2316 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
2318 rDocShell
.UpdatePaintExt( nExtFlags
, nStartCol
, nStartRow
, *itr
, nEndCol
, nEndRow
, *itr
);
2321 bool bUndoOutline
= false;
2325 pDoc
->DeleteRow( nStartCol
, 0, nEndCol
, MAXTAB
, nStartRow
, static_cast<SCSIZE
>(nEndRow
-nStartRow
+1), pRefUndoDoc
, NULL
, &aFullMark
);
2326 nPaintEndRow
= MAXROW
;
2329 pDoc
->DeleteRow( 0, 0, MAXCOL
, MAXTAB
, nStartRow
, static_cast<SCSIZE
>(nEndRow
-nStartRow
+1), pRefUndoDoc
, &bUndoOutline
, &aFullMark
);
2331 nPaintEndCol
= MAXCOL
;
2332 nPaintEndRow
= MAXROW
;
2333 nPaintFlags
|= PAINT_LEFT
;
2336 pDoc
->DeleteCol( nStartRow
, 0, nEndRow
, MAXTAB
, nStartCol
, static_cast<SCSIZE
>(nEndCol
-nStartCol
+1), pRefUndoDoc
, NULL
, &aFullMark
);
2337 nPaintEndCol
= MAXCOL
;
2340 pDoc
->DeleteCol( 0, 0, MAXROW
, MAXTAB
, nStartCol
, static_cast<SCSIZE
>(nEndCol
-nStartCol
+1), pRefUndoDoc
, &bUndoOutline
, &aFullMark
);
2342 nPaintEndRow
= MAXROW
;
2343 nPaintEndCol
= MAXCOL
;
2344 nPaintFlags
|= PAINT_TOP
;
2347 OSL_FAIL("Falscher Code beim Loeschen");
2351 //! Test, ob Outline in Groesse geaendert
2355 itr
= aFullMark
.begin(), itrEnd
= aFullMark
.end();
2356 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
2357 pRefUndoDoc
->DeleteAreaTab(nUndoStartCol
,nUndoStartRow
,nUndoEndCol
,nUndoEndRow
, *itr
, IDF_ALL
);
2359 // alle Tabellen anlegen, damit Formeln kopiert werden koennen:
2360 pUndoDoc
->AddUndoTab( 0, nTabCount
-1, false, false );
2362 // kopieren mit bColRowFlags=false (#54194#)
2363 pRefUndoDoc
->CopyToDocument(0,0,0,MAXCOL
,MAXROW
,MAXTAB
,IDF_FORMULA
,false,pUndoDoc
,NULL
,false);
2366 SCTAB
* pTabs
= new SCTAB
[nSelCount
];
2367 SCTAB
* pScenarios
= new SCTAB
[nSelCount
];
2370 itr
= aMark
.begin(), itrEnd
= aMark
.end();
2371 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
2374 for( SCTAB j
=*itr
+1; j
<nTabCount
&& pDoc
->IsScenario(j
); j
++ )
2377 pScenarios
[nUndoPos
] = nCount
;
2378 pTabs
[nUndoPos
] = *itr
;
2382 if( !bDeletingMerge
)
2384 rDocShell
.GetUndoManager()->LeaveListAction();
2387 rDocShell
.GetUndoManager()->AddUndoAction( new ScUndoDeleteCells(
2388 &rDocShell
, ScRange( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
),nUndoPos
, pTabs
, pScenarios
,
2389 eCmd
, pUndoDoc
, pUndoData
) );
2392 // #i8302 want to be able to insert into the middle of merged cells
2393 // the patch comes from maoyg
2395 while( !qDecreaseRange
.empty() )
2397 ScRange aRange
= qDecreaseRange
.back();
2399 long nDecreaseRowCount
= 0;
2400 long nDecreaseColCount
= 0;
2401 if( eCmd
== DEL_CELLSUP
|| eCmd
== DEL_DELROWS
)
2403 if( nStartRow
>= aRange
.aStart
.Row() && nStartRow
<= aRange
.aEnd
.Row() && nEndRow
>= aRange
.aStart
.Row() && nEndRow
<= aRange
.aEnd
.Row() )
2404 nDecreaseRowCount
= nEndRow
-nStartRow
+1;
2405 else if( nStartRow
>= aRange
.aStart
.Row() && nStartRow
<= aRange
.aEnd
.Row() && nEndRow
>= aRange
.aStart
.Row() && nEndRow
>= aRange
.aEnd
.Row() )
2406 nDecreaseRowCount
= aRange
.aEnd
.Row()-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()-nEndRow
+1;
2410 else if( eCmd
== DEL_CELLSLEFT
|| eCmd
== DEL_DELCOLS
)
2412 if( nStartCol
>= aRange
.aStart
.Col() && nStartCol
<= aRange
.aEnd
.Col() && nEndCol
>= aRange
.aStart
.Col() && nEndCol
<= aRange
.aEnd
.Col() )
2413 nDecreaseColCount
= nEndCol
-nStartCol
+1;
2414 else if( nStartCol
>= aRange
.aStart
.Col() && nStartCol
<= aRange
.aEnd
.Col() && nEndCol
>= aRange
.aStart
.Col() && nEndCol
>= aRange
.aEnd
.Col() )
2415 nDecreaseColCount
= aRange
.aEnd
.Col()-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()-nEndCol
+1;
2424 aRange
.aEnd
.SetRow(static_cast<SCsCOL
>( aRange
.aEnd
.Row()-nDecreaseRowCount
));
2428 aRange
.aEnd
.SetCol(static_cast<SCsCOL
>( aRange
.aEnd
.Col()-nDecreaseColCount
));
2434 if( !pDoc
->HasAttrib( aRange
, HASATTR_OVERLAPPED
| HASATTR_MERGED
) )
2436 ScCellMergeOption
aMergeOption(aRange
);
2437 MergeCells( aMergeOption
, false, true, true );
2439 qDecreaseRange
.pop_back();
2442 if( bDeletingMerge
)
2443 rDocShell
.GetUndoManager()->LeaveListAction();
2447 // #i51445# old merge flag attributes must be deleted also for single cells,
2448 // not only for whole columns/rows
2450 if ( eCmd
==DEL_DELCOLS
|| eCmd
==DEL_CELLSLEFT
)
2451 nMergeTestEndCol
= MAXCOL
;
2452 if ( eCmd
==DEL_DELROWS
|| eCmd
==DEL_CELLSUP
)
2453 nMergeTestEndRow
= MAXROW
;
2454 ScPatternAttr
aPattern( pDoc
->GetPool() );
2455 aPattern
.GetItemSet().Put( ScMergeFlagAttr() );
2457 pDoc
->ApplyPatternArea( nExtendStartCol
, nExtendStartRow
, nMergeTestEndCol
, nMergeTestEndRow
, aMark
, aPattern
);
2459 itr
= aMark
.begin(), itrEnd
= aMark
.end();
2460 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
2462 SCTAB nScenarioCount
= 0;
2464 for( SCTAB j
= *itr
+1; j
<nTabCount
&& pDoc
->IsScenario(j
); j
++ )
2467 ScRange
aMergedRange( nExtendStartCol
, nExtendStartRow
, *itr
, nMergeTestEndCol
, nMergeTestEndRow
, *itr
+nScenarioCount
);
2468 pDoc
->ExtendMerge( aMergedRange
, true );
2472 itr
= aMark
.begin(), itrEnd
= aMark
.end();
2473 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
2475 pDoc
->SetDrawPageSize(*itr
);
2477 if ( eCmd
== DEL_DELCOLS
|| eCmd
== DEL_DELROWS
)
2478 pDoc
->UpdatePageBreaks( *itr
);
2480 rDocShell
.UpdatePaintExt( nExtFlags
, nPaintStartCol
, nPaintStartRow
, *itr
, nPaintEndCol
, nPaintEndRow
, *itr
);
2482 SCTAB nScenarioCount
= 0;
2484 for( SCTAB j
= *itr
+1; j
<nTabCount
&& pDoc
->IsScenario(j
); j
++ )
2487 // ganze Zeilen loeschen: nichts anpassen
2488 if ( eCmd
== DEL_DELROWS
|| !AdjustRowHeight(ScRange( 0, nPaintStartRow
, *itr
, MAXCOL
, nPaintEndRow
, *itr
+nScenarioCount
)) )
2489 rDocShell
.PostPaint( nPaintStartCol
, nPaintStartRow
, *itr
, nPaintEndCol
, nPaintEndRow
, *itr
+nScenarioCount
, nPaintFlags
, nExtFlags
);
2492 // paint only what is not done by AdjustRowHeight
2493 if (nExtFlags
& SC_PF_LINES
)
2494 lcl_PaintAbove( rDocShell
, ScRange( nPaintStartCol
, nPaintStartRow
, *itr
, nPaintEndCol
, nPaintEndRow
, *itr
+nScenarioCount
) );
2495 if (nPaintFlags
& PAINT_TOP
)
2496 rDocShell
.PostPaint( nPaintStartCol
, nPaintStartRow
, *itr
, nPaintEndCol
, nPaintEndRow
, *itr
+nScenarioCount
, PAINT_TOP
);
2500 aModificator
.SetDocumentModified();
2502 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED
) );
2507 bool ScDocFunc::MoveBlock( const ScRange
& rSource
, const ScAddress
& rDestPos
,
2508 bool bCut
, bool bRecord
, bool bPaint
, bool bApi
)
2510 ScDocShellModificator
aModificator( rDocShell
);
2512 SCCOL nStartCol
= rSource
.aStart
.Col();
2513 SCROW nStartRow
= rSource
.aStart
.Row();
2514 SCTAB nStartTab
= rSource
.aStart
.Tab();
2515 SCCOL nEndCol
= rSource
.aEnd
.Col();
2516 SCROW nEndRow
= rSource
.aEnd
.Row();
2517 SCTAB nEndTab
= rSource
.aEnd
.Tab();
2518 SCCOL nDestCol
= rDestPos
.Col();
2519 SCROW nDestRow
= rDestPos
.Row();
2520 SCTAB nDestTab
= rDestPos
.Tab();
2522 if ( !ValidRow(nStartRow
) || !ValidRow(nEndRow
) || !ValidRow(nDestRow
) )
2524 OSL_FAIL("invalid row in MoveBlock");
2528 // zugehoerige Szenarien auch anpassen - nur wenn innerhalb einer Tabelle verschoben wird!
2529 bool bScenariosAdded
= false;
2530 ScDocument
* pDoc
= rDocShell
.GetDocument();
2531 if (bRecord
&& !pDoc
->IsUndoEnabled())
2534 SCTAB nTabCount
= pDoc
->GetTableCount();
2535 if ( nDestTab
== nStartTab
&& !pDoc
->IsScenario(nEndTab
) )
2536 while ( nEndTab
+1 < nTabCount
&& pDoc
->IsScenario(nEndTab
+1) )
2539 bScenariosAdded
= true;
2542 SCTAB nSrcTabCount
= nEndTab
-nStartTab
+1;
2543 SCTAB nDestEndTab
= nDestTab
+nSrcTabCount
-1;
2546 ScDocument
* pClipDoc
= new ScDocument( SCDOCMODE_CLIP
);
2548 ScMarkData aSourceMark
;
2549 for (nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
2550 aSourceMark
.SelectTable( nTab
, true ); // Source selektieren
2551 aSourceMark
.SetMarkArea( rSource
);
2553 ScDocShellRef aDragShellRef
;
2554 if ( pDoc
->HasOLEObjectsInArea( rSource
) )
2556 aDragShellRef
= new ScDocShell
; // DocShell needs a Ref immediately
2557 aDragShellRef
->DoInitNew(NULL
);
2559 ScDrawLayer::SetGlobalDrawPersist(aDragShellRef
);
2561 ScClipParam
aClipParam(ScRange(nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nStartTab
), bCut
);
2562 pDoc
->CopyToClip(aClipParam
, pClipDoc
, &aSourceMark
, false, bScenariosAdded
, true);
2564 ScDrawLayer::SetGlobalDrawPersist(NULL
);
2566 SCCOL nOldEndCol
= nEndCol
;
2567 SCROW nOldEndRow
= nEndRow
;
2568 bool bClipOver
= false;
2569 for (nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
2571 SCCOL nTmpEndCol
= nOldEndCol
;
2572 SCROW nTmpEndRow
= nOldEndRow
;
2573 if (pDoc
->ExtendMerge( nStartCol
, nStartRow
, nTmpEndCol
, nTmpEndRow
, nTab
))
2575 if ( nTmpEndCol
> nEndCol
) nEndCol
= nTmpEndCol
;
2576 if ( nTmpEndRow
> nEndRow
) nEndRow
= nTmpEndRow
;
2579 SCCOL nDestEndCol
= nDestCol
+ ( nOldEndCol
-nStartCol
);
2580 SCROW nDestEndRow
= nDestRow
+ ( nOldEndRow
-nStartRow
);
2582 SCCOL nUndoEndCol
= nDestCol
+ ( nEndCol
-nStartCol
); // erweitert im Zielblock
2583 SCROW nUndoEndRow
= nDestRow
+ ( nEndRow
-nStartRow
);
2585 bool bIncludeFiltered
= bCut
;
2586 if ( !bIncludeFiltered
)
2588 // adjust sizes to include only non-filtered rows
2592 pClipDoc
->GetClipArea( nClipX
, nClipY
, false );
2593 SCROW nUndoAdd
= nUndoEndRow
- nDestEndRow
;
2594 nDestEndRow
= nDestRow
+ nClipY
;
2595 nUndoEndRow
= nDestEndRow
+ nUndoAdd
;
2598 if (!ValidCol(nUndoEndCol
) || !ValidRow(nUndoEndRow
))
2601 rDocShell
.ErrorMessage(STR_PASTE_FULL
);
2606 // Test auf Zellschutz
2608 ScEditableTester aTester
;
2609 for (nTab
=nDestTab
; nTab
<=nDestEndTab
; nTab
++)
2610 aTester
.TestBlock( pDoc
, nTab
, nDestCol
,nDestRow
, nUndoEndCol
,nUndoEndRow
);
2612 for (nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
2613 aTester
.TestBlock( pDoc
, nTab
, nStartCol
,nStartRow
, nEndCol
,nEndRow
);
2615 if (!aTester
.IsEditable())
2618 rDocShell
.ErrorMessage(aTester
.GetMessageId());
2623 // Test auf zusammengefasste - beim Verschieben erst nach dem Loeschen
2625 if (bClipOver
&& !bCut
)
2626 if (pDoc
->HasAttrib( nDestCol
,nDestRow
,nDestTab
, nUndoEndCol
,nUndoEndRow
,nDestEndTab
,
2627 HASATTR_MERGED
| HASATTR_OVERLAPPED
))
2628 { // "Zusammenfassen nicht verschachteln !"
2630 rDocShell
.ErrorMessage(STR_MSSG_MOVEBLOCKTO_0
);
2635 // Are there borders in the cells? (for painting)
2637 sal_uInt16 nSourceExt
= 0;
2638 rDocShell
.UpdatePaintExt( nSourceExt
, nStartCol
,nStartRow
,nStartTab
, nEndCol
,nEndRow
,nEndTab
);
2639 sal_uInt16 nDestExt
= 0;
2640 rDocShell
.UpdatePaintExt( nDestExt
, nDestCol
,nDestRow
,nDestTab
, nDestEndCol
,nDestEndRow
,nDestEndTab
);
2646 ScDocument
* pUndoDoc
= NULL
;
2647 ScDocument
* pRefUndoDoc
= NULL
;
2648 ScRefUndoData
* pUndoData
= NULL
;
2651 bool bWholeCols
= ( nStartRow
== 0 && nEndRow
== MAXROW
);
2652 bool bWholeRows
= ( nStartCol
== 0 && nEndCol
== MAXCOL
);
2653 sal_uInt16 nUndoFlags
= (IDF_ALL
& ~IDF_OBJECTS
) | IDF_NOCAPTIONS
;
2655 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
2656 pUndoDoc
->InitUndo( pDoc
, nStartTab
, nEndTab
, bWholeCols
, bWholeRows
);
2660 pDoc
->CopyToDocument( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
,
2661 nUndoFlags
, false, pUndoDoc
);
2662 pRefUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
2663 pRefUndoDoc
->InitUndo( pDoc
, 0, nTabCount
-1, false, false );
2666 if ( nDestTab
!= nStartTab
)
2667 pUndoDoc
->AddUndoTab( nDestTab
, nDestEndTab
, bWholeCols
, bWholeRows
);
2668 pDoc
->CopyToDocument( nDestCol
, nDestRow
, nDestTab
,
2669 nDestEndCol
, nDestEndRow
, nDestEndTab
,
2670 nUndoFlags
, false, pUndoDoc
);
2672 pUndoData
= new ScRefUndoData( pDoc
);
2674 pDoc
->BeginDrawUndo();
2677 bool bSourceHeight
= false; // Hoehen angepasst?
2680 ScMarkData aDelMark
; // only for tables
2681 for (nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
2683 pDoc
->DeleteAreaTab( nStartCol
,nStartRow
, nOldEndCol
,nOldEndRow
, nTab
, IDF_ALL
);
2684 aDelMark
.SelectTable( nTab
, true );
2686 pDoc
->DeleteObjectsInArea( nStartCol
,nStartRow
, nOldEndCol
,nOldEndRow
, aDelMark
);
2688 // Test auf zusammengefasste
2691 if (pDoc
->HasAttrib( nDestCol
,nDestRow
,nDestTab
,
2692 nUndoEndCol
,nUndoEndRow
,nDestEndTab
,
2693 HASATTR_MERGED
| HASATTR_OVERLAPPED
))
2695 pDoc
->CopyFromClip( rSource
, aSourceMark
, IDF_ALL
, pRefUndoDoc
, pClipDoc
);
2696 for (nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
2698 SCCOL nTmpEndCol
= nEndCol
;
2699 SCROW nTmpEndRow
= nEndRow
;
2700 pDoc
->ExtendMerge( nStartCol
, nStartRow
, nTmpEndCol
, nTmpEndRow
, nTab
, true );
2703 // Fehlermeldung erst nach dem Wiederherstellen des Inhalts
2704 if (!bApi
) // "Zusammenfassen nicht verschachteln !"
2705 rDocShell
.ErrorMessage(STR_MSSG_MOVEBLOCKTO_0
);
2714 bSourceHeight
= AdjustRowHeight( rSource
, false );
2717 ScRange
aPasteDest( nDestCol
, nDestRow
, nDestTab
, nDestEndCol
, nDestEndRow
, nDestEndTab
);
2719 ScMarkData aDestMark
;
2720 for (nTab
=nDestTab
; nTab
<=nDestEndTab
; nTab
++)
2721 aDestMark
.SelectTable( nTab
, true ); // Destination selektieren
2722 aDestMark
.SetMarkArea( aPasteDest
);
2724 /* Do not drawing objects here. While pasting, the
2725 function ScDocument::UpdateReference() is called which calls
2726 ScDrawLayer::MoveCells() which may move away inserted objects to wrong
2727 positions (e.g. if source and destination range overlaps).*/
2728 pDoc
->CopyFromClip( aPasteDest
, aDestMark
, IDF_ALL
& ~(IDF_OBJECTS
),
2729 NULL
, pClipDoc
, true, false, bIncludeFiltered
);
2732 // skipped rows and merged cells don't mix
2733 if ( !bIncludeFiltered
&& pClipDoc
->HasClipFilteredRows() )
2734 UnmergeCells( aPasteDest
, false );
2736 VirtualDevice aVirtDev
;
2737 bool bDestHeight
= AdjustRowHeight(
2738 ScRange( 0,nDestRow
,nDestTab
, MAXCOL
,nDestEndRow
,nDestEndTab
),
2741 /* Paste drawing objects after adjusting formula references
2742 and row heights. There are no cell notes or drawing objects, if the
2743 clipdoc does not contain a drawing layer.*/
2744 if ( pClipDoc
->GetDrawLayer() )
2745 pDoc
->CopyFromClip( aPasteDest
, aDestMark
, IDF_OBJECTS
,
2746 pRefUndoDoc
, pClipDoc
, true, false, bIncludeFiltered
);
2752 // alle Tabellen anlegen, damit Formeln kopiert werden koennen:
2753 pUndoDoc
->AddUndoTab( 0, nTabCount
-1, false, false );
2755 pRefUndoDoc
->DeleteArea( nDestCol
, nDestRow
, nDestEndCol
, nDestEndRow
, aSourceMark
, IDF_ALL
);
2756 // kopieren mit bColRowFlags=sal_False (#54194#)
2757 pRefUndoDoc
->CopyToDocument( 0, 0, 0, MAXCOL
, MAXROW
, MAXTAB
,
2758 IDF_FORMULA
, false, pUndoDoc
, NULL
, false );
2762 rDocShell
.GetUndoManager()->AddUndoAction(
2763 new ScUndoDragDrop( &rDocShell
, ScRange(
2764 nStartCol
, nStartRow
, nStartTab
,
2765 nOldEndCol
, nOldEndRow
, nEndTab
),
2766 ScAddress( nDestCol
, nDestRow
, nDestTab
),
2767 bCut
, pUndoDoc
, pUndoData
, bScenariosAdded
) );
2770 SCCOL nDestPaintEndCol
= nDestEndCol
;
2771 SCROW nDestPaintEndRow
= nDestEndRow
;
2772 for (nTab
=nDestTab
; nTab
<=nDestEndTab
; nTab
++)
2774 SCCOL nTmpEndCol
= nDestEndCol
;
2775 SCROW nTmpEndRow
= nDestEndRow
;
2776 pDoc
->ExtendMerge( nDestCol
, nDestRow
, nTmpEndCol
, nTmpEndRow
, nTab
, true );
2777 if (nTmpEndCol
> nDestPaintEndCol
) nDestPaintEndCol
= nTmpEndCol
;
2778 if (nTmpEndRow
> nDestPaintEndRow
) nDestPaintEndRow
= nTmpEndRow
;
2782 for (nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
2783 pDoc
->RefreshAutoFilter( nStartCol
, nStartRow
, nEndCol
, nEndRow
, nTab
);
2789 SCCOL nPaintStartX
= nDestCol
;
2790 SCROW nPaintStartY
= nDestRow
;
2791 SCCOL nPaintEndX
= nDestPaintEndCol
;
2792 SCROW nPaintEndY
= nDestPaintEndRow
;
2793 sal_uInt16 nFlags
= PAINT_GRID
;
2795 if ( nStartRow
==0 && nEndRow
==MAXROW
) // Breiten mitkopiert?
2797 nPaintEndX
= MAXCOL
;
2799 nPaintEndY
= MAXROW
;
2800 nFlags
|= PAINT_TOP
;
2802 if ( bDestHeight
|| ( nStartCol
== 0 && nEndCol
== MAXCOL
) )
2804 nPaintEndY
= MAXROW
;
2806 nPaintEndX
= MAXCOL
;
2807 nFlags
|= PAINT_LEFT
;
2809 if ( bScenariosAdded
)
2813 nPaintEndX
= MAXCOL
;
2814 nPaintEndY
= MAXROW
;
2817 rDocShell
.PostPaint( nPaintStartX
,nPaintStartY
,nDestTab
,
2818 nPaintEndX
,nPaintEndY
,nDestEndTab
, nFlags
, nSourceExt
| nDestExt
);
2824 nPaintStartX
= nStartCol
;
2825 nPaintStartY
= nStartRow
;
2826 nPaintEndX
= nEndCol
;
2827 nPaintEndY
= nEndRow
;
2828 nFlags
= PAINT_GRID
;
2830 if ( bSourceHeight
)
2832 nPaintEndY
= MAXROW
;
2834 nPaintEndX
= MAXCOL
;
2835 nFlags
|= PAINT_LEFT
;
2837 if ( bScenariosAdded
)
2841 nPaintEndX
= MAXCOL
;
2842 nPaintEndY
= MAXROW
;
2845 rDocShell
.PostPaint( nPaintStartX
,nPaintStartY
,nStartTab
,
2846 nPaintEndX
,nPaintEndY
,nEndTab
, nFlags
, nSourceExt
);
2850 aModificator
.SetDocumentModified();
2852 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED
) );
2859 uno::Reference
< uno::XInterface
> GetDocModuleObject( SfxObjectShell
& rDocSh
, OUString
& sCodeName
)
2861 uno::Reference
< lang::XMultiServiceFactory
> xSF(rDocSh
.GetModel(), uno::UNO_QUERY
);
2862 uno::Reference
< container::XNameAccess
> xVBACodeNamedObjectAccess
;
2863 uno::Reference
< uno::XInterface
> xDocModuleApiObject
;
2866 xVBACodeNamedObjectAccess
.set( xSF
->createInstance("ooo.vba.VBAObjectModuleObjectProvider"), uno::UNO_QUERY
);
2867 xDocModuleApiObject
.set( xVBACodeNamedObjectAccess
->getByName( sCodeName
), uno::UNO_QUERY
);
2869 return xDocModuleApiObject
;
2873 static script::ModuleInfo
lcl_InitModuleInfo( SfxObjectShell
& rDocSh
, OUString
& sModule
)
2875 script::ModuleInfo sModuleInfo
;
2876 sModuleInfo
.ModuleType
= script::ModuleType::DOCUMENT
;
2877 sModuleInfo
.ModuleObject
= GetDocModuleObject( rDocSh
, sModule
);
2881 void VBA_InsertModule( ScDocument
& rDoc
, SCTAB nTab
, const OUString
& sModuleName
, const OUString
& sSource
)
2883 SfxObjectShell
& rDocSh
= *rDoc
.GetDocumentShell();
2884 uno::Reference
< script::XLibraryContainer
> xLibContainer
= rDocSh
.GetBasicContainer();
2885 OSL_ENSURE( xLibContainer
.is(), "No BasicContainer!" );
2887 uno::Reference
< container::XNameContainer
> xLib
;
2888 if( xLibContainer
.is() )
2890 OUString
aLibName( "Standard" );
2891 if ( rDocSh
.GetBasicManager() && !rDocSh
.GetBasicManager()->GetName().isEmpty() )
2893 aLibName
= rDocSh
.GetBasicManager()->GetName();
2895 uno::Any aLibAny
= xLibContainer
->getByName( aLibName
);
2900 // if the Module with codename exists then find a new name
2902 OUString genModuleName
;
2903 if ( !sModuleName
.isEmpty() )
2904 genModuleName
= sModuleName
;
2907 genModuleName
= "Sheet1";
2910 while( xLib
->hasByName( genModuleName
) )
2911 genModuleName
= "Sheet" + OUString::number( ++nNum
);
2913 uno::Any aSourceAny
;
2914 OUString sTmpSource
= sSource
;
2915 if ( sTmpSource
.isEmpty() )
2916 sTmpSource
= "Rem Attribute VBA_ModuleType=VBADocumentModule\nOption VBASupport 1\n";
2917 aSourceAny
<<= sTmpSource
;
2918 uno::Reference
< script::vba::XVBAModuleInfo
> xVBAModuleInfo( xLib
, uno::UNO_QUERY
);
2919 if ( xVBAModuleInfo
.is() )
2921 rDoc
.SetCodeName( nTab
, genModuleName
);
2922 script::ModuleInfo sModuleInfo
= lcl_InitModuleInfo( rDocSh
, genModuleName
);
2923 xVBAModuleInfo
->insertModuleInfo( genModuleName
, sModuleInfo
);
2924 xLib
->insertByName( genModuleName
, aSourceAny
);
2930 void VBA_DeleteModule( ScDocShell
& rDocSh
, const OUString
& sModuleName
)
2932 uno::Reference
< script::XLibraryContainer
> xLibContainer
= rDocSh
.GetBasicContainer();
2933 OSL_ENSURE( xLibContainer
.is(), "No BasicContainer!" );
2935 uno::Reference
< container::XNameContainer
> xLib
;
2936 if( xLibContainer
.is() )
2938 OUString
aLibName( "Standard" );
2939 if ( rDocSh
.GetBasicManager() && !rDocSh
.GetBasicManager()->GetName().isEmpty() )
2941 aLibName
= rDocSh
.GetBasicManager()->GetName();
2943 uno::Any aLibAny
= xLibContainer
->getByName( aLibName
);
2948 uno::Reference
< script::vba::XVBAModuleInfo
> xVBAModuleInfo( xLib
, uno::UNO_QUERY
);
2949 if( xLib
->hasByName( sModuleName
) )
2950 xLib
->removeByName( sModuleName
);
2951 if ( xVBAModuleInfo
.is() && xVBAModuleInfo
->hasModuleInfo(sModuleName
) )
2952 xVBAModuleInfo
->removeModuleInfo( sModuleName
);
2958 bool ScDocFunc::InsertTable( SCTAB nTab
, const OUString
& rName
, bool bRecord
, bool bApi
)
2960 bool bSuccess
= false;
2961 WaitObject
aWait( rDocShell
.GetActiveDialogParent() );
2963 ScDocShellModificator
aModificator( rDocShell
);
2965 ScDocument
* pDoc
= rDocShell
.GetDocument();
2968 // Strange loop, also basic is loaded too early ( InsertTable )
2969 // is called via the xml import for sheets in described in ODF
2970 bool bInsertDocModule
= false;
2972 if( !rDocShell
.GetDocument()->IsImportingXML() )
2974 bInsertDocModule
= pDoc
&& pDoc
->IsInVBAMode();
2976 if ( bInsertDocModule
|| ( bRecord
&& !pDoc
->IsUndoEnabled() ) )
2980 pDoc
->BeginDrawUndo(); // InsertTab erzeugt ein SdrUndoNewPage
2982 SCTAB nTabCount
= pDoc
->GetTableCount();
2983 bool bAppend
= ( nTab
>= nTabCount
);
2985 nTab
= nTabCount
; // wichtig fuer Undo
2987 if (pDoc
->InsertTab( nTab
, rName
))
2990 rDocShell
.GetUndoManager()->AddUndoAction(
2991 new ScUndoInsertTab( &rDocShell
, nTab
, bAppend
, rName
));
2993 // Only insert vba modules if vba mode ( and not currently importing XML )
2994 if( bInsertDocModule
)
2996 OUString sSource
, sCodeName
;
2997 VBA_InsertModule( *pDoc
, nTab
, sCodeName
, sSource
);
2999 rDocShell
.Broadcast( ScTablesHint( SC_TAB_INSERTED
, nTab
) );
3001 rDocShell
.PostPaintExtras();
3002 aModificator
.SetDocumentModified();
3003 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
3007 rDocShell
.ErrorMessage(STR_TABINSERT_ERROR
);
3012 bool ScDocFunc::DeleteTable( SCTAB nTab
, bool bRecord
, bool /* bApi */ )
3014 WaitObject
aWait( rDocShell
.GetActiveDialogParent() );
3016 ScDocShellModificator
aModificator( rDocShell
);
3018 bool bSuccess
= false;
3019 ScDocument
* pDoc
= rDocShell
.GetDocument();
3020 bool bVbaEnabled
= pDoc
&& pDoc
->IsInVBAMode();
3021 if (bRecord
&& !pDoc
->IsUndoEnabled())
3025 bool bWasLinked
= pDoc
->IsLinked(nTab
);
3026 ScDocument
* pUndoDoc
= NULL
;
3027 ScRefUndoData
* pUndoData
= NULL
;
3030 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
3031 SCTAB nCount
= pDoc
->GetTableCount();
3033 pUndoDoc
->InitUndo( pDoc
, nTab
, nTab
, true, true ); // nur nTab mit Flags
3034 pUndoDoc
->AddUndoTab( 0, nCount
-1 ); // alle Tabs fuer Referenzen
3036 pDoc
->CopyToDocument(0,0,nTab
, MAXCOL
,MAXROW
,nTab
, IDF_ALL
,false, pUndoDoc
);
3038 pDoc
->GetName( nTab
, aOldName
);
3039 pUndoDoc
->RenameTab( nTab
, aOldName
, false );
3041 pUndoDoc
->SetLink( nTab
, pDoc
->GetLinkMode(nTab
), pDoc
->GetLinkDoc(nTab
),
3042 pDoc
->GetLinkFlt(nTab
), pDoc
->GetLinkOpt(nTab
),
3043 pDoc
->GetLinkTab(nTab
),
3044 pDoc
->GetLinkRefreshDelay(nTab
) );
3046 if ( pDoc
->IsScenario(nTab
) )
3048 pUndoDoc
->SetScenario( nTab
, true );
3051 sal_uInt16 nScenFlags
;
3052 pDoc
->GetScenarioData( nTab
, aComment
, aColor
, nScenFlags
);
3053 pUndoDoc
->SetScenarioData( nTab
, aComment
, aColor
, nScenFlags
);
3054 bool bActive
= pDoc
->IsActiveScenario( nTab
);
3055 pUndoDoc
->SetActiveScenario( nTab
, bActive
);
3057 pUndoDoc
->SetVisible( nTab
, pDoc
->IsVisible( nTab
) );
3058 pUndoDoc
->SetTabBgColor( nTab
, pDoc
->GetTabBgColor(nTab
) );
3059 pUndoDoc
->SetSheetEvents( nTab
, pDoc
->GetSheetEvents( nTab
) );
3061 // Drawing-Layer muss sein Undo selbst in der Hand behalten !!!
3062 pDoc
->BeginDrawUndo(); // DeleteTab erzeugt ein SdrUndoDelPage
3064 pUndoData
= new ScRefUndoData( pDoc
);
3067 if (pDoc
->DeleteTab(nTab
))
3071 vector
<SCTAB
> theTabs
;
3072 theTabs
.push_back(nTab
);
3073 rDocShell
.GetUndoManager()->AddUndoAction(
3074 new ScUndoDeleteTab( &rDocShell
, theTabs
, pUndoDoc
, pUndoData
));
3080 if( pDoc
->GetCodeName( nTab
, sCodeName
) )
3082 VBA_DeleteModule( rDocShell
, sCodeName
);
3085 rDocShell
.Broadcast( ScTablesHint( SC_TAB_DELETED
, nTab
) );
3089 rDocShell
.UpdateLinks(); // Link-Manager updaten
3090 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
3092 pBindings
->Invalidate(SID_LINKS
);
3095 rDocShell
.PostPaintExtras();
3096 aModificator
.SetDocumentModified();
3098 SfxApplication
* pSfxApp
= SFX_APP(); // Navigator
3099 pSfxApp
->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
3100 pSfxApp
->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED
) );
3101 pSfxApp
->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED
) );
3113 bool ScDocFunc::SetTableVisible( SCTAB nTab
, bool bVisible
, bool bApi
)
3115 ScDocument
* pDoc
= rDocShell
.GetDocument();
3116 bool bUndo(pDoc
->IsUndoEnabled());
3117 if ( pDoc
->IsVisible( nTab
) == bVisible
)
3118 return true; // nichts zu tun - ok
3120 if ( !pDoc
->IsDocEditable() )
3123 rDocShell
.ErrorMessage(STR_PROTECTIONERR
);
3127 ScDocShellModificator
aModificator( rDocShell
);
3129 if ( !bVisible
&& !pDoc
->IsImportingXML() ) // #i57869# allow hiding in any order for loading
3131 // nicht alle Tabellen ausblenden
3133 sal_uInt16 nVisCount
= 0;
3134 SCTAB nCount
= pDoc
->GetTableCount();
3135 for (SCTAB i
=0; i
<nCount
&& nVisCount
<2; i
++)
3136 if (pDoc
->IsVisible(i
))
3142 rDocShell
.ErrorMessage(STR_PROTECTIONERR
); //! eigene Meldung?
3147 pDoc
->SetVisible( nTab
, bVisible
);
3150 std::vector
<SCTAB
> undoTabs
;
3151 undoTabs
.push_back(nTab
);
3152 rDocShell
.GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( &rDocShell
, undoTabs
, bVisible
) );
3157 rDocShell
.Broadcast( ScTablesHint( SC_TAB_HIDDEN
, nTab
) );
3159 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
3160 rDocShell
.PostPaint(0,0,0,MAXCOL
,MAXROW
,MAXTAB
, PAINT_EXTRAS
);
3161 aModificator
.SetDocumentModified();
3166 bool ScDocFunc::SetLayoutRTL( SCTAB nTab
, bool bRTL
, bool /* bApi */ )
3168 ScDocument
* pDoc
= rDocShell
.GetDocument();
3169 bool bUndo(pDoc
->IsUndoEnabled());
3170 if ( pDoc
->IsLayoutRTL( nTab
) == bRTL
)
3171 return true; // nothing to do - ok
3173 //! protection (sheet or document?)
3175 ScDocShellModificator
aModificator( rDocShell
);
3177 pDoc
->SetLayoutRTL( nTab
, bRTL
);
3181 rDocShell
.GetUndoManager()->AddUndoAction( new ScUndoLayoutRTL( &rDocShell
, nTab
, bRTL
) );
3184 rDocShell
.PostPaint( 0,0,0,MAXCOL
,MAXROW
,MAXTAB
, PAINT_ALL
);
3185 aModificator
.SetDocumentModified();
3187 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
3190 pBindings
->Invalidate( FID_TAB_RTL
);
3191 pBindings
->Invalidate( SID_ATTR_SIZE
);
3197 bool ScDocFunc::RenameTable( SCTAB nTab
, const OUString
& rName
, bool bRecord
, bool bApi
)
3199 ScDocument
* pDoc
= rDocShell
.GetDocument();
3200 if (bRecord
&& !pDoc
->IsUndoEnabled())
3202 if ( !pDoc
->IsDocEditable() )
3205 rDocShell
.ErrorMessage(STR_PROTECTIONERR
);
3209 ScDocShellModificator
aModificator( rDocShell
);
3211 bool bSuccess
= false;
3213 pDoc
->GetName(nTab
, sOldName
);
3214 if (pDoc
->RenameTab( nTab
, rName
))
3218 rDocShell
.GetUndoManager()->AddUndoAction(
3219 new ScUndoRenameTab( &rDocShell
, nTab
, sOldName
, rName
));
3221 rDocShell
.PostPaintExtras();
3222 aModificator
.SetDocumentModified();
3223 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
3230 bool ScDocFunc::SetTabBgColor( SCTAB nTab
, const Color
& rColor
, bool bRecord
, bool bApi
)
3233 ScDocument
* pDoc
= rDocShell
.GetDocument();
3234 if (bRecord
&& !pDoc
->IsUndoEnabled())
3236 if ( !pDoc
->IsDocEditable() || pDoc
->IsTabProtected(nTab
) )
3239 rDocShell
.ErrorMessage(STR_PROTECTIONERR
); //TODO Check to see what this string is...
3243 Color aOldTabBgColor
;
3244 aOldTabBgColor
= pDoc
->GetTabBgColor(nTab
);
3246 bool bSuccess
= false;
3247 pDoc
->SetTabBgColor(nTab
, rColor
);
3248 if ( pDoc
->GetTabBgColor(nTab
) == rColor
)
3254 rDocShell
.GetUndoManager()->AddUndoAction(
3255 new ScUndoTabColor( &rDocShell
, nTab
, aOldTabBgColor
, rColor
));
3257 rDocShell
.PostPaintExtras();
3258 ScDocShellModificator
aModificator( rDocShell
);
3259 aModificator
.SetDocumentModified();
3260 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
3267 bool ScDocFunc::SetTabBgColor(
3268 ScUndoTabColorInfo::List
& rUndoTabColorList
, bool bRecord
, bool bApi
)
3270 ScDocument
* pDoc
= rDocShell
.GetDocument();
3271 if (bRecord
&& !pDoc
->IsUndoEnabled())
3274 if ( !pDoc
->IsDocEditable() )
3277 rDocShell
.ErrorMessage(STR_PROTECTIONERR
); //TODO Get a better String Error...
3282 Color aNewTabBgColor
;
3283 bool bSuccess
= true;
3284 size_t nTabProtectCount
= 0;
3285 size_t nTabListCount
= rUndoTabColorList
.size();
3286 for ( size_t i
= 0; i
< nTabListCount
; ++i
)
3288 ScUndoTabColorInfo
& rInfo
= rUndoTabColorList
[i
];
3289 nTab
= rInfo
.mnTabId
;
3290 if ( !pDoc
->IsTabProtected(nTab
) )
3292 aNewTabBgColor
= rInfo
.maNewTabBgColor
;
3293 rInfo
.maOldTabBgColor
= pDoc
->GetTabBgColor(nTab
);
3294 pDoc
->SetTabBgColor(nTab
, aNewTabBgColor
);
3295 if ( pDoc
->GetTabBgColor(nTab
) != aNewTabBgColor
)
3307 if ( nTabProtectCount
== nTabListCount
)
3310 rDocShell
.ErrorMessage(STR_PROTECTIONERR
); //TODO Get a better String Error...
3318 rDocShell
.GetUndoManager()->AddUndoAction(
3319 new ScUndoTabColor( &rDocShell
, rUndoTabColorList
));
3321 rDocShell
.PostPaintExtras();
3322 ScDocShellModificator
aModificator( rDocShell
);
3323 aModificator
.SetDocumentModified();
3328 //! SetWidthOrHeight - noch doppelt zu ViewFunc !!!!!!
3330 //! - Optimale Hoehe fuer Edit-Zellen ist unterschiedlich zwischen Drucker und Bildschirm
3331 //! - Optimale Breite braucht Selektion, um evtl. nur selektierte Zellen zu beruecksichtigen
3333 static sal_uInt16
lcl_GetOptimalColWidth( ScDocShell
& rDocShell
, SCCOL nCol
, SCTAB nTab
, bool bFormula
)
3335 ScSizeDeviceProvider
aProv(&rDocShell
);
3336 OutputDevice
* pDev
= aProv
.GetDevice(); // has pixel MapMode
3337 double nPPTX
= aProv
.GetPPTX();
3338 double nPPTY
= aProv
.GetPPTY();
3340 ScDocument
* pDoc
= rDocShell
.GetDocument();
3342 sal_uInt16 nTwips
= pDoc
->GetOptimalColWidth( nCol
, nTab
, pDev
, nPPTX
, nPPTY
, aOne
, aOne
,
3348 bool ScDocFunc::SetWidthOrHeight(
3349 bool bWidth
, const std::vector
<sc::ColRowSpan
>& rRanges
, SCTAB nTab
,
3350 ScSizeMode eMode
, sal_uInt16 nSizeTwips
, bool bRecord
, bool bApi
)
3352 ScDocShellModificator
aModificator( rDocShell
);
3354 if (rRanges
.empty())
3357 ScDocument
* pDoc
= rDocShell
.GetDocument();
3358 if ( bRecord
&& !pDoc
->IsUndoEnabled() )
3361 // import into read-only document is possible
3362 if ( !pDoc
->IsChangeReadOnlyEnabled() && !rDocShell
.IsEditable() )
3365 rDocShell
.ErrorMessage(STR_PROTECTIONERR
); //! eigene Meldung?
3369 bool bSuccess
= false;
3370 SCCOLROW nStart
= rRanges
[0].mnStart
;
3371 SCCOLROW nEnd
= rRanges
[0].mnEnd
;
3373 bool bFormula
= false;
3374 if ( eMode
== SC_SIZE_OPTIMAL
)
3376 //! Option "Formeln anzeigen" - woher nehmen?
3379 ScDocument
* pUndoDoc
= NULL
;
3380 ScOutlineTable
* pUndoTab
= NULL
;
3381 std::vector
<sc::ColRowSpan
> aUndoRanges
;
3385 pDoc
->BeginDrawUndo(); // Drawing Updates
3387 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
3390 pUndoDoc
->InitUndo( pDoc
, nTab
, nTab
, true, false );
3391 pDoc
->CopyToDocument( static_cast<SCCOL
>(nStart
), 0, nTab
, static_cast<SCCOL
>(nEnd
), MAXROW
, nTab
, IDF_NONE
, false, pUndoDoc
);
3395 pUndoDoc
->InitUndo( pDoc
, nTab
, nTab
, false, true );
3396 pDoc
->CopyToDocument( 0, static_cast<SCROW
>(nStart
), nTab
, MAXCOL
, static_cast<SCROW
>(nEnd
), nTab
, IDF_NONE
, false, pUndoDoc
);
3399 aUndoRanges
= rRanges
;
3401 ScOutlineTable
* pTable
= pDoc
->GetOutlineTable( nTab
);
3403 pUndoTab
= new ScOutlineTable( *pTable
);
3406 bool bShow
= nSizeTwips
> 0 || eMode
!= SC_SIZE_DIRECT
;
3407 bool bOutline
= false;
3409 for (size_t i
= 0, n
= rRanges
.size(); i
< n
; ++i
)
3411 SCCOLROW nStartNo
= rRanges
[i
].mnStart
;
3412 SCCOLROW nEndNo
= rRanges
[i
].mnEnd
;
3414 if ( !bWidth
) // Hoehen immer blockweise
3416 if ( eMode
==SC_SIZE_OPTIMAL
|| eMode
==SC_SIZE_VISOPT
)
3418 bool bAll
= ( eMode
==SC_SIZE_OPTIMAL
);
3421 // fuer alle eingeblendeten CR_MANUALSIZE loeschen,
3422 // dann SetOptimalHeight mit bShrink = FALSE
3423 for (SCROW nRow
=nStartNo
; nRow
<=nEndNo
; nRow
++)
3425 sal_uInt8 nOld
= pDoc
->GetRowFlags(nRow
,nTab
);
3426 SCROW nLastRow
= -1;
3427 bool bHidden
= pDoc
->RowHidden(nRow
, nTab
, NULL
, &nLastRow
);
3428 if ( !bHidden
&& ( nOld
& CR_MANUALSIZE
) )
3429 pDoc
->SetRowFlags( nRow
, nTab
, nOld
& ~CR_MANUALSIZE
);
3433 ScSizeDeviceProvider
aProv( &rDocShell
);
3435 sc::RowHeightContext
aCxt(aProv
.GetPPTX(), aProv
.GetPPTY(), aOne
, aOne
, aProv
.GetDevice());
3436 aCxt
.setForceAutoSize(bAll
);
3437 pDoc
->SetOptimalHeight(aCxt
, nStartNo
, nEndNo
, nTab
);
3440 pDoc
->ShowRows( nStartNo
, nEndNo
, nTab
, true );
3442 // Manual-Flag wird bei bAll=sal_True schon in SetOptimalHeight gesetzt
3443 // (an bei Extra-Height, sonst aus).
3445 else if ( eMode
==SC_SIZE_DIRECT
|| eMode
==SC_SIZE_ORIGINAL
)
3449 pDoc
->SetRowHeightRange( nStartNo
, nEndNo
, nTab
, nSizeTwips
);
3450 pDoc
->SetManualHeight( nStartNo
, nEndNo
, nTab
, true ); // height was set manually
3452 if ( eMode
!= SC_SIZE_ORIGINAL
)
3453 pDoc
->ShowRows( nStartNo
, nEndNo
, nTab
, nSizeTwips
!= 0 );
3455 else if ( eMode
==SC_SIZE_SHOW
)
3457 pDoc
->ShowRows( nStartNo
, nEndNo
, nTab
, true );
3460 else // Spaltenbreiten
3462 for (SCCOL nCol
=static_cast<SCCOL
>(nStartNo
); nCol
<=static_cast<SCCOL
>(nEndNo
); nCol
++)
3464 if ( eMode
!= SC_SIZE_VISOPT
|| !pDoc
->ColHidden(nCol
, nTab
) )
3466 sal_uInt16 nThisSize
= nSizeTwips
;
3468 if ( eMode
==SC_SIZE_OPTIMAL
|| eMode
==SC_SIZE_VISOPT
)
3469 nThisSize
= nSizeTwips
+
3470 lcl_GetOptimalColWidth( rDocShell
, nCol
, nTab
, bFormula
);
3472 pDoc
->SetColWidth( nCol
, nTab
, nThisSize
);
3474 if ( eMode
!= SC_SIZE_ORIGINAL
)
3475 pDoc
->ShowCol( nCol
, nTab
, bShow
);
3482 if ( eMode
!= SC_SIZE_ORIGINAL
)
3485 bOutline
= bOutline
|| pDoc
->UpdateOutlineCol(
3486 static_cast<SCCOL
>(nStartNo
),
3487 static_cast<SCCOL
>(nEndNo
), nTab
, bShow
);
3489 bOutline
= bOutline
|| pDoc
->UpdateOutlineRow(
3490 static_cast<SCROW
>(nStartNo
),
3491 static_cast<SCROW
>(nEndNo
), nTab
, bShow
);
3494 pDoc
->SetDrawPageSize(nTab
);
3502 aMark
.SelectOneTable( nTab
);
3503 rDocShell
.GetUndoManager()->AddUndoAction(
3504 new ScUndoWidthOrHeight(
3505 &rDocShell
, aMark
, nStart
, nTab
, nEnd
, nTab
, pUndoDoc
,
3506 aUndoRanges
, pUndoTab
, eMode
, nSizeTwips
, bWidth
));
3509 pDoc
->UpdatePageBreaks( nTab
);
3511 rDocShell
.PostPaint(0,0,nTab
,MAXCOL
,MAXROW
,nTab
,PAINT_ALL
);
3512 aModificator
.SetDocumentModified();
3518 bool ScDocFunc::InsertPageBreak( bool bColumn
, const ScAddress
& rPos
,
3519 bool bRecord
, bool bSetModified
, bool /* bApi */ )
3521 ScDocShellModificator
aModificator( rDocShell
);
3523 ScDocument
* pDoc
= rDocShell
.GetDocument();
3524 if (bRecord
&& !pDoc
->IsUndoEnabled())
3526 SCTAB nTab
= rPos
.Tab();
3527 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
3529 SCCOLROW nPos
= bColumn
? static_cast<SCCOLROW
>(rPos
.Col()) :
3530 static_cast<SCCOLROW
>(rPos
.Row());
3532 return false; // erste Spalte / Zeile
3534 ScBreakType nBreak
= bColumn
?
3535 pDoc
->HasColBreak(static_cast<SCCOL
>(nPos
), nTab
) :
3536 pDoc
->HasRowBreak(static_cast<SCROW
>(nPos
), nTab
);
3537 if (nBreak
& BREAK_MANUAL
)
3541 rDocShell
.GetUndoManager()->AddUndoAction(
3542 new ScUndoPageBreak( &rDocShell
, rPos
.Col(), rPos
.Row(), nTab
, bColumn
, true ) );
3545 pDoc
->SetColBreak(static_cast<SCCOL
>(nPos
), nTab
, false, true);
3547 pDoc
->SetRowBreak(static_cast<SCROW
>(nPos
), nTab
, false, true);
3549 pDoc
->InvalidatePageBreaks(nTab
);
3550 pDoc
->UpdatePageBreaks( nTab
);
3552 if (pDoc
->IsStreamValid(nTab
))
3553 pDoc
->SetStreamValid(nTab
, false);
3557 rDocShell
.PostPaint( static_cast<SCCOL
>(nPos
)-1, 0, nTab
, MAXCOL
, MAXROW
, nTab
, PAINT_GRID
);
3560 pBindings
->Invalidate( FID_INS_COLBRK
);
3561 pBindings
->Invalidate( FID_DEL_COLBRK
);
3566 rDocShell
.PostPaint( 0, static_cast<SCROW
>(nPos
)-1, nTab
, MAXCOL
, MAXROW
, nTab
, PAINT_GRID
);
3569 pBindings
->Invalidate( FID_INS_ROWBRK
);
3570 pBindings
->Invalidate( FID_DEL_ROWBRK
);
3574 pBindings
->Invalidate( FID_DEL_MANUALBREAKS
);
3577 aModificator
.SetDocumentModified();
3582 bool ScDocFunc::RemovePageBreak( bool bColumn
, const ScAddress
& rPos
,
3583 bool bRecord
, bool bSetModified
, bool /* bApi */ )
3585 ScDocShellModificator
aModificator( rDocShell
);
3587 ScDocument
* pDoc
= rDocShell
.GetDocument();
3588 if (bRecord
&& !pDoc
->IsUndoEnabled())
3590 SCTAB nTab
= rPos
.Tab();
3591 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
3593 SCCOLROW nPos
= bColumn
? static_cast<SCCOLROW
>(rPos
.Col()) :
3594 static_cast<SCCOLROW
>(rPos
.Row());
3598 nBreak
= pDoc
->HasColBreak(static_cast<SCCOL
>(nPos
), nTab
);
3600 nBreak
= pDoc
->HasRowBreak(static_cast<SCROW
>(nPos
), nTab
);
3601 if ((nBreak
& BREAK_MANUAL
) == 0)
3602 // There is no manual break.
3606 rDocShell
.GetUndoManager()->AddUndoAction(
3607 new ScUndoPageBreak( &rDocShell
, rPos
.Col(), rPos
.Row(), nTab
, bColumn
, false ) );
3610 pDoc
->RemoveColBreak(static_cast<SCCOL
>(nPos
), nTab
, false, true);
3612 pDoc
->RemoveRowBreak(static_cast<SCROW
>(nPos
), nTab
, false, true);
3614 pDoc
->UpdatePageBreaks( nTab
);
3616 if (pDoc
->IsStreamValid(nTab
))
3617 pDoc
->SetStreamValid(nTab
, false);
3621 rDocShell
.PostPaint( static_cast<SCCOL
>(nPos
)-1, 0, nTab
, MAXCOL
, MAXROW
, nTab
, PAINT_GRID
);
3624 pBindings
->Invalidate( FID_INS_COLBRK
);
3625 pBindings
->Invalidate( FID_DEL_COLBRK
);
3630 rDocShell
.PostPaint( 0, nPos
-1, nTab
, MAXCOL
, MAXROW
, nTab
, PAINT_GRID
);
3633 pBindings
->Invalidate( FID_INS_ROWBRK
);
3634 pBindings
->Invalidate( FID_DEL_ROWBRK
);
3638 pBindings
->Invalidate( FID_DEL_MANUALBREAKS
);
3641 aModificator
.SetDocumentModified();
3646 void ScDocFunc::ProtectSheet( SCTAB nTab
, const ScTableProtection
& rProtect
)
3648 ScDocument
* pDoc
= rDocShell
.GetDocument();
3650 pDoc
->SetTabProtection(nTab
, &rProtect
);
3651 if (pDoc
->IsUndoEnabled())
3653 ScTableProtection
* pProtect
= pDoc
->GetTabProtection(nTab
);
3654 OSL_ENSURE(pProtect
, "ScDocFunc::Unprotect: ScTableProtection pointer is NULL!");
3657 SAL_WNODEPRECATED_DECLARATIONS_PUSH
3658 ::std::auto_ptr
<ScTableProtection
> p(new ScTableProtection(*pProtect
));
3659 SAL_WNODEPRECATED_DECLARATIONS_POP
3660 p
->setProtected(true); // just in case ...
3661 rDocShell
.GetUndoManager()->AddUndoAction(
3662 new ScUndoTabProtect(&rDocShell
, nTab
, p
) );
3664 // ownership of auto_ptr now transferred to ScUndoTabProtect.
3668 rDocShell
.PostPaintGridAll();
3669 ScDocShellModificator
aModificator(rDocShell
);
3670 aModificator
.SetDocumentModified();
3673 bool ScDocFunc::Protect( SCTAB nTab
, const OUString
& rPassword
, bool /*bApi*/ )
3675 ScDocument
* pDoc
= rDocShell
.GetDocument();
3676 if (nTab
== TABLEID_DOC
)
3678 // document protection
3679 ScDocProtection aProtection
;
3680 aProtection
.setProtected(true);
3681 aProtection
.setPassword(rPassword
);
3682 pDoc
->SetDocProtection(&aProtection
);
3683 if (pDoc
->IsUndoEnabled())
3685 ScDocProtection
* pProtect
= pDoc
->GetDocProtection();
3686 OSL_ENSURE(pProtect
, "ScDocFunc::Unprotect: ScDocProtection pointer is NULL!");
3689 SAL_WNODEPRECATED_DECLARATIONS_PUSH
3690 ::std::auto_ptr
<ScDocProtection
> p(new ScDocProtection(*pProtect
));
3691 SAL_WNODEPRECATED_DECLARATIONS_POP
3692 p
->setProtected(true); // just in case ...
3693 rDocShell
.GetUndoManager()->AddUndoAction(
3694 new ScUndoDocProtect(&rDocShell
, p
) );
3695 // ownership of auto_ptr is transferred to ScUndoDocProtect.
3703 ScTableProtection aProtection
;
3704 aProtection
.setProtected(true);
3705 aProtection
.setPassword(rPassword
);
3706 pDoc
->SetTabProtection(nTab
, &aProtection
);
3707 if (pDoc
->IsUndoEnabled())
3709 ScTableProtection
* pProtect
= pDoc
->GetTabProtection(nTab
);
3710 OSL_ENSURE(pProtect
, "ScDocFunc::Unprotect: ScTableProtection pointer is NULL!");
3713 SAL_WNODEPRECATED_DECLARATIONS_PUSH
3714 ::std::auto_ptr
<ScTableProtection
> p(new ScTableProtection(*pProtect
));
3715 SAL_WNODEPRECATED_DECLARATIONS_POP
3716 p
->setProtected(true); // just in case ...
3717 rDocShell
.GetUndoManager()->AddUndoAction(
3718 new ScUndoTabProtect(&rDocShell
, nTab
, p
) );
3719 // ownership of auto_ptr now transferred to ScUndoTabProtect.
3724 rDocShell
.PostPaintGridAll();
3725 ScDocShellModificator
aModificator( rDocShell
);
3726 aModificator
.SetDocumentModified();
3731 bool ScDocFunc::Unprotect( SCTAB nTab
, const OUString
& rPassword
, bool bApi
)
3733 ScDocument
* pDoc
= rDocShell
.GetDocument();
3735 if (nTab
== TABLEID_DOC
)
3737 // document protection
3739 ScDocProtection
* pDocProtect
= pDoc
->GetDocProtection();
3740 if (!pDocProtect
|| !pDocProtect
->isProtected())
3741 // already unprotected (should not happen)!
3744 // save the protection state before unprotect (for undo).
3745 SAL_WNODEPRECATED_DECLARATIONS_PUSH
3746 ::std::auto_ptr
<ScDocProtection
> pProtectCopy(new ScDocProtection(*pDocProtect
));
3747 SAL_WNODEPRECATED_DECLARATIONS_POP
3749 if (!pDocProtect
->verifyPassword(rPassword
))
3753 InfoBox
aBox( rDocShell
.GetActiveDialogParent(), OUString( ScResId( SCSTR_WRONGPASSWORD
) ) );
3759 pDoc
->SetDocProtection(NULL
);
3760 if (pDoc
->IsUndoEnabled())
3762 pProtectCopy
->setProtected(false);
3763 rDocShell
.GetUndoManager()->AddUndoAction(
3764 new ScUndoDocProtect(&rDocShell
, pProtectCopy
) );
3765 // ownership of auto_ptr now transferred to ScUndoDocProtect.
3772 ScTableProtection
* pTabProtect
= pDoc
->GetTabProtection(nTab
);
3773 if (!pTabProtect
|| !pTabProtect
->isProtected())
3774 // already unprotected (should not happen)!
3777 // save the protection state before unprotect (for undo).
3778 SAL_WNODEPRECATED_DECLARATIONS_PUSH
3779 ::std::auto_ptr
<ScTableProtection
> pProtectCopy(new ScTableProtection(*pTabProtect
));
3780 SAL_WNODEPRECATED_DECLARATIONS_POP
3781 if (!pTabProtect
->verifyPassword(rPassword
))
3785 InfoBox
aBox( rDocShell
.GetActiveDialogParent(), OUString( ScResId( SCSTR_WRONGPASSWORD
) ) );
3791 pDoc
->SetTabProtection(nTab
, NULL
);
3792 if (pDoc
->IsUndoEnabled())
3794 pProtectCopy
->setProtected(false);
3795 rDocShell
.GetUndoManager()->AddUndoAction(
3796 new ScUndoTabProtect(&rDocShell
, nTab
, pProtectCopy
) );
3797 // ownership of auto_ptr now transferred to ScUndoTabProtect.
3801 rDocShell
.PostPaintGridAll();
3802 ScDocShellModificator
aModificator( rDocShell
);
3803 aModificator
.SetDocumentModified();
3808 bool ScDocFunc::ClearItems( const ScMarkData
& rMark
, const sal_uInt16
* pWhich
, bool bApi
)
3810 ScDocShellModificator
aModificator( rDocShell
);
3812 ScDocument
* pDoc
= rDocShell
.GetDocument();
3813 bool bUndo (pDoc
->IsUndoEnabled());
3814 ScEditableTester
aTester( pDoc
, rMark
);
3815 if (!aTester
.IsEditable())
3818 rDocShell
.ErrorMessage(aTester
.GetMessageId());
3822 // #i12940# ClearItems is called (from setPropertyToDefault) directly with uno object's cached
3823 // MarkData (GetMarkData), so rMark must be changed to multi selection for ClearSelectionItems
3827 ScMarkData aMultiMark
= rMark
;
3828 aMultiMark
.SetMarking(false); // for MarkToMulti
3829 aMultiMark
.MarkToMulti();
3830 aMultiMark
.GetMultiMarkArea( aMarkRange
);
3834 SCTAB nStartTab
= aMarkRange
.aStart
.Tab();
3835 SCTAB nEndTab
= aMarkRange
.aEnd
.Tab();
3837 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
3838 pUndoDoc
->InitUndo( pDoc
, nStartTab
, nEndTab
);
3839 pDoc
->CopyToDocument( aMarkRange
, IDF_ATTRIB
, true, pUndoDoc
, (ScMarkData
*)&aMultiMark
);
3841 rDocShell
.GetUndoManager()->AddUndoAction(
3842 new ScUndoClearItems( &rDocShell
, aMultiMark
, pUndoDoc
, pWhich
) );
3845 pDoc
->ClearSelectionItems( pWhich
, aMultiMark
);
3847 rDocShell
.PostPaint( aMarkRange
, PAINT_GRID
, SC_PF_LINES
| SC_PF_TESTMERGE
);
3848 aModificator
.SetDocumentModified();
3850 //! Bindings-Invalidate etc.?
3855 bool ScDocFunc::ChangeIndent( const ScMarkData
& rMark
, bool bIncrement
, bool bApi
)
3857 ScDocShellModificator
aModificator( rDocShell
);
3859 ScDocument
* pDoc
= rDocShell
.GetDocument();
3860 bool bUndo(pDoc
->IsUndoEnabled());
3861 ScEditableTester
aTester( pDoc
, rMark
);
3862 if (!aTester
.IsEditable())
3865 rDocShell
.ErrorMessage(aTester
.GetMessageId());
3870 rMark
.GetMultiMarkArea( aMarkRange
);
3874 SCTAB nStartTab
= aMarkRange
.aStart
.Tab();
3875 SCTAB nTabCount
= pDoc
->GetTableCount();
3877 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
3878 pUndoDoc
->InitUndo( pDoc
, nStartTab
, nStartTab
);
3879 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
3880 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
3881 if (*itr
!= nStartTab
)
3882 pUndoDoc
->AddUndoTab( *itr
, *itr
);
3884 ScRange aCopyRange
= aMarkRange
;
3885 aCopyRange
.aStart
.SetTab(0);
3886 aCopyRange
.aEnd
.SetTab(nTabCount
-1);
3887 pDoc
->CopyToDocument( aCopyRange
, IDF_ATTRIB
, true, pUndoDoc
, (ScMarkData
*)&rMark
);
3889 rDocShell
.GetUndoManager()->AddUndoAction(
3890 new ScUndoIndent( &rDocShell
, rMark
, pUndoDoc
, bIncrement
) );
3893 pDoc
->ChangeSelectionIndent( bIncrement
, rMark
);
3895 rDocShell
.PostPaint( aMarkRange
, PAINT_GRID
, SC_PF_LINES
| SC_PF_TESTMERGE
);
3896 aModificator
.SetDocumentModified();
3898 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
3901 pBindings
->Invalidate( SID_ALIGNLEFT
); // ChangeIndent setzt auf links
3902 pBindings
->Invalidate( SID_ALIGNRIGHT
);
3903 pBindings
->Invalidate( SID_ALIGNBLOCK
);
3904 pBindings
->Invalidate( SID_ALIGNCENTERHOR
);
3905 pBindings
->Invalidate( SID_ATTR_LRSPACE
);
3906 pBindings
->Invalidate( SID_ATTR_PARA_ADJUST_LEFT
);
3907 pBindings
->Invalidate( SID_ATTR_PARA_ADJUST_RIGHT
);
3908 pBindings
->Invalidate( SID_ATTR_PARA_ADJUST_BLOCK
);
3909 pBindings
->Invalidate( SID_ATTR_PARA_ADJUST_CENTER
);
3910 // pseudo slots for Format menu
3911 pBindings
->Invalidate( SID_ALIGN_ANY_HDEFAULT
);
3912 pBindings
->Invalidate( SID_ALIGN_ANY_LEFT
);
3913 pBindings
->Invalidate( SID_ALIGN_ANY_HCENTER
);
3914 pBindings
->Invalidate( SID_ALIGN_ANY_RIGHT
);
3915 pBindings
->Invalidate( SID_ALIGN_ANY_JUSTIFIED
);
3921 bool ScDocFunc::AutoFormat( const ScRange
& rRange
, const ScMarkData
* pTabMark
,
3922 sal_uInt16 nFormatNo
, bool bRecord
, bool bApi
)
3924 ScDocShellModificator
aModificator( rDocShell
);
3926 bool bSuccess
= false;
3927 ScDocument
* pDoc
= rDocShell
.GetDocument();
3928 SCCOL nStartCol
= rRange
.aStart
.Col();
3929 SCROW nStartRow
= rRange
.aStart
.Row();
3930 SCTAB nStartTab
= rRange
.aStart
.Tab();
3931 SCCOL nEndCol
= rRange
.aEnd
.Col();
3932 SCROW nEndRow
= rRange
.aEnd
.Row();
3933 SCTAB nEndTab
= rRange
.aEnd
.Tab();
3935 if (bRecord
&& !pDoc
->IsUndoEnabled())
3942 for (SCTAB nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
3943 aMark
.SelectTable( nTab
, true );
3946 ScAutoFormat
* pAutoFormat
= ScGlobal::GetOrCreateAutoFormat();
3947 ScEditableTester
aTester( pDoc
, nStartCol
,nStartRow
, nEndCol
,nEndRow
, aMark
);
3948 if ( nFormatNo
< pAutoFormat
->size() && aTester
.IsEditable() )
3950 WaitObject
aWait( rDocShell
.GetActiveDialogParent() );
3952 bool bSize
= pAutoFormat
->findByIndex(nFormatNo
)->GetIncludeWidthHeight();
3954 SCTAB nTabCount
= pDoc
->GetTableCount();
3955 ScDocument
* pUndoDoc
= NULL
;
3958 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
3959 pUndoDoc
->InitUndo( pDoc
, nStartTab
, nStartTab
, bSize
, bSize
);
3960 ScMarkData::iterator itr
= aMark
.begin(), itrEnd
= aMark
.end();
3961 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
3962 if (*itr
!= nStartTab
)
3963 pUndoDoc
->AddUndoTab( *itr
, *itr
, bSize
, bSize
);
3965 ScRange aCopyRange
= rRange
;
3966 aCopyRange
.aStart
.SetTab(0);
3967 aCopyRange
.aStart
.SetTab(nTabCount
-1);
3968 pDoc
->CopyToDocument( aCopyRange
, IDF_ATTRIB
, false, pUndoDoc
, &aMark
);
3971 pDoc
->CopyToDocument( nStartCol
,0,0, nEndCol
,MAXROW
,nTabCount
-1,
3972 IDF_NONE
, false, pUndoDoc
, &aMark
);
3973 pDoc
->CopyToDocument( 0,nStartRow
,0, MAXCOL
,nEndRow
,nTabCount
-1,
3974 IDF_NONE
, false, pUndoDoc
, &aMark
);
3976 pDoc
->BeginDrawUndo();
3979 pDoc
->AutoFormat( nStartCol
, nStartRow
, nEndCol
, nEndRow
, nFormatNo
, aMark
);
3983 std::vector
<sc::ColRowSpan
> aCols(1, sc::ColRowSpan(nStartCol
,nEndCol
));
3984 std::vector
<sc::ColRowSpan
> aRows(1, sc::ColRowSpan(nStartRow
,nEndRow
));
3986 ScMarkData::iterator itr
= aMark
.begin(), itrEnd
= aMark
.end();
3987 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
3989 SetWidthOrHeight(true, aCols
, *itr
, SC_SIZE_VISOPT
, STD_EXTRA_WIDTH
, false, true);
3990 SetWidthOrHeight(false, aRows
, *itr
, SC_SIZE_VISOPT
, 0, false, false);
3991 rDocShell
.PostPaint( 0,0,*itr
, MAXCOL
,MAXROW
,*itr
,
3992 PAINT_GRID
| PAINT_LEFT
| PAINT_TOP
);
3997 ScMarkData::iterator itr
= aMark
.begin(), itrEnd
= aMark
.end();
3998 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
4000 bool bAdj
= AdjustRowHeight( ScRange(nStartCol
, nStartRow
, *itr
,
4001 nEndCol
, nEndRow
, *itr
), false );
4003 rDocShell
.PostPaint( 0,nStartRow
,*itr
, MAXCOL
,MAXROW
,*itr
,
4004 PAINT_GRID
| PAINT_LEFT
);
4006 rDocShell
.PostPaint( nStartCol
, nStartRow
, *itr
,
4007 nEndCol
, nEndRow
, *itr
, PAINT_GRID
);
4011 if ( bRecord
) // Draw-Undo erst jetzt verfuegbar
4013 rDocShell
.GetUndoManager()->AddUndoAction(
4014 new ScUndoAutoFormat( &rDocShell
, rRange
, pUndoDoc
, aMark
, bSize
, nFormatNo
) );
4017 aModificator
.SetDocumentModified();
4020 rDocShell
.ErrorMessage(aTester
.GetMessageId());
4025 bool ScDocFunc::EnterMatrix( const ScRange
& rRange
, const ScMarkData
* pTabMark
,
4026 const ScTokenArray
* pTokenArray
, const OUString
& rString
, bool bApi
, bool bEnglish
,
4027 const OUString
& rFormulaNmsp
, const formula::FormulaGrammar::Grammar eGrammar
)
4029 ScDocShellModificator
aModificator( rDocShell
);
4031 bool bSuccess
= false;
4032 ScDocument
* pDoc
= rDocShell
.GetDocument();
4033 SCCOL nStartCol
= rRange
.aStart
.Col();
4034 SCROW nStartRow
= rRange
.aStart
.Row();
4035 SCTAB nStartTab
= rRange
.aStart
.Tab();
4036 SCCOL nEndCol
= rRange
.aEnd
.Col();
4037 SCROW nEndRow
= rRange
.aEnd
.Row();
4038 SCTAB nEndTab
= rRange
.aEnd
.Tab();
4040 bool bUndo(pDoc
->IsUndoEnabled());
4047 for (SCTAB nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
4048 aMark
.SelectTable( nTab
, true );
4051 ScEditableTester
aTester( pDoc
, nStartCol
,nStartRow
, nEndCol
,nEndRow
, aMark
);
4052 if ( aTester
.IsEditable() )
4054 WaitObject
aWait( rDocShell
.GetActiveDialogParent() );
4056 ScDocument
* pUndoDoc
= NULL
;
4060 //! auch bei Undo selektierte Tabellen beruecksichtigen
4061 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
4062 pUndoDoc
->InitUndo( pDoc
, nStartTab
, nEndTab
);
4063 pDoc
->CopyToDocument( rRange
, IDF_ALL
& ~IDF_NOTE
, false, pUndoDoc
);
4066 // use TokenArray if given, string (and flags) otherwise
4069 pDoc
->InsertMatrixFormula( nStartCol
, nStartRow
, nEndCol
, nEndRow
,
4070 aMark
, EMPTY_OUSTRING
, pTokenArray
, eGrammar
);
4072 else if ( pDoc
->IsImportingXML() )
4074 ScTokenArray
* pCode
= lcl_ScDocFunc_CreateTokenArrayXML( rString
, rFormulaNmsp
, eGrammar
);
4075 pDoc
->InsertMatrixFormula( nStartCol
, nStartRow
, nEndCol
, nEndRow
,
4076 aMark
, EMPTY_OUSTRING
, pCode
, eGrammar
);
4078 pDoc
->IncXMLImportedFormulaCount( rString
.getLength() );
4082 ScCompiler
aComp( pDoc
, rRange
.aStart
);
4083 aComp
.SetGrammar(eGrammar
);
4084 ScTokenArray
* pCode
= aComp
.CompileString( rString
);
4085 pDoc
->InsertMatrixFormula( nStartCol
, nStartRow
, nEndCol
, nEndRow
,
4086 aMark
, EMPTY_OUSTRING
, pCode
, eGrammar
);
4090 pDoc
->InsertMatrixFormula( nStartCol
, nStartRow
, nEndCol
, nEndRow
,
4091 aMark
, rString
, NULL
, eGrammar
);
4095 //! auch bei Undo selektierte Tabellen beruecksichtigen
4096 rDocShell
.GetUndoManager()->AddUndoAction(
4097 new ScUndoEnterMatrix( &rDocShell
, rRange
, pUndoDoc
, rString
) );
4100 // Err522 beim Paint von DDE-Formeln werden jetzt beim Interpretieren abgefangen
4101 rDocShell
.PostPaint( nStartCol
,nStartRow
,nStartTab
,nEndCol
,nEndRow
,nEndTab
, PAINT_GRID
);
4102 aModificator
.SetDocumentModified();
4107 rDocShell
.ErrorMessage(aTester
.GetMessageId());
4112 bool ScDocFunc::TabOp( const ScRange
& rRange
, const ScMarkData
* pTabMark
,
4113 const ScTabOpParam
& rParam
, bool bRecord
, bool bApi
)
4115 ScDocShellModificator
aModificator( rDocShell
);
4117 bool bSuccess
= false;
4118 ScDocument
* pDoc
= rDocShell
.GetDocument();
4119 SCCOL nStartCol
= rRange
.aStart
.Col();
4120 SCROW nStartRow
= rRange
.aStart
.Row();
4121 SCTAB nStartTab
= rRange
.aStart
.Tab();
4122 SCCOL nEndCol
= rRange
.aEnd
.Col();
4123 SCROW nEndRow
= rRange
.aEnd
.Row();
4124 SCTAB nEndTab
= rRange
.aEnd
.Tab();
4126 if (bRecord
&& !pDoc
->IsUndoEnabled())
4134 for (SCTAB nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
4135 aMark
.SelectTable( nTab
, true );
4138 ScEditableTester
aTester( pDoc
, nStartCol
,nStartRow
, nEndCol
,nEndRow
, aMark
);
4139 if ( aTester
.IsEditable() )
4141 WaitObject
aWait( rDocShell
.GetActiveDialogParent() );
4142 pDoc
->SetDirty( rRange
);
4145 //! auch bei Undo selektierte Tabellen beruecksichtigen
4146 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
4147 pUndoDoc
->InitUndo( pDoc
, nStartTab
, nEndTab
);
4148 pDoc
->CopyToDocument( rRange
, IDF_ALL
& ~IDF_NOTE
, false, pUndoDoc
);
4150 rDocShell
.GetUndoManager()->AddUndoAction(
4151 new ScUndoTabOp( &rDocShell
,
4152 nStartCol
, nStartRow
, nStartTab
,
4153 nEndCol
, nEndRow
, nEndTab
, pUndoDoc
,
4154 rParam
.aRefFormulaCell
,
4155 rParam
.aRefFormulaEnd
,
4160 pDoc
->InsertTableOp(rParam
, nStartCol
, nStartRow
, nEndCol
, nEndRow
, aMark
);
4161 rDocShell
.PostPaintGridAll();
4162 aModificator
.SetDocumentModified();
4166 rDocShell
.ErrorMessage(aTester
.GetMessageId());
4171 inline ScDirection
DirFromFillDir( FillDir eDir
)
4173 if (eDir
==FILL_TO_BOTTOM
)
4175 else if (eDir
==FILL_TO_RIGHT
)
4177 else if (eDir
==FILL_TO_TOP
)
4179 else // if (eDir==FILL_TO_LEFT)
4186 * Expand the fill range as necessary, to allow copying of adjacent cell(s)
4187 * even when those cells are not in the original range.
4189 void adjustFillRangeForAdjacentCopy(ScRange
& rRange
, FillDir eDir
)
4193 case FILL_TO_BOTTOM
:
4195 if (rRange
.aStart
.Row() == 0)
4198 if (rRange
.aStart
.Row() != rRange
.aEnd
.Row())
4201 // Include the above row.
4202 ScAddress
& s
= rRange
.aStart
;
4203 s
.SetRow(s
.Row()-1);
4208 if (rRange
.aStart
.Row() == MAXROW
)
4211 if (rRange
.aStart
.Row() != rRange
.aEnd
.Row())
4214 // Include the row below.
4215 ScAddress
& e
= rRange
.aEnd
;
4216 e
.SetRow(e
.Row()+1);
4221 if (rRange
.aStart
.Col() == MAXCOL
)
4224 if (rRange
.aStart
.Col() != rRange
.aEnd
.Col())
4227 // Include the column to the right.
4228 ScAddress
& e
= rRange
.aEnd
;
4229 e
.SetCol(e
.Col()+1);
4234 if (rRange
.aStart
.Col() == 0)
4237 if (rRange
.aStart
.Col() != rRange
.aEnd
.Col())
4240 // Include the column to the left.
4241 ScAddress
& s
= rRange
.aStart
;
4242 s
.SetCol(s
.Col()-1);
4252 bool ScDocFunc::FillSimple( const ScRange
& rRange
, const ScMarkData
* pTabMark
,
4253 FillDir eDir
, bool bRecord
, bool bApi
)
4255 ScDocShellModificator
aModificator( rDocShell
);
4256 ScDocument
* pDoc
= rDocShell
.GetDocument();
4258 bool bSuccess
= false;
4259 ScRange aRange
= rRange
;
4260 adjustFillRangeForAdjacentCopy(aRange
, eDir
);
4262 SCCOL nStartCol
= aRange
.aStart
.Col();
4263 SCROW nStartRow
= aRange
.aStart
.Row();
4264 SCTAB nStartTab
= aRange
.aStart
.Tab();
4265 SCCOL nEndCol
= aRange
.aEnd
.Col();
4266 SCROW nEndRow
= aRange
.aEnd
.Row();
4267 SCTAB nEndTab
= aRange
.aEnd
.Tab();
4269 if (bRecord
&& !pDoc
->IsUndoEnabled())
4277 for (SCTAB nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
4278 aMark
.SelectTable( nTab
, true );
4281 ScEditableTester
aTester( pDoc
, nStartCol
,nStartRow
, nEndCol
,nEndRow
, aMark
);
4282 if ( aTester
.IsEditable() )
4284 WaitObject
aWait( rDocShell
.GetActiveDialogParent() );
4286 ScRange aSourceArea
= aRange
;
4287 ScRange aDestArea
= aRange
;
4289 SCCOLROW nCount
= 0;
4292 case FILL_TO_BOTTOM
:
4293 nCount
= aSourceArea
.aEnd
.Row()-aSourceArea
.aStart
.Row();
4294 aSourceArea
.aEnd
.SetRow( aSourceArea
.aStart
.Row() );
4297 nCount
= aSourceArea
.aEnd
.Col()-aSourceArea
.aStart
.Col();
4298 aSourceArea
.aEnd
.SetCol( aSourceArea
.aStart
.Col() );
4301 nCount
= aSourceArea
.aEnd
.Row()-aSourceArea
.aStart
.Row();
4302 aSourceArea
.aStart
.SetRow( aSourceArea
.aEnd
.Row() );
4305 nCount
= aSourceArea
.aEnd
.Col()-aSourceArea
.aStart
.Col();
4306 aSourceArea
.aStart
.SetCol( aSourceArea
.aEnd
.Col() );
4310 ScDocument
* pUndoDoc
= NULL
;
4313 SCTAB nTabCount
= pDoc
->GetTableCount();
4314 SCTAB nDestStartTab
= aDestArea
.aStart
.Tab();
4316 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
4317 pUndoDoc
->InitUndo( pDoc
, nDestStartTab
, nDestStartTab
);
4318 ScMarkData::iterator itr
= aMark
.begin(), itrEnd
= aMark
.end();
4319 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
4320 if (*itr
!= nDestStartTab
)
4321 pUndoDoc
->AddUndoTab( *itr
, *itr
);
4323 ScRange aCopyRange
= aDestArea
;
4324 aCopyRange
.aStart
.SetTab(0);
4325 aCopyRange
.aEnd
.SetTab(nTabCount
-1);
4326 pDoc
->CopyToDocument( aCopyRange
, IDF_AUTOFILL
, false, pUndoDoc
, &aMark
);
4329 sal_uLong nProgCount
;
4330 if (eDir
== FILL_TO_BOTTOM
|| eDir
== FILL_TO_TOP
)
4331 nProgCount
= aSourceArea
.aEnd
.Col() - aSourceArea
.aStart
.Col() + 1;
4333 nProgCount
= aSourceArea
.aEnd
.Row() - aSourceArea
.aStart
.Row() + 1;
4334 nProgCount
*= nCount
;
4335 ScProgress
aProgress( pDoc
->GetDocumentShell(),
4336 ScGlobal::GetRscString(STR_FILL_SERIES_PROGRESS
), nProgCount
);
4338 pDoc
->Fill( aSourceArea
.aStart
.Col(), aSourceArea
.aStart
.Row(),
4339 aSourceArea
.aEnd
.Col(), aSourceArea
.aEnd
.Row(), &aProgress
,
4340 aMark
, nCount
, eDir
, FILL_SIMPLE
);
4341 AdjustRowHeight(aRange
);
4343 if ( bRecord
) // Draw-Undo erst jetzt verfuegbar
4345 rDocShell
.GetUndoManager()->AddUndoAction(
4346 new ScUndoAutoFill( &rDocShell
, aDestArea
, aSourceArea
, pUndoDoc
, aMark
,
4347 eDir
, FILL_SIMPLE
, FILL_DAY
, MAXDOUBLE
, 1.0, 1e307
) );
4350 rDocShell
.PostPaintGridAll();
4351 aModificator
.SetDocumentModified();
4356 rDocShell
.ErrorMessage(aTester
.GetMessageId());
4361 bool ScDocFunc::FillSeries( const ScRange
& rRange
, const ScMarkData
* pTabMark
,
4362 FillDir eDir
, FillCmd eCmd
, FillDateCmd eDateCmd
,
4363 double fStart
, double fStep
, double fMax
,
4364 bool bRecord
, bool bApi
)
4366 ScDocShellModificator
aModificator( rDocShell
);
4368 bool bSuccess
= false;
4369 ScDocument
* pDoc
= rDocShell
.GetDocument();
4370 SCCOL nStartCol
= rRange
.aStart
.Col();
4371 SCROW nStartRow
= rRange
.aStart
.Row();
4372 SCTAB nStartTab
= rRange
.aStart
.Tab();
4373 SCCOL nEndCol
= rRange
.aEnd
.Col();
4374 SCROW nEndRow
= rRange
.aEnd
.Row();
4375 SCTAB nEndTab
= rRange
.aEnd
.Tab();
4377 if (bRecord
&& !pDoc
->IsUndoEnabled())
4385 for (SCTAB nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
4386 aMark
.SelectTable( nTab
, true );
4389 ScEditableTester
aTester( pDoc
, nStartCol
,nStartRow
, nEndCol
,nEndRow
, aMark
);
4390 if ( aTester
.IsEditable() )
4392 WaitObject
aWait( rDocShell
.GetActiveDialogParent() );
4394 ScRange aSourceArea
= rRange
;
4395 ScRange aDestArea
= rRange
;
4397 SCSIZE nCount
= pDoc
->GetEmptyLinesInBlock(
4398 aSourceArea
.aStart
.Col(), aSourceArea
.aStart
.Row(), aSourceArea
.aStart
.Tab(),
4399 aSourceArea
.aEnd
.Col(), aSourceArea
.aEnd
.Row(), aSourceArea
.aEnd
.Tab(),
4400 DirFromFillDir(eDir
) );
4402 // mindestens eine Zeile/Spalte als Quellbereich behalten:
4403 SCSIZE nTotLines
= ( eDir
== FILL_TO_BOTTOM
|| eDir
== FILL_TO_TOP
) ?
4404 static_cast<SCSIZE
>( aSourceArea
.aEnd
.Row() - aSourceArea
.aStart
.Row() + 1 ) :
4405 static_cast<SCSIZE
>( aSourceArea
.aEnd
.Col() - aSourceArea
.aStart
.Col() + 1 );
4406 if ( nCount
>= nTotLines
)
4407 nCount
= nTotLines
- 1;
4411 case FILL_TO_BOTTOM
:
4412 aSourceArea
.aEnd
.SetRow( sal::static_int_cast
<SCROW
>( aSourceArea
.aEnd
.Row() - nCount
) );
4415 aSourceArea
.aEnd
.SetCol( sal::static_int_cast
<SCCOL
>( aSourceArea
.aEnd
.Col() - nCount
) );
4418 aSourceArea
.aStart
.SetRow( sal::static_int_cast
<SCROW
>( aSourceArea
.aStart
.Row() + nCount
) );
4421 aSourceArea
.aStart
.SetCol( sal::static_int_cast
<SCCOL
>( aSourceArea
.aStart
.Col() + nCount
) );
4425 ScDocument
* pUndoDoc
= NULL
;
4428 SCTAB nTabCount
= pDoc
->GetTableCount();
4429 SCTAB nDestStartTab
= aDestArea
.aStart
.Tab();
4431 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
4432 pUndoDoc
->InitUndo( pDoc
, nDestStartTab
, nDestStartTab
);
4433 ScMarkData::iterator itr
= aMark
.begin(), itrEnd
= aMark
.end();
4434 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
4435 if (*itr
!= nDestStartTab
)
4436 pUndoDoc
->AddUndoTab( *itr
, *itr
);
4438 pDoc
->CopyToDocument(
4439 aDestArea
.aStart
.Col(), aDestArea
.aStart
.Row(), 0,
4440 aDestArea
.aEnd
.Col(), aDestArea
.aEnd
.Row(), nTabCount
-1,
4441 IDF_AUTOFILL
, false, pUndoDoc
, &aMark
);
4444 if (aDestArea
.aStart
.Col() <= aDestArea
.aEnd
.Col() &&
4445 aDestArea
.aStart
.Row() <= aDestArea
.aEnd
.Row())
4447 if ( fStart
!= MAXDOUBLE
)
4449 SCCOL nValX
= (eDir
== FILL_TO_LEFT
) ? aDestArea
.aEnd
.Col() : aDestArea
.aStart
.Col();
4450 SCROW nValY
= (eDir
== FILL_TO_TOP
) ? aDestArea
.aEnd
.Row() : aDestArea
.aStart
.Row();
4451 SCTAB nTab
= aDestArea
.aStart
.Tab();
4452 pDoc
->SetValue( nValX
, nValY
, nTab
, fStart
);
4455 sal_uLong nProgCount
;
4456 if (eDir
== FILL_TO_BOTTOM
|| eDir
== FILL_TO_TOP
)
4457 nProgCount
= aSourceArea
.aEnd
.Col() - aSourceArea
.aStart
.Col() + 1;
4459 nProgCount
= aSourceArea
.aEnd
.Row() - aSourceArea
.aStart
.Row() + 1;
4460 nProgCount
*= nCount
;
4461 ScProgress
aProgress( pDoc
->GetDocumentShell(),
4462 ScGlobal::GetRscString(STR_FILL_SERIES_PROGRESS
), nProgCount
);
4464 pDoc
->Fill( aSourceArea
.aStart
.Col(), aSourceArea
.aStart
.Row(),
4465 aSourceArea
.aEnd
.Col(), aSourceArea
.aEnd
.Row(), &aProgress
,
4466 aMark
, nCount
, eDir
, eCmd
, eDateCmd
, fStep
, fMax
);
4467 AdjustRowHeight(rRange
);
4469 rDocShell
.PostPaintGridAll();
4470 aModificator
.SetDocumentModified();
4473 if ( bRecord
) // Draw-Undo erst jetzt verfuegbar
4475 rDocShell
.GetUndoManager()->AddUndoAction(
4476 new ScUndoAutoFill( &rDocShell
, aDestArea
, aSourceArea
, pUndoDoc
, aMark
,
4477 eDir
, eCmd
, eDateCmd
, fStart
, fStep
, fMax
) );
4483 rDocShell
.ErrorMessage(aTester
.GetMessageId());
4488 bool ScDocFunc::FillAuto( ScRange
& rRange
, const ScMarkData
* pTabMark
,
4489 FillDir eDir
, sal_uLong nCount
, bool bRecord
, bool bApi
)
4492 double fMax
= MAXDOUBLE
;
4493 return FillAuto( rRange
, pTabMark
, eDir
, FILL_AUTO
, FILL_DAY
, nCount
, fStep
, fMax
, bRecord
, bApi
);
4496 bool ScDocFunc::FillAuto( ScRange
& rRange
, const ScMarkData
* pTabMark
, FillDir eDir
, FillCmd eCmd
, FillDateCmd eDateCmd
, sal_uLong nCount
, double fStep
, double fMax
, bool bRecord
, bool bApi
)
4498 ScDocShellModificator
aModificator( rDocShell
);
4500 ScDocument
* pDoc
= rDocShell
.GetDocument();
4501 SCCOL nStartCol
= rRange
.aStart
.Col();
4502 SCROW nStartRow
= rRange
.aStart
.Row();
4503 SCTAB nStartTab
= rRange
.aStart
.Tab();
4504 SCCOL nEndCol
= rRange
.aEnd
.Col();
4505 SCROW nEndRow
= rRange
.aEnd
.Row();
4506 SCTAB nEndTab
= rRange
.aEnd
.Tab();
4508 if (bRecord
&& !pDoc
->IsUndoEnabled())
4516 for (SCTAB nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
4517 aMark
.SelectTable( nTab
, true );
4520 ScRange aSourceArea
= rRange
;
4521 ScRange aDestArea
= rRange
;
4526 case FILL_TO_BOTTOM
:
4527 aDestArea
.aEnd
.SetRow( sal::static_int_cast
<SCROW
>( aSourceArea
.aEnd
.Row() + nCount
) );
4530 if (nCount
> sal::static_int_cast
<sal_uLong
>( aSourceArea
.aStart
.Row() ))
4532 OSL_FAIL("FillAuto: Row < 0");
4533 nCount
= aSourceArea
.aStart
.Row();
4535 aDestArea
.aStart
.SetRow( sal::static_int_cast
<SCROW
>( aSourceArea
.aStart
.Row() - nCount
) );
4538 aDestArea
.aEnd
.SetCol( sal::static_int_cast
<SCCOL
>( aSourceArea
.aEnd
.Col() + nCount
) );
4541 if (nCount
> sal::static_int_cast
<sal_uLong
>( aSourceArea
.aStart
.Col() ))
4543 OSL_FAIL("FillAuto: Col < 0");
4544 nCount
= aSourceArea
.aStart
.Col();
4546 aDestArea
.aStart
.SetCol( sal::static_int_cast
<SCCOL
>( aSourceArea
.aStart
.Col() - nCount
) );
4549 OSL_FAIL("Falsche Richtung bei FillAuto");
4553 // Zellschutz testen
4554 //! Quellbereich darf geschuetzt sein !!!
4555 //! aber kein Matrixfragment enthalten !!!
4557 ScEditableTester
aTester( pDoc
, aDestArea
);
4558 if ( !aTester
.IsEditable() )
4561 rDocShell
.ErrorMessage(aTester
.GetMessageId());
4565 if ( pDoc
->HasSelectedBlockMatrixFragment( nStartCol
, nStartRow
,
4566 nEndCol
, nEndRow
, aMark
) )
4569 rDocShell
.ErrorMessage(STR_MATRIXFRAGMENTERR
);
4573 WaitObject
aWait( rDocShell
.GetActiveDialogParent() );
4575 ScDocument
* pUndoDoc
= NULL
;
4578 SCTAB nTabCount
= pDoc
->GetTableCount();
4579 SCTAB nDestStartTab
= aDestArea
.aStart
.Tab();
4581 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
4582 pUndoDoc
->InitUndo( pDoc
, nDestStartTab
, nDestStartTab
);
4583 ScMarkData::iterator itr
= aMark
.begin(), itrEnd
= aMark
.end();
4584 for (; itr
!= itrEnd
&& nTabCount
; ++itr
)
4585 if (*itr
!= nDestStartTab
)
4586 pUndoDoc
->AddUndoTab( *itr
, *itr
);
4588 // do not clone note captions in undo document
4589 pDoc
->CopyToDocument(
4590 aDestArea
.aStart
.Col(), aDestArea
.aStart
.Row(), 0,
4591 aDestArea
.aEnd
.Col(), aDestArea
.aEnd
.Row(), nTabCount
-1,
4592 IDF_AUTOFILL
, false, pUndoDoc
, &aMark
);
4595 sal_uLong nProgCount
;
4596 if (eDir
== FILL_TO_BOTTOM
|| eDir
== FILL_TO_TOP
)
4597 nProgCount
= aSourceArea
.aEnd
.Col() - aSourceArea
.aStart
.Col() + 1;
4599 nProgCount
= aSourceArea
.aEnd
.Row() - aSourceArea
.aStart
.Row() + 1;
4600 nProgCount
*= nCount
;
4601 ScProgress
aProgress( pDoc
->GetDocumentShell(),
4602 ScGlobal::GetRscString(STR_FILL_SERIES_PROGRESS
), nProgCount
);
4604 pDoc
->Fill( aSourceArea
.aStart
.Col(), aSourceArea
.aStart
.Row(),
4605 aSourceArea
.aEnd
.Col(), aSourceArea
.aEnd
.Row(), &aProgress
,
4606 aMark
, nCount
, eDir
, eCmd
, eDateCmd
, fStep
, fMax
);
4608 AdjustRowHeight(aDestArea
);
4610 if ( bRecord
) // Draw-Undo erst jetzt verfuegbar
4612 rDocShell
.GetUndoManager()->AddUndoAction(
4613 new ScUndoAutoFill( &rDocShell
, aDestArea
, aSourceArea
, pUndoDoc
, aMark
,
4614 eDir
, eCmd
, eDateCmd
, MAXDOUBLE
, fStep
, fMax
) );
4617 rDocShell
.PostPaintGridAll();
4618 aModificator
.SetDocumentModified();
4620 rRange
= aDestArea
; // Zielbereich zurueckgeben (zum Markieren)
4624 bool ScDocFunc::MergeCells( const ScCellMergeOption
& rOption
, bool bContents
, bool bRecord
, bool bApi
)
4628 ScDocShellModificator
aModificator( rDocShell
);
4630 SCCOL nStartCol
= rOption
.mnStartCol
;
4631 SCROW nStartRow
= rOption
.mnStartRow
;
4632 SCCOL nEndCol
= rOption
.mnEndCol
;
4633 SCROW nEndRow
= rOption
.mnEndRow
;
4634 if ((nStartCol
== nEndCol
&& nStartRow
== nEndRow
) || rOption
.maTabs
.empty())
4636 // Nothing to do. Bail out quick.
4640 ScDocument
* pDoc
= rDocShell
.GetDocument();
4641 set
<SCTAB
>::const_iterator itrBeg
= rOption
.maTabs
.begin(), itrEnd
= rOption
.maTabs
.end();
4642 SCTAB nTab1
= *itrBeg
, nTab2
= *rOption
.maTabs
.rbegin();
4644 if (bRecord
&& !pDoc
->IsUndoEnabled())
4647 for (set
<SCTAB
>::const_iterator itr
= itrBeg
; itr
!= itrEnd
; ++itr
)
4649 ScEditableTester
aTester( pDoc
, *itr
, nStartCol
, nStartRow
, nEndCol
, nEndRow
);
4650 if (!aTester
.IsEditable())
4653 rDocShell
.ErrorMessage(aTester
.GetMessageId());
4657 if ( pDoc
->HasAttrib( nStartCol
, nStartRow
, *itr
, nEndCol
, nEndRow
, *itr
,
4658 HASATTR_MERGED
| HASATTR_OVERLAPPED
) )
4660 // "Zusammenfassen nicht verschachteln !"
4662 rDocShell
.ErrorMessage(STR_MSSG_MERGECELLS_0
);
4667 ScDocument
* pUndoDoc
= NULL
;
4668 bool bNeedContentsUndo
= false;
4669 for (set
<SCTAB
>::const_iterator itr
= itrBeg
; itr
!= itrEnd
; ++itr
)
4672 bool bNeedContents
= bContents
&&
4673 ( !pDoc
->IsBlockEmpty( nTab
, nStartCol
,nStartRow
+1, nStartCol
,nEndRow
, true ) ||
4674 !pDoc
->IsBlockEmpty( nTab
, nStartCol
+1,nStartRow
, nEndCol
,nEndRow
, true ) );
4678 // test if the range contains other notes which also implies that we need an undo document
4679 bool bHasNotes
= false;
4680 for( ScAddress
aPos( nStartCol
, nStartRow
, nTab
); !bHasNotes
&& (aPos
.Col() <= nEndCol
); aPos
.IncCol() )
4681 for( aPos
.SetRow( nStartRow
); !bHasNotes
&& (aPos
.Row() <= nEndRow
); aPos
.IncRow() )
4682 bHasNotes
= ((aPos
.Col() != nStartCol
) || (aPos
.Row() != nStartRow
)) && (pDoc
->HasNote(aPos
));
4686 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
4687 pUndoDoc
->InitUndo(pDoc
, nTab1
, nTab2
);
4689 // note captions are collected by drawing undo
4690 pDoc
->CopyToDocument( nStartCol
, nStartRow
, nTab
, nEndCol
, nEndRow
, nTab
,
4691 IDF_ALL
|IDF_NOCAPTIONS
, false, pUndoDoc
);
4693 pDoc
->BeginDrawUndo();
4697 pDoc
->DoMergeContents( nTab
, nStartCol
,nStartRow
, nEndCol
,nEndRow
);
4698 pDoc
->DoMerge( nTab
, nStartCol
,nStartRow
, nEndCol
,nEndRow
);
4700 if (rOption
.mbCenter
)
4702 pDoc
->ApplyAttr( nStartCol
, nStartRow
, nTab
, SvxHorJustifyItem( SVX_HOR_JUSTIFY_CENTER
, ATTR_HOR_JUSTIFY
) );
4703 pDoc
->ApplyAttr( nStartCol
, nStartRow
, nTab
, SvxVerJustifyItem( SVX_VER_JUSTIFY_CENTER
, ATTR_VER_JUSTIFY
) );
4706 if ( !AdjustRowHeight( ScRange( 0,nStartRow
,nTab
, MAXCOL
,nEndRow
,nTab
) ) )
4707 rDocShell
.PostPaint( nStartCol
, nStartRow
, nTab
,
4708 nEndCol
, nEndRow
, nTab
, PAINT_GRID
);
4709 if (bNeedContents
|| rOption
.mbCenter
)
4711 ScRange
aRange(nStartCol
, nStartRow
, nTab
, nEndCol
, nEndRow
, nTab
);
4712 pDoc
->SetDirty(aRange
);
4715 bNeedContentsUndo
|= bNeedContents
;
4720 SdrUndoGroup
* pDrawUndo
= pDoc
->GetDrawLayer() ? pDoc
->GetDrawLayer()->GetCalcUndo() : NULL
;
4721 rDocShell
.GetUndoManager()->AddUndoAction(
4722 new ScUndoMerge(&rDocShell
, rOption
, bNeedContentsUndo
, pUndoDoc
, pDrawUndo
) );
4725 aModificator
.SetDocumentModified();
4727 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
4730 pBindings
->Invalidate( FID_MERGE_ON
);
4731 pBindings
->Invalidate( FID_MERGE_OFF
);
4732 pBindings
->Invalidate( FID_MERGE_TOGGLE
);
4738 bool ScDocFunc::UnmergeCells( const ScRange
& rRange
, bool bRecord
)
4740 ScCellMergeOption
aOption(rRange
.aStart
.Col(), rRange
.aStart
.Row(), rRange
.aEnd
.Col(), rRange
.aEnd
.Row());
4741 SCTAB nTab1
= rRange
.aStart
.Tab(), nTab2
= rRange
.aEnd
.Tab();
4742 for (SCTAB i
= nTab1
; i
<= nTab2
; ++i
)
4743 aOption
.maTabs
.insert(i
);
4745 return UnmergeCells(aOption
, bRecord
);
4748 bool ScDocFunc::UnmergeCells( const ScCellMergeOption
& rOption
, bool bRecord
)
4752 if (rOption
.maTabs
.empty())
4753 // Nothing to unmerge.
4756 ScDocShellModificator
aModificator( rDocShell
);
4757 ScDocument
* pDoc
= rDocShell
.GetDocument();
4759 if (bRecord
&& !pDoc
->IsUndoEnabled())
4762 ScDocument
* pUndoDoc
= NULL
;
4763 for (set
<SCTAB
>::const_iterator itr
= rOption
.maTabs
.begin(), itrEnd
= rOption
.maTabs
.end();
4764 itr
!= itrEnd
; ++itr
)
4767 ScRange aRange
= rOption
.getSingleRange(nTab
);
4768 if ( !pDoc
->HasAttrib(aRange
, HASATTR_MERGED
) )
4771 ScRange aExtended
= aRange
;
4772 pDoc
->ExtendMerge(aExtended
);
4773 ScRange aRefresh
= aExtended
;
4774 pDoc
->ExtendOverlapped(aRefresh
);
4780 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
4781 pUndoDoc
->InitUndo(pDoc
, *rOption
.maTabs
.begin(), *rOption
.maTabs
.rbegin());
4783 pDoc
->CopyToDocument(aExtended
, IDF_ATTRIB
, false, pUndoDoc
);
4786 const SfxPoolItem
& rDefAttr
= pDoc
->GetPool()->GetDefaultItem( ATTR_MERGE
);
4787 ScPatternAttr
aPattern( pDoc
->GetPool() );
4788 aPattern
.GetItemSet().Put( rDefAttr
);
4789 pDoc
->ApplyPatternAreaTab( aRange
.aStart
.Col(), aRange
.aStart
.Row(),
4790 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), nTab
,
4793 pDoc
->RemoveFlagsTab( aExtended
.aStart
.Col(), aExtended
.aStart
.Row(),
4794 aExtended
.aEnd
.Col(), aExtended
.aEnd
.Row(), nTab
,
4795 SC_MF_HOR
| SC_MF_VER
);
4797 pDoc
->ExtendMerge( aRefresh
, true );
4799 if ( !AdjustRowHeight( aExtended
) )
4800 rDocShell
.PostPaint( aExtended
, PAINT_GRID
);
4805 rDocShell
.GetUndoManager()->AddUndoAction(
4806 new ScUndoRemoveMerge( &rDocShell
, rOption
, pUndoDoc
) );
4808 aModificator
.SetDocumentModified();
4813 bool ScDocFunc::ModifyRangeNames( const ScRangeName
& rNewRanges
, SCTAB nTab
)
4815 return SetNewRangeNames( new ScRangeName(rNewRanges
), true, nTab
);
4818 bool ScDocFunc::SetNewRangeNames( ScRangeName
* pNewRanges
, bool bModifyDoc
, SCTAB nTab
) // takes ownership of pNewRanges
4820 ScDocShellModificator
aModificator( rDocShell
);
4822 OSL_ENSURE( pNewRanges
, "pNewRanges is 0" );
4823 ScDocument
* pDoc
= rDocShell
.GetDocument();
4824 bool bUndo(pDoc
->IsUndoEnabled());
4831 pOld
= pDoc
->GetRangeName(nTab
);
4835 pOld
= pDoc
->GetRangeName();
4837 ScRangeName
* pUndoRanges
= new ScRangeName(*pOld
);
4838 ScRangeName
* pRedoRanges
= new ScRangeName(*pNewRanges
);
4839 rDocShell
.GetUndoManager()->AddUndoAction(
4840 new ScUndoRangeNames( &rDocShell
, pUndoRanges
, pRedoRanges
, nTab
) );
4843 // #i55926# While loading XML, formula cells only have a single string token,
4844 // so CompileNameFormula would never find any name (index) tokens, and would
4845 // unnecessarily loop through all cells.
4846 bool bCompile
= ( !pDoc
->IsImportingXML() && pDoc
->GetNamedRangesLockCount() == 0 );
4849 pDoc
->PreprocessRangeNameUpdate();
4851 pDoc
->SetRangeName( nTab
, pNewRanges
); // takes ownership
4853 pDoc
->SetRangeName( pNewRanges
); // takes ownership
4855 pDoc
->CompileHybridFormula();
4859 aModificator
.SetDocumentModified();
4860 SFX_APP()->Broadcast( SfxSimpleHint(SC_HINT_AREAS_CHANGED
) );
4866 void ScDocFunc::ModifyAllRangeNames( const boost::ptr_map
<OUString
, ScRangeName
>& rRangeMap
)
4868 ScDocShellModificator
aModificator(rDocShell
);
4869 ScDocument
* pDoc
= rDocShell
.GetDocument();
4871 if (pDoc
->IsUndoEnabled())
4873 std::map
<OUString
, ScRangeName
*> aOldRangeMap
;
4874 pDoc
->GetRangeNameMap(aOldRangeMap
);
4875 rDocShell
.GetUndoManager()->AddUndoAction(
4876 new ScUndoAllRangeNames(&rDocShell
, aOldRangeMap
, rRangeMap
));
4879 pDoc
->PreprocessRangeNameUpdate();
4880 pDoc
->SetAllRangeNames(rRangeMap
);
4881 pDoc
->CompileHybridFormula();
4883 aModificator
.SetDocumentModified();
4884 SFX_APP()->Broadcast(SfxSimpleHint(SC_HINT_AREAS_CHANGED
));
4887 void ScDocFunc::CreateOneName( ScRangeName
& rList
,
4888 SCCOL nPosX
, SCROW nPosY
, SCTAB nTab
,
4889 SCCOL nX1
, SCROW nY1
, SCCOL nX2
, SCROW nY2
,
4890 bool& rCancel
, bool bApi
)
4895 ScDocument
* pDoc
= rDocShell
.GetDocument();
4896 if (!pDoc
->HasValueData( nPosX
, nPosY
, nTab
))
4898 OUString aName
= pDoc
->GetString(nPosX
, nPosY
, nTab
);
4899 ScRangeData::MakeValidName(aName
);
4900 if (!aName
.isEmpty())
4902 OUString
aContent(ScRange( nX1
, nY1
, nTab
, nX2
, nY2
, nTab
).Format(SCR_ABS_3D
, pDoc
));
4904 bool bInsert
= false;
4905 ScRangeData
* pOld
= rList
.findByUpperName(ScGlobal::pCharClass
->uppercase(aName
));
4909 pOld
->GetSymbol( aOldStr
);
4910 if (aOldStr
!= aContent
)
4913 bInsert
= true; // per API nicht nachfragen
4916 OUString aTemplate
= ScGlobal::GetRscString( STR_CREATENAME_REPLACE
);
4918 OUString aMessage
= aTemplate
.getToken( 0, '#' );
4920 aMessage
+= aTemplate
.getToken( 1, '#' );
4922 short nResult
= QueryBox( rDocShell
.GetActiveDialogParent(),
4923 WinBits(WB_YES_NO_CANCEL
| WB_DEF_YES
),
4924 aMessage
).Execute();
4925 if ( nResult
== RET_YES
)
4930 else if ( nResult
== RET_CANCEL
)
4940 ScRangeData
* pData
= new ScRangeData( pDoc
, aName
, aContent
,
4941 ScAddress( nPosX
, nPosY
, nTab
));
4942 if (!rList
.insert(pData
))
4951 bool ScDocFunc::CreateNames( const ScRange
& rRange
, sal_uInt16 nFlags
, bool bApi
, SCTAB aTab
)
4954 return false; // war nix
4956 ScDocShellModificator
aModificator( rDocShell
);
4959 SCCOL nStartCol
= rRange
.aStart
.Col();
4960 SCROW nStartRow
= rRange
.aStart
.Row();
4961 SCCOL nEndCol
= rRange
.aEnd
.Col();
4962 SCROW nEndRow
= rRange
.aEnd
.Row();
4963 SCTAB nTab
= rRange
.aStart
.Tab();
4964 OSL_ENSURE(rRange
.aEnd
.Tab() == nTab
, "CreateNames: mehrere Tabellen geht nicht");
4967 if ( nFlags
& ( NAME_TOP
| NAME_BOTTOM
) )
4968 if ( nStartRow
== nEndRow
)
4970 if ( nFlags
& ( NAME_LEFT
| NAME_RIGHT
) )
4971 if ( nStartCol
== nEndCol
)
4976 ScDocument
* pDoc
= rDocShell
.GetDocument();
4977 ScRangeName
* pNames
;
4979 pNames
= pDoc
->GetRangeName(nTab
);
4981 pNames
= pDoc
->GetRangeName();
4984 return false; // soll nicht sein
4985 ScRangeName
aNewRanges( *pNames
);
4987 bool bTop
= ( ( nFlags
& NAME_TOP
) != 0 );
4988 bool bLeft
= ( ( nFlags
& NAME_LEFT
) != 0 );
4989 bool bBottom
= ( ( nFlags
& NAME_BOTTOM
) != 0 );
4990 bool bRight
= ( ( nFlags
& NAME_RIGHT
) != 0 );
4992 SCCOL nContX1
= nStartCol
;
4993 SCROW nContY1
= nStartRow
;
4994 SCCOL nContX2
= nEndCol
;
4995 SCROW nContY2
= nEndRow
;
5006 bool bCancel
= false;
5011 for (i
=nContX1
; i
<=nContX2
; i
++)
5012 CreateOneName( aNewRanges
, i
,nStartRow
,nTab
, i
,nContY1
,i
,nContY2
, bCancel
, bApi
);
5014 for (j
=nContY1
; j
<=nContY2
; j
++)
5015 CreateOneName( aNewRanges
, nStartCol
,j
,nTab
, nContX1
,j
,nContX2
,j
, bCancel
, bApi
);
5017 for (i
=nContX1
; i
<=nContX2
; i
++)
5018 CreateOneName( aNewRanges
, i
,nEndRow
,nTab
, i
,nContY1
,i
,nContY2
, bCancel
, bApi
);
5020 for (j
=nContY1
; j
<=nContY2
; j
++)
5021 CreateOneName( aNewRanges
, nEndCol
,j
,nTab
, nContX1
,j
,nContX2
,j
, bCancel
, bApi
);
5023 if ( bTop
&& bLeft
)
5024 CreateOneName( aNewRanges
, nStartCol
,nStartRow
,nTab
, nContX1
,nContY1
,nContX2
,nContY2
, bCancel
, bApi
);
5025 if ( bTop
&& bRight
)
5026 CreateOneName( aNewRanges
, nEndCol
,nStartRow
,nTab
, nContX1
,nContY1
,nContX2
,nContY2
, bCancel
, bApi
);
5027 if ( bBottom
&& bLeft
)
5028 CreateOneName( aNewRanges
, nStartCol
,nEndRow
,nTab
, nContX1
,nContY1
,nContX2
,nContY2
, bCancel
, bApi
);
5029 if ( bBottom
&& bRight
)
5030 CreateOneName( aNewRanges
, nEndCol
,nEndRow
,nTab
, nContX1
,nContY1
,nContX2
,nContY2
, bCancel
, bApi
);
5032 bDone
= ModifyRangeNames( aNewRanges
, aTab
);
5034 aModificator
.SetDocumentModified();
5035 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED
) );
5041 bool ScDocFunc::InsertNameList( const ScAddress
& rStartPos
, bool bApi
)
5043 ScDocShellModificator
aModificator( rDocShell
);
5046 ScDocument
* pDoc
= rDocShell
.GetDocument();
5047 const bool bRecord
= pDoc
->IsUndoEnabled();
5048 SCTAB nTab
= rStartPos
.Tab();
5049 ScDocument
* pUndoDoc
= NULL
;
5051 //local names have higher priority than global names
5052 ScRangeName
* pLocalList
= pDoc
->GetRangeName(nTab
);
5053 sal_uInt16 nValidCount
= 0;
5054 ScRangeName::iterator itrLocalBeg
= pLocalList
->begin(), itrLocalEnd
= pLocalList
->end();
5055 for (ScRangeName::iterator itr
= itrLocalBeg
; itr
!= itrLocalEnd
; ++itr
)
5057 const ScRangeData
& r
= *itr
->second
;
5058 if (!r
.HasType(RT_DATABASE
))
5061 ScRangeName
* pList
= pDoc
->GetRangeName();
5062 ScRangeName::iterator itrBeg
= pList
->begin(), itrEnd
= pList
->end();
5063 for (ScRangeName::iterator itr
= itrBeg
; itr
!= itrEnd
; ++itr
)
5065 const ScRangeData
& r
= *itr
->second
;
5066 if (!r
.HasType(RT_DATABASE
) && !pLocalList
->findByUpperName(r
.GetUpperName()))
5072 SCCOL nStartCol
= rStartPos
.Col();
5073 SCROW nStartRow
= rStartPos
.Row();
5074 SCCOL nEndCol
= nStartCol
+ 1;
5075 SCROW nEndRow
= nStartRow
+ static_cast<SCROW
>(nValidCount
) - 1;
5077 ScEditableTester
aTester( pDoc
, nTab
, nStartCol
,nStartRow
, nEndCol
,nEndRow
);
5078 if (aTester
.IsEditable())
5082 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
5083 pUndoDoc
->InitUndo( pDoc
, nTab
, nTab
);
5084 pDoc
->CopyToDocument( nStartCol
,nStartRow
,nTab
, nEndCol
,nEndRow
,nTab
,
5085 IDF_ALL
, false, pUndoDoc
);
5087 pDoc
->BeginDrawUndo(); // wegen Hoehenanpassung
5090 boost::scoped_array
<ScRangeData
*> ppSortArray(new ScRangeData
* [ nValidCount
]);
5092 for (ScRangeName::iterator itr
= itrLocalBeg
; itr
!= itrLocalEnd
; ++itr
)
5094 ScRangeData
& r
= *itr
->second
;
5095 if (!r
.HasType(RT_DATABASE
))
5096 ppSortArray
[j
++] = &r
;
5098 for (ScRangeName::iterator itr
= itrBeg
; itr
!= itrEnd
; ++itr
)
5100 ScRangeData
& r
= *itr
->second
;
5101 if (!r
.HasType(RT_DATABASE
) && !pLocalList
->findByUpperName(itr
->first
))
5102 ppSortArray
[j
++] = &r
;
5104 qsort( (void*)ppSortArray
.get(), nValidCount
, sizeof(ScRangeData
*),
5105 &ScRangeData_QsortNameCompare
);
5107 OUStringBuffer aContent
;
5109 SCROW nOutRow
= nStartRow
;
5110 for (j
=0; j
<nValidCount
; j
++)
5112 ScRangeData
* pData
= ppSortArray
[j
];
5113 pData
->GetName(aName
);
5114 // relative Referenzen Excel-konform auf die linke Spalte anpassen:
5115 pData
->UpdateSymbol(aContent
, ScAddress( nStartCol
, nOutRow
, nTab
));
5116 aFormula
= "=" + aContent
.toString();
5117 ScSetStringParam aParam
;
5118 aParam
.setTextInput();
5119 pDoc
->SetString(ScAddress(nStartCol
,nOutRow
,nTab
), aName
, &aParam
);
5120 pDoc
->SetString(ScAddress(nEndCol
,nOutRow
,nTab
), aFormula
, &aParam
);
5124 ppSortArray
.reset();
5128 ScDocument
* pRedoDoc
= new ScDocument( SCDOCMODE_UNDO
);
5129 pRedoDoc
->InitUndo( pDoc
, nTab
, nTab
);
5130 pDoc
->CopyToDocument( nStartCol
,nStartRow
,nTab
, nEndCol
,nEndRow
,nTab
,
5131 IDF_ALL
, false, pRedoDoc
);
5133 rDocShell
.GetUndoManager()->AddUndoAction(
5134 new ScUndoListNames( &rDocShell
,
5135 ScRange( nStartCol
,nStartRow
,nTab
, nEndCol
,nEndRow
,nTab
),
5136 pUndoDoc
, pRedoDoc
) );
5139 if (!AdjustRowHeight(ScRange(0,nStartRow
,nTab
,MAXCOL
,nEndRow
,nTab
)))
5140 rDocShell
.PostPaint( nStartCol
,nStartRow
,nTab
, nEndCol
,nEndRow
,nTab
, PAINT_GRID
);
5142 aModificator
.SetDocumentModified();
5146 rDocShell
.ErrorMessage(aTester
.GetMessageId());
5151 bool ScDocFunc::ResizeMatrix( const ScRange
& rOldRange
, const ScAddress
& rNewEnd
, bool bApi
)
5153 ScDocument
* pDoc
= rDocShell
.GetDocument();
5154 SCCOL nStartCol
= rOldRange
.aStart
.Col();
5155 SCROW nStartRow
= rOldRange
.aStart
.Row();
5156 SCTAB nTab
= rOldRange
.aStart
.Tab();
5158 bool bUndo(pDoc
->IsUndoEnabled());
5163 pDoc
->GetFormula( nStartCol
, nStartRow
, nTab
, aFormula
);
5164 if ( aFormula
.startsWith("{") && aFormula
.endsWith("}") )
5166 OUString aUndo
= ScGlobal::GetRscString( STR_UNDO_RESIZEMATRIX
);
5168 rDocShell
.GetUndoManager()->EnterListAction( aUndo
, aUndo
);
5170 aFormula
= aFormula
.copy(1, aFormula
.getLength()-2);
5173 aMark
.SetMarkArea( rOldRange
);
5174 aMark
.SelectTable( nTab
, true );
5175 ScRange
aNewRange( rOldRange
.aStart
, rNewEnd
);
5177 if ( DeleteContents( aMark
, IDF_CONTENTS
, true, bApi
) )
5179 // GRAM_PODF_A1 for API compatibility.
5180 bRet
= EnterMatrix( aNewRange
, &aMark
, NULL
, aFormula
, bApi
, false, EMPTY_OUSTRING
, formula::FormulaGrammar::GRAM_PODF_A1
);
5183 // versuchen, alten Zustand wiederherzustellen
5184 EnterMatrix( rOldRange
, &aMark
, NULL
, aFormula
, bApi
, false, EMPTY_OUSTRING
, formula::FormulaGrammar::GRAM_PODF_A1
);
5189 rDocShell
.GetUndoManager()->LeaveListAction();
5195 bool ScDocFunc::InsertAreaLink( const OUString
& rFile
, const OUString
& rFilter
,
5196 const OUString
& rOptions
, const OUString
& rSource
,
5197 const ScRange
& rDestRange
, sal_uLong nRefresh
,
5198 bool bFitBlock
, bool bApi
)
5200 ScDocument
* pDoc
= rDocShell
.GetDocument();
5201 bool bUndo (pDoc
->IsUndoEnabled());
5203 sfx2::LinkManager
* pLinkManager
= pDoc
->GetLinkManager();
5205 // #i52120# if other area links exist at the same start position,
5206 // remove them first (file format specifies only one link definition
5209 sal_uInt16 nLinkCount
= pLinkManager
->GetLinks().size();
5210 sal_uInt16 nRemoved
= 0;
5211 sal_uInt16 nLinkPos
= 0;
5212 while (nLinkPos
<nLinkCount
)
5214 ::sfx2::SvBaseLink
* pBase
= *pLinkManager
->GetLinks()[nLinkPos
];
5215 if ( pBase
->ISA(ScAreaLink
) &&
5216 static_cast<ScAreaLink
*>(pBase
)->GetDestArea().aStart
== rDestRange
.aStart
)
5222 // group all remove and the insert action
5223 OUString aUndo
= ScGlobal::GetRscString( STR_UNDO_INSERTAREALINK
);
5224 rDocShell
.GetUndoManager()->EnterListAction( aUndo
, aUndo
);
5227 ScAreaLink
* pOldArea
= static_cast<ScAreaLink
*>(pBase
);
5228 rDocShell
.GetUndoManager()->AddUndoAction(
5229 new ScUndoRemoveAreaLink( &rDocShell
,
5230 pOldArea
->GetFile(), pOldArea
->GetFilter(), pOldArea
->GetOptions(),
5231 pOldArea
->GetSource(), pOldArea
->GetDestArea(), pOldArea
->GetRefreshDelay() ) );
5233 pLinkManager
->Remove( pBase
);
5234 nLinkCount
= pLinkManager
->GetLinks().size();
5241 OUString aFilterName
= rFilter
;
5242 OUString aNewOptions
= rOptions
;
5243 if (aFilterName
.isEmpty())
5244 ScDocumentLoader::GetFilterName( rFile
, aFilterName
, aNewOptions
, true, !bApi
);
5246 // remove application prefix from filter name here, so the filter options
5247 // aren't reset when the filter name is changed in ScAreaLink::DataChanged
5248 ScDocumentLoader::RemoveAppPrefix( aFilterName
);
5250 ScAreaLink
* pLink
= new ScAreaLink( &rDocShell
, rFile
, aFilterName
,
5251 aNewOptions
, rSource
, rDestRange
, nRefresh
);
5252 OUString aTmp
= aFilterName
;
5253 pLinkManager
->InsertFileLink( *pLink
, OBJECT_CLIENT_FILE
, rFile
, &aTmp
, &rSource
);
5255 // Undo fuer den leeren Link
5259 rDocShell
.GetUndoManager()->AddUndoAction( new ScUndoInsertAreaLink( &rDocShell
,
5260 rFile
, aFilterName
, aNewOptions
,
5261 rSource
, rDestRange
, nRefresh
) );
5263 rDocShell
.GetUndoManager()->LeaveListAction(); // undo for link update is still separate
5266 // Update hat sein eigenes Undo
5267 if (pDoc
->IsExecuteLinkEnabled())
5269 pLink
->SetDoInsert(bFitBlock
); // beim ersten Update ggf. nichts einfuegen
5270 pLink
->Update(); // kein SetInCreate -> Update ausfuehren
5272 pLink
->SetDoInsert(true); // Default = true
5274 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
5276 pBindings
->Invalidate( SID_LINKS
);
5278 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED
) ); // Navigator
5285 void RemoveCondFormatAttributes(ScDocument
* pDoc
, const ScConditionalFormat
* pFormat
, SCTAB nTab
)
5287 const ScRangeList
& rRangeList
= pFormat
->GetRange();
5288 pDoc
->RemoveCondFormatData( rRangeList
, nTab
, pFormat
->GetKey() );
5291 void SetConditionalFormatAttributes(ScDocument
* pDoc
, const ScRangeList
& rRanges
, sal_uLong nIndex
, SCTAB nTab
)
5293 pDoc
->AddCondFormatData( rRanges
, nTab
, nIndex
);
5298 void ScDocFunc::ReplaceConditionalFormat( sal_uLong nOldFormat
, ScConditionalFormat
* pFormat
, SCTAB nTab
, const ScRangeList
& rRanges
)
5300 ScDocShellModificator
aModificator(rDocShell
);
5301 ScDocument
* pDoc
= rDocShell
.GetDocument();
5302 if(pDoc
->IsTabProtected(nTab
))
5305 bool bUndo
= pDoc
->IsUndoEnabled();
5306 ScDocument
* pUndoDoc
= NULL
;
5307 ScRange aCombinedRange
= rRanges
.Combine();
5308 ScRange aCompleteRange
;
5311 pUndoDoc
= new ScDocument(SCDOCMODE_UNDO
);
5312 pUndoDoc
->InitUndo( pDoc
, nTab
, nTab
);
5316 aCompleteRange
= aCombinedRange
;
5320 ScConditionalFormat
* pOldFormat
= pDoc
->GetCondFormList(nTab
)->GetFormat(nOldFormat
);
5322 aCompleteRange
.ExtendTo(pOldFormat
->GetRange().Combine());
5325 pDoc
->CopyToDocument( aCompleteRange
.aStart
.Col(),aCompleteRange
.aStart
.Row(),nTab
,
5326 aCompleteRange
.aEnd
.Col(),aCompleteRange
.aEnd
.Row(),nTab
,
5327 IDF_ALL
, false, pUndoDoc
);
5330 boost::scoped_ptr
<ScRange
> pRepaintRange
;
5333 ScConditionalFormat
* pOldFormat
= pDoc
->GetCondFormList(nTab
)->GetFormat(nOldFormat
);
5336 pRepaintRange
.reset(new ScRange( pOldFormat
->GetRange().Combine() ));
5337 RemoveCondFormatAttributes(pDoc
, pOldFormat
, nTab
);
5340 pDoc
->DeleteConditionalFormat(nOldFormat
, nTab
);
5341 pDoc
->SetStreamValid(nTab
, false);
5346 pRepaintRange
->ExtendTo(aCombinedRange
);
5348 pRepaintRange
.reset(new ScRange(aCombinedRange
));
5350 sal_uLong nIndex
= pDoc
->AddCondFormat(pFormat
, nTab
);
5352 SetConditionalFormatAttributes(pDoc
, rRanges
, nIndex
, nTab
);
5353 pDoc
->SetStreamValid(nTab
, false);
5358 ScDocument
* pRedoDoc
= new ScDocument(SCDOCMODE_UNDO
);
5359 pRedoDoc
->InitUndo( pDoc
, nTab
, nTab
);
5360 pDoc
->CopyToDocument( aCompleteRange
.aStart
.Col(),aCompleteRange
.aStart
.Row(),nTab
,
5361 aCompleteRange
.aEnd
.Col(),aCompleteRange
.aEnd
.Row(),nTab
,
5362 IDF_ALL
, false, pRedoDoc
);
5363 rDocShell
.GetUndoManager()->AddUndoAction(
5364 new ScUndoConditionalFormat(&rDocShell
, pUndoDoc
, pRedoDoc
, aCompleteRange
));
5368 rDocShell
.PostPaint(*pRepaintRange
, PAINT_GRID
);
5370 aModificator
.SetDocumentModified();
5371 SFX_APP()->Broadcast(SfxSimpleHint(SC_HINT_AREAS_CHANGED
));
5374 void ScDocFunc::SetConditionalFormatList( ScConditionalFormatList
* pList
, SCTAB nTab
)
5376 ScDocShellModificator
aModificator(rDocShell
);
5377 ScDocument
* pDoc
= rDocShell
.GetDocument();
5378 if(pDoc
->IsTabProtected(nTab
))
5381 // first remove all old entries
5382 ScConditionalFormatList
* pOldList
= pDoc
->GetCondFormList(nTab
);
5383 for(ScConditionalFormatList::const_iterator itr
= pOldList
->begin(), itrEnd
= pOldList
->end(); itr
!= itrEnd
; ++itr
)
5385 RemoveCondFormatAttributes(pDoc
, &(*itr
), nTab
);
5388 // then set new entries
5389 for(ScConditionalFormatList::iterator itr
= pList
->begin(); itr
!= pList
->end(); ++itr
)
5391 sal_uLong nIndex
= itr
->GetKey();
5392 const ScRangeList
& rRange
= itr
->GetRange();
5393 SetConditionalFormatAttributes(pDoc
, rRange
, nIndex
, nTab
);
5396 pDoc
->SetCondFormList(pList
, nTab
);
5397 rDocShell
.PostPaintGridAll();
5399 pDoc
->SetStreamValid(nTab
, false);
5400 aModificator
.SetDocumentModified();
5401 SFX_APP()->Broadcast(SfxSimpleHint(SC_HINT_AREAS_CHANGED
));
5404 void ScDocFunc::EnterListAction( sal_uInt16 nNameResId
)
5406 OUString
aUndo( ScGlobal::GetRscString( nNameResId
) );
5407 rDocShell
.GetUndoManager()->EnterListAction( aUndo
, aUndo
);
5410 void ScDocFunc::EndListAction()
5412 rDocShell
.GetUndoManager()->LeaveListAction();
5415 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */