Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <sfx2/filedlghelper.hxx>
21 : #include <sal/types.h>
22 : #include <com/sun/star/lang/XInitialization.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/FilePreviewImageFormats.hpp>
27 : #include <com/sun/star/ui/dialogs/ControlActions.hpp>
28 : #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
29 : #include <com/sun/star/ui/dialogs/XControlInformation.hpp>
30 : #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
31 : #include <com/sun/star/ui/dialogs/XFilePickerNotifier.hpp>
32 : #include <com/sun/star/ui/dialogs/XFilePreview.hpp>
33 : #include <com/sun/star/ui/dialogs/XFilterManager.hpp>
34 : #include <com/sun/star/ui/dialogs/XFilterGroupManager.hpp>
35 : #include <com/sun/star/ui/dialogs/XFilePicker2.hpp>
36 : #include <com/sun/star/ui/dialogs/XAsynchronousExecutableDialog.hpp>
37 : #include <com/sun/star/lang/XServiceInfo.hpp>
38 : #include <com/sun/star/beans/XPropertySet.hpp>
39 : #include <com/sun/star/beans/NamedValue.hpp>
40 : #include <com/sun/star/embed/ElementModes.hpp>
41 : #include <com/sun/star/container/XEnumeration.hpp>
42 : #include <com/sun/star/container/XContainerQuery.hpp>
43 : #include <com/sun/star/task/InteractionHandler.hpp>
44 : #include <com/sun/star/task/XInteractionRequest.hpp>
45 : #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
46 :
47 : #include <comphelper/processfactory.hxx>
48 : #include <comphelper/sequenceashashmap.hxx>
49 : #include <comphelper/stillreadwriteinteraction.hxx>
50 : #include <comphelper/string.hxx>
51 : #include <comphelper/types.hxx>
52 : #include <tools/urlobj.hxx>
53 : #include <vcl/help.hxx>
54 : #include <unotools/ucbstreamhelper.hxx>
55 : #include <unotools/ucbhelper.hxx>
56 : #include <unotools/localfilehelper.hxx>
57 : #include <osl/file.hxx>
58 : #include <osl/mutex.hxx>
59 : #include <osl/security.hxx>
60 : #include <osl/thread.hxx>
61 : #include <vcl/cvtgrf.hxx>
62 : #include <vcl/msgbox.hxx>
63 : #include <vcl/mnemonic.hxx>
64 : #include <unotools/pathoptions.hxx>
65 : #include <unotools/securityoptions.hxx>
66 : #include <svl/itemset.hxx>
67 : #include <svl/eitem.hxx>
68 : #include <svl/intitem.hxx>
69 : #include <svl/stritem.hxx>
70 : #include <vcl/dibtools.hxx>
71 : #include <vcl/graphicfilter.hxx>
72 : #include <unotools/viewoptions.hxx>
73 : #include <unotools/moduleoptions.hxx>
74 : #include <svtools/helpid.hrc>
75 : #include <comphelper/docpasswordrequest.hxx>
76 : #include <comphelper/docpasswordhelper.hxx>
77 : #include <ucbhelper/content.hxx>
78 : #include <ucbhelper/commandenvironment.hxx>
79 : #include <comphelper/storagehelper.hxx>
80 : #include <toolkit/helper/vclunohelper.hxx>
81 : #include <sfx2/app.hxx>
82 : #include <sfx2/frame.hxx>
83 : #include <sfx2/docfile.hxx>
84 : #include <sfx2/docfac.hxx>
85 : #include "openflag.hxx"
86 : #include <sfx2/passwd.hxx>
87 : #include <sfx2/sfxresid.hxx>
88 : #include <sfx2/sfxsids.hrc>
89 : #include "filedlghelper.hrc"
90 : #include "filtergrouping.hxx"
91 : #include <sfx2/request.hxx>
92 : #include "filedlgimpl.hxx"
93 : #include <helpid.hrc>
94 : #include <sfxlocal.hrc>
95 : #include <rtl/strbuf.hxx>
96 : #include <comphelper/sequence.hxx>
97 :
98 : #ifdef UNX
99 : #include <errno.h>
100 : #include <sys/stat.h>
101 : #endif
102 :
103 : using namespace ::com::sun::star;
104 : using namespace ::com::sun::star::container;
105 : using namespace ::com::sun::star::lang;
106 : using namespace ::com::sun::star::ui::dialogs;
107 : using namespace ::com::sun::star::ui::dialogs::TemplateDescription;
108 : using namespace ::com::sun::star::uno;
109 : using namespace ::com::sun::star::beans;
110 : using namespace ::cppu;
111 :
112 : #define IODLG_CONFIGNAME OUString("FilePicker_Save")
113 : #define IMPGRF_CONFIGNAME OUString("FilePicker_Graph")
114 : #define USERITEM_NAME OUString("UserItem")
115 :
116 : namespace sfx2
117 : {
118 :
119 : namespace
120 : {
121 0 : bool lclSupportsOOXMLEncryption(const OUString& aFilterName)
122 : {
123 0 : return aFilterName == "Calc MS Excel 2007 XML"
124 0 : || aFilterName == "MS Word 2007 XML"
125 0 : || aFilterName == "Impress MS PowerPoint 2007 XML"
126 0 : || aFilterName == "Impress MS PowerPoint 2007 XML AutoPlay"
127 0 : || aFilterName == "Calc Office Open XML"
128 0 : || aFilterName == "Impress Office Open XML"
129 0 : || aFilterName == "Impress Office Open XML AutoPlay"
130 0 : || aFilterName == "Office Open XML Text";
131 : }
132 : }
133 :
134 0 : const OUString* GetLastFilterConfigId( FileDialogHelper::Context _eContext )
135 : {
136 0 : static const OUString aSD_EXPORT_IDENTIFIER("SdExportLastFilter");
137 0 : static const OUString aSI_EXPORT_IDENTIFIER("SiExportLastFilter");
138 0 : static const OUString aSW_EXPORT_IDENTIFIER("SwExportLastFilter");
139 :
140 0 : const OUString* pRet = NULL;
141 :
142 0 : switch( _eContext )
143 : {
144 0 : case FileDialogHelper::SD_EXPORT: pRet = &aSD_EXPORT_IDENTIFIER; break;
145 0 : case FileDialogHelper::SI_EXPORT: pRet = &aSI_EXPORT_IDENTIFIER; break;
146 0 : case FileDialogHelper::SW_EXPORT: pRet = &aSW_EXPORT_IDENTIFIER; break;
147 0 : default: break;
148 : }
149 :
150 0 : return pRet;
151 : }
152 :
153 : OUString EncodeSpaces_Impl( const OUString& rSource );
154 : OUString DecodeSpaces_Impl( const OUString& rSource );
155 :
156 : // FileDialogHelper_Impl
157 :
158 : // XFilePickerListener Methods
159 0 : void SAL_CALL FileDialogHelper_Impl::fileSelectionChanged( const FilePickerEvent& aEvent ) throw ( RuntimeException, std::exception )
160 : {
161 0 : SolarMutexGuard aGuard;
162 0 : mpAntiImpl->FileSelectionChanged( aEvent );
163 0 : }
164 :
165 0 : void SAL_CALL FileDialogHelper_Impl::directoryChanged( const FilePickerEvent& aEvent ) throw ( RuntimeException, std::exception )
166 : {
167 0 : SolarMutexGuard aGuard;
168 0 : mpAntiImpl->DirectoryChanged( aEvent );
169 0 : }
170 :
171 0 : OUString SAL_CALL FileDialogHelper_Impl::helpRequested( const FilePickerEvent& aEvent ) throw ( RuntimeException, std::exception )
172 : {
173 0 : SolarMutexGuard aGuard;
174 0 : return sfx2::FileDialogHelper::HelpRequested( aEvent );
175 : }
176 :
177 0 : void SAL_CALL FileDialogHelper_Impl::controlStateChanged( const FilePickerEvent& aEvent ) throw ( RuntimeException, std::exception )
178 : {
179 0 : SolarMutexGuard aGuard;
180 0 : mpAntiImpl->ControlStateChanged( aEvent );
181 0 : }
182 :
183 0 : void SAL_CALL FileDialogHelper_Impl::dialogSizeChanged() throw ( RuntimeException, std::exception )
184 : {
185 0 : SolarMutexGuard aGuard;
186 0 : mpAntiImpl->DialogSizeChanged();
187 0 : }
188 :
189 : // XDialogClosedListener Methods
190 0 : void SAL_CALL FileDialogHelper_Impl::dialogClosed( const DialogClosedEvent& _rEvent ) throw ( RuntimeException, std::exception )
191 : {
192 0 : SolarMutexGuard aGuard;
193 0 : mpAntiImpl->DialogClosed( _rEvent );
194 0 : postExecute( _rEvent.DialogResult );
195 0 : }
196 :
197 : // handle XFilePickerListener events
198 0 : void FileDialogHelper_Impl::handleFileSelectionChanged( const FilePickerEvent& )
199 : {
200 0 : if ( mbHasVersions )
201 0 : updateVersions();
202 :
203 0 : if ( mbShowPreview )
204 0 : maPreviewIdle.Start();
205 0 : }
206 :
207 0 : void FileDialogHelper_Impl::handleDirectoryChanged( const FilePickerEvent& )
208 : {
209 0 : if ( mbShowPreview )
210 0 : TimeOutHdl_Impl( NULL );
211 0 : }
212 :
213 0 : OUString FileDialogHelper_Impl::handleHelpRequested( const FilePickerEvent& aEvent )
214 : {
215 : //!!! todo: cache the help strings (here or TRA)
216 :
217 0 : OString sHelpId;
218 : // mapping from element id -> help id
219 0 : switch ( aEvent.ElementId )
220 : {
221 : case ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION :
222 0 : sHelpId = HID_FILESAVE_AUTOEXTENSION;
223 0 : break;
224 :
225 : case ExtendedFilePickerElementIds::CHECKBOX_PASSWORD :
226 0 : sHelpId = HID_FILESAVE_SAVEWITHPASSWORD;
227 0 : break;
228 :
229 : case ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS :
230 0 : sHelpId = HID_FILESAVE_CUSTOMIZEFILTER;
231 0 : break;
232 :
233 : case ExtendedFilePickerElementIds::CHECKBOX_READONLY :
234 0 : sHelpId = HID_FILEOPEN_READONLY;
235 0 : break;
236 :
237 : case ExtendedFilePickerElementIds::CHECKBOX_LINK :
238 0 : sHelpId = HID_FILEDLG_LINK_CB;
239 0 : break;
240 :
241 : case ExtendedFilePickerElementIds::CHECKBOX_PREVIEW :
242 0 : sHelpId = HID_FILEDLG_PREVIEW_CB;
243 0 : break;
244 :
245 : case ExtendedFilePickerElementIds::PUSHBUTTON_PLAY :
246 0 : sHelpId = HID_FILESAVE_DOPLAY;
247 0 : break;
248 :
249 : case ExtendedFilePickerElementIds::LISTBOX_VERSION_LABEL :
250 : case ExtendedFilePickerElementIds::LISTBOX_VERSION :
251 0 : sHelpId = HID_FILEOPEN_VERSION;
252 0 : break;
253 :
254 : case ExtendedFilePickerElementIds::LISTBOX_TEMPLATE_LABEL :
255 : case ExtendedFilePickerElementIds::LISTBOX_TEMPLATE :
256 0 : sHelpId = HID_FILESAVE_TEMPLATE;
257 0 : break;
258 :
259 : case ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE_LABEL :
260 : case ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE :
261 0 : sHelpId = HID_FILEOPEN_IMAGE_TEMPLATE;
262 0 : break;
263 :
264 : case ExtendedFilePickerElementIds::CHECKBOX_SELECTION :
265 0 : sHelpId = HID_FILESAVE_SELECTION;
266 0 : break;
267 :
268 : default:
269 : SAL_WARN( "sfx.dialog", "invalid element id" );
270 : }
271 :
272 0 : OUString aHelpText;
273 0 : Help* pHelp = Application::GetHelp();
274 0 : if ( pHelp )
275 0 : aHelpText = pHelp->GetHelpText( OStringToOUString(sHelpId, RTL_TEXTENCODING_UTF8), NULL );
276 0 : return aHelpText;
277 : }
278 :
279 0 : void FileDialogHelper_Impl::handleControlStateChanged( const FilePickerEvent& aEvent )
280 : {
281 0 : switch ( aEvent.ElementId )
282 : {
283 : case CommonFilePickerElementIds::LISTBOX_FILTER:
284 0 : updateFilterOptionsBox();
285 0 : enablePasswordBox( false );
286 0 : updateSelectionBox();
287 : // only use it for export and with our own dialog
288 0 : if ( mbExport && !mbSystemPicker )
289 0 : updateExportButton();
290 0 : break;
291 :
292 : case ExtendedFilePickerElementIds::CHECKBOX_PREVIEW:
293 0 : updatePreviewState();
294 0 : break;
295 : }
296 0 : }
297 :
298 0 : void FileDialogHelper_Impl::handleDialogSizeChanged()
299 : {
300 0 : if ( mbShowPreview )
301 0 : TimeOutHdl_Impl( NULL );
302 0 : }
303 :
304 : // XEventListener Methods
305 0 : void SAL_CALL FileDialogHelper_Impl::disposing( const EventObject& ) throw ( RuntimeException, std::exception )
306 : {
307 0 : SolarMutexGuard aGuard;
308 0 : dispose();
309 0 : }
310 :
311 0 : void FileDialogHelper_Impl::dispose()
312 : {
313 0 : if ( mxFileDlg.is() )
314 : {
315 : // remove the event listener
316 0 : uno::Reference< XFilePickerNotifier > xNotifier( mxFileDlg, UNO_QUERY );
317 0 : if ( xNotifier.is() )
318 0 : xNotifier->removeFilePickerListener( this );
319 :
320 0 : ::comphelper::disposeComponent( mxFileDlg );
321 0 : mxFileDlg.clear();
322 : }
323 0 : }
324 :
325 0 : OUString FileDialogHelper_Impl::getCurrentFilterUIName() const
326 : {
327 0 : OUString aFilterName;
328 0 : uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY );
329 :
330 0 : if( xFltMgr.is() )
331 : {
332 0 : aFilterName = xFltMgr->getCurrentFilter();
333 :
334 0 : if ( !aFilterName.isEmpty() && isShowFilterExtensionEnabled() )
335 0 : aFilterName = getFilterName( aFilterName );
336 : }
337 :
338 0 : return aFilterName;
339 : }
340 :
341 0 : void FileDialogHelper_Impl::LoadLastUsedFilter( const OUString& _rContextIdentifier )
342 : {
343 0 : SvtViewOptions aDlgOpt( E_DIALOG, IODLG_CONFIGNAME );
344 :
345 0 : if( aDlgOpt.Exists() )
346 : {
347 0 : OUString aLastFilter;
348 0 : if( aDlgOpt.GetUserItem( _rContextIdentifier ) >>= aLastFilter )
349 0 : setFilter( aLastFilter );
350 0 : }
351 0 : }
352 :
353 0 : void FileDialogHelper_Impl::SaveLastUsedFilter( const OUString& _rContextIdentifier )
354 : {
355 : SvtViewOptions( E_DIALOG, IODLG_CONFIGNAME ).SetUserItem( _rContextIdentifier,
356 0 : makeAny( getFilterWithExtension( getFilter() ) ) );
357 0 : }
358 :
359 0 : void FileDialogHelper_Impl::SaveLastUsedFilter()
360 : {
361 0 : const OUString* pConfigId = GetLastFilterConfigId( meContext );
362 0 : if( pConfigId )
363 0 : SaveLastUsedFilter( *pConfigId );
364 0 : }
365 :
366 0 : const SfxFilter* FileDialogHelper_Impl::getCurentSfxFilter()
367 : {
368 0 : OUString aFilterName = getCurrentFilterUIName();
369 :
370 0 : const SfxFilter* pFilter = NULL;
371 0 : if ( mpMatcher && !aFilterName.isEmpty() )
372 0 : pFilter = mpMatcher->GetFilter4UIName( aFilterName, m_nMustFlags, m_nDontFlags );
373 :
374 0 : return pFilter;
375 : }
376 :
377 0 : bool FileDialogHelper_Impl::updateExtendedControl( sal_Int16 _nExtendedControlId, bool _bEnable )
378 : {
379 0 : bool bIsEnabled = false;
380 :
381 0 : uno::Reference < XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
382 0 : if ( xCtrlAccess.is() )
383 : {
384 : try
385 : {
386 0 : xCtrlAccess->enableControl( _nExtendedControlId, _bEnable );
387 0 : bIsEnabled = _bEnable;
388 : }
389 0 : catch( const IllegalArgumentException& )
390 : {
391 : OSL_FAIL( "FileDialogHelper_Impl::updateExtendedControl: caught an exception!" );
392 : }
393 : }
394 0 : return bIsEnabled;
395 : }
396 :
397 0 : bool FileDialogHelper_Impl::CheckFilterOptionsCapability( const SfxFilter* _pFilter )
398 : {
399 0 : bool bResult = false;
400 :
401 0 : if( mxFilterCFG.is() && _pFilter )
402 : {
403 : try {
404 0 : Sequence < PropertyValue > aProps;
405 0 : Any aAny = mxFilterCFG->getByName( _pFilter->GetName() );
406 0 : if ( aAny >>= aProps )
407 : {
408 0 : OUString aServiceName;
409 0 : sal_Int32 nPropertyCount = aProps.getLength();
410 0 : for( sal_Int32 nProperty=0; nProperty < nPropertyCount; ++nProperty )
411 : {
412 0 : if( aProps[nProperty].Name == "UIComponent" )
413 : {
414 0 : aProps[nProperty].Value >>= aServiceName;
415 0 : if( !aServiceName.isEmpty() )
416 0 : bResult = true;
417 : }
418 0 : }
419 0 : }
420 : }
421 0 : catch( const Exception& )
422 : {
423 : }
424 : }
425 :
426 0 : return bResult;
427 : }
428 :
429 0 : bool FileDialogHelper_Impl::isInOpenMode() const
430 : {
431 0 : bool bRet = false;
432 :
433 0 : switch ( m_nDialogType )
434 : {
435 : case FILEOPEN_SIMPLE:
436 : case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
437 : case FILEOPEN_PLAY:
438 : case FILEOPEN_READONLY_VERSION:
439 : case FILEOPEN_LINK_PREVIEW:
440 0 : bRet = true;
441 : }
442 :
443 0 : return bRet;
444 : }
445 :
446 0 : void FileDialogHelper_Impl::updateFilterOptionsBox()
447 : {
448 0 : if ( !m_bHaveFilterOptions )
449 0 : return;
450 :
451 : updateExtendedControl(
452 : ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS,
453 0 : CheckFilterOptionsCapability( getCurentSfxFilter() )
454 0 : );
455 : }
456 :
457 0 : void FileDialogHelper_Impl::updateExportButton()
458 : {
459 0 : uno::Reference < XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
460 0 : if ( xCtrlAccess.is() )
461 : {
462 0 : OUString sEllipses( "..." );
463 0 : OUString sOldLabel( xCtrlAccess->getLabel( CommonFilePickerElementIds::PUSHBUTTON_OK ) );
464 :
465 : // initialize button label; we need the label with the mnemonic char
466 0 : if ( maButtonLabel.isEmpty() || maButtonLabel.indexOf( MNEMONIC_CHAR ) == -1 )
467 : {
468 : // cut the ellipses, if necessary
469 0 : sal_Int32 nIndex = sOldLabel.indexOf( sEllipses );
470 0 : if ( -1 == nIndex )
471 0 : nIndex = sOldLabel.getLength();
472 0 : maButtonLabel = sOldLabel.copy( 0, nIndex );
473 : }
474 :
475 0 : OUString sLabel = maButtonLabel;
476 : // filter with options -> append ellipses on export button label
477 0 : if ( CheckFilterOptionsCapability( getCurentSfxFilter() ) )
478 0 : sLabel += "...";
479 :
480 0 : if ( sOldLabel != sLabel )
481 : {
482 : try
483 : {
484 0 : xCtrlAccess->setLabel( CommonFilePickerElementIds::PUSHBUTTON_OK, sLabel );
485 : }
486 0 : catch( const IllegalArgumentException& )
487 : {
488 : SAL_WARN( "sfx.dialog", "FileDialogHelper_Impl::updateExportButton: caught an exception!" );
489 : }
490 0 : }
491 0 : }
492 0 : }
493 :
494 0 : void FileDialogHelper_Impl::updateSelectionBox()
495 : {
496 0 : if ( !mbHasSelectionBox )
497 0 : return;
498 :
499 : // Does the selection box exist?
500 0 : bool bSelectionBoxFound = false;
501 0 : uno::Reference< XControlInformation > xCtrlInfo( mxFileDlg, UNO_QUERY );
502 0 : if ( xCtrlInfo.is() )
503 : {
504 0 : Sequence< OUString > aCtrlList = xCtrlInfo->getSupportedControls();
505 0 : sal_uInt32 nCount = aCtrlList.getLength();
506 0 : for ( sal_uInt32 nCtrl = 0; nCtrl < nCount; ++nCtrl )
507 0 : if ( aCtrlList[ nCtrl ] == "SelectionBox" )
508 : {
509 0 : bSelectionBoxFound = true;
510 0 : break;
511 0 : }
512 : }
513 :
514 0 : if ( bSelectionBoxFound )
515 : {
516 0 : const SfxFilter* pFilter = getCurentSfxFilter();
517 : mbSelectionFltrEnabled = updateExtendedControl(
518 : ExtendedFilePickerElementIds::CHECKBOX_SELECTION,
519 0 : ( mbSelectionEnabled && pFilter && ( pFilter->GetFilterFlags() & SfxFilterFlags::SUPPORTSSELECTION ) ) );
520 0 : uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
521 0 : xCtrlAccess->setValue( ExtendedFilePickerElementIds::CHECKBOX_SELECTION, 0, makeAny( mbSelection ) );
522 0 : }
523 : }
524 :
525 0 : void FileDialogHelper_Impl::enablePasswordBox( bool bInit )
526 : {
527 0 : if ( ! mbHasPassword )
528 0 : return;
529 :
530 0 : bool bWasEnabled = mbIsPwdEnabled;
531 :
532 0 : const SfxFilter* pCurrentFilter = getCurentSfxFilter();
533 : mbIsPwdEnabled = updateExtendedControl(
534 : ExtendedFilePickerElementIds::CHECKBOX_PASSWORD,
535 0 : pCurrentFilter && ( pCurrentFilter->GetFilterFlags() & SfxFilterFlags::ENCRYPTION )
536 0 : );
537 :
538 0 : if( bInit )
539 : {
540 : // in case of inintialization previous state is not interesting
541 0 : if( mbIsPwdEnabled )
542 : {
543 0 : uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
544 0 : if( mbPwdCheckBoxState )
545 0 : xCtrlAccess->setValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0, makeAny( sal_True ) );
546 : }
547 : }
548 0 : else if( !bWasEnabled && mbIsPwdEnabled )
549 : {
550 0 : uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
551 0 : if( mbPwdCheckBoxState )
552 0 : xCtrlAccess->setValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0, makeAny( sal_True ) );
553 : }
554 0 : else if( bWasEnabled && !mbIsPwdEnabled )
555 : {
556 : // remember user settings until checkbox is enabled
557 0 : uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
558 0 : Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0 );
559 0 : bool bPassWord = false;
560 0 : mbPwdCheckBoxState = ( aValue >>= bPassWord ) && bPassWord;
561 0 : xCtrlAccess->setValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0, makeAny( sal_False ) );
562 : }
563 : }
564 :
565 0 : void FileDialogHelper_Impl::updatePreviewState( bool _bUpdatePreviewWindow )
566 : {
567 0 : if ( mbHasPreview )
568 : {
569 0 : uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
570 :
571 : // check, whether or not we have to display a preview
572 0 : if ( xCtrlAccess.is() )
573 : {
574 : try
575 : {
576 0 : Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0 );
577 0 : bool bShowPreview = false;
578 :
579 0 : if ( aValue >>= bShowPreview )
580 : {
581 0 : mbShowPreview = bShowPreview;
582 :
583 : // setShowState has currently no effect for the
584 : // OpenOffice FilePicker (see svtools/source/filepicker/iodlg.cxx)
585 0 : uno::Reference< XFilePreview > xFilePreview( mxFileDlg, UNO_QUERY );
586 0 : if ( xFilePreview.is() )
587 0 : xFilePreview->setShowState( mbShowPreview );
588 :
589 0 : if ( _bUpdatePreviewWindow )
590 0 : TimeOutHdl_Impl( NULL );
591 0 : }
592 : }
593 0 : catch( const Exception& )
594 : {
595 : SAL_WARN( "sfx.dialog", "FileDialogHelper_Impl::updatePreviewState: caught an exception!" );
596 : }
597 0 : }
598 : }
599 0 : }
600 :
601 0 : void FileDialogHelper_Impl::updateVersions()
602 : {
603 0 : Sequence < OUString > aEntries;
604 0 : Sequence < OUString > aPathSeq = mxFileDlg->getFiles();
605 :
606 0 : if ( aPathSeq.getLength() == 1 )
607 : {
608 0 : INetURLObject aObj( aPathSeq[0] );
609 :
610 0 : if ( ( aObj.GetProtocol() == INetProtocol::File ) &&
611 0 : ( utl::UCBContentHelper::IsDocument( aObj.GetMainURL( INetURLObject::NO_DECODE ) ) ) )
612 : {
613 : try
614 : {
615 : uno::Reference< embed::XStorage > xStorage = ::comphelper::OStorageHelper::GetStorageFromURL(
616 : aObj.GetMainURL( INetURLObject::NO_DECODE ),
617 0 : embed::ElementModes::READ );
618 :
619 : DBG_ASSERT( xStorage.is(), "The method must return the storage or throw an exception!" );
620 0 : if ( !xStorage.is() )
621 0 : throw uno::RuntimeException();
622 :
623 0 : uno::Sequence < util::RevisionTag > xVersions = SfxMedium::GetVersionList( xStorage );
624 :
625 0 : aEntries.realloc( xVersions.getLength() + 1 );
626 0 : aEntries[0] = SfxResId( STR_SFX_FILEDLG_ACTUALVERSION ).toString();
627 :
628 0 : for ( sal_Int32 i=0; i<xVersions.getLength(); i++ )
629 0 : aEntries[ i + 1 ] = xVersions[i].Identifier;
630 : }
631 0 : catch( const uno::Exception& )
632 : {
633 : }
634 0 : }
635 : }
636 :
637 0 : uno::Reference < XFilePickerControlAccess > xDlg( mxFileDlg, UNO_QUERY );
638 0 : Any aValue;
639 :
640 : try
641 : {
642 0 : xDlg->setValue( ExtendedFilePickerElementIds::LISTBOX_VERSION,
643 0 : ControlActions::DELETE_ITEMS, aValue );
644 : }
645 0 : catch( const IllegalArgumentException& ){}
646 :
647 0 : sal_Int32 nCount = aEntries.getLength();
648 :
649 0 : if ( nCount )
650 : {
651 : try
652 : {
653 0 : aValue <<= aEntries;
654 0 : xDlg->setValue( ExtendedFilePickerElementIds::LISTBOX_VERSION,
655 0 : ControlActions::ADD_ITEMS, aValue );
656 :
657 0 : Any aPos;
658 0 : aPos <<= (sal_Int32) 0;
659 0 : xDlg->setValue( ExtendedFilePickerElementIds::LISTBOX_VERSION,
660 0 : ControlActions::SET_SELECT_ITEM, aPos );
661 : }
662 0 : catch( const IllegalArgumentException& ){}
663 0 : }
664 0 : }
665 :
666 0 : IMPL_LINK_NOARG_TYPED(FileDialogHelper_Impl, TimeOutHdl_Impl, Idle *, void)
667 : {
668 0 : if ( !mbHasPreview )
669 0 : return;
670 :
671 0 : maGraphic.Clear();
672 :
673 0 : Any aAny;
674 0 : uno::Reference < XFilePreview > xFilePicker( mxFileDlg, UNO_QUERY );
675 :
676 0 : if ( ! xFilePicker.is() )
677 0 : return;
678 :
679 0 : Sequence < OUString > aPathSeq = mxFileDlg->getFiles();
680 :
681 0 : if ( mbShowPreview && ( aPathSeq.getLength() == 1 ) )
682 : {
683 0 : OUString aURL = aPathSeq[0];
684 :
685 0 : if ( ERRCODE_NONE == getGraphic( aURL, maGraphic ) )
686 : {
687 : // changed the code slightly;
688 : // before: the bitmap was scaled and
689 : // surrounded a white frame
690 : // now: the bitmap will only be scaled
691 : // and the filepicker implementation
692 : // is responsible for placing it at its
693 : // proper position and painting a frame
694 :
695 0 : Bitmap aBmp = maGraphic.GetBitmap();
696 0 : if ( !aBmp.IsEmpty() )
697 : {
698 : // scale the bitmap to the correct size
699 0 : sal_Int32 nOutWidth = xFilePicker->getAvailableWidth();
700 0 : sal_Int32 nOutHeight = xFilePicker->getAvailableHeight();
701 0 : sal_Int32 nBmpWidth = aBmp.GetSizePixel().Width();
702 0 : sal_Int32 nBmpHeight = aBmp.GetSizePixel().Height();
703 :
704 0 : double nXRatio = (double) nOutWidth / nBmpWidth;
705 0 : double nYRatio = (double) nOutHeight / nBmpHeight;
706 :
707 0 : if ( nXRatio < nYRatio )
708 0 : aBmp.Scale( nXRatio, nXRatio );
709 : else
710 0 : aBmp.Scale( nYRatio, nYRatio );
711 :
712 : // Convert to true color, to allow CopyPixel
713 0 : aBmp.Convert( BMP_CONVERSION_24BIT );
714 :
715 : // and copy it into the Any
716 0 : SvMemoryStream aData;
717 :
718 0 : WriteDIB(aBmp, aData, false, true);
719 :
720 : const Sequence < sal_Int8 > aBuffer(
721 0 : static_cast< const sal_Int8* >(aData.GetData()),
722 0 : aData.GetEndOfData() );
723 :
724 0 : aAny <<= aBuffer;
725 0 : }
726 0 : }
727 : }
728 :
729 : try
730 : {
731 0 : SolarMutexReleaser aReleaseForCallback;
732 : // clear the preview window
733 0 : xFilePicker->setImage( FilePreviewImageFormats::BITMAP, aAny );
734 : }
735 0 : catch( const IllegalArgumentException& )
736 : {
737 0 : }
738 : }
739 :
740 0 : ErrCode FileDialogHelper_Impl::getGraphic( const OUString& rURL,
741 : Graphic& rGraphic ) const
742 : {
743 0 : if ( utl::UCBContentHelper::IsFolder( rURL ) )
744 0 : return ERRCODE_IO_NOTAFILE;
745 :
746 0 : if ( !mpGraphicFilter )
747 0 : return ERRCODE_IO_NOTSUPPORTED;
748 :
749 : // select graphic filter from dialog filter selection
750 0 : OUString aCurFilter( getFilter() );
751 :
752 0 : sal_uInt16 nFilter = !aCurFilter.isEmpty() && mpGraphicFilter->GetImportFormatCount()
753 0 : ? mpGraphicFilter->GetImportFormatNumber( aCurFilter )
754 0 : : GRFILTER_FORMAT_DONTKNOW;
755 :
756 0 : INetURLObject aURLObj( rURL );
757 :
758 0 : if ( aURLObj.HasError() || INetProtocol::NotValid == aURLObj.GetProtocol() )
759 : {
760 0 : aURLObj.SetSmartProtocol( INetProtocol::File );
761 0 : aURLObj.SetSmartURL( rURL );
762 : }
763 :
764 0 : ErrCode nRet = ERRCODE_NONE;
765 :
766 0 : GraphicFilterImportFlags nFilterImportFlags = GraphicFilterImportFlags::SetLogsizeForJpeg;
767 : // non-local?
768 0 : if ( INetProtocol::File != aURLObj.GetProtocol() )
769 : {
770 0 : SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( rURL, StreamMode::READ );
771 :
772 0 : if( pStream )
773 0 : nRet = mpGraphicFilter->ImportGraphic( rGraphic, rURL, *pStream, nFilter, NULL, nFilterImportFlags );
774 : else
775 0 : nRet = mpGraphicFilter->ImportGraphic( rGraphic, aURLObj, nFilter, NULL, nFilterImportFlags );
776 0 : delete pStream;
777 : }
778 : else
779 : {
780 0 : nRet = mpGraphicFilter->ImportGraphic( rGraphic, aURLObj, nFilter, NULL, nFilterImportFlags );
781 : }
782 :
783 0 : return nRet;
784 : }
785 :
786 0 : ErrCode FileDialogHelper_Impl::getGraphic( Graphic& rGraphic ) const
787 : {
788 0 : ErrCode nRet = ERRCODE_NONE;
789 :
790 : // rhbz#1079672 do not return maGraphic, it need not be the selected file
791 :
792 0 : OUString aPath;;
793 0 : Sequence<OUString> aPathSeq = mxFileDlg->getFiles();
794 :
795 0 : if (aPathSeq.getLength() == 1)
796 : {
797 0 : aPath = aPathSeq[0];
798 : }
799 :
800 0 : if (!aPath.isEmpty())
801 0 : nRet = getGraphic(aPath, rGraphic);
802 : else
803 0 : nRet = ERRCODE_IO_GENERAL;
804 :
805 0 : return nRet;
806 : }
807 :
808 0 : static bool lcl_isSystemFilePicker( const uno::Reference< XFilePicker >& _rxFP )
809 : {
810 : try
811 : {
812 0 : uno::Reference< XServiceInfo > xSI( _rxFP, UNO_QUERY );
813 0 : if ( !xSI.is() )
814 0 : return true;
815 0 : return xSI->supportsService( "com.sun.star.ui.dialogs.SystemFilePicker" );
816 : }
817 0 : catch( const Exception& )
818 : {
819 : }
820 0 : return false;
821 : }
822 :
823 : enum open_or_save_t {OPEN, SAVE, UNDEFINED};
824 0 : static open_or_save_t lcl_OpenOrSave(sal_Int16 const nDialogType)
825 : {
826 0 : switch (nDialogType)
827 : {
828 : case FILEOPEN_SIMPLE:
829 : case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
830 : case FILEOPEN_PLAY:
831 : case FILEOPEN_READONLY_VERSION:
832 : case FILEOPEN_LINK_PREVIEW:
833 0 : return OPEN;
834 : case FILESAVE_SIMPLE:
835 : case FILESAVE_AUTOEXTENSION_PASSWORD:
836 : case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
837 : case FILESAVE_AUTOEXTENSION_SELECTION:
838 : case FILESAVE_AUTOEXTENSION_TEMPLATE:
839 : case FILESAVE_AUTOEXTENSION:
840 0 : return SAVE;
841 : default:
842 : assert(false); // invalid dialog type
843 : }
844 0 : return UNDEFINED;
845 : }
846 :
847 : // FileDialogHelper_Impl
848 :
849 0 : FileDialogHelper_Impl::FileDialogHelper_Impl(
850 : FileDialogHelper* _pAntiImpl,
851 : sal_Int16 nDialogType,
852 : sal_Int64 nFlags,
853 : sal_Int16 nDialog,
854 : vcl::Window* _pPreferredParentWindow,
855 : const OUString& sStandardDir,
856 : const ::com::sun::star::uno::Sequence< OUString >& rBlackList
857 : )
858 : :m_nDialogType ( nDialogType )
859 0 : ,meContext ( FileDialogHelper::UNKNOWN_CONTEXT )
860 : {
861 0 : const char* pServiceName=0;
862 0 : if ( nDialog == SFX2_IMPL_DIALOG_SYSTEM )
863 0 : pServiceName = FILE_OPEN_SERVICE_NAME_OOO;
864 0 : else if ( nDialog == SFX2_IMPL_DIALOG_OOO )
865 0 : pServiceName = FILE_OPEN_SERVICE_NAME_OOO;
866 : else
867 0 : pServiceName = "com.sun.star.ui.dialogs.FilePicker";
868 0 : OUString aService = OUString::createFromAscii( pServiceName );
869 :
870 0 : uno::Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
871 :
872 : // create the file open dialog
873 : // the flags can be SFXWB_INSERT or SFXWB_MULTISELECTION
874 :
875 0 : mpPreferredParentWindow = _pPreferredParentWindow;
876 0 : mpAntiImpl = _pAntiImpl;
877 0 : mnError = ERRCODE_NONE;
878 0 : mbHasAutoExt = false;
879 0 : mbHasPassword = false;
880 0 : m_bHaveFilterOptions = false;
881 0 : mbIsPwdEnabled = true;
882 0 : mbHasVersions = false;
883 0 : mbHasPreview = false;
884 0 : mbShowPreview = false;
885 0 : mbAddGraphicFilter = SFXWB_GRAPHIC == (nFlags & SFXWB_GRAPHIC);
886 0 : mbDeleteMatcher = false;
887 0 : mbInsert = SFXWB_INSERT == ( nFlags & SFXWB_INSERT );
888 0 : mbExport = SFXWB_EXPORT == ( nFlags & SFXWB_EXPORT );
889 0 : mbIsSaveDlg = false;
890 0 : mbIsSaveACopyDlg = SFXWB_SAVEACOPY == ( nFlags & SFXWB_SAVEACOPY );
891 0 : mbPwdCheckBoxState = false;
892 0 : mbSelection = false;
893 0 : mbSelectionEnabled = true;
894 0 : mbHasSelectionBox = false;
895 0 : mbSelectionFltrEnabled = false;
896 :
897 : // default settings
898 0 : m_nDontFlags = SFX_FILTER_NOTINSTALLED | SfxFilterFlags::INTERNAL | SfxFilterFlags::NOTINFILEDLG;
899 0 : if (OPEN == lcl_OpenOrSave(m_nDialogType))
900 0 : m_nMustFlags = SfxFilterFlags::IMPORT;
901 : else
902 0 : m_nMustFlags = SfxFilterFlags::EXPORT;
903 :
904 :
905 0 : mpMatcher = NULL;
906 0 : mpGraphicFilter = NULL;
907 0 : mnPostUserEventId = 0;
908 :
909 : // create the picker component
910 0 : mxFileDlg.set(xFactory->createInstance( aService ), css::uno::UNO_QUERY);
911 0 : mbSystemPicker = lcl_isSystemFilePicker( mxFileDlg );
912 :
913 0 : uno::Reference< XFilePickerNotifier > xNotifier( mxFileDlg, UNO_QUERY );
914 0 : uno::Reference< XInitialization > xInit( mxFileDlg, UNO_QUERY );
915 :
916 0 : if ( ! mxFileDlg.is() || ! xNotifier.is() )
917 : {
918 0 : mnError = ERRCODE_ABORT;
919 0 : return;
920 : }
921 :
922 :
923 0 : if ( xInit.is() )
924 : {
925 0 : sal_Int16 nTemplateDescription = TemplateDescription::FILEOPEN_SIMPLE;
926 :
927 0 : switch ( m_nDialogType )
928 : {
929 : case FILEOPEN_SIMPLE:
930 0 : nTemplateDescription = TemplateDescription::FILEOPEN_SIMPLE;
931 0 : break;
932 :
933 : case FILESAVE_SIMPLE:
934 0 : nTemplateDescription = TemplateDescription::FILESAVE_SIMPLE;
935 0 : mbIsSaveDlg = true;
936 0 : break;
937 :
938 : case FILESAVE_AUTOEXTENSION_PASSWORD:
939 0 : nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD;
940 0 : mbHasPassword = true;
941 0 : mbHasAutoExt = true;
942 0 : mbIsSaveDlg = true;
943 0 : break;
944 :
945 : case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
946 0 : nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS;
947 0 : mbHasPassword = true;
948 :
949 0 : m_bHaveFilterOptions = true;
950 0 : if( xFactory.is() )
951 : {
952 0 : mxFilterCFG = uno::Reference< XNameAccess >(
953 0 : xFactory->createInstance( "com.sun.star.document.FilterFactory" ),
954 0 : UNO_QUERY );
955 : }
956 :
957 0 : mbHasAutoExt = true;
958 0 : mbIsSaveDlg = true;
959 0 : break;
960 :
961 : case FILESAVE_AUTOEXTENSION_SELECTION:
962 0 : nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION_SELECTION;
963 0 : mbHasAutoExt = true;
964 0 : mbIsSaveDlg = true;
965 0 : mbHasSelectionBox = true;
966 0 : if ( mbExport && !mxFilterCFG.is() && xFactory.is() )
967 : {
968 0 : mxFilterCFG = uno::Reference< XNameAccess >(
969 0 : xFactory->createInstance( "com.sun.star.document.FilterFactory" ),
970 0 : UNO_QUERY );
971 : }
972 0 : break;
973 :
974 : case FILESAVE_AUTOEXTENSION_TEMPLATE:
975 0 : nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION_TEMPLATE;
976 0 : mbHasAutoExt = true;
977 0 : mbIsSaveDlg = true;
978 0 : break;
979 :
980 : case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
981 0 : nTemplateDescription = TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE;
982 0 : mbHasPreview = true;
983 :
984 : // aPreviewTimer
985 0 : maPreviewIdle.SetPriority( SchedulerPriority::LOWEST );
986 0 : maPreviewIdle.SetIdleHdl( LINK( this, FileDialogHelper_Impl, TimeOutHdl_Impl ) );
987 0 : break;
988 :
989 : case FILEOPEN_PLAY:
990 0 : nTemplateDescription = TemplateDescription::FILEOPEN_PLAY;
991 0 : break;
992 :
993 : case FILEOPEN_READONLY_VERSION:
994 0 : nTemplateDescription = TemplateDescription::FILEOPEN_READONLY_VERSION;
995 0 : mbHasVersions = true;
996 0 : break;
997 :
998 : case FILEOPEN_LINK_PREVIEW:
999 0 : nTemplateDescription = TemplateDescription::FILEOPEN_LINK_PREVIEW;
1000 0 : mbHasPreview = true;
1001 : // aPreviewTimer
1002 0 : maPreviewIdle.SetPriority( SchedulerPriority::LOWEST );
1003 0 : maPreviewIdle.SetIdleHdl( LINK( this, FileDialogHelper_Impl, TimeOutHdl_Impl ) );
1004 0 : break;
1005 :
1006 : case FILESAVE_AUTOEXTENSION:
1007 0 : nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION;
1008 0 : mbHasAutoExt = true;
1009 0 : mbIsSaveDlg = true;
1010 0 : break;
1011 :
1012 : default:
1013 : SAL_WARN( "sfx.dialog", "FileDialogHelper::ctor with unknown type" );
1014 0 : break;
1015 : }
1016 :
1017 0 : Sequence < Any > aInitArguments( !mpPreferredParentWindow ? 3 : 4 );
1018 :
1019 : // This is a hack. We currently know that the internal file picker implementation
1020 : // supports the extended arguments as specified below.
1021 : // TODO:
1022 : // a) adjust the service description so that it includes the TemplateDescription and ParentWindow args
1023 : // b) adjust the implementation of the system file picker to that it recognizes it
1024 0 : if ( mbSystemPicker )
1025 : {
1026 0 : aInitArguments[0] <<= nTemplateDescription;
1027 : }
1028 : else
1029 : {
1030 0 : aInitArguments[0] <<= NamedValue(
1031 : OUString( "TemplateDescription" ),
1032 : makeAny( nTemplateDescription )
1033 0 : );
1034 :
1035 0 : OUString sStandardDirTemp = sStandardDir;
1036 :
1037 0 : aInitArguments[1] <<= NamedValue(
1038 : OUString( "StandardDir" ),
1039 : makeAny( sStandardDirTemp )
1040 0 : );
1041 :
1042 0 : aInitArguments[2] <<= NamedValue(
1043 : OUString( "BlackList" ),
1044 : makeAny( rBlackList )
1045 0 : );
1046 :
1047 :
1048 0 : if ( mpPreferredParentWindow )
1049 0 : aInitArguments[3] <<= NamedValue(
1050 : OUString( "ParentWindow" ),
1051 : makeAny( VCLUnoHelper::GetInterface( mpPreferredParentWindow ) )
1052 0 : );
1053 : }
1054 :
1055 : try
1056 : {
1057 0 : xInit->initialize( aInitArguments );
1058 : }
1059 0 : catch( const Exception& )
1060 : {
1061 : OSL_FAIL( "FileDialogHelper_Impl::FileDialogHelper_Impl: could not initialize the picker!" );
1062 0 : }
1063 : }
1064 :
1065 :
1066 : // set multiselection mode
1067 0 : if ( nFlags & SFXWB_MULTISELECTION )
1068 0 : mxFileDlg->setMultiSelectionMode( sal_True );
1069 :
1070 0 : if (mbAddGraphicFilter) // generate graphic filter only on demand
1071 : {
1072 0 : addGraphicFilter();
1073 : }
1074 :
1075 : // Export dialog
1076 0 : if ( mbExport )
1077 : {
1078 0 : mxFileDlg->setTitle( SfxResId( STR_SFX_EXPLORERFILE_EXPORT ).toString() );
1079 : try {
1080 0 : com::sun::star::uno::Reference < XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY_THROW );
1081 0 : xCtrlAccess->enableControl( ExtendedFilePickerElementIds::LISTBOX_FILTER_SELECTOR, sal_True );
1082 : }
1083 0 : catch( const Exception & ) { }
1084 : }
1085 :
1086 : // Save a copy dialog
1087 0 : if ( mbIsSaveACopyDlg )
1088 : {
1089 0 : mxFileDlg->setTitle( SfxResId( STR_PB_SAVEACOPY ).toString() );
1090 : }
1091 :
1092 : // the "insert file" dialog needs another title
1093 0 : if ( mbInsert )
1094 : {
1095 0 : mxFileDlg->setTitle( SfxResId( STR_SFX_EXPLORERFILE_INSERT ).toString() );
1096 0 : uno::Reference < XFilePickerControlAccess > xExtDlg( mxFileDlg, UNO_QUERY );
1097 0 : if ( xExtDlg.is() )
1098 : {
1099 : try
1100 : {
1101 0 : xExtDlg->setLabel( CommonFilePickerElementIds::PUSHBUTTON_OK,
1102 0 : SfxResId( STR_SFX_EXPLORERFILE_BUTTONINSERT ).toString() );
1103 : }
1104 0 : catch( const IllegalArgumentException& ){}
1105 0 : }
1106 : }
1107 :
1108 : // add the event listener
1109 0 : xNotifier->addFilePickerListener( this );
1110 : }
1111 :
1112 0 : FileDialogHelper_Impl::~FileDialogHelper_Impl()
1113 : {
1114 : // Remove user event if we haven't received it yet
1115 0 : if ( mnPostUserEventId )
1116 0 : Application::RemoveUserEvent( mnPostUserEventId );
1117 0 : mnPostUserEventId = 0;
1118 :
1119 0 : delete mpGraphicFilter;
1120 :
1121 0 : if ( mbDeleteMatcher )
1122 0 : delete mpMatcher;
1123 :
1124 0 : maPreviewIdle.SetIdleHdl( Link<Idle *, void>() );
1125 :
1126 0 : ::comphelper::disposeComponent( mxFileDlg );
1127 0 : }
1128 :
1129 0 : void FileDialogHelper_Impl::setControlHelpIds( const sal_Int16* _pControlId, const char** _pHelpId )
1130 : {
1131 : DBG_ASSERT( _pControlId && _pHelpId, "FileDialogHelper_Impl::setControlHelpIds: invalid array pointers!" );
1132 0 : if ( !_pControlId || !_pHelpId )
1133 0 : return;
1134 :
1135 : // forward these ids to the file picker
1136 : try
1137 : {
1138 0 : const OUString sHelpIdPrefix( INET_HID_SCHEME );
1139 : // the ids for the single controls
1140 0 : uno::Reference< XFilePickerControlAccess > xControlAccess( mxFileDlg, UNO_QUERY );
1141 0 : if ( xControlAccess.is() )
1142 : {
1143 0 : while ( *_pControlId )
1144 : {
1145 : DBG_ASSERT( INetURLObject( OStringToOUString( *_pHelpId, RTL_TEXTENCODING_UTF8 ) ).GetProtocol() == INetProtocol::NotValid, "Wrong HelpId!" );
1146 0 : OUString sId( sHelpIdPrefix );
1147 0 : sId += OUString( *_pHelpId, strlen( *_pHelpId ), RTL_TEXTENCODING_UTF8 );
1148 0 : xControlAccess->setValue( *_pControlId, ControlActions::SET_HELP_URL, makeAny( sId ) );
1149 :
1150 0 : ++_pControlId; ++_pHelpId;
1151 0 : }
1152 0 : }
1153 : }
1154 0 : catch( const Exception& )
1155 : {
1156 : OSL_FAIL( "FileDialogHelper_Impl::setControlHelpIds: caught an exception while setting the help ids!" );
1157 : }
1158 : }
1159 :
1160 0 : IMPL_LINK_NOARG( FileDialogHelper_Impl, InitControls )
1161 : {
1162 0 : mnPostUserEventId = 0;
1163 0 : enablePasswordBox( true );
1164 0 : updateFilterOptionsBox( );
1165 0 : updateSelectionBox( );
1166 :
1167 0 : return 0L;
1168 : }
1169 :
1170 0 : void FileDialogHelper_Impl::preExecute()
1171 : {
1172 0 : loadConfig( );
1173 0 : setDefaultValues( );
1174 0 : updatePreviewState( false );
1175 :
1176 0 : implInitializeFileName( );
1177 :
1178 : #if !(defined(MACOSX) && defined(MACOSX)) && !defined(WNT)
1179 : // allow for dialog implementations which need to be executed before they return valid values for
1180 : // current filter and such
1181 :
1182 : // On Vista (at least SP1) it's the same as on MacOSX, the modal dialog won't let message pass
1183 : // through before it returns from execution
1184 0 : mnPostUserEventId = Application::PostUserEvent( LINK( this, FileDialogHelper_Impl, InitControls ) );
1185 : #else
1186 : // However, the Mac OS X implementation's pickers run modally in execute and so the event doesn't
1187 : // get through in time... so we call the methods directly
1188 : enablePasswordBox( true );
1189 : updateFilterOptionsBox( );
1190 : updateSelectionBox( );
1191 : #endif
1192 0 : }
1193 :
1194 0 : void FileDialogHelper_Impl::postExecute( sal_Int16 _nResult )
1195 : {
1196 0 : if ( ExecutableDialogResults::CANCEL != _nResult )
1197 0 : saveConfig();
1198 0 : }
1199 :
1200 0 : void FileDialogHelper_Impl::implInitializeFileName( )
1201 : {
1202 0 : if ( !maFileName.isEmpty() )
1203 : {
1204 0 : INetURLObject aObj( maPath );
1205 0 : aObj.Append( maFileName );
1206 :
1207 : // in case we're operating as save dialog, and "auto extension" is checked,
1208 : // cut the extension from the name
1209 0 : if ( mbIsSaveDlg && mbHasAutoExt )
1210 : {
1211 : try
1212 : {
1213 0 : bool bAutoExtChecked = false;
1214 :
1215 0 : uno::Reference < XFilePickerControlAccess > xControlAccess( mxFileDlg, UNO_QUERY );
1216 0 : if ( xControlAccess.is()
1217 0 : && ( xControlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, 0 )
1218 0 : >>= bAutoExtChecked
1219 : )
1220 : )
1221 : {
1222 0 : if ( bAutoExtChecked )
1223 : { // cut the extension
1224 0 : aObj.removeExtension( );
1225 0 : mxFileDlg->setDefaultName( aObj.GetName( INetURLObject::DECODE_WITH_CHARSET ) );
1226 : }
1227 0 : }
1228 : }
1229 0 : catch( const Exception& )
1230 : {
1231 : OSL_FAIL( "FileDialogHelper_Impl::implInitializeFileName: could not ask for the auto-extension current-value!" );
1232 : }
1233 0 : }
1234 : }
1235 0 : }
1236 :
1237 0 : sal_Int16 FileDialogHelper_Impl::implDoExecute()
1238 : {
1239 0 : preExecute();
1240 :
1241 0 : sal_Int16 nRet = ExecutableDialogResults::CANCEL;
1242 :
1243 : //On MacOSX the native file picker has to run in the primordial thread because of drawing issues
1244 : //On Linux the native gtk file picker, when backed by gnome-vfs2, needs to be run in the same
1245 : //primordial thread as the ucb gnome-vfs2 provider was initialized in.
1246 :
1247 : {
1248 : try
1249 : {
1250 : #ifdef WNT
1251 : if ( mbSystemPicker )
1252 : {
1253 : SolarMutexReleaser aSolarMutex;
1254 : nRet = mxFileDlg->execute();
1255 : }
1256 : else
1257 : #endif
1258 0 : nRet = mxFileDlg->execute();
1259 : }
1260 0 : catch( const Exception& )
1261 : {
1262 : SAL_WARN( "sfx.dialog", "FileDialogHelper_Impl::implDoExecute: caught an exception!" );
1263 : }
1264 : }
1265 :
1266 0 : postExecute( nRet );
1267 :
1268 0 : return nRet;
1269 : }
1270 :
1271 0 : void FileDialogHelper_Impl::implStartExecute()
1272 : {
1273 : DBG_ASSERT( mxFileDlg.is(), "invalid file dialog" );
1274 :
1275 0 : preExecute();
1276 :
1277 0 : if ( mbSystemPicker )
1278 : {
1279 : }
1280 : else
1281 : {
1282 : try
1283 : {
1284 0 : uno::Reference< XAsynchronousExecutableDialog > xAsyncDlg( mxFileDlg, UNO_QUERY );
1285 0 : if ( xAsyncDlg.is() )
1286 0 : xAsyncDlg->startExecuteModal( this );
1287 : }
1288 0 : catch( const Exception& )
1289 : {
1290 : SAL_WARN( "sfx.dialog", "FileDialogHelper_Impl::implDoExecute: caught an exception!" );
1291 : }
1292 : }
1293 0 : }
1294 :
1295 0 : void lcl_saveLastURLs(std::vector<OUString>& rpURLList,
1296 : ::std::vector< OUString >& lLastURLs )
1297 : {
1298 0 : lLastURLs.clear();
1299 0 : for(std::vector<OUString>::iterator i = rpURLList.begin(); i != rpURLList.end(); ++i)
1300 0 : lLastURLs.push_back(*i);
1301 0 : }
1302 :
1303 0 : void FileDialogHelper_Impl::implGetAndCacheFiles(const uno::Reference< XInterface >& xPicker, std::vector<OUString>& rpURLList, const SfxFilter* pFilter)
1304 : {
1305 0 : rpURLList.clear();
1306 :
1307 0 : OUString sExtension;
1308 0 : if (pFilter)
1309 : {
1310 0 : sExtension = pFilter->GetDefaultExtension ();
1311 0 : sExtension = comphelper::string::remove(sExtension, '*');
1312 0 : sExtension = comphelper::string::remove(sExtension, '.');
1313 : }
1314 :
1315 : // a) the new way (optional!)
1316 0 : uno::Reference< XFilePicker2 > xPickNew(xPicker, UNO_QUERY);
1317 0 : if (xPickNew.is())
1318 : {
1319 0 : Sequence< OUString > lFiles = xPickNew->getSelectedFiles();
1320 0 : ::sal_Int32 nFiles = lFiles.getLength();
1321 0 : for(sal_Int32 i = 0; i < nFiles; ++i)
1322 0 : rpURLList.push_back(lFiles[i]);
1323 : }
1324 :
1325 : // b) the olde way ... non optional.
1326 : else
1327 : {
1328 0 : uno::Reference< XFilePicker > xPickOld(xPicker, UNO_QUERY_THROW);
1329 0 : Sequence< OUString > lFiles = xPickOld->getFiles();
1330 0 : ::sal_Int32 nFiles = lFiles.getLength();
1331 0 : if ( nFiles == 1 )
1332 : {
1333 0 : rpURLList.push_back(lFiles[0]);
1334 : }
1335 0 : else if ( nFiles > 1 )
1336 : {
1337 0 : INetURLObject aPath( lFiles[0] );
1338 0 : aPath.setFinalSlash();
1339 :
1340 0 : for (::sal_Int32 i = 1; i < nFiles; i++)
1341 : {
1342 0 : if (i == 1)
1343 0 : aPath.Append( lFiles[i] );
1344 : else
1345 0 : aPath.setName( lFiles[i] );
1346 :
1347 0 : rpURLList.push_back(aPath.GetMainURL(INetURLObject::NO_DECODE));
1348 0 : }
1349 0 : }
1350 : }
1351 :
1352 0 : lcl_saveLastURLs(rpURLList, mlLastURLs);
1353 0 : }
1354 :
1355 0 : ErrCode FileDialogHelper_Impl::execute( std::vector<OUString>& rpURLList,
1356 : SfxItemSet *& rpSet,
1357 : OUString& rFilter )
1358 : {
1359 : // rFilter is a pure output parameter, it shouldn't be used for anything else
1360 : // changing this would surely break code
1361 : // rpSet is in/out parameter, usually just a media-descriptor that can be changed by dialog
1362 :
1363 0 : uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
1364 :
1365 : // retrieves parameters from rpSet
1366 : // for now only Password is used
1367 0 : if ( rpSet )
1368 : {
1369 : // check password checkbox if the document had password before
1370 0 : if( mbHasPassword )
1371 : {
1372 0 : SFX_ITEMSET_ARG( rpSet, pPassItem, SfxBoolItem, SID_PASSWORDINTERACTION, false );
1373 0 : mbPwdCheckBoxState = ( pPassItem != NULL && pPassItem->GetValue() );
1374 :
1375 : // in case the document has password to modify, the dialog should be shown
1376 0 : SFX_ITEMSET_ARG( rpSet, pPassToModifyItem, SfxUnoAnyItem, SID_MODIFYPASSWORDINFO, false );
1377 0 : mbPwdCheckBoxState |= ( pPassToModifyItem && pPassToModifyItem->GetValue().hasValue() );
1378 : }
1379 :
1380 0 : SFX_ITEMSET_ARG( rpSet, pSelectItem, SfxBoolItem, SID_SELECTION, false );
1381 0 : if ( pSelectItem )
1382 0 : mbSelection = pSelectItem->GetValue();
1383 : else
1384 0 : mbSelectionEnabled = false;
1385 :
1386 : // the password will be set in case user decide so
1387 0 : rpSet->ClearItem( SID_PASSWORDINTERACTION );
1388 0 : rpSet->ClearItem( SID_PASSWORD );
1389 0 : rpSet->ClearItem( SID_ENCRYPTIONDATA );
1390 0 : rpSet->ClearItem( SID_RECOMMENDREADONLY );
1391 0 : rpSet->ClearItem( SID_MODIFYPASSWORDINFO );
1392 :
1393 : }
1394 :
1395 0 : if ( mbHasPassword && !mbPwdCheckBoxState )
1396 : {
1397 0 : SvtSecurityOptions aSecOpt;
1398 : mbPwdCheckBoxState = (
1399 0 : aSecOpt.IsOptionSet( SvtSecurityOptions::E_DOCWARN_RECOMMENDPASSWORD ) );
1400 : }
1401 :
1402 0 : rpURLList.clear();
1403 :
1404 0 : if ( ! mxFileDlg.is() )
1405 0 : return ERRCODE_ABORT;
1406 :
1407 0 : if ( ExecutableDialogResults::CANCEL != implDoExecute() )
1408 : {
1409 : // create an itemset if there is no
1410 0 : if( !rpSet )
1411 0 : rpSet = new SfxAllItemSet( SfxGetpApp()->GetPool() );
1412 :
1413 : // the item should remain only if it was set by the dialog
1414 0 : rpSet->ClearItem( SID_SELECTION );
1415 :
1416 0 : if( mbExport && mbHasSelectionBox )
1417 : {
1418 : try
1419 : {
1420 0 : Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_SELECTION, 0 );
1421 0 : bool bSelection = false;
1422 0 : if ( aValue >>= bSelection )
1423 0 : rpSet->Put( SfxBoolItem( SID_SELECTION, bSelection ) );
1424 : }
1425 0 : catch( const IllegalArgumentException& )
1426 : {
1427 : OSL_FAIL( "FileDialogHelper_Impl::execute: caught an IllegalArgumentException!" );
1428 : }
1429 : }
1430 :
1431 :
1432 : // set the read-only flag. When inserting a file, this flag is always set
1433 0 : if ( mbInsert )
1434 0 : rpSet->Put( SfxBoolItem( SID_DOC_READONLY, true ) );
1435 : else
1436 : {
1437 0 : if ( ( FILEOPEN_READONLY_VERSION == m_nDialogType ) && xCtrlAccess.is() )
1438 : {
1439 : try
1440 : {
1441 0 : Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_READONLY, 0 );
1442 0 : bool bReadOnly = false;
1443 0 : if ( ( aValue >>= bReadOnly ) && bReadOnly )
1444 0 : rpSet->Put( SfxBoolItem( SID_DOC_READONLY, bReadOnly ) );
1445 : }
1446 0 : catch( const IllegalArgumentException& )
1447 : {
1448 : OSL_FAIL( "FileDialogHelper_Impl::execute: caught an IllegalArgumentException!" );
1449 : }
1450 : }
1451 : }
1452 0 : if ( mbHasVersions && xCtrlAccess.is() )
1453 : {
1454 : try
1455 : {
1456 0 : Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::LISTBOX_VERSION,
1457 0 : ControlActions::GET_SELECTED_ITEM_INDEX );
1458 0 : sal_Int32 nVersion = 0;
1459 0 : if ( ( aValue >>= nVersion ) && nVersion > 0 )
1460 : // open a special version; 0 == current version
1461 0 : rpSet->Put( SfxInt16Item( SID_VERSION, (short)nVersion ) );
1462 : }
1463 0 : catch( const IllegalArgumentException& ){}
1464 : }
1465 :
1466 : // set the filter
1467 0 : getRealFilter( rFilter );
1468 :
1469 0 : const SfxFilter* pCurrentFilter = getCurentSfxFilter();
1470 :
1471 : // fill the rpURLList
1472 0 : implGetAndCacheFiles( mxFileDlg, rpURLList, pCurrentFilter );
1473 0 : if ( rpURLList.empty() )
1474 0 : return ERRCODE_ABORT;
1475 :
1476 : // check, whether or not we have to display a password box
1477 0 : if ( pCurrentFilter && mbHasPassword && mbIsPwdEnabled && xCtrlAccess.is() )
1478 : {
1479 : try
1480 : {
1481 0 : Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0 );
1482 0 : bool bPassWord = false;
1483 0 : if ( ( aValue >>= bPassWord ) && bPassWord )
1484 : {
1485 : // ask for a password
1486 0 : OUString aDocName(rpURLList[0]);
1487 0 : ErrCode errCode = RequestPassword(pCurrentFilter, aDocName, rpSet);
1488 0 : if (errCode != ERRCODE_NONE)
1489 0 : return errCode;
1490 0 : }
1491 : }
1492 0 : catch( const IllegalArgumentException& ){}
1493 : }
1494 :
1495 0 : SaveLastUsedFilter();
1496 0 : return ERRCODE_NONE;
1497 : }
1498 : else
1499 0 : return ERRCODE_ABORT;
1500 : }
1501 :
1502 0 : ErrCode FileDialogHelper_Impl::execute()
1503 : {
1504 0 : if ( ! mxFileDlg.is() )
1505 0 : return ERRCODE_ABORT;
1506 :
1507 0 : sal_Int16 nRet = implDoExecute();
1508 :
1509 0 : maPath = mxFileDlg->getDisplayDirectory();
1510 :
1511 0 : if ( ExecutableDialogResults::CANCEL == nRet )
1512 0 : return ERRCODE_ABORT;
1513 : else
1514 : {
1515 0 : return ERRCODE_NONE;
1516 : }
1517 : }
1518 :
1519 0 : OUString FileDialogHelper_Impl::getPath() const
1520 : {
1521 0 : OUString aPath;
1522 :
1523 0 : if ( mxFileDlg.is() )
1524 0 : aPath = mxFileDlg->getDisplayDirectory();
1525 :
1526 0 : if ( aPath.isEmpty() )
1527 0 : aPath = maPath;
1528 :
1529 0 : return aPath;
1530 : }
1531 :
1532 0 : OUString FileDialogHelper_Impl::getFilter() const
1533 : {
1534 0 : OUString aFilter = getCurrentFilterUIName();
1535 :
1536 0 : if( aFilter.isEmpty() )
1537 0 : aFilter = maCurFilter;
1538 :
1539 0 : return aFilter;
1540 : }
1541 :
1542 0 : void FileDialogHelper_Impl::getRealFilter( OUString& _rFilter ) const
1543 : {
1544 0 : _rFilter = getCurrentFilterUIName();
1545 :
1546 0 : if ( _rFilter.isEmpty() )
1547 0 : _rFilter = maCurFilter;
1548 :
1549 0 : if ( !_rFilter.isEmpty() && mpMatcher )
1550 : {
1551 : const SfxFilter* pFilter =
1552 0 : mpMatcher->GetFilter4UIName( _rFilter, m_nMustFlags, m_nDontFlags );
1553 0 : _rFilter = pFilter ? pFilter->GetFilterName() : OUString("");
1554 : }
1555 0 : }
1556 :
1557 0 : void FileDialogHelper_Impl::verifyPath()
1558 : {
1559 : #ifdef UNX
1560 : // lp#905355, fdo#43895
1561 : // Check that the file has read only permission and is in /tmp -- this is
1562 : // the case if we have opened the file from the web with firefox only.
1563 0 : if (maFileName.isEmpty()) {
1564 0 : return;
1565 : }
1566 0 : INetURLObject url(maPath);
1567 0 : if (url.GetProtocol() != INetProtocol::File
1568 0 : || url.getName(0, true, INetURLObject::DECODE_WITH_CHARSET) != "tmp")
1569 : {
1570 0 : return;
1571 : }
1572 0 : if (maFileName.indexOf('/') != -1) {
1573 : SAL_WARN("sfx.dialog", maFileName << " contains /");
1574 0 : return;
1575 : }
1576 : url.insertName(
1577 : maFileName, false, INetURLObject::LAST_SEGMENT, true,
1578 0 : INetURLObject::ENCODE_ALL);
1579 0 : OUString sysPathU;
1580 : osl::FileBase::RC e = osl::FileBase::getSystemPathFromFileURL(
1581 0 : url.GetMainURL(INetURLObject::NO_DECODE), sysPathU);
1582 0 : if (e != osl::FileBase::E_None) {
1583 : SAL_WARN(
1584 : "sfx.dialog",
1585 : "getSystemPathFromFileURL("
1586 : << url.GetMainURL(INetURLObject::NO_DECODE) << ") failed with "
1587 : << +e);
1588 0 : return;
1589 : }
1590 0 : OString sysPathC;
1591 0 : if (!sysPathU.convertToString(
1592 0 : &sysPathC, osl_getThreadTextEncoding(),
1593 : (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
1594 0 : | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
1595 : {
1596 : SAL_WARN(
1597 : "sfx.dialog",
1598 : "convertToString(" << sysPathU << ") failed for encoding "
1599 : << +osl_getThreadTextEncoding());
1600 0 : return;
1601 : }
1602 : struct stat aFileStat;
1603 0 : if (stat(sysPathC.getStr(), &aFileStat) == -1) {
1604 : SAL_WARN(
1605 : "sfx.dialog",
1606 : "stat(" << sysPathC.getStr() << ") failed with errno " << errno);
1607 0 : return;
1608 : }
1609 0 : if ((aFileStat.st_mode & (S_IRWXO | S_IRWXG | S_IRWXU)) == S_IRUSR) {
1610 0 : maPath = SvtPathOptions().GetWorkPath();
1611 0 : mxFileDlg->setDisplayDirectory( maPath );
1612 0 : }
1613 : #endif
1614 : }
1615 :
1616 0 : void FileDialogHelper_Impl::displayFolder( const OUString& _rPath )
1617 : {
1618 0 : if ( _rPath.isEmpty() )
1619 : // nothing to do
1620 0 : return;
1621 :
1622 0 : maPath = _rPath;
1623 0 : if ( mxFileDlg.is() )
1624 : {
1625 : try
1626 : {
1627 0 : mxFileDlg->setDisplayDirectory( maPath );
1628 0 : verifyPath();
1629 : }
1630 0 : catch( const IllegalArgumentException& )
1631 : {
1632 : OSL_FAIL( "FileDialogHelper_Impl::displayFolder: caught an exception!" );
1633 : }
1634 : }
1635 : }
1636 :
1637 0 : void FileDialogHelper_Impl::setFileName( const OUString& _rFile )
1638 : {
1639 0 : maFileName = _rFile;
1640 0 : if ( mxFileDlg.is() )
1641 : {
1642 : try
1643 : {
1644 0 : mxFileDlg->setDefaultName( maFileName );
1645 0 : verifyPath();
1646 : }
1647 0 : catch( const IllegalArgumentException& )
1648 : {
1649 : OSL_FAIL( "FileDialogHelper_Impl::setFileName: caught an exception!" );
1650 : }
1651 : }
1652 0 : }
1653 :
1654 0 : void FileDialogHelper_Impl::setFilter( const OUString& rFilter )
1655 : {
1656 : DBG_ASSERT( rFilter.indexOf(':') == -1, "Old filter name used!");
1657 :
1658 0 : maCurFilter = rFilter;
1659 :
1660 0 : if ( !rFilter.isEmpty() && mpMatcher )
1661 : {
1662 : const SfxFilter* pFilter = mpMatcher->GetFilter4FilterName(
1663 0 : rFilter, m_nMustFlags, m_nDontFlags );
1664 0 : if ( pFilter )
1665 0 : maCurFilter = pFilter->GetUIName();
1666 : }
1667 :
1668 0 : uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY );
1669 :
1670 0 : if ( !maCurFilter.isEmpty() && xFltMgr.is() )
1671 : {
1672 : try
1673 : {
1674 0 : xFltMgr->setCurrentFilter( maCurFilter );
1675 : }
1676 0 : catch( const IllegalArgumentException& ){}
1677 0 : }
1678 0 : }
1679 :
1680 0 : void FileDialogHelper_Impl::createMatcher( const OUString& rFactory )
1681 : {
1682 0 : if (mbDeleteMatcher)
1683 0 : delete mpMatcher;
1684 :
1685 0 : mpMatcher = new SfxFilterMatcher( SfxObjectShell::GetServiceNameFromFactory(rFactory) );
1686 0 : mbDeleteMatcher = true;
1687 0 : }
1688 :
1689 0 : void FileDialogHelper_Impl::addFilters( const OUString& rFactory,
1690 : SfxFilterFlags nMust,
1691 : SfxFilterFlags nDont )
1692 : {
1693 0 : uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY );
1694 :
1695 0 : if ( ! xFltMgr.is() )
1696 0 : return;
1697 :
1698 0 : if (mbDeleteMatcher)
1699 0 : delete mpMatcher;
1700 :
1701 : // we still need a matcher to convert UI names to filter names
1702 0 : if ( rFactory.isEmpty() )
1703 : {
1704 0 : SfxApplication *pSfxApp = SfxGetpApp();
1705 0 : mpMatcher = &pSfxApp->GetFilterMatcher();
1706 0 : mbDeleteMatcher = false;
1707 : }
1708 : else
1709 : {
1710 0 : mpMatcher = new SfxFilterMatcher( rFactory );
1711 0 : mbDeleteMatcher = true;
1712 : }
1713 :
1714 0 : uno::Reference< XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
1715 : uno::Reference< XContainerQuery > xFilterCont(
1716 0 : xSMGR->createInstance("com.sun.star.document.FilterFactory"),
1717 0 : UNO_QUERY);
1718 0 : if ( ! xFilterCont.is() )
1719 0 : return;
1720 :
1721 0 : m_nMustFlags |= nMust;
1722 0 : m_nDontFlags |= nDont;
1723 :
1724 : // create the list of filters
1725 0 : OUStringBuffer sQuery(256);
1726 0 : sQuery.append("getSortedFilterList()");
1727 0 : sQuery.append(":module=");
1728 0 : sQuery.append(rFactory); // use long name here !
1729 0 : sQuery.append(":iflags=");
1730 0 : sQuery.append(OUString::number(static_cast<sal_Int32>(m_nMustFlags)));
1731 0 : sQuery.append(":eflags=");
1732 0 : sQuery.append(OUString::number(static_cast<sal_Int32>(m_nDontFlags)));
1733 :
1734 0 : uno::Reference< XEnumeration > xResult;
1735 : try
1736 : {
1737 0 : xResult = xFilterCont->createSubSetEnumerationByQuery(sQuery.makeStringAndClear());
1738 : }
1739 0 : catch( const uno::Exception& )
1740 : {
1741 : SAL_WARN( "sfx.dialog", "Could not get filters from the configuration!" );
1742 : }
1743 :
1744 0 : TSortedFilterList aIter (xResult);
1745 :
1746 : // append the filters
1747 0 : OUString sFirstFilter;
1748 0 : if (OPEN == lcl_OpenOrSave(m_nDialogType))
1749 0 : ::sfx2::appendFiltersForOpen( aIter, xFltMgr, sFirstFilter, *this );
1750 0 : else if ( mbExport )
1751 0 : ::sfx2::appendExportFilters( aIter, xFltMgr, sFirstFilter, *this );
1752 : else
1753 0 : ::sfx2::appendFiltersForSave( aIter, xFltMgr, sFirstFilter, *this, rFactory );
1754 :
1755 : // set our initial selected filter (if we do not already have one)
1756 0 : if ( maSelectFilter.isEmpty() )
1757 0 : maSelectFilter = sFirstFilter;
1758 : }
1759 :
1760 0 : void FileDialogHelper_Impl::addFilter( const OUString& rFilterName,
1761 : const OUString& rExtension )
1762 : {
1763 0 : uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY );
1764 :
1765 0 : if ( ! xFltMgr.is() )
1766 0 : return;
1767 :
1768 : try
1769 : {
1770 0 : xFltMgr->appendFilter( rFilterName, rExtension );
1771 :
1772 0 : if ( maSelectFilter.isEmpty() )
1773 0 : maSelectFilter = rFilterName;
1774 : }
1775 0 : catch( const IllegalArgumentException& )
1776 : {
1777 : SAL_WARN( "sfx.dialog", "Could not append Filter" << rFilterName );
1778 0 : }
1779 : }
1780 :
1781 0 : void FileDialogHelper_Impl::addGraphicFilter()
1782 : {
1783 0 : uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY );
1784 :
1785 0 : if ( ! xFltMgr.is() )
1786 0 : return;
1787 :
1788 : // create the list of filters
1789 0 : mpGraphicFilter = new GraphicFilter;
1790 0 : sal_uInt16 i, j, nCount = mpGraphicFilter->GetImportFormatCount();
1791 :
1792 : // compute the extension string for all known import filters
1793 0 : OUString aExtensions;
1794 :
1795 0 : for ( i = 0; i < nCount; i++ )
1796 : {
1797 0 : j = 0;
1798 0 : OUString sWildcard;
1799 : while( true )
1800 : {
1801 0 : sWildcard = mpGraphicFilter->GetImportWildcard( i, j++ );
1802 0 : if ( sWildcard.isEmpty() )
1803 0 : break;
1804 0 : if ( aExtensions.indexOf( sWildcard ) == -1 )
1805 : {
1806 0 : if ( !aExtensions.isEmpty() )
1807 0 : aExtensions += ";";
1808 0 : aExtensions += sWildcard;
1809 : }
1810 : }
1811 0 : }
1812 :
1813 : #if defined(WNT)
1814 : if ( aExtensions.getLength() > 240 )
1815 : aExtensions = FILEDIALOG_FILTER_ALL;
1816 : #endif
1817 0 : bool bIsInOpenMode = isInOpenMode();
1818 :
1819 : try
1820 : {
1821 0 : OUString aAllFilterName = SfxResId( STR_SFX_IMPORT_ALL ).toString();
1822 0 : aAllFilterName = ::sfx2::addExtension( aAllFilterName, aExtensions, bIsInOpenMode, *this );
1823 :
1824 0 : xFltMgr->appendFilter( aAllFilterName, aExtensions );
1825 0 : maSelectFilter = aAllFilterName;
1826 : }
1827 0 : catch( const IllegalArgumentException& )
1828 : {
1829 : SAL_WARN( "sfx.dialog", "Could not append Filter" );
1830 : }
1831 :
1832 : // Now add the filter
1833 0 : for ( i = 0; i < nCount; i++ )
1834 : {
1835 0 : OUString aName = mpGraphicFilter->GetImportFormatName( i );
1836 0 : OUString aExt;
1837 0 : j = 0;
1838 0 : OUString sWildcard;
1839 : while( true )
1840 : {
1841 0 : sWildcard = mpGraphicFilter->GetImportWildcard( i, j++ );
1842 0 : if ( sWildcard.isEmpty() )
1843 0 : break;
1844 0 : if ( aExt.indexOf( sWildcard ) == -1 )
1845 : {
1846 0 : if ( !aExt.isEmpty() )
1847 0 : aExt += ";";
1848 0 : aExt += sWildcard;
1849 : }
1850 : }
1851 0 : aName = ::sfx2::addExtension( aName, aExt, bIsInOpenMode, *this );
1852 : try
1853 : {
1854 0 : xFltMgr->appendFilter( aName, aExt );
1855 : }
1856 0 : catch( const IllegalArgumentException& )
1857 : {
1858 : SAL_WARN( "sfx.dialog", "Could not append Filter" );
1859 : }
1860 0 : }
1861 : }
1862 :
1863 : #define GRF_CONFIG_STR " "
1864 : #define STD_CONFIG_STR "1 "
1865 :
1866 0 : static void SetToken( OUString& rOrigStr, sal_Int32 nToken, sal_Unicode cTok, const OUString& rStr)
1867 : {
1868 0 : const sal_Unicode* pStr = rOrigStr.getStr();
1869 0 : sal_Int32 nLen = rOrigStr.getLength();
1870 0 : sal_Int32 nTok = 0;
1871 0 : sal_Int32 nFirstChar = 0;
1872 0 : sal_Int32 i = nFirstChar;
1873 :
1874 : // Determine token position and length
1875 0 : pStr += i;
1876 0 : while ( i < nLen )
1877 : {
1878 : // Increase token count if match
1879 0 : if ( *pStr == cTok )
1880 : {
1881 0 : ++nTok;
1882 :
1883 0 : if ( nTok == nToken )
1884 0 : nFirstChar = i+1;
1885 : else
1886 : {
1887 0 : if ( nTok > nToken )
1888 0 : break;
1889 : }
1890 : }
1891 :
1892 : ++pStr,
1893 0 : ++i;
1894 : }
1895 :
1896 0 : if ( nTok >= nToken )
1897 0 : rOrigStr = rOrigStr.replaceAt( nFirstChar, i-nFirstChar, rStr );
1898 0 : }
1899 :
1900 :
1901 0 : void FileDialogHelper_Impl::saveConfig()
1902 : {
1903 0 : uno::Reference < XFilePickerControlAccess > xDlg( mxFileDlg, UNO_QUERY );
1904 0 : Any aValue;
1905 :
1906 0 : if ( ! xDlg.is() )
1907 0 : return;
1908 :
1909 0 : if ( mbHasPreview )
1910 : {
1911 0 : SvtViewOptions aDlgOpt( E_DIALOG, IMPGRF_CONFIGNAME );
1912 0 : OUString aUserData(GRF_CONFIG_STR);
1913 :
1914 : try
1915 : {
1916 0 : aValue = xDlg->getValue( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0 );
1917 0 : bool bValue = false;
1918 0 : aValue >>= bValue;
1919 0 : SetToken( aUserData, 1, ' ', OUString::number( (sal_Int32) bValue ) );
1920 :
1921 0 : INetURLObject aObj( getPath() );
1922 :
1923 0 : if ( aObj.GetProtocol() == INetProtocol::File )
1924 0 : SetToken( aUserData, 2, ' ', aObj.GetMainURL( INetURLObject::NO_DECODE ) );
1925 :
1926 0 : OUString aFilter = getFilter();
1927 0 : aFilter = EncodeSpaces_Impl( aFilter );
1928 0 : SetToken( aUserData, 3, ' ', aFilter );
1929 :
1930 0 : aDlgOpt.SetUserItem( USERITEM_NAME, makeAny( aUserData ) );
1931 : }
1932 0 : catch( const IllegalArgumentException& ){}
1933 : }
1934 : else
1935 : {
1936 0 : bool bWriteConfig = false;
1937 0 : SvtViewOptions aDlgOpt( E_DIALOG, IODLG_CONFIGNAME );
1938 0 : OUString aUserData(STD_CONFIG_STR);
1939 :
1940 0 : if ( aDlgOpt.Exists() )
1941 : {
1942 0 : Any aUserItem = aDlgOpt.GetUserItem( USERITEM_NAME );
1943 0 : OUString aTemp;
1944 0 : if ( aUserItem >>= aTemp )
1945 0 : aUserData = aTemp;
1946 : }
1947 :
1948 0 : if ( mbHasAutoExt )
1949 : {
1950 : try
1951 : {
1952 0 : aValue = xDlg->getValue( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, 0 );
1953 0 : bool bAutoExt = true;
1954 0 : aValue >>= bAutoExt;
1955 0 : SetToken( aUserData, 0, ' ', OUString::number( (sal_Int32) bAutoExt ) );
1956 0 : bWriteConfig = true;
1957 : }
1958 0 : catch( const IllegalArgumentException& ){}
1959 : }
1960 :
1961 0 : if ( ! mbIsSaveDlg )
1962 : {
1963 0 : OUString aPath = getPath();
1964 0 : if ( !aPath.isEmpty() &&
1965 0 : utl::LocalFileHelper::IsLocalFile( aPath ) )
1966 : {
1967 0 : SetToken( aUserData, 1, ' ', aPath );
1968 0 : bWriteConfig = true;
1969 0 : }
1970 : }
1971 :
1972 0 : if( mbHasSelectionBox && mbSelectionFltrEnabled )
1973 : {
1974 : try
1975 : {
1976 0 : aValue = xDlg->getValue( ExtendedFilePickerElementIds::CHECKBOX_SELECTION, 0 );
1977 0 : bool bSelection = true;
1978 0 : aValue >>= bSelection;
1979 0 : if ( comphelper::string::getTokenCount(aUserData, ' ') < 3 )
1980 0 : aUserData += " ";
1981 0 : SetToken( aUserData, 2, ' ', OUString::number( (sal_Int32) bSelection ) );
1982 0 : bWriteConfig = true;
1983 : }
1984 0 : catch( const IllegalArgumentException& ){}
1985 : }
1986 :
1987 0 : if ( bWriteConfig )
1988 0 : aDlgOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( aUserData ) ) );
1989 : }
1990 :
1991 0 : SfxApplication *pSfxApp = SfxGetpApp();
1992 0 : pSfxApp->SetLastDir_Impl( getPath() );
1993 : }
1994 :
1995 : namespace
1996 : {
1997 0 : static OUString getInitPath( const OUString& _rFallback, const sal_Int32 _nFallbackToken )
1998 : {
1999 0 : SfxApplication *pSfxApp = SfxGetpApp();
2000 0 : OUString sPath = pSfxApp->GetLastDir_Impl();
2001 :
2002 0 : if ( sPath.isEmpty() )
2003 0 : sPath = _rFallback.getToken( _nFallbackToken, ' ' );
2004 :
2005 : // check if the path points to a valid (accessible) directory
2006 0 : bool bValid = false;
2007 0 : if ( !sPath.isEmpty() )
2008 : {
2009 0 : OUString sPathCheck( sPath );
2010 0 : if ( sPathCheck[ sPathCheck.getLength() - 1 ] != '/' )
2011 0 : sPathCheck += "/";
2012 0 : sPathCheck += ".";
2013 : try
2014 : {
2015 0 : ::ucbhelper::Content aContent( sPathCheck, uno::Reference< ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
2016 0 : bValid = aContent.isFolder();
2017 : }
2018 0 : catch( const Exception& ) {}
2019 : }
2020 :
2021 0 : if ( !bValid )
2022 0 : sPath.clear();
2023 :
2024 0 : return sPath;
2025 : }
2026 : }
2027 :
2028 0 : void FileDialogHelper_Impl::loadConfig()
2029 : {
2030 0 : uno::Reference < XFilePickerControlAccess > xDlg( mxFileDlg, UNO_QUERY );
2031 0 : Any aValue;
2032 :
2033 0 : if ( ! xDlg.is() )
2034 0 : return;
2035 :
2036 0 : if ( mbHasPreview )
2037 : {
2038 0 : SvtViewOptions aViewOpt( E_DIALOG, IMPGRF_CONFIGNAME );
2039 0 : OUString aUserData;
2040 :
2041 0 : if ( aViewOpt.Exists() )
2042 : {
2043 0 : Any aUserItem = aViewOpt.GetUserItem( USERITEM_NAME );
2044 0 : OUString aTemp;
2045 0 : if ( aUserItem >>= aTemp )
2046 0 : aUserData = aTemp;
2047 : }
2048 :
2049 0 : if ( !aUserData.isEmpty() )
2050 : {
2051 : try
2052 : {
2053 : // respect the last "insert as link" state
2054 0 : bool bLink = aUserData.getToken( 0, ' ' ).toInt32();
2055 0 : aValue <<= bLink;
2056 0 : xDlg->setValue( ExtendedFilePickerElementIds::CHECKBOX_LINK, 0, aValue );
2057 :
2058 : // respect the last "show preview" state
2059 0 : bool bShowPreview = aUserData.getToken( 1, ' ' ).toInt32();
2060 0 : aValue <<= bShowPreview;
2061 0 : xDlg->setValue( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0, aValue );
2062 :
2063 0 : if ( maPath.isEmpty() )
2064 0 : displayFolder( getInitPath( aUserData, 2 ) );
2065 :
2066 0 : if ( maCurFilter.isEmpty() )
2067 : {
2068 0 : OUString aFilter = aUserData.getToken( 3, ' ' );
2069 0 : aFilter = DecodeSpaces_Impl( aFilter );
2070 0 : setFilter( aFilter );
2071 : }
2072 :
2073 : // set the member so we know that we have to show the preview
2074 0 : mbShowPreview = bShowPreview;
2075 : }
2076 0 : catch( const IllegalArgumentException& ){}
2077 : }
2078 :
2079 0 : if ( maPath.isEmpty() )
2080 0 : displayFolder( SvtPathOptions().GetGraphicPath() );
2081 : }
2082 : else
2083 : {
2084 0 : SvtViewOptions aViewOpt( E_DIALOG, IODLG_CONFIGNAME );
2085 0 : OUString aUserData;
2086 :
2087 0 : if ( aViewOpt.Exists() )
2088 : {
2089 0 : Any aUserItem = aViewOpt.GetUserItem( USERITEM_NAME );
2090 0 : OUString aTemp;
2091 0 : if ( aUserItem >>= aTemp )
2092 0 : aUserData = aTemp;
2093 : }
2094 :
2095 0 : if ( aUserData.isEmpty() )
2096 0 : aUserData = STD_CONFIG_STR;
2097 :
2098 0 : if ( maPath.isEmpty() )
2099 0 : displayFolder( getInitPath( aUserData, 1 ) );
2100 :
2101 0 : if ( mbHasAutoExt )
2102 : {
2103 0 : sal_Int32 nFlag = aUserData.getToken( 0, ' ' ).toInt32();
2104 0 : aValue <<= (bool) nFlag;
2105 : try
2106 : {
2107 0 : xDlg->setValue( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, 0, aValue );
2108 : }
2109 0 : catch( const IllegalArgumentException& ){}
2110 : }
2111 :
2112 0 : if( mbHasSelectionBox )
2113 : {
2114 0 : sal_Int32 nFlag = aUserData.getToken( 2, ' ' ).toInt32();
2115 0 : aValue <<= (bool) nFlag;
2116 : try
2117 : {
2118 0 : xDlg->setValue( ExtendedFilePickerElementIds::CHECKBOX_SELECTION, 0, aValue );
2119 : }
2120 0 : catch( const IllegalArgumentException& ){}
2121 : }
2122 :
2123 0 : if ( maPath.isEmpty() )
2124 0 : displayFolder( SvtPathOptions().GetWorkPath() );
2125 0 : }
2126 : }
2127 :
2128 0 : void FileDialogHelper_Impl::setDefaultValues()
2129 : {
2130 : // when no filter is set, we set the curentFilter to <all>
2131 0 : if ( maCurFilter.isEmpty() && !maSelectFilter.isEmpty() )
2132 : {
2133 0 : uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY );
2134 : try
2135 : {
2136 0 : xFltMgr->setCurrentFilter( maSelectFilter );
2137 : }
2138 0 : catch( const IllegalArgumentException& )
2139 0 : {}
2140 : }
2141 :
2142 : // when no path is set, we use the standard 'work' folder
2143 0 : if ( maPath.isEmpty() )
2144 : {
2145 0 : OUString aWorkFolder = SvtPathOptions().GetWorkPath();
2146 : try
2147 : {
2148 0 : mxFileDlg->setDisplayDirectory( aWorkFolder );
2149 : }
2150 0 : catch( const Exception& )
2151 : {
2152 : OSL_FAIL( "FileDialogHelper_Impl::setDefaultValues: caught an exception while setting the display directory!" );
2153 0 : }
2154 : }
2155 0 : }
2156 :
2157 0 : bool FileDialogHelper_Impl::isShowFilterExtensionEnabled() const
2158 : {
2159 0 : return !maFilters.empty();
2160 : }
2161 :
2162 0 : void FileDialogHelper_Impl::addFilterPair( const OUString& rFilter,
2163 : const OUString& rFilterWithExtension )
2164 : {
2165 0 : maFilters.push_back( FilterPair( rFilter, rFilterWithExtension ) );
2166 :
2167 0 : }
2168 :
2169 0 : OUString FileDialogHelper_Impl::getFilterName( const OUString& rFilterWithExtension ) const
2170 : {
2171 0 : OUString sRet;
2172 0 : for( ::std::vector< FilterPair >::const_iterator pIter = maFilters.begin(); pIter != maFilters.end(); ++pIter )
2173 : {
2174 0 : if ( (*pIter).Second == rFilterWithExtension )
2175 : {
2176 0 : sRet = (*pIter).First;
2177 0 : break;
2178 : }
2179 : }
2180 0 : return sRet;
2181 : }
2182 :
2183 0 : OUString FileDialogHelper_Impl::getFilterWithExtension( const OUString& rFilter ) const
2184 : {
2185 0 : OUString sRet;
2186 0 : for( ::std::vector< FilterPair >::const_iterator pIter = maFilters.begin(); pIter != maFilters.end(); ++pIter )
2187 : {
2188 0 : if ( (*pIter).First == rFilter )
2189 : {
2190 0 : sRet = (*pIter).Second;
2191 0 : break;
2192 : }
2193 : }
2194 0 : return sRet;
2195 : }
2196 :
2197 0 : void FileDialogHelper_Impl::SetContext( FileDialogHelper::Context _eNewContext )
2198 : {
2199 0 : meContext = _eNewContext;
2200 :
2201 0 : const OUString* pConfigId = GetLastFilterConfigId( _eNewContext );
2202 0 : if( pConfigId )
2203 0 : LoadLastUsedFilter( *pConfigId );
2204 0 : }
2205 :
2206 : // FileDialogHelper
2207 :
2208 0 : FileDialogHelper::FileDialogHelper(
2209 : sal_Int16 nDialogType,
2210 : sal_Int64 nFlags,
2211 : const OUString& rFact,
2212 : SfxFilterFlags nMust,
2213 : SfxFilterFlags nDont )
2214 0 : : m_nError(0)
2215 : {
2216 0 : mpImp = new FileDialogHelper_Impl( this, nDialogType, nFlags );
2217 0 : mxImp = mpImp;
2218 :
2219 : // create the list of filters
2220 : mpImp->addFilters(
2221 0 : SfxObjectShell::GetServiceNameFromFactory(rFact), nMust, nDont );
2222 0 : }
2223 :
2224 0 : FileDialogHelper::FileDialogHelper(
2225 : sal_Int16 nDialogType,
2226 : sal_Int64 nFlags,
2227 : const OUString& rFact,
2228 : sal_Int16 nDialog,
2229 : SfxFilterFlags nMust,
2230 : SfxFilterFlags nDont,
2231 : const OUString& rStandardDir,
2232 : const ::com::sun::star::uno::Sequence< OUString >& rBlackList)
2233 0 : : m_nError(0)
2234 : {
2235 0 : mpImp = new FileDialogHelper_Impl( this, nDialogType, nFlags, nDialog, NULL, rStandardDir, rBlackList );
2236 0 : mxImp = mpImp;
2237 :
2238 : // create the list of filters
2239 : mpImp->addFilters(
2240 0 : SfxObjectShell::GetServiceNameFromFactory(rFact), nMust, nDont );
2241 0 : }
2242 :
2243 0 : FileDialogHelper::FileDialogHelper(
2244 : sal_Int16 nDialogType,
2245 : sal_Int64 nFlags,
2246 : vcl::Window* _pPreferredParent )
2247 0 : : m_nError(0)
2248 : {
2249 0 : mpImp = new FileDialogHelper_Impl( this, nDialogType, nFlags, SFX2_IMPL_DIALOG_CONFIG, _pPreferredParent );
2250 0 : mxImp = mpImp;
2251 0 : }
2252 :
2253 0 : FileDialogHelper::FileDialogHelper(
2254 : sal_Int16 nDialogType,
2255 : sal_Int64 nFlags,
2256 : const OUString& aFilterUIName,
2257 : const OUString& aExtName,
2258 : const OUString& rStandardDir,
2259 : const ::com::sun::star::uno::Sequence< OUString >& rBlackList,
2260 : vcl::Window* _pPreferredParent )
2261 0 : : m_nError(0)
2262 : {
2263 0 : mpImp = new FileDialogHelper_Impl( this, nDialogType, nFlags, SFX2_IMPL_DIALOG_CONFIG, _pPreferredParent,rStandardDir, rBlackList );
2264 0 : mxImp = mpImp;
2265 :
2266 : // the wildcard here is expected in form "*.extension"
2267 0 : OUString aWildcard;
2268 0 : if ( aExtName.indexOf( (sal_Unicode)'*' ) != 0 )
2269 : {
2270 0 : if ( !aExtName.isEmpty() && aExtName.indexOf( (sal_Unicode)'.' ) != 0 )
2271 0 : aWildcard = "*.";
2272 : else
2273 0 : aWildcard = "*";
2274 : }
2275 :
2276 0 : aWildcard += aExtName;
2277 :
2278 : OUString const aUIString = ::sfx2::addExtension( aFilterUIName,
2279 0 : aWildcard, (OPEN == lcl_OpenOrSave(mpImp->m_nDialogType)), *mpImp);
2280 0 : AddFilter( aUIString, aWildcard );
2281 0 : }
2282 :
2283 0 : FileDialogHelper::~FileDialogHelper()
2284 : {
2285 0 : mpImp->dispose();
2286 0 : mxImp.clear();
2287 0 : }
2288 :
2289 0 : void FileDialogHelper::CreateMatcher( const OUString& rFactory )
2290 : {
2291 0 : mpImp->createMatcher( SfxObjectShell::GetServiceNameFromFactory(rFactory) );
2292 0 : }
2293 :
2294 0 : void FileDialogHelper::SetControlHelpIds( const sal_Int16* _pControlId, const char** _pHelpId )
2295 : {
2296 0 : mpImp->setControlHelpIds( _pControlId, _pHelpId );
2297 0 : }
2298 :
2299 0 : void FileDialogHelper::SetContext( Context _eNewContext )
2300 : {
2301 0 : mpImp->SetContext( _eNewContext );
2302 0 : }
2303 :
2304 0 : IMPL_LINK_NOARG(FileDialogHelper, ExecuteSystemFilePicker)
2305 : {
2306 0 : m_nError = mpImp->execute();
2307 0 : if ( m_aDialogClosedLink.IsSet() )
2308 0 : m_aDialogClosedLink.Call( this );
2309 :
2310 0 : return 0L;
2311 : }
2312 :
2313 : // rDirPath has to be a directory
2314 0 : ErrCode FileDialogHelper::Execute( std::vector<OUString>& rpURLList,
2315 : SfxItemSet *& rpSet,
2316 : OUString& rFilter,
2317 : const OUString& rDirPath )
2318 : {
2319 0 : SetDisplayFolder( rDirPath );
2320 0 : return mpImp->execute( rpURLList, rpSet, rFilter );
2321 : }
2322 :
2323 :
2324 0 : ErrCode FileDialogHelper::Execute()
2325 : {
2326 0 : return mpImp->execute();
2327 : }
2328 :
2329 0 : ErrCode FileDialogHelper::Execute( SfxItemSet *& rpSet,
2330 : OUString& rFilter )
2331 : {
2332 : ErrCode nRet;
2333 0 : std::vector<OUString> rURLList;
2334 0 : nRet = mpImp->execute(rURLList, rpSet, rFilter);
2335 0 : return nRet;
2336 : }
2337 :
2338 0 : void FileDialogHelper::StartExecuteModal( const Link<>& rEndDialogHdl )
2339 : {
2340 0 : m_aDialogClosedLink = rEndDialogHdl;
2341 0 : m_nError = ERRCODE_NONE;
2342 0 : if ( mpImp->isSystemFilePicker() )
2343 0 : Application::PostUserEvent( LINK( this, FileDialogHelper, ExecuteSystemFilePicker ) );
2344 : else
2345 0 : mpImp->implStartExecute();
2346 0 : }
2347 :
2348 :
2349 0 : short FileDialogHelper::GetDialogType() const
2350 : {
2351 0 : return mpImp ? mpImp->m_nDialogType : 0;
2352 : }
2353 :
2354 0 : bool FileDialogHelper::IsPasswordEnabled() const
2355 : {
2356 0 : return mpImp && mpImp->isPasswordEnabled();
2357 : }
2358 :
2359 0 : OUString FileDialogHelper::GetRealFilter() const
2360 : {
2361 0 : OUString sFilter;
2362 0 : if ( mpImp )
2363 0 : mpImp->getRealFilter( sFilter );
2364 0 : return sFilter;
2365 : }
2366 :
2367 0 : void FileDialogHelper::SetTitle( const OUString& rNewTitle )
2368 : {
2369 0 : if ( mpImp->mxFileDlg.is() )
2370 0 : mpImp->mxFileDlg->setTitle( rNewTitle );
2371 0 : }
2372 :
2373 0 : OUString FileDialogHelper::GetPath() const
2374 : {
2375 0 : OUString aPath;
2376 :
2377 0 : if ( mpImp->mlLastURLs.size() > 0)
2378 0 : return mpImp->mlLastURLs[0];
2379 :
2380 0 : if ( mpImp->mxFileDlg.is() )
2381 : {
2382 0 : Sequence < OUString > aPathSeq = mpImp->mxFileDlg->getFiles();
2383 :
2384 0 : if ( aPathSeq.getLength() == 1 )
2385 : {
2386 0 : aPath = aPathSeq[0];
2387 0 : }
2388 : }
2389 :
2390 0 : return aPath;
2391 : }
2392 :
2393 0 : Sequence < OUString > FileDialogHelper::GetMPath() const
2394 : {
2395 0 : if ( mpImp->mlLastURLs.size() > 0)
2396 0 : return comphelper::containerToSequence(mpImp->mlLastURLs);
2397 :
2398 0 : if ( mpImp->mxFileDlg.is() )
2399 0 : return mpImp->mxFileDlg->getFiles();
2400 : else
2401 : {
2402 0 : Sequence < OUString > aEmpty;
2403 0 : return aEmpty;
2404 : }
2405 : }
2406 :
2407 0 : Sequence< OUString > FileDialogHelper::GetSelectedFiles() const
2408 : {
2409 : // a) the new way (optional!)
2410 0 : uno::Sequence< OUString > aResultSeq;
2411 0 : uno::Reference< XFilePicker2 > xPickNew(mpImp->mxFileDlg, UNO_QUERY);
2412 0 : if (xPickNew.is())
2413 : {
2414 0 : aResultSeq = xPickNew->getSelectedFiles();
2415 : }
2416 : // b) the olde way ... non optional.
2417 : else
2418 : {
2419 0 : uno::Reference< XFilePicker > xPickOld(mpImp->mxFileDlg, UNO_QUERY_THROW);
2420 0 : Sequence< OUString > lFiles = xPickOld->getFiles();
2421 0 : ::sal_Int32 nFiles = lFiles.getLength();
2422 0 : if ( nFiles > 1 )
2423 : {
2424 0 : aResultSeq = Sequence< OUString >( nFiles-1 );
2425 :
2426 0 : INetURLObject aPath( lFiles[0] );
2427 0 : aPath.setFinalSlash();
2428 :
2429 0 : for (::sal_Int32 i = 1; i < nFiles; i++)
2430 : {
2431 0 : if (i == 1)
2432 0 : aPath.Append( lFiles[i] );
2433 : else
2434 0 : aPath.setName( lFiles[i] );
2435 :
2436 0 : aResultSeq[i-1] = aPath.GetMainURL( INetURLObject::NO_DECODE );
2437 0 : }
2438 : }
2439 : else
2440 0 : aResultSeq = lFiles;
2441 : }
2442 :
2443 0 : return aResultSeq;
2444 : }
2445 :
2446 0 : OUString FileDialogHelper::GetDisplayDirectory() const
2447 : {
2448 0 : return mpImp->getPath();
2449 : }
2450 :
2451 0 : OUString FileDialogHelper::GetCurrentFilter() const
2452 : {
2453 0 : return mpImp->getFilter();
2454 : }
2455 :
2456 0 : ErrCode FileDialogHelper::GetGraphic( Graphic& rGraphic ) const
2457 : {
2458 0 : return mpImp->getGraphic( rGraphic );
2459 : }
2460 :
2461 0 : static int impl_isFolder( const OUString& rPath )
2462 : {
2463 : try
2464 : {
2465 : ::ucbhelper::Content aContent(
2466 : rPath, uno::Reference< ucb::XCommandEnvironment > (),
2467 0 : comphelper::getProcessComponentContext() );
2468 0 : if ( aContent.isFolder() )
2469 0 : return 1;
2470 :
2471 0 : return 0;
2472 : }
2473 0 : catch ( const Exception & )
2474 : {
2475 : }
2476 :
2477 0 : return -1;
2478 : }
2479 :
2480 0 : void FileDialogHelper::SetDisplayDirectory( const OUString& _rPath )
2481 : {
2482 0 : if ( _rPath.isEmpty() )
2483 0 : return;
2484 :
2485 : // if the given path isn't a folder, we cut off the last part
2486 : // and take it as filename and the rest of the path should be
2487 : // the folder
2488 :
2489 0 : INetURLObject aObj( _rPath );
2490 :
2491 0 : OUString sFileName = aObj.GetName( INetURLObject::DECODE_WITH_CHARSET );
2492 0 : aObj.removeSegment();
2493 0 : OUString sPath = aObj.GetMainURL( INetURLObject::NO_DECODE );
2494 :
2495 0 : int nIsFolder = impl_isFolder( _rPath );
2496 0 : if ( nIsFolder == 0 ||
2497 0 : ( nIsFolder == -1 && impl_isFolder( sPath ) == 1 ) )
2498 : {
2499 0 : mpImp->setFileName( sFileName );
2500 0 : mpImp->displayFolder( sPath );
2501 : }
2502 : else
2503 : {
2504 0 : INetURLObject aObjPathName( _rPath );
2505 0 : OUString sFolder( aObjPathName.GetMainURL( INetURLObject::NO_DECODE ) );
2506 0 : if ( sFolder.isEmpty() )
2507 : {
2508 : // _rPath is not a valid path -> fallback to home directory
2509 0 : osl::Security aSecurity;
2510 0 : aSecurity.getHomeDir( sFolder );
2511 : }
2512 0 : mpImp->displayFolder( sFolder );
2513 0 : }
2514 : }
2515 :
2516 0 : void FileDialogHelper::SetDisplayFolder( const OUString& _rURL )
2517 : {
2518 0 : mpImp->displayFolder( _rURL );
2519 0 : }
2520 :
2521 0 : void FileDialogHelper::SetFileName( const OUString& _rFileName )
2522 : {
2523 0 : mpImp->setFileName( _rFileName );
2524 0 : }
2525 :
2526 0 : void FileDialogHelper::AddFilter( const OUString& rFilterName,
2527 : const OUString& rExtension )
2528 : {
2529 0 : mpImp->addFilter( rFilterName, rExtension );
2530 0 : }
2531 :
2532 0 : void FileDialogHelper::SetCurrentFilter( const OUString& rFilter )
2533 : {
2534 0 : OUString sFilter( rFilter );
2535 0 : if ( mpImp->isShowFilterExtensionEnabled() )
2536 0 : sFilter = mpImp->getFilterWithExtension( rFilter );
2537 0 : mpImp->setFilter( sFilter );
2538 0 : }
2539 :
2540 0 : uno::Reference < XFilePicker > FileDialogHelper::GetFilePicker() const
2541 : {
2542 0 : return mpImp->mxFileDlg;
2543 : }
2544 :
2545 : // XFilePickerListener Methods
2546 0 : void SAL_CALL FileDialogHelper::FileSelectionChanged( const FilePickerEvent& aEvent )
2547 : {
2548 0 : mpImp->handleFileSelectionChanged( aEvent );
2549 0 : }
2550 :
2551 0 : void SAL_CALL FileDialogHelper::DirectoryChanged( const FilePickerEvent& aEvent )
2552 : {
2553 0 : mpImp->handleDirectoryChanged( aEvent );
2554 0 : }
2555 :
2556 0 : OUString SAL_CALL FileDialogHelper::HelpRequested( const FilePickerEvent& aEvent )
2557 : {
2558 0 : return sfx2::FileDialogHelper_Impl::handleHelpRequested( aEvent );
2559 : }
2560 :
2561 0 : void SAL_CALL FileDialogHelper::ControlStateChanged( const FilePickerEvent& aEvent )
2562 : {
2563 0 : mpImp->handleControlStateChanged( aEvent );
2564 0 : }
2565 :
2566 0 : void SAL_CALL FileDialogHelper::DialogSizeChanged()
2567 : {
2568 0 : mpImp->handleDialogSizeChanged();
2569 0 : }
2570 :
2571 0 : void SAL_CALL FileDialogHelper::DialogClosed( const DialogClosedEvent& _rEvent )
2572 : {
2573 0 : m_nError = ( RET_OK == _rEvent.DialogResult ) ? ERRCODE_NONE : ERRCODE_ABORT;
2574 0 : if ( m_aDialogClosedLink.IsSet() )
2575 0 : m_aDialogClosedLink.Call( this );
2576 0 : }
2577 :
2578 0 : ErrCode FileOpenDialog_Impl( sal_Int16 nDialogType,
2579 : sal_Int64 nFlags,
2580 : const OUString& rFact,
2581 : std::vector<OUString>& rpURLList,
2582 : OUString& rFilter,
2583 : SfxItemSet *& rpSet,
2584 : const OUString* pPath,
2585 : sal_Int16 nDialog,
2586 : const OUString& rStandardDir,
2587 : const ::com::sun::star::uno::Sequence< OUString >& rBlackList )
2588 : {
2589 : ErrCode nRet;
2590 : FileDialogHelper aDialog( nDialogType, nFlags,
2591 0 : rFact, nDialog, SfxFilterFlags::NONE, SfxFilterFlags::NONE, rStandardDir, rBlackList );
2592 :
2593 0 : OUString aPath;
2594 0 : if ( pPath )
2595 0 : aPath = *pPath;
2596 :
2597 0 : nRet = aDialog.Execute( rpURLList, rpSet, rFilter, aPath );
2598 : DBG_ASSERT( rFilter.indexOf(": ") == -1, "Old filter name used!");
2599 :
2600 0 : return nRet;
2601 : }
2602 :
2603 0 : ErrCode RequestPassword(const SfxFilter* pCurrentFilter, OUString& aURL, SfxItemSet* pSet)
2604 : {
2605 0 : uno::Reference < task::XInteractionHandler2 > xInteractionHandler = task::InteractionHandler::createWithParent( ::comphelper::getProcessComponentContext(), 0 );
2606 : // TODO: need a save way to distinguish MS filters from other filters
2607 : // for now MS-filters are the only alien filters that support encryption
2608 0 : bool bMSType = !pCurrentFilter->IsOwnFormat();
2609 : ::comphelper::DocPasswordRequestType eType = bMSType ?
2610 : ::comphelper::DocPasswordRequestType_MS :
2611 0 : ::comphelper::DocPasswordRequestType_STANDARD;
2612 :
2613 0 : ::rtl::Reference< ::comphelper::DocPasswordRequest > pPasswordRequest( new ::comphelper::DocPasswordRequest( eType, ::com::sun::star::task::PasswordRequestMode_PASSWORD_CREATE, aURL, bool( pCurrentFilter->GetFilterFlags() & SfxFilterFlags::PASSWORDTOMODIFY ) ) );
2614 :
2615 0 : uno::Reference< com::sun::star::task::XInteractionRequest > rRequest( pPasswordRequest.get() );
2616 0 : xInteractionHandler->handle( rRequest );
2617 0 : if ( pPasswordRequest->isPassword() )
2618 : {
2619 0 : if ( pPasswordRequest->getPassword().getLength() )
2620 : {
2621 : // TODO/LATER: The filters should show the password dialog themself in future
2622 0 : if ( bMSType )
2623 : {
2624 : // Check if filter supports OOXML encryption
2625 0 : if ( lclSupportsOOXMLEncryption( pCurrentFilter->GetFilterName() ) )
2626 : {
2627 0 : ::comphelper::SequenceAsHashMap aHashData;
2628 0 : aHashData[ OUString( "OOXPassword" ) ] <<= pPasswordRequest->getPassword();
2629 0 : pSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aHashData.getAsConstNamedValueList() ) ) );
2630 : }
2631 : else
2632 : {
2633 0 : uno::Sequence< sal_Int8 > aUniqueID = ::comphelper::DocPasswordHelper::GenerateRandomByteSequence( 16 );
2634 0 : uno::Sequence< sal_Int8 > aEncryptionKey = ::comphelper::DocPasswordHelper::GenerateStd97Key( pPasswordRequest->getPassword(), aUniqueID );
2635 :
2636 0 : if ( aEncryptionKey.getLength() )
2637 : {
2638 0 : ::comphelper::SequenceAsHashMap aHashData;
2639 0 : aHashData[ OUString( "STD97EncryptionKey" ) ] <<= aEncryptionKey;
2640 0 : aHashData[ OUString( "STD97UniqueID" ) ] <<= aUniqueID;
2641 :
2642 0 : pSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aHashData.getAsConstNamedValueList() ) ) );
2643 : }
2644 : else
2645 : {
2646 0 : return ERRCODE_IO_NOTSUPPORTED;
2647 0 : }
2648 : }
2649 : }
2650 : else
2651 : {
2652 0 : pSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( ::comphelper::OStorageHelper::CreatePackageEncryptionData( pPasswordRequest->getPassword() ) ) ) );
2653 : }
2654 : }
2655 :
2656 0 : if ( pPasswordRequest->getRecommendReadOnly() )
2657 0 : pSet->Put( SfxBoolItem( SID_RECOMMENDREADONLY, true ) );
2658 :
2659 0 : if ( bMSType )
2660 : {
2661 : // the empty password has 0 as Hash
2662 0 : sal_Int32 nHash = SfxMedium::CreatePasswordToModifyHash( pPasswordRequest->getPasswordToModify(), OUString( "com.sun.star.text.TextDocument" ).equals( pCurrentFilter->GetServiceName() ) );
2663 0 : if ( nHash )
2664 0 : pSet->Put( SfxUnoAnyItem( SID_MODIFYPASSWORDINFO, uno::makeAny( nHash ) ) );
2665 : }
2666 : else
2667 : {
2668 0 : uno::Sequence< beans::PropertyValue > aModifyPasswordInfo = ::comphelper::DocPasswordHelper::GenerateNewModifyPasswordInfo( pPasswordRequest->getPasswordToModify() );
2669 0 : if ( aModifyPasswordInfo.getLength() )
2670 0 : pSet->Put( SfxUnoAnyItem( SID_MODIFYPASSWORDINFO, uno::makeAny( aModifyPasswordInfo ) ) );
2671 : }
2672 : }
2673 : else
2674 0 : return ERRCODE_ABORT;
2675 0 : return ERRCODE_NONE;
2676 : }
2677 :
2678 0 : OUString EncodeSpaces_Impl( const OUString& rSource )
2679 : {
2680 0 : OUString sRet( rSource );
2681 0 : sRet = sRet.replaceAll( " ", "%20" );
2682 0 : return sRet;
2683 : }
2684 :
2685 0 : OUString DecodeSpaces_Impl( const OUString& rSource )
2686 : {
2687 0 : OUString sRet( rSource );
2688 0 : sRet = sRet.replaceAll( "%20", " " );
2689 0 : return sRet;
2690 : }
2691 :
2692 648 : } // end of namespace sfx2
2693 :
2694 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|