xref: /haiku/src/apps/showimage/SupportingAppsMenu.cpp (revision 4c07199d8201fcf267e90be0d24b76799d03cea6)
1 /*
2  * Copyright 2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3  * Copyright 2023, Haiku, Inc.
4  * Distributed under the terms of the MIT License.
5  */
6 
7 
8 #include "SupportingAppsMenu.h"
9 
10 #include <AppFileInfo.h>
11 #include <Menu.h>
12 #include <MenuItem.h>
13 
14 
15 static int
16 compare_menu_items(const void* _a, const void* _b)
17 {
18 	BMenuItem* a = *(BMenuItem**)_a;
19 	BMenuItem* b = *(BMenuItem**)_b;
20 
21 	return strcasecmp(a->Label(), b->Label());
22 }
23 
24 
25 static BMenuItem*
26 create_application_item(const char* signature, uint32 what)
27 {
28 	char name[B_FILE_NAME_LENGTH];
29 
30 	BMessage* message = new BMessage(what);
31 	message->AddString("signature", signature);
32 
33 	BMimeType applicationType(signature);
34 	if (applicationType.GetShortDescription(name) == B_OK)
35 		return new BMenuItem(name, message);
36 
37 	return new BMenuItem(signature, message);
38 }
39 
40 
41 //	#pragma mark - Public functions
42 
43 
44 void
45 update_supporting_apps_menu(BMenu* menu, BMimeType* type, uint32 what, BHandler* target)
46 {
47 	// clear menu
48 	for (int32 i = menu->CountItems(); i-- > 0;)
49 		delete menu->RemoveItem(i);
50 
51 	// fill it again
52 	BMessage applications;
53 	if (type == NULL || type->GetSupportingApps(&applications) != B_OK)
54 		return;
55 
56 	int32 lastFullSupport;
57 	if (applications.FindInt32("be:sub", &lastFullSupport) != B_OK)
58 		lastFullSupport = -1;
59 
60 	BList subList;
61 	BList superList;
62 
63 	const char* signature;
64 	int32 i = 0;
65 	while (applications.FindString("applications", i, &signature) == B_OK) {
66 		if (!strcasecmp(signature, kApplicationSignature)) {
67 			i++;
68 			continue;
69 		}
70 
71 		BMenuItem* item = create_application_item(signature, what);
72 		item->SetTarget(target);
73 
74 		if (i < lastFullSupport)
75 			subList.AddItem(item);
76 		else
77 			superList.AddItem(item);
78 
79 		i++;
80 	}
81 
82 	// sort lists
83 	subList.SortItems(compare_menu_items);
84 	superList.SortItems(compare_menu_items);
85 
86 	// add lists to the menu
87 	for (int32 i = 0; i < subList.CountItems(); i++)
88 		menu->AddItem((BMenuItem*)subList.ItemAt(i));
89 
90 	// Add type separator
91 	if (superList.CountItems() != 0 && subList.CountItems() != 0)
92 		menu->AddSeparatorItem();
93 
94 	for (int32 i = 0; i < superList.CountItems(); i++)
95 		menu->AddItem((BMenuItem*)superList.ItemAt(i));
96 
97 	for (int32 index = 0; index < menu->CountItems(); index++) {
98 		BMenuItem* item = menu->ItemAt(index);
99 		if (item == NULL)
100 			continue;
101 
102 		if (item->Message() == NULL
103 			|| item->Message()->FindString("signature", &signature) != B_OK)
104 			continue;
105 	}
106 }
107