24#include <sfx2/strings.hrc>
28#include <com/sun/star/ui/dialogs/XFilterGroupManager.hpp>
29#include <com/sun/star/beans/StringPair.hpp>
30#include <com/sun/star/uno/Sequence.hxx>
54 using namespace ::
utl;
154 static void lcl_ReadFilterClass(
const OConfigurationNode& _rClassesNode,
const OUString& _rLogicalClassName,
155 FilterClass& _rClass )
158 OConfigurationNode aClassDesc = _rClassesNode.openNode( _rLogicalClassName );
161 aClassDesc.getNodeValue(
"DisplayName" ) >>= _rClass.sDisplayName;
162 aClassDesc.getNodeValue(
"Filters" ) >>= _rClass.aSubFilters;
167 struct CreateEmptyClassRememberPos
181 void operator() (
const FilterName& _rLogicalFilterName )
186 FilterClassList::iterator aInsertPos =
m_rClassList.end();
194 struct ReadGlobalFilter
201 ReadGlobalFilter( OConfigurationNode _aClassesNode,
FilterClassReferrer& _rClassesReferrer )
214 OSL_FAIL(
"ReadGlobalFilter::operator(): unknown filter name!" );
230 _rGlobalClasses.clear();
231 _rGlobalClassNames.clear();
234 Sequence< OUString > aGlobalClasses;
235 _rFilterClassification.getNodeValue(
"GlobalFilters/Order" ) >>= aGlobalClasses;
246 std::cbegin(aGlobalClasses),
247 std::cend(aGlobalClasses),
248 CreateEmptyClassRememberPos( _rGlobalClasses, aClassReferrer )
256 OConfigurationNode aFilterClassesNode =
257 _rFilterClassification.openNode(
"GlobalFilters/Classes" );
258 const Sequence< OUString > aFilterClasses = aFilterClassesNode.getNodeNames();
260 aFilterClasses.begin(),
261 aFilterClasses.end(),
262 ReadGlobalFilter( aFilterClassesNode, aClassReferrer )
268 struct ReadLocalFilter
275 ReadLocalFilter( OConfigurationNode _aClassesNode,
FilterClassList& _rClasses )
297 _rLocalClasses.clear();
300 OConfigurationNode aFilterClassesNode =
301 _rFilterClassification.openNode(
"LocalFilters/Classes" );
302 const Sequence< OUString > aFilterClasses = aFilterClassesNode.getNodeNames();
305 aFilterClasses.begin(),
306 aFilterClasses.end(),
307 ReadLocalFilter( aFilterClassesNode, _rLocalClasses )
316 OConfigurationTreeRoot aFilterClassification = OConfigurationTreeRoot::createWithComponentContext(
317 ::comphelper::getProcessComponentContext(),
318 "org.openoffice.Office.UI/FilterClassification",
320 OConfigurationTreeRoot::CM_READONLY
339 struct ReferToFilterEntry
355 ::std::pair< FilterGroupEntryReferrer::iterator, bool > aInsertRes =
358 !aInsertRes.second,
"sfx.dialog",
359 "already have an element for " << _rName);
364 struct FillClassGroup
378 void operator() (
const FilterClass& _rClass )
383 aClassEntry.First = _rClass.sDisplayName;
394 _rClass.aSubFilters.begin(),
395 _rClass.aSubFilters.end(),
412 struct CheckAppendSingleWildcard
416 explicit CheckAppendSingleWildcard( OUString& _rBase ) :
_rToBeExtended( _rBase ) { }
418 void operator() ( std::u16string_view _rWC )
422 if ( -1 < nExistentPos )
424 if ( ( 0 == nExistentPos )
428 sal_Int32 nExistentWCEnd = nExistentPos + _rWC.size();
448 struct AppendWildcardToDescriptor
454 explicit AppendWildcardToDescriptor(
const OUString& _rWildCard );
457 void operator() (
const FilterGroupEntryReferrer::value_type& _rClassReference )
463 CheckAppendSingleWildcard( _rClassReference.second->Second )
470 AppendWildcardToDescriptor::AppendWildcardToDescriptor(
const OUString& _rWildCard )
473 "AppendWildcardToDescriptor::AppendWildcardToDescriptor: invalid wildcard!" );
475 "AppendWildcardToDescriptor::AppendWildcardToDescriptor: wildcard already separated!" );
479 const sal_Unicode* pTokenLoop = _rWildCard.getStr();
480 const sal_Unicode* pTokenLoopEnd = pTokenLoop + _rWildCard.getLength();
482 for ( ; pTokenLoop != pTokenLoopEnd; ++pTokenLoop )
486 aWildCards.emplace_back( pTokenStart, pTokenLoop - pTokenStart );
492 if ( pTokenStart == pTokenLoopEnd )
497 pTokenLoop = pTokenStart;
500 if ( pTokenLoop > pTokenStart )
502 aWildCards.emplace_back( pTokenStart, pTokenLoop - pTokenStart );
510 FilterGroup& rGlobalFilters = _rAllFilters.front();
517 _rGlobalClasses.begin(),
518 _rGlobalClasses.end(),
519 FillClassGroup( rGlobalFilters, _rGlobalClassesRef )
529 typedef ::std::vector< ::std::pair< FilterGroupEntryReferrer::mapped_type, FilterGroup::iterator > >
535 struct FindGroupEntry
538 explicit FindGroupEntry( FilterGroupEntryReferrer::mapped_type _aLookingFor ) :
aLookingFor(
std::move( _aLookingFor )) { }
540 bool operator() (
const MapGroupEntry2GroupEntry::value_type& _rMapEntry )
546 struct CopyGroupEntryContent
548 void operator() (
const MapGroupEntry2GroupEntry::value_type& _rMapEntry )
550 *_rMapEntry.second = *_rMapEntry.first;
555 struct CopyNonEmptyFilter
562 if ( !_rFilter.Second.isEmpty() )
571 _rAllFilters.clear();
576 std::vector<OUString> aGlobalClassNames;
586 sal_Int32 nGlobalClasses = aGlobalClasses.size();
587 while ( nGlobalClasses-- )
588 _rAllFilters.emplace_back( );
598 aLocalClasses.begin(),
600 FillClassGroup( aCollectedLocals, aLocalClassesRef )
609 GroupedFilterList::iterator aCurrentGroup = _rAllFilters.end();
611 OUString aCurrentServiceName;
613 OUString sFilterWildcard;
614 OUString sFilterName;
616 for ( std::shared_ptr<const SfxFilter> pFilter = _rFilterMatcher.
First(); pFilter; pFilter = _rFilterMatcher.
Next() )
618 sFilterName = pFilter->GetFilterName();
619 sFilterWildcard = pFilter->GetWildcard().getGlob();
620 AppendWildcardToDescriptor aExtendWildcard( sFilterWildcard );
622 DBG_ASSERT( !sFilterWildcard.isEmpty(),
"sfx2::lcl_GroupAndClassify: invalid wildcard of this filter!" );
626 OUString aServiceName = pFilter->GetServiceName();
627 if ( aServiceName != aCurrentServiceName )
632 GroupedFilterList::iterator aGroupPos = _rAllFilters.begin();
634 "sfx2::lcl_GroupAndClassify: invalid all-filters array here!" );
637 auto aGlobalIter = std::find(aGlobalClassNames.begin(), aGlobalClassNames.end(), aServiceName);
638 auto nGroupPosShift = std::min(
639 std::distance(aGlobalClassNames.begin(), aGlobalIter),
640 std::distance(aGroupPos, _rAllFilters.end()));
641 std::advance(aGroupPos, nGroupPosShift);
642 if ( aGroupPos != _rAllFilters.end() )
645 aCurrentGroup = aGroupPos;
648 aCurrentGroup = _rAllFilters.insert( _rAllFilters.end(),
FilterGroup() );
651 aCurrentServiceName = aServiceName;
654 assert(aCurrentGroup != _rAllFilters.end());
655 if (aCurrentGroup == _rAllFilters.end())
656 aCurrentGroup = _rAllFilters.begin();
660 ::std::pair< FilterGroupEntryReferrer::iterator, FilterGroupEntryReferrer::iterator >
661 aBelongsTo = aGlobalClassesRef.equal_range( sFilterName );
674 FilterGroupEntryReferrer::iterator aBelongsToLocal = aLocalClassesRef.find( sFilterName );
675 if ( aLocalClassesRef.end() != aBelongsToLocal )
679 aExtendWildcard( *aBelongsToLocal );
681 if ( std::none_of( aLocalFinalPositions.begin(), aLocalFinalPositions.end(), FindGroupEntry( aBelongsToLocal->second ) ) )
686 aCurrentGroup->push_back(
FilterDescriptor( aBelongsToLocal->second->First, OUString() ) );
688 FilterGroup::iterator aInsertPos = aCurrentGroup->end();
691 aLocalFinalPositions.emplace_back( aBelongsToLocal->second, aInsertPos );
695 aCurrentGroup->push_back(
FilterDescriptor( pFilter->GetUIName(), sFilterWildcard ) );
702 aLocalFinalPositions.begin(),
703 aLocalFinalPositions.end(),
704 CopyGroupEntryContent()
710 FilterGroup& rGlobalFilters = _rAllFilters.front();
713 rGlobalFilters.begin(),
714 rGlobalFilters.end(),
715 CopyNonEmptyFilter( aNonEmptyGlobalFilters )
717 rGlobalFilters.swap( aNonEmptyGlobalFilters );
730 AppendFilter(
const Reference< XFilterManager >& _rxFilterManager,
731 FileDialogHelper_Impl* _pImpl,
bool _bAddExtension ) :
747 : _rFilterEntry.
First;
759 bool bHasAll =
false;
760 _rAllFilterName =
SfxResId( STR_SFX_FILTERNAME_ALL );
764 for ( std::shared_ptr<const SfxFilter> pFilter = _rFilterMatcher.
First(); pFilter && !bHasAll; pFilter = _rFilterMatcher.
Next() )
766 if ( pFilter->GetUIName() == _rAllFilterName )
776 OUString sAllFilterName;
780 DBG_ASSERT( !_rFilters.empty(),
"lcl_EnsureAllFilesEntry: invalid filter list!" );
781 if ( !_rFilters.empty() )
794 struct AppendFilterGroup
802 AppendFilterGroup(
const Reference< XFilterManager >& _rxFilterManager, FileDialogHelper_Impl* _pImpl )
811 void appendGroup(
const FilterGroup& _rGroup,
bool _bAddExtension )
818 if ( !_rGroup.empty() )
821 if ( _bAddExtension )
837 catch(
const Exception& )
846 appendGroup( _rGroup,
true );
855 if (!xFilterList.is())
859 while(xFilterList->hasMoreElements())
865 if (!sFilterName.isEmpty())
890 if (sFilterName.isEmpty())
897 const Reference< XFilterManager >& _rxFilterManager,
899 std::u16string_view _rFactory )
901 DBG_ASSERT( _rxFilterManager.is(),
"sfx2::appendFiltersForSave: invalid manager!" );
902 if ( !_rxFilterManager.is() )
913 sExtension = pDefaultFilter->GetWildcard().getGlob().getToken(0,
';');
914 sUIName =
addExtension( pDefaultFilter->GetUIName(), sExtension,
false, _rFileDlgImpl );
917 _rxFilterManager->appendFilter( sUIName, sExtension );
918 if ( _rFirstNonEmpty.isEmpty() )
919 _rFirstNonEmpty = sUIName;
921 catch(
const IllegalArgumentException& )
923 SAL_WARN(
"sfx.dialog",
"Could not append DefaultFilter" << sUIName );
926 for ( std::shared_ptr<const SfxFilter> pFilter = _rFilterMatcher.
First(); pFilter; pFilter = _rFilterMatcher.
Next() )
928 if (pFilter->GetName() == pDefaultFilter->GetName())
933 sExtension = pFilter->GetWildcard().getGlob().getToken(0,
';');
934 sUIName =
addExtension( pFilter->GetUIName(), sExtension,
false, _rFileDlgImpl );
937 _rxFilterManager->appendFilter( sUIName, sExtension );
938 if ( _rFirstNonEmpty.isEmpty() )
939 _rFirstNonEmpty = sUIName;
941 catch(
const IllegalArgumentException& )
943 SAL_WARN(
"sfx.dialog",
"Could not append Filter" << sUIName );
952 ExportFilter( OUString _aUIName, OUString _aWildcard ) :
962 const Reference< XFilterManager >& _rxFilterManager,
965 DBG_ASSERT( _rxFilterManager.is(),
"sfx2::appendExportFilters: invalid manager!" );
966 if ( !_rxFilterManager.is() )
969 sal_Int32 nHTMLIndex = -1;
970 sal_Int32 nXHTMLIndex = -1;
971 sal_Int32 nPDFIndex = -1;
973 OUString sExtensions;
974 std::vector< ExportFilter > aImportantFilterGroup;
975 std::vector< ExportFilter > aFilterGroup;
976 Reference< XFilterGroupManager > xFilterGroupManager( _rxFilterManager, UNO_QUERY );
979 for ( std::shared_ptr<const SfxFilter> pFilter = _rFilterMatcher.
First(); pFilter; pFilter = _rFilterMatcher.
Next() )
981 sTypeName = pFilter->GetTypeName();
982 sUIName = pFilter->GetUIName();
983 sExtensions = pFilter->GetWildcard().getGlob();
984 ExportFilter aExportFilter( sUIName, sExtensions );
986 if ( nHTMLIndex == -1 &&
987 ( sTypeName ==
"generic_HTML" || sTypeName ==
"graphic_HTML" ) )
989 aImportantFilterGroup.insert( aImportantFilterGroup.begin(), aExportFilter );
992 else if ( nXHTMLIndex == -1 && sTypeName ==
"XHTML_File" )
994 std::vector< ExportFilter >::iterator aIter = aImportantFilterGroup.begin();
995 if ( nHTMLIndex == -1 )
996 aImportantFilterGroup.insert( aIter, aExportFilter );
998 aImportantFilterGroup.insert( ++aIter, aExportFilter );
1001 else if ( nPDFIndex == -1 && sTypeName ==
"pdf_Portable_Document_Format" )
1003 std::vector< ExportFilter >::iterator aIter = aImportantFilterGroup.begin();
1004 if ( nHTMLIndex != -1 )
1006 if ( nXHTMLIndex != -1 )
1008 aImportantFilterGroup.insert( aIter, aExportFilter );
1012 aFilterGroup.push_back( aExportFilter );
1015 if ( xFilterGroupManager.is() )
1018 if ( !aImportantFilterGroup.empty() )
1020 Sequence< StringPair > aFilters( aImportantFilterGroup.size() );
1021 auto pFilters = aFilters.getArray();
1022 for ( sal_Int32
i = 0; i < static_cast<sal_Int32>(aImportantFilterGroup.size());
i++ )
1026 false, _rFileDlgImpl );
1027 pFilters[
i].Second = aImportantFilterGroup[
i].aWildcard;
1032 xFilterGroupManager->appendFilterGroup( OUString(), aFilters );
1034 catch(
const IllegalArgumentException& )
1039 if ( !aFilterGroup.empty() )
1041 Sequence< StringPair > aFilters( aFilterGroup.size() );
1042 auto pFilters = aFilters.getArray();
1043 for ( sal_Int32
i = 0; i < static_cast<sal_Int32>(aFilterGroup.size());
i++ )
1047 false, _rFileDlgImpl );
1048 pFilters[
i].Second = aFilterGroup[
i].aWildcard;
1053 xFilterGroupManager->appendFilterGroup( OUString(), aFilters );
1055 catch(
const IllegalArgumentException& )
1065 for (
n = 0; n < static_cast<sal_Int32>(aImportantFilterGroup.size());
n++ )
1071 false, _rFileDlgImpl );
1073 if ( _rFirstNonEmpty.isEmpty() )
1074 _rFirstNonEmpty = sUIName;
1077 catch(
const IllegalArgumentException& )
1079 SAL_WARN(
"sfx.dialog",
"Could not append Filter" << sUIName );
1083 for (
n = 0; n < static_cast<sal_Int32>(aFilterGroup.size());
n++ )
1089 false, _rFileDlgImpl );
1091 if ( _rFirstNonEmpty.isEmpty() )
1092 _rFirstNonEmpty = sUIName;
1095 catch(
const IllegalArgumentException& )
1097 SAL_WARN(
"sfx.dialog",
"Could not append Filter" << sUIName );
1105 const Reference< XFilterManager >& _rxFilterManager,
1108 DBG_ASSERT( _rxFilterManager.is(),
"sfx2::appendFiltersForOpen: invalid manager!" );
1109 if ( !_rxFilterManager.is() )
1123 if ( !aAllFilters.empty() )
1125 const FilterGroup& rFirstGroup = *aAllFilters.begin();
1126 if ( !rFirstGroup.empty() )
1127 _rFirstNonEmpty = rFirstGroup.begin()->First;
1129 AppendFilterGroup aGroup( _rxFilterManager, &_rFileDlgImpl );
1130 aGroup.appendGroup( rFirstGroup,
false );
1135 if ( !aAllFilters.empty() )
1137 ::std::list< FilterGroup >::iterator pIter = aAllFilters.begin();
1142 AppendFilterGroup( _rxFilterManager, &_rFileDlgImpl ) );
1147 const OUString& _rExtension,
1150 OUString sRet = _rDisplayText;
1152 if ( sRet.indexOf(
"(*.*)" ) == -1 )
1154 OUString sExt = _rExtension;
1158 sExt = sExt.replaceAll(
"*",
"");
1160 sRet +=
" (" + sExt +
")";
static SAL_DLLPRIVATE std::shared_ptr< const SfxFilter > GetDefaultFilter_Impl(std::u16string_view)
static std::shared_ptr< const SfxFilter > GetFilterByName(const OUString &rName)
TValueType getUnpackedValueOrDefault(const OUString &sKey, const TValueType &aDefault) const
void addFilterPair(const OUString &rFilter, const OUString &rFilterWithExtension)
std::shared_ptr< const SfxFilter > impl_getFilter(sal_Int32 nIndex)
::std::vector< OUString > m_lFilters
std::shared_ptr< const SfxFilter > First()
std::shared_ptr< const SfxFilter > Next()
TSortedFilterList(const css::uno::Reference< css::container::XEnumeration > &xFilterList)
#define DBG_ASSERT(sCon, aError)
#define DBG_UNHANDLED_EXCEPTION(...)
constexpr OUStringLiteral FILEDIALOG_FILTER_ALL
Reference< XFilterGroupManager > m_xFilterGroupManager
::std::vector< OUString > aWildCards
FilterGroupEntryReferrer & m_rEntryReferrer
FilterGroup::iterator m_aClassPos
FilterClassList & m_rClasses
FilterClassList & m_rClassList
FilterGroupEntryReferrer::mapped_type aLookingFor
FilterGroup & m_rClassGroup
OConfigurationNode m_aClassesNode
OUString & _rToBeExtended
FilterClassReferrer & m_rClassesReferrer
FileDialogHelper_Impl * m_pFileDlgImpl
FilterGroupEntryReferrer & m_rClassReferrer
FilterClassReferrer & m_aClassReferrer
Sequence< FilterName > aSubFilters
Reference< XFilterManager > m_xFilterManager
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
sal_Int32 getTokenCount(std::string_view rIn, char cTok)
DstType sequenceToContainer(const css::uno::Sequence< SrcType > &i_Sequence)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
static void lcl_ReadFilterClass(const OConfigurationNode &_rClassesNode, const OUString &_rLogicalClassName, FilterClass &_rClass)
OUString addExtension(const OUString &_rDisplayText, const OUString &_rExtension, bool _bForOpen, FileDialogHelper_Impl &_rFileDlgImpl)
adds the given extension to the display text.
::std::list< FilterGroup > GroupedFilterList
const sal_Unicode s_cWildcardSeparator(';')
::std::map< OUString, FilterGroup::iterator > FilterGroupEntryReferrer
void appendFiltersForOpen(TSortedFilterList &_rFilterMatcher, const Reference< XFilterManager > &_rxFilterManager, OUString &_rFirstNonEmpty, FileDialogHelper_Impl &_rFileDlgImpl)
::std::map< OUString, FilterClassList::iterator > FilterClassReferrer
static bool lcl_hasAllFilesFilter(TSortedFilterList &_rFilterMatcher, OUString &_rAllFilterName)
StringPair FilterDescriptor
Some general words about what's going on here...
void appendExportFilters(TSortedFilterList &_rFilterMatcher, const Reference< XFilterManager > &_rxFilterManager, OUString &_rFirstNonEmpty, FileDialogHelper_Impl &_rFileDlgImpl)
::std::list< FilterClass > FilterClassList
OUString FilterName
the logical name of a filter
static void lcl_InitGlobalClasses(GroupedFilterList &_rAllFilters, const FilterClassList &_rGlobalClasses, FilterGroupEntryReferrer &_rGlobalClassesRef)
::std::list< FilterDescriptor > FilterGroup
::std::vector< ::std::pair< FilterGroupEntryReferrer::mapped_type, FilterGroup::iterator > > MapGroupEntry2GroupEntry
static void lcl_ReadClassification(FilterClassList &_rGlobalClasses, std::vector< OUString > &_rGlobalClassNames, FilterClassList &_rLocalClasses)
static void lcl_ReadLocalFilters(const OConfigurationNode &_rFilterClassification, FilterClassList &_rLocalClasses)
static void lcl_ReadGlobalFilters(const OConfigurationNode &_rFilterClassification, FilterClassList &_rGlobalClasses, std::vector< OUString > &_rGlobalClassNames)
static void lcl_EnsureAllFilesEntry(TSortedFilterList &_rFilterMatcher, GroupedFilterList &_rFilters)
static void lcl_GroupAndClassify(TSortedFilterList &_rFilterMatcher, GroupedFilterList &_rAllFilters)
void appendFiltersForSave(TSortedFilterList &_rFilterMatcher, const Reference< XFilterManager > &_rxFilterManager, OUString &_rFirstNonEmpty, FileDialogHelper_Impl &_rFileDlgImpl, std::u16string_view _rFactory)
static OUString getSeparatorString()
OUString SfxResId(TranslateId aId)