/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * 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 .
*/
// Called by the SwEditWin when it gets the focus.
void SwView::GotFocus() const
{ // if we got the focus, and the form shell *is* on the top of the dispatcher // stack, then we need to rebuild the stack (the form shell doesn't belong to // the top then) const SfxDispatcher& rDispatcher = const_cast< SwView* >( this )->GetDispatcher();
SfxShell* pTopShell = rDispatcher.GetShell( 0 );
FmFormShell* pAsFormShell = dynamic_cast<FmFormShell*>( pTopShell ); if ( pAsFormShell )
{
pAsFormShell->ForgetActiveControl(); const_cast< SwView* >( this )->AttrChangedNotify(nullptr);
} elseif ( m_pPostItMgr )
{
SwAnnotationShell* pAsAnnotationShell = dynamic_cast<SwAnnotationShell*>( pTopShell ); if ( pAsAnnotationShell )
{
m_pPostItMgr->SetActiveSidebarWin(nullptr); const_cast< SwView* >( this )->AttrChangedNotify(nullptr);
}
} if (SwWrtShell* pWrtShell = GetWrtShellPtr())
{
SwWrtShell& rWrtShell = GetWrtShell();
rWrtShell.GetDoc()->getIDocumentLayoutAccess().SetCurrentViewShell( pWrtShell );
rWrtShell.GetDoc()->getIDocumentSettingAccess().set( DocumentSettingId::BROWSE_MODE,
rWrtShell.GetViewOptions()->getBrowseMode() );
}
}
// called by the FormShell when a form control is focused. This is // a request to put the form shell on the top of the dispatcher stack
IMPL_LINK_NOARG(SwView, FormControlActivated, LinkParamNone*, void)
{ // if a form control has been activated, and the form shell is not on the top // of the dispatcher stack, then we need to activate it const SfxDispatcher& rDispatcher = GetDispatcher(); const SfxShell* pTopShell = rDispatcher.GetShell( 0 ); const FmFormShell* pAsFormShell = dynamic_cast<const FmFormShell*>( pTopShell ); if ( !pAsFormShell )
{ // if we're editing text currently, cancel this
SdrView *pSdrView = m_pWrtShell ? m_pWrtShell->GetDrawView() : nullptr; if ( pSdrView && pSdrView->IsTextEdit() )
pSdrView->SdrEndTextEdit( true );
void SwView::SelectShell()
{ // Attention: Maintain the SelectShell for the WebView additionally
// In case of m_bDying, our SfxShells are already gone, don't try to select a shell at all. if(m_bInDtor || m_bDying) return;
// Decision if the UpdateTable has to be called bool bUpdateTable = false; const SwFrameFormat* pCurTableFormat = m_pWrtShell->GetTableFormat(); if(pCurTableFormat && pCurTableFormat != m_pLastTableFormat)
{
bUpdateTable = true; // can only be executed later
}
m_pLastTableFormat = pCurTableFormat;
//SEL_TBL and SEL_TBL_CELLS can be ORed!
SelectionType nNewSelectionType = m_pWrtShell->GetSelectionType()
& ~SelectionType::TableCell;
// Determine if a different fly frame was selected. bool bUpdateFly = false; const SwFrameFormat* pCurFlyFormat = nullptr; if (m_nSelectionType & SelectionType::Ole || m_nSelectionType & SelectionType::Graphic)
{
pCurFlyFormat = m_pWrtShell->GetFlyFrameFormat();
} if (pCurFlyFormat && pCurFlyFormat != m_pLastFlyFormat)
{
bUpdateFly = true;
}
m_pLastFlyFormat = pCurFlyFormat;
if ( m_pFormShell && m_pFormShell->IsActiveControl() )
nNewSelectionType |= SelectionType::FormControl;
if ( nNewSelectionType == m_nSelectionType )
{
GetViewFrame().GetBindings().InvalidateAll( false ); if ( m_nSelectionType & SelectionType::Ole ||
m_nSelectionType & SelectionType::Graphic ) // For graphs and OLE the verb can be modified of course!
ImpSetVerb( nNewSelectionType );
if ( m_pShell )
{
rDispatcher.Flush(); // Really erase all cached shells //Remember to the old selection which toolbar was visible
ToolbarId eId = rDispatcher.GetObjectBarId(SFX_OBJECTBAR_OBJECT); if (eId != ToolbarId::None)
pBarCfg->SetTopToolbar(m_nSelectionType, eId);
// Show Mail Merge toolbar initially for documents with Database fields if (!m_bInitOnceCompleted && GetWrtShell().IsAnyDatabaseFieldInDoc() && !comphelper::IsFuzzing())
ShowUIElement(u"private:resource/toolbar/mailmerge"_ustr);
// Activate the toolbar to the new selection which also was active last time. // Before a flush () must be, but does not affect the UI according to MBA and // is not a performance problem. // TODO/LATER: maybe now the Flush() command is superfluous?!
rDispatcher.Flush();
Point aPnt = GetEditWin().OutputToScreenPixel(GetEditWin().GetPointerPosPixel());
aPnt = GetEditWin().PixelToLogic(aPnt);
GetEditWin().UpdatePointer(aPnt);
} // Opportune time for the communication with OLE objects? if ( GetDocShell()->GetDoc()->IsOLEPrtNotifyPending() )
GetDocShell()->GetDoc()->PrtOLENotify( false );
// now the table-update if(bUpdateTable)
m_pWrtShell->UpdateTable();
// Interaction: AttrChangedNotify() and TimeoutHdl. // No Update if actions are still open, since the cursor on the core side // can be somewhere in no man's land. // But since we can no longer supply status and we want instead lock // the dispatcher.
//Opt: Not if PaintLocked. During unlock a notify will be once more triggered. if( !m_pWrtShell->IsPaintLocked() && !g_bNoInterrupt &&
GetDocShell()->IsReadOnly() )
CheckReadonlyState();
// change ui if cursor is at a SwPostItField if (m_pPostItMgr)
{ // only perform the code that is needed to determine, if at the // actual cursor position is a post-it field
m_pPostItMgr->SetShadowState( m_pWrtShell->GetPostItFieldAtCursor() );
}
}
void SwView::CheckReadonlyState()
{
SfxDispatcher &rDis = GetDispatcher(); // To be able to recognize if it is already disabled!
SfxItemState eStateRO, eStateProtAll;
SfxPoolItemHolder aResult; // Query the status from a slot which is only known to us. // Otherwise the slot is known from other; like the BasicIde
eStateRO = rDis.QueryState(FN_INSERT_BOOKMARK, aResult);
eStateProtAll = rDis.QueryState(FN_EDIT_REGION, aResult); bool bChgd = false;
if( (SfxDisableFlags::SwOnProtectedCursor & nDisableFlags ) !=
(SfxDisableFlags::SwOnProtectedCursor & rDis.GetDisableFlags() ) )
{ // Additionally move at the Window the InputContext, so that // in japanese / chinese versions the external input will be // turned on or off. This but only if the correct shell is on // the stack. switch( m_pViewImpl->GetShellMode() )
{ case ShellMode::Text: case ShellMode::ListText: case ShellMode::TableText: case ShellMode::TableListText:
{ // Temporary solution!!! Should set the font of the current insertion point // at each cursor movement, so outside of this "if". But TH does not // evaluates the font at this time and the "purchase" appears to me // as too expensive. // Moreover, we don't have a font, but only attributes from which the // text formatting and the correct font will be build together.
// According to discussion with MBA and further // investigations, no old SfxViewShell will be set as parameter <pOldSh>, // if function "New Window" is performed to open an additional view beside // an already existing one. // If the view is switch from one to another, the 'old' view is given by // parameter <pOldSh>.
bDocSzUpdated = true;
staticbool bFuzzing = comphelper::IsFuzzing();
if (!bFuzzing)
{
CreateScrollbar( true );
CreateScrollbar( false );
}
SwDocShell& rDocSh = dynamic_cast<SwDocShell&>(*_rFrame.GetObjectShell()); bool bOldModifyFlag = rDocSh.IsEnableSetModified(); if (bOldModifyFlag)
rDocSh.EnableSetModified( false ); // HACK: SwDocShell has some cached font info, VCL informs about font updates, // but loading of docs with embedded fonts happens after SwDocShell is created // but before SwEditWin (which handles the VCL event) is created. So update // manually. if (rDocSh.GetDoc()->getIDocumentSettingAccess().get( DocumentSettingId::EMBED_FONTS ))
rDocSh.UpdateFontList(); bool bWebDShell = dynamic_cast<const SwWebDocShell*>(&rDocSh) != nullptr;
// assure that modified state of document // isn't reset, if document is already modified. constbool bIsDocModified = m_pWrtShell->GetDoc()->getIDocumentState().IsModified();
// Thus among other things, the HRuler is not displayed in the read-only case.
aUsrPref.SetReadonly( m_pWrtShell->GetViewOptions()->IsReadonly() );
// no margin for OLE!
Size aBrwsBorder; if( SfxObjectCreateMode::EMBEDDED != rDocSh.GetCreateMode() )
aBrwsBorder = GetMargin();
m_pWrtShell->SetBrowseBorder( aBrwsBorder );
// In CTOR no shell changes may take place, which must be temporarily stored // with the timer. Otherwise, the SFX removes them from the stack! bool bOld = g_bNoInterrupt;
g_bNoInterrupt = true;
// Check and process the DocSize. Via the handler, the shell could not // be found, because the shell is not known in the SFX management // within the CTOR phase.
DocSzChgd( m_pWrtShell->GetDocSize() );
// Set AttrChangedNotify link
m_pWrtShell->SetChgLnk(LINK(this, SwView, AttrChangedNotify));
if (rDocSh.GetCreateMode() == SfxObjectCreateMode::EMBEDDED &&
!rDocSh.GetVisArea(ASPECT_CONTENT).IsEmpty())
SetVisArea(rDocSh.GetVisArea(ASPECT_CONTENT),false);
// Update all tables if necessary: if( m_pWrtShell->GetDoc()->IsUpdateTOX() )
{
SfxRequest aSfxRequest( FN_UPDATE_TOX, SfxCallMode::SLOT, GetPool() );
Execute( aSfxRequest );
m_pWrtShell->GetDoc()->SetUpdateTOX( false ); // reset again
m_pWrtShell->SttEndDoc(true);
}
// No ResetModified, if there is already a view to this doc.
SfxViewFrame& rVFrame = GetViewFrame();
SfxViewFrame* pFirst = SfxViewFrame::GetFirst(&rDocSh); // Currently(360) the view is registered firstly after the CTOR, // the following expression is also working if this changes. // If the modification cannot be canceled by undo, then do NOT set // the modify back. // no reset of modified state, if document // was already modified. if (!m_pWrtShell->GetDoc()->GetIDocumentUndoRedo().IsUndoNoResetModified() &&
( !pFirst || pFirst == &rVFrame ) &&
!bIsDocModified )
{
m_pWrtShell->ResetModified();
}
g_bNoInterrupt = bOld;
// If a new GlobalDoc will be created, the navigator will also be generated. if( dynamic_cast<const SwGlobalDocShell*>(&rDocSh) != nullptr &&
!rVFrame.GetChildWindow( SID_NAVIGATOR ))
{
SfxBoolItem aNavi(SID_NAVIGATOR, true);
GetDispatcher().ExecuteList(SID_NAVIGATOR, SfxCallMode::ASYNCHRON, { &aNavi });
}
// has anybody calls the attrchanged handler in the constructor? if( m_bAttrChgNotifiedWithRegistrations )
{
GetViewFrame().GetBindings().LEAVEREGISTRATIONS(); if( m_aTimer.IsActive() )
m_aTimer.Stop();
}
if (!bFuzzing)
{ if (!m_pHScrollbar->IsScrollbarVisible(true))
ShowHScrollbar( false ); if (!m_pVScrollbar->IsScrollbarVisible(true))
ShowVScrollbar( false );
}
if (m_pWrtShell->GetViewOptions()->IsShowOutlineContentVisibilityButton())
m_pWrtShell->InvalidateOutlineContentVisibility();
if (!bFuzzing)
GetViewFrame().GetWindow().AddChildEventListener(LINK(this, SwView, WindowChildEventListener));
SwViewGlueDocShell::~SwViewGlueDocShell()
{
SwDocShell* pDocSh = m_rView.GetDocShell(); if (pDocSh && pDocSh->GetView() == &m_rView)
pDocSh->SetView(nullptr); if (SwModule* mod = SwModule::get(); mod->GetView() == &m_rView)
mod->SetView(nullptr);
}
SwView::~SwView()
{ // Notify other LOK views that we are going away.
SfxLokHelper::notifyOtherViews(this, LOK_CALLBACK_VIEW_CURSOR_VISIBLE, "visible", "false"_ostr);
SfxLokHelper::notifyOtherViews(this, LOK_CALLBACK_TEXT_VIEW_SELECTION, "selection", ""_ostr);
SfxLokHelper::notifyOtherViews(this, LOK_CALLBACK_GRAPHIC_VIEW_SELECTION, "selection", "EMPTY"_ostr);
// Need to remove activated field's button before disposing EditWin.
GetWrtShell().getIDocumentMarkAccess()->ClearFieldActivation();
// the last view must end the text edit
SdrView *pSdrView = m_pWrtShell->GetDrawView(); if( pSdrView && pSdrView->IsTextEdit() )
pSdrView->SdrEndTextEdit( true ); elseif (pSdrView)
{
pSdrView->DisposeUndoManager();
}
// tdf#155410 speedup shutdown, prevent unnecessary broadcasting during teardown of draw model auto pDrawModel = GetWrtShell().getIDocumentDrawModelAccess().GetDrawModel(); constbool bWasLocked = pDrawModel->isLocked();
pDrawModel->setLock(true);
m_pWrtShell.reset(); // reset here so that it is not accessible by the following dtors.
pDrawModel->setLock(bWasLocked);
// If this was enabled in the ctor for the frame, then disable it here. staticbool bRequestDoubleBuffering = getenv("VCL_DOUBLEBUFFERING_ENABLE"); if (bRequestDoubleBuffering)
m_pEditWin->RequestDoubleBuffering(false);
m_pEditWin.disposeAndClear();
m_pFormatClipboard.reset();
}
void SwView::SetDying()
{
m_bDying = true;
}
void SwView::afterCallbackRegistered()
{ if (!comphelper::LibreOfficeKit::isActive()) return;
// common tasks
SfxViewShell::afterCallbackRegistered();
void SwView::WriteUserData( OUString &rUserData, bool bBrowse )
{ // The browse flag will be passed from Sfx when documents are browsed // (not to be confused with the BrowseMode). // Then that stored data are not persistent!
void SwView::ReadUserData( const OUString &rUserData, bool bBrowse )
{ if ( !(rUserData.indexOf(';')>=0 && // more than one token // For document without layout only in the onlinelayout or // while forward/backward
(!m_pWrtShell->IsNewLayout() || m_pWrtShell->GetViewOptions()->getBrowseMode() || bBrowse)) ) return;
bool bIsOwnDocument = lcl_IsOwnDocument( *this );
CurrShell aCurr(m_pWrtShell.get());
sal_Int32 nPos = 0;
// No it is *not* a good idea to call GetToken within Point constr. immediately, // because which parameter is evaluated first?
tools::Long nX = o3tl::toInt32(o3tl::getToken(rUserData, 0, ';', nPos )),
nY = o3tl::toInt32(o3tl::getToken(rUserData, 0, ';', nPos ));
Point aCursorPos( nX, nY );
// restore editing position
m_pViewImpl->SetRestorePosition(aCursorPos, bSelectObj); // set flag value to avoid macro execution. bool bSavedFlagValue = m_pWrtShell->IsMacroExecAllowed();
m_pWrtShell->SetMacroExecAllowed( false ); // os: changed: The user data has to be read if the view is switched back from page preview // go to the last editing position when opening own files if(m_bOldShellWasPagePreview || bIsOwnDocument)
{
m_pWrtShell->SwCursorShell::SetCursor( aCursorPos, !bSelectObj ); if( bSelectObj )
{
m_pWrtShell->SelectObj( aCursorPos );
m_pWrtShell->EnterSelFrameMode( &aCursorPos );
}
}
// reset flag value
m_pWrtShell->SetMacroExecAllowed( bSavedFlagValue );
// set visible area before applying // information from print preview. Otherwise, the applied information // is lost. // os: changed: The user data has to be read if the view is switched back from page preview // go to the last editing position when opening own files if(m_bOldShellWasPagePreview || bIsOwnDocument )
{ if ( bBrowse )
SetVisArea( aVis.TopLeft() ); else
SetVisArea( aVis );
}
//apply information from print preview - if available if( !m_sNewCursorPos.isEmpty() )
{
sal_Int32 nIdx{ 0 }; const tools::Long nXTmp = o3tl::toInt32(o3tl::getToken(m_sNewCursorPos, 0, ';', nIdx )); const tools::Long nYTmp = o3tl::toInt32(o3tl::getToken(m_sNewCursorPos, 0, ';', nIdx ));
Point aCursorPos2( nXTmp, nYTmp );
bSelectObj = m_pWrtShell->IsObjSelectable( aCursorPos2 );
// set flag value to avoid macro execution. bool bSavedFlagValue = m_pWrtShell->IsMacroExecAllowed();
m_pWrtShell->SetMacroExecAllowed( false ); // os: changed: The user data has to be read if the view is switched back from page preview // go to the last editing position when opening own files
m_pViewImpl->SetRestorePosition(aCursorPos, bSelectObj); if(m_bOldShellWasPagePreview|| bIsOwnDocument)
{
m_pWrtShell->SwCursorShell::SetCursor( aCursorPos, !bSelectObj );
// Update the shell to toggle Header/Footer edit if needed bool bInHeader = true; if ( m_pWrtShell->IsInHeaderFooter( &bInHeader ) )
{ if ( !bInHeader )
{
m_pWrtShell->SetShowHeaderFooterSeparator( FrameControlType::Footer, true );
m_pWrtShell->SetShowHeaderFooterSeparator( FrameControlType::Header, false );
} else
{
m_pWrtShell->SetShowHeaderFooterSeparator( FrameControlType::Header, true );
m_pWrtShell->SetShowHeaderFooterSeparator( FrameControlType::Footer, false );
}
// Force repaint
m_pWrtShell->GetWin()->Invalidate();
} if ( m_pWrtShell->IsInHeaderFooter() != m_pWrtShell->IsHeaderFooterEdit() )
m_pWrtShell->ToggleHeaderFooterEdit();
// reset flag value
m_pWrtShell->SetMacroExecAllowed( bSavedFlagValue );
}
if (bGotKeepRatio && bKeepRatio != pVOpt->IsKeepRatio())
{ // Got a custom value, then it makes sense to trigger notifications.
SwViewOption aUsrPref(*pVOpt);
aUsrPref.SetKeepRatio(bKeepRatio);
SwModule::get()->ApplyUsrPref(aUsrPref, this);
}
// In case we have a 'fixed' view layout of 2 or more columns, // we have to apply the view options *before* starting the action. // Otherwise the SetZoom function cannot work correctly, because // the view layout hasn't been calculated. constbool bZoomNeedsViewLayout = bSetViewLayoutSettings &&
1 < nViewLayoutColumns &&
bSetViewSettings &&
eZoom != SvxZoomType::PERCENT;
if ( !bZoomNeedsViewLayout )
m_pWrtShell->StartAction();
if ( bSetViewLayoutSettings )
SetViewLayout( nViewLayoutColumns, bViewLayoutBookMode, true );
if ( bZoomNeedsViewLayout )
m_pWrtShell->StartAction();
if ( bSetViewSettings )
SetZoom( eZoom, nZoomFactor, true );
// os: changed: The user data has to be read if the view is switched back from page preview // go to the last editing position when opening own files if(m_bOldShellWasPagePreview||bIsOwnDocument)
{ if ( bGotVisibleLeft && bGotVisibleTop )
{
Point aTopLeft(nLeft, nTop); // make sure the document is still centered const SwTwips lBorder = IsDocumentBorder() ? DOCUMENTBORDER : 2 * DOCUMENTBORDER;
SwTwips nEditWidth = GetEditWin().GetOutDev()->GetOutputSize().Width(); if(nEditWidth > (m_aDocSz.Width() + lBorder ))
aTopLeft.setX( ( m_aDocSz.Width() + lBorder - nEditWidth ) / 2 ); else
{ //check if the values are possible
tools::Long nXMax = m_pHScrollbar->GetRangeMax() - m_pHScrollbar->GetVisibleSize(); if( aTopLeft.X() > nXMax )
aTopLeft.setX( nXMax < 0 ? 0 : nXMax );
}
SetVisArea( aTopLeft );
}
}
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.