/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
void ScTabViewShell::Activate(bool bMDI)
{
SfxViewShell::Activate(bMDI);
bIsActive = true; // here no GrabFocus, otherwise there will be problems when something is edited inplace!
if ( bMDI )
{ // for input row (ClearCache)
ScModule* pScMod = ScModule::get();
pScMod->ViewShellChanged(/*bStopEditing=*/ !comphelper::LibreOfficeKit::isActive());
ActivateView( true, bFirstActivate );
// update AutoCorrect, if Writer has newly created this
UpdateDrawTextOutliner();
// RegisterNewTargetNames does not exist anymore
SfxViewFrame& rThisFrame = GetViewFrame(); if ( mpInputHandler && rThisFrame.HasChildWindow(FID_INPUTLINE_STATUS) )
{ // actually only required for Reload (last version): // The InputWindow remains, but the View along with the InputHandler is newly created, // that is why the InputHandler must be set at the InputWindow.
SfxChildWindow* pChild = rThisFrame.GetChildWindow(FID_INPUTLINE_STATUS); if (pChild)
{
ScInputWindow* pWin = static_cast<ScInputWindow*>(pChild->GetWindow()); if (pWin && pWin->IsVisible())
{
pWin->NumLinesChanged(); // tdf#150664
ScInputHandler* pOldHdl=pWin->GetInputHandler();
SfxViewShell* pSh = SfxViewShell::GetFirst( true, checkSfxViewShell<ScTabViewShell> ); while ( pSh!=nullptr && pOldHdl!=nullptr)
{ // Hmm, what if pSh is a shell for a different document? But as this code // does not seem to be LibreOfficeKit-specific, probably that doesn't // happen, because having multiple documents open simultaneously has of // course not been a problem at all in traditional desktop LibreOffice. // (Unlike in a LibreOfficeKit-based process where it has been a problem.) if (static_cast<ScTabViewShell*>(pSh)->GetInputHandler() == pOldHdl)
{
pOldHdl->ResetDelayTimer(); break;
}
pSh = SfxViewShell::GetNext( *pSh, true, checkSfxViewShell<ScTabViewShell> );
}
// ReadExtOptions (view settings from Excel import) must also be done // after the ctor, because of the potential calls to Window::Show. // Even after a bugfix (Window::Show no longer notifies the access // bridge, it's done in ImplSetReallyVisible), there are problems if Window::Show // is called during the ViewShell ctor and reschedules asynchronous calls // (for example from the FmFormShell ctor).
ScExtDocOptions* pExtOpt = GetViewData().GetDocument().GetExtDocOptions(); if ( pExtOpt && pExtOpt->IsChanged() )
{
GetViewData().ReadExtOptions(*pExtOpt); // Excel view settings
SetTabNo( GetViewData().GetTabNo(), true );
pExtOpt->SetChanged( false );
}
}
// don't call CheckSelectionTransfer here - activating a view should not change the // primary selection (may be happening just because the mouse was moved over the window)
if (!inChartOrMathContext(this))
{
ContextChangeEventMultiplexer::NotifyContextChange(
GetController(),
vcl::EnumContext::Context::Default);
}
}
if( bMDI && !comphelper::LibreOfficeKit::isActive())
{ // during shell deactivation, shells must not be switched, or the loop // through the shell stack (in SfxDispatcher::DoDeactivate_Impl) will not work bool bOldDontSwitch = bDontSwitch;
bDontSwitch = true;
ActivateView( false, false );
if ( GetViewFrame().GetFrame().IsInPlace() ) // inplace
GetViewData().GetDocShell().UpdateOle(GetViewData(), true);
if ( pHdl )
pHdl->NotifyChange( nullptr, true ); // timer-delayed due to document switching
if (pScActiveViewShell == this)
pScActiveViewShell = nullptr;
// in LOK case this could be triggered on every action from other view (doc_setView) // we don't want to hide tooltip only because other view did some action if ( pHdl && !comphelper::LibreOfficeKit::isActive() )
pHdl->HideTip(); // Hide formula auto input tip
}
}
void ScTabViewShell::SetActive()
{ // SFX-View would like to activate itself, since then magical things would happen // (eg else the designer may crash)
ActiveGrabFocus();
}
// Call EnterHandler even in formula mode here, // so a formula change in an embedded object isn't lost // (ScDocShell::PrepareClose isn't called then).
ScInputHandler* pHdl = ScModule::get()->GetInputHdl(this); if ( pHdl && pHdl->IsInputMode() )
{
pHdl->EnterHandler();
}
// draw text edit mode must be closed
FuPoor* pPoor = GetDrawFuncPtr(); if (pPoor && IsDrawTextShell())
{ // "clean" end of text edit, including note handling, subshells and draw func switching, // as in FuDraw and ScTabView::DrawDeselectAll
GetViewData().GetDispatcher().Execute( pPoor->GetSlotID(), SfxCallMode::SLOT | SfxCallMode::RECORD );
}
ScDrawView* pDrView = GetScDrawView(); if ( pDrView )
{ // force end of text edit, to be safe // ScEndTextEdit must always be used, to ensure correct UndoManager
pDrView->ScEndTextEdit();
}
if ( pFormShell )
{ bool bRet = pFormShell->PrepareClose(bUI); if (!bRet) return bRet;
} return SfxViewShell::PrepareClose(bUI);
}
// calculate zoom for in-place // from the ratio of VisArea and window size of GridWin
void ScTabViewShell::UpdateOleZoom()
{
ScDocShell& rDocSh = GetViewData().GetDocShell(); if ( rDocSh.GetCreateMode() == SfxObjectCreateMode::EMBEDDED )
{ //TODO/LATER: is there a difference between the two GetVisArea methods?
Size aObjSize = rDocSh.GetVisArea().GetSize(); if ( !aObjSize.IsEmpty() )
{
vcl::Window* pWin = GetActiveWin();
Size aWinHMM = pWin->PixelToLogic(pWin->GetOutputSizePixel(), MapMode(MapUnit::Map100thMM));
SetZoomFactor( Fraction( aWinHMM.Width(),aObjSize.Width() ),
Fraction( aWinHMM.Height(),aObjSize.Height() ) );
}
}
}
void ScTabViewShell::ShowCursor(bool/* bOn */)
{ /*!!! ShowCursor is not called as a pair as in gridwin. here the CursorLockCount for Gridwin must be set directly to 0
if (bOn) ShowAllCursors(); else HideAllCursors();
*/
}
//! if ViewData has more tables than document, remove tables in ViewData
}
void ScTabViewShell::UpdateDrawShell()
{ // Called after user interaction that may delete the selected drawing object. // Remove DrawShell if nothing is selected.
void ScTabViewShell::SetPivotShell( bool bActive )
{ // SetPivotShell is called from CursorPosChanged every time // -> don't change anything except switching between cell and pivot shell
if (eCurOST != OST_Pivot && eCurOST != OST_Cell) return;
if (pFormShell && bFormShellAtTop)
AddSubShell(*pFormShell); // add on top of own subshells
eCurOST=eOST;
// abort "format paint brush" when switching to an incompatible shell if ( ( GetBrushDocument() && !bCellBrush ) || ( GetDrawBrushSet() && !bDrawBrush ) )
ResetBrushDocument();
}
void ScTabViewShell::SetFormShellAtTop( bool bSet )
{ if ( pFormShell && !bSet )
pFormShell->ForgetActiveControl(); // let the FormShell know it no longer has the focus
IMPL_LINK_NOARG(ScTabViewShell, FormControlActivated, LinkParamNone*, void)
{ // a form control got the focus, so the form shell has to be on top
SetFormShellAtTop( true );
}
// GetMySubShell / SetMySubShell: simulate old behavior, // so that there is only one SubShell (only within the 5 own SubShells)
SfxShell* ScTabViewShell::GetMySubShell() const
{ // GetSubShell() was const before, and GetSubShell(sal_uInt16) should also be const...
SfxPrinter* ScTabViewShell::GetPrinter( bool bCreate )
{ // printer is always present (is created for the FontList already on start-up) return GetViewData().GetDocShell().GetPrinter(bCreate);
}
IMPL_LINK_NOARG(ScTabViewShell, SimpleRefClose, const OUString*, void)
{
SfxInPlaceClient* pClient = GetIPClient(); if ( pClient && pClient->IsObjectInPlaceActive() )
{ // If range selection was started with an active embedded object, // switch back to original sheet (while the dialog is still open).
if ( GetActiveViewShell() != this )
{ // #i18833# / #i34499# The API method can be called for a view that's not active. // Then the view has to be activated first, the same way as in Execute for SID_CURRENTDOC. // Can't use GrabFocus here, because it needs to take effect immediately.
rViewFrm.GetFrame().Appear();
}
sal_uInt16 nId = ScSimpleRefDlgWrapper::GetChildWindowId();
if ( !bUsed && !bIsType && nCode != KEY_RETURN ) // input once again afterwards
bUsed = pScMod->InputKeyEvent( rKEvt );
} else
{ // special case: copy/cut for multiselect -> error message // (Slot is disabled, so SfxViewShell::KeyInput would be swallowed without a comment)
KeyFuncType eFunc = aCode.GetFunction(); if ( eFunc == KeyFuncType::CUT )
{
ScRange aDummy;
ScMarkType eMarkType = GetViewData().GetSimpleArea( aDummy ); if (eMarkType != SC_MARK_SIMPLE)
{
ErrorMessage(STR_NOMULTISELECT);
bUsed = true;
}
} if (!bUsed)
bUsed = SfxViewShell::KeyInput( rKEvt ); // accelerators
// during inplace editing, some slots are handled by the // container app and are executed during Window::KeyInput. // -> don't pass keys to input handler that would be used there // but should call slots instead. bool bParent = ( GetViewFrame().GetFrame().IsInPlace() && eFunc != KeyFuncType::DONTKNOW );
if ( rDocSh.GetCreateMode() == SfxObjectCreateMode::EMBEDDED )
{ //TODO/LATER: is there a difference between the two GetVisArea methods?
tools::Rectangle aVisArea = rDocSh.GetVisArea();
SCTAB nVisTab = rDoc.GetVisibleTab(); if (!rDoc.HasTable(nVisTab))
{
nVisTab = 0;
rDoc.SetVisibleTab(nVisTab);
}
SetTabNo( nVisTab ); bool bNegativePage = rDoc.IsNegativePage( nVisTab ); // show the right cells
GetViewData().SetScreenPos( bNegativePage ? aVisArea.TopRight() : aVisArea.TopLeft() );
if ( GetViewFrame().GetFrame().IsInPlace() ) // inplace
{
rDocSh.SetInplace( true ); // already initiated like this if (rDoc.IsEmbedded())
rDoc.ResetEmbedded(); // no blue mark
} elseif ( bFirstView )
{
rDocSh.SetInplace( false );
GetViewData().RefreshZoom(); // recalculate PPT if (!rDoc.IsEmbedded())
rDoc.SetEmbedded( rDoc.GetVisibleTab(), aVisArea ); // mark VisArea
}
}
// ViewInputHandler // Each task now has its own InputWindow, // therefore either should each task get its own InputHandler, // or the InputWindow should create its own InputHandler // (then always search via InputWindow and only if not found // use the InputHandler of the App). // As an intermediate solution each View gets its own InputHandler, // which only yields problems if two Views are in one task window.
mpInputHandler.reset(new ScInputHandler);
// old version: // if ( !GetViewFrame().ISA(SfxTopViewFrame) ) // OLE or Plug-In // pInputHandler = new ScInputHandler;
// create FormShell before MakeDrawView, so that DrawView can be registered at the // FormShell in every case // the FormShell is pushed in the first activate
pFormShell.reset( new FmFormShell(this) );
pFormShell->SetControlActivationHandler( LINK( this, ScTabViewShell, FormControlActivated ) );
// DrawView must not be created in TabView - ctor, // if the ViewShell is not yet constructed... if (rDoc.GetDrawLayer())
MakeDrawView( nForceDesignMode );
ViewOptionsHasChanged(false, false); // possibly also creates DrawView
if ( bFirstView ) // first view?
{
rDoc.SetDocVisible( true ); // used when creating new sheets if ( rDocSh.IsEmpty() )
{ // set first sheet's RTL flag (following will already be initialized because of SetDocVisible)
rDoc.SetLayoutRTL( 0, ScGlobal::IsSystemRTL() );
// append additional sheets (not for OLE object) if ( rDocSh.GetCreateMode() != SfxObjectCreateMode::EMBEDDED )
{ // Get the customized initial tab count const ScDefaultsOptions& rOpt = mod->GetDefaultsOptions();
SCTAB nInitTabCount = rOpt.GetInitTabCount();
for (SCTAB i=1; i<nInitTabCount; i++)
rDoc.MakeTable(i,false);
}
rDocSh.SetEmpty( false ); // #i6232# make sure this is done only once
}
// ReadExtOptions is now in Activate
// link update no nesting if ( rDocSh.GetCreateMode() != SfxObjectCreateMode::INTERNAL &&
rDocSh.IsUpdateEnabled() ) // #105575#; update only in the first creation of the ViewShell
{ // Check if there are any external data. bool bLink = rDoc.GetExternalRefManager()->hasExternalData(); if (!bLink)
{ // #i100042# sheet links can still exist independently from external formula references
SCTAB nTabCount = rDoc.GetTableCount(); for (SCTAB i=0; i<nTabCount && !bLink; i++) if (rDoc.IsLinked(i))
bLink = true;
} if (!bLink)
{ const sc::DocumentLinkManager& rMgr = rDoc.GetDocLinkManager(); if (rDoc.HasLinkFormulaNeedingCheck() || rDoc.HasAreaLinks() || rMgr.hasDdeOrOleOrWebServiceLinks())
bLink = true;
} if (bLink)
{ if ( !pFirst )
pFirst = &GetViewFrame();
if(mod->GetCurRefDlgId()==0)
{
pFirst->GetDispatcher()->Execute( SID_UPDATETABLINKS,
SfxCallMode::ASYNCHRON | SfxCallMode::RECORD );
}
} else
{ // No links yet, but loading an existing document may have // disabled link update but there's no "Allow updating" infobar // that could enable it again. So in order to enable the user // to add formulas with external references allow link updates // again.
rDocSh.AllowLinkUpdate();
}
class ScViewOptiChangesListener : public cppu::WeakImplHelper<util::XChangesListener>
{ public:
ScViewOptiChangesListener(ScTabViewShell&); void stopListening();
void ScViewOptiChangesListener::stopListening()
{ if (m_xViewChangesNotifier)
m_xViewChangesNotifier->removeChangesListener(this); if (m_xColorSchemeChangesNotifier)
m_xColorSchemeChangesNotifier->removeChangesListener(this);
}
if (xCRM.is())
{ if (bRows)
xCRM->removeRange(aCellRange, sheet::CellDeleteMode_UP); else
xCRM->removeRange(aCellRange, sheet::CellDeleteMode_LEFT);
}
}
/* For rows (bool bRows), I am passing reference to already existing sequence, and comparing the required * columns, whereas for columns, I am creating a sequence for each, with only the checked entries * in the dialog.
*/ staticbool lcl_CheckInArray(std::vector<uno::Sequence<uno::Any>>& nUniqueRecords, const uno::Sequence<uno::Any>& nCurrentRecord, const std::vector<int>& rSelectedEntries, bool bRows)
{ for (size_t m = 0; m < nUniqueRecords.size(); ++m)
{ bool bIsDuplicate = true; for (size_t n = 0; n < rSelectedEntries.size(); ++n)
{ // when the first different element is found int nColumn = (bRows ? rSelectedEntries[n] : n); if (nUniqueRecords[m][nColumn] != (bRows ? nCurrentRecord[rSelectedEntries[n]] : nCurrentRecord[n]))
{
bIsDuplicate = false; break;
}
}
if (bIsDuplicate) returntrue;
} returnfalse;
}
uno::Reference<css::sheet::XSpreadsheet> ScTabViewShell::GetRangeWithSheet(css::table::CellRangeAddress& rRangeData, bool& bHasData, bool bHasUnoArguments)
{ // get spreadsheet document model & controller
uno::Reference<frame::XModel> xModel(GetViewData().GetDocShell().GetModel());
uno::Reference<frame::XController> xController(xModel->getCurrentController());
// spreadsheet's extension of com.sun.star.frame.Controller service
uno::Reference<sheet::XSpreadsheetView> SpreadsheetDocument(xController, uno::UNO_QUERY);
uno::Reference<sheet::XSpreadsheet> ActiveSheet = SpreadsheetDocument->getActiveSheet();
if (!bHasUnoArguments)
{ // get the selection supplier, extract selection in XSheetCellRange
uno::Reference<view::XSelectionSupplier> xSelectionSupplier(SpreadsheetDocument, uno::UNO_QUERY);
uno::Any Selection = xSelectionSupplier->getSelection();
uno::Reference<sheet::XSheetCellRange> SelectedCellRange;
Selection >>= SelectedCellRange;
// Get the Selected Range Address.
uno::Reference<sheet::XCellRangeAddressable> xAddressable( SelectedCellRange, uno::UNO_QUERY); if (xAddressable.is())
rRangeData = xAddressable->getRangeAddress(); else
{
bHasData = false; return ActiveSheet;
}
}
// shrink to intersection of data and selection. If no intersection ==> return
bHasData = GetViewData().GetDocument().ShrinkToDataArea(rRangeData.Sheet, nStartColumn, nStartRow, nEndColumn, nEndRow);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.