fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / ui / docshell / docsh5.cxx
blob8ef2a76112f934bfea4f60ba39ba9c6824e8ff91
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 <sal/config.h>
22 #include <cassert>
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>
32 #include "docsh.hxx"
33 #include "global.hxx"
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"
43 #include "dbdata.hxx"
44 #include "progress.hxx"
45 #include "olinetab.hxx"
46 #include "patattr.hxx"
47 #include "attrib.hxx"
48 #include "docpool.hxx"
49 #include "uiitems.hxx"
50 #include "sc.hrc"
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;
64 using ::std::vector;
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)
78 if(IsReadOnly())
80 nGlobStrId=STR_READONLYERR;
84 ScopedVclPtrInstance< InfoBox > aBox( pParent, ScGlobal::GetRscString( nGlobStrId ) );
85 aBox->Execute();
86 if (bFocus)
87 pParent->GrabFocus();
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 );
125 if (!pData)
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;
133 if (pData)
135 // Bereich nehmen, wenn nichts anderes markiert
137 SCTAB nDummy;
138 SCCOL nOldCol1;
139 SCROW nOldRow1;
140 SCCOL nOldCol2;
141 SCROW nOldRow2;
142 pData->GetArea( nDummy, nOldCol1,nOldRow1, nOldCol2,nOldRow2 );
143 bool bIsNoName = ( pData->GetName() == STR_DB_LOCAL_NONAME );
145 if (!bSelected)
147 bUseThis = true;
148 if ( bIsNoName && eMode == SC_DB_MAKE )
150 // If nothing marked or only one row marked, adapt
151 // "unbenannt"/"unnamed" to contiguous area.
152 nStartCol = nCol;
153 nStartRow = nRow;
154 if (bOnlyDown)
156 nEndCol = rMarked.aEnd.Col();
157 nEndRow = rMarked.aEnd.Row();
159 else
161 nEndCol = nStartCol;
162 nEndRow = nStartRow;
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 );
174 else
176 if ( nOldCol1 == nStartCol && nOldRow1 == nStartRow &&
177 nOldCol2 == nEndCol && nOldRow2 == nEndRow ) // genau markiert?
178 bUseThis = true;
179 else
180 bUseThis = false; // immer Markierung nehmen (Bug 11964)
183 // fuer Import nie "unbenannt" nehmen
185 if ( bUseThis && eMode == SC_DB_IMPORT && bIsNoName )
186 bUseThis = false;
189 if ( bUseThis )
191 pData->GetArea( nStartTab, nStartCol,nStartRow, nEndCol,nEndRow );
192 nEndTab = nStartTab;
194 else if ( eMode == SC_DB_OLD )
196 pData = NULL; // nichts gefunden
197 nStartCol = nEndCol = nCol;
198 nStartRow = nEndRow = nRow;
199 nStartTab = nEndTab = nTab;
201 else
203 if ( !bSelected )
204 { // zusammenhaengender Bereich
205 nStartCol = nCol;
206 nStartRow = nRow;
207 if (bOnlyDown)
209 nEndCol = rMarked.aEnd.Col();
210 nEndRow = rMarked.aEnd.Row();
212 else
214 nEndCol = nStartCol;
215 nEndRow = nStartRow;
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 ???)
235 SCCOL nOldX2;
236 SCROW nOldY2;
237 SCTAB nOldTab;
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 );
250 else
252 ScDBCollection* pUndoColl = NULL;
254 OUString aNewName;
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 );
261 long nCount = 0;
262 const ScDBData* pDummy = NULL;
263 ScDBCollection::NamedDBs& rDBs = pColl->getNamedDBs();
266 ++nCount;
267 aNewName = aImport;
268 aNewName += OUString::number( nCount );
269 pDummy = rDBs.findByUpperName(ScGlobal::pCharClass->uppercase(aNewName));
271 while (pDummy);
272 pNoNameData = new ScDBData( aNewName, nTab,
273 nStartCol,nStartRow, nEndCol,nEndRow,
274 true, bHasHeader );
275 bool ins = rDBs.insert(pNoNameData);
276 assert(ins); (void)ins;
278 else
280 aNewName = STR_DB_LOCAL_NONAME;
281 pNoNameData = new ScDBData(aNewName , nTab,
282 nStartCol,nStartRow, nEndCol,nEndRow,
283 true, bHasHeader );
284 aDocument.SetAnonymousDBData(nTab, pNoNameData);
287 if ( pUndoColl )
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 ) );
301 pData = pNoNameData;
304 return pData;
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();
313 if (!pColl)
314 return NULL;
316 ScDBData* pData = pColl->getAnonDBs().getByRange(rRange);
317 if (!pData)
318 return NULL;
320 pData->SetHeader(bHasHeader);
321 return pData;
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
334 //moggi:TODO
335 if ( pOldAutoDBRange )
337 SCTAB nTab = GetCurTab();
338 ScDBData* pDBData = aDocument.GetAnonymousDBData(nTab);
339 if ( pDBData )
341 SCCOL nRangeX1;
342 SCROW nRangeY1;
343 SCCOL nRangeX2;
344 SCROW nRangeY2;
345 SCTAB nRangeTab;
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;
365 // Hoehen anpassen
366 //! mit docfunc zusammenfassen
368 bool ScDocShell::AdjustRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab )
370 ScSizeDeviceProvider aProv(this);
371 Fraction aZoom(1,1);
372 sc::RowHeightContext aCxt(aProv.GetPPTX(), aProv.GetPPTY(), aZoom, aZoom, aProv.GetDevice());
373 bool bChange = aDocument.SetOptimalHeight(aCxt, nStartRow,nEndRow, nTab);
375 if (bChange)
376 PostPaint( 0,nStartRow,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID|PAINT_LEFT );
378 return bChange;
381 void ScDocShell::UpdateAllRowHeights( const ScMarkData* pTabMark )
383 // update automatic row heights
385 ScSizeDeviceProvider aProv(this);
386 Fraction aZoom(1,1);
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;
403 SCTAB nTab;
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();
434 if (!pColl)
435 return;
437 ScDBDocFunc aFunc(*this);
438 for (size_t i = 0, n = pColl->GetCount(); i < n; ++i)
440 ScDPObject* pOld = (*pColl)[i];
441 if (!pOld)
442 continue;
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 )
452 OUString aName;
453 bool bOk = false;
454 ScDBData* pData = pDoc->GetDBAtArea( pArea->nTab, pArea->nColStart, pArea->nRowStart,
455 pArea->nColEnd, pArea->nRowEnd );
456 if (pData)
458 aName = pData->GetName();
459 bOk = true;
462 if (!bOk)
463 pDoc->GetName( pArea->nTab, aName );
465 return aName;
468 void ScDocShell::DoConsolidate( const ScConsolidateParam& rParam, bool bRecord )
470 ScConsData aData;
472 sal_uInt16 nPos;
473 SCCOL nColSize = 0;
474 SCROW nRowSize = 0;
475 bool bErr = false;
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)
485 bErr = true;
488 if (bErr)
490 ScopedVclPtrInstance<InfoBox> aBox( GetActiveDialogParent(),
491 ScGlobal::GetRscString( STR_CONSOLIDATE_ERR1 ) );
492 aBox->Execute();
493 return;
496 // ausfuehren
498 WaitObject aWait( GetActiveDialogParent() );
499 ScDocShellModificator aModificator( *this );
501 ScRange aOldDest;
502 ScDBData* pDestData = aDocument.GetDBAtCursor( rParam.nCol, rParam.nRow, rParam.nTab, true );
503 if (pDestData)
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 );
515 aData.DoneFields();
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();
540 // alte Outlines
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 );
547 // Zeilenstatus
548 aDocument.CopyToDocument( 0,0,nDestTab, MAXCOL,MAXROW,nDestTab,
549 IDF_NONE, false, pUndoDoc );
551 // alle Formeln
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
561 if (pDestData)
562 aDocument.CopyToDocument( aOldDest, IDF_ALL, false, pUndoDoc );
564 GetUndoManager()->AddUndoAction(
565 new ScUndoConsolidate( this, aDestArea, rParam, pUndoDoc,
566 true, nInsertCount, pUndoTab, pUndoData ) );
568 else
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
578 if (pDestData)
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;
602 if (rParam.bByCol)
603 ++nPaintEndRow;
604 if (rParam.bByRow)
605 ++nPaintEndCol;
606 if (rParam.bReferenceData)
608 nPaintStartCol = 0;
609 nPaintEndCol = MAXCOL;
610 nPaintEndRow = MAXROW;
611 nPaintFlags |= PAINT_LEFT | PAINT_SIZE;
613 if (pDestData)
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;
632 OUString aCompare;
633 while ( nEndTab+1 < nTabCount && aDocument.IsScenario(nEndTab+1) )
635 ++nEndTab;
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 );
650 ScRange aMultiRange;
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();
657 if (bRecord)
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 );
664 // Szenarien
665 for (SCTAB i=nTab+1; i<=nEndTab; i++)
667 pUndoDoc->SetScenario( i, true );
668 OUString aComment;
669 Color aColor;
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 ),
684 pUndoDoc, rName ) );
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();
698 else
700 ScopedVclPtrInstance<InfoBox> aBox( GetActiveDialogParent(),
701 ScGlobal::GetRscString( STR_PROTECTIONERR ) );
702 aBox->Execute();
705 else
707 ScopedVclPtrInstance<InfoBox> aBox(GetActiveDialogParent(),
708 ScGlobal::GetRscString( STR_SCENARIO_NOTFOUND ) );
709 aBox->Execute();
712 else
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 )
721 // Undo
722 OUString aOldName;
723 aDocument.GetName( nTab, aOldName );
724 OUString aOldComment;
725 Color aOldColor;
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 ) );
733 // ausfuehren
734 ScDocShellModificator aModificator( *this );
735 aDocument.RenameTab( nTab, rName );
736 aDocument.SetScenarioData( nTab, rComment, rColor, nFlags );
737 PostPaintGridAll();
738 aModificator.SetDocumentModified();
740 if (!aOldName.equals(rName))
741 SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
743 SfxBindings* pBindings = GetViewBindings();
744 if (pBindings)
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 )
752 rMark.MarkToMulti();
753 if (rMark.IsMultiMarked())
755 SCTAB nNewTab = nTab + 1;
756 while (aDocument.IsScenario(nNewTab))
757 ++nNewTab;
759 bool bCopyAll = ( (nFlags & SC_SCENARIO_COPYALL) != 0 );
760 const ScMarkData* pCopyMark = NULL;
761 if (!bCopyAll)
762 pCopyMark = &rMark;
764 ScDocShellModificator aModificator( *this );
766 if (bRecord)
767 aDocument.BeginDrawUndo(); // drawing layer must do its own undo actions
769 if (aDocument.CopyTab( nTab, nNewTab, pCopyMark ))
771 if (bRecord)
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 );
796 if (!bCopyAll)
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 ) );
809 return nNewTab;
812 return nTab;
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
822 ScClipParam aParam;
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 ))
836 OUString aComment;
837 Color aColor;
838 sal_uInt16 nFlags;
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 ) );
856 PostPaintExtras();
857 PostPaintGridAll();
859 return nErrVal;
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();
871 if (bCopy)
873 if (bRecord)
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 ))
880 //! EndDrawUndo?
881 return false;
883 else
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);
892 if (bRecord)
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();
901 if ( bVbaEnabled )
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;
915 OUString sCodeName;
916 OUString sSource;
919 Reference< XNameContainer > xLib;
920 if( xLibContainer.is() )
922 com::sun::star::uno::Any aLibAny = xLibContainer->getByName( aLibName );
923 aLibAny >>= xLib;
925 if( xLib.is() )
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 ) );
938 else
940 if ( aDocument.GetChangeTrack() )
941 return false;
943 if ( nSrcTab<nDestTab && nDestTab!=SC_TAB_APPEND )
944 nDestTab--;
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 );
955 delete pProgress;
956 if (!bDone)
958 return false;
960 else if (bRecord)
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 ) );
971 PostPaintGridAll();
972 PostPaintExtras();
973 aModificator.SetDocumentModified();
974 SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
976 return true;
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())
988 ScRange aRange;
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
992 if (bContinue)
994 aFunc.RepeatDB( pDBData->GetName(), true, true );
995 RefreshPivotTables(aRange);
1000 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */