1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
24 #include "scitems.hxx"
25 #include <vcl/msgbox.hxx>
26 #include <vcl/waitobj.hxx>
27 #include <sfx2/app.hxx>
28 #include <sfx2/bindings.hxx>
30 #include <com/sun/star/script/vba/XVBACompatibility.hpp>
34 #include "globstr.hrc"
35 #include "globalnames.hxx"
36 #include "undodat.hxx"
37 #include "undotab.hxx"
38 #include "undoblk.hxx"
39 #include "dpobject.hxx"
40 #include "dpshttab.hxx"
41 #include "dbdocfun.hxx"
42 #include "consoli.hxx"
44 #include "progress.hxx"
45 #include "olinetab.hxx"
46 #include "patattr.hxx"
48 #include "docpool.hxx"
49 #include "uiitems.hxx"
51 #include "waitoff.hxx"
52 #include "sizedev.hxx"
53 #include "clipparam.hxx"
54 #include <rowheightcontext.hxx>
55 #include <refupdatecontext.hxx>
57 using com::sun::star::script::XLibraryContainer
;
58 using com::sun::star::script::vba::XVBACompatibility
;
59 using com::sun::star::container::XNameContainer
;
60 using com::sun::star::uno::Reference
;
61 using com::sun::star::uno::UNO_QUERY
;
63 using ::std::unique_ptr
;
66 // former viewfunc/dbfunc methods
68 void ScDocShell::ErrorMessage( sal_uInt16 nGlobStrId
)
70 //! StopMarking an der (aktiven) View?
72 vcl::Window
* pParent
= GetActiveDialogParent();
73 ScWaitCursorOff
aWaitOff( pParent
);
74 bool bFocus
= pParent
&& pParent
->HasFocus();
76 if(nGlobStrId
==STR_PROTECTIONERR
)
80 nGlobStrId
=STR_READONLYERR
;
84 ScopedVclPtrInstance
< InfoBox
> aBox( pParent
, ScGlobal::GetRscString( nGlobStrId
) );
90 bool ScDocShell::IsEditable() const
92 // import into read-only document is possible - must be extended if other filters use api
93 // #i108547# MSOOXML filter uses "IsChangeReadOnlyEnabled" property
95 return !IsReadOnly() || aDocument
.IsImportingXML() || aDocument
.IsChangeReadOnlyEnabled();
98 void ScDocShell::DBAreaDeleted( SCTAB nTab
, SCCOL nX1
, SCROW nY1
, SCCOL nX2
, SCROW
/* nY2 */ )
100 ScDocShellModificator
aModificator( *this );
101 aDocument
.RemoveFlagsTab( nX1
, nY1
, nX2
, nY1
, nTab
, SC_MF_AUTO
);
102 PostPaint( nX1
, nY1
, nTab
, nX2
, nY1
, nTab
, PAINT_GRID
);
103 // No SetDocumentModified, as the unnamed database range might have to be restored later.
104 // The UNO hint is broadcast directly instead, to keep UNO objects in valid state.
105 aDocument
.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED
) );
108 ScDBData
* ScDocShell::GetDBData( const ScRange
& rMarked
, ScGetDBMode eMode
, ScGetDBSelection eSel
)
110 SCCOL nCol
= rMarked
.aStart
.Col();
111 SCROW nRow
= rMarked
.aStart
.Row();
112 SCTAB nTab
= rMarked
.aStart
.Tab();
114 SCCOL nStartCol
= nCol
;
115 SCROW nStartRow
= nRow
;
116 SCTAB nStartTab
= nTab
;
117 SCCOL nEndCol
= rMarked
.aEnd
.Col();
118 SCROW nEndRow
= rMarked
.aEnd
.Row();
119 SCTAB nEndTab
= rMarked
.aEnd
.Tab();
120 // Nicht einfach GetDBAtCursor: Der zusammenhaengende Datenbereich
121 // fuer "unbenannt" (GetDataArea) kann neben dem Cursor legen, also muss auch ein
122 // benannter DB-Bereich dort gesucht werden.
123 ScDBCollection
* pColl
= aDocument
.GetDBCollection();
124 ScDBData
* pData
= aDocument
.GetDBAtArea( nTab
, nStartCol
, nStartRow
, nEndCol
, nEndRow
);
126 pData
= pColl
->GetDBNearCursor(nCol
, nRow
, nTab
);
128 bool bSelected
= ( eSel
== SC_DBSEL_FORCE_MARK
||
129 (rMarked
.aStart
!= rMarked
.aEnd
&& eSel
!= SC_DBSEL_ROW_DOWN
) );
130 bool bOnlyDown
= (!bSelected
&& eSel
== SC_DBSEL_ROW_DOWN
&& rMarked
.aStart
.Row() == rMarked
.aEnd
.Row());
132 bool bUseThis
= false;
135 // Bereich nehmen, wenn nichts anderes markiert
142 pData
->GetArea( nDummy
, nOldCol1
,nOldRow1
, nOldCol2
,nOldRow2
);
143 bool bIsNoName
= ( pData
->GetName() == STR_DB_LOCAL_NONAME
);
148 if ( bIsNoName
&& eMode
== SC_DB_MAKE
)
150 // If nothing marked or only one row marked, adapt
151 // "unbenannt"/"unnamed" to contiguous area.
156 nEndCol
= rMarked
.aEnd
.Col();
157 nEndRow
= rMarked
.aEnd
.Row();
164 aDocument
.GetDataArea( nTab
, nStartCol
, nStartRow
, nEndCol
, nEndRow
, false, bOnlyDown
);
165 if ( nOldCol1
!= nStartCol
|| nOldCol2
!= nEndCol
|| nOldRow1
!= nStartRow
)
166 bUseThis
= false; // passt gar nicht
167 else if ( nOldRow2
!= nEndRow
)
169 // Bereich auf neue End-Zeile erweitern
170 pData
->SetArea( nTab
, nOldCol1
,nOldRow1
, nOldCol2
,nEndRow
);
176 if ( nOldCol1
== nStartCol
&& nOldRow1
== nStartRow
&&
177 nOldCol2
== nEndCol
&& nOldRow2
== nEndRow
) // genau markiert?
180 bUseThis
= false; // immer Markierung nehmen (Bug 11964)
183 // fuer Import nie "unbenannt" nehmen
185 if ( bUseThis
&& eMode
== SC_DB_IMPORT
&& bIsNoName
)
191 pData
->GetArea( nStartTab
, nStartCol
,nStartRow
, nEndCol
,nEndRow
);
194 else if ( eMode
== SC_DB_OLD
)
196 pData
= NULL
; // nichts gefunden
197 nStartCol
= nEndCol
= nCol
;
198 nStartRow
= nEndRow
= nRow
;
199 nStartTab
= nEndTab
= nTab
;
204 { // zusammenhaengender Bereich
209 nEndCol
= rMarked
.aEnd
.Col();
210 nEndRow
= rMarked
.aEnd
.Row();
217 aDocument
.GetDataArea( nTab
, nStartCol
, nStartRow
, nEndCol
, nEndRow
, false, bOnlyDown
);
220 bool bHasHeader
= aDocument
.HasColHeader( nStartCol
,nStartRow
, nEndCol
,nEndRow
, nTab
);
222 ScDBData
* pNoNameData
= aDocument
.GetAnonymousDBData(nTab
);
223 if ( eMode
!= SC_DB_IMPORT
&& pNoNameData
)
226 if ( !pOldAutoDBRange
)
228 // store the old unnamed database range with its settings for undo
229 // (store at the first change, get the state before all changes)
230 pOldAutoDBRange
= new ScDBData( *pNoNameData
);
233 SCCOL nOldX1
; // alten Bereich sauber wegnehmen
234 SCROW nOldY1
; //! (UNDO ???)
238 pNoNameData
->GetArea( nOldTab
, nOldX1
, nOldY1
, nOldX2
, nOldY2
);
239 DBAreaDeleted( nOldTab
, nOldX1
, nOldY1
, nOldX2
, nOldY2
);
241 pNoNameData
->SetSortParam( ScSortParam() ); // Parameter zuruecksetzen
242 pNoNameData
->SetQueryParam( ScQueryParam() );
243 pNoNameData
->SetSubTotalParam( ScSubTotalParam() );
245 pNoNameData
->SetArea( nTab
, nStartCol
,nStartRow
, nEndCol
,nEndRow
); // neu setzen
246 pNoNameData
->SetByRow( true );
247 pNoNameData
->SetHeader( bHasHeader
);
248 pNoNameData
->SetAutoFilter( false );
252 ScDBCollection
* pUndoColl
= NULL
;
255 if (eMode
==SC_DB_IMPORT
)
257 aDocument
.PreprocessDBDataUpdate();
258 pUndoColl
= new ScDBCollection( *pColl
); // Undo fuer Import1-Bereich
260 OUString aImport
= ScGlobal::GetRscString( STR_DBNAME_IMPORT
);
262 const ScDBData
* pDummy
= NULL
;
263 ScDBCollection::NamedDBs
& rDBs
= pColl
->getNamedDBs();
268 aNewName
+= OUString::number( nCount
);
269 pDummy
= rDBs
.findByUpperName(ScGlobal::pCharClass
->uppercase(aNewName
));
272 pNoNameData
= new ScDBData( aNewName
, nTab
,
273 nStartCol
,nStartRow
, nEndCol
,nEndRow
,
275 bool ins
= rDBs
.insert(pNoNameData
);
276 assert(ins
); (void)ins
;
280 aNewName
= STR_DB_LOCAL_NONAME
;
281 pNoNameData
= new ScDBData(aNewName
, nTab
,
282 nStartCol
,nStartRow
, nEndCol
,nEndRow
,
284 aDocument
.SetAnonymousDBData(nTab
, pNoNameData
);
289 aDocument
.CompileHybridFormula();
291 ScDBCollection
* pRedoColl
= new ScDBCollection( *pColl
);
292 GetUndoManager()->AddUndoAction( new ScUndoDBData( this, pUndoColl
, pRedoColl
) );
295 // neuen Bereich am Sba anmelden nicht mehr noetig
297 // "Import1" etc am Navigator bekanntmachen
298 if (eMode
==SC_DB_IMPORT
)
299 SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED
) );
307 ScDBData
* ScDocShell::GetAnonymousDBData(const ScRange
& rRange
)
309 bool bHasHeader
= aDocument
.HasColHeader(
310 rRange
.aStart
.Col(), rRange
.aStart
.Row(), rRange
.aEnd
.Col(), rRange
.aEnd
.Row(), rRange
.aStart
.Tab());
312 ScDBCollection
* pColl
= aDocument
.GetDBCollection();
316 ScDBData
* pData
= pColl
->getAnonDBs().getByRange(rRange
);
320 pData
->SetHeader(bHasHeader
);
324 ScDBData
* ScDocShell::GetOldAutoDBRange()
326 ScDBData
* pRet
= pOldAutoDBRange
;
327 pOldAutoDBRange
= NULL
;
328 return pRet
; // has to be deleted by caller!
331 void ScDocShell::CancelAutoDBRange()
333 // called when dialog is cancelled
335 if ( pOldAutoDBRange
)
337 SCTAB nTab
= GetCurTab();
338 ScDBData
* pDBData
= aDocument
.GetAnonymousDBData(nTab
);
346 pDBData
->GetArea( nRangeTab
, nRangeX1
, nRangeY1
, nRangeX2
, nRangeY2
);
347 DBAreaDeleted( nRangeTab
, nRangeX1
, nRangeY1
, nRangeX2
, nRangeY2
);
349 *pDBData
= *pOldAutoDBRange
; // restore old settings
351 if ( pOldAutoDBRange
->HasAutoFilter() )
353 // restore AutoFilter buttons
354 pOldAutoDBRange
->GetArea( nRangeTab
, nRangeX1
, nRangeY1
, nRangeX2
, nRangeY2
);
355 aDocument
.ApplyFlagsTab( nRangeX1
, nRangeY1
, nRangeX2
, nRangeY1
, nRangeTab
, SC_MF_AUTO
);
356 PostPaint( nRangeX1
, nRangeY1
, nRangeTab
, nRangeX2
, nRangeY1
, nRangeTab
, PAINT_GRID
);
360 delete pOldAutoDBRange
;
361 pOldAutoDBRange
= NULL
;
366 //! mit docfunc zusammenfassen
368 bool ScDocShell::AdjustRowHeight( SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
)
370 ScSizeDeviceProvider
aProv(this);
372 sc::RowHeightContext
aCxt(aProv
.GetPPTX(), aProv
.GetPPTY(), aZoom
, aZoom
, aProv
.GetDevice());
373 bool bChange
= aDocument
.SetOptimalHeight(aCxt
, nStartRow
,nEndRow
, nTab
);
376 PostPaint( 0,nStartRow
,nTab
, MAXCOL
,MAXROW
,nTab
, PAINT_GRID
|PAINT_LEFT
);
381 void ScDocShell::UpdateAllRowHeights( const ScMarkData
* pTabMark
)
383 // update automatic row heights
385 ScSizeDeviceProvider
aProv(this);
387 sc::RowHeightContext
aCxt(aProv
.GetPPTX(), aProv
.GetPPTY(), aZoom
, aZoom
, aProv
.GetDevice());
388 aDocument
.UpdateAllRowHeights(aCxt
, pTabMark
);
391 void ScDocShell::UpdatePendingRowHeights( SCTAB nUpdateTab
, bool bBefore
)
393 bool bIsUndoEnabled
= aDocument
.IsUndoEnabled();
394 aDocument
.EnableUndo( false );
395 aDocument
.LockStreamValid( true ); // ignore draw page size (but not formula results)
396 if ( bBefore
) // check all sheets up to nUpdateTab
398 SCTAB nTabCount
= aDocument
.GetTableCount();
399 if ( nUpdateTab
>= nTabCount
)
400 nUpdateTab
= nTabCount
-1; // nUpdateTab is inclusive
402 ScMarkData aUpdateSheets
;
404 for (nTab
=0; nTab
<=nUpdateTab
; ++nTab
)
405 if ( aDocument
.IsPendingRowHeights( nTab
) )
406 aUpdateSheets
.SelectTable( nTab
, true );
408 if (aUpdateSheets
.GetSelectCount())
409 UpdateAllRowHeights(&aUpdateSheets
); // update with a single progress bar
411 for (nTab
=0; nTab
<=nUpdateTab
; ++nTab
)
412 if ( aUpdateSheets
.GetTableSelect( nTab
) )
414 aDocument
.UpdatePageBreaks( nTab
);
415 aDocument
.SetPendingRowHeights( nTab
, false );
418 else // only nUpdateTab
420 if ( aDocument
.IsPendingRowHeights( nUpdateTab
) )
422 AdjustRowHeight( 0, MAXROW
, nUpdateTab
);
423 aDocument
.UpdatePageBreaks( nUpdateTab
);
424 aDocument
.SetPendingRowHeights( nUpdateTab
, false );
427 aDocument
.LockStreamValid( false );
428 aDocument
.EnableUndo( bIsUndoEnabled
);
431 void ScDocShell::RefreshPivotTables( const ScRange
& rSource
)
433 ScDPCollection
* pColl
= aDocument
.GetDPCollection();
437 ScDBDocFunc
aFunc(*this);
438 for (size_t i
= 0, n
= pColl
->GetCount(); i
< n
; ++i
)
440 ScDPObject
* pOld
= (*pColl
)[i
];
444 const ScSheetSourceDesc
* pSheetDesc
= pOld
->GetSheetDesc();
445 if (pSheetDesc
&& pSheetDesc
->GetSourceRange().Intersects(rSource
))
446 aFunc
.UpdatePivotTable(*pOld
, true, false);
450 static OUString
lcl_GetAreaName( ScDocument
* pDoc
, ScArea
* pArea
)
454 ScDBData
* pData
= pDoc
->GetDBAtArea( pArea
->nTab
, pArea
->nColStart
, pArea
->nRowStart
,
455 pArea
->nColEnd
, pArea
->nRowEnd
);
458 aName
= pData
->GetName();
463 pDoc
->GetName( pArea
->nTab
, aName
);
468 void ScDocShell::DoConsolidate( const ScConsolidateParam
& rParam
, bool bRecord
)
476 for (nPos
=0; nPos
<rParam
.nDataAreaCount
; nPos
++)
478 ScArea
* pArea
= rParam
.ppDataAreas
[nPos
];
479 nColSize
= std::max( nColSize
, SCCOL( pArea
->nColEnd
- pArea
->nColStart
+ 1 ) );
480 nRowSize
= std::max( nRowSize
, SCROW( pArea
->nRowEnd
- pArea
->nRowStart
+ 1 ) );
482 // Test, ob Quelldaten verschoben wuerden
483 if (rParam
.bReferenceData
)
484 if (pArea
->nTab
== rParam
.nTab
&& pArea
->nRowEnd
>= rParam
.nRow
)
490 ScopedVclPtrInstance
<InfoBox
> aBox( GetActiveDialogParent(),
491 ScGlobal::GetRscString( STR_CONSOLIDATE_ERR1
) );
498 WaitObject
aWait( GetActiveDialogParent() );
499 ScDocShellModificator
aModificator( *this );
502 ScDBData
* pDestData
= aDocument
.GetDBAtCursor( rParam
.nCol
, rParam
.nRow
, rParam
.nTab
, true );
504 pDestData
->GetArea(aOldDest
);
506 aData
.SetSize( nColSize
, nRowSize
);
507 aData
.SetFlags( rParam
.eFunction
, rParam
.bByCol
, rParam
.bByRow
, rParam
.bReferenceData
);
508 if ( rParam
.bByCol
|| rParam
.bByRow
)
509 for (nPos
=0; nPos
<rParam
.nDataAreaCount
; nPos
++)
511 ScArea
* pArea
= rParam
.ppDataAreas
[nPos
];
512 aData
.AddFields( &aDocument
, pArea
->nTab
, pArea
->nColStart
, pArea
->nRowStart
,
513 pArea
->nColEnd
, pArea
->nRowEnd
);
516 for (nPos
=0; nPos
<rParam
.nDataAreaCount
; nPos
++)
518 ScArea
* pArea
= rParam
.ppDataAreas
[nPos
];
519 aData
.AddData( &aDocument
, pArea
->nTab
, pArea
->nColStart
, pArea
->nRowStart
,
520 pArea
->nColEnd
, pArea
->nRowEnd
);
521 aData
.AddName( lcl_GetAreaName(&aDocument
,pArea
) );
524 aData
.GetSize( nColSize
, nRowSize
);
525 if (bRecord
&& nColSize
> 0 && nRowSize
> 0)
527 ScDBData
* pUndoData
= pDestData
? new ScDBData(*pDestData
) : NULL
;
529 SCTAB nDestTab
= rParam
.nTab
;
530 ScArea
aDestArea( rParam
.nTab
, rParam
.nCol
, rParam
.nRow
,
531 rParam
.nCol
+nColSize
-1, rParam
.nRow
+nRowSize
-1 );
532 if (rParam
.bByCol
) ++aDestArea
.nColEnd
;
533 if (rParam
.bByRow
) ++aDestArea
.nRowEnd
;
535 if (rParam
.bReferenceData
)
537 SCTAB nTabCount
= aDocument
.GetTableCount();
538 SCROW nInsertCount
= aData
.GetInsertCount();
541 ScOutlineTable
* pTable
= aDocument
.GetOutlineTable( nDestTab
);
542 ScOutlineTable
* pUndoTab
= pTable
? new ScOutlineTable( *pTable
) : NULL
;
544 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
545 pUndoDoc
->InitUndo( &aDocument
, 0, nTabCount
-1, false, true );
548 aDocument
.CopyToDocument( 0,0,nDestTab
, MAXCOL
,MAXROW
,nDestTab
,
549 IDF_NONE
, false, pUndoDoc
);
552 aDocument
.CopyToDocument( 0,0,0, MAXCOL
,MAXROW
,nTabCount
-1,
553 IDF_FORMULA
, false, pUndoDoc
);
555 // komplette Ausgangszeilen
556 aDocument
.CopyToDocument( 0,aDestArea
.nRowStart
,nDestTab
,
557 MAXCOL
,aDestArea
.nRowEnd
,nDestTab
,
558 IDF_ALL
, false, pUndoDoc
);
560 // alten Ausgabebereich
562 aDocument
.CopyToDocument( aOldDest
, IDF_ALL
, false, pUndoDoc
);
564 GetUndoManager()->AddUndoAction(
565 new ScUndoConsolidate( this, aDestArea
, rParam
, pUndoDoc
,
566 true, nInsertCount
, pUndoTab
, pUndoData
) );
570 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
571 pUndoDoc
->InitUndo( &aDocument
, aDestArea
.nTab
, aDestArea
.nTab
);
573 aDocument
.CopyToDocument( aDestArea
.nColStart
, aDestArea
.nRowStart
, aDestArea
.nTab
,
574 aDestArea
.nColEnd
, aDestArea
.nRowEnd
, aDestArea
.nTab
,
575 IDF_ALL
, false, pUndoDoc
);
577 // alten Ausgabebereich
579 aDocument
.CopyToDocument( aOldDest
, IDF_ALL
, false, pUndoDoc
);
581 GetUndoManager()->AddUndoAction(
582 new ScUndoConsolidate( this, aDestArea
, rParam
, pUndoDoc
,
583 false, 0, NULL
, pUndoData
) );
587 if (pDestData
) // Zielbereich loeschen / anpassen
589 aDocument
.DeleteAreaTab(aOldDest
, IDF_CONTENTS
);
590 pDestData
->SetArea( rParam
.nTab
, rParam
.nCol
, rParam
.nRow
,
591 rParam
.nCol
+ nColSize
- 1, rParam
.nRow
+ nRowSize
- 1 );
592 pDestData
->SetHeader( rParam
.bByRow
);
595 aData
.OutputToDocument( &aDocument
, rParam
.nCol
, rParam
.nRow
, rParam
.nTab
);
597 SCCOL nPaintStartCol
= rParam
.nCol
;
598 SCROW nPaintStartRow
= rParam
.nRow
;
599 SCCOL nPaintEndCol
= nPaintStartCol
+ nColSize
- 1;
600 SCROW nPaintEndRow
= nPaintStartRow
+ nRowSize
- 1;
601 sal_uInt16 nPaintFlags
= PAINT_GRID
;
606 if (rParam
.bReferenceData
)
609 nPaintEndCol
= MAXCOL
;
610 nPaintEndRow
= MAXROW
;
611 nPaintFlags
|= PAINT_LEFT
| PAINT_SIZE
;
615 if ( aOldDest
.aEnd
.Col() > nPaintEndCol
)
616 nPaintEndCol
= aOldDest
.aEnd
.Col();
617 if ( aOldDest
.aEnd
.Row() > nPaintEndRow
)
618 nPaintEndRow
= aOldDest
.aEnd
.Row();
620 PostPaint( nPaintStartCol
, nPaintStartRow
, rParam
.nTab
,
621 nPaintEndCol
, nPaintEndRow
, rParam
.nTab
, nPaintFlags
);
622 aModificator
.SetDocumentModified();
625 void ScDocShell::UseScenario( SCTAB nTab
, const OUString
& rName
, bool bRecord
)
627 if (!aDocument
.IsScenario(nTab
))
629 SCTAB nTabCount
= aDocument
.GetTableCount();
630 SCTAB nSrcTab
= SCTAB_MAX
;
631 SCTAB nEndTab
= nTab
;
633 while ( nEndTab
+1 < nTabCount
&& aDocument
.IsScenario(nEndTab
+1) )
636 if (nSrcTab
> MAXTAB
) // noch auf der Suche nach dem Szenario?
638 aDocument
.GetName( nEndTab
, aCompare
);
639 if (aCompare
.equals(rName
))
640 nSrcTab
= nEndTab
; // gefunden
643 if (ValidTab(nSrcTab
))
645 if ( aDocument
.TestCopyScenario( nSrcTab
, nTab
) ) // Zellschutz testen
647 ScDocShellModificator
aModificator( *this );
648 ScMarkData aScenMark
;
649 aDocument
.MarkScenario( nSrcTab
, nTab
, aScenMark
);
651 aScenMark
.GetMultiMarkArea( aMultiRange
);
652 SCCOL nStartCol
= aMultiRange
.aStart
.Col();
653 SCROW nStartRow
= aMultiRange
.aStart
.Row();
654 SCCOL nEndCol
= aMultiRange
.aEnd
.Col();
655 SCROW nEndRow
= aMultiRange
.aEnd
.Row();
659 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
660 pUndoDoc
->InitUndo( &aDocument
, nTab
,nEndTab
); // auch alle Szenarien
661 // angezeigte Tabelle:
662 aDocument
.CopyToDocument( nStartCol
,nStartRow
,nTab
,
663 nEndCol
,nEndRow
,nTab
, IDF_ALL
,true, pUndoDoc
, &aScenMark
);
665 for (SCTAB i
=nTab
+1; i
<=nEndTab
; i
++)
667 pUndoDoc
->SetScenario( i
, true );
670 sal_uInt16 nScenFlags
;
671 aDocument
.GetScenarioData( i
, aComment
, aColor
, nScenFlags
);
672 pUndoDoc
->SetScenarioData( i
, aComment
, aColor
, nScenFlags
);
673 bool bActive
= aDocument
.IsActiveScenario( i
);
674 pUndoDoc
->SetActiveScenario( i
, bActive
);
675 // Bei Zurueckkopier-Szenarios auch Inhalte
676 if ( nScenFlags
& SC_SCENARIO_TWOWAY
)
677 aDocument
.CopyToDocument( 0,0,i
, MAXCOL
,MAXROW
,i
,
678 IDF_ALL
,false, pUndoDoc
);
681 GetUndoManager()->AddUndoAction(
682 new ScUndoUseScenario( this, aScenMark
,
683 ScArea( nTab
,nStartCol
,nStartRow
,nEndCol
,nEndRow
),
687 aDocument
.CopyScenario( nSrcTab
, nTab
);
689 sc::SetFormulaDirtyContext aCxt
;
690 aDocument
.SetAllFormulasDirty(aCxt
);
692 // alles painten, weil in anderen Bereichen das aktive Szenario
693 // geaendert sein kann
694 //! nur, wenn sichtbare Rahmen vorhanden?
695 PostPaint( 0,0,nTab
, MAXCOL
,MAXROW
,nTab
, PAINT_GRID
);
696 aModificator
.SetDocumentModified();
700 ScopedVclPtrInstance
<InfoBox
> aBox( GetActiveDialogParent(),
701 ScGlobal::GetRscString( STR_PROTECTIONERR
) );
707 ScopedVclPtrInstance
<InfoBox
> aBox(GetActiveDialogParent(),
708 ScGlobal::GetRscString( STR_SCENARIO_NOTFOUND
) );
714 OSL_FAIL( "UseScenario auf Szenario-Blatt" );
718 void ScDocShell::ModifyScenario( SCTAB nTab
, const OUString
& rName
, const OUString
& rComment
,
719 const Color
& rColor
, sal_uInt16 nFlags
)
723 aDocument
.GetName( nTab
, aOldName
);
724 OUString aOldComment
;
726 sal_uInt16 nOldFlags
;
727 aDocument
.GetScenarioData( nTab
, aOldComment
, aOldColor
, nOldFlags
);
728 GetUndoManager()->AddUndoAction(
729 new ScUndoScenarioFlags( this, nTab
,
730 aOldName
, rName
, aOldComment
, rComment
,
731 aOldColor
, rColor
, nOldFlags
, nFlags
) );
734 ScDocShellModificator
aModificator( *this );
735 aDocument
.RenameTab( nTab
, rName
);
736 aDocument
.SetScenarioData( nTab
, rComment
, rColor
, nFlags
);
738 aModificator
.SetDocumentModified();
740 if (!aOldName
.equals(rName
))
741 SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
743 SfxBindings
* pBindings
= GetViewBindings();
745 pBindings
->Invalidate( SID_SELECT_SCENARIO
);
748 SCTAB
ScDocShell::MakeScenario( SCTAB nTab
, const OUString
& rName
, const OUString
& rComment
,
749 const Color
& rColor
, sal_uInt16 nFlags
,
750 ScMarkData
& rMark
, bool bRecord
)
753 if (rMark
.IsMultiMarked())
755 SCTAB nNewTab
= nTab
+ 1;
756 while (aDocument
.IsScenario(nNewTab
))
759 bool bCopyAll
= ( (nFlags
& SC_SCENARIO_COPYALL
) != 0 );
760 const ScMarkData
* pCopyMark
= NULL
;
764 ScDocShellModificator
aModificator( *this );
767 aDocument
.BeginDrawUndo(); // drawing layer must do its own undo actions
769 if (aDocument
.CopyTab( nTab
, nNewTab
, pCopyMark
))
773 GetUndoManager()->AddUndoAction(
774 new ScUndoMakeScenario( this, nTab
, nNewTab
,
775 rName
, rComment
, rColor
, nFlags
, rMark
));
778 aDocument
.RenameTab( nNewTab
, rName
, false ); // ohne Formel-Update
779 aDocument
.SetScenario( nNewTab
, true );
780 aDocument
.SetScenarioData( nNewTab
, rComment
, rColor
, nFlags
);
782 ScMarkData aDestMark
= rMark
;
783 aDestMark
.SelectOneTable( nNewTab
);
785 //! auf Filter / Buttons / Merging testen !
787 ScPatternAttr
aProtPattern( aDocument
.GetPool() );
788 aProtPattern
.GetItemSet().Put( ScProtectionAttr( true ) );
789 aDocument
.ApplyPatternAreaTab( 0,0, MAXCOL
,MAXROW
, nNewTab
, aProtPattern
);
791 ScPatternAttr
aPattern( aDocument
.GetPool() );
792 aPattern
.GetItemSet().Put( ScMergeFlagAttr( SC_MF_SCENARIO
) );
793 aPattern
.GetItemSet().Put( ScProtectionAttr( true ) );
794 aDocument
.ApplySelectionPattern( aPattern
, aDestMark
);
797 aDocument
.SetVisible( nNewTab
, false );
799 // dies ist dann das aktive Szenario
800 aDocument
.CopyScenario( nNewTab
, nTab
, true ); // sal_True - nicht aus Szenario kopieren
802 if (nFlags
& SC_SCENARIO_SHOWFRAME
)
803 PostPaint( 0,0,nTab
, MAXCOL
,MAXROW
,nTab
, PAINT_GRID
); // Rahmen painten
804 PostPaintExtras(); // Tabellenreiter
805 aModificator
.SetDocumentModified();
807 SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
815 sal_uLong
ScDocShell::TransferTab( ScDocShell
& rSrcDocShell
, SCTAB nSrcPos
,
816 SCTAB nDestPos
, bool bInsertNew
,
817 bool bNotifyAndPaint
)
819 ScDocument
& rSrcDoc
= rSrcDocShell
.GetDocument();
821 // set the transferred area to the copyparam to make adjusting formulas possible
823 ScRange
aRange(0, 0, nSrcPos
, MAXCOL
, MAXROW
, nSrcPos
);
824 aParam
.maRanges
.Append(aRange
);
825 rSrcDoc
.SetClipParam(aParam
);
827 sal_uLong nErrVal
= aDocument
.TransferTab( &rSrcDoc
, nSrcPos
, nDestPos
,
828 bInsertNew
); // no insert
830 // TransferTab doesn't copy drawing objects with bInsertNew=FALSE
831 if ( nErrVal
> 0 && !bInsertNew
)
832 aDocument
.TransferDrawPage( &rSrcDoc
, nSrcPos
, nDestPos
);
834 if(nErrVal
>0 && rSrcDoc
.IsScenario( nSrcPos
))
840 rSrcDoc
.GetScenarioData( nSrcPos
, aComment
,aColor
, nFlags
);
841 aDocument
.SetScenario(nDestPos
,true);
842 aDocument
.SetScenarioData(nDestPos
,aComment
,aColor
,nFlags
);
843 bool bActive
= rSrcDoc
.IsActiveScenario(nSrcPos
);
844 aDocument
.SetActiveScenario(nDestPos
, bActive
);
846 bool bVisible
= rSrcDoc
.IsVisible(nSrcPos
);
847 aDocument
.SetVisible(nDestPos
,bVisible
);
851 if ( nErrVal
> 0 && rSrcDoc
.IsTabProtected( nSrcPos
) )
852 aDocument
.SetTabProtection(nDestPos
, rSrcDoc
.GetTabProtection(nSrcPos
));
853 if ( bNotifyAndPaint
)
855 Broadcast( ScTablesHint( SC_TAB_INSERTED
, nDestPos
) );
862 bool ScDocShell::MoveTable( SCTAB nSrcTab
, SCTAB nDestTab
, bool bCopy
, bool bRecord
)
864 ScDocShellModificator
aModificator( *this );
866 // #i92477# be consistent with ScDocFunc::InsertTable: any index past the last sheet means "append"
867 // #i101139# nDestTab must be the target position, not APPEND (for CopyTabProtection etc.)
868 if ( nDestTab
>= aDocument
.GetTableCount() )
869 nDestTab
= aDocument
.GetTableCount();
874 aDocument
.BeginDrawUndo(); // drawing layer must do its own undo actions
876 OUString sSrcCodeName
;
877 aDocument
.GetCodeName( nSrcTab
, sSrcCodeName
);
878 if (!aDocument
.CopyTab( nSrcTab
, nDestTab
))
885 SCTAB nAdjSource
= nSrcTab
;
886 if ( nDestTab
<= nSrcTab
)
887 ++nAdjSource
; // new position of source table after CopyTab
889 if ( aDocument
.IsTabProtected( nAdjSource
) )
890 aDocument
.CopyTabProtection(nAdjSource
, nDestTab
);
894 unique_ptr
< vector
<SCTAB
> > pSrcList(new vector
<SCTAB
>(1, nSrcTab
));
895 unique_ptr
< vector
<SCTAB
> > pDestList(new vector
<SCTAB
>(1, nDestTab
));
896 GetUndoManager()->AddUndoAction(
897 new ScUndoCopyTab(this, pSrcList
.release(), pDestList
.release()));
900 bool bVbaEnabled
= aDocument
.IsInVBAMode();
903 OUString
aLibName( "Standard" );
904 Reference
< XLibraryContainer
> xLibContainer
= GetBasicContainer();
905 Reference
< XVBACompatibility
> xVBACompat( xLibContainer
, UNO_QUERY
);
907 if ( xVBACompat
.is() )
909 aLibName
= xVBACompat
->getProjectName();
912 SCTAB nTabToUse
= nDestTab
;
913 if ( nDestTab
== SC_TAB_APPEND
)
914 nTabToUse
= aDocument
.GetMaxTableNumber() - 1;
919 Reference
< XNameContainer
> xLib
;
920 if( xLibContainer
.is() )
922 com::sun::star::uno::Any aLibAny
= xLibContainer
->getByName( aLibName
);
927 xLib
->getByName( sSrcCodeName
) >>= sSource
;
930 catch ( const com::sun::star::uno::Exception
& )
933 VBA_InsertModule( aDocument
, nTabToUse
, sCodeName
, sSource
);
936 Broadcast( ScTablesHint( SC_TAB_COPIED
, nSrcTab
, nDestTab
) );
940 if ( aDocument
.GetChangeTrack() )
943 if ( nSrcTab
<nDestTab
&& nDestTab
!=SC_TAB_APPEND
)
946 if ( nSrcTab
== nDestTab
)
948 //! allow only for api calls?
949 return true; // nothing to do, but valid
952 ScProgress
* pProgress
= new ScProgress(this, ScGlobal::GetRscString(STR_UNDO_MOVE_TAB
),
953 aDocument
.GetCodeCount());
954 bool bDone
= aDocument
.MoveTab( nSrcTab
, nDestTab
, pProgress
);
962 unique_ptr
< vector
<SCTAB
> > pSrcList(new vector
<SCTAB
>(1, nSrcTab
));
963 unique_ptr
< vector
<SCTAB
> > pDestList(new vector
<SCTAB
>(1, nDestTab
));
964 GetUndoManager()->AddUndoAction(
965 new ScUndoMoveTab(this, pSrcList
.release(), pDestList
.release()));
968 Broadcast( ScTablesHint( SC_TAB_MOVED
, nSrcTab
, nDestTab
) );
973 aModificator
.SetDocumentModified();
974 SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
979 IMPL_LINK_TYPED( ScDocShell
, RefreshDBDataHdl
, Timer
*, pRefreshTimer
, void )
981 ScDBDocFunc
aFunc(*this);
983 ScDBData
* pDBData
= static_cast<ScDBData
*>(pRefreshTimer
);
984 ScImportParam aImportParam
;
985 pDBData
->GetImportParam( aImportParam
);
986 if (aImportParam
.bImport
&& !pDBData
->HasImportSelection())
989 pDBData
->GetArea( aRange
);
990 bool bContinue
= aFunc
.DoImport( aRange
.aStart
.Tab(), aImportParam
, NULL
, true, false ); //! Api-Flag as parameter
991 // internal operations (sort, query, subtotal) only if no error
994 aFunc
.RepeatDB( pDBData
->GetName(), true, true );
995 RefreshPivotTables(aRange
);
1000 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */