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