From ca3341c7b430ae9c6a1e7ec22f9aa83d46910814 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Mon, 12 Nov 2012 23:51:51 +0100 Subject: [PATCH] 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. --- headers/os/add-ons/mail_daemon/MailFilter.h | 17 +- headers/os/add-ons/mail_daemon/MailProtocol.h | 13 +- .../os/add-ons/mail_daemon/MailSettingsView.h | 25 +++ .../match_header/ConfigView.cpp | 100 ++++++----- .../match_header/MatchHeaderSettings.h | 64 +++++++ .../match_header/RuleFilter.cpp | 52 +++--- .../inbound_filters/match_header/RuleFilter.h | 17 +- .../notifier/NotifierConfigView.cpp | 70 ++++---- .../notifier/NotifierConfigView.h | 9 +- .../notifier/NotifierFilter.cpp | 22 +-- .../spam_filter/SpamFilter.cpp | 38 ++-- .../inbound_filters/spam_filter/SpamFilter.h | 4 +- .../spam_filter/SpamFilterConfig.cpp | 28 +-- src/kits/mail/Jamfile | 1 + src/kits/mail/MailFilter.cpp | 3 +- src/kits/mail/MailProtocol.cpp | 14 +- src/kits/mail/MailSettings.cpp | 2 + src/kits/mail/MailSettingsView.cpp | 19 ++ src/kits/mail/ProtocolConfigView.cpp | 2 +- src/preferences/mail/ConfigViews.cpp | 38 ++-- src/preferences/mail/ConfigViews.h | 20 ++- src/preferences/mail/ConfigWindow.cpp | 8 +- src/preferences/mail/FilterConfigView.cpp | 68 ++++---- src/preferences/mail/FilterConfigView.h | 7 +- src/preferences/mail/FilterList.cpp | 164 +++++++++++------- src/preferences/mail/FilterList.h | 38 ++-- 26 files changed, 495 insertions(+), 348 deletions(-) create mode 100644 headers/os/add-ons/mail_daemon/MailSettingsView.h create mode 100644 src/add-ons/mail_daemon/inbound_filters/match_header/MatchHeaderSettings.h create mode 100644 src/kits/mail/MailSettingsView.cpp diff --git a/headers/os/add-ons/mail_daemon/MailFilter.h b/headers/os/add-ons/mail_daemon/MailFilter.h index 00c66eacdb..c16f269dbe 100644 --- a/headers/os/add-ons/mail_daemon/MailFilter.h +++ b/headers/os/add-ons/mail_daemon/MailFilter.h @@ -11,17 +11,15 @@ class BMailProtocol; -class BView; +class BMailSettingsView; class BMailFilter { public: BMailFilter(BMailProtocol& protocol, - BMailAddOnSettings* settings); + const BMailAddOnSettings* settings); virtual ~BMailFilter(); - virtual BString DescriptiveName() const = 0; - // Message hooks if filter is installed to an inbound protocol virtual void HeaderFetched(const entry_ref& ref, BFile* file); @@ -36,15 +34,18 @@ public: protected: BMailProtocol& fMailProtocol; - BMailAddOnSettings* fSettings; + const BMailAddOnSettings* fSettings; }; // Your filter needs to export these hooks in order to be picked up -extern "C" BView* instantiate_filter_config_panel(BMailAddOnSettings& settings); +extern "C" BMailSettingsView* instantiate_filter_settings_view( + const BMailAccountSettings& accountSettings, + const BMailAddOnSettings& settings); +extern "C" BString filter_name(const BMailAccountSettings& accountSettings, + const BMailAddOnSettings* settings); extern "C" BMailFilter* instantiate_filter(BMailProtocol& protocol, - BMailAddOnSettings* settings); -extern "C" BString filter_name(); + const BMailAddOnSettings& settings); #endif // _MAIL_FILTER_H diff --git a/headers/os/add-ons/mail_daemon/MailProtocol.h b/headers/os/add-ons/mail_daemon/MailProtocol.h index 299ca8e8a0..32cb150cff 100644 --- a/headers/os/add-ons/mail_daemon/MailProtocol.h +++ b/headers/os/add-ons/mail_daemon/MailProtocol.h @@ -22,6 +22,7 @@ class BMailFilter; +class BMailSettingsView; class BView; @@ -103,7 +104,7 @@ protected: const BMailProtocolSettings& settings); private: - BMailFilter* _LoadFilter(BMailAddOnSettings* filterSettings); + BMailFilter* _LoadFilter(const BMailAddOnSettings& settings); protected: const BMailAccountSettings fAccountSettings; @@ -149,12 +150,14 @@ public: // Your protocol needs to export these hooks in order to be picked up -extern "C" _EXPORT BInboundMailProtocol* instantiate_inbound_protocol( +extern "C" BInboundMailProtocol* instantiate_inbound_protocol( const BMailAccountSettings& settings); -extern "C" _EXPORT BOutboundMailProtocol* instantiate_outbound_protocol( +extern "C" BOutboundMailProtocol* instantiate_outbound_protocol( const BMailAccountSettings& settings); -extern "C" _EXPORT BView* instantiate_protocol_config_panel( - BMailAccountSettings& settings); + +extern "C" BMailSettingsView* instantiate_protocol_settings_view( + const BMailAccountSettings& accountSettings, + const BMailProtocolSettings& settings); #endif // _MAIL_PROTOCOL_H diff --git a/headers/os/add-ons/mail_daemon/MailSettingsView.h b/headers/os/add-ons/mail_daemon/MailSettingsView.h new file mode 100644 index 0000000000..30f289242d --- /dev/null +++ b/headers/os/add-ons/mail_daemon/MailSettingsView.h @@ -0,0 +1,25 @@ +/* + * Copyright 2012, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef _MAIL_SETTINGS_VIEW_H +#define _MAIL_SETTINGS_VIEW_H + + +#include +#include + + +class BMailSettingsView : public BView { +public: + BMailSettingsView(const char* name); + virtual ~BMailSettingsView(); + +// virtual BString DescriptiveName() const = 0; + + virtual status_t SaveInto( + BMailAddOnSettings& settings) const = 0; +}; + + +#endif // _MAIL_SETTINGS_VIEW_H diff --git a/src/add-ons/mail_daemon/inbound_filters/match_header/ConfigView.cpp b/src/add-ons/mail_daemon/inbound_filters/match_header/ConfigView.cpp index b4f707db54..7e4698b989 100644 --- a/src/add-ons/mail_daemon/inbound_filters/match_header/ConfigView.cpp +++ b/src/add-ons/mail_daemon/inbound_filters/match_header/ConfigView.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -20,7 +21,7 @@ #include -#include "RuleFilter.h" +#include "MatchHeaderSettings.h" #undef B_TRANSLATION_CONTEXT @@ -33,13 +34,15 @@ using namespace BPrivate; static const uint32 kMsgActionChanged = 'actC'; -class RuleFilterConfig : public BView { +class RuleFilterConfig : public BMailSettingsView { public: - RuleFilterConfig(const BMessage& settings); + RuleFilterConfig( + const BMailAddOnSettings& settings); + + virtual status_t SaveInto(BMailAddOnSettings& settings) const; virtual void MessageReceived(BMessage* message); virtual void AttachedToWindow(); - virtual status_t Archive(BMessage* into, bool deep = true) const; private: void _SetVisible(BView* view, bool visible); @@ -57,48 +60,38 @@ private: }; -RuleFilterConfig::RuleFilterConfig(const BMessage& settings) +RuleFilterConfig::RuleFilterConfig(const BMailAddOnSettings& addOnSettings) : - BView("rulefilter_config", 0), + BMailSettingsView("rulefilter_config"), fActionMenu(NULL) { SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); - if (settings.HasInt32("do_what")) - fAction = settings.FindInt32("do_what"); - else - fAction = -1; + MatchHeaderSettings settings(addOnSettings); + fAction = settings.Action(); fAttributeControl = new BTextControl("attr", B_TRANSLATE("If"), B_TRANSLATE("header (e.g. Subject)"), NULL); - if (settings.HasString("attribute")) - fAttributeControl->SetText(settings.FindString("attribute")); + fAttributeControl->SetText(settings.Attribute()); fRegexControl = new BTextControl("regex", B_TRANSLATE("has"), - B_TRANSLATE("value (use REGEX: in from of regular expressions like " + B_TRANSLATE("value (use REGEX: in front of regular expressions like " "*spam*)"), NULL); - if (settings.HasString("regex")) - fRegexControl->SetText(settings.FindString("regex")); + fRegexControl->SetText(settings.Expression()); fFileControl = new FileControl("arg", NULL, B_TRANSLATE("this field is based on the action")); if (BControl* control = (BControl*)fFileControl->FindView("select_file")) control->SetEnabled(false); - if (fAction == ACTION_MOVE_TO && settings.HasString("argument")) - fFileControl->SetText(settings.FindString("argument")); + fFileControl->SetText(settings.MoveTarget()); fFlagsControl = new BTextControl("flags", NULL, NULL); - if (fAction == ACTION_SET_FLAGS_TO && settings.HasString("argument")) - fFlagsControl->SetText(settings.FindString("argument")); + fFlagsControl->SetText(settings.SetFlagsTo()); // Populate account menu fAccountMenu = new BPopUpMenu(B_TRANSLATE("")); - - if (fAction == ACTION_REPLY_WITH) - fAccountID = settings.FindInt32("argument"); - else - fAccountID = -1; + fAccountID = settings.ReplyAccount(); BMailAccounts accounts; for (int32 i = 0; i < accounts.CountAccounts(); i++) { @@ -145,7 +138,7 @@ RuleFilterConfig::RuleFilterConfig(const BMessage& settings) fActionMenu->AddItem(new BMenuItem(kActions[i].label, message)); } - BMenuField* actionField = new BMenuField("do_what", B_TRANSLATE("Then"), + BMenuField* actionField = new BMenuField("action", B_TRANSLATE("Then"), fActionMenu); // Build layout @@ -166,6 +159,38 @@ RuleFilterConfig::RuleFilterConfig(const BMessage& settings) } +status_t +RuleFilterConfig::SaveInto(BMailAddOnSettings& settings) const +{ + int32 action = fActionMenu->IndexOf(fActionMenu->FindMarked()); + settings.SetInt32("action", action); + settings.SetString("attribute", fAttributeControl->Text()); + settings.SetString("regex", fRegexControl->Text()); + + switch (action) { + case ACTION_MOVE_TO: + settings.SetString("move target", fFileControl->Text()); + break; + + case ACTION_SET_FLAGS_TO: + settings.SetString("set flags", fFlagsControl->Text()); + break; + + case ACTION_REPLY_WITH: + { + BMenuItem* item = fAccountMenu->FindMarked(); + if (item != NULL) { + settings.SetInt32("account", + item->Message()->FindInt32("account id")); + } + break; + } + } + + return B_OK; +} + + void RuleFilterConfig::AttachedToWindow() { @@ -173,26 +198,6 @@ RuleFilterConfig::AttachedToWindow() } -status_t -RuleFilterConfig::Archive(BMessage *into, bool deep) const -{ - into->MakeEmpty(); - into->AddInt32("do_what", fActionMenu->IndexOf(fActionMenu->FindMarked())); - into->AddString("attribute", fAttributeControl->Text()); - into->AddString("regex", fRegexControl->Text()); - if (into->FindInt32("do_what") == ACTION_REPLY_WITH) { - BMenuItem* item = fAccountMenu->FindMarked(); - if (item != NULL) { - into->AddInt32("argument", - item->Message()->FindInt32("account id")); - } - } else - into->AddString("argument", fFileControl->Text()); - - return B_OK; -} - - void RuleFilterConfig::MessageReceived(BMessage* message) { @@ -224,8 +229,9 @@ RuleFilterConfig::_SetVisible(BView* view, bool visible) // #pragma mark - -BView* -instantiate_filter_config_panel(BMailAddOnSettings& settings) +BMailSettingsView* +instantiate_filter_settings_view(const BMailAccountSettings& accountSettings, + const BMailAddOnSettings& settings) { return new RuleFilterConfig(settings); } diff --git a/src/add-ons/mail_daemon/inbound_filters/match_header/MatchHeaderSettings.h b/src/add-ons/mail_daemon/inbound_filters/match_header/MatchHeaderSettings.h new file mode 100644 index 0000000000..39b150863a --- /dev/null +++ b/src/add-ons/mail_daemon/inbound_filters/match_header/MatchHeaderSettings.h @@ -0,0 +1,64 @@ +/* + * Copyright 2012, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + */ +#ifndef MATCH_HEADER_SETTINGS_H +#define MATCH_HEADER_SETTINGS_H + + +#include + + +enum rule_action { + ACTION_MOVE_TO, + ACTION_SET_FLAGS_TO, + ACTION_DELETE_MESSAGE, + ACTION_REPLY_WITH, + ACTION_SET_AS_READ +}; + + +class MatchHeaderSettings { +public: + MatchHeaderSettings(const BMailAddOnSettings& settings) + : + fSettings(settings) + { + } + + rule_action Action() const + { + return (rule_action)fSettings.GetInt32("action", -1); + } + + const char* Attribute() const + { + return fSettings.FindString("attribute"); + } + + const char* Expression() const + { + return fSettings.FindString("regex"); + } + + const char* MoveTarget() const + { + return fSettings.FindString("regex"); + } + + const char* SetFlagsTo() const + { + return fSettings.FindString("set flags"); + } + + const int32 ReplyAccount() const + { + return fSettings.GetInt32("account", -1); + } + +private: + const BMailAddOnSettings& fSettings; +}; + + +#endif // MATCH_HEADER_SETTINGS_H diff --git a/src/add-ons/mail_daemon/inbound_filters/match_header/RuleFilter.cpp b/src/add-ons/mail_daemon/inbound_filters/match_header/RuleFilter.cpp index c90911d8d2..023840ead2 100644 --- a/src/add-ons/mail_daemon/inbound_filters/match_header/RuleFilter.cpp +++ b/src/add-ons/mail_daemon/inbound_filters/match_header/RuleFilter.cpp @@ -22,20 +22,25 @@ #include +#include "MatchHeaderSettings.h" + #undef B_TRANSLATION_CONTEXT #define B_TRANSLATION_CONTEXT "RuleFilter" -RuleFilter::RuleFilter(BMailProtocol& protocol, BMailAddOnSettings* settings) +RuleFilter::RuleFilter(BMailProtocol& protocol, + const BMailAddOnSettings& addOnSettings) : - BMailFilter(protocol, settings) + BMailFilter(protocol, &addOnSettings) { + MatchHeaderSettings settings(addOnSettings); + // attribute is adapted to our "capitalize-each-word-in-the-header" policy - settings->FindString("attribute", &fAttribute); + fAttribute = settings.Attribute(); fAttribute.CapitalizeEachWord(); - settings->FindString("regex", &fExpression); + fExpression = settings.Expression(); int32 index = fExpression.FindFirst("REGEX:"); if (index == B_ERROR || index > 0) EscapeRegexTokens(fExpression); @@ -44,20 +49,10 @@ RuleFilter::RuleFilter(BMailProtocol& protocol, BMailAddOnSettings* settings) fMatcher.SetPattern(fExpression, false); - settings->FindString("argument", &fArg); - settings->FindInt32("do_what", (int32*)&fAction); - if (fAction == ACTION_REPLY_WITH) - settings->FindInt32("argument", &fReplyAccount); -} - - -BString -RuleFilter::DescriptiveName() const -{ - BString name(B_TRANSLATE("Match \"%attribute\" against \"%regex\"")); - name.ReplaceAll("%attribute", fAttribute); - name.ReplaceAll("%regex", fExpression); - return name; + fAction = settings.Action(); + fMoveTarget = settings.MoveTarget(); + fSetFlags = settings.SetFlagsTo(); + fReplyAccount = settings.ReplyAccount(); } @@ -89,7 +84,7 @@ RuleFilter::HeaderFetched(const entry_ref& ref, BFile* file) switch (fAction) { case ACTION_MOVE_TO: { - BDirectory dir(fArg); + BDirectory dir(fMoveTarget); // TODO: move is currently broken! // fMailProtocol.Looper()->TriggerFileMove(ref, dir); break; @@ -100,7 +95,7 @@ RuleFilter::HeaderFetched(const entry_ref& ref, BFile* file) break; case ACTION_SET_FLAGS_TO: - file->WriteAttrString("MAIL:filter_flags", &fArg); + file->WriteAttrString("MAIL:filter_flags", &fSetFlags); break; case ACTION_REPLY_WITH: @@ -126,14 +121,25 @@ RuleFilter::HeaderFetched(const entry_ref& ref, BFile* file) BString -filter_name() +filter_name(const BMailAccountSettings& accountSettings, + const BMailAddOnSettings* addOnSettings) { - return B_TRANSLATE("Rule filter"); + if (addOnSettings != NULL) { + MatchHeaderSettings settings(*addOnSettings); + if (settings.Attribute() != NULL && settings.Expression() != NULL) { + BString name( + B_TRANSLATE("Match \"%attribute\" against \"%regex\"")); + name.ReplaceAll("%attribute", settings.Attribute()); + name.ReplaceAll("%regex", settings.Expression()); + return name; + } + } + return B_TRANSLATE("Match header"); } BMailFilter* -instantiate_filter(BMailProtocol& protocol, BMailAddOnSettings* settings) +instantiate_filter(BMailProtocol& protocol, const BMailAddOnSettings& settings) { return new RuleFilter(protocol, settings); } diff --git a/src/add-ons/mail_daemon/inbound_filters/match_header/RuleFilter.h b/src/add-ons/mail_daemon/inbound_filters/match_header/RuleFilter.h index 2780a7c8fc..b26240774a 100644 --- a/src/add-ons/mail_daemon/inbound_filters/match_header/RuleFilter.h +++ b/src/add-ons/mail_daemon/inbound_filters/match_header/RuleFilter.h @@ -12,24 +12,14 @@ #include #include +#include "MatchHeaderSettings.h" #include "StringMatcher.h" -enum rule_action { - ACTION_MOVE_TO, - ACTION_SET_FLAGS_TO, - ACTION_DELETE_MESSAGE, - ACTION_REPLY_WITH, - ACTION_SET_AS_READ -}; - - class RuleFilter : public BMailFilter { public: RuleFilter(BMailProtocol& protocol, - BMailAddOnSettings* settings); - - virtual BString DescriptiveName() const; + const BMailAddOnSettings& settings); virtual void HeaderFetched(const entry_ref& ref, BFile* file); @@ -38,7 +28,8 @@ private: BString fAttribute; BString fExpression; StringMatcher fMatcher; - BString fArg; + BString fMoveTarget; + BString fSetFlags; int32 fReplyAccount; rule_action fAction; }; diff --git a/src/add-ons/mail_daemon/inbound_filters/notifier/NotifierConfigView.cpp b/src/add-ons/mail_daemon/inbound_filters/notifier/NotifierConfigView.cpp index 3827514c15..2cb46d8004 100644 --- a/src/add-ons/mail_daemon/inbound_filters/notifier/NotifierConfigView.cpp +++ b/src/add-ons/mail_daemon/inbound_filters/notifier/NotifierConfigView.cpp @@ -30,7 +30,7 @@ const uint32 kMsgNotifyMethod = 'nomt'; NotifierConfigView::NotifierConfigView() : - BView("notifier_config", 0) + BMailSettingsView("notifier_config") { SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); @@ -54,14 +54,6 @@ NotifierConfigView::NotifierConfigView() } -void -NotifierConfigView::AttachedToWindow() -{ - if (BMenuField *field = dynamic_cast(FindView("notify"))) - field->Menu()->SetTargetForItems(this); -} - - void NotifierConfigView::SetTo(const BMessage *archive) { @@ -77,12 +69,38 @@ NotifierConfigView::SetTo(const BMessage *archive) BMenuItem *item = field->Menu()->ItemAt(i); item->SetMarked((method & (1L << i)) != 0); } - UpdateNotifyText(); + _UpdateNotifyText(); +} + + +status_t +NotifierConfigView::SaveInto(BMailAddOnSettings& settings) const +{ + int32 method = 0; + + BMenuField *field; + if ((field = dynamic_cast(FindView("notify"))) != NULL) { + for (int32 i = field->Menu()->CountItems(); i-- > 0;) { + BMenuItem *item = field->Menu()->ItemAt(i); + if (item->IsMarked()) + method |= 1L << i; + } + } + + return settings.SetInt32("notification_method", method); } void -NotifierConfigView::UpdateNotifyText() +NotifierConfigView::AttachedToWindow() +{ + if (BMenuField *field = dynamic_cast(FindView("notify"))) + field->Menu()->SetTargetForItems(this); +} + + +void +NotifierConfigView::_UpdateNotifyText() { BMenuField *field; if ((field = dynamic_cast(FindView("notify"))) == NULL) @@ -115,7 +133,7 @@ NotifierConfigView::MessageReceived(BMessage *msg) break; item->SetMarked(!item->IsMarked()); - UpdateNotifyText(); + _UpdateNotifyText(); break; } default: @@ -124,34 +142,14 @@ NotifierConfigView::MessageReceived(BMessage *msg) } -status_t -NotifierConfigView::Archive(BMessage *into, bool /*deep*/) const -{ - int32 method = 0; - - BMenuField *field; - if ((field = dynamic_cast(FindView("notify"))) != NULL) { - for (int32 i = field->Menu()->CountItems(); i-- > 0;) { - BMenuItem *item = field->Menu()->ItemAt(i); - if (item->IsMarked()) - method |= 1L << i; - } - } - - if (into->ReplaceInt32("notification_method", method) != B_OK) - into->AddInt32("notification_method", method); - - return B_OK; -} - - // #pragma mark - -BView* -instantiate_filter_config_panel(BMailAddOnSettings& settings) +BMailSettingsView* +instantiate_filter_settings_view(const BMailAccountSettings& accountSettings, + const BMailAddOnSettings& settings) { - NotifierConfigView *view = new NotifierConfigView(); + NotifierConfigView* view = new NotifierConfigView(); view->SetTo(&settings); return view; } diff --git a/src/add-ons/mail_daemon/inbound_filters/notifier/NotifierConfigView.h b/src/add-ons/mail_daemon/inbound_filters/notifier/NotifierConfigView.h index d5b353b70f..27426b5b99 100644 --- a/src/add-ons/mail_daemon/inbound_filters/notifier/NotifierConfigView.h +++ b/src/add-ons/mail_daemon/inbound_filters/notifier/NotifierConfigView.h @@ -8,7 +8,7 @@ #define NOTIFIER_CONFIG_VIEW_H -#include +#include enum { @@ -21,18 +21,19 @@ enum { }; -class NotifierConfigView : public BView { +class NotifierConfigView : public BMailSettingsView { public: NotifierConfigView(); void SetTo(const BMessage *archive); - virtual status_t Archive(BMessage *into, bool deep = true) const; + virtual status_t SaveInto(BMailAddOnSettings& settings) const; virtual void AttachedToWindow(); virtual void MessageReceived(BMessage *msg); - void UpdateNotifyText(); +private: + void _UpdateNotifyText(); }; diff --git a/src/add-ons/mail_daemon/inbound_filters/notifier/NotifierFilter.cpp b/src/add-ons/mail_daemon/inbound_filters/notifier/NotifierFilter.cpp index 219014b50a..ce78592cb2 100644 --- a/src/add-ons/mail_daemon/inbound_filters/notifier/NotifierFilter.cpp +++ b/src/add-ons/mail_daemon/inbound_filters/notifier/NotifierFilter.cpp @@ -31,9 +31,7 @@ class NotifyFilter : public BMailFilter { public: NotifyFilter(BMailProtocol& protocol, - BMailAddOnSettings* settings); - - virtual BString DescriptiveName() const; + const BMailAddOnSettings& settings); void HeaderFetched(const entry_ref& ref, BFile* file); @@ -46,19 +44,12 @@ private: NotifyFilter::NotifyFilter(BMailProtocol& protocol, - BMailAddOnSettings* settings) + const BMailAddOnSettings& settings) : - BMailFilter(protocol, settings), + BMailFilter(protocol, &settings), fNNewMessages(0) { - fStrategy = settings->FindInt32("notification_method"); -} - - -BString -NotifyFilter::DescriptiveName() const -{ - return filter_name(); + fStrategy = settings.FindInt32("notification_method"); } @@ -130,14 +121,15 @@ NotifyFilter::MailboxSynchronized(status_t status) BString -filter_name() +filter_name(const BMailAccountSettings& accountSettings, + const BMailAddOnSettings* addOnSettings) { return B_TRANSLATE("New mails notification"); } BMailFilter* -instantiate_filter(BMailProtocol& protocol, BMailAddOnSettings* settings) +instantiate_filter(BMailProtocol& protocol, const BMailAddOnSettings& settings) { return new NotifyFilter(protocol, settings); } diff --git a/src/add-ons/mail_daemon/inbound_filters/spam_filter/SpamFilter.cpp b/src/add-ons/mail_daemon/inbound_filters/spam_filter/SpamFilter.cpp index 7ae431b6a1..03b573f690 100644 --- a/src/add-ons/mail_daemon/inbound_filters/spam_filter/SpamFilter.cpp +++ b/src/add-ons/mail_daemon/inbound_filters/spam_filter/SpamFilter.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2002-2011, Haiku, Inc. All rights reserved. + * Copyright 2002-2012, Haiku, Inc. All rights reserved. * Copyright 2002 Alexander G. M. Smith. * Copyright 2011, Clemens Zeidler * Distributed under the terms of the MIT License. @@ -45,23 +45,17 @@ static const char* kAGMSBayesBeepUncertainName = "SpamFilter-Uncertain"; static const char* kServerSignature = "application/x-vnd.agmsmith.spamdbm"; -SpamFilter::SpamFilter(BMailProtocol& protocol, BMailAddOnSettings* settings) +SpamFilter::SpamFilter(BMailProtocol& protocol, + const BMailAddOnSettings& settings) : - BMailFilter(protocol, settings) + BMailFilter(protocol, &settings) { - if (settings->FindBool("AddMarkerToSubject", &fAddSpamToSubject) != B_OK) - fAddSpamToSubject = false; - if (settings->FindBool("AutoTraining", &fAutoTraining) != B_OK) - fAutoTraining = true; - if (settings->FindFloat("GenuineCutoffRatio", &fGenuineCutoffRatio) != B_OK) - fGenuineCutoffRatio = 0.01f; - if (settings->FindBool("NoWordsMeansSpam", &fNoWordsMeansSpam) != B_OK) - fNoWordsMeansSpam = true; - if (settings->FindBool("QuitServerWhenFinished", - &fQuitServerWhenFinished) != B_OK) - fQuitServerWhenFinished = false; - if (settings->FindFloat("SpamCutoffRatio", &fSpamCutoffRatio) != B_OK) - fSpamCutoffRatio = 0.99f; + fAddSpamToSubject = settings.GetBool("AddMarkerToSubject", false); + fAutoTraining = settings.GetBool("AutoTraining", true); + fGenuineCutoffRatio = settings.GetFloat("GenuineCutoffRatio", 0.01f); + fNoWordsMeansSpam = settings.GetBool("NoWordsMeansSpam", true); + fQuitServerWhenFinished = settings.GetBool("QuitServerWhenFinished", false); + fSpamCutoffRatio = settings.GetFloat("SpamCutoffRatio", 0.99f); } @@ -72,13 +66,6 @@ SpamFilter::~SpamFilter() } -BString -SpamFilter::DescriptiveName() const -{ - return filter_name(); -} - - void SpamFilter::HeaderFetched(const entry_ref& ref, BFile* file) { @@ -327,14 +314,15 @@ SpamFilter::_AddSpamToSubject(BNode* file, float spamRatio) BString -filter_name() +filter_name(const BMailAccountSettings& accountSettings, + const BMailAddOnSettings* addOnSettings) { return B_TRANSLATE("Bayesian Spam Filter"); } BMailFilter* -instantiate_filter(BMailProtocol& protocol, BMailAddOnSettings* settings) +instantiate_filter(BMailProtocol& protocol, const BMailAddOnSettings& settings) { return new SpamFilter(protocol, settings); } diff --git a/src/add-ons/mail_daemon/inbound_filters/spam_filter/SpamFilter.h b/src/add-ons/mail_daemon/inbound_filters/spam_filter/SpamFilter.h index 980674ef54..96500079ab 100644 --- a/src/add-ons/mail_daemon/inbound_filters/spam_filter/SpamFilter.h +++ b/src/add-ons/mail_daemon/inbound_filters/spam_filter/SpamFilter.h @@ -15,11 +15,9 @@ class SpamFilter : public BMailFilter { public: SpamFilter(BMailProtocol& protocol, - BMailAddOnSettings* settings); + const BMailAddOnSettings& settings); virtual ~SpamFilter(); - virtual BString DescriptiveName() const; - virtual void HeaderFetched(const entry_ref& ref, BFile* file); virtual void BodyFetched(const entry_ref& ref, BFile* file); diff --git a/src/add-ons/mail_daemon/inbound_filters/spam_filter/SpamFilterConfig.cpp b/src/add-ons/mail_daemon/inbound_filters/spam_filter/SpamFilterConfig.cpp index af1625c817..1035c7521f 100644 --- a/src/add-ons/mail_daemon/inbound_filters/spam_filter/SpamFilterConfig.cpp +++ b/src/add-ons/mail_daemon/inbound_filters/spam_filter/SpamFilterConfig.cpp @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include #include @@ -27,7 +29,6 @@ #include #include -#include #include @@ -35,11 +36,11 @@ #define B_TRANSLATION_CONTEXT "SpamFilterConfig" -class SpamFilterConfig : public BView { +class SpamFilterConfig : public BMailSettingsView { public: SpamFilterConfig(const BMessage* settings); - virtual status_t Archive(BMessage* into, bool deep = true) const; + virtual status_t SaveInto(BMailAddOnSettings& settings) const; private: BCheckBox* fSubjectHintCheckBox; @@ -54,7 +55,7 @@ private: SpamFilterConfig::SpamFilterConfig(const BMessage* settings) : - BView("spamfilter_config", 0), + BMailSettingsView("spamfilter_config"), fSubjectHintCheckBox(NULL), fAutoTrainingCheckBox(NULL), fGenuineCutoffRatioTextControl(NULL), @@ -116,27 +117,27 @@ SpamFilterConfig::SpamFilterConfig(const BMessage* settings) status_t -SpamFilterConfig::Archive(BMessage* into, bool /*deep*/) const +SpamFilterConfig::SaveInto(BMailAddOnSettings& settings) const { - into->MakeEmpty(); + settings.MakeEmpty(); - status_t status = into->AddBool("AddMarkerToSubject", + status_t status = settings.AddBool("AddMarkerToSubject", fSubjectHintCheckBox->Value() == B_CONTROL_ON); if (status == B_OK) { - status = into->AddBool("AutoTraining", + status = settings.AddBool("AutoTraining", fAutoTrainingCheckBox->Value() == B_CONTROL_ON); } if (status == B_OK) { - status = into->AddBool("NoWordsMeansSpam", + status = settings.AddBool("NoWordsMeansSpam", fNoWordsMeansSpamCheckBox->Value() == B_CONTROL_ON); } if (status == B_OK) { - status = into->AddFloat("GenuineCutoffRatio", + status = settings.AddFloat("GenuineCutoffRatio", atof(fGenuineCutoffRatioTextControl->Text())); } if (status == B_OK) { - status = into->AddFloat("SpamCutoffRatio", + status = settings.AddFloat("SpamCutoffRatio", atof(fSpamCutoffRatioTextControl->Text())); } @@ -147,8 +148,9 @@ SpamFilterConfig::Archive(BMessage* into, bool /*deep*/) const // #pragma mark - -BView* -instantiate_filter_config_panel(BMailAddOnSettings& settings) +BMailSettingsView* +instantiate_filter_settings_view(const BMailAccountSettings& accountSettings, + const BMailAddOnSettings& settings) { return new SpamFilterConfig(&settings); } diff --git a/src/kits/mail/Jamfile b/src/kits/mail/Jamfile index a8c73300a0..7eb8a177a4 100644 --- a/src/kits/mail/Jamfile +++ b/src/kits/mail/Jamfile @@ -29,6 +29,7 @@ local sources = MailMessage.cpp MailProtocol.cpp MailSettings.cpp + MailSettingsView.cpp NodeMessage.cpp numailkit.cpp ProtocolConfigView.cpp diff --git a/src/kits/mail/MailFilter.cpp b/src/kits/mail/MailFilter.cpp index 5cd98c8929..5ef9115ebd 100644 --- a/src/kits/mail/MailFilter.cpp +++ b/src/kits/mail/MailFilter.cpp @@ -6,7 +6,8 @@ #include -BMailFilter::BMailFilter(BMailProtocol& protocol, BMailAddOnSettings* settings) +BMailFilter::BMailFilter(BMailProtocol& protocol, + const BMailAddOnSettings* settings) : fMailProtocol(protocol), fSettings(settings) diff --git a/src/kits/mail/MailProtocol.cpp b/src/kits/mail/MailProtocol.cpp index a0824009b2..41113150b1 100644 --- a/src/kits/mail/MailProtocol.cpp +++ b/src/kits/mail/MailProtocol.cpp @@ -305,7 +305,7 @@ BMailProtocol::LoadFilters(const BMailProtocolSettings& settings) { for (int i = 0; i < settings.CountFilterSettings(); i++) { BMailAddOnSettings* filterSettings = settings.FilterSettingsAt(i); - BMailFilter* filter = _LoadFilter(filterSettings); + BMailFilter* filter = _LoadFilter(*filterSettings); if (filter != NULL) AddFilter(filter); } @@ -313,9 +313,9 @@ BMailProtocol::LoadFilters(const BMailProtocolSettings& settings) BMailFilter* -BMailProtocol::_LoadFilter(BMailAddOnSettings* filterSettings) +BMailProtocol::_LoadFilter(const BMailAddOnSettings& settings) { - const entry_ref& ref = filterSettings->AddOnRef(); + const entry_ref& ref = settings.AddOnRef(); std::map::iterator it = fFilterImages.find(ref); image_id image; if (it != fFilterImages.end()) @@ -328,16 +328,16 @@ BMailProtocol::_LoadFilter(BMailAddOnSettings* filterSettings) if (image < 0) return NULL; - BMailFilter* (*instantiate_filter)(BMailProtocol& protocol, - BMailAddOnSettings* settings); + BMailFilter* (*instantiateFilter)(BMailProtocol& protocol, + const BMailAddOnSettings& settings); if (get_image_symbol(image, "instantiate_filter", B_SYMBOL_TYPE_TEXT, - (void**)&instantiate_filter) != B_OK) { + (void**)&instantiateFilter) != B_OK) { unload_add_on(image); return NULL; } fFilterImages[ref] = image; - return (*instantiate_filter)(*this, filterSettings); + return instantiateFilter(*this, settings); } diff --git a/src/kits/mail/MailSettings.cpp b/src/kits/mail/MailSettings.cpp index 6f906b6eed..638a3832d9 100644 --- a/src/kits/mail/MailSettings.cpp +++ b/src/kits/mail/MailSettings.cpp @@ -460,6 +460,8 @@ BMailAddOnSettings::Load(const BMessage& message) MakeEmpty(); Append(settings); +puts("settings:"); +settings.PrintToStream(); fOriginalSettings = *this; fOriginalRef = fRef; diff --git a/src/kits/mail/MailSettingsView.cpp b/src/kits/mail/MailSettingsView.cpp new file mode 100644 index 0000000000..c79bda3301 --- /dev/null +++ b/src/kits/mail/MailSettingsView.cpp @@ -0,0 +1,19 @@ +/* + * Copyright 2012, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + */ + + +#include + + +BMailSettingsView::BMailSettingsView(const char* name) + : + BView(name, 0) +{ +} + + +BMailSettingsView::~BMailSettingsView() +{ +} diff --git a/src/kits/mail/ProtocolConfigView.cpp b/src/kits/mail/ProtocolConfigView.cpp index 7775bb7dac..0132f4745d 100644 --- a/src/kits/mail/ProtocolConfigView.cpp +++ b/src/kits/mail/ProtocolConfigView.cpp @@ -394,7 +394,7 @@ MailProtocolConfigView::_StoreIndexOfMarked(BMessage& message, const char* name, BMenuField* field) const { int32 index = -1; - if (field != NULL) { + if (field != NULL && field->Menu() != NULL) { BMenuItem* item = field->Menu()->FindMarked(); if (item != NULL) index = field->Menu()->IndexOf(item); diff --git a/src/preferences/mail/ConfigViews.cpp b/src/preferences/mail/ConfigViews.cpp index eab3c04367..618265efa8 100644 --- a/src/preferences/mail/ConfigViews.cpp +++ b/src/preferences/mail/ConfigViews.cpp @@ -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; } diff --git a/src/preferences/mail/ConfigViews.h b/src/preferences/mail/ConfigViews.h index 60692ecee3..fa1e6cc5f8 100644 --- a/src/preferences/mail/ConfigViews.h +++ b/src/preferences/mail/ConfigViews.h @@ -12,8 +12,11 @@ #include #include -#include "MailSettings.h" +#include +#include + #include + #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; }; diff --git a/src/preferences/mail/ConfigWindow.cpp b/src/preferences/mail/ConfigWindow.cpp index bb6be61af0..28da6cbcf1 100644 --- a/src/preferences/mail/ConfigWindow.cpp +++ b/src/preferences/mail/ConfigWindow.cpp @@ -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: diff --git a/src/preferences/mail/FilterConfigView.cpp b/src/preferences/mail/FilterConfigView.cpp index 5129cd3398..ef20cc3232 100644 --- a/src/preferences/mail/FilterConfigView.cpp +++ b/src/preferences/mail/FilterConfigView.cpp @@ -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); } } diff --git a/src/preferences/mail/FilterConfigView.h b/src/preferences/mail/FilterConfigView.h index a0110a1aaf..5c31e8c5c1 100644 --- a/src/preferences/mail/FilterConfigView.h +++ b/src/preferences/mail/FilterConfigView.h @@ -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 diff --git a/src/preferences/mail/FilterList.cpp b/src/preferences/mail/FilterList.cpp index 09f03c6036..a717b049b9 100644 --- a/src/preferences/mail/FilterList.cpp +++ b/src/preferences/mail/FilterList.cpp @@ -7,17 +7,17 @@ #include "FilterList.h" +#include + #include #include #include -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 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; } diff --git a/src/preferences/mail/FilterList.h b/src/preferences/mail/FilterList.h index 157851624e..ac46aedff5 100644 --- a/src/preferences/mail/FilterList.h +++ b/src/preferences/mail/FilterList.h @@ -8,7 +8,7 @@ #include -#include +#include 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 fList; };