Major mail protocol/filter settings rework.

* Instead of abusing BArchive::Archive() we now use a BMailSettingsView as
  a base view for all filter/protocol settings that works with
  BMailAddOnSettings.
* Cleanups in E-mail which is now completely layout friendly. But also still
  crashes when changing the views.
This commit is contained in:
Axel Dörfler
2015-01-06 15:22:56 +01:00
parent a6943acbe0
commit ca3341c7b4
26 changed files with 495 additions and 348 deletions
+21 -17
View File
@@ -120,17 +120,18 @@ AccountConfigView::UpdateViews()
// #pragma mark -
ProtocolConfigView::ProtocolConfigView(BMailAccountSettings& accountSettings,
const entry_ref& ref, BMailProtocolSettings& settings)
ProtocolSettingsView::ProtocolSettingsView(const entry_ref& ref,
const BMailAccountSettings& accountSettings,
BMailProtocolSettings& settings)
:
BBox("protocol"),
fSettings(settings),
fConfigView(NULL)
fSettingsView(NULL)
{
status_t status = _CreateConfigView(ref, settings, accountSettings);
BView* view = fConfigView;
status_t status = _CreateSettingsView(ref, accountSettings, settings);
BView* view = fSettingsView;
if (fConfigView != NULL) {
if (status == B_OK) {
SetLabel(ref.name);
} else {
BString text(B_TRANSLATE("An error occurred while creating the "
@@ -151,30 +152,33 @@ ProtocolConfigView::ProtocolConfigView(BMailAccountSettings& accountSettings,
void
ProtocolConfigView::DetachedFromWindow()
ProtocolSettingsView::DetachedFromWindow()
{
if (fConfigView == NULL)
if (fSettingsView == NULL)
return;
BMessage settings;
if (fConfigView->Archive(&settings) != B_OK)
if (fSettingsView->Archive(&settings) != B_OK)
return;
fSettings.MakeEmpty();
fSettings.Append(settings);
RemoveChild(fConfigView);
delete fConfigView;
fConfigView = NULL;
RemoveChild(fSettingsView);
delete fSettingsView;
fSettingsView = NULL;
unload_add_on(fImage);
}
status_t
ProtocolConfigView::_CreateConfigView(const entry_ref& ref,
BMailProtocolSettings& settings, BMailAccountSettings& accountSettings)
ProtocolSettingsView::_CreateSettingsView(const entry_ref& ref,
const BMailAccountSettings& accountSettings,
BMailProtocolSettings& settings)
{
BView* (*instantiateConfig)(BMailProtocolSettings& settings,
BMailAccountSettings& accountSettings);
BMailSettingsView* (*instantiateConfig)(
const BMailAccountSettings& accountSettings,
BMailProtocolSettings& settings);
BPath path(&ref);
image_id image = load_add_on(path.Path());
if (image < 0)
@@ -187,6 +191,6 @@ ProtocolConfigView::_CreateConfigView(const entry_ref& ref,
}
fImage = image;
fConfigView = instantiateConfig(settings, accountSettings);
fSettingsView = instantiateConfig(accountSettings, settings);
return B_OK;
}
+11 -9
View File
@@ -12,8 +12,11 @@
#include <Box.h>
#include <image.h>
#include "MailSettings.h"
#include <MailSettingsView.h>
#include <MailSettings.h>
#include <ProtocolConfigView.h>
#include "FilterConfigView.h"
@@ -43,23 +46,22 @@ private:
};
class ProtocolConfigView : public BBox {
class ProtocolSettingsView : public BBox {
public:
ProtocolConfigView(
BMailAccountSettings& accountSettings,
const entry_ref& ref,
ProtocolSettingsView(const entry_ref& ref,
const BMailAccountSettings& accountSettings,
BMailProtocolSettings& settings);
void DetachedFromWindow();
private:
status_t _CreateConfigView(const entry_ref& ref,
BMailProtocolSettings& settings,
BMailAccountSettings& accountSettings);
status_t _CreateSettingsView(const entry_ref& ref,
const BMailAccountSettings& accountSettings,
BMailProtocolSettings& settings);
private:
BMailProtocolSettings& fSettings;
BView* fConfigView;
BMailSettingsView* fSettingsView;
image_id fImage;
};
+4 -4
View File
@@ -831,13 +831,13 @@ ConfigWindow::_AccountSelected(AccountItem* item)
break;
case INBOUND_ITEM:
view = new ProtocolConfigView(*account, account->InboundAddOnRef(),
account->InboundSettings());
view = new ProtocolSettingsView(account->InboundAddOnRef(),
*account, account->InboundSettings());
break;
case OUTBOUND_ITEM:
view = new ProtocolConfigView(*account, account->OutboundAddOnRef(),
account->OutboundSettings());
view = new ProtocolSettingsView(account->OutboundAddOnRef(),
*account, account->OutboundSettings());
break;
case FILTER_ITEM:
+33 -35
View File
@@ -177,29 +177,30 @@ private:
// #pragma mark -
class FilterConfigBox : public BBox {
class FilterSettingsView : public BBox {
public:
FilterConfigBox(const BString& label, BView* child)
FilterSettingsView(const BString& label, BMailSettingsView* settingsView)
:
BBox(BRect(0,0,100,100)),
fChild(child)
BBox("filter"),
fSettingsView(settingsView)
{
SetLabel(label);
float w = child->Bounds().Width();
float h = child->Bounds().Height();
child->MoveTo(3, 13);
ResizeTo(w + 6, h + 16);
AddChild(child);
BView* contents = new BView("contents", 0);
AddChild(contents);
BLayoutBuilder::Group<>(contents, B_VERTICAL)
.SetInsets(B_USE_DEFAULT_SPACING)
.Add(fSettingsView);
}
status_t
ArchiveAddOn(BMessage* into) const
status_t SaveInto(BMailAddOnSettings& settings) const
{
return fChild->Archive(into);
return fSettingsView->SaveInto(settings);
}
private:
BView* fChild;
BMailSettingsView* fSettingsView;
};
@@ -211,8 +212,8 @@ FiltersConfigView::FiltersConfigView(BMailAccountSettings& account)
BBox("filters"),
fAccount(account),
fDirection(kIncoming),
fInboundFilters(kIncoming, false),
fOutboundFilters(kOutgoing, false),
fInboundFilters(kIncoming),
fOutboundFilters(kOutgoing),
fFilterView(NULL),
fCurrentIndex(-1)
{
@@ -284,11 +285,12 @@ FiltersConfigView::_SelectFilter(int32 index)
= _MailSettings()->FilterSettingsAt(index);
if (filterSettings != NULL) {
::FilterList* filters = _FilterList();
BView* view = filters->CreateConfigView(*filterSettings);
BMailSettingsView* view = filters->CreateSettingsView(fAccount,
*filterSettings);
if (view != NULL) {
BString name;
filters->GetDescriptiveName(filterSettings->AddOnRef(), name);
fFilterView = new FilterConfigBox(name, view);
fFilterView = new FilterSettingsView(
filters->DescriptiveName(filterSettings->AddOnRef(),
fAccount, NULL), view);
Parent()->AddChild(fFilterView);
}
}
@@ -320,31 +322,30 @@ FiltersConfigView::_SetDirection(direction direction)
for (int32 i = 0; i < protocolSettings->CountFilterSettings(); i++) {
BMailAddOnSettings* settings = protocolSettings->FilterSettingsAt(i);
if (filters->InfoIndexFor(settings->AddOnRef()) < 0) {
fprintf(stderr, "Removed missing filter: %s\n",
settings->AddOnRef().name);
protocolSettings->RemoveFilterSettings(i);
i--;
continue;
}
BString name = "Unnamed Filter";
filters->GetDescriptiveName(settings->AddOnRef(), name);
fListView->AddItem(new BStringItem(name));
fListView->AddItem(new BStringItem(filters->DescriptiveName(
settings->AddOnRef(), fAccount, settings)));
}
// remove old filter items
BMenu *menu = fAddField->Menu();
BMenu* menu = fAddField->Menu();
for (int32 i = menu->CountItems(); i-- > 0;) {
BMenuItem *item = menu->RemoveItem(i);
delete item;
}
filters->Reload();
for (int32 i = 0; i < filters->CountInfos(); i++) {
FilterInfo& info = filters->InfoAt(i);
BString name;
filters->GetDescriptiveName(i, name);
const FilterInfo& info = filters->InfoAt(i);
BMessage* msg = new BMessage(kMsgAddFilter);
msg->AddRef("filter", &info.ref);
BMenuItem *item = new BMenuItem(name, msg);
BMenuItem* item = new BMenuItem(filters->SimpleName(i, fAccount), msg);
menu->AddItem(item);
}
@@ -391,15 +392,12 @@ FiltersConfigView::MessageReceived(BMessage *msg)
if (msg->FindRef("filter", &ref) != B_OK)
break;
::FilterList* filters = _FilterList();
int32 index = filters->InfoIndexFor(ref);
int32 index = _MailSettings()->AddFilterSettings(&ref);
if (index < 0)
break;
_MailSettings()->AddFilterSettings(&ref);
BString name;
filters->GetDescriptiveName(index, name);
fListView->AddItem(new BStringItem(name));
fListView->AddItem(new BStringItem(_FilterList()->DescriptiveName(
ref, fAccount, _MailSettings()->FilterSettingsAt(index))));
break;
}
case kMsgRemoveFilter:
@@ -470,6 +468,6 @@ FiltersConfigView::_SaveConfig(int32 index)
if (fFilterView != NULL) {
BMailAddOnSettings* settings = _MailSettings()->FilterSettingsAt(index);
if (settings != NULL)
fFilterView->ArchiveAddOn(settings);
fFilterView->SaveInto(*settings);
}
}
+4 -3
View File
@@ -20,7 +20,7 @@
#include "FilterList.h"
class FilterConfigBox;
class FilterSettingsView;
class FiltersConfigView : public BBox {
@@ -52,9 +52,10 @@ private:
BListView* fListView;
BMenuField* fAddField;
BButton* fRemoveButton;
FilterConfigBox* fFilterView;
FilterSettingsView* fFilterView;
int32 fCurrentIndex;
};
#endif //FILTER_CONFIG_VIEW_H
#endif // FILTER_CONFIG_VIEW_H
+97 -67
View File
@@ -7,17 +7,17 @@
#include "FilterList.h"
#include <set>
#include <Directory.h>
#include <FindDirectory.h>
#include <Path.h>
FilterList::FilterList(direction dir, bool loadOnStart)
FilterList::FilterList(direction dir)
:
fDirection(dir)
{
if (loadOnStart)
Reload();
}
@@ -32,91 +32,116 @@ FilterList::Reload()
{
_MakeEmpty();
BPath path;
status_t status = find_directory(B_SYSTEM_ADDONS_DIRECTORY, &path);
if (status != B_OK)
return;
path.Append("mail_daemon");
if (fDirection == kIncoming)
path.Append("inbound_filters");
else
path.Append("outbound_filters");
std::set<BString> knownNames;
BDirectory dir(path.Path());
if (dir.InitCheck() != B_OK)
return;
BEntry entry;
while (dir.GetNextEntry(&entry) == B_OK)
_LoadAddOn(entry);
directory_which which[] = {B_USER_ADDONS_DIRECTORY,
B_COMMON_ADDONS_DIRECTORY,
B_SYSTEM_ADDONS_DIRECTORY};
for (size_t i = 0; i < sizeof(which) / sizeof(which[0]); i++) {
BPath path;
status_t status = find_directory(which[i], &path);
if (status != B_OK)
continue;
path.Append("mail_daemon");
if (fDirection == kIncoming)
path.Append("inbound_filters");
else
path.Append("outbound_filters");
BDirectory dir(path.Path());
if (dir.InitCheck() != B_OK)
continue;
BEntry entry;
while (dir.GetNextEntry(&entry) == B_OK) {
// Ignore entries we already had before (ie., user add-ons are
// overriding system add-ons)
if (knownNames.find(entry.Name()) != knownNames.end())
continue;
if (_LoadAddOn(entry) == B_OK)
knownNames.insert(entry.Name());
}
}
}
int32
FilterList::CountInfos()
FilterList::CountInfos() const
{
return fList.size();
}
FilterInfo&
FilterList::InfoAt(int32 index)
const FilterInfo&
FilterList::InfoAt(int32 index) const
{
return fList[index];
}
bool
FilterList::GetDescriptiveName(int32 index, BString& name)
int32
FilterList::InfoIndexFor(const entry_ref& ref) const
{
if (index < 0)
return false;
FilterInfo& info = InfoAt(index);
BString (*descriptive_name)();
if (get_image_symbol(info.image, "descriptive_name", B_SYMBOL_TYPE_TEXT,
(void **)&descriptive_name) == B_OK) {
name = (*descriptive_name)();
} else
name = info.ref.name;
return true;
for (size_t i = 0; i < fList.size(); i++) {
const FilterInfo& info = fList[i];
if (info.ref == ref)
return i;
}
return -1;
}
bool
FilterList::GetDescriptiveName(const entry_ref& ref, BString& name)
BString
FilterList::SimpleName(int32 index,
const BMailAccountSettings& accountSettings) const
{
int32 index = InfoIndexFor(ref);
return GetDescriptiveName(index, name);
return DescriptiveName(index, accountSettings, NULL);
}
BView*
FilterList::CreateConfigView(BMailAddOnSettings& settings)
BString
FilterList::SimpleName(const entry_ref& ref,
const BMailAccountSettings& accountSettings) const
{
return DescriptiveName(InfoIndexFor(ref), accountSettings, NULL);
}
BString
FilterList::DescriptiveName(int32 index,
const BMailAccountSettings& accountSettings,
const BMailAddOnSettings* settings) const
{
if (index < 0 || index >= CountInfos())
return "-";
const FilterInfo& info = InfoAt(index);
return info.name(accountSettings, settings);
}
BString
FilterList::DescriptiveName(const entry_ref& ref,
const BMailAccountSettings& accountSettings,
const BMailAddOnSettings* settings) const
{
return DescriptiveName(InfoIndexFor(ref), accountSettings, settings);
}
BMailSettingsView*
FilterList::CreateSettingsView(const BMailAccountSettings& accountSettings,
const BMailAddOnSettings& settings)
{
const entry_ref& ref = settings.AddOnRef();
int32 index = InfoIndexFor(ref);
if (index < 0)
return NULL;
FilterInfo& info = InfoAt(index);
BView* (*instantiateFilterConfigPanel)(BMailAddOnSettings&);
if (get_image_symbol(info.image, "instantiate_filter_config_panel",
B_SYMBOL_TYPE_TEXT, (void **)&instantiateFilterConfigPanel) != B_OK)
return NULL;
return (*instantiateFilterConfigPanel)(settings);
}
int32
FilterList::InfoIndexFor(const entry_ref& ref)
{
for (size_t i = 0; i < fList.size(); i++) {
FilterInfo& info = fList[i];
if (info.ref == ref)
return i;
}
return -1;
const FilterInfo& info = InfoAt(index);
return info.instantiateSettingsView(accountSettings, settings);
}
@@ -131,7 +156,7 @@ FilterList::_MakeEmpty()
}
void
status_t
FilterList::_LoadAddOn(BEntry& entry)
{
FilterInfo info;
@@ -139,17 +164,22 @@ FilterList::_LoadAddOn(BEntry& entry)
BPath path(&entry);
info.image = load_add_on(path.Path());
if (info.image < 0)
return;
return info.image;
BView* (*instantiateFilterConfigPanel)(BMailProtocolSettings&);
if (get_image_symbol(info.image, "instantiate_filter_config_panel",
B_SYMBOL_TYPE_TEXT, (void **)&instantiateFilterConfigPanel)
!= B_OK) {
status_t status = get_image_symbol(info.image,
"instantiate_filter_settings_view", B_SYMBOL_TYPE_TEXT,
(void**)&info.instantiateSettingsView);
if (status == B_OK) {
status = get_image_symbol(info.image, "filter_name", B_SYMBOL_TYPE_TEXT,
(void**)&info.name);
}
if (status != B_OK) {
fprintf(stderr, "Filter \"%s\" misses required hooks!\n", path.Path());
unload_add_on(info.image);
return;
return B_NAME_NOT_FOUND;
}
entry.GetRef(&info.ref);
fList.push_back(info);
return B_OK;
}
+26 -12
View File
@@ -8,7 +8,7 @@
#include <MailSettings.h>
#include <View.h>
#include <MailSettingsView.h>
enum direction {
@@ -20,32 +20,46 @@ enum direction {
struct FilterInfo {
image_id image;
entry_ref ref;
BMailSettingsView* (*instantiateSettingsView)(
const BMailAccountSettings& accountSettings,
const BMailAddOnSettings& settings);
BString (*name)(
const BMailAccountSettings& accountSettings,
const BMailAddOnSettings* settings);
};
class FilterList {
public:
FilterList(direction dir,
bool loadOnStart = true);
FilterList(direction dir);
~FilterList();
void Reload();
int32 CountInfos();
FilterInfo& InfoAt(int32 index);
int32 CountInfos() const;
const FilterInfo& InfoAt(int32 index) const;
int32 InfoIndexFor(const entry_ref& ref) const;
bool GetDescriptiveName(int32 index, BString& name);
bool GetDescriptiveName(const entry_ref& ref,
BString& name);
BString SimpleName(int32 index,
const BMailAccountSettings& settings) const;
BString SimpleName(const entry_ref& ref,
const BMailAccountSettings& settings) const;
BString DescriptiveName(int32 index,
const BMailAccountSettings& settings,
const BMailAddOnSettings* settings) const;
BString DescriptiveName(const entry_ref& ref,
const BMailAccountSettings& settings,
const BMailAddOnSettings* settings) const;
BView* CreateConfigView(BMailAddOnSettings& settings);
int32 InfoIndexFor(const entry_ref& ref);
BMailSettingsView* CreateSettingsView(
const BMailAccountSettings& accountSettings,
const BMailAddOnSettings& settings);
private:
void _MakeEmpty();
void _LoadAddOn(BEntry& entry);
status_t _LoadAddOn(BEntry& entry);
private:
direction fDirection;
std::vector<FilterInfo> fList;
};