usingnamespace ::com::sun::star; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::RuntimeException; using ::com::sun::star::uno::UNO_QUERY_THROW; using ::com::sun::star::lang::DisposedException; using ::com::sun::star::awt::XWindow; using ::com::sun::star::frame::XController; using ::com::sun::star::frame::XDispatchProvider; using ::com::sun::star::document::XViewDataSupplier; using ::com::sun::star::container::XIndexAccess; using ::com::sun::star::beans::PropertyValue; using ::com::sun::star::beans::StringPair; using ::com::sun::star::uno::Sequence; using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::uno::Exception; using ::com::sun::star::frame::XFrame; using ::com::sun::star::frame::XFrameActionListener; using ::com::sun::star::util::XCloseListener; using ::com::sun::star::task::XStatusIndicator; using ::com::sun::star::frame::XTitle; using ::com::sun::star::ui::XSidebarProvider;
void SfxBaseController::SetCreationArguments_Impl( const Sequence< PropertyValue >& i_rCreationArgs )
{
OSL_ENSURE( !m_pData->m_aCreationArgs.hasElements(), "SfxBaseController::SetCreationArguments_Impl: not intended to be called twice!" );
m_pData->m_aCreationArgs = i_rCreationArgs;
}
SfxViewFrame& SfxBaseController::GetViewFrame_Impl() const
{
ENSURE_OR_THROW( m_pData->m_pViewShell, "not to be called without a view shell" );
SfxViewFrame* pActFrame = m_pData->m_pViewShell->GetFrame();
ENSURE_OR_THROW( pActFrame, "a view shell without a view frame is pretty pathological" ); return *pActFrame;
}
if ( m_pData->m_pViewShell )
{
ConnectSfxFrame_Impl( E_CONNECT );
ShowInfoBars( );
// attaching the frame to the controller is the last step in the creation of a new view, so notify this
SfxViewEventHint aHint( SfxEventHintId::ViewCreated, GlobalEventConfig::GetEventName( GlobalEventId::VIEWCREATED ), m_pData->m_pViewShell->GetObjectShell(), Reference< frame::XController2 >( this ) );
SfxGetpApp()->NotifyEvent( aHint );
}
}
if (pSlot && (!pViewFrame->GetFrame().IsInPlace() || !pSlot->IsMode(SfxSlotMode::CONTAINER))) return pViewFrame->GetBindings().GetDispatch(pSlot, aURL, bMasterCommand);
// try to find parent SfxViewFrame if (constauto& xOwnFrame = pViewFrame->GetFrame().GetFrameInterface())
{ if (constauto xParentFrame = xOwnFrame->getCreator())
{ // TODO/LATER: in future probably SfxViewFrame hierarchy should be the same as XFrame hierarchy // SfxViewFrame* pParentFrame = pViewFrame->GetParentViewFrame();
// search the related SfxViewFrame
SfxViewFrame* pParentFrame = nullptr; for (SfxViewFrame* pFrame = SfxViewFrame::GetFirst(); pFrame;
pFrame = SfxViewFrame::GetNext(*pFrame))
{ if (pFrame->GetFrame().GetFrameInterface() == xParentFrame)
{
pParentFrame = pFrame; break;
}
}
uno::Sequence< Reference< frame::XDispatch > > SAL_CALL SfxBaseController::queryDispatches( const uno::Sequence< frame::DispatchDescriptor >& seqDescripts )
{ // Create return list - which must have same size then the given descriptor // It's not allowed to pack it!
sal_Int32 nCount = seqDescripts.getLength();
uno::Sequence< Reference< frame::XDispatch > > lDispatcher( nCount );
SfxObjectShell* pDoc = rFrame.GetObjectShell() ;
SfxViewFrame *pView = SfxViewFrame::GetFirst(pDoc); while( pView )
{ // if there is another ViewFrame or currently the ViewShell in my ViewFrame is switched (PagePreview) if ( pView != &rFrame || pView->GetViewShell() != m_pData->m_pViewShell ) break;
pView = SfxViewFrame::GetNext( *pView, pDoc );
}
m_pData->m_xListener->disposing( aObject );
SfxViewShell *pShell = m_pData->m_pViewShell;
m_pData->m_pViewShell = nullptr; if (rFrame.GetViewShell() == pShell)
{ // Enter registrations only allowed if we are the owner! if ( rFrame.GetFrame().OwnsBindings_Impl() )
rFrame.GetBindings().ENTERREGISTRATIONS();
rFrame.GetFrame().SetFrameInterface_Impl( aXFrame );
rFrame.GetFrame().DoClose_Impl();
}
}
void SfxBaseController::ConnectSfxFrame_Impl( const ConnectSfxFrame i_eConnect )
{
ENSURE_OR_THROW( m_pData->m_pViewShell, "not to be called without a view shell" );
SfxViewFrame* pViewFrame = m_pData->m_pViewShell->GetFrame();
ENSURE_OR_THROW( pViewFrame, "a view shell without a view frame is pretty pathological" );
if ( bConnect )
{ if ( i_eConnect == E_CONNECT )
{ if ( ( m_pData->m_pViewShell->GetObjectShell() != nullptr )
&& ( m_pData->m_pViewShell->GetObjectShell()->GetCreateMode() == SfxObjectCreateMode::EMBEDDED )
)
{
SfxViewFrame& rViewFrm = m_pData->m_pViewShell->GetViewFrame(); if ( !rViewFrm.GetFrame().IsInPlace() )
{ // for outplace embedded objects, we want the layout manager to keep the content window // size constant, if possible try
{
Reference< beans::XPropertySet > xFrameProps( m_pData->m_xFrame, uno::UNO_QUERY_THROW );
Reference< beans::XPropertySet > xLayouterProps(
xFrameProps->getPropertyValue(u"LayoutManager"_ustr), uno::UNO_QUERY_THROW );
xLayouterProps->setPropertyValue(u"PreserveContentSize"_ustr, uno::Any( true ) );
} catch (const uno::Exception&)
{
DBG_UNHANDLED_EXCEPTION("sfx.view");
}
}
}
}
// upon DISCONNECT, we did *not* pop the shells from the stack (this is done elsewhere), so upon // RECONNECT, we're not allowed to push them if ( i_eConnect != E_RECONNECT )
{
pViewFrame->GetDispatcher()->Push( *m_pData->m_pViewShell );
m_pData->m_pViewShell->PushSubShells_Impl();
pViewFrame->GetDispatcher()->Flush();
}
vcl::Window* pEditWin = m_pData->m_pViewShell->GetWindow(); if ( pEditWin )
pEditWin->Show();
if ( SfxViewFrame::Current() == pViewFrame )
pViewFrame->GetDispatcher()->Update_Impl( true );
if ( rFrame.IsInPlace() )
pViewFrame->LockAdjustPosSizePixel();
if ( nPluginMode == 3 )
rFrame.GetWorkWindow_Impl()->SetInternalDockingAllowed( false );
if ( !rFrame.IsInPlace() )
pViewFrame->GetDispatcher()->Update_Impl();
pViewFrame->Show();
rFrame.GetWindow().Show(); if ( !rFrame.IsInPlace() || ( nPluginMode == 3 ) )
pViewFrame->MakeActive_Impl( rFrame.GetFrameInterface()->isActive() );
if ( rFrame.IsInPlace() )
{
pViewFrame->UnlockAdjustPosSizePixel(); // force resize for OLE server to fix layout problems of writer and math // see i53651 if ( nPluginMode == 3 )
pViewFrame->Resize( true );
}
} else
{
DBG_ASSERT( !rFrame.IsInPlace() && !bHasPluginMode, "Special modes not compatible with hidden mode!" );
rFrame.GetWindow().Show();
}
// UpdateTitle now, hidden TopFrames have otherwise no Name!
pViewFrame->UpdateTitle();
if ( !rFrame.IsInPlace() )
pViewFrame->Resize( true );
// sometimes we want to avoid adding to the recent documents bool bAllowPickListEntry = aViewArgs.getOrDefault(u"PickListEntry"_ustr, true);
m_pData->m_pViewShell->GetObjectShell()->AvoidRecentDocs(!bAllowPickListEntry);
// if there's a JumpMark given, then, well, jump to it const OUString sJumpMark = aViewArgs.getOrDefault( u"JumpMark"_ustr, OUString() ); constbool bHasJumpMark = !sJumpMark.isEmpty();
OSL_ENSURE( ( !m_pData->m_pViewShell->GetObjectShell()->IsLoading() )
|| ( sJumpMark.isEmpty() ), "SfxBaseController::ConnectSfxFrame_Impl: so this code wasn't dead?" ); // Before CWS autorecovery, there was code which postponed jumping to the Mark to a later time // (SfxObjectShell::PositionView_Impl), but it seems this branch was never used, since this method // here is never called before the load process finished. At least not with a non-empty jump mark if ( !sJumpMark.isEmpty() )
m_pData->m_pViewShell->JumpToMark( sJumpMark );
// if no plugin mode and no jump mark was supplied, check whether the document itself can provide view data, and // if so, forward it to the view/shell. if ( !bHasPluginMode && !bHasJumpMark )
{ // Note that this might not be the ideal place here. Restoring view data should, IMO, be the // responsibility of the loader, not an implementation detail buried here deep within the controller's // implementation. // What I think should be done to replace the below code: // - change SfxBaseController::restoreViewData to also accept a PropertyValue[] (it currently accepts // a string only), and forward it to its ViewShell's ReadUserDataSequence // - change the frame loader so that when a new document is loaded (as opposed to an existing // document being loaded into a new frame), the model's view data is examine the very same // way as below, and the proper view data is set via XController::restoreViewData // - extend SfxViewFrame::SwitchToViewShell_Impl. Currently, it cares for the case where a non-PrintPreview // view is exchanged, and sets the old view's data at the model. It should also care for the other // way, were the PrintPreview view is left: in this case, the new view should also be initialized // with the model's view data try
{
Reference< XViewDataSupplier > xViewDataSupplier( getModel(), UNO_QUERY_THROW );
Reference< XIndexAccess > xViewData( xViewDataSupplier->getViewData() );
// find the view data item whose ViewId matches the ID of the view we're just connecting to const SfxObjectFactory& rDocFactory( rDoc.GetFactory() ); const sal_Int32 nCount = xViewData.is() ? xViewData->getCount() : 0;
sal_Int32 nViewDataIndex = 0; for ( sal_Int32 i=0; i<nCount; ++i )
{ const ::comphelper::NamedValueCollection aViewData( xViewData->getByIndex(i) );
OUString sViewId( aViewData.getOrDefault( u"ViewId"_ustr, OUString() ) ); if ( sViewId.isEmpty() ) continue;
if ( !(xCmisDoc->isVersionable( ) && aCmisProperties.hasElements( )) ) return;
// Loop over the CMIS Properties to find cmis:isVersionSeriesCheckedOut // and find if it is a Google Drive file. bool bIsGoogleFile = false; bool bCheckedOut = false; for ( constauto& rCmisProp : aCmisProperties )
{ if ( rCmisProp.Id == "cmis:isVersionSeriesCheckedOut" ) {
uno::Sequence< sal_Bool > bTmp;
rCmisProp.Value >>= bTmp;
bCheckedOut = bTmp[0];
} // if it is a Google Drive file, we don't need the checkout bar, // still need the checkout feature for the version dialog. if ( rCmisProp.Name == "title" )
bIsGoogleFile = true;
}
if ( bCheckedOut || bIsGoogleFile ) return;
// Get the Frame and show the InfoBar if not checked out
SfxViewFrame* pViewFrame = m_pData->m_pViewShell->GetFrame(); auto pInfoBar = pViewFrame->AppendInfoBar(u"checkout"_ustr, u""_ustr, SfxResId(STR_NONCHECKEDOUT_DOCUMENT),
InfobarType::WARNING); if (pInfoBar)
{
weld::Button &rBtn = pInfoBar->addButton();
rBtn.set_label(SfxResId(STR_CHECKOUT));
rBtn.connect_clicked(LINK(this, SfxBaseController, CheckOutHandler));
}
}
if (aInfobarType < static_cast<sal_Int32>(InfobarType::INFO)
|| aInfobarType > static_cast<sal_Int32>(InfobarType::DANGER)) throw lang::IllegalArgumentException("Undefined InfobarType: "
+ OUString::number(aInfobarType),
getXWeak(), 0);
SfxViewFrame* pViewFrame = m_pData->m_pViewShell->GetFrame(); if (pViewFrame->HasInfoBarWithID(sId)) throw lang::IllegalArgumentException("Infobar with ID '" + sId + "' already existing.",
getXWeak(), 0);
auto pInfoBar
= pViewFrame->AppendInfoBar(sId, sPrimaryMessage, sSecondaryMessage, static_cast<InfobarType>(aInfobarType), bShowCloseButton); if (!pInfoBar) throw uno::RuntimeException(u"Could not create Infobar"_ustr);
for (const StringPair& actionButton : actionButtons)
{ if (actionButton.First.isEmpty() || actionButton.Second.isEmpty()) continue;
weld::Button& rBtn = pInfoBar->addButton(&actionButton.Second);
rBtn.set_label(actionButton.First);
}
}
SfxViewFrame* pViewFrame = m_pData->m_pViewShell->GetFrame(); if (!pViewFrame->HasInfoBarWithID(sId)) throw css::container::NoSuchElementException("Infobar with ID '" + sId + "' not found.");
pViewFrame->RemoveInfoBar(sId);
}
¤ 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.0.31Bemerkung:
(vorverarbeitet am 2026-10-01)
¤
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.