1 /*************************************************************************
3 * OpenOffice.org - a multi-platform office productivity suite
9 * last change: $Author: tml $ $Date: 2008-03-26 02:30:23 +0200 (on, 26 mar 2008) $
11 * The Contents of this file are made available subject to
12 * the terms of GNU Lesser General Public License Version 2.1.
15 * GNU Lesser General Public License Version 2.1
16 * =============================================
17 * Copyright 2005 by Sun Microsystems, Inc.
18 * 901 San Antonio Road, Palo Alto, CA 94303, USA
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License version 2.1, as published by the Free Software Foundation.
24 * This library is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 * Lesser General Public License for more details.
29 * You should have received a copy of the GNU Lesser General Public
30 * License along with this library; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
34 ************************************************************************/
36 // MARKER(update_precomp.py): autogen include statement, do not remove
37 #include "precompiled_fpicker.hxx"
39 #include "ODMAFilePicker.hxx"
41 #ifndef _TOOLS_DEBUG_HXX
42 #include <tools/debug.hxx>
45 #ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
46 #include <com/sun/star/beans/PropertyValue.hpp>
48 #ifndef _COM_SUN_STAR_BEANS_STRINGPAIR_HPP_
49 #include <com/sun/star/beans/StringPair.hpp>
51 #ifndef _COM_SUN_STAR_UI_DIALOGS_FILEPREVIEWIMAGEFORMATS_HPP_
52 #include <com/sun/star/ui/dialogs/FilePreviewImageFormats.hpp>
54 #ifndef _COM_SUN_STAR_UI_DIALOGS_EXECUTABLEDIALOGRESULTS_HPP_
55 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
57 #ifndef _COM_SUN_STAR_UI_DIALOGS_TEMPLATEDESCRIPTION_HPP_
58 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
60 #ifndef _COM_SUN_STAR_UCB_XCOMMANDENVIRONMENT_HPP_
61 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
63 #ifndef _COM_SUN_STAR_UNO_ANY_HXX_
64 #include <com/sun/star/uno/Any.hxx>
66 #ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
67 #include <com/sun/star/uno/Sequence.hxx>
70 #ifndef _COMPHELPER_SEQUENCE_HXX_
71 #include <comphelper/sequence.hxx>
73 #ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
74 #include <cppuhelper/typeprovider.hxx>
76 #ifndef _UCBHELPER_CONTENT_HXX
77 #include <ucbhelper/content.hxx>
79 #ifndef _UNOTOOLS_UCBHELPER_HXX
80 #include <unotools/ucbhelper.hxx>
84 #include <tools/prewin.h>
85 #include <tools/postwin.h>
86 #include <odma_lib.hxx>
89 // using ----------------------------------------------------------------
91 using namespace ::com::sun::star::beans
;
92 using namespace ::com::sun::star::lang
;
93 using namespace ::com::sun::star::ui::dialogs
;
94 using namespace ::com::sun::star::ucb
;
95 using namespace ::com::sun::star::uno
;
96 using namespace ::com::sun::star::util
;
97 using namespace ::utl
;
99 //------------------------------------------------------------------------------------
100 // class ODMAFilePicker
101 //------------------------------------------------------------------------------------
102 ODMAFilePicker::ODMAFilePicker( const Reference
< XMultiServiceFactory
>& xFactory
) :
103 cppu::WeakComponentImplHelper9
<
106 XFilePickerControlAccess
,
112 XServiceInfo
>( m_rbHelperMtx
),
113 m_bMultiSelectionMode( sal_False
),
116 m_nDialogKind( OPEN
)
118 m_bUseDMS
= ::odma::DMSsAvailable();
119 m_xSystemFilePicker
= xFactory
->createInstance(
120 ::rtl::OUString::createFromAscii( "com.sun.star.ui.dialogs.Win32FilePicker" ) );
123 // XExecutableDialog functions
125 void SAL_CALL
ODMAFilePicker::setTitle( const ::rtl::OUString
& aTitle
)
126 throw (RuntimeException
)
128 Reference
< XExecutableDialog
> xExecutableDialog( m_xSystemFilePicker
, UNO_QUERY
);
129 xExecutableDialog
->setTitle( aTitle
);
132 sal_Int16 SAL_CALL
ODMAFilePicker::execute( )
133 throw (RuntimeException
)
140 status
= NODMRegisterApp( &handle
, ODM_API_VERSION
, "sodma", (DWORD
) GetActiveWindow( ), NULL
);
141 if (status
== ODM_SUCCESS
)
143 if (m_nDialogKind
== OPEN
)
145 const int MAXDOCS
= 10;
146 char docids
[ODM_DOCID_MAX
*MAXDOCS
+1];
147 WORD docidslen
= sizeof( docids
);
150 if (m_bMultiSelectionMode
)
154 status
= NODMSelectDocEx( handle
, docids
, &docidslen
, &count
, &flags
, NULL
);
155 if (status
== ODM_SUCCESS
)
157 // GroupWise doesn't set docidslen or count, so
158 // calculate number of document IDs manually
163 p
+= strlen( p
) + 1;
166 else if (status
== ODM_E_NOSUPPORT
)
168 status
= NODMSelectDoc( handle
, docids
, &flags
);
169 if (status
== ODM_SUCCESS
)
172 NODMUnRegisterApp( handle
);
173 if (status
== ODM_SUCCESS
)
175 rtl::OUString
*strings
= new rtl::OUString
[count
];
179 for (i
= 0; i
< count
; i
++) {
180 // Insane API... the first element is a full URI, the rest
181 // are just the "basenames" in the same "directory".
183 strings
[0] = rtl::OUString::createFromAscii( "vnd.sun.star.odma:/" ) + rtl::OUString::createFromAscii( p
);
185 strings
[i
] = rtl::OUString::createFromAscii( p
);
189 m_aFiles
= Sequence
< rtl::OUString
>( strings
, count
);
191 return ExecutableDialogResults::OK
;
194 else /* m_nDialogKind == SAVE */
196 char newdocid
[ODM_DOCID_MAX
+1];
198 if (m_aDefaultName
.getLength() == 0 ||
199 !m_aDefaultName
.matchIgnoreAsciiCaseAsciiL( "::ODMA\\", 7, 0 ))
201 char tempdocid
[ODM_DOCID_MAX
+1];
203 status
= NODMNewDoc( handle
, tempdocid
, ODM_SILENT
, NULL
, NULL
);
204 if (status
== ODM_SUCCESS
)
205 status
= NODMSaveAs( handle
, tempdocid
, newdocid
, NULL
, NULL
, NULL
);
209 rtl::OString sDefaultName
= rtl::OUStringToOString( m_aDefaultName
, RTL_TEXTENCODING_ASCII_US
);
210 status
= NODMSaveAs( handle
,
211 const_cast<sal_Char
*>( sDefaultName
.getStr() ),
212 newdocid
, NULL
, NULL
, NULL
);
215 NODMUnRegisterApp( handle
);
216 if (status
== ODM_SUCCESS
)
218 rtl::OUString
s( rtl::OUString::createFromAscii( "vnd.sun.star.odma:/" ) +
219 rtl::OUString::createFromAscii( newdocid
) );
220 // Create a Content for the odma URL so that
221 // odma::ContentProvider will learn about the DOCID we
223 ucbhelper::Content
content( s
, Reference
< XCommandEnvironment
>() );
224 m_aFiles
= Sequence
< rtl::OUString
>( &s
, 1 );
225 return ExecutableDialogResults::OK
;
229 if (status
== ODM_E_APPSELECT
)
231 m_bUseDMS
= sal_False
;
233 Reference
< XExecutableDialog
> xExecutableDialog( m_xSystemFilePicker
, UNO_QUERY
);
234 return xExecutableDialog
->execute();
238 return ExecutableDialogResults::CANCEL
;
241 // XFilePicker functions
243 void SAL_CALL
ODMAFilePicker::setMultiSelectionMode( sal_Bool bMode
)
244 throw( RuntimeException
)
246 m_bMultiSelectionMode
= bMode
;
248 Reference
< XFilePicker
> xFilePicker( m_xSystemFilePicker
, UNO_QUERY
);
249 xFilePicker
->setMultiSelectionMode( bMode
);
252 void SAL_CALL
ODMAFilePicker::setDefaultName( const rtl::OUString
& aName
)
253 throw( RuntimeException
)
255 // When editing a document from DMS, and doing Save As, this is
256 // called twice, first with the complete DOCID, the second time
257 // with the "extension" removed. Of course, this is bogus, as
258 // DOCIDs should be treated as opaque strings, they don't have
261 // In the GroupWise case a DOCID is like
262 // ::ODMA\GRPWISE\FOO1.BAR.FOO-Bla_bla:12345.12 where the final
263 // dot separates the version number, not an "extension".
265 // So ignore the second call.
267 // The second call without "extension" is done if the
268 // XFilePickerControlAccess is set to have auto-extension turned
269 // on. (See sfx2/source/dialog/filedlghelper.cxx:
270 // FileDialogHelper_Impl::implInitializeFileName().) Thus we could
271 // alternatively make sure that a getValue call to get
272 // ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION returns
273 // false. But that might be hard as we don't know in advance
274 // whether the user will click the "use application dialog"
275 // button. If so, we indeed do use auto-extensions.
277 // Yes, this is ugly, relying on knowing details on how this
278 // function will be called.
280 if ( m_aDefaultName
.getLength() == 0 )
281 m_aDefaultName
= aName
;
283 Reference
< XFilePicker
> xFilePicker( m_xSystemFilePicker
, UNO_QUERY
);
284 xFilePicker
->setDefaultName( aName
);
287 void SAL_CALL
ODMAFilePicker::setDisplayDirectory( const rtl::OUString
& aDirectory
)
288 throw( IllegalArgumentException
, RuntimeException
)
290 m_aDisplayDirectory
= aDirectory
;
292 Reference
< XFilePicker
> xFilePicker( m_xSystemFilePicker
, UNO_QUERY
);
293 xFilePicker
->setDisplayDirectory( aDirectory
);
296 rtl::OUString SAL_CALL
ODMAFilePicker::getDisplayDirectory( )
297 throw( RuntimeException
)
300 return m_aDisplayDirectory
;
302 Reference
< XFilePicker
> xFilePicker( m_xSystemFilePicker
, UNO_QUERY
);
303 return xFilePicker
->getDisplayDirectory();
306 Sequence
< rtl::OUString
> SAL_CALL
ODMAFilePicker::getFiles( )
307 throw( RuntimeException
)
312 Reference
< XFilePicker
> xFilePicker( m_xSystemFilePicker
, UNO_QUERY
);
313 return xFilePicker
->getFiles();
316 // XFilePickerControlAccess functions
318 void SAL_CALL
ODMAFilePicker::setValue( sal_Int16 nElementID
,
319 sal_Int16 nControlAction
,
321 throw( RuntimeException
)
323 Reference
< XFilePickerControlAccess
> xFilePickerControlAccess( m_xSystemFilePicker
, UNO_QUERY
);
324 xFilePickerControlAccess
->setValue( nElementID
, nControlAction
, rValue
);
327 Any SAL_CALL
ODMAFilePicker::getValue( sal_Int16 nElementID
, sal_Int16 nControlAction
)
328 throw( RuntimeException
)
330 Reference
< XFilePickerControlAccess
> xFilePickerControlAccess( m_xSystemFilePicker
, UNO_QUERY
);
331 return xFilePickerControlAccess
->getValue( nElementID
, nControlAction
);
334 void SAL_CALL
ODMAFilePicker::setLabel( sal_Int16 nLabelID
, const rtl::OUString
& rValue
)
335 throw ( RuntimeException
)
337 Reference
< XFilePickerControlAccess
> xFilePickerControlAccess( m_xSystemFilePicker
, UNO_QUERY
);
338 xFilePickerControlAccess
->setLabel( nLabelID
, rValue
);
341 rtl::OUString SAL_CALL
ODMAFilePicker::getLabel( sal_Int16 nLabelID
)
342 throw ( RuntimeException
)
344 Reference
< XFilePickerControlAccess
> xFilePickerControlAccess( m_xSystemFilePicker
, UNO_QUERY
);
345 return xFilePickerControlAccess
->getLabel( nLabelID
);
348 void SAL_CALL
ODMAFilePicker::enableControl( sal_Int16 nElementID
, sal_Bool bEnable
)
349 throw( RuntimeException
)
351 Reference
< XFilePickerControlAccess
> xFilePickerControlAccess( m_xSystemFilePicker
, UNO_QUERY
);
352 xFilePickerControlAccess
->enableControl( nElementID
, bEnable
);
355 // XFilePickerNotifier functions
357 void SAL_CALL
ODMAFilePicker::addFilePickerListener( const Reference
< XFilePickerListener
>& xListener
)
358 throw ( RuntimeException
)
360 Reference
< XFilePickerNotifier
> xFilePickerNotifier( m_xSystemFilePicker
, UNO_QUERY
);
361 xFilePickerNotifier
->addFilePickerListener( xListener
);
364 void SAL_CALL
ODMAFilePicker::removeFilePickerListener( const Reference
< XFilePickerListener
>& xListener
)
365 throw ( RuntimeException
)
367 Reference
< XFilePickerNotifier
> xFilePickerNotifier( m_xSystemFilePicker
, UNO_QUERY
);
368 xFilePickerNotifier
->removeFilePickerListener( xListener
);
371 // XFilePreview functions
373 Sequence
< sal_Int16
> SAL_CALL
ODMAFilePicker::getSupportedImageFormats( )
374 throw ( RuntimeException
)
376 Reference
< XFilePreview
> xFilePreview( m_xSystemFilePicker
, UNO_QUERY
);
377 return xFilePreview
->getSupportedImageFormats();
380 sal_Int32 SAL_CALL
ODMAFilePicker::getTargetColorDepth( )
381 throw ( RuntimeException
)
383 Reference
< XFilePreview
> xFilePreview( m_xSystemFilePicker
, UNO_QUERY
);
384 return xFilePreview
->getTargetColorDepth();
387 sal_Int32 SAL_CALL
ODMAFilePicker::getAvailableWidth( )
388 throw ( RuntimeException
)
390 Reference
< XFilePreview
> xFilePreview( m_xSystemFilePicker
, UNO_QUERY
);
391 return xFilePreview
->getAvailableWidth();
394 sal_Int32 SAL_CALL
ODMAFilePicker::getAvailableHeight( )
395 throw ( RuntimeException
)
397 Reference
< XFilePreview
> xFilePreview( m_xSystemFilePicker
, UNO_QUERY
);
398 return xFilePreview
->getAvailableHeight();
401 void SAL_CALL
ODMAFilePicker::setImage( sal_Int16 aImageFormat
, const Any
& rImage
)
402 throw ( IllegalArgumentException
, RuntimeException
)
404 Reference
< XFilePreview
> xFilePreview( m_xSystemFilePicker
, UNO_QUERY
);
405 xFilePreview
->setImage( aImageFormat
, rImage
);
408 sal_Bool SAL_CALL
ODMAFilePicker::setShowState( sal_Bool bShowState
)
409 throw ( RuntimeException
)
411 Reference
< XFilePreview
> xFilePreview( m_xSystemFilePicker
, UNO_QUERY
);
412 return xFilePreview
->setShowState( bShowState
);
415 sal_Bool SAL_CALL
ODMAFilePicker::getShowState( )
416 throw ( RuntimeException
)
418 Reference
< XFilePreview
> xFilePreview( m_xSystemFilePicker
, UNO_QUERY
);
419 return xFilePreview
->getShowState();
422 // XFilterGroupManager functions
424 void SAL_CALL
ODMAFilePicker::appendFilterGroup( const ::rtl::OUString
& sGroupTitle
,
425 const Sequence
< StringPair
>& aFilters
)
426 throw ( IllegalArgumentException
, RuntimeException
)
428 Reference
< XFilterGroupManager
> xFilterGroupManager( m_xSystemFilePicker
, UNO_QUERY
);
429 xFilterGroupManager
->appendFilterGroup( sGroupTitle
, aFilters
);
432 // XFilterManager functions
434 void SAL_CALL
ODMAFilePicker::appendFilter( const rtl::OUString
& aTitle
,
435 const rtl::OUString
& aFilter
)
436 throw( IllegalArgumentException
, RuntimeException
)
438 Reference
< XFilterManager
> xFilterManager( m_xSystemFilePicker
, UNO_QUERY
);
439 xFilterManager
->appendFilter( aTitle
, aFilter
);
442 void SAL_CALL
ODMAFilePicker::setCurrentFilter( const rtl::OUString
& aTitle
)
443 throw( IllegalArgumentException
, RuntimeException
)
445 Reference
< XFilterManager
> xFilterManager( m_xSystemFilePicker
, UNO_QUERY
);
446 xFilterManager
->setCurrentFilter( aTitle
);
449 rtl::OUString SAL_CALL
ODMAFilePicker::getCurrentFilter( )
450 throw( RuntimeException
)
452 Reference
< XFilterManager
> xFilterManager( m_xSystemFilePicker
, UNO_QUERY
);
453 return xFilterManager
->getCurrentFilter();
456 // XInitialization functions
458 void SAL_CALL
ODMAFilePicker::initialize( const Sequence
< Any
>& aArguments
)
459 throw ( Exception
, RuntimeException
)
461 if (aArguments
.getLength( ) > 0)
463 Any aAny
= aArguments
[0];
465 if ( (aAny
.getValueType() == ::getCppuType((sal_Int16
*)0)) ||
466 (aAny
.getValueType() == ::getCppuType((sal_Int8
*)0)) )
468 sal_Int16 nTemplateId
= -1;
469 aAny
>>= nTemplateId
;
471 switch (nTemplateId
) {
472 case TemplateDescription::FILEOPEN_SIMPLE
:
473 case TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE
:
474 case TemplateDescription::FILEOPEN_PLAY
:
475 case TemplateDescription::FILEOPEN_READONLY_VERSION
:
476 case TemplateDescription::FILEOPEN_LINK_PREVIEW
:
477 m_nDialogKind
= OPEN
;
480 m_nDialogKind
= SAVE
;
485 Reference
< XInitialization
> xInitialization( m_xSystemFilePicker
, UNO_QUERY
);
486 xInitialization
->initialize( aArguments
);
489 // XCancellable functions
491 void SAL_CALL
ODMAFilePicker::cancel( )
492 throw( ::com::sun::star::uno::RuntimeException
)
494 Reference
< XCancellable
> xCancellable( m_xSystemFilePicker
, UNO_QUERY
);
495 xCancellable
->cancel();
498 // XEventListener functions
500 void SAL_CALL
ODMAFilePicker::disposing( const ::com::sun::star::lang::EventObject
& aEvent
)
501 throw( RuntimeException
)
503 Reference
< XEventListener
> xEventListener( m_xSystemFilePicker
, UNO_QUERY
);
504 xEventListener
->disposing( aEvent
);
507 // XServiceInfo functions
509 rtl::OUString SAL_CALL
ODMAFilePicker::getImplementationName( )
510 throw( RuntimeException
)
512 return impl_getStaticImplementationName();
515 sal_Bool SAL_CALL
ODMAFilePicker::supportsService( const rtl::OUString
& sServiceName
)
516 throw( RuntimeException
)
518 Sequence
< rtl::OUString
> seqServiceNames
= getSupportedServiceNames();
519 const rtl::OUString
* pArray
= seqServiceNames
.getConstArray();
520 for ( sal_Int32 i
= 0; i
< seqServiceNames
.getLength(); i
++ )
522 if ( sServiceName
== pArray
[i
] )
530 Sequence
< rtl::OUString
> SAL_CALL
ODMAFilePicker::getSupportedServiceNames( )
531 throw( RuntimeException
)
533 return impl_getStaticSupportedServiceNames();
536 Sequence
< rtl::OUString
> ODMAFilePicker::impl_getStaticSupportedServiceNames( )
538 Sequence
< rtl::OUString
> seqServiceNames( 2 );
539 rtl::OUString
* pArray
= seqServiceNames
.getArray();
540 pArray
[0] = rtl::OUString::createFromAscii( "com.sun.star.ui.dialogs.ODMAFilePicker" );
542 // Super-ugly, but check the function sal_Bool
543 // lcl_isSystemFilePicker( const Reference< XFilePicker >& ) in
544 // sfx2/source/dialog/filedlghelper.cxx
546 // Lovely undocumented coupling right across abstraction layers,
547 // isn't it? If we don't claim to implement this "service" (which
548 // is not defined in any IDL file, btw), we get hangs.
550 pArray
[1] = rtl::OUString::createFromAscii( "com.sun.star.ui.dialogs.SystemFilePicker" );
551 return seqServiceNames
;
554 rtl::OUString
ODMAFilePicker::impl_getStaticImplementationName( )
556 return rtl::OUString::createFromAscii( "com.sun.star.svtools.ODMAFilePicker" );
559 Reference
< XInterface
> SAL_CALL
ODMAFilePicker::impl_createInstance(
560 const Reference
< XComponentContext
>& rxContext
)
563 Reference
< XMultiServiceFactory
> xServiceManager (rxContext
->getServiceManager(), UNO_QUERY_THROW
);
564 return Reference
< XInterface
>( *new ODMAFilePicker( xServiceManager
) );