xref: /haiku/src/apps/pairs/Pairs.cpp (revision d4474f3a285509ee559c939a4be669a47241425e)
169e62e48SStephan Aßmus /*
24c587adeSStephan Aßmus  * Copyright 2008 Ralf Schülke, ralf.schuelke@googlemail.com.
3c6b0a589SJohn Scipione  * Copyright 2014 Haiku, Inc. All rights reserved.
4c6b0a589SJohn Scipione  *
5c6b0a589SJohn Scipione  * Distributed under the terms of the MIT License.
6c6b0a589SJohn Scipione  *
7c6b0a589SJohn Scipione  * Authors:
8fdc05529SJohn Scipione  *		Ralf Schülke, ralf.schuelke@googlemail.com
9c6b0a589SJohn Scipione  *		John Scipione, jscipione@gmail.com
1069e62e48SStephan Aßmus  */
1169e62e48SStephan Aßmus 
12c6b0a589SJohn Scipione 
13c6b0a589SJohn Scipione #include "Pairs.h"
14c6b0a589SJohn Scipione 
15*d4474f3aSJohn Scipione #include <stdio.h>
16*d4474f3aSJohn Scipione 	// for snprintf()
1769e62e48SStephan Aßmus #include <stdlib.h>
1869e62e48SStephan Aßmus 
1997e1b053SJohn Scipione #include <Alert.h>
2084df7867SAdrien Destugues #include <Catalog.h>
21*d4474f3aSJohn Scipione #include <Message.h>
2297e1b053SJohn Scipione #include <MimeType.h>
23*d4474f3aSJohn Scipione #include <String.h>
2469e62e48SStephan Aßmus 
2569e62e48SStephan Aßmus #include "PairsWindow.h"
2669e62e48SStephan Aßmus 
27c6b0a589SJohn Scipione 
2897e1b053SJohn Scipione #undef B_TRANSLATION_CONTEXT
2997e1b053SJohn Scipione #define B_TRANSLATION_CONTEXT "Pairs"
3097e1b053SJohn Scipione 
3197e1b053SJohn Scipione 
32f3f9e93aSRyan Leavengood const char* kSignature = "application/x-vnd.Haiku-Pairs";
3369e62e48SStephan Aßmus 
3497e1b053SJohn Scipione static const size_t kMinIconCount = 64;
3597e1b053SJohn Scipione static const size_t kMaxIconCount = 384;
3697e1b053SJohn Scipione 
3769e62e48SStephan Aßmus 
38c6b0a589SJohn Scipione //	#pragma mark - Pairs
39c6b0a589SJohn Scipione 
40c6b0a589SJohn Scipione 
Pairs()4169e62e48SStephan Aßmus Pairs::Pairs()
424c587adeSStephan Aßmus 	:
434c587adeSStephan Aßmus 	BApplication(kSignature),
4469e62e48SStephan Aßmus 	fWindow(NULL)
4569e62e48SStephan Aßmus {
4697e1b053SJohn Scipione 	_GetVectorIcons();
4769e62e48SStephan Aßmus }
4869e62e48SStephan Aßmus 
4969e62e48SStephan Aßmus 
~Pairs()5069e62e48SStephan Aßmus Pairs::~Pairs()
5169e62e48SStephan Aßmus {
5269e62e48SStephan Aßmus }
5369e62e48SStephan Aßmus 
5469e62e48SStephan Aßmus 
5569e62e48SStephan Aßmus void
ReadyToRun()5669e62e48SStephan Aßmus Pairs::ReadyToRun()
5769e62e48SStephan Aßmus {
5869e62e48SStephan Aßmus 	fWindow = new PairsWindow();
5969e62e48SStephan Aßmus 	fWindow->Show();
6069e62e48SStephan Aßmus }
6169e62e48SStephan Aßmus 
6269e62e48SStephan Aßmus 
6369e62e48SStephan Aßmus void
RefsReceived(BMessage * message)6469e62e48SStephan Aßmus Pairs::RefsReceived(BMessage* message)
6569e62e48SStephan Aßmus {
6669e62e48SStephan Aßmus 	fWindow->PostMessage(message);
6769e62e48SStephan Aßmus }
6869e62e48SStephan Aßmus 
6969e62e48SStephan Aßmus 
7069e62e48SStephan Aßmus void
MessageReceived(BMessage * message)7169e62e48SStephan Aßmus Pairs::MessageReceived(BMessage* message)
7269e62e48SStephan Aßmus {
7369e62e48SStephan Aßmus 	BApplication::MessageReceived(message);
7469e62e48SStephan Aßmus }
7569e62e48SStephan Aßmus 
7669e62e48SStephan Aßmus 
7797e1b053SJohn Scipione bool
QuitRequested()7897e1b053SJohn Scipione Pairs::QuitRequested()
7997e1b053SJohn Scipione {
8097e1b053SJohn Scipione 	// delete vector icons
8197e1b053SJohn Scipione 	for (IconMap::iterator iter = fIconMap.begin(); iter != fIconMap.end();
8297e1b053SJohn Scipione 			++iter) {
8397e1b053SJohn Scipione 		delete fIconMap[iter->first];
8497e1b053SJohn Scipione 	}
8597e1b053SJohn Scipione 
8697e1b053SJohn Scipione 	return true;
8797e1b053SJohn Scipione }
8897e1b053SJohn Scipione 
8997e1b053SJohn Scipione 
9097e1b053SJohn Scipione //	#pragma mark - Pairs private methods
9197e1b053SJohn Scipione 
9297e1b053SJohn Scipione 
9397e1b053SJohn Scipione void
_GetVectorIcons()9497e1b053SJohn Scipione Pairs::_GetVectorIcons()
9597e1b053SJohn Scipione {
9697e1b053SJohn Scipione 	// Load vector icons from the MIME type database and add a pointer to them
9797e1b053SJohn Scipione 	// into a std::map keyed by a generated hash.
9897e1b053SJohn Scipione 
9997e1b053SJohn Scipione 	BMessage types;
10097e1b053SJohn Scipione 	if (BMimeType::GetInstalledTypes("application", &types) != B_OK)
10197e1b053SJohn Scipione 		return;
10297e1b053SJohn Scipione 
10397e1b053SJohn Scipione 	const char* type;
10497e1b053SJohn Scipione 	for (int32 i = 0; types.FindString("types", i, &type) == B_OK; i++) {
10597e1b053SJohn Scipione 		BMimeType mimeType(type);
10697e1b053SJohn Scipione 		if (mimeType.InitCheck() != B_OK)
10797e1b053SJohn Scipione 			continue;
10897e1b053SJohn Scipione 
10997e1b053SJohn Scipione 		uint8* data;
11097e1b053SJohn Scipione 		size_t size;
11197e1b053SJohn Scipione 
11297e1b053SJohn Scipione 		if (mimeType.GetIcon(&data, &size) != B_OK) {
11397e1b053SJohn Scipione 			// didn't find an icon
11497e1b053SJohn Scipione 			continue;
11597e1b053SJohn Scipione 		}
11697e1b053SJohn Scipione 
11797e1b053SJohn Scipione 		size_t hash = 0xdeadbeef;
11897e1b053SJohn Scipione 		for (size_t i = 0; i < size; i++)
11997e1b053SJohn Scipione 			hash = 31 * hash + data[i];
12097e1b053SJohn Scipione 
12197e1b053SJohn Scipione 		if (fIconMap.find(hash) != fIconMap.end()) {
12297e1b053SJohn Scipione 			// key has already been added to the map
12397e1b053SJohn Scipione 			delete[] data;
12497e1b053SJohn Scipione 			continue;
12597e1b053SJohn Scipione 		}
12697e1b053SJohn Scipione 
12797e1b053SJohn Scipione 		vector_icon* icon = (vector_icon*)malloc(sizeof(vector_icon));
12897e1b053SJohn Scipione 		if (icon == NULL) {
12997e1b053SJohn Scipione 			delete[] data;
13097e1b053SJohn Scipione 			free(icon);
13197e1b053SJohn Scipione 			continue;
13297e1b053SJohn Scipione 		}
13397e1b053SJohn Scipione 
13497e1b053SJohn Scipione 		icon->data = data;
13597e1b053SJohn Scipione 		icon->size = size;
13697e1b053SJohn Scipione 
13797e1b053SJohn Scipione 		// found a vector icon, add it to the list
13897e1b053SJohn Scipione 		fIconMap[hash] = icon;
13997e1b053SJohn Scipione 		if (fIconMap.size() >= kMaxIconCount) {
14097e1b053SJohn Scipione 			// this is enough to choose from, stop eating memory...
14197e1b053SJohn Scipione 			return;
14297e1b053SJohn Scipione 		}
14397e1b053SJohn Scipione 	}
14497e1b053SJohn Scipione 
14597e1b053SJohn Scipione 	if (fIconMap.size() < kMinIconCount) {
14697e1b053SJohn Scipione 		char buffer[512];
14797e1b053SJohn Scipione 		snprintf(buffer, sizeof(buffer),
14897e1b053SJohn Scipione 			B_TRANSLATE_COMMENT("Pairs did not find enough vector icons "
14997e1b053SJohn Scipione 			"to start; it needs at least %zu, found %zu.\n",
15097e1b053SJohn Scipione 			"Don't translate \"%zu\", but make sure to keep them."),
15197e1b053SJohn Scipione 			kMinIconCount, fIconMap.size());
15297e1b053SJohn Scipione 		BString messageString(buffer);
15397e1b053SJohn Scipione 		BAlert* alert = new BAlert("Fatal", messageString.String(),
15497e1b053SJohn Scipione 			B_TRANSLATE("OK"), NULL, NULL, B_WIDTH_FROM_WIDEST,
15597e1b053SJohn Scipione 			B_STOP_ALERT);
15697e1b053SJohn Scipione 		alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
15797e1b053SJohn Scipione 		alert->Go();
15897e1b053SJohn Scipione 		exit(1);
15997e1b053SJohn Scipione 	}
16097e1b053SJohn Scipione }
16197e1b053SJohn Scipione 
16297e1b053SJohn Scipione 
163c6b0a589SJohn Scipione //	#pragma mark - main
164c6b0a589SJohn Scipione 
165c6b0a589SJohn Scipione 
16669e62e48SStephan Aßmus int
main(void)16769e62e48SStephan Aßmus main(void)
16869e62e48SStephan Aßmus {
16969e62e48SStephan Aßmus 	Pairs pairs;
17069e62e48SStephan Aßmus 	pairs.Run();
17169e62e48SStephan Aßmus 
17269e62e48SStephan Aßmus 	return 0;
17369e62e48SStephan Aßmus }
174