1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "scitems.hxx"
21 #include <vcl/msgbox.hxx>
22 #include <vcl/waitobj.hxx>
23 #include <sfx2/app.hxx>
24 #include <sfx2/bindings.hxx>
26 #include <com/sun/star/script/vba/XVBACompatibility.hpp>
30 #include "globstr.hrc"
31 #include "globalnames.hxx"
32 #include "undodat.hxx"
33 #include "undotab.hxx"
34 #include "undoblk.hxx"
35 #include "dpobject.hxx"
36 #include "dpshttab.hxx"
37 #include "dbdocfun.hxx"
38 #include "consoli.hxx"
40 #include "progress.hxx"
41 #include "olinetab.hxx"
42 #include "patattr.hxx"
44 #include "docpool.hxx"
45 #include "uiitems.hxx"
47 #include "waitoff.hxx"
48 #include "sizedev.hxx"
49 #include "clipparam.hxx"
51 // defined in docfunc.cxx
52 void VBA_InsertModule( ScDocument
& rDoc
, SCTAB nTab
, const OUString
& sModuleName
, const OUString
& sModuleSource
);
54 using com::sun::star::script::XLibraryContainer
;
55 using com::sun::star::script::vba::XVBACompatibility
;
56 using com::sun::star::container::XNameContainer
;
57 using com::sun::star::uno::Reference
;
58 using com::sun::star::uno::UNO_QUERY
;
60 using ::std::auto_ptr
;
63 // ---------------------------------------------------------------------------
66 // former viewfunc/dbfunc methods
69 void ScDocShell::ErrorMessage( sal_uInt16 nGlobStrId
)
71 //! StopMarking an der (aktiven) View?
73 Window
* pParent
= GetActiveDialogParent();
74 ScWaitCursorOff
aWaitOff( pParent
);
75 sal_Bool bFocus
= pParent
&& pParent
->HasFocus();
77 if(nGlobStrId
==STR_PROTECTIONERR
)
81 nGlobStrId
=STR_READONLYERR
;
85 InfoBox
aBox( pParent
, ScGlobal::GetRscString( nGlobStrId
) );
91 sal_Bool
ScDocShell::IsEditable() const
93 // import into read-only document is possible - must be extended if other filters use api
94 // #i108547# MSOOXML filter uses "IsChangeReadOnlyEnabled" property
96 return !IsReadOnly() || aDocument
.IsImportingXML() || aDocument
.IsChangeReadOnlyEnabled();
99 void ScDocShell::DBAreaDeleted( SCTAB nTab
, SCCOL nX1
, SCROW nY1
, SCCOL nX2
, SCROW
/* nY2 */ )
101 ScDocShellModificator
aModificator( *this );
102 aDocument
.RemoveFlagsTab( nX1
, nY1
, nX2
, nY1
, nTab
, SC_MF_AUTO
);
103 PostPaint( nX1
, nY1
, nTab
, nX2
, nY1
, nTab
, PAINT_GRID
);
104 // No SetDocumentModified, as the unnamed database range might have to be restored later.
105 // The UNO hint is broadcast directly instead, to keep UNO objects in valid state.
106 aDocument
.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED
) );
109 ScDBData
* ScDocShell::GetDBData( const ScRange
& rMarked
, ScGetDBMode eMode
, ScGetDBSelection eSel
)
111 SCCOL nCol
= rMarked
.aStart
.Col();
112 SCROW nRow
= rMarked
.aStart
.Row();
113 SCTAB nTab
= rMarked
.aStart
.Tab();
115 SCCOL nStartCol
= nCol
;
116 SCROW nStartRow
= nRow
;
117 SCTAB nStartTab
= nTab
;
118 SCCOL nEndCol
= rMarked
.aEnd
.Col();
119 SCROW nEndRow
= rMarked
.aEnd
.Row();
120 SCTAB nEndTab
= rMarked
.aEnd
.Tab();
121 // Nicht einfach GetDBAtCursor: Der zusammenhaengende Datenbereich
122 // fuer "unbenannt" (GetDataArea) kann neben dem Cursor legen, also muss auch ein
123 // benannter DB-Bereich dort gesucht werden.
124 ScDBCollection
* pColl
= aDocument
.GetDBCollection();
125 ScDBData
* pData
= aDocument
.GetDBAtArea( nTab
, nStartCol
, nStartRow
, nEndCol
, nEndRow
);
127 pData
= pColl
->GetDBNearCursor(nCol
, nRow
, nTab
);
129 sal_Bool bSelected
= ( eSel
== SC_DBSEL_FORCE_MARK
||
130 (rMarked
.aStart
!= rMarked
.aEnd
&& eSel
!= SC_DBSEL_ROW_DOWN
) );
131 bool bOnlyDown
= (!bSelected
&& eSel
== SC_DBSEL_ROW_DOWN
&& rMarked
.aStart
.Row() == rMarked
.aEnd
.Row());
133 sal_Bool bUseThis
= false;
136 // Bereich nehmen, wenn nichts anderes markiert
143 pData
->GetArea( nDummy
, nOldCol1
,nOldRow1
, nOldCol2
,nOldRow2
);
144 sal_Bool bIsNoName
= ( pData
->GetName() == STR_DB_LOCAL_NONAME
);
149 if ( bIsNoName
&& eMode
== SC_DB_MAKE
)
151 // If nothing marked or only one row marked, adapt
152 // "unbenannt"/"unnamed" to contiguous area.
157 nEndCol
= rMarked
.aEnd
.Col();
158 nEndRow
= rMarked
.aEnd
.Row();
165 aDocument
.GetDataArea( nTab
, nStartCol
, nStartRow
, nEndCol
, nEndRow
, false, bOnlyDown
);
166 if ( nOldCol1
!= nStartCol
|| nOldCol2
!= nEndCol
|| nOldRow1
!= nStartRow
)
167 bUseThis
= false; // passt gar nicht
168 else if ( nOldRow2
!= nEndRow
)
170 // Bereich auf neue End-Zeile erweitern
171 pData
->SetArea( nTab
, nOldCol1
,nOldRow1
, nOldCol2
,nEndRow
);
177 if ( nOldCol1
== nStartCol
&& nOldRow1
== nStartRow
&&
178 nOldCol2
== nEndCol
&& nOldRow2
== nEndRow
) // genau markiert?
181 bUseThis
= false; // immer Markierung nehmen (Bug 11964)
184 // fuer Import nie "unbenannt" nehmen
186 if ( bUseThis
&& eMode
== SC_DB_IMPORT
&& bIsNoName
)
192 pData
->GetArea( nStartTab
, nStartCol
,nStartRow
, nEndCol
,nEndRow
);
195 else if ( eMode
== SC_DB_OLD
)
197 pData
= NULL
; // nichts gefunden
198 nStartCol
= nEndCol
= nCol
;
199 nStartRow
= nEndRow
= nRow
;
200 nStartTab
= nEndTab
= nTab
;
205 { // zusammenhaengender Bereich
210 nEndCol
= rMarked
.aEnd
.Col();
211 nEndRow
= rMarked
.aEnd
.Row();
218 aDocument
.GetDataArea( nTab
, nStartCol
, nStartRow
, nEndCol
, nEndRow
, false, bOnlyDown
);
221 sal_Bool bHasHeader
= aDocument
.HasColHeader( nStartCol
,nStartRow
, nEndCol
,nEndRow
, nTab
);
223 ScDBData
* pNoNameData
= aDocument
.GetAnonymousDBData(nTab
);
224 if ( eMode
!= SC_DB_IMPORT
&& pNoNameData
)
227 if ( !pOldAutoDBRange
)
229 // store the old unnamed database range with its settings for undo
230 // (store at the first change, get the state before all changes)
231 pOldAutoDBRange
= new ScDBData( *pNoNameData
);
234 SCCOL nOldX1
; // alten Bereich sauber wegnehmen
235 SCROW nOldY1
; //! (UNDO ???)
239 pNoNameData
->GetArea( nOldTab
, nOldX1
, nOldY1
, nOldX2
, nOldY2
);
240 DBAreaDeleted( nOldTab
, nOldX1
, nOldY1
, nOldX2
, nOldY2
);
242 pNoNameData
->SetSortParam( ScSortParam() ); // Parameter zuruecksetzen
243 pNoNameData
->SetQueryParam( ScQueryParam() );
244 pNoNameData
->SetSubTotalParam( ScSubTotalParam() );
246 pNoNameData
->SetArea( nTab
, nStartCol
,nStartRow
, nEndCol
,nEndRow
); // neu setzen
247 pNoNameData
->SetByRow( sal_True
);
248 pNoNameData
->SetHeader( bHasHeader
);
249 pNoNameData
->SetAutoFilter( false );
253 ScDBCollection
* pUndoColl
= NULL
;
256 if (eMode
==SC_DB_IMPORT
)
258 aDocument
.CompileDBFormula( sal_True
); // CreateFormulaString
259 pUndoColl
= new ScDBCollection( *pColl
); // Undo fuer Import1-Bereich
261 OUString aImport
= ScGlobal::GetRscString( STR_DBNAME_IMPORT
);
263 const ScDBData
* pDummy
= NULL
;
264 ScDBCollection::NamedDBs
& rDBs
= pColl
->getNamedDBs();
269 aNewName
+= OUString::number( nCount
);
270 pDummy
= rDBs
.findByUpperName(ScGlobal::pCharClass
->uppercase(aNewName
));
273 pNoNameData
= new ScDBData( aNewName
, nTab
,
274 nStartCol
,nStartRow
, nEndCol
,nEndRow
,
275 sal_True
, bHasHeader
);
276 rDBs
.insert(pNoNameData
);
280 aNewName
= OUString(STR_DB_LOCAL_NONAME
);
281 pNoNameData
= new ScDBData(aNewName
, nTab
,
282 nStartCol
,nStartRow
, nEndCol
,nEndRow
,
283 sal_True
, bHasHeader
);
284 aDocument
.SetAnonymousDBData(nTab
, pNoNameData
);
291 aDocument
.CompileDBFormula( false ); // CompileFormulaString
293 ScDBCollection
* pRedoColl
= new ScDBCollection( *pColl
);
294 GetUndoManager()->AddUndoAction( new ScUndoDBData( this, pUndoColl
, pRedoColl
) );
297 // neuen Bereich am Sba anmelden nicht mehr noetig
299 // "Import1" etc am Navigator bekanntmachen
300 if (eMode
==SC_DB_IMPORT
)
301 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED
) );
309 ScDBData
* ScDocShell::GetAnonymousDBData(const ScRange
& rRange
)
311 bool bHasHeader
= aDocument
.HasColHeader(
312 rRange
.aStart
.Col(), rRange
.aStart
.Row(), rRange
.aEnd
.Col(), rRange
.aEnd
.Row(), rRange
.aStart
.Tab());
314 ScDBCollection
* pColl
= aDocument
.GetDBCollection();
318 ScDBData
* pData
= pColl
->getAnonDBs().getByRange(rRange
);
322 pData
->SetHeader(bHasHeader
);
326 ScDBData
* ScDocShell::GetOldAutoDBRange()
328 ScDBData
* pRet
= pOldAutoDBRange
;
329 pOldAutoDBRange
= NULL
;
330 return pRet
; // has to be deleted by caller!
333 void ScDocShell::CancelAutoDBRange()
335 // called when dialog is cancelled
337 if ( pOldAutoDBRange
)
339 SCTAB nTab
= GetCurTab();
340 ScDBData
* pDBData
= aDocument
.GetAnonymousDBData(nTab
);
348 pDBData
->GetArea( nRangeTab
, nRangeX1
, nRangeY1
, nRangeX2
, nRangeY2
);
349 DBAreaDeleted( nRangeTab
, nRangeX1
, nRangeY1
, nRangeX2
, nRangeY2
);
351 *pDBData
= *pOldAutoDBRange
; // restore old settings
353 if ( pOldAutoDBRange
->HasAutoFilter() )
355 // restore AutoFilter buttons
356 pOldAutoDBRange
->GetArea( nRangeTab
, nRangeX1
, nRangeY1
, nRangeX2
, nRangeY2
);
357 aDocument
.ApplyFlagsTab( nRangeX1
, nRangeY1
, nRangeX2
, nRangeY1
, nRangeTab
, SC_MF_AUTO
);
358 PostPaint( nRangeX1
, nRangeY1
, nRangeTab
, nRangeX2
, nRangeY1
, nRangeTab
, PAINT_GRID
);
362 delete pOldAutoDBRange
;
363 pOldAutoDBRange
= NULL
;
369 //! mit docfunc zusammenfassen
371 sal_Bool
ScDocShell::AdjustRowHeight( SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
)
373 ScSizeDeviceProvider
aProv(this);
375 sal_Bool bChange
= aDocument
.SetOptimalHeight( nStartRow
,nEndRow
, nTab
, 0, aProv
.GetDevice(),
376 aProv
.GetPPTX(),aProv
.GetPPTY(), aZoom
,aZoom
, false );
378 PostPaint( 0,nStartRow
,nTab
, MAXCOL
,MAXROW
,nTab
, PAINT_GRID
|PAINT_LEFT
);
383 void ScDocShell::UpdateAllRowHeights( const ScMarkData
* pTabMark
)
385 // update automatic row heights
387 ScSizeDeviceProvider
aProv(this);
389 aDocument
.UpdateAllRowHeights( aProv
.GetDevice(), aProv
.GetPPTX(), aProv
.GetPPTY(), aZoom
, aZoom
, pTabMark
);
392 void ScDocShell::UpdatePendingRowHeights( SCTAB nUpdateTab
, bool bBefore
)
394 sal_Bool bIsUndoEnabled
= aDocument
.IsUndoEnabled();
395 aDocument
.EnableUndo( false );
396 aDocument
.LockStreamValid( true ); // ignore draw page size (but not formula results)
397 if ( bBefore
) // check all sheets up to nUpdateTab
399 SCTAB nTabCount
= aDocument
.GetTableCount();
400 if ( nUpdateTab
>= nTabCount
)
401 nUpdateTab
= nTabCount
-1; // nUpdateTab is inclusive
403 ScMarkData aUpdateSheets
;
405 for (nTab
=0; nTab
<=nUpdateTab
; ++nTab
)
406 if ( aDocument
.IsPendingRowHeights( nTab
) )
407 aUpdateSheets
.SelectTable( nTab
, sal_True
);
409 if (aUpdateSheets
.GetSelectCount())
410 UpdateAllRowHeights(&aUpdateSheets
); // update with a single progress bar
412 for (nTab
=0; nTab
<=nUpdateTab
; ++nTab
)
413 if ( aUpdateSheets
.GetTableSelect( nTab
) )
415 aDocument
.UpdatePageBreaks( nTab
);
416 aDocument
.SetPendingRowHeights( nTab
, false );
419 else // only nUpdateTab
421 if ( aDocument
.IsPendingRowHeights( nUpdateTab
) )
423 AdjustRowHeight( 0, MAXROW
, nUpdateTab
);
424 aDocument
.UpdatePageBreaks( nUpdateTab
);
425 aDocument
.SetPendingRowHeights( nUpdateTab
, false );
428 aDocument
.LockStreamValid( false );
429 aDocument
.EnableUndo( bIsUndoEnabled
);
432 void ScDocShell::RefreshPivotTables( const ScRange
& rSource
)
434 ScDPCollection
* pColl
= aDocument
.GetDPCollection();
438 ScDBDocFunc
aFunc(*this);
439 for (size_t i
= 0, n
= pColl
->GetCount(); i
< n
; ++i
)
441 ScDPObject
* pOld
= (*pColl
)[i
];
445 const ScSheetSourceDesc
* pSheetDesc
= pOld
->GetSheetDesc();
446 if (pSheetDesc
&& pSheetDesc
->GetSourceRange().Intersects(rSource
))
447 aFunc
.UpdatePivotTable(*pOld
, true, false);
451 static OUString
lcl_GetAreaName( ScDocument
* pDoc
, ScArea
* pArea
)
454 sal_Bool bOk
= false;
455 ScDBData
* pData
= pDoc
->GetDBAtArea( pArea
->nTab
, pArea
->nColStart
, pArea
->nRowStart
,
456 pArea
->nColEnd
, pArea
->nRowEnd
);
459 aName
= pData
->GetName();
464 pDoc
->GetName( pArea
->nTab
, aName
);
469 void ScDocShell::DoConsolidate( const ScConsolidateParam
& rParam
, sal_Bool bRecord
)
476 sal_Bool bErr
= false;
477 for (nPos
=0; nPos
<rParam
.nDataAreaCount
; nPos
++)
479 ScArea
* pArea
= rParam
.ppDataAreas
[nPos
];
480 nColSize
= std::max( nColSize
, SCCOL( pArea
->nColEnd
- pArea
->nColStart
+ 1 ) );
481 nRowSize
= std::max( nRowSize
, SCROW( pArea
->nRowEnd
- pArea
->nRowStart
+ 1 ) );
483 // Test, ob Quelldaten verschoben wuerden
484 if (rParam
.bReferenceData
)
485 if (pArea
->nTab
== rParam
.nTab
&& pArea
->nRowEnd
>= rParam
.nRow
)
491 InfoBox
aBox( GetActiveDialogParent(),
492 ScGlobal::GetRscString( STR_CONSOLIDATE_ERR1
) );
499 WaitObject
aWait( GetActiveDialogParent() );
500 ScDocShellModificator
aModificator( *this );
503 ScDBData
* pDestData
= aDocument
.GetDBAtCursor( rParam
.nCol
, rParam
.nRow
, rParam
.nTab
, true );
505 pDestData
->GetArea(aOldDest
);
507 aData
.SetSize( nColSize
, nRowSize
);
508 aData
.SetFlags( rParam
.eFunction
, rParam
.bByCol
, rParam
.bByRow
, rParam
.bReferenceData
);
509 if ( rParam
.bByCol
|| rParam
.bByRow
)
510 for (nPos
=0; nPos
<rParam
.nDataAreaCount
; nPos
++)
512 ScArea
* pArea
= rParam
.ppDataAreas
[nPos
];
513 aData
.AddFields( &aDocument
, pArea
->nTab
, pArea
->nColStart
, pArea
->nRowStart
,
514 pArea
->nColEnd
, pArea
->nRowEnd
);
517 for (nPos
=0; nPos
<rParam
.nDataAreaCount
; nPos
++)
519 ScArea
* pArea
= rParam
.ppDataAreas
[nPos
];
520 aData
.AddData( &aDocument
, pArea
->nTab
, pArea
->nColStart
, pArea
->nRowStart
,
521 pArea
->nColEnd
, pArea
->nRowEnd
);
522 aData
.AddName( lcl_GetAreaName(&aDocument
,pArea
) );
525 aData
.GetSize( nColSize
, nRowSize
);
526 if (bRecord
&& nColSize
> 0 && nRowSize
> 0)
528 ScDBData
* pUndoData
= pDestData
? new ScDBData(*pDestData
) : NULL
;
530 SCTAB nDestTab
= rParam
.nTab
;
531 ScArea
aDestArea( rParam
.nTab
, rParam
.nCol
, rParam
.nRow
,
532 rParam
.nCol
+nColSize
-1, rParam
.nRow
+nRowSize
-1 );
533 if (rParam
.bByCol
) ++aDestArea
.nColEnd
;
534 if (rParam
.bByRow
) ++aDestArea
.nRowEnd
;
536 if (rParam
.bReferenceData
)
538 SCTAB nTabCount
= aDocument
.GetTableCount();
539 SCROW nInsertCount
= aData
.GetInsertCount();
542 ScOutlineTable
* pTable
= aDocument
.GetOutlineTable( nDestTab
);
543 ScOutlineTable
* pUndoTab
= pTable
? new ScOutlineTable( *pTable
) : NULL
;
545 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
546 pUndoDoc
->InitUndo( &aDocument
, 0, nTabCount
-1, false, sal_True
);
549 aDocument
.CopyToDocument( 0,0,nDestTab
, MAXCOL
,MAXROW
,nDestTab
,
550 IDF_NONE
, false, pUndoDoc
);
553 aDocument
.CopyToDocument( 0,0,0, MAXCOL
,MAXROW
,nTabCount
-1,
554 IDF_FORMULA
, false, pUndoDoc
);
556 // komplette Ausgangszeilen
557 aDocument
.CopyToDocument( 0,aDestArea
.nRowStart
,nDestTab
,
558 MAXCOL
,aDestArea
.nRowEnd
,nDestTab
,
559 IDF_ALL
, false, pUndoDoc
);
561 // alten Ausgabebereich
563 aDocument
.CopyToDocument( aOldDest
, IDF_ALL
, false, pUndoDoc
);
565 GetUndoManager()->AddUndoAction(
566 new ScUndoConsolidate( this, aDestArea
, rParam
, pUndoDoc
,
567 sal_True
, nInsertCount
, pUndoTab
, pUndoData
) );
571 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
572 pUndoDoc
->InitUndo( &aDocument
, aDestArea
.nTab
, aDestArea
.nTab
);
574 aDocument
.CopyToDocument( aDestArea
.nColStart
, aDestArea
.nRowStart
, aDestArea
.nTab
,
575 aDestArea
.nColEnd
, aDestArea
.nRowEnd
, aDestArea
.nTab
,
576 IDF_ALL
, false, pUndoDoc
);
578 // alten Ausgabebereich
580 aDocument
.CopyToDocument( aOldDest
, IDF_ALL
, false, pUndoDoc
);
582 GetUndoManager()->AddUndoAction(
583 new ScUndoConsolidate( this, aDestArea
, rParam
, pUndoDoc
,
584 false, 0, NULL
, pUndoData
) );
588 if (pDestData
) // Zielbereich loeschen / anpassen
590 aDocument
.DeleteAreaTab(aOldDest
, IDF_CONTENTS
);
591 pDestData
->SetArea( rParam
.nTab
, rParam
.nCol
, rParam
.nRow
,
592 rParam
.nCol
+ nColSize
- 1, rParam
.nRow
+ nRowSize
- 1 );
593 pDestData
->SetHeader( rParam
.bByRow
);
596 aData
.OutputToDocument( &aDocument
, rParam
.nCol
, rParam
.nRow
, rParam
.nTab
);
598 SCCOL nPaintStartCol
= rParam
.nCol
;
599 SCROW nPaintStartRow
= rParam
.nRow
;
600 SCCOL nPaintEndCol
= nPaintStartCol
+ nColSize
- 1;
601 SCROW nPaintEndRow
= nPaintStartRow
+ nRowSize
- 1;
602 sal_uInt16 nPaintFlags
= PAINT_GRID
;
607 if (rParam
.bReferenceData
)
610 nPaintEndCol
= MAXCOL
;
611 nPaintEndRow
= MAXROW
;
612 nPaintFlags
|= PAINT_LEFT
| PAINT_SIZE
;
616 if ( aOldDest
.aEnd
.Col() > nPaintEndCol
)
617 nPaintEndCol
= aOldDest
.aEnd
.Col();
618 if ( aOldDest
.aEnd
.Row() > nPaintEndRow
)
619 nPaintEndRow
= aOldDest
.aEnd
.Row();
621 PostPaint( nPaintStartCol
, nPaintStartRow
, rParam
.nTab
,
622 nPaintEndCol
, nPaintEndRow
, rParam
.nTab
, nPaintFlags
);
623 aModificator
.SetDocumentModified();
626 void ScDocShell::UseScenario( SCTAB nTab
, const OUString
& rName
, sal_Bool bRecord
)
628 if (!aDocument
.IsScenario(nTab
))
630 SCTAB nTabCount
= aDocument
.GetTableCount();
631 SCTAB nSrcTab
= SCTAB_MAX
;
632 SCTAB nEndTab
= nTab
;
634 while ( nEndTab
+1 < nTabCount
&& aDocument
.IsScenario(nEndTab
+1) )
637 if (nSrcTab
> MAXTAB
) // noch auf der Suche nach dem Szenario?
639 aDocument
.GetName( nEndTab
, aCompare
);
640 if (aCompare
.equals(rName
))
641 nSrcTab
= nEndTab
; // gefunden
644 if (ValidTab(nSrcTab
))
646 if ( aDocument
.TestCopyScenario( nSrcTab
, nTab
) ) // Zellschutz testen
648 ScDocShellModificator
aModificator( *this );
649 ScMarkData aScenMark
;
650 aDocument
.MarkScenario( nSrcTab
, nTab
, aScenMark
);
652 aScenMark
.GetMultiMarkArea( aMultiRange
);
653 SCCOL nStartCol
= aMultiRange
.aStart
.Col();
654 SCROW nStartRow
= aMultiRange
.aStart
.Row();
655 SCCOL nEndCol
= aMultiRange
.aEnd
.Col();
656 SCROW nEndRow
= aMultiRange
.aEnd
.Row();
660 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
661 pUndoDoc
->InitUndo( &aDocument
, nTab
,nEndTab
); // auch alle Szenarien
662 // angezeigte Tabelle:
663 aDocument
.CopyToDocument( nStartCol
,nStartRow
,nTab
,
664 nEndCol
,nEndRow
,nTab
, IDF_ALL
,sal_True
, pUndoDoc
, &aScenMark
);
666 for (SCTAB i
=nTab
+1; i
<=nEndTab
; i
++)
668 pUndoDoc
->SetScenario( i
, sal_True
);
671 sal_uInt16 nScenFlags
;
672 aDocument
.GetScenarioData( i
, aComment
, aColor
, nScenFlags
);
673 pUndoDoc
->SetScenarioData( i
, aComment
, aColor
, nScenFlags
);
674 sal_Bool bActive
= aDocument
.IsActiveScenario( i
);
675 pUndoDoc
->SetActiveScenario( i
, bActive
);
676 // Bei Zurueckkopier-Szenarios auch Inhalte
677 if ( nScenFlags
& SC_SCENARIO_TWOWAY
)
678 aDocument
.CopyToDocument( 0,0,i
, MAXCOL
,MAXROW
,i
,
679 IDF_ALL
,false, pUndoDoc
);
682 GetUndoManager()->AddUndoAction(
683 new ScUndoUseScenario( this, aScenMark
,
684 ScArea( nTab
,nStartCol
,nStartRow
,nEndCol
,nEndRow
),
688 aDocument
.CopyScenario( nSrcTab
, nTab
);
689 aDocument
.SetDirty();
691 // alles painten, weil in anderen Bereichen das aktive Szenario
692 // geaendert sein kann
693 //! nur, wenn sichtbare Rahmen vorhanden?
694 PostPaint( 0,0,nTab
, MAXCOL
,MAXROW
,nTab
, PAINT_GRID
);
695 aModificator
.SetDocumentModified();
699 InfoBox
aBox(GetActiveDialogParent(),
700 ScGlobal::GetRscString( STR_PROTECTIONERR
) );
706 InfoBox
aBox(GetActiveDialogParent(),
707 ScGlobal::GetRscString( STR_SCENARIO_NOTFOUND
) );
713 OSL_FAIL( "UseScenario auf Szenario-Blatt" );
717 void ScDocShell::ModifyScenario( SCTAB nTab
, const OUString
& rName
, const OUString
& rComment
,
718 const Color
& rColor
, sal_uInt16 nFlags
)
722 aDocument
.GetName( nTab
, aOldName
);
723 OUString aOldComment
;
725 sal_uInt16 nOldFlags
;
726 aDocument
.GetScenarioData( nTab
, aOldComment
, aOldColor
, nOldFlags
);
727 GetUndoManager()->AddUndoAction(
728 new ScUndoScenarioFlags( this, nTab
,
729 aOldName
, rName
, aOldComment
, rComment
,
730 aOldColor
, rColor
, nOldFlags
, nFlags
) );
733 ScDocShellModificator
aModificator( *this );
734 aDocument
.RenameTab( nTab
, rName
);
735 aDocument
.SetScenarioData( nTab
, rComment
, rColor
, nFlags
);
737 aModificator
.SetDocumentModified();
739 if (!aOldName
.equals(rName
))
740 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
742 SfxBindings
* pBindings
= GetViewBindings();
744 pBindings
->Invalidate( SID_SELECT_SCENARIO
);
747 SCTAB
ScDocShell::MakeScenario( SCTAB nTab
, const OUString
& rName
, const OUString
& rComment
,
748 const Color
& rColor
, sal_uInt16 nFlags
,
749 ScMarkData
& rMark
, sal_Bool bRecord
)
752 if (rMark
.IsMultiMarked())
754 SCTAB nNewTab
= nTab
+ 1;
755 while (aDocument
.IsScenario(nNewTab
))
758 sal_Bool bCopyAll
= ( (nFlags
& SC_SCENARIO_COPYALL
) != 0 );
759 const ScMarkData
* pCopyMark
= NULL
;
763 ScDocShellModificator
aModificator( *this );
766 aDocument
.BeginDrawUndo(); // drawing layer must do its own undo actions
768 if (aDocument
.CopyTab( nTab
, nNewTab
, pCopyMark
))
772 GetUndoManager()->AddUndoAction(
773 new ScUndoMakeScenario( this, nTab
, nNewTab
,
774 rName
, rComment
, rColor
, nFlags
, rMark
));
777 aDocument
.RenameTab( nNewTab
, rName
, false ); // ohne Formel-Update
778 aDocument
.SetScenario( nNewTab
, sal_True
);
779 aDocument
.SetScenarioData( nNewTab
, rComment
, rColor
, nFlags
);
781 ScMarkData aDestMark
= rMark
;
782 aDestMark
.SelectOneTable( nNewTab
);
784 //! auf Filter / Buttons / Merging testen !
786 ScPatternAttr
aProtPattern( aDocument
.GetPool() );
787 aProtPattern
.GetItemSet().Put( ScProtectionAttr( sal_True
) );
788 aDocument
.ApplyPatternAreaTab( 0,0, MAXCOL
,MAXROW
, nNewTab
, aProtPattern
);
790 ScPatternAttr
aPattern( aDocument
.GetPool() );
791 aPattern
.GetItemSet().Put( ScMergeFlagAttr( SC_MF_SCENARIO
) );
792 aPattern
.GetItemSet().Put( ScProtectionAttr( sal_True
) );
793 aDocument
.ApplySelectionPattern( aPattern
, aDestMark
);
796 aDocument
.SetVisible( nNewTab
, false );
798 // dies ist dann das aktive Szenario
799 aDocument
.CopyScenario( nNewTab
, nTab
, sal_True
); // sal_True - nicht aus Szenario kopieren
801 if (nFlags
& SC_SCENARIO_SHOWFRAME
)
802 PostPaint( 0,0,nTab
, MAXCOL
,MAXROW
,nTab
, PAINT_GRID
); // Rahmen painten
803 PostPaintExtras(); // Tabellenreiter
804 aModificator
.SetDocumentModified();
806 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
814 sal_uLong
ScDocShell::TransferTab( ScDocShell
& rSrcDocShell
, SCTAB nSrcPos
,
815 SCTAB nDestPos
, sal_Bool bInsertNew
,
816 sal_Bool bNotifyAndPaint
)
818 ScDocument
* pSrcDoc
= rSrcDocShell
.GetDocument();
820 // set the transferred area to the copyparam to make adjusting formulas possible
822 ScRange
aRange(0, 0, nSrcPos
, MAXCOL
, MAXROW
, nSrcPos
);
823 aParam
.maRanges
.Append(aRange
);
824 pSrcDoc
->SetClipParam(aParam
);
826 sal_uLong nErrVal
= aDocument
.TransferTab( pSrcDoc
, nSrcPos
, nDestPos
,
827 bInsertNew
); // no insert
829 // TransferTab doesn't copy drawing objects with bInsertNew=FALSE
830 if ( nErrVal
> 0 && !bInsertNew
)
831 aDocument
.TransferDrawPage( pSrcDoc
, nSrcPos
, nDestPos
);
833 if(nErrVal
>0 && pSrcDoc
->IsScenario( nSrcPos
))
839 pSrcDoc
->GetScenarioData( nSrcPos
, aComment
,aColor
, nFlags
);
840 aDocument
.SetScenario(nDestPos
,true);
841 aDocument
.SetScenarioData(nDestPos
,aComment
,aColor
,nFlags
);
842 sal_Bool bActive
= pSrcDoc
->IsActiveScenario(nSrcPos
);
843 aDocument
.SetActiveScenario(nDestPos
, bActive
);
845 sal_Bool bVisible
=pSrcDoc
->IsVisible(nSrcPos
);
846 aDocument
.SetVisible(nDestPos
,bVisible
);
850 if ( nErrVal
> 0 && pSrcDoc
->IsTabProtected( nSrcPos
) )
851 aDocument
.SetTabProtection(nDestPos
, pSrcDoc
->GetTabProtection(nSrcPos
));
852 if ( bNotifyAndPaint
)
854 Broadcast( ScTablesHint( SC_TAB_INSERTED
, nDestPos
) );
861 sal_Bool
ScDocShell::MoveTable( SCTAB nSrcTab
, SCTAB nDestTab
, sal_Bool bCopy
, sal_Bool bRecord
)
863 ScDocShellModificator
aModificator( *this );
865 // #i92477# be consistent with ScDocFunc::InsertTable: any index past the last sheet means "append"
866 // #i101139# nDestTab must be the target position, not APPEND (for CopyTabProtection etc.)
867 if ( nDestTab
>= aDocument
.GetTableCount() )
868 nDestTab
= aDocument
.GetTableCount();
873 aDocument
.BeginDrawUndo(); // drawing layer must do its own undo actions
875 OUString sSrcCodeName
;
876 aDocument
.GetCodeName( nSrcTab
, sSrcCodeName
);
877 if (!aDocument
.CopyTab( nSrcTab
, nDestTab
))
884 SCTAB nAdjSource
= nSrcTab
;
885 if ( nDestTab
<= nSrcTab
)
886 ++nAdjSource
; // new position of source table after CopyTab
888 if ( aDocument
.IsTabProtected( nAdjSource
) )
889 aDocument
.CopyTabProtection(nAdjSource
, nDestTab
);
893 SAL_WNODEPRECATED_DECLARATIONS_PUSH
894 auto_ptr
< vector
<SCTAB
> > pSrcList(new vector
<SCTAB
>(1, nSrcTab
));
895 auto_ptr
< vector
<SCTAB
> > pDestList(new vector
<SCTAB
>(1, nDestTab
));
896 SAL_WNODEPRECATED_DECLARATIONS_POP
897 GetUndoManager()->AddUndoAction(
898 new ScUndoCopyTab(this, pSrcList
.release(), pDestList
.release()));
901 sal_Bool bVbaEnabled
= aDocument
.IsInVBAMode();
904 OUString
aLibName( "Standard" );
905 Reference
< XLibraryContainer
> xLibContainer
= GetBasicContainer();
906 Reference
< XVBACompatibility
> xVBACompat( xLibContainer
, UNO_QUERY
);
908 if ( xVBACompat
.is() )
910 aLibName
= xVBACompat
->getProjectName();
913 SCTAB nTabToUse
= nDestTab
;
914 if ( nDestTab
== SC_TAB_APPEND
)
915 nTabToUse
= aDocument
.GetMaxTableNumber() - 1;
920 Reference
< XNameContainer
> xLib
;
921 if( xLibContainer
.is() )
923 com::sun::star::uno::Any aLibAny
= xLibContainer
->getByName( aLibName
);
928 xLib
->getByName( sSrcCodeName
) >>= sSource
;
931 catch ( const com::sun::star::uno::Exception
& )
934 VBA_InsertModule( aDocument
, nTabToUse
, sCodeName
, sSource
);
937 Broadcast( ScTablesHint( SC_TAB_COPIED
, nSrcTab
, nDestTab
) );
941 if ( aDocument
.GetChangeTrack() )
944 if ( nSrcTab
<nDestTab
&& nDestTab
!=SC_TAB_APPEND
)
947 if ( nSrcTab
== nDestTab
)
949 //! allow only for api calls?
950 return sal_True
; // nothing to do, but valid
953 ScProgress
* pProgress
= new ScProgress(this, ScGlobal::GetRscString(STR_UNDO_MOVE_TAB
),
954 aDocument
.GetCodeCount());
955 bool bDone
= aDocument
.MoveTab( nSrcTab
, nDestTab
, pProgress
);
963 SAL_WNODEPRECATED_DECLARATIONS_PUSH
964 auto_ptr
< vector
<SCTAB
> > pSrcList(new vector
<SCTAB
>(1, nSrcTab
));
965 auto_ptr
< vector
<SCTAB
> > pDestList(new vector
<SCTAB
>(1, nDestTab
));
966 SAL_WNODEPRECATED_DECLARATIONS_POP
967 GetUndoManager()->AddUndoAction(
968 new ScUndoMoveTab(this, pSrcList
.release(), pDestList
.release()));
971 Broadcast( ScTablesHint( SC_TAB_MOVED
, nSrcTab
, nDestTab
) );
976 aModificator
.SetDocumentModified();
977 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
983 IMPL_LINK( ScDocShell
, RefreshDBDataHdl
, ScRefreshTimer
*, pRefreshTimer
)
985 ScDBDocFunc
aFunc(*this);
987 sal_Bool bContinue
= sal_True
;
988 ScDBData
* pDBData
= static_cast<ScDBData
*>(pRefreshTimer
);
989 ScImportParam aImportParam
;
990 pDBData
->GetImportParam( aImportParam
);
991 if (aImportParam
.bImport
&& !pDBData
->HasImportSelection())
994 pDBData
->GetArea( aRange
);
995 bContinue
= aFunc
.DoImport( aRange
.aStart
.Tab(), aImportParam
, NULL
, true, false ); //! Api-Flag as parameter
996 // internal operations (sort, query, subtotal) only if no error
999 aFunc
.RepeatDB( pDBData
->GetName(), sal_True
, sal_True
);
1000 RefreshPivotTables(aRange
);
1004 return bContinue
!= 0;
1007 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */