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
This commit is contained in:
Ingo Weinhold
2006-01-28 20:20:27 +00:00
parent 15424f3d37
commit 0b537029e3
4 changed files with 181 additions and 29 deletions
+13 -7
View File
@@ -1,7 +1,8 @@
//---------------------------------------------------------------------- /*
// This software is part of the OpenBeOS distribution and is covered * Copyright 2004-2006, Haiku Inc. All Rights Reserved.
// by the OpenBeOS license. * Distributed under the terms of the MIT License.
//--------------------------------------------------------------------- */
/*! /*!
\file Mime.h \file Mime.h
Mime type C functions interface declarations. Mime type C functions interface declarations.
@@ -37,11 +38,18 @@ enum icon_size {
B_MINI_ICON = 16 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 #ifdef __cplusplus
} }
#endif #endif
// OpenBeOS only! // Haiku only!
#ifdef __cplusplus #ifdef __cplusplus
class BBitmap; class BBitmap;
@@ -56,5 +64,3 @@ status_t get_device_icon(const char *dev, BBitmap *icon, icon_size which);
#endif #endif
#endif // _MIME_H #endif // _MIME_H
@@ -23,9 +23,11 @@ namespace BPrivate {
namespace Storage { namespace Storage {
namespace Mime { namespace Mime {
CreateAppMetaMimeThread::CreateAppMetaMimeThread(const char *name, int32 priority, CreateAppMetaMimeThread::CreateAppMetaMimeThread(const char *name,
BMessenger managerMessenger, const entry_ref *root, bool recursive, bool force, BMessage *replyee) int32 priority, BMessenger managerMessenger, const entry_ref *root,
: MimeUpdateThread(name, priority, managerMessenger, root, recursive, force, replyee) bool recursive, int32 force, BMessage *replyee)
: MimeUpdateThread(name, priority, managerMessenger, root, recursive, force,
replyee)
{ {
} }
@@ -42,8 +42,9 @@ namespace Mime {
field detached from the registrar's mime manager looper (though this is not verified). 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. The message will be replied to at the end of the thread's execution.
*/ */
MimeUpdateThread::MimeUpdateThread(const char *name, int32 priority, BMessenger managerMessenger, MimeUpdateThread::MimeUpdateThread(const char *name, int32 priority,
const entry_ref *root, bool recursive, bool force, BMessage *replyee) BMessenger managerMessenger, const entry_ref *root, bool recursive,
int32 force, BMessage *replyee)
: RegistrarThread(name, priority, managerMessenger) : RegistrarThread(name, priority, managerMessenger)
, fRoot(root ? *root : entry_ref()) , fRoot(root ? *root : entry_ref())
, fRecursive(recursive) , fRecursive(recursive)
@@ -9,7 +9,10 @@
#include "mime/UpdateMimeInfoThread.h" #include "mime/UpdateMimeInfoThread.h"
#include <AppFileInfo.h>
#include <Bitmap.h>
#include <fs_attr.h> #include <fs_attr.h>
#include <Message.h>
#include <MimeType.h> #include <MimeType.h>
#include <mime/database_support.h> #include <mime/database_support.h>
#include <Node.h> #include <Node.h>
@@ -18,11 +21,36 @@ namespace BPrivate {
namespace Storage { namespace Storage {
namespace Mime { 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 // constructor
//! Creates a new UpdateMimeInfoThread object //! Creates a new UpdateMimeInfoThread object
UpdateMimeInfoThread::UpdateMimeInfoThread(const char *name, int32 priority, UpdateMimeInfoThread::UpdateMimeInfoThread(const char *name, int32 priority,
BMessenger managerMessenger, const entry_ref *root, bool recursive, bool force, BMessage *replyee) BMessenger managerMessenger, const entry_ref *root, bool recursive,
: MimeUpdateThread(name, priority, managerMessenger, root, recursive, force, replyee) 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) UpdateMimeInfoThread::DoMimeUpdate(const entry_ref *entry, bool *entryIsDir)
{ {
status_t err = entry ? B_OK : B_BAD_VALUE; status_t err = entry ? B_OK : B_BAD_VALUE;
bool doUpdate = true; bool updateType = false;
bool updateAppInfo = false;
BNode node; BNode node;
if (!err) if (!err)
err = node.SetTo(entry); err = node.SetTo(entry);
if (!err && entryIsDir) if (!err && entryIsDir)
*entryIsDir = node.IsDirectory(); *entryIsDir = node.IsDirectory();
if (!err && !fForce) { if (!err) {
// If not forced, only update if the entry has no file type attribute // If not forced, only update if the entry has no file type attribute
attr_info info; attr_info info;
if (!err) if (fForce == B_UPDATE_MIME_INFO_FORCE_UPDATE_ALL
doUpdate = node.GetAttrInfo(kFileTypeAttr, &info) == B_ENTRY_NOT_FOUND; || 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); err = BMimeType::GuessMimeType(entry, &type);
if (!err) if (!err)
err = type.InitCheck(); err = type.InitCheck();
if (!err) { }
const char *typeStr = type.Type();
ssize_t len = strlen(typeStr)+1; // update the MIME type
ssize_t bytes = node.WriteAttr(kFileTypeAttr, kFileTypeType, 0, typeStr, len); if (!err && updateType) {
if (bytes < B_OK) const char *typeStr = type.Type();
err = bytes; ssize_t len = strlen(typeStr)+1;
else ssize_t bytes = node.WriteAttr(kFileTypeAttr, kFileTypeType, 0, typeStr,
err = (bytes != len ? (status_t)B_FILE_ERROR : (status_t)B_OK); 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; return err;
} }