1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_fpicker.hxx" 30 31 //------------------------------------------------------------------------ 32 // includes 33 //------------------------------------------------------------------------ 34 #include <com/sun/star/lang/DisposedException.hpp> 35 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 36 #include <com/sun/star/uri/XExternalUriReferenceTranslator.hpp> 37 #include <com/sun/star/lang/SystemDependent.hpp> 38 #include <com/sun/star/awt/XSystemDependentWindowPeer.hpp> 39 #include <com/sun/star/awt/SystemDependentXWindow.hpp> 40 #include <com/sun/star/beans/NamedValue.hpp> 41 #include <com/sun/star/container/XNameAccess.hpp> 42 #include <comphelper/processfactory.hxx> 43 #include <cppuhelper/interfacecontainer.h> 44 #include <rtl/process.h> 45 #include <osl/diagnose.h> 46 #include <com/sun/star/uno/Any.hxx> 47 #include <FPServiceInfo.hxx> 48 #include <vos/mutex.hxx> 49 #include <vcl/svapp.hxx> 50 #include "SalGtkPicker.hxx" 51 #include <tools/urlobj.hxx> 52 #include <stdio.h> 53 54 //------------------------------------------------------------------------ 55 // namespace directives 56 //------------------------------------------------------------------------ 57 58 using namespace ::rtl; 59 using namespace ::com::sun::star; 60 using namespace ::com::sun::star::lang; 61 using namespace ::com::sun::star::uno; 62 63 rtl::OUString SalGtkPicker::uritounicode(const gchar* pIn) 64 { 65 if (!pIn) 66 return rtl::OUString(); 67 68 rtl::OUString sURL( const_cast<const sal_Char *>(pIn), strlen(pIn), 69 RTL_TEXTENCODING_UTF8 ); 70 71 INetURLObject aURL(sURL); 72 if (INET_PROT_FILE == aURL.GetProtocol()) 73 { 74 // all the URLs are handled by office in UTF-8 75 // so the Gnome FP related URLs should be converted accordingly 76 gchar *pEncodedFileName = g_filename_from_uri(pIn, NULL, NULL); 77 if ( pEncodedFileName ) 78 { 79 rtl::OUString sEncoded(pEncodedFileName, strlen(pEncodedFileName), 80 osl_getThreadTextEncoding()); 81 INetURLObject aCurrentURL(sEncoded, INetURLObject::FSYS_UNX); 82 aCurrentURL.SetHost(aURL.GetHost()); 83 sURL = aCurrentURL.getExternalURL(); 84 } 85 else 86 { 87 OUString aNewURL = Reference<uri::XExternalUriReferenceTranslator>(Reference<XMultiServiceFactory>(comphelper::getProcessServiceFactory(), UNO_QUERY_THROW)->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uri.ExternalUriReferenceTranslator"))), UNO_QUERY_THROW)->translateToInternal(sURL); 88 if( aNewURL.getLength() ) 89 sURL = aNewURL; 90 } 91 } 92 return sURL; 93 } 94 95 rtl::OString SalGtkPicker::unicodetouri(const rtl::OUString &rURL) 96 { 97 // all the URLs are handled by office in UTF-8 ( and encoded with "%xx" codes based on UTF-8 ) 98 // so the Gnome FP related URLs should be converted accordingly 99 OString sURL = OUStringToOString(rURL, RTL_TEXTENCODING_UTF8); 100 INetURLObject aURL(rURL); 101 if (INET_PROT_FILE == aURL.GetProtocol()) 102 { 103 OUString aNewURL = Reference<uri::XExternalUriReferenceTranslator>(Reference<XMultiServiceFactory>(comphelper::getProcessServiceFactory(), UNO_QUERY_THROW)->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uri.ExternalUriReferenceTranslator"))), UNO_QUERY_THROW)->translateToExternal( rURL ); 104 105 if( aNewURL.getLength() ) 106 { 107 // At this point the URL should contain ascii characters only actually 108 sURL = OUStringToOString( aNewURL, osl_getThreadTextEncoding() ); 109 } 110 } 111 return sURL; 112 } 113 114 gboolean canceldialog(RunDialog *pDialog) 115 { 116 pDialog->cancel(); 117 return false; 118 } 119 120 extern "C" 121 { 122 struct Display; 123 extern GdkDisplay* gdk_x11_lookup_xdisplay (void*xdisplay); 124 } 125 126 RunDialog::RunDialog( GtkWidget *pDialog, uno::Reference< awt::XExtendedToolkit >& rToolkit ) : 127 cppu::WeakComponentImplHelper1< awt::XTopWindowListener >( maLock ), 128 mpDialog(pDialog), mpCreatedParent(NULL), mxToolkit(rToolkit) 129 { 130 awt::SystemDependentXWindow aWindowHandle; 131 132 if (mxToolkit.is()) 133 { 134 uno::Reference< awt::XTopWindow > xWindow(mxToolkit->getActiveTopWindow()); 135 if (xWindow.is()) 136 { 137 uno::Reference< awt::XSystemDependentWindowPeer > xSystemDepParent(xWindow, uno::UNO_QUERY); 138 if (xSystemDepParent.is()) 139 { 140 141 sal_Int8 processID[16]; 142 143 rtl_getGlobalProcessId( (sal_uInt8*)processID ); 144 uno::Sequence<sal_Int8> processIdSeq(processID, 16); 145 uno::Any anyHandle = xSystemDepParent->getWindowHandle(processIdSeq, SystemDependent::SYSTEM_XWINDOW); 146 147 anyHandle >>= aWindowHandle; 148 } 149 } 150 } 151 152 GdkThreadLock aLock; 153 154 GdkDisplay *pDisplay = aWindowHandle.DisplayPointer ? gdk_x11_lookup_xdisplay(reinterpret_cast<void*>(static_cast<sal_IntPtr>(aWindowHandle.DisplayPointer))) : NULL; 155 GdkWindow* pParent = pDisplay ? gdk_window_lookup_for_display(pDisplay, aWindowHandle.WindowHandle) : NULL; 156 if (!pParent && pDisplay) 157 pParent = mpCreatedParent = gdk_window_foreign_new_for_display( pDisplay, aWindowHandle.WindowHandle); 158 if (pParent) 159 { 160 gtk_widget_realize(mpDialog); 161 gdk_window_set_transient_for(mpDialog->window, pParent); 162 } 163 } 164 165 166 RunDialog::~RunDialog() 167 { 168 if (mpCreatedParent) 169 { 170 GdkThreadLock aLock; 171 gdk_window_destroy (mpCreatedParent); 172 } 173 } 174 175 void SAL_CALL RunDialog::windowOpened( const ::com::sun::star::lang::EventObject& ) 176 throw (::com::sun::star::uno::RuntimeException) 177 { 178 GdkThreadLock aLock; 179 g_timeout_add_full(G_PRIORITY_HIGH_IDLE, 0, (GSourceFunc)canceldialog, this, NULL); 180 } 181 182 void RunDialog::cancel() 183 { 184 GdkThreadLock aLock; 185 gtk_dialog_response( GTK_DIALOG( mpDialog ), GTK_RESPONSE_CANCEL ); 186 gtk_widget_hide( mpDialog ); 187 } 188 189 gint RunDialog::run() 190 { 191 if (mxToolkit.is()) 192 mxToolkit->addTopWindowListener(this); 193 194 GdkThreadLock aLock; 195 gint nStatus = gtk_dialog_run( GTK_DIALOG( mpDialog ) ); 196 197 if (mxToolkit.is()) 198 mxToolkit->removeTopWindowListener(this); 199 200 if (nStatus != 1) //PLAY 201 gtk_widget_hide( mpDialog ); 202 203 return nStatus; 204 } 205 206 static void lcl_setGTKLanguage(const uno::Reference<lang::XMultiServiceFactory>& xServiceMgr) 207 { 208 static bool bSet = false; 209 if (bSet) 210 return; 211 212 OUString sUILocale; 213 try 214 { 215 uno::Reference<lang::XMultiServiceFactory> xConfigMgr = 216 uno::Reference<lang::XMultiServiceFactory>(xServiceMgr->createInstance( 217 OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider")), 218 UNO_QUERY_THROW ); 219 220 Sequence< Any > theArgs(1); 221 theArgs[ 0 ] <<= OUString::createFromAscii("org.openoffice.Office.Linguistic/General"); 222 223 uno::Reference< container::XNameAccess > xNameAccess = 224 uno::Reference< container::XNameAccess >(xConfigMgr->createInstanceWithArguments( 225 OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess"), theArgs ), 226 UNO_QUERY_THROW ); 227 228 if (xNameAccess.is()) 229 xNameAccess->getByName(OUString::createFromAscii("UILocale")) >>= sUILocale; 230 } catch (...) {} 231 232 if (sUILocale.getLength()) 233 { 234 sUILocale = sUILocale.replace('-', '_'); 235 rtl::OUString envVar(RTL_CONSTASCII_USTRINGPARAM("LANGUAGE")); 236 osl_setEnvironment(envVar.pData, sUILocale.pData); 237 } 238 bSet = true; 239 } 240 241 SalGtkPicker::SalGtkPicker(const uno::Reference<lang::XMultiServiceFactory>& xServiceMgr) : m_pDialog(0) 242 { 243 lcl_setGTKLanguage(xServiceMgr); 244 } 245 246 SalGtkPicker::~SalGtkPicker() 247 { 248 if (m_pDialog) 249 { 250 GdkThreadLock aLock; 251 gtk_widget_destroy(m_pDialog); 252 } 253 } 254 255 void SAL_CALL SalGtkPicker::implsetDisplayDirectory( const rtl::OUString& aDirectory ) 256 throw( lang::IllegalArgumentException, uno::RuntimeException ) 257 { 258 OSL_ASSERT( m_pDialog != NULL ); 259 260 OString aTxt = unicodetouri(aDirectory); 261 262 if( aTxt.lastIndexOf('/') == aTxt.getLength() - 1 ) 263 aTxt = aTxt.copy( 0, aTxt.getLength() - 1 ); 264 265 OSL_TRACE( "setting path to %s\n", aTxt.getStr() ); 266 267 GdkThreadLock aLock; 268 gtk_file_chooser_set_current_folder_uri( GTK_FILE_CHOOSER( m_pDialog ), 269 aTxt.getStr() ); 270 } 271 272 rtl::OUString SAL_CALL SalGtkPicker::implgetDisplayDirectory() throw( uno::RuntimeException ) 273 { 274 OSL_ASSERT( m_pDialog != NULL ); 275 276 GdkThreadLock aLock; 277 278 gchar* pCurrentFolder = 279 gtk_file_chooser_get_current_folder_uri( GTK_FILE_CHOOSER( m_pDialog ) ); 280 ::rtl::OUString aCurrentFolderName = uritounicode(pCurrentFolder); 281 g_free( pCurrentFolder ); 282 283 return aCurrentFolderName; 284 } 285 286 void SAL_CALL SalGtkPicker::implsetTitle( const rtl::OUString& aTitle ) throw( uno::RuntimeException ) 287 { 288 OSL_ASSERT( m_pDialog != NULL ); 289 290 ::rtl::OString aWindowTitle = OUStringToOString( aTitle, RTL_TEXTENCODING_UTF8 ); 291 292 GdkThreadLock aLock; 293 gtk_window_set_title( GTK_WINDOW( m_pDialog ), aWindowTitle.getStr() ); 294 } 295