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