LibreOffice Module sfx2 (master) 1
filedlghelper.cxx
Go to the documentation of this file.
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 <memory>
21#include <optional>
22#include <string_view>
23
25#include <sal/types.h>
26#include <com/sun/star/lang/XInitialization.hpp>
27#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
28#include <com/sun/star/ui/dialogs/ControlActions.hpp>
29#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
30#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
31#include <com/sun/star/ui/dialogs/FilePreviewImageFormats.hpp>
32#include <com/sun/star/ui/dialogs/FolderPicker.hpp>
33#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
34#include <com/sun/star/ui/dialogs/XControlInformation.hpp>
35#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
36#include <com/sun/star/ui/dialogs/XFilePreview.hpp>
37#include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
38#include <com/sun/star/ui/dialogs/XAsynchronousExecutableDialog.hpp>
39#include <com/sun/star/lang/XServiceInfo.hpp>
40#include <com/sun/star/lang/XSingleServiceFactory.hpp>
41#include <com/sun/star/lang/XMultiServiceFactory.hpp>
42#include <com/sun/star/beans/PropertyValue.hpp>
43#include <com/sun/star/beans/NamedValue.hpp>
44#include <com/sun/star/beans/XPropertySet.hpp>
45#include <com/sun/star/embed/ElementModes.hpp>
46#include <com/sun/star/container/XEnumeration.hpp>
47#include <com/sun/star/container/XContainerQuery.hpp>
48#include <com/sun/star/container/XNameAccess.hpp>
49#include <com/sun/star/container/XNameContainer.hpp>
50#include <com/sun/star/task/InteractionHandler.hpp>
51#include <com/sun/star/task/XInteractionRequest.hpp>
52#include <com/sun/star/util/RevisionTag.hpp>
56#include <comphelper/string.hxx>
57#include <comphelper/types.hxx>
58#include <tools/urlobj.hxx>
59#include <vcl/help.hxx>
60#include <vcl/weld.hxx>
63#include <osl/file.hxx>
64#include <osl/security.hxx>
65#include <vcl/mnemonic.hxx>
66#include <vcl/svapp.hxx>
68#include <unotools/saveopt.hxx>
70#include <svl/itemset.hxx>
71#include <svl/eitem.hxx>
72#include <svl/intitem.hxx>
73#include <vcl/dibtools.hxx>
74#include <vcl/graphicfilter.hxx>
76#include <svtools/helpids.h>
79#include <ucbhelper/content.hxx>
81#include <sfx2/app.hxx>
82#include <sfx2/frame.hxx>
83#include <sfx2/docfile.hxx>
84#include <sfx2/docfilt.hxx>
85#include <sfx2/objsh.hxx>
86#include <sfx2/sfxresid.hxx>
87#include <sfx2/sfxsids.hrc>
88#include "filtergrouping.hxx"
89#include "filedlgimpl.hxx"
90#include <sfx2/strings.hrc>
91#include <sal/log.hxx>
94#include <o3tl/string_view.hxx>
95#include <officecfg/Office/Common.hxx>
96
97#ifdef UNX
98#include <errno.h>
99#include <sys/stat.h>
100#endif
101
102using namespace ::com::sun::star;
103using namespace ::com::sun::star::container;
104using namespace ::com::sun::star::lang;
105using namespace ::com::sun::star::ui::dialogs;
106using namespace ::com::sun::star::ui::dialogs::TemplateDescription;
107using namespace ::com::sun::star::uno;
108using namespace ::com::sun::star::beans;
109using namespace ::cppu;
110
111constexpr OUStringLiteral IODLG_CONFIGNAME = u"FilePicker_Save";
112constexpr OUStringLiteral IMPGRF_CONFIGNAME = u"FilePicker_Graph";
113constexpr OUStringLiteral USERITEM_NAME = u"UserItem";
114
115namespace sfx2
116{
117
118namespace
119{
120 bool lclSupportsOOXMLEncryption(std::u16string_view aFilterName)
121 {
122 return aFilterName == u"Calc MS Excel 2007 XML"
123 || aFilterName == u"MS Word 2007 XML"
124 || aFilterName == u"Impress MS PowerPoint 2007 XML"
125 || aFilterName == u"Impress MS PowerPoint 2007 XML AutoPlay"
126 || aFilterName == u"Calc Office Open XML"
127 || aFilterName == u"Impress Office Open XML"
128 || aFilterName == u"Impress Office Open XML AutoPlay"
129 || aFilterName == u"Office Open XML Text";
130 }
131}
132
133static std::optional<OUString> GetLastFilterConfigId( FileDialogHelper::Context _eContext )
134{
135 static constexpr OUStringLiteral aSD_EXPORT_IDENTIFIER(u"SdExportLastFilter");
136 static constexpr OUStringLiteral aSI_EXPORT_IDENTIFIER(u"SiExportLastFilter");
137 static constexpr OUStringLiteral aSW_EXPORT_IDENTIFIER(u"SwExportLastFilter");
138
139 switch( _eContext )
140 {
141 case FileDialogHelper::DrawExport: return aSD_EXPORT_IDENTIFIER;
142 case FileDialogHelper::ImpressExport: return aSI_EXPORT_IDENTIFIER;
143 case FileDialogHelper::WriterExport: return aSW_EXPORT_IDENTIFIER;
144 default: break;
145 }
146
147 return {};
148}
149
150static OUString EncodeSpaces_Impl( const OUString& rSource );
151static OUString DecodeSpaces_Impl( const OUString& rSource );
152
153// FileDialogHelper_Impl
154
155// XFilePickerListener Methods
156void SAL_CALL FileDialogHelper_Impl::fileSelectionChanged( const FilePickerEvent& )
157{
158 SolarMutexGuard aGuard;
160}
161
162void SAL_CALL FileDialogHelper_Impl::directoryChanged( const FilePickerEvent& )
163{
164 SolarMutexGuard aGuard;
166}
167
168OUString SAL_CALL FileDialogHelper_Impl::helpRequested( const FilePickerEvent& aEvent )
169{
170 SolarMutexGuard aGuard;
172}
173
174void SAL_CALL FileDialogHelper_Impl::controlStateChanged( const FilePickerEvent& aEvent )
175{
176 SolarMutexGuard aGuard;
178}
179
181{
182 SolarMutexGuard aGuard;
184}
185
186// XDialogClosedListener Methods
187void SAL_CALL FileDialogHelper_Impl::dialogClosed( const DialogClosedEvent& _rEvent )
188{
189 SolarMutexGuard aGuard;
190 mpAntiImpl->DialogClosed( _rEvent );
191 postExecute( _rEvent.DialogResult );
192}
193
194// handle XFilePickerListener events
196{
197 if ( mbHasVersions )
199
200 if ( mbShowPreview )
202}
203
205{
206 if ( mbShowPreview )
207 TimeOutHdl_Impl( nullptr );
208}
209
210OUString FileDialogHelper_Impl::handleHelpRequested( const FilePickerEvent& aEvent )
211{
213
214 OUString sHelpId;
215 // mapping from element id -> help id
216 switch ( aEvent.ElementId )
217 {
218 case ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION :
220 break;
221
222 case ExtendedFilePickerElementIds::CHECKBOX_PASSWORD :
224 break;
225
226 case ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS :
228 break;
229
230 case ExtendedFilePickerElementIds::CHECKBOX_READONLY :
231 sHelpId = HID_FILEOPEN_READONLY;
232 break;
233
234 case ExtendedFilePickerElementIds::CHECKBOX_LINK :
235 sHelpId = HID_FILEDLG_LINK_CB;
236 break;
237
238 case ExtendedFilePickerElementIds::CHECKBOX_PREVIEW :
239 sHelpId = HID_FILEDLG_PREVIEW_CB;
240 break;
241
242 case ExtendedFilePickerElementIds::PUSHBUTTON_PLAY :
243 sHelpId = HID_FILESAVE_DOPLAY;
244 break;
245
246 case ExtendedFilePickerElementIds::LISTBOX_VERSION_LABEL :
247 case ExtendedFilePickerElementIds::LISTBOX_VERSION :
248 sHelpId = HID_FILEOPEN_VERSION;
249 break;
250
251 case ExtendedFilePickerElementIds::LISTBOX_TEMPLATE_LABEL :
252 case ExtendedFilePickerElementIds::LISTBOX_TEMPLATE :
253 sHelpId = HID_FILESAVE_TEMPLATE;
254 break;
255
256 case ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE_LABEL :
257 case ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE :
259 break;
260
261 case ExtendedFilePickerElementIds::LISTBOX_IMAGE_ANCHOR_LABEL :
262 case ExtendedFilePickerElementIds::LISTBOX_IMAGE_ANCHOR :
264 break;
265
266 case ExtendedFilePickerElementIds::CHECKBOX_SELECTION :
267 sHelpId = HID_FILESAVE_SELECTION;
268 break;
269
270 default:
271 SAL_WARN( "sfx.dialog", "invalid element id" );
272 }
273
274 OUString aHelpText;
275 Help* pHelp = Application::GetHelp();
276 if ( pHelp )
277 aHelpText = pHelp->GetHelpText(sHelpId, static_cast<weld::Widget*>(nullptr));
278 return aHelpText;
279}
280
281void FileDialogHelper_Impl::handleControlStateChanged( const FilePickerEvent& aEvent )
282{
283 switch ( aEvent.ElementId )
284 {
285 case CommonFilePickerElementIds::LISTBOX_FILTER:
287 enablePasswordBox( false );
289 // only use it for export and with our own dialog
290 if ( mbExport && !mbSystemPicker )
292 break;
293
294 case ExtendedFilePickerElementIds::CHECKBOX_PREVIEW:
295 updatePreviewState(true);
296 break;
297 }
298}
299
301{
302 if ( mbShowPreview )
303 TimeOutHdl_Impl( nullptr );
304}
305
306// XEventListener Methods
307void SAL_CALL FileDialogHelper_Impl::disposing( const EventObject& )
308{
309 SolarMutexGuard aGuard;
310 dispose();
311}
312
314{
315 if ( mxFileDlg.is() )
316 {
317 // remove the event listener
318 mxFileDlg->removeFilePickerListener( this );
319
320 ::comphelper::disposeComponent( mxFileDlg );
321 mxFileDlg.clear();
322 }
323}
324
326{
327 OUString aFilterName;
328
329 if( mxFileDlg.is() )
330 {
331 aFilterName = mxFileDlg->getCurrentFilter();
332
333 if ( !aFilterName.isEmpty() && isShowFilterExtensionEnabled() )
334 aFilterName = getFilterName( aFilterName );
335 }
336
337 return aFilterName;
338}
339
340void FileDialogHelper_Impl::LoadLastUsedFilter( const OUString& _rContextIdentifier )
341{
342 SvtViewOptions aDlgOpt( EViewType::Dialog, IODLG_CONFIGNAME );
343
344 if( aDlgOpt.Exists() )
345 {
346 OUString aLastFilter;
347 if( aDlgOpt.GetUserItem( _rContextIdentifier ) >>= aLastFilter )
348 setFilter( aLastFilter );
349 }
350}
351
353{
354 std::optional<OUString> pConfigId = GetLastFilterConfigId( meContext );
355 if( pConfigId )
356 SvtViewOptions( EViewType::Dialog, IODLG_CONFIGNAME ).SetUserItem( *pConfigId,
358}
359
360std::shared_ptr<const SfxFilter> FileDialogHelper_Impl::getCurrentSfxFilter()
361{
362 OUString aFilterName = getCurrentFilterUIName();
363
364 if ( mpMatcher && !aFilterName.isEmpty() )
365 return mpMatcher->GetFilter4UIName( aFilterName, m_nMustFlags, m_nDontFlags );
366
367 return nullptr;
368}
369
370bool FileDialogHelper_Impl::updateExtendedControl( sal_Int16 _nExtendedControlId, bool _bEnable )
371{
372 bool bIsEnabled = false;
373
374 uno::Reference < XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
375 if ( xCtrlAccess.is() )
376 {
377 try
378 {
379 xCtrlAccess->enableControl( _nExtendedControlId, _bEnable );
380 bIsEnabled = _bEnable;
381 }
382 catch( const IllegalArgumentException& )
383 {
384 TOOLS_WARN_EXCEPTION( "sfx", "FileDialogHelper_Impl::updateExtendedControl" );
385 }
386 }
387 return bIsEnabled;
388}
389
390bool FileDialogHelper_Impl::CheckFilterOptionsCapability( const std::shared_ptr<const SfxFilter>& _pFilter )
391{
392 bool bResult = false;
393
394 if( mxFilterCFG.is() && _pFilter )
395 {
396 try
397 {
398 Sequence < PropertyValue > aProps;
399 Any aAny = mxFilterCFG->getByName( _pFilter->GetName() );
400 if ( aAny >>= aProps )
401 {
402 OUString aServiceName;
403 for( const auto& rProp : std::as_const(aProps) )
404 {
405 if( rProp.Name == "UIComponent" )
406 {
407 rProp.Value >>= aServiceName;
408 if( !aServiceName.isEmpty() )
409 bResult = true;
410 }
411 }
412 }
413 }
414 catch( const Exception& )
415 {
416 }
417 }
418
419 return bResult;
420}
421
423{
424 bool bRet = false;
425
426 switch ( m_nDialogType )
427 {
428 case FILEOPEN_SIMPLE:
429 case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
430 case FILEOPEN_PLAY:
431 case FILEOPEN_LINK_PLAY:
432 case FILEOPEN_READONLY_VERSION:
433 case FILEOPEN_LINK_PREVIEW:
434 case FILEOPEN_PREVIEW:
435 bRet = true;
436 }
437
438 return bRet;
439}
440
442{
444 return;
445
447 ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS,
449 );
450}
451
453{
454 uno::Reference < XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
455 if ( !xCtrlAccess.is() )
456 return;
457
458 OUString sOldLabel( xCtrlAccess->getLabel( CommonFilePickerElementIds::PUSHBUTTON_OK ) );
459
460 // initialize button label; we need the label with the mnemonic char
461 if ( maButtonLabel.isEmpty() || maButtonLabel.indexOf( MNEMONIC_CHAR ) == -1 )
462 {
463 // cut the ellipses, if necessary
464 sal_Int32 nIndex = sOldLabel.indexOf( "..." );
465 if ( -1 == nIndex )
466 nIndex = sOldLabel.getLength();
467 maButtonLabel = sOldLabel.copy( 0, nIndex );
468 }
469
470 OUString sLabel = maButtonLabel;
471 // filter with options -> append ellipses on export button label
473 sLabel += "...";
474
475 if ( sOldLabel != sLabel )
476 {
477 try
478 {
479 xCtrlAccess->setLabel( CommonFilePickerElementIds::PUSHBUTTON_OK, sLabel );
480 }
481 catch( const IllegalArgumentException& )
482 {
483 TOOLS_WARN_EXCEPTION( "sfx.dialog", "FileDialogHelper_Impl::updateExportButton" );
484 }
485 }
486}
487
489{
490 if ( !mbHasSelectionBox )
491 return;
492
493 // Does the selection box exist?
494 bool bSelectionBoxFound = false;
495 uno::Reference< XControlInformation > xCtrlInfo( mxFileDlg, UNO_QUERY );
496 if ( xCtrlInfo.is() )
497 {
498 Sequence< OUString > aCtrlList = xCtrlInfo->getSupportedControls();
499 bSelectionBoxFound = comphelper::findValue(aCtrlList, "SelectionBox") != -1;
500 }
501
502 if ( bSelectionBoxFound )
503 {
504 std::shared_ptr<const SfxFilter> pFilter = getCurrentSfxFilter();
506 ExtendedFilePickerElementIds::CHECKBOX_SELECTION,
507 ( mbSelectionEnabled && pFilter && ( pFilter->GetFilterFlags() & SfxFilterFlags::SUPPORTSSELECTION ) ) );
508 uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
509 xCtrlAccess->setValue( ExtendedFilePickerElementIds::CHECKBOX_SELECTION, 0, Any( mbSelection ) );
510 }
511}
512
514{
515 if ( ! mbHasPassword )
516 return;
517
518 bool bWasEnabled = mbIsPwdEnabled;
519
520 std::shared_ptr<const SfxFilter> pCurrentFilter = getCurrentSfxFilter();
522 ExtendedFilePickerElementIds::CHECKBOX_PASSWORD,
523 pCurrentFilter && ( pCurrentFilter->GetFilterFlags() & SfxFilterFlags::ENCRYPTION )
524 );
525
526 if( bInit )
527 {
528 // in case of initialization previous state is not interesting
529 if( mbIsPwdEnabled )
530 {
531 uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
533 xCtrlAccess->setValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0, Any( true ) );
534 }
535 }
536 else if( !bWasEnabled && mbIsPwdEnabled )
537 {
538 uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
540 xCtrlAccess->setValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0, Any( true ) );
541 }
542 else if( bWasEnabled && !mbIsPwdEnabled )
543 {
544 // remember user settings until checkbox is enabled
545 uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
546 Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0 );
547 bool bPassWord = false;
548 mbPwdCheckBoxState = ( aValue >>= bPassWord ) && bPassWord;
549 xCtrlAccess->setValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0, Any( false ) );
550 }
551}
552
553void FileDialogHelper_Impl::updatePreviewState( bool _bUpdatePreviewWindow )
554{
555 if ( !mbHasPreview )
556 return;
557
558 uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
559
560 // check, whether or not we have to display a preview
561 if ( !xCtrlAccess.is() )
562 return;
563
564 try
565 {
566 Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0 );
567 bool bShowPreview = false;
568
569 if ( aValue >>= bShowPreview )
570 {
571 mbShowPreview = bShowPreview;
572
573 // setShowState has currently no effect for the
574 // OpenOffice FilePicker (see svtools/source/filepicker/iodlg.cxx)
575 uno::Reference< XFilePreview > xFilePreview( mxFileDlg, UNO_QUERY );
576 if ( xFilePreview.is() )
577 xFilePreview->setShowState( mbShowPreview );
578
579 if ( _bUpdatePreviewWindow )
580 TimeOutHdl_Impl( nullptr );
581 }
582 }
583 catch( const Exception& )
584 {
585 TOOLS_WARN_EXCEPTION( "sfx.dialog", "FileDialogHelper_Impl::updatePreviewState" );
586 }
587}
588
590{
591 Sequence < OUString > aEntries;
592 Sequence < OUString > aPathSeq = mxFileDlg->getFiles();
593
594 if ( aPathSeq.getLength() == 1 )
595 {
596 INetURLObject aObj( aPathSeq[0] );
597
598 if ( ( aObj.GetProtocol() == INetProtocol::File ) &&
600 {
601 try
602 {
603 uno::Reference< embed::XStorage > xStorage = ::comphelper::OStorageHelper::GetStorageFromURL(
605 embed::ElementModes::READ );
606
607 DBG_ASSERT( xStorage.is(), "The method must return the storage or throw exception!" );
608 if ( !xStorage.is() )
609 throw uno::RuntimeException();
610
611 const uno::Sequence < util::RevisionTag > xVersions = SfxMedium::GetVersionList( xStorage );
612
613 aEntries.realloc( xVersions.getLength() + 1 );
614 aEntries.getArray()[0] = SfxResId( STR_SFX_FILEDLG_ACTUALVERSION );
615
616 std::transform(xVersions.begin(), xVersions.end(), std::next(aEntries.getArray()),
617 [](const util::RevisionTag& rVersion) -> OUString { return rVersion.Identifier; });
618 }
619 catch( const uno::Exception& )
620 {
621 }
622 }
623 }
624
625 uno::Reference < XFilePickerControlAccess > xDlg( mxFileDlg, UNO_QUERY );
626 Any aValue;
627
628 try
629 {
630 xDlg->setValue( ExtendedFilePickerElementIds::LISTBOX_VERSION,
631 ControlActions::DELETE_ITEMS, aValue );
632 }
633 catch( const IllegalArgumentException& ){}
634
635 if ( !aEntries.hasElements() )
636 return;
637
638 try
639 {
640 aValue <<= aEntries;
641 xDlg->setValue( ExtendedFilePickerElementIds::LISTBOX_VERSION,
642 ControlActions::ADD_ITEMS, aValue );
643
644 Any aPos;
645 aPos <<= sal_Int32(0);
646 xDlg->setValue( ExtendedFilePickerElementIds::LISTBOX_VERSION,
647 ControlActions::SET_SELECT_ITEM, aPos );
648 }
649 catch( const IllegalArgumentException& ){}
650}
651
653{
654 if ( !mbHasPreview )
655 return;
656
658
659 Any aAny;
660 uno::Reference < XFilePreview > xFilePicker( mxFileDlg, UNO_QUERY );
661
662 if ( ! xFilePicker.is() )
663 return;
664
665 Sequence < OUString > aPathSeq = mxFileDlg->getFiles();
666
667 if ( mbShowPreview && ( aPathSeq.getLength() == 1 ) )
668 {
669 OUString aURL = aPathSeq[0];
670
671 if ( ERRCODE_NONE == getGraphic( aURL, maGraphic ) )
672 {
673 // changed the code slightly;
674 // before: the bitmap was scaled and
675 // surrounded a white frame
676 // now: the bitmap will only be scaled
677 // and the filepicker implementation
678 // is responsible for placing it at its
679 // proper position and painting a frame
680
682 if ( !aBmp.IsEmpty() )
683 {
684 // scale the bitmap to the correct size
685 sal_Int32 nOutWidth = xFilePicker->getAvailableWidth();
686 sal_Int32 nOutHeight = xFilePicker->getAvailableHeight();
687 sal_Int32 nBmpWidth = aBmp.GetSizePixel().Width();
688 sal_Int32 nBmpHeight = aBmp.GetSizePixel().Height();
689
690 double nXRatio = static_cast<double>(nOutWidth) / nBmpWidth;
691 double nYRatio = static_cast<double>(nOutHeight) / nBmpHeight;
692
693 if ( nXRatio < nYRatio )
694 aBmp.Scale( nXRatio, nXRatio );
695 else
696 aBmp.Scale( nYRatio, nYRatio );
697
698 // Convert to true color, to allow CopyPixel
699 aBmp.Convert( BmpConversion::N24Bit );
700
701 // and copy it into the Any
703
704 WriteDIB(aBmp, aData, false);
705
706 const Sequence < sal_Int8 > aBuffer(
707 static_cast< const sal_Int8* >(aData.GetData()),
708 aData.GetEndOfData() );
709
710 aAny <<= aBuffer;
711 }
712 }
713 }
714
715 try
716 {
717 SolarMutexReleaser aReleaseForCallback;
718 // clear the preview window
719 xFilePicker->setImage( FilePreviewImageFormats::BITMAP, aAny );
720 }
721 catch( const IllegalArgumentException& )
722 {
723 }
724}
725
727 Graphic& rGraphic ) const
728{
730 return ERRCODE_IO_NOTAFILE;
731
732 if ( !mpGraphicFilter )
734
735 // select graphic filter from dialog filter selection
736 OUString aCurFilter( getFilter() );
737
738 sal_uInt16 nFilter = !aCurFilter.isEmpty() && mpGraphicFilter->GetImportFormatCount()
739 ? mpGraphicFilter->GetImportFormatNumber( aCurFilter )
741
742 INetURLObject aURLObj( rURL );
743
744 if ( aURLObj.HasError() || INetProtocol::NotValid == aURLObj.GetProtocol() )
745 {
746 aURLObj.SetSmartProtocol( INetProtocol::File );
747 aURLObj.SetSmartURL( rURL );
748 }
749
750 ErrCode nRet = ERRCODE_NONE;
751
752 GraphicFilterImportFlags nFilterImportFlags = GraphicFilterImportFlags::SetLogsizeForJpeg;
753 // non-local?
754 if ( INetProtocol::File != aURLObj.GetProtocol() )
755 {
756 std::unique_ptr<SvStream> pStream = ::utl::UcbStreamHelper::CreateStream( rURL, StreamMode::READ );
757
758 if( pStream )
759 nRet = mpGraphicFilter->ImportGraphic( rGraphic, rURL, *pStream, nFilter, nullptr, nFilterImportFlags );
760 else
761 nRet = mpGraphicFilter->ImportGraphic( rGraphic, aURLObj, nFilter, nullptr, nFilterImportFlags );
762 }
763 else
764 {
765 nRet = mpGraphicFilter->ImportGraphic( rGraphic, aURLObj, nFilter, nullptr, nFilterImportFlags );
766 }
767
768 return nRet;
769}
770
772{
773 ErrCode nRet = ERRCODE_NONE;
774
775 // rhbz#1079672 do not return maGraphic, it needs not to be the selected file
776
777 OUString aPath;
778 Sequence<OUString> aPathSeq = mxFileDlg->getFiles();
779
780 if (aPathSeq.getLength() == 1)
781 {
782 aPath = aPathSeq[0];
783 }
784
785 if (!aPath.isEmpty())
786 nRet = getGraphic(aPath, rGraphic);
787 else
788 nRet = ERRCODE_IO_GENERAL;
789
790 return nRet;
791}
792
793static bool lcl_isSystemFilePicker( const uno::Reference< XExecutableDialog >& _rxFP )
794{
795 try
796 {
797 uno::Reference< XServiceInfo > xSI( _rxFP, UNO_QUERY );
798 if ( !xSI.is() )
799 return true;
800 return xSI->supportsService( "com.sun.star.ui.dialogs.SystemFilePicker" );
801 }
802 catch( const Exception& )
803 {
804 }
805 return false;
806}
807
808namespace {
809
810bool lcl_isAsyncFilePicker( const uno::Reference< XExecutableDialog >& _rxFP )
811{
812 try
813 {
814 uno::Reference<XAsynchronousExecutableDialog> xSI(_rxFP, UNO_QUERY);
815 return xSI.is();
816 }
817 catch( const Exception& )
818 {
819 }
820 return false;
821}
822
823enum open_or_save_t {OPEN, SAVE, UNDEFINED};
824
825}
826
827static open_or_save_t lcl_OpenOrSave(sal_Int16 const nDialogType)
828{
829 switch (nDialogType)
830 {
831 case FILEOPEN_SIMPLE:
832 case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
833 case FILEOPEN_LINK_PREVIEW_IMAGE_ANCHOR:
834 case FILEOPEN_PLAY:
835 case FILEOPEN_LINK_PLAY:
836 case FILEOPEN_READONLY_VERSION:
837 case FILEOPEN_LINK_PREVIEW:
838 case FILEOPEN_PREVIEW:
839 return OPEN;
840 case FILESAVE_SIMPLE:
841 case FILESAVE_AUTOEXTENSION_PASSWORD:
842 case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
843 case FILESAVE_AUTOEXTENSION_SELECTION:
844 case FILESAVE_AUTOEXTENSION_TEMPLATE:
845 case FILESAVE_AUTOEXTENSION:
846 return SAVE;
847 default:
848 assert(false); // invalid dialog type
849 }
850 return UNDEFINED;
851}
852
853// FileDialogHelper_Impl
854
855css::uno::Reference<css::awt::XWindow> FileDialogHelper_Impl::GetFrameInterface()
856{
857 if (mpFrameWeld)
858 return mpFrameWeld->GetXWindow();
859 return css::uno::Reference<css::awt::XWindow>();
860}
861
863 FileDialogHelper* _pAntiImpl,
864 sal_Int16 nDialogType,
865 FileDialogFlags nFlags,
866 sal_Int16 nDialog,
867 weld::Window* pFrameWeld,
868 const OUString& sStandardDir,
869 const css::uno::Sequence< OUString >& rDenyList
870 )
871 :maPreviewIdle("sfx2 FileDialogHelper_Impl maPreviewIdle")
872 ,m_nDialogType ( nDialogType )
873 ,meContext ( FileDialogHelper::UnknownContext )
874{
875 const char* pServiceName=nullptr;
876 switch (nDialog)
877 {
880 pServiceName = "com.sun.star.ui.dialogs.OfficeFilePicker";
881 break;
883 pServiceName = "com.sun.star.ui.dialogs.RemoteFilePicker";
884 break;
885 default:
886 pServiceName = "com.sun.star.ui.dialogs.FilePicker";
887 break;
888 }
889
890 OUString aService = OUString::createFromAscii( pServiceName );
891
892 uno::Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
893
894 // create the file open dialog
895 // the flags can be SFXWB_INSERT or SFXWB_MULTISELECTION
896
897 mpFrameWeld = pFrameWeld;
898 mpAntiImpl = _pAntiImpl;
899 mbHasAutoExt = false;
900 mbHasPassword = false;
901 m_bHaveFilterOptions = false;
902 mbIsPwdEnabled = true;
903 mbHasVersions = false;
904 mbHasPreview = false;
905 mbShowPreview = false;
906 mbDeleteMatcher = false;
907 mbInsert = bool(nFlags & (FileDialogFlags::Insert|
910 mbExport = bool(nFlags & FileDialogFlags::Export);
911 mbIsSaveDlg = false;
912 mbPwdCheckBoxState = false;
913 mbSelection = false;
914 mbSelectionEnabled = true;
915 mbHasSelectionBox = false;
917
918 // default settings
919 m_nDontFlags = SFX_FILTER_NOTINSTALLED | SfxFilterFlags::INTERNAL | SfxFilterFlags::NOTINFILEDLG;
921 m_nMustFlags = SfxFilterFlags::IMPORT;
922 else
923 m_nMustFlags = SfxFilterFlags::EXPORT;
924
925
926 mpMatcher = nullptr;
927 mpGraphicFilter = nullptr;
928 mnPostUserEventId = nullptr;
929
930 // create the picker component
931 mxFileDlg.set(xFactory->createInstance( aService ), css::uno::UNO_QUERY);
933 mbAsyncPicker = lcl_isAsyncFilePicker(mxFileDlg);
934
935 uno::Reference< XInitialization > xInit( mxFileDlg, UNO_QUERY );
936
937 if ( ! mxFileDlg.is() )
938 {
939 return;
940 }
941
942
943 if ( xInit.is() )
944 {
945 sal_Int16 nTemplateDescription = TemplateDescription::FILEOPEN_SIMPLE;
946
947 switch ( m_nDialogType )
948 {
949 case FILEOPEN_SIMPLE:
950 nTemplateDescription = TemplateDescription::FILEOPEN_SIMPLE;
951 break;
952
953 case FILESAVE_SIMPLE:
954 nTemplateDescription = TemplateDescription::FILESAVE_SIMPLE;
955 mbIsSaveDlg = true;
956 break;
957
958 case FILESAVE_AUTOEXTENSION_PASSWORD:
959 nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD;
960 mbHasPassword = true;
961 mbHasAutoExt = true;
962 mbIsSaveDlg = true;
963 break;
964
965 case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
966 nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS;
967 mbHasPassword = true;
968
970 if( xFactory.is() )
971 {
972 mxFilterCFG.set(
973 xFactory->createInstance( "com.sun.star.document.FilterFactory" ),
974 UNO_QUERY );
975 }
976
977 mbHasAutoExt = true;
978 mbIsSaveDlg = true;
979 break;
980
981 case FILESAVE_AUTOEXTENSION_SELECTION:
982 nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION_SELECTION;
983 mbHasAutoExt = true;
984 mbIsSaveDlg = true;
985 mbHasSelectionBox = true;
986 if ( mbExport && !mxFilterCFG.is() && xFactory.is() )
987 {
988 mxFilterCFG.set(
989 xFactory->createInstance( "com.sun.star.document.FilterFactory" ),
990 UNO_QUERY );
991 }
992 break;
993
994 case FILESAVE_AUTOEXTENSION_TEMPLATE:
995 nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION_TEMPLATE;
996 mbHasAutoExt = true;
997 mbIsSaveDlg = true;
998 break;
999
1000 case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
1001 nTemplateDescription = TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE;
1002 mbHasPreview = true;
1003 break;
1004
1005 case FILEOPEN_LINK_PREVIEW_IMAGE_ANCHOR:
1006 nTemplateDescription = TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_ANCHOR;
1007 mbHasPreview = true;
1008 break;
1009
1010 case FILEOPEN_PLAY:
1011 nTemplateDescription = TemplateDescription::FILEOPEN_PLAY;
1012 break;
1013
1014 case FILEOPEN_LINK_PLAY:
1015 nTemplateDescription = TemplateDescription::FILEOPEN_LINK_PLAY;
1016 break;
1017
1018 case FILEOPEN_READONLY_VERSION:
1019 nTemplateDescription = TemplateDescription::FILEOPEN_READONLY_VERSION;
1020 mbHasVersions = true;
1021 break;
1022
1023 case FILEOPEN_LINK_PREVIEW:
1024 nTemplateDescription = TemplateDescription::FILEOPEN_LINK_PREVIEW;
1025 mbHasPreview = true;
1026 break;
1027
1028 case FILESAVE_AUTOEXTENSION:
1029 nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION;
1030 mbHasAutoExt = true;
1031 mbIsSaveDlg = true;
1032 break;
1033
1034 case FILEOPEN_PREVIEW:
1035 nTemplateDescription = TemplateDescription::FILEOPEN_PREVIEW;
1036 mbHasPreview = true;
1037 break;
1038
1039 default:
1040 SAL_WARN( "sfx.dialog", "FileDialogHelper::ctor with unknown type" );
1041 break;
1042 }
1043
1044 if (mbHasPreview)
1045 {
1046 maPreviewIdle.SetPriority( TaskPriority::LOWEST );
1047 maPreviewIdle.SetInvokeHandler( LINK( this, FileDialogHelper_Impl, TimeOutHdl_Impl ) );
1048 }
1049
1050 auto xWindow = GetFrameInterface();
1051
1052 Sequence < Any > aInitArguments(!xWindow.is() ? 3 : 4);
1053 auto pInitArguments = aInitArguments.getArray();
1054
1055 // This is a hack. We currently know that the internal file picker implementation
1056 // supports the extended arguments as specified below.
1057 // TODO:
1058 // a) adjust the service description so that it includes the TemplateDescription and ParentWindow args
1059 // b) adjust the implementation of the system file picker to that it recognizes it
1060 if ( mbSystemPicker )
1061 {
1062 pInitArguments[0] <<= nTemplateDescription;
1063 if (xWindow.is())
1064 pInitArguments[1] <<= xWindow;
1065 }
1066 else
1067 {
1068 pInitArguments[0] <<= NamedValue(
1069 "TemplateDescription",
1070 Any( nTemplateDescription )
1071 );
1072
1073 pInitArguments[1] <<= NamedValue(
1074 "StandardDir",
1075 Any( sStandardDir )
1076 );
1077
1078 pInitArguments[2] <<= NamedValue(
1079 "DenyList",
1080 Any( rDenyList )
1081 );
1082
1083
1084 if (xWindow.is())
1085 pInitArguments[3] <<= NamedValue("ParentWindow", Any(xWindow));
1086 }
1087
1088 try
1089 {
1090 xInit->initialize( aInitArguments );
1091 }
1092 catch( const Exception& )
1093 {
1094 OSL_FAIL( "FileDialogHelper_Impl::FileDialogHelper_Impl: could not initialize the picker!" );
1095 }
1096 }
1097
1098
1099 // set multiselection mode
1100 if ( nFlags & FileDialogFlags::MultiSelection )
1101 mxFileDlg->setMultiSelectionMode( true );
1102
1103 if ( nFlags & FileDialogFlags::Graphic ) // generate graphic filter only on demand
1104 {
1106 }
1107
1108 // Export dialog
1109 if ( mbExport )
1110 {
1111 mxFileDlg->setTitle( SfxResId( STR_SFX_EXPLORERFILE_EXPORT ) );
1112 try {
1113 css::uno::Reference < XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY_THROW );
1114 xCtrlAccess->enableControl( ExtendedFilePickerElementIds::LISTBOX_FILTER_SELECTOR, true );
1115 }
1116 catch( const Exception & ) { }
1117 }
1118
1119 // Save a copy dialog
1120 if ( nFlags & FileDialogFlags::SaveACopy )
1121 {
1122 mxFileDlg->setTitle( SfxResId( STR_PB_SAVEACOPY ) );
1123 }
1124
1125 // the "insert file" dialog needs another title
1126 if ( mbInsert )
1127 {
1128 if ( nFlags & FileDialogFlags::InsertCompare )
1129 {
1130 mxFileDlg->setTitle( SfxResId( STR_PB_COMPAREDOC ) );
1131 }
1132 else if ( nFlags & FileDialogFlags::InsertMerge )
1133 {
1134 mxFileDlg->setTitle( SfxResId( STR_PB_MERGEDOC ) );
1135 }
1136 else
1137 {
1138 mxFileDlg->setTitle( SfxResId( STR_SFX_EXPLORERFILE_INSERT ) );
1139 }
1140 uno::Reference < XFilePickerControlAccess > xExtDlg( mxFileDlg, UNO_QUERY );
1141 if ( xExtDlg.is() )
1142 {
1143 try
1144 {
1145 xExtDlg->setLabel( CommonFilePickerElementIds::PUSHBUTTON_OK,
1146 SfxResId( STR_SFX_EXPLORERFILE_BUTTONINSERT ) );
1147 }
1148 catch( const IllegalArgumentException& ){}
1149 }
1150 }
1151
1152 // add the event listener
1153 mxFileDlg->addFilePickerListener( this );
1154}
1155
1156css::uno::Reference<css::ui::dialogs::XFolderPicker2> createFolderPicker(const css::uno::Reference<css::uno::XComponentContext>& rContext, weld::Window* pPreferredParent)
1157{
1158 auto xRet = css::ui::dialogs::FolderPicker::create(rContext);
1159
1160 // see FileDialogHelper_Impl::FileDialogHelper_Impl (above) for args to FilePicker
1161 // reuse the same arguments for FolderPicker
1162 if (pPreferredParent && lcl_isSystemFilePicker(xRet))
1163 {
1164 uno::Reference< XInitialization > xInit(xRet, UNO_QUERY);
1165 if (xInit.is())
1166 {
1167 Sequence<Any> aInitArguments{ Any(sal_Int32(0)), Any(pPreferredParent->GetXWindow()) };
1168
1169 try
1170 {
1171 xInit->initialize(aInitArguments);
1172 }
1173 catch (const Exception&)
1174 {
1175 OSL_FAIL( "createFolderPicker: could not initialize the picker!" );
1176 }
1177 }
1178 }
1179
1180 return xRet;
1181}
1182
1184{
1185 // Remove user event if we haven't received it yet
1186 if ( mnPostUserEventId )
1188 mnPostUserEventId = nullptr;
1189
1190 mpGraphicFilter.reset();
1191
1192 if ( mbDeleteMatcher )
1193 delete mpMatcher;
1194
1196
1197 ::comphelper::disposeComponent( mxFileDlg );
1198}
1199
1200void FileDialogHelper_Impl::setControlHelpIds( const sal_Int16* _pControlId, const char** _pHelpId )
1201{
1202 DBG_ASSERT( _pControlId && _pHelpId, "FileDialogHelper_Impl::setControlHelpIds: invalid array pointers!" );
1203 if ( !_pControlId || !_pHelpId )
1204 return;
1205
1206 // forward these ids to the file picker
1207 try
1208 {
1209 const OUString sHelpIdPrefix( INET_HID_SCHEME );
1210 // the ids for the single controls
1211 uno::Reference< XFilePickerControlAccess > xControlAccess( mxFileDlg, UNO_QUERY );
1212 if ( xControlAccess.is() )
1213 {
1214 while ( *_pControlId )
1215 {
1216 DBG_ASSERT( INetURLObject( OStringToOUString( *_pHelpId, RTL_TEXTENCODING_UTF8 ) ).GetProtocol() == INetProtocol::NotValid, "Wrong HelpId!" );
1217 OUString sId = sHelpIdPrefix +
1218 OUString( *_pHelpId, strlen( *_pHelpId ), RTL_TEXTENCODING_UTF8 );
1219 xControlAccess->setValue( *_pControlId, ControlActions::SET_HELP_URL, Any( sId ) );
1220
1221 ++_pControlId; ++_pHelpId;
1222 }
1223 }
1224 }
1225 catch( const Exception& )
1226 {
1227 TOOLS_WARN_EXCEPTION( "sfx.dialog", "FileDialogHelper_Impl::setControlHelpIds: caught an exception while setting the help ids!" );
1228 }
1229}
1230
1231IMPL_LINK_NOARG( FileDialogHelper_Impl, InitControls, void*, void )
1232{
1233 mnPostUserEventId = nullptr;
1234 enablePasswordBox( true );
1235 updateFilterOptionsBox( );
1236 updateSelectionBox( );
1237}
1238
1240{
1241 loadConfig( );
1243 updatePreviewState( false );
1244
1246
1247#if !(defined(MACOSX) && defined(MACOSX)) && !defined(_WIN32)
1248 // allow for dialog implementations which need to be executed before they return valid values for
1249 // current filter and such
1250
1251 // On Vista (at least SP1) it's the same as on MacOSX, the modal dialog won't let message pass
1252 // through before it returns from execution
1254#else
1255 // However, the macOS implementation's pickers run modally in execute and so the event doesn't
1256 // get through in time... so we call the methods directly
1257 enablePasswordBox( true );
1260#endif
1261}
1262
1263void FileDialogHelper_Impl::postExecute( sal_Int16 _nResult )
1264{
1265 if ( ExecutableDialogResults::CANCEL != _nResult )
1266 saveConfig();
1267}
1268
1270{
1271 if ( maFileName.isEmpty() )
1272 return;
1273
1274 INetURLObject aObj( maPath );
1275 aObj.Append( maFileName );
1276
1277 // in case we're operating as save dialog, and "auto extension" is checked,
1278 // cut the extension from the name
1279 if ( !(mbIsSaveDlg && mbHasAutoExt) )
1280 return;
1281
1282 try
1283 {
1284 bool bAutoExtChecked = false;
1285
1286 uno::Reference < XFilePickerControlAccess > xControlAccess( mxFileDlg, UNO_QUERY );
1287 if ( xControlAccess.is()
1288 && ( xControlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, 0 )
1289 >>= bAutoExtChecked
1290 )
1291 )
1292 {
1293 if ( bAutoExtChecked )
1294 { // cut the extension
1295 aObj.removeExtension( );
1296 mxFileDlg->setDefaultName(
1298 }
1299 }
1300 }
1301 catch( const Exception& )
1302 {
1303 OSL_FAIL( "FileDialogHelper_Impl::implInitializeFileName: could not ask for the auto-extension current-value!" );
1304 }
1305}
1306
1308{
1309 preExecute();
1310
1311 sal_Int16 nRet = ExecutableDialogResults::CANCEL;
1312
1313//On MacOSX the native file picker has to run in the primordial thread because of drawing issues
1314//On Linux the native gtk file picker, when backed by gnome-vfs2, needs to be run in the same
1315//primordial thread as the ucb gnome-vfs2 provider was initialized in.
1316
1317 {
1318 try
1319 {
1320#ifdef _WIN32
1321 if ( mbSystemPicker )
1322 {
1323 SolarMutexReleaser aSolarMutex;
1324 nRet = mxFileDlg->execute();
1325 }
1326 else
1327#endif
1328 nRet = mxFileDlg->execute();
1329 }
1330 catch( const Exception& )
1331 {
1332 TOOLS_WARN_EXCEPTION( "sfx.dialog", "FileDialogHelper_Impl::implDoExecute" );
1333 }
1334 }
1335
1336 postExecute( nRet );
1337
1338 return nRet;
1339}
1340
1342{
1343 DBG_ASSERT( mxFileDlg.is(), "invalid file dialog" );
1344
1345 assert(mbAsyncPicker);
1346 preExecute();
1347
1348 try
1349 {
1350 uno::Reference< XAsynchronousExecutableDialog > xAsyncDlg( mxFileDlg, UNO_QUERY );
1351 if ( xAsyncDlg.is() )
1352 xAsyncDlg->startExecuteModal( this );
1353 }
1354 catch( const Exception& )
1355 {
1356 TOOLS_WARN_EXCEPTION( "sfx.dialog", "FileDialogHelper_Impl::implDoExecute" );
1357 }
1358}
1359
1360void FileDialogHelper_Impl::implGetAndCacheFiles(const uno::Reference< XInterface >& xPicker, std::vector<OUString>& rpURLList)
1361{
1362 rpURLList.clear();
1363
1364 // a) the new way (optional!)
1365 uno::Reference< XFilePicker3 > xPickNew(xPicker, UNO_QUERY);
1366 if (xPickNew.is())
1367 {
1368 Sequence< OUString > lFiles = xPickNew->getSelectedFiles();
1369 comphelper::sequenceToContainer(rpURLList, lFiles);
1370 }
1371
1372 // b) the olde way ... non optional.
1373 else
1374 {
1375 uno::Reference< XFilePicker3 > xPickOld(xPicker, UNO_QUERY_THROW);
1376 Sequence< OUString > lFiles = xPickOld->getFiles();
1377 ::sal_Int32 nFiles = lFiles.getLength();
1378 if ( nFiles == 1 )
1379 {
1380 rpURLList.push_back(lFiles[0]);
1381 }
1382 else if ( nFiles > 1 )
1383 {
1384 INetURLObject aPath( lFiles[0] );
1385 aPath.setFinalSlash();
1386
1387 for (::sal_Int32 i = 1; i < nFiles; i++)
1388 {
1389 if (i == 1)
1390 aPath.Append( lFiles[i] );
1391 else
1392 aPath.setName( lFiles[i] );
1393
1394 rpURLList.push_back(aPath.GetMainURL(INetURLObject::DecodeMechanism::NONE));
1395 }
1396 }
1397 }
1398
1399 mlLastURLs = rpURLList;
1400}
1401
1402ErrCode FileDialogHelper_Impl::execute( std::vector<OUString>& rpURLList,
1403 std::optional<SfxAllItemSet>& rpSet,
1404 OUString& rFilter )
1405{
1406 // rFilter is a pure output parameter, it shouldn't be used for anything else
1407 // changing this would surely break code
1408 // rpSet is in/out parameter, usually just a media-descriptor that can be changed by dialog
1409
1410 uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
1411
1412 // retrieves parameters from rpSet
1413 // for now only Password is used
1414 if ( rpSet )
1415 {
1416 // check password checkbox if the document had password before
1417 if( mbHasPassword )
1418 {
1419 const SfxBoolItem* pPassItem = SfxItemSet::GetItem<SfxBoolItem>(&*rpSet, SID_PASSWORDINTERACTION, false);
1420 mbPwdCheckBoxState = ( pPassItem != nullptr && pPassItem->GetValue() );
1421
1422 // in case the document has password to modify, the dialog should be shown
1423 const SfxUnoAnyItem* pPassToModifyItem = SfxItemSet::GetItem<SfxUnoAnyItem>(&*rpSet, SID_MODIFYPASSWORDINFO, false);
1424 mbPwdCheckBoxState |= ( pPassToModifyItem && pPassToModifyItem->GetValue().hasValue() );
1425 }
1426
1427 const SfxBoolItem* pSelectItem = SfxItemSet::GetItem<SfxBoolItem>(&*rpSet, SID_SELECTION, false);
1428 if ( pSelectItem )
1429 mbSelection = pSelectItem->GetValue();
1430 else
1431 mbSelectionEnabled = false;
1432
1433 // the password will be set in case user decide so
1434 rpSet->ClearItem( SID_PASSWORDINTERACTION );
1435 if (rpSet->HasItem( SID_PASSWORD ))
1436 {
1437 // As the SID_ENCRYPTIONDATA and SID_PASSWORD are using for setting password together, we need to clear them both.
1438 // Note: Do not remove SID_ENCRYPTIONDATA without SID_PASSWORD
1439 rpSet->ClearItem( SID_PASSWORD );
1440 rpSet->ClearItem( SID_ENCRYPTIONDATA );
1441 }
1442 rpSet->ClearItem( SID_RECOMMENDREADONLY );
1443 rpSet->ClearItem( SID_MODIFYPASSWORDINFO );
1444
1445 }
1446
1448 {
1451 }
1452
1453 rpURLList.clear();
1454
1455 if ( ! mxFileDlg.is() )
1456 return ERRCODE_ABORT;
1457
1458 if ( ExecutableDialogResults::CANCEL != implDoExecute() )
1459 {
1460 // create an itemset if there is no
1461 if( !rpSet )
1462 rpSet.emplace( SfxGetpApp()->GetPool() );
1463
1464 // the item should remain only if it was set by the dialog
1465 rpSet->ClearItem( SID_SELECTION );
1466
1468 {
1469 try
1470 {
1471 Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_SELECTION, 0 );
1472 bool bSelection = false;
1473 if ( aValue >>= bSelection )
1474 rpSet->Put( SfxBoolItem( SID_SELECTION, bSelection ) );
1475 }
1476 catch( const IllegalArgumentException& )
1477 {
1478 TOOLS_WARN_EXCEPTION( "sfx.dialog", "FileDialogHelper_Impl::execute: caught an IllegalArgumentException!" );
1479 }
1480 }
1481
1482
1483 // set the read-only flag. When inserting a file, this flag is always set
1484 if ( mbInsert )
1485 rpSet->Put( SfxBoolItem( SID_DOC_READONLY, true ) );
1486 else
1487 {
1488 if ( ( FILEOPEN_READONLY_VERSION == m_nDialogType ) && xCtrlAccess.is() )
1489 {
1490 try
1491 {
1492 Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_READONLY, 0 );
1493 bool bReadOnly = false;
1494 if ( ( aValue >>= bReadOnly ) && bReadOnly )
1495 rpSet->Put( SfxBoolItem( SID_DOC_READONLY, bReadOnly ) );
1496 }
1497 catch( const IllegalArgumentException& )
1498 {
1499 TOOLS_WARN_EXCEPTION( "sfx.dialog", "FileDialogHelper_Impl::execute: caught an IllegalArgumentException!" );
1500 }
1501 }
1502 }
1503 if ( mbHasVersions && xCtrlAccess.is() )
1504 {
1505 try
1506 {
1507 Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::LISTBOX_VERSION,
1508 ControlActions::GET_SELECTED_ITEM_INDEX );
1509 sal_Int32 nVersion = 0;
1510 if ( ( aValue >>= nVersion ) && nVersion > 0 )
1511 // open a special version; 0 == current version
1512 rpSet->Put( SfxInt16Item( SID_VERSION, static_cast<short>(nVersion) ) );
1513 }
1514 catch( const IllegalArgumentException& ){}
1515 }
1516
1517 // set the filter
1518 getRealFilter( rFilter );
1519
1520 std::shared_ptr<const SfxFilter> pCurrentFilter = getCurrentSfxFilter();
1521
1522 // fill the rpURLList
1523 implGetAndCacheFiles( mxFileDlg, rpURLList );
1524 if ( rpURLList.empty() )
1525 return ERRCODE_ABORT;
1526
1527 // check, whether or not we have to display a password box
1528 if ( pCurrentFilter && mbHasPassword && mbIsPwdEnabled && xCtrlAccess.is() )
1529 {
1530 try
1531 {
1532 Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0 );
1533 bool bPassWord = false;
1534 if ( ( aValue >>= bPassWord ) && bPassWord )
1535 {
1536 // ask for a password
1537 OUString aDocName(rpURLList[0]);
1538 ErrCode errCode = RequestPassword(pCurrentFilter, aDocName, &*rpSet, GetFrameInterface());
1539 if (errCode != ERRCODE_NONE)
1540 return errCode;
1541 }
1542 }
1543 catch( const IllegalArgumentException& ){}
1544 }
1545 // check, whether or not we have to display a key selection box
1546 if ( pCurrentFilter && mbHasPassword && xCtrlAccess.is() )
1547 {
1548 try
1549 {
1550 Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_GPGENCRYPTION, 0 );
1551 bool bGpg = false;
1552 if ( ( aValue >>= bGpg ) && bGpg )
1553 {
1554 uno::Sequence< beans::NamedValue > aEncryptionData;
1555 while(true)
1556 {
1557 try
1558 {
1559 // ask for keys
1561 break; // user cancelled or we've some keys now
1562 }
1563 catch( const IllegalArgumentException& )
1564 {
1565 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(mpFrameWeld,
1566 VclMessageType::Warning, VclButtonsType::Ok,
1567 SfxResId(RID_SVXSTR_GPG_ENCRYPT_FAILURE)));
1568 xBox->run();
1569 }
1570 }
1571
1572 if ( aEncryptionData.hasElements() )
1573 rpSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::Any( aEncryptionData) ) );
1574 }
1575 }
1576 catch( const IllegalArgumentException& ){}
1577 }
1578
1580 return ERRCODE_NONE;
1581 }
1582 else
1583 return ERRCODE_ABORT;
1584}
1585
1587{
1588 if ( ! mxFileDlg.is() )
1589 return ERRCODE_ABORT;
1590
1591 sal_Int16 nRet = implDoExecute();
1592
1593 maPath = mxFileDlg->getDisplayDirectory();
1594
1595 if ( ExecutableDialogResults::CANCEL == nRet )
1596 return ERRCODE_ABORT;
1597 else
1598 {
1599 return ERRCODE_NONE;
1600 }
1601}
1602
1604{
1605 OUString aPath;
1606
1607 if ( mxFileDlg.is() )
1608 aPath = mxFileDlg->getDisplayDirectory();
1609
1610 if ( aPath.isEmpty() )
1611 aPath = maPath;
1612
1613 return aPath;
1614}
1615
1617{
1618 OUString aFilter = getCurrentFilterUIName();
1619
1620 if( aFilter.isEmpty() )
1621 aFilter = maCurFilter;
1622
1623 return aFilter;
1624}
1625
1626void FileDialogHelper_Impl::getRealFilter( OUString& _rFilter ) const
1627{
1628 _rFilter = getCurrentFilterUIName();
1629
1630 if ( _rFilter.isEmpty() )
1631 _rFilter = maCurFilter;
1632
1633 if ( !_rFilter.isEmpty() && mpMatcher )
1634 {
1635 std::shared_ptr<const SfxFilter> pFilter =
1637 _rFilter = pFilter ? pFilter->GetFilterName() : OUString();
1638 }
1639}
1640
1642{
1643#ifdef UNX
1644 // lp#905355, fdo#43895
1645 // Check that the file has read only permission and is in /tmp -- this is
1646 // the case if we have opened the file from the web with firefox only.
1647 if (maFileName.isEmpty()) {
1648 return;
1649 }
1650 INetURLObject url(maPath);
1651 if (url.GetProtocol() != INetProtocol::File
1652 || url.getName(0, true, INetURLObject::DecodeMechanism::WithCharset) != "tmp")
1653 {
1654 return;
1655 }
1656 if (maFileName.indexOf('/') != -1) {
1657 SAL_WARN("sfx.dialog", maFileName << " contains /");
1658 return;
1659 }
1660 url.insertName(
1663 OUString sysPathU;
1664 osl::FileBase::RC e = osl::FileBase::getSystemPathFromFileURL(
1666 if (e != osl::FileBase::E_None) {
1667 SAL_WARN(
1668 "sfx.dialog",
1669 "getSystemPathFromFileURL("
1670 << url.GetMainURL(INetURLObject::DecodeMechanism::NONE) << ") failed with "
1671 << +e);
1672 return;
1673 }
1674 OString sysPathC;
1675 if (!sysPathU.convertToString(
1676 &sysPathC, osl_getThreadTextEncoding(),
1677 (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
1678 | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
1679 {
1680 SAL_WARN(
1681 "sfx.dialog",
1682 "convertToString(" << sysPathU << ") failed for encoding "
1683 << +osl_getThreadTextEncoding());
1684 return;
1685 }
1686 struct stat aFileStat;
1687 if (stat(sysPathC.getStr(), &aFileStat) == -1) {
1688 SAL_WARN( "sfx.dialog", "stat(" << sysPathC << ") failed with errno " << errno);
1689 return;
1690 }
1691 if ((aFileStat.st_mode & (S_IRWXO | S_IRWXG | S_IRWXU)) == S_IRUSR) {
1693 mxFileDlg->setDisplayDirectory( maPath );
1694 }
1695#else
1696 (void) this;
1697#endif
1698}
1699
1700void FileDialogHelper_Impl::displayFolder( const OUString& _rPath )
1701{
1702 if ( _rPath.isEmpty() )
1703 // nothing to do
1704 return;
1705
1706 maPath = _rPath;
1707 if ( mxFileDlg.is() )
1708 {
1709 try
1710 {
1711 mxFileDlg->setDisplayDirectory( maPath );
1712 verifyPath();
1713 }
1714 catch( const IllegalArgumentException& )
1715 {
1716 TOOLS_WARN_EXCEPTION( "sfx", "FileDialogHelper_Impl::displayFolder" );
1717 }
1718 }
1719}
1720
1721void FileDialogHelper_Impl::setFileName( const OUString& _rFile )
1722{
1723 maFileName = _rFile;
1724 if ( mxFileDlg.is() )
1725 {
1726 try
1727 {
1728 mxFileDlg->setDefaultName( maFileName );
1729 verifyPath();
1730 }
1731 catch( const IllegalArgumentException& )
1732 {
1733 TOOLS_WARN_EXCEPTION( "sfx", "FileDialogHelper_Impl::setFileName" );
1734 }
1735 }
1736}
1737
1738void FileDialogHelper_Impl::setFilter( const OUString& rFilter )
1739{
1740 DBG_ASSERT( rFilter.indexOf(':') == -1, "Old filter name used!");
1741
1742 maCurFilter = rFilter;
1743
1744 if ( !rFilter.isEmpty() && mpMatcher )
1745 {
1746 std::shared_ptr<const SfxFilter> pFilter = mpMatcher->GetFilter4FilterName(
1747 rFilter, m_nMustFlags, m_nDontFlags );
1748 if ( pFilter )
1749 maCurFilter = pFilter->GetUIName();
1750 }
1751
1752 if ( !maCurFilter.isEmpty() && mxFileDlg.is() )
1753 {
1754 try
1755 {
1756 mxFileDlg->setCurrentFilter( maCurFilter );
1757 }
1758 catch( const IllegalArgumentException& ){}
1759 }
1760}
1761
1762void FileDialogHelper_Impl::createMatcher( const OUString& rFactory )
1763{
1764 if (mbDeleteMatcher)
1765 delete mpMatcher;
1766
1768 mbDeleteMatcher = true;
1769}
1770
1771void FileDialogHelper_Impl::addFilters( const OUString& rFactory,
1772 SfxFilterFlags nMust,
1773 SfxFilterFlags nDont )
1774{
1775 if ( ! mxFileDlg.is() )
1776 return;
1777
1778 if (mbDeleteMatcher)
1779 delete mpMatcher;
1780
1781 // we still need a matcher to convert UI names to filter names
1782 if ( rFactory.isEmpty() )
1783 {
1784 SfxApplication *pSfxApp = SfxGetpApp();
1785 mpMatcher = &pSfxApp->GetFilterMatcher();
1786 mbDeleteMatcher = false;
1787 }
1788 else
1789 {
1790 mpMatcher = new SfxFilterMatcher( rFactory );
1791 mbDeleteMatcher = true;
1792 }
1793
1794 uno::Reference< XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
1795 uno::Reference< XContainerQuery > xFilterCont(
1796 xSMGR->createInstance("com.sun.star.document.FilterFactory"),
1797 UNO_QUERY);
1798 if ( ! xFilterCont.is() )
1799 return;
1800
1801 m_nMustFlags |= nMust;
1802 m_nDontFlags |= nDont;
1803
1804 // create the list of filters
1805 OUString sQuery =
1806 "getSortedFilterList()"
1807 ":module=" +
1808 rFactory + // use long name here !
1809 ":iflags=" +
1810 OUString::number(static_cast<sal_Int32>(m_nMustFlags)) +
1811 ":eflags=" +
1812 OUString::number(static_cast<sal_Int32>(m_nDontFlags));
1813
1814 uno::Reference< XEnumeration > xResult;
1815 try
1816 {
1817 xResult = xFilterCont->createSubSetEnumerationByQuery(sQuery);
1818 }
1819 catch( const uno::Exception& )
1820 {
1821 SAL_WARN( "sfx.dialog", "Could not get filters from the configuration!" );
1822 }
1823
1824 TSortedFilterList aIter (xResult);
1825
1826 // append the filters
1827 OUString sFirstFilter;
1829 ::sfx2::appendFiltersForOpen( aIter, mxFileDlg, sFirstFilter, *this );
1830 else if ( mbExport )
1831 ::sfx2::appendExportFilters( aIter, mxFileDlg, sFirstFilter, *this );
1832 else
1833 ::sfx2::appendFiltersForSave( aIter, mxFileDlg, sFirstFilter, *this, rFactory );
1834
1835 // set our initial selected filter (if we do not already have one)
1836 if ( maSelectFilter.isEmpty() )
1837 maSelectFilter = sFirstFilter;
1838}
1839
1840void FileDialogHelper_Impl::addFilter( const OUString& rFilterName,
1841 const OUString& rExtension )
1842{
1843 if ( ! mxFileDlg.is() )
1844 return;
1845
1846 try
1847 {
1848 mxFileDlg->appendFilter( rFilterName, rExtension );
1849
1850 if ( maSelectFilter.isEmpty() )
1851 maSelectFilter = rFilterName;
1852 }
1853 catch( const IllegalArgumentException& )
1854 {
1855 SAL_WARN( "sfx.dialog", "Could not append Filter" << rFilterName );
1856 }
1857}
1858
1860{
1861 if ( ! mxFileDlg.is() )
1862 return;
1863
1864 // create the list of filters
1865 mpGraphicFilter.reset( new GraphicFilter );
1866 sal_uInt16 i, j, nCount = mpGraphicFilter->GetImportFormatCount();
1867
1868 // compute the extension string for all known import filters
1869 OUString aExtensions;
1870
1871 for ( i = 0; i < nCount; i++ )
1872 {
1873 j = 0;
1874 while( true )
1875 {
1876 OUString sWildcard = mpGraphicFilter->GetImportWildcard( i, j++ );
1877 if ( sWildcard.isEmpty() )
1878 break;
1879 if ( aExtensions.indexOf( sWildcard ) == -1 )
1880 {
1881 if ( !aExtensions.isEmpty() )
1882 aExtensions += ";";
1883 aExtensions += sWildcard;
1884 }
1885 }
1886 }
1887
1888#if defined(_WIN32)
1889 if ( aExtensions.getLength() > 240 )
1890 aExtensions = FILEDIALOG_FILTER_ALL;
1891#endif
1892 bool bIsInOpenMode = isInOpenMode();
1893
1894 try
1895 {
1896 // if the extension is not "All files", insert "All images"
1897 if (aExtensions != FILEDIALOG_FILTER_ALL)
1898 {
1899 OUString aAllFilterName = SfxResId(STR_SFX_IMPORT_ALL_IMAGES);
1900 aAllFilterName = ::sfx2::addExtension( aAllFilterName, aExtensions, bIsInOpenMode, *this );
1901 mxFileDlg->appendFilter( aAllFilterName, aExtensions );
1902 maSelectFilter = aAllFilterName; // and make it the default
1903 }
1904
1905 // rhbz#1715109 always include All files *.* or *
1906 OUString aAllFilesName = SfxResId( STR_SFX_FILTERNAME_ALL );
1907 aAllFilesName = ::sfx2::addExtension( aAllFilesName, FILEDIALOG_FILTER_ALL, bIsInOpenMode, *this );
1908 mxFileDlg->appendFilter( aAllFilesName, FILEDIALOG_FILTER_ALL );
1909
1910 // if the extension is "All files", make that the default
1911 if (aExtensions == FILEDIALOG_FILTER_ALL)
1912 maSelectFilter = aAllFilesName;
1913 }
1914 catch( const IllegalArgumentException& )
1915 {
1916 SAL_WARN( "sfx.dialog", "Could not append Filter" );
1917 }
1918
1919 // Now add the filter
1920 for ( i = 0; i < nCount; i++ )
1921 {
1922 OUString aName = mpGraphicFilter->GetImportFormatName( i );
1923 OUString aExt;
1924 j = 0;
1925 while( true )
1926 {
1927 OUString sWildcard = mpGraphicFilter->GetImportWildcard( i, j++ );
1928 if ( sWildcard.isEmpty() )
1929 break;
1930 if ( aExt.indexOf( sWildcard ) == -1 )
1931 {
1932 if ( !aExt.isEmpty() )
1933 aExt += ";";
1934 aExt += sWildcard;
1935 }
1936 }
1937 aName = ::sfx2::addExtension( aName, aExt, bIsInOpenMode, *this );
1938 try
1939 {
1940 mxFileDlg->appendFilter( aName, aExt );
1941 }
1942 catch( const IllegalArgumentException& )
1943 {
1944 SAL_WARN( "sfx.dialog", "Could not append Filter" );
1945 }
1946 }
1947}
1948
1949constexpr OUStringLiteral GRF_CONFIG_STR = u" ";
1950constexpr OUStringLiteral STD_CONFIG_STR = u"1 ";
1951
1952static void SetToken( OUString& rOrigStr, sal_Int32 nToken, sal_Unicode cTok, std::u16string_view rStr)
1953{
1954 const sal_Unicode* pStr = rOrigStr.getStr();
1955 sal_Int32 nLen = rOrigStr.getLength();
1956 sal_Int32 nTok = 0;
1957 sal_Int32 nFirstChar = 0;
1958 sal_Int32 i = nFirstChar;
1959
1960 // Determine token position and length
1961 pStr += i;
1962 while ( i < nLen )
1963 {
1964 // Increase token count if match
1965 if ( *pStr == cTok )
1966 {
1967 ++nTok;
1968
1969 if ( nTok == nToken )
1970 nFirstChar = i+1;
1971 else
1972 {
1973 if ( nTok > nToken )
1974 break;
1975 }
1976 }
1977
1978 ++pStr;
1979 ++i;
1980 }
1981
1982 if ( nTok >= nToken )
1983 rOrigStr = rOrigStr.replaceAt( nFirstChar, i-nFirstChar, rStr );
1984}
1985
1986namespace
1987{
1988void SaveLastDirectory(OUString const& sContext, OUString const& sDirectory)
1989{
1990 if (sContext.isEmpty())
1991 return;
1992
1993 std::shared_ptr<comphelper::ConfigurationChanges> batch(
1995 Reference<container::XNameContainer> set(
1996 officecfg::Office::Common::Misc::FilePickerLastDirectory::get(batch));
1997
1998 bool found;
1999 Any v;
2000 try
2001 {
2002 v = set->getByName(sContext);
2003 found = true;
2004 }
2005 catch (container::NoSuchElementException&)
2006 {
2007 found = false;
2008 }
2009 if (found)
2010 {
2011 Reference<XPropertySet> el(v.get<Reference<XPropertySet>>(), UNO_SET_THROW);
2012 el->setPropertyValue("LastPath", Any(sDirectory));
2013 }
2014 else
2015 {
2016 Reference<XPropertySet> el(
2017 (Reference<lang::XSingleServiceFactory>(set, UNO_QUERY_THROW)->createInstance()),
2018 UNO_QUERY_THROW);
2019 el->setPropertyValue("LastPath", Any(sDirectory));
2020 Any v2(el);
2021 set->insertByName(sContext, v2);
2022 }
2023 batch->commit();
2024}
2025}
2026
2028{
2029 uno::Reference < XFilePickerControlAccess > xDlg( mxFileDlg, UNO_QUERY );
2030 Any aValue;
2031
2032 if ( ! xDlg.is() )
2033 return;
2034
2035 if ( mbHasPreview )
2036 {
2037 SvtViewOptions aDlgOpt( EViewType::Dialog, IMPGRF_CONFIGNAME );
2038
2039 try
2040 {
2041 aValue = xDlg->getValue( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0 );
2042 bool bValue = false;
2043 aValue >>= bValue;
2044 OUString aUserData(GRF_CONFIG_STR);
2045 SetToken( aUserData, 1, ' ', OUString::number( static_cast<sal_Int32>(bValue) ) );
2046
2047 INetURLObject aObj( getPath() );
2048
2049 if ( aObj.GetProtocol() == INetProtocol::File )
2050 SetToken( aUserData, 2, ' ', aObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
2051
2052 OUString aFilter = getFilter();
2053 aFilter = EncodeSpaces_Impl( aFilter );
2054 SetToken( aUserData, 3, ' ', aFilter );
2055
2056 aDlgOpt.SetUserItem( USERITEM_NAME, Any( aUserData ) );
2057 }
2058 catch( const IllegalArgumentException& ){}
2059 }
2060 else
2061 {
2062 bool bWriteConfig = false;
2063 SvtViewOptions aDlgOpt( EViewType::Dialog, IODLG_CONFIGNAME );
2064 OUString aUserData(STD_CONFIG_STR);
2065
2066 if ( aDlgOpt.Exists() )
2067 {
2068 Any aUserItem = aDlgOpt.GetUserItem( USERITEM_NAME );
2069 OUString aTemp;
2070 if ( aUserItem >>= aTemp )
2071 aUserData = aTemp;
2072 }
2073
2074 if ( mbHasAutoExt )
2075 {
2076 try
2077 {
2078 aValue = xDlg->getValue( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, 0 );
2079 bool bAutoExt = true;
2080 aValue >>= bAutoExt;
2081 SetToken( aUserData, 0, ' ', OUString::number( static_cast<sal_Int32>(bAutoExt) ) );
2082 bWriteConfig = true;
2083 }
2084 catch( const IllegalArgumentException& ){}
2085 }
2086
2087 if ( ! mbIsSaveDlg )
2088 {
2089 OUString aPath = getPath();
2090 if ( comphelper::isFileUrl( aPath ) )
2091 {
2092 SetToken( aUserData, 1, ' ', aPath );
2093 bWriteConfig = true;
2094 }
2095 }
2096
2098 {
2099 try
2100 {
2101 aValue = xDlg->getValue( ExtendedFilePickerElementIds::CHECKBOX_SELECTION, 0 );
2102 bool bSelection = true;
2103 aValue >>= bSelection;
2104 if ( comphelper::string::getTokenCount(aUserData, ' ') < 3 )
2105 aUserData += " ";
2106 SetToken( aUserData, 2, ' ', OUString::number( static_cast<sal_Int32>(bSelection) ) );
2107 bWriteConfig = true;
2108 }
2109 catch( const IllegalArgumentException& ){}
2110 }
2111
2112 if ( bWriteConfig )
2113 aDlgOpt.SetUserItem( USERITEM_NAME, Any( aUserData ) );
2114 }
2115
2116 // Store to config, if explicit context is set. Otherwise store in (global) runtime var.
2118 {
2120 }
2121 else
2122 {
2123 SfxApplication *pSfxApp = SfxGetpApp();
2124 pSfxApp->SetLastDir_Impl( getPath() );
2125 }
2126}
2127
2128OUString FileDialogHelper_Impl::getInitPath(std::u16string_view _rFallback,
2129 const sal_Int32 _nFallbackToken)
2130{
2131 OUString sPath;
2132 // Load from config, if explicit context is set. Otherwise load from (global) runtime var.
2134 {
2135 OUString sContext = FileDialogHelper::contextToString(meContext);
2136 Reference<XNameAccess> set(officecfg::Office::Common::Misc::FilePickerLastDirectory::get());
2137 Any v;
2138 try
2139 {
2140 v = set->getByName(sContext);
2141 Reference<XPropertySet> el(v.get<Reference<XPropertySet>>(), UNO_SET_THROW);
2142 sPath = el->getPropertyValue("LastPath").get<OUString>();
2143 }
2144 catch (NoSuchElementException&)
2145 {
2146 }
2147 }
2148 else
2149 {
2150 SfxApplication *pSfxApp = SfxGetpApp();
2151 sPath = pSfxApp->GetLastDir_Impl();
2152 }
2153
2154 if ( sPath.isEmpty() )
2155 sPath = o3tl::getToken(_rFallback, _nFallbackToken, ' ' );
2156
2157 // check if the path points to a valid (accessible) directory
2158 bool bValid = false;
2159 if ( !sPath.isEmpty() )
2160 {
2161 OUString sPathCheck( sPath );
2162 if ( sPathCheck[ sPathCheck.getLength() - 1 ] != '/' )
2163 sPathCheck += "/";
2164 sPathCheck += ".";
2165 try
2166 {
2167 ::ucbhelper::Content aContent( sPathCheck,
2170 bValid = aContent.isFolder();
2171 }
2172 catch( const Exception& ) {}
2173 }
2174 if ( !bValid )
2175 sPath.clear();
2176 return sPath;
2177}
2178
2180{
2181 uno::Reference < XFilePickerControlAccess > xDlg( mxFileDlg, UNO_QUERY );
2182 Any aValue;
2183
2184 if ( ! xDlg.is() )
2185 return;
2186
2187 if ( mbHasPreview )
2188 {
2189 SvtViewOptions aViewOpt( EViewType::Dialog, IMPGRF_CONFIGNAME );
2190 OUString aUserData;
2191
2192 if ( aViewOpt.Exists() )
2193 {
2194 Any aUserItem = aViewOpt.GetUserItem( USERITEM_NAME );
2195 OUString aTemp;
2196 if ( aUserItem >>= aTemp )
2197 aUserData = aTemp;
2198 }
2199
2200 if ( !aUserData.isEmpty() )
2201 {
2202 try
2203 {
2204 // respect the last "insert as link" state
2205 bool bLink = o3tl::toInt32(o3tl::getToken(aUserData, 0, ' ' ));
2206 aValue <<= bLink;
2207 xDlg->setValue( ExtendedFilePickerElementIds::CHECKBOX_LINK, 0, aValue );
2208
2209 // respect the last "show preview" state
2210 bool bShowPreview = o3tl::toInt32(o3tl::getToken(aUserData, 1, ' ' ));
2211 aValue <<= bShowPreview;
2212 xDlg->setValue( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0, aValue );
2213
2214 if ( maPath.isEmpty() )
2215 displayFolder( getInitPath( aUserData, 2 ) );
2216
2217 if ( maCurFilter.isEmpty() )
2218 {
2219 OUString aFilter = aUserData.getToken( 3, ' ' );
2220 aFilter = DecodeSpaces_Impl( aFilter );
2221 setFilter( aFilter );
2222 }
2223
2224 // set the member so we know that we have to show the preview
2225 mbShowPreview = bShowPreview;
2226 }
2227 catch( const IllegalArgumentException& ){}
2228 }
2229
2230 if ( maPath.isEmpty() )
2231 displayFolder( SvtPathOptions().GetWorkPath() );
2232 }
2233 else
2234 {
2235 SvtViewOptions aViewOpt( EViewType::Dialog, IODLG_CONFIGNAME );
2236 OUString aUserData;
2237
2238 if ( aViewOpt.Exists() )
2239 {
2240 Any aUserItem = aViewOpt.GetUserItem( USERITEM_NAME );
2241 OUString aTemp;
2242 if ( aUserItem >>= aTemp )
2243 aUserData = aTemp;
2244 }
2245
2246 if ( aUserData.isEmpty() )
2247 aUserData = STD_CONFIG_STR;
2248
2249 if ( maPath.isEmpty() )
2250 displayFolder( getInitPath( aUserData, 1 ) );
2251
2252 if ( mbHasAutoExt )
2253 {
2254 sal_Int32 nFlag = o3tl::toInt32(o3tl::getToken(aUserData, 0, ' ' ));
2255 aValue <<= static_cast<bool>(nFlag);
2256 try
2257 {
2258 xDlg->setValue( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, 0, aValue );
2259 }
2260 catch( const IllegalArgumentException& ){}
2261 }
2262
2263 if( mbHasSelectionBox )
2264 {
2265 sal_Int32 nFlag = o3tl::toInt32(o3tl::getToken(aUserData, 2, ' ' ));
2266 aValue <<= static_cast<bool>(nFlag);
2267 try
2268 {
2269 xDlg->setValue( ExtendedFilePickerElementIds::CHECKBOX_SELECTION, 0, aValue );
2270 }
2271 catch( const IllegalArgumentException& ){}
2272 }
2273
2274 if ( maPath.isEmpty() )
2275 displayFolder( SvtPathOptions().GetWorkPath() );
2276 }
2277}
2278
2280{
2281 // when no filter is set, we set the currentFilter to <all>
2282 if ( maCurFilter.isEmpty() && !maSelectFilter.isEmpty() )
2283 {
2284 try
2285 {
2286 mxFileDlg->setCurrentFilter( maSelectFilter );
2287 }
2288 catch( const IllegalArgumentException& )
2289 {}
2290 }
2291
2292 // when no path is set, we use the standard 'work' folder
2293 if ( maPath.isEmpty() )
2294 {
2295 OUString aWorkFolder = SvtPathOptions().GetWorkPath();
2296 try
2297 {
2298 mxFileDlg->setDisplayDirectory( aWorkFolder );
2299 }
2300 catch( const Exception& )
2301 {
2302 TOOLS_WARN_EXCEPTION( "sfx.dialog", "FileDialogHelper_Impl::setDefaultValues: caught an exception while setting the display directory!" );
2303 }
2304 }
2305}
2306
2308{
2309 return !maFilters.empty();
2310}
2311
2312void FileDialogHelper_Impl::addFilterPair( const OUString& rFilter,
2313 const OUString& rFilterWithExtension )
2314{
2315 maFilters.emplace_back( rFilter, rFilterWithExtension );
2316
2317}
2318
2319OUString FileDialogHelper_Impl::getFilterName( std::u16string_view rFilterWithExtension ) const
2320{
2321 OUString sRet;
2322 for (auto const& filter : maFilters)
2323 {
2324 if (filter.Second == rFilterWithExtension)
2325 {
2326 sRet = filter.First;
2327 break;
2328 }
2329 }
2330 return sRet;
2331}
2332
2333OUString FileDialogHelper_Impl::getFilterWithExtension( std::u16string_view rFilter ) const
2334{
2335 OUString sRet;
2336 for (auto const& filter : maFilters)
2337 {
2338 if ( filter.First == rFilter )
2339 {
2340 sRet = filter.Second;
2341 break;
2342 }
2343 }
2344 return sRet;
2345}
2346
2348{
2349 meContext = _eNewContext;
2350
2351 std::optional<OUString> pConfigId = GetLastFilterConfigId( _eNewContext );
2352 if( pConfigId )
2353 LoadLastUsedFilter( *pConfigId );
2354}
2355
2356// FileDialogHelper
2357
2359 sal_Int16 nDialogType,
2360 FileDialogFlags nFlags,
2361 const OUString& rFact,
2362 SfxFilterFlags nMust,
2363 SfxFilterFlags nDont,
2364 weld::Window* pPreferredParent)
2365 : m_nError(0),
2366 mpImpl(new FileDialogHelper_Impl(this, nDialogType, nFlags, SFX2_IMPL_DIALOG_CONFIG, pPreferredParent))
2367{
2368
2369 // create the list of filters
2370 mpImpl->addFilters(
2371 SfxObjectShell::GetServiceNameFromFactory(rFact), nMust, nDont );
2372}
2373
2375 sal_Int16 nDialogType,
2376 FileDialogFlags nFlags,
2377 const OUString& rFact,
2378 sal_Int16 nDialog,
2379 SfxFilterFlags nMust,
2380 SfxFilterFlags nDont,
2381 const OUString& rStandardDir,
2382 const css::uno::Sequence< OUString >& rDenyList,
2383 weld::Window* pPreferredParent)
2384 : m_nError(0),
2385 mpImpl( new FileDialogHelper_Impl( this, nDialogType, nFlags, nDialog, pPreferredParent, rStandardDir, rDenyList ) )
2386{
2387 // create the list of filters
2388 mpImpl->addFilters(
2389 SfxObjectShell::GetServiceNameFromFactory(rFact), nMust, nDont );
2390}
2391
2392FileDialogHelper::FileDialogHelper(sal_Int16 nDialogType, FileDialogFlags nFlags, weld::Window* pPreferredParent)
2393 : m_nError(0),
2394 mpImpl( new FileDialogHelper_Impl( this, nDialogType, nFlags, SFX2_IMPL_DIALOG_CONFIG, pPreferredParent ) )
2395{
2396}
2397
2399 sal_Int16 nDialogType,
2400 FileDialogFlags nFlags,
2401 const OUString& aFilterUIName,
2402 std::u16string_view aExtName,
2403 const OUString& rStandardDir,
2404 const css::uno::Sequence< OUString >& rDenyList,
2405 weld::Window* pPreferredParent )
2406 : m_nError(0),
2407 mpImpl( new FileDialogHelper_Impl( this, nDialogType, nFlags, SFX2_IMPL_DIALOG_CONFIG, pPreferredParent, rStandardDir, rDenyList ) )
2408{
2409 // the wildcard here is expected in form "*.extension"
2410 OUString aWildcard;
2411 if ( aExtName.find( '*' ) != 0 )
2412 {
2413 if ( !aExtName.empty() && aExtName.find( '.' ) != 0 )
2414 aWildcard = "*.";
2415 else
2416 aWildcard = "*";
2417 }
2418
2419 aWildcard += aExtName;
2420
2421 OUString const aUIString = ::sfx2::addExtension(
2422 aFilterUIName, aWildcard, (OPEN == lcl_OpenOrSave(mpImpl->m_nDialogType)), *mpImpl);
2423 AddFilter( aUIString, aWildcard );
2424}
2425
2427{
2428 mpImpl->dispose();
2429}
2430
2431void FileDialogHelper::CreateMatcher( const OUString& rFactory )
2432{
2433 mpImpl->createMatcher( SfxObjectShell::GetServiceNameFromFactory(rFactory) );
2434}
2435
2436void FileDialogHelper::SetControlHelpIds( const sal_Int16* _pControlId, const char** _pHelpId )
2437{
2438 mpImpl->setControlHelpIds( _pControlId, _pHelpId );
2439}
2440
2442{
2443 mpImpl->SetContext( _eNewContext );
2444}
2445
2447{
2448 // These strings are used in the configuration, to store the last used directory for each context.
2449 // Please don't change them.
2450 switch(context) {
2451 case AcceleratorConfig:
2452 return "AcceleratorConfig";
2453 case AutoRedact:
2454 return "AutoRedact";
2455 case BaseDataSource:
2456 return "BaseDataSource";
2457 case BaseSaveAs:
2458 return "BaseSaveAs";
2459 case BasicExportDialog:
2460 return "BasicExportDialog";
2461 case BasicExportPackage:
2462 return "BasicExportPackage";
2463 case BasicExportSource:
2464 return "BasicExportSource";
2465 case BasicImportDialog:
2466 return "BasicImportDialog";
2467 case BasicImportSource:
2468 return "BasicImportSource";
2469 case BasicInsertLib:
2470 return "BasicInsertLib";
2471 case BulletsAddImage:
2472 return "BulletsAddImage";
2473 case CalcDataProvider:
2474 return "CalcDataProvider";
2475 case CalcDataStream:
2476 return "CalcDataStream";
2477 case CalcExport:
2478 return "CalcExport";
2479 case CalcSaveAs:
2480 return "CalcSaveAs";
2481 case CalcXMLSource:
2482 return "CalcXMLSource";
2483 case ExportImage:
2484 return "ExportImage";
2485 case ExtensionManager:
2486 return "ExtensionManager";
2487 case FormsAddInstance:
2488 return "FormsAddInstance";
2489 case FormsInsertImage:
2490 return "FormsInsertImage";
2491 case LinkClientOLE:
2492 return "LinkClientOLE";
2493 case LinkClientFile:
2494 return "LinkClientFile";
2496 return "DrawImpressInsertFile";
2498 return "DrawImpressOpenSound";
2499 case DrawExport:
2500 return "DrawExport";
2501 case DrawSaveAs:
2502 return "DrawSaveAs";
2503 case IconImport:
2504 return "IconImport";
2505 case ImpressClickAction:
2506 return "ImpressClickAction";
2507 case ImpressExport:
2508 return "ImpressExport";
2509 case ImpressPhotoDialog:
2510 return "ImpressPhotoDialog";
2511 case ImpressSaveAs:
2512 return "ImpressSaveAs";
2513 case ImageMap:
2514 return "ImageMap";
2515 case InsertDoc:
2516 return "InsertDoc";
2517 case InsertImage:
2518 return "InsertImage";
2519 case InsertOLE:
2520 return "InsertOLE";
2521 case InsertMedia:
2522 return "InsertMedia";
2523 case JavaClassPath:
2524 return "JavaClassPath";
2525 case ReportInsertImage:
2526 return "ReportInsertImage";
2528 return "ScreenshotAnnotation";
2529 case SignatureLine:
2530 return "SignatureLine";
2531 case TemplateImport:
2532 return "TemplateImport";
2534 return "WriterCreateAddressList";
2535 case WriterExport:
2536 return "WriterExport";
2538 return "WriterImportAutotext";
2540 return "WriterInsertHyperlink";
2541 case WriterInsertImage:
2542 return "WriterInsertImage";
2543 case WriterInsertScript:
2544 return "WriterInsertScript";
2545 case WriterLoadTemplate:
2546 return "WriterLoadTemplate";
2547 case WriterMailMerge:
2548 return "WriterMailMerge";
2550 return "WriterMailMergeSaveAs";
2552 return "WriterNewHTMLGlobalDoc";
2554 return "WriterRegisterDataSource";
2555 case WriterSaveAs:
2556 return "WriterSaveAs";
2557 case WriterSaveHTML:
2558 return "WriterSaveHTML";
2559 case XMLFilterSettings:
2560 return "XMLFilterSettings";
2561 case UnknownContext:
2562 default:
2563 return "";
2564 }
2565}
2566
2567IMPL_LINK_NOARG(FileDialogHelper, ExecuteSystemFilePicker, void*, void)
2568{
2569 m_nError = mpImpl->execute();
2570 m_aDialogClosedLink.Call( this );
2571}
2572
2573// rDirPath has to be a directory
2574ErrCode FileDialogHelper::Execute( std::vector<OUString>& rpURLList,
2575 std::optional<SfxAllItemSet>& rpSet,
2576 OUString& rFilter,
2577 const OUString& rDirPath )
2578{
2579 SetDisplayFolder( rDirPath );
2580 return mpImpl->execute( rpURLList, rpSet, rFilter );
2581}
2582
2583
2585{
2586 return mpImpl->execute();
2587}
2588
2589ErrCode FileDialogHelper::Execute( std::optional<SfxAllItemSet>& rpSet,
2590 OUString& rFilter )
2591{
2592 ErrCode nRet;
2593 std::vector<OUString> rURLList;
2594 nRet = mpImpl->execute(rURLList, rpSet, rFilter);
2595 return nRet;
2596}
2597
2599{
2600 m_aDialogClosedLink = rEndDialogHdl;
2602 if (!mpImpl->isAsyncFilePicker())
2603 Application::PostUserEvent( LINK( this, FileDialogHelper, ExecuteSystemFilePicker ) );
2604 else
2605 mpImpl->implStartExecute();
2606}
2607
2608sal_Int16 FileDialogHelper::GetDialogType() const { return mpImpl ? mpImpl->m_nDialogType : 0; }
2609
2611{
2612 return mpImpl && mpImpl->isPasswordEnabled();
2613}
2614
2616{
2617 OUString sFilter;
2618 if (mpImpl)
2619 mpImpl->getRealFilter( sFilter );
2620 return sFilter;
2621}
2622
2623void FileDialogHelper::SetTitle( const OUString& rNewTitle )
2624{
2625 if ( mpImpl->mxFileDlg.is() )
2626 mpImpl->mxFileDlg->setTitle( rNewTitle );
2627}
2628
2630{
2631 OUString aPath;
2632
2633 if ( !mpImpl->mlLastURLs.empty())
2634 return mpImpl->mlLastURLs[0];
2635
2636 if ( mpImpl->mxFileDlg.is() )
2637 {
2638 Sequence < OUString > aPathSeq = mpImpl->mxFileDlg->getFiles();
2639
2640 if ( aPathSeq.getLength() == 1 )
2641 {
2642 aPath = aPathSeq[0];
2643 }
2644 }
2645
2646 return aPath;
2647}
2648
2649Sequence < OUString > FileDialogHelper::GetMPath() const
2650{
2651 if ( !mpImpl->mlLastURLs.empty())
2652 return comphelper::containerToSequence(mpImpl->mlLastURLs);
2653
2654 if ( mpImpl->mxFileDlg.is() )
2655 return mpImpl->mxFileDlg->getFiles();
2656 else
2657 {
2658 Sequence < OUString > aEmpty;
2659 return aEmpty;
2660 }
2661}
2662
2663Sequence< OUString > FileDialogHelper::GetSelectedFiles() const
2664{
2665 // a) the new way (optional!)
2666 uno::Sequence< OUString > aResultSeq;
2667 if (mpImpl->mxFileDlg.is())
2668 {
2669 aResultSeq = mpImpl->mxFileDlg->getSelectedFiles();
2670 }
2671 // b) the olde way ... non optional.
2672 else
2673 {
2674 uno::Reference< XFilePicker > xPickOld(mpImpl->mxFileDlg, UNO_QUERY_THROW);
2675 Sequence< OUString > lFiles = xPickOld->getFiles();
2676 ::sal_Int32 nFiles = lFiles.getLength();
2677 if ( nFiles > 1 )
2678 {
2679 aResultSeq = Sequence< OUString >( nFiles-1 );
2680 auto pResultSeq = aResultSeq.getArray();
2681
2682 INetURLObject aPath( lFiles[0] );
2683 aPath.setFinalSlash();
2684
2685 for (::sal_Int32 i = 1; i < nFiles; i++)
2686 {
2687 if (i == 1)
2688 aPath.Append( lFiles[i] );
2689 else
2690 aPath.setName( lFiles[i] );
2691
2692 pResultSeq[i-1] = aPath.GetMainURL( INetURLObject::DecodeMechanism::NONE );
2693 }
2694 }
2695 else
2696 aResultSeq = lFiles;
2697 }
2698
2699 return aResultSeq;
2700}
2701
2703{
2704 return mpImpl->getPath();
2705}
2706
2708{
2709 return mpImpl->getFilter();
2710}
2711
2713{
2714 return mpImpl->getGraphic( rGraphic );
2715}
2716
2717static int impl_isFolder( const OUString& rPath )
2718{
2719 try
2720 {
2721 ::ucbhelper::Content aContent(
2722 rPath, uno::Reference< ucb::XCommandEnvironment > (),
2724 if ( aContent.isFolder() )
2725 return 1;
2726
2727 return 0;
2728 }
2729 catch ( const Exception & )
2730 {
2731 }
2732
2733 return -1;
2734}
2735
2736void FileDialogHelper::SetDisplayDirectory( const OUString& _rPath )
2737{
2738 if ( _rPath.isEmpty() )
2739 return;
2740
2741 // if the given path isn't a folder, we cut off the last part
2742 // and take it as filename and the rest of the path should be
2743 // the folder
2744
2745 INetURLObject aObj( _rPath );
2746
2748 aObj.removeSegment();
2749 OUString sPath = aObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
2750
2751 int nIsFolder = impl_isFolder( _rPath );
2752 if ( nIsFolder == 0 ||
2753 ( nIsFolder == -1 && impl_isFolder( sPath ) == 1 ) )
2754 {
2755 mpImpl->setFileName( sFileName );
2756 mpImpl->displayFolder( sPath );
2757 }
2758 else
2759 {
2760 INetURLObject aObjPathName( _rPath );
2761 OUString sFolder( aObjPathName.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
2762 if ( sFolder.isEmpty() )
2763 {
2764 // _rPath is not a valid path -> fallback to home directory
2765 osl::Security aSecurity;
2766 aSecurity.getHomeDir( sFolder );
2767 }
2768 mpImpl->displayFolder( sFolder );
2769 }
2770}
2771
2772void FileDialogHelper::SetDisplayFolder( const OUString& _rURL )
2773{
2774 mpImpl->displayFolder( _rURL );
2775}
2776
2777void FileDialogHelper::SetFileName( const OUString& _rFileName )
2778{
2779 mpImpl->setFileName( _rFileName );
2780}
2781
2782void FileDialogHelper::AddFilter( const OUString& rFilterName,
2783 const OUString& rExtension )
2784{
2785 mpImpl->addFilter( rFilterName, rExtension );
2786}
2787
2788void FileDialogHelper::SetCurrentFilter( const OUString& rFilter )
2789{
2790 OUString sFilter( rFilter );
2791 if ( mpImpl->isShowFilterExtensionEnabled() )
2792 sFilter = mpImpl->getFilterWithExtension( rFilter );
2793 mpImpl->setFilter( sFilter );
2794}
2795
2796const uno::Reference < XFilePicker3 >& FileDialogHelper::GetFilePicker() const
2797{
2798 return mpImpl->mxFileDlg;
2799}
2800
2801// XFilePickerListener Methods
2803{
2804 mpImpl->handleFileSelectionChanged();
2805}
2806
2808{
2809 mpImpl->handleDirectoryChanged();
2810}
2811
2812OUString FileDialogHelper::HelpRequested( const FilePickerEvent& aEvent )
2813{
2815}
2816
2817void FileDialogHelper::ControlStateChanged( const FilePickerEvent& aEvent )
2818{
2819 mpImpl->handleControlStateChanged( aEvent );
2820}
2821
2823{
2824 mpImpl->handleDialogSizeChanged();
2825}
2826
2827void FileDialogHelper::DialogClosed( const DialogClosedEvent& _rEvent )
2828{
2829 m_nError = ( RET_OK == _rEvent.DialogResult ) ? ERRCODE_NONE : ERRCODE_ABORT;
2830 m_aDialogClosedLink.Call( this );
2831}
2832
2834 sal_Int16 nDialogType,
2835 FileDialogFlags nFlags,
2836 std::vector<OUString>& rpURLList,
2837 OUString& rFilter,
2838 std::optional<SfxAllItemSet>& rpSet,
2839 const OUString* pPath,
2840 sal_Int16 nDialog,
2841 const OUString& rStandardDir,
2842 const css::uno::Sequence< OUString >& rDenyList )
2843{
2844 ErrCode nRet;
2845 std::unique_ptr<FileDialogHelper> pDialog;
2846 // Sign existing PDF: only works with PDF files and they are opened
2847 // read-only to discourage editing (which would invalidate existing
2848 // signatures).
2849 if (nFlags & FileDialogFlags::SignPDF)
2850 pDialog.reset(new FileDialogHelper(nDialogType, nFlags, SfxResId(STR_SFX_FILTERNAME_PDF), u"pdf", rStandardDir, rDenyList, pParent));
2851 else
2852 pDialog.reset(new FileDialogHelper(nDialogType, nFlags, OUString(), nDialog, SfxFilterFlags::NONE, SfxFilterFlags::NONE, rStandardDir, rDenyList, pParent));
2853
2854 OUString aPath;
2855 if ( pPath )
2856 aPath = *pPath;
2857
2858 nRet = pDialog->Execute(rpURLList, rpSet, rFilter, aPath);
2859 DBG_ASSERT( rFilter.indexOf(": ") == -1, "Old filter name used!");
2860
2861 if (rpSet && nFlags & FileDialogFlags::SignPDF)
2862 rpSet->Put(SfxBoolItem(SID_DOC_READONLY, true));
2863 return nRet;
2864}
2865
2866bool IsMSType(const std::shared_ptr<const SfxFilter>& pCurrentFilter)
2867{
2868 // TODO: need a save way to distinguish MS filters from other filters
2869 // for now MS-filters are the only alien filters that support encryption
2870 return !pCurrentFilter->IsOwnFormat();
2871}
2872
2873bool IsOOXML(const std::shared_ptr<const SfxFilter>& pCurrentFilter)
2874{
2875 // For OOXML we can use the standard password ("unlimited" characters)
2876 return IsMSType(pCurrentFilter) && lclSupportsOOXMLEncryption( pCurrentFilter->GetFilterName());
2877}
2878
2879ErrCode SetPassword(const std::shared_ptr<const SfxFilter>& pCurrentFilter, SfxItemSet* pSet,
2880 const OUString& rPasswordToOpen, std::u16string_view rPasswordToModify,
2881 bool bAllowPasswordReset)
2882{
2883 const bool bMSType = IsMSType(pCurrentFilter);
2884 const bool bOOXML = IsOOXML(pCurrentFilter);
2885
2886 if ( rPasswordToOpen.getLength() )
2887 {
2888 css::uno::Sequence< css::beans::NamedValue > aEncryptionData;
2889
2890 if ( bMSType )
2891 {
2892 if (bOOXML)
2893 {
2895 aHashData[ OUString( "OOXPassword" ) ] <<= rPasswordToOpen;
2896 aHashData[ OUString( "CryptoType" ) ] <<= OUString( "Standard" );
2897 aEncryptionData = aHashData.getAsConstNamedValueList();
2898 }
2899 else
2900 {
2901 uno::Sequence< sal_Int8 > aUniqueID = ::comphelper::DocPasswordHelper::GenerateRandomByteSequence( 16 );
2902 uno::Sequence< sal_Int8 > aEncryptionKey = ::comphelper::DocPasswordHelper::GenerateStd97Key( rPasswordToOpen, aUniqueID );
2903
2904 if ( aEncryptionKey.hasElements() )
2905 {
2907 aHashData[ OUString( "STD97EncryptionKey" ) ] <<= aEncryptionKey;
2908 aHashData[ OUString( "STD97UniqueID" ) ] <<= aUniqueID;
2909
2910 aEncryptionData = aHashData.getAsConstNamedValueList();
2911 }
2912 else
2913 {
2915 }
2916 }
2917 }
2918
2919 // tdf#118639: We need ODF encryption data for autorecovery where password will already
2920 // be unavailable, even for non-ODF documents, so append it here unconditionally
2921 pSet->Put(SfxUnoAnyItem(
2922 SID_ENCRYPTIONDATA,
2925 rPasswordToOpen)))));
2926 }
2927 else if (bAllowPasswordReset)
2928 {
2929 // Remove password
2930
2931 if (pSet->HasItem(SID_ENCRYPTIONDATA))
2932 pSet->ClearItem(SID_MODIFYPASSWORDINFO);
2933 if (pSet->HasItem(SID_ENCRYPTIONDATA))
2934 pSet->ClearItem(SID_ENCRYPTIONDATA);
2935
2936 return ERRCODE_NONE;
2937 }
2938
2939 if ( bMSType )
2940 {
2941 if (bOOXML)
2942 {
2943 uno::Sequence<beans::PropertyValue> aModifyPasswordInfo
2945 rPasswordToModify);
2946 if (aModifyPasswordInfo.hasElements() && pSet)
2947 pSet->Put(
2948 SfxUnoAnyItem(SID_MODIFYPASSWORDINFO, uno::Any(aModifyPasswordInfo)));
2949 }
2950 else
2951 {
2952 // the empty password has 0 as Hash
2953 sal_Int32 nHash = SfxMedium::CreatePasswordToModifyHash(
2954 rPasswordToModify,
2955 pCurrentFilter->GetServiceName() == "com.sun.star.text.TextDocument");
2956 if (nHash && pSet)
2957 pSet->Put(SfxUnoAnyItem(SID_MODIFYPASSWORDINFO, uno::Any(nHash)));
2958 }
2959 }
2960 else
2961 {
2962 uno::Sequence< beans::PropertyValue > aModifyPasswordInfo = ::comphelper::DocPasswordHelper::GenerateNewModifyPasswordInfo( rPasswordToModify );
2963 if ( aModifyPasswordInfo.hasElements() && pSet)
2964 pSet->Put( SfxUnoAnyItem( SID_MODIFYPASSWORDINFO, uno::Any( aModifyPasswordInfo ) ) );
2965 }
2966 return ERRCODE_NONE;
2967}
2968
2969
2970
2971ErrCode RequestPassword(const std::shared_ptr<const SfxFilter>& pCurrentFilter, OUString const & aURL, SfxItemSet* pSet, const css::uno::Reference<css::awt::XWindow>& rParent)
2972{
2973 uno::Reference<task::XInteractionHandler2> xInteractionHandler = task::InteractionHandler::createWithParent(::comphelper::getProcessComponentContext(), rParent);
2974 const auto eType = IsMSType(pCurrentFilter) && !IsOOXML(pCurrentFilter) ?
2975 ::comphelper::DocPasswordRequestType::MS :
2977
2978 ::rtl::Reference< ::comphelper::DocPasswordRequest > pPasswordRequest( new ::comphelper::DocPasswordRequest( eType, css::task::PasswordRequestMode_PASSWORD_CREATE, aURL, bool( pCurrentFilter->GetFilterFlags() & SfxFilterFlags::PASSWORDTOMODIFY ) ) );
2979
2980 const bool bMSType = IsMSType(pCurrentFilter);
2981
2982 uno::Reference< css::task::XInteractionRequest > rRequest( pPasswordRequest );
2983 do
2984 {
2985 xInteractionHandler->handle( rRequest );
2986 if (!pPasswordRequest->isPassword() || bMSType)
2987 {
2988 break;
2989 }
2990 OString const utf8Pwd(OUStringToOString(pPasswordRequest->getPassword(), RTL_TEXTENCODING_UTF8));
2991 OString const utf8Ptm(OUStringToOString(pPasswordRequest->getPasswordToModify(), RTL_TEXTENCODING_UTF8));
2992 if (!(52 <= utf8Pwd.getLength() && utf8Pwd.getLength() <= 55
2994 && (52 > utf8Ptm.getLength() || utf8Ptm.getLength() > 55))
2995 {
2996 break;
2997 }
2998 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(Application::GetFrameWeld(rParent), VclMessageType::Warning,
2999 VclButtonsType::Ok, SfxResId(STR_PASSWORD_LEN)));
3000 xBox->set_secondary_text(SfxResId(STR_PASSWORD_WARNING));
3001 xBox->run();
3002 }
3003 while (true);
3004 if ( !pPasswordRequest->isPassword() )
3005 return ERRCODE_ABORT;
3006
3007 const auto result = SetPassword(pCurrentFilter, pSet, pPasswordRequest->getPassword(), pPasswordRequest->getPasswordToModify());
3008
3009 if ( result != ERRCODE_IO_NOTSUPPORTED && pPasswordRequest->getRecommendReadOnly() )
3010 pSet->Put( SfxBoolItem( SID_RECOMMENDREADONLY, true ) );
3011
3012 return result;
3013}
3014
3015OUString EncodeSpaces_Impl( const OUString& rSource )
3016{
3017 OUString sRet = rSource.replaceAll( " ", "%20" );
3018 return sRet;
3019}
3020
3021OUString DecodeSpaces_Impl( const OUString& rSource )
3022{
3023 OUString sRet = rSource.replaceAll( "%20", " " );
3024 return sRet;
3025}
3026
3027} // end of namespace sfx2
3028
3029/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const short SAVE
const short OPEN
HRESULT createInstance(REFIID iid, Ifc **ppIfc)
SfxApplication * SfxGetpApp()
Definition: app.hxx:231
constexpr OUStringLiteral sStandardDir
Definition: appuno.cxx:142
AnyEventRef aEvent
const sal_uInt16 nVersion
Definition: childwin.cxx:43
static weld::Window * GetFrameWeld(const css::uno::Reference< css::awt::XWindow > &rWindow)
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
static void RemoveUserEvent(ImplSVEvent *nUserEvent)
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, const ILibreOfficeKitNotifier *pNotifier=nullptr)
static Help * GetHelp()
bool Scale(const Size &rNewSize, BmpScaleFlag nScaleFlag=BmpScaleFlag::Default)
bool Convert(BmpConversion eConversion)
bool IsEmpty() const
const Size & GetSizePixel() const
BitmapEx GetBitmapEx(const GraphicConversionParameters &rParameters=GraphicConversionParameters()) const
void Clear()
virtual OUString GetHelpText(const OUString &aHelpURL, const weld::Widget *pWidget)
OUString getName(sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true, DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
void SetSmartProtocol(INetProtocol eTheSmartScheme)
bool removeExtension(sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true)
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
bool HasError() const
bool removeSegment(sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true)
bool setFinalSlash()
bool SetSmartURL(std::u16string_view rTheAbsURIRef, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8, FSysStyle eStyle=FSysStyle::Detect)
OUString GetLastName(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
bool insertName(std::u16string_view rTheName, bool bAppendFinalSlash=false, sal_Int32 nIndex=LAST_SEGMENT, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
bool setName(std::u16string_view rTheName, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
INetProtocol GetProtocol() const
bool Append(std::u16string_view rTheSegment, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
virtual void Start(bool bStartTimer=true) override
SfxFilterMatcher & GetFilterMatcher()
Definition: appmain.cxx:27
SAL_DLLPRIVATE void SetLastDir_Impl(const OUString &)
Definition: app.cxx:204
SAL_DLLPRIVATE const OUString & GetLastDir_Impl() const
Definition: app.cxx:185
bool GetValue() const
std::shared_ptr< const SfxFilter > GetFilter4FilterName(const OUString &rName, SfxFilterFlags nMust=SfxFilterFlags::NONE, SfxFilterFlags nDont=SFX_FILTER_NOTINSTALLED) const
Definition: fltfnc.cxx:728
std::shared_ptr< const SfxFilter > GetFilter4UIName(std::u16string_view rName, SfxFilterFlags nMust=SfxFilterFlags::NONE, SfxFilterFlags nDont=SFX_FILTER_NOTINSTALLED) const
Definition: fltfnc.cxx:709
sal_uInt16 ClearItem(sal_uInt16 nWhich=0)
bool HasItem(sal_uInt16 nWhich, const SfxPoolItem **ppItem=nullptr) const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
static sal_uInt32 CreatePasswordToModifyHash(std::u16string_view aPasswd, bool bWriter)
Definition: docfile.cxx:3116
const css::uno::Sequence< css::util::RevisionTag > & GetVersionList(bool _bNoReload=false)
Definition: docfile.cxx:3687
static OUString GetServiceNameFromFactory(const OUString &rFact)
Definition: objxtor.cxx:921
SfxItemPool & GetPool() const
Each Subclass of SfxShell must reference a pool.
Definition: shell.hxx:511
const css::uno::Any & GetValue() const
Definition: frame.hxx:175
constexpr tools::Long Height() const
constexpr tools::Long Width() const
const OUString & GetWorkPath() const
css::uno::Any GetUserItem(const OUString &sName) const
void SetUserItem(const OUString &sName, const css::uno::Any &aValue)
bool Exists() const
void SetPriority(TaskPriority ePriority)
void SetInvokeHandler(const Link< Timer *, void > &rLink)
void ClearInvokeHandler()
static std::shared_ptr< ConfigurationChanges > create()
static css::uno::Sequence< sal_Int8 > GenerateRandomByteSequence(sal_Int32 nLength)
static css::uno::Sequence< css::beans::PropertyValue > GenerateNewModifyPasswordInfoOOXML(std::u16string_view aPassword)
static css::uno::Sequence< css::beans::PropertyValue > GenerateNewModifyPasswordInfo(std::u16string_view aPassword)
static css::uno::Sequence< sal_Int8 > GenerateStd97Key(std::u16string_view aPassword, const css::uno::Sequence< sal_Int8 > &aDocId)
static css::uno::Sequence< css::beans::NamedValue > CreateGpgPackageEncryptionData()
static css::uno::Sequence< css::beans::NamedValue > CreatePackageEncryptionData(std::u16string_view aPassword)
static css::uno::Reference< css::embed::XStorage > GetStorageFromURL(const OUString &aURL, sal_Int32 nStorageMode, const css::uno::Reference< css::uno::XComponentContext > &rxContext=css::uno::Reference< css::uno::XComponentContext >())
css::uno::Sequence< css::beans::NamedValue > getAsConstNamedValueList() const
virtual void SAL_CALL dialogSizeChanged() override
virtual void SAL_CALL controlStateChanged(const css::ui::dialogs::FilePickerEvent &aEvent) override
void createMatcher(const OUString &rFactory)
void updatePreviewState(bool _bUpdatePreviewWindow)
css::uno::Reference< css::awt::XWindow > GetFrameInterface()
OUString getFilterWithExtension(std::u16string_view rFilter) const
void displayFolder(const OUString &rPath)
sets the directory which should be browsed
FileDialogHelper::Context meContext
Definition: filedlgimpl.hxx:75
std::unique_ptr< GraphicFilter > mpGraphicFilter
Definition: filedlgimpl.hxx:53
virtual void SAL_CALL directoryChanged(const css::ui::dialogs::FilePickerEvent &aEvent) override
bool isShowFilterExtensionEnabled() const
void addFilterPair(const OUString &rFilter, const OUString &rFilterWithExtension)
ErrCode getGraphic(const OUString &rURL, Graphic &rGraphic) const
void getRealFilter(OUString &_rFilter) const
::std::vector< OUString > mlLastURLs
Definition: filedlgimpl.hxx:57
void setFileName(const OUString &_rFile)
void SetContext(FileDialogHelper::Context _eNewContext)
void addFilters(const OUString &rFactory, SfxFilterFlags nMust, SfxFilterFlags nDont)
void addFilter(const OUString &rFilterName, const OUString &rExtension)
OUString getCurrentFilterUIName() const
void setControlHelpIds(const sal_Int16 *_pControlId, const char **_pHelpId)
void implGetAndCacheFiles(const css::uno::Reference< XInterface > &xPicker, std::vector< OUString > &rpURLList)
OUString getInitPath(std::u16string_view _rFallback, const sal_Int32 _nFallbackToken)
css::uno::Reference< css::container::XNameAccess > mxFilterCFG
Definition: filedlgimpl.hxx:48
virtual void SAL_CALL dialogClosed(const css::ui::dialogs::DialogClosedEvent &_rEvent) override
virtual void SAL_CALL disposing(const css::lang::EventObject &Source) override
void LoadLastUsedFilter(const OUString &_rContextIdentifier)
void handleControlStateChanged(const css::ui::dialogs::FilePickerEvent &aEvent)
SfxFilterMatcher * mpMatcher
Definition: filedlgimpl.hxx:52
std::vector< css::beans::StringPair > maFilters
Definition: filedlgimpl.hxx:50
bool updateExtendedControl(sal_Int16 _nExtendedControlId, bool _bEnable)
FileDialogHelper_Impl(FileDialogHelper *_pAntiImpl, const sal_Int16 nDialogType, FileDialogFlags nFlags, sal_Int16 nDialog, weld::Window *pFrameWeld, const OUString &sStandardDir=OUString(), const css::uno::Sequence< OUString > &rDenyList=css::uno::Sequence< OUString >())
css::uno::Reference< css::ui::dialogs::XFilePicker3 > mxFileDlg
Definition: filedlgimpl.hxx:47
void postExecute(sal_Int16 _nResult)
virtual void SAL_CALL fileSelectionChanged(const css::ui::dialogs::FilePickerEvent &aEvent) override
FileDialogHelper * mpAntiImpl
Definition: filedlgimpl.hxx:54
virtual OUString SAL_CALL helpRequested(const css::ui::dialogs::FilePickerEvent &aEvent) override
void enablePasswordBox(bool bInit)
OUString getFilterName(std::u16string_view rFilterWithExtension) const
ImplSVEvent * mnPostUserEventId
Definition: filedlgimpl.hxx:73
virtual ~FileDialogHelper_Impl() override
std::shared_ptr< const SfxFilter > getCurrentSfxFilter()
bool CheckFilterOptionsCapability(const std::shared_ptr< const SfxFilter > &_pFilter)
static OUString handleHelpRequested(const css::ui::dialogs::FilePickerEvent &aEvent)
void setFilter(const OUString &rFilter)
OUString GetPath() const
void SetControlHelpIds(const sal_Int16 *_pControlId, const char **_pHelpId)
sets help ids for the controls in the dialog
void AddFilter(const OUString &rFilterName, const OUString &rExtension)
void StartExecuteModal(const Link< FileDialogHelper *, void > &rEndDialogHdl)
void SetDisplayDirectory(const OUString &rPath)
sets an initial display directory/file name
sal_Int16 GetDialogType() const
void CreateMatcher(const OUString &rName)
const css::uno::Reference< css::ui::dialogs::XFilePicker3 > & GetFilePicker() const
OUString GetRealFilter() const
void DialogClosed(const css::ui::dialogs::DialogClosedEvent &_rEvent)
static OUString HelpRequested(const css::ui::dialogs::FilePickerEvent &aEvent)
bool IsPasswordEnabled() const
rtl::Reference< FileDialogHelper_Impl > mpImpl
static OUString contextToString(Context context)
void SetDisplayFolder(const OUString &_rURL)
sets a new folder whose content is to be displayed in the file picker
void SetTitle(const OUString &rNewTitle)
css::uno::Sequence< OUString > GetSelectedFiles() const
Provides the selected files with full path information.
OUString GetCurrentFilter() const
css::uno::Sequence< OUString > GetMPath() const
void SetFileName(const OUString &_rFileName)
sets an initial file name to display
virtual void ControlStateChanged(const css::ui::dialogs::FilePickerEvent &aEvent)
void SetCurrentFilter(const OUString &rFilter)
void SetContext(Context _eNewContext)
sets the context of the dialog and trigger necessary actions e.g.
ErrCode GetGraphic(Graphic &rGraphic) const
Link< FileDialogHelper *, void > m_aDialogClosedLink
FileDialogHelper(sal_Int16 nDialogType, FileDialogFlags nFlags, weld::Window *pPreferredParent)
OUString GetDisplayDirectory() const
static std::unique_ptr< SvStream > CreateStream(const OUString &rFileName, StreamMode eOpenMode, css::uno::Reference< css::awt::XWindow > xParentWin=nullptr)
virtual css::uno::Reference< css::awt::XWindow > GetXWindow()=0
int nCount
#define DBG_ASSERT(sCon, aError)
#define TOOLS_WARN_EXCEPTION(area, stream)
bool VCL_DLLPUBLIC WriteDIB(const Bitmap &rSource, SvStream &rOStm, bool bCompressed, bool bFileHeader)
URL aURL
SfxFilterFlags
#define SFX_FILTER_NOTINSTALLED
float v
float u
ScXMLEditAttributeMap::Entry const aEntries[]
UNDEFINED
#define ERRCODE_IO_GENERAL
#define ERRCODE_ABORT
#define ERRCODE_IO_NOTSUPPORTED
#define ERRCODE_NONE
#define ERRCODE_IO_NOTAFILE
Reference< XSingleServiceFactory > xFactory
constexpr OUStringLiteral IMPGRF_CONFIGNAME
constexpr OUStringLiteral USERITEM_NAME
constexpr OUStringLiteral IODLG_CONFIGNAME
#define SFX2_IMPL_DIALOG_CONFIG
constexpr OUStringLiteral FILEDIALOG_FILTER_ALL
#define SFX2_IMPL_DIALOG_SYSTEM
FileDialogFlags
@ InsertMerge
Special insertion ("Compare" caption)
@ SignPDF
Sign existing PDF.
#define SFX2_IMPL_DIALOG_OOO
#define SFX2_IMPL_DIALOG_REMOTE
OUString aWildcard
DocumentType eType
bool bReadOnly
#define GRFILTER_FORMAT_DONTKNOW
GraphicFilterImportFlags
const Graphic maGraphic
constexpr OUStringLiteral HID_FILEOPEN_IMAGE_ANCHOR
constexpr OUStringLiteral HID_FILEDLG_PREVIEW_CB
constexpr OUStringLiteral HID_FILESAVE_TEMPLATE
constexpr OUStringLiteral HID_FILESAVE_AUTOEXTENSION
constexpr OUStringLiteral HID_FILEOPEN_READONLY
constexpr OUStringLiteral HID_FILESAVE_SELECTION
constexpr OUStringLiteral HID_FILEDLG_LINK_CB
constexpr OUStringLiteral HID_FILESAVE_CUSTOMIZEFILTER
constexpr OUStringLiteral HID_FILEOPEN_VERSION
constexpr OUStringLiteral HID_FILEOPEN_IMAGE_TEMPLATE
constexpr OUStringLiteral HID_FILESAVE_SAVEWITHPASSWORD
constexpr OUStringLiteral HID_FILESAVE_DOPLAY
sal_Int32 nIndex
OUString aName
DdeData aData
Definition: lnkbase2.cxx:82
#define SAL_WARN(area, stream)
#define MNEMONIC_CHAR
bool IsOptionSet(EOption eOption)
void set(css::uno::UnoInterfaceReference const &value)
@ Exception
sal_Int32 getTokenCount(std::string_view rIn, char cTok)
COMPHELPER_DLLPUBLIC bool isFileUrl(std::u16string_view url)
sal_Int32 findValue(const css::uno::Sequence< T1 > &_rList, const T2 &_rValue)
css::uno::Sequence< T > concatSequences(const css::uno::Sequence< T > &rS1, const Ss &... rSn)
DstType sequenceToContainer(const css::uno::Sequence< SrcType > &i_Sequence)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
Reference< XComponentContext > getProcessComponentContext()
int i
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
IMPL_LINK_NOARG(SvDDELinkEditDialog, EditHdl_Impl, weld::Entry &, void)
Definition: impldde.cxx:91
OUString addExtension(const OUString &_rDisplayText, const OUString &_rExtension, bool _bForOpen, FileDialogHelper_Impl &_rFileDlgImpl)
adds the given extension to the display text.
static open_or_save_t lcl_OpenOrSave(sal_Int16 const nDialogType)
bool IsMSType(const std::shared_ptr< const SfxFilter > &pCurrentFilter)
static bool lcl_isSystemFilePicker(const uno::Reference< XExecutableDialog > &_rxFP)
css::uno::Reference< css::ui::dialogs::XFolderPicker2 > createFolderPicker(const css::uno::Reference< css::uno::XComponentContext > &rContext, weld::Window *pPreferredParent)
void appendFiltersForOpen(TSortedFilterList &_rFilterMatcher, const Reference< XFilterManager > &_rxFilterManager, OUString &_rFirstNonEmpty, FileDialogHelper_Impl &_rFileDlgImpl)
static std::optional< OUString > GetLastFilterConfigId(FileDialogHelper::Context _eContext)
static OUString EncodeSpaces_Impl(const OUString &rSource)
static void SetToken(OUString &rOrigStr, sal_Int32 nToken, sal_Unicode cTok, std::u16string_view rStr)
static int impl_isFolder(const OUString &rPath)
constexpr OUStringLiteral GRF_CONFIG_STR
bool IsOOXML(const std::shared_ptr< const SfxFilter > &pCurrentFilter)
void appendExportFilters(TSortedFilterList &_rFilterMatcher, const Reference< XFilterManager > &_rxFilterManager, OUString &_rFirstNonEmpty, FileDialogHelper_Impl &_rFileDlgImpl)
ErrCode SetPassword(const std::shared_ptr< const SfxFilter > &pCurrentFilter, SfxItemSet *pSet, const OUString &rPasswordToOpen, std::u16string_view rPasswordToModify, bool bAllowPasswordReset)
ErrCode RequestPassword(const std::shared_ptr< const SfxFilter > &pCurrentFilter, OUString const &aURL, SfxItemSet *pSet, const css::uno::Reference< css::awt::XWindow > &rParent)
constexpr OUStringLiteral STD_CONFIG_STR
static OUString DecodeSpaces_Impl(const OUString &rSource)
ErrCode FileOpenDialog_Impl(weld::Window *pParent, sal_Int16 nDialogType, FileDialogFlags nFlags, std::vector< OUString > &rpURLList, OUString &rFilter, std::optional< SfxAllItemSet > &rpSet, const OUString *pPath, sal_Int16 nDialog, const OUString &rStandardDir, const css::uno::Sequence< OUString > &rDenyList)
void appendFiltersForSave(TSortedFilterList &_rFilterMatcher, const Reference< XFilterManager > &_rxFilterManager, OUString &_rFirstNonEmpty, FileDialogHelper_Impl &_rFileDlgImpl, std::u16string_view _rFactory)
UNOTOOLS_DLLPUBLIC bool IsDocument(OUString const &url)
UNOTOOLS_DLLPUBLIC css::uno::Reference< css::ucb::XCommandEnvironment > getDefaultCommandEnvironment()
UNOTOOLS_DLLPUBLIC bool IsFolder(OUString const &url)
DefTokenId nToken
UNOTOOLS_DLLPUBLIC SvtSaveOptions::ODFSaneDefaultVersion GetODFSaneDefaultVersion()
OUString SfxResId(TranslateId aId)
Definition: sfxresid.cxx:22
bool bIsEnabled
sal_uInt16 sal_Unicode
signed char sal_Int8
Any result
OUString sId
constexpr OUStringLiteral INET_HID_SCHEME
RET_OK
std::unique_ptr< char[]> aBuffer