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