xref: /haiku/src/servers/registrar/mime/CreateAppMetaMimeThread.cpp (revision 746cac055adc6ac3308c7bc2d29040fb95689cc9)
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 #include "Database.h"
26 
27 
28 namespace BPrivate {
29 namespace Storage {
30 namespace Mime {
31 
32 
33 CreateAppMetaMimeThread::CreateAppMetaMimeThread(const char *name,
34 	int32 priority, Database *database, BMessenger managerMessenger,
35 	const entry_ref *root, bool recursive, int32 force, BMessage *replyee)
36 	: MimeUpdateThread(name, priority, database, managerMessenger, root,
37 		recursive, force, replyee)
38 {
39 }
40 
41 
42 status_t
43 CreateAppMetaMimeThread::DoMimeUpdate(const entry_ref* ref, bool* _entryIsDir)
44 {
45 	if (ref == NULL)
46 		return B_BAD_VALUE;
47 
48 	BNode typeNode;
49 
50 	BFile file;
51 	status_t status = file.SetTo(ref, B_READ_ONLY);
52 	if (status < B_OK)
53 		return status;
54 
55 	bool isDir = file.IsDirectory();
56 	if (_entryIsDir != NULL)
57 		*_entryIsDir = isDir;
58 
59 	if (isDir)
60 		return B_OK;
61 
62 	BAppFileInfo appInfo(&file);
63 	status = appInfo.InitCheck();
64 	if (status < B_OK)
65 		return status;
66 
67 	// Read the app sig (which consequently keeps us from updating
68 	// non-applications, since we get an error if the file has no
69 	// app sig)
70 	BString signature;
71 	status = file.ReadAttrString("BEOS:APP_SIG", &signature);
72 	if (status < B_OK)
73 		return B_BAD_TYPE;
74 
75 	// Init our various objects
76 
77 	BMimeType mime;
78 	status = mime.SetTo(signature.String());
79 	if (status < B_OK)
80 		return status;
81 
82 	InstallNotificationDeferrer _(fDatabase, signature.String());
83 
84 	if (!mime.IsInstalled())
85 		mime.Install();
86 
87 	BString path = "/";
88 	path.Append(signature);
89 	path.ToLower();
90 		// Signatures and MIME types are case insensitive, but we want to
91 		// preserve the case wherever possible
92 	path.Prepend(kDatabaseDir.c_str());
93 
94 	status = typeNode.SetTo(path.String());
95 	if (status < B_OK)
96 		return status;
97 
98 	// Preferred App
99 	attr_info info;
100 	if (status == B_OK && (fForce || typeNode.GetAttrInfo(kPreferredAppAttr, &info) != B_OK))
101 		status = mime.SetPreferredApp(signature.String());
102 
103 	// Short Description (name of the application)
104 	if (status == B_OK && (fForce || typeNode.GetAttrInfo(kShortDescriptionAttr, &info) != B_OK))
105 		status = mime.SetShortDescription(ref->name);
106 
107 	// App Hint
108 	if (status == B_OK && (fForce || typeNode.GetAttrInfo(kAppHintAttr, &info) != B_OK))
109 		status = mime.SetAppHint(ref);
110 
111 	// Vector Icon
112 	if (status == B_OK && (fForce || typeNode.GetAttrInfo(kIconAttr, &info) != B_OK)) {
113 		uint8* data = NULL;
114 		size_t size = 0;
115 		if (appInfo.GetIcon(&data, &size) == B_OK) {
116 			status = mime.SetIcon(data, size);
117 			free(data);
118 		}
119 	}
120 	// Mini Icon
121 	BBitmap miniIcon(BRect(0, 0, 15, 15), B_BITMAP_NO_SERVER_LINK, B_CMAP8);
122 	if (status == B_OK && (fForce || typeNode.GetAttrInfo(kMiniIconAttr, &info) != B_OK)) {
123 		if (appInfo.GetIcon(&miniIcon, B_MINI_ICON) == B_OK)
124 			status = mime.SetIcon(&miniIcon, B_MINI_ICON);
125 	}
126 	// Large Icon
127 	BBitmap largeIcon(BRect(0, 0, 31, 31), B_BITMAP_NO_SERVER_LINK, B_CMAP8);
128 	if (status == B_OK && (fForce || typeNode.GetAttrInfo(kLargeIconAttr, &info) != B_OK)) {
129 		if (appInfo.GetIcon(&largeIcon, B_LARGE_ICON) == B_OK)
130 			status = mime.SetIcon(&largeIcon, B_LARGE_ICON);
131 	}
132 
133 	// Supported Types
134 	bool setSupportedTypes = false;
135 	BMessage supportedTypes;
136 	if (status == B_OK && (fForce || typeNode.GetAttrInfo(kSupportedTypesAttr, &info) != B_OK)) {
137 		if (appInfo.GetSupportedTypes(&supportedTypes) == B_OK)
138 			setSupportedTypes = true;
139 	}
140 
141 	// defer notifications for supported types
142 	const char* type;
143 	for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK; i++)
144 		fDatabase->DeferInstallNotification(type);
145 
146 	// set supported types
147 	if (setSupportedTypes)
148 		status = mime.SetSupportedTypes(&supportedTypes);
149 
150 	// Icons for supported types
151 	for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK; i++) {
152 		// vector icon
153 		uint8* data = NULL;
154 		size_t size = 0;
155 		if (status == B_OK && appInfo.GetIconForType(type, &data, &size) == B_OK) {
156 			status = mime.SetIconForType(type, data, size);
157 			free(data);
158 		}
159 		// mini icon
160 		if (status == B_OK && appInfo.GetIconForType(type, &miniIcon, B_MINI_ICON) == B_OK)
161 			status = mime.SetIconForType(type, &miniIcon, B_MINI_ICON);
162 		// large icon
163 		if (status == B_OK && appInfo.GetIconForType(type, &largeIcon, B_LARGE_ICON) == B_OK)
164 			status = mime.SetIconForType(type, &largeIcon, B_LARGE_ICON);
165 	}
166 
167 	// undefer notifications for supported types
168 	for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK; i++)
169 		fDatabase->UndeferInstallNotification(type);
170 
171 	return status;
172 }
173 
174 }	// namespace Mime
175 }	// namespace Storage
176 }	// namespace BPrivate
177 
178