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