_TranslateType() now falls back to the preferred app of the super type in
case the preferred app of the type itself is not available or valid. Ie. if you have deleted an application that was the preferred app for "image/png", the system will now try to open the file with the preferred app for "image". git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16565 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+60
-25
@@ -2120,46 +2120,81 @@ BRoster::_TranslateType(const char *mimeType, BMimeType *appMeta,
|
|||||||
status_t error = type.SetTo(mimeType);
|
status_t error = type.SetTo(mimeType);
|
||||||
|
|
||||||
// get the preferred app
|
// get the preferred app
|
||||||
char appSignature[B_MIME_TYPE_LENGTH];
|
char primarySignature[B_MIME_TYPE_LENGTH];
|
||||||
|
char secondarySignature[B_MIME_TYPE_LENGTH];
|
||||||
|
primarySignature[0] = '\0';
|
||||||
|
secondarySignature[0] = '\0';
|
||||||
|
|
||||||
if (error == B_OK) {
|
if (error == B_OK) {
|
||||||
if (type.IsInstalled()) {
|
if (type.IsInstalled()) {
|
||||||
BMimeType superType;
|
BMimeType superType;
|
||||||
if (type.GetPreferredApp(appSignature) != B_OK
|
if (type.GetSupertype(&superType) == B_OK)
|
||||||
&& (type.GetSupertype(&superType) != B_OK
|
superType.GetPreferredApp(secondarySignature);
|
||||||
|| superType.GetPreferredApp(appSignature) != B_OK)) {
|
|
||||||
|
if (type.GetPreferredApp(primarySignature) != B_OK
|
||||||
|
&& !primarySignature[0]) {
|
||||||
// The type is installed, but has no preferred app.
|
// The type is installed, but has no preferred app.
|
||||||
// In fact it might be an app signature and even having a
|
// In fact it might be an app signature and even having a
|
||||||
// valid app hint. Nevertheless we fail.
|
// valid app hint. Nevertheless we fail.
|
||||||
error = B_LAUNCH_FAILED_NO_PREFERRED_APP;
|
error = B_LAUNCH_FAILED_NO_PREFERRED_APP;
|
||||||
|
} else if (!strcmp(primarySignature, secondarySignature)) {
|
||||||
|
// Both types have the same preferred app, there is
|
||||||
|
// no point in testing it twice.
|
||||||
|
secondarySignature[0] = '\0';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// The type is not installed. We assume it is an app signature.
|
// The type is not installed. We assume it is an app signature.
|
||||||
strcpy(appSignature, mimeType);
|
strcpy(primarySignature, mimeType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (error == B_OK)
|
|
||||||
error = appMeta->SetTo(appSignature);
|
if (error != B_OK)
|
||||||
// check, whether the signature is installed and has an app hint
|
return error;
|
||||||
bool appFound = false;
|
|
||||||
if (error == B_OK && appMeta->GetAppHint(appRef) == B_OK) {
|
// see if we can find the application and if it's valid, try
|
||||||
// resolve symbolic links, if necessary
|
// both preferred app signatures, if available (from type and
|
||||||
BEntry entry;
|
// super type)
|
||||||
if (entry.SetTo(appRef, true) == B_OK && entry.IsFile()
|
|
||||||
&& entry.GetRef(appRef) == B_OK) {
|
status_t primaryError = B_OK;
|
||||||
appFound = true;
|
|
||||||
|
for (int32 tries = 0; tries < 2; tries++) {
|
||||||
|
const char* signature = tries == 0 ? primarySignature : secondarySignature;
|
||||||
|
if (signature[0] == '\0')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
error = appMeta->SetTo(signature);
|
||||||
|
|
||||||
|
// 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
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// in case there is no app hint or it is invalid, we need to query for the
|
||||||
|
// app
|
||||||
|
if (error == B_OK && !appFound)
|
||||||
|
error = query_for_app(appMeta->Type(), appRef);
|
||||||
|
if (error == B_OK)
|
||||||
|
error = appFile->SetTo(appRef, B_READ_ONLY);
|
||||||
|
// check, whether the app can be used
|
||||||
|
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
|
} else
|
||||||
appMeta->SetAppHint(NULL); // bad app hint -- remove it
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// in case there is no app hint or it is invalid, we need to query for the
|
|
||||||
// app
|
|
||||||
if (error == B_OK && !appFound)
|
|
||||||
error = query_for_app(appMeta->Type(), appRef);
|
|
||||||
if (error == B_OK)
|
|
||||||
error = appFile->SetTo(appRef, B_READ_ONLY);
|
|
||||||
// check, whether the app can be used
|
|
||||||
if (error == B_OK)
|
|
||||||
error = can_app_be_used(appRef);
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user