1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: docfunc.cxx,v $
10 * $Revision: 1.70.100.10 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 // INCLUDE ---------------------------------------------------------------
38 #include "scitems.hxx"
39 #include <svx/eeitem.hxx>
41 #include <sfx2/app.hxx>
42 #include <svx/editobj.hxx>
43 #include <svx/linkmgr.hxx>
44 #include <svx/svdundo.hxx>
45 #include <sfx2/bindings.hxx>
46 #include <sfx2/printer.hxx>
47 #include <vcl/msgbox.hxx>
48 #include <vcl/sound.hxx>
49 #include <vcl/virdev.hxx>
50 #include <vcl/waitobj.hxx>
51 #include <svtools/zforlist.hxx>
52 #include <svtools/PasswordHelper.hxx>
54 #include <basic/sbstar.hxx>
55 #include <com/sun/star/container/XNameContainer.hpp>
56 #include <com/sun/star/script/XLibraryContainer.hpp>
57 #include <com/sun/star/script/ModuleInfo.hpp>
58 #include <com/sun/star/script/ModuleType.hpp>
62 #include "docfunc.hxx"
66 #include "arealink.hxx"
68 #include "dociter.hxx"
69 #include "autoform.hxx"
71 #include "cellmergeoption.hxx"
72 #include "detdata.hxx"
73 #include "detfunc.hxx"
74 #include "docpool.hxx"
76 #include "drwlayer.hxx"
77 #include "editutil.hxx"
78 #include "globstr.hrc"
79 //CHINA001 #include "namecrea.hxx" // NAME_TOP etc.
80 #include "olinetab.hxx"
81 #include "patattr.hxx"
82 #include "rangenam.hxx"
83 #include "rangeutl.hxx"
84 #include "refundo.hxx"
85 #include "scresid.hxx"
86 #include "stlpool.hxx"
87 #include "stlsheet.hxx"
88 #include "tablink.hxx"
89 #include "tabvwsh.hxx"
90 #include "uiitems.hxx"
91 #include "undoblk.hxx"
92 #include "undocell.hxx"
93 #include "undodraw.hxx"
94 #include "undotab.hxx"
95 #include "waitoff.hxx"
96 #include "sizedev.hxx"
98 #include "inputhdl.hxx"
99 #include "inputwin.hxx"
100 #include "editable.hxx"
101 #include "compiler.hxx"
102 #include "scui_def.hxx" //CHINA001
103 #include "tabprotection.hxx"
104 #include "clipparam.hxx"
109 using namespace com::sun::star
;
110 using ::com::sun::star::uno::Sequence
;
114 // STATIC DATA -----------------------------------------------------------
116 //========================================================================
118 IMPL_LINK( ScDocFunc
, NotifyDrawUndo
, SdrUndoAction
*, pUndoAction
)
120 // #i101118# if drawing layer collects the undo actions, add it there
121 ScDrawLayer
* pDrawLayer
= rDocShell
.GetDocument()->GetDrawLayer();
122 if( pDrawLayer
&& pDrawLayer
->IsRecording() )
123 pDrawLayer
->AddCalcUndo( pUndoAction
);
125 rDocShell
.GetUndoManager()->AddUndoAction( new ScUndoDraw( pUndoAction
, &rDocShell
) );
126 rDocShell
.SetDrawModified();
128 // the affected sheet isn't known, so all stream positions are invalidated
129 ScDocument
* pDoc
= rDocShell
.GetDocument();
130 SCTAB nTabCount
= pDoc
->GetTableCount();
131 for (SCTAB nTab
=0; nTab
<nTabCount
; nTab
++)
132 if (pDoc
->IsStreamValid(nTab
))
133 pDoc
->SetStreamValid(nTab
, FALSE
);
138 //------------------------------------------------------------------------
140 // Zeile ueber dem Range painten (fuer Linien nach AdjustRowHeight)
142 void lcl_PaintAbove( ScDocShell
& rDocShell
, const ScRange
& rRange
)
144 SCROW nRow
= rRange
.aStart
.Row();
147 SCTAB nTab
= rRange
.aStart
.Tab(); //! alle?
149 rDocShell
.PostPaint( ScRange(0,nRow
,nTab
, MAXCOL
,nRow
,nTab
), PAINT_GRID
);
153 //------------------------------------------------------------------------
155 BOOL
ScDocFunc::AdjustRowHeight( const ScRange
& rRange
, BOOL bPaint
)
157 ScDocument
* pDoc
= rDocShell
.GetDocument();
158 if ( pDoc
->IsImportingXML() )
160 // for XML import, all row heights are updated together after importing
163 if ( !pDoc
->IsAdjustHeightEnabled() )
168 SCTAB nTab
= rRange
.aStart
.Tab();
169 SCROW nStartRow
= rRange
.aStart
.Row();
170 SCROW nEndRow
= rRange
.aEnd
.Row();
172 ScSizeDeviceProvider
aProv( &rDocShell
);
175 BOOL bChanged
= pDoc
->SetOptimalHeight( nStartRow
, nEndRow
, nTab
, 0, aProv
.GetDevice(),
176 aProv
.GetPPTX(), aProv
.GetPPTY(), aOne
, aOne
, FALSE
);
178 if ( bPaint
&& bChanged
)
179 rDocShell
.PostPaint( 0, nStartRow
, nTab
, MAXCOL
, MAXROW
, nTab
,
180 PAINT_GRID
| PAINT_LEFT
);
186 //------------------------------------------------------------------------
188 BOOL
ScDocFunc::DetectiveAddPred(const ScAddress
& rPos
)
190 ScDocShellModificator
aModificator( rDocShell
);
192 rDocShell
.MakeDrawLayer();
193 ScDocument
* pDoc
= rDocShell
.GetDocument();
194 BOOL
bUndo (pDoc
->IsUndoEnabled());
195 ScDrawLayer
* pModel
= pDoc
->GetDrawLayer();
196 SCCOL nCol
= rPos
.Col();
197 SCROW nRow
= rPos
.Row();
198 SCTAB nTab
= rPos
.Tab();
201 pModel
->BeginCalcUndo();
202 BOOL bDone
= ScDetectiveFunc( pDoc
,nTab
).ShowPred( nCol
, nRow
);
203 SdrUndoGroup
* pUndo
= NULL
;
205 pUndo
= pModel
->GetCalcUndo();
208 ScDetOpData
aOperation( ScAddress(nCol
,nRow
,nTab
), SCDETOP_ADDPRED
);
209 pDoc
->AddDetectiveOperation( aOperation
);
212 rDocShell
.GetUndoManager()->AddUndoAction(
213 new ScUndoDetective( &rDocShell
, pUndo
, &aOperation
) );
215 aModificator
.SetDocumentModified();
216 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
218 pBindings
->Invalidate( SID_DETECTIVE_REFRESH
);
226 BOOL
ScDocFunc::DetectiveDelPred(const ScAddress
& rPos
)
228 ScDocument
* pDoc
= rDocShell
.GetDocument();
230 BOOL
bUndo(pDoc
->IsUndoEnabled());
231 ScDrawLayer
* pModel
= pDoc
->GetDrawLayer();
235 ScDocShellModificator
aModificator( rDocShell
);
237 SCCOL nCol
= rPos
.Col();
238 SCROW nRow
= rPos
.Row();
239 SCTAB nTab
= rPos
.Tab();
242 pModel
->BeginCalcUndo();
243 BOOL bDone
= ScDetectiveFunc( pDoc
,nTab
).DeletePred( nCol
, nRow
);
244 SdrUndoGroup
* pUndo
= NULL
;
246 pUndo
= pModel
->GetCalcUndo();
249 ScDetOpData
aOperation( ScAddress(nCol
,nRow
,nTab
), SCDETOP_DELPRED
);
250 pDoc
->AddDetectiveOperation( aOperation
);
253 rDocShell
.GetUndoManager()->AddUndoAction(
254 new ScUndoDetective( &rDocShell
, pUndo
, &aOperation
) );
256 aModificator
.SetDocumentModified();
257 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
259 pBindings
->Invalidate( SID_DETECTIVE_REFRESH
);
267 BOOL
ScDocFunc::DetectiveAddSucc(const ScAddress
& rPos
)
269 ScDocShellModificator
aModificator( rDocShell
);
271 rDocShell
.MakeDrawLayer();
272 ScDocument
* pDoc
= rDocShell
.GetDocument();
274 BOOL
bUndo(pDoc
->IsUndoEnabled());
275 ScDrawLayer
* pModel
= pDoc
->GetDrawLayer();
276 SCCOL nCol
= rPos
.Col();
277 SCROW nRow
= rPos
.Row();
278 SCTAB nTab
= rPos
.Tab();
281 pModel
->BeginCalcUndo();
282 BOOL bDone
= ScDetectiveFunc( pDoc
,nTab
).ShowSucc( nCol
, nRow
);
283 SdrUndoGroup
* pUndo
= NULL
;
285 pUndo
= pModel
->GetCalcUndo();
288 ScDetOpData
aOperation( ScAddress(nCol
,nRow
,nTab
), SCDETOP_ADDSUCC
);
289 pDoc
->AddDetectiveOperation( aOperation
);
292 rDocShell
.GetUndoManager()->AddUndoAction(
293 new ScUndoDetective( &rDocShell
, pUndo
, &aOperation
) );
295 aModificator
.SetDocumentModified();
296 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
298 pBindings
->Invalidate( SID_DETECTIVE_REFRESH
);
306 BOOL
ScDocFunc::DetectiveDelSucc(const ScAddress
& rPos
)
308 ScDocument
* pDoc
= rDocShell
.GetDocument();
310 BOOL
bUndo (pDoc
->IsUndoEnabled());
311 ScDrawLayer
* pModel
= pDoc
->GetDrawLayer();
315 ScDocShellModificator
aModificator( rDocShell
);
317 SCCOL nCol
= rPos
.Col();
318 SCROW nRow
= rPos
.Row();
319 SCTAB nTab
= rPos
.Tab();
322 pModel
->BeginCalcUndo();
323 BOOL bDone
= ScDetectiveFunc( pDoc
,nTab
).DeleteSucc( nCol
, nRow
);
324 SdrUndoGroup
* pUndo
= NULL
;
326 pUndo
= pModel
->GetCalcUndo();
329 ScDetOpData
aOperation( ScAddress(nCol
,nRow
,nTab
), SCDETOP_DELSUCC
);
330 pDoc
->AddDetectiveOperation( aOperation
);
333 rDocShell
.GetUndoManager()->AddUndoAction(
334 new ScUndoDetective( &rDocShell
, pUndo
, &aOperation
) );
336 aModificator
.SetDocumentModified();
337 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
339 pBindings
->Invalidate( SID_DETECTIVE_REFRESH
);
347 BOOL
ScDocFunc::DetectiveAddError(const ScAddress
& rPos
)
349 ScDocShellModificator
aModificator( rDocShell
);
351 rDocShell
.MakeDrawLayer();
352 ScDocument
* pDoc
= rDocShell
.GetDocument();
354 BOOL
bUndo (pDoc
->IsUndoEnabled());
355 ScDrawLayer
* pModel
= pDoc
->GetDrawLayer();
356 SCCOL nCol
= rPos
.Col();
357 SCROW nRow
= rPos
.Row();
358 SCTAB nTab
= rPos
.Tab();
361 pModel
->BeginCalcUndo();
362 BOOL bDone
= ScDetectiveFunc( pDoc
,nTab
).ShowError( nCol
, nRow
);
363 SdrUndoGroup
* pUndo
= NULL
;
365 pUndo
= pModel
->GetCalcUndo();
368 ScDetOpData
aOperation( ScAddress(nCol
,nRow
,nTab
), SCDETOP_ADDERROR
);
369 pDoc
->AddDetectiveOperation( aOperation
);
372 rDocShell
.GetUndoManager()->AddUndoAction(
373 new ScUndoDetective( &rDocShell
, pUndo
, &aOperation
) );
375 aModificator
.SetDocumentModified();
376 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
378 pBindings
->Invalidate( SID_DETECTIVE_REFRESH
);
386 BOOL
ScDocFunc::DetectiveMarkInvalid(SCTAB nTab
)
388 ScDocShellModificator
aModificator( rDocShell
);
390 rDocShell
.MakeDrawLayer();
391 ScDocument
* pDoc
= rDocShell
.GetDocument();
393 BOOL
bUndo (pDoc
->IsUndoEnabled());
394 ScDrawLayer
* pModel
= pDoc
->GetDrawLayer();
396 Window
* pWaitWin
= rDocShell
.GetActiveDialogParent();
398 pWaitWin
->EnterWait();
400 pModel
->BeginCalcUndo();
402 BOOL bDone
= ScDetectiveFunc( pDoc
,nTab
).MarkInvalid( bOverflow
);
403 SdrUndoGroup
* pUndo
= NULL
;
405 pUndo
= pModel
->GetCalcUndo();
407 pWaitWin
->LeaveWait();
412 pUndo
->SetComment( ScGlobal::GetRscString( STR_UNDO_DETINVALID
) );
413 rDocShell
.GetUndoManager()->AddUndoAction( pUndo
);
415 aModificator
.SetDocumentModified();
419 ScGlobal::GetRscString( STR_DETINVALID_OVERFLOW
) ).Execute();
428 BOOL
ScDocFunc::DetectiveDelAll(SCTAB nTab
)
430 ScDocument
* pDoc
= rDocShell
.GetDocument();
432 BOOL
bUndo (pDoc
->IsUndoEnabled());
433 ScDrawLayer
* pModel
= pDoc
->GetDrawLayer();
437 ScDocShellModificator
aModificator( rDocShell
);
440 pModel
->BeginCalcUndo();
441 BOOL bDone
= ScDetectiveFunc( pDoc
,nTab
).DeleteAll( SC_DET_DETECTIVE
);
442 SdrUndoGroup
* pUndo
= NULL
;
444 pUndo
= pModel
->GetCalcUndo();
447 ScDetOpList
* pOldList
= pDoc
->GetDetOpList();
448 ScDetOpList
* pUndoList
= NULL
;
450 pUndoList
= pOldList
? new ScDetOpList(*pOldList
) : NULL
;
452 pDoc
->ClearDetectiveOperations();
456 rDocShell
.GetUndoManager()->AddUndoAction(
457 new ScUndoDetective( &rDocShell
, pUndo
, NULL
, pUndoList
) );
459 aModificator
.SetDocumentModified();
460 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
462 pBindings
->Invalidate( SID_DETECTIVE_REFRESH
);
470 BOOL
ScDocFunc::DetectiveRefresh( BOOL bAutomatic
)
473 ScDocument
* pDoc
= rDocShell
.GetDocument();
475 BOOL
bUndo (pDoc
->IsUndoEnabled());
476 ScDetOpList
* pList
= pDoc
->GetDetOpList();
477 if ( pList
&& pList
->Count() )
479 rDocShell
.MakeDrawLayer();
480 ScDrawLayer
* pModel
= pDoc
->GetDrawLayer();
482 pModel
->BeginCalcUndo();
484 // Loeschen auf allen Tabellen
486 SCTAB nTabCount
= pDoc
->GetTableCount();
487 for (SCTAB nTab
=0; nTab
<nTabCount
; nTab
++)
488 ScDetectiveFunc( pDoc
,nTab
).DeleteAll( SC_DET_ARROWS
); // don't remove circles
492 USHORT nCount
= pList
->Count();
493 for (USHORT i
=0; i
<nCount
; i
++)
495 ScDetOpData
* pData
= (*pList
)[i
];
498 ScAddress aPos
= pData
->GetPos();
499 ScDetectiveFunc
aFunc( pDoc
, aPos
.Tab() );
500 SCCOL nCol
= aPos
.Col();
501 SCROW nRow
= aPos
.Row();
502 switch (pData
->GetOperation())
504 case SCDETOP_ADDSUCC
:
505 aFunc
.ShowSucc( nCol
, nRow
);
507 case SCDETOP_DELSUCC
:
508 aFunc
.DeleteSucc( nCol
, nRow
);
510 case SCDETOP_ADDPRED
:
511 aFunc
.ShowPred( nCol
, nRow
);
513 case SCDETOP_DELPRED
:
514 aFunc
.DeletePred( nCol
, nRow
);
516 case SCDETOP_ADDERROR
:
517 aFunc
.ShowError( nCol
, nRow
);
520 DBG_ERROR("falsche Op bei DetectiveRefresh");
527 SdrUndoGroup
* pUndo
= pModel
->GetCalcUndo();
530 pUndo
->SetComment( ScGlobal::GetRscString( STR_UNDO_DETREFRESH
) );
531 // wenn automatisch, an letzte Aktion anhaengen
532 rDocShell
.GetUndoManager()->AddUndoAction(
533 new ScUndoDraw( pUndo
, &rDocShell
),
537 rDocShell
.SetDrawModified();
543 static void lcl_collectAllPredOrSuccRanges(
544 const ScRangeList
& rSrcRanges
, vector
<ScSharedTokenRef
>& rRefTokens
, ScDocShell
& rDocShell
,
547 ScDocument
* pDoc
= rDocShell
.GetDocument();
548 vector
<ScSharedTokenRef
> aRefTokens
;
549 ScRangeList
aSrcRanges(rSrcRanges
);
550 ScRange
* p
= aSrcRanges
.First();
553 ScDetectiveFunc
aDetFunc(pDoc
, p
->aStart
.Tab());
554 ScRangeList aDestRanges
;
555 for (; p
; p
= aSrcRanges
.Next())
559 aDetFunc
.GetAllPreds(
560 p
->aStart
.Col(), p
->aStart
.Row(), p
->aEnd
.Col(), p
->aEnd
.Row(), aRefTokens
);
564 aDetFunc
.GetAllSuccs(
565 p
->aStart
.Col(), p
->aStart
.Row(), p
->aEnd
.Col(), p
->aEnd
.Row(), aRefTokens
);
568 rRefTokens
.swap(aRefTokens
);
571 void ScDocFunc::DetectiveCollectAllPreds(const ScRangeList
& rSrcRanges
, vector
<ScSharedTokenRef
>& rRefTokens
)
573 lcl_collectAllPredOrSuccRanges(rSrcRanges
, rRefTokens
, rDocShell
, true);
576 void ScDocFunc::DetectiveCollectAllSuccs(const ScRangeList
& rSrcRanges
, vector
<ScSharedTokenRef
>& rRefTokens
)
578 lcl_collectAllPredOrSuccRanges(rSrcRanges
, rRefTokens
, rDocShell
, false);
581 //------------------------------------------------------------------------
583 BOOL
ScDocFunc::DeleteContents( const ScMarkData
& rMark
, USHORT nFlags
,
584 BOOL bRecord
, BOOL bApi
)
586 ScDocShellModificator
aModificator( rDocShell
);
588 if ( !rMark
.IsMarked() && !rMark
.IsMultiMarked() )
590 DBG_ERROR("ScDocFunc::DeleteContents ohne Markierung");
594 ScDocument
* pDoc
= rDocShell
.GetDocument();
596 if (bRecord
&& !pDoc
->IsUndoEnabled())
599 ScEditableTester
aTester( pDoc
, rMark
);
600 if (!aTester
.IsEditable())
603 rDocShell
.ErrorMessage(aTester
.GetMessageId());
608 BOOL bSimple
= FALSE
;
610 ScMarkData aMultiMark
= rMark
;
611 aMultiMark
.SetMarking(FALSE
); // fuer MarkToMulti
613 ScDocument
* pUndoDoc
= NULL
;
614 BOOL bMulti
= !bSimple
&& aMultiMark
.IsMultiMarked();
617 aMultiMark
.MarkToMulti();
618 aMultiMark
.GetMultiMarkArea( aMarkRange
);
620 ScRange
aExtendedRange(aMarkRange
);
623 if ( pDoc
->ExtendMerge( aExtendedRange
, TRUE
) )
627 // keine Objekte auf geschuetzten Tabellen
628 BOOL bObjects
= FALSE
;
629 if ( nFlags
& IDF_OBJECTS
)
632 SCTAB nTabCount
= pDoc
->GetTableCount();
633 for (SCTAB nTab
=0; nTab
<nTabCount
; nTab
++)
634 if (aMultiMark
.GetTableSelect(nTab
) && pDoc
->IsTabProtected(nTab
))
638 USHORT nExtFlags
= 0; // extra flags are needed only if attributes are deleted
639 if ( nFlags
& IDF_ATTRIB
)
640 rDocShell
.UpdatePaintExt( nExtFlags
, aMarkRange
);
644 // 2) Objekte loeschen (DrawUndo wird gefuellt)
645 // 3) Inhalte fuer Undo kopieren und Undo-Aktion anlegen
646 // 4) Inhalte loeschen
648 bool bDrawUndo
= bObjects
|| (nFlags
& IDF_NOTE
);
649 if (bRecord
&& bDrawUndo
)
650 pDoc
->BeginDrawUndo();
655 pDoc
->DeleteObjectsInSelection( aMultiMark
);
657 pDoc
->DeleteObjectsInArea( aMarkRange
.aStart
.Col(), aMarkRange
.aStart
.Row(),
658 aMarkRange
.aEnd
.Col(), aMarkRange
.aEnd
.Row(),
664 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
665 pUndoDoc
->InitUndo( pDoc
, aMarkRange
.aStart
.Tab(), aMarkRange
.aEnd
.Tab() );
667 // bei "Format/Standard" alle Attribute kopieren, weil CopyToDocument
668 // nur mit IDF_HARDATTR zu langsam ist:
669 USHORT nUndoDocFlags
= nFlags
;
670 if (nFlags
& IDF_ATTRIB
)
671 nUndoDocFlags
|= IDF_ATTRIB
;
672 if (nFlags
& IDF_EDITATTR
) // Edit-Engine-Attribute
673 nUndoDocFlags
|= IDF_STRING
; // -> Zellen werden geaendert
674 if (nFlags
& IDF_NOTE
)
675 nUndoDocFlags
|= IDF_CONTENTS
; // #68795# copy all cells with their notes
676 // note captions are handled in drawing undo
677 nUndoDocFlags
|= IDF_NOCAPTIONS
;
678 pDoc
->CopyToDocument( aExtendedRange
, nUndoDocFlags
, bMulti
, pUndoDoc
, &aMultiMark
);
681 //! HideAllCursors(); // falls Zusammenfassung aufgehoben wird
683 pDoc
->DeleteArea( aMarkRange
.aStart
.Col(), aMarkRange
.aStart
.Row(),
684 aMarkRange
.aEnd
.Col(), aMarkRange
.aEnd
.Row(),
685 aMultiMark
, nFlags
);
688 pDoc
->DeleteSelection( nFlags
, aMultiMark
);
689 // aMultiMark.MarkToSimple();
692 // add undo action after drawing undo is complete (objects and note captions)
694 rDocShell
.GetUndoManager()->AddUndoAction(
695 new ScUndoDeleteContents( &rDocShell
, aMultiMark
, aExtendedRange
,
696 pUndoDoc
, bMulti
, nFlags
, bDrawUndo
) );
698 if (!AdjustRowHeight( aExtendedRange
))
699 rDocShell
.PostPaint( aExtendedRange
, PAINT_GRID
, nExtFlags
);
700 else if (nExtFlags
& SC_PF_LINES
)
701 lcl_PaintAbove( rDocShell
, aExtendedRange
); // fuer Linien ueber dem Bereich
703 // rDocShell.UpdateOle(GetViewData()); //! an der View?
704 aModificator
.SetDocumentModified();
705 //! CellContentChanged();
706 //! ShowAllCursors();
709 //! muss an der View bleiben !!!!
710 if ( nFlags
& IDF_ATTRIB
)
712 if ( nFlags
& IDF_CONTENTS
)
715 StartFormatArea(); // Attribute loeschen ist auch Attributierung
722 //------------------------------------------------------------------------
724 BOOL
ScDocFunc::TransliterateText( const ScMarkData
& rMark
, sal_Int32 nType
,
725 BOOL bRecord
, BOOL bApi
)
727 ScDocShellModificator
aModificator( rDocShell
);
729 ScDocument
* pDoc
= rDocShell
.GetDocument();
730 if (bRecord
&& !pDoc
->IsUndoEnabled())
733 ScEditableTester
aTester( pDoc
, rMark
);
734 if (!aTester
.IsEditable())
737 rDocShell
.ErrorMessage(aTester
.GetMessageId());
742 ScMarkData aMultiMark
= rMark
;
743 aMultiMark
.SetMarking(FALSE
); // for MarkToMulti
744 aMultiMark
.MarkToMulti();
745 aMultiMark
.GetMultiMarkArea( aMarkRange
);
749 SCTAB nStartTab
= aMarkRange
.aStart
.Tab();
750 SCTAB nTabCount
= pDoc
->GetTableCount();
752 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
753 pUndoDoc
->InitUndo( pDoc
, nStartTab
, nStartTab
);
754 for (SCTAB i
=0; i
<nTabCount
; i
++)
755 if (i
!= nStartTab
&& rMark
.GetTableSelect(i
))
756 pUndoDoc
->AddUndoTab( i
, i
);
758 ScRange aCopyRange
= aMarkRange
;
759 aCopyRange
.aStart
.SetTab(0);
760 aCopyRange
.aEnd
.SetTab(nTabCount
-1);
761 pDoc
->CopyToDocument( aCopyRange
, IDF_CONTENTS
, TRUE
, pUndoDoc
, &aMultiMark
);
763 rDocShell
.GetUndoManager()->AddUndoAction(
764 new ScUndoTransliterate( &rDocShell
, aMultiMark
, pUndoDoc
, nType
) );
767 pDoc
->TransliterateText( aMultiMark
, nType
);
769 if (!AdjustRowHeight( aMarkRange
))
770 rDocShell
.PostPaint( aMarkRange
, PAINT_GRID
);
772 aModificator
.SetDocumentModified();
777 //------------------------------------------------------------------------
779 BOOL
ScDocFunc::SetNormalString( const ScAddress
& rPos
, const String
& rText
, BOOL bApi
)
781 ScDocShellModificator
aModificator( rDocShell
);
782 ScDocument
* pDoc
= rDocShell
.GetDocument();
784 BOOL
bUndo(pDoc
->IsUndoEnabled());
785 ScEditableTester
aTester( pDoc
, rPos
.Tab(), rPos
.Col(),rPos
.Row(), rPos
.Col(),rPos
.Row() );
786 if (!aTester
.IsEditable())
789 rDocShell
.ErrorMessage(aTester
.GetMessageId());
794 ScBaseCell
** ppOldCells
= NULL
;
795 BOOL
* pHasFormat
= NULL
;
796 ULONG
* pOldFormats
= NULL
;
797 ScBaseCell
* pDocCell
= pDoc
->GetCell( rPos
);
798 BOOL bEditDeleted
= (pDocCell
&& pDocCell
->GetCellType() == CELLTYPE_EDIT
);
801 pTabs
= new SCTAB
[1];
802 pTabs
[0] = rPos
.Tab();
803 ppOldCells
= new ScBaseCell
*[1];
804 ppOldCells
[0] = pDocCell
? pDocCell
->CloneWithoutNote( *pDoc
) : 0;
806 pHasFormat
= new BOOL
[1];
807 pOldFormats
= new ULONG
[1];
808 const SfxPoolItem
* pItem
;
809 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( rPos
.Col(),rPos
.Row(),rPos
.Tab() );
810 if ( SFX_ITEM_SET
== pPattern
->GetItemSet().GetItemState(
811 ATTR_VALUE_FORMAT
,FALSE
,&pItem
) )
813 pHasFormat
[0] = TRUE
;
814 pOldFormats
[0] = ((const SfxUInt32Item
*)pItem
)->GetValue();
817 pHasFormat
[0] = FALSE
;
820 pDoc
->SetString( rPos
.Col(), rPos
.Row(), rPos
.Tab(), rText
);
824 // wegen ChangeTracking darf UndoAction erst nach SetString angelegt werden
825 rDocShell
.GetUndoManager()->AddUndoAction(new ScUndoEnterData( &rDocShell
, rPos
.Col(),rPos
.Row(),rPos
.Tab(), 1,pTabs
,
826 ppOldCells
, pHasFormat
, pOldFormats
, rText
, NULL
) );
829 if ( bEditDeleted
|| pDoc
->HasAttrib( ScRange(rPos
), HASATTR_NEEDHEIGHT
) )
830 AdjustRowHeight( ScRange(rPos
) );
832 rDocShell
.PostPaintCell( rPos
);
833 aModificator
.SetDocumentModified();
835 // #107160# notify input handler here the same way as in PutCell
837 NotifyInputHandler( rPos
);
842 BOOL
ScDocFunc::PutCell( const ScAddress
& rPos
, ScBaseCell
* pNewCell
, BOOL bApi
)
844 ScDocShellModificator
aModificator( rDocShell
);
845 ScDocument
* pDoc
= rDocShell
.GetDocument();
846 BOOL
bUndo (pDoc
->IsUndoEnabled());
847 BOOL
bXMLLoading(pDoc
->IsImportingXML());
849 // #i925#; it is not neccessary to test whether the cell is editable on loading a XML document
852 ScEditableTester
aTester( pDoc
, rPos
.Tab(), rPos
.Col(),rPos
.Row(), rPos
.Col(),rPos
.Row() );
853 if (!aTester
.IsEditable())
856 rDocShell
.ErrorMessage(aTester
.GetMessageId());
862 BOOL bEditCell
= ( pNewCell
->GetCellType() == CELLTYPE_EDIT
);
863 ScBaseCell
* pDocCell
= pDoc
->GetCell( rPos
);
864 BOOL bEditDeleted
= (pDocCell
&& pDocCell
->GetCellType() == CELLTYPE_EDIT
);
865 BOOL bHeight
= ( bEditDeleted
|| bEditCell
||
866 pDoc
->HasAttrib( ScRange(rPos
), HASATTR_NEEDHEIGHT
) );
868 ScBaseCell
* pUndoCell
= (bUndo
&& pDocCell
) ? pDocCell
->CloneWithoutNote( *pDoc
, rPos
) : 0;
869 ScBaseCell
* pRedoCell
= (bUndo
&& pNewCell
) ? pNewCell
->CloneWithoutNote( *pDoc
, rPos
) : 0;
871 pDoc
->PutCell( rPos
, pNewCell
);
873 // wegen ChangeTracking darf UndoAction erst nach PutCell angelegt werden
876 rDocShell
.GetUndoManager()->AddUndoAction(
877 new ScUndoPutCell( &rDocShell
, rPos
, pUndoCell
, pRedoCell
, bHeight
) );
881 AdjustRowHeight( ScRange(rPos
) );
884 rDocShell
.PostPaintCell( rPos
);
886 aModificator
.SetDocumentModified();
888 // #i925#; it is not neccessary to notify on loading a XML document
889 // #103934#; notify editline and cell in edit mode
890 if (bApi
&& !bXMLLoading
)
891 NotifyInputHandler( rPos
);
896 void ScDocFunc::NotifyInputHandler( const ScAddress
& /* rPos */ )
898 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
899 if ( pViewSh
&& pViewSh
->GetViewData()->GetDocShell() == &rDocShell
)
901 ScInputHandler
* pInputHdl
= SC_MOD()->GetInputHdl();
904 sal_Bool
bIsEditMode(pInputHdl
->IsEditMode());
906 // set modified if in editmode, because so the string is not set in the InputWindow like in the cell
907 // (the cell shows the same like the InputWindow)
909 pInputHdl
->SetModified();
910 pViewSh
->UpdateInputHandler(FALSE
, !bIsEditMode
);
915 struct ScMyRememberItem
920 ScMyRememberItem(const SfxItemSet
& rItemSet
, USHORT nTempIndex
) :
921 nIndex(nTempIndex
), aItemSet(rItemSet
) {}
924 typedef ::std::list
<ScMyRememberItem
*> ScMyRememberItemList
;
926 BOOL
ScDocFunc::PutData( const ScAddress
& rPos
, ScEditEngineDefaulter
& rEngine
, BOOL bInterpret
, BOOL bApi
)
928 // PutData ruft PutCell oder SetNormalString
931 ScDocument
* pDoc
= rDocShell
.GetDocument();
932 ScEditAttrTester
aTester( &rEngine
);
933 BOOL bEditCell
= aTester
.NeedsObject();
936 // #i61702# With bLoseContent set, the content of rEngine isn't restored
937 // (used in loading XML, where after the removeActionLock call the API obejct's
938 // EditEngine isn't accessed again.
939 sal_Bool bLoseContent
= pDoc
->IsImportingXML();
941 sal_Bool
bUpdateMode(rEngine
.GetUpdateMode());
943 rEngine
.SetUpdateMode(sal_False
);
945 ScMyRememberItemList aRememberItems
;
946 ScMyRememberItem
* pRememberItem
= NULL
;
948 // All paragraph attributes must be removed before calling CreateTextObject,
949 // not only alignment, so the object doesn't contain the cell attributes as
950 // paragraph attributes. Before remove the attributes store they in a list to
951 // set they back to the EditEngine.
952 USHORT nCount
= rEngine
.GetParagraphCount();
953 for (USHORT i
=0; i
<nCount
; i
++)
955 const SfxItemSet
& rOld
= rEngine
.GetParaAttribs( i
);
960 pRememberItem
= new ScMyRememberItem(rEngine
.GetParaAttribs(i
), i
);
961 aRememberItems
.push_back(pRememberItem
);
963 rEngine
.SetParaAttribs( i
, SfxItemSet( *rOld
.GetPool(), rOld
.GetRanges() ) );
967 EditTextObject
* pNewData
= rEngine
.CreateTextObject();
968 bRet
= PutCell( rPos
,
969 new ScEditCell( pNewData
, pDoc
, rEngine
.GetEditTextObjectPool() ),
973 // Set the paragraph attributes back to the EditEngine.
974 if (!aRememberItems
.empty())
976 // ScMyRememberItem* pRememberItem = NULL;
977 ScMyRememberItemList::iterator aItr
= aRememberItems
.begin();
978 while (aItr
!= aRememberItems
.end())
980 pRememberItem
= *aItr
;
981 rEngine
.SetParaAttribs(pRememberItem
->nIndex
, pRememberItem
->aItemSet
);
982 delete pRememberItem
;
983 aItr
= aRememberItems
.erase(aItr
);
987 // #i61702# if the content isn't accessed, there's no need to set the UpdateMode again
988 if ( bUpdateMode
&& !bLoseContent
)
989 rEngine
.SetUpdateMode(sal_True
);
993 String aText
= rEngine
.GetText();
994 if ( bInterpret
|| !aText
.Len() )
995 bRet
= SetNormalString( rPos
, aText
, bApi
);
997 bRet
= PutCell( rPos
, new ScStringCell( aText
), bApi
);
1000 if ( bRet
&& aTester
.NeedsCellAttr() )
1002 const SfxItemSet
& rEditAttr
= aTester
.GetAttribs();
1003 ScPatternAttr
aPattern( pDoc
->GetPool() );
1004 aPattern
.GetFromEditItemSet( &rEditAttr
);
1005 aPattern
.DeleteUnchanged( pDoc
->GetPattern( rPos
.Col(), rPos
.Row(), rPos
.Tab() ) );
1006 aPattern
.GetItemSet().ClearItem( ATTR_HOR_JUSTIFY
); // wasn't removed above if no edit object
1007 if ( aPattern
.GetItemSet().Count() > 0 )
1010 aMark
.SelectTable( rPos
.Tab(), TRUE
);
1011 aMark
.SetMarkArea( ScRange( rPos
) );
1012 ApplyAttributes( aMark
, aPattern
, TRUE
, bApi
);
1020 ScTokenArray
* lcl_ScDocFunc_CreateTokenArrayXML( const String
& rText
, const String
& rFormulaNmsp
, const formula::FormulaGrammar::Grammar eGrammar
)
1022 ScTokenArray
* pCode
= new ScTokenArray
;
1023 pCode
->AddString( rText
);
1024 if( (eGrammar
== formula::FormulaGrammar::GRAM_EXTERNAL
) && (rFormulaNmsp
.Len() > 0) )
1025 pCode
->AddString( rFormulaNmsp
);
1030 ScBaseCell
* ScDocFunc::InterpretEnglishString( const ScAddress
& rPos
,
1031 const String
& rText
, const String
& rFormulaNmsp
, const formula::FormulaGrammar::Grammar eGrammar
)
1033 ScDocument
* pDoc
= rDocShell
.GetDocument();
1034 ScBaseCell
* pNewCell
= NULL
;
1036 if ( rText
.Len() > 1 && rText
.GetChar(0) == '=' )
1038 ScTokenArray
* pCode
;
1039 if ( pDoc
->IsImportingXML() )
1040 { // temporary formula string as string tokens
1041 pCode
= lcl_ScDocFunc_CreateTokenArrayXML( rText
, rFormulaNmsp
, eGrammar
);
1042 pDoc
->IncXMLImportedFormulaCount( rText
.Len() );
1046 ScCompiler
aComp( pDoc
, rPos
);
1047 aComp
.SetGrammar(eGrammar
);
1048 pCode
= aComp
.CompileString( rText
);
1050 pNewCell
= new ScFormulaCell( pDoc
, rPos
, pCode
, eGrammar
, MM_NONE
);
1051 delete pCode
; // Zell-ctor hat das TokenArray kopiert
1053 else if ( rText
.Len() > 1 && rText
.GetChar(0) == '\'' )
1055 // for bEnglish, "'" at the beginning is always interpreted as text
1056 // marker and stripped
1057 pNewCell
= ScBaseCell::CreateTextCell( rText
.Copy( 1 ), pDoc
);
1059 else // (nur) auf englisches Zahlformat testen
1061 SvNumberFormatter
* pFormatter
= pDoc
->GetFormatTable();
1062 sal_uInt32 nEnglish
= pFormatter
->GetStandardIndex(LANGUAGE_ENGLISH_US
);
1064 if ( pFormatter
->IsNumberFormat( rText
, nEnglish
, fVal
) )
1065 pNewCell
= new ScValueCell( fVal
);
1066 else if ( rText
.Len() )
1067 pNewCell
= ScBaseCell::CreateTextCell( rText
, pDoc
);
1069 // das (englische) Zahlformat wird nicht gesetzt
1070 //! passendes lokales Format suchen und setzen???
1077 BOOL
ScDocFunc::SetCellText( const ScAddress
& rPos
, const String
& rText
,
1078 BOOL bInterpret
, BOOL bEnglish
, BOOL bApi
,
1079 const String
& rFormulaNmsp
, const formula::FormulaGrammar::Grammar eGrammar
)
1081 // SetCellText ruft PutCell oder SetNormalString
1083 ScDocument
* pDoc
= rDocShell
.GetDocument();
1084 ScBaseCell
* pNewCell
= NULL
;
1089 // code moved to own method InterpretEnglishString because it is also used in
1090 // ScCellRangeObj::setFormulaArray
1092 pNewCell
= InterpretEnglishString( rPos
, rText
, rFormulaNmsp
, eGrammar
);
1094 // sonst Null behalten -> SetString mit lokalen Formeln/Zahlformat
1096 else if ( rText
.Len() )
1098 OSL_ENSURE( rFormulaNmsp
.Len() == 0, "ScDocFunc::SetCellText - formula namespace, but do not interpret?" );
1099 pNewCell
= ScBaseCell::CreateTextCell( rText
, pDoc
); // immer Text
1103 return PutCell( rPos
, pNewCell
, bApi
);
1105 return SetNormalString( rPos
, rText
, bApi
);
1108 //------------------------------------------------------------------------
1110 bool ScDocFunc::ShowNote( const ScAddress
& rPos
, bool bShow
)
1112 ScDocument
& rDoc
= *rDocShell
.GetDocument();
1113 ScPostIt
* pNote
= rDoc
.GetNote( rPos
);
1114 if( !pNote
|| (bShow
== pNote
->IsCaptionShown()) ) return false;
1116 // move the caption to internal or hidden layer and create undo action
1117 pNote
->ShowCaption( rPos
, bShow
);
1118 if( rDoc
.IsUndoEnabled() )
1119 rDocShell
.GetUndoManager()->AddUndoAction( new ScUndoShowHideNote( rDocShell
, rPos
, bShow
) );
1121 if (rDoc
.IsStreamValid(rPos
.Tab()))
1122 rDoc
.SetStreamValid(rPos
.Tab(), FALSE
);
1124 rDocShell
.SetDocumentModified();
1129 //------------------------------------------------------------------------
1131 bool ScDocFunc::SetNoteText( const ScAddress
& rPos
, const String
& rText
, BOOL bApi
)
1133 ScDocShellModificator
aModificator( rDocShell
);
1135 ScDocument
* pDoc
= rDocShell
.GetDocument();
1136 ScEditableTester
aTester( pDoc
, rPos
.Tab(), rPos
.Col(),rPos
.Row(), rPos
.Col(),rPos
.Row() );
1137 if (!aTester
.IsEditable())
1140 rDocShell
.ErrorMessage(aTester
.GetMessageId());
1144 String aNewText
= rText
;
1145 aNewText
.ConvertLineEnd(); //! ist das noetig ???
1147 if( ScPostIt
* pNote
= (aNewText
.Len() > 0) ? pDoc
->GetOrCreateNote( rPos
) : pDoc
->GetNote( rPos
) )
1148 pNote
->SetText( rPos
, aNewText
);
1152 if (pDoc
->IsStreamValid(rPos
.Tab()))
1153 pDoc
->SetStreamValid(rPos
.Tab(), FALSE
);
1155 rDocShell
.PostPaintCell( rPos
);
1156 aModificator
.SetDocumentModified();
1161 //------------------------------------------------------------------------
1163 bool ScDocFunc::ReplaceNote( const ScAddress
& rPos
, const String
& rNoteText
, const String
* pAuthor
, const String
* pDate
, BOOL bApi
)
1167 ScDocShellModificator
aModificator( rDocShell
);
1168 ScDocument
& rDoc
= *rDocShell
.GetDocument();
1169 ScEditableTester
aTester( &rDoc
, rPos
.Tab(), rPos
.Col(),rPos
.Row(), rPos
.Col(),rPos
.Row() );
1170 if (aTester
.IsEditable())
1172 ScDrawLayer
* pDrawLayer
= rDoc
.GetDrawLayer();
1173 SfxUndoManager
* pUndoMgr
= (pDrawLayer
&& rDoc
.IsUndoEnabled()) ? rDocShell
.GetUndoManager() : 0;
1175 ScNoteData aOldData
;
1176 ScPostIt
* pOldNote
= rDoc
.ReleaseNote( rPos
);
1179 // ensure existing caption object before draw undo tracking starts
1180 pOldNote
->GetOrCreateCaption( rPos
);
1181 // rescue note data for undo
1182 aOldData
= pOldNote
->GetNoteData();
1185 // collect drawing undo actions for deleting/inserting caption obejcts
1187 pDrawLayer
->BeginCalcUndo();
1189 // delete the note (creates drawing undo action for the caption object)
1192 // create new note (creates drawing undo action for the new caption object)
1193 ScNoteData aNewData
;
1194 if( ScPostIt
* pNewNote
= ScNoteUtil::CreateNoteFromString( rDoc
, rPos
, rNoteText
, false, true ) )
1196 if( pAuthor
) pNewNote
->SetAuthor( *pAuthor
);
1197 if( pDate
) pNewNote
->SetDate( *pDate
);
1198 // rescue note data for undo
1199 aNewData
= pNewNote
->GetNoteData();
1202 // create the undo action
1203 if( pUndoMgr
&& (aOldData
.mpCaption
|| aNewData
.mpCaption
) )
1204 pUndoMgr
->AddUndoAction( new ScUndoReplaceNote( rDocShell
, rPos
, aOldData
, aNewData
, pDrawLayer
->GetCalcUndo() ) );
1206 // repaint cell (to make note marker visible)
1207 rDocShell
.PostPaintCell( rPos
);
1209 if (rDoc
.IsStreamValid(rPos
.Tab()))
1210 rDoc
.SetStreamValid(rPos
.Tab(), FALSE
);
1212 aModificator
.SetDocumentModified();
1217 rDocShell
.ErrorMessage(aTester
.GetMessageId());
1223 //------------------------------------------------------------------------
1225 BOOL
ScDocFunc::ApplyAttributes( const ScMarkData
& rMark
, const ScPatternAttr
& rPattern
,
1226 BOOL bRecord
, BOOL bApi
)
1228 ScDocument
* pDoc
= rDocShell
.GetDocument();
1229 if ( bRecord
&& !pDoc
->IsUndoEnabled() )
1232 BOOL bImportingXML
= pDoc
->IsImportingXML();
1233 // Cell formats can still be set if the range isn't editable only because of matrix formulas.
1234 // #i62483# When loading XML, the check can be skipped altogether.
1235 BOOL bOnlyNotBecauseOfMatrix
;
1236 if ( !bImportingXML
&& !pDoc
->IsSelectionEditable( rMark
, &bOnlyNotBecauseOfMatrix
)
1237 && !bOnlyNotBecauseOfMatrix
)
1240 rDocShell
.ErrorMessage(STR_PROTECTIONERR
);
1244 ScDocShellModificator
aModificator( rDocShell
);
1248 ScRange aMultiRange
;
1249 BOOL bMulti
= rMark
.IsMultiMarked();
1251 rMark
.GetMultiMarkArea( aMultiRange
);
1253 rMark
.GetMarkArea( aMultiRange
);
1257 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1258 pUndoDoc
->InitUndo( pDoc
, aMultiRange
.aStart
.Tab(), aMultiRange
.aEnd
.Tab() );
1259 pDoc
->CopyToDocument( aMultiRange
, IDF_ATTRIB
, bMulti
, pUndoDoc
, &rMark
);
1261 rDocShell
.GetUndoManager()->AddUndoAction(
1262 new ScUndoSelectionAttr(
1264 aMultiRange
.aStart
.Col(), aMultiRange
.aStart
.Row(), aMultiRange
.aStart
.Tab(),
1265 aMultiRange
.aEnd
.Col(), aMultiRange
.aEnd
.Row(), aMultiRange
.aEnd
.Tab(),
1266 pUndoDoc
, bMulti
, &rPattern
) );
1269 // While loading XML it is not neccessary to ask HasAttrib. It needs too much time.
1270 USHORT nExtFlags
= 0;
1271 if ( !bImportingXML
)
1272 rDocShell
.UpdatePaintExt( nExtFlags
, aMultiRange
); // content before the change
1273 pDoc
->ApplySelectionPattern( rPattern
, rMark
);
1274 if ( !bImportingXML
)
1275 rDocShell
.UpdatePaintExt( nExtFlags
, aMultiRange
); // content after the change
1277 if (!AdjustRowHeight( aMultiRange
))
1278 rDocShell
.PostPaint( aMultiRange
, PAINT_GRID
, nExtFlags
);
1279 else if (nExtFlags
& SC_PF_LINES
)
1280 lcl_PaintAbove( rDocShell
, aMultiRange
); // fuer Linien ueber dem Bereich
1282 aModificator
.SetDocumentModified();
1288 BOOL
ScDocFunc::ApplyStyle( const ScMarkData
& rMark
, const String
& rStyleName
,
1289 BOOL bRecord
, BOOL bApi
)
1291 ScDocument
* pDoc
= rDocShell
.GetDocument();
1292 if ( bRecord
&& !pDoc
->IsUndoEnabled() )
1295 BOOL bImportingXML
= pDoc
->IsImportingXML();
1296 // Cell formats can still be set if the range isn't editable only because of matrix formulas.
1297 // #i62483# When loading XML, the check can be skipped altogether.
1298 BOOL bOnlyNotBecauseOfMatrix
;
1299 if ( !bImportingXML
&& !pDoc
->IsSelectionEditable( rMark
, &bOnlyNotBecauseOfMatrix
)
1300 && !bOnlyNotBecauseOfMatrix
)
1303 rDocShell
.ErrorMessage(STR_PROTECTIONERR
);
1307 ScStyleSheet
* pStyleSheet
= (ScStyleSheet
*) pDoc
->GetStyleSheetPool()->Find(
1308 rStyleName
, SFX_STYLE_FAMILY_PARA
);
1312 ScDocShellModificator
aModificator( rDocShell
);
1314 ScRange aMultiRange
;
1315 BOOL bMulti
= rMark
.IsMultiMarked();
1317 rMark
.GetMultiMarkArea( aMultiRange
);
1319 rMark
.GetMarkArea( aMultiRange
);
1323 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1324 SCTAB nStartTab
= aMultiRange
.aStart
.Tab();
1325 SCTAB nTabCount
= pDoc
->GetTableCount();
1326 pUndoDoc
->InitUndo( pDoc
, nStartTab
, nStartTab
);
1327 for (SCTAB i
=0; i
<nTabCount
; i
++)
1328 if (i
!= nStartTab
&& rMark
.GetTableSelect(i
))
1329 pUndoDoc
->AddUndoTab( i
, i
);
1331 ScRange aCopyRange
= aMultiRange
;
1332 aCopyRange
.aStart
.SetTab(0);
1333 aCopyRange
.aEnd
.SetTab(nTabCount
-1);
1334 pDoc
->CopyToDocument( aCopyRange
, IDF_ATTRIB
, bMulti
, pUndoDoc
, &rMark
);
1336 rDocShell
.GetUndoManager()->AddUndoAction(
1337 new ScUndoSelectionStyle(
1338 &rDocShell
, rMark
, aMultiRange
, rStyleName
, pUndoDoc
) );
1342 // BOOL bPaintExt = pDoc->HasAttrib( aMultiRange, HASATTR_PAINTEXT );
1343 // pDoc->ApplySelectionPattern( rPattern, rMark );
1345 pDoc
->ApplySelectionStyle( (ScStyleSheet
&)*pStyleSheet
, rMark
);
1348 // bPaintExt = pDoc->HasAttrib( aMultiRange, HASATTR_PAINTEXT );
1349 // USHORT nExtFlags = bPaintExt ? SC_PF_LINES : 0;
1350 USHORT nExtFlags
= 0;
1351 if (!AdjustRowHeight( aMultiRange
))
1352 rDocShell
.PostPaint( aMultiRange
, PAINT_GRID
, nExtFlags
);
1353 else if (nExtFlags
& SC_PF_LINES
)
1354 lcl_PaintAbove( rDocShell
, aMultiRange
); // fuer Linien ueber dem Bereich
1356 aModificator
.SetDocumentModified();
1361 //------------------------------------------------------------------------
1363 BOOL
ScDocFunc::InsertCells( const ScRange
& rRange
, const ScMarkData
* pTabMark
, InsCellCmd eCmd
,
1364 BOOL bRecord
, BOOL bApi
, BOOL bPartOfPaste
)
1366 ScDocShellModificator
aModificator( rDocShell
);
1368 SCCOL nStartCol
= rRange
.aStart
.Col();
1369 SCROW nStartRow
= rRange
.aStart
.Row();
1370 SCTAB nStartTab
= rRange
.aStart
.Tab();
1371 SCCOL nEndCol
= rRange
.aEnd
.Col();
1372 SCROW nEndRow
= rRange
.aEnd
.Row();
1373 SCTAB nEndTab
= rRange
.aEnd
.Tab();
1375 if ( !ValidRow(nStartRow
) || !ValidRow(nEndRow
) )
1377 DBG_ERROR("invalid row in InsertCells");
1381 ScDocument
* pDoc
= rDocShell
.GetDocument();
1382 SCTAB nTabCount
= pDoc
->GetTableCount();
1383 SCCOL nPaintStartX
= nStartCol
;
1384 SCROW nPaintStartY
= nStartRow
;
1385 SCCOL nPaintEndX
= nEndCol
;
1386 SCROW nPaintEndY
= nEndRow
;
1387 USHORT nPaintFlags
= PAINT_GRID
;
1391 ScTabViewShell
* pViewSh
= rDocShell
.GetBestViewShell(); //preserve current cursor position
1392 SCCOL nCursorCol
= 0;
1393 SCROW nCursorRow
= 0;
1396 nCursorCol
= pViewSh
->GetViewData()->GetCurX();
1397 nCursorRow
= pViewSh
->GetViewData()->GetCurY();
1400 if (bRecord
&& !pDoc
->IsUndoEnabled())
1409 for( i
=0; i
<nTabCount
; i
++ )
1411 if( !pDoc
->IsScenario(i
) )
1414 if( nCount
== nEndTab
+1 )
1416 aMark
.SelectTable( i
, TRUE
);
1423 ScMarkData
aFullMark( aMark
); // including scenario sheets
1424 for( i
=0; i
<nTabCount
; i
++ )
1425 if( aMark
.GetTableSelect( i
) )
1427 for( SCTAB j
= i
+1; j
<nTabCount
&& pDoc
->IsScenario(j
); j
++ )
1428 aFullMark
.SelectTable( j
, TRUE
);
1431 SCTAB nSelCount
= aMark
.GetSelectCount();
1433 // zugehoerige Szenarien auch anpassen
1434 // Test zusammengefasste
1436 SCCOL nMergeTestStartX
= nStartCol
;
1437 SCROW nMergeTestStartY
= nStartRow
;
1438 SCCOL nMergeTestEndX
= nEndCol
;
1439 SCROW nMergeTestEndY
= nEndRow
;
1441 ScRange
aExtendMergeRange( rRange
);
1443 if( rRange
.aStart
== rRange
.aEnd
&& pDoc
->HasAttrib(rRange
, HASATTR_MERGED
) )
1445 pDoc
->ExtendMerge( aExtendMergeRange
);
1446 pDoc
->ExtendOverlapped( aExtendMergeRange
);
1447 nMergeTestEndX
= aExtendMergeRange
.aEnd
.Col();
1448 nMergeTestEndY
= aExtendMergeRange
.aEnd
.Row();
1449 nPaintEndX
= nMergeTestEndX
;
1450 nPaintEndY
= nMergeTestEndY
;
1453 if ( eCmd
== INS_INSROWS
)
1455 nMergeTestStartX
= 0;
1456 nMergeTestEndX
= MAXCOL
;
1458 if ( eCmd
== INS_INSCOLS
)
1460 nMergeTestStartY
= 0;
1461 nMergeTestEndY
= MAXROW
;
1463 if ( eCmd
== INS_CELLSDOWN
)
1464 nMergeTestEndY
= MAXROW
;
1465 if ( eCmd
== INS_CELLSRIGHT
)
1466 nMergeTestEndX
= MAXCOL
;
1468 BOOL bNeedRefresh
= FALSE
;
1470 SCCOL nEditTestEndX
= (eCmd
==INS_INSCOLS
) ? MAXCOL
: nMergeTestEndX
;
1471 SCROW nEditTestEndY
= (eCmd
==INS_INSROWS
) ? MAXROW
: nMergeTestEndY
;
1472 ScEditableTester
aTester( pDoc
, nMergeTestStartX
, nMergeTestStartY
, nEditTestEndX
, nEditTestEndY
, aMark
);
1473 if (!aTester
.IsEditable())
1476 rDocShell
.ErrorMessage(aTester
.GetMessageId());
1480 WaitObject
aWait( rDocShell
.GetActiveDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference
1482 ScDocument
* pRefUndoDoc
= NULL
;
1483 ScRefUndoData
* pUndoData
= NULL
;
1486 pRefUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1487 pRefUndoDoc
->InitUndo( pDoc
, 0, nTabCount
-1, FALSE
, FALSE
);
1489 // pRefUndoDoc is filled in InsertCol / InsertRow
1491 pUndoData
= new ScRefUndoData( pDoc
);
1493 pDoc
->BeginDrawUndo();
1496 // #i8302 : we unmerge overwhelming ranges, before insertion all the actions are put in the same ListAction
1497 // the patch comes from mloiseleur and maoyg
1498 BOOL bInsertMerge
= FALSE
;
1499 std::vector
<ScRange
> qIncreaseRange
;
1500 String aUndo
= ScGlobal::GetRscString( STR_UNDO_INSERTCELLS
);
1502 rDocShell
.GetUndoManager()->EnterListAction( aUndo
, aUndo
);
1504 for( i
=0; i
<nTabCount
; i
++ )
1506 if( aMark
.GetTableSelect(i
) )
1508 if( pDoc
->HasAttrib( nMergeTestStartX
, nMergeTestStartY
, i
, nMergeTestEndX
, nMergeTestEndY
, i
, HASATTR_MERGED
| HASATTR_OVERLAPPED
) )
1510 if (eCmd
==INS_CELLSRIGHT
)
1511 bNeedRefresh
= TRUE
;
1513 SCCOL nMergeStartX
= nMergeTestStartX
;
1514 SCROW nMergeStartY
= nMergeTestStartY
;
1515 SCCOL nMergeEndX
= nMergeTestEndX
;
1516 SCROW nMergeEndY
= nMergeTestEndY
;
1518 pDoc
->ExtendMerge( nMergeStartX
, nMergeStartY
, nMergeEndX
, nMergeEndY
, i
);
1519 pDoc
->ExtendOverlapped( nMergeStartX
, nMergeStartY
, nMergeEndX
, nMergeEndY
, i
);
1521 if(( eCmd
== INS_CELLSDOWN
&& ( nMergeStartX
!= nMergeTestStartX
|| nMergeEndX
!= nMergeTestEndX
)) ||
1522 (eCmd
== INS_CELLSRIGHT
&& ( nMergeStartY
!= nMergeTestStartY
|| nMergeEndY
!= nMergeTestEndY
)) )
1525 rDocShell
.ErrorMessage(STR_MSSG_INSERTCELLS_0
);
1526 rDocShell
.GetUndoManager()->LeaveListAction();
1530 SCCOL nTestCol
= -1;
1531 SCROW nTestRow1
= -1;
1532 SCROW nTestRow2
= -1;
1534 ScDocAttrIterator
aTestIter( pDoc
, i
, nMergeTestStartX
, nMergeTestStartY
, nMergeTestEndX
, nMergeTestEndY
);
1535 ScRange
aExtendRange( nMergeTestStartX
, nMergeTestStartY
, i
, nMergeTestEndX
, nMergeTestEndY
, i
);
1536 const ScPatternAttr
* pPattern
= NULL
;
1537 const ScMergeAttr
* pMergeFlag
= NULL
;
1538 const ScMergeFlagAttr
* pMergeFlagAttr
= NULL
;
1539 while ( ( pPattern
= aTestIter
.GetNext( nTestCol
, nTestRow1
, nTestRow2
) ) != NULL
)
1541 pMergeFlag
= (const ScMergeAttr
*) &pPattern
->GetItem(ATTR_MERGE
);
1542 pMergeFlagAttr
= (const ScMergeFlagAttr
*) &pPattern
->GetItem(ATTR_MERGE_FLAG
);
1543 INT16 nNewFlags
= pMergeFlagAttr
->GetValue() & ( SC_MF_HOR
| SC_MF_VER
);
1544 if( ( pMergeFlag
&& pMergeFlag
->IsMerged() ) || nNewFlags
== SC_MF_HOR
|| nNewFlags
== SC_MF_VER
)
1546 ScRange
aRange( nTestCol
, nTestRow1
, i
);
1547 pDoc
->ExtendOverlapped(aRange
);
1548 pDoc
->ExtendMerge(aRange
, TRUE
, TRUE
);
1550 if( nTestRow1
< nTestRow2
&& nNewFlags
== SC_MF_HOR
)
1552 for( SCROW nTestRow
= nTestRow1
; nTestRow
<= nTestRow2
; nTestRow
++ )
1554 ScRange
aTestRange( nTestCol
, nTestRow
, i
);
1555 pDoc
->ExtendOverlapped( aTestRange
);
1556 pDoc
->ExtendMerge( aTestRange
, TRUE
, TRUE
);
1557 ScRange
aMergeRange( aTestRange
.aStart
.Col(),aTestRange
.aStart
.Row(), i
);
1558 if( !aExtendRange
.In( aMergeRange
) )
1560 qIncreaseRange
.push_back( aTestRange
);
1561 bInsertMerge
= TRUE
;
1567 ScRange
aMergeRange( aRange
.aStart
.Col(),aRange
.aStart
.Row(), i
);
1568 if( !aExtendRange
.In( aMergeRange
) )
1570 qIncreaseRange
.push_back( aRange
);
1572 bInsertMerge
= TRUE
;
1579 if( eCmd
== INS_INSROWS
|| eCmd
== INS_CELLSDOWN
)
1581 nStartRow
= aExtendMergeRange
.aStart
.Row();
1582 nEndRow
= aExtendMergeRange
.aEnd
.Row();
1584 if( eCmd
== INS_CELLSDOWN
)
1585 nEndCol
= nMergeTestEndX
;
1592 else if( eCmd
== INS_CELLSRIGHT
|| eCmd
== INS_INSCOLS
)
1595 nStartCol
= aExtendMergeRange
.aStart
.Col();
1596 nEndCol
= aExtendMergeRange
.aEnd
.Col();
1597 if( eCmd
== INS_CELLSRIGHT
)
1599 nEndRow
= nMergeTestEndY
;
1608 if( !qIncreaseRange
.empty() )
1610 for( ::std::vector
<ScRange
>::const_iterator
iIter( qIncreaseRange
.begin()); iIter
!= qIncreaseRange
.end(); iIter
++ )
1612 ScRange
aRange( *iIter
);
1613 if( pDoc
->HasAttrib( aRange
, HASATTR_OVERLAPPED
| HASATTR_MERGED
) )
1615 UnmergeCells( aRange
, TRUE
, TRUE
);
1623 rDocShell
.ErrorMessage(STR_MSSG_INSERTCELLS_0
);
1624 rDocShell
.GetUndoManager()->LeaveListAction();
1634 bSuccess
= pDoc
->InsertRow( nStartCol
, 0, nEndCol
, MAXTAB
, nStartRow
, static_cast<SCSIZE
>(nEndRow
-nStartRow
+1), pRefUndoDoc
, &aFullMark
);
1635 nPaintEndY
= MAXROW
;
1638 bSuccess
= pDoc
->InsertRow( 0, 0, MAXCOL
, MAXTAB
, nStartRow
, static_cast<SCSIZE
>(nEndRow
-nStartRow
+1), pRefUndoDoc
, &aFullMark
);
1640 nPaintEndX
= MAXCOL
;
1641 nPaintEndY
= MAXROW
;
1642 nPaintFlags
|= PAINT_LEFT
;
1644 case INS_CELLSRIGHT
:
1645 bSuccess
= pDoc
->InsertCol( nStartRow
, 0, nEndRow
, MAXTAB
, nStartCol
, static_cast<SCSIZE
>(nEndCol
-nStartCol
+1), pRefUndoDoc
, &aFullMark
);
1646 nPaintEndX
= MAXCOL
;
1649 bSuccess
= pDoc
->InsertCol( 0, 0, MAXROW
, MAXTAB
, nStartCol
, static_cast<SCSIZE
>(nEndCol
-nStartCol
+1), pRefUndoDoc
, &aFullMark
);
1651 nPaintEndY
= MAXROW
;
1652 nPaintEndX
= MAXCOL
;
1653 nPaintFlags
|= PAINT_TOP
;
1656 DBG_ERROR("Falscher Code beim Einfuegen");
1663 SCTAB
* pTabs
= NULL
;
1664 SCTAB
* pScenarios
= NULL
;
1669 pTabs
= new SCTAB
[nSelCount
];
1670 pScenarios
= new SCTAB
[nSelCount
];
1672 for( i
=0; i
<nTabCount
; i
++ )
1674 if( aMark
.GetTableSelect( i
) )
1677 for( SCTAB j
=i
+1; j
<nTabCount
&& pDoc
->IsScenario(j
); j
++ )
1680 pScenarios
[nUndoPos
] = nCount
;
1681 pTabs
[nUndoPos
] = i
;
1688 rDocShell
.GetUndoManager()->LeaveListAction();
1691 rDocShell
.GetUndoManager()->AddUndoAction( new ScUndoInsertCells(
1692 &rDocShell
, ScRange( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
),
1693 nUndoPos
, pTabs
, pScenarios
, eCmd
, pRefUndoDoc
, pUndoData
, bPartOfPaste
) );
1696 // #i8302 : we remerge growing ranges, with the new part inserted
1698 while( !qIncreaseRange
.empty() )
1700 ScRange aRange
= qIncreaseRange
.back();
1701 if( !pDoc
->HasAttrib( aRange
, HASATTR_OVERLAPPED
| HASATTR_MERGED
) )
1707 aRange
.aEnd
.IncRow(static_cast<SCsCOL
>(nEndRow
-nStartRow
+1));
1709 case INS_CELLSRIGHT
:
1711 aRange
.aEnd
.IncCol(static_cast<SCsCOL
>(nEndCol
-nStartCol
+1));
1716 ScCellMergeOption
aMergeOption(
1717 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
1718 aRange
.aEnd
.Col(), aRange
.aEnd
.Row() );
1719 aMergeOption
.maTabs
.insert(aRange
.aStart
.Tab());
1720 MergeCells(aMergeOption
, FALSE
, TRUE
, TRUE
);
1722 qIncreaseRange
.pop_back();
1726 rDocShell
.GetUndoManager()->LeaveListAction();
1728 for( i
=0; i
<nTabCount
; i
++ )
1730 if( aMark
.GetTableSelect( i
) )
1733 pDoc
->ExtendMerge( nMergeTestStartX
, nMergeTestStartY
, nMergeTestEndX
, nMergeTestEndY
, i
, TRUE
);
1735 pDoc
->RefreshAutoFilter( nMergeTestStartX
, nMergeTestStartY
, nMergeTestEndX
, nMergeTestEndY
, i
);
1737 if ( eCmd
== INS_INSROWS
|| eCmd
== INS_INSCOLS
)
1738 pDoc
->UpdatePageBreaks( i
);
1740 USHORT nExtFlags
= 0;
1741 rDocShell
.UpdatePaintExt( nExtFlags
, nPaintStartX
, nPaintStartY
, i
, nPaintEndX
, nPaintEndY
, i
);
1743 SCTAB nScenarioCount
= 0;
1745 for( SCTAB j
= i
+1; j
<nTabCount
&& pDoc
->IsScenario(j
); j
++ )
1748 BOOL bAdjusted
= ( eCmd
== INS_INSROWS
) ? AdjustRowHeight(ScRange(0, nStartRow
, i
, MAXCOL
, nEndRow
, i
+nScenarioCount
)) :
1749 AdjustRowHeight(ScRange(0, nPaintStartY
, i
, MAXCOL
, nPaintEndY
, i
+nScenarioCount
));
1752 // paint only what is not done by AdjustRowHeight
1753 if (nPaintFlags
& PAINT_TOP
)
1754 rDocShell
.PostPaint( nPaintStartX
, nPaintStartY
, i
, nPaintEndX
, nPaintEndY
, i
+nScenarioCount
, PAINT_TOP
);
1757 rDocShell
.PostPaint( nPaintStartX
, nPaintStartY
, i
, nPaintEndX
, nPaintEndY
, i
+nScenarioCount
, nPaintFlags
, nExtFlags
);
1760 //aModificator.SetDocumentModified();
1766 while( !qIncreaseRange
.empty() )
1768 ScRange aRange
= qIncreaseRange
.back();
1769 ScCellMergeOption
aMergeOption(
1770 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
1771 aRange
.aEnd
.Col(), aRange
.aEnd
.Row() );
1772 MergeCells(aMergeOption
, FALSE
, TRUE
, TRUE
);
1773 qIncreaseRange
.pop_back();
1778 pViewSh
->MarkRange( rRange
, FALSE
);
1779 pViewSh
->SetCursor( nCursorCol
, nCursorRow
);
1783 rDocShell
.GetUndoManager()->LeaveListAction();
1784 SfxUndoManager
* pMgr
= rDocShell
.GetUndoManager();
1785 pMgr
->RemoveLastUndoAction();
1790 rDocShell
.ErrorMessage(STR_INSERT_FULL
); // Spalte/Zeile voll
1793 aModificator
.SetDocumentModified();
1795 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED
) );
1799 BOOL
ScDocFunc::DeleteCells( const ScRange
& rRange
, const ScMarkData
* pTabMark
, DelCellCmd eCmd
,
1800 BOOL bRecord
, BOOL bApi
)
1802 ScDocShellModificator
aModificator( rDocShell
);
1804 SCCOL nStartCol
= rRange
.aStart
.Col();
1805 SCROW nStartRow
= rRange
.aStart
.Row();
1806 SCTAB nStartTab
= rRange
.aStart
.Tab();
1807 SCCOL nEndCol
= rRange
.aEnd
.Col();
1808 SCROW nEndRow
= rRange
.aEnd
.Row();
1809 SCTAB nEndTab
= rRange
.aEnd
.Tab();
1811 if ( !ValidRow(nStartRow
) || !ValidRow(nEndRow
) )
1813 DBG_ERROR("invalid row in DeleteCells");
1817 ScDocument
* pDoc
= rDocShell
.GetDocument();
1818 SCTAB nTabCount
= pDoc
->GetTableCount();
1819 SCCOL nPaintStartX
= nStartCol
;
1820 SCROW nPaintStartY
= nStartRow
;
1821 SCCOL nPaintEndX
= nEndCol
;
1822 SCROW nPaintEndY
= nEndRow
;
1823 USHORT nPaintFlags
= PAINT_GRID
;
1826 if (bRecord
&& !pDoc
->IsUndoEnabled())
1835 for( i
=0; i
<nTabCount
; i
++ )
1837 if( !pDoc
->IsScenario(i
) )
1840 if( nCount
== nEndTab
+1 )
1842 aMark
.SelectTable( i
, TRUE
);
1849 ScMarkData
aFullMark( aMark
); // including scenario sheets
1850 for( i
=0; i
<nTabCount
; i
++ )
1851 if( aMark
.GetTableSelect( i
) )
1853 for( SCTAB j
= i
+1; j
<nTabCount
&& pDoc
->IsScenario(j
); j
++ )
1854 aFullMark
.SelectTable( j
, TRUE
);
1857 SCTAB nSelCount
= aMark
.GetSelectCount();
1859 SCCOL nUndoStartX
= nStartCol
;
1860 SCROW nUndoStartY
= nStartRow
;
1861 SCCOL nUndoEndX
= nEndCol
;
1862 SCROW nUndoEndY
= nEndRow
;
1864 ScRange
aExtendMergeRange( rRange
);
1866 if( rRange
.aStart
== rRange
.aEnd
&& pDoc
->HasAttrib(rRange
, HASATTR_MERGED
) )
1868 pDoc
->ExtendMerge( aExtendMergeRange
);
1869 pDoc
->ExtendOverlapped( aExtendMergeRange
);
1870 nUndoEndX
= aExtendMergeRange
.aEnd
.Col();
1871 nUndoEndY
= aExtendMergeRange
.aEnd
.Row();
1872 nPaintEndX
= nUndoEndX
;
1873 nPaintEndY
= nUndoEndY
;
1876 if (eCmd
==DEL_DELROWS
)
1881 if (eCmd
==DEL_DELCOLS
)
1888 SCCOL nEditTestEndX
= nUndoEndX
;
1889 if ( eCmd
==DEL_DELCOLS
|| eCmd
==DEL_CELLSLEFT
)
1890 nEditTestEndX
= MAXCOL
;
1891 SCROW nEditTestEndY
= nUndoEndY
;
1892 if ( eCmd
==DEL_DELROWS
|| eCmd
==DEL_CELLSUP
)
1893 nEditTestEndY
= MAXROW
;
1894 ScEditableTester
aTester( pDoc
, nUndoStartX
, nUndoStartY
, nEditTestEndX
, nEditTestEndY
, aMark
);
1895 if (!aTester
.IsEditable())
1898 rDocShell
.ErrorMessage(aTester
.GetMessageId());
1902 // Test zusammengefasste
1904 SCCOL nMergeTestEndX
= (eCmd
==DEL_CELLSLEFT
) ? MAXCOL
: nUndoEndX
;
1905 SCROW nMergeTestEndY
= (eCmd
==DEL_CELLSUP
) ? MAXROW
: nUndoEndY
;
1906 SCCOL nExtendStartCol
= nUndoStartX
;
1907 SCROW nExtendStartRow
= nUndoStartY
;
1908 BOOL bNeedRefresh
= FALSE
;
1910 //Issue 8302 want to be able to insert into the middle of merged cells
1911 //the patch comes from maoyg
1912 ::std::vector
<ScRange
> qDecreaseRange
;
1913 BOOL bDeletingMerge
= FALSE
;
1914 String aUndo
= ScGlobal::GetRscString( STR_UNDO_DELETECELLS
);
1916 rDocShell
.GetUndoManager()->EnterListAction( aUndo
, aUndo
);
1918 for( i
=0; i
<nTabCount
; i
++ )
1920 if( aMark
.GetTableSelect(i
) )
1922 if ( pDoc
->HasAttrib( nUndoStartX
, nUndoStartY
, i
, nMergeTestEndX
, nMergeTestEndY
, i
, HASATTR_MERGED
| HASATTR_OVERLAPPED
))
1924 SCCOL nMergeStartX
= nUndoStartX
;
1925 SCROW nMergeStartY
= nUndoStartY
;
1926 SCCOL nMergeEndX
= nMergeTestEndX
;
1927 SCROW nMergeEndY
= nMergeTestEndY
;
1929 pDoc
->ExtendMerge( nMergeStartX
, nMergeStartY
, nMergeEndX
, nMergeEndY
, i
);
1930 pDoc
->ExtendOverlapped( nMergeStartX
, nMergeStartY
, nMergeEndX
, nMergeEndY
, i
);
1931 if( ( eCmd
== DEL_CELLSUP
&& ( nMergeStartX
!= nUndoStartX
|| nMergeEndX
!= nMergeTestEndX
))||
1932 ( eCmd
== DEL_CELLSLEFT
&& ( nMergeStartY
!= nUndoStartY
|| nMergeEndY
!= nMergeTestEndY
)))
1935 rDocShell
.ErrorMessage(STR_MSSG_DELETECELLS_0
);
1936 rDocShell
.GetUndoManager()->LeaveListAction();
1940 nExtendStartCol
= nMergeStartX
;
1941 nExtendStartRow
= nMergeStartY
;
1942 SCCOL nTestCol
= -1;
1943 SCROW nTestRow1
= -1;
1944 SCROW nTestRow2
= -1;
1946 ScDocAttrIterator
aTestIter( pDoc
, i
, nUndoStartX
, nUndoStartY
, nMergeTestEndX
, nMergeTestEndY
);
1947 ScRange
aExtendRange( nUndoStartX
, nUndoStartY
, i
, nMergeTestEndX
, nMergeTestEndY
, i
);
1948 const ScPatternAttr
* pPattern
= NULL
;
1949 const ScMergeAttr
* pMergeFlag
= NULL
;
1950 const ScMergeFlagAttr
* pMergeFlagAttr
= NULL
;
1951 while ( ( pPattern
= aTestIter
.GetNext( nTestCol
, nTestRow1
, nTestRow2
) ) != NULL
)
1953 pMergeFlag
= (const ScMergeAttr
*) &pPattern
->GetItem( ATTR_MERGE
);
1954 pMergeFlagAttr
= (const ScMergeFlagAttr
*) &pPattern
->GetItem( ATTR_MERGE_FLAG
);
1955 INT16 nNewFlags
= pMergeFlagAttr
->GetValue() & ( SC_MF_HOR
| SC_MF_VER
);
1956 if( ( pMergeFlag
&& pMergeFlag
->IsMerged() ) || nNewFlags
== SC_MF_HOR
|| nNewFlags
== SC_MF_VER
)
1958 ScRange
aRange( nTestCol
, nTestRow1
, i
);
1959 pDoc
->ExtendOverlapped( aRange
);
1960 pDoc
->ExtendMerge( aRange
, TRUE
, TRUE
);
1962 if( nTestRow1
< nTestRow2
&& nNewFlags
== SC_MF_HOR
)
1964 for( SCROW nTestRow
= nTestRow1
; nTestRow
<= nTestRow2
; nTestRow
++ )
1966 ScRange
aTestRange( nTestCol
, nTestRow
, i
);
1967 pDoc
->ExtendOverlapped( aTestRange
);
1968 pDoc
->ExtendMerge( aTestRange
, TRUE
, TRUE
);
1969 ScRange
aMergeRange( aTestRange
.aStart
.Col(),aTestRange
.aStart
.Row(), i
);
1970 if( !aExtendRange
.In( aMergeRange
) )
1972 qDecreaseRange
.push_back( aTestRange
);
1973 bDeletingMerge
= TRUE
;
1979 ScRange
aMergeRange( aRange
.aStart
.Col(),aRange
.aStart
.Row(), i
);
1980 if( !aExtendRange
.In( aMergeRange
) )
1982 qDecreaseRange
.push_back( aRange
);
1984 bDeletingMerge
= TRUE
;
1989 if( bDeletingMerge
)
1992 if( eCmd
== DEL_DELROWS
|| eCmd
== DEL_CELLSUP
)
1994 nStartRow
= aExtendMergeRange
.aStart
.Row();
1995 nEndRow
= aExtendMergeRange
.aEnd
.Row();
1996 bNeedRefresh
= TRUE
;
1998 if( eCmd
== DEL_CELLSUP
)
2000 nEndCol
= aExtendMergeRange
.aEnd
.Col();
2008 else if( eCmd
== DEL_CELLSLEFT
|| eCmd
== DEL_DELCOLS
)
2011 nStartCol
= aExtendMergeRange
.aStart
.Col();
2012 nEndCol
= aExtendMergeRange
.aEnd
.Col();
2013 if( eCmd
== DEL_CELLSLEFT
)
2015 nEndRow
= aExtendMergeRange
.aEnd
.Row();
2016 bNeedRefresh
= TRUE
;
2025 if( !qDecreaseRange
.empty() )
2027 for( ::std::vector
<ScRange
>::const_iterator
iIter( qDecreaseRange
.begin()); iIter
!= qDecreaseRange
.end(); iIter
++ )
2029 ScRange
aRange( *iIter
);
2030 if( pDoc
->HasAttrib( aRange
, HASATTR_OVERLAPPED
| HASATTR_MERGED
) )
2032 UnmergeCells( aRange
, TRUE
, TRUE
);
2040 rDocShell
.ErrorMessage(STR_MSSG_DELETECELLS_0
);
2041 rDocShell
.GetUndoManager()->LeaveListAction();
2052 WaitObject
aWait( rDocShell
.GetActiveDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference
2054 ScDocument
* pUndoDoc
= NULL
;
2055 ScDocument
* pRefUndoDoc
= NULL
;
2056 ScRefUndoData
* pUndoData
= NULL
;
2059 // With the fix for #101329#, UpdateRef always puts cells into pRefUndoDoc at their old position,
2060 // so it's no longer necessary to copy more than the deleted range into pUndoDoc.
2062 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
2063 pUndoDoc
->InitUndo( pDoc
, 0, nTabCount
-1, (eCmd
==DEL_DELCOLS
), (eCmd
==DEL_DELROWS
) );
2064 for( i
=0; i
<nTabCount
; i
++ )
2066 if( aMark
.GetTableSelect( i
) )
2068 SCTAB nScenarioCount
= 0;
2070 for( SCTAB j
= i
+1; j
<nTabCount
&& pDoc
->IsScenario(j
); j
++ )
2073 pDoc
->CopyToDocument( nUndoStartX
, nUndoStartY
, i
, nUndoEndX
, nUndoEndY
, i
+nScenarioCount
,
2074 IDF_ALL
| IDF_NOCAPTIONS
, FALSE
, pUndoDoc
);
2078 pRefUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
2079 pRefUndoDoc
->InitUndo( pDoc
, 0, nTabCount
-1, FALSE
, FALSE
);
2081 pUndoData
= new ScRefUndoData( pDoc
);
2083 pDoc
->BeginDrawUndo();
2086 USHORT nExtFlags
= 0;
2087 for( i
=0; i
<nTabCount
; i
++ )
2089 if( aMark
.GetTableSelect( i
) )
2090 rDocShell
.UpdatePaintExt( nExtFlags
, nStartCol
, nStartRow
, i
, nEndCol
, nEndRow
, i
);
2093 BOOL bUndoOutline
= FALSE
;
2097 pDoc
->DeleteRow( nStartCol
, 0, nEndCol
, MAXTAB
, nStartRow
, static_cast<SCSIZE
>(nEndRow
-nStartRow
+1), pRefUndoDoc
, NULL
, &aFullMark
);
2098 nPaintEndY
= MAXROW
;
2101 pDoc
->DeleteRow( 0, 0, MAXCOL
, MAXTAB
, nStartRow
, static_cast<SCSIZE
>(nEndRow
-nStartRow
+1), pRefUndoDoc
, &bUndoOutline
, &aFullMark
);
2103 nPaintEndX
= MAXCOL
;
2104 nPaintEndY
= MAXROW
;
2105 nPaintFlags
|= PAINT_LEFT
;
2108 pDoc
->DeleteCol( nStartRow
, 0, nEndRow
, MAXTAB
, nStartCol
, static_cast<SCSIZE
>(nEndCol
-nStartCol
+1), pRefUndoDoc
, NULL
, &aFullMark
);
2109 nPaintEndX
= MAXCOL
;
2112 pDoc
->DeleteCol( 0, 0, MAXROW
, MAXTAB
, nStartCol
, static_cast<SCSIZE
>(nEndCol
-nStartCol
+1), pRefUndoDoc
, &bUndoOutline
, &aFullMark
);
2114 nPaintEndY
= MAXROW
;
2115 nPaintEndX
= MAXCOL
;
2116 nPaintFlags
|= PAINT_TOP
;
2119 DBG_ERROR("Falscher Code beim Loeschen");
2123 //! Test, ob Outline in Groesse geaendert
2127 for( i
=0; i
<nTabCount
; i
++ )
2128 if( aFullMark
.GetTableSelect( i
) )
2129 pRefUndoDoc
->DeleteAreaTab(nUndoStartX
,nUndoStartY
,nUndoEndX
,nUndoEndY
, i
, IDF_ALL
);
2131 // alle Tabellen anlegen, damit Formeln kopiert werden koennen:
2132 pUndoDoc
->AddUndoTab( 0, nTabCount
-1, FALSE
, FALSE
);
2134 // kopieren mit bColRowFlags=FALSE (#54194#)
2135 pRefUndoDoc
->CopyToDocument(0,0,0,MAXCOL
,MAXROW
,MAXTAB
,IDF_FORMULA
,FALSE
,pUndoDoc
,NULL
,FALSE
);
2138 SCTAB
* pTabs
= new SCTAB
[nSelCount
];
2139 SCTAB
* pScenarios
= new SCTAB
[nSelCount
];
2142 for( i
=0; i
<nTabCount
; i
++ )
2144 if( aMark
.GetTableSelect( i
) )
2147 for( SCTAB j
=i
+1; j
<nTabCount
&& pDoc
->IsScenario(j
); j
++ )
2150 pScenarios
[nUndoPos
] = nCount
;
2151 pTabs
[nUndoPos
] = i
;
2156 if( !bDeletingMerge
)
2158 rDocShell
.GetUndoManager()->LeaveListAction();
2161 rDocShell
.GetUndoManager()->AddUndoAction( new ScUndoDeleteCells(
2162 &rDocShell
, ScRange( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
),nUndoPos
, pTabs
, pScenarios
,
2163 eCmd
, pUndoDoc
, pUndoData
) );
2166 // #i8302 want to be able to insert into the middle of merged cells
2167 // the patch comes from maoyg
2169 while( !qDecreaseRange
.empty() )
2171 ScRange aRange
= qDecreaseRange
.back();
2173 long nDecreaseRowCount
= 0;
2174 long nDecreaseColCount
= 0;
2175 if( eCmd
== DEL_CELLSUP
|| eCmd
== DEL_DELROWS
)
2177 if( nStartRow
>= aRange
.aStart
.Row() && nStartRow
<= aRange
.aEnd
.Row() && nEndRow
>= aRange
.aStart
.Row() && nEndRow
<= aRange
.aEnd
.Row() )
2178 nDecreaseRowCount
= nEndRow
-nStartRow
+1;
2179 else if( nStartRow
>= aRange
.aStart
.Row() && nStartRow
<= aRange
.aEnd
.Row() && nEndRow
>= aRange
.aStart
.Row() && nEndRow
>= aRange
.aEnd
.Row() )
2180 nDecreaseRowCount
= aRange
.aEnd
.Row()-nStartRow
+1;
2181 else if( nStartRow
>= aRange
.aStart
.Row() && nStartRow
>= aRange
.aEnd
.Row() && nEndRow
>= aRange
.aStart
.Row() && nEndRow
<= aRange
.aEnd
.Row() )
2182 nDecreaseRowCount
= aRange
.aEnd
.Row()-nEndRow
+1;
2184 else if( eCmd
== DEL_CELLSLEFT
|| eCmd
== DEL_DELCOLS
)
2186 if( nStartCol
>= aRange
.aStart
.Col() && nStartCol
<= aRange
.aEnd
.Col() && nEndCol
>= aRange
.aStart
.Col() && nEndCol
<= aRange
.aEnd
.Col() )
2187 nDecreaseColCount
= nEndCol
-nStartCol
+1;
2188 else if( nStartCol
>= aRange
.aStart
.Col() && nStartCol
<= aRange
.aEnd
.Col() && nEndCol
>= aRange
.aStart
.Col() && nEndCol
>= aRange
.aEnd
.Col() )
2189 nDecreaseColCount
= aRange
.aEnd
.Col()-nStartCol
+1;
2190 else if( nStartCol
>= aRange
.aStart
.Col() && nStartCol
>= aRange
.aEnd
.Col() && nEndCol
>= aRange
.aStart
.Col() && nEndCol
<= aRange
.aEnd
.Col() )
2191 nDecreaseColCount
= aRange
.aEnd
.Col()-nEndCol
+1;
2198 aRange
.aEnd
.SetRow(static_cast<SCsCOL
>( aRange
.aEnd
.Row()-nDecreaseRowCount
));
2202 aRange
.aEnd
.SetCol(static_cast<SCsCOL
>( aRange
.aEnd
.Col()-nDecreaseColCount
));
2208 if( !pDoc
->HasAttrib( aRange
, HASATTR_OVERLAPPED
| HASATTR_MERGED
) )
2210 ScCellMergeOption
aMergeOption(
2211 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
2212 aRange
.aEnd
.Col(), aRange
.aEnd
.Row() );
2213 MergeCells( aMergeOption
, FALSE
, TRUE
, TRUE
);
2215 qDecreaseRange
.pop_back();
2218 if( bDeletingMerge
)
2219 rDocShell
.GetUndoManager()->LeaveListAction();
2223 // #i51445# old merge flag attributes must be deleted also for single cells,
2224 // not only for whole columns/rows
2226 if ( eCmd
==DEL_DELCOLS
|| eCmd
==DEL_CELLSLEFT
)
2227 nMergeTestEndX
= MAXCOL
;
2228 if ( eCmd
==DEL_DELROWS
|| eCmd
==DEL_CELLSUP
)
2229 nMergeTestEndY
= MAXROW
;
2230 ScPatternAttr
aPattern( pDoc
->GetPool() );
2231 aPattern
.GetItemSet().Put( ScMergeFlagAttr() );
2233 pDoc
->ApplyPatternArea( nExtendStartCol
, nExtendStartRow
, nMergeTestEndX
, nMergeTestEndY
, aMark
, aPattern
);
2235 for( i
=0; i
<nTabCount
; i
++ )
2237 if( aMark
.GetTableSelect( i
) )
2239 SCTAB nScenarioCount
= 0;
2241 for( SCTAB j
= i
+1; j
<nTabCount
&& pDoc
->IsScenario(j
); j
++ )
2244 ScRange
aMergedRange( nExtendStartCol
, nExtendStartRow
, i
, nMergeTestEndX
, nMergeTestEndY
, i
+nScenarioCount
);
2245 pDoc
->ExtendMerge( aMergedRange
, TRUE
);
2250 for( i
=0; i
<nTabCount
; i
++ )
2252 if( aMark
.GetTableSelect( i
) )
2254 if ( eCmd
== DEL_DELCOLS
|| eCmd
== DEL_DELROWS
)
2255 pDoc
->UpdatePageBreaks( i
);
2257 rDocShell
.UpdatePaintExt( nExtFlags
, nPaintStartX
, nPaintStartY
, i
, nPaintEndX
, nPaintEndY
, i
);
2259 SCTAB nScenarioCount
= 0;
2261 for( SCTAB j
= i
+1; j
<nTabCount
&& pDoc
->IsScenario(j
); j
++ )
2264 // ganze Zeilen loeschen: nichts anpassen
2265 if ( eCmd
== DEL_DELROWS
|| !AdjustRowHeight(ScRange( 0, nPaintStartY
, i
, MAXCOL
, nPaintEndY
, i
+nScenarioCount
)) )
2266 rDocShell
.PostPaint( nPaintStartX
, nPaintStartY
, i
, nPaintEndX
, nPaintEndY
, i
+nScenarioCount
, nPaintFlags
, nExtFlags
);
2269 // paint only what is not done by AdjustRowHeight
2270 if (nExtFlags
& SC_PF_LINES
)
2271 lcl_PaintAbove( rDocShell
, ScRange( nPaintStartX
, nPaintStartY
, i
, nPaintEndX
, nPaintEndY
, i
+nScenarioCount
) );
2272 if (nPaintFlags
& PAINT_TOP
)
2273 rDocShell
.PostPaint( nPaintStartX
, nPaintStartY
, i
, nPaintEndX
, nPaintEndY
, i
+nScenarioCount
, PAINT_TOP
);
2277 aModificator
.SetDocumentModified();
2279 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED
) );
2284 BOOL
ScDocFunc::MoveBlock( const ScRange
& rSource
, const ScAddress
& rDestPos
,
2285 BOOL bCut
, BOOL bRecord
, BOOL bPaint
, BOOL bApi
)
2287 ScDocShellModificator
aModificator( rDocShell
);
2289 SCCOL nStartCol
= rSource
.aStart
.Col();
2290 SCROW nStartRow
= rSource
.aStart
.Row();
2291 SCTAB nStartTab
= rSource
.aStart
.Tab();
2292 SCCOL nEndCol
= rSource
.aEnd
.Col();
2293 SCROW nEndRow
= rSource
.aEnd
.Row();
2294 SCTAB nEndTab
= rSource
.aEnd
.Tab();
2295 SCCOL nDestCol
= rDestPos
.Col();
2296 SCROW nDestRow
= rDestPos
.Row();
2297 SCTAB nDestTab
= rDestPos
.Tab();
2299 if ( !ValidRow(nStartRow
) || !ValidRow(nEndRow
) || !ValidRow(nDestRow
) )
2301 DBG_ERROR("invalid row in MoveBlock");
2305 // zugehoerige Szenarien auch anpassen - nur wenn innerhalb einer Tabelle verschoben wird!
2306 BOOL bScenariosAdded
= FALSE
;
2307 ScDocument
* pDoc
= rDocShell
.GetDocument();
2308 if (bRecord
&& !pDoc
->IsUndoEnabled())
2311 SCTAB nTabCount
= pDoc
->GetTableCount();
2312 if ( nDestTab
== nStartTab
&& !pDoc
->IsScenario(nEndTab
) )
2313 while ( nEndTab
+1 < nTabCount
&& pDoc
->IsScenario(nEndTab
+1) )
2316 bScenariosAdded
= TRUE
;
2319 SCTAB nSrcTabCount
= nEndTab
-nStartTab
+1;
2320 SCTAB nDestEndTab
= nDestTab
+nSrcTabCount
-1;
2323 ScDocument
* pClipDoc
= new ScDocument( SCDOCMODE_CLIP
);
2325 ScMarkData aSourceMark
;
2326 for (nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
2327 aSourceMark
.SelectTable( nTab
, TRUE
); // Source selektieren
2328 aSourceMark
.SetMarkArea( rSource
);
2330 ScDocShellRef aDragShellRef
;
2331 if ( pDoc
->HasOLEObjectsInArea( rSource
) )
2333 aDragShellRef
= new ScDocShell
; // DocShell needs a Ref immediately
2334 aDragShellRef
->DoInitNew(NULL
);
2336 ScDrawLayer::SetGlobalDrawPersist(aDragShellRef
);
2338 ScClipParam
aClipParam(ScRange(nStartCol
, nStartRow
, 0, nEndCol
, nEndRow
, 0), bCut
);
2339 pDoc
->CopyToClip(aClipParam
, pClipDoc
, &aSourceMark
, false, bScenariosAdded
, true);
2341 ScDrawLayer::SetGlobalDrawPersist(NULL
);
2343 SCCOL nOldEndCol
= nEndCol
;
2344 SCROW nOldEndRow
= nEndRow
;
2345 BOOL bClipOver
= FALSE
;
2346 for (nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
2348 SCCOL nTmpEndCol
= nOldEndCol
;
2349 SCROW nTmpEndRow
= nOldEndRow
;
2350 if (pDoc
->ExtendMerge( nStartCol
, nStartRow
, nTmpEndCol
, nTmpEndRow
, nTab
))
2352 if ( nTmpEndCol
> nEndCol
) nEndCol
= nTmpEndCol
;
2353 if ( nTmpEndRow
> nEndRow
) nEndRow
= nTmpEndRow
;
2356 SCCOL nDestEndCol
= nDestCol
+ ( nOldEndCol
-nStartCol
);
2357 SCROW nDestEndRow
= nDestRow
+ ( nOldEndRow
-nStartRow
);
2359 SCCOL nUndoEndCol
= nDestCol
+ ( nEndCol
-nStartCol
); // erweitert im Zielblock
2360 SCROW nUndoEndRow
= nDestRow
+ ( nEndRow
-nStartRow
);
2362 BOOL bIncludeFiltered
= bCut
;
2363 if ( !bIncludeFiltered
)
2365 // adjust sizes to include only non-filtered rows
2369 pClipDoc
->GetClipArea( nClipX
, nClipY
, FALSE
);
2370 SCROW nUndoAdd
= nUndoEndRow
- nDestEndRow
;
2371 nDestEndRow
= nDestRow
+ nClipY
;
2372 nUndoEndRow
= nDestEndRow
+ nUndoAdd
;
2375 if (!ValidCol(nUndoEndCol
) || !ValidRow(nUndoEndRow
))
2378 rDocShell
.ErrorMessage(STR_PASTE_FULL
);
2383 // Test auf Zellschutz
2385 ScEditableTester aTester
;
2386 for (nTab
=nDestTab
; nTab
<=nDestEndTab
; nTab
++)
2387 aTester
.TestBlock( pDoc
, nTab
, nDestCol
,nDestRow
, nUndoEndCol
,nUndoEndRow
);
2389 for (nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
2390 aTester
.TestBlock( pDoc
, nTab
, nStartCol
,nStartRow
, nEndCol
,nEndRow
);
2392 if (!aTester
.IsEditable())
2395 rDocShell
.ErrorMessage(aTester
.GetMessageId());
2400 // Test auf zusammengefasste - beim Verschieben erst nach dem Loeschen
2402 if (bClipOver
&& !bCut
)
2403 if (pDoc
->HasAttrib( nDestCol
,nDestRow
,nDestTab
, nUndoEndCol
,nUndoEndRow
,nDestEndTab
,
2404 HASATTR_MERGED
| HASATTR_OVERLAPPED
))
2405 { // "Zusammenfassen nicht verschachteln !"
2407 rDocShell
.ErrorMessage(STR_MSSG_MOVEBLOCKTO_0
);
2412 // Are there borders in the cells? (for painting)
2414 USHORT nSourceExt
= 0;
2415 rDocShell
.UpdatePaintExt( nSourceExt
, nStartCol
,nStartRow
,nStartTab
, nEndCol
,nEndRow
,nEndTab
);
2416 USHORT nDestExt
= 0;
2417 rDocShell
.UpdatePaintExt( nDestExt
, nDestCol
,nDestRow
,nDestTab
, nDestEndCol
,nDestEndRow
,nDestEndTab
);
2423 ScDocument
* pUndoDoc
= NULL
;
2424 ScDocument
* pRefUndoDoc
= NULL
;
2425 ScRefUndoData
* pUndoData
= NULL
;
2428 BOOL bWholeCols
= ( nStartRow
== 0 && nEndRow
== MAXROW
);
2429 BOOL bWholeRows
= ( nStartCol
== 0 && nEndCol
== MAXCOL
);
2430 USHORT nUndoFlags
= (IDF_ALL
& ~IDF_OBJECTS
) | IDF_NOCAPTIONS
;
2432 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
2433 pUndoDoc
->InitUndo( pDoc
, nStartTab
, nEndTab
, bWholeCols
, bWholeRows
);
2437 pDoc
->CopyToDocument( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
,
2438 nUndoFlags
, FALSE
, pUndoDoc
);
2439 pRefUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
2440 pRefUndoDoc
->InitUndo( pDoc
, 0, nTabCount
-1, FALSE
, FALSE
);
2443 if ( nDestTab
!= nStartTab
)
2444 pUndoDoc
->AddUndoTab( nDestTab
, nDestEndTab
, bWholeCols
, bWholeRows
);
2445 pDoc
->CopyToDocument( nDestCol
, nDestRow
, nDestTab
,
2446 nDestEndCol
, nDestEndRow
, nDestEndTab
,
2447 nUndoFlags
, FALSE
, pUndoDoc
);
2449 pUndoData
= new ScRefUndoData( pDoc
);
2451 pDoc
->BeginDrawUndo();
2454 BOOL bSourceHeight
= FALSE
; // Hoehen angepasst?
2457 ScMarkData aDelMark
; // only for tables
2458 for (nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
2460 pDoc
->DeleteAreaTab( nStartCol
,nStartRow
, nOldEndCol
,nOldEndRow
, nTab
, IDF_ALL
);
2461 aDelMark
.SelectTable( nTab
, TRUE
);
2463 pDoc
->DeleteObjectsInArea( nStartCol
,nStartRow
, nOldEndCol
,nOldEndRow
, aDelMark
);
2465 // Test auf zusammengefasste
2468 if (pDoc
->HasAttrib( nDestCol
,nDestRow
,nDestTab
,
2469 nUndoEndCol
,nUndoEndRow
,nDestEndTab
,
2470 HASATTR_MERGED
| HASATTR_OVERLAPPED
))
2472 pDoc
->CopyFromClip( rSource
, aSourceMark
, IDF_ALL
, pRefUndoDoc
, pClipDoc
);
2473 for (nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
2475 SCCOL nTmpEndCol
= nEndCol
;
2476 SCROW nTmpEndRow
= nEndRow
;
2477 pDoc
->ExtendMerge( nStartCol
, nStartRow
, nTmpEndCol
, nTmpEndRow
, nTab
, TRUE
);
2480 // Fehlermeldung erst nach dem Wiederherstellen des Inhalts
2481 if (!bApi
) // "Zusammenfassen nicht verschachteln !"
2482 rDocShell
.ErrorMessage(STR_MSSG_MOVEBLOCKTO_0
);
2491 bSourceHeight
= AdjustRowHeight( rSource
, FALSE
);
2494 ScRange
aPasteDest( nDestCol
, nDestRow
, nDestTab
, nDestEndCol
, nDestEndRow
, nDestEndTab
);
2496 ScMarkData aDestMark
;
2497 for (nTab
=nDestTab
; nTab
<=nDestEndTab
; nTab
++)
2498 aDestMark
.SelectTable( nTab
, TRUE
); // Destination selektieren
2499 aDestMark
.SetMarkArea( aPasteDest
);
2501 /* Do not copy cell notes and drawing objects here. While pasting, the
2502 function ScDocument::UpdateReference() is called which calls
2503 ScDrawLayer::MoveCells() which may move away inserted objects to wrong
2504 positions (e.g. if source and destination range overlaps). Cell notes
2505 and drawing objects are pasted below after doing all adjusting. */
2506 pDoc
->CopyFromClip( aPasteDest
, aDestMark
, IDF_ALL
& ~(IDF_NOTE
| IDF_OBJECTS
),
2507 pRefUndoDoc
, pClipDoc
, TRUE
, FALSE
, bIncludeFiltered
);
2509 // skipped rows and merged cells don't mix
2510 if ( !bIncludeFiltered
&& pClipDoc
->HasClipFilteredRows() )
2511 UnmergeCells( aPasteDest
, FALSE
, TRUE
);
2513 VirtualDevice aVirtDev
;
2514 BOOL bDestHeight
= AdjustRowHeight(
2515 ScRange( 0,nDestRow
,nDestTab
, MAXCOL
,nDestEndRow
,nDestEndTab
),
2518 /* Paste cell notes and drawing objects after adjusting formula references
2519 and row heights. There are no cell notes or drawing objects, if the
2520 clipdoc does not contain a drawing layer.
2521 #i102056# Passing IDF_NOTE only would overwrite cell contents with
2522 empty note cells, therefore the special modifier IDF_ADDNOTES is passed
2523 here too which changes the behaviour of ScColumn::CopyFromClip() to not
2524 touch existing cells. */
2525 if ( pClipDoc
->GetDrawLayer() )
2526 pDoc
->CopyFromClip( aPasteDest
, aDestMark
, IDF_NOTE
| IDF_ADDNOTES
| IDF_OBJECTS
,
2527 pRefUndoDoc
, pClipDoc
, TRUE
, FALSE
, bIncludeFiltered
);
2533 // alle Tabellen anlegen, damit Formeln kopiert werden koennen:
2534 pUndoDoc
->AddUndoTab( 0, nTabCount
-1, FALSE
, FALSE
);
2536 pRefUndoDoc
->DeleteArea( nDestCol
, nDestRow
, nDestEndCol
, nDestEndRow
, aSourceMark
, IDF_ALL
);
2537 // kopieren mit bColRowFlags=FALSE (#54194#)
2538 pRefUndoDoc
->CopyToDocument( 0, 0, 0, MAXCOL
, MAXROW
, MAXTAB
,
2539 IDF_FORMULA
, FALSE
, pUndoDoc
, NULL
, FALSE
);
2543 rDocShell
.GetUndoManager()->AddUndoAction(
2544 new ScUndoDragDrop( &rDocShell
, ScRange(
2545 nStartCol
, nStartRow
, nStartTab
,
2546 nOldEndCol
, nOldEndRow
, nEndTab
),
2547 ScAddress( nDestCol
, nDestRow
, nDestTab
),
2548 bCut
, pUndoDoc
, pUndoData
, bScenariosAdded
) );
2551 SCCOL nDestPaintEndCol
= nDestEndCol
;
2552 SCROW nDestPaintEndRow
= nDestEndRow
;
2553 for (nTab
=nDestTab
; nTab
<=nDestEndTab
; nTab
++)
2555 SCCOL nTmpEndCol
= nDestEndCol
;
2556 SCROW nTmpEndRow
= nDestEndRow
;
2557 pDoc
->ExtendMerge( nDestCol
, nDestRow
, nTmpEndCol
, nTmpEndRow
, nTab
, TRUE
);
2558 if (nTmpEndCol
> nDestPaintEndCol
) nDestPaintEndCol
= nTmpEndCol
;
2559 if (nTmpEndRow
> nDestPaintEndRow
) nDestPaintEndRow
= nTmpEndRow
;
2563 for (nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
2564 pDoc
->RefreshAutoFilter( nStartCol
, nStartRow
, nEndCol
, nEndRow
, nTab
);
2570 SCCOL nPaintStartX
= nDestCol
;
2571 SCROW nPaintStartY
= nDestRow
;
2572 SCCOL nPaintEndX
= nDestPaintEndCol
;
2573 SCROW nPaintEndY
= nDestPaintEndRow
;
2574 USHORT nFlags
= PAINT_GRID
;
2576 if ( nStartRow
==0 && nEndRow
==MAXROW
) // Breiten mitkopiert?
2578 nPaintEndX
= MAXCOL
;
2580 nPaintEndY
= MAXROW
;
2581 nFlags
|= PAINT_TOP
;
2583 if ( bDestHeight
|| ( nStartCol
== 0 && nEndCol
== MAXCOL
) )
2585 nPaintEndY
= MAXROW
;
2587 nPaintEndX
= MAXCOL
;
2588 nFlags
|= PAINT_LEFT
;
2590 if ( bScenariosAdded
)
2594 nPaintEndX
= MAXCOL
;
2595 nPaintEndY
= MAXROW
;
2598 rDocShell
.PostPaint( nPaintStartX
,nPaintStartY
,nDestTab
,
2599 nPaintEndX
,nPaintEndY
,nDestEndTab
, nFlags
, nSourceExt
| nDestExt
);
2605 nPaintStartX
= nStartCol
;
2606 nPaintStartY
= nStartRow
;
2607 nPaintEndX
= nEndCol
;
2608 nPaintEndY
= nEndRow
;
2609 nFlags
= PAINT_GRID
;
2611 if ( bSourceHeight
)
2613 nPaintEndY
= MAXROW
;
2615 nPaintEndX
= MAXCOL
;
2616 nFlags
|= PAINT_LEFT
;
2618 if ( bScenariosAdded
)
2622 nPaintEndX
= MAXCOL
;
2623 nPaintEndY
= MAXROW
;
2626 rDocShell
.PostPaint( nPaintStartX
,nPaintStartY
,nStartTab
,
2627 nPaintEndX
,nPaintEndY
,nEndTab
, nFlags
, nSourceExt
);
2631 aModificator
.SetDocumentModified();
2633 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED
) );
2639 //------------------------------------------------------------------------
2640 uno::Reference
< uno::XInterface
> GetDocModuleObject( SfxObjectShell
& rDocSh
, String
& sCodeName
)
2642 uno::Reference
< lang::XMultiServiceFactory
> xSF(rDocSh
.GetModel(), uno::UNO_QUERY
);
2643 uno::Reference
< container::XNameAccess
> xVBACodeNamedObjectAccess
;
2644 uno::Reference
< uno::XInterface
> xDocModuleApiObject
;
2647 xVBACodeNamedObjectAccess
.set( xSF
->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAObjectModuleObjectProvider"))), uno::UNO_QUERY
);
2648 xDocModuleApiObject
.set( xVBACodeNamedObjectAccess
->getByName( sCodeName
), uno::UNO_QUERY
);
2650 return xDocModuleApiObject
;
2654 script::ModuleInfo
lcl_InitModuleInfo( SfxObjectShell
& rDocSh
, String
& sModule
, String
& sSource
)
2656 ::rtl::OUString
aModName( sModule
);
2657 ::rtl::OUString
sVbaOption( RTL_CONSTASCII_USTRINGPARAM( "Rem Attribute VBA_ModuleType=VBADocumentModule\nOption VBASupport 1\n" ));
2658 script::ModuleInfo sModuleInfo
;
2659 sModuleInfo
.ModuleName
= aModName
;
2660 if ( sSource
.Len() > 0 )
2661 sModuleInfo
.ModuleSource
= sSource
;
2663 sModuleInfo
.ModuleSource
= sVbaOption
;
2664 sModuleInfo
.ModuleType
= script::ModuleType::Document
;
2665 sModuleInfo
.ModuleObject
= GetDocModuleObject( rDocSh
, sModule
);
2669 void lcl_InsertModule( ScDocShell
& rDocSh
, SCTAB nTab
, String
& sModuleName
, String
& sSource
)
2671 SFX_APP()->EnterBasicCall();
2672 script::ModuleInfo sModuleInfo
= lcl_InitModuleInfo( rDocSh
, sModuleName
, sSource
);
2673 uno::Reference
< script::XLibraryContainer
> xLibContainer
= rDocSh
.GetBasicContainer();
2674 DBG_ASSERT( xLibContainer
.is(), "No BasicContainer!" );
2676 uno::Reference
< container::XNameContainer
> xLib
;
2677 if( xLibContainer
.is() )
2679 String
aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
2680 uno::Any aLibAny
= xLibContainer
->getByName( aLibName
);
2685 // if the Module with codename exists then find a new name
2687 sModuleInfo
.ModuleName
= sModuleName
;
2688 while( xLib
->hasByName( sModuleInfo
.ModuleName
) )
2690 sModuleInfo
.ModuleName
= rtl::OUString::createFromAscii( "Sheet" ) + rtl::OUString::valueOf( nNum
);
2693 uno::Any aSourceAny
;
2694 aSourceAny
<<= sModuleInfo
;
2695 xLib
->insertByName( sModuleInfo
.ModuleName
, aSourceAny
);
2696 ScDocument
* pDoc
= rDocSh
.GetDocument();
2697 String
sCodeName( sModuleInfo
.ModuleName
);
2698 pDoc
->SetCodeName( nTab
, sCodeName
);
2700 SFX_APP()->LeaveBasicCall();
2703 void lcl_DeleteModule( ScDocShell
& rDocSh
, String
& sModuleName
)
2705 SFX_APP()->EnterBasicCall();
2706 uno::Reference
< script::XLibraryContainer
> xLibContainer
= rDocSh
.GetBasicContainer();
2707 DBG_ASSERT( xLibContainer
.is(), "No BasicContainer!" );
2709 uno::Reference
< container::XNameContainer
> xLib
;
2710 if( xLibContainer
.is() )
2712 String
aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
2713 uno::Any aLibAny
= xLibContainer
->getByName( aLibName
);
2718 if( xLib
->hasByName( sModuleName
) )
2720 xLib
->removeByName( sModuleName
);
2723 SFX_APP()->LeaveBasicCall();
2727 BOOL
ScDocFunc::InsertTable( SCTAB nTab
, const String
& rName
, BOOL bRecord
, BOOL bApi
)
2729 BOOL bSuccess
= FALSE
;
2730 WaitObject
aWait( rDocShell
.GetActiveDialogParent() );
2732 ScDocShellModificator
aModificator( rDocShell
);
2734 ScDocument
* pDoc
= rDocShell
.GetDocument();
2735 // Strange loop, also basic is loaded too early ( InsertTable )
2736 // is called via the xml import for sheets in described in odf
2737 BOOL bInsertDocModule
= false;
2739 if( !rDocShell
.GetDocument()->IsImportingXML() )
2741 StarBASIC
* pStarBASIC
= rDocShell
.GetBasic();
2742 bInsertDocModule
= pStarBASIC
? pStarBASIC
->isVBAEnabled() : false;
2744 if ( bInsertDocModule
|| ( bRecord
&& !pDoc
->IsUndoEnabled() ) )
2748 pDoc
->BeginDrawUndo(); // InsertTab erzeugt ein SdrUndoNewPage
2750 SCTAB nTabCount
= pDoc
->GetTableCount();
2751 BOOL bAppend
= ( nTab
>= nTabCount
);
2753 nTab
= nTabCount
; // wichtig fuer Undo
2755 if (pDoc
->InsertTab( nTab
, rName
))
2759 rDocShell
.GetUndoManager()->AddUndoAction(
2760 new ScUndoInsertTab( &rDocShell
, nTab
, bAppend
, rName
));
2762 // Only insert vba modules if vba mode ( and not currently importing XML )
2763 if( bInsertDocModule
)
2765 if ( sCodeName
.Len() == 0 )
2768 lcl_InsertModule( rDocShell
, nTab
, sCodeName
, sSource
);
2770 rDocShell
.Broadcast( ScTablesHint( SC_TAB_INSERTED
, nTab
) );
2772 rDocShell
.PostPaintExtras();
2773 aModificator
.SetDocumentModified();
2774 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
2778 rDocShell
.ErrorMessage(STR_TABINSERT_ERROR
);
2783 BOOL
ScDocFunc::DeleteTable( SCTAB nTab
, BOOL bRecord
, BOOL
/* bApi */ )
2785 WaitObject
aWait( rDocShell
.GetActiveDialogParent() );
2787 ScDocShellModificator
aModificator( rDocShell
);
2789 BOOL bSuccess
= FALSE
;
2790 ScDocument
* pDoc
= rDocShell
.GetDocument();
2791 StarBASIC
* pStarBASIC
= rDocShell
.GetBasic();
2792 BOOL bVbaEnabled
= pStarBASIC
->isVBAEnabled();
2793 if (bRecord
&& !pDoc
->IsUndoEnabled())
2797 BOOL bWasLinked
= pDoc
->IsLinked(nTab
);
2798 ScDocument
* pUndoDoc
= NULL
;
2799 ScRefUndoData
* pUndoData
= NULL
;
2802 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
2803 SCTAB nCount
= pDoc
->GetTableCount();
2805 pUndoDoc
->InitUndo( pDoc
, nTab
, nTab
, TRUE
, TRUE
); // nur nTab mit Flags
2806 pUndoDoc
->AddUndoTab( 0, nCount
-1 ); // alle Tabs fuer Referenzen
2808 pDoc
->CopyToDocument(0,0,nTab
, MAXCOL
,MAXROW
,nTab
, IDF_ALL
,FALSE
, pUndoDoc
);
2810 pDoc
->GetName( nTab
, aOldName
);
2811 pUndoDoc
->RenameTab( nTab
, aOldName
, FALSE
);
2813 pUndoDoc
->SetLink( nTab
, pDoc
->GetLinkMode(nTab
), pDoc
->GetLinkDoc(nTab
),
2814 pDoc
->GetLinkFlt(nTab
), pDoc
->GetLinkOpt(nTab
),
2815 pDoc
->GetLinkTab(nTab
),
2816 pDoc
->GetLinkRefreshDelay(nTab
) );
2818 if ( pDoc
->IsScenario(nTab
) )
2820 pUndoDoc
->SetScenario( nTab
, TRUE
);
2824 pDoc
->GetScenarioData( nTab
, aComment
, aColor
, nScenFlags
);
2825 pUndoDoc
->SetScenarioData( nTab
, aComment
, aColor
, nScenFlags
);
2826 BOOL bActive
= pDoc
->IsActiveScenario( nTab
);
2827 pUndoDoc
->SetActiveScenario( nTab
, bActive
);
2829 pUndoDoc
->SetVisible( nTab
, pDoc
->IsVisible( nTab
) );
2831 // Drawing-Layer muss sein Undo selbst in der Hand behalten !!!
2832 pDoc
->BeginDrawUndo(); // DeleteTab erzeugt ein SdrUndoDelPage
2834 pUndoData
= new ScRefUndoData( pDoc
);
2838 BOOL bHasCodeName
= pDoc
->GetCodeName( nTab
, sCodeName
);
2839 if (pDoc
->DeleteTab( nTab
, pUndoDoc
))
2844 theTabs
.Insert(nTab
,theTabs
.Count());
2845 rDocShell
.GetUndoManager()->AddUndoAction(
2846 new ScUndoDeleteTab( &rDocShell
, theTabs
, pUndoDoc
, pUndoData
));
2853 lcl_DeleteModule( rDocShell
, sCodeName
);
2856 rDocShell
.Broadcast( ScTablesHint( SC_TAB_DELETED
, nTab
) );
2860 rDocShell
.UpdateLinks(); // Link-Manager updaten
2861 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
2863 pBindings
->Invalidate(SID_LINKS
);
2866 rDocShell
.PostPaintExtras();
2867 aModificator
.SetDocumentModified();
2869 SfxApplication
* pSfxApp
= SFX_APP(); // Navigator
2870 pSfxApp
->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
2871 pSfxApp
->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED
) );
2872 pSfxApp
->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED
) );
2884 BOOL
ScDocFunc::SetTableVisible( SCTAB nTab
, BOOL bVisible
, BOOL bApi
)
2886 ScDocument
* pDoc
= rDocShell
.GetDocument();
2887 BOOL
bUndo(pDoc
->IsUndoEnabled());
2888 if ( pDoc
->IsVisible( nTab
) == bVisible
)
2889 return TRUE
; // nichts zu tun - ok
2891 if ( !pDoc
->IsDocEditable() )
2894 rDocShell
.ErrorMessage(STR_PROTECTIONERR
);
2898 ScDocShellModificator
aModificator( rDocShell
);
2900 if ( !bVisible
&& !pDoc
->IsImportingXML() ) // #i57869# allow hiding in any order for loading
2902 // nicht alle Tabellen ausblenden
2904 USHORT nVisCount
= 0;
2905 SCTAB nCount
= pDoc
->GetTableCount();
2906 for (SCTAB i
=0; i
<nCount
; i
++)
2907 if (pDoc
->IsVisible(i
))
2913 rDocShell
.ErrorMessage(STR_PROTECTIONERR
); //! eigene Meldung?
2918 pDoc
->SetVisible( nTab
, bVisible
);
2920 rDocShell
.GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( &rDocShell
, nTab
, bVisible
) );
2924 rDocShell
.Broadcast( ScTablesHint( SC_TAB_HIDDEN
, nTab
) );
2926 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
2927 rDocShell
.PostPaint(0,0,0,MAXCOL
,MAXROW
,MAXTAB
, PAINT_EXTRAS
);
2928 aModificator
.SetDocumentModified();
2933 BOOL
ScDocFunc::SetLayoutRTL( SCTAB nTab
, BOOL bRTL
, BOOL
/* bApi */ )
2935 ScDocument
* pDoc
= rDocShell
.GetDocument();
2936 BOOL
bUndo(pDoc
->IsUndoEnabled());
2937 if ( pDoc
->IsLayoutRTL( nTab
) == bRTL
)
2938 return TRUE
; // nothing to do - ok
2940 //! protection (sheet or document?)
2942 ScDocShellModificator
aModificator( rDocShell
);
2944 pDoc
->SetLayoutRTL( nTab
, bRTL
);
2948 rDocShell
.GetUndoManager()->AddUndoAction( new ScUndoLayoutRTL( &rDocShell
, nTab
, bRTL
) );
2951 rDocShell
.PostPaint( 0,0,0,MAXCOL
,MAXROW
,MAXTAB
, PAINT_ALL
);
2952 aModificator
.SetDocumentModified();
2954 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
2957 pBindings
->Invalidate( FID_TAB_RTL
);
2958 pBindings
->Invalidate( SID_ATTR_SIZE
);
2964 //UNUSED2009-05 BOOL ScDocFunc::SetGrammar( formula::FormulaGrammar::Grammar eGrammar )
2966 //UNUSED2009-05 ScDocument* pDoc = rDocShell.GetDocument();
2968 //UNUSED2009-05 if ( pDoc->GetGrammar() == eGrammar )
2969 //UNUSED2009-05 return TRUE;
2971 //UNUSED2009-05 BOOL bUndo(pDoc->IsUndoEnabled());
2972 //UNUSED2009-05 ScDocShellModificator aModificator( rDocShell );
2974 //UNUSED2009-05 pDoc->SetGrammar( eGrammar );
2976 //UNUSED2009-05 if (bUndo)
2978 //UNUSED2009-05 rDocShell.GetUndoManager()->AddUndoAction( new ScUndoSetGrammar( &rDocShell, eGrammar ) );
2981 //UNUSED2009-05 rDocShell.PostPaint( 0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_ALL );
2983 //UNUSED2009-05 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
2984 //UNUSED2009-05 if (NULL != pViewSh)
2986 //UNUSED2009-05 pViewSh->UpdateInputHandler( FALSE, FALSE );
2989 //UNUSED2009-05 aModificator.SetDocumentModified();
2991 //UNUSED2009-05 SfxBindings* pBindings = rDocShell.GetViewBindings();
2992 //UNUSED2009-05 if (pBindings)
2994 //UNUSED2009-05 // erAck: 2006-09-07T22:19+0200 commented out in CWS scr1c1
2995 //UNUSED2009-05 //pBindings->Invalidate( FID_TAB_USE_R1C1 );
2998 //UNUSED2009-05 return TRUE;
3001 BOOL
ScDocFunc::RenameTable( SCTAB nTab
, const String
& rName
, BOOL bRecord
, BOOL bApi
)
3003 ScDocument
* pDoc
= rDocShell
.GetDocument();
3004 if (bRecord
&& !pDoc
->IsUndoEnabled())
3006 if ( !pDoc
->IsDocEditable() )
3009 rDocShell
.ErrorMessage(STR_PROTECTIONERR
);
3013 ScDocShellModificator
aModificator( rDocShell
);
3015 BOOL bSuccess
= FALSE
;
3017 pDoc
->GetName(nTab
, sOldName
);
3018 if (pDoc
->RenameTab( nTab
, rName
))
3022 rDocShell
.GetUndoManager()->AddUndoAction(
3023 new ScUndoRenameTab( &rDocShell
, nTab
, sOldName
, rName
));
3025 rDocShell
.PostPaintExtras();
3026 aModificator
.SetDocumentModified();
3027 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
3034 BOOL
ScDocFunc::SetTabBgColor( SCTAB nTab
, const Color
& rColor
, BOOL bRecord
, BOOL bApi
)
3037 ScDocument
* pDoc
= rDocShell
.GetDocument();
3038 if (bRecord
&& !pDoc
->IsUndoEnabled())
3040 if ( !pDoc
->IsDocEditable() || pDoc
->IsTabProtected(nTab
) )
3043 rDocShell
.ErrorMessage(STR_PROTECTIONERR
); //TODO Check to see what this string is...
3047 ScViewData
* pViewData
= rDocShell
.GetViewData();
3049 Color aOldTabBgColor
;
3050 aOldTabBgColor
= pViewData
->GetTabBgColor(nTab
);
3052 BOOL bSuccess
= FALSE
;
3053 pViewData
->SetTabBgColor(rColor
, nTab
);
3054 if ( pViewData
->GetTabBgColor( nTab
) == rColor
)
3060 rDocShell
.GetUndoManager()->AddUndoAction(
3061 new ScUndoSetTabBgColor( &rDocShell
, nTab
, aOldTabBgColor
, rColor
));
3063 rDocShell
.PostPaintExtras();
3064 ScDocShellModificator
aModificator( rDocShell
);
3065 aModificator
.SetDocumentModified();
3066 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
3073 BOOL
ScDocFunc::SetTabBgColor( ScUndoSetTabBgColorInfoList
* rUndoSetTabBgColorInfoList
, BOOL bRecord
, BOOL bApi
)
3075 ScDocument
* pDoc
= rDocShell
.GetDocument();
3076 if (bRecord
&& !pDoc
->IsUndoEnabled())
3078 if ( !pDoc
->IsDocEditable() )
3081 rDocShell
.ErrorMessage(STR_PROTECTIONERR
); //TODO Get a better String Error...
3085 ScViewData
* pViewData
= rDocShell
.GetViewData();
3087 Color aNewTabBgColor
;
3088 ScUndoSetTabBgColorInfo
* rUndoSetTabBgColorInfo
;
3089 BOOL bSuccess
= TRUE
;
3090 USHORT nTabProtectCount
= 0;
3091 for ( USHORT i
=0; i
< rUndoSetTabBgColorInfoList
->Count(); i
++ )
3093 rUndoSetTabBgColorInfo
= rUndoSetTabBgColorInfoList
->GetObject(i
);
3094 nTab
= rUndoSetTabBgColorInfo
->nTabId
;
3095 if ( !pDoc
->IsTabProtected(nTab
) )
3097 aNewTabBgColor
= rUndoSetTabBgColorInfo
->aNewTabBgColor
;
3098 rUndoSetTabBgColorInfo
->aOldTabBgColor
= pViewData
->GetTabBgColor(nTab
);
3099 pViewData
->SetTabBgColor(aNewTabBgColor
, nTab
);
3100 if ( pViewData
->GetTabBgColor( nTab
) != aNewTabBgColor
)
3111 if ( nTabProtectCount
== rUndoSetTabBgColorInfoList
->Count() )
3114 rDocShell
.ErrorMessage(STR_PROTECTIONERR
); //TODO Get a better String Error...
3121 rDocShell
.GetUndoManager()->AddUndoAction(
3122 new ScUndoSetTabBgColor( &rDocShell
, rUndoSetTabBgColorInfoList
));
3124 rDocShell
.PostPaintExtras();
3125 ScDocShellModificator
aModificator( rDocShell
);
3126 aModificator
.SetDocumentModified();
3127 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
3132 //------------------------------------------------------------------------
3134 //! SetWidthOrHeight - noch doppelt zu ViewFunc !!!!!!
3136 //! - Optimale Hoehe fuer Edit-Zellen ist unterschiedlich zwischen Drucker und Bildschirm
3137 //! - Optimale Breite braucht Selektion, um evtl. nur selektierte Zellen zu beruecksichtigen
3139 USHORT
lcl_GetOptimalColWidth( ScDocShell
& rDocShell
, SCCOL nCol
, SCTAB nTab
, BOOL bFormula
)
3143 ScSizeDeviceProvider
aProv(&rDocShell
);
3144 OutputDevice
* pDev
= aProv
.GetDevice(); // has pixel MapMode
3145 double nPPTX
= aProv
.GetPPTX();
3146 double nPPTY
= aProv
.GetPPTY();
3148 ScDocument
* pDoc
= rDocShell
.GetDocument();
3150 nTwips
= pDoc
->GetOptimalColWidth( nCol
, nTab
, pDev
, nPPTX
, nPPTY
, aOne
, aOne
,
3156 BOOL
ScDocFunc::SetWidthOrHeight( BOOL bWidth
, SCCOLROW nRangeCnt
, SCCOLROW
* pRanges
, SCTAB nTab
,
3157 ScSizeMode eMode
, USHORT nSizeTwips
,
3158 BOOL bRecord
, BOOL bApi
)
3163 ScDocument
* pDoc
= rDocShell
.GetDocument();
3164 if ( bRecord
&& !pDoc
->IsUndoEnabled() )
3167 // import into read-only document is possible
3168 if ( !pDoc
->IsChangeReadOnlyEnabled() && !rDocShell
.IsEditable() )
3171 rDocShell
.ErrorMessage(STR_PROTECTIONERR
); //! eigene Meldung?
3175 BOOL bSuccess
= FALSE
;
3176 SCCOLROW nStart
= pRanges
[0];
3177 SCCOLROW nEnd
= pRanges
[2*nRangeCnt
-1];
3179 BOOL bFormula
= FALSE
;
3180 if ( eMode
== SC_SIZE_OPTIMAL
)
3182 //! Option "Formeln anzeigen" - woher nehmen?
3185 ScDocument
* pUndoDoc
= NULL
;
3186 ScOutlineTable
* pUndoTab
= NULL
;
3187 SCCOLROW
* pUndoRanges
= NULL
;
3191 pDoc
->BeginDrawUndo(); // Drawing Updates
3193 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
3196 pUndoDoc
->InitUndo( pDoc
, nTab
, nTab
, TRUE
, FALSE
);
3197 pDoc
->CopyToDocument( static_cast<SCCOL
>(nStart
), 0, nTab
, static_cast<SCCOL
>(nEnd
), MAXROW
, nTab
, IDF_NONE
, FALSE
, pUndoDoc
);
3201 pUndoDoc
->InitUndo( pDoc
, nTab
, nTab
, FALSE
, TRUE
);
3202 pDoc
->CopyToDocument( 0, static_cast<SCROW
>(nStart
), nTab
, MAXCOL
, static_cast<SCROW
>(nEnd
), nTab
, IDF_NONE
, FALSE
, pUndoDoc
);
3205 pUndoRanges
= new SCCOLROW
[ 2*nRangeCnt
];
3206 memmove( pUndoRanges
, pRanges
, 2*nRangeCnt
*sizeof(SCCOLROW
) );
3208 ScOutlineTable
* pTable
= pDoc
->GetOutlineTable( nTab
);
3210 pUndoTab
= new ScOutlineTable( *pTable
);
3213 BOOL bShow
= nSizeTwips
> 0 || eMode
!= SC_SIZE_DIRECT
;
3214 BOOL bOutline
= FALSE
;
3216 pDoc
->IncSizeRecalcLevel( nTab
); // nicht fuer jede Spalte einzeln
3217 for (SCCOLROW nRangeNo
=0; nRangeNo
<nRangeCnt
; nRangeNo
++)
3219 SCCOLROW nStartNo
= *(pRanges
++);
3220 SCCOLROW nEndNo
= *(pRanges
++);
3222 if ( !bWidth
) // Hoehen immer blockweise
3224 if ( eMode
==SC_SIZE_OPTIMAL
|| eMode
==SC_SIZE_VISOPT
)
3226 BOOL bAll
= ( eMode
==SC_SIZE_OPTIMAL
);
3229 // fuer alle eingeblendeten CR_MANUALSIZE loeschen,
3230 // dann SetOptimalHeight mit bShrink = FALSE
3231 for (SCROW nRow
=nStartNo
; nRow
<=nEndNo
; nRow
++)
3233 BYTE nOld
= pDoc
->GetRowFlags(nRow
,nTab
);
3234 SCROW nLastRow
= -1;
3235 bool bHidden
= pDoc
->RowHidden(nRow
, nTab
, nLastRow
);
3236 if ( !bHidden
&& ( nOld
& CR_MANUALSIZE
) )
3237 pDoc
->SetRowFlags( nRow
, nTab
, nOld
& ~CR_MANUALSIZE
);
3241 ScSizeDeviceProvider
aProv( &rDocShell
);
3243 pDoc
->SetOptimalHeight( nStartNo
, nEndNo
, nTab
, 0, aProv
.GetDevice(),
3244 aProv
.GetPPTX(), aProv
.GetPPTY(), aOne
, aOne
, bAll
);
3247 pDoc
->ShowRows( nStartNo
, nEndNo
, nTab
, TRUE
);
3249 // Manual-Flag wird bei bAll=TRUE schon in SetOptimalHeight gesetzt
3250 // (an bei Extra-Height, sonst aus).
3252 else if ( eMode
==SC_SIZE_DIRECT
|| eMode
==SC_SIZE_ORIGINAL
)
3256 pDoc
->SetRowHeightRange( nStartNo
, nEndNo
, nTab
, nSizeTwips
);
3257 pDoc
->SetManualHeight( nStartNo
, nEndNo
, nTab
, TRUE
); // height was set manually
3259 if ( eMode
!= SC_SIZE_ORIGINAL
)
3260 pDoc
->ShowRows( nStartNo
, nEndNo
, nTab
, nSizeTwips
!= 0 );
3262 else if ( eMode
==SC_SIZE_SHOW
)
3264 pDoc
->ShowRows( nStartNo
, nEndNo
, nTab
, TRUE
);
3267 else // Spaltenbreiten
3269 for (SCCOL nCol
=static_cast<SCCOL
>(nStartNo
); nCol
<=static_cast<SCCOL
>(nEndNo
); nCol
++)
3271 SCCOL nLastCol
= -1;
3272 if ( eMode
!= SC_SIZE_VISOPT
|| !pDoc
->ColHidden(nCol
, nTab
, nLastCol
) )
3274 USHORT nThisSize
= nSizeTwips
;
3276 if ( eMode
==SC_SIZE_OPTIMAL
|| eMode
==SC_SIZE_VISOPT
)
3277 nThisSize
= nSizeTwips
+
3278 lcl_GetOptimalColWidth( rDocShell
, nCol
, nTab
, bFormula
);
3280 pDoc
->SetColWidth( nCol
, nTab
, nThisSize
);
3282 if ( eMode
!= SC_SIZE_ORIGINAL
)
3283 pDoc
->ShowCol( nCol
, nTab
, bShow
);
3290 if ( eMode
!= SC_SIZE_ORIGINAL
)
3293 bOutline
= bOutline
|| pDoc
->UpdateOutlineCol(
3294 static_cast<SCCOL
>(nStartNo
),
3295 static_cast<SCCOL
>(nEndNo
), nTab
, bShow
);
3297 bOutline
= bOutline
|| pDoc
->UpdateOutlineRow(
3298 static_cast<SCROW
>(nStartNo
),
3299 static_cast<SCROW
>(nEndNo
), nTab
, bShow
);
3302 pDoc
->DecSizeRecalcLevel( nTab
); // nicht fuer jede Spalte einzeln
3310 aMark
.SelectOneTable( nTab
);
3311 rDocShell
.GetUndoManager()->AddUndoAction(
3312 new ScUndoWidthOrHeight( &rDocShell
, aMark
,
3313 nStart
, nTab
, nEnd
, nTab
,
3314 pUndoDoc
, nRangeCnt
, pUndoRanges
,
3315 pUndoTab
, eMode
, nSizeTwips
, bWidth
) );
3318 pDoc
->UpdatePageBreaks( nTab
);
3320 rDocShell
.PostPaint(0,0,nTab
,MAXCOL
,MAXROW
,nTab
,PAINT_ALL
);
3326 BOOL
ScDocFunc::InsertPageBreak( BOOL bColumn
, const ScAddress
& rPos
,
3327 BOOL bRecord
, BOOL bSetModified
, BOOL
/* bApi */ )
3329 ScDocShellModificator
aModificator( rDocShell
);
3331 ScDocument
* pDoc
= rDocShell
.GetDocument();
3332 if (bRecord
&& !pDoc
->IsUndoEnabled())
3334 SCTAB nTab
= rPos
.Tab();
3335 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
3337 SCCOLROW nPos
= bColumn
? static_cast<SCCOLROW
>(rPos
.Col()) :
3338 static_cast<SCCOLROW
>(rPos
.Row());
3340 return FALSE
; // erste Spalte / Zeile
3342 ScBreakType nBreak
= bColumn
?
3343 pDoc
->HasColBreak(static_cast<SCCOL
>(nPos
), nTab
) :
3344 pDoc
->HasRowBreak(static_cast<SCROW
>(nPos
), nTab
);
3345 if (nBreak
& BREAK_MANUAL
)
3349 rDocShell
.GetUndoManager()->AddUndoAction(
3350 new ScUndoPageBreak( &rDocShell
, rPos
.Col(), rPos
.Row(), nTab
, bColumn
, TRUE
) );
3353 pDoc
->SetColBreak(static_cast<SCCOL
>(nPos
), nTab
, false, true);
3355 pDoc
->SetRowBreak(static_cast<SCROW
>(nPos
), nTab
, false, true);
3357 pDoc
->InvalidatePageBreaks(nTab
);
3358 pDoc
->UpdatePageBreaks( nTab
);
3362 rDocShell
.PostPaint( static_cast<SCCOL
>(nPos
)-1, 0, nTab
, MAXCOL
, MAXROW
, nTab
, PAINT_GRID
);
3365 pBindings
->Invalidate( FID_INS_COLBRK
);
3366 pBindings
->Invalidate( FID_DEL_COLBRK
);
3371 rDocShell
.PostPaint( 0, static_cast<SCROW
>(nPos
)-1, nTab
, MAXCOL
, MAXROW
, nTab
, PAINT_GRID
);
3374 pBindings
->Invalidate( FID_INS_ROWBRK
);
3375 pBindings
->Invalidate( FID_DEL_ROWBRK
);
3379 pBindings
->Invalidate( FID_DEL_MANUALBREAKS
);
3382 aModificator
.SetDocumentModified();
3387 BOOL
ScDocFunc::RemovePageBreak( BOOL bColumn
, const ScAddress
& rPos
,
3388 BOOL bRecord
, BOOL bSetModified
, BOOL
/* bApi */ )
3390 ScDocShellModificator
aModificator( rDocShell
);
3392 ScDocument
* pDoc
= rDocShell
.GetDocument();
3393 if (bRecord
&& !pDoc
->IsUndoEnabled())
3395 SCTAB nTab
= rPos
.Tab();
3396 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
3398 SCCOLROW nPos
= bColumn
? static_cast<SCCOLROW
>(rPos
.Col()) :
3399 static_cast<SCCOLROW
>(rPos
.Row());
3403 nBreak
= pDoc
->HasColBreak(static_cast<SCCOL
>(nPos
), nTab
);
3405 nBreak
= pDoc
->HasRowBreak(static_cast<SCROW
>(nPos
), nTab
);
3406 if ((nBreak
& BREAK_MANUAL
) == 0)
3407 // There is no manual break.
3411 rDocShell
.GetUndoManager()->AddUndoAction(
3412 new ScUndoPageBreak( &rDocShell
, rPos
.Col(), rPos
.Row(), nTab
, bColumn
, FALSE
) );
3415 pDoc
->RemoveColBreak(static_cast<SCCOL
>(nPos
), nTab
, false, true);
3417 pDoc
->RemoveRowBreak(static_cast<SCROW
>(nPos
), nTab
, false, true);
3419 pDoc
->UpdatePageBreaks( nTab
);
3423 rDocShell
.PostPaint( static_cast<SCCOL
>(nPos
)-1, 0, nTab
, MAXCOL
, MAXROW
, nTab
, PAINT_GRID
);
3426 pBindings
->Invalidate( FID_INS_COLBRK
);
3427 pBindings
->Invalidate( FID_DEL_COLBRK
);
3432 rDocShell
.PostPaint( 0, nPos
-1, nTab
, MAXCOL
, MAXROW
, nTab
, PAINT_GRID
);
3435 pBindings
->Invalidate( FID_INS_ROWBRK
);
3436 pBindings
->Invalidate( FID_DEL_ROWBRK
);
3440 pBindings
->Invalidate( FID_DEL_MANUALBREAKS
);
3443 aModificator
.SetDocumentModified();
3448 //------------------------------------------------------------------------
3450 void ScDocFunc::ProtectSheet( SCTAB nTab
, const ScTableProtection
& rProtect
)
3452 ScDocument
* pDoc
= rDocShell
.GetDocument();
3454 pDoc
->SetTabProtection(nTab
, &rProtect
);
3455 if (pDoc
->IsUndoEnabled())
3457 ScTableProtection
* pProtect
= pDoc
->GetTabProtection(nTab
);
3458 DBG_ASSERT(pProtect
, "ScDocFunc::Unprotect: ScTableProtection pointer is NULL!");
3461 ::std::auto_ptr
<ScTableProtection
> p(new ScTableProtection(*pProtect
));
3462 p
->setProtected(true); // just in case ...
3463 rDocShell
.GetUndoManager()->AddUndoAction(
3464 new ScUndoTabProtect(&rDocShell
, nTab
, p
) );
3466 // ownership of auto_ptr now transferred to ScUndoTabProtect.
3470 rDocShell
.PostPaintGridAll();
3471 ScDocShellModificator
aModificator(rDocShell
);
3472 aModificator
.SetDocumentModified();
3475 BOOL
ScDocFunc::Protect( SCTAB nTab
, const String
& rPassword
, BOOL
/*bApi*/ )
3477 ScDocument
* pDoc
= rDocShell
.GetDocument();
3478 if (nTab
== TABLEID_DOC
)
3480 // document protection
3481 ScDocProtection aProtection
;
3482 aProtection
.setProtected(true);
3483 aProtection
.setPassword(rPassword
);
3484 pDoc
->SetDocProtection(&aProtection
);
3485 if (pDoc
->IsUndoEnabled())
3487 ScDocProtection
* pProtect
= pDoc
->GetDocProtection();
3488 DBG_ASSERT(pProtect
, "ScDocFunc::Unprotect: ScDocProtection pointer is NULL!");
3491 ::std::auto_ptr
<ScDocProtection
> p(new ScDocProtection(*pProtect
));
3492 p
->setProtected(true); // just in case ...
3493 rDocShell
.GetUndoManager()->AddUndoAction(
3494 new ScUndoDocProtect(&rDocShell
, p
) );
3495 // ownership of auto_ptr is transferred to ScUndoDocProtect.
3503 ScTableProtection aProtection
;
3504 aProtection
.setProtected(true);
3505 aProtection
.setPassword(rPassword
);
3506 pDoc
->SetTabProtection(nTab
, &aProtection
);
3507 if (pDoc
->IsUndoEnabled())
3509 ScTableProtection
* pProtect
= pDoc
->GetTabProtection(nTab
);
3510 DBG_ASSERT(pProtect
, "ScDocFunc::Unprotect: ScTableProtection pointer is NULL!");
3513 ::std::auto_ptr
<ScTableProtection
> p(new ScTableProtection(*pProtect
));
3514 p
->setProtected(true); // just in case ...
3515 rDocShell
.GetUndoManager()->AddUndoAction(
3516 new ScUndoTabProtect(&rDocShell
, nTab
, p
) );
3517 // ownership of auto_ptr now transferred to ScUndoTabProtect.
3522 rDocShell
.PostPaintGridAll();
3523 ScDocShellModificator
aModificator( rDocShell
);
3524 aModificator
.SetDocumentModified();
3529 BOOL
ScDocFunc::Unprotect( SCTAB nTab
, const String
& rPassword
, BOOL bApi
)
3531 ScDocument
* pDoc
= rDocShell
.GetDocument();
3533 if (nTab
== TABLEID_DOC
)
3535 // document protection
3537 ScDocProtection
* pDocProtect
= pDoc
->GetDocProtection();
3538 if (!pDocProtect
|| !pDocProtect
->isProtected())
3539 // already unprotected (should not happen)!
3542 // save the protection state before unprotect (for undo).
3543 ::std::auto_ptr
<ScDocProtection
> pProtectCopy(new ScDocProtection(*pDocProtect
));
3545 if (!pDocProtect
->verifyPassword(rPassword
))
3549 InfoBox
aBox( rDocShell
.GetActiveDialogParent(), String( ScResId( SCSTR_WRONGPASSWORD
) ) );
3555 pDoc
->SetDocProtection(NULL
);
3556 if (pDoc
->IsUndoEnabled())
3558 pProtectCopy
->setProtected(false);
3559 rDocShell
.GetUndoManager()->AddUndoAction(
3560 new ScUndoDocProtect(&rDocShell
, pProtectCopy
) );
3561 // ownership of auto_ptr now transferred to ScUndoDocProtect.
3568 ScTableProtection
* pTabProtect
= pDoc
->GetTabProtection(nTab
);
3569 if (!pTabProtect
|| !pTabProtect
->isProtected())
3570 // already unprotected (should not happen)!
3573 // save the protection state before unprotect (for undo).
3574 ::std::auto_ptr
<ScTableProtection
> pProtectCopy(new ScTableProtection(*pTabProtect
));
3575 if (!pTabProtect
->verifyPassword(rPassword
))
3579 InfoBox
aBox( rDocShell
.GetActiveDialogParent(), String( ScResId( SCSTR_WRONGPASSWORD
) ) );
3585 pDoc
->SetTabProtection(nTab
, NULL
);
3586 if (pDoc
->IsUndoEnabled())
3588 pProtectCopy
->setProtected(false);
3589 rDocShell
.GetUndoManager()->AddUndoAction(
3590 new ScUndoTabProtect(&rDocShell
, nTab
, pProtectCopy
) );
3591 // ownership of auto_ptr now transferred to ScUndoTabProtect.
3595 rDocShell
.PostPaintGridAll();
3596 ScDocShellModificator
aModificator( rDocShell
);
3597 aModificator
.SetDocumentModified();
3602 //------------------------------------------------------------------------
3604 BOOL
ScDocFunc::ClearItems( const ScMarkData
& rMark
, const USHORT
* pWhich
, BOOL bApi
)
3606 ScDocShellModificator
aModificator( rDocShell
);
3608 ScDocument
* pDoc
= rDocShell
.GetDocument();
3609 BOOL
bUndo (pDoc
->IsUndoEnabled());
3610 ScEditableTester
aTester( pDoc
, rMark
);
3611 if (!aTester
.IsEditable())
3614 rDocShell
.ErrorMessage(aTester
.GetMessageId());
3618 // #i12940# ClearItems is called (from setPropertyToDefault) directly with uno object's cached
3619 // MarkData (GetMarkData), so rMark must be changed to multi selection for ClearSelectionItems
3623 ScMarkData aMultiMark
= rMark
;
3624 aMultiMark
.SetMarking(FALSE
); // for MarkToMulti
3625 aMultiMark
.MarkToMulti();
3626 aMultiMark
.GetMultiMarkArea( aMarkRange
);
3631 SCTAB nStartTab
= aMarkRange
.aStart
.Tab();
3632 SCTAB nEndTab
= aMarkRange
.aEnd
.Tab();
3634 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
3635 pUndoDoc
->InitUndo( pDoc
, nStartTab
, nEndTab
);
3636 pDoc
->CopyToDocument( aMarkRange
, IDF_ATTRIB
, TRUE
, pUndoDoc
, (ScMarkData
*)&aMultiMark
);
3638 rDocShell
.GetUndoManager()->AddUndoAction(
3639 new ScUndoClearItems( &rDocShell
, aMultiMark
, pUndoDoc
, pWhich
) );
3642 pDoc
->ClearSelectionItems( pWhich
, aMultiMark
);
3644 rDocShell
.PostPaint( aMarkRange
, PAINT_GRID
, SC_PF_LINES
| SC_PF_TESTMERGE
);
3645 aModificator
.SetDocumentModified();
3647 //! Bindings-Invalidate etc.?
3652 BOOL
ScDocFunc::ChangeIndent( const ScMarkData
& rMark
, BOOL bIncrement
, BOOL bApi
)
3654 ScDocShellModificator
aModificator( rDocShell
);
3656 ScDocument
* pDoc
= rDocShell
.GetDocument();
3657 BOOL
bUndo(pDoc
->IsUndoEnabled());
3658 ScEditableTester
aTester( pDoc
, rMark
);
3659 if (!aTester
.IsEditable())
3662 rDocShell
.ErrorMessage(aTester
.GetMessageId());
3667 rMark
.GetMultiMarkArea( aMarkRange
);
3672 SCTAB nStartTab
= aMarkRange
.aStart
.Tab();
3673 SCTAB nTabCount
= pDoc
->GetTableCount();
3675 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
3676 pUndoDoc
->InitUndo( pDoc
, nStartTab
, nStartTab
);
3677 for (SCTAB i
=0; i
<nTabCount
; i
++)
3678 if (i
!= nStartTab
&& rMark
.GetTableSelect(i
))
3679 pUndoDoc
->AddUndoTab( i
, i
);
3681 ScRange aCopyRange
= aMarkRange
;
3682 aCopyRange
.aStart
.SetTab(0);
3683 aCopyRange
.aEnd
.SetTab(nTabCount
-1);
3684 pDoc
->CopyToDocument( aCopyRange
, IDF_ATTRIB
, TRUE
, pUndoDoc
, (ScMarkData
*)&rMark
);
3686 rDocShell
.GetUndoManager()->AddUndoAction(
3687 new ScUndoIndent( &rDocShell
, rMark
, pUndoDoc
, bIncrement
) );
3690 pDoc
->ChangeSelectionIndent( bIncrement
, rMark
);
3692 rDocShell
.PostPaint( aMarkRange
, PAINT_GRID
, SC_PF_LINES
| SC_PF_TESTMERGE
);
3693 aModificator
.SetDocumentModified();
3695 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
3698 pBindings
->Invalidate( SID_ALIGNLEFT
); // ChangeIndent setzt auf links
3699 pBindings
->Invalidate( SID_ALIGNRIGHT
);
3700 pBindings
->Invalidate( SID_ALIGNBLOCK
);
3701 pBindings
->Invalidate( SID_ALIGNCENTERHOR
);
3702 // pseudo slots for Format menu
3703 pBindings
->Invalidate( SID_ALIGN_ANY_HDEFAULT
);
3704 pBindings
->Invalidate( SID_ALIGN_ANY_LEFT
);
3705 pBindings
->Invalidate( SID_ALIGN_ANY_HCENTER
);
3706 pBindings
->Invalidate( SID_ALIGN_ANY_RIGHT
);
3707 pBindings
->Invalidate( SID_ALIGN_ANY_JUSTIFIED
);
3713 BOOL
ScDocFunc::AutoFormat( const ScRange
& rRange
, const ScMarkData
* pTabMark
,
3714 USHORT nFormatNo
, BOOL bRecord
, BOOL bApi
)
3716 ScDocShellModificator
aModificator( rDocShell
);
3718 BOOL bSuccess
= FALSE
;
3719 ScDocument
* pDoc
= rDocShell
.GetDocument();
3720 SCCOL nStartCol
= rRange
.aStart
.Col();
3721 SCROW nStartRow
= rRange
.aStart
.Row();
3722 SCTAB nStartTab
= rRange
.aStart
.Tab();
3723 SCCOL nEndCol
= rRange
.aEnd
.Col();
3724 SCROW nEndRow
= rRange
.aEnd
.Row();
3725 SCTAB nEndTab
= rRange
.aEnd
.Tab();
3727 if (bRecord
&& !pDoc
->IsUndoEnabled())
3734 for (SCTAB nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
3735 aMark
.SelectTable( nTab
, TRUE
);
3738 ScAutoFormat
* pAutoFormat
= ScGlobal::GetAutoFormat();
3739 ScEditableTester
aTester( pDoc
, nStartCol
,nStartRow
, nEndCol
,nEndRow
, aMark
);
3740 if ( pAutoFormat
&& nFormatNo
< pAutoFormat
->GetCount() && aTester
.IsEditable() )
3742 WaitObject
aWait( rDocShell
.GetActiveDialogParent() );
3744 BOOL bSize
= (*pAutoFormat
)[nFormatNo
]->GetIncludeWidthHeight();
3746 SCTAB nTabCount
= pDoc
->GetTableCount();
3747 ScDocument
* pUndoDoc
= NULL
;
3750 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
3751 pUndoDoc
->InitUndo( pDoc
, nStartTab
, nStartTab
, bSize
, bSize
);
3752 for (SCTAB i
=0; i
<nTabCount
; i
++)
3753 if (i
!= nStartTab
&& aMark
.GetTableSelect(i
))
3754 pUndoDoc
->AddUndoTab( i
, i
, bSize
, bSize
);
3756 ScRange aCopyRange
= rRange
;
3757 aCopyRange
.aStart
.SetTab(0);
3758 aCopyRange
.aStart
.SetTab(nTabCount
-1);
3759 pDoc
->CopyToDocument( aCopyRange
, IDF_ATTRIB
, FALSE
, pUndoDoc
, &aMark
);
3762 pDoc
->CopyToDocument( nStartCol
,0,0, nEndCol
,MAXROW
,nTabCount
-1,
3763 IDF_NONE
, FALSE
, pUndoDoc
, &aMark
);
3764 pDoc
->CopyToDocument( 0,nStartRow
,0, MAXCOL
,nEndRow
,nTabCount
-1,
3765 IDF_NONE
, FALSE
, pUndoDoc
, &aMark
);
3767 pDoc
->BeginDrawUndo();
3770 pDoc
->AutoFormat( nStartCol
, nStartRow
, nEndCol
, nEndRow
, nFormatNo
, aMark
);
3775 nCols[0] = nStartCol;
3778 nRows[0] = nStartRow;
3781 SCCOLROW nCols
[2] = { nStartCol
, nEndCol
};
3782 SCCOLROW nRows
[2] = { nStartRow
, nEndRow
};
3784 for (SCTAB nTab
=0; nTab
<nTabCount
; nTab
++)
3785 if (aMark
.GetTableSelect(nTab
))
3787 SetWidthOrHeight( TRUE
, 1,nCols
, nTab
, SC_SIZE_VISOPT
, STD_EXTRA_WIDTH
, FALSE
, TRUE
);
3788 SetWidthOrHeight( FALSE
,1,nRows
, nTab
, SC_SIZE_VISOPT
, 0, FALSE
, FALSE
);
3789 rDocShell
.PostPaint( 0,0,nTab
, MAXCOL
,MAXROW
,nTab
,
3790 PAINT_GRID
| PAINT_LEFT
| PAINT_TOP
);
3795 for (SCTAB nTab
=0; nTab
<nTabCount
; nTab
++)
3796 if (aMark
.GetTableSelect(nTab
))
3798 BOOL bAdj
= AdjustRowHeight( ScRange(nStartCol
, nStartRow
, nTab
,
3799 nEndCol
, nEndRow
, nTab
), FALSE
);
3801 rDocShell
.PostPaint( 0,nStartRow
,nTab
, MAXCOL
,MAXROW
,nTab
,
3802 PAINT_GRID
| PAINT_LEFT
);
3804 rDocShell
.PostPaint( nStartCol
, nStartRow
, nTab
,
3805 nEndCol
, nEndRow
, nTab
, PAINT_GRID
);
3809 if ( bRecord
) // Draw-Undo erst jetzt verfuegbar
3811 rDocShell
.GetUndoManager()->AddUndoAction(
3812 new ScUndoAutoFormat( &rDocShell
, rRange
, pUndoDoc
, aMark
, bSize
, nFormatNo
) );
3815 aModificator
.SetDocumentModified();
3818 rDocShell
.ErrorMessage(aTester
.GetMessageId());
3823 //------------------------------------------------------------------------
3825 BOOL
ScDocFunc::EnterMatrix( const ScRange
& rRange
, const ScMarkData
* pTabMark
,
3826 const ScTokenArray
* pTokenArray
, const String
& rString
, BOOL bApi
, BOOL bEnglish
,
3827 const String
& rFormulaNmsp
, const formula::FormulaGrammar::Grammar eGrammar
)
3829 ScDocShellModificator
aModificator( rDocShell
);
3831 BOOL bSuccess
= FALSE
;
3832 ScDocument
* pDoc
= rDocShell
.GetDocument();
3833 SCCOL nStartCol
= rRange
.aStart
.Col();
3834 SCROW nStartRow
= rRange
.aStart
.Row();
3835 SCTAB nStartTab
= rRange
.aStart
.Tab();
3836 SCCOL nEndCol
= rRange
.aEnd
.Col();
3837 SCROW nEndRow
= rRange
.aEnd
.Row();
3838 SCTAB nEndTab
= rRange
.aEnd
.Tab();
3840 BOOL
bUndo(pDoc
->IsUndoEnabled());
3847 for (SCTAB nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
3848 aMark
.SelectTable( nTab
, TRUE
);
3851 ScEditableTester
aTester( pDoc
, nStartCol
,nStartRow
, nEndCol
,nEndRow
, aMark
);
3852 if ( aTester
.IsEditable() )
3854 WaitObject
aWait( rDocShell
.GetActiveDialogParent() );
3856 ScDocument
* pUndoDoc
= NULL
;
3857 // if (bRecord) // immer
3860 //! auch bei Undo selektierte Tabellen beruecksichtigen
3861 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
3862 pUndoDoc
->InitUndo( pDoc
, nStartTab
, nEndTab
);
3863 pDoc
->CopyToDocument( rRange
, IDF_ALL
& ~IDF_NOTE
, FALSE
, pUndoDoc
);
3866 // use TokenArray if given, string (and flags) otherwise
3869 pDoc
->InsertMatrixFormula( nStartCol
, nStartRow
, nEndCol
, nEndRow
,
3870 aMark
, EMPTY_STRING
, pTokenArray
, eGrammar
);
3872 else if ( pDoc
->IsImportingXML() )
3874 ScTokenArray
* pCode
= lcl_ScDocFunc_CreateTokenArrayXML( rString
, rFormulaNmsp
, eGrammar
);
3875 pDoc
->InsertMatrixFormula( nStartCol
, nStartRow
, nEndCol
, nEndRow
,
3876 aMark
, EMPTY_STRING
, pCode
, eGrammar
);
3878 pDoc
->IncXMLImportedFormulaCount( rString
.Len() );
3882 ScCompiler
aComp( pDoc
, rRange
.aStart
);
3883 aComp
.SetGrammar(eGrammar
);
3884 ScTokenArray
* pCode
= aComp
.CompileString( rString
);
3885 pDoc
->InsertMatrixFormula( nStartCol
, nStartRow
, nEndCol
, nEndRow
,
3886 aMark
, EMPTY_STRING
, pCode
, eGrammar
);
3890 pDoc
->InsertMatrixFormula( nStartCol
, nStartRow
, nEndCol
, nEndRow
,
3891 aMark
, rString
, NULL
, eGrammar
);
3893 // if (bRecord) // immer
3896 //! auch bei Undo selektierte Tabellen beruecksichtigen
3897 rDocShell
.GetUndoManager()->AddUndoAction(
3898 new ScUndoEnterMatrix( &rDocShell
, rRange
, pUndoDoc
, rString
) );
3901 // Err522 beim Paint von DDE-Formeln werden jetzt beim Interpretieren abgefangen
3902 rDocShell
.PostPaint( nStartCol
,nStartRow
,nStartTab
,nEndCol
,nEndRow
,nEndTab
, PAINT_GRID
);
3903 aModificator
.SetDocumentModified();
3908 rDocShell
.ErrorMessage(aTester
.GetMessageId());
3913 //------------------------------------------------------------------------
3915 BOOL
ScDocFunc::TabOp( const ScRange
& rRange
, const ScMarkData
* pTabMark
,
3916 const ScTabOpParam
& rParam
, BOOL bRecord
, BOOL bApi
)
3918 ScDocShellModificator
aModificator( rDocShell
);
3920 BOOL bSuccess
= FALSE
;
3921 ScDocument
* pDoc
= rDocShell
.GetDocument();
3922 SCCOL nStartCol
= rRange
.aStart
.Col();
3923 SCROW nStartRow
= rRange
.aStart
.Row();
3924 SCTAB nStartTab
= rRange
.aStart
.Tab();
3925 SCCOL nEndCol
= rRange
.aEnd
.Col();
3926 SCROW nEndRow
= rRange
.aEnd
.Row();
3927 SCTAB nEndTab
= rRange
.aEnd
.Tab();
3929 if (bRecord
&& !pDoc
->IsUndoEnabled())
3937 for (SCTAB nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
3938 aMark
.SelectTable( nTab
, TRUE
);
3941 ScEditableTester
aTester( pDoc
, nStartCol
,nStartRow
, nEndCol
,nEndRow
, aMark
);
3942 if ( aTester
.IsEditable() )
3944 WaitObject
aWait( rDocShell
.GetActiveDialogParent() );
3945 pDoc
->SetDirty( rRange
);
3948 //! auch bei Undo selektierte Tabellen beruecksichtigen
3949 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
3950 pUndoDoc
->InitUndo( pDoc
, nStartTab
, nEndTab
);
3951 pDoc
->CopyToDocument( rRange
, IDF_ALL
& ~IDF_NOTE
, FALSE
, pUndoDoc
);
3953 rDocShell
.GetUndoManager()->AddUndoAction(
3954 new ScUndoTabOp( &rDocShell
,
3955 nStartCol
, nStartRow
, nStartTab
,
3956 nEndCol
, nEndRow
, nEndTab
, pUndoDoc
,
3957 rParam
.aRefFormulaCell
,
3958 rParam
.aRefFormulaEnd
,
3963 pDoc
->InsertTableOp(rParam
, nStartCol
, nStartRow
, nEndCol
, nEndRow
, aMark
);
3964 rDocShell
.PostPaintGridAll();
3965 aModificator
.SetDocumentModified();
3969 rDocShell
.ErrorMessage(aTester
.GetMessageId());
3974 //------------------------------------------------------------------------
3976 inline ScDirection
DirFromFillDir( FillDir eDir
)
3978 if (eDir
==FILL_TO_BOTTOM
)
3980 else if (eDir
==FILL_TO_RIGHT
)
3982 else if (eDir
==FILL_TO_TOP
)
3984 else // if (eDir==FILL_TO_LEFT)
3988 BOOL
ScDocFunc::FillSimple( const ScRange
& rRange
, const ScMarkData
* pTabMark
,
3989 FillDir eDir
, BOOL bRecord
, BOOL bApi
)
3991 ScDocShellModificator
aModificator( rDocShell
);
3993 BOOL bSuccess
= FALSE
;
3994 ScDocument
* pDoc
= rDocShell
.GetDocument();
3995 SCCOL nStartCol
= rRange
.aStart
.Col();
3996 SCROW nStartRow
= rRange
.aStart
.Row();
3997 SCTAB nStartTab
= rRange
.aStart
.Tab();
3998 SCCOL nEndCol
= rRange
.aEnd
.Col();
3999 SCROW nEndRow
= rRange
.aEnd
.Row();
4000 SCTAB nEndTab
= rRange
.aEnd
.Tab();
4002 if (bRecord
&& !pDoc
->IsUndoEnabled())
4010 for (SCTAB nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
4011 aMark
.SelectTable( nTab
, TRUE
);
4014 ScEditableTester
aTester( pDoc
, nStartCol
,nStartRow
, nEndCol
,nEndRow
, aMark
);
4015 if ( aTester
.IsEditable() )
4017 WaitObject
aWait( rDocShell
.GetActiveDialogParent() );
4019 ScRange aSourceArea
= rRange
;
4020 ScRange aDestArea
= rRange
;
4022 SCCOLROW nCount
= 0;
4025 case FILL_TO_BOTTOM
:
4026 nCount
= aSourceArea
.aEnd
.Row()-aSourceArea
.aStart
.Row();
4027 aSourceArea
.aEnd
.SetRow( aSourceArea
.aStart
.Row() );
4030 nCount
= aSourceArea
.aEnd
.Col()-aSourceArea
.aStart
.Col();
4031 aSourceArea
.aEnd
.SetCol( aSourceArea
.aStart
.Col() );
4034 nCount
= aSourceArea
.aEnd
.Row()-aSourceArea
.aStart
.Row();
4035 aSourceArea
.aStart
.SetRow( aSourceArea
.aEnd
.Row() );
4038 nCount
= aSourceArea
.aEnd
.Col()-aSourceArea
.aStart
.Col();
4039 aSourceArea
.aStart
.SetCol( aSourceArea
.aEnd
.Col() );
4043 ScDocument
* pUndoDoc
= NULL
;
4046 SCTAB nTabCount
= pDoc
->GetTableCount();
4047 SCTAB nDestStartTab
= aDestArea
.aStart
.Tab();
4049 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
4050 pUndoDoc
->InitUndo( pDoc
, nDestStartTab
, nDestStartTab
);
4051 for (SCTAB i
=0; i
<nTabCount
; i
++)
4052 if (i
!= nDestStartTab
&& aMark
.GetTableSelect(i
))
4053 pUndoDoc
->AddUndoTab( i
, i
);
4055 ScRange aCopyRange
= aDestArea
;
4056 aCopyRange
.aStart
.SetTab(0);
4057 aCopyRange
.aEnd
.SetTab(nTabCount
-1);
4058 pDoc
->CopyToDocument( aCopyRange
, IDF_AUTOFILL
, FALSE
, pUndoDoc
, &aMark
);
4061 pDoc
->Fill( aSourceArea
.aStart
.Col(), aSourceArea
.aStart
.Row(),
4062 aSourceArea
.aEnd
.Col(), aSourceArea
.aEnd
.Row(), aMark
,
4063 nCount
, eDir
, FILL_SIMPLE
);
4064 AdjustRowHeight(rRange
);
4066 if ( bRecord
) // Draw-Undo erst jetzt verfuegbar
4068 rDocShell
.GetUndoManager()->AddUndoAction(
4069 new ScUndoAutoFill( &rDocShell
, aDestArea
, aSourceArea
, pUndoDoc
, aMark
,
4070 eDir
, FILL_SIMPLE
, FILL_DAY
, MAXDOUBLE
, 1.0, 1e307
,
4071 pDoc
->GetRangeName()->GetSharedMaxIndex()+1 ) );
4074 rDocShell
.PostPaintGridAll();
4075 // rDocShell.PostPaintDataChanged();
4076 aModificator
.SetDocumentModified();
4081 rDocShell
.ErrorMessage(aTester
.GetMessageId());
4086 BOOL
ScDocFunc::FillSeries( const ScRange
& rRange
, const ScMarkData
* pTabMark
,
4087 FillDir eDir
, FillCmd eCmd
, FillDateCmd eDateCmd
,
4088 double fStart
, double fStep
, double fMax
,
4089 BOOL bRecord
, BOOL bApi
)
4091 ScDocShellModificator
aModificator( rDocShell
);
4093 BOOL bSuccess
= FALSE
;
4094 ScDocument
* pDoc
= rDocShell
.GetDocument();
4095 SCCOL nStartCol
= rRange
.aStart
.Col();
4096 SCROW nStartRow
= rRange
.aStart
.Row();
4097 SCTAB nStartTab
= rRange
.aStart
.Tab();
4098 SCCOL nEndCol
= rRange
.aEnd
.Col();
4099 SCROW nEndRow
= rRange
.aEnd
.Row();
4100 SCTAB nEndTab
= rRange
.aEnd
.Tab();
4102 if (bRecord
&& !pDoc
->IsUndoEnabled())
4110 for (SCTAB nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
4111 aMark
.SelectTable( nTab
, TRUE
);
4114 ScEditableTester
aTester( pDoc
, nStartCol
,nStartRow
, nEndCol
,nEndRow
, aMark
);
4115 if ( aTester
.IsEditable() )
4117 WaitObject
aWait( rDocShell
.GetActiveDialogParent() );
4119 ScRange aSourceArea
= rRange
;
4120 ScRange aDestArea
= rRange
;
4122 SCSIZE nCount
= pDoc
->GetEmptyLinesInBlock(
4123 aSourceArea
.aStart
.Col(), aSourceArea
.aStart
.Row(), aSourceArea
.aStart
.Tab(),
4124 aSourceArea
.aEnd
.Col(), aSourceArea
.aEnd
.Row(), aSourceArea
.aEnd
.Tab(),
4125 DirFromFillDir(eDir
) );
4127 // #27665# mindestens eine Zeile/Spalte als Quellbereich behalten:
4128 SCSIZE nTotLines
= ( eDir
== FILL_TO_BOTTOM
|| eDir
== FILL_TO_TOP
) ?
4129 static_cast<SCSIZE
>( aSourceArea
.aEnd
.Row() - aSourceArea
.aStart
.Row() + 1 ) :
4130 static_cast<SCSIZE
>( aSourceArea
.aEnd
.Col() - aSourceArea
.aStart
.Col() + 1 );
4131 if ( nCount
>= nTotLines
)
4132 nCount
= nTotLines
- 1;
4136 case FILL_TO_BOTTOM
:
4137 aSourceArea
.aEnd
.SetRow( sal::static_int_cast
<SCROW
>( aSourceArea
.aEnd
.Row() - nCount
) );
4140 aSourceArea
.aEnd
.SetCol( sal::static_int_cast
<SCCOL
>( aSourceArea
.aEnd
.Col() - nCount
) );
4143 aSourceArea
.aStart
.SetRow( sal::static_int_cast
<SCROW
>( aSourceArea
.aStart
.Row() + nCount
) );
4146 aSourceArea
.aStart
.SetCol( sal::static_int_cast
<SCCOL
>( aSourceArea
.aStart
.Col() + nCount
) );
4150 ScDocument
* pUndoDoc
= NULL
;
4153 SCTAB nTabCount
= pDoc
->GetTableCount();
4154 SCTAB nDestStartTab
= aDestArea
.aStart
.Tab();
4156 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
4157 pUndoDoc
->InitUndo( pDoc
, nDestStartTab
, nDestStartTab
);
4158 for (SCTAB i
=0; i
<nTabCount
; i
++)
4159 if (i
!= nDestStartTab
&& aMark
.GetTableSelect(i
))
4160 pUndoDoc
->AddUndoTab( i
, i
);
4162 pDoc
->CopyToDocument(
4163 aDestArea
.aStart
.Col(), aDestArea
.aStart
.Row(), 0,
4164 aDestArea
.aEnd
.Col(), aDestArea
.aEnd
.Row(), nTabCount
-1,
4165 IDF_AUTOFILL
, FALSE
, pUndoDoc
, &aMark
);
4168 if (aDestArea
.aStart
.Col() <= aDestArea
.aEnd
.Col() &&
4169 aDestArea
.aStart
.Row() <= aDestArea
.aEnd
.Row())
4171 if ( fStart
!= MAXDOUBLE
)
4173 SCCOL nValX
= (eDir
== FILL_TO_LEFT
) ? aDestArea
.aEnd
.Col() : aDestArea
.aStart
.Col();
4174 SCROW nValY
= (eDir
== FILL_TO_TOP
) ? aDestArea
.aEnd
.Row() : aDestArea
.aStart
.Row();
4175 SCTAB nTab
= aDestArea
.aStart
.Tab();
4176 pDoc
->SetValue( nValX
, nValY
, nTab
, fStart
);
4178 pDoc
->Fill( aSourceArea
.aStart
.Col(), aSourceArea
.aStart
.Row(),
4179 aSourceArea
.aEnd
.Col(), aSourceArea
.aEnd
.Row(), aMark
,
4180 nCount
, eDir
, eCmd
, eDateCmd
, fStep
, fMax
);
4181 AdjustRowHeight(rRange
);
4183 rDocShell
.PostPaintGridAll();
4184 // rDocShell.PostPaintDataChanged();
4185 aModificator
.SetDocumentModified();
4188 if ( bRecord
) // Draw-Undo erst jetzt verfuegbar
4190 rDocShell
.GetUndoManager()->AddUndoAction(
4191 new ScUndoAutoFill( &rDocShell
, aDestArea
, aSourceArea
, pUndoDoc
, aMark
,
4192 eDir
, eCmd
, eDateCmd
, fStart
, fStep
, fMax
,
4193 pDoc
->GetRangeName()->GetSharedMaxIndex()+1 ) );
4199 rDocShell
.ErrorMessage(aTester
.GetMessageId());
4204 BOOL
ScDocFunc::FillAuto( ScRange
& rRange
, const ScMarkData
* pTabMark
,
4205 FillDir eDir
, ULONG nCount
, BOOL bRecord
, BOOL bApi
)
4208 double fMax
= MAXDOUBLE
;
4209 return FillAuto( rRange
, pTabMark
, eDir
, FILL_AUTO
, FILL_DAY
, nCount
, fStep
, fMax
, bRecord
, bApi
);
4212 BOOL
ScDocFunc::FillAuto( ScRange
& rRange
, const ScMarkData
* pTabMark
, FillDir eDir
, FillCmd eCmd
, FillDateCmd eDateCmd
, ULONG nCount
, double fStep
, double fMax
, BOOL bRecord
, BOOL bApi
)
4214 ScDocShellModificator
aModificator( rDocShell
);
4216 ScDocument
* pDoc
= rDocShell
.GetDocument();
4217 SCCOL nStartCol
= rRange
.aStart
.Col();
4218 SCROW nStartRow
= rRange
.aStart
.Row();
4219 SCTAB nStartTab
= rRange
.aStart
.Tab();
4220 SCCOL nEndCol
= rRange
.aEnd
.Col();
4221 SCROW nEndRow
= rRange
.aEnd
.Row();
4222 SCTAB nEndTab
= rRange
.aEnd
.Tab();
4224 if (bRecord
&& !pDoc
->IsUndoEnabled())
4232 for (SCTAB nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
4233 aMark
.SelectTable( nTab
, TRUE
);
4236 ScRange aSourceArea
= rRange
;
4237 ScRange aDestArea
= rRange
;
4242 case FILL_TO_BOTTOM
:
4243 aDestArea
.aEnd
.SetRow( sal::static_int_cast
<SCROW
>( aSourceArea
.aEnd
.Row() + nCount
) );
4246 if (nCount
> sal::static_int_cast
<ULONG
>( aSourceArea
.aStart
.Row() ))
4248 DBG_ERROR("FillAuto: Row < 0");
4249 nCount
= aSourceArea
.aStart
.Row();
4251 aDestArea
.aStart
.SetRow( sal::static_int_cast
<SCROW
>( aSourceArea
.aStart
.Row() - nCount
) );
4254 aDestArea
.aEnd
.SetCol( sal::static_int_cast
<SCCOL
>( aSourceArea
.aEnd
.Col() + nCount
) );
4257 if (nCount
> sal::static_int_cast
<ULONG
>( aSourceArea
.aStart
.Col() ))
4259 DBG_ERROR("FillAuto: Col < 0");
4260 nCount
= aSourceArea
.aStart
.Col();
4262 aDestArea
.aStart
.SetCol( sal::static_int_cast
<SCCOL
>( aSourceArea
.aStart
.Col() - nCount
) );
4265 DBG_ERROR("Falsche Richtung bei FillAuto");
4269 // Zellschutz testen
4270 //! Quellbereich darf geschuetzt sein !!!
4271 //! aber kein Matrixfragment enthalten !!!
4273 ScEditableTester
aTester( pDoc
, aDestArea
);
4274 if ( !aTester
.IsEditable() )
4277 rDocShell
.ErrorMessage(aTester
.GetMessageId());
4281 if ( pDoc
->HasSelectedBlockMatrixFragment( nStartCol
, nStartRow
,
4282 nEndCol
, nEndRow
, aMark
) )
4285 rDocShell
.ErrorMessage(STR_MATRIXFRAGMENTERR
);
4289 WaitObject
aWait( rDocShell
.GetActiveDialogParent() );
4291 ScDocument
* pUndoDoc
= NULL
;
4294 SCTAB nTabCount
= pDoc
->GetTableCount();
4295 SCTAB nDestStartTab
= aDestArea
.aStart
.Tab();
4297 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
4298 pUndoDoc
->InitUndo( pDoc
, nDestStartTab
, nDestStartTab
);
4299 for (SCTAB i
=0; i
<nTabCount
; i
++)
4300 if (i
!= nDestStartTab
&& aMark
.GetTableSelect(i
))
4301 pUndoDoc
->AddUndoTab( i
, i
);
4303 // do not clone note captions in undo document
4304 pDoc
->CopyToDocument(
4305 aDestArea
.aStart
.Col(), aDestArea
.aStart
.Row(), 0,
4306 aDestArea
.aEnd
.Col(), aDestArea
.aEnd
.Row(), nTabCount
-1,
4307 IDF_AUTOFILL
, FALSE
, pUndoDoc
, &aMark
);
4310 pDoc
->Fill( aSourceArea
.aStart
.Col(), aSourceArea
.aStart
.Row(),
4311 aSourceArea
.aEnd
.Col(), aSourceArea
.aEnd
.Row(), aMark
,
4312 nCount
, eDir
, eCmd
, eDateCmd
, fStep
, fMax
);
4314 AdjustRowHeight(aDestArea
);
4316 if ( bRecord
) // Draw-Undo erst jetzt verfuegbar
4318 rDocShell
.GetUndoManager()->AddUndoAction(
4319 new ScUndoAutoFill( &rDocShell
, aDestArea
, aSourceArea
, pUndoDoc
, aMark
,
4320 eDir
, eCmd
, eDateCmd
, MAXDOUBLE
, fStep
, fMax
,
4321 pDoc
->GetRangeName()->GetSharedMaxIndex()+1 ) );
4324 rDocShell
.PostPaintGridAll();
4325 // rDocShell.PostPaintDataChanged();
4326 aModificator
.SetDocumentModified();
4328 rRange
= aDestArea
; // Zielbereich zurueckgeben (zum Markieren)
4332 //------------------------------------------------------------------------
4334 BOOL
ScDocFunc::MergeCells( const ScCellMergeOption
& rOption
, BOOL bContents
, BOOL bRecord
, BOOL bApi
)
4338 ScDocShellModificator
aModificator( rDocShell
);
4340 SCCOL nStartCol
= rOption
.mnStartCol
;
4341 SCROW nStartRow
= rOption
.mnStartRow
;
4342 SCCOL nEndCol
= rOption
.mnEndCol
;
4343 SCROW nEndRow
= rOption
.mnEndRow
;
4344 if ((nStartCol
== nEndCol
&& nStartRow
== nEndRow
) || rOption
.maTabs
.empty())
4346 // Nothing to do. Bail out quick.
4350 ScDocument
* pDoc
= rDocShell
.GetDocument();
4351 set
<SCTAB
>::const_iterator itrBeg
= rOption
.maTabs
.begin(), itrEnd
= rOption
.maTabs
.end();
4352 SCTAB nTab1
= *itrBeg
, nTab2
= *rOption
.maTabs
.rbegin();
4354 if (bRecord
&& !pDoc
->IsUndoEnabled())
4357 for (set
<SCTAB
>::const_iterator itr
= itrBeg
; itr
!= itrEnd
; ++itr
)
4359 ScEditableTester
aTester( pDoc
, *itr
, nStartCol
, nStartRow
, nEndCol
, nEndRow
);
4360 if (!aTester
.IsEditable())
4363 rDocShell
.ErrorMessage(aTester
.GetMessageId());
4367 if ( pDoc
->HasAttrib( nStartCol
, nStartRow
, *itr
, nEndCol
, nEndRow
, *itr
,
4368 HASATTR_MERGED
| HASATTR_OVERLAPPED
) )
4370 // "Zusammenfassen nicht verschachteln !"
4372 rDocShell
.ErrorMessage(STR_MSSG_MERGECELLS_0
);
4377 ScDocument
* pUndoDoc
= NULL
;
4378 bool bNeedContentsUndo
= false;
4379 for (set
<SCTAB
>::const_iterator itr
= itrBeg
; itr
!= itrEnd
; ++itr
)
4382 bool bNeedContents
= bContents
&&
4383 ( !pDoc
->IsBlockEmpty( nTab
, nStartCol
,nStartRow
+1, nStartCol
,nEndRow
, true ) ||
4384 !pDoc
->IsBlockEmpty( nTab
, nStartCol
+1,nStartRow
, nEndCol
,nEndRow
, true ) );
4388 // test if the range contains other notes which also implies that we need an undo document
4389 bool bHasNotes
= false;
4390 for( ScAddress
aPos( nStartCol
, nStartRow
, nTab
); !bHasNotes
&& (aPos
.Col() <= nEndCol
); aPos
.IncCol() )
4391 for( aPos
.SetRow( nStartRow
); !bHasNotes
&& (aPos
.Row() <= nEndRow
); aPos
.IncRow() )
4392 bHasNotes
= ((aPos
.Col() != nStartCol
) || (aPos
.Row() != nStartRow
)) && (pDoc
->GetNote( aPos
) != 0);
4394 if (bNeedContents
|| bHasNotes
|| rOption
.mbCenter
)
4398 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
4399 pUndoDoc
->InitUndo(pDoc
, nTab1
, nTab2
);
4401 // note captions are collected by drawing undo
4402 pDoc
->CopyToDocument( nStartCol
, nStartRow
, nTab
, nEndCol
, nEndRow
, nTab
,
4403 IDF_ALL
|IDF_NOCAPTIONS
, FALSE
, pUndoDoc
);
4406 pDoc
->BeginDrawUndo();
4410 pDoc
->DoMergeContents( nTab
, nStartCol
,nStartRow
, nEndCol
,nEndRow
);
4411 pDoc
->DoMerge( nTab
, nStartCol
,nStartRow
, nEndCol
,nEndRow
);
4413 if (rOption
.mbCenter
)
4415 pDoc
->ApplyAttr( nStartCol
, nStartRow
, nTab
, SvxHorJustifyItem( SVX_HOR_JUSTIFY_CENTER
, ATTR_HOR_JUSTIFY
) );
4416 pDoc
->ApplyAttr( nStartCol
, nStartRow
, nTab
, SvxVerJustifyItem( SVX_VER_JUSTIFY_CENTER
, ATTR_VER_JUSTIFY
) );
4419 if ( !AdjustRowHeight( ScRange( 0,nStartRow
,nTab
, MAXCOL
,nEndRow
,nTab
) ) )
4420 rDocShell
.PostPaint( nStartCol
, nStartRow
, nTab
,
4421 nEndCol
, nEndRow
, nTab
, PAINT_GRID
);
4422 if (bNeedContents
|| rOption
.mbCenter
)
4424 ScRange
aRange(nStartCol
, nStartRow
, nTab
, nEndCol
, nEndRow
, nTab
);
4425 pDoc
->SetDirty(aRange
);
4428 bNeedContentsUndo
|= bNeedContents
;
4433 SdrUndoGroup
* pDrawUndo
= pDoc
->GetDrawLayer() ? pDoc
->GetDrawLayer()->GetCalcUndo() : NULL
;
4434 rDocShell
.GetUndoManager()->AddUndoAction(
4435 new ScUndoMerge(&rDocShell
, rOption
, bNeedContentsUndo
, pUndoDoc
, pDrawUndo
) );
4438 aModificator
.SetDocumentModified();
4440 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
4443 pBindings
->Invalidate( FID_MERGE_ON
);
4444 pBindings
->Invalidate( FID_MERGE_OFF
);
4445 pBindings
->Invalidate( FID_MERGE_TOGGLE
);
4451 BOOL
ScDocFunc::UnmergeCells( const ScRange
& rRange
, BOOL bRecord
, BOOL bApi
)
4453 ScCellMergeOption
aOption(rRange
.aStart
.Col(), rRange
.aStart
.Row(), rRange
.aEnd
.Col(), rRange
.aEnd
.Row());
4454 SCTAB nTab1
= rRange
.aStart
.Tab(), nTab2
= rRange
.aEnd
.Tab();
4455 for (SCTAB i
= nTab1
; i
<= nTab2
; ++i
)
4456 aOption
.maTabs
.insert(i
);
4458 return UnmergeCells(aOption
, bRecord
, bApi
);
4461 bool ScDocFunc::UnmergeCells( const ScCellMergeOption
& rOption
, BOOL bRecord
, BOOL bApi
)
4465 if (rOption
.maTabs
.empty())
4466 // Nothing to unmerge.
4469 ScDocShellModificator
aModificator( rDocShell
);
4470 ScDocument
* pDoc
= rDocShell
.GetDocument();
4472 if (bRecord
&& !pDoc
->IsUndoEnabled())
4475 ScDocument
* pUndoDoc
= NULL
;
4477 for (set
<SCTAB
>::const_iterator itr
= rOption
.maTabs
.begin(), itrEnd
= rOption
.maTabs
.end();
4478 itr
!= itrEnd
; ++itr
)
4481 ScRange aRange
= rOption
.getSingleRange(nTab
);
4482 if ( !pDoc
->HasAttrib(aRange
, HASATTR_MERGED
) )
4488 ScRange aExtended
= aRange
;
4489 pDoc
->ExtendMerge(aExtended
);
4490 ScRange aRefresh
= aExtended
;
4491 pDoc
->ExtendOverlapped(aRefresh
);
4497 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
4498 pUndoDoc
->InitUndo(pDoc
, *rOption
.maTabs
.begin(), *rOption
.maTabs
.rbegin());
4500 pDoc
->CopyToDocument(aExtended
, IDF_ATTRIB
, FALSE
, pUndoDoc
);
4503 const SfxPoolItem
& rDefAttr
= pDoc
->GetPool()->GetDefaultItem( ATTR_MERGE
);
4504 ScPatternAttr
aPattern( pDoc
->GetPool() );
4505 aPattern
.GetItemSet().Put( rDefAttr
);
4506 pDoc
->ApplyPatternAreaTab( aRange
.aStart
.Col(), aRange
.aStart
.Row(),
4507 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), nTab
,
4510 pDoc
->RemoveFlagsTab( aExtended
.aStart
.Col(), aExtended
.aStart
.Row(),
4511 aExtended
.aEnd
.Col(), aExtended
.aEnd
.Row(), nTab
,
4512 SC_MF_HOR
| SC_MF_VER
);
4514 pDoc
->ExtendMerge( aRefresh
, TRUE
, FALSE
);
4516 if ( !AdjustRowHeight( aExtended
) )
4517 rDocShell
.PostPaint( aExtended
, PAINT_GRID
);
4524 rDocShell
.GetUndoManager()->AddUndoAction(
4525 new ScUndoRemoveMerge( &rDocShell
, rOption
, pUndoDoc
) );
4527 aModificator
.SetDocumentModified();
4532 //------------------------------------------------------------------------
4534 BOOL
ScDocFunc::ModifyRangeNames( const ScRangeName
& rNewRanges
, BOOL bApi
)
4536 return SetNewRangeNames( new ScRangeName( rNewRanges
), bApi
);
4539 BOOL
ScDocFunc::SetNewRangeNames( ScRangeName
* pNewRanges
, BOOL
/* bApi */ ) // takes ownership of pNewRanges
4541 ScDocShellModificator
aModificator( rDocShell
);
4543 DBG_ASSERT( pNewRanges
, "pNewRanges is 0" );
4544 ScDocument
* pDoc
= rDocShell
.GetDocument();
4545 BOOL
bUndo(pDoc
->IsUndoEnabled());
4549 ScRangeName
* pOld
= pDoc
->GetRangeName();
4550 ScRangeName
* pUndoRanges
= new ScRangeName(*pOld
);
4551 ScRangeName
* pRedoRanges
= new ScRangeName(*pNewRanges
);
4552 rDocShell
.GetUndoManager()->AddUndoAction(
4553 new ScUndoRangeNames( &rDocShell
, pUndoRanges
, pRedoRanges
) );
4556 // #i55926# While loading XML, formula cells only have a single string token,
4557 // so CompileNameFormula would never find any name (index) tokens, and would
4558 // unnecessarily loop through all cells.
4559 BOOL bCompile
= ( !pDoc
->IsImportingXML() && pDoc
->GetNamedRangesLockCount() == 0 );
4562 pDoc
->CompileNameFormula( TRUE
); // CreateFormulaString
4563 pDoc
->SetRangeName( pNewRanges
); // takes ownership
4565 pDoc
->CompileNameFormula( FALSE
); // CompileFormulaString
4567 aModificator
.SetDocumentModified();
4568 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED
) );
4573 //------------------------------------------------------------------------
4575 void ScDocFunc::CreateOneName( ScRangeName
& rList
,
4576 SCCOL nPosX
, SCROW nPosY
, SCTAB nTab
,
4577 SCCOL nX1
, SCROW nY1
, SCCOL nX2
, SCROW nY2
,
4578 BOOL
& rCancel
, BOOL bApi
)
4583 ScDocument
* pDoc
= rDocShell
.GetDocument();
4584 if (!pDoc
->HasValueData( nPosX
, nPosY
, nTab
))
4587 pDoc
->GetString( nPosX
, nPosY
, nTab
, aName
);
4588 ScRangeData::MakeValidName(aName
);
4592 ScRange( nX1
, nY1
, nTab
, nX2
, nY2
, nTab
).Format( aContent
, SCR_ABS_3D
, pDoc
);
4594 BOOL bInsert
= FALSE
;
4596 if (rList
.SearchName( aName
, nOldPos
)) // vorhanden ?
4598 ScRangeData
* pOld
= rList
[nOldPos
];
4600 pOld
->GetSymbol( aOldStr
);
4601 if (aOldStr
!= aContent
)
4604 bInsert
= TRUE
; // per API nicht nachfragen
4607 String aTemplate
= ScGlobal::GetRscString( STR_CREATENAME_REPLACE
);
4609 String aMessage
= aTemplate
.GetToken( 0, '#' );
4611 aMessage
+= aTemplate
.GetToken( 1, '#' );
4613 short nResult
= QueryBox( rDocShell
.GetActiveDialogParent(),
4614 WinBits(WB_YES_NO_CANCEL
| WB_DEF_YES
),
4615 aMessage
).Execute();
4616 if ( nResult
== RET_YES
)
4618 rList
.AtFree(nOldPos
);
4621 else if ( nResult
== RET_CANCEL
)
4631 ScRangeData
* pData
= new ScRangeData( pDoc
, aName
, aContent
,
4632 ScAddress( nPosX
, nPosY
, nTab
));
4633 if (!rList
.Insert(pData
))
4643 BOOL
ScDocFunc::CreateNames( const ScRange
& rRange
, USHORT nFlags
, BOOL bApi
)
4646 return FALSE
; // war nix
4648 ScDocShellModificator
aModificator( rDocShell
);
4651 SCCOL nStartCol
= rRange
.aStart
.Col();
4652 SCROW nStartRow
= rRange
.aStart
.Row();
4653 SCCOL nEndCol
= rRange
.aEnd
.Col();
4654 SCROW nEndRow
= rRange
.aEnd
.Row();
4655 SCTAB nTab
= rRange
.aStart
.Tab();
4656 DBG_ASSERT(rRange
.aEnd
.Tab() == nTab
, "CreateNames: mehrere Tabellen geht nicht");
4659 if ( nFlags
& ( NAME_TOP
| NAME_BOTTOM
) )
4660 if ( nStartRow
== nEndRow
)
4662 if ( nFlags
& ( NAME_LEFT
| NAME_RIGHT
) )
4663 if ( nStartCol
== nEndCol
)
4668 ScDocument
* pDoc
= rDocShell
.GetDocument();
4669 ScRangeName
* pNames
= pDoc
->GetRangeName();
4671 return FALSE
; // soll nicht sein
4672 ScRangeName
aNewRanges( *pNames
);
4674 BOOL bTop
= ( ( nFlags
& NAME_TOP
) != 0 );
4675 BOOL bLeft
= ( ( nFlags
& NAME_LEFT
) != 0 );
4676 BOOL bBottom
= ( ( nFlags
& NAME_BOTTOM
) != 0 );
4677 BOOL bRight
= ( ( nFlags
& NAME_RIGHT
) != 0 );
4679 SCCOL nContX1
= nStartCol
;
4680 SCROW nContY1
= nStartRow
;
4681 SCCOL nContX2
= nEndCol
;
4682 SCROW nContY2
= nEndRow
;
4693 BOOL bCancel
= FALSE
;
4698 for (i
=nContX1
; i
<=nContX2
; i
++)
4699 CreateOneName( aNewRanges
, i
,nStartRow
,nTab
, i
,nContY1
,i
,nContY2
, bCancel
, bApi
);
4701 for (j
=nContY1
; j
<=nContY2
; j
++)
4702 CreateOneName( aNewRanges
, nStartCol
,j
,nTab
, nContX1
,j
,nContX2
,j
, bCancel
, bApi
);
4704 for (i
=nContX1
; i
<=nContX2
; i
++)
4705 CreateOneName( aNewRanges
, i
,nEndRow
,nTab
, i
,nContY1
,i
,nContY2
, bCancel
, bApi
);
4707 for (j
=nContY1
; j
<=nContY2
; j
++)
4708 CreateOneName( aNewRanges
, nEndCol
,j
,nTab
, nContX1
,j
,nContX2
,j
, bCancel
, bApi
);
4710 if ( bTop
&& bLeft
)
4711 CreateOneName( aNewRanges
, nStartCol
,nStartRow
,nTab
, nContX1
,nContY1
,nContX2
,nContY2
, bCancel
, bApi
);
4712 if ( bTop
&& bRight
)
4713 CreateOneName( aNewRanges
, nEndCol
,nStartRow
,nTab
, nContX1
,nContY1
,nContX2
,nContY2
, bCancel
, bApi
);
4714 if ( bBottom
&& bLeft
)
4715 CreateOneName( aNewRanges
, nStartCol
,nEndRow
,nTab
, nContX1
,nContY1
,nContX2
,nContY2
, bCancel
, bApi
);
4716 if ( bBottom
&& bRight
)
4717 CreateOneName( aNewRanges
, nEndCol
,nEndRow
,nTab
, nContX1
,nContY1
,nContX2
,nContY2
, bCancel
, bApi
);
4719 bDone
= ModifyRangeNames( aNewRanges
, bApi
);
4721 aModificator
.SetDocumentModified();
4722 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED
) );
4728 //------------------------------------------------------------------------
4730 BOOL
ScDocFunc::InsertNameList( const ScAddress
& rStartPos
, BOOL bApi
)
4732 ScDocShellModificator
aModificator( rDocShell
);
4736 ScDocument
* pDoc
= rDocShell
.GetDocument();
4737 const BOOL bRecord
= pDoc
->IsUndoEnabled();
4738 SCTAB nTab
= rStartPos
.Tab();
4739 ScDocument
* pUndoDoc
= NULL
;
4741 ScRangeName
* pList
= pDoc
->GetRangeName();
4742 USHORT nCount
= pList
->GetCount();
4743 USHORT nValidCount
= 0;
4745 for (i
=0; i
<nCount
; i
++)
4747 ScRangeData
* pData
= (*pList
)[i
];
4748 if ( !pData
->HasType( RT_DATABASE
) && !pData
->HasType( RT_SHARED
) )
4754 SCCOL nStartCol
= rStartPos
.Col();
4755 SCROW nStartRow
= rStartPos
.Row();
4756 SCCOL nEndCol
= nStartCol
+ 1;
4757 SCROW nEndRow
= nStartRow
+ static_cast<SCROW
>(nValidCount
) - 1;
4759 ScEditableTester
aTester( pDoc
, nTab
, nStartCol
,nStartRow
, nEndCol
,nEndRow
);
4760 if (aTester
.IsEditable())
4764 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
4765 pUndoDoc
->InitUndo( pDoc
, nTab
, nTab
);
4766 pDoc
->CopyToDocument( nStartCol
,nStartRow
,nTab
, nEndCol
,nEndRow
,nTab
,
4767 IDF_ALL
, FALSE
, pUndoDoc
);
4769 pDoc
->BeginDrawUndo(); // wegen Hoehenanpassung
4772 ScRangeData
** ppSortArray
= new ScRangeData
* [ nValidCount
];
4774 for (i
=0; i
<nCount
; i
++)
4776 ScRangeData
* pData
= (*pList
)[i
];
4777 if ( !pData
->HasType( RT_DATABASE
) && !pData
->HasType( RT_SHARED
) )
4778 ppSortArray
[j
++] = pData
;
4781 qsort( (void*)ppSortArray
, nValidCount
, sizeof(ScRangeData
*),
4782 &ScRangeData_QsortNameCompare
);
4784 qsort( (void*)ppSortArray
, nValidCount
, sizeof(ScRangeData
*),
4785 ICCQsortNameCompare
);
4788 rtl::OUStringBuffer aContent
;
4790 SCROW nOutRow
= nStartRow
;
4791 for (j
=0; j
<nValidCount
; j
++)
4793 ScRangeData
* pData
= ppSortArray
[j
];
4794 pData
->GetName(aName
);
4795 // relative Referenzen Excel-konform auf die linke Spalte anpassen:
4796 pData
->UpdateSymbol(aContent
, ScAddress( nStartCol
, nOutRow
, nTab
));
4798 aFormula
+= aContent
;
4799 pDoc
->PutCell( nStartCol
,nOutRow
,nTab
, new ScStringCell( aName
) );
4800 pDoc
->PutCell( nEndCol
,nOutRow
,nTab
, new ScStringCell( aFormula
) );
4804 delete [] ppSortArray
;
4808 ScDocument
* pRedoDoc
= new ScDocument( SCDOCMODE_UNDO
);
4809 pRedoDoc
->InitUndo( pDoc
, nTab
, nTab
);
4810 pDoc
->CopyToDocument( nStartCol
,nStartRow
,nTab
, nEndCol
,nEndRow
,nTab
,
4811 IDF_ALL
, FALSE
, pRedoDoc
);
4813 rDocShell
.GetUndoManager()->AddUndoAction(
4814 new ScUndoListNames( &rDocShell
,
4815 ScRange( nStartCol
,nStartRow
,nTab
, nEndCol
,nEndRow
,nTab
),
4816 pUndoDoc
, pRedoDoc
) );
4819 if (!AdjustRowHeight(ScRange(0,nStartRow
,nTab
,MAXCOL
,nEndRow
,nTab
)))
4820 rDocShell
.PostPaint( nStartCol
,nStartRow
,nTab
, nEndCol
,nEndRow
,nTab
, PAINT_GRID
);
4821 //! rDocShell.UpdateOle(GetViewData());
4822 aModificator
.SetDocumentModified();
4826 rDocShell
.ErrorMessage(aTester
.GetMessageId());
4831 //------------------------------------------------------------------------
4833 BOOL
ScDocFunc::ResizeMatrix( const ScRange
& rOldRange
, const ScAddress
& rNewEnd
, BOOL bApi
)
4835 ScDocument
* pDoc
= rDocShell
.GetDocument();
4836 SCCOL nStartCol
= rOldRange
.aStart
.Col();
4837 SCROW nStartRow
= rOldRange
.aStart
.Row();
4838 SCTAB nTab
= rOldRange
.aStart
.Tab();
4840 BOOL
bUndo(pDoc
->IsUndoEnabled());
4845 pDoc
->GetFormula( nStartCol
, nStartRow
, nTab
, aFormula
);
4846 if ( aFormula
.GetChar(0) == '{' && aFormula
.GetChar(aFormula
.Len()-1) == '}' )
4848 String aUndo
= ScGlobal::GetRscString( STR_UNDO_RESIZEMATRIX
);
4850 rDocShell
.GetUndoManager()->EnterListAction( aUndo
, aUndo
);
4852 aFormula
.Erase(0,1);
4853 aFormula
.Erase(aFormula
.Len()-1,1);
4856 aMark
.SetMarkArea( rOldRange
);
4857 aMark
.SelectTable( nTab
, TRUE
);
4858 ScRange
aNewRange( rOldRange
.aStart
, rNewEnd
);
4860 if ( DeleteContents( aMark
, IDF_CONTENTS
, TRUE
, bApi
) )
4862 // GRAM_PODF_A1 for API compatibility.
4863 bRet
= EnterMatrix( aNewRange
, &aMark
, NULL
, aFormula
, bApi
, FALSE
, EMPTY_STRING
, formula::FormulaGrammar::GRAM_PODF_A1
);
4866 // versuchen, alten Zustand wiederherzustellen
4867 EnterMatrix( rOldRange
, &aMark
, NULL
, aFormula
, bApi
, FALSE
, EMPTY_STRING
, formula::FormulaGrammar::GRAM_PODF_A1
);
4872 rDocShell
.GetUndoManager()->LeaveListAction();
4878 //------------------------------------------------------------------------
4880 BOOL
ScDocFunc::InsertAreaLink( const String
& rFile
, const String
& rFilter
,
4881 const String
& rOptions
, const String
& rSource
,
4882 const ScRange
& rDestRange
, ULONG nRefresh
,
4883 BOOL bFitBlock
, BOOL bApi
)
4885 //! auch fuer ScViewFunc::InsertAreaLink benutzen!
4887 ScDocument
* pDoc
= rDocShell
.GetDocument();
4888 BOOL
bUndo (pDoc
->IsUndoEnabled());
4890 SvxLinkManager
* pLinkManager
= pDoc
->GetLinkManager();
4892 // #i52120# if other area links exist at the same start position,
4893 // remove them first (file format specifies only one link definition
4896 USHORT nLinkCount
= pLinkManager
->GetLinks().Count();
4897 USHORT nRemoved
= 0;
4898 USHORT nLinkPos
= 0;
4899 while (nLinkPos
<nLinkCount
)
4901 ::sfx2::SvBaseLink
* pBase
= *pLinkManager
->GetLinks()[nLinkPos
];
4902 if ( pBase
->ISA(ScAreaLink
) &&
4903 static_cast<ScAreaLink
*>(pBase
)->GetDestArea().aStart
== rDestRange
.aStart
)
4909 // group all remove and the insert action
4910 String aUndo
= ScGlobal::GetRscString( STR_UNDO_INSERTAREALINK
);
4911 rDocShell
.GetUndoManager()->EnterListAction( aUndo
, aUndo
);
4914 ScAreaLink
* pOldArea
= static_cast<ScAreaLink
*>(pBase
);
4915 rDocShell
.GetUndoManager()->AddUndoAction(
4916 new ScUndoRemoveAreaLink( &rDocShell
,
4917 pOldArea
->GetFile(), pOldArea
->GetFilter(), pOldArea
->GetOptions(),
4918 pOldArea
->GetSource(), pOldArea
->GetDestArea(), pOldArea
->GetRefreshDelay() ) );
4920 pLinkManager
->Remove( pBase
);
4921 nLinkCount
= pLinkManager
->GetLinks().Count();
4928 String aFilterName
= rFilter
;
4929 String aNewOptions
= rOptions
;
4930 if (!aFilterName
.Len())
4931 ScDocumentLoader::GetFilterName( rFile
, aFilterName
, aNewOptions
, TRUE
, !bApi
);
4933 // remove application prefix from filter name here, so the filter options
4934 // aren't reset when the filter name is changed in ScAreaLink::DataChanged
4935 ScDocumentLoader::RemoveAppPrefix( aFilterName
);
4937 ScAreaLink
* pLink
= new ScAreaLink( &rDocShell
, rFile
, aFilterName
,
4938 aNewOptions
, rSource
, rDestRange
, nRefresh
);
4939 pLinkManager
->InsertFileLink( *pLink
, OBJECT_CLIENT_FILE
, rFile
, &aFilterName
, &rSource
);
4941 // Undo fuer den leeren Link
4945 rDocShell
.GetUndoManager()->AddUndoAction( new ScUndoInsertAreaLink( &rDocShell
,
4946 rFile
, aFilterName
, aNewOptions
,
4947 rSource
, rDestRange
, nRefresh
) );
4949 rDocShell
.GetUndoManager()->LeaveListAction(); // undo for link update is still separate
4952 // Update hat sein eigenes Undo
4954 pLink
->SetDoInsert(bFitBlock
); // beim ersten Update ggf. nichts einfuegen
4955 pLink
->Update(); // kein SetInCreate -> Update ausfuehren
4956 pLink
->SetDoInsert(TRUE
); // Default = TRUE
4958 SfxBindings
* pBindings
= rDocShell
.GetViewBindings();
4960 pBindings
->Invalidate( SID_LINKS
);
4962 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED
) ); // Navigator