Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / source / ui / docshell / docsh5.cxx
blob9ad746df08239a15c83350b65a626eabe3cfc9c0
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
28 #include "docsh.hxx"
29 #include "global.hxx"
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"
39 #include "dbdata.hxx"
40 #include "progress.hxx"
41 #include "olinetab.hxx"
42 #include "patattr.hxx"
43 #include "attrib.hxx"
44 #include "docpool.hxx"
45 #include "uiitems.hxx"
46 #include "sc.hrc"
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;
61 using ::std::vector;
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)
79 if(IsReadOnly())
81 nGlobStrId=STR_READONLYERR;
85 InfoBox aBox( pParent, ScGlobal::GetRscString( nGlobStrId ) );
86 aBox.Execute();
87 if (bFocus)
88 pParent->GrabFocus();
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 );
126 if (!pData && pColl)
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;
134 if (pData)
136 // Bereich nehmen, wenn nichts anderes markiert
138 SCTAB nDummy;
139 SCCOL nOldCol1;
140 SCROW nOldRow1;
141 SCCOL nOldCol2;
142 SCROW nOldRow2;
143 pData->GetArea( nDummy, nOldCol1,nOldRow1, nOldCol2,nOldRow2 );
144 sal_Bool bIsNoName = ( pData->GetName() == STR_DB_LOCAL_NONAME );
146 if (!bSelected)
148 bUseThis = sal_True;
149 if ( bIsNoName && eMode == SC_DB_MAKE )
151 // If nothing marked or only one row marked, adapt
152 // "unbenannt"/"unnamed" to contiguous area.
153 nStartCol = nCol;
154 nStartRow = nRow;
155 if (bOnlyDown)
157 nEndCol = rMarked.aEnd.Col();
158 nEndRow = rMarked.aEnd.Row();
160 else
162 nEndCol = nStartCol;
163 nEndRow = nStartRow;
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 );
175 else
177 if ( nOldCol1 == nStartCol && nOldRow1 == nStartRow &&
178 nOldCol2 == nEndCol && nOldRow2 == nEndRow ) // genau markiert?
179 bUseThis = sal_True;
180 else
181 bUseThis = false; // immer Markierung nehmen (Bug 11964)
184 // fuer Import nie "unbenannt" nehmen
186 if ( bUseThis && eMode == SC_DB_IMPORT && bIsNoName )
187 bUseThis = false;
190 if ( bUseThis )
192 pData->GetArea( nStartTab, nStartCol,nStartRow, nEndCol,nEndRow );
193 nEndTab = nStartTab;
195 else if ( eMode == SC_DB_OLD )
197 pData = NULL; // nichts gefunden
198 nStartCol = nEndCol = nCol;
199 nStartRow = nEndRow = nRow;
200 nStartTab = nEndTab = nTab;
202 else
204 if ( !bSelected )
205 { // zusammenhaengender Bereich
206 nStartCol = nCol;
207 nStartRow = nRow;
208 if (bOnlyDown)
210 nEndCol = rMarked.aEnd.Col();
211 nEndRow = rMarked.aEnd.Row();
213 else
215 nEndCol = nStartCol;
216 nEndRow = nStartRow;
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 ???)
236 SCCOL nOldX2;
237 SCROW nOldY2;
238 SCTAB nOldTab;
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 );
251 else
253 ScDBCollection* pUndoColl = NULL;
255 OUString aNewName;
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 );
262 long nCount = 0;
263 const ScDBData* pDummy = NULL;
264 ScDBCollection::NamedDBs& rDBs = pColl->getNamedDBs();
267 ++nCount;
268 aNewName = aImport;
269 aNewName += OUString::number( nCount );
270 pDummy = rDBs.findByUpperName(ScGlobal::pCharClass->uppercase(aNewName));
272 while (pDummy);
273 pNoNameData = new ScDBData( aNewName, nTab,
274 nStartCol,nStartRow, nEndCol,nEndRow,
275 sal_True, bHasHeader );
276 rDBs.insert(pNoNameData);
278 else
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);
289 if ( pUndoColl )
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 ) );
303 pData = pNoNameData;
306 return pData;
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();
315 if (!pColl)
316 return NULL;
318 ScDBData* pData = pColl->getAnonDBs().getByRange(rRange);
319 if (!pData)
320 return NULL;
322 pData->SetHeader(bHasHeader);
323 return pData;
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
336 //moggi:TODO
337 if ( pOldAutoDBRange )
339 SCTAB nTab = GetCurTab();
340 ScDBData* pDBData = aDocument.GetAnonymousDBData(nTab);
341 if ( pDBData )
343 SCCOL nRangeX1;
344 SCROW nRangeY1;
345 SCCOL nRangeX2;
346 SCROW nRangeY2;
347 SCTAB nRangeTab;
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;
368 // Hoehen anpassen
369 //! mit docfunc zusammenfassen
371 sal_Bool ScDocShell::AdjustRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab )
373 ScSizeDeviceProvider aProv(this);
374 Fraction aZoom(1,1);
375 sal_Bool bChange = aDocument.SetOptimalHeight( nStartRow,nEndRow, nTab, 0, aProv.GetDevice(),
376 aProv.GetPPTX(),aProv.GetPPTY(), aZoom,aZoom, false );
377 if (bChange)
378 PostPaint( 0,nStartRow,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID|PAINT_LEFT );
380 return bChange;
383 void ScDocShell::UpdateAllRowHeights( const ScMarkData* pTabMark )
385 // update automatic row heights
387 ScSizeDeviceProvider aProv(this);
388 Fraction aZoom(1,1);
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;
404 SCTAB nTab;
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();
435 if (!pColl)
436 return;
438 ScDBDocFunc aFunc(*this);
439 for (size_t i = 0, n = pColl->GetCount(); i < n; ++i)
441 ScDPObject* pOld = (*pColl)[i];
442 if (!pOld)
443 continue;
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 )
453 OUString aName;
454 sal_Bool bOk = false;
455 ScDBData* pData = pDoc->GetDBAtArea( pArea->nTab, pArea->nColStart, pArea->nRowStart,
456 pArea->nColEnd, pArea->nRowEnd );
457 if (pData)
459 aName = pData->GetName();
460 bOk = sal_True;
463 if (!bOk)
464 pDoc->GetName( pArea->nTab, aName );
466 return aName;
469 void ScDocShell::DoConsolidate( const ScConsolidateParam& rParam, sal_Bool bRecord )
471 ScConsData aData;
473 sal_uInt16 nPos;
474 SCCOL nColSize = 0;
475 SCROW nRowSize = 0;
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)
486 bErr = sal_True;
489 if (bErr)
491 InfoBox aBox( GetActiveDialogParent(),
492 ScGlobal::GetRscString( STR_CONSOLIDATE_ERR1 ) );
493 aBox.Execute();
494 return;
497 // ausfuehren
499 WaitObject aWait( GetActiveDialogParent() );
500 ScDocShellModificator aModificator( *this );
502 ScRange aOldDest;
503 ScDBData* pDestData = aDocument.GetDBAtCursor( rParam.nCol, rParam.nRow, rParam.nTab, true );
504 if (pDestData)
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 );
516 aData.DoneFields();
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();
541 // alte Outlines
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 );
548 // Zeilenstatus
549 aDocument.CopyToDocument( 0,0,nDestTab, MAXCOL,MAXROW,nDestTab,
550 IDF_NONE, false, pUndoDoc );
552 // alle Formeln
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
562 if (pDestData)
563 aDocument.CopyToDocument( aOldDest, IDF_ALL, false, pUndoDoc );
565 GetUndoManager()->AddUndoAction(
566 new ScUndoConsolidate( this, aDestArea, rParam, pUndoDoc,
567 sal_True, nInsertCount, pUndoTab, pUndoData ) );
569 else
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
579 if (pDestData)
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;
603 if (rParam.bByCol)
604 ++nPaintEndRow;
605 if (rParam.bByRow)
606 ++nPaintEndCol;
607 if (rParam.bReferenceData)
609 nPaintStartCol = 0;
610 nPaintEndCol = MAXCOL;
611 nPaintEndRow = MAXROW;
612 nPaintFlags |= PAINT_LEFT | PAINT_SIZE;
614 if (pDestData)
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;
633 OUString aCompare;
634 while ( nEndTab+1 < nTabCount && aDocument.IsScenario(nEndTab+1) )
636 ++nEndTab;
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 );
651 ScRange aMultiRange;
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();
658 if (bRecord)
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 );
665 // Szenarien
666 for (SCTAB i=nTab+1; i<=nEndTab; i++)
668 pUndoDoc->SetScenario( i, sal_True );
669 OUString aComment;
670 Color aColor;
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 ),
685 pUndoDoc, rName ) );
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();
697 else
699 InfoBox aBox(GetActiveDialogParent(),
700 ScGlobal::GetRscString( STR_PROTECTIONERR ) );
701 aBox.Execute();
704 else
706 InfoBox aBox(GetActiveDialogParent(),
707 ScGlobal::GetRscString( STR_SCENARIO_NOTFOUND ) );
708 aBox.Execute();
711 else
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 )
720 // Undo
721 OUString aOldName;
722 aDocument.GetName( nTab, aOldName );
723 OUString aOldComment;
724 Color aOldColor;
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 ) );
732 // ausfuehren
733 ScDocShellModificator aModificator( *this );
734 aDocument.RenameTab( nTab, rName );
735 aDocument.SetScenarioData( nTab, rComment, rColor, nFlags );
736 PostPaintGridAll();
737 aModificator.SetDocumentModified();
739 if (!aOldName.equals(rName))
740 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
742 SfxBindings* pBindings = GetViewBindings();
743 if (pBindings)
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 )
751 rMark.MarkToMulti();
752 if (rMark.IsMultiMarked())
754 SCTAB nNewTab = nTab + 1;
755 while (aDocument.IsScenario(nNewTab))
756 ++nNewTab;
758 sal_Bool bCopyAll = ( (nFlags & SC_SCENARIO_COPYALL) != 0 );
759 const ScMarkData* pCopyMark = NULL;
760 if (!bCopyAll)
761 pCopyMark = &rMark;
763 ScDocShellModificator aModificator( *this );
765 if (bRecord)
766 aDocument.BeginDrawUndo(); // drawing layer must do its own undo actions
768 if (aDocument.CopyTab( nTab, nNewTab, pCopyMark ))
770 if (bRecord)
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 );
795 if (!bCopyAll)
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 ) );
808 return nNewTab;
811 return nTab;
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
821 ScClipParam aParam;
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 ))
835 OUString aComment;
836 Color aColor;
837 sal_uInt16 nFlags;
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 ) );
855 PostPaintExtras();
856 PostPaintGridAll();
858 return nErrVal;
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();
870 if (bCopy)
872 if (bRecord)
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 ))
879 //! EndDrawUndo?
880 return false;
882 else
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);
891 if (bRecord)
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();
902 if ( bVbaEnabled )
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;
916 OUString sCodeName;
917 OUString sSource;
920 Reference< XNameContainer > xLib;
921 if( xLibContainer.is() )
923 com::sun::star::uno::Any aLibAny = xLibContainer->getByName( aLibName );
924 aLibAny >>= xLib;
926 if( xLib.is() )
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 ) );
939 else
941 if ( aDocument.GetChangeTrack() )
942 return false;
944 if ( nSrcTab<nDestTab && nDestTab!=SC_TAB_APPEND )
945 nDestTab--;
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 );
956 delete pProgress;
957 if (!bDone)
959 return false;
961 else if (bRecord)
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 ) );
974 PostPaintGridAll();
975 PostPaintExtras();
976 aModificator.SetDocumentModified();
977 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
979 return sal_True;
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())
993 ScRange aRange;
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
997 if (bContinue)
999 aFunc.RepeatDB( pDBData->GetName(), sal_True, sal_True );
1000 RefreshPivotTables(aRange);
1004 return bContinue != 0;
1007 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */