Version 4.3.0.0.beta1, tag libreoffice-4.3.0.0.beta1
[LibreOffice.git] / vcl / unx / kde / UnxFilePicker.cxx
blobfd92f1359cede880cff8abde13a7cb529f179e8b
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/ExecutableDialogResults.hpp>
25 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
26 #include <com/sun/star/ui/dialogs/ControlActions.hpp>
28 #include <FPServiceInfo.hxx>
30 #include <cppuhelper/interfacecontainer.h>
31 #include <cppuhelper/supportsservice.hxx>
32 #include <osl/diagnose.h>
33 #include <osl/file.hxx>
34 #include <rtl/ustring.hxx>
35 #include <rtl/ustrbuf.hxx>
36 #include <rtl/bootstrap.hxx>
37 #include <tools/resmgr.hxx>
39 #include <UnxFilePicker.hxx>
40 #include <UnxCommandThread.hxx>
41 #include <UnxNotifyThread.hxx>
43 #include <vcl/fpicker.hrc>
44 #include <vcl/svapp.hxx>
45 #include <vcl/sysdata.hxx>
46 #include <vcl/syswin.hxx>
47 #include <vcl/window.hxx>
49 #include <sys/wait.h>
50 #include <unistd.h>
51 #include <fcntl.h>
52 #include <stdio.h>
54 #include <iostream>
56 #include <config_vclplug.h>
58 using namespace ::com::sun::star;
60 using namespace ::com::sun::star::ui::dialogs;
61 using namespace ::com::sun::star::ui::dialogs::TemplateDescription;
63 // helper functions
65 namespace
67 uno::Sequence<OUString> SAL_CALL FilePicker_getSupportedServiceNames()
69 uno::Sequence<OUString> aRet(3);
70 aRet[0] = "com.sun.star.ui.dialogs.FilePicker";
71 aRet[1] = "com.sun.star.ui.dialogs.SystemFilePicker";
72 #if ENABLE_TDE
73 aRet[2] = "com.sun.star.ui.dialogs.TDEFilePicker";
74 #else // ENABLE_TDE
75 aRet[2] = "com.sun.star.ui.dialogs.KDEFilePicker";
76 #endif // ENABLE_TDE
77 return aRet;
81 // UnxFilePicker
83 UnxFilePicker::UnxFilePicker( const uno::Reference<uno::XComponentContext>& )
84 : UnxFilePicker_Base( m_rbHelperMtx ),
85 m_nFilePickerPid( -1 ),
86 m_nFilePickerWrite( -1 ),
87 m_nFilePickerRead( -1 ),
88 m_pNotifyThread( NULL ),
89 m_pCommandThread( NULL ),
90 m_pResMgr( ResMgr::CreateResMgr("fps_office") )
94 UnxFilePicker::~UnxFilePicker()
96 if ( m_nFilePickerPid > 0 )
98 sendCommand( OUString( "exit" ) );
99 waitpid( m_nFilePickerPid, NULL, 0 );
102 if ( m_pCommandThread )
104 m_pCommandThread->join();
106 delete m_pCommandThread, m_pCommandThread = NULL;
109 if ( m_pNotifyThread )
111 m_pNotifyThread->exit();
113 m_pNotifyThread->join();
115 delete m_pNotifyThread, m_pNotifyThread = NULL;
118 if ( m_nFilePickerWrite >= 0 )
119 close( m_nFilePickerWrite );
121 if ( m_nFilePickerRead >= 0 )
122 close( m_nFilePickerRead );
124 delete m_pResMgr, m_pResMgr = NULL;
127 void SAL_CALL UnxFilePicker::addFilePickerListener( const uno::Reference<XFilePickerListener>& xListener )
128 throw( uno::RuntimeException, std::exception )
130 OSL_ASSERT( m_pNotifyThread );
131 osl::MutexGuard aGuard( m_aMutex );
133 m_pNotifyThread->addFilePickerListener( xListener );
136 void SAL_CALL UnxFilePicker::removeFilePickerListener( const uno::Reference<XFilePickerListener>& xListener )
137 throw( uno::RuntimeException, std::exception )
139 OSL_ASSERT( m_pNotifyThread );
140 osl::MutexGuard aGuard( m_aMutex );
142 m_pNotifyThread->removeFilePickerListener( xListener );
145 void SAL_CALL UnxFilePicker::setTitle( const OUString &rTitle )
146 throw( uno::RuntimeException, std::exception )
148 checkFilePicker();
149 ::osl::MutexGuard aGuard( m_aMutex );
151 OUStringBuffer aBuffer( 1024 );
153 aBuffer.appendAscii( "setTitle " );
154 appendEscaped( aBuffer, rTitle );
156 sendCommand( aBuffer.makeStringAndClear() );
159 sal_Int16 SAL_CALL UnxFilePicker::execute()
160 throw( uno::RuntimeException, std::exception )
162 checkFilePicker();
164 // this is _not_ an osl::Condition, see i#93366
165 m_pCommandThread->execCondition().reset();
167 sendCommand( OUString( "exec" ));
169 m_pCommandThread->execCondition().wait();
171 return m_pCommandThread->result()
172 ? css::ui::dialogs::ExecutableDialogResults::OK
173 : css::ui::dialogs::ExecutableDialogResults::CANCEL;
176 void SAL_CALL UnxFilePicker::setMultiSelectionMode( sal_Bool bMode )
177 throw( uno::RuntimeException, std::exception )
179 checkFilePicker();
180 ::osl::MutexGuard aGuard( m_aMutex );
182 OUString aString = bMode?
183 OUString( "setMultiSelection true" ):
184 OUString( "setMultiSelection false" );
186 sendCommand( aString );
189 void SAL_CALL UnxFilePicker::setDefaultName( const OUString &rName )
190 throw( uno::RuntimeException, std::exception )
192 checkFilePicker();
193 ::osl::MutexGuard aGuard( m_aMutex );
195 OUStringBuffer aBuffer( 1024 );
197 aBuffer.appendAscii( "setDefaultName " );
198 appendEscaped( aBuffer, rName );
200 sendCommand( aBuffer.makeStringAndClear() );
203 void SAL_CALL UnxFilePicker::setDisplayDirectory( const OUString &rDirectory )
204 throw( uno::RuntimeException, std::exception )
206 checkFilePicker();
207 ::osl::MutexGuard aGuard( m_aMutex );
209 OUStringBuffer aBuffer( 1024 );
211 aBuffer.appendAscii( "setDirectory " );
212 appendEscaped( aBuffer, rDirectory );
214 sendCommand( aBuffer.makeStringAndClear() );
217 OUString SAL_CALL UnxFilePicker::getDisplayDirectory()
218 throw( uno::RuntimeException, std::exception )
220 checkFilePicker();
221 ::osl::MutexGuard aGuard( m_aMutex );
223 sendCommand( OUString( "getDirectory" ),
224 m_pCommandThread->getDirectoryCondition() );
226 return m_pCommandThread->getDirectory();
229 uno::Sequence< OUString > SAL_CALL UnxFilePicker::getFiles()
230 throw( uno::RuntimeException, std::exception )
232 checkFilePicker();
233 ::osl::MutexGuard aGuard( m_aMutex );
235 sendCommand( OUString( "getFiles" ),
236 m_pCommandThread->getFilesCondition() );
238 return m_pCommandThread->getFiles();
241 void SAL_CALL UnxFilePicker::appendFilter( const OUString &rTitle, const OUString &rFilter )
242 throw( lang::IllegalArgumentException, uno::RuntimeException, std::exception )
244 checkFilePicker();
245 ::osl::MutexGuard aGuard( m_aMutex );
247 OUStringBuffer aBuffer( 1024 );
249 aBuffer.appendAscii( "appendFilter " );
250 appendEscaped( aBuffer, rTitle );
251 aBuffer.appendAscii( " ", 1 );
252 appendEscaped( aBuffer, rFilter );
254 sendCommand( aBuffer.makeStringAndClear() );
257 void SAL_CALL UnxFilePicker::setCurrentFilter( const OUString &rTitle )
258 throw( lang::IllegalArgumentException, uno::RuntimeException, std::exception )
260 checkFilePicker();
261 ::osl::MutexGuard aGuard( m_aMutex );
263 OUStringBuffer aBuffer( 1024 );
265 aBuffer.appendAscii( "setCurrentFilter " );
266 appendEscaped( aBuffer, rTitle );
268 sendCommand( aBuffer.makeStringAndClear() );
271 OUString SAL_CALL UnxFilePicker::getCurrentFilter()
272 throw( uno::RuntimeException, std::exception )
274 checkFilePicker();
275 ::osl::MutexGuard aGuard( m_aMutex );
277 sendCommand( OUString( "getCurrentFilter" ),
278 m_pCommandThread->getCurrentFilterCondition() );
280 return m_pCommandThread->getCurrentFilter();
283 void SAL_CALL UnxFilePicker::appendFilterGroup( const OUString &rGroupTitle, const uno::Sequence<beans::StringPair> &rFilters )
284 throw( lang::IllegalArgumentException, uno::RuntimeException, std::exception )
286 checkFilePicker();
287 ::osl::MutexGuard aGuard( m_aMutex );
289 OUStringBuffer aBuffer( 1024 );
291 aBuffer.appendAscii( "appendFilterGroup " );
292 appendEscaped( aBuffer, rGroupTitle );
294 for ( sal_Int32 i = 0; i < rFilters.getLength(); ++i )
296 beans::StringPair aPair = rFilters[i];
298 aBuffer.appendAscii( " ", 1 );
299 appendEscaped( aBuffer, aPair.First );
300 aBuffer.appendAscii( " ", 1 );
301 appendEscaped( aBuffer, aPair.Second );
304 sendCommand( aBuffer.makeStringAndClear() );
307 void SAL_CALL UnxFilePicker::setValue( sal_Int16 nControlId, sal_Int16 nControlAction, const uno::Any &rValue )
308 throw( uno::RuntimeException, std::exception )
310 checkFilePicker();
311 ::osl::MutexGuard aGuard( m_aMutex );
313 OUString aType;
314 OUString aAction;
315 sal_Int32 nTitleId;
317 if ( controlIdInfo( nControlId, aType, nTitleId ) && controlActionInfo( nControlAction, aAction ) )
319 OUStringBuffer aBuffer( 1024 );
321 aBuffer.appendAscii( "setValue " );
322 aBuffer.append( static_cast< sal_Int32 >( nControlId ) );
323 aBuffer.appendAscii( " ", 1 );
324 aBuffer.append( aAction );
326 if ( aType == "checkbox" )
328 bool bControlValue;
329 if ( ( rValue >>= bControlValue ) && bControlValue )
330 aBuffer.appendAscii( " true" );
331 else
332 aBuffer.appendAscii( " false" );
334 else if ( aType == "listbox" )
336 switch ( nControlAction )
338 case ControlActions::ADD_ITEM:
339 case ControlActions::SET_HELP_URL:
341 OUString aString;
342 if ( rValue >>= aString )
344 aBuffer.appendAscii( " ", 1 );
345 appendEscaped( aBuffer, aString );
348 break;
350 case ControlActions::ADD_ITEMS:
352 uno::Sequence< OUString > aSequence;
353 if ( rValue >>= aSequence )
355 for ( sal_Int32 nIdx = 0; nIdx < aSequence.getLength(); ++nIdx )
357 aBuffer.appendAscii( " ", 1 );
358 appendEscaped( aBuffer, aSequence[nIdx] );
363 break;
365 case ControlActions::DELETE_ITEM:
366 case ControlActions::SET_SELECT_ITEM:
368 sal_Int32 nInt;
369 if ( rValue >>= nInt )
371 aBuffer.appendAscii( " ", 1 );
372 aBuffer.append( nInt );
375 break;
377 default:
378 // nothing
379 break;
382 // TODO else if push button...
384 sendCommand( aBuffer.makeStringAndClear() );
388 uno::Any SAL_CALL UnxFilePicker::getValue( sal_Int16 nControlId, sal_Int16 nControlAction )
389 throw( uno::RuntimeException, std::exception )
391 checkFilePicker();
392 ::osl::MutexGuard aGuard( m_aMutex );
394 OUString aAction;
396 if ( controlActionInfo( nControlAction, aAction ) )
398 OUStringBuffer aBuffer( 1024 );
400 aBuffer.appendAscii( "getValue " );
401 aBuffer.append( static_cast< sal_Int32 >( nControlId ) );
402 aBuffer.appendAscii( " ", 1 );
403 aBuffer.append( aAction );
405 sendCommand( aBuffer.makeStringAndClear(),
406 m_pCommandThread->getValueCondition() );
408 return m_pCommandThread->getValue();
411 return uno::Any();
414 void SAL_CALL UnxFilePicker::enableControl( sal_Int16 nControlId, sal_Bool bEnable )
415 throw( uno::RuntimeException, std::exception )
417 checkFilePicker();
418 ::osl::MutexGuard aGuard( m_aMutex );
420 OUStringBuffer aBuffer( 1024 );
422 aBuffer.appendAscii( "enableControl " );
423 aBuffer.append( static_cast< sal_Int32 >( nControlId ) );
424 aBuffer.appendAscii( bEnable? " true": " false" );
426 sendCommand( aBuffer.makeStringAndClear() );
429 void SAL_CALL UnxFilePicker::setLabel( sal_Int16 nControlId, const OUString &rLabel )
430 throw( uno::RuntimeException, std::exception )
432 checkFilePicker();
433 ::osl::MutexGuard aGuard( m_aMutex );
435 OUStringBuffer aBuffer( 1024 );
437 aBuffer.appendAscii( "setLabel " );
438 aBuffer.append( static_cast< sal_Int32 >( nControlId ) );
439 aBuffer.appendAscii( " ", 1 );
440 appendEscaped( aBuffer, rLabel );
442 sendCommand( aBuffer.makeStringAndClear() );
445 OUString SAL_CALL UnxFilePicker::getLabel(sal_Int16 /*nControlId*/)
446 throw ( uno::RuntimeException, std::exception )
448 // FIXME getLabel() is not yet implemented
449 checkFilePicker();
450 ::osl::MutexGuard aGuard( m_aMutex );
452 // TODO return m_pImpl->getLabel(nControlId);
453 return OUString();
456 /* TODO
457 uno::Sequence<sal_Int16> SAL_CALL UnxFilePicker::getSupportedImageFormats()
458 throw( uno::RuntimeException )
460 checkFilePicker();
461 ::osl::MutexGuard aGuard( m_aMutex );
463 return m_pImpl->getSupportedImageFormats();
466 sal_Int32 SAL_CALL UnxFilePicker::getTargetColorDepth()
467 throw( uno::RuntimeException )
469 checkFilePicker();
470 ::osl::MutexGuard aGuard( m_aMutex );
472 return m_pImpl->getTargetColorDepth();
475 sal_Int32 SAL_CALL UnxFilePicker::getAvailableWidth()
476 throw( uno::RuntimeException )
478 checkFilePicker();
479 ::osl::MutexGuard aGuard( m_aMutex );
481 return m_pImpl->getAvailableWidth();
484 sal_Int32 SAL_CALL UnxFilePicker::getAvailableHeight()
485 throw( uno::RuntimeException )
487 checkFilePicker();
488 ::osl::MutexGuard aGuard( m_aMutex );
490 return m_pImpl->getAvailableHeight();
493 void SAL_CALL UnxFilePicker::setImage( sal_Int16 aImageFormat, const uno::Any &rImage )
494 throw( lang::IllegalArgumentException, uno::RuntimeException )
496 checkFilePicker();
497 ::osl::MutexGuard aGuard( m_aMutex );
499 m_pImpl->setImage( aImageFormat, aImage );
502 sal_Bool SAL_CALL UnxFilePicker::setShowState( sal_Bool bShowState )
503 throw( uno::RuntimeException )
505 checkFilePicker();
506 ::osl::MutexGuard aGuard( m_aMutex );
508 return m_pImpl->setShowState( bShowState );
511 sal_Bool SAL_CALL UnxFilePicker::getShowState()
512 throw( uno::RuntimeException )
514 checkFilePicker();
515 ::osl::MutexGuard aGuard( m_aMutex );
517 return m_pImpl->getShowState();
521 void SAL_CALL UnxFilePicker::initialize( const uno::Sequence<uno::Any> &rArguments )
522 throw( uno::Exception, uno::RuntimeException, std::exception )
524 initFilePicker();
526 // parameter checking
527 uno::Any aAny;
528 if ( 0 == rArguments.getLength( ) )
529 throw lang::IllegalArgumentException(
530 OUString( "no arguments" ),
531 static_cast< XFilePicker2* >( this ), 1 );
533 aAny = rArguments[0];
535 if ( ( aAny.getValueType() != cppu::UnoType<sal_Int16>::get()) && ( aAny.getValueType() != cppu::UnoType<sal_Int8>::get()) )
536 throw lang::IllegalArgumentException(
537 OUString( "invalid argument type" ),
538 static_cast< XFilePicker2* >( this ), 1 );
540 sal_Int16 templateId = -1;
541 aAny >>= templateId;
543 OUString aTypeOpen( "setType \"open\"" );
544 OUString aTypeSaveAs( "setType \"save\"" );
546 switch ( templateId )
548 case FILEOPEN_SIMPLE:
549 sendCommand( aTypeOpen );
550 break;
552 case FILESAVE_SIMPLE:
553 sendCommand( aTypeSaveAs );
554 break;
556 case FILESAVE_AUTOEXTENSION_PASSWORD:
557 sendCommand( aTypeSaveAs );
559 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION );
560 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD );
561 break;
563 case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
564 sendCommand( aTypeSaveAs );
566 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION );
567 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD );
568 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS );
569 break;
571 case FILESAVE_AUTOEXTENSION_SELECTION:
572 sendCommand( aTypeSaveAs );
574 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION );
575 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_SELECTION );
576 break;
578 case FILESAVE_AUTOEXTENSION_TEMPLATE:
579 sendCommand( aTypeSaveAs );
581 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION );
582 sendAppendControlCommand( ExtendedFilePickerElementIds::LISTBOX_TEMPLATE );
583 break;
585 case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
586 sendCommand( aTypeOpen );
588 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_LINK );
589 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW );
590 sendAppendControlCommand( ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE );
591 break;
593 case FILEOPEN_PLAY:
594 sendCommand( aTypeOpen );
596 sendAppendControlCommand( ExtendedFilePickerElementIds::PUSHBUTTON_PLAY );
597 break;
599 case FILEOPEN_READONLY_VERSION:
600 sendCommand( aTypeOpen );
602 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_READONLY );
603 sendAppendControlCommand( ExtendedFilePickerElementIds::LISTBOX_VERSION );
604 break;
606 case FILEOPEN_LINK_PREVIEW:
607 sendCommand( aTypeOpen );
609 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_LINK );
610 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW );
611 break;
613 case FILESAVE_AUTOEXTENSION:
614 sendCommand( aTypeSaveAs );
616 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION );
617 break;
619 default:
620 throw lang::IllegalArgumentException(
621 OUString( "Unknown template" ),
622 static_cast< XFilePicker2* >( this ),
623 1 );
627 void SAL_CALL UnxFilePicker::cancel()
628 throw ( uno::RuntimeException, std::exception )
630 // FIXME cancel() is not implemented
631 checkFilePicker();
632 ::osl::MutexGuard aGuard( m_aMutex );
634 // TODO m_pImpl->cancel();
637 void SAL_CALL UnxFilePicker::disposing( const lang::EventObject &rEvent )
638 throw( uno::RuntimeException )
640 uno::Reference<XFilePickerListener> xFilePickerListener( rEvent.Source, uno::UNO_QUERY );
642 if ( xFilePickerListener.is() )
643 removeFilePickerListener( xFilePickerListener );
646 OUString SAL_CALL UnxFilePicker::getImplementationName()
647 throw( uno::RuntimeException, std::exception )
649 return OUString( FILE_PICKER_IMPL_NAME );
652 sal_Bool SAL_CALL UnxFilePicker::supportsService( const OUString& ServiceName )
653 throw( uno::RuntimeException, std::exception )
655 return cppu::supportsService(this, ServiceName);
658 uno::Sequence< OUString > SAL_CALL UnxFilePicker::getSupportedServiceNames()
659 throw( uno::RuntimeException, std::exception )
661 return FilePicker_getSupportedServiceNames();
664 void UnxFilePicker::initFilePicker()
666 int aFiledesStdin[2], aFiledesStdout[2];
667 if ( pipe( aFiledesStdin ) < 0 || pipe( aFiledesStdout ) < 0 )
668 return;
670 m_nFilePickerPid = fork();
671 if ( m_nFilePickerPid < 0 )
672 return;
674 if ( m_nFilePickerPid == 0 )
676 // Child...
677 close( aFiledesStdin[1] ); // write end of the pipe
678 dup2( aFiledesStdin[0], 0 );
679 close( aFiledesStdin[0] );
681 close( aFiledesStdout[0] ); // read end of the pipe
682 dup2( aFiledesStdout[1], 1 );
683 close( aFiledesStdout[1] );
685 #if OSL_DEBUG_LEVEL == 0
686 int nRedirect = open( "/dev/null", O_WRONLY );
687 if( nRedirect != -1 )
689 dup2( nRedirect, 2 );
691 #endif
693 // The executable name
694 #if ENABLE_TDE
695 OUString helperurl("${ORIGIN}/tdefilepicker");
696 #else // ENABLE_TDE
697 OUString helperurl("${ORIGIN}/kdefilepicker");
698 #endif // ENABLE_TDE
699 rtl::Bootstrap::expandMacros( helperurl );
700 OUString helperpath;
701 osl::FileBase::getSystemPathFromFileURL( helperurl, helperpath );
702 OString helper( OUStringToOString( helperpath, osl_getThreadTextEncoding()));
704 // ID of the main window
705 const int nIdLen = 20;
706 char pWinId[nIdLen] = "0";
708 // TODO pass here the real parent (not possible for system dialogs
709 // yet), and default to GetDefDialogParent() only when the real parent
710 // is NULL
711 Window *pParentWin = Application::GetDefDialogParent();
712 if ( pParentWin )
714 const SystemEnvData* pSysData = ((SystemWindow *)pParentWin)->GetSystemData();
715 if ( pSysData )
717 snprintf( pWinId, nIdLen, "%ld", pSysData->aWindow ); // unx only
718 pWinId[nIdLen-1] = 0;
722 // Execute the fpicker implementation
723 execlp( helper.getStr(), helper.getStr(), "--winid", pWinId, NULL );
725 // Error, finish the child
726 exit( -1 );
729 // Parent continues
730 close( aFiledesStdin[0] );
731 m_nFilePickerWrite = aFiledesStdin[1];
733 close( aFiledesStdout[1] );
734 m_nFilePickerRead = aFiledesStdout[0];
736 // Create the notify thread
737 if ( !m_pNotifyThread )
738 m_pNotifyThread = new UnxFilePickerNotifyThread( this );
740 // Create the command thread
741 if ( !m_pCommandThread )
742 m_pCommandThread = new UnxFilePickerCommandThread( m_pNotifyThread, m_nFilePickerRead );
744 // Start the threads
745 m_pNotifyThread->create();
746 m_pCommandThread->create();
748 return;
751 void UnxFilePicker::checkFilePicker() throw( ::com::sun::star::uno::RuntimeException )
753 if ( m_nFilePickerPid > 0 )
755 // TODO check if external file picker is runnning
757 else
759 throw uno::RuntimeException(
760 OUString( "the external file picker does not run" ),
761 *this );
765 void UnxFilePicker::sendCommand( const OUString &rCommand )
767 if ( m_nFilePickerWrite < 0 )
768 return;
770 OString aUtfString = OUStringToOString( rCommand + "\n", RTL_TEXTENCODING_UTF8 );
772 #if OSL_DEBUG_LEVEL > 0
773 ::std::cerr << "UnxFilePicker sent: \"" << aUtfString.getStr() << "\"" << ::std::endl;
774 #endif
776 write( m_nFilePickerWrite, aUtfString.getStr(), aUtfString.getLength() );
779 void UnxFilePicker::sendCommand( const OUString &rCommand, ::osl::Condition &rCondition )
781 rCondition.reset();
783 sendCommand( rCommand );
785 rCondition.wait();
788 void UnxFilePicker::appendEscaped( OUStringBuffer &rBuffer, const OUString &rString )
790 const sal_Unicode *pUnicode = rString.getStr();
791 const sal_Unicode *pEnd = pUnicode + rString.getLength();
793 rBuffer.appendAscii( "\"" , 1 );
795 for ( ; pUnicode != pEnd; ++pUnicode )
797 if ( *pUnicode == '\\' )
798 rBuffer.appendAscii( "\\\\", 2 );
799 else if ( *pUnicode == '"' )
800 rBuffer.appendAscii( "\\\"", 2 );
801 else if ( *pUnicode == '\n' )
802 rBuffer.appendAscii( "\\n", 2 );
803 else
804 rBuffer.append( *pUnicode );
807 rBuffer.appendAscii( "\"", 1 );
810 bool UnxFilePicker::controlIdInfo( sal_Int16 nControlId, OUString &rType, sal_Int32 &rTitleId )
812 typedef struct {
813 sal_Int16 nId;
814 const OUString *pType;
815 sal_Int32 nTitle;
816 } ElementToName;
818 const OUString aCheckBox( "checkbox" );
819 const OUString aControl( "control" );
820 const OUString aEdit( "edit" );
821 const OUString aLabel( "label" );
822 const OUString aListBox( "listbox" );
823 const OUString aPushButton( "pushbutton" );
825 const ElementToName *pPtr;
826 const ElementToName pArray[] =
828 { CommonFilePickerElementIds::PUSHBUTTON_OK, &aPushButton, 0/*FIXME?*/ },
829 { CommonFilePickerElementIds::PUSHBUTTON_CANCEL, &aPushButton, 0/*FIXME?*/ },
830 { CommonFilePickerElementIds::LISTBOX_FILTER, &aListBox, 0/*FIXME?*/ },
831 { CommonFilePickerElementIds::CONTROL_FILEVIEW, &aControl, 0/*FIXME?*/ },
832 { CommonFilePickerElementIds::EDIT_FILEURL, &aEdit, 0/*FIXME?*/ },
833 { CommonFilePickerElementIds::LISTBOX_FILTER_LABEL, &aLabel, 0/*FIXME?*/ },
834 { CommonFilePickerElementIds::EDIT_FILEURL_LABEL, &aLabel, 0/*FIXME?*/ },
836 { ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, &aCheckBox, STR_SVT_FILEPICKER_AUTO_EXTENSION },
837 { ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, &aCheckBox, STR_SVT_FILEPICKER_PASSWORD },
838 { ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS, &aCheckBox, STR_SVT_FILEPICKER_FILTER_OPTIONS },
839 { ExtendedFilePickerElementIds::CHECKBOX_READONLY, &aCheckBox, STR_SVT_FILEPICKER_READONLY },
840 { ExtendedFilePickerElementIds::CHECKBOX_LINK, &aCheckBox, STR_SVT_FILEPICKER_INSERT_AS_LINK },
841 { ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, &aCheckBox, STR_SVT_FILEPICKER_SHOW_PREVIEW },
842 { ExtendedFilePickerElementIds::PUSHBUTTON_PLAY, &aPushButton, STR_SVT_FILEPICKER_PLAY },
843 { ExtendedFilePickerElementIds::LISTBOX_VERSION, &aListBox, STR_SVT_FILEPICKER_VERSION },
844 { ExtendedFilePickerElementIds::LISTBOX_TEMPLATE, &aListBox, STR_SVT_FILEPICKER_TEMPLATES },
845 { ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE, &aListBox, STR_SVT_FILEPICKER_IMAGE_TEMPLATE },
846 { ExtendedFilePickerElementIds::CHECKBOX_SELECTION, &aCheckBox, STR_SVT_FILEPICKER_SELECTION },
847 { 0, 0, 0 }
850 for ( pPtr = pArray; pPtr->nId && ( pPtr->nId != nControlId ); ++pPtr )
853 if ( pPtr->nId == nControlId )
855 rType = *(pPtr->pType);
856 rTitleId = pPtr->nTitle;
858 return true;
861 return false;
864 bool UnxFilePicker::controlActionInfo( sal_Int16 nControlAction, OUString &rType )
866 typedef struct {
867 sal_Int16 nId;
868 const OUString pType;
869 } ElementToName;
871 const ElementToName *pPtr;
872 const ElementToName pArray[] =
874 { ControlActions::ADD_ITEM, OUString( "addItem" ) },
875 { ControlActions::ADD_ITEMS, OUString( "addItems" ) },
876 { ControlActions::DELETE_ITEM, OUString( "deleteItem" ) },
877 { ControlActions::DELETE_ITEMS, OUString( "deleteItems" ) },
878 { ControlActions::SET_SELECT_ITEM, OUString( "setSelectedItem" ) },
879 { ControlActions::GET_ITEMS, OUString( "getItems" ) },
880 { ControlActions::GET_SELECTED_ITEM, OUString( "getSelectedItem" ) },
881 { ControlActions::GET_SELECTED_ITEM_INDEX, OUString( "getSelectedItemIndex" ) },
882 { ControlActions::SET_HELP_URL, OUString( "setHelpURL" ) },
883 { ControlActions::GET_HELP_URL, OUString( "getHelpURL" ) },
884 { 0, OUString( "noAction" ) }
887 for ( pPtr = pArray; pPtr->nId && ( pPtr->nId != nControlAction ); ++pPtr )
890 rType = pPtr->pType;
892 return true;
895 void UnxFilePicker::sendAppendControlCommand( sal_Int16 nControlId )
897 OUString aType;
898 sal_Int32 nTitleId;
900 if ( controlIdInfo( nControlId, aType, nTitleId ) )
902 OUStringBuffer aBuffer( 1024 );
904 aBuffer.appendAscii( "appendControl " );
905 aBuffer.append( static_cast< sal_Int32 >( nControlId ) );
906 aBuffer.appendAscii( " ", 1 );
907 appendEscaped( aBuffer, aType );
908 aBuffer.appendAscii( " ", 1 );
909 appendEscaped( aBuffer, m_pResMgr? ResId(nTitleId, *m_pResMgr).toString(): OUString() );
911 sendCommand( aBuffer.makeStringAndClear() );
915 uno::Sequence< OUString > SAL_CALL UnxFilePicker::getSelectedFiles()
916 throw( uno::RuntimeException, std::exception )
918 return getFiles();
921 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */