Changed the resolving of the best handler for a MIME type to consider other

supporting apps of the sub-type only when there is a preferred handler for the
sub-type configured at all. In this case, it is assumed that the super-type
preferred handler is not really suitable. In the case when no sub-type
preferred handler is configured, the super-type preferred handler will always
get precedence, even if there are applications installed that declare direct
support for the sub-type. This makes the behavior more consistent/deterministic
and the "Open With" menu that Tracker displays will have the checkmark at
the app again that will really be used to open the type by default. Should
fix #5821 for good, as suggested by Axel.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36500 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2010-04-27 10:24:00 +00:00
parent e234c03470
commit da72ff2672
1 changed files with 41 additions and 20 deletions

View File

@ -843,21 +843,26 @@ BRoster::GetActiveAppInfo(app_info* info) const
/*! \brief Finds an application associated with a MIME type. /*! \brief Finds an application associated with a MIME type.
The method gets the signature of the supplied type's preferred application The method gets the signature of the supplied type's preferred application
and the signatures of all other applications supporting the MIME type and the signature of the super type's preferred application. It will also
directly. Additionally, the preferred application signature and all get all supporting applications for the type and super type and build a
supporting applications for the supertype are retrieved. list of candiate handlers. In the case that a preferred handler is
Then the MIME database is asked which executable is associated with the configured for the sub-type, other supporting apps will be inserted in the
signatures in the resulting list. If the database doesn't have a reference candidate list before the super-type preferred and supporting handlers,
to an exectuable, the boot volume is queried for a file with the signature. since it is assumed that the super type handlers are not well suited for
If more than one file has been found, the one with the greatest version is the sub-type. The following resolving algorithm is performed on each
picked, or if no file has a version info, the one with the most recent signature of the resulting list:
modification date. The first application from the signature list which can The MIME database is asked which executable is associated with the
be successfully resolved by this algorithm is returned. Contrary to BeOS signature. If the database doesn't have a reference to an exectuable, the
behavior, this means that if the preferred application of the provided MIME boot volume is queried for a file with the signature. If more than one file
type cannot be resolved, or if it does not have a preferred application has been found, the one with the greatest version is picked, or if no file
associated, the method will return other applications with direct support has a version info, the one with the most recent modification date. The
for the MIME type before it resorts to the preferred application or first application from the signature list which can be successfully
supporting applications of the super type. resolved by this algorithm is returned. Contrary to BeOS behavior, this
means that if the preferred application of the provided MIME type cannot
be resolved, or if it does not have a preferred application associated,
the method will return other applications with direct support for the MIME
type before it resorts to the preferred application or supporting
applications of the super type.
\param mimeType The MIME type for which an application shall be found. \param mimeType The MIME type for which an application shall be found.
\param app A pointer to a pre-allocated entry_ref to be filled with \param app A pointer to a pre-allocated entry_ref to be filled with
@ -2609,8 +2614,20 @@ BRoster::_TranslateType(const char* mimeType, BMimeType* appMeta,
// applications for the sub and the super type respectively. // applications for the sub and the super type respectively.
const char* kSigField = "applications"; const char* kSigField = "applications";
BMessage signatures; BMessage signatures;
if (error == B_OK && primarySignature[0] != '\0') if (error == B_OK) {
if (primarySignature[0] != '\0')
error = signatures.AddString(kSigField, primarySignature); error = signatures.AddString(kSigField, primarySignature);
else {
// If there is a preferred app configured for the super type,
// but no preferred type for the sub-type, add the preferred
// super type handler in front of any other handlers. This way
// we fall-back to non-preferred but supporting apps only in the
// case when there is a preferred handler for the sub-type but
// it cannot be resolved (misconfiguration).
if (secondarySignature[0] != '\0')
error = signatures.AddString(kSigField, secondarySignature);
}
}
BMessage supportingSignatures; BMessage supportingSignatures;
if (error == B_OK if (error == B_OK
@ -2628,9 +2645,13 @@ BRoster::_TranslateType(const char* mimeType, BMimeType* appMeta,
error = signatures.AddString(kSigField, supportingType); error = signatures.AddString(kSigField, supportingType);
} }
// Add the preferred type of the super type here before adding // Add the preferred type of the super type here before adding
// the other types supporting the super type. // the other types supporting the super type, but only if we have
if (error == B_OK && secondarySignature[0] != '\0') // not already added it in case there was no preferred app for the
// sub-type configured.
if (error == B_OK && primarySignature[0] != '\0'
&& secondarySignature[0] != '\0') {
error = signatures.AddString(kSigField, secondarySignature); error = signatures.AddString(kSigField, secondarySignature);
}
// Add all signatures with support for the super-type // Add all signatures with support for the super-type
for (int32 i = subCount; error == B_OK for (int32 i = subCount; error == B_OK
&& supportingSignatures.FindString(kSigField, i, && supportingSignatures.FindString(kSigField, i,
@ -2641,7 +2662,7 @@ BRoster::_TranslateType(const char* mimeType, BMimeType* appMeta,
} }
} else { } else {
// Failed to get supporting apps, just add the preferred apps. // Failed to get supporting apps, just add the preferred apps.
if (error == B_OK) if (error == B_OK && secondarySignature[0] != '\0')
error = signatures.AddString(kSigField, secondarySignature); error = signatures.AddString(kSigField, secondarySignature);
} }