summaryrefslogtreecommitdiff
path: root/vcl/unx/gtk
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@suse.com>2011-11-04 10:46:56 +0000
committerMichael Meeks <michael.meeks@suse.com>2011-11-04 11:56:12 +0000
commite335eb1438ed99260a5ca050548b2693b5b22b1c (patch)
tree9b8c75e23916089bef38153bda3ed6d5f4ea182f /vcl/unx/gtk
parent1097edc1e2275e8453829b1959c53ffe9d1343f9 (diff)
gtk3: move gtk+ file picker into vcl - a more sensible place for it
Diffstat (limited to 'vcl/unx/gtk')
-rw-r--r--vcl/unx/gtk/fpicker/FPServiceInfo.hxx53
-rw-r--r--vcl/unx/gtk/fpicker/FPentry.cxx141
-rw-r--r--vcl/unx/gtk/fpicker/SalGtkFilePicker.cxx2082
-rw-r--r--vcl/unx/gtk/fpicker/SalGtkFilePicker.hxx356
-rw-r--r--vcl/unx/gtk/fpicker/SalGtkFolderPicker.cxx253
-rw-r--r--vcl/unx/gtk/fpicker/SalGtkFolderPicker.hxx127
-rw-r--r--vcl/unx/gtk/fpicker/SalGtkPicker.cxx313
-rw-r--r--vcl/unx/gtk/fpicker/SalGtkPicker.hxx138
-rw-r--r--vcl/unx/gtk/fpicker/eventnotification.hxx54
-rw-r--r--vcl/unx/gtk/fpicker/fps_gnome.component37
-rw-r--r--vcl/unx/gtk/fpicker/fps_gnome.xml79
-rw-r--r--vcl/unx/gtk/fpicker/resourceprovider.cxx229
-rw-r--r--vcl/unx/gtk/fpicker/resourceprovider.hxx69
13 files changed, 3931 insertions, 0 deletions
diff --git a/vcl/unx/gtk/fpicker/FPServiceInfo.hxx b/vcl/unx/gtk/fpicker/FPServiceInfo.hxx
new file mode 100644
index 000000000000..c0352af2b25d
--- /dev/null
+++ b/vcl/unx/gtk/fpicker/FPServiceInfo.hxx
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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 _FPSERVICEINFO_HXX_
+#define _FPSERVICEINFO_HXX_
+
+//------------------------------------------------------------------------
+// defines
+//------------------------------------------------------------------------
+
+// the service names
+#define FILE_PICKER_SERVICE_NAME "com.sun.star.ui.dialogs.GtkFilePicker"
+#define FOLDER_PICKER_SERVICE_NAME "com.sun.star.ui.dialogs.GtkFolderPicker"
+
+// the implementation names
+#define FILE_PICKER_IMPL_NAME "com.sun.star.ui.dialogs.SalGtkFilePicker"
+#define FOLDER_PICKER_IMPL_NAME "com.sun.star.ui.dialogs.SalGtkFolderPicker"
+
+// the registry key names
+// a key under which this service will be registered,
+// Format: -> "/ImplName/UNO/SERVICES/ServiceName"
+// <Implementation-Name></UNO/SERVICES/><Service-Name>
+#define FILE_PICKER_REGKEY_NAME "/com.sun.star.ui.dialogs.SalGtkFilePicker/UNO/SERVICES/com.sun.star.ui.dialogs.GtkFilePicker"
+#define FOLDER_PICKER_REGKEY_NAME "/com.sun.star.ui.dialogs.SalGtkFolderPicker/UNO/SERVICES/com.sun.star.ui.dialogs.GtkFolderPicker"
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk/fpicker/FPentry.cxx b/vcl/unx/gtk/fpicker/FPentry.cxx
new file mode 100644
index 000000000000..0ea7fb4bd8c2
--- /dev/null
+++ b/vcl/unx/gtk/fpicker/FPentry.cxx
@@ -0,0 +1,141 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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_fpicker.hxx"
+
+#ifdef AIX
+#define _LINUX_SOURCE_COMPAT
+#include <sys/timer.h>
+#undef _LINUX_SOURCE_COMPAT
+#endif
+
+//----------------------------------------------
+// includes of other projects
+//----------------------------------------------
+#include <cppuhelper/factory.hxx>
+#include <osl/diagnose.h>
+#include "SalGtkFilePicker.hxx"
+#include "SalGtkFolderPicker.hxx"
+#include "FPServiceInfo.hxx"
+
+#include <glib-object.h>
+
+extern const guint gtk_major_version;
+extern const guint gtk_minor_version;
+
+//-----------------------------------------------
+// namespace directives
+//-----------------------------------------------
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::registry;
+using namespace ::cppu;
+using ::com::sun::star::ui::dialogs::XFilePicker2;
+using ::com::sun::star::ui::dialogs::XFolderPicker;
+
+//------------------------------------------------
+//
+//------------------------------------------------
+
+static Reference< XInterface > SAL_CALL createFileInstance(
+ const Reference< XMultiServiceFactory >& rServiceManager )
+{
+ return Reference< XInterface >(
+ static_cast< XFilePicker2* >(
+ new SalGtkFilePicker( rServiceManager ) ) );
+}
+
+static Reference< XInterface > SAL_CALL createFolderInstance(
+ const Reference< XMultiServiceFactory >& rServiceManager )
+{
+ return Reference< XInterface >(
+ static_cast< XFolderPicker* >(
+ new SalGtkFolderPicker( rServiceManager ) ) );
+}
+
+extern "C"
+{
+
+SAL_DLLPUBLIC_EXPORT void* SAL_CALL component_getFactory(
+ const sal_Char* pImplName, uno_Interface* pSrvManager, uno_Interface* /*pRegistryKey*/ )
+{
+ void* pRet = 0;
+
+ if( pSrvManager )
+ {
+ if (
+ /* crude gtkplug check */ !g_type_from_name( "GdkDisplay" ) ||
+ /* old version */ !( gtk_major_version >= 2 && gtk_minor_version >= 4 )
+ )
+ {
+ return 0;
+ }
+
+ Reference< XSingleServiceFactory > xFactory;
+
+ if (0 == rtl_str_compare(pImplName, FILE_PICKER_IMPL_NAME))
+ {
+ Sequence< OUString > aSNS( 1 );
+ aSNS.getArray( )[0] =
+ OUString(RTL_CONSTASCII_USTRINGPARAM(FILE_PICKER_SERVICE_NAME));
+
+ xFactory = createSingleFactory(
+ reinterpret_cast< XMultiServiceFactory* > ( pSrvManager ),
+ OUString::createFromAscii( pImplName ),
+ createFileInstance,
+ aSNS );
+ }
+ else if (0 == rtl_str_compare(pImplName, FOLDER_PICKER_IMPL_NAME))
+ {
+ Sequence< OUString > aSNS( 1 );
+ aSNS.getArray( )[0] =
+ OUString(RTL_CONSTASCII_USTRINGPARAM(FOLDER_PICKER_SERVICE_NAME));
+
+ xFactory = createSingleFactory(
+ reinterpret_cast< XMultiServiceFactory* > ( pSrvManager ),
+ OUString::createFromAscii( pImplName ),
+ createFolderInstance,
+ aSNS );
+ }
+
+ if ( xFactory.is() )
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+ }
+
+ return pRet;
+}
+
+} // extern "C"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk/fpicker/SalGtkFilePicker.cxx b/vcl/unx/gtk/fpicker/SalGtkFilePicker.cxx
new file mode 100644
index 000000000000..1cac9895c6ca
--- /dev/null
+++ b/vcl/unx/gtk/fpicker/SalGtkFilePicker.cxx
@@ -0,0 +1,2082 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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_fpicker.hxx"
+
+#ifdef AIX
+#define _LINUX_SOURCE_COMPAT
+#include <sys/timer.h>
+#undef _LINUX_SOURCE_COMPAT
+#endif
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
+#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
+#include <osl/diagnose.h>
+#include <osl/process.h>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/ui/dialogs/ControlActions.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <FPServiceInfo.hxx>
+#include <osl/mutex.hxx>
+#include <SalGtkFilePicker.hxx>
+
+#include <vcl/svapp.hxx>
+
+#include <tools/string.hxx>
+#include <tools/urlobj.hxx>
+
+#include <algorithm>
+#include <set>
+#include <string.h>
+#include "resourceprovider.hxx"
+
+//------------------------------------------------------------------------
+// namespace directives
+//------------------------------------------------------------------------
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::ui::dialogs::TemplateDescription;
+using namespace ::com::sun::star::ui::dialogs::ExtendedFilePickerElementIds;
+using namespace ::com::sun::star::ui::dialogs::CommonFilePickerElementIds;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+
+//------------------------------------------------------------------------
+// helper functions
+//------------------------------------------------------------------------
+
+namespace
+{
+ // controling event notifications
+ const bool STARTUP_SUSPENDED = true;
+ const bool STARTUP_ALIVE = false;
+
+ uno::Sequence<rtl::OUString> SAL_CALL FilePicker_getSupportedServiceNames()
+ {
+ uno::Sequence<rtl::OUString> aRet(3);
+ aRet[0] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.dialogs.FilePicker" ));
+ aRet[1] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.dialogs.SystemFilePicker" ));
+ aRet[2] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.dialogs.GtkFilePicker" ));
+ return aRet;
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+// constructor
+//-----------------------------------------------------------------------------------------
+
+static void expandexpanders(GtkContainer *pWidget)
+{
+ GList *pChildren = gtk_container_get_children(pWidget);
+ for( GList *p = pChildren; p; p = p->next )
+ {
+ if GTK_IS_CONTAINER(GTK_WIDGET(p->data))
+ expandexpanders(GTK_CONTAINER(GTK_WIDGET(p->data)));
+ if GTK_IS_EXPANDER(GTK_WIDGET(p->data))
+ gtk_expander_set_expanded(GTK_EXPANDER(GTK_WIDGET(p->data)), sal_True);
+ }
+ g_list_free(pChildren);
+}
+
+void SalGtkFilePicker::dialog_mapped_cb(GtkWidget *, SalGtkFilePicker *pobjFP)
+{
+ pobjFP->InitialMapping();
+}
+
+void SalGtkFilePicker::InitialMapping()
+{
+ if (!mbPreviewState )
+ {
+ gtk_widget_hide( m_pPreview );
+ gtk_file_chooser_set_preview_widget_active( GTK_FILE_CHOOSER( m_pDialog ), false);
+ }
+ gtk_widget_set_size_request (m_pPreview, -1, -1);
+}
+
+SalGtkFilePicker::SalGtkFilePicker( const uno::Reference<lang::XMultiServiceFactory>& xServiceMgr ) :
+ SalGtkPicker(xServiceMgr),
+ cppu::WeakComponentImplHelper10<
+ XFilterManager,
+ XFilterGroupManager,
+ XFilePickerControlAccess,
+ XFilePickerNotifier,
+ XFilePreview,
+ XFilePicker2,
+ lang::XInitialization,
+ util::XCancellable,
+ lang::XEventListener,
+ lang::XServiceInfo>( m_rbHelperMtx ),
+ m_xServiceMgr( xServiceMgr ),
+ m_pFilterList( NULL ),
+ m_pVBox ( NULL ),
+ mnHID_FolderChange( 0 ),
+ mnHID_SelectionChange( 0 ),
+ bVersionWidthUnset( false ),
+ mbPreviewState( sal_False ),
+ mHID_Preview( 0 ),
+ m_pPreview( NULL ),
+ m_pPseudoFilter( NULL ),
+ m_PreviewImageWidth( 256 ),
+ m_PreviewImageHeight( 256 )
+{
+ int i;
+
+ for( i = 0; i < TOGGLE_LAST; i++ )
+ {
+ m_pToggles[i] = NULL;
+ mbToggleVisibility[i] = false;
+ }
+
+ for( i = 0; i < BUTTON_LAST; i++ )
+ {
+ m_pButtons[i] = NULL;
+ mbButtonVisibility[i] = false;
+ }
+
+ for( i = 0; i < LIST_LAST; i++ )
+ {
+ m_pHBoxs[i] = NULL;
+ m_pAligns[i] = NULL;
+ m_pLists[i] = NULL;
+ m_pListLabels[i] = NULL;
+ mbListVisibility[i] = false;
+ }
+
+ CResourceProvider aResProvider;
+ OUString aFilePickerTitle = aResProvider.getResString( FILE_PICKER_TITLE_OPEN );
+
+ m_pDialog = gtk_file_chooser_dialog_new(
+ OUStringToOString( aFilePickerTitle, RTL_TEXTENCODING_UTF8 ).getStr(),
+ NULL,
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ (char *)NULL );
+
+ gtk_dialog_set_default_response( GTK_DIALOG (m_pDialog), GTK_RESPONSE_ACCEPT );
+
+ gtk_file_chooser_set_local_only( GTK_FILE_CHOOSER( m_pDialog ), sal_False );
+ gtk_file_chooser_set_select_multiple( GTK_FILE_CHOOSER( m_pDialog ), sal_False );
+
+ m_pVBox = gtk_vbox_new( sal_False, 0 );
+
+ // We don't want clickable items to have a huge hit-area
+ GtkWidget *pHBox = gtk_hbox_new( sal_False, 0 );
+ GtkWidget *pThinVBox = gtk_vbox_new( sal_False, 0 );
+
+ gtk_box_pack_end (GTK_BOX( m_pVBox ), pHBox, sal_False, sal_False, 0);
+ gtk_box_pack_start (GTK_BOX( pHBox ), pThinVBox, sal_False, sal_False, 0);
+ gtk_widget_show( pHBox );
+ gtk_widget_show( pThinVBox );
+
+ OUString aLabel;
+
+ for( i = 0; i < TOGGLE_LAST; i++ )
+ {
+ m_pToggles[i] = gtk_check_button_new();
+
+#define LABEL_TOGGLE( elem ) \
+ case elem : \
+ aLabel = aResProvider.getResString( CHECKBOX_##elem ); \
+ setLabel( CHECKBOX_##elem, aLabel ); \
+ break
+
+ switch( i ) {
+
+ LABEL_TOGGLE( AUTOEXTENSION );
+ LABEL_TOGGLE( PASSWORD );
+ LABEL_TOGGLE( FILTEROPTIONS );
+ LABEL_TOGGLE( READONLY );
+ LABEL_TOGGLE( LINK );
+ LABEL_TOGGLE( PREVIEW );
+ LABEL_TOGGLE( SELECTION );
+ default:
+ OSL_TRACE("Handle unknown control %d", i);
+ break;
+ }
+
+ gtk_box_pack_end( GTK_BOX( pThinVBox ), m_pToggles[i], sal_False, sal_False, 0 );
+ }
+
+ for( i = 0; i < LIST_LAST; i++ )
+ {
+ m_pHBoxs[i] = gtk_hbox_new( sal_False, 0 );
+
+ m_pAligns[i] = gtk_alignment_new(0, 0, 0, 1);
+
+ m_pLists[i] = gtk_combo_box_new_text();
+
+ m_pListLabels[i] = gtk_label_new( "" );
+
+#define LABEL_LIST( elem ) \
+ case elem : \
+ aLabel = aResProvider.getResString( LISTBOX_##elem##_LABEL ); \
+ setLabel( LISTBOX_##elem##_LABEL, aLabel ); \
+ break
+
+ switch( i )
+ {
+ LABEL_LIST( VERSION );
+ LABEL_LIST( TEMPLATE );
+ LABEL_LIST( IMAGE_TEMPLATE );
+ default:
+ OSL_TRACE("Handle unknown control %d", i);
+ break;
+ }
+
+ gtk_container_add( GTK_CONTAINER( m_pAligns[i]), m_pLists[i] );
+ gtk_box_pack_end( GTK_BOX( m_pHBoxs[i] ), m_pAligns[i], sal_False, sal_False, 0 );
+
+ gtk_box_pack_end( GTK_BOX( m_pHBoxs[i] ), m_pListLabels[i], sal_False, sal_False, 0 );
+
+ gtk_box_pack_end( GTK_BOX( m_pVBox ), m_pHBoxs[i], sal_False, sal_False, 0 );
+ }
+
+ aLabel = aResProvider.getResString( FILE_PICKER_FILE_TYPE );
+ m_pFilterExpander = gtk_expander_new_with_mnemonic(
+ OUStringToOString( aLabel, RTL_TEXTENCODING_UTF8 ).getStr());
+
+ gtk_box_pack_end( GTK_BOX( m_pVBox ), m_pFilterExpander, sal_False, sal_True, 0 );
+
+ GtkWidget *scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window),
+ GTK_SHADOW_IN);
+ gtk_container_add (GTK_CONTAINER (m_pFilterExpander), scrolled_window);
+ gtk_widget_show (scrolled_window);
+
+ rtl::OString sExpand(getenv("SAL_EXPANDFPICKER"));
+ sal_Int32 nExpand = sExpand.toInt32();
+ switch (nExpand)
+ {
+ default:
+ case 0:
+ break;
+ case 1:
+ gtk_expander_set_expanded(GTK_EXPANDER(m_pFilterExpander), sal_True);
+ break;
+ case 2:
+ expandexpanders(GTK_CONTAINER(m_pDialog));
+ gtk_expander_set_expanded(GTK_EXPANDER(m_pFilterExpander), sal_True);
+ break;
+ }
+
+ m_pFilterStore = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING);
+ m_pFilterView = gtk_tree_view_new_with_model (GTK_TREE_MODEL(m_pFilterStore));
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(m_pFilterView), false);
+ gtk_tree_view_set_rules_hint (GTK_TREE_VIEW(m_pFilterView), true);
+
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *cell;
+
+ for (i = 0; i < 2; ++i)
+ {
+ column = gtk_tree_view_column_new ();
+ cell = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_set_expand (column, sal_True);
+ gtk_tree_view_column_pack_start (column, cell, sal_False);
+ gtk_tree_view_column_set_attributes (column, cell, "text", i, (char *)NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW(m_pFilterView), column);
+ }
+
+ gtk_container_add (GTK_CONTAINER (scrolled_window), m_pFilterView);
+ gtk_widget_show (m_pFilterView);
+
+ gtk_file_chooser_set_extra_widget( GTK_FILE_CHOOSER( m_pDialog ), m_pVBox );
+
+ m_pPreview = gtk_image_new();
+ gtk_file_chooser_set_preview_widget( GTK_FILE_CHOOSER( m_pDialog ), m_pPreview );
+
+ g_signal_connect( G_OBJECT( m_pToggles[PREVIEW] ), "toggled",
+ G_CALLBACK( preview_toggled_cb ), this );
+ g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW(m_pFilterView)), "changed",
+ G_CALLBACK ( type_changed_cb ), this);
+ g_signal_connect( G_OBJECT( m_pDialog ), "notify::filter",
+ G_CALLBACK( filter_changed_cb ), this);
+ g_signal_connect( G_OBJECT( m_pFilterExpander ), "activate",
+ G_CALLBACK( expander_changed_cb ), this);
+ g_signal_connect (G_OBJECT( m_pDialog ), "map",
+ G_CALLBACK (dialog_mapped_cb), this);
+
+ gtk_widget_show( m_pVBox );
+
+ PangoLayout *layout = gtk_widget_create_pango_layout (m_pFilterView, NULL);
+ guint ypad;
+ PangoRectangle row_height;
+ pango_layout_set_markup (layout, "All Files", -1);
+ pango_layout_get_pixel_extents (layout, NULL, &row_height);
+ g_object_get (cell, "ypad", &ypad, (char *)NULL);
+ guint height = (row_height.height + 2*ypad) * 5;
+ gtk_widget_set_size_request (m_pFilterView, -1, height);
+ gtk_widget_set_size_request (m_pPreview, 1, height);
+
+ gtk_file_chooser_set_preview_widget_active( GTK_FILE_CHOOSER( m_pDialog ), true);
+}
+
+//------------------------------------------------------------------------------------
+// XFilePickerNotifier
+//------------------------------------------------------------------------------------
+
+void SAL_CALL SalGtkFilePicker::addFilePickerListener( const uno::Reference<XFilePickerListener>& xListener )
+ throw( uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ OSL_ENSURE(!m_xListener.is(),
+ "SalGtkFilePicker only talks with one listener at a time...");
+ m_xListener = xListener;
+}
+
+void SAL_CALL SalGtkFilePicker::removeFilePickerListener( const uno::Reference<XFilePickerListener>& )
+ throw( uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ m_xListener.clear();
+}
+
+// -------------------------------------------------
+// XEventListener
+// -------------------------------------------------
+
+void SAL_CALL SalGtkFilePicker::disposing( const lang::EventObject& aEvent ) throw( uno::RuntimeException )
+{
+ // no member access => no mutex needed
+
+ uno::Reference<XFilePickerListener> xFilePickerListener( aEvent.Source, ::com::sun::star::uno::UNO_QUERY );
+
+ if( xFilePickerListener.is() )
+ removeFilePickerListener( xFilePickerListener );
+}
+
+//-----------------------------------------------------------------------------------------
+// FilePicker Event functions
+//-----------------------------------------------------------------------------------------
+
+void SalGtkFilePicker::impl_fileSelectionChanged( FilePickerEvent aEvent )
+{
+ OSL_TRACE( "file selection changed");
+ if (m_xListener.is()) m_xListener->fileSelectionChanged( aEvent );
+}
+
+void SalGtkFilePicker::impl_directoryChanged( FilePickerEvent aEvent )
+{
+ OSL_TRACE("directory changed");
+ if (m_xListener.is()) m_xListener->directoryChanged( aEvent );
+}
+
+void SalGtkFilePicker::impl_controlStateChanged( FilePickerEvent aEvent )
+{
+ OSL_TRACE("control state changed");
+ if (m_xListener.is()) m_xListener->controlStateChanged( aEvent );
+}
+
+//=====================================================================
+
+struct FilterEntry
+{
+protected:
+ ::rtl::OUString m_sTitle;
+ ::rtl::OUString m_sFilter;
+
+ UnoFilterList m_aSubFilters;
+
+public:
+ FilterEntry( const ::rtl::OUString& _rTitle, const ::rtl::OUString& _rFilter )
+ :m_sTitle( _rTitle )
+ ,m_sFilter( _rFilter )
+ {
+ }
+
+ FilterEntry( const ::rtl::OUString& _rTitle, const UnoFilterList& _rSubFilters );
+
+ ::rtl::OUString getTitle() const { return m_sTitle; }
+ ::rtl::OUString getFilter() const { return m_sFilter; }
+
+ /// determines if the filter has sub filter (i.e., the filter is a filter group in real)
+ sal_Bool hasSubFilters( ) const;
+
+ /** retrieves the filters belonging to the entry
+ @return
+ the number of sub filters
+ */
+ sal_Int32 getSubFilters( UnoFilterList& _rSubFilterList );
+
+ // helpers for iterating the sub filters
+ const UnoFilterEntry* beginSubFilters() const { return m_aSubFilters.getConstArray(); }
+ const UnoFilterEntry* endSubFilters() const { return m_aSubFilters.getConstArray() + m_aSubFilters.getLength(); }
+};
+
+//=====================================================================
+
+//---------------------------------------------------------------------
+FilterEntry::FilterEntry( const ::rtl::OUString& _rTitle, const UnoFilterList& _rSubFilters )
+ :m_sTitle( _rTitle )
+ ,m_aSubFilters( _rSubFilters )
+{
+}
+
+//---------------------------------------------------------------------
+sal_Bool FilterEntry::hasSubFilters() const
+{
+ return( 0 < m_aSubFilters.getLength() );
+}
+
+//---------------------------------------------------------------------
+sal_Int32 FilterEntry::getSubFilters( UnoFilterList& _rSubFilterList )
+{
+ _rSubFilterList = m_aSubFilters;
+ return m_aSubFilters.getLength();
+}
+
+static bool
+isFilterString( const rtl::OUString &rFilterString, const char *pMatch )
+{
+ sal_Int32 nIndex = 0;
+ rtl::OUString aToken;
+ bool bIsFilter = true;
+
+ rtl::OUString aMatch(rtl::OUString::createFromAscii(pMatch));
+
+ do
+ {
+ aToken = rFilterString.getToken( 0, ';', nIndex );
+ if( !aToken.match( aMatch ) )
+ {
+ bIsFilter = false;
+ break;
+ }
+ }
+ while( nIndex >= 0 );
+
+ return bIsFilter;
+}
+
+static rtl::OUString
+shrinkFilterName( const rtl::OUString &rFilterName, bool bAllowNoStar = false )
+{
+ int i;
+ int nBracketLen = -1;
+ int nBracketEnd = -1;
+ const sal_Unicode *pStr = rFilterName.getStr();
+ OUString aRealName = rFilterName;
+
+ for( i = aRealName.getLength() - 1; i > 0; i-- )
+ {
+ if( pStr[i] == ')' )
+ nBracketEnd = i;
+ else if( pStr[i] == '(' )
+ {
+ nBracketLen = nBracketEnd - i;
+ if( nBracketEnd <= 0 )
+ continue;
+ if( isFilterString( rFilterName.copy( i + 1, nBracketLen - 1 ), "*." ) )
+ aRealName = aRealName.replaceAt( i, nBracketLen + 1, rtl::OUString() );
+ else if (bAllowNoStar)
+ {
+ if( isFilterString( rFilterName.copy( i + 1, nBracketLen - 1 ), ".") )
+ aRealName = aRealName.replaceAt( i, nBracketLen + 1, rtl::OUString() );
+ }
+ }
+ }
+
+ return aRealName;
+}
+
+static void
+dialog_remove_buttons( GtkDialog *pDialog )
+{
+ g_return_if_fail( GTK_IS_DIALOG( pDialog ) );
+
+ GList *pChildren =
+ gtk_container_get_children( GTK_CONTAINER( pDialog->action_area ) );
+
+ for( GList *p = pChildren; p; p = p->next )
+ gtk_widget_destroy( GTK_WIDGET( p->data ) );
+
+ g_list_free( pChildren );
+}
+
+//------------------------------------------------------------------------------------
+namespace {
+ //................................................................................
+ struct FilterTitleMatch : public ::std::unary_function< FilterEntry, bool >
+ {
+ protected:
+ const ::rtl::OUString& rTitle;
+
+ public:
+ FilterTitleMatch( const ::rtl::OUString& _rTitle ) : rTitle( _rTitle ) { }
+
+ //............................................................................
+ bool operator () ( const FilterEntry& _rEntry )
+ {
+ sal_Bool bMatch;
+ if( !_rEntry.hasSubFilters() )
+ // a real filter
+ bMatch = ( _rEntry.getTitle() == rTitle );
+ else
+ // a filter group -> search the sub filters
+ bMatch =
+ _rEntry.endSubFilters() != ::std::find_if(
+ _rEntry.beginSubFilters(),
+ _rEntry.endSubFilters(),
+ *this
+ );
+
+ return bMatch ? true : false;
+ }
+ bool operator () ( const UnoFilterEntry& _rEntry )
+ {
+ OUString aShrunkName = shrinkFilterName( _rEntry.First );
+ return aShrunkName == rTitle ? true : false;
+ }
+ };
+}
+
+
+//------------------------------------------------------------------------------------
+sal_Bool SalGtkFilePicker::FilterNameExists( const ::rtl::OUString& rTitle )
+{
+ sal_Bool bRet = sal_False;
+
+ if( m_pFilterList )
+ bRet =
+ m_pFilterList->end() != ::std::find_if(
+ m_pFilterList->begin(),
+ m_pFilterList->end(),
+ FilterTitleMatch( rTitle )
+ );
+
+ return bRet;
+}
+
+//------------------------------------------------------------------------------------
+sal_Bool SalGtkFilePicker::FilterNameExists( const UnoFilterList& _rGroupedFilters )
+{
+ sal_Bool bRet = sal_False;
+
+ if( m_pFilterList )
+ {
+ const UnoFilterEntry* pStart = _rGroupedFilters.getConstArray();
+ const UnoFilterEntry* pEnd = pStart + _rGroupedFilters.getLength();
+ for( ; pStart != pEnd; ++pStart )
+ if( m_pFilterList->end() != ::std::find_if(
+ m_pFilterList->begin(),
+ m_pFilterList->end(),
+ FilterTitleMatch( pStart->First ) ) )
+ break;
+
+ bRet = pStart != pEnd;
+ }
+
+ return bRet;
+}
+
+//------------------------------------------------------------------------------------
+void SalGtkFilePicker::ensureFilterList( const ::rtl::OUString& _rInitialCurrentFilter )
+{
+ if( !m_pFilterList )
+ {
+ m_pFilterList = new FilterList;
+
+ // set the first filter to the current filter
+ if ( !m_aCurrentFilter.getLength() )
+ m_aCurrentFilter = _rInitialCurrentFilter;
+ }
+}
+
+
+//-----------------------------------------------------------------------------------------
+//
+//-----------------------------------------------------------------------------------------
+
+void SAL_CALL SalGtkFilePicker::appendFilter( const rtl::OUString& aTitle, const rtl::OUString& aFilter )
+ throw( lang::IllegalArgumentException, uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ OSL_ASSERT( m_pDialog != NULL );
+
+ if( FilterNameExists( aTitle ) )
+ throw IllegalArgumentException();
+
+ // ensure that we have a filter list
+ ensureFilterList( aTitle );
+
+ // append the filter
+ m_pFilterList->insert( m_pFilterList->end(), FilterEntry( aTitle, aFilter ) );
+}
+
+//-----------------------------------------------------------------------------------------
+//
+//-----------------------------------------------------------------------------------------
+
+void SAL_CALL SalGtkFilePicker::setCurrentFilter( const rtl::OUString& aTitle )
+ throw( lang::IllegalArgumentException, uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ OSL_ASSERT( m_pDialog != NULL );
+
+ OSL_TRACE( "Setting current filter to %s\n",
+ OUStringToOString( aTitle, RTL_TEXTENCODING_UTF8 ).getStr() );
+
+ if( aTitle != m_aCurrentFilter )
+ {
+ m_aCurrentFilter = aTitle;
+ SetCurFilter( m_aCurrentFilter );
+ OSL_TRACE( "REALLY Setting current filter to %s\n",
+ OUStringToOString( aTitle, RTL_TEXTENCODING_UTF8 ).getStr() );
+
+ }
+
+ // TODO m_pImpl->setCurrentFilter( aTitle );
+}
+
+//-----------------------------------------------------------------------------------------
+//
+//-----------------------------------------------------------------------------------------
+
+void SalGtkFilePicker::updateCurrentFilterFromName(const gchar* filtername)
+{
+ OUString aFilterName(filtername, strlen(filtername), RTL_TEXTENCODING_UTF8);
+ FilterList::iterator aEnd = m_pFilterList->end();
+ for (FilterList::iterator aIter = m_pFilterList->begin(); aIter != aEnd; ++aIter)
+ {
+ if (aFilterName == shrinkFilterName( aIter->getTitle()))
+ {
+ m_aCurrentFilter = aIter->getTitle();
+ break;
+ }
+ }
+}
+
+void SalGtkFilePicker::UpdateFilterfromUI()
+{
+ // Update the filtername from the users selection if they have had a chance to do so.
+ // If the user explicitly sets a type then use that, if not then take the implicit type
+ // from the filter of the files glob on which he is currently searching
+ if (!mnHID_FolderChange || !mnHID_SelectionChange)
+ return;
+
+ GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(m_pFilterView));
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ gchar *title;
+ gtk_tree_model_get (model, &iter, 2, &title, -1);
+ updateCurrentFilterFromName(title);
+ g_free (title);
+ }
+ else if( GtkFileFilter *filter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(m_pDialog)))
+ {
+ if (m_pPseudoFilter != filter)
+ updateCurrentFilterFromName(gtk_file_filter_get_name( filter ));
+ else
+ updateCurrentFilterFromName(OUStringToOString( m_aInitialFilter, RTL_TEXTENCODING_UTF8 ).getStr());
+ }
+}
+
+rtl::OUString SAL_CALL SalGtkFilePicker::getCurrentFilter() throw( uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ OSL_ASSERT( m_pDialog != NULL );
+
+ OSL_TRACE( "GetCURRENTfilter" );
+
+ UpdateFilterfromUI();
+
+ OSL_TRACE( "Returning current filter of %s\n",
+ OUStringToOString( m_aCurrentFilter, RTL_TEXTENCODING_UTF8 ).getStr() );
+
+ return m_aCurrentFilter;
+}
+
+//-----------------------------------------------------------------------------------------
+// XFilterGroupManager functions
+//-----------------------------------------------------------------------------------------
+
+void SAL_CALL SalGtkFilePicker::appendFilterGroup( const rtl::OUString& /*sGroupTitle*/, const uno::Sequence<beans::StringPair>& aFilters )
+ throw( lang::IllegalArgumentException, uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ OSL_ASSERT( m_pDialog != NULL );
+
+ // TODO m_pImpl->appendFilterGroup( sGroupTitle, aFilters );
+ // check the names
+ if( FilterNameExists( aFilters ) )
+ // TODO: a more precise exception message
+ throw IllegalArgumentException();
+
+ // ensure that we have a filter list
+ ::rtl::OUString sInitialCurrentFilter;
+ if( aFilters.getLength() )
+ sInitialCurrentFilter = aFilters[0].First;
+
+ ensureFilterList( sInitialCurrentFilter );
+
+ // append the filter
+ const StringPair* pSubFilters = aFilters.getConstArray();
+ const StringPair* pSubFiltersEnd = pSubFilters + aFilters.getLength();
+ for( ; pSubFilters != pSubFiltersEnd; ++pSubFilters )
+ m_pFilterList->insert( m_pFilterList->end(), FilterEntry( pSubFilters->First, pSubFilters->Second ) );
+
+}
+
+//-----------------------------------------------------------------------------------------
+// XFilePicker functions
+//-----------------------------------------------------------------------------------------
+
+void SAL_CALL SalGtkFilePicker::setMultiSelectionMode( sal_Bool bMode ) throw( uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ OSL_ASSERT( m_pDialog != NULL );
+
+ gtk_file_chooser_set_select_multiple( GTK_FILE_CHOOSER(m_pDialog), bMode );
+}
+
+void SAL_CALL SalGtkFilePicker::setDefaultName( const rtl::OUString& aName )
+ throw( uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ OSL_ASSERT( m_pDialog != NULL );
+
+ OString aStr = OUStringToOString( aName, RTL_TEXTENCODING_UTF8 );
+ GtkFileChooserAction eAction = gtk_file_chooser_get_action( GTK_FILE_CHOOSER( m_pDialog ) );
+
+ // set_current_name launches a Gtk critical error if called for other than save
+ if( GTK_FILE_CHOOSER_ACTION_SAVE == eAction )
+ gtk_file_chooser_set_current_name( GTK_FILE_CHOOSER( m_pDialog ), aStr.getStr() );
+}
+
+void SAL_CALL SalGtkFilePicker::setDisplayDirectory( const rtl::OUString& rDirectory )
+ throw( lang::IllegalArgumentException, uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ implsetDisplayDirectory(rDirectory);
+}
+
+rtl::OUString SAL_CALL SalGtkFilePicker::getDisplayDirectory() throw( uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ return implgetDisplayDirectory();
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL SalGtkFilePicker::getFiles() throw( uno::RuntimeException )
+{
+ // no member access => no mutex needed
+
+ uno::Sequence< rtl::OUString > aFiles = getSelectedFiles();
+ /*
+ The previous multiselection API design was completely broken
+ and unimplementable for some hetrogenous pseudo-URIs eg. search://
+ Thus crop unconditionally to a single selection.
+ */
+ aFiles.realloc (1);
+ return aFiles;
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL SalGtkFilePicker::getSelectedFiles() throw( uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ OSL_ASSERT( m_pDialog != NULL );
+
+ GSList* pPathList = gtk_file_chooser_get_uris( GTK_FILE_CHOOSER(m_pDialog) );
+
+ int nCount = g_slist_length( pPathList );
+ int nIndex = 0;
+ OSL_TRACE( "GETFILES called %d files", nCount );
+
+ // get the current action setting
+ GtkFileChooserAction eAction = gtk_file_chooser_get_action(
+ GTK_FILE_CHOOSER( m_pDialog ));
+
+ uno::Sequence< rtl::OUString > aSelectedFiles(nCount);
+
+ // Convert to OOo
+ for( GSList *pElem = pPathList; pElem; pElem = pElem->next)
+ {
+ gchar *pURI = reinterpret_cast<gchar*>(pElem->data);
+ aSelectedFiles[ nIndex ] = uritounicode(pURI);
+
+ if( GTK_FILE_CHOOSER_ACTION_SAVE == eAction )
+ {
+ OUString sFilterName;
+ sal_Int32 nTokenIndex = 0;
+ bool bExtensionTypedIn = false;
+
+ GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(m_pFilterView));
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ gchar *title;
+ gtk_tree_model_get (model, &iter, 2, &title, -1);
+ sFilterName = OUString( title, strlen( title), RTL_TEXTENCODING_UTF8 );
+ g_free (title);
+ }
+ else
+ {
+ if( aSelectedFiles[nIndex].indexOf('.') > 0 )
+ {
+ rtl::OUString sExtension;
+ nTokenIndex = 0;
+ do
+ sExtension = aSelectedFiles[nIndex].getToken( 0, '.', nTokenIndex );
+ while( nTokenIndex >= 0 );
+
+ if( sExtension.getLength() >= 3 ) // 3 = typical/minimum extension length
+ {
+ static const OUString aStarDot(RTL_CONSTASCII_USTRINGPARAM( "*." ));
+
+ ::rtl::OUString aNewFilter;
+ ::rtl::OUString aOldFilter = getCurrentFilter();
+ sal_Bool bChangeFilter = sal_True;
+ for ( FilterList::iterator aListIter = m_pFilterList->begin();
+ aListIter != m_pFilterList->end();
+ ++aListIter
+ )
+ {
+ if( aListIter->getFilter().equalsIgnoreAsciiCase( aStarDot+sExtension ) )
+ {
+ if( !aNewFilter.getLength() )
+ aNewFilter = aListIter->getTitle();
+
+ if( aOldFilter == aListIter->getTitle() )
+ bChangeFilter = sal_False;
+
+ bExtensionTypedIn = true;
+ }
+ }
+ if( bChangeFilter && bExtensionTypedIn )
+ setCurrentFilter( aNewFilter );
+ }
+ }
+
+ GtkFileFilter *filter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(m_pDialog));
+ if (m_pPseudoFilter != filter)
+ {
+ const gchar* filtername = gtk_file_filter_get_name( filter );
+ sFilterName = OUString( filtername, strlen( filtername ), RTL_TEXTENCODING_UTF8 );
+ }
+ else
+ sFilterName = m_aInitialFilter;
+ }
+
+ OSL_TRACE( "2: current filter is %s\n",
+ OUStringToOString( sFilterName, RTL_TEXTENCODING_UTF8 ).getStr() );
+
+ FilterList::iterator aListIter = ::std::find_if(
+ m_pFilterList->begin(), m_pFilterList->end(), FilterTitleMatch(sFilterName) );
+
+ OUString aFilter;
+ if (aListIter != m_pFilterList->end())
+ aFilter = aListIter->getFilter();
+
+ OSL_TRACE( "turned into %s\n",
+ OUStringToOString( aFilter, RTL_TEXTENCODING_UTF8 ).getStr() );
+
+ nTokenIndex = 0;
+ rtl::OUString sToken;
+ // rtl::OUString strExt;
+ do
+ {
+ sToken = aFilter.getToken( 0, '.', nTokenIndex );
+
+ if ( sToken.lastIndexOf( ';' ) != -1 )
+ {
+ sal_Int32 nZero = 0;
+ OUString aCurrentToken = sToken.getToken( 0, ';', nZero);
+
+ sToken = aCurrentToken;
+ break;
+ }
+ }
+ while( nTokenIndex >= 0 );
+
+ if( !bExtensionTypedIn && ( !sToken.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("*")) ) )
+ {
+ //if the filename does not already have the auto extension, stick it on
+ OUString sExtension = OUString(RTL_CONSTASCII_USTRINGPARAM( "." )) + sToken;
+ OUString &rBase = aSelectedFiles[nIndex];
+ sal_Int32 nExtensionIdx = rBase.getLength() - sExtension.getLength();
+ OSL_TRACE( "idx are %d %d", rBase.lastIndexOf( sExtension ), nExtensionIdx );
+
+ if( rBase.lastIndexOf( sExtension ) != nExtensionIdx )
+ rBase += sExtension;
+ }
+
+ }
+
+ nIndex++;
+ g_free( pURI );
+ }
+
+ g_slist_free( pPathList );
+
+ return aSelectedFiles;
+}
+
+//-----------------------------------------------------------------------------------------
+// XExecutableDialog functions
+//-----------------------------------------------------------------------------------------
+
+void SAL_CALL SalGtkFilePicker::setTitle( const rtl::OUString& rTitle ) throw( uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ implsetTitle(rTitle);
+}
+
+sal_Int16 SAL_CALL SalGtkFilePicker::execute() throw( uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ OSL_TRACE( "1: HERE WE ARE");
+ OSL_ASSERT( m_pDialog != NULL );
+
+ sal_Int16 retVal = 0;
+
+ SetFilters();
+
+ mnHID_FolderChange =
+ g_signal_connect( GTK_FILE_CHOOSER( m_pDialog ), "current-folder-changed",
+ G_CALLBACK( folder_changed_cb ), ( gpointer )this );
+
+ mnHID_SelectionChange =
+ g_signal_connect( GTK_FILE_CHOOSER( m_pDialog ), "selection-changed",
+ G_CALLBACK( selection_changed_cb ), ( gpointer )this );
+
+ int btn = GTK_RESPONSE_NO;
+
+ uno::Reference< awt::XExtendedToolkit > xToolkit(
+ m_xServiceMgr->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.Toolkit")) ), uno::UNO_QUERY);
+
+ uno::Reference< frame::XDesktop > xDesktop(
+ m_xServiceMgr->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ), uno::UNO_QUERY);
+
+ RunDialog* pRunDialog = new RunDialog(m_pDialog, xToolkit, xDesktop);
+ uno::Reference < awt::XTopWindowListener > xLifeCycle(pRunDialog);
+ while( GTK_RESPONSE_NO == btn )
+ {
+ btn = GTK_RESPONSE_YES; // we dont want to repeat unless user clicks NO for file save.
+
+ gint nStatus = pRunDialog->run();
+ switch( nStatus )
+ {
+ case GTK_RESPONSE_ACCEPT:
+ if( GTK_FILE_CHOOSER_ACTION_SAVE == gtk_file_chooser_get_action( GTK_FILE_CHOOSER( m_pDialog ) ) )
+ {
+ Sequence < OUString > aPathSeq = getFiles();
+ if( aPathSeq.getLength() == 1 )
+ {
+ OString sFileName = unicodetouri( aPathSeq[0] );
+ if( g_file_test( g_filename_from_uri( sFileName.getStr(), NULL, NULL ), G_FILE_TEST_IS_REGULAR ) )
+ {
+ CResourceProvider aResProvider;
+ GtkWidget *dlg;
+
+
+ INetURLObject aFileObj( sFileName );
+
+ OString baseName(
+ OUStringToOString(
+ aFileObj.getName(
+ INetURLObject::LAST_SEGMENT,
+ true,
+ INetURLObject::DECODE_WITH_CHARSET
+ ),
+ RTL_TEXTENCODING_UTF8
+ )
+ );
+ OString aMsg(
+ OUStringToOString(
+ aResProvider.getResString( FILE_PICKER_OVERWRITE ),
+ RTL_TEXTENCODING_UTF8
+ )
+ );
+ OString toReplace( RTL_CONSTASCII_STRINGPARAM( "$filename$" ));
+
+ aMsg = aMsg.replaceAt(
+ aMsg.indexOf( toReplace ),
+ toReplace.getLength(),
+ baseName
+ );
+
+ dlg = gtk_message_dialog_new( NULL,
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_QUESTION,
+ GTK_BUTTONS_YES_NO,
+ "%s",
+ aMsg.getStr()
+ );
+
+ gtk_window_set_title( GTK_WINDOW( dlg ),
+ OUStringToOString(aResProvider.getResString(FILE_PICKER_TITLE_SAVE ),
+ RTL_TEXTENCODING_UTF8 ).getStr() );
+
+ RunDialog* pAnotherDialog = new RunDialog(dlg, xToolkit, xDesktop);
+ uno::Reference < awt::XTopWindowListener > xAnotherLifeCycle(pAnotherDialog);
+ btn = pAnotherDialog->run();
+
+ gtk_widget_destroy( dlg );
+ }
+
+ if( btn == GTK_RESPONSE_YES )
+ retVal = ExecutableDialogResults::OK;
+ }
+ }
+ else
+ retVal = ExecutableDialogResults::OK;
+ break;
+
+ case GTK_RESPONSE_CANCEL:
+ retVal = ExecutableDialogResults::CANCEL;
+ break;
+
+ case 1: //PLAY
+ {
+ FilePickerEvent evt;
+ evt.ElementId = PUSHBUTTON_PLAY;
+ OSL_TRACE( "filter_changed, isn't it great %x", this);
+ impl_controlStateChanged( evt );
+ btn = GTK_RESPONSE_NO;
+ }
+ break;
+
+ default:
+ retVal = 0;
+ break;
+ }
+ }
+
+ if (mnHID_FolderChange)
+ g_signal_handler_disconnect(GTK_FILE_CHOOSER( m_pDialog ), mnHID_FolderChange);
+ if (mnHID_SelectionChange)
+ g_signal_handler_disconnect(GTK_FILE_CHOOSER( m_pDialog ), mnHID_SelectionChange);
+
+ return retVal;
+}
+
+//------------------------------------------------------------------------------------
+
+// cf. offapi/com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.idl
+GtkWidget *SalGtkFilePicker::getWidget( sal_Int16 nControlId, GType *pType )
+{
+ OSL_TRACE("control id is %d", nControlId);
+ GType tType = GTK_TYPE_TOGGLE_BUTTON; //prevent waring by initializing
+ GtkWidget *pWidget = 0;
+
+#define MAP_TOGGLE( elem ) \
+ case ExtendedFilePickerElementIds::CHECKBOX_##elem: \
+ pWidget = m_pToggles[elem]; tType = GTK_TYPE_TOGGLE_BUTTON; \
+ break
+#define MAP_BUTTON( elem ) \
+ case ExtendedFilePickerElementIds::PUSHBUTTON_##elem: \
+ pWidget = m_pButtons[elem]; tType = GTK_TYPE_BUTTON; \
+ break
+#define MAP_LIST( elem ) \
+ case ExtendedFilePickerElementIds::LISTBOX_##elem: \
+ pWidget = m_pLists[elem]; tType = GTK_TYPE_COMBO_BOX; \
+ break
+#define MAP_LIST_LABEL( elem ) \
+ case ExtendedFilePickerElementIds::LISTBOX_##elem##_LABEL: \
+ pWidget = m_pListLabels[elem]; tType = GTK_TYPE_LABEL; \
+ break
+
+ switch( nControlId )
+ {
+ MAP_TOGGLE( AUTOEXTENSION );
+ MAP_TOGGLE( PASSWORD );
+ MAP_TOGGLE( FILTEROPTIONS );
+ MAP_TOGGLE( READONLY );
+ MAP_TOGGLE( LINK );
+ MAP_TOGGLE( PREVIEW );
+ MAP_TOGGLE( SELECTION );
+ MAP_BUTTON( PLAY );
+ MAP_LIST( VERSION );
+ MAP_LIST( TEMPLATE );
+ MAP_LIST( IMAGE_TEMPLATE );
+ MAP_LIST_LABEL( VERSION );
+ MAP_LIST_LABEL( TEMPLATE );
+ MAP_LIST_LABEL( IMAGE_TEMPLATE );
+ default:
+ OSL_TRACE("Handle unknown control %d", nControlId);
+ break;
+ }
+#undef MAP
+
+ if( pType )
+ *pType = tType;
+ return pWidget;
+}
+
+
+
+//------------------------------------------------------------------------------------
+// XFilePickerControlAccess functions
+//------------------------------------------------------------------------------------
+namespace
+{
+ void HackWidthToFirst(GtkComboBox *pWidget)
+ {
+ GtkRequisition requisition;
+ gtk_widget_size_request(GTK_WIDGET(pWidget), &requisition);
+ gtk_widget_set_size_request(GTK_WIDGET(pWidget), requisition.width, -1);
+ }
+}
+
+void SalGtkFilePicker::HandleSetListValue(GtkComboBox *pWidget, sal_Int16 nControlAction, const uno::Any& rValue)
+{
+ switch (nControlAction)
+ {
+ case ControlActions::ADD_ITEM:
+ {
+ OUString sItem;
+ rValue >>= sItem;
+ gtk_combo_box_append_text(pWidget, rtl::OUStringToOString(sItem, RTL_TEXTENCODING_UTF8).getStr());
+ if (!bVersionWidthUnset)
+ {
+ HackWidthToFirst(pWidget);
+ bVersionWidthUnset = true;
+ }
+ }
+ break;
+ case ControlActions::ADD_ITEMS:
+ {
+ Sequence< OUString > aStringList;
+ rValue >>= aStringList;
+ sal_Int32 nItemCount = aStringList.getLength();
+ for (sal_Int32 i = 0; i < nItemCount; ++i)
+ {
+ gtk_combo_box_append_text(pWidget,
+ rtl::OUStringToOString(aStringList[i], RTL_TEXTENCODING_UTF8).getStr());
+ if (!bVersionWidthUnset)
+ {
+ HackWidthToFirst(pWidget);
+ bVersionWidthUnset = true;
+ }
+ }
+ }
+ break;
+ case ControlActions::DELETE_ITEM:
+ {
+ sal_Int32 nPos=0;
+ rValue >>= nPos;
+ gtk_combo_box_remove_text(pWidget, nPos);
+ }
+ break;
+ case ControlActions::DELETE_ITEMS:
+ {
+ gtk_combo_box_set_active(pWidget, -1);
+ gint nItems = 0;
+ do
+ {
+ nItems =
+ gtk_tree_model_iter_n_children(
+ gtk_combo_box_get_model(pWidget), NULL);
+ for (gint nI = 0; nI < nItems; ++nI)
+ gtk_combo_box_remove_text(pWidget, nI);
+ }
+ while (nItems);
+ }
+ break;
+ case ControlActions::SET_SELECT_ITEM:
+ {
+ sal_Int32 nPos=0;
+ rValue >>= nPos;
+ gtk_combo_box_set_active(pWidget, nPos);
+ }
+ break;
+ default:
+ OSL_TRACE("undocumented/unimplemented ControlAction for a list");
+ break;
+ }
+
+ //I think its best to make it insensitive unless there is the chance to
+ //actually select something from the list.
+ gint nItems = gtk_tree_model_iter_n_children(
+ gtk_combo_box_get_model(pWidget), NULL);
+ gtk_widget_set_sensitive(GTK_WIDGET(pWidget), nItems > 1 ? true : false);
+}
+
+uno::Any SalGtkFilePicker::HandleGetListValue(GtkComboBox *pWidget, sal_Int16 nControlAction) const
+{
+ uno::Any aAny;
+ switch (nControlAction)
+ {
+ case ControlActions::GET_ITEMS:
+ {
+ Sequence< OUString > aItemList;
+
+ GtkTreeModel *pTree = gtk_combo_box_get_model(pWidget);
+ GtkTreeIter iter;
+ if (gtk_tree_model_get_iter_first(pTree, &iter))
+ {
+ sal_Int32 nSize = gtk_tree_model_iter_n_children(
+ pTree, NULL);
+
+ aItemList.realloc(nSize);
+ for (sal_Int32 i=0; i < nSize; ++i)
+ {
+ gchar *item;
+ gtk_tree_model_get(gtk_combo_box_get_model(pWidget),
+ &iter, 0, &item, -1);
+ aItemList[i] = OUString(item, strlen(item), RTL_TEXTENCODING_UTF8);
+ g_free(item);
+ gtk_tree_model_iter_next(pTree, &iter);
+ }
+ }
+ aAny <<= aItemList;
+ }
+ break;
+ case ControlActions::GET_SELECTED_ITEM:
+ {
+ GtkTreeIter iter;
+ if (gtk_combo_box_get_active_iter(pWidget, &iter))
+ {
+ gchar *item;
+ gtk_tree_model_get(gtk_combo_box_get_model(pWidget),
+ &iter, 0, &item, -1);
+ OUString sItem(item, strlen(item), RTL_TEXTENCODING_UTF8);
+ aAny <<= sItem;
+ g_free(item);
+ }
+ }
+ break;
+ case ControlActions::GET_SELECTED_ITEM_INDEX:
+ {
+ gint nActive = gtk_combo_box_get_active(pWidget);
+ aAny <<= static_cast< sal_Int32 >(nActive);
+ }
+ break;
+ default:
+ OSL_TRACE("undocumented/unimplemented ControlAction for a list");
+ break;
+ }
+ return aAny;
+}
+
+void SAL_CALL SalGtkFilePicker::setValue( sal_Int16 nControlId, sal_Int16 nControlAction, const uno::Any& rValue )
+ throw( uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ OSL_ASSERT( m_pDialog != NULL );
+
+ OSL_TRACE( "SETTING VALUE %d", nControlAction );
+ GType tType;
+ GtkWidget *pWidget;
+
+ if( !( pWidget = getWidget( nControlId, &tType ) ) )
+ OSL_TRACE("enable unknown control %d", nControlId);
+ else if( tType == GTK_TYPE_TOGGLE_BUTTON )
+ {
+ sal_Bool bChecked = false;
+ rValue >>= bChecked;
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( pWidget ), bChecked );
+ }
+ else if( tType == GTK_TYPE_COMBO_BOX )
+ HandleSetListValue(GTK_COMBO_BOX(pWidget), nControlAction, rValue);
+ else
+ {
+ OSL_TRACE("Can't set value on button / list %d %d\n",
+ nControlId, nControlAction);
+ }
+}
+
+uno::Any SAL_CALL SalGtkFilePicker::getValue( sal_Int16 nControlId, sal_Int16 nControlAction )
+ throw( uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ OSL_ASSERT( m_pDialog != NULL );
+
+ uno::Any aRetval;
+
+ GType tType;
+ GtkWidget *pWidget;
+
+ if( !( pWidget = getWidget( nControlId, &tType ) ) )
+ OSL_TRACE("enable unknown control %d", nControlId);
+ else if( tType == GTK_TYPE_TOGGLE_BUTTON )
+ aRetval <<= (sal_Bool) gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( pWidget ) );
+ else if( tType == GTK_TYPE_COMBO_BOX )
+ aRetval = HandleGetListValue(GTK_COMBO_BOX(pWidget), nControlAction);
+ else
+ OSL_TRACE("Can't get value on button / list %d %d\n",
+ nControlId, nControlAction );
+
+ return aRetval;
+}
+
+void SAL_CALL SalGtkFilePicker::enableControl( sal_Int16 nControlId, sal_Bool bEnable )
+throw( uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ OSL_ASSERT( m_pDialog != NULL );
+
+ GtkWidget *pWidget;
+
+ if ( nControlId == ExtendedFilePickerElementIds::LISTBOX_FILTER_SELECTOR )
+ gtk_expander_set_expanded( GTK_EXPANDER( m_pFilterExpander ), bEnable );
+ else if( ( pWidget = getWidget( nControlId ) ) )
+ {
+ if( bEnable )
+ {
+ OSL_TRACE( "enable" );
+ gtk_widget_set_sensitive( pWidget, sal_True );
+ }
+ else
+ {
+ OSL_TRACE( "disable" );
+ gtk_widget_set_sensitive( pWidget, sal_False );
+ }
+ }
+ else
+ OSL_TRACE("enable unknown control %d", nControlId );
+}
+
+void SAL_CALL SalGtkFilePicker::setLabel( sal_Int16 nControlId, const ::rtl::OUString& rLabel )
+ throw( uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ OSL_ASSERT( m_pDialog != NULL );
+
+ GType tType;
+ GtkWidget *pWidget;
+
+ if( !( pWidget = getWidget( nControlId, &tType ) ) )
+ {
+ OSL_TRACE("Set label on unknown control %d", nControlId);
+ return;
+ }
+
+ OString aTxt = OUStringToOString( rLabel.replace('~', '_'), RTL_TEXTENCODING_UTF8 );
+ if (nControlId == ExtendedFilePickerElementIds::PUSHBUTTON_PLAY)
+ {
+#ifdef GTK_STOCK_MEDIA_PLAY
+ if (!msPlayLabel.getLength())
+ msPlayLabel = rLabel;
+ if (msPlayLabel == rLabel)
+ gtk_button_set_label(GTK_BUTTON(pWidget), GTK_STOCK_MEDIA_PLAY);
+ else
+ gtk_button_set_label(GTK_BUTTON(pWidget), GTK_STOCK_MEDIA_STOP);
+#else
+ gtk_button_set_label(GTK_BUTTON(pWidget), aTxt.getStr());
+#endif
+ }
+ else if( tType == GTK_TYPE_TOGGLE_BUTTON || tType == GTK_TYPE_BUTTON || tType == GTK_TYPE_LABEL )
+ g_object_set( pWidget, "label", aTxt.getStr(),
+ "use_underline", sal_True, (char *)NULL );
+ else
+ OSL_TRACE("Can't set label on list");
+}
+
+rtl::OUString SAL_CALL SalGtkFilePicker::getLabel( sal_Int16 nControlId )
+ throw( uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ OSL_ASSERT( m_pDialog != NULL );
+
+ GType tType;
+ OString aTxt;
+ GtkWidget *pWidget;
+
+ if( !( pWidget = getWidget( nControlId, &tType ) ) )
+ OSL_TRACE("Get label on unknown control %d", nControlId);
+ else if( tType == GTK_TYPE_TOGGLE_BUTTON || tType == GTK_TYPE_BUTTON || tType == GTK_TYPE_LABEL )
+ aTxt = gtk_button_get_label( GTK_BUTTON( pWidget ) );
+ else
+ OSL_TRACE("Can't get label on list");
+
+ return OStringToOUString( aTxt, RTL_TEXTENCODING_UTF8 );
+}
+
+//------------------------------------------------------------------------------------
+// XFilePreview functions
+//------------------------------------------------------------------------------------
+
+uno::Sequence<sal_Int16> SAL_CALL SalGtkFilePicker::getSupportedImageFormats() throw( uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ OSL_ASSERT( m_pDialog != NULL );
+
+ // TODO return m_pImpl->getSupportedImageFormats();
+ return uno::Sequence<sal_Int16>();
+}
+
+sal_Int32 SAL_CALL SalGtkFilePicker::getTargetColorDepth() throw( uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ OSL_ASSERT( m_pDialog != NULL );
+
+ // TODO return m_pImpl->getTargetColorDepth();
+ return 0;
+}
+
+sal_Int32 SAL_CALL SalGtkFilePicker::getAvailableWidth() throw( uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ OSL_ASSERT( m_pDialog != NULL );
+
+ return m_PreviewImageWidth;
+}
+
+sal_Int32 SAL_CALL SalGtkFilePicker::getAvailableHeight() throw( uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ OSL_ASSERT( m_pDialog != NULL );
+
+ return m_PreviewImageHeight;
+}
+
+void SAL_CALL SalGtkFilePicker::setImage( sal_Int16 /*aImageFormat*/, const uno::Any& /*aImage*/ )
+ throw( lang::IllegalArgumentException, uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ OSL_ASSERT( m_pDialog != NULL );
+
+ // TODO m_pImpl->setImage( aImageFormat, aImage );
+}
+
+void SalGtkFilePicker::implChangeType( GtkTreeSelection *selection )
+{
+ CResourceProvider aResProvider;
+ OUString aLabel = aResProvider.getResString( FILE_PICKER_FILE_TYPE );
+
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ gchar *title;
+ gtk_tree_model_get (model, &iter, 2, &title, -1);
+ aLabel += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( ": " ));
+ aLabel += rtl::OUString( title, strlen(title), RTL_TEXTENCODING_UTF8 );
+ g_free (title);
+ }
+ gtk_expander_set_label (GTK_EXPANDER (m_pFilterExpander),
+ OUStringToOString( aLabel, RTL_TEXTENCODING_UTF8 ).getStr());
+ FilePickerEvent evt;
+ evt.ElementId = LISTBOX_FILTER;
+ impl_controlStateChanged( evt );
+}
+
+void SalGtkFilePicker::type_changed_cb( GtkTreeSelection *selection, SalGtkFilePicker *pobjFP )
+{
+ pobjFP->implChangeType(selection);
+}
+
+void SalGtkFilePicker::unselect_type()
+{
+ gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(GTK_TREE_VIEW(m_pFilterView)));
+}
+
+void SalGtkFilePicker::expander_changed_cb( GtkExpander *expander, SalGtkFilePicker *pobjFP )
+{
+ if (gtk_expander_get_expanded(expander))
+ pobjFP->unselect_type();
+}
+
+void SalGtkFilePicker::filter_changed_cb( GtkFileChooser *, GParamSpec *,
+ SalGtkFilePicker *pobjFP )
+{
+ FilePickerEvent evt;
+ evt.ElementId = LISTBOX_FILTER;
+ OSL_TRACE( "filter_changed, isn't it great %x", pobjFP );
+ pobjFP->impl_controlStateChanged( evt );
+}
+
+void SalGtkFilePicker::folder_changed_cb( GtkFileChooser *, SalGtkFilePicker *pobjFP )
+{
+ FilePickerEvent evt;
+ OSL_TRACE( "folder_changed, isn't it great %x", pobjFP );
+ pobjFP->impl_directoryChanged( evt );
+}
+
+void SalGtkFilePicker::selection_changed_cb( GtkFileChooser *, SalGtkFilePicker *pobjFP )
+{
+ FilePickerEvent evt;
+ OSL_TRACE( "selection_changed, isn't it great %x", pobjFP );
+ pobjFP->impl_fileSelectionChanged( evt );
+}
+
+void SalGtkFilePicker::update_preview_cb( GtkFileChooser *file_chooser, SalGtkFilePicker* pobjFP )
+{
+ GtkWidget *preview;
+ char *filename;
+ GdkPixbuf *pixbuf;
+ gboolean have_preview = sal_False;
+
+ preview = pobjFP->m_pPreview;
+ filename = gtk_file_chooser_get_preview_filename( file_chooser );
+
+ if( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( pobjFP->m_pToggles[PREVIEW] ) ) && g_file_test( filename, G_FILE_TEST_IS_REGULAR ) )
+ {
+ pixbuf = gdk_pixbuf_new_from_file_at_size(
+ filename,
+ pobjFP->m_PreviewImageWidth,
+ pobjFP->m_PreviewImageHeight, NULL );
+
+ have_preview = ( pixbuf != NULL );
+
+ gtk_image_set_from_pixbuf( GTK_IMAGE( preview ), pixbuf );
+ if( pixbuf )
+ gdk_pixbuf_unref( pixbuf );
+
+ }
+
+ gtk_file_chooser_set_preview_widget_active( file_chooser, have_preview );
+
+ if( filename )
+ g_free( filename );
+}
+
+sal_Bool SAL_CALL SalGtkFilePicker::setShowState( sal_Bool bShowState ) throw( uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ OSL_ASSERT( m_pDialog != NULL );
+
+ // TODO return m_pImpl->setShowState( bShowState );
+ if( bShowState != mbPreviewState )
+ {
+ if( bShowState )
+ {
+ // Show
+ if( !mHID_Preview )
+ {
+ mHID_Preview = g_signal_connect(
+ GTK_FILE_CHOOSER( m_pDialog ), "update-preview",
+ G_CALLBACK( update_preview_cb ), ( gpointer )this );
+ }
+ gtk_widget_show( m_pPreview );
+ }
+ else
+ {
+ // Hide
+ gtk_widget_hide( m_pPreview );
+ }
+
+ // also emit the signal
+ g_signal_emit_by_name( GTK_OBJECT( m_pDialog ), "update-preview" );
+
+ mbPreviewState = bShowState;
+ }
+ return true;
+}
+
+sal_Bool SAL_CALL SalGtkFilePicker::getShowState() throw( uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ OSL_ASSERT( m_pDialog != NULL );
+
+ return mbPreviewState;
+}
+
+//------------------------------------------------------------------------------------
+// XInitialization
+//------------------------------------------------------------------------------------
+
+void SAL_CALL SalGtkFilePicker::initialize( const uno::Sequence<uno::Any>& aArguments )
+ throw( uno::Exception, uno::RuntimeException )
+{
+ // parameter checking
+ uno::Any aAny;
+ if( 0 == aArguments.getLength() )
+ throw lang::IllegalArgumentException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "no arguments" )),
+ static_cast<XFilePicker2*>( this ), 1 );
+
+ aAny = aArguments[0];
+
+ if( ( aAny.getValueType() != ::getCppuType( ( sal_Int16* )0 ) ) &&
+ (aAny.getValueType() != ::getCppuType( ( sal_Int8* )0 ) ) )
+ throw lang::IllegalArgumentException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "invalid argument type" )),
+ static_cast<XFilePicker2*>( this ), 1 );
+
+ sal_Int16 templateId = -1;
+ aAny >>= templateId;
+
+ GtkFileChooserAction eAction = GTK_FILE_CHOOSER_ACTION_OPEN;
+ const gchar *first_button_text = GTK_STOCK_OPEN;
+
+ SolarMutexGuard g;
+
+ // TODO: extract full semantic from
+ // svtools/source/filepicker/filepicker.cxx (getWinBits)
+ switch( templateId )
+ {
+ case FILEOPEN_SIMPLE:
+ eAction = GTK_FILE_CHOOSER_ACTION_OPEN;
+ first_button_text = GTK_STOCK_OPEN;
+ OSL_TRACE( "3all true" );
+ break;
+ case FILESAVE_SIMPLE:
+ eAction = GTK_FILE_CHOOSER_ACTION_SAVE;
+ first_button_text = GTK_STOCK_SAVE;
+ OSL_TRACE( "2all true" );
+ break;
+ case FILESAVE_AUTOEXTENSION_PASSWORD:
+ eAction = GTK_FILE_CHOOSER_ACTION_SAVE;
+ first_button_text = GTK_STOCK_SAVE;
+ mbToggleVisibility[PASSWORD] = true;
+ OSL_TRACE( "1all true" );
+ // TODO
+ break;
+ case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
+ eAction = GTK_FILE_CHOOSER_ACTION_SAVE;
+ first_button_text = GTK_STOCK_SAVE;
+ mbToggleVisibility[PASSWORD] = true;
+ mbToggleVisibility[FILTEROPTIONS] = true;
+ OSL_TRACE( "4all true" );
+ // TODO
+ break;
+ case FILESAVE_AUTOEXTENSION_SELECTION:
+ eAction = GTK_FILE_CHOOSER_ACTION_SAVE; // SELECT_FOLDER ?
+ first_button_text = GTK_STOCK_SAVE;
+ mbToggleVisibility[SELECTION] = true;
+ OSL_TRACE( "5all true" );
+ // TODO
+ break;
+ case FILESAVE_AUTOEXTENSION_TEMPLATE:
+ eAction = GTK_FILE_CHOOSER_ACTION_SAVE;
+ first_button_text = GTK_STOCK_SAVE;
+ mbListVisibility[TEMPLATE] = true;
+ OSL_TRACE( "6all true" );
+ // TODO
+ break;
+ case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
+ eAction = GTK_FILE_CHOOSER_ACTION_OPEN;
+ first_button_text = GTK_STOCK_OPEN;
+ mbToggleVisibility[LINK] = true;
+ mbToggleVisibility[PREVIEW] = true;
+ mbListVisibility[IMAGE_TEMPLATE] = true;
+ // TODO
+ break;
+ case FILEOPEN_PLAY:
+ eAction = GTK_FILE_CHOOSER_ACTION_OPEN;
+ first_button_text = GTK_STOCK_OPEN;
+ mbButtonVisibility[PLAY] = true;
+ // TODO
+ break;
+ case FILEOPEN_READONLY_VERSION:
+ eAction = GTK_FILE_CHOOSER_ACTION_OPEN;
+ first_button_text = GTK_STOCK_OPEN;
+ mbToggleVisibility[READONLY] = true;
+ mbListVisibility[VERSION] = true;
+ break;
+ case FILEOPEN_LINK_PREVIEW:
+ eAction = GTK_FILE_CHOOSER_ACTION_OPEN;
+ first_button_text = GTK_STOCK_OPEN;
+ mbToggleVisibility[LINK] = true;
+ mbToggleVisibility[PREVIEW] = true;
+ // TODO
+ break;
+ case FILESAVE_AUTOEXTENSION:
+ eAction = GTK_FILE_CHOOSER_ACTION_SAVE;
+ first_button_text = GTK_STOCK_SAVE;
+ OSL_TRACE( "7all true" );
+ // TODO
+ break;
+ default:
+ throw lang::IllegalArgumentException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Unknown template" )),
+ static_cast< XFilePicker2* >( this ),
+ 1 );
+ }
+
+ if( GTK_FILE_CHOOSER_ACTION_SAVE == eAction )
+ {
+ CResourceProvider aResProvider;
+ OUString aFilePickerTitle(aResProvider.getResString( FILE_PICKER_TITLE_SAVE ));
+ gtk_window_set_title ( GTK_WINDOW( m_pDialog ),
+ OUStringToOString( aFilePickerTitle, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+
+ gtk_file_chooser_set_action( GTK_FILE_CHOOSER( m_pDialog ), eAction);
+ dialog_remove_buttons( GTK_DIALOG( m_pDialog ) );
+ gtk_dialog_add_button( GTK_DIALOG( m_pDialog ), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL );
+ for( int nTVIndex = 0; nTVIndex < BUTTON_LAST; nTVIndex++ )
+ {
+ if( mbButtonVisibility[nTVIndex] )
+ {
+#ifdef GTK_STOCK_MEDIA_PLAY
+ m_pButtons[ nTVIndex ] = gtk_dialog_add_button( GTK_DIALOG( m_pDialog ), GTK_STOCK_MEDIA_PLAY, 1 );
+#else
+ CResourceProvider aResProvider;
+ OString aPlay = OUStringToOString( aResProvider.getResString( PUSHBUTTON_PLAY ), RTL_TEXTENCODING_UTF8 );
+ m_pButtons[ nTVIndex ] = gtk_dialog_add_button( GTK_DIALOG( m_pDialog ), aPlay.getStr(), 1 );
+#endif
+ }
+ }
+ gtk_dialog_add_button( GTK_DIALOG( m_pDialog ), first_button_text, GTK_RESPONSE_ACCEPT );
+
+ gtk_dialog_set_default_response( GTK_DIALOG (m_pDialog), GTK_RESPONSE_ACCEPT );
+
+ // Setup special flags
+ for( int nTVIndex = 0; nTVIndex < TOGGLE_LAST; nTVIndex++ )
+ {
+ if( mbToggleVisibility[nTVIndex] )
+ gtk_widget_show( m_pToggles[ nTVIndex ] );
+ }
+
+ for( int nTVIndex = 0; nTVIndex < LIST_LAST; nTVIndex++ )
+ {
+ if( mbListVisibility[nTVIndex] )
+ {
+ gtk_widget_set_sensitive( m_pLists[ nTVIndex ], false );
+ gtk_widget_show( m_pLists[ nTVIndex ] );
+ gtk_widget_show( m_pListLabels[ nTVIndex ] );
+ gtk_widget_show( m_pAligns[ nTVIndex ] );
+ gtk_widget_show( m_pHBoxs[ nTVIndex ] );
+ }
+ }
+}
+
+void SalGtkFilePicker::preview_toggled_cb( GtkObject *cb, SalGtkFilePicker* pobjFP )
+{
+ if( pobjFP->mbToggleVisibility[PREVIEW] )
+ pobjFP->setShowState( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( cb ) ) );
+}
+
+//------------------------------------------------------------------------------------
+// XCancellable
+//------------------------------------------------------------------------------------
+
+void SAL_CALL SalGtkFilePicker::cancel() throw( uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ OSL_ASSERT( m_pDialog != NULL );
+
+ // TODO m_pImpl->cancel();
+}
+
+// -------------------------------------------------
+// XServiceInfo
+// -------------------------------------------------
+
+rtl::OUString SAL_CALL SalGtkFilePicker::getImplementationName()
+ throw( uno::RuntimeException )
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( FILE_PICKER_IMPL_NAME ));
+}
+
+// -------------------------------------------------
+// XServiceInfo
+// -------------------------------------------------
+
+sal_Bool SAL_CALL SalGtkFilePicker::supportsService( const rtl::OUString& ServiceName )
+ throw( uno::RuntimeException )
+{
+ uno::Sequence <rtl::OUString> SupportedServicesNames = FilePicker_getSupportedServiceNames();
+
+ for( sal_Int32 n = SupportedServicesNames.getLength(); n--; )
+ if( SupportedServicesNames[n].compareTo( ServiceName ) == 0)
+ return sal_True;
+
+ return sal_False;
+}
+
+// -------------------------------------------------
+// XServiceInfo
+// -------------------------------------------------
+
+uno::Sequence<rtl::OUString> SAL_CALL SalGtkFilePicker::getSupportedServiceNames()
+ throw( uno::RuntimeException )
+{
+ return FilePicker_getSupportedServiceNames();
+}
+
+
+//--------------------------------------------------
+// Misc
+//-------------------------------------------------
+void SalGtkFilePicker::SetCurFilter( const OUString& rFilter )
+{
+ // Get all the filters already added
+ GSList *filters = gtk_file_chooser_list_filters ( GTK_FILE_CHOOSER( m_pDialog ) );
+ bool bFound = false;
+
+ for( GSList *iter = filters; !bFound && iter; iter = iter->next )
+ {
+ GtkFileFilter* pFilter = reinterpret_cast<GtkFileFilter *>( iter->data );
+ G_CONST_RETURN gchar * filtername = gtk_file_filter_get_name( pFilter );
+ OUString sFilterName( filtername, strlen( filtername ), RTL_TEXTENCODING_UTF8 );
+
+ OUString aShrunkName = shrinkFilterName( rFilter );
+ if( aShrunkName.equals( sFilterName) )
+ {
+ OSL_TRACE( "actually setting %s", filtername );
+ gtk_file_chooser_set_filter( GTK_FILE_CHOOSER( m_pDialog ), pFilter );
+ bFound = true;
+ }
+ }
+
+ g_slist_free( filters );
+}
+
+extern "C"
+{
+static gboolean
+case_insensitive_filter (const GtkFileFilterInfo *filter_info, gpointer data)
+{
+ gboolean bRetval = sal_False;
+ const char *pFilter = (const char *) data;
+
+ g_return_val_if_fail( data != NULL, sal_False );
+ g_return_val_if_fail( filter_info != NULL, sal_False );
+
+ if( !filter_info->uri )
+ return sal_False;
+
+ const char *pExtn = strrchr( filter_info->uri, '.' );
+ if( !pExtn )
+ return sal_False;
+ pExtn++;
+
+ if( !g_ascii_strcasecmp( pFilter, pExtn ) )
+ bRetval = sal_True;
+
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "'%s' match extn '%s' vs '%s' yeilds %d\n",
+ filter_info->uri, pExtn, pFilter, bRetval );
+#endif
+
+ return bRetval;
+}
+}
+
+GtkFileFilter* SalGtkFilePicker::implAddFilter( const OUString& rFilter, const OUString& rType )
+{
+ GtkFileFilter *filter = gtk_file_filter_new();
+
+ OUString aShrunkName = shrinkFilterName( rFilter );
+ OString aFilterName = rtl::OUStringToOString( aShrunkName, RTL_TEXTENCODING_UTF8 );
+ gtk_file_filter_set_name( filter, aFilterName.getStr() );
+
+ static const OUString aStarDot(RTL_CONSTASCII_USTRINGPARAM( "*." ));
+ OUString aTokens;
+
+ bool bAllGlob = !rType.compareToAscii( "*.*" ) || !rType.compareToAscii( "*" );
+ if (bAllGlob)
+ gtk_file_filter_add_pattern( filter, "*" );
+ else
+ {
+ sal_Int32 nIndex = 0;
+ rtl::OUString aToken;
+ do
+ {
+ aToken = rType.getToken( 0, ';', nIndex );
+ // Assume all have the "*.<extn>" syntax
+ aToken = aToken.copy( aToken.lastIndexOf( aStarDot ) + 2 );
+ if (aToken.getLength())
+ {
+ if (aTokens.getLength())
+ aTokens += OUString(RTL_CONSTASCII_USTRINGPARAM(","));
+ aTokens = aTokens += aToken;
+ gtk_file_filter_add_custom (filter, GTK_FILE_FILTER_URI,
+ case_insensitive_filter,
+ g_strdup( rtl::OUStringToOString(aToken, RTL_TEXTENCODING_UTF8).getStr() ),
+ (GDestroyNotify) g_free );
+
+ OSL_TRACE( "fustering with %s", rtl::OUStringToOString( aToken, RTL_TEXTENCODING_UTF8 ).getStr());
+ }
+#if OSL_DEBUG_LEVEL > 0
+ else
+ {
+ g_warning( "Duff filter token '%s'\n",
+ rtl::OUStringToOString(
+ rType.getToken( 0, ';', nIndex ), RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+#endif
+ }
+ while( nIndex >= 0 );
+ }
+
+ gtk_file_chooser_add_filter( GTK_FILE_CHOOSER( m_pDialog ), filter );
+
+ if (!bAllGlob)
+ {
+ GtkTreeIter iter;
+ gtk_list_store_append (m_pFilterStore, &iter);
+ gtk_list_store_set (m_pFilterStore, &iter,
+ 0, OUStringToOString(shrinkFilterName( rFilter, true ), RTL_TEXTENCODING_UTF8).getStr(),
+ 1, OUStringToOString(aTokens, RTL_TEXTENCODING_UTF8).getStr(),
+ 2, aFilterName.getStr(),
+ 3, OUStringToOString(rType, RTL_TEXTENCODING_UTF8).getStr(),
+ -1);
+ }
+ return filter;
+}
+
+void SalGtkFilePicker::implAddFilterGroup( const OUString& /*_rFilter*/, const Sequence< StringPair >& _rFilters )
+{
+ // Gtk+ has no filter group concept I think so ...
+ // implAddFilter( _rFilter, String() );
+ const StringPair* pSubFilters = _rFilters.getConstArray();
+ const StringPair* pSubFiltersEnd = pSubFilters + _rFilters.getLength();
+ for( ; pSubFilters != pSubFiltersEnd; ++pSubFilters )
+ implAddFilter( pSubFilters->First, pSubFilters->Second );
+}
+
+void SalGtkFilePicker::SetFilters()
+{
+ if (!m_aInitialFilter.getLength())
+ m_aInitialFilter = m_aCurrentFilter;
+
+ rtl::OUString sPseudoFilter;
+ if( GTK_FILE_CHOOSER_ACTION_SAVE == gtk_file_chooser_get_action( GTK_FILE_CHOOSER( m_pDialog ) ) )
+ {
+ std::set<OUString> aAllFormats;
+ if( m_pFilterList && !m_pFilterList->empty() )
+ {
+ for ( FilterList::iterator aListIter = m_pFilterList->begin();
+ aListIter != m_pFilterList->end();
+ ++aListIter
+ )
+ {
+ if( aListIter->hasSubFilters() )
+ { // it's a filter group
+ UnoFilterList aSubFilters;
+ aListIter->getSubFilters( aSubFilters );
+ const StringPair* pSubFilters = aSubFilters.getConstArray();
+ const StringPair* pSubFiltersEnd = pSubFilters + aSubFilters.getLength();
+ for( ; pSubFilters != pSubFiltersEnd; ++pSubFilters )
+ aAllFormats.insert(pSubFilters->Second);
+ }
+ else
+ aAllFormats.insert(aListIter->getFilter());
+ }
+ }
+ if (aAllFormats.size() > 1)
+ {
+ rtl::OUString sAllFilter;
+ std::set<OUString>::const_iterator aEnd = aAllFormats.end();
+ for (std::set<OUString>::const_iterator aIter = aAllFormats.begin(); aIter != aEnd; ++aIter)
+ {
+ if (sAllFilter.getLength())
+ sAllFilter += OUString(sal_Unicode(';'));
+ sAllFilter += *aIter;
+ }
+ CResourceProvider aResProvider;
+ sPseudoFilter = aResProvider.getResString(FILE_PICKER_ALLFORMATS);
+ m_pPseudoFilter = implAddFilter( sPseudoFilter, sAllFilter );
+ }
+ }
+
+ if( m_pFilterList && !m_pFilterList->empty() )
+ {
+ for ( FilterList::iterator aListIter = m_pFilterList->begin();
+ aListIter != m_pFilterList->end();
+ ++aListIter
+ )
+ {
+ if( aListIter->hasSubFilters() )
+ { // it's a filter group
+
+ UnoFilterList aSubFilters;
+ aListIter->getSubFilters( aSubFilters );
+
+ implAddFilterGroup( aListIter->getTitle(), aSubFilters );
+ }
+ else
+ {
+ // it's a single filter
+
+ implAddFilter( aListIter->getTitle(), aListIter->getFilter() );
+ }
+ }
+ }
+
+ if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(m_pFilterStore), NULL)) //If m_pFilterStore is not empty
+ gtk_widget_show( m_pFilterExpander );
+ else
+ gtk_widget_hide( m_pFilterExpander );
+
+ // set the default filter
+ if (sPseudoFilter.getLength())
+ SetCurFilter( sPseudoFilter );
+ else if(m_aCurrentFilter.getLength())
+ SetCurFilter( m_aCurrentFilter );
+
+ OSL_TRACE( "end setting filters");
+}
+
+SalGtkFilePicker::~SalGtkFilePicker()
+{
+ SolarMutexGuard g;
+
+ int i;
+
+ for( i = 0; i < TOGGLE_LAST; i++ )
+ gtk_widget_destroy( m_pToggles[i] );
+
+ for( i = 0; i < LIST_LAST; i++ )
+ {
+ gtk_widget_destroy( m_pListLabels[i] );
+ gtk_widget_destroy( m_pAligns[i] ); //m_pAligns[i] owns m_pLists[i]
+ gtk_widget_destroy( m_pHBoxs[i] );
+ }
+
+ delete m_pFilterList;
+
+ gtk_widget_destroy( m_pVBox );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk/fpicker/SalGtkFilePicker.hxx b/vcl/unx/gtk/fpicker/SalGtkFilePicker.hxx
new file mode 100644
index 000000000000..832e9445c342
--- /dev/null
+++ b/vcl/unx/gtk/fpicker/SalGtkFilePicker.hxx
@@ -0,0 +1,356 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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 _SALGTKFILEPICKER_HXX_
+#define _SALGTKFILEPICKER_HXX_
+
+//_______________________________________________________________________________________________________________________
+// includes of other projects
+//_______________________________________________________________________________________________________________________
+
+#include <cppuhelper/compbase10.hxx>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/ui/dialogs/XFilePickerNotifier.hpp>
+#include <com/sun/star/ui/dialogs/XFilterManager.hpp>
+#include <com/sun/star/ui/dialogs/XFilterGroupManager.hpp>
+#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
+#include <com/sun/star/ui/dialogs/XFilePreview.hpp>
+#include <com/sun/star/beans/StringPair.hpp>
+
+#include "SalGtkPicker.hxx"
+
+#include <memory>
+
+#include <rtl/ustring.hxx>
+
+#include <list>
+
+//----------------------------------------------------------
+// Implementation class for the XFilePicker Interface
+//----------------------------------------------------------
+
+//----------------------------------------------------------
+// forward declarations
+//----------------------------------------------------------
+
+using ::rtl::OUString;
+using ::rtl::OString;
+struct FilterEntry;
+struct ElementEntry_Impl;
+
+typedef ::std::list < FilterEntry > FilterList;
+typedef ::std::list < ElementEntry_Impl > ElementList;
+typedef ::com::sun::star::beans::StringPair UnoFilterEntry;
+typedef ::com::sun::star::uno::Sequence< UnoFilterEntry > UnoFilterList; // can be transported more effectively
+
+
+//----------------------------------------------------------
+// class declaration
+//----------------------------------------------------------
+
+class SalGtkFilePicker :
+ public SalGtkPicker,
+ public cppu::WeakComponentImplHelper10<
+ ::com::sun::star::ui::dialogs::XFilterManager,
+ ::com::sun::star::ui::dialogs::XFilterGroupManager,
+ ::com::sun::star::ui::dialogs::XFilePickerControlAccess,
+ ::com::sun::star::ui::dialogs::XFilePickerNotifier,
+ ::com::sun::star::ui::dialogs::XFilePreview,
+ ::com::sun::star::ui::dialogs::XFilePicker2,
+ ::com::sun::star::lang::XInitialization,
+ ::com::sun::star::util::XCancellable,
+ ::com::sun::star::lang::XEventListener,
+ ::com::sun::star::lang::XServiceInfo >
+{
+ public:
+
+ // constructor
+ SalGtkFilePicker( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceMgr );
+
+ //------------------------------------------------------------------------------------
+ // XFilePickerNotifier
+ //------------------------------------------------------------------------------------
+
+ virtual void SAL_CALL addFilePickerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XFilePickerListener >& xListener )
+ throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL removeFilePickerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XFilePickerListener >& xListener )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ //------------------------------------------------------------------------------------
+ // XExecutableDialog functions
+ //------------------------------------------------------------------------------------
+
+ virtual void SAL_CALL setTitle( const ::rtl::OUString& aTitle )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int16 SAL_CALL execute()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ //------------------------------------------------------------------------------------
+ // XFilePicker functions
+ //------------------------------------------------------------------------------------
+
+ virtual void SAL_CALL setMultiSelectionMode( sal_Bool bMode )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL setDefaultName( const ::rtl::OUString& aName )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL setDisplayDirectory( const ::rtl::OUString& aDirectory )
+ throw( com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual ::rtl::OUString SAL_CALL getDisplayDirectory( )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getFiles( )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ //------------------------------------------------------------------------------------
+ // XFilePicker2 functions
+ //------------------------------------------------------------------------------------
+
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSelectedFiles()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ //------------------------------------------------------------------------------------
+ // XFilterManager functions
+ //------------------------------------------------------------------------------------
+
+ virtual void SAL_CALL appendFilter( const ::rtl::OUString& aTitle, const ::rtl::OUString& aFilter )
+ throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL setCurrentFilter( const ::rtl::OUString& aTitle )
+ throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException );
+
+ virtual ::rtl::OUString SAL_CALL getCurrentFilter( )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ //------------------------------------------------------------------------------------
+ // XFilterGroupManager functions
+ //------------------------------------------------------------------------------------
+
+ virtual void SAL_CALL appendFilterGroup( const ::rtl::OUString& sGroupTitle, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair >& aFilters )
+ throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+
+ //------------------------------------------------------------------------------------
+ // XFilePickerControlAccess functions
+ //------------------------------------------------------------------------------------
+
+ virtual void SAL_CALL setValue( sal_Int16 nControlId, sal_Int16 nControlAction, const ::com::sun::star::uno::Any& aValue )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Any SAL_CALL getValue( sal_Int16 aControlId, sal_Int16 aControlAction )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL enableControl( sal_Int16 nControlId, sal_Bool bEnable )
+ throw(::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL setLabel( sal_Int16 nControlId, const ::rtl::OUString& aLabel )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::rtl::OUString SAL_CALL getLabel( sal_Int16 nControlId )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ //------------------------------------------------
+ // XFilePreview
+ //------------------------------------------------
+
+ virtual ::com::sun::star::uno::Sequence< sal_Int16 > SAL_CALL getSupportedImageFormats( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getTargetColorDepth( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getAvailableWidth( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getAvailableHeight( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL setImage( sal_Int16 aImageFormat, const ::com::sun::star::uno::Any& aImage )
+ throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL setShowState( sal_Bool bShowState )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL getShowState( )
+ 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, ::com::sun::star::uno::RuntimeException);
+
+ //------------------------------------------------
+ // XCancellable
+ //------------------------------------------------
+
+ virtual void SAL_CALL cancel( )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ //------------------------------------------------
+ // XEventListener
+ //------------------------------------------------
+
+ using cppu::WeakComponentImplHelperBase::disposing;
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& aEvent )
+ throw(::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);
+
+ //------------------------------------------------------------------------------------
+ // FilePicker Event functions
+ //------------------------------------------------------------------------------------
+
+ private:
+ // prevent copy and assignment
+ SalGtkFilePicker( const SalGtkFilePicker& );
+ SalGtkFilePicker& operator=( const SalGtkFilePicker& );
+
+ sal_Bool FilterNameExists( const ::rtl::OUString& rTitle );
+ sal_Bool FilterNameExists( const UnoFilterList& _rGroupedFilters );
+
+ void ensureFilterList( const ::rtl::OUString& _rInitialCurrentFilter );
+
+ // to instanciate own services
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xServiceMgr;
+
+ void impl_fileSelectionChanged( ::com::sun::star::ui::dialogs::FilePickerEvent aEvent );
+ void impl_directoryChanged( ::com::sun::star::ui::dialogs::FilePickerEvent aEvent );
+ void impl_controlStateChanged( ::com::sun::star::ui::dialogs::FilePickerEvent aEvent );
+
+
+ private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XFilePickerListener >
+ m_xListener;
+ ::rtl::OUString msPlayLabel;
+ FilterList *m_pFilterList;
+ GtkWidget *m_pVBox;
+
+ GtkWidget *m_pFilterExpander;
+ GtkWidget *m_pFilterView;
+ GtkListStore *m_pFilterStore;
+
+ enum {
+ AUTOEXTENSION,
+ PASSWORD,
+ FILTEROPTIONS,
+ READONLY,
+ LINK,
+ PREVIEW,
+ SELECTION,
+ TOGGLE_LAST
+ };
+
+ GtkWidget *m_pToggles[ TOGGLE_LAST ];
+
+ bool mbToggleVisibility[TOGGLE_LAST];
+ bool mbToggleChecked[TOGGLE_LAST];
+
+ static const rtl::OString m_ToggleLabels[TOGGLE_LAST];
+
+ enum {
+ PLAY,
+ BUTTON_LAST };
+
+ GtkWidget *m_pButtons[ BUTTON_LAST ];
+
+ enum {
+ VERSION,
+ TEMPLATE,
+ IMAGE_TEMPLATE,
+ LIST_LAST
+ };
+
+ GtkWidget *m_pHBoxs[ LIST_LAST ];
+ GtkWidget *m_pAligns[ LIST_LAST ];
+ GtkWidget *m_pLists[ LIST_LAST ];
+ GtkWidget *m_pListLabels[ LIST_LAST ];
+ bool mbListVisibility[ LIST_LAST ];
+ bool mbButtonVisibility[ BUTTON_LAST ];
+ gulong mnHID_FolderChange;
+ gulong mnHID_SelectionChange;
+
+ ::rtl::OUString m_aCurrentFilter;
+ ::rtl::OUString m_aInitialFilter;
+
+ bool bVersionWidthUnset;
+ sal_Bool mbPreviewState;
+ gulong mHID_Preview;
+ GtkWidget* m_pPreview;
+ GtkFileFilter* m_pPseudoFilter;
+ sal_Int32 m_PreviewImageWidth;
+ sal_Int32 m_PreviewImageHeight;
+
+ GtkWidget *getWidget( sal_Int16 nControlId, GType *pType = NULL);
+
+ void SetCurFilter( const OUString& rFilter );
+ void SetFilters();
+ void UpdateFilterfromUI();
+
+ void implChangeType( GtkTreeSelection *selection );
+ GtkFileFilter * implAddFilter( const OUString& rFilter, const OUString& rType );
+ void implAddFilterGroup( const OUString& rFilter,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair>& _rFilters );
+ void updateCurrentFilterFromName(const gchar* filtername);
+ void unselect_type();
+ void InitialMapping();
+
+ void HandleSetListValue(GtkComboBox *pWidget, sal_Int16 nControlAction,
+ const ::com::sun::star::uno::Any& rValue);
+ ::com::sun::star::uno::Any HandleGetListValue(GtkComboBox *pWidget, sal_Int16 nControlAction) const;
+
+ static void expander_changed_cb( GtkExpander *expander, SalGtkFilePicker *pobjFP );
+ static void preview_toggled_cb (GtkObject *cb, SalGtkFilePicker *pobjFP);
+ static void filter_changed_cb (GtkFileChooser *file_chooser, GParamSpec *pspec, SalGtkFilePicker *pobjFP);
+ static void type_changed_cb( GtkTreeSelection *selection, SalGtkFilePicker *pobjFP );
+ static void folder_changed_cb (GtkFileChooser *file_chooser, SalGtkFilePicker *pobjFP);
+ static void selection_changed_cb (GtkFileChooser *file_chooser, SalGtkFilePicker *pobjFP);
+ static void update_preview_cb (GtkFileChooser *file_chooser, SalGtkFilePicker *pobjFP);
+ static void dialog_mapped_cb(GtkWidget *widget, SalGtkFilePicker *pobjFP);
+ public:
+ virtual ~SalGtkFilePicker();
+
+};
+#endif // _SALGTKFILEPICKER_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk/fpicker/SalGtkFolderPicker.cxx b/vcl/unx/gtk/fpicker/SalGtkFolderPicker.cxx
new file mode 100644
index 000000000000..52d9c78ba1e0
--- /dev/null
+++ b/vcl/unx/gtk/fpicker/SalGtkFolderPicker.cxx
@@ -0,0 +1,253 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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_fpicker.hxx"
+
+#ifdef AIX
+#define _LINUX_SOURCE_COMPAT
+#include <sys/timer.h>
+#undef _LINUX_SOURCE_COMPAT
+#endif
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
+#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
+#include <osl/diagnose.h>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <FPServiceInfo.hxx>
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include "SalGtkFolderPicker.hxx"
+#include "resourceprovider.hxx"
+
+#include <string.h>
+
+//------------------------------------------------------------------------
+// namespace directives
+//------------------------------------------------------------------------
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+
+//------------------------------------------------------------------------
+// helper functions
+//------------------------------------------------------------------------
+
+namespace
+{
+ // controling event notifications
+ uno::Sequence<rtl::OUString> SAL_CALL FolderPicker_getSupportedServiceNames()
+ {
+ uno::Sequence<rtl::OUString> aRet(2);
+ aRet[0] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.dialogs.SystemFolderPicker" ));
+ aRet[1] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.dialogs.GtkFolderPicker" ));
+ return aRet;
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+// constructor
+//-----------------------------------------------------------------------------------------
+SalGtkFolderPicker::SalGtkFolderPicker( const uno::Reference<lang::XMultiServiceFactory>& xServiceMgr ) :
+ SalGtkPicker(xServiceMgr),
+ m_xServiceMgr(xServiceMgr)
+{
+ CResourceProvider aResProvider;
+
+ m_pDialog = gtk_file_chooser_dialog_new(
+ OUStringToOString( aResProvider.getResString( FOLDERPICKER_TITLE ), RTL_TEXTENCODING_UTF8 ).getStr(),
+ NULL, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, (char *)NULL );
+
+ gtk_dialog_set_default_response( GTK_DIALOG (m_pDialog), GTK_RESPONSE_ACCEPT );
+ gtk_file_chooser_set_local_only( GTK_FILE_CHOOSER( m_pDialog ), sal_False );
+ gtk_file_chooser_set_select_multiple( GTK_FILE_CHOOSER( m_pDialog ), sal_False );
+}
+
+// -------------------------------------------------
+// XEventListener
+// -------------------------------------------------
+
+void SAL_CALL SalGtkFolderPicker::disposing( const lang::EventObject& )
+ throw( uno::RuntimeException )
+{
+}
+
+void SAL_CALL SalGtkFolderPicker::setDisplayDirectory( const rtl::OUString& aDirectory )
+ throw( lang::IllegalArgumentException, uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ OSL_ASSERT( m_pDialog != NULL );
+
+ OString aTxt = unicodetouri( aDirectory );
+
+ if( aTxt.lastIndexOf('/') == aTxt.getLength() - 1 )
+ aTxt = aTxt.copy( 0, aTxt.getLength() - 1 );
+
+ OSL_TRACE( "setting path to %s", aTxt.getStr() );
+
+ gtk_file_chooser_set_current_folder_uri( GTK_FILE_CHOOSER( m_pDialog ),
+ aTxt.getStr() );
+}
+
+rtl::OUString SAL_CALL SalGtkFolderPicker::getDisplayDirectory() throw( uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ OSL_ASSERT( m_pDialog != NULL );
+
+ gchar* pCurrentFolder =
+ gtk_file_chooser_get_current_folder_uri( GTK_FILE_CHOOSER( m_pDialog ) );
+ ::rtl::OUString aCurrentFolderName = uritounicode(pCurrentFolder);
+ g_free( pCurrentFolder );
+
+ return aCurrentFolderName;
+}
+
+rtl::OUString SAL_CALL SalGtkFolderPicker::getDirectory() throw( uno::RuntimeException )
+{
+ return getDisplayDirectory();
+}
+
+void SAL_CALL SalGtkFolderPicker::setDescription( const rtl::OUString& rDescription )
+ throw( uno::RuntimeException )
+{
+ ::rtl::OString aDescription = OUStringToOString( rDescription, RTL_TEXTENCODING_UTF8 );
+}
+
+
+
+//-----------------------------------------------------------------------------------------
+// XExecutableDialog functions
+//-----------------------------------------------------------------------------------------
+
+void SAL_CALL SalGtkFolderPicker::setTitle( const rtl::OUString& aTitle ) throw( uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ OSL_ASSERT( m_pDialog != NULL );
+
+ ::rtl::OString aWindowTitle = OUStringToOString( aTitle, RTL_TEXTENCODING_UTF8 );
+
+ gtk_window_set_title( GTK_WINDOW( m_pDialog ), aWindowTitle.getStr() );
+}
+
+sal_Int16 SAL_CALL SalGtkFolderPicker::execute() throw( uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ OSL_TRACE( "1: HERE WE ARE");
+ OSL_ASSERT( m_pDialog != NULL );
+
+ sal_Int16 retVal = 0;
+
+ uno::Reference< awt::XExtendedToolkit > xToolkit(
+ m_xServiceMgr->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.Toolkit")) ), uno::UNO_QUERY);
+
+ uno::Reference< frame::XDesktop > xDesktop(
+ m_xServiceMgr->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ), uno::UNO_QUERY);
+
+ RunDialog* pRunDialog = new RunDialog(m_pDialog, xToolkit, xDesktop);
+ uno::Reference < awt::XTopWindowListener > xLifeCycle(pRunDialog);
+ gint nStatus = pRunDialog->run();
+ switch( nStatus )
+ {
+ case GTK_RESPONSE_ACCEPT:
+ retVal = ExecutableDialogResults::OK;
+ break;
+ case GTK_RESPONSE_CANCEL:
+ retVal = ExecutableDialogResults::CANCEL;
+ break;
+ default:
+ retVal = 0;
+ break;
+ }
+
+ return retVal;
+}
+
+//------------------------------------------------------------------------------------
+// XCancellable
+//------------------------------------------------------------------------------------
+
+void SAL_CALL SalGtkFolderPicker::cancel() throw( uno::RuntimeException )
+{
+ SolarMutexGuard g;
+
+ OSL_ASSERT( m_pDialog != NULL );
+
+ // TODO m_pImpl->cancel();
+}
+
+// -------------------------------------------------
+// XServiceInfo
+// -------------------------------------------------
+
+rtl::OUString SAL_CALL SalGtkFolderPicker::getImplementationName()
+ throw( uno::RuntimeException )
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( FOLDER_PICKER_IMPL_NAME ));
+}
+
+// -------------------------------------------------
+// XServiceInfo
+// -------------------------------------------------
+
+sal_Bool SAL_CALL SalGtkFolderPicker::supportsService( const rtl::OUString& ServiceName )
+ throw( uno::RuntimeException )
+{
+ uno::Sequence <rtl::OUString> SupportedServicesNames = FolderPicker_getSupportedServiceNames();
+
+ for( sal_Int32 n = SupportedServicesNames.getLength(); n--; )
+ if( SupportedServicesNames[n].compareTo( ServiceName ) == 0)
+ return sal_True;
+
+ return sal_False;
+}
+
+// -------------------------------------------------
+// XServiceInfo
+// -------------------------------------------------
+
+uno::Sequence<rtl::OUString> SAL_CALL SalGtkFolderPicker::getSupportedServiceNames()
+ throw( uno::RuntimeException )
+{
+ return FolderPicker_getSupportedServiceNames();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk/fpicker/SalGtkFolderPicker.hxx b/vcl/unx/gtk/fpicker/SalGtkFolderPicker.hxx
new file mode 100644
index 000000000000..5110ea86a0f6
--- /dev/null
+++ b/vcl/unx/gtk/fpicker/SalGtkFolderPicker.hxx
@@ -0,0 +1,127 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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 _SALGTKFOLDERPICKER_HXX_
+#define _SALGTKFOLDERPICKER_HXX_
+
+//_______________________________________________________________________________________________________________________
+// includes of other projects
+//_______________________________________________________________________________________________________________________
+
+#include <cppuhelper/implbase3.hxx>
+
+#include "SalGtkPicker.hxx"
+
+#include <memory>
+
+#include <rtl/ustring.hxx>
+
+#include <list>
+
+//----------------------------------------------------------
+// class declaration
+//----------------------------------------------------------
+
+class SalGtkFolderPicker :
+ public SalGtkPicker,
+ public cppu::WeakImplHelper3<
+ ::com::sun::star::ui::dialogs::XFolderPicker,
+ ::com::sun::star::lang::XServiceInfo,
+ ::com::sun::star::util::XCancellable >
+{
+ public:
+
+ // constructor
+ SalGtkFolderPicker( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceMgr );
+
+ //------------------------------------------------------------------------------------
+ // XExecutableDialog functions
+ //------------------------------------------------------------------------------------
+
+ virtual void SAL_CALL setTitle( const ::rtl::OUString& aTitle )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int16 SAL_CALL execute( )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ //------------------------------------------------------------------------------------
+ // XFolderPicker functions
+ //------------------------------------------------------------------------------------
+
+ virtual void SAL_CALL setDisplayDirectory( const rtl::OUString& rDirectory )
+ throw( com::sun::star::lang::IllegalArgumentException, com::sun::star::uno::RuntimeException );
+
+ virtual rtl::OUString SAL_CALL getDisplayDirectory( )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual rtl::OUString SAL_CALL getDirectory( )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL setDescription( const rtl::OUString& rDescription )
+ throw( 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);
+
+ //------------------------------------------------
+ // XCancellable
+ //------------------------------------------------
+
+ virtual void SAL_CALL cancel( )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ //------------------------------------------------
+ // XEventListener
+ //------------------------------------------------
+
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& aEvent )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ private:
+ // prevent copy and assignment
+ SalGtkFolderPicker( const SalGtkFolderPicker& );
+ SalGtkFolderPicker& operator=( const SalGtkFolderPicker& );
+ private:
+ // to instanciate own services
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xServiceMgr;
+};
+
+#endif // _SALGTKFOLDERPICKER_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk/fpicker/SalGtkPicker.cxx b/vcl/unx/gtk/fpicker/SalGtkPicker.cxx
new file mode 100644
index 000000000000..d52c2c60e37d
--- /dev/null
+++ b/vcl/unx/gtk/fpicker/SalGtkPicker.cxx
@@ -0,0 +1,313 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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_fpicker.hxx"
+
+#ifdef AIX
+#define _LINUX_SOURCE_COMPAT
+#include <sys/timer.h>
+#undef _LINUX_SOURCE_COMPAT
+#endif
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/uri/XExternalUriReferenceTranslator.hpp>
+#include <com/sun/star/lang/SystemDependent.hpp>
+#include <com/sun/star/awt/XSystemDependentWindowPeer.hpp>
+#include <com/sun/star/awt/SystemDependentXWindow.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <comphelper/processfactory.hxx>
+#include <cppuhelper/interfacecontainer.h>
+#include <rtl/process.h>
+#include <osl/diagnose.h>
+#include <com/sun/star/uno/Any.hxx>
+#include <FPServiceInfo.hxx>
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include "SalGtkPicker.hxx"
+#include <tools/urlobj.hxx>
+#include <stdio.h>
+
+//------------------------------------------------------------------------
+// namespace directives
+//------------------------------------------------------------------------
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+
+rtl::OUString SalGtkPicker::uritounicode(const gchar* pIn)
+{
+ if (!pIn)
+ return rtl::OUString();
+
+ rtl::OUString sURL( const_cast<const sal_Char *>(pIn), strlen(pIn),
+ RTL_TEXTENCODING_UTF8 );
+
+ INetURLObject aURL(sURL);
+ if (INET_PROT_FILE == aURL.GetProtocol())
+ {
+ // all the URLs are handled by office in UTF-8
+ // so the Gnome FP related URLs should be converted accordingly
+ gchar *pEncodedFileName = g_filename_from_uri(pIn, NULL, NULL);
+ if ( pEncodedFileName )
+ {
+ rtl::OUString sEncoded(pEncodedFileName, strlen(pEncodedFileName),
+ osl_getThreadTextEncoding());
+ INetURLObject aCurrentURL(sEncoded, INetURLObject::FSYS_UNX);
+ aCurrentURL.SetHost(aURL.GetHost());
+ sURL = aCurrentURL.getExternalURL();
+ }
+ else
+ {
+ 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);
+ if( aNewURL.getLength() )
+ sURL = aNewURL;
+ }
+ }
+ return sURL;
+}
+
+rtl::OString SalGtkPicker::unicodetouri(const rtl::OUString &rURL)
+{
+ // all the URLs are handled by office in UTF-8 ( and encoded with "%xx" codes based on UTF-8 )
+ // so the Gnome FP related URLs should be converted accordingly
+ OString sURL = OUStringToOString(rURL, RTL_TEXTENCODING_UTF8);
+ INetURLObject aURL(rURL);
+ if (INET_PROT_FILE == aURL.GetProtocol())
+ {
+ 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 );
+
+ if( aNewURL.getLength() )
+ {
+ // At this point the URL should contain ascii characters only actually
+ sURL = OUStringToOString( aNewURL, osl_getThreadTextEncoding() );
+ }
+ }
+ return sURL;
+}
+
+extern "C"
+{
+ struct Display;
+ extern GdkDisplay* gdk_x11_lookup_xdisplay (void*xdisplay);
+
+ static gboolean canceldialog(RunDialog *pDialog)
+ {
+ GdkThreadLock lock;
+ pDialog->cancel();
+ return false;
+ }
+}
+
+RunDialog::RunDialog( GtkWidget *pDialog, uno::Reference< awt::XExtendedToolkit >& rToolkit,
+ uno::Reference< frame::XDesktop >& rDesktop ) :
+ cppu::WeakComponentImplHelper2< awt::XTopWindowListener, frame::XTerminateListener >( maLock ),
+ mpDialog(pDialog), mpCreatedParent(NULL), mxToolkit(rToolkit), mxDesktop(rDesktop)
+{
+ awt::SystemDependentXWindow aWindowHandle;
+
+ if (mxToolkit.is())
+ {
+ uno::Reference< awt::XTopWindow > xWindow(mxToolkit->getActiveTopWindow());
+ if (xWindow.is())
+ {
+ uno::Reference< awt::XSystemDependentWindowPeer > xSystemDepParent(xWindow, uno::UNO_QUERY);
+ if (xSystemDepParent.is())
+ {
+
+ sal_Int8 processID[16];
+
+ rtl_getGlobalProcessId( (sal_uInt8*)processID );
+ uno::Sequence<sal_Int8> processIdSeq(processID, 16);
+ uno::Any anyHandle = xSystemDepParent->getWindowHandle(processIdSeq, SystemDependent::SYSTEM_XWINDOW);
+
+ anyHandle >>= aWindowHandle;
+ }
+ }
+ }
+
+ GdkDisplay *pDisplay = aWindowHandle.DisplayPointer ? gdk_x11_lookup_xdisplay(reinterpret_cast<void*>(static_cast<sal_IntPtr>(aWindowHandle.DisplayPointer))) : NULL;
+ GdkWindow* pParent = pDisplay ? gdk_window_lookup_for_display(pDisplay, aWindowHandle.WindowHandle) : NULL;
+ if (!pParent && pDisplay)
+ pParent = mpCreatedParent = gdk_window_foreign_new_for_display( pDisplay, aWindowHandle.WindowHandle);
+ if (pParent)
+ {
+ gtk_widget_realize(mpDialog);
+ gdk_window_set_transient_for(mpDialog->window, pParent);
+ }
+}
+
+
+RunDialog::~RunDialog()
+{
+ SolarMutexGuard g;
+
+ if (mpCreatedParent)
+ gdk_window_destroy (mpCreatedParent);
+
+ g_source_remove_by_user_data (this);
+}
+
+void SAL_CALL RunDialog::windowOpened( const ::com::sun::star::lang::EventObject& )
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ SolarMutexGuard g;
+
+ g_timeout_add_full(G_PRIORITY_HIGH_IDLE, 0, (GSourceFunc)canceldialog, this, NULL);
+}
+
+void SAL_CALL RunDialog::queryTermination( const ::com::sun::star::lang::EventObject& )
+ throw(::com::sun::star::frame::TerminationVetoException, ::com::sun::star::uno::RuntimeException)
+{
+}
+
+void SAL_CALL RunDialog::notifyTermination( const ::com::sun::star::lang::EventObject& )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ SolarMutexGuard g;
+
+ g_timeout_add_full(G_PRIORITY_HIGH_IDLE, 0, (GSourceFunc)canceldialog, this, NULL);
+}
+
+void RunDialog::cancel()
+{
+ gtk_dialog_response( GTK_DIALOG( mpDialog ), GTK_RESPONSE_CANCEL );
+ gtk_widget_hide( mpDialog );
+}
+
+gint RunDialog::run()
+{
+ if (mxToolkit.is())
+ mxToolkit->addTopWindowListener(this);
+
+ gint nStatus = gtk_dialog_run( GTK_DIALOG( mpDialog ) );
+
+ if (mxToolkit.is())
+ mxToolkit->removeTopWindowListener(this);
+
+ if (nStatus != 1) //PLAY
+ gtk_widget_hide( mpDialog );
+
+ return nStatus;
+}
+
+static void lcl_setGTKLanguage(const uno::Reference<lang::XMultiServiceFactory>& xServiceMgr)
+{
+ static bool bSet = false;
+ if (bSet)
+ return;
+
+ OUString sUILocale;
+ try
+ {
+ uno::Reference<lang::XMultiServiceFactory> xConfigMgr =
+ uno::Reference<lang::XMultiServiceFactory>(xServiceMgr->createInstance(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationProvider"))),
+ UNO_QUERY_THROW );
+
+ Sequence< Any > theArgs(1);
+ theArgs[ 0 ] <<= OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Linguistic/General"));
+
+ uno::Reference< container::XNameAccess > xNameAccess =
+ uno::Reference< container::XNameAccess >(xConfigMgr->createInstanceWithArguments(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationAccess")), theArgs ),
+ UNO_QUERY_THROW );
+
+ if (xNameAccess.is())
+ xNameAccess->getByName(OUString(RTL_CONSTASCII_USTRINGPARAM("UILocale"))) >>= sUILocale;
+ } catch (...) {}
+
+ if (sUILocale.getLength())
+ {
+ sUILocale = sUILocale.replace('-', '_');
+ rtl::OUString envVar(RTL_CONSTASCII_USTRINGPARAM("LANGUAGE"));
+ osl_setEnvironment(envVar.pData, sUILocale.pData);
+ }
+ bSet = true;
+}
+
+SalGtkPicker::SalGtkPicker(const uno::Reference<lang::XMultiServiceFactory>& xServiceMgr) : m_pDialog(0)
+{
+ lcl_setGTKLanguage(xServiceMgr);
+}
+
+SalGtkPicker::~SalGtkPicker()
+{
+ SolarMutexGuard g;
+
+ if (m_pDialog)
+ {
+ gtk_widget_destroy(m_pDialog);
+ }
+}
+
+void SAL_CALL SalGtkPicker::implsetDisplayDirectory( const rtl::OUString& aDirectory )
+ throw( lang::IllegalArgumentException, uno::RuntimeException )
+{
+ OSL_ASSERT( m_pDialog != NULL );
+
+ OString aTxt = unicodetouri(aDirectory);
+
+ if( aTxt.lastIndexOf('/') == aTxt.getLength() - 1 )
+ aTxt = aTxt.copy( 0, aTxt.getLength() - 1 );
+
+ OSL_TRACE( "setting path to %s", aTxt.getStr() );
+
+ gtk_file_chooser_set_current_folder_uri( GTK_FILE_CHOOSER( m_pDialog ),
+ aTxt.getStr() );
+}
+
+rtl::OUString SAL_CALL SalGtkPicker::implgetDisplayDirectory() throw( uno::RuntimeException )
+{
+ OSL_ASSERT( m_pDialog != NULL );
+
+ gchar* pCurrentFolder =
+ gtk_file_chooser_get_current_folder_uri( GTK_FILE_CHOOSER( m_pDialog ) );
+ ::rtl::OUString aCurrentFolderName = uritounicode(pCurrentFolder);
+ g_free( pCurrentFolder );
+
+ return aCurrentFolderName;
+}
+
+void SAL_CALL SalGtkPicker::implsetTitle( const rtl::OUString& aTitle ) throw( uno::RuntimeException )
+{
+ OSL_ASSERT( m_pDialog != NULL );
+
+ ::rtl::OString aWindowTitle = OUStringToOString( aTitle, RTL_TEXTENCODING_UTF8 );
+
+ gtk_window_set_title( GTK_WINDOW( m_pDialog ), aWindowTitle.getStr() );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk/fpicker/SalGtkPicker.hxx b/vcl/unx/gtk/fpicker/SalGtkPicker.hxx
new file mode 100644
index 000000000000..cd9e6553a925
--- /dev/null
+++ b/vcl/unx/gtk/fpicker/SalGtkPicker.hxx
@@ -0,0 +1,138 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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 _SALGTKFPICKER_HXX_
+#define _SALGTKFPICKER_HXX_
+
+//_____________________________________________________________________________
+// includes of other projects
+//_____________________________________________________________________________
+
+#include <osl/mutex.hxx>
+#include <cppuhelper/compbase2.hxx>
+#include <com/sun/star/ui/dialogs/XFilePicker.hpp>
+#include <com/sun/star/ui/dialogs/XFilePicker2.hpp>
+#include <com/sun/star/ui/dialogs/XFolderPicker.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/util/XCancellable.hpp>
+
+#include <com/sun/star/awt/XTopWindowListener.hpp>
+#include <com/sun/star/awt/XExtendedToolkit.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/frame/XTerminateListener.hpp>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+
+//----------------------------------------------------------
+// class declaration
+//----------------------------------------------------------
+
+class SalGtkPicker
+{
+ public:
+ SalGtkPicker(const ::com::sun::star::uno::Reference<com::sun::star::lang::XMultiServiceFactory>& xServiceMgr);
+ virtual ~SalGtkPicker();
+ protected:
+ osl::Mutex m_rbHelperMtx;
+ GtkWidget *m_pDialog;
+ protected:
+ virtual void SAL_CALL implsetTitle( const ::rtl::OUString& aTitle )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL implsetDisplayDirectory( const rtl::OUString& rDirectory )
+ throw( com::sun::star::lang::IllegalArgumentException, com::sun::star::uno::RuntimeException );
+
+ virtual rtl::OUString SAL_CALL implgetDisplayDirectory( )
+ throw( com::sun::star::uno::RuntimeException );
+ static rtl::OUString uritounicode(const gchar *pIn);
+ static rtl::OString unicodetouri(const rtl::OUString &rURL);
+};
+
+class GdkThreadLock
+{
+public:
+ GdkThreadLock() { gdk_threads_enter(); }
+ ~GdkThreadLock() { gdk_threads_leave(); }
+};
+
+//Run the Gtk Dialog. Watch for any "new windows" created while we're
+//executing and consider that a CANCEL event to avoid e.g. "file cannot be opened"
+//modal dialogs and this one getting locked if some other API call causes this
+//to happen while we're opened waiting for user input, e.g.
+//https://bugzilla.redhat.com/show_bug.cgi?id=441108
+class RunDialog :
+ public cppu::WeakComponentImplHelper2<
+ ::com::sun::star::awt::XTopWindowListener,
+ ::com::sun::star::frame::XTerminateListener >
+{
+private:
+ osl::Mutex maLock;
+ GtkWidget *mpDialog;
+ GdkWindow *mpCreatedParent;
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XExtendedToolkit> mxToolkit;
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDesktop > mxDesktop;
+public:
+
+ // XTopWindowListener
+ using cppu::WeakComponentImplHelperBase::disposing;
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& )
+ throw(::com::sun::star::uno::RuntimeException) {}
+ virtual void SAL_CALL windowOpened( const ::com::sun::star::lang::EventObject& e )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL windowClosing( const ::com::sun::star::lang::EventObject& )
+ throw (::com::sun::star::uno::RuntimeException) {}
+ virtual void SAL_CALL windowClosed( const ::com::sun::star::lang::EventObject& )
+ throw (::com::sun::star::uno::RuntimeException) {}
+ virtual void SAL_CALL windowMinimized( const ::com::sun::star::lang::EventObject& )
+ throw (::com::sun::star::uno::RuntimeException) {}
+ virtual void SAL_CALL windowNormalized( const ::com::sun::star::lang::EventObject& )
+ throw (::com::sun::star::uno::RuntimeException) {}
+ virtual void SAL_CALL windowActivated( const ::com::sun::star::lang::EventObject& )
+ throw (::com::sun::star::uno::RuntimeException) {}
+ virtual void SAL_CALL windowDeactivated( const ::com::sun::star::lang::EventObject& )
+ 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);
+public:
+ RunDialog(GtkWidget *pDialog,
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XExtendedToolkit > &rToolkit,
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDesktop > &rDesktop
+ );
+ virtual ~RunDialog();
+ gint run();
+ void cancel();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk/fpicker/eventnotification.hxx b/vcl/unx/gtk/fpicker/eventnotification.hxx
new file mode 100644
index 000000000000..3866ca59946f
--- /dev/null
+++ b/vcl/unx/gtk/fpicker/eventnotification.hxx
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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 _EVENTNOTIFICATION_HXX_
+#define _EVENTNOTIFICATION_HXX_
+
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+//-----------------------------------
+// encapsulate a filepicker event
+// notification, because there are
+// two types of filepicker notifications
+// with and without parameter
+// this is an application of the
+// "command" pattern see GoF
+//-----------------------------------
+
+class CEventNotification
+{
+public:
+ virtual ~CEventNotification() { };
+
+ virtual void SAL_CALL notifyEventListener( com::sun::star::uno::Reference< com::sun::star::uno::XInterface > xListener ) = 0;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk/fpicker/fps_gnome.component b/vcl/unx/gtk/fpicker/fps_gnome.component
new file mode 100644
index 000000000000..72bca42f8acf
--- /dev/null
+++ b/vcl/unx/gtk/fpicker/fps_gnome.component
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**********************************************************************
+*
+* 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.
+*
+**********************************************************************-->
+
+<component loader="com.sun.star.loader.SharedLibrary"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.ui.dialogs.SalGtkFilePicker">
+ <service name="com.sun.star.ui.dialogs.GtkFilePicker"/>
+ </implementation>
+ <implementation name="com.sun.star.ui.dialogs.SalGtkFolderPicker">
+ <service name="com.sun.star.ui.dialogs.GtkFolderPicker"/>
+ </implementation>
+</component>
diff --git a/vcl/unx/gtk/fpicker/fps_gnome.xml b/vcl/unx/gtk/fpicker/fps_gnome.xml
new file mode 100644
index 000000000000..d4dd4f9231d6
--- /dev/null
+++ b/vcl/unx/gtk/fpicker/fps_gnome.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+ <module-name>fps</module-name>
+ <component-description>
+ <author> Jan Holesovsky </author>
+ <name> com.sun.star.comp.ui.dialogs.FilePicker </name>
+ <description>
+ The Gnome implementation of the FilePicker service.
+ </description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="beta"/>
+ <supported-service> com.sun.star.ui.dialogs.FilePicker </supported-service>
+ <service-dependency>...</service-dependency>
+ <type> com.sun.star.ui.dialogs.XExecutableDialog </type>
+ <type> com.sun.star.ui.dialogs.XFilePicker </type>
+ <type> com.sun.star.ui.dialogs.XFilterManager </type>
+ <type> com.sun.star.ui.dialogs.XFilterGroupManager </type>
+ <type> com.sun.star.ui.dialogs.XFilePickerListener </type>
+ <type> com.sun.star.ui.dialogs.ExecutableDialogException </type>
+ <type> com.sun.star.ui.dialogs.XFilePickerNotifier </type>
+ <type> com.sun.star.ui.dialogs.XFilePickerControlAccess </type>
+ <type> com.sun.star.ui.dialogs.XFilePreview </type>
+ <type> com.sun.star.ui.dialogs.ExtendedFilePickerElementIds </type>
+ <type> com.sun.star.ui.dialogs.ExecutableDialogResults </type>
+ <type> com.sun.star.ui.dialogs.FilePickerEvent </type>
+ <type> com.sun.star.ui.dialogs.CommonFilePickerElementIds </type>
+ <type> com.sun.star.ui.dialogs.ListboxControlActions </type>
+ <type> com.sun.star.ui.dialogs.TemplateDescription </type>
+ <type> com.sun.star.ui.dialogs.FilePreviewImageFormats </type>
+ <type> com.sun.star.util.XCancellable </type>
+ <type> com.sun.star.lang.XComponent </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.lang.IllegalArgumentException </type>
+ <type> com.sun.star.uno.TypeClass </type>
+ <type> com.sun.star.uno.XWeak </type>
+ <type> com.sun.star.uno.XAggregation </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.container.XSet </type>
+ </component-description>
+ <component-description>
+ <author> Caolan McNamara </author>
+ <name> com.sun.star.comp.ui.dialogs.FolderPicker </name>
+ <description>
+ The Gnome implementation of the FolderPicker service.
+ </description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="beta"/>
+ <supported-service> com.sun.star.ui.dialogs.FolderPicker </supported-service>
+ <service-dependency>...</service-dependency>
+ <type> com.sun.star.ui.dialogs.XExecutableDialog </type>
+ <type> com.sun.star.ui.dialogs.XFolderPicker </type>
+ <type> com.sun.star.ui.dialogs.ExecutableDialogException </type>
+ <type> com.sun.star.ui.dialogs.ExecutableDialogResults </type>
+ <type> com.sun.star.util.XCancellable </type>
+ <type> com.sun.star.lang.XComponent </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.lang.IllegalArgumentException </type>
+ <type> com.sun.star.uno.TypeClass </type>
+ <type> com.sun.star.uno.XWeak </type>
+ <type> com.sun.star.uno.XAggregation </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.container.XSet </type>
+ </component-description>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> sal </project-build-dependency>
+ <runtime-module-dependency> cppuhelper </runtime-module-dependency>
+ <runtime-module-dependency> cppu2 </runtime-module-dependency>
+ <runtime-module-dependency> sal2 </runtime-module-dependency>
+</module-description>
diff --git a/vcl/unx/gtk/fpicker/resourceprovider.cxx b/vcl/unx/gtk/fpicker/resourceprovider.cxx
new file mode 100644
index 000000000000..4a4f49cc089d
--- /dev/null
+++ b/vcl/unx/gtk/fpicker/resourceprovider.cxx
@@ -0,0 +1,229 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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_fpicker.hxx"
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+#include <osl/diagnose.h>
+#include <rtl/ustrbuf.hxx>
+#include "resourceprovider.hxx"
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <tools/resmgr.hxx>
+#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
+#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
+
+#include <svtools/svtools.hrc>
+#include <svtools/filedlg2.hrc>
+
+//------------------------------------------------------------
+// namespace directives
+//------------------------------------------------------------
+
+using rtl::OUString;
+using namespace ::com::sun::star::ui::dialogs::ExtendedFilePickerElementIds;
+using namespace ::com::sun::star::ui::dialogs::CommonFilePickerElementIds;
+
+//------------------------------------------------------------
+//
+//------------------------------------------------------------
+
+static const char* RES_NAME = "fps_office";
+static const char* OTHER_RES_NAME = "svt";
+
+//------------------------------------------------------------
+// we have to translate control ids to resource ids
+//------------------------------------------------------------
+
+struct _Entry
+{
+ sal_Int32 ctrlId;
+ sal_Int16 resId;
+};
+
+_Entry CtrlIdToResIdTable[] = {
+ { CHECKBOX_AUTOEXTENSION, STR_SVT_FILEPICKER_AUTO_EXTENSION },
+ { CHECKBOX_PASSWORD, STR_SVT_FILEPICKER_PASSWORD },
+ { CHECKBOX_FILTEROPTIONS, STR_SVT_FILEPICKER_FILTER_OPTIONS },
+ { CHECKBOX_READONLY, STR_SVT_FILEPICKER_READONLY },
+ { CHECKBOX_LINK, STR_SVT_FILEPICKER_INSERT_AS_LINK },
+ { CHECKBOX_PREVIEW, STR_SVT_FILEPICKER_SHOW_PREVIEW },
+ { PUSHBUTTON_PLAY, STR_SVT_FILEPICKER_PLAY },
+ { LISTBOX_VERSION_LABEL, STR_SVT_FILEPICKER_VERSION },
+ { LISTBOX_TEMPLATE_LABEL, STR_SVT_FILEPICKER_TEMPLATES },
+ { LISTBOX_IMAGE_TEMPLATE_LABEL, STR_SVT_FILEPICKER_IMAGE_TEMPLATE },
+ { CHECKBOX_SELECTION, STR_SVT_FILEPICKER_SELECTION },
+ { FOLDERPICKER_TITLE, STR_SVT_FOLDERPICKER_DEFAULT_TITLE },
+ { FOLDER_PICKER_DEF_DESCRIPTION, STR_SVT_FOLDERPICKER_DEFAULT_DESCRIPTION },
+ { FILE_PICKER_OVERWRITE, STR_SVT_ALREADYEXISTOVERWRITE },
+ { FILE_PICKER_ALLFORMATS, STR_SVT_ALLFORMATS }
+};
+
+_Entry OtherCtrlIdToResIdTable[] = {
+ { FILE_PICKER_TITLE_OPEN, STR_FILEDLG_OPEN },
+ { FILE_PICKER_TITLE_SAVE, STR_FILEDLG_SAVE },
+ { FILE_PICKER_FILE_TYPE, STR_FILEDLG_TYPE },
+};
+
+
+const sal_Int32 SIZE_TABLE = SAL_N_ELEMENTS( CtrlIdToResIdTable );
+const sal_Int32 OTHER_SIZE_TABLE = SAL_N_ELEMENTS( OtherCtrlIdToResIdTable );
+
+//------------------------------------------------------------
+//
+//------------------------------------------------------------
+
+sal_Int16 CtrlIdToResId( sal_Int32 aControlId )
+{
+ sal_Int16 aResId = -1;
+
+ for ( sal_Int32 i = 0; i < SIZE_TABLE; i++ )
+ {
+ if ( CtrlIdToResIdTable[i].ctrlId == aControlId )
+ {
+ aResId = CtrlIdToResIdTable[i].resId;
+ break;
+ }
+ }
+
+ return aResId;
+}
+
+sal_Int16 OtherCtrlIdToResId( sal_Int32 aControlId )
+{
+ sal_Int16 aResId = -1;
+
+ for ( sal_Int32 i = 0; i < OTHER_SIZE_TABLE; i++ )
+ {
+ if ( OtherCtrlIdToResIdTable[i].ctrlId == aControlId )
+ {
+ aResId = OtherCtrlIdToResIdTable[i].resId;
+ break;
+ }
+ }
+
+ return aResId;
+}
+
+//------------------------------------------------------------
+//
+//------------------------------------------------------------
+
+class CResourceProvider_Impl
+{
+public:
+
+ //-------------------------------------
+ //
+ //-------------------------------------
+
+ CResourceProvider_Impl( )
+ {
+ m_ResMgr = ResMgr::CreateResMgr( RES_NAME );
+ m_OtherResMgr = ResMgr::CreateResMgr( OTHER_RES_NAME );
+ }
+
+ //-------------------------------------
+ //
+ //-------------------------------------
+
+ ~CResourceProvider_Impl( )
+ {
+ delete m_ResMgr;
+ delete m_OtherResMgr;
+ }
+
+ //-------------------------------------
+ //
+ //-------------------------------------
+
+ OUString getResString( sal_Int16 aId )
+ {
+ String aResString;
+ OUString aResOUString;
+
+ try
+ {
+ OSL_ASSERT( m_ResMgr && m_OtherResMgr );
+
+ // translate the control id to a resource id
+ sal_Int16 aResId = CtrlIdToResId( aId );
+ if ( aResId > -1 )
+ aResString = String( ResId( aResId, *m_ResMgr ) );
+ else
+ {
+ aResId = OtherCtrlIdToResId( aId );
+ if ( aResId > -1 )
+ aResString = String( ResId( aResId, *m_OtherResMgr ) );
+ }
+ if ( aResId > -1 )
+ aResOUString = OUString( aResString );
+ }
+ catch(...)
+ {
+ }
+
+ return aResOUString;
+ }
+
+public:
+ ResMgr* m_ResMgr;
+ ResMgr* m_OtherResMgr;
+};
+
+//------------------------------------------------------------
+//
+//------------------------------------------------------------
+
+CResourceProvider::CResourceProvider( ) :
+ m_pImpl( new CResourceProvider_Impl() )
+{
+}
+
+//------------------------------------------------------------
+//
+//------------------------------------------------------------
+
+CResourceProvider::~CResourceProvider( )
+{
+ delete m_pImpl;
+}
+
+//------------------------------------------------------------
+//
+//------------------------------------------------------------
+
+OUString CResourceProvider::getResString( sal_Int32 aId )
+{
+ return m_pImpl->getResString( aId ).replace('~', '_');
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk/fpicker/resourceprovider.hxx b/vcl/unx/gtk/fpicker/resourceprovider.hxx
new file mode 100644
index 000000000000..5bbbbfd68e7e
--- /dev/null
+++ b/vcl/unx/gtk/fpicker/resourceprovider.hxx
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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 _RESOURCEPROVIDER_HXX_
+#define _RESOURCEPROVIDER_HXX_
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+
+#include <sal/types.h>
+
+#include <rtl/ustring.hxx>
+
+#define FOLDERPICKER_TITLE 500
+#define FOLDER_PICKER_DEF_DESCRIPTION 501
+#define FILE_PICKER_TITLE_OPEN 502
+#define FILE_PICKER_TITLE_SAVE 503
+#define FILE_PICKER_FILE_TYPE 504
+#define FILE_PICKER_OVERWRITE 505
+#define FILE_PICKER_ALLFORMATS 506
+
+//------------------------------------------------------------------------
+// deklarations
+//------------------------------------------------------------------------
+
+class CResourceProvider_Impl;
+
+class CResourceProvider
+{
+public:
+ CResourceProvider( );
+ ~CResourceProvider( );
+
+ rtl::OUString getResString( sal_Int32 aId );
+
+private:
+ CResourceProvider_Impl* m_pImpl;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */