diff options
Diffstat (limited to 'sfx2/source/appl')
55 files changed, 30748 insertions, 0 deletions
diff --git a/sfx2/source/appl/app.cxx b/sfx2/source/appl/app.cxx new file mode 100644 index 000000000000..7e4e9921573a --- /dev/null +++ b/sfx2/source/appl/app.cxx @@ -0,0 +1,845 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" + +#if defined UNX +#include <limits.h> +#else // UNX +#include <stdlib.h> +#define PATH_MAX _MAX_PATH +#endif // UNX + +#include <sfx2/app.hxx> +#include <sfx2/frame.hxx> +#include <vos/process.hxx> +#include <tools/simplerm.hxx> +#include <tools/config.hxx> +#include <basic/basrdll.hxx> +#include <svtools/asynclink.hxx> +#include <svl/stritem.hxx> +#ifndef _SOUND_HXX //autogen +#include <vcl/sound.hxx> +#endif +#include <svl/eitem.hxx> +#include <svl/urlbmk.hxx> +#ifndef _MSGBOX_HXX //autogen +#include <vcl/msgbox.hxx> +#endif +#include <svtools/sfxecode.hxx> +#include <svtools/ehdl.hxx> + +#include <svl/svdde.hxx> +#include <tools/urlobj.hxx> +#include <unotools/tempfile.hxx> +#include <osl/file.hxx> +#ifndef GCC +#endif + +#define _SVSTDARR_STRINGSDTOR +#include <svl/svstdarr.hxx> + +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/frame/XFrameActionListener.hpp> +#include <com/sun/star/frame/XComponentLoader.hpp> +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/frame/FrameActionEvent.hpp> +#include <com/sun/star/frame/FrameAction.hpp> +#include <com/sun/star/loader/XImplementationLoader.hpp> +#include <com/sun/star/loader/CannotActivateFactoryException.hpp> +#include <com/sun/star/mozilla/XPluginInstance.hpp> +#include <com/sun/star/frame/XFramesSupplier.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#ifndef _UNOTOOLS_PROCESSFACTORY_HXX +#include <comphelper/processfactory.hxx> +#endif +#include <com/sun/star/uri/XUriReferenceFactory.hpp> +#include <com/sun/star/uri/XVndSunStarScriptUrl.hpp> + +#include <basic/basmgr.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <vcl/svapp.hxx> + +#include <rtl/logfile.hxx> + +#include <sfx2/appuno.hxx> +#include "sfxhelp.hxx" +#include <sfx2/request.hxx> +#include "sfxtypes.hxx" +#include "sfxresid.hxx" +#include "arrdecl.hxx" +#include <sfx2/progress.hxx> +#include <sfx2/objsh.hxx> +#include <sfx2/docfac.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/docfilt.hxx> +#include "fltfnc.hxx" +#include "nfltdlg.hxx" +#include <sfx2/new.hxx> +#include <sfx2/bindings.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/viewsh.hxx> +#include <sfx2/genlink.hxx> +#include <sfx2/viewfrm.hxx> +#include "appdata.hxx" +#include "openflag.hxx" +#include "app.hrc" +#include "virtmenu.hxx" +#include <sfx2/module.hxx> +#include <sfx2/event.hxx> +#include "imestatuswindow.hxx" +#include "workwin.hxx" +#include <sfx2/module.hxx> +#include <sfx2/tbxctrl.hxx> +#include <sfx2/sfxdlg.hxx> +#include "stbitem.hxx" +#include "eventsupplier.hxx" +#include <sfx2/dockwin.hxx> + +#ifdef DBG_UTIL +#include <sfx2/tbxctrl.hxx> +#include <sfx2/mnuitem.hxx> +#endif + +#if defined( WNT ) || defined( OS2 ) +#define DDE_AVAILABLE +#endif + +#include <unotools/saveopt.hxx> +#include <unotools/undoopt.hxx> +#include <svtools/helpopt.hxx> +#include <unotools/pathoptions.hxx> +#include <unotools/viewoptions.hxx> +#include <unotools/moduleoptions.hxx> +#include <unotools/historyoptions.hxx> +#include <svtools/menuoptions.hxx> +#include <svtools/miscopt.hxx> +#include <unotools/useroptions.hxx> +#include <unotools/startoptions.hxx> +#include <unotools/securityoptions.hxx> +#include <unotools/localisationoptions.hxx> +#include <unotools/inetoptions.hxx> +#include <unotools/fontoptions.hxx> +#include <unotools/internaloptions.hxx> +#include <unotools/workingsetoptions.hxx> +#include <unotools/syslocaleoptions.hxx> +#include <unotools/syslocale.hxx> +#include <framework/addonsoptions.hxx> +#include <svtools/ttprops.hxx> +#include <unotools/extendedsecurityoptions.hxx> + +using namespace ::com::sun::star; + +// Static member +SfxApplication* SfxApplication::pApp = NULL; +static BasicDLL* pBasic = NULL; + +class SfxPropertyHandler : public PropertyHandler +{ + virtual void Property( ApplicationProperty& ); +}; + +static SfxPropertyHandler* pPropertyHandler = 0; + +SfxPropertyHandler* GetOrCreatePropertyHandler() +{ + if ( !pPropertyHandler ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if ( !pPropertyHandler ) + pPropertyHandler = new SfxPropertyHandler; + } + + return pPropertyHandler; +} + +void SfxPropertyHandler::Property( ApplicationProperty& rProp ) +{ + TTProperties* pTTProperties = PTR_CAST( TTProperties, &rProp ); + if ( pTTProperties ) + { + pTTProperties->nPropertyVersion = TT_PROPERTIES_VERSION; + switch ( pTTProperties->nActualPR ) + { + case TT_PR_SLOTS: + { + pTTProperties->nSidOpenUrl = SID_OPENURL; + pTTProperties->nSidFileName = SID_FILE_NAME; + pTTProperties->nSidNewDocDirect = SID_NEWDOCDIRECT; + pTTProperties->nSidCopy = SID_COPY; + pTTProperties->nSidPaste = SID_PASTE; + pTTProperties->nSidSourceView = SID_SOURCEVIEW; + pTTProperties->nSidSelectAll = SID_SELECTALL; + pTTProperties->nSidReferer = SID_REFERER; + pTTProperties->nActualPR = 0; + } + break; + case TT_PR_DISPATCHER: + { + // interface for TestTool + SfxViewFrame* pViewFrame=0; + SfxDispatcher* pDispatcher=0; + pViewFrame = SfxViewFrame::Current(); + if ( !pViewFrame ) + pViewFrame = SfxViewFrame::GetFirst(); + if ( pViewFrame ) + pDispatcher = pViewFrame->GetDispatcher(); + else + pDispatcher = NULL; + if ( !pDispatcher ) + pTTProperties->nActualPR = TT_PR_ERR_NODISPATCHER; + else + { + pDispatcher->SetExecuteMode(EXECUTEMODE_DIALOGASYNCHRON); + if ( pTTProperties->mnSID == SID_NEWDOCDIRECT + || pTTProperties->mnSID == SID_OPENDOC ) + { + SfxPoolItem** pArgs = pTTProperties->mppArgs; + SfxAllItemSet aSet( SFX_APP()->GetPool() ); + if ( pArgs && *pArgs ) + { + for ( SfxPoolItem **pArg = pArgs; *pArg; ++pArg ) + aSet.Put( **pArg ); + } + if ( pTTProperties->mnSID == SID_NEWDOCDIRECT ) + { + String aFactory = String::CreateFromAscii("private:factory/"); + if ( pArgs && *pArgs ) + { + SFX_ITEMSET_ARG( &aSet, pFactoryName, SfxStringItem, SID_NEWDOCDIRECT, FALSE ); + if ( pFactoryName ) + aFactory += pFactoryName->GetValue(); + else + aFactory += String::CreateFromAscii("swriter"); + } + else + aFactory += String::CreateFromAscii("swriter"); + + aSet.Put( SfxStringItem( SID_FILE_NAME, aFactory ) ); + aSet.ClearItem( SID_NEWDOCDIRECT ); + pTTProperties->mnSID = SID_OPENDOC; + } + + aSet.Put( SfxStringItem( SID_TARGETNAME, DEFINE_CONST_UNICODE("_blank") ) ); + if ( pDispatcher->ExecuteFunction( pTTProperties->mnSID, aSet, pTTProperties->mnMode ) + == EXECUTE_NO ) + pTTProperties->nActualPR = TT_PR_ERR_NOEXECUTE; + else + pTTProperties->nActualPR = 0; + } + else + { + if ( pDispatcher->ExecuteFunction( + pTTProperties->mnSID, pTTProperties->mppArgs, pTTProperties->mnMode ) + == EXECUTE_NO ) + pTTProperties->nActualPR = TT_PR_ERR_NOEXECUTE; + else + pTTProperties->nActualPR = 0; + } + } + } + break; +/* + case TT_PR_IMG: + { + SvDataMemberObjectRef aDataObject = new SvDataMemberObject(); + SvData* pDataBmp = new SvData( FORMAT_BITMAP ); + pDataBmp->SetData( pTTProperties->mpBmp ); + aDataObject->Append( pDataBmp ); + aDataObject->CopyClipboard(); + pTTProperties->nActualPR = 0; + } + break; +*/ + default: + { + pTTProperties->nPropertyVersion = 0; + } + } + return; + } +} + +#include <framework/imageproducer.hxx> +#include <framework/acceleratorinfo.hxx> +#include <framework/sfxhelperfunctions.hxx> +#include "imagemgr.hxx" +#include "fwkhelper.hxx" + +::osl::Mutex SfxApplication::gMutex; + +SfxApplication* SfxApplication::GetOrCreate() +{ + // SFX on demand + ::osl::MutexGuard aGuard(SfxApplication::gMutex); + if ( !pApp ) + { + SfxApplication *pNew = new SfxApplication; + + //TODO/CLEANUP + //ist das Mutex-Handling OK? + static ::osl::Mutex aProtector; + ::osl::MutexGuard aGuard2( aProtector ); + + RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mb93783) ::SfxApplication::SetApp" ); + pApp = pNew; + + // at the moment a bug may occur when Initialize_Impl returns FALSE, but this is only temporary because all code that may cause such a + // fault will be moved outside the SFX + pApp->Initialize_Impl(); + + ::framework::SetImageProducer( GetImage ); + ::framework::SetRefreshToolbars( RefreshToolbars ); + ::framework::SetToolBoxControllerCreator( SfxToolBoxControllerFactory ); + ::framework::SetStatusBarControllerCreator( SfxStatusBarControllerFactory ); + ::framework::SetDockingWindowCreator( SfxDockingWindowFactory ); + ::framework::SetIsDockingWindowVisible( IsDockingWindowVisible ); + ::framework::SetActivateToolPanel( &SfxViewFrame::ActivateToolPanel ); + + SfxHelp* pSfxHelp = new SfxHelp; + Application::SetHelp( pSfxHelp ); + if ( SvtHelpOptions().IsHelpTips() ) + Help::EnableQuickHelp(); + else + Help::DisableQuickHelp(); + if ( SvtHelpOptions().IsHelpTips() && SvtHelpOptions().IsExtendedHelp() ) + Help::EnableBalloonHelp(); + else + Help::DisableBalloonHelp(); + } + return pApp; +} + +SfxApplication::SfxApplication() + : pAppData_Impl( 0 ) +{ + RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mb93783) ::SfxApplication::SfxApplication" ); + + SetName( DEFINE_CONST_UNICODE("StarOffice") ); + GetpApp()->SetPropertyHandler( GetOrCreatePropertyHandler() ); + + SvtViewOptions::AcquireOptions(); + + pAppData_Impl = new SfxAppData_Impl( this ); + pAppData_Impl->UpdateApplicationSettings( SvtMenuOptions().IsEntryHidingEnabled() ); + pAppData_Impl->m_xImeStatusWindow->init(); + pApp->PreInit(); + + RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ initialize DDE" ); + +#ifdef DDE_AVAILABLE +#ifndef DBG_UTIL + InitializeDde(); +#else + if( !InitializeDde() ) + { + ByteString aStr( "Kein DDE-Service moeglich. Fehler: " ); + if( GetDdeService() ) + aStr += ByteString::CreateFromInt32(GetDdeService()->GetError()); + else + aStr += '?'; + DBG_ASSERT( sal_False, aStr.GetBuffer() ); + } +#endif +#endif + + if ( !InitLabelResMgr( "iso" ) ) + // no "iso" resource -> search for "ooo" resource + InitLabelResMgr( "ooo", true ); + pBasic = new BasicDLL; + + StarBASIC::SetGlobalErrorHdl( LINK( this, SfxApplication, GlobalBasicErrorHdl_Impl ) ); + + + + RTL_LOGFILE_CONTEXT_TRACE( aLog, "} initialize DDE" ); +} + +SfxApplication::~SfxApplication() +{ + Broadcast( SfxSimpleHint(SFX_HINT_DYING) ); + + SfxModule::DestroyModules_Impl(); + + // delete global options + SvtViewOptions::ReleaseOptions(); + delete pBasic; + + if ( !pAppData_Impl->bDowning ) + Deinitialize(); + + delete pAppData_Impl; + pApp = 0; +} + +//==================================================================== + +const String& SfxApplication::GetLastDir_Impl() const + +/* [Beschreibung] + + Interne Methode, mit der im SFx das zuletzt mit der Methode + <SfxApplication::SetLastDir_Impl()> gesetzte Verzeichnis + zurueckgegeben wird. + + Dieses ist i.d.R. das zuletzt durch den SfxFileDialog + angesprochene Verzeichnis. + + [Querverweis] + <SfxApplication::SetLastDir_Impl()> +*/ + +{ + return pAppData_Impl->aLastDir; +} + +const String& SfxApplication::GetLastSaveDirectory() const + +/* [Beschreibung] + + Wie <SfxApplication::GetLastDir_Impl()>, nur extern + + [Querverweis] + <SfxApplication::GetLastDir_Impl()> +*/ + +{ + return GetLastDir_Impl(); +} + +//-------------------------------------------------------------------- + +void SfxApplication::SetLastDir_Impl +( + const String& rNewDir /* kompletter Verzeichnis-Pfad als String */ + ) + +/* [Beschreibung] + + Interne Methode, mit der ein Verzeichnis-Pfad gesetzt wird, der + zuletzt (z.B. durch den SfxFileDialog) angesprochen wurde. + + [Querverweis] + <SfxApplication::GetLastDir_Impl()> +*/ + +{ + pAppData_Impl->aLastDir = rNewDir; +} + +//-------------------------------------------------------------------- + +void SfxApplication::ResetLastDir() +{ + String aEmpty; + pAppData_Impl->aLastDir = aEmpty; +} + +//-------------------------------------------------------------------- + +SfxDispatcher* SfxApplication::GetDispatcher_Impl() +{ + return pAppData_Impl->pViewFrame? pAppData_Impl->pViewFrame->GetDispatcher(): pAppData_Impl->pAppDispat; +} + +//-------------------------------------------------------------------- +void SfxApplication::SetViewFrame_Impl( SfxViewFrame *pFrame ) +{ + if ( pFrame != pAppData_Impl->pViewFrame ) + { + // get the containerframes ( if one of the frames is an InPlaceFrame ) + SfxViewFrame *pOldContainerFrame = pAppData_Impl->pViewFrame; + while ( pOldContainerFrame && pOldContainerFrame->GetParentViewFrame_Impl() ) + pOldContainerFrame = pOldContainerFrame->GetParentViewFrame_Impl(); + SfxViewFrame *pNewContainerFrame = pFrame; + while ( pNewContainerFrame && pNewContainerFrame->GetParentViewFrame_Impl() ) + pNewContainerFrame = pNewContainerFrame->GetParentViewFrame_Impl(); + + // DocWinActivate : both frames belong to the same TopWindow + // TopWinActivate : both frames belong to different TopWindows +// not used anymore! +// BOOL bDocWinActivate = pOldContainerFrame && pNewContainerFrame && +// pOldContainerFrame->GetTopViewFrame() == pNewContainerFrame->GetTopViewFrame(); + BOOL bTaskActivate = pOldContainerFrame != pNewContainerFrame; + + if ( pOldContainerFrame ) + { + if ( bTaskActivate ) + NotifyEvent( SfxEventHint( SFX_EVENT_DEACTIVATEDOC, GlobalEventConfig::GetEventName(STR_EVENT_DEACTIVATEDOC), pOldContainerFrame->GetObjectShell() ) ); + pOldContainerFrame->DoDeactivate( bTaskActivate, pFrame ); + + if( pOldContainerFrame->GetProgress() ) + pOldContainerFrame->GetProgress()->Suspend(); + } + + pAppData_Impl->pViewFrame = pFrame; + + //const SfxObjectShell* pSh = pViewFrame ? pViewFrame->GetObjectShell() : 0; + //if ( !pSh ) + //{ + // // otherwise BaseURL is set in activation of document + // INetURLObject aObject( SvtPathOptions().GetWorkPath() ); + // aObject.setFinalSlash(); + // INetURLObject::SetBaseURL( aObject.GetMainURL( INetURLObject::NO_DECODE ) ); + //} + + if( pNewContainerFrame ) + { + pNewContainerFrame->DoActivate( bTaskActivate ); + if ( bTaskActivate && pNewContainerFrame->GetObjectShell() ) + { + pNewContainerFrame->GetObjectShell()->PostActivateEvent_Impl( pNewContainerFrame ); + NotifyEvent(SfxEventHint(SFX_EVENT_ACTIVATEDOC, GlobalEventConfig::GetEventName(STR_EVENT_ACTIVATEDOC), pNewContainerFrame->GetObjectShell() ) ); + } + + SfxProgress *pProgress = pNewContainerFrame->GetProgress(); + if ( pProgress ) + { + if( pProgress->IsSuspended() ) + pProgress->Resume(); + else + pProgress->SetState( pProgress->GetState() ); + } + + if ( pAppData_Impl->pViewFrame->GetViewShell() ) + { + SfxDispatcher* pDisp = pAppData_Impl->pViewFrame->GetDispatcher(); + pDisp->Flush(); + pDisp->Update_Impl(sal_True); + } + } + } + + // even if the frame actually didn't change, ensure its document is forwarded + // to SfxObjectShell::SetCurrentComponent. + // Otherwise, the CurrentComponent might not be correct, in case it has meanwhile + // been reset to some other document, by some non-SFX component. + // #i49133# / 2007-12-19 / frank.schoenheit@sun.com + if ( pFrame && pFrame->GetViewShell() ) + pFrame->GetViewShell()->SetCurrentDocument(); +} + +//-------------------------------------------------------------------- + +short SfxApplication::QuerySave_Impl( SfxObjectShell& rDoc, sal_Bool /*bAutoSave*/ ) +{ + if ( !rDoc.IsModified() ) + return RET_NO; + + String aMsg( SfxResId( STR_ISMODIFIED ) ); + aMsg.SearchAndReplaceAscii( "%1", rDoc.GetTitle() ); + + SfxFrame& rFrame = SfxViewFrame::GetFirst(&rDoc)->GetFrame(); + rFrame.Appear(); + + WinBits nBits = WB_YES_NO_CANCEL | WB_DEF_NO; + QueryBox aBox( &rFrame.GetWindow(), nBits, aMsg ); + + return aBox.Execute(); +} + +//--------------------------------------------------------------------- + +ResMgr* SfxApplication::CreateResManager( const char *pPrefix ) +{ + String aMgrName = String::CreateFromAscii( pPrefix ); + return ResMgr::CreateResMgr(U2S(aMgrName)); +} + +//--------------------------------------------------------------------- + +SimpleResMgr* SfxApplication::CreateSimpleResManager() +{ + SimpleResMgr *pRet; + const AllSettings& rAllSettings = Application::GetSettings(); + ::com::sun::star::lang::Locale aLocale = rAllSettings.GetUILocale(); + pRet = new SimpleResMgr( CREATEVERSIONRESMGR_NAME(sfx), aLocale ); + + return pRet; +} + +//-------------------------------------------------------------------- + +ResMgr* SfxApplication::GetSfxResManager() +{ + return SfxResId::GetResMgr(); +} + +//-------------------------------------------------------------------- + +ResMgr* SfxApplication::GetLabelResManager() const +{ + return pAppData_Impl->pLabelResMgr; +} + +//-------------------------------------------------------------------- + +SimpleResMgr* SfxApplication::GetSimpleResManager() +{ + if ( !pAppData_Impl->pSimpleResManager ) + pAppData_Impl->pSimpleResManager = CreateSimpleResManager(); + return pAppData_Impl->pSimpleResManager; +} + +//------------------------------------------------------------------------ + +void SfxApplication::SetProgress_Impl +( + SfxProgress *pProgress + +) +{ + DBG_ASSERT( ( !pAppData_Impl->pProgress && pProgress ) || + ( pAppData_Impl->pProgress && !pProgress ), + "Progress acitivation/deacitivation mismatch" ); + + if ( pAppData_Impl->pProgress && pProgress ) + { + pAppData_Impl->pProgress->Suspend(); + pAppData_Impl->pProgress->UnLock(); + delete pAppData_Impl->pProgress; + } + + pAppData_Impl->pProgress = pProgress; +} + +//------------------------------------------------------------------------ + +sal_uInt16 SfxApplication::GetFreeIndex() +{ + return pAppData_Impl->aIndexBitSet.GetFreeIndex()+1; +} + +//------------------------------------------------------------------------ + +void SfxApplication::ReleaseIndex(sal_uInt16 i) +{ + pAppData_Impl->aIndexBitSet.ReleaseIndex(i-1); +} + +//-------------------------------------------------------------------- + +void SfxApplication::EnterAsynchronCall_Impl() +{ + ++pAppData_Impl->nAsynchronCalls; +} + +//-------------------------------------------------------------------- + +void SfxApplication::LeaveAsynchronCall_Impl() +{ + --pAppData_Impl->nAsynchronCalls; +} + +//-------------------------------------------------------------------- + +FASTBOOL SfxApplication::IsInAsynchronCall_Impl() const +{ + return pAppData_Impl->nAsynchronCalls > 0; +} + +//-------------------------------------------------------------------- + +Window* SfxApplication::GetTopWindow() const +{ + SfxWorkWindow* pWork = GetWorkWindow_Impl( SfxViewFrame::Current() ); + return pWork ? pWork->GetWindow() : NULL; +} + +//-------------------------------------------------------------------- + +uno::Reference< task::XStatusIndicator > SfxApplication::GetStatusIndicator() const +{ + if ( !pAppData_Impl->pViewFrame ) + return uno::Reference< task::XStatusIndicator >(); + + SfxViewFrame *pTop = pAppData_Impl->pViewFrame; + while ( pTop->GetParentViewFrame_Impl() ) + pTop = pTop->GetParentViewFrame_Impl(); + + return pTop->GetFrame().GetWorkWindow_Impl()->GetStatusIndicator(); +} + +SfxTbxCtrlFactArr_Impl& SfxApplication::GetTbxCtrlFactories_Impl() const +{ + return *pAppData_Impl->pTbxCtrlFac; +} + +SfxStbCtrlFactArr_Impl& SfxApplication::GetStbCtrlFactories_Impl() const +{ + return *pAppData_Impl->pStbCtrlFac; +} + +SfxMenuCtrlFactArr_Impl& SfxApplication::GetMenuCtrlFactories_Impl() const +{ + return *pAppData_Impl->pMenuCtrlFac; +} + +SfxViewFrameArr_Impl& SfxApplication::GetViewFrames_Impl() const +{ + return *pAppData_Impl->pViewFrames; +} + +SfxViewShellArr_Impl& SfxApplication::GetViewShells_Impl() const +{ + return *pAppData_Impl->pViewShells; +} + +SfxObjectShellArr_Impl& SfxApplication::GetObjectShells_Impl() const +{ + return *pAppData_Impl->pObjShells; +} + +void SfxApplication::Invalidate( USHORT nId ) +{ + for( SfxViewFrame* pFrame = SfxViewFrame::GetFirst(); pFrame; pFrame = SfxViewFrame::GetNext( *pFrame ) ) + Invalidate_Impl( pFrame->GetBindings(), nId ); +} + +#define DOSTRING( x ) #x +#define STRING( x ) DOSTRING( x ) + +typedef long (SAL_CALL *basicide_handle_basic_error)(void*); +typedef rtl_uString* (SAL_CALL *basicide_choose_macro)(void*, BOOL, rtl_uString*); +typedef void* (SAL_CALL *basicide_macro_organizer)(INT16); + +extern "C" { static void SAL_CALL thisModule() {} } + +IMPL_LINK( SfxApplication, GlobalBasicErrorHdl_Impl, StarBASIC*, pStarBasic ) +{ + // get basctl dllname + String sLibName = String::CreateFromAscii( STRING( DLL_NAME ) ); + sLibName.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "sfx" ) ), String( RTL_CONSTASCII_USTRINGPARAM( "basctl" ) ) ); + ::rtl::OUString aLibName( sLibName ); + + // load module + oslModule handleMod = osl_loadModuleRelative( + &thisModule, aLibName.pData, 0 ); + + // get symbol + ::rtl::OUString aSymbol( RTL_CONSTASCII_USTRINGPARAM( "basicide_handle_basic_error" ) ); + basicide_handle_basic_error pSymbol = (basicide_handle_basic_error) osl_getFunctionSymbol( handleMod, aSymbol.pData ); + + // call basicide_handle_basic_error in basctl + long nRet = pSymbol( pStarBasic ); + + return nRet; +} + +sal_Bool SfxApplication::IsXScriptURL( const String& rScriptURL ) +{ + sal_Bool result = FALSE; + + ::com::sun::star::uno::Reference + < ::com::sun::star::lang::XMultiServiceFactory > xSMgr = + ::comphelper::getProcessServiceFactory(); + + ::com::sun::star::uno::Reference + < ::com::sun::star::uri::XUriReferenceFactory > + xFactory( xSMgr->createInstance( + ::rtl::OUString::createFromAscii( + "com.sun.star.uri.UriReferenceFactory" ) ), + ::com::sun::star::uno::UNO_QUERY ); + + if ( xFactory.is() ) + { + try + { + ::com::sun::star::uno::Reference + < ::com::sun::star::uri::XVndSunStarScriptUrl > + xUrl( xFactory->parse( rScriptURL ), + ::com::sun::star::uno::UNO_QUERY ); + + if ( xUrl.is() ) + { + result = TRUE; + } + } + catch ( ::com::sun::star::uno::RuntimeException& ) + { + // ignore, will just return FALSE + } + } + return result; +} + +::rtl::OUString +SfxApplication::ChooseScript() +{ + ::rtl::OUString aScriptURL; + + SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create(); + if ( pFact ) + { + OSL_TRACE("create selector dialog"); + + const SfxViewFrame* pViewFrame = SfxViewFrame::Current(); + const SfxFrame* pFrame = pViewFrame ? &pViewFrame->GetFrame() : NULL; + uno::Reference< frame::XFrame > xFrame( pFrame ? pFrame->GetFrameInterface() : uno::Reference< frame::XFrame >() ); + + AbstractScriptSelectorDialog* pDlg = + pFact->CreateScriptSelectorDialog( NULL, FALSE, xFrame ); + + OSL_TRACE("done, now exec it"); + + USHORT nRet = pDlg->Execute(); + + OSL_TRACE("has returned"); + + if ( nRet == RET_OK ) + { + aScriptURL = pDlg->GetScriptURL(); + } + + delete pDlg; + } + return aScriptURL; +} + +void SfxApplication::MacroOrganizer( INT16 nTabId ) +{ + // get basctl dllname + String sLibName = String::CreateFromAscii( STRING( DLL_NAME ) ); + sLibName.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "sfx" ) ), String( RTL_CONSTASCII_USTRINGPARAM( "basctl" ) ) ); + ::rtl::OUString aLibName( sLibName ); + + // load module + oslModule handleMod = osl_loadModuleRelative( + &thisModule, aLibName.pData, 0 ); + + // get symbol + ::rtl::OUString aSymbol( RTL_CONSTASCII_USTRINGPARAM( "basicide_macro_organizer" ) ); + basicide_macro_organizer pSymbol = (basicide_macro_organizer) osl_getFunctionSymbol( handleMod, aSymbol.pData ); + + // call basicide_choose_macro in basctl + pSymbol( nTabId ); +} + diff --git a/sfx2/source/appl/app.hrc b/sfx2/source/appl/app.hrc new file mode 100644 index 000000000000..dca172269443 --- /dev/null +++ b/sfx2/source/appl/app.hrc @@ -0,0 +1,274 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SFX_APP_HRC +#define _SFX_APP_HRC + +#include <sfx2/sfx.hrc> + +// #defines ***************************************************************** + +#define ACC_IBM (RID_SFX_APP_START+2) +#define MSG_ERR_WRITE_CFG (RID_SFX_APP_START+2) +#define MSG_ERR_READ_CFG (RID_SFX_APP_START+3) +#define MSG_ERR_OPEN_CFG (RID_SFX_APP_START+4) +#define MSG_ERR_FILETYPE_CFG (RID_SFX_APP_START+5) +#define MSG_ERR_VERSION_CFG (RID_SFX_APP_START+6) +#define MSG_ERR_NO_WEBBROWSER_FOUND (RID_SFX_APP_START+7) + +// Note: no longer in use +// #define MSG_ERR_EXTERNAL_APP_NOT_FOUND (RID_SFX_APP_START+8) + +#define MSG_ISPRINTING_QUERYABORT (RID_SFX_APP_START+9) +#define MSG_CANT_QUIT (RID_SFX_APP_START+10) +#define STR_ISMODIFIED (RID_SFX_APP_START+11) +#define STR_AUTOSAVE (RID_SFX_APP_START+12) +#define STR_MAIL (RID_SFX_APP_START+13) +#define MSG_ERR_WRITE_SBL (RID_SFX_APP_START+14) +#define MSG_IS_SERVER (RID_SFX_APP_START+15) + +#define STR_RESEXCEPTION (RID_SFX_APP_START+21) +#define STR_SYSRESEXCEPTION (RID_SFX_APP_START+22) +#define STR_DOUBLEEXCEPTION (RID_SFX_APP_START+23) +#define STR_RESWARNING (RID_SFX_APP_START+24) +#define STR_ERR_NOTEMPLATE (RID_SFX_APP_START+27) +#define STR_RECOVER_TITLE (RID_SFX_APP_START+28) +#define STR_RECOVER_QUERY (RID_SFX_APP_START+29) +#define STR_RECOVER_PREPARED (RID_SFX_APP_START+30) +#define MSG_ERR_SOINIT (RID_SFX_APP_START+31) + +#define MSG_IOERR_FILE_NOT_FOUND (RID_SFX_APP_START+32) +#define MSG_IOERR_PATH_NOT_FOUND (RID_SFX_APP_START+33) +#define MSG_IOERR_TOO_MANY_OPEN_FILES (RID_SFX_APP_START+34) +#define MSG_IOERR_ACCESS_DENIED (RID_SFX_APP_START+35) +#define MSG_IOERR_INVALID_ACCESS (RID_SFX_APP_START+36) +#define MSG_IOERR_INVALID_HANDLE (RID_SFX_APP_START+37) +#define MSG_IOERR_CANNOT_MAKE (RID_SFX_APP_START+38) +#define MSG_IOERR_SHARING (RID_SFX_APP_START+39) +#define MSG_IOERR_INVALID_PARAMETER (RID_SFX_APP_START+40) +#define MSG_IOERR_GENERAL (RID_SFX_APP_START+41) + +#define RID_FULLSCREENTOOLBOX (RID_SFX_APP_START+42) +#define RID_RECORDINGTOOLBOX (RID_SFX_APP_START+43) +#define RID_ENVTOOLBOX (RID_SFX_APP_START+44) + +#define STR_QUITAPP (RID_SFX_APP_START+59) +#define STR_EXITANDRETURN (RID_SFX_APP_START+60) +#define STR_ERR_NOFILE (RID_SFX_APP_START+61) +#define STR_EXTHELPSTATUS (RID_SFX_APP_START+62) + +#define STR_ADDRESS_NAME (RID_SFX_APP_START+65) + +#define RID_STR_HLPFILENOTEXIST (RID_SFX_APP_START+68) +#define RID_STR_HLPAPPNOTSTARTED (RID_SFX_APP_START+69) + +#define STR_NODOUBLE (RID_SFX_APP_START+75) +#define STR_NOPRINTER (RID_SFX_APP_START+76) + +#define MSG_SIGNAL (RID_SFX_APP_START+77) + +#define RID_STR_HELP (RID_SFX_APP_START+79) +#define RID_STR_NOAUTOSTARTHELPAGENT (RID_SFX_APP_START+80) +#define RID_HELPBAR (RID_SFX_APP_START+81) +#define RID_SPECIALCONFIG_ERROR (RID_SFX_APP_START+82) + +#define STR_MEMINFO_HEADER (RID_SFX_APP_START+84) +#define STR_MEMINFO_FOOTER (RID_SFX_APP_START+85) +#define STR_MEMINFO_OBJINFO (RID_SFX_APP_START+86) + +#define RID_PLUGIN (RID_SFX_APP_START+87) + +#define RID_WARN_POST_MAILTO (RID_SFX_APP_START+88) + +#define RID_STR_NOWELCOMESCREEN (RID_SFX_APP_START+91) + +// --> PB 2004-08-20 #i33095# +/* obsolete +#define STR_EDITOBJECT (RID_SFX_APP_START+92) +#define STR_OPENOBJECT (RID_SFX_APP_START+93) +*/ + +#define STR_CORRUPT_INSTALLATION (RID_SFX_APP_START+94) +#define IDS_SBERR_STOREREF (RID_SFX_APP_START+97) + +#define CONFIG_PATH_START (RID_SFX_APP_START+98) + +#define STR_KEY_ADDINS_PATH (CONFIG_PATH_START+0) +#define STR_KEY_AUTOCORRECT_DIR (CONFIG_PATH_START+1) +#define STR_KEY_GLOSSARY_PATH (CONFIG_PATH_START+2) +#define STR_KEY_BACKUP_PATH (CONFIG_PATH_START+3) +#define STR_KEY_BASIC_PATH (CONFIG_PATH_START+4) +#define STR_KEY_BITMAP_PATH (CONFIG_PATH_START+5) +#define STR_KEY_CONFIG_DIR (CONFIG_PATH_START+6) +#define STR_KEY_DICTIONARY_PATH (CONFIG_PATH_START+7) +#define STR_KEY_FAVORITES_DIR (CONFIG_PATH_START+8) +#define STR_KEY_FILTER_PATH (CONFIG_PATH_START+9) +#define STR_KEY_GALLERY_DIR (CONFIG_PATH_START+10) +#define STR_KEY_GRAPHICS_PATH (CONFIG_PATH_START+11) +#define STR_KEY_HELP_DIR (CONFIG_PATH_START+12) +#define STR_KEY_LINGUISTIC_DIR (CONFIG_PATH_START+13) +#define STR_KEY_MODULES_PATH (CONFIG_PATH_START+14) +#define STR_KEY_PALETTE_PATH (CONFIG_PATH_START+15) +#define STR_KEY_PLUGINS_PATH (CONFIG_PATH_START+16) +#define STR_KEY_STORAGE_DIR (CONFIG_PATH_START+17) +#define STR_KEY_TEMP_PATH (CONFIG_PATH_START+18) +#define STR_KEY_TEMPLATE_PATH (CONFIG_PATH_START+19) +#define STR_KEY_USERCONFIG_PATH (CONFIG_PATH_START+20) +#define STR_KEY_USERDICTIONARY_DIR (CONFIG_PATH_START+21) +#define STR_KEY_WORK_PATH (CONFIG_PATH_START+22) + +#define WIN_HELPINDEX (RID_SFX_APP_START+99) +#define TP_HELP_CONTENT (RID_SFX_APP_START+100) +#define TP_HELP_INDEX (RID_SFX_APP_START+101) +#define TP_HELP_SEARCH (RID_SFX_APP_START+102) +#define TP_HELP_BOOKMARKS (RID_SFX_APP_START+103) +#define DLG_HELP_ADDBOOKMARK (RID_SFX_APP_START+104) +#define MENU_HELP_BOOKMARKS (RID_SFX_APP_START+105) +#define RID_INFO_NOSEARCHRESULTS (RID_SFX_APP_START+106) +#define RID_INFO_NOSEARCHTEXTFOUND (RID_SFX_APP_START+107) + +#define IMG_HELP_TOOLBOX_INDEX_ON (RID_SFX_APP_START+110) +#define IMG_HELP_TOOLBOX_INDEX_OFF (RID_SFX_APP_START+111) +#define IMG_HELP_TOOLBOX_START (RID_SFX_APP_START+112) +#define IMG_HELP_TOOLBOX_PREV (RID_SFX_APP_START+113) +#define IMG_HELP_TOOLBOX_NEXT (RID_SFX_APP_START+114) +#define IMG_HELP_TOOLBOX_PRINT (RID_SFX_APP_START+115) +#define IMG_HELP_TOOLBOX_BOOKMARKS (RID_SFX_APP_START+116) +#define IMG_HELP_TOOLBOX_SEARCHDIALOG (RID_SFX_APP_START+117) +#define IMG_HELP_TOOLBOX_COPY (RID_SFX_APP_START+118) + +#define IMG_HELP_CONTENT_BOOK_OPEN (RID_SFX_APP_START+120) +#define IMG_HELP_CONTENT_BOOK_OPEN_HC (RID_SFX_APP_START+121) +#define IMG_HELP_CONTENT_BOOK_CLOSED (RID_SFX_APP_START+122) +#define IMG_HELP_CONTENT_BOOK_CLOSED_HC (RID_SFX_APP_START+123) +#define IMG_HELP_CONTENT_DOC (RID_SFX_APP_START+124) + +#define IMG_HELP_CONTENT_DOC_HC (RID_SFX_APP_START+125) // image + +#define IMG_MISSING_1 (RID_SFX_APP_START+126) // image +#define IMG_MISSING_2 (RID_SFX_APP_START+127) // image +#define IMG_MISSING_3 (RID_SFX_APP_START+128) // image +#define IMG_MISSING_4 (RID_SFX_APP_START+129) // image + +#define STR_HELP_WINDOW_TITLE (RID_SFX_APP_START+125) // string + +#define STR_HELP_BUTTON_INDEX_ON (RID_SFX_APP_START+126) +#define STR_HELP_BUTTON_START (RID_SFX_APP_START+127) +#define STR_HELP_BUTTON_PREV (RID_SFX_APP_START+128) +#define STR_HELP_BUTTON_NEXT (RID_SFX_APP_START+129) +#define STR_HELP_BUTTON_PRINT (RID_SFX_APP_START+130) +#define STR_HELP_BUTTON_SOURCEVIEW (RID_SFX_APP_START+131) +#define STR_HELP_FIRST_MESSAGE (RID_SFX_APP_START+132) +#define STR_HELP_FIRST_HTML (RID_SFX_APP_START+133) + +#define STR_QUICKSTART_EXIT (RID_SFX_APP_START+134) +#define STR_QUICKSTART_TIP (RID_SFX_APP_START+135) +#define STR_QUICKSTART_FILEOPEN (RID_SFX_APP_START+136) +#define STR_QUICKSTART_FROMTEMPLATE (RID_SFX_APP_START+137) +#define STR_QUICKSTART_PRELAUNCH (RID_SFX_APP_START+138) +#define STR_QUICKSTART_LNKNAME (RID_SFX_APP_START+139) +#define STR_HELP_BUTTON_ADDBOOKMARK (RID_SFX_APP_START+140) +#define STR_HELP_BUTTON_INDEX_OFF (RID_SFX_APP_START+141) +#define STR_HELP_BUTTON_SEARCHDIALOG (RID_SFX_APP_START+142) +#define STR_HELP_MENU_TEXT_SELECTION_MODE (RID_SFX_APP_START+143) +#define STR_HELP_MENU_TEXT_COPY (RID_SFX_APP_START+144) +#define STR_QUICKSTART_PRELAUNCH_UNX (RID_SFX_APP_START+146) +#define STR_QUICKSTART_FILE (RID_SFX_APP_START+147) +#define STR_QUICKSTART_STARTCENTER (RID_SFX_APP_START+148) +#define STR_QUICKSTART_RECENTDOC (RID_SFX_APP_START+149) + +#define RID_HELP_ONSTARTUP_BOX (RID_SFX_APP_START+144) +#define RID_HELP_ONSTARTUP_TEXT (RID_SFX_APP_START+145) + +#define IMG_HELP_TOOLBOX_HC_INDEX_ON (RID_SFX_APP_START+150) +#define IMG_HELP_TOOLBOX_HC_INDEX_OFF (RID_SFX_APP_START+151) +#define IMG_HELP_TOOLBOX_HC_START (RID_SFX_APP_START+152) +#define IMG_HELP_TOOLBOX_HC_PREV (RID_SFX_APP_START+153) +#define IMG_HELP_TOOLBOX_HC_NEXT (RID_SFX_APP_START+154) +#define IMG_HELP_TOOLBOX_HC_PRINT (RID_SFX_APP_START+155) +#define IMG_HELP_TOOLBOX_HC_BOOKMARKS (RID_SFX_APP_START+156) +#define IMG_HELP_TOOLBOX_HC_SEARCHDIALOG (RID_SFX_APP_START+157) +#define IMG_HELP_TOOLBOX_HC_COPY (RID_SFX_APP_START+158) + +#define IMG_HELP_TOOLBOX_L_INDEX_ON (RID_SFX_APP_START+160) +#define IMG_HELP_TOOLBOX_L_INDEX_OFF (RID_SFX_APP_START+161) +#define IMG_HELP_TOOLBOX_L_START (RID_SFX_APP_START+162) +#define IMG_HELP_TOOLBOX_L_PREV (RID_SFX_APP_START+163) +#define IMG_HELP_TOOLBOX_L_NEXT (RID_SFX_APP_START+164) +#define IMG_HELP_TOOLBOX_L_PRINT (RID_SFX_APP_START+165) +#define IMG_HELP_TOOLBOX_L_BOOKMARKS (RID_SFX_APP_START+166) +#define IMG_HELP_TOOLBOX_L_SEARCHDIALOG (RID_SFX_APP_START+167) +#define IMG_HELP_TOOLBOX_L_COPY (RID_SFX_APP_START+168) + +#define IMG_HELP_TOOLBOX_HCL_INDEX_ON (RID_SFX_APP_START+170) +#define IMG_HELP_TOOLBOX_HCL_INDEX_OFF (RID_SFX_APP_START+171) +#define IMG_HELP_TOOLBOX_HCL_START (RID_SFX_APP_START+172) +#define IMG_HELP_TOOLBOX_HCL_PREV (RID_SFX_APP_START+173) +#define IMG_HELP_TOOLBOX_HCL_NEXT (RID_SFX_APP_START+174) +#define IMG_HELP_TOOLBOX_HCL_PRINT (RID_SFX_APP_START+175) +#define IMG_HELP_TOOLBOX_HCL_BOOKMARKS (RID_SFX_APP_START+176) +#define IMG_HELP_TOOLBOX_HCL_SEARCHDIALOG (RID_SFX_APP_START+177) +#define IMG_HELP_TOOLBOX_HCL_COPY (RID_SFX_APP_START+178) + +#define RID_SECURITY_WARNING_HYPERLINK (RID_SFX_APP_START + 180) +#define RID_SECURITY_WARNING_TITLE (RID_SFX_APP_START + 181) + +#define RID_INVALID_URL_MSG (RID_SFX_APP_START + 182) +#define RID_INVALID_URL_TITLE (RID_SFX_APP_START + 183) +#define RID_DESKTOP (RID_SFX_APP_START + 184) + +// #define RID_XMLSEC_WARNING_BROKENSIGNATURE (RID_SFX_APP_START + 185) +#define RID_XMLSEC_QUERY_LOSINGSIGNATURE (RID_SFX_APP_START + 186) +#define RID_XMLSEC_QUERY_SAVEBEFORESIGN (RID_SFX_APP_START + 187) + // FREE + // FREE +#define RID_XMLSEC_INFO_WRONGDOCFORMAT (RID_SFX_APP_START + 190) + +/* obsolete +#define RID_WARNING_MACROSDISABLED (RID_SFX_APP_START + 191) +*/ + +#define STR_QUERY_UPDATE_LINKS (RID_SFX_APP_START + 192) +#define STR_DDE_ERROR (RID_SFX_APP_START + 193) +#define RID_SECURITY_WARNING_NO_HYPERLINKS (RID_SFX_APP_START + 194) + +#define RID_SVXSTR_FILELINK (RID_SFX_APP_START + 195) +#define RID_SVXSTR_GRAFIKLINK (RID_SFX_APP_START + 196) +#define RID_SVXSTR_EDITGRFLINK (RID_SFX_APP_START + 197) + +// strings for error messsages of OpenGraphics dialog +#define RID_SVXSTR_GRFILTER_OPENERROR (RID_SFX_APP_START + 198) +#define RID_SVXSTR_GRFILTER_IOERROR (RID_SFX_APP_START + 199) +#define RID_SVXSTR_GRFILTER_FORMATERROR (RID_SFX_APP_START + 200) +#define RID_SVXSTR_GRFILTER_VERSIONERROR (RID_SFX_APP_START + 201) +#define RID_SVXSTR_GRFILTER_FILTERERROR (RID_SFX_APP_START + 202) +#define RID_SVXSTR_GRFILTER_TOOBIG (RID_SFX_APP_START + 203) + +#define MD_DDE_LINKEDIT (RID_SFX_APP_START + 1) + +#endif // #ifndef _SFX_APP_HRC + +// ******************************************************************* EOF diff --git a/sfx2/source/appl/app.src b/sfx2/source/appl/app.src new file mode 100644 index 000000000000..0858e66e7347 --- /dev/null +++ b/sfx2/source/appl/app.src @@ -0,0 +1,1094 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + // include ------------------------------------------------------------------ + +#include <sfx2/sfx.hrc> +#include "app.hrc" +#include "helpid.hrc" + +InfoBox RID_DOCALREADYLOADED_DLG +{ + Message [ en-US ] = "Document already open." ; +}; + +ErrorBox RID_CANTLOADDOC_DLG +{ + Message [ en-US ] = "Cannot open document." ; +}; + +ErrorBox MSG_ERR_READ_CFG +{ + BUTTONS = WB_OK ; + DEFBUTTON = WB_DEF_OK ; + Message [ en-US ] = "Error reading configuration file." ; +}; + +ErrorBox MSG_ERR_WRITE_CFG +{ + BUTTONS = WB_OK ; + DEFBUTTON = WB_DEF_OK ; + Message [ en-US ] = "Error writing configuration file." ; +}; + +ErrorBox MSG_ERR_OPEN_CFG +{ + BUTTONS = WB_OK ; + DEFBUTTON = WB_DEF_OK ; + Message [ en-US ] = "Error opening configuration file." ; +}; + +ErrorBox MSG_ERR_FILETYPE_CFG +{ + BUTTONS = WB_OK ; + DEFBUTTON = WB_DEF_OK ; + Message [ en-US ] = "File is not a configuration file." ; +}; + +ErrorBox MSG_ERR_VERSION_CFG +{ + BUTTONS = WB_OK ; + DEFBUTTON = WB_DEF_OK ; + Message [ en-US ] = "Configuration file contains the wrong version." ; +}; + +ErrorBox MSG_ERR_WRITE_SBL +{ + BUTTONS = WB_OK ; + DEFBUTTON = WB_DEF_OK ; + Message [ en-US ] = "Error recording BASIC library in\n'@'." ; +}; + +ErrorBox MSG_SIGNAL +{ + BUTTONS = WB_YES_NO ; + DEFBUTTON = WB_DEF_YES ; + Message [ en-US ] = "An unexpected program error has occurred.\n\nDo you want to try to save your changes in all open documents before the program is terminated?" ; +}; + +ErrorBox MSG_ERR_NO_WEBBROWSER_FOUND +{ + BUTTONS = WB_OK ; + DEFBUTTON = WB_DEF_OK ; + Message[ en-US ] = "%PRODUCTNAME could not find a web browser on your system. Please check your Desktop Preferences or install a web browser (for example, Mozilla) in the default location requested during the browser installation." ; +}; + +Resource SID_UNKNOWN +{ + String 1 "-" ; +}; + +Resource BMP_SFX_COLOR +{ + ExtraData = + { + SID_NEWDOC; // 043 + SID_OPENDOC; // 044 + SID_CLOSEDOC; // 045 + SID_RELOAD; // 046 + SID_SAVEASDOC; // 047 + SID_PRINTDOC; // 051 + SID_SETUPPRINTER; // 053 + SID_QUITAPP; // 054 + SID_UNDO; // 055 + SID_REDO; // 056 + SID_REPEAT; // 057 + SID_CUT; // 058 + SID_COPY; // 059 + SID_PASTE; // 060 + SID_DELETE; // 061 + SID_SELECTALL; // 062 + SID_SAVEDOC; // 063 vormals 046 + SID_EXITANDRETURN; // 064 vormals 054 + SID_RECORDMACRO; // 095 + SID_EDITMACRO; // 096 + SID_HELPMENU; // 098 + SID_CONFIG; // 123 + SID_CONFIGTOOLBOX; // 124 + 0; + }; + Bitmap BMP_SFX_SMALL { File = "sco.bmp" ; }; + Bitmap BMP_SFX_LARGE { File = "lco.bmp" ; }; +}; + +Resource BMP_SFX_MONO +{ + ExtraData = + { + SID_NEWDOC; // 043 + SID_OPENDOC; // 044 + SID_CLOSEDOC; // 045 + SID_RELOAD; // 046 + SID_SAVEASDOC; // 047 + SID_PRINTDOC; // 051 + SID_SETUPPRINTER; // 053 + SID_QUITAPP; // 054 + SID_UNDO; // 055 + SID_REDO; // 056 + SID_REPEAT; // 057 + SID_CUT; // 058 + SID_COPY; // 059 + SID_PASTE; // 060 + SID_DELETE; // 061 + SID_SELECTALL; // 062 + SID_SAVEDOC; // 063 vormals 046 + SID_EXITANDRETURN; // 064 vormals 054 + SID_RECORDMACRO; // 095 + SID_EDITMACRO; // 096 + SID_HELPMENU; // 098 + SID_CONFIG; // 123 + SID_CONFIGTOOLBOX; // 124 + 0; + }; + Bitmap BMP_SFX_SMALL { File = "smo.bmp" ; }; + Bitmap BMP_SFX_LARGE { File = "lmo.bmp" ; }; +}; + +WarningBox RID_WARN_POST_MAILTO +{ + BUTTONS = WB_OK_CANCEL ; + DEFBUTTON = WB_DEF_OK ; + Message [ en-US ] = "A form is to be sent by e-mail.\nThis means that the receiver will get to see your e-mail address." ; +}; + +String STR_RECOVER_TITLE +{ + Text [ en-US ] = "File Recovery" ; +}; + +String STR_RECOVER_QUERY +{ + Text [ en-US ] = "Should the file \"$1\" be restored?" ; +}; + +String GID_INTERN +{ + Text [ en-US ] = "Internal" ; +}; + +String GID_APPLICATION +{ + Text [ en-US ] = "Application" ; +}; + +String GID_VIEW +{ + Text [ en-US ] = "View" ; +}; + +String GID_DOCUMENT +{ + Text [ en-US ] = "Documents" ; +}; + +String GID_EDIT +{ + Text [ en-US ] = "Edit" ; +}; + +String GID_MACRO +{ + Text [ en-US ] = "BASIC" ; +}; + +String GID_OPTIONS +{ + Text [ en-US ] = "Options" ; +}; + +String GID_MATH +{ + Text [ en-US ] = "Math" ; +}; + +String GID_NAVIGATOR +{ + Text [ en-US ] = "Navigate" ; +}; + +String GID_INSERT +{ + Text [ en-US ] = "Insert" ; +}; + +String GID_FORMAT +{ + Text [ en-US ] = "Format" ; +}; + +String GID_TEMPLATE +{ + Text [ en-US ] = "Templates" ; +}; + +String GID_TEXT +{ + Text [ en-US ] = "Text" ; +}; + +String GID_FRAME +{ + Text [ en-US ] = "Frame" ; +}; + +String GID_GRAPHIC +{ + Text [ en-US ] = "Graphic" ; +}; + +String GID_TABLE +{ + Text [ en-US ] = "Table" ; +}; + +String GID_ENUMERATION +{ + Text [ en-US ] = "Numbering" ; +}; + +String GID_DATA +{ + Text [ en-US ] = "Data" ; +}; + +String GID_SPECIAL +{ + Text [ en-US ] = "Special Functions" ; +}; + +String GID_IMAGE +{ + Text [ en-US ] = "Image" ; +}; + +String GID_CHART +{ + Text [ en-US ] = "Chart" ; +}; + +String GID_EXPLORER +{ + Text [ en-US ] = "Explorer" ; +}; + +String GID_CONNECTOR +{ + Text [ en-US ] = "Connector" ; +}; + +String GID_MODIFY +{ + Text [ en-US ] = "Modify" ; +}; + +String GID_DRAWING +{ + Text [ en-US ] = "Drawing" ; +}; + +String GID_CONTROLS +{ + Text [ en-US ] = "Controls" ; +}; + +TabDialog SID_OPTIONS +{ + OutputSize = TRUE ; + SVLook = TRUE ; + Size = MAP_APPFONT ( 244 , 155 ) ; + Text [ en-US ] = "Options" ; + Moveable = TRUE ; + Closeable = TRUE ; + TabControl 1 + { + SVLook = TRUE ; + Pos = MAP_APPFONT ( 3 , 15 ) ; + Size = MAP_APPFONT ( 221 , 130 ) ; + PageList = + { + PageItem + { + Identifier = RID_SFXPAGE_GENERAL ; + Text [ en-US ] = "General" ; + PageResID = 256 ; + }; + PageItem + { + Identifier = RID_SFXPAGE_SAVE ; + Text [ en-US ] = "Save" ; + PageResID = 257 ; + }; + PageItem + { + Identifier = RID_SFXPAGE_PATH ; + Text [ en-US ] = "Paths" ; + PageResID = 258 ; + }; + PageItem + { + Identifier = RID_SFXPAGE_SPELL ; + Text [ en-US ] = "Spellcheck" ; + PageResID = 259 ; + }; + }; + }; +}; + +InfoBox MSG_CANT_QUIT +{ + Message [ en-US ] = "The application cannot be terminated at the moment.\nPlease wait until all print jobs and/or\nOLE actions have finished and close all dialogs." ; +}; + +QueryBox MSG_IS_SERVER +{ + Buttons = WB_YES_NO ; + DefButton = WB_DEF_NO ; + Message [ en-US ] = "This application is as object or print server active.\nDo you want to terminate anyway?" ; +}; + +String STR_NODOUBLE +{ + Text [ en-US ] = "%PRODUCTNAME cannot be started more than once." ; +}; + +String STR_NOPRINTER +{ + Text [ en-US ] = "Some %PRODUCTNAME functions will not work properly without a printer driver.\nPlease install a printer driver." ; +}; + +String STR_ISMODIFIED +{ + Text [ en-US ] = "Do you want to save the changes to %1?" ; +}; + +String STR_AUTOSAVE +{ + Text [ en-US ] = "AutoSave" ; +}; + +String STR_RESWARNING +{ + Text [ en-US ] = "Limited system resources. Please quit other applications or close some windows before continuing." ; +}; +String STR_RESEXCEPTION +{ + Text [ en-US ] = "There are files missing. Please check application setup." ; +}; + +String STR_DOUBLEEXCEPTION +{ + Text [ en-US ] = "Another error occurred during the save recovery.\nPossibly, the data could not be entirely saved." ; +}; + +String STR_SYSRESEXCEPTION +{ + Text [ en-US ] = "System resources exhausted. Please restart the application." ; +}; + +ErrorBox MSG_ERR_SOINIT +{ + Message [ en-US ] = "Error initializing object-system." ; +}; + +String MSG_IOERR_FILE_NOT_FOUND +{ + Text [ en-US ] = "The file $(FILE) doesn't exist." ; +}; + +String MSG_IOERR_PATH_NOT_FOUND +{ + Text [ en-US ] = "The path to file $(FILE) doesn't exist." ; +}; + +String MSG_IOERR_TOO_MANY_OPEN_FILES +{ + Text [ en-US ] = "The file $(FILE) could not be opened,\nbecause too many files are open.\nPlease close some files and try again." ; +}; + +String MSG_IOERR_ACCESS_DENIED +{ + Text [ en-US ] = "The file $(FILE) could not be opened due to missing access rights." ; +}; + +String MSG_IOERR_INVALID_ACCESS +{ + Text [ en-US ] = "The file $(FILE) could not be accessed." ; +}; + +String MSG_IOERR_INVALID_HANDLE +{ + Text [ en-US ] = "The file $(FILE) could not be opened due to an invalid file handle." ; +}; + +String MSG_IOERR_CANNOT_MAKE +{ + Text [ en-US ] = "The file $(FILE) could not be created." ; +}; + +String MSG_IOERR_SHARING +{ + Text [ en-US ] = "Error by shared access to $(FILE)." ; +}; + +String MSG_IOERR_INVALID_PARAMETER +{ + Text [ en-US ] = "" ; +}; + +String MSG_IOERR_GENERAL +{ + Text [ en-US ] = "General I/O error accessing $(FILE)." ; +}; + +String RID_FULLSCREENTOOLBOX +{ + Text = "" ; +}; + +ToolBox RID_FULLSCREENTOOLBOX +{ + HelpId = HID_FULLSCREENTOOLBOX ; + ButtonType = BUTTON_SYMBOL ; + LineSpacing = TRUE ; + Border = TRUE ; + Scroll = TRUE ; + SVLook = TRUE ; + Moveable = TRUE ; + Sizeable = TRUE ; + Closeable = TRUE ; + Zoomable = TRUE ; + Customize = TRUE ; + FloatingMode = TRUE ; + Hide = TRUE ; + _FloatingPosMapMode = MAP_APPFONT ; + _FloatingPosX = -50 ; + _FloatingPosY = -70 ; + FloatingLines = 1 ; + HideWhenDeactivate = TRUE ; + Align = BOXALIGN_TOP ; + ItemList = + { + ToolBoxItem + { + Identifier = SID_WIN_FULLSCREEN ; + }; + }; +}; + +String STR_ERR_NOTEMPLATE +{ + Text [ en-US ] = "The selected template has an incorrect format" ; +}; + +String STR_ERR_NOFILE +{ + Text [ en-US ] = "Can't open file $." ; +}; + +String STR_QUITAPP +{ + Text [ en-US ] = "E~xit" ; +}; + +String STR_EXITANDRETURN +{ + Text [ en-US ] = "E~xit & return to " ; +}; + +String STR_EXTHELPSTATUS +{ + Text [ en-US ] = "Select a command or click to select a theme." ; +}; + +String STR_MAIL +{ + Text [ en-US ] = "Mail" ; +}; + +String STR_ADDRESS_NAME +{ + Text [ en-US ] = "Addresses" ; +}; + +String RID_STR_HELP +{ + Text [ en-US ] = "Help" ; +}; + +String RID_STR_NOAUTOSTARTHELPAGENT +{ + Text [ en-US ] = "No automatic start at 'XX'" ; +}; + +String RID_STR_NOWELCOMESCREEN +{ + Text [ en-US ] = "Don't display tips" ; +}; + +String RID_HELPBAR +{ + Text [ en-US ] = "Help Bar" ; +}; + +ToolBox RID_HELPBAR +{ + HelpId = HID_HELPBAR ; + Hide = TRUE ; + ItemList = + { + ToolBoxItem + { + Identifier = SID_HELP_INDEX ; + }; + ToolBoxItem + { + Identifier = SID_HELP_HELPFILEBOX ; + }; + ToolBoxItem + { + Type = TOOLBOXITEM_SEPARATOR ; + }; + ToolBoxItem + { + Identifier = SID_HELP_ZOOMOUT; + }; + ToolBoxItem + { + Identifier = SID_HELP_ZOOMIN; + }; + ToolBoxItem + { + Type = TOOLBOXITEM_SEPARATOR ; + }; + ToolBoxItem + { + Identifier = SID_HELP_SEARCH ; + }; + ToolBoxItem + { + Identifier = SID_HELP_BOOKMARK ; + }; + ToolBoxItem + { + Identifier = SID_HELP_ANNOTATE ; + }; + /* + ToolBoxItem + { + Type = TOOLBOXITEM_SEPARATOR ; + }; + ToolBoxItem + { + Identifier = SID_HELP_DOWNLOAD ; + }; +*/ + }; +}; + +String RID_STR_HLPFILENOTEXIST +{ + Text [ en-US ] = "The help file for this topic is not installed." ; +}; + +String RID_STR_HLPAPPNOTSTARTED +{ + Text [ en-US ] = "The help system could not be started" ; +}; + + //---------------------------------------------------------------------------- + +String RID_ENVTOOLBOX +{ + Text [ en-US ] = "Function Bar" ; +}; + +ToolBox RID_ENVTOOLBOX +{ + HelpId = RID_ENVTOOLBOX ; + ButtonType = BUTTON_SYMBOL ; + LineSpacing = TRUE ; + Border = TRUE ; + Scroll = TRUE ; + SVLook = TRUE ; + Dockable = TRUE ; + Moveable = TRUE ; + Sizeable = TRUE ; + Closeable = TRUE ; + Zoomable = TRUE ; + Customize = TRUE ; + FloatingMode = FALSE ; + Hide = TRUE ; + HideWhenDeactivate = TRUE ; + Align = BOXALIGN_TOP ; + ItemList = + { + ToolBoxItem + { + Identifier = SID_OPENURL ; + }; + ToolBoxItem + { + Type = TOOLBOXITEM_SEPARATOR ; + }; + ToolBoxItem + { + Identifier = SID_NEWDOCDIRECT ; + DropDown = TRUE; + }; + ToolBoxItem + { + Identifier = SID_NEWDOC ; + Hide = TRUE; + }; + ToolBoxItem + { + Identifier = SID_OPENDOC ; + }; + ToolBoxItem + { + Identifier = SID_SAVEDOC ; + }; + ToolBoxItem + { + Identifier = SID_SAVEASDOC ; + Hide = TRUE; + }; + ToolBoxItem + { + Type = TOOLBOXITEM_SEPARATOR ; + }; + ToolBoxItem + { + Identifier = SID_EDITDOC ; + }; + ToolBoxItem + { + Type = TOOLBOXITEM_SEPARATOR ; + }; + ToolBoxItem + { + Identifier = SID_DIRECTEXPORTDOCASPDF ; + }; + ToolBoxItem + { + Identifier = SID_PRINTDOCDIRECT ; + }; + ToolBoxItem + { + Identifier = FN_FAX ; + Hide = TRUE; + }; + ToolBoxItem + { + Type = TOOLBOXITEM_SEPARATOR ; + }; + ToolBoxItem + { + Identifier = SID_CUT ; + }; + ToolBoxItem + { + Identifier = SID_COPY ; + }; + ToolBoxItem + { + Identifier = SID_PASTE ; + }; + ToolBoxItem + { + Type = TOOLBOXITEM_SEPARATOR ; + }; + ToolBoxItem + { + Identifier = SID_UNDO ; + }; + ToolBoxItem + { + Identifier = SID_REDO ; + }; + ToolBoxItem + { + Type = TOOLBOXITEM_SEPARATOR ; + }; + ToolBoxItem + { + Identifier = SID_NAVIGATOR ; + }; + ToolBoxItem + { + Identifier = SID_STYLE_DESIGNER ; + }; + ToolBoxItem + { + Identifier = SID_HYPERLINK_DIALOG ; + }; + ToolBoxItem + { + Identifier = SID_HYPERLINK_INSERT ; + Hide = TRUE; + }; + ToolBoxItem + { + Identifier = SID_WIN_FULLSCREEN ; + Hide = TRUE; + }; + ToolBoxItem + { + Type = TOOLBOXITEM_SEPARATOR ; + }; + ToolBoxItem + { + Identifier = SID_RECORDMACRO; + Hide = TRUE; + }; + ToolBoxItem + { + Type = TOOLBOXITEM_SEPARATOR ; + }; + ToolBoxItem + { + Identifier = SID_GALLERY ; + }; + ToolBoxItem + { + Identifier = SID_AVMEDIA_PLAYER ; + }; + ToolBoxItem + { + Type = TOOLBOXITEM_SEPARATOR ; + }; + ToolBoxItem + { + Identifier = SID_CLOSEDOC; + Hide = TRUE; + }; + }; +}; + +String RID_SPECIALCONFIG_ERROR +{ + Text [ en-US ] = "An error has occurred in the special configuration.\nPlease contact your administrator." ; +}; + +String STR_MEMINFO_HEADER +{ +}; + +String STR_MEMINFO_FOOTER +{ + Text = "</table>" ; +}; + +String STR_MEMINFO_OBJINFO +{ + Text = "<tr><td >$(VISIBLE)</td><td>$(CACHED)</td><td>$(EXPIRE)</td><td>$(JSDIRTY)</td><td>$(JSEXEC)</td><td>$(FORBID)</td><td>$(FACTORY)</td><td>$(URL)</td><td>$(ORIGURL)</td><td>$(POSTSTRING)</td></tr>" ; +}; + +String RID_PLUGIN +{ + Text [ en-US ] = "Enable plug-ins" ; +}; + +String STR_CORRUPT_INSTALLATION +{ + Text [ en-US ] = "Important program components could not be initialized correctly.\nPlease start the setup program with the option /Repair." ; +}; + +String IDS_SBERR_STOREREF +{ + Text [ en-US ] = "Reference will not be saved: " ; +}; + +String STR_KEY_CONFIG_DIR +{ + Text [ en-US ] = "Configuration" ; +}; +String STR_KEY_WORK_PATH +{ + Text [ en-US ] = "My Documents" ; +}; +String STR_KEY_GRAPHICS_PATH +{ + Text [ en-US ] = "Graphics" ; +}; +String STR_KEY_BITMAP_PATH +{ + Text [ en-US ] = "Icons" ; +}; +String STR_KEY_BASIC_PATH +{ + Text = "BASIC" ; +}; + +String STR_KEY_PALETTE_PATH +{ + Text [ en-US ] = "Palettes" ; +}; +String STR_KEY_BACKUP_PATH +{ + Text [ en-US ] = "Backups" ; +}; +String STR_KEY_MODULES_PATH +{ + Text [ en-US ] = "Modules" ; +}; +String STR_KEY_TEMPLATE_PATH +{ + Text [ en-US ] = "Templates" ; +}; +String STR_KEY_GLOSSARY_PATH +{ + Text [ en-US ] = "AutoText" ; +}; +String STR_KEY_DICTIONARY_PATH +{ + Text [ en-US ] = "Dictionaries" ; +}; +String STR_KEY_HELP_DIR +{ + Text [ en-US ] = "Help" ; +}; +String STR_KEY_GALLERY_DIR +{ + Text [ en-US ] = "Gallery" ; +}; + +String STR_KEY_STORAGE_DIR +{ + Text [ en-US ] = "Message Storage" ; +}; +String STR_KEY_TEMP_PATH +{ + Text [ en-US ] = "Temporary files" ; +}; +String STR_KEY_PLUGINS_PATH +{ + Text [ en-US ] = "Plug-ins" ; +}; +String STR_KEY_FAVORITES_DIR +{ + Text [ en-US ] = "Folder Bookmarks" ; +}; +String STR_KEY_FILTER_PATH +{ + Text [ en-US ] = "Filters" ; +}; +String STR_KEY_ADDINS_PATH +{ + Text [ en-US ] = "Add-ins" ; +}; +String STR_KEY_USERCONFIG_PATH +{ + Text [ en-US ] = "User Configuration" ; +}; +String STR_KEY_USERDICTIONARY_DIR +{ + Text [ en-US ] = "User-defined dictionaries" ; +}; +String STR_KEY_AUTOCORRECT_DIR +{ + Text [ en-US ] = "AutoCorrect" ; +}; +String STR_KEY_LINGUISTIC_DIR +{ + Text [ en-US ] = "Writing aids" ; +}; +String STR_QUICKSTART_EXIT +{ + Text [ en-US ] = "Exit Quickstarter" ; +}; +String STR_QUICKSTART_TIP +{ + Text [ en-US ] = "%PRODUCTNAME %PRODUCTVERSION Quickstarter" ; +}; +String STR_QUICKSTART_FILEOPEN +{ + Text [ en-US ] = "Open Document..." ; +}; +String STR_QUICKSTART_FROMTEMPLATE +{ + Text [ en-US ] = "From Template..." ; +}; +String STR_QUICKSTART_PRELAUNCH +{ + Text [ en-US ] = "Load %PRODUCTNAME During System Start-Up" ; +}; +String STR_QUICKSTART_PRELAUNCH_UNX +{ + Text[ en-US ] = "Disable systray Quickstarter"; +}; +String STR_QUICKSTART_LNKNAME +{ + Text [ en-US ] = "%PRODUCTNAME %PRODUCTVERSION" ; +}; +String STR_QUICKSTART_FILE +{ + Text [ en-US ] = "File"; +}; + +String STR_QUICKSTART_STARTCENTER +{ + Text [ en-US ] = "Startcenter"; +}; + +String STR_QUICKSTART_RECENTDOC +{ + Text [ en-US ] = "Recent Documents"; +}; + +String STR_QUERY_UPDATE_LINKS +{ + Text [ en-US ] = "Update all links?" ; +}; + +String STR_DDE_ERROR +{ + Text [ en-US ] = "DDE link to % for % area % are not available." ; +}; + +WarningBox RID_SECURITY_WARNING_HYPERLINK +{ + HelpId = HID_WARNING_SECURITY_HYPERLINK; + Buttons = WB_YES_NO ; + DefButton = WB_DEF_NO ; + Message [ en-US ] = "This hyperlink is going to open \"%s\". Do you want to proceed?" ; +}; + +WarningBox RID_SECURITY_WARNING_NO_HYPERLINKS +{ + //HelpId = HID_WARNING_SECURITY_NO_HYPERLINKS; + Buttons = WB_OK ; + DefButton = WB_DEF_OK ; + Message [ en-US ] = "For security reasons, the hyperlink cannot be executed.\nThe stated address will not be opened."; +}; + +String RID_SECURITY_WARNING_TITLE +{ + Text [ en-US ] = "Security Warning" ; +}; + +ErrorBox RID_INVALID_URL_MSG +{ + Buttons = WB_OK ; + Message [ en-US ] = "The URL is not valid." ; +}; + +String RID_INVALID_URL_TITLE +{ + Text = "%PRODUCTNAME %PRODUCTVERSION" ; +}; + +String RID_DESKTOP +{ + Text = "%PRODUCTNAME" ; +}; + +QueryBox RID_XMLSEC_QUERY_LOSINGSIGNATURE +{ +// HelpId = HID_XMLSEC_QUERY_LOSINGSIGNATURE; + Buttons = WB_YES_NO ; + DefButton = WB_DEF_NO ; + Message [ en-US ] = "Saving will remove all existing signatures.\nDo you want to continue saving the document?" ; +}; + +QueryBox RID_XMLSEC_QUERY_SAVEBEFORESIGN +{ +// HelpId = HID_XMLSEC_QUERY_SAVEBEFORESIGN; + Buttons = WB_YES_NO ; + DefButton = WB_DEF_YES ; + Message [ en-US ] = "The document has to be saved before it can be signed.\nDo you want to save the document?" ; +}; + +InfoBox RID_XMLSEC_INFO_WRONGDOCFORMAT +{ +// HelpId = HID_XMLSEC_INFO_WRONGDOCFORMAT; + Message [ en-US ] = "This document must be saved in OpenDocument file format before it can be digitally signed." ; +}; + +String RID_XMLSEC_DOCUMENTSIGNED +{ + Text [ en-US ] = " (Signed)" ; +}; + +Image IMG_MISSING_1 +{ + ImageBitmap = Bitmap { File = "sc05539.bmp" ; }; +}; + +Image IMG_MISSING_2 +{ + ImageBitmap = Bitmap { File = "sc05700.bmp" ; }; +}; + +Image IMG_MISSING_3 +{ + ImageBitmap = Bitmap { File = "sc06302.bmp" ; }; +}; + +Image IMG_MISSING_4 +{ + ImageBitmap = Bitmap { File = "sn064.bmp" ; }; +}; + +String RID_SVXSTR_FILELINK +{ + Text [ en-US ] = "Document" ; +}; +String RID_SVXSTR_GRAFIKLINK +{ + Text [ en-US ] = "Graphic" ; +}; +String RID_SVXSTR_EDITGRFLINK +{ + Text [ en-US ] = "Link graphics" ; +}; + +String RID_SVXSTR_GRFILTER_OPENERROR +{ + Text [ en-US ] = "Graphics file cannot be opened" ; +}; +String RID_SVXSTR_GRFILTER_IOERROR +{ + Text [ en-US ] = "Graphics file cannot be read" ; +}; +String RID_SVXSTR_GRFILTER_FORMATERROR +{ + Text [ en-US ] = "Unknown graphics format" ; +}; +String RID_SVXSTR_GRFILTER_VERSIONERROR +{ + Text [ en-US ] = "This version of the graphics file is not supported" ; +}; +String RID_SVXSTR_GRFILTER_FILTERERROR +{ + Text [ en-US ] = "Graphics filter not found" ; +}; +String RID_SVXSTR_GRFILTER_TOOBIG +{ + Text [ en-US ] = "Not enough memory to insert graphic" ; +}; + diff --git a/sfx2/source/appl/appbas.cxx b/sfx2/source/appl/appbas.cxx new file mode 100644 index 000000000000..10c4a6bc6797 --- /dev/null +++ b/sfx2/source/appl/appbas.cxx @@ -0,0 +1,590 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" +#include <com/sun/star/frame/XDesktop.hpp> +#include <com/sun/star/script/XLibraryContainer.hpp> +#include <comphelper/processfactory.hxx> +#include <com/sun/star/uno/Reference.h> +#include <basic/basrdll.hxx> +#include <tools/urlobj.hxx> +#include <svl/macitem.hxx> +#include <basic/sbxfac.hxx> +#include <basic/sbx.hxx> +#include <vcl/gradient.hxx> +#include <svl/rectitem.hxx> +#include <svl/intitem.hxx> +#include <svl/eitem.hxx> +#include <basic/sbmod.hxx> +#include <svl/whiter.hxx> +#include <basic/sbmeth.hxx> +#include <basic/sbstar.hxx> +#include <vcl/wrkwin.hxx> +#include <vcl/msgbox.hxx> +#include <basic/sbuno.hxx> +#include <svtools/sfxecode.hxx> +#include <svtools/ehdl.hxx> + +#include <unotools/undoopt.hxx> +#include <unotools/pathoptions.hxx> +#include <unotools/useroptions.hxx> +#include <unotools/bootstrap.hxx> + +#include <sfx2/appuno.hxx> +#include <sfx2/module.hxx> +#include "arrdecl.hxx" +#include <sfx2/app.hxx> +#include "sfxtypes.hxx" +#include "sfxresid.hxx" +#include <sfx2/msg.hxx> +#include <sfx2/msgpool.hxx> +#include <sfx2/progress.hxx> +#include <sfx2/objsh.hxx> +#include <sfx2/objitem.hxx> +#include <sfx2/viewfrm.hxx> +#include <sfx2/viewsh.hxx> +#include <sfx2/dispatch.hxx> +#include "tplpitem.hxx" +#include "minfitem.hxx" +#include "app.hrc" +#include <sfx2/evntconf.hxx> +#include <sfx2/macrconf.hxx> +#include <sfx2/request.hxx> +#include <sfx2/dinfdlg.hxx> +#include "appdata.hxx" +#include "appbas.hxx" +#include "sfxhelp.hxx" +#include "basmgr.hxx" +#include "sorgitm.hxx" +#include "appbaslib.hxx" +#include <basic/basicmanagerrepository.hxx> + +#define ITEMID_SEARCH SID_SEARCH_ITEM + +#include <svl/srchitem.hxx> +#include <vos/socket.hxx> + +#define SFX_TYPEMAP +#define Selection +#include "sfxslots.hxx" + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::script; + +using ::basic::BasicManagerRepository; + +// #ifndef STR_VERSION_ID +// #define STR_VERSION_ID 1 +// #endif +// #ifndef STR_VERSION_TYPE +// #define STR_VERSION_TYPE 1 +// #endif + +//========================================================================= +/*ASDBG +const SfxConstant __FAR_DATA aConstants[] = +{ + SFX_USHORT_CONSTANT( "AlignBottom", ALIGN_BOTTOM ), + SFX_USHORT_CONSTANT( "AlignTop", ALIGN_TOP ), + SFX_USHORT_CONSTANT( "CharSetANSI", CHARSET_ANSI ), + SFX_USHORT_CONSTANT( "CharSetDontKnow", CHARSET_DONTKNOW ), + SFX_USHORT_CONSTANT( "CharSetIBMPC437", CHARSET_IBMPC_437 ), + SFX_USHORT_CONSTANT( "CharSetIBMPC850", CHARSET_IBMPC_850 ), + SFX_USHORT_CONSTANT( "CharSetIBMPC860", CHARSET_IBMPC_860 ), + SFX_USHORT_CONSTANT( "CharSetIBMPC861", CHARSET_IBMPC_861 ), + SFX_USHORT_CONSTANT( "CharSetIBMPC863", CHARSET_IBMPC_863 ), + SFX_USHORT_CONSTANT( "CharSetIBMPC865", CHARSET_IBMPC_865 ), + SFX_USHORT_CONSTANT( "CharSetIBMPC", CHARSET_IBMPC ), + SFX_USHORT_CONSTANT( "CharSetMac", CHARSET_MAC ), + SFX_USHORT_CONSTANT( "CharSetSymbol", CHARSET_SYMBOL ), + SFX_USHORT_CONSTANT( "CharSetSystem", RTL_TEXTENCODING_UTF8 ), + SFX_USHORT_CONSTANT( "FamilyDecorative", FAMILY_DECORATIVE ), + SFX_USHORT_CONSTANT( "FamilyDontknow", FAMILY_DONTKNOW ), + SFX_USHORT_CONSTANT( "FamilyModern", FAMILY_MODERN ), + SFX_USHORT_CONSTANT( "FamilyRoman", FAMILY_ROMAN ), + SFX_USHORT_CONSTANT( "FamilyScript", FAMILY_SCRIPT ), + SFX_USHORT_CONSTANT( "FamilySwiss", FAMILY_SWISS ), + SFX_USHORT_CONSTANT( "FamilySystem", FAMILY_SYSTEM ), + SFX_USHORT_CONSTANT( "GradientAxial", GRADIENT_AXIAL ), + SFX_USHORT_CONSTANT( "GradientElliptical", GRADIENT_ELLIPTICAL ), + SFX_USHORT_CONSTANT( "GradientLinear", GRADIENT_LINEAR ), + SFX_USHORT_CONSTANT( "GradientRadial", GRADIENT_RADIAL ), + SFX_USHORT_CONSTANT( "GradientRect", GRADIENT_RECT ), + SFX_USHORT_CONSTANT( "GradientSquare", GRADIENT_SQUARE ), + SFX_USHORT_CONSTANT( "ItalicNone", ITALIC_NONE ), + SFX_USHORT_CONSTANT( "ItalicOblique", ITALIC_OBLIQUE ), + SFX_USHORT_CONSTANT( "StrikeThroughDouble", STRIKEOUT_DOUBLE ), + SFX_USHORT_CONSTANT( "StrikeThroughNone", STRIKEOUT_NONE ), + SFX_USHORT_CONSTANT( "StrikeThroughSingle", STRIKEOUT_SINGLE ), + SFX_USHORT_CONSTANT( "UnderlineDotted", UNDERLINE_DOTTED ), + SFX_USHORT_CONSTANT( "UnderlineDouble", UNDERLINE_DOUBLE ), + SFX_USHORT_CONSTANT( "UnderlineNone", UNDERLINE_NONE ), + SFX_USHORT_CONSTANT( "UnderlineSingle", UNDERLINE_SINGLE ), + SFX_USHORT_CONSTANT( "UnitFoot", FUNIT_FOOT ), + SFX_USHORT_CONSTANT( "UnitInch", FUNIT_INCH ), + SFX_USHORT_CONSTANT( "UnitMile", FUNIT_MILE ), + SFX_USHORT_CONSTANT( "UnitPercent", FUNIT_PERCENT ), + SFX_USHORT_CONSTANT( "UnitPoint", FUNIT_POINT ), + SFX_USHORT_CONSTANT( "UnitTwip", FUNIT_TWIP ), + SFX_USHORT_CONSTANT( "Unit_cm", FUNIT_CM ), + SFX_USHORT_CONSTANT( "Unit_m", FUNIT_M ), + SFX_USHORT_CONSTANT( "Unit_mm", FUNIT_MM ), + SFX_USHORT_CONSTANT( "WeightBlack", WEIGHT_BLACK ), + SFX_USHORT_CONSTANT( "WeightBold", WEIGHT_BOLD ), + SFX_USHORT_CONSTANT( "WeightDontKnow", WEIGHT_DONTKNOW ), + SFX_USHORT_CONSTANT( "WeightLight", WEIGHT_LIGHT ), + SFX_USHORT_CONSTANT( "WeightMedium", WEIGHT_MEDIUM ), + SFX_USHORT_CONSTANT( "WeightNormal", WEIGHT_NORMAL ), + SFX_USHORT_CONSTANT( "WeightSemibold", WEIGHT_SEMIBOLD ), + SFX_USHORT_CONSTANT( "WeightSemilight", WEIGHT_SEMILIGHT ), + SFX_USHORT_CONSTANT( "WeightThin", WEIGHT_THIN ), + SFX_USHORT_CONSTANT( "WeightUltrabold", WEIGHT_ULTRABOLD ), + SFX_USHORT_CONSTANT( "WeightUltralight", WEIGHT_ULTRALIGHT ) +}; +*/ +//======================================================================== + +//------------------------------------------------------------------------ +String lcl_GetVersionString(ResMgr* /*pAppData_ImplResMgr*/) +{ + ::rtl::OUString aDefault; + String aVersion( utl::Bootstrap::getBuildIdData( aDefault )); + + if ( aVersion.Len() == 0 ) + { + DBG_ERROR( "No BUILDID in bootstrap file found" ); + } + + aVersion.Erase( 0, aVersion.Search( ':' ) + 1 ); + aVersion.Erase( aVersion.Search( ')' ) ); + return aVersion; +} + +//========================================================================= +sal_uInt16 SfxApplication::SaveBasicManager() const +{ + return 0; +} + +//-------------------------------------------------------------------- +sal_uInt16 SfxApplication::SaveBasicAndDialogContainer() const +{ + if ( pAppData_Impl->pBasicManager->isValid() ) + pAppData_Impl->pBasicManager->storeAllLibraries(); + return 0; +} + +//-------------------------------------------------------------------- + +void SfxApplication::RegisterBasicConstants +( + const char*, // Prefix vor Konstanten-Namen + const SfxConstant*, // Array von <SfxConstant> Instanzen + sal_uInt16 // Anahl der Kontanten in pConsts +) + +/* [Beschreibung] + + Diese Methode meldet Konstanten beim BASIC an. Sie sollte on-demand + (in GetSbxObject() der Applikation) gerufen werden. Das Array mu\s + alphabetisch nach den Namen sortiert sein! + + Durch den Prefix kann Speicher gespart und das Suchen beschleunigt + werden. Im StarOffice soll der Prefix "so" verwendet werden. + + + [Beispiel] + + const SfxConstant __FAR_DATA aConstants[] = + { + SFX_BOOL_CONSTANT( "False", sal_False ), + SFX_BOOL_CONSTANT( "True", sal_True ), + }; + + ... + SFX_APP()->RegisterBasicConstants( 0, aConstants, 2 ); + ... + +*/ + +{ +// DBG_ASSERT( pAppData_Impl->pBasicMgr, "no basic available" ); + +// pAppData_Impl->pBasicMgr->GetLib(0)->Insert( +// new SfxConstants_Impl( pPrefix, pConsts, nCount ) ); +} + +//-------------------------------------------------------------------- + +SbxVariable* MakeVariable( StarBASIC *pBas, SbxObject *pObject, + const char *pName, sal_uInt32 nSID, SbxDataType eType, SbxClassType eClassType ) +{ + SbxVariable *pVar = pBas->Make( String::CreateFromAscii(pName), eClassType, eType ); //SbxCLASS_PROPERTY + pVar->SetUserData( nSID ); + pVar->SetFlag( SBX_DONTSTORE ); + pObject->StartListening( pVar->GetBroadcaster() ); + return pVar; +} + +//-------------------------------------------------------------------- + +BasicManager* SfxApplication::GetBasicManager() +{ +// DBG_ASSERT( pAppData_Impl->nBasicCallLevel != 0, +// "unnecessary call to GetBasicManager() - inefficient!" ); + if ( pAppData_Impl->nBasicCallLevel == 0 ) + // sicherheitshalber + EnterBasicCall(); + + return BasicManagerRepository::getApplicationBasicManager( true ); +} + +//-------------------------------------------------------------------- + +Reference< XLibraryContainer > SfxApplication::GetDialogContainer() +{ + if ( !pAppData_Impl->pBasicManager->isValid() ) + GetBasicManager(); + return pAppData_Impl->pBasicManager->getLibraryContainer( SfxBasicManagerHolder::DIALOGS ); +} + +//-------------------------------------------------------------------- + +Reference< XLibraryContainer > SfxApplication::GetBasicContainer() +{ + if ( !pAppData_Impl->pBasicManager->isValid() ) + GetBasicManager(); + return pAppData_Impl->pBasicManager->getLibraryContainer( SfxBasicManagerHolder::SCRIPTS ); +} + +//-------------------------------------------------------------------- + +StarBASIC* SfxApplication::GetBasic() +{ + return GetBasicManager()->GetLib(0); +} + +//-------------------------------------------------------------------- + +FASTBOOL SfxApplication::IsInBasicCall() const +{ + return 0 != pAppData_Impl->nBasicCallLevel; +} + +//-------------------------------------------------------------------- + +void SfxApplication::EnterBasicCall() +{ + if ( 1 == ++pAppData_Impl->nBasicCallLevel ) + { + DBG_TRACE( "SfxShellObject: BASIC-on-demand" ); + + // das kann l"anger dauern, da Progress nicht geht, wenigstens Sanduhr +//(mba)/task SfxWaitCursor aWait; + + // zuerst das BASIC laden + GetBasic(); +/* + // als erstes SfxShellObject das SbxObject der SfxApplication erzeugen + SbxObject *pSbx = GetSbxObject(); + DBG_ASSERT( pSbx, "SfxShellObject: can't create SbxObject for SfxApplication" ); + + // die SbxObjects aller Module erzeugen + SfxModuleArr_Impl& rArr = GetModules_Impl(); + for ( sal_uInt16 n = 0; n < rArr.Count(); ++n ) + { + SfxModule *pMod = rArr.GetObject(n); + if ( pMod->IsLoaded() ) + { + pSbx = pMod->GetSbxObject(); + DBG_ASSERT( pSbx, "SfxModule: can't create SbxObject" ); + } + } + + // die SbxObjects aller Tasks erzeugen + for ( SfxTask *pTask = SfxTask::GetFirst(); pTask; pTask = SfxTask::GetNext( *pTask ) ) + pTask->GetSbxObject(); + + // die SbxObjects aller SfxObjectShells erzeugen (ggf. Frame-los!) + for ( SfxObjectShell *pObjSh = SfxObjectShell::GetFirst( NULL, sal_False ); + pObjSh; + pObjSh = SfxObjectShell::GetNext(*pObjSh, NULL, sal_False) ) + { + // kein IP-Object oder wenn doch dann initialisiert? + SvStorageRef aStorage; + if ( !pObjSh->IsHandsOff() ) + aStorage = pObjSh->GetStorage(); + if ( !pObjSh->GetInPlaceObject() || aStorage.Is() ) + { + DBG( DbgOutf( "SfxShellObject: BASIC-on-demand for %s", + pObjSh->SfxShell::GetName().GetBuffer() ) ); + pSbx = pObjSh->GetSbxObject(); + DBG_ASSERT( pSbx, "SfxShellObject: can't create SbxObject" ); + } + } + + // die SbxObjects der SfxShells auf den Stacks der Frames erzeugen + for ( SfxViewFrame *pFrame = SfxViewFrame::GetFirst(0,sal_False); + pFrame; + pFrame = SfxViewFrame::GetNext(*pFrame,0,0,sal_False) ) + { + // den Dispatcher des Frames rausholen + SfxDispatcher *pDispat = pFrame->GetDispatcher(); + pDispat->Flush(); + + // "uber alle SfxShells auf dem Stack des Dispatchers iterieren + // Frame selbst wird ausgespart, da er indirekt angezogen wird, + // sofern er ein Dokument enth"alt. + for ( sal_uInt16 nStackIdx = pDispat->GetShellLevel(*pFrame); + 0 != nStackIdx; + --nStackIdx ) + { + DBG( DbgOutf( "SfxShellObject: BASIC-on-demand for level %u", nStackIdx-1 ); ) + pSbx = pDispat->GetShell(nStackIdx - 1)->GetSbxObject(); + DBG_ASSERT( pSbx, "SfxShellObject: can't create SbxObject" ); + } + + if ( !pFrame->GetObjectShell() ) + { + DBG( DbgOutf( "SfxShellObject: BASIC-on-demand for empty frame" ); ) + pSbx = pFrame->GetSbxObject(); + DBG_ASSERT( pSbx, "SfxShellObject: can't create SbxObject" ); + } + } +*/ + // Factories anmelden +// SbxBase::AddFactory( new SfxSbxObjectFactory_Impl ); + } +} + +//-------------------------------------------------------------------- + +void SfxApplication::LeaveBasicCall() +{ + --pAppData_Impl->nBasicCallLevel; +} + +//------------------------------------------------------------------------- +void SfxApplication::PropExec_Impl( SfxRequest &rReq ) +{ + rReq.GetArgs(); + sal_uInt16 nSID = rReq.GetSlot(); + switch ( nSID ) + { + case SID_CREATE_BASICOBJECT: + { + SFX_REQUEST_ARG(rReq, pItem, SfxStringItem, nSID, sal_False); + if ( pItem ) + { + SbxObject* pObject = SbxBase::CreateObject( pItem->GetValue() ); + pObject->AddRef(); +//(mba) rReq.SetReturnValue( SfxObjectItem( 0, pObject ) ); + rReq.Done(); + } + break; + } + + case SID_DELETE_BASICOBJECT: + { + SFX_REQUEST_ARG(rReq, pItem, SfxObjectItem, nSID, sal_False); + if ( pItem ) + { +//(mba) SbxObject* pObject = pItem->GetObject(); +//(mba) pObject->ReleaseRef(); + } + break; + } + + case SID_ATTR_UNDO_COUNT: + { + SFX_REQUEST_ARG(rReq, pCountItem, SfxUInt16Item, nSID, sal_False); + SvtUndoOptions().SetUndoCount( pCountItem->GetValue() ); + break; + } + + case SID_WIN_VISIBLE: + { + break; + } + + case SID_STATUSBARTEXT: + { + SFX_REQUEST_ARG(rReq, pStringItem, SfxStringItem, nSID, sal_False); + String aText = pStringItem->GetValue(); + if ( aText.Len() ) + GetpApp()->ShowStatusText( aText ); + else + GetpApp()->HideStatusText(); + break; + } + + case SID_PLAYMACRO: + PlayMacro_Impl( rReq, GetBasic() ); + break; + + case SID_OFFICE_PRIVATE_USE: + case SID_OFFICE_COMMERCIAL_USE: + { + DBG_ASSERT( sal_False, "SfxApplication::PropExec_Impl()\nSID_OFFICE_PRIVATE_USE & SID_OFFICE_COMMERCIAL_USE are obsolete!\n" ); + break; + } + + case SID_OFFICE_CUSTOMERNUMBER: + { + SFX_REQUEST_ARG(rReq, pStringItem, SfxStringItem, nSID, sal_False); + + if ( pStringItem ) + SvtUserOptions().SetCustomerNumber( pStringItem->GetValue() ); + break; + } + } +} + +//------------------------------------------------------------------------- +void SfxApplication::PropState_Impl( SfxItemSet &rSet ) +{ +// SfxViewFrame *pFrame = SfxViewFrame::Current(); + SfxWhichIter aIter(rSet); + for ( sal_uInt16 nSID = aIter.FirstWhich(); nSID; nSID = aIter.NextWhich() ) + { + switch ( nSID ) + { + case SID_PROGNAME: + rSet.Put( SfxStringItem( SID_PROGNAME, GetName() ) ); + break; + + case SID_ACTIVEDOCUMENT: + rSet.Put( SfxObjectItem( SID_ACTIVEDOCUMENT, SfxObjectShell::Current() ) ); + break; + + case SID_APPLICATION: + rSet.Put( SfxObjectItem( SID_APPLICATION, this ) ); + break; + + case SID_PROGFILENAME: + rSet.Put( SfxStringItem( SID_PROGFILENAME, Application::GetAppFileName() ) ); + break; + + case SID_ATTR_UNDO_COUNT: + rSet.Put( SfxUInt16Item( SID_ATTR_UNDO_COUNT, sal::static_int_cast< UINT16 >( SvtUndoOptions().GetUndoCount() ) ) ); + break; + + case SID_UPDATE_VERSION: + rSet.Put( SfxUInt32Item( SID_UPDATE_VERSION, SUPD ) ); + break; + + case SID_BUILD_VERSION: + { + String aVersion = lcl_GetVersionString(pAppData_Impl->pLabelResMgr); + rSet.Put( SfxUInt32Item( SID_BUILD_VERSION, (sal_uInt32) aVersion.ToInt32() ) ); + break; + } + + case SID_OFFICE_PRIVATE_USE: + case SID_OFFICE_COMMERCIAL_USE: + { + DBG_ASSERT( sal_False, "SfxApplication::PropState_Impl()\nSID_OFFICE_PRIVATE_USE & SID_OFFICE_COMMERCIAL_USE are obsolete!\n" ); + break; + } + + case SID_OFFICE_CUSTOMERNUMBER: + { + rSet.Put( SfxStringItem( nSID, SvtUserOptions().GetCustomerNumber() ) ); + break; + } + } + } +} + +//-------------------------------------------------------------------- +void SfxApplication::MacroExec_Impl( SfxRequest& rReq ) +{ + DBG_MEMTEST(); + if ( SfxMacroConfig::IsMacroSlot( rReq.GetSlot() ) ) + { + // SlotId referenzieren, damit nicht im Execute der Slot abgeschossen + // werden kann + GetMacroConfig()->RegisterSlotId(rReq.GetSlot()); + SFX_REQUEST_ARG(rReq, pArgs, SfxStringItem, + rReq.GetSlot(), sal_False); + String aArgs; + if( pArgs ) aArgs = pArgs->GetValue(); + if ( GetMacroConfig()->ExecuteMacro(rReq.GetSlot(), aArgs ) ) + rReq.Done(); + GetMacroConfig()->ReleaseSlotId(rReq.GetSlot()); + } +} + +//-------------------------------------------------------------------- +void SfxApplication::MacroState_Impl( SfxItemSet& ) +{ + DBG_MEMTEST(); +} + +//------------------------------------------------------------------------- + +void SfxApplication::PlayMacro_Impl( SfxRequest &rReq, StarBASIC *pBasic ) +{ + EnterBasicCall(); + sal_Bool bOK = sal_False; + + // Makro und asynch-Flag + SFX_REQUEST_ARG(rReq,pMacro,SfxStringItem,SID_STATEMENT,sal_False); + SFX_REQUEST_ARG(rReq,pAsynch,SfxBoolItem,SID_ASYNCHRON,sal_False); + + if ( pAsynch && pAsynch->GetValue() ) + { + // asynchron ausf"uhren + GetDispatcher_Impl()->Execute( SID_PLAYMACRO, SFX_CALLMODE_ASYNCHRON, pMacro, 0L ); + rReq.Done(); + } + else if ( pMacro ) + { + // Statement aufbereiten + DBG_ASSERT( pBasic, "no BASIC found" ) ; + String aStatement( '[' ); + aStatement += pMacro->GetValue(); + aStatement += ']'; + + // P"aventiv den Request abschlie\sen, da er ggf. zerst"ort wird + rReq.Done(); + rReq.ReleaseArgs(); + + // Statement ausf"uhren + pBasic->Execute( aStatement ); + bOK = 0 == SbxBase::GetError(); + SbxBase::ResetError(); + } + + LeaveBasicCall(); + rReq.SetReturnValue(SfxBoolItem(0,bOK)); +} + + diff --git a/sfx2/source/appl/appbaslib.cxx b/sfx2/source/appl/appbaslib.cxx new file mode 100644 index 000000000000..96c998b2674d --- /dev/null +++ b/sfx2/source/appl/appbaslib.cxx @@ -0,0 +1,249 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "appbaslib.hxx" + +#include <sfx2/sfxuno.hxx> +#include "sfxtypes.hxx" +#include <sfx2/app.hxx> + +#include <basic/basmgr.hxx> +#include <tools/diagnose_ex.h> +#include <comphelper/processfactory.hxx> + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::script; +using namespace ::com::sun::star::embed; +using ::rtl::OUString; +using ::osl::MutexGuard; +using ::osl::Mutex; + +//============================================================================ +SfxBasicManagerHolder::SfxBasicManagerHolder() + :mpBasicManager( NULL ) +{ +} + +void SfxBasicManagerHolder::reset( BasicManager* _pBasicManager ) +{ + impl_releaseContainers(); + + // Note: we do not delete the old BasicManager. BasicManager instances are + // nowadays obtained from the BasicManagerRepository, and the ownership is with + // the repository. + // @see basic::BasicManagerRepository::getApplicationBasicManager + // @see basic::BasicManagerRepository::getDocumentBasicManager + mpBasicManager = _pBasicManager; + + if ( mpBasicManager ) + { + try + { + mxBasicContainer.set( mpBasicManager->GetScriptLibraryContainer(), UNO_QUERY_THROW ); + mxDialogContainer.set( mpBasicManager->GetDialogLibraryContainer(), UNO_QUERY_THROW ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } +} + +bool SfxBasicManagerHolder::isAnyContainerModified() const +{ + OSL_PRECOND( isValid(), "SfxBasicManagerHolder::isAnyContainerModified: not initialized!" ); + + if ( mxBasicContainer.is() && mxBasicContainer->isModified() ) + return true; + if ( mxDialogContainer.is() && mxDialogContainer->isModified() ) + return true; + + return false; +} + +void SfxBasicManagerHolder::storeAllLibraries() +{ + OSL_PRECOND( isValid(), "SfxBasicManagerHolder::storeAllLibraries: not initialized!" ); + try + { + if ( mxBasicContainer.is() ) + mxBasicContainer->storeLibraries(); + if ( mxDialogContainer.is() ) + mxDialogContainer->storeLibraries(); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } +} + +void SfxBasicManagerHolder::setStorage( const Reference< XStorage >& _rxStorage ) +{ + try + { + if ( mxBasicContainer.is() ) + mxBasicContainer->setRootStorage( _rxStorage ); + if ( mxDialogContainer.is() ) + mxDialogContainer->setRootStorage( _rxStorage ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } +} + +void SfxBasicManagerHolder::storeLibrariesToStorage( const Reference< XStorage >& _rxStorage ) +{ + OSL_PRECOND( isValid(), "SfxBasicManagerHolder::storeLibrariesToStorage: not initialized!" ); + + try + { + if ( mxBasicContainer.is() ) + mxBasicContainer->storeLibrariesToStorage( _rxStorage ); + if ( mxDialogContainer.is() ) + mxDialogContainer->storeLibrariesToStorage( _rxStorage ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } +} + +Reference< XLibraryContainer > SfxBasicManagerHolder::getLibraryContainer( ContainerType _eType ) +{ + OSL_PRECOND( isValid(), "SfxBasicManagerHolder::getLibraryContainer: not initialized!" ); + + switch ( _eType ) + { + case SCRIPTS: return mxBasicContainer.get(); + case DIALOGS: return mxDialogContainer.get(); + } + DBG_ERROR( "SfxBasicManagerHolder::getLibraryContainer: illegal container type!" ); + return NULL; +} + +void SfxBasicManagerHolder::impl_releaseContainers() +{ + mxBasicContainer.clear(); + mxDialogContainer.clear(); +} + +sal_Bool +SfxBasicManagerHolder::LegacyPsswdBinaryLimitExceeded( Sequence< rtl::OUString >& sModules ) +{ + if ( mpBasicManager ) + return mpBasicManager->LegacyPsswdBinaryLimitExceeded( sModules ); + return sal_True; +} + +//============================================================================ +// Service for application library container +SFX_IMPL_ONEINSTANCEFACTORY( SfxApplicationDialogLibraryContainer ) + +Sequence< OUString > SfxApplicationDialogLibraryContainer::impl_getStaticSupportedServiceNames() +{ + static Sequence< OUString > seqServiceNames( 1 ); + static sal_Bool bNeedsInit = sal_True; + + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if( bNeedsInit ) + { + OUString* pSeq = seqServiceNames.getArray(); + pSeq[0] = OUString::createFromAscii( "com.sun.star.script.ApplicationDialogLibraryContainer" ); + bNeedsInit = sal_False; + } + return seqServiceNames; +} + +OUString SfxApplicationDialogLibraryContainer::impl_getStaticImplementationName() +{ + static OUString aImplName; + static sal_Bool bNeedsInit = sal_True; + + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if( bNeedsInit ) + { + aImplName = OUString::createFromAscii( "com.sun.star.comp.sfx2.ApplicationDialogLibraryContainer" ); + bNeedsInit = sal_False; + } + return aImplName; +} + +Reference< XInterface > SAL_CALL SfxApplicationDialogLibraryContainer::impl_createInstance + ( const Reference< XMultiServiceFactory >& ) + throw( Exception ) +{ + SFX_APP()->GetBasicManager(); + Reference< XInterface > xRet = + Reference< XInterface >( SFX_APP()->GetDialogContainer(), UNO_QUERY ); + return xRet; +} + +//============================================================================ +// Service for application library container +SFX_IMPL_ONEINSTANCEFACTORY( SfxApplicationScriptLibraryContainer ) + +Sequence< OUString > SfxApplicationScriptLibraryContainer::impl_getStaticSupportedServiceNames() +{ + static Sequence< OUString > seqServiceNames( 1 ); + static sal_Bool bNeedsInit = sal_True; + + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if( bNeedsInit ) + { + OUString* pSeq = seqServiceNames.getArray(); + pSeq[0] = OUString::createFromAscii( "com.sun.star.script.ApplicationScriptLibraryContainer" ); + bNeedsInit = sal_False; + } + return seqServiceNames; +} + +OUString SfxApplicationScriptLibraryContainer::impl_getStaticImplementationName() +{ + static OUString aImplName; + static sal_Bool bNeedsInit = sal_True; + + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if( bNeedsInit ) + { + aImplName = OUString::createFromAscii( "com.sun.star.comp.sfx2.ApplicationScriptLibraryContainer" ); + bNeedsInit = sal_False; + } + return aImplName; +} + +Reference< XInterface > SAL_CALL SfxApplicationScriptLibraryContainer::impl_createInstance + ( const Reference< XMultiServiceFactory >& ) + throw( Exception ) +{ + SFX_APP()->GetBasicManager(); + Reference< XInterface > xRet = + Reference< XInterface >( SFX_APP()->GetBasicContainer(), UNO_QUERY ); + return xRet; +} + diff --git a/sfx2/source/appl/appcfg.cxx b/sfx2/source/appl/appcfg.cxx new file mode 100644 index 000000000000..6afa8c68ed83 --- /dev/null +++ b/sfx2/source/appl/appcfg.cxx @@ -0,0 +1,1058 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/frame/XDesktop.hpp> +#include <com/sun/star/util/XURLTransformer.hpp> +#ifndef _COM_SUN_STAR_BEANS_PropertyValue_HPP_ +#include <com/sun/star/beans/PropertyValue.hpp> +#endif +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/util/XFlushable.hpp> + +#ifndef _STDLIB_H +#include <stdlib.h> +#endif +#include <tools/config.hxx> +#include <vcl/sound.hxx> +#include <vcl/msgbox.hxx> +#include <tools/string.hxx> +#include <svl/itempool.hxx> +#include <svl/aeitem.hxx> +#include <svl/slstitm.hxx> +#include <svl/stritem.hxx> +#include <svl/intitem.hxx> +#include <svl/eitem.hxx> +#include <svl/szitem.hxx> +#include <svl/undo.hxx> + +#define _SVSTDARR_STRINGS +#include <svl/svstdarr.hxx> +#include <svtools/ttprops.hxx> +#include <sfx2/sfxsids.hrc> +#include <sot/exchange.hxx> + +//#include <svtools/agprop.hxx> +//#include <sj2/sjapplet.hxx> +#include <svl/isethint.hxx> + +#include <unotools/configmgr.hxx> +#include <tools/urlobj.hxx> +#include <tools/wldcrd.hxx> +#include <unotools/saveopt.hxx> +#include <svtools/helpopt.hxx> +#include <unotools/undoopt.hxx> +#include <unotools/securityoptions.hxx> +#include <unotools/pathoptions.hxx> +#include <unotools/inetoptions.hxx> +#include <svtools/miscopt.hxx> +#include <vcl/toolbox.hxx> +#include <unotools/localfilehelper.hxx> +#include <comphelper/processfactory.hxx> +#include <rtl/ustrbuf.hxx> + +#include <sfx2/app.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/viewfrm.hxx> +#include "sfxhelp.hxx" +#include "sfxtypes.hxx" +#include <sfx2/dispatch.hxx> +#include <sfx2/objsh.hxx> +#include "objshimp.hxx" +#include <sfx2/viewsh.hxx> +#include <sfx2/request.hxx> +#include <sfx2/evntconf.hxx> +#include "appdata.hxx" +#include "workwin.hxx" +#include <sfx2/macrconf.hxx> +#include "helper.hxx" // SfxContentHelper::... +#include "app.hrc" +#include "sfxresid.hxx" +#include "shutdownicon.hxx" + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::beans; + +//------------------------------------------------------------------------- + +class SfxEventAsyncer_Impl : public SfxListener +{ + SfxEventHint aHint; + Timer* pTimer; + +public: + + virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ); + SfxEventAsyncer_Impl( const SfxEventHint& rHint ); + ~SfxEventAsyncer_Impl(); + DECL_LINK( TimerHdl, Timer*); +}; + +// ----------------------------------------------------------------------- + +void SfxEventAsyncer_Impl::Notify( SfxBroadcaster&, const SfxHint& rHint ) +{ + SfxSimpleHint* pHint = PTR_CAST( SfxSimpleHint, &rHint ); + if( pHint && pHint->GetId() == SFX_HINT_DYING && pTimer->IsActive() ) + { + pTimer->Stop(); + delete this; + } +} + +// ----------------------------------------------------------------------- + +SfxEventAsyncer_Impl::SfxEventAsyncer_Impl( const SfxEventHint& rHint ) + : aHint( rHint ) +{ + if( rHint.GetObjShell() ) + StartListening( *rHint.GetObjShell() ); + pTimer = new Timer; + pTimer->SetTimeoutHdl( LINK(this, SfxEventAsyncer_Impl, TimerHdl) ); + pTimer->SetTimeout( 0 ); + pTimer->Start(); +} + +// ----------------------------------------------------------------------- + +SfxEventAsyncer_Impl::~SfxEventAsyncer_Impl() +{ + delete pTimer; +} + +// ----------------------------------------------------------------------- + +IMPL_LINK(SfxEventAsyncer_Impl, TimerHdl, Timer*, pAsyncTimer) +{ + (void)pAsyncTimer; // unused variable + SfxObjectShellRef xRef( aHint.GetObjShell() ); + pAsyncTimer->Stop(); +#ifdef DBG_UTIL + if (!xRef.Is()) + { + ByteString aTmp( "SfxEvent: "); + aTmp += ByteString( String( aHint.GetEventName() ), RTL_TEXTENCODING_UTF8 ); + DBG_TRACE( aTmp.GetBuffer() ); + } +#endif + SFX_APP()->Broadcast( aHint ); + if ( xRef.Is() ) + xRef->Broadcast( aHint ); + delete this; + return 0L; +} + + +//-------------------------------------------------------------------- + +BOOL SfxApplication::GetOptions( SfxItemSet& rSet ) +{ + BOOL bRet = FALSE; + SfxItemPool &rPool = GetPool(); + String aTRUEStr('1'); + + const USHORT *pRanges = rSet.GetRanges(); + SvtSaveOptions aSaveOptions; + SvtUndoOptions aUndoOptions; + SvtHelpOptions aHelpOptions; + SvtInetOptions aInetOptions; + SvtSecurityOptions aSecurityOptions; + SvtMiscOptions aMiscOptions; + + while ( *pRanges ) + { + for(USHORT nWhich = *pRanges++; nWhich <= *pRanges; ++nWhich) + { + switch(nWhich) + { + case SID_ATTR_BUTTON_OUTSTYLE3D : + if(rSet.Put( SfxBoolItem( rPool.GetWhich( SID_ATTR_BUTTON_OUTSTYLE3D ), + aMiscOptions.GetToolboxStyle() != TOOLBOX_STYLE_FLAT))) + bRet = TRUE; + break; + case SID_ATTR_BUTTON_BIGSIZE : + { + if( rSet.Put( SfxBoolItem( rPool.GetWhich( SID_ATTR_BUTTON_BIGSIZE ), aMiscOptions.AreCurrentSymbolsLarge() ) ) ) + bRet = TRUE; + break; + } + case SID_ATTR_BACKUP : + { + bRet = TRUE; + if (!aSaveOptions.IsReadOnly(SvtSaveOptions::E_BACKUP)) + if (!rSet.Put( SfxBoolItem( rPool.GetWhich( SID_ATTR_BACKUP ),aSaveOptions.IsBackup()))) + bRet = FALSE; + } + break; + case SID_ATTR_PRETTYPRINTING: + { + bRet = TRUE; + if (!aSaveOptions.IsReadOnly(SvtSaveOptions::E_DOPRETTYPRINTING)) + if (!rSet.Put( SfxBoolItem( rPool.GetWhich( SID_ATTR_PRETTYPRINTING ), aSaveOptions.IsPrettyPrinting()))) + bRet = FALSE; + } + break; + case SID_ATTR_WARNALIENFORMAT: + { + bRet = TRUE; + if (!aSaveOptions.IsReadOnly(SvtSaveOptions::E_WARNALIENFORMAT)) + if (!rSet.Put( SfxBoolItem( rPool.GetWhich( SID_ATTR_WARNALIENFORMAT ), aSaveOptions.IsWarnAlienFormat()))) + bRet = FALSE; + } + break; + case SID_ATTR_AUTOSAVE : + { + bRet = TRUE; + if (!aSaveOptions.IsReadOnly(SvtSaveOptions::E_AUTOSAVE)) + if (!rSet.Put( SfxBoolItem( rPool.GetWhich( SID_ATTR_AUTOSAVE ), aSaveOptions.IsAutoSave()))) + bRet = FALSE; + } + break; + case SID_ATTR_AUTOSAVEPROMPT : + { + bRet = TRUE; + if (!aSaveOptions.IsReadOnly(SvtSaveOptions::E_AUTOSAVEPROMPT)) + if (!rSet.Put( SfxBoolItem( rPool.GetWhich( SID_ATTR_AUTOSAVEPROMPT ), aSaveOptions.IsAutoSavePrompt()))) + bRet = FALSE; + } + break; + case SID_ATTR_AUTOSAVEMINUTE : + { + bRet = TRUE; + if (!aSaveOptions.IsReadOnly(SvtSaveOptions::E_AUTOSAVETIME)) + if (!rSet.Put( SfxUInt16Item( rPool.GetWhich( SID_ATTR_AUTOSAVEMINUTE ), (UINT16)aSaveOptions.GetAutoSaveTime()))) + bRet = FALSE; + } + break; + case SID_ATTR_DOCINFO : + { + bRet = TRUE; + if (!aSaveOptions.IsReadOnly(SvtSaveOptions::E_DOCINFSAVE)) + if (!rSet.Put( SfxBoolItem( rPool.GetWhich( SID_ATTR_DOCINFO ), aSaveOptions.IsDocInfoSave()))) + bRet = FALSE; + } + break; + case SID_ATTR_WORKINGSET : + { + bRet = TRUE; + if (!aSaveOptions.IsReadOnly(SvtSaveOptions::E_SAVEWORKINGSET)) + if (!rSet.Put( SfxBoolItem( rPool.GetWhich( SID_ATTR_WORKINGSET ), aSaveOptions.IsSaveWorkingSet()))) + bRet = FALSE; + } + break; + case SID_ATTR_SAVEDOCVIEW : + { + bRet = TRUE; + if (!aSaveOptions.IsReadOnly(SvtSaveOptions::E_SAVEDOCVIEW)) + if (!rSet.Put( SfxBoolItem( rPool.GetWhich( SID_ATTR_SAVEDOCVIEW ), aSaveOptions.IsSaveDocView()))) + bRet = FALSE; + } + break; + case SID_ATTR_METRIC : +// if(rSet.Put( SfxUInt16Item( rPool.GetWhich( SID_ATTR_METRIC ), +// pOptions->GetMetric() ) ) ) +// bRet = TRUE; + break; + case SID_HELPBALLOONS : + if(rSet.Put( SfxBoolItem ( rPool.GetWhich( SID_HELPBALLOONS ), + aHelpOptions.IsExtendedHelp() ) ) ) + bRet = TRUE; + break; + case SID_HELPTIPS : + if(rSet.Put( SfxBoolItem ( rPool.GetWhich( SID_HELPTIPS ), + aHelpOptions.IsHelpTips() ) ) ) + bRet = TRUE; + break; + case SID_ATTR_AUTOHELPAGENT : + if(rSet.Put( SfxBoolItem ( rPool.GetWhich( SID_ATTR_AUTOHELPAGENT ), + aHelpOptions.IsHelpAgentAutoStartMode() ) ) ) + bRet = TRUE; + break; + case SID_HELPAGENT_TIMEOUT : + if ( rSet.Put( SfxInt32Item( rPool.GetWhich( SID_HELPAGENT_TIMEOUT ), + aHelpOptions.GetHelpAgentTimeoutPeriod() ) ) ) + bRet = TRUE; + break; + case SID_ATTR_WELCOMESCREEN : + if(rSet.Put( SfxBoolItem ( rPool.GetWhich( SID_ATTR_WELCOMESCREEN ), + aHelpOptions.IsWelcomeScreen() ) ) ) + bRet = TRUE; + break; + case SID_HELP_STYLESHEET : + if(rSet.Put( SfxStringItem ( rPool.GetWhich( SID_HELP_STYLESHEET ), + aHelpOptions.GetHelpStyleSheet() ) ) ) + bRet = TRUE; + break; + case SID_ATTR_UNDO_COUNT : + if(rSet.Put( SfxUInt16Item ( rPool.GetWhich( SID_ATTR_UNDO_COUNT ), + (UINT16)aUndoOptions.GetUndoCount() ) ) ) + bRet = TRUE; + break; + case SID_ATTR_QUICKLAUNCHER : + { + if ( ShutdownIcon::IsQuickstarterInstalled() ) + { + if ( rSet.Put( SfxBoolItem( rPool.GetWhich( SID_ATTR_QUICKLAUNCHER ), + ShutdownIcon::GetAutostart() ) ) ) + bRet = TRUE; + } + else + { + rSet.DisableItem( rPool.GetWhich( SID_ATTR_QUICKLAUNCHER ) ); + bRet = TRUE; + } + break; + } + case SID_SAVEREL_INET : + { + bRet = TRUE; + if (!aSaveOptions.IsReadOnly(SvtSaveOptions::E_SAVERELINET)) + if (!rSet.Put( SfxBoolItem ( rPool.GetWhich( SID_SAVEREL_INET ), aSaveOptions.IsSaveRelINet() ))) + bRet = FALSE; + } + break; + case SID_SAVEREL_FSYS : + { + bRet = TRUE; + if (!aSaveOptions.IsReadOnly(SvtSaveOptions::E_SAVERELFSYS)) + if (!rSet.Put( SfxBoolItem ( rPool.GetWhich( SID_SAVEREL_FSYS ), aSaveOptions.IsSaveRelFSys() ))) + bRet = FALSE; + } + break; + case SID_BASIC_ENABLED : + { + bRet = TRUE; + if (!aSecurityOptions.IsReadOnly(SvtSecurityOptions::E_BASICMODE)) + { + if ( !rSet.Put( SfxUInt16Item( rPool.GetWhich( SID_BASIC_ENABLED ), sal::static_int_cast< UINT16 >(aSecurityOptions.GetBasicMode())))) + bRet = FALSE; + } + } + break; + case SID_INET_EXE_PLUGIN : + { + bRet = TRUE; + if (!aSecurityOptions.IsReadOnly(SvtSecurityOptions::E_EXECUTEPLUGINS)) + { + if ( !rSet.Put( SfxBoolItem( SID_INET_EXE_PLUGIN, aSecurityOptions.IsExecutePlugins() ) ) ) + bRet = FALSE; + } + } + break; + case SID_MACRO_WARNING : + { + bRet = TRUE; + if (!aSecurityOptions.IsReadOnly(SvtSecurityOptions::E_WARNING)) + { + if ( !rSet.Put( SfxBoolItem( SID_MACRO_WARNING, aSecurityOptions.IsWarningEnabled() ) ) ) + bRet = FALSE; + } + } + break; + case SID_MACRO_CONFIRMATION : + { + bRet = TRUE; + if (!aSecurityOptions.IsReadOnly(SvtSecurityOptions::E_CONFIRMATION)) + { + if ( !rSet.Put( SfxBoolItem( SID_MACRO_CONFIRMATION, aSecurityOptions.IsConfirmationEnabled() ) ) ) + bRet = FALSE; + } + } + break; + case SID_SECURE_URL : + { + bRet = TRUE; + if (!aSecurityOptions.IsReadOnly(SvtSecurityOptions::E_SECUREURLS)) + { + ::com::sun::star::uno::Sequence< ::rtl::OUString > seqURLs = aSecurityOptions.GetSecureURLs(); + List aList; + sal_uInt32 nCount = seqURLs.getLength(); + sal_uInt32 nURL; + for( nURL=0; nURL<nCount; ++nURL ) + { + aList.Insert( new String( seqURLs[nURL] ), LIST_APPEND ); + } + if( !rSet.Put( SfxStringListItem( rPool.GetWhich(SID_SECURE_URL), + &aList ) ) ) + { + bRet = FALSE; + } + for( nURL=0; nURL<nCount; ++nURL ) + { + delete (String*)aList.GetObject(nURL); + } + aList.Clear(); + } + } + break; + case SID_ENABLE_METAFILEPRINT : +#ifdef ENABLE_MISSINGKEYASSERTIONS//MUSTINI + DBG_ASSERT(sal_False, "SfxApplication::GetOptions()\nSoffice.ini key \"Common\\MetafilePrint\" is obsolete! .. How I can support SID_ENABLE_METAFILEPRINT any longer?\n"); +#endif + break; + case SID_INET_PROXY_TYPE : + { + if( rSet.Put( SfxUInt16Item ( rPool.GetWhich( SID_INET_PROXY_TYPE ), + (UINT16)aInetOptions.GetProxyType() ))) + bRet = TRUE; + break; + } + case SID_INET_HTTP_PROXY_NAME : + { + if ( rSet.Put( SfxStringItem ( rPool.GetWhich(SID_INET_HTTP_PROXY_NAME ), + aInetOptions.GetProxyHttpName() ))) + bRet = TRUE; + break; + } + case SID_INET_HTTP_PROXY_PORT : + if ( rSet.Put( SfxInt32Item( rPool.GetWhich(SID_INET_HTTP_PROXY_PORT ), + aInetOptions.GetProxyHttpPort() ))) + bRet = TRUE; + break; + case SID_INET_FTP_PROXY_NAME : + if ( rSet.Put( SfxStringItem ( rPool.GetWhich(SID_INET_FTP_PROXY_NAME ), + aInetOptions.GetProxyFtpName() ))) + bRet = TRUE; + break; + case SID_INET_FTP_PROXY_PORT : + if ( rSet.Put( SfxInt32Item ( rPool.GetWhich(SID_INET_FTP_PROXY_PORT ), + aInetOptions.GetProxyFtpPort() ))) + bRet = TRUE; + break; + case SID_INET_SECURITY_PROXY_NAME : + case SID_INET_SECURITY_PROXY_PORT : +#ifdef ENABLE_MISSINGKEYASSERTIONS//MUSTINI + DBG_ASSERT( sal_False, "SfxApplication::GetOptions()\nSome INET values no longer supported!\n" ); +#endif + break; + case SID_INET_NOPROXY : + if( rSet.Put( SfxStringItem ( rPool.GetWhich( SID_INET_NOPROXY), + aInetOptions.GetProxyNoProxy() ))) + bRet = TRUE; + break; + case SID_ATTR_PATHNAME : + case SID_ATTR_PATHGROUP : + { + SfxAllEnumItem aNames(rPool.GetWhich(SID_ATTR_PATHGROUP)); + SfxAllEnumItem aValues(rPool.GetWhich(SID_ATTR_PATHNAME)); + SvtPathOptions aPathCfg; + for ( USHORT nProp = SvtPathOptions::PATH_ADDIN; + nProp <= SvtPathOptions::PATH_WORK; nProp++ ) + { + const String aName( SfxResId( CONFIG_PATH_START + nProp ) ); + aNames.InsertValue( nProp, aName ); + String aValue; + switch ( nProp ) + { + case SvtPathOptions::PATH_ADDIN: ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aPathCfg.GetAddinPath(), aValue ); break; + case SvtPathOptions::PATH_AUTOCORRECT: aValue = aPathCfg.GetAutoCorrectPath(); break; + case SvtPathOptions::PATH_AUTOTEXT: aValue = aPathCfg.GetAutoTextPath(); break; + case SvtPathOptions::PATH_BACKUP: aValue = aPathCfg.GetBackupPath(); break; + case SvtPathOptions::PATH_BASIC: aValue = aPathCfg.GetBasicPath(); break; + case SvtPathOptions::PATH_BITMAP: aValue = aPathCfg.GetBitmapPath(); break; + case SvtPathOptions::PATH_CONFIG: aValue = aPathCfg.GetConfigPath(); break; + case SvtPathOptions::PATH_DICTIONARY: aValue = aPathCfg.GetDictionaryPath(); break; + case SvtPathOptions::PATH_FAVORITES: aValue = aPathCfg.GetFavoritesPath(); break; + case SvtPathOptions::PATH_FILTER: ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aPathCfg.GetFilterPath(), aValue ); break; + case SvtPathOptions::PATH_GALLERY: aValue = aPathCfg.GetGalleryPath(); break; + case SvtPathOptions::PATH_GRAPHIC: aValue = aPathCfg.GetGraphicPath(); break; + case SvtPathOptions::PATH_HELP: ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aPathCfg.GetHelpPath(), aValue ); break; + case SvtPathOptions::PATH_LINGUISTIC: aValue = aPathCfg.GetLinguisticPath(); break; + case SvtPathOptions::PATH_MODULE: ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aPathCfg.GetModulePath(), aValue ); break; + case SvtPathOptions::PATH_PALETTE: aValue = aPathCfg.GetPalettePath(); break; + case SvtPathOptions::PATH_PLUGIN: ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aPathCfg.GetPluginPath(), aValue ); break; + case SvtPathOptions::PATH_STORAGE: ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aPathCfg.GetStoragePath(), aValue ); break; + case SvtPathOptions::PATH_TEMP: aValue = aPathCfg.GetTempPath(); break; + case SvtPathOptions::PATH_TEMPLATE: aValue = aPathCfg.GetTemplatePath(); break; + case SvtPathOptions::PATH_USERCONFIG: aValue = aPathCfg.GetUserConfigPath(); break; + case SvtPathOptions::PATH_WORK: aValue = aPathCfg.GetWorkPath(); break; + } + aValues.InsertValue( nProp, aValue ); + } + + if ( rSet.Put(aNames) || rSet.Put(aValues) ) + bRet = TRUE; + } + + default: + DBG_WARNING( "W1:Wrong ID while getting Options!" ); + break; + } +#ifdef DBG_UTIL + if ( !bRet ) + DBG_ERROR( "Putting options failed!" ); +#endif + } + pRanges++; + } + + return bRet; +} + +//-------------------------------------------------------------------- +BOOL SfxApplication::IsSecureURL( const INetURLObject& rURL, const String* pReferer ) const +{ + return SvtSecurityOptions().IsSecureURL( rURL.GetMainURL( INetURLObject::NO_DECODE ), *pReferer ); +} +//-------------------------------------------------------------------- +// TODO/CLEANUP: wieso zwei SetOptions Methoden? +void SfxApplication::SetOptions_Impl( const SfxItemSet& rSet ) +{ + const SfxPoolItem *pItem = 0; + SfxItemPool &rPool = GetPool(); + BOOL bResetSession = FALSE; + BOOL bProxiesModified = FALSE; + + SvtSaveOptions aSaveOptions; + SvtUndoOptions aUndoOptions; + SvtHelpOptions aHelpOptions; + SvtSecurityOptions aSecurityOptions; + SvtPathOptions aPathOptions; + SvtInetOptions aInetOptions; + SvtMiscOptions aMiscOptions; + if ( SFX_ITEM_SET == rSet.GetItemState(rPool.GetWhich(SID_ATTR_BUTTON_OUTSTYLE3D), TRUE, &pItem) ) + { + DBG_ASSERT(pItem->ISA(SfxBoolItem), "BoolItem expected"); + USHORT nOutStyle = + ( (const SfxBoolItem *)pItem)->GetValue() ? 0 : TOOLBOX_STYLE_FLAT; + aMiscOptions.SetToolboxStyle( nOutStyle ); + } + + if ( SFX_ITEM_SET == rSet.GetItemState(rPool.GetWhich(SID_ATTR_BUTTON_BIGSIZE), TRUE, &pItem) ) + { + DBG_ASSERT(pItem->ISA(SfxBoolItem), "BoolItem expected"); + BOOL bBigSize = ( (const SfxBoolItem*)pItem )->GetValue(); + aMiscOptions.SetSymbolsSize( + sal::static_int_cast< sal_Int16 >( + bBigSize ? SFX_SYMBOLS_SIZE_LARGE : SFX_SYMBOLS_SIZE_SMALL ) ); + SfxViewFrame* pCurrViewFrame = SfxViewFrame::GetFirst(); + while ( pCurrViewFrame ) + { + // update all "final" dispatchers + if ( !pCurrViewFrame->GetActiveChildFrame_Impl() ) + pCurrViewFrame->GetDispatcher()->Update_Impl(sal_True); + pCurrViewFrame = SfxViewFrame::GetNext(*pCurrViewFrame); + } + } + + // Backup + if ( SFX_ITEM_SET == rSet.GetItemState(rPool.GetWhich(SID_ATTR_BACKUP), TRUE, &pItem) ) + { + DBG_ASSERT(pItem->ISA(SfxBoolItem), "BoolItem expected"); + aSaveOptions.SetBackup( ( (const SfxBoolItem*)pItem )->GetValue() ); + } + + // PrettyPrinting + if ( SFX_ITEM_SET == rSet.GetItemState( rPool.GetWhich( SID_ATTR_PRETTYPRINTING ), TRUE, &pItem ) ) + { + DBG_ASSERT( pItem->ISA( SfxBoolItem ), "BoolItem expected" ); + aSaveOptions.SetPrettyPrinting( static_cast< const SfxBoolItem*> ( pItem )->GetValue() ); + } + + // WarnAlienFormat + if ( SFX_ITEM_SET == rSet.GetItemState( rPool.GetWhich( SID_ATTR_WARNALIENFORMAT ), TRUE, &pItem ) ) + { + DBG_ASSERT( pItem->ISA( SfxBoolItem ), "BoolItem expected" ); + aSaveOptions.SetWarnAlienFormat( static_cast< const SfxBoolItem*> ( pItem )->GetValue() ); + } + + // AutoSave + if ( SFX_ITEM_SET == rSet.GetItemState(rPool.GetWhich(SID_ATTR_AUTOSAVE), TRUE, &pItem)) + { + DBG_ASSERT(pItem->ISA(SfxBoolItem), "BoolItem expected"); + aSaveOptions.SetAutoSave( ( (const SfxBoolItem*)pItem )->GetValue() ); + } + + // AutoSave-Propt + if ( SFX_ITEM_SET == rSet.GetItemState(rPool.GetWhich(SID_ATTR_AUTOSAVEPROMPT), TRUE, &pItem)) + { + DBG_ASSERT(pItem->ISA(SfxBoolItem), "BoolItem expected"); + aSaveOptions.SetAutoSavePrompt(((const SfxBoolItem *)pItem)->GetValue()); + } + + // AutoSave-Time + if ( SFX_ITEM_SET == rSet.GetItemState(rPool.GetWhich(SID_ATTR_AUTOSAVEMINUTE), TRUE, &pItem)) + { + DBG_ASSERT(pItem->ISA(SfxUInt16Item), "UInt16Item expected"); + aSaveOptions.SetAutoSaveTime(((const SfxUInt16Item *)pItem)->GetValue()); + } + + // DocInfo + if ( SFX_ITEM_SET == rSet.GetItemState(rPool.GetWhich(SID_ATTR_DOCINFO), TRUE, &pItem)) + { + DBG_ASSERT(pItem->ISA(SfxBoolItem), "BoolItem expected"); + aSaveOptions.SetDocInfoSave(((const SfxBoolItem *)pItem)->GetValue()); + } + + // offende Dokumente merken + if ( SFX_ITEM_SET == rSet.GetItemState(rPool.GetWhich(SID_ATTR_WORKINGSET), TRUE, &pItem)) + { + DBG_ASSERT(pItem->ISA(SfxBoolItem), "BoolItem expected"); + aSaveOptions.SetSaveWorkingSet(((const SfxBoolItem *)pItem)->GetValue()); + } + + // Fenster-Einstellung speichern + if ( SFX_ITEM_SET == rSet.GetItemState(rPool.GetWhich(SID_ATTR_SAVEDOCVIEW), TRUE, &pItem)) + { + DBG_ASSERT(pItem->ISA(SfxBoolItem), "BoolItem expected"); + aSaveOptions.SetSaveDocView(((const SfxBoolItem *)pItem)->GetValue()); + } + + // Metric + if ( SFX_ITEM_SET == rSet.GetItemState(rPool.GetWhich(SID_ATTR_METRIC), TRUE, &pItem)) + { + DBG_ASSERT(pItem->ISA(SfxUInt16Item), "UInt16Item expected"); +// pOptions->SetMetric((FieldUnit)((const SfxUInt16Item*)pItem)->GetValue()); + } + + // HelpBalloons + if ( SFX_ITEM_SET == rSet.GetItemState(rPool.GetWhich(SID_HELPBALLOONS), TRUE, &pItem)) + { + DBG_ASSERT(pItem->ISA(SfxBoolItem), "BoolItem expected"); + aHelpOptions.SetExtendedHelp(((const SfxBoolItem *)pItem)->GetValue()); + } + + // HelpTips + if ( SFX_ITEM_SET == rSet.GetItemState(rPool.GetWhich(SID_HELPTIPS), TRUE, &pItem)) + { + DBG_ASSERT(pItem->ISA(SfxBoolItem), "BoolItem expected"); + aHelpOptions.SetHelpTips(((const SfxBoolItem *)pItem)->GetValue()); + } + + // AutoHelpAgent + if ( SFX_ITEM_SET == rSet.GetItemState(rPool.GetWhich(SID_ATTR_AUTOHELPAGENT ), TRUE, &pItem)) + { + DBG_ASSERT(pItem->ISA(SfxBoolItem), "BoolItem expected"); + aHelpOptions.SetHelpAgentAutoStartMode( ((const SfxBoolItem *)pItem)->GetValue() ); + } + + // help agent timeout + if ( SFX_ITEM_SET == rSet.GetItemState( rPool.GetWhich( SID_HELPAGENT_TIMEOUT ), TRUE, &pItem ) ) + { + DBG_ASSERT(pItem->ISA(SfxInt32Item), "Int32Item expected"); + aHelpOptions.SetHelpAgentTimeoutPeriod( ( (const SfxInt32Item*)pItem )->GetValue() ); + } + + // WelcomeScreen + if ( SFX_ITEM_SET == rSet.GetItemState(rPool.GetWhich(SID_ATTR_WELCOMESCREEN ), TRUE, &pItem)) + { + DBG_ASSERT(pItem->ISA(SfxBoolItem), "BoolItem expected"); + aHelpOptions.SetWelcomeScreen( ((const SfxBoolItem *)pItem)->GetValue() ); + } + + // WelcomeScreen + if ( SFX_ITEM_SET == rSet.GetItemState(rPool.GetWhich(SID_WELCOMESCREEN_RESET ), TRUE, &pItem)) + { + DBG_ASSERT(pItem->ISA(SfxBoolItem), "BoolItem expected"); + BOOL bReset = ((const SfxBoolItem *)pItem)->GetValue(); + if ( bReset ) + { + DBG_ERROR( "Not implemented, may be EOL!" ); + } } + + if ( SFX_ITEM_SET == rSet.GetItemState(rPool.GetWhich(SID_HELP_STYLESHEET ), TRUE, &pItem)) + { + DBG_ASSERT(pItem->ISA(SfxStringItem), "StringItem expected"); + aHelpOptions.SetHelpStyleSheet( ((const SfxStringItem *)pItem)->GetValue() ); + } + + // SaveRelINet + if ( SFX_ITEM_SET == rSet.GetItemState(rPool.GetWhich(SID_SAVEREL_INET), TRUE, &pItem)) + { + DBG_ASSERT(pItem->ISA(SfxBoolItem), "BoolItem expected"); + aSaveOptions.SetSaveRelINet(((const SfxBoolItem *)pItem)->GetValue()); + } + + // SaveRelFSys + if ( SFX_ITEM_SET == rSet.GetItemState(rPool.GetWhich(SID_SAVEREL_FSYS), TRUE, &pItem)) + { + DBG_ASSERT(pItem->ISA(SfxBoolItem), "BoolItem expected"); + aSaveOptions.SetSaveRelFSys(((const SfxBoolItem *)pItem)->GetValue()); + } + + // Undo-Count + if ( SFX_ITEM_SET == rSet.GetItemState(rPool.GetWhich(SID_ATTR_UNDO_COUNT), TRUE, &pItem)) + { + DBG_ASSERT(pItem->ISA(SfxUInt16Item), "UInt16Item expected"); + USHORT nUndoCount = ((const SfxUInt16Item*)pItem)->GetValue(); + aUndoOptions.SetUndoCount( nUndoCount ); + + // um alle Undo-Manager zu erwischen: "uber alle Frames iterieren + for ( SfxViewFrame *pFrame = SfxViewFrame::GetFirst(); + pFrame; + pFrame = SfxViewFrame::GetNext(*pFrame) ) + { + // den Dispatcher des Frames rausholen + SfxDispatcher *pDispat = pFrame->GetDispatcher(); + pDispat->Flush(); + + // "uber alle SfxShells auf dem Stack des Dispatchers iterieren + USHORT nIdx = 0; + for ( SfxShell *pSh = pDispat->GetShell(nIdx); + pSh; + ++nIdx, pSh = pDispat->GetShell(nIdx) ) + { + SfxUndoManager *pShUndoMgr = pSh->GetUndoManager(); + if ( pShUndoMgr ) + pShUndoMgr->SetMaxUndoActionCount( nUndoCount ); + } + } + } + + // Office autostart + if ( SFX_ITEM_SET == rSet.GetItemState(rPool.GetWhich(SID_ATTR_QUICKLAUNCHER), TRUE, &pItem)) + { + DBG_ASSERT(pItem->ISA(SfxBoolItem), "BoolItem expected"); + ShutdownIcon::SetAutostart( ( (const SfxBoolItem*)pItem )->GetValue() != FALSE ); + } + + // StarBasic Enable + if ( SFX_ITEM_SET == rSet.GetItemState(SID_BASIC_ENABLED, TRUE, &pItem)) + { + DBG_ASSERT(pItem->ISA(SfxUInt16Item), "SfxInt16Item expected"); + aSecurityOptions.SetBasicMode( (EBasicSecurityMode)( (const SfxUInt16Item*)pItem )->GetValue() ); + } + + // Execute PlugIns + if ( SFX_ITEM_SET == rSet.GetItemState(SID_INET_EXE_PLUGIN, TRUE, &pItem)) + { + DBG_ASSERT(pItem->ISA(SfxBoolItem), "SfxBoolItem expected"); + aSecurityOptions.SetExecutePlugins( ( (const SfxBoolItem *)pItem )->GetValue() ); + bResetSession = TRUE; + } + + if ( SFX_ITEM_SET == rSet.GetItemState(rPool.GetWhich(SID_INET_PROXY_TYPE), TRUE, &pItem)) + { + DBG_ASSERT( pItem->ISA(SfxUInt16Item), "UInt16Item expected" ); + aInetOptions.SetProxyType((SvtInetOptions::ProxyType)( (const SfxUInt16Item*)pItem )->GetValue()); + bResetSession = TRUE; + bProxiesModified = TRUE; + } + + if ( SFX_ITEM_SET == rSet.GetItemState( rPool.GetWhich( SID_INET_HTTP_PROXY_NAME ), TRUE, &pItem ) ) + { + DBG_ASSERT( pItem->ISA(SfxStringItem), "StringItem expected" ); + aInetOptions.SetProxyHttpName( ((const SfxStringItem *)pItem)->GetValue() ); + bResetSession = TRUE; + bProxiesModified = TRUE; + } + if ( SFX_ITEM_SET == rSet.GetItemState( rPool.GetWhich( SID_INET_HTTP_PROXY_PORT ), TRUE, &pItem ) ) + { + DBG_ASSERT( pItem->ISA(SfxInt32Item), "Int32Item expected" ); + aInetOptions.SetProxyHttpPort( ( (const SfxInt32Item*)pItem )->GetValue() ); + bResetSession = TRUE; + bProxiesModified = TRUE; + } + if ( SFX_ITEM_SET == rSet.GetItemState( rPool.GetWhich( SID_INET_FTP_PROXY_NAME ), TRUE, &pItem ) ) + { + DBG_ASSERT( pItem->ISA(SfxStringItem), "StringItem expected" ); + aInetOptions.SetProxyFtpName( ((const SfxStringItem *)pItem)->GetValue() ); + bResetSession = TRUE; + bProxiesModified = TRUE; + } + if ( SFX_ITEM_SET == rSet.GetItemState( rPool.GetWhich( SID_INET_FTP_PROXY_PORT ), TRUE, &pItem ) ) + { + DBG_ASSERT( pItem->ISA(SfxInt32Item), "Int32Item expected" ); + aInetOptions.SetProxyFtpPort( ( (const SfxInt32Item*)pItem )->GetValue() ); + bResetSession = TRUE; + bProxiesModified = TRUE; + } + if ( SFX_ITEM_SET == rSet.GetItemState(SID_INET_NOPROXY, TRUE, &pItem)) + { + DBG_ASSERT(pItem->ISA(SfxStringItem), "StringItem expected"); + aInetOptions.SetProxyNoProxy(((const SfxStringItem *)pItem)->GetValue()); + bResetSession = TRUE; + bProxiesModified = TRUE; + } + + // Secure-Referers + if ( SFX_ITEM_SET == rSet.GetItemState(SID_SECURE_URL, TRUE, &pItem)) + { + DELETEZ(pAppData_Impl->pSecureURLs); + + DBG_ASSERT(pItem->ISA(SfxStringListItem), "StringListItem expected"); + const List *pList = ((SfxStringListItem*)pItem)->GetList(); + sal_uInt32 nCount = pList->Count(); + ::com::sun::star::uno::Sequence< ::rtl::OUString > seqURLs(nCount); + for( sal_uInt32 nPosition=0;nPosition<nCount;++nPosition) + { + seqURLs[nPosition] = *(const String*)(pList->GetObject(nPosition)); + } + aSecurityOptions.SetSecureURLs( seqURLs ); + } + + if ( SFX_ITEM_SET == rSet.GetItemState(SID_MACRO_WARNING, TRUE, &pItem)) + { + DBG_ASSERT(pItem->ISA(SfxBoolItem), "SfxBoolItem expected"); + aSecurityOptions.SetWarningEnabled( ( (const SfxBoolItem *)pItem )->GetValue() ); + } + if ( SFX_ITEM_SET == rSet.GetItemState(SID_MACRO_CONFIRMATION, TRUE, &pItem)) + { + DBG_ASSERT(pItem->ISA(SfxBoolItem), "SfxBoolItem expected"); + aSecurityOptions.SetConfirmationEnabled( ( (const SfxBoolItem *)pItem )->GetValue() ); + } + + // EnableMetafilePrint + if ( SFX_ITEM_SET == rSet.GetItemState( rPool.GetWhich( SID_ENABLE_METAFILEPRINT ), TRUE, &pItem ) ) + { +#ifdef ENABLE_MISSINGKEYASSERTIONS//MUSTINI + DBG_ASSERT(sal_False, "SfxApplication::SetOptions_Impl()\nsoffice.ini key \"MetafilPrint\" not supported any longer!\n"); +#endif + } + + // INet Session neu aufsetzen + if ( bResetSession ) + { + // no more sj2 + #if 0 + try + { + SjApplet2::settingsChanged(); + } + catch ( ... ) + { + DBG_ERRORFILE( "SjApplet2::settingsChanged() throws an exception" ); + } + #endif + } + + // geaenderte Daten speichern + aInetOptions.flush(); +} + +//-------------------------------------------------------------------- +void SfxApplication::SetOptions(const SfxItemSet &rSet) +{ + SvtPathOptions aPathOptions; + + // Daten werden in DocInfo und IniManager gespeichert + const SfxPoolItem *pItem = 0; + SfxItemPool &rPool = GetPool(); + + SfxAllItemSet aSendSet( rSet ); + + // PathName + if ( SFX_ITEM_SET == rSet.GetItemState(rPool.GetWhich(SID_ATTR_PATHNAME), TRUE, &pItem)) + { + DBG_ASSERT(pItem->ISA(SfxAllEnumItem), "AllEnumItem expected"); + const SfxAllEnumItem* pEnumItem = (const SfxAllEnumItem *)pItem; + sal_uInt32 nCount = pEnumItem->GetValueCount(); + String aNoChangeStr( ' ' ); + for( sal_uInt32 nPath=0; nPath<nCount; ++nPath ) + { + String sValue = pEnumItem->GetValueTextByPos((USHORT)nPath); + if ( sValue != aNoChangeStr ) + { + switch( nPath ) + { + case SvtPathOptions::PATH_ADDIN: + { + String aTmp; + if( ::utl::LocalFileHelper::ConvertURLToPhysicalName( sValue, aTmp ) ) + aPathOptions.SetAddinPath( aTmp ); + break; + } + + case SvtPathOptions::PATH_AUTOCORRECT: aPathOptions.SetAutoCorrectPath( sValue );break; + case SvtPathOptions::PATH_AUTOTEXT: aPathOptions.SetAutoTextPath( sValue );break; + case SvtPathOptions::PATH_BACKUP: aPathOptions.SetBackupPath( sValue );break; + case SvtPathOptions::PATH_BASIC: aPathOptions.SetBasicPath( sValue );break; + case SvtPathOptions::PATH_BITMAP: aPathOptions.SetBitmapPath( sValue );break; + case SvtPathOptions::PATH_CONFIG: aPathOptions.SetConfigPath( sValue );break; + case SvtPathOptions::PATH_DICTIONARY: aPathOptions.SetDictionaryPath( sValue );break; + case SvtPathOptions::PATH_FAVORITES: aPathOptions.SetFavoritesPath( sValue );break; + case SvtPathOptions::PATH_FILTER: + { + String aTmp; + if( ::utl::LocalFileHelper::ConvertURLToPhysicalName( sValue, aTmp ) ) + aPathOptions.SetFilterPath( aTmp ); + break; + } + case SvtPathOptions::PATH_GALLERY: aPathOptions.SetGalleryPath( sValue );break; + case SvtPathOptions::PATH_GRAPHIC: aPathOptions.SetGraphicPath( sValue );break; + case SvtPathOptions::PATH_HELP: + { + String aTmp; + if( ::utl::LocalFileHelper::ConvertURLToPhysicalName( sValue, aTmp ) ) + aPathOptions.SetHelpPath( aTmp ); + break; + } + + case SvtPathOptions::PATH_LINGUISTIC: aPathOptions.SetLinguisticPath( sValue );break; + case SvtPathOptions::PATH_MODULE: + { + String aTmp; + if( ::utl::LocalFileHelper::ConvertURLToPhysicalName( sValue, aTmp ) ) + aPathOptions.SetModulePath( aTmp ); + break; + } + + case SvtPathOptions::PATH_PALETTE: aPathOptions.SetPalettePath( sValue );break; + case SvtPathOptions::PATH_PLUGIN: + { + String aTmp; + if( ::utl::LocalFileHelper::ConvertURLToPhysicalName( sValue, aTmp ) ) + aPathOptions.SetPluginPath( aTmp ); + break; + } + + case SvtPathOptions::PATH_STORAGE: + { + String aTmp; + if( ::utl::LocalFileHelper::ConvertURLToPhysicalName( sValue, aTmp ) ) + aPathOptions.SetStoragePath( aTmp ); + break; + } + + case SvtPathOptions::PATH_TEMP: aPathOptions.SetTempPath( sValue );break; + case SvtPathOptions::PATH_TEMPLATE: aPathOptions.SetTemplatePath( sValue );break; + case SvtPathOptions::PATH_USERCONFIG: aPathOptions.SetUserConfigPath( sValue );break; + case SvtPathOptions::PATH_WORK: aPathOptions.SetWorkPath( sValue );break; + default: DBG_ERRORFILE("SfxApplication::SetOptions_Impl()\nInvalid path number found for set directories!"); + } + } + } + + aSendSet.ClearItem( rPool.GetWhich( SID_ATTR_PATHNAME ) ); + } + + SetOptions_Impl( rSet ); + + // Undo-Count + Broadcast( SfxItemSetHint( rSet ) ); +} + +//-------------------------------------------------------------------- + +// alle Dokumente speichern + +BOOL SfxApplication::SaveAll_Impl(BOOL bPrompt, BOOL bAutoSave) +{ + bAutoSave = FALSE; // functionality moved to new AutoRecovery Service! + + BOOL bFunc = TRUE; + short nRet; + + for ( SfxObjectShell *pDoc = SfxObjectShell::GetFirst(); + pDoc; + pDoc = SfxObjectShell::GetNext(*pDoc) ) + { + if( SFX_CREATE_MODE_STANDARD == pDoc->GetCreateMode() && + SfxViewFrame::GetFirst(pDoc) && + !pDoc->IsInModalMode() && + !pDoc->HasModalViews() ) + { + if ( pDoc->GetProgress() == 0 ) + { + if ( !pDoc->IsModified() ) + continue; + + if ( bPrompt || (bAutoSave && !pDoc->HasName()) ) + nRet = QuerySave_Impl( *pDoc, bAutoSave ); + else + nRet = RET_YES; + + if ( nRet == RET_YES ) + { + SfxRequest aReq( SID_SAVEDOC, 0, pDoc->GetPool() ); + const SfxPoolItem *pPoolItem = pDoc->ExecuteSlot( aReq ); + if ( !pPoolItem || !pPoolItem->ISA(SfxBoolItem) || + !( (const SfxBoolItem*) pPoolItem )->GetValue() ) + bFunc = FALSE; + } + else if ( nRet == RET_CANCEL ) + { + bFunc = FALSE; + break; + } + else if ( nRet == RET_NO ) + { + } + } + } + } + + return bFunc; +} + +//-------------------------------------------------------------------- + +SfxMacroConfig* SfxApplication::GetMacroConfig() const +{ + return SfxMacroConfig::GetOrCreate(); +} + +//-------------------------------------------------------------------- +SfxEventConfiguration* SfxApplication::GetEventConfig() const +{ + if (!pAppData_Impl->pEventConfig) + pAppData_Impl->pEventConfig = new SfxEventConfiguration; + return pAppData_Impl->pEventConfig; +} + +//-------------------------------------------------------------------- + +//-------------------------------------------------------------------- +void SfxApplication::NotifyEvent( const SfxEventHint& rEventHint, FASTBOOL bSynchron ) +{ + //DBG_ASSERT(pAppData_Impl->pEventConfig,"Keine Events angemeldet!"); + + SfxObjectShell *pDoc = rEventHint.GetObjShell(); + if ( pDoc && ( pDoc->IsPreview() || !pDoc->Get_Impl()->bInitialized ) ) + return; + +#ifdef DBG_UTIL + //::rtl::OUString aName = SfxEventConfiguration::GetEventName_Impl( rEventHint.GetEventId() ); + //ByteString aTmp( "SfxEvent: "); + //aTmp += ByteString( String(aName), RTL_TEXTENCODING_UTF8 ); + //DBG_TRACE( aTmp.GetBuffer() ); +#endif + + if ( bSynchron ) + { +#ifdef DBG_UTIL + if (!pDoc) + { + ByteString aTmp( "SfxEvent: "); + aTmp += ByteString( String( rEventHint.GetEventName() ), RTL_TEXTENCODING_UTF8 ); + DBG_TRACE( aTmp.GetBuffer() ); + } +#endif + Broadcast(rEventHint); + if ( pDoc ) + pDoc->Broadcast( rEventHint ); + } + else + new SfxEventAsyncer_Impl( rEventHint ); +} + +IMPL_OBJHINT( SfxStringHint, String ) + diff --git a/sfx2/source/appl/appchild.cxx b/sfx2/source/appl/appchild.cxx new file mode 100644 index 000000000000..b18fc905abdc --- /dev/null +++ b/sfx2/source/appl/appchild.cxx @@ -0,0 +1,176 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" + +#ifndef GCC +#endif +#include <svl/whiter.hxx> +#include <svl/eitem.hxx> + +#include <sfx2/app.hxx> +#include "appdata.hxx" +#include "workwin.hxx" +#include <sfx2/childwin.hxx> +#include "arrdecl.hxx" +#include <sfx2/templdlg.hxx> +#include <sfx2/request.hxx> +#include <sfx2/bindings.hxx> +#include <sfx2/dispatch.hxx> +#include "sfxtypes.hxx" +#include <sfx2/module.hxx> +#include <sfx2/sfxsids.hrc> + +//========================================================================= + + +void SfxApplication::RegisterChildWindow_Impl( SfxModule *pMod, SfxChildWinFactory *pFact ) +{ + if ( pMod ) + { + pMod->RegisterChildWindow( pFact ); + return; + } + + if (!pAppData_Impl->pFactArr) + pAppData_Impl->pFactArr = new SfxChildWinFactArr_Impl; + +//#ifdef DBG_UTIL + for (USHORT nFactory=0; nFactory<pAppData_Impl->pFactArr->Count(); ++nFactory) + { + if (pFact->nId == (*pAppData_Impl->pFactArr)[nFactory]->nId) + { + pAppData_Impl->pFactArr->Remove( nFactory ); +// DBG_ERROR("ChildWindow mehrfach registriert!"); +// return; + } + } +//#endif + + pAppData_Impl->pFactArr->C40_INSERT( + SfxChildWinFactory, pFact, pAppData_Impl->pFactArr->Count() ); +} + +void SfxApplication::RegisterChildWindowContext_Impl( SfxModule *pMod, USHORT nId, + SfxChildWinContextFactory *pFact) +{ + SfxChildWinFactArr_Impl *pFactories; + SfxChildWinFactory *pF = NULL; + if ( pMod ) + { + // Modul "ubergeben, ChildwindowFactory dort suchen + pFactories = pMod->GetChildWinFactories_Impl(); + if ( pFactories ) + { + USHORT nCount = pFactories->Count(); + for (USHORT nFactory=0; nFactory<nCount; ++nFactory) + { + SfxChildWinFactory *pFac = (*pFactories)[nFactory]; + if ( nId == pFac->nId ) + { + // Factory gefunden, Context dort registrieren + pF = pFac; + break; + } + } + } + } + + if ( !pF ) + { + // Factory an der Application suchen + DBG_ASSERT( pAppData_Impl, "Keine AppDaten!" ); + DBG_ASSERT( pAppData_Impl->pFactArr, "Keine Factories!" ); + + pFactories = pAppData_Impl->pFactArr; + USHORT nCount = pFactories->Count(); + for (USHORT nFactory=0; nFactory<nCount; ++nFactory) + { + SfxChildWinFactory *pFac = (*pFactories)[nFactory]; + if ( nId == pFac->nId ) + { + if ( pMod ) + { + // Wenn der Context von einem Modul registriert wurde, + // mu\s die ChildwindowFactory auch dort zur Verf"ugung + // stehen, sonst m"u\ste sich die Contextfactory im DLL-Exit + // wieder abmelden ! + pF = new SfxChildWinFactory( pFac->pCtor, pFac->nId, + pFac->nPos ); + pMod->RegisterChildWindow( pF ); + } + else + pF = pFac; + break; + } + } + } + + if ( pF ) + { + if ( !pF->pArr ) + pF->pArr = new SfxChildWinContextArr_Impl; + pF->pArr->C40_INSERT( SfxChildWinContextFactory, pFact, pF->pArr->Count() ); + return; + } + + DBG_ERROR( "Kein ChildWindow fuer diesen Context!" ); +} + +//-------------------------------------------------------------------- + +SfxChildWinFactArr_Impl& SfxApplication::GetChildWinFactories_Impl() const +{ + return ( *(pAppData_Impl->pFactArr)); +} + +//-------------------------------------------------------------------- + +SfxTemplateDialog* SfxApplication::GetTemplateDialog() +{ + if ( pAppData_Impl->pViewFrame ) + { + SfxChildWindow *pChild = pAppData_Impl->pViewFrame->GetChildWindow(SfxTemplateDialogWrapper::GetChildWindowId()); + return pChild ? (SfxTemplateDialog*) pChild->GetWindow() : 0; + } + + return NULL; +} + +//-------------------------------------------------------------------- + +SfxWorkWindow* SfxApplication::GetWorkWindow_Impl(const SfxViewFrame *pFrame) const +{ + if ( pFrame ) + return pFrame->GetFrame().GetWorkWindow_Impl(); + else if ( pAppData_Impl->pViewFrame ) + return pAppData_Impl->pViewFrame->GetFrame().GetWorkWindow_Impl(); + else + return NULL; +} + diff --git a/sfx2/source/appl/appdata.cxx b/sfx2/source/appl/appdata.cxx new file mode 100644 index 000000000000..38ea69280c49 --- /dev/null +++ b/sfx2/source/appl/appdata.cxx @@ -0,0 +1,187 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" +#include <tools/cachestr.hxx> +#include <tools/config.hxx> +#ifndef _INETSTRM_HXX //autogen +#include <svl/inetstrm.hxx> +#endif +#include <svl/stritem.hxx> + +#define _SVSTDARR_STRINGS +#include <svl/svstdarr.hxx> +#include <vos/mutex.hxx> + +#include <vcl/menu.hxx> +#include <vcl/msgbox.hxx> +#include <svl/dateitem.hxx> +#include <vcl/menu.hxx> +#include <vcl/wrkwin.hxx> +#include "comphelper/processfactory.hxx" + +#include <sfx2/viewfrm.hxx> +#include "appdata.hxx" +#include <sfx2/dispatch.hxx> +#include <sfx2/event.hxx> +#include "sfxtypes.hxx" +#include <sfx2/doctempl.hxx> +#include "arrdecl.hxx" +#include <sfx2/docfac.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/request.hxx> +#include "referers.hxx" +#include "app.hrc" +#include "sfxresid.hxx" +#include "objshimp.hxx" +#include <sfx2/appuno.hxx> +#include "imestatuswindow.hxx" +#include "appbaslib.hxx" + +#include <basic/basicmanagerrepository.hxx> +#include <basic/basmgr.hxx> + +using ::basic::BasicManagerRepository; +using ::basic::BasicManagerCreationListener; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::frame::XModel; +using ::com::sun::star::uno::XInterface; + +class SfxBasicManagerCreationListener : public ::basic::BasicManagerCreationListener +{ +private: + SfxAppData_Impl& m_rAppData; + +public: + SfxBasicManagerCreationListener( SfxAppData_Impl& _rAppData ) :m_rAppData( _rAppData ) { } + + virtual void onBasicManagerCreated( const Reference< XModel >& _rxForDocument, BasicManager& _rBasicManager ); +}; + +void SfxBasicManagerCreationListener::onBasicManagerCreated( const Reference< XModel >& _rxForDocument, BasicManager& _rBasicManager ) +{ + if ( _rxForDocument == NULL ) + m_rAppData.OnApplicationBasicManagerCreated( _rBasicManager ); +} + +SfxAppData_Impl::SfxAppData_Impl( SfxApplication* ) : + pDdeService( 0 ), + pDocTopics( 0 ), + pTriggerTopic(0), + pDdeService2(0), + pFactArr(0), + pTopFrames( new SfxFrameArr_Impl ), + pInitLinkList(0), + pMatcher( 0 ), + pLabelResMgr( 0 ), + pAppDispatch(NULL), + pTemplates( 0 ), + pPool(0), + pEventConfig(0), + pDisabledSlotList( 0 ), + pSecureURLs(0), + pSaveOptions( 0 ), + pUndoOptions( 0 ), + pHelpOptions( 0 ), + pProgress(0), + pTemplateCommon( 0 ), + nDocModalMode(0), + nAutoTabPageId(0), + nBasicCallLevel(0), + nRescheduleLocks(0), + nInReschedule(0), + nAsynchronCalls(0), + m_xImeStatusWindow(new sfx2::appl::ImeStatusWindow(comphelper::getProcessServiceFactory())) + , pTbxCtrlFac(0) + , pStbCtrlFac(0) + , pViewFrames(0) + , pObjShells(0) + , pSfxResManager(0) + , pOfaResMgr(0) + , pSimpleResManager(0) + , pBasicManager( new SfxBasicManagerHolder ) + , pBasMgrListener( new SfxBasicManagerCreationListener( *this ) ) + , pViewFrame( 0 ) + , pSlotPool( 0 ) + , pResMgr( 0 ) + , pAppDispat( 0 ) + , pInterfaces( 0 ) + , nDocNo(0) + , nInterfaces( 0 ) + , bDowning( sal_True ) + , bInQuit( sal_False ) + , bInvalidateOnUnlock( sal_False ) + , bODFVersionWarningLater( sal_False ) + +{ + BasicManagerRepository::registerCreationListener( *pBasMgrListener ); +} + +SfxAppData_Impl::~SfxAppData_Impl() +{ + DeInitDDE(); + delete pTopFrames; + delete pSecureURLs; + delete pBasicManager; + + BasicManagerRepository::revokeCreationListener( *pBasMgrListener ); + delete pBasMgrListener; +} + +void SfxAppData_Impl::UpdateApplicationSettings( sal_Bool bDontHide ) +{ + AllSettings aAllSet = Application::GetSettings(); + StyleSettings aStyleSet = aAllSet.GetStyleSettings(); + sal_uInt32 nStyleOptions = aStyleSet.GetOptions(); + if ( bDontHide ) + nStyleOptions &= ~STYLE_OPTION_HIDEDISABLED; + else + nStyleOptions |= STYLE_OPTION_HIDEDISABLED; + aStyleSet.SetOptions( nStyleOptions ); + aAllSet.SetStyleSettings( aStyleSet ); + Application::SetSettings( aAllSet ); +} + +SfxDocumentTemplates* SfxAppData_Impl::GetDocumentTemplates() +{ + if ( !pTemplates ) + pTemplates = new SfxDocumentTemplates; + else + pTemplates->ReInitFromComponent(); + return pTemplates; +} + +void SfxAppData_Impl::OnApplicationBasicManagerCreated( BasicManager& _rBasicManager ) +{ + pBasicManager->reset( &_rBasicManager ); + + // global constants, additionally to the ones already added by createApplicationBasicManager: + // ThisComponent + Reference< XInterface > xCurrentComponent = SfxObjectShell::GetCurrentComponent(); + _rBasicManager.SetGlobalUNOConstant( "ThisComponent", makeAny( xCurrentComponent ) ); +} diff --git a/sfx2/source/appl/appdde.cxx b/sfx2/source/appl/appdde.cxx new file mode 100644 index 000000000000..808731f8bba8 --- /dev/null +++ b/sfx2/source/appl/appdde.cxx @@ -0,0 +1,710 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" +#include <vcl/wrkwin.hxx> +#include <svl/rectitem.hxx> +#include <svl/eitem.hxx> +#include <svl/intitem.hxx> +#include <basic/sbstar.hxx> +#include <svl/stritem.hxx> +#include <svl/svdde.hxx> +#include <sfx2/lnkbase.hxx> +#include <sfx2/linkmgr.hxx> + +#include <tools/urlobj.hxx> +#include <unotools/pathoptions.hxx> +#ifndef GCC +#endif + +#include <sfx2/app.hxx> +#include "appdata.hxx" +#include <sfx2/objsh.hxx> +#include <sfx2/viewfrm.hxx> +#include <sfx2/viewfrm.hxx> +#include <sfx2/dispatch.hxx> +#include "sfxtypes.hxx" +#include <sfx2/sfxsids.hrc> +#include "helper.hxx" +#include <sfx2/docfile.hxx> + +//======================================================================== + +String SfxDdeServiceName_Impl( const String& sIn ) +{ + ByteString sTemp = U2S( sIn ); + ByteString sReturn; + + for ( sal_uInt16 n = sTemp.Len(); n; --n ) + if ( sTemp.Copy( n-1, 1 ).IsAlphaNumericAscii() ) + sReturn += sTemp.GetChar(n-1); + + return S2U( sReturn ); +} + + +class ImplDdeService : public DdeService +{ +public: + ImplDdeService( const String& rNm ) + : DdeService( rNm ) + {} + virtual BOOL MakeTopic( const String& ); + + virtual String Topics(); +// virtual String Formats(); +// virtual String SysItems(); +// virtual String Status(); + + virtual BOOL SysTopicExecute( const String* pStr ); +}; + +class SfxDdeTriggerTopic_Impl : public DdeTopic +{ +public: + SfxDdeTriggerTopic_Impl() + : DdeTopic( DEFINE_CONST_UNICODE("TRIGGER") ) + {} + + virtual BOOL Execute( const String* ); +}; + +class SfxDdeDocTopic_Impl : public DdeTopic +{ +public: + SfxObjectShell* pSh; + DdeData aData; + ::com::sun::star::uno::Sequence< sal_Int8 > aSeq; + + SfxDdeDocTopic_Impl( SfxObjectShell* pShell ) + : DdeTopic( pShell->GetTitle(SFX_TITLE_FULLNAME) ), pSh( pShell ) + {} + + virtual DdeData* Get( ULONG ); + virtual BOOL Put( const DdeData* ); + virtual BOOL Execute( const String* ); + virtual BOOL StartAdviseLoop(); + virtual BOOL MakeItem( const String& rItem ); + +// wird benoetigt? +// virtual void Connect( long n ); +// virtual void Disconnect( long n ); +// virtual void StopAdviseLoop(); + +}; + + +SV_DECL_PTRARR( SfxDdeDocTopics_Impl, SfxDdeDocTopic_Impl *, 4, 4 ) +SV_IMPL_PTRARR( SfxDdeDocTopics_Impl, SfxDdeDocTopic_Impl *) + +//======================================================================== + +BOOL SfxAppEvent_Impl( ApplicationEvent &rAppEvent, + const String &rCmd, const String &rEvent ) + +/* [Beschreibung] + + Pr"uft, ob 'rCmd' das Event 'rEvent' ist (ohne '(') und baut + aus diesem dann ein <ApplicationEvent> zusammen, das per + <Application::AppEvent()> ausgef"uhrt werden kann. Ist 'rCmd' das + angegegeben Event 'rEvent', dann wird TRUE zur"uckgegeben, sonst FALSE. + + + [Beispiel] + + rCmd = "Open(\"d:\doc\doc.sdw\")" + rEvent = "Open" +*/ + +{ + String aEvent( rEvent ); + aEvent += '('; + if ( rCmd.CompareIgnoreCaseToAscii( aEvent, aEvent.Len() ) == COMPARE_EQUAL ) + { + String aData( rCmd ); + aData.Erase( 0, aEvent.Len() ); + if ( aData.Len() > 2 ) + { + // in das ApplicationEvent-Format wandeln + aData.Erase( aData.Len()-1, 1 ); + for ( USHORT n = 0; n < aData.Len(); ++n ) + { + if ( aData.GetChar(n) == 0x0022 ) // " = 22h + for ( ; aData.GetChar(++n) != 0x0022 ; ) + /* empty loop */ ; + else if ( aData.GetChar(n) == 0x0020 ) // SPACE = 20h + aData.SetChar(n, '\n'); + } + aData.EraseAllChars( 0x0022 ); + ApplicationAddress aAddr; + rAppEvent = ApplicationEvent( String(), aAddr, U2S(rEvent), aData ); + return TRUE; + } + } + + return FALSE; +} + +//------------------------------------------------------------------------- + +long SfxApplication::DdeExecute +( + const String& rCmd // in unserer BASIC-Syntax formuliert +) + +/* [Beschreibung] + + Diese Methode kann vom Applikationsentwickler "uberladen werden, + um an seine SfxApplication-Subklasse gerichtete DDE-Kommandos + zu empfangen. + + Die Basisimplementierung versteht die API-Funktionalit"at der + betreffenden SfxApplication-Subklasse in BASIC-Syntax. R"uckgabewerte + k"onnen dabei leider nicht "ubertragen werden. +*/ + +{ + // Print oder Open-Event? + ApplicationEvent aAppEvent; + if ( SfxAppEvent_Impl( aAppEvent, rCmd, DEFINE_CONST_UNICODE("Print") ) || + SfxAppEvent_Impl( aAppEvent, rCmd, DEFINE_CONST_UNICODE("Open") ) ) + GetpApp()->AppEvent( aAppEvent ); + else + { + // alle anderen per BASIC + EnterBasicCall(); + StarBASIC* pBasic = GetBasic(); + DBG_ASSERT( pBasic, "Wo ist mein Basic???" ); + SbxVariable* pRet = pBasic->Execute( rCmd ); + LeaveBasicCall(); + if( !pRet ) + { + SbxBase::ResetError(); + return 0; + } + } + return 1; +} + +//-------------------------------------------------------------------- + +long SfxApplication::DdeGetData +( + const String&, // das anzusprechende Item + const String&, // in: Format + ::com::sun::star::uno::Any& // out: angeforderte Daten +) + +/* [Beschreibung] + + Diese Methode kann vom Applikationsentwickler "uberladen werden, + um an seine SfxApplication-Subklasse gerichtete DDE-Daten-Anforderungen + zu empfangen. + + Die Basisimplementierung liefert keine Daten und gibt 0 zur"uck. +*/ + +{ + return 0; +} + +//-------------------------------------------------------------------- + +long SfxApplication::DdeSetData +( + const String&, // das anzusprechende Item + const String&, // in: Format + const ::com::sun::star::uno::Any& // out: angeforderte Daten +) + +/* [Beschreibung] + + Diese Methode kann vom Applikationsentwickler "uberladen werden, + um an seine SfxApplication-Subklasse gerichtete DDE-Daten + zu empfangen. + + Die Basisimplementierung nimmt keine Daten entgegen und liefert 0 zur"uck. +*/ + +{ + return 0; +} + +//-------------------------------------------------------------------- + +::sfx2::SvLinkSource* SfxApplication::DdeCreateLinkSource +( + const String& // das zu erzeugende Item +) + +/* [Beschreibung] + + Diese Methode kann vom Applikationsentwickler "uberladen werden, + um an seiner SfxApplication-Subklasse einen DDE-Hotlink einzurichten + + Die Basisimplementierung erzeugt keinen und liefert 0 zur"uck. +*/ + +{ + return 0; +} + +//======================================================================== + +long SfxObjectShell::DdeExecute +( + const String& rCmd // in unserer BASIC-Syntax formuliert +) + +/* [Beschreibung] + + Diese Methode kann vom Applikationsentwickler "uberladen werden, + um an seine SfxObjectShell-Subklasse gerichtete DDE-Kommandos + zu empfangen. + + Die Basisimplementierung f"uhrt nichts aus und liefert 0 zur"uck. +*/ + +{ + StarBASIC* pBasic = GetBasic(); + DBG_ASSERT( pBasic, "Wo ist mein Basic???" ) ; + SbxVariable* pRet = pBasic->Execute( rCmd ); + if( !pRet ) + { + SbxBase::ResetError(); + return 0; + } + + return 1; +} + +//-------------------------------------------------------------------- + +long SfxObjectShell::DdeGetData +( + const String&, // das anzusprechende Item + const String&, // in: Format + ::com::sun::star::uno::Any& // out: angeforderte Daten +) + +/* [Beschreibung] + + Diese Methode kann vom Applikationsentwickler "uberladen werden, + um an seine SfxObjectShell-Subklasse gerichtete DDE-Daten-Anforderungen + zu empfangen. + + Die Basisimplementierung liefert keine Daten und gibt 0 zur"uck. +*/ + +{ + return 0; +} + +//-------------------------------------------------------------------- + +long SfxObjectShell::DdeSetData +( + const String&, // das anzusprechende Item + const String&, // in: Format + const ::com::sun::star::uno::Any& // out: angeforderte Daten +) + +/* [Beschreibung] + + Diese Methode kann vom Applikationsentwickler "uberladen werden, + um an seine SfxObjectShell-Subklasse gerichtete DDE-Daten + zu empfangen. + + Die Basisimplementierung nimmt keine Daten entgegen und liefert 0 zur"uck. +*/ + +{ + return 0; +} + +//-------------------------------------------------------------------- +::sfx2::SvLinkSource* SfxObjectShell::DdeCreateLinkSource +( + const String& // das zu erzeugende Item +) + +/* [Beschreibung] + + Diese Methode kann vom Applikationsentwickler "uberladen werden, + um an seiner SfxObjectShell-Subklasse einen DDE-Hotlink einzurichten + + Die Basisimplementierung erzeugt keinen und liefert 0 zur"uck. +*/ + +{ + return 0; +} + +//======================================================================== + +long SfxViewFrame::DdeExecute +( + const String& rCmd // in unserer BASIC-Syntax formuliert +) + +/* [Beschreibung] + + Diese Methode kann vom Applikationsentwickler "uberladen werden, + um an seine SfxViewFrame-Subklasse gerichtete DDE-Kommandos + zu empfangen. + + Die Basisimplementierung versteht die API-Funktionalit"at des + betreffenden SfxViewFrame, der darin dargestellten SfxViewShell und + der betreffenden SfxObjectShell-Subklasse in BASIC-Syntax. + R"uckgabewerte k"onnen dabei leider nicht "ubertragen werden. +*/ + +{ + if ( GetObjectShell() ) + return GetObjectShell()->DdeExecute( rCmd ); + + return 0; +} + +//-------------------------------------------------------------------- + +long SfxViewFrame::DdeGetData +( + const String&, // das anzusprechende Item + const String&, // in: Format + ::com::sun::star::uno::Any& // out: angeforderte Daten +) + +/* [Beschreibung] + + Diese Methode kann vom Applikationsentwickler "uberladen werden, + um an seine SfxViewFrame-Subklasse gerichtete DDE-Daten-Anforderungen + zu empfangen. + + Die Basisimplementierung liefert keine Daten und gibt 0 zur"uck. +*/ + +{ + return 0; +} + +//-------------------------------------------------------------------- + +long SfxViewFrame::DdeSetData +( + const String& , // das anzusprechende Item + const String& , // in: Format + const ::com::sun::star::uno::Any& // out: angeforderte Daten +) + +/* [Beschreibung] + + Diese Methode kann vom Applikationsentwickler "uberladen werden, + um an seine SfxViewFrame-Subklasse gerichtete DDE-Daten + zu empfangen. + + Die Basisimplementierung nimmt keine Daten entgegen und liefert 0 zur"uck. +*/ + +{ + return 0; +} + +//-------------------------------------------------------------------- + +::sfx2::SvLinkSource* SfxViewFrame::DdeCreateLinkSource +( + const String& // das zu erzeugende Item +) + +/* [Beschreibung] + + Diese Methode kann vom Applikationsentwickler "uberladen werden, + um an seiner SfxViewFrame-Subklasse einen DDE-Hotlink einzurichten + + Die Basisimplementierung erzeugt keinen und liefert 0 zur"uck. +*/ + +{ + return 0; +} + +//======================================================================== + +BOOL SfxApplication::InitializeDde() +{ + DBG_ASSERT( !pAppData_Impl->pDdeService, + "Dde kann nicht mehrfach initialisiert werden" ); + + pAppData_Impl->pDdeService = new ImplDdeService( Application::GetAppName() ); + int nError = pAppData_Impl->pDdeService->GetError(); + if( !nError ) + { + pAppData_Impl->pDocTopics = new SfxDdeDocTopics_Impl; + + // wir wollen auf jedenfall RTF unterstuetzen! + pAppData_Impl->pDdeService->AddFormat( FORMAT_RTF ); + + // Config-Pfad als Topic wegen Mehrfachstart + INetURLObject aOfficeLockFile( SvtPathOptions().GetUserConfigPath() ); + aOfficeLockFile.insertName( DEFINE_CONST_UNICODE( "soffice.lck" ) ); + String aService( SfxDdeServiceName_Impl( + aOfficeLockFile.GetMainURL(INetURLObject::DECODE_TO_IURI) ) ); + aService.ToUpperAscii(); + pAppData_Impl->pDdeService2 = new ImplDdeService( aService ); + pAppData_Impl->pTriggerTopic = new SfxDdeTriggerTopic_Impl; + pAppData_Impl->pDdeService2->AddTopic( *pAppData_Impl->pTriggerTopic ); + } + return !nError; +} + +void SfxAppData_Impl::DeInitDDE() +{ + DELETEZ( pTriggerTopic ); + DELETEZ( pDdeService2 ); + DELETEZ( pDocTopics ); + DELETEZ( pDdeService ); +} + +//-------------------------------------------------------------------- + +void SfxApplication::AddDdeTopic( SfxObjectShell* pSh ) +{ + DBG_ASSERT( pAppData_Impl->pDocTopics, "es gibt gar keinen Dde-Service" ); + //OV: Im Serverbetrieb ist DDE abgeklemmt! + if( !pAppData_Impl->pDocTopics ) + return; + + // doppeltes Eintragen verhindern + String sShellNm; + BOOL bFnd = FALSE; + for( USHORT n = pAppData_Impl->pDocTopics->Count(); n; ) + if( (*pAppData_Impl->pDocTopics)[ --n ]->pSh == pSh ) + { + // JP 18.03.96 - Bug 26470 + // falls das Document unbenannt wurde, ist trotzdem ein + // neues Topics anzulegen! + if( !bFnd ) + { + bFnd = TRUE; + (sShellNm = pSh->GetTitle(SFX_TITLE_FULLNAME)).ToLowerAscii(); + } + String sNm( (*pAppData_Impl->pDocTopics)[ n ]->GetName() ); + if( sShellNm == sNm.ToLowerAscii() ) + return ; + } + + const SfxDdeDocTopic_Impl* pTopic = new SfxDdeDocTopic_Impl( pSh ); + pAppData_Impl->pDocTopics->Insert( pTopic, + pAppData_Impl->pDocTopics->Count() ); + pAppData_Impl->pDdeService->AddTopic( *pTopic ); +} + +void SfxApplication::RemoveDdeTopic( SfxObjectShell* pSh ) +{ + DBG_ASSERT( pAppData_Impl->pDocTopics, "es gibt gar keinen Dde-Service" ); + //OV: Im Serverbetrieb ist DDE abgeklemmt! + if( !pAppData_Impl->pDocTopics ) + return; + + SfxDdeDocTopic_Impl* pTopic; + for( USHORT n = pAppData_Impl->pDocTopics->Count(); n; ) + if( ( pTopic = (*pAppData_Impl->pDocTopics)[ --n ])->pSh == pSh ) + { + pAppData_Impl->pDdeService->RemoveTopic( *pTopic ); + pAppData_Impl->pDocTopics->DeleteAndDestroy( n ); + } +} + +const DdeService* SfxApplication::GetDdeService() const +{ + return pAppData_Impl->pDdeService; +} + +DdeService* SfxApplication::GetDdeService() +{ + return pAppData_Impl->pDdeService; +} + +//-------------------------------------------------------------------- + +BOOL ImplDdeService::MakeTopic( const String& rNm ) +{ + // Workaround gegen Event nach unserem Main() unter OS/2 + // passierte wenn man beim Beenden aus dem OffMgr die App neu startet + if ( !Application::IsInExecute() ) + return FALSE; + + // das Topic rNm wird gesucht, haben wir es ? + // erstmal nur ueber die ObjectShells laufen und die mit dem + // Namen heraussuchen: + BOOL bRet = FALSE; + String sNm( rNm ); + sNm.ToLowerAscii(); + TypeId aType( TYPE(SfxObjectShell) ); + SfxObjectShell* pShell = SfxObjectShell::GetFirst( &aType ); + while( pShell ) + { + String sTmp( pShell->GetTitle(SFX_TITLE_FULLNAME) ); + sTmp.ToLowerAscii(); + if( sTmp == sNm ) // die wollen wir haben + { + SFX_APP()->AddDdeTopic( pShell ); + bRet = TRUE; + break; + } + pShell = SfxObjectShell::GetNext( *pShell, &aType ); + } + + if( !bRet ) + { + INetURLObject aWorkPath( SvtPathOptions().GetWorkPath() ); + INetURLObject aFile; + if ( aWorkPath.GetNewAbsURL( rNm, &aFile ) && + SfxContentHelper::IsDocument( aFile.GetMainURL( INetURLObject::NO_DECODE ) ) ) + { + // File vorhanden + + // dann versuche die Datei zu laden: + SfxStringItem aName( SID_FILE_NAME, aFile.GetMainURL( INetURLObject::NO_DECODE ) ); + SfxBoolItem aNewView(SID_OPEN_NEW_VIEW, TRUE); + + SfxBoolItem aSilent(SID_SILENT, TRUE); + SfxDispatcher* pDispatcher = SFX_APP()->GetDispatcher_Impl(); + const SfxPoolItem* pRet = pDispatcher->Execute( SID_OPENDOC, + SFX_CALLMODE_SYNCHRON, + &aName, &aNewView, + &aSilent, 0L ); + + if( pRet && pRet->ISA( SfxViewFrameItem ) && + ((SfxViewFrameItem*)pRet)->GetFrame() && + 0 != ( pShell = ((SfxViewFrameItem*)pRet) + ->GetFrame()->GetObjectShell() ) ) + { + SFX_APP()->AddDdeTopic( pShell ); + bRet = TRUE; + } + } + } + return bRet; +} + +String ImplDdeService::Topics() +{ + String sRet; + if( GetSysTopic() ) + sRet += GetSysTopic()->GetName(); + + TypeId aType( TYPE(SfxObjectShell) ); + SfxObjectShell* pShell = SfxObjectShell::GetFirst( &aType ); + while( pShell ) + { + if( SfxViewFrame::GetFirst( pShell ) ) + { + if( sRet.Len() ) + sRet += '\t'; + sRet += pShell->GetTitle(SFX_TITLE_FULLNAME); + } + pShell = SfxObjectShell::GetNext( *pShell, &aType ); + } + if( sRet.Len() ) + sRet += DEFINE_CONST_UNICODE("\r\n"); + return sRet; +} + +BOOL ImplDdeService::SysTopicExecute( const String* pStr ) +{ + return (BOOL)SFX_APP()->DdeExecute( *pStr ); +} + +//-------------------------------------------------------------------- + +BOOL SfxDdeTriggerTopic_Impl::Execute( const String* ) +{ + return TRUE; +} + +//-------------------------------------------------------------------- +DdeData* SfxDdeDocTopic_Impl::Get( ULONG nFormat ) +{ + String sMimeType( SotExchange::GetFormatMimeType( nFormat )); + ::com::sun::star::uno::Any aValue; + long nRet = pSh->DdeGetData( GetCurItem(), sMimeType, aValue ); + if( nRet && aValue.hasValue() && ( aValue >>= aSeq ) ) + { + aData = DdeData( aSeq.getConstArray(), aSeq.getLength(), nFormat ); + return &aData; + } + aSeq.realloc( 0 ); + return 0; +} + +BOOL SfxDdeDocTopic_Impl::Put( const DdeData* pData ) +{ + aSeq = ::com::sun::star::uno::Sequence< sal_Int8 >( + (sal_Int8*)(const void*)*pData, (long)*pData ); + BOOL bRet; + if( aSeq.getLength() ) + { + ::com::sun::star::uno::Any aValue; + aValue <<= aSeq; + String sMimeType( SotExchange::GetFormatMimeType( pData->GetFormat() )); + bRet = 0 != pSh->DdeSetData( GetCurItem(), sMimeType, aValue ); + } + else + bRet = FALSE; + return bRet; +} + +BOOL SfxDdeDocTopic_Impl::Execute( const String* pStr ) +{ + long nRet = pStr ? pSh->DdeExecute( *pStr ) : 0; + return 0 != nRet; +} + +BOOL SfxDdeDocTopic_Impl::MakeItem( const String& rItem ) +{ + AddItem( DdeItem( rItem ) ); + return TRUE; +} + +BOOL SfxDdeDocTopic_Impl::StartAdviseLoop() +{ + BOOL bRet = FALSE; + ::sfx2::SvLinkSource* pNewObj = pSh->DdeCreateLinkSource( GetCurItem() ); + if( pNewObj ) + { + // dann richten wir auch einen entsprechenden SvBaseLink ein + String sNm, sTmp( Application::GetAppName() ); + ::sfx2::MakeLnkName( sNm, &sTmp, pSh->GetTitle(SFX_TITLE_FULLNAME), GetCurItem() ); + new ::sfx2::SvBaseLink( sNm, OBJECT_DDE_EXTERN, pNewObj ); + bRet = TRUE; + } + return bRet; +} + diff --git a/sfx2/source/appl/appinit.cxx b/sfx2/source/appl/appinit.cxx new file mode 100644 index 000000000000..08023c5414a6 --- /dev/null +++ b/sfx2/source/appl/appinit.cxx @@ -0,0 +1,321 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" + +#include <sfx2/app.hxx> +#include <com/sun/star/frame/XTerminateListener.hpp> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/frame/XDesktop.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> + +#include <svtools/soerr.hxx> +#include <svtools/svtools.hrc> +#include <unotools/saveopt.hxx> +#include <unotools/localisationoptions.hxx> +#include <tools/config.hxx> +#ifndef _SV_RESARY_HXX +#include <tools/resary.hxx> +#endif +#include <tools/urlobj.hxx> +#include <svl/intitem.hxx> +#include <svl/eitem.hxx> +#include <svl/stritem.hxx> +#ifndef _MSGBOX_HXX //autogen +#include <vcl/msgbox.hxx> +#endif +#include <svtools/ehdl.hxx> +#ifndef _UNOTOOLS_PROCESSFACTORY_HXX +#include <comphelper/processfactory.hxx> +#endif +#include <unotools/configmgr.hxx> +#include <rtl/ustrbuf.hxx> +#include <vos/security.hxx> +#include <ucbhelper/configurationkeys.hxx> +#include <unotools/pathoptions.hxx> +#include <unotools/historyoptions.hxx> +#include <unotools/moduleoptions.hxx> +#include <cppuhelper/implbase2.hxx> + +#include <rtl/logfile.hxx> +#include <vcl/edit.hxx> + +#ifndef GCC +#endif + +#include <sfx2/unoctitm.hxx> +#include "app.hrc" +#include "sfxlocal.hrc" +#include "appdata.hxx" +#include "arrdecl.hxx" +#include <sfx2/dispatch.hxx> +#include <sfx2/docfac.hxx> +#include <sfx2/evntconf.hxx> +#include "intro.hxx" +#include <sfx2/macrconf.hxx> +#include <sfx2/mnumgr.hxx> +#include <sfx2/msgpool.hxx> +#include <sfx2/progress.hxx> +#include "sfxhelp.hxx" +#include "sfxresid.hxx" +#include "sfxtypes.hxx" +#include <sfx2/viewsh.hxx> +#include "nochaos.hxx" +#include <sfx2/fcontnr.hxx> +#include "helper.hxx" // SfxContentHelper::Kill() +#include "sfxpicklist.hxx" + +#ifdef UNX +#define stricmp(a,b) strcmp(a,b) +#endif + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star; +namespace css = ::com::sun::star; + +class SfxTerminateListener_Impl : public ::cppu::WeakImplHelper2< XTerminateListener, XServiceInfo > +{ +public: + + // XTerminateListener + virtual void SAL_CALL queryTermination( const EventObject& aEvent ) throw( TerminationVetoException, RuntimeException ); + virtual void SAL_CALL notifyTermination( const EventObject& aEvent ) throw( RuntimeException ); + virtual void SAL_CALL disposing( const EventObject& Source ) throw( RuntimeException ); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() throw (RuntimeException); + virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& sServiceName ) throw (RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw (RuntimeException); +}; + +void SAL_CALL SfxTerminateListener_Impl::disposing( const EventObject& ) throw( RuntimeException ) +{ +} + +void SAL_CALL SfxTerminateListener_Impl::queryTermination( const EventObject& ) throw(TerminationVetoException, RuntimeException ) +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + if ( !SFX_APP()->QueryExit_Impl() ) + throw TerminationVetoException(); +} + +void SAL_CALL SfxTerminateListener_Impl::notifyTermination( const EventObject& aEvent ) throw(RuntimeException ) +{ + static ::rtl::OUString SERVICE_GLOBALEVENTBROADCASTER = ::rtl::OUString::createFromAscii("com.sun.star.frame.GlobalEventBroadcaster"); + static ::rtl::OUString EVENT_QUIT_APP = ::rtl::OUString::createFromAscii("OnCloseApp"); + + Reference< XDesktop > xDesktop( aEvent.Source, UNO_QUERY ); + if( xDesktop.is() == sal_True ) + xDesktop->removeTerminateListener( this ); + + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + utl::ConfigManager::GetConfigManager()->StoreConfigItems(); + SfxApplication* pApp = SFX_APP(); + pApp->Broadcast( SfxSimpleHint( SFX_HINT_DEINITIALIZING ) ); + pApp->Get_Impl()->pAppDispatch->ReleaseAll(); + pApp->Get_Impl()->pAppDispatch->release(); + + css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory(); + css::uno::Reference< css::document::XEventListener > xGlobalBroadcaster(xSMGR->createInstance(SERVICE_GLOBALEVENTBROADCASTER), css::uno::UNO_QUERY); + if (xGlobalBroadcaster.is()) + { + css::document::EventObject aEvent2; + aEvent2.EventName = EVENT_QUIT_APP; + xGlobalBroadcaster->notifyEvent(aEvent2); + } + + //pApp->Deinitialize(); + delete pApp; + Application::Quit(); +} + +::rtl::OUString SAL_CALL SfxTerminateListener_Impl::getImplementationName() throw (RuntimeException) +{ + static const ::rtl::OUString IMPLNAME = ::rtl::OUString::createFromAscii("com.sun.star.comp.sfx2.SfxTerminateListener"); + return IMPLNAME; +} + +::sal_Bool SAL_CALL SfxTerminateListener_Impl::supportsService( const ::rtl::OUString& sServiceName ) throw (RuntimeException) +{ + Sequence< ::rtl::OUString > lNames = getSupportedServiceNames(); + ::sal_Int32 c = lNames.getLength(); + ::sal_Int32 i = 0; + + for (i=0; i<c; ++i) + { + if (lNames[i].equals(sServiceName)) + return sal_True; + } + + return sal_False; +} + +Sequence< ::rtl::OUString > SAL_CALL SfxTerminateListener_Impl::getSupportedServiceNames() throw (RuntimeException) +{ + // Note: That service does not realy exists .-) + // But this implementation is not thought to be registered realy within our service.rdb. + // At least we need the implementation name only to identify these service at the global desktop instance. + // The desktop must know, which listener will terminate the SfxApplication in real ! + // It must call this special listener as last one ... otherwise we shutdown the SfxApplication BEFORE other listener + // can react ... + static const ::rtl::OUString SERVICENAME = ::rtl::OUString::createFromAscii("com.sun.star.frame.TerminateListener"); + Sequence< ::rtl::OUString > lNames(1); + lNames[0] = SERVICENAME; + return lNames; +} + +//==================================================================== + +#define DOSTRING( x ) #x +#define STRING( x ) DOSTRING( x ) + +typedef bool ( *PFunc_getSpecialCharsForEdit)( Window* i_pParent, const Font& i_rFont, String& o_rOutString ); + +//==================================================================== +// Lazy binding of the GetSpecialCharsForEdit function as it resides in +// a library above us. +//==================================================================== + +extern "C" { static void SAL_CALL thisModule() {} } + +String GetSpecialCharsForEdit(Window* pParent, const Font& rFont) +{ + static bool bDetermineFunction = false; + static PFunc_getSpecialCharsForEdit pfunc_getSpecialCharsForEdit = 0; + + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + if ( !bDetermineFunction ) + { + bDetermineFunction = true; + + String sLibName = String::CreateFromAscii( STRING( DLL_NAME ) ); + sLibName.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "sfx" ) ), String( RTL_CONSTASCII_USTRINGPARAM( "cui" ) ) ); + + rtl::OUString aLibName( sLibName ); + oslModule handleMod = osl_loadModuleRelative( + &thisModule, aLibName.pData, 0 ); + + // get symbol + ::rtl::OUString aSymbol( RTL_CONSTASCII_USTRINGPARAM( "GetSpecialCharsForEdit" ) ); + pfunc_getSpecialCharsForEdit = (PFunc_getSpecialCharsForEdit)osl_getFunctionSymbol( handleMod, aSymbol.pData ); + DBG_ASSERT( pfunc_getSpecialCharsForEdit, "GetSpecialCharsForEdit() not found!" ); + } + + String aRet; + if ( pfunc_getSpecialCharsForEdit ) + (*pfunc_getSpecialCharsForEdit)( pParent, rFont, aRet ); + return aRet; +} + +//==================================================================== + +FASTBOOL SfxApplication::Initialize_Impl() +{ + RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mb93783) ::SfxApplication::Initialize_Impl" ); + +#ifdef TLX_VALIDATE + StgIo::SetErrorLink( LINK( this, SfxStorageErrHdl, Error ) ); +#endif + + Reference < XDesktop > xDesktop ( ::comphelper::getProcessServiceFactory()->createInstance( DEFINE_CONST_UNICODE("com.sun.star.frame.Desktop") ), UNO_QUERY ); + if (!xDesktop.is()) + throw RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Couldn't create mandatory desktop service!" )), xDesktop ); + xDesktop->addTerminateListener( new SfxTerminateListener_Impl() ); + + Application::EnableAutoHelpId(); + + pAppData_Impl->pAppDispatch = new SfxStatusDispatcher; + pAppData_Impl->pAppDispatch->acquire(); + + // SV-Look + Help::EnableContextHelp(); + Help::EnableExtHelp(); + + SvtLocalisationOptions aLocalisation; + Application::EnableAutoMnemonic ( aLocalisation.IsAutoMnemonic() ); + Application::SetDialogScaleX ( (short)(aLocalisation.GetDialogScale()) ); + + +#ifdef DBG_UTIL + // Der SimplerErrorHandler dient Debugzwecken. In der Product werden + // nichtgehandelte Fehler durch Errorcode 1 an SFX gegeben. + new SimpleErrorHandler; +#endif + new SfxErrorHandler(RID_ERRHDL, ERRCODE_AREA_TOOLS, ERRCODE_AREA_LIB1); + + new SfxErrorHandler( + RID_SO_ERROR_HANDLER, ERRCODE_AREA_SO, ERRCODE_AREA_SO_END); + new SfxErrorHandler( + RID_BASIC_START, ERRCODE_AREA_SBX, ERRCODE_AREA_SBX_END ); + + // diverse Pointer + SfxPickList::GetOrCreate( SvtHistoryOptions().GetSize( ePICKLIST ) ); + + ///////////////////////////////////////////////////////////////// + + DBG_ASSERT( !pAppData_Impl->pAppDispat, "AppDispatcher already exists" ); + pAppData_Impl->pAppDispat = new SfxDispatcher((SfxDispatcher*)0); + pAppData_Impl->pSlotPool = new SfxSlotPool; + pAppData_Impl->pTbxCtrlFac = new SfxTbxCtrlFactArr_Impl; + pAppData_Impl->pStbCtrlFac = new SfxStbCtrlFactArr_Impl; + pAppData_Impl->pMenuCtrlFac = new SfxMenuCtrlFactArr_Impl; + pAppData_Impl->pViewFrames = new SfxViewFrameArr_Impl; + pAppData_Impl->pViewShells = new SfxViewShellArr_Impl; + pAppData_Impl->pObjShells = new SfxObjectShellArr_Impl; + pAppData_Impl->nInterfaces = SFX_INTERFACE_APP+8; + pAppData_Impl->pInterfaces = new SfxInterface*[pAppData_Impl->nInterfaces]; + memset( pAppData_Impl->pInterfaces, 0, sizeof(SfxInterface*) * pAppData_Impl->nInterfaces ); + + Registrations_Impl(); + + // Subklasse initialisieren + pAppData_Impl->bDowning = sal_False; + Init(); + + // get CHAOS item pool... + pAppData_Impl->pPool = NoChaos::GetItemPool(); + SetPool( pAppData_Impl->pPool ); + + if ( pAppData_Impl->bDowning ) + return sal_False; + + // App-Dispatcher aufbauen + pAppData_Impl->pAppDispat->Push(*this); + pAppData_Impl->pAppDispat->Flush(); + pAppData_Impl->pAppDispat->DoActivate_Impl( sal_True, NULL ); + + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + // Set special characters callback on vcl edit control + Edit::SetGetSpecialCharsFunction(&GetSpecialCharsForEdit); + } + + return sal_True; +} diff --git a/sfx2/source/appl/appmain.cxx b/sfx2/source/appl/appmain.cxx new file mode 100644 index 000000000000..cf097b900b52 --- /dev/null +++ b/sfx2/source/appl/appmain.cxx @@ -0,0 +1,207 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" + +//#define TF_NEWDESKTOP + +#define _SDINTERN_HXX + +#include <stdio.h> +#include <tools/urlobj.hxx> +#include <tools/config.hxx> +#include <svtools/ehdl.hxx> +#include <unotools/startoptions.hxx> +#include <svl/itempool.hxx> +#include <svl/urihelper.hxx> +#include <svtools/helpopt.hxx> +#include <vos/process.hxx> +#include <framework/sfxhelperfunctions.hxx> +#include <rtl/ustring.hxx> +#include <com/sun/star/uno/Exception.hpp> +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/uno/Reference.hxx> + +#include "sfxtypes.hxx" +#include "appdata.hxx" +#include <sfx2/docfac.hxx> +#include <sfx2/app.hxx> +#include "arrdecl.hxx" +#include <sfx2/dispatch.hxx> +#include "sfxresid.hxx" +#include <sfx2/fcontnr.hxx> +#include <sfx2/viewsh.hxx> +#include "intro.hxx" +#include <sfx2/msgpool.hxx> +#include <sfx2/mnumgr.hxx> +#include <sfx2/appuno.hxx> +#include "app.hrc" +#include <sfx2/docfile.hxx> +#include "workwin.hxx" + +#ifdef UNX +#define stricmp(a,b) strcmp(a,b) +#endif + + +//=================================================================== + +DBG_NAME(SfxAppMainNewMenu) +DBG_NAME(SfxAppMainBmkMenu) +DBG_NAME(SfxAppMainWizMenu) +DBG_NAME(SfxAppMainOLEReg) +DBG_NAME(SfxAppMainCHAOSReg) + +//=================================================================== + +#define SFX_TEMPNAMEBASE_DIR "soffice.tmp" +#define SFX_KEY_TEMPNAMEBASE "Temp-Dir" + +//=================================================================== + +#ifdef TF_POOLABLE +static SfxItemInfo __READONLY_DATA aItemInfos[] = +{ + { 0, 0 } +}; +#endif + +//=================================================================== + +TYPEINIT2(SfxApplication,SfxShell,SfxBroadcaster); + +//-------------------------------------------------------------------- +void SfxApplication::Init +( +) + +/* [Beschreibung] + + Diese virtuelle Methode wird vom SFx aus Application:a:Main() gerufen, + bevor Execute() ausgef"uhrt wird und + - das Intro bereits angezeigt ist, + - das Applikationsfenster exisitiert, aber noch hidden ist, + - die Bindings bereits existieren (Controller sind anmeldbar), + - der Ini- und Config-Manager bereits existiert, + - die Standard-Controller bereits exisitieren, + - die SFx-Shells ihre Interfaces bereits registriert haben. + + [Querverweise] + <SfxApplication::Exit()> + <SfxApplication::OpenClients()> +*/ +{ +#ifdef DDE_AVAILABLE +#ifndef DBG_UTIL + InitializeDde(); +#else + if( !InitializeDde() ) + { + ByteString aStr( "Kein DDE-Service moeglich. Fehler: " ); + if( GetDdeService() ) + aStr += GetDdeService()->GetError(); + else + aStr += '?'; + DBG_ASSERT( sal_False, aStr.GetBuffer() ) + } +#endif +#endif +} + +//-------------------------------------------------------------------- + +void SfxApplication::Exit() + +/* [Beschreibung] + + Diese virtuelle Methode wird vom SFx aus Application::Main() gerufen, + nachdem Execute() beendet ist und + - die Konfiguration (SfxConfigManager) bereits gespeichert wurde, + - die Fensterpostionen etc. in den SfxIniManager geschrieben wurden, + - das Applikationsfenster noch existiert, aber hidden ist + - s"amtliche Dokumente und deren Views bereits geschlossen sind. + - Dispatcher, Bindings etc. bereits zerst"ort sind + + [Querverweise] + <SfxApplication::Init(int,char*[])> +*/ + +{ +} + +//--------------------------------------------------------------------------- + +void SfxApplication::PreInit( ) +{ +} + +//--------------------------------------------------------------------------- +bool SfxApplication::InitLabelResMgr( const char* _pLabelPrefix, bool _bException ) +{ + bool bRet = false; + // Label-DLL mit diversen Resourcen fuer OEM-Ver. etc. (Intro, Titel, About) + DBG_ASSERT( _pLabelPrefix, "Wrong initialisation!" ); + if ( _pLabelPrefix ) + { + // versuchen, die Label-DLL zu erzeugen + pAppData_Impl->pLabelResMgr = CreateResManager( _pLabelPrefix ); + + // keine separate Label-DLL vorhanden? + if ( !pAppData_Impl->pLabelResMgr ) + { + if ( _bException ) + { + // maybe corrupted installation + throw (::com::sun::star::uno::RuntimeException( + ::rtl::OUString::createFromAscii("iso resource could not be loaded by SfxApplication"), + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >())); + } + } + else + bRet = true; + } + + return bRet; +} + +void SfxApplication::Main( ) +{ +} + +//------------------------------------------------------------------------- + +SfxFilterMatcher& SfxApplication::GetFilterMatcher() +{ + if( !pAppData_Impl->pMatcher ) + { + pAppData_Impl->pMatcher = new SfxFilterMatcher(); + URIHelper::SetMaybeFileHdl( STATIC_LINK( + pAppData_Impl->pMatcher, SfxFilterMatcher, MaybeFileHdl_Impl ) ); + } + return *pAppData_Impl->pMatcher; +} diff --git a/sfx2/source/appl/appmisc.cxx b/sfx2/source/appl/appmisc.cxx new file mode 100644 index 000000000000..70147e8d9146 --- /dev/null +++ b/sfx2/source/appl/appmisc.cxx @@ -0,0 +1,335 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" +#include <vcl/status.hxx> +#include <vcl/msgbox.hxx> +#ifndef _VOS_PROCESS_HXX //autogen +#include <vos/process.hxx> +#endif +#include <vos/xception.hxx> +#include <svl/whiter.hxx> +#include <svl/stritem.hxx> +#include <svl/intitem.hxx> +#include <svl/eitem.hxx> +#include <svtools/filter.hxx> +#include <unotools/internaloptions.hxx> +#include <unotools/pathoptions.hxx> +#include <com/sun/star/registry/InvalidRegistryException.hpp> +#ifndef _COM_SUN_STAR_BEANS_PropertyValue_HPP_ +#include <com/sun/star/beans/PropertyValue.hpp> +#endif +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/util/XURLTransformer.hpp> +#include <com/sun/star/frame/XFramesSupplier.hpp> +#include <com/sun/star/uno/Reference.h> +#include <tools/config.hxx> +#include <tools/rcid.h> +#include <vos/mutex.hxx> +#ifndef GCC +#endif +#include <unotools/configmgr.hxx> +#include <com/sun/star/frame/XDesktop.hpp> + +#include <unotools/ucbstreamhelper.hxx> +#include <framework/menuconfiguration.hxx> +#include <comphelper/processfactory.hxx> +#include <unotools/localfilehelper.hxx> +#include <unotools/bootstrap.hxx> +#include <unotools/moduleoptions.hxx> +#include <osl/file.hxx> + +#include "sfxresid.hxx" +#include <sfx2/app.hxx> +#include "appdata.hxx" +#include "arrdecl.hxx" +#include <sfx2/tbxctrl.hxx> +#include "stbitem.hxx" +#include <sfx2/mnuitem.hxx> +#include <sfx2/docfac.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/docfilt.hxx> +#include <sfx2/request.hxx> +#include <sfx2/bindings.hxx> +#include <sfx2/dispatch.hxx> +#include "workwin.hxx" +#include "intro.hxx" +#include <sfx2/fcontnr.hxx> +#include "sfxlocal.hrc" +#include <sfx2/sfx.hrc> +#include "app.hrc" +#include <sfx2/templdlg.hxx> +#include <sfx2/module.hxx> +#include <sfx2/msgpool.hxx> +#include <sfx2/viewfrm.hxx> +#include "openflag.hxx" +#include <sfx2/viewsh.hxx> +#include <sfx2/objface.hxx> +#include "helper.hxx" // SfxContentHelper::Kill() + +using namespace ::vos; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::container; + +//=================================================================== + +SV_IMPL_PTRARR( SfxTbxCtrlFactArr_Impl, SfxTbxCtrlFactory* ); +SV_IMPL_PTRARR( SfxStbCtrlFactArr_Impl, SfxStbCtrlFactory* ); +SV_IMPL_PTRARR( SfxMenuCtrlFactArr_Impl, SfxMenuCtrlFactory* ); +SV_IMPL_PTRARR( SfxChildWinFactArr_Impl, SfxChildWinFactory* ); +SV_IMPL_PTRARR( SfxModuleArr_Impl, SfxModule* ); + +//=================================================================== + +#define SfxApplication +#include "sfxslots.hxx" + +class SfxSpecialConfigError_Impl +{ + String aError; + +public: + + SfxSpecialConfigError_Impl( const String& rStr ); + DECL_LINK( TimerHdl, Timer*); +}; + + +SfxSpecialConfigError_Impl::SfxSpecialConfigError_Impl( const String& rStr ) : + aError( rStr ) +{ + Timer *pTimer = new Timer; + pTimer->SetTimeoutHdl( LINK(this, SfxSpecialConfigError_Impl, TimerHdl) ); + pTimer->SetTimeout( 0 ); + pTimer->Start(); +} + +IMPL_LINK( SfxSpecialConfigError_Impl, TimerHdl, Timer*, pTimer ) +{ + delete pTimer; + ErrorBox( 0, WinBits( WB_OK ) , aError ).Execute(); + delete this; + SFX_APP()->GetAppDispatcher_Impl()->Execute( SID_QUITAPP ); + return 0L; +} + +//==================================================================== + +#define SFX_ITEMTYPE_STATBAR 4 + +SFX_IMPL_INTERFACE(SfxApplication,SfxShell,SfxResId(RID_DESKTOP)) +{ + SFX_STATUSBAR_REGISTRATION(SfxResId(SFX_ITEMTYPE_STATBAR)); + SFX_CHILDWINDOW_REGISTRATION(SID_DOCKWIN_0); + SFX_CHILDWINDOW_REGISTRATION(SID_DOCKWIN_1); + SFX_CHILDWINDOW_REGISTRATION(SID_DOCKWIN_2); + SFX_CHILDWINDOW_REGISTRATION(SID_DOCKWIN_3); + SFX_CHILDWINDOW_REGISTRATION(SID_DOCKWIN_4); + SFX_CHILDWINDOW_REGISTRATION(SID_DOCKWIN_5); + SFX_CHILDWINDOW_REGISTRATION(SID_DOCKWIN_6); + SFX_CHILDWINDOW_REGISTRATION(SID_DOCKWIN_7); + SFX_CHILDWINDOW_REGISTRATION(SID_DOCKWIN_8); + SFX_CHILDWINDOW_REGISTRATION(SID_DOCKWIN_9); +} + +//-------------------------------------------------------------------- + +void SfxApplication::InitializeDisplayName_Impl() +{ + SfxAppData_Impl* pAppData = Get_Impl(); + if ( !pAppData->pLabelResMgr ) + return; + + String aTitle = Application::GetDisplayName(); + if ( !aTitle.Len() ) + { + OClearableGuard aGuard( OMutex::getGlobalMutex() ); + + // create version string +/*!!! (pb) don't show a version number at the moment + USHORT nProductVersion = ProductVersion::GetVersion().ToInt32(); + String aVersion( String::CreateFromInt32( nProductVersion / 10 ) ); + aVersion += 0x002E ; // 2Eh ^= '.' + aVersion += ( String::CreateFromInt32( nProductVersion % 10 ) ); +*/ + // load application title + aTitle = String( ResId( RID_APPTITLE, *pAppData->pLabelResMgr ) ); + // merge version into title + aTitle.SearchAndReplaceAscii( "$(VER)", String() /*aVersion*/ ); + + aGuard.clear(); + +#ifdef DBG_UTIL + ::rtl::OUString aDefault; + aTitle += DEFINE_CONST_UNICODE(" ["); + + String aVerId( utl::Bootstrap::getBuildIdData( aDefault )); + aTitle += aVerId; + aTitle += ']'; +#endif + Application::SetDisplayName( aTitle ); + } +} + +//-------------------------------------------------------------------- +SfxProgress* SfxApplication::GetProgress() const + +/* [Beschreibung] + + Liefert den f"ur die gesamte Applikation laufenden SfxProgress + oder 0, falls keiner f"ur die gesamte Applikation l"auft. + + + [Querverweise] + + <SfxProgress::GetActiveProgress(SfxViewFrame*)> + <SfxViewFrame::GetProgress()const> +*/ + +{ + return pAppData_Impl->pProgress; +} + +//------------------------------------------------------------------------ + +SvUShorts* SfxApplication::GetDisabledSlotList_Impl() +{ + sal_Bool bError = sal_False; + SvUShorts* pList = pAppData_Impl->pDisabledSlotList; + if ( !pList ) + { + // Gibt es eine Slotdatei ? + INetURLObject aUserObj( SvtPathOptions().GetUserConfigPath() ); + aUserObj.insertName( DEFINE_CONST_UNICODE( "slots.cfg" ) ); + SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aUserObj.GetMainURL( INetURLObject::NO_DECODE ), STREAM_STD_READ ); + if ( !pStream || pStream->GetError() == ERRCODE_IO_NOTEXISTS ) + { + delete pStream; + INetURLObject aObj( SvtPathOptions().GetConfigPath() ); + aObj.insertName( DEFINE_CONST_UNICODE( "slots.cfg" ) ); + pStream = ::utl::UcbStreamHelper::CreateStream( aObj.GetMainURL( INetURLObject::NO_DECODE ), STREAM_STD_READ ); + } + + BOOL bSlotsEnabled = SvtInternalOptions().SlotCFGEnabled(); + BOOL bSlots = ( pStream && !pStream->GetError() ); + if( bSlots && bSlotsEnabled ) + { + // SlotDatei einlesen + String aTitle; + pStream->ReadByteString(aTitle); + if ( aTitle.CompareToAscii("SfxSlotFile" ) == COMPARE_EQUAL ) + { + sal_uInt16 nCount; + (*pStream) >> nCount; + pList = pAppData_Impl->pDisabledSlotList = + new SvUShorts( nCount < 255 ? (sal_Int8) nCount : 255, 255 ); + + sal_uInt16 nSlot; + for ( sal_uInt16 n=0; n<nCount; n++ ) + { + (*pStream) >> nSlot; + pList->Insert( nSlot, n ); + } + + pStream->ReadByteString(aTitle); + if ( aTitle.CompareToAscii("END" ) != COMPARE_EQUAL || pStream->GetError() ) + { + // Lesen schief gegangen + DELETEZ( pList ); + bError = sal_True; + } + } + else + { + // Streamerkennung fehlgeschlagen + bError = sal_True; + } + } + else if ( bSlots != bSlotsEnabled ) + { + // Wenn kein Slotlist-Eintrag, dann darf auch keine SlotDatei + // vorhanden sein + bError = sal_True; + } + + delete pStream; + } + else if ( pList == (SvUShorts*) -1L ) + { + return NULL; + } + + if ( !pList ) + pAppData_Impl->pDisabledSlotList = (SvUShorts*) -1L; + + if ( bError ) + { + // Wenn ein Sloteintrag vorhanden ist, aber keine oder eine fehlerhafte + // SlotDatei, oder aber eine Slotdatei, aber kein Sloteintrag, dann + // gilt dies als fehlerhafte Konfiguration + new SfxSpecialConfigError_Impl( String( SfxResId( RID_SPECIALCONFIG_ERROR ) ) ); + } + + return pList; +} + + +SfxModule* SfxApplication::GetModule_Impl() +{ + SfxModule* pModule = SfxModule::GetActiveModule(); + if ( !pModule ) + pModule = SfxModule::GetActiveModule( SfxViewFrame::GetFirst( FALSE ) ); + if( pModule ) + return pModule; + else + { + DBG_ERROR( "No module!" ); + return NULL; + } +} + +ISfxTemplateCommon* SfxApplication::GetCurrentTemplateCommon( SfxBindings& rBindings ) +{ + if( pAppData_Impl->pTemplateCommon ) + return pAppData_Impl->pTemplateCommon; + SfxChildWindow *pChild = rBindings.GetWorkWindow_Impl()->GetChildWindow_Impl( + SfxTemplateDialogWrapper::GetChildWindowId() ); + if ( pChild ) + return ((SfxTemplateDialog*) pChild->GetWindow())->GetISfxTemplateCommon(); + return 0; +} + +SfxResourceManager& SfxApplication::GetResourceManager() const { return *pAppData_Impl->pResMgr; } +BOOL SfxApplication::IsDowning() const { return pAppData_Impl->bDowning; } +SfxDispatcher* SfxApplication::GetAppDispatcher_Impl() { return pAppData_Impl->pAppDispat; } +SfxSlotPool& SfxApplication::GetAppSlotPool_Impl() const { return *pAppData_Impl->pSlotPool; } +//SfxOptions& SfxApplication::GetOptions() { return *pAppData_Impl->pOptions; } +//const SfxOptions& SfxApplication::GetOptions() const { return *pAppData_Impl->pOptions; } + diff --git a/sfx2/source/appl/appopen.cxx b/sfx2/source/appl/appopen.cxx new file mode 100644 index 000000000000..89bb5f23f1de --- /dev/null +++ b/sfx2/source/appl/appopen.cxx @@ -0,0 +1,1332 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" +#include <com/sun/star/uno/Reference.h> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/frame/FrameSearchFlag.hpp> +#include <com/sun/star/frame/XComponentLoader.hpp> +#include <com/sun/star/frame/XNotifyingDispatch.hpp> +#include <com/sun/star/frame/XDispatchProvider.hpp> +#include <com/sun/star/util/XCloseable.hpp> +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/frame/XDesktop.hpp> +#include <com/sun/star/frame/DispatchResultState.hpp> +#include <com/sun/star/frame/XDispatchResultListener.hpp> +#include <com/sun/star/util/URL.hpp> +#include <com/sun/star/util/XURLTransformer.hpp> +#include <com/sun/star/system/XSystemShellExecute.hpp> +#include <com/sun/star/document/XTypeDetection.hpp> +#include <com/sun/star/system/SystemShellExecuteFlags.hpp> +#include <com/sun/star/document/MacroExecMode.hpp> +#include <com/sun/star/document/UpdateDocMode.hpp> +#include <com/sun/star/task/ErrorCodeRequest.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/embed/ElementModes.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/uno/Sequence.h> +#include <comphelper/processfactory.hxx> +#include <cppuhelper/implbase1.hxx> +#include <rtl/ustring.hxx> + + +#include <comphelper/storagehelper.hxx> +#include <comphelper/synchronousdispatch.hxx> +#include <comphelper/configurationhelper.hxx> +#include <comphelper/sequenceasvector.hxx> + +#include <vcl/wrkwin.hxx> +#include <svl/intitem.hxx> +#include <vcl/msgbox.hxx> +#include <svl/stritem.hxx> +#include <svl/eitem.hxx> +#include <sfx2/doctempl.hxx> +#include <svtools/sfxecode.hxx> +#include <framework/preventduplicateinteraction.hxx> +#include <svtools/ehdl.hxx> +#include <basic/sbxobj.hxx> +#include <svl/urihelper.hxx> +#include <unotools/localfilehelper.hxx> +#include <unotools/pathoptions.hxx> +#include <unotools/moduleoptions.hxx> +#include <svtools/templdlg.hxx> +#include <osl/file.hxx> +#include <unotools/extendedsecurityoptions.hxx> +#include <comphelper/docpasswordhelper.hxx> +#include <vcl/svapp.hxx> + +#include <vos/mutex.hxx> + +#include <rtl/logfile.hxx> + +#include <sfx2/app.hxx> +#include <sfx2/bindings.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/fcontnr.hxx> +#include <sfx2/new.hxx> +#include <sfx2/objitem.hxx> +#include <sfx2/objsh.hxx> +#include <svl/slstitm.hxx> +#include "objshimp.hxx" +#include "openflag.hxx" +#include <sfx2/passwd.hxx> +#include "referers.hxx" +#include <sfx2/request.hxx> +#include "sfxresid.hxx" +#include <sfx2/viewsh.hxx> +#include "app.hrc" +#include <sfx2/viewfrm.hxx> +#include <sfx2/sfxuno.hxx> +#include <sfx2/objface.hxx> +#include <sfx2/filedlghelper.hxx> +#include <sfx2/docfac.hxx> +#include <sfx2/event.hxx> + +#define _SVSTDARR_STRINGSDTOR +#include <svl/svstdarr.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::system; +using namespace ::com::sun::star::task; +using namespace ::com::sun::star::container; +using namespace ::cppu; +using namespace ::sfx2; + +namespace css = ::com::sun::star; + +//========================================================================= + +class SfxOpenDocStatusListener_Impl : public WeakImplHelper1< XDispatchResultListener > +{ +public: + BOOL bFinished; + BOOL bSuccess; + virtual void SAL_CALL dispatchFinished( const DispatchResultEvent& Event ) throw(RuntimeException); + virtual void SAL_CALL disposing( const EventObject& Source ) throw(RuntimeException); + SfxOpenDocStatusListener_Impl() + : bFinished( FALSE ) + , bSuccess( FALSE ) + {} +}; + +void SAL_CALL SfxOpenDocStatusListener_Impl::dispatchFinished( const DispatchResultEvent& aEvent ) throw(RuntimeException) +{ + bSuccess = ( aEvent.State == DispatchResultState::SUCCESS ); + bFinished = TRUE; +} + +void SAL_CALL SfxOpenDocStatusListener_Impl::disposing( const EventObject& ) throw(RuntimeException) +{ +} + +SfxObjectShellRef SfxApplication::DocAlreadyLoaded +( + const String& rName, // Name des Dokuments mit Pfad + BOOL bSilent, // TRUE: nicht nach neuer Sicht fragen + BOOL bActivate, // soll bestehende Sicht aktiviert werden + BOOL bForbidVisible, + const String* pPostStr +) + +/* [Beschreibung] + + Stellt fest, ob ein Dokument mit dem Namen 'rName' bereits geladen + ist und liefert einen Pointer darauf zu"uck. + + Ist das Dokument noch nicht geladen, wird ein 0-Pointer zur"uckgeliefert. +*/ + +{ + // zu suchenden Namen als URL aufbereiten + INetURLObject aUrlToFind( rName ); + DBG_ASSERT( aUrlToFind.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL" ); + String aPostString; + if ( pPostStr ) + aPostString = *pPostStr; + + // noch offen? + SfxObjectShellRef xDoc; + + if ( !aUrlToFind.HasError() ) + { + // dann bei den normal geoeffneten Docs + if ( !xDoc.Is() ) + { + xDoc = SfxObjectShell::GetFirst( 0, FALSE ); // auch hidden Docs + while( xDoc.Is() ) + { + if ( xDoc->GetMedium() && + xDoc->GetCreateMode() == SFX_CREATE_MODE_STANDARD && + !xDoc->IsAbortingImport() && !xDoc->IsLoading() ) + { + // Vergleiche anhand der URLs + INetURLObject aUrl( xDoc->GetMedium()->GetName() ); + if ( !aUrl.HasError() && aUrl == aUrlToFind && + (!bForbidVisible || !SfxViewFrame::GetFirst( xDoc, TRUE )) && + !xDoc->IsLoading()) + { + break; + } + } + xDoc = SfxObjectShell::GetNext( *xDoc, 0, FALSE ); + } + } + } + + // gefunden? + if ( xDoc.Is() && bActivate ) + { + DBG_ASSERT( + !bForbidVisible, "Unsichtbares kann nicht aktiviert werden" ); + + SfxViewFrame* pFrame; + for( pFrame = SfxViewFrame::GetFirst( xDoc ); + pFrame && !pFrame->IsVisible(); + pFrame = SfxViewFrame::GetNext( *pFrame, xDoc ) ) ; + if ( pFrame ) + { + SfxViewFrame *pCur = SfxViewFrame::Current(); + if ( !bSilent && pFrame == pCur ) + InfoBox( 0, SfxResId(RID_DOCALREADYLOADED_DLG)).Execute(); + if ( bActivate ) + { + pFrame->MakeActive_Impl( TRUE ); + } + } + } + return xDoc; +} + +//==================================================================== + +void SetTemplate_Impl( const String &rFileName, + const String &rLongName, + SfxObjectShell *pDoc) +{ + // write TemplateName to DocumentInfo of document + // TemplateDate stays as default (=current date) + pDoc->ResetFromTemplate( rLongName, rFileName ); +} + +//-------------------------------------------------------------------- + +class SfxDocPasswordVerifier : public ::comphelper::IDocPasswordVerifier +{ +public: + inline explicit SfxDocPasswordVerifier( const Reference< embed::XStorage >& rxStorage ) : + mxStorage( rxStorage ) {} + + virtual ::comphelper::DocPasswordVerifierResult + verifyPassword( const ::rtl::OUString& rPassword ); + +private: + Reference< embed::XStorage > mxStorage; +}; + +::comphelper::DocPasswordVerifierResult SfxDocPasswordVerifier::verifyPassword( const ::rtl::OUString& rPassword ) +{ + ::comphelper::DocPasswordVerifierResult eResult = ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD; + try + { + // check the password + // if the password correct is the stream will be opened successfuly + // and immediatelly closed + ::comphelper::OStorageHelper::SetCommonStoragePassword( mxStorage, rPassword ); + + mxStorage->openStreamElement( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "content.xml" ) ), + embed::ElementModes::READ | embed::ElementModes::NOCREATE ); + + // no exception -> success + eResult = ::comphelper::DocPasswordVerifierResult_OK; + } + catch( const packages::WrongPasswordException& ) + { + eResult = ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD; + } + catch( const uno::Exception& ) + { + // unknown error, do not try to ask again + eResult = ::comphelper::DocPasswordVerifierResult_ABORT; + } + return eResult; +} + +//-------------------------------------------------------------------- + +sal_uInt32 CheckPasswd_Impl +( + //Window *pWin, // Parent des Dialogs + SfxObjectShell* pDoc, + SfxItemPool& /*rPool*/, // Pool, falls ein Set erzeugt werden mus + SfxMedium* pFile // das Medium, dessen Passwort gfs. erfragt werden soll +) + +/* [Beschreibung] + + Zu einem Medium das Passwort erfragen; funktioniert nur, wenn es sich + um einen Storage handelt. + Wenn in der Documentinfo das Passwort-Flag gesetzt ist, wird + das Passwort vom Benutzer per Dialog erfragt und an dem Set + des Mediums gesetzt; das Set wird, wenn nicht vorhanden, erzeugt. +*/ +{ + ULONG nRet = ERRCODE_NONE; + + if( ( !pFile->GetFilter() || pFile->IsStorage() ) ) + { + uno::Reference< embed::XStorage > xStorage = pFile->GetStorage( sal_True ); + if( xStorage.is() ) + { + uno::Reference< beans::XPropertySet > xStorageProps( xStorage, uno::UNO_QUERY ); + if ( xStorageProps.is() ) + { + sal_Bool bIsEncrypted = sal_False; + try { + xStorageProps->getPropertyValue( ::rtl::OUString::createFromAscii("HasEncryptedEntries") ) + >>= bIsEncrypted; + } catch( uno::Exception& ) + { + // TODO/LATER: + // the storage either has no encrypted elements or it's just + // does not allow to detect it, probably it should be implemented laiter + /* + bIsEncrypted = ( aInfo.Load( xStorage ) && aInfo.IsPasswd() ); + */ + } + + if ( bIsEncrypted ) + { + Window* pWin = pDoc ? pDoc->GetDialogParent( pFile ) : NULL; + if ( pWin ) + pWin->Show(); + + nRet = ERRCODE_SFX_CANTGETPASSWD; + + SfxItemSet *pSet = pFile->GetItemSet(); + if( pSet ) + { + Reference< ::com::sun::star::task::XInteractionHandler > xInteractionHandler = pFile->GetInteractionHandler(); + if( xInteractionHandler.is() ) + { + // use the comphelper password helper to request a password + ::rtl::OUString aDocumentName = INetURLObject( pFile->GetOrigURL() ).GetMainURL( INetURLObject::DECODE_WITH_CHARSET ); + SfxDocPasswordVerifier aVerifier( xStorage ); + ::rtl::OUString aPassword = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword( + aVerifier, ::rtl::OUString(), xInteractionHandler, aDocumentName, comphelper::DocPasswordRequestType_STANDARD ); + + if ( aPassword.getLength() > 0 ) + { + pSet->Put( SfxStringItem( SID_PASSWORD, aPassword ) ); + + try + { + // update the version list of the medium using the new password + pFile->GetVersionList(); + } + catch( uno::Exception& ) + { + // TODO/LATER: set the error code + } + + nRet = ERRCODE_NONE; + } + else + nRet = ERRCODE_IO_ABORT; + } + } + } + } + else + { + OSL_ENSURE( sal_False, "A storage must implement XPropertySet interface!" ); + nRet = ERRCODE_SFX_CANTGETPASSWD; + } + } + } + + return nRet; +} + +//-------------------------------------------------------------------- + + +ULONG SfxApplication::LoadTemplate( SfxObjectShellLock& xDoc, const String &rFileName, BOOL bCopy, SfxItemSet* pSet ) +{ + const SfxFilter* pFilter = NULL; + SfxMedium aMedium( rFileName, ( STREAM_READ | STREAM_SHARE_DENYNONE ), FALSE ); + + if ( !aMedium.GetStorage( sal_True ).is() ) + aMedium.GetInStream(); + + if ( aMedium.GetError() ) + { + delete pSet; + return aMedium.GetErrorCode(); + } + + aMedium.UseInteractionHandler( TRUE ); + ULONG nErr = GetFilterMatcher().GuessFilter( aMedium,&pFilter,SFX_FILTER_TEMPLATE, 0 ); + if ( 0 != nErr) + { + delete pSet; + return ERRCODE_SFX_NOTATEMPLATE; + } + + if( !pFilter || !pFilter->IsAllowedAsTemplate() ) + { + delete pSet; + return ERRCODE_SFX_NOTATEMPLATE; + } + + if ( pFilter->GetFilterFlags() & SFX_FILTER_STARONEFILTER ) + { + DBG_ASSERT( !xDoc.Is(), "Sorry, not implemented!" ); + delete pSet; + SfxStringItem aName( SID_FILE_NAME, rFileName ); + SfxStringItem aReferer( SID_REFERER, String::CreateFromAscii("private:user") ); + SfxStringItem aFlags( SID_OPTIONS, String::CreateFromAscii("T") ); + SfxBoolItem aHidden( SID_HIDDEN, TRUE ); + const SfxPoolItem *pRet = GetDispatcher_Impl()->Execute( SID_OPENDOC, SFX_CALLMODE_SYNCHRON, &aName, &aHidden, &aReferer, &aFlags, 0L ); + const SfxObjectItem *pObj = PTR_CAST( SfxObjectItem, pRet ); + if ( pObj ) + xDoc = PTR_CAST( SfxObjectShell, pObj->GetShell() ); + else + { + const SfxViewFrameItem *pView = PTR_CAST( SfxViewFrameItem, pRet ); + if ( pView ) + { + SfxViewFrame *pFrame = pView->GetFrame(); + if ( pFrame ) + xDoc = pFrame->GetObjectShell(); + } + } + + if ( !xDoc.Is() ) + return ERRCODE_SFX_DOLOADFAILED; + } + else + { + if ( !xDoc.Is() ) + xDoc = SfxObjectShell::CreateObject( pFilter->GetServiceName() ); + + SfxMedium *pMedium = new SfxMedium( rFileName, STREAM_STD_READ, FALSE, pFilter, pSet ); + if(!xDoc->DoLoad(pMedium)) + { + ErrCode nErrCode = xDoc->GetErrorCode(); + xDoc->DoClose(); + xDoc.Clear(); + return nErrCode; + } + } + + if( bCopy ) + { + try + { + // TODO: introduce error handling + + uno::Reference< embed::XStorage > xTempStorage = ::comphelper::OStorageHelper::GetTemporaryStorage(); + if( !xTempStorage.is() ) + throw uno::RuntimeException(); + + xDoc->GetStorage()->copyToStorage( xTempStorage ); + +//REMOVE // the following operations should be done in one step +//REMOVE xDoc->DoHandsOff(); + if ( !xDoc->DoSaveCompleted( new SfxMedium( xTempStorage, String() ) ) ) + throw uno::RuntimeException(); + } + catch( uno::Exception& ) + { + xDoc->DoClose(); + xDoc.Clear(); + + // TODO: transfer correct error outside + return ERRCODE_SFX_GENERAL; + } + + SetTemplate_Impl( rFileName, String(), xDoc ); + } + else + SetTemplate_Impl( rFileName, String(), xDoc ); + + xDoc->SetNoName(); + xDoc->InvalidateName(); + xDoc->SetModified(FALSE); + xDoc->ResetError(); + + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > xModel ( xDoc->GetModel(), ::com::sun::star::uno::UNO_QUERY ); + if ( xModel.is() ) + { + SfxItemSet* pNew = xDoc->GetMedium()->GetItemSet()->Clone(); + pNew->ClearItem( SID_PROGRESS_STATUSBAR_CONTROL ); + pNew->ClearItem( SID_FILTER_NAME ); + //pNew->Put( SfxStringItem( SID_FILTER_NAME, xDoc->GetFactory().GetFilter(0)->GetFilterName() ) ); + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aArgs; + TransformItems( SID_OPENDOC, *pNew, aArgs ); + sal_Int32 nLength = aArgs.getLength(); + aArgs.realloc( nLength + 1 ); + aArgs[nLength].Name = DEFINE_CONST_UNICODE("Title"); + aArgs[nLength].Value <<= ::rtl::OUString( xDoc->GetTitle( SFX_TITLE_DETECT ) ); + xModel->attachResource( ::rtl::OUString(), aArgs ); + delete pNew; + } + + return xDoc->GetErrorCode(); +} + +//-------------------------------------------------------------------- + +void SfxApplication::NewDocDirectExec_Impl( SfxRequest& rReq ) +{ + DBG_MEMTEST(); + + SFX_REQUEST_ARG( rReq, pFactoryItem, SfxStringItem, SID_NEWDOCDIRECT, FALSE); + String aFactName; + if ( pFactoryItem ) + aFactName = pFactoryItem->GetValue(); + else + aFactName = SvtModuleOptions().GetDefaultModuleName(); + + + SfxRequest aReq( SID_OPENDOC, SFX_CALLMODE_SYNCHRON, GetPool() ); + String aFact = String::CreateFromAscii("private:factory/"); + aFact += aFactName; + aReq.AppendItem( SfxStringItem( SID_FILE_NAME, aFact ) ); + aReq.AppendItem( SfxFrameItem( SID_DOCFRAME, GetFrame() ) ); + aReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii( "_default" ) ) ); + + // TODO/LATER: Should the other arguments be transfered as well? + SFX_REQUEST_ARG( rReq, pDefaultPathItem, SfxStringItem, SID_DEFAULTFILEPATH, FALSE); + if ( pDefaultPathItem ) + aReq.AppendItem( *pDefaultPathItem ); + SFX_REQUEST_ARG( rReq, pDefaultNameItem, SfxStringItem, SID_DEFAULTFILENAME, FALSE); + if ( pDefaultNameItem ) + aReq.AppendItem( *pDefaultNameItem ); + + SFX_APP()->ExecuteSlot( aReq ); + const SfxViewFrameItem* pItem = PTR_CAST( SfxViewFrameItem, aReq.GetReturnValue() ); + if ( pItem ) + rReq.SetReturnValue( SfxFrameItem( 0, pItem->GetFrame() ) ); +} + +//-------------------------------------------------------------------- + +void SfxApplication::NewDocExec_Impl( SfxRequest& rReq ) +{ + DBG_MEMTEST(); + + // keine Parameter vom BASIC nur Factory angegeben? + SFX_REQUEST_ARG(rReq, pTemplNameItem, SfxStringItem, SID_TEMPLATE_NAME, FALSE); + SFX_REQUEST_ARG(rReq, pTemplFileNameItem, SfxStringItem, SID_FILE_NAME, FALSE); + SFX_REQUEST_ARG(rReq, pTemplRegionNameItem, SfxStringItem, SID_TEMPLATE_REGIONNAME, FALSE); + + SfxObjectShellLock xDoc; + + String aTemplateRegion, aTemplateName, aTemplateFileName; + BOOL bDirect = FALSE; // "uber FileName anstelle Region/Template + SfxErrorContext aEc(ERRCTX_SFX_NEWDOC); + if ( !pTemplNameItem && !pTemplFileNameItem ) + { + Window* pTopWin = GetTopWindow(); + SvtDocumentTemplateDialog* pDocTemplDlg = new SvtDocumentTemplateDialog( NULL ); + int nRet = pDocTemplDlg->Execute(); + sal_Bool bNewWin = sal_False; + if ( nRet == RET_OK ) + { + rReq.Done(); + if ( pTopWin != GetTopWindow() ) + { + // the dialogue opens a document -> a new TopWindow appears + pTopWin = GetTopWindow(); + bNewWin = sal_True; + } + } + + delete pDocTemplDlg; + if ( bNewWin && pTopWin ) + // after the destruction of the dialogue its parent comes to top, + // but we want that the new document is on top + pTopWin->ToTop(); + + return; + } + else + { + // Template-Name + if ( pTemplNameItem ) + aTemplateName = pTemplNameItem->GetValue(); + + // Template-Region + if ( pTemplRegionNameItem ) + aTemplateRegion = pTemplRegionNameItem->GetValue(); + + // Template-File-Name + if ( pTemplFileNameItem ) + { + aTemplateFileName = pTemplFileNameItem->GetValue(); + bDirect = TRUE; + } + } + + ULONG lErr = 0; + SfxItemSet* pSet = new SfxAllItemSet( GetPool() ); + pSet->Put( SfxBoolItem( SID_TEMPLATE, TRUE ) ); + if ( !bDirect ) + { + SfxDocumentTemplates aTmpFac; + if( !aTemplateFileName.Len() ) + aTmpFac.GetFull( aTemplateRegion, aTemplateName, aTemplateFileName ); + + if( !aTemplateFileName.Len() ) + lErr = ERRCODE_SFX_TEMPLATENOTFOUND; + } + + INetURLObject aObj( aTemplateFileName ); + SfxErrorContext aEC( ERRCTX_SFX_LOADTEMPLATE, aObj.PathToFileName() ); + + if ( lErr != ERRCODE_NONE ) + { + ULONG lFatalErr = ERRCODE_TOERROR(lErr); + if ( lFatalErr ) + ErrorHandler::HandleError(lErr); + } + else + { + SfxCallMode eMode = SFX_CALLMODE_SYNCHRON; + + const SfxPoolItem *pRet=0; + SfxStringItem aReferer( SID_REFERER, DEFINE_CONST_UNICODE("private:user") ); + SfxStringItem aTarget( SID_TARGETNAME, DEFINE_CONST_UNICODE("_default") ); + if ( aTemplateFileName.Len() ) + { + DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Illegal URL!" ); + + SfxStringItem aName( SID_FILE_NAME, aObj.GetMainURL( INetURLObject::NO_DECODE ) ); + SfxStringItem aTemplName( SID_TEMPLATE_NAME, aTemplateName ); + SfxStringItem aTemplRegionName( SID_TEMPLATE_REGIONNAME, aTemplateRegion ); + pRet = GetDispatcher_Impl()->Execute( SID_OPENDOC, eMode, &aName, &aTarget, &aReferer, &aTemplName, &aTemplRegionName, 0L ); + } + else + { + SfxStringItem aName( SID_FILE_NAME, DEFINE_CONST_UNICODE("private:factory") ); + pRet = GetDispatcher_Impl()->Execute( SID_OPENDOC, eMode, &aName, &aTarget, &aReferer, 0L ); + } + + if ( pRet ) + rReq.SetReturnValue( *pRet ); + } +} + +//--------------------------------------------------------------------------- + +void SfxApplication::OpenDocExec_Impl( SfxRequest& rReq ) +{ + DBG_MEMTEST(); + + USHORT nSID = rReq.GetSlot(); + SFX_REQUEST_ARG( rReq, pFileNameItem, SfxStringItem, SID_FILE_NAME, FALSE ); + if ( pFileNameItem ) + { + String aCommand( pFileNameItem->GetValue() ); + const SfxSlot* pSlot = GetInterface()->GetSlot( aCommand ); + if ( pSlot ) + { + pFileNameItem = NULL; + } + else + { + sal_Int32 nIndex = aCommand.SearchAscii("slot:"); + if ( !nIndex ) + { + USHORT nSlotId = (USHORT) String( aCommand, 5, aCommand.Len()-5 ).ToInt32(); + if ( nSlotId == SID_OPENDOC ) + pFileNameItem = NULL; + } + } + } + + if ( !pFileNameItem ) + { + // get FileName from dialog + SvStringsDtor* pURLList = NULL; + String aFilter; + SfxItemSet* pSet = NULL; + String aPath; + SFX_REQUEST_ARG( rReq, pFolderNameItem, SfxStringItem, SID_PATH, FALSE ); + if ( pFolderNameItem ) + aPath = pFolderNameItem->GetValue(); + else if ( nSID == SID_OPENTEMPLATE ) + { + aPath = SvtPathOptions().GetTemplatePath(); + sal_Int32 nTokenCount = aPath.GetTokenCount( ';' ); + aPath = aPath.GetToken( + sal::static_int_cast< xub_StrLen >( + nTokenCount ? ( nTokenCount - 1 ) : 0 ), + ';' ); + } + + sal_Int16 nDialog = SFX2_IMPL_DIALOG_CONFIG; + SFX_REQUEST_ARG( rReq, pSystemDialogItem, SfxBoolItem, SID_FILE_DIALOG, FALSE ); + if ( pSystemDialogItem ) + nDialog = pSystemDialogItem->GetValue() ? SFX2_IMPL_DIALOG_SYSTEM : SFX2_IMPL_DIALOG_OOO; + + String sStandardDir; + + SFX_REQUEST_ARG( rReq, pStandardDirItem, SfxStringItem, SID_STANDARD_DIR, FALSE ); + if ( pStandardDirItem ) + sStandardDir = pStandardDirItem->GetValue(); + + ::com::sun::star::uno::Sequence< ::rtl::OUString > aBlackList; + + SFX_REQUEST_ARG( rReq, pBlackListItem, SfxStringListItem, SID_BLACK_LIST, FALSE ); + if ( pBlackListItem ) + pBlackListItem->GetStringList( aBlackList ); + + + ULONG nErr = sfx2::FileOpenDialog_Impl( + WB_OPEN | SFXWB_MULTISELECTION | SFXWB_SHOWVERSIONS, String(), pURLList, aFilter, pSet, &aPath, nDialog, sStandardDir, aBlackList ); + + if ( nErr == ERRCODE_ABORT ) + { + delete pURLList; + return; + } + + rReq.SetArgs( *(SfxAllItemSet*)pSet ); + if (aFilter.Len() >0 ) + rReq.AppendItem( SfxStringItem( SID_FILTER_NAME, aFilter ) ); + rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_default") ) ); + rReq.AppendItem( SfxStringItem( SID_REFERER, String::CreateFromAscii(SFX_REFERER_USER) ) ); + delete pSet; + + if ( pURLList->Count() ) + { + if ( nSID == SID_OPENTEMPLATE ) + rReq.AppendItem( SfxBoolItem( SID_TEMPLATE, FALSE ) ); + + // This helper wraps an existing (or may new created InteractionHandler) + // intercept all incoming interactions and provide usefull informations + // later if the following transaction was finished. + + ::framework::PreventDuplicateInteraction* pHandler = new ::framework::PreventDuplicateInteraction(::comphelper::getProcessServiceFactory()); + css::uno::Reference< css::task::XInteractionHandler > xHandler (static_cast< css::task::XInteractionHandler* >(pHandler), css::uno::UNO_QUERY); + css::uno::Reference< css::task::XInteractionHandler > xWrappedHandler; + + // wrap existing handler or create new UUI handler + SFX_REQUEST_ARG(rReq, pInteractionItem, SfxUnoAnyItem, SID_INTERACTIONHANDLER, FALSE); + if (pInteractionItem) + { + pInteractionItem->GetValue() >>= xWrappedHandler; + rReq.RemoveItem( SID_INTERACTIONHANDLER ); + } + if (xWrappedHandler.is()) + pHandler->setHandler(xWrappedHandler); + else + pHandler->useDefaultUUIHandler(); + rReq.AppendItem( SfxUnoAnyItem(SID_INTERACTIONHANDLER,::com::sun::star::uno::makeAny(xHandler)) ); + + // define rules for this handler + css::uno::Type aInteraction = ::getCppuType(static_cast< css::task::ErrorCodeRequest* >(0)); + ::framework::PreventDuplicateInteraction::InteractionInfo aRule (aInteraction, 1); + pHandler->addInteractionRule(aRule); + + for ( USHORT i = 0; i < pURLList->Count(); ++i ) + { + String aURL = *(pURLList->GetObject(i)); + rReq.RemoveItem( SID_FILE_NAME ); + rReq.AppendItem( SfxStringItem( SID_FILE_NAME, aURL ) ); + + // synchron ausf"uhren, damit beim Reschedulen nicht schon das n"achste Dokument + // geladen wird + // TODO/LATER: use URLList argument and always remove one document after another, each step in asychronous execution, until finished + // but only if reschedule is a problem + GetDispatcher_Impl()->Execute( SID_OPENDOC, SFX_CALLMODE_SYNCHRON, *rReq.GetArgs() ); + + // check for special interaction "NO MORE DOCUMENTS ALLOWED" and + // break loop then. Otherwise we risk showing the same interaction more then once. + if ( pHandler->getInteractionInfo(aInteraction, &aRule) ) + { + if (aRule.m_nCallCount > 0) + { + if (aRule.m_xRequest.is()) + { + css::task::ErrorCodeRequest aRequest; + if (aRule.m_xRequest->getRequest() >>= aRequest) + { + if (aRequest.ErrCode == + sal::static_int_cast< sal_Int32 >( + ERRCODE_SFX_NOMOREDOCUMENTSALLOWED)) + break; + } + } + } + } + } + + delete pURLList; + return; + } + delete pURLList; + } + + if ( !rReq.IsSynchronCall() ) + { + // now check wether a stream is already there + // if not: download it in a thread and restart the call + // return; + } + + BOOL bHyperlinkUsed = FALSE; + + if ( SID_OPENURL == nSID ) + { + // SID_OPENURL does the same as SID_OPENDOC! + rReq.SetSlot( SID_OPENDOC ); + nSID = SID_OPENDOC; + } + else if ( nSID == SID_OPENTEMPLATE ) + { + rReq.AppendItem( SfxBoolItem( SID_TEMPLATE, FALSE ) ); + } + // pass URL to OS by using ShellExecuter or open it internal + // if it seams to be an own format. + /* Attention! + There exist two possibilities to open hyperlinks: + a) using SID_OPENHYPERLINK (new) + b) using SID_BROWSE (old) + */ + else if ( nSID == SID_OPENHYPERLINK ) + { + rReq.SetSlot( SID_OPENDOC ); + nSID = SID_OPENDOC; + bHyperlinkUsed = TRUE; + } + + // no else here! It's optional ... + if (!bHyperlinkUsed) + { + SFX_REQUEST_ARG(rReq, pHyperLinkUsedItem, SfxBoolItem, SID_BROWSE, FALSE); + if ( pHyperLinkUsedItem ) + bHyperlinkUsed = pHyperLinkUsedItem->GetValue(); + // no "official" item, so remove it from ItemSet before using UNO-API + rReq.RemoveItem( SID_BROWSE ); + } + + SFX_REQUEST_ARG( rReq, pFileName, SfxStringItem, SID_FILE_NAME, FALSE ); + String aFileName = pFileName->GetValue(); + + String aReferer; + SFX_REQUEST_ARG( rReq, pRefererItem, SfxStringItem, SID_REFERER, FALSE ); + if ( pRefererItem ) + aReferer = pRefererItem->GetValue(); + + SFX_REQUEST_ARG( rReq, pFileFlagsItem, SfxStringItem, SID_OPTIONS, FALSE); + if ( pFileFlagsItem ) + { + String aFileFlags = pFileFlagsItem->GetValue(); + aFileFlags.ToUpperAscii(); + if ( STRING_NOTFOUND != aFileFlags.Search( 0x0054 ) ) // T = 54h + { + rReq.RemoveItem( SID_TEMPLATE ); + rReq.AppendItem( SfxBoolItem( SID_TEMPLATE, TRUE ) ); + } + + if ( STRING_NOTFOUND != aFileFlags.Search( 0x0048 ) ) // H = 48h + { + rReq.RemoveItem( SID_HIDDEN ); + rReq.AppendItem( SfxBoolItem( SID_HIDDEN, TRUE ) ); + } + + if ( STRING_NOTFOUND != aFileFlags.Search( 0x0052 ) ) // R = 52h + { + rReq.RemoveItem( SID_DOC_READONLY ); + rReq.AppendItem( SfxBoolItem( SID_DOC_READONLY, TRUE ) ); + } + + if ( STRING_NOTFOUND != aFileFlags.Search( 0x0042 ) ) // B = 42h + { + rReq.RemoveItem( SID_PREVIEW ); + rReq.AppendItem( SfxBoolItem( SID_PREVIEW, TRUE ) ); + } + + if ( STRING_NOTFOUND != aFileFlags.Search( 0x0053 ) ) // S = 53h + { + // not supported anymore + //rReq.RemoveItem( SID_SILENT ); + //rReq.AppendItem( SfxBoolItem( SID_SILENT, TRUE ) ); + } + + rReq.RemoveItem( SID_OPTIONS ); + } + + // Mark without URL cannot be handled by hyperlink code + if ( bHyperlinkUsed && aFileName.Len() && aFileName.GetChar(0) != '#' ) + { + Reference< ::com::sun::star::document::XTypeDetection > xTypeDetection( + ::comphelper::getProcessServiceFactory()->createInstance( + ::rtl::OUString::createFromAscii( "com.sun.star.document.TypeDetection" )), + UNO_QUERY ); + if ( xTypeDetection.is() ) + { + URL aURL; + ::rtl::OUString aTypeName; + + aURL.Complete = aFileName; + Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance( + ::rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" )), UNO_QUERY ); + xTrans->parseStrict( aURL ); + + INetProtocol aINetProtocol = INetURLObject( aURL.Complete ).GetProtocol(); + SvtExtendedSecurityOptions aExtendedSecurityOptions; + SvtExtendedSecurityOptions::OpenHyperlinkMode eMode = aExtendedSecurityOptions.GetOpenHyperlinkMode(); + if ( eMode == SvtExtendedSecurityOptions::OPEN_WITHSECURITYCHECK ) + { + if ( aINetProtocol == INET_PROT_FILE ) + { +/*!!! pb: #i49802# no security warning any longer + // Check if file URL is a directory. This is not insecure! + osl::Directory aDir( aURL.Main ); + sal_Bool bIsDir = ( aDir.open() == osl::Directory::E_None ); + + if ( !bIsDir && !aExtendedSecurityOptions.IsSecureHyperlink( aURL.Complete ) ) + { + // Security check for local files depending on the extension + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window *pWindow = SFX_APP()->GetTopWindow(); + + String aSecurityWarningBoxTitle( SfxResId( RID_SECURITY_WARNING_TITLE )); + WarningBox aSecurityWarningBox( pWindow, SfxResId( RID_SECURITY_WARNING_HYPERLINK )); + aSecurityWarningBox.SetText( aSecurityWarningBoxTitle ); + + // Replace %s with the real file name + String aMsgText = aSecurityWarningBox.GetMessText(); + String aMainURL( aURL.Main ); + String aFileName; + + utl::LocalFileHelper::ConvertURLToPhysicalName( aMainURL, aFileName ); + aMsgText.SearchAndReplaceAscii( "%s", aFileName ); + aSecurityWarningBox.SetMessText( aMsgText ); + + if( aSecurityWarningBox.Execute() == RET_NO ) + return; + } +*/ + } + } + else if ( eMode == SvtExtendedSecurityOptions::OPEN_NEVER && aINetProtocol != INET_PROT_VND_SUN_STAR_HELP ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window *pWindow = SFX_APP()->GetTopWindow(); + + String aSecurityWarningBoxTitle( SfxResId( RID_SECURITY_WARNING_TITLE )); + WarningBox aSecurityWarningBox( pWindow, SfxResId( RID_SECURITY_WARNING_NO_HYPERLINKS )); + aSecurityWarningBox.SetText( aSecurityWarningBoxTitle ); + aSecurityWarningBox.Execute(); + return; + } + + aTypeName = xTypeDetection->queryTypeByURL( aURL.Main ); + SfxFilterMatcher& rMatcher = SFX_APP()->GetFilterMatcher(); + const SfxFilter* pFilter = rMatcher.GetFilter4EA( aTypeName ); + if ( !pFilter || !( pFilter->IsOwnFormat() )) + { + // hyperlink does not link to own type => special handling (http, ftp) browser and (other external protocols) OS + Reference< XSystemShellExecute > xSystemShellExecute( ::comphelper::getProcessServiceFactory()->createInstance( + ::rtl::OUString::createFromAscii( "com.sun.star.system.SystemShellExecute" )), UNO_QUERY ); + if ( xSystemShellExecute.is() ) + { + if ( aINetProtocol == INET_PROT_MAILTO ) + { + // don't dispatch mailto hyperlink to desktop dispatcher + rReq.RemoveItem( SID_TARGETNAME ); + rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_self") ) ); + } + else if ( aINetProtocol == INET_PROT_FTP || + aINetProtocol == INET_PROT_HTTP || + aINetProtocol == INET_PROT_HTTPS ) + { + try + { + // start browser + ::rtl::OUString aURLString( aURL.Complete ); + xSystemShellExecute->execute( aURLString, ::rtl::OUString(), SystemShellExecuteFlags::DEFAULTS ); + } + catch ( ::com::sun::star::lang::IllegalArgumentException& ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window *pWindow = SFX_APP()->GetTopWindow(); + ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute(); + } + catch ( ::com::sun::star::system::SystemShellExecuteException& ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window *pWindow = SFX_APP()->GetTopWindow(); + ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute(); + } + + return; + } + else + { + // check for "internal" protocols that should not be forwarded to the system + Sequence < ::rtl::OUString > aProtocols(2); + + // add special protocols that always should be treated as internal + aProtocols[0] = ::rtl::OUString::createFromAscii("private:*"); + aProtocols[1] = ::rtl::OUString::createFromAscii("vnd.sun.star.*"); + + try + { + // get registered protocol handlers from configuration + Reference < XNameAccess > xAccess( ::comphelper::ConfigurationHelper::openConfig( ::comphelper::getProcessServiceFactory(), + ::rtl::OUString::createFromAscii("org.openoffice.Office.ProtocolHandler/HandlerSet"), ::comphelper::ConfigurationHelper::E_READONLY ), UNO_QUERY ); + if ( xAccess.is() ) + { + Sequence < ::rtl::OUString > aNames = xAccess->getElementNames(); + for ( sal_Int32 nName = 0; nName < aNames.getLength(); nName ++) + { + Reference < XPropertySet > xSet; + Any aRet = xAccess->getByName( aNames[nName] ); + aRet >>= xSet; + if ( xSet.is() ) + { + // copy protocols + aRet = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("Protocols") ); + Sequence < ::rtl::OUString > aTmp; + aRet >>= aTmp; + + // todo: add operator+= to SequenceAsVector class and use SequenceAsVector for aProtocols + sal_Int32 nLength = aProtocols.getLength(); + aProtocols.realloc( nLength+aTmp.getLength() ); + for ( sal_Int32 n=0; n<aTmp.getLength(); n++ ) + aProtocols[(++nLength)-1] = aTmp[n]; + } + } + } + } + catch ( Exception& ) + { + // registered protocols could not be read + } + + sal_Bool bFound = sal_False; + for ( sal_Int32 nProt=0; nProt<aProtocols.getLength(); nProt++ ) + { + WildCard aPattern(aProtocols[nProt]); + if ( aPattern.Matches( aURL.Complete ) ) + { + bFound = sal_True; + break; + } + } + + if ( !bFound ) + { + BOOL bLoadInternal = FALSE; + + // security reservation: => we have to check the referer before executing + if (SFX_APP()->IsSecureURL(rtl::OUString(), &aReferer)) + { + ::rtl::OUString aURLString( aURL.Complete ); + + try + { + // give os this file + xSystemShellExecute->execute( aURLString, ::rtl::OUString(), SystemShellExecuteFlags::DEFAULTS ); + } + catch ( ::com::sun::star::lang::IllegalArgumentException& ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window *pWindow = SFX_APP()->GetTopWindow(); + ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute(); + } + catch ( ::com::sun::star::system::SystemShellExecuteException& ) + { + if ( !pFilter ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window *pWindow = SFX_APP()->GetTopWindow(); + ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute(); + } + else + { + rReq.RemoveItem( SID_TARGETNAME ); + rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_default") ) ); + bLoadInternal = TRUE; + } + } + } + else + { + SfxErrorContext aCtx( ERRCTX_SFX_OPENDOC, aURL.Complete ); + ErrorHandler::HandleError( ERRCODE_IO_ACCESSDENIED ); + } + + if ( !bLoadInternal ) + return; + } + } + } + } + else + { + // hyperlink document must be loaded into a new frame + rReq.RemoveItem( SID_TARGETNAME ); + rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_default") ) ); + } + } + } + + if ( !SFX_APP()->IsSecureURL( INetURLObject(aFileName), &aReferer ) ) + { + SfxErrorContext aCtx( ERRCTX_SFX_OPENDOC, aFileName ); + ErrorHandler::HandleError( ERRCODE_IO_ACCESSDENIED ); + return; + } + + SfxFrame* pTargetFrame = NULL; + Reference< XFrame > xTargetFrame; + + SFX_REQUEST_ARG(rReq, pFrameItem, SfxFrameItem, SID_DOCFRAME, FALSE); + if ( pFrameItem ) + pTargetFrame = pFrameItem->GetFrame(); + + if ( !pTargetFrame ) + { + SFX_REQUEST_ARG(rReq, pUnoFrameItem, SfxUnoFrameItem, SID_FILLFRAME, FALSE); + if ( pUnoFrameItem ) + xTargetFrame = pUnoFrameItem->GetFrame(); + } + + if ( !pTargetFrame && !xTargetFrame.is() && SfxViewFrame::Current() ) + pTargetFrame = &SfxViewFrame::Current()->GetFrame(); + + // check if caller has set a callback + SFX_REQUEST_ARG(rReq, pLinkItem, SfxLinkItem, SID_DONELINK, FALSE ); + + // remove from Itemset, because it confuses the parameter transformation + if ( pLinkItem ) + pLinkItem = (SfxLinkItem*) pLinkItem->Clone(); + + rReq.RemoveItem( SID_DONELINK ); + + // check if the view must be hidden + BOOL bHidden = FALSE; + SFX_REQUEST_ARG(rReq, pHidItem, SfxBoolItem, SID_HIDDEN, FALSE); + if ( pHidItem ) + bHidden = pHidItem->GetValue(); + + // This request is a UI call. We have to set the right values inside the MediaDescriptor + // for: InteractionHandler, StatusIndicator, MacroExecutionMode and DocTemplate. + // But we have to look for already existing values or for real hidden requests. + SFX_REQUEST_ARG(rReq, pPreviewItem, SfxBoolItem, SID_PREVIEW, FALSE); + if (!bHidden && ( !pPreviewItem || !pPreviewItem->GetValue() ) ) + { + SFX_REQUEST_ARG(rReq, pInteractionItem, SfxUnoAnyItem, SID_INTERACTIONHANDLER, FALSE); + SFX_REQUEST_ARG(rReq, pMacroExecItem , SfxUInt16Item, SID_MACROEXECMODE , FALSE); + SFX_REQUEST_ARG(rReq, pDocTemplateItem, SfxUInt16Item, SID_UPDATEDOCMODE , FALSE); + + if (!pInteractionItem) + { + Reference < ::com::sun::star::task::XInteractionHandler > xHdl( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.comp.uui.UUIInteractionHandler")), UNO_QUERY ); + if (xHdl.is()) + rReq.AppendItem( SfxUnoAnyItem(SID_INTERACTIONHANDLER,::com::sun::star::uno::makeAny(xHdl)) ); + } + if (!pMacroExecItem) + rReq.AppendItem( SfxUInt16Item(SID_MACROEXECMODE,::com::sun::star::document::MacroExecMode::USE_CONFIG) ); + if (!pDocTemplateItem) + rReq.AppendItem( SfxUInt16Item(SID_UPDATEDOCMODE,::com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG) ); + } + + // extract target name + ::rtl::OUString aTarget; + SFX_REQUEST_ARG(rReq, pTargetItem, SfxStringItem, SID_TARGETNAME, FALSE); + if ( pTargetItem ) + aTarget = pTargetItem->GetValue(); + else + { + SFX_REQUEST_ARG( rReq, pNewViewItem, SfxBoolItem, SID_OPEN_NEW_VIEW, FALSE ); + if ( pNewViewItem && pNewViewItem->GetValue() ) + aTarget = String::CreateFromAscii("_blank" ); + } + + if ( bHidden ) + { + aTarget = String::CreateFromAscii("_blank"); + DBG_ASSERT( rReq.IsSynchronCall() || pLinkItem, "Hidden load process must be done synchronously!" ); + } + + Reference < XController > xController; +// if ( ( !bIsBlankTarget && pFrame ) || pLinkItem || !rReq.IsSynchronCall() ) +// { + // if a frame is given, it must be used for the starting point of the targetting mechanism + // this code is also used if asynchronous loading is possible, because loadComponent always is synchron + if ( !xTargetFrame.is() ) + { + if ( pTargetFrame ) + { + xTargetFrame = pTargetFrame->GetFrameInterface(); + } + else + { + xTargetFrame.set( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop")), UNO_QUERY ); + } + } + + // make URL ready + SFX_REQUEST_ARG( rReq, pURLItem, SfxStringItem, SID_FILE_NAME, FALSE ); + aFileName = pURLItem->GetValue(); + if( aFileName.Len() && aFileName.GetChar(0) == '#' ) // Mark without URL + { + SfxViewFrame *pView = pTargetFrame ? pTargetFrame->GetCurrentViewFrame() : 0; + if ( !pView ) + pView = SfxViewFrame::Current(); + pView->GetViewShell()->JumpToMark( aFileName.Copy(1) ); + rReq.SetReturnValue( SfxViewFrameItem( 0, pView ) ); + return; + } + + // convert items to properties for framework API calls + Sequence < PropertyValue > aArgs; + TransformItems( SID_OPENDOC, *rReq.GetArgs(), aArgs ); + + // TODO/LATER: either remove LinkItem or create an asynchronous process for it + if( bHidden || pLinkItem || rReq.IsSynchronCall() ) + { + // if loading must be done synchron, we must wait for completion to get a return value + // find frame by myself; I must konw the exact frame to get the controller for the return value from it + //if( aTarget.getLength() ) + // xTargetFrame = xTargetFrame->findFrame( aTarget, FrameSearchFlag::ALL ); + Reference < XComponent > xComp; + + try + { + xComp = ::comphelper::SynchronousDispatch::dispatch( xTargetFrame, aFileName, aTarget, 0, aArgs ); +// Reference < XComponentLoader > xLoader( xTargetFrame, UNO_QUERY ); +// xComp = xLoader->loadComponentFromURL( aFileName, aTarget, 0, aArgs ); + } + catch(const RuntimeException&) + { + throw; + } + catch(const ::com::sun::star::uno::Exception&) + { + } + + Reference < XModel > xModel( xComp, UNO_QUERY ); + if ( xModel.is() ) + xController = xModel->getCurrentController(); + else + xController = Reference < XController >( xComp, UNO_QUERY ); + + } + else + { + URL aURL; + aURL.Complete = aFileName; + Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance( rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" )), UNO_QUERY ); + xTrans->parseStrict( aURL ); + + Reference < XDispatchProvider > xProv( xTargetFrame, UNO_QUERY ); + Reference < XDispatch > xDisp = xProv.is() ? xProv->queryDispatch( aURL, aTarget, FrameSearchFlag::ALL ) : Reference < XDispatch >();; + RTL_LOGFILE_PRODUCT_CONTEXT( aLog2, "PERFORMANCE - SfxApplication::OpenDocExec_Impl" ); + if ( xDisp.is() ) + xDisp->dispatch( aURL, aArgs ); + } + /* + } + else + { + // synchron loading without a given frame or as blank frame + SFX_REQUEST_ARG( rReq, pFileNameItem, SfxStringItem, SID_FILE_NAME, FALSE ); + + // Desktop service must exists! dont catch() or check for problems here ... + // But loading of documents can fail by other reasons. Handle it more gracefully. + Reference < XComponentLoader > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop")), UNO_QUERY ); + Reference < XComponent > xComp; + try + { + xComp = xDesktop->loadComponentFromURL( pFileNameItem->GetValue(), aTarget, 0, aArgs ); + } + catch(const RuntimeException&) + { + throw; + } + catch(const ::com::sun::star::uno::Exception&) + { + xDesktop.clear(); + xComp.clear(); + } + + Reference < XModel > xModel( xComp, UNO_QUERY ); + if ( xModel.is() ) + xController = xModel->getCurrentController(); + else + xController = Reference < XController >( xComp, UNO_QUERY ); + }*/ + + if ( xController.is() ) + { + // try to find the SfxFrame for the controller + SfxFrame* pCntrFrame = NULL; + for ( SfxViewShell* pShell = SfxViewShell::GetFirst( 0, FALSE ); pShell; pShell = SfxViewShell::GetNext( *pShell, 0, FALSE ) ) + { + if ( pShell->GetController() == xController ) + { + pCntrFrame = &pShell->GetViewFrame()->GetFrame(); + break; + } + } + + if ( pCntrFrame ) + { + SfxObjectShell* pSh = pCntrFrame->GetCurrentDocument(); + DBG_ASSERT( pSh, "Controller without ObjectShell ?!" ); + + rReq.SetReturnValue( SfxViewFrameItem( 0, pCntrFrame->GetCurrentViewFrame() ) ); + + if ( bHidden ) + pSh->RestoreNoDelete(); + } + } + + if ( pLinkItem ) + { + SfxPoolItem* pRet = rReq.GetReturnValue()->Clone(); + pLinkItem->GetValue().Call(pRet); + delete pLinkItem; + } +} diff --git a/sfx2/source/appl/appquit.cxx b/sfx2/source/appl/appquit.cxx new file mode 100644 index 000000000000..7399742d1e94 --- /dev/null +++ b/sfx2/source/appl/appquit.cxx @@ -0,0 +1,174 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" +#include <basic/basmgr.hxx> +#include <basic/sbstar.hxx> + +#include <svl/svdde.hxx> +#ifndef _MSGBOX_HXX //autogen +#include <vcl/msgbox.hxx> +#endif +#include <svl/eitem.hxx> + +#include <unotools/saveopt.hxx> +#include <unotools/misccfg.hxx> + +#ifndef GCC +#endif + +#include "app.hrc" +#include <sfx2/app.hxx> +#include <sfx2/unoctitm.hxx> +#include "appdata.hxx" +#include <sfx2/viewsh.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/printer.hxx> +#include "arrdecl.hxx" +#include "sfxresid.hxx" +#include <sfx2/event.hxx> +#include <sfx2/macrconf.hxx> +#include <sfx2/mnumgr.hxx> +#include <sfx2/templdlg.hxx> +#include <sfx2/msgpool.hxx> +#include <sfx2/docfile.hxx> +#include "sfxtypes.hxx" +#include "sfxlocal.hrc" +#include <sfx2/fcontnr.hxx> +#include "nochaos.hxx" +#include <sfx2/appuno.hxx> +#include <sfx2/doctempl.hxx> +#include <sfx2/viewfrm.hxx> +#include <sfx2/objsh.hxx> +#include <sfx2/docfac.hxx> +#include "appbaslib.hxx" +#include <basic/basicmanagerrepository.hxx> + +using ::basic::BasicManagerRepository; + +//=================================================================== +BOOL SfxApplication::QueryExit_Impl() +{ + BOOL bQuit = TRUE; + + // will trotzdem noch jemand, den man nicht abschiessen kann, die App haben? + if ( !bQuit ) + { + // nicht wirklich beenden, nur minimieren + InfoBox aInfoBox( NULL, SfxResId(MSG_CANT_QUIT) ); + aInfoBox.Execute(); + DBG_TRACE( "QueryExit => FALSE (in use)" ); + return FALSE; + } + + return TRUE; +} + +//------------------------------------------------------------------------- + +void SfxApplication::Deinitialize() +{ + if ( pAppData_Impl->bDowning ) + return; + + StarBASIC::Stop(); + + // ggf. BASIC speichern + BasicManager* pBasMgr = BasicManagerRepository::getApplicationBasicManager( false ); + if ( pBasMgr && pBasMgr->IsModified() ) + SaveBasicManager(); + + SaveBasicAndDialogContainer(); + + pAppData_Impl->bDowning = TRUE; // wegen Timer aus DecAliveCount und QueryExit + + DELETEZ( pAppData_Impl->pTemplates ); + + // By definition there shouldn't be any open view frames when we reach + // this method. Therefore this call makes no sense and is the source of + // some stack traces, which we don't understand. + // For more information see: + // #123501# + //SetViewFrame(0); + pAppData_Impl->bDowning = FALSE; + DBG_ASSERT( !SfxViewFrame::GetFirst(), + "existing SfxViewFrame after Execute" ); + DBG_ASSERT( !SfxObjectShell::GetFirst(), + "existing SfxObjectShell after Execute" ); + pAppData_Impl->pAppDispat->Pop( *this, SFX_SHELL_POP_UNTIL ); + pAppData_Impl->pAppDispat->Flush(); + pAppData_Impl->bDowning = TRUE; + pAppData_Impl->pAppDispat->DoDeactivate_Impl( TRUE, NULL ); + + // call derived application-exit + Exit(); + + // Controller u."a. freigeben + // dabei sollten auch restliche Komponenten ( Beamer! ) verschwinden + BasicManagerRepository::resetApplicationBasicManager(); + pAppData_Impl->pBasicManager->reset( NULL ); + // this will also delete pBasMgr + + DBG_ASSERT( pAppData_Impl->pViewFrame == 0, "active foreign ViewFrame" ); + + delete[] pAppData_Impl->pInterfaces, pAppData_Impl->pInterfaces = 0; + + // free administration managers + DELETEZ(pAppData_Impl->pAppDispat); + SfxResId::DeleteResMgr(); + DELETEZ(pAppData_Impl->pOfaResMgr); + + // ab hier d"urfen keine SvObjects mehr existieren + DELETEZ(pAppData_Impl->pMatcher); + + delete pAppData_Impl->pLabelResMgr; + + DELETEX(pAppData_Impl->pSlotPool); + DELETEX(pAppData_Impl->pEventConfig); + SfxMacroConfig::Release_Impl(); + DELETEX(pAppData_Impl->pFactArr); + DELETEX(pAppData_Impl->pInitLinkList); + + DELETEX(pAppData_Impl->pTbxCtrlFac); + DELETEX(pAppData_Impl->pStbCtrlFac); + DELETEX(pAppData_Impl->pMenuCtrlFac); + DELETEX(pAppData_Impl->pViewFrames); + DELETEX(pAppData_Impl->pViewShells); + DELETEX(pAppData_Impl->pObjShells); + + //TODO/CLEANTUP + //ReleaseArgs could be used instead! +/* This leak is intended ! + Otherwise the TestTool cant use .uno:QuitApp ... + because every destructed ItemSet work's on an already + released pool pointer .-) + + NoChaos::ReleaseItemPool(); +*/ + pAppData_Impl->pPool = NULL; +} diff --git a/sfx2/source/appl/appreg.cxx b/sfx2/source/appl/appreg.cxx new file mode 100644 index 000000000000..addace134362 --- /dev/null +++ b/sfx2/source/appl/appreg.cxx @@ -0,0 +1,153 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" + +#include <vcl/toolbox.hxx> + +#ifndef GCC +#endif + +#include <sfx2/app.hxx> +#include "appdata.hxx" +#include "arrdecl.hxx" +#include "sfxhelp.hxx" +#include <sfx2/templdlg.hxx> +#include "objmnctl.hxx" +#include "inettbc.hxx" +#include "stbitem.hxx" +#include <sfx2/navigat.hxx> +#include <sfx2/taskpane.hxx> +#include <sfx2/module.hxx> +#include <sfx2/viewfrm.hxx> +#include "partwnd.hxx" +#include <sfx2/sfxsids.hrc> +#include "recfloat.hxx" +#include <sfx2/objsh.hxx> +#include <sfx2/viewsh.hxx> +#include <sfx2/objface.hxx> + +//=================================================================== + +void SfxApplication::Registrations_Impl() +{ + // Interfaces + SfxApplication::RegisterInterface(); + SfxModule::RegisterInterface(); + SfxViewFrame::RegisterInterface(); + SfxObjectShell::RegisterInterface(); + SfxViewShell::RegisterInterface(); + + // ChildWindows + SfxRecordingFloatWrapper_Impl::RegisterChildWindow(); + SfxNavigatorWrapper::RegisterChildWindow( FALSE, NULL, SFX_CHILDWIN_NEVERHIDE ); + SfxPartChildWnd_Impl::RegisterChildWindow(); + SfxTemplateDialogWrapper::RegisterChildWindow(TRUE); + SfxDockingWrapper::RegisterChildWindow(); + + // Controller + SfxToolBoxControl::RegisterControl(SID_REPEAT); + SfxURLToolBoxControl_Impl::RegisterControl(SID_OPENURL); + SfxAppToolBoxControl_Impl::RegisterControl( SID_NEWDOCDIRECT ); + SfxAppToolBoxControl_Impl::RegisterControl( SID_AUTOPILOTMENU ); +}; + +//-------------------------------------------------------------------- + +void SfxApplication::RegisterToolBoxControl_Impl( SfxModule *pMod, SfxTbxCtrlFactory *pFact ) +{ + if ( pMod ) + { + pMod->RegisterToolBoxControl( pFact ); + return; + } + +#ifdef DBG_UTIL + for ( USHORT n=0; n<pAppData_Impl->pTbxCtrlFac->Count(); n++ ) + { + SfxTbxCtrlFactory *pF = (*pAppData_Impl->pTbxCtrlFac)[n]; + if ( pF->nTypeId && pF->nTypeId == pFact->nTypeId && + (pF->nSlotId == pFact->nSlotId || pF->nSlotId == 0) ) + { + DBG_WARNING("TbxController-Registrierung ist nicht eindeutig!"); + } + } +#endif + + pAppData_Impl->pTbxCtrlFac->C40_INSERT( SfxTbxCtrlFactory, pFact, pAppData_Impl->pTbxCtrlFac->Count() ); +} + +//-------------------------------------------------------------------- + +void SfxApplication::RegisterStatusBarControl_Impl( SfxModule *pMod, SfxStbCtrlFactory *pFact ) +{ + if ( pMod ) + { + pMod->RegisterStatusBarControl( pFact ); + return; + } + +#ifdef DBG_UTIL + for ( USHORT n=0; n<pAppData_Impl->pStbCtrlFac->Count(); n++ ) + { + SfxStbCtrlFactory *pF = (*pAppData_Impl->pStbCtrlFac)[n]; + if ( pF->nTypeId && pF->nTypeId == pFact->nTypeId && + (pF->nSlotId == pFact->nSlotId || pF->nSlotId == 0) ) + { + DBG_WARNING("StbController-Registrierung ist nicht eindeutig!"); + } + } +#endif + + pAppData_Impl->pStbCtrlFac->C40_INSERT( SfxStbCtrlFactory, pFact, pAppData_Impl->pStbCtrlFac->Count() ); +} + +//-------------------------------------------------------------------- + +void SfxApplication::RegisterMenuControl_Impl( SfxModule *pMod, SfxMenuCtrlFactory *pFact ) +{ + if ( pMod ) + { + pMod->RegisterMenuControl( pFact ); + return; + } + +#ifdef DBG_UTIL + for ( USHORT n=0; n<pAppData_Impl->pMenuCtrlFac->Count(); n++ ) + { + SfxMenuCtrlFactory *pF = (*pAppData_Impl->pMenuCtrlFac)[n]; + if ( pF->nTypeId && pF->nTypeId == pFact->nTypeId && + (pF->nSlotId == pFact->nSlotId || pF->nSlotId == 0) ) + { + DBG_WARNING("MenuController-Registrierung ist nicht eindeutig!"); + } + } +#endif + + pAppData_Impl->pMenuCtrlFac->C40_INSERT( SfxMenuCtrlFactory, pFact, pAppData_Impl->pMenuCtrlFac->Count() ); +} diff --git a/sfx2/source/appl/appserv.cxx b/sfx2/source/appl/appserv.cxx new file mode 100644 index 000000000000..bd9efc9bca1e --- /dev/null +++ b/sfx2/source/appl/appserv.cxx @@ -0,0 +1,1355 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" +#include <com/sun/star/uno/Reference.hxx> +#ifndef _COM_SUN_STAR_LANG_XMultiServiceFactory_HPP_ +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#endif +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/frame/DispatchResultEvent.hpp> +#include <com/sun/star/frame/DispatchResultState.hpp> +#include <com/sun/star/task/XJobExecutor.hpp> +#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp> +#include <com/sun/star/frame/XDesktop.hpp> +#include <com/sun/star/frame/XDispatchHelper.hpp> +#include <com/sun/star/frame/XFramesSupplier.hpp> +#include <com/sun/star/util/XCloseable.hpp> +#ifndef _COM_SUN_STAR_UTIL_CloseVetoException_HPP_ +#include <com/sun/star/util/CloseVetoException.hpp> +#endif +#include <com/sun/star/frame/XLayoutManager.hpp> +#include <com/sun/star/document/XEmbeddedScripts.hpp> +#include <com/sun/star/embed/XStorage.hpp> +#include <com/sun/star/embed/ElementModes.hpp> +#include <com/sun/star/system/XSystemShellExecute.hpp> +#include <com/sun/star/system/SystemShellExecuteFlags.hpp> +#include <com/sun/star/system/SystemShellExecuteException.hpp> + +#include <comphelper/processfactory.hxx> +#include <comphelper/storagehelper.hxx> +#include "comphelper/configurationhelper.hxx" + +#include <svtools/addresstemplate.hxx> +#include <svl/visitem.hxx> +#include <unotools/intlwrapper.hxx> + +#include <unotools/configmgr.hxx> +#include <tools/config.hxx> +#include <tools/diagnose_ex.h> +#include <vcl/msgbox.hxx> +#include <svl/intitem.hxx> +#include <svl/eitem.hxx> +#include <svl/stritem.hxx> +#include <basic/sbstar.hxx> +#include <basic/basmgr.hxx> +#include <basic/basrdll.hxx> +#include <svtools/sfxecode.hxx> +#include <svtools/ehdl.hxx> +#include <vcl/help.hxx> +#include <vcl/stdtext.hxx> +#include <rtl/ustrbuf.hxx> + +#include <unotools/pathoptions.hxx> +#include <unotools/moduleoptions.hxx> +#include <unotools/regoptions.hxx> +#include <svtools/helpopt.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <tools/shl.hxx> +#include <unotools/bootstrap.hxx> +#include <vos/process.hxx> +#include <rtl/bootstrap.hxx> +#include <cppuhelper/exc_hlp.hxx> +#include <rtl/ustrbuf.hxx> + +#include <com/sun/star/script/provider/XScriptProviderFactory.hpp> +#include <com/sun/star/frame/XModuleManager.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> + +#include "about.hxx" +#include "frmload.hxx" +#include "referers.hxx" +#include <sfx2/app.hxx> +#include <sfx2/request.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/bindings.hxx> +#include <sfx2/msg.hxx> +#include <sfx2/objface.hxx> +#include <sfx2/objitem.hxx> +#include <sfx2/objsh.hxx> +#include <sfx2/hintpost.hxx> +#include <sfx2/viewsh.hxx> +#include <sfx2/docfac.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/docfilt.hxx> +#include "docvor.hxx" +#include <sfx2/new.hxx> +#include <sfx2/templdlg.hxx> +#include "sfxtypes.hxx" +#include "sfxbasic.hxx" +#include <sfx2/tabdlg.hxx> +#include "arrdecl.hxx" +#include "fltfnc.hxx" +#include <sfx2/sfx.hrc> +#include "app.hrc" +#include <sfx2/passwd.hxx> +#include "sfxresid.hxx" +#include "arrdecl.hxx" +#include <sfx2/childwin.hxx> +#include "appdata.hxx" +#include <sfx2/macrconf.hxx> +#include "minfitem.hxx" +#include <sfx2/event.hxx> +#include <sfx2/module.hxx> +#include <sfx2/viewfrm.hxx> +#include "sfxpicklist.hxx" +#include "imestatuswindow.hxx" +#include <sfx2/sfxdlg.hxx> +#include <sfx2/dialogs.hrc> +#include "sorgitm.hxx" +#include "sfxhelp.hxx" + +using namespace ::com::sun::star; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::script; +using namespace ::com::sun::star::system; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::document; + +namespace css = com::sun::star; + +//------------------------------------------------------------------------- +long QuitAgain_Impl( void* pObj, void* pArg ) +{ + SfxApplication* pApp = (SfxApplication*)pObj; + Timer* pTimer = (Timer*)pArg; + delete pTimer; + pApp->GetDispatcher_Impl()->Execute( SID_QUITAPP, SFX_CALLMODE_ASYNCHRON ); + return 0; +} + +void SfxApplication::MiscExec_Impl( SfxRequest& rReq ) +{ + DBG_MEMTEST(); + FASTBOOL bDone = FALSE; + switch ( rReq.GetSlot() ) + { + case SID_SETOPTIONS: + { + if( rReq.GetArgs() ) + SetOptions_Impl( *rReq.GetArgs() ); + break; + } + + case SID_QUITAPP: + case SID_EXITANDRETURN: + case SID_LOGOUT: + { + // protect against reentrant calls + if ( pAppData_Impl->bInQuit ) + return; + + if ( rReq.GetSlot() == SID_LOGOUT ) + { + for ( SfxObjectShell *pObjSh = SfxObjectShell::GetFirst(); + pObjSh; pObjSh = SfxObjectShell::GetNext( *pObjSh ) ) + { + if ( !pObjSh->IsModified() ) + continue; + + SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pObjSh ); + if ( !pFrame || !pFrame->GetWindow().IsReallyVisible() ) + continue; + + if ( pObjSh->PrepareClose(2) ) + pObjSh->SetModified( FALSE ); + else + return; + } + + String aName = String::CreateFromAscii("vnd.sun.star.cmd:logout"); + SfxStringItem aNameItem( SID_FILE_NAME, aName ); + SfxStringItem aReferer( SID_REFERER, DEFINE_CONST_UNICODE( "private/user" ) ); + pAppData_Impl->pAppDispat->Execute( SID_OPENDOC, SFX_CALLMODE_SLOT, &aNameItem, &aReferer, 0L ); + return; + } + + // aus verschachtelten Requests nach 100ms nochmal probieren + if( Application::GetDispatchLevel() > 1 ) + { + /* Dont save the request for closing the application and try it later + again. This is an UI bound functionality ... and the user will try it again + if the dialog is closed. But we shouldnt close the application automaticly + if this dialog is closed by the user ... + So we ignore this request now and wait for a new user decision. + */ + DBG_TRACE1( "QueryExit => FALSE (DispatchLevel == %u)", Application::GetDispatchLevel() ); + return; + } + + // block reentrant calls + pAppData_Impl->bInQuit = TRUE; + Reference < XDesktop > xDesktop ( ::comphelper::getProcessServiceFactory()->createInstance( DEFINE_CONST_UNICODE("com.sun.star.frame.Desktop") ), UNO_QUERY ); + + rReq.ForgetAllArgs(); + + // if terminate() failed, pAppData_Impl->bInQuit will now be FALSE, allowing further calls of SID_QUITAPP + BOOL bTerminated = xDesktop->terminate(); + if (!bTerminated) + // if terminate() was successful, SfxApplication is now dead! + pAppData_Impl->bInQuit = FALSE; + + // Returnwert setzten, ggf. terminieren + rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), bTerminated ) ); + return; + } + + case SID_CONFIG: + case SID_TOOLBOXOPTIONS: + case SID_CONFIGSTATUSBAR: + case SID_CONFIGMENU: + case SID_CONFIGACCEL: + case SID_CONFIGEVENT: + { + SfxAbstractDialogFactory* pFact = + SfxAbstractDialogFactory::Create(); + + if ( pFact ) + { + SFX_REQUEST_ARG(rReq, pStringItem, + SfxStringItem, SID_CONFIG, sal_False); + + SfxItemSet aSet( + GetPool(), SID_CONFIG, SID_CONFIG ); + + if ( pStringItem ) + { + aSet.Put( SfxStringItem( + SID_CONFIG, pStringItem->GetValue() ) ); + } + + Reference< XFrame > xFrame; + const SfxItemSet* pIntSet = rReq.GetInternalArgs_Impl(); + SFX_ITEMSET_ARG( pIntSet, pFrameItem, SfxUnoFrameItem, SID_FILLFRAME, FALSE ); + if ( pFrameItem ) + xFrame = pFrameItem->GetFrame(); + + SfxAbstractTabDialog* pDlg = pFact->CreateTabDialog( + RID_SVXDLG_CUSTOMIZE, + NULL, &aSet, xFrame ); + + if ( pDlg ) + { + const short nRet = pDlg->Execute(); + + if ( nRet ) + bDone = TRUE; + + delete pDlg; + } + } + break; + } + + case SID_CLOSEDOCS: + case SID_CLOSEWINS: + { + + Reference < XFramesSupplier > xDesktop ( ::comphelper::getProcessServiceFactory()->createInstance( DEFINE_CONST_UNICODE("com.sun.star.frame.Desktop") ), UNO_QUERY ); + Reference< XIndexAccess > xTasks( xDesktop->getFrames(), UNO_QUERY ); + if ( !xTasks.is() ) + break; + + sal_Int32 n=0; + do + { + if ( xTasks->getCount() <= n ) + break; + + Any aAny = xTasks->getByIndex(n); + Reference < XCloseable > xTask; + aAny >>= xTask; + try + { + xTask->close(sal_True); + n++; + } + catch( CloseVetoException& ) + { + } + } + while( sal_True ); + + BOOL bOk = ( n == 0); + rReq.SetReturnValue( SfxBoolItem( 0, bOk ) ); + bDone = TRUE; + break; + } + + case SID_SAVEDOCS: + { + BOOL bOK = TRUE; + BOOL bTmpDone = TRUE; + for ( SfxObjectShell *pObjSh = SfxObjectShell::GetFirst(); + pObjSh; + pObjSh = SfxObjectShell::GetNext( *pObjSh ) ) + { + SfxRequest aReq( SID_SAVEDOC, 0, pObjSh->GetPool() ); + if ( pObjSh->IsModified() ) + { + pObjSh->ExecuteSlot( aReq ); + SfxBoolItem *pItem = PTR_CAST( SfxBoolItem, aReq.GetReturnValue() ); + bTmpDone = aReq.IsDone(); + if ( !pItem || !pItem->GetValue() ) + bOK = FALSE; + } + } + + rReq.SetReturnValue( SfxBoolItem( 0, bOK ) ); + rReq.Done(); + break; + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case SID_HELPINDEX: + case SID_HELP_SUPPORTPAGE: + { + Help* pHelp = Application::GetHelp(); + if ( pHelp ) + { + ULONG nHelpId = ( rReq.GetSlot() == SID_HELP_SUPPORTPAGE ) ? 66056 : 0; + if ( 66056 == nHelpId ) + { + // show Support page with new URL + String sHelpURL = SfxHelp::CreateHelpURL( nHelpId, String() ); + String sParams = sHelpURL.Copy( sHelpURL.Search( '?' ) ); + sHelpURL = String::CreateFromAscii("vnd.sun.star.help://shared/text/shared/05/00000001.xhp"); + sHelpURL += sParams; + sHelpURL += String::CreateFromAscii("&UseDB=no"); + pHelp->Start( sHelpURL, NULL ); + } + else + pHelp->Start( nHelpId, NULL ); // show start page + bDone = TRUE; + } + break; + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case SID_HELPTIPS: + { + // Parameter aus werten + SFX_REQUEST_ARG(rReq, pOnItem, SfxBoolItem, SID_HELPTIPS, FALSE); + bool bOn = pOnItem + ? ((SfxBoolItem*)pOnItem)->GetValue() + : !Help::IsQuickHelpEnabled(); + + // ausf"uhren + if ( bOn ) + Help::EnableQuickHelp(); + else + Help::DisableQuickHelp(); + SvtHelpOptions().SetHelpTips( bOn ); + Invalidate(SID_HELPTIPS); + bDone = TRUE; + + // ggf. recorden + if ( !rReq.IsAPI() ) + rReq.AppendItem( SfxBoolItem( SID_HELPTIPS, bOn) ); + break; + } + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case SID_EXTENDEDHELP: + { + Help::StartExtHelp(); + break; + } + case SID_HELPBALLOONS: + { + // Parameter auswerten + SFX_REQUEST_ARG(rReq, pOnItem, SfxBoolItem, SID_HELPBALLOONS, FALSE); + bool bOn = pOnItem + ? ((SfxBoolItem*)pOnItem)->GetValue() + : !Help::IsBalloonHelpEnabled(); + + // ausf"uhren + if ( bOn ) + Help::EnableBalloonHelp(); + else + Help::DisableBalloonHelp(); + SvtHelpOptions().SetExtendedHelp( bOn ); + Invalidate(SID_HELPBALLOONS); + bDone = TRUE; + + // ggf. recorden + if ( !rReq.IsAPI() ) + rReq.AppendItem( SfxBoolItem( SID_HELPBALLOONS, bOn) ); + break; + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case SID_HELP_PI: + { + SvtHelpOptions aHelpOpt; + SFX_REQUEST_ARG(rReq, pOnItem, SfxBoolItem, SID_HELP_PI, FALSE); + sal_Bool bOn = pOnItem + ? ((SfxBoolItem*)pOnItem)->GetValue() + : !aHelpOpt.IsHelpAgentAutoStartMode(); + aHelpOpt.SetHelpAgentAutoStartMode( bOn ); + Invalidate(SID_HELP_PI); + bDone = TRUE; + break; + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case SID_ABOUT: + { + const String sCWSSchema( String::CreateFromAscii( "[CWS:" ) ); + rtl::OUString sDefault; + String sBuildId( utl::Bootstrap::getBuildIdData( sDefault ) ); + OSL_ENSURE( sBuildId.Len() > 0, "No BUILDID in bootstrap file" ); + if ( sBuildId.Len() > 0 && sBuildId.Search( sCWSSchema ) == STRING_NOTFOUND ) + { + // no cws part in brand buildid -> try basis buildid + rtl::OUString sBasisBuildId( DEFINE_CONST_OUSTRING( + "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("version") ":buildid}" ) ); + rtl::Bootstrap::expandMacros( sBasisBuildId ); + sal_Int32 nIndex = sBasisBuildId.indexOf( sCWSSchema ); + if ( nIndex != -1 ) + sBuildId += String( sBasisBuildId.copy( nIndex ) ); + } + + String sProductSource( utl::Bootstrap::getProductSource( sDefault ) ); + OSL_ENSURE( sProductSource.Len() > 0, "No ProductSource in bootstrap file" ); + + // the product source is something like "DEV300", where the + // build id is something like "300m12(Build:12345)". For better readability, + // strip the duplicate UPD ("300"). + if ( sProductSource.Len() ) + { + bool bMatchingUPD = + ( sProductSource.Len() >= 3 ) + && ( sBuildId.Len() >= 3 ) + && ( sProductSource.Copy( sProductSource.Len() - 3 ) == sBuildId.Copy( 0, 3 ) ); + OSL_ENSURE( bMatchingUPD, "BUILDID and ProductSource do not match in their UPD" ); + if ( bMatchingUPD ) + sProductSource = sProductSource.Copy( 0, sProductSource.Len() - 3 ); + + // prepend the product source + sBuildId.Insert( sProductSource, 0 ); + } + + // --> PB 2008-10-30 #i94693# + /* if the build ids of the basis or ure layer are different from the build id + * of the brand layer then show them */ + rtl::OUString aBasisProductBuildId( DEFINE_CONST_OUSTRING( + "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("version") ":ProductBuildid}" ) ); + rtl::Bootstrap::expandMacros( aBasisProductBuildId ); + rtl::OUString aUREProductBuildId( DEFINE_CONST_OUSTRING( + "${$URE_BIN_DIR/" SAL_CONFIGFILE("version") ":ProductBuildid}" ) ); + rtl::Bootstrap::expandMacros( aUREProductBuildId ); + if ( sBuildId.Search( String( aBasisProductBuildId ) ) == STRING_NOTFOUND + || sBuildId.Search( String( aUREProductBuildId ) ) == STRING_NOTFOUND ) + { + String sTemp( '-' ); + sTemp += String( aBasisProductBuildId ); + sTemp += '-'; + sTemp += String( aUREProductBuildId ); + sBuildId.Insert( sTemp, sBuildId.Search( ')' ) ); + } + // <-- + + // the build id format is "milestone(build)[cwsname]". For readability, it would + // be nice to have some more spaces in there. + xub_StrLen nPos = 0; + if ( ( nPos = sBuildId.Search( sal_Unicode( '(' ) ) ) != STRING_NOTFOUND ) + sBuildId.Insert( sal_Unicode( ' ' ), nPos ); + if ( ( nPos = sBuildId.Search( sal_Unicode( '[' ) ) ) != STRING_NOTFOUND ) + sBuildId.Insert( sal_Unicode( ' ' ), nPos ); + + // search for the resource of the about box + ResId aDialogResId( RID_DEFAULTABOUT, *pAppData_Impl->pLabelResMgr ); + ResMgr* pResMgr = pAppData_Impl->pLabelResMgr; + if( ! pResMgr->IsAvailable( aDialogResId.SetRT( RSC_MODALDIALOG ) ) ) + pResMgr = GetOffResManager_Impl(); + + aDialogResId.SetResMgr( pResMgr ); + if ( !pResMgr->IsAvailable( aDialogResId ) ) + { + DBG_ERRORFILE( "No RID_DEFAULTABOUT in label-resource-dll" ); + } + + // then show the about box + AboutDialog* pDlg = new AboutDialog( 0, aDialogResId, sBuildId ); + pDlg->Execute(); + delete pDlg; + bDone = TRUE; + break; + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case SID_ORGANIZER: + { + SfxTemplateOrganizeDlg *pDlg = + new SfxTemplateOrganizeDlg(NULL); + pDlg->Execute(); + delete pDlg; + bDone = TRUE; + break; + } + + case SID_TEMPLATE_ADDRESSBOKSOURCE: + { + svt::AddressBookSourceDialog aDialog(GetTopWindow(), ::comphelper::getProcessServiceFactory()); + aDialog.Execute(); + bDone = TRUE; + break; + } + + case SID_BASICSTOP: + StarBASIC::Stop(); + break; + + case SID_BASICBREAK : + BASIC_DLL()->BasicBreak(); + break; + + case SID_CRASH : + { + // Provoke a crash: + char * crash = 0; + *crash = 0; + break; + } + + case SID_SHOW_IME_STATUS_WINDOW: + if (pAppData_Impl->m_xImeStatusWindow->canToggle()) + { + SfxBoolItem const * pItem = static_cast< SfxBoolItem const * >( + rReq.GetArg(SID_SHOW_IME_STATUS_WINDOW, false, + TYPE(SfxBoolItem))); + bool bShow = pItem == 0 + ? !pAppData_Impl->m_xImeStatusWindow->isShowing() + : ( pItem->GetValue() == TRUE ); + pAppData_Impl->m_xImeStatusWindow->show(bShow); + if (pItem == 0) + rReq.AppendItem(SfxBoolItem(SID_SHOW_IME_STATUS_WINDOW, + bShow)); + } + bDone = true; + break; + + case SID_AVAILABLE_TOOLBARS: + { + SfxStringItem const * pToolbarName = static_cast< SfxStringItem const *>( + rReq.GetArg(SID_AVAILABLE_TOOLBARS, false, TYPE(SfxStringItem))); + + if ( pToolbarName ) + { + com::sun::star::uno::Reference< com::sun::star::frame::XFrame > xFrame; + Reference < XFramesSupplier > xDesktop ( ::comphelper::getProcessServiceFactory()->createInstance( + DEFINE_CONST_UNICODE("com.sun.star.frame.Desktop") ), UNO_QUERY ); + xFrame = xDesktop->getActiveFrame(); + + 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; + } + catch ( ::com::sun::star::uno::RuntimeException& e ) + { + throw e; + } + catch ( ::com::sun::star::uno::Exception& ) + { + } + } + + if ( xLayoutManager.is() ) + { + rtl::OUString aToolbarResName( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/" )); + rtl::OUStringBuffer aBuf( aToolbarResName ); + aBuf.append( pToolbarName->GetValue() ); + + // Parameter auswerten + rtl::OUString aToolbarName( aBuf.makeStringAndClear() ); + BOOL bShow( !xLayoutManager->isElementVisible( aToolbarName )); + + if ( bShow ) + { + xLayoutManager->createElement( aToolbarName ); + xLayoutManager->showElement( aToolbarName ); + } + else + xLayoutManager->hideElement( aToolbarName ); + } + } + + bDone = true; + break; + } + + default: + break; + } + + if ( bDone ) + rReq.Done(); +} + +//-------------------------------------------------------------------- + +void SfxApplication::MiscState_Impl(SfxItemSet &rSet) +{ + DBG_MEMTEST(); + + LocaleDataWrapper aLocaleWrapper( ::comphelper::getProcessServiceFactory(), Application::GetSettings().GetLocale() ); + const USHORT *pRanges = rSet.GetRanges(); + DBG_ASSERT(pRanges && *pRanges, "Set ohne Bereich"); + while ( *pRanges ) + { + for(USHORT nWhich = *pRanges++; nWhich <= *pRanges; ++nWhich) + { + switch(nWhich) + { + case SID_TEMPLATE_ADDRESSBOKSOURCE: + if ( !SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::E_SDATABASE) ) + rSet.Put(SfxVisibilityItem(nWhich, sal_False)); + break; + case SID_EXITANDRETURN: + case SID_QUITAPP: + { + if ( pAppData_Impl->nDocModalMode ) + rSet.DisableItem(nWhich); + else + rSet.Put(SfxStringItem(nWhich, String(SfxResId(STR_QUITAPP)))); + break; + } + + case SID_BASICSTOP: + if ( !StarBASIC::IsRunning() ) + rSet.DisableItem(nWhich); + break; + + case SID_HELPTIPS: + { + rSet.Put( SfxBoolItem( SID_HELPTIPS, Help::IsQuickHelpEnabled() ) ); + } + break; + case SID_HELPBALLOONS: + { + rSet.Put( SfxBoolItem( SID_HELPBALLOONS, Help::IsBalloonHelpEnabled() ) ); + } + break; + case SID_HELP_PI: + { + rSet.Put( SfxBoolItem( SID_HELP_PI, SvtHelpOptions().IsHelpAgentAutoStartMode() ) ); + } + break; + + case SID_EXTENDEDHELP: + { + } + break; + + case SID_CLOSEDOCS: + case SID_CLOSEWINS: + { + Reference < XFramesSupplier > xDesktop ( ::comphelper::getProcessServiceFactory()->createInstance( DEFINE_CONST_UNICODE("com.sun.star.frame.Desktop") ), UNO_QUERY ); + Reference< XIndexAccess > xTasks( xDesktop->getFrames(), UNO_QUERY ); + if ( !xTasks.is() || !xTasks->getCount() ) + rSet.DisableItem(nWhich); + break; + } + + case SID_SAVEDOCS: + { + BOOL bModified = FALSE; + for ( SfxObjectShell *pObjSh = SfxObjectShell::GetFirst(); + pObjSh; + pObjSh = SfxObjectShell::GetNext( *pObjSh ) ) + { + if ( pObjSh->IsModified() ) + { + bModified = TRUE; + break; + } + } + + if ( !bModified ) + rSet.DisableItem( nWhich ); + break; + } + + case SID_SHOW_IME_STATUS_WINDOW: + if (pAppData_Impl->m_xImeStatusWindow->canToggle()) + rSet.Put(SfxBoolItem( + SID_SHOW_IME_STATUS_WINDOW, + pAppData_Impl->m_xImeStatusWindow-> + isShowing())); + else + rSet.DisableItem(SID_SHOW_IME_STATUS_WINDOW); + break; + + default: + break; + } + } + + ++pRanges; + } +} + +static const ::rtl::OUString& getProductRegistrationServiceName( ) +{ + static ::rtl::OUString s_sServiceName = ::rtl::OUString::createFromAscii( "com.sun.star.setup.ProductRegistration" ); + return s_sServiceName; +} + +typedef rtl_uString* (SAL_CALL *basicide_choose_macro)(XModel*, BOOL, rtl_uString*); +typedef void (SAL_CALL *basicide_macro_organizer)( INT16 ); + +#define DOSTRING( x ) #x +#define STRING( x ) DOSTRING( x ) + +extern "C" { static void SAL_CALL thisModule() {} } + +::rtl::OUString ChooseMacro( const Reference< XModel >& rxLimitToDocument, BOOL bChooseOnly, const ::rtl::OUString& rMacroDesc = ::rtl::OUString() ) +{ + // get basctl dllname + String sLibName = String::CreateFromAscii( STRING( DLL_NAME ) ); + sLibName.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "sfx" ) ), String( RTL_CONSTASCII_USTRINGPARAM( "basctl" ) ) ); + ::rtl::OUString aLibName( sLibName ); + + // load module + oslModule handleMod = osl_loadModuleRelative( + &thisModule, aLibName.pData, 0 ); + + // get symbol + ::rtl::OUString aSymbol( RTL_CONSTASCII_USTRINGPARAM( "basicide_choose_macro" ) ); + basicide_choose_macro pSymbol = (basicide_choose_macro) osl_getFunctionSymbol( handleMod, aSymbol.pData ); + + // call basicide_choose_macro in basctl + rtl_uString* pScriptURL = pSymbol( rxLimitToDocument.get(), bChooseOnly, rMacroDesc.pData ); + ::rtl::OUString aScriptURL( pScriptURL ); + rtl_uString_release( pScriptURL ); + return aScriptURL; +} + +void MacroOrganizer( INT16 nTabId ) +{ + // get basctl dllname + String sLibName = String::CreateFromAscii( STRING( DLL_NAME ) ); + sLibName.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "sfx" ) ), String( RTL_CONSTASCII_USTRINGPARAM( "basctl" ) ) ); + ::rtl::OUString aLibName( sLibName ); + + // load module + oslModule handleMod = osl_loadModuleRelative( + &thisModule, aLibName.pData, 0 ); + + // get symbol + ::rtl::OUString aSymbol( RTL_CONSTASCII_USTRINGPARAM( "basicide_macro_organizer" ) ); + basicide_macro_organizer pSymbol = (basicide_macro_organizer) osl_getFunctionSymbol( handleMod, aSymbol.pData ); + + // call basicide_macro_organizer in basctl + pSymbol( nTabId ); +} + +#define RID_ERRBOX_MODULENOTINSTALLED (RID_OFA_START + 72) + +ResMgr* SfxApplication::GetOffResManager_Impl() +{ + if ( !pAppData_Impl->pOfaResMgr ) + pAppData_Impl->pOfaResMgr = CreateResManager( "ofa"); + return pAppData_Impl->pOfaResMgr; +} + +namespace +{ + Window* lcl_getDialogParent( const Reference< XFrame >& _rxFrame, Window* _pFallback ) + { + if ( !_rxFrame.is() ) + return _pFallback; + + try + { + Reference< awt::XWindow > xContainerWindow( _rxFrame->getContainerWindow(), UNO_SET_THROW ); + Window* pWindow = VCLUnoHelper::GetWindow( xContainerWindow ); + OSL_ENSURE( pWindow, "lcl_getDialogParent: cool, somebody implemented a VCL-less toolkit!" ); + + if ( pWindow ) + return pWindow->GetSystemWindow(); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return _pFallback; + } + + const ::rtl::OUString& lcl_getBasicIDEServiceName() + { + static const ::rtl::OUString s_sBasicName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.BasicIDE" ) ); + return s_sBasicName; + } + + SfxViewFrame* lcl_getBasicIDEViewFrame( SfxObjectShell* i_pBasicIDE ) + { + SfxViewFrame* pView = SfxViewFrame::GetFirst( i_pBasicIDE ); + while ( pView ) + { + if ( pView->GetObjectShell()->GetFactory().GetDocumentServiceName() == lcl_getBasicIDEServiceName() ) + break; + pView = SfxViewFrame::GetNext( *pView, i_pBasicIDE ); + } + return pView; + } + Reference< XFrame > lcl_findStartModuleFrame( const ::comphelper::ComponentContext& i_rContext ) + { + try + { + Reference < XFramesSupplier > xSupplier( i_rContext.createComponent( "com.sun.star.frame.Desktop" ), UNO_QUERY_THROW ); + Reference < XIndexAccess > xContainer( xSupplier->getFrames(), UNO_QUERY_THROW ); + + Reference< XModuleManager > xCheck( i_rContext.createComponent( "com.sun.star.frame.ModuleManager" ), UNO_QUERY_THROW ); + + sal_Int32 nCount = xContainer->getCount(); + for ( sal_Int32 i=0; i<nCount; ++i ) + { + try + { + Reference < XFrame > xFrame( xContainer->getByIndex(i), UNO_QUERY_THROW ); + ::rtl::OUString sModule = xCheck->identify( xFrame ); + if ( sModule.equalsAscii( "com.sun.star.frame.StartModule" ) ) + return xFrame; + } + catch( const UnknownModuleException& ) + { + // silence + } + catch(const Exception&) + { + // re-throw, caught below + throw; + } + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return NULL; + } +} + +static ::rtl::OUString getConfigurationStringValue( + const ::rtl::OUString& rPackage, + const ::rtl::OUString& rRelPath, + const ::rtl::OUString& rKey, + const ::rtl::OUString& rDefaultValue ) +{ + ::rtl::OUString aDefVal( rDefaultValue ); + + try + { + ::comphelper::ConfigurationHelper::readDirectKey( + comphelper::getProcessServiceFactory(), + rPackage, + rRelPath, + rKey, + ::comphelper::ConfigurationHelper::E_READONLY) >>= aDefVal; + } + catch(const com::sun::star::uno::RuntimeException& exRun) + { throw exRun; } + catch(const com::sun::star::uno::Exception&) + {} + + return aDefVal; +} + +void SfxApplication::OfaExec_Impl( SfxRequest& rReq ) +{ + DBG_MEMTEST(); + switch ( rReq.GetSlot() ) + { + case SID_OPTIONS_TREEDIALOG: + { + String sPageURL; + SFX_REQUEST_ARG( rReq, pURLItem, SfxStringItem, SID_OPTIONS_PAGEURL, sal_False ); + if ( pURLItem ) + sPageURL = pURLItem->GetValue(); + const SfxItemSet* pArgs = rReq.GetInternalArgs_Impl(); + const SfxPoolItem* pItem = NULL; + Reference < XFrame > xFrame; + if ( pArgs && pArgs->GetItemState( SID_FILLFRAME, sal_False, &pItem ) == SFX_ITEM_SET ) + { + OSL_ENSURE( pItem->ISA( SfxUnoFrameItem ), "SfxApplication::OfaExec_Impl: XFrames are to be transported via SfxUnoFrameItem by now!" ); + xFrame = static_cast< const SfxUnoFrameItem*>( pItem )->GetFrame(); + } + SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create(); + if ( pFact ) + { + VclAbstractDialog* pDlg = + pFact->CreateFrameDialog( NULL, xFrame, rReq.GetSlot(), sPageURL ); + pDlg->Execute(); + delete pDlg; + SfxViewFrame* pView = SfxViewFrame::GetFirst(); + while ( pView ) + { + pView->GetBindings().InvalidateAll(FALSE); + pView = SfxViewFrame::GetNext( *pView ); + } + } + break; + } + + case SID_MORE_DICTIONARIES: + { + try + { + uno::Reference< lang::XMultiServiceFactory > xSMGR = + ::comphelper::getProcessServiceFactory(); + uno::Reference< css::system::XSystemShellExecute > xSystemShell( + xSMGR->createInstance( DEFINE_CONST_UNICODE("com.sun.star.system.SystemShellExecute" ) ), + uno::UNO_QUERY_THROW ); + + // read repository URL from configuration + ::rtl::OUString sTemplRepoURL = + getConfigurationStringValue( + ::rtl::OUString::createFromAscii("org.openoffice.Office.Common"), + ::rtl::OUString::createFromAscii("Dictionaries"), + ::rtl::OUString::createFromAscii("RepositoryURL"), + ::rtl::OUString()); + + if ( xSystemShell.is() && sTemplRepoURL.getLength() > 0 ) + { + ::rtl::OUStringBuffer aURLBuf( sTemplRepoURL ); + aURLBuf.appendAscii( "?" ); + aURLBuf.appendAscii( "lang=" ); + + // read locale from configuration + ::rtl::OUString sLocale = getConfigurationStringValue( + ::rtl::OUString::createFromAscii("org.openoffice.Setup"), + ::rtl::OUString::createFromAscii("L10N"), + ::rtl::OUString::createFromAscii("ooLocale"), + ::rtl::OUString::createFromAscii("en-US")); + + aURLBuf.append( sLocale ); + xSystemShell->execute( + aURLBuf.makeStringAndClear(), + ::rtl::OUString(), + css::system::SystemShellExecuteFlags::DEFAULTS ); + } + } + catch( const ::com::sun::star::uno::Exception& ) + { + DBG_ERRORFILE( "SfxApplication::OfaExec_Impl(SID_MORE_DICTIONARIES): caught an exception!" ); + } + break; + } + + case SID_ONLINE_REGISTRATION: + { + try + { + // create the ProductRegistration component + Reference< com::sun::star::lang::XMultiServiceFactory > xORB( ::comphelper::getProcessServiceFactory() ); + Reference< com::sun::star::task::XJobExecutor > xProductRegistration; + if ( xORB.is() ) + xProductRegistration = xProductRegistration.query( xORB->createInstance( getProductRegistrationServiceName() ) ); + DBG_ASSERT( xProductRegistration.is(), "OfficeApplication::ExecuteApp_Impl: could not create the service!" ); + + // tell it that the user wants to register + if ( xProductRegistration.is() ) + { + xProductRegistration->trigger( ::rtl::OUString::createFromAscii( "RegistrationRequired" ) ); + } + } + catch( const ::com::sun::star::uno::Exception& ) + { + DBG_ERROR( "OfficeApplication::ExecuteApp_Impl(SID_ONLINE_REGISTRATION): caught an exception!" ); + } + } + break; + + case SID_BASICIDE_APPEAR: + { + SfxViewFrame* pView = lcl_getBasicIDEViewFrame( NULL ); + if ( !pView ) + { + SfxObjectShell* pBasicIDE = SfxObjectShell::CreateObject( lcl_getBasicIDEServiceName() ); + pBasicIDE->DoInitNew( 0 ); + pBasicIDE->SetModified( FALSE ); + try + { + // load the Basic IDE via direct access to the SFX frame loader. A generic loadComponentFromURL + // (which could be done via SfxViewFrame::LoadDocumentIntoFrame) is not feasible here, since the Basic IDE + // does not really play nice with the framework's concept. For instance, it is a "singleton document", + // which conflicts, at the latest, with the framework's concept of loading into _blank frames. + // So, since we know that our frame loader can handle it, we skip the generic framework loader + // mechanism, and the type detection (which doesn't know about the Basic IDE). + ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() ); + Reference< XSynchronousFrameLoader > xLoader( aContext.createComponent( + SfxFrameLoader_Impl::impl_getStaticImplementationName() ), UNO_QUERY_THROW ); + ::comphelper::NamedValueCollection aLoadArgs; + aLoadArgs.put( "Model", pBasicIDE->GetModel() ); + aLoadArgs.put( "URL", ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:factory/sbasic" ) ) ); + + Reference< XFrame > xTargetFrame( lcl_findStartModuleFrame( aContext ) ); + if ( !xTargetFrame.is() ) + xTargetFrame = SfxFrame::CreateBlankFrame(); + ENSURE_OR_THROW( xTargetFrame.is(), "could not obtain a frameto load the Basic IDE into!" ); + + xLoader->load( aLoadArgs.getPropertyValues(), xTargetFrame ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + pView = lcl_getBasicIDEViewFrame( pBasicIDE ); + if ( pView ) + pView->SetName( String( RTL_CONSTASCII_USTRINGPARAM( "BASIC:1" ) ) ); + } + + if ( pView ) + pView->GetFrame().Appear(); + + const SfxItemSet* pArgs = rReq.GetArgs(); + if ( pArgs && pView ) + { + SfxViewShell* pViewShell = pView->GetViewShell(); + SfxObjectShell* pObjShell = pView->GetObjectShell(); + if ( pViewShell && pObjShell ) + { + SfxRequest aReq( SID_BASICIDE_SHOWWINDOW, SFX_CALLMODE_SYNCHRON, pObjShell->GetPool() ); + aReq.SetArgs( *pArgs ); + pViewShell->ExecuteSlot( aReq ); + } + } + + rReq.Done(); + } + break; + + case SID_BASICCHOOSER: + { + const SfxItemSet* pArgs = rReq.GetArgs(); + const SfxPoolItem* pItem; + BOOL bChooseOnly = FALSE; + Reference< XModel > xLimitToModel; + if(pArgs && SFX_ITEM_SET == pArgs->GetItemState(SID_RECORDMACRO, sal_False, &pItem) ) + { + BOOL bRecord = ((SfxBoolItem*)pItem)->GetValue(); + if ( bRecord ) + { + // !Hack + bChooseOnly = FALSE; + SfxObjectShell* pCurrentShell = SfxObjectShell::Current(); + OSL_ENSURE( pCurrentShell, "macro recording outside an SFX document?" ); + if ( pCurrentShell ) + xLimitToModel = pCurrentShell->GetModel(); + } + } + + rReq.SetReturnValue( SfxStringItem( rReq.GetSlot(), ChooseMacro( xLimitToModel, bChooseOnly ) ) ); + rReq.Done(); + } + break; + + case SID_MACROORGANIZER: + { + OSL_TRACE("handling SID_MACROORGANIZER"); + const SfxItemSet* pArgs = rReq.GetArgs(); + const SfxPoolItem* pItem; + INT16 nTabId = 0; + if(pArgs && SFX_ITEM_SET == pArgs->GetItemState(SID_MACROORGANIZER, sal_False, &pItem) ) + { + nTabId = ((SfxUInt16Item*)pItem)->GetValue(); + } + + SfxApplication::MacroOrganizer( nTabId ); + rReq.Done(); + } + break; + + case SID_RUNMACRO: + { + SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create(); + OSL_TRACE("SfxApplication::OfaExec_Impl: case ScriptOrg"); + + Reference< XFrame > xFrame; + const SfxItemSet* pIntSet = rReq.GetInternalArgs_Impl(); + SFX_ITEMSET_ARG( pIntSet, pFrameItem, SfxUnoFrameItem, SID_FILLFRAME, FALSE ); + if ( pFrameItem ) + xFrame = pFrameItem->GetFrame(); + + if ( !xFrame.is() ) + { + const SfxViewFrame* pViewFrame = SfxViewFrame::Current(); + if ( pViewFrame ) + xFrame = pViewFrame->GetFrame().GetFrameInterface(); + } + + do // artificial loop for flow control + { + AbstractScriptSelectorDialog* pDlg = pFact->CreateScriptSelectorDialog( + lcl_getDialogParent( xFrame, GetTopWindow() ), FALSE, xFrame ); + OSL_ENSURE( pDlg, "SfxApplication::OfaExec_Impl( SID_RUNMACRO ): no dialog!" ); + if ( !pDlg ) + break; + pDlg->SetRunLabel(); + + short nDialogResult = pDlg->Execute(); + if ( !nDialogResult ) + break; + + Sequence< Any > args; + Sequence< sal_Int16 > outIndex; + Sequence< Any > outArgs; + Any ret; + + Reference< XInterface > xScriptContext; + + Reference< XController > xController; + if ( xFrame.is() ) + xController = xFrame->getController(); + if ( xController.is() ) + xScriptContext = xController->getModel(); + if ( !xScriptContext.is() ) + xScriptContext = xController; + + SfxObjectShell::CallXScript( xScriptContext, pDlg->GetScriptURL(), args, ret, outIndex, outArgs ); + } + while ( false ); + rReq.Done(); + } + break; + + case SID_SCRIPTORGANIZER: + { + SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create(); + OSL_TRACE("SfxApplication::OfaExec_Impl: case ScriptOrg"); + const SfxItemSet* pArgs = rReq.GetArgs(); + const SfxPoolItem* pItem; + String aLanguage; + if(pArgs && SFX_ITEM_SET == pArgs->GetItemState(SID_SCRIPTORGANIZER, sal_False, &pItem) ) + { + aLanguage = ((SfxScriptOrganizerItem*)pItem)->getLanguage(); + } + + ::rtl::OUString aLang( aLanguage ); + OSL_TRACE("SfxApplication::OfaExec_Impl: about to create dialog for: %s", ::rtl::OUStringToOString( aLang , RTL_TEXTENCODING_ASCII_US ).pData->buffer); + // not sure about the Window* + VclAbstractDialog* pDlg = pFact->CreateSvxScriptOrgDialog( GetTopWindow(), aLanguage ); + if( pDlg ) + { + pDlg->Execute(); + } + else + { + OSL_TRACE("no dialog!!!"); + } + rReq.Done(); + } + break; + + case SID_OFFICE_CHECK_PLZ: + { + sal_Bool bRet = sal_False; + SFX_REQUEST_ARG(rReq, pStringItem, SfxStringItem, rReq.GetSlot(), sal_False); + + if ( pStringItem ) + { + String aPLZ = pStringItem->GetValue(); + bRet = TRUE /*!!!SfxIniManager::CheckPLZ( aPLZ )*/; + } + else + SbxBase::SetError( SbxERR_WRONG_ARGS ); + rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), bRet ) ); + } + break; + + case SID_AUTO_CORRECT_DLG: + { + SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create(); + if ( pFact ) + { + SfxItemSet aSet(GetPool(), SID_AUTO_CORRECT_DLG, SID_AUTO_CORRECT_DLG); + const SfxPoolItem* pItem=NULL; + const SfxItemSet* pSet = rReq.GetArgs(); + SfxItemPool* pSetPool = pSet ? pSet->GetPool() : NULL; + if ( pSet && pSet->GetItemState( pSetPool->GetWhich( SID_AUTO_CORRECT_DLG ), FALSE, &pItem ) == SFX_ITEM_SET ) + aSet.Put( *pItem ); + + SfxAbstractTabDialog* pDlg = pFact->CreateTabDialog( RID_OFA_AUTOCORR_DLG, NULL, &aSet, NULL ); + pDlg->Execute(); + delete pDlg; + } + + break; + } + + case SID_SD_AUTOPILOT : + case SID_NEWSD : + { + SvtModuleOptions aModuleOpt; + if ( !aModuleOpt.IsImpress() ) + { + ErrorBox( 0, ResId( RID_ERRBOX_MODULENOTINSTALLED, *GetOffResManager_Impl() )).Execute(); + return; + } + + Reference< com::sun::star::lang::XMultiServiceFactory > xORB = ::comphelper::getProcessServiceFactory(); + Reference< com::sun::star::frame::XDispatchProvider > xProv( + xORB->createInstance( ::rtl::OUString::createFromAscii("com.sun.star.drawing.ModuleDispatcher")), UNO_QUERY ); + + if ( xProv.is() ) + { + ::rtl::OUString aCmd = ::rtl::OUString::createFromAscii( GetInterface()->GetSlot( rReq.GetSlot() )->GetUnoName() ); + Reference< com::sun::star::frame::XDispatchHelper > xHelper( + xORB->createInstance( ::rtl::OUString::createFromAscii("com.sun.star.frame.DispatchHelper")), UNO_QUERY ); + if ( xHelper.is() ) + { + Sequence < com::sun::star::beans::PropertyValue > aSeq; + if ( rReq.GetArgs() ) + TransformItems( rReq.GetSlot(), *rReq.GetArgs(), aSeq ); + Any aResult = xHelper->executeDispatch( xProv, aCmd, ::rtl::OUString(), 0, aSeq ); + ::com::sun::star::frame::DispatchResultEvent aEvent; + sal_Bool bSuccess = ( + (aResult >>= aEvent) && + (aEvent.State == ::com::sun::star::frame::DispatchResultState::SUCCESS) + ); + rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), bSuccess ) ); + } + } + } + break; + + case FN_LABEL : + case FN_BUSINESS_CARD : + case FN_XFORMS_INIT : + { + Reference< com::sun::star::lang::XMultiServiceFactory > xORB = ::comphelper::getProcessServiceFactory(); + Reference< com::sun::star::frame::XDispatchProvider > xProv( + xORB->createInstance( ::rtl::OUString::createFromAscii("com.sun.star.text.ModuleDispatcher")), UNO_QUERY ); + + if ( xProv.is() ) + { + ::rtl::OUString aCmd = ::rtl::OUString::createFromAscii( GetInterface()->GetSlot( rReq.GetSlot() )->GetUnoName() ); + Reference< com::sun::star::frame::XDispatchHelper > xHelper( + xORB->createInstance( ::rtl::OUString::createFromAscii("com.sun.star.frame.DispatchHelper")), UNO_QUERY ); + if ( xHelper.is() ) + { + Sequence < com::sun::star::beans::PropertyValue > aSeq; + if ( rReq.GetArgs() ) + TransformItems( rReq.GetSlot(), *rReq.GetArgs(), aSeq ); + Any aResult = xHelper->executeDispatch( xProv, aCmd, ::rtl::OUString(), 0, aSeq ); + ::com::sun::star::frame::DispatchResultEvent aEvent; + sal_Bool bSuccess = ( + (aResult >>= aEvent) && + (aEvent.State == ::com::sun::star::frame::DispatchResultState::SUCCESS) + ); + rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), bSuccess ) ); + } + } + } + break; + + case SID_ADDRESS_DATA_SOURCE: + { + ::rtl::OUString sDialogServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.dialogs.AddressBookSourcePilot" ) ); + try + { + Reference< com::sun::star::lang::XMultiServiceFactory > xORB = ::comphelper::getProcessServiceFactory(); + Reference< com::sun::star::ui::dialogs::XExecutableDialog > xDialog; + if (xORB.is()) + xDialog = Reference< com::sun::star::ui::dialogs::XExecutableDialog >(xORB->createInstance(sDialogServiceName), UNO_QUERY); + if (xDialog.is()) + xDialog->execute(); + else + ShowServiceNotAvailableError(NULL, sDialogServiceName, TRUE); + } + catch(::com::sun::star::uno::Exception&) + { + } + } + break; + + case SID_COMP_BIBLIOGRAPHY: + { + SfxStringItem aURL(SID_FILE_NAME, String::CreateFromAscii(".component:Bibliography/View1")); + SfxStringItem aRef(SID_REFERER, String::CreateFromAscii("private:user")); + SfxStringItem aTarget(SID_TARGETNAME, String::CreateFromAscii("_blank")); + SfxViewFrame::Current()->GetDispatcher()->Execute( SID_OPENDOC, SFX_CALLMODE_ASYNCHRON, &aURL, &aRef, &aTarget, 0L); + } + break; + } +} + +void SfxApplication::OfaState_Impl(SfxItemSet &rSet) +{ + const USHORT *pRanges = rSet.GetRanges(); + DBG_ASSERT(pRanges && *pRanges, "Set ohne Bereich"); + while ( *pRanges ) + { + for(USHORT nWhich = *pRanges++; nWhich <= *pRanges; ++nWhich) + { + switch(nWhich) + { + case SID_ONLINE_REGISTRATION: + { + ::utl::RegOptions aOptions; + if ( !aOptions.allowMenu() ) + rSet.DisableItem( SID_ONLINE_REGISTRATION ); + } + break; + } + } + } + + SvtModuleOptions aModuleOpt; + + if( !aModuleOpt.IsWriter()) + { + rSet.DisableItem( FN_LABEL ); + rSet.DisableItem( FN_BUSINESS_CARD ); + rSet.DisableItem( FN_XFORMS_INIT ); + } + + if ( !aModuleOpt.IsImpress() ) + rSet.DisableItem( SID_SD_AUTOPILOT ); +} diff --git a/sfx2/source/appl/appuno.cxx b/sfx2/source/appl/appuno.cxx new file mode 100644 index 000000000000..b0aae115aa9b --- /dev/null +++ b/sfx2/source/appl/appuno.cxx @@ -0,0 +1,2351 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" +#if defined(_MSC_VER) && (_MSC_VER >= 1300) +#pragma warning( disable : 4290 ) +#endif +#include <com/sun/star/document/UpdateDocMode.hpp> + +#include "sal/config.h" + +#include <sfx2/appuno.hxx> +#include "appbaslib.hxx" + +#include "sfx2/dllapi.h" + +#include <basic/sbx.hxx> +#include <svl/itempool.hxx> +#include <svl/rectitem.hxx> +#include <tools/debug.hxx> +#include <tools/wldcrd.hxx> + +#include <tools/urlobj.hxx> +#include <tools/config.hxx> +#include <basic/sbxmeth.hxx> +#include <basic/sbmeth.hxx> +#include <basic/sbxobj.hxx> +#include <basic/sberrors.hxx> +#include <basic/basmgr.hxx> +#ifndef _BASIC_SBUNO_HXX +#include <basic/sbuno.hxx> +#endif + +#include <basic/sbxcore.hxx> +#include <svl/ownlist.hxx> +#include <svl/lckbitem.hxx> +#include <svl/stritem.hxx> +#include <svl/slstitm.hxx> +#include <svl/intitem.hxx> +#include <svl/eitem.hxx> +#include <com/sun/star/task/XStatusIndicatorFactory.hpp> +#include <com/sun/star/task/XInteractionHandler.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/frame/XFrameActionListener.hpp> +#include <com/sun/star/frame/XComponentLoader.hpp> +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/frame/FrameActionEvent.hpp> +#include <com/sun/star/frame/FrameAction.hpp> +#include <com/sun/star/container/XContainer.hpp> +#include <com/sun/star/container/XIndexContainer.hpp> +#include <com/sun/star/container/XNameReplace.hpp> +#include <com/sun/star/container/XContainerListener.hpp> +#include <com/sun/star/container/XSet.hpp> +#include <com/sun/star/container/ContainerEvent.hpp> +#include <com/sun/star/container/XIndexReplace.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/awt/XTopWindow.hpp> +#include <com/sun/star/awt/XWindow.hpp> +#include <com/sun/star/awt/PosSize.hpp> +#include <com/sun/star/registry/RegistryValueType.hpp> +#include <comphelper/processfactory.hxx> +#include <com/sun/star/awt/PosSize.hpp> +#include <com/sun/star/awt/XButton.hpp> +#include <com/sun/star/frame/DispatchResultEvent.hpp> +#include <com/sun/star/frame/DispatchResultState.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/document/MacroExecMode.hpp> +#include <com/sun/star/ucb/XContent.hpp> + +#include <tools/cachestr.hxx> +#include <osl/mutex.hxx> +#include <comphelper/sequence.hxx> +#include <rtl/ustrbuf.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::ucb; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::registry; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::io; + +#ifndef GCC +#endif + +#include "sfxtypes.hxx" +#include <sfx2/sfxuno.hxx> +#include <sfx2/app.hxx> +#include <sfx2/sfxsids.hrc> +#include <sfx2/msg.hxx> +#include <sfx2/msgpool.hxx> +#include <sfx2/request.hxx> +#include <sfx2/module.hxx> +#include <sfx2/fcontnr.hxx> +#include "frmload.hxx" +#include <sfx2/frame.hxx> +#include "sfxbasic.hxx" +#include <sfx2/objsh.hxx> +#include <sfx2/objuno.hxx> +#include <sfx2/unoctitm.hxx> +#include <sfx2/dispatch.hxx> +#include "doctemplates.hxx" +#include "shutdownicon.hxx" +#include "objshimp.hxx" +#include "fltoptint.hxx" +#include <sfx2/docfile.hxx> +#include <sfx2/sfxbasecontroller.hxx> +#include "brokenpackageint.hxx" +#include "eventsupplier.hxx" +#include "xpackcreator.hxx" +// #include "applet.hxx" +#include "plugin.hxx" +#include "iframe.hxx" +#include <ownsubfilterservice.hxx> +#include "SfxDocumentMetaData.hxx" + + +#define FRAMELOADER_SERVICENAME "com.sun.star.frame.FrameLoader" +#define PROTOCOLHANDLER_SERVICENAME "com.sun.star.frame.ProtocolHandler" + +static char const sTemplateRegionName[] = "TemplateRegionName"; +static char const sTemplateName[] = "TemplateName"; +static char const sAsTemplate[] = "AsTemplate"; +static char const sOpenNewView[] = "OpenNewView"; +static char const sViewId[] = "ViewId"; +static char const sPluginMode[] = "PluginMode"; +static char const sReadOnly[] = "ReadOnly"; +static char const sStartPresentation[] = "StartPresentation"; +static char const sFrameName[] = "FrameName"; +static char const sMediaType[] = "MediaType"; +static char const sPostData[] = "PostData"; +static char const sCharacterSet[] = "CharacterSet"; +static char const sInputStream[] = "InputStream"; +static char const sStream[] = "Stream"; +static char const sOutputStream[] = "OutputStream"; +static char const sHidden[] = "Hidden"; +static char const sPreview[] = "Preview"; +static char const sViewOnly[] = "ViewOnly"; +static char const sDontEdit[] = "DontEdit"; +static char const sSilent[] = "Silent"; +static char const sJumpMark[] = "JumpMark"; +static char const sFileName[] = "FileName"; +static char const sSalvageURL[] = "SalvagedFile"; +static char const sStatusInd[] = "StatusIndicator"; +static char const sModel[] = "Model"; +static char const sFrame[] = "Frame"; +static char const sViewData[] = "ViewData"; +static char const sFilterData[] = "FilterData"; +static char const sSelectionOnly[] = "SelectionOnly"; +static char const sFilterFlags[] = "FilterFlags"; +static char const sMacroExecMode[] = "MacroExecutionMode"; +static char const sUpdateDocMode[] = "UpdateDocMode"; +static char const sMinimized[] = "Minimized"; +static char const sInteractionHdl[] = "InteractionHandler"; +static char const sUCBContent[] = "UCBContent"; +static char const sRepairPackage[] = "RepairPackage"; +static char const sDocumentTitle[] = "DocumentTitle"; +static char const sComponentData[] = "ComponentData"; +static char const sComponentContext[] = "ComponentContext"; +static char const sDocumentBaseURL[] = "DocumentBaseURL"; +static char const sHierarchicalDocumentName[] = "HierarchicalDocumentName"; +static char const sCopyStreamIfPossible[] = "CopyStreamIfPossible"; +static char const sNoAutoSave[] = "NoAutoSave"; +static char const sFolderName[] = "FolderName"; +static char const sUseSystemDialog[] = "UseSystemDialog"; +static char const sStandardDir[] = "StandardDir"; +static char const sBlackList[] = "BlackList"; +static char const sModifyPasswordInfo[] = "ModifyPasswordInfo"; + +void TransformParameters( sal_uInt16 nSlotId, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue>& rArgs, SfxAllItemSet& rSet, const SfxSlot* pSlot ) +{ + if ( !pSlot ) + pSlot = SFX_SLOTPOOL().GetSlot( nSlotId ); + + if ( !pSlot ) + return; + + if ( nSlotId == SID_OPENURL ) + nSlotId = SID_OPENDOC; + if ( nSlotId == SID_SAVEASURL ) + nSlotId = SID_SAVEASDOC; + + sal_Int32 nCount = rArgs.getLength(); + if ( !nCount ) + return; + + const ::com::sun::star::beans::PropertyValue* pPropsVal = rArgs.getConstArray(); + if ( !pSlot->IsMode(SFX_SLOT_METHOD) ) + { + // slot is a property + const SfxType* pType = pSlot->GetType(); + SfxPoolItem* pItem = pType->CreateItem(); + if ( !pItem ) + { +#ifdef DBG_UTIL + ByteString aStr( "No creator method for item: "); + aStr += ByteString::CreateFromInt32( nSlotId ); + DBG_ERROR( aStr.GetBuffer() ); +#endif + return; + } + + USHORT nWhich = rSet.GetPool()->GetWhich(nSlotId); + BOOL bConvertTwips = ( rSet.GetPool()->GetMetric( nWhich ) == SFX_MAPUNIT_TWIP ); + pItem->SetWhich( nWhich ); + USHORT nSubCount = pType->nAttribs; + + const ::com::sun::star::beans::PropertyValue& rProp = pPropsVal[0]; + String aName = rProp.Name; + if ( nCount == 1 && aName.CompareToAscii( pSlot->pUnoName ) == COMPARE_EQUAL ) + { + // there is only one parameter and its name matches the name of the property, + // so it's either a simple property or a complex property in one single UNO struct + if( pItem->PutValue( rProp.Value, bConvertTwips ? CONVERT_TWIPS : 0 ) ) + // only use successfully converted items + rSet.Put( *pItem ); +#ifdef DBG_UTIL + else + { + ByteString aStr( "Property not convertable: "); + aStr += pSlot->pUnoName; + DBG_ERROR( aStr.GetBuffer() ); + } +#endif + } +#ifdef DBG_UTIL + else if ( nSubCount == 0 ) + { + // for a simple property there can be only one parameter and its name *must* match + ByteString aStr( "Property name does not match: "); + aStr += ByteString( aName, RTL_TEXTENCODING_UTF8 ); + DBG_ERROR( aStr.GetBuffer() ); + } +#endif + else + { + // there is more than one parameter and the property is a complex one +#ifdef DBG_UTIL + // if the dispatch API is used for UI purposes or from the testtool, + // it is possible to skip some or all arguments, + // but it indicates an error for macro recording; + // so this should be notified as a warning only + if ( nCount != nSubCount ) + { + ByteString aStr( "MacroPlayer: wrong number of parameters for slot: "); + aStr += ByteString::CreateFromInt32( nSlotId ); + DBG_WARNING( aStr.GetBuffer() ); + } +#endif + // complex property; collect sub items from the parameter set and reconstruct complex item + USHORT nFound=0; + for ( sal_uInt16 n=0; n<nCount; n++ ) + { + const ::com::sun::star::beans::PropertyValue& rPropValue = pPropsVal[n]; + USHORT nSub; + for ( nSub=0; nSub<nSubCount; nSub++ ) + { + // search sub item by name + ByteString aStr( pSlot->pUnoName ); + aStr += '.'; + aStr += ByteString( pType->aAttrib[nSub].pName ); + const char* pName = aStr.GetBuffer(); + if ( rPropValue.Name.compareToAscii( pName ) == COMPARE_EQUAL ) + { + BYTE nSubId = (BYTE) (sal_Int8) pType->aAttrib[nSub].nAID; + if ( bConvertTwips ) + nSubId |= CONVERT_TWIPS; + if ( pItem->PutValue( rPropValue.Value, nSubId ) ) + nFound++; +#ifdef DBG_UTIL + else + { + ByteString aDbgStr( "Property not convertable: "); + aDbgStr += pSlot->pUnoName; + DBG_ERROR( aDbgStr.GetBuffer() ); + } +#endif + break; + } + } + +#ifdef DBG_UTIL + if ( nSub >= nSubCount ) + { + // there was a parameter with a name that didn't match to any of the members + ByteString aStr( "Property name does not match: "); + aStr += ByteString( String(rPropValue.Name), RTL_TEXTENCODING_UTF8 ); + DBG_ERROR( aStr.GetBuffer() ); + } +#endif + } + + // at least one part of the complex item must be present; other parts can have default values + if ( nFound > 0 ) + rSet.Put( *pItem ); + } + + delete pItem; + } + else if ( nCount ) + { +#ifdef DBG_UTIL + // detect parameters that don't match to any formal argument or one of its members + sal_Int32 nFoundArgs = 0; +#endif + // slot is a method + for ( sal_uInt16 nArgs=0; nArgs<pSlot->nArgDefCount; nArgs++ ) + { + const SfxFormalArgument &rArg = pSlot->GetFormalArgument( nArgs ); + SfxPoolItem* pItem = rArg.CreateItem(); + if ( !pItem ) + { +#ifdef DBG_UTIL + ByteString aStr( "No creator method for argument: "); + aStr += rArg.pName; + DBG_ERROR( aStr.GetBuffer() ); +#endif + return; + } + + USHORT nWhich = rSet.GetPool()->GetWhich(rArg.nSlotId); + BOOL bConvertTwips = ( rSet.GetPool()->GetMetric( nWhich ) == SFX_MAPUNIT_TWIP ); + pItem->SetWhich( nWhich ); + const SfxType* pType = rArg.pType; + USHORT nSubCount = pType->nAttribs; + if ( nSubCount == 0 ) + { + // "simple" (base type) argument + for ( sal_uInt16 n=0; n<nCount; n++ ) + { + const ::com::sun::star::beans::PropertyValue& rProp = pPropsVal[n]; + String aName = rProp.Name; + if ( aName.CompareToAscii(rArg.pName) == COMPARE_EQUAL ) + { +#ifdef DBG_UTIL + ++nFoundArgs; +#endif + if( pItem->PutValue( rProp.Value ) ) + // only use successfully converted items + rSet.Put( *pItem ); +#ifdef DBG_UTIL + else + { + ByteString aStr( "Property not convertable: "); + aStr += rArg.pName; + DBG_ERROR( aStr.GetBuffer() ); + } +#endif + break; + } + } + } + else + { + // complex argument, could be passed in one struct + BOOL bAsWholeItem = FALSE; + for ( sal_uInt16 n=0; n<nCount; n++ ) + { + const ::com::sun::star::beans::PropertyValue& rProp = pPropsVal[n]; + String aName = rProp.Name; + if ( aName.CompareToAscii(rArg.pName) == COMPARE_EQUAL ) + { + bAsWholeItem = TRUE; +#ifdef DBG_UTIL + ++nFoundArgs; +#endif + if( pItem->PutValue( rProp.Value ) ) + // only use successfully converted items + rSet.Put( *pItem ); +#ifdef DBG_UTIL + else + { + ByteString aStr( "Property not convertable: "); + aStr += rArg.pName; + DBG_ERROR( aStr.GetBuffer() ); + } +#endif + } + } + + if ( !bAsWholeItem ) + { + // complex argument; collect sub items from argument array and reconstruct complex item + // only put item if at least one member was found and had the correct type + // (is this a good idea?! Should we ask for *all* members?) + BOOL bRet = FALSE; + for ( sal_uInt16 n=0; n<nCount; n++ ) + { + const ::com::sun::star::beans::PropertyValue& rProp = pPropsVal[n]; + for ( USHORT nSub=0; nSub<nSubCount; nSub++ ) + { + // search sub item by name + ByteString aStr( rArg.pName ); + aStr += '.'; + aStr += pType->aAttrib[nSub].pName; + const char* pName = aStr.GetBuffer(); + if ( rProp.Name.compareToAscii( pName ) == COMPARE_EQUAL ) + { + // at least one member found ... + bRet = TRUE; +#ifdef DBG_UTIL + ++nFoundArgs; +#endif + BYTE nSubId = (BYTE) (sal_Int8) pType->aAttrib[nSub].nAID; + if ( bConvertTwips ) + nSubId |= CONVERT_TWIPS; + if (!pItem->PutValue( rProp.Value, nSubId ) ) + { + // ... but it was not convertable + bRet = FALSE; +#ifdef DBG_UTIL + ByteString aDbgStr( "Property not convertable: "); + aDbgStr += rArg.pName; + DBG_ERROR( aDbgStr.GetBuffer() ); +#endif + } + + break; + } + } + } + + if ( bRet ) + // only use successfully converted items + rSet.Put( *pItem ); + + } + } + + delete pItem; + } + + // special additional parameters for some slots not seen in the slot definitions + // Some of these slots are not considered to be used for macro recording, because they shouldn't be recorded as slots, + // but as dispatching or factory or arbitrary URLs to the frame + // Some also can use additional arguments that are not recordable (will be changed later, + // f.e. "SaveAs" shouldn't support parameters not in the slot definition!) + if ( nSlotId == SID_NEWWINDOW ) + { + for ( sal_uInt16 n=0; n<nCount; n++ ) + { + const ::com::sun::star::beans::PropertyValue& rProp = pPropsVal[n]; + rtl::OUString aName = rProp.Name; + if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sFrame)) ) + { + Reference< XFrame > xFrame; + OSL_VERIFY( rProp.Value >>= xFrame ); + rSet.Put( SfxUnoFrameItem( SID_FILLFRAME, xFrame ) ); + } + else + if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sHidden)) ) + { + sal_Bool bVal = sal_False; + if (rProp.Value >>= bVal) + rSet.Put( SfxBoolItem( SID_HIDDEN, bVal ) ); + } + } + } + else if ( nSlotId == SID_OPENDOC || nSlotId == SID_EXPORTDOC || nSlotId == SID_SAVEASDOC || nSlotId == SID_SAVEDOC || + nSlotId == SID_SAVETO || nSlotId == SID_EXPORTDOCASPDF || nSlotId == SID_DIRECTEXPORTDOCASPDF ) + { + for ( sal_uInt16 n=0; n<nCount; n++ ) + { +#ifdef DBG_UTIL + ++nFoundArgs; +#endif + const ::com::sun::star::beans::PropertyValue& rProp = pPropsVal[n]; + rtl::OUString aName = rProp.Name; + if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sModel)) ) + rSet.Put( SfxUnoAnyItem( SID_DOCUMENT, rProp.Value ) ); + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sComponentData)) ) + { + rSet.Put( SfxUnoAnyItem( SID_COMPONENTDATA, rProp.Value ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sComponentContext)) ) + { + rSet.Put( SfxUnoAnyItem( SID_COMPONENTCONTEXT, rProp.Value ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sStatusInd)) ) + { + Reference< ::com::sun::star::task::XStatusIndicator > xVal; + sal_Bool bOK = ((rProp.Value >>= xVal) && xVal.is()); + DBG_ASSERT( bOK, "invalid type for StatusIndicator" ); + if (bOK) + rSet.Put( SfxUnoAnyItem( SID_PROGRESS_STATUSBAR_CONTROL, rProp.Value ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sInteractionHdl)) ) + { + Reference< ::com::sun::star::task::XInteractionHandler > xVal; + sal_Bool bOK = ((rProp.Value >>= xVal) && xVal.is()); + DBG_ASSERT( bOK, "invalid type for InteractionHandler" ); + if (bOK) + rSet.Put( SfxUnoAnyItem( SID_INTERACTIONHANDLER, rProp.Value ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sViewData)) ) + rSet.Put( SfxUnoAnyItem( SID_VIEW_DATA, rProp.Value ) ); + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sFilterData)) ) + rSet.Put( SfxUnoAnyItem( SID_FILTER_DATA, rProp.Value ) ); + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sInputStream)) ) + { + Reference< XInputStream > xVal; + sal_Bool bOK = ((rProp.Value >>= xVal) && xVal.is()); + DBG_ASSERT( bOK, "invalid type for InputStream" ); + if (bOK) + rSet.Put( SfxUnoAnyItem( SID_INPUTSTREAM, rProp.Value ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sStream)) ) + { + Reference< XInputStream > xVal; + sal_Bool bOK = ((rProp.Value >>= xVal) && xVal.is()); + DBG_ASSERT( bOK, "invalid type for Stream" ); + if (bOK) + rSet.Put( SfxUnoAnyItem( SID_STREAM, rProp.Value ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sUCBContent)) ) + { + Reference< XContent > xVal; + sal_Bool bOK = ((rProp.Value >>= xVal) && xVal.is()); + DBG_ASSERT( bOK, "invalid type for UCBContent" ); + if (bOK) + rSet.Put( SfxUnoAnyItem( SID_CONTENT, rProp.Value ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sOutputStream)) ) + { + Reference< XOutputStream > xVal; + sal_Bool bOK = ((rProp.Value >>= xVal) && xVal.is()); + DBG_ASSERT( bOK, "invalid type for OutputStream" ); + if (bOK) + rSet.Put( SfxUnoAnyItem( SID_OUTPUTSTREAM, rProp.Value ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sPostData)) ) + { + Reference< XInputStream > xVal; + sal_Bool bOK = (rProp.Value >>= xVal); + DBG_ASSERT( bOK, "invalid type for PostData" ); + if (bOK) + rSet.Put( SfxUnoAnyItem( SID_POSTDATA, rProp.Value ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sFrame)) ) + { + Reference< XFrame > xFrame; + sal_Bool bOK = (rProp.Value >>= xFrame); + DBG_ASSERT( bOK, "invalid type for Frame" ); + if (bOK) + rSet.Put( SfxUnoFrameItem( SID_FILLFRAME, xFrame ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sAsTemplate)) ) + { + sal_Bool bVal = sal_False; + sal_Bool bOK = (rProp.Value >>= bVal); + DBG_ASSERT( bOK, "invalid type for AsTemplate" ); + if (bOK) + rSet.Put( SfxBoolItem( SID_TEMPLATE, bVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sOpenNewView)) ) + { + sal_Bool bVal = sal_False; + sal_Bool bOK = (rProp.Value >>= bVal); + DBG_ASSERT( bOK, "invalid type for OpenNewView" ); + if (bOK) + rSet.Put( SfxBoolItem( SID_OPEN_NEW_VIEW, bVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sViewId)) ) + { + sal_Int16 nVal = -1; + sal_Bool bOK = ((rProp.Value >>= nVal) && (nVal != -1)); + DBG_ASSERT( bOK, "invalid type for ViewId" ); + if (bOK) + rSet.Put( SfxUInt16Item( SID_VIEW_ID, nVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sPluginMode)) ) + { + sal_Int16 nVal = -1; + sal_Bool bOK = ((rProp.Value >>= nVal) && (nVal != -1)); + DBG_ASSERT( bOK, "invalid type for PluginMode" ); + if (bOK) + rSet.Put( SfxUInt16Item( SID_PLUGIN_MODE, nVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sReadOnly)) ) + { + sal_Bool bVal = sal_False; + sal_Bool bOK = (rProp.Value >>= bVal); + DBG_ASSERT( bOK, "invalid type for ReadOnly" ); + if (bOK) + rSet.Put( SfxBoolItem( SID_DOC_READONLY, bVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sStartPresentation)) ) + { + sal_Bool bVal = sal_False; + sal_Bool bOK = (rProp.Value >>= bVal); + DBG_ASSERT( bOK, "invalid type for StartPresentation" ); + if (bOK) + rSet.Put( SfxBoolItem( SID_DOC_STARTPRESENTATION, bVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sSelectionOnly)) ) + { + sal_Bool bVal = sal_False; + sal_Bool bOK = (rProp.Value >>= bVal); + DBG_ASSERT( bOK, "invalid type for SelectionOnly" ); + if (bOK) + rSet.Put( SfxBoolItem( SID_SELECTION, bVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sHidden)) ) + { + sal_Bool bVal = sal_False; + sal_Bool bOK = (rProp.Value >>= bVal); + DBG_ASSERT( bOK, "invalid type for Hidden" ); + if (bOK) + rSet.Put( SfxBoolItem( SID_HIDDEN, bVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sMinimized)) ) + { + sal_Bool bVal = sal_False; + sal_Bool bOK = (rProp.Value >>= bVal); + DBG_ASSERT( bOK, "invalid type for Minimized" ); + if (bOK) + rSet.Put( SfxBoolItem( SID_MINIMIZED, bVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sSilent)) ) + { + sal_Bool bVal = sal_False; + sal_Bool bOK = (rProp.Value >>= bVal); + DBG_ASSERT( bOK, "invalid type for Silent" ); + if (bOK) + rSet.Put( SfxBoolItem( SID_SILENT, bVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sPreview)) ) + { + sal_Bool bVal = sal_False; + sal_Bool bOK = (rProp.Value >>= bVal); + DBG_ASSERT( bOK, "invalid type for Preview" ); + if (bOK) + rSet.Put( SfxBoolItem( SID_PREVIEW, bVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sViewOnly)) ) + { + sal_Bool bVal = sal_False; + sal_Bool bOK = (rProp.Value >>= bVal); + DBG_ASSERT( bOK, "invalid type for ViewOnly" ); + if (bOK) + rSet.Put( SfxBoolItem( SID_VIEWONLY, bVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sDontEdit)) ) + { + sal_Bool bVal = sal_False; + sal_Bool bOK = (rProp.Value >>= bVal); + DBG_ASSERT( bOK, "invalid type for ViewOnly" ); + if (bOK) + rSet.Put( SfxBoolItem( SID_EDITDOC, !bVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sUseSystemDialog)) ) + { + sal_Bool bVal = sal_False; + sal_Bool bOK = (rProp.Value >>= bVal); + DBG_ASSERT( bOK, "invalid type for ViewOnly" ); + if (bOK) + rSet.Put( SfxBoolItem( SID_FILE_DIALOG, bVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sStandardDir)) ) + { + ::rtl::OUString sVal; + sal_Bool bOK = ((rProp.Value >>= sVal) && sVal.getLength()); + DBG_ASSERT( bOK, "invalid type or value for StanadardDir" ); + if (bOK) + rSet.Put( SfxStringItem( SID_STANDARD_DIR, sVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sBlackList)) ) + { + ::com::sun::star::uno::Sequence< ::rtl::OUString > xVal; + sal_Bool bOK = (rProp.Value >>= xVal); + DBG_ASSERT( bOK, "invalid type or value for BlackList" ); + if (bOK) + { + SfxStringListItem stringList(SID_BLACK_LIST); + stringList.SetStringList( xVal ); + rSet.Put( stringList ); + } + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sFileName)) ) + { + ::rtl::OUString sVal; + sal_Bool bOK = ((rProp.Value >>= sVal) && sVal.getLength()); + DBG_ASSERT( bOK, "invalid type or value for FileName" ); + if (bOK) + rSet.Put( SfxStringItem( SID_FILE_NAME, sVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sSalvageURL)) ) + { + ::rtl::OUString sVal; + sal_Bool bOK = (rProp.Value >>= sVal); + DBG_ASSERT( bOK, "invalid type or value for SalvageURL" ); + if (bOK) + rSet.Put( SfxStringItem( SID_DOC_SALVAGE, sVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sFolderName)) ) + { + ::rtl::OUString sVal; + sal_Bool bOK = (rProp.Value >>= sVal); + DBG_ASSERT( bOK, "invalid type or value for SalvageURL" ); + if (bOK) + rSet.Put( SfxStringItem( SID_PATH, sVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sFrameName)) ) + { + ::rtl::OUString sVal; + sal_Bool bOK = (rProp.Value >>= sVal); + DBG_ASSERT( bOK, "invalid type for FrameName" ); + if (bOK && sVal.getLength()) + rSet.Put( SfxStringItem( SID_TARGETNAME, sVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sMediaType)) ) + { + ::rtl::OUString sVal; + sal_Bool bOK = ((rProp.Value >>= sVal) && sVal.getLength()); + DBG_ASSERT( bOK, "invalid type or value for MediaType" ); + if (bOK) + rSet.Put( SfxStringItem( SID_CONTENTTYPE, sVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sTemplateName)) ) + { + ::rtl::OUString sVal; + sal_Bool bOK = ((rProp.Value >>= sVal) && sVal.getLength()); + DBG_ASSERT( bOK, "invalid type or value for TemplateName" ); + if (bOK) + rSet.Put( SfxStringItem( SID_TEMPLATE_NAME, sVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sTemplateRegionName)) ) + { + ::rtl::OUString sVal; + sal_Bool bOK = ((rProp.Value >>= sVal) && sVal.getLength()); + DBG_ASSERT( bOK, "invalid type or value for TemplateRegionName" ); + if (bOK) + rSet.Put( SfxStringItem( SID_TEMPLATE_REGIONNAME, sVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sJumpMark)) ) + { + ::rtl::OUString sVal; + sal_Bool bOK = ((rProp.Value >>= sVal) && sVal.getLength()); + DBG_ASSERT( bOK, "invalid type or value for JumpMark" ); + if (bOK) + rSet.Put( SfxStringItem( SID_JUMPMARK, sVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sCharacterSet)) ) + { + ::rtl::OUString sVal; + sal_Bool bOK = ((rProp.Value >>= sVal) && sVal.getLength()); + DBG_ASSERT( bOK, "invalid type or value for CharacterSet" ); + if (bOK) + rSet.Put( SfxStringItem( SID_CHARSET, sVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sFilterFlags)) ) + { + ::rtl::OUString sVal; + sal_Bool bOK = ((rProp.Value >>= sVal) && sVal.getLength()); + DBG_ASSERT( bOK, "invalid type or value for FilterFlags" ); + if (bOK) + rSet.Put( SfxStringItem( SID_FILE_FILTEROPTIONS, sVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sMacroExecMode)) ) + { + sal_Int16 nVal =-1; + sal_Bool bOK = ((rProp.Value >>= nVal) && (nVal != -1)); + DBG_ASSERT( bOK, "invalid type for MacroExecMode" ); + if (bOK) + rSet.Put( SfxUInt16Item( SID_MACROEXECMODE, nVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sUpdateDocMode)) ) + { + sal_Int16 nVal =-1; + sal_Bool bOK = ((rProp.Value >>= nVal) && (nVal != -1)); + DBG_ASSERT( bOK, "invalid type for UpdateDocMode" ); + if (bOK) + rSet.Put( SfxUInt16Item( SID_UPDATEDOCMODE, nVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sRepairPackage)) ) + { + sal_Bool bVal = sal_False; + sal_Bool bOK = (rProp.Value >>= bVal); + DBG_ASSERT( bOK, "invalid type for RepairPackage" ); + if (bOK) + rSet.Put( SfxBoolItem( SID_REPAIRPACKAGE, bVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sDocumentTitle)) ) + { + ::rtl::OUString sVal; + sal_Bool bOK = ((rProp.Value >>= sVal) && sVal.getLength()); + DBG_ASSERT( bOK, "invalid type or value for DocumentTitle" ); + if (bOK) + rSet.Put( SfxStringItem( SID_DOCINFO_TITLE, sVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sDocumentBaseURL)) ) + { + ::rtl::OUString sVal; + // the base url can be set to empty ( for embedded objects for example ) + sal_Bool bOK = (rProp.Value >>= sVal); + DBG_ASSERT( bOK, "invalid type or value for DocumentBaseURL" ); + if (bOK) + rSet.Put( SfxStringItem( SID_DOC_BASEURL, sVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sHierarchicalDocumentName)) ) + { + ::rtl::OUString sVal; + sal_Bool bOK = ((rProp.Value >>= sVal) && sVal.getLength()); + DBG_ASSERT( bOK, "invalid type or value for HierarchicalDocumentName" ); + if (bOK) + rSet.Put( SfxStringItem( SID_DOC_HIERARCHICALNAME, sVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sCopyStreamIfPossible)) ) + { + sal_Bool bVal = sal_False; + sal_Bool bOK = (rProp.Value >>= bVal); + DBG_ASSERT( bOK, "invalid type for CopyStreamIfPossible" ); + if (bOK) + rSet.Put( SfxBoolItem( SID_COPY_STREAM_IF_POSSIBLE, bVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sNoAutoSave)) ) + { + sal_Bool bVal = sal_False; + sal_Bool bOK = (rProp.Value >>= bVal); + DBG_ASSERT( bOK, "invalid type for NoAutoSave" ); + if (bOK) + rSet.Put( SfxBoolItem( SID_NOAUTOSAVE, bVal ) ); + } + else if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(sModifyPasswordInfo)) ) + { + rSet.Put( SfxUnoAnyItem( SID_MODIFYPASSWORDINFO, rProp.Value ) ); + } +#ifdef DBG_UTIL + else + --nFoundArgs; +#endif + } + } + // --> PB 2007-12-09 #i83757# + else + { + // transform parameter "OptionsPageURL" of slot "OptionsTreeDialog" + String sSlotName( DEFINE_CONST_UNICODE( "OptionsTreeDialog" ) ); + String sPropName( DEFINE_CONST_UNICODE( "OptionsPageURL" ) ); + if ( sSlotName.EqualsAscii( pSlot->pUnoName ) ) + { + for ( sal_uInt16 n = 0; n < nCount; ++n ) + { + const PropertyValue& rProp = pPropsVal[n]; + String sName( rProp.Name ); + if ( sName == sPropName ) + { + ::rtl::OUString sURL; + if ( rProp.Value >>= sURL ) + rSet.Put( SfxStringItem( SID_OPTIONS_PAGEURL, sURL ) ); + break; + } + } + } + } + // <-- +#ifdef DB_UTIL + if ( nFoundArgs == nCount ) + { + // except for the "special" slots: assure that every argument was convertable + ByteString aStr( "MacroPlayer: Some properties didn't match to any formal argument for slot: "); + aStr += pSlot->pUnoName; + DBG_WARNING( aStr.GetBuffer() ); + } +#endif + } +} + +void TransformItems( sal_uInt16 nSlotId, const SfxItemSet& rSet, ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue>& rArgs, const SfxSlot* pSlot ) +{ + if ( !pSlot ) + pSlot = SFX_SLOTPOOL().GetSlot( nSlotId ); + + if ( !pSlot) + return; + + if ( nSlotId == SID_OPENURL ) + nSlotId = SID_OPENDOC; + if ( nSlotId == SID_SAVEASURL ) + nSlotId = SID_SAVEASDOC; + + // find number of properties to avoid permanent reallocations in the sequence + sal_Int32 nProps=0; + +#ifdef DBG_UTIL + // trace number of items and compare with number of properties for debugging purposes + sal_Int32 nItems=0; +#endif + + const SfxType *pType = pSlot->GetType(); + if ( !pSlot->IsMode(SFX_SLOT_METHOD) ) + { + // slot is a property + USHORT nWhich = rSet.GetPool()->GetWhich(nSlotId); + if ( rSet.GetItemState( nWhich ) == SFX_ITEM_SET ) //??? + { + USHORT nSubCount = pType->nAttribs; + if ( nSubCount ) + // it's a complex property, we want it split into simple types + // so we expect to get as many items as we have (sub) members + nProps = nSubCount; + else + // simple property: we expect to get exactly one item + nProps++; + } +#ifdef DBG_UTIL + else + { + // we will not rely on the "toggle" ability of some property slots + ByteString aStr( "Processing property slot without argument: "); + aStr += ByteString::CreateFromInt32( nSlotId ); + DBG_ERROR( aStr.GetBuffer() ); + } +#endif + +#ifdef DBG_UTIL + nItems++; +#endif + } + else + { + // slot is a method + USHORT nFormalArgs = pSlot->GetFormalArgumentCount(); + for ( USHORT nArg=0; nArg<nFormalArgs; ++nArg ) + { + // check every formal argument of the method + const SfxFormalArgument &rArg = pSlot->GetFormalArgument( nArg ); + USHORT nWhich = rSet.GetPool()->GetWhich( rArg.nSlotId ); + if ( rSet.GetItemState( nWhich ) == SFX_ITEM_SET ) //??? + { + USHORT nSubCount = rArg.pType->nAttribs; + if ( nSubCount ) + // argument has a complex type, we want it split into simple types + // so for this argument we expect to get as many items as we have (sub) members + nProps += nSubCount; + else + // argument of simple type: we expect to get exactly one item for it + nProps++; +#ifdef DBG_UTIL + nItems++; +#endif + } + } + + // special treatment for slots that are *not* meant to be recorded as slots (except SaveAs/To) + if ( nSlotId == SID_OPENDOC || nSlotId == SID_EXPORTDOC || nSlotId == SID_SAVEASDOC || nSlotId == SID_SAVEDOC || + nSlotId == SID_SAVETO || nSlotId == SID_EXPORTDOCASPDF || nSlotId == SID_DIRECTEXPORTDOCASPDF ) + { + sal_Int32 nAdditional=0; + if ( rSet.GetItemState( SID_PROGRESS_STATUSBAR_CONTROL ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_INTERACTIONHANDLER ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_DOC_SALVAGE ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_PATH ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_FILE_DIALOG ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_STANDARD_DIR ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_BLACK_LIST ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_CONTENT ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_INPUTSTREAM ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_STREAM ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_OUTPUTSTREAM ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_TEMPLATE ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_OPEN_NEW_VIEW ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_VIEW_ID ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_VIEW_DATA ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_FILTER_DATA ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_PLUGIN_MODE ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_DOC_READONLY ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_DOC_STARTPRESENTATION ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_SELECTION ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_CONTENTTYPE ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_POSTDATA ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_FILLFRAME ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_CHARSET ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_TARGETNAME ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_TEMPLATE_NAME ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_TEMPLATE_REGIONNAME ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_HIDDEN ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_MINIMIZED ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_PREVIEW ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_VIEWONLY ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_EDITDOC ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_SILENT ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_JUMPMARK ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_DOCUMENT ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_MACROEXECMODE ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_UPDATEDOCMODE ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_REPAIRPACKAGE ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_DOCINFO_TITLE ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_COMPONENTDATA ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_COMPONENTCONTEXT ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_DOC_BASEURL ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_DOC_HIERARCHICALNAME ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_COPY_STREAM_IF_POSSIBLE ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_NOAUTOSAVE ) == SFX_ITEM_SET ) + nAdditional++; + if ( rSet.GetItemState( SID_MODIFYPASSWORDINFO ) == SFX_ITEM_SET ) + nAdditional++; + + // consider additional arguments + nProps += nAdditional; +#ifdef DBG_UTIL + nItems += nAdditional; +#endif + } + } + +#ifdef DBG_UTIL + // now check the itemset: is there any item that is not convertable using the list of formal arguments + // or the table of additional items?! + if ( rSet.Count() != nItems ) + { + // detect unknown item and present error message + const USHORT *pRanges = rSet.GetRanges(); + while ( *pRanges ) + { + for(USHORT nId = *pRanges++; nId <= *pRanges; ++nId) + { + if ( rSet.GetItemState(nId) < SFX_ITEM_SET ) //??? + // not really set + continue; + + if ( !pSlot->IsMode(SFX_SLOT_METHOD) && nId == rSet.GetPool()->GetWhich( pSlot->GetSlotId() ) ) + continue; + + USHORT nFormalArgs = pSlot->GetFormalArgumentCount(); + USHORT nArg; + for ( nArg=0; nArg<nFormalArgs; ++nArg ) + { + const SfxFormalArgument &rArg = pSlot->GetFormalArgument( nArg ); + USHORT nWhich = rSet.GetPool()->GetWhich( rArg.nSlotId ); + if ( nId == nWhich ) + break; + } + + if ( nArg<nFormalArgs ) + continue; + + if ( nSlotId == SID_OPENDOC || nSlotId == SID_EXPORTDOC || nSlotId == SID_SAVEASDOC || nSlotId == SID_SAVEDOC || + nSlotId == SID_SAVETO || nSlotId == SID_EXPORTDOCASPDF || nSlotId == SID_DIRECTEXPORTDOCASPDF ) + { + if ( nId == SID_DOCFRAME ) + continue; + if ( nId == SID_PROGRESS_STATUSBAR_CONTROL ) + continue; + if ( nId == SID_INTERACTIONHANDLER ) + continue; + if ( nId == SID_VIEW_DATA ) + continue; + if ( nId == SID_FILTER_DATA ) + continue; + if ( nId == SID_DOCUMENT ) + continue; + if ( nId == SID_CONTENT ) + continue; + if ( nId == SID_INPUTSTREAM ) + continue; + if ( nId == SID_STREAM ) + continue; + if ( nId == SID_OUTPUTSTREAM ) + continue; + if ( nId == SID_POSTDATA ) + continue; + if ( nId == SID_FILLFRAME ) + continue; + if ( nId == SID_TEMPLATE ) + continue; + if ( nId == SID_OPEN_NEW_VIEW ) + continue; + if ( nId == SID_VIEW_ID ) + continue; + if ( nId == SID_PLUGIN_MODE ) + continue; + if ( nId == SID_DOC_READONLY ) + continue; + if ( nId == SID_DOC_STARTPRESENTATION ) + continue; + if ( nId == SID_SELECTION ) + continue; + if ( nId == SID_HIDDEN ) + continue; + if ( nId == SID_MINIMIZED ) + continue; + if ( nId == SID_SILENT ) + continue; + if ( nId == SID_PREVIEW ) + continue; + if ( nId == SID_VIEWONLY ) + continue; + if ( nId == SID_EDITDOC ) + continue; + if ( nId == SID_TARGETNAME ) + continue; + if ( nId == SID_DOC_SALVAGE ) + continue; + if ( nId == SID_PATH ) + continue; + if ( nId == SID_FILE_DIALOG ) + continue; + if ( nId == SID_STANDARD_DIR ) + continue; + if ( nId == SID_BLACK_LIST ) + continue; + if ( nId == SID_CONTENTTYPE ) + continue; + if ( nId == SID_TEMPLATE_NAME ) + continue; + if ( nId == SID_TEMPLATE_REGIONNAME ) + continue; + if ( nId == SID_JUMPMARK ) + continue; + if ( nId == SID_CHARSET ) + continue; + if ( nId == SID_MACROEXECMODE ) + continue; + if ( nId == SID_UPDATEDOCMODE ) + continue; + if ( nId == SID_REPAIRPACKAGE ) + continue; + if ( nId == SID_DOCINFO_TITLE ) + continue; + if ( nId == SID_COMPONENTDATA ) + continue; + if ( nId == SID_COMPONENTCONTEXT ) + continue; + if ( nId == SID_DOC_BASEURL ) + continue; + if ( nId == SID_DOC_HIERARCHICALNAME ) + continue; + if ( nId == SID_COPY_STREAM_IF_POSSIBLE ) + continue; + if ( nId == SID_NOAUTOSAVE ) + continue; + + // used only internally + if ( nId == SID_SAVETO ) + continue; + if ( nId == SID_MODIFYPASSWORDINFO ) + continue; + } + + ByteString aDbg( "Unknown item detected: "); + aDbg += ByteString::CreateFromInt32( nId ); + DBG_ASSERT( nArg<nFormalArgs, aDbg.GetBuffer() ); + } + } + } +#endif + + if ( !nProps ) + return; + + // convert every item into a property + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue> aSequ( nProps ); + ::com::sun::star::beans::PropertyValue *pValue = aSequ.getArray(); + + sal_Int32 nActProp=0; + if ( !pSlot->IsMode(SFX_SLOT_METHOD) ) + { + // slot is a property + USHORT nWhich = rSet.GetPool()->GetWhich(nSlotId); + BOOL bConvertTwips = ( rSet.GetPool()->GetMetric( nWhich ) == SFX_MAPUNIT_TWIP ); + SFX_ITEMSET_ARG( &rSet, pItem, SfxPoolItem, nWhich, sal_False ); + if ( pItem ) //??? + { + USHORT nSubCount = pType->nAttribs; + if ( !nSubCount ) + { + //rPool.FillVariable( *pItem, *pVar, eUserMetric ); + pValue[nActProp].Name = String( String::CreateFromAscii( pSlot->pUnoName ) ) ; + if ( !pItem->QueryValue( pValue[nActProp].Value ) ) + { + ByteString aStr( "Item not convertable: "); + aStr += ByteString::CreateFromInt32(nSlotId); + DBG_ERROR( aStr.GetBuffer() ); + } + } + else + { + // complex type, add a property value for every member of the struct + for ( USHORT n=1; n<=nSubCount; ++n ) + { + //rPool.FillVariable( *pItem, *pVar, eUserMetric ); + BYTE nSubId = (BYTE) (sal_Int8) pType->aAttrib[n-1].nAID; + if ( bConvertTwips ) + nSubId |= CONVERT_TWIPS; + + DBG_ASSERT(( pType->aAttrib[n-1].nAID ) <= 127, "Member ID out of range" ); + String aName( String::CreateFromAscii( pSlot->pUnoName ) ) ; + aName += '.'; + aName += String( String::CreateFromAscii( pType->aAttrib[n-1].pName ) ) ; + pValue[nActProp].Name = aName; + if ( !pItem->QueryValue( pValue[nActProp++].Value, nSubId ) ) + { + ByteString aStr( "Sub item "); + aStr += ByteString::CreateFromInt32( pType->aAttrib[n-1].nAID ); + aStr += " not convertable in slot: "; + aStr += ByteString::CreateFromInt32(nSlotId); + DBG_ERROR( aStr.GetBuffer() ); + } + } + } + } + } + else + { + // slot is a method + USHORT nFormalArgs = pSlot->GetFormalArgumentCount(); + for ( USHORT nArg=0; nArg<nFormalArgs; ++nArg ) + { + const SfxFormalArgument &rArg = pSlot->GetFormalArgument( nArg ); + USHORT nWhich = rSet.GetPool()->GetWhich( rArg.nSlotId ); + BOOL bConvertTwips = ( rSet.GetPool()->GetMetric( nWhich ) == SFX_MAPUNIT_TWIP ); + SFX_ITEMSET_ARG( &rSet, pItem, SfxPoolItem, nWhich, sal_False ); + if ( pItem ) //??? + { + USHORT nSubCount = rArg.pType->nAttribs; + if ( !nSubCount ) + { + //rPool.FillVariable( *pItem, *pVar, eUserMetric ); + pValue[nActProp].Name = String( String::CreateFromAscii( rArg.pName ) ) ; + if ( !pItem->QueryValue( pValue[nActProp++].Value ) ) + { + ByteString aStr( "Item not convertable: "); + aStr += ByteString::CreateFromInt32(rArg.nSlotId); + DBG_ERROR( aStr.GetBuffer() ); + } + } + else + { + // complex type, add a property value for every member of the struct + for ( USHORT n = 1; n <= nSubCount; ++n ) + { + //rPool.FillVariable( rItem, *pVar, eUserMetric ); + BYTE nSubId = (BYTE) (sal_Int8) rArg.pType->aAttrib[n-1].nAID; + if ( bConvertTwips ) + nSubId |= CONVERT_TWIPS; + + DBG_ASSERT((rArg.pType->aAttrib[n-1].nAID) <= 127, "Member ID out of range" ); + String aName( String::CreateFromAscii( rArg.pName ) ) ; + aName += '.'; + aName += String( String::CreateFromAscii( rArg.pType->aAttrib[n-1].pName ) ) ; + pValue[nActProp].Name = aName; + if ( !pItem->QueryValue( pValue[nActProp++].Value, nSubId ) ) + { + ByteString aStr( "Sub item "); + aStr += ByteString::CreateFromInt32( rArg.pType->aAttrib[n-1].nAID ); + aStr += " not convertable in slot: "; + aStr += ByteString::CreateFromInt32(rArg.nSlotId); + DBG_ERROR( aStr.GetBuffer() ); + } + } + } + } + } + + if ( nSlotId == SID_OPENDOC || nSlotId == SID_EXPORTDOC || nSlotId == SID_SAVEASDOC || nSlotId == SID_SAVEDOC || + nSlotId == SID_SAVETO || nSlotId == SID_EXPORTDOCASPDF || nSlotId == SID_DIRECTEXPORTDOCASPDF ) + { + const SfxPoolItem *pItem=0; + if ( rSet.GetItemState( SID_COMPONENTDATA, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sComponentData)); + pValue[nActProp++].Value = ( ((SfxUnoAnyItem*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_COMPONENTCONTEXT, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sComponentContext)); + pValue[nActProp++].Value = ( ((SfxUnoAnyItem*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_PROGRESS_STATUSBAR_CONTROL, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sStatusInd)); + pValue[nActProp++].Value = ( ((SfxUnoAnyItem*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_INTERACTIONHANDLER, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sInteractionHdl)); + pValue[nActProp++].Value = ( ((SfxUnoAnyItem*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_VIEW_DATA, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sViewData)); + pValue[nActProp++].Value = ( ((SfxUnoAnyItem*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_FILTER_DATA, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sFilterData)); + pValue[nActProp++].Value = ( ((SfxUnoAnyItem*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_DOCUMENT, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sModel)); + pValue[nActProp++].Value = ( ((SfxUnoAnyItem*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_CONTENT, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sUCBContent)); + pValue[nActProp++].Value = ( ((SfxUnoAnyItem*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_INPUTSTREAM, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sInputStream)); + pValue[nActProp++].Value = ( ((SfxUnoAnyItem*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_STREAM, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sStream)); + pValue[nActProp++].Value = ( ((SfxUnoAnyItem*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_OUTPUTSTREAM, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sOutputStream)); + pValue[nActProp++].Value = ( ((SfxUnoAnyItem*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_POSTDATA, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sPostData)); + pValue[nActProp++].Value = ( ((SfxUnoAnyItem*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_FILLFRAME, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sFrame)); + if ( pItem->ISA( SfxUsrAnyItem ) ) + { + OSL_ENSURE( false, "TransformItems: transporting an XFrame via an SfxUsrAnyItem is not deprecated!" ); + pValue[nActProp++].Value = static_cast< const SfxUsrAnyItem* >( pItem )->GetValue(); + } + else if ( pItem->ISA( SfxUnoFrameItem ) ) + pValue[nActProp++].Value <<= static_cast< const SfxUnoFrameItem* >( pItem )->GetFrame(); + else + OSL_ENSURE( false, "TransformItems: invalid item type for SID_FILLFRAME!" ); + } + if ( rSet.GetItemState( SID_TEMPLATE, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sAsTemplate)); + pValue[nActProp++].Value <<= ( ((SfxBoolItem*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_OPEN_NEW_VIEW, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sOpenNewView)); + pValue[nActProp++].Value <<= ( ((SfxBoolItem*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_VIEW_ID, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sViewId)); + pValue[nActProp++].Value <<= ( (sal_Int16) ((SfxUInt16Item*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_PLUGIN_MODE, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sPluginMode)); + pValue[nActProp++].Value <<= ( (sal_Int16) ((SfxUInt16Item*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_DOC_READONLY, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sReadOnly)); + pValue[nActProp++].Value <<= ( ((SfxBoolItem*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_DOC_STARTPRESENTATION, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sStartPresentation)); + pValue[nActProp++].Value <<= ( ((SfxBoolItem*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_SELECTION, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sSelectionOnly)); + pValue[nActProp++].Value <<= ( ((SfxBoolItem*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_HIDDEN, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sHidden)); + pValue[nActProp++].Value <<= ( ((SfxBoolItem*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_MINIMIZED, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sMinimized)); + pValue[nActProp++].Value <<= ( ((SfxBoolItem*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_SILENT, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sSilent)); + pValue[nActProp++].Value <<= ( ((SfxBoolItem*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_PREVIEW, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sPreview)); + pValue[nActProp++].Value <<= ( ((SfxBoolItem*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_VIEWONLY, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sViewOnly)); + pValue[nActProp++].Value <<= (sal_Bool) (( ((SfxBoolItem*)pItem)->GetValue() )); + } + if ( rSet.GetItemState( SID_EDITDOC, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sDontEdit)); + pValue[nActProp++].Value <<= (sal_Bool) (!( ((SfxBoolItem*)pItem)->GetValue() )); + } + if ( rSet.GetItemState( SID_FILE_DIALOG, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sUseSystemDialog)); + pValue[nActProp++].Value <<= (sal_Bool) ( ((SfxBoolItem*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_STANDARD_DIR, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sStandardDir)); + pValue[nActProp++].Value <<= ( ::rtl::OUString(((SfxStringItem*)pItem)->GetValue()) ); + } + if ( rSet.GetItemState( SID_BLACK_LIST, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sBlackList)); + + com::sun::star::uno::Sequence< rtl::OUString > aList; + ((SfxStringListItem*)pItem)->GetStringList( aList ); + pValue[nActProp++].Value <<= aList ; + } + if ( rSet.GetItemState( SID_TARGETNAME, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sFrameName)); + pValue[nActProp++].Value <<= ( ::rtl::OUString(((SfxStringItem*)pItem)->GetValue()) ); + } + if ( rSet.GetItemState( SID_DOC_SALVAGE, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sSalvageURL)); + pValue[nActProp++].Value <<= ( ::rtl::OUString(((SfxStringItem*)pItem)->GetValue()) ); + } + if ( rSet.GetItemState( SID_PATH, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sFolderName)); + pValue[nActProp++].Value <<= ( ::rtl::OUString(((SfxStringItem*)pItem)->GetValue()) ); + } + if ( rSet.GetItemState( SID_CONTENTTYPE, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sMediaType)); + pValue[nActProp++].Value <<= ( ::rtl::OUString(((SfxStringItem*)pItem)->GetValue()) ); + } + if ( rSet.GetItemState( SID_TEMPLATE_NAME, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sTemplateName)); + pValue[nActProp++].Value <<= ( ::rtl::OUString(((SfxStringItem*)pItem)->GetValue()) ); + } + if ( rSet.GetItemState( SID_TEMPLATE_REGIONNAME, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sTemplateRegionName)); + pValue[nActProp++].Value <<= ( ::rtl::OUString(((SfxStringItem*)pItem)->GetValue()) ); + } + if ( rSet.GetItemState( SID_JUMPMARK, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sJumpMark)); + pValue[nActProp++].Value <<= ( ::rtl::OUString(((SfxStringItem*)pItem)->GetValue()) ); + } + + if ( rSet.GetItemState( SID_CHARSET, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sCharacterSet)); + pValue[nActProp++].Value <<= ( ::rtl::OUString(((SfxStringItem*)pItem)->GetValue()) ); + } + if ( rSet.GetItemState( SID_MACROEXECMODE, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sMacroExecMode)); + pValue[nActProp++].Value <<= ( (sal_Int16) ((SfxUInt16Item*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_UPDATEDOCMODE, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sUpdateDocMode)); + pValue[nActProp++].Value <<= ( (sal_Int16) ((SfxUInt16Item*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_REPAIRPACKAGE, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sRepairPackage)); + pValue[nActProp++].Value <<= ( ((SfxBoolItem*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_DOCINFO_TITLE, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sDocumentTitle)); + pValue[nActProp++].Value <<= ( ::rtl::OUString(((SfxStringItem*)pItem)->GetValue()) ); + } + if ( rSet.GetItemState( SID_DOC_BASEURL, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sDocumentBaseURL)); + pValue[nActProp++].Value <<= ( ::rtl::OUString(((SfxStringItem*)pItem)->GetValue()) ); + } + if ( rSet.GetItemState( SID_DOC_HIERARCHICALNAME, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sHierarchicalDocumentName)); + pValue[nActProp++].Value <<= ( ::rtl::OUString(((SfxStringItem*)pItem)->GetValue()) ); + } + if ( rSet.GetItemState( SID_COPY_STREAM_IF_POSSIBLE, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sCopyStreamIfPossible)); + pValue[nActProp++].Value = ( ((SfxUnoAnyItem*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_NOAUTOSAVE, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sNoAutoSave)); + pValue[nActProp++].Value <<= ( ((SfxBoolItem*)pItem)->GetValue() ); + } + if ( rSet.GetItemState( SID_MODIFYPASSWORDINFO, sal_False, &pItem ) == SFX_ITEM_SET ) + { + pValue[nActProp].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sModifyPasswordInfo)); + pValue[nActProp++].Value = ( ((SfxUnoAnyItem*)pItem)->GetValue() ); + } + } + } + + rArgs = aSequ; +} + +SFX_IMPL_XINTERFACE_5( SfxMacroLoader, OWeakObject, ::com::sun::star::frame::XDispatchProvider, ::com::sun::star::frame::XNotifyingDispatch, ::com::sun::star::frame::XDispatch, ::com::sun::star::frame::XSynchronousDispatch,::com::sun::star::lang::XInitialization ) +SFX_IMPL_XTYPEPROVIDER_5( SfxMacroLoader, ::com::sun::star::frame::XDispatchProvider, ::com::sun::star::frame::XNotifyingDispatch, ::com::sun::star::frame::XDispatch, ::com::sun::star::frame::XSynchronousDispatch,::com::sun::star::lang::XInitialization ) +SFX_IMPL_XSERVICEINFO( SfxMacroLoader, PROTOCOLHANDLER_SERVICENAME, "com.sun.star.comp.sfx2.SfxMacroLoader" ) +SFX_IMPL_SINGLEFACTORY( SfxMacroLoader ) + +void SAL_CALL SfxMacroLoader::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) +{ + Reference < XFrame > xFrame; + if ( aArguments.getLength() ) + { + aArguments[0] >>= xFrame; + m_xFrame = xFrame; + } +} + +SfxObjectShell* SfxMacroLoader::GetObjectShell_Impl() +{ + SfxObjectShell* pDocShell = NULL; + Reference < XFrame > xFrame( m_xFrame.get(), UNO_QUERY ); + if ( xFrame.is() ) + { + SfxFrame* pFrame=0; + for ( pFrame = SfxFrame::GetFirst(); pFrame; pFrame = SfxFrame::GetNext( *pFrame ) ) + { + if ( pFrame->GetFrameInterface() == xFrame ) + break; + } + + if ( pFrame ) + pDocShell = pFrame->GetCurrentDocument(); + } + + return pDocShell; +} + +// ----------------------------------------------------------------------- +::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > SAL_CALL SfxMacroLoader::queryDispatch( + const ::com::sun::star::util::URL& aURL , + const ::rtl::OUString& /*sTargetFrameName*/, + sal_Int32 /*nSearchFlags*/ ) throw( ::com::sun::star::uno::RuntimeException ) +{ + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > xDispatcher; + if(aURL.Complete.compareToAscii("macro:",6)==0) + xDispatcher = this; + return xDispatcher; +} + +// ----------------------------------------------------------------------- +::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference < ::com::sun::star::frame::XDispatch > > SAL_CALL + SfxMacroLoader::queryDispatches( const ::com::sun::star::uno::Sequence < ::com::sun::star::frame::DispatchDescriptor >& seqDescriptor ) + throw( ::com::sun::star::uno::RuntimeException ) +{ + sal_Int32 nCount = seqDescriptor.getLength(); + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference < ::com::sun::star::frame::XDispatch > > lDispatcher(nCount); + for( sal_Int32 i=0; i<nCount; ++i ) + lDispatcher[i] = this->queryDispatch( seqDescriptor[i].FeatureURL, + seqDescriptor[i].FrameName, + seqDescriptor[i].SearchFlags ); + return lDispatcher; +} + +// ----------------------------------------------------------------------- +void SAL_CALL SfxMacroLoader::dispatchWithNotification( const ::com::sun::star::util::URL& aURL , + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& lArgs , + const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchResultListener >& xListener ) + throw (::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + sal_uInt32 nPropertyCount = lArgs.getLength(); + ::rtl::OUString aReferer; + for( sal_uInt32 nProperty=0; nProperty<nPropertyCount; ++nProperty ) + { + if( lArgs[nProperty].Name == ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Referer")) ) + { + lArgs[nProperty].Value >>= aReferer; + break; + } + } + + ::com::sun::star::uno::Any aAny; + ErrCode nErr = loadMacro( aURL.Complete, aAny, GetObjectShell_Impl() ); + if( xListener.is() ) + { + // always call dispatchFinished(), because we didn't load a document but + // executed a macro instead! + ::com::sun::star::frame::DispatchResultEvent aEvent; + + aEvent.Source = static_cast< ::cppu::OWeakObject* >(this); + if( nErr == ERRCODE_NONE ) + aEvent.State = ::com::sun::star::frame::DispatchResultState::SUCCESS; + else + aEvent.State = ::com::sun::star::frame::DispatchResultState::FAILURE; + + xListener->dispatchFinished( aEvent ) ; + } +} + +::com::sun::star::uno::Any SAL_CALL SfxMacroLoader::dispatchWithReturnValue( + const ::com::sun::star::util::URL& aURL, + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& ) throw (::com::sun::star::uno::RuntimeException) +{ + ::com::sun::star::uno::Any aRet; + /*ErrCode nErr = */loadMacro( aURL.Complete, aRet, GetObjectShell_Impl() ); + return aRet; +} + +// ----------------------------------------------------------------------- +void SAL_CALL SfxMacroLoader::dispatch( const ::com::sun::star::util::URL& aURL , + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& lArgs ) + throw (::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + sal_uInt32 nPropertyCount = lArgs.getLength(); + ::rtl::OUString aReferer; + for( sal_uInt32 nProperty=0; nProperty<nPropertyCount; ++nProperty ) + { + if( lArgs[nProperty].Name == ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Referer")) ) + { + lArgs[nProperty].Value >>= aReferer; + break; + } + } + + ::com::sun::star::uno::Any aAny; + /*ErrCode nErr = */loadMacro( aURL.Complete, aAny, GetObjectShell_Impl() ); +} + +// ----------------------------------------------------------------------- +void SAL_CALL SfxMacroLoader::addStatusListener( + const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener >& , + const ::com::sun::star::util::URL& ) + throw (::com::sun::star::uno::RuntimeException) +{ + /* TODO + How we can handle different listener for further coming or currently running dispatch() jobs + without any inconsistency! + */ +} + +// ----------------------------------------------------------------------- +void SAL_CALL SfxMacroLoader::removeStatusListener( + const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener >&, + const ::com::sun::star::util::URL& ) + throw (::com::sun::star::uno::RuntimeException) +{ +} + +// ----------------------------------------------------------------------- +ErrCode SfxMacroLoader::loadMacro( const ::rtl::OUString& rURL, com::sun::star::uno::Any& rRetval, SfxObjectShell* pSh ) + throw ( ::com::sun::star::uno::RuntimeException ) +{ + SfxApplication* pApp = SFX_APP(); + pApp->EnterBasicCall(); + SfxObjectShell* pCurrent = pSh; + if ( !pCurrent ) + // all not full qualified names use the BASIC of the given or current document + pCurrent = SfxObjectShell::Current(); + + // 'macro:///lib.mod.proc(args)' => macro of App-BASIC + // 'macro://[docname|.]/lib.mod.proc(args)' => macro of current or qualified document + // 'macro://obj.method(args)' => direct API call, execute it via App-BASIC + String aMacro( rURL ); + sal_uInt16 nHashPos = aMacro.Search( '/', 8 ); + sal_uInt16 nArgsPos = aMacro.Search( '(' ); + BasicManager *pAppMgr = SFX_APP()->GetBasicManager(); + BasicManager *pBasMgr = 0; + ErrCode nErr = ERRCODE_NONE; + + // should a macro function be executed ( no direct API call)? + if ( STRING_NOTFOUND != nHashPos && nHashPos < nArgsPos ) + { + // find BasicManager + SfxObjectShell* pDoc = NULL; + String aBasMgrName( INetURLObject::decode(aMacro.Copy( 8, nHashPos-8 ), INET_HEX_ESCAPE, INetURLObject::DECODE_WITH_CHARSET) ); + if ( !aBasMgrName.Len() ) + pBasMgr = pAppMgr; + else if ( aBasMgrName.EqualsAscii(".") ) + { + // current/actual document + pDoc = pCurrent; + if (pDoc) + pBasMgr = pDoc->GetBasicManager(); + } + else + { + // full qualified name, find document by name + for ( SfxObjectShell *pObjSh = SfxObjectShell::GetFirst(); + pObjSh && !pBasMgr; + pObjSh = SfxObjectShell::GetNext(*pObjSh) ) + if ( aBasMgrName == pObjSh->GetTitle(SFX_TITLE_APINAME) ) + { + pDoc = pObjSh; + pBasMgr = pDoc->GetBasicManager(); + } + } + + if ( pBasMgr ) + { + if ( pSh && pDoc ) + { + // security check for macros from document basic if an SFX context (pSh) is given + if ( !pDoc->AdjustMacroMode( String() ) ) + // check forbids execution + return ERRCODE_IO_ACCESSDENIED; + } + else if ( pSh && pSh->GetMedium() ) + { + pSh->AdjustMacroMode( String() ); + SFX_ITEMSET_ARG( pSh->GetMedium()->GetItemSet(), pUpdateDocItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False); + SFX_ITEMSET_ARG( pSh->GetMedium()->GetItemSet(), pMacroExecModeItem, SfxUInt16Item, SID_MACROEXECMODE, sal_False); + if ( pUpdateDocItem && pMacroExecModeItem + && pUpdateDocItem->GetValue() == document::UpdateDocMode::NO_UPDATE + && pMacroExecModeItem->GetValue() == document::MacroExecMode::NEVER_EXECUTE ) + return ERRCODE_IO_ACCESSDENIED; + } + + // find BASIC method + String aQualifiedMethod( INetURLObject::decode(aMacro.Copy( nHashPos+1 ), INET_HEX_ESCAPE, INetURLObject::DECODE_WITH_CHARSET) ); + String aArgs; + if ( STRING_NOTFOUND != nArgsPos ) + { + // remove arguments from macro name + aArgs = aQualifiedMethod.Copy( nArgsPos - nHashPos - 1 ); + aQualifiedMethod.Erase( nArgsPos - nHashPos - 1 ); + } + + SbxMethod *pMethod = SfxQueryMacro( pBasMgr, aQualifiedMethod ); + if ( pMethod ) + { + // arguments must be quoted + String aQuotedArgs; + if ( aArgs.Len()<2 || aArgs.GetBuffer()[1] == '\"') + // no args or already quoted args + aQuotedArgs = aArgs; + else + { + // quote parameters + aArgs.Erase(0,1); + aArgs.Erase( aArgs.Len()-1,1); + + aQuotedArgs = '('; + + sal_uInt16 nCount = aArgs.GetTokenCount(','); + for ( sal_uInt16 n=0; n<nCount; n++ ) + { + aQuotedArgs += '\"'; + aQuotedArgs += aArgs.GetToken( n, ',' ); + aQuotedArgs += '\"'; + if ( n<nCount-1 ) + aQuotedArgs += ','; + } + + aQuotedArgs += ')'; + } + + Any aOldThisComponent; + if ( pSh ) + { + if ( pBasMgr != pAppMgr ) + // mark document: it executes an own macro, so it's in a modal mode + pSh->SetMacroMode_Impl( TRUE ); + if ( pBasMgr == pAppMgr ) + { + // document is executed via AppBASIC, adjust ThisComponent variable + aOldThisComponent = pAppMgr->SetGlobalUNOConstant( "ThisComponent", makeAny( pSh->GetModel() ) ); + } + } + + // add quoted arguments and do the call + String aCall( '[' ); + aCall += pMethod->GetName(); + aCall += aQuotedArgs; + aCall += ']'; + + // just to let the shell be alive + SfxObjectShellRef rSh = pSh; + + // execute function using its Sbx parent, + //SbxVariable* pRet = pMethod->GetParent()->Execute( aCall ); + //rRetval = sbxToUnoValue( pRet ); + + SbxVariable* pRet = pMethod->GetParent()->Execute( aCall ); + if ( pRet ) + { + USHORT nFlags = pRet->GetFlags(); + pRet->SetFlag( SBX_READWRITE | SBX_NO_BROADCAST ); + rRetval = sbxToUnoValue( pRet ); + pRet->SetFlags( nFlags ); + } + + nErr = SbxBase::GetError(); + if ( ( pBasMgr == pAppMgr ) && pSh ) + { + pAppMgr->SetGlobalUNOConstant( "ThisComponent", aOldThisComponent ); + } + + if ( pSh && pSh->GetModel().is() ) + // remove flag for modal mode + pSh->SetMacroMode_Impl( FALSE ); + } + else + nErr = ERRCODE_BASIC_PROC_UNDEFINED; + } + else + nErr = ERRCODE_IO_NOTEXISTS; + } + else + { + // direct API call on a specified object + String aCall( '[' ); + aCall += String(INetURLObject::decode(aMacro.Copy(6), INET_HEX_ESCAPE, + INetURLObject::DECODE_WITH_CHARSET)); + aCall += ']'; + pAppMgr->GetLib(0)->Execute( aCall ); + nErr = SbxBase::GetError(); + } + + pApp->LeaveBasicCall(); + SbxBase::ResetError(); + return nErr; +} + +SFX_IMPL_XSERVICEINFO( SfxAppDispatchProvider, "com.sun.star.frame.DispatchProvider", "com.sun.star.comp.sfx2.AppDispatchProvider" ) \ +SFX_IMPL_SINGLEFACTORY( SfxAppDispatchProvider ); + +void SAL_CALL SfxAppDispatchProvider::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) +{ + Reference < XFrame > xFrame; + if ( aArguments.getLength() ) + { + aArguments[0] >>= xFrame; + m_xFrame = xFrame; + } +} + +Reference < XDispatch > SAL_CALL SfxAppDispatchProvider::queryDispatch( + const ::com::sun::star::util::URL& aURL, + const ::rtl::OUString& /*sTargetFrameName*/, + FrameSearchFlags /*eSearchFlags*/ ) throw( RuntimeException ) +{ + USHORT nId( 0 ); + sal_Bool bMasterCommand( sal_False ); + Reference < XDispatch > xDisp; + const SfxSlot* pSlot = 0; + SfxDispatcher* pAppDisp = SFX_APP()->GetAppDispatcher_Impl(); + if ( aURL.Protocol.compareToAscii( "slot:" ) == COMPARE_EQUAL || + aURL.Protocol.compareToAscii( "commandId:" ) == COMPARE_EQUAL ) + { + nId = (USHORT) aURL.Path.toInt32(); + SfxShell* pShell; + pAppDisp->GetShellAndSlot_Impl( nId, &pShell, &pSlot, TRUE, TRUE ); + } + else if ( aURL.Protocol.compareToAscii( ".uno:" ) == COMPARE_EQUAL ) + { + // Support ".uno" commands. Map commands to slotid + bMasterCommand = SfxOfficeDispatch::IsMasterUnoCommand( aURL ); + if ( bMasterCommand ) + pSlot = pAppDisp->GetSlot( SfxOfficeDispatch::GetMasterUnoCommand( aURL ) ); + else + pSlot = pAppDisp->GetSlot( aURL.Main ); + } + + if ( pSlot ) + { + SfxOfficeDispatch* pDispatch = new SfxOfficeDispatch( pAppDisp, pSlot, aURL ) ; + pDispatch->SetFrame(m_xFrame); + pDispatch->SetMasterUnoCommand( bMasterCommand ); + xDisp = pDispatch; + } + + return xDisp; +} + +Sequence< Reference < XDispatch > > SAL_CALL SfxAppDispatchProvider::queryDispatches( const Sequence < DispatchDescriptor >& seqDescriptor ) +throw( RuntimeException ) +{ + sal_Int32 nCount = seqDescriptor.getLength(); + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference < ::com::sun::star::frame::XDispatch > > lDispatcher(nCount); + for( sal_Int32 i=0; i<nCount; ++i ) + lDispatcher[i] = this->queryDispatch( seqDescriptor[i].FeatureURL, + seqDescriptor[i].FrameName, + seqDescriptor[i].SearchFlags ); + return lDispatcher; +} + +Sequence< sal_Int16 > SAL_CALL SfxAppDispatchProvider::getSupportedCommandGroups() +throw (::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + std::list< sal_Int16 > aGroupList; + SfxSlotPool* pAppSlotPool = &SFX_APP()->GetAppSlotPool_Impl(); + + const ULONG nMode( SFX_SLOT_TOOLBOXCONFIG|SFX_SLOT_ACCELCONFIG|SFX_SLOT_MENUCONFIG ); + + // Gruppe anw"ahlen ( Gruppe 0 ist intern ) + for ( USHORT i=0; i<pAppSlotPool->GetGroupCount(); i++ ) + { + String aName = pAppSlotPool->SeekGroup( i ); + const SfxSlot* pSfxSlot = pAppSlotPool->FirstSlot(); + while ( pSfxSlot ) + { + if ( pSfxSlot->GetMode() & nMode ) + { + sal_Int16 nCommandGroup = MapGroupIDToCommandGroup( pSfxSlot->GetGroupId() ); + aGroupList.push_back( nCommandGroup ); + break; + } + pSfxSlot = pAppSlotPool->NextSlot(); + } + } + + ::com::sun::star::uno::Sequence< sal_Int16 > aSeq = + comphelper::containerToSequence< sal_Int16, std::list< sal_Int16 > >( aGroupList ); + + return aSeq; +} + +Sequence< ::com::sun::star::frame::DispatchInformation > SAL_CALL SfxAppDispatchProvider::getConfigurableDispatchInformation( sal_Int16 nCmdGroup ) +throw (::com::sun::star::uno::RuntimeException) +{ + std::list< ::com::sun::star::frame::DispatchInformation > aCmdList; + + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + SfxSlotPool* pAppSlotPool = &SFX_APP()->GetAppSlotPool_Impl(); + + if ( pAppSlotPool ) + { + const ULONG nMode( SFX_SLOT_TOOLBOXCONFIG|SFX_SLOT_ACCELCONFIG|SFX_SLOT_MENUCONFIG ); + rtl::OUString aCmdPrefix( RTL_CONSTASCII_USTRINGPARAM( ".uno:" )); + + // Gruppe anw"ahlen ( Gruppe 0 ist intern ) + for ( USHORT i=0; i<pAppSlotPool->GetGroupCount(); i++ ) + { + String aName = pAppSlotPool->SeekGroup( i ); + const SfxSlot* pSfxSlot = pAppSlotPool->FirstSlot(); + if ( pSfxSlot ) + { + sal_Int16 nCommandGroup = MapGroupIDToCommandGroup( pSfxSlot->GetGroupId() ); + if ( nCommandGroup == nCmdGroup ) + { + while ( pSfxSlot ) + { + if ( pSfxSlot->GetMode() & nMode ) + { + ::com::sun::star::frame::DispatchInformation aCmdInfo; + ::rtl::OUStringBuffer aBuf( aCmdPrefix ); + aBuf.appendAscii( pSfxSlot->GetUnoName() ); + aCmdInfo.Command = aBuf.makeStringAndClear(); + aCmdInfo.GroupId = nCommandGroup; + aCmdList.push_back( aCmdInfo ); + } + pSfxSlot = pAppSlotPool->NextSlot(); + } + } + } + } + } + + ::com::sun::star::uno::Sequence< ::com::sun::star::frame::DispatchInformation > aSeq = + comphelper::containerToSequence< ::com::sun::star::frame::DispatchInformation, std::list< ::com::sun::star::frame::DispatchInformation > >( aCmdList ); + + return aSeq; +} + +#ifdef TEST_HANDLERS +#include <cppuhelper/implbase2.hxx> + +#include <com/sun/star/awt/XKeyHandler.hdl> +#include <com/sun/star/awt/XMouseClickHandler.hdl> + +class TestKeyHandler: public ::cppu::WeakImplHelper2 +< + com::sun::star::awt::XKeyHandler, + com::sun::star::lang::XServiceInfo +> +{ +public: + TestKeyHandler( const com::sun::star::uno::Reference < ::com::sun::star::lang::XMultiServiceFactory >& ){} + + SFX_DECL_XSERVICEINFO + virtual sal_Bool SAL_CALL keyPressed( const ::com::sun::star::awt::KeyEvent& aEvent ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL keyReleased( const ::com::sun::star::awt::KeyEvent& aEvent ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source) + throw (::com::sun::star::uno::RuntimeException); +}; + +class TestMouseClickHandler: public ::cppu::WeakImplHelper2 +< + com::sun::star::awt::XMouseClickHandler, + com::sun::star::lang::XServiceInfo +> +{ +public: + TestMouseClickHandler( const com::sun::star::uno::Reference < ::com::sun::star::lang::XMultiServiceFactory >& ){} + + SFX_DECL_XSERVICEINFO + virtual sal_Bool SAL_CALL mousePressed( const ::com::sun::star::awt::MouseEvent& e ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL mouseReleased( const ::com::sun::star::awt::MouseEvent& e ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source) + throw (::com::sun::star::uno::RuntimeException); +}; + +sal_Bool SAL_CALL TestKeyHandler::keyPressed( const ::com::sun::star::awt::KeyEvent& aEvent ) throw (::com::sun::star::uno::RuntimeException) +{ + return sal_False; +} + +sal_Bool SAL_CALL TestKeyHandler::keyReleased( const ::com::sun::star::awt::KeyEvent& aEvent ) throw (::com::sun::star::uno::RuntimeException) +{ + return sal_False; +} + +void SAL_CALL TestKeyHandler::disposing( const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException) +{ +} + +sal_Bool SAL_CALL TestMouseClickHandler::mousePressed( const ::com::sun::star::awt::MouseEvent& e ) throw (::com::sun::star::uno::RuntimeException) +{ + return sal_False; +} + +sal_Bool SAL_CALL TestMouseClickHandler::mouseReleased( const ::com::sun::star::awt::MouseEvent& e ) throw (::com::sun::star::uno::RuntimeException) +{ + return sal_False; +} + +void SAL_CALL TestMouseClickHandler::disposing( const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException) +{ +} + +SFX_IMPL_XSERVICEINFO( TestKeyHandler, "com.sun.star.task.Job", "com.sun.star.comp.Office.KeyHandler"); +SFX_IMPL_XSERVICEINFO( TestMouseClickHandler, "com.sun.star.task.Job", "com.sun.star.comp.Office.MouseClickHandler"); +SFX_IMPL_SINGLEFACTORY( TestKeyHandler ); +SFX_IMPL_SINGLEFACTORY( TestMouseClickHandler ); +#endif +// ----------------------------------------------------------------------- + +extern "C" { + +SFX2_DLLPUBLIC void SAL_CALL component_getImplementationEnvironment( + const sal_Char** ppEnvironmentTypeName , + uno_Environment** ) +{ + *ppEnvironmentTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ; +} + +SFX2_DLLPUBLIC void* SAL_CALL component_getFactory( + const sal_Char* pImplementationName , + void* pServiceManager , + void* ) +{ + // Set default return value for this operation - if it failed. + void* pReturn = NULL ; + + if ( + ( pImplementationName != NULL ) && + ( pServiceManager != NULL ) + ) + { + // Define variables which are used in following macros. + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > + xFactory; + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceManager( reinterpret_cast< ::com::sun::star::lang::XMultiServiceFactory* >( pServiceManager ) ) ; + + //============================================================================= + // Add new macro line to handle new service. + // + // !!! ATTENTION !!! + // Write no ";" at end of line and dont forget "else" ! (see macro) + //============================================================================= + IF_NAME_CREATECOMPONENTFACTORY( SfxGlobalEvents_Impl ) + IF_NAME_CREATECOMPONENTFACTORY( SfxFrameLoader_Impl ) + IF_NAME_CREATECOMPONENTFACTORY( SfxMacroLoader ) + IF_NAME_CREATECOMPONENTFACTORY( SfxStandaloneDocumentInfoObject ) + IF_NAME_CREATECOMPONENTFACTORY( SfxAppDispatchProvider ) + IF_NAME_CREATECOMPONENTFACTORY( SfxDocTplService ) + IF_NAME_CREATECOMPONENTFACTORY( ShutdownIcon ) + IF_NAME_CREATECOMPONENTFACTORY( SfxApplicationScriptLibraryContainer ) + IF_NAME_CREATECOMPONENTFACTORY( SfxApplicationDialogLibraryContainer ) +#ifdef TEST_HANDLERS + IF_NAME_CREATECOMPONENTFACTORY( TestKeyHandler ) + IF_NAME_CREATECOMPONENTFACTORY( TestMouseClickHandler ) +#endif + IF_NAME_CREATECOMPONENTFACTORY( OPackageStructureCreator ) + #if 0 + if ( ::sfx2::AppletObject::impl_getStaticImplementationName().equals( + ::rtl::OUString::createFromAscii( pImplementationName ) ) ) + { + xFactory = ::sfx2::AppletObject::impl_createFactory(); + } + #endif + IF_NAME_CREATECOMPONENTFACTORY( ::sfx2::PluginObject ) + IF_NAME_CREATECOMPONENTFACTORY( ::sfx2::IFrameObject ) + IF_NAME_CREATECOMPONENTFACTORY( ::sfx2::OwnSubFilterService ) + if ( ::comp_SfxDocumentMetaData::_getImplementationName().equals( + ::rtl::OUString::createFromAscii( pImplementationName ) ) ) + { + xFactory = ::cppu::createSingleComponentFactory( + ::comp_SfxDocumentMetaData::_create, + ::comp_SfxDocumentMetaData::_getImplementationName(), + ::comp_SfxDocumentMetaData::_getSupportedServiceNames()); + } + + // Factory is valid - service was found. + if ( xFactory.is() ) + { + xFactory->acquire(); + pReturn = xFactory.get(); + } + } + // Return with result of this operation. + return pReturn ; +} +} // extern "C" + +//========================================================================= + +void SAL_CALL FilterOptionsContinuation::setFilterOptions( + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rProps ) + throw (::com::sun::star::uno::RuntimeException) +{ + rProperties = rProps; +} + +::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL + FilterOptionsContinuation::getFilterOptions() + throw (::com::sun::star::uno::RuntimeException) +{ + return rProperties; +} + +//========================================================================= + +RequestFilterOptions::RequestFilterOptions( ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > rModel, + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > rProperties ) +{ + ::rtl::OUString temp; + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > temp2; + ::com::sun::star::document::FilterOptionsRequest aOptionsRequest( temp, + temp2, + rModel, + rProperties ); + + m_aRequest <<= aOptionsRequest; + + m_pAbort = new ContinuationAbort; + m_pOptions = new FilterOptionsContinuation; + + m_lContinuations.realloc( 2 ); + m_lContinuations[0] = ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation >( m_pAbort ); + m_lContinuations[1] = ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation >( m_pOptions ); +} + +::com::sun::star::uno::Any SAL_CALL RequestFilterOptions::getRequest() + throw( ::com::sun::star::uno::RuntimeException ) +{ + return m_aRequest; +} + +::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > > + SAL_CALL RequestFilterOptions::getContinuations() + throw( ::com::sun::star::uno::RuntimeException ) +{ + return m_lContinuations; +} + +//========================================================================= + +RequestPackageReparation::RequestPackageReparation( ::rtl::OUString aName ) +{ + ::rtl::OUString temp; + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > temp2; + ::com::sun::star::document::BrokenPackageRequest aBrokenPackageRequest( temp, + temp2, + aName ); + + m_aRequest <<= aBrokenPackageRequest; + + m_pApprove = new ContinuationApprove; + m_pDisapprove = new ContinuationDisapprove; + + m_lContinuations.realloc( 2 ); + m_lContinuations[0] = ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation >( m_pApprove ); + m_lContinuations[1] = ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation >( m_pDisapprove ); +} + +/*uno::*/Any SAL_CALL RequestPackageReparation::queryInterface( const /*uno::*/Type& rType ) throw (RuntimeException) +{ + return ::cppu::queryInterface ( rType, + // OWeakObject interfaces + dynamic_cast< XInterface* > ( (XInteractionRequest *) this ), + static_cast< XWeak* > ( this ), + // my own interfaces + static_cast< XInteractionRequest* > ( this ) ); +} + +void SAL_CALL RequestPackageReparation::acquire( ) throw () +{ + OWeakObject::acquire(); +} + +void SAL_CALL RequestPackageReparation::release( ) throw () +{ + OWeakObject::release(); +} + +::com::sun::star::uno::Any SAL_CALL RequestPackageReparation::getRequest() + throw( ::com::sun::star::uno::RuntimeException ) +{ + return m_aRequest; +} + +::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > > + SAL_CALL RequestPackageReparation::getContinuations() + throw( ::com::sun::star::uno::RuntimeException ) +{ + return m_lContinuations; +} + +//========================================================================= + +NotifyBrokenPackage::NotifyBrokenPackage( ::rtl::OUString aName ) +{ + ::rtl::OUString temp; + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > temp2; + ::com::sun::star::document::BrokenPackageRequest aBrokenPackageRequest( temp, + temp2, + aName ); + + m_aRequest <<= aBrokenPackageRequest; + + m_pAbort = new ContinuationAbort; + + m_lContinuations.realloc( 1 ); + m_lContinuations[0] = ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation >( m_pAbort ); +} + +/*uno::*/Any SAL_CALL NotifyBrokenPackage::queryInterface( const /*uno::*/Type& rType ) throw (RuntimeException) +{ + return ::cppu::queryInterface ( rType, + // OWeakObject interfaces + dynamic_cast< XInterface* > ( (XInteractionRequest *) this ), + static_cast< XWeak* > ( this ), + // my own interfaces + static_cast< XInteractionRequest* > ( this ) ); +} + +void SAL_CALL NotifyBrokenPackage::acquire( ) throw () +{ + OWeakObject::acquire(); +} + +void SAL_CALL NotifyBrokenPackage::release( ) throw () +{ + OWeakObject::release(); +} + +::com::sun::star::uno::Any SAL_CALL NotifyBrokenPackage::getRequest() + throw( ::com::sun::star::uno::RuntimeException ) +{ + return m_aRequest; +} + +::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > > + SAL_CALL NotifyBrokenPackage::getContinuations() + throw( ::com::sun::star::uno::RuntimeException ) +{ + return m_lContinuations; +} + + diff --git a/sfx2/source/appl/childwin.cxx b/sfx2/source/appl/childwin.cxx new file mode 100644 index 000000000000..b8e8a92da1b8 --- /dev/null +++ b/sfx2/source/appl/childwin.cxx @@ -0,0 +1,855 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" + +#ifndef _TOOLBOX_HXX //autogen +#include <vcl/toolbox.hxx> +#endif +#ifndef _RCID_H +#include <tools/rcid.h> +#endif +#include <unotools/viewoptions.hxx> +#include <com/sun/star/frame/XController.hpp> +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/util/XCloseable.hpp> +#include <cppuhelper/implbase1.hxx> + +#ifndef GCC +#endif + +#include <sfx2/childwin.hxx> +#include <sfx2/app.hxx> +#include "arrdecl.hxx" +#include <sfx2/bindings.hxx> +#include <sfx2/module.hxx> +#include <sfx2/dockwin.hxx> +#include <sfx2/dispatch.hxx> +#include "workwin.hxx" + +static const sal_uInt16 nVersion = 2; + +DBG_NAME(SfxChildWindow) + +SV_IMPL_PTRARR( SfxChildWinContextArr_Impl, SfxChildWinContextFactory* ); + +struct SfxChildWindow_Impl +{ + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xFrame; + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > xListener; + SfxChildWinFactory* pFact; + sal_Bool bHideNotDelete; + sal_Bool bVisible; + sal_Bool bHideAtToggle; + sal_Bool bWantsFocus; + SfxModule* pContextModule; + SfxWorkWindow* pWorkWin; +}; + +// ----------------------------------------------------------------------- + +class DisposeListener : public ::cppu::WeakImplHelper1< ::com::sun::star::lang::XEventListener > +{ + public: + DisposeListener( SfxChildWindow* pOwner , + SfxChildWindow_Impl* pData ) + : m_pOwner( pOwner ) + , m_pData ( pData ) + {} + + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& aSource ) throw (::com::sun::star::uno::RuntimeException) + { + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > xSelfHold( this ); + + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > xComp( aSource.Source, ::com::sun::star::uno::UNO_QUERY ); + if( xComp.is() ) + xComp->removeEventListener( this ); + + if( m_pOwner && m_pData ) + { + m_pData->xListener = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >(); + + if ( m_pData->pWorkWin ) + { + // m_pOwner and m_pData will be killed + m_pData->xFrame = ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >(); + m_pData->pWorkWin->GetBindings().Execute( m_pOwner->GetType() ); + } + else + { + delete m_pOwner; + } + + m_pOwner = NULL; + m_pData = NULL; + } + } + + private: + SfxChildWindow* m_pOwner; + SfxChildWindow_Impl* m_pData ; +}; + +// ----------------------------------------------------------------------- + +sal_Bool GetPosSizeFromString( const String& rStr, Point& rPos, Size& rSize ) +{ + if ( rStr.GetTokenCount('/') != 4 ) + return sal_False; + + xub_StrLen nIdx = 0; + rPos.X() = rStr.GetToken(0, '/', nIdx).ToInt32(); + rPos.Y() = rStr.GetToken(0, '/', nIdx).ToInt32(); + rSize.Width() = rStr.GetToken(0, '/', nIdx).ToInt32(); + rSize.Height() = rStr.GetToken(0, '/', nIdx).ToInt32(); + + // negative sizes are invalid + if ( rSize.Width() < 0 || rSize.Height() < 0 ) + return sal_False; + + return sal_True; +} + +sal_Bool GetSplitSizeFromString( const String& rStr, Size& rSize ) +{ + xub_StrLen nIndex = rStr.Search( ',' ); + if ( nIndex != STRING_NOTFOUND ) + { + String aStr = rStr.Copy( nIndex+1 ); + + sal_Int32 nCount = aStr.GetTokenCount(';'); + if ( nCount != 2 ) + return sal_False; + + rSize.Width() = aStr.GetToken(0, ';' ).ToInt32(); + rSize.Height() = aStr.GetToken(1, ';' ).ToInt32(); + + // negative sizes are invalid + if ( rSize.Width() < 0 || rSize.Height() < 0 ) + return sal_False; + + return sal_True; + } + + return sal_False; +} + +//========================================================================= +SfxChildWindow::SfxChildWindow(Window *pParentWindow, sal_uInt16 nId) + : pParent(pParentWindow) + , nType(nId) + , eChildAlignment(SFX_ALIGN_NOALIGNMENT) + , pWindow(0L) +{ + pImp = new SfxChildWindow_Impl; + pImp->pFact = 0L; + pImp->bHideNotDelete = sal_False; + pImp->bHideAtToggle = sal_False; + pImp->bWantsFocus = sal_True; + pImp->bVisible = sal_True; + pImp->pContextModule = NULL; + pImp->pWorkWin = NULL; + + pContext = 0L; + DBG_CTOR(SfxChildWindow,0); +} + +void SfxChildWindow::Destroy() +{ + if ( GetFrame().is() ) + { + pImp->pWorkWin = NULL; + try + { + ::com::sun::star::uno::Reference < ::com::sun::star::util::XCloseable > xClose( GetFrame(), ::com::sun::star::uno::UNO_QUERY ); + if ( xClose.is() ) + xClose->close( sal_True ); + else + GetFrame()->dispose(); + } + catch ( com::sun::star::uno::Exception& ) + { + } + } + else + delete this; +} + +//------------------------------------------------------------------------- +SfxChildWindow::~SfxChildWindow() +{ + DBG_DTOR(SfxChildWindow,0); + if ( pContext ) + delete pContext; + if ( pWindow ) + delete pWindow; + delete pImp; +} + +//------------------------------------------------------------------------- +SfxChildWindow* SfxChildWindow::CreateChildWindow( sal_uInt16 nId, + Window *pParent, SfxBindings* pBindings, SfxChildWinInfo& rInfo) +{ + SfxChildWindow *pChild=0; + SfxChildWinFactory* pFact=0; + sal_uInt16 nOldMode = Application::GetSystemWindowMode(); + + // Zuerst ChildWindow im SDT suchen; "Uberlagerungen m"ussen mit einem + // ChildWindowContext realisiert werden + SfxApplication *pApp = SFX_APP(); + { + SfxChildWinFactArr_Impl &rFactories = pApp->GetChildWinFactories_Impl(); + for ( sal_uInt16 nFactory = 0; nFactory < rFactories.Count(); ++nFactory ) + { + pFact = rFactories[nFactory]; + if ( pFact->nId == nId ) + { + SfxChildWinInfo& rFactInfo = pFact->aInfo; + if ( rInfo.bVisible ) + { + if ( pBindings ) + pBindings->ENTERREGISTRATIONS(); + SfxChildWinInfo aInfo = rFactInfo; + Application::SetSystemWindowMode( SYSTEMWINDOW_MODE_NOAUTOMODE ); + pChild = pFact->pCtor( pParent, nId, pBindings, &aInfo ); + Application::SetSystemWindowMode( nOldMode ); + if ( pBindings ) + pBindings->LEAVEREGISTRATIONS(); + } + + break; + } + } + } + + SfxDispatcher *pDisp = pBindings->GetDispatcher_Impl(); + SfxModule *pMod = pDisp ? SfxModule::GetActiveModule( pDisp->GetFrame() ) :0; + if ( !pChild && pMod ) + { + SfxChildWinFactArr_Impl *pFactories = pMod->GetChildWinFactories_Impl(); + if ( pFactories ) + { + SfxChildWinFactArr_Impl &rFactories = *pFactories; + for ( sal_uInt16 nFactory = 0; nFactory < rFactories.Count(); ++nFactory ) + { + pFact = rFactories[nFactory]; + if ( pFact->nId == nId ) + { + SfxChildWinInfo& rFactInfo = pFact->aInfo; + if ( rInfo.bVisible ) + { + if ( pBindings ) + pBindings->ENTERREGISTRATIONS(); + SfxChildWinInfo aInfo = rFactInfo; + Application::SetSystemWindowMode( SYSTEMWINDOW_MODE_NOAUTOMODE ); + pChild = pFact->pCtor( pParent, nId, pBindings, &aInfo ); + Application::SetSystemWindowMode( nOldMode ); + if ( pBindings ) + pBindings->LEAVEREGISTRATIONS(); + } + + break; + } + } + } + } + + if ( pChild ) + pChild->SetFactory_Impl( pFact ); + + DBG_ASSERT(pFact && (pChild || !rInfo.bVisible), "ChildWindow-Typ nicht registriert!"); + + if ( pChild && !pChild->pWindow ) + { + DELETEZ(pChild); + DBG_WARNING("ChildWindow hat kein Fenster!"); + } + + return pChild; +} + +//------------------------------------------------------------------------- +void SfxChildWindow::SaveStatus(const SfxChildWinInfo& rInfo) +{ + sal_uInt16 nID = GetType(); + + String aWinData( 'V' ); + aWinData += String::CreateFromInt32( nVersion ); + aWinData += ','; + aWinData += rInfo.bVisible ? 'V' : 'H'; + aWinData += ','; + aWinData += String::CreateFromInt32( rInfo.nFlags ); + if ( rInfo.aExtraString.Len() ) + { + aWinData += ','; + aWinData += rInfo.aExtraString; + } + + SvtViewOptions aWinOpt( E_WINDOW, String::CreateFromInt32( nID ) ); + // aWinOpt.SetPosition( rInfo.aPos.X(), rInfo.aPos.Y() ); + // aWinOpt.SetSize( rInfo.aSize.Width(), rInfo.aSize.Height() ); + aWinOpt.SetWindowState( String( rInfo.aWinState, RTL_TEXTENCODING_UTF8 ) ); + + ::com::sun::star::uno::Sequence < ::com::sun::star::beans::NamedValue > aSeq(1); + aSeq[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Data") ); + aSeq[0].Value <<= ::rtl::OUString( aWinData ); + aWinOpt.SetUserData( aSeq ); + + // ... but save status at runtime! + pImp->pFact->aInfo = rInfo; +} + +//------------------------------------------------------------------------- +void SfxChildWindow::SetAlignment(SfxChildAlignment eAlign) +{ + DBG_CHKTHIS(SfxChildWindow,0); + + eChildAlignment = eAlign; +} + +//------------------------------------------------------------------------- +void SfxChildWindow::SetPosSizePixel(const Point& rPoint, Size& rSize) +{ + DBG_CHKTHIS(SfxChildWindow,0); + + pWindow->SetPosSizePixel(rPoint, rSize); +} + +//------------------------------------------------------------------------- +SfxChildWinInfo SfxChildWindow::GetInfo() const +{ + DBG_CHKTHIS(SfxChildWindow,0); + + SfxChildWinInfo aInfo; + aInfo.aPos = pWindow->GetPosPixel(); + aInfo.aSize = pWindow->GetSizePixel(); + if ( pWindow->IsSystemWindow() ) + { + ULONG nMask = WINDOWSTATE_MASK_POS | WINDOWSTATE_MASK_STATE; + if ( pWindow->GetStyle() & WB_SIZEABLE ) + nMask |= ( WINDOWSTATE_MASK_WIDTH | WINDOWSTATE_MASK_HEIGHT ); + aInfo.aWinState = ((SystemWindow*)pWindow)->GetWindowState( nMask ); + } + else if ( pWindow->GetType() == RSC_DOCKINGWINDOW ) + { + if (((DockingWindow*)pWindow)->GetFloatingWindow() ) + aInfo.aWinState = ((DockingWindow*)pWindow)->GetFloatingWindow()->GetWindowState(); + else + { + SfxChildWinInfo aTmpInfo; + ((SfxDockingWindow*)pWindow)->FillInfo( aTmpInfo ); + aInfo.aExtraString = aTmpInfo.aExtraString; + } + } + + aInfo.bVisible = pImp->bVisible; + aInfo.nFlags = 0; + return aInfo; +} + +//------------------------------------------------------------------------- +sal_uInt16 SfxChildWindow::GetPosition() +{ + return pImp->pFact->nPos; +} + +#if 0 +static void ImplWindowStateFromStr( Point rPos, Size rSize, const ByteString& rStr ) +{ + ULONG nValidMask = 0; + xub_StrLen nIndex = 0; + ByteString aTokenStr; + + aTokenStr = rStr.GetToken( 0, ',', nIndex ); + if ( aTokenStr.Len() ) + { + rPos.X() = aTokenStr.ToInt32(); + nValidMask |= WINDOWSTATE_MASK_X; + } + + aTokenStr = rStr.GetToken( 0, ',', nIndex ); + if ( aTokenStr.Len() ) + { + rPos.Y() = aTokenStr.ToInt32(); + nValidMask |= WINDOWSTATE_MASK_Y; + } + + aTokenStr = rStr.GetToken( 0, ',', nIndex ); + if ( aTokenStr.Len() ) + { + rSize.Width() = aTokenStr.ToInt32(); + nValidMask |= WINDOWSTATE_MASK_WIDTH; + } + + aTokenStr = rStr.GetToken( 0, ';', nIndex ); + if ( aTokenStr.Len() ) + { + rSize.Height() = aTokenStr.ToInt32(); + nValidMask |= WINDOWSTATE_MASK_HEIGHT; + } +} +#endif + +//------------------------------------------------------------------------- +void SfxChildWindow::InitializeChildWinFactory_Impl( sal_uInt16 nId, SfxChildWinInfo& rInfo ) +{ + // load configuration + SvtViewOptions aWinOpt( E_WINDOW, String::CreateFromInt32( nId ) ); + + if ( aWinOpt.Exists() ) + rInfo.bVisible = aWinOpt.IsVisible(); // set state from configuration. Can be overwritten by UserData, see below + + ::com::sun::star::uno::Sequence < ::com::sun::star::beans::NamedValue > aSeq = aWinOpt.GetUserData(); + + ::rtl::OUString aTmp; + if ( aSeq.getLength() ) + aSeq[0].Value >>= aTmp; + + String aWinData( aTmp ); + rInfo.aWinState = ByteString( String(aWinOpt.GetWindowState()), RTL_TEXTENCODING_UTF8 ); + + //ImplWindowStateFromStr( rInfo.aPos, rInfo.aSize, ByteString( aWinState, RTL_TEXTENCODING_UTF8 ) ); + + if ( aWinData.Len() ) + { + // Nach Versionskennung suchen + if ( aWinData.GetChar((sal_uInt16)0) != 0x0056 ) // 'V' = 56h + // Keine Versionskennung, daher nicht verwenden + return; + + // 'V' l"oschen + aWinData.Erase(0,1); + + // Version lesen + char cToken = ','; + sal_uInt16 nPos = aWinData.Search( cToken ); + sal_uInt16 nActVersion = (sal_uInt16)aWinData.Copy( 0, nPos + 1 ).ToInt32(); + if ( nActVersion != nVersion ) + return; + + aWinData.Erase(0,nPos+1); + + //aWinOpt.GetPosition( rInfo.aPos.X(), rInfo.aPos.Y() ); + //aWinOpt.GetSize( rInfo.aSize.Width(), rInfo.aSize.Height() ); + + // Sichtbarkeit laden: ist als ein char codiert + rInfo.bVisible = (aWinData.GetChar(0) == 0x0056); // 'V' = 56h + aWinData.Erase(0,1); + nPos = aWinData.Search( cToken ); + if (nPos != STRING_NOTFOUND) + { + USHORT nNextPos = aWinData.Search( cToken, 2 ); + if ( nNextPos != STRING_NOTFOUND ) + { + // es gibt noch Extra-Information + rInfo.nFlags = (sal_uInt16)aWinData.Copy( nPos+1, nNextPos - nPos - 1 ).ToInt32(); + aWinData.Erase( nPos, nNextPos-nPos+1 ); + rInfo.aExtraString = aWinData; + } + else + rInfo.nFlags = (sal_uInt16)aWinData.Copy( nPos+1 ).ToInt32(); + } + } +} + +void SfxChildWindow::CreateContext( sal_uInt16 nContextId, SfxBindings& rBindings ) +{ + SfxChildWindowContext *pCon = NULL; + SfxChildWinFactory* pFact=0; + SfxApplication *pApp = SFX_APP(); + SfxDispatcher *pDisp = rBindings.GetDispatcher_Impl(); + SfxModule *pMod = pDisp ? SfxModule::GetActiveModule( pDisp->GetFrame() ) :0; + if ( pMod ) + { + SfxChildWinFactArr_Impl *pFactories = pMod->GetChildWinFactories_Impl(); + if ( pFactories ) + { + SfxChildWinFactArr_Impl &rFactories = *pFactories; + for ( sal_uInt16 nFactory = 0; nFactory < rFactories.Count(); ++nFactory ) + { + pFact = rFactories[nFactory]; + if ( pFact->nId == GetType() ) + { + DBG_ASSERT( pFact->pArr, "Kein Kontext angemeldet!" ); + if ( !pFact->pArr ) + break; + + SfxChildWinContextFactory *pConFact=0; + for ( sal_uInt16 n=0; n<pFact->pArr->Count(); ++n ) + { + pConFact = (*pFact->pArr)[n]; + rBindings.ENTERREGISTRATIONS(); + if ( pConFact->nContextId == nContextId ) + { + SfxChildWinInfo aInfo = pFact->aInfo; + pCon = pConFact->pCtor( GetWindow(), &rBindings, &aInfo ); + pCon->nContextId = pConFact->nContextId; + pImp->pContextModule = pMod; + } + rBindings.LEAVEREGISTRATIONS(); + } + break; + } + } + } + } + + if ( !pCon ) + { + SfxChildWinFactArr_Impl &rFactories = pApp->GetChildWinFactories_Impl(); + for ( sal_uInt16 nFactory = 0; nFactory < rFactories.Count(); ++nFactory ) + { + pFact = rFactories[nFactory]; + if ( pFact->nId == GetType() ) + { + DBG_ASSERT( pFact->pArr, "Kein Kontext angemeldet!" ); + if ( !pFact->pArr ) + break; + + SfxChildWinContextFactory *pConFact=0; + for ( sal_uInt16 n=0; n<pFact->pArr->Count(); ++n ) + { + pConFact = (*pFact->pArr)[n]; + rBindings.ENTERREGISTRATIONS(); + if ( pConFact->nContextId == nContextId ) + { + SfxChildWinInfo aInfo = pFact->aInfo; + pCon = pConFact->pCtor( GetWindow(), &rBindings, &aInfo ); + pCon->nContextId = pConFact->nContextId; + pImp->pContextModule = NULL; + } + rBindings.LEAVEREGISTRATIONS(); + } + break; + } + } + } + + if ( !pCon ) + { + DBG_ERROR( "Kein geeigneter Context gefunden!" ); + return; + } + + if ( pContext ) + delete( pContext ); + pContext = pCon; + pContext->GetWindow()->SetSizePixel( pWindow->GetOutputSizePixel() ); + pContext->GetWindow()->Show(); +} + +SfxChildWindowContext::SfxChildWindowContext( sal_uInt16 nId ) + : pWindow( NULL ) + , nContextId( nId ) +{ +} + +SfxChildWindowContext::~SfxChildWindowContext() +{ + delete pWindow; +} + +FloatingWindow* SfxChildWindowContext::GetFloatingWindow() const +{ + Window *pParent = pWindow->GetParent(); + if ( pParent->GetType() == RSC_DOCKINGWINDOW || pParent->GetType() == RSC_TOOLBOX ) + { + return ((DockingWindow*)pParent)->GetFloatingWindow(); + } + else if ( pParent->GetType() == RSC_FLOATINGWINDOW ) + { + return (FloatingWindow*) pParent; + } + else + { + DBG_ERROR("Kein FloatingWindow-Context!"); + return NULL; + } +} + +SfxChildAlignment SfxChildWindowContext::GetAlignment() const +{ + Window *pParent = pWindow->GetParent(); + if ( pParent->GetType() == RSC_DOCKINGWINDOW ) + { + return ((SfxDockingWindow*)pParent)->GetAlignment(); + } + else if ( pParent->GetType() == RSC_TOOLBOX ) + { + HACK(noch nicht verwendet und noch nicht implementiert); + return SFX_ALIGN_NOALIGNMENT; + } + else + return SFX_ALIGN_NOALIGNMENT; +} + +void SfxChildWindowContext::Resizing( Size& ) +{ +} + +sal_Bool SfxChildWindowContext::Close() +{ + return sal_True; +} + +void SfxChildWindow::SetFactory_Impl( SfxChildWinFactory *pF ) +{ + pImp->pFact = pF; +} + +void SfxChildWindow::SetHideNotDelete( sal_Bool bOn ) +{ + pImp->bHideNotDelete = bOn; +} + +sal_Bool SfxChildWindow::IsHideNotDelete() const +{ + return pImp->bHideNotDelete; +} + +void SfxChildWindow::SetHideAtToggle( sal_Bool bOn ) +{ + pImp->bHideAtToggle = bOn; +} + +sal_Bool SfxChildWindow::IsHideAtToggle() const +{ + return pImp->bHideAtToggle; +} + +void SfxChildWindow::SetWantsFocus( BOOL bSet ) +{ + pImp->bWantsFocus = bSet; +} + +sal_Bool SfxChildWindow::WantsFocus() const +{ + return pImp->bWantsFocus; +} + +sal_Bool SfxChildWinInfo::GetExtraData_Impl +( + SfxChildAlignment *pAlign, + SfxChildAlignment *pLastAlign, + Size *pSize, + sal_uInt16 *pLine, + sal_uInt16 *pPos +) const +{ + // ung"ultig? + if ( !aExtraString.Len() ) + return sal_False; + String aStr; + sal_uInt16 nPos = aExtraString.SearchAscii("AL:"); + if ( nPos == STRING_NOTFOUND ) + return sal_False; + + // Versuche, den Alignment-String "ALIGN:(...)" einzulesen; wenn + // er nicht vorhanden ist, liegt eine "altere Version vor + if ( nPos != STRING_NOTFOUND ) + { + sal_uInt16 n1 = aExtraString.Search('(', nPos); + if ( n1 != STRING_NOTFOUND ) + { + sal_uInt16 n2 = aExtraString.Search(')', n1); + if ( n2 != STRING_NOTFOUND ) + { + // Alignment-String herausschneiden + aStr = aExtraString.Copy(nPos, n2 - nPos + 1); + aStr.Erase(nPos, n1-nPos+1); + } + } + } + + // Zuerst das Alignment extrahieren + if ( !aStr.Len() ) + return sal_False; + if ( pAlign ) + *pAlign = (SfxChildAlignment) (sal_uInt16) aStr.ToInt32(); + + // Dann das LastAlignment + nPos = aStr.Search(','); + if ( nPos == STRING_NOTFOUND ) + return sal_False; + aStr.Erase(0, nPos+1); + if ( pLastAlign ) + *pLastAlign = (SfxChildAlignment) (sal_uInt16) aStr.ToInt32(); + + // Dann die Splitting-Informationen + nPos = aStr.Search(','); + if ( nPos == STRING_NOTFOUND ) + // Dockt nicht in einem Splitwindow + return sal_True; + aStr.Erase(0, nPos+1); + Point aChildPos; + Size aChildSize; + if ( GetPosSizeFromString( aStr, aChildPos, aChildSize ) ) + { + if ( pSize ) + *pSize = aChildSize; + if ( pLine ) + *pLine = (sal_uInt16) aChildPos.X(); + if ( pPos ) + *pPos = (sal_uInt16) aChildPos.Y(); + return sal_True; + } + return sal_False; +} + +sal_Bool SfxChildWindow::IsVisible() const +{ + return pImp->bVisible; +} + +void SfxChildWindow::SetVisible_Impl( sal_Bool bVis ) +{ + pImp->bVisible = bVis; +} + +void SfxChildWindow::Hide() +{ + switch ( pWindow->GetType() ) + { + case RSC_DOCKINGWINDOW : + ((DockingWindow*)pWindow)->Hide(); + break; + case RSC_TOOLBOX : + ((ToolBox*)pWindow)->Hide(); + break; + default: + pWindow->Hide(); + break; + } +} + + + +void SfxChildWindow::Show( USHORT nFlags ) +{ + switch ( pWindow->GetType() ) + { + case RSC_DOCKINGWINDOW : + ((DockingWindow*)pWindow)->Show( TRUE, nFlags ); + break; + case RSC_TOOLBOX : + ((ToolBox*)pWindow)->Show( TRUE, nFlags ); + break; + default: + pWindow->Show( TRUE, nFlags ); + break; + } +} + +Window* SfxChildWindow::GetContextWindow( SfxModule *pModule ) const +{ + return pModule == pImp->pContextModule && pContext ? pContext->GetWindow(): 0; +} + +void SfxChildWindow::SetWorkWindow_Impl( SfxWorkWindow* pWin ) +{ + pImp->pWorkWin = pWin; + if ( pWin && pWindow->HasChildPathFocus() ) + pImp->pWorkWin->SetActiveChild_Impl( pWindow ); +} + +//SfxWorkWindow* SfxChildWindow::GetWorkWindow_Impl() const +//{ +// return pImp->pWorkWin; +//} + +void SfxChildWindow::Activate_Impl() +{ + if(pImp->pWorkWin!=NULL) //@#60568# + pImp->pWorkWin->SetActiveChild_Impl( pWindow ); +} + +void SfxChildWindow::Deactivate_Impl() +{ +// pImp->pWorkWin->SetActiveChild_Impl( NULL ); +} + +sal_Bool SfxChildWindow::QueryClose() +{ + sal_Bool bAllow = sal_True; + + if ( pImp->xFrame.is() ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController > xCtrl = pImp->xFrame->getController(); + if ( xCtrl.is() ) + bAllow = xCtrl->suspend( sal_True ); + } + + if ( bAllow ) + bAllow = !GetWindow()->IsInModalMode(); + + return bAllow; +} + +::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > SfxChildWindow::GetFrame() +{ + return pImp->xFrame; +} + +void SfxChildWindow::SetFrame( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > & rFrame ) +{ + // Do nothing if nothing will be changed ... + if( pImp->xFrame != rFrame ) + { + // ... but stop listening on old frame, if connection exist! + if( pImp->xFrame.is() ) + pImp->xFrame->removeEventListener( pImp->xListener ); + + // If new frame isnt NULL -> we must guarantee valid listener for disposing events. + // Use already existing or create new one. + if( rFrame.is() ) + if( !pImp->xListener.is() ) + pImp->xListener = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >( new DisposeListener( this, pImp ) ); + + // Set new frame in data container + // and build new listener connection, if neccessary. + pImp->xFrame = rFrame; + if( pImp->xFrame.is() ) + pImp->xFrame->addEventListener( pImp->xListener ); + } +} + +sal_Bool SfxChildWindow::CanGetFocus() const +{ + return !(pImp->pFact->aInfo.nFlags & SFX_CHILDWIN_CANTGETFOCUS); +} + +void SfxChildWindowContext::RegisterChildWindowContext(SfxModule* pMod, USHORT nId, SfxChildWinContextFactory* pFact) +{ + SFX_APP()->RegisterChildWindowContext_Impl( pMod, nId, pFact ); +} + +void SfxChildWindow::RegisterChildWindow(SfxModule* pMod, SfxChildWinFactory* pFact) +{ + SFX_APP()->RegisterChildWindow_Impl( pMod, pFact ); +} + diff --git a/sfx2/source/appl/dde.hrc b/sfx2/source/appl/dde.hrc new file mode 100644 index 000000000000..d3e178606809 --- /dev/null +++ b/sfx2/source/appl/dde.hrc @@ -0,0 +1,40 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SFX_DDE_HRC +#define _SFX_DDE_HRC + +#include "app.hrc" + +#define ED_DDE_APP 50 +#define ED_DDE_TOPIC 51 +#define ED_DDE_ITEM 52 +#define FT_DDE_APP 53 +#define FT_DDE_TOPIC 54 +#define FT_DDE_ITEM 55 +#define GROUP_DDE_CHG 56 + +#endif diff --git a/sfx2/source/appl/dde.src b/sfx2/source/appl/dde.src new file mode 100644 index 000000000000..22df8eff16ba --- /dev/null +++ b/sfx2/source/appl/dde.src @@ -0,0 +1,91 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "dde.hrc" + +ModalDialog MD_DDE_LINKEDIT +{ + OutputSize = TRUE ; + SVLook = TRUE ; + Size = MAP_APPFONT ( 223 , 74 ) ; + Text [ en-US ] = "Modify Link" ; + Moveable = TRUE ; + FixedText FT_DDE_APP + { + Pos = MAP_APPFONT ( 12 , 16 ) ; + Size = MAP_APPFONT ( 40 , 8 ) ; + Text [ en-US ] = "~Application:" ; + }; + Edit ED_DDE_APP + { + Border = TRUE ; + Pos = MAP_APPFONT ( 55 , 14 ) ; + Size = MAP_APPFONT ( 100 , 12 ) ; + }; + FixedText FT_DDE_TOPIC + { + Pos = MAP_APPFONT ( 12 , 34 ) ; + Size = MAP_APPFONT ( 40 , 8 ) ; + Text [ en-US ] = "~File:" ; + }; + Edit ED_DDE_TOPIC + { + Border = TRUE ; + Pos = MAP_APPFONT ( 55 , 32 ) ; + Size = MAP_APPFONT ( 100 , 12 ) ; + }; + FixedText FT_DDE_ITEM + { + Pos = MAP_APPFONT ( 12 , 52 ) ; + Size = MAP_APPFONT ( 40 , 8 ) ; + Text [ en-US ] = "~Category:" ; + }; + Edit ED_DDE_ITEM + { + Border = TRUE ; + Pos = MAP_APPFONT ( 55 , 50 ) ; + Size = MAP_APPFONT ( 100 , 12 ) ; + }; + FixedLine GROUP_DDE_CHG + { + Pos = MAP_APPFONT ( 6 , 3 ) ; + Size = MAP_APPFONT ( 155 , 8 ) ; + Text [ en-US ] = "Modify link" ; + }; + OKButton 1 + { + Pos = MAP_APPFONT ( 167 , 6 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; + DefButton = TRUE ; + }; + CancelButton 1 + { + Pos = MAP_APPFONT ( 167 , 23 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; + }; +}; + diff --git a/sfx2/source/appl/fileobj.cxx b/sfx2/source/appl/fileobj.cxx new file mode 100644 index 000000000000..294d6ef17da5 --- /dev/null +++ b/sfx2/source/appl/fileobj.cxx @@ -0,0 +1,706 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" + +#include <vcl/wrkwin.hxx> +#include <vcl/msgbox.hxx> +#include <tools/urlobj.hxx> +#include <tools/stream.hxx> +#include <sot/formats.hxx> +#include <svtools/filter.hxx> +#include <sfx2/lnkbase.hxx> +#include <sfx2/app.hxx> +#include <sfx2/progress.hxx> +#include <sfx2/docfilt.hxx> +#include <sfx2/filedlghelper.hxx> +#include <sot/exchange.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <sfx2/docfac.hxx> +#include <com/sun/star/document/XTypeDetection.hpp> +#include <comphelper/mediadescriptor.hxx> +#include <comphelper/processfactory.hxx> +#include <sfx2/linkmgr.hxx> +#include <sfx2/opengrf.hxx> +#include "sfxresid.hxx" +#include "fileobj.hxx" +#include "app.hrc" + +namespace css = ::com::sun::star; + +#define FILETYPE_TEXT 1 +#define FILETYPE_GRF 2 +#define FILETYPE_OBJECT 3 + +struct Impl_DownLoadData +{ + Graphic aGrf; + Timer aTimer; + + Impl_DownLoadData( const Link& rLink ) + { + aTimer.SetTimeout( 100 ); + aTimer.SetTimeoutHdl( rLink ); + aGrf.SetDefaultType(); + } + ~Impl_DownLoadData() + { + aTimer.Stop(); + } +}; + +// -------------------------------------------------------------------------- + + +SvFileObject::SvFileObject() : + pDownLoadData( NULL ), pOldParent( NULL ), nType( FILETYPE_TEXT ) +{ + bLoadAgain = TRUE; + bSynchron = bLoadError = bWaitForData = bDataReady = bNativFormat = + bClearMedium = bStateChangeCalled = bInCallDownLoad = FALSE; +} + + +SvFileObject::~SvFileObject() +{ + if ( xMed.Is() ) + { + xMed->SetDataAvailableLink( Link() ); + xMed->SetDoneLink( Link() ); + xMed.Clear(); + } + delete pDownLoadData; +} + + +BOOL SvFileObject::GetData( ::com::sun::star::uno::Any & rData, + const String & rMimeType, + BOOL bGetSynchron ) +{ + ULONG nFmt = SotExchange::GetFormatStringId( rMimeType ); + switch( nType ) + { + case FILETYPE_TEXT: + if( FORMAT_FILE == nFmt ) + { + // das Medium muss in der Applikation geoffnet werden, um die + // relativen Datei Links aufzuloesen!!!! Wird ueber den + // LinkManager und damit von dessen Storage erledigt. + rData <<= rtl::OUString( sFileNm ); + } + break; + + case FILETYPE_GRF: + if( !bLoadError ) + { + SfxMediumRef xTmpMed; + + if( FORMAT_GDIMETAFILE == nFmt || FORMAT_BITMAP == nFmt || + SOT_FORMATSTR_ID_SVXB == nFmt ) + { + Graphic aGrf; + + //JP 15.07.98: Bug 52959 + // falls das Nativformat doch erwuenscht ist, muss am + // Ende das Flag zurueckgesetzt werden. +// wird einzig und allein im sw/ndgrf.cxx benutzt, wenn der Link vom +// GraphicNode entfernt wird. + BOOL bOldNativFormat = bNativFormat; +//!!?? bNativFormat = 0 != (ASPECT_ICON & pSvData->GetAspect()); + + // falls gedruckt werden soll, warten wir bis die + // Daten vorhanden sind + if( bGetSynchron ) + { + // testhalber mal ein LoadFile rufen um das nach- + // laden ueberahaupt anzustossen + if( !xMed.Is() ) + LoadFile_Impl(); + + if( !bInCallDownLoad ) + { + xTmpMed = xMed; + while( bWaitForData ) + Application::Reschedule(); + + xMed = xTmpMed; + bClearMedium = TRUE; + } + } + + if( pDownLoadData || + ( !bWaitForData && ( xMed.Is() || // wurde als URL geladen + ( bSynchron && LoadFile_Impl() && xMed.Is() ) )) ) + { + // falls + + // falls es uebers Internet gesogen wurde, nicht + // wieder versuchen + if( !bGetSynchron ) + bLoadAgain = !xMed->IsRemote(); + bLoadError = !GetGraphic_Impl( aGrf, xMed->GetInStream() ); + } + else if( !LoadFile_Impl() || + !GetGraphic_Impl( aGrf, xMed.Is() ? xMed->GetInStream() : 0 )) + { + if( !xMed.Is() ) + break; + aGrf.SetDefaultType(); + } + + if( SOT_FORMATSTR_ID_SVXB != nFmt ) + nFmt = (bLoadError || GRAPHIC_BITMAP == aGrf.GetType()) + ? FORMAT_BITMAP + : FORMAT_GDIMETAFILE; + + SvMemoryStream aMemStm( 0, 65535 ); + switch ( nFmt ) + { + case SOT_FORMATSTR_ID_SVXB: + if( GRAPHIC_NONE != aGrf.GetType() ) + { + aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 ); + aMemStm << aGrf; + } + break; + + case FORMAT_BITMAP: + if( !aGrf.GetBitmap().IsEmpty()) + aMemStm << aGrf.GetBitmap(); + break; + + default: + if( aGrf.GetGDIMetaFile().GetActionCount() ) + { + GDIMetaFile aMeta( aGrf.GetGDIMetaFile() ); + aMeta.Write( aMemStm ); + } + } + rData <<= css::uno::Sequence< sal_Int8 >( (sal_Int8*) aMemStm.GetData(), + aMemStm.Seek( STREAM_SEEK_TO_END ) ); + + bNativFormat = bOldNativFormat; + + // alles fertig? + if( xMed.Is() && !bSynchron && bClearMedium ) + { + xMed.Clear(); + bClearMedium = FALSE; + } + } + } + break; + case FILETYPE_OBJECT: + // TODO/LATER: possibility to insert a new object + rData <<= rtl::OUString( sFileNm ); + break; + } + return sal_True/*0 != aTypeList.Count()*/; +} + + + + +BOOL SvFileObject::Connect( sfx2::SvBaseLink* pLink ) +{ + if( !pLink || !pLink->GetLinkManager() ) + return FALSE; + + // teste doch mal, ob nicht ein anderer Link mit der gleichen + // Verbindung schon existiert + pLink->GetLinkManager()->GetDisplayNames( pLink, 0, &sFileNm, 0, &sFilter ); + + if( OBJECT_CLIENT_GRF == pLink->GetObjType() ) + { + SfxObjectShellRef pShell = pLink->GetLinkManager()->GetPersist(); + if( pShell.Is() ) + { + if( pShell->IsAbortingImport() ) + return FALSE; + + if( pShell->GetMedium() ) + sReferer = pShell->GetMedium()->GetName(); + } + } + + switch( pLink->GetObjType() ) + { + case OBJECT_CLIENT_GRF: + nType = FILETYPE_GRF; + bSynchron = pLink->IsSynchron(); + break; + + case OBJECT_CLIENT_FILE: + nType = FILETYPE_TEXT; + break; + + case OBJECT_CLIENT_OLE: + nType = FILETYPE_OBJECT; + // TODO/LATER: introduce own type to be used for exchanging + break; + + default: + return FALSE; + } + + SetUpdateTimeout( 0 ); + + // und jetzt bei diesem oder gefundenem Pseudo-Object anmelden + AddDataAdvise( pLink, SotExchange::GetFormatMimeType( pLink->GetContentType()), 0 ); + return TRUE; +} + + +BOOL SvFileObject::LoadFile_Impl() +{ + // wir sind noch im Laden!! + if( bWaitForData || !bLoadAgain || xMed.Is() || pDownLoadData ) + return FALSE; + + // z.Z. nur auf die aktuelle DocShell + xMed = new SfxMedium( sFileNm, STREAM_STD_READ, TRUE ); + SvLinkSource::StreamToLoadFrom aStreamToLoadFrom = + getStreamToLoadFrom(); + xMed->setStreamToLoadFrom( + aStreamToLoadFrom.m_xInputStreamToLoadFrom, + aStreamToLoadFrom.m_bIsReadOnly); + // setStreamToLoadFrom(0,0); + if( sReferer.Len() ) + xMed->SetReferer( sReferer ); + + if( !bSynchron ) + { + bLoadAgain = bDataReady = bInNewData = FALSE; + bWaitForData = TRUE; + + SfxMediumRef xTmpMed = xMed; + xMed->SetDataAvailableLink( STATIC_LINK( this, SvFileObject, LoadGrfNewData_Impl ) ); + bInCallDownLoad = TRUE; + xMed->DownLoad( STATIC_LINK( this, SvFileObject, LoadGrfReady_Impl ) ); + bInCallDownLoad = FALSE; + + bClearMedium = !xMed.Is(); + if( bClearMedium ) + xMed = xTmpMed; // falls gleich im DownLoad schon schluss ist + return bDataReady; + } + + bWaitForData = TRUE; + bDataReady = bInNewData = FALSE; + xMed->DownLoad(); + bLoadAgain = !xMed->IsRemote(); + bWaitForData = FALSE; + + // Grafik ist fertig, also DataChanged von der Statusaederung schicken: + SendStateChg_Impl( xMed->GetInStream() && xMed->GetInStream()->GetError() + ? sfx2::LinkManager::STATE_LOAD_ERROR : sfx2::LinkManager::STATE_LOAD_OK ); + return TRUE; +} + + +BOOL SvFileObject::GetGraphic_Impl( Graphic& rGrf, SvStream* pStream ) +{ + GraphicFilter* pGF = GraphicFilter::GetGraphicFilter(); + + const USHORT nFilter = sFilter.Len() && pGF->GetImportFormatCount() + ? pGF->GetImportFormatNumber( sFilter ) + : GRFILTER_FORMAT_DONTKNOW; + + String aEmptyStr; + int nRes; + + // vermeiden, dass ein native Link angelegt wird + if( ( !pStream || !pDownLoadData ) && !rGrf.IsLink() && + !rGrf.GetContext() && !bNativFormat ) + rGrf.SetLink( GfxLink() ); + + if( !pStream ) + nRes = xMed.Is() ? GRFILTER_OPENERROR + : pGF->ImportGraphic( rGrf, INetURLObject(sFileNm), + nFilter ); + else if( !pDownLoadData ) + { + pStream->Seek( STREAM_SEEK_TO_BEGIN ); + nRes = pGF->ImportGraphic( rGrf, aEmptyStr, *pStream, nFilter ); + } + else + { + nRes = pGF->ImportGraphic( pDownLoadData->aGrf, aEmptyStr, + *pStream, nFilter ); + + if( pDownLoadData ) + { + rGrf = pDownLoadData->aGrf; + if( GRAPHIC_NONE == rGrf.GetType() ) + rGrf.SetDefaultType(); + + + if( !pDownLoadData->aGrf.GetContext() ) + { + xMed->SetDataAvailableLink( Link() ); +// xMed->SetDoneLink( Link() ); + delete pDownLoadData, pDownLoadData = 0; + bDataReady = TRUE; + bWaitForData = FALSE; + } + else if( FALSE ) + { + // Timer aufsetzen, um zurueck zukehren + pDownLoadData->aTimer.Start(); + } + } + } + + if( pStream && ERRCODE_IO_PENDING == pStream->GetError() ) + pStream->ResetError(); + +#ifdef DBG_UTIL + if( nRes ) + { + if( xMed.Is() && !pStream ) + { + DBG_WARNING3( "GrafikFehler [%d] - [%s] URL[%s]", + nRes, + xMed->GetPhysicalName().GetBuffer(), + sFileNm.GetBuffer() ); + } + else + { + DBG_WARNING2( "GrafikFehler [%d] - [%s]", + nRes, sFileNm.GetBuffer() ); + } + } +#endif + + return GRFILTER_OK == nRes; +} + +/** detect the filter of the given file + + @param _rURL + specifies the URL of the file which filter is to detected.<br/> + If the URL doesn't denote a valid (existent and accessible) file, the + request is silently dropped. +*/ +String impl_getFilter( const String& _rURL ) +{ + String sFilter; + if ( _rURL.Len() == 0 ) + return sFilter; + + try + { + css::uno::Reference< ::com::sun::star::document::XTypeDetection > xTypeDetection( + ::comphelper::getProcessServiceFactory()->createInstance( + ::rtl::OUString::createFromAscii("com.sun.star.document.TypeDetection") ), + css::uno::UNO_QUERY ); + if ( xTypeDetection.is() ) + { + ::comphelper::MediaDescriptor aDescr; + aDescr[ ::comphelper::MediaDescriptor::PROP_URL() ] <<= ::rtl::OUString( _rURL ); + css::uno::Sequence< css::beans::PropertyValue > aDescrList = + aDescr.getAsConstPropertyValueList(); + ::rtl::OUString sType = xTypeDetection->queryTypeByDescriptor( aDescrList, sal_True ); + if ( sType.getLength() ) + { + css::uno::Reference< css::container::XNameAccess > xTypeCont( xTypeDetection, + css::uno::UNO_QUERY ); + if ( xTypeCont.is() ) + { + ::comphelper::SequenceAsHashMap lTypeProps( xTypeCont->getByName( sType ) ); + sFilter = lTypeProps.getUnpackedValueOrDefault( + ::rtl::OUString::createFromAscii("PreferredFilter"), ::rtl::OUString() ); + } + } + } + } + catch( const css::uno::Exception& ) + { + } + + return sFilter; +} + +void SvFileObject::Edit( Window* pParent, sfx2::SvBaseLink* pLink, const Link& rEndEditHdl ) +{ + aEndEditLink = rEndEditHdl; + String sFile, sRange, sTmpFilter; + if( pLink && pLink->GetLinkManager() ) + { + pLink->GetLinkManager()->GetDisplayNames( pLink, 0, &sFile, &sRange, &sTmpFilter ); + + switch( pLink->GetObjType() ) + { + case OBJECT_CLIENT_GRF: + { + nType = FILETYPE_GRF; // falls noch nicht gesetzt + + SvxOpenGraphicDialog aDlg(SfxResId(RID_SVXSTR_EDITGRFLINK)); + aDlg.EnableLink(sal_False); + aDlg.SetPath( sFile, sal_True ); + aDlg.SetCurrentFilter( sTmpFilter ); + + if( !aDlg.Execute() ) + { + sFile = aDlg.GetPath(); + sFile += ::sfx2::cTokenSeperator; + sFile += ::sfx2::cTokenSeperator; + sFile += aDlg.GetCurrentFilter(); + + if ( aEndEditLink.IsSet() ) + aEndEditLink.Call( &sFile ); + } + else + sFile.Erase(); + } + break; + + case OBJECT_CLIENT_OLE: + { + nType = FILETYPE_OBJECT; // if not set already + pOldParent = Application::GetDefDialogParent(); + Application::SetDefDialogParent( pParent ); + + ::sfx2::FileDialogHelper* pFileDlg = + pLink->GetFileDialog( (SFXWB_INSERT | WB_3DLOOK), String() ); + pFileDlg->StartExecuteModal( LINK( this, SvFileObject, DialogClosedHdl ) ); + } + break; + + case OBJECT_CLIENT_FILE: + { + nType = FILETYPE_TEXT; // if not set already + pOldParent = Application::GetDefDialogParent(); + Application::SetDefDialogParent( pParent ); + + String sFactory; + SfxObjectShell* pShell = pLink->GetLinkManager()->GetPersist(); + if ( pShell ) + sFactory = pShell->GetFactory().GetFactoryName(); + + ::sfx2::FileDialogHelper* pFileDlg = + pLink->GetFileDialog( (SFXWB_INSERT | WB_3DLOOK), sFactory ); + pFileDlg->StartExecuteModal( LINK( this, SvFileObject, DialogClosedHdl ) ); + } + break; + + default: + sFile.Erase(); + } + } +} + +IMPL_STATIC_LINK( SvFileObject, LoadGrfReady_Impl, void*, EMPTYARG ) +{ + // wenn wir von hier kommen, kann es kein Fehler mehr sein + pThis->bLoadError = FALSE; + pThis->bWaitForData = FALSE; + pThis->bInCallDownLoad = FALSE; + + if( !pThis->bInNewData && !pThis->bDataReady ) + { + // Grafik ist fertig, also DataChanged von der Status- + // aederung schicken: + pThis->bDataReady = TRUE; + pThis->SendStateChg_Impl( sfx2::LinkManager::STATE_LOAD_OK ); + + // und dann nochmal die Daten senden + pThis->NotifyDataChanged(); + } + + if( pThis->bDataReady ) + { + pThis->bLoadAgain = TRUE; + if( pThis->xMed.Is() ) + { + pThis->xMed->SetDataAvailableLink( Link() ); + pThis->xMed->SetDoneLink( Link() ); + + Application::PostUserEvent( + STATIC_LINK( pThis, SvFileObject, DelMedium_Impl ), + new SfxMediumRef( pThis->xMed )); + pThis->xMed.Clear(); + } + if( pThis->pDownLoadData ) + delete pThis->pDownLoadData, pThis->pDownLoadData = 0; + } + + return 0; +} + +IMPL_STATIC_LINK( SvFileObject, DelMedium_Impl, SfxMediumRef*, pDelMed ) +{ + (void)pThis; + delete pDelMed; + return 0; +} + +IMPL_STATIC_LINK( SvFileObject, LoadGrfNewData_Impl, void*, EMPTYARG ) +{ + // wenn wir von hier kommen, kann es kein Fehler mehr sein + if( pThis->bInNewData ) + return 0; + + pThis->bInNewData = TRUE; + pThis->bLoadError = FALSE; + + if( !pThis->pDownLoadData ) + { + pThis->pDownLoadData = new Impl_DownLoadData( + STATIC_LINK( pThis, SvFileObject, LoadGrfNewData_Impl ) ); + + // Null-Link setzen, damit keine temporaeren Grafiken + // rausgeswapt werden; der Filter prueft, ob schon + // ein Link gesetzt ist => falls dies zutrifft, wird + // _kein_ neuer Link gesetzt; der Link muss hier gesetzt werden, + // (bevor das erste Mal gefiltert wird), um zu verhindern, + // dass der Kontext zurueckgesetzt wird (aynchrones Laden) + if( !pThis->bNativFormat ) + { + static GfxLink aDummyLink; + pThis->pDownLoadData->aGrf.SetLink( aDummyLink ); + } + } + + pThis->NotifyDataChanged(); + + SvStream* pStrm = pThis->xMed.Is() ? pThis->xMed->GetInStream() : 0; + if( pStrm && pStrm->GetError() ) + { + if( ERRCODE_IO_PENDING == pStrm->GetError() ) + pStrm->ResetError(); + + // im DataChanged ein DataReady? + else if( pThis->bWaitForData && pThis->pDownLoadData ) + { + pThis->bLoadError = TRUE; + } + } + + if( pThis->bDataReady ) + { + // Grafik ist fertig, also DataChanged von der Status- + // aederung schicken: + pThis->SendStateChg_Impl( pStrm->GetError() ? sfx2::LinkManager::STATE_LOAD_ERROR : sfx2::LinkManager::STATE_LOAD_OK ); + } + + pThis->bInNewData = FALSE; + return 0; +} + +IMPL_LINK( SvFileObject, DialogClosedHdl, sfx2::FileDialogHelper*, _pFileDlg ) +{ + String sFile; + Application::SetDefDialogParent( pOldParent ); + + if ( FILETYPE_TEXT == nType || FILETYPE_OBJECT == nType ) + { + if ( _pFileDlg && _pFileDlg->GetError() == ERRCODE_NONE ) + { + String sURL( _pFileDlg->GetPath() ); + sFile = sURL; + sFile += ::sfx2::cTokenSeperator; + sFile += ::sfx2::cTokenSeperator; + sFile += impl_getFilter( sURL ); + } + } + else + { + DBG_ERRORFILE( "SvFileObject::DialogClosedHdl(): wrong file type" ); + } + + if ( aEndEditLink.IsSet() ) + aEndEditLink.Call( &sFile ); + return 0; +} + +/* [Beschreibung] + + Die Methode stellt fest, ob aus einem DDE-Object die Daten gelesen + werden kann. + Zurueckgegeben wird: + ERRCODE_NONE wenn sie komplett gelesen wurde + ERRCODE_SO_PENDING wenn sie noch nicht komplett gelesen wurde + ERRCODE_SO_FALSE sonst +*/ +BOOL SvFileObject::IsPending() const +{ + return FILETYPE_GRF == nType && !bLoadError && + ( pDownLoadData || bWaitForData ); +} +BOOL SvFileObject::IsDataComplete() const +{ + BOOL bRet = FALSE; + if( FILETYPE_GRF != nType ) + bRet = TRUE; + else if( !bLoadError && ( !bWaitForData && !pDownLoadData )) + { + SvFileObject* pThis = (SvFileObject*)this; + if( bDataReady || + ( bSynchron && pThis->LoadFile_Impl() && xMed.Is() ) ) + bRet = TRUE; + else + { + INetURLObject aUrl( sFileNm ); + if( aUrl.HasError() || + INET_PROT_NOT_VALID == aUrl.GetProtocol() ) + bRet = TRUE; + } + } + return bRet; +} + + + +void SvFileObject::CancelTransfers() +{ + // und aus dem Cache austragen, wenn man mitten im Laden ist + if( !bDataReady ) + { + // nicht noch mal aufsetzen + bLoadAgain = FALSE; + bDataReady = bLoadError = bWaitForData = TRUE; + SendStateChg_Impl( sfx2::LinkManager::STATE_LOAD_ABORT ); + } +} + + +void SvFileObject::SendStateChg_Impl( sfx2::LinkManager::LinkState nState ) +{ + if( !bStateChangeCalled && HasDataLinks() ) + { + css::uno::Any aAny; + aAny <<= rtl::OUString::valueOf( (sal_Int32)nState ); + DataChanged( SotExchange::GetFormatName( + sfx2::LinkManager::RegisterStatusInfoId()), aAny ); + bStateChangeCalled = TRUE; + } +} + + diff --git a/sfx2/source/appl/fileobj.hxx b/sfx2/source/appl/fileobj.hxx new file mode 100644 index 000000000000..50f934a75436 --- /dev/null +++ b/sfx2/source/appl/fileobj.hxx @@ -0,0 +1,95 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _FILEOBJ_HXX +#define _FILEOBJ_HXX + +#include <tools/string.hxx> +#include <sfx2/linksrc.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/linkmgr.hxx> + +class Graphic; +struct Impl_DownLoadData; +namespace sfx2 { class FileDialogHelper; } + +class SvFileObject : public sfx2::SvLinkSource +{ + String sFileNm; + String sFilter; + String sReferer; + Link aEndEditLink; + SfxMediumRef xMed; + Impl_DownLoadData* pDownLoadData; + Window* pOldParent; + + BYTE nType; + + BOOL bLoadAgain : 1; + BOOL bSynchron : 1; + BOOL bLoadError : 1; + BOOL bWaitForData : 1; + BOOL bInNewData : 1; + BOOL bDataReady : 1; + BOOL bMedUseCache : 1; + BOOL bNativFormat : 1; + BOOL bClearMedium : 1; + BOOL bStateChangeCalled : 1; + BOOL bInCallDownLoad : 1; + + BOOL GetGraphic_Impl( Graphic&, SvStream* pStream = 0 ); + BOOL LoadFile_Impl(); + void SendStateChg_Impl( sfx2::LinkManager::LinkState nState ); + + DECL_STATIC_LINK( SvFileObject, DelMedium_Impl, SfxMediumRef* ); + DECL_STATIC_LINK( SvFileObject, LoadGrfReady_Impl, void* ); + DECL_STATIC_LINK( SvFileObject, LoadGrfNewData_Impl, void* ); + DECL_LINK( DialogClosedHdl, sfx2::FileDialogHelper* ); + +protected: + virtual ~SvFileObject(); + +public: + SvFileObject(); + + virtual BOOL GetData( ::com::sun::star::uno::Any & rData /*out param*/, + const String & rMimeType, + BOOL bSynchron = FALSE ); + + virtual BOOL Connect( sfx2::SvBaseLink* ); + virtual void Edit( Window *, sfx2::SvBaseLink *, const Link& rEndEditHdl ); + + // erfrage ob das man direkt auf die Daten zugreifen kann oder ob das + // erst angestossen werden muss + virtual BOOL IsPending() const; + virtual BOOL IsDataComplete() const; + + void CancelTransfers(); +}; + + +#endif + diff --git a/sfx2/source/appl/fwkhelper.cxx b/sfx2/source/appl/fwkhelper.cxx new file mode 100644 index 000000000000..1909bcac2e17 --- /dev/null +++ b/sfx2/source/appl/fwkhelper.cxx @@ -0,0 +1,59 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/frame/XFrame.hpp> +#include "sal/config.h" + +#include <vos/mutex.hxx> +#include <vcl/svapp.hxx> + +#include "workwin.hxx" +#include <sfx2/frame.hxx> + +void SAL_CALL RefreshToolbars( ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame ) +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + if ( xFrame.is() ) + { + SfxFrame* pFrame=0; + for ( pFrame = SfxFrame::GetFirst(); pFrame; pFrame = SfxFrame::GetNext( *pFrame ) ) + { + if ( pFrame->GetFrameInterface() == xFrame ) + break; + } + + if ( pFrame ) + { + SfxWorkWindow* pWrkWin = pFrame->GetWorkWindow_Impl(); + if ( pWrkWin ) + pWrkWin->UpdateObjectBars_Impl(); + } + } +} diff --git a/sfx2/source/appl/helpdispatch.cxx b/sfx2/source/appl/helpdispatch.cxx new file mode 100644 index 000000000000..2e1128aea277 --- /dev/null +++ b/sfx2/source/appl/helpdispatch.cxx @@ -0,0 +1,123 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" + +#include "helpdispatch.hxx" +#include <sfx2/sfxuno.hxx> +#include "newhelp.hxx" +#include <tools/debug.hxx> +#include <tools/urlobj.hxx> +#include <com/sun/star/frame/XNotifyingDispatch.hpp> + +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::util; + +// class HelpInterceptor_Impl -------------------------------------------- + +HelpDispatch_Impl::HelpDispatch_Impl( HelpInterceptor_Impl& _rInterceptor, + const ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XDispatch >& _xDisp ) : + + m_rInterceptor ( _rInterceptor ), + m_xRealDispatch ( _xDisp ) + +{ +} + +// ----------------------------------------------------------------------- + +HelpDispatch_Impl::~HelpDispatch_Impl() +{ +} + +// ----------------------------------------------------------------------- +// XDispatch + +void SAL_CALL HelpDispatch_Impl::dispatch( + + const URL& aURL, const Sequence< PropertyValue >& aArgs ) throw( RuntimeException ) + +{ + DBG_ASSERT( m_xRealDispatch.is(), "invalid dispatch" ); + + // search for a keyword (dispatch from the basic ide) + sal_Bool bHasKeyword = sal_False; + String sKeyword; + const PropertyValue* pBegin = aArgs.getConstArray(); + const PropertyValue* pEnd = pBegin + aArgs.getLength(); + for ( ; pBegin != pEnd; ++pBegin ) + { + if ( 0 == ( *pBegin ).Name.compareToAscii( "HelpKeyword" ) ) + { + rtl::OUString sHelpKeyword; + if ( ( ( *pBegin ).Value >>= sHelpKeyword ) && sHelpKeyword.getLength() > 0 ) + { + sKeyword = String( sHelpKeyword ); + bHasKeyword = ( sKeyword.Len() > 0 ); + break; + } + } + } + + // if a keyword was found, then open it + SfxHelpWindow_Impl* pHelpWin = m_rInterceptor.GetHelpWindow(); + DBG_ASSERT( pHelpWin, "invalid HelpWindow" ); + if ( bHasKeyword ) + { + pHelpWin->OpenKeyword( sKeyword ); + return; + } + + pHelpWin->loadHelpContent(aURL.Complete); +} + +// ----------------------------------------------------------------------- + +void SAL_CALL HelpDispatch_Impl::addStatusListener( + + const Reference< XStatusListener >& xControl, const URL& aURL ) throw( RuntimeException ) + +{ + DBG_ASSERT( m_xRealDispatch.is(), "invalid dispatch" ); + m_xRealDispatch->addStatusListener( xControl, aURL ); +} + +// ----------------------------------------------------------------------- + +void SAL_CALL HelpDispatch_Impl::removeStatusListener( + + const Reference< XStatusListener >& xControl, const URL& aURL ) throw( RuntimeException ) + +{ + DBG_ASSERT( m_xRealDispatch.is(), "invalid dispatch" ); + m_xRealDispatch->removeStatusListener( xControl, aURL ); +} + diff --git a/sfx2/source/appl/helpdispatch.hxx b/sfx2/source/appl/helpdispatch.hxx new file mode 100644 index 000000000000..b9d1e7b17b63 --- /dev/null +++ b/sfx2/source/appl/helpdispatch.hxx @@ -0,0 +1,54 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef SFX_HELPDISPATCH_HXX +#define SFX_HELPDISPATCH_HXX + +#include <com/sun/star/frame/XDispatch.hpp> +#include <cppuhelper/implbase1.hxx> + +#include "helpinterceptor.hxx" + +class HelpDispatch_Impl : public ::cppu::WeakImplHelper1< ::com::sun::star::frame::XDispatch > +{ +private: + HelpInterceptor_Impl& m_rInterceptor; + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > + m_xRealDispatch; + +public: + HelpDispatch_Impl( HelpInterceptor_Impl& _rInterceptor, + const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch >& _xDisp ); + ~HelpDispatch_Impl(); + + // XDispatch + virtual void SAL_CALL dispatch( const ::com::sun::star::util::URL& aURL, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aArgs ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addStatusListener( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener >& xControl, const ::com::sun::star::util::URL& aURL ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeStatusListener( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener >& xControl, const ::com::sun::star::util::URL& aURL ) throw(::com::sun::star::uno::RuntimeException); +}; + +#endif // #ifndef SFX_HELPDISPATCHER_HXX + diff --git a/sfx2/source/appl/helpinterceptor.cxx b/sfx2/source/appl/helpinterceptor.cxx new file mode 100644 index 000000000000..2d997dcc26ff --- /dev/null +++ b/sfx2/source/appl/helpinterceptor.cxx @@ -0,0 +1,367 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" + +#include "helpinterceptor.hxx" +#include "helpdispatch.hxx" +#include "newhelp.hxx" +#include <sfx2/sfxuno.hxx> +#include <tools/urlobj.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/frame/XNotifyingDispatch.hpp> +#include <cppuhelper/interfacecontainer.h> +#include <vcl/window.hxx> +#include <limits.h> + +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::lang; + +extern void AppendConfigToken_Impl( String& rURL, sal_Bool bQuestionMark ); // sfxhelp.cxx + +// class HelpInterceptor_Impl -------------------------------------------- + +HelpInterceptor_Impl::HelpInterceptor_Impl() : + + m_pHistory ( NULL ), + m_nCurPos ( 0 ) + +{ +} + +// ----------------------------------------------------------------------- + +HelpInterceptor_Impl::~HelpInterceptor_Impl() +{ + for ( USHORT i = 0; m_pHistory && i < m_pHistory->Count(); ++i ) + delete m_pHistory->GetObject(i); + delete m_pHistory; +} + +// ----------------------------------------------------------------------- + +void HelpInterceptor_Impl::addURL( const String& rURL ) +{ + if ( !m_pHistory ) + m_pHistory = new HelpHistoryList_Impl; + ULONG nCount = m_pHistory->Count(); + if ( nCount && m_nCurPos < ( nCount - 1 ) ) + { + for ( ULONG i = nCount - 1; i > m_nCurPos; i-- ) + delete m_pHistory->Remove(i); + } + Reference<XFrame> xFrame(m_xIntercepted, UNO_QUERY); + Reference<XController> xController; + if(xFrame.is()) + xController = xFrame->getController(); + Any aViewData; + if(xController.is() && m_pHistory->Count()) + { + m_pHistory->GetObject(m_nCurPos)->aViewData = xController->getViewData(); + } + + m_aCurrentURL = rURL; + Any aEmptyViewData; + m_pHistory->Insert( new HelpHistoryEntry_Impl( rURL, aEmptyViewData ), LIST_APPEND ); + m_nCurPos = m_pHistory->Count() - 1; +// TODO ? + if ( m_xListener.is() ) + { + ::com::sun::star::frame::FeatureStateEvent aEvent; + URL aURL; + aURL.Complete = rURL; + aEvent.FeatureURL = aURL; + aEvent.Source = (::com::sun::star::frame::XDispatch*)this; + m_xListener->statusChanged( aEvent ); + } + + m_pWindow->UpdateToolbox(); +} + +// ----------------------------------------------------------------------- + +void HelpInterceptor_Impl::setInterception( Reference< XFrame > xFrame ) +{ + m_xIntercepted = Reference< XDispatchProviderInterception>( xFrame, UNO_QUERY ); + + if ( m_xIntercepted.is() ) + m_xIntercepted->registerDispatchProviderInterceptor( (XDispatchProviderInterceptor*)this ); +} + +// ----------------------------------------------------------------------- + +void HelpInterceptor_Impl::SetStartURL( const String& rURL ) +{ + DBG_ASSERT( !m_pHistory, "invalid history" ); + if ( !m_pHistory ) + { + m_pHistory = new HelpHistoryList_Impl; + Any aEmptyViewData; + m_pHistory->Insert( new HelpHistoryEntry_Impl( rURL, aEmptyViewData ), ((ULONG)0x0) ); + m_nCurPos = m_pHistory->Count() - 1; + + m_pWindow->UpdateToolbox(); + } + m_aCurrentURL = rURL; +} + +sal_Bool HelpInterceptor_Impl::HasHistoryPred() const +{ + return m_pHistory && ( m_nCurPos > 0 ); +} + +sal_Bool HelpInterceptor_Impl::HasHistorySucc() const +{ + return m_pHistory && ( m_nCurPos < ( m_pHistory->Count() - 1 ) ); +} + + +// ----------------------------------------------------------------------- +// XDispatchProvider + +Reference< XDispatch > SAL_CALL HelpInterceptor_Impl::queryDispatch( + + const URL& aURL, const ::rtl::OUString& aTargetFrameName, sal_Int32 nSearchFlags ) + + throw( RuntimeException ) + +{ + Reference< XDispatch > xResult; + if ( m_xSlaveDispatcher.is() ) + xResult = m_xSlaveDispatcher->queryDispatch( aURL, aTargetFrameName, nSearchFlags ); + + // INetURLObject aObj( aURL.Complete ); + // sal_Bool bHelpURL = ( aObj.GetProtocol() == INET_PROT_VND_SUN_STAR_HELP ); + BOOL bHelpURL = aURL.Complete.toAsciiLowerCase().match(rtl::OUString::createFromAscii("vnd.sun.star.help"),0); + + if ( bHelpURL ) + { + DBG_ASSERT( xResult.is(), "invalid dispatch" ); + HelpDispatch_Impl* pHelpDispatch = new HelpDispatch_Impl( *this, xResult ); + xResult = Reference< XDispatch >( static_cast< ::cppu::OWeakObject* >(pHelpDispatch), UNO_QUERY ); + } + + return xResult; +} + +// ----------------------------------------------------------------------- + +Sequence < Reference < XDispatch > > SAL_CALL HelpInterceptor_Impl::queryDispatches( + + const Sequence< DispatchDescriptor >& aDescripts ) + + throw( RuntimeException ) + +{ + Sequence< Reference< XDispatch > > aReturn( aDescripts.getLength() ); + Reference< XDispatch >* pReturn = aReturn.getArray(); + const DispatchDescriptor* pDescripts = aDescripts.getConstArray(); + for ( sal_Int16 i = 0; i < aDescripts.getLength(); ++i, ++pReturn, ++pDescripts ) + { + *pReturn = queryDispatch( pDescripts->FeatureURL, pDescripts->FrameName, pDescripts->SearchFlags ); + } + return aReturn; +} + +// ----------------------------------------------------------------------- +// XDispatchProviderInterceptor + +Reference< XDispatchProvider > SAL_CALL HelpInterceptor_Impl::getSlaveDispatchProvider() + + throw( RuntimeException ) + +{ + return m_xSlaveDispatcher; +} + +// ----------------------------------------------------------------------- + +void SAL_CALL HelpInterceptor_Impl::setSlaveDispatchProvider( const Reference< XDispatchProvider >& xNewSlave ) + + throw( RuntimeException ) + +{ + m_xSlaveDispatcher = xNewSlave; +} + +// ----------------------------------------------------------------------- + +Reference< XDispatchProvider > SAL_CALL HelpInterceptor_Impl::getMasterDispatchProvider() + + throw( RuntimeException ) + +{ + return m_xMasterDispatcher; +} + +// ----------------------------------------------------------------------- + +void SAL_CALL HelpInterceptor_Impl::setMasterDispatchProvider( const Reference< XDispatchProvider >& xNewMaster ) + + throw( RuntimeException ) + +{ + m_xMasterDispatcher = xNewMaster; +} + +// ----------------------------------------------------------------------- +// XInterceptorInfo + +Sequence< ::rtl::OUString > SAL_CALL HelpInterceptor_Impl::getInterceptedURLs() + + throw( RuntimeException ) + +{ + Sequence< ::rtl::OUString > aURLList( 1 ); + aURLList[0] = DEFINE_CONST_UNICODE("vnd.sun.star.help://*"); + return aURLList;; +} + +// ----------------------------------------------------------------------- +// XDispatch + +void SAL_CALL HelpInterceptor_Impl::dispatch( + const URL& aURL, const Sequence< ::com::sun::star::beans::PropertyValue >& ) throw( RuntimeException ) +{ + sal_Bool bBack = ( String( DEFINE_CONST_UNICODE(".uno:Backward") ) == String( aURL.Complete ) ); + if ( bBack || String( DEFINE_CONST_UNICODE(".uno:Forward") ) == String( aURL.Complete ) ) + { + if ( m_pHistory ) + { + if(m_pHistory->Count() > m_nCurPos) + { + Reference<XFrame> xFrame(m_xIntercepted, UNO_QUERY); + Reference<XController> xController; + if(xFrame.is()) + xController = xFrame->getController(); + if(xController.is()) + { + m_pHistory->GetObject(m_nCurPos)->aViewData = xController->getViewData(); + } + } + + ULONG nPos = ( bBack && m_nCurPos > 0 ) ? --m_nCurPos + : ( !bBack && m_nCurPos < m_pHistory->Count() - 1 ) + ? ++m_nCurPos + : ULONG_MAX; + + if ( nPos < ULONG_MAX ) + { + HelpHistoryEntry_Impl* pEntry = m_pHistory->GetObject( nPos ); + if ( pEntry ) + m_pWindow->loadHelpContent(pEntry->aURL, sal_False); // false => dont add item to history again! + } + + m_pWindow->UpdateToolbox(); + } + } +} + +// ----------------------------------------------------------------------- + +void SAL_CALL HelpInterceptor_Impl::addStatusListener( + const Reference< XStatusListener >& xControl, const URL& ) throw( RuntimeException ) +{ + DBG_ASSERT( !m_xListener.is(), "listener already exists" ); + m_xListener = xControl; +} + +// ----------------------------------------------------------------------- + +void SAL_CALL HelpInterceptor_Impl::removeStatusListener( + const Reference< XStatusListener >&, const URL&) throw( RuntimeException ) +{ + m_xListener = 0; +} + +// HelpListener_Impl ----------------------------------------------------- + +HelpListener_Impl::HelpListener_Impl( HelpInterceptor_Impl* pInter ) +{ + pInterceptor = pInter; + pInterceptor->addStatusListener( this, ::com::sun::star::util::URL() ); +} + +// ----------------------------------------------------------------------- + +void SAL_CALL HelpListener_Impl::statusChanged( const ::com::sun::star::frame::FeatureStateEvent& Event ) + + throw( ::com::sun::star::uno::RuntimeException ) + +{ + INetURLObject aObj( Event.FeatureURL.Complete ); + aFactory = aObj.GetHost(); + aChangeLink.Call( this ); +} + +// ----------------------------------------------------------------------- + +void SAL_CALL HelpListener_Impl::disposing( const ::com::sun::star::lang::EventObject& ) + + throw( ::com::sun::star::uno::RuntimeException ) + +{ + pInterceptor->removeStatusListener( this, ::com::sun::star::util::URL() ); + pInterceptor = NULL; +} +/*-- 05.09.2002 12:17:59--------------------------------------------------- + + -----------------------------------------------------------------------*/ +HelpStatusListener_Impl::HelpStatusListener_Impl( + Reference < XDispatch > aDispatch, URL& rURL) +{ + aDispatch->addStatusListener(this, rURL); +} +/*-- 05.09.2002 12:17:59--------------------------------------------------- + + -----------------------------------------------------------------------*/ +HelpStatusListener_Impl::~HelpStatusListener_Impl() +{ + if(xDispatch.is()) + xDispatch->removeStatusListener(this, com::sun::star::util::URL()); +} +/*-- 05.09.2002 12:17:59--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void HelpStatusListener_Impl::statusChanged( + const FeatureStateEvent& rEvent ) throw( RuntimeException ) +{ + aStateEvent = rEvent; +} +/*-- 05.09.2002 12:18:00--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void HelpStatusListener_Impl::disposing( const EventObject& ) throw( RuntimeException ) +{ + xDispatch->removeStatusListener(this, com::sun::star::util::URL()); + xDispatch = 0; +} diff --git a/sfx2/source/appl/helpinterceptor.hxx b/sfx2/source/appl/helpinterceptor.hxx new file mode 100644 index 000000000000..3476f0d305b5 --- /dev/null +++ b/sfx2/source/appl/helpinterceptor.hxx @@ -0,0 +1,173 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef INCLUDED_SFX_HELPINTERCEPTOR_HXX +#define INCLUDED_SFX_HELPINTERCEPTOR_HXX + +#ifndef _CPPUHELPER_IMPLBASE2_HXX_ +#include <cppuhelper/implbase3.hxx> +#endif +#include <com/sun/star/frame/XDispatchProviderInterceptor.hpp> +#include <com/sun/star/frame/XInterceptorInfo.hpp> +#include <com/sun/star/frame/XDispatch.hpp> +#include <com/sun/star/frame/XDispatchProviderInterception.hpp> +#include <com/sun/star/frame/XFrame.hpp> +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/frame/XStatusListener.hpp> +#include <tools/string.hxx> +#include <tools/list.hxx> +#include <tools/link.hxx> + +struct HelpHistoryEntry_Impl +{ + String aURL; + com::sun::star::uno::Any aViewData; + + HelpHistoryEntry_Impl( const String& rURL, const com::sun::star::uno::Any& rViewData ) : + aURL( rURL ), aViewData(rViewData) {} +}; + +DECLARE_LIST(HelpHistoryList_Impl,HelpHistoryEntry_Impl*) + +class SfxHelpWindow_Impl; +class HelpInterceptor_Impl : public ::cppu::WeakImplHelper3< + + ::com::sun::star::frame::XDispatchProviderInterceptor, + ::com::sun::star::frame::XInterceptorInfo, + ::com::sun::star::frame::XDispatch > + +{ +private: +friend class HelpDispatch_Impl; +friend class SfxHelpWindow_Impl; + + // the component which's dispatches we're intercepting + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProviderInterception > m_xIntercepted; + + // chaining + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider > m_xSlaveDispatcher; + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider > m_xMasterDispatcher; + + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener > m_xListener; + + HelpHistoryList_Impl* m_pHistory; + SfxHelpWindow_Impl* m_pWindow; + ULONG m_nCurPos; + String m_aCurrentURL; + com::sun::star::uno::Any m_aViewData; + + void addURL( const String& rURL ); + +public: + HelpInterceptor_Impl(); + ~HelpInterceptor_Impl(); + + void setInterception( ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xFrame ); + void SetStartURL( const String& rURL ); + String GetCurrentURL() const { return m_aCurrentURL; } + + + + const com::sun::star::uno::Any& GetViewData()const {return m_aViewData;} + + sal_Bool HasHistoryPred() const; // is there a predecessor for the current in the history + sal_Bool HasHistorySucc() const; // is there a successor for the current in the history + + // XDispatchProvider + virtual ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > SAL_CALL + queryDispatch( const ::com::sun::star::util::URL& aURL, const ::rtl::OUString& aTargetFrameName, sal_Int32 nSearchFlags ) throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > > SAL_CALL + queryDispatches( const ::com::sun::star::uno::Sequence< ::com::sun::star::frame::DispatchDescriptor >& aDescripts ) throw(::com::sun::star::uno::RuntimeException); + + // XDispatchProviderInterceptor + virtual ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider > SAL_CALL + getSlaveDispatchProvider( ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setSlaveDispatchProvider( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider >& xNewSlave ) throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider > SAL_CALL + getMasterDispatchProvider( ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setMasterDispatchProvider( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider >& xNewMaster ) throw(::com::sun::star::uno::RuntimeException); + + // XInterceptorInfo + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL + getInterceptedURLs( ) throw(::com::sun::star::uno::RuntimeException); + + // XDispatch + virtual void SAL_CALL dispatch( const ::com::sun::star::util::URL& aURL, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aArgs ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addStatusListener( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener >& xControl, const ::com::sun::star::util::URL& aURL ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeStatusListener( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener >& xControl, const ::com::sun::star::util::URL& aURL ) throw(::com::sun::star::uno::RuntimeException); + + // extras + void InitWaiter( SfxHelpWindow_Impl* pWindow ) + { m_pWindow = pWindow; } + SfxHelpWindow_Impl* GetHelpWindow() const { return m_pWindow; } +}; + +// HelpListener_Impl ----------------------------------------------------- + +class HelpListener_Impl : public ::cppu::WeakImplHelper1< ::com::sun::star::frame::XStatusListener > +{ +private: + HelpInterceptor_Impl* pInterceptor; + Link aChangeLink; + String aFactory; + +public: + HelpListener_Impl( HelpInterceptor_Impl* pInter ); + + virtual void SAL_CALL statusChanged( const ::com::sun::star::frame::FeatureStateEvent& Event ) + throw( ::com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& obj ) + throw( ::com::sun::star::uno::RuntimeException ); + + void SetChangeHdl( const Link& rLink ) { aChangeLink = rLink; } + String GetFactory() const { return aFactory; } +}; +// HelpStatusListener_Impl ----------------------------------------------------- + +class HelpStatusListener_Impl : public +::cppu::WeakImplHelper1< ::com::sun::star::frame::XStatusListener > +{ +private: + ::com::sun::star::uno::Reference < ::com::sun::star::frame::XDispatch > xDispatch; + ::com::sun::star::frame::FeatureStateEvent aStateEvent; + +public: + HelpStatusListener_Impl( + ::com::sun::star::uno::Reference < ::com::sun::star::frame::XDispatch > xDispatch, + com::sun::star::util::URL& rURL); + ~HelpStatusListener_Impl(); + + virtual void SAL_CALL statusChanged( const ::com::sun::star::frame::FeatureStateEvent& Event ) + throw( ::com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& obj ) + throw( ::com::sun::star::uno::RuntimeException ); + const ::com::sun::star::frame::FeatureStateEvent& + GetStateEvent() const {return aStateEvent;} +}; + + +#endif // #ifndef INCLUDED_SFX_HELPINTERCEPTOR_HXX + diff --git a/sfx2/source/appl/imagemgr.cxx b/sfx2/source/appl/imagemgr.cxx new file mode 100644 index 000000000000..3b26eae1858d --- /dev/null +++ b/sfx2/source/appl/imagemgr.cxx @@ -0,0 +1,234 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" +#include "imagemgr.hxx" +#include <com/sun/star/frame/XController.hpp> +#include <com/sun/star/ui/XImageManager.hpp> +#include <com/sun/star/frame/XModuleManager.hpp> +#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp> +#include <com/sun/star/ui/ImageType.hpp> +#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp> + +#include <tools/urlobj.hxx> +#include <svtools/imagemgr.hxx> +#include <comphelper/processfactory.hxx> +#include <rtl/ustring.hxx> +#include <rtl/logfile.hxx> + +#include "imgmgr.hxx" +#include <sfx2/app.hxx> +#include <sfx2/unoctitm.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/msg.hxx> +#include <sfx2/msgpool.hxx> +#include <sfx2/viewfrm.hxx> +#include <sfx2/module.hxx> +#include <sfx2/objsh.hxx> +#include <sfx2/docfac.hxx> + +#include <hash_map> + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::ui; +using namespace ::com::sun::star::frame; + +typedef std::hash_map< ::rtl::OUString, + WeakReference< XImageManager >, + ::rtl::OUStringHash, + ::std::equal_to< ::rtl::OUString > > ModuleIdToImagegMgr; + +static WeakReference< XModuleManager > m_xModuleManager; +static WeakReference< XModuleUIConfigurationManagerSupplier > m_xModuleCfgMgrSupplier; +static WeakReference< XURLTransformer > m_xURLTransformer; +static ModuleIdToImagegMgr m_aModuleIdToImageMgrMap; + +Image SAL_CALL GetImage( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame, const ::rtl::OUString& aURL, BOOL bBig, BOOL bHiContrast ) +{ + // TODO/LATeR: shouldn't this become a method at SfxViewFrame?! That would save the UnoTunnel + if ( !rFrame.is() ) + return Image(); + + INetURLObject aObj( aURL ); + INetProtocol nProtocol = aObj.GetProtocol(); + + Reference < XController > xController; + Reference < XModel > xModel; + if ( rFrame.is() ) + xController = rFrame->getController(); + if ( xController.is() ) + xModel = xController->getModel(); + + rtl::OUString aCommandURL( aURL ); + if ( nProtocol == INET_PROT_SLOT ) + { + /* + // Support old way to retrieve image via slot URL + Reference< XURLTransformer > xURLTransformer = m_xURLTransformer; + if ( !xURLTransformer.is() ) + { + xURLTransformer = Reference< XURLTransformer >( + ::comphelper::getProcessServiceFactory()->createInstance( + rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" )), + UNO_QUERY ); + m_xURLTransformer = xURLTransformer; + } + + URL aTargetURL; + aTargetURL.Complete = aURL; + xURLTransformer->parseStrict( aTargetURL ); + USHORT nId = ( USHORT ) aTargetURL.Path.toInt32();*/ + USHORT nId = ( USHORT ) String(aURL).Copy(5).ToInt32(); + const SfxSlot* pSlot = 0; + if ( xModel.is() ) + { + Reference < XUnoTunnel > xObj( xModel, UNO_QUERY ); + Sequence < sal_Int8 > aSeq( SvGlobalName( SFX_GLOBAL_CLASSID ).GetByteSequence() ); + sal_Int64 nHandle = xObj.is() ? xObj->getSomething( aSeq ) : 0; + if ( nHandle ) + { + SfxObjectShell* pDoc = reinterpret_cast<SfxObjectShell*>(sal::static_int_cast<sal_IntPtr>( nHandle )); + SfxModule* pModule = pDoc->GetFactory().GetModule(); + pSlot = pModule->GetSlotPool()->GetSlot( nId ); + } + } + else + pSlot = SfxSlotPool::GetSlotPool().GetSlot( nId ); + + if ( pSlot ) + { + aCommandURL = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:" )); + aCommandURL += rtl::OUString::createFromAscii( pSlot->GetUnoName() ); + } + else + aCommandURL = rtl::OUString(); + } + + Reference< XImageManager > xDocImgMgr; + if ( xModel.is() ) + { + Reference< XUIConfigurationManagerSupplier > xSupplier( xModel, UNO_QUERY ); + if ( xSupplier.is() ) + { + Reference< XUIConfigurationManager > xDocUICfgMgr( xSupplier->getUIConfigurationManager(), UNO_QUERY ); + xDocImgMgr = Reference< XImageManager >( xDocUICfgMgr->getImageManager(), UNO_QUERY ); + } + } + + sal_Int16 nImageType( ::com::sun::star::ui::ImageType::COLOR_NORMAL| + ::com::sun::star::ui::ImageType::SIZE_DEFAULT ); + if ( bBig ) + nImageType |= ::com::sun::star::ui::ImageType::SIZE_LARGE; + if ( bHiContrast ) + nImageType |= ::com::sun::star::ui::ImageType::COLOR_HIGHCONTRAST; + + if ( xDocImgMgr.is() ) + { + Sequence< Reference< ::com::sun::star::graphic::XGraphic > > aGraphicSeq; + Sequence< rtl::OUString > aImageCmdSeq( 1 ); + aImageCmdSeq[0] = aCommandURL; + + try + { + aGraphicSeq = xDocImgMgr->getImages( nImageType, aImageCmdSeq ); + Reference< ::com::sun::star::graphic::XGraphic > xGraphic = aGraphicSeq[0]; + Image aImage( xGraphic ); + + if ( !!aImage ) + return aImage; + } + catch ( Exception& ) + { + } + } + + Reference< XModuleManager > xModuleManager = m_xModuleManager; + + if ( !xModuleManager.is() ) + { + xModuleManager = Reference< XModuleManager >( + ::comphelper::getProcessServiceFactory()->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.frame.ModuleManager" ))), + UNO_QUERY ); + m_xModuleManager = xModuleManager; + } + + try + { + if ( aCommandURL.getLength() > 0 ) + { + Reference< XImageManager > xModuleImageManager; + rtl::OUString aModuleId = xModuleManager->identify( rFrame ); + ModuleIdToImagegMgr::iterator pIter = m_aModuleIdToImageMgrMap.find( aModuleId ); + if ( pIter != m_aModuleIdToImageMgrMap.end() ) + xModuleImageManager = pIter->second; + else + { + Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier = m_xModuleCfgMgrSupplier; + + if ( !xModuleCfgMgrSupplier.is() ) + { + xModuleCfgMgrSupplier = Reference< XModuleUIConfigurationManagerSupplier >( + ::comphelper::getProcessServiceFactory()->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.ui.ModuleUIConfigurationManagerSupplier" ))), + UNO_QUERY ); + + m_xModuleCfgMgrSupplier = xModuleCfgMgrSupplier; + } + + Reference< XUIConfigurationManager > xUICfgMgr = xModuleCfgMgrSupplier->getUIConfigurationManager( aModuleId ); + xModuleImageManager = Reference< XImageManager >( xUICfgMgr->getImageManager(), UNO_QUERY ); + m_aModuleIdToImageMgrMap.insert( ModuleIdToImagegMgr::value_type( aModuleId, xModuleImageManager )); + } + + Sequence< Reference< ::com::sun::star::graphic::XGraphic > > aGraphicSeq; + Sequence< rtl::OUString > aImageCmdSeq( 1 ); + aImageCmdSeq[0] = aCommandURL; + + aGraphicSeq = xModuleImageManager->getImages( nImageType, aImageCmdSeq ); + + Reference< ::com::sun::star::graphic::XGraphic > xGraphic = aGraphicSeq[0]; + Image aImage( xGraphic ); + + if ( !!aImage ) + return aImage; + else if ( nProtocol != INET_PROT_UNO && nProtocol != INET_PROT_SLOT ) + return SvFileInformationManager::GetImageNoDefault( aObj, bBig, bHiContrast ); + } + } + catch ( Exception& ) + { + } + + return Image(); +} diff --git a/sfx2/source/appl/imestatuswindow.cxx b/sfx2/source/appl/imestatuswindow.cxx new file mode 100644 index 000000000000..07eb47bd92ad --- /dev/null +++ b/sfx2/source/appl/imestatuswindow.cxx @@ -0,0 +1,231 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" + +#include "imestatuswindow.hxx" + +#include <sfx2/app.hxx> +#include <sfx2/sfxsids.hrc> + +#include "com/sun/star/beans/PropertyState.hpp" +#include "com/sun/star/beans/PropertyValue.hpp" +#include "com/sun/star/beans/XPropertySet.hpp" +#include "com/sun/star/lang/DisposedException.hpp" +#include "com/sun/star/lang/XMultiServiceFactory.hpp" +#include "com/sun/star/uno/Any.hxx" +#include "com/sun/star/uno/Exception.hpp" +#include "com/sun/star/uno/Reference.hxx" +#include "com/sun/star/uno/RuntimeException.hpp" +#include "com/sun/star/uno/Sequence.hxx" +#include "com/sun/star/util/XChangesBatch.hpp" +#include "osl/diagnose.h" +#include "osl/mutex.hxx" +#include "rtl/ustring.h" +#include "rtl/ustring.hxx" +#include "sal/types.h" +#include "vcl/svapp.hxx" +#include "vos/mutex.hxx" + +namespace css = com::sun::star; + +using sfx2::appl::ImeStatusWindow; + +ImeStatusWindow::ImeStatusWindow( + css::uno::Reference< css::lang::XMultiServiceFactory > const & + rServiceFactory): + m_xServiceFactory(rServiceFactory), + m_bDisposed(false) +{} + +void ImeStatusWindow::init() +{ + if (Application::CanToggleImeStatusWindow()) + try + { + sal_Bool bShow = sal_Bool(); + if (getConfig()->getPropertyValue( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "ShowStatusWindow"))) + >>= bShow) + Application::ShowImeStatusWindow(bShow); + } + catch (css::uno::Exception &) + { + OSL_ENSURE(false, "com.sun.star.uno.Exception"); + // Degrade gracefully and use the VCL-supplied default if no + // configuration is available. + } +} + +bool ImeStatusWindow::isShowing() +{ + try + { + sal_Bool bShow = sal_Bool(); + if (getConfig()->getPropertyValue( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowStatusWindow"))) + >>= bShow) + return bShow; + } + catch (css::uno::Exception &) + { + OSL_ENSURE(false, "com.sun.star.uno.Exception"); + // Degrade gracefully and use the VCL-supplied default if no + // configuration is available. + } + return Application::GetShowImeStatusWindowDefault(); +} + +void ImeStatusWindow::show(bool bShow) +{ + try + { + css::uno::Reference< css::beans::XPropertySet > xConfig(getConfig()); + xConfig->setPropertyValue( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowStatusWindow")), + css::uno::makeAny(static_cast< sal_Bool >(bShow))); + css::uno::Reference< css::util::XChangesBatch > xCommit( + xConfig, css::uno::UNO_QUERY); + // Degrade gracefully by not saving the settings permanently: + if (xCommit.is()) + xCommit->commitChanges(); + // Alternatively, setting the VCL status could be done even if updating + // the configuration failed: + Application::ShowImeStatusWindow(bShow); + } + catch (css::uno::Exception &) + { + OSL_ENSURE(false, "com.sun.star.uno.Exception"); + } +} + +bool ImeStatusWindow::canToggle() const +{ + return Application::CanToggleImeStatusWindow(); +} + +ImeStatusWindow::~ImeStatusWindow() +{ + if (m_xConfig.is()) + // We should never get here, but just in case... + try + { + m_xConfig->removePropertyChangeListener( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowStatusWindow")), + this); + } + catch (css::uno::Exception &) + { + OSL_ENSURE(false, "com.sun.star.uno.RuntimeException"); + } +} + +void SAL_CALL ImeStatusWindow::disposing(css::lang::EventObject const & ) + throw (css::uno::RuntimeException) +{ + osl::MutexGuard aGuard(m_aMutex); + m_xConfig = 0; + m_bDisposed = true; +} + +void SAL_CALL +ImeStatusWindow::propertyChange(css::beans::PropertyChangeEvent const & ) + throw (css::uno::RuntimeException) +{ + vos::OGuard aGuard(Application::GetSolarMutex()); + SfxApplication* pApp = SfxApplication::Get(); + if (pApp) + pApp->Invalidate(SID_SHOW_IME_STATUS_WINDOW); +} + +css::uno::Reference< css::beans::XPropertySet > ImeStatusWindow::getConfig() +{ + css::uno::Reference< css::beans::XPropertySet > xConfig; + bool bAdd = false; + { + osl::MutexGuard aGuard(m_aMutex); + if (!m_xConfig.is()) + { + if (m_bDisposed) + throw css::lang::DisposedException(); + if (!m_xServiceFactory.is()) + throw css::uno::RuntimeException( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "null comphelper::getProcessServiceFactory")), + 0); + css::uno::Reference< css::lang::XMultiServiceFactory > xProvider( + m_xServiceFactory->createInstance( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.configuration.ConfigurationProvider"))), + css::uno::UNO_QUERY); + if (!xProvider.is()) + throw css::uno::RuntimeException( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "null com.sun.star.configuration." + "ConfigurationProvider")), + 0); + css::beans::PropertyValue aArg( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("nodepath")), -1, + css::uno::makeAny( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "/org.openoffice.Office.Common/I18N/InputMethod"))), + css::beans::PropertyState_DIRECT_VALUE); + css::uno::Sequence< css::uno::Any > aArgs(1); + aArgs[0] <<= aArg; + m_xConfig + = css::uno::Reference< css::beans::XPropertySet >( + xProvider->createInstanceWithArguments( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.configuration.ConfigurationUpdateAccess")), + aArgs), + css::uno::UNO_QUERY); + if (!m_xConfig.is()) + throw css::uno::RuntimeException( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "null com.sun.star.configuration." + "ConfigurationUpdateAccess")), + 0); + bAdd = true; + } + xConfig = m_xConfig; + } + if (bAdd) + // Exceptions here could be handled individually, to support graceful + // degradation (no update notification mechanism in this case---but also + // no dispose notifications): + xConfig->addPropertyChangeListener( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowStatusWindow")), + this); + return xConfig; +} + diff --git a/sfx2/source/appl/imestatuswindow.hxx b/sfx2/source/appl/imestatuswindow.hxx new file mode 100644 index 000000000000..4edba523ed30 --- /dev/null +++ b/sfx2/source/appl/imestatuswindow.hxx @@ -0,0 +1,125 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#if !defined INCLUDED_SFX2_APPL_IMESTATUSWINDOW_HXX +#define INCLUDED_SFX2_APPL_IMESTATUSWINDOW_HXX + +#include "com/sun/star/beans/XPropertyChangeListener.hpp" +#include "com/sun/star/uno/Reference.hxx" +#include "cppuhelper/implbase1.hxx" +#include "osl/mutex.hxx" + +namespace com { namespace sun { namespace star { + namespace beans { class XPropertySet; } + namespace lang { class XMultiServiceFactory; } +} } } + +namespace sfx2 { namespace appl { + +// The MS compiler needs this typedef work-around to accept the using +// declarations within ImeStatusWindow: +typedef cppu::WeakImplHelper1< com::sun::star::beans::XPropertyChangeListener > +ImeStatusWindow_Impl; + +/** Control the behavior of any (platform-dependent) IME status windows. + + The decision of whether a status window shall be displayed or not can be + stored permanently in the configuration (under key + org.openoffice.office.Common/I18N/InputMethod/ShowStatusWindow; if that + entry is nil, VCL is asked for a default). + */ +class ImeStatusWindow: private ImeStatusWindow_Impl +{ +public: + ImeStatusWindow( com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > const& rServiceFactory ); + + /** Set up VCL according to the configuration. + + Is it not strictly required that this method is called exactly once + (though that will be the typical use). + + Must only be called with the Solar mutex locked. + */ + void init(); + + /** Return true if the status window is toggled on. + + This is only meaningful when canToggle returns true. + + Can be called without the Solar mutex locked. + */ + bool isShowing(); + + /** Toggle the status window on or off. + + This only works if canToggle returns true (otherwise, any calls of this + method are ignored). + + Must only be called with the Solar mutex locked. + */ + void show(bool bShow); + + /** Return true if the status window can be toggled on and off externally. + + Must only be called with the Solar mutex locked. + */ + bool canToggle() const; + + using ImeStatusWindow_Impl::acquire; + using ImeStatusWindow_Impl::release; + using ImeStatusWindow_Impl::operator new; + using ImeStatusWindow_Impl::operator delete; + +private: + ImeStatusWindow(ImeStatusWindow &); // not implemented + void operator =(ImeStatusWindow); // not implemented + + virtual ~ImeStatusWindow(); + + virtual void SAL_CALL + disposing(com::sun::star::lang::EventObject const & rSource) + throw (com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + propertyChange(com::sun::star::beans::PropertyChangeEvent const & rEvent) + throw (com::sun::star::uno::RuntimeException); + + com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > + getConfig(); + + com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > + m_xServiceFactory; + + osl::Mutex m_aMutex; + com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > + m_xConfig; + bool m_bDisposed; +}; + +} } + +#endif // INCLUDED_SFX2_APPL_IMESTATUSWINDOW_HXX diff --git a/sfx2/source/appl/impldde.cxx b/sfx2/source/appl/impldde.cxx new file mode 100644 index 000000000000..20b7abb5d087 --- /dev/null +++ b/sfx2/source/appl/impldde.cxx @@ -0,0 +1,448 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" + +#if defined(WNT) +#include <tools/svwin.h> +#endif + +#include "impldde.hxx" + +#include <vcl/svapp.hxx> +#include <vcl/fixed.hxx> +#include <vcl/edit.hxx> +#include <vcl/button.hxx> +#include <vcl/msgbox.hxx> +#include <sot/exchange.hxx> +#include <rtl/ustring.hxx> + +#include "dde.hrc" +#include <sfx2/lnkbase.hxx> +#include <sfx2/linkmgr.hxx> +#include "sfxresid.hxx" + +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> + +#include <svl/svdde.hxx> +#include <sot/formats.hxx> + +#define DDELINK_COLD 0 +#define DDELINK_HOT 1 + +#define DDELINK_ERROR_APP 1 +#define DDELINK_ERROR_DATA 2 +#define DDELINK_ERROR_LINK 3 + +using namespace ::com::sun::star::uno; + +namespace sfx2 +{ + +class SvDDELinkEditDialog : public ModalDialog +{ + FixedText aFtDdeApp; + Edit aEdDdeApp; + FixedText aFtDdeTopic; + Edit aEdDdeTopic; + FixedText aFtDdeItem; + Edit aEdDdeItem; + FixedLine aGroupDdeChg; + OKButton aOKButton1; + CancelButton aCancelButton1; + + DECL_STATIC_LINK( SvDDELinkEditDialog, EditHdl_Impl, Edit* ); +public: + SvDDELinkEditDialog( Window* pParent, SvBaseLink* ); + String GetCmd() const; +}; + +SvDDELinkEditDialog::SvDDELinkEditDialog( Window* pParent, SvBaseLink* pLink ) + : ModalDialog( pParent, SfxResId( MD_DDE_LINKEDIT ) ), + aFtDdeApp( this, SfxResId( FT_DDE_APP ) ), + aEdDdeApp( this, SfxResId( ED_DDE_APP ) ), + aFtDdeTopic( this, SfxResId( FT_DDE_TOPIC ) ), + aEdDdeTopic( this, SfxResId( ED_DDE_TOPIC ) ), + aFtDdeItem( this, SfxResId( FT_DDE_ITEM ) ), + aEdDdeItem( this, SfxResId( ED_DDE_ITEM ) ), + aGroupDdeChg( this, SfxResId( GROUP_DDE_CHG ) ), + aOKButton1( this, SfxResId( 1 ) ), + aCancelButton1( this, SfxResId( 1 ) ) +{ + FreeResource(); + + String sServer, sTopic, sItem; + pLink->GetLinkManager()->GetDisplayNames( pLink, &sServer, &sTopic, &sItem ); + + aEdDdeApp.SetText( sServer ); + aEdDdeTopic.SetText( sTopic ); + aEdDdeItem.SetText( sItem ); + + aEdDdeApp.SetModifyHdl( STATIC_LINK( this, SvDDELinkEditDialog, EditHdl_Impl)); + aEdDdeTopic.SetModifyHdl( STATIC_LINK( this, SvDDELinkEditDialog, EditHdl_Impl)); + aEdDdeItem.SetModifyHdl( STATIC_LINK( this, SvDDELinkEditDialog, EditHdl_Impl)); + + aOKButton1.Enable( sServer.Len() && sTopic.Len() && sItem.Len() ); +} + +String SvDDELinkEditDialog::GetCmd() const +{ + String sCmd( aEdDdeApp.GetText() ), sRet; + ::sfx2::MakeLnkName( sRet, &sCmd, aEdDdeTopic.GetText(), aEdDdeItem.GetText() ); + return sRet; +} + +IMPL_STATIC_LINK( SvDDELinkEditDialog, EditHdl_Impl, Edit *, pEdit ) +{ + (void)pEdit; // unused variable + pThis->aOKButton1.Enable( pThis->aEdDdeApp.GetText().Len() && + pThis->aEdDdeTopic.GetText().Len() && + pThis->aEdDdeItem.GetText().Len() ); + return 0; +} + +/* */ + + +SvDDEObject::SvDDEObject() + : pConnection( 0 ), pLink( 0 ), pRequest( 0 ), pGetData( 0 ), nError( 0 ) +{ + SetUpdateTimeout( 100 ); + bWaitForData = FALSE; +} + +SvDDEObject::~SvDDEObject() +{ + delete pLink; + delete pRequest; + delete pConnection; +} + +BOOL SvDDEObject::GetData( ::com::sun::star::uno::Any & rData /*out param*/, + const String & rMimeType, + BOOL bSynchron ) +{ + if( !pConnection ) + return FALSE; + + if( pConnection->GetError() ) // dann versuchen wir es nochmal + { + String sServer( pConnection->GetServiceName() ); + String sTopic( pConnection->GetTopicName() ); + + delete pConnection; + pConnection = new DdeConnection( sServer, sTopic ); + if( pConnection->GetError() ) + nError = DDELINK_ERROR_APP; + } + + if( bWaitForData ) // wir sind rekursiv drin, wieder raus + return FALSE; + + // Verriegeln gegen Reentrance + bWaitForData = TRUE; + + // falls gedruckt werden soll, warten wir bis die Daten vorhanden sind + if( bSynchron ) + { + DdeRequest aReq( *pConnection, sItem, 5000 ); + aReq.SetDataHdl( LINK( this, SvDDEObject, ImplGetDDEData ) ); + aReq.SetFormat( SotExchange::GetFormatIdFromMimeType( rMimeType )); + + pGetData = &rData; + + do { + aReq.Execute(); + } while( aReq.GetError() && ImplHasOtherFormat( aReq ) ); + + if( pConnection->GetError() ) + nError = DDELINK_ERROR_DATA; + + bWaitForData = FALSE; + } + else + { + // ansonsten wird es asynchron ausgefuehrt +// if( !pLink || !pLink->IsBusy() ) + { + if( pRequest ) + delete pRequest; + + pRequest = new DdeRequest( *pConnection, sItem ); + pRequest->SetDataHdl( LINK( this, SvDDEObject, ImplGetDDEData ) ); + pRequest->SetDoneHdl( LINK( this, SvDDEObject, ImplDoneDDEData ) ); + pRequest->SetFormat( SotExchange::GetFormatIdFromMimeType( + rMimeType ) ); + pRequest->Execute(); + } + + ::rtl::OUString aEmptyStr; + rData <<= aEmptyStr; + } + return 0 == pConnection->GetError(); +} + + +BOOL SvDDEObject::Connect( SvBaseLink * pSvLink ) +{ +#if defined(WNT) + static BOOL bInWinExec = FALSE; +#endif + USHORT nLinkType = pSvLink->GetUpdateMode(); + if( pConnection ) // Verbindung steht ja schon + { + // tja, dann nur noch als Abhaengig eintragen + AddDataAdvise( pSvLink, + SotExchange::GetFormatMimeType( pSvLink->GetContentType()), + LINKUPDATE_ONCALL == nLinkType + ? ADVISEMODE_ONLYONCE + : 0 ); + AddConnectAdvise( pSvLink ); + + return TRUE; + } + + if( !pSvLink->GetLinkManager() ) + return FALSE; + + String sServer, sTopic; + pSvLink->GetLinkManager()->GetDisplayNames( pSvLink, &sServer, &sTopic, &sItem ); + + if( !sServer.Len() || !sTopic.Len() || !sItem.Len() ) + return FALSE; + + pConnection = new DdeConnection( sServer, sTopic ); + if( pConnection->GetError() ) + { + // kann man denn das System-Topic ansprechen ? + // dann ist der Server oben, kennt nur nicht das Topic! + if( sTopic.EqualsIgnoreCaseAscii( "SYSTEM" ) ) + { + BOOL bSysTopic; + { + DdeConnection aTmp( sServer, String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "SYSTEM" ) ) ); + bSysTopic = !aTmp.GetError(); + } + + if( bSysTopic ) + { + nError = DDELINK_ERROR_DATA; + return FALSE; + } + // ansonsten unter Win/WinNT die Applikation direkt starten + } + +#if defined(WNT) + + // Server nicht da, starten und nochmal versuchen + if( !bInWinExec ) + { + ByteString aCmdLine( sServer, RTL_TEXTENCODING_ASCII_US ); + aCmdLine.Append( ".exe " ); + aCmdLine.Append( ByteString( sTopic, RTL_TEXTENCODING_ASCII_US ) ); + + if( WinExec( aCmdLine.GetBuffer(), SW_SHOWMINIMIZED ) < 32 ) + nError = DDELINK_ERROR_APP; + else + { + USHORT i; + for( i=0; i<5; i++ ) + { + bInWinExec = TRUE; + Application::Reschedule(); + bInWinExec = FALSE; + + delete pConnection; + pConnection = new DdeConnection( sServer, sTopic ); + if( !pConnection->GetError() ) + break; + } + + if( i == 5 ) + { + nError = DDELINK_ERROR_APP; + } + } + } + else +#endif // WNT + { + nError = DDELINK_ERROR_APP; + } + } + + if( LINKUPDATE_ALWAYS == nLinkType && !pLink && !pConnection->GetError() ) + { + // Hot Link einrichten, Daten kommen irgendwann spaeter + pLink = new DdeHotLink( *pConnection, sItem ); + pLink->SetDataHdl( LINK( this, SvDDEObject, ImplGetDDEData ) ); + pLink->SetDoneHdl( LINK( this, SvDDEObject, ImplDoneDDEData ) ); + pLink->SetFormat( pSvLink->GetContentType() ); + pLink->Execute(); + } + + if( pConnection->GetError() ) + return FALSE; + + AddDataAdvise( pSvLink, + SotExchange::GetFormatMimeType( pSvLink->GetContentType()), + LINKUPDATE_ONCALL == nLinkType + ? ADVISEMODE_ONLYONCE + : 0 ); + AddConnectAdvise( pSvLink ); + SetUpdateTimeout( 0 ); + return TRUE; +} + +void SvDDEObject::Edit( Window* pParent, sfx2::SvBaseLink* pBaseLink, const Link& rEndEditHdl ) +{ + SvDDELinkEditDialog aDlg( pParent, pBaseLink ); + if ( RET_OK == aDlg.Execute() && rEndEditHdl.IsSet() ) + { + String sCommand = aDlg.GetCmd(); + rEndEditHdl.Call( &sCommand ); + } +} + +BOOL SvDDEObject::ImplHasOtherFormat( DdeTransaction& rReq ) +{ + USHORT nFmt = 0; + switch( rReq.GetFormat() ) + { + case FORMAT_RTF: + nFmt = FORMAT_STRING; + break; + + case SOT_FORMATSTR_ID_HTML_SIMPLE: + case SOT_FORMATSTR_ID_HTML: + nFmt = FORMAT_RTF; + break; + + case FORMAT_GDIMETAFILE: + nFmt = FORMAT_BITMAP; + break; + + case SOT_FORMATSTR_ID_SVXB: + nFmt = FORMAT_GDIMETAFILE; + break; + + // sonst noch irgendwas ?? + } + if( nFmt ) + rReq.SetFormat( nFmt ); // damit nochmal versuchen + return 0 != nFmt; +} + +BOOL SvDDEObject::IsPending() const +/* [Beschreibung] + + Die Methode stellt fest, ob aus einem DDE-Object die Daten gelesen + werden kann. + Zurueckgegeben wird: + ERRCODE_NONE wenn sie komplett gelesen wurde + ERRCODE_SO_PENDING wenn sie noch nicht komplett gelesen wurde + ERRCODE_SO_FALSE sonst +*/ +{ + return bWaitForData; +} + +BOOL SvDDEObject::IsDataComplete() const +{ + return bWaitForData; +} + +IMPL_LINK( SvDDEObject, ImplGetDDEData, DdeData*, pData ) +{ + ULONG nFmt = pData->GetFormat(); + switch( nFmt ) + { + case FORMAT_GDIMETAFILE: + break; + + case FORMAT_BITMAP: + break; + + default: + { + const sal_Char* p = (sal_Char*)( pData->operator const void*() ); + long nLen = FORMAT_STRING == nFmt ? (p ? strlen( p ) : 0) : (long)*pData; + + Sequence< sal_Int8 > aSeq( (const sal_Int8*)p, nLen ); + if( pGetData ) + { + *pGetData <<= aSeq; // Daten kopieren + pGetData = 0; // und den Pointer bei mir zuruecksetzen + } + else + { + Any aVal; + aVal <<= aSeq; + DataChanged( SotExchange::GetFormatMimeType( + pData->GetFormat() ), aVal ); + bWaitForData = FALSE; + } + } + } + + return 0; +} + +IMPL_LINK( SvDDEObject, ImplDoneDDEData, void*, pData ) +{ + BOOL bValid = (BOOL)(ULONG)pData; + if( !bValid && ( pRequest || pLink )) + { + DdeTransaction* pReq = 0; + if( !pLink || ( pLink && pLink->IsBusy() )) + pReq = pRequest; // dann kann nur der fertig sein + else if( pRequest && pRequest->IsBusy() ) + pReq = pLink; // dann kann nur der fertig sein + + if( pReq ) + { + if( ImplHasOtherFormat( *pReq ) ) + { + pReq->Execute(); + } + else if( pReq == pRequest ) + { + // das wars dann + bWaitForData = FALSE; + } + } + } + else + // das warten ist beendet + bWaitForData = FALSE; + + return 0; +} + +} diff --git a/sfx2/source/appl/impldde.hxx b/sfx2/source/appl/impldde.hxx new file mode 100644 index 000000000000..b361df4468d3 --- /dev/null +++ b/sfx2/source/appl/impldde.hxx @@ -0,0 +1,78 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _IMPLDDE_HXX +#define _IMPLDDE_HXX + +#include <sfx2/linksrc.hxx> +#include <tools/string.hxx> + +class DdeConnection; +class DdeData; +class DdeLink; +class DdeRequest; +class DdeTransaction; + +namespace sfx2 +{ + +class SvDDEObject : public SvLinkSource +{ + String sItem; + + DdeConnection* pConnection; + DdeLink* pLink; + DdeRequest* pRequest; + ::com::sun::star::uno::Any * pGetData; + + BYTE bWaitForData : 1; // wird auf Daten gewartet? + BYTE nError : 7; // Error Code fuer den Dialog + + + BOOL ImplHasOtherFormat( DdeTransaction& ); + DECL_LINK( ImplGetDDEData, DdeData* ); + DECL_LINK( ImplDoneDDEData, void* ); + +protected: + virtual ~SvDDEObject(); + +public: + SvDDEObject(); + + virtual BOOL GetData( ::com::sun::star::uno::Any & rData /*out param*/, + const String & aMimeType, + BOOL bSynchron = FALSE ); + + virtual BOOL Connect( SvBaseLink * ); + virtual void Edit( Window* pParent, sfx2::SvBaseLink* pBaseLink, const Link& rEndEditHdl ); + + virtual BOOL IsPending() const; + virtual BOOL IsDataComplete() const; +}; + +} + +#endif diff --git a/sfx2/source/appl/linkmgr2.cxx b/sfx2/source/appl/linkmgr2.cxx new file mode 100644 index 000000000000..ce69ba225157 --- /dev/null +++ b/sfx2/source/appl/linkmgr2.cxx @@ -0,0 +1,636 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" + +#include <sfx2/linkmgr.hxx> +#include <com/sun/star/document/UpdateDocMode.hpp> +#include <sfx2/objsh.hxx> +#include <svl/urihelper.hxx> +#include <sot/formats.hxx> +#include <tools/urlobj.hxx> +#include <sot/exchange.hxx> +#include <tools/debug.hxx> +#include <vcl/msgbox.hxx> +#include <sfx2/lnkbase.hxx> +#include <sfx2/app.hxx> +#include <vcl/graph.hxx> +#include <svl/stritem.hxx> +#include <svl/eitem.hxx> +#include <svl/intitem.hxx> +#include <unotools/localfilehelper.hxx> +#include <i18npool/mslangid.hxx> +#include <sfx2/request.hxx> + +#include "fileobj.hxx" +#include "impldde.hxx" +#include "app.hrc" +#include "sfxresid.hxx" + +#define _SVSTDARR_STRINGSDTOR +#include <svl/svstdarr.hxx> + +namespace sfx2 +{ + +class SvxInternalLink : public sfx2::SvLinkSource +{ +public: + SvxInternalLink() {} + + virtual BOOL Connect( sfx2::SvBaseLink* ); +}; + + +SV_IMPL_PTRARR( SvBaseLinks, SvBaseLinkRefPtr ) + +LinkManager::LinkManager(SfxObjectShell* p) + : pPersist( p ) +{ +} + + +LinkManager::~LinkManager() +{ + SvBaseLinkRef** ppRef = (SvBaseLinkRef**)aLinkTbl.GetData(); + for( USHORT n = aLinkTbl.Count(); n; --n, ++ppRef ) + { + if( (*ppRef)->Is() ) + { + (*(*ppRef))->Disconnect(); + (*(*ppRef))->SetLinkManager( NULL ); + } + delete *ppRef; + } +} + + +/************************************************************************ +|* LinkManager::Remove() +|* +|* Beschreibung +*************************************************************************/ + +void LinkManager::Remove( SvBaseLink *pLink ) +{ + // keine Links doppelt einfuegen + int bFound = FALSE; + SvBaseLinkRef** ppRef = (SvBaseLinkRef**)aLinkTbl.GetData(); + for( USHORT n = aLinkTbl.Count(); n; --n, ++ppRef ) + { + if( pLink == *(*ppRef) ) + { + (*(*ppRef))->Disconnect(); + (*(*ppRef))->SetLinkManager( NULL ); + (*(*ppRef)).Clear(); + bFound = TRUE; + } + + // falls noch leere rum stehen sollten, weg damit + if( !(*ppRef)->Is() ) + { + delete *ppRef; + aLinkTbl.Remove( aLinkTbl.Count() - n, 1 ); + if( bFound ) + return ; + --ppRef; + } + } +} + + +void LinkManager::Remove( USHORT nPos, USHORT nCnt ) +{ + if( nCnt && nPos < aLinkTbl.Count() ) + { + if( nPos + nCnt > aLinkTbl.Count() ) + nCnt = aLinkTbl.Count() - nPos; + + SvBaseLinkRef** ppRef = (SvBaseLinkRef**)aLinkTbl.GetData() + nPos; + for( USHORT n = nCnt; n; --n, ++ppRef ) + { + if( (*ppRef)->Is() ) + { + (*(*ppRef))->Disconnect(); + (*(*ppRef))->SetLinkManager( NULL ); + } + delete *ppRef; + } + aLinkTbl.Remove( nPos, nCnt ); + } +} + + +BOOL LinkManager::Insert( SvBaseLink* pLink ) +{ + // keine Links doppelt einfuegen + for( USHORT n = 0; n < aLinkTbl.Count(); ++n ) + { + SvBaseLinkRef* pTmp = aLinkTbl[ n ]; + if( !pTmp->Is() ) + aLinkTbl.DeleteAndDestroy( n-- ); + + if( pLink == *pTmp ) + return FALSE; + } + + SvBaseLinkRef* pTmp = new SvBaseLinkRef( pLink ); + pLink->SetLinkManager( this ); + aLinkTbl.Insert( pTmp, aLinkTbl.Count() ); + return TRUE; +} + + +BOOL LinkManager::InsertLink( SvBaseLink * pLink, + USHORT nObjType, + USHORT nUpdateMode, + const String* pName ) +{ + // unbedingt zuerst + pLink->SetObjType( nObjType ); + if( pName ) + pLink->SetName( *pName ); + pLink->SetUpdateMode( nUpdateMode ); + return Insert( pLink ); +} + + +BOOL LinkManager::InsertDDELink( SvBaseLink * pLink, + const String& rServer, + const String& rTopic, + const String& rItem ) +{ + if( !( OBJECT_CLIENT_SO & pLink->GetObjType() ) ) + return FALSE; + + String sCmd; + ::sfx2::MakeLnkName( sCmd, &rServer, rTopic, rItem ); + + pLink->SetObjType( OBJECT_CLIENT_DDE ); + pLink->SetName( sCmd ); + return Insert( pLink ); +} + + +BOOL LinkManager::InsertDDELink( SvBaseLink * pLink ) +{ + DBG_ASSERT( OBJECT_CLIENT_SO & pLink->GetObjType(), "no OBJECT_CLIENT_SO" ); + if( !( OBJECT_CLIENT_SO & pLink->GetObjType() ) ) + return FALSE; + + if( pLink->GetObjType() == OBJECT_CLIENT_SO ) + pLink->SetObjType( OBJECT_CLIENT_DDE ); + + return Insert( pLink ); +} + + +// erfrage die Strings fuer den Dialog +BOOL LinkManager::GetDisplayNames( const SvBaseLink * pLink, + String* pType, + String* pFile, + String* pLinkStr, + String* pFilter ) const +{ + BOOL bRet = FALSE; + const String sLNm( pLink->GetLinkSourceName() ); + if( sLNm.Len() ) + { + switch( pLink->GetObjType() ) + { + case OBJECT_CLIENT_FILE: + case OBJECT_CLIENT_GRF: + case OBJECT_CLIENT_OLE: + { + USHORT nPos = 0; + String sFile( sLNm.GetToken( 0, ::sfx2::cTokenSeperator, nPos ) ); + String sRange( sLNm.GetToken( 0, ::sfx2::cTokenSeperator, nPos ) ); + + if( pFile ) + *pFile = sFile; + if( pLinkStr ) + *pLinkStr = sRange; + if( pFilter ) + *pFilter = sLNm.Copy( nPos ); + + if( pType ) + { + sal_uInt16 nObjType = pLink->GetObjType(); + *pType = String( SfxResId( + ( OBJECT_CLIENT_FILE == nObjType || OBJECT_CLIENT_OLE == nObjType ) + ? RID_SVXSTR_FILELINK + : RID_SVXSTR_GRAFIKLINK )); + } + bRet = TRUE; + } + break; + case OBJECT_CLIENT_DDE: + { + USHORT nTmp = 0; + String sCmd( sLNm ); + String sServer( sCmd.GetToken( 0, cTokenSeperator, nTmp ) ); + String sTopic( sCmd.GetToken( 0, cTokenSeperator, nTmp ) ); + + if( pType ) + *pType = sServer; + if( pFile ) + *pFile = sTopic; + if( pLinkStr ) + *pLinkStr = sCmd.Copy( nTmp ); + bRet = TRUE; + } + break; + default: + break; + } + } + + return bRet; +} + + +void LinkManager::UpdateAllLinks( + BOOL bAskUpdate, + BOOL /*bCallErrHdl*/, + BOOL bUpdateGrfLinks, + Window* pParentWin ) +{ + SvStringsDtor aApps, aTopics, aItems; + String sApp, sTopic, sItem; + + // erstmal eine Kopie vom Array machen, damit sich updatende Links in + // Links in ... nicht dazwischen funken!! + SvPtrarr aTmpArr( 255, 50 ); + USHORT n; + for( n = 0; n < aLinkTbl.Count(); ++n ) + { + SvBaseLink* pLink = *aLinkTbl[ n ]; + if( !pLink ) + { + Remove( n-- ); + continue; + } + aTmpArr.Insert( pLink, aTmpArr.Count() ); + } + + for( n = 0; n < aTmpArr.Count(); ++n ) + { + SvBaseLink* pLink = (SvBaseLink*)aTmpArr[ n ]; + + // suche erstmal im Array nach dem Eintrag + USHORT nFndPos = USHRT_MAX; + for( USHORT i = 0; i < aLinkTbl.Count(); ++i ) + if( pLink == *aLinkTbl[ i ] ) + { + nFndPos = i; + break; + } + + if( USHRT_MAX == nFndPos ) + continue; // war noch nicht vorhanden! + + // Graphic-Links noch nicht updaten + if( !pLink->IsVisible() || + ( !bUpdateGrfLinks && OBJECT_CLIENT_GRF == pLink->GetObjType() )) + continue; + + if( bAskUpdate ) + { + int nRet = QueryBox( pParentWin, WB_YES_NO | WB_DEF_YES, SfxResId( STR_QUERY_UPDATE_LINKS ) ).Execute(); + if( RET_YES != nRet ) + return ; // es soll nichts geupdatet werden + bAskUpdate = FALSE; // einmal reicht + } + + pLink->Update(); + } +} + +/************************************************************************ +|* SvBaseLink::CreateObject() +|* +|* Beschreibung +*************************************************************************/ + +SvLinkSourceRef LinkManager::CreateObj( SvBaseLink * pLink ) +{ + switch( pLink->GetObjType() ) + { + case OBJECT_CLIENT_FILE: + case OBJECT_CLIENT_GRF: + case OBJECT_CLIENT_OLE: + return new SvFileObject; + case OBJECT_INTERN: + return new SvxInternalLink; + case OBJECT_CLIENT_DDE: + return new SvDDEObject; + default: + return SvLinkSourceRef(); + } +} + +BOOL LinkManager::InsertServer( SvLinkSource* pObj ) +{ + // keine doppelt einfuegen + if( !pObj || USHRT_MAX != aServerTbl.GetPos( pObj ) ) + return FALSE; + + aServerTbl.Insert( pObj, aServerTbl.Count() ); + return TRUE; +} + + +void LinkManager::RemoveServer( SvLinkSource* pObj ) +{ + USHORT nPos = aServerTbl.GetPos( pObj ); + if( USHRT_MAX != nPos ) + aServerTbl.Remove( nPos, 1 ); +} + + +void MakeLnkName( String& rName, const String* pType, const String& rFile, + const String& rLink, const String* pFilter ) +{ + if( pType ) + (rName = *pType).EraseLeadingChars().EraseTrailingChars() += cTokenSeperator; + else if( rName.Len() ) + rName.Erase(); + + ((rName += rFile).EraseLeadingChars().EraseTrailingChars() += + cTokenSeperator ).EraseLeadingChars().EraseTrailingChars() += rLink; + if( pFilter ) + ((rName += cTokenSeperator ) += *pFilter).EraseLeadingChars().EraseTrailingChars(); +} + +BOOL LinkManager::InsertFileLink( sfx2::SvBaseLink& rLink, + USHORT nFileType, + const String& rFileNm, + const String* pFilterNm, + const String* pRange ) +{ + if( !( OBJECT_CLIENT_SO & rLink.GetObjType() )) + return FALSE; + + String sCmd( rFileNm ); + sCmd += ::sfx2::cTokenSeperator; + if( pRange ) + sCmd += *pRange; + if( pFilterNm ) + ( sCmd += ::sfx2::cTokenSeperator ) += *pFilterNm; + + return InsertLink( &rLink, nFileType, sfx2::LINKUPDATE_ONCALL, &sCmd ); +} + +BOOL LinkManager::InsertFileLink( sfx2::SvBaseLink& rLink ) +{ + if( OBJECT_CLIENT_FILE == ( OBJECT_CLIENT_FILE & rLink.GetObjType() )) + return InsertLink( &rLink, rLink.GetObjType(), sfx2::LINKUPDATE_ONCALL ); + return FALSE; +} + +// eine Uebertragung wird abgebrochen, also alle DownloadMedien canceln +// (ist zur Zeit nur fuer die FileLinks interressant!) +void LinkManager::CancelTransfers() +{ + SvFileObject* pFileObj; + sfx2::SvBaseLink* pLnk; + + const sfx2::SvBaseLinks& rLnks = GetLinks(); + for( USHORT n = rLnks.Count(); n; ) + if( 0 != ( pLnk = &(*rLnks[ --n ])) && + OBJECT_CLIENT_FILE == (OBJECT_CLIENT_FILE & pLnk->GetObjType()) && + 0 != ( pFileObj = (SvFileObject*)pLnk->GetObj() ) ) +// 0 != ( pFileObj = (SvFileObject*)SvFileObject::ClassFactory()-> +// CastAndAddRef( pLnk->GetObj() )) ) + pFileObj->CancelTransfers(); +} + + // um Status Informationen aus dem FileObject an den BaseLink zu + // senden, gibt es eine eigene ClipBoardId. Das SvData-Object hat + // dann die entsprechenden Informationen als String. + // Wird zur Zeit fuer FileObject in Verbindung mit JavaScript benoetigt + // - das braucht Informationen ueber Load/Abort/Error +ULONG LinkManager::RegisterStatusInfoId() +{ + static ULONG nFormat = 0; + + if( !nFormat ) + { +// wie sieht die neue Schnittstelle aus? +// nFormat = Exchange::RegisterFormatName( "StatusInfo vom SvxInternalLink" ); + nFormat = SotExchange::RegisterFormatName( + String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( + "StatusInfo vom SvxInternalLink" ))); + } + return nFormat; +} + +// ---------------------------------------------------------------------- + +BOOL LinkManager::GetGraphicFromAny( const String& rMimeType, + const ::com::sun::star::uno::Any & rValue, + Graphic& rGrf ) +{ + BOOL bRet = FALSE; + ::com::sun::star::uno::Sequence< sal_Int8 > aSeq; + if( rValue.hasValue() && ( rValue >>= aSeq ) ) + { + SvMemoryStream aMemStm( (void*)aSeq.getConstArray(), aSeq.getLength(), + STREAM_READ ); + aMemStm.Seek( 0 ); + + switch( SotExchange::GetFormatIdFromMimeType( rMimeType ) ) + { + case SOT_FORMATSTR_ID_SVXB: + { + aMemStm >> rGrf; + bRet = TRUE; + } + break; + case FORMAT_GDIMETAFILE: + { + GDIMetaFile aMtf; + aMtf.Read( aMemStm ); + rGrf = aMtf; + bRet = TRUE; + } + break; + case FORMAT_BITMAP: + { + Bitmap aBmp; + aMemStm >> aBmp; + rGrf = aBmp; + bRet = TRUE; + } + break; + } + } + return bRet; +} + + +// ---------------------------------------------------------------------- +String lcl_DDE_RelToAbs( const String& rTopic, const String& rBaseURL ) +{ + String sRet; + INetURLObject aURL( rTopic ); + if( INET_PROT_NOT_VALID == aURL.GetProtocol() ) + utl::LocalFileHelper::ConvertSystemPathToURL( rTopic, rBaseURL, sRet ); + if( !sRet.Len() ) + sRet = URIHelper::SmartRel2Abs( INetURLObject(rBaseURL), rTopic, URIHelper::GetMaybeFileHdl(), true ); + return sRet; +} + +BOOL SvxInternalLink::Connect( sfx2::SvBaseLink* pLink ) +{ + SfxObjectShell* pFndShell = 0; + USHORT nUpdateMode = com::sun::star::document::UpdateDocMode::NO_UPDATE; + String sTopic, sItem, sReferer; + if( pLink->GetLinkManager() && + pLink->GetLinkManager()->GetDisplayNames( pLink, 0, &sTopic, &sItem ) + && sTopic.Len() ) + { + // erstmal nur ueber die DocumentShells laufen und die mit dem + // Namen heraussuchen: + + com::sun::star::lang::Locale aLocale; + MsLangId::convertLanguageToLocale( LANGUAGE_SYSTEM, aLocale ); + CharClass aCC( aLocale ); + + String sNm( sTopic ), sTmp; + aCC.toLower( sNm ); + + TypeId aType( TYPE(SfxObjectShell) ); + + BOOL bFirst = TRUE; + SfxObjectShell* pShell = pLink->GetLinkManager()->GetPersist(); + if( pShell && pShell->GetMedium() ) + { + sReferer = pShell->GetMedium()->GetBaseURL(); + SFX_ITEMSET_ARG( pShell->GetMedium()->GetItemSet(), pItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False ); + if ( pItem ) + nUpdateMode = pItem->GetValue(); + } + + String sNmURL( lcl_DDE_RelToAbs( sTopic, sReferer ) ); + aCC.toLower( sNmURL ); + + if ( !pShell ) + { + bFirst = FALSE; + pShell = SfxObjectShell::GetFirst( &aType, sal_False ); + } + + while( pShell ) + { + if( !sTmp.Len() ) + { + sTmp = pShell->GetTitle( SFX_TITLE_FULLNAME ); + sTmp = lcl_DDE_RelToAbs(sTmp, sReferer ); + } + + + aCC.toLower( sTmp ); + if( sTmp == sNmURL ) // die wollen wir haben + { + pFndShell = pShell; + break; + } + + if( bFirst ) + { + bFirst = FALSE; + pShell = SfxObjectShell::GetFirst( &aType, sal_False ); + } + else + pShell = SfxObjectShell::GetNext( *pShell, &aType, sal_False ); + + sTmp.Erase(); + } + } + + // empty topics are not allowed - which document is it + if( !sTopic.Len() ) + return FALSE; + + if( !pFndShell ) + { + // dann versuche die Datei zu laden: + INetURLObject aURL( sTopic ); + INetProtocol eOld = aURL.GetProtocol(); + aURL.SetURL( sTopic = lcl_DDE_RelToAbs( sTopic, sReferer ) ); + if( INET_PROT_NOT_VALID != eOld || + INET_PROT_HTTP != aURL.GetProtocol() ) + { + SfxStringItem aName( SID_FILE_NAME, sTopic ); + SfxBoolItem aMinimized(SID_MINIMIZED, TRUE); + SfxBoolItem aHidden(SID_HIDDEN, TRUE); + SfxStringItem aTarget( SID_TARGETNAME, String::CreateFromAscii("_blank") ); + SfxStringItem aReferer( SID_REFERER, sReferer ); + SfxUInt16Item aUpdate( SID_UPDATEDOCMODE, nUpdateMode ); + SfxBoolItem aReadOnly(SID_DOC_READONLY, TRUE); + + // #i14200# (DDE-link crashes wordprocessor) + SfxAllItemSet aArgs( SFX_APP()->GetPool() ); + aArgs.Put(aReferer); + aArgs.Put(aTarget); + aArgs.Put(aHidden); + aArgs.Put(aMinimized); + aArgs.Put(aName); + aArgs.Put(aUpdate); + aArgs.Put(aReadOnly); + pFndShell = SfxObjectShell::CreateAndLoadObject( aArgs ); + } + } + + BOOL bRet = FALSE; + if( pFndShell ) + { + sfx2::SvLinkSource* pNewSrc = pFndShell->DdeCreateLinkSource( sItem ); + if( pNewSrc ) + { + bRet = TRUE; + + ::com::sun::star::datatransfer::DataFlavor aFl; + SotExchange::GetFormatDataFlavor( pLink->GetContentType(), aFl ); + + pLink->SetObj( pNewSrc ); + pNewSrc->AddDataAdvise( pLink, aFl.MimeType, + sfx2::LINKUPDATE_ONCALL == pLink->GetUpdateMode() + ? ADVISEMODE_ONLYONCE + : 0 ); + } + } + return bRet; +} + + +} + + + diff --git a/sfx2/source/appl/linksrc.cxx b/sfx2/source/appl/linksrc.cxx new file mode 100644 index 000000000000..e9fbde42328f --- /dev/null +++ b/sfx2/source/appl/linksrc.cxx @@ -0,0 +1,435 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" + +#include <sfx2/linksrc.hxx> +#include <sfx2/lnkbase.hxx> +//#include <sot/exchange.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> + +#include <tools/debug.hxx> +#include <vcl/timer.hxx> +#include <svl/svarray.hxx> + + +using namespace ::com::sun::star::uno; + +namespace sfx2 +{ + +TYPEINIT0( SvLinkSource ) + +/************** class SvLinkSourceTimer *********************************/ +class SvLinkSourceTimer : public Timer +{ + SvLinkSource * pOwner; + virtual void Timeout(); +public: + SvLinkSourceTimer( SvLinkSource * pOwn ); +}; + +SvLinkSourceTimer::SvLinkSourceTimer( SvLinkSource * pOwn ) + : pOwner( pOwn ) +{ +} + +void SvLinkSourceTimer::Timeout() +{ + // sicher gegen zerstoeren im Handler + SvLinkSourceRef aAdv( pOwner ); + pOwner->SendDataChanged(); +} + +static void StartTimer( SvLinkSourceTimer ** ppTimer, SvLinkSource * pOwner, + ULONG nTimeout ) +{ + if( !*ppTimer ) + { + *ppTimer = new SvLinkSourceTimer( pOwner ); + (*ppTimer)->SetTimeout( nTimeout ); + (*ppTimer)->Start(); + } +} + + +struct SvLinkSource_Entry_Impl +{ + SvBaseLinkRef xSink; + String aDataMimeType; + USHORT nAdviseModes; + BOOL bIsDataSink; + + SvLinkSource_Entry_Impl( SvBaseLink* pLink, const String& rMimeType, + USHORT nAdvMode ) + : xSink( pLink ), aDataMimeType( rMimeType ), + nAdviseModes( nAdvMode ), bIsDataSink( TRUE ) + {} + + SvLinkSource_Entry_Impl( SvBaseLink* pLink ) + : xSink( pLink ), nAdviseModes( 0 ), bIsDataSink( FALSE ) + {} + + ~SvLinkSource_Entry_Impl(); +}; + +SvLinkSource_Entry_Impl::~SvLinkSource_Entry_Impl() +{ +} + +typedef SvLinkSource_Entry_Impl* SvLinkSource_Entry_ImplPtr; +SV_DECL_PTRARR_DEL( SvLinkSource_Array_Impl, SvLinkSource_Entry_ImplPtr, 4, 4 ) +SV_IMPL_PTRARR( SvLinkSource_Array_Impl, SvLinkSource_Entry_ImplPtr ); + +class SvLinkSource_EntryIter_Impl +{ + SvLinkSource_Array_Impl aArr; + const SvLinkSource_Array_Impl& rOrigArr; + USHORT nPos; +public: + SvLinkSource_EntryIter_Impl( const SvLinkSource_Array_Impl& rArr ); + ~SvLinkSource_EntryIter_Impl(); + SvLinkSource_Entry_Impl* Curr() + { return nPos < aArr.Count() ? aArr[ nPos ] : 0; } + SvLinkSource_Entry_Impl* Next(); + sal_Bool IsValidCurrValue( SvLinkSource_Entry_Impl* pEntry ); +}; + +SvLinkSource_EntryIter_Impl::SvLinkSource_EntryIter_Impl( + const SvLinkSource_Array_Impl& rArr ) + : rOrigArr( rArr ), nPos( 0 ) +{ + aArr.Insert( &rArr, 0 ); +} +SvLinkSource_EntryIter_Impl::~SvLinkSource_EntryIter_Impl() +{ + aArr.Remove( 0, aArr.Count() ); +} + +sal_Bool SvLinkSource_EntryIter_Impl::IsValidCurrValue( SvLinkSource_Entry_Impl* pEntry ) +{ + return ( nPos < aArr.Count() && aArr[nPos] == pEntry && USHRT_MAX != rOrigArr.GetPos( pEntry ) ); +} + +SvLinkSource_Entry_Impl* SvLinkSource_EntryIter_Impl::Next() +{ + SvLinkSource_Entry_ImplPtr pRet = 0; + if( nPos + 1 < aArr.Count() ) + { + ++nPos; + if( rOrigArr.Count() == aArr.Count() && + rOrigArr[ nPos ] == aArr[ nPos ] ) + pRet = aArr[ nPos ]; + else + { + // then we must search the current (or the next) in the orig + do { + pRet = aArr[ nPos ]; + if( USHRT_MAX != rOrigArr.GetPos( pRet )) + break; + pRet = 0; + ++nPos; + } while( nPos < aArr.Count() ); + + if( nPos >= aArr.Count() ) + pRet = 0; + } + } + return pRet; +} + +struct SvLinkSource_Impl +{ + SvLinkSource_Array_Impl aArr; + String aDataMimeType; + SvLinkSourceTimer * pTimer; + ULONG nTimeout; + com::sun::star::uno::Reference<com::sun::star::io::XInputStream> + m_xInputStreamToLoadFrom; + sal_Bool m_bIsReadOnly; + + SvLinkSource_Impl() : pTimer( 0 ), nTimeout( 3000 ) {} + ~SvLinkSource_Impl(); + + void Closed(); +}; + +SvLinkSource_Impl::~SvLinkSource_Impl() +{ + delete pTimer; +} + +SvLinkSource::SvLinkSource() + : pImpl( new SvLinkSource_Impl ) +{ +} + +SvLinkSource::~SvLinkSource() +{ + delete pImpl; +} + + +SvLinkSource::StreamToLoadFrom SvLinkSource::getStreamToLoadFrom() +{ + return StreamToLoadFrom( + pImpl->m_xInputStreamToLoadFrom, + pImpl->m_bIsReadOnly); +} + +void SvLinkSource::setStreamToLoadFrom(const com::sun::star::uno::Reference<com::sun::star::io::XInputStream>& xInputStream,sal_Bool bIsReadOnly ) +{ + pImpl->m_xInputStreamToLoadFrom = xInputStream; + pImpl->m_bIsReadOnly = bIsReadOnly; +} + +// --> OD 2008-06-18 #i88291# +void SvLinkSource::clearStreamToLoadFrom() +{ + pImpl->m_xInputStreamToLoadFrom.clear(); +} +// <-- + +void SvLinkSource::Closed() +{ + SvLinkSource_EntryIter_Impl aIter( pImpl->aArr ); + for( SvLinkSource_Entry_Impl* p = aIter.Curr(); p; p = aIter.Next() ) + if( !p->bIsDataSink ) + p->xSink->Closed(); +} + +ULONG SvLinkSource::GetUpdateTimeout() const +{ + return pImpl->nTimeout; +} + +void SvLinkSource::SetUpdateTimeout( ULONG nTimeout ) +{ + pImpl->nTimeout = nTimeout; + if( pImpl->pTimer ) + pImpl->pTimer->SetTimeout( nTimeout ); +} + +void SvLinkSource::SendDataChanged() +{ + SvLinkSource_EntryIter_Impl aIter( pImpl->aArr ); + for( SvLinkSource_Entry_ImplPtr p = aIter.Curr(); p; p = aIter.Next() ) + { + if( p->bIsDataSink ) + { + String sDataMimeType( pImpl->aDataMimeType ); + if( !sDataMimeType.Len() ) + sDataMimeType = p->aDataMimeType; + + Any aVal; + if( ( p->nAdviseModes & ADVISEMODE_NODATA ) || + GetData( aVal, sDataMimeType, TRUE ) ) + { + p->xSink->DataChanged( sDataMimeType, aVal ); + + if ( !aIter.IsValidCurrValue( p ) ) + continue; + + if( p->nAdviseModes & ADVISEMODE_ONLYONCE ) + { + USHORT nFndPos = pImpl->aArr.GetPos( p ); + if( USHRT_MAX != nFndPos ) + pImpl->aArr.DeleteAndDestroy( nFndPos ); + } + + } + } + } + if( pImpl->pTimer ) + { + delete pImpl->pTimer; + pImpl->pTimer = NULL; + } + pImpl->aDataMimeType.Erase(); +} + +void SvLinkSource::NotifyDataChanged() +{ + if( pImpl->nTimeout ) + StartTimer( &pImpl->pTimer, this, pImpl->nTimeout ); // Timeout neu + else + { + SvLinkSource_EntryIter_Impl aIter( pImpl->aArr ); + for( SvLinkSource_Entry_ImplPtr p = aIter.Curr(); p; p = aIter.Next() ) + if( p->bIsDataSink ) + { + Any aVal; + if( ( p->nAdviseModes & ADVISEMODE_NODATA ) || + GetData( aVal, p->aDataMimeType, TRUE ) ) + { + p->xSink->DataChanged( p->aDataMimeType, aVal ); + + if ( !aIter.IsValidCurrValue( p ) ) + continue; + + if( p->nAdviseModes & ADVISEMODE_ONLYONCE ) + { + USHORT nFndPos = pImpl->aArr.GetPos( p ); + if( USHRT_MAX != nFndPos ) + pImpl->aArr.DeleteAndDestroy( nFndPos ); + } + } + } + + if( pImpl->pTimer ) + { + delete pImpl->pTimer; + pImpl->pTimer = NULL; + } + } +} + +// notify the sink, the mime type is not +// a selection criterion +void SvLinkSource::DataChanged( const String & rMimeType, + const ::com::sun::star::uno::Any & rVal ) +{ + if( pImpl->nTimeout && !rVal.hasValue() ) + { // nur wenn keine Daten mitgegeben wurden + // fire all data to the sink, independent of the requested format + pImpl->aDataMimeType = rMimeType; + StartTimer( &pImpl->pTimer, this, pImpl->nTimeout ); // Timeout neu + } + else + { + SvLinkSource_EntryIter_Impl aIter( pImpl->aArr ); + for( SvLinkSource_Entry_ImplPtr p = aIter.Curr(); p; p = aIter.Next() ) + { + if( p->bIsDataSink ) + { + p->xSink->DataChanged( rMimeType, rVal ); + + if ( !aIter.IsValidCurrValue( p ) ) + continue; + + if( p->nAdviseModes & ADVISEMODE_ONLYONCE ) + { + USHORT nFndPos = pImpl->aArr.GetPos( p ); + if( USHRT_MAX != nFndPos ) + pImpl->aArr.DeleteAndDestroy( nFndPos ); + } + } + } + + if( pImpl->pTimer ) + { + delete pImpl->pTimer; + pImpl->pTimer = NULL; + } + } +} + + +// only one link is correct +void SvLinkSource::AddDataAdvise( SvBaseLink * pLink, const String& rMimeType, + USHORT nAdviseModes ) +{ + SvLinkSource_Entry_ImplPtr pNew = new SvLinkSource_Entry_Impl( + pLink, rMimeType, nAdviseModes ); + pImpl->aArr.Insert( pNew, pImpl->aArr.Count() ); +} + +void SvLinkSource::RemoveAllDataAdvise( SvBaseLink * pLink ) +{ + SvLinkSource_EntryIter_Impl aIter( pImpl->aArr ); + for( SvLinkSource_Entry_ImplPtr p = aIter.Curr(); p; p = aIter.Next() ) + if( p->bIsDataSink && &p->xSink == pLink ) + { + USHORT nFndPos = pImpl->aArr.GetPos( p ); + if( USHRT_MAX != nFndPos ) + pImpl->aArr.DeleteAndDestroy( nFndPos ); + } +} + +// only one link is correct +void SvLinkSource::AddConnectAdvise( SvBaseLink * pLink ) +{ + SvLinkSource_Entry_ImplPtr pNew = new SvLinkSource_Entry_Impl( pLink ); + pImpl->aArr.Insert( pNew, pImpl->aArr.Count() ); +} + +void SvLinkSource::RemoveConnectAdvise( SvBaseLink * pLink ) +{ + SvLinkSource_EntryIter_Impl aIter( pImpl->aArr ); + for( SvLinkSource_Entry_ImplPtr p = aIter.Curr(); p; p = aIter.Next() ) + if( !p->bIsDataSink && &p->xSink == pLink ) + { + USHORT nFndPos = pImpl->aArr.GetPos( p ); + if( USHRT_MAX != nFndPos ) + pImpl->aArr.DeleteAndDestroy( nFndPos ); + } +} + +BOOL SvLinkSource::HasDataLinks( const SvBaseLink* pLink ) const +{ + BOOL bRet = FALSE; + const SvLinkSource_Entry_Impl* p; + for( USHORT n = 0, nEnd = pImpl->aArr.Count(); n < nEnd; ++n ) + if( ( p = pImpl->aArr[ n ] )->bIsDataSink && + ( !pLink || &p->xSink == pLink ) ) + { + bRet = TRUE; + break; + } + return bRet; +} + +// TRUE => waitinmg for data +BOOL SvLinkSource::IsPending() const +{ + return FALSE; +} + +// TRUE => data complete loaded +BOOL SvLinkSource::IsDataComplete() const +{ + return TRUE; +} + +BOOL SvLinkSource::Connect( SvBaseLink* ) +{ + return TRUE; +} + +BOOL SvLinkSource::GetData( ::com::sun::star::uno::Any &, const String &, BOOL ) +{ + return FALSE; +} + +void SvLinkSource::Edit( Window *, SvBaseLink *, const Link& ) +{ +} + +} + diff --git a/sfx2/source/appl/lnkbase2.cxx b/sfx2/source/appl/lnkbase2.cxx new file mode 100644 index 000000000000..314832e2249d --- /dev/null +++ b/sfx2/source/appl/lnkbase2.cxx @@ -0,0 +1,699 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" + + +#include <sfx2/lnkbase.hxx> +#include <sot/exchange.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <vcl/msgbox.hxx> +#include <sfx2/linkmgr.hxx> +#include <vcl/svapp.hxx> +#include "app.hrc" +#include "sfxresid.hxx" +#include <sfx2/filedlghelper.hxx> +#include <tools/debug.hxx> +#include <svl/svdde.hxx> + +using namespace ::com::sun::star::uno; + +namespace sfx2 +{ + +TYPEINIT0( SvBaseLink ) + +static DdeTopic* FindTopic( const String &, USHORT* = 0 ); + +class ImplDdeItem; + +struct BaseLink_Impl +{ + Link m_aEndEditLink; + LinkManager* m_pLinkMgr; + Window* m_pParentWin; + FileDialogHelper* m_pFileDlg; + bool m_bIsConnect; + + BaseLink_Impl() : + m_pLinkMgr( NULL ) + , m_pParentWin( NULL ) + , m_pFileDlg( NULL ) + , m_bIsConnect( false ) + {} + + ~BaseLink_Impl() + { delete m_pFileDlg; } +}; + +// nur fuer die interne Verwaltung +struct ImplBaseLinkData +{ + struct tClientType + { + // gilt fuer alle Links + ULONG nCntntType; // Update Format + // nicht Ole-Links + BOOL bIntrnlLnk; // ist es ein interner Link + USHORT nUpdateMode;// UpdateMode + }; + + struct tDDEType + { + ImplDdeItem* pItem; + }; + + union { + tClientType ClientType; + tDDEType DDEType; + }; + ImplBaseLinkData() + { + ClientType.nCntntType = 0; + ClientType.bIntrnlLnk = FALSE; + ClientType.nUpdateMode = 0; + DDEType.pItem = NULL; + } +}; + + +class ImplDdeItem : public DdeGetPutItem +{ + SvBaseLink* pLink; + DdeData aData; + Sequence< sal_Int8 > aSeq; // Datacontainer for DdeData !!! + BOOL bIsValidData : 1; + BOOL bIsInDTOR : 1; +public: + ImplDdeItem( SvBaseLink& rLink, const String& rStr ) + : DdeGetPutItem( rStr ), pLink( &rLink ), bIsValidData( FALSE ), + bIsInDTOR( FALSE ) + {} + virtual ~ImplDdeItem(); + + virtual DdeData* Get( ULONG ); + virtual BOOL Put( const DdeData* ); + virtual void AdviseLoop( BOOL ); + + void Notify() + { + bIsValidData = FALSE; + DdeGetPutItem::NotifyClient(); + } + + BOOL IsInDTOR() const { return bIsInDTOR; } +}; + + +/************************************************************************ +|* SvBaseLink::SvBaseLink() +|* +|* Beschreibung +*************************************************************************/ + +SvBaseLink::SvBaseLink() +{ + pImpl = new BaseLink_Impl(); + nObjType = OBJECT_CLIENT_SO; + pImplData = new ImplBaseLinkData; + bVisible = bSynchron = bUseCache = TRUE; + bWasLastEditOK = FALSE; +} + +/************************************************************************ +|* SvBaseLink::SvBaseLink() +|* +|* Beschreibung +*************************************************************************/ + +SvBaseLink::SvBaseLink( USHORT nUpdateMode, ULONG nContentType ) +{ + pImpl = new BaseLink_Impl(); + nObjType = OBJECT_CLIENT_SO; + pImplData = new ImplBaseLinkData; + bVisible = bSynchron = bUseCache = TRUE; + bWasLastEditOK = FALSE; + + // falls es ein Ole-Link wird, + pImplData->ClientType.nUpdateMode = nUpdateMode; + pImplData->ClientType.nCntntType = nContentType; + pImplData->ClientType.bIntrnlLnk = FALSE; +} + +/************************************************************************ +|* SvBaseLink::SvBaseLink() +|* +|* Beschreibung +*************************************************************************/ + +SvBaseLink::SvBaseLink( const String& rLinkName, USHORT nObjectType, SvLinkSource* pObj ) +{ + bVisible = bSynchron = bUseCache = TRUE; + bWasLastEditOK = FALSE; + aLinkName = rLinkName; + pImplData = new ImplBaseLinkData; + nObjType = nObjectType; + + if( !pObj ) + { + DBG_ASSERT( pObj, "Wo ist mein zu linkendes Object" ); + return; + } + + if( OBJECT_DDE_EXTERN == nObjType ) + { + USHORT nItemStt = 0; + DdeTopic* pTopic = FindTopic( aLinkName, &nItemStt ); + if( pTopic ) + { + // dann haben wir alles zusammen + // MM hat gefummelt ??? + // MM_TODO wie kriege ich den Namen + String aStr = aLinkName; // xLinkName->GetDisplayName(); + aStr = aStr.Copy( nItemStt ); + pImplData->DDEType.pItem = new ImplDdeItem( *this, aStr ); + pTopic->InsertItem( pImplData->DDEType.pItem ); + + // dann koennen wir uns auch das Advise merken + xObj = pObj; + } + } + else if( pObj->Connect( this ) ) + xObj = pObj; +} + +/************************************************************************ +|* SvBaseLink::~SvBaseLink() +|* +|* Beschreibung +*************************************************************************/ + +SvBaseLink::~SvBaseLink() +{ + Disconnect(); + + switch( nObjType ) + { + case OBJECT_DDE_EXTERN: + if( !pImplData->DDEType.pItem->IsInDTOR() ) + delete pImplData->DDEType.pItem; + break; + } + + delete pImplData; +} + +IMPL_LINK( SvBaseLink, EndEditHdl, String*, _pNewName ) +{ + String sNewName; + if ( _pNewName ) + sNewName = *_pNewName; + if ( !ExecuteEdit( sNewName ) ) + sNewName.Erase(); + bWasLastEditOK = ( sNewName.Len() > 0 ); + if ( pImpl->m_aEndEditLink.IsSet() ) + pImpl->m_aEndEditLink.Call( this ); + return 0; +} + +/************************************************************************ +|* SvBaseLink::SetObjType() +|* +|* Beschreibung +*************************************************************************/ + +void SvBaseLink::SetObjType( USHORT nObjTypeP ) +{ + DBG_ASSERT( nObjType != OBJECT_CLIENT_DDE, "type already set" ); + DBG_ASSERT( !xObj.Is(), "object exist" ); + + nObjType = nObjTypeP; +} + +/************************************************************************ +|* SvBaseLink::SetName() +|* +|* Beschreibung +*************************************************************************/ + +void SvBaseLink::SetName( const String & rNm ) +{ + aLinkName = rNm; +} + +/************************************************************************ +|* SvBaseLink::GetName() +|* +|* Beschreibung +*************************************************************************/ + +String SvBaseLink::GetName() const +{ + return aLinkName; +} + +/************************************************************************ +|* SvBaseLink::SetObj() +|* +|* Beschreibung +*************************************************************************/ + +void SvBaseLink::SetObj( SvLinkSource * pObj ) +{ + DBG_ASSERT( (nObjType & OBJECT_CLIENT_SO && + pImplData->ClientType.bIntrnlLnk) || + nObjType == OBJECT_CLIENT_GRF, + "no intern link" ); + xObj = pObj; +} + +/************************************************************************ +|* SvBaseLink::SetLinkSourceName() +|* +|* Beschreibung +*************************************************************************/ + +void SvBaseLink::SetLinkSourceName( const String & rLnkNm ) +{ + if( aLinkName == rLnkNm ) + return; + + AddNextRef(); // sollte ueberfluessig sein + // Alte Verbindung weg + Disconnect(); + + aLinkName = rLnkNm; + + // Neu verbinden + _GetRealObject(); + ReleaseRef(); // sollte ueberfluessig sein +} + +/************************************************************************ +|* SvBaseLink::GetLinkSourceName() +|* +|* Beschreibung +*************************************************************************/ + +String SvBaseLink::GetLinkSourceName() const +{ + return aLinkName; +} + + +/************************************************************************ +|* SvBaseLink::SetUpdateMode() +|* +|* Beschreibung +*************************************************************************/ + +void SvBaseLink::SetUpdateMode( USHORT nMode ) +{ + if( ( OBJECT_CLIENT_SO & nObjType ) && + pImplData->ClientType.nUpdateMode != nMode ) + { + AddNextRef(); + Disconnect(); + + pImplData->ClientType.nUpdateMode = nMode; + _GetRealObject(); + ReleaseRef(); + } +} + +// --> OD 2008-06-19 #i88291# +void SvBaseLink::clearStreamToLoadFrom() +{ + m_xInputStreamToLoadFrom.clear(); + if( xObj.Is() ) + { + xObj->clearStreamToLoadFrom(); + } +} +// <-- + +BOOL SvBaseLink::Update() +{ + if( OBJECT_CLIENT_SO & nObjType ) + { + AddNextRef(); + Disconnect(); + + _GetRealObject(); + ReleaseRef(); + if( xObj.Is() ) + { + xObj->setStreamToLoadFrom(m_xInputStreamToLoadFrom,m_bIsReadOnly); + // m_xInputStreamToLoadFrom = 0; + String sMimeType( SotExchange::GetFormatMimeType( + pImplData->ClientType.nCntntType )); + Any aData; + + if( xObj->GetData( aData, sMimeType ) ) + { + DataChanged( sMimeType, aData ); + //JP 13.07.00: Bug 76817 - for manual Updates there is no + // need to hold the ServerObject + if( OBJECT_CLIENT_DDE == nObjType && + LINKUPDATE_ONCALL == GetUpdateMode() && xObj.Is() ) + xObj->RemoveAllDataAdvise( this ); + return TRUE; + } + if( xObj.Is() ) + { + // sollten wir asynschron sein? + if( xObj->IsPending() ) + return TRUE; + + // dann brauchen wir das Object auch nicht mehr + AddNextRef(); + Disconnect(); + ReleaseRef(); + } + } + } + return FALSE; +} + + +USHORT SvBaseLink::GetUpdateMode() const +{ + return ( OBJECT_CLIENT_SO & nObjType ) + ? pImplData->ClientType.nUpdateMode + : sal::static_int_cast< USHORT >( LINKUPDATE_ONCALL ); +} + + +void SvBaseLink::_GetRealObject( BOOL bConnect) +{ + if( !pImpl->m_pLinkMgr ) + return; + + DBG_ASSERT( !xObj.Is(), "object already exist" ); + + if( OBJECT_CLIENT_DDE == nObjType ) + { + String sServer; + if( pImpl->m_pLinkMgr->GetDisplayNames( this, &sServer ) && + sServer == GetpApp()->GetAppName() ) // interner Link !!! + { + // damit der Internal - Link erzeugt werden kann !!! + nObjType = OBJECT_INTERN; + xObj = pImpl->m_pLinkMgr->CreateObj( this ); + + pImplData->ClientType.bIntrnlLnk = TRUE; + nObjType = OBJECT_CLIENT_DDE; // damit wir wissen was es mal war !! + } + else + { + pImplData->ClientType.bIntrnlLnk = FALSE; + xObj = pImpl->m_pLinkMgr->CreateObj( this ); + } + } + else if( (OBJECT_CLIENT_SO & nObjType) ) + xObj = pImpl->m_pLinkMgr->CreateObj( this ); + + if( bConnect && ( !xObj.Is() || !xObj->Connect( this ) ) ) + Disconnect(); +} + +ULONG SvBaseLink::GetContentType() const +{ + if( OBJECT_CLIENT_SO & nObjType ) + return pImplData->ClientType.nCntntType; + + return 0; // alle Formate ? +} + + +BOOL SvBaseLink::SetContentType( ULONG nType ) +{ + if( OBJECT_CLIENT_SO & nObjType ) + { + pImplData->ClientType.nCntntType = nType; + return TRUE; + } + return FALSE; +} + +LinkManager* SvBaseLink::GetLinkManager() +{ + return pImpl->m_pLinkMgr; +} + +const LinkManager* SvBaseLink::GetLinkManager() const +{ + return pImpl->m_pLinkMgr; +} + +void SvBaseLink::SetLinkManager( LinkManager* _pMgr ) +{ + pImpl->m_pLinkMgr = _pMgr; +} + +void SvBaseLink::Disconnect() +{ + if( xObj.Is() ) + { + xObj->RemoveAllDataAdvise( this ); + xObj->RemoveConnectAdvise( this ); + xObj.Clear(); + } +} + +void SvBaseLink::DataChanged( const String &, const ::com::sun::star::uno::Any & ) +{ + switch( nObjType ) + { + case OBJECT_DDE_EXTERN: + if( pImplData->DDEType.pItem ) + pImplData->DDEType.pItem->Notify(); + break; + } +} + +void SvBaseLink::Edit( Window* pParent, const Link& rEndEditHdl ) +{ + pImpl->m_pParentWin = pParent; + pImpl->m_aEndEditLink = rEndEditHdl; + pImpl->m_bIsConnect = ( xObj.Is() != sal_False ); + if( !pImpl->m_bIsConnect ) + _GetRealObject( xObj.Is() ); + + bool bAsync = false; + Link aLink = LINK( this, SvBaseLink, EndEditHdl ); + + if( OBJECT_CLIENT_SO & nObjType && pImplData->ClientType.bIntrnlLnk ) + { + if( pImpl->m_pLinkMgr ) + { + SvLinkSourceRef ref = pImpl->m_pLinkMgr->CreateObj( this ); + if( ref.Is() ) + { + ref->Edit( pParent, this, aLink ); + bAsync = true; + } + } + } + else + { + xObj->Edit( pParent, this, aLink ); + bAsync = true; + } + + if ( !bAsync ) + { + ExecuteEdit( String() ); + bWasLastEditOK = FALSE; + if ( pImpl->m_aEndEditLink.IsSet() ) + pImpl->m_aEndEditLink.Call( this ); + } +} + +bool SvBaseLink::ExecuteEdit( const String& _rNewName ) +{ + if( _rNewName.Len() != 0 ) + { + SetLinkSourceName( _rNewName ); + if( !Update() ) + { + String sApp, sTopic, sItem, sError; + pImpl->m_pLinkMgr->GetDisplayNames( this, &sApp, &sTopic, &sItem ); + if( nObjType == OBJECT_CLIENT_DDE ) + { + sError = SfxResId( STR_DDE_ERROR ); + + USHORT nFndPos = sError.Search( '%' ); + if( STRING_NOTFOUND != nFndPos ) + { + sError.Erase( nFndPos, 1 ).Insert( sApp, nFndPos ); + nFndPos = nFndPos + sApp.Len(); + } + if( STRING_NOTFOUND != ( nFndPos = sError.Search( '%', nFndPos ))) + { + sError.Erase( nFndPos, 1 ).Insert( sTopic, nFndPos ); + nFndPos = nFndPos + sTopic.Len(); + } + if( STRING_NOTFOUND != ( nFndPos = sError.Search( '%', nFndPos ))) + sError.Erase( nFndPos, 1 ).Insert( sItem, nFndPos ); + } + else + return false; + + ErrorBox( pImpl->m_pParentWin, WB_OK, sError ).Execute(); + } + } + else if( !pImpl->m_bIsConnect ) + Disconnect(); + pImpl->m_bIsConnect = false; + return true; +} + +void SvBaseLink::Closed() +{ + if( xObj.Is() ) + // beim Advise Abmelden + xObj->RemoveAllDataAdvise( this ); +} + +FileDialogHelper* SvBaseLink::GetFileDialog( sal_uInt32 nFlags, const String& rFactory ) const +{ + if ( pImpl->m_pFileDlg ) + delete pImpl->m_pFileDlg; + pImpl->m_pFileDlg = new FileDialogHelper( nFlags, rFactory ); + return pImpl->m_pFileDlg; +} + +ImplDdeItem::~ImplDdeItem() +{ + bIsInDTOR = TRUE; + // damit im Disconnect nicht jemand auf die Idee kommt, den Pointer zu + // loeschen!! + SvBaseLinkRef aRef( pLink ); + aRef->Disconnect(); +} + +DdeData* ImplDdeItem::Get( ULONG nFormat ) +{ + if( pLink->GetObj() ) + { + // ist das noch gueltig? + if( bIsValidData && nFormat == aData.GetFormat() ) + return &aData; + + Any aValue; + String sMimeType( SotExchange::GetFormatMimeType( nFormat )); + if( pLink->GetObj()->GetData( aValue, sMimeType ) ) + { + if( aValue >>= aSeq ) + { + aData = DdeData( (const char *)aSeq.getConstArray(), aSeq.getLength(), nFormat ); + + bIsValidData = TRUE; + return &aData; + } + } + } + aSeq.realloc( 0 ); + bIsValidData = FALSE; + return 0; +} + + +BOOL ImplDdeItem::Put( const DdeData* ) +{ + DBG_ERROR( "ImplDdeItem::Put not implemented" ); + return FALSE; +} + + +void ImplDdeItem::AdviseLoop( BOOL bOpen ) +{ + // Verbindung wird geschlossen, also Link abmelden + if( pLink->GetObj() ) + { + if( bOpen ) + { + // es wird wieder eine Verbindung hergestellt + if( OBJECT_DDE_EXTERN == pLink->GetObjType() ) + { + pLink->GetObj()->AddDataAdvise( pLink, String::CreateFromAscii( "text/plain;charset=utf-16" ), ADVISEMODE_NODATA ); + pLink->GetObj()->AddConnectAdvise( pLink ); + } + } + else + { + // damit im Disconnect nicht jemand auf die Idee kommt, + // den Pointer zu loeschen!! + SvBaseLinkRef aRef( pLink ); + aRef->Disconnect(); + } + } +} + + +static DdeTopic* FindTopic( const String & rLinkName, USHORT* pItemStt ) +{ + if( 0 == rLinkName.Len() ) + return 0; + + String sNm( rLinkName ); + USHORT nTokenPos = 0; + String sService( sNm.GetToken( 0, cTokenSeperator, nTokenPos ) ); + + DdeServices& rSvc = DdeService::GetServices(); + for( DdeService* pService = rSvc.First(); pService; + pService = rSvc.Next() ) + if( pService->GetName() == sService ) + { + // dann suchen wir uns das Topic + String sTopic( sNm.GetToken( 0, cTokenSeperator, nTokenPos ) ); + if( pItemStt ) + *pItemStt = nTokenPos; + + DdeTopics& rTopics = pService->GetTopics(); + + for( int i = 0; i < 2; ++i ) + { + for( DdeTopic* pTopic = rTopics.First(); pTopic; + pTopic = rTopics.Next() ) + if( pTopic->GetName() == sTopic ) + return pTopic; + + // Topic nicht gefunden ? + // dann versuchen wir ihn mal anzulegen + if( i || !pService->MakeTopic( sTopic ) ) + break; // hat nicht geklappt, also raus + } + break; + } + return 0; +} + +} diff --git a/sfx2/source/appl/makefile.mk b/sfx2/source/appl/makefile.mk new file mode 100644 index 000000000000..30f74355077a --- /dev/null +++ b/sfx2/source/appl/makefile.mk @@ -0,0 +1,158 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=sfx2 +TARGET=appl +ENABLE_EXCEPTIONS=TRUE +LIBTARGET=NO + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# w.g. compilerbugs +.IF "$(GUI)"=="WNT" +.IF "$(COM)"!="GCC" +CFLAGS+=-Od +CFLAGS+=-DENABLE_QUICKSTART_APPLET +.ENDIF +.ENDIF + +.IF "$(GUIBASE)"=="aqua" +CFLAGS+=-DENABLE_QUICKSTART_APPLET +.ENDIF + +.IF "$(GUI)"=="UNX" + CDEFS+=-DDLL_NAME=libsfx$(DLLPOSTFIX)$(DLLPOST) +.IF "$(ENABLE_SYSTRAY_GTK)"=="TRUE" + PKGCONFIG_MODULES=gtk+-2.0 + .INCLUDE: pkg_config.mk + CFLAGS+=$(PKGCONFIG_CFLAGS) + CFLAGS+=-DENABLE_QUICKSTART_APPLET + CDEFS+=-DPLUGIN_NAME=libqstart_gtk$(DLLPOSTFIX)$(DLLPOST) +.ENDIF # "$(ENABLE_SYSTRAY_GTK)"=="TRUE" +.ELSE + CDEFS+=-DDLL_NAME=sfx$(DLLPOSTFIX)$(DLLPOST) +.ENDIF + +# --- Files -------------------------------------------------------- + +SRS1NAME=appl +SRC1FILES = \ + app.src newhelp.src dde.src + +SRS2NAME=sfx +SRC2FILES = \ + sfx.src + +SFX_OBJECTS = \ + $(SLO)$/app.obj \ + $(SLO)$/appbas.obj \ + $(SLO)$/appcfg.obj \ + $(SLO)$/appchild.obj \ + $(SLO)$/appdata.obj \ + $(SLO)$/appdde.obj \ + $(SLO)$/appinit.obj \ + $(SLO)$/appmain.obj \ + $(SLO)$/appmisc.obj \ + $(SLO)$/appopen.obj \ + $(SLO)$/appquit.obj \ + $(SLO)$/appreg.obj \ + $(SLO)$/appserv.obj \ + $(SLO)$/appuno.obj \ + $(SLO)$/appbaslib.obj \ + $(SLO)$/childwin.obj \ + $(SLO)$/fileobj.obj \ + $(SLO)$/helpdispatch.obj \ + $(SLO)$/helpinterceptor.obj \ + $(SLO)$/imagemgr.obj\ + $(SLO)$/imestatuswindow.obj \ + $(SLO)$/impldde.obj \ + $(SLO)$/linkmgr2.obj \ + $(SLO)$/linksrc.obj \ + $(SLO)$/lnkbase2.obj \ + $(SLO)$/module.obj \ + $(SLO)$/newhelp.obj \ + $(SLO)$/opengrf.obj \ + $(SLO)$/sfxhelp.obj \ + $(SLO)$/sfxpicklist.obj \ + $(SLO)$/shutdownicon.obj \ + $(SLO)$/shutdowniconw32.obj \ + $(SLO)$/workwin.obj \ + $(SLO)$/xpackcreator.obj \ + $(SLO)$/fwkhelper.obj + +.IF "$(GUI)"=="OS2" +SFX_OBJECTS += $(SLO)$/shutdowniconOs2.obj +.ENDIF + +.IF "$(GUIBASE)"=="aqua" +SFX_OBJECTS += $(SLO)$/shutdowniconaqua.obj +.ENDIF + +SLOFILES = $(SFX_OBJECTS) +LIB1TARGET= $(SLB)$/$(TARGET).lib +LIB1OBJFILES= $(SFX_OBJECTS) + +.IF "$(ENABLE_SYSTRAY_GTK)"=="TRUE" +QUICKSTART_OBJECTS = $(SLO)$/shutdowniconunx.obj +SLOFILES += $(QUICKSTART_OBJECTS) + +LIB2TARGET= $(SLB)$/quickstart.lib +LIB2OBJFILES= $(QUICKSTART_OBJECTS) +.ENDIF + +.IF "$(GUI)"=="OS2" +SLOFILES += $(SLO)$/shutdowniconOs2.obj +.ENDIF + +EXCEPTIONSFILES=\ + $(SLO)$/imagemgr.obj \ + $(SLO)$/appopen.obj \ + $(SLO)$/appmain.obj \ + $(SLO)$/appmisc.obj \ + $(SLO)$/appinit.obj \ + $(SLO)$/appcfg.obj \ + $(SLO)$/fileobj.obj \ + $(SLO)$/helpinterceptor.obj \ + $(SLO)$/newhelp.obj \ + $(SLO)$/opengrf.obj \ + $(SLO)$/sfxhelp.obj \ + $(SLO)$/shutdownicon.obj \ + $(SLO)$/shutdowniconw32.obj \ + $(SLO)$/sfxpicklist.obj \ + $(SLO)$/helpdispatch.obj \ + $(SLO)$/xpackcreator.obj + + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/sfx2/source/appl/module.cxx b/sfx2/source/appl/module.cxx new file mode 100644 index 000000000000..895263ef4783 --- /dev/null +++ b/sfx2/source/appl/module.cxx @@ -0,0 +1,450 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" + +#ifndef GCC +#endif + +#include <stdio.h> +#include <tools/rcid.h> + +#include <cstdarg> +#include <sfx2/module.hxx> +#include <sfx2/app.hxx> +#include "arrdecl.hxx" +#include "sfxresid.hxx" +#include <sfx2/msgpool.hxx> +#include <sfx2/tbxctrl.hxx> +#include "stbitem.hxx" +#include <sfx2/mnuitem.hxx> +#include <sfx2/childwin.hxx> +#include <sfx2/mnumgr.hxx> +#include <sfx2/docfac.hxx> +#include <sfx2/objface.hxx> +#include <sfx2/viewfrm.hxx> +#include <svl/intitem.hxx> +#include "sfx2/taskpane.hxx" +#include <tools/diagnose_ex.h> + +#define SfxModule +#include "sfxslots.hxx" + +static SfxModuleArr_Impl* pModules=0; + +class SfxModule_Impl +{ +public: + + SfxSlotPool* pSlotPool; + SfxTbxCtrlFactArr_Impl* pTbxCtrlFac; + SfxStbCtrlFactArr_Impl* pStbCtrlFac; + SfxMenuCtrlFactArr_Impl* pMenuCtrlFac; + SfxChildWinFactArr_Impl* pFactArr; + ImageList* pImgListSmall; + ImageList* pImgListBig; + ImageList* pImgListHiSmall; + ImageList* pImgListHiBig; + + SfxModule_Impl(); + ~SfxModule_Impl(); + ImageList* GetImageList( ResMgr*, BOOL, BOOL bHiContrast = FALSE ); +}; + +SfxModule_Impl::SfxModule_Impl() + : pSlotPool(0) +{ +} + +SfxModule_Impl::~SfxModule_Impl() +{ + delete pSlotPool; + delete pTbxCtrlFac; + delete pStbCtrlFac; + delete pMenuCtrlFac; + delete pFactArr; + delete pImgListSmall; + delete pImgListBig; + delete pImgListHiSmall; + delete pImgListHiBig; +} + +ImageList* SfxModule_Impl::GetImageList( ResMgr* pResMgr, BOOL bBig, BOOL bHiContrast ) +{ + ImageList*& rpList = bBig ? ( bHiContrast ? pImgListHiBig: pImgListBig ) : + ( bHiContrast ? pImgListHiSmall : pImgListSmall ); + if ( !rpList ) + { + ResId aResId( bBig ? ( bHiContrast ? RID_DEFAULTIMAGELIST_LCH : RID_DEFAULTIMAGELIST_LC ) : + ( bHiContrast ? RID_DEFAULTIMAGELIST_SCH : RID_DEFAULTIMAGELIST_SC ), *pResMgr ); + aResId.SetRT( RSC_IMAGELIST ); + + DBG_ASSERT( pResMgr->IsAvailable(aResId), "No default ImageList!" ); + + if ( pResMgr->IsAvailable(aResId) ) + rpList = new ImageList( aResId ); + else + rpList = new ImageList(); + } + + return rpList; } + +TYPEINIT1(SfxModule, SfxShell); + +//========================================================================= + +SFX_IMPL_INTERFACE(SfxModule,SfxShell,SfxResId(0)) +{ +} + +//==================================================================== + +ResMgr* SfxModule::GetResMgr() +{ + return pResMgr; +} + +//==================================================================== +/* +SfxModule::SfxModule( ResMgr* pMgrP, BOOL bDummyP, + SfxObjectFactory* pFactoryP ) + : pResMgr( pMgrP ), bDummy( bDummyP ), pImpl(0L) +{ + Construct_Impl(); + if ( pFactoryP ) + pFactoryP->SetModule_Impl( this ); +} +*/ +SfxModule::SfxModule( ResMgr* pMgrP, BOOL bDummyP, + SfxObjectFactory* pFactoryP, ... ) + : pResMgr( pMgrP ), bDummy( bDummyP ), pImpl(0L) +{ + Construct_Impl(); + va_list pVarArgs; + va_start( pVarArgs, pFactoryP ); + for ( SfxObjectFactory *pArg = pFactoryP; pArg; + pArg = va_arg( pVarArgs, SfxObjectFactory* ) ) + pArg->SetModule_Impl( this ); + va_end(pVarArgs); +} + +void SfxModule::Construct_Impl() +{ + if( !bDummy ) + { + SfxApplication *pApp = SFX_APP(); + SfxModuleArr_Impl& rArr = GetModules_Impl(); + SfxModule* pPtr = (SfxModule*)this; + rArr.C40_INSERT( SfxModule, pPtr, rArr.Count() ); + pImpl = new SfxModule_Impl; + pImpl->pSlotPool = new SfxSlotPool( &pApp->GetAppSlotPool_Impl(), pResMgr ); + + pImpl->pTbxCtrlFac=0; + pImpl->pStbCtrlFac=0; + pImpl->pMenuCtrlFac=0; + pImpl->pFactArr=0; + pImpl->pImgListSmall=0; + pImpl->pImgListBig=0; + pImpl->pImgListHiSmall=0; + pImpl->pImgListHiBig=0; + + SetPool( &pApp->GetPool() ); + } +} + +//==================================================================== + +SfxModule::~SfxModule() +{ + if( !bDummy ) + { + if ( SFX_APP()->Get_Impl() ) + { + // Das Modul wird noch vor dem DeInitialize zerst"ort, also auis dem Array entfernen + SfxModuleArr_Impl& rArr = GetModules_Impl(); + for( USHORT nPos = rArr.Count(); nPos--; ) + { + if( rArr[ nPos ] == this ) + { + rArr.Remove( nPos ); + break; + } + } + + delete pImpl; + } + + delete pResMgr; + } +} + +//------------------------------------------------------------------------- + +SfxSlotPool* SfxModule::GetSlotPool() const +{ + return pImpl->pSlotPool; +} + +//------------------------------------------------------------------------- + +void SfxModule::RegisterChildWindow(SfxChildWinFactory *pFact) +{ + DBG_ASSERT( pImpl, "Kein echtes Modul!" ); + + if (!pImpl->pFactArr) + pImpl->pFactArr = new SfxChildWinFactArr_Impl; + +//#ifdef DBG_UTIL + for (USHORT nFactory=0; nFactory<pImpl->pFactArr->Count(); ++nFactory) + { + if (pFact->nId == (*pImpl->pFactArr)[nFactory]->nId) + { + pImpl->pFactArr->Remove( nFactory ); + DBG_ERROR("ChildWindow mehrfach registriert!"); + return; + } + } +//#endif + + pImpl->pFactArr->C40_INSERT( + SfxChildWinFactory, pFact, pImpl->pFactArr->Count() ); +} + +//------------------------------------------------------------------------- + +void SfxModule::RegisterChildWindowContext( USHORT nId, + SfxChildWinContextFactory *pFact) +{ + DBG_ASSERT( pImpl, "Kein echtes Modul!" ); + + USHORT nCount = pImpl->pFactArr->Count(); + for (USHORT nFactory=0; nFactory<nCount; ++nFactory) + { + SfxChildWinFactory *pF = (*pImpl->pFactArr)[nFactory]; + if ( nId == pF->nId ) + { + if ( !pF->pArr ) + pF->pArr = new SfxChildWinContextArr_Impl; + pF->pArr->C40_INSERT( SfxChildWinContextFactory, pFact, pF->pArr->Count() ); + return; + } + } + + DBG_ERROR( "Kein ChildWindow fuer diesen Context!" ); +} + +//------------------------------------------------------------------------- + +void SfxModule::RegisterToolBoxControl( SfxTbxCtrlFactory *pFact ) +{ + if (!pImpl->pTbxCtrlFac) + pImpl->pTbxCtrlFac = new SfxTbxCtrlFactArr_Impl; + +#ifdef DBG_UTIL + for ( USHORT n=0; n<pImpl->pTbxCtrlFac->Count(); n++ ) + { + SfxTbxCtrlFactory *pF = (*pImpl->pTbxCtrlFac)[n]; + if ( pF->nTypeId && pF->nTypeId == pFact->nTypeId && + (pF->nSlotId == pFact->nSlotId || pF->nSlotId == 0) ) + { + DBG_WARNING("TbxController-Registrierung ist nicht eindeutig!"); + } + } +#endif + + pImpl->pTbxCtrlFac->C40_INSERT( SfxTbxCtrlFactory, pFact, pImpl->pTbxCtrlFac->Count() ); +} + +//------------------------------------------------------------------------- + +void SfxModule::RegisterStatusBarControl( SfxStbCtrlFactory *pFact ) +{ + if (!pImpl->pStbCtrlFac) + pImpl->pStbCtrlFac = new SfxStbCtrlFactArr_Impl; + +#ifdef DBG_UTIL + for ( USHORT n=0; n<pImpl->pStbCtrlFac->Count(); n++ ) + { + SfxStbCtrlFactory *pF = (*pImpl->pStbCtrlFac)[n]; + if ( pF->nTypeId && pF->nTypeId == pFact->nTypeId && + (pF->nSlotId == pFact->nSlotId || pF->nSlotId == 0) ) + { + DBG_WARNING("StbController-Registrierung ist nicht eindeutig!"); + } + } +#endif + + pImpl->pStbCtrlFac->C40_INSERT( SfxStbCtrlFactory, pFact, pImpl->pStbCtrlFac->Count() ); +} + +//------------------------------------------------------------------------- + +void SfxModule::RegisterMenuControl( SfxMenuCtrlFactory *pFact ) +{ + if (!pImpl->pMenuCtrlFac) + pImpl->pMenuCtrlFac = new SfxMenuCtrlFactArr_Impl; + +#ifdef DBG_UTIL + for ( USHORT n=0; n<pImpl->pMenuCtrlFac->Count(); n++ ) + { + SfxMenuCtrlFactory *pF = (*pImpl->pMenuCtrlFac)[n]; + if ( pF->nTypeId && pF->nTypeId == pFact->nTypeId && + (pF->nSlotId == pFact->nSlotId || pF->nSlotId == 0) ) + { + DBG_WARNING("MenuController-Registrierung ist nicht eindeutig!"); + } + } +#endif + + pImpl->pMenuCtrlFac->C40_INSERT( SfxMenuCtrlFactory, pFact, pImpl->pMenuCtrlFac->Count() ); +} + +//------------------------------------------------------------------------- + +SfxTbxCtrlFactArr_Impl* SfxModule::GetTbxCtrlFactories_Impl() const +{ + return pImpl->pTbxCtrlFac; +} + +//------------------------------------------------------------------------- + +SfxStbCtrlFactArr_Impl* SfxModule::GetStbCtrlFactories_Impl() const +{ + return pImpl->pStbCtrlFac; +} + +//------------------------------------------------------------------------- + +SfxMenuCtrlFactArr_Impl* SfxModule::GetMenuCtrlFactories_Impl() const +{ + return pImpl->pMenuCtrlFac; +} + +//------------------------------------------------------------------------- + +SfxChildWinFactArr_Impl* SfxModule::GetChildWinFactories_Impl() const +{ + return pImpl->pFactArr; +} + +ImageList* SfxModule::GetImageList_Impl( BOOL bBig ) +{ + return pImpl->GetImageList( pResMgr, bBig, FALSE ); +} + +ImageList* SfxModule::GetImageList_Impl( BOOL bBig, BOOL bHiContrast ) +{ + return pImpl->GetImageList( pResMgr, bBig, bHiContrast ); +} + +SfxTabPage* SfxModule::CreateTabPage( USHORT, Window*, const SfxItemSet& ) +{ + return NULL; +} + +SfxModuleArr_Impl& SfxModule::GetModules_Impl() +{ + if( !pModules ) + pModules = new SfxModuleArr_Impl; + return *pModules; +}; + +void SfxModule::DestroyModules_Impl() +{ + if ( pModules ) + { + SfxModuleArr_Impl& rModules = *pModules; + for( USHORT nPos = rModules.Count(); nPos--; ) + { + SfxModule* pMod = rModules.GetObject(nPos); + delete pMod; + } + } +} + +void SfxModule::Invalidate( USHORT nId ) +{ + for( SfxViewFrame* pFrame = SfxViewFrame::GetFirst(); pFrame; pFrame = SfxViewFrame::GetNext( *pFrame ) ) + if ( pFrame->GetObjectShell()->GetModule() == this ) + Invalidate_Impl( pFrame->GetBindings(), nId ); +} + +BOOL SfxModule::IsActive() const +{ + SfxViewFrame* pFrame = SfxViewFrame::Current(); + if ( pFrame && pFrame->GetObjectShell()->GetFactory().GetModule() == this ) + return TRUE; + return FALSE; +} + +bool SfxModule::IsChildWindowAvailable( const USHORT i_nId, const SfxViewFrame* i_pViewFrame ) const +{ + if ( i_nId != SID_TASKPANE ) + // by default, assume it is + return true; + + const SfxViewFrame* pViewFrame = i_pViewFrame ? i_pViewFrame : GetFrame(); + ENSURE_OR_RETURN( pViewFrame, "SfxModule::IsChildWindowAvailable: no frame to ask for the module identifier!", false ); + return ::sfx2::ModuleTaskPane::ModuleHasToolPanels( pViewFrame->GetFrame().GetFrameInterface() ); +} + +SfxModule* SfxModule::GetActiveModule( SfxViewFrame* pFrame ) +{ + if ( !pFrame ) + pFrame = SfxViewFrame::Current(); + SfxObjectShell* pSh = 0; + if( pFrame ) + pSh = pFrame->GetObjectShell(); + return pSh ? pSh->GetModule() : 0; +} + +FieldUnit SfxModule::GetCurrentFieldUnit() +{ + FieldUnit eUnit = FUNIT_INCH; + SfxModule* pModule = GetActiveModule(); + if ( pModule ) + { + const SfxPoolItem* pItem = pModule->GetItem( SID_ATTR_METRIC ); + DBG_ASSERT( pItem, "GetFieldUnit(): no item" ); + if ( pItem ) + eUnit = (FieldUnit)( (SfxUInt16Item*)pItem )->GetValue(); + } + else + DBG_ERRORFILE( "GetModuleFieldUnit(): no module found" ); + return eUnit; +} + +FieldUnit SfxModule::GetFieldUnit() const +{ + FieldUnit eUnit = FUNIT_INCH; + const SfxPoolItem* pItem = GetItem( SID_ATTR_METRIC ); + DBG_ASSERT( pItem, "GetFieldUnit(): no item" ); + if ( pItem ) + eUnit = (FieldUnit)( (SfxUInt16Item*)pItem )->GetValue(); + return eUnit; +} diff --git a/sfx2/source/appl/newhelp.cxx b/sfx2/source/appl/newhelp.cxx new file mode 100644 index 000000000000..597509cf34bd --- /dev/null +++ b/sfx2/source/appl/newhelp.cxx @@ -0,0 +1,3492 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" + +#include "newhelp.hxx" +#include <sfx2/sfxuno.hxx> +#include "sfxresid.hxx" +#include "helpinterceptor.hxx" +#include "helper.hxx" +#include <sfx2/msgpool.hxx> +#include <sfx2/app.hxx> +#include "sfxtypes.hxx" +#include "panelist.hxx" +#include "imgmgr.hxx" +#include "srchdlg.hxx" +#include "sfxhelp.hxx" + +#include "app.hrc" +#include "newhelp.hrc" +#include "helpid.hrc" + +#include <hash_map> +#include <rtl/ustrbuf.hxx> +#include <comphelper/processfactory.hxx> +#include <comphelper/configurationhelper.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <com/sun/star/util/XModifiable.hpp> +#include <com/sun/star/frame/XComponentLoader.hpp> +#include <com/sun/star/util/XCloseable.hpp> +#include <com/sun/star/util/CloseVetoException.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/awt/PosSize.hpp> +#include <com/sun/star/awt/XWindow.hpp> +#include <com/sun/star/beans/Property.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/frame/XTitle.hpp> +#include <com/sun/star/frame/XLayoutManager.hpp> +#include <com/sun/star/frame/DispatchResultState.hpp> +#include <com/sun/star/frame/XController.hpp> +#include <com/sun/star/frame/XDispatch.hpp> +#include <com/sun/star/frame/XDispatchProvider.hpp> +#include <com/sun/star/frame/XDispatchProviderInterception.hpp> +#include <com/sun/star/frame/XFrame.hpp> +#ifndef _COM_SUN_STAR_TEXT_XBREAKITERATOR_HPP_ +#include <com/sun/star/i18n/XBreakIterator.hpp> +#endif +#include <com/sun/star/i18n/WordType.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/style/XStyle.hpp> +#include <com/sun/star/style/XStyleFamiliesSupplier.hpp> +#include <com/sun/star/text/XText.hpp> +#include <com/sun/star/text/XTextCursor.hpp> +#include <com/sun/star/text/XTextDocument.hpp> +#include <com/sun/star/text/XTextRange.hpp> +#include <com/sun/star/text/XTextViewCursor.hpp> +#include <com/sun/star/text/XTextViewCursorSupplier.hpp> +#include <com/sun/star/ucb/CommandAbortedException.hpp> +#include <com/sun/star/util/URL.hpp> +#include <com/sun/star/util/XSearchable.hpp> +#include <com/sun/star/util/XSearchDescriptor.hpp> +#include <com/sun/star/util/XURLTransformer.hpp> +#include <com/sun/star/view/XSelectionSupplier.hpp> +#include <com/sun/star/view/XViewSettingsSupplier.hpp> +#include <com/sun/star/ui/XDockingAreaAcceptor.hpp> +#include <svtools/helpopt.hxx> +#include <unotools/historyoptions.hxx> +#include <svtools/menuoptions.hxx> +#include <unotools/pathoptions.hxx> +#include <unotools/viewoptions.hxx> +#include <svtools/svtdata.hxx> +#include <tools/urlobj.hxx> +#include <tools/cachestr.hxx> +#include <unotools/streamhelper.hxx> +#include <svtools/imagemgr.hxx> +#include <svtools/miscopt.hxx> +#include <svtools/imgdef.hxx> +#include <vcl/unohelp.hxx> +#include <vcl/i18nhelp.hxx> + +#include <ucbhelper/content.hxx> +#include <vcl/msgbox.hxx> +#include <vcl/waitobj.hxx> +#include <unotools/ucbhelper.hxx> + +#include <sfx2/viewfrm.hxx> +#include <sfx2/objsh.hxx> +#include <sfx2/docfac.hxx> + +using namespace ::ucbhelper; +using namespace ::com::sun::star::ucb; + +using namespace ::com::sun::star; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::i18n; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::style; +using namespace ::com::sun::star::text; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::view; +using namespace ::com::sun::star::ui; + +using namespace ::comphelper; + +extern void AppendConfigToken_Impl( String& rURL, sal_Bool bQuestionMark ); // sfxhelp.cxx + +// defines --------------------------------------------------------------- + +#define SPLITSET_ID 0 +#define COLSET_ID 1 +#define INDEXWIN_ID 2 +#define TEXTWIN_ID 3 + +#define TOOLBOX_OFFSET 3 + +#define TBI_INDEX 1001 +#define TBI_BACKWARD 1002 +#define TBI_FORWARD 1003 +#define TBI_START 1004 +#define TBI_PRINT 1005 +#define TBI_COPY 1006 +#define TBI_BOOKMARKS 1007 +#define TBI_SEARCHDIALOG 1008 +#define TBI_SOURCEVIEW 1009 +#define TBI_SELECTIONMODE 1010 +#define TBI_ONSTARTUP 1011 + +#define CONFIGNAME_HELPWIN DEFINE_CONST_UNICODE("OfficeHelp") +#define CONFIGNAME_INDEXWIN DEFINE_CONST_UNICODE("OfficeHelpIndex") +#define CONFIGNAME_SEARCHPAGE DEFINE_CONST_UNICODE("OfficeHelpSearch") +#define IMAGE_URL DEFINE_CONST_UNICODE("private:factory/") + +#define PROPERTY_KEYWORDLIST DEFINE_CONST_OUSTRING("KeywordList") +#define PROPERTY_KEYWORDREF DEFINE_CONST_OUSTRING("KeywordRef") +#define PROPERTY_ANCHORREF DEFINE_CONST_OUSTRING("KeywordAnchorForRef") +#define PROPERTY_TITLEREF DEFINE_CONST_OUSTRING("KeywordTitleForRef") +#define PROPERTY_TITLE DEFINE_CONST_OUSTRING("Title") +#define HELP_URL DEFINE_CONST_OUSTRING("vnd.sun.star.help://") +#define HELP_SEARCH_TAG DEFINE_CONST_OUSTRING("/?Query=") +#define USERITEM_NAME DEFINE_CONST_OUSTRING("UserItem") + +#define PACKAGE_SETUP DEFINE_CONST_OUSTRING("/org.openoffice.Setup") +#define PATH_OFFICE_FACTORIES DEFINE_CONST_OUSTRING("Office/Factories/") +#define KEY_HELP_ON_OPEN DEFINE_CONST_OUSTRING("ooSetupFactoryHelpOnOpen") +#define KEY_UI_NAME DEFINE_CONST_OUSTRING("ooSetupFactoryUIName") + +#define PARSE_URL( aURL ) \ + Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance( \ + DEFINE_CONST_UNICODE("com.sun.star.util.URLTransformer" )), UNO_QUERY ); \ + xTrans->parseStrict( aURL ) + +//......................................................................... +namespace sfx2 +{ +//......................................................................... + + void HandleTaskPaneList( Window* pWindow, BOOL bAddToList ) + { + Window* pParent = pWindow->GetParent(); + DBG_ASSERT( pParent, "HandleTaskPaneList(): every window here should have a parent" ); + + SystemWindow* pSysWin = pParent->GetSystemWindow(); + if( pSysWin ) + { + TaskPaneList* pTaskPaneList = pSysWin->GetTaskPaneList(); + if( pTaskPaneList ) + { + if( bAddToList ) + pTaskPaneList->AddWindow( pWindow ); + else + pTaskPaneList->RemoveWindow( pWindow ); + } + } + } + + /** Prepare a search string for searching or selecting. + For searching every search word needs the postfix '*' and the delimiter ' ' if necessary. + For selecting the delimiter '|' is required to search with regular expressions. + Samples: + search string | output for searching | output for selecting + ----------------------------------------------------------- + "text" | "text*" | "text" + "text*" | "text*" | "text" + "text menu" | "text* menu*" | "text|menu" + */ + String PrepareSearchString( const String& rSearchString, + Reference< XBreakIterator > xBreak, bool bForSearch ) + { + String sSearchStr; + sal_Int32 nStartPos = 0; + const Locale aLocale = Application::GetSettings().GetUILocale(); + Boundary aBoundary = xBreak->getWordBoundary( + rSearchString, nStartPos, aLocale, WordType::ANYWORD_IGNOREWHITESPACES, sal_True ); + + while ( aBoundary.startPos != aBoundary.endPos ) + { + nStartPos = aBoundary.endPos; + String sSearchToken( rSearchString.Copy( + (USHORT)aBoundary.startPos, (USHORT)aBoundary.endPos - (USHORT)aBoundary.startPos ) ); + if ( sSearchToken.Len() > 0 && ( sSearchToken.Len() > 1 || sSearchToken.GetChar(0) != '.' ) ) + { + if ( bForSearch && sSearchToken.GetChar( sSearchToken.Len() - 1 ) != '*' ) + sSearchToken += '*'; + + if ( sSearchToken.Len() > 1 || + ( sSearchToken.Len() > 0 && sSearchToken.GetChar( 0 ) != '*' ) ) + { + if ( sSearchStr.Len() > 0 ) + { + if ( bForSearch ) + sSearchStr += ' '; + else + sSearchStr += '|'; + } + sSearchStr += sSearchToken; + } + } + aBoundary = xBreak->nextWord( rSearchString, nStartPos, + aLocale, WordType::ANYWORD_IGNOREWHITESPACES ); + } + + return sSearchStr; + } +//......................................................................... +// namespace sfx2 +} +//......................................................................... + +// struct IndexEntry_Impl ------------------------------------------------ + +struct IndexEntry_Impl +{ + sal_Bool m_bSubEntry; + String m_aURL; + + IndexEntry_Impl( const String& rURL, sal_Bool bSubEntry ) : + m_bSubEntry( bSubEntry ), m_aURL( rURL ) {} +}; + +#define NEW_ENTRY( url, bool ) \ + (void*)(ULONG)( new IndexEntry_Impl( url, bool ) ) + +// struct ContentEntry_Impl ---------------------------------------------- + +struct ContentEntry_Impl +{ + String aURL; + sal_Bool bIsFolder; + + ContentEntry_Impl( const String& rURL, sal_Bool bFolder ) : + aURL( rURL ), bIsFolder( bFolder ) {} +}; + +// ContentListBox_Impl --------------------------------------------------- + +ContentListBox_Impl::ContentListBox_Impl( Window* pParent, const ResId& rResId ) : + + SvTreeListBox( pParent, rResId ), + + aOpenBookImage ( SfxResId( IMG_HELP_CONTENT_BOOK_OPEN ) ), + aClosedBookImage ( SfxResId( IMG_HELP_CONTENT_BOOK_CLOSED ) ), + aDocumentImage ( SfxResId( IMG_HELP_CONTENT_DOC ) ) + +{ + if ( GetSettings().GetStyleSettings().GetHighContrastMode() ) + { + aOpenBookImage = Image( SfxResId( IMG_HELP_CONTENT_BOOK_OPEN_HC ) ); + aClosedBookImage = Image( SfxResId( IMG_HELP_CONTENT_BOOK_CLOSED_HC ) ); + aDocumentImage = Image( SfxResId( IMG_HELP_CONTENT_DOC_HC ) ); + } + + SetWindowBits( WB_HIDESELECTION | WB_HSCROLL ); + + SetEntryHeight( 16 ); + SetSelectionMode( SINGLE_SELECTION ); + SetSpaceBetweenEntries( 2 ); + SetNodeBitmaps( aClosedBookImage, aOpenBookImage ); + + SetSublistOpenWithReturn(); + SetSublistOpenWithLeftRight(); + + InitRoot(); +} + +// ----------------------------------------------------------------------- + +ContentListBox_Impl::~ContentListBox_Impl() +{ + USHORT nPos = 0; + SvLBoxEntry* pEntry = GetEntry( nPos++ ); + while ( pEntry ) + { + ::rtl::OUString aTemp( GetEntryText( pEntry ) ); + ClearChildren( pEntry ); + delete (ContentEntry_Impl*)pEntry->GetUserData(); + pEntry = GetEntry( nPos++ ); + } +} + +// ----------------------------------------------------------------------- + +void ContentListBox_Impl::InitRoot() +{ + String aHelpTreeviewURL( DEFINE_CONST_UNICODE("vnd.sun.star.hier://com.sun.star.help.TreeView/") ); + ::com::sun::star::uno::Sequence< ::rtl::OUString > aList = + SfxContentHelper::GetHelpTreeViewContents( aHelpTreeviewURL ); + + const ::rtl::OUString* pEntries = aList.getConstArray(); + UINT32 i, nCount = aList.getLength(); + for ( i = 0; i < nCount; ++i ) + { + String aRow( pEntries[i] ); + String aTitle, aURL; + xub_StrLen nIdx = 0; + aTitle = aRow.GetToken( 0, '\t', nIdx ); + aURL = aRow.GetToken( 0, '\t', nIdx ); + sal_Unicode cFolder = aRow.GetToken( 0, '\t', nIdx ).GetChar(0); + sal_Bool bIsFolder = ( '1' == cFolder ); + SvLBoxEntry* pEntry = InsertEntry( aTitle, aOpenBookImage, aClosedBookImage, NULL, TRUE ); + if ( bIsFolder ) + pEntry->SetUserData( new ContentEntry_Impl( aURL, sal_True ) ); + } +} + +// ----------------------------------------------------------------------- + +void ContentListBox_Impl::ClearChildren( SvLBoxEntry* pParent ) +{ + SvLBoxEntry* pEntry = FirstChild( pParent ); + while ( pEntry ) + { + ::rtl::OUString aTemp( GetEntryText( pEntry ) ); + ClearChildren( pEntry ); + delete (ContentEntry_Impl*)pEntry->GetUserData(); + pEntry = NextSibling( pEntry ); + } +} + +// ----------------------------------------------------------------------- + +void ContentListBox_Impl::RequestingChilds( SvLBoxEntry* pParent ) +{ + try + { + if ( !pParent->HasChilds() ) + { + if ( pParent->GetUserData() ) + { + String aTmpURL( ( (ContentEntry_Impl*)pParent->GetUserData() )->aURL ); + ::com::sun::star::uno::Sequence< ::rtl::OUString > aList = + SfxContentHelper::GetHelpTreeViewContents( aTmpURL ); + + const ::rtl::OUString* pEntries = aList.getConstArray(); + UINT32 i, nCount = aList.getLength(); + for ( i = 0; i < nCount; ++i ) + { + String aRow( pEntries[i] ); + String aTitle, aURL; + xub_StrLen nIdx = 0; + aTitle = aRow.GetToken( 0, '\t', nIdx ); + aURL = aRow.GetToken( 0, '\t', nIdx ); + sal_Unicode cFolder = aRow.GetToken( 0, '\t', nIdx ).GetChar(0); + sal_Bool bIsFolder = ( '1' == cFolder ); + SvLBoxEntry* pEntry = NULL; + if ( bIsFolder ) + { + pEntry = InsertEntry( aTitle, aOpenBookImage, aClosedBookImage, pParent, TRUE ); + pEntry->SetUserData( new ContentEntry_Impl( aURL, sal_True ) ); + } + else + { + pEntry = InsertEntry( aTitle, aDocumentImage, aDocumentImage, pParent ); + Any aAny( ::utl::UCBContentHelper::GetProperty( aURL, String(RTL_CONSTASCII_USTRINGPARAM("TargetURL" ) ) ) ); + rtl::OUString aTargetURL; + if ( aAny >>= aTargetURL ) + pEntry->SetUserData( new ContentEntry_Impl( aTargetURL, sal_False ) ); + } + } + } + } + } + catch( Exception& ) + { + DBG_ERROR( "ContentListBox_Impl::RequestingChilds(): unexpected exception" ); + } +} + +// ----------------------------------------------------------------------- + +long ContentListBox_Impl::Notify( NotifyEvent& rNEvt ) +{ + sal_Bool bHandled = sal_False; + if ( rNEvt.GetType() == EVENT_KEYINPUT && + KEY_RETURN == rNEvt.GetKeyEvent()->GetKeyCode().GetCode() ) + { + GetDoubleClickHdl().Call( NULL ); + bHandled = sal_True; + } + + return bHandled ? 1 : SvTreeListBox::Notify( rNEvt ); +} + +// ----------------------------------------------------------------------- + +String ContentListBox_Impl::GetSelectEntry() const +{ + String aRet; + SvLBoxEntry* pEntry = FirstSelected(); + if ( pEntry && !( (ContentEntry_Impl*)pEntry->GetUserData() )->bIsFolder ) + aRet = ( (ContentEntry_Impl*)pEntry->GetUserData() )->aURL; + return aRet; +} + +// class HelpTabPage_Impl ------------------------------------------------ + +HelpTabPage_Impl::HelpTabPage_Impl( + Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin, const ResId& rResId ) : + + TabPage( pParent, rResId ), + + m_pIdxWin( _pIdxWin ) + +{ +} + +// class ContentTabPage_Impl --------------------------------------------- + +ContentTabPage_Impl::ContentTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin ) : + + HelpTabPage_Impl( pParent, _pIdxWin, SfxResId( TP_HELP_CONTENT ) ), + + aContentBox( this, SfxResId( LB_CONTENTS ) ) + +{ + FreeResource(); + + aContentBox.Show(); +} + +// ----------------------------------------------------------------------- + +void ContentTabPage_Impl::Resize() +{ + Size aSize = GetOutputSizePixel(); + aSize.Width() -= 8; + aSize.Height() -= 8; + aContentBox.SetPosSizePixel( Point( 4, 4 ), aSize ); +} + +// ----------------------------------------------------------------------- + +void ContentTabPage_Impl::ActivatePage() +{ + if ( !m_pIdxWin->WasCursorLeftOrRight() ) + SetFocusOnBox(); +} + +// ----------------------------------------------------------------------- + +Control* ContentTabPage_Impl::GetLastFocusControl() +{ + return &aContentBox; +} + +// class IndexBox_Impl --------------------------------------------------- + +IndexBox_Impl::IndexBox_Impl( Window* pParent, const ResId& rResId ) : + + ComboBox( pParent, rResId ) + +{ + EnableAutocomplete( TRUE ); + EnableUserDraw( TRUE ); +} + +// ----------------------------------------------------------------------- + +void IndexBox_Impl::UserDraw( const UserDrawEvent& rUDEvt ) +{ + IndexEntry_Impl* pEntry = (IndexEntry_Impl*)(ULONG)GetEntryData( rUDEvt.GetItemId() ); + if ( pEntry && pEntry->m_bSubEntry ) + { + // indent sub entries + Point aPos( rUDEvt.GetRect().TopLeft() ); + aPos.X() += 8; + aPos.Y() += ( rUDEvt.GetRect().GetHeight() - rUDEvt.GetDevice()->GetTextHeight() ) / 2; + String aEntry( GetEntry( rUDEvt.GetItemId() ) ); + USHORT nPos = aEntry.Search( ';' ); + rUDEvt.GetDevice()->DrawText( aPos, ( nPos != STRING_NOTFOUND ) ? aEntry.Copy( nPos + 1 ) : aEntry ); + } + else + DrawEntry( rUDEvt, FALSE, TRUE, TRUE ); +} + +// ----------------------------------------------------------------------- + +long IndexBox_Impl::Notify( NotifyEvent& rNEvt ) +{ + sal_Bool bHandled = sal_False; + if ( rNEvt.GetType() == EVENT_KEYINPUT && + KEY_RETURN == rNEvt.GetKeyEvent()->GetKeyCode().GetCode() ) + { + GetDoubleClickHdl().Call( NULL ); + bHandled = sal_True; + } + + return bHandled ? 1 : ComboBox::Notify( rNEvt ); +} + +// ----------------------------------------------------------------------- + +void IndexBox_Impl::SelectExecutableEntry() +{ + USHORT nPos = GetEntryPos( GetText() ); + if ( nPos != COMBOBOX_ENTRY_NOTFOUND ) + { + USHORT nOldPos = nPos; + String aEntryText; + IndexEntry_Impl* pEntry = (IndexEntry_Impl*)(ULONG)GetEntryData( nPos ); + USHORT nCount = GetEntryCount(); + while ( nPos < nCount && ( !pEntry || pEntry->m_aURL.Len() == 0 ) ) + { + pEntry = (IndexEntry_Impl*)(ULONG)GetEntryData( ++nPos ); + aEntryText = GetEntry( nPos ); + } + + if ( nOldPos != nPos ) + SetText( aEntryText ); + } +} + +// class IndexTabPage_Impl ----------------------------------------------- + +IndexTabPage_Impl::IndexTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin ) : + + HelpTabPage_Impl( pParent, _pIdxWin, SfxResId( TP_HELP_INDEX ) ), + + aExpressionFT ( this, SfxResId( FT_EXPRESSION ) ), + aIndexCB ( this, SfxResId( CB_INDEX ) ), + aOpenBtn ( this, SfxResId( PB_OPEN_INDEX ) ), + + bIsActivated ( sal_False ) + +{ + FreeResource(); + + aOpenBtn.SetClickHdl( LINK( this, IndexTabPage_Impl, OpenHdl ) ); + Link aTimeoutLink = LINK( this, IndexTabPage_Impl, TimeoutHdl ); + aFactoryTimer.SetTimeoutHdl( aTimeoutLink ); + aFactoryTimer.SetTimeout( 300 ); + aKeywordTimer.SetTimeoutHdl( aTimeoutLink ); + aFactoryTimer.SetTimeout( 300 ); + + nMinWidth = aOpenBtn.GetSizePixel().Width(); +} + +// ----------------------------------------------------------------------- + +IndexTabPage_Impl::~IndexTabPage_Impl() +{ + ClearIndex(); +} + +// ----------------------------------------------------------------------- + +namespace sfx2 { + + struct equalOUString + { + bool operator()( const ::rtl::OUString& rKey1, const ::rtl::OUString& rKey2 ) const + { + return !!( rKey1 == rKey2 ); + } + }; + + + struct hashOUString + { + size_t operator()( const ::rtl::OUString& rName ) const + { + return rName.hashCode(); + } + }; + + typedef ::std::hash_map< ::rtl::OUString, int, hashOUString, equalOUString > KeywordInfo; +} + +#define UNIFY_AND_INSERT_TOKEN( aToken ) \ + it = \ + aInfo.insert( sfx2::KeywordInfo::value_type( aToken, 0 ) ).first; \ + if ( ( tmp = it->second++ ) != 0 ) \ + nPos = aIndexCB.InsertEntry( aToken + rtl::OUString( append, tmp ) ); \ + else \ + nPos = aIndexCB.InsertEntry( aToken ) + +#define INSERT_DATA( j ) \ + if ( aAnchorList[j].getLength() > 0 ) \ + { \ + aData.append( aRefList[j] ).append( sal_Unicode('#') ).append( aAnchorList[j] ); \ + aIndexCB.SetEntryData( nPos, NEW_ENTRY( aData.makeStringAndClear(), insert ) ); \ + } \ + else \ + aIndexCB.SetEntryData( nPos, NEW_ENTRY( aRefList[j], insert ) ); + +// ----------------------------------------------------------------------- + +void IndexTabPage_Impl::InitializeIndex() +{ + WaitObject( this ); + + // By now more than 256 equal entries are not allowed + sal_Unicode append[256]; + for( int k = 0; k < 256; ++k ) + append[k] = sal_Unicode( ' ' ); + + sfx2::KeywordInfo aInfo; + aIndexCB.SetUpdateMode( FALSE ); + + try + { + ::rtl::OUString aURL = HELP_URL; + aURL += ::rtl::OUString( sFactory ); + + String aTemp = aURL; + AppendConfigToken_Impl( aTemp, sal_True ); + aURL = aTemp; + + Content aCnt( aURL, Reference< ::com::sun::star::ucb::XCommandEnvironment > () ); + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > xInfo = aCnt.getProperties(); + if ( xInfo->hasPropertyByName( PROPERTY_ANCHORREF ) ) + { + ::com::sun::star::uno::Sequence< ::rtl::OUString > aPropSeq( 4 ); + aPropSeq[0] = PROPERTY_KEYWORDLIST; + aPropSeq[1] = PROPERTY_KEYWORDREF; + aPropSeq[2] = PROPERTY_ANCHORREF; + aPropSeq[3] = PROPERTY_TITLEREF; + + // abi: use one possibly remote call only + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > aAnySeq = + aCnt.getPropertyValues( aPropSeq ); + + ::com::sun::star::uno::Sequence< ::rtl::OUString > aKeywordList; + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::rtl::OUString > > aKeywordRefList; + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::rtl::OUString > > aAnchorRefList; + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::rtl::OUString > > aTitleRefList; + + if ( ( aAnySeq[0] >>= aKeywordList ) && ( aAnySeq[1] >>= aKeywordRefList ) && + ( aAnySeq[2] >>= aAnchorRefList ) && ( aAnySeq[3] >>= aTitleRefList ) ) + { + sal_Bool insert; + USHORT nPos; + int ndx,tmp; + ::rtl::OUString aIndex, aTempString; + ::rtl::OUStringBuffer aData( 128 ); // Capacity of up to 128 characters + sfx2::KeywordInfo::iterator it; + + for ( int i = 0; i < aKeywordList.getLength(); ++i ) + { + // abi: Do not copy, but use references + const ::rtl::OUString& aKeywordPair = aKeywordList[i]; + DBG_ASSERT( aKeywordPair.getLength() > 0, "invalid help index" ); + const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aRefList = aKeywordRefList[i]; + const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aAnchorList = aAnchorRefList[i]; + const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aTitleList = aTitleRefList[i]; + + DBG_ASSERT( aRefList.getLength() == aAnchorList.getLength(),"reference list and title list of different length" ); + + insert = ( ( ndx = aKeywordPair.indexOf( sal_Unicode( ';' ) ) ) == -1 ? sal_False : sal_True ); + + if ( insert ) + { + aTempString = aKeywordPair.copy( 0, ndx ); + if ( aIndex != aTempString ) + { + aIndex = aTempString; + UNIFY_AND_INSERT_TOKEN( aTempString ); + } + } + else + aIndex = ::rtl::OUString(); + + // Assume the token is trimed + UNIFY_AND_INSERT_TOKEN( aKeywordPair ); + + sal_uInt32 nRefListLen = aRefList.getLength(); + + DBG_ASSERT( aAnchorList.getLength(), "*IndexTabPage_Impl::InitializeIndex(): AnchorList is empty!" ); \ + DBG_ASSERT( nRefListLen, "*IndexTabPage_Impl::InitializeIndex(): RefList is empty!" ); \ + + if ( aAnchorList.getLength() && nRefListLen ) + { + INSERT_DATA( 0 ); + } + + for ( sal_uInt32 j = 1; j < nRefListLen ; ++j ) + { + aData + .append( aKeywordPair ) + .append( sal_Unicode(' ') ) + .append( sal_Unicode('-') ) + .append( sal_Unicode(' ') ) + .append( aTitleList[j] ); + + aTempString = aData.makeStringAndClear(); + UNIFY_AND_INSERT_TOKEN( aTempString ); + INSERT_DATA( j ); + } + } + } + } + } + catch( Exception& ) + { + DBG_ERROR( "IndexTabPage_Impl::InitializeIndex(): unexpected exception" ); + } + + aIndexCB.SetUpdateMode( TRUE ); + + if ( sKeyword.Len() > 0 ) + aKeywordLink.Call( this ); +} + +#undef INSERT_DATA +#undef UNIFY_AND_INSERT_TOKEN + +// ----------------------------------------------------------------------- + +void IndexTabPage_Impl::ClearIndex() +{ + USHORT nCount = aIndexCB.GetEntryCount(); + for ( USHORT i = 0; i < nCount; ++i ) + delete (IndexEntry_Impl*)(ULONG)aIndexCB.GetEntryData(i); + aIndexCB.Clear(); +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( IndexTabPage_Impl, OpenHdl, PushButton*, EMPTYARG ) +{ + aIndexCB.GetDoubleClickHdl().Call( &aIndexCB ); + return 0; +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( IndexTabPage_Impl, TimeoutHdl, Timer*, pTimer ) +{ + if ( &aFactoryTimer == pTimer ) + InitializeIndex(); + else if ( &aKeywordTimer == pTimer && sKeyword.Len() > 0 ) + aKeywordLink.Call( this ); + return 0; +} + +// ----------------------------------------------------------------------- + +void IndexTabPage_Impl::Resize() +{ + Size aSize = GetSizePixel(); + if ( aSize.Width() < nMinWidth ) + aSize.Width() = nMinWidth; + Point aPnt = aExpressionFT.GetPosPixel(); + Size aNewSize = aExpressionFT.GetSizePixel(); + aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 ); + aExpressionFT.SetSizePixel( aNewSize ); + + Size a6Size = LogicToPixel( Size( 6, 6 ), MAP_APPFONT ); + Size aBtnSize = aOpenBtn.GetSizePixel(); + + aPnt = aIndexCB.GetPosPixel(); + aNewSize = aIndexCB.GetSizePixel(); + aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 ); + aNewSize.Height() = aSize.Height() - aPnt.Y(); + aNewSize.Height() -= ( aBtnSize.Height() + ( a6Size.Height() * 3 / 2 ) ); + aIndexCB.SetSizePixel( aNewSize ); + + aPnt.X() += ( aNewSize.Width() - aBtnSize.Width() ); + aPnt.Y() += aNewSize.Height() + ( a6Size.Height() / 2 ); + long nMinX = aIndexCB.GetPosPixel().X(); + if ( aPnt.X() < nMinX ) + aPnt.X() = nMinX; + aOpenBtn.SetPosPixel( aPnt ); +} + +// ----------------------------------------------------------------------- + +void IndexTabPage_Impl::ActivatePage() +{ + if ( !bIsActivated ) + { + bIsActivated = sal_True; + aFactoryTimer.Start(); + } + + if ( !m_pIdxWin->WasCursorLeftOrRight() ) + SetFocusOnBox(); +} + +// ----------------------------------------------------------------------- + +Control* IndexTabPage_Impl::GetLastFocusControl() +{ + return &aOpenBtn; +} + +// ----------------------------------------------------------------------- + +void IndexTabPage_Impl::SetDoubleClickHdl( const Link& rLink ) +{ + aIndexCB.SetDoubleClickHdl( rLink ); +} + +// ----------------------------------------------------------------------- + +void IndexTabPage_Impl::SetFactory( const String& rFactory ) +{ + String sNewFactory( rFactory ); + DBG_ASSERT( sNewFactory.Len() > 0, "empty factory" ); + bool bValid = m_pIdxWin->IsValidFactory( rFactory ); + + if ( sFactory.Len() == 0 && !bValid ) + { + sNewFactory = SfxHelp::GetDefaultHelpModule(); + bValid = true; + } + + if ( sNewFactory != sFactory && bValid ) + { + sFactory = sNewFactory; + ClearIndex(); + if ( bIsActivated ) + aFactoryTimer.Start(); + } +} + +// ----------------------------------------------------------------------- + +String IndexTabPage_Impl::GetSelectEntry() const +{ + String aRet; + IndexEntry_Impl* pEntry = (IndexEntry_Impl*)(ULONG)aIndexCB.GetEntryData( aIndexCB.GetEntryPos( aIndexCB.GetText() ) ); + if ( pEntry ) + aRet = pEntry->m_aURL; + return aRet; +} + +// ----------------------------------------------------------------------- + +void IndexTabPage_Impl::SetKeyword( const String& rKeyword ) +{ + sKeyword = rKeyword; + + if ( aIndexCB.GetEntryCount() > 0 ) + aKeywordTimer.Start(); + else if ( !bIsActivated ) + aFactoryTimer.Start(); +} + +// ----------------------------------------------------------------------- + +sal_Bool IndexTabPage_Impl::HasKeyword() const +{ + sal_Bool bRet = sal_False; + if ( sKeyword.Len() > 0 ) + { + USHORT nPos = aIndexCB.GetEntryPos( sKeyword ); + bRet = ( nPos != LISTBOX_ENTRY_NOTFOUND ); + } + + return bRet; +} + +// ----------------------------------------------------------------------- +//added by BerryJia for fixing Bug98251, 2002-12-11 +sal_Bool IndexTabPage_Impl::HasKeywordIgnoreCase() +{ + sal_Bool bRet = sal_False; + if ( sKeyword.Len() > 0 ) + { + USHORT nEntries = aIndexCB.GetEntryCount(); + String sIndexItem; + const vcl::I18nHelper& rI18nHelper = GetSettings().GetLocaleI18nHelper(); + for ( USHORT n = 0; n < nEntries; n++) + { + sIndexItem = aIndexCB.GetEntry( n ); + if (rI18nHelper.MatchString( sIndexItem, sKeyword )) + { + sKeyword = sIndexItem; + bRet = sal_True; + } + } + } + + return bRet; +} + +// ----------------------------------------------------------------------- + +void IndexTabPage_Impl::OpenKeyword() +{ + if ( sKeyword.Len() > 0 ) + { + aIndexCB.SetText( sKeyword ); + aIndexCB.GetDoubleClickHdl().Call( NULL ); + sKeyword.Erase(); + } +} + +// class SearchBox_Impl -------------------------------------------------- + +long SearchBox_Impl::PreNotify( NotifyEvent& rNEvt ) +{ + sal_Bool bHandled = sal_False; + if ( !IsInDropDown() && + rNEvt.GetWindow() == GetSubEdit() && + rNEvt.GetType() == EVENT_KEYINPUT && + KEY_RETURN == rNEvt.GetKeyEvent()->GetKeyCode().GetCode() ) + { + aSearchLink.Call( NULL ); + bHandled = sal_True; + } + return bHandled ? 1 : ComboBox::PreNotify( rNEvt ); +} + +// ----------------------------------------------------------------------- + +void SearchBox_Impl::Select() +{ + if ( !IsTravelSelect() ) + aSearchLink.Call( NULL ); +} + +// class SearchResultsBox_Impl ------------------------------------------- + +long SearchResultsBox_Impl::Notify( NotifyEvent& rNEvt ) +{ + sal_Bool bHandled = sal_False; + if ( rNEvt.GetType() == EVENT_KEYINPUT && + KEY_RETURN == rNEvt.GetKeyEvent()->GetKeyCode().GetCode() ) + { + GetDoubleClickHdl().Call( NULL ); + bHandled = sal_True; + } + + return bHandled ? 1 : ListBox::Notify( rNEvt ); +} + +// class SearchTabPage_Impl ---------------------------------------------- + +SearchTabPage_Impl::SearchTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin ) : + + HelpTabPage_Impl( pParent, _pIdxWin, SfxResId( TP_HELP_SEARCH ) ), + + aSearchFT ( this, SfxResId( FT_SEARCH ) ), + aSearchED ( this, SfxResId( ED_SEARCH ) ), + aSearchBtn ( this, SfxResId( PB_SEARCH ) ), + aFullWordsCB ( this, SfxResId( CB_FULLWORDS ) ), + aScopeCB ( this, SfxResId( CB_SCOPE ) ), + aResultsLB ( this, SfxResId( LB_RESULT ) ), + aOpenBtn ( this, SfxResId( PB_OPEN_SEARCH ) ), + xBreakIterator ( vcl::unohelper::CreateBreakIterator() ) + +{ + FreeResource(); + + Link aLink = LINK( this, SearchTabPage_Impl, SearchHdl ); + aSearchED.SetSearchLink( aLink ); + aSearchBtn.SetClickHdl( aLink ); + aSearchED.SetModifyHdl( LINK( this, SearchTabPage_Impl, ModifyHdl ) ); + aOpenBtn.SetClickHdl( LINK( this, SearchTabPage_Impl, OpenHdl ) ); + + aMinSize = GetSizePixel(); + + SvtViewOptions aViewOpt( E_TABPAGE, CONFIGNAME_SEARCHPAGE ); + if ( aViewOpt.Exists() ) + { + String aUserData; + Any aUserItem = aViewOpt.GetUserItem( USERITEM_NAME ); + ::rtl::OUString aTemp; + if ( aUserItem >>= aTemp ) + { + aUserData = String( aTemp ); + BOOL bChecked = ( 1 == aUserData.GetToken(0).ToInt32() ) ? TRUE : FALSE; + aFullWordsCB.Check( bChecked ); + bChecked = ( 1 == aUserData.GetToken(1).ToInt32() ) ? TRUE : FALSE; + aScopeCB.Check( bChecked ); + + for ( USHORT i = 2; i < aUserData.GetTokenCount(); ++i ) + { + String aToken = aUserData.GetToken(i); + aSearchED.InsertEntry( INetURLObject::decode( + aToken, '%', INetURLObject::DECODE_WITH_CHARSET ) ); + } + } + } + + ModifyHdl( &aSearchED ); +} + +// ----------------------------------------------------------------------- + +SearchTabPage_Impl::~SearchTabPage_Impl() +{ + SvtViewOptions aViewOpt( E_TABPAGE, CONFIGNAME_SEARCHPAGE ); + sal_Int32 nChecked = aFullWordsCB.IsChecked() ? 1 : 0; + String aUserData = String::CreateFromInt32( nChecked ); + aUserData += ';'; + nChecked = aScopeCB.IsChecked() ? 1 : 0; + aUserData += String::CreateFromInt32( nChecked ); + aUserData += ';'; + USHORT nCount = Min( aSearchED.GetEntryCount(), (USHORT)10 ); // save only 10 entries + + for ( USHORT i = 0; i < nCount; ++i ) + { + rtl::OUString aText = aSearchED.GetEntry(i); + aUserData += String(INetURLObject::encode( + aText, INetURLObject::PART_UNO_PARAM_VALUE, '%', + INetURLObject::ENCODE_ALL )); + aUserData += ';'; + } + + aUserData.EraseTrailingChars(';'); + Any aUserItem = makeAny( ::rtl::OUString( aUserData ) ); + aViewOpt.SetUserItem( USERITEM_NAME, aUserItem ); +} + +// ----------------------------------------------------------------------- + +void SearchTabPage_Impl::ClearSearchResults() +{ + USHORT nCount = aResultsLB.GetEntryCount(); + for ( USHORT i = 0; i < nCount; ++i ) + delete (String*)(ULONG)aResultsLB.GetEntryData(i); + aResultsLB.Clear(); + aResultsLB.Update(); +} + +// ----------------------------------------------------------------------- + +void SearchTabPage_Impl::RememberSearchText( const String& rSearchText ) +{ + for ( USHORT i = 0; i < aSearchED.GetEntryCount(); ++i ) + { + if ( rSearchText == aSearchED.GetEntry(i) ) + { + aSearchED.RemoveEntry(i); + break; + } + } + + aSearchED.InsertEntry( rSearchText, 0 ); +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( SearchTabPage_Impl, SearchHdl, PushButton*, EMPTYARG ) +{ + String aSearchText = TRIM( aSearchED.GetText() ); + if ( aSearchText.Len() > 0 ) + { + EnterWait(); + ClearSearchResults(); + RememberSearchText( aSearchText ); + String aSearchURL = HELP_URL; + aSearchURL += aFactory; + aSearchURL += String( HELP_SEARCH_TAG ); + if ( !aFullWordsCB.IsChecked() ) + aSearchText = sfx2::PrepareSearchString( aSearchText, xBreakIterator, true ); + aSearchURL += aSearchText; + AppendConfigToken_Impl( aSearchURL, sal_False ); + if ( aScopeCB.IsChecked() ) + aSearchURL += DEFINE_CONST_UNICODE("&Scope=Heading"); + Sequence< ::rtl::OUString > aFactories = SfxContentHelper::GetResultSet( aSearchURL ); + const ::rtl::OUString* pFacs = aFactories.getConstArray(); + UINT32 i, nCount = aFactories.getLength(); + for ( i = 0; i < nCount; ++i ) + { + String aRow( pFacs[i] ); + String aTitle, aType; + xub_StrLen nIdx = 0; + aTitle = aRow.GetToken( 0, '\t', nIdx ); + aType = aRow.GetToken( 0, '\t', nIdx ); + String* pURL = new String( aRow.GetToken( 0, '\t', nIdx ) ); + USHORT nPos = aResultsLB.InsertEntry( aTitle ); + aResultsLB.SetEntryData( nPos, (void*)(ULONG)pURL ); + } + LeaveWait(); + + if ( !nCount ) + { + InfoBox aBox( this, SfxResId( RID_INFO_NOSEARCHRESULTS ) ); + aBox.SetText( String( SfxResId( STR_HELP_WINDOW_TITLE ) ) ); + aBox.Execute(); + } + } + return 0; +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( SearchTabPage_Impl, OpenHdl, PushButton*, EMPTYARG ) +{ + aResultsLB.GetDoubleClickHdl().Call( &aResultsLB ); + return 0; +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( SearchTabPage_Impl, ModifyHdl, Edit*, EMPTYARG ) +{ + String aSearchText = TRIM( aSearchED.GetText() ); + aSearchBtn.Enable( aSearchText.Len() > 0 ); + return 0; +} + +// ----------------------------------------------------------------------- + +void SearchTabPage_Impl::Resize() +{ + Size a6Size = LogicToPixel( Size( 6, 6 ), MAP_APPFONT ); + Size aSize = GetSizePixel(); + if ( aSize.Width() < aMinSize.Width() ) + aSize.Width() = aMinSize.Width(); + Point aPnt = aSearchFT.GetPosPixel(); + Size aNewSize = aSearchFT.GetSizePixel(); + aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 ); + aSearchFT.SetSizePixel( aNewSize ); + aNewSize.Height() = aResultsLB.GetSizePixel().Height(); + aResultsLB.SetSizePixel( aNewSize ); + aNewSize.Height() = aFullWordsCB.GetSizePixel().Height(); + aFullWordsCB.SetSizePixel( aNewSize ); + aScopeCB.SetSizePixel( aNewSize ); + aNewSize = aSearchED.GetSizePixel(); + aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 ) - + ( aSearchBtn.GetSizePixel().Width() + ( aPnt.X() / 2 ) ); + aSearchED.SetSizePixel( aNewSize ); + Point aNewPnt = aSearchBtn.GetPosPixel(); + aNewPnt.X() = aPnt.X() + aNewSize.Width() + ( aPnt.X() / 2 ); + aSearchBtn.SetPosPixel( aNewPnt ); + + if ( aSize.Height() > aMinSize.Height() ) + { + long n3Height = a6Size.Height() / 2; + Size aBtnSize = aOpenBtn.GetSizePixel(); + long nExtraHeight = aBtnSize.Height() + n3Height; + + aPnt = aResultsLB.GetPosPixel(); + aNewSize = aResultsLB.GetSizePixel(); + aNewSize.Height() = aSize.Height() - aPnt.Y(); + aNewSize.Height() -= ( nExtraHeight + ( a6Size.Height() * 3 / 2 ) ); + aResultsLB.SetSizePixel( aNewSize ); + + aPnt.X() += ( aNewSize.Width() - aBtnSize.Width() ); + aPnt.Y() += aNewSize.Height() + a6Size.Height(); + aOpenBtn.SetPosPixel( aPnt ); + } +} + +// ----------------------------------------------------------------------- + +void SearchTabPage_Impl::ActivatePage() +{ + if ( !m_pIdxWin->WasCursorLeftOrRight() ) + aSearchED.GrabFocus(); +} + +// ----------------------------------------------------------------------- + +Control* SearchTabPage_Impl::GetLastFocusControl() +{ + return &aOpenBtn; +} + +// ----------------------------------------------------------------------- + +void SearchTabPage_Impl::SetDoubleClickHdl( const Link& rLink ) +{ + aResultsLB.SetDoubleClickHdl( rLink ); +} + +// ----------------------------------------------------------------------- + +String SearchTabPage_Impl::GetSelectEntry() const +{ + String aRet; + String* pData = (String*)(ULONG)aResultsLB.GetEntryData( aResultsLB.GetSelectEntryPos() ); + if ( pData ) + aRet = String( *pData ); + return aRet; +} + +// ----------------------------------------------------------------------- + +void SearchTabPage_Impl::ClearPage() +{ + ClearSearchResults(); + aSearchED.SetText( String() ); +} + +// ----------------------------------------------------------------------- + +sal_Bool SearchTabPage_Impl::OpenKeyword( const String& rKeyword ) +{ + sal_Bool bRet = sal_False; + aSearchED.SetText( rKeyword ); + SearchHdl( NULL ); + if ( aResultsLB.GetEntryCount() > 0 ) + { + // found keyword -> open it + aResultsLB.SelectEntryPos(0); + OpenHdl( NULL ); + bRet = sal_True; + } + + return bRet; +} + +// class BookmarksTabPage_Impl ------------------------------------------- + +void GetBookmarkEntry_Impl +( + Sequence< PropertyValue >& aBookmarkEntry, + ::rtl::OUString& rTitle, + ::rtl::OUString& rURL +) +{ + for ( int i = 0; i < aBookmarkEntry.getLength(); i++ ) + { + PropertyValue aValue = aBookmarkEntry[i]; + if ( aValue.Name == HISTORY_PROPERTYNAME_URL ) + aValue.Value >>= rURL; + else if ( aValue.Name == HISTORY_PROPERTYNAME_TITLE ) + aValue.Value >>= rTitle; + } +} + +// ----------------------------------------------------------------------- + +BookmarksBox_Impl::BookmarksBox_Impl( Window* pParent, const ResId& rResId ) : + + ListBox( pParent, rResId ) + +{ +} + +// ----------------------------------------------------------------------- + +BookmarksBox_Impl::~BookmarksBox_Impl() +{ + // save bookmarks to configuration + SvtHistoryOptions aHistOpt; + aHistOpt.Clear( eHELPBOOKMARKS ); + rtl::OUString sEmpty; + USHORT nCount = GetEntryCount(); + for ( USHORT i = 0; i < nCount; ++i ) + { + String aTitle = GetEntry(i); + String* pURL = (String*)(ULONG)GetEntryData(i); + aHistOpt.AppendItem( eHELPBOOKMARKS, rtl::OUString( *pURL ), sEmpty, rtl::OUString( aTitle ), sEmpty ); + delete pURL; + } +} + +// ----------------------------------------------------------------------- + +void BookmarksBox_Impl::DoAction( USHORT nAction ) +{ + switch ( nAction ) + { + case MID_OPEN : + GetDoubleClickHdl().Call( NULL ); + break; + + case MID_RENAME : + { + USHORT nPos = GetSelectEntryPos(); + if ( nPos != LISTBOX_ENTRY_NOTFOUND ) + { + SfxAddHelpBookmarkDialog_Impl aDlg( this, sal_True ); + aDlg.SetTitle( GetEntry( nPos ) ); + if ( aDlg.Execute() == RET_OK ) + { + String* pURL = (String*)(ULONG)GetEntryData( nPos ); + RemoveEntry( nPos ); + rtl::OUString aImageURL = IMAGE_URL; + aImageURL += INetURLObject( *pURL ).GetHost(); + nPos = InsertEntry( aDlg.GetTitle(), SvFileInformationManager::GetImage( aImageURL ) ); + SetEntryData( nPos, (void*)(ULONG)( new String( *pURL ) ) ); + SelectEntryPos( nPos ); + delete pURL; + } + } + break; + } + + case MID_DELETE : + { + USHORT nPos = GetSelectEntryPos(); + if ( nPos != LISTBOX_ENTRY_NOTFOUND ) + { + RemoveEntry( nPos ); + USHORT nCount = GetEntryCount(); + if ( nCount ) + { + if ( nPos >= nCount ) + nPos = nCount - 1; + SelectEntryPos( nPos ); + } + } + break; + } + } +} + +// ----------------------------------------------------------------------- + +long BookmarksBox_Impl::Notify( NotifyEvent& rNEvt ) +{ + long nRet = 0; + USHORT nType = rNEvt.GetType(); + if ( EVENT_KEYINPUT == nType ) + { + USHORT nCode = rNEvt.GetKeyEvent()->GetKeyCode().GetCode(); + if ( KEY_DELETE == nCode && GetEntryCount() > 0 ) + { + DoAction( MID_DELETE ); + nRet = 1; + } + else if ( KEY_RETURN == nCode ) + { + GetDoubleClickHdl().Call( NULL ); + nRet = 1; + } + } + else if ( EVENT_COMMAND == nType ) + { + const CommandEvent* pCEvt = rNEvt.GetCommandEvent(); + if ( pCEvt->GetCommand() == COMMAND_CONTEXTMENU ) + { + PopupMenu aMenu( SfxResId( MENU_HELP_BOOKMARKS ) ); + sal_uInt16 nId = aMenu.Execute( this, pCEvt->GetMousePosPixel() ); + if ( nId != MENU_ITEM_NOTFOUND ) + DoAction( nId ); + nRet = 1; + } + } + + return nRet ? nRet : ListBox::Notify( rNEvt ); +} + +// class BookmarksTabPage_Impl ------------------------------------------- + +BookmarksTabPage_Impl::BookmarksTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin ) : + + HelpTabPage_Impl( pParent, _pIdxWin, SfxResId( TP_HELP_BOOKMARKS ) ), + + aBookmarksFT ( this, SfxResId( FT_BOOKMARKS ) ), + aBookmarksBox ( this, SfxResId( LB_BOOKMARKS ) ), + aBookmarksPB ( this, SfxResId( PB_BOOKMARKS ) ) + +{ + FreeResource(); + + nMinWidth = aBookmarksPB.GetSizePixel().Width(); + + aBookmarksPB.SetClickHdl( LINK( this, BookmarksTabPage_Impl, OpenHdl ) ); + + // load bookmarks from configuration + Sequence< Sequence< PropertyValue > > aBookmarkSeq; + aBookmarkSeq = SvtHistoryOptions().GetList( eHELPBOOKMARKS ); + + ::rtl::OUString aTitle; + ::rtl::OUString aURL; + + UINT32 i, nCount = aBookmarkSeq.getLength(); + for ( i = 0; i < nCount; ++i ) + { + GetBookmarkEntry_Impl( aBookmarkSeq[i], aTitle, aURL ); + AddBookmarks( aTitle, aURL ); + } +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( BookmarksTabPage_Impl, OpenHdl, PushButton*, EMPTYARG ) +{ + aBookmarksBox.GetDoubleClickHdl().Call( &aBookmarksBox ); + return 0; +} + +// ----------------------------------------------------------------------- + +void BookmarksTabPage_Impl::Resize() +{ + Size aSize = GetSizePixel(); + if ( aSize.Width() < nMinWidth ) + aSize.Width() = nMinWidth; + Point aPnt = aBookmarksFT.GetPosPixel(); + Size aNewSize = aBookmarksFT.GetSizePixel(); + aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 ); + aBookmarksFT.SetSizePixel( aNewSize ); + + Size a6Size = LogicToPixel( Size( 6, 6 ), MAP_APPFONT ); + Size aBtnSize = aBookmarksPB.GetSizePixel(); + + aPnt = aBookmarksBox.GetPosPixel(); + aNewSize = aBookmarksBox.GetSizePixel(); + aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 ); + aNewSize.Height() = aSize.Height() - aPnt.Y(); + aNewSize.Height() -= ( aBtnSize.Height() + ( a6Size.Height() * 3 / 2 ) ); + aBookmarksBox.SetSizePixel( aNewSize ); + + aPnt.X() += ( aNewSize.Width() - aBtnSize.Width() ); + aPnt.Y() += aNewSize.Height() + ( a6Size.Height() / 2 ); + long nMinX = aBookmarksBox.GetPosPixel().X(); + if ( aPnt.X() < nMinX ) + aPnt.X() = nMinX; + aBookmarksPB.SetPosPixel( aPnt ); +} + +// ----------------------------------------------------------------------- + +void BookmarksTabPage_Impl::ActivatePage() +{ + if ( !m_pIdxWin->WasCursorLeftOrRight() ) + SetFocusOnBox(); +} + +// ----------------------------------------------------------------------- + +Control* BookmarksTabPage_Impl::GetLastFocusControl() +{ + return &aBookmarksPB; +} + +// ----------------------------------------------------------------------- + +void BookmarksTabPage_Impl::SetDoubleClickHdl( const Link& rLink ) +{ + aBookmarksBox.SetDoubleClickHdl( rLink ); +} + +// ----------------------------------------------------------------------- + +String BookmarksTabPage_Impl::GetSelectEntry() const +{ + String aRet; + String* pData = (String*)(ULONG)aBookmarksBox.GetEntryData( aBookmarksBox.GetSelectEntryPos() ); + if ( pData ) + aRet = String( *pData ); + return aRet; +} + +// ----------------------------------------------------------------------- + +void BookmarksTabPage_Impl::AddBookmarks( const String& rTitle, const String& rURL ) +{ + rtl::OUString aImageURL = IMAGE_URL; + aImageURL += INetURLObject( rURL ).GetHost(); + USHORT nPos = aBookmarksBox.InsertEntry( rTitle, SvFileInformationManager::GetImage( aImageURL ) ); + aBookmarksBox.SetEntryData( nPos, (void*)(ULONG)( new String( rURL ) ) ); +} + +// class SfxHelpIndexWindow_Impl ----------------------------------------- + +sal_Bool SfxHelpWindow_Impl::splitHelpURL(const ::rtl::OUString& sHelpURL, + ::rtl::OUString& sFactory, + ::rtl::OUString& sContent, + ::rtl::OUString& sAnchor ) +{ + Reference < XURLTransformer > xParser( ::comphelper::getProcessServiceFactory()->createInstance( + DEFINE_CONST_UNICODE("com.sun.star.util.URLTransformer" )), UNO_QUERY_THROW ); + + URL aURL; + aURL.Complete = sHelpURL; + sal_Bool bResult = xParser->parseStrict(aURL); + + sFactory = aURL.Server; + sContent = aURL.Path.copy(1); // strip "/"! + sAnchor = aURL.Mark; + + return bResult; +} + +::rtl::OUString SfxHelpWindow_Impl::buildHelpURL(const ::rtl::OUString& sFactory , + const ::rtl::OUString& sContent , + const ::rtl::OUString& sAnchor , + sal_Bool bUseQuestionMark) +{ + ::rtl::OUStringBuffer sHelpURL(256); + sHelpURL.append(HELP_URL); + sHelpURL.append(sFactory); + sHelpURL.append(sContent); + String sURL = String(sHelpURL.makeStringAndClear()); + AppendConfigToken_Impl(sURL, bUseQuestionMark); + if (sAnchor.getLength()) + sURL += String(sAnchor); + return ::rtl::OUString(sURL); +} + +void SfxHelpWindow_Impl::loadHelpContent(const ::rtl::OUString& sHelpURL, sal_Bool bAddToHistory) +{ + Reference< XComponentLoader > xLoader(getTextFrame(), UNO_QUERY); + if (!xLoader.is()) + return; + + // --> PB 2007-03-12 #134037# + // If a print job runs do not open a new page + Reference< XFrame > xTextFrame = pTextWin->getFrame(); + Reference< XController > xTextController ; + if (xTextFrame.is()) + xTextController = xTextFrame->getController (); + if ( xTextController.is() && !xTextController->suspend( sal_True ) ) + { + xTextController->suspend( sal_False ); + return; + } + // <-- + + // save url to history + if (bAddToHistory) + pHelpInterceptor->addURL(sHelpURL); + + if ( !IsWait() ) + EnterWait(); + sal_Bool bSuccess = sal_False; +// TODO implement locale fallback ... see below while(sal_True) + { + try + { + Reference< XComponent > xContent = xLoader->loadComponentFromURL(sHelpURL, DEFINE_CONST_UNICODE("_self"), 0, Sequence< PropertyValue >()); + if (xContent.is()) + { + bSuccess = sal_True; +// break; + } + } + catch(const RuntimeException&) + { throw; } + catch(const Exception&) + { /*break;*/ } + + /* TODO try next locale ... + no further locale available? => break loop and show error page + */ + } + openDone(sHelpURL, bSuccess); + if ( IsWait() ) + LeaveWait(); +} + +SfxHelpIndexWindow_Impl::SfxHelpIndexWindow_Impl( SfxHelpWindow_Impl* _pParent ) : + + Window( _pParent, SfxResId( WIN_HELPINDEX ) ), + + aActiveLB ( this, SfxResId( LB_ACTIVE ) ), + aActiveLine ( this, SfxResId( FL_ACTIVE ) ), + aTabCtrl ( this, SfxResId( TC_INDEX ) ), + + aIndexKeywordLink ( LINK( this, SfxHelpIndexWindow_Impl, KeywordHdl ) ), + pParentWin ( _pParent ), + + pCPage ( NULL ), + pIPage ( NULL ), + pSPage ( NULL ), + pBPage ( NULL ), + + bWasCursorLeftOrRight( false ), + bIsInitDone ( false ) + +{ + FreeResource(); + + sfx2::AddToTaskPaneList( this ); + + aTabCtrl.SetActivatePageHdl( LINK( this, SfxHelpIndexWindow_Impl, ActivatePageHdl ) ); + aTabCtrl.Show(); + + sal_Int32 nPageId = HELP_INDEX_PAGE_INDEX; + SvtViewOptions aViewOpt( E_TABDIALOG, CONFIGNAME_INDEXWIN ); + if ( aViewOpt.Exists() ) + nPageId = aViewOpt.GetPageID(); + aTabCtrl.SetCurPageId( (USHORT)nPageId ); + ActivatePageHdl( &aTabCtrl ); + aActiveLB.SetSelectHdl( LINK( this, SfxHelpIndexWindow_Impl, SelectHdl ) ); + nMinWidth = ( aActiveLB.GetSizePixel().Width() / 2 ); + + aTimer.SetTimeoutHdl( LINK( this, SfxHelpIndexWindow_Impl, InitHdl ) ); + aTimer.SetTimeout( 200 ); + aTimer.Start(); +} + +// ----------------------------------------------------------------------- + +SfxHelpIndexWindow_Impl::~SfxHelpIndexWindow_Impl() +{ + sfx2::RemoveFromTaskPaneList( this ); + + DELETEZ( pCPage ); + DELETEZ( pIPage ); + DELETEZ( pSPage ); + DELETEZ( pBPage ); + + for ( USHORT i = 0; i < aActiveLB.GetEntryCount(); ++i ) + delete (String*)(ULONG)aActiveLB.GetEntryData(i); + + SvtViewOptions aViewOpt( E_TABDIALOG, CONFIGNAME_INDEXWIN ); + aViewOpt.SetPageID( (sal_Int32)aTabCtrl.GetCurPageId() ); +} + +// ----------------------------------------------------------------------- + +void SfxHelpIndexWindow_Impl::Initialize() +{ + String aHelpURL = HELP_URL; + AppendConfigToken_Impl( aHelpURL, sal_True ); + Sequence< ::rtl::OUString > aFactories = SfxContentHelper::GetResultSet( aHelpURL ); + const ::rtl::OUString* pFacs = aFactories.getConstArray(); + UINT32 i, nCount = aFactories.getLength(); + for ( i = 0; i < nCount; ++i ) + { + String aRow( pFacs[i] ); + String aTitle, aType, aURL; + xub_StrLen nIdx = 0; + aTitle = aRow.GetToken( 0, '\t', nIdx ); + aType = aRow.GetToken( 0, '\t', nIdx ); + aURL = aRow.GetToken( 0, '\t', nIdx ); + String* pFactory = new String( INetURLObject( aURL ).GetHost() ); + USHORT nPos = aActiveLB.InsertEntry( aTitle ); + aActiveLB.SetEntryData( nPos, (void*)(ULONG)pFactory ); + } + + aActiveLB.SetDropDownLineCount( (USHORT)nCount ); + if ( aActiveLB.GetSelectEntryPos() == LISTBOX_ENTRY_NOTFOUND ) + SetActiveFactory(); +} + +// ----------------------------------------------------------------------- + +void SfxHelpIndexWindow_Impl::SetActiveFactory() +{ + DBG_ASSERT( pIPage, "index page not initialized" ); + if ( !bIsInitDone && !aActiveLB.GetEntryCount() ) + { + aTimer.Stop(); + InitHdl( NULL ); + } + + for ( USHORT i = 0; i < aActiveLB.GetEntryCount(); ++i ) + { + String* pFactory = (String*)(ULONG)aActiveLB.GetEntryData(i); + pFactory->ToLowerAscii(); + if ( *pFactory == pIPage->GetFactory() ) + { + if ( aActiveLB.GetSelectEntryPos() != i ) + { + aActiveLB.SelectEntryPos(i); + aSelectFactoryLink.Call( NULL ); + } + break; + } + } +} + +// ----------------------------------------------------------------------- + +HelpTabPage_Impl* SfxHelpIndexWindow_Impl::GetCurrentPage( USHORT& rCurId ) +{ + rCurId = aTabCtrl.GetCurPageId(); + HelpTabPage_Impl* pPage = NULL; + + switch ( rCurId ) + { + case HELP_INDEX_PAGE_CONTENTS: + { + pPage = GetContentPage(); + break; + } + + case HELP_INDEX_PAGE_INDEX: + { + pPage = GetIndexPage(); + break; + } + + case HELP_INDEX_PAGE_SEARCH: + { + pPage = GetSearchPage(); + break; + } + + case HELP_INDEX_PAGE_BOOKMARKS: + { + pPage = GetBookmarksPage(); + break; + } + } + + DBG_ASSERT( pPage, "SfxHelpIndexWindow_Impl::GetCurrentPage(): no current page" ); + return pPage; +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( SfxHelpIndexWindow_Impl, ActivatePageHdl, TabControl *, pTabCtrl ) +{ + USHORT nId = 0; + TabPage* pPage = GetCurrentPage( nId ); + pTabCtrl->SetTabPage( nId, pPage ); + return 0; +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( SfxHelpIndexWindow_Impl, SelectHdl, ListBox *, EMPTYARG ) +{ + aTimer.Start(); + + return 0; +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( SfxHelpIndexWindow_Impl, InitHdl, Timer *, EMPTYARG ) +{ + bIsInitDone = true; + Initialize(); + + // now use the timer for selection + aTimer.SetTimeoutHdl( LINK( this, SfxHelpIndexWindow_Impl, SelectFactoryHdl ) ); + aTimer.SetTimeout( 1000 ); + + return 0; +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( SfxHelpIndexWindow_Impl, SelectFactoryHdl, Timer *, EMPTYARG ) +{ + String* pFactory = (String*)(ULONG)aActiveLB.GetEntryData( aActiveLB.GetSelectEntryPos() ); + if ( pFactory ) + { + String aFactory( *pFactory ); + aFactory.ToLowerAscii(); + SetFactory( aFactory, sal_False ); + aSelectFactoryLink.Call( this ); + } + + return 0; +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( SfxHelpIndexWindow_Impl, KeywordHdl, IndexTabPage_Impl *, EMPTYARG ) +{ + // keyword found on index? + sal_Bool bIndex = pIPage->HasKeyword(); + //The following two lines are added by BerryJia for fixing Bug98251, 2002-12-11 + if( !bIndex) + bIndex = pIPage->HasKeywordIgnoreCase(); + // then set index or search page as current. + USHORT nPageId = ( bIndex ) ? HELP_INDEX_PAGE_INDEX : HELP_INDEX_PAGE_SEARCH; + if ( nPageId != aTabCtrl.GetCurPageId() ) + { + aTabCtrl.SetCurPageId( nPageId ); + ActivatePageHdl( &aTabCtrl ); + } + + // at last we open the keyword + if ( bIndex ) + pIPage->OpenKeyword(); + else if ( !pSPage->OpenKeyword( sKeyword ) ) + pParentWin->ShowStartPage(); + + return 0; +} + +// ----------------------------------------------------------------------- + +void SfxHelpIndexWindow_Impl::Resize() +{ + Size aSize = GetOutputSizePixel(); + if ( aSize.Width() < nMinWidth ) + aSize.Width() = nMinWidth; + + Point aPnt = aActiveLB.GetPosPixel(); + Size aNewSize = aActiveLB.GetSizePixel(); + aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 ); + aActiveLB.SetSizePixel( aNewSize ); + aPnt = aActiveLine.GetPosPixel(); + aNewSize = aActiveLine.GetSizePixel(); + aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 ); + aActiveLine.SetSizePixel( aNewSize ); + aPnt = aTabCtrl.GetPosPixel(); + aNewSize = aSize; + aSize.Width() -= aPnt.X(); + aSize.Height() -= aPnt.Y(); + aTabCtrl.SetSizePixel( aSize ); +} + +// ----------------------------------------------------------------------- + +long SfxHelpIndexWindow_Impl::PreNotify( NotifyEvent& rNEvt ) +{ + long nDone = 0; + USHORT nType = rNEvt.GetType(); + if ( EVENT_KEYINPUT == nType && rNEvt.GetKeyEvent() ) + { + const KeyCode& rKeyCode = rNEvt.GetKeyEvent()->GetKeyCode(); + USHORT nCode = rKeyCode.GetCode(); + + if ( KEY_TAB == nCode ) + { + // don't exit index pane with <TAB> + USHORT nPageId = 0; + HelpTabPage_Impl* pCurPage = GetCurrentPage( nPageId ); + Control* pControl = pCurPage->GetLastFocusControl(); + BOOL bShift = rKeyCode.IsShift(); + BOOL bCtrl = rKeyCode.IsMod1(); + if ( !bCtrl && bShift && aActiveLB.HasChildPathFocus() ) + { + pControl->GrabFocus(); + nDone = 1; + } + else if ( !bCtrl && !bShift && pControl->HasChildPathFocus() ) + { + aActiveLB.GrabFocus(); + nDone = 1; + } + else if ( bCtrl ) + { + // <STRG><TAB> moves through the pages + if ( nPageId < HELP_INDEX_PAGE_LAST ) + nPageId++; + else + nPageId = HELP_INDEX_PAGE_FIRST; + aTabCtrl.SetCurPageId( (USHORT)nPageId ); + ActivatePageHdl( &aTabCtrl ); + nDone = 1; + } + } + else if ( aTabCtrl.HasFocus() && ( KEY_LEFT == nCode || KEY_RIGHT == nCode ) ) + { + bWasCursorLeftOrRight = true; + } + } + + return nDone ? nDone : Window::PreNotify( rNEvt ); +} + +// ----------------------------------------------------------------------- + +void SfxHelpIndexWindow_Impl::DataChanged( const DataChangedEvent& rDCEvt ) +{ + Window::DataChanged( rDCEvt ); + + if ( ( ( rDCEvt.GetType() == DATACHANGED_SETTINGS ) || + ( rDCEvt.GetType() == DATACHANGED_DISPLAY ) ) && + ( rDCEvt.GetFlags() & SETTINGS_STYLE ) ) + { + SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFaceColor() ) ); + } +} + +// ----------------------------------------------------------------------- + +void SfxHelpIndexWindow_Impl::SetDoubleClickHdl( const Link& rLink ) +{ + aPageDoubleClickLink = rLink; + if ( pCPage ) + pCPage->SetOpenHdl( aPageDoubleClickLink ); + if ( pIPage ) + pIPage->SetDoubleClickHdl( aPageDoubleClickLink ); + if ( pSPage ) + pSPage->SetDoubleClickHdl( aPageDoubleClickLink ); + if ( pBPage ) + pBPage->SetDoubleClickHdl( aPageDoubleClickLink ); +} + +// ----------------------------------------------------------------------- + +void SfxHelpIndexWindow_Impl::SetFactory( const String& rFactory, sal_Bool bActive ) +{ + if ( rFactory.Len() > 0 ) + { + GetIndexPage()->SetFactory( rFactory ); + // the index page did a check if rFactory is valid, + // so the index page always returns a valid factory + GetSearchPage()->SetFactory( GetIndexPage()->GetFactory() ); + if ( bActive ) + SetActiveFactory(); + } +} + +// ----------------------------------------------------------------------- + +String SfxHelpIndexWindow_Impl::GetSelectEntry() const +{ + String sRet; + + switch ( aTabCtrl.GetCurPageId() ) + { + case HELP_INDEX_PAGE_CONTENTS: + sRet = pCPage->GetSelectEntry(); + break; + + case HELP_INDEX_PAGE_INDEX: + sRet = pIPage->GetSelectEntry(); + break; + + case HELP_INDEX_PAGE_SEARCH: + sRet = pSPage->GetSelectEntry(); + break; + + case HELP_INDEX_PAGE_BOOKMARKS: + sRet = pBPage->GetSelectEntry(); + break; + } + + return sRet; +} + +// ----------------------------------------------------------------------- + +void SfxHelpIndexWindow_Impl::AddBookmarks( const String& rTitle, const String& rURL ) +{ + GetBookmarksPage()->AddBookmarks( rTitle, rURL ); +} + +// ----------------------------------------------------------------------- + +bool SfxHelpIndexWindow_Impl::IsValidFactory( const String& _rFactory ) +{ + bool bValid = false; + for ( USHORT i = 0; i < aActiveLB.GetEntryCount(); ++i ) + { + String* pFactory = (String*)(ULONG)aActiveLB.GetEntryData(i); + if ( *pFactory == _rFactory ) + { + bValid = true; + break; + } + } + return bValid; +} + +// ----------------------------------------------------------------------- + +void SfxHelpIndexWindow_Impl::ClearSearchPage() +{ + if ( pSPage ) + pSPage->ClearPage(); +} + +// ----------------------------------------------------------------------- + +void SfxHelpIndexWindow_Impl::GrabFocusBack() +{ + if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_CONTENTS && pCPage ) + pCPage->SetFocusOnBox(); + else if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_INDEX && pIPage ) + pIPage->SetFocusOnBox(); + else if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_SEARCH && pSPage ) + pSPage->SetFocusOnBox(); + else if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_BOOKMARKS && pBPage ) + pBPage->SetFocusOnBox(); +} + +// ----------------------------------------------------------------------- + +sal_Bool SfxHelpIndexWindow_Impl::HasFocusOnEdit() const +{ + sal_Bool bRet = sal_False; + if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_INDEX && pIPage ) + bRet = pIPage->HasFocusOnEdit(); + else if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_SEARCH && pSPage ) + bRet = pSPage->HasFocusOnEdit(); + return bRet; +} + +// ----------------------------------------------------------------------- + +String SfxHelpIndexWindow_Impl::GetSearchText() const +{ + String sRet; + if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_SEARCH && pSPage ) + sRet = pSPage->GetSearchText(); + return sRet; +} + +// ----------------------------------------------------------------------- + +sal_Bool SfxHelpIndexWindow_Impl::IsFullWordSearch() const +{ + sal_Bool bRet = sal_False; + if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_SEARCH && pSPage ) + bRet = pSPage->IsFullWordSearch(); + return bRet; +} + +// ----------------------------------------------------------------------- + +void SfxHelpIndexWindow_Impl::OpenKeyword( const String& rKeyword ) +{ + sKeyword = rKeyword; + DBG_ASSERT( pIPage, "invalid index page" ); + pIPage->SetKeyword( sKeyword ); +} + +// ----------------------------------------------------------------------- + +void SfxHelpIndexWindow_Impl::SelectExecutableEntry() +{ + if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_INDEX && pIPage ) + pIPage->SelectExecutableEntry(); +} + +// class TextWin_Impl ---------------------------------------------------- + +TextWin_Impl::TextWin_Impl( Window* p ) : DockingWindow( p, 0 ) +{ +} + +TextWin_Impl::~TextWin_Impl() +{ +} + +long TextWin_Impl::Notify( NotifyEvent& rNEvt ) +{ + if( ( rNEvt.GetType() == EVENT_KEYINPUT ) && rNEvt.GetKeyEvent()->GetKeyCode().GetCode() == KEY_TAB ) + return GetParent()->Notify( rNEvt ); + else + return DockingWindow::Notify( rNEvt ); +} + +// ----------------------------------------------------------------------- +// remove docking area acceptor from layoutmanager, so it will not layout anything further .-) +void lcl_disableLayoutOfFrame(const Reference< XFrame >& xFrame) +{ + static const ::rtl::OUString PROP_LAYOUT_MANAGER(DEFINE_CONST_UNICODE("LayoutManager")); + + Reference< XPropertySet > xPropSet(xFrame, UNO_QUERY_THROW); + xPropSet->setPropertyValue(PROP_LAYOUT_MANAGER, makeAny(Reference< XLayoutManager >())); +} + +// class SfxHelpTextWindow_Impl ------------------------------------------ + +SfxHelpTextWindow_Impl::SfxHelpTextWindow_Impl( SfxHelpWindow_Impl* pParent ) : + + Window( pParent, WB_CLIPCHILDREN | WB_TABSTOP | WB_DIALOGCONTROL ), + + aToolBox ( this, 0 ), + aOnStartupCB ( this, SfxResId( RID_HELP_ONSTARTUP_BOX ) ), + aIndexOnImage ( SfxResId( IMG_HELP_TOOLBOX_INDEX_ON ) ), + aIndexOffImage ( SfxResId( IMG_HELP_TOOLBOX_INDEX_OFF ) ), + aIndexOnText ( SfxResId( STR_HELP_BUTTON_INDEX_ON ) ), + aIndexOffText ( SfxResId( STR_HELP_BUTTON_INDEX_OFF ) ), + aOnStartupText ( SfxResId( RID_HELP_ONSTARTUP_TEXT ) ), + pHelpWin ( pParent ), + pTextWin ( new TextWin_Impl( this ) ), + pSrchDlg ( NULL ), + nMinPos ( 0 ), + bIsDebug ( sal_False ), + bIsIndexOn ( sal_False ), + bIsInClose ( sal_False ), + bIsFullWordSearch ( sal_False ) + +{ + sfx2::AddToTaskPaneList( &aToolBox ); + + xFrame = Reference < XFrame > ( ::comphelper::getProcessServiceFactory()->createInstance( + DEFINE_CONST_UNICODE("com.sun.star.frame.Frame") ), UNO_QUERY ); + xFrame->initialize( VCLUnoHelper::GetInterface ( pTextWin ) ); + xFrame->setName( DEFINE_CONST_UNICODE("OFFICE_HELP") ); + lcl_disableLayoutOfFrame(xFrame); + + aToolBox.SetHelpId( HID_HELP_TOOLBOX ); + + aToolBox.InsertItem( TBI_INDEX, aIndexOffText ); + aToolBox.SetHelpId( TBI_INDEX, HID_HELP_TOOLBOXITEM_INDEX ); + aToolBox.InsertSeparator(); + aToolBox.InsertItem( TBI_BACKWARD, String( SfxResId( STR_HELP_BUTTON_PREV ) ) ); + aToolBox.SetHelpId( TBI_BACKWARD, HID_HELP_TOOLBOXITEM_BACKWARD ); + aToolBox.InsertItem( TBI_FORWARD, String( SfxResId( STR_HELP_BUTTON_NEXT ) ) ); + aToolBox.SetHelpId( TBI_FORWARD, HID_HELP_TOOLBOXITEM_FORWARD ); + aToolBox.InsertItem( TBI_START, String( SfxResId( STR_HELP_BUTTON_START ) ) ); + aToolBox.SetHelpId( TBI_START, HID_HELP_TOOLBOXITEM_START ); + aToolBox.InsertSeparator(); + aToolBox.InsertItem( TBI_PRINT, String( SfxResId( STR_HELP_BUTTON_PRINT ) ) ); + aToolBox.SetHelpId( TBI_PRINT, HID_HELP_TOOLBOXITEM_PRINT ); + aToolBox.InsertItem( TBI_BOOKMARKS, String( SfxResId( STR_HELP_BUTTON_ADDBOOKMARK ) ) ); + aToolBox.SetHelpId( TBI_BOOKMARKS, HID_HELP_TOOLBOXITEM_BOOKMARKS ); + aToolBox.InsertItem( TBI_SEARCHDIALOG, String( SfxResId( STR_HELP_BUTTON_SEARCHDIALOG ) ) ); + aToolBox.SetHelpId( TBI_SEARCHDIALOG, HID_HELP_TOOLBOXITEM_SEARCHDIALOG ); + + InitToolBoxImages(); + aToolBox.Show(); + InitOnStartupBox( false ); + aOnStartupCB.SetClickHdl( LINK( this, SfxHelpTextWindow_Impl, CheckHdl ) ); + + aSelectTimer.SetTimeoutHdl( LINK( this, SfxHelpTextWindow_Impl, SelectHdl ) ); + aSelectTimer.SetTimeout( 1000 ); + + char* pEnv = getenv( "help_debug" ); + if ( pEnv ) + bIsDebug = sal_True; + + SvtMiscOptions().AddListenerLink( LINK( this, SfxHelpTextWindow_Impl, NotifyHdl ) ); + + if ( aOnStartupCB.GetHelpId() == 0 ) + aOnStartupCB.SetHelpId( HID_HELP_ONSTARTUP_BOX ); +} + +// ----------------------------------------------------------------------- + +SfxHelpTextWindow_Impl::~SfxHelpTextWindow_Impl() +{ + sfx2::RemoveFromTaskPaneList( &aToolBox ); + + bIsInClose = sal_True; + SvtMiscOptions().RemoveListenerLink( LINK( this, SfxHelpTextWindow_Impl, NotifyHdl ) ); + delete pSrchDlg; +} + +// ----------------------------------------------------------------------- + +sal_Bool SfxHelpTextWindow_Impl::HasSelection() const +{ + // is there any selection in the text and not only a cursor? + sal_Bool bRet = sal_False; + Reference < XTextRange > xRange = getCursor(); + if ( xRange.is() ) + { + Reference < XText > xText = xRange->getText(); + Reference < XTextCursor > xCursor = xText->createTextCursorByRange( xRange ); + bRet = !xCursor->isCollapsed(); + } + + return bRet; +} + +// ----------------------------------------------------------------------- + +void SfxHelpTextWindow_Impl::InitToolBoxImages() +{ + sal_Bool bLarge = SvtMiscOptions().AreCurrentSymbolsLarge(); + sal_Bool bHiContrast = GetSettings().GetStyleSettings().GetHighContrastMode(); + + aIndexOnImage = Image( SfxResId( + bLarge ? bHiContrast ? IMG_HELP_TOOLBOX_HCL_INDEX_ON : IMG_HELP_TOOLBOX_L_INDEX_ON + : bHiContrast ? IMG_HELP_TOOLBOX_HC_INDEX_ON : IMG_HELP_TOOLBOX_INDEX_ON ) ); + aIndexOffImage = Image( SfxResId( + bLarge ? bHiContrast ? IMG_HELP_TOOLBOX_HCL_INDEX_OFF : IMG_HELP_TOOLBOX_L_INDEX_OFF + : bHiContrast ? IMG_HELP_TOOLBOX_HC_INDEX_OFF : IMG_HELP_TOOLBOX_INDEX_OFF ) ); + aToolBox.SetItemImage( TBI_INDEX, bIsIndexOn ? aIndexOffImage : aIndexOnImage ); + + aToolBox.SetItemImage( TBI_BACKWARD, Image( SfxResId( + bLarge ? bHiContrast ? IMG_HELP_TOOLBOX_HCL_PREV : IMG_HELP_TOOLBOX_L_PREV + : bHiContrast ? IMG_HELP_TOOLBOX_HC_PREV : IMG_HELP_TOOLBOX_PREV ) ) ); + aToolBox.SetItemImage( TBI_FORWARD, Image( SfxResId( + bLarge ? bHiContrast ? IMG_HELP_TOOLBOX_HCL_NEXT : IMG_HELP_TOOLBOX_L_NEXT + : bHiContrast ? IMG_HELP_TOOLBOX_HC_NEXT : IMG_HELP_TOOLBOX_NEXT ) ) ); + aToolBox.SetItemImage( TBI_START, Image( SfxResId( + bLarge ? bHiContrast ? IMG_HELP_TOOLBOX_HCL_START : IMG_HELP_TOOLBOX_L_START + : bHiContrast ? IMG_HELP_TOOLBOX_HC_START : IMG_HELP_TOOLBOX_START ) ) ); + aToolBox.SetItemImage( TBI_PRINT, Image( SfxResId( + bLarge ? bHiContrast ? IMG_HELP_TOOLBOX_HCL_PRINT : IMG_HELP_TOOLBOX_L_PRINT + : bHiContrast ? IMG_HELP_TOOLBOX_HC_PRINT : IMG_HELP_TOOLBOX_PRINT ) ) ); + aToolBox.SetItemImage( TBI_BOOKMARKS, Image( SfxResId( + bLarge ? bHiContrast ? IMG_HELP_TOOLBOX_HCL_BOOKMARKS : IMG_HELP_TOOLBOX_L_BOOKMARKS + : bHiContrast ? IMG_HELP_TOOLBOX_HC_BOOKMARKS : IMG_HELP_TOOLBOX_BOOKMARKS ) ) ); + aToolBox.SetItemImage( TBI_SEARCHDIALOG, Image( SfxResId( + bLarge ? bHiContrast ? IMG_HELP_TOOLBOX_HCL_SEARCHDIALOG : IMG_HELP_TOOLBOX_L_SEARCHDIALOG + : bHiContrast ? IMG_HELP_TOOLBOX_HC_SEARCHDIALOG : IMG_HELP_TOOLBOX_SEARCHDIALOG ) ) ); + + Size aSize = aToolBox.CalcWindowSizePixel(); + aSize.Height() += TOOLBOX_OFFSET; + aToolBox.SetPosSizePixel( Point( 0, TOOLBOX_OFFSET ), aSize ); + + SvtMiscOptions aMiscOptions; + if ( aMiscOptions.GetToolboxStyle() != aToolBox.GetOutStyle() ) + aToolBox.SetOutStyle( aMiscOptions.GetToolboxStyle() ); +} + +// ----------------------------------------------------------------------- + +void SfxHelpTextWindow_Impl::InitOnStartupBox( bool bOnlyText ) +{ + sCurrentFactory = SfxHelp::GetCurrentModuleIdentifier(); + + Reference< XMultiServiceFactory > xMultiServiceFac = ::comphelper::getProcessServiceFactory(); + Reference< XInterface > xConfig; + ::rtl::OUString sPath( PATH_OFFICE_FACTORIES ); + sPath += sCurrentFactory; + ::rtl::OUString sKey( KEY_HELP_ON_OPEN ); + + // Attention: This check boy knows two states: + // 1) Reading of the config key fails with an exception or by getting an empty Any (!) => check box must be hidden + // 2) We read TRUE/FALSE => check box must be shown and enabled/disabled + + bool bHideBox = true; + sal_Bool bHelpAtStartup = sal_False; + try + { + xConfiguration = ConfigurationHelper::openConfig( + xMultiServiceFac, PACKAGE_SETUP, ConfigurationHelper::E_STANDARD ); + if ( xConfiguration.is() ) + { + Any aAny = ConfigurationHelper::readRelativeKey( xConfiguration, sPath, sKey ); + if (aAny >>= bHelpAtStartup) + bHideBox = false; + } + } + catch( Exception& ) + { + bHideBox = true; + } + + if ( bHideBox ) + aOnStartupCB.Hide(); + else + { + // detect module name + String sModuleName; + + if ( xConfiguration.is() ) + { + ::rtl::OUString sTemp; + sKey = KEY_UI_NAME; + try + { + Any aAny = ConfigurationHelper::readRelativeKey( xConfiguration, sPath, sKey ); + aAny >>= sTemp; + } + catch( Exception& ) + { + DBG_ERRORFILE( "SfxHelpTextWindow_Impl::InitOnStartupBox(): unexpected exception" ); + } + sModuleName = String( sTemp ); + } + + if ( sModuleName.Len() > 0 ) + { + // set module name in checkbox text + String sText( aOnStartupText ); + sText.SearchAndReplace( String::CreateFromAscii( "%MODULENAME" ), sModuleName ); + aOnStartupCB.SetText( sText ); + // and show it + aOnStartupCB.Show(); + // set check state + aOnStartupCB.Check( bHelpAtStartup ); + aOnStartupCB.SaveValue(); + + // calculate and set optimal width of the onstartup checkbox + String sCBText( DEFINE_CONST_UNICODE( "XXX" ) ); + sCBText += aOnStartupCB.GetText(); + long nTextWidth = aOnStartupCB.GetTextWidth( sCBText ); + Size aSize = aOnStartupCB.GetSizePixel(); + aSize.Width() = nTextWidth; + aOnStartupCB.SetSizePixel( aSize ); + SetOnStartupBoxPosition(); + } + + if ( !bOnlyText ) + { + // set position of the checkbox + Size a3Size = LogicToPixel( Size( 3, 3 ), MAP_APPFONT ); + Size aTBSize = aToolBox.GetSizePixel(); + Size aCBSize = aOnStartupCB.GetSizePixel(); + Point aPnt = aToolBox.GetPosPixel(); + aPnt.X() += aTBSize.Width() + a3Size.Width(); + aPnt.Y() += ( ( aTBSize.Height() - aCBSize.Height() ) / 2 ); + aOnStartupCB.SetPosPixel( aPnt ); + nMinPos = aPnt.X(); + } + } +} + +// ----------------------------------------------------------------------- + +void SfxHelpTextWindow_Impl::SetOnStartupBoxPosition() +{ + long nX = Max( GetOutputSizePixel().Width() - aOnStartupCB.GetSizePixel().Width(), nMinPos ); + Point aPos = aOnStartupCB.GetPosPixel(); + aPos.X() = nX; + aOnStartupCB.SetPosPixel( aPos ); +} + +// ----------------------------------------------------------------------- + +Reference< XBreakIterator > SfxHelpTextWindow_Impl::GetBreakIterator() +{ + if ( !xBreakIterator.is() ) + xBreakIterator = vcl::unohelper::CreateBreakIterator(); + DBG_ASSERT( xBreakIterator.is(), "Could not create BreakIterator" ); + return xBreakIterator; +} + +// ----------------------------------------------------------------------- + +Reference< XTextRange > SfxHelpTextWindow_Impl::getCursor() const +{ + // return the current cursor + Reference< XTextRange > xCursor; + + try + { + Reference < XSelectionSupplier > xSelSup( xFrame->getController(), UNO_QUERY ); + if ( xSelSup.is() ) + { + Any aAny = xSelSup->getSelection(); + Reference < XIndexAccess > xSelection; + if ( aAny >>= xSelection ) + { + if ( xSelection->getCount() == 1 ) + { + aAny = xSelection->getByIndex(0); + aAny >>= xCursor; + } + } + } + } + catch( Exception& ) + { + DBG_ERROR( "SfxHelpTextWindow_Impl::getCursor(): unexpected exception" ); + } + + return xCursor; +} + +// ----------------------------------------------------------------------- + +bool SfxHelpTextWindow_Impl::isHandledKey( const KeyCode& _rKeyCode ) +{ + bool bRet = false; + USHORT nCode = _rKeyCode.GetCode(); + + // the keys <STRG><A> (select all), <STRG><C> (copy), + // <STRG><F> (find), <STRG><P> (print) and <STRG><W> (close window) + // were handled in help + if ( _rKeyCode.IsMod1() && + ( KEY_A == nCode || KEY_C == nCode || KEY_F == nCode || KEY_P == nCode || KEY_W == nCode ) ) + { + if ( KEY_F == nCode ) + DoSearch(); + else + bRet = true; + } + + return bRet; +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( SfxHelpTextWindow_Impl, SelectHdl, Timer*, EMPTYARG ) +{ + try + { + // select the words, which are equal to the search text of the search page + Reference < XController > xController = xFrame->getController(); + if ( xController.is() ) + { + // get document + Reference < XSearchable > xSearchable( xController->getModel(), UNO_QUERY ); + if ( xSearchable.is() ) + { + // create descriptor, set string and find all words + Reference < XSearchDescriptor > xSrchDesc = xSearchable->createSearchDescriptor(); + Reference < XPropertySet > xPropSet( xSrchDesc, UNO_QUERY ); + xPropSet->setPropertyValue( DEFINE_CONST_OUSTRING("SearchRegularExpression"), + makeAny( sal_Bool( sal_True ) ) ); + if ( bIsFullWordSearch ) + xPropSet->setPropertyValue( DEFINE_CONST_OUSTRING("SearchWords"), + makeAny( sal_Bool( sal_True ) ) ); + + String sSearchString = sfx2::PrepareSearchString( aSearchText, GetBreakIterator(), false ); + xSrchDesc->setSearchString( sSearchString ); + Reference< XIndexAccess > xSelection = xSearchable->findAll( xSrchDesc ); + + // then select all found words + Reference < XSelectionSupplier > xSelectionSup( xController, UNO_QUERY ); + if ( xSelectionSup.is() ) + { + Any aAny; + aAny <<= xSelection; + xSelectionSup->select( aAny ); + } + } + } + } + catch( Exception& ) + { + DBG_ERROR( "SfxHelpTextWindow_Impl::SelectHdl(): unexpected exception" ); + } + + return 1; +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( SfxHelpTextWindow_Impl, NotifyHdl, SvtMiscOptions*, pOptions ) +{ + (void)pOptions; // unused variable + InitToolBoxImages(); + Resize(); + aToolBox.Invalidate(); + return 0; +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( SfxHelpTextWindow_Impl, FindHdl, sfx2::SearchDialog*, pDlg ) +{ + bool bWrapAround = ( NULL == pDlg ); + if ( bWrapAround ) + pDlg = pSrchDlg; + DBG_ASSERT( pDlg, "invalid search dialog" ); + String sSearchText = pDlg->GetSearchText(); + try + { + // select the words, which are equal to the search text of the search page + Reference < XController > xController = xFrame->getController(); + if ( xController.is() ) + { + // get document + Reference < XSearchable > xSearchable( xController->getModel(), UNO_QUERY ); + if ( xSearchable.is() ) + { + // create descriptor, set string and find all words + Reference < XSearchDescriptor > xSrchDesc = xSearchable->createSearchDescriptor(); + Reference < XPropertySet > xPropSet( xSrchDesc, UNO_QUERY ); + xPropSet->setPropertyValue( DEFINE_CONST_OUSTRING("SearchWords"), makeAny( sal_Bool( pDlg->IsOnlyWholeWords() != false ) ) ); + xPropSet->setPropertyValue( DEFINE_CONST_OUSTRING("SearchCaseSensitive"), makeAny( sal_Bool( pDlg->IsMarchCase() != false ) ) ); + xPropSet->setPropertyValue( DEFINE_CONST_OUSTRING("SearchBackwards"), makeAny( sal_Bool( pDlg->IsSearchBackwards() != false ) ) ); + xSrchDesc->setSearchString( sSearchText ); + Reference< XInterface > xSelection; + Reference< XTextRange > xCursor = getCursor(); + + if ( xCursor.is() ) + { + if ( pDlg->IsSearchBackwards() ) + xCursor = xCursor->getStart(); + xSelection = xSearchable->findNext( xCursor, xSrchDesc ); + } + else + xSelection = xSearchable->findFirst( xSrchDesc ); + + // then select the found word + if ( xSelection.is() ) + { + Reference < XSelectionSupplier > xSelectionSup( xController, UNO_QUERY ); + if ( xSelectionSup.is() ) + { + Any aAny; + aAny <<= xSelection; + xSelectionSup->select( aAny ); + } + } + else if ( pDlg->IsWrapAround() && !bWrapAround ) + { + Reference < text::XTextViewCursorSupplier > xCrsrSupp( xController, uno::UNO_QUERY ); + Reference < text::XTextViewCursor > xTVCrsr( xCrsrSupp->getViewCursor(), uno::UNO_QUERY ); + if ( xTVCrsr.is() ) + { + Reference < text::XTextDocument > xDoc( xController->getModel(), uno::UNO_QUERY ); + Reference < text::XText > xText = xDoc->getText(); + if ( xText.is() ) + { + if ( pDlg->IsSearchBackwards() ) + xTVCrsr->gotoRange( xText->getEnd(), sal_False ); + else + xTVCrsr->gotoRange( xText->getStart(), sal_False ); + FindHdl( NULL ); + } + } + } + else + { + DBG_ASSERT( pSrchDlg, "no search dialog" ); + InfoBox aBox( pSrchDlg, SfxResId( RID_INFO_NOSEARCHTEXTFOUND ) ); + aBox.Execute(); + pSrchDlg->SetFocusOnEdit(); + } + } + } + } + catch( Exception& ) + { + DBG_ERROR( "SfxHelpTextWindow_Impl::SelectHdl(): unexpected exception" ); + } + + return 0; +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( SfxHelpTextWindow_Impl, CloseHdl, sfx2::SearchDialog*, pDlg ) +{ + if ( pDlg ) + delete pSrchDlg; + pSrchDlg = NULL; + return 0; +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( SfxHelpTextWindow_Impl, CheckHdl, CheckBox*, pBox ) +{ + if ( xConfiguration.is() ) + { + sal_Bool bChecked = pBox->IsChecked(); + ::rtl::OUString sPath( PATH_OFFICE_FACTORIES ); + sPath += sCurrentFactory; + try + { + ConfigurationHelper::writeRelativeKey( + xConfiguration, sPath, KEY_HELP_ON_OPEN, makeAny( bChecked ) ); + ConfigurationHelper::flush( xConfiguration ); + } + catch( Exception& ) + { + DBG_ERRORFILE( "SfxHelpTextWindow_Impl::CheckHdl(): unexpected exception" ); + } + } + + return 0; +} + +// ----------------------------------------------------------------------- + +void SfxHelpTextWindow_Impl::Resize() +{ + Size aSize = GetOutputSizePixel(); + long nToolBoxHeight = aToolBox.GetSizePixel().Height() + TOOLBOX_OFFSET; + aSize.Height() -= nToolBoxHeight; + pTextWin->SetPosSizePixel( Point( 0, nToolBoxHeight ), aSize ); + SetOnStartupBoxPosition(); +} + +// ----------------------------------------------------------------------- + +long SfxHelpTextWindow_Impl::PreNotify( NotifyEvent& rNEvt ) +{ + long nDone = 0; + USHORT nType = rNEvt.GetType(); + if ( EVENT_COMMAND == nType && rNEvt.GetCommandEvent() ) + { + const CommandEvent* pCmdEvt = rNEvt.GetCommandEvent(); + Window* pCmdWin = rNEvt.GetWindow(); + + if ( pCmdEvt->GetCommand() == COMMAND_CONTEXTMENU && pCmdWin != this && pCmdWin != &aToolBox ) + { + sal_Bool bHiContrast = GetSettings().GetStyleSettings().GetHighContrastMode(); + Point aPos; + if ( pCmdEvt->IsMouseEvent() ) + aPos = pCmdEvt->GetMousePosPixel(); + else + aPos = Point( pTextWin->GetPosPixel().X() + 20, 20 ); + aPos.Y() += pTextWin->GetPosPixel().Y(); + PopupMenu aMenu; + if ( bIsIndexOn ) + aMenu.InsertItem( TBI_INDEX, aIndexOffText, Image( SfxResId( + bHiContrast ? IMG_HELP_TOOLBOX_HC_INDEX_OFF : IMG_HELP_TOOLBOX_INDEX_OFF ) ) ); + else + aMenu.InsertItem( TBI_INDEX, aIndexOnText, Image( SfxResId( + bHiContrast ? IMG_HELP_TOOLBOX_HC_INDEX_ON : IMG_HELP_TOOLBOX_INDEX_ON ) ) ); + aMenu.SetHelpId( TBI_INDEX, HID_HELP_TOOLBOXITEM_INDEX ); + aMenu.InsertSeparator(); + aMenu.InsertItem( TBI_BACKWARD, String( SfxResId( STR_HELP_BUTTON_PREV ) ), + Image( SfxResId( bHiContrast ? IMG_HELP_TOOLBOX_HC_PREV : IMG_HELP_TOOLBOX_PREV ) ) ); + aMenu.SetHelpId( TBI_BACKWARD, HID_HELP_TOOLBOXITEM_BACKWARD ); + aMenu.EnableItem( TBI_BACKWARD, pHelpWin->HasHistoryPredecessor() ); + aMenu.InsertItem( TBI_FORWARD, String( SfxResId( STR_HELP_BUTTON_NEXT ) ), + Image( SfxResId( bHiContrast ? IMG_HELP_TOOLBOX_HC_NEXT : IMG_HELP_TOOLBOX_NEXT ) ) ); + aMenu.SetHelpId( TBI_FORWARD, HID_HELP_TOOLBOXITEM_FORWARD ); + aMenu.EnableItem( TBI_FORWARD, pHelpWin->HasHistorySuccessor() ); + aMenu.InsertItem( TBI_START, String( SfxResId( STR_HELP_BUTTON_START ) ), + Image( SfxResId( bHiContrast ? IMG_HELP_TOOLBOX_HC_START : IMG_HELP_TOOLBOX_START ) ) ); + aMenu.SetHelpId( TBI_START, HID_HELP_TOOLBOXITEM_START ); + aMenu.InsertSeparator(); + aMenu.InsertItem( TBI_PRINT, String( SfxResId( STR_HELP_BUTTON_PRINT ) ), + Image( SfxResId( bHiContrast ? IMG_HELP_TOOLBOX_HC_PRINT : IMG_HELP_TOOLBOX_PRINT ) ) ); + aMenu.SetHelpId( TBI_PRINT, HID_HELP_TOOLBOXITEM_PRINT ); + aMenu.InsertItem( TBI_BOOKMARKS, String( SfxResId( STR_HELP_BUTTON_ADDBOOKMARK ) ), + Image( SfxResId( bHiContrast ? IMG_HELP_TOOLBOX_HC_BOOKMARKS : IMG_HELP_TOOLBOX_BOOKMARKS ) ) ); + aMenu.SetHelpId( TBI_BOOKMARKS, HID_HELP_TOOLBOXITEM_BOOKMARKS ); + aMenu.InsertItem( TBI_SEARCHDIALOG, String( SfxResId( STR_HELP_BUTTON_SEARCHDIALOG ) ), + Image( SfxResId( bHiContrast ? IMG_HELP_TOOLBOX_HC_SEARCHDIALOG : IMG_HELP_TOOLBOX_SEARCHDIALOG ) ) ); + aMenu.SetHelpId( TBI_SEARCHDIALOG, HID_HELP_TOOLBOXITEM_SEARCHDIALOG ); + aMenu.InsertSeparator(); + aMenu.InsertItem( TBI_SELECTIONMODE, String( SfxResId( STR_HELP_MENU_TEXT_SELECTION_MODE ) ) ); + aMenu.SetHelpId( TBI_SELECTIONMODE, HID_HELP_TEXT_SELECTION_MODE ); + Reference < XDispatchProvider > xProv( xFrame, UNO_QUERY ); + URL aURL; + aURL.Complete = DEFINE_CONST_UNICODE(".uno:SelectTextMode"); + PARSE_URL( aURL ); + Reference < XDispatch > xDisp = xProv.is() ? + xProv->queryDispatch( aURL, rtl::OUString(), 0 ) : Reference < XDispatch >(); + if(xDisp.is()) + { + HelpStatusListener_Impl* pStateListener; + Reference<XStatusListener>xStateListener = pStateListener = + new HelpStatusListener_Impl(xDisp, aURL ); + FeatureStateEvent rEvent = pStateListener->GetStateEvent(); + sal_Bool bCheck = sal_False; + rEvent.State >>= bCheck; + aMenu.CheckItem(TBI_SELECTIONMODE, bCheck); + } + aMenu.InsertSeparator(); + aMenu.InsertItem( TBI_COPY, String( SfxResId( STR_HELP_MENU_TEXT_COPY ) ), + Image( SfxResId( bHiContrast ? IMG_HELP_TOOLBOX_HC_COPY : IMG_HELP_TOOLBOX_COPY ) ) ); + aMenu.SetHelpId( TBI_COPY, SID_COPY ); + aMenu.EnableItem( TBI_COPY, HasSelection() ); + + if ( bIsDebug ) + { + aMenu.InsertSeparator(); + aMenu.InsertItem( TBI_SOURCEVIEW, String( SfxResId( STR_HELP_BUTTON_SOURCEVIEW ) ) ); + } + + if( SvtMenuOptions().IsEntryHidingEnabled() == sal_False ) + aMenu.SetMenuFlags( aMenu.GetMenuFlags() | MENU_FLAG_HIDEDISABLEDENTRIES ); + + USHORT nId = aMenu.Execute( this, aPos ); + pHelpWin->DoAction( nId ); + nDone = 1; + } + } + else if ( EVENT_KEYINPUT == nType && rNEvt.GetKeyEvent() ) + { + const KeyEvent* pKEvt = rNEvt.GetKeyEvent(); + const KeyCode& rKeyCode = pKEvt->GetKeyCode(); + USHORT nKeyGroup = rKeyCode.GetGroup(); + USHORT nKey = rKeyCode.GetCode(); + if ( KEYGROUP_ALPHA == nKeyGroup && !isHandledKey( rKeyCode ) ) + { + // do nothing disables the writer accelerators + nDone = 1; + } + else if ( rKeyCode.IsMod1() && ( KEY_F4 == nKey || KEY_W == nKey ) ) + { + // <STRG><F4> or <STRG><W> -> close top frame + pHelpWin->CloseWindow(); + nDone = 1; + } + else if ( KEY_TAB == nKey && aOnStartupCB.HasChildPathFocus() ) + { + aToolBox.GrabFocus(); + nDone = 1; + } + } + + return nDone ? nDone : Window::PreNotify( rNEvt ); +} + +// ----------------------------------------------------------------------- + +void SfxHelpTextWindow_Impl::GetFocus() +{ + if ( !bIsInClose ) + { + try + { + if( xFrame.is() ) + { + Reference< ::com::sun::star::awt::XWindow > xWindow = xFrame->getComponentWindow(); + if( xWindow.is() ) + xWindow->setFocus(); + } + } + catch( Exception& ) + { + DBG_ERRORFILE( "SfxHelpTextWindow_Impl::GetFocus(): unexpected exception" ); + } + } +} + +// ----------------------------------------------------------------------- + +void SfxHelpTextWindow_Impl::DataChanged( const DataChangedEvent& rDCEvt ) +{ + Window::DataChanged( rDCEvt ); + + if ( ( ( rDCEvt.GetType() == DATACHANGED_SETTINGS ) || + ( rDCEvt.GetType() == DATACHANGED_DISPLAY ) ) && + ( rDCEvt.GetFlags() & SETTINGS_STYLE ) ) + { + SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFaceColor() ) ); + InitToolBoxImages(); + } +} + +// ----------------------------------------------------------------------- + +void SfxHelpTextWindow_Impl::ToggleIndex( sal_Bool bOn ) +{ + bIsIndexOn = bOn; + if ( bIsIndexOn ) + { + aToolBox.SetItemImage( TBI_INDEX, aIndexOffImage ); + aToolBox.SetItemText( TBI_INDEX, aIndexOffText ); + } + else + { + aToolBox.SetItemImage( TBI_INDEX, aIndexOnImage ); + aToolBox.SetItemText( TBI_INDEX, aIndexOnText ); + } +} + +// ----------------------------------------------------------------------- + +void SfxHelpTextWindow_Impl::SelectSearchText( const String& rSearchText, sal_Bool _bIsFullWordSearch ) +{ + aSearchText = rSearchText; + bIsFullWordSearch = _bIsFullWordSearch; + aSelectTimer.Start(); +} + +// ----------------------------------------------------------------------- + +void SfxHelpTextWindow_Impl::SetPageStyleHeaderOff() const +{ +#ifdef DBG_UTIL + sal_Bool bSetOff = sal_False; +#endif + // set off the pagestyle header to prevent print output of the help URL + try + { + Reference < XController > xController = xFrame->getController(); + Reference < XSelectionSupplier > xSelSup( xController, UNO_QUERY ); + if ( xSelSup.is() ) + { + Reference < XIndexAccess > xSelection; + if ( xSelSup->getSelection() >>= xSelection ) + { + Reference < XTextRange > xRange; + if ( xSelection->getByIndex(0) >>= xRange ) + { + Reference < XText > xText = xRange->getText(); + Reference < XPropertySet > xProps( xText->createTextCursorByRange( xRange ), UNO_QUERY ); + ::rtl::OUString sStyleName; + if ( xProps->getPropertyValue( DEFINE_CONST_OUSTRING("PageStyleName") ) >>= sStyleName ) + { + Reference < XStyleFamiliesSupplier > xStyles( xController->getModel(), UNO_QUERY ); + Reference < XNameContainer > xContainer; + if ( xStyles->getStyleFamilies()->getByName( DEFINE_CONST_OUSTRING("PageStyles") ) + >>= xContainer ) + { + Reference < XStyle > xStyle; + if ( xContainer->getByName( sStyleName ) >>= xStyle ) + { + Reference < XPropertySet > xPropSet( xStyle, UNO_QUERY ); + xPropSet->setPropertyValue( DEFINE_CONST_OUSTRING("HeaderIsOn"), + makeAny( sal_Bool( sal_False ) ) ); + + Reference< XModifiable > xReset(xStyles, UNO_QUERY); + xReset->setModified(sal_False); +#ifdef DBG_UTIL + bSetOff = sal_True; +#endif + } + } + } + } + } + } + } + catch( Exception& ) + { + DBG_ERRORFILE( "SfxHelpTextWindow_Impl::SetPageStyleHeaderOff(): unexpected exception" ); + } + +#ifdef DBG_UTIL + if ( !bSetOff ) + { + DBG_ERRORFILE( "SfxHelpTextWindow_Impl::SetPageStyleHeaderOff(): set off failed" ); + } +#endif +} + +// ----------------------------------------------------------------------- + +void SfxHelpTextWindow_Impl::CloseFrame() +{ + bIsInClose = sal_True; + try + { + ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloseable > xCloseable ( xFrame, ::com::sun::star::uno::UNO_QUERY ); + if (xCloseable.is()) + xCloseable->close(sal_True); + } + catch( ::com::sun::star::util::CloseVetoException& ) + { + } +} + +// ----------------------------------------------------------------------- + +void SfxHelpTextWindow_Impl::DoSearch() +{ + if ( !pSrchDlg ) + { + // create the search dialog + pSrchDlg = new sfx2::SearchDialog( pTextWin, DEFINE_CONST_UNICODE("HelpSearchDialog") ); + // set handler + pSrchDlg->SetFindHdl( LINK( this, SfxHelpTextWindow_Impl, FindHdl ) ); + pSrchDlg->SetCloseHdl( LINK( this, SfxHelpTextWindow_Impl, CloseHdl ) ); + // get selected text of the help page to set it as the search text + Reference< XTextRange > xCursor = getCursor(); + if ( xCursor.is() ) + { + String sText = xCursor->getString(); + if ( sText.Len() > 0 ) + pSrchDlg->SetSearchText( sText ); + } + pSrchDlg->Show(); + } +} + +// class SfxHelpWindow_Impl ---------------------------------------------- + +void SfxHelpWindow_Impl::Resize() +{ + SplitWindow::Resize(); + InitSizes(); +} + +// ----------------------------------------------------------------------- + +void SfxHelpWindow_Impl::Split() +{ + static long nMinSplitSize = 5; + static long nMaxSplitSize = 99 - nMinSplitSize; + + SplitWindow::Split(); + + nIndexSize = GetItemSize( INDEXWIN_ID ); + nTextSize = GetItemSize( TEXTWIN_ID ); + + BOOL bMod = FALSE; + if( nIndexSize < nMinSplitSize ) + { + nIndexSize = nMinSplitSize; + nTextSize = nMaxSplitSize; + + bMod = TRUE; + } + else if( nTextSize < nMinSplitSize ) + { + nTextSize = nMinSplitSize; + nIndexSize = nMaxSplitSize; + + bMod = TRUE; + } + else + bMod = FALSE; + + if( bMod ) + { + SetItemSize( INDEXWIN_ID, nIndexSize ); + SetItemSize( TEXTWIN_ID, nTextSize ); + } + + InitSizes(); +} + +// ----------------------------------------------------------------------- + +void SfxHelpWindow_Impl::GetFocus() +{ + pTextWin->GrabFocus(); +} + +// ----------------------------------------------------------------------- + +void SfxHelpWindow_Impl::MakeLayout() +{ + if ( nHeight > 0 && xWindow.is() ) + { + Window* pScreenWin = VCLUnoHelper::GetWindow( xWindow ); + + /* #i55528# + Hide() / Show() will produce starnge effects. + The returned size (used later to be written back into the configuration) + isnt the right after a resize during the window is hidden. + If this resize is done if the window is visible evyrthing works as aspected. + Some VCL-patches could not solve this problem so I've established the + workaround: resize the help window if it's visible .-) + */ +// pScreenWin->Hide(); + + ::com::sun::star::awt::Rectangle aRect = xWindow->getPosSize(); + sal_Int32 nOldWidth = bIndex ? nCollapseWidth : nExpandWidth; + sal_Int32 nWidth = bIndex ? nExpandWidth : nCollapseWidth; + xWindow->setPosSize( aRect.X, aRect.Y, nWidth, nHeight, ::com::sun::star::awt::PosSize::SIZE ); + + if ( aRect.Width > 0 && aRect.Height > 0 ) + { + Rectangle aScreenRect = pScreenWin->GetClientWindowExtentsRelative( NULL ); + Point aNewPos = aScreenRect.TopLeft(); + sal_Int32 nDiffWidth = nOldWidth - nWidth; + aNewPos.X() += nDiffWidth; + pScreenWin->SetPosPixel( aNewPos ); + } + else if ( aWinPos.X() > 0 && aWinPos.Y() > 0 ) + pScreenWin->SetPosPixel( aWinPos ); + +// pScreenWin->Show(); + } + + Clear(); + + if ( bIndex ) + { + pIndexWin->Show(); + InsertItem( COLSET_ID, 100, SPLITWINDOW_APPEND, SPLITSET_ID, SWIB_PERCENTSIZE | SWIB_COLSET ); + InsertItem( INDEXWIN_ID, pIndexWin, nIndexSize, SPLITWINDOW_APPEND, COLSET_ID, SWIB_PERCENTSIZE ); + InsertItem( TEXTWIN_ID, pTextWin, nTextSize, SPLITWINDOW_APPEND, COLSET_ID, SWIB_PERCENTSIZE ); + } + else + { + pIndexWin->Hide(); + InsertItem( COLSET_ID, 100, SPLITWINDOW_APPEND, SPLITSET_ID, SWIB_PERCENTSIZE | SWIB_COLSET ); + InsertItem( TEXTWIN_ID, pTextWin, 100, SPLITWINDOW_APPEND, 1, SWIB_PERCENTSIZE ); + } +} + +// ----------------------------------------------------------------------- + +void SfxHelpWindow_Impl::InitSizes() +{ + if ( xWindow.is() ) + { + ::com::sun::star::awt::Rectangle aRect = xWindow->getPosSize(); + nHeight = aRect.Height; + + if ( bIndex ) + { + nExpandWidth = aRect.Width; + nCollapseWidth = nExpandWidth * nTextSize / 100; + } + else + { + nCollapseWidth = aRect.Width; + nExpandWidth = nCollapseWidth * 100 / nTextSize; + } + } +} + +// ----------------------------------------------------------------------- + +void SfxHelpWindow_Impl::LoadConfig() +{ + SvtViewOptions aViewOpt( E_WINDOW, CONFIGNAME_HELPWIN ); + if ( aViewOpt.Exists() ) + { + bIndex = aViewOpt.IsVisible(); + String aUserData; + Any aUserItem = aViewOpt.GetUserItem( USERITEM_NAME ); + rtl::OUString aTemp; + if ( aUserItem >>= aTemp ) + { + aUserData = String( aTemp ); + DBG_ASSERT( aUserData.GetTokenCount() == 6, "invalid user data" ); + USHORT nIdx = 0; + nIndexSize = aUserData.GetToken( 0, ';', nIdx ).ToInt32(); + nTextSize = aUserData.GetToken( 0, ';', nIdx ).ToInt32(); + sal_Int32 nWidth = aUserData.GetToken( 0, ';', nIdx ).ToInt32(); + nHeight = aUserData.GetToken( 0, ';', nIdx ).ToInt32(); + aWinPos.X() = aUserData.GetToken( 0, ';', nIdx ).ToInt32(); + aWinPos.Y() = aUserData.GetToken( 0, ';', nIdx ).ToInt32(); + if ( bIndex ) + { + nExpandWidth = nWidth; + nCollapseWidth = nExpandWidth * nTextSize / 100; + } + else + { + nCollapseWidth = nWidth; + nExpandWidth = nCollapseWidth * 100 / nTextSize; + } + } + + pTextWin->ToggleIndex( bIndex ); + } +} + +// ----------------------------------------------------------------------- + +void SfxHelpWindow_Impl::SaveConfig() +{ + SvtViewOptions aViewOpt( E_WINDOW, CONFIGNAME_HELPWIN ); + sal_Int32 nW = 0, nH = 0; + + if ( xWindow.is() ) + { + ::com::sun::star::awt::Rectangle aRect = xWindow->getPosSize(); + nW = aRect.Width; + nH = aRect.Height; + } + + aViewOpt.SetVisible( bIndex ); + String aUserData = String::CreateFromInt32( nIndexSize ); + aUserData += ';'; + aUserData += String::CreateFromInt32( nTextSize ); + aUserData += ';'; + aUserData += String::CreateFromInt32( nW ); + aUserData += ';'; + aUserData += String::CreateFromInt32( nH ); + + Window* pScreenWin = VCLUnoHelper::GetWindow( xWindow ); + aWinPos = pScreenWin->GetWindowExtentsRelative( NULL ).TopLeft(); + aUserData += ';'; + aUserData += String::CreateFromInt32( aWinPos.X() ); + aUserData += ';'; + aUserData += String::CreateFromInt32( aWinPos.Y() ); + + aViewOpt.SetUserItem( USERITEM_NAME, makeAny( rtl::OUString( aUserData ) ) ); +} + +// ----------------------------------------------------------------------- + +void SfxHelpWindow_Impl::ShowStartPage() +{ + ::rtl::OUString sHelpURL = SfxHelpWindow_Impl::buildHelpURL(pIndexWin->GetFactory(), + DEFINE_CONST_UNICODE("/start"), + ::rtl::OUString(), + sal_True); + loadHelpContent(sHelpURL); +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( SfxHelpWindow_Impl, SelectHdl, ToolBox* , pToolBox ) +{ + if ( pToolBox ) + { + bGrabFocusToToolBox = pToolBox->HasChildPathFocus(); + DoAction( pToolBox->GetCurItemId() ); + } + + return 1; +} + +//------------------------------------------------------------------------- + +IMPL_LINK( SfxHelpWindow_Impl, OpenHdl, SfxHelpIndexWindow_Impl* , EMPTYARG ) +{ + pIndexWin->SelectExecutableEntry(); + String aEntry = pIndexWin->GetSelectEntry(); + + if ( aEntry.Len() < 1 ) + return 0; + + ::rtl::OUString sHelpURL; + +// INetURLObject aObj(aEntry); +// BOOL bComplete = ( aObj.GetProtocol() == INET_PROT_VND_SUN_STAR_HELP ); + + BOOL bComplete = rtl::OUString(aEntry).toAsciiLowerCase().match(rtl::OUString::createFromAscii("vnd.sun.star.help"),0); + + if (bComplete) + sHelpURL = ::rtl::OUString(aEntry); + else + { + String aId; + String aAnchor = String('#'); + if ( aEntry.GetTokenCount( '#' ) == 2 ) + { + aId = aEntry.GetToken( 0, '#' ); + aAnchor += aEntry.GetToken( 1, '#' ); + } + else + aId = aEntry; + + aEntry = '/'; + aEntry += aId; + + sHelpURL = SfxHelpWindow_Impl::buildHelpURL(pIndexWin->GetFactory(), + aEntry, + aAnchor, + sal_True); + } + + loadHelpContent(sHelpURL); + + return 0; +} + +//------------------------------------------------------------------------- + +IMPL_LINK( SfxHelpWindow_Impl, SelectFactoryHdl, SfxHelpIndexWindow_Impl* , pWin ) +{ + if ( sTitle.Len() == 0 ) + sTitle = GetParent()->GetText(); + + String aNewTitle = sTitle; + aNewTitle += DEFINE_CONST_UNICODE(" - "); + aNewTitle += pIndexWin->GetActiveFactoryTitle(); + + Reference< XTitle > xTitle(xFrame, UNO_QUERY); + if (xTitle.is ()) + xTitle->setTitle (aNewTitle); + + if ( pWin ) + ShowStartPage(); + pIndexWin->ClearSearchPage(); + + return 0; +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( SfxHelpWindow_Impl, ChangeHdl, HelpListener_Impl*, pListener ) +{ + SetFactory( pListener->GetFactory() ); + return 0; +} + +// ----------------------------------------------------------------------- + +void SfxHelpWindow_Impl::openDone(const ::rtl::OUString& sURL , + sal_Bool bSuccess) +{ + INetURLObject aObj( sURL ); + if ( aObj.GetProtocol() == INET_PROT_VND_SUN_STAR_HELP ) + SetFactory( aObj.GetHost() ); + if ( IsWait() ) + LeaveWait(); + if ( bGrabFocusToToolBox ) + { + pTextWin->GetToolBox().GrabFocus(); + bGrabFocusToToolBox = sal_False; + } + else + pIndexWin->GrabFocusBack(); + if ( bSuccess ) + { + // set some view settings: "prevent help tips" and "helpid == 68245" + try + { + Reference < XController > xController = pTextWin->getFrame()->getController(); + if ( xController.is() ) + { + Reference < XViewSettingsSupplier > xSettings( xController, UNO_QUERY ); + Reference < XPropertySet > xViewProps = xSettings->getViewSettings(); + Reference< XPropertySetInfo > xInfo = xViewProps->getPropertySetInfo(); + Any aBoolAny = makeAny( sal_Bool( sal_True ) ); + xViewProps->setPropertyValue( DEFINE_CONST_OUSTRING("PreventHelpTips"), aBoolAny ); + xViewProps->setPropertyValue( DEFINE_CONST_OUSTRING("ShowGraphics"), aBoolAny ); + xViewProps->setPropertyValue( DEFINE_CONST_OUSTRING("ShowTables"), aBoolAny ); + xViewProps->setPropertyValue( DEFINE_CONST_OUSTRING("HelpURL"), makeAny( DEFINE_CONST_OUSTRING("HID:68245") ) ); + ::rtl::OUString sProperty( DEFINE_CONST_OUSTRING("IsExecuteHyperlinks") ); + if ( xInfo->hasPropertyByName( sProperty ) ) + xViewProps->setPropertyValue( sProperty, aBoolAny ); + xController->restoreViewData(pHelpInterceptor->GetViewData()); + } + } + catch( Exception& ) + { + DBG_ERROR( "SfxHelpWindow_Impl::OpenDoneHdl(): unexpected exception" ); + } + + // When the SearchPage opens the help doc, then select all words, which are equal to its text + String sSearchText = TRIM( pIndexWin->GetSearchText() ); + if ( sSearchText.Len() > 0 ) + pTextWin->SelectSearchText( sSearchText, pIndexWin->IsFullWordSearch() ); + + // no page style header -> this prevents a print output of the URL + pTextWin->SetPageStyleHeaderOff(); + } +} + +// ----------------------------------------------------------------------- + +SfxHelpWindow_Impl::SfxHelpWindow_Impl( + const ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFrame >& rFrame, + Window* pParent, WinBits ) : + + SplitWindow( pParent, WB_3DLOOK | WB_NOSPLITDRAW ), + + xFrame ( rFrame ), + pIndexWin ( NULL ), + pTextWin ( NULL ), + pHelpInterceptor ( new HelpInterceptor_Impl() ), + pHelpListener ( new HelpListener_Impl( pHelpInterceptor ) ), + nExpandWidth ( 0 ), + nCollapseWidth ( 0 ), + nHeight ( 0 ), + nIndexSize ( 40 ), + nTextSize ( 60 ), + bIndex ( sal_True ), + bGrabFocusToToolBox ( sal_False ), + aWinPos ( 0, 0 ), + sTitle ( pParent->GetText() ) +{ + SetHelpId( HID_HELP_WINDOW ); + SetStyle( GetStyle() | WB_DIALOGCONTROL ); + + pHelpInterceptor->InitWaiter( this ); + pIndexWin = new SfxHelpIndexWindow_Impl( this ); + pIndexWin->SetDoubleClickHdl( LINK( this, SfxHelpWindow_Impl, OpenHdl ) ); + pIndexWin->SetSelectFactoryHdl( LINK( this, SfxHelpWindow_Impl, SelectFactoryHdl ) ); + pIndexWin->Show(); + pTextWin = new SfxHelpTextWindow_Impl( this ); + Reference < XFramesSupplier > xSup( rFrame, UNO_QUERY ); + Reference < XFrames > xFrames = xSup->getFrames(); + xFrames->append( pTextWin->getFrame() ); + pTextWin->SetSelectHdl( LINK( this, SfxHelpWindow_Impl, SelectHdl ) ); + pTextWin->Show(); + pHelpInterceptor->setInterception( pTextWin->getFrame() ); + pHelpListener->SetChangeHdl( LINK( this, SfxHelpWindow_Impl, ChangeHdl ) ); + LoadConfig(); +} + +// ----------------------------------------------------------------------- + +SfxHelpWindow_Impl::~SfxHelpWindow_Impl() +{ + SaveConfig(); + Window* pDel = pIndexWin; + pIndexWin = NULL; + delete pDel; + + pTextWin->CloseFrame(); + delete pTextWin; +} + +// ----------------------------------------------------------------------- + +long SfxHelpWindow_Impl::PreNotify( NotifyEvent& rNEvt ) +{ + sal_Bool bHandled = sal_False; + if ( rNEvt.GetType() == EVENT_KEYINPUT ) + { + // Backward == <ALT><LEFT> or <BACKSPACE> Forward == <ALT><RIGHT> + const KeyCode& rKeyCode = rNEvt.GetKeyEvent()->GetKeyCode(); + USHORT nKey = rKeyCode.GetCode(); + if ( ( rKeyCode.IsMod2() && ( KEY_LEFT == nKey || KEY_RIGHT == nKey ) ) || + ( !rKeyCode.GetModifier() && KEY_BACKSPACE == nKey && !pIndexWin->HasFocusOnEdit() ) ) + { + DoAction( rKeyCode.GetCode() == KEY_RIGHT ? TBI_FORWARD : TBI_BACKWARD ); + bHandled = sal_True; + } + else if ( rKeyCode.IsMod1() && ( KEY_F4 == nKey || KEY_W == nKey ) ) + { + // <STRG><F4> or <STRG><W> -> close top frame + CloseWindow(); + bHandled = sal_True; + } + } + return bHandled ? 1 : Window::PreNotify( rNEvt ); +} + +// ----------------------------------------------------------------------- + +void SfxHelpWindow_Impl::setContainerWindow( Reference < ::com::sun::star::awt::XWindow > xWin ) +{ + xWindow = xWin; + MakeLayout(); +} + +// ----------------------------------------------------------------------- + +void SfxHelpWindow_Impl::SetFactory( const String& rFactory ) +{ + pIndexWin->SetFactory( rFactory, sal_True ); +} + +// ----------------------------------------------------------------------- + +void SfxHelpWindow_Impl::SetHelpURL( const String& rURL ) +{ + INetURLObject aObj( rURL ); + if ( aObj.GetProtocol() == INET_PROT_VND_SUN_STAR_HELP ) + SetFactory( aObj.GetHost() ); +} + +// ----------------------------------------------------------------------- + +void SfxHelpWindow_Impl::DoAction( USHORT nActionId ) +{ + switch ( nActionId ) + { + case TBI_INDEX : + { + bIndex = !bIndex; + MakeLayout(); + pTextWin->ToggleIndex( bIndex ); + break; + } + + case TBI_START : + { + ShowStartPage(); + break; + } + + case TBI_BACKWARD : + case TBI_FORWARD : + { + URL aURL; + aURL.Complete = DEFINE_CONST_UNICODE(".uno:Backward"); + if ( TBI_FORWARD == nActionId ) + aURL.Complete = DEFINE_CONST_UNICODE(".uno:Forward"); + PARSE_URL( aURL ); + pHelpInterceptor->dispatch( aURL, Sequence < PropertyValue >() ); + break; + } + + case TBI_SEARCHDIALOG : + { + pTextWin->DoSearch(); + break; + } + + case TBI_PRINT : + case TBI_SOURCEVIEW : + case TBI_COPY : + case TBI_SELECTIONMODE: + { + Reference < XDispatchProvider > xProv( pTextWin->getFrame(), UNO_QUERY ); + if ( xProv.is() ) + { + URL aURL; + if ( TBI_PRINT == nActionId ) + aURL.Complete = DEFINE_CONST_UNICODE(".uno:Print"); + else if ( TBI_SOURCEVIEW == nActionId ) + aURL.Complete = DEFINE_CONST_UNICODE(".uno:SourceView"); + else if ( TBI_COPY == nActionId ) + aURL.Complete = DEFINE_CONST_UNICODE(".uno:Copy"); + else if ( TBI_SELECTIONMODE == nActionId ) + aURL.Complete = DEFINE_CONST_UNICODE(".uno:SelectTextMode"); + else + aURL.Complete = DEFINE_CONST_UNICODE(".uno:SearchDialog"); + PARSE_URL( aURL ); + Reference < XDispatch > xDisp = xProv->queryDispatch( aURL, String(), 0 ); + if ( xDisp.is() ) + xDisp->dispatch( aURL, Sequence < PropertyValue >() ); + } + break; + } + + case TBI_BOOKMARKS : + { + String aURL = pHelpInterceptor->GetCurrentURL(); + if ( aURL.Len() > 0 ) + { + try + { + Content aCnt( aURL, Reference< ::com::sun::star::ucb::XCommandEnvironment > () ); + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > xInfo = aCnt.getProperties(); + if ( xInfo->hasPropertyByName( PROPERTY_TITLE ) ) + { + ::com::sun::star::uno::Any aAny = aCnt.getPropertyValue( PROPERTY_TITLE ); + rtl::OUString aValue; + if ( aAny >>= aValue ) + { + String aTitle( aValue ); + SfxAddHelpBookmarkDialog_Impl aDlg( this, sal_False ); + aDlg.SetTitle( aTitle ); + if ( aDlg.Execute() == RET_OK ) + { + aTitle = aDlg.GetTitle(); + pIndexWin->AddBookmarks( aTitle, aURL ); + } + } + } + } + catch( Exception& ) + { + DBG_ERROR( "SfxHelpWindow_Impl::DoAction(): unexpected exception" ); + } + } + break; + } + } +} + +// ----------------------------------------------------------------------- + +void SfxHelpWindow_Impl::CloseWindow() +{ + try + { + // search for top frame + Reference< XFramesSupplier > xCreator = getTextFrame()->getCreator(); + while ( xCreator.is() && !xCreator->isTop() ) + { + xCreator = xCreator->getCreator(); + } + + // when found, close it + if ( xCreator.is() && xCreator->isTop() ) + { + Reference < XCloseable > xCloser( xCreator, UNO_QUERY ); + if ( xCloser.is() ) + xCloser->close( sal_False ); + } + } + catch( Exception& ) + { + DBG_ERRORFILE( "SfxHelpWindow_Impl::CloseWindow(): caught an exception" ); + } +} + +// ----------------------------------------------------------------------- + +void SfxHelpWindow_Impl::UpdateToolbox() +{ + pTextWin->GetToolBox().EnableItem( TBI_BACKWARD, pHelpInterceptor->HasHistoryPred() ); + pTextWin->GetToolBox().EnableItem( TBI_FORWARD, pHelpInterceptor->HasHistorySucc() ); +} + +// ----------------------------------------------------------------------- + +sal_Bool SfxHelpWindow_Impl::HasHistoryPredecessor() const +{ + return pHelpInterceptor->HasHistoryPred(); +} + +// ----------------------------------------------------------------------- + +sal_Bool SfxHelpWindow_Impl::HasHistorySuccessor() const +{ + return pHelpInterceptor->HasHistorySucc(); +} + +// class SfxAddHelpBookmarkDialog_Impl ----------------------------------- + +SfxAddHelpBookmarkDialog_Impl::SfxAddHelpBookmarkDialog_Impl( Window* pParent, sal_Bool bRename ) : + + ModalDialog( pParent, SfxResId( DLG_HELP_ADDBOOKMARK ) ), + + aTitleFT ( this, SfxResId( FT_BOOKMARK_TITLE ) ), + aTitleED ( this, SfxResId( ED_BOOKMARK_TITLE ) ), + aOKBtn ( this, SfxResId( PB_BOOKMARK_OK ) ), + aEscBtn ( this, SfxResId( PB_BOOKMARK_CANCEL ) ), + aHelpBtn ( this, SfxResId( PB_BOOKMARK_HELP ) ) + +{ + if ( bRename ) + SetText( String( SfxResId( STR_BOOKMARK_RENAME ) ) ); + + FreeResource(); +} + +// ----------------------------------------------------------------------- + +SfxAddHelpBookmarkDialog_Impl::~SfxAddHelpBookmarkDialog_Impl() +{ +} + +// ----------------------------------------------------------------------- + +void SfxAddHelpBookmarkDialog_Impl::SetTitle( const String& rTitle ) +{ + aTitleED.SetText( rTitle ); + aTitleED.SetSelection( Selection( 0, rTitle.Len() ) ); +} + diff --git a/sfx2/source/appl/newhelp.hrc b/sfx2/source/appl/newhelp.hrc new file mode 100644 index 000000000000..7bb9aa85678c --- /dev/null +++ b/sfx2/source/appl/newhelp.hrc @@ -0,0 +1,84 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SFX_NEWHELP_HRC +#define _SFX_NEWHELP_HRC + +// #defines ***************************************************************** + +// Index Window +#define LB_ACTIVE 10 +#define FL_ACTIVE 11 +#define TC_INDEX 12 + +// Index TabPage +#define FT_EXPRESSION 10 +#define CB_INDEX 11 +#define PB_OPEN_INDEX 12 + +// Search TabPage +#define FT_SEARCH 10 +#define ED_SEARCH 11 +#define PB_SEARCH 12 +#define FT_RESULT 13 +#define CB_FULLWORDS 14 +#define CB_SCOPE 15 +#define LB_RESULT 16 +#define PB_OPEN_SEARCH 17 + +// Bookmarks TabPage +#define FT_BOOKMARKS 10 +#define LB_BOOKMARKS 11 +#define PB_BOOKMARKS 12 + +// Content TabPage +#define LB_CONTENTS 10 + +// Add to bookmarks dialog +#define FT_BOOKMARK_TITLE 10 +#define ED_BOOKMARK_TITLE 11 +#define PB_BOOKMARK_OK 12 +#define PB_BOOKMARK_CANCEL 13 +#define PB_BOOKMARK_HELP 14 +#define STR_BOOKMARK_RENAME 15 + +// Index Window: Id's of the tabpages +#define HELP_INDEX_PAGE_FIRST 1 +#define HELP_INDEX_PAGE_CONTENTS HELP_INDEX_PAGE_FIRST +#define HELP_INDEX_PAGE_INDEX 2 +#define HELP_INDEX_PAGE_SEARCH 3 +#define HELP_INDEX_PAGE_BOOKMARKS 4 +#define HELP_INDEX_PAGE_LAST HELP_INDEX_PAGE_BOOKMARKS + +// context menu ids +#define MID_OPEN 1 +#define MID_RENAME 2 +#define MID_DELETE 3 + +#endif // #ifndef _SFX_NEWHELP_HRC + +// ******************************************************************* EOF + diff --git a/sfx2/source/appl/newhelp.hxx b/sfx2/source/appl/newhelp.hxx new file mode 100644 index 000000000000..95a5bfe52230 --- /dev/null +++ b/sfx2/source/appl/newhelp.hxx @@ -0,0 +1,614 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef INCLUDED_SFX_NEWHELP_HXX +#define INCLUDED_SFX_NEWHELP_HXX + +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/uno/Reference.h> +#include <com/sun/star/frame/XDispatchResultListener.hpp> +#include <com/sun/star/frame/XDispatch.hpp> +#include <com/sun/star/frame/XFrame.hpp> + +namespace com { namespace sun { namespace star { namespace awt { class XWindow; } } } } +namespace com { namespace sun { namespace star { namespace frame { class XFrame; } } } } +namespace com { namespace sun { namespace star { namespace i18n { class XBreakIterator; } } } } +namespace com { namespace sun { namespace star { namespace text { class XTextRange; } } } } + +#include <vcl/window.hxx> +#include <vcl/toolbox.hxx> +#include <vcl/tabpage.hxx> +#include <vcl/splitwin.hxx> +#include <vcl/tabctrl.hxx> +#include <vcl/combobox.hxx> +#include <vcl/fixed.hxx> +#include <vcl/button.hxx> +#include <vcl/lstbox.hxx> +#include <vcl/dialog.hxx> +#include <svtools/svtreebx.hxx> +#include <unotools/moduleoptions.hxx> + +#include "srchdlg.hxx" + +// class OpenStatusListener_Impl ----------------------------------------- + +class OpenStatusListener_Impl : public ::cppu::WeakImplHelper1< ::com::sun::star::frame::XDispatchResultListener > +{ +private: + sal_Bool m_bFinished; + sal_Bool m_bSuccess; + Link m_aOpenLink; + String m_sURL; + +public: + OpenStatusListener_Impl() : m_bFinished( FALSE ), m_bSuccess( FALSE ) {} + + virtual void SAL_CALL dispatchFinished( const ::com::sun::star::frame::DispatchResultEvent& Event ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException); + + inline sal_Bool IsFinished() const { return m_bFinished; } + inline sal_Bool IsSuccessful() const { return m_bSuccess; } + inline void SetURL( const String& rURL ) { m_sURL = rURL; } + inline String GetURL() const { return m_sURL; } + inline void SetOpenHdl( const Link& rLink ) { m_aOpenLink = rLink; } +}; + +// ContentListBox_Impl --------------------------------------------------- + +class ContentListBox_Impl : public SvTreeListBox +{ +private: + Image aOpenBookImage; + Image aClosedBookImage; + Image aDocumentImage; + + void InitRoot(); + void ClearChildren( SvLBoxEntry* pParent ); + +public: + ContentListBox_Impl( Window* pParent, const ResId& rResId ); + ~ContentListBox_Impl(); + + + virtual void RequestingChilds( SvLBoxEntry* pParent ); + virtual long Notify( NotifyEvent& rNEvt ); + + inline void SetOpenHdl( const Link& rLink ) { SetDoubleClickHdl( rLink ); } + String GetSelectEntry() const; +}; + +// class HelpTabPage_Impl ------------------------------------------------ + +class SfxHelpIndexWindow_Impl; + +class HelpTabPage_Impl : public TabPage +{ +protected: + SfxHelpIndexWindow_Impl* m_pIdxWin; + +public: + HelpTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin, const ResId& rResId ); + + virtual Control* GetLastFocusControl() = 0; +}; + +// class ContentTabPage_Impl --------------------------------------------- + +class ContentTabPage_Impl : public HelpTabPage_Impl +{ +private: + ContentListBox_Impl aContentBox; + +public: + ContentTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin ); + + virtual void Resize(); + virtual void ActivatePage(); + virtual Control* GetLastFocusControl(); + + inline void SetOpenHdl( const Link& rLink ) { aContentBox.SetOpenHdl( rLink ); } + inline String GetSelectEntry() const { return aContentBox.GetSelectEntry(); } + inline void SetFocusOnBox() { aContentBox.GrabFocus(); } +}; + +// class IndexTabPage_Impl ----------------------------------------------- + +class IndexBox_Impl : public ComboBox +{ +public: + IndexBox_Impl( Window* pParent, const ResId& rResId ); + + virtual void UserDraw( const UserDrawEvent& rUDEvt ); + virtual long Notify( NotifyEvent& rNEvt ); + + void SelectExecutableEntry(); +}; + +class IndexTabPage_Impl : public HelpTabPage_Impl +{ +private: + FixedText aExpressionFT; + IndexBox_Impl aIndexCB; + PushButton aOpenBtn; + + Timer aFactoryTimer; + Timer aKeywordTimer; + Link aKeywordLink; + + String sFactory; + String sKeyword; + + long nMinWidth; + sal_Bool bIsActivated; + + void InitializeIndex(); + void ClearIndex(); + + DECL_LINK( OpenHdl, PushButton* ); + DECL_LINK( TimeoutHdl, Timer* ); + +public: + IndexTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin ); + ~IndexTabPage_Impl(); + + virtual void Resize(); + virtual void ActivatePage(); + virtual Control* GetLastFocusControl(); + + void SetDoubleClickHdl( const Link& rLink ); + void SetFactory( const String& rFactory ); + inline String GetFactory() const { return sFactory; } + String GetSelectEntry() const; + inline void SetFocusOnBox() { aIndexCB.GrabFocus(); } + inline sal_Bool HasFocusOnEdit() const { return aIndexCB.HasChildPathFocus(); } + + inline void SetKeywordHdl( const Link& rLink ) { aKeywordLink = rLink; } + void SetKeyword( const String& rKeyword ); + sal_Bool HasKeyword() const; + sal_Bool HasKeywordIgnoreCase(); //added by BerryJia for fixing Bug98251, 2002-12-11 + void OpenKeyword(); + + inline void SelectExecutableEntry() { aIndexCB.SelectExecutableEntry(); } +}; + +// class SearchTabPage_Impl ---------------------------------------------- + +class SearchBox_Impl : public ComboBox +{ +private: + Link aSearchLink; + +public: + SearchBox_Impl( Window* pParent, const ResId& rResId ) : + ComboBox( pParent, rResId ) { SetDropDownLineCount( 5 ); } + + virtual long PreNotify( NotifyEvent& rNEvt ); + virtual void Select(); + + inline void SetSearchLink( const Link& rLink ) { aSearchLink = rLink; } +}; + +class SearchResultsBox_Impl : public ListBox +{ +public: + SearchResultsBox_Impl( Window* pParent, const ResId& rResId ) : ListBox( pParent, rResId ) {} + + virtual long Notify( NotifyEvent& rNEvt ); +}; + +class SearchTabPage_Impl : public HelpTabPage_Impl +{ +private: + FixedText aSearchFT; + SearchBox_Impl aSearchED; + PushButton aSearchBtn; + CheckBox aFullWordsCB; + CheckBox aScopeCB; + SearchResultsBox_Impl aResultsLB; + PushButton aOpenBtn; + + Size aMinSize; + String aFactory; + + ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XBreakIterator > + xBreakIterator; + + void ClearSearchResults(); + void RememberSearchText( const String& rSearchText ); + + DECL_LINK( SearchHdl, PushButton* ); + DECL_LINK( OpenHdl, PushButton* ); + DECL_LINK( ModifyHdl, Edit* ); + +public: + SearchTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin ); + ~SearchTabPage_Impl(); + + virtual void Resize(); + virtual void ActivatePage(); + virtual Control* GetLastFocusControl(); + + void SetDoubleClickHdl( const Link& rLink ); + inline void SetFactory( const String& rFactory ) { aFactory = rFactory; } + String GetSelectEntry() const; + void ClearPage(); + inline void SetFocusOnBox() { aResultsLB.GrabFocus(); } + inline sal_Bool HasFocusOnEdit() const { return aSearchED.HasChildPathFocus(); } + inline String GetSearchText() const { return aSearchED.GetText(); } + inline sal_Bool IsFullWordSearch() const { return aFullWordsCB.IsChecked(); } + sal_Bool OpenKeyword( const String& rKeyword ); +}; + +// class BookmarksTabPage_Impl ------------------------------------------- + +class BookmarksBox_Impl : public ListBox +{ +private: + void DoAction( USHORT nAction ); + +public: + BookmarksBox_Impl( Window* pParent, const ResId& rResId ); + ~BookmarksBox_Impl(); + + virtual long Notify( NotifyEvent& rNEvt ); +}; + +class BookmarksTabPage_Impl : public HelpTabPage_Impl +{ +private: + FixedText aBookmarksFT; + BookmarksBox_Impl aBookmarksBox; + PushButton aBookmarksPB; + + long nMinWidth; + + DECL_LINK( OpenHdl, PushButton* ); + +public: + BookmarksTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin ); + + virtual void Resize(); + virtual void ActivatePage(); + virtual Control* GetLastFocusControl(); + + void SetDoubleClickHdl( const Link& rLink ); + String GetSelectEntry() const; + void AddBookmarks( const String& rTitle, const String& rURL ); + inline void SetFocusOnBox() { aBookmarksBox.GrabFocus(); } +}; + +// class SfxHelpIndexWindow_Impl ----------------------------------------- + +class SfxHelpWindow_Impl; + +class SfxHelpIndexWindow_Impl : public Window +{ +private: + ListBox aActiveLB; + FixedLine aActiveLine; + + TabControl aTabCtrl; + Timer aTimer; + + Link aSelectFactoryLink; + Link aPageDoubleClickLink; + Link aIndexKeywordLink; + String sKeyword; + + SfxHelpWindow_Impl* pParentWin; + + ContentTabPage_Impl* pCPage; + IndexTabPage_Impl* pIPage; + SearchTabPage_Impl* pSPage; + BookmarksTabPage_Impl* pBPage; + + long nMinWidth; + bool bWasCursorLeftOrRight; + bool bIsInitDone; + + void Initialize(); + void SetActiveFactory(); + HelpTabPage_Impl* GetCurrentPage( USHORT& rCurId ); + + inline ContentTabPage_Impl* GetContentPage(); + inline IndexTabPage_Impl* GetIndexPage(); + inline SearchTabPage_Impl* GetSearchPage(); + inline BookmarksTabPage_Impl* GetBookmarksPage(); + + DECL_LINK( ActivatePageHdl, TabControl* ); + DECL_LINK( SelectHdl, ListBox* ); + DECL_LINK( InitHdl, Timer* ); + DECL_LINK( SelectFactoryHdl, Timer* ); + DECL_LINK( KeywordHdl, IndexTabPage_Impl* ); + +public: + SfxHelpIndexWindow_Impl( SfxHelpWindow_Impl* pParent ); + ~SfxHelpIndexWindow_Impl(); + + virtual void Resize(); + virtual long PreNotify( NotifyEvent& rNEvt ); + virtual void DataChanged( const DataChangedEvent& rDCEvt ); + + void SetDoubleClickHdl( const Link& rLink ); + inline void SetSelectFactoryHdl( const Link& rLink ) { aSelectFactoryLink = rLink; } + void SetFactory( const String& rFactory, sal_Bool bActive ); + inline String GetFactory() const { return pIPage->GetFactory(); } + String GetSelectEntry() const; + void AddBookmarks( const String& rTitle, const String& rURL ); + bool IsValidFactory( const String& _rFactory ); + inline String GetActiveFactoryTitle() const { return aActiveLB.GetSelectEntry(); } + inline void UpdateTabControl() { aTabCtrl.Invalidate(); } + void ClearSearchPage(); + void GrabFocusBack(); + sal_Bool HasFocusOnEdit() const; + String GetSearchText() const; + sal_Bool IsFullWordSearch() const; + void OpenKeyword( const String& rKeyword ); + void SelectExecutableEntry(); + inline bool WasCursorLeftOrRight(); +}; + +// inlines --------------------------------------------------------------- + +ContentTabPage_Impl* SfxHelpIndexWindow_Impl::GetContentPage() +{ + if ( !pCPage ) + { + pCPage = new ContentTabPage_Impl( &aTabCtrl, this ); + pCPage->SetOpenHdl( aPageDoubleClickLink ); + } + return pCPage; +} +IndexTabPage_Impl* SfxHelpIndexWindow_Impl::GetIndexPage() +{ + if ( !pIPage ) + { + pIPage = new IndexTabPage_Impl( &aTabCtrl, this ); + pIPage->SetDoubleClickHdl( aPageDoubleClickLink ); + pIPage->SetKeywordHdl( aIndexKeywordLink ); + } + return pIPage; +} + +SearchTabPage_Impl* SfxHelpIndexWindow_Impl::GetSearchPage() +{ + if ( !pSPage ) + { + pSPage = new SearchTabPage_Impl( &aTabCtrl, this ); + pSPage->SetDoubleClickHdl( aPageDoubleClickLink ); + } + return pSPage; +} + +BookmarksTabPage_Impl* SfxHelpIndexWindow_Impl::GetBookmarksPage() +{ + if ( !pBPage ) + { + pBPage = new BookmarksTabPage_Impl( &aTabCtrl, this ); + pBPage->SetDoubleClickHdl( aPageDoubleClickLink ); + } + return pBPage; +} + +bool SfxHelpIndexWindow_Impl::WasCursorLeftOrRight() +{ + bool bRet = bWasCursorLeftOrRight; + bWasCursorLeftOrRight = false; + return bRet; +} + +// class TextWin_Impl ---------------------------------------------------- + +class TextWin_Impl : public DockingWindow +{ +public: + TextWin_Impl( Window* pParent ); + virtual ~TextWin_Impl(); + + virtual long Notify( NotifyEvent& rNEvt ); +}; + +// class SfxHelpTextWindow_Impl ------------------------------------------ + +class SvtMiscOptions; +class SfxHelpWindow_Impl; + +class SfxHelpTextWindow_Impl : public Window +{ +private: + ToolBox aToolBox; + CheckBox aOnStartupCB; + Timer aSelectTimer; + Image aIndexOnImage; + Image aIndexOffImage; + String aIndexOnText; + String aIndexOffText; + String aSearchText; + String aOnStartupText; + ::rtl::OUString sCurrentFactory; + + SfxHelpWindow_Impl* pHelpWin; + Window* pTextWin; + sfx2::SearchDialog* pSrchDlg; + ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFrame > + xFrame; + ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XBreakIterator > + xBreakIterator; + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > + xConfiguration; + long nMinPos; + sal_Bool bIsDebug; + sal_Bool bIsIndexOn; + sal_Bool bIsInClose; + sal_Bool bIsFullWordSearch; + + sal_Bool HasSelection() const; + void InitToolBoxImages(); + void InitOnStartupBox( bool bOnlyText ); + void SetOnStartupBoxPosition(); + + ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XBreakIterator > + GetBreakIterator(); + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > + getCursor() const; + bool isHandledKey( const KeyCode& _rKeyCode ); + + DECL_LINK( SelectHdl, Timer* ); + DECL_LINK( NotifyHdl, SvtMiscOptions* ); + DECL_LINK( FindHdl, sfx2::SearchDialog* ); + DECL_LINK( CloseHdl, sfx2::SearchDialog* ); + DECL_LINK( CheckHdl, CheckBox* ); + +public: + SfxHelpTextWindow_Impl( SfxHelpWindow_Impl* pParent ); + ~SfxHelpTextWindow_Impl(); + + virtual void Resize(); + virtual long PreNotify( NotifyEvent& rNEvt ); + virtual void GetFocus(); + virtual void DataChanged( const DataChangedEvent& rDCEvt ); + + inline ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFrame > + getFrame() const { return xFrame; } + + inline void SetSelectHdl( const Link& rLink ) { aToolBox.SetSelectHdl( rLink ); } + void ToggleIndex( sal_Bool bOn ); + void SelectSearchText( const String& rSearchText, sal_Bool _bIsFullWordSearch ); + void SetPageStyleHeaderOff() const; + inline ToolBox& GetToolBox() { return aToolBox; } + void CloseFrame(); + void DoSearch(); +}; + +// class SfxHelpWindow_Impl ---------------------------------------------- + +class HelpInterceptor_Impl; +class HelpListener_Impl; +class SfxHelpWindow_Impl : public SplitWindow +{ +private: +friend class SfxHelpIndexWindow_Impl; + + ::com::sun::star::uno::Reference < ::com::sun::star::awt::XWindow > + xWindow; + ::com::sun::star::uno::Reference < ::com::sun::star::frame::XDispatchResultListener > + xOpenListener; + ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFrame > + xFrame; + + SfxHelpIndexWindow_Impl* pIndexWin; + SfxHelpTextWindow_Impl* pTextWin; + HelpInterceptor_Impl* pHelpInterceptor; + HelpListener_Impl* pHelpListener; + + sal_Int32 nExpandWidth; + sal_Int32 nCollapseWidth; + sal_Int32 nHeight; + long nIndexSize; + long nTextSize; + sal_Bool bIndex; + sal_Bool bGrabFocusToToolBox; + Point aWinPos; + String sTitle; + String sKeyword; + + virtual void Resize(); + virtual void Split(); + virtual void GetFocus(); + + void MakeLayout(); + void InitSizes(); + void LoadConfig(); + void SaveConfig(); + void ShowStartPage(); + + DECL_LINK( SelectHdl, ToolBox* ); + DECL_LINK( OpenHdl, SfxHelpIndexWindow_Impl* ); + DECL_LINK( SelectFactoryHdl, SfxHelpIndexWindow_Impl* ); + DECL_LINK( ChangeHdl, HelpListener_Impl* ); + +public: + SfxHelpWindow_Impl( const ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFrame >& rFrame, + Window* pParent, WinBits nBits ); + ~SfxHelpWindow_Impl(); + + virtual long PreNotify( NotifyEvent& rNEvt ); + + void setContainerWindow( + ::com::sun::star::uno::Reference < ::com::sun::star::awt::XWindow > xWin ); + inline ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFrame > + getTextFrame() const { return pTextWin->getFrame(); } + inline ::com::sun::star::uno::Reference < ::com::sun::star::frame::XDispatchResultListener > + getOpenListener() const { return xOpenListener; } + + void SetFactory( const String& rFactory ); + void SetHelpURL( const String& rURL ); + void DoAction( USHORT nActionId ); + void CloseWindow(); + + void UpdateToolbox(); + inline void OpenKeyword( const String& rKeyword ) { pIndexWin->OpenKeyword( rKeyword ); } + inline String GetFactory() const { return pIndexWin->GetFactory(); } + + sal_Bool HasHistoryPredecessor() const; // forward to interceptor + sal_Bool HasHistorySuccessor() const; // forward to interceptor + + void openDone(const ::rtl::OUString& sURL , + sal_Bool bSuccess); + + static sal_Bool splitHelpURL(const ::rtl::OUString& sHelpURL, + ::rtl::OUString& sFactory, + ::rtl::OUString& sContent, + ::rtl::OUString& sAnchor ); + + static ::rtl::OUString buildHelpURL(const ::rtl::OUString& sFactory , + const ::rtl::OUString& sContent , + const ::rtl::OUString& sAnchor , + sal_Bool bUseQuestionMark); + + void loadHelpContent(const ::rtl::OUString& sHelpURL , + sal_Bool bAddToHistory = sal_True); +}; + +class SfxAddHelpBookmarkDialog_Impl : public ModalDialog +{ +private: + FixedText aTitleFT; + Edit aTitleED; + OKButton aOKBtn; + CancelButton aEscBtn; + HelpButton aHelpBtn; + +public: + SfxAddHelpBookmarkDialog_Impl( Window* pParent, sal_Bool bRename = sal_True ); + ~SfxAddHelpBookmarkDialog_Impl(); + + void SetTitle( const String& rTitle ); + inline String GetTitle() const { return aTitleED.GetText(); } +}; + +#endif // #ifndef INCLUDED_SFX_NEWHELP_HXX + diff --git a/sfx2/source/appl/newhelp.src b/sfx2/source/appl/newhelp.src new file mode 100644 index 000000000000..8a2b4f760f7e --- /dev/null +++ b/sfx2/source/appl/newhelp.src @@ -0,0 +1,580 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "app.hrc" +#include "newhelp.hrc" +#include "helpid.hrc" + +Window WIN_HELPINDEX +{ + Hide = TRUE ; + Size = MAP_APPFONT ( 120 , 200 ) ; + DialogControl = TRUE; + ListBox LB_ACTIVE + { + HelpId = HID_HELP_LISTBOX; + Border = TRUE ; + DropDown = TRUE; + Pos = MAP_APPFONT ( 3 , 3 ) ; + Size = MAP_APPFONT ( 114 , 40 ) ; + }; + FixedLine FL_ACTIVE + { + Hide = True; + Pos = MAP_APPFONT ( 2, 19 ) ; + Size = MAP_APPFONT ( 118 , 1 ) ; + }; + TabControl TC_INDEX + { + HelpId = HID_HELP_TABCONTROL; + Pos = MAP_APPFONT ( 3, 19 ) ; + TabStop = TRUE; + PageList = + { + PageItem + { + Identifier = HELP_INDEX_PAGE_CONTENTS ; + Text [ en-US ] = "Contents"; + }; + PageItem + { + Identifier = HELP_INDEX_PAGE_INDEX ; + Text [ en-US ] = "Index"; + }; + PageItem + { + Identifier = HELP_INDEX_PAGE_SEARCH ; + Text [ en-US ] = "Find"; + }; + PageItem + { + Identifier = HELP_INDEX_PAGE_BOOKMARKS ; + Text [ en-US ] = "Bookmarks"; + }; + }; + }; +}; + +TabPage TP_HELP_INDEX +{ + HelpId = HID_HELP_TABPAGE_INDEX; + Hide = TRUE ; + DialogControl = TRUE; + Size = MAP_APPFONT ( 120 , 200 ) ; + FixedText FT_EXPRESSION + { + Pos = MAP_APPFONT ( 6 , 6 ) ; + Size = MAP_APPFONT ( 108 , 10 ) ; + Text [ en-US ] = "~Search term" ; + }; + ComboBox CB_INDEX + { + Border = TRUE ; + Pos = MAP_APPFONT ( 6 , 17 ) ; + Size = MAP_APPFONT ( 108 , 97 ) ; + }; + PushButton PB_OPEN_INDEX + { + Pos = MAP_APPFONT ( 64 , 115 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; + Text [ en-US ] = "~Display" ; + }; +}; + +TabPage TP_HELP_SEARCH +{ + HelpId = HID_HELP_TABPAGE_SEARCH; + Hide = TRUE ; + DialogControl = TRUE; + Size = MAP_APPFONT ( 140 , 122 ) ; + FixedText FT_SEARCH + { + Pos = MAP_APPFONT ( 6 , 6 ) ; + Size = MAP_APPFONT ( 128 , 10 ) ; + Text [ en-US ] = "S~earch term" ; + }; + ComboBox ED_SEARCH + { + Border = TRUE ; + DropDown = TRUE; + Pos = MAP_APPFONT ( 6 , 17 ) ; + Size = MAP_APPFONT ( 92 , 40 ) ; + }; + PushButton PB_SEARCH + { + Pos = MAP_APPFONT ( 101 , 17 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; + Text [ en-US ] = "~Find"; + }; + CheckBox CB_FULLWORDS + { + Pos = MAP_APPFONT ( 6, 34 ) ; + Size = MAP_APPFONT ( 128 , 10 ) ; + Text [ en-US ] = "~Complete words only"; + }; + CheckBox CB_SCOPE + { + Pos = MAP_APPFONT ( 6, 47 ) ; + Size = MAP_APPFONT ( 128 , 10 ) ; + Text [ en-US ] = "Find in ~headings only"; + }; + ListBox LB_RESULT + { + Border = TRUE ; + Pos = MAP_APPFONT ( 6 , 60 ) ; + Size = MAP_APPFONT ( 128 , 30 ) ; + }; + PushButton PB_OPEN_SEARCH + { + Pos = MAP_APPFONT ( 84 , 182 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; + Text [ en-US ] = "~Display" ; + }; +}; + +TabPage TP_HELP_BOOKMARKS +{ + HelpId = HID_HELP_TABPAGE_BOOKMARKS; + Hide = TRUE ; + DialogControl = TRUE; + Size = MAP_APPFONT ( 120 , 200 ) ; + FixedText FT_BOOKMARKS + { + Pos = MAP_APPFONT ( 6 , 6 ) ; + Size = MAP_APPFONT ( 108 , 10 ) ; + Text [ en-US ] = "~Bookmarks" ; + }; + ListBox LB_BOOKMARKS + { + Border = TRUE ; + Sort = TRUE; + Pos = MAP_APPFONT ( 6 , 19 ) ; + Size = MAP_APPFONT ( 108 , 97 ) ; + }; + PushButton PB_BOOKMARKS + { + Pos = MAP_APPFONT ( 64 , 119 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; + Text [ en-US ] = "~Display" ; + }; +}; + +TabPage TP_HELP_CONTENT +{ + HelpId = HID_HELP_TABPAGE_CONTENTS; + Hide = TRUE ; + DialogControl = TRUE; + Size = MAP_APPFONT ( 120 , 200 ) ; + Control LB_CONTENTS + { + HelpId = HID_HELP_TREELISTBOX_CONTENTS ; + Border = TRUE ; + TabStop = TRUE; + Pos = MAP_APPFONT ( 6 , 6 ) ; + Size = MAP_APPFONT ( 108 , 188 ) ; + }; +}; + +#define MASKCOLOR_MAGENTA \ + MaskColor = Color { Red = 0xFFFF ; Green = 0x0000 ; Blue = 0xFFFF ; }; + +Image IMG_HELP_TOOLBOX_INDEX_ON +{ + ImageBitmap = Bitmap { File = "indexon_small.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_INDEX_OFF +{ + ImageBitmap = Bitmap { File = "indexoff_small.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_START +{ + ImageBitmap = Bitmap { File = "sc06303.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_PREV +{ + ImageBitmap = Bitmap { File = "sc06301.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_NEXT +{ + ImageBitmap = Bitmap { File = "sc06300.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_PRINT +{ + ImageBitmap = Bitmap { File = "sc05504.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_BOOKMARKS +{ + ImageBitmap = Bitmap { File = "favourite.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_SEARCHDIALOG +{ + ImageBitmap = Bitmap { File = "sc05961.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_COPY +{ + ImageBitmap = Bitmap { File = "sc05711.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_CONTENT_BOOK_OPEN +{ + ImageBitmap = Bitmap { File = "hlpbookopen.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_CONTENT_BOOK_OPEN_HC +{ + ImageBitmap = Bitmap { File = "hlpbookopen_h.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_CONTENT_BOOK_CLOSED +{ + ImageBitmap = Bitmap { File = "hlpbookclosed.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_CONTENT_BOOK_CLOSED_HC +{ + ImageBitmap = Bitmap { File = "hlpbookclosed_h.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_CONTENT_DOC +{ + ImageBitmap = Bitmap { File = "hlpdoc.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_CONTENT_DOC_HC +{ + ImageBitmap = Bitmap { File = "hlpdoc_h.bmp" ; }; + MASKCOLOR_MAGENTA +}; + +String STR_HELP_WINDOW_TITLE +{ + Text [ en-US ] = "%PRODUCTNAME Help"; +}; +String STR_HELP_BUTTON_INDEX_ON +{ + Text [ en-US ] = "Show Navigation Pane"; +}; +String STR_HELP_BUTTON_INDEX_OFF +{ + Text [ en-US ] = "Hide Navigation Pane"; +}; +String STR_HELP_BUTTON_START +{ + Text [ en-US ] = "First Page"; +}; +String STR_HELP_BUTTON_PREV +{ + Text [ en-US ] = "Previous Page"; +}; +String STR_HELP_BUTTON_NEXT +{ + Text [ en-US ] = "Next Page"; +}; +String STR_HELP_BUTTON_PRINT +{ + Text [ en-US ] = "Print..."; +}; +String STR_HELP_BUTTON_ADDBOOKMARK +{ + Text [ en-US ] = "Add to Bookmarks..."; +}; +String STR_HELP_BUTTON_SEARCHDIALOG +{ + Text [ en-US ] = "Find on this Page..."; +}; +String STR_HELP_BUTTON_SOURCEVIEW +{ + Text [ en-US ] = "HTML Source"; +}; + +String STR_HELP_FIRST_MESSAGE +{ + Text [ en-US ] = "The Help is being started..."; +}; +String STR_HELP_FIRST_HTML +{ + Text = "<html></head><body><center><br></br><br></br><p><tt>%1</tt></center></body></html>"; +}; +String STR_HELP_MENU_TEXT_SELECTION_MODE +{ + Text [ en-US ] = "Select Text"; +}; +String STR_HELP_MENU_TEXT_COPY +{ + Text [ en-US ] = "~Copy" ; +}; +ModalDialog DLG_HELP_ADDBOOKMARK +{ + Size = MAP_APPFONT ( 208 , 43 ) ; + Text [ en-US ] = "Add to Bookmarks"; + MOVEABLE = TRUE ; + CLOSEABLE = TRUE ; + OUTPUTSIZE = TRUE ; + SVLOOK = TRUE ; + FixedText FT_BOOKMARK_TITLE + { + PosSize = MAP_APPFONT ( 6 , 6 , 140 , 10 ) ; + Text [ en-US ] = "Bookmark:" ; + TABSTOP = FALSE ; + GROUP = TRUE ; + LEFT = TRUE ; + }; + Edit ED_BOOKMARK_TITLE + { + PosSize = MAP_APPFONT ( 6 , 19 , 140 , 12 ) ; + TABSTOP = TRUE ; + BORDER = TRUE ; + }; + OKButton PB_BOOKMARK_OK + { + PosSize = MAP_APPFONT ( 152 , 6 , 50 , 14 ) ; + HIDE = FALSE ; + TABSTOP = TRUE ; + GROUP = TRUE ; + Disable = FALSE ; + DefButton = TRUE ; + }; + CancelButton PB_BOOKMARK_CANCEL + { + PosSize = MAP_APPFONT ( 152 , 23 , 50 , 14 ) ; + TABSTOP = TRUE ; + GROUP = TRUE ; + }; + HelpButton PB_BOOKMARK_HELP + { + PosSize = MAP_APPFONT ( 152 , 43 , 50 , 14 ) ; + TABSTOP = TRUE ; + GROUP = TRUE ; + Hide = TRUE; + }; + String STR_BOOKMARK_RENAME + { + Text [ en-US ] = "Rename Bookmark"; + }; +}; + +Menu MENU_HELP_BOOKMARKS +{ + ItemList = + { + MenuItem + { + Identifier = MID_OPEN ; + HelpId = HID_HELP_BOOKMARKS_OPEN; + Text [ en-US ] = "Display"; + }; + MenuItem + { + Separator = TRUE ; + }; + MenuItem + { + Identifier = MID_RENAME ; + HelpId = HID_HELP_BOOKMARKS_RENAME; + Text [ en-US ] = "Rename..."; + }; + MenuItem + { + Identifier = MID_DELETE ; + HelpId = HID_HELP_BOOKMARKS_DELETE; + Text [ en-US ] = "Delete"; + }; + }; +}; + +InfoBox RID_INFO_NOSEARCHRESULTS +{ + BUTTONS = WB_OK ; + DEFBUTTON = WB_DEF_OK ; + Message [ en-US ] = "No topics found."; +}; + +InfoBox RID_INFO_NOSEARCHTEXTFOUND +{ + BUTTONS = WB_OK ; + DEFBUTTON = WB_DEF_OK ; + Message [ en-US ] = "The text you entered was not found."; +}; + +Image IMG_HELP_TOOLBOX_HC_INDEX_ON +{ + ImageBitmap = Bitmap { File = "indexon_small_h.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_HC_INDEX_OFF +{ + ImageBitmap = Bitmap { File = "indexoff_small_h.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_HC_START +{ + ImageBitmap = Bitmap { File = "sch06303.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_HC_PREV +{ + ImageBitmap = Bitmap { File = "sch06301.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_HC_NEXT +{ + ImageBitmap = Bitmap { File = "sch06300.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_HC_PRINT +{ + ImageBitmap = Bitmap { File = "sch05504.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_HC_BOOKMARKS +{ + ImageBitmap = Bitmap { File = "favourite_h.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_HC_SEARCHDIALOG +{ + ImageBitmap = Bitmap { File = "sch05961.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_HC_COPY +{ + ImageBitmap = Bitmap { File = "sch05711.bmp" ; }; + MASKCOLOR_MAGENTA +}; + +Image IMG_HELP_TOOLBOX_L_INDEX_ON +{ + ImageBitmap = Bitmap { File = "indexon_big.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_L_INDEX_OFF +{ + ImageBitmap = Bitmap { File = "indexoff_big.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_L_START +{ + ImageBitmap = Bitmap { File = "lc06303.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_L_PREV +{ + ImageBitmap = Bitmap { File = "lc06301.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_L_NEXT +{ + ImageBitmap = Bitmap { File = "lc06300.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_L_PRINT +{ + ImageBitmap = Bitmap { File = "lc05504.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_L_BOOKMARKS +{ + ImageBitmap = Bitmap { File = "favourite_big.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_L_SEARCHDIALOG +{ + ImageBitmap = Bitmap { File = "lc05961.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_L_COPY +{ + ImageBitmap = Bitmap { File = "lc05711.bmp" ; }; + MASKCOLOR_MAGENTA +}; + +Image IMG_HELP_TOOLBOX_HCL_INDEX_ON +{ + ImageBitmap = Bitmap { File = "indexon_big_h.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_HCL_INDEX_OFF +{ + ImageBitmap = Bitmap { File = "indexoff_big_h.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_HCL_START +{ + ImageBitmap = Bitmap { File = "lch06303.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_HCL_PREV +{ + ImageBitmap = Bitmap { File = "lch06301.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_HCL_NEXT +{ + ImageBitmap = Bitmap { File = "lch06300.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_HCL_PRINT +{ + ImageBitmap = Bitmap { File = "lch05504.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_HCL_BOOKMARKS +{ + ImageBitmap = Bitmap { File = "favourite_big_h.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_HCL_SEARCHDIALOG +{ + ImageBitmap = Bitmap { File = "lch05961.bmp" ; }; + MASKCOLOR_MAGENTA +}; +Image IMG_HELP_TOOLBOX_HCL_COPY +{ + ImageBitmap = Bitmap { File = "lch05711.bmp" ; }; + MASKCOLOR_MAGENTA +}; + +CheckBox RID_HELP_ONSTARTUP_BOX +{ + HelpId = HID_HELP_ONSTARTUP_BOX; + Hide = TRUE; + TabStop = TRUE; + Size = MAP_APPFONT ( 200 , 10 ) ; +}; +String RID_HELP_ONSTARTUP_TEXT +{ + Text [ en-US ] = "~Display %PRODUCTNAME %MODULENAME Help at Startup"; +}; + diff --git a/sfx2/source/appl/opengrf.cxx b/sfx2/source/appl/opengrf.cxx new file mode 100644 index 000000000000..a4d134df27fa --- /dev/null +++ b/sfx2/source/appl/opengrf.cxx @@ -0,0 +1,295 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" + +#include <tools/urlobj.hxx> +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/uno/Reference.h> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp> +#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp> +#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp> +#include <com/sun/star/ui/dialogs/FilePreviewImageFormats.hpp> +#include <com/sun/star/ui/dialogs/ListboxControlActions.hpp> +#include <com/sun/star/ui/dialogs/TemplateDescription.hpp> +#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp> +#include <com/sun/star/ui/dialogs/XFilePicker.hpp> +#include <com/sun/star/ui/dialogs/XFilePickerListener.hpp> +#include <com/sun/star/ui/dialogs/XFilePickerNotifier.hpp> +#include <com/sun/star/ui/dialogs/XFilePreview.hpp> +#include <com/sun/star/ui/dialogs/XFilterManager.hpp> +#include <svl/urihelper.hxx> +#include <unotools/ucbstreamhelper.hxx> +#include <svtools/transfer.hxx> +#include <sot/formats.hxx> +#include <vcl/msgbox.hxx> +#include <sfx2/filedlghelper.hxx> +#include <sfx2/docfile.hxx> +#include <unotools/pathoptions.hxx> +#include <sfx2/opengrf.hxx> +#include "app.hrc" +#include "sfxresid.hxx" + +//----------------------------------------------------------------------------- + +using namespace ::com::sun::star; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::ui::dialogs; +using namespace ::com::sun::star::uno; +using namespace ::rtl; +using namespace ::cppu; + + +//----------------------------------------------------------------------------- + +USHORT SvxOpenGrfErr2ResId( short err ) +{ + switch( err ) + { + case GRFILTER_OPENERROR: + return RID_SVXSTR_GRFILTER_OPENERROR; + case GRFILTER_IOERROR: + return RID_SVXSTR_GRFILTER_IOERROR; + case GRFILTER_VERSIONERROR: + return RID_SVXSTR_GRFILTER_VERSIONERROR; + case GRFILTER_FILTERERROR: + return RID_SVXSTR_GRFILTER_FILTERERROR; + case GRFILTER_FORMATERROR: + default: + return RID_SVXSTR_GRFILTER_FORMATERROR; + } +} + + +struct SvxOpenGrf_Impl +{ + SvxOpenGrf_Impl (); + + sfx2::FileDialogHelper aFileDlg; + uno::Reference < XFilePickerControlAccess > xCtrlAcc; +}; + + +SvxOpenGrf_Impl::SvxOpenGrf_Impl() : + aFileDlg(SFXWB_GRAPHIC) +{ + uno::Reference < XFilePicker > xFP = aFileDlg.GetFilePicker(); + xCtrlAcc = uno::Reference < XFilePickerControlAccess >(xFP, UNO_QUERY); +} + + +SvxOpenGraphicDialog::SvxOpenGraphicDialog( const String& rTitle ) : + mpImpl( new SvxOpenGrf_Impl ) +{ + mpImpl->aFileDlg.SetTitle(rTitle); +} + + +SvxOpenGraphicDialog::~SvxOpenGraphicDialog() +{ +} + + +short SvxOpenGraphicDialog::Execute() +{ + USHORT nImpRet; + BOOL bQuitLoop(FALSE); + + while( bQuitLoop == FALSE && + mpImpl->aFileDlg.Execute() == ERRCODE_NONE ) + { + if( GetPath().Len() ) + { + GraphicFilter* pFilter = GraphicFilter::GetGraphicFilter(); + INetURLObject aObj( GetPath() ); + + // check whether we can load the graphic + String aCurFilter( GetCurrentFilter() ); + USHORT nFormatNum = pFilter->GetImportFormatNumber( aCurFilter ); + USHORT nRetFormat = 0; + USHORT nFound = USHRT_MAX; + + // non-local? + if ( INET_PROT_FILE != aObj.GetProtocol() ) + { + SfxMedium aMed( aObj.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ, TRUE ); + aMed.DownLoad(); + SvStream* pStream = aMed.GetInStream(); + + if( pStream ) + nImpRet = pFilter->CanImportGraphic( aObj.GetMainURL( INetURLObject::NO_DECODE ), *pStream, nFormatNum, &nRetFormat ); + else + nImpRet = pFilter->CanImportGraphic( aObj, nFormatNum, &nRetFormat ); + + if ( GRFILTER_OK != nImpRet ) + { + if ( !pStream ) + nImpRet = pFilter->CanImportGraphic( aObj, GRFILTER_FORMAT_DONTKNOW, &nRetFormat ); + else + nImpRet = pFilter->CanImportGraphic( aObj.GetMainURL( INetURLObject::NO_DECODE ), *pStream, + GRFILTER_FORMAT_DONTKNOW, &nRetFormat ); + } + } + else + { + if( (nImpRet=pFilter->CanImportGraphic( aObj, nFormatNum, &nRetFormat )) != GRFILTER_OK ) + nImpRet = pFilter->CanImportGraphic( aObj, GRFILTER_FORMAT_DONTKNOW, &nRetFormat ); + } + + if ( GRFILTER_OK == nImpRet ) + nFound = nRetFormat; + + // could not load? + if ( nFound == USHRT_MAX ) + { + WarningBox aWarningBox( NULL, WB_3DLOOK | WB_RETRY_CANCEL, String( SfxResId( SvxOpenGrfErr2ResId(nImpRet) ) ) ); + bQuitLoop = aWarningBox.Execute()==RET_RETRY ? FALSE : TRUE; + } + else + { + // setup appropriate filter (so next time, it will work) + if( pFilter->GetImportFormatCount() ) + { + String aFormatName(pFilter->GetImportFormatName(nFound)); + SetCurrentFilter(aFormatName); + } + + return nImpRet; + } + } + } + + // cancel + return -1; +} + + +void SvxOpenGraphicDialog::SetPath( const String& rPath ) +{ + mpImpl->aFileDlg.SetDisplayDirectory(rPath); +} + +void SvxOpenGraphicDialog::SetPath( const String& rPath, sal_Bool bLinkState ) +{ + SetPath(rPath); + AsLink(bLinkState); +} + + +void SvxOpenGraphicDialog::EnableLink( sal_Bool state ) +{ + if( mpImpl->xCtrlAcc.is() ) + { + try + { + mpImpl->xCtrlAcc->enableControl( ExtendedFilePickerElementIds::CHECKBOX_LINK, state ); + } + catch(IllegalArgumentException) + { +#ifdef DBG_UTIL + DBG_ERROR( "Cannot enable \"link\" checkbox" ); +#endif + } + } +} + + +void SvxOpenGraphicDialog::AsLink(sal_Bool bState) +{ + if( mpImpl->xCtrlAcc.is() ) + { + try + { + Any aAny; aAny <<= bState; + mpImpl->xCtrlAcc->setValue( ExtendedFilePickerElementIds::CHECKBOX_LINK, 0, aAny ); + } + catch(IllegalArgumentException) + { +#ifdef DBG_UTIL + DBG_ERROR( "Cannot check \"link\" checkbox" ); +#endif + } + } +} + + +sal_Bool SvxOpenGraphicDialog::IsAsLink() const +{ + try + { + if( mpImpl->xCtrlAcc.is() ) + { + Any aVal = mpImpl->xCtrlAcc->getValue( ExtendedFilePickerElementIds::CHECKBOX_LINK, 0 ); + DBG_ASSERT(aVal.hasValue(), "Value CBX_INSERT_AS_LINK not found"); + return aVal.hasValue() ? *(sal_Bool*) aVal.getValue() : sal_False; + } + } + catch(IllegalArgumentException) + { +#ifdef DBG_UTIL + DBG_ERROR( "Cannot access \"link\" checkbox" ); +#endif + } + + return sal_False; +} + + +int SvxOpenGraphicDialog::GetGraphic(Graphic& rGraphic) const +{ + return mpImpl->aFileDlg.GetGraphic(rGraphic); +} + + +String SvxOpenGraphicDialog::GetPath() const +{ + return mpImpl->aFileDlg.GetPath(); +} + + +String SvxOpenGraphicDialog::GetCurrentFilter() const +{ + return mpImpl->aFileDlg.GetCurrentFilter(); +} + + +void SvxOpenGraphicDialog::SetCurrentFilter(const String& rStr) +{ + mpImpl->aFileDlg.SetCurrentFilter(rStr); +} + +void SvxOpenGraphicDialog::SetControlHelpIds( const INT16* _pControlId, const INT32* _pHelpId ) +{ + mpImpl->aFileDlg.SetControlHelpIds( _pControlId, _pHelpId ); +} + +void SvxOpenGraphicDialog::SetDialogHelpId( const INT32 _nHelpId ) +{ + mpImpl->aFileDlg.SetDialogHelpId( _nHelpId ); +} diff --git a/sfx2/source/appl/panelist.hxx b/sfx2/source/appl/panelist.hxx new file mode 100644 index 000000000000..2406709aede9 --- /dev/null +++ b/sfx2/source/appl/panelist.hxx @@ -0,0 +1,50 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SFX_PANELIST_HXX + +#include <vcl/taskpanelist.hxx> // includes also vcl/window.hxx + +namespace sfx2 +{ + // source in newhelp.cxx + + void HandleTaskPaneList( Window* pWindow, BOOL bAddToList ); + // pWindow: just a system window or something which is child of a system window + + inline void AddToTaskPaneList( Window* pWindowToBeHandled ) + { + HandleTaskPaneList( pWindowToBeHandled, TRUE ); + } + + inline void RemoveFromTaskPaneList( Window* pWindowToBeHandled ) + { + HandleTaskPaneList( pWindowToBeHandled, FALSE ); + } +} + +#endif diff --git a/sfx2/source/appl/sfx.src b/sfx2/source/appl/sfx.src new file mode 100644 index 000000000000..7d4bb0db1726 --- /dev/null +++ b/sfx2/source/appl/sfx.src @@ -0,0 +1,133 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <sfx2/sfx.hrc> + +String STR_NONAME +{ + Text [ en-US ] = "Untitled" ; +}; + +String STR_NONE +{ + Text [ en-US ] = "- None -" ; +}; + +String STR_CLOSE +{ + Text [ en-US ] = "Close" ; +}; + +String STR_STYLE_FILTER_AUTO +{ + Text [ en-US ] = "Automatic" ; +}; + +String STR_STYLE_FILTER_USED +{ + Text [ en-US ] = "Applied Styles" ; +}; + + + +String STR_STYLE_FILTER_USERDEF +{ + Text [ en-US ] = "Custom Styles" ; +}; + +String STR_STYLE_FILTER_ALL +{ + Text [ en-US ] = "All Styles" ; +}; + +String STR_STANDARD +{ + Text [ en-US ] = "Standard" ; +}; +String STR_STANDARD_SHORTCUT +{ + Text [ en-US ] = "Standard" ; +}; + +String STR_SFX_FILTERNAME_ALL +{ + Text [ en-US ] = "All files (*.*)" ; +}; + +String STR_BYTES +{ + Text [ en-US ] = "Bytes" ; +}; + +String STR_KB +{ + Text [ en-US ] = "KB" ; +}; + +String STR_MB +{ + Text [ en-US ] = "MB" ; +}; + + +String STR_GB +{ + Text [ en-US ] = "GB" ; +}; + +String STR_UNDO +{ + Text [ en-US ] = "Undo: " ; +}; + +String STR_REDO +{ + Text [ en-US ] = "Re~do: " ; +}; + +String STR_REPEAT +{ + Text [ en-US ] = "~Repeat: " ; +}; + +String RID_STR_NEW_TASK +{ + Text [ en-US ] = "New task"; +}; +QueryBox MSG_QUERY_LASTVERSION +{ + Buttons = WB_YES_NO ; + DefButton = WB_DEF_NO ; + Message [ en-US ] = "Cancel all changes?" ; +}; + +// i66948 used in project scripting +String STR_ERRUNOEVENTBINDUNG +{ + Text [ en-US ] = "An appropriate component method %1\ncould not be found.\n\nCheck spelling of method name."; +}; + diff --git a/sfx2/source/appl/sfxhelp.cxx b/sfx2/source/appl/sfxhelp.cxx new file mode 100644 index 000000000000..b9ff344a1513 --- /dev/null +++ b/sfx2/source/appl/sfxhelp.cxx @@ -0,0 +1,1018 @@ + /************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" + +#include "sfxhelp.hxx" + +#include <algorithm> +#include <com/sun/star/uno/Reference.h> +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/frame/XComponentLoader.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <comphelper/processfactory.hxx> +#include <com/sun/star/awt/XWindow.hpp> +#include <com/sun/star/awt/XTopWindow.hpp> +#include <com/sun/star/awt/PosSize.hpp> +#include <com/sun/star/frame/XDesktop.hpp> +#include <com/sun/star/util/XURLTransformer.hpp> +#include <com/sun/star/frame/XDispatch.hpp> +#include <com/sun/star/frame/XDispatchProvider.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/frame/FrameSearchFlag.hpp> +#include <toolkit/helper/vclunohelper.hxx> +#include <com/sun/star/frame/XModuleManager.hpp> +#include <unotools/configmgr.hxx> +#include <unotools/configitem.hxx> +#include <svtools/helpopt.hxx> +#include <unotools/moduleoptions.hxx> +#include <tools/urlobj.hxx> +#include <unotools/configmgr.hxx> +#include <ucbhelper/content.hxx> +#include <unotools/pathoptions.hxx> +#include <rtl/ustring.hxx> +#include <osl/process.h> +#include <osl/file.hxx> +#include <unotools/bootstrap.hxx> +#include <rtl/uri.hxx> +#include <vcl/msgbox.hxx> +#include <svtools/ehdl.hxx> +#include <svtools/sfxecode.hxx> + +#define _SVSTDARR_STRINGSDTOR +#define _SVSTDARR_ULONGSSORT +#include <svl/svstdarr.hxx> + +#include "newhelp.hxx" +#include "sfxresid.hxx" +#include "helper.hxx" +#include "app.hrc" +#include <sfx2/sfxuno.hxx> +#include <vcl/svapp.hxx> +#include <sfx2/frame.hxx> + +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::lang; + +#define ERROR_TAG String( DEFINE_CONST_UNICODE("Error: ") ) +#define PATH_TAG String( DEFINE_CONST_UNICODE("\nPath: ") ) + +// class NoHelpErrorBox -------------------------------------------------- + +class NoHelpErrorBox : public ErrorBox +{ +public: + NoHelpErrorBox( Window* _pParent ); + + virtual void RequestHelp( const HelpEvent& rHEvt ); +}; + +NoHelpErrorBox::NoHelpErrorBox( Window* _pParent ) : + + ErrorBox( _pParent, WB_OK, String( SfxResId( RID_STR_HLPFILENOTEXIST ) ) ) +{ + // Error message: "No help available" +} + +void NoHelpErrorBox::RequestHelp( const HelpEvent& ) +{ + // do nothing, because no help available +} + +// ----------------------------------------------------------------------- + +#define STARTERLIST 0 + +rtl::OUString HelpLocaleString() +{ + static rtl::OUString aLocaleStr; + if (!aLocaleStr.getLength()) + { + // detect installed locale + Any aLocale = + ::utl::ConfigManager::GetConfigManager()->GetDirectConfigProperty( + ::utl::ConfigManager::LOCALE ); + aLocale >>= aLocaleStr; + bool bOk = aLocaleStr.getLength() != 0; + if ( bOk ) + { + rtl::OUString aBaseInstallPath; + // utl::Bootstrap::PathStatus aBaseLocateResult = + utl::Bootstrap::locateBaseInstallation(aBaseInstallPath); + static const char *szHelpPath = "/help/"; + + rtl::OUString sHelpPath = aBaseInstallPath + + rtl::OUString::createFromAscii(szHelpPath) + aLocaleStr; + osl::DirectoryItem aDirItem; + + if (!osl::DirectoryItem::get(sHelpPath, aDirItem) == osl::FileBase::E_None) + { + bOk = false; + String sLang(aLocaleStr); + xub_StrLen nSepPos = sLang.Search( '-' ); + if (nSepPos != STRING_NOTFOUND) + { + bOk = true; + sLang = sLang.Copy( 0, nSepPos ); + sHelpPath = aBaseInstallPath + + rtl::OUString::createFromAscii(szHelpPath) + sLang; + if (!osl::DirectoryItem::get(sHelpPath, aDirItem) == osl::FileBase::E_None) + bOk = false; + } + } + } + if (!bOk) + aLocaleStr = rtl::OUString( DEFINE_CONST_UNICODE("en") ); + } + return aLocaleStr; +} + +void AppendConfigToken_Impl( String& rURL, sal_Bool bQuestionMark ) +{ + ::rtl::OUString aLocaleStr(HelpLocaleString()); + + // query part exists? + if ( bQuestionMark ) + // no, so start with '?' + rURL += '?'; + else + // yes, so only append with '&' + rURL += '&'; + + // set parameters + rURL += DEFINE_CONST_UNICODE("Language="); + rURL += String( aLocaleStr ); + rURL += DEFINE_CONST_UNICODE("&System="); + rURL += SvtHelpOptions().GetSystem(); + +} + +// ----------------------------------------------------------------------- + +sal_Bool GetHelpAnchor_Impl( const String& _rURL, String& _rAnchor ) +{ + sal_Bool bRet = sal_False; + ::rtl::OUString sAnchor; + + // --> OD 2009-07-01 #159496# + // do not release solar mutex due to crash regarding accessibility +// ULONG nSolarCount = Application::ReleaseSolarMutex(); + // <-- + try + { + ::ucbhelper::Content aCnt( INetURLObject( _rURL ).GetMainURL( INetURLObject::NO_DECODE ), + Reference< ::com::sun::star::ucb::XCommandEnvironment > () ); + if ( ( aCnt.getPropertyValue( ::rtl::OUString::createFromAscii( "AnchorName" ) ) >>= sAnchor ) ) + { + + if ( sAnchor.getLength() > 0 ) + { + _rAnchor = String( sAnchor ); + bRet = sal_True; + } + } + else + { + DBG_ERRORFILE( "Property 'AnchorName' is missing" ); + } + } + catch( ::com::sun::star::uno::Exception& ) + { + } + // --> OD 2009-07-01 #159496# +// Application::AcquireSolarMutex( nSolarCount ); + // <-- + + return bRet; +} + +// ----------------------------------------------------------------------- + +class SfxHelpOptions_Impl : public utl::ConfigItem +{ +private: + SvULongsSort* m_pIds; + +public: + SfxHelpOptions_Impl(); + ~SfxHelpOptions_Impl(); + + BOOL HasId( ULONG nId ) { USHORT nDummy; return m_pIds ? m_pIds->Seek_Entry( nId, &nDummy ) : FALSE; } + virtual void Notify( const com::sun::star::uno::Sequence< rtl::OUString >& aPropertyNames ); + virtual void Commit(); +}; + +static Sequence< ::rtl::OUString > GetPropertyNames() +{ + static const char* aPropNames[] = + { + "HelpAgentStarterList", + }; + + const int nCount = sizeof( aPropNames ) / sizeof( const char* ); + Sequence< ::rtl::OUString > aNames( nCount ); + ::rtl::OUString* pNames = aNames.getArray(); + ::rtl::OUString* pEnd = pNames + aNames.getLength(); + int i = 0; + for ( ; pNames != pEnd; ++pNames ) + *pNames = ::rtl::OUString::createFromAscii( aPropNames[i++] ); + + return aNames; +} + +// ----------------------------------------------------------------------- + +SfxHelpOptions_Impl::SfxHelpOptions_Impl() + : ConfigItem( ::rtl::OUString::createFromAscii("Office.SFX/Help") ) + , m_pIds( NULL ) +{ + Sequence< ::rtl::OUString > aNames = GetPropertyNames(); + Sequence< Any > aValues = GetProperties( aNames ); + EnableNotification( aNames ); + const Any* pValues = aValues.getConstArray(); + DBG_ASSERT( aValues.getLength() == aNames.getLength(), "GetProperties failed" ); + if ( aValues.getLength() == aNames.getLength() ) + { + for ( int nProp = 0; nProp < aNames.getLength(); nProp++ ) + { + DBG_ASSERT( pValues[nProp].hasValue(), "property value missing" ); + if ( pValues[nProp].hasValue() ) + { + switch ( nProp ) + { + case STARTERLIST : + { + ::rtl::OUString aCodedList; + if ( pValues[nProp] >>= aCodedList ) + { + String aTmp( aCodedList ); + USHORT nCount = aTmp.GetTokenCount( ',' ); + m_pIds = new SvULongsSort(); + for ( USHORT n=0; n<nCount; n++ ) + m_pIds->Insert( (ULONG) aTmp.GetToken( n, ',' ).ToInt64() ); + } + else { + DBG_ERRORFILE( "Wrong property type!" ); + } + + break; + } + + default: + DBG_ERRORFILE( "Wrong property!" ); + break; + } + } + } + } +} + +SfxHelpOptions_Impl::~SfxHelpOptions_Impl() +{ + delete m_pIds; +} + + +void SfxHelpOptions_Impl::Notify( const com::sun::star::uno::Sequence< rtl::OUString >& ) +{ +} + +void SfxHelpOptions_Impl::Commit() +{ +} + +// class SfxHelp_Impl ---------------------------------------------------- + +class SfxHelp_Impl +{ +private: + sal_Bool m_bIsDebug; // environment variable "help_debug=1" + SfxHelpOptions_Impl* m_pOpt; // the options + ::std::vector< ::rtl::OUString > m_aModulesList; // list of all installed modules + void Load(); + +public: + SfxHelp_Impl( sal_Bool bDebug ); + ~SfxHelp_Impl(); + + SfxHelpOptions_Impl* GetOptions(); + String GetHelpText( ULONG nHelpId, const String& rModule ); // get "Active Help" + String GetHelpText( const rtl::OUString& aCommandURL, const String& rModule ); + sal_Bool HasModule( const ::rtl::OUString& rModule ); // module installed + sal_Bool IsHelpInstalled(); // module list not empty +}; + +SfxHelp_Impl::SfxHelp_Impl( sal_Bool bDebug ) : + + m_bIsDebug ( bDebug ), + m_pOpt ( NULL ) + +{ +} + +SfxHelp_Impl::~SfxHelp_Impl() +{ + delete m_pOpt; +} + +void SfxHelp_Impl::Load() +{ + // fill modules list + // create the help url (empty, without module and helpid) + String sHelpURL( DEFINE_CONST_UNICODE("vnd.sun.star.help://") ); + AppendConfigToken_Impl( sHelpURL, sal_True ); + + // open ucb content and get the list of the help modules + // the list contains strings with three tokens "ui title \t type \t url" + Sequence< ::rtl::OUString > aAllModulesList = SfxContentHelper::GetResultSet( sHelpURL ); + sal_Int32 nLen = aAllModulesList.getLength(); + m_aModulesList.reserve( nLen + 1 ); + const ::rtl::OUString* pBegin = aAllModulesList.getConstArray(); + const ::rtl::OUString* pEnd = pBegin + nLen; + for ( ; pBegin != pEnd; ++pBegin ) + { + // get one module string + String sModule( *pBegin ); + // extract the url + String sURL = sModule.GetToken( 2, '\t' ); + // insert the module (the host part of the "vnd.sun.star.help" url) + m_aModulesList.push_back( ::rtl::OUString( INetURLObject( sURL ).GetHost() ) ); + } +} + +String SfxHelp_Impl::GetHelpText( ULONG nHelpId, const String& rModule ) +{ + // create help url + String aHelpURL = SfxHelp::CreateHelpURL( nHelpId, rModule ); + // added 'active' parameter + aHelpURL.Insert( String( DEFINE_CONST_UNICODE("&Active=true") ), aHelpURL.SearchBackward( '#' ) ); + // load help string + return SfxContentHelper::GetActiveHelpString( aHelpURL ); +} + +String SfxHelp_Impl::GetHelpText( const rtl::OUString& aCommandURL, const String& rModule ) +{ + // create help url + String aHelpURL = SfxHelp::CreateHelpURL( aCommandURL, rModule ); + // added 'active' parameter + aHelpURL.Insert( String( DEFINE_CONST_UNICODE("&Active=true") ), aHelpURL.SearchBackward( '#' ) ); + // load help string + return SfxContentHelper::GetActiveHelpString( aHelpURL ); +} + +SfxHelpOptions_Impl* SfxHelp_Impl::GetOptions() +{ + // create if not exists + if ( !m_pOpt ) + m_pOpt = new SfxHelpOptions_Impl; + return m_pOpt; +} + +sal_Bool SfxHelp_Impl::HasModule( const ::rtl::OUString& rModule ) +{ + if ( !m_aModulesList.size() ) + Load(); + return ( ::std::find( m_aModulesList.begin(), m_aModulesList.end(), rModule ) != m_aModulesList.end() ); +} + +sal_Bool SfxHelp_Impl::IsHelpInstalled() +{ + if ( !m_aModulesList.size() ) + Load(); + return ( m_aModulesList.begin() != m_aModulesList.end() ); +} + +// class SfxHelp --------------------------------------------------------- + +SfxHelp::SfxHelp() : + + bIsDebug( sal_False ), + pImp ( NULL ) + +{ + // read the environment variable "HELP_DEBUG" + // if it's set, you will see debug output on active help + { + ::rtl::OUString sHelpDebug; + ::rtl::OUString sEnvVarName( RTL_CONSTASCII_USTRINGPARAM( "HELP_DEBUG" ) ); + osl_getEnvironment( sEnvVarName.pData, &sHelpDebug.pData ); + bIsDebug = ( 0 != sHelpDebug.getLength() ); + } + + pImp = new SfxHelp_Impl( bIsDebug ); + + ::rtl::OUString aLocaleStr = HelpLocaleString(); + + sal_Int32 nSepPos = aLocaleStr.indexOf( '_' ); + if ( nSepPos != -1 ) + { + aLanguageStr = aLocaleStr.copy( 0, nSepPos ); + aCountryStr = aLocaleStr.copy( nSepPos+1 ); + } + else + { + nSepPos = aLocaleStr.indexOf( '-' ); + if ( nSepPos != -1 ) + { + aLanguageStr = aLocaleStr.copy( 0, nSepPos ); + aCountryStr = aLocaleStr.copy( nSepPos+1 ); + } + else + { + aLanguageStr = aLocaleStr; + } + } +} + +SfxHelp::~SfxHelp() +{ + delete pImp; +} + +::rtl::OUString getDefaultModule_Impl() +{ + rtl::OUString sDefaultModule; + SvtModuleOptions aModOpt; + if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) ) + sDefaultModule = DEFINE_CONST_UNICODE("swriter"); + else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) ) + sDefaultModule = DEFINE_CONST_UNICODE("scalc"); + else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) ) + sDefaultModule = DEFINE_CONST_UNICODE("simpress"); + else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) ) + sDefaultModule = DEFINE_CONST_UNICODE("sdraw"); + else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SMATH ) ) + sDefaultModule = DEFINE_CONST_UNICODE("smath"); + else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SCHART ) ) + sDefaultModule = DEFINE_CONST_UNICODE("schart"); + else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SBASIC ) ) + sDefaultModule = DEFINE_CONST_UNICODE("sbasic"); + else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) ) + sDefaultModule = DEFINE_CONST_UNICODE("sdatabase"); + else + { + DBG_ERRORFILE( "getDefaultModule_Impl(): no module installed" ); + } + return sDefaultModule; +} + +::rtl::OUString getCurrentModuleIdentifier_Impl() +{ + ::rtl::OUString sIdentifier; + Reference < XFrame > xCurrentFrame; + Reference < XModuleManager > xModuleManager( ::comphelper::getProcessServiceFactory()->createInstance( + DEFINE_CONST_UNICODE("com.sun.star.frame.ModuleManager") ), UNO_QUERY ); + Reference < XDesktop > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance( + DEFINE_CONST_UNICODE("com.sun.star.frame.Desktop") ), UNO_QUERY ); + if ( xDesktop.is() ) + xCurrentFrame = xDesktop->getCurrentFrame(); + + if ( xCurrentFrame.is() && xModuleManager.is() ) + { + try + { + sIdentifier = xModuleManager->identify( xCurrentFrame ); + } + catch ( ::com::sun::star::frame::UnknownModuleException& ) + { + DBG_WARNING( "SfxHelp::getCurrentModuleIdentifier_Impl(): unknown module (help in help?)" ); + } + catch ( Exception& ) + { + DBG_ERRORFILE( "SfxHelp::getCurrentModuleIdentifier_Impl(): exception of XModuleManager::identify()" ); + } + } + + return sIdentifier; +} + +String SfxHelp::GetHelpModuleName_Impl() +{ + String sModuleName; + rtl::OUString aFactoryShortName; + rtl::OUString aModuleIdentifier = getCurrentModuleIdentifier_Impl(); + + if ( aModuleIdentifier.getLength() > 0 ) + { + try + { + Reference < XModuleManager > xModuleManager( + ::comphelper::getProcessServiceFactory()->createInstance( + DEFINE_CONST_UNICODE("com.sun.star.frame.ModuleManager") ), UNO_QUERY ); + Sequence< PropertyValue > lProps; + Reference< ::com::sun::star::container::XNameAccess > xCont( xModuleManager, UNO_QUERY); + if ( xCont.is() ) + xCont->getByName( aModuleIdentifier ) >>= lProps; + for ( sal_Int32 i = 0; i < lProps.getLength(); ++i ) + { + if ( lProps[i].Name.equalsAscii("ooSetupFactoryShortName") ) + { + lProps[i].Value >>= aFactoryShortName; + break; + } + } + } + catch ( Exception& ) + { + DBG_ERRORFILE( "SfxHelp::GetHelpModuleName_Impl(): exception of XNameAccess::getByName()" ); + } + } + + rtl::OUString sDefaultModule = getDefaultModule_Impl(); + if ( aFactoryShortName.getLength() > 0 ) + { + // Map some module identifiers to their "real" help module string. + if ( aFactoryShortName.equalsAscii( "chart2" ) ) + aFactoryShortName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "schart" ) ); + else if ( aFactoryShortName.equalsAscii( "BasicIDE" ) ) + aFactoryShortName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "sbasic" ) ); + else if ( aFactoryShortName.equalsAscii( "sweb" ) + || aFactoryShortName.equalsAscii( "sglobal" ) + || aFactoryShortName.equalsAscii( "swxform" ) ) + aFactoryShortName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "swriter" ) ); + else if ( aFactoryShortName.equalsAscii( "dbquery" ) + || aFactoryShortName.equalsAscii( "dbbrowser" ) + || aFactoryShortName.equalsAscii( "dbrelation" ) + || aFactoryShortName.equalsAscii( "dbtable" ) + || aFactoryShortName.equalsAscii( "dbapp" ) + || aFactoryShortName.equalsAscii( "dbreport" ) + || aFactoryShortName.equalsAscii( "swreport" ) + || aFactoryShortName.equalsAscii( "dbbrowser" ) + || aFactoryShortName.equalsAscii( "swform" ) ) + aFactoryShortName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "sdatabase" ) ); + else if ( aFactoryShortName.equalsAscii( "sbibliography" ) + || aFactoryShortName.equalsAscii( "StartModule" ) ) + aFactoryShortName = sDefaultModule; + } + else + aFactoryShortName = sDefaultModule; + + sModuleName = String( aFactoryShortName ); + return sModuleName; +} + +String SfxHelp::CreateHelpURL_Impl( ULONG nHelpId, const String& rModuleName ) +{ + String aModuleName( rModuleName ); + if ( aModuleName.Len() == 0 ) + aModuleName = getDefaultModule_Impl(); + + // build up the help URL + String aHelpURL; + if ( aTicket.Len() ) + { + // if there is a ticket, we are inside a plugin, so a special Help URL must be sent + aHelpURL = DEFINE_CONST_UNICODE("vnd.sun.star.cmd:help?"); + aHelpURL += DEFINE_CONST_UNICODE("HELP_Request_Mode=contextIndex&HELP_Session_Mode=context&HELP_CallMode=portal&HELP_Device=html"); + + if ( !nHelpId ) + { + // no help id -> start page + aHelpURL += DEFINE_CONST_UNICODE("&HELP_ContextID=start"); + } + else + { + aHelpURL += DEFINE_CONST_UNICODE("&HELP_ContextID="); + aHelpURL += String::CreateFromInt64( nHelpId ); + } + + aHelpURL += DEFINE_CONST_UNICODE("&HELP_ProgramID="); + aHelpURL += aModuleName; + aHelpURL += DEFINE_CONST_UNICODE("&HELP_User="); + aHelpURL += aUser; + aHelpURL += DEFINE_CONST_UNICODE("&HELP_Ticket="); + aHelpURL += aTicket; + aHelpURL += DEFINE_CONST_UNICODE("&HELP_Language="); + aHelpURL += aLanguageStr; + if ( aCountryStr.Len() ) + { + aHelpURL += DEFINE_CONST_UNICODE("&HELP_Country="); + aHelpURL += aCountryStr; + } + } + else + { + sal_Bool bHasAnchor = sal_False; + String aAnchor; + aHelpURL = String::CreateFromAscii("vnd.sun.star.help://"); + aHelpURL += aModuleName; + + if ( !nHelpId ) + aHelpURL += String::CreateFromAscii("/start"); + else + { + aHelpURL += '/'; + aHelpURL += String::CreateFromInt64( nHelpId ); + + String aTempURL = aHelpURL; + AppendConfigToken_Impl( aTempURL, sal_True ); + bHasAnchor = GetHelpAnchor_Impl( aTempURL, aAnchor ); + } + + AppendConfigToken_Impl( aHelpURL, sal_True ); + + if ( bHasAnchor ) + { + aHelpURL += '#'; + aHelpURL += aAnchor; + } + } + + return aHelpURL; +} + +String SfxHelp::CreateHelpURL_Impl( const String& aCommandURL, const String& rModuleName ) +{ + // build up the help URL + String aHelpURL; + sal_Bool bHasAnchor = sal_False; + String aAnchor; + + String aModuleName( rModuleName ); + if ( aModuleName.Len() == 0 ) + { + // no active module (quicklaunch?) -> detect default module + SvtModuleOptions aModOpt; + if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) ) + aModuleName = DEFINE_CONST_UNICODE("swriter"); + else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) ) + aModuleName = DEFINE_CONST_UNICODE("scalc"); + else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) ) + aModuleName = DEFINE_CONST_UNICODE("simpress"); + else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) ) + aModuleName = DEFINE_CONST_UNICODE("sdraw"); + else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SMATH ) ) + aModuleName = DEFINE_CONST_UNICODE("smath"); + else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SCHART ) ) + aModuleName = DEFINE_CONST_UNICODE("schart"); + else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SBASIC ) ) + aModuleName = DEFINE_CONST_UNICODE("sbasic"); + else + { + DBG_ERRORFILE( "no installed module found" ); + } + } + + aHelpURL = String::CreateFromAscii("vnd.sun.star.help://"); + aHelpURL += aModuleName; + + if ( !aCommandURL.Len() ) + aHelpURL += String::CreateFromAscii("/start"); + else + { + aHelpURL += '/'; + aHelpURL += String( rtl::Uri::encode( aCommandURL, + rtl_UriCharClassRelSegment, + rtl_UriEncodeKeepEscapes, + RTL_TEXTENCODING_ASCII_US )); + + String aTempURL = aHelpURL; + AppendConfigToken_Impl( aTempURL, sal_True ); + bHasAnchor = GetHelpAnchor_Impl( aTempURL, aAnchor ); + } + + AppendConfigToken_Impl( aHelpURL, sal_True ); + + if ( bHasAnchor ) + { + aHelpURL += '#'; + aHelpURL += aAnchor; + } + + return aHelpURL; +} + +SfxHelpWindow_Impl* impl_createHelp(Reference< XFrame >& rHelpTask , + Reference< XFrame >& rHelpContent) +{ + Reference < XFrame > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance( + DEFINE_CONST_UNICODE("com.sun.star.frame.Desktop") ), UNO_QUERY ); + + // otherwhise - create new help task + Reference< XFrame > xHelpTask = xDesktop->findFrame( + ::rtl::OUString(DEFINE_CONST_UNICODE("OFFICE_HELP_TASK")), + FrameSearchFlag::TASKS | FrameSearchFlag::CREATE); + if (!xHelpTask.is()) + return 0; + + // create all internal windows and sub frames ... + Reference< ::com::sun::star::awt::XWindow > xParentWindow = xHelpTask->getContainerWindow(); + Window* pParentWindow = VCLUnoHelper::GetWindow( xParentWindow ); + SfxHelpWindow_Impl* pHelpWindow = new SfxHelpWindow_Impl( xHelpTask, pParentWindow, WB_DOCKBORDER ); + Reference< ::com::sun::star::awt::XWindow > xHelpWindow = VCLUnoHelper::GetInterface( pHelpWindow ); + + Reference< XFrame > xHelpContent; + if (xHelpTask->setComponent( xHelpWindow, Reference< XController >() )) + { + // Customize UI ... + xHelpTask->setName( ::rtl::OUString(DEFINE_CONST_UNICODE("OFFICE_HELP_TASK")) ); + + Reference< XPropertySet > xProps(xHelpTask, UNO_QUERY); + if (xProps.is()) + xProps->setPropertyValue( + DEFINE_CONST_UNICODE("Title"), + makeAny(::rtl::OUString(String(SfxResId(STR_HELP_WINDOW_TITLE))))); + + pHelpWindow->setContainerWindow( xParentWindow ); + xParentWindow->setVisible(sal_True); + xHelpWindow->setVisible(sal_True); + + // This sub frame is created internaly (if we called new SfxHelpWindow_Impl() ...) + // It should exist :-) + xHelpContent = xHelpTask->findFrame(::rtl::OUString(DEFINE_CONST_UNICODE("OFFICE_HELP")), FrameSearchFlag::CHILDREN); + } + + if (!xHelpContent.is()) + delete pHelpWindow; + + xHelpContent->setName(::rtl::OUString(DEFINE_CONST_UNICODE("OFFICE_HELP"))); + + rHelpTask = xHelpTask; + rHelpContent = xHelpContent; + return pHelpWindow; +} + +BOOL SfxHelp::Start( const String& rURL, const Window* pWindow ) +{ + // check if help is available + String aHelpRootURL( DEFINE_CONST_OUSTRING("vnd.sun.star.help://") ); + AppendConfigToken_Impl( aHelpRootURL, sal_True ); + Sequence< ::rtl::OUString > aFactories = SfxContentHelper::GetResultSet( aHelpRootURL ); + if ( 0 == aFactories.getLength() ) + { + // no factories -> no help -> error message and return + NoHelpErrorBox aErrBox( const_cast< Window* >( pWindow ) ); + aErrBox.Execute(); + return FALSE; + } + + // check if it's an URL or a jump mark! + String aHelpURL(rURL ); + INetURLObject aParser (aHelpURL); + ::rtl::OUString sKeyword; + INetProtocol nProtocol = aParser.GetProtocol(); + if ( nProtocol != INET_PROT_VND_SUN_STAR_HELP ) + { + // #i90162 Accept anything that is not invalid as help id, as both + // uno: URLs used as commands/help ids in the Office and the scheme + // used in extension help ids (e.g. com.foocorp.foo-ext:FooDialogButton) + // are accepted as INET_PROT_UNO respectively INET_PROT_GENERIC + bool bAcceptAsURL = ( nProtocol != INET_PROT_NOT_VALID ); + + // #i94891 As in some extensions help ids like foo.bar.dummy without + // any : have been used that worked before the fix of #i90162 (see + // above) strings containing . will be also accepted to avoid brea- + // king the help of existing extensions. + if( !bAcceptAsURL ) + bAcceptAsURL = ( rURL.Search( '.' ) != STRING_NOTFOUND ); + + if ( bAcceptAsURL ) + { + aHelpURL = CreateHelpURL_Impl( rURL, GetHelpModuleName_Impl( ) ); + } + else + { + aHelpURL = CreateHelpURL_Impl( 0, GetHelpModuleName_Impl( ) ); + + // pb i91715: strings begin with ".HelpId:" are not words of the basic ide + // they are helpid-strings used by the testtool -> so we ignore them + static const String sHelpIdScheme( DEFINE_CONST_OUSTRING(".HelpId:") ); + if ( rURL.Search( sHelpIdScheme ) != 0 ) + sKeyword = ::rtl::OUString( rURL ); + } + } + + Reference < XFrame > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance( + DEFINE_CONST_UNICODE("com.sun.star.frame.Desktop") ), UNO_QUERY ); + + // check if help is still open + // If not - create new one and return acces directly + // to the internal sub frame, which shows the help content. + + // Note further: We search for this sub frame here directly instead of + // the real top level help task ... It's needed to have the same + // sub frame available - so we can use it for loading (which is done + // in both cases)! + + Reference< XFrame > xHelp = xDesktop->findFrame( + ::rtl::OUString(DEFINE_CONST_UNICODE("OFFICE_HELP_TASK")), + FrameSearchFlag::CHILDREN); + Reference< XFrame > xHelpContent = xDesktop->findFrame( + ::rtl::OUString(DEFINE_CONST_UNICODE("OFFICE_HELP")), + FrameSearchFlag::CHILDREN); + + SfxHelpWindow_Impl* pHelpWindow = 0; + if (!xHelp.is()) + pHelpWindow = impl_createHelp(xHelp, xHelpContent); + else + pHelpWindow = (SfxHelpWindow_Impl*)VCLUnoHelper::GetWindow(xHelp->getComponentWindow()); + if (!xHelp.is() || !xHelpContent.is() || !pHelpWindow) + return FALSE; + + pHelpWindow->SetHelpURL( aHelpURL ); + pHelpWindow->loadHelpContent(aHelpURL); + if ( sKeyword.getLength() > 0 ) + pHelpWindow->OpenKeyword( sKeyword ); + + Reference < ::com::sun::star::awt::XTopWindow > xTopWindow( xHelp->getContainerWindow(), UNO_QUERY ); + if ( xTopWindow.is() ) + xTopWindow->toFront(); + + return TRUE; +} + +BOOL SfxHelp::Start( ULONG nHelpId, const Window* pWindow ) +{ + String aHelpModuleName( GetHelpModuleName_Impl() ); + String aHelpURL = CreateHelpURL( nHelpId, aHelpModuleName ); + if ( pWindow && SfxContentHelper::IsHelpErrorDocument( aHelpURL ) ) + { + // no help found -> try with parent help id. + Window* pParent = pWindow->GetParent(); + while ( pParent ) + { + nHelpId = pParent->GetSmartUniqueOrHelpId().GetNum(); + aHelpURL = CreateHelpURL( nHelpId, aHelpModuleName ); + + if ( !SfxContentHelper::IsHelpErrorDocument( aHelpURL ) ) + break; + else + { + pParent = pParent->GetParent(); + if ( !pParent ) + // create help url of start page ( helpid == 0 -> start page) + aHelpURL = CreateHelpURL( 0, aHelpModuleName ); + } + } + } + + return Start( aHelpURL, pWindow ); +} + +XubString SfxHelp::GetHelpText( ULONG nHelpId, const Window* pWindow ) +{ + String aModuleName = GetHelpModuleName_Impl(); + String aHelpText = pImp->GetHelpText( nHelpId, aModuleName ); + ULONG nNewHelpId = 0; + + if ( pWindow && aHelpText.Len() == 0 ) + { + // no help text found -> try with parent help id. + Window* pParent = pWindow->GetParent(); + while ( pParent ) + { + nNewHelpId = pParent->GetHelpId(); + aHelpText = pImp->GetHelpText( nNewHelpId, aModuleName ); + + if ( aHelpText.Len() > 0 ) + pParent = NULL; + else + pParent = pParent->GetParent(); + } + + if ( bIsDebug && aHelpText.Len() == 0 ) + nNewHelpId = 0; + } + + if ( bIsDebug ) + { + aHelpText += DEFINE_CONST_UNICODE("\n\n"); + aHelpText += aModuleName; + aHelpText += DEFINE_CONST_UNICODE(" - "); + aHelpText += String::CreateFromInt64( nHelpId ); + if ( nNewHelpId ) + { + aHelpText += DEFINE_CONST_UNICODE(" - "); + aHelpText += String::CreateFromInt64( nNewHelpId ); + } + } + + return aHelpText; +} + +XubString SfxHelp::GetHelpText( const String& aCommandURL, const Window* ) +{ + String sModuleName = GetHelpModuleName_Impl(); + String sHelpText = pImp->GetHelpText( aCommandURL, sModuleName ); + + // add some debug information? + if ( bIsDebug ) + { + sHelpText += DEFINE_CONST_UNICODE("\n-------------\n"); + sHelpText += String( sModuleName ); + sHelpText += DEFINE_CONST_UNICODE(": "); + sHelpText += aCommandURL; + } + + return sHelpText; +} + +String SfxHelp::CreateHelpURL( ULONG nHelpId, const String& rModuleName ) +{ + String aURL; + SfxHelp* pHelp = SAL_STATIC_CAST( SfxHelp*, Application::GetHelp() ); + if ( pHelp ) + aURL = pHelp->CreateHelpURL_Impl( nHelpId, rModuleName ); + return aURL; +} + +String SfxHelp::CreateHelpURL( const String& aCommandURL, const String& rModuleName ) +{ + String aURL; + SfxHelp* pHelp = SAL_STATIC_CAST( SfxHelp*, Application::GetHelp() ); + if ( pHelp ) + aURL = pHelp->CreateHelpURL_Impl( aCommandURL, rModuleName ); + return aURL; +} + +void SfxHelp::OpenHelpAgent( SfxFrame*, ULONG nHelpId ) +{ + SfxHelp* pHelp = SAL_STATIC_CAST( SfxHelp*, Application::GetHelp() ); + if ( pHelp ) + pHelp->OpenHelpAgent( nHelpId ); +} + +void SfxHelp::OpenHelpAgent( ULONG nHelpId ) +{ + if ( SvtHelpOptions().IsHelpAgentAutoStartMode() ) + { +// SfxHelp* pHelp = SAL_STATIC_CAST( SfxHelp*, Application::GetHelp() ); +// if ( pHelp ) +// { + SfxHelpOptions_Impl *pOpt = pImp->GetOptions(); + if ( !pOpt->HasId( nHelpId ) ) + return; + + try + { + URL aURL; + aURL.Complete = CreateHelpURL_Impl( nHelpId, GetHelpModuleName_Impl() ); + Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance( + ::rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" ) ), UNO_QUERY ); + xTrans->parseStrict(aURL); + + Reference < XFrame > xCurrentFrame; + Reference < XDesktop > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance( + DEFINE_CONST_UNICODE("com.sun.star.frame.Desktop") ), UNO_QUERY ); + if ( xDesktop.is() ) + xCurrentFrame = xDesktop->getCurrentFrame(); + + Reference< XDispatchProvider > xDispProv( xCurrentFrame, UNO_QUERY ); + Reference< XDispatch > xHelpDispatch; + if ( xDispProv.is() ) + xHelpDispatch = xDispProv->queryDispatch( + aURL, ::rtl::OUString::createFromAscii("_helpagent"), + FrameSearchFlag::PARENT | FrameSearchFlag::SELF ); + + DBG_ASSERT( xHelpDispatch.is(), "OpenHelpAgent: could not get a dispatcher!" ); + if ( xHelpDispatch.is() ) + xHelpDispatch->dispatch( aURL, Sequence< PropertyValue >() ); + } + catch( const Exception& ) + { + DBG_ERRORFILE( "OpenHelpAgent: caught an exception while executing the dispatch!" ); + } +// } + } +} + +String SfxHelp::GetDefaultHelpModule() +{ + return getDefaultModule_Impl(); +} + +::rtl::OUString SfxHelp::GetCurrentModuleIdentifier() +{ + return getCurrentModuleIdentifier_Impl(); +} + diff --git a/sfx2/source/appl/sfxpicklist.cxx b/sfx2/source/appl/sfxpicklist.cxx new file mode 100644 index 000000000000..0074faac192f --- /dev/null +++ b/sfx2/source/appl/sfxpicklist.cxx @@ -0,0 +1,473 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" + +#include <com/sun/star/document/XDocumentProperties.hpp> +#include <unotools/historyoptions.hxx> +#include <unotools/useroptions.hxx> +#include <tools/urlobj.hxx> +#include <framework/menuconfiguration.hxx> +#include <svl/inethist.hxx> +#include <svl/stritem.hxx> +#include <svl/eitem.hxx> +#include <osl/file.hxx> +#include <unotools/localfilehelper.hxx> +#include <cppuhelper/implbase1.hxx> + +// ---------------------------------------------------------------------------- + +#include <sfx2/app.hxx> +#include "sfxpicklist.hxx" +#include <sfx2/sfxuno.hxx> +#include "sfxtypes.hxx" +#include <sfx2/request.hxx> +#include <sfx2/sfxsids.hrc> +#include <sfx2/sfx.hrc> +#include <sfx2/event.hxx> +#include <sfx2/objsh.hxx> +#include <sfx2/bindings.hxx> +#include "referers.hxx" +#include <sfx2/docfile.hxx> +#include "objshimp.hxx" +#include <sfx2/docfilt.hxx> + +#include <algorithm> + +// ---------------------------------------------------------------------------- + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::util; + +// ---------------------------------------------------------------------------- + +osl::Mutex* SfxPickList::pMutex = 0; +SfxPickList* SfxPickList::pUniqueInstance = 0; + +// ---------------------------------------------------------------------------- + +class StringLength : public ::cppu::WeakImplHelper1< XStringWidth > +{ + public: + StringLength() {} + virtual ~StringLength() {} + + // XStringWidth + sal_Int32 SAL_CALL queryStringWidth( const ::rtl::OUString& aString ) + throw (::com::sun::star::uno::RuntimeException) + { + return aString.getLength(); + } +}; + +// ---------------------------------------------------------------------------- + +osl::Mutex* SfxPickList::GetOrCreateMutex() +{ + if ( !pMutex ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if ( !pMutex ) + pMutex = new osl::Mutex; + } + + return pMutex; +} + +void SfxPickList::CreatePicklistMenuTitle( Menu* pMenu, USHORT nItemId, const String& aURLString, sal_uInt32 nNo ) +{ + String aPickEntry; + + if ( nNo < 9 ) + { + aPickEntry += '~'; + aPickEntry += String::CreateFromInt32( nNo + 1 ); + } + else if ( nNo == 9 ) + aPickEntry += DEFINE_CONST_UNICODE("1~0"); + else + aPickEntry += String::CreateFromInt32( nNo + 1 ); + aPickEntry += DEFINE_CONST_UNICODE(": "); + + INetURLObject aURL( aURLString ); + rtl::OUString aTipHelpText; + rtl::OUString aAccessibleName( aPickEntry ); + + if ( aURL.GetProtocol() == INET_PROT_FILE ) + { + // Do handle file URL differently => convert it to a system + // path and abbreviate it with a special function: + String aFileSystemPath( aURL.getFSysPath( INetURLObject::FSYS_DETECT ) ); + +// ::utl::LocalFileHelper::ConvertURLToPhysicalName( aURLString, aPhysicalName ); + + ::rtl::OUString aSystemPath( aFileSystemPath ); + ::rtl::OUString aCompactedSystemPath; + + aTipHelpText = aSystemPath; + aAccessibleName += aSystemPath; + oslFileError nError = osl_abbreviateSystemPath( aSystemPath.pData, &aCompactedSystemPath.pData, 46, NULL ); + if ( !nError ) + aPickEntry += String( aCompactedSystemPath ); + else + aPickEntry += aFileSystemPath; + + if ( aPickEntry.Len() > 50 ) + { + aPickEntry.Erase( 47 ); + aPickEntry += DEFINE_CONST_UNICODE("..."); + } + } + else + { + // Use INetURLObject to abbreviate all other URLs + String aShortURL; + aShortURL = aURL.getAbbreviated( m_xStringLength, 46, INetURLObject::DECODE_UNAMBIGUOUS ); + aPickEntry += aShortURL; + aTipHelpText = aURLString; + aAccessibleName += aURLString; + } + + // Set menu item text, tip help and accessible name + pMenu->SetItemText( nItemId, aPickEntry ); + pMenu->SetTipHelpText( nItemId, aTipHelpText ); + pMenu->SetAccessibleName( nItemId, aAccessibleName ); +} + +void SfxPickList::RemovePickListEntries() +{ + ::osl::MutexGuard aGuard( GetOrCreateMutex() ); + for ( sal_uInt32 i = 0; i < m_aPicklistVector.size(); i++ ) + delete m_aPicklistVector[i]; + m_aPicklistVector.clear(); +} + +SfxPickList::PickListEntry* SfxPickList::GetPickListEntry( sal_uInt32 nIndex ) +{ + OSL_ASSERT( m_aPicklistVector.size() > nIndex ); + + if ( nIndex < m_aPicklistVector.size() ) + return m_aPicklistVector[ nIndex ]; + else + return 0; +} + +SfxPickList* SfxPickList::GetOrCreate( const sal_uInt32 nMenuSize ) +{ + if ( !pUniqueInstance ) + { + ::osl::MutexGuard aGuard( GetOrCreateMutex() ); + if ( !pUniqueInstance ) + pUniqueInstance = new SfxPickList( nMenuSize ); + } + + return pUniqueInstance; +} + +SfxPickList* SfxPickList::Get() +{ + ::osl::MutexGuard aGuard( GetOrCreateMutex() ); + return pUniqueInstance; +} + +void SfxPickList::Delete() +{ + ::osl::MutexGuard aGuard( GetOrCreateMutex() ); + DELETEZ( pUniqueInstance ); +} + +SfxPickList::SfxPickList( sal_uInt32 nAllowedMenuSize ) : + m_nAllowedMenuSize( nAllowedMenuSize ) +{ + m_xStringLength = new StringLength; + m_nAllowedMenuSize = ::std::min( m_nAllowedMenuSize, (sal_uInt32)PICKLIST_MAXSIZE ); + StartListening( *SFX_APP() ); +} + +SfxPickList::~SfxPickList() +{ + RemovePickListEntries(); +} + +void SfxPickList::CreatePickListEntries() +{ + RemovePickListEntries(); + + // Einlesen der Pickliste + Sequence< Sequence< PropertyValue > > seqPicklist = SvtHistoryOptions().GetList( ePICKLIST ); + + sal_uInt32 nCount = seqPicklist.getLength(); + sal_uInt32 nEntries = ::std::min( m_nAllowedMenuSize, nCount ); + + for( sal_uInt32 nItem=0; nItem < nEntries; ++nItem ) + { + Sequence< PropertyValue > seqPropertySet = seqPicklist[ nItem ]; + + INetURLObject aURL; + ::rtl::OUString sURL; + ::rtl::OUString sFilter; + ::rtl::OUString sTitle; + ::rtl::OUString sPassword; + + sal_uInt32 nPropertyCount = seqPropertySet.getLength(); + for( sal_uInt32 nProperty=0; nProperty<nPropertyCount; ++nProperty ) + { + if( seqPropertySet[nProperty].Name == HISTORY_PROPERTYNAME_URL ) + { + seqPropertySet[nProperty].Value >>= sURL; + } + else if( seqPropertySet[nProperty].Name == HISTORY_PROPERTYNAME_FILTER ) + { + seqPropertySet[nProperty].Value >>= sFilter; + } + else if( seqPropertySet[nProperty].Name == HISTORY_PROPERTYNAME_TITLE ) + { + seqPropertySet[nProperty].Value >>= sTitle; + } + else if( seqPropertySet[nProperty].Name == HISTORY_PROPERTYNAME_PASSWORD ) + { + seqPropertySet[nProperty].Value >>= sPassword; + } + } + + aURL.SetSmartURL( sURL ); + aURL.SetPass( SfxStringDecode( sPassword ) ); + + PickListEntry *pPick = new PickListEntry( aURL.GetMainURL( INetURLObject::NO_DECODE ), sFilter, sTitle ); + m_aPicklistVector.push_back( pPick ); + } +} + +void SfxPickList::CreateMenuEntries( Menu* pMenu ) +{ + static sal_Bool bPickListMenuInitializing = sal_False; + + ::osl::MutexGuard aGuard( GetOrCreateMutex() ); + + if ( bPickListMenuInitializing ) // method is not reentrant! + return; + + bPickListMenuInitializing = sal_True; + CreatePickListEntries(); + + for ( sal_uInt16 nId = START_ITEMID_PICKLIST; nId <= END_ITEMID_PICKLIST; ++nId ) + pMenu->RemoveItem( pMenu->GetItemPos( nId ) ); + + if ( pMenu->GetItemType( pMenu->GetItemCount()-1 ) == MENUITEM_SEPARATOR ) + pMenu->RemoveItem( pMenu->GetItemCount()-1 ); + + if ( m_aPicklistVector.size() > 0 && + pMenu->GetItemType( pMenu->GetItemCount()-1 ) + != MENUITEM_SEPARATOR && m_nAllowedMenuSize ) + pMenu->InsertSeparator(); + + rtl::OUString aEmptyString; + for ( sal_uInt32 i = 0; i < m_aPicklistVector.size(); i++ ) + { + PickListEntry* pEntry = GetPickListEntry( i ); + + pMenu->InsertItem( (USHORT)(START_ITEMID_PICKLIST + i), aEmptyString ); + CreatePicklistMenuTitle( pMenu, (USHORT)(START_ITEMID_PICKLIST + i), pEntry->aName, i ); + } + + bPickListMenuInitializing = sal_False; +} + +void SfxPickList::ExecuteEntry( sal_uInt32 nIndex ) +{ + ::osl::ClearableMutexGuard aGuard( GetOrCreateMutex() ); + + PickListEntry *pPick = SfxPickList::Get()->GetPickListEntry( nIndex ); + + if ( pPick ) + { + SfxRequest aReq( SID_OPENDOC, SFX_CALLMODE_ASYNCHRON, SFX_APP()->GetPool() ); + aReq.AppendItem( SfxStringItem( SID_FILE_NAME, pPick->aName )); + aReq.AppendItem( SfxStringItem( SID_REFERER, DEFINE_CONST_UNICODE( SFX_REFERER_USER ) ) ); + aReq.AppendItem( SfxStringItem( SID_TARGETNAME, DEFINE_CONST_UNICODE("_default") ) ); + String aFilter( pPick->aFilter ); + aGuard.clear(); + + USHORT nPos=aFilter.Search('|'); + if( nPos != STRING_NOTFOUND ) + { + String aOptions(aFilter.Copy( nPos ).GetBuffer()+1); + aFilter.Erase( nPos ); + aReq.AppendItem( SfxStringItem(SID_FILE_FILTEROPTIONS, aOptions)); + } + + aReq.AppendItem(SfxStringItem( SID_FILTER_NAME, aFilter )); + aReq.AppendItem( SfxBoolItem( SID_TEMPLATE, sal_False ) ); + SFX_APP()->ExecuteSlot( aReq ); + } +} + +void SfxPickList::ExecuteMenuEntry( USHORT nId ) +{ + ExecuteEntry( (sal_uInt32)( nId - START_ITEMID_PICKLIST ) ); +} + +String SfxPickList::GetMenuEntryTitle( sal_uInt32 nIndex ) +{ + PickListEntry *pPick = SfxPickList::Get()->GetPickListEntry( nIndex ); + + if ( pPick ) + return pPick->aTitle; + else + return String(); +} + +void SfxPickList::Notify( SfxBroadcaster&, const SfxHint& rHint ) +{ + if ( rHint.IsA( TYPE( SfxStringHint ))) + { + SfxStringHint* pStringHint = (SfxStringHint*) &rHint; + + if ( pStringHint->GetId() == SID_OPENURL ) + INetURLHistory::GetOrCreate()->PutUrl( INetURLObject( pStringHint->GetObject() )); + } + + if ( rHint.IsA( TYPE( SfxEventHint ))) + { + SfxEventHint* pEventHint = PTR_CAST(SfxEventHint,&rHint); + // nur ObjectShell-bezogene Events mit Medium interessieren + SfxObjectShell* pDocSh = pEventHint->GetObjShell(); + if( !pDocSh ) + return; + + switch ( pEventHint->GetEventId() ) + { + case SFX_EVENT_CREATEDOC: + { + sal_Bool bAllowModif = pDocSh->IsEnableSetModified(); + if ( bAllowModif ) + pDocSh->EnableSetModified( sal_False ); + + using namespace ::com::sun::star; + uno::Reference<document::XDocumentProperties> xDocProps( + pDocSh->getDocProperties()); + if (xDocProps.is()) { + xDocProps->setAuthor( SvtUserOptions().GetFullName() ); + ::DateTime now; + xDocProps->setCreationDate( util::DateTime( + now.Get100Sec(), now.GetSec(), now.GetMin(), + now.GetHour(), now.GetDay(), now.GetMonth(), + now.GetYear() ) ); + } + + if ( bAllowModif ) + pDocSh->EnableSetModified( bAllowModif ); + } + break; + + case SFX_EVENT_OPENDOC: + { + SfxMedium *pMed = pDocSh->GetMedium(); + if( !pMed ) + return; + + // unbenannt-Docs und embedded-Docs nicht in History + if ( !pDocSh->HasName() || + SFX_CREATE_MODE_STANDARD != pDocSh->GetCreateMode() ) + return; + + // Hilfe nicht in History + INetURLObject aURL( pDocSh->IsDocShared() ? pDocSh->GetSharedFileURL() : ::rtl::OUString( pMed->GetOrigURL() ) ); + if ( aURL.GetProtocol() == INET_PROT_VND_SUN_STAR_HELP ) + return; + + ::rtl::OUString aTitle = pDocSh->GetTitle(SFX_TITLE_PICKLIST); + ::rtl::OUString aFilter; + const SfxFilter* pFilter = pMed->GetOrigFilter(); + if ( pFilter ) + aFilter = pFilter->GetFilterName(); + + // add to svtool history options + SvtHistoryOptions().AppendItem( eHISTORY, + aURL.GetURLNoPass( INetURLObject::NO_DECODE ), + aFilter, + aTitle, + SfxStringEncode( aURL.GetPass() ) ); + } + break; + + case SFX_EVENT_CLOSEDOC: + { + SfxMedium *pMed = pDocSh->GetMedium(); + if( !pMed ) + return; + + // unbenannt-Docs und embedded-Docs nicht in Pickliste + if ( !pDocSh->HasName() || + SFX_CREATE_MODE_STANDARD != pDocSh->GetCreateMode() ) + return; + + // Hilfe nicht in History + INetURLObject aURL( pDocSh->IsDocShared() ? pDocSh->GetSharedFileURL() : ::rtl::OUString( pMed->GetOrigURL() ) ); + if ( aURL.GetProtocol() == INET_PROT_VND_SUN_STAR_HELP ) + return; + + // only add r/w document into picklist + if ( pDocSh->IsReadOnly() || !pMed->IsUpdatePickList() ) + return; + + // add no document that forbids this (for example Message-Body) + SFX_ITEMSET_ARG( pMed->GetItemSet(), pPicklistItem, SfxBoolItem, SID_PICKLIST, sal_False ); + if ( + (pPicklistItem && !pPicklistItem->GetValue()) || + (!(pDocSh->Get_Impl()->bWaitingForPicklist) ) + ) + return; + + // ignore hidden documents + if ( !SfxViewFrame::GetFirst( pDocSh, TRUE ) ) + return; + + ::rtl::OUString aTitle = pDocSh->GetTitle(SFX_TITLE_PICKLIST); + ::rtl::OUString aFilter; + const SfxFilter* pFilter = pMed->GetOrigFilter(); + if ( pFilter ) + aFilter = pFilter->GetFilterName(); + + // add to svtool history options + SvtHistoryOptions().AppendItem( ePICKLIST, + aURL.GetURLNoPass( INetURLObject::NO_DECODE ), + aFilter, + aTitle, + SfxStringEncode( aURL.GetPass() ) ); + + pDocSh->Get_Impl()->bWaitingForPicklist = sal_False; + + if ( aURL.GetProtocol() == INET_PROT_FILE ) + Application::AddToRecentDocumentList( aURL.GetURLNoPass( INetURLObject::NO_DECODE ), (pFilter) ? pFilter->GetMimeType() : String() ); + } + break; + } + } +} diff --git a/sfx2/source/appl/shutdownicon.cxx b/sfx2/source/appl/shutdownicon.cxx new file mode 100644 index 000000000000..3fce25e7e0d6 --- /dev/null +++ b/sfx2/source/appl/shutdownicon.cxx @@ -0,0 +1,957 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" + +#include <shutdownicon.hxx> +#include <app.hrc> +#include <sfx2/app.hxx> +#include <vos/mutex.hxx> +#include <svtools/imagemgr.hxx> +#include <svtools/miscopt.hxx> +// #include <cmdlineargs.hxx> +#include <com/sun/star/task/XInteractionHandler.hpp> +#include <com/sun/star/frame/XDispatchResultListener.hpp> +#include <com/sun/star/frame/XNotifyingDispatch.hpp> +#include <com/sun/star/frame/XFramesSupplier.hpp> +#include <com/sun/star/frame/XComponentLoader.hpp> +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/util/XURLTransformer.hpp> +#include <com/sun/star/frame/XFramesSupplier.hpp> +#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp> +#include <com/sun/star/ui/dialogs/XFilterManager.hpp> +#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp> +#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp> +#include <com/sun/star/ui/dialogs/ControlActions.hpp> +#include <com/sun/star/document/MacroExecMode.hpp> +#include <com/sun/star/document/UpdateDocMode.hpp> +#include <sfx2/filedlghelper.hxx> +#include <sfx2/fcontnr.hxx> +#ifndef _UNOTOOLS_PROCESSFACTORY_HXX +#include <comphelper/processfactory.hxx> +#endif +#include <cppuhelper/compbase1.hxx> +#include <sfx2/dispatch.hxx> +#include <comphelper/extract.hxx> +#include <tools/urlobj.hxx> +#include <osl/security.hxx> +#include <osl/file.hxx> +#include <rtl/bootstrap.hxx> +#include <tools/link.hxx> +#ifdef UNX // need symlink +#include <unistd.h> +#include <errno.h> +#endif +#include <vcl/timer.hxx> + +#include "sfxresid.hxx" + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::ui::dialogs; +using namespace ::vos; +using namespace ::rtl; +using namespace ::sfx2; + +#ifdef ENABLE_QUICKSTART_APPLET +# if !defined(WIN32) && !defined(QUARTZ) +extern "C" { static void SAL_CALL thisModule() {} } +# endif +#endif + +class SfxNotificationListener_Impl : public cppu::WeakImplHelper1< XDispatchResultListener > +{ +public: + virtual void SAL_CALL dispatchFinished( const DispatchResultEvent& aEvent ) throw( RuntimeException ); + virtual void SAL_CALL disposing( const EventObject& aEvent ) throw( RuntimeException ); +}; + +void SAL_CALL SfxNotificationListener_Impl::dispatchFinished( const DispatchResultEvent& ) throw( RuntimeException ) +{ + ShutdownIcon::LeaveModalMode(); +} + +void SAL_CALL SfxNotificationListener_Impl::disposing( const EventObject& ) throw( RuntimeException ) +{ +} + +SFX_IMPL_XSERVICEINFO( ShutdownIcon, "com.sun.star.office.Quickstart", "com.sun.star.comp.desktop.QuickstartWrapper" ) \ +SFX_IMPL_ONEINSTANCEFACTORY( ShutdownIcon ); + +bool ShutdownIcon::bModalMode = false; +ShutdownIcon* ShutdownIcon::pShutdownIcon = NULL; + +// To remove conditionals +extern "C" { + static void disabled_initSystray() { } + static void disabled_deInitSystray() { } +} +#define DOSTRING( x ) #x +#define STRING( x ) DOSTRING( x ) + +bool ShutdownIcon::LoadModule( osl::Module **pModule, + oslGenericFunction *pInit, + oslGenericFunction *pDeInit ) +{ + if ( pModule ) + { + OSL_ASSERT ( pInit && pDeInit ); + *pInit = *pDeInit = NULL; + *pModule = NULL; + } + +#ifdef ENABLE_QUICKSTART_APPLET +# ifdef WIN32 + if ( pModule ) + { + *pInit = win32_init_sys_tray; + *pDeInit = win32_shutdown_sys_tray; + } + return true; +# elif defined QUARTZ + *pInit = aqua_init_systray; + *pDeInit = aqua_shutdown_systray; + return true; +# else // UNX + osl::Module *pPlugin; + pPlugin = new osl::Module(); + + oslGenericFunction pTmpInit = NULL; + oslGenericFunction pTmpDeInit = NULL; + if ( pPlugin->loadRelative( &thisModule, OUString (RTL_CONSTASCII_USTRINGPARAM( STRING( PLUGIN_NAME ) ) ) ) ) + { + pTmpInit = pPlugin->getFunctionSymbol( + OUString( RTL_CONSTASCII_USTRINGPARAM( "plugin_init_sys_tray" ) ) ); + pTmpDeInit = pPlugin->getFunctionSymbol( + OUString( RTL_CONSTASCII_USTRINGPARAM( "plugin_shutdown_sys_tray" ) ) ); + } + if ( !pTmpInit || !pTmpDeInit ) + { + delete pPlugin; + pPlugin = NULL; + } + if ( pModule ) + { + *pModule = pPlugin; + *pInit = pTmpInit; + *pDeInit = pTmpDeInit; + } + else + { + bool bRet = pPlugin != NULL; + delete pPlugin; + return bRet; + } +# endif // UNX +#endif // ENABLE_QUICKSTART_APPLET + if ( pModule ) + { + if ( !*pInit ) + *pInit = disabled_initSystray; + if ( !*pDeInit ) + *pDeInit = disabled_deInitSystray; + } + + return true; +} + +class IdleUnloader : Timer +{ + ::osl::Module *m_pModule; +public: + IdleUnloader (::osl::Module **pModule) : + m_pModule (*pModule) + { + *pModule = NULL; + Start(); + } + virtual void Timeout() + { + delete m_pModule; + delete this; + } +}; + +void ShutdownIcon::initSystray() +{ + if (m_bInitialized) + return; + m_bInitialized = true; + + (void) LoadModule( &m_pPlugin, &m_pInitSystray, &m_pDeInitSystray ); + m_bVeto = true; + m_pInitSystray(); +} + +void ShutdownIcon::deInitSystray() +{ + if (!m_bInitialized) + return; + + if (m_pDeInitSystray) + m_pDeInitSystray(); + + m_bVeto = false; + m_pInitSystray = 0; + m_pDeInitSystray = 0; + new IdleUnloader (&m_pPlugin); + + delete m_pFileDlg; + m_pFileDlg = NULL; + m_bInitialized = false; +} + + +ShutdownIcon::ShutdownIcon( Reference< XMultiServiceFactory > aSMgr ) : + ShutdownIconServiceBase( m_aMutex ), + m_bVeto ( false ), + m_bListenForTermination ( false ), + m_bSystemDialogs( false ), + m_pResMgr( NULL ), + m_pFileDlg( NULL ), + m_xServiceManager( aSMgr ), + m_pInitSystray( 0 ), + m_pDeInitSystray( 0 ), + m_pPlugin( 0 ), + m_bInitialized( false ) +{ + m_bSystemDialogs = SvtMiscOptions().UseSystemFileDialog(); +} + +ShutdownIcon::~ShutdownIcon() +{ + deInitSystray(); + new IdleUnloader (&m_pPlugin); +} + +// --------------------------------------------------------------------------- + +void ShutdownIcon::OpenURL( const ::rtl::OUString& aURL, const ::rtl::OUString& rTarget, const Sequence< PropertyValue >& aArgs ) +{ + if ( getInstance() && getInstance()->m_xDesktop.is() ) + { + Reference < XDispatchProvider > xDispatchProvider( getInstance()->m_xDesktop, UNO_QUERY ); + if ( xDispatchProvider.is() ) + { + com::sun::star::util::URL aDispatchURL; + aDispatchURL.Complete = aURL; + + Reference < com::sun::star::util::XURLTransformer > xURLTransformer( + ::comphelper::getProcessServiceFactory()->createInstance( OUString::createFromAscii("com.sun.star.util.URLTransformer") ), + com::sun::star::uno::UNO_QUERY ); + if ( xURLTransformer.is() ) + { + try + { + Reference< com::sun::star::frame::XDispatch > xDispatch; + + xURLTransformer->parseStrict( aDispatchURL ); + xDispatch = xDispatchProvider->queryDispatch( aDispatchURL, rTarget, 0 ); + if ( xDispatch.is() ) + xDispatch->dispatch( aDispatchURL, aArgs ); + } + catch ( com::sun::star::uno::RuntimeException& ) + { + throw; + } + catch ( com::sun::star::uno::Exception& ) + { + } + } + } + } +} + +// --------------------------------------------------------------------------- + +void ShutdownIcon::FileOpen() +{ + if ( getInstance() && getInstance()->m_xDesktop.is() ) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + EnterModalMode(); + getInstance()->StartFileDialog(); + } +} + +// --------------------------------------------------------------------------- + +void ShutdownIcon::FromTemplate() +{ + if ( getInstance() && getInstance()->m_xDesktop.is() ) + { + Reference < ::com::sun::star::frame::XFramesSupplier > xDesktop ( getInstance()->m_xDesktop, UNO_QUERY); + Reference < ::com::sun::star::frame::XFrame > xFrame( xDesktop->getActiveFrame() ); + if ( !xFrame.is() ) + xFrame = Reference < ::com::sun::star::frame::XFrame >( xDesktop, UNO_QUERY ); + + URL aTargetURL; + aTargetURL.Complete = OUString( RTL_CONSTASCII_USTRINGPARAM( "slot:5500" ) ); + Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance( rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" )), UNO_QUERY ); + xTrans->parseStrict( aTargetURL ); + + Reference < ::com::sun::star::frame::XDispatchProvider > xProv( xFrame, UNO_QUERY ); + Reference < ::com::sun::star::frame::XDispatch > xDisp; + if ( xProv.is() ) + { + if ( aTargetURL.Protocol.compareToAscii("slot:") == COMPARE_EQUAL ) + xDisp = xProv->queryDispatch( aTargetURL, ::rtl::OUString(), 0 ); + else + xDisp = xProv->queryDispatch( aTargetURL, ::rtl::OUString::createFromAscii("_blank"), 0 ); + } + if ( xDisp.is() ) + { + Sequence<PropertyValue> aArgs(1); + PropertyValue* pArg = aArgs.getArray(); + pArg[0].Name = rtl::OUString::createFromAscii("Referer"); + pArg[0].Value <<= ::rtl::OUString::createFromAscii("private:user"); + Reference< ::com::sun::star::frame::XNotifyingDispatch > xNotifyer( xDisp, UNO_QUERY ); + if ( xNotifyer.is() ) + { + EnterModalMode(); + xNotifyer->dispatchWithNotification( aTargetURL, aArgs, new SfxNotificationListener_Impl() ); + } + else + xDisp->dispatch( aTargetURL, aArgs ); + } + } +} + +// --------------------------------------------------------------------------- +#include <tools/rcid.h> +OUString ShutdownIcon::GetResString( int id ) +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + if( ! m_pResMgr ) + m_pResMgr = SfxResId::GetResMgr(); + ResId aResId( id, *m_pResMgr ); + aResId.SetRT( RSC_STRING ); + if( !m_pResMgr || !m_pResMgr->IsAvailable( aResId ) ) + return OUString(); + + UniString aRes( ResId(id, *m_pResMgr) ); + return OUString( aRes ); +} + +// --------------------------------------------------------------------------- + +OUString ShutdownIcon::GetUrlDescription( const OUString& aUrl ) +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + return OUString( SvFileInformationManager::GetDescription( INetURLObject( aUrl ) ) ); +} + +// --------------------------------------------------------------------------- + +void ShutdownIcon::StartFileDialog() +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + bool bDirty = ( m_bSystemDialogs != static_cast<bool>(SvtMiscOptions().UseSystemFileDialog()) ); + + if ( m_pFileDlg && bDirty ) + { + // Destroy instance as changing the system file dialog setting + // forces us to create a new FileDialogHelper instance! + delete m_pFileDlg; + m_pFileDlg = NULL; + } + + if ( !m_pFileDlg ) + m_pFileDlg = new FileDialogHelper( WB_OPEN | SFXWB_MULTISELECTION, String() ); + m_pFileDlg->StartExecuteModal( STATIC_LINK( this, ShutdownIcon, DialogClosedHdl_Impl ) ); +} + +// --------------------------------------------------------------------------- + +IMPL_STATIC_LINK( ShutdownIcon, DialogClosedHdl_Impl, FileDialogHelper*, EMPTYARG ) +{ + DBG_ASSERT( pThis->m_pFileDlg, "ShutdownIcon, DialogClosedHdl_Impl(): no file dialog" ); + + // use ctor for filling up filters automatically! #89169# + if ( ERRCODE_NONE == pThis->m_pFileDlg->GetError() ) + { + Reference< XFilePicker > xPicker = pThis->m_pFileDlg->GetFilePicker(); + + try + { + + if ( xPicker.is() ) + { + + Reference < XFilePickerControlAccess > xPickerControls ( xPicker, UNO_QUERY ); + Reference < XFilterManager > xFilterManager ( xPicker, UNO_QUERY ); + + Sequence< OUString > sFiles = xPicker->getFiles(); + int nFiles = sFiles.getLength(); + + int nArgs=3; + Sequence< PropertyValue > aArgs(3); + + Reference < com::sun::star::task::XInteractionHandler > xInteraction( + ::comphelper::getProcessServiceFactory()->createInstance( OUString::createFromAscii("com.sun.star.task.InteractionHandler") ), + com::sun::star::uno::UNO_QUERY ); + + aArgs[0].Name = OUString::createFromAscii( "InteractionHandler" ); + aArgs[0].Value <<= xInteraction; + + sal_Int16 nMacroExecMode = ::com::sun::star::document::MacroExecMode::USE_CONFIG; + aArgs[1].Name = OUString::createFromAscii( "MacroExecutionMode" ); + aArgs[1].Value <<= nMacroExecMode; + + sal_Int16 nUpdateDoc = ::com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG; + aArgs[2].Name = OUString::createFromAscii( "UpdateDocMode" ); + aArgs[2].Value <<= nUpdateDoc; + + // pb: #102643# use the filedlghelper to get the current filter name, + // because it removes the extensions before you get the filter name. + OUString aFilterName( pThis->m_pFileDlg->GetCurrentFilter() ); + + if ( xPickerControls.is() ) + { + + // Set readonly flag + + sal_Bool bReadOnly = sal_False; + + + xPickerControls->getValue( ExtendedFilePickerElementIds::CHECKBOX_READONLY, 0 ) >>= bReadOnly; + + // #95239#: Only set porperty if readonly is set to TRUE + + if ( bReadOnly ) + { + aArgs.realloc( ++nArgs ); + aArgs[nArgs-1].Name = OUString::createFromAscii( "ReadOnly" ); + aArgs[nArgs-1].Value <<= bReadOnly; + } + + // Get version string + + sal_Int32 iVersion = -1; + + xPickerControls->getValue( ExtendedFilePickerElementIds::LISTBOX_VERSION, ControlActions::GET_SELECTED_ITEM_INDEX ) >>= iVersion; + + if ( iVersion >= 0 ) + { + sal_Int16 uVersion = (sal_Int16)iVersion; + + aArgs.realloc( ++nArgs ); + aArgs[nArgs-1].Name = OUString::createFromAscii( "Version" ); + aArgs[nArgs-1].Value <<= uVersion; + } + + // Retrieve the current filter + + if ( !aFilterName.getLength() ) + xPickerControls->getValue( CommonFilePickerElementIds::LISTBOX_FILTER, ControlActions::GET_SELECTED_ITEM ) >>= aFilterName; + + } + + + // Convert UI filter name to internal filter name + + if ( aFilterName.getLength() ) + { + const SfxFilter* pFilter = SFX_APP()->GetFilterMatcher().GetFilter4UIName( aFilterName, 0, SFX_FILTER_NOTINFILEDLG ); + + if ( pFilter ) + { + aFilterName = pFilter->GetFilterName(); + + if ( aFilterName.getLength() ) + { + aArgs.realloc( ++nArgs ); + aArgs[nArgs-1].Name = OUString::createFromAscii( "FilterName" ); + aArgs[nArgs-1].Value <<= aFilterName; + } + } + } + + if ( 1 == nFiles ) + OpenURL( sFiles[0], OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ), aArgs ); + else + { + OUString aBaseDirURL = sFiles[0]; + if ( aBaseDirURL.getLength() > 0 && aBaseDirURL[aBaseDirURL.getLength()-1] != '/' ) + aBaseDirURL += OUString::createFromAscii("/"); + + int iFiles; + for ( iFiles = 1; iFiles < nFiles; iFiles++ ) + { + OUString aURL = aBaseDirURL; + aURL += sFiles[iFiles]; + OpenURL( aURL, OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ), aArgs ); + } + } + } + } + catch ( ... ) + { + } + } + +#ifdef WNT + // #103346 Destroy dialog to prevent problems with custom controls + // This fix is dependent on the dialog settings. Destroying the dialog here will + // crash the non-native dialog implementation! Therefore make this dependent on + // the settings. + if ( SvtMiscOptions().UseSystemFileDialog() ) + { + delete pThis->m_pFileDlg; + pThis->m_pFileDlg = NULL; + } +#endif + + LeaveModalMode(); + return 0; +} + +// --------------------------------------------------------------------------- + +void ShutdownIcon::addTerminateListener() +{ + ShutdownIcon* pInst = getInstance(); + if ( ! pInst) + return; + + if (pInst->m_bListenForTermination) + return; + + Reference< XDesktop > xDesktop = pInst->m_xDesktop; + if ( ! xDesktop.is()) + return; + + xDesktop->addTerminateListener( pInst ); + pInst->m_bListenForTermination = true; +} + +// --------------------------------------------------------------------------- + +void ShutdownIcon::terminateDesktop() +{ + ShutdownIcon* pInst = getInstance(); + if ( ! pInst) + return; + + Reference< XDesktop > xDesktop = pInst->m_xDesktop; + if ( ! xDesktop.is()) + return; + + // always remove ourselves as listener + xDesktop->removeTerminateListener( pInst ); + pInst->m_bListenForTermination = true; + + // terminate desktop only if no tasks exist + Reference< XFramesSupplier > xSupplier( xDesktop, UNO_QUERY ); + if ( xSupplier.is() ) + { + Reference< XIndexAccess > xTasks ( xSupplier->getFrames(), UNO_QUERY ); + if( xTasks.is() ) + { + if( xTasks->getCount() < 1 ) + xDesktop->terminate(); + } + } + + // remove the instance pointer + ShutdownIcon::pShutdownIcon = 0; +} + +// --------------------------------------------------------------------------- + +ShutdownIcon* ShutdownIcon::getInstance() +{ + OSL_ASSERT( pShutdownIcon ); + return pShutdownIcon; +} + +// --------------------------------------------------------------------------- + +ShutdownIcon* ShutdownIcon::createInstance() +{ + if (pShutdownIcon) + return pShutdownIcon; + + ShutdownIcon *pIcon = NULL; + try { + Reference< XMultiServiceFactory > xSMgr( comphelper::getProcessServiceFactory() ); + pIcon = new ShutdownIcon( xSMgr ); + pIcon->init (); + pShutdownIcon = pIcon; + } catch (...) { + delete pIcon; + } + + return pShutdownIcon; +} + +void ShutdownIcon::init() throw( ::com::sun::star::uno::Exception ) +{ + // access resource system and sfx only protected by solarmutex + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ResMgr *pResMgr = SfxResId::GetResMgr(); + + ::osl::ResettableMutexGuard aGuard( m_aMutex ); + m_pResMgr = pResMgr; + aGuard.clear(); + Reference < XDesktop > xDesktop( m_xServiceManager->createInstance( + DEFINE_CONST_UNICODE( "com.sun.star.frame.Desktop" )), + UNO_QUERY ); + aGuard.reset(); + m_xDesktop = xDesktop; +} + +// --------------------------------------------------------------------------- + +void SAL_CALL ShutdownIcon::disposing() +{ + m_xServiceManager = Reference< XMultiServiceFactory >(); + m_xDesktop = Reference< XDesktop >(); +} + +// --------------------------------------------------------------------------- + +// XEventListener +void SAL_CALL ShutdownIcon::disposing( const ::com::sun::star::lang::EventObject& ) + throw(::com::sun::star::uno::RuntimeException) +{ +} + +// --------------------------------------------------------------------------- + +// XTerminateListener +void SAL_CALL ShutdownIcon::queryTermination( const ::com::sun::star::lang::EventObject& ) +throw(::com::sun::star::frame::TerminationVetoException, ::com::sun::star::uno::RuntimeException) +{ + ::osl::ClearableMutexGuard aGuard( m_aMutex ); + + if ( m_bVeto ) + throw ::com::sun::star::frame::TerminationVetoException(); +} + + +// --------------------------------------------------------------------------- + +void SAL_CALL ShutdownIcon::notifyTermination( const ::com::sun::star::lang::EventObject& ) +throw(::com::sun::star::uno::RuntimeException) +{ +} + + +// --------------------------------------------------------------------------- + +void SAL_CALL ShutdownIcon::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any>& aArguments ) + throw( ::com::sun::star::uno::Exception ) +{ + ::osl::ResettableMutexGuard aGuard( m_aMutex ); + + // third argument only sets veto, everything else will be ignored! + if (aArguments.getLength() > 2) + { + sal_Bool bVeto = sal_True; + bVeto = ::cppu::any2bool(aArguments[2]); + m_bVeto = bVeto; + return; + } + + if ( aArguments.getLength() > 0 ) + { + if ( !ShutdownIcon::pShutdownIcon ) + { + try + { + sal_Bool bQuickstart = sal_False; + bQuickstart = ::cppu::any2bool( aArguments[0] ); + if( !bQuickstart && !GetAutostart() ) + return; + aGuard.clear(); + init (); + aGuard.reset(); + if ( !m_xDesktop.is() ) + return; + + /* Create a sub-classed instance - foo */ + ShutdownIcon::pShutdownIcon = this; + initSystray(); +#ifdef OS2 + // above win32 starts the quickstart thread, but we have + // quickstart running only when -quickstart is specified + // on command line (next boot). + // so if -quickstart was not specified, we cannot issue + // quickstart veto on shutdown. + if (bQuickstart) + { + // disable shutdown + ShutdownIcon::getInstance()->SetVeto( true ); + ShutdownIcon::getInstance()->addTerminateListener(); + } +#endif + } + catch(const ::com::sun::star::lang::IllegalArgumentException&) + { + } + } + } + if ( aArguments.getLength() > 1 ) + { + sal_Bool bAutostart = sal_False; + bAutostart = ::cppu::any2bool( aArguments[1] ); + if (bAutostart && !GetAutostart()) + SetAutostart( sal_True ); + if (!bAutostart && GetAutostart()) + SetAutostart( sal_False ); + } + +} + +// ------------------------------- + +void ShutdownIcon::EnterModalMode() +{ + bModalMode = TRUE; +} + +// ------------------------------- + +void ShutdownIcon::LeaveModalMode() +{ + bModalMode = FALSE; +} + +#ifdef WNT +// defined in shutdowniconw32.cxx +#elif defined(OS2) +// defined in shutdowniconOs2.cxx +#elif defined QUARTZ +// defined in shutdowniconaqua.cxx +#else +bool ShutdownIcon::IsQuickstarterInstalled() +{ +#ifndef ENABLE_QUICKSTART_APPLET + return false; +#else // !ENABLE_QUICKSTART_APPLET +#ifdef UNX + return LoadModule( NULL, NULL, NULL); +#endif // UNX +#endif // !ENABLE_QUICKSTART_APPLET +} +#endif // !WNT + +// --------------------------------------------------------------------------- + +#if defined (ENABLE_QUICKSTART_APPLET) && defined (UNX) +static OUString getDotAutostart( bool bCreate = false ) +{ + OUString aShortcut; + const char *pConfigHome; + if( (pConfigHome = getenv("XDG_CONFIG_HOME") ) ) + aShortcut = OStringToOUString( OString( pConfigHome ), RTL_TEXTENCODING_UTF8 ); + else + { + OUString aHomeURL; + osl::Security().getHomeDir( aHomeURL ); + ::osl::File::getSystemPathFromFileURL( aHomeURL, aShortcut ); + aShortcut += OUString( RTL_CONSTASCII_USTRINGPARAM( "/.config" ) ); + } + aShortcut += OUString( RTL_CONSTASCII_USTRINGPARAM( "/autostart" ) ); + if (bCreate) + { + OUString aShortcutUrl; + osl::File::getFileURLFromSystemPath( aShortcut, aShortcutUrl ); + osl::Directory::createPath( aShortcutUrl ); + } + return aShortcut; +} +#endif + +rtl::OUString ShutdownIcon::getShortcutName() +{ +#ifndef ENABLE_QUICKSTART_APPLET + return OUString(); +#else + + OUString aShortcutName( RTL_CONSTASCII_USTRINGPARAM( "StarOffice 6.0" ) ); + ResMgr* pMgr = SfxResId::GetResMgr(); + if( pMgr ) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + UniString aRes( SfxResId( STR_QUICKSTART_LNKNAME ) ); + aShortcutName = OUString( aRes ); + } +#ifdef WNT + aShortcutName += OUString( RTL_CONSTASCII_USTRINGPARAM( ".lnk" ) ); + + OUString aShortcut(GetAutostartFolderNameW32()); + aShortcut += OUString( RTL_CONSTASCII_USTRINGPARAM( "\\" ) ); + aShortcut += aShortcutName; +#else // UNX + OUString aShortcut = getDotAutostart(); + aShortcut += OUString( RTL_CONSTASCII_USTRINGPARAM( "/qstart.desktop" ) ); +#endif // UNX + return aShortcut; +#endif // ENABLE_QUICKSTART_APPLET +} + +bool ShutdownIcon::GetAutostart( ) +{ +#if defined(OS2) + return GetAutostartOs2( ); +#elif defined QUARTZ + return true; +#else + bool bRet = false; +#ifdef ENABLE_QUICKSTART_APPLET + OUString aShortcut( getShortcutName() ); + OUString aShortcutUrl; + osl::File::getFileURLFromSystemPath( aShortcut, aShortcutUrl ); + osl::File f( aShortcutUrl ); + osl::File::RC error = f.open( OpenFlag_Read ); + if( error == osl::File::E_None ) + { + f.close(); + bRet = true; + } +#endif // ENABLE_QUICKSTART_APPLET + return bRet; +#endif +} + +void ShutdownIcon::SetAutostart( bool bActivate ) +{ +#ifdef ENABLE_QUICKSTART_APPLET + OUString aShortcut( getShortcutName() ); + + if( bActivate && IsQuickstarterInstalled() ) + { +#ifdef WNT + EnableAutostartW32( aShortcut ); +#else // UNX + getDotAutostart( true ); + + OUString aPath( RTL_CONSTASCII_USTRINGPARAM("${BRAND_BASE_DIR}/share/xdg/qstart.desktop" ) ); + Bootstrap::expandMacros( aPath ); + + OUString aDesktopFile; + ::osl::File::getSystemPathFromFileURL( aPath, aDesktopFile ); + + OString aDesktopFileUnx = OUStringToOString( aDesktopFile, + osl_getThreadTextEncoding() ); + OString aShortcutUnx = OUStringToOString( aShortcut, + osl_getThreadTextEncoding() ); + if ((0 != symlink(aDesktopFileUnx, aShortcutUnx)) && (errno == EEXIST)) + { + unlink(aShortcutUnx); + symlink(aDesktopFileUnx, aShortcutUnx); + } + + ShutdownIcon *pIcon = ShutdownIcon::createInstance(); + if( pIcon ) + pIcon->initSystray(); +#endif // UNX + } + else + { + OUString aShortcutUrl; + ::osl::File::getFileURLFromSystemPath( aShortcut, aShortcutUrl ); + ::osl::File::remove( aShortcutUrl ); +#ifdef UNX + if (pShutdownIcon) + { + ShutdownIcon *pIcon = getInstance(); + pIcon->deInitSystray(); + } +#endif + } +#elif defined OS2 + SetAutostartOs2( bActivate ); +#else + (void)bActivate; // unused variable +#endif // ENABLE_QUICKSTART_APPLET +} + +static const ::sal_Int32 PROPHANDLE_TERMINATEVETOSTATE = 0; + +// XFastPropertySet +void SAL_CALL ShutdownIcon::setFastPropertyValue( ::sal_Int32 nHandle, + const ::com::sun::star::uno::Any& aValue ) + throw (::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::beans::PropertyVetoException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException) +{ + switch(nHandle) + { + case PROPHANDLE_TERMINATEVETOSTATE : + { + // use new value in case it's a valid information only + ::sal_Bool bState( sal_False ); + if (! (aValue >>= bState)) + return; + + m_bVeto = bState; + if (m_bVeto && ! m_bListenForTermination) + addTerminateListener(); + } + break; + + default : + throw ::com::sun::star::beans::UnknownPropertyException(); + } +} + +// XFastPropertySet +::com::sun::star::uno::Any SAL_CALL ShutdownIcon::getFastPropertyValue( ::sal_Int32 nHandle ) + throw (::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException) +{ + ::com::sun::star::uno::Any aValue; + switch(nHandle) + { + case PROPHANDLE_TERMINATEVETOSTATE : + { + bool bState = (m_bListenForTermination && m_bVeto); + aValue <<= bState; + } + break; + + default : + throw ::com::sun::star::beans::UnknownPropertyException(); + } + + return aValue; +} diff --git a/sfx2/source/appl/shutdownicon.hxx b/sfx2/source/appl/shutdownicon.hxx new file mode 100644 index 000000000000..d702f2a50977 --- /dev/null +++ b/sfx2/source/appl/shutdownicon.hxx @@ -0,0 +1,175 @@ + +#ifndef __SHUTDOWNICON_HXX__ +#define __SHUTDOWNICON_HXX__ + +#include <com/sun/star/frame/XTerminateListener.hpp> +#include <com/sun/star/frame/XDesktop.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XEventListener.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/beans/XFastPropertySet.hpp> +#ifndef _RTL_STRING_HXX +#include <rtl/string.hxx> +#endif +#ifndef _RTL_USTRING_HXX +#include <rtl/ustring.hxx> +#endif +#include <osl/mutex.hxx> +#include <osl/module.hxx> +#include <sfx2/sfxuno.hxx> +#include <cppuhelper/compbase4.hxx> +#include <sfx2/dllapi.h> + +class ResMgr; +namespace sfx2 +{ + class FileDialogHelper; +} + +typedef ::cppu::WeakComponentImplHelper4< + ::com::sun::star::lang::XInitialization, + ::com::sun::star::frame::XTerminateListener, + ::com::sun::star::lang::XServiceInfo, + ::com::sun::star::beans::XFastPropertySet > ShutdownIconServiceBase; + +#if defined(USE_APP_SHORTCUTS) +#define WRITER_URL "private:factory/swriter" +#define CALC_URL "private:factory/scalc" +#define IMPRESS_URL "private:factory/simpress" +#define IMPRESS_WIZARD_URL "private:factory/simpress?slot=6686" +#define DRAW_URL "private:factory/sdraw" +#define MATH_URL "private:factory/smath" +#define BASE_URL "private:factory/sdatabase?Interactive" +#define STARTMODULE_URL ".uno:ShowStartModule" +#endif + +class SFX2_DLLPUBLIC ShutdownIcon : public ShutdownIconServiceBase +{ + ::osl::Mutex m_aMutex; + bool m_bVeto; + bool m_bListenForTermination; + bool m_bSystemDialogs; + ResMgr* m_pResMgr; + sfx2::FileDialogHelper* m_pFileDlg; + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xServiceManager; + + static ShutdownIcon *pShutdownIcon; // one instance + + oslGenericFunction m_pInitSystray; + oslGenericFunction m_pDeInitSystray; + ::osl::Module *m_pPlugin; + + bool m_bInitialized; + void initSystray(); + void deInitSystray(); + + static bool LoadModule( osl::Module **pModule, + oslGenericFunction *pInit, + oslGenericFunction *pDeInit ); + static void EnterModalMode(); + static void LeaveModalMode(); + static rtl::OUString getShortcutName(); + + friend class SfxNotificationListener_Impl; + + public: + ShutdownIcon( ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > aSMgr ); + + virtual ~ShutdownIcon(); + + SFX_DECL_XSERVICEINFO + + static ShutdownIcon* getInstance(); + static ShutdownIcon* createInstance(); + + static void terminateDesktop(); + static void addTerminateListener(); + + static void FileOpen(); + static void OpenURL( const ::rtl::OUString& aURL, const ::rtl::OUString& rTarget, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& = + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >( 0 ) ); + static void FromTemplate(); + + static void SetAutostart( bool bActivate ); + static bool GetAutostart(); + static bool bModalMode; + + void init() throw( ::com::sun::star::uno::Exception ); + + static ::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleServiceFactory > + GetWrapperFactory( ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & xSMgr ); + static ::rtl::OUString GetImplementationName_static(); + + ::rtl::OUString GetResString( int id ); + ::rtl::OUString GetUrlDescription( const ::rtl::OUString& aUrl ); + + void SetVeto( bool bVeto ) { m_bVeto = bVeto;} + bool GetVeto() { return m_bVeto; } + + void StartFileDialog(); + sfx2::FileDialogHelper* GetFileDialog() const { return m_pFileDlg; } + static long DialogClosedHdl_Impl( ShutdownIcon*, sfx2::FileDialogHelper* ); + + static bool IsQuickstarterInstalled(); + + // Component Helper - force override + virtual void SAL_CALL disposing(); + + // XEventListener + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) + throw(::com::sun::star::uno::RuntimeException); + + // XTerminateListener + virtual void SAL_CALL queryTermination( const ::com::sun::star::lang::EventObject& aEvent ) + throw(::com::sun::star::frame::TerminationVetoException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL notifyTermination( const ::com::sun::star::lang::EventObject& aEvent ) + throw(::com::sun::star::uno::RuntimeException); + + // XInitialization + virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) + throw( ::com::sun::star::uno::Exception ); + + // XFastPropertySet + virtual void SAL_CALL setFastPropertyValue( ::sal_Int32 nHandle, + const ::com::sun::star::uno::Any& aValue ) + throw (::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::beans::PropertyVetoException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getFastPropertyValue( ::sal_Int32 nHandle ) + throw (::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDesktop > m_xDesktop; + +#ifdef WNT + static void EnableAutostartW32( const rtl::OUString &aShortcutName ); + static rtl::OUString GetAutostartFolderNameW32(); +#endif +#ifdef OS2 + static void SetAutostartOs2( bool bActivate ); + static bool GetAutostartOs2( ); +#endif +}; + +extern "C" { +# ifdef WNT + // builtin win32 systray + void win32_init_sys_tray(); + void win32_shutdown_sys_tray(); +# elif defined QUARTZ + void aqua_init_systray(); + void aqua_shutdown_systray(); +# endif + // external plugin systray impl. + void plugin_init_sys_tray(); + void plugin_shutdown_sys_tray(); +} + +#endif diff --git a/sfx2/source/appl/shutdowniconOs2.cxx b/sfx2/source/appl/shutdowniconOs2.cxx new file mode 100644 index 000000000000..936d6f925053 --- /dev/null +++ b/sfx2/source/appl/shutdowniconOs2.cxx @@ -0,0 +1,94 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#include <unotools/moduleoptions.hxx> + +#include <unotools/dynamicmenuoptions.hxx> + +#include "shutdownicon.hxx" +#include <comphelper/processfactory.hxx> +#include <com/sun/star/uno/Reference.h> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/task/XJob.hpp> +#include <com/sun/star/beans/NamedValue.hpp> + + +using namespace ::rtl; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::task; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; +using namespace ::osl; + +// +// This ObjectID must match the one created in WarpIN scripts!! +// +#define QUICKSTART_OBJID "OO2_QUICKSTART" + +bool ShutdownIcon::IsQuickstarterInstalled() +{ + HOBJECT hObject; + // Check quickstart icon presence + hObject = WinQueryObject( "<" QUICKSTART_OBJID ">"); + if (hObject) + return true; + // object not found, quickstart not available + return false; +} + +void ShutdownIcon::SetAutostartOs2( bool bActivate ) +{ + HOBJECT hObject; + + if( bActivate && IsQuickstarterInstalled() ) + { + // place quickstart shadow in the startup folder + hObject = WinCreateObject( "WPShadow", "dummy", + "OBJECTID=<" QUICKSTART_OBJID "_SHW>;SHADOWID=<" QUICKSTART_OBJID ">;", + "<WP_START>", + CO_UPDATEIFEXISTS); + } + else + { + // remove quickstart shadow from the startup folder + hObject = WinQueryObject( "<" QUICKSTART_OBJID "_SHW>"); + if (hObject) + WinDestroyObject( hObject); + } +} + +bool ShutdownIcon::GetAutostartOs2( ) +{ + // check for quickstart shadow in the startup folder + if (WinQueryObject( "<" QUICKSTART_OBJID "_SHW>")) + return true; + else + return false; +} + + diff --git a/sfx2/source/appl/shutdowniconaqua.mm b/sfx2/source/appl/shutdowniconaqua.mm new file mode 100644 index 000000000000..14f12c79b53b --- /dev/null +++ b/sfx2/source/appl/shutdowniconaqua.mm @@ -0,0 +1,510 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" + +#include "unotools/moduleoptions.hxx" +#include "unotools/dynamicmenuoptions.hxx" +#include "unotools/historyoptions.hxx" +#include "tools/urlobj.hxx" +#include "osl/file.h" +#include "comphelper/sequenceashashmap.hxx" +#include "vos/mutex.hxx" +#include "sfx2/app.hxx" +#include "app.hrc" +#define USE_APP_SHORTCUTS +#include "shutdownicon.hxx" + +#include "com/sun/star/util/XStringWidth.hpp" + +#include "cppuhelper/implbase1.hxx" + +#include <set> +#include <vector> + +#include "premac.h" +#include <Cocoa/Cocoa.h> +#include "postmac.h" + +using namespace ::rtl; +using namespace ::osl; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::task; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::util; + +#define MI_OPEN 1 +#define MI_WRITER 2 +#define MI_CALC 3 +#define MI_IMPRESS 4 +#define MI_DRAW 5 +#define MI_BASE 6 +#define MI_MATH 7 +#define MI_TEMPLATE 8 +#define MI_STARTMODULE 9 + +@interface QSMenuExecute : NSObject +{ +} +-(void)executeMenuItem: (NSMenuItem*)pItem; +-(void)dockIconClicked: (NSObject*)pSender; +@end + +@implementation QSMenuExecute +-(void)executeMenuItem: (NSMenuItem*)pItem +{ + switch( [pItem tag] ) + { + case MI_OPEN: + ShutdownIcon::FileOpen(); + break; + case MI_WRITER: + ShutdownIcon::OpenURL( OUString( RTL_CONSTASCII_USTRINGPARAM( WRITER_URL ) ), OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ) ); + break; + case MI_CALC: + ShutdownIcon::OpenURL( OUString( RTL_CONSTASCII_USTRINGPARAM( CALC_URL ) ), OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ) ); + break; + case MI_IMPRESS: + ShutdownIcon::OpenURL( OUString( RTL_CONSTASCII_USTRINGPARAM( IMPRESS_URL ) ), OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ) ); + break; + case MI_DRAW: + ShutdownIcon::OpenURL( OUString( RTL_CONSTASCII_USTRINGPARAM( DRAW_URL ) ), OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ) ); + break; + case MI_BASE: + ShutdownIcon::OpenURL( OUString( RTL_CONSTASCII_USTRINGPARAM( BASE_URL ) ), OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ) ); + break; + case MI_MATH: + ShutdownIcon::OpenURL( OUString( RTL_CONSTASCII_USTRINGPARAM( MATH_URL ) ), OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ) ); + break; + case MI_TEMPLATE: + ShutdownIcon::FromTemplate(); + break; + case MI_STARTMODULE: + ShutdownIcon::OpenURL( OUString( RTL_CONSTASCII_USTRINGPARAM( STARTMODULE_URL ) ), OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ) ); + break; + default: + break; + } +} + +-(void)dockIconClicked: (NSObject*)pSender +{ + // start start module + ShutdownIcon::OpenURL( OUString( RTL_CONSTASCII_USTRINGPARAM( STARTMODULE_URL ) ), OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ) ); +} + +@end + +bool ShutdownIcon::IsQuickstarterInstalled() +{ + return true; +} + +static NSMenuItem* pDefMenu = nil, *pDockSubMenu = nil; +static QSMenuExecute* pExecute = nil; + +static std::set< OUString > aShortcuts; + +static NSString* getAutoreleasedString( const rtl::OUString& rStr ) +{ + return [[[NSString alloc] initWithCharacters: rStr.getStr() length: rStr.getLength()] autorelease]; +} + +struct RecentMenuEntry +{ + rtl::OUString aURL; + rtl::OUString aFilter; + rtl::OUString aTitle; + rtl::OUString aPassword; +}; + +class RecentFilesStringLength : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XStringWidth > +{ + public: + RecentFilesStringLength() {} + virtual ~RecentFilesStringLength() {} + + // XStringWidth + sal_Int32 SAL_CALL queryStringWidth( const ::rtl::OUString& aString ) + throw (::com::sun::star::uno::RuntimeException) + { + return aString.getLength(); + } +}; + +@interface RecentMenuDelegate : NSObject +{ + std::vector< RecentMenuEntry >* m_pRecentFilesItems; +} +-(id)init; +-(void)dealloc; +-(void)menuNeedsUpdate:(NSMenu *)menu; +-(void)executeRecentEntry: (NSMenuItem*)item; +@end + +@implementation RecentMenuDelegate +-(id)init +{ + if( (self = [super init]) ) + { + m_pRecentFilesItems = new std::vector< RecentMenuEntry >(); + } + return self; +} + +-(void)dealloc +{ + delete m_pRecentFilesItems; + [super dealloc]; +} + +-(void)menuNeedsUpdate:(NSMenu *)menu +{ + // clear menu + int nItems = [menu numberOfItems]; + while( nItems -- ) + [menu removeItemAtIndex: 0]; + + // update recent item list + Sequence< Sequence< PropertyValue > > aHistoryList( SvtHistoryOptions().GetList( ePICKLIST ) ); + + int nPickListMenuItems = ( aHistoryList.getLength() > 99 ) ? 99 : aHistoryList.getLength(); + + m_pRecentFilesItems->clear(); + if( ( nPickListMenuItems > 0 ) ) + { + for ( int i = 0; i < nPickListMenuItems; i++ ) + { + Sequence< PropertyValue >& rPickListEntry = aHistoryList[i]; + RecentMenuEntry aRecentFile; + + for ( int j = 0; j < rPickListEntry.getLength(); j++ ) + { + Any a = rPickListEntry[j].Value; + + if ( rPickListEntry[j].Name == HISTORY_PROPERTYNAME_URL ) + a >>= aRecentFile.aURL; + else if ( rPickListEntry[j].Name == HISTORY_PROPERTYNAME_FILTER ) + a >>= aRecentFile.aFilter; + else if ( rPickListEntry[j].Name == HISTORY_PROPERTYNAME_TITLE ) + a >>= aRecentFile.aTitle; + else if ( rPickListEntry[j].Name == HISTORY_PROPERTYNAME_PASSWORD ) + a >>= aRecentFile.aPassword; + } + + m_pRecentFilesItems->push_back( aRecentFile ); + } + } + + // insert new recent items + for ( sal_uInt32 i = 0; i < m_pRecentFilesItems->size(); i++ ) + { + rtl::OUString aMenuTitle; + INetURLObject aURL( (*m_pRecentFilesItems)[i].aURL ); + + if ( aURL.GetProtocol() == INET_PROT_FILE ) + { + // Do handle file URL differently => convert it to a system + // path and abbreviate it with a special function: + String aFileSystemPath( aURL.getFSysPath( INetURLObject::FSYS_DETECT ) ); + + ::rtl::OUString aSystemPath( aFileSystemPath ); + ::rtl::OUString aCompactedSystemPath; + + oslFileError nError = osl_abbreviateSystemPath( aSystemPath.pData, &aCompactedSystemPath.pData, 46, NULL ); + if ( !nError ) + aMenuTitle = String( aCompactedSystemPath ); + else + aMenuTitle = aSystemPath; + } + else + { + // Use INetURLObject to abbreviate all other URLs + Reference< XStringWidth > xStringLength( new RecentFilesStringLength() ); + aMenuTitle = aURL.getAbbreviated( xStringLength, 46, INetURLObject::DECODE_UNAMBIGUOUS ); + } + + NSMenuItem* pNewItem = [[NSMenuItem alloc] initWithTitle: getAutoreleasedString( aMenuTitle ) + action: @selector(executeRecentEntry:) + keyEquivalent: @""]; + [pNewItem setTag: i]; + [pNewItem setTarget: self]; + [pNewItem setEnabled: YES]; + [menu addItem: pNewItem]; + [pNewItem autorelease]; + } +} + +-(void)executeRecentEntry: (NSMenuItem*)item +{ + sal_Int32 nIndex = [item tag]; + if( ( nIndex >= 0 ) && ( nIndex < static_cast<sal_Int32>( m_pRecentFilesItems->size() ) ) ) + { + const RecentMenuEntry& rRecentFile = (*m_pRecentFilesItems)[ nIndex ]; + int NUM_OF_PICKLIST_ARGS = 3; + Sequence< PropertyValue > aArgsList( NUM_OF_PICKLIST_ARGS ); + + aArgsList[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Referer" )); + aArgsList[0].Value = makeAny( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:user" ) ) ); + + // documents in the picklist will never be opened as templates + aArgsList[1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AsTemplate" )); + aArgsList[1].Value = makeAny( (sal_Bool) sal_False ); + + ::rtl::OUString aFilter( rRecentFile.aFilter ); + sal_Int32 nPos = aFilter.indexOf( '|' ); + if ( nPos >= 0 ) + { + rtl::OUString aFilterOptions; + + if ( nPos < ( aFilter.getLength() - 1 ) ) + aFilterOptions = aFilter.copy( nPos+1 ); + + aArgsList[2].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterOptions" )); + aArgsList[2].Value = makeAny( aFilterOptions ); + + aFilter = aFilter.copy( 0, nPos-1 ); + aArgsList.realloc( ++NUM_OF_PICKLIST_ARGS ); + } + + aArgsList[NUM_OF_PICKLIST_ARGS-1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" )); + aArgsList[NUM_OF_PICKLIST_ARGS-1].Value = makeAny( aFilter ); + + ShutdownIcon::OpenURL( rRecentFile.aURL, OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ), aArgsList ); + } +} +@end + +static RecentMenuDelegate* pRecentDelegate = nil; + +static rtl::OUString getShortCut( const rtl::OUString i_rTitle ) +{ + // create shortcut + rtl::OUString aKeyEquiv; + for( sal_Int32 nIndex = 0; nIndex < i_rTitle.getLength(); nIndex++ ) + { + rtl::OUString aShortcut( i_rTitle.copy( nIndex, 1 ).toAsciiLowerCase() ); + if( aShortcuts.find( aShortcut ) == aShortcuts.end() ) + { + aShortcuts.insert( aShortcut ); + aKeyEquiv = aShortcut; + break; + } + } + + return aKeyEquiv; +} + +static void appendMenuItem( NSMenu* i_pMenu, NSMenu* i_pDockMenu, const rtl::OUString& i_rTitle, int i_nTag, const rtl::OUString& i_rKeyEquiv ) +{ + if( ! i_rTitle.getLength() ) + return; + + NSMenuItem* pItem = [[NSMenuItem alloc] initWithTitle: getAutoreleasedString( i_rTitle ) + action: @selector(executeMenuItem:) + keyEquivalent: (i_rKeyEquiv.getLength() ? getAutoreleasedString( i_rKeyEquiv ) : @"") + ]; + [pItem setTag: i_nTag]; + [pItem setTarget: pExecute]; + [pItem setEnabled: YES]; + [i_pMenu addItem: pItem]; + + if( i_pDockMenu ) + { + // create a similar entry in the dock menu + pItem = [[NSMenuItem alloc] initWithTitle: getAutoreleasedString( i_rTitle ) + action: @selector(executeMenuItem:) + keyEquivalent: @"" + ]; + [pItem setTag: i_nTag]; + [pItem setTarget: pExecute]; + [pItem setEnabled: YES]; + [i_pDockMenu addItem: pItem]; + } +} + +static void appendRecentMenu( NSMenu* i_pMenu, NSMenu* i_pDockMenu, const String& i_rTitle ) +{ + if( ! pRecentDelegate ) + pRecentDelegate = [[RecentMenuDelegate alloc] init]; + + NSMenuItem* pItem = [i_pMenu addItemWithTitle: getAutoreleasedString( i_rTitle ) + action: @selector(executeMenuItem:) + keyEquivalent: @"" + ]; + [pItem setEnabled: YES]; + NSMenu* pRecentMenu = [[NSMenu alloc] initWithTitle: getAutoreleasedString( i_rTitle ) ]; + [pRecentMenu setDelegate: pRecentDelegate]; + [pRecentMenu setAutoenablesItems: NO]; + [pItem setSubmenu: pRecentMenu]; + + if( i_pDockMenu ) + { + // create a similar entry in the dock menu + pItem = [i_pDockMenu addItemWithTitle: getAutoreleasedString( i_rTitle ) + action: @selector(executeMenuItem:) + keyEquivalent: @"" + ]; + [pItem setEnabled: YES]; + pRecentMenu = [[NSMenu alloc] initWithTitle: getAutoreleasedString( i_rTitle ) ]; + [pRecentMenu setDelegate: pRecentDelegate]; + [pRecentMenu setAutoenablesItems: NO]; + [pItem setSubmenu: pRecentMenu]; + } +} + + +extern "C" +{ + +void aqua_init_systray() +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + ShutdownIcon *pShutdownIcon = ShutdownIcon::getInstance(); + if( ! pShutdownIcon ) + return; + + // disable shutdown + pShutdownIcon->SetVeto( true ); + pShutdownIcon->addTerminateListener(); + + if( ! pDefMenu ) + { + if( [NSApp respondsToSelector: @selector(addFallbackMenuItem:)] ) + { + aShortcuts.clear(); + + pExecute = [[QSMenuExecute alloc] init]; + pDefMenu = [[NSMenuItem alloc] initWithTitle: getAutoreleasedString( pShutdownIcon->GetResString( STR_QUICKSTART_FILE ) ) action: NULL keyEquivalent: @""]; + pDockSubMenu = [[NSMenuItem alloc] initWithTitle: getAutoreleasedString( pShutdownIcon->GetResString( STR_QUICKSTART_FILE ) ) action: NULL keyEquivalent: @""]; + NSMenu* pMenu = [[NSMenu alloc] initWithTitle: getAutoreleasedString( pShutdownIcon->GetResString( STR_QUICKSTART_FILE ) )]; + [pMenu setAutoenablesItems: NO]; + NSMenu* pDockMenu = [[NSMenu alloc] initWithTitle: getAutoreleasedString( pShutdownIcon->GetResString( STR_QUICKSTART_FILE ) )]; + [pDockMenu setAutoenablesItems: NO]; + + // collect the URLs of the entries in the File/New menu + SvtModuleOptions aModuleOptions; + std::set< rtl::OUString > aFileNewAppsAvailable; + SvtDynamicMenuOptions aOpt; + Sequence < Sequence < PropertyValue > > aNewMenu = aOpt.GetMenu( E_NEWMENU ); + const rtl::OUString sURLKey( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ); + + const Sequence< PropertyValue >* pNewMenu = aNewMenu.getConstArray(); + const Sequence< PropertyValue >* pNewMenuEnd = aNewMenu.getConstArray() + aNewMenu.getLength(); + for ( ; pNewMenu != pNewMenuEnd; ++pNewMenu ) + { + comphelper::SequenceAsHashMap aEntryItems( *pNewMenu ); + rtl::OUString sURL( aEntryItems.getUnpackedValueOrDefault( sURLKey, rtl::OUString() ) ); + if ( sURL.getLength() ) + aFileNewAppsAvailable.insert( sURL ); + } + + // describe the menu entries for launching the applications + struct MenuEntryDescriptor + { + SvtModuleOptions::EModule eModuleIdentifier; + int nMenuTag; + const char* pAsciiURLDescription; + } aMenuItems[] = + { + { SvtModuleOptions::E_SWRITER, MI_WRITER, WRITER_URL }, + { SvtModuleOptions::E_SCALC, MI_CALC, CALC_URL }, + { SvtModuleOptions::E_SIMPRESS, MI_IMPRESS, IMPRESS_WIZARD_URL }, + { SvtModuleOptions::E_SDRAW, MI_DRAW, DRAW_URL }, + { SvtModuleOptions::E_SDATABASE, MI_BASE, BASE_URL }, + { SvtModuleOptions::E_SMATH, MI_MATH, MATH_URL } + }; + + // insert entry for startcenter + if( aModuleOptions.IsModuleInstalled( SvtModuleOptions::E_SSTARTMODULE ) ) + { + appendMenuItem( pMenu, nil, pShutdownIcon->GetResString( STR_QUICKSTART_STARTCENTER ), MI_STARTMODULE, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "n" ) ) ); + if( [NSApp respondsToSelector: @selector(setDockIconClickHandler:)] ) + [NSApp performSelector:@selector(setDockIconClickHandler:) withObject: pExecute]; + else + DBG_ERROR( "setDockIconClickHandler selector failed on NSApp\n" ); + + } + + // insert the menu entries for launching the applications + for ( size_t i = 0; i < sizeof( aMenuItems ) / sizeof( aMenuItems[0] ); ++i ) + { + if ( !aModuleOptions.IsModuleInstalled( aMenuItems[i].eModuleIdentifier ) ) + // the complete application is not even installed + continue; + + rtl::OUString sURL( ::rtl::OUString::createFromAscii( aMenuItems[i].pAsciiURLDescription ) ); + + if ( aFileNewAppsAvailable.find( sURL ) == aFileNewAppsAvailable.end() ) + // the application is installed, but the entry has been configured to *not* appear in the File/New + // menu => also let not appear it in the quickstarter + continue; + + rtl::OUString aKeyEquiv( getShortCut( pShutdownIcon->GetUrlDescription( sURL ) ) ); + + appendMenuItem( pMenu, pDockMenu, pShutdownIcon->GetUrlDescription( sURL ), aMenuItems[i].nMenuTag, aKeyEquiv ); + } + + // insert the remaining menu entries + + // add recent menu + appendRecentMenu( pMenu, pDockMenu, pShutdownIcon->GetResString( STR_QUICKSTART_RECENTDOC ) ); + + rtl::OUString aTitle( pShutdownIcon->GetResString( STR_QUICKSTART_FROMTEMPLATE ) ); + rtl::OUString aKeyEquiv( getShortCut( aTitle ) ); + appendMenuItem( pMenu, pDockMenu, aTitle, MI_TEMPLATE, aKeyEquiv ); + aTitle = pShutdownIcon->GetResString( STR_QUICKSTART_FILEOPEN ); + aKeyEquiv = getShortCut( aTitle ); + appendMenuItem( pMenu, pDockMenu, aTitle, MI_OPEN, aKeyEquiv ); + + [pDefMenu setSubmenu: pMenu]; + [NSApp performSelector:@selector(addFallbackMenuItem:) withObject: pDefMenu]; + + if( [NSApp respondsToSelector: @selector(addDockMenuItem:)] ) + { + [pDockSubMenu setSubmenu: pDockMenu]; + // insert a separator to the dock menu + [NSApp performSelector:@selector(addDockMenuItem:) withObject: [NSMenuItem separatorItem]]; + // and now add the submenu + [NSApp performSelector:@selector(addDockMenuItem:) withObject: pDockSubMenu]; + } + else + DBG_ERROR( "addDockMenuItem selector failed on NSApp\n" ); + } + else + DBG_ERROR( "addFallbackMenuItem selector failed on NSApp\n" ); + } +} + +void SAL_DLLPUBLIC_EXPORT aqua_shutdown_systray() +{ +} + +} diff --git a/sfx2/source/appl/shutdowniconunx.cxx b/sfx2/source/appl/shutdowniconunx.cxx new file mode 100644 index 000000000000..b9799f5818b7 --- /dev/null +++ b/sfx2/source/appl/shutdowniconunx.cxx @@ -0,0 +1,409 @@ + +#ifdef ENABLE_QUICKSTART_APPLET + +#include <unotools/moduleoptions.hxx> + +#include <unotools/dynamicmenuoptions.hxx> + +#include <gtk/gtk.h> +#include <glib.h> +#include <eggtray/eggtrayicon.h> +#include <vos/mutex.hxx> +#include <vcl/bitmapex.hxx> +#include <vcl/bmpacc.hxx> +#include <sfx2/app.hxx> +#ifndef _SFX_APP_HRC +#include "app.hrc" +#endif +#ifndef __SHUTDOWNICON_HXX__ +#define USE_APP_SHORTCUTS +#include "shutdownicon.hxx" +#endif + +// Cut/paste from vcl/inc/svids.hrc +#define SV_ICON_SMALL_START 25000 + +#define SV_ICON_ID_OFFICE 1 +#define SV_ICON_ID_TEXT 2 +#define SV_ICON_ID_SPREADSHEET 4 +#define SV_ICON_ID_DRAWING 6 +#define SV_ICON_ID_PRESENTATION 8 +#define SV_ICON_ID_DATABASE 14 +#define SV_ICON_ID_FORMULA 15 +#define SV_ICON_ID_TEMPLATE 16 + +using namespace ::rtl; +using namespace ::osl; + +static ResMgr *pVCLResMgr; +static EggTrayIcon *pTrayIcon; +static GtkWidget *pExitMenuItem = NULL; +static GtkWidget *pOpenMenuItem = NULL; + +static void open_url_cb( GtkWidget *, gpointer data ) +{ + ShutdownIcon::OpenURL( *(OUString *)data, + OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ) ); +} + +static void open_file_cb( GtkWidget * ) +{ + if ( !ShutdownIcon::bModalMode ) + ShutdownIcon::FileOpen(); +} + +static void open_template_cb( GtkWidget * ) +{ + if ( !ShutdownIcon::bModalMode ) + ShutdownIcon::FromTemplate(); +} + +static void systray_disable_cb() +{ + ShutdownIcon::SetAutostart( false ); + ShutdownIcon::terminateDesktop(); +} + +static void exit_quickstarter_cb( GtkWidget * ) +{ + egg_tray_icon_cancel_message (pTrayIcon, 1 ); + ShutdownIcon::getInstance()->terminateDesktop(); + plugin_shutdown_sys_tray(); +} + +static void menu_deactivate_cb( GtkWidget *pMenu ) +{ + gtk_menu_popdown( GTK_MENU( pMenu ) ); +} + +static GdkPixbuf * ResIdToPixbuf( USHORT nResId ) +{ + ResId aResId( SV_ICON_SMALL_START + nResId, *pVCLResMgr ); + BitmapEx aIcon( aResId ); + Bitmap pInSalBitmap = aIcon.GetBitmap(); + AlphaMask pInSalAlpha = aIcon.GetAlpha(); + + BitmapReadAccess* pSalBitmap = pInSalBitmap.AcquireReadAccess(); + BitmapReadAccess* pSalAlpha = pInSalAlpha.AcquireReadAccess(); + + g_return_val_if_fail( pSalBitmap != NULL, NULL ); + + Size aSize( pSalBitmap->Width(), pSalBitmap->Height() ); + g_return_val_if_fail( Size( pSalAlpha->Width(), pSalAlpha->Height() ) == aSize, NULL ); + + int nX, nY; + guchar *pPixbufData = ( guchar * )g_malloc( 4 * aSize.Width() * aSize.Height() ); + guchar *pDestData = pPixbufData; + + for( nY = 0; nY < pSalBitmap->Height(); nY++ ) + { + for( nX = 0; nX < pSalBitmap->Width(); nX++ ) + { + BitmapColor aPix; + aPix = pSalBitmap->GetPixel( nY, nX ); + pDestData[0] = aPix.GetRed(); + pDestData[1] = aPix.GetGreen(); + pDestData[2] = aPix.GetBlue(); + if (pSalAlpha) + { + aPix = pSalAlpha->GetPixel( nY, nX ); + pDestData[3] = 255 - aPix.GetIndex(); + } + else + pDestData[3] = 255; + pDestData += 4; + } + } + + pInSalBitmap.ReleaseAccess( pSalBitmap ); + if( pSalAlpha ) + pInSalAlpha.ReleaseAccess( pSalAlpha ); + + return gdk_pixbuf_new_from_data( pPixbufData, + GDK_COLORSPACE_RGB, TRUE, 8, + aSize.Width(), aSize.Height(), + aSize.Width() * 4, + (GdkPixbufDestroyNotify) g_free, + NULL ); +} + +extern "C" { +static void oustring_delete (gpointer data, + GClosure * /* closure */) +{ + OUString *pURL = (OUString *) data; + delete pURL; +} +} + +static void add_item( GtkMenuShell *pMenuShell, const char *pAsciiURL, + OUString *pOverrideLabel, + USHORT nResId, GCallback pFnCallback ) +{ + OUString *pURL = new OUString (OStringToOUString( pAsciiURL, + RTL_TEXTENCODING_UTF8 )); + OString aLabel; + if (pOverrideLabel) + aLabel = OUStringToOString (*pOverrideLabel, RTL_TEXTENCODING_UTF8); + else + { + ShutdownIcon *pShutdownIcon = ShutdownIcon::getInstance(); + aLabel = OUStringToOString (pShutdownIcon->GetUrlDescription( *pURL ), + RTL_TEXTENCODING_UTF8); + } + + GdkPixbuf *pPixbuf= ResIdToPixbuf( nResId ); + GtkWidget *pImage = gtk_image_new_from_pixbuf( pPixbuf ); + g_object_unref( G_OBJECT( pPixbuf ) ); + + GtkWidget *pMenuItem = gtk_image_menu_item_new_with_label( aLabel ); + gtk_image_menu_item_set_image( GTK_IMAGE_MENU_ITEM( pMenuItem ), pImage ); + g_signal_connect_data( pMenuItem, "activate", pFnCallback, pURL, + oustring_delete, GConnectFlags(0)); + + gtk_menu_shell_append( pMenuShell, pMenuItem ); +} + +// Unbelievably nasty +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::task; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; + +static void add_ugly_db_item( GtkMenuShell *pMenuShell, const char *pAsciiURL, + USHORT nResId, GCallback pFnCallback ) +{ + SvtDynamicMenuOptions aOpt; + Sequence < Sequence < PropertyValue > > aMenu = aOpt.GetMenu( E_NEWMENU ); + for ( sal_Int32 n=0; n<aMenu.getLength(); n++ ) + { + ::rtl::OUString aURL; + ::rtl::OUString aDescription; + Sequence < PropertyValue >& aEntry = aMenu[n]; + for ( sal_Int32 m=0; m<aEntry.getLength(); m++ ) + { + if ( aEntry[m].Name.equalsAsciiL( "URL", 3 ) ) + aEntry[m].Value >>= aURL; + if ( aEntry[m].Name.equalsAsciiL( "Title", 5 ) ) + aEntry[m].Value >>= aDescription; + } + + if ( aURL.equalsAscii( BASE_URL ) && aDescription.getLength() ) + { + add_item (pMenuShell, pAsciiURL, &aDescription, nResId, pFnCallback); + break; + } + } +} + +static GtkWidget * +add_image_menu_item( GtkMenuShell *pMenuShell, + const gchar *stock_id, + rtl::OUString aLabel, + GCallback activate_cb ) +{ + OString aUtfLabel = rtl::OUStringToOString (aLabel, RTL_TEXTENCODING_UTF8 ); + + GtkWidget *pImage; + pImage = gtk_image_new_from_stock( stock_id, GTK_ICON_SIZE_MENU ); + + GtkWidget *pMenuItem; + pMenuItem = gtk_image_menu_item_new_with_label( aUtfLabel ); + gtk_image_menu_item_set_image( GTK_IMAGE_MENU_ITEM( pMenuItem ), pImage ); + + gtk_menu_shell_append( pMenuShell, pMenuItem ); + g_signal_connect( pMenuItem, "activate", activate_cb, NULL); + + return pMenuItem; +} + +static void populate_menu( GtkWidget *pMenu ) +{ + ShutdownIcon *pShutdownIcon = ShutdownIcon::getInstance(); + GtkMenuShell *pMenuShell = GTK_MENU_SHELL( pMenu ); + SvtModuleOptions aModuleOptions; + + if ( aModuleOptions.IsWriter() ) + add_item (pMenuShell, WRITER_URL, NULL, + SV_ICON_ID_TEXT, G_CALLBACK( open_url_cb )); + + if ( aModuleOptions.IsCalc() ) + add_item (pMenuShell, CALC_URL, NULL, + SV_ICON_ID_SPREADSHEET, G_CALLBACK( open_url_cb )); + + if ( aModuleOptions.IsImpress() ) + add_item (pMenuShell, IMPRESS_URL, NULL, + SV_ICON_ID_PRESENTATION, G_CALLBACK( open_url_cb )); + + if ( aModuleOptions.IsDraw() ) + add_item (pMenuShell, DRAW_URL, NULL, + SV_ICON_ID_DRAWING, G_CALLBACK( open_url_cb )); + + if ( aModuleOptions.IsDataBase() ) + add_ugly_db_item (pMenuShell, BASE_URL, + SV_ICON_ID_DATABASE, G_CALLBACK( open_url_cb )); + + if ( aModuleOptions.IsMath() ) + add_item (pMenuShell, MATH_URL, NULL, + SV_ICON_ID_FORMULA, G_CALLBACK( open_url_cb )); + + OUString aULabel = pShutdownIcon->GetResString( STR_QUICKSTART_FROMTEMPLATE ); + add_item (pMenuShell, "dummy", &aULabel, + SV_ICON_ID_TEMPLATE, G_CALLBACK( open_template_cb )); + + OString aLabel; + GtkWidget *pMenuItem; + + pMenuItem = gtk_separator_menu_item_new(); + gtk_menu_shell_append( pMenuShell, pMenuItem ); + + pOpenMenuItem = add_image_menu_item + (pMenuShell, GTK_STOCK_OPEN, + pShutdownIcon->GetResString( STR_QUICKSTART_FILEOPEN ), + G_CALLBACK( open_file_cb )); + + pMenuItem = gtk_separator_menu_item_new(); + gtk_menu_shell_append( pMenuShell, pMenuItem ); + + (void) add_image_menu_item + ( pMenuShell, GTK_STOCK_CLOSE, + pShutdownIcon->GetResString( STR_QUICKSTART_PRELAUNCH_UNX ), + G_CALLBACK( systray_disable_cb ) ); + + pMenuItem = gtk_separator_menu_item_new(); + gtk_menu_shell_append( pMenuShell, pMenuItem ); + + pExitMenuItem = add_image_menu_item + ( pMenuShell, GTK_STOCK_QUIT, + pShutdownIcon->GetResString( STR_QUICKSTART_EXIT ), + G_CALLBACK( exit_quickstarter_cb ) ); + + gtk_widget_show_all( pMenu ); +} + +static void refresh_menu( GtkWidget *pMenu ) +{ + if (!pExitMenuItem) + populate_menu( pMenu ); + + bool bModal = ShutdownIcon::bModalMode; + gtk_widget_set_sensitive( pExitMenuItem, !bModal); + gtk_widget_set_sensitive( pOpenMenuItem, !bModal); +} + +extern "C" { +static void +layout_menu( GtkMenu *menu, + gint *x, gint *y, gboolean *push_in, + gpointer ) +{ + GtkRequisition req; + GtkWidget *ebox = GTK_BIN( pTrayIcon )->child; + + gtk_widget_size_request( GTK_WIDGET( menu ), &req ); + gdk_window_get_origin( ebox->window, x, y ); + + (*x) += ebox->allocation.x; + (*y) += ebox->allocation.y; + + if (*y >= gdk_screen_get_height (gtk_widget_get_screen (ebox)) / 2) + (*y) -= req.height; + else + (*y) += ebox->allocation.height; + + *push_in = TRUE; +} +} + +static gboolean display_menu_cb( GtkWidget *, + GdkEventButton *event, GtkWidget *pMenu ) +{ + if (event->button == 2) + return FALSE; + +#ifdef TEMPLATE_DIALOG_MORE_POLISHED + if (event->button == 1 && + event->type == GDK_2BUTTON_PRESS) + { + open_template_cb( NULL ); + return TRUE; + } + if (event->button == 3) + { + ... as below ... +#endif + + refresh_menu( pMenu ); + + gtk_menu_popup( GTK_MENU( pMenu ), NULL, NULL, + layout_menu, NULL, 0, event->time ); + + return TRUE; +} + +extern "C" { + static gboolean + show_at_idle( gpointer ) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + gtk_widget_show_all( GTK_WIDGET( pTrayIcon ) ); + return FALSE; + } +} + +void SAL_DLLPUBLIC_EXPORT plugin_init_sys_tray() +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + if( !g_type_from_name( "GdkDisplay" ) ) + return; + + OString aLabel; + ShutdownIcon *pShutdownIcon = ShutdownIcon::getInstance(); + + aLabel = rtl::OUStringToOString ( + pShutdownIcon->GetResString( STR_QUICKSTART_TIP ), + RTL_TEXTENCODING_UTF8 ); + + pTrayIcon = egg_tray_icon_new( aLabel ); + + GtkWidget *pParent = gtk_event_box_new(); + GtkTooltips *pTooltips = gtk_tooltips_new(); + gtk_tooltips_set_tip( GTK_TOOLTIPS( pTooltips ), pParent, aLabel, NULL ); + + GtkWidget *pIconImage = gtk_image_new(); + gtk_container_add( GTK_CONTAINER( pParent ), pIconImage ); + + pVCLResMgr = CREATEVERSIONRESMGR( vcl ); + + GdkPixbuf *pPixbuf = ResIdToPixbuf( SV_ICON_ID_OFFICE ); + gtk_image_set_from_pixbuf( GTK_IMAGE( pIconImage ), pPixbuf ); + g_object_unref( pPixbuf ); + + GtkWidget *pMenu = gtk_menu_new(); + g_signal_connect (pMenu, "deactivate", + G_CALLBACK (menu_deactivate_cb), NULL); + g_signal_connect( pParent, "button_press_event", + G_CALLBACK( display_menu_cb ), pMenu ); + gtk_container_add( GTK_CONTAINER( pTrayIcon ), pParent ); + + // Show at idle to avoid artefacts at startup + g_idle_add (show_at_idle, (gpointer) pTrayIcon); + + // disable shutdown + pShutdownIcon->SetVeto( true ); + pShutdownIcon->addTerminateListener(); +} + +void SAL_DLLPUBLIC_EXPORT plugin_shutdown_sys_tray() +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + if( !pTrayIcon ) + return; + gtk_widget_destroy( GTK_WIDGET( pTrayIcon ) ); + pTrayIcon = NULL; + pExitMenuItem = NULL; + pOpenMenuItem = NULL; +} + +#endif // ENABLE_QUICKSTART_APPLET diff --git a/sfx2/source/appl/shutdowniconw32.cxx b/sfx2/source/appl/shutdowniconw32.cxx new file mode 100644 index 000000000000..26fd35272a51 --- /dev/null +++ b/sfx2/source/appl/shutdowniconw32.cxx @@ -0,0 +1,977 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" + +#ifdef WNT + +// necessary to include system headers without warnings +#ifdef _MSC_VER +#pragma warning(disable:4668 4917) +#endif + +// Support Windows 95 too +#undef WINVER +#define WINVER 0x0400 +#define USE_APP_SHORTCUTS +// +// the systray icon is only available on windows +// + +#include <unotools/moduleoptions.hxx> +#include <unotools/dynamicmenuoptions.hxx> + +#include "shutdownicon.hxx" +#include "app.hrc" +#include <shlobj.h> +#include <objidl.h> +#include <stdio.h> +#include <io.h> +#include <osl/thread.h> +#include <setup_native/qswin32.h> +#include <comphelper/sequenceashashmap.hxx> +#include <comphelper/processfactory.hxx> +#include <com/sun/star/uno/Reference.h> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/task/XJob.hpp> +#include <com/sun/star/beans/NamedValue.hpp> + +#include <set> + +using namespace ::rtl; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::task; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; +using namespace ::osl; + + +#define EXECUTER_WINDOWCLASS "SO Executer Class" +#define EXECUTER_WINDOWNAME "SO Executer Window" + + +#define ID_QUICKSTART 1 +#define IDM_EXIT 2 +#if defined(USE_APP_SHORTCUTS) +# define IDM_OPEN 3 +# define IDM_WRITER 4 +# define IDM_CALC 5 +# define IDM_IMPRESS 6 +# define IDM_DRAW 7 +# define IDM_BASE 8 +# define IDM_TEMPLATE 9 +# define IDM_MATH 12 +#endif +#define IDM_INSTALL 10 +#define IDM_UNINSTALL 11 + + +#define ICON_SO_DEFAULT 1 +#define ICON_TEXT_DOCUMENT 2 +#define ICON_TEXT_TEMPLATE 3 +#define ICON_SPREADSHEET_DOCUMENT 4 +#define ICON_SPREADSHEET_TEMPLATE 5 +#define ICON_DRAWING_DOCUMENT 6 +#define ICON_DRAWING_TEMPLATE 7 +#define ICON_PRESENTATION_DOCUMENT 8 +#define ICON_PRESENTATION_TEMPLATE 9 +#define ICON_PRESENTATION_COMPRESSED 10 +#define ICON_GLOBAL_DOCUMENT 11 +#define ICON_HTML_DOCUMENT 12 +#define ICON_CHART_DOCUMENT 13 +#define ICON_DATABASE_DOCUMENT 14 +#define ICON_MATH_DOCUMENT 15 +#define ICON_TEMPLATE 16 +#define ICON_MACROLIBRARY 17 +#define ICON_CONFIGURATION 18 +#define ICON_OPEN 5 // See index of open folder icon in shell32.dll +#define ICON_SETUP 500 + +#define SFX_TASKBAR_NOTIFICATION WM_USER+1 + +static HWND aListenerWindow = NULL; +static HWND aExecuterWindow = NULL; +static HMENU popupMenu = NULL; + +static void OnMeasureItem(HWND hwnd, LPMEASUREITEMSTRUCT lpmis); +static void OnDrawItem(HWND hwnd, LPDRAWITEMSTRUCT lpdis); + +typedef struct tagMYITEM +{ + OUString text; + OUString module; + UINT iconId; +} MYITEM; + +// ------------------------------- + +static bool isNT() +{ + static bool bInitialized = false; + static bool bWnt = false; + + if( !bInitialized ) + { + bInitialized = true; + + OSVERSIONINFO aVerInfo; + aVerInfo.dwOSVersionInfoSize = sizeof( aVerInfo ); + if ( GetVersionEx( &aVerInfo ) ) + { + if ( aVerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT ) + bWnt = true; + } + } + return bWnt; +} + + +// ------------------------------- + +static void addMenuItem( HMENU hMenu, UINT id, UINT iconId, const OUString& text, int& pos, int bOwnerdraw, const OUString& module ) +{ + MENUITEMINFOW mi; + memset( &mi, 0, sizeof( MENUITEMINFOW ) ); + + mi.cbSize = sizeof( MENUITEMINFOW ); + if( id == -1 ) + { + mi.fMask=MIIM_TYPE; + mi.fType=MFT_SEPARATOR; + } + else + { + if( bOwnerdraw ) + { + mi.fMask=MIIM_TYPE | MIIM_STATE | MIIM_ID | MIIM_DATA; + mi.fType=MFT_OWNERDRAW; + mi.fState=MFS_ENABLED; + mi.wID = id; + + MYITEM *pMyItem = new MYITEM; + pMyItem->text = text; + pMyItem->iconId = iconId; + pMyItem->module = module; + mi.dwItemData = (DWORD) pMyItem; + } + else + { + mi.fMask=MIIM_TYPE | MIIM_STATE | MIIM_ID | MIIM_DATA; + mi.fType=MFT_STRING; + mi.fState=MFS_ENABLED; + mi.wID = id; + mi.dwTypeData = (LPWSTR) text.getStr(); + mi.cch = text.getLength(); + } + +#if defined(USE_APP_SHORTCUTS) + if ( IDM_TEMPLATE == id ) + mi.fState |= MFS_DEFAULT; +#endif + } + + InsertMenuItemW( hMenu, pos++, TRUE, &mi ); +} + +// ------------------------------- + +static HMENU createSystrayMenu( ) +{ + SvtModuleOptions aModuleOptions; + + HMENU hMenu = CreatePopupMenu(); + int pos=0; + + ShutdownIcon *pShutdownIcon = ShutdownIcon::getInstance(); + OSL_ENSURE( pShutdownIcon, "ShutdownIcon instance empty!"); + + if( !pShutdownIcon ) + return NULL; + +#if defined(USE_APP_SHORTCUTS) + // collect the URLs of the entries in the File/New menu + ::std::set< ::rtl::OUString > aFileNewAppsAvailable; + SvtDynamicMenuOptions aOpt; + Sequence < Sequence < PropertyValue > > aNewMenu = aOpt.GetMenu( E_NEWMENU ); + const ::rtl::OUString sURLKey( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ); + + const Sequence< PropertyValue >* pNewMenu = aNewMenu.getConstArray(); + const Sequence< PropertyValue >* pNewMenuEnd = aNewMenu.getConstArray() + aNewMenu.getLength(); + for ( ; pNewMenu != pNewMenuEnd; ++pNewMenu ) + { + ::comphelper::SequenceAsHashMap aEntryItems( *pNewMenu ); + ::rtl::OUString sURL( aEntryItems.getUnpackedValueOrDefault( sURLKey, ::rtl::OUString() ) ); + if ( sURL.getLength() ) + aFileNewAppsAvailable.insert( sURL ); + } + + // describe the menu entries for launching the applications + struct MenuEntryDescriptor + { + SvtModuleOptions::EModule eModuleIdentifier; + UINT nMenuItemID; + UINT nMenuIconID; + const char* pAsciiURLDescription; + } aMenuItems[] = + { + { SvtModuleOptions::E_SWRITER, IDM_WRITER, ICON_TEXT_DOCUMENT, WRITER_URL }, + { SvtModuleOptions::E_SCALC, IDM_CALC, ICON_SPREADSHEET_DOCUMENT, CALC_URL }, + { SvtModuleOptions::E_SIMPRESS, IDM_IMPRESS,ICON_PRESENTATION_DOCUMENT, IMPRESS_WIZARD_URL }, + { SvtModuleOptions::E_SDRAW, IDM_DRAW, ICON_DRAWING_DOCUMENT, DRAW_URL }, + { SvtModuleOptions::E_SDATABASE, IDM_BASE, ICON_DATABASE_DOCUMENT, BASE_URL }, + { SvtModuleOptions::E_SMATH, IDM_MATH, ICON_MATH_DOCUMENT, MATH_URL }, + }; + + OUString aEmpty; + + // insert the menu entries for launching the applications + for ( size_t i = 0; i < sizeof( aMenuItems ) / sizeof( aMenuItems[0] ); ++i ) + { + if ( !aModuleOptions.IsModuleInstalled( aMenuItems[i].eModuleIdentifier ) ) + // the complete application is not even installed + continue; + + ::rtl::OUString sURL( ::rtl::OUString::createFromAscii( aMenuItems[i].pAsciiURLDescription ) ); + + if ( aFileNewAppsAvailable.find( sURL ) == aFileNewAppsAvailable.end() ) + // the application is installed, but the entry has been configured to *not* appear in the File/New + // menu => also let not appear it in the quickstarter + continue; + + addMenuItem( hMenu, aMenuItems[i].nMenuItemID, aMenuItems[i].nMenuIconID, + pShutdownIcon->GetUrlDescription( sURL ), pos, true, aEmpty ); + } + + + + // insert the remaining menu entries + addMenuItem( hMenu, IDM_TEMPLATE, ICON_TEMPLATE, + pShutdownIcon->GetResString( STR_QUICKSTART_FROMTEMPLATE ), pos, true, aEmpty); + addMenuItem( hMenu, static_cast< UINT >( -1 ), 0, OUString(), pos, false, aEmpty ); + addMenuItem( hMenu, IDM_OPEN, ICON_OPEN, pShutdownIcon->GetResString( STR_QUICKSTART_FILEOPEN ), pos, true, OUString::createFromAscii( "SHELL32" )); + addMenuItem( hMenu, static_cast< UINT >( -1 ), 0, OUString(), pos, false, aEmpty ); +#endif + addMenuItem( hMenu, IDM_INSTALL,0, pShutdownIcon->GetResString( STR_QUICKSTART_PRELAUNCH ), pos, false, aEmpty ); + addMenuItem( hMenu, static_cast< UINT >( -1 ), 0, OUString(), pos, false, aEmpty ); + addMenuItem( hMenu, IDM_EXIT, 0, pShutdownIcon->GetResString( STR_QUICKSTART_EXIT ), pos, false, aEmpty ); + + // indicate status of autostart folder + CheckMenuItem( hMenu, IDM_INSTALL, MF_BYCOMMAND | (ShutdownIcon::GetAutostart() ? MF_CHECKED : MF_UNCHECKED) ); + + return hMenu; +} + +// ------------------------------- + +static void deleteSystrayMenu( HMENU hMenu ) +{ + if( !hMenu || !IsMenu( hMenu )) + return; + + MENUITEMINFOW mi; + MYITEM *pMyItem; + int pos=0; + memset( &mi, 0, sizeof( mi ) ); + mi.cbSize = sizeof( mi ); + mi.fMask = MIIM_DATA; + + while( GetMenuItemInfoW( hMenu, pos++, true, &mi ) ) + { + pMyItem = (MYITEM*) mi.dwItemData; + if( pMyItem ) + { + pMyItem->text = OUString(); + delete pMyItem; + } + mi.fMask = MIIM_DATA; + } +} + +// ------------------------------- + +static void addTaskbarIcon( HWND hWnd ) +{ + OUString strTip; + if( ShutdownIcon::getInstance() ) + strTip = ShutdownIcon::getInstance()->GetResString( STR_QUICKSTART_TIP ); + + // add taskbar icon + NOTIFYICONDATAA nid; + nid.hIcon = (HICON)LoadImageA( GetModuleHandle( NULL ), MAKEINTRESOURCE( ICON_SO_DEFAULT ), + IMAGE_ICON, GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ), + LR_DEFAULTCOLOR | LR_SHARED ); + + // better use unicode wrapper here ? + strncpy( nid.szTip, ( OUStringToOString(strTip, osl_getThreadTextEncoding()).getStr() ), 64 ); + + nid.cbSize = sizeof(nid); + nid.hWnd = hWnd; + nid.uID = ID_QUICKSTART; + nid.uCallbackMessage = SFX_TASKBAR_NOTIFICATION; + nid.uFlags = NIF_MESSAGE|NIF_TIP|NIF_ICON; + + Shell_NotifyIconA(NIM_ADD, &nid); +} + +// ------------------------------- + +/* +static void removeTaskbarIcon() +{ + ShutdownIcon *pShutdownIcon = ShutdownIcon::getInstance(); + OSL_ENSURE( pShutdownIcon, "ShutdownIcon instance empty!"); + + if( !pShutdownIcon ) + return; + + if ( IsWindow( aListenerWindow )) + { + deleteSystrayMenu( popupMenu ); + + NOTIFYICONDATAA nid; + nid.cbSize=sizeof(NOTIFYICONDATA); + nid.hWnd = aListenerWindow; + nid.uID = ID_QUICKSTART; + Shell_NotifyIconA(NIM_DELETE, &nid); + } +} +*/ + +// ------------------------------- + +LRESULT CALLBACK listenerWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + static UINT s_uTaskbarRestart = 0; + static UINT s_uMsgKillTray = 0; + + switch (uMsg) + { + case WM_NCCREATE: + return TRUE; + case WM_CREATE: + { + // request notfication when taskbar is recreated + // we then have to add our icon again + s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated")); + s_uMsgKillTray = RegisterWindowMessage( SHUTDOWN_QUICKSTART_MESSAGE ); + + // create the menu + if( !popupMenu ) + if( (popupMenu = createSystrayMenu( )) == NULL ) + return -1; + + // and the icon + addTaskbarIcon( hWnd ); + + // disable shutdown + ShutdownIcon::getInstance()->SetVeto( true ); + ShutdownIcon::getInstance()->addTerminateListener(); + } + return 0; + + case WM_MEASUREITEM: + OnMeasureItem(hWnd, (LPMEASUREITEMSTRUCT) lParam); + return TRUE; + + case WM_DRAWITEM: + OnDrawItem(hWnd, (LPDRAWITEMSTRUCT) lParam); + return TRUE; + + case SFX_TASKBAR_NOTIFICATION: + switch( lParam ) + { + case WM_LBUTTONDBLCLK: +#if defined(USE_APP_SHORTCUTS) + PostMessage( aExecuterWindow, WM_COMMAND, IDM_TEMPLATE, (LPARAM)hWnd ); +#endif + break; + + case WM_RBUTTONDOWN: + { + POINT pt; + GetCursorPos(&pt); + SetForegroundWindow( hWnd ); + + // update status before showing menu, could have been changed from option page + CheckMenuItem( popupMenu, IDM_INSTALL, MF_BYCOMMAND| (ShutdownIcon::GetAutostart() ? MF_CHECKED : MF_UNCHECKED) ); + + EnableMenuItem( popupMenu, IDM_EXIT, MF_BYCOMMAND | (ShutdownIcon::bModalMode ? MF_GRAYED : MF_ENABLED) ); +#if defined(USE_APP_SHORTCUTS) + EnableMenuItem( popupMenu, IDM_OPEN, MF_BYCOMMAND | (ShutdownIcon::bModalMode ? MF_GRAYED : MF_ENABLED) ); + EnableMenuItem( popupMenu, IDM_TEMPLATE, MF_BYCOMMAND | (ShutdownIcon::bModalMode ? MF_GRAYED : MF_ENABLED) ); +#endif + int m = TrackPopupMenuEx( popupMenu, TPM_RETURNCMD|TPM_LEFTALIGN|TPM_RIGHTBUTTON, + pt.x, pt.y, hWnd, NULL ); + // BUGFIX: See Q135788 (PRB: Menus for Notification Icons Don't Work Correctly) + PostMessage( hWnd, NULL, 0, 0 ); + switch( m ) + { +#if defined(USE_APP_SHORTCUTS) + case IDM_OPEN: + case IDM_WRITER: + case IDM_CALC: + case IDM_IMPRESS: + case IDM_DRAW: + case IDM_TEMPLATE: + case IDM_BASE: + case IDM_MATH: + break; +#endif + case IDM_INSTALL: + CheckMenuItem( popupMenu, IDM_INSTALL, MF_BYCOMMAND| (ShutdownIcon::GetAutostart() ? MF_CHECKED : MF_UNCHECKED) ); + break; + case IDM_EXIT: + // delete taskbar icon + NOTIFYICONDATAA nid; + nid.cbSize=sizeof(NOTIFYICONDATA); + nid.hWnd = hWnd; + nid.uID = ID_QUICKSTART; + Shell_NotifyIconA(NIM_DELETE, &nid); + break; + } + + PostMessage( aExecuterWindow, WM_COMMAND, m, (LPARAM)hWnd ); + } + break; + } + break; + case WM_DESTROY: + deleteSystrayMenu( popupMenu ); + // We don't need the Systray Thread anymore + PostQuitMessage( 0 ); + return DefWindowProc(hWnd, uMsg, wParam, lParam); + default: + if( uMsg == s_uTaskbarRestart ) + { + // re-create taskbar icon + addTaskbarIcon( hWnd ); + } + else if ( uMsg == s_uMsgKillTray ) + { + // delete taskbar icon + NOTIFYICONDATAA nid; + nid.cbSize=sizeof(NOTIFYICONDATA); + nid.hWnd = hWnd; + nid.uID = ID_QUICKSTART; + Shell_NotifyIconA(NIM_DELETE, &nid); + + PostMessage( aExecuterWindow, WM_COMMAND, IDM_EXIT, (LPARAM)hWnd ); + } + else + return DefWindowProc(hWnd, uMsg, wParam, lParam); + } + return 0; +} + +// ------------------------------- + +static sal_Bool checkOEM() { + Reference<XMultiServiceFactory> rFactory = ::comphelper::getProcessServiceFactory(); + Reference<XJob> rOemJob(rFactory->createInstance( + OUString::createFromAscii("com.sun.star.office.OEMPreloadJob")), + UNO_QUERY ); + Sequence<NamedValue> args; + sal_Bool bResult = sal_False; + if (rOemJob.is()) + { + Any aResult = rOemJob->execute(args); + aResult >>= bResult; + } else bResult = sal_True; + return bResult; +} + +LRESULT CALLBACK executerWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_NCCREATE: + return TRUE; + case WM_CREATE: + return 0; + + case WM_COMMAND: + switch( LOWORD(wParam) ) + { +#if defined(USE_APP_SHORTCUTS) + case IDM_OPEN: + if ( !ShutdownIcon::bModalMode && checkOEM() ) + ShutdownIcon::FileOpen(); + break; + case IDM_WRITER: + if (checkOEM()) + ShutdownIcon::OpenURL( OUString( RTL_CONSTASCII_USTRINGPARAM( WRITER_URL ) ), OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ) ); + break; + case IDM_CALC: + if (checkOEM()) + ShutdownIcon::OpenURL( OUString( RTL_CONSTASCII_USTRINGPARAM( CALC_URL ) ), OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ) ); + break; + case IDM_IMPRESS: + if (checkOEM()) + ShutdownIcon::OpenURL( OUString( RTL_CONSTASCII_USTRINGPARAM( IMPRESS_WIZARD_URL ) ), OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ) ); + break; + case IDM_DRAW: + if (checkOEM()) + ShutdownIcon::OpenURL( OUString( RTL_CONSTASCII_USTRINGPARAM( DRAW_URL ) ), OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ) ); + break; + case IDM_BASE: + if (checkOEM()) + ShutdownIcon::OpenURL( OUString( RTL_CONSTASCII_USTRINGPARAM( BASE_URL ) ), OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ) ); + break; + case IDM_MATH: + if (checkOEM()) + ShutdownIcon::OpenURL( OUString( RTL_CONSTASCII_USTRINGPARAM( MATH_URL ) ), OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ) ); + break; + case IDM_TEMPLATE: + if ( !ShutdownIcon::bModalMode && checkOEM()) + ShutdownIcon::FromTemplate(); + break; +#endif + case IDM_INSTALL: + ShutdownIcon::SetAutostart( !ShutdownIcon::GetAutostart() ); + break; + case IDM_EXIT: + // remove listener and + // terminate office if running in background + if ( !ShutdownIcon::bModalMode ) + ShutdownIcon::terminateDesktop(); + break; + } + break; + case WM_DESTROY: + default: + return DefWindowProc(hWnd, uMsg, wParam, lParam); + } + return 0; +} + +// ------------------------------- + + +DWORD WINAPI SystrayThread( LPVOID /*lpParam*/ ) +{ + aListenerWindow = CreateWindowExA(0, + QUICKSTART_CLASSNAME, // registered class name + QUICKSTART_WINDOWNAME, // window name + 0, // window style + CW_USEDEFAULT, // horizontal position of window + CW_USEDEFAULT, // vertical position of window + CW_USEDEFAULT, // window width + CW_USEDEFAULT, // window height + (HWND) NULL, // handle to parent or owner window + NULL, // menu handle or child identifier + (HINSTANCE) GetModuleHandle( NULL ), // handle to application instance + NULL // window-creation data + ); + + MSG msg; + + while ( GetMessage( &msg, NULL, 0, 0 ) ) + { + TranslateMessage( &msg ); + DispatchMessage( &msg ); + } + + return msg.wParam; // Exit code of WM_QUIT +} + +// ------------------------------- + +void win32_init_sys_tray() +{ + if ( ShutdownIcon::IsQuickstarterInstalled() ) + { + WNDCLASSEXA listenerClass; + listenerClass.cbSize = sizeof(WNDCLASSEX); + listenerClass.style = 0; + listenerClass.lpfnWndProc = listenerWndProc; + listenerClass.cbClsExtra = 0; + listenerClass.cbWndExtra = 0; + listenerClass.hInstance = (HINSTANCE) GetModuleHandle( NULL ); + listenerClass.hIcon = NULL; + listenerClass.hCursor = NULL; + listenerClass.hbrBackground = NULL; + listenerClass.lpszMenuName = NULL; + listenerClass.lpszClassName = QUICKSTART_CLASSNAME; + listenerClass.hIconSm = NULL; + + RegisterClassExA(&listenerClass); + + WNDCLASSEXA executerClass; + executerClass.cbSize = sizeof(WNDCLASSEX); + executerClass.style = 0; + executerClass.lpfnWndProc = executerWndProc; + executerClass.cbClsExtra = 0; + executerClass.cbWndExtra = 0; + executerClass.hInstance = (HINSTANCE) GetModuleHandle( NULL ); + executerClass.hIcon = NULL; + executerClass.hCursor = NULL; + executerClass.hbrBackground = NULL; + executerClass.lpszMenuName = NULL; + executerClass.lpszClassName = EXECUTER_WINDOWCLASS; + executerClass.hIconSm = NULL; + + RegisterClassExA( &executerClass ); + + aExecuterWindow = CreateWindowExA(0, + EXECUTER_WINDOWCLASS, // registered class name + EXECUTER_WINDOWNAME, // window name + 0, // window style + CW_USEDEFAULT, // horizontal position of window + CW_USEDEFAULT, // vertical position of window + CW_USEDEFAULT, // window width + CW_USEDEFAULT, // window height + (HWND) NULL, // handle to parent or owner window + NULL, // menu handle or child identifier + (HINSTANCE) GetModuleHandle( NULL ), // handle to application instance + NULL // window-creation data + ); + + DWORD dwThreadId; + CreateThread( NULL, 0, SystrayThread, NULL, 0, &dwThreadId ); + } +} + +// ------------------------------- + +void win32_shutdown_sys_tray() +{ + if ( ShutdownIcon::IsQuickstarterInstalled() ) + { + if( IsWindow( aListenerWindow ) ) + { + DestroyWindow( aListenerWindow ); + aListenerWindow = NULL; + DestroyWindow( aExecuterWindow ); + aExecuterWindow = NULL; + } + UnregisterClassA( QUICKSTART_CLASSNAME, GetModuleHandle( NULL ) ); + UnregisterClassA( EXECUTER_WINDOWCLASS, GetModuleHandle( NULL ) ); + } +} + + + +// ------------------------------- + +void OnMeasureItem(HWND hwnd, LPMEASUREITEMSTRUCT lpmis) +{ + MYITEM *pMyItem = (MYITEM *) lpmis->itemData; + HDC hdc = GetDC(hwnd); + SIZE size; + + NONCLIENTMETRICS ncm; + memset(&ncm, 0, sizeof(ncm)); + ncm.cbSize = sizeof(ncm); + + SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, (PVOID) &ncm, 0); + + // Assume every menu item can be default and printed bold + ncm.lfMenuFont.lfWeight = FW_BOLD; + + HFONT hfntOld = (HFONT) SelectObject(hdc, (HFONT) CreateFontIndirect( &ncm.lfMenuFont )); + + GetTextExtentPoint32W(hdc, reinterpret_cast<LPCWSTR>(pMyItem->text.getStr()), + pMyItem->text.getLength(), &size); + + lpmis->itemWidth = size.cx + 4 + GetSystemMetrics( SM_CXSMICON ); + lpmis->itemHeight = (size.cy > GetSystemMetrics( SM_CYSMICON )) ? size.cy : GetSystemMetrics( SM_CYSMICON ); + lpmis->itemHeight += 4; + + DeleteObject( SelectObject(hdc, hfntOld) ); + ReleaseDC(hwnd, hdc); +} + +void OnDrawItem(HWND /*hwnd*/, LPDRAWITEMSTRUCT lpdis) +{ + MYITEM *pMyItem = (MYITEM *) lpdis->itemData; + COLORREF clrPrevText, clrPrevBkgnd; + HFONT hfntOld; + HBRUSH hbrOld; + int x, y; + BOOL fSelected = lpdis->itemState & ODS_SELECTED; + BOOL fDisabled = lpdis->itemState & (ODS_DISABLED | ODS_GRAYED); + + // Set the appropriate foreground and background colors. + + RECT aRect = lpdis->rcItem; + + clrPrevBkgnd = SetBkColor( lpdis->hDC, GetSysColor(COLOR_MENU) ); + + if ( fDisabled ) + clrPrevText = SetTextColor( lpdis->hDC, GetSysColor( COLOR_GRAYTEXT ) ); + else + clrPrevText = SetTextColor( lpdis->hDC, GetSysColor( fSelected ? COLOR_HIGHLIGHTTEXT : COLOR_MENUTEXT ) ); + + if ( fSelected ) + clrPrevBkgnd = SetBkColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT) ); + else + clrPrevBkgnd = SetBkColor( lpdis->hDC, GetSysColor(COLOR_MENU) ); + + hbrOld = (HBRUSH)SelectObject( lpdis->hDC, CreateSolidBrush( GetBkColor( lpdis->hDC ) ) ); + + // Fill background + PatBlt(lpdis->hDC, aRect.left, aRect.top, aRect.right-aRect.left, aRect.bottom-aRect.top, PATCOPY); + + int height = aRect.bottom-aRect.top; + + x = aRect.left; + y = aRect.top; + + int cx = GetSystemMetrics( SM_CXSMICON ); + int cy = GetSystemMetrics( SM_CYSMICON ); + HICON hIcon( 0 ); + HMODULE hModule( GetModuleHandle( NULL ) ); + + if ( pMyItem->module.getLength() > 0 ) + { + LPCWSTR pModuleName = reinterpret_cast<LPCWSTR>( pMyItem->module.getStr() ); + hModule = GetModuleHandleW( pModuleName ); + if ( hModule == NULL ) + { + LoadLibraryW( pModuleName ); + hModule = GetModuleHandleW( pModuleName ); + } + } + + hIcon = (HICON) LoadImageA( hModule, MAKEINTRESOURCE( pMyItem->iconId ), + IMAGE_ICON, cx, cy, + LR_DEFAULTCOLOR | LR_SHARED ); + + // DrawIconEx( lpdis->hDC, x, y+(height-cy)/2, hIcon, cx, cy, 0, NULL, DI_NORMAL ); + + HBRUSH hbrIcon = CreateSolidBrush( GetSysColor( COLOR_GRAYTEXT ) ); + + DrawStateW( lpdis->hDC, (HBRUSH)hbrIcon, (DRAWSTATEPROC)NULL, (LPARAM)hIcon, (WPARAM)0, x, y+(height-cy)/2, 0, 0, DST_ICON | (fDisabled ? (fSelected ? DSS_MONO : DSS_DISABLED) : DSS_NORMAL) ); + + DeleteObject( hbrIcon ); + + x += cx + 4; // space for icon + aRect.left = x; + + NONCLIENTMETRICS ncm; + memset(&ncm, 0, sizeof(ncm)); + ncm.cbSize = sizeof(ncm); + + SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, (PVOID) &ncm, 0); + + // Print default menu entry with bold font + if ( lpdis->itemState & ODS_DEFAULT ) + ncm.lfMenuFont.lfWeight = FW_BOLD; + + hfntOld = (HFONT) SelectObject(lpdis->hDC, (HFONT) CreateFontIndirect( &ncm.lfMenuFont )); + + + SIZE size; + GetTextExtentPointW( lpdis->hDC, reinterpret_cast<LPCWSTR>(pMyItem->text.getStr()), pMyItem->text.getLength(), &size ); + + DrawStateW( lpdis->hDC, (HBRUSH)NULL, (DRAWSTATEPROC)NULL, (LPARAM)pMyItem->text.getStr(), (WPARAM)0, aRect.left, aRect.top + (height - size.cy)/2, 0, 0, DST_TEXT | (fDisabled && !fSelected ? DSS_DISABLED : DSS_NORMAL) ); + + // Restore the original font and colors. + DeleteObject( SelectObject( lpdis->hDC, hbrOld ) ); + DeleteObject( SelectObject( lpdis->hDC, hfntOld) ); + SetTextColor(lpdis->hDC, clrPrevText); + SetBkColor(lpdis->hDC, clrPrevBkgnd); +} + +// ------------------------------- +// code from setup2 project +// ------------------------------- + +void _SHFree( void *pv ) +{ + IMalloc *pMalloc; + if( NOERROR == SHGetMalloc(&pMalloc) ) + { + pMalloc->Free( pv ); + pMalloc->Release(); + } +} + +#define ALLOC(type, n) ((type *) HeapAlloc(GetProcessHeap(), 0, sizeof(type) * n )) +#define FREE(p) HeapFree(GetProcessHeap(), 0, p) + +static OUString _SHGetSpecialFolder( int nFolderID ) +{ + + LPITEMIDLIST pidl; + HRESULT hHdl = SHGetSpecialFolderLocation( NULL, nFolderID, &pidl ); + OUString aFolder; + + if( hHdl == NOERROR ) + { + WCHAR *lpFolderA; + lpFolderA = ALLOC( WCHAR, 16000 ); + + SHGetPathFromIDListW( pidl, lpFolderA ); + aFolder = OUString( reinterpret_cast<const sal_Unicode*>(lpFolderA) ); + + FREE( lpFolderA ); + _SHFree( pidl ); + } + return aFolder; +} + +OUString ShutdownIcon::GetAutostartFolderNameW32() +{ + return _SHGetSpecialFolder(CSIDL_STARTUP); +} + +static HRESULT WINAPI SHCoCreateInstance( LPVOID lpszReserved, REFCLSID clsid, LPUNKNOWN pUnkUnknown, REFIID iid, LPVOID *ppv ) +{ + HRESULT hResult = E_NOTIMPL; + HMODULE hModShell = GetModuleHandle( "SHELL32" ); + + if ( hModShell != NULL ) + { + typedef HRESULT (WINAPI *SHCoCreateInstance_PROC)( LPVOID lpszReserved, REFCLSID clsid, LPUNKNOWN pUnkUnknwon, REFIID iid, LPVOID *ppv ); + + SHCoCreateInstance_PROC lpfnSHCoCreateInstance = (SHCoCreateInstance_PROC)GetProcAddress( hModShell, MAKEINTRESOURCE(102) ); + + if ( lpfnSHCoCreateInstance ) + hResult = lpfnSHCoCreateInstance( lpszReserved, clsid, pUnkUnknown, iid, ppv ); + } + return hResult; +} + +BOOL CreateShortcut( const OUString& rAbsObject, const OUString& rAbsObjectPath, + const OUString& rAbsShortcut, const OUString& rDescription, const OUString& rParameter ) +{ + HRESULT hres; + IShellLink* psl; + CLSID clsid_ShellLink = CLSID_ShellLink; + CLSID clsid_IShellLink = IID_IShellLink; + + hres = CoCreateInstance( clsid_ShellLink, NULL, CLSCTX_INPROC_SERVER, + clsid_IShellLink, (void**)&psl ); + if( FAILED(hres) ) + hres = SHCoCreateInstance( NULL, clsid_ShellLink, NULL, clsid_IShellLink, (void**)&psl ); + + if( SUCCEEDED(hres) ) + { + IPersistFile* ppf; + psl->SetPath( OUStringToOString(rAbsObject, osl_getThreadTextEncoding()).getStr() ); + psl->SetWorkingDirectory( OUStringToOString(rAbsObjectPath, osl_getThreadTextEncoding()).getStr() ); + psl->SetDescription( OUStringToOString(rDescription, osl_getThreadTextEncoding()).getStr() ); + if( rParameter.getLength() ) + psl->SetArguments( OUStringToOString(rParameter, osl_getThreadTextEncoding()).getStr() ); + + CLSID clsid_IPersistFile = IID_IPersistFile; + hres = psl->QueryInterface( clsid_IPersistFile, (void**)&ppf ); + + if( SUCCEEDED(hres) ) + { + hres = ppf->Save( reinterpret_cast<LPCOLESTR>(rAbsShortcut.getStr()), TRUE ); + ppf->Release(); + } else return FALSE; + psl->Release(); + } else return FALSE; + return TRUE; +} + +// ------------------ +// install/uninstall + +static bool FileExistsW( LPCWSTR lpPath ) +{ + bool bExists = false; + WIN32_FIND_DATAW aFindData; + + HANDLE hFind = FindFirstFileW( lpPath, &aFindData ); + + if ( INVALID_HANDLE_VALUE != hFind ) + { + bExists = true; + FindClose( hFind ); + } + + return bExists; +} + +bool ShutdownIcon::IsQuickstarterInstalled() +{ + wchar_t aPath[_MAX_PATH]; + if( isNT() ) + { + GetModuleFileNameW( NULL, aPath, _MAX_PATH-1); + } + else + { + char szPathA[_MAX_PATH]; + GetModuleFileNameA( NULL, szPathA, _MAX_PATH-1); + + // calc the string wcstr len + int nNeededWStrBuffSize = MultiByteToWideChar( CP_ACP, 0, szPathA, -1, NULL, 0 ); + + // copy the string if necessary + if ( nNeededWStrBuffSize > 0 ) + MultiByteToWideChar( CP_ACP, 0, szPathA, -1, aPath, nNeededWStrBuffSize ); + } + + OUString aOfficepath( reinterpret_cast<const sal_Unicode*>(aPath) ); + int i = aOfficepath.lastIndexOf((sal_Char) '\\'); + if( i != -1 ) + aOfficepath = aOfficepath.copy(0, i); + + OUString quickstartExe(aOfficepath); + quickstartExe += OUString( RTL_CONSTASCII_USTRINGPARAM( "\\quickstart.exe" ) ); + + return FileExistsW( reinterpret_cast<LPCWSTR>(quickstartExe.getStr()) ); +} + +void ShutdownIcon::EnableAutostartW32( const rtl::OUString &aShortcut ) +{ + wchar_t aPath[_MAX_PATH]; + if( isNT() ) + GetModuleFileNameW( NULL, aPath, _MAX_PATH-1); + else + { + char szPathA[_MAX_PATH]; + GetModuleFileNameA( NULL, szPathA, _MAX_PATH-1); + + // calc the string wcstr len + int nNeededWStrBuffSize = MultiByteToWideChar( CP_ACP, 0, szPathA, -1, NULL, 0 ); + + // copy the string if necessary + if ( nNeededWStrBuffSize > 0 ) + MultiByteToWideChar( CP_ACP, 0, szPathA, -1, aPath, nNeededWStrBuffSize ); + } + + OUString aOfficepath( reinterpret_cast<const sal_Unicode*>(aPath) ); + int i = aOfficepath.lastIndexOf((sal_Char) '\\'); + if( i != -1 ) + aOfficepath = aOfficepath.copy(0, i); + + OUString quickstartExe(aOfficepath); + quickstartExe += OUString( RTL_CONSTASCII_USTRINGPARAM( "\\quickstart.exe" ) ); + + CreateShortcut( quickstartExe, aOfficepath, aShortcut, OUString(), OUString() ); +} + +#endif // WNT + + diff --git a/sfx2/source/appl/workwin.cxx b/sfx2/source/appl/workwin.cxx new file mode 100644 index 000000000000..f9a388deee5c --- /dev/null +++ b/sfx2/source/appl/workwin.cxx @@ -0,0 +1,3142 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" + +#ifndef GCC +#endif + +#include <stdio.h> +#include <hash_map> + +#include <sfx2/docfile.hxx> +#include <sfx2/objsh.hxx> +#include <sfx2/app.hxx> +#include "workwin.hxx" +#include <sfx2/viewfrm.hxx> +#include "arrdecl.hxx" +#include <sfx2/viewfrm.hxx> +#include <sfx2/module.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/dockwin.hxx> +#include <sfx2/viewsh.hxx> +#include "splitwin.hxx" +#include <sfx2/msgpool.hxx> +#include "sfxresid.hxx" +#include <sfx2/objsh.hxx> +#include <sfx2/request.hxx> // SFX_ITEMSET_SET +#include <vcl/taskpanelist.hxx> +#include <vcl/toolbox.hxx> +#include <tools/rcid.h> +#include <tools/diagnose_ex.h> +#include <toolkit/helper/vclunohelper.hxx> +#include <svl/itempool.hxx> +#include <svl/itemiter.hxx> +#include <svl/whiter.hxx> +#include <svl/intitem.hxx> +#ifndef _SFXEITEM_HXX //autogen +#include <svl/eitem.hxx> +#endif +#include <com/sun/star/ui/XUIElement.hpp> +#include <com/sun/star/frame/XLayoutManager.hpp> +#include <com/sun/star/frame/XLayoutManagerEventBroadcaster.hpp> +#include <com/sun/star/frame/LayoutManagerEvents.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/awt/XWindow.hpp> +#include <com/sun/star/lang/DisposedException.hpp> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +namespace css = ::com::sun::star; + +struct ResIdToResName +{ + USHORT nId; + const char* pName; +}; + +static const ResIdToResName pToolBarResToName[] = +{ + { 558, "fullscreenbar" }, + { 560, "standardbar", }, + { 18001, "formsnavigationbar" }, + { 18002, "formsfilterbar" }, + { 18003, "formtextobjectbar" }, + { 18004, "formcontrols" }, + { 18005, "moreformcontrols" }, + { 18006, "formdesign" }, + { 20050, "toolbar" }, //math + { 30001, "objectbar" }, //chart + { 30513, "toolbar" }, //chart + { 25005, "textobjectbar" }, //calc + { 25053, "drawobjectbar" }, + { 25054, "graphicobjectbar" }, + { 25001, "formatobjectbar" }, + { 25006, "previewbar" }, + { 25035, "toolbar" }, //calc + { 23015, "bezierobjectbar" }, //draw/impress + { 23019, "gluepointsobjectbar" }, + { 23030, "graphicobjectbar" }, + { 23013, "drawingobjectbar" }, //impress + { 23016, "textobjectbar" }, //impress + { 23028, "textobjectbar" }, //draw + { 23011, "toolbar" }, //impress + { 23020, "optionsbar" }, + { 23021, "commontaskbar" }, + { 23025, "toolbar" }, //draw + { 23026, "optionsbar" }, + { 23027, "drawingobjectbar" }, //draw + { 23017, "outlinetoolbar" }, //impress + { 23012, "slideviewtoolbar" }, + { 23014, "slideviewobjectbar" }, + { 23283, "bezierobjectbar" }, //writer + { 23269, "drawingobjectbar" }, + { 23270, "drawtextobjectbar" }, + { 23267, "frameobjectbar" }, + { 23268, "graphicobjectbar" }, + { 23271, "numobjectbar" }, + { 23272, "oleobjectbar" }, + { 23266, "tableobjectbar" }, + { 23265, "textobjectbar" }, + { 20631, "previewobjectbar" }, //writer + { 20402, "toolbar" }, //web + { 20403, "textobjectbar" }, + { 23273, "toolbar" }, //writer + { 20408, "frameobjectbar" }, //web + { 20410, "graphicobjectbar" }, + { 20411, "oleobjectbar" }, + { 14850, "macrobar" }, + { 10987, "fontworkobjectbar" }, //global + { 10986, "extrusionobjectbar" }, + { 23022, "formsobjectbar" }, + { 23310, "viewerbar" }, //writer (plugin) + { 25000, "viewerbar" }, //calc (plugin) + { 23023, "viewerbar" }, //impress(plugin) + { 23024, "viewerbar" }, //draw (plugin) + { 23031, "mediaobjectbar" }, //draw/impress + { 25060, "mediaobjectbar" }, //calc + { 23311, "mediaobjectbar" }, //writer + { 0, "" } +}; + +DBG_NAME(SfxWorkWindow) + +//SV_IMPL_OBJARR( SfxObjectBarArr_Impl, SfxObjectBar_Impl ); + +//==================================================================== +// Sortiert die Children nach ihrem Alignment +// Reihenfolge entspricht der im enum SfxChildAlignment (->CHILDWIN.HXX). +// + +// Hilfe, um die "Anderungen am Alignment kompatibal zu machen! + + +SFX_IMPL_XINTERFACE_3( LayoutManagerListener, OWeakObject, ::com::sun::star::frame::XLayoutManagerListener, ::com::sun::star::lang::XEventListener, ::com::sun::star::lang::XComponent ) +SFX_IMPL_XTYPEPROVIDER_3( LayoutManagerListener, ::com::sun::star::frame::XLayoutManagerListener, ::com::sun::star::lang::XEventListener, ::com::sun::star::lang::XComponent ) + +LayoutManagerListener::LayoutManagerListener( + SfxWorkWindow* pWrkWin ) : + m_bHasFrame( sal_False ), + m_pWrkWin( pWrkWin ), + m_aLayoutManagerPropName( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" )) +{ +} + +LayoutManagerListener::~LayoutManagerListener() +{ +} + +void LayoutManagerListener::setFrame( const css::uno::Reference< css::frame::XFrame >& xFrame ) +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + if ( m_pWrkWin && !m_bHasFrame ) + { + m_xFrame = xFrame; + m_bHasFrame = sal_True; + + if ( xFrame.is() ) + { + css::uno::Reference< css::beans::XPropertySet > xPropSet( xFrame, UNO_QUERY ); + css::uno::Reference< css::frame::XLayoutManagerEventBroadcaster > xLayoutManager; + if ( xPropSet.is() ) + { + try + { + Any aValue = xPropSet->getPropertyValue( m_aLayoutManagerPropName ); + aValue >>= xLayoutManager; + + if ( xLayoutManager.is() ) + xLayoutManager->addLayoutManagerEventListener( + css::uno::Reference< css::frame::XLayoutManagerListener >( + static_cast< OWeakObject* >( this ), css::uno::UNO_QUERY )); + + xPropSet = css::uno::Reference< css::beans::XPropertySet >( xLayoutManager, UNO_QUERY ); + if ( xPropSet.is() ) + { + aValue = xPropSet->getPropertyValue( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LockCount" )) ); + aValue >>= m_pWrkWin->m_nLock; + } + } + catch ( css::lang::DisposedException& ) + { + } + catch ( css::uno::RuntimeException& e ) + { + throw e; + } + catch ( css::uno::Exception& ) + { + } + } + } + } +} + +//--------------------------------------------------------------------------------------------------------- +// XComponent +//--------------------------------------------------------------------------------------------------------- +void SAL_CALL LayoutManagerListener::addEventListener( + const css::uno::Reference< css::lang::XEventListener >& ) +throw (::com::sun::star::uno::RuntimeException) +{ + // do nothing, only internal class +} + +void SAL_CALL LayoutManagerListener::removeEventListener( + const css::uno::Reference< css::lang::XEventListener >& ) +throw (::com::sun::star::uno::RuntimeException) +{ + // do nothing, only internal class +} + +void SAL_CALL LayoutManagerListener::dispose() +throw( css::uno::RuntimeException ) +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + // reset member + m_pWrkWin = 0; + + css::uno::Reference< css::frame::XFrame > xFrame( m_xFrame.get(), css::uno::UNO_QUERY ); + if ( xFrame.is() ) + { + m_xFrame = css::uno::Reference< css::frame::XFrame >(); + m_bHasFrame = sal_False; + + css::uno::Reference< css::beans::XPropertySet > xPropSet( xFrame, css::uno::UNO_QUERY ); + css::uno::Reference< css::frame::XLayoutManagerEventBroadcaster > xLayoutManager; + if ( xPropSet.is() ) + { + try + { + css::uno::Any aValue = xPropSet->getPropertyValue( m_aLayoutManagerPropName ); + aValue >>= xLayoutManager; + + // remove as listener from layout manager + if ( xLayoutManager.is() ) + xLayoutManager->removeLayoutManagerEventListener( + css::uno::Reference< css::frame::XLayoutManagerListener >( + static_cast< OWeakObject* >( this ), css::uno::UNO_QUERY )); + } + catch ( css::lang::DisposedException& ) + { + } + catch ( css::uno::RuntimeException& e ) + { + throw e; + } + catch ( css::uno::Exception& ) + { + } + } + } +} + +//--------------------------------------------------------------------------------------------------------- +// XEventListener +//--------------------------------------------------------------------------------------------------------- +void SAL_CALL LayoutManagerListener::disposing( + const css::lang::EventObject& ) +throw( css::uno::RuntimeException ) +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + m_pWrkWin = 0; + m_bHasFrame = sal_False; + m_xFrame = css::uno::Reference< css::frame::XFrame >(); +} + +//--------------------------------------------------------------------------------------------------------- +// XLayoutManagerEventListener +//--------------------------------------------------------------------------------------------------------- +void SAL_CALL LayoutManagerListener::layoutEvent( + const css::lang::EventObject&, + ::sal_Int16 eLayoutEvent, + const css::uno::Any& ) +throw (css::uno::RuntimeException) +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + if ( m_pWrkWin ) + { + if ( eLayoutEvent == css::frame::LayoutManagerEvents::VISIBLE ) + { + m_pWrkWin->MakeVisible_Impl( TRUE ); + m_pWrkWin->ShowChilds_Impl(); + m_pWrkWin->ArrangeChilds_Impl( TRUE ); + } + else if ( eLayoutEvent == css::frame::LayoutManagerEvents::INVISIBLE ) + { + m_pWrkWin->MakeVisible_Impl( FALSE ); + m_pWrkWin->HideChilds_Impl(); + m_pWrkWin->ArrangeChilds_Impl( TRUE ); + } + else if ( eLayoutEvent == css::frame::LayoutManagerEvents::LOCK ) + { + m_pWrkWin->Lock_Impl( TRUE ); + } + else if ( eLayoutEvent == css::frame::LayoutManagerEvents::UNLOCK ) + { + m_pWrkWin->Lock_Impl( FALSE ); + } + } +} + +//==================================================================== + +typedef std::hash_map< sal_Int32, rtl::OUString > ToolBarResIdToResourceURLMap; + +static sal_Bool bMapInitialized = sal_False; +static ToolBarResIdToResourceURLMap aResIdToResourceURLMap; + +static rtl::OUString GetResourceURLFromResId( USHORT nResId ) +{ + if ( !bMapInitialized ) + { + osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; + if ( !bMapInitialized ) + { + sal_Int32 nIndex( 0 ); + while ( pToolBarResToName[nIndex].nId != 0 ) + { + rtl::OUString aResourceURL( rtl::OUString::createFromAscii( pToolBarResToName[nIndex].pName )); + aResIdToResourceURLMap.insert( ToolBarResIdToResourceURLMap::value_type( + sal_Int32( pToolBarResToName[nIndex].nId ), aResourceURL )); + ++nIndex; + } + bMapInitialized = sal_True; + } + } + + ToolBarResIdToResourceURLMap::const_iterator pIter = aResIdToResourceURLMap.find( nResId ); + if ( pIter != aResIdToResourceURLMap.end() ) + return pIter->second; + else + return rtl::OUString(); +} + +BOOL IsAppWorkWinToolbox_Impl( USHORT nPos ) +{ + switch ( nPos ) + { + case SFX_OBJECTBAR_APPLICATION : + case SFX_OBJECTBAR_MACRO: + case SFX_OBJECTBAR_FULLSCREEN: + return TRUE; + default: + return FALSE; + } +} + +USHORT TbxMatch( USHORT nPos ) +{ + switch ( nPos ) + { + case SFX_OBJECTBAR_APPLICATION : + return 0; + case SFX_OBJECTBAR_OPTIONS: + return 1; + case SFX_OBJECTBAR_MACRO: + return 2; + case SFX_OBJECTBAR_OBJECT: + return 3; + case SFX_OBJECTBAR_TOOLS: + return 4; + case SFX_OBJECTBAR_FULLSCREEN: + case SFX_OBJECTBAR_COMMONTASK: + case SFX_OBJECTBAR_RECORDING: + return nPos+1; + default: + return nPos; + } +} + +USHORT ChildAlignValue(SfxChildAlignment eAlign) +{ + USHORT ret = 17; + + switch (eAlign) + { + case SFX_ALIGN_HIGHESTTOP: + ret = 1; + break; + case SFX_ALIGN_LOWESTBOTTOM: + ret = 2; + break; + case SFX_ALIGN_FIRSTLEFT: + ret = 3; + break; + case SFX_ALIGN_LASTRIGHT: + ret = 4; + break; + case SFX_ALIGN_LEFT: + ret = 5; + break; + case SFX_ALIGN_RIGHT: + ret = 6; + break; + case SFX_ALIGN_FIRSTRIGHT: + ret = 7; + break; + case SFX_ALIGN_LASTLEFT: + ret = 8; + break; + case SFX_ALIGN_TOP: + ret = 9; + break; + case SFX_ALIGN_BOTTOM: + ret = 10; + break; + case SFX_ALIGN_TOOLBOXTOP: + ret = 11; + break; + case SFX_ALIGN_TOOLBOXBOTTOM: + ret = 12; + break; + case SFX_ALIGN_LOWESTTOP: + ret = 13; + break; + case SFX_ALIGN_HIGHESTBOTTOM: + ret = 14; + break; + case SFX_ALIGN_TOOLBOXLEFT: + ret = 15; + break; + case SFX_ALIGN_TOOLBOXRIGHT: + ret = 16; + break; + case SFX_ALIGN_NOALIGNMENT: + break; // -Wall not handled... + } + + return ret; +} + +USHORT ChildTravelValue( SfxChildAlignment eAlign ) +{ + USHORT ret = 17; + + switch (eAlign) + { + case SFX_ALIGN_FIRSTLEFT: + ret = 1; + break; + case SFX_ALIGN_LEFT: + ret = 2; + break; + case SFX_ALIGN_LASTLEFT: + ret = 3; + break; + case SFX_ALIGN_TOOLBOXLEFT: + ret = 4; + break; + case SFX_ALIGN_HIGHESTTOP: + ret = 5; + break; + case SFX_ALIGN_TOP: + ret = 6; + break; + case SFX_ALIGN_TOOLBOXTOP: + ret = 7; + break; + case SFX_ALIGN_LOWESTTOP: + ret = 8; + break; + case SFX_ALIGN_HIGHESTBOTTOM: + ret = 9; + break; + case SFX_ALIGN_TOOLBOXBOTTOM: + ret = 10; + break; + case SFX_ALIGN_BOTTOM: + ret = 11; + break; + case SFX_ALIGN_LOWESTBOTTOM: + ret = 12; + break; + case SFX_ALIGN_TOOLBOXRIGHT: + ret = 13; + break; + case SFX_ALIGN_FIRSTRIGHT: + ret = 14; + break; + case SFX_ALIGN_RIGHT: + ret = 15; + break; + case SFX_ALIGN_LASTRIGHT: + ret = 16; + break; + case SFX_ALIGN_NOALIGNMENT: + break; // -Wall not handled. + } + + return ret; +} + +void SfxWorkWindow::Sort_Impl() +{ + aSortedList.Remove(0, aSortedList.Count()); + for (USHORT i=0; i<pChilds->Count(); i++) + { + SfxChild_Impl *pCli = (*pChilds)[i]; + if (pCli) + { + USHORT k; + for (k=0; k<aSortedList.Count(); k++) +// if ( (*pChilds)[aSortedList[k]]->eAlign > pCli->eAlign ) + if (ChildAlignValue((*pChilds)[aSortedList[k]]->eAlign) > + ChildAlignValue(pCli->eAlign)) + break; + aSortedList.Insert (i,k); + } + } + + bSorted = TRUE; +} + + +//==================================================================== +// ctor f"ur workwin eines Frames + +SfxFrameWorkWin_Impl::SfxFrameWorkWin_Impl( Window *pWin, SfxFrame *pFrm, SfxFrame* pMaster ) + : SfxWorkWindow( + pWin, + pFrm->GetCurrentViewFrame()->GetBindings(), + pFrm->GetParentFrame() ? pFrm->GetParentFrame()->GetWorkWindow_Impl() : NULL ) + , pMasterFrame( pMaster ) + , pFrame( pFrm ) +{ + pConfigShell = pFrm->GetCurrentViewFrame(); + if ( pConfigShell && pConfigShell->GetObjectShell() ) + { + bShowStatusBar = ( !pConfigShell->GetObjectShell()->IsInPlaceActive() ); + bDockingAllowed = sal_True; + bInternalDockingAllowed = sal_True; + } + + // Die ben"otigten SplitWindows (je eins f"ur jede Seite) werden erzeugt + for ( USHORT n=0; n<SFX_SPLITWINDOWS_MAX; n++ ) + { + // Die SplitWindows sind direkte ChildWindows des WorkWindows und enthalten + // die angedockten Fenster. + + SfxChildAlignment eAlign = + ( n == SFX_SPLITWINDOWS_LEFT ? SFX_ALIGN_LEFT : + n == SFX_SPLITWINDOWS_RIGHT ? SFX_ALIGN_RIGHT : + n == SFX_SPLITWINDOWS_TOP ? SFX_ALIGN_TOP : + SFX_ALIGN_BOTTOM ); + SfxSplitWindow *pSplitWin = new SfxSplitWindow(pWorkWin, eAlign, this, pParent==0 ); + pSplit[n] = pSplitWin; + } + + //nOrigMode = SFX_VISIBILITY_CLIENT; + nOrigMode = SFX_VISIBILITY_STANDARD; + nUpdateMode = SFX_VISIBILITY_STANDARD; +} + +//==================================================================== +// ctor der Basisklasse + +SfxWorkWindow::SfxWorkWindow( Window *pWin, SfxBindings& rB, SfxWorkWindow* pParentWorkwin ) : + pParent( pParentWorkwin ), + pBindings(&rB), + pWorkWin (pWin), + pConfigShell( 0 ), + pActiveChild( 0 ), + nChilds( 0 ), + nOrigMode( 0 ), + bSorted( TRUE ), + bDockingAllowed(TRUE), + bInternalDockingAllowed(TRUE), + bAllChildsVisible(TRUE), + bIsFullScreen( FALSE ), + bShowStatusBar( TRUE ), + m_nLock( 0 ), + m_aStatusBarResName( RTL_CONSTASCII_USTRINGPARAM( "private:resource/statusbar/statusbar" )), + m_aLayoutManagerPropName( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" )), + m_aTbxTypeName( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/" )), + m_aProgressBarResName( RTL_CONSTASCII_USTRINGPARAM( "private:resource/progressbar/progressbar" )) +{ + DBG_CTOR(SfxWorkWindow, 0); + DBG_ASSERT (pBindings, "Keine Bindings!"); + + pBindings->SetWorkWindow_Impl( this ); + + pChildWins = new SfxChildWindows_Impl; + pChilds = new SfxChildList_Impl; + + // F"ur die ObjectBars wird ein fester Platz in der ChildList reserviert, + // damit sie immer in einer definierten Reihenfolge kommen. + SfxChild_Impl* pChild=0; + for (USHORT n=0; n < SFX_OBJECTBAR_MAX; ++n) + pChilds->Insert(0,pChild); + + // create and initialize layout manager listener + Reference< com::sun::star::frame::XFrame > xFrame = GetFrameInterface(); + LayoutManagerListener* pLayoutManagerListener = new LayoutManagerListener( this ); + m_xLayoutManagerListener = css::uno::Reference< css::lang::XComponent >( + static_cast< cppu::OWeakObject* >( pLayoutManagerListener ), + css::uno::UNO_QUERY ); + pLayoutManagerListener->setFrame( xFrame ); +} + +//==================================================================== +// dtor + +SfxWorkWindow::~SfxWorkWindow() +{ + DBG_DTOR(SfxWorkWindow, 0); + + // SplitWindows l"oschen + for ( USHORT n=0; n<SFX_SPLITWINDOWS_MAX; n++ ) + { + SfxSplitWindow *p = pSplit[n]; + if (p->GetWindowCount()) + ReleaseChild_Impl(*p); + delete p; + } + + // Hilfsstruktur f"ur Child-Windows l"oschen + DBG_ASSERT( pChilds->Count() == 0, "dangling childs" ); + delete pChilds; + delete pChildWins; + + if ( m_xLayoutManagerListener.is() ) + m_xLayoutManagerListener->dispose(); +} + +SystemWindow* SfxWorkWindow::GetTopWindow() const +{ + Window* pRet = pWorkWin; + while ( pRet && !pRet->IsSystemWindow() ) + pRet = pRet->GetParent(); + return (SystemWindow*) pRet; +} + +void SfxWorkWindow::Lock_Impl( BOOL bLock ) +{ + if ( bLock ) + m_nLock++; + else + --m_nLock; + if ( m_nLock<0 ) + { + DBG_ERROR("Lock count underflow!"); + m_nLock = 0; + } + + if ( !m_nLock ) + ArrangeChilds_Impl(); +} + +void SfxWorkWindow::ChangeWindow_Impl( Window *pNew ) +{ + Window *pOld = pWorkWin; + pWorkWin = pNew; + for ( USHORT nPos = 0; nPos < pChilds->Count(); ++nPos ) + { + SfxChild_Impl *pCli = (*pChilds)[nPos]; + if ( pCli && pCli->pWin && pCli->pWin->GetParent() == pOld ) + { + pCli->pWin->SetParent( pNew ); + } + } +} + +void SfxWorkWindow::SaveStatus_Impl() +{ + USHORT nCount = pChildWins->Count(); + for ( USHORT n=0; n<nCount; n++ ) + { + SfxChildWin_Impl* pCW = (*pChildWins)[n]; + SfxChildWindow *pChild = pCW->pWin; + if (pChild) + { + USHORT nFlags = pCW->aInfo.nFlags; + pCW->aInfo = pChild->GetInfo(); + pCW->aInfo.nFlags |= nFlags; + SaveStatus_Impl(pChild, pCW->aInfo); + } + } +} + +//-------------------------------------------------------------------- +// Hilfsmethode zum Freigeben der Childlisten. Wenn danach nicht der dtor +// aufgerufen wird, sondern weiter gearbeitet wird, mu\s wie im ctor von +// SfxWorkWindow noch Platz f"ur die Objectbars und SplitWindows reserviert +// werden. + +void SfxWorkWindow::DeleteControllers_Impl() +{ + DBG_CHKTHIS(SfxWorkWindow, 0); + + // SplitWindows locken (d.h. Resize-Reaktion an den + // DockingWindows unterdr"ucken) + USHORT n; + for ( n=0; n<SFX_SPLITWINDOWS_MAX; n++ ) + { + SfxSplitWindow *p = pSplit[n]; + if (p->GetWindowCount()) + p->Lock(); + } + + // Child-Windows l"oschen + for ( n=0; n<pChildWins->Count(); ) + { + SfxChildWin_Impl* pCW = (*pChildWins)[n]; + pChildWins->Remove(n); + SfxChildWindow *pChild = pCW->pWin; + if (pChild) + { +/* + USHORT nFlags = pCW->aInfo.nFlags; + pCW->aInfo = pChild->GetInfo(); + pCW->aInfo.nFlags |= nFlags; + SaveStatus_Impl(pChild, pCW->aInfo); +*/ + pChild->Hide(); + + // Wenn das ChildWindow ein direktes Childfenster ist und nicht + // in einem SplitWindow liegt, am WorkWindow abmelden. + // Nach TH ist eine Abmeldung am Splitwindow nicht erforderlich, + // wenn dieses auch gleich mit zerst"ort wird (s.u.). + if (pCW->pCli) + ReleaseChild_Impl(*pChild->GetWindow()); + pCW->pWin = 0; + pWorkWin->GetSystemWindow()->GetTaskPaneList()->RemoveWindow( pChild->GetWindow() ); + pChild->Destroy(); + } + + delete pCW; + + // ATTENTION: The array itself is cleared after this loop!! + // Therefore we have to set every array entry to zero as it could be + // accessed by calling pChild->Destroy(). + // See task 128307 (Windows) + // Window::NotifyAllChilds() calls SfxWorkWindow::DataChanged_Impl for + // 8-bit displays (WM_QUERYPALETTECHANGED message due to focus change)!! + //(*pChildWins)[n] = 0; + } + + //pChildWins->Remove((USHORT)0, nCount); + + Reference< com::sun::star::frame::XFrame > xFrame = GetFrameInterface(); + 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( m_aLayoutManagerPropName ); + aValue >>= xLayoutManager; + } + catch ( Exception& ) + { + } + } + + if ( xLayoutManager.is() ) + { + xLayoutManager->reset(); + + // StatusBar l"oschen + ResetStatusBar_Impl(); + + // ObjectBars l"oschen( zuletzt, damit pChilds nicht tote Pointer enh"alt ) + for ( USHORT i = 0; i < aObjBarList.size(); i++ ) + { + // Nicht jede Position mu\s belegt sein + USHORT nId = aObjBarList[i].nId; + if ( nId ) + aObjBarList[i].nId = 0; + } + } + + // ObjectBars werden alle auf einmal released, da sie einen + // festen zusammenh"angenden Bereich im Array pChilds belegen + pChilds->Remove(0, SFX_OBJECTBAR_MAX); + bSorted = FALSE; + + nChilds = 0; +} + +//==================================================================== +// Virtuelle Methode zum Anordnen der Childfenster. + +void SfxWorkWindow::ArrangeChilds_Impl( BOOL /*bForce*/) +{ + Arrange_Impl(); +} + +void SfxFrameWorkWin_Impl::ArrangeChilds_Impl( BOOL bForce ) +{ + if ( pFrame->IsClosing_Impl() || ( m_nLock && !bForce )) + return; + + SfxInPlaceClient *pClient = 0; + SfxViewFrame *pF = pFrame->GetCurrentViewFrame(); + if ( pF && pF->GetViewShell() ) + pClient = pF->GetViewShell()->GetIPClient(); + + if ( pClient ) + return; + + aClientArea = GetTopRect_Impl(); + if ( aClientArea.IsEmpty() ) + return; + + SvBorder aBorder; + if ( nChilds ) + { + if ( IsVisible_Impl() ) + aBorder = Arrange_Impl(); + } + + // Wenn das aktuelle Dokument der Applikation einen IPClient enth"alt, mu\s + // dem dazugeh"origen Objekt durch SetTopToolFramePixel der zur Verf"ugung + // stehende Platz zugeteilt werden. Das Objekt zeigt dann seine UITools an + // und setzt den App-Border(->SfxInPlaceEnv_Impl::ArrangeChilds_Impl()). + // Anderenfalls wird hier direkt der AppBorder gesetzt, um evtl. den Border + // zu "uberschreiben, den bisher ein Objekt aus einem anderen Dokument + // gesetzt hatte. + // Das Objekt setzt, wenn es seine UI-Tools wegnimmt, den SetAppBorder nicht, + // damit kein ObjectBar-Zappeln entsteht. + // (->SfxInPlaceEnv_Impl::ArrangeChilds_Impl()) + + pMasterFrame->SetToolSpaceBorderPixel_Impl( aBorder ); + + ArrangeAutoHideWindows( NULL ); +} + +//-------------------------------------------------------------------- + +SvBorder SfxWorkWindow::Arrange_Impl() + +/* [Beschreibung] + + Diese Methode ordnet alle sichtbaren ChildFenster so an, da\s die angedockten + Fenster nach der Sorierreihenfolge von au\sen nach innen aneinander + gesetzt werden. Wenn ein an sich sichtbares Fenster nicht mehr in die + noch freie ClientArea pa\st, wird es auf "nicht sichtbar" gesetzt. + +*/ +{ + DBG_CHKTHIS(SfxWorkWindow, 0); + + aClientArea = GetTopRect_Impl(); + aUpperClientArea = aClientArea; + + SvBorder aBorder; + if ( !nChilds ) + return aBorder; + + if (!bSorted) + Sort_Impl(); + + Point aPos; + Size aSize; + Rectangle aTmp( aClientArea ); + + for ( USHORT n=0; n<aSortedList.Count(); ++n ) + { + SfxChild_Impl* pCli = (*pChilds)[aSortedList[n]]; + if ( !pCli->pWin ) + continue; + + // Zun"achst nehmen wir an, da\s das Fenster Platz hat + pCli->nVisible |= CHILD_FITS_IN; + + // Nicht sichtbare Fenster "uberspringen + if (pCli->nVisible != CHILD_VISIBLE) + continue; + + if ( pCli->bResize ) + aSize = pCli->aSize; + else + aSize = pCli->pWin->GetSizePixel(); + + SvBorder aTemp = aBorder; + BOOL bAllowHiding = TRUE; + switch ( pCli->eAlign ) + { + case SFX_ALIGN_HIGHESTTOP: + case SFX_ALIGN_TOP: + case SFX_ALIGN_TOOLBOXTOP: + case SFX_ALIGN_LOWESTTOP: + aSize.Width() = aTmp.GetWidth(); + if ( pCli->pWin->GetType() == WINDOW_SPLITWINDOW ) + aSize = ((SplitWindow *)(pCli->pWin))->CalcLayoutSizePixel( aSize ); + bAllowHiding = FALSE; + aBorder.Top() += aSize.Height(); + aPos = aTmp.TopLeft(); + aTmp.Top() += aSize.Height(); + if ( pCli->eAlign == SFX_ALIGN_HIGHESTTOP ) + aUpperClientArea.Top() += aSize.Height(); + break; + + case SFX_ALIGN_LOWESTBOTTOM: + case SFX_ALIGN_BOTTOM: + case SFX_ALIGN_TOOLBOXBOTTOM: + case SFX_ALIGN_HIGHESTBOTTOM: + aSize.Width() = aTmp.GetWidth(); + if ( pCli->pWin->GetType() == WINDOW_SPLITWINDOW ) + aSize = ((SplitWindow *)(pCli->pWin))->CalcLayoutSizePixel( aSize ); + aBorder.Bottom() += aSize.Height(); + aPos = aTmp.BottomLeft(); + aPos.Y() -= (aSize.Height()-1); + aTmp.Bottom() -= aSize.Height(); + if ( pCli->eAlign == SFX_ALIGN_LOWESTBOTTOM ) + aUpperClientArea.Bottom() -= aSize.Height(); + break; + + case SFX_ALIGN_FIRSTLEFT: + case SFX_ALIGN_LEFT: + case SFX_ALIGN_LASTLEFT: + case SFX_ALIGN_TOOLBOXLEFT: + aSize.Height() = aTmp.GetHeight(); + if ( pCli->pWin->GetType() == WINDOW_SPLITWINDOW ) + aSize = ((SplitWindow *)(pCli->pWin))->CalcLayoutSizePixel( aSize ); + bAllowHiding = FALSE; + aBorder.Left() += aSize.Width(); + aPos = aTmp.TopLeft(); + aTmp.Left() += aSize.Width(); + if ( pCli->eAlign != SFX_ALIGN_TOOLBOXLEFT ) + aUpperClientArea.Left() += aSize.Width(); + break; + + case SFX_ALIGN_FIRSTRIGHT: + case SFX_ALIGN_RIGHT: + case SFX_ALIGN_LASTRIGHT: + case SFX_ALIGN_TOOLBOXRIGHT: + aSize.Height() = aTmp.GetHeight(); + if ( pCli->pWin->GetType() == WINDOW_SPLITWINDOW ) + aSize = ((SplitWindow *)(pCli->pWin))->CalcLayoutSizePixel( aSize ); + aBorder.Right() += aSize.Width(); + aPos = aTmp.TopRight(); + aPos.X() -= (aSize.Width()-1); + aTmp.Right() -= aSize.Width(); + if ( pCli->eAlign != SFX_ALIGN_TOOLBOXRIGHT ) + aUpperClientArea.Right() -= aSize.Width(); + break; + + default: + pCli->aSize = pCli->pWin->GetSizePixel(); + pCli->bResize = FALSE; + continue; + } + + pCli->pWin->SetPosSizePixel( aPos, aSize ); + pCli->bResize = FALSE; + pCli->aSize = aSize; + if( bAllowHiding && !RequestTopToolSpacePixel_Impl( aBorder ) ) + { + pCli->nVisible ^= CHILD_FITS_IN; + aBorder = aTemp; + } + } + + if ( aClientArea.GetWidth() >= aBorder.Left() + aBorder.Right() ) + { + aClientArea.Left() += aBorder.Left(); + aClientArea.Right() -= aBorder.Right(); + } + else + { + aBorder.Left() = aClientArea.Left(); + aBorder.Right() = aClientArea.Right(); + aClientArea.Right() = aClientArea.Left() = aTmp.Left(); + } + + if ( aClientArea.GetHeight() >= aBorder.Top() + aBorder.Bottom() ) + { + aClientArea.Top() += aBorder.Top(); + aClientArea.Bottom() -= aBorder.Bottom(); + } + else + { + aBorder.Top() = aClientArea.Top(); + aBorder.Bottom() = aClientArea.Bottom(); + aClientArea.Top() = aClientArea.Bottom() = aTmp.Top(); + } + + return IsDockingAllowed() ? aBorder : SvBorder(); +} + +//-------------------------------------------------------------------- +// Close-Handler: die Konfiguration der ChildWindows wird gespeichert. +// + +void SfxWorkWindow::Close_Impl() +{ + for (USHORT n=0; n<pChildWins->Count(); n++) + { + SfxChildWin_Impl *pCW = (*pChildWins)[n]; + SfxChildWindow *pChild = pCW->pWin; + if (pChild) + { + USHORT nFlags = pCW->aInfo.nFlags; + pCW->aInfo = pChild->GetInfo(); + pCW->aInfo.nFlags |= nFlags; + SaveStatus_Impl(pChild, pCW->aInfo); + } + } +} + +BOOL SfxWorkWindow::PrepareClose_Impl() +{ + for (USHORT n=0; n<pChildWins->Count(); n++) + { + SfxChildWin_Impl *pCW = (*pChildWins)[n]; + SfxChildWindow *pChild = pCW->pWin; + if ( pChild && !pChild->QueryClose() ) + return FALSE; + } + + return TRUE; +} + +//-------------------------------------------------------------------- + +SfxChild_Impl* SfxWorkWindow::RegisterChild_Impl( Window& rWindow, + SfxChildAlignment eAlign, BOOL bCanGetFocus ) +{ + DBG_CHKTHIS(SfxWorkWindow, 0); + DBG_ASSERT( pChilds->Count() < 255, "too many childs" ); + DBG_ASSERT( SfxChildAlignValid(eAlign), "invalid align" ); + DBG_ASSERT( !FindChild_Impl(rWindow), "child registered more than once" ); + + + if ( rWindow.GetParent() != pWorkWin ) + rWindow.SetParent( pWorkWin ); + + SfxChild_Impl *pChild = new SfxChild_Impl(rWindow, rWindow.GetSizePixel(), + eAlign, rWindow.IsVisible()); + pChild->bCanGetFocus = bCanGetFocus; + + pChilds->Insert(pChilds->Count(), pChild); + bSorted = FALSE; + nChilds++; + return (*pChilds)[pChilds->Count()-1]; +} + +//-------------------------------------------------------------------- + +void SfxWorkWindow::AlignChild_Impl( Window& rWindow, + const Size& rNewSize, + SfxChildAlignment eAlign ) +{ + DBG_CHKTHIS(SfxWorkWindow, 0); +// DBG_ASSERT( pChilds, "aligning unregistered child" ); + DBG_ASSERT( SfxChildAlignValid(eAlign), "invalid align" ); + + SfxChild_Impl *pChild = FindChild_Impl(rWindow); + if ( pChild ) + { + if (pChild->eAlign != eAlign) + bSorted = FALSE; + + pChild->eAlign = eAlign; + pChild->aSize = rNewSize; + pChild->bResize = TRUE; + } + else { + DBG_ERROR( "aligning unregistered child" ); + } +} + +//-------------------------------------------------------------------- + +void SfxWorkWindow::ReleaseChild_Impl( Window& rWindow ) +{ + DBG_CHKTHIS(SfxWorkWindow, 0); +// DBG_ASSERT( pChilds, "releasing unregistered child" ); + + SfxChild_Impl *pChild = 0; + USHORT nPos; + for ( nPos = 0; nPos < pChilds->Count(); ++nPos ) + { + pChild = (*pChilds)[nPos]; + if ( pChild ) + if ( pChild->pWin == &rWindow ) + break; + } + + if ( nPos < pChilds->Count() ) + { + bSorted = FALSE; + nChilds--; + pChilds->Remove(nPos); + delete pChild; + } + else { + DBG_ERROR( "releasing unregistered child" ); + } +} + +//-------------------------------------------------------------------- + +SfxChild_Impl* SfxWorkWindow::FindChild_Impl( const Window& rWindow ) const +{ + DBG_CHKTHIS(SfxWorkWindow, 0); + + SfxChild_Impl *pChild = 0; + USHORT nCount = pChilds->Count(); + for ( USHORT nPos = 0; nPos < nCount; ++nPos ) + { + pChild = (*pChilds)[nPos]; + if ( pChild ) + if ( pChild->pWin == &rWindow ) + return pChild; + } + + return 0; +} + +//-------------------------------------------------------------------- + +void SfxWorkWindow::ShowChilds_Impl() +{ + DBG_CHKTHIS(SfxWorkWindow, 0); + + bool bInvisible = ( !IsVisible_Impl() || ( !pWorkWin->IsReallyVisible() && !pWorkWin->IsReallyShown() )); + + SfxChild_Impl *pCli = 0; + for ( USHORT nPos = 0; nPos < pChilds->Count(); ++nPos ) + { + SfxChildWin_Impl* pCW = 0; + pCli = (*pChilds)[nPos]; + + if ( pCli && pCli->pWin ) + { + // We have to find the SfxChildWin_Impl to retrieve the + // SFX_CHILDWIN flags that can influence visibility. + for (USHORT n=0; n<pChildWins->Count(); n++) + { + SfxChildWin_Impl* pCWin = (*pChildWins)[n]; + SfxChild_Impl* pChild = pCWin->pCli; + if ( pChild == pCli ) + { + pCW = pCWin; + break; + } + } + + bool bVisible( !bInvisible ); + if ( pCW ) + { + // Check flag SFX_CHILDWIN_NEVERHIDE that forces us to show + // the child window even in situations where no child window is + // visible. + sal_uInt16 nFlags = pCW->aInfo.nFlags; + bVisible = !bInvisible || ( bInvisible & (( nFlags & SFX_CHILDWIN_NEVERHIDE ) != 0 )); + } + + if ( CHILD_VISIBLE == (pCli->nVisible & CHILD_VISIBLE) && bVisible ) + { + USHORT nFlags = pCli->bSetFocus ? 0 : SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE; + switch ( pCli->pWin->GetType() ) + { + case RSC_DOCKINGWINDOW : + ((DockingWindow*)pCli->pWin)->Show( TRUE, nFlags ); + break; + case RSC_SPLITWINDOW : + ((SplitWindow*)pCli->pWin)->Show( TRUE, nFlags ); + break; + default: + pCli->pWin->Show( TRUE, nFlags ); + break; + } + + pCli->bSetFocus = FALSE; + } + else + { + switch ( pCli->pWin->GetType() ) + { + case RSC_DOCKINGWINDOW : + ((DockingWindow*)pCli->pWin)->Hide(); + break; + default: + pCli->pWin->Hide(); + break; + } + } + } + } +} + +//-------------------------------------------------------------------- + +void SfxWorkWindow::HideChilds_Impl() +{ + SfxChild_Impl *pChild = 0; + for ( USHORT nPos = pChilds->Count(); nPos > 0; --nPos ) + { + pChild = (*pChilds)[nPos-1]; + if (pChild && pChild->pWin) + { + switch ( pChild->pWin->GetType() ) + { + case RSC_DOCKINGWINDOW : + ((DockingWindow*)pChild->pWin)->Hide(); + break; + default: + pChild->pWin->Hide(); + break; + } + } + } +} + +//------------------------------------------------------------------------ + +void SfxWorkWindow::ResetObjectBars_Impl() +{ + USHORT n; + for ( n = 0; n < aObjBarList.size(); n++ ) + aObjBarList[n].bDestroy = sal_True; + + for ( n = 0; n < pChildWins->Count(); ++n ) + (*pChildWins)[n]->nId = 0; +} + +void SfxWorkWindow::NextObjectBar_Impl( USHORT ) +{ +} + +USHORT SfxWorkWindow::HasNextObjectBar_Impl( USHORT, String* ) +{ + return 0; +} + +//------------------------------------------------------------------------ + +void SfxWorkWindow::SetObjectBar_Impl( USHORT nPos, sal_uInt32 nResId, + SfxInterface* pIFace, const String *pName) +{ + DBG_ASSERT( (nPos & SFX_POSITION_MASK) < SFX_OBJECTBAR_MAX, + "object bar position overflow" ); + + USHORT nRealPos = nPos & SFX_POSITION_MASK; + if ( pParent && IsAppWorkWinToolbox_Impl( nRealPos ) ) + { + pParent->SetObjectBar_Impl( nPos, nResId, pIFace, pName ); + return; + } + + SfxObjectBar_Impl aObjBar; + aObjBar.pIFace = pIFace; + aObjBar.nId = sal::static_int_cast<USHORT>(nResId); + aObjBar.nPos = nRealPos; + aObjBar.nMode = (nPos & SFX_VISIBILITY_MASK); + if (pName) + aObjBar.aName = *pName; + else + aObjBar.aName.Erase(); + + for ( USHORT n=0; n<aObjBarList.size(); n++ ) + { + if ( aObjBarList[n].nId == aObjBar.nId ) + { + aObjBarList[n] = aObjBar; + return; + } + } + + aObjBarList.push_back( aObjBar ); +} + +//------------------------------------------------------------------------ + +FASTBOOL SfxWorkWindow::KnowsObjectBar_Impl( USHORT nPos ) const + +/* [Beschreibung] + + Stellt fest, ob an der betreffenden Position "uberhaupt eine + Objektleiste zur Verf"ugung stehen w"urde. Ist unabh"agig davon, + ob diese tats"achlich ein- oder ausgeschaltet ist. +*/ + +{ + USHORT nRealPos = nPos & SFX_POSITION_MASK; + if ( pParent && IsAppWorkWinToolbox_Impl( nRealPos ) ) + return pParent->KnowsObjectBar_Impl( nPos ); + + for ( USHORT n=0; n<aObjBarList.size(); n++ ) + { + if ( aObjBarList[n].nPos == nRealPos ) + return TRUE; + } + + return FALSE; +} + +//------------------------------------------------------------------------ + +BOOL SfxWorkWindow::IsVisible_Impl( USHORT nMode ) const +{ + switch( nUpdateMode ) + { + case SFX_VISIBILITY_STANDARD: + return TRUE; + case SFX_VISIBILITY_UNVISIBLE: + return FALSE; + case SFX_VISIBILITY_PLUGSERVER: + case SFX_VISIBILITY_PLUGCLIENT: + case SFX_VISIBILITY_CLIENT: + case SFX_VISIBILITY_SERVER: + return !!(nMode & nUpdateMode); + default: + return !!(nMode & nOrigMode ) || + nOrigMode == SFX_VISIBILITY_STANDARD; + } +} + +Window* SfxWorkWindow::GetObjectBar_Impl( USHORT, sal_uInt32 ) +{ + return NULL; +} + +//------------------------------------------------------------------------ +void SfxFrameWorkWin_Impl::UpdateObjectBars_Impl() +{ + if ( pFrame->IsClosing_Impl() ) + return; + + SfxWorkWindow *pWork = pParent; + while ( pWork ) + { + pWork->SfxWorkWindow::UpdateObjectBars_Impl(); + pWork = pWork->GetParent_Impl(); + } + + SfxWorkWindow::UpdateObjectBars_Impl(); + +// if ( pTask->IsActive() ) + { + pWork = pParent; + while ( pWork ) + { + pWork->ArrangeChilds_Impl(); + pWork = pWork->GetParent_Impl(); + } + + ArrangeChilds_Impl( FALSE ); + + pWork = pParent; + while ( pWork ) + { + pWork->ShowChilds_Impl(); + pWork = pWork->GetParent_Impl(); + } + + ShowChilds_Impl(); + } + + ShowChilds_Impl(); +} + +Reference< ::com::sun::star::task::XStatusIndicator > SfxWorkWindow::GetStatusIndicator() +{ + Reference< com::sun::star::beans::XPropertySet > xPropSet( GetFrameInterface(), UNO_QUERY ); + Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager; + Reference< com::sun::star::task::XStatusIndicator > xStatusIndicator; + + if ( xPropSet.is() ) + { + Any aValue = xPropSet->getPropertyValue( m_aLayoutManagerPropName ); + aValue >>= xLayoutManager; + if ( xLayoutManager.is() ) + { + xLayoutManager->createElement( m_aProgressBarResName ); + xLayoutManager->showElement( m_aProgressBarResName ); + + Reference< ::com::sun::star::ui::XUIElement > xProgressBar = + xLayoutManager->getElement( m_aProgressBarResName ); + if ( xProgressBar.is() ) + { + xStatusIndicator = Reference< ::com::sun::star::task::XStatusIndicator >( + xProgressBar->getRealInterface(), UNO_QUERY ); + } + } + } + + return xStatusIndicator; +} + +//------------------------------------------------------------------------ + +sal_Bool SfxWorkWindow::IsPluginMode( SfxObjectShell* pObjShell ) +{ + if ( pObjShell && pObjShell->GetMedium() ) + { + SFX_ITEMSET_ARG( pObjShell->GetMedium()->GetItemSet(), pViewOnlyItem, SfxBoolItem, SID_VIEWONLY, sal_False ); + if ( pViewOnlyItem && pViewOnlyItem->GetValue() ) + return sal_True; + } + + return sal_False; +} + +//------------------------------------------------------------------------ + +::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > SfxWorkWindow::GetFrameInterface() +{ + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xFrame; + + SfxDispatcher* pDispatcher( GetBindings().GetDispatcher() ); + if ( pDispatcher ) + { + SfxViewFrame* pFrame = pDispatcher->GetFrame(); + if ( pFrame ) + xFrame = pFrame->GetFrame().GetFrameInterface(); + } + + return xFrame; +} + +//------------------------------------------------------------------------ + +void SfxWorkWindow::UpdateObjectBars_Impl() +{ + // SplitWindows locken (d.h. Resize-Reaktion an den + // DockingWindows unterdr"ucken) + USHORT n; + for ( n=0; n<SFX_SPLITWINDOWS_MAX; n++ ) + { + SfxSplitWindow *p = pSplit[n]; + if (p->GetWindowCount()) + p->Lock(); + } + + // was man so "ofters braucht, merkt man sich (spart Code und Laufzeit) + SFX_APP(); + + Reference< com::sun::star::beans::XPropertySet > xPropSet( GetFrameInterface(), UNO_QUERY ); + Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager; + + if ( xPropSet.is() ) + { + Any aValue = xPropSet->getPropertyValue( m_aLayoutManagerPropName ); + aValue >>= xLayoutManager; + } + + if ( !xLayoutManager.is() ) + return; + + sal_Bool bPluginMode( sal_False ); + SfxDispatcher* pDispatcher( GetBindings().GetDispatcher() ); + + if ( pDispatcher ) + { + SfxViewFrame* pFrame = pDispatcher->GetFrame(); + if ( pFrame ) + bPluginMode = IsPluginMode( pFrame->GetObjectShell() ); + } + + // "uber alle Toolboxen iterieren + xLayoutManager->lock(); + for ( n = 0; n < aObjBarList.size(); ++n ) + { + USHORT nId = aObjBarList[n].nId; + sal_Bool bDestroy = aObjBarList[n].bDestroy; + + // die Modi bestimmen, f"ur die die ToolBox gilt + USHORT nTbxMode = aObjBarList[n].nMode; + FASTBOOL bFullScreenTbx = SFX_VISIBILITY_FULLSCREEN == + ( nTbxMode & SFX_VISIBILITY_FULLSCREEN ); + nTbxMode &= ~SFX_VISIBILITY_FULLSCREEN; + nTbxMode &= ~SFX_VISIBILITY_VIEWER; + + // wird in diesem Kontext eine ToolBox gefordert? + FASTBOOL bModesMatching = ( nUpdateMode && ( nTbxMode & nUpdateMode) == nUpdateMode ); + if ( bDestroy ) + { + rtl::OUString aTbxId( m_aTbxTypeName ); + aTbxId += GetResourceURLFromResId( aObjBarList[n].nId ); + xLayoutManager->destroyElement( aTbxId ); + } + else if ( nId != 0 && ( ( bModesMatching && !bIsFullScreen ) || + ( bIsFullScreen && bFullScreenTbx ) ) ) + { + rtl::OUString aTbxId( m_aTbxTypeName ); + aTbxId += GetResourceURLFromResId( aObjBarList[n].nId ); + if ( !IsDockingAllowed() && !xLayoutManager->isElementFloating( aTbxId )) + xLayoutManager->destroyElement( aTbxId ); + else + { + xLayoutManager->requestElement( aTbxId ); + if ( bPluginMode ) + xLayoutManager->lockWindow( aTbxId ); + } + } + else if ( nId != 0 ) + { + // ggf. Toolbox an dieser Position l"oschen + rtl::OUString aTbxId( m_aTbxTypeName ); + aTbxId += GetResourceURLFromResId( aObjBarList[n].nId ); + xLayoutManager->destroyElement( aTbxId ); + } + } + + UpdateStatusBar_Impl(); + + // unlocking automatically forces Layout + xLayoutManager->unlock(); + + UpdateChildWindows_Impl(); + + // SplitWindows wieder ent-locken + for ( n=0; n<SFX_SPLITWINDOWS_MAX; n++ ) + { + SfxSplitWindow *p = pSplit[n]; + if (p->GetWindowCount()) + p->Lock(FALSE); + } +} + +bool SfxWorkWindow::AllowChildWindowCreation_Impl( const SfxChildWin_Impl& i_rCW ) const +{ + // or checking the availability of child windows, we need access to the module + const SfxViewFrame* pViewFrame = pBindings->GetDispatcher_Impl()->GetFrame(); + const SfxObjectShell* pShell = pViewFrame ? pViewFrame->GetObjectShell() : NULL; + const SfxModule* pModule = pShell ? pShell->GetModule() : NULL; + ENSURE_OR_RETURN( pModule, "SfxWorkWindow::UpdateChildWindows_Impl: did not find an SfxModule to ask for the child win availability!", true ); + return pModule->IsChildWindowAvailable( i_rCW.nId, pViewFrame ); +} + +void SfxWorkWindow::UpdateChildWindows_Impl() +{ + // alle vorhandenen oder in den Kontext gekommenen ChildWindows + for ( USHORT n=0; n<pChildWins->Count(); n++ ) + { + SfxChildWin_Impl *pCW = (*pChildWins)[n]; + SfxChildWindow *pChildWin = pCW->pWin; + BOOL bCreate = FALSE; + if ( pCW->nId && !pCW->bDisabled && (pCW->aInfo.nFlags & SFX_CHILDWIN_ALWAYSAVAILABLE || IsVisible_Impl( pCW->nVisibility ) ) ) + { + // Im Kontext ist ein geeignetes ChildWindow erlaubt; + // ist es auch eingeschaltet ? + if ( pChildWin == NULL && pCW->bCreate ) + { + // Internal docking is only used for embedding into another + // container. We force the floating state of all floatable + // child windows. + if ( !bInternalDockingAllowed ) + { + // Special case for all non-floatable child windows. We have + // to prevent the creation here! + bCreate = !( pCW->aInfo.nFlags & SFX_CHILDWIN_FORCEDOCK ); + } + else if ( !IsDockingAllowed() || bIsFullScreen ) // || !bInternalDocking ) + { + // im PresentationMode oder FullScreen nur FloatingWindows + SfxChildAlignment eAlign; + if ( pCW->aInfo.GetExtraData_Impl( &eAlign ) ) + bCreate = ( eAlign == SFX_ALIGN_NOALIGNMENT ); + } + else + bCreate = TRUE; + + if ( bCreate ) + bCreate = AllowChildWindowCreation_Impl( *pCW ); + + // Momentan kein Fenster da, aber es ist eingeschaltet; Fenster + // und ggf. Context erzeugen + if ( bCreate ) + CreateChildWin_Impl( pCW, FALSE ); + + if ( !bAllChildsVisible ) + { + if ( pCW->pCli ) + pCW->pCli->nVisible &= ~CHILD_ACTIVE; + } + } + else if ( pChildWin ) + { + // Fenster existiert schon; soll es auch sichtbar sein ? + if ( ( !bIsFullScreen || pChildWin->GetAlignment() == SFX_ALIGN_NOALIGNMENT ) && bAllChildsVisible ) + { + // Updatemode ist kompatibel; auf jeden Fall wieder einschalten + bCreate = AllowChildWindowCreation_Impl( *pCW ); + if ( bCreate ) + { + if ( pCW->pCli ) + { + // Fenster ist direktes Child + if ( bAllChildsVisible && ( (IsDockingAllowed() && bInternalDockingAllowed) || pCW->pCli->eAlign == SFX_ALIGN_NOALIGNMENT ) ) + pCW->pCli->nVisible |= CHILD_NOT_HIDDEN; + } + else + { + if ( pCW->bCreate && IsDockingAllowed() && bInternalDockingAllowed ) + // Fenster liegt in einem SplitWindow + ((SfxDockingWindow*)pChildWin->GetWindow())->Reappear_Impl(); + } + + if ( pCW->nInterfaceId != pChildWin->GetContextId() ) + pChildWin->CreateContext( pCW->nInterfaceId, GetBindings() ); + } + } + } + } + + if ( pChildWin && !bCreate ) + { + if ( !pChildWin->QueryClose() || pChildWin->IsHideNotDelete() || Application::IsUICaptured() ) + { + if ( pCW->pCli ) + { + if ( pCW->pCli->nVisible & CHILD_NOT_HIDDEN ) + pCW->pCli->nVisible ^= CHILD_NOT_HIDDEN; + } + else + ((SfxDockingWindow*)pChildWin->GetWindow())->Disappear_Impl(); + } + else + RemoveChildWin_Impl( pCW ); + } + } +} + +void SfxWorkWindow::CreateChildWin_Impl( SfxChildWin_Impl *pCW, BOOL bSetFocus ) +{ + if ( pCW->aInfo.bVisible != 42 ) + pCW->aInfo.bVisible = TRUE; + + SfxChildWindow *pChildWin = SfxChildWindow::CreateChildWindow( pCW->nId, pWorkWin, &GetBindings(), pCW->aInfo); + if (pChildWin) + { + if ( bSetFocus ) + bSetFocus = pChildWin->WantsFocus(); + pChildWin->SetWorkWindow_Impl( this ); +#if 0 + // Enable-Status richtig setzen + pChildWin->GetWindow()->EnableInput( pCW->bEnable && + ( pWorkWin->IsInputEnabled() /* || pChildWin->GetAlignment() == SFX_ALIGN_NOALIGNMENT */ ) ); +#endif + // Zumindest der ExtraString wird beim Auswerten ver"andert, also neu holen + SfxChildWinInfo aInfo = pChildWin->GetInfo(); + pCW->aInfo.aExtraString = aInfo.aExtraString; + pCW->aInfo.bVisible = aInfo.bVisible; + pCW->aInfo.nFlags |= aInfo.nFlags; + + // Nein !! Sonst kann man keine Fenster defaultmaessig ausschalten ( Partwindow! ) +// pCW->aInfo.bVisible = TRUE; + + // Erzeugung war erfolgreich + GetBindings().Invalidate(pCW->nId); + + USHORT nPos = pChildWin->GetPosition(); + if (nPos != CHILDWIN_NOPOS) + { + DBG_ASSERT(nPos < SFX_OBJECTBAR_MAX, "Illegal objectbar position!"); + if ((*pChilds)[TbxMatch(nPos)])// && +// pChildWin->GetAlignment() == (*pChilds)[nPos]->eAlign ) + { + // ChildWindow ersetzt ObjectBar + (*pChilds)[TbxMatch(nPos)]->nVisible ^= CHILD_NOT_HIDDEN; + } + } + + // make childwin keyboard accessible + pWorkWin->GetSystemWindow()->GetTaskPaneList()->AddWindow( pChildWin->GetWindow() ); + + pCW->pWin = pChildWin; + + if ( pChildWin->GetAlignment() == SFX_ALIGN_NOALIGNMENT || pChildWin->GetWindow()->GetParent() == pWorkWin) + { + // Das Fenster ist entweder nicht angedockt oder au\serhalb + // eines SplitWindows angedockt und mu\s daher explizit als + // Child registriert werden + pCW->pCli = RegisterChild_Impl(*(pChildWin->GetWindow()), pChildWin->GetAlignment(), pChildWin->CanGetFocus()); + pCW->pCli->nVisible = CHILD_VISIBLE; + if ( pChildWin->GetAlignment() != SFX_ALIGN_NOALIGNMENT && bIsFullScreen ) + pCW->pCli->nVisible ^= CHILD_ACTIVE; + pCW->pCli->bSetFocus = bSetFocus; + } + else + { + // Ein angedocktes Fenster, dessen Parent nicht das WorkWindow ist, + // mu\s in einem SplitWindow liegen und daher nicht explizit + // registriert werden. + // Das passiert aber schon bei der Initialisierung des + // SfxDockingWindows! + } + + if ( pCW->nInterfaceId != pChildWin->GetContextId() ) + pChildWin->CreateContext( pCW->nInterfaceId, GetBindings() ); + + // Information in der INI-Datei sichern + SaveStatus_Impl(pChildWin, pCW->aInfo); + } +} + +void SfxWorkWindow::RemoveChildWin_Impl( SfxChildWin_Impl *pCW ) +{ + USHORT nId = pCW->nSaveId; + SfxChildWindow *pChildWin = pCW->pWin; + + // vorhandenes Fenster geht aus dem Kontext und wird daher entfernt + USHORT nPos = pChildWin->GetPosition(); + if (nPos != CHILDWIN_NOPOS) + { +/* + // ChildWindow "uberlagert einen ObjectBar + DBG_ASSERT(nPos < SFX_OBJECTBAR_MAX, "Illegal objectbar position!"); + if ((*pChilds)[TbxMatch(nPos)] && + (aObjBars[nPos].nMode & nUpdateMode) ) //&& +// pChildWin->GetAlignment() == (*pChilds)[nPos]->eAlign ) + { + // ObjectBar war "uberlagert; jetzt wieder anzeigen + (*pChilds)[TbxMatch(nPos)]->nVisible ^= CHILD_NOT_HIDDEN; + } +*/ + } + + // Information in der INI-Datei sichern + USHORT nFlags = pCW->aInfo.nFlags; + pCW->aInfo = pChildWin->GetInfo(); + pCW->aInfo.nFlags |= nFlags; + SaveStatus_Impl(pChildWin, pCW->aInfo); + + pChildWin->Hide(); + + if ( pCW->pCli ) + { + // ChildWindow ist ein direktes ChildWindow und mu\s sich daher + // beim WorkWindow abmelden + pCW->pCli = 0; + ReleaseChild_Impl(*pChildWin->GetWindow()); + } + else + { + // ChildWindow liegt in einem SplitWindow und meldet sich + // selbst im dtor dort ab + } + + pWorkWin->GetSystemWindow()->GetTaskPaneList()->RemoveWindow( pChildWin->GetWindow() ); + pCW->pWin = 0; + pChildWin->Destroy(); + + GetBindings().Invalidate( nId ); +} + +void SfxWorkWindow::ResetStatusBar_Impl() +{ + aStatBar.nId = 0; +} + +//-------------------------------------------------------------------- +void SfxWorkWindow::SetStatusBar_Impl( sal_uInt32 nResId, SfxShell*, SfxBindings& ) +{ + if ( nResId && bShowStatusBar && IsVisible_Impl() ) + aStatBar.nId = sal::static_int_cast<USHORT>(nResId); +} + +#define SFX_ITEMTYPE_STATBAR 4 + +void SfxWorkWindow::SetTempStatusBar_Impl( BOOL bSet ) +{ + if ( aStatBar.bTemp != bSet && bShowStatusBar && IsVisible_Impl() ) + { + BOOL bOn = FALSE; + BOOL bReset = FALSE; + if ( bSet && !aStatBar.nId ) + { + bReset = TRUE; + SetStatusBar_Impl( SFX_ITEMTYPE_STATBAR, SFX_APP(), GetBindings() ); + } + + if ( aStatBar.nId && aStatBar.bOn && !bIsFullScreen ) + bOn = TRUE; + + aStatBar.bTemp = bSet; + if ( !bOn || bReset || (!bSet && aStatBar.nId ) ) + { + // Nur was tun, wenn die Temp-Einstellung wirklich was bewirkt + UpdateStatusBar_Impl(); + ArrangeChilds_Impl(); + ShowChilds_Impl(); + } + + if ( bReset ) + ResetStatusBar_Impl(); + } +} + +void SfxWorkWindow::UpdateStatusBar_Impl() +{ + Reference< ::com::sun::star::beans::XPropertySet > xPropSet( GetFrameInterface(), UNO_QUERY ); + Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager; + + Any aValue = xPropSet->getPropertyValue( m_aLayoutManagerPropName ); + aValue >>= xLayoutManager; + + // keine Statusleiste, wenn keine Id gew"unscht oder bei FullScreenView + // oder wenn ausgeschaltet + if ( aStatBar.nId && IsDockingAllowed() && bInternalDockingAllowed && bShowStatusBar && + ( (aStatBar.bOn && !bIsFullScreen) || aStatBar.bTemp ) ) + { + // Id hat sich ge"andert, also passenden Statusbarmanager erzeugen, + // dieser "ubernimmt die aktuelle Statusleiste; + if ( xLayoutManager.is() ) + xLayoutManager->requestElement( m_aStatusBarResName ); + } + else + { + // Aktuelle StatusBar vernichten + // Der Manager erzeugt die Statusleiste nur, er zerst"ort sie + // nicht ! + if ( xLayoutManager.is() ) + xLayoutManager->destroyElement( m_aStatusBarResName ); + } +} + +//------------------------------------------------------------------------ +/* +void SfxWorkWindow::SetObjectBarVisibility_Impl( USHORT nMask ) +{ + switch( nMask ) + { + case SFX_VISIBILITY_UNVISIBLE: + case SFX_VISIBILITY_STANDARD: + case SFX_VISIBILITY_CLIENT: + case SFX_VISIBILITY_SERVER: + nOrigMode = nMask; + } + if (nMask != nUpdateMode) + nUpdateMode = nMask; +}*/ + +void SfxWorkWindow::MakeVisible_Impl( BOOL bVis ) +{ + if ( bVis ) + nOrigMode = SFX_VISIBILITY_STANDARD; + else + nOrigMode = SFX_VISIBILITY_UNVISIBLE; + + if ( nOrigMode != nUpdateMode) + nUpdateMode = nOrigMode; +} + +BOOL SfxWorkWindow::IsVisible_Impl() +{ + return nOrigMode != SFX_VISIBILITY_UNVISIBLE; +} + +//------------------------------------------------------------------------ +void SfxWorkWindow::HidePopups_Impl(BOOL bHide, BOOL bParent, USHORT nId ) +{ + for ( USHORT n = 0; n < pChildWins->Count(); ++n ) + { + SfxChildWindow *pCW = (*pChildWins)[n]->pWin; + if (pCW && pCW->GetAlignment() == SFX_ALIGN_NOALIGNMENT && pCW->GetType() != nId) + { + Window *pWin = pCW->GetWindow(); + SfxChild_Impl *pChild = FindChild_Impl(*pWin); + if (bHide) + { + pChild->nVisible &= ~CHILD_ACTIVE; + pCW->Hide(); + } + else + { + pChild->nVisible |= CHILD_ACTIVE; + if ( CHILD_VISIBLE == (pChild->nVisible & CHILD_VISIBLE) ) + pCW->Show( SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE ); + } + } + } + + if ( bParent && pParent ) + pParent->HidePopups_Impl( bHide, bParent, nId ); +} + +//------------------------------------------------------------------------ + +void SfxWorkWindow::ConfigChild_Impl(SfxChildIdentifier eChild, + SfxDockingConfig eConfig, USHORT nId) +{ + SfxDockingWindow* pDockWin=0; + USHORT nPos = USHRT_MAX; + Window *pWin=0; + SfxChildWin_Impl *pCW = 0; + + if ( eChild == SFX_CHILDWIN_OBJECTBAR ) + { + return; + } + else + { + // configure direct childwindow + for (USHORT n=0; n<pChildWins->Count(); n++) + { + pCW = (*pChildWins)[n]; + SfxChildWindow *pChild = pCW->pWin; + if ( pChild ) + { + if ( pChild->GetType() == nId ) + { + if ( pChild->GetWindow()->GetType() == RSC_DOCKINGWINDOW ) + // it's a DockingWindow + pDockWin = (SfxDockingWindow*) pChild->GetWindow(); + else + // FloatingWindow or ModelessDialog + pWin = pChild->GetWindow(); + break; + } + } + } + + if ( pDockWin ) + { + if ( eChild == SFX_CHILDWIN_DOCKINGWINDOW || pDockWin->GetAlignment() == SFX_ALIGN_NOALIGNMENT ) + { + if ( eChild == SFX_CHILDWIN_SPLITWINDOW && eConfig == SFX_TOGGLEFLOATMODE) + { + // DockingWindow was dragged out of a SplitWindow + pCW->pCli = RegisterChild_Impl(*pDockWin, pDockWin->GetAlignment(), pCW->pWin->CanGetFocus()); + pCW->pCli->nVisible = CHILD_VISIBLE; + } + + pWin = pDockWin; + } + else + { + SfxSplitWindow *pSplitWin = GetSplitWindow_Impl(pDockWin->GetAlignment()); + + // configure DockingWindow inside a SplitWindow + if ( eConfig == SFX_TOGGLEFLOATMODE) + { + // DockingWindow was dragged into a SplitWindow + pCW->pCli = 0; + ReleaseChild_Impl(*pDockWin); + } + + pWin = pSplitWin->GetSplitWindow(); + if ( pSplitWin->GetWindowCount() == 1 ) + ((SplitWindow*)pWin)->Show( TRUE, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE ); + } + } + + DBG_ASSERT( pCW, "Unknown window!" ); + if ( !pCW && pParent ) + { + pParent->ConfigChild_Impl( eChild, eConfig, nId ); + return; + } + } + + if ( !bSorted ) + // windows may have been registered and released without an update until now + Sort_Impl(); + + SfxChild_Impl *pChild = 0; + USHORT n; + for ( n=0; n<aSortedList.Count(); ++n ) + { + pChild = (*pChilds)[aSortedList[n]]; + if ( pChild ) + if ( pChild->pWin == pWin ) + break; + } + + if ( n < aSortedList.Count() ) + // sometimes called while toggeling float mode + nPos = aSortedList[n]; + + switch ( eConfig ) + { + case SFX_SETDOCKINGRECTS : + { + if ( nPos == USHRT_MAX ) + return; + +// SfxChild_Impl *pChild = (*pChilds)[nPos]; + Rectangle aOuterRect( GetTopRect_Impl() ); + aOuterRect.SetPos( pWorkWin->OutputToScreenPixel( aOuterRect.TopLeft() )); + Rectangle aInnerRect( aOuterRect ); + BOOL bTbx = (eChild == SFX_CHILDWIN_OBJECTBAR); + + // Das gerade betroffene Fenster wird bei der Berechnung des + // inneren Rechtecks mit eingeschlossen! + for ( USHORT m=0; m<aSortedList.Count(); ++m ) + { + USHORT i=aSortedList[m]; + SfxChild_Impl* pCli = (*pChilds)[i]; + + if ( pCli && pCli->nVisible == CHILD_VISIBLE && pCli->pWin ) + { + switch ( pCli->eAlign ) + { + case SFX_ALIGN_TOP: + // Objekt-Toolboxen kommen immer zuletzt + //if ( bTbx || i <= nPos) + aInnerRect.Top() += pCli->aSize.Height(); + break; + + case SFX_ALIGN_TOOLBOXTOP: + // Toolbox geht nur vor, wenn nicht h"ohere Position + if ( bTbx && i <= nPos) + aInnerRect.Top() += pCli->aSize.Height(); + break; + + case SFX_ALIGN_HIGHESTTOP: + // Geht immer vor + aInnerRect.Top() += pCli->aSize.Height(); + break; + + case SFX_ALIGN_LOWESTTOP: + // Wird nur mitgez"ahlt, wenn es das aktuelle Fenster ist + if ( i == nPos ) + aInnerRect.Top() += pCli->aSize.Height(); + break; + + case SFX_ALIGN_BOTTOM: + // Objekt-Toolboxen kommen immer zuletzt + //if ( bTbx || i <= nPos) + aInnerRect.Bottom() -= pCli->aSize.Height(); + break; + + case SFX_ALIGN_TOOLBOXBOTTOM: + // Toolbox geht nur vor, wenn nicht h"ohere Position + if ( bTbx && i <= nPos) + aInnerRect.Bottom() -= pCli->aSize.Height(); + break; + + case SFX_ALIGN_LOWESTBOTTOM: + // Geht immer vor + aInnerRect.Bottom() -= pCli->aSize.Height(); + break; + + case SFX_ALIGN_HIGHESTBOTTOM: + // Wird nur mitgez"ahlt, wenn es das aktuelle Fenster ist + if ( i == nPos ) + aInnerRect.Bottom() -= pCli->aSize.Height(); + break; + + case SFX_ALIGN_LEFT: + // Toolboxen kommen immer zuletzt + //if (bTbx || i <= nPos) + aInnerRect.Left() += pCli->aSize.Width(); + break; + + case SFX_ALIGN_TOOLBOXLEFT: + // Toolboxen kommen immer zuletzt + if (bTbx && i <= nPos) + aInnerRect.Left() += pCli->aSize.Width(); + break; + + case SFX_ALIGN_FIRSTLEFT: + // Geht immer vor + aInnerRect.Left() += pCli->aSize.Width(); + break; + + case SFX_ALIGN_LASTLEFT: + // Wird nur mitgez"ahlt, wenn es das aktuelle Fenster ist + if (i == nPos) + aInnerRect.Left() += pCli->aSize.Width(); + + case SFX_ALIGN_RIGHT: + // Toolboxen kommen immer zuletzt + //if (bTbx || i <= nPos) + aInnerRect.Right() -= pCli->aSize.Width(); + break; + + case SFX_ALIGN_TOOLBOXRIGHT: + // Toolboxen kommen immer zuletzt + if (bTbx && i <= nPos) + aInnerRect.Right() -= pCli->aSize.Width(); + break; + + case SFX_ALIGN_FIRSTRIGHT: + // Wird nur mitgez"ahlt, wenn es das aktuelle Fenster ist + if (i == nPos) + aInnerRect.Right() -= pCli->aSize.Width(); + break; + + case SFX_ALIGN_LASTRIGHT: + // Geht immer vor + aInnerRect.Right() -= pCli->aSize.Width(); + break; + + default: + break; + } + } + } + + pDockWin->SetDockingRects(aOuterRect, aInnerRect); + break; + } + + case SFX_MOVEDOCKINGWINDOW : + case SFX_ALIGNDOCKINGWINDOW : + case SFX_TOGGLEFLOATMODE: + { + if ( nPos == USHRT_MAX && !pCW ) + return; + + SfxChildAlignment eAlign = SFX_ALIGN_NOALIGNMENT; + SfxChild_Impl *pCli = ( nPos != USHRT_MAX ) ? (*pChilds)[nPos] : 0; + if ( pCli && pDockWin ) + { + eAlign = pDockWin->GetAlignment(); + if ( eChild == SFX_CHILDWIN_DOCKINGWINDOW || eAlign == SFX_ALIGN_NOALIGNMENT) + { + // configuration inside the SplitWindow, no change for the SplitWindows' configuration + pCli->bResize = TRUE; + pCli->aSize = pDockWin->GetSizePixel(); + } + } + + if ( pCli ) + { + if( pCli->eAlign != eAlign ) + { + bSorted = FALSE; + pCli->eAlign = eAlign; + } + + ArrangeChilds_Impl(); + ShowChilds_Impl(); + } + + if ( pCW && pCW->pWin ) + { + // store changed configuration + USHORT nFlags = pCW->aInfo.nFlags; + pCW->aInfo = pCW->pWin->GetInfo(); + pCW->aInfo.nFlags |= nFlags; + if ( eConfig != SFX_MOVEDOCKINGWINDOW ) + SaveStatus_Impl( pCW->pWin, pCW->aInfo); + } + + break; + } + } +} + + +//-------------------------------------------------------------------- + +void SfxWorkWindow::SetChildWindowVisible_Impl( sal_uInt32 lId, BOOL bEnabled, USHORT nMode ) +{ + USHORT nInter = (USHORT) ( lId >> 16 ); + USHORT nId = (USHORT) ( lId & 0xFFFF ); + + SfxChildWin_Impl *pCW=NULL; + SfxWorkWindow *pWork = pParent; + + // Den obersten parent nehmen; ChildWindows werden immer am WorkWindow + // der Task bzw. des Frames oder am AppWorkWindow angemeldet + while ( pWork && pWork->pParent ) + pWork = pWork->pParent; + + if ( pWork ) + { + // Dem Parent schon bekannt ? + USHORT nCount = pWork->pChildWins->Count(); + for (USHORT n=0; n<nCount; n++) + if ((*pWork->pChildWins)[n]->nSaveId == nId) + { + pCW = (*pWork->pChildWins)[n]; + break; + } + } + + if ( !pCW ) + { + // Kein Parent oder dem Parent noch unbekannt, dann bei mir suchen + USHORT nCount = pChildWins->Count(); + for (USHORT n=0; n<nCount; n++) + if ((*pChildWins)[n]->nSaveId == nId) + { + pCW = (*pChildWins)[n]; + break; + } + } + + if ( !pCW ) + { + // Ist neu, also initialisieren; je nach Flag beim Parent oder bei + // mir eintragen + pCW = new SfxChildWin_Impl( lId ); + pCW->nId = nId; + InitializeChild_Impl( pCW ); + if ( pWork && !( pCW->aInfo.nFlags & SFX_CHILDWIN_TASK ) ) + pWork->pChildWins->Insert( pWork->pChildWins->Count(), pCW ); + else + pChildWins->Insert( pChildWins->Count(), pCW ); + } + + pCW->nId = nId; + if ( nInter ) + pCW->nInterfaceId = nInter; + pCW->nVisibility = nMode; + pCW->bEnable = bEnabled; +#if 0 + if ( pCW->pWin ) + pCW->pWin->GetWindow()->EnableInput( bEnabled && + ( pWorkWin->IsInputEnabled() /* || pCW->pWin->GetAlignment() == SFX_ALIGN_NOALIGNMENT */ ) ); +#endif + pCW->nVisibility = nMode; +} + +//-------------------------------------------------------------------- +// Der An/Aus-Status eines ChildWindows wird umgeschaltet. + +void SfxWorkWindow::ToggleChildWindow_Impl(USHORT nId, BOOL bSetFocus) +{ + USHORT nCount = pChildWins->Count(); + USHORT n; + for (n=0; n<nCount; n++) + if ((*pChildWins)[n]->nId == nId) + break; + + if ( n<nCount ) + { + // Das Fenster ist schon bekannt + SfxChildWin_Impl *pCW = (*pChildWins)[n]; + SfxChildWindow *pChild = pCW->pWin; + + bool bCreationAllowed( true ); + if ( !bInternalDockingAllowed ) + { + // Special case for all non-floatable child windows. We have + // to prevent the creation here! + bCreationAllowed = !( pCW->aInfo.nFlags & SFX_CHILDWIN_FORCEDOCK ); + } + + if ( bCreationAllowed ) + { + if ( pCW->bCreate ) + { + if ( pChild ) + { + if ( pChild->QueryClose() ) + { + pCW->bCreate = FALSE; + if ( pChild->IsHideAtToggle() ) + { + ShowChildWindow_Impl( nId, FALSE, bSetFocus ); + } + else + { + // Fenster soll ausgeschaltet werdem + pChild->SetVisible_Impl( FALSE ); + RemoveChildWin_Impl( pCW ); + } + } + } + else + { + // no actual Window exists, yet => just remember the "switched off" state + pCW->bCreate = FALSE; + } + } + else + { + pCW->bCreate = AllowChildWindowCreation_Impl( *pCW ); + if ( pCW->bCreate ) + { + if ( pChild ) + { + ShowChildWindow_Impl( nId, TRUE, bSetFocus ); + } + else + { + // create actual Window + CreateChildWin_Impl( pCW, bSetFocus ); + if ( !pCW->pWin ) + // no success + pCW->bCreate = FALSE; + } + } + } + } + + ArrangeChilds_Impl(); + ShowChilds_Impl(); + + if ( pCW->bCreate && bCreationAllowed ) + { + if ( !pCW->pCli ) + { + SfxDockingWindow *pDock = + (SfxDockingWindow*) pCW->pWin->GetWindow(); + if ( pDock->IsAutoHide_Impl() ) + pDock->AutoShow_Impl(); + } + } + + return; + } + else if ( pParent ) + { + pParent->ToggleChildWindow_Impl( nId, bSetFocus ); + return; + } + +#ifdef DBG_UTIL + nCount = pChildWins->Count(); + for (n=0; n<nCount; n++) + if ((*pChildWins)[n]->nSaveId == nId) + break; + + if ( n < nCount ) + { + DBG_ERROR("ChildWindow ist nicht im Kontext!"); + } + else + { + DBG_ERROR("ChildWindow ist nicht registriert!"); + } +#endif +} + +//-------------------------------------------------------------------- + +BOOL SfxWorkWindow::HasChildWindow_Impl(USHORT nId) +{ + USHORT nCount = pChildWins->Count(); + USHORT n; + for (n=0; n<nCount; n++) + if ((*pChildWins)[n]->nSaveId == nId) + break; + + if (n<nCount) + { + SfxChildWin_Impl *pCW = (*pChildWins)[n]; + SfxChildWindow *pChild = pCW->pWin; + return ( pChild && pCW->bCreate ); + } + + if ( pParent ) + return pParent->HasChildWindow_Impl( nId ); + + return FALSE; +} + +BOOL SfxWorkWindow::IsFloating( USHORT nId ) +{ + SfxChildWin_Impl *pCW=NULL; + SfxWorkWindow *pWork = pParent; + + // Den obersten parent nehmen; ChildWindows werden immer am WorkWindow + // der Task bzw. des Frames oder am AppWorkWindow angemeldet + while ( pWork && pWork->pParent ) + pWork = pWork->pParent; + + if ( pWork ) + { + // Dem Parent schon bekannt ? + USHORT nCount = pWork->pChildWins->Count(); + for (USHORT n=0; n<nCount; n++) + if ((*pWork->pChildWins)[n]->nSaveId == nId) + { + pCW = (*pWork->pChildWins)[n]; + break; + } + } + + if ( !pCW ) + { + // Kein Parent oder dem Parent noch unbekannt, dann bei mir suchen + USHORT nCount = pChildWins->Count(); + for (USHORT n=0; n<nCount; n++) + if ((*pChildWins)[n]->nSaveId == nId) + { + pCW = (*pChildWins)[n]; + break; + } + } + + if ( !pCW ) + { + // Ist neu, also initialisieren; je nach Flag beim Parent oder bei + // mir eintragen + pCW = new SfxChildWin_Impl( nId ); + pCW->bEnable = FALSE; + pCW->nId = 0; + pCW->nVisibility = 0; + InitializeChild_Impl( pCW ); + if ( pWork && !( pCW->aInfo.nFlags & SFX_CHILDWIN_TASK ) ) + pWork->pChildWins->Insert( pWork->pChildWins->Count(), pCW ); + else + pChildWins->Insert( pChildWins->Count(), pCW ); + } + + SfxChildAlignment eAlign; + if ( pCW->aInfo.GetExtraData_Impl( &eAlign ) ) + return( eAlign == SFX_ALIGN_NOALIGNMENT ); + else + return TRUE; +} + +//-------------------------------------------------------------------- + +BOOL SfxWorkWindow::KnowsChildWindow_Impl(USHORT nId) +{ + SfxChildWin_Impl *pCW=0; + USHORT nCount = pChildWins->Count(); + USHORT n; + for (n=0; n<nCount; n++) + { + pCW = (*pChildWins)[n]; + if ( pCW->nSaveId == nId) + break; + } + + if (n<nCount) + { + if ( !(pCW->aInfo.nFlags & SFX_CHILDWIN_ALWAYSAVAILABLE) && !IsVisible_Impl( pCW->nVisibility ) ) + return FALSE; + return pCW->bEnable; + } + else if ( pParent ) + return pParent->KnowsChildWindow_Impl( nId ); + else + return FALSE; +} + +//-------------------------------------------------------------------- + +void SfxWorkWindow::SetChildWindow_Impl(USHORT nId, BOOL bOn, BOOL bSetFocus) +{ + SfxChildWin_Impl *pCW=NULL; + SfxWorkWindow *pWork = pParent; + + // Den obersten parent nehmen; ChildWindows werden immer am WorkWindow + // der Task bzw. des Frames oder am AppWorkWindow angemeldet + while ( pWork && pWork->pParent ) + pWork = pWork->pParent; + + if ( pWork ) + { + // Dem Parent schon bekannt ? + USHORT nCount = pWork->pChildWins->Count(); + for (USHORT n=0; n<nCount; n++) + if ((*pWork->pChildWins)[n]->nSaveId == nId) + { + pCW = (*pWork->pChildWins)[n]; + break; + } + } + + if ( !pCW ) + { + // Kein Parent oder dem Parent noch unbekannt, dann bei mir suchen + USHORT nCount = pChildWins->Count(); + for (USHORT n=0; n<nCount; n++) + if ((*pChildWins)[n]->nSaveId == nId) + { + pCW = (*pChildWins)[n]; + pWork = this; + break; + } + } + + if ( !pCW ) + { + // Ist neu, also initialisieren; je nach Flag beim Parent oder bei + // mir eintragen + pCW = new SfxChildWin_Impl( nId ); + InitializeChild_Impl( pCW ); + if ( !pWork || pCW->aInfo.nFlags & SFX_CHILDWIN_TASK ) + pWork = this; + pWork->pChildWins->Insert( pWork->pChildWins->Count(), pCW ); + } + + if ( pCW->bCreate != bOn ) + pWork->ToggleChildWindow_Impl(nId,bSetFocus); +} + +//-------------------------------------------------------------------- + +void SfxWorkWindow::ShowChildWindow_Impl(USHORT nId, BOOL bVisible, BOOL bSetFocus) +{ + USHORT nCount = pChildWins->Count(); + SfxChildWin_Impl* pCW=0; + USHORT n; + for (n=0; n<nCount; n++) + { + pCW = (*pChildWins)[n]; + if (pCW->nId == nId) + break; + } + + if ( n<nCount ) + { + SfxChildWindow *pChildWin = pCW->pWin; + if ( pChildWin ) + { + if ( bVisible ) + { + if ( pCW->pCli ) + { + pCW->pCli->bSetFocus = bSetFocus; + pCW->pCli->nVisible = CHILD_VISIBLE; + pChildWin->Show( bSetFocus && pChildWin->WantsFocus() ? 0 : SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE ); + } + else + ((SfxDockingWindow*)pChildWin->GetWindow())->Reappear_Impl(); + + } + else + { + if ( pCW->pCli ) + { + pCW->pCli->nVisible = CHILD_VISIBLE ^ CHILD_NOT_HIDDEN; + pCW->pWin->Hide(); + } + else + ((SfxDockingWindow*)pChildWin->GetWindow())->Disappear_Impl(); + + } + + ArrangeChilds_Impl(); + ShowChilds_Impl(); + } + else if ( bVisible ) + { + SetChildWindow_Impl( nId, TRUE, bSetFocus ); + pChildWin = pCW->pWin; + } + + if ( pChildWin ) + { + pChildWin->SetVisible_Impl( bVisible ); + USHORT nFlags = pCW->aInfo.nFlags; + pCW->aInfo = pChildWin->GetInfo(); + pCW->aInfo.nFlags |= nFlags; + if ( !pCW->bCreate ) + SaveStatus_Impl( pChildWin, pCW->aInfo ); + } + + return; + } + + if ( pParent ) + { + pParent->ShowChildWindow_Impl( nId, bVisible, bSetFocus ); + return; + } + +#ifdef DBG_UTIL + nCount = pChildWins->Count(); + for (n=0; n<nCount; n++) + if ((*pChildWins)[n]->nSaveId == nId) + break; + + if ( n<nCount ) + { + DBG_ERROR("ChildWindow ist nicht im Kontext!"); + } + else + { + DBG_ERROR("ChildWindow ist nicht registriert!"); + } +#endif +} + +//-------------------------------------------------------------------- + +SfxChildWindow* SfxWorkWindow::GetChildWindow_Impl(USHORT nId) +{ + USHORT nCount = pChildWins->Count(); + USHORT n; + for (n=0; n<nCount; n++) + if ((*pChildWins)[n]->nSaveId == nId) + break; + + if (n<nCount) + return (*pChildWins)[n]->pWin; + else if ( pParent ) + return pParent->GetChildWindow_Impl( nId ); + return 0; +} + +//------------------------------------------------------------------------ + +void SfxWorkWindow::ResetChildWindows_Impl() +{ +// if ( pParent ) +// pParent->ResetChildWindows_Impl(); + + for ( USHORT n = 0; n < pChildWins->Count(); ++n ) + { + (*pChildWins)[n]->nId = 0; + (*pChildWins)[n]->bEnable = FALSE; + } +} + +//------------------------------------------------------------------------ +// Virtuelle Methode, die die Gr"o\se der Fl"ache (client area) des parent +// windows liefert, in der Child-Fenster angeordnet werden k"onnen. +// in der ClientArea des parent findet. + +Rectangle SfxWorkWindow::GetTopRect_Impl() +{ + return Rectangle (Point(), pWorkWin->GetOutputSizePixel() ); +} + +//------------------------------------------------------------------------ +// Virtuelle Methode, die die Gr"o\se der Fl"ache (client area) des parent +// windows liefert, in der Child-Fenster angeordnet werden k"onnen. +// in der ClientArea des parent findet. + +Rectangle SfxFrameWorkWin_Impl::GetTopRect_Impl() +{ + return pMasterFrame->GetTopOuterRectPixel_Impl(); +} + +//------------------------------------------------------------------------ +// Virtuelle Methode, um herauszufinden, ob ein Child-Fenster noch Platz +// in der ClientArea des parent findet. + +BOOL SfxWorkWindow::RequestTopToolSpacePixel_Impl( SvBorder aBorder ) +{ + if ( !IsDockingAllowed() || + aClientArea.GetWidth() < aBorder.Left() + aBorder.Right() || + aClientArea.GetHeight() < aBorder.Top() + aBorder.Bottom() ) + return FALSE; + else + return TRUE;; +} + +void SfxWorkWindow::SaveStatus_Impl(SfxChildWindow *pChild, const SfxChildWinInfo &rInfo) +{ + // Den Status vom Presentation mode wollen wir nicht sichern + if ( IsDockingAllowed() && bInternalDockingAllowed ) + pChild->SaveStatus(rInfo); +} + +void SfxWorkWindow::InitializeChild_Impl(SfxChildWin_Impl *pCW) +{ + SfxChildWinFactory* pFact=0; + SfxApplication *pApp = SFX_APP(); + { + SfxChildWinFactArr_Impl &rFactories = pApp->GetChildWinFactories_Impl(); + for ( USHORT nFactory = 0; nFactory < rFactories.Count(); ++nFactory ) + { + pFact = rFactories[nFactory]; + if ( pFact->nId == pCW->nSaveId ) + { + pCW->aInfo = pFact->aInfo; + SfxChildWindow::InitializeChildWinFactory_Impl( + pCW->nSaveId, pCW->aInfo); + pCW->bCreate = pCW->aInfo.bVisible; + USHORT nFlags = pFact->aInfo.nFlags; + if ( nFlags & SFX_CHILDWIN_TASK ) + pCW->aInfo.nFlags |= SFX_CHILDWIN_TASK; + if ( nFlags & SFX_CHILDWIN_CANTGETFOCUS ) + pCW->aInfo.nFlags |= SFX_CHILDWIN_CANTGETFOCUS; + if ( nFlags & SFX_CHILDWIN_FORCEDOCK ) + pCW->aInfo.nFlags |= SFX_CHILDWIN_FORCEDOCK; + pFact->aInfo = pCW->aInfo; + return; + } + } + } + + SfxDispatcher *pDisp = pBindings->GetDispatcher_Impl(); + SfxModule *pMod = pDisp ? SfxModule::GetActiveModule( pDisp->GetFrame() ) :0; + if ( pMod ) + { + SfxChildWinFactArr_Impl *pFactories = pMod->GetChildWinFactories_Impl(); + if ( pFactories ) + { + SfxChildWinFactArr_Impl &rFactories = *pFactories; + for ( USHORT nFactory = 0; nFactory < rFactories.Count(); ++nFactory ) + { + pFact = rFactories[nFactory]; + if ( pFact->nId == pCW->nSaveId ) + { + pCW->aInfo = pFact->aInfo; + SfxChildWindow::InitializeChildWinFactory_Impl( + pCW->nSaveId, pCW->aInfo); + pCW->bCreate = pCW->aInfo.bVisible; + USHORT nFlags = pFact->aInfo.nFlags; + if ( nFlags & SFX_CHILDWIN_TASK ) + pCW->aInfo.nFlags |= SFX_CHILDWIN_TASK; + if ( nFlags & SFX_CHILDWIN_CANTGETFOCUS ) + pCW->aInfo.nFlags |= SFX_CHILDWIN_CANTGETFOCUS; + if ( nFlags & SFX_CHILDWIN_FORCEDOCK ) + pCW->aInfo.nFlags |= SFX_CHILDWIN_FORCEDOCK; + if ( nFlags & SFX_CHILDWIN_ALWAYSAVAILABLE ) + pCW->aInfo.nFlags |= SFX_CHILDWIN_ALWAYSAVAILABLE; + pFact->aInfo = pCW->aInfo; + return; + } + } + } + } +} +/* +SfxStatBar_Impl* SfxWorkWindow::GetStatusBar_Impl() +{ + return &aStatBar; +} */ + +SfxSplitWindow* SfxWorkWindow::GetSplitWindow_Impl( SfxChildAlignment eAlign ) +{ + switch ( eAlign ) + { + case SFX_ALIGN_TOP: + return pSplit[2]; + + case SFX_ALIGN_BOTTOM: + return pSplit[3]; + + case SFX_ALIGN_LEFT: + return pSplit[0]; + + case SFX_ALIGN_RIGHT: + return pSplit[1]; + + default: + return 0; + } +} + +void SfxWorkWindow::MakeChildsVisible_Impl( BOOL bVis ) +{ + if ( pParent ) + pParent->MakeChildsVisible_Impl( bVis ); + + bAllChildsVisible = bVis; + if ( bVis ) + { + if ( !bSorted ) + Sort_Impl(); + for ( USHORT n=0; n<aSortedList.Count(); ++n ) + { + SfxChild_Impl* pCli = (*pChilds)[aSortedList[n]]; + if ( (pCli->eAlign == SFX_ALIGN_NOALIGNMENT) || (IsDockingAllowed() && bInternalDockingAllowed) ) + pCli->nVisible |= CHILD_ACTIVE; + } + } + else + { + if ( !bSorted ) + Sort_Impl(); + for ( USHORT n=0; n<aSortedList.Count(); ++n ) + { + SfxChild_Impl* pCli = (*pChilds)[aSortedList[n]]; + pCli->nVisible &= ~CHILD_ACTIVE; + } + } +} + +BOOL SfxWorkWindow::IsAutoHideMode( const SfxSplitWindow *pSplitWin ) +{ + for ( USHORT n=0; n<SFX_SPLITWINDOWS_MAX; n++ ) + { + if ( pSplit[n] != pSplitWin && pSplit[n]->IsAutoHide( TRUE ) ) + return TRUE; + } + return FALSE; +} + + +void SfxWorkWindow::EndAutoShow_Impl( Point aPos ) +{ + if ( pParent ) + pParent->EndAutoShow_Impl( aPos ); + + for ( USHORT n=0; n<SFX_SPLITWINDOWS_MAX; n++ ) + { + SfxSplitWindow *p = pSplit[n]; + if ( p && p->IsAutoHide() ) + { + Point aLocalPos = p->ScreenToOutputPixel( aPos ); + Point aEmptyPoint = Point(); + Rectangle aRect( aEmptyPoint, p->GetSizePixel() ); + if ( !aRect.IsInside( aLocalPos ) ) + p->FadeOut(); + } + } +} + +void SfxWorkWindow::ArrangeAutoHideWindows( SfxSplitWindow *pActSplitWin ) +{ + if ( m_nLock ) + return; + + if ( pParent ) + pParent->ArrangeAutoHideWindows( pActSplitWin ); + + Rectangle aArea( aUpperClientArea ); + for ( USHORT n=0; n<SFX_SPLITWINDOWS_MAX; n++ ) + { + // Es werden entweder Dummyfenster oder Fenster im AutoShow-Modus + // ( nicht gepinned, FadeIn ) behandelt. + // Nur das "ubergebene Fenster darf unsichtbar sein, denn vielleicht + // soll daf"ur gerade die Gr"o\se berechnet werden, bevor es angezeigt + // wird. + SfxSplitWindow* pSplitWin = pSplit[n]; + BOOL bDummyWindow = !pSplitWin->IsFadeIn(); + Window *pDummy = pSplitWin->GetSplitWindow(); + Window *pWin = bDummyWindow ? pDummy : pSplitWin; + if ( (pSplitWin->IsPinned() && !bDummyWindow) || (!pWin->IsVisible() && pActSplitWin != pSplitWin) ) + continue; + + // Breite und Position des Dummy-Fensters als Ausgangspunkt + Size aSize = pDummy->GetSizePixel(); + Point aPos = pDummy->GetPosPixel(); + + switch ( n ) + { + case ( 0 ) : + { + // Linkes SplitWindow + // Breite vom Fenster selbst holen, wenn nicht das DummyWindow + if ( !bDummyWindow ) + aSize.Width() = pSplitWin->GetSizePixel().Width(); + + // Wenn links ein Window sichtbar ist, beginnt der freie + // Bereich rechts davon bzw. bei der Client area + long nLeft = aPos.X() + aSize.Width(); + if ( nLeft > aArea.Left() ) + aArea.Left() = nLeft; + break; + } + case ( 1 ) : + { + // Rechtes SplitWindow + // Position um Differenz der Breiten korrigieren + aPos.X() += aSize.Width(); + + // Breite vom Fenster selbst holen, wenn nicht das DummyWindow + if ( !bDummyWindow ) + aSize.Width() = pSplitWin->GetSizePixel().Width(); + + aPos.X() -= aSize.Width(); + + // Wenn links schon ein Fenster aufgeklappt ist, darf + // das rechte nicht dar"uber gehen + if ( aPos.X() < aArea.Left() ) + { + aPos.X() = aArea.Left(); + aSize.Width() = aArea.GetWidth(); + } + + // Wenn rechts ein Window sichtbar ist, endet der freie + // Bereich links davon bzw. bei der Client area + long nRight = aPos.X(); + if ( nRight < aArea.Right() ) + aArea.Right() = nRight; + break; + } + case ( 2 ) : + { + // Oberes SplitWindow + // H"ohe vom Fenster selbst holen, wenn nicht das DummyWindow + if ( !bDummyWindow ) + aSize.Height() = pSplitWin->GetSizePixel().Height(); + + // Breite anpassen, je nachdem ob links oder rechts + // schon ein Fenster aufgeklappt ist + aPos.X() = aArea.Left(); + aSize.Width() = aArea.GetWidth(); + + // Wenn oben ein Window sichtbar ist, beginnt der freie + // Bereich darunter bzw. bei der Client Area + long nTop = aPos.Y() + aSize.Height(); + if ( nTop > aArea.Top() ) + aArea.Top() = nTop; + break; + } + case ( 3 ) : + { + // Das untere SplitWindow + // Position um Differenz der H"ohen korrigieren + aPos.Y() += aSize.Height(); + + // H"ohe vom Fenster selbst holen, wenn nicht das DummmyWindow + if ( !bDummyWindow ) + aSize.Height() = pSplitWin->GetSizePixel().Height(); + + aPos.Y() -= aSize.Height(); + + // Breite anpassen, je nachdem ob links oder rechts + // schon ein Fenster aufgeklappt ist + aPos.X() = aArea.Left(); + aSize.Width() = aArea.GetWidth(); + + // Wenn oben schon ein Fenster aufgeklappt ist, darf + // das untere nicht dar"uber gehen + if ( aPos.Y() < aArea.Top() ) + { + aPos.Y() = aArea.Top(); + aSize.Height() = aArea.GetHeight(); + } + + break; + } + } + + if ( !bDummyWindow ) + // Das FadeIn-Window ist ein Float, dessen Koordinaten in + // Screenkoordinaten gesetzt werden + pSplitWin->SetPosSizePixel( pWorkWin->OutputToScreenPixel(aPos), aSize ); + else + // Das angedockte DummyWindow + pDummy->SetPosSizePixel( aPos, aSize ); + } +} + +Rectangle SfxWorkWindow::GetFreeArea( BOOL bAutoHide ) const +{ + if ( bAutoHide ) + { + Rectangle aArea( aClientArea ); + for ( USHORT n=0; n<SFX_SPLITWINDOWS_MAX; n++ ) + { + if ( pSplit[n]->IsPinned() || !pSplit[n]->IsVisible() ) + continue; + + Size aSize = pSplit[n]->GetSizePixel(); + switch ( n ) + { + case ( 0 ) : + aArea.Left() += aSize.Width(); + break; + case ( 1 ) : + aArea.Right() -= aSize.Width(); + break; + case ( 2 ) : + aArea.Top() += aSize.Height(); + break; + case ( 3 ) : + aArea.Bottom() -= aSize.Height(); + break; + } + } + + return aArea; + } + else + return aClientArea; +} + +SfxChildWinController_Impl::SfxChildWinController_Impl( USHORT nID, SfxWorkWindow *pWork ) + : SfxControllerItem( nID, pWork->GetBindings() ) + , pWorkwin( pWork ) +{} + +::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > SfxWorkWindow::CreateDispatch( const String& ) +{ + return ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch >(); +} + +void SfxChildWinController_Impl::StateChanged( + USHORT nSID, SfxItemState eState, const SfxPoolItem* ) +{ + pWorkwin->DisableChildWindow_Impl( nSID, eState == SFX_ITEM_DISABLED ); +} + +void SfxWorkWindow::DisableChildWindow_Impl( USHORT nId, BOOL bDisable ) +{ + USHORT nCount = pChildWins->Count(); + USHORT n; + for (n=0; n<nCount; n++) + if ((*pChildWins)[n]->nSaveId == nId) + break; + if ( n<nCount && (*pChildWins)[n]->bDisabled != bDisable ) + { + (*pChildWins)[n]->bDisabled = bDisable; + UpdateChildWindows_Impl(); + ArrangeChilds_Impl(); + ShowChilds_Impl(); + } +} + +void SfxWorkWindow::SetActiveChild_Impl( Window *pChild ) +{ + pActiveChild = pChild; +} + +Window* SfxWorkWindow::GetActiveChild_Impl() +{ + return pActiveChild; +} + +BOOL SfxWorkWindow::ActivateNextChild_Impl( BOOL bForward ) +{ + // Alle Kinder gem"a\s Liste sortieren + SvUShorts aList; + for ( USHORT i=SFX_OBJECTBAR_MAX; i<pChilds->Count(); i++) + { + SfxChild_Impl *pCli = (*pChilds)[i]; + if ( pCli && pCli->bCanGetFocus && pCli->pWin ) + { + USHORT k; + for (k=0; k<aList.Count(); k++) + if ( ChildTravelValue((*pChilds)[aList[k]]->eAlign) > ChildTravelValue(pCli->eAlign) ) + break; + aList.Insert(i,k); + } + } + + if ( aList.Count() == 0 ) + return FALSE; + + USHORT nTopValue = ChildTravelValue( SFX_ALIGN_LOWESTTOP ); + for ( USHORT i=0; i<aList.Count(); i++ ) + { + SfxChild_Impl* pCli = (*pChilds)[aList[i]]; + if ( pCli->pWin && ChildTravelValue( pCli->eAlign ) > nTopValue ) + break; + } + + USHORT n = bForward ? 0 : aList.Count()-1; + SfxChild_Impl *pAct=NULL; + if ( pActiveChild ) + { + // Das aktive Fenster suchen + for ( n=0; n<aList.Count(); n++ ) + { + SfxChild_Impl* pCli = (*pChilds)[aList[n]]; + if ( pCli && pCli->pWin && ( pCli->pWin == pActiveChild || !pActiveChild ) ) + { + pAct = pCli; + break; + } + } + } + + // dummy entries for the container window + aList.Insert( 0xFFFF, 0 ); + aList.Insert( 0xFFFF, aList.Count() ); + n = n + 1; + if ( pAct ) + { + for ( USHORT i=0; i<SFX_SPLITWINDOWS_MAX; i++ ) + { + // Eventuell ist pAct ein Splitwindow + SfxSplitWindow *p = pSplit[i]; + if ( pAct->pWin == p ) + { + if( p->ActivateNextChild_Impl( bForward ) ) + return TRUE; + break; + } + } + + // pAct ist ein direktes ChildWindow + // mit dem Nachfolger bzw. Vorg"anger des aktiven Fensters weitermachen + if ( bForward ) + n = n+1; + else + n = n-1; + + if ( n == 0 || n == aList.Count()-1 ) + return FALSE; + } + + for( ;; ) + { + SfxChild_Impl* pCli = (*pChilds)[aList[n]]; + if ( pCli->pWin ) + { + SfxChild_Impl* pNext = pCli; + for ( USHORT i=0; n<SFX_SPLITWINDOWS_MAX; n++ ) + { + // Eventuell ist pNext ein Splitwindow + SfxSplitWindow *p = pSplit[i]; + if ( pNext->pWin == p ) + { + // Das erste/letzte Fenster dort aktivieren + p->SetActiveWindow_Impl( NULL ); + pNext = NULL; + if( p->ActivateNextChild_Impl( bForward ) ) + return TRUE; + break; + } + } + + if ( pNext ) + { + pNext->pWin->GrabFocus(); + pActiveChild = pNext->pWin; + return TRUE; + } + } + + if ( bForward ) + n = n+1; + else + n = n-1; + + if ( n == 0 || n == aList.Count()-1 ) + break; + } + + return FALSE; +} + +void SfxWorkWindow::SetObjectBarCustomizeMode_Impl( BOOL ) +{ +} + +void SfxWorkWindow::DataChanged_Impl( const DataChangedEvent& ) +{ + USHORT n; + USHORT nCount = pChildWins->Count(); + for (n=0; n<nCount; n++) + { + SfxChildWin_Impl*pCW = (*pChildWins)[n]; + if ( pCW && pCW->pWin ) + pCW->pWin->GetWindow()->UpdateSettings( Application::GetSettings() ); + } + + ArrangeChilds_Impl(); +} + diff --git a/sfx2/source/appl/xpackcreator.cxx b/sfx2/source/appl/xpackcreator.cxx new file mode 100644 index 000000000000..6e6606a67041 --- /dev/null +++ b/sfx2/source/appl/xpackcreator.cxx @@ -0,0 +1,202 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" +#include <com/sun/star/ucb/XCommandEnvironment.hpp> +#include <com/sun/star/io/XOutputStream.hpp> + + +#include "xpackcreator.hxx" + +#include <sot/stg.hxx> +#include <sot/storage.hxx> +#include <tools/stream.hxx> +#include <unotools/tempfile.hxx> +#include <unotools/ucbhelper.hxx> +#include <ucbhelper/content.hxx> +#include <ucbhelper/commandenvironment.hxx> + +using namespace ::com::sun::star; + +//------------------------------------------------------------------------- +uno::Sequence< ::rtl::OUString > SAL_CALL OPackageStructureCreator::impl_getStaticSupportedServiceNames() +{ + uno::Sequence< ::rtl::OUString > aRet(2); + aRet[0] = ::rtl::OUString::createFromAscii("com.sun.star.embed.PackageStructureCreator"); + aRet[1] = ::rtl::OUString::createFromAscii("com.sun.star.comp.embed.PackageStructureCreator"); + return aRet; +} + +//------------------------------------------------------------------------- +::rtl::OUString SAL_CALL OPackageStructureCreator::impl_getStaticImplementationName() +{ + return ::rtl::OUString::createFromAscii("com.sun.star.comp.embed.PackageStructureCreator"); +} + +//------------------------------------------------------------------------- +uno::Reference< lang::XSingleServiceFactory > SAL_CALL OPackageStructureCreator::impl_createFactory( + const uno::Reference< lang::XMultiServiceFactory >& xServiceManager ) +{ + return ::cppu::createOneInstanceFactory( xServiceManager, + OPackageStructureCreator::impl_getStaticImplementationName(), + OPackageStructureCreator::impl_staticCreateSelfInstance, + OPackageStructureCreator::impl_getStaticSupportedServiceNames() ); +} + +//------------------------------------------------------------------------- +uno::Reference< uno::XInterface > SAL_CALL OPackageStructureCreator::impl_staticCreateSelfInstance( + const uno::Reference< lang::XMultiServiceFactory >& xServiceManager ) +{ + return uno::Reference< uno::XInterface >( *new OPackageStructureCreator( xServiceManager ) ); +} + + +//------------------------------------------------------------------------- +void SAL_CALL OPackageStructureCreator::convertToPackage( const ::rtl::OUString& aFolderUrl, + const uno::Reference< io::XOutputStream >& xTargetStream ) + throw ( io::IOException, + uno::RuntimeException ) +{ + uno::Reference< ucb::XCommandEnvironment > xComEnv; + + if ( !xTargetStream.is() ) + throw io::IOException(); // TODO/LATER + + sal_Bool bSuccess = sal_False; + ::ucbhelper::Content aContent; + if( ::ucbhelper::Content::create( aFolderUrl, xComEnv, aContent ) ) + { + SvStream* pTempStream = NULL; + + ::rtl::OUString aTempURL = ::utl::TempFile().GetURL(); + try { + if ( aContent.isFolder() ) + { + UCBStorage* pUCBStorage = new UCBStorage( aContent, + aFolderUrl, + STREAM_READ, + sal_False, + sal_True ); + SotStorageRef aStorage = new SotStorage( pUCBStorage ); + + if ( aTempURL.getLength() ) + { + pTempStream = new SvFileStream( aTempURL, STREAM_STD_READWRITE ); + SotStorageRef aTargetStorage = new SotStorage( sal_True, *pTempStream ); + aStorage->CopyTo( aTargetStorage ); + aTargetStorage->Commit(); + + if ( aStorage->GetError() || aTargetStorage->GetError() || pTempStream->GetError() ) + throw io::IOException(); + + aTargetStorage = NULL; + aStorage = NULL; + + pTempStream->Seek( 0 ); + + uno::Sequence< sal_Int8 > aSeq( 32000 ); + sal_uInt32 nRead = 0; + do { + if ( aSeq.getLength() < 32000 ) + aSeq.realloc( 32000 ); + + nRead = pTempStream->Read( aSeq.getArray(), 32000 ); + if ( nRead < 32000 ) + aSeq.realloc( nRead ); + xTargetStream->writeBytes( aSeq ); + } while( !pTempStream->IsEof() && !pTempStream->GetError() && nRead ); + + if ( pTempStream->GetError() ) + throw io::IOException(); + + bSuccess = sal_True; + } + } + } + catch ( uno::RuntimeException& ) + { + if ( pTempStream ) + delete pTempStream; + + if ( aTempURL.getLength() ) + ::utl::UCBContentHelper::Kill( aTempURL ); + + throw; + } + catch ( io::IOException& ) + { + if ( pTempStream ) + delete pTempStream; + + if ( aTempURL.getLength() ) + ::utl::UCBContentHelper::Kill( aTempURL ); + + throw; + } + catch ( uno::Exception& ) + { + } + + if ( pTempStream ) + delete pTempStream; + + if ( aTempURL.getLength() ) + ::utl::UCBContentHelper::Kill( aTempURL ); + } + + if ( !bSuccess ) + throw io::IOException(); // TODO/LATER: can't proceed with creation +} + +//------------------------------------------------------------------------- +::rtl::OUString SAL_CALL OPackageStructureCreator::getImplementationName() + throw ( uno::RuntimeException ) +{ + return impl_getStaticImplementationName(); +} + +//------------------------------------------------------------------------- +sal_Bool SAL_CALL OPackageStructureCreator::supportsService( const ::rtl::OUString& ServiceName ) + throw ( uno::RuntimeException ) +{ + uno::Sequence< ::rtl::OUString > aSeq = impl_getStaticSupportedServiceNames(); + + for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ ) + if ( ServiceName.compareTo( aSeq[nInd] ) == 0 ) + return sal_True; + + return sal_False; +} + +//------------------------------------------------------------------------- +uno::Sequence< ::rtl::OUString > SAL_CALL OPackageStructureCreator::getSupportedServiceNames() + throw ( uno::RuntimeException ) +{ + return impl_getStaticSupportedServiceNames(); +} + diff --git a/sfx2/source/appl/xpackcreator.hxx b/sfx2/source/appl/xpackcreator.hxx new file mode 100644 index 000000000000..ff3b84dbec64 --- /dev/null +++ b/sfx2/source/appl/xpackcreator.hxx @@ -0,0 +1,75 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef __XFACTORY_HXX_ +#define __XFACTORY_HXX_ + +#include <com/sun/star/embed/XPackageStructureCreator.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> + + +#include <cppuhelper/implbase2.hxx> + + +class OPackageStructureCreator : public ::cppu::WeakImplHelper2< ::com::sun::star::embed::XPackageStructureCreator, + ::com::sun::star::lang::XServiceInfo > +{ + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xFactory; + +public: + OPackageStructureCreator( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory ) + : m_xFactory( xFactory ) + { + OSL_ENSURE( xFactory.is(), "No service manager is provided!\n" ); + } + + static ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL impl_getStaticSupportedServiceNames(); + + static ::rtl::OUString SAL_CALL impl_getStaticImplementationName(); + + static ::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleServiceFactory > SAL_CALL + impl_createFactory( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ); + + static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL + impl_staticCreateSelfInstance( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ); + + // XPackageStructureCreator + virtual void SAL_CALL convertToPackage( const ::rtl::OUString& aFolderUrl, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xTargetStream ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw (::com::sun::star::uno::RuntimeException); + +}; + +#endif + |