예제 #1
0
파일: Prefs.cpp 프로젝트: simonsouth/haiku
BPopUpMenu*
TPrefsWindow::_BuildAccountMenu(int32 account)
{
	BPopUpMenu* menu = new BPopUpMenu("");
	BMenuItem* item;

	//menu->SetRadioMode(true);
	BMailAccounts accounts;
	if (accounts.CountAccounts() == 0) {
		menu->AddItem(item = new BMenuItem(B_TRANSLATE("<no account found>"), NULL));
		item->SetEnabled(false);
		return menu;
	}

	BMessage* msg;
	for (int32 i = 0; i < accounts.CountAccounts(); i++) {
		BMailAccountSettings* settings = accounts.AccountAt(i);
		item = new BMenuItem(settings->Name(), msg = new BMessage(P_ACCOUNT));

		msg->AddInt32("id", settings->AccountID());

		if (account == settings->AccountID())
			item->SetMarked(true);

		menu->AddItem(item);
	}
	return menu;
}
예제 #2
0
void
ConfigWindow::_AccountSelected(AccountItem* item)
{
	AccountUpdated(fLastSelectedAccount);

	BMailAccountSettings* account = item->Account();
	fLastSelectedAccount = account;

	BView* view = NULL;
	switch (item->Type()) {
		case ACCOUNT_ITEM:
			view = new AccountConfigView(account);
			break;

		case INBOUND_ITEM:
			view = new ProtocolSettingsView(account->InboundAddOnRef(),
				*account, account->InboundSettings());
			break;

		case OUTBOUND_ITEM:
			view = new ProtocolSettingsView(account->OutboundAddOnRef(),
				*account, account->OutboundSettings());
			break;

		case FILTER_ITEM:
			view = new FiltersConfigView(*account);
			break;
	}

	_ReplaceConfigView(view);
}
예제 #3
0
void
BEmailMessage::SendViaAccount(const char *account_name)
{
	BMailAccounts accounts;
	BMailAccountSettings* account = accounts.AccountByName(account_name);
	if (!account)
		return;
	SendViaAccount(account->AccountID());
}
예제 #4
0
BMailAccountSettings*
BMailAccounts::AccountByID(int32 id)
{
	for (int i = 0; i < fAccounts.CountItems(); i++) {
		BMailAccountSettings* account = fAccounts.ItemAt(i);
		if (account->AccountID() == id)
			return account;
	}
	return NULL;
}
예제 #5
0
HaikuMailFormatFilter::HaikuMailFormatFilter(BMailProtocol& protocol,
	const BMailAccountSettings& settings)
	:
	BMailFilter(protocol, NULL),
	fAccountID(settings.AccountID()),
	fAccountName(settings.Name())
{
	const BMessage& outboundSettings = settings.OutboundSettings();
	outboundSettings.FindString("destination", &fOutboundDirectory);
}
예제 #6
0
BMailAccountSettings*
BMailAccounts::AccountByName(const char* name)
{
	for (int i = 0; i < fAccounts.CountItems(); i++) {
		BMailAccountSettings* account = fAccounts.ItemAt(i);
		if (strcmp(account->Name(), name) == 0)
			return account;
	}
	return NULL;
}
예제 #7
0
status_t
BEmailMessage::Send(bool sendNow)
{
	BMailAccounts accounts;
	BMailAccountSettings* account = accounts.AccountByID(_account_id);
	if (!account || !account->HasOutbound()) {
		account = accounts.AccountByID(
			BMailSettings().DefaultOutboundAccount());
		if (!account)
			return B_ERROR;
		SendViaAccount(account->AccountID());
	}

	BString path;
	if (account->OutboundSettings().Settings().FindString("path", &path)
			!= B_OK) {
		BPath defaultMailOutPath;
		if (find_directory(B_USER_DIRECTORY, &defaultMailOutPath) != B_OK
			|| defaultMailOutPath.Append("mail/out") != B_OK)
			path = "/boot/home/mail/out";
		else
			path = defaultMailOutPath.Path();
	}

	create_directory(path.String(), 0777);
	BDirectory directory(path.String());

	BEntry message;

	status_t status = RenderTo(&directory, &message);
	if (status >= B_OK && sendNow) {
		BMailSettings settings_file;
		if (settings_file.SendOnlyIfPPPUp()) {
			// TODO!
		}

		BMessenger daemon(B_MAIL_DAEMON_SIGNATURE);
		if (!daemon.IsValid())
			return B_MAIL_NO_DAEMON;

		BMessage msg('msnd');
		msg.AddInt32("account",_account_id);
		BPath path;
		message.GetPath(&path);
		msg.AddString("message_path",path.Path());
		daemon.SendMessage(&msg);
	}

	return status;
}
예제 #8
0
void
BEmailMessage::SendViaAccount(int32 account)
{
	_account_id = account;

	BMailAccounts accounts;
	BMailAccountSettings* accountSettings = accounts.AccountByID(_account_id);

	BString from;
	if (accountSettings) {
		from << '\"' << accountSettings->RealName() << "\" <"
			<< accountSettings->ReturnAddress() << '>';
	}
	SetFrom(from);
}
예제 #9
0
_EXPORT status_t
get_smtp_host(char* buffer)
{
	BMailAccounts accounts;
	BMailAccountSettings* account = accounts.AccountAt(
		BMailSettings().DefaultOutboundAccount());
	if (account == NULL)
		return B_ERROR;

	const BMessage& settings = account->OutboundSettings();

	if (!settings.HasString("server"))
		return B_NAME_NOT_FOUND;

	strcpy(buffer, settings.FindString("server"));
	return B_OK;
}
예제 #10
0
BMailAccounts::BMailAccounts()
{
	BPath path;
	status_t status = AccountsPath(path);
	if (status != B_OK)
		return;

	BDirectory dir(path.Path());
	if (dir.InitCheck() != B_OK)
		return;

	std::vector<time_t> creationTimeList;
	BEntry entry;
	while (dir.GetNextEntry(&entry) != B_ENTRY_NOT_FOUND) {
		BNode node(&entry);
		time_t creationTime;
		if (node.GetCreationTime(&creationTime) != B_OK)
			continue;

		BMailAccountSettings* account = new BMailAccountSettings(entry);
		if (account->InitCheck() != B_OK) {
			delete account;
			continue;
		}

		// sort by creation time
		int insertIndex = -1;
		for (unsigned int i = 0; i < creationTimeList.size(); i++) {
			if (creationTimeList[i] > creationTime) {
				insertIndex = i;
				break;
			}
		}
		if (insertIndex < 0) {
			fAccounts.AddItem(account);
			creationTimeList.push_back(creationTime);
		} else {
			fAccounts.AddItem(account, insertIndex);
			creationTimeList.insert(creationTimeList.begin() + insertIndex,
				creationTime);
		}
	}
}
예제 #11
0
status_t
BEmailMessage::GetAccountName(BString& accountName) const
{
	BFile *file = dynamic_cast<BFile *>(fData);
	if (file == NULL)
		return B_ERROR;

	int32 accountId;
	size_t read = file->ReadAttr(B_MAIL_ATTR_ACCOUNT, B_INT32_TYPE, 0,
		&accountId, sizeof(int32));
	if (read < sizeof(int32))
		return B_ERROR;

	BMailAccounts accounts;
	BMailAccountSettings* account =  accounts.AccountByID(accountId);
	if (account)
		accountName = account->Name();
	else
		accountName = "";

	return B_OK;
}
예제 #12
0
_EXPORT status_t
get_pop_account(mail_pop_account* account, int32 index)
{
	BMailAccounts accounts;
	BMailAccountSettings* accountSettings = accounts.AccountAt(index);
	if (accountSettings == NULL)
		return B_BAD_INDEX;

	const BMessage& settings = accountSettings->InboundSettings();
	strcpy(account->pop_name, settings.FindString("username"));
	strcpy(account->pop_host, settings.FindString("server"));
	strcpy(account->real_name, accountSettings->RealName());
	strcpy(account->reply_to, accountSettings->ReturnAddress());

	const char* encryptedPassword = get_passwd(&settings, "cpasswd");
	const char* password = encryptedPassword;
	if (password == NULL)
		password = settings.FindString("password");
	strcpy(account->pop_password, password);

	delete[] encryptedPassword;
	return B_OK;
}
예제 #13
0
void
MailDaemonApp::_InitAccount(BMailAccountSettings& settings)
{
	account_protocols account;
	// inbound
	if (settings.IsInboundEnabled()) {
		account.inboundProtocol = _CreateInboundProtocol(settings,
			account.inboundImage);
	} else {
		account.inboundProtocol = NULL;
	}
	if (account.inboundProtocol) {
		DefaultNotifier* notifier = new DefaultNotifier(settings.Name(), true,
			fErrorLogWindow, fNotifyMode);
		account.inboundProtocol->SetMailNotifier(notifier);

		account.inboundThread = new InboundProtocolThread(
			account.inboundProtocol);
		account.inboundThread->Run();
	}

	// outbound
	if (settings.IsOutboundEnabled()) {
		account.outboundProtocol = _CreateOutboundProtocol(settings,
			account.outboundImage);
	} else {
		account.outboundProtocol = NULL;
	}
	if (account.outboundProtocol) {
		DefaultNotifier* notifier = new DefaultNotifier(settings.Name(), false,
			fErrorLogWindow, fNotifyMode);
		account.outboundProtocol->SetMailNotifier(notifier);

		account.outboundThread = new OutboundProtocolThread(
			account.outboundProtocol);
		account.outboundThread->Run();
	}

	printf("account name %s, id %i, in %p, out %p\n", settings.Name(),
		(int)settings.AccountID(), account.inboundProtocol,
		account.outboundProtocol);
	if (!account.inboundProtocol && !account.outboundProtocol)
		return;
	fAccounts[settings.AccountID()] = account;
}
예제 #14
0
BPopUpMenu*
DeskbarView::_BuildMenu()
{
	BPopUpMenu* menu = new BPopUpMenu(B_EMPTY_STRING, false, false);
	menu->SetFont(be_plain_font);

	menu->AddItem(new BMenuItem(MDR_DIALECT_CHOICE (
		"Create new message", "N) 新規メッセージ作成")B_UTF8_ELLIPSIS,
		new BMessage(MD_OPEN_NEW)));
	menu->AddSeparatorItem();

	BMessenger tracker(kTrackerSignature);
	BNavMenu* navMenu;
	BMenuItem* item;
	BMessage* msg;
	entry_ref ref;

	BPath path;
	find_directory(B_USER_SETTINGS_DIRECTORY, &path);
	path.Append("Mail/Menu Links");

	BDirectory directory;
	if (_CreateMenuLinks(directory, path)) {
		int32 count = 0;

		while (directory.GetNextRef(&ref) == B_OK) {
			count++;

			path.SetTo(&ref);
			// the true here dereferences the symlinks all the way :)
			BEntry entry(&ref, true);

			// do we want to use the NavMenu, or just an ordinary BMenuItem?
			// we are using the NavMenu only for directories and queries
			bool useNavMenu = false;

			if (entry.InitCheck() == B_OK) {
				if (entry.IsDirectory())
					useNavMenu = true;
				else if (entry.IsFile()) {
					// Files should use the BMenuItem unless they are queries
					char mimeString[B_MIME_TYPE_LENGTH];
					BNode node(&entry);
					BNodeInfo info(&node);
					if (info.GetType(mimeString) == B_OK
						&& strcmp(mimeString, "application/x-vnd.Be-query")
							== 0)
						useNavMenu = true;
				}
				// clobber the existing ref only if the symlink derefernces
				// completely, otherwise we'll stick with what we have
				entry.GetRef(&ref);
			}

			msg = new BMessage(B_REFS_RECEIVED);
			msg->AddRef("refs", &ref);

			if (useNavMenu) {
				item = new BMenuItem(navMenu = new BNavMenu(path.Leaf(),
					B_REFS_RECEIVED, tracker), msg);
				navMenu->SetNavDir(&ref);
			} else
				item = new BMenuItem(path.Leaf(), msg);

			menu->AddItem(item);
			if(entry.InitCheck() != B_OK)
				item->SetEnabled(false);
		}
		if (count > 0)
			menu->AddSeparatorItem();
	}

	// Hack for R5's buggy Query Notification
	#ifdef HAIKU_TARGET_PLATFORM_BEOS
		menu->AddItem(new BMenuItem(
			MDR_DIALECT_CHOICE("Refresh New Mail Count",
				"未読メールカウントを更新"),
			new BMessage(MD_REFRESH_QUERY)));
	#endif

	// The New E-mail query

	if (fNewMessages > 0) {
		BString string;
		MDR_DIALECT_CHOICE(
			string << fNewMessages << " new message"
				<< (fNewMessages != 1 ? "s" : B_EMPTY_STRING),
			string << fNewMessages << " 通の未読メッセージ");

		_GetNewQueryRef(ref);

		item = new BMenuItem(navMenu = new BNavMenu(string.String(),
			B_REFS_RECEIVED, BMessenger(kTrackerSignature)),
			msg = new BMessage(B_REFS_RECEIVED));
		msg->AddRef("refs", &ref);
		navMenu->SetNavDir(&ref);

		menu->AddItem(item);
	} else {
		menu->AddItem(item = new BMenuItem(
			MDR_DIALECT_CHOICE ("No new messages","未読メッセージなし"), NULL));
		item->SetEnabled(false);
	}

	BMailAccounts accounts;
	if (modifiers() & B_SHIFT_KEY) {
		BMenu *accountMenu = new BMenu(
			MDR_DIALECT_CHOICE ("Check for mails only","R) メール受信のみ"));
		BFont font;
		menu->GetFont(&font);
		accountMenu->SetFont(&font);

		for (int32 i = 0; i < accounts.CountAccounts(); i++) {
			BMailAccountSettings* account = accounts.AccountAt(i);

			BMessage* message = new BMessage(MD_CHECK_FOR_MAILS);
			message->AddInt32("account", account->AccountID());

			accountMenu->AddItem(new BMenuItem(account->Name(), message));
		}
		if (accounts.CountAccounts() == 0) {
			item = new BMenuItem("<no accounts>", NULL);
			item->SetEnabled(false);
			accountMenu->AddItem(item);
		}
		accountMenu->SetTargetForItems(this);
		menu->AddItem(new BMenuItem(accountMenu,
			new BMessage(MD_CHECK_FOR_MAILS)));

		// Not used:
		// menu->AddItem(new BMenuItem(MDR_DIALECT_CHOICE (
		// "Check For Mails Only","メール受信のみ"), new BMessage(MD_CHECK_FOR_MAILS)));
		menu->AddItem(new BMenuItem(
			MDR_DIALECT_CHOICE ("Send pending mails", "M) 保留メールを送信"),
		new BMessage(MD_SEND_MAILS)));
	} else {
		menu->AddItem(item = new BMenuItem(
			MDR_DIALECT_CHOICE ("Check for mail now", "C) メールチェック"),
			new BMessage(MD_CHECK_SEND_NOW)));
		if (accounts.CountAccounts() == 0)
			item->SetEnabled(false);
	}

	menu->AddSeparatorItem();
	menu->AddItem(new BMenuItem(
		MDR_DIALECT_CHOICE ("Preferences", "P) メール環境設定") B_UTF8_ELLIPSIS,
		new BMessage(MD_OPEN_PREFS)));

	if (modifiers() & B_SHIFT_KEY) {
		menu->AddItem(new BMenuItem(
			MDR_DIALECT_CHOICE ("Shutdown mail services", "Q) 終了"),
			new BMessage(B_QUIT_REQUESTED)));
	}

	// Reset Item Targets (only those which aren't already set)

	for (int32 i = menu->CountItems(); i-- > 0;) {
		item = menu->ItemAt(i);
		if (item && (msg = item->Message()) != NULL) {
			if (msg->what == B_REFS_RECEIVED)
				item->SetTarget(tracker);
			else
				item->SetTarget(this);
		}
	}
	return menu;
}
예제 #15
0
void
ConfigWindow::MessageReceived(BMessage *msg)
{
	float fontFactor = be_plain_font->Size() / 12.0f;
	BRect autoConfigRect(0, 0, 400 * fontFactor, 300 * fontFactor);
	BRect frame;

	AutoConfigWindow *autoConfigWindow = NULL;
	switch (msg->what) {
		case B_COLORS_UPDATED:
		{
			rgb_color textColor;
			if (msg->FindColor(ui_color_name(B_PANEL_TEXT_COLOR), &textColor)
					== B_OK) {
				BFont font;
				fHowToTextView->SetFontAndColor(&font, 0, &textColor);
			}
			break;
		}

		case kMsgAccountsRightClicked:
		{
			BPoint point;
			msg->FindPoint("point", &point);
			int32 index = msg->FindInt32("index");
			AccountItem* clickedItem = dynamic_cast<AccountItem*>(
				fAccountsListView->ItemAt(index));
			if (clickedItem == NULL || clickedItem->Type() != ACCOUNT_ITEM)
				break;

			BPopUpMenu rightClickMenu("accounts", false, false);

			BMenuItem* inMenuItem = new BMenuItem(B_TRANSLATE("Incoming"),
				NULL);
			BMenuItem* outMenuItem = new BMenuItem(B_TRANSLATE("Outgoing"),
				NULL);
			rightClickMenu.AddItem(inMenuItem);
			rightClickMenu.AddItem(outMenuItem);

			BMailAccountSettings* settings = clickedItem->Account();
			if (settings->IsInboundEnabled())
				inMenuItem->SetMarked(true);
			if (settings->IsOutboundEnabled())
				outMenuItem->SetMarked(true);

			BMenuItem* selectedItem = rightClickMenu.Go(point);
			if (selectedItem == NULL)
				break;
			if (selectedItem == inMenuItem) {
				AccountItem* item = dynamic_cast<AccountItem*>(
					fAccountsListView->ItemAt(index + 1));
				if (item == NULL)
					break;
				if (settings->IsInboundEnabled()) {
					settings->SetInboundEnabled(false);
					item->SetEnabled(false);
				} else {
					settings->SetInboundEnabled(true);
					item->SetEnabled(true);
				}
			} else {
				AccountItem* item = dynamic_cast<AccountItem*>(
					fAccountsListView->ItemAt(index + 2));
				if (item == NULL)
					break;
				if (settings->IsOutboundEnabled()) {
					settings->SetOutboundEnabled(false);
					item->SetEnabled(false);
				} else {
					settings->SetOutboundEnabled(true);
					item->SetEnabled(true);
				}
			}
		}

		case kMsgAccountSelected:
		{
			int32 index;
			if (msg->FindInt32("index", &index) != B_OK || index < 0) {
				// deselect current item
				_ReplaceConfigView(_BuildHowToView());
				break;
			}
			AccountItem* item = (AccountItem*)fAccountsListView->ItemAt(index);
			if (item != NULL)
				_AccountSelected(item);
			break;
		}

		case kMsgAddAccount:
		{
			frame = Frame();
			autoConfigRect.OffsetTo(
				frame.left + (frame.Width() - autoConfigRect.Width()) / 2,
				frame.top + (frame.Width() - autoConfigRect.Height()) / 2);
			autoConfigWindow = new AutoConfigWindow(autoConfigRect, this);
			autoConfigWindow->Show();
			break;
		}

		case kMsgRemoveAccount:
		{
			int32 index = fAccountsListView->CurrentSelection();
			if (index >= 0) {
				AccountItem *item = (AccountItem *)fAccountsListView->ItemAt(
					index);
				if (item != NULL) {
					_RemoveAccount(item->Account());
					_ReplaceConfigView(_BuildHowToView());
				}
			}
			break;
		}

		case kMsgIntervalUnitChanged:
		{
			int32 index;
			if (msg->FindInt32("index",&index) == B_OK)
				fIntervalControl->SetEnabled(index != 0);
			break;
		}

		case kMsgShowStatusWindowChanged:
		{
			// the status window stuff is the only "live" setting
			BMessenger messenger("application/x-vnd.Be-POST");
			if (messenger.IsValid())
				messenger.SendMessage(msg);
			break;
		}

		case kMsgRevertSettings:
			_RevertToLastSettings();
			break;

		case kMsgSaveSettings:
			fSaveSettings = true;
			_SaveSettings();
			AccountUpdated(fLastSelectedAccount);
			_ReplaceConfigView(_BuildHowToView());
			fAccountsListView->DeselectAll();
			break;

		default:
			BWindow::MessageReceived(msg);
			break;
	}
}
예제 #16
0
void
ConfigWindow::_SaveSettings()
{
	// collect changed accounts
	BMessage changedAccounts(BPrivate::kMsgAccountsChanged);
	for (int32 i = 0; i < fAccounts.CountItems(); i++) {
		BMailAccountSettings* account = fAccounts.ItemAt(i);
		if (account && account->HasBeenModified())
			changedAccounts.AddInt32("account", account->AccountID());
	}
	for (int32 i = 0; i < fToDeleteAccounts.CountItems(); i++) {
		BMailAccountSettings* account = fToDeleteAccounts.ItemAt(i);
		changedAccounts.AddInt32("account", account->AccountID());
	}

	// cleanup account directory
	for (int32 i = 0; i < fToDeleteAccounts.CountItems(); i++) {
		BMailAccountSettings* account = fToDeleteAccounts.ItemAt(i);
		BEntry entry(account->AccountFile());
		entry.Remove();
		delete account;
	}
	fToDeleteAccounts.MakeEmpty();

	// Apply and save general settings

	BMailSettings settings;
	if (fSaveSettings) {
		bigtime_t interval = 0;
		if (fCheckMailCheckBox->Value() == B_CONTROL_ON) {
			// figure out time interval
			float floatInterval;
			sscanf(fIntervalControl->Text(), "%f", &floatInterval);
			interval = bigtime_t(60000000L * floatInterval);
		}

		settings.SetAutoCheckInterval(interval);
		settings.SetDaemonAutoStarts(!fAccounts.IsEmpty());

		// status mode (alway, fetching/retrieving, ...)
		int32 index = fStatusModeField->Menu()->IndexOf(
			fStatusModeField->Menu()->FindMarked());
		settings.SetShowStatusWindow(index);

		settings.Save();
	}

	// Save accounts

	if (fSaveSettings) {
		for (int i = 0; i < fAccounts.CountItems(); i++)
			fAccounts.ItemAt(i)->Save();
	}

	BMessenger messenger(B_MAIL_DAEMON_SIGNATURE);
	if (messenger.IsValid()) {
		// server should reload general settings
		messenger.SendMessage(BPrivate::kMsgSettingsUpdated);
		// notify server about changed accounts
		messenger.SendMessage(&changedAccounts);
	}

	// Start/stop the mail_daemon depending on the settings
	BMailDaemon daemon;
	if (fSaveSettings) {
		if (settings.DaemonAutoStarts() && !daemon.IsRunning())
			daemon.Launch();
		else if (!settings.DaemonAutoStarts() && daemon.IsRunning())
			daemon.Quit();
	}
}
예제 #17
0
파일: Header.cpp 프로젝트: sahil9912/haiku
THeaderView::THeaderView(BRect rect, BRect windowRect, bool incoming,
	bool resending, uint32 defaultCharacterSet, int32 defaultAccount)
	:
	BBox(rect, "m_header", B_FOLLOW_LEFT_RIGHT, B_WILL_DRAW, B_NO_BORDER),

	fAccountMenu(NULL),
	fEncodingMenu(NULL),
	fAccountID(defaultAccount),
	fAccountTo(NULL),
	fAccount(NULL),
	fBcc(NULL),
	fCc(NULL),
	fSubject(NULL),
	fTo(NULL),
	fDateLabel(NULL),
	fDate(NULL),
	fIncoming(incoming),
	fCharacterSetUserSees(defaultCharacterSet),
	fResending(resending),
	fBccMenu(NULL),
	fCcMenu(NULL),
	fToMenu(NULL),
	fEmailList(NULL)
{
	BMenuField* field;
	BMessage* msg;

	float x = StringWidth( /* The longest title string in the header area */
		B_TRANSLATE("Attachments: ")) + 9;
	float y = TO_FIELD_V;

	BMenuBar* dummy = new BMenuBar(BRect(0, 0, 100, 15), "Dummy");
	AddChild(dummy);
	float width, menuBarHeight;
	dummy->GetPreferredSize(&width, &menuBarHeight);
	dummy->RemoveSelf();
	delete dummy;

	float menuFieldHeight = menuBarHeight + 6;
	float controlHeight = menuBarHeight + floorf(be_plain_font->Size() / 1.15);

	if (!fIncoming) {
		InitEmailCompletion();
		InitGroupCompletion();
	}

	// Prepare the character set selection pop-up menu (we tell the user that
	// it is the Encoding menu, even though it is really the character set).
	// It may appear in the first line, to the right of the From box if the
	// user is reading an e-mail.  It appears on the second line, to the right
	// of the e-mail account menu, if the user is composing a message.  It lets
	// the user quickly select a character set different from the application
	// wide default one, and also shows them which character set is active.  If
	// you are reading a message, you also see an item that says "Automatic"
	// for automatic decoding character set choice.  It can slide around as the
	// window is resized when viewing a message, but not when composing
	// (because the adjacent pop-up menu can't resize dynamically due to a BeOS
	// bug).

	float widestCharacterSet = 0;
	bool markedCharSet = false;
	BMenuItem* item;

	fEncodingMenu = new BPopUpMenu(B_EMPTY_STRING);

	BCharacterSetRoster roster;
	BCharacterSet charset;
	while (roster.GetNextCharacterSet(&charset) == B_OK) {
		BString name(charset.GetPrintName());
		const char* mime = charset.GetMIMEName();
		if (mime)
			name << " (" << mime << ")";

		uint32 convertID;
		if (mime == NULL || strcasecmp(mime, "UTF-8") != 0)
			convertID = charset.GetConversionID();
		else
			convertID = B_MAIL_UTF8_CONVERSION;

		msg = new BMessage(kMsgEncoding);
		msg->AddInt32("charset", convertID);
		fEncodingMenu->AddItem(item = new BMenuItem(name.String(), msg));
		if (convertID == fCharacterSetUserSees && !markedCharSet) {
			item->SetMarked(true);
			markedCharSet = true;
		}
		if (StringWidth(name.String()) > widestCharacterSet)
			widestCharacterSet = StringWidth(name.String());
	}

	msg = new BMessage(kMsgEncoding);
	msg->AddInt32("charset", B_MAIL_US_ASCII_CONVERSION);
	fEncodingMenu->AddItem(item = new BMenuItem("US-ASCII", msg));
	if (fCharacterSetUserSees == B_MAIL_US_ASCII_CONVERSION && !markedCharSet) {
		item->SetMarked(true);
		markedCharSet = true;
	}

	if (!resending && fIncoming) {
		// reading a message, display the Automatic item
		fEncodingMenu->AddSeparatorItem();
		msg = new BMessage(kMsgEncoding);
		msg->AddInt32("charset", B_MAIL_NULL_CONVERSION);
		fEncodingMenu->AddItem(item = new BMenuItem(B_TRANSLATE("Automatic"), msg));
		if (!markedCharSet)
			item->SetMarked(true);
	}

	// First line of the header, From for reading e-mails (includes the
	// character set choice at the right), To when composing (nothing else in
	// the row).

	BRect r;
	char string[20];
	if (fIncoming && !resending) {
		// Set up the character set pop-up menu on the right of "To" box.
		r.Set (windowRect.Width() - widestCharacterSet -
			StringWidth (B_TRANSLATE("Decoding:")) - 2 * SEPARATOR_MARGIN,
				y - 2, windowRect.Width() - SEPARATOR_MARGIN,
				y + menuFieldHeight);
		field = new BMenuField (r, "decoding", B_TRANSLATE("Decoding:"),
			fEncodingMenu, true /* fixedSize */,
			B_FOLLOW_TOP | B_FOLLOW_RIGHT,
			B_WILL_DRAW | B_NAVIGABLE | B_NAVIGABLE_JUMP);
		field->SetDivider(field->StringWidth(B_TRANSLATE("Decoding:")) + 5);
		AddChild(field);
		r.Set(SEPARATOR_MARGIN, y,
			  field->Frame().left - SEPARATOR_MARGIN, y + menuFieldHeight);
		sprintf(string, B_TRANSLATE("From:"));
	} else {
		r.Set(x - 12, y, windowRect.Width() - SEPARATOR_MARGIN,
			y + menuFieldHeight);
		string[0] = 0;
	}

	y += controlHeight;
	fTo = new TTextControl(r, string, new BMessage(TO_FIELD), fIncoming,
		resending, B_FOLLOW_LEFT_RIGHT);
	fTo->SetFilter(mail_to_filter);

	if (!fIncoming || resending) {
		fTo->SetChoiceList(&fEmailList);
		fTo->SetAutoComplete(true);
	} else {
		fTo->SetDivider(x - 12 - SEPARATOR_MARGIN);
		fTo->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
	}

	AddChild(fTo);
	msg = new BMessage(FIELD_CHANGED);
	msg->AddInt32("bitmask", FIELD_TO);
	fTo->SetModificationMessage(msg);

	if (!fIncoming || resending) {
		r.right = r.left - 5;
		r.left = r.right - ceilf(be_plain_font->StringWidth(
			B_TRANSLATE("To:")) + 25);
		r.top -= 1;
		fToMenu = new QPopupMenu(B_TRANSLATE("To:"));
		field = new BMenuField(r, "", "", fToMenu, true,
			B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW);
		field->SetDivider(0.0);
		field->SetEnabled(true);
		AddChild(field);
	}

	// "From:" accounts Menu and Encoding Menu.
	if (!fIncoming || resending) {
		// Put the character set box on the right of the From field.
		r.Set(windowRect.Width() - widestCharacterSet -
			StringWidth(B_TRANSLATE("Encoding:")) - 2 * SEPARATOR_MARGIN,
			y - 2, windowRect.Width() - SEPARATOR_MARGIN, y + menuFieldHeight);
		BMenuField* encodingField = new BMenuField(r, "encoding",
			B_TRANSLATE("Encoding:"), fEncodingMenu, true /* fixedSize */,
			B_FOLLOW_TOP | B_FOLLOW_RIGHT,
			B_WILL_DRAW | B_NAVIGABLE | B_NAVIGABLE_JUMP);
		encodingField->SetDivider(encodingField->StringWidth(
			B_TRANSLATE("Encoding:")) + 5);
		AddChild(encodingField);

		field = encodingField;

		// And now the "from account" pop-up menu, on the left side, taking the
		// remaining space.

		fAccountMenu = new BPopUpMenu(B_EMPTY_STRING);

		BMailAccounts accounts;
		bool marked = false;
		for (int32 i = 0; i < accounts.CountAccounts(); i++) {
			BMailAccountSettings* account = accounts.AccountAt(i);
			BString name = account->Name();
			name << ":   " << account->RealName() << "  <"
				<< account->ReturnAddress() << ">";

			msg = new BMessage(kMsgFrom);
			BMenuItem *item = new BMenuItem(name, msg);

			msg->AddInt32("id", account->AccountID());

			if (defaultAccount == account->AccountID()) {
				item->SetMarked(true);
				marked = true;
			}
			fAccountMenu->AddItem(item);
		}

		if (!marked) {
			BMenuItem *item = fAccountMenu->ItemAt(0);
			if (item != NULL) {
				item->SetMarked(true);
				fAccountID = item->Message()->FindInt32("id");
			} else {
				fAccountMenu->AddItem(
					item = new BMenuItem(B_TRANSLATE("<none>"), NULL));
				item->SetEnabled(false);
				fAccountID = ~0UL;
			}
			// default account is invalid, set to marked
			// TODO: do this differently, no casting and knowledge
			// of TMailApp here....
			if (TMailApp* app = dynamic_cast<TMailApp*>(be_app))
				app->SetDefaultAccount(fAccountID);
		}

		r.Set(SEPARATOR_MARGIN, y - 2,
			  field->Frame().left - SEPARATOR_MARGIN, y + menuFieldHeight);
		field = new BMenuField(r, "account", B_TRANSLATE("From:"),
			fAccountMenu, true /* fixedSize */,
			B_FOLLOW_TOP | B_FOLLOW_LEFT_RIGHT,
			B_WILL_DRAW | B_NAVIGABLE | B_NAVIGABLE_JUMP);
		AddChild(field, encodingField);
		field->SetDivider(x - 12 - SEPARATOR_MARGIN + kMenuFieldDividerOffset);
		field->SetAlignment(B_ALIGN_RIGHT);
		y += controlHeight;
	} else {
		// To: account
		bool account = BMailAccounts().CountAccounts() > 0;

		r.Set(SEPARATOR_MARGIN, y,
			  windowRect.Width() - SEPARATOR_MARGIN, y + menuFieldHeight);
		if (account)
			r.right -= SEPARATOR_MARGIN + ACCOUNT_FIELD_WIDTH;
		fAccountTo = new TTextControl(r, B_TRANSLATE("To:"), NULL, fIncoming,
			false, B_FOLLOW_LEFT_RIGHT);
		fAccountTo->SetEnabled(false);
		fAccountTo->SetDivider(x - 12 - SEPARATOR_MARGIN);
		fAccountTo->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
		AddChild(fAccountTo);

		if (account) {
			r.left = r.right + 6;  r.right = windowRect.Width() - SEPARATOR_MARGIN;
			fAccount = new TTextControl(r, B_TRANSLATE("Account:"), NULL,
				fIncoming, false, B_FOLLOW_RIGHT | B_FOLLOW_TOP);
			fAccount->SetEnabled(false);
			AddChild(fAccount);
		}
		y += controlHeight;
	}
	
	if (fIncoming) {
		--y;
		r.Set(SEPARATOR_MARGIN, y,
			windowRect.Width() - SEPARATOR_MARGIN, y + menuFieldHeight);
		y += controlHeight;
		fCc = new TTextControl(r, B_TRANSLATE("Cc:"),
			NULL, fIncoming, false, B_FOLLOW_LEFT_RIGHT);
		fCc->SetEnabled(false);
		fCc->SetDivider(x - 12 - SEPARATOR_MARGIN);
		fCc->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
		AddChild(fCc);
	}

	--y;
	r.Set(SEPARATOR_MARGIN, y,
		windowRect.Width() - SEPARATOR_MARGIN, y + menuFieldHeight);
	y += controlHeight;
	fSubject = new TTextControl(r, B_TRANSLATE("Subject:"),
		new BMessage(SUBJECT_FIELD),fIncoming, false, B_FOLLOW_LEFT_RIGHT);
	AddChild(fSubject);
	(msg = new BMessage(FIELD_CHANGED))->AddInt32("bitmask", FIELD_SUBJECT);
	fSubject->SetModificationMessage(msg);
	fSubject->SetDivider(x - 12 - SEPARATOR_MARGIN);
	fSubject->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
	if (fResending)
		fSubject->SetEnabled(false);

	--y;

	if (!fIncoming) {
		r.Set(x - 12, y, CC_FIELD_H + CC_FIELD_WIDTH, y + menuFieldHeight);
		fCc = new TTextControl(r, "", new BMessage(CC_FIELD), fIncoming, false);
		fCc->SetFilter(mail_to_filter);
		fCc->SetChoiceList(&fEmailList);
		fCc->SetAutoComplete(true);
		AddChild(fCc);
		(msg = new BMessage(FIELD_CHANGED))->AddInt32("bitmask", FIELD_CC);
		fCc->SetModificationMessage(msg);

		r.right = r.left - 5;
		r.left = r.right - ceilf(be_plain_font->StringWidth(
			B_TRANSLATE("Cc:")) + 25);
		r.top -= 1;
		fCcMenu = new QPopupMenu(B_TRANSLATE("Cc:"));
		field = new BMenuField(r, "", "", fCcMenu, true,
			B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW);

		field->SetDivider(0.0);
		field->SetEnabled(true);
		AddChild(field);

		r.Set(BCC_FIELD_H + be_plain_font->StringWidth(B_TRANSLATE("Bcc:")), y,
			  windowRect.Width() - SEPARATOR_MARGIN, y + menuFieldHeight);
		y += controlHeight;
		fBcc = new TTextControl(r, "", new BMessage(BCC_FIELD),
						fIncoming, false, B_FOLLOW_LEFT_RIGHT);
		fBcc->SetFilter(mail_to_filter);
		fBcc->SetChoiceList(&fEmailList);
		fBcc->SetAutoComplete(true);
		AddChild(fBcc);
		(msg = new BMessage(FIELD_CHANGED))->AddInt32("bitmask", FIELD_BCC);
		fBcc->SetModificationMessage(msg);

		r.right = r.left - 5;
		r.left = r.right - ceilf(be_plain_font->StringWidth(
			B_TRANSLATE("Bcc:")) + 25);
		r.top -= 1;
		fBccMenu = new QPopupMenu(B_TRANSLATE("Bcc:"));
		field = new BMenuField(r, "", "", fBccMenu, true,
			B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW);
		field->SetDivider(0.0);
		field->SetEnabled(true);
		AddChild(field);
	} else {
		y -= SEPARATOR_MARGIN;
		r.Set(SEPARATOR_MARGIN, y, x - 12 - 1, y + menuFieldHeight);
		fDateLabel = new BStringView(r, "", kDateLabel);
		fDateLabel->SetAlignment(B_ALIGN_RIGHT);
		AddChild(fDateLabel);
		fDateLabel->SetHighColor(0, 0, 0);

		r.Set(r.right + 9, y, windowRect.Width() - SEPARATOR_MARGIN,
			y + menuFieldHeight);
		fDate = new BStringView(r, "", "");
		AddChild(fDate);
		fDate->SetHighColor(0, 0, 0);

		y += controlHeight + 5;
	}
	ResizeTo(Bounds().Width(), y);
}
예제 #18
0
void
ConfigWindow::_SaveSettings()
{
	// remove config views (trigger view archive)
	fConfigView->DeleteChildren();

	// collect changed accounts
	BMessage changedAccounts(kMsgAccountsChanged);
	for (int32 i = 0; i < fAccounts.CountItems(); i++) {
		BMailAccountSettings* account = fAccounts.ItemAt(i);
		if (account && account->HasBeenModified())
			changedAccounts.AddInt32("account", account->AccountID());
	}
	for (int32 i = 0; i < fToDeleteAccounts.CountItems(); i++) {
		BMailAccountSettings* account = fToDeleteAccounts.ItemAt(i);
		changedAccounts.AddInt32("account", account->AccountID());
	}

	// cleanup account directory
	for (int32 i = 0; i < fToDeleteAccounts.CountItems(); i++) {
		BMailAccountSettings* account = fToDeleteAccounts.ItemAt(i);
		BEntry entry(account->AccountFile());
		entry.Remove();
		delete account;
	}
	fToDeleteAccounts.MakeEmpty();

	/*** save general settings ***/

	// figure out time interval
	float interval;
	sscanf(fIntervalControl->Text(),"%f",&interval);
	float multiplier = 0;
	switch (fIntervalUnitField->Menu()->IndexOf(
			fIntervalUnitField->Menu()->FindMarked())) {
		case 1:		// minutes
			multiplier = 60;
			break;
		case 2:		// hours
			multiplier = 60 * 60;
			break;
		case 3:		// days
			multiplier = 24 * 60 * 60;
			break;
	}
	time_t time = (time_t)(multiplier * interval);

	// apply and save general settings
	BMailSettings settings;
	if (fSaveSettings) {
		settings.SetAutoCheckInterval(time * 1e6);
		settings.SetCheckOnlyIfPPPUp(fPPPActiveCheckBox->Value()
			== B_CONTROL_ON);
		settings.SetSendOnlyIfPPPUp(fPPPActiveSendCheckBox->Value()
			== B_CONTROL_ON);
		settings.SetDaemonAutoStarts(fAutoStartCheckBox->Value()
			== B_CONTROL_ON);

		// status mode (alway, fetching/retrieving, ...)
		int32 index = fStatusModeField->Menu()->IndexOf(
			fStatusModeField->Menu()->FindMarked());
		settings.SetShowStatusWindow(index);

	} else {
		// restore status window look
		settings.SetStatusWindowLook(settings.StatusWindowLook());
	}

	settings.SetConfigWindowFrame(Frame());
	settings.Save();

	/*** save accounts ***/

	if (fSaveSettings) {
		for (int i = 0; i < fAccounts.CountItems(); i++)
			fAccounts.ItemAt(i)->Save();
	}

	BMessenger messenger("application/x-vnd.Be-POST");
	if (messenger.IsValid()) {
		// server should reload general settings
		messenger.SendMessage(kMsgSettingsUpdated);
		// notify server about changed accounts
		messenger.SendMessage(&changedAccounts);
	}

	// start the mail_daemon if auto start was selected
	if (fSaveSettings && fAutoStartCheckBox->Value() == B_CONTROL_ON
		&& !be_roster->IsRunning("application/x-vnd.Be-POST"))
	{
		be_roster->Launch("application/x-vnd.Be-POST");
	}
}
예제 #19
0
BEmailMessage *
BEmailMessage::ReplyMessage(mail_reply_to_mode replyTo, bool accountFromMail,
	const char *quoteStyle)
{
	BEmailMessage *reply = new BEmailMessage;

	// Set ReplyTo:

	if (replyTo == B_MAIL_REPLY_TO_ALL) {
		reply->SetTo(From());

		BList list;
		get_address_list(list, CC(), extract_address);
		get_address_list(list, To(), extract_address);

		// Filter out the sender
		BMailAccounts accounts;
		BMailAccountSettings* account = accounts.AccountByID(Account());
		BString sender;
		if (account)
			sender = account->ReturnAddress();
		extract_address(sender);

		BString cc;

		for (int32 i = list.CountItems(); i-- > 0;) {
			char *address = (char *)list.RemoveItem((int32)0);

			// add everything which is not the sender and not already in the list
			if (sender.ICompare(address) && cc.FindFirst(address) < 0) {
				if (cc.Length() > 0)
					cc << ", ";

				cc << address;
			}

			free(address);
		}

		if (cc.Length() > 0)
			reply->SetCC(cc.String());
	} else if (replyTo == B_MAIL_REPLY_TO_SENDER || ReplyTo() == NULL)
		reply->SetTo(From());
	else
		reply->SetTo(ReplyTo());

	// Set special "In-Reply-To:" header (used for threading)
	const char *messageID = _body ? _body->HeaderField("Message-Id") : NULL;
	if (messageID != NULL)
		reply->SetHeaderField("In-Reply-To", messageID);

	// quote body text
	reply->SetBodyTextTo(BodyText());
	if (quoteStyle)
		reply->Body()->Quote(quoteStyle);

	// Set the subject (and add a "Re:" if needed)
	BString string = Subject();
	if (string.ICompare("re:", 3) != 0)
		string.Prepend("Re: ");
	reply->SetSubject(string.String());

	// set the matching outbound chain
	if (accountFromMail)
		reply->SendViaAccountFrom(this);

	return reply;
}