Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / sc / source / ui / docshell / docsh4.cxx
blob853692cf898e59ba15e713d5c297768b1c1b6bd5
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 <config_features.h>
22 #include <com/sun/star/embed/XEmbeddedObject.hpp>
23 #include <com/sun/star/frame/Desktop.hpp>
24 #include <com/sun/star/frame/XComponentLoader.hpp>
26 using namespace ::com::sun::star;
28 #include <math.h>
30 #include "scitems.hxx"
31 #include <editeng/flstitem.hxx>
32 #include <sfx2/fcontnr.hxx>
33 #include <sfx2/linkmgr.hxx>
34 #include <sfx2/objface.hxx>
35 #include <sfx2/docfile.hxx>
36 #include <svtools/ehdl.hxx>
37 #include <basic/sbxcore.hxx>
38 #include <svtools/sfxecode.hxx>
39 #include <svx/ofaitem.hxx>
40 #include <svl/whiter.hxx>
41 #include <vcl/msgbox.hxx>
42 #include <vcl/waitobj.hxx>
43 #include <svx/dataaccessdescriptor.hxx>
44 #include <svx/drawitem.hxx>
45 #include <svx/fmshell.hxx>
46 #include <svtools/xwindowitem.hxx>
47 #include <svx/svdoole2.hxx>
48 #include <sfx2/passwd.hxx>
49 #include <sfx2/filedlghelper.hxx>
50 #include <sfx2/dispatch.hxx>
51 #include <svl/PasswordHelper.hxx>
52 #include <svl/documentlockfile.hxx>
53 #include <svl/sharecontrolfile.hxx>
54 #include <unotools/securityoptions.hxx>
56 #include <comphelper/processfactory.hxx>
57 #include "docuno.hxx"
59 #include <com/sun/star/sdbc/XResultSet.hpp>
60 #include "docsh.hxx"
61 #include "docshimp.hxx"
62 #include "docfunc.hxx"
63 #include "sc.hrc"
64 #include "stlsheet.hxx"
65 #include "stlpool.hxx"
66 #include "appoptio.hxx"
67 #include "globstr.hrc"
68 #include "global.hxx"
69 #include "dbdocfun.hxx"
70 #include "printfun.hxx"
71 #include "viewdata.hxx"
72 #include "tabvwsh.hxx"
73 #include "impex.hxx"
74 #include "attrib.hxx"
75 #include "undodat.hxx"
76 #include "autostyl.hxx"
77 #include "undocell.hxx"
78 #include "undotab.hxx"
79 #include "inputhdl.hxx"
80 #include "dbdata.hxx"
81 #include "servobj.hxx"
82 #include "rangenam.hxx"
83 #include "scmod.hxx"
84 #include "chgviset.hxx"
85 #include "reffact.hxx"
86 #include "chartlis.hxx"
87 #include "chartpos.hxx"
88 #include "waitoff.hxx"
89 #include "tablink.hxx"
90 #include "drwlayer.hxx"
91 #include "docoptio.hxx"
92 #include "undostyl.hxx"
93 #include "rangeseq.hxx"
94 #include "chgtrack.hxx"
95 #include "printopt.hxx"
96 #include <com/sun/star/document/UpdateDocMode.hpp>
97 #include "scresid.hxx"
98 #include "scabstdlg.hxx"
99 #include "externalrefmgr.hxx"
100 #include "sharedocdlg.hxx"
101 #include "conditio.hxx"
102 #include "sheetevents.hxx"
103 #include "formulacell.hxx"
104 #include <documentlinkmgr.hxx>
105 #include <memory>
106 #include <sfx2/notebookbar/SfxNotebookBar.hxx>
108 void ScDocShell::Execute( SfxRequest& rReq )
110 // SID_SC_RANGE (Range),
111 // SID_SC_CELLTEXT (CellText),
112 // SID_SC_CELLS (Cells) - removed (old Basic)
114 const SfxItemSet* pReqArgs = rReq.GetArgs();
115 SfxBindings* pBindings = GetViewBindings();
116 bool bUndo (aDocument.IsUndoEnabled());
118 sal_uInt16 nSlot = rReq.GetSlot();
119 switch ( nSlot )
121 case SID_SC_SETTEXT:
123 const SfxPoolItem* pColItem;
124 const SfxPoolItem* pRowItem;
125 const SfxPoolItem* pTabItem;
126 const SfxPoolItem* pTextItem;
127 if( pReqArgs && pReqArgs->HasItem( FN_PARAM_1, &pColItem ) &&
128 pReqArgs->HasItem( FN_PARAM_2, &pRowItem ) &&
129 pReqArgs->HasItem( FN_PARAM_3, &pTabItem ) &&
130 pReqArgs->HasItem( SID_SC_SETTEXT, &pTextItem ) )
132 // Parameter sind 1-based !!!
133 SCCOL nCol = static_cast<const SfxInt16Item*>(pColItem)->GetValue() - 1;
134 SCROW nRow = static_cast<const SfxInt32Item*>(pRowItem)->GetValue() - 1;
135 SCTAB nTab = static_cast<const SfxInt16Item*>(pTabItem)->GetValue() - 1;
137 SCTAB nTabCount = aDocument.GetTableCount();
138 if ( ValidCol(nCol) && ValidRow(nRow) && ValidTab(nTab,nTabCount) )
140 if ( aDocument.IsBlockEditable( nTab, nCol,nRow, nCol, nRow ) )
142 OUString aVal = static_cast<const SfxStringItem*>(pTextItem)->GetValue();
143 aDocument.SetString( nCol, nRow, nTab, aVal );
145 PostPaintCell( nCol, nRow, nTab );
146 SetDocumentModified();
148 rReq.Done();
149 break;
151 else // geschuetzte Zelle
153 #if HAVE_FEATURE_SCRIPTING
154 SbxBase::SetError( ERRCODE_SBX_BAD_PARAMETER ); //! welchen Fehler ?
155 #endif
156 break;
160 #if HAVE_FEATURE_SCRIPTING
161 SbxBase::SetError( ERRCODE_SBX_NO_OBJECT );
162 #endif
164 break;
166 case SID_SBA_IMPORT:
168 if (pReqArgs)
170 const SfxPoolItem* pItem;
171 svx::ODataAccessDescriptor aDesc;
172 if ( pReqArgs->GetItemState( nSlot, true, &pItem ) == SfxItemState::SET )
174 uno::Any aAny = static_cast<const SfxUsrAnyItem*>(pItem)->GetValue();
175 uno::Sequence<beans::PropertyValue> aProperties;
176 if ( aAny >>= aProperties )
177 aDesc.initializeFrom( aProperties );
180 OUString sTarget;
181 if ( pReqArgs->GetItemState( FN_PARAM_1, true, &pItem ) == SfxItemState::SET )
182 sTarget = static_cast<const SfxStringItem*>(pItem)->GetValue();
184 bool bIsNewArea = true; // Default sal_True (keine Nachfrage)
185 if ( pReqArgs->GetItemState( FN_PARAM_2, true, &pItem ) == SfxItemState::SET )
186 bIsNewArea = static_cast<const SfxBoolItem*>(pItem)->GetValue();
188 // bei Bedarf neuen Datenbankbereich anlegen
189 bool bMakeArea = false;
190 if (bIsNewArea)
192 ScDBCollection* pDBColl = aDocument.GetDBCollection();
193 if ( !pDBColl || !pDBColl->getNamedDBs().findByUpperName(ScGlobal::pCharClass->uppercase(sTarget)) )
195 ScAddress aPos;
196 if ( aPos.Parse( sTarget, &aDocument, aDocument.GetAddressConvention() ) & ScRefFlags::VALID )
198 bMakeArea = true;
199 if (bUndo)
201 OUString aStrImport = ScGlobal::GetRscString( STR_UNDO_IMPORTDATA );
202 GetUndoManager()->EnterListAction( aStrImport, aStrImport );
205 ScDBData* pDBData = GetDBData( ScRange(aPos), SC_DB_IMPORT, SC_DBSEL_KEEP );
206 OSL_ENSURE(pDBData, "kann DB-Daten nicht anlegen");
207 sTarget = pDBData->GetName();
212 // nachfragen, bevor alter DB-Bereich ueberschrieben wird
213 bool bDo = true;
214 if (!bIsNewArea)
216 OUString aTemplate = ScGlobal::GetRscString( STR_IMPORT_REPLACE );
217 OUString aMessage = aTemplate.getToken( 0, '#' );
218 aMessage += sTarget;
219 aMessage += aTemplate.getToken( 1, '#' );
221 ScopedVclPtrInstance< QueryBox > aBox( nullptr, WinBits(WB_YES_NO | WB_DEF_YES), aMessage );
222 bDo = ( aBox->Execute() == RET_YES );
225 if (bDo)
227 ScDBDocFunc(*this).UpdateImport( sTarget, aDesc );
228 rReq.Done();
230 // UpdateImport aktualisiert auch die internen Operationen
232 else
233 rReq.Ignore();
235 if ( bMakeArea && bUndo)
236 GetUndoManager()->LeaveListAction();
238 else
240 OSL_FAIL( "arguments expected" );
243 break;
245 case SID_CHART_SOURCE:
246 case SID_CHART_ADDSOURCE:
247 if (pReqArgs)
249 ScDocument& rDoc = GetDocument();
250 const SfxPoolItem* pItem;
251 OUString aChartName, aRangeName;
253 ScRange aSingleRange;
254 ScRangeListRef aRangeListRef;
255 bool bMultiRange = false;
257 bool bColHeaders = true;
258 bool bRowHeaders = true;
259 bool bColInit = false;
260 bool bRowInit = false;
261 bool bAddRange = (nSlot == SID_CHART_ADDSOURCE);
263 if( pReqArgs->HasItem( SID_CHART_NAME, &pItem ) )
264 aChartName = static_cast<const SfxStringItem*>(pItem)->GetValue();
266 if( pReqArgs->HasItem( SID_CHART_SOURCE, &pItem ) )
267 aRangeName = static_cast<const SfxStringItem*>(pItem)->GetValue();
269 if( pReqArgs->HasItem( FN_PARAM_1, &pItem ) )
271 bColHeaders = static_cast<const SfxBoolItem*>(pItem)->GetValue();
272 bColInit = true;
274 if( pReqArgs->HasItem( FN_PARAM_2, &pItem ) )
276 bRowHeaders = static_cast<const SfxBoolItem*>(pItem)->GetValue();
277 bRowInit = true;
280 ScAddress::Details aDetails(rDoc.GetAddressConvention(), 0, 0);
281 bool bValid = (aSingleRange.ParseAny(aRangeName, &rDoc, aDetails) & ScRefFlags::VALID) == ScRefFlags::ZERO;
282 if (!bValid)
284 aRangeListRef = new ScRangeList;
285 aRangeListRef->Parse( aRangeName, &rDoc );
286 if ( !aRangeListRef->empty() )
288 bMultiRange = true;
289 aSingleRange = *aRangeListRef->front(); // fuer Header
290 bValid = true;
292 else
293 aRangeListRef.Clear();
296 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
297 if (pViewSh && bValid && !aChartName.isEmpty() )
299 vcl::Window* pParent = pViewSh->GetDialogParent();
301 SCCOL nCol1 = aSingleRange.aStart.Col();
302 SCROW nRow1 = aSingleRange.aStart.Row();
303 SCCOL nCol2 = aSingleRange.aEnd.Col();
304 SCROW nRow2 = aSingleRange.aEnd.Row();
305 SCTAB nTab = aSingleRange.aStart.Tab();
307 //! immer oder gar nicht begrenzen ???
308 if (!bMultiRange)
309 aDocument.LimitChartArea( nTab, nCol1,nRow1, nCol2,nRow2 );
311 // Dialog fuer Spalten/Zeilenkoepfe
312 bool bOk = true;
313 if ( !bAddRange && ( !bColInit || !bRowInit ) )
315 ScChartPositioner aChartPositioner( &aDocument, nTab, nCol1,nRow1, nCol2,nRow2 );
316 if (!bColInit)
317 bColHeaders = aChartPositioner.HasColHeaders();
318 if (!bRowInit)
319 bRowHeaders = aChartPositioner.HasRowHeaders();
321 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
322 OSL_ENSURE(pFact, "ScAbstractFactory create fail!");
324 std::unique_ptr<AbstractScColRowLabelDlg> pDlg(pFact->CreateScColRowLabelDlg(pParent, bRowHeaders, bColHeaders));
325 OSL_ENSURE(pDlg, "Dialog create fail!");
326 if ( pDlg->Execute() == RET_OK )
328 bColHeaders = pDlg->IsRow();
329 bRowHeaders = pDlg->IsCol();
331 rReq.AppendItem(SfxBoolItem(FN_PARAM_1, bColHeaders));
332 rReq.AppendItem(SfxBoolItem(FN_PARAM_2, bRowHeaders));
334 else
335 bOk = false;
338 if (bOk) // ausfuehren
340 if (bMultiRange)
342 if (bUndo)
344 GetUndoManager()->AddUndoAction(
345 new ScUndoChartData( this, aChartName, aRangeListRef,
346 bColHeaders, bRowHeaders, bAddRange ) );
348 aDocument.UpdateChartArea( aChartName, aRangeListRef,
349 bColHeaders, bRowHeaders, bAddRange );
351 else
353 ScRange aNewRange( nCol1,nRow1,nTab, nCol2,nRow2,nTab );
354 if (bUndo)
356 GetUndoManager()->AddUndoAction(
357 new ScUndoChartData( this, aChartName, aNewRange,
358 bColHeaders, bRowHeaders, bAddRange ) );
360 aDocument.UpdateChartArea( aChartName, aNewRange,
361 bColHeaders, bRowHeaders, bAddRange );
365 else
367 OSL_FAIL("UpdateChartArea: keine ViewShell oder falsche Daten");
369 rReq.Done();
371 else
373 OSL_FAIL("SID_CHART_SOURCE ohne Argumente");
375 break;
377 case FID_AUTO_CALC:
379 bool bNewVal;
380 const SfxPoolItem* pItem;
381 if ( pReqArgs && SfxItemState::SET == pReqArgs->GetItemState( nSlot, true, &pItem ) )
382 bNewVal = static_cast<const SfxBoolItem*>(pItem)->GetValue();
383 else
384 bNewVal = !aDocument.GetAutoCalc(); // Toggle fuer Menue
385 aDocument.SetAutoCalc( bNewVal );
386 SetDocumentModified();
387 if (pBindings)
389 pBindings->Invalidate( FID_AUTO_CALC );
391 rReq.AppendItem( SfxBoolItem( FID_AUTO_CALC, bNewVal ) );
392 rReq.Done();
394 break;
395 case FID_RECALC:
396 DoRecalc( rReq.IsAPI() );
397 rReq.Done();
398 break;
399 case FID_HARD_RECALC:
400 DoHardRecalc( rReq.IsAPI() );
401 rReq.Done();
402 break;
403 case SID_UPDATETABLINKS:
405 comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = getEmbeddedObjectContainer();
406 rEmbeddedObjectContainer.setUserAllowsLinkUpdate(true);
408 ScDocument& rDoc = GetDocument();
410 ScLkUpdMode nSet = rDoc.GetLinkMode();
412 sal_uInt16 nDlgRet=RET_NO;
413 if(nSet==LM_UNKNOWN)
415 ScAppOptions aAppOptions=SC_MOD()->GetAppOptions();
416 nSet=aAppOptions.GetLinkMode();
419 if (nCanUpdate == css::document::UpdateDocMode::NO_UPDATE)
420 nSet = LM_NEVER;
421 else if (nCanUpdate == css::document::UpdateDocMode::FULL_UPDATE)
422 nSet = LM_ALWAYS;
424 if (nSet == LM_ALWAYS
425 && !(SvtSecurityOptions()
426 .isTrustedLocationUriForUpdatingLinks(
427 GetMedium() == nullptr
428 ? OUString() : GetMedium()->GetName())))
430 nSet = LM_ON_DEMAND;
432 if (nCanUpdate == css::document::UpdateDocMode::QUIET_UPDATE
433 && nSet == LM_ON_DEMAND)
435 nSet = LM_NEVER;
438 if(nSet==LM_ON_DEMAND)
440 ScopedVclPtrInstance<QueryBox> aBox( GetActiveDialogParent(), WinBits(WB_YES_NO | WB_DEF_YES),
441 ScGlobal::GetRscString(STR_RELOAD_TABLES) );
443 nDlgRet=aBox->Execute();
446 if (nDlgRet == RET_YES || nSet==LM_ALWAYS)
448 ReloadTabLinks();
449 aDocument.UpdateExternalRefLinks(GetActiveDialogParent());
451 bool bAnyDde = aDocument.GetDocLinkManager().updateDdeOrOleLinks(GetActiveDialogParent());
453 if (bAnyDde)
455 // Formeln berechnen und painten wie im TrackTimeHdl
456 aDocument.TrackFormulas();
457 Broadcast(SfxSimpleHint(FID_DATACHANGED));
459 // wenn FID_DATACHANGED irgendwann mal asynchron werden sollte
460 // (z.B. mit Invalidate am Window), muss hier ein Update erzwungen werden.
463 aDocument.UpdateAreaLinks();
465 //! Test, ob Fehler
466 rReq.Done();
468 else
470 rEmbeddedObjectContainer.setUserAllowsLinkUpdate(false);
471 rReq.Ignore();
474 break;
476 case SID_REIMPORT_AFTER_LOAD:
478 // wird nach dem Laden aufgerufen, wenn DB-Bereiche mit
479 // weggelassenen Daten enthalten sind
481 bool bDone = false;
482 ScDBCollection* pDBColl = aDocument.GetDBCollection();
484 if ((nCanUpdate != css::document::UpdateDocMode::NO_UPDATE) &&
485 (nCanUpdate != css::document::UpdateDocMode::QUIET_UPDATE))
487 ScRange aRange;
488 ScTabViewShell* pViewSh = GetBestViewShell();
489 OSL_ENSURE(pViewSh,"SID_REIMPORT_AFTER_LOAD: keine View");
490 if (pViewSh && pDBColl)
492 ScopedVclPtrInstance<QueryBox> aBox( GetActiveDialogParent(), WinBits(WB_YES_NO | WB_DEF_YES),
493 ScGlobal::GetRscString(STR_REIMPORT_AFTER_LOAD) );
494 if (aBox->Execute() == RET_YES)
496 ScDBCollection::NamedDBs& rDBs = pDBColl->getNamedDBs();
497 ScDBCollection::NamedDBs::iterator itr = rDBs.begin(), itrEnd = rDBs.end();
498 for (; itr != itrEnd; ++itr)
500 ScDBData& rDBData = **itr;
501 if ( rDBData.IsStripData() &&
502 rDBData.HasImportParam() && !rDBData.HasImportSelection() )
504 rDBData.GetArea(aRange);
505 pViewSh->MarkRange(aRange);
507 // Import und interne Operationen wie SID_REFRESH_DBAREA
508 // (Abfrage auf Import hier nicht noetig)
510 ScImportParam aImportParam;
511 rDBData.GetImportParam( aImportParam );
512 bool bContinue = pViewSh->ImportData( aImportParam );
513 rDBData.SetImportParam( aImportParam );
515 // markieren (Groesse kann sich geaendert haben)
516 rDBData.GetArea(aRange);
517 pViewSh->MarkRange(aRange);
519 if ( bContinue ) // Fehler beim Import -> Abbruch
521 // interne Operationen, wenn welche gespeichert
523 if ( rDBData.HasQueryParam() || rDBData.HasSortParam() ||
524 rDBData.HasSubTotalParam() )
525 pViewSh->RepeatDB();
527 // Pivottabellen die den Bereich als Quelldaten haben
529 RefreshPivotTables(aRange);
533 bDone = true;
538 if ( !bDone && pDBColl )
540 // wenn nicht, dann aber die abhaengigen Formeln updaten
541 //! auch fuer einzelne Bereiche, die nicht aktualisiert werden koennen
543 aDocument.CalcAll(); //! nur die abhaengigen
544 PostDataChanged();
547 if (bDone)
548 rReq.Done();
549 else
550 rReq.Ignore();
552 break;
554 case SID_AUTO_STYLE:
555 OSL_FAIL("use ScAutoStyleHint instead of SID_AUTO_STYLE");
556 break;
558 case SID_GET_COLORLIST:
560 const SvxColorListItem* pColItem = static_cast<const SvxColorListItem*>(GetItem(SID_COLOR_TABLE));
561 XColorListRef pList = pColItem->GetColorList();
562 rReq.SetReturnValue(OfaRefItem<XColorList>(SID_GET_COLORLIST, pList));
564 break;
566 case FID_CHG_RECORD:
568 ScDocument& rDoc = GetDocument();
569 // get argument (recorded macro)
570 const SfxBoolItem* pItem = rReq.GetArg<SfxBoolItem>(FID_CHG_RECORD);
571 bool bDo = true;
573 // xmlsec05/06:
574 // getting real parent window when called from Security-Options TP
575 vcl::Window* pParent = nullptr;
576 const SfxPoolItem* pParentItem;
577 if( pReqArgs && SfxItemState::SET == pReqArgs->GetItemState( SID_ATTR_XWINDOW, false, &pParentItem ) )
578 pParent = static_cast<const XWindowItem*>( pParentItem )->GetWindowPtr();
580 // desired state
581 ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
582 bool bActivateTracking = (pChangeTrack == nullptr); // toggle
583 if ( pItem )
584 bActivateTracking = pItem->GetValue(); // from argument
586 if ( !bActivateTracking )
588 if ( !pItem )
590 // no dialog on playing the macro
591 ScopedVclPtrInstance<WarningBox> aBox( pParent ? pParent : GetActiveDialogParent(),
592 WinBits(WB_YES_NO | WB_DEF_NO),
593 ScGlobal::GetRscString( STR_END_REDLINING ) );
594 bDo = ( aBox->Execute() == RET_YES );
597 if ( bDo )
599 if (pChangeTrack)
601 if ( pChangeTrack->IsProtected() )
602 bDo = ExecuteChangeProtectionDialog( nullptr );
604 if ( bDo )
606 rDoc.EndChangeTracking();
607 PostPaintGridAll();
611 else
613 rDoc.StartChangeTracking();
614 ScChangeViewSettings aChangeViewSet;
615 aChangeViewSet.SetShowChanges(true);
616 rDoc.SetChangeViewSettings(aChangeViewSet);
619 if ( bDo )
621 UpdateAcceptChangesDialog();
623 // Slots invalidieren
624 if (pBindings)
625 pBindings->InvalidateAll(false);
626 if ( !pItem )
627 rReq.AppendItem( SfxBoolItem( FID_CHG_RECORD, bActivateTracking ) );
628 rReq.Done();
630 else
631 rReq.Ignore();
633 break;
635 case SID_CHG_PROTECT :
637 vcl::Window* pParent = nullptr;
638 const SfxPoolItem* pParentItem;
639 if( pReqArgs && SfxItemState::SET == pReqArgs->GetItemState( SID_ATTR_XWINDOW, false, &pParentItem ) )
640 pParent = static_cast<const XWindowItem*>( pParentItem )->GetWindowPtr();
641 if ( ExecuteChangeProtectionDialog( pParent ) )
643 rReq.Done();
644 SetDocumentModified();
646 else
647 rReq.Ignore();
649 break;
651 case SID_DOCUMENT_MERGE:
652 case SID_DOCUMENT_COMPARE:
654 bool bDo = true;
655 ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack();
656 if ( pChangeTrack && !pImpl->bIgnoreLostRedliningWarning )
658 if ( nSlot == SID_DOCUMENT_COMPARE )
659 { //! old changes trace will be lost
660 ScopedVclPtrInstance<WarningBox> aBox( GetActiveDialogParent(),
661 WinBits(WB_YES_NO | WB_DEF_NO),
662 ScGlobal::GetRscString( STR_END_REDLINING ) );
663 if( aBox->Execute() == RET_YES )
664 bDo = ExecuteChangeProtectionDialog( nullptr, true );
665 else
666 bDo = false;
668 else // merge might reject some actions
669 bDo = ExecuteChangeProtectionDialog( nullptr, true );
671 if ( !bDo )
673 rReq.Ignore();
674 break;
676 SfxApplication* pApp = SfxGetpApp();
677 const SfxPoolItem* pItem;
678 const SfxStringItem* pStringItem(nullptr);
679 SfxMedium* pMed = nullptr;
680 if (pReqArgs && pReqArgs->GetItemState(SID_FILE_NAME, true, &pItem) == SfxItemState::SET)
682 pStringItem = dynamic_cast<const SfxStringItem*>(pItem);
684 if (pStringItem)
686 OUString aFileName = pStringItem->GetValue();
688 OUString aFilterName;
689 pStringItem = nullptr;
690 if (pReqArgs->GetItemState(SID_FILTER_NAME, true, &pItem) == SfxItemState::SET)
691 pStringItem = dynamic_cast<const SfxStringItem*>(pItem);
692 if (pStringItem)
694 aFilterName = pStringItem->GetValue();
696 OUString aOptions;
697 pStringItem = nullptr;
698 if (pReqArgs->GetItemState(SID_FILE_FILTEROPTIONS, true, &pItem) == SfxItemState::SET)
699 pStringItem = dynamic_cast<const SfxStringItem*>(pItem);
700 if (pStringItem)
702 aOptions = pStringItem->GetValue();
704 short nVersion = 0;
705 const SfxInt16Item* pInt16Item(nullptr);
706 if (pReqArgs->GetItemState(SID_VERSION, true, &pItem) == SfxItemState::SET)
707 pInt16Item = dynamic_cast<const SfxInt16Item*>(pItem);
708 if (pInt16Item)
710 nVersion = pInt16Item->GetValue();
713 // kein Filter angegeben -> Detection
714 if (aFilterName.isEmpty())
715 ScDocumentLoader::GetFilterName( aFileName, aFilterName, aOptions, true, false );
717 // filter name from dialog contains application prefix,
718 // GetFilter needs name without the prefix.
719 ScDocumentLoader::RemoveAppPrefix( aFilterName );
721 std::shared_ptr<const SfxFilter> pFilter = ScDocShell::Factory().GetFilterContainer()->GetFilter4FilterName( aFilterName );
722 SfxItemSet* pSet = new SfxAllItemSet( pApp->GetPool() );
723 if (!aOptions.isEmpty())
724 pSet->Put( SfxStringItem( SID_FILE_FILTEROPTIONS, aOptions ) );
725 if ( nVersion != 0 )
726 pSet->Put( SfxInt16Item( SID_VERSION, nVersion ) );
727 pMed = new SfxMedium( aFileName, STREAM_STD_READ, pFilter, pSet );
729 else
731 // start file dialog asynchronous
732 pImpl->bIgnoreLostRedliningWarning = true;
733 delete pImpl->pRequest;
734 pImpl->pRequest = new SfxRequest( rReq );
735 delete pImpl->pDocInserter;
736 pImpl->pDocInserter = new ::sfx2::DocumentInserter(
737 OUString::createFromAscii( ScDocShell::Factory().GetShortName() ), false );
738 pImpl->pDocInserter->StartExecuteModal( LINK( this, ScDocShell, DialogClosedHdl ) );
739 return ;
742 if ( pMed ) // nun wirklich ausfuehren...
744 SfxErrorContext aEc( ERRCTX_SFX_OPENDOC, pMed->GetName() );
746 // pOtherDocSh->DoClose() will be called explicitly later, but it is still more safe to use SfxObjectShellLock here
747 ScDocShell* pOtherDocSh = new ScDocShell;
748 SfxObjectShellLock aDocShTablesRef = pOtherDocSh;
749 pOtherDocSh->DoLoad( pMed );
750 sal_uLong nErr = pOtherDocSh->GetErrorCode();
751 if (nErr)
752 ErrorHandler::HandleError( nErr ); // auch Warnings
754 if ( !pOtherDocSh->GetError() ) // nur Errors
756 bool bHadTrack = ( aDocument.GetChangeTrack() != nullptr );
757 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
758 sal_uLong nStart = 0;
759 if ( nSlot == SID_DOCUMENT_MERGE && pChangeTrack )
761 nStart = pChangeTrack->GetActionMax() + 1;
763 #endif
764 if ( nSlot == SID_DOCUMENT_COMPARE )
765 CompareDocument( pOtherDocSh->GetDocument() );
766 else
767 MergeDocument( pOtherDocSh->GetDocument() );
769 // show "accept changes" dialog
770 //! get view for this document!
771 if ( !IsDocShared() )
773 SfxViewFrame* pViewFrm = SfxViewFrame::Current();
774 if ( pViewFrm )
776 pViewFrm->ShowChildWindow( ScAcceptChgDlgWrapper::GetChildWindowId() ); //@51669
778 if ( pBindings )
780 pBindings->Invalidate( FID_CHG_ACCEPT );
784 rReq.SetReturnValue( SfxInt32Item( nSlot, 0 ) ); //! ???????
785 rReq.Done();
787 if (!bHadTrack) // neu eingeschaltet -> auch anzeigen
789 ScChangeViewSettings* pOldSet = aDocument.GetChangeViewSettings();
790 if ( !pOldSet || !pOldSet->ShowChanges() )
792 ScChangeViewSettings aChangeViewSet;
793 aChangeViewSet.SetShowChanges(true);
794 aDocument.SetChangeViewSettings(aChangeViewSet);
797 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
798 else if ( nSlot == SID_DOCUMENT_MERGE && IsDocShared() && pChangeTrack )
800 sal_uLong nEnd = pChangeTrack->GetActionMax();
801 if ( nEnd >= nStart )
803 // only show changes from merged document
804 ScChangeViewSettings aChangeViewSet;
805 aChangeViewSet.SetShowChanges( true );
806 aChangeViewSet.SetShowAccepted( true );
807 aChangeViewSet.SetHasActionRange();
808 aChangeViewSet.SetTheActionRange( nStart, nEnd );
809 aDocument.SetChangeViewSettings( aChangeViewSet );
811 // update view
812 PostPaintExtras();
813 PostPaintGridAll();
816 #endif
818 pOtherDocSh->DoClose(); // delete passiert mit der Ref
821 break;
823 case SID_DELETE_SCENARIO:
824 if (pReqArgs)
826 const SfxPoolItem* pItem;
827 if ( pReqArgs->GetItemState( nSlot, true, &pItem ) == SfxItemState::SET )
829 if (const SfxStringItem* pStringItem = dynamic_cast<const SfxStringItem*>(pItem))
831 OUString aName = pStringItem->GetValue();
832 SCTAB nTab;
833 if (aDocument.GetTable( aName, nTab ))
835 // DeleteTable von viewfunc nach docfunc verschieben!
837 ScTabViewShell* pSh = GetBestViewShell();
838 if ( pSh )
840 //! SetTabNo in DeleteTable weglassen?
841 SCTAB nDispTab = pSh->GetViewData().GetTabNo();
842 pSh->DeleteTable( nTab );
843 pSh->SetTabNo(nDispTab);
844 rReq.Done();
850 break;
852 case SID_EDIT_SCENARIO:
854 const SfxPoolItem* pItem;
855 if ( pReqArgs->GetItemState( nSlot, true, &pItem ) == SfxItemState::SET )
857 if (const SfxStringItem* pStringItem = dynamic_cast<const SfxStringItem*>(pItem))
859 OUString aName = pStringItem->GetValue();
860 SCTAB nTab;
861 if (aDocument.GetTable( aName, nTab ))
863 if (aDocument.IsScenario(nTab))
865 OUString aComment;
866 Color aColor;
867 sal_uInt16 nFlags;
868 aDocument.GetScenarioData( nTab, aComment, aColor, nFlags );
870 // Determine if the Sheet that the Scenario was created on
871 // is protected. But first we need to find that Sheet.
872 // Rewind back to the actual sheet.
873 SCTAB nActualTab = nTab;
876 nActualTab--;
878 while(aDocument.IsScenario(nActualTab));
879 bool bSheetProtected = aDocument.IsTabProtected(nActualTab);
881 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
882 OSL_ENSURE(pFact, "ScAbstractFactory create fail!");
884 std::unique_ptr<AbstractScNewScenarioDlg> pNewDlg(pFact->CreateScNewScenarioDlg(GetActiveDialogParent(), aName, true, bSheetProtected));
885 OSL_ENSURE(pNewDlg, "Dialog create fail!");
886 pNewDlg->SetScenarioData( aName, aComment, aColor, nFlags );
887 if ( pNewDlg->Execute() == RET_OK )
889 pNewDlg->GetScenarioData( aName, aComment, aColor, nFlags );
890 ModifyScenario( nTab, aName, aComment, aColor, nFlags );
891 rReq.Done();
898 break;
900 case SID_ATTR_YEAR2000 :
902 const SfxPoolItem* pItem;
903 if ( pReqArgs->GetItemState( nSlot, true, &pItem ) == SfxItemState::SET )
905 if (const SfxUInt16Item* pInt16Item = dynamic_cast<const SfxUInt16Item*>(pItem))
907 sal_uInt16 nY2k = pInt16Item->GetValue();
908 // immer an den DocOptions setzen, damit das auch fuer SO50
909 // gespeichert wird (und alle Abfragen bisher auch darauf laufen).
910 // SetDocOptions propagiert das an den NumberFormatter
911 ScDocOptions aDocOpt( aDocument.GetDocOptions() );
912 aDocOpt.SetYear2000( nY2k );
913 aDocument.SetDocOptions( aDocOpt );
914 // die FormShell soll es mitbekommen
915 ScTabViewShell* pSh = GetBestViewShell();
916 if ( pSh )
918 FmFormShell* pFSh = pSh->GetFormShell();
919 if ( pFSh )
920 pFSh->SetY2KState( nY2k );
925 break;
927 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
928 case SID_SHARE_DOC:
930 ScViewData* pViewData = GetViewData();
931 if ( !pViewData )
933 rReq.Ignore();
934 break;
937 ScopedVclPtrInstance< ScShareDocumentDlg > aDlg( GetActiveDialogParent(), pViewData );
938 if ( aDlg->Execute() == RET_OK )
940 bool bSetShared = aDlg->IsShareDocumentChecked();
941 if ( bSetShared != static_cast< bool >( IsDocShared() ) )
943 if ( bSetShared )
945 bool bContinue = true;
946 if ( HasName() )
948 ScopedVclPtrInstance<QueryBox> aBox(
949 GetActiveDialogParent(),
950 WinBits( WB_YES_NO | WB_DEF_YES ),
951 ScGlobal::GetRscString( STR_DOC_WILLBESAVED ) );
952 if ( aBox->Execute() == RET_NO )
954 bContinue = false;
957 if ( bContinue )
959 EnableSharedSettings( true );
961 SC_MOD()->SetInSharedDocSaving( true );
962 if ( !SwitchToShared( true, true ) )
964 // TODO/LATER: what should be done in case the switch has failed?
965 // for example in case the user has cancelled the saveAs operation
968 SC_MOD()->SetInSharedDocSaving( false );
970 InvalidateName();
971 GetUndoManager()->Clear();
973 ScTabView* pTabView = dynamic_cast< ScTabView* >( pViewData->GetView() );
974 if ( pTabView )
976 pTabView->UpdateLayerLocks();
980 else
982 uno::Reference< frame::XModel > xModel;
985 // load shared file
986 xModel.set( LoadSharedDocument(), uno::UNO_QUERY_THROW );
987 uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY_THROW );
989 // check if shared flag is set in shared file
990 bool bShared = false;
991 ScModelObj* pDocObj = ScModelObj::getImplementation( xModel );
992 if ( pDocObj )
994 ScDocShell* pDocShell = dynamic_cast< ScDocShell* >( pDocObj->GetEmbeddedObject() );
995 if ( pDocShell )
997 bShared = pDocShell->HasSharedXMLFlagSet();
1001 // #i87870# check if shared status was disabled and enabled again
1002 bool bOwnEntry = false;
1005 ::svt::ShareControlFile aControlFile( GetSharedFileURL() );
1006 bOwnEntry = aControlFile.HasOwnEntry();
1008 catch ( uno::Exception& )
1012 if ( bShared && bOwnEntry )
1014 uno::Reference< frame::XStorable > xStorable( xModel, uno::UNO_QUERY_THROW );
1015 if ( xStorable->isReadonly() )
1017 xCloseable->close( true );
1019 OUString aUserName( ScGlobal::GetRscString( STR_UNKNOWN_USER ) );
1022 ::svt::DocumentLockFile aLockFile( GetSharedFileURL() );
1023 LockFileEntry aData = aLockFile.GetLockData();
1024 if ( !aData[LockFileComponent::OOOUSERNAME].isEmpty() )
1026 aUserName = aData[LockFileComponent::OOOUSERNAME];
1028 else if ( !aData[LockFileComponent::SYSUSERNAME].isEmpty() )
1030 aUserName = aData[LockFileComponent::SYSUSERNAME];
1033 catch ( uno::Exception& )
1036 OUString aMessage( ScGlobal::GetRscString( STR_FILE_LOCKED_TRY_LATER ) );
1037 aMessage = aMessage.replaceFirst( "%1", aUserName );
1039 ScopedVclPtrInstance< WarningBox > aBox( GetActiveDialogParent(), WinBits( WB_OK ), aMessage );
1040 aBox->Execute();
1042 else
1044 ScopedVclPtrInstance<WarningBox> aBox(
1045 GetActiveDialogParent(),
1046 WinBits( WB_YES_NO | WB_DEF_YES ),
1047 ScGlobal::GetRscString( STR_DOC_DISABLESHARED ) );
1048 if ( aBox->Execute() == RET_YES )
1050 xCloseable->close( true );
1052 if ( !SwitchToShared( false, true ) )
1054 // TODO/LATER: what should be done in case the switch has failed?
1055 // for example in case the user has cancelled the saveAs operation
1058 EnableSharedSettings( false );
1060 if ( pBindings )
1062 pBindings->ExecuteSynchron( SID_SAVEDOC );
1065 ScTabView* pTabView = dynamic_cast< ScTabView* >( pViewData->GetView() );
1066 if ( pTabView )
1068 pTabView->UpdateLayerLocks();
1071 else
1073 xCloseable->close( true );
1077 else
1079 xCloseable->close( true );
1080 ScopedVclPtrInstance<WarningBox> aBox( GetActiveDialogParent(), WinBits( WB_OK ),
1081 ScGlobal::GetRscString( STR_DOC_NOLONGERSHARED ) );
1082 aBox->Execute();
1085 catch ( uno::Exception& )
1087 OSL_FAIL( "SID_SHARE_DOC: caught exception\n" );
1088 SC_MOD()->SetInSharedDocSaving( false );
1092 uno::Reference< util::XCloseable > xClose( xModel, uno::UNO_QUERY_THROW );
1093 xClose->close( true );
1095 catch ( uno::Exception& )
1102 rReq.Done();
1104 break;
1105 #endif
1106 case SID_OPEN_CALC:
1108 SfxStringItem aApp(SID_DOC_SERVICE, OUString("com.sun.star.sheet.SpreadsheetDocument"));
1109 SfxStringItem aTarget(SID_TARGETNAME, OUString("_blank"));
1110 GetViewData()->GetDispatcher().ExecuteList(
1111 SID_OPENDOC, SfxCallMode::API|SfxCallMode::SYNCHRON,
1112 { &aApp, &aTarget });
1114 break;
1115 case SID_NOTEBOOKBAR:
1117 if (pBindings)
1118 sfx2::SfxNotebookBar::ExecMethod(*pBindings);
1120 break;
1121 default:
1123 // kleiner (?) Hack -> forward der Slots an TabViewShell
1124 ScTabViewShell* pSh = GetBestViewShell();
1125 if ( pSh )
1126 pSh->Execute( rReq );
1127 #if HAVE_FEATURE_SCRIPTING
1128 else
1129 SbxBase::SetError( ERRCODE_SBX_NO_ACTIVE_OBJECT );
1130 #endif
1135 void UpdateAcceptChangesDialog()
1137 // update "accept changes" dialog
1138 //! notify all views
1139 SfxViewFrame* pViewFrm = SfxViewFrame::Current();
1140 if ( pViewFrm && pViewFrm->HasChildWindow( FID_CHG_ACCEPT ) )
1142 SfxChildWindow* pChild = pViewFrm->GetChildWindow( FID_CHG_ACCEPT );
1143 if ( pChild )
1144 static_cast<ScAcceptChgDlgWrapper*>(pChild)->ReInitDlg();
1148 bool ScDocShell::ExecuteChangeProtectionDialog( vcl::Window* _pParent, bool bJustQueryIfProtected )
1150 bool bDone = false;
1151 ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack();
1152 if ( pChangeTrack )
1154 bool bProtected = pChangeTrack->IsProtected();
1155 if ( bJustQueryIfProtected && !bProtected )
1156 return true;
1158 OUString aTitle( ScResId( bProtected ? SCSTR_CHG_UNPROTECT : SCSTR_CHG_PROTECT ) );
1159 OUString aText( ScResId( SCSTR_PASSWORD ) );
1160 OUString aPassword;
1162 ScopedVclPtrInstance<SfxPasswordDialog> pDlg(
1163 _pParent ? _pParent : GetActiveDialogParent(), &aText );
1164 pDlg->SetText( aTitle );
1165 pDlg->SetMinLen( 1 );
1166 pDlg->SetHelpId( GetStaticInterface()->GetSlot(SID_CHG_PROTECT)->GetCommand() );
1167 pDlg->SetEditHelpId( HID_CHG_PROTECT );
1168 if ( !bProtected )
1169 pDlg->ShowExtras( SfxShowExtras::CONFIRM );
1170 if ( pDlg->Execute() == RET_OK )
1171 aPassword = pDlg->GetPassword();
1172 pDlg.disposeAndClear();
1174 if (!aPassword.isEmpty())
1176 if ( bProtected )
1178 if ( SvPasswordHelper::CompareHashPassword(pChangeTrack->GetProtection(), aPassword) )
1180 if ( bJustQueryIfProtected )
1181 bDone = true;
1182 else
1183 pChangeTrack->SetProtection(
1184 css::uno::Sequence< sal_Int8 > (0) );
1186 else
1188 ScopedVclPtrInstance<InfoBox> aBox( GetActiveDialogParent(),
1189 OUString( ScResId( SCSTR_WRONGPASSWORD ) ) );
1190 aBox->Execute();
1193 else
1195 css::uno::Sequence< sal_Int8 > aPass;
1196 SvPasswordHelper::GetHashPassword( aPass, aPassword );
1197 pChangeTrack->SetProtection( aPass );
1199 if ( bProtected != pChangeTrack->IsProtected() )
1201 UpdateAcceptChangesDialog();
1202 bDone = true;
1206 else if ( bJustQueryIfProtected )
1207 bDone = true;
1208 return bDone;
1211 void ScDocShell::DoRecalc( bool bApi )
1213 bool bDone = false;
1214 ScTabViewShell* pSh = GetBestViewShell();
1215 ScInputHandler* pHdl = ( pSh ? SC_MOD()->GetInputHdl( pSh ) : nullptr );
1216 if ( pSh )
1218 if ( pHdl && pHdl->IsInputMode() && pHdl->IsFormulaMode() && !bApi )
1220 pHdl->FormulaPreview(); // Teilergebnis als QuickHelp
1221 bDone = true;
1223 else
1225 ScTabView::UpdateInputLine(); // InputEnterHandler
1226 pSh->UpdateInputHandler();
1229 if (!bDone) // sonst Dokument neu berechnen
1231 WaitObject aWaitObj( GetActiveDialogParent() );
1232 if ( pHdl )
1234 // tdf97897 set current cell to Dirty to force recalculation of cell
1235 ScFormulaCell* pFC = aDocument.GetFormulaCell( pHdl->GetCursorPos());
1236 if (pFC)
1237 pFC->SetDirty();
1239 aDocument.CalcFormulaTree();
1240 if ( pSh )
1241 pSh->UpdateCharts(true);
1243 aDocument.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) );
1245 // Wenn es Charts gibt, dann alles painten, damit nicht
1246 // PostDataChanged und die Charts nacheinander kommen und Teile
1247 // doppelt gepainted werden.
1249 ScChartListenerCollection* pCharts = aDocument.GetChartListenerCollection();
1250 if ( pCharts && pCharts->hasListeners() )
1251 PostPaintGridAll();
1252 else
1253 PostDataChanged();
1257 void ScDocShell::DoHardRecalc( bool /* bApi */ )
1259 WaitObject aWaitObj( GetActiveDialogParent() );
1260 ScTabViewShell* pSh = GetBestViewShell();
1261 if ( pSh )
1263 ScTabView::UpdateInputLine(); // InputEnterHandler
1264 pSh->UpdateInputHandler();
1266 aDocument.CalcAll();
1267 GetDocFunc().DetectiveRefresh(); // erzeugt eigenes Undo
1268 if ( pSh )
1269 pSh->UpdateCharts(true);
1271 // set notification flags for "calculate" event (used in SFX_HINT_DATACHANGED broadcast)
1272 // (might check for the presence of any formulas on each sheet)
1273 SCTAB nTabCount = aDocument.GetTableCount();
1274 if (aDocument.HasAnySheetEventScript( ScSheetEventId::CALCULATE, true )) // search also for VBA handler
1275 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
1276 aDocument.SetCalcNotification(nTab);
1278 // CalcAll doesn't broadcast value changes, so SC_HINT_CALCALL is broadcasted globally
1279 // in addition to SFX_HINT_DATACHANGED.
1280 aDocument.BroadcastUno( SfxSimpleHint( SC_HINT_CALCALL ) );
1281 aDocument.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) );
1283 // use hard recalc also to disable stream-copying of all sheets
1284 // (somewhat consistent with charts)
1285 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
1286 if (aDocument.IsStreamValid(nTab))
1287 aDocument.SetStreamValid(nTab, false);
1289 PostPaintGridAll();
1292 void ScDocShell::DoAutoStyle( const ScRange& rRange, const OUString& rStyle )
1294 ScStyleSheetPool* pStylePool = aDocument.GetStyleSheetPool();
1295 ScStyleSheet* pStyleSheet =
1296 pStylePool->FindCaseIns( rStyle, SfxStyleFamily::Para );
1297 if (!pStyleSheet)
1298 pStyleSheet = static_cast<ScStyleSheet*>(
1299 pStylePool->Find( ScGlobal::GetRscString(STR_STYLENAME_STANDARD), SfxStyleFamily::Para ));
1300 if (pStyleSheet)
1302 OSL_ENSURE(rRange.aStart.Tab() == rRange.aEnd.Tab(),
1303 "DoAutoStyle mit mehreren Tabellen");
1304 SCTAB nTab = rRange.aStart.Tab();
1305 SCCOL nStartCol = rRange.aStart.Col();
1306 SCROW nStartRow = rRange.aStart.Row();
1307 SCCOL nEndCol = rRange.aEnd.Col();
1308 SCROW nEndRow = rRange.aEnd.Row();
1309 aDocument.ApplyStyleAreaTab( nStartCol, nStartRow, nEndCol, nEndRow, nTab, *pStyleSheet );
1310 aDocument.ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, nTab );
1311 PostPaint( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab, PAINT_GRID );
1315 void ScDocShell::NotifyStyle( const SfxStyleSheetHint& rHint )
1317 sal_uInt16 nId = rHint.GetHint();
1318 const SfxStyleSheetBase* pStyle = rHint.GetStyleSheet();
1319 if (!pStyle)
1320 return;
1322 if ( pStyle->GetFamily() == SfxStyleFamily::Page )
1324 if ( nId == SfxStyleSheetHintId::MODIFIED )
1326 ScDocShellModificator aModificator( *this );
1328 OUString aNewName = pStyle->GetName();
1329 OUString aOldName = aNewName;
1330 const SfxStyleSheetHintExtended* pExtendedHint = dynamic_cast<const SfxStyleSheetHintExtended*>(&rHint); // Name geaendert?
1331 if (pExtendedHint)
1332 aOldName = pExtendedHint->GetOldName();
1334 if ( aNewName != aOldName )
1335 aDocument.RenamePageStyleInUse( aOldName, aNewName );
1337 SCTAB nTabCount = aDocument.GetTableCount();
1338 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
1339 if (aDocument.GetPageStyle(nTab) == aNewName) // schon auf neu angepasst
1341 aDocument.PageStyleModified( nTab, aNewName );
1342 ScPrintFunc aPrintFunc( this, GetPrinter(), nTab );
1343 aPrintFunc.UpdatePages();
1346 aModificator.SetDocumentModified();
1348 if (pExtendedHint)
1350 SfxBindings* pBindings = GetViewBindings();
1351 if (pBindings)
1353 pBindings->Invalidate( SID_STATUS_PAGESTYLE );
1354 pBindings->Invalidate( SID_STYLE_FAMILY4 );
1355 pBindings->Invalidate( FID_RESET_PRINTZOOM );
1356 pBindings->Invalidate( SID_ATTR_PARA_LEFT_TO_RIGHT );
1357 pBindings->Invalidate( SID_ATTR_PARA_RIGHT_TO_LEFT );
1362 else if ( pStyle->GetFamily() == SfxStyleFamily::Para )
1364 if ( nId == SfxStyleSheetHintId::MODIFIED)
1366 OUString aNewName = pStyle->GetName();
1367 OUString aOldName = aNewName;
1368 const SfxStyleSheetHintExtended* pExtendedHint = dynamic_cast<const SfxStyleSheetHintExtended*>(&rHint);
1369 if (pExtendedHint)
1370 aOldName = pExtendedHint->GetOldName();
1371 if ( aNewName != aOldName )
1373 for(SCTAB i = 0; i < aDocument.GetTableCount(); ++i)
1375 ScConditionalFormatList* pList = aDocument.GetCondFormList(i);
1376 if (pList)
1377 pList->RenameCellStyle( aOldName,aNewName );
1383 // alles andere geht ueber Slots...
1386 // wie in printfun.cxx
1387 #define ZOOM_MIN 10
1389 void ScDocShell::SetPrintZoom( SCTAB nTab, sal_uInt16 nScale, sal_uInt16 nPages )
1391 OUString aStyleName = aDocument.GetPageStyle( nTab );
1392 ScStyleSheetPool* pStylePool = aDocument.GetStyleSheetPool();
1393 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStyleName, SfxStyleFamily::Page );
1394 OSL_ENSURE( pStyleSheet, "PageStyle not found" );
1395 if ( pStyleSheet )
1397 ScDocShellModificator aModificator( *this );
1399 SfxItemSet& rSet = pStyleSheet->GetItemSet();
1400 const bool bUndo(aDocument.IsUndoEnabled());
1401 if (bUndo)
1403 sal_uInt16 nOldScale = static_cast<const SfxUInt16Item&>(rSet.Get(ATTR_PAGE_SCALE)).GetValue();
1404 sal_uInt16 nOldPages = static_cast<const SfxUInt16Item&>(rSet.Get(ATTR_PAGE_SCALETOPAGES)).GetValue();
1405 GetUndoManager()->AddUndoAction( new ScUndoPrintZoom(
1406 this, nTab, nOldScale, nOldPages, nScale, nPages ) );
1409 rSet.Put( SfxUInt16Item( ATTR_PAGE_SCALE, nScale ) );
1410 rSet.Put( SfxUInt16Item( ATTR_PAGE_SCALETOPAGES, nPages ) );
1412 ScPrintFunc aPrintFunc( this, GetPrinter(), nTab );
1413 aPrintFunc.UpdatePages();
1414 aModificator.SetDocumentModified();
1416 SfxBindings* pBindings = GetViewBindings();
1417 if (pBindings)
1418 pBindings->Invalidate( FID_RESET_PRINTZOOM );
1422 bool ScDocShell::AdjustPrintZoom( const ScRange& rRange )
1424 bool bChange = false;
1425 SCTAB nTab = rRange.aStart.Tab();
1427 OUString aStyleName = aDocument.GetPageStyle( nTab );
1428 ScStyleSheetPool* pStylePool = aDocument.GetStyleSheetPool();
1429 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStyleName, SfxStyleFamily::Page );
1430 OSL_ENSURE( pStyleSheet, "PageStyle not found" );
1431 if ( pStyleSheet )
1433 SfxItemSet& rSet = pStyleSheet->GetItemSet();
1434 bool bHeaders = static_cast<const SfxBoolItem&>(rSet.Get(ATTR_PAGE_HEADERS)).GetValue();
1435 sal_uInt16 nOldScale = static_cast<const SfxUInt16Item&>(rSet.Get(ATTR_PAGE_SCALE)).GetValue();
1436 sal_uInt16 nOldPages = static_cast<const SfxUInt16Item&>(rSet.Get(ATTR_PAGE_SCALETOPAGES)).GetValue();
1437 const ScRange* pRepeatCol = aDocument.GetRepeatColRange( nTab );
1438 const ScRange* pRepeatRow = aDocument.GetRepeatRowRange( nTab );
1440 // benoetigte Skalierung fuer Selektion ausrechnen
1442 sal_uInt16 nNewScale = nOldScale;
1444 long nBlkTwipsX = 0;
1445 if (bHeaders)
1446 nBlkTwipsX += (long) PRINT_HEADER_WIDTH;
1447 SCCOL nStartCol = rRange.aStart.Col();
1448 SCCOL nEndCol = rRange.aEnd.Col();
1449 if ( pRepeatCol && nStartCol >= pRepeatCol->aStart.Col() )
1451 for (SCCOL i=pRepeatCol->aStart.Col(); i<=pRepeatCol->aEnd.Col(); i++ )
1452 nBlkTwipsX += aDocument.GetColWidth( i, nTab );
1453 if ( nStartCol <= pRepeatCol->aEnd.Col() )
1454 nStartCol = pRepeatCol->aEnd.Col() + 1;
1456 // legacy compilers' own scope for i
1458 for ( SCCOL i=nStartCol; i<=nEndCol; i++ )
1459 nBlkTwipsX += aDocument.GetColWidth( i, nTab );
1462 long nBlkTwipsY = 0;
1463 if (bHeaders)
1464 nBlkTwipsY += (long) PRINT_HEADER_HEIGHT;
1465 SCROW nStartRow = rRange.aStart.Row();
1466 SCROW nEndRow = rRange.aEnd.Row();
1467 if ( pRepeatRow && nStartRow >= pRepeatRow->aStart.Row() )
1469 nBlkTwipsY += aDocument.GetRowHeight( pRepeatRow->aStart.Row(),
1470 pRepeatRow->aEnd.Row(), nTab );
1471 if ( nStartRow <= pRepeatRow->aEnd.Row() )
1472 nStartRow = pRepeatRow->aEnd.Row() + 1;
1474 nBlkTwipsY += aDocument.GetRowHeight( nStartRow, nEndRow, nTab );
1476 Size aPhysPage;
1477 long nHdr, nFtr;
1478 ScPrintFunc aOldPrFunc( this, GetPrinter(), nTab );
1479 aOldPrFunc.GetScaleData( aPhysPage, nHdr, nFtr );
1480 nBlkTwipsY += nHdr + nFtr;
1482 if ( nBlkTwipsX == 0 ) // hidden columns/rows may lead to 0
1483 nBlkTwipsX = 1;
1484 if ( nBlkTwipsY == 0 )
1485 nBlkTwipsY = 1;
1487 long nNeeded = std::min( aPhysPage.Width() * 100 / nBlkTwipsX,
1488 aPhysPage.Height() * 100 / nBlkTwipsY );
1489 if ( nNeeded < ZOOM_MIN )
1490 nNeeded = ZOOM_MIN; // Begrenzung
1491 if ( nNeeded < (long) nNewScale )
1492 nNewScale = (sal_uInt16) nNeeded;
1494 bChange = ( nNewScale != nOldScale || nOldPages != 0 );
1495 if ( bChange )
1496 SetPrintZoom( nTab, nNewScale, 0 );
1498 return bChange;
1501 void ScDocShell::PageStyleModified( const OUString& rStyleName, bool bApi )
1503 ScDocShellModificator aModificator( *this );
1505 SCTAB nTabCount = aDocument.GetTableCount();
1506 SCTAB nUseTab = MAXTAB+1;
1507 for (SCTAB nTab=0; nTab<nTabCount && nUseTab>MAXTAB; nTab++)
1508 if ( aDocument.GetPageStyle(nTab) == rStyleName &&
1509 ( !bApi || aDocument.GetPageSize(nTab).Width() ) )
1510 nUseTab = nTab;
1511 // bei bApi nur, wenn Umbrueche schon angezeigt
1513 if (ValidTab(nUseTab)) // nicht verwendet -> nichts zu tun
1515 bool bWarn = false;
1517 ScPrintFunc aPrintFunc( this, GetPrinter(), nUseTab ); //! ohne CountPages auskommen
1518 if (!aPrintFunc.UpdatePages()) // setzt Umbrueche auf allen Tabs
1519 bWarn = true;
1521 if (bWarn && !bApi)
1523 ScWaitCursorOff aWaitOff( GetActiveDialogParent() );
1524 ScopedVclPtrInstance<InfoBox> aInfoBox(GetActiveDialogParent(),
1525 ScGlobal::GetRscString(STR_PRINT_INVALID_AREA));
1526 aInfoBox->Execute();
1530 aModificator.SetDocumentModified();
1532 SfxBindings* pBindings = GetViewBindings();
1533 if (pBindings)
1535 pBindings->Invalidate( FID_RESET_PRINTZOOM );
1536 pBindings->Invalidate( SID_ATTR_PARA_LEFT_TO_RIGHT );
1537 pBindings->Invalidate( SID_ATTR_PARA_RIGHT_TO_LEFT );
1541 void ScDocShell::ExecutePageStyle( SfxViewShell& rCaller,
1542 SfxRequest& rReq,
1543 SCTAB nCurTab )
1545 const SfxItemSet* pReqArgs = rReq.GetArgs();
1547 switch ( rReq.GetSlot() )
1549 case SID_STATUS_PAGESTYLE: // Click auf StatusBar-Control
1550 case SID_FORMATPAGE:
1552 if ( pReqArgs == nullptr )
1554 OUString aOldName = aDocument.GetPageStyle( nCurTab );
1555 ScStyleSheetPool* pStylePool = aDocument.GetStyleSheetPool();
1556 SfxStyleSheetBase* pStyleSheet
1557 = pStylePool->Find( aOldName, SfxStyleFamily::Page );
1559 OSL_ENSURE( pStyleSheet, "PageStyle not found! :-/" );
1561 if ( pStyleSheet )
1563 ScStyleSaveData aOldData;
1564 const bool bUndo(aDocument.IsUndoEnabled());
1565 if (bUndo)
1566 aOldData.InitFromStyle( pStyleSheet );
1568 SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
1570 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
1571 OSL_ENSURE(pFact, "ScAbstractFactory create fail!");
1573 std::unique_ptr<SfxAbstractTabDialog> pDlg(pFact->CreateScStyleDlg( GetActiveDialogParent(), *pStyleSheet, RID_SCDLG_STYLES_PAGE, RID_SCDLG_STYLES_PAGE ));
1574 OSL_ENSURE(pDlg, "Dialog create fail!");
1576 if ( pDlg->Execute() == RET_OK )
1578 const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
1580 WaitObject aWait( GetActiveDialogParent() );
1582 OUString aNewName = pStyleSheet->GetName();
1583 if ( aNewName != aOldName &&
1584 aDocument.RenamePageStyleInUse( aOldName, aNewName ) )
1586 SfxBindings* pBindings = GetViewBindings();
1587 if (pBindings)
1589 pBindings->Invalidate( SID_STATUS_PAGESTYLE );
1590 pBindings->Invalidate( FID_RESET_PRINTZOOM );
1594 if ( pOutSet )
1595 aDocument.ModifyStyleSheet( *pStyleSheet, *pOutSet );
1597 // merken fuer GetState():
1598 GetPageOnFromPageStyleSet( &rStyleSet, nCurTab, bHeaderOn, bFooterOn );
1599 rCaller.GetViewFrame()->GetBindings().Invalidate( SID_HFEDIT );
1601 ScStyleSaveData aNewData;
1602 aNewData.InitFromStyle( pStyleSheet );
1603 if (bUndo)
1605 GetUndoManager()->AddUndoAction(
1606 new ScUndoModifyStyle( this, SfxStyleFamily::Page,
1607 aOldData, aNewData ) );
1610 PageStyleModified( aNewName, false );
1611 rReq.Done();
1613 pDlg.reset();
1615 rStyleSet.ClearItem( ATTR_PAGE_PAPERTRAY );
1619 break;
1621 case SID_HFEDIT:
1623 if ( pReqArgs == nullptr )
1625 OUString aStr( aDocument.GetPageStyle( nCurTab ) );
1627 ScStyleSheetPool* pStylePool
1628 = aDocument.GetStyleSheetPool();
1630 SfxStyleSheetBase* pStyleSheet
1631 = pStylePool->Find( aStr, SfxStyleFamily::Page );
1633 OSL_ENSURE( pStyleSheet, "PageStyle not found! :-/" );
1635 if ( pStyleSheet )
1637 SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
1639 SvxPageUsage eUsage =
1640 SvxPageUsage( static_cast<const SvxPageItem&>(
1641 rStyleSet.Get( ATTR_PAGE )).
1642 GetPageUsage() );
1643 bool bShareHeader = static_cast<const SfxBoolItem&>(
1644 static_cast<const SvxSetItem&>(rStyleSet
1645 .Get(ATTR_PAGE_HEADERSET))
1646 .GetItemSet()
1647 .Get(ATTR_PAGE_SHARED))
1648 .GetValue();
1649 bool bShareFooter = static_cast<const SfxBoolItem&>(
1650 static_cast<const SvxSetItem&>(rStyleSet
1651 .Get(ATTR_PAGE_FOOTERSET))
1652 .GetItemSet()
1653 .Get(ATTR_PAGE_SHARED))
1654 .GetValue();
1655 sal_uInt16 nResId = 0;
1657 switch ( eUsage )
1659 case SVX_PAGE_LEFT:
1660 case SVX_PAGE_RIGHT:
1662 if ( bHeaderOn && bFooterOn )
1663 nResId = RID_SCDLG_HFEDIT;
1664 else if ( SVX_PAGE_RIGHT == eUsage )
1666 if ( !bHeaderOn && bFooterOn )
1667 nResId = RID_SCDLG_HFEDIT_RIGHTFOOTER;
1668 else if ( bHeaderOn && !bFooterOn )
1669 nResId = RID_SCDLG_HFEDIT_RIGHTHEADER;
1671 else
1673 // #69193a# respect "shared" setting
1674 if ( !bHeaderOn && bFooterOn )
1675 nResId = bShareFooter ?
1676 RID_SCDLG_HFEDIT_RIGHTFOOTER :
1677 RID_SCDLG_HFEDIT_LEFTFOOTER;
1678 else if ( bHeaderOn && !bFooterOn )
1679 nResId = bShareHeader ?
1680 RID_SCDLG_HFEDIT_RIGHTHEADER :
1681 RID_SCDLG_HFEDIT_LEFTHEADER;
1684 break;
1686 case SVX_PAGE_MIRROR:
1687 case SVX_PAGE_ALL:
1688 default:
1690 if ( !bShareHeader && !bShareFooter )
1692 if ( bHeaderOn && bFooterOn )
1693 nResId = RID_SCDLG_HFEDIT_ALL;
1694 else if ( !bHeaderOn && bFooterOn )
1695 nResId = RID_SCDLG_HFEDIT_FOOTER;
1696 else if ( bHeaderOn && !bFooterOn )
1697 nResId = RID_SCDLG_HFEDIT_HEADER;
1699 else if ( bShareHeader && bShareFooter )
1701 if ( bHeaderOn && bFooterOn )
1702 nResId = RID_SCDLG_HFEDIT;
1703 else
1705 if ( !bHeaderOn && bFooterOn )
1706 nResId = RID_SCDLG_HFEDIT_RIGHTFOOTER;
1707 else if ( bHeaderOn && !bFooterOn )
1708 nResId = RID_SCDLG_HFEDIT_RIGHTHEADER;
1711 else if ( !bShareHeader && bShareFooter )
1713 if ( bHeaderOn && bFooterOn )
1714 nResId = RID_SCDLG_HFEDIT_SFTR;
1715 else if ( !bHeaderOn && bFooterOn )
1716 nResId = RID_SCDLG_HFEDIT_RIGHTFOOTER;
1717 else if ( bHeaderOn && !bFooterOn )
1718 nResId = RID_SCDLG_HFEDIT_HEADER;
1720 else if ( bShareHeader && !bShareFooter )
1722 if ( bHeaderOn && bFooterOn )
1723 nResId = RID_SCDLG_HFEDIT_SHDR;
1724 else if ( !bHeaderOn && bFooterOn )
1725 nResId = RID_SCDLG_HFEDIT_FOOTER;
1726 else if ( bHeaderOn && !bFooterOn )
1727 nResId = RID_SCDLG_HFEDIT_RIGHTHEADER;
1732 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
1733 OSL_ENSURE(pFact, "ScAbstractFactory create fail!");
1735 std::unique_ptr<SfxAbstractTabDialog> pDlg(pFact->CreateScHFEditDlg(
1736 GetActiveDialogParent(),
1737 rStyleSet,
1738 aStr,
1739 nResId));
1740 OSL_ENSURE(pDlg, "Dialog create fail!");
1741 if ( pDlg->Execute() == RET_OK )
1743 const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
1745 if ( pOutSet )
1746 aDocument.ModifyStyleSheet( *pStyleSheet, *pOutSet );
1748 SetDocumentModified();
1749 rReq.Done();
1754 break;
1756 default:
1757 break;
1761 void ScDocShell::GetStatePageStyle( SfxViewShell& /* rCaller */,
1762 SfxItemSet& rSet,
1763 SCTAB nCurTab )
1765 SfxWhichIter aIter(rSet);
1766 sal_uInt16 nWhich = aIter.FirstWhich();
1767 while ( nWhich )
1769 switch (nWhich)
1771 case SID_STATUS_PAGESTYLE:
1772 rSet.Put( SfxStringItem( nWhich, aDocument.GetPageStyle( nCurTab ) ) );
1773 break;
1775 case SID_HFEDIT:
1777 OUString aStr = aDocument.GetPageStyle( nCurTab );
1778 ScStyleSheetPool* pStylePool = aDocument.GetStyleSheetPool();
1779 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStr, SfxStyleFamily::Page );
1781 OSL_ENSURE( pStyleSheet, "PageStyle not found! :-/" );
1783 if ( pStyleSheet )
1785 SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
1786 GetPageOnFromPageStyleSet( &rStyleSet, nCurTab, bHeaderOn, bFooterOn );
1788 if ( !bHeaderOn && !bFooterOn )
1789 rSet.DisableItem( nWhich );
1792 break;
1795 nWhich = aIter.NextWhich();
1799 void ScDocShell::GetState( SfxItemSet &rSet )
1801 bool bTabView = GetBestViewShell() != nullptr;
1803 SfxWhichIter aIter(rSet);
1804 for (sal_uInt16 nWhich = aIter.FirstWhich(); nWhich; nWhich = aIter.NextWhich())
1806 if (!bTabView)
1808 rSet.DisableItem(nWhich);
1809 continue;
1812 switch (nWhich)
1814 case FID_AUTO_CALC:
1815 if ( aDocument.GetHardRecalcState() != ScDocument::HARDRECALCSTATE_OFF )
1816 rSet.DisableItem( nWhich );
1817 else
1818 rSet.Put( SfxBoolItem( nWhich, aDocument.GetAutoCalc() ) );
1819 break;
1821 case FID_CHG_RECORD:
1822 if ( IsDocShared() )
1823 rSet.DisableItem( nWhich );
1824 else
1825 rSet.Put( SfxBoolItem( nWhich,
1826 aDocument.GetChangeTrack() != nullptr ) );
1827 break;
1829 case SID_CHG_PROTECT:
1831 ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack();
1832 if ( pChangeTrack && !IsDocShared() )
1833 rSet.Put( SfxBoolItem( nWhich,
1834 pChangeTrack->IsProtected() ) );
1835 else
1836 rSet.DisableItem( nWhich );
1838 break;
1840 case SID_DOCUMENT_COMPARE:
1842 if ( IsDocShared() )
1844 rSet.DisableItem( nWhich );
1847 break;
1849 // Wenn eine Formel editiert wird, muss FID_RECALC auf jeden Fall enabled sein.
1850 // Recalc fuer das Doc war mal wegen eines Bugs disabled, wenn AutoCalc an war,
1851 // ist jetzt wegen eines anderen Bugs aber auch immer enabled.
1853 case SID_TABLES_COUNT:
1854 rSet.Put( SfxInt16Item( nWhich, aDocument.GetTableCount() ) );
1855 break;
1857 case SID_ATTR_YEAR2000 :
1858 rSet.Put( SfxUInt16Item( nWhich,
1859 aDocument.GetDocOptions().GetYear2000() ) );
1860 break;
1862 case SID_SHARE_DOC:
1864 if ( IsReadOnly() )
1866 rSet.DisableItem( nWhich );
1869 break;
1871 case SID_ATTR_CHAR_FONTLIST:
1872 rSet.Put( SvxFontListItem( pImpl->pFontList, nWhich ) );
1873 break;
1875 case SID_NOTEBOOKBAR:
1877 if (GetViewBindings())
1878 sfx2::SfxNotebookBar::StateMethod(*GetViewBindings(), "modules/scalc/ui/notebookbar.ui");
1880 break;
1882 default:
1885 break;
1890 void ScDocShell::GetSbxState( SfxItemSet &rSet )
1892 // SID_SC_SELECTION (Selection),
1893 // SID_SC_ACTIVECELL (ActiveCell),
1894 // SID_SC_ACTIVETAB (ActiveTable),
1895 // SID_TABLES_GET (Tables),
1896 // SID_PIVOT_GET (DataPilotTables) - removed (old Basic)
1898 // Wenn hier Slots von der View-Shell executed werden, muss auch der
1899 // GetState weitergeleitet werden!
1901 ScTabViewShell* pVisibleSh = GetBestViewShell(); // sichtbare View
1902 if ( pVisibleSh )
1903 pVisibleSh->GetState( rSet );
1906 void ScDocShell::Draw( OutputDevice* pDev, const JobSetup & /* rSetup */, sal_uInt16 nAspect )
1909 SCTAB nVisTab = aDocument.GetVisibleTab();
1910 if (!aDocument.HasTable(nVisTab))
1911 return;
1913 ComplexTextLayoutMode nOldLayoutMode = pDev->GetLayoutMode();
1914 pDev->SetLayoutMode( TEXT_LAYOUT_DEFAULT ); // even if it's the same, to get the metafile action
1916 if ( nAspect == ASPECT_THUMBNAIL )
1918 Rectangle aBoundRect = GetVisArea( ASPECT_THUMBNAIL );
1919 ScViewData aTmpData( this, nullptr );
1920 aTmpData.SetTabNo(nVisTab);
1921 SnapVisArea( aBoundRect );
1922 aTmpData.SetScreen( aBoundRect );
1923 ScPrintFunc::DrawToDev( &aDocument, pDev, 1.0, aBoundRect, &aTmpData, true );
1925 else
1927 Rectangle aBoundRect = SfxObjectShell::GetVisArea();
1928 ScViewData aTmpData( this, nullptr );
1929 aTmpData.SetTabNo(nVisTab);
1930 SnapVisArea( aBoundRect );
1931 aTmpData.SetScreen( aBoundRect );
1932 ScPrintFunc::DrawToDev( &aDocument, pDev, 1.0, aBoundRect, &aTmpData, true );
1935 pDev->SetLayoutMode( nOldLayoutMode );
1938 Rectangle ScDocShell::GetVisArea( sal_uInt16 nAspect ) const
1940 SfxObjectCreateMode eShellMode = GetCreateMode();
1941 if ( eShellMode == SfxObjectCreateMode::ORGANIZER )
1943 // ohne Inhalte wissen wir auch nicht, wie gross die Inhalte sind
1944 // leeres Rechteck zurueckgeben, das wird dann nach dem Laden berechnet
1945 return Rectangle();
1948 if( nAspect == ASPECT_THUMBNAIL )
1950 SCTAB nVisTab = aDocument.GetVisibleTab();
1951 if (!aDocument.HasTable(nVisTab))
1953 nVisTab = 0;
1954 const_cast<ScDocShell*>(this)->aDocument.SetVisibleTab(nVisTab);
1956 Size aSize = aDocument.GetPageSize(nVisTab);
1957 const long SC_PREVIEW_SIZE_X = 10000;
1958 const long SC_PREVIEW_SIZE_Y = 12400;
1959 Rectangle aArea( 0,0, SC_PREVIEW_SIZE_X, SC_PREVIEW_SIZE_Y);
1960 if (aSize.Width() > aSize.Height())
1962 aArea.Right() = SC_PREVIEW_SIZE_Y;
1963 aArea.Bottom() = SC_PREVIEW_SIZE_X;
1966 bool bNegativePage = aDocument.IsNegativePage( aDocument.GetVisibleTab() );
1967 if ( bNegativePage )
1968 ScDrawLayer::MirrorRectRTL( aArea );
1969 SnapVisArea( aArea );
1970 return aArea;
1972 else if( nAspect == ASPECT_CONTENT && eShellMode != SfxObjectCreateMode::EMBEDDED )
1974 // Visarea holen wie nach Load
1976 SCTAB nVisTab = aDocument.GetVisibleTab();
1977 if (!aDocument.HasTable(nVisTab))
1979 nVisTab = 0;
1980 const_cast<ScDocShell*>(this)->aDocument.SetVisibleTab(nVisTab);
1982 SCCOL nStartCol;
1983 SCROW nStartRow;
1984 aDocument.GetDataStart( nVisTab, nStartCol, nStartRow );
1985 SCCOL nEndCol;
1986 SCROW nEndRow;
1987 aDocument.GetPrintArea( nVisTab, nEndCol, nEndRow );
1988 if (nStartCol>nEndCol)
1989 nStartCol = nEndCol;
1990 if (nStartRow>nEndRow)
1991 nStartRow = nEndRow;
1992 Rectangle aNewArea = ((ScDocument&)aDocument)
1993 .GetMMRect( nStartCol,nStartRow, nEndCol,nEndRow, nVisTab );
1994 //TODO/LATER: different methods for setting VisArea?!
1995 const_cast<ScDocShell*>(this)->SfxObjectShell::SetVisArea( aNewArea );
1996 return aNewArea;
1998 else
1999 return SfxObjectShell::GetVisArea( nAspect );
2002 namespace {
2004 void SnapHor( const ScDocument& rDoc, SCTAB nTab, long& rVal, SCCOL& rStartCol )
2006 SCCOL nCol = 0;
2007 long nTwips = (long) (rVal / HMM_PER_TWIPS);
2008 long nSnap = 0;
2009 while ( nCol<MAXCOL )
2011 long nAdd = rDoc.GetColWidth(nCol, nTab);
2012 if ( nSnap + nAdd/2 < nTwips || nCol < rStartCol )
2014 nSnap += nAdd;
2015 ++nCol;
2017 else
2018 break;
2020 rVal = (long) ( nSnap * HMM_PER_TWIPS );
2021 rStartCol = nCol;
2024 void SnapVer( const ScDocument& rDoc, SCTAB nTab, long& rVal, SCROW& rStartRow )
2026 SCROW nRow = 0;
2027 long nTwips = (long) (rVal / HMM_PER_TWIPS);
2028 long nSnap = 0;
2030 bool bFound = false;
2031 for (SCROW i = nRow; i <= MAXROW; ++i)
2033 SCROW nLastRow;
2034 if (rDoc.RowHidden(i, nTab, nullptr, &nLastRow))
2036 i = nLastRow;
2037 continue;
2040 nRow = i;
2041 long nAdd = rDoc.GetRowHeight(i, nTab);
2042 if ( nSnap + nAdd/2 < nTwips || nRow < rStartRow )
2044 nSnap += nAdd;
2045 ++nRow;
2047 else
2049 bFound = true;
2050 break;
2053 if (!bFound)
2054 nRow = MAXROW; // all hidden down to the bottom
2056 rVal = (long) ( nSnap * HMM_PER_TWIPS );
2057 rStartRow = nRow;
2062 void ScDocShell::SnapVisArea( Rectangle& rRect ) const
2064 SCTAB nTab = aDocument.GetVisibleTab();
2065 bool bNegativePage = aDocument.IsNegativePage( nTab );
2066 if ( bNegativePage )
2067 ScDrawLayer::MirrorRectRTL( rRect ); // calculate with positive (LTR) values
2069 SCCOL nCol = 0;
2070 SnapHor( aDocument, nTab, rRect.Left(), nCol );
2071 ++nCol; // mindestens eine Spalte
2072 SnapHor( aDocument, nTab, rRect.Right(), nCol );
2074 SCROW nRow = 0;
2075 SnapVer( aDocument, nTab, rRect.Top(), nRow );
2076 ++nRow; // mindestens eine Zeile
2077 SnapVer( aDocument, nTab, rRect.Bottom(), nRow );
2079 if ( bNegativePage )
2080 ScDrawLayer::MirrorRectRTL( rRect ); // back to real rectangle
2083 void ScDocShell::GetPageOnFromPageStyleSet( const SfxItemSet* pStyleSet,
2084 SCTAB nCurTab,
2085 bool& rbHeader,
2086 bool& rbFooter )
2088 if ( !pStyleSet )
2090 ScStyleSheetPool* pStylePool = aDocument.GetStyleSheetPool();
2091 SfxStyleSheetBase* pStyleSheet = pStylePool->
2092 Find( aDocument.GetPageStyle( nCurTab ),
2093 SfxStyleFamily::Page );
2095 OSL_ENSURE( pStyleSheet, "PageStyle not found! :-/" );
2097 if ( pStyleSheet )
2098 pStyleSet = &pStyleSheet->GetItemSet();
2099 else
2100 rbHeader = rbFooter = false;
2103 OSL_ENSURE( pStyleSet, "PageStyle-Set not found! :-(" );
2104 if (!pStyleSet)
2105 return;
2107 const SvxSetItem* pSetItem = nullptr;
2108 const SfxItemSet* pSet = nullptr;
2110 pSetItem = static_cast<const SvxSetItem*>( &pStyleSet->Get( ATTR_PAGE_HEADERSET ) );
2111 pSet = &pSetItem->GetItemSet();
2112 rbHeader = static_cast<const SfxBoolItem&>(pSet->Get(ATTR_PAGE_ON)).GetValue();
2114 pSetItem = static_cast<const SvxSetItem*>( &pStyleSet->Get( ATTR_PAGE_FOOTERSET ) );
2115 pSet = &pSetItem->GetItemSet();
2116 rbFooter = static_cast<const SfxBoolItem&>(pSet->Get(ATTR_PAGE_ON)).GetValue();
2119 #if defined(_WIN32)
2120 bool ScDocShell::DdeGetData( const OUString& rItem,
2121 const OUString& rMimeType,
2122 css::uno::Any & rValue )
2124 if( SotClipboardFormatId::STRING == SotExchange::GetFormatIdFromMimeType( rMimeType ) )
2126 if( rItem.equalsIgnoreAsciiCase( "Format" ) )
2128 OString aFmtByte(OUStringToOString(aDdeTextFmt,
2129 osl_getThreadTextEncoding()));
2130 rValue <<= css::uno::Sequence< sal_Int8 >(
2131 reinterpret_cast<const sal_Int8*>(aFmtByte.getStr()),
2132 aFmtByte.getLength() + 1 );
2133 return true;
2135 ScImportExport aObj( &aDocument, rItem );
2136 if ( !aObj.IsRef() )
2137 return false; // ungueltiger Bereich
2139 if( aDdeTextFmt[0] == 'F' )
2140 aObj.SetFormulas( true );
2141 if( aDdeTextFmt == "SYLK" ||
2142 aDdeTextFmt == "FSYLK" )
2144 OString aData;
2145 if( aObj.ExportByteString( aData, osl_getThreadTextEncoding(),
2146 SotClipboardFormatId::SYLK ) )
2148 rValue <<= css::uno::Sequence< sal_Int8 >(
2149 reinterpret_cast<const sal_Int8*>(aData.getStr()),
2150 aData.getLength() + 1 );
2151 return true;
2153 else
2154 return false;
2156 if( aDdeTextFmt == "CSV" ||
2157 aDdeTextFmt == "FCSV" )
2158 aObj.SetSeparator( ',' );
2159 aObj.SetExportTextOptions( ScExportTextOptions( ScExportTextOptions::ToSpace, 0, false ) );
2160 return aObj.ExportData( rMimeType, rValue );
2163 ScImportExport aObj( &aDocument, rItem );
2164 aObj.SetExportTextOptions( ScExportTextOptions( ScExportTextOptions::ToSpace, 0, false ) );
2165 return aObj.IsRef() && aObj.ExportData( rMimeType, rValue );
2168 bool ScDocShell::DdeSetData( const OUString& rItem,
2169 const OUString& rMimeType,
2170 const css::uno::Any & rValue )
2172 if( SotClipboardFormatId::STRING == SotExchange::GetFormatIdFromMimeType( rMimeType ))
2174 if( rItem.equalsIgnoreAsciiCase( "Format" ) )
2176 if ( ScByteSequenceToString::GetString( aDdeTextFmt, rValue, osl_getThreadTextEncoding() ) )
2178 aDdeTextFmt = aDdeTextFmt.toAsciiUpperCase();
2179 return true;
2181 return false;
2183 ScImportExport aObj( &aDocument, rItem );
2184 if( aDdeTextFmt[0] == 'F' )
2185 aObj.SetFormulas( true );
2186 if( aDdeTextFmt == "SYLK" ||
2187 aDdeTextFmt == "FSYLK" )
2189 OUString aData;
2190 if ( ScByteSequenceToString::GetString( aData, rValue, osl_getThreadTextEncoding() ) )
2192 return aObj.ImportString( aData, SotClipboardFormatId::SYLK );
2194 return false;
2196 if( aDdeTextFmt == "CSV" ||
2197 aDdeTextFmt == "FCSV" )
2198 aObj.SetSeparator( ',' );
2199 return aObj.ImportData( rMimeType, rValue );
2201 ScImportExport aObj( &aDocument, rItem );
2202 return aObj.IsRef() && aObj.ImportData( rMimeType, rValue );
2204 #endif
2206 ::sfx2::SvLinkSource* ScDocShell::DdeCreateLinkSource( const OUString& rItem )
2208 // only check for valid item string - range is parsed again in ScServerObject ctor
2210 // named range?
2211 OUString aPos = rItem;
2212 ScRangeName* pRange = aDocument.GetRangeName();
2213 if( pRange )
2215 const ScRangeData* pData = pRange->findByUpperName(ScGlobal::pCharClass->uppercase(aPos));
2216 if (pData)
2218 if( pData->HasType( ScRangeData::Type::RefArea )
2219 || pData->HasType( ScRangeData::Type::AbsArea )
2220 || pData->HasType( ScRangeData::Type::AbsPos ) )
2221 pData->GetSymbol( aPos ); // continue with the name's contents
2225 // Address in DDE function must be always parsed as CONV_OOO so that it
2226 // would always work regardless of current address conversion. We do this
2227 // because the address item in a DDE entry is *not* normalized when saved
2228 // into ODF.
2229 ScRange aRange;
2230 bool bValid = ( (aRange.Parse(aPos, &aDocument, formula::FormulaGrammar::CONV_OOO ) & ScRefFlags::VALID) ||
2231 (aRange.aStart.Parse(aPos, &aDocument, formula::FormulaGrammar::CONV_OOO) & ScRefFlags::VALID) );
2233 ScServerObject* pObj = nullptr; // NULL = error
2234 if ( bValid )
2235 pObj = new ScServerObject( this, rItem );
2237 // GetLinkManager()->InsertServer() is in the ScServerObject ctor
2239 return pObj;
2242 ScViewData* ScDocShell::GetViewData()
2244 SfxViewShell* pCur = SfxViewShell::Current();
2245 ScTabViewShell* pViewSh = dynamic_cast< ScTabViewShell *>( pCur );
2246 return pViewSh ? &pViewSh->GetViewData() : nullptr;
2249 SCTAB ScDocShell::GetCurTab()
2251 //! this must be made non-static and use a ViewShell from this document!
2253 ScViewData* pViewData = GetViewData();
2255 return pViewData ? pViewData->GetTabNo() : static_cast<SCTAB>(0);
2258 ScTabViewShell* ScDocShell::GetBestViewShell( bool bOnlyVisible )
2260 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
2261 // falsches Doc?
2262 if( pViewSh && pViewSh->GetViewData().GetDocShell() != this )
2263 pViewSh = nullptr;
2264 if( !pViewSh )
2266 // 1. ViewShell suchen
2267 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this, bOnlyVisible );
2268 if( pFrame )
2270 SfxViewShell* p = pFrame->GetViewShell();
2271 pViewSh = dynamic_cast< ScTabViewShell *>( p );
2274 return pViewSh;
2277 SfxBindings* ScDocShell::GetViewBindings()
2279 // used to invalidate slots after changes to this document
2281 SfxViewShell* pViewSh = GetBestViewShell();
2282 if (pViewSh)
2283 return &pViewSh->GetViewFrame()->GetBindings();
2284 else
2285 return nullptr;
2288 ScDocShell* ScDocShell::GetShellByNum( sal_uInt16 nDocNo ) // static
2290 ScDocShell* pFound = nullptr;
2291 SfxObjectShell* pShell = SfxObjectShell::GetFirst();
2292 sal_uInt16 nShellCnt = 0;
2294 while ( pShell && !pFound )
2296 if ( dynamic_cast<const ScDocShell*>(pShell) != nullptr )
2298 if ( nShellCnt == nDocNo )
2299 pFound = static_cast<ScDocShell*>(pShell);
2300 else
2301 ++nShellCnt;
2303 pShell = SfxObjectShell::GetNext( *pShell );
2306 return pFound;
2309 IMPL_LINK_TYPED( ScDocShell, DialogClosedHdl, sfx2::FileDialogHelper*, _pFileDlg, void )
2311 OSL_ENSURE( _pFileDlg, "ScDocShell::DialogClosedHdl(): no file dialog" );
2312 OSL_ENSURE( pImpl->pDocInserter, "ScDocShell::DialogClosedHdl(): no document inserter" );
2314 if ( ERRCODE_NONE == _pFileDlg->GetError() )
2316 sal_uInt16 nSlot = pImpl->pRequest->GetSlot();
2317 SfxMedium* pMed = pImpl->pDocInserter->CreateMedium();
2318 // #i87094# If a .odt was selected pMed is NULL.
2319 if (pMed)
2321 pImpl->pRequest->AppendItem( SfxStringItem( SID_FILE_NAME, pMed->GetName() ) );
2322 if ( SID_DOCUMENT_COMPARE == nSlot )
2324 if ( pMed->GetFilter() )
2325 pImpl->pRequest->AppendItem(
2326 SfxStringItem( SID_FILTER_NAME, pMed->GetFilter()->GetFilterName() ) );
2327 OUString sOptions = ScDocumentLoader::GetOptions( *pMed );
2328 if ( !sOptions.isEmpty() )
2329 pImpl->pRequest->AppendItem( SfxStringItem( SID_FILE_FILTEROPTIONS, sOptions ) );
2331 const SfxPoolItem* pItem = nullptr;
2332 const SfxInt16Item* pInt16Item(nullptr);
2333 SfxItemSet* pSet = pMed->GetItemSet();
2334 if (pSet && pSet->GetItemState(SID_VERSION, true, &pItem) == SfxItemState::SET)
2336 pInt16Item = dynamic_cast<const SfxInt16Item*>(pItem);
2338 if (pInt16Item)
2340 pImpl->pRequest->AppendItem( *pItem );
2343 Execute( *(pImpl->pRequest) );
2347 pImpl->bIgnoreLostRedliningWarning = false;
2350 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
2352 void ScDocShell::EnableSharedSettings( bool bEnable )
2354 SetDocumentModified();
2356 if ( bEnable )
2358 aDocument.EndChangeTracking();
2359 aDocument.StartChangeTracking();
2361 // hide accept or reject changes dialog
2362 sal_uInt16 nId = ScAcceptChgDlgWrapper::GetChildWindowId();
2363 SfxViewFrame* pViewFrame = SfxViewFrame::Current();
2364 if ( pViewFrame && pViewFrame->HasChildWindow( nId ) )
2366 pViewFrame->ToggleChildWindow( nId );
2367 SfxBindings* pBindings = GetViewBindings();
2368 if ( pBindings )
2370 pBindings->Invalidate( FID_CHG_ACCEPT );
2374 else
2376 aDocument.EndChangeTracking();
2379 ScChangeViewSettings aChangeViewSet;
2380 aChangeViewSet.SetShowChanges( false );
2381 aDocument.SetChangeViewSettings( aChangeViewSet );
2384 uno::Reference< frame::XModel > ScDocShell::LoadSharedDocument()
2386 uno::Reference< frame::XModel > xModel;
2389 SC_MOD()->SetInSharedDocLoading( true );
2390 uno::Reference< frame::XDesktop2 > xLoader = frame::Desktop::create( ::comphelper::getProcessComponentContext() );
2391 uno::Sequence < beans::PropertyValue > aArgs( 1 );
2392 aArgs[0].Name = "Hidden";
2393 aArgs[0].Value <<= true;
2395 if ( GetMedium() )
2397 const SfxStringItem* pPasswordItem = SfxItemSet::GetItem<SfxStringItem>(GetMedium()->GetItemSet(), SID_PASSWORD, false);
2398 if ( pPasswordItem && !pPasswordItem->GetValue().isEmpty() )
2400 aArgs.realloc( 2 );
2401 aArgs[1].Name = "Password";
2402 aArgs[1].Value <<= pPasswordItem->GetValue();
2406 xModel.set(
2407 xLoader->loadComponentFromURL( GetSharedFileURL(), "_blank", 0, aArgs ),
2408 uno::UNO_QUERY_THROW );
2409 SC_MOD()->SetInSharedDocLoading( false );
2411 catch ( uno::Exception& )
2413 OSL_FAIL( "ScDocShell::LoadSharedDocument(): caught exception\n" );
2414 SC_MOD()->SetInSharedDocLoading( false );
2417 uno::Reference< util::XCloseable > xClose( xModel, uno::UNO_QUERY_THROW );
2418 xClose->close( true );
2419 return uno::Reference< frame::XModel >();
2421 catch ( uno::Exception& )
2423 return uno::Reference< frame::XModel >();
2426 return xModel;
2429 #endif
2431 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */