Version 4.2.0.1, tag libreoffice-4.2.0.1
[LibreOffice.git] / vcl / unx / kde / UnxFilePicker.cxx
bloba990f1fe1cc097c21eaa9ff4cc3fd98de8249519
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/lang/DisposedException.hpp>
21 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
22 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
23 #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
24 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
25 #include <com/sun/star/ui/dialogs/ControlActions.hpp>
27 #include <FPServiceInfo.hxx>
29 #include <cppuhelper/interfacecontainer.h>
30 #include <cppuhelper/supportsservice.hxx>
31 #include <osl/diagnose.h>
32 #include <osl/file.hxx>
33 #include <rtl/ustring.hxx>
34 #include <rtl/ustrbuf.hxx>
35 #include <rtl/bootstrap.hxx>
36 #include <tools/resmgr.hxx>
38 #include <UnxFilePicker.hxx>
39 #include <UnxCommandThread.hxx>
40 #include <UnxNotifyThread.hxx>
42 #include <vcl/fpicker.hrc>
43 #include <vcl/svapp.hxx>
44 #include <vcl/sysdata.hxx>
45 #include <vcl/syswin.hxx>
46 #include <vcl/window.hxx>
48 #include <sys/wait.h>
49 #include <unistd.h>
50 #include <fcntl.h>
51 #include <stdio.h>
53 #include <iostream>
55 #include <config_vclplug.h>
57 using namespace ::com::sun::star;
59 using namespace ::com::sun::star::ui::dialogs;
60 using namespace ::com::sun::star::ui::dialogs::TemplateDescription;
62 //////////////////////////////////////////////////////////////////////////
63 // helper functions
64 //////////////////////////////////////////////////////////////////////////
66 namespace
68 uno::Sequence<OUString> SAL_CALL FilePicker_getSupportedServiceNames()
70 uno::Sequence<OUString> aRet(3);
71 aRet[0] = "com.sun.star.ui.dialogs.FilePicker";
72 aRet[1] = "com.sun.star.ui.dialogs.SystemFilePicker";
73 #if ENABLE_TDE
74 aRet[2] = "com.sun.star.ui.dialogs.TDEFilePicker";
75 #else // ENABLE_TDE
76 aRet[2] = "com.sun.star.ui.dialogs.KDEFilePicker";
77 #endif // ENABLE_TDE
78 return aRet;
82 //////////////////////////////////////////////////////////////////////////
83 // UnxFilePicker
84 //////////////////////////////////////////////////////////////////////////
86 UnxFilePicker::UnxFilePicker( const uno::Reference<uno::XComponentContext>& )
87 : UnxFilePicker_Base( m_rbHelperMtx ),
88 m_nFilePickerPid( -1 ),
89 m_nFilePickerWrite( -1 ),
90 m_nFilePickerRead( -1 ),
91 m_pNotifyThread( NULL ),
92 m_pCommandThread( NULL ),
93 m_pResMgr( ResMgr::CreateResMgr("fps_office") )
97 UnxFilePicker::~UnxFilePicker()
99 if ( m_nFilePickerPid > 0 )
101 sendCommand( OUString( "exit" ) );
102 waitpid( m_nFilePickerPid, NULL, 0 );
105 if ( m_pCommandThread )
107 m_pCommandThread->join();
109 delete m_pCommandThread, m_pCommandThread = NULL;
112 if ( m_pNotifyThread )
114 m_pNotifyThread->exit();
116 m_pNotifyThread->join();
118 delete m_pNotifyThread, m_pNotifyThread = NULL;
121 if ( m_nFilePickerWrite >= 0 )
122 close( m_nFilePickerWrite );
124 if ( m_nFilePickerRead >= 0 )
125 close( m_nFilePickerRead );
127 delete m_pResMgr, m_pResMgr = NULL;
130 void SAL_CALL UnxFilePicker::addFilePickerListener( const uno::Reference<XFilePickerListener>& xListener )
131 throw( uno::RuntimeException )
133 OSL_ASSERT( m_pNotifyThread );
134 osl::MutexGuard aGuard( m_aMutex );
136 m_pNotifyThread->addFilePickerListener( xListener );
139 void SAL_CALL UnxFilePicker::removeFilePickerListener( const uno::Reference<XFilePickerListener>& xListener )
140 throw( uno::RuntimeException )
142 OSL_ASSERT( m_pNotifyThread );
143 osl::MutexGuard aGuard( m_aMutex );
145 m_pNotifyThread->removeFilePickerListener( xListener );
148 void SAL_CALL UnxFilePicker::setTitle( const OUString &rTitle )
149 throw( uno::RuntimeException )
151 checkFilePicker();
152 ::osl::MutexGuard aGuard( m_aMutex );
154 OUStringBuffer aBuffer( 1024 );
156 aBuffer.appendAscii( "setTitle " );
157 appendEscaped( aBuffer, rTitle );
159 sendCommand( aBuffer.makeStringAndClear() );
162 sal_Int16 SAL_CALL UnxFilePicker::execute()
163 throw( uno::RuntimeException )
165 checkFilePicker();
167 // this is _not_ an osl::Condition, see i#93366
168 m_pCommandThread->execCondition().reset();
170 sendCommand( OUString( "exec" ));
172 m_pCommandThread->execCondition().wait();
174 return m_pCommandThread->result();
177 void SAL_CALL UnxFilePicker::setMultiSelectionMode( sal_Bool bMode )
178 throw( uno::RuntimeException )
180 checkFilePicker();
181 ::osl::MutexGuard aGuard( m_aMutex );
183 OUString aString = bMode?
184 OUString( "setMultiSelection true" ):
185 OUString( "setMultiSelection false" );
187 sendCommand( aString );
190 void SAL_CALL UnxFilePicker::setDefaultName( const OUString &rName )
191 throw( uno::RuntimeException )
193 checkFilePicker();
194 ::osl::MutexGuard aGuard( m_aMutex );
196 OUStringBuffer aBuffer( 1024 );
198 aBuffer.appendAscii( "setDefaultName " );
199 appendEscaped( aBuffer, rName );
201 sendCommand( aBuffer.makeStringAndClear() );
204 void SAL_CALL UnxFilePicker::setDisplayDirectory( const OUString &rDirectory )
205 throw( uno::RuntimeException )
207 checkFilePicker();
208 ::osl::MutexGuard aGuard( m_aMutex );
210 OUStringBuffer aBuffer( 1024 );
212 aBuffer.appendAscii( "setDirectory " );
213 appendEscaped( aBuffer, rDirectory );
215 sendCommand( aBuffer.makeStringAndClear() );
218 OUString SAL_CALL UnxFilePicker::getDisplayDirectory()
219 throw( uno::RuntimeException )
221 checkFilePicker();
222 ::osl::MutexGuard aGuard( m_aMutex );
224 sendCommand( OUString( "getDirectory" ),
225 m_pCommandThread->getDirectoryCondition() );
227 return m_pCommandThread->getDirectory();
230 uno::Sequence< OUString > SAL_CALL UnxFilePicker::getFiles()
231 throw( uno::RuntimeException )
233 checkFilePicker();
234 ::osl::MutexGuard aGuard( m_aMutex );
236 sendCommand( OUString( "getFiles" ),
237 m_pCommandThread->getFilesCondition() );
239 return m_pCommandThread->getFiles();
242 void SAL_CALL UnxFilePicker::appendFilter( const OUString &rTitle, const OUString &rFilter )
243 throw( lang::IllegalArgumentException, uno::RuntimeException )
245 checkFilePicker();
246 ::osl::MutexGuard aGuard( m_aMutex );
248 OUStringBuffer aBuffer( 1024 );
250 aBuffer.appendAscii( "appendFilter " );
251 appendEscaped( aBuffer, rTitle );
252 aBuffer.appendAscii( " ", 1 );
253 appendEscaped( aBuffer, rFilter );
255 sendCommand( aBuffer.makeStringAndClear() );
258 void SAL_CALL UnxFilePicker::setCurrentFilter( const OUString &rTitle )
259 throw( lang::IllegalArgumentException, uno::RuntimeException )
261 checkFilePicker();
262 ::osl::MutexGuard aGuard( m_aMutex );
264 OUStringBuffer aBuffer( 1024 );
266 aBuffer.appendAscii( "setCurrentFilter " );
267 appendEscaped( aBuffer, rTitle );
269 sendCommand( aBuffer.makeStringAndClear() );
272 OUString SAL_CALL UnxFilePicker::getCurrentFilter()
273 throw( uno::RuntimeException )
275 checkFilePicker();
276 ::osl::MutexGuard aGuard( m_aMutex );
278 sendCommand( OUString( "getCurrentFilter" ),
279 m_pCommandThread->getCurrentFilterCondition() );
281 return m_pCommandThread->getCurrentFilter();
284 void SAL_CALL UnxFilePicker::appendFilterGroup( const OUString &rGroupTitle, const uno::Sequence<beans::StringPair> &rFilters )
285 throw( lang::IllegalArgumentException, uno::RuntimeException )
287 checkFilePicker();
288 ::osl::MutexGuard aGuard( m_aMutex );
290 OUStringBuffer aBuffer( 1024 );
292 aBuffer.appendAscii( "appendFilterGroup " );
293 appendEscaped( aBuffer, rGroupTitle );
295 for ( sal_Int32 i = 0; i < rFilters.getLength(); ++i )
297 beans::StringPair aPair = rFilters[i];
299 aBuffer.appendAscii( " ", 1 );
300 appendEscaped( aBuffer, aPair.First );
301 aBuffer.appendAscii( " ", 1 );
302 appendEscaped( aBuffer, aPair.Second );
305 sendCommand( aBuffer.makeStringAndClear() );
308 void SAL_CALL UnxFilePicker::setValue( sal_Int16 nControlId, sal_Int16 nControlAction, const uno::Any &rValue )
309 throw( uno::RuntimeException )
311 checkFilePicker();
312 ::osl::MutexGuard aGuard( m_aMutex );
314 OUString aType;
315 OUString aAction;
316 sal_Int32 nTitleId;
318 if ( controlIdInfo( nControlId, aType, nTitleId ) && controlActionInfo( nControlAction, aAction ) )
320 OUStringBuffer aBuffer( 1024 );
322 aBuffer.appendAscii( "setValue " );
323 aBuffer.append( static_cast< sal_Int32 >( nControlId ) );
324 aBuffer.appendAscii( " ", 1 );
325 aBuffer.append( aAction );
327 if ( aType == "checkbox" )
329 sal_Bool bControlValue;
330 if ( ( rValue >>= bControlValue ) && bControlValue )
331 aBuffer.appendAscii( " true" );
332 else
333 aBuffer.appendAscii( " false" );
335 else if ( aType == "listbox" )
337 switch ( nControlAction )
339 case ControlActions::ADD_ITEM:
340 case ControlActions::SET_HELP_URL:
342 OUString aString;
343 if ( rValue >>= aString )
345 aBuffer.appendAscii( " ", 1 );
346 appendEscaped( aBuffer, aString );
349 break;
351 case ControlActions::ADD_ITEMS:
353 uno::Sequence< OUString > aSequence;
354 if ( rValue >>= aSequence )
356 for ( sal_Int32 nIdx = 0; nIdx < aSequence.getLength(); ++nIdx )
358 aBuffer.appendAscii( " ", 1 );
359 appendEscaped( aBuffer, aSequence[nIdx] );
364 break;
366 case ControlActions::DELETE_ITEM:
367 case ControlActions::SET_SELECT_ITEM:
369 sal_Int32 nInt;
370 if ( rValue >>= nInt )
372 aBuffer.appendAscii( " ", 1 );
373 aBuffer.append( nInt );
376 break;
378 default:
379 // nothing
380 break;
383 // TODO else if push button...
385 sendCommand( aBuffer.makeStringAndClear() );
389 uno::Any SAL_CALL UnxFilePicker::getValue( sal_Int16 nControlId, sal_Int16 nControlAction )
390 throw( uno::RuntimeException )
392 checkFilePicker();
393 ::osl::MutexGuard aGuard( m_aMutex );
395 OUString aAction;
397 if ( controlActionInfo( nControlAction, aAction ) )
399 OUStringBuffer aBuffer( 1024 );
401 aBuffer.appendAscii( "getValue " );
402 aBuffer.append( static_cast< sal_Int32 >( nControlId ) );
403 aBuffer.appendAscii( " ", 1 );
404 aBuffer.append( aAction );
406 sendCommand( aBuffer.makeStringAndClear(),
407 m_pCommandThread->getValueCondition() );
409 return m_pCommandThread->getValue();
412 return uno::Any();
415 void SAL_CALL UnxFilePicker::enableControl( sal_Int16 nControlId, sal_Bool bEnable )
416 throw( uno::RuntimeException )
418 checkFilePicker();
419 ::osl::MutexGuard aGuard( m_aMutex );
421 OUStringBuffer aBuffer( 1024 );
423 aBuffer.appendAscii( "enableControl " );
424 aBuffer.append( static_cast< sal_Int32 >( nControlId ) );
425 aBuffer.appendAscii( bEnable? " true": " false" );
427 sendCommand( aBuffer.makeStringAndClear() );
430 void SAL_CALL UnxFilePicker::setLabel( sal_Int16 nControlId, const OUString &rLabel )
431 throw( uno::RuntimeException )
433 checkFilePicker();
434 ::osl::MutexGuard aGuard( m_aMutex );
436 OUStringBuffer aBuffer( 1024 );
438 aBuffer.appendAscii( "setLabel " );
439 aBuffer.append( static_cast< sal_Int32 >( nControlId ) );
440 aBuffer.appendAscii( " ", 1 );
441 appendEscaped( aBuffer, rLabel );
443 sendCommand( aBuffer.makeStringAndClear() );
446 OUString SAL_CALL UnxFilePicker::getLabel(sal_Int16 /*nControlId*/)
447 throw ( uno::RuntimeException )
449 // FIXME getLabel() is not yet implemented
450 checkFilePicker();
451 ::osl::MutexGuard aGuard( m_aMutex );
453 // TODO return m_pImpl->getLabel(nControlId);
454 return OUString();
457 /* TODO
458 uno::Sequence<sal_Int16> SAL_CALL UnxFilePicker::getSupportedImageFormats()
459 throw( uno::RuntimeException )
461 checkFilePicker();
462 ::osl::MutexGuard aGuard( m_aMutex );
464 return m_pImpl->getSupportedImageFormats();
467 sal_Int32 SAL_CALL UnxFilePicker::getTargetColorDepth()
468 throw( uno::RuntimeException )
470 checkFilePicker();
471 ::osl::MutexGuard aGuard( m_aMutex );
473 return m_pImpl->getTargetColorDepth();
476 sal_Int32 SAL_CALL UnxFilePicker::getAvailableWidth()
477 throw( uno::RuntimeException )
479 checkFilePicker();
480 ::osl::MutexGuard aGuard( m_aMutex );
482 return m_pImpl->getAvailableWidth();
485 sal_Int32 SAL_CALL UnxFilePicker::getAvailableHeight()
486 throw( uno::RuntimeException )
488 checkFilePicker();
489 ::osl::MutexGuard aGuard( m_aMutex );
491 return m_pImpl->getAvailableHeight();
494 void SAL_CALL UnxFilePicker::setImage( sal_Int16 aImageFormat, const uno::Any &rImage )
495 throw( lang::IllegalArgumentException, uno::RuntimeException )
497 checkFilePicker();
498 ::osl::MutexGuard aGuard( m_aMutex );
500 m_pImpl->setImage( aImageFormat, aImage );
503 sal_Bool SAL_CALL UnxFilePicker::setShowState( sal_Bool bShowState )
504 throw( uno::RuntimeException )
506 checkFilePicker();
507 ::osl::MutexGuard aGuard( m_aMutex );
509 return m_pImpl->setShowState( bShowState );
512 sal_Bool SAL_CALL UnxFilePicker::getShowState()
513 throw( uno::RuntimeException )
515 checkFilePicker();
516 ::osl::MutexGuard aGuard( m_aMutex );
518 return m_pImpl->getShowState();
522 void SAL_CALL UnxFilePicker::initialize( const uno::Sequence<uno::Any> &rArguments )
523 throw( uno::Exception, uno::RuntimeException )
525 initFilePicker();
527 // parameter checking
528 uno::Any aAny;
529 if ( 0 == rArguments.getLength( ) )
530 throw lang::IllegalArgumentException(
531 OUString( "no arguments" ),
532 static_cast< XFilePicker2* >( this ), 1 );
534 aAny = rArguments[0];
536 if ( ( aAny.getValueType() != ::getCppuType( (sal_Int16*)0 ) ) && ( aAny.getValueType() != ::getCppuType( (sal_Int8*)0 ) ) )
537 throw lang::IllegalArgumentException(
538 OUString( "invalid argument type" ),
539 static_cast< XFilePicker2* >( this ), 1 );
541 sal_Int16 templateId = -1;
542 aAny >>= templateId;
544 OUString aTypeOpen( "setType \"open\"" );
545 OUString aTypeSaveAs( "setType \"save\"" );
547 switch ( templateId )
549 case FILEOPEN_SIMPLE:
550 sendCommand( aTypeOpen );
551 break;
553 case FILESAVE_SIMPLE:
554 sendCommand( aTypeSaveAs );
555 break;
557 case FILESAVE_AUTOEXTENSION_PASSWORD:
558 sendCommand( aTypeSaveAs );
560 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION );
561 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD );
562 break;
564 case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
565 sendCommand( aTypeSaveAs );
567 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION );
568 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD );
569 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS );
570 break;
572 case FILESAVE_AUTOEXTENSION_SELECTION:
573 sendCommand( aTypeSaveAs );
575 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION );
576 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_SELECTION );
577 break;
579 case FILESAVE_AUTOEXTENSION_TEMPLATE:
580 sendCommand( aTypeSaveAs );
582 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION );
583 sendAppendControlCommand( ExtendedFilePickerElementIds::LISTBOX_TEMPLATE );
584 break;
586 case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
587 sendCommand( aTypeOpen );
589 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_LINK );
590 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW );
591 sendAppendControlCommand( ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE );
592 break;
594 case FILEOPEN_PLAY:
595 sendCommand( aTypeOpen );
597 sendAppendControlCommand( ExtendedFilePickerElementIds::PUSHBUTTON_PLAY );
598 break;
600 case FILEOPEN_READONLY_VERSION:
601 sendCommand( aTypeOpen );
603 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_READONLY );
604 sendAppendControlCommand( ExtendedFilePickerElementIds::LISTBOX_VERSION );
605 break;
607 case FILEOPEN_LINK_PREVIEW:
608 sendCommand( aTypeOpen );
610 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_LINK );
611 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW );
612 break;
614 case FILESAVE_AUTOEXTENSION:
615 sendCommand( aTypeSaveAs );
617 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION );
618 break;
620 default:
621 throw lang::IllegalArgumentException(
622 OUString( "Unknown template" ),
623 static_cast< XFilePicker2* >( this ),
624 1 );
628 void SAL_CALL UnxFilePicker::cancel()
629 throw ( uno::RuntimeException )
631 // FIXME cancel() is not implemented
632 checkFilePicker();
633 ::osl::MutexGuard aGuard( m_aMutex );
635 // TODO m_pImpl->cancel();
638 void SAL_CALL UnxFilePicker::disposing( const lang::EventObject &rEvent )
639 throw( uno::RuntimeException )
641 uno::Reference<XFilePickerListener> xFilePickerListener( rEvent.Source, uno::UNO_QUERY );
643 if ( xFilePickerListener.is() )
644 removeFilePickerListener( xFilePickerListener );
647 OUString SAL_CALL UnxFilePicker::getImplementationName()
648 throw( uno::RuntimeException )
650 return OUString( FILE_PICKER_IMPL_NAME );
653 sal_Bool SAL_CALL UnxFilePicker::supportsService( const OUString& ServiceName )
654 throw( uno::RuntimeException )
656 return cppu::supportsService(this, ServiceName);
659 uno::Sequence< OUString > SAL_CALL UnxFilePicker::getSupportedServiceNames()
660 throw( uno::RuntimeException )
662 return FilePicker_getSupportedServiceNames();
665 void UnxFilePicker::initFilePicker()
667 int aFiledesStdin[2], aFiledesStdout[2];
668 if ( pipe( aFiledesStdin ) < 0 || pipe( aFiledesStdout ) < 0 )
669 return;
671 m_nFilePickerPid = fork();
672 if ( m_nFilePickerPid < 0 )
673 return;
675 if ( m_nFilePickerPid == 0 )
677 // Child...
678 close( aFiledesStdin[1] ); // write end of the pipe
679 dup2( aFiledesStdin[0], 0 );
680 close( aFiledesStdin[0] );
682 close( aFiledesStdout[0] ); // read end of the pipe
683 dup2( aFiledesStdout[1], 1 );
684 close( aFiledesStdout[1] );
686 #if OSL_DEBUG_LEVEL == 0
687 int nRedirect = open( "/dev/null", O_WRONLY );
688 if( nRedirect != -1 )
690 dup2( nRedirect, 2 );
692 #endif
694 // The executable name
695 #if ENABLE_TDE
696 OUString helperurl("${ORIGIN}/tdefilepicker");
697 #else // ENABLE_TDE
698 OUString helperurl("${ORIGIN}/kdefilepicker");
699 #endif // ENABLE_TDE
700 rtl::Bootstrap::expandMacros( helperurl );
701 OUString helperpath;
702 osl::FileBase::getSystemPathFromFileURL( helperurl, helperpath );
703 OString helper( OUStringToOString( helperpath, osl_getThreadTextEncoding()));
705 // ID of the main window
706 const int nIdLen = 20;
707 char pWinId[nIdLen] = "0";
709 // TODO pass here the real parent (not possible for system dialogs
710 // yet), and default to GetDefDialogParent() only when the real parent
711 // is NULL
712 Window *pParentWin = Application::GetDefDialogParent();
713 if ( pParentWin )
715 const SystemEnvData* pSysData = ((SystemWindow *)pParentWin)->GetSystemData();
716 if ( pSysData )
718 snprintf( pWinId, nIdLen, "%ld", pSysData->aWindow ); // unx only
719 pWinId[nIdLen-1] = 0;
723 // Execute the fpicker implementation
724 execlp( helper.getStr(), helper.getStr(), "--winid", pWinId, NULL );
726 // Error, finish the child
727 exit( -1 );
730 // Parent continues
731 close( aFiledesStdin[0] );
732 m_nFilePickerWrite = aFiledesStdin[1];
734 close( aFiledesStdout[1] );
735 m_nFilePickerRead = aFiledesStdout[0];
737 // Create the notify thread
738 if ( !m_pNotifyThread )
739 m_pNotifyThread = new UnxFilePickerNotifyThread( this );
741 // Create the command thread
742 if ( !m_pCommandThread )
743 m_pCommandThread = new UnxFilePickerCommandThread( m_pNotifyThread, m_nFilePickerRead );
745 // Start the threads
746 m_pNotifyThread->create();
747 m_pCommandThread->create();
749 return;
752 void UnxFilePicker::checkFilePicker() throw( ::com::sun::star::uno::RuntimeException )
754 if ( m_nFilePickerPid > 0 )
756 // TODO check if external file picker is runnning
758 else
760 throw uno::RuntimeException(
761 OUString( "the external file picker does not run" ),
762 *this );
766 void UnxFilePicker::sendCommand( const OUString &rCommand )
768 if ( m_nFilePickerWrite < 0 )
769 return;
771 OString aUtfString = OUStringToOString( rCommand + OUString( "\n" ), RTL_TEXTENCODING_UTF8 );
773 #if OSL_DEBUG_LEVEL > 0
774 ::std::cerr << "UnxFilePicker sent: \"" << aUtfString.getStr() << "\"" << ::std::endl;
775 #endif
777 write( m_nFilePickerWrite, aUtfString.getStr(), aUtfString.getLength() );
780 void UnxFilePicker::sendCommand( const OUString &rCommand, ::osl::Condition &rCondition )
782 rCondition.reset();
784 sendCommand( rCommand );
786 rCondition.wait();
789 void UnxFilePicker::appendEscaped( OUStringBuffer &rBuffer, const OUString &rString )
791 const sal_Unicode *pUnicode = rString.getStr();
792 const sal_Unicode *pEnd = pUnicode + rString.getLength();
794 rBuffer.appendAscii( "\"" , 1 );
796 for ( ; pUnicode != pEnd; ++pUnicode )
798 if ( *pUnicode == '\\' )
799 rBuffer.appendAscii( "\\\\", 2 );
800 else if ( *pUnicode == '"' )
801 rBuffer.appendAscii( "\\\"", 2 );
802 else if ( *pUnicode == '\n' )
803 rBuffer.appendAscii( "\\n", 2 );
804 else
805 rBuffer.append( *pUnicode );
808 rBuffer.appendAscii( "\"", 1 );
811 sal_Bool UnxFilePicker::controlIdInfo( sal_Int16 nControlId, OUString &rType, sal_Int32 &rTitleId )
813 typedef struct {
814 sal_Int16 nId;
815 const OUString *pType;
816 sal_Int32 nTitle;
817 } ElementToName;
819 const OUString aCheckBox( "checkbox" );
820 const OUString aControl( "control" );
821 const OUString aEdit( "edit" );
822 const OUString aLabel( "label" );
823 const OUString aListBox( "listbox" );
824 const OUString aPushButton( "pushbutton" );
826 const ElementToName *pPtr;
827 const ElementToName pArray[] =
829 { CommonFilePickerElementIds::PUSHBUTTON_OK, &aPushButton, 0/*FIXME?*/ },
830 { CommonFilePickerElementIds::PUSHBUTTON_CANCEL, &aPushButton, 0/*FIXME?*/ },
831 { CommonFilePickerElementIds::LISTBOX_FILTER, &aListBox, 0/*FIXME?*/ },
832 { CommonFilePickerElementIds::CONTROL_FILEVIEW, &aControl, 0/*FIXME?*/ },
833 { CommonFilePickerElementIds::EDIT_FILEURL, &aEdit, 0/*FIXME?*/ },
834 { CommonFilePickerElementIds::LISTBOX_FILTER_LABEL, &aLabel, 0/*FIXME?*/ },
835 { CommonFilePickerElementIds::EDIT_FILEURL_LABEL, &aLabel, 0/*FIXME?*/ },
837 { ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, &aCheckBox, STR_SVT_FILEPICKER_AUTO_EXTENSION },
838 { ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, &aCheckBox, STR_SVT_FILEPICKER_PASSWORD },
839 { ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS, &aCheckBox, STR_SVT_FILEPICKER_FILTER_OPTIONS },
840 { ExtendedFilePickerElementIds::CHECKBOX_READONLY, &aCheckBox, STR_SVT_FILEPICKER_READONLY },
841 { ExtendedFilePickerElementIds::CHECKBOX_LINK, &aCheckBox, STR_SVT_FILEPICKER_INSERT_AS_LINK },
842 { ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, &aCheckBox, STR_SVT_FILEPICKER_SHOW_PREVIEW },
843 { ExtendedFilePickerElementIds::PUSHBUTTON_PLAY, &aPushButton, STR_SVT_FILEPICKER_PLAY },
844 { ExtendedFilePickerElementIds::LISTBOX_VERSION, &aListBox, STR_SVT_FILEPICKER_VERSION },
845 { ExtendedFilePickerElementIds::LISTBOX_TEMPLATE, &aListBox, STR_SVT_FILEPICKER_TEMPLATES },
846 { ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE, &aListBox, STR_SVT_FILEPICKER_IMAGE_TEMPLATE },
847 { ExtendedFilePickerElementIds::CHECKBOX_SELECTION, &aCheckBox, STR_SVT_FILEPICKER_SELECTION },
848 { 0, 0, 0 }
851 for ( pPtr = pArray; pPtr->nId && ( pPtr->nId != nControlId ); ++pPtr )
854 if ( pPtr->nId == nControlId )
856 rType = *(pPtr->pType);
857 rTitleId = pPtr->nTitle;
859 return sal_True;
862 return sal_False;
865 sal_Bool UnxFilePicker::controlActionInfo( sal_Int16 nControlAction, OUString &rType )
867 typedef struct {
868 sal_Int16 nId;
869 const OUString pType;
870 } ElementToName;
872 const ElementToName *pPtr;
873 const ElementToName pArray[] =
875 { ControlActions::ADD_ITEM, OUString( "addItem" ) },
876 { ControlActions::ADD_ITEMS, OUString( "addItems" ) },
877 { ControlActions::DELETE_ITEM, OUString( "deleteItem" ) },
878 { ControlActions::DELETE_ITEMS, OUString( "deleteItems" ) },
879 { ControlActions::SET_SELECT_ITEM, OUString( "setSelectedItem" ) },
880 { ControlActions::GET_ITEMS, OUString( "getItems" ) },
881 { ControlActions::GET_SELECTED_ITEM, OUString( "getSelectedItem" ) },
882 { ControlActions::GET_SELECTED_ITEM_INDEX, OUString( "getSelectedItemIndex" ) },
883 { ControlActions::SET_HELP_URL, OUString( "setHelpURL" ) },
884 { ControlActions::GET_HELP_URL, OUString( "getHelpURL" ) },
885 { 0, OUString( "noAction" ) }
888 for ( pPtr = pArray; pPtr->nId && ( pPtr->nId != nControlAction ); ++pPtr )
891 rType = pPtr->pType;
893 return sal_True;
896 void UnxFilePicker::sendAppendControlCommand( sal_Int16 nControlId )
898 OUString aType;
899 sal_Int32 nTitleId;
901 if ( controlIdInfo( nControlId, aType, nTitleId ) )
903 OUStringBuffer aBuffer( 1024 );
905 aBuffer.appendAscii( "appendControl " );
906 aBuffer.append( static_cast< sal_Int32 >( nControlId ) );
907 aBuffer.appendAscii( " ", 1 );
908 appendEscaped( aBuffer, aType );
909 aBuffer.appendAscii( " ", 1 );
910 appendEscaped( aBuffer, m_pResMgr? ResId(nTitleId, *m_pResMgr).toString(): OUString() );
912 sendCommand( aBuffer.makeStringAndClear() );
916 uno::Sequence< OUString > SAL_CALL UnxFilePicker::getSelectedFiles()
917 throw( uno::RuntimeException )
919 return getFiles();
922 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */