Branch libreoffice-5-0-4
[LibreOffice.git] / vcl / unx / kde / UnxFilePicker.cxx
blobfaeb4e01fba05cb1e516e1a6b6c0a808c64c7305
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;
80 void appendEscaped( OUStringBuffer &rBuffer, const OUString &rString )
82 const sal_Unicode *pUnicode = rString.getStr();
83 const sal_Unicode *pEnd = pUnicode + rString.getLength();
85 rBuffer.appendAscii( "\"" , 1 );
87 for ( ; pUnicode != pEnd; ++pUnicode )
89 if ( *pUnicode == '\\' )
90 rBuffer.appendAscii( "\\\\", 2 );
91 else if ( *pUnicode == '"' )
92 rBuffer.appendAscii( "\\\"", 2 );
93 else if ( *pUnicode == '\n' )
94 rBuffer.appendAscii( "\\n", 2 );
95 else
96 rBuffer.append( *pUnicode );
99 rBuffer.appendAscii( "\"", 1 );
102 bool controlIdInfo( sal_Int16 nControlId, OUString &rType, sal_Int32 &rTitleId )
104 typedef struct {
105 sal_Int16 nId;
106 const OUString *pType;
107 sal_Int32 nTitle;
108 } ElementToName;
110 const OUString aCheckBox( "checkbox" );
111 const OUString aControl( "control" );
112 const OUString aEdit( "edit" );
113 const OUString aLabel( "label" );
114 const OUString aListBox( "listbox" );
115 const OUString aPushButton( "pushbutton" );
117 const ElementToName *pPtr;
118 const ElementToName pArray[] =
120 { CommonFilePickerElementIds::PUSHBUTTON_OK, &aPushButton, 0/*FIXME?*/ },
121 { CommonFilePickerElementIds::PUSHBUTTON_CANCEL, &aPushButton, 0/*FIXME?*/ },
122 { CommonFilePickerElementIds::LISTBOX_FILTER, &aListBox, 0/*FIXME?*/ },
123 { CommonFilePickerElementIds::CONTROL_FILEVIEW, &aControl, 0/*FIXME?*/ },
124 { CommonFilePickerElementIds::EDIT_FILEURL, &aEdit, 0/*FIXME?*/ },
125 { CommonFilePickerElementIds::LISTBOX_FILTER_LABEL, &aLabel, 0/*FIXME?*/ },
126 { CommonFilePickerElementIds::EDIT_FILEURL_LABEL, &aLabel, 0/*FIXME?*/ },
128 { ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, &aCheckBox, STR_SVT_FILEPICKER_AUTO_EXTENSION },
129 { ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, &aCheckBox, STR_SVT_FILEPICKER_PASSWORD },
130 { ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS, &aCheckBox, STR_SVT_FILEPICKER_FILTER_OPTIONS },
131 { ExtendedFilePickerElementIds::CHECKBOX_READONLY, &aCheckBox, STR_SVT_FILEPICKER_READONLY },
132 { ExtendedFilePickerElementIds::CHECKBOX_LINK, &aCheckBox, STR_SVT_FILEPICKER_INSERT_AS_LINK },
133 { ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, &aCheckBox, STR_SVT_FILEPICKER_SHOW_PREVIEW },
134 { ExtendedFilePickerElementIds::PUSHBUTTON_PLAY, &aPushButton, STR_SVT_FILEPICKER_PLAY },
135 { ExtendedFilePickerElementIds::LISTBOX_VERSION, &aListBox, STR_SVT_FILEPICKER_VERSION },
136 { ExtendedFilePickerElementIds::LISTBOX_TEMPLATE, &aListBox, STR_SVT_FILEPICKER_TEMPLATES },
137 { ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE, &aListBox, STR_SVT_FILEPICKER_IMAGE_TEMPLATE },
138 { ExtendedFilePickerElementIds::CHECKBOX_SELECTION, &aCheckBox, STR_SVT_FILEPICKER_SELECTION },
139 { 0, 0, 0 }
142 for ( pPtr = pArray; pPtr->nId && ( pPtr->nId != nControlId ); ++pPtr )
145 if ( pPtr->nId == nControlId )
147 rType = *(pPtr->pType);
148 rTitleId = pPtr->nTitle;
150 return true;
153 return false;
156 bool controlActionInfo( sal_Int16 nControlAction, OUString &rType )
158 typedef struct {
159 sal_Int16 nId;
160 const OUString pType;
161 } ElementToName;
163 const ElementToName *pPtr;
164 const ElementToName pArray[] =
166 { ControlActions::ADD_ITEM, OUString( "addItem" ) },
167 { ControlActions::ADD_ITEMS, OUString( "addItems" ) },
168 { ControlActions::DELETE_ITEM, OUString( "deleteItem" ) },
169 { ControlActions::DELETE_ITEMS, OUString( "deleteItems" ) },
170 { ControlActions::SET_SELECT_ITEM, OUString( "setSelectedItem" ) },
171 { ControlActions::GET_ITEMS, OUString( "getItems" ) },
172 { ControlActions::GET_SELECTED_ITEM, OUString( "getSelectedItem" ) },
173 { ControlActions::GET_SELECTED_ITEM_INDEX, OUString( "getSelectedItemIndex" ) },
174 { ControlActions::SET_HELP_URL, OUString( "setHelpURL" ) },
175 { ControlActions::GET_HELP_URL, OUString( "getHelpURL" ) },
176 { 0, OUString( "noAction" ) }
179 for ( pPtr = pArray; pPtr->nId && ( pPtr->nId != nControlAction ); ++pPtr )
182 rType = pPtr->pType;
184 return true;
189 // UnxFilePicker
191 UnxFilePicker::UnxFilePicker( const uno::Reference<uno::XComponentContext>& )
192 : UnxFilePicker_Base( m_rbHelperMtx ),
193 m_nFilePickerPid( -1 ),
194 m_nFilePickerWrite( -1 ),
195 m_nFilePickerRead( -1 ),
196 m_pNotifyThread( NULL ),
197 m_pCommandThread( NULL ),
198 m_pResMgr( ResMgr::CreateResMgr("fps_office") )
202 UnxFilePicker::~UnxFilePicker()
204 if ( m_nFilePickerPid > 0 )
206 sendCommand( OUString( "exit" ) );
207 waitpid( m_nFilePickerPid, NULL, 0 );
210 if ( m_pCommandThread )
212 m_pCommandThread->join();
214 delete m_pCommandThread, m_pCommandThread = NULL;
217 if ( m_pNotifyThread )
219 m_pNotifyThread->exit();
221 m_pNotifyThread->join();
223 delete m_pNotifyThread, m_pNotifyThread = NULL;
226 if ( m_nFilePickerWrite >= 0 )
227 close( m_nFilePickerWrite );
229 if ( m_nFilePickerRead >= 0 )
230 close( m_nFilePickerRead );
232 delete m_pResMgr, m_pResMgr = NULL;
235 void SAL_CALL UnxFilePicker::addFilePickerListener( const uno::Reference<XFilePickerListener>& xListener )
236 throw( uno::RuntimeException, std::exception )
238 OSL_ASSERT( m_pNotifyThread );
239 osl::MutexGuard aGuard( m_aMutex );
241 m_pNotifyThread->addFilePickerListener( xListener );
244 void SAL_CALL UnxFilePicker::removeFilePickerListener( const uno::Reference<XFilePickerListener>& xListener )
245 throw( uno::RuntimeException, std::exception )
247 OSL_ASSERT( m_pNotifyThread );
248 osl::MutexGuard aGuard( m_aMutex );
250 m_pNotifyThread->removeFilePickerListener( xListener );
253 void SAL_CALL UnxFilePicker::setTitle( const OUString &rTitle )
254 throw( uno::RuntimeException, std::exception )
256 checkFilePicker();
257 ::osl::MutexGuard aGuard( m_aMutex );
259 OUStringBuffer aBuffer( 1024 );
261 aBuffer.appendAscii( "setTitle " );
262 appendEscaped( aBuffer, rTitle );
264 sendCommand( aBuffer.makeStringAndClear() );
267 sal_Int16 SAL_CALL UnxFilePicker::execute()
268 throw( uno::RuntimeException, std::exception )
270 checkFilePicker();
272 // this is _not_ an osl::Condition, see i#93366
273 m_pCommandThread->execCondition().reset();
275 sendCommand( OUString( "exec" ));
277 m_pCommandThread->execCondition().wait();
279 return m_pCommandThread->result()
280 ? css::ui::dialogs::ExecutableDialogResults::OK
281 : css::ui::dialogs::ExecutableDialogResults::CANCEL;
284 void SAL_CALL UnxFilePicker::setMultiSelectionMode( sal_Bool bMode )
285 throw( uno::RuntimeException, std::exception )
287 checkFilePicker();
288 ::osl::MutexGuard aGuard( m_aMutex );
290 OUString aString = bMode?
291 OUString( "setMultiSelection true" ):
292 OUString( "setMultiSelection false" );
294 sendCommand( aString );
297 void SAL_CALL UnxFilePicker::setDefaultName( const OUString &rName )
298 throw( uno::RuntimeException, std::exception )
300 checkFilePicker();
301 ::osl::MutexGuard aGuard( m_aMutex );
303 OUStringBuffer aBuffer( 1024 );
305 aBuffer.appendAscii( "setDefaultName " );
306 appendEscaped( aBuffer, rName );
308 sendCommand( aBuffer.makeStringAndClear() );
311 void SAL_CALL UnxFilePicker::setDisplayDirectory( const OUString &rDirectory )
312 throw( uno::RuntimeException, std::exception )
314 checkFilePicker();
315 ::osl::MutexGuard aGuard( m_aMutex );
317 OUStringBuffer aBuffer( 1024 );
319 aBuffer.appendAscii( "setDirectory " );
320 appendEscaped( aBuffer, rDirectory );
322 sendCommand( aBuffer.makeStringAndClear() );
325 OUString SAL_CALL UnxFilePicker::getDisplayDirectory()
326 throw( uno::RuntimeException, std::exception )
328 checkFilePicker();
329 ::osl::MutexGuard aGuard( m_aMutex );
331 sendCommand( OUString( "getDirectory" ),
332 m_pCommandThread->getDirectoryCondition() );
334 return m_pCommandThread->getDirectory();
337 uno::Sequence< OUString > SAL_CALL UnxFilePicker::getFiles()
338 throw( uno::RuntimeException, std::exception )
340 checkFilePicker();
341 ::osl::MutexGuard aGuard( m_aMutex );
343 sendCommand( OUString( "getFiles" ),
344 m_pCommandThread->getFilesCondition() );
346 return m_pCommandThread->getFiles();
349 void SAL_CALL UnxFilePicker::appendFilter( const OUString &rTitle, const OUString &rFilter )
350 throw( lang::IllegalArgumentException, uno::RuntimeException, std::exception )
352 checkFilePicker();
353 ::osl::MutexGuard aGuard( m_aMutex );
355 OUStringBuffer aBuffer( 1024 );
357 aBuffer.appendAscii( "appendFilter " );
358 appendEscaped( aBuffer, rTitle );
359 aBuffer.appendAscii( " ", 1 );
360 appendEscaped( aBuffer, rFilter );
362 sendCommand( aBuffer.makeStringAndClear() );
365 void SAL_CALL UnxFilePicker::setCurrentFilter( const OUString &rTitle )
366 throw( lang::IllegalArgumentException, uno::RuntimeException, std::exception )
368 checkFilePicker();
369 ::osl::MutexGuard aGuard( m_aMutex );
371 OUStringBuffer aBuffer( 1024 );
373 aBuffer.appendAscii( "setCurrentFilter " );
374 appendEscaped( aBuffer, rTitle );
376 sendCommand( aBuffer.makeStringAndClear() );
379 OUString SAL_CALL UnxFilePicker::getCurrentFilter()
380 throw( uno::RuntimeException, std::exception )
382 checkFilePicker();
383 ::osl::MutexGuard aGuard( m_aMutex );
385 sendCommand( OUString( "getCurrentFilter" ),
386 m_pCommandThread->getCurrentFilterCondition() );
388 return m_pCommandThread->getCurrentFilter();
391 void SAL_CALL UnxFilePicker::appendFilterGroup( const OUString &rGroupTitle, const uno::Sequence<beans::StringPair> &rFilters )
392 throw( lang::IllegalArgumentException, uno::RuntimeException, std::exception )
394 checkFilePicker();
395 ::osl::MutexGuard aGuard( m_aMutex );
397 OUStringBuffer aBuffer( 1024 );
399 aBuffer.appendAscii( "appendFilterGroup " );
400 appendEscaped( aBuffer, rGroupTitle );
402 for ( sal_Int32 i = 0; i < rFilters.getLength(); ++i )
404 beans::StringPair aPair = rFilters[i];
406 aBuffer.appendAscii( " ", 1 );
407 appendEscaped( aBuffer, aPair.First );
408 aBuffer.appendAscii( " ", 1 );
409 appendEscaped( aBuffer, aPair.Second );
412 sendCommand( aBuffer.makeStringAndClear() );
415 void SAL_CALL UnxFilePicker::setValue( sal_Int16 nControlId, sal_Int16 nControlAction, const uno::Any &rValue )
416 throw( uno::RuntimeException, std::exception )
418 checkFilePicker();
419 ::osl::MutexGuard aGuard( m_aMutex );
421 OUString aType;
422 OUString aAction;
423 sal_Int32 nTitleId;
425 if ( controlIdInfo( nControlId, aType, nTitleId ) && controlActionInfo( nControlAction, aAction ) )
427 OUStringBuffer aBuffer( 1024 );
429 aBuffer.appendAscii( "setValue " );
430 aBuffer.append( static_cast< sal_Int32 >( nControlId ) );
431 aBuffer.appendAscii( " ", 1 );
432 aBuffer.append( aAction );
434 if ( aType == "checkbox" )
436 bool bControlValue;
437 if ( ( rValue >>= bControlValue ) && bControlValue )
438 aBuffer.appendAscii( " true" );
439 else
440 aBuffer.appendAscii( " false" );
442 else if ( aType == "listbox" )
444 switch ( nControlAction )
446 case ControlActions::ADD_ITEM:
447 case ControlActions::SET_HELP_URL:
449 OUString aString;
450 if ( rValue >>= aString )
452 aBuffer.appendAscii( " ", 1 );
453 appendEscaped( aBuffer, aString );
456 break;
458 case ControlActions::ADD_ITEMS:
460 uno::Sequence< OUString > aSequence;
461 if ( rValue >>= aSequence )
463 for ( sal_Int32 nIdx = 0; nIdx < aSequence.getLength(); ++nIdx )
465 aBuffer.appendAscii( " ", 1 );
466 appendEscaped( aBuffer, aSequence[nIdx] );
471 break;
473 case ControlActions::DELETE_ITEM:
474 case ControlActions::SET_SELECT_ITEM:
476 sal_Int32 nInt;
477 if ( rValue >>= nInt )
479 aBuffer.appendAscii( " ", 1 );
480 aBuffer.append( nInt );
483 break;
485 default:
486 // nothing
487 break;
490 // TODO else if push button...
492 sendCommand( aBuffer.makeStringAndClear() );
496 uno::Any SAL_CALL UnxFilePicker::getValue( sal_Int16 nControlId, sal_Int16 nControlAction )
497 throw( uno::RuntimeException, std::exception )
499 checkFilePicker();
500 ::osl::MutexGuard aGuard( m_aMutex );
502 OUString aAction;
504 if ( controlActionInfo( nControlAction, aAction ) )
506 OUStringBuffer aBuffer( 1024 );
508 aBuffer.appendAscii( "getValue " );
509 aBuffer.append( static_cast< sal_Int32 >( nControlId ) );
510 aBuffer.appendAscii( " ", 1 );
511 aBuffer.append( aAction );
513 sendCommand( aBuffer.makeStringAndClear(),
514 m_pCommandThread->getValueCondition() );
516 return m_pCommandThread->getValue();
519 return uno::Any();
522 void SAL_CALL UnxFilePicker::enableControl( sal_Int16 nControlId, sal_Bool bEnable )
523 throw( uno::RuntimeException, std::exception )
525 checkFilePicker();
526 ::osl::MutexGuard aGuard( m_aMutex );
528 OUStringBuffer aBuffer( 1024 );
530 aBuffer.appendAscii( "enableControl " );
531 aBuffer.append( static_cast< sal_Int32 >( nControlId ) );
532 aBuffer.appendAscii( bEnable? " true": " false" );
534 sendCommand( aBuffer.makeStringAndClear() );
537 void SAL_CALL UnxFilePicker::setLabel( sal_Int16 nControlId, const OUString &rLabel )
538 throw( uno::RuntimeException, std::exception )
540 checkFilePicker();
541 ::osl::MutexGuard aGuard( m_aMutex );
543 OUStringBuffer aBuffer( 1024 );
545 aBuffer.appendAscii( "setLabel " );
546 aBuffer.append( static_cast< sal_Int32 >( nControlId ) );
547 aBuffer.appendAscii( " ", 1 );
548 appendEscaped( aBuffer, rLabel );
550 sendCommand( aBuffer.makeStringAndClear() );
553 OUString SAL_CALL UnxFilePicker::getLabel(sal_Int16 /*nControlId*/)
554 throw ( uno::RuntimeException, std::exception )
556 // FIXME getLabel() is not yet implemented
557 checkFilePicker();
558 ::osl::MutexGuard aGuard( m_aMutex );
560 // TODO return m_pImpl->getLabel(nControlId);
561 return OUString();
564 /* TODO
565 uno::Sequence<sal_Int16> SAL_CALL UnxFilePicker::getSupportedImageFormats()
566 throw( uno::RuntimeException )
568 checkFilePicker();
569 ::osl::MutexGuard aGuard( m_aMutex );
571 return m_pImpl->getSupportedImageFormats();
574 sal_Int32 SAL_CALL UnxFilePicker::getTargetColorDepth()
575 throw( uno::RuntimeException )
577 checkFilePicker();
578 ::osl::MutexGuard aGuard( m_aMutex );
580 return m_pImpl->getTargetColorDepth();
583 sal_Int32 SAL_CALL UnxFilePicker::getAvailableWidth()
584 throw( uno::RuntimeException )
586 checkFilePicker();
587 ::osl::MutexGuard aGuard( m_aMutex );
589 return m_pImpl->getAvailableWidth();
592 sal_Int32 SAL_CALL UnxFilePicker::getAvailableHeight()
593 throw( uno::RuntimeException )
595 checkFilePicker();
596 ::osl::MutexGuard aGuard( m_aMutex );
598 return m_pImpl->getAvailableHeight();
601 void SAL_CALL UnxFilePicker::setImage( sal_Int16 aImageFormat, const uno::Any &rImage )
602 throw( lang::IllegalArgumentException, uno::RuntimeException )
604 checkFilePicker();
605 ::osl::MutexGuard aGuard( m_aMutex );
607 m_pImpl->setImage( aImageFormat, aImage );
610 sal_Bool SAL_CALL UnxFilePicker::setShowState( sal_Bool bShowState )
611 throw( uno::RuntimeException )
613 checkFilePicker();
614 ::osl::MutexGuard aGuard( m_aMutex );
616 return m_pImpl->setShowState( bShowState );
619 sal_Bool SAL_CALL UnxFilePicker::getShowState()
620 throw( uno::RuntimeException )
622 checkFilePicker();
623 ::osl::MutexGuard aGuard( m_aMutex );
625 return m_pImpl->getShowState();
629 void SAL_CALL UnxFilePicker::initialize( const uno::Sequence<uno::Any> &rArguments )
630 throw( uno::Exception, uno::RuntimeException, std::exception )
632 initFilePicker();
634 // parameter checking
635 uno::Any aAny;
636 if ( 0 == rArguments.getLength( ) )
637 throw lang::IllegalArgumentException(
638 OUString( "no arguments" ),
639 static_cast< XFilePicker2* >( this ), 1 );
641 aAny = rArguments[0];
643 if ( ( aAny.getValueType() != cppu::UnoType<sal_Int16>::get()) && ( aAny.getValueType() != cppu::UnoType<sal_Int8>::get()) )
644 throw lang::IllegalArgumentException(
645 OUString( "invalid argument type" ),
646 static_cast< XFilePicker2* >( this ), 1 );
648 sal_Int16 templateId = -1;
649 aAny >>= templateId;
651 OUString aTypeOpen( "setType \"open\"" );
652 OUString aTypeSaveAs( "setType \"save\"" );
654 switch ( templateId )
656 case FILEOPEN_SIMPLE:
657 sendCommand( aTypeOpen );
658 break;
660 case FILESAVE_SIMPLE:
661 sendCommand( aTypeSaveAs );
662 break;
664 case FILESAVE_AUTOEXTENSION_PASSWORD:
665 sendCommand( aTypeSaveAs );
667 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION );
668 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD );
669 break;
671 case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
672 sendCommand( aTypeSaveAs );
674 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION );
675 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD );
676 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS );
677 break;
679 case FILESAVE_AUTOEXTENSION_SELECTION:
680 sendCommand( aTypeSaveAs );
682 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION );
683 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_SELECTION );
684 break;
686 case FILESAVE_AUTOEXTENSION_TEMPLATE:
687 sendCommand( aTypeSaveAs );
689 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION );
690 sendAppendControlCommand( ExtendedFilePickerElementIds::LISTBOX_TEMPLATE );
691 break;
693 case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
694 sendCommand( aTypeOpen );
696 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_LINK );
697 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW );
698 sendAppendControlCommand( ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE );
699 break;
701 case FILEOPEN_PLAY:
702 sendCommand( aTypeOpen );
704 sendAppendControlCommand( ExtendedFilePickerElementIds::PUSHBUTTON_PLAY );
705 break;
707 case FILEOPEN_READONLY_VERSION:
708 sendCommand( aTypeOpen );
710 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_READONLY );
711 sendAppendControlCommand( ExtendedFilePickerElementIds::LISTBOX_VERSION );
712 break;
714 case FILEOPEN_LINK_PREVIEW:
715 sendCommand( aTypeOpen );
717 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_LINK );
718 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW );
719 break;
721 case FILESAVE_AUTOEXTENSION:
722 sendCommand( aTypeSaveAs );
724 sendAppendControlCommand( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION );
725 break;
727 default:
728 throw lang::IllegalArgumentException(
729 OUString( "Unknown template" ),
730 static_cast< XFilePicker2* >( this ),
731 1 );
735 void SAL_CALL UnxFilePicker::cancel()
736 throw ( uno::RuntimeException, std::exception )
738 // FIXME cancel() is not implemented
739 checkFilePicker();
740 ::osl::MutexGuard aGuard( m_aMutex );
742 // TODO m_pImpl->cancel();
745 void SAL_CALL UnxFilePicker::disposing( const lang::EventObject &rEvent )
746 throw( uno::RuntimeException )
748 uno::Reference<XFilePickerListener> xFilePickerListener( rEvent.Source, uno::UNO_QUERY );
750 if ( xFilePickerListener.is() )
751 removeFilePickerListener( xFilePickerListener );
754 OUString SAL_CALL UnxFilePicker::getImplementationName()
755 throw( uno::RuntimeException, std::exception )
757 return OUString( FILE_PICKER_IMPL_NAME );
760 sal_Bool SAL_CALL UnxFilePicker::supportsService( const OUString& ServiceName )
761 throw( uno::RuntimeException, std::exception )
763 return cppu::supportsService(this, ServiceName);
766 uno::Sequence< OUString > SAL_CALL UnxFilePicker::getSupportedServiceNames()
767 throw( uno::RuntimeException, std::exception )
769 return FilePicker_getSupportedServiceNames();
772 void UnxFilePicker::initFilePicker()
774 int aFiledesStdin[2], aFiledesStdout[2];
775 if ( pipe( aFiledesStdin ) < 0 || pipe( aFiledesStdout ) < 0 )
776 return;
778 m_nFilePickerPid = fork();
779 if ( m_nFilePickerPid < 0 )
780 return;
782 if ( m_nFilePickerPid == 0 )
784 // Child...
785 close( aFiledesStdin[1] ); // write end of the pipe
786 dup2( aFiledesStdin[0], 0 );
787 close( aFiledesStdin[0] );
789 close( aFiledesStdout[0] ); // read end of the pipe
790 dup2( aFiledesStdout[1], 1 );
791 close( aFiledesStdout[1] );
793 #if OSL_DEBUG_LEVEL == 0
794 int nRedirect = open( "/dev/null", O_WRONLY );
795 if( nRedirect != -1 )
797 dup2( nRedirect, 2 );
799 #endif
801 // The executable name
802 #if ENABLE_TDE
803 OUString helperurl("${ORIGIN}/tdefilepicker");
804 #else // ENABLE_TDE
805 OUString helperurl("${ORIGIN}/kdefilepicker");
806 #endif // ENABLE_TDE
807 rtl::Bootstrap::expandMacros( helperurl );
808 OUString helperpath;
809 osl::FileBase::getSystemPathFromFileURL( helperurl, helperpath );
810 OString helper( OUStringToOString( helperpath, osl_getThreadTextEncoding()));
812 // ID of the main window
813 const int nIdLen = 20;
814 char pWinId[nIdLen] = "0";
816 // TODO pass here the real parent (not possible for system dialogs
817 // yet), and default to GetDefDialogParent() only when the real parent
818 // is NULL
819 vcl::Window *pParentWin = Application::GetDefDialogParent();
820 if ( pParentWin )
822 const SystemEnvData* pSysData = static_cast<SystemWindow *>(pParentWin)->GetSystemData();
823 if ( pSysData )
825 snprintf( pWinId, nIdLen, "%ld", pSysData->aWindow ); // unx only
826 pWinId[nIdLen-1] = 0;
830 // Execute the fpicker implementation
831 execlp( helper.getStr(), helper.getStr(), "--winid", pWinId, NULL );
833 // Error, finish the child
834 exit( -1 );
837 // Parent continues
838 close( aFiledesStdin[0] );
839 m_nFilePickerWrite = aFiledesStdin[1];
841 close( aFiledesStdout[1] );
842 m_nFilePickerRead = aFiledesStdout[0];
844 // Create the notify thread
845 if ( !m_pNotifyThread )
846 m_pNotifyThread = new UnxFilePickerNotifyThread( this );
848 // Create the command thread
849 if ( !m_pCommandThread )
850 m_pCommandThread = new UnxFilePickerCommandThread( m_pNotifyThread, m_nFilePickerRead );
852 // Start the threads
853 m_pNotifyThread->create();
854 m_pCommandThread->create();
856 return;
859 void UnxFilePicker::checkFilePicker() throw( ::com::sun::star::uno::RuntimeException )
861 if ( m_nFilePickerPid > 0 )
863 // TODO check if external file picker is runnning
865 else
867 throw uno::RuntimeException(
868 OUString( "the external file picker does not run" ),
869 *this );
873 void UnxFilePicker::sendCommand( const OUString &rCommand )
875 if ( m_nFilePickerWrite < 0 )
876 return;
878 OString aUtfString = OUStringToOString( rCommand + "\n", RTL_TEXTENCODING_UTF8 );
880 #if OSL_DEBUG_LEVEL > 0
881 ::std::cerr << "UnxFilePicker sent: \"" << aUtfString.getStr() << "\"" << ::std::endl;
882 #endif
884 write( m_nFilePickerWrite, aUtfString.getStr(), aUtfString.getLength() );
887 void UnxFilePicker::sendCommand( const OUString &rCommand, ::osl::Condition &rCondition )
889 rCondition.reset();
891 sendCommand( rCommand );
893 rCondition.wait();
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, std::exception )
919 return getFiles();
922 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */