* Copyright 2002-2013, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Tyler Dauwalder
* Axel DΓΆrfler, axeld@pinc-software.de
* Ingo Weinhold, ingo_weinhold@gmx.de
*/
#include <mime/AppMetaMimeCreator.h>
#include <stdlib.h>
#include <AppFileInfo.h>
#include <Bitmap.h>
#include <File.h>
#include <fs_attr.h>
#include <Message.h>
#include <MimeType.h>
#include <String.h>
#include <AutoLocker.h>
#include <mime/Database.h>
#include <mime/database_support.h>
#include <mime/DatabaseLocation.h>
namespace BPrivate {
namespace Storage {
namespace Mime {
AppMetaMimeCreator::AppMetaMimeCreator(Database* database,
DatabaseLocker* databaseLocker, int32 force)
:
MimeEntryProcessor(database, databaseLocker, force)
{
}
AppMetaMimeCreator::~AppMetaMimeCreator()
{
}
status_t
AppMetaMimeCreator::Do(const entry_ref& entry, bool* _entryIsDir)
{
BFile file;
status_t status = file.SetTo(&entry, B_READ_ONLY | O_NOTRAVERSE);
if (status < B_OK)
return status;
bool isDir = file.IsDirectory();
if (_entryIsDir != NULL)
*_entryIsDir = isDir;
if (isDir || !file.IsFile())
return B_OK;
BAppFileInfo appInfo(&file);
status = appInfo.InitCheck();
if (status < B_OK)
return status;
BString signature;
status = file.ReadAttrString("BEOS:APP_SIG", &signature);
if (status != B_OK)
return B_BAD_TYPE;
if (!BMimeType::IsValid(signature))
return B_BAD_TYPE;
InstallNotificationDeferrer _(fDatabase, signature.String());
if (!fDatabase->Location()->IsInstalled(signature)) {
AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker);
fDatabase->Install(signature);
}
BNode typeNode;
status = fDatabase->Location()->OpenType(signature, typeNode);
if (status != B_OK)
return status;
attr_info info;
if (status == B_OK
&& (fForce || typeNode.GetAttrInfo(kPreferredAppAttr, &info) != B_OK)) {
AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker);
status = fDatabase->SetPreferredApp(signature, signature);
}
if (status == B_OK
&& (fForce
|| typeNode.GetAttrInfo(kShortDescriptionAttr, &info) != B_OK)) {
AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker);
status = fDatabase->SetShortDescription(signature, entry.name);
}
if (status == B_OK
&& (fForce || typeNode.GetAttrInfo(kAppHintAttr, &info) != B_OK)) {
AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker);
status = fDatabase->SetAppHint(signature, &entry);
}
if (status == B_OK
&& (fForce || typeNode.GetAttrInfo(kIconAttr, &info) != B_OK)) {
uint8* data = NULL;
size_t size = 0;
if (appInfo.GetIcon(&data, &size) == B_OK) {
AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker);
status = fDatabase->SetIcon(signature, data, size);
free(data);
}
}
BBitmap miniIcon(BRect(0, 0, 15, 15), B_BITMAP_NO_SERVER_LINK, B_CMAP8);
if (status == B_OK
&& (fForce || typeNode.GetAttrInfo(kMiniIconAttr, &info) != B_OK)) {
if (appInfo.GetIcon(&miniIcon, B_MINI_ICON) == B_OK) {
AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker);
status = fDatabase->SetIcon(signature, &miniIcon, B_MINI_ICON);
}
}
BBitmap largeIcon(BRect(0, 0, 31, 31), B_BITMAP_NO_SERVER_LINK, B_CMAP8);
if (status == B_OK
&& (fForce || typeNode.GetAttrInfo(kLargeIconAttr, &info) != B_OK)) {
if (appInfo.GetIcon(&largeIcon, B_LARGE_ICON) == B_OK) {
AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker);
status = fDatabase->SetIcon(signature, &largeIcon, B_LARGE_ICON);
}
}
bool setSupportedTypes = false;
BMessage supportedTypes;
if (status == B_OK
&& (fForce
|| typeNode.GetAttrInfo(kSupportedTypesAttr, &info) != B_OK)) {
if (appInfo.GetSupportedTypes(&supportedTypes) == B_OK)
setSupportedTypes = true;
}
const char* type;
for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK; i++)
fDatabase->DeferInstallNotification(type);
if (setSupportedTypes) {
AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker);
status = fDatabase->SetSupportedTypes(signature, &supportedTypes, true);
}
for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK;
i++) {
uint8* data = NULL;
size_t size = 0;
if (status == B_OK
&& appInfo.GetIconForType(type, &data, &size) == B_OK) {
AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker);
status = fDatabase->SetIconForType(signature, type, data, size);
free(data);
}
if (status == B_OK
&& appInfo.GetIconForType(type, &miniIcon, B_MINI_ICON) == B_OK) {
AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker);
status = fDatabase->SetIconForType(signature, type, &miniIcon,
B_MINI_ICON);
}
if (status == B_OK
&& appInfo.GetIconForType(type, &largeIcon, B_LARGE_ICON) == B_OK) {
AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker);
status = fDatabase->SetIconForType(signature, type, &largeIcon,
B_LARGE_ICON);
}
}
for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK; i++)
fDatabase->UndeferInstallNotification(type);
return status;
}
}
}
}