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