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