From 0b537029e3ee788c7b5cd666e6603aa40b93c529 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sat, 28 Jan 2006 20:20:27 +0000 Subject: [PATCH] Synchronized the MIME stuff in the build platform support libbe with the current Haiku libbe. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16124 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/build/os/storage/Mime.h | 20 +- .../storage/mime/CreateAppMetaMimeThread.cpp | 8 +- .../libbe/storage/mime/MimeUpdateThread.cpp | 5 +- .../storage/mime/UpdateMimeInfoThread.cpp | 177 ++++++++++++++++-- 4 files changed, 181 insertions(+), 29 deletions(-) diff --git a/headers/build/os/storage/Mime.h b/headers/build/os/storage/Mime.h index 314e95d7bb..e79f33acff 100644 --- a/headers/build/os/storage/Mime.h +++ b/headers/build/os/storage/Mime.h @@ -1,7 +1,8 @@ -//---------------------------------------------------------------------- -// This software is part of the OpenBeOS distribution and is covered -// by the OpenBeOS license. -//--------------------------------------------------------------------- +/* + * Copyright 2004-2006, Haiku Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + */ + /*! \file Mime.h Mime type C functions interface declarations. @@ -37,11 +38,18 @@ enum icon_size { B_MINI_ICON = 16 }; +// values for the "force" parameter of update_mime_info() (Haiku only) +enum { + B_UPDATE_MIME_INFO_NO_FORCE = 0, + B_UPDATE_MIME_INFO_FORCE_KEEP_TYPE = 1, + B_UPDATE_MIME_INFO_FORCE_UPDATE_ALL = 2, +}; + #ifdef __cplusplus } #endif -// OpenBeOS only! +// Haiku only! #ifdef __cplusplus class BBitmap; @@ -56,5 +64,3 @@ status_t get_device_icon(const char *dev, BBitmap *icon, icon_size which); #endif #endif // _MIME_H - - diff --git a/src/build/libbe/storage/mime/CreateAppMetaMimeThread.cpp b/src/build/libbe/storage/mime/CreateAppMetaMimeThread.cpp index 894c14b323..4fc33ba712 100644 --- a/src/build/libbe/storage/mime/CreateAppMetaMimeThread.cpp +++ b/src/build/libbe/storage/mime/CreateAppMetaMimeThread.cpp @@ -23,9 +23,11 @@ namespace BPrivate { namespace Storage { namespace Mime { -CreateAppMetaMimeThread::CreateAppMetaMimeThread(const char *name, int32 priority, - BMessenger managerMessenger, const entry_ref *root, bool recursive, bool force, BMessage *replyee) - : MimeUpdateThread(name, priority, managerMessenger, root, recursive, force, replyee) +CreateAppMetaMimeThread::CreateAppMetaMimeThread(const char *name, + int32 priority, BMessenger managerMessenger, const entry_ref *root, + bool recursive, int32 force, BMessage *replyee) + : MimeUpdateThread(name, priority, managerMessenger, root, recursive, force, + replyee) { } diff --git a/src/build/libbe/storage/mime/MimeUpdateThread.cpp b/src/build/libbe/storage/mime/MimeUpdateThread.cpp index 2a63b3e539..6c7a296c3a 100644 --- a/src/build/libbe/storage/mime/MimeUpdateThread.cpp +++ b/src/build/libbe/storage/mime/MimeUpdateThread.cpp @@ -42,8 +42,9 @@ namespace Mime { field detached from the registrar's mime manager looper (though this is not verified). The message will be replied to at the end of the thread's execution. */ -MimeUpdateThread::MimeUpdateThread(const char *name, int32 priority, BMessenger managerMessenger, - const entry_ref *root, bool recursive, bool force, BMessage *replyee) +MimeUpdateThread::MimeUpdateThread(const char *name, int32 priority, + BMessenger managerMessenger, const entry_ref *root, bool recursive, + int32 force, BMessage *replyee) : RegistrarThread(name, priority, managerMessenger) , fRoot(root ? *root : entry_ref()) , fRecursive(recursive) diff --git a/src/build/libbe/storage/mime/UpdateMimeInfoThread.cpp b/src/build/libbe/storage/mime/UpdateMimeInfoThread.cpp index 9d282e3b68..e3576dcc1d 100644 --- a/src/build/libbe/storage/mime/UpdateMimeInfoThread.cpp +++ b/src/build/libbe/storage/mime/UpdateMimeInfoThread.cpp @@ -9,7 +9,10 @@ #include "mime/UpdateMimeInfoThread.h" +#include +#include #include +#include #include #include #include @@ -18,11 +21,36 @@ namespace BPrivate { namespace Storage { namespace Mime { +static const char *kAppFlagsAttribute = "BEOS:APP_FLAGS"; + +// update_icon +static status_t +update_icon(BAppFileInfo &appFileInfoRead, BAppFileInfo &appFileInfoWrite, + const char *type, BBitmap &icon, icon_size iconSize) +{ + status_t err = appFileInfoRead.GetIconForType(type, &icon, iconSize); + if (err == B_OK) + err = appFileInfoWrite.SetIconForType(type, &icon, iconSize); + else if (err == B_ENTRY_NOT_FOUND) + err = appFileInfoWrite.SetIconForType(type, NULL, iconSize); + return err; +} + +// is_shared_object_mime_type +static bool +is_shared_object_mime_type(BMimeType &type) +{ + return (type == "application/x-vnd.Be-elfexecutable"); +} + + // constructor //! Creates a new UpdateMimeInfoThread object UpdateMimeInfoThread::UpdateMimeInfoThread(const char *name, int32 priority, - BMessenger managerMessenger, const entry_ref *root, bool recursive, bool force, BMessage *replyee) - : MimeUpdateThread(name, priority, managerMessenger, root, recursive, force, replyee) + BMessenger managerMessenger, const entry_ref *root, bool recursive, + int32 force, BMessage *replyee) + : MimeUpdateThread(name, priority, managerMessenger, root, recursive, force, + replyee) { } @@ -36,34 +64,149 @@ status_t UpdateMimeInfoThread::DoMimeUpdate(const entry_ref *entry, bool *entryIsDir) { status_t err = entry ? B_OK : B_BAD_VALUE; - bool doUpdate = true; + bool updateType = false; + bool updateAppInfo = false; BNode node; if (!err) err = node.SetTo(entry); if (!err && entryIsDir) *entryIsDir = node.IsDirectory(); - if (!err && !fForce) { + if (!err) { // If not forced, only update if the entry has no file type attribute attr_info info; - if (!err) - doUpdate = node.GetAttrInfo(kFileTypeAttr, &info) == B_ENTRY_NOT_FOUND; + if (fForce == B_UPDATE_MIME_INFO_FORCE_UPDATE_ALL + || node.GetAttrInfo(kFileTypeAttr, &info) == B_ENTRY_NOT_FOUND) { + updateType = true; + } + updateAppInfo = (updateType + || fForce == B_UPDATE_MIME_INFO_FORCE_KEEP_TYPE); } - if (!err && doUpdate) { - BMimeType type; + + // guess the MIME type + BMimeType type; + if (!err && (updateType || updateAppInfo)) { err = BMimeType::GuessMimeType(entry, &type); if (!err) err = type.InitCheck(); - if (!err) { - const char *typeStr = type.Type(); - ssize_t len = strlen(typeStr)+1; - ssize_t bytes = node.WriteAttr(kFileTypeAttr, kFileTypeType, 0, typeStr, len); - if (bytes < B_OK) - err = bytes; - else - err = (bytes != len ? (status_t)B_FILE_ERROR : (status_t)B_OK); - } } + + // update the MIME type + if (!err && updateType) { + const char *typeStr = type.Type(); + ssize_t len = strlen(typeStr)+1; + ssize_t bytes = node.WriteAttr(kFileTypeAttr, kFileTypeType, 0, typeStr, + len); + if (bytes < B_OK) + err = bytes; + else + err = (bytes != len ? (status_t)B_FILE_ERROR : (status_t)B_OK); + } + + // update the app file info attributes, if this is a shared object + BFile file; + BAppFileInfo appFileInfoRead; + BAppFileInfo appFileInfoWrite; + if (!err && updateAppInfo && node.IsFile() + && is_shared_object_mime_type(type) + && file.SetTo(entry, B_READ_WRITE) == B_OK + && appFileInfoRead.SetTo(&file) == B_OK + && appFileInfoWrite.SetTo(&file) == B_OK) { + + // we read from resources and write to attributes + appFileInfoRead.SetInfoLocation(B_USE_RESOURCES); + appFileInfoWrite.SetInfoLocation(B_USE_ATTRIBUTES); + + // signature + char signature[B_MIME_TYPE_LENGTH]; + err = appFileInfoRead.GetSignature(signature); + if (err == B_OK) + err = appFileInfoWrite.SetSignature(signature); + else if (err == B_ENTRY_NOT_FOUND) + err = appFileInfoWrite.SetSignature(NULL); + if (err != B_OK) + return err; + + // app flags + uint32 appFlags; + err = appFileInfoRead.GetAppFlags(&appFlags); + if (err == B_OK) { + err = appFileInfoWrite.SetAppFlags(appFlags); + } else if (err == B_ENTRY_NOT_FOUND) { + file.RemoveAttr(kAppFlagsAttribute); + err = B_OK; + } + if (err != B_OK) + return err; + + // supported types + BMessage supportedTypes; + bool hasSupportedTypes = false; + err = appFileInfoRead.GetSupportedTypes(&supportedTypes); + if (err == B_OK) { + err = appFileInfoWrite.SetSupportedTypes(&supportedTypes); + hasSupportedTypes = true; + } else if (err == B_ENTRY_NOT_FOUND) + err = appFileInfoWrite.SetSignature(NULL); + if (err != B_OK) + return err; + + // small icon + BBitmap smallIcon(BRect(0, 0, 15, 15), B_BITMAP_NO_SERVER_LINK, + B_CMAP8); + if (smallIcon.InitCheck() != B_OK) + return smallIcon.InitCheck(); + err = update_icon(appFileInfoRead, appFileInfoWrite, NULL, smallIcon, + B_MINI_ICON); + if (err != B_OK) + return err; + + // large icon + BBitmap largeIcon(BRect(0, 0, 31, 31), B_BITMAP_NO_SERVER_LINK, + B_CMAP8); + if (largeIcon.InitCheck() != B_OK) + return largeIcon.InitCheck(); + err = update_icon(appFileInfoRead, appFileInfoWrite, NULL, largeIcon, + B_LARGE_ICON); + if (err != B_OK) + return err; + + // version infos + const version_kind versionKinds[] + = {B_APP_VERSION_KIND, B_SYSTEM_VERSION_KIND}; + for (int i = 0; i < 2; i++) { + version_kind kind = versionKinds[i]; + version_info versionInfo; + err = appFileInfoRead.GetVersionInfo(&versionInfo, kind); + if (err == B_OK) + err = appFileInfoWrite.SetVersionInfo(&versionInfo, kind); + else if (err == B_ENTRY_NOT_FOUND) + err = appFileInfoWrite.SetVersionInfo(NULL, kind); + if (err != B_OK) + return err; + } + + // icons for supported types + if (hasSupportedTypes) { + const char *supportedType; + for (int32 i = 0; + supportedTypes.FindString("types", i, &supportedType) == B_OK; + i++) { + // small icon + err = update_icon(appFileInfoRead, appFileInfoWrite, + supportedType, smallIcon, B_MINI_ICON); + if (err != B_OK) + return err; + + // large icon + err = update_icon(appFileInfoRead, appFileInfoWrite, + supportedType, largeIcon, B_LARGE_ICON); + if (err != B_OK) + return err; + } + } + } + return err; }