merge the formfield patch from ooo-build
[ooovba.git] / fpicker / source / unx / kde_unx / UnxFilePicker.cxx
blob3edefd5d2403b980229f38b03230c7b82a6e3c07
1 /*************************************************************************
9 * The Contents of this file are made available subject to the terms of
10 * either of the following licenses
12 * - GNU Lesser General Public License Version 2.1
13 * - Sun Industry Standards Source License Version 1.1
15 * Sun Microsystems Inc., October, 2000
17 * GNU Lesser General Public License Version 2.1
18 * =============================================
19 * Copyright 2000 by Sun Microsystems, Inc.
20 * 901 San Antonio Road, Palo Alto, CA 94303, USA
22 * This library is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU Lesser General Public
24 * License version 2.1, as published by the Free Software Foundation.
26 * This library is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
29 * Lesser General Public License for more details.
31 * You should have received a copy of the GNU Lesser General Public
32 * License along with this library; if not, write to the Free Software
33 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
34 * MA 02111-1307 USA
37 * Sun Industry Standards Source License Version 1.1
38 * =================================================
39 * The contents of this file are subject to the Sun Industry Standards
40 * Source License Version 1.1 (the "License"); You may not use this file
41 * except in compliance with the License. You may obtain a copy of the
42 * License at http://www.openoffice.org/license.html.
44 * Software provided under this License is provided on an "AS IS" basis,
45 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
46 * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
47 * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
48 * See the License for the specific provisions governing your rights and
49 * obligations concerning the Software.
51 * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
53 * Copyright: 2000 by Sun Microsystems, Inc.
55 * All Rights Reserved.
57 * Contributor(s): Jan Holesovsky <kendy@openoffice.org>
60 ************************************************************************/
62 //////////////////////////////////////////////////////////////////////////
63 // includes
64 //////////////////////////////////////////////////////////////////////////
66 #ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
67 #include <com/sun/star/lang/DisposedException.hpp>
68 #endif
70 #ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
71 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
72 #endif
74 #ifndef _CPPUHELPER_INTERFACECONTAINER_H_
75 #include <cppuhelper/interfacecontainer.h>
76 #endif
78 #ifndef _OSL_DIAGNOSE_H_
79 #include <osl/diagnose.h>
80 #endif
82 #ifndef _COM_SUN_STAR_UI_DIALOGS_TEMPLATEDESCRIPTION_HPP_
83 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
84 #endif
86 #ifndef _COM_SUN_STAR_UI_DIALOGS_COMMONFILEPICKERELEMENTIDS_HPP_
87 #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
88 #endif
90 #ifndef _COM_SUN_STAR_UI_DIALOGS_EXTENDEDFILEPICKERELEMENTIDS_HPP_
91 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
92 #endif
94 #ifndef _COM_SUN_STAR_UI_DIALOGS_CONTROLACTIONS_HPP_
95 #include <com/sun/star/ui/dialogs/ControlActions.hpp>
96 #endif
98 #ifndef _RTL_USTRING_H_
99 #include <rtl/ustring.hxx>
100 #endif
102 #ifndef _RTL_USTRBUF_HXX_
103 #include <rtl/ustrbuf.hxx>
104 #endif
106 #ifndef _FPSERVICEINFO_HXX_
107 #include <FPServiceInfo.hxx>
108 #endif
110 #ifndef _TOOLS_RESMGR_HXX
111 #include <tools/resmgr.hxx>
112 #endif
114 #ifndef _SVTOOLS_HRC
115 #include <svtools/svtools.hrc>
116 #endif
118 #ifndef _UNXFILEOPENIMPL_HXX_
119 #include <UnxFilePicker.hxx>
120 #endif
122 #ifndef _UNXCOMMANDTHREAD_HXX_
123 #include <UnxCommandThread.hxx>
124 #endif
126 #ifndef _UNXNOTIFYTHREAD_HXX_
127 #include <UnxNotifyThread.hxx>
128 #endif
130 #include <vcl/svapp.hxx>
131 #include <vcl/sysdata.hxx>
132 #include <vcl/syswin.hxx>
133 #include <vcl/window.hxx>
135 #include <sys/wait.h>
136 #include <unistd.h>
137 #include <fcntl.h>
138 #include <stdio.h>
140 #include <iostream>
142 using namespace ::com::sun::star;
144 using namespace ::com::sun::star::ui::dialogs;
145 using namespace ::com::sun::star::ui::dialogs::TemplateDescription;
147 //////////////////////////////////////////////////////////////////////////
148 // helper functions
149 //////////////////////////////////////////////////////////////////////////
151 namespace
153 // controling event notifications
154 const bool STARTUP_SUSPENDED = true;
155 const bool STARTUP_ALIVE = false;
157 uno::Sequence<rtl::OUString> SAL_CALL FilePicker_getSupportedServiceNames()
159 uno::Sequence<rtl::OUString> aRet(3);
160 aRet[0] = rtl::OUString::createFromAscii("com.sun.star.ui.dialogs.FilePicker");
161 aRet[1] = rtl::OUString::createFromAscii("com.sun.star.ui.dialogs.SystemFilePicker");
162 aRet[2] = rtl::OUString::createFromAscii("com.sun.star.ui.dialogs.KDEFilePicker");
163 return aRet;
167 //////////////////////////////////////////////////////////////////////////
168 // UnxFilePicker
169 //////////////////////////////////////////////////////////////////////////
171 UnxFilePicker::UnxFilePicker( const uno::Reference<lang::XMultiServiceFactory>& xServiceMgr )
172 : cppu::WeakComponentImplHelper8<
173 XFilterManager,
174 XFilterGroupManager,
175 XFilePickerControlAccess,
176 XFilePickerNotifier,
177 // TODO XFilePreview,
178 lang::XInitialization,
179 util::XCancellable,
180 lang::XEventListener,
181 lang::XServiceInfo>( m_rbHelperMtx ),
182 m_xServiceMgr( xServiceMgr ),
183 m_nFilePickerPid( -1 ),
184 m_nFilePickerWrite( -1 ),
185 m_nFilePickerRead( -1 ),
186 m_pNotifyThread( NULL ),
187 m_pCommandThread( NULL ),
188 m_pResMgr( CREATEVERSIONRESMGR( fps_office ) )
192 UnxFilePicker::~UnxFilePicker()
194 if ( m_nFilePickerPid > 0 )
196 sendCommand( ::rtl::OUString::createFromAscii( "exit" ) );
197 waitpid( m_nFilePickerPid, NULL, 0 );
200 if ( m_pCommandThread )
202 m_pCommandThread->join();
204 delete m_pCommandThread, m_pCommandThread = NULL;
207 if ( m_pNotifyThread )
209 m_pNotifyThread->exit();
211 m_pNotifyThread->join();
213 delete m_pNotifyThread, m_pNotifyThread = NULL;
216 if ( m_nFilePickerWrite >= 0 )
217 close( m_nFilePickerWrite );
219 if ( m_nFilePickerRead >= 0 )
220 close( m_nFilePickerRead );
222 delete m_pResMgr, m_pResMgr = NULL;
225 void SAL_CALL UnxFilePicker::addFilePickerListener( const uno::Reference<XFilePickerListener>& xListener )
226 throw( uno::RuntimeException )
228 OSL_ASSERT( m_pNotifyThread );
229 osl::MutexGuard aGuard( m_aMutex );
231 m_pNotifyThread->addFilePickerListener( xListener );
234 void SAL_CALL UnxFilePicker::removeFilePickerListener( const uno::Reference<XFilePickerListener>& xListener )
235 throw( uno::RuntimeException )
237 OSL_ASSERT( m_pNotifyThread );
238 osl::MutexGuard aGuard( m_aMutex );
240 m_pNotifyThread->removeFilePickerListener( xListener );
243 void SAL_CALL UnxFilePicker::setTitle( const rtl::OUString &rTitle )
244 throw( uno::RuntimeException )
246 checkFilePicker();
247 ::osl::MutexGuard aGuard( m_aMutex );
249 ::rtl::OUStringBuffer aBuffer( 1024 );
251 aBuffer.appendAscii( "setTitle " );
252 appendEscaped( aBuffer, rTitle );
254 sendCommand( aBuffer.makeStringAndClear() );
257 sal_Int16 SAL_CALL UnxFilePicker::execute()
258 throw( uno::RuntimeException )
260 checkFilePicker();
262 // this is _not_ an osl::Condition, see i#93366
263 m_pCommandThread->execCondition().reset();
265 sendCommand( ::rtl::OUString::createFromAscii( "exec" ) );
267 m_pCommandThread->execCondition().wait();
269 return m_pCommandThread->result();
272 void SAL_CALL UnxFilePicker::setMultiSelectionMode( sal_Bool bMode )
273 throw( uno::RuntimeException )
275 checkFilePicker();
276 ::osl::MutexGuard aGuard( m_aMutex );
278 ::rtl::OUString aString = bMode?
279 ::rtl::OUString::createFromAscii( "setMultiSelection true" ):
280 ::rtl::OUString::createFromAscii( "setMultiSelection false" );
282 sendCommand( aString );
285 void SAL_CALL UnxFilePicker::setDefaultName( const ::rtl::OUString &rName )
286 throw( uno::RuntimeException )
288 checkFilePicker();
289 ::osl::MutexGuard aGuard( m_aMutex );
291 ::rtl::OUStringBuffer aBuffer( 1024 );
293 aBuffer.appendAscii( "setDefaultName " );
294 appendEscaped( aBuffer, rName );
296 sendCommand( aBuffer.makeStringAndClear() );
299 void SAL_CALL UnxFilePicker::setDisplayDirectory( const rtl::OUString &rDirectory )
300 throw( uno::RuntimeException )
302 checkFilePicker();
303 ::osl::MutexGuard aGuard( m_aMutex );
305 ::rtl::OUStringBuffer aBuffer( 1024 );
307 aBuffer.appendAscii( "setDirectory " );
308 appendEscaped( aBuffer, rDirectory );
310 sendCommand( aBuffer.makeStringAndClear() );
313 rtl::OUString SAL_CALL UnxFilePicker::getDisplayDirectory()
314 throw( uno::RuntimeException )
316 checkFilePicker();
317 ::osl::MutexGuard aGuard( m_aMutex );
319 sendCommand( ::rtl::OUString::createFromAscii( "getDirectory" ),
320 m_pCommandThread->getDirectoryCondition() );
322 return m_pCommandThread->getDirectory();
325 uno::Sequence< ::rtl::OUString > SAL_CALL UnxFilePicker::getFiles()
326 throw( uno::RuntimeException )
328 checkFilePicker();
329 ::osl::MutexGuard aGuard( m_aMutex );
331 sendCommand( ::rtl::OUString::createFromAscii( "getFiles" ),
332 m_pCommandThread->getFilesCondition() );
334 return m_pCommandThread->getFiles();
337 void SAL_CALL UnxFilePicker::appendFilter( const ::rtl::OUString &rTitle, const ::rtl::OUString &rFilter )
338 throw( lang::IllegalArgumentException, uno::RuntimeException )
340 checkFilePicker();
341 ::osl::MutexGuard aGuard( m_aMutex );
343 ::rtl::OUStringBuffer aBuffer( 1024 );
345 aBuffer.appendAscii( "appendFilter " );
346 appendEscaped( aBuffer, rTitle );
347 aBuffer.appendAscii( " ", 1 );
348 appendEscaped( aBuffer, rFilter );
350 sendCommand( aBuffer.makeStringAndClear() );
353 void SAL_CALL UnxFilePicker::setCurrentFilter( const rtl::OUString &rTitle )
354 throw( lang::IllegalArgumentException, uno::RuntimeException )
356 checkFilePicker();
357 ::osl::MutexGuard aGuard( m_aMutex );
359 ::rtl::OUStringBuffer aBuffer( 1024 );
361 aBuffer.appendAscii( "setCurrentFilter " );
362 appendEscaped( aBuffer, rTitle );
364 sendCommand( aBuffer.makeStringAndClear() );
367 rtl::OUString SAL_CALL UnxFilePicker::getCurrentFilter()
368 throw( uno::RuntimeException )
370 checkFilePicker();
371 ::osl::MutexGuard aGuard( m_aMutex );
373 sendCommand( ::rtl::OUString::createFromAscii( "getCurrentFilter" ),
374 m_pCommandThread->getCurrentFilterCondition() );
376 return m_pCommandThread->getCurrentFilter();
379 void SAL_CALL UnxFilePicker::appendFilterGroup( const rtl::OUString &rGroupTitle, const uno::Sequence<beans::StringPair> &rFilters )
380 throw( lang::IllegalArgumentException, uno::RuntimeException )
382 checkFilePicker();
383 ::osl::MutexGuard aGuard( m_aMutex );
385 ::rtl::OUStringBuffer aBuffer( 1024 );
387 aBuffer.appendAscii( "appendFilterGroup " );
388 appendEscaped( aBuffer, rGroupTitle );
390 for ( sal_Int32 i = 0; i < rFilters.getLength(); ++i )
392 beans::StringPair aPair = rFilters[i];
394 aBuffer.appendAscii( " ", 1 );
395 appendEscaped( aBuffer, aPair.First );
396 aBuffer.appendAscii( " ", 1 );
397 appendEscaped( aBuffer, aPair.Second );
400 sendCommand( aBuffer.makeStringAndClear() );
403 void SAL_CALL UnxFilePicker::setValue( sal_Int16 nControlId, sal_Int16 nControlAction, const uno::Any &rValue )
404 throw( uno::RuntimeException )
406 checkFilePicker();
407 ::osl::MutexGuard aGuard( m_aMutex );
409 ::rtl::OUString aType;
410 ::rtl::OUString aAction;
411 sal_Int32 nTitleId;
413 if ( controlIdInfo( nControlId, aType, nTitleId ) && controlActionInfo( nControlAction, aAction ) )
415 ::rtl::OUStringBuffer aBuffer( 1024 );
417 aBuffer.appendAscii( "setValue " );
418 aBuffer.append( static_cast< sal_Int32 >( nControlId ) );
419 aBuffer.appendAscii( " ", 1 );
420 aBuffer.append( aAction );
422 if ( aType.equalsAscii( "checkbox" ) )
424 sal_Bool bControlValue;
425 if ( ( rValue >>= bControlValue ) && bControlValue )
426 aBuffer.appendAscii( " true" );
427 else
428 aBuffer.appendAscii( " false" );
430 else if ( aType.equalsAscii( "listbox" ) )
432 switch ( nControlAction )
434 case ControlActions::ADD_ITEM:
435 case ControlActions::SET_HELP_URL:
437 ::rtl::OUString aString;
438 if ( rValue >>= aString )
440 aBuffer.appendAscii( " ", 1 );
441 appendEscaped( aBuffer, aString );
444 break;
446 case ControlActions::ADD_ITEMS:
448 uno::Sequence< ::rtl::OUString > aSequence;
449 if ( rValue >>= aSequence )
451 for ( sal_Int32 nIdx = 0; nIdx < aSequence.getLength(); ++nIdx )
453 aBuffer.appendAscii( " ", 1 );
454 appendEscaped( aBuffer, aSequence[nIdx] );
459 break;
461 case ControlActions::DELETE_ITEM:
462 case ControlActions::SET_SELECT_ITEM:
464 sal_Int32 nInt;
465 if ( rValue >>= nInt )
467 aBuffer.appendAscii( " ", 1 );
468 aBuffer.append( nInt );
471 break;
473 default:
474 // nothing
475 break;
478 // TODO else if push button...
480 sendCommand( aBuffer.makeStringAndClear() );
484 uno::Any SAL_CALL UnxFilePicker::getValue( sal_Int16 nControlId, sal_Int16 nControlAction )
485 throw( uno::RuntimeException )
487 checkFilePicker();
488 ::osl::MutexGuard aGuard( m_aMutex );
490 ::rtl::OUString aAction;
492 if ( controlActionInfo( nControlAction, aAction ) )
494 ::rtl::OUStringBuffer aBuffer( 1024 );
496 aBuffer.appendAscii( "getValue " );
497 aBuffer.append( static_cast< sal_Int32 >( nControlId ) );
498 aBuffer.appendAscii( " ", 1 );
499 aBuffer.append( aAction );
501 sendCommand( aBuffer.makeStringAndClear(),
502 m_pCommandThread->getValueCondition() );
504 return m_pCommandThread->getValue();
507 return uno::Any();
510 void SAL_CALL UnxFilePicker::enableControl( sal_Int16 nControlId, sal_Bool bEnable )
511 throw( uno::RuntimeException )
513 checkFilePicker();
514 ::osl::MutexGuard aGuard( m_aMutex );
516 ::rtl::OUStringBuffer aBuffer( 1024 );
518 aBuffer.appendAscii( "enableControl " );
519 aBuffer.append( static_cast< sal_Int32 >( nControlId ) );
520 aBuffer.appendAscii( bEnable? " true": " false" );
522 sendCommand( aBuffer.makeStringAndClear() );
525 void SAL_CALL UnxFilePicker::setLabel( sal_Int16 nControlId, const ::rtl::OUString &rLabel )
526 throw( uno::RuntimeException )
528 checkFilePicker();
529 ::osl::MutexGuard aGuard( m_aMutex );
531 ::rtl::OUStringBuffer aBuffer( 1024 );
533 aBuffer.appendAscii( "setLabel " );
534 aBuffer.append( static_cast< sal_Int32 >( nControlId ) );
535 aBuffer.appendAscii( " ", 1 );
536 appendEscaped( aBuffer, rLabel );
538 sendCommand( aBuffer.makeStringAndClear() );
541 rtl::OUString SAL_CALL UnxFilePicker::getLabel(sal_Int16 /*nControlId*/)
542 throw ( uno::RuntimeException )
544 // FIXME getLabel() is not yet implemented
545 checkFilePicker();
546 ::osl::MutexGuard aGuard( m_aMutex );
548 // TODO return m_pImpl->getLabel(nControlId);
549 return ::rtl::OUString();
552 /* TODO
553 uno::Sequence<sal_Int16> SAL_CALL UnxFilePicker::getSupportedImageFormats()
554 throw( uno::RuntimeException )
556 checkFilePicker();
557 ::osl::MutexGuard aGuard( m_aMutex );
559 return m_pImpl->getSupportedImageFormats();
562 sal_Int32 SAL_CALL UnxFilePicker::getTargetColorDepth()
563 throw( uno::RuntimeException )
565 checkFilePicker();
566 ::osl::MutexGuard aGuard( m_aMutex );
568 return m_pImpl->getTargetColorDepth();
571 sal_Int32 SAL_CALL UnxFilePicker::getAvailableWidth()
572 throw( uno::RuntimeException )
574 checkFilePicker();
575 ::osl::MutexGuard aGuard( m_aMutex );
577 return m_pImpl->getAvailableWidth();
580 sal_Int32 SAL_CALL UnxFilePicker::getAvailableHeight()
581 throw( uno::RuntimeException )
583 checkFilePicker();
584 ::osl::MutexGuard aGuard( m_aMutex );
586 return m_pImpl->getAvailableHeight();
589 void SAL_CALL UnxFilePicker::setImage( sal_Int16 aImageFormat, const uno::Any &rImage )
590 throw( lang::IllegalArgumentException, uno::RuntimeException )
592 checkFilePicker();
593 ::osl::MutexGuard aGuard( m_aMutex );
595 m_pImpl->setImage( aImageFormat, aImage );
598 sal_Bool SAL_CALL UnxFilePicker::setShowState( sal_Bool bShowState )
599 throw( uno::RuntimeException )
601 checkFilePicker();
602 ::osl::MutexGuard aGuard( m_aMutex );
604 return m_pImpl->setShowState( bShowState );
607 sal_Bool SAL_CALL UnxFilePicker::getShowState()
608 throw( uno::RuntimeException )
610 checkFilePicker();
611 ::osl::MutexGuard aGuard( m_aMutex );
613 return m_pImpl->getShowState();
617 void SAL_CALL UnxFilePicker::initialize( const uno::Sequence<uno::Any> &rArguments )
618 throw( uno::Exception, uno::RuntimeException )
620 initFilePicker();
622 // parameter checking
623 uno::Any aAny;
624 if ( 0 == rArguments.getLength( ) )
625 throw lang::IllegalArgumentException(
626 rtl::OUString::createFromAscii( "no arguments" ),
627 static_cast< XFilePicker* >( this ), 1 );
629 aAny = rArguments[0];
631 if ( ( aAny.getValueType() != ::getCppuType( (sal_Int16*)0 ) ) && ( aAny.getValueType() != ::getCppuType( (sal_Int8*)0 ) ) )
632 throw lang::IllegalArgumentException(
633 rtl::OUString::createFromAscii( "invalid argument type" ),
634 static_cast< XFilePicker* >( this ), 1 );
636 sal_Int16 templateId = -1;
637 aAny >>= templateId;
639 ::rtl::OUString aTypeOpen = ::rtl::OUString::createFromAscii( "setType \"open\"" );
640 ::rtl::OUString aTypeSaveAs = ::rtl::OUString::createFromAscii( "setType \"save\"" );
642 switch ( templateId )
644 case FILEOPEN_SIMPLE:
645 sendCommand( aTypeOpen );
646 break;
648 case FILESAVE_SIMPLE:
649 sendCommand( aTypeSaveAs );
650 break;
652 case FILESAVE_AUTOEXTENSION_PASSWORD:
653 sendCommand( aTypeSaveAs );
655 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION );
656 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD );
657 break;
659 case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
660 sendCommand( aTypeSaveAs );
662 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION );
663 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD );
664 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS );
665 break;
667 case FILESAVE_AUTOEXTENSION_SELECTION:
668 sendCommand( aTypeSaveAs );
670 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION );
671 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_SELECTION );
672 break;
674 case FILESAVE_AUTOEXTENSION_TEMPLATE:
675 sendCommand( aTypeSaveAs );
677 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION );
678 sendAppendControlCommand( ExtendedFilePickerElementIds::LISTBOX_TEMPLATE );
679 break;
681 case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
682 sendCommand( aTypeOpen );
684 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_LINK );
685 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW );
686 sendAppendControlCommand( ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE );
687 break;
689 case FILEOPEN_PLAY:
690 sendCommand( aTypeOpen );
692 sendAppendControlCommand( ExtendedFilePickerElementIds::PUSHBUTTON_PLAY );
693 break;
695 case FILEOPEN_READONLY_VERSION:
696 sendCommand( aTypeOpen );
698 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_READONLY );
699 sendAppendControlCommand( ExtendedFilePickerElementIds::LISTBOX_VERSION );
700 break;
702 case FILEOPEN_LINK_PREVIEW:
703 sendCommand( aTypeOpen );
705 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_LINK );
706 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW );
707 break;
709 case FILESAVE_AUTOEXTENSION:
710 sendCommand( aTypeSaveAs );
712 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION );
713 break;
715 default:
716 throw lang::IllegalArgumentException(
717 rtl::OUString::createFromAscii( "Unknown template" ),
718 static_cast< XFilePicker* >( this ),
719 1 );
723 void SAL_CALL UnxFilePicker::cancel()
724 throw ( uno::RuntimeException )
726 // FIXME cancel() is not implemented
727 checkFilePicker();
728 ::osl::MutexGuard aGuard( m_aMutex );
730 // TODO m_pImpl->cancel();
733 void SAL_CALL UnxFilePicker::disposing( const lang::EventObject &rEvent )
734 throw( uno::RuntimeException )
736 uno::Reference<XFilePickerListener> xFilePickerListener( rEvent.Source, uno::UNO_QUERY );
738 if ( xFilePickerListener.is() )
739 removeFilePickerListener( xFilePickerListener );
742 rtl::OUString SAL_CALL UnxFilePicker::getImplementationName()
743 throw( uno::RuntimeException )
745 return rtl::OUString::createFromAscii( FILE_PICKER_IMPL_NAME );
748 sal_Bool SAL_CALL UnxFilePicker::supportsService( const rtl::OUString& ServiceName )
749 throw( uno::RuntimeException )
751 uno::Sequence< ::rtl::OUString > SupportedServicesNames = FilePicker_getSupportedServiceNames();
753 for ( sal_Int32 n = SupportedServicesNames.getLength(); n--; )
755 if ( SupportedServicesNames[n].compareTo( ServiceName ) == 0 )
756 return sal_True;
759 return sal_False;
762 uno::Sequence< ::rtl::OUString > SAL_CALL UnxFilePicker::getSupportedServiceNames()
763 throw( uno::RuntimeException )
765 return FilePicker_getSupportedServiceNames();
768 void UnxFilePicker::initFilePicker()
770 int aFiledesStdin[2], aFiledesStdout[2];
771 if ( pipe( aFiledesStdin ) < 0 || pipe( aFiledesStdout ) < 0 )
772 return;
774 m_nFilePickerPid = fork();
775 if ( m_nFilePickerPid < 0 )
776 return;
778 if ( m_nFilePickerPid == 0 )
780 // Child...
781 close( aFiledesStdin[1] ); // write end of the pipe
782 dup2( aFiledesStdin[0], 0 );
783 close( aFiledesStdin[0] );
785 close( aFiledesStdout[0] ); // read end of the pipe
786 dup2( aFiledesStdout[1], 1 );
787 close( aFiledesStdout[1] );
789 #if OSL_DEBUG_LEVEL == 0
790 int nRedirect = open( "/dev/null", O_WRONLY );
791 if( nRedirect != -1 )
793 dup2( nRedirect, 2 );
795 #endif
797 // The executable name
798 const char *pFname = "kdefilepicker";
800 // ID of the main window
801 const int nIdLen = 20;
802 char pWinId[nIdLen] = "0";
804 // TODO pass here the real parent (not possible for system dialogs
805 // yet), and default to GetDefDialogParent() only when the real parent
806 // is NULL
807 Window *pParentWin = Application::GetDefDialogParent();
808 if ( pParentWin )
810 const SystemEnvData* pSysData = ((SystemWindow *)pParentWin)->GetSystemData();
811 if ( pSysData )
813 snprintf( pWinId, nIdLen, "%ld", pSysData->aWindow ); // unx only
814 pWinId[nIdLen-1] = 0;
818 // Execute the fpicker implementation
819 execlp( pFname, pFname, "--winid", pWinId, NULL );
821 // Error, finish the child
822 exit( -1 );
825 // Parent continues
826 close( aFiledesStdin[0] );
827 m_nFilePickerWrite = aFiledesStdin[1];
829 close( aFiledesStdout[1] );
830 m_nFilePickerRead = aFiledesStdout[0];
832 // Create the notify thread
833 if ( !m_pNotifyThread )
834 m_pNotifyThread = new UnxFilePickerNotifyThread( this );
836 // Create the command thread
837 if ( !m_pCommandThread )
838 m_pCommandThread = new UnxFilePickerCommandThread( m_pNotifyThread, m_nFilePickerRead );
840 // Start the threads
841 m_pNotifyThread->create();
842 m_pCommandThread->create();
844 return;
847 void UnxFilePicker::checkFilePicker() throw( ::com::sun::star::uno::RuntimeException )
849 if ( m_nFilePickerPid > 0 )
851 // TODO check if external file picker is runnning
853 else
855 throw uno::RuntimeException(
856 ::rtl::OUString::createFromAscii( "the external file picker does not run" ),
857 *this );
861 void UnxFilePicker::sendCommand( const ::rtl::OUString &rCommand )
863 if ( m_nFilePickerWrite < 0 )
864 return;
866 ::rtl::OString aUtfString = OUStringToOString( rCommand + ::rtl::OUString::createFromAscii( "\n" ), RTL_TEXTENCODING_UTF8 );
868 #if OSL_DEBUG_LEVEL > 0
869 ::std::cerr << "UnxFilePicker sent: \"" << aUtfString.getStr() << "\"" << ::std::endl;
870 #endif
872 write( m_nFilePickerWrite, aUtfString.getStr(), aUtfString.getLength() );
875 void UnxFilePicker::sendCommand( const ::rtl::OUString &rCommand, ::osl::Condition &rCondition )
877 rCondition.reset();
879 sendCommand( rCommand );
881 rCondition.wait();
884 void UnxFilePicker::appendEscaped( ::rtl::OUStringBuffer &rBuffer, const ::rtl::OUString &rString )
886 const sal_Unicode *pUnicode = rString.getStr();
887 const sal_Unicode *pEnd = pUnicode + rString.getLength();
889 rBuffer.appendAscii( "\"" , 1 );
891 for ( ; pUnicode != pEnd; ++pUnicode )
893 if ( *pUnicode == '\\' )
894 rBuffer.appendAscii( "\\\\", 2 );
895 else if ( *pUnicode == '"' )
896 rBuffer.appendAscii( "\\\"", 2 );
897 else if ( *pUnicode == '\n' )
898 rBuffer.appendAscii( "\\n", 2 );
899 else
900 rBuffer.append( *pUnicode );
903 rBuffer.appendAscii( "\"", 1 );
906 sal_Bool UnxFilePicker::controlIdInfo( sal_Int16 nControlId, ::rtl::OUString &rType, sal_Int32 &rTitleId )
908 typedef struct {
909 sal_Int16 nId;
910 const ::rtl::OUString *pType;
911 sal_Int32 nTitle;
912 } ElementToName;
914 const ::rtl::OUString aCheckBox( RTL_CONSTASCII_USTRINGPARAM( "checkbox" ) );
915 const ::rtl::OUString aControl( RTL_CONSTASCII_USTRINGPARAM( "control" ) );
916 const ::rtl::OUString aEdit( RTL_CONSTASCII_USTRINGPARAM( "edit" ) );
917 const ::rtl::OUString aLabel( RTL_CONSTASCII_USTRINGPARAM( "label" ) );
918 const ::rtl::OUString aListBox( RTL_CONSTASCII_USTRINGPARAM( "listbox" ) );
919 const ::rtl::OUString aPushButton( RTL_CONSTASCII_USTRINGPARAM( "pushbutton" ) );
921 const ElementToName *pPtr;
922 const ElementToName pArray[] =
924 { CommonFilePickerElementIds::PUSHBUTTON_OK, &aPushButton, 0/*FIXME?*/ },
925 { CommonFilePickerElementIds::PUSHBUTTON_CANCEL, &aPushButton, 0/*FIXME?*/ },
926 { CommonFilePickerElementIds::LISTBOX_FILTER, &aListBox, 0/*FIXME?*/ },
927 { CommonFilePickerElementIds::CONTROL_FILEVIEW, &aControl, 0/*FIXME?*/ },
928 { CommonFilePickerElementIds::EDIT_FILEURL, &aEdit, 0/*FIXME?*/ },
929 { CommonFilePickerElementIds::LISTBOX_FILTER_LABEL, &aLabel, 0/*FIXME?*/ },
930 { CommonFilePickerElementIds::EDIT_FILEURL_LABEL, &aLabel, 0/*FIXME?*/ },
932 { ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, &aCheckBox, STR_SVT_FILEPICKER_AUTO_EXTENSION },
933 { ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, &aCheckBox, STR_SVT_FILEPICKER_PASSWORD },
934 { ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS, &aCheckBox, STR_SVT_FILEPICKER_FILTER_OPTIONS },
935 { ExtendedFilePickerElementIds::CHECKBOX_READONLY, &aCheckBox, STR_SVT_FILEPICKER_READONLY },
936 { ExtendedFilePickerElementIds::CHECKBOX_LINK, &aCheckBox, STR_SVT_FILEPICKER_INSERT_AS_LINK },
937 { ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, &aCheckBox, STR_SVT_FILEPICKER_SHOW_PREVIEW },
938 { ExtendedFilePickerElementIds::PUSHBUTTON_PLAY, &aPushButton, STR_SVT_FILEPICKER_PLAY },
939 { ExtendedFilePickerElementIds::LISTBOX_VERSION, &aListBox, STR_SVT_FILEPICKER_VERSION },
940 { ExtendedFilePickerElementIds::LISTBOX_TEMPLATE, &aListBox, STR_SVT_FILEPICKER_TEMPLATES },
941 { ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE, &aListBox, STR_SVT_FILEPICKER_IMAGE_TEMPLATE },
942 { ExtendedFilePickerElementIds::CHECKBOX_SELECTION, &aCheckBox, STR_SVT_FILEPICKER_SELECTION },
943 { 0, 0, 0 }
946 for ( pPtr = pArray; pPtr->nId && ( pPtr->nId != nControlId ); ++pPtr )
949 if ( pPtr->nId == nControlId )
951 rType = *(pPtr->pType);
952 rTitleId = pPtr->nTitle;
954 return sal_True;
957 return sal_False;
960 sal_Bool UnxFilePicker::controlActionInfo( sal_Int16 nControlAction, ::rtl::OUString &rType )
962 typedef struct {
963 sal_Int16 nId;
964 const ::rtl::OUString pType;
965 } ElementToName;
967 const ElementToName *pPtr;
968 const ElementToName pArray[] =
970 { ControlActions::ADD_ITEM, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "addItem" ) ) },
971 { ControlActions::ADD_ITEMS, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "addItems" ) ) },
972 { ControlActions::DELETE_ITEM, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "deleteItem" ) ) },
973 { ControlActions::DELETE_ITEMS, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "deleteItems" ) ) },
974 { ControlActions::SET_SELECT_ITEM, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "setSelectedItem" ) ) },
975 { ControlActions::GET_ITEMS, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getItems" ) ) },
976 { ControlActions::GET_SELECTED_ITEM, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getSelectedItem" ) ) },
977 { ControlActions::GET_SELECTED_ITEM_INDEX, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getSelectedItemIndex" ) ) },
978 { ControlActions::SET_HELP_URL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "setHelpURL" ) ) },
979 { ControlActions::GET_HELP_URL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getHelpURL" ) ) },
980 { 0, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "noAction" ) ) }
983 for ( pPtr = pArray; pPtr->nId && ( pPtr->nId != nControlAction ); ++pPtr )
986 rType = pPtr->pType;
988 return sal_True;
991 void UnxFilePicker::sendAppendControlCommand( sal_Int16 nControlId )
993 ::rtl::OUString aType;
994 sal_Int32 nTitleId;
996 if ( controlIdInfo( nControlId, aType, nTitleId ) )
998 ::rtl::OUStringBuffer aBuffer( 1024 );
1000 aBuffer.appendAscii( "appendControl " );
1001 aBuffer.append( static_cast< sal_Int32 >( nControlId ) );
1002 aBuffer.appendAscii( " ", 1 );
1003 appendEscaped( aBuffer, aType );
1004 aBuffer.appendAscii( " ", 1 );
1005 appendEscaped( aBuffer, m_pResMgr? String( ResId( nTitleId, *m_pResMgr ) ): String() );
1007 sendCommand( aBuffer.makeStringAndClear() );