/*
* Copyright 2004-2016, Haiku, Inc. All rights reserved.
* Copyright 2001 Dr. Zoidberg Enterprises. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/
#include <stdio.h>
#include <Catalog.h>
#include <LayoutBuilder.h>
#include <MailFilter.h>
#include <MailSettings.h>
#include <MailSettingsView.h>
#include <MenuField.h>
#include <MenuItem.h>
#include <Message.h>
#include <PopUpMenu.h>
#include <TextControl.h>
#include <FileConfigView.h>
#include "MatchHeaderSettings.h"
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "ConfigView"
using namespace BPrivate;
static const uint32 kMsgActionChanged = 'actC';
class RuleFilterConfig : public BMailSettingsView {
public:
RuleFilterConfig(
const BMailAddOnSettings& settings);
virtual status_t SaveInto(BMailAddOnSettings& settings) const;
virtual void MessageReceived(BMessage* message);
virtual void AttachedToWindow();
private:
void _SetVisible(BView* view, bool visible);
private:
BTextControl* fAttributeControl;
BTextControl* fRegexControl;
FileControl* fFileControl;
BTextControl* fFlagsControl;
BPopUpMenu* fActionMenu;
BPopUpMenu* fAccountMenu;
BMenuField* fAccountField;
int fAction;
int32 fAccountID;
};
RuleFilterConfig::RuleFilterConfig(const BMailAddOnSettings& addOnSettings)
:
BMailSettingsView("rulefilter_config"),
fActionMenu(NULL)
{
SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
MatchHeaderSettings settings(addOnSettings);
fAction = settings.Action();
fAttributeControl = new BTextControl("attr", B_TRANSLATE("If"), NULL, NULL);
fAttributeControl->SetToolTip(
B_TRANSLATE("Header field (e.g. Subject, From, " B_UTF8_ELLIPSIS ")"));
fAttributeControl->SetText(settings.Attribute());
fRegexControl = new BTextControl("regex", B_TRANSLATE("has"), NULL, NULL);
fRegexControl->SetToolTip(B_TRANSLATE("Wildcard value like \"*spam*\".\n"
"Prefix with \"REGEX:\" in order to use regular expressions."));
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);
fFileControl->SetText(settings.MoveTarget());
fFlagsControl = new BTextControl("flags", NULL, NULL);
fFlagsControl->SetText(settings.SetFlagsTo());
// Populate account menu
fAccountMenu = new BPopUpMenu(B_TRANSLATE("<Choose account>"));
fAccountID = settings.ReplyAccount();
BMailAccounts accounts;
for (int32 i = 0; i < accounts.CountAccounts(); i++) {
BMailAccountSettings* account = accounts.AccountAt(i);
if (!account->HasOutbound())
continue;
BMessage* message = new BMessage();
message->AddInt32("account id", account->AccountID());
BMenuItem* item = new BMenuItem(account->Name(), message);
fAccountMenu->AddItem(item);
if (account->AccountID() == fAccountID)
item->SetMarked(true);
}
fAccountField = new BMenuField("reply", B_TRANSLATE("Account"),
fAccountMenu);
// Popuplate action menu
fActionMenu = new BPopUpMenu(B_TRANSLATE("<Choose action>"));
const struct {
rule_action action;
const char* label;
} kActions[] = {
{ACTION_MOVE_TO, B_TRANSLATE("Move to")},
{ACTION_SET_FLAGS_TO, B_TRANSLATE("Set flags to")},
{ACTION_DELETE_MESSAGE, B_TRANSLATE("Delete message")},
{ACTION_REPLY_WITH, B_TRANSLATE("Reply with")},
{ACTION_SET_AS_READ, B_TRANSLATE("Set as read")},
};
for (size_t i = 0; i < sizeof(kActions) / sizeof(kActions[0]); i++) {
BMessage* message = new BMessage(kMsgActionChanged);
message->AddInt32("action", (int32)kActions[i].action);
fActionMenu->AddItem(new BMenuItem(kActions[i].label, message));
}
BMenuField* actionField = new BMenuField("action", B_TRANSLATE("Then"),
fActionMenu);
if (fAction >= 0) {
BMenuItem* item = fActionMenu->ItemAt(fAction);
if (item != NULL) {
item->SetMarked(true);
MessageReceived(item->Message());
}
}
// Build layout
BLayoutBuilder::Group<>(this, B_VERTICAL)
.AddGroup(B_HORIZONTAL)
.Add(fAttributeControl->CreateLabelLayoutItem())
.Add(fAttributeControl->CreateTextViewLayoutItem())
.Add(fRegexControl->CreateLabelLayoutItem())
.Add(fRegexControl->CreateTextViewLayoutItem())
.End()
.AddGroup(B_HORIZONTAL)
.Add(actionField->CreateLabelLayoutItem())
.Add(actionField->CreateMenuBarLayoutItem())
.End()
.Add(fFileControl)
.Add(fAccountField);
}
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()
{
fActionMenu->SetTargetForItems(this);
}
void
RuleFilterConfig::MessageReceived(BMessage* message)
{
switch (message->what) {
case kMsgActionChanged:
fAction = message->FindInt32("action");
_SetVisible(fFileControl, fAction == ACTION_MOVE_TO);
_SetVisible(fFlagsControl, fAction == ACTION_SET_FLAGS_TO);
_SetVisible(fAccountField, fAction == ACTION_REPLY_WITH);
break;
default:
BView::MessageReceived(message);
}
}
void
RuleFilterConfig::_SetVisible(BView* view, bool visible)
{
while (visible && view->IsHidden(view))
view->Show();
while (!visible && !view->IsHidden(view))
view->Hide();
}
// #pragma mark -
BMailSettingsView*
instantiate_filter_settings_view(const BMailAccountSettings& accountSettings,
const BMailAddOnSettings& settings)
{
return new RuleFilterConfig(settings);
}
↑ V773 Visibility scope of the 'actionField' pointer was exited without releasing the memory. A memory leak is possible.