xref: /haiku/src/apps/pairs/Pairs.cpp (revision 22440f4105cafc95cc1d49f9bc65bb395c527d86)
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 
32 const char* kSignature = "application/x-vnd.Haiku-Pairs";
33 
34 static const size_t kMinIconCount = 64;
35 static const size_t kMaxIconCount = 384;
36 
37 
38 //	#pragma mark - Pairs
39 
40 
41 Pairs::Pairs()
42 	:
43 	BApplication(kSignature),
44 	fWindow(NULL)
45 {
46 	_GetVectorIcons();
47 }
48 
49 
50 Pairs::~Pairs()
51 {
52 }
53 
54 
55 void
56 Pairs::ReadyToRun()
57 {
58 	fWindow = new PairsWindow();
59 	fWindow->Show();
60 }
61 
62 
63 void
64 Pairs::RefsReceived(BMessage* message)
65 {
66 	fWindow->PostMessage(message);
67 }
68 
69 
70 void
71 Pairs::MessageReceived(BMessage* message)
72 {
73 	BApplication::MessageReceived(message);
74 }
75 
76 
77 bool
78 Pairs::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 
93 void
94 Pairs::_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 
166 int
167 main(void)
168 {
169 	Pairs pairs;
170 	pairs.Run();
171 
172 	return 0;
173 }
174