1/*
2 * Copyright 2004-2016, Haiku, Inc. All rights reserved.
3 * Copyright 2001 Dr. Zoidberg Enterprises. All rights reserved.
4 *
5 * Distributed under the terms of the MIT License.
6 */
7
8
9#include <stdio.h>
10
11#include <Catalog.h>
12#include <LayoutBuilder.h>
13#include <MailFilter.h>
14#include <MailSettings.h>
15#include <MailSettingsView.h>
16#include <MenuField.h>
17#include <MenuItem.h>
18#include <Message.h>
19#include <PopUpMenu.h>
20#include <TextControl.h>
21
22#include <FileConfigView.h>
23
24#include "MatchHeaderSettings.h"
25
26
27#undef B_TRANSLATION_CONTEXT
28#define B_TRANSLATION_CONTEXT "ConfigView"
29
30
31using namespace BPrivate;
32
33
34static const uint32 kMsgActionChanged = 'actC';
35
36
37class RuleFilterConfig : public BMailSettingsView {
38public:
39								RuleFilterConfig(
40									const BMailAddOnSettings& settings);
41
42	virtual status_t			SaveInto(BMailAddOnSettings& settings) const;
43
44	virtual	void				MessageReceived(BMessage* message);
45	virtual	void				AttachedToWindow();
46
47private:
48			void				_SetVisible(BView* view, bool visible);
49
50private:
51			BTextControl*		fAttributeControl;
52			BTextControl*		fRegexControl;
53			FileControl*		fFileControl;
54			BTextControl*		fFlagsControl;
55			BPopUpMenu*			fActionMenu;
56			BPopUpMenu*			fAccountMenu;
57			BMenuField*			fAccountField;
58			int					fAction;
59			int32				fAccountID;
60};
61
62
63RuleFilterConfig::RuleFilterConfig(const BMailAddOnSettings& addOnSettings)
64	:
65	BMailSettingsView("rulefilter_config"),
66	fActionMenu(NULL)
67{
68	SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
69
70	MatchHeaderSettings settings(addOnSettings);
71	fAction = settings.Action();
72
73	fAttributeControl = new BTextControl("attr", B_TRANSLATE("If"), NULL, NULL);
74	fAttributeControl->SetToolTip(
75		B_TRANSLATE("Header field (e.g. Subject, From, " B_UTF8_ELLIPSIS ")"));
76	fAttributeControl->SetText(settings.Attribute());
77
78	fRegexControl = new BTextControl("regex", B_TRANSLATE("has"), NULL, NULL);
79	fRegexControl->SetToolTip(B_TRANSLATE("Wildcard value like \"*spam*\".\n"
80		"Prefix with \"REGEX:\" in order to use regular expressions."));
81	fRegexControl->SetText(settings.Expression());
82
83	fFileControl = new FileControl("arg", NULL,
84		B_TRANSLATE("this field is based on the action"));
85	if (BControl* control = (BControl*)fFileControl->FindView("select_file"))
86		control->SetEnabled(false);
87	fFileControl->SetText(settings.MoveTarget());
88
89	fFlagsControl = new BTextControl("flags", NULL, NULL);
90	fFlagsControl->SetText(settings.SetFlagsTo());
91
92	// Populate account menu
93
94	fAccountMenu = new BPopUpMenu(B_TRANSLATE("<Choose account>"));
95	fAccountID = settings.ReplyAccount();
96
97	BMailAccounts accounts;
98	for (int32 i = 0; i < accounts.CountAccounts(); i++) {
99		BMailAccountSettings* account = accounts.AccountAt(i);
100		if (!account->HasOutbound())
101			continue;
102
103		BMessage* message = new BMessage();
104		message->AddInt32("account id", account->AccountID());
105
106		BMenuItem* item = new BMenuItem(account->Name(), message);
107		fAccountMenu->AddItem(item);
108		if (account->AccountID() == fAccountID)
109			item->SetMarked(true);
110	}
111
112	fAccountField = new BMenuField("reply", B_TRANSLATE("Account"),
113		fAccountMenu);
114
115	// Popuplate action menu
116
117	fActionMenu = new BPopUpMenu(B_TRANSLATE("<Choose action>"));
118
119	const struct {
120		rule_action	action;
121		const char*	label;
122	} kActions[] = {
123		{ACTION_MOVE_TO, B_TRANSLATE("Move to")},
124		{ACTION_SET_FLAGS_TO, B_TRANSLATE("Set flags to")},
125		{ACTION_DELETE_MESSAGE, B_TRANSLATE("Delete message")},
126		{ACTION_REPLY_WITH, B_TRANSLATE("Reply with")},
127		{ACTION_SET_AS_READ, B_TRANSLATE("Set as read")},
128	};
129	for (size_t i = 0; i < sizeof(kActions) / sizeof(kActions[0]); i++) {
130		BMessage* message = new BMessage(kMsgActionChanged);
131		message->AddInt32("action", (int32)kActions[i].action);
132
133		fActionMenu->AddItem(new BMenuItem(kActions[i].label, message));
134	}
135
136	BMenuField* actionField = new BMenuField("action", B_TRANSLATE("Then"),
137		fActionMenu);
138	if (fAction >= 0) {
139		BMenuItem* item = fActionMenu->ItemAt(fAction);
140		if (item != NULL) {
141			item->SetMarked(true);
142			MessageReceived(item->Message());
143		}
144	}
145
146	// Build layout
147
148	BLayoutBuilder::Group<>(this, B_VERTICAL)
149		.AddGroup(B_HORIZONTAL)
150			.Add(fAttributeControl->CreateLabelLayoutItem())
151			.Add(fAttributeControl->CreateTextViewLayoutItem())
152			.Add(fRegexControl->CreateLabelLayoutItem())
153			.Add(fRegexControl->CreateTextViewLayoutItem())
154		.End()
155		.AddGroup(B_HORIZONTAL)
156			.Add(actionField->CreateLabelLayoutItem())
157			.Add(actionField->CreateMenuBarLayoutItem())
158		.End()
159		.Add(fFileControl)
160		.Add(fAccountField);
161}
162
163
164status_t
165RuleFilterConfig::SaveInto(BMailAddOnSettings& settings) const
166{
167	int32 action = fActionMenu->IndexOf(fActionMenu->FindMarked());
168	settings.SetInt32("action", action);
169	settings.SetString("attribute", fAttributeControl->Text());
170	settings.SetString("regex", fRegexControl->Text());
171
172	switch (action) {
173		case ACTION_MOVE_TO:
174			settings.SetString("move target", fFileControl->Text());
175			break;
176
177		case ACTION_SET_FLAGS_TO:
178			settings.SetString("set flags", fFlagsControl->Text());
179			break;
180
181		case ACTION_REPLY_WITH:
182		{
183			BMenuItem* item = fAccountMenu->FindMarked();
184			if (item != NULL) {
185				settings.SetInt32("account",
186					item->Message()->FindInt32("account id"));
187			}
188			break;
189		}
190	}
191
192	return B_OK;
193}
194
195
196void
197RuleFilterConfig::AttachedToWindow()
198{
199	fActionMenu->SetTargetForItems(this);
200}
201
202
203void
204RuleFilterConfig::MessageReceived(BMessage* message)
205{
206	switch (message->what) {
207		case kMsgActionChanged:
208			fAction = message->FindInt32("action");
209
210			_SetVisible(fFileControl, fAction == ACTION_MOVE_TO);
211			_SetVisible(fFlagsControl, fAction == ACTION_SET_FLAGS_TO);
212			_SetVisible(fAccountField, fAction == ACTION_REPLY_WITH);
213			break;
214
215		default:
216			BView::MessageReceived(message);
217	}
218}
219
220
221void
222RuleFilterConfig::_SetVisible(BView* view, bool visible)
223{
224	while (visible && view->IsHidden(view))
225		view->Show();
226	while (!visible && !view->IsHidden(view))
227		view->Hide();
228}
229
230
231// #pragma mark -
232
233
234BMailSettingsView*
235instantiate_filter_settings_view(const BMailAccountSettings& accountSettings,
236	const BMailAddOnSettings& settings)
237{
238	return new RuleFilterConfig(settings);
239}
240