diff options
-rw-r--r-- | unotools/inc/unotools/idhelper.hxx | 13 | ||||
-rw-r--r-- | vcl/aqua/inc/salinst.h | 1 | ||||
-rw-r--r-- | vcl/aqua/source/app/salinst.cxx | 86 | ||||
-rw-r--r-- | vcl/inc/vcl/salinst.hxx | 1 | ||||
-rw-r--r-- | vcl/inc/vcl/svapp.hxx | 14 | ||||
-rw-r--r-- | vcl/os2/inc/salinst.h | 1 | ||||
-rw-r--r-- | vcl/os2/source/app/salinst.cxx | 4 | ||||
-rw-r--r-- | vcl/source/app/svapp.cxx | 6 | ||||
-rw-r--r-- | vcl/unx/gtk/app/gtkinst.cxx | 28 | ||||
-rw-r--r-- | vcl/unx/headless/svpinst.cxx | 4 | ||||
-rw-r--r-- | vcl/unx/headless/svpinst.hxx | 2 | ||||
-rw-r--r-- | vcl/unx/inc/plugins/gtk/gtkinst.hxx | 1 | ||||
-rw-r--r-- | vcl/unx/inc/salinst.h | 2 | ||||
-rw-r--r-- | vcl/unx/source/app/salinst.cxx | 19 | ||||
-rw-r--r-- | vcl/win/inc/salinst.h | 1 | ||||
-rw-r--r-- | vcl/win/source/app/salinst.cxx | 34 |
16 files changed, 198 insertions, 19 deletions
diff --git a/unotools/inc/unotools/idhelper.hxx b/unotools/inc/unotools/idhelper.hxx index 2fcac8550af5..a2aa28d26c1b 100644 --- a/unotools/inc/unotools/idhelper.hxx +++ b/unotools/inc/unotools/idhelper.hxx @@ -125,9 +125,6 @@ public: \ static void release(); \ \ static ::com::sun::star::uno::Sequence< sal_Int8 > getImplementationId( \ - const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XTypeProvider >& _rxProvider); \ - \ - static ::com::sun::star::uno::Sequence< sal_Int8 > getImplementationId( \ const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type >& _rTypes); \ \ private: \ @@ -182,16 +179,6 @@ void classname::release() \ \ /*-----------------------------------------------------------------------*/ \ ::com::sun::star::uno::Sequence< sal_Int8 > classname::getImplementationId( \ - const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XTypeProvider >& _rxProvider) \ -{ \ - ::osl::MutexGuard aGuard(s_aMutex); \ - if (_rxProvider.is()) \ - return getImplementationId(_rxProvider->getTypes()); \ - return ::com::sun::star::uno::Sequence< sal_Int8 >(); \ -} \ - \ -/*-----------------------------------------------------------------------*/ \ -::com::sun::star::uno::Sequence< sal_Int8 > classname::getImplementationId( \ const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type >& _rTypes) \ { \ ::osl::MutexGuard aGuard(s_aMutex); \ diff --git a/vcl/aqua/inc/salinst.h b/vcl/aqua/inc/salinst.h index 82ac5b6f4ffd..5b1cf0d84562 100644 --- a/vcl/aqua/inc/salinst.h +++ b/vcl/aqua/inc/salinst.h @@ -143,6 +143,7 @@ public: virtual void DestroyMenuItem( SalMenuItem* ); virtual SalSession* CreateSalSession(); virtual void* GetConnectionIdentifier( ConnectionIdentifierType& rReturnedType, int& rReturnedBytes ); + virtual void AddToRecentDocumentList(const rtl::OUString& rFileUrl, const rtl::OUString& rMimeType); virtual void SetEventCallback( void* pInstance, bool(*pCallback)(void*,void*,int) ); virtual void SetErrorEventCallback( void* pInstance, bool(*pCallback)(void*,void*,int) ); diff --git a/vcl/aqua/source/app/salinst.cxx b/vcl/aqua/source/app/salinst.cxx index 56bf1a612b40..e4037df0c4aa 100644 --- a/vcl/aqua/source/app/salinst.cxx +++ b/vcl/aqua/source/app/salinst.cxx @@ -55,6 +55,14 @@ #include "saltimer.h" #include "vclnsapp.h" +#include <comphelper/processfactory.hxx> + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/uri/XExternalUriReferenceTranslator.hpp> +#include <com/sun/star/uri/ExternalUriReferenceTranslator.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> + #include "premac.h" #include <Foundation/Foundation.h> #include <ApplicationServices/ApplicationServices.h> @@ -64,6 +72,7 @@ using namespace std; +using namespace ::com::sun::star; extern BOOL ImplSVMain(); @@ -1029,6 +1038,83 @@ void* AquaSalInstance::GetConnectionIdentifier( ConnectionIdentifierType& rRetur return (void*)""; } +// We need to re-encode file urls because osl_getFileURLFromSystemPath converts +// to UTF-8 before encoding non ascii characters, which is not what other apps expect. +static rtl::OUString translateToExternalUrl(const rtl::OUString& internalUrl) +{ + rtl::OUString extUrl; + + uno::Reference< lang::XMultiServiceFactory > sm = comphelper::getProcessServiceFactory(); + if (sm.is()) + { + uno::Reference< beans::XPropertySet > pset; + sm->queryInterface( getCppuType( &pset )) >>= pset; + if (pset.is()) + { + uno::Reference< uno::XComponentContext > context; + static const rtl::OUString DEFAULT_CONTEXT( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ); + pset->getPropertyValue(DEFAULT_CONTEXT) >>= context; + if (context.is()) + extUrl = uri::ExternalUriReferenceTranslator::create(context)->translateToExternal(internalUrl); + } + } + return extUrl; +} + +// #i104525# many versions of OSX have problems with some URLs: +// when an app requests OSX to add one of these URLs to the "Recent Items" list +// then this app gets killed (TextEdit, Preview, etc. and also OOo) +static bool isDangerousUrl( const rtl::OUString& rUrl ) +{ + // use a heuristic that detects all known cases since there is no official comment + // on the exact impact and root cause of the OSX bug + const int nLen = rUrl.getLength(); + const sal_Unicode* p = rUrl.getStr(); + for( int i = 0; i < nLen-3; ++i, ++p ) { + if( p[0] != '%' ) + continue; + // escaped percent? + if( (p[1] == '2') && (p[2] == '5') ) + return true; + // escapes are considered to be UTF-8 encoded + // => check for invalid UTF-8 leading byte + if( (p[1] != 'f') && (p[1] != 'F') ) + continue; + int cLowNibble = p[2]; + if( (cLowNibble >= '0' ) && (cLowNibble <= '9')) + return false; + if( cLowNibble >= 'a' ) + cLowNibble -= 'a' - 'A'; + if( (cLowNibble < 'A') || (cLowNibble >= 'C')) + return true; + } + + return false; +} + +void AquaSalInstance::AddToRecentDocumentList(const rtl::OUString& rFileUrl, const rtl::OUString& /*rMimeType*/) +{ + // Convert file URL for external use (see above) + rtl::OUString externalUrl = translateToExternalUrl(rFileUrl); + if( 0 == externalUrl.getLength() ) + externalUrl = rFileUrl; + + if( externalUrl.getLength() && !isDangerousUrl( externalUrl ) ) + { + NSString* pString = CreateNSString( externalUrl ); + NSURL* pURL = [NSURL URLWithString: pString]; + + if( pURL ) + { + NSDocumentController* pCtrl = [NSDocumentController sharedDocumentController]; + [pCtrl noteNewRecentDocumentURL: pURL]; + } + if( pString ) + [pString release]; + } +} + + // ----------------------------------------------------------------------- SalTimer* AquaSalInstance::CreateSalTimer() diff --git a/vcl/inc/vcl/salinst.hxx b/vcl/inc/vcl/salinst.hxx index 650e57cdccc4..f8c148859516 100644 --- a/vcl/inc/vcl/salinst.hxx +++ b/vcl/inc/vcl/salinst.hxx @@ -184,6 +184,7 @@ public: CreateClipboard( const com::sun::star::uno::Sequence< com::sun::star::uno::Any >& i_rArguments ); virtual com::sun::star::uno::Reference< com::sun::star::uno::XInterface > CreateDragSource(); virtual com::sun::star::uno::Reference< com::sun::star::uno::XInterface > CreateDropTarget(); + virtual void AddToRecentDocumentList(const rtl::OUString& rFileUrl, const rtl::OUString& rMimeType) = 0; }; // called from SVMain diff --git a/vcl/inc/vcl/svapp.hxx b/vcl/inc/vcl/svapp.hxx index f853fae6c268..1e0c5218d1c5 100644 --- a/vcl/inc/vcl/svapp.hxx +++ b/vcl/inc/vcl/svapp.hxx @@ -479,6 +479,20 @@ public: */ static const ::rtl::OUString& GetDesktopEnvironment(); + /** Add a file to the system shells recent document list if there is any. + This function may have no effect under Unix because there is no + standard API among the different desktop managers. + + @param rFileUrl + The file url of the document. + + @param rMimeType + The mime content type of the document specified by aFileUrl. + If an empty string will be provided "application/octet-stream" + will be used. + */ + static void AddToRecentDocumentList(const rtl::OUString& rFileUrl, const rtl::OUString& rMimeType); + private: DECL_STATIC_LINK( Application, PostEventHandler, void* ); diff --git a/vcl/os2/inc/salinst.h b/vcl/os2/inc/salinst.h index 119324c1acd6..ba8dc7ddc43f 100644 --- a/vcl/os2/inc/salinst.h +++ b/vcl/os2/inc/salinst.h @@ -96,6 +96,7 @@ public: virtual void DestroyMenuItem( SalMenuItem* ); virtual SalSession* CreateSalSession(); virtual void* GetConnectionIdentifier( ConnectionIdentifierType& rReturnedType, int& rReturnedBytes ); + virtual void AddToRecentDocumentList(const rtl::OUString& rFileUrl, const rtl::OUString& rMimeType); }; SalFrame* ImplSalCreateFrame( Os2SalInstance* pInst, HWND hWndParent, ULONG nSalFrameStyle ); diff --git a/vcl/os2/source/app/salinst.cxx b/vcl/os2/source/app/salinst.cxx index a14881c253ee..d4d324ad469c 100644 --- a/vcl/os2/source/app/salinst.cxx +++ b/vcl/os2/source/app/salinst.cxx @@ -811,6 +811,10 @@ void* Os2SalInstance::GetConnectionIdentifier( ConnectionIdentifierType& rReturn return (void*) ""; } +void Os2SalInstance::AddToRecentDocumentList(const rtl::OUString& /*rFileUrl*/, const rtl::OUString& /*rMimeType*/) +{ +} + // ----------------------------------------------------------------------- SalTimer* Os2SalInstance::CreateSalTimer() diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx index b53ceceeb757..6057409baa14 100644 --- a/vcl/source/app/svapp.cxx +++ b/vcl/source/app/svapp.cxx @@ -1989,6 +1989,12 @@ const ::rtl::OUString& Application::GetDesktopEnvironment() return SalGetDesktopEnvironment(); } +void Application::AddToRecentDocumentList(const rtl::OUString& rFileUrl, const rtl::OUString& rMimeType) +{ + ImplSVData* pSVData = ImplGetSVData(); + pSVData->mpDefInst->AddToRecentDocumentList(rFileUrl, rMimeType); +} + BOOL Application::IsAccessibilityEnabled() { return FALSE; diff --git a/vcl/unx/gtk/app/gtkinst.cxx b/vcl/unx/gtk/app/gtkinst.cxx index 8bed40fa539f..af3a1df97a8c 100644 --- a/vcl/unx/gtk/app/gtkinst.cxx +++ b/vcl/unx/gtk/app/gtkinst.cxx @@ -216,6 +216,34 @@ SalObject* GtkInstance::CreateObject( SalFrame* pParent, SystemWindowData* pWind return new GtkSalObject( static_cast<GtkSalFrame*>(pParent), bShow ); } +extern "C" +{ + typedef void*(* getDefaultFnc)(); + typedef void(* addItemFnc)(void *, const char *); +} + +void GtkInstance::AddToRecentDocumentList(const rtl::OUString& rFileUrl, const rtl::OUString& rMimeType) +{ +#if GTK_CHECK_VERSION(2,10,0) + GtkRecentManager *manager = gtk_recent_manager_get_default (); + gtk_recent_manager_add_item (manager, rtl::OUStringToOString(rFileUrl, RTL_TEXTENCODING_UTF8).getStr()); + (void)rMimeType; +#else + static getDefaultFnc sym_gtk_recent_manager_get_default = + (getDefaultFnc)osl_getAsciiFunctionSymbol( GetSalData()->m_pPlugin, "gtk_recent_manager_get_default" ); + + static addItemFnc sym_gtk_recent_manager_add_item = + (addItemFnc)osl_getAsciiFunctionSymbol( GetSalData()->m_pPlugin, "gtk_recent_manager_add_item"); + if (sym_gtk_recent_manager_get_default && sym_gtk_recent_manager_add_item) + { + sym_gtk_recent_manager_add_item(sym_gtk_recent_manager_get_default(), + rtl::OUStringToOString(rFileUrl, RTL_TEXTENCODING_UTF8).getStr()); + } + else + X11SalInstance::AddToRecentDocumentList(rFileUrl, rMimeType); +#endif +} + GtkYieldMutex::GtkYieldMutex() { } diff --git a/vcl/unx/headless/svpinst.cxx b/vcl/unx/headless/svpinst.cxx index 87d0e4662f29..7b93e59b6acd 100644 --- a/vcl/unx/headless/svpinst.cxx +++ b/vcl/unx/headless/svpinst.cxx @@ -504,6 +504,10 @@ void SvpSalInstance::StartTimer( ULONG nMS ) } } +void SvpSalInstance::AddToRecentDocumentList(const rtl::OUString&, const rtl::OUString&) +{ +} + SvpSalTimer::~SvpSalTimer() { } diff --git a/vcl/unx/headless/svpinst.hxx b/vcl/unx/headless/svpinst.hxx index 71c463f071a9..e77debb53f1d 100644 --- a/vcl/unx/headless/svpinst.hxx +++ b/vcl/unx/headless/svpinst.hxx @@ -193,6 +193,8 @@ public: virtual SalSession* CreateSalSession(); virtual void* GetConnectionIdentifier( ConnectionIdentifierType& rReturnedType, int& rReturnedBytes ); + + virtual void AddToRecentDocumentList(const rtl::OUString& rFileUrl, const rtl::OUString& rMimeType); }; #endif // _SV_SALINST_HXX diff --git a/vcl/unx/inc/plugins/gtk/gtkinst.hxx b/vcl/unx/inc/plugins/gtk/gtkinst.hxx index 22c50f627e0c..16dce4688ede 100644 --- a/vcl/unx/inc/plugins/gtk/gtkinst.hxx +++ b/vcl/unx/inc/plugins/gtk/gtkinst.hxx @@ -91,6 +91,7 @@ public: virtual SalFrame* CreateChildFrame( SystemParentData* pParent, ULONG nStyle ); virtual SalObject* CreateObject( SalFrame* pParent, SystemWindowData* pWindowData, BOOL bShow = TRUE ); virtual SalSystem* CreateSalSystem(); + virtual void AddToRecentDocumentList(const rtl::OUString& rFileUrl, const rtl::OUString& rMimeType); }; class GtkSalSystem : public X11SalSystem diff --git a/vcl/unx/inc/salinst.h b/vcl/unx/inc/salinst.h index bef5cfd5e9b4..399326c44f27 100644 --- a/vcl/unx/inc/salinst.h +++ b/vcl/unx/inc/salinst.h @@ -121,6 +121,8 @@ public: CreateClipboard( const com::sun::star::uno::Sequence< com::sun::star::uno::Any >& i_rArguments ); virtual com::sun::star::uno::Reference< com::sun::star::uno::XInterface > CreateDragSource(); virtual com::sun::star::uno::Reference< com::sun::star::uno::XInterface > CreateDropTarget(); + virtual void AddToRecentDocumentList(const rtl::OUString& rFileUrl, const rtl::OUString& rMimeType); + bool isPrinterInit() const { diff --git a/vcl/unx/source/app/salinst.cxx b/vcl/unx/source/app/salinst.cxx index d84b7fa5df6d..1dc2d1404009 100644 --- a/vcl/unx/source/app/salinst.cxx +++ b/vcl/unx/source/app/salinst.cxx @@ -35,6 +35,8 @@ #include <stdio.h> #include <stdlib.h> +#include <osl/module.hxx> + #include "salunx.h" #include "saldata.hxx" @@ -413,3 +415,20 @@ void X11SalInstance::FillFontPathList( std::list< rtl::OString >& o_rFontPaths ) #endif /* SOLARIS */ } +extern "C" { static void SAL_CALL thisModule() {} } + +void X11SalInstance::AddToRecentDocumentList(const rtl::OUString& rFileUrl, const rtl::OUString& rMimeType) +{ + const rtl::OUString SYM_ADD_TO_RECENTLY_USED_FILE_LIST(RTL_CONSTASCII_USTRINGPARAM("add_to_recently_used_file_list")); + const rtl::OUString LIB_RECENT_FILE(RTL_CONSTASCII_USTRINGPARAM("librecentfile.so")); + typedef void (*PFUNC_ADD_TO_RECENTLY_USED_LIST)(const rtl::OUString&, const rtl::OUString&); + + PFUNC_ADD_TO_RECENTLY_USED_LIST add_to_recently_used_file_list = 0; + + osl::Module module; + module.loadRelative( &thisModule, LIB_RECENT_FILE ); + if (module.is()) + add_to_recently_used_file_list = (PFUNC_ADD_TO_RECENTLY_USED_LIST)module.getFunctionSymbol(SYM_ADD_TO_RECENTLY_USED_FILE_LIST); + if (add_to_recently_used_file_list) + add_to_recently_used_file_list(rFileUrl, rMimeType); +} diff --git a/vcl/win/inc/salinst.h b/vcl/win/inc/salinst.h index 26afe892b9a3..33a1a941ed49 100644 --- a/vcl/win/inc/salinst.h +++ b/vcl/win/inc/salinst.h @@ -88,6 +88,7 @@ public: virtual void DestroyMenuItem( SalMenuItem* ); virtual SalSession* CreateSalSession(); virtual void* GetConnectionIdentifier( ConnectionIdentifierType& rReturnedType, int& rReturnedBytes ); + virtual void AddToRecentDocumentList(const rtl::OUString& rFileUrl, const rtl::OUString& rMimeType); static int WorkaroundExceptionHandlingInUSER32Lib(int nExcept, LPEXCEPTION_POINTERS pExceptionInfo); }; diff --git a/vcl/win/source/app/salinst.cxx b/vcl/win/source/app/salinst.cxx index d57cdd48eed2..2b5ac6d3162d 100644 --- a/vcl/win/source/app/salinst.cxx +++ b/vcl/win/source/app/salinst.cxx @@ -39,7 +39,7 @@ #ifdef __MINGW32__ #include <excpt.h> #endif - +#include <osl/file.hxx> #include <vos/mutex.hxx> #include <tools/debug.hxx> #include <wincomp.hxx> @@ -65,11 +65,13 @@ #if defined _MSC_VER #pragma warning(push, 1) +#pragma warning( disable: 4917 ) #endif #include <GdiPlus.h> #include <GdiPlusEnums.h> #include <GdiPlusColor.h> +#include <Shlobj.h> #if defined _MSC_VER #pragma warning(pop) @@ -456,10 +458,10 @@ void InitSalData() { SalData* pSalData = new SalData; CoInitialize(0); -
- // init GDIPlus
- static Gdiplus::GdiplusStartupInput gdiplusStartupInput;
- Gdiplus::GdiplusStartup(&pSalData->gdiplusToken, &gdiplusStartupInput, NULL);
+ + // init GDIPlus + static Gdiplus::GdiplusStartupInput gdiplusStartupInput; + Gdiplus::GdiplusStartup(&pSalData->gdiplusToken, &gdiplusStartupInput, NULL); } @@ -471,7 +473,7 @@ void DeInitSalData() // deinit GDIPlus if(pSalData) { - Gdiplus::GdiplusShutdown(pSalData->gdiplusToken);
+ Gdiplus::GdiplusShutdown(pSalData->gdiplusToken); } delete pSalData; @@ -1089,6 +1091,26 @@ void* WinSalInstance::GetConnectionIdentifier( ConnectionIdentifierType& rReturn // ----------------------------------------------------------------------- +/** Add a file to the system shells recent document list if there is any. + This function may have no effect under Unix because there is no + standard API among the different desktop managers. + + @param aFileUrl + The file url of the document. +*/ +void WinSalInstance::AddToRecentDocumentList(const rtl::OUString& rFileUrl, const rtl::OUString& /*rMimeType*/) +{ + rtl::OUString system_path; + osl::FileBase::RC rc = osl::FileBase::getSystemPathFromFileURL(rFileUrl, system_path); + + OSL_ENSURE(osl::FileBase::E_None == rc, "Invalid file url"); + + if (osl::FileBase::E_None == rc) + SHAddToRecentDocs(SHARD_PATHW, system_path.getStr()); +} + +// ----------------------------------------------------------------------- + SalTimer* WinSalInstance::CreateSalTimer() { return new WinSalTimer(); |