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