/************************************************************** * * 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 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sfx2.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "view.hrc" #include #include "viewimp.hxx" #include "sfx2/sfxresid.hxx" #include #include #include #include #include #include "arrdecl.hxx" #include #include "view.hrc" #include "sfxlocal.hrc" #include #include "sfx2/mailmodelapi.hxx" #include #include #include #include #include "workwin.hxx" #include #include // #110897# #ifndef _UNOTOOLS_PROCESSFACTORY_HXX #include #endif using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::frame; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::util; using namespace ::com::sun::star::system; using namespace ::cppu; namespace css = ::com::sun::star; //========================================================================= DBG_NAME(SfxViewShell) #define SfxViewShell #include "sfxslots.hxx" //========================================================================= class SfxClipboardChangeListener : public ::cppu::WeakImplHelper1< datatransfer::clipboard::XClipboardListener > { public: SfxClipboardChangeListener( SfxViewShell* pView, const uno::Reference< datatransfer::clipboard::XClipboardNotifier >& xClpbrdNtfr ); virtual ~SfxClipboardChangeListener(); // XEventListener virtual void SAL_CALL disposing( const lang::EventObject& rEventObject ) throw ( uno::RuntimeException ); // XClipboardListener virtual void SAL_CALL changedContents( const datatransfer::clipboard::ClipboardEvent& rEventObject ) throw ( uno::RuntimeException ); void DisconnectViewShell() { m_pViewShell = NULL; } void ChangedContents(); enum AsyncExecuteCmd { ASYNCEXECUTE_CMD_DISPOSING, ASYNCEXECUTE_CMD_CHANGEDCONTENTS }; struct AsyncExecuteInfo { AsyncExecuteInfo( AsyncExecuteCmd eCmd, uno::Reference< datatransfer::clipboard::XClipboardListener > xThis, SfxClipboardChangeListener* pListener ) : m_eCmd( eCmd ), m_xThis( xThis ), m_pListener( pListener ) {} AsyncExecuteCmd m_eCmd; uno::Reference< datatransfer::clipboard::XClipboardListener > m_xThis; SfxClipboardChangeListener* m_pListener; }; private: SfxViewShell* m_pViewShell; uno::Reference< datatransfer::clipboard::XClipboardNotifier > m_xClpbrdNtfr; uno::Reference< lang::XComponent > m_xCtrl; DECL_STATIC_LINK( SfxClipboardChangeListener, AsyncExecuteHdl_Impl, AsyncExecuteInfo* ); }; SfxClipboardChangeListener::SfxClipboardChangeListener( SfxViewShell* pView, const uno::Reference< datatransfer::clipboard::XClipboardNotifier >& xClpbrdNtfr ) : m_pViewShell( 0 ), m_xClpbrdNtfr( xClpbrdNtfr ) { m_xCtrl = uno::Reference < lang::XComponent >( pView->GetController(), uno::UNO_QUERY ); if ( m_xCtrl.is() ) { m_xCtrl->addEventListener( uno::Reference < lang::XEventListener > ( static_cast < lang::XEventListener* >( this ) ) ); m_pViewShell = pView; } if ( m_xClpbrdNtfr.is() ) { m_xClpbrdNtfr->addClipboardListener( uno::Reference< datatransfer::clipboard::XClipboardListener >( static_cast< datatransfer::clipboard::XClipboardListener* >( this ))); } } SfxClipboardChangeListener::~SfxClipboardChangeListener() { } void SfxClipboardChangeListener::ChangedContents() { const ::vos::OGuard aGuard( Application::GetSolarMutex() ); if( m_pViewShell ) { SfxBindings& rBind = m_pViewShell->GetViewFrame()->GetBindings(); rBind.Invalidate( SID_PASTE ); rBind.Invalidate( SID_PASTE_SPECIAL ); rBind.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS ); } } IMPL_STATIC_LINK_NOINSTANCE( SfxClipboardChangeListener, AsyncExecuteHdl_Impl, AsyncExecuteInfo*, pAsyncExecuteInfo ) { if ( pAsyncExecuteInfo ) { uno::Reference< datatransfer::clipboard::XClipboardListener > xThis( pAsyncExecuteInfo->m_xThis ); if ( pAsyncExecuteInfo->m_pListener ) { if ( pAsyncExecuteInfo->m_eCmd == ASYNCEXECUTE_CMD_DISPOSING ) pAsyncExecuteInfo->m_pListener->DisconnectViewShell(); else if ( pAsyncExecuteInfo->m_eCmd == ASYNCEXECUTE_CMD_CHANGEDCONTENTS ) pAsyncExecuteInfo->m_pListener->ChangedContents(); } } delete pAsyncExecuteInfo; return 0; } void SAL_CALL SfxClipboardChangeListener::disposing( const lang::EventObject& /*rEventObject*/ ) throw ( uno::RuntimeException ) { // Either clipboard or ViewShell is going to be destroyed -> no interest in listening anymore uno::Reference< lang::XComponent > xCtrl( m_xCtrl ); uno::Reference< datatransfer::clipboard::XClipboardNotifier > xNotify( m_xClpbrdNtfr ); uno::Reference< datatransfer::clipboard::XClipboardListener > xThis( static_cast< datatransfer::clipboard::XClipboardListener* >( this )); if ( xCtrl.is() ) xCtrl->removeEventListener( uno::Reference < lang::XEventListener > ( static_cast < lang::XEventListener* >( this ))); if ( xNotify.is() ) xNotify->removeClipboardListener( xThis ); // Make asynchronous call to avoid locking SolarMutex which is the // root for many deadlocks, especially in conjuction with the "Windows" // based single thread apartment clipboard code! AsyncExecuteInfo* pInfo = new AsyncExecuteInfo( ASYNCEXECUTE_CMD_DISPOSING, xThis, this ); Application::PostUserEvent( STATIC_LINK( 0, SfxClipboardChangeListener, AsyncExecuteHdl_Impl ), pInfo ); } void SAL_CALL SfxClipboardChangeListener::changedContents( const datatransfer::clipboard::ClipboardEvent& ) throw ( RuntimeException ) { // Make asynchronous call to avoid locking SolarMutex which is the // root for many deadlocks, especially in conjuction with the "Windows" // based single thread apartment clipboard code! uno::Reference< datatransfer::clipboard::XClipboardListener > xThis( static_cast< datatransfer::clipboard::XClipboardListener* >( this )); AsyncExecuteInfo* pInfo = new AsyncExecuteInfo( ASYNCEXECUTE_CMD_CHANGEDCONTENTS, xThis, this ); Application::PostUserEvent( STATIC_LINK( 0, SfxClipboardChangeListener, AsyncExecuteHdl_Impl ), pInfo ); } //========================================================================= static ::rtl::OUString RetrieveLabelFromCommand( const ::rtl::OUString& rCommandURL, const css::uno::Reference< css::frame::XFrame >& rFrame ) { static css::uno::WeakReference< frame::XModuleManager > s_xModuleManager; static css::uno::WeakReference< container::XNameAccess > s_xNameAccess; ::rtl::OUString aLabel; css::uno::Reference< css::frame::XModuleManager > xModuleManager( s_xModuleManager ); css::uno::Reference< css::container::XNameAccess > xNameAccess( s_xNameAccess ); css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR( ::comphelper::getProcessServiceFactory(), css::uno::UNO_QUERY_THROW); try { if ( !xModuleManager.is() ) { xModuleManager = css::uno::Reference< css::frame::XModuleManager >( xSMGR->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.ModuleManager" ))), css::uno::UNO_QUERY_THROW ); s_xModuleManager = xModuleManager; } ::rtl::OUString aModuleIdentifier = xModuleManager->identify( rFrame ); if ( !xNameAccess.is() ) { xNameAccess = css::uno::Reference< css::container::XNameAccess >( xSMGR->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.UICommandDescription" ))), css::uno::UNO_QUERY_THROW ); s_xNameAccess = xNameAccess; } css::uno::Any a = xNameAccess->getByName( aModuleIdentifier ); css::uno::Reference< css::container::XNameAccess > xUICommands; a >>= xUICommands; rtl::OUString aStr; css::uno::Sequence< css::beans::PropertyValue > aPropSeq; a = xUICommands->getByName( rCommandURL ); if ( a >>= aPropSeq ) { for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ ) { if ( aPropSeq[i].Name.equalsAscii( "Label" )) { aPropSeq[i].Value >>= aStr; break; } } aLabel = aStr; } } catch ( css::uno::Exception& ) { } return aLabel; } //========================================================================= SfxViewShell_Impl::SfxViewShell_Impl(sal_uInt16 const nFlags) : aInterceptorContainer( aMutex ) , m_bControllerSet(false) , m_nPrinterLocks(0) , m_bCanPrint(SFX_VIEW_CAN_PRINT == (nFlags & SFX_VIEW_CAN_PRINT)) , m_bHasPrintOptions( SFX_VIEW_HAS_PRINTOPTIONS == (nFlags & SFX_VIEW_HAS_PRINTOPTIONS)) , m_bPlugInsActive(true) , m_bIsShowView(SFX_VIEW_NO_SHOW != (nFlags & SFX_VIEW_NO_SHOW)) , m_bGotOwnership(false) , m_bGotFrameOwnership(false) , m_eScroll(SCROLLING_DEFAULT) , m_nFamily(0xFFFF) // undefined, default set by TemplateDialog , m_pController(0) , m_pAccExec(0) {} //========================================================================= SFX_IMPL_INTERFACE(SfxViewShell,SfxShell,SfxResId(0)) { SFX_CHILDWINDOW_REGISTRATION( SID_MAIL_CHILDWIN ); } TYPEINIT2(SfxViewShell,SfxShell,SfxListener); //-------------------------------------------------------------------- /** search for a filter name dependent on type and module */ static ::rtl::OUString impl_retrieveFilterNameFromTypeAndModule( const css::uno::Reference< css::container::XContainerQuery >& rContainerQuery, const ::rtl::OUString& rType, const ::rtl::OUString& rModuleIdentifier, const sal_Int32 nFlags ) { // Retrieve filter from type css::uno::Sequence< css::beans::NamedValue > aQuery( 2 ); aQuery[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Type" )); aQuery[0].Value = css::uno::makeAny( rType ); aQuery[1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentService" )); aQuery[1].Value = css::uno::makeAny( rModuleIdentifier ); css::uno::Reference< css::container::XEnumeration > xEnumeration = rContainerQuery->createSubSetEnumerationByProperties( aQuery ); ::rtl::OUString aFoundFilterName; while ( xEnumeration->hasMoreElements() ) { ::comphelper::SequenceAsHashMap aFilterPropsHM( xEnumeration->nextElement() ); ::rtl::OUString aFilterName = aFilterPropsHM.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "Name" ), ::rtl::OUString() ); sal_Int32 nFilterFlags = aFilterPropsHM.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "Flags" ), sal_Int32( 0 ) ); if ( nFilterFlags & nFlags ) { aFoundFilterName = aFilterName; break; } } return aFoundFilterName; } //-------------------------------------------------------------------- /** search for an internal typename, which map to the current app module and map also to a "family" of file formats as e.g. PDF/MS Doc/OOo Doc. */ enum ETypeFamily { E_MS_DOC, E_OOO_DOC }; ::rtl::OUString impl_searchFormatTypeForApp(const css::uno::Reference< css::frame::XFrame >& xFrame , ETypeFamily eTypeFamily) { static ::rtl::OUString SERVICENAME_MODULEMANAGER = ::rtl::OUString::createFromAscii("com.sun.star.frame.ModuleManager"); try { css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR (::comphelper::getProcessServiceFactory() , css::uno::UNO_QUERY_THROW); css::uno::Reference< css::frame::XModuleManager > xModuleManager(xSMGR->createInstance(SERVICENAME_MODULEMANAGER), css::uno::UNO_QUERY_THROW); ::rtl::OUString sModule = xModuleManager->identify(xFrame); ::rtl::OUString sType ; switch(eTypeFamily) { case E_MS_DOC: { if (sModule.equalsAscii( "com.sun.star.text.TextDocument" )) sType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "writer_MS_Word_97" )); else if (sModule.equalsAscii( "com.sun.star.sheet.SpreadsheetDocument" )) sType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "calc_MS_Excel_97" )); else if (sModule.equalsAscii( "com.sun.star.drawing.DrawingDocument" )) sType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "impress_MS_PowerPoint_97" )); else if (sModule.equalsAscii( "com.sun.star.presentation.PresentationDocument" )) sType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "impress_MS_PowerPoint_97" )); } break; case E_OOO_DOC: { if (sModule.equalsAscii( "com.sun.star.text.TextDocument" )) sType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "writer8" )); else if (sModule.equalsAscii( "com.sun.star.sheet.SpreadsheetDocument" )) sType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "calc8" )); else if (sModule.equalsAscii( "com.sun.star.drawing.DrawingDocument" )) sType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "draw8" )); else if (sModule.equalsAscii( "com.sun.star.presentation.PresentationDocument" )) sType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "impress8" )); } break; } return sType; } catch(const css::uno::RuntimeException& exRun) { throw exRun; } catch(const css::uno::Exception&) {} return ::rtl::OUString(); } //-------------------------------------------------------------------- void SfxViewShell::ExecMisc_Impl( SfxRequest &rReq ) { const sal_uInt16 nId = rReq.GetSlot(); switch( nId ) { case SID_STYLE_FAMILY : { SFX_REQUEST_ARG(rReq, pItem, SfxUInt16Item, nId, sal_False); if (pItem) { pImp->m_nFamily = pItem->GetValue(); } break; } case SID_STYLE_CATALOG: { SfxTemplateCatalog aCatalog( SFX_APP()->GetTopWindow(), &GetViewFrame()->GetBindings()); aCatalog.Execute(); rReq.Ignore(); break; } case SID_ACTIVATE_STYLE_APPLY: { com::sun::star::uno::Reference< com::sun::star::frame::XFrame > xFrame( GetViewFrame()->GetFrame().GetFrameInterface(), com::sun::star::uno::UNO_QUERY); Reference< com::sun::star::beans::XPropertySet > xPropSet( xFrame, UNO_QUERY ); Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager; if ( xPropSet.is() ) { try { Any aValue = xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))); aValue >>= xLayoutManager; if ( xLayoutManager.is() ) { rtl::OUString aTextResString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/textobjectbar" )); uno::Reference< ui::XUIElement > xElement = xLayoutManager->getElement( aTextResString ); if(!xElement.is()) { rtl::OUString aFrameResString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/frameobjectbar" )); xElement = xLayoutManager->getElement( aFrameResString ); } if(!xElement.is()) { rtl::OUString aOleResString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/oleobjectbar" )); xElement = xLayoutManager->getElement( aOleResString ); } if(xElement.is()) { uno::Reference< awt::XWindow > xWin( xElement->getRealInterface(), uno::UNO_QUERY_THROW ); Window* pWin = VCLUnoHelper::GetWindow( xWin ); ToolBox* pTextToolbox = dynamic_cast< ToolBox* >( pWin ); if( pTextToolbox ) { sal_uInt16 nItemCount = pTextToolbox->GetItemCount(); for( sal_uInt16 nItem = 0; nItem < nItemCount; ++nItem ) { sal_uInt16 nItemId = pTextToolbox->GetItemId( nItem ); const XubString& rCommand = pTextToolbox->GetItemCommand( nItemId ); if( rCommand.EqualsAscii( ".uno:StyleApply" ) ) { Window* pItemWin = pTextToolbox->GetItemWindow( nItemId ); if( pItemWin ) pItemWin->GrabFocus(); break; } } } } } } catch ( Exception& ) { } } rReq.Done(); } break; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case SID_MAIL_SENDDOCASMS: case SID_MAIL_SENDDOCASOOO: case SID_MAIL_SENDDOCASPDF: case SID_MAIL_SENDDOC: case SID_MAIL_SENDDOCASFORMAT: { SfxObjectShell* pDoc = GetObjectShell(); if ( pDoc && pDoc->QueryHiddenInformation( WhenSaving, &GetViewFrame()->GetWindow() ) != RET_YES ) break; if ( SvtInternalOptions().MailUIEnabled() ) { GetViewFrame()->SetChildWindow( SID_MAIL_CHILDWIN, sal_True ); } else { SfxMailModel aModel; rtl::OUString aDocType; SFX_REQUEST_ARG(rReq, pMailSubject, SfxStringItem, SID_MAIL_SUBJECT, sal_False ); if ( pMailSubject ) aModel.SetSubject( pMailSubject->GetValue() ); SFX_REQUEST_ARG(rReq, pMailRecipient, SfxStringItem, SID_MAIL_RECIPIENT, sal_False ); if ( pMailRecipient ) { String aRecipient( pMailRecipient->GetValue() ); String aMailToStr( String::CreateFromAscii( "mailto:" )); if ( aRecipient.Search( aMailToStr ) == 0 ) aRecipient = aRecipient.Erase( 0, aMailToStr.Len() ); aModel.AddAddress( aRecipient, SfxMailModel::ROLE_TO ); } SFX_REQUEST_ARG(rReq, pMailDocType, SfxStringItem, SID_TYPE_NAME, sal_False ); if ( pMailDocType ) aDocType = pMailDocType->GetValue(); uno::Reference < frame::XFrame > xFrame( pFrame->GetFrame().GetFrameInterface() ); SfxMailModel::SendMailResult eResult = SfxMailModel::SEND_MAIL_ERROR; if ( nId == SID_MAIL_SENDDOC ) eResult = aModel.SaveAndSend( xFrame, rtl::OUString() ); else if ( nId == SID_MAIL_SENDDOCASPDF ) eResult = aModel.SaveAndSend( xFrame, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "pdf_Portable_Document_Format" ))); else if ( nId == SID_MAIL_SENDDOCASMS ) { aDocType = impl_searchFormatTypeForApp(xFrame, E_MS_DOC); if (aDocType.getLength() > 0) eResult = aModel.SaveAndSend( xFrame, aDocType ); } else if ( nId == SID_MAIL_SENDDOCASOOO ) { aDocType = impl_searchFormatTypeForApp(xFrame, E_OOO_DOC); if (aDocType.getLength() > 0) eResult = aModel.SaveAndSend( xFrame, aDocType ); } if ( eResult == SfxMailModel::SEND_MAIL_ERROR ) { InfoBox aBox( SFX_APP()->GetTopWindow(), SfxResId( MSG_ERROR_SEND_MAIL )); aBox.Execute(); rReq.Ignore(); } else rReq.Done(); } break; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case SID_WEBHTML: { static const char HTML_DOCUMENT_TYPE[] = "writer_web_HTML"; static const char HTML_GRAPHIC_TYPE[] = "graphic_HTML"; const sal_Int32 FILTERFLAG_EXPORT = 0x00000002; css::uno::Reference< lang::XMultiServiceFactory > xSMGR(::comphelper::getProcessServiceFactory(), css::uno::UNO_QUERY_THROW); css::uno::Reference < css::frame::XFrame > xFrame( pFrame->GetFrame().GetFrameInterface() ); css::uno::Reference< css::frame::XModel > xModel; const rtl::OUString aModuleManager( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.ModuleManager" )); css::uno::Reference< css::frame::XModuleManager > xModuleManager( xSMGR->createInstance( aModuleManager ), css::uno::UNO_QUERY_THROW ); if ( !xModuleManager.is() ) { rReq.Done(sal_False); return; } rtl::OUString aModule; try { aModule = xModuleManager->identify( xFrame ); } catch ( css::uno::RuntimeException& ) { throw; } catch ( css::uno::Exception& ) { } if ( xFrame.is() ) { css::uno::Reference< css::frame::XController > xController = xFrame->getController(); if ( xController.is() ) xModel = xController->getModel(); } // We need at least a valid module name and model reference css::uno::Reference< css::frame::XStorable > xStorable( xModel, css::uno::UNO_QUERY ); if ( xModel.is() && xStorable.is() ) { rtl::OUString aFilterName; rtl::OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM( HTML_DOCUMENT_TYPE )); rtl::OUString aFileName; rtl::OUString aExtension( RTL_CONSTASCII_USTRINGPARAM( "htm" )); rtl::OUString aLocation = xStorable->getLocation(); INetURLObject aFileObj( aLocation ); bool bPrivateProtocol = ( aFileObj.GetProtocol() == INET_PROT_PRIV_SOFFICE ); bool bHasLocation = ( aLocation.getLength() > 0 ) && !bPrivateProtocol; css::uno::Reference< css::container::XContainerQuery > xContainerQuery( xSMGR->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.FilterFactory" ))), css::uno::UNO_QUERY_THROW ); // Retrieve filter from type sal_Int32 nFilterFlags = FILTERFLAG_EXPORT; aFilterName = impl_retrieveFilterNameFromTypeAndModule( xContainerQuery, aTypeName, aModule, nFilterFlags ); if ( aFilterName.getLength() == 0 ) { // Draw/Impress uses a different type. 2nd chance try to use alternative type name aFilterName = impl_retrieveFilterNameFromTypeAndModule( xContainerQuery, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( HTML_GRAPHIC_TYPE )), aModule, nFilterFlags ); } // No filter found => error // No type and no location => error if (( aFilterName.getLength() == 0 ) || ( aTypeName.getLength() == 0 )) { rReq.Done(sal_False); return; } // Use provided save file name. If empty determine file name if ( !bHasLocation ) { // Create a default file name with the correct extension const rtl::OUString aPreviewFileName( RTL_CONSTASCII_USTRINGPARAM( "webpreview" )); aFileName = aPreviewFileName; } else { // Determine file name from model INetURLObject aFObj( xStorable->getLocation() ); aFileName = aFObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::NO_DECODE ); } OSL_ASSERT( aFilterName.getLength() > 0 ); OSL_ASSERT( aFileName.getLength() > 0 ); // Creates a temporary directory to store our predefined file into it. ::utl::TempFile aTempDir( NULL, sal_True ); INetURLObject aFilePathObj( aTempDir.GetURL() ); aFilePathObj.insertName( aFileName ); aFilePathObj.setExtension( aExtension ); rtl::OUString aFileURL = aFilePathObj.GetMainURL( INetURLObject::NO_DECODE ); css::uno::Sequence< css::beans::PropertyValue > aArgs( 1 ); aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" )); aArgs[0].Value = css::uno::makeAny( aFilterName ); // Store document in the html format try { xStorable->storeToURL( aFileURL, aArgs ); } catch ( com::sun::star::io::IOException& ) { rReq.Done(sal_False); return; } ::com::sun::star::uno::Reference< XSystemShellExecute > xSystemShellExecute( com::sun::star::system::SystemShellExecute::create( ::comphelper::getProcessComponentContext() ) ); sal_Bool bRet( sal_True ); if ( xSystemShellExecute.is() ) { try { xSystemShellExecute->execute( aFileURL, ::rtl::OUString(), SystemShellExecuteFlags::DEFAULTS ); } catch ( uno::Exception& ) { vos::OGuard aGuard( Application::GetSolarMutex() ); Window *pParent = SFX_APP()->GetTopWindow(); ErrorBox( pParent, SfxResId( MSG_ERROR_NO_WEBBROWSER_FOUND )).Execute(); bRet = sal_False; } } rReq.Done(bRet); break; } else { rReq.Done(sal_False); return; } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case SID_PLUGINS_ACTIVE: { SFX_REQUEST_ARG(rReq, pShowItem, SfxBoolItem, nId, sal_False); bool const bActive = (pShowItem) ? pShowItem->GetValue() : !pImp->m_bPlugInsActive; // ggf. recorden if ( !rReq.IsAPI() ) rReq.AppendItem( SfxBoolItem( nId, bActive ) ); // Jetzt schon DONE aufrufen, da die Argumente evtl. einen Pool // benutzen, der demn"achst weg ist rReq.Done(sal_True); // ausfuehren if (!pShowItem || (bActive != pImp->m_bPlugInsActive)) { SfxFrame* pTopFrame = &GetFrame()->GetTopFrame(); if ( pTopFrame != &GetFrame()->GetFrame() ) { // FramesetDocument SfxViewShell *pShell = pTopFrame->GetCurrentViewFrame()->GetViewShell(); if ( pShell->GetInterface()->GetSlot( nId ) ) pShell->ExecuteSlot( rReq ); break; } SfxFrameIterator aIter( *pTopFrame ); while ( pTopFrame ) { if ( pTopFrame->GetCurrentViewFrame() ) { SfxViewShell *pView = pTopFrame->GetCurrentViewFrame()->GetViewShell(); if ( pView ) { pView->pImp->m_bPlugInsActive = bActive; Rectangle aVisArea = GetObjectShell()->GetVisArea(); VisAreaChanged(aVisArea); // the plugins might need change in their state SfxInPlaceClientList *pClients = pView->GetIPClientList_Impl(sal_False); if ( pClients ) { for (sal_uInt16 n=0; n < pClients->Count(); n++) { SfxInPlaceClient* pIPClient = pClients->GetObject(n); if ( pIPClient ) pView->CheckIPClient_Impl( pIPClient, aVisArea ); } } } } if ( !pTopFrame->GetParentFrame() ) pTopFrame = aIter.FirstFrame(); else pTopFrame = aIter.NextFrame( *pTopFrame ); } } break; } } } //-------------------------------------------------------------------- void SfxViewShell::GetState_Impl( SfxItemSet &rSet ) { DBG_CHKTHIS(SfxViewShell, 0); SfxWhichIter aIter( rSet ); for ( sal_uInt16 nSID = aIter.FirstWhich(); nSID; nSID = aIter.NextWhich() ) { switch ( nSID ) { case SID_STYLE_CATALOG: { if ( !GetViewFrame()->KnowsChildWindow( SID_STYLE_DESIGNER ) ) rSet.DisableItem( nSID ); break; } // Printer-Funktionen case SID_PRINTDOC: case SID_PRINTDOCDIRECT: case SID_SETUPPRINTER: case SID_PRINTER_NAME: { bool bEnabled = pImp->m_bCanPrint && !pImp->m_nPrinterLocks; bEnabled = bEnabled && !Application::GetSettings().GetMiscSettings().GetDisablePrinting(); if ( bEnabled ) { SfxPrinter *pPrinter = GetPrinter(sal_False); if ( SID_PRINTDOCDIRECT == nSID ) { rtl::OUString aPrinterName; if ( pPrinter != NULL ) aPrinterName = pPrinter->GetName(); else aPrinterName = Printer::GetDefaultPrinterName(); if ( aPrinterName.getLength() > 0 ) { uno::Reference < frame::XFrame > xFrame( pFrame->GetFrame().GetFrameInterface() ); ::rtl::OUStringBuffer aBuffer( 60 ); aBuffer.append( RetrieveLabelFromCommand( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:PrintDefault" )), xFrame )); aBuffer.appendAscii( " (" ); aBuffer.append( aPrinterName ); aBuffer.appendAscii( ")" ); rSet.Put( SfxStringItem( SID_PRINTDOCDIRECT, aBuffer.makeStringAndClear() ) ); } } bEnabled = !pPrinter || !pPrinter->IsPrinting(); } if ( !bEnabled ) { // will now be handled by requeing the request /* rSet.DisableItem( SID_PRINTDOC ); rSet.DisableItem( SID_PRINTDOCDIRECT ); rSet.DisableItem( SID_SETUPPRINTER ); */ } break; } // Mail-Funktionen case SID_MAIL_SENDDOCASPDF: case SID_MAIL_SENDDOC: case SID_MAIL_SENDDOCASFORMAT: { sal_Bool bEnable = !GetViewFrame()->HasChildWindow( SID_MAIL_CHILDWIN ); if ( !bEnable ) rSet.DisableItem( nSID ); break; } // PlugIns running case SID_PLUGINS_ACTIVE: { rSet.Put( SfxBoolItem( SID_PLUGINS_ACTIVE, !pImp->m_bPlugInsActive) ); break; } /* // SelectionText case SID_SELECTION_TEXT: { rSet.Put( SfxStringItem( SID_SELECTION_TEXT, GetSelectionText() ) ); break; } // SelectionTextExt case SID_SELECTION_TEXT_EXT: { rSet.Put( SfxStringItem( SID_SELECTION_TEXT_EXT, GetSelectionText(sal_True) ) ); break; } */ case SID_STYLE_FAMILY : { rSet.Put( SfxUInt16Item( SID_STYLE_FAMILY, pImp->m_nFamily ) ); break; } } } } //-------------------------------------------------------------------- void SfxViewShell::SetZoomFactor( const Fraction &rZoomX, const Fraction &rZoomY ) { DBG_ASSERT( GetWindow(), "no window" ); MapMode aMap( GetWindow()->GetMapMode() ); aMap.SetScaleX( rZoomX ); aMap.SetScaleY( rZoomY ); GetWindow()->SetMapMode( aMap ); } //-------------------------------------------------------------------- ErrCode SfxViewShell::DoVerb(long /*nVerb*/) /* [Beschreibung] Virtuelle Methode, um am selektierten Objekt ein Verb auszuf"uhren. Da dieses Objekt nur den abgeleiteten Klassen bekannt ist, muss DoVerb dort "uberschrieben werden. */ { return ERRCODE_SO_NOVERBS; } //-------------------------------------------------------------------- void SfxViewShell::OutplaceActivated( sal_Bool bActive, SfxInPlaceClient* /*pClient*/ ) { if ( !bActive ) GetFrame()->GetFrame().Appear(); } //-------------------------------------------------------------------- void SfxViewShell::InplaceActivating( SfxInPlaceClient* /*pClient*/ ) { // TODO/LATER: painting of the bitmap can be stopped, it is required if CLIPCHILDREN problem #i25788# is not solved, // but may be the bug will not affect the real office vcl windows, then it is not required } //-------------------------------------------------------------------- void SfxViewShell::InplaceDeactivated( SfxInPlaceClient* /*pClient*/ ) { // TODO/LATER: paint the replacement image in normal way if the painting was stopped } //-------------------------------------------------------------------- void SfxViewShell::UIActivating( SfxInPlaceClient* /*pClient*/ ) { uno::Reference < frame::XFrame > xOwnFrame( pFrame->GetFrame().GetFrameInterface() ); uno::Reference < frame::XFramesSupplier > xParentFrame( xOwnFrame->getCreator(), uno::UNO_QUERY ); if ( xParentFrame.is() ) xParentFrame->setActiveFrame( xOwnFrame ); pFrame->GetBindings().HidePopups(sal_True); pFrame->GetDispatcher()->Update_Impl( sal_True ); } //-------------------------------------------------------------------- void SfxViewShell::UIDeactivated( SfxInPlaceClient* /*pClient*/ ) { if ( !pFrame->GetFrame().IsClosing_Impl() || SfxViewFrame::Current() != pFrame ) pFrame->GetDispatcher()->Update_Impl( sal_True ); pFrame->GetBindings().HidePopups(sal_False); // uno::Reference < frame::XFrame > xOwnFrame( pFrame->GetFrame().GetFrameInterface() ); // uno::Reference < frame::XFramesSupplier > xParentFrame( xOwnFrame->getCreator(), uno::UNO_QUERY ); // if ( xParentFrame.is() ) // xParentFrame->setActiveFrame( uno::Reference < frame::XFrame >() ); } //-------------------------------------------------------------------- SfxInPlaceClient* SfxViewShell::FindIPClient ( const uno::Reference < embed::XEmbeddedObject >& xObj, Window* pObjParentWin ) const { SfxInPlaceClientList *pClients = GetIPClientList_Impl(sal_False); if ( !pClients ) return 0; if( !pObjParentWin ) pObjParentWin = GetWindow(); for (sal_uInt16 n=0; n < pClients->Count(); n++) { SfxInPlaceClient *pIPClient = (SfxInPlaceClient*) pClients->GetObject(n); if ( pIPClient->GetObject() == xObj && pIPClient->GetEditWin() == pObjParentWin ) return pIPClient; } return 0; } //-------------------------------------------------------------------- SfxInPlaceClient* SfxViewShell::GetIPClient() const { return GetUIActiveClient(); } //-------------------------------------------------------------------- SfxInPlaceClient* SfxViewShell::GetUIActiveIPClient_Impl() const { // this method is needed as long as SFX still manages the border space for ChildWindows (see SfxFrame::Resize) SfxInPlaceClientList *pClients = GetIPClientList_Impl(sal_False); if ( !pClients ) return 0; for (sal_uInt16 n=0; n < pClients->Count(); n++) { SfxInPlaceClient* pIPClient = pClients->GetObject(n); if ( pIPClient->IsUIActive() ) return pIPClient; } return NULL; } SfxInPlaceClient* SfxViewShell::GetUIActiveClient() const { SfxInPlaceClientList *pClients = GetIPClientList_Impl(sal_False); if ( !pClients ) return 0; for (sal_uInt16 n=0; n < pClients->Count(); n++) { SfxInPlaceClient* pIPClient = pClients->GetObject(n); if ( pIPClient->IsObjectUIActive() ) return pIPClient; } return NULL; } //-------------------------------------------------------------------- void SfxViewShell::Activate( sal_Bool bMDI ) { DBG_CHKTHIS(SfxViewShell, 0); if ( bMDI ) { SfxObjectShell *pSh = GetViewFrame()->GetObjectShell(); if ( pSh->GetModel().is() ) pSh->GetModel()->setCurrentController( GetViewFrame()->GetFrame().GetController() ); SetCurrentDocument(); } } //-------------------------------------------------------------------- void SfxViewShell::Deactivate(sal_Bool /*bMDI*/) { DBG_CHKTHIS(SfxViewShell, 0); } //-------------------------------------------------------------------- void SfxViewShell::AdjustPosSizePixel ( const Point& /*rToolOffset*/,// linke obere Ecke der Tools im Frame-Window const Size& /*rSize*/ // gesamte zur Verf"ugung stehende Gr"o\se ) { DBG_CHKTHIS(SfxViewShell, 0); } //-------------------------------------------------------------------- void SfxViewShell::Move() /* [Beschreibung] Diese virtuelle Methode wird gerufen, wenn das Fenster, in dem die SfxViewShell dargestellt wird eine StarView-Move() Nachricht erh"alt. Die Basisimplementierung braucht nicht gerufen zu werden. [Anmerkung] Diese Methode kann dazu verwendet werden, eine Selektion abzubrechen, um durch das Moven des Fensters erzeugte Maus-Bewegungen anzufangen. Zur Zeit funktioniert die Benachrichtigung nicht In-Place. */ { } //-------------------------------------------------------------------- void SfxViewShell::OuterResizePixel ( const Point& /*rToolOffset*/,// linke obere Ecke der Tools im Frame-Window const Size& /*rSize*/ // gesamte zur Verf"ugung stehende Gr"o\se ) /* [Beschreibung] Diese Methode muss ueberladen werden, um auf "Anderungen der Groesse der View zu reagieren. Dabei definieren wir die View als das Edit-Window zuz"uglich der um das Edit-Window angeordnenten Tools (z.B. Lineale). Das Edit-Window darf weder in Gr"o\se noch Position ver"andert werden. Die Vis-Area der SfxObjectShell, dessen Skalierung und Position d"urfen hier ver"andert werden. Der Hauptanwendungsfall ist dabei, das Ver"andern der Gr"o\se der Vis-Area. "Andert sich durch die neue Berechnung der Border, so mu\s dieser mit gesetzt werden. Erst nach Aufruf von 'SetBorderPixel' ist das Positionieren von Tools erlaubt. [Beispiel] void AppViewSh::OuterViewResizePixel( const Point &rOfs, const Size &rSz ) { // Tool-Positionen und Gr"o\sen von au\sen berechnen, NICHT setzen! // (wegen folgender Border-Berechnung) Point aHLinPos...; Size aHLinSz...; ... // Border f"ur Tools passend zu rSize berechnen und setzen SvBorder aBorder... SetBorderPixel( aBorder ); // ab jetzt sind Positionierungen erlaubt // Tools anordnen pHLin->SetPosSizePixel( aHLinPos, aHLinSz ); ... } [Querverweise] */ { DBG_CHKTHIS(SfxViewShell, 0); SetBorderPixel( SvBorder() ); } //-------------------------------------------------------------------- void SfxViewShell::InnerResizePixel ( const Point& /*rToolOffset*/,// linke obere Ecke der Tools im Frame-Window const Size& /*rSize*/ // dem Edit-Win zur Verf"ugung stehende Gr"o\se ) /* [Beschreibung] Diese Methode muss ueberladen werden, um auf "Anderungen der Groesse des Edit-Windows zu reagieren. Das Edit-Window darf weder in Gr"o\se noch Position ver"andert werden. Weder die Vis-Area der SfxObjectShell noch dessen Skalierung oder Position d"urfen ver"andert werden. "Andert sich durch die neue Berechnung der Border, so mu\s dieser mit gesetzt werden. Erst nach Aufruf von 'SetBorderPixel' ist das Positionieren von Tools erlaubt. [Beispiel] void AppViewSh::InnerViewResizePixel( const Point &rOfs, const Size &rSz ) { // Tool-Positionen und Gr"o\sen von innen berechnen, NICHT setzen! // (wegen folgender Border-Berechnung) Point aHLinPos...; Size aHLinSz...; ... // Border f"ur Tools passend zu rSz berechnen und setzen SvBorder aBorder... SetBorderPixel( aBorder ); // ab jetzt sind Positionierungen erlaubt // Tools anordnen pHLin->SetPosSizePixel( aHLinPos, aHLinSz ); ... } [Querverweise] */ { DBG_CHKTHIS(SfxViewShell, 0); SetBorderPixel( SvBorder() ); } //-------------------------------------------------------------------- void SfxViewShell::InvalidateBorder() { DBG_CHKTHIS(SfxViewShell, 0); DBG_ASSERT( GetViewFrame(), "SfxViewShell without SfxViewFrame" ); GetViewFrame()->InvalidateBorderImpl( this ); if (pImp->m_pController.is()) { pImp->m_pController->BorderWidthsChanged_Impl(); } } //-------------------------------------------------------------------- void SfxViewShell::SetBorderPixel( const SvBorder &rBorder ) { DBG_CHKTHIS(SfxViewShell, 0); DBG_ASSERT( GetViewFrame(), "SfxViewShell without SfxViewFrame" ); //if ( rBorder != GetBorderPixel()) { GetViewFrame()->SetBorderPixelImpl( this, rBorder ); // notify related controller that border size is changed if (pImp->m_pController.is()) { pImp->m_pController->BorderWidthsChanged_Impl(); } } } //-------------------------------------------------------------------- const SvBorder& SfxViewShell::GetBorderPixel() const { DBG_CHKTHIS(SfxViewShell, 0); DBG_ASSERT( GetViewFrame(), "SfxViewShell without SfxViewFrame" ); return GetViewFrame()->GetBorderPixelImpl( this ); } //-------------------------------------------------------------------- void SfxViewShell::SetWindow ( Window* pViewPort // Pointer auf das Datenfenster bzw. 0 im Destruktor ) /* [Beschreibung] Mit dieser Methode wird der SfxViewShell das Datenfenster mitgeteilt. Dieses wird f"ur den In-Place-Container und f"ur das korrekte Wiederherstellen des Focus ben"otigt. Selbst In-Place-aktiv ist das Umsetzen des ViewPort-Windows verboten. */ { if( pWindow == pViewPort ) return; // ggf. vorhandene IP-Clients disconnecten DisconnectAllClients(); //TODO: should we have a "ReconnectAllClients" method? DiscardClients_Impl(); // View-Port austauschen sal_Bool bHadFocus = pWindow ? pWindow->HasChildPathFocus( sal_True ) : sal_False; pWindow = pViewPort; if( pWindow ) { // Disable automatic GUI mirroring (right-to-left) for document windows pWindow->EnableRTL( sal_False ); } if ( bHadFocus && pWindow ) pWindow->GrabFocus(); //TODO/CLEANUP //brauchen wir die Methode doch noch?! //SFX_APP()->GrabFocus( pWindow ); } //-------------------------------------------------------------------- Size SfxViewShell::GetOptimalSizePixel() const { DBG_ERROR( "Useless call!" ); return Size(); } //------------------------------------------------------------------------ SfxViewShell::SfxViewShell ( SfxViewFrame* pViewFrame, /* , in dem diese View dargestellt wird */ sal_uInt16 nFlags /* siehe */ ) : SfxShell(this) , pImp( new SfxViewShell_Impl(nFlags) ) ,pIPClientList( 0 ) ,pFrame(pViewFrame) ,pSubShell(0) ,pWindow(0) ,bNoNewWindow( 0 != (nFlags & SFX_VIEW_NO_NEWWINDOW) ) { DBG_CTOR(SfxViewShell, 0); //pImp->pPrinterCommandQueue = new SfxAsyncPrintExec_Impl( this ); if ( pViewFrame->GetParentViewFrame() ) { pImp->m_bPlugInsActive = pViewFrame->GetParentViewFrame() ->GetViewShell()->pImp->m_bPlugInsActive; } SetMargin( pViewFrame->GetMargin_Impl() ); SetPool( &pViewFrame->GetObjectShell()->GetPool() ); StartListening(*pViewFrame->GetObjectShell()); // in Liste eintragen const SfxViewShell *pThis = this; // wegen der kranken Array-Syntax SfxViewShellArr_Impl &rViewArr = SFX_APP()->GetViewShells_Impl(); rViewArr.Insert(pThis, rViewArr.Count() ); } //-------------------------------------------------------------------- SfxViewShell::~SfxViewShell() { DBG_DTOR(SfxViewShell, 0); // aus Liste austragen const SfxViewShell *pThis = this; SfxViewShellArr_Impl &rViewArr = SFX_APP()->GetViewShells_Impl(); rViewArr.Remove( rViewArr.GetPos(pThis) ); if ( pImp->xClipboardListener.is() ) { pImp->xClipboardListener->DisconnectViewShell(); pImp->xClipboardListener = NULL; } if (pImp->m_pController.is()) { pImp->m_pController->ReleaseShell_Impl(); pImp->m_pController.clear(); } //DELETEZ( pImp->pPrinterCommandQueue ); DELETEZ( pImp ); DELETEZ( pIPClientList ); } //-------------------------------------------------------------------- sal_uInt16 SfxViewShell::PrepareClose ( sal_Bool bUI, // sal_True: Dialoge etc. erlaubt, sal_False: silent-mode sal_Bool /*bForBrowsing*/ ) { SfxPrinter *pPrinter = GetPrinter(); if ( pPrinter && pPrinter->IsPrinting() ) { if ( bUI ) { InfoBox aInfoBox( &GetViewFrame()->GetWindow(), SfxResId( MSG_CANT_CLOSE ) ); aInfoBox.Execute(); } return sal_False; } if( GetViewFrame()->IsInModalMode() ) return sal_False; if( bUI && GetViewFrame()->GetDispatcher()->IsLocked() ) return sal_False; return sal_True; } //-------------------------------------------------------------------- SfxViewShell* SfxViewShell::Current() { SfxViewFrame *pCurrent = SfxViewFrame::Current(); return pCurrent ? pCurrent->GetViewShell() : NULL; } //-------------------------------------------------------------------- SfxViewShell* SfxViewShell::Get( const Reference< XController>& i_rController ) { if ( !i_rController.is() ) return NULL; for ( SfxViewShell* pViewShell = SfxViewShell::GetFirst( NULL, sal_False ); pViewShell; pViewShell = SfxViewShell::GetNext( *pViewShell, NULL, sal_False ) ) { if ( pViewShell->GetController() == i_rController ) return pViewShell; } return NULL; } //-------------------------------------------------------------------- SdrView* SfxViewShell::GetDrawView() const /* [Beschreibung] Diese virtuelle Methode mu\s von den Subklassen "uberladen werden, wenn der Property-Editor zur Verf"ugung stehen soll. Die Default-Implementierung liefert immer 0. */ { return 0; } //-------------------------------------------------------------------- String SfxViewShell::GetSelectionText ( sal_Bool /*bCompleteWords*/ /* sal_False (default) Nur der tats"achlich selektierte Text wird zur"uckgegeben. TRUE Der selektierte Text wird soweit erweitert, da\s nur ganze W"orter zur"uckgegeben werden. Als Worttrenner gelten White-Spaces und die Satzzeichen ".,;" sowie einfache und doppelte Anf"uhrungszeichen. */ ) /* [Beschreibung] Diese Methode kann von Anwendungsprogrammierer "uberladen werden, um einen Text zur"uckzuliefern, der in der aktuellen Selektion steht. Dieser wird z.B. beim Versenden (email) verwendet. Mit "CompleteWords == TRUE" ger"ufen, reicht z.B. auch der Cursor, der in einer URL steht, um die gesamte URL zu liefern. */ { return String(); } //-------------------------------------------------------------------- sal_Bool SfxViewShell::HasSelection( sal_Bool ) const /* [Beschreibung] Mit dieser virtuellen Methode kann z.B. ein Dialog abfragen, ob in der aktuellen View etwas selektiert ist. Wenn der Parameter sal_True ist, wird abgefragt, ob Text selektiert ist. */ { return sal_False; } //-------------------------------------------------------------------- void SfxViewShell::SetSubShell( SfxShell *pShell ) /* [Beschreibung] Mit dieser Methode kann eine Selektions- oder Cursor-Shell angemeldet werden, die automatisch unmittelbar nach der SfxViewShell auf den SfxDispatcher gepusht wird, und automatisch umittelbar vor ihr gepoppt wird. Ist die SfxViewShell-Instanz bereits gepusht, dann wird pShell sofort ebenfalls gepusht. Wird mit SetSubShell eine andere SfxShell Instanz angemeldet, als vorher angemeldet war, wird die zuvor angemeldete ggf. automatisch gepoppt. Mit pShell==0 kann daher die aktuelle Sub-Shell abgemeldet werden. */ { // ist diese ViewShell "uberhaupt aktiv? SfxDispatcher *pDisp = pFrame->GetDispatcher(); if ( pDisp->IsActive(*this) ) { // Dispatcher updaten if ( pSubShell ) pDisp->Pop(*pSubShell); if ( pShell ) pDisp->Push(*pShell); pDisp->Flush(); } pSubShell = pShell; } void SfxViewShell::AddSubShell( SfxShell& rShell ) { pImp->aArr.Insert( &rShell, pImp->aArr.Count() ); SfxDispatcher *pDisp = pFrame->GetDispatcher(); if ( pDisp->IsActive(*this) ) { pDisp->Push(rShell); pDisp->Flush(); } } void SfxViewShell::RemoveSubShell( SfxShell* pShell ) { SfxDispatcher *pDisp = pFrame->GetDispatcher(); if ( !pShell ) { sal_uInt16 nCount = pImp->aArr.Count(); if ( pDisp->IsActive(*this) ) { for ( sal_uInt16 n=nCount; n>0; n-- ) pDisp->Pop( *pImp->aArr[n-1] ); pDisp->Flush(); } pImp->aArr.Remove(0, nCount); } else { sal_uInt16 nPos = pImp->aArr.GetPos( pShell ); if ( nPos != 0xFFFF ) { pImp->aArr.Remove( nPos ); if ( pDisp->IsActive(*this) ) { pDisp->RemoveShell_Impl( *pShell ); pDisp->Flush(); } } } } SfxShell* SfxViewShell::GetSubShell( sal_uInt16 nNo ) { sal_uInt16 nCount = pImp->aArr.Count(); if ( nNoaArr[nCount-nNo-1]; return NULL; } void SfxViewShell::PushSubShells_Impl( sal_Bool bPush ) { sal_uInt16 nCount = pImp->aArr.Count(); SfxDispatcher *pDisp = pFrame->GetDispatcher(); if ( bPush ) { for ( sal_uInt16 n=0; nPush( *pImp->aArr[n] ); } else if ( nCount ) { SfxShell& rPopUntil = *pImp->aArr[0]; if ( pDisp->GetShellLevel( rPopUntil ) != USHRT_MAX ) pDisp->Pop( rPopUntil, SFX_SHELL_POP_UNTIL ); } pDisp->Flush(); } //-------------------------------------------------------------------- void SfxViewShell::WriteUserData( String&, sal_Bool ) { } //-------------------------------------------------------------------- void SfxViewShell::ReadUserData(const String&, sal_Bool ) { } void SfxViewShell::ReadUserDataSequence ( const ::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue >&, sal_Bool ) { } void SfxViewShell::WriteUserDataSequence ( ::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue >&, sal_Bool ) { } //-------------------------------------------------------------------- // returns the first shell of spec. type viewing the specified doc. SfxViewShell* SfxViewShell::GetFirst ( const TypeId* pType, sal_Bool bOnlyVisible ) { // search for a SfxViewShell of the specified type SfxViewShellArr_Impl &rShells = SFX_APP()->GetViewShells_Impl(); SfxViewFrameArr_Impl &rFrames = SFX_APP()->GetViewFrames_Impl(); for ( sal_uInt16 nPos = 0; nPos < rShells.Count(); ++nPos ) { SfxViewShell *pShell = rShells.GetObject(nPos); if ( pShell ) { // sometimes dangling SfxViewShells exist that point to a dead SfxViewFrame // these ViewShells shouldn't be accessible anymore // a destroyed ViewFrame is not in the ViewFrame array anymore, so checking this array helps for ( sal_uInt16 n=0; nGetViewFrame() ) { // only ViewShells with a valid ViewFrame will be returned if ( ( !bOnlyVisible || pFrame->IsVisible() ) && ( !pType || pShell->IsA(*pType) ) ) return pShell; break; } } } } return 0; } //-------------------------------------------------------------------- // returns the next shell of spec. type viewing the specified doc. SfxViewShell* SfxViewShell::GetNext ( const SfxViewShell& rPrev, const TypeId* pType, sal_Bool bOnlyVisible ) { SfxViewShellArr_Impl &rShells = SFX_APP()->GetViewShells_Impl(); SfxViewFrameArr_Impl &rFrames = SFX_APP()->GetViewFrames_Impl(); sal_uInt16 nPos; for ( nPos = 0; nPos < rShells.Count(); ++nPos ) if ( rShells.GetObject(nPos) == &rPrev ) break; for ( ++nPos; nPos < rShells.Count(); ++nPos ) { SfxViewShell *pShell = rShells.GetObject(nPos); if ( pShell ) { // sometimes dangling SfxViewShells exist that point to a dead SfxViewFrame // these ViewShells shouldn't be accessible anymore // a destroyed ViewFrame is not in the ViewFrame array anymore, so checking this array helps for ( sal_uInt16 n=0; nGetViewFrame() ) { // only ViewShells with a valid ViewFrame will be returned if ( ( !bOnlyVisible || pFrame->IsVisible() ) && ( !pType || pShell->IsA(*pType) ) ) return pShell; break; } } } } return 0; } //-------------------------------------------------------------------- void SfxViewShell::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) { if ( rHint.IsA(TYPE(SfxEventHint)) ) { switch ( ((SfxEventHint&)rHint).GetEventId() ) { case SFX_EVENT_LOADFINISHED: { if ( GetController().is() ) { // avoid access to dangling ViewShells SfxViewFrameArr_Impl &rFrames = SFX_APP()->GetViewFrames_Impl(); for ( sal_uInt16 n=0; nGetMedium()->GetItemSet(); SFX_ITEMSET_ARG( pSet, pItem, SfxUnoAnyItem, SID_VIEW_DATA, sal_False ); if ( pItem ) { pImp->m_pController->restoreViewData( pItem->GetValue() ); pSet->ClearItem( SID_VIEW_DATA ); } break; } } } break; } } } } //-------------------------------------------------------------------- sal_Bool SfxViewShell::ExecKey_Impl(const KeyEvent& aKey) { if (!pImp->m_pAccExec.get()) { pImp->m_pAccExec.reset( ::svt::AcceleratorExecute::createAcceleratorHelper() ); pImp->m_pAccExec->init(::comphelper::getProcessServiceFactory(), pFrame->GetFrame().GetFrameInterface()); } return pImp->m_pAccExec->execute(aKey.GetKeyCode()); } //-------------------------------------------------------------------- FASTBOOL SfxViewShell::KeyInput( const KeyEvent &rKeyEvent ) /* [Beschreibung] Diese Methode f"uhrt das KeyEvent 'rKeyEvent' "uber die an dieser SfxViewShell direkt oder indirekt (z.B. via Applikation) konfigurierten Tasten (Accelerator) aus. [R"uckgabewert] FASTBOOL sal_True die Taste ist konfiguriert, der betreffende Handler wurde gerufen FALSE die Taste ist nicht konfiguriert, es konnte also kein Handler gerufen werden [Querverweise] */ { return ExecKey_Impl(rKeyEvent); } bool SfxViewShell::GlobalKeyInput_Impl( const KeyEvent &rKeyEvent ) { return ExecKey_Impl(rKeyEvent); } //-------------------------------------------------------------------- void SfxViewShell::ShowCursor( FASTBOOL /*bOn*/ ) /* [Beschreibung] Diese Methode mu\s von Subklassen "uberladen werden, damit vom SFx aus der Cursor ein- und ausgeschaltet werden kann. Dies geschieht z.B. bei laufendem . */ { } //-------------------------------------------------------------------- void SfxViewShell::GotFocus() const /* [Beschreibung] Diese Methode mu\s vom Applikationsentwickler gerufen werden, wenn das Edit-Window den Focus erhalten hat. Der SFx hat so z.B. die M"oglichkeit, den Accelerator einzuschalten. [Anmerkung] liefert leider keine M"oglichkeit, solche Events 'von der Seite' einzuh"angen. */ { } //-------------------------------------------------------------------- void SfxViewShell::ResetAllClients_Impl( SfxInPlaceClient *pIP ) { SfxInPlaceClientList *pClients = GetIPClientList_Impl(sal_False); if ( !pClients ) return; for ( sal_uInt16 n=0; n < pClients->Count(); n++ ) { SfxInPlaceClient* pIPClient = pClients->GetObject(n); if( pIPClient != pIP ) pIPClient->ResetObject(); } } //-------------------------------------------------------------------- void SfxViewShell::DisconnectAllClients() { SfxInPlaceClientList *pClients = GetIPClientList_Impl(sal_False); if ( !pClients ) return; for ( sal_uInt16 n=0; nCount(); ) // clients will remove themselves from the list delete pClients->GetObject(n); } //-------------------------------------------------------------------- void SfxViewShell::QueryObjAreaPixel( Rectangle& ) const { } //-------------------------------------------------------------------- void SfxViewShell::AdjustVisArea(const Rectangle& rRect) { DBG_ASSERT (pFrame, "Kein Frame?"); GetObjectShell()->SetVisArea( rRect ); } //-------------------------------------------------------------------- void SfxViewShell::VisAreaChanged(const Rectangle& /*rVisArea*/) { SfxInPlaceClientList *pClients = GetIPClientList_Impl(sal_False); if ( !pClients ) return; for (sal_uInt16 n=0; n < pClients->Count(); n++) { SfxInPlaceClient* pIPClient = pClients->GetObject(n); if ( pIPClient->IsObjectInPlaceActive() ) // client is active, notify client that the VisArea might have changed pIPClient->VisAreaChanged(); } } //-------------------------------------------------------------------- void SfxViewShell::CheckIPClient_Impl( SfxInPlaceClient *pIPClient, const Rectangle& rVisArea ) { if ( GetObjectShell()->IsInClose() ) return; sal_Bool bAlwaysActive = ( ( pIPClient->GetObjectMiscStatus() & embed::EmbedMisc::EMBED_ACTIVATEIMMEDIATELY ) != 0 ); sal_Bool bActiveWhenVisible = ( ( pIPClient->GetObjectMiscStatus() & embed::EmbedMisc::MS_EMBED_ACTIVATEWHENVISIBLE ) != 0 ); // this method is called when either a client is created or the "Edit/Plugins" checkbox is checked if ( !pIPClient->IsObjectInPlaceActive() && pImp->m_bPlugInsActive ) { // object in client is currently not active // check if the object wants to be activated always or when it becomes at least partially visible // TODO/LATER: maybe we should use the scaled area instead of the ObjArea?! if ( bAlwaysActive || (bActiveWhenVisible && rVisArea.IsOver(pIPClient->GetObjArea())) ) { try { pIPClient->GetObject()->changeState( embed::EmbedStates::INPLACE_ACTIVE ); } catch ( uno::Exception& ) { } } } else if (!pImp->m_bPlugInsActive) { // object in client is currently active and "Edit/Plugins" checkbox is selected // check if the object wants to be activated always or when it becomes at least partially visible // in this case selecting of the "Edit/Plugin" checkbox should let such objects deactivate if ( bAlwaysActive || bActiveWhenVisible ) pIPClient->GetObject()->changeState( embed::EmbedStates::RUNNING ); } } //-------------------------------------------------------------------- sal_Bool SfxViewShell::PlugInsActive() const { return pImp->m_bPlugInsActive; } //-------------------------------------------------------------------- void SfxViewShell::DiscardClients_Impl() /* [Beschreibung] Diese Methode dient dazu, vor dem Schlie\sen eines Dokuments das Speichern der Objekte zu verhindern, wenn der Benutzer Schlie\en ohne Speichern gew"ahlt hatte. */ { SfxInPlaceClientList *pClients = GetIPClientList_Impl(sal_False); if ( !pClients ) return; for (sal_uInt16 n=0; n < pClients->Count(); ) delete pClients->GetObject(n); } //-------------------------------------------------------------------- SfxScrollingMode SfxViewShell::GetScrollingMode() const { return pImp->m_eScroll; } //-------------------------------------------------------------------- void SfxViewShell::SetScrollingMode( SfxScrollingMode eMode ) { pImp->m_eScroll = eMode; } //-------------------------------------------------------------------- SfxObjectShell* SfxViewShell::GetObjectShell() { return pFrame ? pFrame->GetObjectShell() : NULL; } //-------------------------------------------------------------------- Reference< XModel > SfxViewShell::GetCurrentDocument() const { Reference< XModel > xDocument; const SfxObjectShell* pDocShell( const_cast< SfxViewShell* >( this )->GetObjectShell() ); OSL_ENSURE( pDocShell, "SfxViewFrame::GetCurrentDocument: no DocShell!?" ); if ( pDocShell ) xDocument = pDocShell->GetModel(); return xDocument; } //-------------------------------------------------------------------- void SfxViewShell::SetCurrentDocument() const { uno::Reference< frame::XModel > xDocument( GetCurrentDocument() ); if ( xDocument.is() ) SfxObjectShell::SetCurrentComponent( xDocument ); } //-------------------------------------------------------------------- const Size& SfxViewShell::GetMargin() const { return pImp->aMargin; } //-------------------------------------------------------------------- void SfxViewShell::SetMargin( const Size& rSize ) { // Der default-Margin wurde "geeicht" mit www.apple.com !! Size aMargin = rSize; if ( aMargin.Width() == -1 ) aMargin.Width() = DEFAULT_MARGIN_WIDTH; if ( aMargin.Height() == -1 ) aMargin.Height() = DEFAULT_MARGIN_HEIGHT; if ( aMargin != pImp->aMargin ) { pImp->aMargin = aMargin; MarginChanged(); } } //-------------------------------------------------------------------- void SfxViewShell::MarginChanged() { } //-------------------------------------------------------------------- sal_Bool SfxViewShell::IsShowView_Impl() const { return pImp->m_bIsShowView; } //-------------------------------------------------------------------- SfxFrame* SfxViewShell::GetSmartSelf( SfxFrame* pSelf, SfxMedium& /*rMedium*/ ) { return pSelf; } //------------------------------------------------------------------------ void SfxViewShell::JumpToMark( const String& rMark ) { SfxStringItem aMarkItem( SID_JUMPTOMARK, rMark ); GetViewFrame()->GetDispatcher()->Execute( SID_JUMPTOMARK, SFX_CALLMODE_SYNCHRON|SFX_CALLMODE_RECORD, &aMarkItem, 0L ); } //------------------------------------------------------------------------ SfxInPlaceClientList* SfxViewShell::GetIPClientList_Impl( sal_Bool bCreate ) const { if ( !pIPClientList && bCreate ) ( (SfxViewShell*) this )->pIPClientList = new SfxInPlaceClientList; return pIPClientList; } void SfxViewShell::SetController( SfxBaseController* pController ) { pImp->m_pController = pController; pImp->m_bControllerSet = true; // there should be no old listener, but if there is one, it should be disconnected if ( pImp->xClipboardListener.is() ) pImp->xClipboardListener->DisconnectViewShell(); pImp->xClipboardListener = new SfxClipboardChangeListener( this, GetClipboardNotifier() ); } Reference < XController > SfxViewShell::GetController() { return pImp->m_pController.get(); } SfxBaseController* SfxViewShell::GetBaseController_Impl() const { return pImp->m_pController.get(); } void SfxViewShell::AddContextMenuInterceptor_Impl( const REFERENCE< XCONTEXTMENUINTERCEPTOR >& xInterceptor ) { pImp->aInterceptorContainer.addInterface( xInterceptor ); } void SfxViewShell::RemoveContextMenuInterceptor_Impl( const REFERENCE< XCONTEXTMENUINTERCEPTOR >& xInterceptor ) { pImp->aInterceptorContainer.removeInterface( xInterceptor ); } ::cppu::OInterfaceContainerHelper& SfxViewShell::GetContextMenuInterceptors() const { return pImp->aInterceptorContainer; } void Change( Menu* pMenu, SfxViewShell* pView ) { SfxDispatcher *pDisp = pView->GetViewFrame()->GetDispatcher(); sal_uInt16 nCount = pMenu->GetItemCount(); for ( sal_uInt16 nPos=0; nPosGetItemId(nPos); String aCmd = pMenu->GetItemCommand(nId); PopupMenu* pPopup = pMenu->GetPopupMenu(nId); if ( pPopup ) { Change( pPopup, pView ); } else if ( nId < 5000 ) { if ( aCmd.CompareToAscii(".uno:", 5) == 0 ) { for (sal_uInt16 nIdx=0;;) { SfxShell *pShell=pDisp->GetShell(nIdx++); if (pShell == NULL) break; const SfxInterface *pIFace = pShell->GetInterface(); const SfxSlot* pSlot = pIFace->GetSlot( aCmd ); if ( pSlot ) { pMenu->InsertItem( pSlot->GetSlotId(), pMenu->GetItemText( nId ), pMenu->GetItemBits( nId ), nPos ); pMenu->SetItemCommand( pSlot->GetSlotId(), aCmd ); pMenu->RemoveItem( nPos+1 ); break; } } } } } } sal_Bool SfxViewShell::TryContextMenuInterception( Menu& rIn, const ::rtl::OUString& rMenuIdentifier, Menu*& rpOut, ui::ContextMenuExecuteEvent aEvent ) { rpOut = NULL; sal_Bool bModified = sal_False; // create container from menu // #110897# // aEvent.ActionTriggerContainer = ::framework::ActionTriggerHelper::CreateActionTriggerContainerFromMenu( &rIn ); aEvent.ActionTriggerContainer = ::framework::ActionTriggerHelper::CreateActionTriggerContainerFromMenu( ::comphelper::getProcessServiceFactory(), &rIn, &rMenuIdentifier ); // get selection from controller aEvent.Selection = uno::Reference < view::XSelectionSupplier > ( GetController(), uno::UNO_QUERY ); // call interceptors ::cppu::OInterfaceIteratorHelper aIt( pImp->aInterceptorContainer ); while( aIt.hasMoreElements() ) { try { ui::ContextMenuInterceptorAction eAction = ((ui::XContextMenuInterceptor*)aIt.next())->notifyContextMenuExecute( aEvent ); switch ( eAction ) { case ui::ContextMenuInterceptorAction_CANCELLED : // interceptor does not want execution return sal_False; case ui::ContextMenuInterceptorAction_EXECUTE_MODIFIED : // interceptor wants his modified menu to be executed bModified = sal_True; break; case ui::ContextMenuInterceptorAction_CONTINUE_MODIFIED : // interceptor has modified menu, but allows for calling other interceptors bModified = sal_True; continue; case ui::ContextMenuInterceptorAction_IGNORED : // interceptor is indifferent continue; default: DBG_ERROR("Wrong return value of ContextMenuInterceptor!"); continue; } } catch( uno::RuntimeException& ) { aIt.remove(); } break; } if ( bModified ) { // container was modified, create a new window out of it rpOut = new PopupMenu; ::framework::ActionTriggerHelper::CreateMenuFromActionTriggerContainer( rpOut, aEvent.ActionTriggerContainer ); Change( rpOut, this ); } return sal_True; } void SfxViewShell::TakeOwnerShip_Impl() { // currently there is only one reason to take OwnerShip: a hidden frame is printed // so the ViewShell will check this on EndPrint (->prnmon.cxx) pImp->m_bGotOwnership = true; } void SfxViewShell::TakeFrameOwnerShip_Impl() { // currently there is only one reason to take OwnerShip: a hidden frame is printed // so the ViewShell will check this on EndPrint (->prnmon.cxx) pImp->m_bGotFrameOwnership = true; } void SfxViewShell::CheckOwnerShip_Impl() { sal_Bool bSuccess = sal_False; if (pImp->m_bGotOwnership) { uno::Reference < util::XCloseable > xModel( GetObjectShell()->GetModel(), uno::UNO_QUERY ); if ( xModel.is() ) { try { // this call will destroy this object in case of success! xModel->close( sal_True ); bSuccess = sal_True; } catch ( util::CloseVetoException& ) { } } } if (!bSuccess && pImp->m_bGotFrameOwnership) { // document couldn't be closed or it shouldn't, now try at least to close the frame uno::Reference < util::XCloseable > xFrame( GetViewFrame()->GetFrame().GetFrameInterface(), com::sun::star::uno::UNO_QUERY ); if ( xFrame.is() ) { try { xFrame->close( sal_True ); } catch ( util::CloseVetoException& ) { } } } } long SfxViewShell::HandleNotifyEvent_Impl( NotifyEvent& rEvent ) { if (pImp->m_pController.is()) return pImp->m_pController->HandleEvent_Impl( rEvent ); return 0; } sal_Bool SfxViewShell::HasKeyListeners_Impl() { return (pImp->m_pController.is()) ? pImp->m_pController->HasKeyListeners_Impl() : sal_False; } sal_Bool SfxViewShell::HasMouseClickListeners_Impl() { return (pImp->m_pController.is()) ? pImp->m_pController->HasMouseClickListeners_Impl() : sal_False; } void SfxViewShell::SetAdditionalPrintOptions( const com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue >& rOpts ) { pImp->aPrintOpts = rOpts; // GetObjectShell()->Broadcast( SfxPrintingHint( -3, NULL, NULL, rOpts ) ); } sal_Bool SfxViewShell::Escape() { return GetViewFrame()->GetBindings().Execute( SID_TERMINATE_INPLACEACTIVATION ); } Reference< view::XRenderable > SfxViewShell::GetRenderable() { Reference< view::XRenderable >xRender; SfxObjectShell* pObj = GetObjectShell(); if( pObj ) { Reference< frame::XModel > xModel( pObj->GetModel() ); if( xModel.is() ) xRender = Reference< view::XRenderable >( xModel, UNO_QUERY ); } return xRender; } uno::Reference< datatransfer::clipboard::XClipboardNotifier > SfxViewShell::GetClipboardNotifier() { uno::Reference< datatransfer::clipboard::XClipboardNotifier > xClipboardNotifier; if ( GetViewFrame() ) xClipboardNotifier = uno::Reference< datatransfer::clipboard::XClipboardNotifier >( GetViewFrame()->GetWindow().GetClipboard(), uno::UNO_QUERY ); return xClipboardNotifier; } void SfxViewShell::AddRemoveClipboardListener( const uno::Reference < datatransfer::clipboard::XClipboardListener >& rClp, sal_Bool bAdd ) { try { if ( GetViewFrame() ) { uno::Reference< datatransfer::clipboard::XClipboard > xClipboard( GetViewFrame()->GetWindow().GetClipboard() ); if( xClipboard.is() ) { uno::Reference< datatransfer::clipboard::XClipboardNotifier > xClpbrdNtfr( xClipboard, uno::UNO_QUERY ); if( xClpbrdNtfr.is() ) { if( bAdd ) xClpbrdNtfr->addClipboardListener( rClp ); else xClpbrdNtfr->removeClipboardListener( rClp ); } } } } catch( const uno::Exception& ) { } }