1/* 2 * Copyright 2011-2016, Haiku, Inc. All rights reserved. 3 * Copyright 2011, Clemens Zeidler <haiku@clemens-zeidler.de> 4 * Distributed under the terms of the MIT License. 5 */ 6 7 8#include "FilterList.h" 9 10#include <set> 11#include <stdio.h> 12 13#include <Directory.h> 14#include <PathFinder.h> 15#include <Path.h> 16 17 18FilterList::FilterList(direction dir) 19 : 20 fDirection(dir) 21{ 22} 23 24 25FilterList::~FilterList() 26{ 27 _MakeEmpty(); 28} 29 30 31void 32FilterList::Reload() 33{ 34 _MakeEmpty(); 35 36 std::set<BString> knownNames; 37 38 BString subPath("mail_daemon/"); 39 subPath << (fDirection == kIncoming 40 ? "inbound_filters" : "outbound_filters"); 41 42 BStringList paths; 43 BPathFinder().FindPaths(B_FIND_PATH_ADD_ONS_DIRECTORY, subPath, paths); 44 for (int32 i = 0; i < paths.CountStrings(); i++) { 45 BPath path(paths.StringAt(i)); 46 47 BDirectory dir(path.Path()); 48 if (dir.InitCheck() != B_OK) 49 continue; 50 51 BEntry entry; 52 while (dir.GetNextEntry(&entry) == B_OK) { 53 // Ignore entries we already had before (ie., user add-ons are 54 // overriding system add-ons) 55 if (knownNames.find(entry.Name()) != knownNames.end()) 56 continue; 57 58 if (_LoadAddOn(entry) == B_OK) 59 knownNames.insert(entry.Name()); 60 } 61 } 62} 63 64 65int32 66FilterList::CountInfos() const 67{ 68 return fList.size(); 69} 70 71 72const FilterInfo& 73FilterList::InfoAt(int32 index) const 74{ 75 return fList[index]; 76} 77 78 79int32 80FilterList::InfoIndexFor(const entry_ref& ref) const 81{ 82 for (size_t i = 0; i < fList.size(); i++) { 83 const FilterInfo& info = fList[i]; 84 if (info.ref == ref) 85 return i; 86 } 87 return -1; 88} 89 90 91BString 92FilterList::SimpleName(int32 index, 93 const BMailAccountSettings& accountSettings) const 94{ 95 return DescriptiveName(index, accountSettings, NULL); 96} 97 98 99BString 100FilterList::SimpleName(const entry_ref& ref, 101 const BMailAccountSettings& accountSettings) const 102{ 103 return DescriptiveName(InfoIndexFor(ref), accountSettings, NULL); 104} 105 106 107BString 108FilterList::DescriptiveName(int32 index, 109 const BMailAccountSettings& accountSettings, 110 const BMailAddOnSettings* settings) const 111{ 112 if (index < 0 || index >= CountInfos()) 113 return "-"; 114 115 const FilterInfo& info = InfoAt(index); 116 return info.name(accountSettings, settings); 117} 118 119 120BString 121FilterList::DescriptiveName(const entry_ref& ref, 122 const BMailAccountSettings& accountSettings, 123 const BMailAddOnSettings* settings) const 124{ 125 return DescriptiveName(InfoIndexFor(ref), accountSettings, settings); 126} 127 128 129BMailSettingsView* 130FilterList::CreateSettingsView(const BMailAccountSettings& accountSettings, 131 const BMailAddOnSettings& settings) 132{ 133 const entry_ref& ref = settings.AddOnRef(); 134 int32 index = InfoIndexFor(ref); 135 if (index < 0) 136 return NULL; 137 138 const FilterInfo& info = InfoAt(index); 139 return info.instantiateSettingsView(accountSettings, settings); 140} 141 142 143void 144FilterList::_MakeEmpty() 145{ 146 for (size_t i = 0; i < fList.size(); i++) { 147 FilterInfo& info = fList[i]; 148 unload_add_on(info.image); 149 } 150 fList.clear(); 151} 152 153 154status_t 155FilterList::_LoadAddOn(BEntry& entry) 156{ 157 FilterInfo info; 158 159 BPath path(&entry); 160 info.image = load_add_on(path.Path()); 161 if (info.image < 0) 162 return info.image; 163 164 status_t status = get_image_symbol(info.image, 165 "instantiate_filter_settings_view", B_SYMBOL_TYPE_TEXT, 166 (void**)&info.instantiateSettingsView); 167 if (status == B_OK) { 168 status = get_image_symbol(info.image, "filter_name", B_SYMBOL_TYPE_TEXT, 169 (void**)&info.name); 170 } 171 if (status != B_OK) { 172 fprintf(stderr, "Filter \"%s\" misses required hooks!\n", path.Path()); 173 unload_add_on(info.image); 174 return B_NAME_NOT_FOUND; 175 } 176 177 entry.GetRef(&info.ref); 178 fList.push_back(info); 179 return B_OK; 180} 181