1/* 2 * Copyright 2008 Ralf Sch��lke, ralf.schuelke@googlemail.com. 3 * Copyright 2014 Haiku, Inc. All rights reserved. 4 * 5 * Distributed under the terms of the MIT License. 6 * 7 * Authors: 8 * Ralf Sch��lke, ralf.schuelke@googlemail.com 9 * John Scipione, jscipione@gmail.com 10 */ 11 12 13#include "Pairs.h" 14 15#include <stdio.h> 16 // for snprintf() 17#include <stdlib.h> 18 19#include <Alert.h> 20#include <Catalog.h> 21#include <Message.h> 22#include <MimeType.h> 23#include <String.h> 24 25#include "PairsWindow.h" 26 27 28#undef B_TRANSLATION_CONTEXT 29#define B_TRANSLATION_CONTEXT "Pairs" 30 31 32const char* kSignature = "application/x-vnd.Haiku-Pairs"; 33 34static const size_t kMinIconCount = 64; 35static const size_t kMaxIconCount = 384; 36 37 38// #pragma mark - Pairs 39 40 41Pairs::Pairs() 42 : 43 BApplication(kSignature), 44 fWindow(NULL) 45{ 46 _GetVectorIcons(); 47} 48 49 50Pairs::~Pairs() 51{ 52} 53 54 55void 56Pairs::ReadyToRun() 57{ 58 fWindow = new PairsWindow(); 59 fWindow->Show(); 60} 61 62 63void 64Pairs::RefsReceived(BMessage* message) 65{ 66 fWindow->PostMessage(message); 67} 68 69 70void 71Pairs::MessageReceived(BMessage* message) 72{ 73 BApplication::MessageReceived(message); 74} 75 76 77bool 78Pairs::QuitRequested() 79{ 80 // delete vector icons 81 for (IconMap::iterator iter = fIconMap.begin(); iter != fIconMap.end(); 82 ++iter) { 83 delete fIconMap[iter->first]; 84 } 85 86 return true; 87} 88 89 90// #pragma mark - Pairs private methods 91 92 93void 94Pairs::_GetVectorIcons() 95{ 96 // Load vector icons from the MIME type database and add a pointer to them 97 // into a std::map keyed by a generated hash. 98 99 BMessage types; 100 if (BMimeType::GetInstalledTypes("application", &types) != B_OK) 101 return; 102 103 const char* type; 104 for (int32 i = 0; types.FindString("types", i, &type) == B_OK; i++) { 105 BMimeType mimeType(type); 106 if (mimeType.InitCheck() != B_OK) 107 continue; 108 109 uint8* data; 110 size_t size; 111 112 if (mimeType.GetIcon(&data, &size) != B_OK) { 113 // didn't find an icon 114 continue; 115 } 116 117 size_t hash = 0xdeadbeef; 118 for (size_t i = 0; i < size; i++) 119 hash = 31 * hash + data[i]; 120 121 if (fIconMap.find(hash) != fIconMap.end()) { 122 // key has already been added to the map 123 delete[] data; 124 continue; 125 } 126 127 vector_icon* icon = (vector_icon*)malloc(sizeof(vector_icon)); 128 if (icon == NULL) { 129 delete[] data; 130 free(icon); 131 continue; 132 } 133 134 icon->data = data; 135 icon->size = size; 136 137 // found a vector icon, add it to the list 138 fIconMap[hash] = icon; 139 if (fIconMap.size() >= kMaxIconCount) { 140 // this is enough to choose from, stop eating memory... 141 return; 142 } 143 } 144 145 if (fIconMap.size() < kMinIconCount) { 146 char buffer[512]; 147 snprintf(buffer, sizeof(buffer), 148 B_TRANSLATE_COMMENT("Pairs did not find enough vector icons " 149 "to start; it needs at least %zu, found %zu.\n", 150 "Don't translate \"%zu\", but make sure to keep them."), 151 kMinIconCount, fIconMap.size()); 152 BString messageString(buffer); 153 BAlert* alert = new BAlert("Fatal", messageString.String(), 154 B_TRANSLATE("OK"), NULL, NULL, B_WIDTH_FROM_WIDEST, 155 B_STOP_ALERT); 156 alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); 157 alert->Go(); 158 exit(1); 159 } 160} 161 162 163// #pragma mark - main 164 165 166int 167main(void) 168{ 169 Pairs pairs; 170 pairs.Run(); 171 172 return 0; 173} 174