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: docsh5.cxx,v $
10 * $Revision: 1.20.30.2 $
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"
34 // System - Includes -----------------------------------------------------
39 #include "scitems.hxx"
40 #include <vcl/svapp.hxx>
41 #include <vcl/msgbox.hxx>
42 #include <vcl/waitobj.hxx>
43 #include <sfx2/app.hxx>
44 #include <sfx2/bindings.hxx>
45 #include <svtools/smplhint.hxx>
47 #include <com/sun/star/sdbc/XResultSet.hpp>
49 // INCLUDE ---------------------------------------------------------------
53 #include "globstr.hrc"
54 #include "undodat.hxx"
55 #include "undotab.hxx"
56 #include "undoblk.hxx"
57 //#include "pivot.hxx"
58 #include "dpobject.hxx"
59 #include "dpshttab.hxx"
60 #include "dbdocfun.hxx"
61 #include "consoli.hxx"
62 #include "dbcolect.hxx"
63 #include "olinetab.hxx"
64 #include "patattr.hxx"
66 #include "docpool.hxx"
67 #include "uiitems.hxx"
69 #include "waitoff.hxx"
70 #include "sizedev.hxx"
71 #include <basic/sbstar.hxx>
72 #include <basic/basmgr.hxx>
74 // defined in docfunc.cxx
75 void lcl_InsertModule( ScDocShell
& rDocSh
, SCTAB nTab
, String
& sModuleName
, String
& sModuleSource
);
77 // ---------------------------------------------------------------------------
80 // ehemalige viewfunc/dbfunc Methoden
83 void ScDocShell::ErrorMessage( USHORT nGlobStrId
)
85 //! StopMarking an der (aktiven) View?
87 Window
* pParent
= GetActiveDialogParent();
88 ScWaitCursorOff
aWaitOff( pParent
);
89 BOOL bFocus
= pParent
&& pParent
->HasFocus();
91 if(nGlobStrId
==STR_PROTECTIONERR
)
95 nGlobStrId
=STR_READONLYERR
;
99 InfoBox
aBox( pParent
, ScGlobal::GetRscString( nGlobStrId
) );
102 pParent
->GrabFocus();
105 BOOL
ScDocShell::IsEditable() const
107 // import into read-only document is possible - must be extended if other filters use api
109 return !IsReadOnly() || aDocument
.IsImportingXML();
112 void ScDocShell::DBAreaDeleted( SCTAB nTab
, SCCOL nX1
, SCROW nY1
, SCCOL nX2
, SCROW
/* nY2 */ )
114 ScDocShellModificator
aModificator( *this );
115 aDocument
.RemoveFlagsTab( nX1
, nY1
, nX2
, nY1
, nTab
, SC_MF_AUTO
);
116 PostPaint( nX1
, nY1
, nTab
, nX2
, nY1
, nTab
, PAINT_GRID
);
117 // No SetDocumentModified, as the unnamed database range might have to be restored later.
118 // The UNO hint is broadcast directly instead, to keep UNO objects in valid state.
119 aDocument
.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED
) );
122 ScDBData
* lcl_GetDBNearCursor( ScDBCollection
* pColl
, SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
124 //! nach document/dbcolect verschieben
129 ScDBData
* pNoNameData
= NULL
;
130 ScDBData
* pNearData
= NULL
;
131 USHORT nCount
= pColl
->GetCount();
132 String aNoName
= ScGlobal::GetRscString( STR_DB_NONAME
);
134 SCCOL nStartCol
, nEndCol
;
135 SCROW nStartRow
, nEndRow
;
136 for (USHORT i
= 0; i
< nCount
; i
++)
138 ScDBData
* pDB
= (*pColl
)[i
];
139 pDB
->GetArea( nAreaTab
, nStartCol
, nStartRow
, nEndCol
, nEndRow
);
140 if ( nTab
== nAreaTab
&& nCol
+1 >= nStartCol
&& nCol
<= nEndCol
+1 &&
141 nRow
+1 >= nStartRow
&& nRow
<= nEndRow
+1 )
143 if ( pDB
->GetName() == aNoName
)
145 else if ( nCol
< nStartCol
|| nCol
> nEndCol
|| nRow
< nStartRow
|| nRow
> nEndRow
)
148 pNearData
= pDB
; // ersten angrenzenden Bereich merken
151 return pDB
; // nicht "unbenannt" und Cursor steht wirklich drin
155 return pNearData
; // angrenzender, wenn nichts direkt getroffen
156 return pNoNameData
; // "unbenannt" nur zurueck, wenn sonst nichts gefunden
159 ScDBData
* ScDocShell::GetDBData( const ScRange
& rMarked
, ScGetDBMode eMode
, BOOL bForceMark
)
161 SCCOL nCol
= rMarked
.aStart
.Col();
162 SCROW nRow
= rMarked
.aStart
.Row();
163 SCTAB nTab
= rMarked
.aStart
.Tab();
165 SCCOL nStartCol
= nCol
;
166 SCROW nStartRow
= nRow
;
167 SCTAB nStartTab
= nTab
;
168 SCCOL nEndCol
= rMarked
.aEnd
.Col();
169 SCROW nEndRow
= rMarked
.aEnd
.Row();
170 SCTAB nEndTab
= rMarked
.aEnd
.Tab();
172 // Wegen #49655# nicht einfach GetDBAtCursor: Der zusammenhaengende Datenbereich
173 // fuer "unbenannt" (GetDataArea) kann neben dem Cursor legen, also muss auch ein
174 // benannter DB-Bereich dort gesucht werden.
176 ScDBData
* pData
= aDocument
.GetDBAtArea( nTab
, nStartCol
, nStartRow
, nEndCol
, nEndRow
);
178 pData
= lcl_GetDBNearCursor( aDocument
.GetDBCollection(), nCol
, nRow
, nTab
);
180 BOOL bSelected
= ( bForceMark
|| rMarked
.aStart
!= rMarked
.aEnd
);
182 BOOL bUseThis
= FALSE
;
185 // Bereich nehmen, wenn nichts anderes markiert
192 pData
->GetArea( nDummy
, nOldCol1
,nOldRow1
, nOldCol2
,nOldRow2
);
193 BOOL bIsNoName
= ( pData
->GetName() == ScGlobal::GetRscString( STR_DB_NONAME
) );
198 if ( bIsNoName
&& eMode
== SC_DB_MAKE
)
200 // wenn nichts markiert, "unbenannt" auf zusammenhaengenden Bereich anpassen
205 aDocument
.GetDataArea( nTab
, nStartCol
, nStartRow
, nEndCol
, nEndRow
, FALSE
);
206 if ( nOldCol1
!= nStartCol
|| nOldCol2
!= nEndCol
|| nOldRow1
!= nStartRow
)
207 bUseThis
= FALSE
; // passt gar nicht
208 else if ( nOldRow2
!= nEndRow
)
210 // Bereich auf neue End-Zeile erweitern
211 pData
->SetArea( nTab
, nOldCol1
,nOldRow1
, nOldCol2
,nEndRow
);
217 if ( nOldCol1
== nStartCol
&& nOldRow1
== nStartRow
&&
218 nOldCol2
== nEndCol
&& nOldRow2
== nEndRow
) // genau markiert?
221 bUseThis
= FALSE
; // immer Markierung nehmen (Bug 11964)
224 // fuer Import nie "unbenannt" nehmen
226 if ( bUseThis
&& eMode
== SC_DB_IMPORT
&& bIsNoName
)
232 pData
->GetArea( nStartTab
, nStartCol
,nStartRow
, nEndCol
,nEndRow
);
235 else if ( eMode
== SC_DB_OLD
)
237 pData
= NULL
; // nichts gefunden
238 nStartCol
= nEndCol
= nCol
;
239 nStartRow
= nEndRow
= nRow
;
240 nStartTab
= nEndTab
= nTab
;
241 // bMark = FALSE; // nichts zu markieren
250 { // zusammenhaengender Bereich
255 aDocument
.GetDataArea( nTab
, nStartCol
, nStartRow
, nEndCol
, nEndRow
, FALSE
);
258 BOOL bHasHeader
= aDocument
.HasColHeader( nStartCol
,nStartRow
, nEndCol
,nEndRow
, nTab
);
260 ScDBData
* pNoNameData
;
262 ScDBCollection
* pColl
= aDocument
.GetDBCollection();
263 if ( eMode
!= SC_DB_IMPORT
&&
264 pColl
->SearchName( ScGlobal::GetRscString( STR_DB_NONAME
), nNoNameIndex
) )
266 pNoNameData
= (*pColl
)[nNoNameIndex
];
268 if ( !pOldAutoDBRange
)
270 // store the old unnamed database range with its settings for undo
271 // (store at the first change, get the state before all changes)
272 pOldAutoDBRange
= new ScDBData( *pNoNameData
);
275 SCCOL nOldX1
; // alten Bereich sauber wegnehmen
276 SCROW nOldY1
; //! (UNDO ???)
280 pNoNameData
->GetArea( nOldTab
, nOldX1
, nOldY1
, nOldX2
, nOldY2
);
281 DBAreaDeleted( nOldTab
, nOldX1
, nOldY1
, nOldX2
, nOldY2
);
283 pNoNameData
->SetSortParam( ScSortParam() ); // Parameter zuruecksetzen
284 pNoNameData
->SetQueryParam( ScQueryParam() );
285 pNoNameData
->SetSubTotalParam( ScSubTotalParam() );
287 pNoNameData
->SetArea( nTab
, nStartCol
,nStartRow
, nEndCol
,nEndRow
); // neu setzen
288 pNoNameData
->SetByRow( TRUE
);
289 pNoNameData
->SetHeader( bHasHeader
);
290 pNoNameData
->SetAutoFilter( FALSE
);
294 ScDBCollection
* pUndoColl
= NULL
;
297 if (eMode
==SC_DB_IMPORT
)
299 aDocument
.CompileDBFormula( TRUE
); // CreateFormulaString
300 pUndoColl
= new ScDBCollection( *pColl
); // Undo fuer Import1-Bereich
302 String aImport
= ScGlobal::GetRscString( STR_DBNAME_IMPORT
);
309 aNewName
+= String::CreateFromInt32( nCount
);
311 while (pColl
->SearchName( aNewName
, nDummy
));
314 aNewName
= ScGlobal::GetRscString( STR_DB_NONAME
);
315 pNoNameData
= new ScDBData( aNewName
, nTab
,
316 nStartCol
,nStartRow
, nEndCol
,nEndRow
,
318 pColl
->Insert( pNoNameData
);
322 aDocument
.CompileDBFormula( FALSE
); // CompileFormulaString
324 ScDBCollection
* pRedoColl
= new ScDBCollection( *pColl
);
325 GetUndoManager()->AddUndoAction( new ScUndoDBData( this, pUndoColl
, pRedoColl
) );
328 // neuen Bereich am Sba anmelden nicht mehr noetig
330 // "Import1" etc am Navigator bekanntmachen
331 if (eMode
==SC_DB_IMPORT
)
332 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED
) );
338 // MarkRange( ScRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab ), FALSE );
343 ScDBData
* ScDocShell::GetOldAutoDBRange()
345 ScDBData
* pRet
= pOldAutoDBRange
;
346 pOldAutoDBRange
= NULL
;
347 return pRet
; // has to be deleted by caller!
350 void ScDocShell::CancelAutoDBRange()
352 // called when dialog is cancelled
353 if ( pOldAutoDBRange
)
356 ScDBCollection
* pColl
= aDocument
.GetDBCollection();
357 if ( pColl
->SearchName( ScGlobal::GetRscString( STR_DB_NONAME
), nNoNameIndex
) )
359 ScDBData
* pNoNameData
= (*pColl
)[nNoNameIndex
];
366 pNoNameData
->GetArea( nRangeTab
, nRangeX1
, nRangeY1
, nRangeX2
, nRangeY2
);
367 DBAreaDeleted( nRangeTab
, nRangeX1
, nRangeY1
, nRangeX2
, nRangeY2
);
369 *pNoNameData
= *pOldAutoDBRange
; // restore old settings
371 if ( pOldAutoDBRange
->HasAutoFilter() )
373 // restore AutoFilter buttons
374 pOldAutoDBRange
->GetArea( nRangeTab
, nRangeX1
, nRangeY1
, nRangeX2
, nRangeY2
);
375 aDocument
.ApplyFlagsTab( nRangeX1
, nRangeY1
, nRangeX2
, nRangeY1
, nRangeTab
, SC_MF_AUTO
);
376 PostPaint( nRangeX1
, nRangeY1
, nRangeTab
, nRangeX2
, nRangeY1
, nRangeTab
, PAINT_GRID
);
380 delete pOldAutoDBRange
;
381 pOldAutoDBRange
= NULL
;
387 //! mit docfunc zusammenfassen
389 BOOL
ScDocShell::AdjustRowHeight( SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
)
391 ScSizeDeviceProvider
aProv(this);
393 BOOL bChange
= aDocument
.SetOptimalHeight( nStartRow
,nEndRow
, nTab
, 0, aProv
.GetDevice(),
394 aProv
.GetPPTX(),aProv
.GetPPTY(), aZoom
,aZoom
, FALSE
);
396 PostPaint( 0,nStartRow
,nTab
, MAXCOL
,MAXROW
,nTab
, PAINT_GRID
|PAINT_LEFT
);
401 void ScDocShell::UpdateAllRowHeights( const ScMarkData
* pTabMark
)
403 // update automatic row heights
405 ScSizeDeviceProvider
aProv(this);
407 aDocument
.UpdateAllRowHeights( aProv
.GetDevice(), aProv
.GetPPTX(), aProv
.GetPPTY(), aZoom
, aZoom
, pTabMark
);
410 void ScDocShell::UpdatePendingRowHeights( SCTAB nUpdateTab
, bool bBefore
)
412 BOOL bIsUndoEnabled
= aDocument
.IsUndoEnabled();
413 aDocument
.EnableUndo( FALSE
);
414 aDocument
.LockStreamValid( true ); // ignore draw page size (but not formula results)
415 if ( bBefore
) // check all sheets up to nUpdateTab
417 SCTAB nTabCount
= aDocument
.GetTableCount();
418 if ( nUpdateTab
>= nTabCount
)
419 nUpdateTab
= nTabCount
-1; // nUpdateTab is inclusive
421 ScMarkData aUpdateSheets
;
423 for (nTab
=0; nTab
<=nUpdateTab
; ++nTab
)
424 if ( aDocument
.IsPendingRowHeights( nTab
) )
425 aUpdateSheets
.SelectTable( nTab
, TRUE
);
427 if (aUpdateSheets
.GetSelectCount())
428 UpdateAllRowHeights(&aUpdateSheets
); // update with a single progress bar
430 for (nTab
=0; nTab
<=nUpdateTab
; ++nTab
)
431 if ( aUpdateSheets
.GetTableSelect( nTab
) )
433 aDocument
.UpdatePageBreaks( nTab
);
434 aDocument
.SetPendingRowHeights( nTab
, FALSE
);
437 else // only nUpdateTab
439 if ( aDocument
.IsPendingRowHeights( nUpdateTab
) )
441 AdjustRowHeight( 0, MAXROW
, nUpdateTab
);
442 aDocument
.UpdatePageBreaks( nUpdateTab
);
443 aDocument
.SetPendingRowHeights( nUpdateTab
, FALSE
);
446 aDocument
.LockStreamValid( false );
447 aDocument
.EnableUndo( bIsUndoEnabled
);
450 void ScDocShell::RefreshPivotTables( const ScRange
& rSource
)
452 //! rename to RefreshDataPilotTables?
454 ScDPCollection
* pColl
= aDocument
.GetDPCollection();
457 // DataPilotUpdate doesn't modify the collection order like PivotUpdate did,
458 // so a simple loop can be used.
460 USHORT nCount
= pColl
->GetCount();
461 for ( USHORT i
=0; i
<nCount
; i
++ )
463 ScDPObject
* pOld
= (*pColl
)[i
];
466 const ScSheetSourceDesc
* pSheetDesc
= pOld
->GetSheetDesc();
467 if ( pSheetDesc
&& pSheetDesc
->aSourceRange
.Intersects( rSource
) )
469 ScDPObject
* pNew
= new ScDPObject( *pOld
);
470 ScDBDocFunc
aFunc( *this );
471 aFunc
.DataPilotUpdate( pOld
, pNew
, TRUE
, FALSE
);
472 delete pNew
; // DataPilotUpdate copies settings from "new" object
479 String
lcl_GetAreaName( ScDocument
* pDoc
, ScArea
* pArea
)
483 ScDBData
* pData
= pDoc
->GetDBAtArea( pArea
->nTab
, pArea
->nColStart
, pArea
->nRowStart
,
484 pArea
->nColEnd
, pArea
->nRowEnd
);
487 pData
->GetName( aName
);
488 if ( aName
!= ScGlobal::GetRscString( STR_DB_NONAME
) )
493 pDoc
->GetName( pArea
->nTab
, aName
);
498 void ScDocShell::DoConsolidate( const ScConsolidateParam
& rParam
, BOOL bRecord
)
506 for (nPos
=0; nPos
<rParam
.nDataAreaCount
; nPos
++)
508 ScArea
* pArea
= rParam
.ppDataAreas
[nPos
];
509 nColSize
= Max( nColSize
, SCCOL( pArea
->nColEnd
- pArea
->nColStart
+ 1 ) );
510 nRowSize
= Max( nRowSize
, SCROW( pArea
->nRowEnd
- pArea
->nRowStart
+ 1 ) );
512 // Test, ob Quelldaten verschoben wuerden
513 if (rParam
.bReferenceData
)
514 if (pArea
->nTab
== rParam
.nTab
&& pArea
->nRowEnd
>= rParam
.nRow
)
520 InfoBox
aBox( GetActiveDialogParent(),
521 ScGlobal::GetRscString( STR_CONSOLIDATE_ERR1
) );
528 WaitObject
aWait( GetActiveDialogParent() );
529 ScDocShellModificator
aModificator( *this );
532 ScDBData
* pDestData
= aDocument
.GetDBAtCursor( rParam
.nCol
, rParam
.nRow
, rParam
.nTab
, TRUE
);
534 pDestData
->GetArea(aOldDest
);
536 aData
.SetSize( nColSize
, nRowSize
);
537 aData
.SetFlags( rParam
.eFunction
, rParam
.bByCol
, rParam
.bByRow
, rParam
.bReferenceData
);
538 if ( rParam
.bByCol
|| rParam
.bByRow
)
539 for (nPos
=0; nPos
<rParam
.nDataAreaCount
; nPos
++)
541 ScArea
* pArea
= rParam
.ppDataAreas
[nPos
];
542 aData
.AddFields( &aDocument
, pArea
->nTab
, pArea
->nColStart
, pArea
->nRowStart
,
543 pArea
->nColEnd
, pArea
->nRowEnd
);
546 for (nPos
=0; nPos
<rParam
.nDataAreaCount
; nPos
++)
548 ScArea
* pArea
= rParam
.ppDataAreas
[nPos
];
549 aData
.AddData( &aDocument
, pArea
->nTab
, pArea
->nColStart
, pArea
->nRowStart
,
550 pArea
->nColEnd
, pArea
->nRowEnd
);
551 aData
.AddName( lcl_GetAreaName(&aDocument
,pArea
) );
554 aData
.GetSize( nColSize
, nRowSize
);
555 if (bRecord
&& nColSize
> 0 && nRowSize
> 0)
557 ScDBData
* pUndoData
= pDestData
? new ScDBData(*pDestData
) : NULL
;
559 SCTAB nDestTab
= rParam
.nTab
;
560 ScArea
aDestArea( rParam
.nTab
, rParam
.nCol
, rParam
.nRow
,
561 rParam
.nCol
+nColSize
-1, rParam
.nRow
+nRowSize
-1 );
562 if (rParam
.bByCol
) ++aDestArea
.nColEnd
;
563 if (rParam
.bByRow
) ++aDestArea
.nRowEnd
;
565 if (rParam
.bReferenceData
)
567 SCTAB nTabCount
= aDocument
.GetTableCount();
568 SCROW nInsertCount
= aData
.GetInsertCount();
571 ScOutlineTable
* pTable
= aDocument
.GetOutlineTable( nDestTab
);
572 ScOutlineTable
* pUndoTab
= pTable
? new ScOutlineTable( *pTable
) : NULL
;
574 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
575 pUndoDoc
->InitUndo( &aDocument
, 0, nTabCount
-1, FALSE
, TRUE
);
578 aDocument
.CopyToDocument( 0,0,nDestTab
, MAXCOL
,MAXROW
,nDestTab
,
579 IDF_NONE
, FALSE
, pUndoDoc
);
582 aDocument
.CopyToDocument( 0,0,0, MAXCOL
,MAXROW
,nTabCount
-1,
583 IDF_FORMULA
, FALSE
, pUndoDoc
);
585 // komplette Ausgangszeilen
586 aDocument
.CopyToDocument( 0,aDestArea
.nRowStart
,nDestTab
,
587 MAXCOL
,aDestArea
.nRowEnd
,nDestTab
,
588 IDF_ALL
, FALSE
, pUndoDoc
);
590 // alten Ausgabebereich
592 aDocument
.CopyToDocument( aOldDest
, IDF_ALL
, FALSE
, pUndoDoc
);
594 GetUndoManager()->AddUndoAction(
595 new ScUndoConsolidate( this, aDestArea
, rParam
, pUndoDoc
,
596 TRUE
, nInsertCount
, pUndoTab
, pUndoData
) );
600 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
601 pUndoDoc
->InitUndo( &aDocument
, aDestArea
.nTab
, aDestArea
.nTab
);
603 aDocument
.CopyToDocument( aDestArea
.nColStart
, aDestArea
.nRowStart
, aDestArea
.nTab
,
604 aDestArea
.nColEnd
, aDestArea
.nRowEnd
, aDestArea
.nTab
,
605 IDF_ALL
, FALSE
, pUndoDoc
);
607 // alten Ausgabebereich
609 aDocument
.CopyToDocument( aOldDest
, IDF_ALL
, FALSE
, pUndoDoc
);
611 GetUndoManager()->AddUndoAction(
612 new ScUndoConsolidate( this, aDestArea
, rParam
, pUndoDoc
,
613 FALSE
, 0, NULL
, pUndoData
) );
617 if (pDestData
) // Zielbereich loeschen / anpassen
619 aDocument
.DeleteAreaTab(aOldDest
, IDF_CONTENTS
);
620 pDestData
->SetArea( rParam
.nTab
, rParam
.nCol
, rParam
.nRow
,
621 rParam
.nCol
+ nColSize
- 1, rParam
.nRow
+ nRowSize
- 1 );
622 pDestData
->SetHeader( rParam
.bByRow
);
625 aData
.OutputToDocument( &aDocument
, rParam
.nCol
, rParam
.nRow
, rParam
.nTab
);
627 SCCOL nPaintStartCol
= rParam
.nCol
;
628 SCROW nPaintStartRow
= rParam
.nRow
;
629 SCCOL nPaintEndCol
= nPaintStartCol
+ nColSize
- 1;
630 SCROW nPaintEndRow
= nPaintStartRow
+ nRowSize
- 1;
631 USHORT nPaintFlags
= PAINT_GRID
;
636 if (rParam
.bReferenceData
)
639 nPaintEndCol
= MAXCOL
;
640 nPaintEndRow
= MAXROW
;
641 nPaintFlags
|= PAINT_LEFT
| PAINT_SIZE
;
645 if ( aOldDest
.aEnd
.Col() > nPaintEndCol
)
646 nPaintEndCol
= aOldDest
.aEnd
.Col();
647 if ( aOldDest
.aEnd
.Row() > nPaintEndRow
)
648 nPaintEndRow
= aOldDest
.aEnd
.Row();
650 PostPaint( nPaintStartCol
, nPaintStartRow
, rParam
.nTab
,
651 nPaintEndCol
, nPaintEndRow
, rParam
.nTab
, nPaintFlags
);
652 aModificator
.SetDocumentModified();
655 void ScDocShell::UseScenario( SCTAB nTab
, const String
& rName
, BOOL bRecord
)
657 if (!aDocument
.IsScenario(nTab
))
659 SCTAB nTabCount
= aDocument
.GetTableCount();
660 SCTAB nSrcTab
= SCTAB_MAX
;
661 SCTAB nEndTab
= nTab
;
663 while ( nEndTab
+1 < nTabCount
&& aDocument
.IsScenario(nEndTab
+1) )
666 if (nSrcTab
> MAXTAB
) // noch auf der Suche nach dem Szenario?
668 aDocument
.GetName( nEndTab
, aCompare
);
669 if (aCompare
== rName
)
670 nSrcTab
= nEndTab
; // gefunden
673 if (ValidTab(nSrcTab
))
675 if ( aDocument
.TestCopyScenario( nSrcTab
, nTab
) ) // Zellschutz testen
677 ScDocShellModificator
aModificator( *this );
678 ScMarkData aScenMark
;
679 aDocument
.MarkScenario( nSrcTab
, nTab
, aScenMark
);
681 aScenMark
.GetMultiMarkArea( aMultiRange
);
682 SCCOL nStartCol
= aMultiRange
.aStart
.Col();
683 SCROW nStartRow
= aMultiRange
.aStart
.Row();
684 SCCOL nEndCol
= aMultiRange
.aEnd
.Col();
685 SCROW nEndRow
= aMultiRange
.aEnd
.Row();
689 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
690 pUndoDoc
->InitUndo( &aDocument
, nTab
,nEndTab
); // auch alle Szenarien
691 // angezeigte Tabelle:
692 aDocument
.CopyToDocument( nStartCol
,nStartRow
,nTab
,
693 nEndCol
,nEndRow
,nTab
, IDF_ALL
,TRUE
, pUndoDoc
, &aScenMark
);
695 for (SCTAB i
=nTab
+1; i
<=nEndTab
; i
++)
697 pUndoDoc
->SetScenario( i
, TRUE
);
701 aDocument
.GetScenarioData( i
, aComment
, aColor
, nScenFlags
);
702 pUndoDoc
->SetScenarioData( i
, aComment
, aColor
, nScenFlags
);
703 BOOL bActive
= aDocument
.IsActiveScenario( i
);
704 pUndoDoc
->SetActiveScenario( i
, bActive
);
705 // Bei Zurueckkopier-Szenarios auch Inhalte
706 if ( nScenFlags
& SC_SCENARIO_TWOWAY
)
707 aDocument
.CopyToDocument( 0,0,i
, MAXCOL
,MAXROW
,i
,
708 IDF_ALL
,FALSE
, pUndoDoc
);
711 GetUndoManager()->AddUndoAction(
712 new ScUndoUseScenario( this, aScenMark
,
713 ScArea( nTab
,nStartCol
,nStartRow
,nEndCol
,nEndRow
),
717 aDocument
.CopyScenario( nSrcTab
, nTab
);
718 aDocument
.SetDirty();
720 // alles painten, weil in anderen Bereichen das aktive Szenario
721 // geaendert sein kann
722 //! nur, wenn sichtbare Rahmen vorhanden?
723 PostPaint( 0,0,nTab
, MAXCOL
,MAXROW
,nTab
, PAINT_GRID
);
724 aModificator
.SetDocumentModified();
728 InfoBox
aBox(GetActiveDialogParent(),
729 ScGlobal::GetRscString( STR_PROTECTIONERR
) );
735 InfoBox
aBox(GetActiveDialogParent(),
736 ScGlobal::GetRscString( STR_SCENARIO_NOTFOUND
) );
742 DBG_ERROR( "UseScenario auf Szenario-Blatt" );
746 void ScDocShell::ModifyScenario( SCTAB nTab
, const String
& rName
, const String
& rComment
,
747 const Color
& rColor
, USHORT nFlags
)
751 aDocument
.GetName( nTab
, aOldName
);
755 aDocument
.GetScenarioData( nTab
, aOldComment
, aOldColor
, nOldFlags
);
756 GetUndoManager()->AddUndoAction(
757 new ScUndoScenarioFlags( this, nTab
,
758 aOldName
, rName
, aOldComment
, rComment
,
759 aOldColor
, rColor
, nOldFlags
, nFlags
) );
762 ScDocShellModificator
aModificator( *this );
763 aDocument
.RenameTab( nTab
, rName
);
764 aDocument
.SetScenarioData( nTab
, rComment
, rColor
, nFlags
);
766 aModificator
.SetDocumentModified();
768 if ( rName
!= aOldName
)
769 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
771 SfxBindings
* pBindings
= GetViewBindings();
773 pBindings
->Invalidate( SID_SELECT_SCENARIO
);
776 SCTAB
ScDocShell::MakeScenario( SCTAB nTab
, const String
& rName
, const String
& rComment
,
777 const Color
& rColor
, USHORT nFlags
,
778 ScMarkData
& rMark
, BOOL bRecord
)
781 if (rMark
.IsMultiMarked())
783 SCTAB nNewTab
= nTab
+ 1;
784 while (aDocument
.IsScenario(nNewTab
))
787 BOOL bCopyAll
= ( (nFlags
& SC_SCENARIO_COPYALL
) != 0 );
788 const ScMarkData
* pCopyMark
= NULL
;
792 ScDocShellModificator
aModificator( *this );
795 aDocument
.BeginDrawUndo(); // drawing layer must do its own undo actions
797 if (aDocument
.CopyTab( nTab
, nNewTab
, pCopyMark
))
801 GetUndoManager()->AddUndoAction(
802 new ScUndoMakeScenario( this, nTab
, nNewTab
,
803 rName
, rComment
, rColor
, nFlags
, rMark
));
806 aDocument
.RenameTab( nNewTab
, rName
, FALSE
); // ohne Formel-Update
807 aDocument
.SetScenario( nNewTab
, TRUE
);
808 aDocument
.SetScenarioData( nNewTab
, rComment
, rColor
, nFlags
);
810 ScMarkData aDestMark
= rMark
;
811 aDestMark
.SelectOneTable( nNewTab
);
813 //! auf Filter / Buttons / Merging testen !
815 ScPatternAttr
aProtPattern( aDocument
.GetPool() );
816 aProtPattern
.GetItemSet().Put( ScProtectionAttr( TRUE
) );
817 aDocument
.ApplyPatternAreaTab( 0,0, MAXCOL
,MAXROW
, nNewTab
, aProtPattern
);
819 ScPatternAttr
aPattern( aDocument
.GetPool() );
820 aPattern
.GetItemSet().Put( ScMergeFlagAttr( SC_MF_SCENARIO
) );
821 aPattern
.GetItemSet().Put( ScProtectionAttr( TRUE
) );
822 aDocument
.ApplySelectionPattern( aPattern
, aDestMark
);
825 aDocument
.SetVisible( nNewTab
, FALSE
);
827 // dies ist dann das aktive Szenario
828 aDocument
.CopyScenario( nNewTab
, nTab
, TRUE
); // TRUE - nicht aus Szenario kopieren
830 if (nFlags
& SC_SCENARIO_SHOWFRAME
)
831 PostPaint( 0,0,nTab
, MAXCOL
,MAXROW
,nTab
, PAINT_GRID
); // Rahmen painten
832 PostPaintExtras(); // Tabellenreiter
833 aModificator
.SetDocumentModified();
835 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
843 BOOL
ScDocShell::MoveTable( SCTAB nSrcTab
, SCTAB nDestTab
, BOOL bCopy
, BOOL bRecord
)
845 ScDocShellModificator
aModificator( *this );
847 // #i92477# be consistent with ScDocFunc::InsertTable: any index past the last sheet means "append"
848 if ( nDestTab
>= aDocument
.GetTableCount() )
849 nDestTab
= SC_TAB_APPEND
;
854 aDocument
.BeginDrawUndo(); // drawing layer must do its own undo actions
856 if (!aDocument
.CopyTab( nSrcTab
, nDestTab
))
863 SCTAB nAdjSource
= nSrcTab
;
864 if ( nDestTab
<= nSrcTab
)
865 ++nAdjSource
; // new position of source table after CopyTab
867 if ( aDocument
.IsTabProtected( nAdjSource
) )
868 aDocument
.CopyTabProtection(nAdjSource
, nDestTab
);
874 aSrcList
.Insert(nSrcTab
,0);
875 aDestList
.Insert(nDestTab
,0);
876 GetUndoManager()->AddUndoAction(
877 new ScUndoCopyTab( this, aSrcList
, aDestList
) );
880 StarBASIC
* pStarBASIC
= GetBasic();
881 String
aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
882 if ( GetBasicManager()->GetName().Len() > 0 )
884 aLibName
= GetBasicManager()->GetName();
885 pStarBASIC
= GetBasicManager()->GetLib( aLibName
);
887 BOOL bVbaEnabled
= pStarBASIC
? pStarBASIC
->isVBAEnabled() : FALSE
;
888 SCTAB nTabToUse
= nDestTab
;
890 if ( nDestTab
== SC_TAB_APPEND
)
891 nTabToUse
= aDocument
.GetMaxTableNumber() - 1;
897 aDocument
.GetCodeName( nTabToUse
, sCodeName
);
898 com::sun::star::uno::Reference
< com::sun::star::script::XLibraryContainer
> xLibContainer
= GetBasicContainer();
899 com::sun::star::uno::Reference
< com::sun::star::container::XNameContainer
> xLib
;
900 if( xLibContainer
.is() )
902 com::sun::star::uno::Any aLibAny
= xLibContainer
->getByName( aLibName
);
908 aDocument
.GetCodeName( nSrcTab
, sSrcCodeName
);
909 rtl::OUString sModName
= sSrcCodeName
;
910 com::sun::star::script::ModuleInfo sModuleInfo
;
911 xLib
->getByName( sModName
) >>= sModuleInfo
;
912 sSource
= sModuleInfo
.ModuleSource
;
914 lcl_InsertModule( *this, nTabToUse
, sCodeName
, sSource
);
918 Broadcast( ScTablesHint( SC_TAB_COPIED
, nSrcTab
, nDestTab
) );
922 if ( aDocument
.GetChangeTrack() )
925 if ( nSrcTab
<nDestTab
&& nDestTab
!=SC_TAB_APPEND
)
928 if ( nSrcTab
== nDestTab
)
930 //! allow only for api calls?
931 return TRUE
; // nothing to do, but valid
934 if (!aDocument
.MoveTab( nSrcTab
, nDestTab
))
940 aSrcList
.Insert(nSrcTab
,0);
941 aDestList
.Insert(nDestTab
,0);
942 GetUndoManager()->AddUndoAction(
943 new ScUndoMoveTab( this, aSrcList
, aDestList
) );
946 Broadcast( ScTablesHint( SC_TAB_MOVED
, nSrcTab
, nDestTab
) );
951 aModificator
.SetDocumentModified();
952 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
958 IMPL_LINK( ScDocShell
, RefreshDBDataHdl
, ScRefreshTimer
*, pRefreshTimer
)
960 ScDBDocFunc
aFunc(*this);
962 BOOL bContinue
= TRUE
;
963 ScDBData
* pDBData
= static_cast<ScDBData
*>(pRefreshTimer
);
964 ScImportParam aImportParam
;
965 pDBData
->GetImportParam( aImportParam
);
966 if (aImportParam
.bImport
&& !pDBData
->HasImportSelection())
969 pDBData
->GetArea( aRange
);
970 ::com::sun::star::uno::Reference
< ::com::sun::star::sdbc::XResultSet
> xResultSet
;
971 bContinue
= aFunc
.DoImport( aRange
.aStart
.Tab(), aImportParam
, xResultSet
, NULL
, TRUE
, FALSE
); //! Api-Flag as parameter
972 // internal operations (sort, query, subtotal) only if no error
975 aFunc
.RepeatDB( pDBData
->GetName(), TRUE
, TRUE
);
976 RefreshPivotTables(aRange
);
980 return bContinue
!= 0;