xref: /haiku/src/servers/registrar/mime/CreateAppMetaMimeThread.cpp (revision f82c11c0793269f483e03fc6f1a3a93aa1d092f0)
1 /*
2  * Copyright 2002-2006, Haiku.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Tyler Dauwalder
7  *		Axel Dörfler, axeld@pinc-software.de
8  */
9 
10 
11 #include "CreateAppMetaMimeThread.h"
12 
13 #include <stdio.h>
14 
15 #include <AppFileInfo.h>
16 #include <Bitmap.h>
17 #include <fs_attr.h>
18 #include <MimeType.h>
19 #include <Node.h>
20 #include <Path.h>
21 #include <String.h>
22 
23 #include <mime/database_support.h>
24 
25 namespace BPrivate {
26 namespace Storage {
27 namespace Mime {
28 
29 
30 CreateAppMetaMimeThread::CreateAppMetaMimeThread(const char *name,
31 	int32 priority, BMessenger managerMessenger, const entry_ref *root,
32 	bool recursive, int32 force, BMessage *replyee)
33 	: MimeUpdateThread(name, priority, managerMessenger, root, recursive, force,
34 		replyee)
35 {
36 }
37 
38 
39 status_t
40 CreateAppMetaMimeThread::DoMimeUpdate(const entry_ref* ref, bool* _entryIsDir)
41 {
42 	if (ref == NULL)
43 		return B_BAD_VALUE;
44 
45 	BNode typeNode;
46 
47 	BFile file;
48 	status_t status = file.SetTo(ref, B_READ_ONLY);
49 	if (status < B_OK)
50 		return status;
51 
52 	BAppFileInfo appInfo(&file);
53 	status = appInfo.InitCheck();
54 	if (status < B_OK)
55 		return status;
56 
57 	// Read the app sig (which consequently keeps us from updating
58 	// non-applications, since we get an error if the file has no
59 	// app sig)
60 	BString signature;
61 	status = file.ReadAttrString("BEOS:APP_SIG", &signature);
62 	if (status < B_OK)
63 		return B_BAD_TYPE;
64 
65 	// Init our various objects
66 
67 	BMimeType mime;
68 	status = mime.SetTo(signature.String());
69 	if (status < B_OK)
70 		return status;
71 
72 	if (!mime.IsInstalled())
73 		mime.Install();
74 
75 	BString path = "/";
76 	path.Append(signature);
77 	path.ToLower();
78 		// Signatures and MIME types are case insensitive, but we want to
79 		// preserve the case wherever possible
80 	path.Prepend(kDatabaseDir.c_str());
81 
82 	status = typeNode.SetTo(path.String());
83 	if (status < B_OK)
84 		return status;
85 
86 	// Preferred App
87 	attr_info info;
88 	if (status == B_OK && (fForce || typeNode.GetAttrInfo(kPreferredAppAttr, &info) != B_OK))
89 		status = mime.SetPreferredApp(signature.String());
90 
91 	// Short Description (name of the application)
92 	if (status == B_OK && (fForce || typeNode.GetAttrInfo(kShortDescriptionAttr, &info) != B_OK))
93 		status = mime.SetShortDescription(ref->name);
94 
95 	// App Hint
96 	if (status == B_OK && (fForce || typeNode.GetAttrInfo(kAppHintAttr, &info) != B_OK))
97 		status = mime.SetAppHint(ref);
98 
99 	// Vector Icon
100 	if (status == B_OK && (fForce || typeNode.GetAttrInfo(kIconAttr, &info) != B_OK)) {
101 		uint8* data = NULL;
102 		size_t size = 0;
103 		if (appInfo.GetIcon(&data, &size) == B_OK) {
104 			status = mime.SetIcon(data, size);
105 			free(data);
106 		}
107 	}
108 	// Mini Icon
109 	BBitmap miniIcon(BRect(0, 0, 15, 15), B_BITMAP_NO_SERVER_LINK, B_CMAP8);
110 	if (status == B_OK && (fForce || typeNode.GetAttrInfo(kMiniIconAttr, &info) != B_OK)) {
111 		if (appInfo.GetIcon(&miniIcon, B_MINI_ICON) == B_OK)
112 			status = mime.SetIcon(&miniIcon, B_MINI_ICON);
113 	}
114 	// Large Icon
115 	BBitmap largeIcon(BRect(0, 0, 31, 31), B_BITMAP_NO_SERVER_LINK, B_CMAP8);
116 	if (status == B_OK && (fForce || typeNode.GetAttrInfo(kLargeIconAttr, &info) != B_OK)) {
117 		if (appInfo.GetIcon(&largeIcon, B_LARGE_ICON) == B_OK)
118 			status = mime.SetIcon(&largeIcon, B_LARGE_ICON);
119 	}
120 
121 	// Supported Types
122 	BMessage supportedTypes;
123 	if (status == B_OK && (fForce || typeNode.GetAttrInfo(kSupportedTypesAttr, &info) != B_OK)) {
124 		if (appInfo.GetSupportedTypes(&supportedTypes) == B_OK)
125 			status = mime.SetSupportedTypes(&supportedTypes);
126 	}
127 
128 	// Icons for supported types
129 	const char* type;
130 	for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK; i++) {
131 		// vector icon
132 		uint8* data = NULL;
133 		size_t size = 0;
134 		if (status == B_OK && appInfo.GetIconForType(type, &data, &size) == B_OK) {
135 			status = mime.SetIconForType(type, data, size);
136 			free(data);
137 		}
138 		// mini icon
139 		if (status == B_OK && appInfo.GetIconForType(type, &miniIcon, B_MINI_ICON) == B_OK)
140 			status = mime.SetIconForType(type, &miniIcon, B_MINI_ICON);
141 		// large icon
142 		if (status == B_OK && appInfo.GetIconForType(type, &largeIcon, B_LARGE_ICON) == B_OK)
143 			status = mime.SetIconForType(type, &largeIcon, B_LARGE_ICON);
144 	}
145 
146 	if (status == B_OK && _entryIsDir != NULL)
147 		*_entryIsDir = file.IsDirectory();
148 
149 	return status;
150 }
151 
152 }	// namespace Mime
153 }	// namespace Storage
154 }	// namespace BPrivate
155 
156