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
15static int
16compare_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
25static BMenuItem*
26create_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
44void
45update_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