Changed the behavior for BRoster::FindApp(), Launch() and related functionality:
Instead of only checking the preferred applications of a given MIME type and its super type (i.e. "text/html" and "text"), build a list of all supporting apps, where the preferred types of the sub and super type lead the respective sections of the list. Then try to find the first valid application in the list. This makes it possible to double click "Welcome" on the Desktop, even though the text/html MIME type still has BeZillaBrowser set as preferred application. Previously it would launch StyledEdit, even though WebPositive was readily available. The previous behavior was probably implementing exactly the BeOS behavior, but I can't see a good reason why we should be compatible here. Until now, my testing has also not revealed any regression. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36471 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
5af798836a
commit
da24e53cf8
@ -2563,11 +2563,11 @@ BRoster::_TranslateType(const char* mimeType, BMimeType* appMeta,
|
||||
|| appFile == NULL || strlen(mimeType) >= B_MIME_TYPE_LENGTH)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// create a BMimeType and check, if the type is installed
|
||||
// Create a BMimeType and check, if the type is installed.
|
||||
BMimeType type;
|
||||
status_t error = type.SetTo(mimeType);
|
||||
|
||||
// get the preferred app
|
||||
// Get the preferred apps from the sub and super type.
|
||||
char primarySignature[B_MIME_TYPE_LENGTH];
|
||||
char secondarySignature[B_MIME_TYPE_LENGTH];
|
||||
primarySignature[0] = '\0';
|
||||
@ -2579,12 +2579,9 @@ BRoster::_TranslateType(const char* mimeType, BMimeType* appMeta,
|
||||
if (type.GetSupertype(&superType) == B_OK)
|
||||
superType.GetPreferredApp(secondarySignature);
|
||||
|
||||
if (type.GetPreferredApp(primarySignature) != B_OK
|
||||
&& !secondarySignature[0]) {
|
||||
if (type.GetPreferredApp(primarySignature) != B_OK) {
|
||||
// The type is installed, but has no preferred app.
|
||||
// In fact it might be an app signature and even having a
|
||||
// valid app hint. Nevertheless we fail.
|
||||
error = B_LAUNCH_FAILED_NO_PREFERRED_APP;
|
||||
primarySignature[0] = '\0';
|
||||
} else if (!strcmp(primarySignature, secondarySignature)) {
|
||||
// Both types have the same preferred app, there is
|
||||
// no point in testing it twice.
|
||||
@ -2596,37 +2593,80 @@ BRoster::_TranslateType(const char* mimeType, BMimeType* appMeta,
|
||||
}
|
||||
}
|
||||
|
||||
// We will use this BMessage "signatures" to hold all supporting apps
|
||||
// so we can iterator over them in the preferred order. We include
|
||||
// the supporting apps in such a way that the configured preferred
|
||||
// applications for the MIME type are in front of other supporting
|
||||
// applications for the sub and the super type respectively.
|
||||
const char* kSigField = "applications";
|
||||
BMessage signatures;
|
||||
if (error == B_OK && primarySignature[0] != '\0')
|
||||
error = signatures.AddString(kSigField, primarySignature);
|
||||
|
||||
BMessage supportingSignatures;
|
||||
if (error == B_OK
|
||||
&& type.GetSupportingApps(&supportingSignatures) == B_OK) {
|
||||
int32 subCount;
|
||||
if (supportingSignatures.FindInt32("be:sub", &subCount) != B_OK)
|
||||
subCount = 0;
|
||||
// Add all signatures with direct support for the sub-type
|
||||
const char* supportingType;
|
||||
for (int32 i = 0; error == B_OK && i < subCount
|
||||
&& supportingSignatures.FindString(kSigField, i,
|
||||
&supportingType) == B_OK; i++) {
|
||||
// don't add the signature if it's the preferred app already.
|
||||
if (strcmp(primarySignature, supportingType) != 0)
|
||||
error = signatures.AddString(kSigField, supportingType);
|
||||
}
|
||||
// Add the preferred type of the super type here before adding
|
||||
// the other types supporting the super type.
|
||||
if (error == B_OK && secondarySignature[0] != '\0')
|
||||
error = signatures.AddString(kSigField, secondarySignature);
|
||||
// Add all signatures with support for the super-type
|
||||
for (int32 i = subCount; error == B_OK
|
||||
&& supportingSignatures.FindString(kSigField, i,
|
||||
&supportingType) == B_OK; i++) {
|
||||
// don't add the signature if it's the preferred app already.
|
||||
if (strcmp(secondarySignature, supportingType) != 0)
|
||||
error = signatures.AddString(kSigField, supportingType);
|
||||
}
|
||||
} else {
|
||||
// Failed to get supporting apps, just add the preferred apps.
|
||||
if (error == B_OK)
|
||||
error = signatures.AddString(kSigField, secondarySignature);
|
||||
}
|
||||
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// see if we can find the application and if it's valid, try
|
||||
// both preferred app signatures, if available (from type and
|
||||
// super type)
|
||||
// Set an error in case we can't resolve a single supporting app.
|
||||
error = B_LAUNCH_FAILED_NO_PREFERRED_APP;
|
||||
|
||||
status_t primaryError = B_OK;
|
||||
|
||||
for (int32 tries = 0; tries < 2; tries++) {
|
||||
const char* signature = tries == 0
|
||||
? primarySignature : secondarySignature;
|
||||
// See if we can find a good application that is valid from the messege.
|
||||
const char* signature;
|
||||
for (int32 i = 0;
|
||||
signatures.FindString(kSigField, i, &signature) == B_OK; i++) {
|
||||
if (signature[0] == '\0')
|
||||
continue;
|
||||
|
||||
error = appMeta->SetTo(signature);
|
||||
|
||||
// check, whether the signature is installed and has an app hint
|
||||
// Check, whether the signature is installed and has an app hint
|
||||
bool appFound = false;
|
||||
if (error == B_OK && appMeta->GetAppHint(appRef) == B_OK) {
|
||||
// resolve symbolic links, if necessary
|
||||
// Resolve symbolic links, if necessary
|
||||
BEntry entry;
|
||||
if (entry.SetTo(appRef, true) == B_OK && entry.IsFile()
|
||||
&& entry.GetRef(appRef) == B_OK) {
|
||||
appFound = true;
|
||||
} else
|
||||
appMeta->SetAppHint(NULL); // bad app hint -- remove it
|
||||
} else {
|
||||
// Bad app hint -- remove it
|
||||
appMeta->SetAppHint(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// In case there is no app hint or it is invalid, we need to query for
|
||||
// the app
|
||||
// the app.
|
||||
if (error == B_OK && !appFound)
|
||||
error = query_for_app(appMeta->Type(), appRef);
|
||||
if (error == B_OK)
|
||||
@ -2635,12 +2675,7 @@ BRoster::_TranslateType(const char* mimeType, BMimeType* appMeta,
|
||||
if (error == B_OK)
|
||||
error = can_app_be_used(appRef);
|
||||
|
||||
if (error != B_OK) {
|
||||
if (tries == 0)
|
||||
primaryError = error;
|
||||
else if (primarySignature[0])
|
||||
error = primaryError;
|
||||
} else
|
||||
if (error == B_OK)
|
||||
break;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user