summaryrefslogtreecommitdiff
path: root/filter
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@gmail.com>2013-03-06 02:00:02 -0500
committerKohei Yoshida <kohei.yoshida@gmail.com>2013-03-07 01:44:45 -0500
commit1a3c7b84b7b22109d691a770649af42c1033d709 (patch)
tree91c8964ce2a4a1dd81b51a01d3bfcf3498171892 /filter
parent74d68ec05761b001bc82c1c9c2dc168648cde49b (diff)
Test all file format types regardless of document services.
The old type detection would only test file format types that are relevant to the current document service. But this would not work if the user tries to open an Excel document whose name ends with a non-default extension (such as .tmp) from Writer UI. To amend this, we need to test all possible format types that are supported by all our modules regardless of the current module, but prioritize them per current module. TODO: The above scenario doesn't work yet. I still need to fix the individual type detection services to get it to work. Change-Id: I51dbdff28299aa64cedc6752b9ff82b96d5d79cf
Diffstat (limited to 'filter')
-rw-r--r--filter/source/config/cache/typedetection.cxx217
-rw-r--r--filter/source/config/cache/typedetection.hxx22
2 files changed, 120 insertions, 119 deletions
diff --git a/filter/source/config/cache/typedetection.cxx b/filter/source/config/cache/typedetection.cxx
index d8fb82e96275..6b29abf4174e 100644
--- a/filter/source/config/cache/typedetection.cxx
+++ b/filter/source/config/cache/typedetection.cxx
@@ -170,7 +170,6 @@ int getFlatTypeRank(const rtl::OUString& rType)
"calc_DIF",
"calc_dBase",
-
// Non-compressed XML
"writer_ODT_FlatXML",
"calc_ODS_FlatXML",
@@ -227,7 +226,16 @@ struct SortByPriority : public std::binary_function<FlatDetectionInfo, FlatDetec
}
};
-struct EqualByName : public std::binary_function<FlatDetectionInfo, FlatDetectionInfo, bool>
+struct SortByType : public std::binary_function<FlatDetectionInfo, FlatDetectionInfo, bool>
+
+{
+ bool operator() (const FlatDetectionInfo& r1, const FlatDetectionInfo& r2) const
+ {
+ return r1.sType > r2.sType;
+ }
+};
+
+struct EqualByType : public std::binary_function<FlatDetectionInfo, FlatDetectionInfo, bool>
{
bool operator() (const FlatDetectionInfo& r1, const FlatDetectionInfo& r2) const
{
@@ -235,10 +243,21 @@ struct EqualByName : public std::binary_function<FlatDetectionInfo, FlatDetectio
}
};
+class FindByType : std::unary_function<FlatDetectionInfo, bool>
+{
+ OUString maType;
+public:
+ FindByType(const OUString& rType) : maType(rType) {}
+ bool operator() (const FlatDetectionInfo& rInfo) const
+ {
+ return rInfo.sType == maType;
+ }
+};
+
#if DEBUG_TYPE_DETECTION
void printFlatDetectionList(const char* caption, const FlatDetection& types)
{
- cout << "-- " << caption << endl;
+ cout << "-- " << caption << " (size=" << types.size() << ")" << endl;
FlatDetection::const_iterator it = types.begin(), itEnd = types.end();
for (; it != itEnd; ++it)
{
@@ -292,17 +311,39 @@ void printFlatDetectionList(const char* caption, const FlatDetection& types)
FlatDetection lFlatTypes;
impl_getPreselection(aURL, stlDescriptor, lFlatTypes);
- //*******************************************
- // get all types, which match to the given descriptor
- // That can be true by: extensions/url pattern/mime type etcpp.
- m_rCache->detectFlatForURL(aURL, lFlatTypes);
+ {
+ // Get all types that match the URL alone.
+ FlatDetection aFlatByURL;
+ m_rCache->detectFlatForURL(aURL, aFlatByURL);
+ FlatDetection::const_iterator it = aFlatByURL.begin(), itEnd = aFlatByURL.end();
+ for (; it != itEnd; ++it)
+ {
+ FlatDetection::iterator itPos = std::find_if(lFlatTypes.begin(), lFlatTypes.end(), FindByType(it->sType));
+ if (itPos == lFlatTypes.end())
+ // Not in the list yet.
+ lFlatTypes.push_back(*it);
+ else
+ {
+ // Already in the list. Update the flags.
+ FlatDetectionInfo& rInfo = *itPos;
+ const FlatDetectionInfo& rThisInfo = *it;
+ if (rThisInfo.bMatchByExtension)
+ rInfo.bMatchByExtension = true;
+ if (rThisInfo.bMatchByPattern)
+ rInfo.bMatchByPattern = true;
+ if (rThisInfo.bPreselectedByDocumentService)
+ rInfo.bPreselectedByDocumentService = true;
+ }
+ }
+ }
+
aLock.clear();
// <- SAFE ----------------------------------
// Properly prioritize all candidate types.
lFlatTypes.sort(SortByPriority());
- lFlatTypes.unique(EqualByName());
+ lFlatTypes.unique(EqualByType());
::rtl::OUString sType ;
::rtl::OUString sLastChance;
@@ -529,9 +570,8 @@ void TypeDetection::impl_checkResultsAndAddBestFilter(::comphelper::MediaDescrip
-sal_Bool TypeDetection::impl_getPreselectionForType(const ::rtl::OUString& sPreSelType,
- const css::util::URL& aParsedURL ,
- FlatDetection& rFlatTypes )
+bool TypeDetection::impl_getPreselectionForType(
+ const OUString& sPreSelType, const util::URL& aParsedURL, FlatDetection& rFlatTypes, bool bDocService)
{
// Can be used to supress execution of some parts of this method
// if its already clear that detected type is valid or not.
@@ -547,14 +587,6 @@ sal_Bool TypeDetection::impl_getPreselectionForType(const ::rtl::OUString& sPreS
// it matches by it's extension too.
bool bMatchByExtension = false;
- // If we e.g. collect all filters of a factory (be a forced factory preselection)
- // we should preferr all filters of this factory, where the type match the given URL.
- // All other types (which sorrespond to filters of the same factory - but dont match
- // the URL) should be "used later" for detection and sorted at the end of our return vector
- // rFlatTypes!
- // => bPreferredPreselection = (matchByExtension || matchByURLPattern)
- bool bPreferredPreselection = false;
-
// validate type
::rtl::OUString sType(sPreSelType);
CacheItem aType;
@@ -603,7 +635,6 @@ sal_Bool TypeDetection::impl_getPreselectionForType(const ::rtl::OUString& sPreS
{
bBreakDetection = true;
bMatchByExtension = true;
- bPreferredPreselection = true;
break;
}
}
@@ -619,7 +650,6 @@ sal_Bool TypeDetection::impl_getPreselectionForType(const ::rtl::OUString& sPreS
{
bBreakDetection = true;
bMatchByPattern = true;
- bPreferredPreselection = true;
break;
}
}
@@ -629,15 +659,16 @@ sal_Bool TypeDetection::impl_getPreselectionForType(const ::rtl::OUString& sPreS
// if its a valid type - set it on all return values!
if (!sType.isEmpty())
{
- FlatDetectionInfo aInfo;
- aInfo.sType = sType;
- aInfo.bMatchByExtension = bMatchByExtension;
- aInfo.bMatchByPattern = bMatchByPattern;
-
- if (bPreferredPreselection)
- rFlatTypes.push_front(aInfo);
- else
- rFlatTypes.push_back(aInfo);
+ FlatDetection::iterator it = std::find_if(rFlatTypes.begin(), rFlatTypes.end(), FindByType(sType));
+ if (it != rFlatTypes.end())
+ {
+ if (bMatchByExtension)
+ it->bMatchByExtension = true;
+ if (bMatchByPattern)
+ it->bMatchByPattern = true;
+ if (bDocService)
+ it->bPreselectedByDocumentService = true;
+ }
return true;
}
@@ -646,59 +677,8 @@ sal_Bool TypeDetection::impl_getPreselectionForType(const ::rtl::OUString& sPreS
return false;
}
-
-
-sal_Bool TypeDetection::impl_getPreselectionForFilter(const ::rtl::OUString& sPreSelFilter,
- const css::util::URL& aParsedURL ,
- FlatDetection& rFlatTypes )
-{
- // Can be used to supress execution of some parts of this method
- // if its already clear that detected filter is valid or not.
- // Its necessary to use shared code at the end, which update
- // all return parameters constistency!
- sal_Bool bBreakDetection = sal_False;
-
- // validate filter
- ::rtl::OUString sFilter(sPreSelFilter);
- CacheItem aFilter;
- try
- {
- // SAFE -> --------------------------
- ::osl::ResettableMutexGuard aLock(m_aLock);
- aFilter = m_rCache->getItem(FilterCache::E_FILTER, sFilter);
- aLock.clear();
- // <- SAFE --------------------------
- }
- catch(const css::container::NoSuchElementException&)
- {
- sFilter = ::rtl::OUString();
- bBreakDetection = sal_True;
- }
-
- if (!bBreakDetection)
- {
- // get its type and check if it matches the given URL
- ::rtl::OUString sType;
- aFilter[PROPNAME_TYPE] >>= sType;
-
- bBreakDetection = impl_getPreselectionForType(sType, aParsedURL, rFlatTypes);
-
- // not a valid type? -> not a valid filter!
- if (!bBreakDetection)
- sFilter = ::rtl::OUString();
- }
-
- if (!sFilter.isEmpty())
- return sal_True;
- else
- return sal_False;
-}
-
-
-
-sal_Bool TypeDetection::impl_getPreselectionForDocumentService(const ::rtl::OUString& sPreSelDocumentService,
- const css::util::URL& aParsedURL ,
- FlatDetection& rFlatTypes )
+bool TypeDetection::impl_getPreselectionForDocumentService(
+ const OUString& sPreSelDocumentService, const util::URL& aParsedURL, FlatDetection& rFlatTypes)
{
// get all filters, which match to this doc service
OUStringList lFilters;
@@ -719,7 +699,7 @@ sal_Bool TypeDetection::impl_getPreselectionForDocumentService(const ::rtl::OUSt
aLock.clear();
// <- SAFE --------------------------
}
- catch(const css::container::NoSuchElementException&)
+ catch (const css::container::NoSuchElementException&)
{
lFilters.clear();
}
@@ -729,36 +709,41 @@ sal_Bool TypeDetection::impl_getPreselectionForDocumentService(const ::rtl::OUSt
// But use temp. list of "preselected types" instead of incoming rFlatTypes list!
// The reason behind: we must filter the getted results. And copying of stl entries
// is an easier job then removing it .-)
- FlatDetection lPreselections;
for (OUStringList::const_iterator pFilter = lFilters.begin();
- pFilter != lFilters.end() ;
- ++pFilter )
+ pFilter != lFilters.end();
+ ++pFilter)
{
- const ::rtl::OUString sFilter = *pFilter;
- impl_getPreselectionForFilter(sFilter, aParsedURL, lPreselections);
- }
+ OUString aType = impl_getTypeFromFilter(*pFilter);
+ if (aType.isEmpty())
+ continue;
- // We have to mark all retrieved preselection items as "preselected by document service".
- // Further we must ignore all preselected items, which does not match the URL!
- FlatDetection::iterator pIt;
- for ( pIt = lPreselections.begin();
- pIt != lPreselections.end() ;
- ++pIt )
- {
- FlatDetectionInfo& rInfo = *pIt;
- rInfo.bPreselectedByDocumentService = true ;
- rFlatTypes.push_back(rInfo);
+ impl_getPreselectionForType(aType, aParsedURL, rFlatTypes, true);
}
return true;
}
+OUString TypeDetection::impl_getTypeFromFilter(const OUString& rFilterName)
+{
+ CacheItem aFilter;
+ try
+ {
+ osl::MutexGuard aLock(m_aLock);
+ aFilter = m_rCache->getItem(FilterCache::E_FILTER, rFilterName);
+ }
+ catch (const container::NoSuchElementException&)
+ {
+ return OUString();
+ }
+ OUString aType;
+ aFilter[PROPNAME_TYPE] >>= aType;
+ return aType;
+}
void TypeDetection::impl_getPreselection(
const util::URL& aParsedURL, comphelper::MediaDescriptor& rDescriptor, FlatDetection& rFlatTypes)
{
- // done to be shure, that only valid results leave this function!
rFlatTypes.clear();
/* #i55122#
@@ -777,9 +762,37 @@ void TypeDetection::impl_getPreselection(
So it must be pereferred. An order between type and filter selection cant be discussed .-)
*/
+ OUStringList aFilterNames;
+ try
+ {
+ osl::MutexGuard aLock(m_aLock);
+ m_rCache->load(FilterCache::E_CONTAINS_FILTERS);
+ aFilterNames = m_rCache->getItemNames(FilterCache::E_FILTER);
+ }
+ catch (const container::NoSuchElementException&)
+ {
+ return;
+ }
+
+ for (OUStringList::const_iterator it = aFilterNames.begin(); it != aFilterNames.end(); ++it)
+ {
+ OUString aType = impl_getTypeFromFilter(*it);
+
+ if (aType.isEmpty())
+ continue;
+
+ FlatDetectionInfo aInfo; // all flags set to false by default.
+ aInfo.sType = aType;
+ rFlatTypes.push_back(aInfo);
+ }
+
+ // Remove duplicates.
+ rFlatTypes.sort(SortByType());
+ rFlatTypes.unique(EqualByType());
+
::rtl::OUString sSelectedType = rDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_TYPENAME(), ::rtl::OUString());
if (!sSelectedType.isEmpty())
- impl_getPreselectionForType(sSelectedType, aParsedURL, rFlatTypes);
+ impl_getPreselectionForType(sSelectedType, aParsedURL, rFlatTypes, false);
::rtl::OUString sSelectedDoc = rDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_DOCUMENTSERVICE(), ::rtl::OUString());
if (!sSelectedDoc.isEmpty())
diff --git a/filter/source/config/cache/typedetection.hxx b/filter/source/config/cache/typedetection.hxx
index d7f89a4eb6b3..ec41aff39c82 100644
--- a/filter/source/config/cache/typedetection.hxx
+++ b/filter/source/config/cache/typedetection.hxx
@@ -65,25 +65,13 @@ public:
private:
- //---------------------------------------
- /** TODO document me */
- sal_Bool impl_getPreselectionForType(const ::rtl::OUString& sPreSelType,
- const css::util::URL& aParsedURL ,
- FlatDetection& rFlatTypes );
+ bool impl_getPreselectionForType(
+ const OUString& sPreSelType, const com::sun::star::util::URL& aParsedURL, FlatDetection& rFlatTypes, bool bDocService);
- //---------------------------------------
- /** TODO document me */
- sal_Bool impl_getPreselectionForFilter(const ::rtl::OUString& sPreSelFilter,
- const css::util::URL& aParsedURL ,
- FlatDetection& rFlatTypes );
+ bool impl_getPreselectionForDocumentService(
+ const OUString& sPreSelDocumentService, const com::sun::star::util::URL& aParsedURL, FlatDetection& rFlatTypes);
- //---------------------------------------
- /** TODO document me */
- sal_Bool impl_getPreselectionForDocumentService(const ::rtl::OUString& sPreSelDocumentService,
- const css::util::URL& aParsedURL ,
- FlatDetection& rFlatTypes );
-
- //---------------------------------------
+ OUString impl_getTypeFromFilter(const OUString& rFilterName);
/** @short check if a filter or a type was preselected inside the given
MediaDescriptor and validate this information.